autonomous-coding-toolkit 1.0.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 (324) hide show
  1. package/.claude-plugin/marketplace.json +22 -0
  2. package/.claude-plugin/plugin.json +13 -0
  3. package/LICENSE +21 -0
  4. package/Makefile +21 -0
  5. package/README.md +140 -0
  6. package/SECURITY.md +28 -0
  7. package/agents/bash-expert.md +113 -0
  8. package/agents/dependency-auditor.md +138 -0
  9. package/agents/integration-tester.md +120 -0
  10. package/agents/lesson-scanner.md +149 -0
  11. package/agents/python-expert.md +179 -0
  12. package/agents/service-monitor.md +141 -0
  13. package/agents/shell-expert.md +147 -0
  14. package/benchmarks/runner.sh +147 -0
  15. package/benchmarks/tasks/01-rest-endpoint/rubric.sh +29 -0
  16. package/benchmarks/tasks/01-rest-endpoint/task.md +17 -0
  17. package/benchmarks/tasks/02-refactor-module/task.md +8 -0
  18. package/benchmarks/tasks/03-fix-integration-bug/task.md +8 -0
  19. package/benchmarks/tasks/04-add-test-coverage/task.md +8 -0
  20. package/benchmarks/tasks/05-multi-file-feature/task.md +8 -0
  21. package/bin/act.js +238 -0
  22. package/commands/autocode.md +6 -0
  23. package/commands/cancel-ralph.md +18 -0
  24. package/commands/code-factory.md +53 -0
  25. package/commands/create-prd.md +55 -0
  26. package/commands/ralph-loop.md +18 -0
  27. package/commands/run-plan.md +117 -0
  28. package/commands/submit-lesson.md +122 -0
  29. package/docs/ARCHITECTURE.md +630 -0
  30. package/docs/CONTRIBUTING.md +125 -0
  31. package/docs/lessons/0001-bare-exception-swallowing.md +34 -0
  32. package/docs/lessons/0002-async-def-without-await.md +28 -0
  33. package/docs/lessons/0003-create-task-without-callback.md +28 -0
  34. package/docs/lessons/0004-hardcoded-test-counts.md +28 -0
  35. package/docs/lessons/0005-sqlite-without-closing.md +33 -0
  36. package/docs/lessons/0006-venv-pip-path.md +27 -0
  37. package/docs/lessons/0007-runner-state-self-rejection.md +35 -0
  38. package/docs/lessons/0008-quality-gate-blind-spot.md +33 -0
  39. package/docs/lessons/0009-parser-overcount-empty-batches.md +36 -0
  40. package/docs/lessons/0010-local-outside-function-bash.md +33 -0
  41. package/docs/lessons/0011-batch-tests-for-unimplemented-code.md +36 -0
  42. package/docs/lessons/0012-api-markdown-unescaped-chars.md +33 -0
  43. package/docs/lessons/0013-export-prefix-env-parsing.md +33 -0
  44. package/docs/lessons/0014-decorator-registry-import-side-effect.md +43 -0
  45. package/docs/lessons/0015-frontend-backend-schema-drift.md +43 -0
  46. package/docs/lessons/0016-event-driven-cold-start-seeding.md +44 -0
  47. package/docs/lessons/0017-copy-paste-logic-diverges.md +43 -0
  48. package/docs/lessons/0018-layer-passes-pipeline-broken.md +45 -0
  49. package/docs/lessons/0019-systemd-envfile-ignores-export.md +41 -0
  50. package/docs/lessons/0020-persist-state-incrementally.md +44 -0
  51. package/docs/lessons/0021-dual-axis-testing.md +48 -0
  52. package/docs/lessons/0022-jsx-factory-shadowing.md +43 -0
  53. package/docs/lessons/0023-static-analysis-spiral.md +51 -0
  54. package/docs/lessons/0024-shared-pipeline-implementation.md +55 -0
  55. package/docs/lessons/0025-defense-in-depth-all-entry-points.md +65 -0
  56. package/docs/lessons/0026-linter-no-rules-false-enforcement.md +54 -0
  57. package/docs/lessons/0027-jsx-silent-prop-drop.md +64 -0
  58. package/docs/lessons/0028-no-infrastructure-in-client-code.md +49 -0
  59. package/docs/lessons/0029-never-write-secrets-to-files.md +61 -0
  60. package/docs/lessons/0030-cache-merge-not-replace.md +62 -0
  61. package/docs/lessons/0031-verify-units-at-boundaries.md +66 -0
  62. package/docs/lessons/0032-module-lifecycle-subscribe-unsubscribe.md +89 -0
  63. package/docs/lessons/0033-async-iteration-mutable-snapshot.md +72 -0
  64. package/docs/lessons/0034-caller-missing-await-silent-discard.md +65 -0
  65. package/docs/lessons/0035-duplicate-registration-silent-overwrite.md +85 -0
  66. package/docs/lessons/0036-websocket-dirty-disconnect.md +33 -0
  67. package/docs/lessons/0037-parallel-agents-worktree-corruption.md +31 -0
  68. package/docs/lessons/0038-subscribe-no-stored-ref.md +36 -0
  69. package/docs/lessons/0039-fallback-or-default-hides-bugs.md +34 -0
  70. package/docs/lessons/0040-event-firehose-filter-first.md +36 -0
  71. package/docs/lessons/0041-ambiguous-base-dir-path-nesting.md +32 -0
  72. package/docs/lessons/0042-spec-compliance-insufficient.md +36 -0
  73. package/docs/lessons/0043-exact-count-extensible-collections.md +32 -0
  74. package/docs/lessons/0044-relative-file-deps-worktree.md +39 -0
  75. package/docs/lessons/0045-iterative-design-improvement.md +33 -0
  76. package/docs/lessons/0046-plan-assertion-math-bugs.md +38 -0
  77. package/docs/lessons/0047-pytest-single-threaded-default.md +37 -0
  78. package/docs/lessons/0048-integration-wiring-batch.md +40 -0
  79. package/docs/lessons/0049-ab-verification.md +41 -0
  80. package/docs/lessons/0050-editing-sourced-files-during-execution.md +33 -0
  81. package/docs/lessons/0051-infrastructure-fixes-cant-self-heal.md +30 -0
  82. package/docs/lessons/0052-uncommitted-changes-poison-quality-gates.md +31 -0
  83. package/docs/lessons/0053-jq-compact-flag-inconsistency.md +31 -0
  84. package/docs/lessons/0054-parser-matches-inside-code-blocks.md +30 -0
  85. package/docs/lessons/0055-agents-compensate-for-garbled-prompts.md +31 -0
  86. package/docs/lessons/0056-grep-count-exit-code-on-zero.md +42 -0
  87. package/docs/lessons/0057-new-artifacts-break-git-clean-gates.md +42 -0
  88. package/docs/lessons/0058-dead-config-keys-never-consumed.md +49 -0
  89. package/docs/lessons/0059-contract-test-shared-structures.md +53 -0
  90. package/docs/lessons/0060-set-e-silent-death-in-runners.md +53 -0
  91. package/docs/lessons/0061-context-injection-dirty-state.md +50 -0
  92. package/docs/lessons/0062-sibling-bug-neighborhood-scan.md +29 -0
  93. package/docs/lessons/0063-one-flag-two-lifetimes.md +31 -0
  94. package/docs/lessons/0064-test-passes-wrong-reason.md +31 -0
  95. package/docs/lessons/0065-pipefail-grep-count-double-output.md +39 -0
  96. package/docs/lessons/0066-local-keyword-outside-function.md +37 -0
  97. package/docs/lessons/0067-stdin-hang-non-interactive-shell.md +36 -0
  98. package/docs/lessons/0068-agent-builds-wrong-thing-correctly.md +31 -0
  99. package/docs/lessons/0069-plan-quality-dominates-execution.md +30 -0
  100. package/docs/lessons/0070-spec-echo-back-prevents-drift.md +31 -0
  101. package/docs/lessons/0071-positive-instructions-outperform-negative.md +30 -0
  102. package/docs/lessons/0072-lost-in-the-middle-context-placement.md +30 -0
  103. package/docs/lessons/0073-unscoped-lessons-cause-false-positives.md +30 -0
  104. package/docs/lessons/0074-stale-context-injection-wrong-batch.md +32 -0
  105. package/docs/lessons/0075-research-artifacts-must-persist.md +32 -0
  106. package/docs/lessons/0076-wrong-decomposition-contaminates-downstream.md +30 -0
  107. package/docs/lessons/0077-cherry-pick-merges-need-manual-resolution.md +30 -0
  108. package/docs/lessons/0078-static-review-without-live-test.md +30 -0
  109. package/docs/lessons/0079-integration-wiring-batch-required.md +32 -0
  110. package/docs/lessons/FRAMEWORK.md +161 -0
  111. package/docs/lessons/SUMMARY.md +201 -0
  112. package/docs/lessons/TEMPLATE.md +85 -0
  113. package/docs/plans/2026-02-21-code-factory-v2-design.md +204 -0
  114. package/docs/plans/2026-02-21-code-factory-v2-implementation-plan.md +2189 -0
  115. package/docs/plans/2026-02-21-code-factory-v2-phase4-design.md +537 -0
  116. package/docs/plans/2026-02-21-code-factory-v2-phase4-implementation-plan.md +2012 -0
  117. package/docs/plans/2026-02-21-hardening-pass-design.md +108 -0
  118. package/docs/plans/2026-02-21-hardening-pass-plan.md +1378 -0
  119. package/docs/plans/2026-02-21-mab-research-report.md +406 -0
  120. package/docs/plans/2026-02-21-marketplace-restructure-design.md +240 -0
  121. package/docs/plans/2026-02-21-marketplace-restructure-plan.md +832 -0
  122. package/docs/plans/2026-02-21-phase4-completion-plan.md +697 -0
  123. package/docs/plans/2026-02-21-validator-suite-design.md +148 -0
  124. package/docs/plans/2026-02-21-validator-suite-plan.md +540 -0
  125. package/docs/plans/2026-02-22-mab-research-round2.md +556 -0
  126. package/docs/plans/2026-02-22-mab-run-design.md +462 -0
  127. package/docs/plans/2026-02-22-mab-run-plan.md +2046 -0
  128. package/docs/plans/2026-02-22-operations-design-methodology-research.md +681 -0
  129. package/docs/plans/2026-02-22-research-agent-failure-taxonomy.md +532 -0
  130. package/docs/plans/2026-02-22-research-code-guideline-policies.md +886 -0
  131. package/docs/plans/2026-02-22-research-codebase-audit-refactoring.md +908 -0
  132. package/docs/plans/2026-02-22-research-coding-standards-documentation.md +541 -0
  133. package/docs/plans/2026-02-22-research-competitive-landscape.md +687 -0
  134. package/docs/plans/2026-02-22-research-comprehensive-testing.md +1076 -0
  135. package/docs/plans/2026-02-22-research-context-utilization.md +459 -0
  136. package/docs/plans/2026-02-22-research-cost-quality-tradeoff.md +548 -0
  137. package/docs/plans/2026-02-22-research-lesson-transferability.md +508 -0
  138. package/docs/plans/2026-02-22-research-multi-agent-coordination.md +312 -0
  139. package/docs/plans/2026-02-22-research-phase-integration.md +602 -0
  140. package/docs/plans/2026-02-22-research-plan-quality.md +428 -0
  141. package/docs/plans/2026-02-22-research-prompt-engineering.md +558 -0
  142. package/docs/plans/2026-02-22-research-unconventional-perspectives.md +528 -0
  143. package/docs/plans/2026-02-22-research-user-adoption.md +638 -0
  144. package/docs/plans/2026-02-22-research-verification-effectiveness.md +433 -0
  145. package/docs/plans/2026-02-23-agent-suite-design.md +299 -0
  146. package/docs/plans/2026-02-23-agent-suite-plan.md +578 -0
  147. package/docs/plans/2026-02-23-phase3-cost-infrastructure-design.md +148 -0
  148. package/docs/plans/2026-02-23-phase3-cost-infrastructure-plan.md +1062 -0
  149. package/docs/plans/2026-02-23-research-bash-expert-agent.md +543 -0
  150. package/docs/plans/2026-02-23-research-dependency-auditor-agent.md +564 -0
  151. package/docs/plans/2026-02-23-research-improving-existing-agents.md +503 -0
  152. package/docs/plans/2026-02-23-research-integration-tester-agent.md +454 -0
  153. package/docs/plans/2026-02-23-research-python-expert-agent.md +429 -0
  154. package/docs/plans/2026-02-23-research-service-monitor-agent.md +425 -0
  155. package/docs/plans/2026-02-23-research-shell-expert-agent.md +533 -0
  156. package/docs/plans/2026-02-23-roadmap-to-completion.md +530 -0
  157. package/docs/plans/2026-02-24-headless-module-split-design.md +98 -0
  158. package/docs/plans/2026-02-24-headless-module-split.md +443 -0
  159. package/docs/plans/2026-02-24-lesson-scope-metadata-design.md +228 -0
  160. package/docs/plans/2026-02-24-lesson-scope-metadata-plan.md +968 -0
  161. package/docs/plans/2026-02-24-npm-packaging-design.md +841 -0
  162. package/docs/plans/2026-02-24-npm-packaging-plan.md +1965 -0
  163. package/docs/plans/audit-findings.md +186 -0
  164. package/docs/telegram-notification-format.md +98 -0
  165. package/examples/example-plan.md +51 -0
  166. package/examples/example-prd.json +72 -0
  167. package/examples/example-roadmap.md +33 -0
  168. package/examples/quickstart-plan.md +63 -0
  169. package/hooks/hooks.json +26 -0
  170. package/hooks/setup-symlinks.sh +48 -0
  171. package/hooks/stop-hook.sh +135 -0
  172. package/package.json +47 -0
  173. package/policies/bash.md +71 -0
  174. package/policies/python.md +71 -0
  175. package/policies/testing.md +61 -0
  176. package/policies/universal.md +60 -0
  177. package/scripts/analyze-report.sh +97 -0
  178. package/scripts/architecture-map.sh +145 -0
  179. package/scripts/auto-compound.sh +273 -0
  180. package/scripts/batch-audit.sh +42 -0
  181. package/scripts/batch-test.sh +101 -0
  182. package/scripts/entropy-audit.sh +221 -0
  183. package/scripts/failure-digest.sh +51 -0
  184. package/scripts/generate-ast-rules.sh +96 -0
  185. package/scripts/init.sh +112 -0
  186. package/scripts/lesson-check.sh +428 -0
  187. package/scripts/lib/common.sh +61 -0
  188. package/scripts/lib/cost-tracking.sh +153 -0
  189. package/scripts/lib/ollama.sh +60 -0
  190. package/scripts/lib/progress-writer.sh +128 -0
  191. package/scripts/lib/run-plan-context.sh +215 -0
  192. package/scripts/lib/run-plan-echo-back.sh +231 -0
  193. package/scripts/lib/run-plan-headless.sh +396 -0
  194. package/scripts/lib/run-plan-notify.sh +57 -0
  195. package/scripts/lib/run-plan-parser.sh +81 -0
  196. package/scripts/lib/run-plan-prompt.sh +215 -0
  197. package/scripts/lib/run-plan-quality-gate.sh +132 -0
  198. package/scripts/lib/run-plan-routing.sh +315 -0
  199. package/scripts/lib/run-plan-sampling.sh +170 -0
  200. package/scripts/lib/run-plan-scoring.sh +146 -0
  201. package/scripts/lib/run-plan-state.sh +142 -0
  202. package/scripts/lib/run-plan-team.sh +199 -0
  203. package/scripts/lib/telegram.sh +54 -0
  204. package/scripts/lib/thompson-sampling.sh +176 -0
  205. package/scripts/license-check.sh +74 -0
  206. package/scripts/mab-run.sh +575 -0
  207. package/scripts/module-size-check.sh +146 -0
  208. package/scripts/patterns/async-no-await.yml +5 -0
  209. package/scripts/patterns/bare-except.yml +6 -0
  210. package/scripts/patterns/empty-catch.yml +6 -0
  211. package/scripts/patterns/hardcoded-localhost.yml +9 -0
  212. package/scripts/patterns/retry-loop-no-backoff.yml +12 -0
  213. package/scripts/pipeline-status.sh +197 -0
  214. package/scripts/policy-check.sh +226 -0
  215. package/scripts/prior-art-search.sh +133 -0
  216. package/scripts/promote-mab-lessons.sh +126 -0
  217. package/scripts/prompts/agent-a-superpowers.md +29 -0
  218. package/scripts/prompts/agent-b-ralph.md +29 -0
  219. package/scripts/prompts/judge-agent.md +61 -0
  220. package/scripts/prompts/planner-agent.md +44 -0
  221. package/scripts/pull-community-lessons.sh +90 -0
  222. package/scripts/quality-gate.sh +266 -0
  223. package/scripts/research-gate.sh +90 -0
  224. package/scripts/run-plan.sh +329 -0
  225. package/scripts/scope-infer.sh +159 -0
  226. package/scripts/setup-ralph-loop.sh +155 -0
  227. package/scripts/telemetry.sh +230 -0
  228. package/scripts/tests/run-all-tests.sh +52 -0
  229. package/scripts/tests/test-act-cli.sh +46 -0
  230. package/scripts/tests/test-agents-md.sh +87 -0
  231. package/scripts/tests/test-analyze-report.sh +114 -0
  232. package/scripts/tests/test-architecture-map.sh +89 -0
  233. package/scripts/tests/test-auto-compound.sh +169 -0
  234. package/scripts/tests/test-batch-test.sh +65 -0
  235. package/scripts/tests/test-benchmark-runner.sh +25 -0
  236. package/scripts/tests/test-common.sh +168 -0
  237. package/scripts/tests/test-cost-tracking.sh +158 -0
  238. package/scripts/tests/test-echo-back.sh +180 -0
  239. package/scripts/tests/test-entropy-audit.sh +146 -0
  240. package/scripts/tests/test-failure-digest.sh +66 -0
  241. package/scripts/tests/test-generate-ast-rules.sh +145 -0
  242. package/scripts/tests/test-helpers.sh +82 -0
  243. package/scripts/tests/test-init.sh +47 -0
  244. package/scripts/tests/test-lesson-check.sh +278 -0
  245. package/scripts/tests/test-lesson-local.sh +55 -0
  246. package/scripts/tests/test-license-check.sh +109 -0
  247. package/scripts/tests/test-mab-run.sh +182 -0
  248. package/scripts/tests/test-ollama-lib.sh +49 -0
  249. package/scripts/tests/test-ollama.sh +60 -0
  250. package/scripts/tests/test-pipeline-status.sh +198 -0
  251. package/scripts/tests/test-policy-check.sh +124 -0
  252. package/scripts/tests/test-prior-art-search.sh +96 -0
  253. package/scripts/tests/test-progress-writer.sh +140 -0
  254. package/scripts/tests/test-promote-mab-lessons.sh +110 -0
  255. package/scripts/tests/test-pull-community-lessons.sh +149 -0
  256. package/scripts/tests/test-quality-gate.sh +241 -0
  257. package/scripts/tests/test-research-gate.sh +132 -0
  258. package/scripts/tests/test-run-plan-cli.sh +86 -0
  259. package/scripts/tests/test-run-plan-context.sh +305 -0
  260. package/scripts/tests/test-run-plan-e2e.sh +153 -0
  261. package/scripts/tests/test-run-plan-headless.sh +424 -0
  262. package/scripts/tests/test-run-plan-notify.sh +124 -0
  263. package/scripts/tests/test-run-plan-parser.sh +217 -0
  264. package/scripts/tests/test-run-plan-prompt.sh +254 -0
  265. package/scripts/tests/test-run-plan-quality-gate.sh +222 -0
  266. package/scripts/tests/test-run-plan-routing.sh +178 -0
  267. package/scripts/tests/test-run-plan-scoring.sh +148 -0
  268. package/scripts/tests/test-run-plan-state.sh +261 -0
  269. package/scripts/tests/test-run-plan-team.sh +157 -0
  270. package/scripts/tests/test-scope-infer.sh +150 -0
  271. package/scripts/tests/test-setup-ralph-loop.sh +63 -0
  272. package/scripts/tests/test-telegram-env.sh +38 -0
  273. package/scripts/tests/test-telegram.sh +121 -0
  274. package/scripts/tests/test-telemetry.sh +46 -0
  275. package/scripts/tests/test-thompson-sampling.sh +139 -0
  276. package/scripts/tests/test-validate-all.sh +60 -0
  277. package/scripts/tests/test-validate-commands.sh +89 -0
  278. package/scripts/tests/test-validate-hooks.sh +98 -0
  279. package/scripts/tests/test-validate-lessons.sh +150 -0
  280. package/scripts/tests/test-validate-plan-quality.sh +235 -0
  281. package/scripts/tests/test-validate-plans.sh +187 -0
  282. package/scripts/tests/test-validate-plugin.sh +106 -0
  283. package/scripts/tests/test-validate-prd.sh +184 -0
  284. package/scripts/tests/test-validate-skills.sh +134 -0
  285. package/scripts/validate-all.sh +57 -0
  286. package/scripts/validate-commands.sh +67 -0
  287. package/scripts/validate-hooks.sh +89 -0
  288. package/scripts/validate-lessons.sh +98 -0
  289. package/scripts/validate-plan-quality.sh +369 -0
  290. package/scripts/validate-plans.sh +120 -0
  291. package/scripts/validate-plugin.sh +86 -0
  292. package/scripts/validate-policies.sh +42 -0
  293. package/scripts/validate-prd.sh +118 -0
  294. package/scripts/validate-skills.sh +96 -0
  295. package/skills/autocode/SKILL.md +285 -0
  296. package/skills/autocode/ab-verification.md +51 -0
  297. package/skills/autocode/code-quality-standards.md +37 -0
  298. package/skills/autocode/competitive-mode.md +364 -0
  299. package/skills/brainstorming/SKILL.md +97 -0
  300. package/skills/capture-lesson/SKILL.md +187 -0
  301. package/skills/check-lessons/SKILL.md +116 -0
  302. package/skills/dispatching-parallel-agents/SKILL.md +110 -0
  303. package/skills/executing-plans/SKILL.md +85 -0
  304. package/skills/finishing-a-development-branch/SKILL.md +201 -0
  305. package/skills/receiving-code-review/SKILL.md +72 -0
  306. package/skills/requesting-code-review/SKILL.md +59 -0
  307. package/skills/requesting-code-review/code-reviewer.md +82 -0
  308. package/skills/research/SKILL.md +145 -0
  309. package/skills/roadmap/SKILL.md +115 -0
  310. package/skills/subagent-driven-development/SKILL.md +98 -0
  311. package/skills/subagent-driven-development/code-quality-reviewer-prompt.md +18 -0
  312. package/skills/subagent-driven-development/implementer-prompt.md +73 -0
  313. package/skills/subagent-driven-development/spec-reviewer-prompt.md +57 -0
  314. package/skills/systematic-debugging/SKILL.md +134 -0
  315. package/skills/systematic-debugging/condition-based-waiting.md +64 -0
  316. package/skills/systematic-debugging/defense-in-depth.md +32 -0
  317. package/skills/systematic-debugging/root-cause-tracing.md +55 -0
  318. package/skills/test-driven-development/SKILL.md +167 -0
  319. package/skills/using-git-worktrees/SKILL.md +219 -0
  320. package/skills/using-superpowers/SKILL.md +54 -0
  321. package/skills/verification-before-completion/SKILL.md +140 -0
  322. package/skills/verify/SKILL.md +82 -0
  323. package/skills/writing-plans/SKILL.md +128 -0
  324. package/skills/writing-skills/SKILL.md +93 -0
