codex-orchestrator 0.1.19 → 0.1.21
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/README.md +132 -33
- package/dist/src/codex/command-adapter.d.ts +3 -0
- package/dist/src/codex/command-adapter.d.ts.map +1 -1
- package/dist/src/codex/command-adapter.js +18 -7
- package/dist/src/codex/command-adapter.js.map +1 -1
- package/dist/src/config/schema.d.ts +3 -0
- package/dist/src/config/schema.d.ts.map +1 -1
- package/dist/src/config/schema.js +3 -0
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/git/worktree.d.ts +17 -0
- package/dist/src/git/worktree.d.ts.map +1 -1
- package/dist/src/git/worktree.js +35 -2
- package/dist/src/git/worktree.js.map +1 -1
- package/dist/src/github/gh-issue-adapter.js +6 -3
- package/dist/src/github/gh-issue-adapter.js.map +1 -1
- package/dist/src/github/issues.d.ts +1 -1
- package/dist/src/github/issues.d.ts.map +1 -1
- package/dist/src/index.d.ts +6 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/path-policy.d.ts +27 -0
- package/dist/src/path-policy.d.ts.map +1 -0
- package/dist/src/path-policy.js +83 -0
- package/dist/src/path-policy.js.map +1 -0
- package/dist/src/process/command.d.ts +3 -0
- package/dist/src/process/command.d.ts.map +1 -1
- package/dist/src/process/command.js +59 -9
- package/dist/src/process/command.js.map +1 -1
- package/dist/src/runner/command-utils.d.ts +5 -0
- package/dist/src/runner/command-utils.d.ts.map +1 -1
- package/dist/src/runner/command-utils.js +46 -1
- package/dist/src/runner/command-utils.js.map +1 -1
- package/dist/src/runner/completion-report.d.ts +54 -0
- package/dist/src/runner/completion-report.d.ts.map +1 -0
- package/dist/src/runner/completion-report.js +220 -0
- package/dist/src/runner/completion-report.js.map +1 -0
- package/dist/src/runner/handoff-evidence.d.ts +105 -0
- package/dist/src/runner/handoff-evidence.d.ts.map +1 -0
- package/dist/src/runner/handoff-evidence.js +224 -0
- package/dist/src/runner/handoff-evidence.js.map +1 -0
- package/dist/src/runner/issue-tree.d.ts +4 -1
- package/dist/src/runner/issue-tree.d.ts.map +1 -1
- package/dist/src/runner/issue-tree.js +75 -0
- package/dist/src/runner/issue-tree.js.map +1 -1
- package/dist/src/runner/local-execution-session.d.ts +79 -0
- package/dist/src/runner/local-execution-session.d.ts.map +1 -0
- package/dist/src/runner/local-execution-session.js +236 -0
- package/dist/src/runner/local-execution-session.js.map +1 -0
- package/dist/src/runner/local-state.d.ts +1 -0
- package/dist/src/runner/local-state.d.ts.map +1 -1
- package/dist/src/runner/local-state.js +2 -1
- package/dist/src/runner/local-state.js.map +1 -1
- package/dist/src/runner/plan-auto-command.d.ts +1 -0
- package/dist/src/runner/plan-auto-command.d.ts.map +1 -1
- package/dist/src/runner/plan-auto-command.js +143 -302
- package/dist/src/runner/plan-auto-command.js.map +1 -1
- package/dist/src/runner/prompt.d.ts +2 -53
- package/dist/src/runner/prompt.d.ts.map +1 -1
- package/dist/src/runner/prompt.js +20 -265
- package/dist/src/runner/prompt.js.map +1 -1
- package/dist/src/runner/review-gate-policy.d.ts +24 -0
- package/dist/src/runner/review-gate-policy.d.ts.map +1 -0
- package/dist/src/runner/review-gate-policy.js +104 -0
- package/dist/src/runner/review-gate-policy.js.map +1 -0
- package/dist/src/runner/review-gates.d.ts +4 -9
- package/dist/src/runner/review-gates.d.ts.map +1 -1
- package/dist/src/runner/review-gates.js +17 -63
- package/dist/src/runner/review-gates.js.map +1 -1
- package/dist/src/runner/run-log.d.ts +18 -0
- package/dist/src/runner/run-log.d.ts.map +1 -0
- package/dist/src/runner/run-log.js +53 -0
- package/dist/src/runner/run-log.js.map +1 -0
- package/dist/src/runner/safety.d.ts +1 -1
- package/dist/src/runner/safety.d.ts.map +1 -1
- package/dist/src/runner/safety.js +5 -20
- package/dist/src/runner/safety.js.map +1 -1
- package/dist/src/runner/scoped-auto-command.d.ts +4 -0
- package/dist/src/runner/scoped-auto-command.d.ts.map +1 -1
- package/dist/src/runner/scoped-auto-command.js +70 -172
- package/dist/src/runner/scoped-auto-command.js.map +1 -1
- package/dist/src/runner/visual-proof-runner.d.ts +3 -8
- package/dist/src/runner/visual-proof-runner.d.ts.map +1 -1
- package/dist/src/runner/visual-proof-runner.js +71 -17
- package/dist/src/runner/visual-proof-runner.js.map +1 -1
- package/dist/src/setup/project-config.d.ts.map +1 -1
- package/dist/src/setup/project-config.js +5 -0
- package/dist/src/setup/project-config.js.map +1 -1
- package/dist/src/setup/setup-command.d.ts.map +1 -1
- package/dist/src/setup/setup-command.js +42 -0
- package/dist/src/setup/setup-command.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { globMatches } from '../path-policy.js';
|
|
2
|
+
export function buildVisualProofPromptLines(config, issueNumber) {
|
|
3
|
+
const command = config.reviewGates.visualProof.runnerValidationCommand?.trim();
|
|
4
|
+
if (!command) {
|
|
5
|
+
return [
|
|
6
|
+
'For visual/UI work, use the BrowserUse/browser plugin when it is available in the session. If it is unavailable, state that explicitly in skippedChecks instead of claiming visual validation.',
|
|
7
|
+
`For visual/UI work, save screenshot proof files under ${config.reviewGates.visualProof.artifactDir}/issue-${issueNumber}/ and include them as screenshot artifacts.`,
|
|
8
|
+
];
|
|
9
|
+
}
|
|
10
|
+
const envNames = config.reviewGates.visualProof.envPassthrough ?? [];
|
|
11
|
+
const loginEnvLine = envNames.length > 0
|
|
12
|
+
? `The runner visual proof command will receive these project environment variables when they exist: ${envNames.join(', ')}. Use them for login if authentication is required; never hardcode credentials.`
|
|
13
|
+
: 'If authentication is required, make the visual proof script read credentials from environment variables configured in reviewGates.visualProof.envPassthrough; never hardcode credentials.';
|
|
14
|
+
return [
|
|
15
|
+
`For visual/UI work, prepare screenshot proof files under ${config.reviewGates.visualProof.artifactDir}/issue-${issueNumber}/ and include them as screenshot artifacts when you create them.`,
|
|
16
|
+
`After your run, the runner will execute this visual proof command outside the child Codex sandbox: ${command}.`,
|
|
17
|
+
'Prepare any project files this command needs, but do not execute this runner-owned command yourself or start long-lived browser/dev-server proof loops from child Codex.',
|
|
18
|
+
'Do not open BrowserUse, Playwright, or any other browser from the child Codex session when this runner-owned visual proof command is configured.',
|
|
19
|
+
'When this runner-owned proof command can validate the visual behavior, treat it as the primary visual proof path.',
|
|
20
|
+
'Do not report BrowserUse or browser unavailability as a skipped check or residual risk when the runner-owned proof command is prepared.',
|
|
21
|
+
'For UI layout fixes, a focused visual proof script with concrete assertions can be the TDD evidence when regular unit tests cannot observe the layout.',
|
|
22
|
+
'Do not claim the runner-owned visual proof passed; the runner will append the passed/failed result after your run.',
|
|
23
|
+
'The runner will expose CODEX_ORCHESTRATOR_PLAYWRIGHT_PROFILE_DIR for proof scripts that need a stable Playwright user data directory.',
|
|
24
|
+
loginEnvLine,
|
|
25
|
+
'If required login environment variables are missing, the visual proof script must fail with a short clear error.',
|
|
26
|
+
];
|
|
27
|
+
}
|
|
28
|
+
export function buildQualityGatePromptLines(config) {
|
|
29
|
+
const quality = config.reviewGates.quality;
|
|
30
|
+
if (!quality.enabled) {
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
return [
|
|
34
|
+
'## Quality Gate Contract',
|
|
35
|
+
'For runtime behavior changes, use strict TDD red-to-green: write one focused behavior test first, prove the test fails before implementation, then make the smallest implementation that passes after implementation.',
|
|
36
|
+
'Report TDD as a passed validation line that includes failing/red and passing/green evidence. Do not batch many tests before implementation.',
|
|
37
|
+
`Runtime files are detected with these globs: ${quality.runtimeChangedPathGlobs.join(', ')}.`,
|
|
38
|
+
`Test files are detected with these globs: ${quality.testChangedPathGlobs.join(', ')}.`,
|
|
39
|
+
'Run code-review before completion for runtime changes and report it as a passed validation line.',
|
|
40
|
+
`Run cleanup-review before code-review when the runtime change touches at least ${quality.cleanupReview.runtimeFileThreshold} runtime files, and report it as a passed validation line.`,
|
|
41
|
+
];
|
|
42
|
+
}
|
|
43
|
+
export function shouldApplyVisualProofGate(input) {
|
|
44
|
+
const visualProof = input.config.reviewGates.visualProof;
|
|
45
|
+
if (!visualProof.enabled) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
const issueText = `${input.issue.title}\n${input.issue.body}`;
|
|
49
|
+
const issueLooksVisual = visualProof.issueTextPatterns.some((pattern) => regexMatches(pattern, issueText));
|
|
50
|
+
const changedUiFiles = input.changedFiles.filter((path) => visualProof.changedPathGlobs.some((pattern) => globMatches(pattern, path)));
|
|
51
|
+
return issueLooksVisual || changedUiFiles.length > 0;
|
|
52
|
+
}
|
|
53
|
+
export function hasPassedValidation(validation, patterns) {
|
|
54
|
+
return validation.some((line) => line.status === 'passed' && patterns.some((pattern) => regexMatches(pattern, validationText(line))));
|
|
55
|
+
}
|
|
56
|
+
export function hasPassedTddValidation(validation, patterns) {
|
|
57
|
+
if (validation.some((line) => line.status === 'passed'
|
|
58
|
+
&& !hasMissingTddProofText(validationText(line))
|
|
59
|
+
&& patterns.some((pattern) => regexMatches(pattern, validationText(line))))) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
const passedTexts = validation
|
|
63
|
+
.filter((line) => line.status === 'passed')
|
|
64
|
+
.map(validationText)
|
|
65
|
+
.filter((text) => !hasMissingTddProofText(text));
|
|
66
|
+
const hasRedEvidence = passedTexts.some(hasTddRedEvidence);
|
|
67
|
+
const hasGreenEvidence = passedTexts.some(hasTddGreenEvidence);
|
|
68
|
+
return hasRedEvidence && hasGreenEvidence;
|
|
69
|
+
}
|
|
70
|
+
export function validationText(line) {
|
|
71
|
+
return `${line.command}\n${line.summary}`;
|
|
72
|
+
}
|
|
73
|
+
export function isStrongVisualValidation(line) {
|
|
74
|
+
return /(BrowserUse|Playwright|screenshot|viewport)/iu.test(validationText(line));
|
|
75
|
+
}
|
|
76
|
+
export function isRunnerVisualValidation(line) {
|
|
77
|
+
return /runner visual proof/iu.test(validationText(line));
|
|
78
|
+
}
|
|
79
|
+
export function regexMatches(pattern, text) {
|
|
80
|
+
return new RegExp(pattern, 'iu').test(text);
|
|
81
|
+
}
|
|
82
|
+
export function runnerVisualProofPolicy(config) {
|
|
83
|
+
const visualProof = config.reviewGates.visualProof;
|
|
84
|
+
return {
|
|
85
|
+
commandTemplate: visualProof.runnerValidationCommand?.trim() || undefined,
|
|
86
|
+
artifactDir: visualProof.artifactDir,
|
|
87
|
+
envPassthrough: visualProof.envPassthrough ?? [],
|
|
88
|
+
timeoutMs: visualProof.runnerTimeoutMs,
|
|
89
|
+
minScreenshotArtifacts: visualProof.minScreenshotArtifacts,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function hasTddRedEvidence(text) {
|
|
93
|
+
return /\bred\s*:/iu.test(text) || /\b(?:test|spec|check)\b[\s\S]{0,120}\bfail(?:ed|ing)?\b/iu.test(text);
|
|
94
|
+
}
|
|
95
|
+
function hasTddGreenEvidence(text) {
|
|
96
|
+
return /\bgreen\s*:/iu.test(text)
|
|
97
|
+
|| /\b(?:test|spec|jest|vitest|playwright|pytest)\b[\s\S]{0,120}\bpass(?:ed|ing)?\b/iu.test(text)
|
|
98
|
+
|| /\b(?:flutter|dart|npm|pnpm|yarn)\s+(?:run\s+)?test\b[\s\S]{0,120}\bpass(?:ed|ing)?\b/iu.test(text);
|
|
99
|
+
}
|
|
100
|
+
function hasMissingTddProofText(text) {
|
|
101
|
+
return /\b(?:without|missing|no|lack(?:s|ing)?)\b[\s\S]{0,40}\bred[-\s]?green\b/iu.test(text)
|
|
102
|
+
|| /\bred[-\s]?green\b[\s\S]{0,40}\b(?:missing|without|no|lack(?:s|ing)?)\b/iu.test(text);
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=review-gate-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-gate-policy.js","sourceRoot":"","sources":["../../../src/runner/review-gate-policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
import type { CodexOrchestratorConfig } from '../config/schema.js';
|
|
2
2
|
import type { GitHubIssue } from '../github/issues.js';
|
|
3
|
-
import type { ScopedCompletionReport } from './
|
|
4
|
-
|
|
5
|
-
command: string;
|
|
6
|
-
status: 'passed' | 'failed' | 'skipped';
|
|
7
|
-
summary: string;
|
|
8
|
-
}
|
|
3
|
+
import type { ScopedCompletionReport } from './completion-report.js';
|
|
4
|
+
import type { RunnerValidationLine } from './handoff-evidence.js';
|
|
9
5
|
export interface ReviewGateInput {
|
|
10
6
|
config: CodexOrchestratorConfig;
|
|
11
7
|
issue: GitHubIssue;
|
|
12
8
|
changedFiles: string[];
|
|
13
|
-
validation:
|
|
9
|
+
validation: RunnerValidationLine[];
|
|
14
10
|
skippedChecks: string[];
|
|
15
11
|
report: ScopedCompletionReport;
|
|
16
12
|
worktreePath?: string;
|
|
@@ -19,7 +15,6 @@ export interface ReviewGateResult {
|
|
|
19
15
|
ok: boolean;
|
|
20
16
|
reasons: string[];
|
|
21
17
|
}
|
|
22
|
-
export
|
|
18
|
+
export { shouldApplyVisualProofGate } from './review-gate-policy.js';
|
|
23
19
|
export declare function evaluateReviewGates(input: ReviewGateInput): ReviewGateResult;
|
|
24
|
-
export {};
|
|
25
20
|
//# sourceMappingURL=review-gates.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review-gates.d.ts","sourceRoot":"","sources":["../../../src/runner/review-gates.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"review-gates.d.ts","sourceRoot":"","sources":["../../../src/runner/review-gates.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAMvD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAWlE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,uBAAuB,CAAC;IAChC,KAAK,EAAE,WAAW,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,EAAE,oBAAoB,EAAE,CAAC;IACnC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,MAAM,EAAE,sBAAsB,CAAC;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AAErE,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,eAAe,GAAG,gBAAgB,CA8D5E"}
|
|
@@ -1,15 +1,8 @@
|
|
|
1
1
|
import { existsSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
return false;
|
|
7
|
-
}
|
|
8
|
-
const issueText = `${input.issue.title}\n${input.issue.body}`;
|
|
9
|
-
const issueLooksVisual = visualProof.issueTextPatterns.some((pattern) => regexMatches(pattern, issueText));
|
|
10
|
-
const changedUiFiles = input.changedFiles.filter((path) => visualProof.changedPathGlobs.some((pattern) => globMatches(pattern, normalizePath(path))));
|
|
11
|
-
return issueLooksVisual || changedUiFiles.length > 0;
|
|
12
|
-
}
|
|
3
|
+
import { acceptsScreenshotArtifactPath, classifyChangedPaths, isRunnerVisualProofCodeArtifactPath, } from '../path-policy.js';
|
|
4
|
+
import { hasPassedTddValidation, hasPassedValidation, isRunnerVisualValidation, isStrongVisualValidation, regexMatches, shouldApplyVisualProofGate, validationText, } from './review-gate-policy.js';
|
|
5
|
+
export { shouldApplyVisualProofGate } from './review-gate-policy.js';
|
|
13
6
|
export function evaluateReviewGates(input) {
|
|
14
7
|
const reasons = [];
|
|
15
8
|
reasons.push(...evaluateQualityGate(input));
|
|
@@ -35,13 +28,14 @@ export function evaluateReviewGates(input) {
|
|
|
35
28
|
if (!artifact.path) {
|
|
36
29
|
return false;
|
|
37
30
|
}
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
31
|
+
const worktreePath = input.worktreePath;
|
|
32
|
+
return acceptsScreenshotArtifactPath({
|
|
33
|
+
artifactPath: artifact.path,
|
|
34
|
+
artifactDir: visualProof.artifactDir,
|
|
35
|
+
changedFiles: input.changedFiles,
|
|
36
|
+
hasPassedRunnerVisualValidation,
|
|
37
|
+
exists: worktreePath ? (path) => existsSync(join(worktreePath, path)) : undefined,
|
|
38
|
+
});
|
|
45
39
|
});
|
|
46
40
|
if (!hasPassedVisualValidation) {
|
|
47
41
|
reasons.push('Visual proof gate requires a passed BrowserUse/Playwright/screenshot validation line.');
|
|
@@ -65,19 +59,16 @@ function evaluateQualityGate(input) {
|
|
|
65
59
|
if (!quality.enabled) {
|
|
66
60
|
return [];
|
|
67
61
|
}
|
|
68
|
-
const runtimeFiles = input.changedFiles
|
|
69
|
-
.
|
|
70
|
-
|
|
71
|
-
|
|
62
|
+
const { runtimeFiles, testFiles } = classifyChangedPaths(input.changedFiles, {
|
|
63
|
+
runtimeChangedPathGlobs: quality.runtimeChangedPathGlobs,
|
|
64
|
+
testChangedPathGlobs: quality.testChangedPathGlobs,
|
|
65
|
+
});
|
|
72
66
|
if (runtimeFiles.length === 0) {
|
|
73
67
|
return [];
|
|
74
68
|
}
|
|
75
69
|
const reasons = [];
|
|
76
|
-
const testFiles = input.changedFiles
|
|
77
|
-
.map(normalizePath)
|
|
78
|
-
.filter((path) => quality.testChangedPathGlobs.some((pattern) => globMatches(pattern, path)));
|
|
79
70
|
if (quality.tdd.enabled) {
|
|
80
|
-
const hasTddValidation =
|
|
71
|
+
const hasTddValidation = hasPassedTddValidation(input.validation, quality.tdd.requiredValidationPatterns);
|
|
81
72
|
const hasRunnerVisualProofEvidence = hasPassedRunnerVisualProofEvidence(input);
|
|
82
73
|
if (quality.tdd.requireTestChange && testFiles.length === 0 && !hasRunnerVisualProofEvidence) {
|
|
83
74
|
reasons.push('Quality gate requires TDD test file change for runtime changes.');
|
|
@@ -100,18 +91,6 @@ function evaluateQualityGate(input) {
|
|
|
100
91
|
}
|
|
101
92
|
return reasons;
|
|
102
93
|
}
|
|
103
|
-
function hasPassedValidation(validation, patterns) {
|
|
104
|
-
return validation.some((line) => line.status === 'passed' && patterns.some((pattern) => regexMatches(pattern, validationText(line))));
|
|
105
|
-
}
|
|
106
|
-
function validationText(line) {
|
|
107
|
-
return `${line.command}\n${line.summary}`;
|
|
108
|
-
}
|
|
109
|
-
function isStrongVisualValidation(line) {
|
|
110
|
-
return /(BrowserUse|Playwright|screenshot|viewport)/iu.test(validationText(line));
|
|
111
|
-
}
|
|
112
|
-
function isRunnerVisualValidation(line) {
|
|
113
|
-
return /runner visual proof/iu.test(validationText(line));
|
|
114
|
-
}
|
|
115
94
|
function hasPassedRunnerVisualProofEvidence(input) {
|
|
116
95
|
if (!shouldApplyVisualProofGate(input)) {
|
|
117
96
|
return false;
|
|
@@ -122,33 +101,8 @@ function hasPassedRunnerVisualProofEvidence(input) {
|
|
|
122
101
|
if (!hasPassedRunnerProof) {
|
|
123
102
|
return false;
|
|
124
103
|
}
|
|
125
|
-
const artifactDir = normalizePath(input.config.reviewGates.visualProof.artifactDir);
|
|
126
104
|
return input.changedFiles.some((file) => {
|
|
127
|
-
|
|
128
|
-
return globMatches(`${artifactDir}/**`, path) && /\.(?:cjs|js|mjs|ts|tsx)$/iu.test(path);
|
|
105
|
+
return isRunnerVisualProofCodeArtifactPath(file, input.config.reviewGates.visualProof.artifactDir);
|
|
129
106
|
});
|
|
130
107
|
}
|
|
131
|
-
function regexMatches(pattern, text) {
|
|
132
|
-
return new RegExp(pattern, 'iu').test(text);
|
|
133
|
-
}
|
|
134
|
-
function globMatches(pattern, path) {
|
|
135
|
-
const escaped = normalizePath(pattern)
|
|
136
|
-
.split('/')
|
|
137
|
-
.map((segment) => {
|
|
138
|
-
if (segment === '**') {
|
|
139
|
-
return '.*';
|
|
140
|
-
}
|
|
141
|
-
return segment
|
|
142
|
-
.replace(/[.+?^${}()|[\]\\]/g, '\\$&')
|
|
143
|
-
.replaceAll('*', '[^/]*');
|
|
144
|
-
})
|
|
145
|
-
.join('/');
|
|
146
|
-
return new RegExp(`^${escaped}$`).test(normalizePath(path));
|
|
147
|
-
}
|
|
148
|
-
function normalizePath(path) {
|
|
149
|
-
return path.replaceAll('\\', '/').replace(/^\.\//, '');
|
|
150
|
-
}
|
|
151
|
-
function changedPathCovers(changedPath, artifactPath) {
|
|
152
|
-
return changedPath === artifactPath || artifactPath.startsWith(changedPath.replace(/\/?$/, '/'));
|
|
153
|
-
}
|
|
154
108
|
//# sourceMappingURL=review-gates.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review-gates.js","sourceRoot":"","sources":["../../../src/runner/review-gates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"review-gates.js","sourceRoot":"","sources":["../../../src/runner/review-gates.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { CodexOrchestratorConfig } from '../config/schema.js';
|
|
2
|
+
export declare function sessionLogPath(input: {
|
|
3
|
+
targetRoot: string;
|
|
4
|
+
config: CodexOrchestratorConfig;
|
|
5
|
+
issueNumber: number;
|
|
6
|
+
sessionId: string;
|
|
7
|
+
}): string;
|
|
8
|
+
export declare class RunLogWriter {
|
|
9
|
+
private readonly logPath;
|
|
10
|
+
constructor(logPath: string);
|
|
11
|
+
appendStdout(chunk: string): Promise<void>;
|
|
12
|
+
appendStderr(chunk: string): Promise<void>;
|
|
13
|
+
appendLifecycle(message: string): Promise<void>;
|
|
14
|
+
close(): Promise<void>;
|
|
15
|
+
private append;
|
|
16
|
+
}
|
|
17
|
+
export declare function renderCodexStreamChunk(chunk: string, stream: 'stdout' | 'stderr'): string[];
|
|
18
|
+
//# sourceMappingURL=run-log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-log.d.ts","sourceRoot":"","sources":["../../../src/runner/run-log.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAEnE,wBAAgB,cAAc,CAAC,KAAK,EAAE;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,uBAAuB,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,MAAM,CAOT;AAED,qBAAa,YAAY;IACJ,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,MAAM;IAEtC,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAIrB,MAAM;CAIrB;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,EAAE,CAE3F"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { appendFile, mkdir } from 'node:fs/promises';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
export function sessionLogPath(input) {
|
|
4
|
+
return join(input.targetRoot, input.config.runner.stateDir, 'logs', `issue-${input.issueNumber}-${input.sessionId}.log`);
|
|
5
|
+
}
|
|
6
|
+
export class RunLogWriter {
|
|
7
|
+
logPath;
|
|
8
|
+
constructor(logPath) {
|
|
9
|
+
this.logPath = logPath;
|
|
10
|
+
}
|
|
11
|
+
async appendStdout(chunk) {
|
|
12
|
+
await this.append(renderCodexStreamChunk(chunk, 'stdout').join(''));
|
|
13
|
+
}
|
|
14
|
+
async appendStderr(chunk) {
|
|
15
|
+
await this.append(renderCodexStreamChunk(chunk, 'stderr').join(''));
|
|
16
|
+
}
|
|
17
|
+
async appendLifecycle(message) {
|
|
18
|
+
await this.append(`[lifecycle] ${message}\n`);
|
|
19
|
+
}
|
|
20
|
+
async close() {
|
|
21
|
+
await this.appendLifecycle('log closed');
|
|
22
|
+
}
|
|
23
|
+
async append(content) {
|
|
24
|
+
await mkdir(dirname(this.logPath), { recursive: true });
|
|
25
|
+
await appendFile(this.logPath, content, 'utf8');
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export function renderCodexStreamChunk(chunk, stream) {
|
|
29
|
+
return chunk.split(/(?<=\n)/u).filter((line) => line.length > 0).map((line) => renderCodexStreamLine(line, stream));
|
|
30
|
+
}
|
|
31
|
+
function renderCodexStreamLine(line, stream) {
|
|
32
|
+
const trimmed = line.trim();
|
|
33
|
+
if (!trimmed.startsWith('{') || !trimmed.endsWith('}')) {
|
|
34
|
+
return `[${stream}] ${line}`;
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const parsed = JSON.parse(trimmed);
|
|
38
|
+
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
|
|
39
|
+
return `[${stream}] ${line}`;
|
|
40
|
+
}
|
|
41
|
+
const record = parsed;
|
|
42
|
+
const eventType = readString(record.type) ?? readString(record.event) ?? 'codex-event';
|
|
43
|
+
const text = readString(record.message) ?? readString(record.delta) ?? readString(record.text);
|
|
44
|
+
return text ? `[${stream}] ${eventType}: ${text}\n` : `[${stream}] ${eventType}: ${trimmed}\n`;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return `[${stream}] ${line}`;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function readString(value) {
|
|
51
|
+
return typeof value === 'string' && value.length > 0 ? value : undefined;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=run-log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-log.js","sourceRoot":"","sources":["../../../src/runner/run-log.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CodexOrchestratorConfig } from '../config/schema.js';
|
|
2
|
-
import type { ScopedCompletionReport } from './
|
|
2
|
+
import type { ScopedCompletionReport } from './completion-report.js';
|
|
3
3
|
export type SafetyViolationCode = 'secret-file-change' | 'secret-file-read' | 'destructive-db-or-cache' | 'production-deploy-or-release' | 'agent-owned-git-publication';
|
|
4
4
|
export interface SafetyViolation {
|
|
5
5
|
code: SafetyViolationCode;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"safety.d.ts","sourceRoot":"","sources":["../../../src/runner/safety.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"safety.d.ts","sourceRoot":"","sources":["../../../src/runner/safety.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAEnE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAErE,MAAM,MAAM,mBAAmB,GAC3B,oBAAoB,GACpB,kBAAkB,GAClB,yBAAyB,GACzB,8BAA8B,GAC9B,6BAA6B,CAAC;AAElC,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,uBAAuB,GAAG,eAAe,EAAE,CAQxG;AAED,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,sBAAsB,GAAG,eAAe,EAAE,CAKhG;AAED,wBAAgB,kCAAkC,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,eAAe,EAAE,CAU3G"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
import { findDeniedPathMatch } from '../path-policy.js';
|
|
1
2
|
/**
|
|
2
3
|
* Supports exact path literals, `*` within one path segment, and `**` across path segments.
|
|
3
4
|
*/
|
|
4
5
|
export function validateChangedPaths(paths, config) {
|
|
5
6
|
const patterns = [...config.deny.secretFiles, ...config.deny.additionalPathGlobs];
|
|
6
7
|
return paths.flatMap((path) => {
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
const matched = findDeniedPathMatch(path, patterns);
|
|
9
|
+
return matched
|
|
10
|
+
? [{ code: 'secret-file-change', message: `Changed path ${matched.path} matches denied pattern ${matched.pattern}` }]
|
|
11
|
+
: [];
|
|
10
12
|
});
|
|
11
13
|
}
|
|
12
14
|
export function validateCompletionReportSafety(report) {
|
|
@@ -26,21 +28,4 @@ export function validateNoAgentOwnedGitPublication(beforeHead, afterHead) {
|
|
|
26
28
|
}
|
|
27
29
|
return [];
|
|
28
30
|
}
|
|
29
|
-
function globMatches(pattern, path) {
|
|
30
|
-
const escaped = pattern
|
|
31
|
-
.split('/')
|
|
32
|
-
.map((segment) => {
|
|
33
|
-
if (segment === '**') {
|
|
34
|
-
return '.*';
|
|
35
|
-
}
|
|
36
|
-
return segment
|
|
37
|
-
.replace(/[.+?^${}()|[\]\\]/g, '\\$&')
|
|
38
|
-
.replaceAll('*', '[^/]*');
|
|
39
|
-
})
|
|
40
|
-
.join('/');
|
|
41
|
-
return new RegExp(`^${escaped}$`).test(path);
|
|
42
|
-
}
|
|
43
|
-
function normalizePath(path) {
|
|
44
|
-
return path.replaceAll('\\', '/').replace(/^\.\//, '');
|
|
45
|
-
}
|
|
46
31
|
//# sourceMappingURL=safety.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"safety.js","sourceRoot":"","sources":["../../../src/runner/safety.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"safety.js","sourceRoot":"","sources":["../../../src/runner/safety.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAexD;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAe,EAAE,MAA+B;IACnF,MAAM,QAAQ,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAClF,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QAC5B,MAAM,OAAO,GAAG,mBAAmB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACpD,OAAO,OAAO;YACZ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,oBAA6B,EAAE,OAAO,EAAE,gBAAgB,OAAO,CAAC,IAAI,2BAA2B,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YAC9H,CAAC,CAAC,EAAE,CAAC;IACT,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,8BAA8B,CAAC,MAA8B;IAC3E,OAAO,MAAM,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC/C,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,OAAO,EAAE,MAAM,CAAC,WAAW;KAC5B,CAAC,CAAC,CAAC;AACN,CAAC;AAED,MAAM,UAAU,kCAAkC,CAAC,UAAkB,EAAE,SAAiB;IACtF,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO;YACL;gBACE,IAAI,EAAE,6BAA6B;gBACnC,OAAO,EAAE,+DAA+D;aACzE;SACF,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC"}
|
|
@@ -3,6 +3,7 @@ import type { GitHubIssueAdapter } from '../github/issues.js';
|
|
|
3
3
|
import type { GitHubPullRequest, GitHubPullRequestAdapter } from '../github/pull-requests.js';
|
|
4
4
|
import { GitWorktreeManager } from '../git/worktree.js';
|
|
5
5
|
import { type ShellCommandExecutor } from '../process/command.js';
|
|
6
|
+
import { type LocalExecutionPhaseExecutor } from './local-execution-session.js';
|
|
6
7
|
export interface ScopedAutoCommandOptions {
|
|
7
8
|
targetRoot: string;
|
|
8
9
|
issueNumber: number;
|
|
@@ -12,6 +13,8 @@ export interface ScopedAutoCommandOptions {
|
|
|
12
13
|
codexAdapter?: {
|
|
13
14
|
run(input: CodexCommandRunInput): Promise<CodexCommandRunResult>;
|
|
14
15
|
};
|
|
16
|
+
localPhases?: string[];
|
|
17
|
+
localPhaseExecutor?: LocalExecutionPhaseExecutor;
|
|
15
18
|
shellExecutor?: ShellCommandExecutor;
|
|
16
19
|
now?: Date;
|
|
17
20
|
}
|
|
@@ -21,6 +24,7 @@ export interface ScopedAutoCommandResult {
|
|
|
21
24
|
worktreePath: string;
|
|
22
25
|
promptPath: string;
|
|
23
26
|
reportPath: string;
|
|
27
|
+
logPath: string;
|
|
24
28
|
pullRequest?: GitHubPullRequest;
|
|
25
29
|
status: 'review-ready' | 'blocked' | 'promotion-requested';
|
|
26
30
|
reportComment: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scoped-auto-command.d.ts","sourceRoot":"","sources":["../../../src/runner/scoped-auto-command.ts"],"names":[],"mappings":"AAGA,OAAO,EAAuB,KAAK,oBAAoB,EAAE,KAAK,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAIzH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"scoped-auto-command.d.ts","sourceRoot":"","sources":["../../../src/runner/scoped-auto-command.ts"],"names":[],"mappings":"AAGA,OAAO,EAAuB,KAAK,oBAAoB,EAAE,KAAK,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAIzH,OAAO,KAAK,EAAe,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAC9F,OAAO,EAAE,kBAAkB,EAAwB,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAA+B,KAAK,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAa/F,OAAO,EAEL,KAAK,2BAA2B,EACjC,MAAM,8BAA8B,CAAC;AAWtC,MAAM,WAAW,wBAAwB;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC,kBAAkB,CAAC,EAAE,wBAAwB,CAAC;IAC9C,GAAG,CAAC,EAAE,kBAAkB,CAAC;IACzB,YAAY,CAAC,EAAE;QAAE,GAAG,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAA;KAAE,CAAC;IACpF,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,kBAAkB,CAAC,EAAE,2BAA2B,CAAC;IACjD,aAAa,CAAC,EAAE,oBAAoB,CAAC;IACrC,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,MAAM,EAAE,cAAc,GAAG,SAAS,GAAG,qBAAqB,CAAC;IAC3D,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAqM9G"}
|