agent-harness-kit 0.3.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.
Files changed (55) hide show
  1. package/.claude-plugin/marketplace.json +27 -0
  2. package/.claude-plugin/plugin.json +25 -0
  3. package/LICENSE +21 -0
  4. package/README.md +165 -0
  5. package/bin/cli.mjs +261 -0
  6. package/package.json +64 -0
  7. package/src/core/detect-stack.mjs +181 -0
  8. package/src/core/doctor.mjs +106 -0
  9. package/src/core/patch-package-json.mjs +53 -0
  10. package/src/core/render-templates.mjs +277 -0
  11. package/src/core/upgrade.mjs +274 -0
  12. package/src/templates/.claude/agents/api-consistency-reviewer.md +33 -0
  13. package/src/templates/.claude/agents/architecture-reviewer.md.hbs +41 -0
  14. package/src/templates/.claude/agents/performance-reviewer.md +35 -0
  15. package/src/templates/.claude/agents/reliability-reviewer.md +38 -0
  16. package/src/templates/.claude/agents/security-reviewer.md +39 -0
  17. package/src/templates/.claude/hooks/hooks.json.hbs +39 -0
  18. package/src/templates/.claude/settings.json.hbs +25 -0
  19. package/src/templates/.claude/skills/add-adr/SKILL.md +60 -0
  20. package/src/templates/.claude/skills/add-feature/SKILL.md.hbs +50 -0
  21. package/src/templates/.claude/skills/debug-flow/SKILL.md.hbs +38 -0
  22. package/src/templates/.claude/skills/doc-drift-scan/SKILL.md +43 -0
  23. package/src/templates/.claude/skills/eval-runner/SKILL.md +55 -0
  24. package/src/templates/.claude/skills/garbage-collection/SKILL.md.hbs +49 -0
  25. package/src/templates/.claude/skills/inspect-app/SKILL.md +57 -0
  26. package/src/templates/.claude/skills/inspect-module/SKILL.md.hbs +53 -0
  27. package/src/templates/.claude/skills/propose-harness-improvement/SKILL.md +43 -0
  28. package/src/templates/.claude/skills/structural-test-author/SKILL.md.hbs +46 -0
  29. package/src/templates/.claude/skills/write-skill/SKILL.md +39 -0
  30. package/src/templates/CLAUDE.md.hbs +70 -0
  31. package/src/templates/_adapter-python/.importlinter +14 -0
  32. package/src/templates/_adapter-python/harness/__init__.py +0 -0
  33. package/src/templates/_adapter-python/harness/eval_runner.py +281 -0
  34. package/src/templates/_adapter-python/harness/structural_test.py +195 -0
  35. package/src/templates/_adapter-typescript/.dependency-cruiser.cjs +27 -0
  36. package/src/templates/_adapter-typescript/eslint.config.mjs +38 -0
  37. package/src/templates/_adapter-typescript/harness/eval-runner.mjs +322 -0
  38. package/src/templates/_adapter-typescript/harness/structural-test.mjs +125 -0
  39. package/src/templates/_ci/.github/workflows/eval-nightly.yml +59 -0
  40. package/src/templates/_ci/.github/workflows/harness.yml +55 -0
  41. package/src/templates/docs/adr/0001-use-agent-harness-kit.md.hbs +56 -0
  42. package/src/templates/docs/agent-failures.md +25 -0
  43. package/src/templates/docs/architecture.md.hbs +47 -0
  44. package/src/templates/docs/core-beliefs.md.hbs +41 -0
  45. package/src/templates/docs/golden-principles.md.hbs +80 -0
  46. package/src/templates/docs/tech-debt-tracker.md +30 -0
  47. package/src/templates/feature_list.json.hbs +29 -0
  48. package/src/templates/harness.config.json.hbs +40 -0
  49. package/src/templates/scripts/dev-up.sh.hbs +51 -0
  50. package/src/templates/scripts/harness-report.mjs +189 -0
  51. package/src/templates/scripts/install-git-hooks.sh +18 -0
  52. package/src/templates/scripts/pre-push.sh +21 -0
  53. package/src/templates/scripts/precompletion-checklist.sh.hbs +99 -0
  54. package/src/templates/scripts/structural-test-on-edit.sh.hbs +53 -0
  55. package/src/templates/scripts/telemetry-on-skill.sh +26 -0
