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.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +236 -0
  3. package/README.zh-CN.md +236 -0
  4. package/dist/chunk-3P72TGGQ.js +82 -0
  5. package/dist/chunk-3P72TGGQ.js.map +1 -0
  6. package/dist/chunk-JKJ3FP6T.js +51 -0
  7. package/dist/chunk-JKJ3FP6T.js.map +1 -0
  8. package/dist/chunk-LOE6IDTT.js +65 -0
  9. package/dist/chunk-LOE6IDTT.js.map +1 -0
  10. package/dist/chunk-PQWK2OBN.js +18 -0
  11. package/dist/chunk-PQWK2OBN.js.map +1 -0
  12. package/dist/chunk-R6VGYQOH.js +771 -0
  13. package/dist/chunk-R6VGYQOH.js.map +1 -0
  14. package/dist/config-PUMLWJWT.js +46 -0
  15. package/dist/config-PUMLWJWT.js.map +1 -0
  16. package/dist/context-SRWWNVTI.js +33 -0
  17. package/dist/context-SRWWNVTI.js.map +1 -0
  18. package/dist/doctor-TYLZH27K.js +199 -0
  19. package/dist/doctor-TYLZH27K.js.map +1 -0
  20. package/dist/harness.js +62 -0
  21. package/dist/harness.js.map +1 -0
  22. package/dist/index.d.ts +846 -0
  23. package/dist/index.js +1181 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/list-ABNY2TO7.js +124 -0
  26. package/dist/list-ABNY2TO7.js.map +1 -0
  27. package/dist/loader-RDQZFHOB.js +19 -0
  28. package/dist/loader-RDQZFHOB.js.map +1 -0
  29. package/dist/run-I5GVJH3N.js +45 -0
  30. package/dist/run-I5GVJH3N.js.map +1 -0
  31. package/dist/scaffold-C6JA3STC.js +98 -0
  32. package/dist/scaffold-C6JA3STC.js.map +1 -0
  33. package/dist/schema-AHX7LXUQ.js +27 -0
  34. package/dist/schema-AHX7LXUQ.js.map +1 -0
  35. package/dist/setup-CWDCKM34.js +115 -0
  36. package/dist/setup-CWDCKM34.js.map +1 -0
  37. package/dist/update-CTPDQCLU.js +87 -0
  38. package/dist/update-CTPDQCLU.js.map +1 -0
  39. package/dist/verify-NI3VCE2H.js +136 -0
  40. package/dist/verify-NI3VCE2H.js.map +1 -0
  41. package/package.json +61 -0
  42. package/templates/agents-md/full.md.tmpl +98 -0
  43. package/templates/agents-md/minimal.md.tmpl +20 -0
  44. package/templates/agents-md/standard.md.tmpl +43 -0
  45. package/templates/configs/harness.config.yaml.tmpl +28 -0
  46. 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}}"
@@ -0,0 +1,14 @@
1
+ ---
2
+ name: {{name}}
3
+ description: {{description}}
4
+ ---
5
+
6
+ # {{displayName}}
7
+
8
+ ## Overview
9
+
10
+ TODO: Describe what this skill does.
11
+
12
+ ## Usage
13
+
14
+ TODO: Describe how to use this skill.