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.
- package/.claude-plugin/marketplace.json +22 -0
- package/.claude-plugin/plugin.json +13 -0
- package/LICENSE +21 -0
- package/Makefile +21 -0
- package/README.md +140 -0
- package/SECURITY.md +28 -0
- package/agents/bash-expert.md +113 -0
- package/agents/dependency-auditor.md +138 -0
- package/agents/integration-tester.md +120 -0
- package/agents/lesson-scanner.md +149 -0
- package/agents/python-expert.md +179 -0
- package/agents/service-monitor.md +141 -0
- package/agents/shell-expert.md +147 -0
- package/benchmarks/runner.sh +147 -0
- package/benchmarks/tasks/01-rest-endpoint/rubric.sh +29 -0
- package/benchmarks/tasks/01-rest-endpoint/task.md +17 -0
- package/benchmarks/tasks/02-refactor-module/task.md +8 -0
- package/benchmarks/tasks/03-fix-integration-bug/task.md +8 -0
- package/benchmarks/tasks/04-add-test-coverage/task.md +8 -0
- package/benchmarks/tasks/05-multi-file-feature/task.md +8 -0
- package/bin/act.js +238 -0
- package/commands/autocode.md +6 -0
- package/commands/cancel-ralph.md +18 -0
- package/commands/code-factory.md +53 -0
- package/commands/create-prd.md +55 -0
- package/commands/ralph-loop.md +18 -0
- package/commands/run-plan.md +117 -0
- package/commands/submit-lesson.md +122 -0
- package/docs/ARCHITECTURE.md +630 -0
- package/docs/CONTRIBUTING.md +125 -0
- package/docs/lessons/0001-bare-exception-swallowing.md +34 -0
- package/docs/lessons/0002-async-def-without-await.md +28 -0
- package/docs/lessons/0003-create-task-without-callback.md +28 -0
- package/docs/lessons/0004-hardcoded-test-counts.md +28 -0
- package/docs/lessons/0005-sqlite-without-closing.md +33 -0
- package/docs/lessons/0006-venv-pip-path.md +27 -0
- package/docs/lessons/0007-runner-state-self-rejection.md +35 -0
- package/docs/lessons/0008-quality-gate-blind-spot.md +33 -0
- package/docs/lessons/0009-parser-overcount-empty-batches.md +36 -0
- package/docs/lessons/0010-local-outside-function-bash.md +33 -0
- package/docs/lessons/0011-batch-tests-for-unimplemented-code.md +36 -0
- package/docs/lessons/0012-api-markdown-unescaped-chars.md +33 -0
- package/docs/lessons/0013-export-prefix-env-parsing.md +33 -0
- package/docs/lessons/0014-decorator-registry-import-side-effect.md +43 -0
- package/docs/lessons/0015-frontend-backend-schema-drift.md +43 -0
- package/docs/lessons/0016-event-driven-cold-start-seeding.md +44 -0
- package/docs/lessons/0017-copy-paste-logic-diverges.md +43 -0
- package/docs/lessons/0018-layer-passes-pipeline-broken.md +45 -0
- package/docs/lessons/0019-systemd-envfile-ignores-export.md +41 -0
- package/docs/lessons/0020-persist-state-incrementally.md +44 -0
- package/docs/lessons/0021-dual-axis-testing.md +48 -0
- package/docs/lessons/0022-jsx-factory-shadowing.md +43 -0
- package/docs/lessons/0023-static-analysis-spiral.md +51 -0
- package/docs/lessons/0024-shared-pipeline-implementation.md +55 -0
- package/docs/lessons/0025-defense-in-depth-all-entry-points.md +65 -0
- package/docs/lessons/0026-linter-no-rules-false-enforcement.md +54 -0
- package/docs/lessons/0027-jsx-silent-prop-drop.md +64 -0
- package/docs/lessons/0028-no-infrastructure-in-client-code.md +49 -0
- package/docs/lessons/0029-never-write-secrets-to-files.md +61 -0
- package/docs/lessons/0030-cache-merge-not-replace.md +62 -0
- package/docs/lessons/0031-verify-units-at-boundaries.md +66 -0
- package/docs/lessons/0032-module-lifecycle-subscribe-unsubscribe.md +89 -0
- package/docs/lessons/0033-async-iteration-mutable-snapshot.md +72 -0
- package/docs/lessons/0034-caller-missing-await-silent-discard.md +65 -0
- package/docs/lessons/0035-duplicate-registration-silent-overwrite.md +85 -0
- package/docs/lessons/0036-websocket-dirty-disconnect.md +33 -0
- package/docs/lessons/0037-parallel-agents-worktree-corruption.md +31 -0
- package/docs/lessons/0038-subscribe-no-stored-ref.md +36 -0
- package/docs/lessons/0039-fallback-or-default-hides-bugs.md +34 -0
- package/docs/lessons/0040-event-firehose-filter-first.md +36 -0
- package/docs/lessons/0041-ambiguous-base-dir-path-nesting.md +32 -0
- package/docs/lessons/0042-spec-compliance-insufficient.md +36 -0
- package/docs/lessons/0043-exact-count-extensible-collections.md +32 -0
- package/docs/lessons/0044-relative-file-deps-worktree.md +39 -0
- package/docs/lessons/0045-iterative-design-improvement.md +33 -0
- package/docs/lessons/0046-plan-assertion-math-bugs.md +38 -0
- package/docs/lessons/0047-pytest-single-threaded-default.md +37 -0
- package/docs/lessons/0048-integration-wiring-batch.md +40 -0
- package/docs/lessons/0049-ab-verification.md +41 -0
- package/docs/lessons/0050-editing-sourced-files-during-execution.md +33 -0
- package/docs/lessons/0051-infrastructure-fixes-cant-self-heal.md +30 -0
- package/docs/lessons/0052-uncommitted-changes-poison-quality-gates.md +31 -0
- package/docs/lessons/0053-jq-compact-flag-inconsistency.md +31 -0
- package/docs/lessons/0054-parser-matches-inside-code-blocks.md +30 -0
- package/docs/lessons/0055-agents-compensate-for-garbled-prompts.md +31 -0
- package/docs/lessons/0056-grep-count-exit-code-on-zero.md +42 -0
- package/docs/lessons/0057-new-artifacts-break-git-clean-gates.md +42 -0
- package/docs/lessons/0058-dead-config-keys-never-consumed.md +49 -0
- package/docs/lessons/0059-contract-test-shared-structures.md +53 -0
- package/docs/lessons/0060-set-e-silent-death-in-runners.md +53 -0
- package/docs/lessons/0061-context-injection-dirty-state.md +50 -0
- package/docs/lessons/0062-sibling-bug-neighborhood-scan.md +29 -0
- package/docs/lessons/0063-one-flag-two-lifetimes.md +31 -0
- package/docs/lessons/0064-test-passes-wrong-reason.md +31 -0
- package/docs/lessons/0065-pipefail-grep-count-double-output.md +39 -0
- package/docs/lessons/0066-local-keyword-outside-function.md +37 -0
- package/docs/lessons/0067-stdin-hang-non-interactive-shell.md +36 -0
- package/docs/lessons/0068-agent-builds-wrong-thing-correctly.md +31 -0
- package/docs/lessons/0069-plan-quality-dominates-execution.md +30 -0
- package/docs/lessons/0070-spec-echo-back-prevents-drift.md +31 -0
- package/docs/lessons/0071-positive-instructions-outperform-negative.md +30 -0
- package/docs/lessons/0072-lost-in-the-middle-context-placement.md +30 -0
- package/docs/lessons/0073-unscoped-lessons-cause-false-positives.md +30 -0
- package/docs/lessons/0074-stale-context-injection-wrong-batch.md +32 -0
- package/docs/lessons/0075-research-artifacts-must-persist.md +32 -0
- package/docs/lessons/0076-wrong-decomposition-contaminates-downstream.md +30 -0
- package/docs/lessons/0077-cherry-pick-merges-need-manual-resolution.md +30 -0
- package/docs/lessons/0078-static-review-without-live-test.md +30 -0
- package/docs/lessons/0079-integration-wiring-batch-required.md +32 -0
- package/docs/lessons/FRAMEWORK.md +161 -0
- package/docs/lessons/SUMMARY.md +201 -0
- package/docs/lessons/TEMPLATE.md +85 -0
- package/docs/plans/2026-02-21-code-factory-v2-design.md +204 -0
- package/docs/plans/2026-02-21-code-factory-v2-implementation-plan.md +2189 -0
- package/docs/plans/2026-02-21-code-factory-v2-phase4-design.md +537 -0
- package/docs/plans/2026-02-21-code-factory-v2-phase4-implementation-plan.md +2012 -0
- package/docs/plans/2026-02-21-hardening-pass-design.md +108 -0
- package/docs/plans/2026-02-21-hardening-pass-plan.md +1378 -0
- package/docs/plans/2026-02-21-mab-research-report.md +406 -0
- package/docs/plans/2026-02-21-marketplace-restructure-design.md +240 -0
- package/docs/plans/2026-02-21-marketplace-restructure-plan.md +832 -0
- package/docs/plans/2026-02-21-phase4-completion-plan.md +697 -0
- package/docs/plans/2026-02-21-validator-suite-design.md +148 -0
- package/docs/plans/2026-02-21-validator-suite-plan.md +540 -0
- package/docs/plans/2026-02-22-mab-research-round2.md +556 -0
- package/docs/plans/2026-02-22-mab-run-design.md +462 -0
- package/docs/plans/2026-02-22-mab-run-plan.md +2046 -0
- package/docs/plans/2026-02-22-operations-design-methodology-research.md +681 -0
- package/docs/plans/2026-02-22-research-agent-failure-taxonomy.md +532 -0
- package/docs/plans/2026-02-22-research-code-guideline-policies.md +886 -0
- package/docs/plans/2026-02-22-research-codebase-audit-refactoring.md +908 -0
- package/docs/plans/2026-02-22-research-coding-standards-documentation.md +541 -0
- package/docs/plans/2026-02-22-research-competitive-landscape.md +687 -0
- package/docs/plans/2026-02-22-research-comprehensive-testing.md +1076 -0
- package/docs/plans/2026-02-22-research-context-utilization.md +459 -0
- package/docs/plans/2026-02-22-research-cost-quality-tradeoff.md +548 -0
- package/docs/plans/2026-02-22-research-lesson-transferability.md +508 -0
- package/docs/plans/2026-02-22-research-multi-agent-coordination.md +312 -0
- package/docs/plans/2026-02-22-research-phase-integration.md +602 -0
- package/docs/plans/2026-02-22-research-plan-quality.md +428 -0
- package/docs/plans/2026-02-22-research-prompt-engineering.md +558 -0
- package/docs/plans/2026-02-22-research-unconventional-perspectives.md +528 -0
- package/docs/plans/2026-02-22-research-user-adoption.md +638 -0
- package/docs/plans/2026-02-22-research-verification-effectiveness.md +433 -0
- package/docs/plans/2026-02-23-agent-suite-design.md +299 -0
- package/docs/plans/2026-02-23-agent-suite-plan.md +578 -0
- package/docs/plans/2026-02-23-phase3-cost-infrastructure-design.md +148 -0
- package/docs/plans/2026-02-23-phase3-cost-infrastructure-plan.md +1062 -0
- package/docs/plans/2026-02-23-research-bash-expert-agent.md +543 -0
- package/docs/plans/2026-02-23-research-dependency-auditor-agent.md +564 -0
- package/docs/plans/2026-02-23-research-improving-existing-agents.md +503 -0
- package/docs/plans/2026-02-23-research-integration-tester-agent.md +454 -0
- package/docs/plans/2026-02-23-research-python-expert-agent.md +429 -0
- package/docs/plans/2026-02-23-research-service-monitor-agent.md +425 -0
- package/docs/plans/2026-02-23-research-shell-expert-agent.md +533 -0
- package/docs/plans/2026-02-23-roadmap-to-completion.md +530 -0
- package/docs/plans/2026-02-24-headless-module-split-design.md +98 -0
- package/docs/plans/2026-02-24-headless-module-split.md +443 -0
- package/docs/plans/2026-02-24-lesson-scope-metadata-design.md +228 -0
- package/docs/plans/2026-02-24-lesson-scope-metadata-plan.md +968 -0
- package/docs/plans/2026-02-24-npm-packaging-design.md +841 -0
- package/docs/plans/2026-02-24-npm-packaging-plan.md +1965 -0
- package/docs/plans/audit-findings.md +186 -0
- package/docs/telegram-notification-format.md +98 -0
- package/examples/example-plan.md +51 -0
- package/examples/example-prd.json +72 -0
- package/examples/example-roadmap.md +33 -0
- package/examples/quickstart-plan.md +63 -0
- package/hooks/hooks.json +26 -0
- package/hooks/setup-symlinks.sh +48 -0
- package/hooks/stop-hook.sh +135 -0
- package/package.json +47 -0
- package/policies/bash.md +71 -0
- package/policies/python.md +71 -0
- package/policies/testing.md +61 -0
- package/policies/universal.md +60 -0
- package/scripts/analyze-report.sh +97 -0
- package/scripts/architecture-map.sh +145 -0
- package/scripts/auto-compound.sh +273 -0
- package/scripts/batch-audit.sh +42 -0
- package/scripts/batch-test.sh +101 -0
- package/scripts/entropy-audit.sh +221 -0
- package/scripts/failure-digest.sh +51 -0
- package/scripts/generate-ast-rules.sh +96 -0
- package/scripts/init.sh +112 -0
- package/scripts/lesson-check.sh +428 -0
- package/scripts/lib/common.sh +61 -0
- package/scripts/lib/cost-tracking.sh +153 -0
- package/scripts/lib/ollama.sh +60 -0
- package/scripts/lib/progress-writer.sh +128 -0
- package/scripts/lib/run-plan-context.sh +215 -0
- package/scripts/lib/run-plan-echo-back.sh +231 -0
- package/scripts/lib/run-plan-headless.sh +396 -0
- package/scripts/lib/run-plan-notify.sh +57 -0
- package/scripts/lib/run-plan-parser.sh +81 -0
- package/scripts/lib/run-plan-prompt.sh +215 -0
- package/scripts/lib/run-plan-quality-gate.sh +132 -0
- package/scripts/lib/run-plan-routing.sh +315 -0
- package/scripts/lib/run-plan-sampling.sh +170 -0
- package/scripts/lib/run-plan-scoring.sh +146 -0
- package/scripts/lib/run-plan-state.sh +142 -0
- package/scripts/lib/run-plan-team.sh +199 -0
- package/scripts/lib/telegram.sh +54 -0
- package/scripts/lib/thompson-sampling.sh +176 -0
- package/scripts/license-check.sh +74 -0
- package/scripts/mab-run.sh +575 -0
- package/scripts/module-size-check.sh +146 -0
- package/scripts/patterns/async-no-await.yml +5 -0
- package/scripts/patterns/bare-except.yml +6 -0
- package/scripts/patterns/empty-catch.yml +6 -0
- package/scripts/patterns/hardcoded-localhost.yml +9 -0
- package/scripts/patterns/retry-loop-no-backoff.yml +12 -0
- package/scripts/pipeline-status.sh +197 -0
- package/scripts/policy-check.sh +226 -0
- package/scripts/prior-art-search.sh +133 -0
- package/scripts/promote-mab-lessons.sh +126 -0
- package/scripts/prompts/agent-a-superpowers.md +29 -0
- package/scripts/prompts/agent-b-ralph.md +29 -0
- package/scripts/prompts/judge-agent.md +61 -0
- package/scripts/prompts/planner-agent.md +44 -0
- package/scripts/pull-community-lessons.sh +90 -0
- package/scripts/quality-gate.sh +266 -0
- package/scripts/research-gate.sh +90 -0
- package/scripts/run-plan.sh +329 -0
- package/scripts/scope-infer.sh +159 -0
- package/scripts/setup-ralph-loop.sh +155 -0
- package/scripts/telemetry.sh +230 -0
- package/scripts/tests/run-all-tests.sh +52 -0
- package/scripts/tests/test-act-cli.sh +46 -0
- package/scripts/tests/test-agents-md.sh +87 -0
- package/scripts/tests/test-analyze-report.sh +114 -0
- package/scripts/tests/test-architecture-map.sh +89 -0
- package/scripts/tests/test-auto-compound.sh +169 -0
- package/scripts/tests/test-batch-test.sh +65 -0
- package/scripts/tests/test-benchmark-runner.sh +25 -0
- package/scripts/tests/test-common.sh +168 -0
- package/scripts/tests/test-cost-tracking.sh +158 -0
- package/scripts/tests/test-echo-back.sh +180 -0
- package/scripts/tests/test-entropy-audit.sh +146 -0
- package/scripts/tests/test-failure-digest.sh +66 -0
- package/scripts/tests/test-generate-ast-rules.sh +145 -0
- package/scripts/tests/test-helpers.sh +82 -0
- package/scripts/tests/test-init.sh +47 -0
- package/scripts/tests/test-lesson-check.sh +278 -0
- package/scripts/tests/test-lesson-local.sh +55 -0
- package/scripts/tests/test-license-check.sh +109 -0
- package/scripts/tests/test-mab-run.sh +182 -0
- package/scripts/tests/test-ollama-lib.sh +49 -0
- package/scripts/tests/test-ollama.sh +60 -0
- package/scripts/tests/test-pipeline-status.sh +198 -0
- package/scripts/tests/test-policy-check.sh +124 -0
- package/scripts/tests/test-prior-art-search.sh +96 -0
- package/scripts/tests/test-progress-writer.sh +140 -0
- package/scripts/tests/test-promote-mab-lessons.sh +110 -0
- package/scripts/tests/test-pull-community-lessons.sh +149 -0
- package/scripts/tests/test-quality-gate.sh +241 -0
- package/scripts/tests/test-research-gate.sh +132 -0
- package/scripts/tests/test-run-plan-cli.sh +86 -0
- package/scripts/tests/test-run-plan-context.sh +305 -0
- package/scripts/tests/test-run-plan-e2e.sh +153 -0
- package/scripts/tests/test-run-plan-headless.sh +424 -0
- package/scripts/tests/test-run-plan-notify.sh +124 -0
- package/scripts/tests/test-run-plan-parser.sh +217 -0
- package/scripts/tests/test-run-plan-prompt.sh +254 -0
- package/scripts/tests/test-run-plan-quality-gate.sh +222 -0
- package/scripts/tests/test-run-plan-routing.sh +178 -0
- package/scripts/tests/test-run-plan-scoring.sh +148 -0
- package/scripts/tests/test-run-plan-state.sh +261 -0
- package/scripts/tests/test-run-plan-team.sh +157 -0
- package/scripts/tests/test-scope-infer.sh +150 -0
- package/scripts/tests/test-setup-ralph-loop.sh +63 -0
- package/scripts/tests/test-telegram-env.sh +38 -0
- package/scripts/tests/test-telegram.sh +121 -0
- package/scripts/tests/test-telemetry.sh +46 -0
- package/scripts/tests/test-thompson-sampling.sh +139 -0
- package/scripts/tests/test-validate-all.sh +60 -0
- package/scripts/tests/test-validate-commands.sh +89 -0
- package/scripts/tests/test-validate-hooks.sh +98 -0
- package/scripts/tests/test-validate-lessons.sh +150 -0
- package/scripts/tests/test-validate-plan-quality.sh +235 -0
- package/scripts/tests/test-validate-plans.sh +187 -0
- package/scripts/tests/test-validate-plugin.sh +106 -0
- package/scripts/tests/test-validate-prd.sh +184 -0
- package/scripts/tests/test-validate-skills.sh +134 -0
- package/scripts/validate-all.sh +57 -0
- package/scripts/validate-commands.sh +67 -0
- package/scripts/validate-hooks.sh +89 -0
- package/scripts/validate-lessons.sh +98 -0
- package/scripts/validate-plan-quality.sh +369 -0
- package/scripts/validate-plans.sh +120 -0
- package/scripts/validate-plugin.sh +86 -0
- package/scripts/validate-policies.sh +42 -0
- package/scripts/validate-prd.sh +118 -0
- package/scripts/validate-skills.sh +96 -0
- package/skills/autocode/SKILL.md +285 -0
- package/skills/autocode/ab-verification.md +51 -0
- package/skills/autocode/code-quality-standards.md +37 -0
- package/skills/autocode/competitive-mode.md +364 -0
- package/skills/brainstorming/SKILL.md +97 -0
- package/skills/capture-lesson/SKILL.md +187 -0
- package/skills/check-lessons/SKILL.md +116 -0
- package/skills/dispatching-parallel-agents/SKILL.md +110 -0
- package/skills/executing-plans/SKILL.md +85 -0
- package/skills/finishing-a-development-branch/SKILL.md +201 -0
- package/skills/receiving-code-review/SKILL.md +72 -0
- package/skills/requesting-code-review/SKILL.md +59 -0
- package/skills/requesting-code-review/code-reviewer.md +82 -0
- package/skills/research/SKILL.md +145 -0
- package/skills/roadmap/SKILL.md +115 -0
- package/skills/subagent-driven-development/SKILL.md +98 -0
- package/skills/subagent-driven-development/code-quality-reviewer-prompt.md +18 -0
- package/skills/subagent-driven-development/implementer-prompt.md +73 -0
- package/skills/subagent-driven-development/spec-reviewer-prompt.md +57 -0
- package/skills/systematic-debugging/SKILL.md +134 -0
- package/skills/systematic-debugging/condition-based-waiting.md +64 -0
- package/skills/systematic-debugging/defense-in-depth.md +32 -0
- package/skills/systematic-debugging/root-cause-tracing.md +55 -0
- package/skills/test-driven-development/SKILL.md +167 -0
- package/skills/using-git-worktrees/SKILL.md +219 -0
- package/skills/using-superpowers/SKILL.md +54 -0
- package/skills/verification-before-completion/SKILL.md +140 -0
- package/skills/verify/SKILL.md +82 -0
- package/skills/writing-plans/SKILL.md +128 -0
- 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
|
+
}
|
package/policies/bash.md
ADDED
|
@@ -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
|