cc-agent-harness 0.0.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 -0
- package/README.md +236 -0
- package/README.zh-CN.md +236 -0
- package/dist/chunk-3P72TGGQ.js +82 -0
- package/dist/chunk-3P72TGGQ.js.map +1 -0
- package/dist/chunk-JKJ3FP6T.js +51 -0
- package/dist/chunk-JKJ3FP6T.js.map +1 -0
- package/dist/chunk-LOE6IDTT.js +65 -0
- package/dist/chunk-LOE6IDTT.js.map +1 -0
- package/dist/chunk-PQWK2OBN.js +18 -0
- package/dist/chunk-PQWK2OBN.js.map +1 -0
- package/dist/chunk-R6VGYQOH.js +771 -0
- package/dist/chunk-R6VGYQOH.js.map +1 -0
- package/dist/config-PUMLWJWT.js +46 -0
- package/dist/config-PUMLWJWT.js.map +1 -0
- package/dist/context-SRWWNVTI.js +33 -0
- package/dist/context-SRWWNVTI.js.map +1 -0
- package/dist/doctor-TYLZH27K.js +199 -0
- package/dist/doctor-TYLZH27K.js.map +1 -0
- package/dist/harness.js +62 -0
- package/dist/harness.js.map +1 -0
- package/dist/index.d.ts +846 -0
- package/dist/index.js +1181 -0
- package/dist/index.js.map +1 -0
- package/dist/list-ABNY2TO7.js +124 -0
- package/dist/list-ABNY2TO7.js.map +1 -0
- package/dist/loader-RDQZFHOB.js +19 -0
- package/dist/loader-RDQZFHOB.js.map +1 -0
- package/dist/run-I5GVJH3N.js +45 -0
- package/dist/run-I5GVJH3N.js.map +1 -0
- package/dist/scaffold-C6JA3STC.js +98 -0
- package/dist/scaffold-C6JA3STC.js.map +1 -0
- package/dist/schema-AHX7LXUQ.js +27 -0
- package/dist/schema-AHX7LXUQ.js.map +1 -0
- package/dist/setup-CWDCKM34.js +115 -0
- package/dist/setup-CWDCKM34.js.map +1 -0
- package/dist/update-CTPDQCLU.js +87 -0
- package/dist/update-CTPDQCLU.js.map +1 -0
- package/dist/verify-NI3VCE2H.js +136 -0
- package/dist/verify-NI3VCE2H.js.map +1 -0
- package/package.json +61 -0
- package/templates/agents-md/full.md.tmpl +98 -0
- package/templates/agents-md/minimal.md.tmpl +20 -0
- package/templates/agents-md/standard.md.tmpl +43 -0
- package/templates/configs/harness.config.yaml.tmpl +28 -0
- package/templates/skills/basic/SKILL.md.tmpl +14 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
getTemplatesDir
|
|
4
|
+
} from "./chunk-PQWK2OBN.js";
|
|
5
|
+
import {
|
|
6
|
+
render
|
|
7
|
+
} from "./chunk-JKJ3FP6T.js";
|
|
8
|
+
import {
|
|
9
|
+
HarnessRuntime,
|
|
10
|
+
detectLanguage
|
|
11
|
+
} from "./chunk-R6VGYQOH.js";
|
|
12
|
+
import "./chunk-3P72TGGQ.js";
|
|
13
|
+
import "./chunk-LOE6IDTT.js";
|
|
14
|
+
|
|
15
|
+
// src/cli/setup.ts
|
|
16
|
+
import { mkdir, writeFile, readFile } from "fs/promises";
|
|
17
|
+
import { existsSync } from "fs";
|
|
18
|
+
import { resolve, join, basename } from "path";
|
|
19
|
+
import { stringify as yamlStringify } from "yaml";
|
|
20
|
+
async function runSetup(opts) {
|
|
21
|
+
const cwd = process.cwd();
|
|
22
|
+
const harnessDir = resolve(cwd, ".harness");
|
|
23
|
+
const preRuntime = await HarnessRuntime.create();
|
|
24
|
+
console.log("Agent Harness Setup");
|
|
25
|
+
console.log("===================\n");
|
|
26
|
+
const language = opts.language ?? detectLanguage(cwd);
|
|
27
|
+
const variant = opts.template ?? "standard";
|
|
28
|
+
await preRuntime.dispatchHooks("setup.pre", {
|
|
29
|
+
command: "setup",
|
|
30
|
+
language,
|
|
31
|
+
template: variant
|
|
32
|
+
});
|
|
33
|
+
console.log(` Detected language: ${language}`);
|
|
34
|
+
console.log(` Template variant: ${variant}
|
|
35
|
+
`);
|
|
36
|
+
if (existsSync(harnessDir)) {
|
|
37
|
+
console.log(" .harness/ directory already exists \u2014 updating configuration.\n");
|
|
38
|
+
} else {
|
|
39
|
+
await mkdir(harnessDir, { recursive: true });
|
|
40
|
+
console.log(" Created .harness/ directory.");
|
|
41
|
+
}
|
|
42
|
+
const skillsDir = resolve(harnessDir, "skills");
|
|
43
|
+
if (!existsSync(skillsDir)) {
|
|
44
|
+
await mkdir(skillsDir, { recursive: true });
|
|
45
|
+
console.log(" Created .harness/skills/ directory.");
|
|
46
|
+
}
|
|
47
|
+
const configPath = resolve(harnessDir, "harness.config.yaml");
|
|
48
|
+
const projectName = basename(cwd) || "my-project";
|
|
49
|
+
const config = {
|
|
50
|
+
project: {
|
|
51
|
+
name: projectName,
|
|
52
|
+
language,
|
|
53
|
+
description: ""
|
|
54
|
+
},
|
|
55
|
+
agents: {
|
|
56
|
+
delegation_first: true,
|
|
57
|
+
model_routing: {
|
|
58
|
+
low: "low",
|
|
59
|
+
medium: "medium",
|
|
60
|
+
high: "high"
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
skills: {
|
|
64
|
+
directories: [".harness/skills"],
|
|
65
|
+
auto_detect: true
|
|
66
|
+
},
|
|
67
|
+
workflows: {
|
|
68
|
+
verification: {
|
|
69
|
+
checks: ["build", "test", "lint"]
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
templates: {
|
|
73
|
+
agents_md: {
|
|
74
|
+
variant
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
await writeFile(configPath, yamlStringify(config), "utf-8");
|
|
79
|
+
console.log(" Generated harness.config.yaml.");
|
|
80
|
+
const agentsMdPath = resolve(cwd, "AGENTS.md");
|
|
81
|
+
if (!existsSync(agentsMdPath)) {
|
|
82
|
+
const templatesDir = getTemplatesDir();
|
|
83
|
+
const templateFile = join(templatesDir, "agents-md", `${variant}.md.tmpl`);
|
|
84
|
+
if (existsSync(templateFile)) {
|
|
85
|
+
const template = await readFile(templateFile, "utf-8");
|
|
86
|
+
const rendered = render(template, {
|
|
87
|
+
projectName,
|
|
88
|
+
language,
|
|
89
|
+
delegationFirst: "true",
|
|
90
|
+
customRules: []
|
|
91
|
+
});
|
|
92
|
+
await writeFile(agentsMdPath, rendered, "utf-8");
|
|
93
|
+
console.log(` Generated AGENTS.md (${variant} variant).`);
|
|
94
|
+
} else {
|
|
95
|
+
console.log(` Template ${variant}.md.tmpl not found \u2014 skipping AGENTS.md generation.`);
|
|
96
|
+
}
|
|
97
|
+
} else {
|
|
98
|
+
console.log(" AGENTS.md already exists \u2014 skipping (use `agent-harness update` to refresh).");
|
|
99
|
+
}
|
|
100
|
+
const postRuntime = await HarnessRuntime.create();
|
|
101
|
+
await postRuntime.dispatchHooks("setup.post", {
|
|
102
|
+
command: "setup",
|
|
103
|
+
language,
|
|
104
|
+
template: variant
|
|
105
|
+
});
|
|
106
|
+
await postRuntime.log("setup", "Setup completed", {
|
|
107
|
+
language,
|
|
108
|
+
template: variant
|
|
109
|
+
});
|
|
110
|
+
console.log("\nSetup complete! Run `agent-harness doctor` to verify.");
|
|
111
|
+
}
|
|
112
|
+
export {
|
|
113
|
+
runSetup
|
|
114
|
+
};
|
|
115
|
+
//# sourceMappingURL=setup-CWDCKM34.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/setup.ts"],"sourcesContent":["import { mkdir, writeFile, readFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { resolve, join, basename } from \"node:path\";\nimport { stringify as yamlStringify } from \"yaml\";\nimport { detectLanguage } from \"../adapter/detector.js\";\nimport { render } from \"../template/engine.js\";\nimport { getTemplatesDir } from \"./utils.js\";\nimport { HarnessRuntime } from \"../runtime/harness.js\";\n\nexport interface SetupOptions {\n language?: string;\n template?: string;\n}\n\nexport async function runSetup(opts: SetupOptions): Promise<void> {\n const cwd = process.cwd();\n const harnessDir = resolve(cwd, \".harness\");\n const preRuntime = await HarnessRuntime.create();\n\n console.log(\"Agent Harness Setup\");\n console.log(\"===================\\n\");\n\n const language = opts.language ?? detectLanguage(cwd);\n const variant = opts.template ?? \"standard\";\n\n await preRuntime.dispatchHooks(\"setup.pre\", {\n command: \"setup\",\n language,\n template: variant,\n });\n\n console.log(` Detected language: ${language}`);\n console.log(` Template variant: ${variant}\\n`);\n\n if (existsSync(harnessDir)) {\n console.log(\" .harness/ directory already exists — updating configuration.\\n\");\n } else {\n await mkdir(harnessDir, { recursive: true });\n console.log(\" Created .harness/ directory.\");\n }\n\n const skillsDir = resolve(harnessDir, \"skills\");\n if (!existsSync(skillsDir)) {\n await mkdir(skillsDir, { recursive: true });\n console.log(\" Created .harness/skills/ directory.\");\n }\n\n const configPath = resolve(harnessDir, \"harness.config.yaml\");\n const projectName = basename(cwd) || \"my-project\";\n\n const config = {\n project: {\n name: projectName,\n language,\n description: \"\",\n },\n agents: {\n delegation_first: true,\n model_routing: {\n low: \"low\",\n medium: \"medium\",\n high: \"high\",\n },\n },\n skills: {\n directories: [\".harness/skills\"],\n auto_detect: true,\n },\n workflows: {\n verification: {\n checks: [\"build\", \"test\", \"lint\"],\n },\n },\n templates: {\n agents_md: {\n variant,\n },\n },\n };\n\n await writeFile(configPath, yamlStringify(config), \"utf-8\");\n console.log(\" Generated harness.config.yaml.\");\n\n const agentsMdPath = resolve(cwd, \"AGENTS.md\");\n if (!existsSync(agentsMdPath)) {\n const templatesDir = getTemplatesDir();\n const templateFile = join(templatesDir, \"agents-md\", `${variant}.md.tmpl`);\n\n if (existsSync(templateFile)) {\n const template = await readFile(templateFile, \"utf-8\");\n const rendered = render(template, {\n projectName,\n language,\n delegationFirst: \"true\",\n customRules: [],\n });\n await writeFile(agentsMdPath, rendered, \"utf-8\");\n console.log(` Generated AGENTS.md (${variant} variant).`);\n } else {\n console.log(` Template ${variant}.md.tmpl not found — skipping AGENTS.md generation.`);\n }\n } else {\n console.log(\" AGENTS.md already exists — skipping (use `agent-harness update` to refresh).\");\n }\n\n const postRuntime = await HarnessRuntime.create();\n await postRuntime.dispatchHooks(\"setup.post\", {\n command: \"setup\",\n language,\n template: variant,\n });\n await postRuntime.log(\"setup\", \"Setup completed\", {\n language,\n template: variant,\n });\n\n console.log(\"\\nSetup complete! Run `agent-harness doctor` to verify.\");\n}\n"],"mappings":";;;;;;;;;;;;;;;AAAA,SAAS,OAAO,WAAW,gBAAgB;AAC3C,SAAS,kBAAkB;AAC3B,SAAS,SAAS,MAAM,gBAAgB;AACxC,SAAS,aAAa,qBAAqB;AAW3C,eAAsB,SAAS,MAAmC;AAChE,QAAM,MAAM,QAAQ,IAAI;AACxB,QAAM,aAAa,QAAQ,KAAK,UAAU;AAC1C,QAAM,aAAa,MAAM,eAAe,OAAO;AAE/C,UAAQ,IAAI,qBAAqB;AACjC,UAAQ,IAAI,uBAAuB;AAEnC,QAAM,WAAW,KAAK,YAAY,eAAe,GAAG;AACpD,QAAM,UAAU,KAAK,YAAY;AAEjC,QAAM,WAAW,cAAc,aAAa;AAAA,IAC1C,SAAS;AAAA,IACT;AAAA,IACA,UAAU;AAAA,EACZ,CAAC;AAED,UAAQ,IAAI,wBAAwB,QAAQ,EAAE;AAC9C,UAAQ,IAAI,wBAAwB,OAAO;AAAA,CAAI;AAE/C,MAAI,WAAW,UAAU,GAAG;AAC1B,YAAQ,IAAI,uEAAkE;AAAA,EAChF,OAAO;AACL,UAAM,MAAM,YAAY,EAAE,WAAW,KAAK,CAAC;AAC3C,YAAQ,IAAI,gCAAgC;AAAA,EAC9C;AAEA,QAAM,YAAY,QAAQ,YAAY,QAAQ;AAC9C,MAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,UAAM,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;AAC1C,YAAQ,IAAI,uCAAuC;AAAA,EACrD;AAEA,QAAM,aAAa,QAAQ,YAAY,qBAAqB;AAC5D,QAAM,cAAc,SAAS,GAAG,KAAK;AAErC,QAAM,SAAS;AAAA,IACb,SAAS;AAAA,MACP,MAAM;AAAA,MACN;AAAA,MACA,aAAa;AAAA,IACf;AAAA,IACA,QAAQ;AAAA,MACN,kBAAkB;AAAA,MAClB,eAAe;AAAA,QACb,KAAK;AAAA,QACL,QAAQ;AAAA,QACR,MAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,MACN,aAAa,CAAC,iBAAiB;AAAA,MAC/B,aAAa;AAAA,IACf;AAAA,IACA,WAAW;AAAA,MACT,cAAc;AAAA,QACZ,QAAQ,CAAC,SAAS,QAAQ,MAAM;AAAA,MAClC;AAAA,IACF;AAAA,IACA,WAAW;AAAA,MACT,WAAW;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,YAAY,cAAc,MAAM,GAAG,OAAO;AAC1D,UAAQ,IAAI,kCAAkC;AAE9C,QAAM,eAAe,QAAQ,KAAK,WAAW;AAC7C,MAAI,CAAC,WAAW,YAAY,GAAG;AAC7B,UAAM,eAAe,gBAAgB;AACrC,UAAM,eAAe,KAAK,cAAc,aAAa,GAAG,OAAO,UAAU;AAEzE,QAAI,WAAW,YAAY,GAAG;AAC5B,YAAM,WAAW,MAAM,SAAS,cAAc,OAAO;AACrD,YAAM,WAAW,OAAO,UAAU;AAAA,QAChC;AAAA,QACA;AAAA,QACA,iBAAiB;AAAA,QACjB,aAAa,CAAC;AAAA,MAChB,CAAC;AACD,YAAM,UAAU,cAAc,UAAU,OAAO;AAC/C,cAAQ,IAAI,0BAA0B,OAAO,YAAY;AAAA,IAC3D,OAAO;AACL,cAAQ,IAAI,cAAc,OAAO,0DAAqD;AAAA,IACxF;AAAA,EACF,OAAO;AACL,YAAQ,IAAI,qFAAgF;AAAA,EAC9F;AAEA,QAAM,cAAc,MAAM,eAAe,OAAO;AAChD,QAAM,YAAY,cAAc,cAAc;AAAA,IAC5C,SAAS;AAAA,IACT;AAAA,IACA,UAAU;AAAA,EACZ,CAAC;AACD,QAAM,YAAY,IAAI,SAAS,mBAAmB;AAAA,IAChD;AAAA,IACA,UAAU;AAAA,EACZ,CAAC;AAED,UAAQ,IAAI,yDAAyD;AACvE;","names":[]}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
getTemplatesDir
|
|
4
|
+
} from "./chunk-PQWK2OBN.js";
|
|
5
|
+
import {
|
|
6
|
+
render
|
|
7
|
+
} from "./chunk-JKJ3FP6T.js";
|
|
8
|
+
import {
|
|
9
|
+
HarnessRuntime
|
|
10
|
+
} from "./chunk-R6VGYQOH.js";
|
|
11
|
+
import {
|
|
12
|
+
projectConfigExists
|
|
13
|
+
} from "./chunk-3P72TGGQ.js";
|
|
14
|
+
import "./chunk-LOE6IDTT.js";
|
|
15
|
+
|
|
16
|
+
// src/cli/update.ts
|
|
17
|
+
import { readFile, writeFile } from "fs/promises";
|
|
18
|
+
import { existsSync } from "fs";
|
|
19
|
+
import { resolve, join } from "path";
|
|
20
|
+
async function runUpdate(opts) {
|
|
21
|
+
const cwd = process.cwd();
|
|
22
|
+
const dryRun = opts.check ?? false;
|
|
23
|
+
console.log(`Agent Harness Update${dryRun ? " (dry-run)" : ""}`);
|
|
24
|
+
console.log("====================\n");
|
|
25
|
+
if (!projectConfigExists(cwd)) {
|
|
26
|
+
console.log(" No harness configuration found. Run `agent-harness setup` first.");
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const runtime = await HarnessRuntime.create({ requireProjectConfig: true });
|
|
30
|
+
const config = runtime.config;
|
|
31
|
+
const templatesDir = getTemplatesDir();
|
|
32
|
+
if (!config) {
|
|
33
|
+
throw new Error("Runtime expected configuration but none was loaded.");
|
|
34
|
+
}
|
|
35
|
+
await runtime.dispatchHooks("update.pre", {
|
|
36
|
+
command: "update",
|
|
37
|
+
dryRun,
|
|
38
|
+
template: opts.template ?? null
|
|
39
|
+
});
|
|
40
|
+
if (!opts.template || opts.template === "agents-md") {
|
|
41
|
+
await updateAgentsMd(cwd, config, templatesDir, dryRun);
|
|
42
|
+
}
|
|
43
|
+
await runtime.dispatchHooks("update.post", {
|
|
44
|
+
command: "update",
|
|
45
|
+
dryRun,
|
|
46
|
+
template: opts.template ?? null
|
|
47
|
+
});
|
|
48
|
+
await runtime.log("update", dryRun ? "Update dry-run completed" : "Update completed", {
|
|
49
|
+
dryRun,
|
|
50
|
+
template: opts.template ?? null
|
|
51
|
+
});
|
|
52
|
+
console.log(dryRun ? "\nDry-run complete. No files modified." : "\nUpdate complete.");
|
|
53
|
+
}
|
|
54
|
+
async function updateAgentsMd(cwd, config, templatesDir, dryRun) {
|
|
55
|
+
const variant = config.templates.agents_md.variant;
|
|
56
|
+
const templateFile = join(templatesDir, "agents-md", `${variant}.md.tmpl`);
|
|
57
|
+
if (!existsSync(templateFile)) {
|
|
58
|
+
console.log(` Template ${variant}.md.tmpl not found \u2014 skipping AGENTS.md.`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const template = await readFile(templateFile, "utf-8");
|
|
62
|
+
const rendered = render(template, {
|
|
63
|
+
projectName: config.project.name,
|
|
64
|
+
language: config.project.language,
|
|
65
|
+
delegationFirst: String(config.agents.delegation_first),
|
|
66
|
+
customRules: config.templates.agents_md.custom_rules
|
|
67
|
+
});
|
|
68
|
+
const agentsMdPath = resolve(cwd, "AGENTS.md");
|
|
69
|
+
if (existsSync(agentsMdPath)) {
|
|
70
|
+
const current = await readFile(agentsMdPath, "utf-8");
|
|
71
|
+
if (current === rendered) {
|
|
72
|
+
console.log(" AGENTS.md is up to date.");
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
console.log(` AGENTS.md would be updated (${variant} variant).`);
|
|
76
|
+
} else {
|
|
77
|
+
console.log(` AGENTS.md would be created (${variant} variant).`);
|
|
78
|
+
}
|
|
79
|
+
if (!dryRun) {
|
|
80
|
+
await writeFile(agentsMdPath, rendered, "utf-8");
|
|
81
|
+
console.log(" AGENTS.md updated.");
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
export {
|
|
85
|
+
runUpdate
|
|
86
|
+
};
|
|
87
|
+
//# sourceMappingURL=update-CTPDQCLU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/update.ts"],"sourcesContent":["import { readFile, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { resolve, join } from \"node:path\";\nimport { projectConfigExists } from \"../config/loader.js\";\nimport type { HarnessConfig } from \"../config/loader.js\";\nimport { render } from \"../template/engine.js\";\nimport { getTemplatesDir } from \"./utils.js\";\nimport { HarnessRuntime } from \"../runtime/harness.js\";\n\nexport interface UpdateOptions {\n check?: boolean;\n template?: string;\n}\n\nexport async function runUpdate(opts: UpdateOptions): Promise<void> {\n const cwd = process.cwd();\n const dryRun = opts.check ?? false;\n\n console.log(`Agent Harness Update${dryRun ? \" (dry-run)\" : \"\"}`);\n console.log(\"====================\\n\");\n\n if (!projectConfigExists(cwd)) {\n console.log(\" No harness configuration found. Run `agent-harness setup` first.\");\n return;\n }\n\n const runtime = await HarnessRuntime.create({ requireProjectConfig: true });\n const config = runtime.config;\n const templatesDir = getTemplatesDir();\n\n if (!config) {\n throw new Error(\"Runtime expected configuration but none was loaded.\");\n }\n\n await runtime.dispatchHooks(\"update.pre\", {\n command: \"update\",\n dryRun,\n template: opts.template ?? null,\n });\n\n if (!opts.template || opts.template === \"agents-md\") {\n await updateAgentsMd(cwd, config, templatesDir, dryRun);\n }\n\n await runtime.dispatchHooks(\"update.post\", {\n command: \"update\",\n dryRun,\n template: opts.template ?? null,\n });\n await runtime.log(\"update\", dryRun ? \"Update dry-run completed\" : \"Update completed\", {\n dryRun,\n template: opts.template ?? null,\n });\n\n console.log(dryRun ? \"\\nDry-run complete. No files modified.\" : \"\\nUpdate complete.\");\n}\n\nasync function updateAgentsMd(\n cwd: string,\n config: HarnessConfig,\n templatesDir: string,\n dryRun: boolean,\n): Promise<void> {\n const variant = config.templates.agents_md.variant;\n const templateFile = join(templatesDir, \"agents-md\", `${variant}.md.tmpl`);\n\n if (!existsSync(templateFile)) {\n console.log(` Template ${variant}.md.tmpl not found — skipping AGENTS.md.`);\n return;\n }\n\n const template = await readFile(templateFile, \"utf-8\");\n const rendered = render(template, {\n projectName: config.project.name,\n language: config.project.language,\n delegationFirst: String(config.agents.delegation_first),\n customRules: config.templates.agents_md.custom_rules,\n });\n\n const agentsMdPath = resolve(cwd, \"AGENTS.md\");\n if (existsSync(agentsMdPath)) {\n const current = await readFile(agentsMdPath, \"utf-8\");\n if (current === rendered) {\n console.log(\" AGENTS.md is up to date.\");\n return;\n }\n console.log(` AGENTS.md would be updated (${variant} variant).`);\n } else {\n console.log(` AGENTS.md would be created (${variant} variant).`);\n }\n\n if (!dryRun) {\n await writeFile(agentsMdPath, rendered, \"utf-8\");\n console.log(\" AGENTS.md updated.\");\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA,SAAS,UAAU,iBAAiB;AACpC,SAAS,kBAAkB;AAC3B,SAAS,SAAS,YAAY;AAY9B,eAAsB,UAAU,MAAoC;AAClE,QAAM,MAAM,QAAQ,IAAI;AACxB,QAAM,SAAS,KAAK,SAAS;AAE7B,UAAQ,IAAI,uBAAuB,SAAS,eAAe,EAAE,EAAE;AAC/D,UAAQ,IAAI,wBAAwB;AAEpC,MAAI,CAAC,oBAAoB,GAAG,GAAG;AAC7B,YAAQ,IAAI,oEAAoE;AAChF;AAAA,EACF;AAEA,QAAM,UAAU,MAAM,eAAe,OAAO,EAAE,sBAAsB,KAAK,CAAC;AAC1E,QAAM,SAAS,QAAQ;AACvB,QAAM,eAAe,gBAAgB;AAErC,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AAEA,QAAM,QAAQ,cAAc,cAAc;AAAA,IACxC,SAAS;AAAA,IACT;AAAA,IACA,UAAU,KAAK,YAAY;AAAA,EAC7B,CAAC;AAED,MAAI,CAAC,KAAK,YAAY,KAAK,aAAa,aAAa;AACnD,UAAM,eAAe,KAAK,QAAQ,cAAc,MAAM;AAAA,EACxD;AAEA,QAAM,QAAQ,cAAc,eAAe;AAAA,IACzC,SAAS;AAAA,IACT;AAAA,IACA,UAAU,KAAK,YAAY;AAAA,EAC7B,CAAC;AACD,QAAM,QAAQ,IAAI,UAAU,SAAS,6BAA6B,oBAAoB;AAAA,IACpF;AAAA,IACA,UAAU,KAAK,YAAY;AAAA,EAC7B,CAAC;AAED,UAAQ,IAAI,SAAS,2CAA2C,oBAAoB;AACtF;AAEA,eAAe,eACb,KACA,QACA,cACA,QACe;AACf,QAAM,UAAU,OAAO,UAAU,UAAU;AAC3C,QAAM,eAAe,KAAK,cAAc,aAAa,GAAG,OAAO,UAAU;AAEzE,MAAI,CAAC,WAAW,YAAY,GAAG;AAC7B,YAAQ,IAAI,cAAc,OAAO,+CAA0C;AAC3E;AAAA,EACF;AAEA,QAAM,WAAW,MAAM,SAAS,cAAc,OAAO;AACrD,QAAM,WAAW,OAAO,UAAU;AAAA,IAChC,aAAa,OAAO,QAAQ;AAAA,IAC5B,UAAU,OAAO,QAAQ;AAAA,IACzB,iBAAiB,OAAO,OAAO,OAAO,gBAAgB;AAAA,IACtD,aAAa,OAAO,UAAU,UAAU;AAAA,EAC1C,CAAC;AAED,QAAM,eAAe,QAAQ,KAAK,WAAW;AAC7C,MAAI,WAAW,YAAY,GAAG;AAC5B,UAAM,UAAU,MAAM,SAAS,cAAc,OAAO;AACpD,QAAI,YAAY,UAAU;AACxB,cAAQ,IAAI,4BAA4B;AACxC;AAAA,IACF;AACA,YAAQ,IAAI,iCAAiC,OAAO,YAAY;AAAA,EAClE,OAAO;AACL,YAAQ,IAAI,iCAAiC,OAAO,YAAY;AAAA,EAClE;AAEA,MAAI,CAAC,QAAQ;AACX,UAAM,UAAU,cAAc,UAAU,OAAO;AAC/C,YAAQ,IAAI,sBAAsB;AAAA,EACpC;AACF;","names":[]}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
HarnessRuntime
|
|
4
|
+
} from "./chunk-R6VGYQOH.js";
|
|
5
|
+
import "./chunk-3P72TGGQ.js";
|
|
6
|
+
import "./chunk-LOE6IDTT.js";
|
|
7
|
+
|
|
8
|
+
// src/cli/verify.ts
|
|
9
|
+
import { execSync } from "child_process";
|
|
10
|
+
async function runVerify(opts) {
|
|
11
|
+
const runtime = await HarnessRuntime.create({ requireProjectConfig: true });
|
|
12
|
+
const config = runtime.config;
|
|
13
|
+
if (!config) {
|
|
14
|
+
throw new Error("Runtime expected configuration but none was loaded.");
|
|
15
|
+
}
|
|
16
|
+
const globalFailFast = opts.failFast ?? config.workflows.verification.fail_fast;
|
|
17
|
+
const stages = buildPipeline(config, runtime.listTasks());
|
|
18
|
+
if (stages.length === 0) {
|
|
19
|
+
if (opts.json) {
|
|
20
|
+
console.log(JSON.stringify({ results: [], summary: { pass: 0, fail: 0, skip: 0, totalMs: 0 } }, null, 2));
|
|
21
|
+
} else {
|
|
22
|
+
console.log("Agent Harness Verification");
|
|
23
|
+
console.log("==========================\n");
|
|
24
|
+
console.log(" No verification stages configured.");
|
|
25
|
+
}
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (!opts.json) {
|
|
29
|
+
console.log("Agent Harness Verification");
|
|
30
|
+
console.log("==========================\n");
|
|
31
|
+
}
|
|
32
|
+
await runtime.dispatchHooks("verify.pre", {
|
|
33
|
+
command: "verify",
|
|
34
|
+
stages: stages.map((stage) => stage.name)
|
|
35
|
+
});
|
|
36
|
+
const results = [];
|
|
37
|
+
let failed = false;
|
|
38
|
+
for (const stage of stages) {
|
|
39
|
+
if (!stage.command) {
|
|
40
|
+
if (!opts.json) {
|
|
41
|
+
console.log(` [SKIP] ${stage.name} \u2014 no command configured`);
|
|
42
|
+
}
|
|
43
|
+
results.push({
|
|
44
|
+
stage: stage.name,
|
|
45
|
+
command: "",
|
|
46
|
+
source: stage.source,
|
|
47
|
+
status: "skip",
|
|
48
|
+
durationMs: 0
|
|
49
|
+
});
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
const start = Date.now();
|
|
53
|
+
try {
|
|
54
|
+
execSync(stage.command, { cwd: runtime.cwd, stdio: "pipe", timeout: 12e4 });
|
|
55
|
+
const durationMs = Date.now() - start;
|
|
56
|
+
if (!opts.json) {
|
|
57
|
+
console.log(` [PASS] ${stage.name} \u2014 ${stage.command} (${durationMs}ms)`);
|
|
58
|
+
}
|
|
59
|
+
results.push({
|
|
60
|
+
stage: stage.name,
|
|
61
|
+
command: stage.command,
|
|
62
|
+
source: stage.source,
|
|
63
|
+
status: "pass",
|
|
64
|
+
durationMs
|
|
65
|
+
});
|
|
66
|
+
} catch (err) {
|
|
67
|
+
const durationMs = Date.now() - start;
|
|
68
|
+
const output = err instanceof Error ? err.stderr?.toString() ?? err.message : String(err);
|
|
69
|
+
if (!opts.json) {
|
|
70
|
+
console.log(` [FAIL] ${stage.name} \u2014 ${stage.command} (${durationMs}ms)`);
|
|
71
|
+
}
|
|
72
|
+
results.push({
|
|
73
|
+
stage: stage.name,
|
|
74
|
+
command: stage.command,
|
|
75
|
+
source: stage.source,
|
|
76
|
+
status: "fail",
|
|
77
|
+
durationMs,
|
|
78
|
+
output
|
|
79
|
+
});
|
|
80
|
+
failed = true;
|
|
81
|
+
const shouldStop = globalFailFast || stage.failFast;
|
|
82
|
+
if (shouldStop) {
|
|
83
|
+
if (!opts.json) {
|
|
84
|
+
console.log(`
|
|
85
|
+
Stopping: fail_fast enabled for stage "${stage.name}".`);
|
|
86
|
+
}
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const passed = results.filter((r) => r.status === "pass").length;
|
|
92
|
+
const failures = results.filter((r) => r.status === "fail").length;
|
|
93
|
+
const skipped = results.filter((r) => r.status === "skip").length;
|
|
94
|
+
const totalMs = results.reduce((sum, r) => sum + r.durationMs, 0);
|
|
95
|
+
const summary = { pass: passed, fail: failures, skip: skipped, totalMs };
|
|
96
|
+
await runtime.dispatchHooks("verify.post", {
|
|
97
|
+
command: "verify",
|
|
98
|
+
summary,
|
|
99
|
+
status: failed ? "fail" : "pass"
|
|
100
|
+
});
|
|
101
|
+
await runtime.log("verify", "Verification run completed", {
|
|
102
|
+
summary,
|
|
103
|
+
failed
|
|
104
|
+
});
|
|
105
|
+
if (opts.json) {
|
|
106
|
+
console.log(JSON.stringify({ results, summary }, null, 2));
|
|
107
|
+
} else {
|
|
108
|
+
console.log(`
|
|
109
|
+
Verification: ${passed} passed, ${failures} failed, ${skipped} skipped (${totalMs}ms total)`);
|
|
110
|
+
}
|
|
111
|
+
if (failed) {
|
|
112
|
+
process.exitCode = 1;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function buildPipeline(config, tasks) {
|
|
116
|
+
const verification = config.workflows.verification;
|
|
117
|
+
const commandMap = new Map(tasks.map((task) => [task.name, task]));
|
|
118
|
+
if (verification.pipeline && verification.pipeline.length > 0) {
|
|
119
|
+
return verification.pipeline.map((s) => ({
|
|
120
|
+
name: s.name,
|
|
121
|
+
command: s.command ?? commandMap.get(s.name)?.command ?? config.workflows.commands[s.name],
|
|
122
|
+
source: s.command ? "pipeline" : commandMap.get(s.name)?.source ?? "workflow",
|
|
123
|
+
failFast: s.fail_fast
|
|
124
|
+
}));
|
|
125
|
+
}
|
|
126
|
+
return verification.checks.map((check) => ({
|
|
127
|
+
name: check,
|
|
128
|
+
command: commandMap.get(check)?.command ?? config.workflows.commands[check],
|
|
129
|
+
source: commandMap.get(check)?.source ?? "workflow",
|
|
130
|
+
failFast: verification.fail_fast
|
|
131
|
+
}));
|
|
132
|
+
}
|
|
133
|
+
export {
|
|
134
|
+
runVerify
|
|
135
|
+
};
|
|
136
|
+
//# sourceMappingURL=verify-NI3VCE2H.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/verify.ts"],"sourcesContent":["import { execSync } from \"node:child_process\";\nimport { HarnessRuntime, type RuntimeTask } from \"../runtime/harness.js\";\n\nexport interface VerifyOptions {\n failFast?: boolean;\n json?: boolean;\n}\n\nexport interface StageResult {\n stage: string;\n command: string;\n source?: RuntimeTask[\"source\"] | \"pipeline\";\n status: \"pass\" | \"fail\" | \"skip\";\n durationMs: number;\n output?: string;\n}\n\nexport async function runVerify(opts: VerifyOptions): Promise<void> {\n const runtime = await HarnessRuntime.create({ requireProjectConfig: true });\n const config = runtime.config;\n\n if (!config) {\n throw new Error(\"Runtime expected configuration but none was loaded.\");\n }\n\n const globalFailFast = opts.failFast ?? config.workflows.verification.fail_fast;\n const stages = buildPipeline(config, runtime.listTasks());\n\n if (stages.length === 0) {\n if (opts.json) {\n console.log(JSON.stringify({ results: [], summary: { pass: 0, fail: 0, skip: 0, totalMs: 0 } }, null, 2));\n } else {\n console.log(\"Agent Harness Verification\");\n console.log(\"==========================\\n\");\n console.log(\" No verification stages configured.\");\n }\n return;\n }\n\n if (!opts.json) {\n console.log(\"Agent Harness Verification\");\n console.log(\"==========================\\n\");\n }\n\n await runtime.dispatchHooks(\"verify.pre\", {\n command: \"verify\",\n stages: stages.map((stage) => stage.name),\n });\n\n const results: StageResult[] = [];\n let failed = false;\n\n for (const stage of stages) {\n if (!stage.command) {\n if (!opts.json) {\n console.log(` [SKIP] ${stage.name} — no command configured`);\n }\n results.push({\n stage: stage.name,\n command: \"\",\n source: stage.source,\n status: \"skip\",\n durationMs: 0,\n });\n continue;\n }\n\n const start = Date.now();\n try {\n execSync(stage.command, { cwd: runtime.cwd, stdio: \"pipe\", timeout: 120_000 });\n const durationMs = Date.now() - start;\n if (!opts.json) {\n console.log(` [PASS] ${stage.name} — ${stage.command} (${durationMs}ms)`);\n }\n results.push({\n stage: stage.name,\n command: stage.command,\n source: stage.source,\n status: \"pass\",\n durationMs,\n });\n } catch (err) {\n const durationMs = Date.now() - start;\n const output = err instanceof Error ? (err as { stderr?: Buffer }).stderr?.toString() ?? err.message : String(err);\n if (!opts.json) {\n console.log(` [FAIL] ${stage.name} — ${stage.command} (${durationMs}ms)`);\n }\n results.push({\n stage: stage.name,\n command: stage.command,\n source: stage.source,\n status: \"fail\",\n durationMs,\n output,\n });\n failed = true;\n\n const shouldStop = globalFailFast || stage.failFast;\n if (shouldStop) {\n if (!opts.json) {\n console.log(`\\n Stopping: fail_fast enabled for stage \"${stage.name}\".`);\n }\n break;\n }\n }\n }\n\n const passed = results.filter((r) => r.status === \"pass\").length;\n const failures = results.filter((r) => r.status === \"fail\").length;\n const skipped = results.filter((r) => r.status === \"skip\").length;\n const totalMs = results.reduce((sum, r) => sum + r.durationMs, 0);\n\n const summary = { pass: passed, fail: failures, skip: skipped, totalMs };\n await runtime.dispatchHooks(\"verify.post\", {\n command: \"verify\",\n summary,\n status: failed ? \"fail\" : \"pass\",\n });\n await runtime.log(\"verify\", \"Verification run completed\", {\n summary,\n failed,\n });\n\n if (opts.json) {\n console.log(JSON.stringify({ results, summary }, null, 2));\n } else {\n console.log(`\\nVerification: ${passed} passed, ${failures} failed, ${skipped} skipped (${totalMs}ms total)`);\n }\n\n if (failed) {\n process.exitCode = 1;\n }\n}\n\ninterface PipelineStage {\n name: string;\n command: string | undefined;\n source?: RuntimeTask[\"source\"] | \"pipeline\";\n failFast: boolean;\n}\n\nfunction buildPipeline(\n config: NonNullable<HarnessRuntime[\"config\"]>,\n tasks: RuntimeTask[],\n): PipelineStage[] {\n const verification = config.workflows.verification;\n const commandMap = new Map(tasks.map((task) => [task.name, task] as const));\n\n if (verification.pipeline && verification.pipeline.length > 0) {\n return verification.pipeline.map((s) => ({\n name: s.name,\n command: s.command ?? commandMap.get(s.name)?.command ?? config.workflows.commands[s.name],\n source: s.command ? \"pipeline\" : commandMap.get(s.name)?.source ?? \"workflow\",\n failFast: s.fail_fast,\n }));\n }\n\n return verification.checks.map((check) => ({\n name: check,\n command: commandMap.get(check)?.command ?? config.workflows.commands[check],\n source: commandMap.get(check)?.source ?? \"workflow\",\n failFast: verification.fail_fast,\n }));\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cc-agent-harness",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Universal development pipeline harness — configuration, templates, skill management, and health checks for AI-assisted projects.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/KwokJay/cc-agent-harness.git"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/KwokJay/cc-agent-harness#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/KwokJay/cc-agent-harness/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"agent",
|
|
17
|
+
"harness",
|
|
18
|
+
"cli",
|
|
19
|
+
"ai",
|
|
20
|
+
"workflow",
|
|
21
|
+
"context-engineering",
|
|
22
|
+
"developer-tools"
|
|
23
|
+
],
|
|
24
|
+
"bin": {
|
|
25
|
+
"agent-harness": "./dist/harness.js"
|
|
26
|
+
},
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"import": "./dist/index.js",
|
|
30
|
+
"types": "./dist/index.d.ts"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist",
|
|
35
|
+
"templates"
|
|
36
|
+
],
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "tsup",
|
|
39
|
+
"build:watch": "tsup --watch",
|
|
40
|
+
"clean": "rm -rf dist",
|
|
41
|
+
"lint": "tsc --noEmit",
|
|
42
|
+
"test": "vitest run",
|
|
43
|
+
"test:watch": "vitest",
|
|
44
|
+
"prepublishOnly": "pnpm lint && pnpm test && pnpm build"
|
|
45
|
+
},
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=22"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"commander": "^13.1.0",
|
|
51
|
+
"yaml": "^2.7.0",
|
|
52
|
+
"zod": "^3.24.2",
|
|
53
|
+
"zod-to-json-schema": "^3.25.1"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@types/node": "^22.15.0",
|
|
57
|
+
"tsup": "^8.5.0",
|
|
58
|
+
"typescript": "^5.9.2",
|
|
59
|
+
"vitest": "^3.1.0"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# {{projectName}}
|
|
2
|
+
|
|
3
|
+
## Project Info
|
|
4
|
+
|
|
5
|
+
- **Language**: {{language}}
|
|
6
|
+
|
|
7
|
+
## Coding Guidelines
|
|
8
|
+
|
|
9
|
+
- Follow established project conventions and style guides.
|
|
10
|
+
- Write clear, self-documenting code with minimal comments.
|
|
11
|
+
- Prefer editing existing files over creating new ones.
|
|
12
|
+
- Run tests after making changes to verify correctness.
|
|
13
|
+
- Run linters/formatters before finalizing changes.
|
|
14
|
+
- Do not create small helper methods referenced only once.
|
|
15
|
+
- Prefer exhaustive match/switch statements over wildcard arms.
|
|
16
|
+
{{#each customRules}}
|
|
17
|
+
- {{.}}
|
|
18
|
+
{{/each}}
|
|
19
|
+
|
|
20
|
+
## Delegation-First Philosophy
|
|
21
|
+
|
|
22
|
+
**Your job is to ORCHESTRATE specialists, not to do work yourself.**
|
|
23
|
+
|
|
24
|
+
| Action | Do Directly | Delegate |
|
|
25
|
+
|--------|-------------|----------|
|
|
26
|
+
| Read files for context | Yes | — |
|
|
27
|
+
| Quick status checks | Yes | — |
|
|
28
|
+
| Communicate with user | Yes | — |
|
|
29
|
+
| Code changes | NEVER | executor |
|
|
30
|
+
| Complex debugging | NEVER | architect |
|
|
31
|
+
| UI/frontend work | NEVER | designer |
|
|
32
|
+
| Documentation | NEVER | writer |
|
|
33
|
+
| Deep analysis | NEVER | architect / analyst |
|
|
34
|
+
|
|
35
|
+
## Smart Model Routing
|
|
36
|
+
|
|
37
|
+
| Task Complexity | Tier | When to Use |
|
|
38
|
+
|-----------------|------|-------------|
|
|
39
|
+
| Simple lookup | low | "What does this return?" |
|
|
40
|
+
| Standard work | medium | "Add error handling" |
|
|
41
|
+
| Complex reasoning | high | "Debug race condition" |
|
|
42
|
+
|
|
43
|
+
## Verification Protocol
|
|
44
|
+
|
|
45
|
+
**Iron Law: NO COMPLETION CLAIMS WITHOUT FRESH VERIFICATION EVIDENCE.**
|
|
46
|
+
|
|
47
|
+
Before ANY agent says "done", "fixed", or "complete":
|
|
48
|
+
|
|
49
|
+
| Step | Action |
|
|
50
|
+
|------|--------|
|
|
51
|
+
| 1 | IDENTIFY: What command proves this claim? |
|
|
52
|
+
| 2 | RUN: Execute verification command |
|
|
53
|
+
| 3 | READ: Check output — did it pass? |
|
|
54
|
+
| 4 | CLAIM: Make claim WITH evidence |
|
|
55
|
+
|
|
56
|
+
Required evidence:
|
|
57
|
+
|
|
58
|
+
| Claim | Required Evidence |
|
|
59
|
+
|-------|-------------------|
|
|
60
|
+
| "Fixed" | Test showing it passes now |
|
|
61
|
+
| "Implemented" | Build clean + tests pass |
|
|
62
|
+
| "Refactored" | All tests still pass |
|
|
63
|
+
| "Debugged" | Root cause identified with file:line |
|
|
64
|
+
|
|
65
|
+
## Parallelization Rules
|
|
66
|
+
|
|
67
|
+
- 2+ independent tasks with >30s work → Run in parallel
|
|
68
|
+
- Sequential dependencies → Run in order
|
|
69
|
+
- Quick tasks (<10s) → Do directly
|
|
70
|
+
|
|
71
|
+
## Skills
|
|
72
|
+
|
|
73
|
+
Skills are discovered from:
|
|
74
|
+
|
|
75
|
+
- `.harness/skills/`
|
|
76
|
+
|
|
77
|
+
## Agent Catalog
|
|
78
|
+
|
|
79
|
+
### Analysis
|
|
80
|
+
- `architect-low` (low) / `architect-medium` (medium) / `architect` (high)
|
|
81
|
+
|
|
82
|
+
### Execution
|
|
83
|
+
- `executor-low` (low) / `executor` (medium) / `executor-high` (high)
|
|
84
|
+
|
|
85
|
+
### Search
|
|
86
|
+
- `explore` (low) / `explore-medium` (medium) / `explore-high` (high)
|
|
87
|
+
|
|
88
|
+
### Frontend
|
|
89
|
+
- `designer-low` (low) / `designer` (medium) / `designer-high` (high)
|
|
90
|
+
|
|
91
|
+
### Testing
|
|
92
|
+
- `qa-tester` (medium) / `qa-tester-high` (high)
|
|
93
|
+
|
|
94
|
+
### Code Review
|
|
95
|
+
- `code-reviewer-low` (low) / `code-reviewer` (high)
|
|
96
|
+
|
|
97
|
+
### Security
|
|
98
|
+
- `security-reviewer-low` (low) / `security-reviewer` (high)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# {{projectName}}
|
|
2
|
+
|
|
3
|
+
## Project Info
|
|
4
|
+
|
|
5
|
+
- **Language**: {{language}}
|
|
6
|
+
|
|
7
|
+
## Coding Guidelines
|
|
8
|
+
|
|
9
|
+
- Follow established project conventions.
|
|
10
|
+
- Write clear, self-documenting code.
|
|
11
|
+
- Prefer editing existing files over creating new ones.
|
|
12
|
+
{{#each customRules}}
|
|
13
|
+
- {{.}}
|
|
14
|
+
{{/each}}
|
|
15
|
+
{{#if delegationFirst}}
|
|
16
|
+
|
|
17
|
+
## Agent Delegation
|
|
18
|
+
|
|
19
|
+
When working on this project, prefer delegating complex tasks to specialized agents.
|
|
20
|
+
{{/if}}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# {{projectName}}
|
|
2
|
+
|
|
3
|
+
## Project Info
|
|
4
|
+
|
|
5
|
+
- **Language**: {{language}}
|
|
6
|
+
|
|
7
|
+
## Coding Guidelines
|
|
8
|
+
|
|
9
|
+
- Follow established project conventions and style guides.
|
|
10
|
+
- Write clear, self-documenting code with minimal comments.
|
|
11
|
+
- Prefer editing existing files over creating new ones.
|
|
12
|
+
- Run tests after making changes to verify correctness.
|
|
13
|
+
- Run linters/formatters before finalizing changes.
|
|
14
|
+
{{#each customRules}}
|
|
15
|
+
- {{.}}
|
|
16
|
+
{{/each}}
|
|
17
|
+
|
|
18
|
+
## Agent Delegation
|
|
19
|
+
|
|
20
|
+
Prefer delegating substantive work to specialized agents:
|
|
21
|
+
|
|
22
|
+
| Task Type | Recommended Agent | Tier |
|
|
23
|
+
|-----------|-------------------|------|
|
|
24
|
+
| Quick lookup | explore | low |
|
|
25
|
+
| Feature implementation | executor | medium |
|
|
26
|
+
| Complex debugging | architect | high |
|
|
27
|
+
| UI/frontend work | designer | medium |
|
|
28
|
+
| Documentation | writer | low |
|
|
29
|
+
| Code review | code-reviewer | high |
|
|
30
|
+
|
|
31
|
+
## Verification Protocol
|
|
32
|
+
|
|
33
|
+
Before claiming any task is complete:
|
|
34
|
+
|
|
35
|
+
1. Run the build to check for compilation errors.
|
|
36
|
+
2. Run relevant tests to verify correctness.
|
|
37
|
+
3. Run linter to check for style issues.
|
|
38
|
+
|
|
39
|
+
## Skills
|
|
40
|
+
|
|
41
|
+
Skills are discovered from these directories:
|
|
42
|
+
|
|
43
|
+
- `.harness/skills/`
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
project:
|
|
2
|
+
name: "{{projectName}}"
|
|
3
|
+
language: "{{language}}"
|
|
4
|
+
description: ""
|
|
5
|
+
|
|
6
|
+
agents:
|
|
7
|
+
delegation_first: true
|
|
8
|
+
model_routing:
|
|
9
|
+
low: "low"
|
|
10
|
+
medium: "medium"
|
|
11
|
+
high: "high"
|
|
12
|
+
providers: {}
|
|
13
|
+
|
|
14
|
+
skills:
|
|
15
|
+
directories:
|
|
16
|
+
- ".harness/skills"
|
|
17
|
+
auto_detect: true
|
|
18
|
+
|
|
19
|
+
workflows:
|
|
20
|
+
verification:
|
|
21
|
+
checks:
|
|
22
|
+
- build
|
|
23
|
+
- test
|
|
24
|
+
- lint
|
|
25
|
+
|
|
26
|
+
templates:
|
|
27
|
+
agents_md:
|
|
28
|
+
variant: "{{variant}}"
|