ai-dev-harness 0.1.0
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 +131 -0
- package/dist/agent.js +100 -0
- package/dist/audit.js +21 -0
- package/dist/cli.js +279 -0
- package/dist/config.js +156 -0
- package/dist/context.js +114 -0
- package/dist/init.js +29 -0
- package/dist/integration.js +173 -0
- package/dist/mcp.js +145 -0
- package/dist/runPaths.js +21 -0
- package/dist/summarize.js +72 -0
- package/dist/templates.js +217 -0
- package/dist/types.js +1 -0
- package/dist/utils.js +95 -0
- package/dist/verify.js +28 -0
- package/package.json +40 -0
- package/scripts/read-evidence.ps1 +36 -0
- package/scripts/run-harness.ps1 +53 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { defaultConfigYaml } from "./config.js";
|
|
2
|
+
export const rootTemplates = {
|
|
3
|
+
"harness.yaml": defaultConfigYaml(),
|
|
4
|
+
"AGENTS.md": `# Project Agent Rules
|
|
5
|
+
|
|
6
|
+
- Work inside this Git repository only.
|
|
7
|
+
- Prefer small, reviewable changes.
|
|
8
|
+
- Do not modify generated or dependency directories.
|
|
9
|
+
- Always explain impact, risk, verification, and follow-up knowledge updates.
|
|
10
|
+
- Before changing code, state assumptions, affected areas, and a minimal plan.
|
|
11
|
+
- If required context is missing or confidence is low, stop and report what is missing instead of guessing.
|
|
12
|
+
- Do not perform broad refactors, formatting-only sweeps, dependency upgrades, or unrelated cleanup unless the task explicitly asks for them.
|
|
13
|
+
`,
|
|
14
|
+
"TOOLS.md": `# Tool Rules
|
|
15
|
+
|
|
16
|
+
- Codex and Claude Code are execution agents.
|
|
17
|
+
- CodeGraph MCP provides code impact context.
|
|
18
|
+
- Knowledge Graph MCP provides ADR, module, API, runbook, and decision context.
|
|
19
|
+
- Verification commands are defined in harness.yaml and skill verify.yaml files.
|
|
20
|
+
- Harness run evidence is stored in runs/<run_id>/ and must be treated as the audit record.
|
|
21
|
+
- Knowledge Graph is read-only in v1. Write suggestions to persist_suggestions.md only.
|
|
22
|
+
`,
|
|
23
|
+
"SKILLS.md": `# Skill Index
|
|
24
|
+
|
|
25
|
+
- fix_bug: diagnose and fix a defect with tests when possible.
|
|
26
|
+
- add_feature: implement a scoped feature with verification.
|
|
27
|
+
- write_tests: add or improve tests for existing behavior.
|
|
28
|
+
- update_docs: update project documentation and knowledge suggestions.
|
|
29
|
+
|
|
30
|
+
Every skill follows the same execution contract:
|
|
31
|
+
|
|
32
|
+
1. Analysis Contract: identify assumptions, affected files/modules, likely risks, and the smallest viable plan.
|
|
33
|
+
2. Execution Contract: make only task-relevant changes and avoid opportunistic refactors.
|
|
34
|
+
3. Verification Contract: run or defer verification with explicit reasons.
|
|
35
|
+
4. Report Contract: explain root cause or intent, changed files, verification, residual risk, and knowledge suggestions.
|
|
36
|
+
`
|
|
37
|
+
};
|
|
38
|
+
const baseContext = `queries:
|
|
39
|
+
- related files
|
|
40
|
+
- symbols
|
|
41
|
+
- call graph
|
|
42
|
+
- dependencies
|
|
43
|
+
- impact analysis
|
|
44
|
+
fallbackInclude:
|
|
45
|
+
- README.md
|
|
46
|
+
- src
|
|
47
|
+
`;
|
|
48
|
+
const defaultVerify = `- name: git status
|
|
49
|
+
command: git status --short
|
|
50
|
+
`;
|
|
51
|
+
export const skillTemplates = {
|
|
52
|
+
fix_bug: {
|
|
53
|
+
"SKILL.md": `# fix_bug
|
|
54
|
+
|
|
55
|
+
## Goal
|
|
56
|
+
Diagnose and fix a defect with the smallest safe code change.
|
|
57
|
+
|
|
58
|
+
## Inputs
|
|
59
|
+
- Task text or issue description.
|
|
60
|
+
- CodeGraph impact context.
|
|
61
|
+
- Knowledge Graph related decisions, module notes, APIs, and runbooks.
|
|
62
|
+
|
|
63
|
+
## Outputs
|
|
64
|
+
- Code change.
|
|
65
|
+
- Test or verification result.
|
|
66
|
+
- Summary with root cause, impact, risk, and follow-up suggestions.
|
|
67
|
+
|
|
68
|
+
## Analysis Contract
|
|
69
|
+
- Restate the observed defect and expected behavior.
|
|
70
|
+
- Identify the likely root cause and the code path involved.
|
|
71
|
+
- List assumptions and confidence level before editing.
|
|
72
|
+
- Use CodeGraph impact context to avoid missing callers or dependent modules.
|
|
73
|
+
- Use Knowledge Graph decisions and runbooks to avoid violating historical constraints.
|
|
74
|
+
|
|
75
|
+
## Execution Contract
|
|
76
|
+
- Make the smallest task-relevant change.
|
|
77
|
+
- Prefer adding or updating a regression test when feasible.
|
|
78
|
+
- Do not rewrite unrelated code, rename public APIs, change formatting broadly, or upgrade dependencies.
|
|
79
|
+
- If root cause is unclear after inspection, stop and report missing evidence instead of guessing.
|
|
80
|
+
|
|
81
|
+
## Verification Contract
|
|
82
|
+
- Run the configured verification commands through Harness.
|
|
83
|
+
- If manual or targeted verification is needed, describe the exact command or scenario.
|
|
84
|
+
- Record any verification that could not be run and why.
|
|
85
|
+
|
|
86
|
+
## Report Contract
|
|
87
|
+
- Root cause.
|
|
88
|
+
- Files changed.
|
|
89
|
+
- Why the fix is safe.
|
|
90
|
+
- Verification result.
|
|
91
|
+
- Residual risk.
|
|
92
|
+
- Knowledge or runbook update suggestions.
|
|
93
|
+
|
|
94
|
+
## Acceptance
|
|
95
|
+
- The defect is explained.
|
|
96
|
+
- The change is limited to the affected area.
|
|
97
|
+
- Relevant verification commands pass or failures are recorded.
|
|
98
|
+
`,
|
|
99
|
+
"verify.yaml": defaultVerify,
|
|
100
|
+
"context.yaml": baseContext
|
|
101
|
+
},
|
|
102
|
+
add_feature: {
|
|
103
|
+
"SKILL.md": `# add_feature
|
|
104
|
+
|
|
105
|
+
## Goal
|
|
106
|
+
Implement a scoped feature using existing project patterns.
|
|
107
|
+
|
|
108
|
+
## Analysis Contract
|
|
109
|
+
- Restate the feature intent and non-goals.
|
|
110
|
+
- Identify affected modules, public interfaces, data flows, and compatibility risks.
|
|
111
|
+
- Check CodeGraph context for callers, dependencies, and likely integration points.
|
|
112
|
+
- Check Knowledge Graph context for ADRs, API contracts, and previous decisions.
|
|
113
|
+
|
|
114
|
+
## Execution Contract
|
|
115
|
+
- Implement the smallest coherent slice that satisfies the task.
|
|
116
|
+
- Follow existing patterns before introducing new abstractions.
|
|
117
|
+
- Do not change unrelated behavior or broaden scope.
|
|
118
|
+
- Preserve backward compatibility unless the task explicitly allows breaking changes.
|
|
119
|
+
|
|
120
|
+
## Verification Contract
|
|
121
|
+
- Add or update tests when behavior changes.
|
|
122
|
+
- Run configured verification commands through Harness.
|
|
123
|
+
- Record unverified scenarios and reasons.
|
|
124
|
+
|
|
125
|
+
## Report Contract
|
|
126
|
+
- Feature behavior implemented.
|
|
127
|
+
- Files changed.
|
|
128
|
+
- Compatibility notes.
|
|
129
|
+
- Verification result.
|
|
130
|
+
- Residual risk.
|
|
131
|
+
- Documentation or knowledge suggestions.
|
|
132
|
+
|
|
133
|
+
## Outputs
|
|
134
|
+
- Code change.
|
|
135
|
+
- Tests or verification.
|
|
136
|
+
- Documentation and knowledge suggestions when behavior changes.
|
|
137
|
+
`,
|
|
138
|
+
"verify.yaml": defaultVerify,
|
|
139
|
+
"context.yaml": baseContext
|
|
140
|
+
},
|
|
141
|
+
write_tests: {
|
|
142
|
+
"SKILL.md": `# write_tests
|
|
143
|
+
|
|
144
|
+
## Goal
|
|
145
|
+
Add or improve tests for existing behavior without changing production behavior unless required.
|
|
146
|
+
|
|
147
|
+
## Analysis Contract
|
|
148
|
+
- Identify the behavior under test and the risk it protects.
|
|
149
|
+
- Locate existing test patterns, fixtures, and helper APIs.
|
|
150
|
+
- Check CodeGraph context for affected code paths.
|
|
151
|
+
- Avoid inventing behavior not supported by source code or knowledge context.
|
|
152
|
+
|
|
153
|
+
## Execution Contract
|
|
154
|
+
- Prefer focused tests over broad snapshot or brittle integration tests.
|
|
155
|
+
- Do not change production code unless the existing code is untestable and the change is minimal.
|
|
156
|
+
- Keep fixtures deterministic and local to the test where possible.
|
|
157
|
+
|
|
158
|
+
## Verification Contract
|
|
159
|
+
- Run the relevant test command or configured Harness verification.
|
|
160
|
+
- If the full suite is too expensive, document the targeted command and why.
|
|
161
|
+
|
|
162
|
+
## Report Contract
|
|
163
|
+
- Scenarios covered.
|
|
164
|
+
- Files changed.
|
|
165
|
+
- Verification result.
|
|
166
|
+
- Remaining uncovered risks.
|
|
167
|
+
|
|
168
|
+
## Outputs
|
|
169
|
+
- Test files or fixture updates.
|
|
170
|
+
- Verification result.
|
|
171
|
+
- Summary of covered scenarios.
|
|
172
|
+
`,
|
|
173
|
+
"verify.yaml": defaultVerify,
|
|
174
|
+
"context.yaml": baseContext
|
|
175
|
+
},
|
|
176
|
+
update_docs: {
|
|
177
|
+
"SKILL.md": `# update_docs
|
|
178
|
+
|
|
179
|
+
## Goal
|
|
180
|
+
Update project documentation and propose knowledge graph additions.
|
|
181
|
+
|
|
182
|
+
## Analysis Contract
|
|
183
|
+
- Identify the audience and purpose of the documentation update.
|
|
184
|
+
- Cross-check docs against code, CodeGraph context, and Knowledge Graph records.
|
|
185
|
+
- Distinguish confirmed facts from inferred guidance.
|
|
186
|
+
|
|
187
|
+
## Execution Contract
|
|
188
|
+
- Update only documentation or knowledge suggestion artifacts unless explicitly asked to change code.
|
|
189
|
+
- Keep docs concise, operational, and linked to actual project behavior.
|
|
190
|
+
- Do not write directly to Knowledge Graph in v1.
|
|
191
|
+
|
|
192
|
+
## Verification Contract
|
|
193
|
+
- Check links, commands, paths, and filenames mentioned in the docs.
|
|
194
|
+
- Run configured verification when docs affect generated artifacts or examples.
|
|
195
|
+
|
|
196
|
+
## Report Contract
|
|
197
|
+
- Docs changed.
|
|
198
|
+
- Source of truth used.
|
|
199
|
+
- Verification result.
|
|
200
|
+
- Knowledge Graph suggestions.
|
|
201
|
+
|
|
202
|
+
## Outputs
|
|
203
|
+
- Documentation changes.
|
|
204
|
+
- Persist suggestions for ADR, module notes, runbooks, or decisions.
|
|
205
|
+
`,
|
|
206
|
+
"verify.yaml": defaultVerify,
|
|
207
|
+
"context.yaml": `queries:
|
|
208
|
+
- related docs
|
|
209
|
+
- ADR
|
|
210
|
+
- module notes
|
|
211
|
+
- API docs
|
|
212
|
+
fallbackInclude:
|
|
213
|
+
- README.md
|
|
214
|
+
- docs
|
|
215
|
+
`
|
|
216
|
+
}
|
|
217
|
+
};
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
export async function pathExists(filePath) {
|
|
5
|
+
try {
|
|
6
|
+
await stat(filePath);
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export async function ensureDir(dir) {
|
|
14
|
+
await mkdir(dir, { recursive: true });
|
|
15
|
+
}
|
|
16
|
+
export async function writeFileIfMissing(filePath, content) {
|
|
17
|
+
if (await pathExists(filePath))
|
|
18
|
+
return false;
|
|
19
|
+
await ensureDir(path.dirname(filePath));
|
|
20
|
+
await writeFile(filePath, content, "utf8");
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
export async function readTextIfExists(filePath) {
|
|
24
|
+
if (!(await pathExists(filePath)))
|
|
25
|
+
return "";
|
|
26
|
+
return readFile(filePath, "utf8");
|
|
27
|
+
}
|
|
28
|
+
export function nowIso() {
|
|
29
|
+
return new Date().toISOString();
|
|
30
|
+
}
|
|
31
|
+
export function slugify(input) {
|
|
32
|
+
return input
|
|
33
|
+
.toLowerCase()
|
|
34
|
+
.replace(/[^a-z0-9\u4e00-\u9fa5]+/g, "-")
|
|
35
|
+
.replace(/^-+|-+$/g, "")
|
|
36
|
+
.slice(0, 48) || "task";
|
|
37
|
+
}
|
|
38
|
+
export function timestampId() {
|
|
39
|
+
return new Date().toISOString().replace(/[:.]/g, "-");
|
|
40
|
+
}
|
|
41
|
+
export function truncate(input, max = 4000) {
|
|
42
|
+
if (input.length <= max)
|
|
43
|
+
return input;
|
|
44
|
+
return `${input.slice(0, max)}\n...[truncated ${input.length - max} chars]`;
|
|
45
|
+
}
|
|
46
|
+
export function runCommand(command, cwd, input, timeoutMs = 10 * 60 * 1000, options = {}) {
|
|
47
|
+
const started = Date.now();
|
|
48
|
+
return new Promise((resolve) => {
|
|
49
|
+
const child = spawn(command, {
|
|
50
|
+
cwd,
|
|
51
|
+
shell: true,
|
|
52
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
53
|
+
windowsHide: true
|
|
54
|
+
});
|
|
55
|
+
let stdout = "";
|
|
56
|
+
let stderr = "";
|
|
57
|
+
const timer = setTimeout(() => {
|
|
58
|
+
child.kill();
|
|
59
|
+
stderr += `\nCommand timed out after ${timeoutMs}ms.`;
|
|
60
|
+
}, timeoutMs);
|
|
61
|
+
child.stdout.on("data", (chunk) => {
|
|
62
|
+
const text = chunk.toString();
|
|
63
|
+
stdout += text;
|
|
64
|
+
if (options.live)
|
|
65
|
+
process.stdout.write(options.stdoutPrefix ? prefixLines(text, options.stdoutPrefix) : text);
|
|
66
|
+
});
|
|
67
|
+
child.stderr.on("data", (chunk) => {
|
|
68
|
+
const text = chunk.toString();
|
|
69
|
+
stderr += text;
|
|
70
|
+
if (options.live)
|
|
71
|
+
process.stderr.write(options.stderrPrefix ? prefixLines(text, options.stderrPrefix) : text);
|
|
72
|
+
});
|
|
73
|
+
child.on("error", (error) => {
|
|
74
|
+
clearTimeout(timer);
|
|
75
|
+
resolve({ exitCode: null, stdout, stderr: `${stderr}\n${error.message}`, durationMs: Date.now() - started });
|
|
76
|
+
});
|
|
77
|
+
child.on("close", (code) => {
|
|
78
|
+
clearTimeout(timer);
|
|
79
|
+
resolve({ exitCode: code, stdout, stderr, durationMs: Date.now() - started });
|
|
80
|
+
});
|
|
81
|
+
if (input)
|
|
82
|
+
child.stdin.write(input);
|
|
83
|
+
child.stdin.end();
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
function prefixLines(text, prefix) {
|
|
87
|
+
return text
|
|
88
|
+
.split(/(\r?\n)/)
|
|
89
|
+
.map((part) => (part === "\n" || part === "\r\n" || part === "" ? part : `${prefix}${part}`))
|
|
90
|
+
.join("");
|
|
91
|
+
}
|
|
92
|
+
export async function git(cwd, args) {
|
|
93
|
+
const result = await runCommand(`git ${args}`, cwd, undefined, 60_000);
|
|
94
|
+
return result.exitCode === 0 ? result.stdout.trim() : "";
|
|
95
|
+
}
|
package/dist/verify.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { writeFile } from "node:fs/promises";
|
|
2
|
+
import { runCommand, truncate } from "./utils.js";
|
|
3
|
+
export async function runVerify(cwd, config, skill, verifyPath) {
|
|
4
|
+
const commands = skill.verifyCommands.length ? skill.verifyCommands : config.verify.defaultCommands;
|
|
5
|
+
if (!commands.length) {
|
|
6
|
+
const skipped = { status: "skipped", commands: [] };
|
|
7
|
+
await writeFile(verifyPath, `${JSON.stringify(skipped, null, 2)}\n`, "utf8");
|
|
8
|
+
return skipped;
|
|
9
|
+
}
|
|
10
|
+
const results = [];
|
|
11
|
+
for (const command of commands) {
|
|
12
|
+
const result = await runCommand(command.command, cwd);
|
|
13
|
+
results.push({
|
|
14
|
+
name: command.name,
|
|
15
|
+
command: command.command,
|
|
16
|
+
exitCode: result.exitCode,
|
|
17
|
+
stdout: truncate(result.stdout, 6000),
|
|
18
|
+
stderr: truncate(result.stderr, 6000),
|
|
19
|
+
durationMs: result.durationMs
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
const verify = {
|
|
23
|
+
status: results.every((item) => item.exitCode === 0) ? "passed" : "failed",
|
|
24
|
+
commands: results
|
|
25
|
+
};
|
|
26
|
+
await writeFile(verifyPath, `${JSON.stringify(verify, null, 2)}\n`, "utf8");
|
|
27
|
+
return verify;
|
|
28
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ai-dev-harness",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Auditable AI development harness for Codex and Claude Code.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"ai",
|
|
8
|
+
"agent",
|
|
9
|
+
"codex",
|
|
10
|
+
"claude",
|
|
11
|
+
"harness",
|
|
12
|
+
"mcp",
|
|
13
|
+
"cli"
|
|
14
|
+
],
|
|
15
|
+
"type": "module",
|
|
16
|
+
"bin": {
|
|
17
|
+
"harness": "dist/cli.js"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist/",
|
|
21
|
+
"!dist/**/*.test.js",
|
|
22
|
+
"!dist/testSupport.js",
|
|
23
|
+
"scripts/",
|
|
24
|
+
"README.md",
|
|
25
|
+
"package.json"
|
|
26
|
+
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsc -p tsconfig.json",
|
|
29
|
+
"test": "npm run build && node --test dist/**/*.test.js",
|
|
30
|
+
"start": "node dist/cli.js",
|
|
31
|
+
"prepack": "npm run build"
|
|
32
|
+
},
|
|
33
|
+
"engines": {
|
|
34
|
+
"node": ">=20"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "^22.10.2",
|
|
38
|
+
"typescript": "^5.7.2"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
param(
|
|
2
|
+
[Parameter(Mandatory = $true)]
|
|
3
|
+
[string]$Run,
|
|
4
|
+
|
|
5
|
+
[string]$Repo = (Get-Location).Path
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
$ErrorActionPreference = "Stop"
|
|
9
|
+
|
|
10
|
+
$repoPath = Resolve-Path -LiteralPath $Repo
|
|
11
|
+
$runPath = if (Test-Path -LiteralPath $Run) {
|
|
12
|
+
Resolve-Path -LiteralPath $Run
|
|
13
|
+
} else {
|
|
14
|
+
Resolve-Path -LiteralPath (Join-Path $repoPath "runs\$Run")
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
Write-Host "[harness-skill] evidence: $runPath"
|
|
18
|
+
|
|
19
|
+
$summary = Join-Path $runPath "summary.md"
|
|
20
|
+
$verify = Join-Path $runPath "verify.json"
|
|
21
|
+
$audit = Join-Path $runPath "audit.jsonl"
|
|
22
|
+
|
|
23
|
+
if (Test-Path -LiteralPath $summary) {
|
|
24
|
+
Write-Host "`n--- summary.md ---"
|
|
25
|
+
Get-Content -LiteralPath $summary
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (Test-Path -LiteralPath $verify) {
|
|
29
|
+
Write-Host "`n--- verify.json ---"
|
|
30
|
+
Get-Content -LiteralPath $verify
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (Test-Path -LiteralPath $audit) {
|
|
34
|
+
Write-Host "`n--- audit degraded/errors ---"
|
|
35
|
+
Select-String -LiteralPath $audit -Pattern "degraded|failed|error|run_finished" | ForEach-Object { $_.Line }
|
|
36
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
param(
|
|
2
|
+
[Parameter(Mandatory = $true)]
|
|
3
|
+
[string]$Task,
|
|
4
|
+
|
|
5
|
+
[Parameter(Mandatory = $true)]
|
|
6
|
+
[ValidateSet("fix_bug", "add_feature", "write_tests", "update_docs")]
|
|
7
|
+
[string]$Skill,
|
|
8
|
+
|
|
9
|
+
[Parameter(Mandatory = $true)]
|
|
10
|
+
[ValidateSet("claude", "codex")]
|
|
11
|
+
[string]$Agent,
|
|
12
|
+
|
|
13
|
+
[string]$Repo = (Get-Location).Path,
|
|
14
|
+
|
|
15
|
+
[switch]$Live = $true
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
$ErrorActionPreference = "Stop"
|
|
19
|
+
|
|
20
|
+
$repoPath = Resolve-Path -LiteralPath $Repo
|
|
21
|
+
$harnessYaml = Join-Path $repoPath "harness.yaml"
|
|
22
|
+
$cliPath = Resolve-Path -LiteralPath (Join-Path $PSScriptRoot "..\dist\cli.js")
|
|
23
|
+
|
|
24
|
+
Write-Host "[harness-skill] repo: $repoPath"
|
|
25
|
+
Write-Host "[harness-skill] checking config: $harnessYaml"
|
|
26
|
+
|
|
27
|
+
if (-not (Test-Path -LiteralPath $harnessYaml)) {
|
|
28
|
+
Write-Error "harness.yaml not found in $repoPath. Run: node `"$cliPath`" init"
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
$gitCheck = git -C $repoPath rev-parse --show-toplevel 2>$null
|
|
32
|
+
if ($LASTEXITCODE -ne 0) {
|
|
33
|
+
Write-Error "$repoPath is not a Git repository. AI Dev Harness run requires a business Git repository."
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
$argsList = @(
|
|
37
|
+
$cliPath,
|
|
38
|
+
"run",
|
|
39
|
+
"--task",
|
|
40
|
+
$Task,
|
|
41
|
+
"--skill",
|
|
42
|
+
$Skill,
|
|
43
|
+
"--agent",
|
|
44
|
+
$Agent
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
if ($Live) {
|
|
48
|
+
$argsList += "--live"
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
Write-Host "[harness-skill] starting harness: $Skill via $Agent"
|
|
52
|
+
node @argsList
|
|
53
|
+
exit $LASTEXITCODE
|