@@ -0,0 +1,27 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/claude-code-marketplace.json",
3
+ "name": "agent-harness-kit-marketplace",
4
+ "owner": {
5
+ "name": "Tuan Le"
6
+ },
7
+ "description": "Solo-dev harness engineering kit for Claude Code.",
8
+ "plugins": [
9
+ {
10
+ "name": "agent-harness-kit",
11
+ "source": {
12
+ "source": "github",
13
+ "repo": "tuanle96/agent-harness-kit",
14
+ "ref": "v0.3.0"
15
+ },
16
+ "version": "0.3.0",
17
+ "description": "Solo-dev harness engineering kit — layered architecture, GC ritual, structural tests, review subagents.",
18
+ "category": "development",
19
+ "keywords": [
20
+ "harness",
21
+ "architecture",
22
+ "review",
23
+ "solo-dev"
24
+ ]
25
+ }
26
+ ]
27
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "agent-harness-kit",
3
+ "version": "0.3.0",
4
+ "description": "Solo-dev harness engineering kit — layered architecture, garbage-collection ritual, structural tests, review subagents. Optimized for Claude Code 2.1+.",
5
+ "author": {
6
+ "name": "Tuan Le"
7
+ },
8
+ "homepage": "https://github.com/tuanle96/agent-harness-kit",
9
+ "repository": "https://github.com/tuanle96/agent-harness-kit",
10
+ "license": "MIT",
11
+ "keywords": [
12
+ "harness-engineering",
13
+ "claude-code",
14
+ "structural-tests",
15
+ "layered-architecture",
16
+ "solo-dev",
17
+ "code-review",
18
+ "agents",
19
+ "skills"
20
+ ],
21
+ "skills": "./src/templates/.claude/skills/",
22
+ "agents": "./src/templates/.claude/agents/",
23
+ "hooks": "./src/templates/.claude/hooks/hooks.json",
24
+ "commands": "./src/templates/.claude/skills/"
25
+ }
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Tuan Le
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,165 @@
1
+ # agent-harness-kit
2
+
3
+ Solo-dev harness engineering kit for Claude Code. One command, ~30 minutes,
4
+ and your hobby project gets the patterns OpenAI used to ship 1M lines of
5
+ agent-generated code: layered architecture, structural tests, garbage
6
+ collection, review subagents, JSON feature tracking, and pre-completion
7
+ checklists — without the Stripe/OpenAI overhead.
8
+
9
+ ## Why
10
+
11
+ - Claude Code 2.1+ merged slash commands and Skills into one format.
12
+ - Plugins are now a stable distribution channel.
13
+ - LangChain proved harness changes alone can take a coding agent from Top 30
14
+ to Top 5 on Terminal-Bench 2.0.
15
+ - Mitchell Hashimoto's "engineer the harness" + Anthropic's two-fold
16
+ initializer/coding-agent pattern + OpenAI's golden-principles GC ritual
17
+ scale down nicely to one developer.
18
+
19
+ ## Install
20
+
21
+ Option A: scaffold into an existing repo
22
+
23
+ ```bash
24
+ npx agent-harness-kit init
25
+ ```
26
+
27
+ Option B: install as a Claude Code plugin
28
+
29
+ ```text
30
+ /plugin marketplace add tuanle96/agent-harness-kit
31
+ /plugin install agent-harness-kit@agent-harness-kit-marketplace
32
+ ```
33
+
34
+ ## What ships
35
+
36
+ - 10 skills (`inspect-module`, `add-feature`, `garbage-collection`,
37
+ `propose-harness-improvement`, `write-skill`, `debug-flow`, `eval-runner`,
38
+ `add-adr`, `doc-drift-scan`, `structural-test-author`)
39
+ - 5 read-only review subagents (`architecture-reviewer`, `security-reviewer`,
40
+ `reliability-reviewer`, `performance-reviewer`, `api-consistency-reviewer`)
41
+ - 1 PostToolUse hook (structural-test on every edit) + 1 Stop hook
42
+ (pre-completion checklist with `stop_hook_active` loop guard)
43
+ - TypeScript adapter (ts-morph + eslint-plugin-boundaries +
44
+ dependency-cruiser)
45
+ - Python adapter (libcst + import-linter)
46
+ - Eval harness (outcome / process / style / efficiency dimensions)
47
+
48
+ ## Slash commands generated
49
+
50
+ | Command | Purpose |
51
+ | -------------------------------- | -------------------------------------------------------- |
52
+ | `/inspect-module <path>` | Map a module before editing |
53
+ | `/add-feature <description>` | Implement one item from `feature_list.json` |
54
+ | `/garbage-collection` | Friday cleanup (top-3 fixes only at solo scale) |
55
+ | `/structural-test-author` | Codify a new architectural rule mechanically |
56
+ | `/propose-harness-improvement` | Convert an agent failure into a permanent prevention |
57
+ | `/eval-runner` | Regression-test the harness itself |
58
+ | `/write-skill` | Create a new SKILL.md with valid frontmatter |
59
+ | `/add-adr` | Add a numbered Architecture Decision Record |
60
+ | `/doc-drift-scan` | Find stale path/command references in `docs/` |
61
+ | `/debug-flow` | Run the failing flow before fixing it |
62
+
63
+ ## Philosophy (4 axioms)
64
+
65
+ 1. **CLAUDE.md is a table of contents, not an encyclopedia** (HumanLayer
66
+ measured ~150–200 instructions as the reliable cap; OpenAI's own root file
67
+ is ~100 lines). The kit's CLAUDE.md is 50–80 lines.
68
+ 2. **Every agent failure becomes a permanent harness change** (Hashimoto's
69
+ discipline). The `/propose-harness-improvement` skill enforces this.
70
+ 3. **Computational sensors before LLM sensors** (Fowler/Böckeler). The TS and
71
+ Python adapters ship one deterministic structural test per language; LLM
72
+ subagents are reserved for semantic judgment.
73
+ 4. **Garbage collection over Friday cleanup, scaled to solo** (OpenAI's
74
+ ritual, shrunk to top-3 fixes per week).
75
+
76
+ ## Directory the kit drops into your repo
77
+
78
+ ```text
79
+ your-repo/
80
+ ├── CLAUDE.md # 50–80 line table of contents
81
+ ├── AGENTS.md # symlink → CLAUDE.md
82
+ ├── docs/
83
+ │ ├── architecture.md
84
+ │ ├── core-beliefs.md
85
+ │ ├── golden-principles.md
86
+ │ ├── tech-debt-tracker.md
87
+ │ └── adr/
88
+ │ └── 0001-use-agent-harness-kit.md
89
+ ├── feature_list.json # JSON, not Markdown — Anthropic pattern
90
+ ├── harness.config.json
91
+ ├── .claude/
92
+ │ ├── settings.json
93
+ │ ├── skills/ # 10 skills as SKILL.md files
94
+ │ ├── agents/ # 5 reviewer personas
95
+ │ └── hooks/hooks.json
96
+ ├── .harness/
97
+ │ ├── installed.json # kit lockfile (sha-tracked)
98
+ │ ├── PROGRESS.md # session log
99
+ │ └── structural-baseline.json # existing-violation baseline
100
+ └── scripts/
101
+ ├── structural-test-on-edit.sh # PostToolUse hook target
102
+ ├── precompletion-checklist.sh # Stop hook target
103
+ ├── dev-up.sh
104
+ ├── pre-push.sh
105
+ └── install-git-hooks.sh
106
+ ```
107
+
108
+ ## Configuration (`harness.config.json`)
109
+
110
+ ```json
111
+ {
112
+ "version": "0.1.0",
113
+ "language": "typescript",
114
+ "framework": "nextjs",
115
+ "preset": "nextjs",
116
+ "domains": [
117
+ {
118
+ "name": "default",
119
+ "root": "src",
120
+ "layers": ["types", "config", "repo", "service", "runtime", "ui"]
121
+ }
122
+ ],
123
+ "providers": ["auth", "telemetry", "feature-flags"],
124
+ "models": {
125
+ "main": "claude-sonnet-4-6",
126
+ "reviewers": "claude-sonnet-4-6",
127
+ "explore": "claude-haiku-4-5"
128
+ },
129
+ "budgets": { "perRunUsd": 2.0, "perDayUsd": 10.0 }
130
+ }
131
+ ```
132
+
133
+ ## CLI commands
134
+
135
+ ```text
136
+ agent-harness-kit init # scaffold a repo (interactive)
137
+ agent-harness-kit init --yes # accept all detected defaults
138
+ agent-harness-kit upgrade # non-destructive upgrade, preserves user edits
139
+ agent-harness-kit doctor # diagnose installed kit + Claude Code env
140
+ agent-harness-kit --version
141
+ ```
142
+
143
+ ## Token / cost expectations
144
+
145
+ A typical day with the default model split (Sonnet 4.6 main + Haiku 4.5
146
+ explore + Sonnet 4.6 reviewers) stays under ~$2 of API traffic for a single
147
+ developer. The `eval-runner` skill enforces a per-run budget set in
148
+ `harness.config.json`.
149
+
150
+ ## Support matrix
151
+
152
+ | Stack | Adapter | Preset | Dev command | Status |
153
+ | ------------------------------ | ------------ | ----------- | -------------------------------------- | ------ |
154
+ | Next.js 14 + TypeScript | typescript | `nextjs` | `npm run dev` | v0.1 |
155
+ | Express | typescript | `node-api` | `node ./src/server.js` | v0.1 |
156
+ | Fastify | typescript | `node-api` | `node ./src/server.js` | v0.1 |
157
+ | NestJS | typescript | `node-api` | `npm run start:dev` | v0.1 |
158
+ | FastAPI | python | `fastapi` | `uvicorn app.main:app --reload` | v0.1 |
159
+ | Django | python | `django` | `python manage.py runserver` | v0.1 |
160
+ | Flask | python | `flask` | `flask --app app run --debug` | v0.1 |
161
+ | Go / Rust | core only | none | (manual) | v0.4 |
162
+
163
+ ## License
164
+
165
+ MIT.
package/bin/cli.mjs ADDED
@@ -0,0 +1,261 @@
1
+ #!/usr/bin/env node
2
+ // agent-harness-kit CLI — solo-dev harness scaffolder for Claude Code.
3
+ // Implements: init, upgrade, doctor.
4
+
5
+ import { Command } from "commander";
6
+ import { input, select, confirm } from "@inquirer/prompts";
7
+ import pc from "picocolors";
8
+ import { fileURLToPath } from "node:url";
9
+ import { dirname, resolve } from "node:path";
10
+ import { readFile } from "node:fs/promises";
11
+
12
+ import { detectStack } from "../src/core/detect-stack.mjs";
13
+ import { renderAll } from "../src/core/render-templates.mjs";
14
+ import { upgrade } from "../src/core/upgrade.mjs";
15
+ import { doctor } from "../src/core/doctor.mjs";
16
+
17
+ const __dirname = dirname(fileURLToPath(import.meta.url));
18
+ const pkgJsonPath = resolve(__dirname, "..", "package.json");
19
+ const pkg = JSON.parse(await readFile(pkgJsonPath, "utf8"));
20
+
21
+ const program = new Command();
22
+ program
23
+ .name("agent-harness-kit")
24
+ .description(
25
+ "Solo-dev harness engineering kit for Claude Code (skills + subagents + hooks + structural tests).",
26
+ )
27
+ .version(pkg.version);
28
+
29
+ program
30
+ .command("init")
31
+ .description("Scaffold the harness into the current repository")
32
+ .option("-y, --yes", "accept all detected defaults", false)
33
+ .option("--cwd <path>", "target directory (defaults to process.cwd())")
34
+ .option("--no-hooks", "skip hook installation")
35
+ .option("--no-ci", "skip GitHub Actions workflow")
36
+ .option(
37
+ "--allow-polyglot-root",
38
+ "force init at the root of a polyglot monorepo (not recommended — kit enforces one layered architecture per init)",
39
+ false,
40
+ )
41
+ .option(
42
+ "--allow-unsupported",
43
+ "force init for languages without a structural-test adapter yet (go, rust, swift, kotlin)",
44
+ false,
45
+ )
46
+ .action(async (opts) => {
47
+ const cwd = opts.cwd ? resolve(opts.cwd) : process.cwd();
48
+ console.log(pc.bold(pc.cyan(`\nagent-harness-kit v${pkg.version}\n`)));
49
+ console.log(`Target: ${pc.dim(cwd)}\n`);
50
+
51
+ const stack = await detectStack(cwd);
52
+ console.log(
53
+ `Detected: ${pc.green(stack.language)} / ${pc.green(stack.framework ?? "generic")} ` +
54
+ `(package manager: ${pc.green(stack.packageManager)}` +
55
+ (stack.monorepo ? `, ${pc.yellow("monorepo")}` : "") +
56
+ ")\n",
57
+ );
58
+
59
+ if (stack.polyglotSignals.length >= 2 && stack.appCandidates.length > 0) {
60
+ console.log(pc.yellow("⚠ Polyglot monorepo detected."));
61
+ console.log(
62
+ ` Languages found in subdirectories: ${pc.yellow(stack.polyglotSignals.join(", "))}.`,
63
+ );
64
+ console.log(
65
+ ` The kit's structural test enforces ${pc.yellow("one")} layered architecture per repo.`,
66
+ );
67
+ console.log(
68
+ ` ${pc.bold("Recommended:")} run \`agent-harness-kit init\` once per app instead of at the root:`,
69
+ );
70
+ for (const app of stack.appCandidates.slice(0, 5)) {
71
+ console.log(` ${pc.dim("→")} cd ${app.path} && agent-harness-kit init ${pc.dim("# " + app.languages.join("+"))}`);
72
+ }
73
+ if (stack.appCandidates.length > 5) {
74
+ console.log(pc.dim(` ...and ${stack.appCandidates.length - 5} more.`));
75
+ }
76
+ console.log("");
77
+
78
+ if (!opts.allowPolyglotRoot) {
79
+ if (opts.yes) {
80
+ console.error(
81
+ pc.red(
82
+ `Aborting: refusing to init at the root of a polyglot monorepo in --yes mode.`,
83
+ ),
84
+ );
85
+ console.error(
86
+ pc.dim(
87
+ ` Run init in each app directory above, or pass --allow-polyglot-root to override.`,
88
+ ),
89
+ );
90
+ process.exit(1);
91
+ }
92
+ const ok = await confirm({
93
+ message: "Continue init at root anyway?",
94
+ default: false,
95
+ });
96
+ if (!ok) {
97
+ console.log(pc.yellow("Aborted. Run init inside one of the listed app directories."));
98
+ process.exit(0);
99
+ }
100
+ }
101
+ }
102
+
103
+ // Unsupported-language guard. Kit ships TS + Python adapters today;
104
+ // initing at the root of a Go/Rust/Swift/Kotlin project produces a
105
+ // half-broken harness (structural test missing, ts-morph engine pinned).
106
+ // Skills + reviewers still work, but the user should opt in explicitly.
107
+ const UNSUPPORTED = new Set(["go", "rust", "swift", "kotlin"]);
108
+ if (UNSUPPORTED.has(stack.language) && !opts.allowUnsupported) {
109
+ console.log(
110
+ pc.yellow(
111
+ `⚠ No structural-test adapter for ${pc.bold(stack.language)} yet (deferred to v0.4).`,
112
+ ),
113
+ );
114
+ console.log(
115
+ pc.dim(
116
+ ` You'll get skills + reviewers + hooks, but \`harness:check\` will be a no-op.`,
117
+ ),
118
+ );
119
+ if (opts.yes) {
120
+ console.error(
121
+ pc.red(`Aborting: pass --allow-unsupported to init anyway, or wait for v0.4.`),
122
+ );
123
+ process.exit(1);
124
+ }
125
+ const ok = await confirm({
126
+ message: `Continue with the generic harness (skills + reviewers only)?`,
127
+ default: false,
128
+ });
129
+ if (!ok) {
130
+ console.log(pc.yellow("Aborted."));
131
+ process.exit(0);
132
+ }
133
+ }
134
+
135
+ let projectName = stack.suggestedName;
136
+ let preset = stack.suggestedPreset;
137
+ let layers = ["types", "config", "repo", "service", "runtime", "ui"];
138
+ let installHooks = opts.hooks !== false;
139
+ let installCi = opts.ci !== false;
140
+
141
+ if (!opts.yes) {
142
+ projectName = await input({
143
+ message: "Project name",
144
+ default: stack.suggestedName,
145
+ });
146
+
147
+ const presetChoices = stack.availablePresets.map((p) => ({
148
+ name: p,
149
+ value: p,
150
+ }));
151
+ presetChoices.push({ name: "(none — generic)", value: "generic" });
152
+ preset = await select({
153
+ message: "Preset",
154
+ default: stack.suggestedPreset,
155
+ choices: presetChoices,
156
+ });
157
+
158
+ const layersOk = await confirm({
159
+ message: `Use default layer order [${layers.join(" → ")}]?`,
160
+ default: true,
161
+ });
162
+ if (!layersOk) {
163
+ const custom = await input({
164
+ message: "Custom layer order (comma separated, low → high)",
165
+ default: layers.join(","),
166
+ });
167
+ layers = custom.split(",").map((s) => s.trim()).filter(Boolean);
168
+ }
169
+
170
+ installHooks = await confirm({
171
+ message: "Install Claude Code hooks (PostToolUse + Stop)?",
172
+ default: true,
173
+ });
174
+
175
+ installCi = await confirm({
176
+ message: "Set up GitHub Actions nightly eval workflow?",
177
+ default: false,
178
+ });
179
+ }
180
+
181
+ const result = await renderAll({
182
+ cwd,
183
+ projectName,
184
+ preset,
185
+ layers,
186
+ stack,
187
+ installHooks,
188
+ installCi,
189
+ kitVersion: pkg.version,
190
+ });
191
+
192
+ console.log("");
193
+ for (const f of result.written) {
194
+ console.log(` ${pc.green("✓")} ${pc.dim("wrote")} ${f}`);
195
+ }
196
+ if (result.skipped.length > 0) {
197
+ console.log("");
198
+ for (const f of result.skipped) {
199
+ console.log(` ${pc.yellow("~")} ${pc.dim("skipped (existed)")} ${f}`);
200
+ }
201
+ }
202
+
203
+ console.log(pc.bold("\nNext steps:"));
204
+ const nextSteps = renderNextSteps(stack);
205
+ nextSteps.forEach((s, i) => console.log(` ${i + 1}. ${s}`));
206
+ console.log("");
207
+ });
208
+
209
+ program
210
+ .command("upgrade")
211
+ .description("Upgrade installed kit version, preserving user edits")
212
+ .option("--cwd <path>", "target directory (defaults to process.cwd())")
213
+ .option("-y, --yes", "apply without confirmation prompts", false)
214
+ .action(async (opts) => {
215
+ const cwd = opts.cwd ? resolve(opts.cwd) : process.cwd();
216
+ await upgrade({ cwd, kitVersion: pkg.version, yes: opts.yes });
217
+ });
218
+
219
+ program
220
+ .command("doctor")
221
+ .description("Diagnose installed kit + Claude Code environment")
222
+ .option("--cwd <path>", "target directory (defaults to process.cwd())")
223
+ .action(async (opts) => {
224
+ const cwd = opts.cwd ? resolve(opts.cwd) : process.cwd();
225
+ await doctor({ cwd, kitVersion: pkg.version });
226
+ });
227
+
228
+ function renderNextSteps(stack) {
229
+ const out = [];
230
+ if (stack.language === "typescript") {
231
+ out.push(`Run ${pc.cyan("npm install")} to install dev dependencies.`);
232
+ } else if (stack.language === "python") {
233
+ out.push(
234
+ `Run ${pc.cyan("pip install -e '.[dev]'")} (or your tool of choice) to pull dev deps.`,
235
+ );
236
+ } else {
237
+ out.push(
238
+ `Install your language's deps manually — kit shipped without an adapter for ${pc.yellow(stack.language)}.`,
239
+ );
240
+ }
241
+ out.push(
242
+ `Run ${pc.cyan("bash scripts/install-git-hooks.sh")} to enable pre-push checks.`,
243
+ );
244
+ out.push(
245
+ `Open Claude Code in this repo and run ${pc.cyan("/inspect-module .")} to bootstrap context.`,
246
+ );
247
+ out.push(
248
+ `Try ${pc.cyan("/add-feature \"a small first feature\"")} to see the workflow end-to-end.`,
249
+ );
250
+ return out;
251
+ }
252
+
253
+ program.parseAsync(process.argv).catch((err) => {
254
+ if (err && err.name === "ExitPromptError") {
255
+ console.error(pc.yellow("\naborted by user."));
256
+ process.exit(130);
257
+ }
258
+ console.error(pc.red("\nagent-harness-kit failed:"));
259
+ console.error(err && err.stack ? err.stack : err);
260
+ process.exit(1);
261
+ });
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "agent-harness-kit",
3
+ "version": "0.3.0",
4
+ "description": "Solo-dev harness engineering kit for Claude Code. Layered architecture, structural tests, garbage-collection ritual, review subagents — without the enterprise overhead.",
5
+ "type": "module",
6
+ "bin": {
7
+ "agent-harness-kit": "./bin/cli.mjs"
8
+ },
9
+ "files": [
10
+ "bin",
11
+ "src",
12
+ "schema.json",
13
+ ".claude-plugin",
14
+ "README.md",
15
+ "LICENSE"
16
+ ],
17
+ "engines": {
18
+ "node": ">=20"
19
+ },
20
+ "keywords": [
21
+ "claude-code",
22
+ "harness-engineering",
23
+ "layered-architecture",
24
+ "structural-tests",
25
+ "solo-dev",
26
+ "code-review",
27
+ "agents",
28
+ "skills"
29
+ ],
30
+ "author": "Tuan Le",
31
+ "license": "MIT",
32
+ "homepage": "https://github.com/tuanle96/agent-harness-kit",
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/tuanle96/agent-harness-kit.git"
36
+ },
37
+ "bugs": {
38
+ "url": "https://github.com/tuanle96/agent-harness-kit/issues"
39
+ },
40
+ "scripts": {
41
+ "test": "node --test tests/*.test.mjs",
42
+ "lint": "echo 'no-op (kit is plain ESM JS)'",
43
+ "selftest": "node bin/cli.mjs --version"
44
+ },
45
+ "dependencies": {
46
+ "@inquirer/prompts": "^7.0.0",
47
+ "commander": "^12.1.0",
48
+ "handlebars": "^4.7.8",
49
+ "picocolors": "^1.1.1"
50
+ },
51
+ "peerDependencies": {
52
+ "ts-morph": ">=24",
53
+ "eslint-plugin-boundaries": ">=5",
54
+ "dependency-cruiser": ">=16"
55
+ },
56
+ "peerDependenciesMeta": {
57
+ "ts-morph": { "optional": true },
58
+ "eslint-plugin-boundaries": { "optional": true },
59
+ "dependency-cruiser": { "optional": true }
60
+ },
61
+ "publishConfig": {
62
+ "access": "public"
63
+ }
64
+ }