Files
MokoCLI/mcp/src/runner.ts
T
Jonathan Miller 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
feat: security advisory aggregator, manifest API rewrite, namespace rename (#150, #283)
- 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/
2026-06-20 20:24:58 -05:00

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),
});
});
});
}
}