@pedyc/harness-core 1.0.1 → 1.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/LICENSE +21 -21
- package/README.md +55 -48
- package/dist/adapters/provider-runner.d.ts +18 -0
- package/dist/adapters/provider-runner.d.ts.map +1 -0
- package/dist/adapters/provider-runner.js +45 -0
- package/dist/adapters/provider-runner.js.map +1 -0
- package/dist/contracts/agent.d.ts +79 -0
- package/dist/contracts/agent.d.ts.map +1 -0
- package/dist/contracts/agent.js +2 -0
- package/dist/contracts/agent.js.map +1 -0
- package/dist/contracts/index.d.ts +7 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +2 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/contracts/policy.d.ts +30 -0
- package/dist/contracts/policy.d.ts.map +1 -0
- package/dist/contracts/policy.js +2 -0
- package/dist/contracts/policy.js.map +1 -0
- package/dist/contracts/preset.d.ts +27 -0
- package/dist/contracts/preset.d.ts.map +1 -0
- package/dist/contracts/preset.js +2 -0
- package/dist/contracts/preset.js.map +1 -0
- package/dist/contracts/run.d.ts +41 -0
- package/dist/contracts/run.d.ts.map +1 -0
- package/dist/contracts/run.js +2 -0
- package/dist/contracts/run.js.map +1 -0
- package/dist/contracts/task.d.ts +35 -0
- package/dist/contracts/task.d.ts.map +1 -0
- package/dist/contracts/task.js +2 -0
- package/dist/contracts/task.js.map +1 -0
- package/dist/contracts/validation.d.ts +7 -0
- package/dist/contracts/validation.d.ts.map +1 -0
- package/dist/contracts/validation.js +2 -0
- package/dist/contracts/validation.js.map +1 -0
- package/dist/core/agent.d.ts +22 -0
- package/dist/core/agent.d.ts.map +1 -0
- package/dist/core/agent.js +47 -0
- package/dist/core/agent.js.map +1 -0
- package/dist/core/approval-gate.d.ts +17 -0
- package/dist/core/approval-gate.d.ts.map +1 -0
- package/dist/core/approval-gate.js +18 -0
- package/dist/core/approval-gate.js.map +1 -0
- package/dist/core/command.d.ts +14 -0
- package/dist/core/command.d.ts.map +1 -0
- package/dist/core/command.js +33 -0
- package/dist/core/command.js.map +1 -0
- package/dist/core/diff-inspector.d.ts +7 -0
- package/dist/core/diff-inspector.d.ts.map +1 -0
- package/dist/core/diff-inspector.js +27 -0
- package/dist/core/diff-inspector.js.map +1 -0
- package/dist/core/executor.d.ts +21 -0
- package/dist/core/executor.d.ts.map +1 -0
- package/dist/core/executor.js +142 -0
- package/dist/core/executor.js.map +1 -0
- package/dist/core/intake.d.ts +11 -0
- package/dist/core/intake.d.ts.map +1 -0
- package/dist/core/intake.js +33 -0
- package/dist/core/intake.js.map +1 -0
- package/dist/core/package-manager.d.ts +14 -0
- package/dist/core/package-manager.d.ts.map +1 -0
- package/dist/core/package-manager.js +20 -0
- package/dist/core/package-manager.js.map +1 -0
- package/dist/core/policy-engine.d.ts +14 -0
- package/dist/core/policy-engine.d.ts.map +1 -0
- package/dist/core/policy-engine.js +29 -0
- package/dist/core/policy-engine.js.map +1 -0
- package/dist/core/validator.d.ts +25 -0
- package/dist/core/validator.d.ts.map +1 -0
- package/dist/core/validator.js +24 -0
- package/dist/core/validator.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/package.json +50 -13
- package/src/agent.mjs +0 -27
- package/src/command.mjs +0 -28
- package/src/index.mjs +0 -11
- package/src/intake.mjs +0 -23
- package/src/orchestrator.mjs +0 -119
- package/src/package-manager.mjs +0 -17
- package/src/policy.mjs +0 -19
- package/src/provider.mjs +0 -32
- package/src/schema.mjs +0 -24
- package/src/snapshots.mjs +0 -20
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval-gate.d.ts","sourceRoot":"","sources":["../../src/core/approval-gate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAE/E;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GACzB,cAAc,iBAAiB,EAAE,EACjC,cAAc,eAAe,KAC5B,OAGwC,CAAA;AAE3C;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GAC3B,UAAU,eAAe,EACzB,mBAAmB,MAAM,EAAE,KAC1B,OACmF,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether the tester stage may pass.
|
|
3
|
+
*
|
|
4
|
+
* Two independent conditions: every configured gate actually passed, and the
|
|
5
|
+
* tester agent approved the evidence it was handed. A run never passes on the
|
|
6
|
+
* coder's own claim.
|
|
7
|
+
*/
|
|
8
|
+
export const testerApproved = (verification, externalTest) => verification.every((check) => check.result === 'pass')
|
|
9
|
+
&& externalTest.ok
|
|
10
|
+
&& externalTest.payload.approved === true;
|
|
11
|
+
/**
|
|
12
|
+
* Whether the reviewer stage may pass.
|
|
13
|
+
*
|
|
14
|
+
* Scope is checked here rather than trusted to the agent: any out-of-scope file
|
|
15
|
+
* rejects the change even when the reviewer approves it.
|
|
16
|
+
*/
|
|
17
|
+
export const reviewerApproved = (reviewer, outOfScopeChanges) => reviewer.ok && reviewer.payload?.approved === true && outOfScopeChanges.length === 0;
|
|
18
|
+
//# sourceMappingURL=approval-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval-gate.js","sourceRoot":"","sources":["../../src/core/approval-gate.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,YAAiC,EACjC,YAA6B,EACpB,EAAE,CACX,YAAY,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC;OACnD,YAAY,CAAC,EAAE;OACf,YAAY,CAAC,OAAO,CAAC,QAAQ,KAAK,IAAI,CAAA;AAE3C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,QAAyB,EACzB,iBAA2B,EAClB,EAAE,CACX,QAAQ,CAAC,EAAE,IAAI,QAAQ,CAAC,OAAO,EAAE,QAAQ,KAAK,IAAI,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** The outcome of one spawned process. */
|
|
2
|
+
export interface CommandResult {
|
|
3
|
+
code: number;
|
|
4
|
+
stdout: string;
|
|
5
|
+
stderr: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Runs a command in `root` and resolves with its exit code and output.
|
|
9
|
+
*
|
|
10
|
+
* Failures resolve rather than reject: a non-zero exit is a normal result that
|
|
11
|
+
* the orchestrator records as evidence.
|
|
12
|
+
*/
|
|
13
|
+
export declare const runCommand: (root: string, command: string, args?: string[], stdin?: unknown) => Promise<CommandResult>;
|
|
14
|
+
//# sourceMappingURL=command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/core/command.ts"],"names":[],"mappings":"AAEA,0CAA0C;AAC1C,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf;AAcD;;;;;GAKG;AACH,eAAO,MAAM,UAAU,GACrB,MAAM,MAAM,EACZ,SAAS,MAAM,EACf,OAAM,MAAM,EAAO,EACnB,QAAO,OAAc,KACpB,OAAO,CAAC,aAAa,CActB,CAAA"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
// Windows resolves these through .cmd shims, which spawn cannot find by bare name.
|
|
3
|
+
const normalizeCommand = (command) => {
|
|
4
|
+
if (process.platform === 'win32'
|
|
5
|
+
&& ['npm', 'npx', 'pnpm', 'yarn'].includes(command)
|
|
6
|
+
&& !command.endsWith('.cmd')) {
|
|
7
|
+
return `${command}.cmd`;
|
|
8
|
+
}
|
|
9
|
+
return command;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Runs a command in `root` and resolves with its exit code and output.
|
|
13
|
+
*
|
|
14
|
+
* Failures resolve rather than reject: a non-zero exit is a normal result that
|
|
15
|
+
* the orchestrator records as evidence.
|
|
16
|
+
*/
|
|
17
|
+
export const runCommand = (root, command, args = [], stdin = null) => new Promise((resolve) => {
|
|
18
|
+
const child = spawn(normalizeCommand(command), args, {
|
|
19
|
+
cwd: root,
|
|
20
|
+
shell: process.platform === 'win32',
|
|
21
|
+
windowsHide: true,
|
|
22
|
+
});
|
|
23
|
+
let stdout = '';
|
|
24
|
+
let stderr = '';
|
|
25
|
+
child.stdout.on('data', (chunk) => { stdout += chunk; });
|
|
26
|
+
child.stderr.on('data', (chunk) => { stderr += chunk; });
|
|
27
|
+
child.on('close', (code) => resolve({ code: code ?? 1, stdout, stderr }));
|
|
28
|
+
child.on('error', (error) => resolve({ code: 1, stdout, stderr: error.message }));
|
|
29
|
+
if (stdin !== null)
|
|
30
|
+
child.stdin.write(`${JSON.stringify(stdin)}\n`);
|
|
31
|
+
child.stdin.end();
|
|
32
|
+
});
|
|
33
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/core/command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAS1C,mFAAmF;AACnF,MAAM,gBAAgB,GAAG,CAAC,OAAe,EAAU,EAAE;IACnD,IACE,OAAO,CAAC,QAAQ,KAAK,OAAO;WACzB,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;WAChD,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAC5B,CAAC;QACD,OAAO,GAAG,OAAO,MAAM,CAAA;IACzB,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,IAAY,EACZ,OAAe,EACf,OAAiB,EAAE,EACnB,QAAiB,IAAI,EACG,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;IACnD,MAAM,KAAK,GAAG,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE;QACnD,GAAG,EAAE,IAAI;QACT,KAAK,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO;QACnC,WAAW,EAAE,IAAI;KAClB,CAAC,CAAA;IACF,IAAI,MAAM,GAAG,EAAE,CAAA;IACf,IAAI,MAAM,GAAG,EAAE,CAAA;IACf,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,GAAG,MAAM,IAAI,KAAK,CAAA,CAAC,CAAC,CAAC,CAAA;IACvD,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,GAAG,MAAM,IAAI,KAAK,CAAA,CAAC,CAAC,CAAC,CAAA;IACvD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;IACzE,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;IACjF,IAAI,KAAK,KAAK,IAAI;QAAE,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACnE,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,CAAA;AACnB,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** File contents keyed by repository-relative POSIX path. */
|
|
2
|
+
export type FileSnapshot = Map<string, string>;
|
|
3
|
+
/** Captures every product file's contents so a later snapshot can be compared. */
|
|
4
|
+
export declare const snapshotFiles: (root: string) => FileSnapshot;
|
|
5
|
+
/** Names the files that were added, removed or modified between two snapshots. */
|
|
6
|
+
export declare const changedFiles: (before: FileSnapshot, after: FileSnapshot) => string[];
|
|
7
|
+
//# sourceMappingURL=diff-inspector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-inspector.d.ts","sourceRoot":"","sources":["../../src/core/diff-inspector.ts"],"names":[],"mappings":"AAGA,6DAA6D;AAC7D,MAAM,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAmB9C,kFAAkF;AAClF,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,KAAG,YAC2C,CAAA;AAExF,kFAAkF;AAClF,eAAO,MAAM,YAAY,GAAI,QAAQ,YAAY,EAAE,OAAO,YAAY,KAAG,MAAM,EAEqB,CAAA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
|
2
|
+
import { join, relative } from 'node:path';
|
|
3
|
+
// Build output and installed dependencies are never part of a product change,
|
|
4
|
+
// so these directories are skipped at every depth. Restricting the check to the
|
|
5
|
+
// root would make a monorepo snapshot every dependency under `pkg/node_modules`
|
|
6
|
+
// and every build artifact under `pkg/dist`.
|
|
7
|
+
const ignoredDirectories = ['node_modules', 'dist', '.git'];
|
|
8
|
+
const listFiles = (root, directory = root, result = []) => {
|
|
9
|
+
if (!existsSync(directory))
|
|
10
|
+
return result;
|
|
11
|
+
for (const entry of readdirSync(directory)) {
|
|
12
|
+
if (ignoredDirectories.includes(entry))
|
|
13
|
+
continue;
|
|
14
|
+
const path = join(directory, entry);
|
|
15
|
+
if (statSync(path).isDirectory())
|
|
16
|
+
listFiles(root, path, result);
|
|
17
|
+
else
|
|
18
|
+
result.push(relative(root, path).replaceAll('\\', '/'));
|
|
19
|
+
}
|
|
20
|
+
return result;
|
|
21
|
+
};
|
|
22
|
+
/** Captures every product file's contents so a later snapshot can be compared. */
|
|
23
|
+
export const snapshotFiles = (root) => new Map(listFiles(root).map((file) => [file, readFileSync(join(root, file), 'utf8')]));
|
|
24
|
+
/** Names the files that were added, removed or modified between two snapshots. */
|
|
25
|
+
export const changedFiles = (before, after) => [...new Set([...before.keys(), ...after.keys()])]
|
|
26
|
+
.filter((file) => !before.has(file) || !after.has(file) || before.get(file) !== after.get(file));
|
|
27
|
+
//# sourceMappingURL=diff-inspector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-inspector.js","sourceRoot":"","sources":["../../src/core/diff-inspector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AACzE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAK1C,8EAA8E;AAC9E,gFAAgF;AAChF,gFAAgF;AAChF,6CAA6C;AAC7C,MAAM,kBAAkB,GAAG,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;AAE3D,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,YAAoB,IAAI,EAAE,SAAmB,EAAE,EAAY,EAAE;IAC5F,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,MAAM,CAAA;IACzC,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3C,IAAI,kBAAkB,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,SAAQ;QAChD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;QACnC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE;YAAE,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;;YAC1D,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAA;IAC9D,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAED,kFAAkF;AAClF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAY,EAAgB,EAAE,CAC1D,IAAI,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;AAExF,kFAAkF;AAClF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAoB,EAAE,KAAmB,EAAY,EAAE,CAClF,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;KAC9C,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { NormalizedTask, OrchestrationResult, Policy, RunAgent, VerificationCheck } from '../contracts/index.js';
|
|
2
|
+
import type { FileSnapshot } from './diff-inspector.js';
|
|
3
|
+
export interface OrchestratorOptions {
|
|
4
|
+
input: NormalizedTask;
|
|
5
|
+
policy: Policy;
|
|
6
|
+
dryRun: boolean;
|
|
7
|
+
snapshot: () => FileSnapshot;
|
|
8
|
+
changedFiles: (before: FileSnapshot, after: FileSnapshot) => string[];
|
|
9
|
+
runAgent: RunAgent;
|
|
10
|
+
runVerification: () => Promise<VerificationCheck[]>;
|
|
11
|
+
writeVerification?: (iteration: number, verification: VerificationCheck[]) => void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Runs the fixed Planner → Coder → Tester → Reviewer pipeline.
|
|
15
|
+
*
|
|
16
|
+
* The loop retries the coder only while the tester has not approved and the
|
|
17
|
+
* iteration budget allows it; a planner, coder or reviewer failure stops the
|
|
18
|
+
* run outright.
|
|
19
|
+
*/
|
|
20
|
+
export declare const runOrchestrator: ({ input, policy, dryRun, snapshot, changedFiles, runAgent, runVerification, writeVerification, }: OrchestratorOptions) => Promise<OrchestrationResult>;
|
|
21
|
+
//# sourceMappingURL=executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/core/executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,cAAc,EACd,mBAAmB,EAGnB,MAAM,EACN,QAAQ,EACR,iBAAiB,EAClB,MAAM,uBAAuB,CAAA;AAE9B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAGvD,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,cAAc,CAAA;IACrB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,OAAO,CAAA;IACf,QAAQ,EAAE,MAAM,YAAY,CAAA;IAC5B,YAAY,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,KAAK,MAAM,EAAE,CAAA;IACrE,QAAQ,EAAE,QAAQ,CAAA;IAClB,eAAe,EAAE,MAAM,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAA;IACnD,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,iBAAiB,EAAE,KAAK,IAAI,CAAA;CACnF;AAED;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAAU,kGASnC,mBAAmB,KAAG,OAAO,CAAC,mBAAmB,CA8InD,CAAA"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { reviewerApproved, testerApproved } from './approval-gate.js';
|
|
2
|
+
import { findOutOfScopeChanges } from './policy-engine.js';
|
|
3
|
+
/**
|
|
4
|
+
* Runs the fixed Planner → Coder → Tester → Reviewer pipeline.
|
|
5
|
+
*
|
|
6
|
+
* The loop retries the coder only while the tester has not approved and the
|
|
7
|
+
* iteration budget allows it; a planner, coder or reviewer failure stops the
|
|
8
|
+
* run outright.
|
|
9
|
+
*/
|
|
10
|
+
export const runOrchestrator = async ({ input, policy, dryRun, snapshot, changedFiles, runAgent, runVerification, writeVerification = () => { }, }) => {
|
|
11
|
+
const maxIterations = Math.min(Math.max(Number(input.maxIterations ?? policy.maxIterations ?? 3), 1), policy.maxIterations ?? 3);
|
|
12
|
+
const phases = [];
|
|
13
|
+
const issues = [];
|
|
14
|
+
const fileChanges = [];
|
|
15
|
+
const implementationPlan = [
|
|
16
|
+
`Analyze the requested feature: ${input.feature.trim()}.`,
|
|
17
|
+
`Implement the objective while satisfying ${input.acceptanceCriteria.length} acceptance criteria.`,
|
|
18
|
+
'Run configured verification gates and review the result before reporting completion.',
|
|
19
|
+
];
|
|
20
|
+
if (dryRun) {
|
|
21
|
+
// A dry run is a safe preview: no Agent Provider is invoked, no verification
|
|
22
|
+
// gate is executed, and no product file can change. Report the same four
|
|
23
|
+
// phases so callers can consume the result with the regular output contract.
|
|
24
|
+
for (const [name, details] of [
|
|
25
|
+
['planner', 'Dry run: planner execution skipped; no agent provider was invoked.'],
|
|
26
|
+
['coder', 'Dry run: coder execution skipped; no product files were changed.'],
|
|
27
|
+
['tester', 'Dry run: tester execution skipped; no verification gates were executed.'],
|
|
28
|
+
['reviewer', 'Dry run: reviewer execution skipped; no product files were changed.'],
|
|
29
|
+
]) {
|
|
30
|
+
phases.push({ name, iteration: 1, status: 'passed', details });
|
|
31
|
+
}
|
|
32
|
+
return { completed: true, implementationPlan, fileChanges, verification: [], issues, phases, iterations: 1 };
|
|
33
|
+
}
|
|
34
|
+
const recordPhase = (name, status, details, iteration) => {
|
|
35
|
+
const phase = { name, status, details };
|
|
36
|
+
if (iteration)
|
|
37
|
+
phase.iteration = iteration;
|
|
38
|
+
phases.push(phase);
|
|
39
|
+
return phase;
|
|
40
|
+
};
|
|
41
|
+
recordPhase('planner', 'running', 'Validating task input and preparing an implementation plan.');
|
|
42
|
+
const plan = await runAgent('planner', { phase: 'planner', input, implementationPlan });
|
|
43
|
+
phases[phases.length - 1] = { name: 'planner', status: plan.ok ? 'passed' : 'failed', details: plan.details };
|
|
44
|
+
if (plan.payload.implementationPlan?.length) {
|
|
45
|
+
implementationPlan.splice(0, implementationPlan.length, ...plan.payload.implementationPlan);
|
|
46
|
+
}
|
|
47
|
+
if (!plan.ok)
|
|
48
|
+
issues.push(plan.details);
|
|
49
|
+
let lastVerification = [];
|
|
50
|
+
let completed = false;
|
|
51
|
+
for (let iteration = 1; iteration <= maxIterations && issues.length === 0; iteration += 1) {
|
|
52
|
+
const before = snapshot();
|
|
53
|
+
recordPhase('coder', 'running', 'Applying the approved implementation plan.', iteration);
|
|
54
|
+
const coder = await runAgent('coder', {
|
|
55
|
+
phase: 'coder',
|
|
56
|
+
input,
|
|
57
|
+
implementationPlan,
|
|
58
|
+
iteration,
|
|
59
|
+
previousVerification: lastVerification,
|
|
60
|
+
});
|
|
61
|
+
phases[phases.length - 1] = {
|
|
62
|
+
name: 'coder',
|
|
63
|
+
iteration,
|
|
64
|
+
status: coder.ok ? 'passed' : 'failed',
|
|
65
|
+
details: coder.details,
|
|
66
|
+
};
|
|
67
|
+
for (const file of changedFiles(before, snapshot())) {
|
|
68
|
+
fileChanges.push({ file, change: `Changed during coder iteration ${iteration}.` });
|
|
69
|
+
}
|
|
70
|
+
if (!coder.ok) {
|
|
71
|
+
issues.push(coder.details);
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
recordPhase('tester', 'running', 'Running required verification gates.', iteration);
|
|
75
|
+
const verification = await runVerification();
|
|
76
|
+
const externalTest = await runAgent('tester', {
|
|
77
|
+
phase: 'tester',
|
|
78
|
+
input,
|
|
79
|
+
implementationPlan,
|
|
80
|
+
verification,
|
|
81
|
+
iteration,
|
|
82
|
+
});
|
|
83
|
+
if (!externalTest.ok) {
|
|
84
|
+
verification.push({ command: 'external tester', result: 'fail', details: externalTest.details });
|
|
85
|
+
}
|
|
86
|
+
lastVerification = verification;
|
|
87
|
+
const testerOk = testerApproved(verification, externalTest);
|
|
88
|
+
phases[phases.length - 1] = {
|
|
89
|
+
name: 'tester',
|
|
90
|
+
iteration,
|
|
91
|
+
status: testerOk ? 'passed' : 'failed',
|
|
92
|
+
details: testerOk
|
|
93
|
+
? 'All required gates passed and tester approved the evidence.'
|
|
94
|
+
: externalTest.ok
|
|
95
|
+
? 'At least one required gate failed or tester rejected the evidence.'
|
|
96
|
+
: externalTest.details,
|
|
97
|
+
};
|
|
98
|
+
writeVerification(iteration, verification);
|
|
99
|
+
if (!testerOk && iteration === maxIterations) {
|
|
100
|
+
issues.push('Verification did not pass before maxIterations was reached.');
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
if (!testerOk)
|
|
104
|
+
continue;
|
|
105
|
+
recordPhase('reviewer', 'running', 'Checking scope, output contract, and acceptance criteria.', iteration);
|
|
106
|
+
const outOfScopeChanges = findOutOfScopeChanges(fileChanges.map(({ file }) => file), policy);
|
|
107
|
+
const reviewer = await runAgent('reviewer', {
|
|
108
|
+
phase: 'reviewer',
|
|
109
|
+
input,
|
|
110
|
+
implementationPlan,
|
|
111
|
+
verification,
|
|
112
|
+
fileChanges,
|
|
113
|
+
iteration,
|
|
114
|
+
});
|
|
115
|
+
const reviewerOk = reviewerApproved(reviewer, outOfScopeChanges);
|
|
116
|
+
const reviewerDetails = outOfScopeChanges.length
|
|
117
|
+
? `Out-of-scope files changed: ${outOfScopeChanges.join(', ')}`
|
|
118
|
+
: reviewer.details;
|
|
119
|
+
phases[phases.length - 1] = {
|
|
120
|
+
name: 'reviewer',
|
|
121
|
+
iteration,
|
|
122
|
+
status: reviewerOk ? 'passed' : 'failed',
|
|
123
|
+
details: reviewerDetails,
|
|
124
|
+
};
|
|
125
|
+
if (!reviewerOk) {
|
|
126
|
+
issues.push(reviewerDetails);
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
completed = true;
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
completed,
|
|
134
|
+
implementationPlan,
|
|
135
|
+
fileChanges,
|
|
136
|
+
verification: lastVerification,
|
|
137
|
+
issues,
|
|
138
|
+
phases,
|
|
139
|
+
iterations: phases.filter((phase) => phase.name === 'coder').length,
|
|
140
|
+
};
|
|
141
|
+
};
|
|
142
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/core/executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { IntakeResult, RawTaskInput } from '../contracts/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Folds any of the three input layers into the normalized task contract.
|
|
4
|
+
*
|
|
5
|
+
* Missing key information is reported as questions instead of an error, so the
|
|
6
|
+
* caller can ask a human rather than fail the run.
|
|
7
|
+
*/
|
|
8
|
+
export declare const normalizeTask: (task: RawTaskInput) => IntakeResult;
|
|
9
|
+
/** Reads a human task file and normalizes it. */
|
|
10
|
+
export declare const readTaskFile: (path: string) => IntakeResult;
|
|
11
|
+
//# sourceMappingURL=intake.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intake.d.ts","sourceRoot":"","sources":["../../src/core/intake.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAkB,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAIvF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GAAI,MAAM,YAAY,KAAG,YAoBlD,CAAA;AAED,iDAAiD;AACjD,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,KAAG,YAC2B,CAAA"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
const defaultChecks = ['pnpm run harness:verify', 'pnpm run type-check', 'pnpm run test:unit', 'pnpm run build'];
|
|
3
|
+
/**
|
|
4
|
+
* Folds any of the three input layers into the normalized task contract.
|
|
5
|
+
*
|
|
6
|
+
* Missing key information is reported as questions instead of an error, so the
|
|
7
|
+
* caller can ask a human rather than fail the run.
|
|
8
|
+
*/
|
|
9
|
+
export const normalizeTask = (task) => {
|
|
10
|
+
const normalized = {
|
|
11
|
+
feature: task.task?.trim() || task.feature?.trim() || '',
|
|
12
|
+
objective: task.goal?.trim() || task.objective?.trim() || '',
|
|
13
|
+
constraints: task.specialConstraints ?? task.constraints ?? [],
|
|
14
|
+
acceptanceCriteria: task.acceptance ?? task.acceptanceCriteria ?? [],
|
|
15
|
+
testHints: task.testHints ?? defaultChecks,
|
|
16
|
+
maxIterations: task.maxIterations ?? 3,
|
|
17
|
+
};
|
|
18
|
+
const questions = [];
|
|
19
|
+
if (!normalized.feature)
|
|
20
|
+
questions.push('要实现的任务或功能是什么?');
|
|
21
|
+
if (!normalized.objective)
|
|
22
|
+
questions.push('任务的目标是什么?');
|
|
23
|
+
if (!normalized.acceptanceCriteria.length)
|
|
24
|
+
questions.push('完成任务的验收标准是什么?');
|
|
25
|
+
return {
|
|
26
|
+
status: questions.length > 0 ? 'needs_input' : 'ready',
|
|
27
|
+
questions,
|
|
28
|
+
normalizedTask: normalized,
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
/** Reads a human task file and normalizes it. */
|
|
32
|
+
export const readTaskFile = (path) => normalizeTask(JSON.parse(readFileSync(path, 'utf8')));
|
|
33
|
+
//# sourceMappingURL=intake.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intake.js","sourceRoot":"","sources":["../../src/core/intake.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAGtC,MAAM,aAAa,GAAG,CAAC,yBAAyB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,gBAAgB,CAAC,CAAA;AAEhH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAkB,EAAgB,EAAE;IAChE,MAAM,UAAU,GAAmB;QACjC,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE;QACxD,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE;QAC5D,WAAW,EAAE,IAAI,CAAC,kBAAkB,IAAI,IAAI,CAAC,WAAW,IAAI,EAAE;QAC9D,kBAAkB,EAAE,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,kBAAkB,IAAI,EAAE;QACpE,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,aAAa;QAC1C,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,CAAC;KACvC,CAAA;IAED,MAAM,SAAS,GAAa,EAAE,CAAA;IAC9B,IAAI,CAAC,UAAU,CAAC,OAAO;QAAE,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;IACxD,IAAI,CAAC,UAAU,CAAC,SAAS;QAAE,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IACtD,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC,MAAM;QAAE,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;IAE1E,OAAO;QACL,MAAM,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO;QACtD,SAAS;QACT,cAAc,EAAE,UAAU;KAC3B,CAAA;AACH,CAAC,CAAA;AAED,iDAAiD;AACjD,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAAY,EAAgB,EAAE,CACzD,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAiB,CAAC,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface PackageManager {
|
|
2
|
+
name: 'pnpm' | 'yarn' | 'npm';
|
|
3
|
+
command: string;
|
|
4
|
+
args: string[];
|
|
5
|
+
}
|
|
6
|
+
export interface PackageScriptCommand extends PackageManager {
|
|
7
|
+
/** The command as a human would type it, for evidence output. */
|
|
8
|
+
display: string;
|
|
9
|
+
}
|
|
10
|
+
/** Picks the package manager from the lockfile a project committed. */
|
|
11
|
+
export declare const detectPackageManager: (root: string) => PackageManager;
|
|
12
|
+
/** Builds the invocation that runs one package script in `root`. */
|
|
13
|
+
export declare const packageScriptCommand: (root: string, script: string) => PackageScriptCommand;
|
|
14
|
+
//# sourceMappingURL=package-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-manager.d.ts","sourceRoot":"","sources":["../../src/core/package-manager.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAA;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,EAAE,CAAA;CACf;AAED,MAAM,WAAW,oBAAqB,SAAQ,cAAc;IAC1D,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,uEAAuE;AACvE,eAAO,MAAM,oBAAoB,GAAI,MAAM,MAAM,KAAG,cAInD,CAAA;AAED,oEAAoE;AACpE,eAAO,MAAM,oBAAoB,GAAI,MAAM,MAAM,EAAE,QAAQ,MAAM,KAAG,oBAOnE,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
/** Picks the package manager from the lockfile a project committed. */
|
|
4
|
+
export const detectPackageManager = (root) => {
|
|
5
|
+
if (existsSync(join(root, 'pnpm-lock.yaml')))
|
|
6
|
+
return { name: 'pnpm', command: 'pnpm', args: ['run'] };
|
|
7
|
+
if (existsSync(join(root, 'yarn.lock')))
|
|
8
|
+
return { name: 'yarn', command: 'yarn', args: [] };
|
|
9
|
+
return { name: 'npm', command: 'npm', args: ['run'] };
|
|
10
|
+
};
|
|
11
|
+
/** Builds the invocation that runs one package script in `root`. */
|
|
12
|
+
export const packageScriptCommand = (root, script) => {
|
|
13
|
+
const manager = detectPackageManager(root);
|
|
14
|
+
return {
|
|
15
|
+
...manager,
|
|
16
|
+
args: [...manager.args, script],
|
|
17
|
+
display: `${manager.command} ${[...manager.args, script].join(' ')}`,
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=package-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-manager.js","sourceRoot":"","sources":["../../src/core/package-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAahC,uEAAuE;AACvE,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,IAAY,EAAkB,EAAE;IACnE,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,CAAA;IACrG,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,CAAA;IAC3F,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,CAAA;AACvD,CAAC,CAAA;AAED,oEAAoE;AACpE,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,IAAY,EAAE,MAAc,EAAwB,EAAE;IACzF,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAA;IAC1C,OAAO;QACL,GAAG,OAAO;QACV,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;QAC/B,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;KACrE,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CommandPolicy, Policy } from '../contracts/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Checks a policy document read from disk.
|
|
4
|
+
*
|
|
5
|
+
* The document is untrusted JSON, so this takes `unknown` and reports the first
|
|
6
|
+
* problem as a message instead of throwing. A caller that gets `null` back may
|
|
7
|
+
* treat the document as a `Policy`.
|
|
8
|
+
*/
|
|
9
|
+
export declare const validatePolicy: (policy: unknown) => string | null;
|
|
10
|
+
/** Names the files the coder touched that the policy does not allow. */
|
|
11
|
+
export declare const findOutOfScopeChanges: (files: string[], policy: Policy) => string[];
|
|
12
|
+
/** Whether an agent may run a command. An empty allow list means "no restriction". */
|
|
13
|
+
export declare const isCommandAllowed: (command: string, policy: CommandPolicy) => boolean;
|
|
14
|
+
//# sourceMappingURL=policy-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-engine.d.ts","sourceRoot":"","sources":["../../src/core/policy-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAKlE;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,OAAO,KAAG,MAAM,GAAG,IAYzD,CAAA;AAED,wEAAwE;AACxE,eAAO,MAAM,qBAAqB,GAAI,OAAO,MAAM,EAAE,EAAE,QAAQ,MAAM,KAAG,MAAM,EAG3E,CAAA;AAEH,sFAAsF;AACtF,eAAO,MAAM,gBAAgB,GAAI,SAAS,MAAM,EAAE,QAAQ,aAAa,KAAG,OACa,CAAA"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const asRecord = (value) => value !== null && typeof value === 'object' ? value : null;
|
|
2
|
+
/**
|
|
3
|
+
* Checks a policy document read from disk.
|
|
4
|
+
*
|
|
5
|
+
* The document is untrusted JSON, so this takes `unknown` and reports the first
|
|
6
|
+
* problem as a message instead of throwing. A caller that gets `null` back may
|
|
7
|
+
* treat the document as a `Policy`.
|
|
8
|
+
*/
|
|
9
|
+
export const validatePolicy = (policy) => {
|
|
10
|
+
const candidate = asRecord(policy);
|
|
11
|
+
if (!candidate)
|
|
12
|
+
return 'Policy must be an object.';
|
|
13
|
+
if (!Array.isArray(candidate.allowedProductPaths) || candidate.allowedProductPaths.length === 0) {
|
|
14
|
+
return 'Harness policy must define at least one allowedProductPaths entry.';
|
|
15
|
+
}
|
|
16
|
+
if (!Number.isInteger(candidate.maxIterations) || candidate.maxIterations < 1) {
|
|
17
|
+
return 'Harness policy maxIterations must be a positive integer.';
|
|
18
|
+
}
|
|
19
|
+
if (!Array.isArray(candidate.protectedPaths))
|
|
20
|
+
return 'Harness policy protectedPaths must be an array.';
|
|
21
|
+
if (!Array.isArray(candidate.requiredChecks))
|
|
22
|
+
return 'Harness policy requiredChecks must be an array.';
|
|
23
|
+
return null;
|
|
24
|
+
};
|
|
25
|
+
/** Names the files the coder touched that the policy does not allow. */
|
|
26
|
+
export const findOutOfScopeChanges = (files, policy) => files.filter((file) => !policy.allowedProductPaths.some((allowedPath) => file.startsWith(allowedPath)));
|
|
27
|
+
/** Whether an agent may run a command. An empty allow list means "no restriction". */
|
|
28
|
+
export const isCommandAllowed = (command, policy) => !policy.allowedAgentCommands?.length || policy.allowedAgentCommands.includes(command);
|
|
29
|
+
//# sourceMappingURL=policy-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-engine.js","sourceRoot":"","sources":["../../src/core/policy-engine.ts"],"names":[],"mappings":"AAEA,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAkC,EAAE,CAClE,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAgC,CAAC,CAAC,CAAC,IAAI,CAAA;AAEvF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,MAAe,EAAiB,EAAE;IAC/D,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAA;IAClC,IAAI,CAAC,SAAS;QAAE,OAAO,2BAA2B,CAAA;IAClD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,mBAAmB,CAAC,IAAI,SAAS,CAAC,mBAAmB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChG,OAAO,oEAAoE,CAAA;IAC7E,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,aAAa,CAAC,IAAK,SAAS,CAAC,aAAwB,GAAG,CAAC,EAAE,CAAC;QAC1F,OAAO,0DAA0D,CAAA;IACnE,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,cAAc,CAAC;QAAE,OAAO,iDAAiD,CAAA;IACtG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,cAAc,CAAC;QAAE,OAAO,iDAAiD,CAAA;IACtG,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,wEAAwE;AACxE,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,KAAe,EAAE,MAAc,EAAY,EAAE,CACjF,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CACpB,CAAC,MAAM,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAChF,CAAA;AAEH,sFAAsF;AACtF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAAe,EAAE,MAAqB,EAAW,EAAE,CAClF,CAAC,MAAM,CAAC,oBAAoB,EAAE,MAAM,IAAI,MAAM,CAAC,oBAAoB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Ajv2020 } from 'ajv/dist/2020.js';
|
|
2
|
+
import type { ErrorObject, ValidateFunction } from 'ajv';
|
|
3
|
+
/** The raw JSON Schema documents a project commits under `.harness/`. */
|
|
4
|
+
export interface HarnessSchemas {
|
|
5
|
+
input: object;
|
|
6
|
+
output: object;
|
|
7
|
+
agentResponse: object;
|
|
8
|
+
}
|
|
9
|
+
export interface HarnessValidators {
|
|
10
|
+
ajv: Ajv2020;
|
|
11
|
+
input: ValidateFunction;
|
|
12
|
+
output: ValidateFunction;
|
|
13
|
+
agentResponse: ValidateFunction;
|
|
14
|
+
}
|
|
15
|
+
/** A compiled validator, including the `errors` it records on failure. */
|
|
16
|
+
export interface ResponseValidator {
|
|
17
|
+
(value: unknown): boolean;
|
|
18
|
+
errors?: null | ErrorObject[];
|
|
19
|
+
}
|
|
20
|
+
/** The only Ajv capability the agent-response parser needs. */
|
|
21
|
+
export type SchemaErrorFormatter = Pick<Ajv2020, 'errorsText'>;
|
|
22
|
+
export declare const loadSchemas: (root: string) => HarnessSchemas;
|
|
23
|
+
export declare const createValidators: (schemas: HarnessSchemas) => HarnessValidators;
|
|
24
|
+
export declare const validationDetails: (ajv: SchemaErrorFormatter, validator: ResponseValidator) => string;
|
|
25
|
+
//# sourceMappingURL=validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/core/validator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAG1C,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,KAAK,CAAA;AAExD,yEAAyE;AACzE,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,OAAO,CAAA;IACZ,KAAK,EAAE,gBAAgB,CAAA;IACvB,MAAM,EAAE,gBAAgB,CAAA;IACxB,aAAa,EAAE,gBAAgB,CAAA;CAChC;AAED,0EAA0E;AAC1E,MAAM,WAAW,iBAAiB;IAChC,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAA;IACzB,MAAM,CAAC,EAAE,IAAI,GAAG,WAAW,EAAE,CAAA;CAC9B;AAED,+DAA+D;AAC/D,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;AAE9D,eAAO,MAAM,WAAW,GAAI,MAAM,MAAM,KAAG,cAS1C,CAAA;AAED,eAAO,MAAM,gBAAgB,GAAI,SAAS,cAAc,KAAG,iBAQ1D,CAAA;AAED,eAAO,MAAM,iBAAiB,GAAI,KAAK,oBAAoB,EAAE,WAAW,iBAAiB,KAAG,MAC1D,CAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// The default export is typed as a namespace under NodeNext; the named export is
|
|
2
|
+
// the class, and ajv ships it on both the ESM and CJS sides.
|
|
3
|
+
import { Ajv2020 } from 'ajv/dist/2020.js';
|
|
4
|
+
import { readFileSync } from 'node:fs';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
export const loadSchemas = (root) => {
|
|
7
|
+
const read = (name) => JSON.parse(readFileSync(join(root, '.harness', name), 'utf8'));
|
|
8
|
+
return {
|
|
9
|
+
input: read('input.schema.json'),
|
|
10
|
+
output: read('output.schema.json'),
|
|
11
|
+
agentResponse: read('agent-response.schema.json'),
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
export const createValidators = (schemas) => {
|
|
15
|
+
const ajv = new Ajv2020({ allErrors: true, strict: false });
|
|
16
|
+
return {
|
|
17
|
+
ajv,
|
|
18
|
+
input: ajv.compile(schemas.input),
|
|
19
|
+
output: ajv.compile(schemas.output),
|
|
20
|
+
agentResponse: ajv.compile(schemas.agentResponse),
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
export const validationDetails = (ajv, validator) => ajv.errorsText(validator.errors);
|
|
24
|
+
//# sourceMappingURL=validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/core/validator.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,6DAA6D;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AA0BhC,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAY,EAAkB,EAAE;IAC1D,MAAM,IAAI,GAAG,CAAC,IAAY,EAAU,EAAE,CACpC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAW,CAAA;IAE1E,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,mBAAmB,CAAC;QAChC,MAAM,EAAE,IAAI,CAAC,oBAAoB,CAAC;QAClC,aAAa,EAAE,IAAI,CAAC,4BAA4B,CAAC;KAClD,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAAuB,EAAqB,EAAE;IAC7E,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAA;IAC3D,OAAO;QACL,GAAG;QACH,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;QACjC,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;QACnC,aAAa,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC;KAClD,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,GAAyB,EAAE,SAA4B,EAAU,EAAE,CACnG,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type * from './contracts/index.js';
|
|
2
|
+
export { detectPackageManager, packageScriptCommand } from './core/package-manager.js';
|
|
3
|
+
export type { PackageManager, PackageScriptCommand } from './core/package-manager.js';
|
|
4
|
+
export { normalizeTask, readTaskFile } from './core/intake.js';
|
|
5
|
+
export { runCommand } from './core/command.js';
|
|
6
|
+
export type { CommandResult } from './core/command.js';
|
|
7
|
+
export { changedFiles, snapshotFiles } from './core/diff-inspector.js';
|
|
8
|
+
export type { FileSnapshot } from './core/diff-inspector.js';
|
|
9
|
+
export { loadSchemas, createValidators, validationDetails } from './core/validator.js';
|
|
10
|
+
export type { HarnessSchemas, HarnessValidators, ResponseValidator, SchemaErrorFormatter, } from './core/validator.js';
|
|
11
|
+
export { parseAgentResponse, validateStageResponse } from './core/agent.js';
|
|
12
|
+
export type { ParsedAgentResponse } from './core/agent.js';
|
|
13
|
+
export { validatePolicy, findOutOfScopeChanges, isCommandAllowed } from './core/policy-engine.js';
|
|
14
|
+
export { testerApproved, reviewerApproved } from './core/approval-gate.js';
|
|
15
|
+
export { createProviderRunner } from './adapters/provider-runner.js';
|
|
16
|
+
export type { ProviderRunnerOptions } from './adapters/provider-runner.js';
|
|
17
|
+
export { runOrchestrator } from './core/executor.js';
|
|
18
|
+
export type { OrchestratorOptions } from './core/executor.js';
|
|
19
|
+
export declare const harnessCoreVersion: string;
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,mBAAmB,sBAAsB,CAAA;AAEzC,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AACtF,YAAY,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAErF,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEtD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACtE,YAAY,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAE5D,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACtF,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AAC3E,YAAY,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAE1D,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AACjG,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAE1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAA;AACpE,YAAY,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAA;AAE1E,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAI7D,eAAO,MAAM,kBAAkB,EAAE,MAAkE,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
export { detectPackageManager, packageScriptCommand } from './core/package-manager.js';
|
|
3
|
+
export { normalizeTask, readTaskFile } from './core/intake.js';
|
|
4
|
+
export { runCommand } from './core/command.js';
|
|
5
|
+
export { changedFiles, snapshotFiles } from './core/diff-inspector.js';
|
|
6
|
+
export { loadSchemas, createValidators, validationDetails } from './core/validator.js';
|
|
7
|
+
export { parseAgentResponse, validateStageResponse } from './core/agent.js';
|
|
8
|
+
export { validatePolicy, findOutOfScopeChanges, isCommandAllowed } from './core/policy-engine.js';
|
|
9
|
+
export { testerApproved, reviewerApproved } from './core/approval-gate.js';
|
|
10
|
+
export { createProviderRunner } from './adapters/provider-runner.js';
|
|
11
|
+
export { runOrchestrator } from './core/executor.js';
|
|
12
|
+
// Read from the manifest rather than repeating the literal here: a hardcoded copy silently
|
|
13
|
+
// kept reporting the previous release after the version was bumped.
|
|
14
|
+
export const harnessCoreVersion = createRequire(import.meta.url)('../package.json').version;
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAI3C,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAGtF,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAG9C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAGtE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAQtF,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AAG3E,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AACjG,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAE1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAA;AAGpE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAGpD,2FAA2F;AAC3F,oEAAoE;AACpE,MAAM,CAAC,MAAM,kBAAkB,GAAW,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAA"}
|