@@ -0,0 +1,135 @@
1
+ #!/bin/bash
2
+
3
+ # Ralph Loop Stop Hook
4
+ # Prevents session exit when a ralph-loop is active
5
+ # Feeds Claude's output back as input to continue the loop
6
+
7
+ set -euo pipefail
8
+
9
+ # Read hook input from stdin (advanced stop hook API)
10
+ HOOK_INPUT=$(cat)
11
+
12
+ # Check if ralph-loop is active
13
+ RALPH_STATE_FILE=".claude/ralph-loop.local.md"
14
+
15
+ if [[ ! -f "$RALPH_STATE_FILE" ]]; then
16
+ # No active loop - allow exit
17
+ exit 0
18
+ fi
19
+
20
+ # Parse markdown frontmatter (YAML between ---) and extract values
21
+ FRONTMATTER=$(sed -n '/^---$/,/^---$/{ /^---$/d; p; }' "$RALPH_STATE_FILE")
22
+ ITERATION=$(echo "$FRONTMATTER" | grep '^iteration:' | sed 's/iteration: *//')
23
+ MAX_ITERATIONS=$(echo "$FRONTMATTER" | grep '^max_iterations:' | sed 's/max_iterations: *//')
24
+ # Extract completion_promise and strip surrounding quotes if present
25
+ COMPLETION_PROMISE=$(echo "$FRONTMATTER" | grep '^completion_promise:' | sed 's/completion_promise: *//' | sed 's/^"\(.*\)"$/\1/')
26
+
27
+ # Validate numeric fields before arithmetic operations
28
+ if [[ ! "$ITERATION" =~ ^[0-9]+$ ]]; then
29
+ echo "Ralph loop: State file corrupted (iteration not numeric)" >&2
30
+ rm "$RALPH_STATE_FILE"
31
+ exit 0
32
+ fi
33
+
34
+ if [[ ! "$MAX_ITERATIONS" =~ ^[0-9]+$ ]]; then
35
+ echo "Ralph loop: State file corrupted (max_iterations not numeric)" >&2
36
+ rm "$RALPH_STATE_FILE"
37
+ exit 0
38
+ fi
39
+
40
+ # Check if max iterations reached
41
+ if [[ $MAX_ITERATIONS -gt 0 ]] && [[ $ITERATION -ge $MAX_ITERATIONS ]]; then
42
+ echo "Ralph loop: Max iterations ($MAX_ITERATIONS) reached."
43
+ rm "$RALPH_STATE_FILE"
44
+ exit 0
45
+ fi
46
+
47
+ # Get transcript path from hook input
48
+ TRANSCRIPT_PATH=$(echo "$HOOK_INPUT" | jq -r '.transcript_path')
49
+
50
+ if [[ ! -f "$TRANSCRIPT_PATH" ]]; then
51
+ echo "Ralph loop: Transcript file not found" >&2
52
+ rm "$RALPH_STATE_FILE"
53
+ exit 0
54
+ fi
55
+
56
+ # Read last assistant message from transcript (JSONL format)
57
+ if ! grep -q '"role":"assistant"' "$TRANSCRIPT_PATH"; then
58
+ echo "Ralph loop: No assistant messages found in transcript" >&2
59
+ rm "$RALPH_STATE_FILE"
60
+ exit 0
61
+ fi
62
+
63
+ LAST_LINE=$(grep '"role":"assistant"' "$TRANSCRIPT_PATH" | tail -1)
64
+ if [[ -z "$LAST_LINE" ]]; then
65
+ echo "Ralph loop: Failed to extract last assistant message" >&2
66
+ rm "$RALPH_STATE_FILE"
67
+ exit 0
68
+ fi
69
+
70
+ # Parse JSON with error handling
71
+ LAST_OUTPUT=$(echo "$LAST_LINE" | jq -r '
72
+ .message.content |
73
+ map(select(.type == "text")) |
74
+ map(.text) |
75
+ join("\n")
76
+ ' 2>&1)
77
+
78
+ if [[ $? -ne 0 ]]; then
79
+ echo "Ralph loop: Failed to parse assistant message JSON" >&2
80
+ rm "$RALPH_STATE_FILE"
81
+ exit 0
82
+ fi
83
+
84
+ if [[ -z "$LAST_OUTPUT" ]]; then
85
+ echo "Ralph loop: Assistant message contained no text content" >&2
86
+ rm "$RALPH_STATE_FILE"
87
+ exit 0
88
+ fi
89
+
90
+ # Check for completion promise (only if set)
91
+ if [[ "$COMPLETION_PROMISE" != "null" ]] && [[ -n "$COMPLETION_PROMISE" ]]; then
92
+ PROMISE_TEXT=$(echo "$LAST_OUTPUT" | perl -0777 -pe 's/.*?<promise>(.*?)<\/promise>.*/$1/s; s/^\s+|\s+$//g; s/\s+/ /g' 2>/dev/null || echo "")
93
+
94
+ if [[ -n "$PROMISE_TEXT" ]] && [[ "$PROMISE_TEXT" = "$COMPLETION_PROMISE" ]]; then
95
+ echo "Ralph loop: Detected <promise>$COMPLETION_PROMISE</promise>"
96
+ rm "$RALPH_STATE_FILE"
97
+ exit 0
98
+ fi
99
+ fi
100
+
101
+ # Not complete - continue loop with SAME PROMPT
102
+ NEXT_ITERATION=$((ITERATION + 1))
103
+
104
+ # Extract prompt (everything after the closing ---)
105
+ PROMPT_TEXT=$(awk '/^---$/{i++; next} i>=2' "$RALPH_STATE_FILE")
106
+
107
+ if [[ -z "$PROMPT_TEXT" ]]; then
108
+ echo "Ralph loop: State file corrupted (no prompt text)" >&2
109
+ rm "$RALPH_STATE_FILE"
110
+ exit 0
111
+ fi
112
+
113
+ # Update iteration in frontmatter
114
+ TEMP_FILE="${RALPH_STATE_FILE}.tmp.$$"
115
+ sed "s/^iteration: .*/iteration: $NEXT_ITERATION/" "$RALPH_STATE_FILE" > "$TEMP_FILE"
116
+ mv "$TEMP_FILE" "$RALPH_STATE_FILE"
117
+
118
+ # Build system message
119
+ if [[ "$COMPLETION_PROMISE" != "null" ]] && [[ -n "$COMPLETION_PROMISE" ]]; then
120
+ SYSTEM_MSG="Ralph iteration $NEXT_ITERATION | To stop: output <promise>$COMPLETION_PROMISE</promise> (ONLY when statement is TRUE - do not lie to exit!)"
121
+ else
122
+ SYSTEM_MSG="Ralph iteration $NEXT_ITERATION | No completion promise set - loop runs infinitely"
123
+ fi
124
+
125
+ # Output JSON to block the stop and feed prompt back
126
+ jq -n \
127
+ --arg prompt "$PROMPT_TEXT" \
128
+ --arg msg "$SYSTEM_MSG" \
129
+ '{
130
+ "decision": "block",
131
+ "reason": $prompt,
132
+ "systemMessage": $msg
133
+ }'
134
+
135
+ exit 0
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "autonomous-coding-toolkit",
3
+ "version": "1.0.0",
4
+ "description": "Autonomous AI coding pipeline: quality gates, fresh-context execution, community lessons, and compounding learning",
5
+ "license": "MIT",
6
+ "author": "Justin McFarland <parthalon025@gmail.com>",
7
+ "homepage": "https://github.com/parthalon025/autonomous-coding-toolkit",
8
+ "repository": "https://github.com/parthalon025/autonomous-coding-toolkit",
9
+ "bin": {
10
+ "act": "./bin/act.js"
11
+ },
12
+ "files": [
13
+ "bin/",
14
+ "scripts/",
15
+ "skills/",
16
+ "commands/",
17
+ "agents/",
18
+ "hooks/",
19
+ "policies/",
20
+ "examples/",
21
+ "benchmarks/",
22
+ "docs/",
23
+ ".claude-plugin/",
24
+ "Makefile",
25
+ "SECURITY.md"
26
+ ],
27
+ "engines": {
28
+ "node": ">=18.0.0"
29
+ },
30
+ "os": [
31
+ "linux",
32
+ "darwin",
33
+ "win32"
34
+ ],
35
+ "keywords": [
36
+ "autonomous-coding",
37
+ "ai-agents",
38
+ "quality-gates",
39
+ "claude-code",
40
+ "tdd",
41
+ "lessons-learned",
42
+ "headless",
43
+ "multi-armed-bandit",
44
+ "code-review",
45
+ "pipeline"
46
+ ]
47
+ }
@@ -0,0 +1,71 @@
1
+ # Bash Policies
2
+
3
+ Positive patterns for shell scripts. Derived from lessons #51, #58, #74, #75.
4
+
5
+ ## Strict Mode
6
+
7
+ **Start every script with `set -euo pipefail`.**
8
+ Without strict mode, failed commands are silently ignored and undefined variables expand to empty strings.
9
+
10
+ ```bash
11
+ #!/usr/bin/env bash
12
+ set -euo pipefail
13
+ ```
14
+
15
+ ## Quote Variables
16
+
17
+ **Always quote variable expansions.**
18
+ Unquoted variables undergo word splitting and glob expansion, breaking on filespace names and special characters.
19
+
20
+ ```bash
21
+ # Pattern: double-quote all expansions
22
+ cp "$source_file" "$dest_dir/"
23
+ if [[ -f "$config_path" ]]; then
24
+ ```
25
+
26
+ ## Subshell for Directory Changes
27
+
28
+ **Use a subshell when `cd` is temporary.**
29
+ Forgetting to `cd` back breaks all subsequent relative paths. A subshell automatically restores the working directory.
30
+
31
+ ```bash
32
+ # Pattern: subshell isolates cd
33
+ (
34
+ cd "$build_dir"
35
+ make install
36
+ )
37
+ # Back to original directory automatically
38
+ ```
39
+
40
+ ## Temp File Cleanup
41
+
42
+ **Use `trap` to clean up temporary files.**
43
+ Early exits from `set -e` skip manual cleanup. A trap ensures cleanup runs regardless of exit path.
44
+
45
+ ```bash
46
+ tmpfile=$(mktemp)
47
+ trap 'rm -f "$tmpfile"' EXIT
48
+
49
+ # Use $tmpfile safely — cleanup guaranteed
50
+ ```
51
+
52
+ ## Redirect Then Move
53
+
54
+ **Write to a temp file, then `mv` to the target.**
55
+ Writing directly to the target risks corruption on failure — a partial write leaves an invalid file. `mv` is atomic on the same filesystem.
56
+
57
+ ```bash
58
+ # Pattern: write to tmp, then atomic move
59
+ jq '.count += 1' "$state_file" > "$tmp" && mv "$tmp" "$state_file"
60
+ ```
61
+
62
+ ## Arithmetic Evaluation
63
+
64
+ **Use `$(( ))` for arithmetic, not bare expressions.**
65
+ Shell arithmetic needs explicit evaluation context. Without it, expressions are treated as strings.
66
+
67
+ ```bash
68
+ # Pattern: explicit arithmetic
69
+ delta=$(( end_time - start_time ))
70
+ if [[ $count -gt 0 ]]; then
71
+ ```
@@ -0,0 +1,71 @@
1
+ # Python Policies
2
+
3
+ Positive patterns for Python codebases. Derived from lessons #25, #30, #33, #37, #43.
4
+
5
+ ## Async Discipline
6
+
7
+ **Only use `async def` when the function performs I/O.**
8
+ Unnecessary async adds complexity without benefit. If there's no `await` inside, it shouldn't be async.
9
+
10
+ ```python
11
+ # Pattern: async def must contain await
12
+ async def fetch_user(user_id: str) -> User:
13
+ return await db.get(user_id) # I/O justifies async
14
+ ```
15
+
16
+ ## Await at Call Sites
17
+
18
+ **Verify every call to an async function is awaited.**
19
+ Missing `await` returns a coroutine object instead of the result — often passes truthiness checks silently.
20
+
21
+ ```python
22
+ # Pattern: await at every async call site
23
+ user = await fetch_user(user_id) # not: user = fetch_user(user_id)
24
+ ```
25
+
26
+ ## SQLite Closing
27
+
28
+ **Use `closing()` context manager for sqlite3 connections.**
29
+ Without it, connections leak on exceptions. The `closing()` wrapper guarantees cleanup.
30
+
31
+ ```python
32
+ from contextlib import closing
33
+ import sqlite3
34
+
35
+ with closing(sqlite3.connect("db.sqlite")) as conn:
36
+ cursor = conn.execute("SELECT ...")
37
+ ```
38
+
39
+ ## Task Error Visibility
40
+
41
+ **Add a `done_callback` to every `create_task` call.**
42
+ Unobserved task exceptions vanish silently. The callback surfaces errors immediately.
43
+
44
+ ```python
45
+ task = asyncio.create_task(background_work())
46
+ task.add_done_callback(lambda t: t.result() if not t.cancelled() else None)
47
+ ```
48
+
49
+ ## Subscriber Lifecycle
50
+
51
+ **Store callback references on `self` and unsubscribe in `shutdown()`.**
52
+ Anonymous lambda callbacks can't be unsubscribed. Leaked subscriptions cause duplicate processing after restart.
53
+
54
+ ```python
55
+ class MyService:
56
+ def __init__(self, bus):
57
+ self._unsub = bus.subscribe("event", self._handle)
58
+
59
+ async def shutdown(self):
60
+ self._unsub()
61
+ ```
62
+
63
+ ## Install via Module
64
+
65
+ **Use `.venv/bin/python -m pip` instead of `.venv/bin/pip`.**
66
+ Direct pip invocation can resolve to Homebrew Python on mixed-runtime systems, installing packages into the wrong environment.
67
+
68
+ ```bash
69
+ # Pattern: always invoke pip through python -m
70
+ .venv/bin/python -m pip install pytest-xdist
71
+ ```
@@ -0,0 +1,61 @@
1
+ # Testing Policies
2
+
3
+ Positive patterns for test suites. Derived from lessons #32, #44, #50, #73, #78.
4
+
5
+ ## No Hardcoded Counts
6
+
7
+ **Assert test behavior, not test quantities.**
8
+ Hardcoded counts break when tests are added or removed. Count assertions create false failures unrelated to code quality.
9
+
10
+ ```bash
11
+ # Pattern: assert threshold, not exact count
12
+ test_count=$(pytest --co -q 2>/dev/null | tail -1 | grep -o '[0-9]*')
13
+ [[ "$test_count" -ge 10 ]] # not: [[ "$test_count" -eq 42 ]]
14
+ ```
15
+
16
+ ## Verify Threshold Math
17
+
18
+ **Test boundary conditions explicitly.**
19
+ Off-by-one errors in thresholds are the most common assertion bug. Test at, below, and above the boundary.
20
+
21
+ ```python
22
+ # Pattern: test exact boundary
23
+ assert is_valid(threshold) # at boundary
24
+ assert not is_valid(threshold - 1) # below
25
+ assert is_valid(threshold + 1) # above (if applicable)
26
+ ```
27
+
28
+ ## Test the Test
29
+
30
+ **Verify a test fails when the condition it checks is broken.**
31
+ A test that always passes catches nothing. Temporarily break the code and confirm the test detects it.
32
+
33
+ ```bash
34
+ # Pattern: red-green verification
35
+ # 1. Write test → see it FAIL (red)
36
+ # 2. Write code → see it PASS (green)
37
+ # 3. Break code → see it FAIL again (confirms test works)
38
+ ```
39
+
40
+ ## Live Over Static
41
+
42
+ **One live integration test catches more bugs than six static reviewers.**
43
+ Static analysis finds structural issues but misses behavioral bugs. Always include at least one end-to-end test that exercises the real system.
44
+
45
+ ```bash
46
+ # Pattern: combine static + live
47
+ shellcheck scripts/*.sh # static: catches syntax
48
+ bash scripts/run-plan.sh --dry-run # live: catches behavior
49
+ ```
50
+
51
+ ## Monotonic Test Count
52
+
53
+ **Test counts only go up between batches.**
54
+ A decreasing test count means something was deleted or broken. Track the high-water mark and enforce it.
55
+
56
+ ```bash
57
+ # Pattern: compare against high-water mark
58
+ prev_count=$(jq -r '.test_count' .run-plan-state.json)
59
+ curr_count=$(pytest --co -q 2>/dev/null | tail -1 | grep -o '[0-9]*')
60
+ [[ "$curr_count" -ge "$prev_count" ]]
61
+ ```
@@ -0,0 +1,60 @@
1
+ # Universal Policies
2
+
3
+ Cross-language positive patterns. These apply to all projects regardless of language.
4
+
5
+ ## Error Visibility
6
+
7
+ **Always log before returning a fallback value.**
8
+ When a function catches an error and returns a default, the error must be logged first. Silent fallbacks hide bugs.
9
+
10
+ ```
11
+ # Pattern: catch → log → fallback
12
+ try:
13
+ result = fetch_data()
14
+ except ConnectionError as e:
15
+ logger.warning("fetch_data failed, using cache: %s", e)
16
+ result = cached_value
17
+ ```
18
+
19
+ ## Test Before Ship
20
+
21
+ **Run the full test suite before claiming work is complete.**
22
+ Partial test runs miss integration failures. "It works on my machine" is not verification.
23
+
24
+ ```
25
+ # Pattern: test → verify → commit
26
+ make ci # or: pytest / npm test / make test
27
+ git add <files>
28
+ git commit
29
+ ```
30
+
31
+ ## Fresh Context Per Unit
32
+
33
+ **Start each independent unit of work with a clean context.**
34
+ Context degradation compounds — stale variables, wrong assumptions, and accumulated state cause subtle bugs after extended sessions.
35
+
36
+ ```
37
+ # Pattern: checkpoint → clear → resume
38
+ # After 5+ batches or major topic shift, start fresh
39
+ ```
40
+
41
+ ## Append-Only Progress
42
+
43
+ **Never overwrite progress files — always append.**
44
+ Truncating progress loses discoveries from prior batches. The next context reset will repeat mistakes.
45
+
46
+ ```
47
+ # Pattern: append to progress.txt
48
+ echo "## Batch 3: Added auth middleware" >> progress.txt
49
+ ```
50
+
51
+ ## Durable Artifacts
52
+
53
+ **Every research activity produces a file, not just conversation.**
54
+ Conversation context resets; files persist. If it's worth investigating, it's worth writing down.
55
+
56
+ ```
57
+ # Pattern: investigate → write file → reference file
58
+ # Bad: "I looked into it and found..."
59
+ # Good: Write findings to tasks/research-<slug>.md
60
+ ```
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env bash
2
+ # analyze-report.sh — Analyze a report and pick the #1 actionable priority
3
+ #
4
+ # Usage: analyze-report.sh <report-file> [--dry-run] [--model MODEL]
5
+ #
6
+ # Reads a markdown report (test failures, errors, user feedback, metrics)
7
+ # and uses an LLM to identify the single most impactful fix.
8
+ #
9
+ # Output: analysis.json with priority, reasoning, and suggested PRD outline
10
+ #
11
+ # Models: Uses Ollama queue (port 7683) for serialized execution.
12
+ # Default model: deepseek-r1:8b (reasoning-optimized)
13
+
14
+ set -euo pipefail
15
+
16
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
17
+ source "$SCRIPT_DIR/lib/common.sh"
18
+ source "$SCRIPT_DIR/lib/ollama.sh"
19
+
20
+ REPORT_FILE="${1:-}"
21
+ DRY_RUN=false
22
+ MODEL="deepseek-r1:8b"
23
+ OUTPUT_DIR="."
24
+
25
+ # Parse remaining args
26
+ shift || true
27
+ while [[ $# -gt 0 ]]; do
28
+ case $1 in
29
+ --dry-run) DRY_RUN=true; shift ;;
30
+ --model) MODEL="$2"; shift 2 ;;
31
+ --output-dir) OUTPUT_DIR="$2"; shift 2 ;;
32
+ *) echo "Unknown option: $1" >&2; exit 1 ;;
33
+ esac
34
+ done
35
+
36
+ if [[ -z "$REPORT_FILE" ]] || [[ ! -f "$REPORT_FILE" ]]; then
37
+ echo "Usage: analyze-report.sh <report-file> [--dry-run] [--model MODEL]" >&2
38
+ echo "" >&2
39
+ echo "Report file not found: ${REPORT_FILE:-<none>}" >&2
40
+ exit 1
41
+ fi
42
+
43
+ REPORT_CONTENT=$(cat "$REPORT_FILE")
44
+
45
+ PROMPT="You are analyzing a development report to identify the single most impactful priority to fix.
46
+
47
+ ## Report
48
+ $REPORT_CONTENT
49
+
50
+ ## Instructions
51
+ 1. Read the report carefully
52
+ 2. Identify ALL issues mentioned
53
+ 3. Rank them by: revenue impact > user-facing bugs > developer experience > tech debt
54
+ 4. Pick the #1 priority — the one fix that delivers the most value
55
+
56
+ ## Output
57
+ Respond with ONLY valid JSON (no markdown fences, no explanation):
58
+ {
59
+ \"priority\": \"Short title of the #1 issue\",
60
+ \"reasoning\": \"Why this is #1 (2-3 sentences)\",
61
+ \"severity\": \"critical|high|medium|low\",
62
+ \"estimated_tasks\": 5,
63
+ \"prd_outline\": [
64
+ \"Task 1 title\",
65
+ \"Task 2 title\"
66
+ ]
67
+ }"
68
+
69
+ if [[ "$DRY_RUN" == "true" ]]; then
70
+ echo "=== DRY RUN ==="
71
+ echo "Report: $REPORT_FILE"
72
+ echo "Model: $MODEL"
73
+ echo "Prompt length: ${#PROMPT} chars"
74
+ echo ""
75
+ echo "Would send to Ollama and save to $OUTPUT_DIR/analysis.json"
76
+ exit 0
77
+ fi
78
+
79
+ # Query Ollama (uses queue if available, falls back to direct)
80
+ ANALYSIS=$(ollama_query "$MODEL" "$PROMPT")
81
+
82
+ if [[ -z "$ANALYSIS" ]]; then
83
+ echo "Error: Empty response from Ollama" >&2
84
+ exit 1
85
+ fi
86
+
87
+ # Parse as JSON
88
+ CLEANED=$(echo "$ANALYSIS" | ollama_extract_json)
89
+ if [[ -n "$CLEANED" ]]; then
90
+ echo "$CLEANED" | jq . > "$OUTPUT_DIR/analysis.json"
91
+ else
92
+ echo "Warning: Could not parse LLM response as JSON, saving raw" >&2
93
+ echo "{\"raw_response\": $(echo "$ANALYSIS" | jq -Rs .)}" > "$OUTPUT_DIR/analysis.json"
94
+ fi
95
+
96
+ echo "Analysis saved to $OUTPUT_DIR/analysis.json" >&2
97
+ cat "$OUTPUT_DIR/analysis.json"
@@ -0,0 +1,145 @@
1
+ #!/usr/bin/env bash
2
+ # architecture-map.sh — Scan project for import/source dependencies → ARCHITECTURE-MAP.json
3
+ #
4
+ # Usage: architecture-map.sh [--project-root <dir>] [--help]
5
+ #
6
+ # Scans *.sh (source/. statements), *.py (import/from), *.js/*.ts (import/require).
7
+ # Groups by directory into modules. Outputs JSON to docs/ARCHITECTURE-MAP.json.
8
+ # Skips: node_modules, .git, __pycache__, .venv, .claude, .worktrees
9
+ set -euo pipefail
10
+
11
+ PROJECT_ROOT="."
12
+
13
+ usage() {
14
+ cat <<'USAGE'
15
+ architecture-map.sh — Scan project for dependency graph
16
+
17
+ Usage: architecture-map.sh [--project-root <dir>] [--help]
18
+
19
+ Outputs: docs/ARCHITECTURE-MAP.json
20
+
21
+ Scans shell (source/.), Python (import/from), JS/TS (import/require) files.
22
+ Groups files by directory into modules with dependency edges.
23
+ USAGE
24
+ }
25
+
26
+ parse_args() {
27
+ while [[ $# -gt 0 ]]; do
28
+ case "$1" in
29
+ --help|-h) usage; exit 0 ;;
30
+ --project-root) PROJECT_ROOT="$2"; shift 2 ;;
31
+ *) echo "ERROR: Unknown option: $1" >&2; exit 1 ;;
32
+ esac
33
+ done
34
+ }
35
+
36
+ # Extract dependencies from a single file
37
+ # Output: one dependency per line (relative path)
38
+ extract_deps() {
39
+ local file="$1"
40
+ local ext="${file##*.}"
41
+
42
+ case "$ext" in
43
+ sh|bash)
44
+ # Match: source <path>, . <path>, source "<path>", . "<path>"
45
+ grep -oE '(source|\.)\s+"?[^"[:space:]]+"?' "$file" 2>/dev/null \
46
+ | sed -E 's/^(source|\.)\s+"?//; s/"?$//' \
47
+ | grep -v '^\$' || true # Skip variable expansions
48
+ ;;
49
+ py)
50
+ # Match: from <module> import ..., import <module>
51
+ grep -oE '(from\s+\S+\s+import|^import\s+\S+)' "$file" 2>/dev/null \
52
+ | sed -E 's/^from\s+//; s/\s+import.*//; s/^import\s+//; s/\./\//g' \
53
+ | while IFS= read -r mod; do
54
+ # Convert module path to file path
55
+ if [[ -f "$PROJECT_ROOT/$mod.py" ]]; then
56
+ echo "$mod.py"
57
+ elif [[ -f "$PROJECT_ROOT/$mod/__init__.py" ]]; then
58
+ echo "$mod/__init__.py"
59
+ fi
60
+ done
61
+ ;;
62
+ js|ts|jsx|tsx)
63
+ # Match: import ... from '<path>', require('<path>')
64
+ grep -oE "(from\s+['\"][^'\"]+['\"]|require\(['\"][^'\"]+['\"]\))" "$file" 2>/dev/null \
65
+ | sed -E "s/from\s+['\"]//; s/require\(['\"]//; s/['\"].*//; s/\)$//" \
66
+ | grep -E '^\.' || true # Only relative imports
67
+ ;;
68
+ esac
69
+ }
70
+
71
+ # Build the architecture map JSON
72
+ build_map() {
73
+ local generated_at
74
+ generated_at=$(date -u +%Y-%m-%dT%H:%M:%SZ)
75
+
76
+ # Find all relevant files, excluding common noise directories
77
+ local -a all_files=()
78
+ while IFS= read -r -d '' file; do
79
+ all_files+=("$file")
80
+ done < <(find "$PROJECT_ROOT" \
81
+ -not -path '*/.git/*' \
82
+ -not -path '*/node_modules/*' \
83
+ -not -path '*/__pycache__/*' \
84
+ -not -path '*/.venv/*' \
85
+ -not -path '*/.claude/*' \
86
+ -not -path '*/.worktrees/*' \
87
+ \( -name '*.sh' -o -name '*.py' -o -name '*.js' -o -name '*.ts' -o -name '*.jsx' -o -name '*.tsx' \) \
88
+ -print0 2>/dev/null | sort -z)
89
+
90
+ # Group files by directory (module)
91
+ declare -A modules
92
+
93
+ for file in "${all_files[@]}"; do
94
+ # Make path relative to project root
95
+ local rel_path="${file#"$PROJECT_ROOT/"}"
96
+ local dir
97
+ dir=$(dirname "$rel_path")
98
+ [[ "$dir" == "." ]] && dir="root"
99
+
100
+ # Extract dependencies
101
+ local deps=""
102
+ while IFS= read -r dep; do
103
+ [[ -z "$dep" ]] && continue
104
+ if [[ -n "$deps" ]]; then
105
+ deps+=","
106
+ fi
107
+ deps+="\"$dep\""
108
+ done < <(extract_deps "$file" | sort -u)
109
+
110
+ local file_json="{\"path\":\"$rel_path\",\"dependencies\":[$deps]}"
111
+
112
+ if [[ -n "${modules[$dir]:-}" ]]; then
113
+ modules["$dir"]+=","
114
+ fi
115
+ modules["$dir"]+="$file_json"
116
+ done
117
+
118
+ # Build modules array
119
+ local modules_json=""
120
+ for dir in $(echo "${!modules[@]}" | tr ' ' '\n' | sort); do
121
+ if [[ -n "$modules_json" ]]; then
122
+ modules_json+=","
123
+ fi
124
+ modules_json+="{\"name\":\"$dir\",\"files\":[${modules[$dir]}]}"
125
+ done
126
+
127
+ # Write output
128
+ local output_dir="$PROJECT_ROOT/docs"
129
+ mkdir -p "$output_dir"
130
+
131
+ cat > "$output_dir/ARCHITECTURE-MAP.json" <<JSON
132
+ {
133
+ "generated_at": "$generated_at",
134
+ "project_root": "$(realpath "$PROJECT_ROOT")",
135
+ "modules": [$modules_json]
136
+ }
137
+ JSON
138
+
139
+ echo "Generated: $output_dir/ARCHITECTURE-MAP.json"
140
+ echo " Modules: $(echo "${!modules[@]}" | wc -w | tr -d ' ')"
141
+ echo " Files: ${#all_files[@]}"
142
+ }
143
+
144
+ parse_args "$@"
145
+ build_map