Public Access
033e948c79
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: PR Check / Branch Policy (pull_request) Failing after 2s
Generic: Repo Health / Access control (pull_request) Successful in 2s
Universal: PR Check / Validate PR (pull_request) Failing after 7s
Universal: Security Audit / Dependency Audit (pull_request) Successful in 7s
Universal: Auto Version Bump / Version Bump (push) Successful in 14s
Platform: mokoplatform CI / Gate 1: Code Quality (pull_request) Failing after 1m8s
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
Platform: mokoplatform CI / Gate 2: Unit Tests (8.1) (pull_request) Has been cancelled
Platform: mokoplatform CI / Gate 2: Unit Tests (8.2) (pull_request) Has been cancelled
Platform: mokoplatform CI / Gate 2: Unit Tests (8.3) (pull_request) Has been cancelled
Platform: mokoplatform CI / Gate 3: Self-Health Check (pull_request) Has been cancelled
Platform: mokoplatform CI / Gate 4: Governance (pull_request) Has been cancelled
Platform: mokoplatform CI / Gate 5: Template Integrity (pull_request) Has been cancelled
Platform: mokoplatform CI / CI Summary (pull_request) Has been cancelled
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Universal: PR Check / Report Issues (pull_request) Has been cancelled
Generic: Repo Health / Scripts governance (pull_request) Has been cancelled
Generic: Repo Health / Repository health (pull_request) Has been cancelled
Generic: Repo Health / Report Issues (pull_request) Has been cancelled
- Add `security:advisories` command — cross-repo CVE scanner via composer audit with checkpoint resumability, severity filtering, and auto-issue creation - Rewrite `manifest:read` to use Gitea manifest API as primary source with auto-detection fallback from source tree (no more manifest.xml dependency) - Rename MokoStandards namespace → MokoCli across all files - Rename MokoEnterprise namespace → MokoCli across all files - Rename MokoStandardsParser class → ManifestParser - Fix composer.json autoload paths: src/ → source/
56 lines
1.9 KiB
TypeScript
56 lines
1.9 KiB
TypeScript
/* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
|
*
|
|
* This file is part of a Moko Consulting project.
|
|
*
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*
|
|
* FILE INFORMATION
|
|
* DEFGROUP: mokostandards-mcp.Runner
|
|
* INGROUP: MokoCli-API
|
|
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
|
|
* PATH: /mcp/src/runner.ts
|
|
* BRIEF: PHP CLI command runner for MokoCli tools — uses execFile (no shell injection)
|
|
*/
|
|
|
|
import { execFile as nodeExecFile } from 'node:child_process';
|
|
import { resolve } from 'node:path';
|
|
import type { StandardsConfig, ExecResult } from './types.js';
|
|
|
|
const TIMEOUT_MS = 60_000;
|
|
|
|
/**
|
|
* Runs MokoCli PHP CLI tools via execFile (safe, no shell).
|
|
* All arguments are passed as array elements — never interpolated into a shell string.
|
|
*/
|
|
export class StandardsRunner {
|
|
private readonly apiPath: string;
|
|
|
|
constructor(config: StandardsConfig) {
|
|
this.apiPath = config.apiPath;
|
|
}
|
|
|
|
async runCli(script: string, args: string[] = []): Promise<ExecResult> {
|
|
const scriptPath = resolve(this.apiPath, 'cli', script);
|
|
return this.run('php', [scriptPath, ...args]);
|
|
}
|
|
|
|
async runValidate(script: string, args: string[] = []): Promise<ExecResult> {
|
|
const scriptPath = resolve(this.apiPath, 'validate', script);
|
|
return this.run('php', [scriptPath, ...args]);
|
|
}
|
|
|
|
private run(command: string, args: string[]): Promise<ExecResult> {
|
|
return new Promise((resolvePromise) => {
|
|
// execFile is used intentionally — it does NOT spawn a shell,
|
|
// so arguments cannot be injected. This is the safe alternative to exec().
|
|
nodeExecFile(command, args, { timeout: TIMEOUT_MS, maxBuffer: 10 * 1024 * 1024 }, (err, stdout, stderr) => {
|
|
resolvePromise({
|
|
stdout: stdout?.toString() ?? '',
|
|
stderr: stderr?.toString() ?? '',
|
|
exitCode: err && 'code' in err ? (err as { code: number }).code : (err ? 1 : 0),
|
|
});
|
|
});
|
|
});
|
|
}
|
|
}
|