osv-security-cli 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/osv-security.js +96 -79
- package/dist/bin/osv-security.js.map +1 -1
- package/dist/src/index.d.ts +7 -2
- package/dist/src/index.js +73 -75
- package/dist/src/index.js.map +1 -1
- package/package.json +2 -2
package/dist/src/index.js
CHANGED
|
@@ -18,6 +18,7 @@ var RuntimeConfigSchema = z.object({
|
|
|
18
18
|
package_manager_js: z.string(),
|
|
19
19
|
execution: z.enum(["docker", "local"]),
|
|
20
20
|
docker_service: z.string(),
|
|
21
|
+
docker_workdir: z.string().optional(),
|
|
21
22
|
test_command: z.string(),
|
|
22
23
|
build_commands: z.object({
|
|
23
24
|
frontend: z.string(),
|
|
@@ -75,7 +76,7 @@ var GateValidationError = class extends Error {
|
|
|
75
76
|
};
|
|
76
77
|
|
|
77
78
|
// src/config/loader.ts
|
|
78
|
-
var DEFAULT_CONFIG_PATH = "
|
|
79
|
+
var DEFAULT_CONFIG_PATH = "project-config.yml";
|
|
79
80
|
async function loadConfig(configPath, cwd = process.cwd()) {
|
|
80
81
|
const absolutePath = resolve(cwd, configPath);
|
|
81
82
|
let raw;
|
|
@@ -109,70 +110,66 @@ ${issues}`,
|
|
|
109
110
|
}
|
|
110
111
|
|
|
111
112
|
// src/config/generator.ts
|
|
112
|
-
import { stringify } from "yaml";
|
|
113
113
|
function generateConfigYaml(opts = {}) {
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
""
|
|
174
|
-
].join("\n");
|
|
175
|
-
return header + stringify(config, { lineWidth: 0 });
|
|
114
|
+
const projectName = opts.projectName ?? "My Laravel Project";
|
|
115
|
+
const client = opts.client ?? "Client Name";
|
|
116
|
+
const execution = opts.execution ?? "docker";
|
|
117
|
+
const dockerService = opts.dockerService ?? "app";
|
|
118
|
+
const dockerWorkdir = opts.dockerWorkdir;
|
|
119
|
+
const phpVersion = opts.phpVersion ?? "8.2";
|
|
120
|
+
const laravelVersion = opts.laravelVersion ?? "10.x";
|
|
121
|
+
const nodeVersion = opts.nodeVersion ?? "20.x";
|
|
122
|
+
const testCommand = opts.testCommand ?? "php artisan test --compact";
|
|
123
|
+
const frontendBuild = opts.frontendBuildCommand ?? "npm run development-frontend";
|
|
124
|
+
const backendBuild = opts.backendBuildCommand ?? "npm run development-backend";
|
|
125
|
+
const workdirLine = dockerWorkdir ? `
|
|
126
|
+
docker_workdir: '${dockerWorkdir}'` : "";
|
|
127
|
+
return `# OSV Security CLI \u2014 project configuration
|
|
128
|
+
# Generated by: osv-security init
|
|
129
|
+
# Documentation: https://github.com/google/osv-scanner
|
|
130
|
+
#
|
|
131
|
+
# protected_packages: packages that must NEVER be auto-upgraded beyond their stated constraint.
|
|
132
|
+
# Any update requiring a constraint change needs explicit per-package authorization.
|
|
133
|
+
# safe_update_policy: patch/minor updates within existing constraints are auto-safe.
|
|
134
|
+
|
|
135
|
+
project:
|
|
136
|
+
name: '${projectName}'
|
|
137
|
+
client: '${client}'
|
|
138
|
+
|
|
139
|
+
runtime:
|
|
140
|
+
php: '${phpVersion}'
|
|
141
|
+
laravel: '${laravelVersion}'
|
|
142
|
+
node: '${nodeVersion}'
|
|
143
|
+
package_manager_php: 'composer'
|
|
144
|
+
package_manager_js: 'npm'
|
|
145
|
+
execution: '${execution}'
|
|
146
|
+
docker_service: '${dockerService}'${workdirLine}
|
|
147
|
+
test_command: '${testCommand}'
|
|
148
|
+
build_commands:
|
|
149
|
+
frontend: '${frontendBuild}'
|
|
150
|
+
backend: '${backendBuild}'
|
|
151
|
+
|
|
152
|
+
# Add packages that must not be auto-upgraded beyond their constraint.
|
|
153
|
+
# Examples:
|
|
154
|
+
# composer:
|
|
155
|
+
# - package: 'laravel/framework'
|
|
156
|
+
# constraint: '^10.0'
|
|
157
|
+
# reason: 'Major upgrade to Laravel 11 requires a dedicated project'
|
|
158
|
+
# npm:
|
|
159
|
+
# - package: 'tailwindcss'
|
|
160
|
+
# constraint: '^3.3.3'
|
|
161
|
+
# reason: 'Tailwind v4 has breaking config changes'
|
|
162
|
+
protected_packages:
|
|
163
|
+
composer: []
|
|
164
|
+
npm: []
|
|
165
|
+
|
|
166
|
+
safe_update_policy:
|
|
167
|
+
allow_patch_and_minor_within_constraints: true
|
|
168
|
+
require_authorization_for_constraint_change: true
|
|
169
|
+
authorization_format: 'sim, confirmo breaking changes para [vendor/pacote]'
|
|
170
|
+
|
|
171
|
+
conflict_resolution: 'stop_and_ask'
|
|
172
|
+
`;
|
|
176
173
|
}
|
|
177
174
|
|
|
178
175
|
// src/gates/validator.ts
|
|
@@ -1015,19 +1012,19 @@ var DockerExecutor = class {
|
|
|
1015
1012
|
constructor(service, options = {}) {
|
|
1016
1013
|
this.service = service;
|
|
1017
1014
|
this.dryRun = options.dryRun ?? false;
|
|
1015
|
+
this.workdir = options.workdir;
|
|
1018
1016
|
}
|
|
1019
1017
|
dryRun;
|
|
1020
1018
|
environment = "docker";
|
|
1019
|
+
workdir;
|
|
1020
|
+
buildDockerCommand(command) {
|
|
1021
|
+
const workdirFlag = this.workdir ? `--workdir ${this.workdir} ` : "";
|
|
1022
|
+
return `docker-compose exec -T ${workdirFlag}${this.service} sh -c "${command.replace(/"/g, '\\"')}"`;
|
|
1023
|
+
}
|
|
1021
1024
|
async run(command, options = {}) {
|
|
1022
|
-
const dockerCommand =
|
|
1025
|
+
const dockerCommand = this.buildDockerCommand(command);
|
|
1023
1026
|
if (this.dryRun) {
|
|
1024
|
-
return {
|
|
1025
|
-
stdout: "",
|
|
1026
|
-
stderr: "",
|
|
1027
|
-
exitCode: 0,
|
|
1028
|
-
command: dockerCommand,
|
|
1029
|
-
dryRun: true
|
|
1030
|
-
};
|
|
1027
|
+
return { stdout: "", stderr: "", exitCode: 0, command: dockerCommand, dryRun: true };
|
|
1031
1028
|
}
|
|
1032
1029
|
try {
|
|
1033
1030
|
const result = await execa2(dockerCommand, {
|
|
@@ -1057,7 +1054,7 @@ var DockerExecutor = class {
|
|
|
1057
1054
|
};
|
|
1058
1055
|
|
|
1059
1056
|
// src/environment/detector.ts
|
|
1060
|
-
async function detectEnvironment(preferredEnv, dockerService, cwd, dryRun = false) {
|
|
1057
|
+
async function detectEnvironment(preferredEnv, dockerService, cwd, dryRun = false, dockerWorkdir) {
|
|
1061
1058
|
if (preferredEnv === "local") {
|
|
1062
1059
|
logger.debug("Using local execution (configured preference)");
|
|
1063
1060
|
return new LocalExecutor({ dryRun });
|
|
@@ -1068,8 +1065,9 @@ async function detectEnvironment(preferredEnv, dockerService, cwd, dryRun = fals
|
|
|
1068
1065
|
{ cwd }
|
|
1069
1066
|
);
|
|
1070
1067
|
if (result.exitCode === 0 && parseInt(result.stdout.trim(), 10) > 0) {
|
|
1071
|
-
|
|
1072
|
-
|
|
1068
|
+
const workdirInfo = dockerWorkdir ? ` (workdir: ${dockerWorkdir})` : "";
|
|
1069
|
+
logger.debug(`Using Docker execution (service: ${dockerService}${workdirInfo})`);
|
|
1070
|
+
return new DockerExecutor(dockerService, { dryRun, workdir: dockerWorkdir });
|
|
1073
1071
|
}
|
|
1074
1072
|
logger.warn(`Docker service "${dockerService}" not running \u2014 falling back to local execution`);
|
|
1075
1073
|
return new LocalExecutor({ dryRun });
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/config/loader.ts","../../src/config/schema.ts","../../src/utils/errors.ts","../../src/config/generator.ts","../../src/gates/validator.ts","../../src/utils/logger.ts","../../src/utils/osv-commands.ts","../../src/phases/scanner.ts","../../src/utils/git.ts","../../src/phases/npm-updater.ts","../../src/phases/composer-updater.ts","../../src/phases/orchestrator.ts","../../src/report/consolidated.ts","../../src/report/executive.ts","../../src/executor/local-executor.ts","../../src/executor/docker-executor.ts","../../src/environment/detector.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport { parse } from 'yaml';\nimport { ProjectConfigSchema } from './schema.js';\nimport type { ProjectConfig } from '../types/config.js';\nimport { ConfigLoadError } from '../utils/errors.js';\n\nexport const DEFAULT_CONFIG_PATH = '.github/agents/project-config.yml';\n\nexport async function loadConfig(\n configPath: string,\n cwd: string = process.cwd(),\n): Promise<ProjectConfig> {\n const absolutePath = resolve(cwd, configPath);\n\n let raw: string;\n try {\n raw = await readFile(absolutePath, 'utf-8');\n } catch (err) {\n throw new ConfigLoadError(\n `Cannot read config file: ${absolutePath}`,\n absolutePath,\n );\n }\n\n let parsed: unknown;\n try {\n parsed = parse(raw);\n } catch (err) {\n throw new ConfigLoadError(\n `Invalid YAML in config file: ${absolutePath}`,\n absolutePath,\n );\n }\n\n const result = ProjectConfigSchema.safeParse(parsed);\n if (!result.success) {\n const issues = result.error.issues\n .map((i) => ` ${i.path.join('.')}: ${i.message}`)\n .join('\\n');\n throw new ConfigLoadError(\n `Config validation failed in ${absolutePath}:\\n${issues}`,\n absolutePath,\n );\n }\n\n return result.data;\n}\n","import { z } from 'zod';\n\nconst ProtectedPackageSchema = z.object({\n package: z.string(),\n constraint: z.string(),\n reason: z.string(),\n});\n\nconst RuntimeConfigSchema = z.object({\n php: z.string(),\n laravel: z.string(),\n node: z.string(),\n package_manager_php: z.string(),\n package_manager_js: z.string(),\n execution: z.enum(['docker', 'local']),\n docker_service: z.string(),\n test_command: z.string(),\n build_commands: z.object({\n frontend: z.string(),\n backend: z.string(),\n }),\n});\n\nconst SafeUpdatePolicySchema = z.object({\n allow_patch_and_minor_within_constraints: z.boolean(),\n require_authorization_for_constraint_change: z.boolean(),\n authorization_format: z.string(),\n});\n\nexport const ProjectConfigSchema = z.object({\n project: z.object({\n name: z.string(),\n client: z.string(),\n }),\n runtime: RuntimeConfigSchema,\n protected_packages: z.object({\n composer: z.array(ProtectedPackageSchema),\n npm: z.array(ProtectedPackageSchema),\n }),\n safe_update_policy: SafeUpdatePolicySchema,\n conflict_resolution: z.string(),\n});\n\nexport type ProjectConfigInput = z.input<typeof ProjectConfigSchema>;\n","export class ConfigLoadError extends Error {\n constructor(message: string, public readonly path: string) {\n super(message);\n this.name = 'ConfigLoadError';\n }\n}\n\nexport class EnvironmentError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'EnvironmentError';\n }\n}\n\nexport class PhaseError extends Error {\n constructor(\n message: string,\n public readonly phase: string,\n public readonly cause?: unknown,\n ) {\n super(message);\n this.name = 'PhaseError';\n }\n}\n\nexport class GateValidationError extends Error {\n constructor(\n message: string,\n public readonly gate: 'A' | 'B' | 'C',\n public readonly errors: string[],\n ) {\n super(message);\n this.name = 'GateValidationError';\n }\n}\n","import { stringify } from 'yaml';\n\nexport interface GenerateConfigOptions {\n projectName?: string;\n client?: string;\n execution?: 'docker' | 'local';\n dockerService?: string;\n phpVersion?: string;\n laravelVersion?: string;\n nodeVersion?: string;\n testCommand?: string;\n frontendBuildCommand?: string;\n backendBuildCommand?: string;\n}\n\nexport function generateConfigYaml(opts: GenerateConfigOptions = {}): string {\n const config = {\n project: {\n name: opts.projectName ?? 'My Laravel Project',\n client: opts.client ?? 'Client Name',\n },\n runtime: {\n php: opts.phpVersion ?? '8.2',\n laravel: opts.laravelVersion ?? '10.x',\n node: opts.nodeVersion ?? '20.x',\n package_manager_php: 'composer',\n package_manager_js: 'npm',\n execution: opts.execution ?? 'docker',\n docker_service: opts.dockerService ?? 'app',\n test_command: opts.testCommand ?? 'php artisan test --compact',\n build_commands: {\n frontend: opts.frontendBuildCommand ?? 'npm run development-frontend',\n backend: opts.backendBuildCommand ?? 'npm run development-backend',\n },\n },\n protected_packages: {\n composer: [\n {\n package: 'laravel/framework',\n constraint: '^10.0',\n reason: 'Major upgrade to Laravel 11 requires a dedicated project',\n },\n {\n package: 'livewire/livewire',\n constraint: '^2.12',\n reason: 'Livewire 3 has breaking API changes; do not migrate without a project',\n },\n ],\n npm: [\n {\n package: 'alpinejs',\n constraint: '^3.10.2',\n reason: 'Alpine v4 may have breaking syntax changes',\n },\n {\n package: 'tailwindcss',\n constraint: '^3.3.3',\n reason: 'Tailwind v4 has breaking config and migration requirements',\n },\n ],\n },\n safe_update_policy: {\n allow_patch_and_minor_within_constraints: true,\n require_authorization_for_constraint_change: true,\n authorization_format: 'sim, confirmo breaking changes para [vendor/pacote]',\n },\n conflict_resolution: 'stop_and_ask',\n };\n\n const header = [\n '# OSV Security CLI — project configuration',\n '# Generated by: osv-security init',\n '# Documentation: https://github.com/google/osv-scanner',\n '#',\n '# - protected_packages: packages that must never be auto-upgraded beyond their constraint',\n '# - safe_update_policy: patch/minor within constraints are auto-safe; constraint changes require authorization',\n '',\n ].join('\\n');\n\n return header + stringify(config, { lineWidth: 0 });\n}\n","import { z } from 'zod';\nimport type { GateResult } from '../types/common.js';\nimport type { ScanResultJson } from '../types/scan.js';\nimport type { UpdateResultJson } from '../types/update.js';\n\nconst EcosystemScanResultSchema = z.object({\n vulnerabilities_total: z.number(),\n auto_safe: z.number(),\n breaking: z.number(),\n manual: z.number(),\n auto_safe_packages: z.array(z.string()),\n breaking_packages: z.array(z.string()),\n manual_packages: z.array(z.string()),\n});\n\nconst ScanResultSchema = z.object({\n $schema: z.literal('osv-scan-result/v1'),\n agent: z.literal('osv-scanner'),\n status: z.enum(['success', 'error', 'skipped']),\n environment: z.enum(['docker', 'local']),\n php: EcosystemScanResultSchema,\n npm: EcosystemScanResultSchema,\n error: z.string().nullable(),\n});\n\nconst UpdateResultSchema = z.object({\n $schema: z.literal('osv-update-result/v1'),\n agent: z.enum(['composer-safe-update', 'npm-safe-update']),\n status: z.enum(['success', 'error', 'skipped']),\n packages_updated: z.array(z.string()),\n packages_skipped: z.array(z.string()),\n packages_pending_breaking: z.array(z.string()),\n tests: z.enum(['pass', 'fail', 'skipped']),\n tests_detail: z.string(),\n build_status: z.enum(['pass', 'fail', 'skipped']).optional(),\n build_detail: z.string().optional(),\n error: z.string().nullable(),\n});\n\nexport function validateGateA(data: unknown): GateResult {\n const result = ScanResultSchema.safeParse(data);\n if (!result.success) {\n return {\n valid: false,\n gate: 'A',\n errors: result.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`),\n };\n }\n if (result.data.status === 'error') {\n return {\n valid: false,\n gate: 'A',\n errors: [`Scanner returned error: ${result.data.error ?? 'unknown'}`],\n };\n }\n return { valid: true, gate: 'A', errors: [] };\n}\n\nexport function validateGateB(data: unknown): GateResult {\n const result = UpdateResultSchema.safeParse(data);\n if (!result.success) {\n return {\n valid: false,\n gate: 'B',\n errors: result.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`),\n };\n }\n if (result.data.agent !== 'npm-safe-update') {\n return {\n valid: false,\n gate: 'B',\n errors: [`Expected agent \"npm-safe-update\", got \"${result.data.agent}\"`],\n };\n }\n if (result.data.status === 'error') {\n return {\n valid: false,\n gate: 'B',\n errors: [`npm updater returned error: ${result.data.error ?? 'unknown'}`],\n };\n }\n return { valid: true, gate: 'B', errors: [] };\n}\n\nexport function validateGateC(data: unknown): GateResult {\n const result = UpdateResultSchema.safeParse(data);\n if (!result.success) {\n return {\n valid: false,\n gate: 'C',\n errors: result.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`),\n };\n }\n if (result.data.agent !== 'composer-safe-update') {\n return {\n valid: false,\n gate: 'C',\n errors: [`Expected agent \"composer-safe-update\", got \"${result.data.agent}\"`],\n };\n }\n if (result.data.status === 'error') {\n return {\n valid: false,\n gate: 'C',\n errors: [`Composer updater returned error: ${result.data.error ?? 'unknown'}`],\n };\n }\n return { valid: true, gate: 'C', errors: [] };\n}\n\nexport function validateScanResult(data: ScanResultJson): GateResult {\n return validateGateA(data);\n}\n\nexport function validateUpdateResult(\n data: UpdateResultJson,\n gate: 'B' | 'C',\n): GateResult {\n return gate === 'B' ? validateGateB(data) : validateGateC(data);\n}\n","export type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nconst LEVELS: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\nlet currentLevel: LogLevel = 'info';\n\nexport function setLogLevel(level: LogLevel): void {\n currentLevel = level;\n}\n\nfunction shouldLog(level: LogLevel): boolean {\n return LEVELS[level] >= LEVELS[currentLevel];\n}\n\nfunction format(level: LogLevel, message: string): string {\n const prefix: Record<LogLevel, string> = {\n debug: '[DEBUG]',\n info: '[INFO] ',\n warn: '[WARN] ',\n error: '[ERROR]',\n };\n return `${prefix[level]} ${message}`;\n}\n\nexport const logger = {\n debug(message: string): void {\n if (shouldLog('debug')) process.stderr.write(format('debug', message) + '\\n');\n },\n info(message: string): void {\n if (shouldLog('info')) process.stderr.write(format('info', message) + '\\n');\n },\n warn(message: string): void {\n if (shouldLog('warn')) process.stderr.write(format('warn', message) + '\\n');\n },\n error(message: string): void {\n if (shouldLog('error')) process.stderr.write(format('error', message) + '\\n');\n },\n};\n","export const OSV = {\n scanAll: 'osv-scanner --lockfile composer.lock --lockfile package-lock.json --format json',\n scanPhp: 'osv-scanner --lockfile composer.lock --format json',\n scanNpm: 'osv-scanner --lockfile package-lock.json --format json',\n fixNpm: 'osv-scanner fix --strategy=in-place -L package-lock.json',\n checkAvailable: 'osv-scanner --version',\n} as const;\n","import type { CommandRunner } from '../types/common.js';\nimport type { ProjectConfig } from '../types/config.js';\nimport type { ScanResultJson, EcosystemScanResult } from '../types/scan.js';\nimport { PhaseError, EnvironmentError } from '../utils/errors.js';\nimport { logger } from '../utils/logger.js';\nimport { OSV } from '../utils/osv-commands.js';\n\nfunction emptyEcosystem(): EcosystemScanResult {\n return {\n vulnerabilities_total: 0,\n auto_safe: 0,\n breaking: 0,\n manual: 0,\n auto_safe_packages: [],\n breaking_packages: [],\n manual_packages: [],\n };\n}\n\nfunction extractSafeVersion(\n vulnerabilities: Array<{\n affected?: Array<{ ranges?: Array<{ events?: Array<{ fixed?: string }> }> }>;\n }>,\n): string | null {\n for (const vuln of vulnerabilities) {\n for (const affected of vuln.affected ?? []) {\n for (const range of affected.ranges ?? []) {\n for (const event of range.events ?? []) {\n if (event.fixed) return event.fixed;\n }\n }\n }\n }\n return null;\n}\n\ntype OsvJsonOutput = {\n results?: Array<{\n packages?: Array<{\n package?: { name?: string; version?: string; ecosystem?: string };\n vulnerabilities?: Array<{\n affected?: Array<{ ranges?: Array<{ events?: Array<{ fixed?: string }> }> }>;\n }>;\n }>;\n }>;\n};\n\nfunction classifyPackageIntoEcosystem(\n pkgName: string,\n pkgVersion: string,\n ecosystem: string,\n safeVersion: string | null,\n protectedComposer: Set<string>,\n protectedNpm: Set<string>,\n php: EcosystemScanResult,\n npm: EcosystemScanResult,\n): void {\n const isPhp = ecosystem === 'packagist' || ecosystem === 'composer';\n const isNpm = ecosystem === 'npm';\n const target = isPhp ? php : isNpm ? npm : null;\n if (!target) return;\n\n const isProtected = (isPhp ? protectedComposer : protectedNpm).has(pkgName);\n const packageRef = `${pkgName}@${pkgVersion}`;\n\n target.vulnerabilities_total++;\n\n if (!safeVersion || isProtected) {\n target.breaking++;\n target.breaking_packages.push(packageRef);\n } else {\n target.auto_safe++;\n target.auto_safe_packages.push(packageRef);\n }\n}\n\nfunction parseOsvJsonOutput(\n stdout: string,\n config: ProjectConfig,\n): Pick<ScanResultJson, 'php' | 'npm'> {\n const data = JSON.parse(stdout) as OsvJsonOutput;\n const php = emptyEcosystem();\n const npm = emptyEcosystem();\n\n if (!data.results) return { php, npm };\n\n const protectedComposer = new Set(config.protected_packages.composer.map((p) => p.package));\n const protectedNpm = new Set(config.protected_packages.npm.map((p) => p.package));\n\n for (const result of data.results) {\n for (const pkg of result.packages ?? []) {\n const pkgName = pkg.package?.name ?? '';\n const pkgVersion = pkg.package?.version ?? '';\n const ecosystem = pkg.package?.ecosystem?.toLowerCase() ?? '';\n const safeVersion = extractSafeVersion(pkg.vulnerabilities ?? []);\n\n classifyPackageIntoEcosystem(\n pkgName, pkgVersion, ecosystem, safeVersion,\n protectedComposer, protectedNpm, php, npm,\n );\n }\n }\n\n return { php, npm };\n}\n\nasync function assertOsvScannerAvailable(runner: CommandRunner, cwd: string): Promise<void> {\n const result = await runner.run(OSV.checkAvailable, { cwd });\n if (result.exitCode !== 0) {\n throw new EnvironmentError(\n 'osv-scanner not found. Install it with: brew install osv-scanner (macOS) or see https://github.com/google/osv-scanner',\n );\n }\n}\n\nasync function executeScan(runner: CommandRunner, cwd: string) {\n logger.debug(`Running: ${OSV.scanAll}`);\n return runner.run(OSV.scanAll, { cwd });\n}\n\nexport async function runScanner(\n runner: CommandRunner,\n config: ProjectConfig,\n cwd: string,\n): Promise<ScanResultJson> {\n logger.info('Phase 1: Running OSV vulnerability scan...');\n\n const base: ScanResultJson = {\n $schema: 'osv-scan-result/v1',\n agent: 'osv-scanner',\n status: 'success',\n environment: runner.environment,\n php: emptyEcosystem(),\n npm: emptyEcosystem(),\n error: null,\n };\n\n try {\n await assertOsvScannerAvailable(runner, cwd);\n\n if (runner.dryRun) {\n logger.info(`[DRY-RUN] Would execute: ${OSV.scanAll}`);\n return base;\n }\n\n const scanResult = await executeScan(runner, cwd);\n\n if (scanResult.exitCode !== 0 && !scanResult.stdout) {\n return {\n ...base,\n status: 'error',\n error: `Scan failed (exit ${scanResult.exitCode}): ${scanResult.stderr}`,\n };\n }\n\n const parsed = parseOsvJsonOutput(scanResult.stdout, config);\n return { ...base, ...parsed };\n } catch (err) {\n if (err instanceof EnvironmentError) throw err;\n throw new PhaseError(\n `OSV scanner phase failed: ${err instanceof Error ? err.message : String(err)}`,\n 'scanner',\n err,\n );\n }\n}\n","import type { CommandRunner } from '../types/common.js';\n\nexport async function revertFiles(\n runner: CommandRunner,\n files: string[],\n cwd: string,\n): Promise<void> {\n if (files.length === 0) return;\n const fileList = files.join(' ');\n await runner.run(`git checkout -- ${fileList}`, { cwd });\n}\n\nexport async function isWorkingTreeClean(\n runner: CommandRunner,\n files: string[],\n cwd: string,\n): Promise<boolean> {\n const result = await runner.run(`git status --porcelain -- ${files.join(' ')}`, { cwd });\n return result.exitCode === 0 && result.stdout.trim() === '';\n}\n","import type { CommandRunner, CommandResult } from '../types/common.js';\nimport type { ProjectConfig } from '../types/config.js';\nimport type { UpdateResultJson } from '../types/update.js';\nimport type { ScanResultJson } from '../types/scan.js';\nimport { PhaseError } from '../utils/errors.js';\nimport { revertFiles, isWorkingTreeClean } from '../utils/git.js';\nimport { logger } from '../utils/logger.js';\nimport { OSV } from '../utils/osv-commands.js';\n\nconst NPM_FILES = ['package.json', 'package-lock.json'];\n\nasync function checkCurrentState(runner: CommandRunner, cwd: string): Promise<void> {\n logger.debug('Running npm outdated and npm audit (informational)...');\n await runner.run('npm outdated', { cwd });\n await runner.run('npm audit', { cwd });\n}\n\nasync function applyOsvFix(runner: CommandRunner, cwd: string): Promise<void> {\n logger.info(`Applying OSV in-place fix: ${OSV.fixNpm}`);\n const result = await runner.run(OSV.fixNpm, { cwd });\n if (result.exitCode !== 0) {\n logger.warn(`osv-scanner fix exited with ${result.exitCode}: ${result.stderr}`);\n }\n}\n\nasync function runNpmUpdate(runner: CommandRunner, cwd: string): Promise<CommandResult> {\n logger.info('Running npm update...');\n return runner.run('npm update', { cwd });\n}\n\nasync function validateBuilds(\n runner: CommandRunner,\n config: ProjectConfig,\n cwd: string,\n): Promise<{ frontend: CommandResult; backend: CommandResult }> {\n logger.info('Validating frontend build...');\n const frontend = await runner.run(config.runtime.build_commands.frontend, { cwd });\n logger.info('Validating backend build...');\n const backend = await runner.run(config.runtime.build_commands.backend, { cwd });\n return { frontend, backend };\n}\n\nasync function revertNpmChanges(runner: CommandRunner, cwd: string): Promise<void> {\n await revertFiles(runner, NPM_FILES, cwd);\n await runner.run('npm install', { cwd });\n}\n\nasync function verifyResidualVulnerabilities(runner: CommandRunner, cwd: string): Promise<void> {\n logger.info(`Running post-update OSV verification: ${OSV.scanNpm}`);\n await runner.run(OSV.scanNpm, { cwd });\n}\n\nexport async function runNpmUpdater(\n runner: CommandRunner,\n config: ProjectConfig,\n scanResult: ScanResultJson,\n cwd: string,\n): Promise<UpdateResultJson> {\n logger.info('Phase 2: Running npm safe updates...');\n\n const base: UpdateResultJson = {\n $schema: 'osv-update-result/v1',\n agent: 'npm-safe-update',\n status: 'success',\n packages_updated: [],\n packages_skipped: [],\n packages_pending_breaking: scanResult.npm.breaking_packages,\n tests: 'skipped',\n tests_detail: 'Build validated; unit tests not applicable to npm phase',\n build_status: 'skipped',\n build_detail: '',\n error: null,\n };\n\n if (runner.dryRun) {\n logger.info(`[DRY-RUN] Would execute: ${OSV.fixNpm}`);\n logger.info('[DRY-RUN] Would execute: npm update');\n logger.info(`[DRY-RUN] Would execute: ${config.runtime.build_commands.frontend}`);\n logger.info(`[DRY-RUN] Would execute: ${config.runtime.build_commands.backend}`);\n logger.info(`[DRY-RUN] Would execute: ${OSV.scanNpm}`);\n return { ...base, build_status: 'pass', build_detail: 'Dry-run — not executed' };\n }\n\n try {\n const isClean = await isWorkingTreeClean(runner, NPM_FILES, cwd);\n if (!isClean) {\n return {\n ...base,\n status: 'error',\n error: 'package.json or package-lock.json has uncommitted changes — aborting to prevent data loss on revert',\n };\n }\n\n await checkCurrentState(runner, cwd);\n await applyOsvFix(runner, cwd);\n\n const updateResult = await runNpmUpdate(runner, cwd);\n if (updateResult.exitCode !== 0) {\n return {\n ...base,\n status: 'error',\n build_status: 'fail',\n error: `npm update failed: ${updateResult.stderr}`,\n };\n }\n\n const { frontend, backend } = await validateBuilds(runner, config, cwd);\n\n if (frontend.exitCode !== 0) {\n logger.error('Frontend build failed — reverting...');\n await revertNpmChanges(runner, cwd);\n return {\n ...base,\n status: 'error',\n build_status: 'fail',\n build_detail: `Frontend build failed: ${frontend.stderr}`,\n error: 'Frontend build failed after npm update — changes reverted',\n };\n }\n\n if (backend.exitCode !== 0) {\n logger.error('Backend build failed — reverting...');\n await revertNpmChanges(runner, cwd);\n return {\n ...base,\n status: 'error',\n build_status: 'fail',\n build_detail: `Backend build failed: ${backend.stderr}`,\n error: 'Backend build failed after npm update — changes reverted',\n };\n }\n\n await verifyResidualVulnerabilities(runner, cwd);\n\n return {\n ...base,\n packages_updated: scanResult.npm.auto_safe_packages,\n build_status: 'pass',\n build_detail: 'Frontend and backend builds passed after update',\n };\n } catch (err) {\n throw new PhaseError(\n `npm updater phase failed: ${err instanceof Error ? err.message : String(err)}`,\n 'npm-updater',\n err,\n );\n }\n}\n","import type { CommandRunner, CommandResult } from '../types/common.js';\nimport type { ProjectConfig } from '../types/config.js';\nimport type { UpdateResultJson } from '../types/update.js';\nimport type { ScanResultJson } from '../types/scan.js';\nimport { PhaseError } from '../utils/errors.js';\nimport { revertFiles, isWorkingTreeClean } from '../utils/git.js';\nimport { logger } from '../utils/logger.js';\nimport { OSV } from '../utils/osv-commands.js';\n\nconst COMPOSER_FILES = ['composer.json', 'composer.lock'];\n\nfunction extractPackageNames(packageRefs: string[]): string[] {\n return packageRefs.map((ref) => {\n const atIndex = ref.lastIndexOf('@');\n return atIndex > 0 ? ref.slice(0, atIndex) : ref;\n });\n}\n\nasync function checkCurrentState(runner: CommandRunner, cwd: string): Promise<void> {\n logger.debug('Running composer outdated --direct (informational)...');\n await runner.run('composer outdated --direct', { cwd });\n}\n\nasync function applyComposerUpdate(\n runner: CommandRunner,\n packageNames: string[],\n cwd: string,\n): Promise<CommandResult> {\n const pkgList = packageNames.join(' ');\n logger.info(`Updating packages: ${pkgList}`);\n return runner.run(`composer update ${pkgList} --no-interaction`, { cwd });\n}\n\nasync function runTestSuite(\n runner: CommandRunner,\n testCommand: string,\n cwd: string,\n): Promise<CommandResult> {\n logger.info(`Running tests: ${testCommand}`);\n return runner.run(testCommand, { cwd });\n}\n\nasync function revertComposerChanges(runner: CommandRunner, cwd: string): Promise<void> {\n await revertFiles(runner, COMPOSER_FILES, cwd);\n await runner.run('composer install --no-interaction', { cwd });\n}\n\nasync function verifyResidualVulnerabilities(runner: CommandRunner, cwd: string): Promise<void> {\n logger.info(`Running post-update OSV verification: ${OSV.scanPhp}`);\n await runner.run(OSV.scanPhp, { cwd });\n}\n\nexport async function runComposerUpdater(\n runner: CommandRunner,\n config: ProjectConfig,\n scanResult: ScanResultJson,\n cwd: string,\n): Promise<UpdateResultJson> {\n logger.info('Phase 3: Running Composer safe updates...');\n\n const base: UpdateResultJson = {\n $schema: 'osv-update-result/v1',\n agent: 'composer-safe-update',\n status: 'success',\n packages_updated: [],\n packages_skipped: [],\n packages_pending_breaking: scanResult.php.breaking_packages,\n tests: 'skipped',\n tests_detail: '',\n error: null,\n };\n\n const autoSafePackageNames = extractPackageNames(scanResult.php.auto_safe_packages);\n\n if (autoSafePackageNames.length === 0) {\n return { ...base, tests_detail: 'No auto-safe packages to update' };\n }\n\n if (runner.dryRun) {\n logger.info(`[DRY-RUN] Would execute: composer update ${autoSafePackageNames.join(' ')} --no-interaction`);\n logger.info(`[DRY-RUN] Would execute: ${config.runtime.test_command}`);\n logger.info(`[DRY-RUN] Would execute: ${OSV.scanPhp}`);\n return {\n ...base,\n packages_updated: scanResult.php.auto_safe_packages,\n tests_detail: 'Dry-run — not executed',\n };\n }\n\n try {\n const isClean = await isWorkingTreeClean(runner, COMPOSER_FILES, cwd);\n if (!isClean) {\n return {\n ...base,\n status: 'error',\n error: 'composer.json or composer.lock has uncommitted changes — aborting to prevent data loss on revert',\n };\n }\n\n await checkCurrentState(runner, cwd);\n\n const updateResult = await applyComposerUpdate(runner, autoSafePackageNames, cwd);\n if (updateResult.exitCode !== 0) {\n return {\n ...base,\n status: 'error',\n tests: 'skipped',\n error: `composer update failed: ${updateResult.stderr}`,\n };\n }\n\n const testResult = await runTestSuite(runner, config.runtime.test_command, cwd);\n if (testResult.exitCode !== 0) {\n logger.error('Tests failed — reverting Composer updates...');\n await revertComposerChanges(runner, cwd);\n return {\n ...base,\n status: 'error',\n tests: 'fail',\n tests_detail: testResult.stdout || testResult.stderr,\n error: 'Tests failed after composer update — changes reverted',\n };\n }\n\n await verifyResidualVulnerabilities(runner, cwd);\n\n const testDetail = testResult.stdout.trim().split('\\n').slice(-2).join(' ');\n\n return {\n ...base,\n packages_updated: scanResult.php.auto_safe_packages,\n tests: 'pass',\n tests_detail: testDetail || 'Tests passed',\n };\n } catch (err) {\n throw new PhaseError(\n `Composer updater phase failed: ${err instanceof Error ? err.message : String(err)}`,\n 'composer-updater',\n err,\n );\n }\n}\n","import type { CommandRunner, PhaseStatus } from '../types/common.js';\nimport type { ProjectConfig } from '../types/config.js';\nimport type { ScanResultJson } from '../types/scan.js';\nimport type { UpdateResultJson } from '../types/update.js';\nimport { validateGateA, validateGateB, validateGateC } from '../gates/validator.js';\nimport { GateValidationError } from '../utils/errors.js';\nimport { logger } from '../utils/logger.js';\nimport { runScanner } from './scanner.js';\nimport { runNpmUpdater } from './npm-updater.js';\nimport { runComposerUpdater } from './composer-updater.js';\n\nexport interface OrchestratorOptions {\n configPath: string;\n cwd: string;\n dryRun: boolean;\n verbose: boolean;\n phases?: ('scan' | 'npm' | 'composer' | 'report')[];\n executiveReport?: {\n client: string;\n project: string;\n };\n}\n\nexport interface OrchestratorResult {\n scan: ScanResultJson | null;\n npmUpdate: UpdateResultJson | null;\n composerUpdate: UpdateResultJson | null;\n overallStatus: PhaseStatus;\n}\n\nfunction shouldRunPhase(\n phase: 'scan' | 'npm' | 'composer',\n options: OrchestratorOptions,\n): boolean {\n if (!options.phases) return true;\n return options.phases.includes(phase);\n}\n\nexport async function runOrchestrator(\n runner: CommandRunner,\n config: ProjectConfig,\n options: OrchestratorOptions,\n): Promise<OrchestratorResult> {\n const result: OrchestratorResult = {\n scan: null,\n npmUpdate: null,\n composerUpdate: null,\n overallStatus: 'success',\n };\n\n // Phase 1 — Scan (hard precondition)\n if (!shouldRunPhase('scan', options)) {\n logger.warn('Skipping scan phase — phases option does not include \"scan\"');\n result.overallStatus = 'skipped';\n return result;\n }\n\n logger.info('=== Phase 1: Vulnerability Scan ===');\n const scanResult = await runScanner(runner, config, options.cwd);\n result.scan = scanResult;\n\n // Gate A validation\n const gateA = validateGateA(scanResult);\n if (!gateA.valid) {\n throw new GateValidationError(\n `Gate A validation failed: ${gateA.errors.join(', ')}`,\n 'A',\n gateA.errors,\n );\n }\n\n logger.info(\n `Scan complete: ${scanResult.php.vulnerabilities_total} PHP vulns ` +\n `(${scanResult.php.auto_safe} auto-safe, ${scanResult.php.breaking} breaking), ` +\n `${scanResult.npm.vulnerabilities_total} npm vulns ` +\n `(${scanResult.npm.auto_safe} auto-safe, ${scanResult.npm.breaking} breaking)`,\n );\n\n // Check if any updates are needed\n const hasNpmUpdates = scanResult.npm.auto_safe > 0;\n const hasPhpUpdates = scanResult.php.auto_safe > 0;\n\n if (!hasNpmUpdates && !hasPhpUpdates) {\n logger.info('No auto-safe vulnerabilities found — no updates needed');\n return result;\n }\n\n // Phase 2 — npm remediation\n if (shouldRunPhase('npm', options) && hasNpmUpdates) {\n logger.info('=== Phase 2: npm Safe Updates ===');\n const npmResult = await runNpmUpdater(runner, config, scanResult, options.cwd);\n result.npmUpdate = npmResult;\n\n // Gate B validation\n const gateB = validateGateB(npmResult);\n if (!gateB.valid) {\n throw new GateValidationError(\n `Gate B validation failed: ${gateB.errors.join(', ')}`,\n 'B',\n gateB.errors,\n );\n }\n\n if (npmResult.build_status === 'fail') {\n logger.error('npm build failed — stopping before Composer phase');\n result.overallStatus = 'error';\n return result;\n }\n\n logger.info(\n `npm update complete: ${npmResult.packages_updated.length} packages updated`,\n );\n } else if (!hasNpmUpdates) {\n logger.info('Phase 2: Skipping npm update — no auto-safe npm vulnerabilities');\n }\n\n // Phase 3 — Composer remediation\n if (shouldRunPhase('composer', options) && hasPhpUpdates) {\n logger.info('=== Phase 3: Composer Safe Updates ===');\n const composerResult = await runComposerUpdater(runner, config, scanResult, options.cwd);\n result.composerUpdate = composerResult;\n\n // Gate C validation\n const gateC = validateGateC(composerResult);\n if (!gateC.valid) {\n throw new GateValidationError(\n `Gate C validation failed: ${gateC.errors.join(', ')}`,\n 'C',\n gateC.errors,\n );\n }\n\n if (composerResult.tests === 'fail') {\n logger.error('Composer tests failed — workflow stopped');\n result.overallStatus = 'error';\n return result;\n }\n\n logger.info(\n `Composer update complete: ${composerResult.packages_updated.length} packages updated`,\n );\n } else if (!hasPhpUpdates) {\n logger.info('Phase 3: Skipping Composer update — no auto-safe PHP vulnerabilities');\n }\n\n // Check if there are pending items\n const hasPendingItems =\n scanResult.php.breaking > 0 ||\n scanResult.npm.breaking > 0 ||\n scanResult.php.manual > 0 ||\n scanResult.npm.manual > 0;\n\n if (hasPendingItems) {\n result.overallStatus = 'error'; // exit code 1: vulns remain\n }\n\n return result;\n}\n","import type { ConsolidatedReport } from '../types/report.js';\n\nexport function generateConsolidatedReport(data: ConsolidatedReport): string {\n const lines: string[] = [];\n\n lines.push(`# Security Report — ${data.projectName}`);\n lines.push(`**Date:** ${data.date}`);\n lines.push(`**Environment:** ${data.environment}`);\n lines.push('');\n\n // Vulnerabilities found\n lines.push('## Vulnerabilities Found');\n const scan = data.scan;\n const totalVulns = scan.php.vulnerabilities_total + scan.npm.vulnerabilities_total;\n lines.push(`- **Total:** ${totalVulns}`);\n lines.push(\n `- **PHP (auto-safe/breaking/manual):** ${scan.php.auto_safe}/${scan.php.breaking}/${scan.php.manual}`,\n );\n lines.push(\n `- **npm (auto-safe/breaking/manual):** ${scan.npm.auto_safe}/${scan.npm.breaking}/${scan.npm.manual}`,\n );\n lines.push('');\n\n // Fixes applied\n lines.push('## Fixes Applied');\n\n if (data.npmUpdate && data.npmUpdate.packages_updated.length > 0) {\n lines.push('### npm');\n for (const pkg of data.npmUpdate.packages_updated) {\n lines.push(`- ${pkg}`);\n }\n } else {\n lines.push('### npm');\n lines.push('- No packages updated');\n }\n lines.push('');\n\n if (data.composerUpdate && data.composerUpdate.packages_updated.length > 0) {\n lines.push('### Composer (PHP)');\n for (const pkg of data.composerUpdate.packages_updated) {\n lines.push(`- ${pkg}`);\n }\n } else {\n lines.push('### Composer (PHP)');\n lines.push('- No packages updated');\n }\n lines.push('');\n\n // Validation results\n lines.push('## Validation After Updates');\n if (data.composerUpdate) {\n const testStatus = data.composerUpdate.tests === 'pass' ? '✅ PASS' : data.composerUpdate.tests === 'fail' ? '❌ FAIL' : '— skipped';\n lines.push(`- PHP test suite: ${testStatus}`);\n if (data.composerUpdate.tests_detail) {\n lines.push(` ${data.composerUpdate.tests_detail}`);\n }\n }\n if (data.npmUpdate) {\n const buildStatus = data.npmUpdate.build_status === 'pass' ? '✅ PASS' : data.npmUpdate.build_status === 'fail' ? '❌ FAIL' : '— skipped';\n lines.push(`- npm build: ${buildStatus}`);\n if (data.npmUpdate.build_detail) {\n lines.push(` ${data.npmUpdate.build_detail}`);\n }\n }\n lines.push('');\n\n // Pending items\n const pendingBreaking = [\n ...scan.php.breaking_packages.map((p) => `[PHP] ${p}`),\n ...scan.npm.breaking_packages.map((p) => `[npm] ${p}`),\n ];\n const pendingManual = [\n ...scan.php.manual_packages.map((p) => `[PHP] ${p}`),\n ...scan.npm.manual_packages.map((p) => `[npm] ${p}`),\n ];\n\n if (pendingBreaking.length > 0 || pendingManual.length > 0) {\n lines.push('## Pending — Require Manual Action');\n\n if (pendingBreaking.length > 0) {\n lines.push('### Require BREAKING CHANGE (awaiting per-package authorization)');\n for (const pkg of pendingBreaking) {\n lines.push(`- ${pkg}`);\n lines.push(\n ` To authorize: \"sim, confirmo breaking changes para [package]\"`,\n );\n }\n lines.push('');\n }\n\n if (pendingManual.length > 0) {\n lines.push('### No safe version within current constraint');\n for (const pkg of pendingManual) {\n lines.push(`- ${pkg}`);\n }\n lines.push('');\n }\n }\n\n return lines.join('\\n');\n}\n","import type { ExecutiveReportOptions } from '../types/report.js';\n\nfunction monthName(date: Date): string {\n return date.toLocaleString('en-US', { month: 'long' });\n}\n\nfunction monthNamePt(date: Date): string {\n const months = [\n 'Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho',\n 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro',\n ];\n return months[date.getMonth()]!;\n}\n\nfunction zeroPad(n: number): string {\n return String(n).padStart(2, '0');\n}\n\nexport function generateExecutiveReport(opts: ExecutiveReportOptions): string {\n const now = new Date();\n const year = now.getFullYear();\n const month = zeroPad(now.getMonth() + 1);\n const monthFull = monthNamePt(now);\n\n const npmFixed = opts.npmUpdate?.packages_updated ?? [];\n const composerFixed = opts.composerUpdate?.packages_updated ?? [];\n const allFixed = [...composerFixed.map((p) => ({ type: 'Composer', pkg: p })), ...npmFixed.map((p) => ({ type: 'npm', pkg: p }))];\n\n const npmBreaking = opts.scanBefore.npm.breaking_packages;\n const phpBreaking = opts.scanBefore.php.breaking_packages;\n const allPending = [\n ...phpBreaking.map((p) => ({ type: 'Composer', pkg: p })),\n ...npmBreaking.map((p) => ({ type: 'npm', pkg: p })),\n ];\n\n const hasFixed = allFixed.length > 0;\n const hasPending = allPending.length > 0;\n const noneFound =\n opts.scanBefore.php.vulnerabilities_total === 0 &&\n opts.scanBefore.npm.vulnerabilities_total === 0;\n\n const lines: string[] = [];\n\n lines.push(`Cliente: ${opts.client}`);\n lines.push(`Projeto: ${opts.project}`);\n lines.push(`Período: ${monthFull} ${year}`);\n lines.push('');\n lines.push('---');\n lines.push('');\n lines.push('Tarefa');\n lines.push('');\n lines.push('Manutenção de Segurança — OSV Scanner (rotina mensal)');\n lines.push('');\n lines.push(\n 'Verificação mensal das dependências instaladas (PHP/Composer e npm) para identificar pacotes com vulnerabilidades conhecidas e aplicar correções disponíveis.',\n );\n lines.push('');\n lines.push('---');\n lines.push('');\n lines.push('Resolução');\n lines.push('');\n\n if (noneFound) {\n lines.push(\n 'Nenhuma vulnerabilidade foi identificada nas dependências PHP ou npm. O projeto está atualizado e seguro.',\n );\n } else if (hasFixed) {\n lines.push(\n 'Após a execução da varredura, os seguintes problemas foram encontrados e corrigidos:',\n );\n lines.push('');\n lines.push(\n '| Tipo | Pacote | Versão Corrigida | Risco |',\n );\n lines.push('|------|--------|-----------------|-------|');\n for (const { type, pkg } of allFixed) {\n lines.push(`| ${type} | ${pkg} | — | — |`);\n }\n }\n\n if (hasPending) {\n lines.push('');\n lines.push(\n 'As seguintes vulnerabilidades não puderam ser corrigidas automaticamente e permanecem pendentes:',\n );\n lines.push('');\n lines.push('| Tipo | Pacote | Versão Atual | Motivo |');\n lines.push('|------|--------|-------------|--------|');\n for (const { type, pkg } of allPending) {\n lines.push(`| ${type} | ${pkg} | — | Requer mudança disruptiva |`);\n }\n }\n\n lines.push('');\n lines.push('---');\n lines.push('');\n lines.push('Resumo');\n lines.push('');\n\n if (noneFound) {\n lines.push(\n 'Nenhuma vulnerabilidade foi identificada nas dependências PHP ou npm. O projeto está atualizado e seguro.',\n );\n } else if (hasFixed && !hasPending) {\n lines.push(\n 'Todas as vulnerabilidades identificadas foram corrigidas. O projeto está atualizado e seguro em relação às suas dependências.',\n );\n } else if (hasFixed && hasPending) {\n lines.push(\n 'Todas as vulnerabilidades que puderam ser corrigidas sem mudanças disruptivas foram aplicadas. Os itens listados acima requerem avaliação ou autorização de versão principal.',\n );\n } else {\n lines.push(\n 'Vulnerabilidades identificadas requerem ação manual — nenhuma correção automática foi aplicada.',\n );\n }\n\n return lines.join('\\n');\n}\n\nexport function executiveReportFilename(client: string, project: string): string {\n const now = new Date();\n const year = now.getFullYear();\n const month = String(now.getMonth() + 1).padStart(2, '0');\n const monthEn = monthName(now);\n return `[${client} ${project}] Report OSV Scanner - ${year}-${month} - ${monthEn}.md`;\n}\n","import { execa } from 'execa';\nimport type { CommandRunner, CommandRunnerOptions, CommandResult } from '../types/common.js';\n\nexport class LocalExecutor implements CommandRunner {\n readonly dryRun: boolean;\n readonly environment = 'local' as const;\n\n constructor(options: { dryRun?: boolean } = {}) {\n this.dryRun = options.dryRun ?? false;\n }\n\n async run(command: string, options: CommandRunnerOptions = {}): Promise<CommandResult> {\n if (this.dryRun) {\n return {\n stdout: '',\n stderr: '',\n exitCode: 0,\n command,\n dryRun: true,\n };\n }\n\n try {\n const result = await execa(command, {\n shell: true,\n cwd: options.cwd,\n timeout: options.timeout,\n env: options.env ? { ...process.env, ...options.env } : process.env,\n reject: false,\n });\n\n return {\n stdout: result.stdout ?? '',\n stderr: result.stderr ?? '',\n exitCode: result.exitCode ?? 1,\n command,\n dryRun: false,\n };\n } catch (err) {\n return {\n stdout: '',\n stderr: err instanceof Error ? err.message : String(err),\n exitCode: 1,\n command,\n dryRun: false,\n };\n }\n }\n}\n","import { execa } from 'execa';\nimport type { CommandRunner, CommandRunnerOptions, CommandResult } from '../types/common.js';\n\nexport class DockerExecutor implements CommandRunner {\n readonly dryRun: boolean;\n readonly environment = 'docker' as const;\n\n constructor(\n private readonly service: string,\n options: { dryRun?: boolean } = {},\n ) {\n this.dryRun = options.dryRun ?? false;\n }\n\n async run(command: string, options: CommandRunnerOptions = {}): Promise<CommandResult> {\n const dockerCommand = `docker-compose exec -T ${this.service} sh -c \"${command.replace(/\"/g, '\\\\\"')}\"`;\n\n if (this.dryRun) {\n return {\n stdout: '',\n stderr: '',\n exitCode: 0,\n command: dockerCommand,\n dryRun: true,\n };\n }\n\n try {\n const result = await execa(dockerCommand, {\n shell: true,\n cwd: options.cwd,\n timeout: options.timeout,\n env: options.env ? { ...process.env, ...options.env } : process.env,\n reject: false,\n });\n\n return {\n stdout: result.stdout ?? '',\n stderr: result.stderr ?? '',\n exitCode: result.exitCode ?? 1,\n command: dockerCommand,\n dryRun: false,\n };\n } catch (err) {\n return {\n stdout: '',\n stderr: err instanceof Error ? err.message : String(err),\n exitCode: 1,\n command: dockerCommand,\n dryRun: false,\n };\n }\n }\n}\n","import type { CommandRunner, ExecutionEnv } from '../types/common.js';\nimport { LocalExecutor } from '../executor/local-executor.js';\nimport { DockerExecutor } from '../executor/docker-executor.js';\nimport { logger } from '../utils/logger.js';\n\nexport async function detectEnvironment(\n preferredEnv: ExecutionEnv,\n dockerService: string,\n cwd: string,\n dryRun = false,\n): Promise<CommandRunner> {\n if (preferredEnv === 'local') {\n logger.debug('Using local execution (configured preference)');\n return new LocalExecutor({ dryRun });\n }\n\n // Try Docker\n const probe = new LocalExecutor();\n const result = await probe.run(\n `docker-compose ps ${dockerService} 2>/dev/null | grep -c \"Up\"`,\n { cwd },\n );\n\n if (result.exitCode === 0 && parseInt(result.stdout.trim(), 10) > 0) {\n logger.debug(`Using Docker execution (service: ${dockerService})`);\n return new DockerExecutor(dockerService, { dryRun });\n }\n\n logger.warn(`Docker service \"${dockerService}\" not running — falling back to local execution`);\n return new LocalExecutor({ dryRun });\n}\n"],"mappings":"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","names":["z","checkCurrentState","verifyResidualVulnerabilities","execa"]}
|
|
1
|
+
{"version":3,"sources":["../../src/config/loader.ts","../../src/config/schema.ts","../../src/utils/errors.ts","../../src/config/generator.ts","../../src/gates/validator.ts","../../src/utils/logger.ts","../../src/utils/osv-commands.ts","../../src/phases/scanner.ts","../../src/utils/git.ts","../../src/phases/npm-updater.ts","../../src/phases/composer-updater.ts","../../src/phases/orchestrator.ts","../../src/report/consolidated.ts","../../src/report/executive.ts","../../src/executor/local-executor.ts","../../src/executor/docker-executor.ts","../../src/environment/detector.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport { parse } from 'yaml';\nimport { ProjectConfigSchema } from './schema.js';\nimport type { ProjectConfig } from '../types/config.js';\nimport { ConfigLoadError } from '../utils/errors.js';\n\nexport const DEFAULT_CONFIG_PATH = 'project-config.yml';\n\nexport async function loadConfig(\n configPath: string,\n cwd: string = process.cwd(),\n): Promise<ProjectConfig> {\n const absolutePath = resolve(cwd, configPath);\n\n let raw: string;\n try {\n raw = await readFile(absolutePath, 'utf-8');\n } catch (err) {\n throw new ConfigLoadError(\n `Cannot read config file: ${absolutePath}`,\n absolutePath,\n );\n }\n\n let parsed: unknown;\n try {\n parsed = parse(raw);\n } catch (err) {\n throw new ConfigLoadError(\n `Invalid YAML in config file: ${absolutePath}`,\n absolutePath,\n );\n }\n\n const result = ProjectConfigSchema.safeParse(parsed);\n if (!result.success) {\n const issues = result.error.issues\n .map((i) => ` ${i.path.join('.')}: ${i.message}`)\n .join('\\n');\n throw new ConfigLoadError(\n `Config validation failed in ${absolutePath}:\\n${issues}`,\n absolutePath,\n );\n }\n\n return result.data;\n}\n","import { z } from 'zod';\n\nconst ProtectedPackageSchema = z.object({\n package: z.string(),\n constraint: z.string(),\n reason: z.string(),\n});\n\nconst RuntimeConfigSchema = z.object({\n php: z.string(),\n laravel: z.string(),\n node: z.string(),\n package_manager_php: z.string(),\n package_manager_js: z.string(),\n execution: z.enum(['docker', 'local']),\n docker_service: z.string(),\n docker_workdir: z.string().optional(),\n test_command: z.string(),\n build_commands: z.object({\n frontend: z.string(),\n backend: z.string(),\n }),\n});\n\nconst SafeUpdatePolicySchema = z.object({\n allow_patch_and_minor_within_constraints: z.boolean(),\n require_authorization_for_constraint_change: z.boolean(),\n authorization_format: z.string(),\n});\n\nexport const ProjectConfigSchema = z.object({\n project: z.object({\n name: z.string(),\n client: z.string(),\n }),\n runtime: RuntimeConfigSchema,\n protected_packages: z.object({\n composer: z.array(ProtectedPackageSchema),\n npm: z.array(ProtectedPackageSchema),\n }),\n safe_update_policy: SafeUpdatePolicySchema,\n conflict_resolution: z.string(),\n});\n\nexport type ProjectConfigInput = z.input<typeof ProjectConfigSchema>;\n","export class ConfigLoadError extends Error {\n constructor(message: string, public readonly path: string) {\n super(message);\n this.name = 'ConfigLoadError';\n }\n}\n\nexport class EnvironmentError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'EnvironmentError';\n }\n}\n\nexport class PhaseError extends Error {\n constructor(\n message: string,\n public readonly phase: string,\n public readonly cause?: unknown,\n ) {\n super(message);\n this.name = 'PhaseError';\n }\n}\n\nexport class GateValidationError extends Error {\n constructor(\n message: string,\n public readonly gate: 'A' | 'B' | 'C',\n public readonly errors: string[],\n ) {\n super(message);\n this.name = 'GateValidationError';\n }\n}\n","export interface GenerateConfigOptions {\n projectName?: string;\n client?: string;\n execution?: 'docker' | 'local';\n dockerService?: string;\n dockerWorkdir?: string;\n phpVersion?: string;\n laravelVersion?: string;\n nodeVersion?: string;\n testCommand?: string;\n frontendBuildCommand?: string;\n backendBuildCommand?: string;\n}\n\nexport function generateConfigYaml(opts: GenerateConfigOptions = {}): string {\n const projectName = opts.projectName ?? 'My Laravel Project';\n const client = opts.client ?? 'Client Name';\n const execution = opts.execution ?? 'docker';\n const dockerService = opts.dockerService ?? 'app';\n const dockerWorkdir = opts.dockerWorkdir;\n const phpVersion = opts.phpVersion ?? '8.2';\n const laravelVersion = opts.laravelVersion ?? '10.x';\n const nodeVersion = opts.nodeVersion ?? '20.x';\n const testCommand = opts.testCommand ?? 'php artisan test --compact';\n const frontendBuild = opts.frontendBuildCommand ?? 'npm run development-frontend';\n const backendBuild = opts.backendBuildCommand ?? 'npm run development-backend';\n\n const workdirLine = dockerWorkdir ? `\\n docker_workdir: '${dockerWorkdir}'` : '';\n\n return `# OSV Security CLI — project configuration\n# Generated by: osv-security init\n# Documentation: https://github.com/google/osv-scanner\n#\n# protected_packages: packages that must NEVER be auto-upgraded beyond their stated constraint.\n# Any update requiring a constraint change needs explicit per-package authorization.\n# safe_update_policy: patch/minor updates within existing constraints are auto-safe.\n\nproject:\n name: '${projectName}'\n client: '${client}'\n\nruntime:\n php: '${phpVersion}'\n laravel: '${laravelVersion}'\n node: '${nodeVersion}'\n package_manager_php: 'composer'\n package_manager_js: 'npm'\n execution: '${execution}'\n docker_service: '${dockerService}'${workdirLine}\n test_command: '${testCommand}'\n build_commands:\n frontend: '${frontendBuild}'\n backend: '${backendBuild}'\n\n# Add packages that must not be auto-upgraded beyond their constraint.\n# Examples:\n# composer:\n# - package: 'laravel/framework'\n# constraint: '^10.0'\n# reason: 'Major upgrade to Laravel 11 requires a dedicated project'\n# npm:\n# - package: 'tailwindcss'\n# constraint: '^3.3.3'\n# reason: 'Tailwind v4 has breaking config changes'\nprotected_packages:\n composer: []\n npm: []\n\nsafe_update_policy:\n allow_patch_and_minor_within_constraints: true\n require_authorization_for_constraint_change: true\n authorization_format: 'sim, confirmo breaking changes para [vendor/pacote]'\n\nconflict_resolution: 'stop_and_ask'\n`;\n}\n","import { z } from 'zod';\nimport type { GateResult } from '../types/common.js';\nimport type { ScanResultJson } from '../types/scan.js';\nimport type { UpdateResultJson } from '../types/update.js';\n\nconst EcosystemScanResultSchema = z.object({\n vulnerabilities_total: z.number(),\n auto_safe: z.number(),\n breaking: z.number(),\n manual: z.number(),\n auto_safe_packages: z.array(z.string()),\n breaking_packages: z.array(z.string()),\n manual_packages: z.array(z.string()),\n});\n\nconst ScanResultSchema = z.object({\n $schema: z.literal('osv-scan-result/v1'),\n agent: z.literal('osv-scanner'),\n status: z.enum(['success', 'error', 'skipped']),\n environment: z.enum(['docker', 'local']),\n php: EcosystemScanResultSchema,\n npm: EcosystemScanResultSchema,\n error: z.string().nullable(),\n});\n\nconst UpdateResultSchema = z.object({\n $schema: z.literal('osv-update-result/v1'),\n agent: z.enum(['composer-safe-update', 'npm-safe-update']),\n status: z.enum(['success', 'error', 'skipped']),\n packages_updated: z.array(z.string()),\n packages_skipped: z.array(z.string()),\n packages_pending_breaking: z.array(z.string()),\n tests: z.enum(['pass', 'fail', 'skipped']),\n tests_detail: z.string(),\n build_status: z.enum(['pass', 'fail', 'skipped']).optional(),\n build_detail: z.string().optional(),\n error: z.string().nullable(),\n});\n\nexport function validateGateA(data: unknown): GateResult {\n const result = ScanResultSchema.safeParse(data);\n if (!result.success) {\n return {\n valid: false,\n gate: 'A',\n errors: result.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`),\n };\n }\n if (result.data.status === 'error') {\n return {\n valid: false,\n gate: 'A',\n errors: [`Scanner returned error: ${result.data.error ?? 'unknown'}`],\n };\n }\n return { valid: true, gate: 'A', errors: [] };\n}\n\nexport function validateGateB(data: unknown): GateResult {\n const result = UpdateResultSchema.safeParse(data);\n if (!result.success) {\n return {\n valid: false,\n gate: 'B',\n errors: result.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`),\n };\n }\n if (result.data.agent !== 'npm-safe-update') {\n return {\n valid: false,\n gate: 'B',\n errors: [`Expected agent \"npm-safe-update\", got \"${result.data.agent}\"`],\n };\n }\n if (result.data.status === 'error') {\n return {\n valid: false,\n gate: 'B',\n errors: [`npm updater returned error: ${result.data.error ?? 'unknown'}`],\n };\n }\n return { valid: true, gate: 'B', errors: [] };\n}\n\nexport function validateGateC(data: unknown): GateResult {\n const result = UpdateResultSchema.safeParse(data);\n if (!result.success) {\n return {\n valid: false,\n gate: 'C',\n errors: result.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`),\n };\n }\n if (result.data.agent !== 'composer-safe-update') {\n return {\n valid: false,\n gate: 'C',\n errors: [`Expected agent \"composer-safe-update\", got \"${result.data.agent}\"`],\n };\n }\n if (result.data.status === 'error') {\n return {\n valid: false,\n gate: 'C',\n errors: [`Composer updater returned error: ${result.data.error ?? 'unknown'}`],\n };\n }\n return { valid: true, gate: 'C', errors: [] };\n}\n\nexport function validateScanResult(data: ScanResultJson): GateResult {\n return validateGateA(data);\n}\n\nexport function validateUpdateResult(\n data: UpdateResultJson,\n gate: 'B' | 'C',\n): GateResult {\n return gate === 'B' ? validateGateB(data) : validateGateC(data);\n}\n","export type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nconst LEVELS: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\nlet currentLevel: LogLevel = 'info';\n\nexport function setLogLevel(level: LogLevel): void {\n currentLevel = level;\n}\n\nfunction shouldLog(level: LogLevel): boolean {\n return LEVELS[level] >= LEVELS[currentLevel];\n}\n\nfunction format(level: LogLevel, message: string): string {\n const prefix: Record<LogLevel, string> = {\n debug: '[DEBUG]',\n info: '[INFO] ',\n warn: '[WARN] ',\n error: '[ERROR]',\n };\n return `${prefix[level]} ${message}`;\n}\n\nexport const logger = {\n debug(message: string): void {\n if (shouldLog('debug')) process.stderr.write(format('debug', message) + '\\n');\n },\n info(message: string): void {\n if (shouldLog('info')) process.stderr.write(format('info', message) + '\\n');\n },\n warn(message: string): void {\n if (shouldLog('warn')) process.stderr.write(format('warn', message) + '\\n');\n },\n error(message: string): void {\n if (shouldLog('error')) process.stderr.write(format('error', message) + '\\n');\n },\n};\n","export const OSV = {\n scanAll: 'osv-scanner --lockfile composer.lock --lockfile package-lock.json --format json',\n scanPhp: 'osv-scanner --lockfile composer.lock --format json',\n scanNpm: 'osv-scanner --lockfile package-lock.json --format json',\n fixNpm: 'osv-scanner fix --strategy=in-place -L package-lock.json',\n checkAvailable: 'osv-scanner --version',\n} as const;\n","import type { CommandRunner } from '../types/common.js';\nimport type { ProjectConfig } from '../types/config.js';\nimport type { ScanResultJson, EcosystemScanResult } from '../types/scan.js';\nimport { PhaseError, EnvironmentError } from '../utils/errors.js';\nimport { logger } from '../utils/logger.js';\nimport { OSV } from '../utils/osv-commands.js';\n\nfunction emptyEcosystem(): EcosystemScanResult {\n return {\n vulnerabilities_total: 0,\n auto_safe: 0,\n breaking: 0,\n manual: 0,\n auto_safe_packages: [],\n breaking_packages: [],\n manual_packages: [],\n };\n}\n\nfunction extractSafeVersion(\n vulnerabilities: Array<{\n affected?: Array<{ ranges?: Array<{ events?: Array<{ fixed?: string }> }> }>;\n }>,\n): string | null {\n for (const vuln of vulnerabilities) {\n for (const affected of vuln.affected ?? []) {\n for (const range of affected.ranges ?? []) {\n for (const event of range.events ?? []) {\n if (event.fixed) return event.fixed;\n }\n }\n }\n }\n return null;\n}\n\ntype OsvJsonOutput = {\n results?: Array<{\n packages?: Array<{\n package?: { name?: string; version?: string; ecosystem?: string };\n vulnerabilities?: Array<{\n affected?: Array<{ ranges?: Array<{ events?: Array<{ fixed?: string }> }> }>;\n }>;\n }>;\n }>;\n};\n\nfunction classifyPackageIntoEcosystem(\n pkgName: string,\n pkgVersion: string,\n ecosystem: string,\n safeVersion: string | null,\n protectedComposer: Set<string>,\n protectedNpm: Set<string>,\n php: EcosystemScanResult,\n npm: EcosystemScanResult,\n): void {\n const isPhp = ecosystem === 'packagist' || ecosystem === 'composer';\n const isNpm = ecosystem === 'npm';\n const target = isPhp ? php : isNpm ? npm : null;\n if (!target) return;\n\n const isProtected = (isPhp ? protectedComposer : protectedNpm).has(pkgName);\n const packageRef = `${pkgName}@${pkgVersion}`;\n\n target.vulnerabilities_total++;\n\n if (!safeVersion || isProtected) {\n target.breaking++;\n target.breaking_packages.push(packageRef);\n } else {\n target.auto_safe++;\n target.auto_safe_packages.push(packageRef);\n }\n}\n\nfunction parseOsvJsonOutput(\n stdout: string,\n config: ProjectConfig,\n): Pick<ScanResultJson, 'php' | 'npm'> {\n const data = JSON.parse(stdout) as OsvJsonOutput;\n const php = emptyEcosystem();\n const npm = emptyEcosystem();\n\n if (!data.results) return { php, npm };\n\n const protectedComposer = new Set(config.protected_packages.composer.map((p) => p.package));\n const protectedNpm = new Set(config.protected_packages.npm.map((p) => p.package));\n\n for (const result of data.results) {\n for (const pkg of result.packages ?? []) {\n const pkgName = pkg.package?.name ?? '';\n const pkgVersion = pkg.package?.version ?? '';\n const ecosystem = pkg.package?.ecosystem?.toLowerCase() ?? '';\n const safeVersion = extractSafeVersion(pkg.vulnerabilities ?? []);\n\n classifyPackageIntoEcosystem(\n pkgName, pkgVersion, ecosystem, safeVersion,\n protectedComposer, protectedNpm, php, npm,\n );\n }\n }\n\n return { php, npm };\n}\n\nasync function assertOsvScannerAvailable(runner: CommandRunner, cwd: string): Promise<void> {\n const result = await runner.run(OSV.checkAvailable, { cwd });\n if (result.exitCode !== 0) {\n throw new EnvironmentError(\n 'osv-scanner not found. Install it with: brew install osv-scanner (macOS) or see https://github.com/google/osv-scanner',\n );\n }\n}\n\nasync function executeScan(runner: CommandRunner, cwd: string) {\n logger.debug(`Running: ${OSV.scanAll}`);\n return runner.run(OSV.scanAll, { cwd });\n}\n\nexport async function runScanner(\n runner: CommandRunner,\n config: ProjectConfig,\n cwd: string,\n): Promise<ScanResultJson> {\n logger.info('Phase 1: Running OSV vulnerability scan...');\n\n const base: ScanResultJson = {\n $schema: 'osv-scan-result/v1',\n agent: 'osv-scanner',\n status: 'success',\n environment: runner.environment,\n php: emptyEcosystem(),\n npm: emptyEcosystem(),\n error: null,\n };\n\n try {\n await assertOsvScannerAvailable(runner, cwd);\n\n if (runner.dryRun) {\n logger.info(`[DRY-RUN] Would execute: ${OSV.scanAll}`);\n return base;\n }\n\n const scanResult = await executeScan(runner, cwd);\n\n if (scanResult.exitCode !== 0 && !scanResult.stdout) {\n return {\n ...base,\n status: 'error',\n error: `Scan failed (exit ${scanResult.exitCode}): ${scanResult.stderr}`,\n };\n }\n\n const parsed = parseOsvJsonOutput(scanResult.stdout, config);\n return { ...base, ...parsed };\n } catch (err) {\n if (err instanceof EnvironmentError) throw err;\n throw new PhaseError(\n `OSV scanner phase failed: ${err instanceof Error ? err.message : String(err)}`,\n 'scanner',\n err,\n );\n }\n}\n","import type { CommandRunner } from '../types/common.js';\n\nexport async function revertFiles(\n runner: CommandRunner,\n files: string[],\n cwd: string,\n): Promise<void> {\n if (files.length === 0) return;\n const fileList = files.join(' ');\n await runner.run(`git checkout -- ${fileList}`, { cwd });\n}\n\nexport async function isWorkingTreeClean(\n runner: CommandRunner,\n files: string[],\n cwd: string,\n): Promise<boolean> {\n const result = await runner.run(`git status --porcelain -- ${files.join(' ')}`, { cwd });\n return result.exitCode === 0 && result.stdout.trim() === '';\n}\n","import type { CommandRunner, CommandResult } from '../types/common.js';\nimport type { ProjectConfig } from '../types/config.js';\nimport type { UpdateResultJson } from '../types/update.js';\nimport type { ScanResultJson } from '../types/scan.js';\nimport { PhaseError } from '../utils/errors.js';\nimport { revertFiles, isWorkingTreeClean } from '../utils/git.js';\nimport { logger } from '../utils/logger.js';\nimport { OSV } from '../utils/osv-commands.js';\n\nconst NPM_FILES = ['package.json', 'package-lock.json'];\n\nasync function checkCurrentState(runner: CommandRunner, cwd: string): Promise<void> {\n logger.debug('Running npm outdated and npm audit (informational)...');\n await runner.run('npm outdated', { cwd });\n await runner.run('npm audit', { cwd });\n}\n\nasync function applyOsvFix(runner: CommandRunner, cwd: string): Promise<void> {\n logger.info(`Applying OSV in-place fix: ${OSV.fixNpm}`);\n const result = await runner.run(OSV.fixNpm, { cwd });\n if (result.exitCode !== 0) {\n logger.warn(`osv-scanner fix exited with ${result.exitCode}: ${result.stderr}`);\n }\n}\n\nasync function runNpmUpdate(runner: CommandRunner, cwd: string): Promise<CommandResult> {\n logger.info('Running npm update...');\n return runner.run('npm update', { cwd });\n}\n\nasync function validateBuilds(\n runner: CommandRunner,\n config: ProjectConfig,\n cwd: string,\n): Promise<{ frontend: CommandResult; backend: CommandResult }> {\n logger.info('Validating frontend build...');\n const frontend = await runner.run(config.runtime.build_commands.frontend, { cwd });\n logger.info('Validating backend build...');\n const backend = await runner.run(config.runtime.build_commands.backend, { cwd });\n return { frontend, backend };\n}\n\nasync function revertNpmChanges(runner: CommandRunner, cwd: string): Promise<void> {\n await revertFiles(runner, NPM_FILES, cwd);\n await runner.run('npm install', { cwd });\n}\n\nasync function verifyResidualVulnerabilities(runner: CommandRunner, cwd: string): Promise<void> {\n logger.info(`Running post-update OSV verification: ${OSV.scanNpm}`);\n await runner.run(OSV.scanNpm, { cwd });\n}\n\nexport async function runNpmUpdater(\n runner: CommandRunner,\n config: ProjectConfig,\n scanResult: ScanResultJson,\n cwd: string,\n): Promise<UpdateResultJson> {\n logger.info('Phase 2: Running npm safe updates...');\n\n const base: UpdateResultJson = {\n $schema: 'osv-update-result/v1',\n agent: 'npm-safe-update',\n status: 'success',\n packages_updated: [],\n packages_skipped: [],\n packages_pending_breaking: scanResult.npm.breaking_packages,\n tests: 'skipped',\n tests_detail: 'Build validated; unit tests not applicable to npm phase',\n build_status: 'skipped',\n build_detail: '',\n error: null,\n };\n\n if (runner.dryRun) {\n logger.info(`[DRY-RUN] Would execute: ${OSV.fixNpm}`);\n logger.info('[DRY-RUN] Would execute: npm update');\n logger.info(`[DRY-RUN] Would execute: ${config.runtime.build_commands.frontend}`);\n logger.info(`[DRY-RUN] Would execute: ${config.runtime.build_commands.backend}`);\n logger.info(`[DRY-RUN] Would execute: ${OSV.scanNpm}`);\n return { ...base, build_status: 'pass', build_detail: 'Dry-run — not executed' };\n }\n\n try {\n const isClean = await isWorkingTreeClean(runner, NPM_FILES, cwd);\n if (!isClean) {\n return {\n ...base,\n status: 'error',\n error: 'package.json or package-lock.json has uncommitted changes — aborting to prevent data loss on revert',\n };\n }\n\n await checkCurrentState(runner, cwd);\n await applyOsvFix(runner, cwd);\n\n const updateResult = await runNpmUpdate(runner, cwd);\n if (updateResult.exitCode !== 0) {\n return {\n ...base,\n status: 'error',\n build_status: 'fail',\n error: `npm update failed: ${updateResult.stderr}`,\n };\n }\n\n const { frontend, backend } = await validateBuilds(runner, config, cwd);\n\n if (frontend.exitCode !== 0) {\n logger.error('Frontend build failed — reverting...');\n await revertNpmChanges(runner, cwd);\n return {\n ...base,\n status: 'error',\n build_status: 'fail',\n build_detail: `Frontend build failed: ${frontend.stderr}`,\n error: 'Frontend build failed after npm update — changes reverted',\n };\n }\n\n if (backend.exitCode !== 0) {\n logger.error('Backend build failed — reverting...');\n await revertNpmChanges(runner, cwd);\n return {\n ...base,\n status: 'error',\n build_status: 'fail',\n build_detail: `Backend build failed: ${backend.stderr}`,\n error: 'Backend build failed after npm update — changes reverted',\n };\n }\n\n await verifyResidualVulnerabilities(runner, cwd);\n\n return {\n ...base,\n packages_updated: scanResult.npm.auto_safe_packages,\n build_status: 'pass',\n build_detail: 'Frontend and backend builds passed after update',\n };\n } catch (err) {\n throw new PhaseError(\n `npm updater phase failed: ${err instanceof Error ? err.message : String(err)}`,\n 'npm-updater',\n err,\n );\n }\n}\n","import type { CommandRunner, CommandResult } from '../types/common.js';\nimport type { ProjectConfig } from '../types/config.js';\nimport type { UpdateResultJson } from '../types/update.js';\nimport type { ScanResultJson } from '../types/scan.js';\nimport { PhaseError } from '../utils/errors.js';\nimport { revertFiles, isWorkingTreeClean } from '../utils/git.js';\nimport { logger } from '../utils/logger.js';\nimport { OSV } from '../utils/osv-commands.js';\n\nconst COMPOSER_FILES = ['composer.json', 'composer.lock'];\n\nfunction extractPackageNames(packageRefs: string[]): string[] {\n return packageRefs.map((ref) => {\n const atIndex = ref.lastIndexOf('@');\n return atIndex > 0 ? ref.slice(0, atIndex) : ref;\n });\n}\n\nasync function checkCurrentState(runner: CommandRunner, cwd: string): Promise<void> {\n logger.debug('Running composer outdated --direct (informational)...');\n await runner.run('composer outdated --direct', { cwd });\n}\n\nasync function applyComposerUpdate(\n runner: CommandRunner,\n packageNames: string[],\n cwd: string,\n): Promise<CommandResult> {\n const pkgList = packageNames.join(' ');\n logger.info(`Updating packages: ${pkgList}`);\n return runner.run(`composer update ${pkgList} --no-interaction`, { cwd });\n}\n\nasync function runTestSuite(\n runner: CommandRunner,\n testCommand: string,\n cwd: string,\n): Promise<CommandResult> {\n logger.info(`Running tests: ${testCommand}`);\n return runner.run(testCommand, { cwd });\n}\n\nasync function revertComposerChanges(runner: CommandRunner, cwd: string): Promise<void> {\n await revertFiles(runner, COMPOSER_FILES, cwd);\n await runner.run('composer install --no-interaction', { cwd });\n}\n\nasync function verifyResidualVulnerabilities(runner: CommandRunner, cwd: string): Promise<void> {\n logger.info(`Running post-update OSV verification: ${OSV.scanPhp}`);\n await runner.run(OSV.scanPhp, { cwd });\n}\n\nexport async function runComposerUpdater(\n runner: CommandRunner,\n config: ProjectConfig,\n scanResult: ScanResultJson,\n cwd: string,\n): Promise<UpdateResultJson> {\n logger.info('Phase 3: Running Composer safe updates...');\n\n const base: UpdateResultJson = {\n $schema: 'osv-update-result/v1',\n agent: 'composer-safe-update',\n status: 'success',\n packages_updated: [],\n packages_skipped: [],\n packages_pending_breaking: scanResult.php.breaking_packages,\n tests: 'skipped',\n tests_detail: '',\n error: null,\n };\n\n const autoSafePackageNames = extractPackageNames(scanResult.php.auto_safe_packages);\n\n if (autoSafePackageNames.length === 0) {\n return { ...base, tests_detail: 'No auto-safe packages to update' };\n }\n\n if (runner.dryRun) {\n logger.info(`[DRY-RUN] Would execute: composer update ${autoSafePackageNames.join(' ')} --no-interaction`);\n logger.info(`[DRY-RUN] Would execute: ${config.runtime.test_command}`);\n logger.info(`[DRY-RUN] Would execute: ${OSV.scanPhp}`);\n return {\n ...base,\n packages_updated: scanResult.php.auto_safe_packages,\n tests_detail: 'Dry-run — not executed',\n };\n }\n\n try {\n const isClean = await isWorkingTreeClean(runner, COMPOSER_FILES, cwd);\n if (!isClean) {\n return {\n ...base,\n status: 'error',\n error: 'composer.json or composer.lock has uncommitted changes — aborting to prevent data loss on revert',\n };\n }\n\n await checkCurrentState(runner, cwd);\n\n const updateResult = await applyComposerUpdate(runner, autoSafePackageNames, cwd);\n if (updateResult.exitCode !== 0) {\n return {\n ...base,\n status: 'error',\n tests: 'skipped',\n error: `composer update failed: ${updateResult.stderr}`,\n };\n }\n\n const testResult = await runTestSuite(runner, config.runtime.test_command, cwd);\n if (testResult.exitCode !== 0) {\n logger.error('Tests failed — reverting Composer updates...');\n await revertComposerChanges(runner, cwd);\n return {\n ...base,\n status: 'error',\n tests: 'fail',\n tests_detail: testResult.stdout || testResult.stderr,\n error: 'Tests failed after composer update — changes reverted',\n };\n }\n\n await verifyResidualVulnerabilities(runner, cwd);\n\n const testDetail = testResult.stdout.trim().split('\\n').slice(-2).join(' ');\n\n return {\n ...base,\n packages_updated: scanResult.php.auto_safe_packages,\n tests: 'pass',\n tests_detail: testDetail || 'Tests passed',\n };\n } catch (err) {\n throw new PhaseError(\n `Composer updater phase failed: ${err instanceof Error ? err.message : String(err)}`,\n 'composer-updater',\n err,\n );\n }\n}\n","import type { CommandRunner, PhaseStatus } from '../types/common.js';\nimport type { ProjectConfig } from '../types/config.js';\nimport type { ScanResultJson } from '../types/scan.js';\nimport type { UpdateResultJson } from '../types/update.js';\nimport { validateGateA, validateGateB, validateGateC } from '../gates/validator.js';\nimport { GateValidationError } from '../utils/errors.js';\nimport { logger } from '../utils/logger.js';\nimport { runScanner } from './scanner.js';\nimport { runNpmUpdater } from './npm-updater.js';\nimport { runComposerUpdater } from './composer-updater.js';\n\nexport interface OrchestratorOptions {\n configPath: string;\n cwd: string;\n dryRun: boolean;\n verbose: boolean;\n phases?: ('scan' | 'npm' | 'composer' | 'report')[];\n executiveReport?: {\n client: string;\n project: string;\n };\n}\n\nexport interface OrchestratorResult {\n scan: ScanResultJson | null;\n npmUpdate: UpdateResultJson | null;\n composerUpdate: UpdateResultJson | null;\n overallStatus: PhaseStatus;\n}\n\nfunction shouldRunPhase(\n phase: 'scan' | 'npm' | 'composer',\n options: OrchestratorOptions,\n): boolean {\n if (!options.phases) return true;\n return options.phases.includes(phase);\n}\n\nexport async function runOrchestrator(\n runner: CommandRunner,\n config: ProjectConfig,\n options: OrchestratorOptions,\n): Promise<OrchestratorResult> {\n const result: OrchestratorResult = {\n scan: null,\n npmUpdate: null,\n composerUpdate: null,\n overallStatus: 'success',\n };\n\n // Phase 1 — Scan (hard precondition)\n if (!shouldRunPhase('scan', options)) {\n logger.warn('Skipping scan phase — phases option does not include \"scan\"');\n result.overallStatus = 'skipped';\n return result;\n }\n\n logger.info('=== Phase 1: Vulnerability Scan ===');\n const scanResult = await runScanner(runner, config, options.cwd);\n result.scan = scanResult;\n\n // Gate A validation\n const gateA = validateGateA(scanResult);\n if (!gateA.valid) {\n throw new GateValidationError(\n `Gate A validation failed: ${gateA.errors.join(', ')}`,\n 'A',\n gateA.errors,\n );\n }\n\n logger.info(\n `Scan complete: ${scanResult.php.vulnerabilities_total} PHP vulns ` +\n `(${scanResult.php.auto_safe} auto-safe, ${scanResult.php.breaking} breaking), ` +\n `${scanResult.npm.vulnerabilities_total} npm vulns ` +\n `(${scanResult.npm.auto_safe} auto-safe, ${scanResult.npm.breaking} breaking)`,\n );\n\n // Check if any updates are needed\n const hasNpmUpdates = scanResult.npm.auto_safe > 0;\n const hasPhpUpdates = scanResult.php.auto_safe > 0;\n\n if (!hasNpmUpdates && !hasPhpUpdates) {\n logger.info('No auto-safe vulnerabilities found — no updates needed');\n return result;\n }\n\n // Phase 2 — npm remediation\n if (shouldRunPhase('npm', options) && hasNpmUpdates) {\n logger.info('=== Phase 2: npm Safe Updates ===');\n const npmResult = await runNpmUpdater(runner, config, scanResult, options.cwd);\n result.npmUpdate = npmResult;\n\n // Gate B validation\n const gateB = validateGateB(npmResult);\n if (!gateB.valid) {\n throw new GateValidationError(\n `Gate B validation failed: ${gateB.errors.join(', ')}`,\n 'B',\n gateB.errors,\n );\n }\n\n if (npmResult.build_status === 'fail') {\n logger.error('npm build failed — stopping before Composer phase');\n result.overallStatus = 'error';\n return result;\n }\n\n logger.info(\n `npm update complete: ${npmResult.packages_updated.length} packages updated`,\n );\n } else if (!hasNpmUpdates) {\n logger.info('Phase 2: Skipping npm update — no auto-safe npm vulnerabilities');\n }\n\n // Phase 3 — Composer remediation\n if (shouldRunPhase('composer', options) && hasPhpUpdates) {\n logger.info('=== Phase 3: Composer Safe Updates ===');\n const composerResult = await runComposerUpdater(runner, config, scanResult, options.cwd);\n result.composerUpdate = composerResult;\n\n // Gate C validation\n const gateC = validateGateC(composerResult);\n if (!gateC.valid) {\n throw new GateValidationError(\n `Gate C validation failed: ${gateC.errors.join(', ')}`,\n 'C',\n gateC.errors,\n );\n }\n\n if (composerResult.tests === 'fail') {\n logger.error('Composer tests failed — workflow stopped');\n result.overallStatus = 'error';\n return result;\n }\n\n logger.info(\n `Composer update complete: ${composerResult.packages_updated.length} packages updated`,\n );\n } else if (!hasPhpUpdates) {\n logger.info('Phase 3: Skipping Composer update — no auto-safe PHP vulnerabilities');\n }\n\n // Check if there are pending items\n const hasPendingItems =\n scanResult.php.breaking > 0 ||\n scanResult.npm.breaking > 0 ||\n scanResult.php.manual > 0 ||\n scanResult.npm.manual > 0;\n\n if (hasPendingItems) {\n result.overallStatus = 'error'; // exit code 1: vulns remain\n }\n\n return result;\n}\n","import type { ConsolidatedReport } from '../types/report.js';\n\nexport function generateConsolidatedReport(data: ConsolidatedReport): string {\n const lines: string[] = [];\n\n lines.push(`# Security Report — ${data.projectName}`);\n lines.push(`**Date:** ${data.date}`);\n lines.push(`**Environment:** ${data.environment}`);\n lines.push('');\n\n // Vulnerabilities found\n lines.push('## Vulnerabilities Found');\n const scan = data.scan;\n const totalVulns = scan.php.vulnerabilities_total + scan.npm.vulnerabilities_total;\n lines.push(`- **Total:** ${totalVulns}`);\n lines.push(\n `- **PHP (auto-safe/breaking/manual):** ${scan.php.auto_safe}/${scan.php.breaking}/${scan.php.manual}`,\n );\n lines.push(\n `- **npm (auto-safe/breaking/manual):** ${scan.npm.auto_safe}/${scan.npm.breaking}/${scan.npm.manual}`,\n );\n lines.push('');\n\n // Fixes applied\n lines.push('## Fixes Applied');\n\n if (data.npmUpdate && data.npmUpdate.packages_updated.length > 0) {\n lines.push('### npm');\n for (const pkg of data.npmUpdate.packages_updated) {\n lines.push(`- ${pkg}`);\n }\n } else {\n lines.push('### npm');\n lines.push('- No packages updated');\n }\n lines.push('');\n\n if (data.composerUpdate && data.composerUpdate.packages_updated.length > 0) {\n lines.push('### Composer (PHP)');\n for (const pkg of data.composerUpdate.packages_updated) {\n lines.push(`- ${pkg}`);\n }\n } else {\n lines.push('### Composer (PHP)');\n lines.push('- No packages updated');\n }\n lines.push('');\n\n // Validation results\n lines.push('## Validation After Updates');\n if (data.composerUpdate) {\n const testStatus = data.composerUpdate.tests === 'pass' ? '✅ PASS' : data.composerUpdate.tests === 'fail' ? '❌ FAIL' : '— skipped';\n lines.push(`- PHP test suite: ${testStatus}`);\n if (data.composerUpdate.tests_detail) {\n lines.push(` ${data.composerUpdate.tests_detail}`);\n }\n }\n if (data.npmUpdate) {\n const buildStatus = data.npmUpdate.build_status === 'pass' ? '✅ PASS' : data.npmUpdate.build_status === 'fail' ? '❌ FAIL' : '— skipped';\n lines.push(`- npm build: ${buildStatus}`);\n if (data.npmUpdate.build_detail) {\n lines.push(` ${data.npmUpdate.build_detail}`);\n }\n }\n lines.push('');\n\n // Pending items\n const pendingBreaking = [\n ...scan.php.breaking_packages.map((p) => `[PHP] ${p}`),\n ...scan.npm.breaking_packages.map((p) => `[npm] ${p}`),\n ];\n const pendingManual = [\n ...scan.php.manual_packages.map((p) => `[PHP] ${p}`),\n ...scan.npm.manual_packages.map((p) => `[npm] ${p}`),\n ];\n\n if (pendingBreaking.length > 0 || pendingManual.length > 0) {\n lines.push('## Pending — Require Manual Action');\n\n if (pendingBreaking.length > 0) {\n lines.push('### Require BREAKING CHANGE (awaiting per-package authorization)');\n for (const pkg of pendingBreaking) {\n lines.push(`- ${pkg}`);\n lines.push(\n ` To authorize: \"sim, confirmo breaking changes para [package]\"`,\n );\n }\n lines.push('');\n }\n\n if (pendingManual.length > 0) {\n lines.push('### No safe version within current constraint');\n for (const pkg of pendingManual) {\n lines.push(`- ${pkg}`);\n }\n lines.push('');\n }\n }\n\n return lines.join('\\n');\n}\n","import type { ExecutiveReportOptions } from '../types/report.js';\n\nfunction monthName(date: Date): string {\n return date.toLocaleString('en-US', { month: 'long' });\n}\n\nfunction monthNamePt(date: Date): string {\n const months = [\n 'Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho',\n 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro',\n ];\n return months[date.getMonth()]!;\n}\n\nfunction zeroPad(n: number): string {\n return String(n).padStart(2, '0');\n}\n\nexport function generateExecutiveReport(opts: ExecutiveReportOptions): string {\n const now = new Date();\n const year = now.getFullYear();\n const month = zeroPad(now.getMonth() + 1);\n const monthFull = monthNamePt(now);\n\n const npmFixed = opts.npmUpdate?.packages_updated ?? [];\n const composerFixed = opts.composerUpdate?.packages_updated ?? [];\n const allFixed = [...composerFixed.map((p) => ({ type: 'Composer', pkg: p })), ...npmFixed.map((p) => ({ type: 'npm', pkg: p }))];\n\n const npmBreaking = opts.scanBefore.npm.breaking_packages;\n const phpBreaking = opts.scanBefore.php.breaking_packages;\n const allPending = [\n ...phpBreaking.map((p) => ({ type: 'Composer', pkg: p })),\n ...npmBreaking.map((p) => ({ type: 'npm', pkg: p })),\n ];\n\n const hasFixed = allFixed.length > 0;\n const hasPending = allPending.length > 0;\n const noneFound =\n opts.scanBefore.php.vulnerabilities_total === 0 &&\n opts.scanBefore.npm.vulnerabilities_total === 0;\n\n const lines: string[] = [];\n\n lines.push(`Cliente: ${opts.client}`);\n lines.push(`Projeto: ${opts.project}`);\n lines.push(`Período: ${monthFull} ${year}`);\n lines.push('');\n lines.push('---');\n lines.push('');\n lines.push('Tarefa');\n lines.push('');\n lines.push('Manutenção de Segurança — OSV Scanner (rotina mensal)');\n lines.push('');\n lines.push(\n 'Verificação mensal das dependências instaladas (PHP/Composer e npm) para identificar pacotes com vulnerabilidades conhecidas e aplicar correções disponíveis.',\n );\n lines.push('');\n lines.push('---');\n lines.push('');\n lines.push('Resolução');\n lines.push('');\n\n if (noneFound) {\n lines.push(\n 'Nenhuma vulnerabilidade foi identificada nas dependências PHP ou npm. O projeto está atualizado e seguro.',\n );\n } else if (hasFixed) {\n lines.push(\n 'Após a execução da varredura, os seguintes problemas foram encontrados e corrigidos:',\n );\n lines.push('');\n lines.push(\n '| Tipo | Pacote | Versão Corrigida | Risco |',\n );\n lines.push('|------|--------|-----------------|-------|');\n for (const { type, pkg } of allFixed) {\n lines.push(`| ${type} | ${pkg} | — | — |`);\n }\n }\n\n if (hasPending) {\n lines.push('');\n lines.push(\n 'As seguintes vulnerabilidades não puderam ser corrigidas automaticamente e permanecem pendentes:',\n );\n lines.push('');\n lines.push('| Tipo | Pacote | Versão Atual | Motivo |');\n lines.push('|------|--------|-------------|--------|');\n for (const { type, pkg } of allPending) {\n lines.push(`| ${type} | ${pkg} | — | Requer mudança disruptiva |`);\n }\n }\n\n lines.push('');\n lines.push('---');\n lines.push('');\n lines.push('Resumo');\n lines.push('');\n\n if (noneFound) {\n lines.push(\n 'Nenhuma vulnerabilidade foi identificada nas dependências PHP ou npm. O projeto está atualizado e seguro.',\n );\n } else if (hasFixed && !hasPending) {\n lines.push(\n 'Todas as vulnerabilidades identificadas foram corrigidas. O projeto está atualizado e seguro em relação às suas dependências.',\n );\n } else if (hasFixed && hasPending) {\n lines.push(\n 'Todas as vulnerabilidades que puderam ser corrigidas sem mudanças disruptivas foram aplicadas. Os itens listados acima requerem avaliação ou autorização de versão principal.',\n );\n } else {\n lines.push(\n 'Vulnerabilidades identificadas requerem ação manual — nenhuma correção automática foi aplicada.',\n );\n }\n\n return lines.join('\\n');\n}\n\nexport function executiveReportFilename(client: string, project: string): string {\n const now = new Date();\n const year = now.getFullYear();\n const month = String(now.getMonth() + 1).padStart(2, '0');\n const monthEn = monthName(now);\n return `[${client} ${project}] Report OSV Scanner - ${year}-${month} - ${monthEn}.md`;\n}\n","import { execa } from 'execa';\nimport type { CommandRunner, CommandRunnerOptions, CommandResult } from '../types/common.js';\n\nexport class LocalExecutor implements CommandRunner {\n readonly dryRun: boolean;\n readonly environment = 'local' as const;\n\n constructor(options: { dryRun?: boolean } = {}) {\n this.dryRun = options.dryRun ?? false;\n }\n\n async run(command: string, options: CommandRunnerOptions = {}): Promise<CommandResult> {\n if (this.dryRun) {\n return {\n stdout: '',\n stderr: '',\n exitCode: 0,\n command,\n dryRun: true,\n };\n }\n\n try {\n const result = await execa(command, {\n shell: true,\n cwd: options.cwd,\n timeout: options.timeout,\n env: options.env ? { ...process.env, ...options.env } : process.env,\n reject: false,\n });\n\n return {\n stdout: result.stdout ?? '',\n stderr: result.stderr ?? '',\n exitCode: result.exitCode ?? 1,\n command,\n dryRun: false,\n };\n } catch (err) {\n return {\n stdout: '',\n stderr: err instanceof Error ? err.message : String(err),\n exitCode: 1,\n command,\n dryRun: false,\n };\n }\n }\n}\n","import { execa } from 'execa';\nimport type { CommandRunner, CommandRunnerOptions, CommandResult } from '../types/common.js';\n\nexport class DockerExecutor implements CommandRunner {\n readonly dryRun: boolean;\n readonly environment = 'docker' as const;\n\n constructor(\n private readonly service: string,\n options: { dryRun?: boolean; workdir?: string } = {},\n ) {\n this.dryRun = options.dryRun ?? false;\n this.workdir = options.workdir;\n }\n\n private readonly workdir?: string;\n\n private buildDockerCommand(command: string): string {\n const workdirFlag = this.workdir ? `--workdir ${this.workdir} ` : '';\n return `docker-compose exec -T ${workdirFlag}${this.service} sh -c \"${command.replace(/\"/g, '\\\\\"')}\"`;\n }\n\n async run(command: string, options: CommandRunnerOptions = {}): Promise<CommandResult> {\n const dockerCommand = this.buildDockerCommand(command);\n\n if (this.dryRun) {\n return { stdout: '', stderr: '', exitCode: 0, command: dockerCommand, dryRun: true };\n }\n\n try {\n const result = await execa(dockerCommand, {\n shell: true,\n cwd: options.cwd,\n timeout: options.timeout,\n env: options.env ? { ...process.env, ...options.env } : process.env,\n reject: false,\n });\n\n return {\n stdout: result.stdout ?? '',\n stderr: result.stderr ?? '',\n exitCode: result.exitCode ?? 1,\n command: dockerCommand,\n dryRun: false,\n };\n } catch (err) {\n return {\n stdout: '',\n stderr: err instanceof Error ? err.message : String(err),\n exitCode: 1,\n command: dockerCommand,\n dryRun: false,\n };\n }\n }\n}\n","import type { CommandRunner, ExecutionEnv } from '../types/common.js';\nimport { LocalExecutor } from '../executor/local-executor.js';\nimport { DockerExecutor } from '../executor/docker-executor.js';\nimport { logger } from '../utils/logger.js';\n\nexport async function detectEnvironment(\n preferredEnv: ExecutionEnv,\n dockerService: string,\n cwd: string,\n dryRun = false,\n dockerWorkdir?: string,\n): Promise<CommandRunner> {\n if (preferredEnv === 'local') {\n logger.debug('Using local execution (configured preference)');\n return new LocalExecutor({ dryRun });\n }\n\n const probe = new LocalExecutor();\n const result = await probe.run(\n `docker-compose ps ${dockerService} 2>/dev/null | grep -c \"Up\"`,\n { cwd },\n );\n\n if (result.exitCode === 0 && parseInt(result.stdout.trim(), 10) > 0) {\n const workdirInfo = dockerWorkdir ? ` (workdir: ${dockerWorkdir})` : '';\n logger.debug(`Using Docker execution (service: ${dockerService}${workdirInfo})`);\n return new DockerExecutor(dockerService, { dryRun, workdir: dockerWorkdir });\n }\n\n logger.warn(`Docker service \"${dockerService}\" not running — falling back to local execution`);\n return new LocalExecutor({ dryRun });\n}\n"],"mappings":"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","names":["z","checkCurrentState","verifyResidualVulnerabilities","execa"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "osv-security-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "CLI tool for automated OSV vulnerability scanning and safe dependency updates",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -39,4 +39,4 @@
|
|
|
39
39
|
"typescript": "^5.5.4",
|
|
40
40
|
"vitest": "^2.0.5"
|
|
41
41
|
}
|
|
42
|
-
}
|
|
42
|
+
}
|