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,273 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# auto-compound.sh — Automated Code Factory pipeline
|
|
3
|
+
#
|
|
4
|
+
# Usage: auto-compound.sh <project-dir> [--report <file>] [--dry-run] [--max-iterations N]
|
|
5
|
+
#
|
|
6
|
+
# Pipeline:
|
|
7
|
+
# 1. Analyze report → pick #1 priority (analyze-report.sh)
|
|
8
|
+
# 2. Generate PRD → create prd.json with acceptance criteria (claude /create-prd)
|
|
9
|
+
# 3. Create branch → compound/<feature-slug>
|
|
10
|
+
# 4. Run Ralph loop → iterate until all tasks pass
|
|
11
|
+
# 5. Push branch → open PR for review
|
|
12
|
+
#
|
|
13
|
+
# Requires: claude CLI, jq, gh, ollama
|
|
14
|
+
|
|
15
|
+
set -euo pipefail
|
|
16
|
+
|
|
17
|
+
SCRIPT_DIR="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)"
|
|
18
|
+
source "$SCRIPT_DIR/lib/common.sh"
|
|
19
|
+
source "$SCRIPT_DIR/lib/ollama.sh"
|
|
20
|
+
PROJECT_DIR="${1:-}"
|
|
21
|
+
REPORT_FILE=""
|
|
22
|
+
DRY_RUN=false
|
|
23
|
+
MAX_ITERATIONS=25
|
|
24
|
+
MODEL="deepseek-r1:8b"
|
|
25
|
+
|
|
26
|
+
# Parse args
|
|
27
|
+
shift || true
|
|
28
|
+
while [[ $# -gt 0 ]]; do
|
|
29
|
+
case $1 in
|
|
30
|
+
--report) REPORT_FILE="$2"; shift 2 ;;
|
|
31
|
+
--dry-run) DRY_RUN=true; shift ;;
|
|
32
|
+
--max-iterations) MAX_ITERATIONS="$2"; shift 2 ;;
|
|
33
|
+
--model) MODEL="$2"; shift 2 ;;
|
|
34
|
+
-h|--help)
|
|
35
|
+
cat <<'EOF'
|
|
36
|
+
auto-compound.sh — Automated Code Factory pipeline
|
|
37
|
+
|
|
38
|
+
USAGE:
|
|
39
|
+
auto-compound.sh <project-dir> [OPTIONS]
|
|
40
|
+
|
|
41
|
+
OPTIONS:
|
|
42
|
+
--report <file> Path to report file (default: latest in reports/)
|
|
43
|
+
--dry-run Show what would happen without executing
|
|
44
|
+
--max-iterations <n> Max Ralph loop iterations (default: 25)
|
|
45
|
+
--model <name> Ollama model for analysis (default: deepseek-r1:8b)
|
|
46
|
+
|
|
47
|
+
PIPELINE:
|
|
48
|
+
1. Analyze report → pick #1 priority
|
|
49
|
+
2. Generate PRD with machine-verifiable acceptance criteria
|
|
50
|
+
3. Create feature branch (compound/<slug>)
|
|
51
|
+
4. Run Ralph loop with quality gates
|
|
52
|
+
5. Push and open PR for review
|
|
53
|
+
|
|
54
|
+
REPORT FORMAT:
|
|
55
|
+
Any markdown file in reports/ with issues, metrics, feedback.
|
|
56
|
+
See scripts/analyze-report.sh for details.
|
|
57
|
+
EOF
|
|
58
|
+
exit 0
|
|
59
|
+
;;
|
|
60
|
+
*) echo "Unknown option: $1" >&2; exit 1 ;;
|
|
61
|
+
esac
|
|
62
|
+
done
|
|
63
|
+
|
|
64
|
+
if [[ -z "$PROJECT_DIR" ]] || [[ ! -d "$PROJECT_DIR" ]]; then
|
|
65
|
+
echo "Error: Project directory required" >&2
|
|
66
|
+
echo "Usage: auto-compound.sh <project-dir> [--report <file>]" >&2
|
|
67
|
+
exit 1
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
cd "$PROJECT_DIR"
|
|
71
|
+
|
|
72
|
+
# Find report file
|
|
73
|
+
if [[ -z "$REPORT_FILE" ]]; then
|
|
74
|
+
if [[ -d "reports" ]]; then
|
|
75
|
+
REPORT_FILE=$(find reports/ -name '*.md' -printf '%T@ %p\n' 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-)
|
|
76
|
+
fi
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
if [[ -z "$REPORT_FILE" ]] || [[ ! -f "$REPORT_FILE" ]]; then
|
|
80
|
+
echo "Error: No report file found" >&2
|
|
81
|
+
echo "Provide --report <file> or place reports in reports/*.md" >&2
|
|
82
|
+
exit 1
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
echo "═══════════════════════════════════════════════"
|
|
86
|
+
echo " Code Factory Pipeline"
|
|
87
|
+
echo "═══════════════════════════════════════════════"
|
|
88
|
+
echo "Project: $PROJECT_DIR"
|
|
89
|
+
echo "Report: $REPORT_FILE"
|
|
90
|
+
echo "Model: $MODEL"
|
|
91
|
+
echo "Max iters: $MAX_ITERATIONS"
|
|
92
|
+
echo "═══════════════════════════════════════════════"
|
|
93
|
+
echo ""
|
|
94
|
+
|
|
95
|
+
# Step 1: Analyze report
|
|
96
|
+
echo "📊 Step 1: Analyzing report..."
|
|
97
|
+
if [[ "$DRY_RUN" == "true" ]]; then
|
|
98
|
+
echo " [dry-run] Would analyze $REPORT_FILE with $MODEL"
|
|
99
|
+
PRIORITY="example-feature"
|
|
100
|
+
FEATURE_SLUG="example-feature"
|
|
101
|
+
else
|
|
102
|
+
"$SCRIPT_DIR/analyze-report.sh" "$REPORT_FILE" --model "$MODEL" --output-dir .
|
|
103
|
+
PRIORITY=$(jq -r '.priority' analysis.json)
|
|
104
|
+
# Create slug from priority
|
|
105
|
+
FEATURE_SLUG=$(echo "$PRIORITY" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | cut -c1-40)
|
|
106
|
+
fi
|
|
107
|
+
echo " Priority: $PRIORITY"
|
|
108
|
+
echo " Branch: compound/$FEATURE_SLUG"
|
|
109
|
+
echo ""
|
|
110
|
+
|
|
111
|
+
# Step 2: Create branch
|
|
112
|
+
echo "🌿 Step 2: Creating branch..."
|
|
113
|
+
BRANCH_NAME="compound/$FEATURE_SLUG"
|
|
114
|
+
if [[ "$DRY_RUN" == "true" ]]; then
|
|
115
|
+
echo " [dry-run] Would create branch: $BRANCH_NAME"
|
|
116
|
+
else
|
|
117
|
+
git checkout -b "$BRANCH_NAME" 2>/dev/null || git checkout "$BRANCH_NAME"
|
|
118
|
+
fi
|
|
119
|
+
echo ""
|
|
120
|
+
|
|
121
|
+
# Step 2.5: Research phase
|
|
122
|
+
echo "🔎 Step 2.5: Running research phase..."
|
|
123
|
+
if [[ "$DRY_RUN" == "true" ]]; then
|
|
124
|
+
echo " [dry-run] Would research: $PRIORITY"
|
|
125
|
+
else
|
|
126
|
+
mkdir -p tasks
|
|
127
|
+
RESEARCH_SLUG=$(echo "$FEATURE_SLUG" | cut -c1-30)
|
|
128
|
+
RESEARCH_JSON="tasks/research-${RESEARCH_SLUG}.json"
|
|
129
|
+
|
|
130
|
+
# Run research via Claude (produces tasks/research-*.md and tasks/research-*.json)
|
|
131
|
+
research_output=$(claude --print "Use the research skill to investigate: $PRIORITY. Design context: $(cat analysis.json). Write findings to tasks/research-${RESEARCH_SLUG}.md and tasks/research-${RESEARCH_SLUG}.json" 2>&1) || {
|
|
132
|
+
echo "WARNING: Research phase failed (non-fatal):" >&2
|
|
133
|
+
echo "$research_output" | tail -10 >&2
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
# Check research gate
|
|
137
|
+
if [[ -f "$RESEARCH_JSON" ]]; then
|
|
138
|
+
"$SCRIPT_DIR/research-gate.sh" "$RESEARCH_JSON" || {
|
|
139
|
+
echo "BLOCKED: Unresolved research issues. Resolve or re-run with --force on research-gate.sh" >&2
|
|
140
|
+
exit 1
|
|
141
|
+
}
|
|
142
|
+
echo " Research gate: clear"
|
|
143
|
+
else
|
|
144
|
+
echo " No research JSON produced (continuing without research context)"
|
|
145
|
+
fi
|
|
146
|
+
|
|
147
|
+
# Append to progress.txt
|
|
148
|
+
echo "## Research: $PRIORITY" >> progress.txt
|
|
149
|
+
if [[ -f "$RESEARCH_JSON" ]]; then
|
|
150
|
+
jq -r '.recommended_approach // "No approach documented"' "$RESEARCH_JSON" >> progress.txt
|
|
151
|
+
fi
|
|
152
|
+
echo "" >> progress.txt
|
|
153
|
+
fi
|
|
154
|
+
echo ""
|
|
155
|
+
|
|
156
|
+
# Step 3: Generate PRD
|
|
157
|
+
echo "📋 Step 3: Generating PRD..."
|
|
158
|
+
if [[ "$DRY_RUN" == "true" ]]; then
|
|
159
|
+
echo " [dry-run] Would run: claude '/create-prd $PRIORITY'"
|
|
160
|
+
echo " [dry-run] Would create tasks/prd.json"
|
|
161
|
+
else
|
|
162
|
+
mkdir -p tasks
|
|
163
|
+
# Include research context if available
|
|
164
|
+
research_context=""
|
|
165
|
+
RESEARCH_SLUG=$(echo "$FEATURE_SLUG" | cut -c1-30)
|
|
166
|
+
RESEARCH_JSON="tasks/research-${RESEARCH_SLUG}.json"
|
|
167
|
+
if [[ -f "$RESEARCH_JSON" ]]; then
|
|
168
|
+
research_context=" Research findings: $(jq -c '{approach: .recommended_approach, warnings: .warnings, dependencies: .dependencies}' "$RESEARCH_JSON" 2>/dev/null || echo "{}")"
|
|
169
|
+
fi
|
|
170
|
+
# Use Claude to generate the PRD
|
|
171
|
+
prd_output=$(claude --print "/create-prd $PRIORITY. Context from analysis: $(cat analysis.json).$research_context" 2>&1) || {
|
|
172
|
+
echo "WARNING: PRD generation failed:" >&2
|
|
173
|
+
echo "$prd_output" | tail -10 >&2
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if [[ ! -f "tasks/prd.json" ]]; then
|
|
177
|
+
echo "Warning: PRD generation didn't create tasks/prd.json" >&2
|
|
178
|
+
echo "You may need to run /create-prd manually" >&2
|
|
179
|
+
fi
|
|
180
|
+
fi
|
|
181
|
+
echo ""
|
|
182
|
+
|
|
183
|
+
# Step 4: Configure quality checks
|
|
184
|
+
echo "🔍 Step 4: Configuring quality checks..."
|
|
185
|
+
QUALITY_GATE="$SCRIPT_DIR/quality-gate.sh"
|
|
186
|
+
if [[ -x "$QUALITY_GATE" ]]; then
|
|
187
|
+
QUALITY_CHECKS="$QUALITY_GATE --project-root $PROJECT_DIR"
|
|
188
|
+
echo " Using composite quality gate: $QUALITY_GATE"
|
|
189
|
+
else
|
|
190
|
+
# Fallback: use detect_project_type if quality-gate.sh not available
|
|
191
|
+
project_type=$(detect_project_type "$PROJECT_DIR")
|
|
192
|
+
case "$project_type" in
|
|
193
|
+
python) QUALITY_CHECKS="pytest --timeout=120 -x -q" ;;
|
|
194
|
+
node)
|
|
195
|
+
QUALITY_CHECKS=""
|
|
196
|
+
grep -q '"test"' package.json 2>/dev/null && QUALITY_CHECKS+="npm test"
|
|
197
|
+
grep -q '"lint"' package.json 2>/dev/null && { [[ -n "$QUALITY_CHECKS" ]] && QUALITY_CHECKS+=";"; QUALITY_CHECKS+="npm run lint"; }
|
|
198
|
+
;;
|
|
199
|
+
make) QUALITY_CHECKS="make test" ;;
|
|
200
|
+
*) QUALITY_CHECKS="" ;;
|
|
201
|
+
esac
|
|
202
|
+
echo " Fallback mode — quality-gate.sh not found"
|
|
203
|
+
fi
|
|
204
|
+
|
|
205
|
+
echo " Quality checks: ${QUALITY_CHECKS:-none detected}"
|
|
206
|
+
echo ""
|
|
207
|
+
|
|
208
|
+
# Step 5: Run Ralph loop
|
|
209
|
+
echo "🔄 Step 5: Starting Ralph loop..."
|
|
210
|
+
if [[ "$DRY_RUN" == "true" ]]; then
|
|
211
|
+
echo " [dry-run] Would run Ralph loop with:"
|
|
212
|
+
echo " --max-iterations $MAX_ITERATIONS"
|
|
213
|
+
echo " --quality-checks '$QUALITY_CHECKS'"
|
|
214
|
+
echo " --prd tasks/prd.json"
|
|
215
|
+
echo " --completion-promise 'ALL TASKS COMPLETE'"
|
|
216
|
+
else
|
|
217
|
+
RALPH_ARGS="Implement the features in tasks/prd.json. Read prd.json, pick the next task where passes is false, implement it, verify acceptance criteria pass, update prd.json, commit, and move to the next task."
|
|
218
|
+
RALPH_ARGS+=" --max-iterations $MAX_ITERATIONS"
|
|
219
|
+
RALPH_ARGS+=" --completion-promise 'ALL TASKS COMPLETE'"
|
|
220
|
+
|
|
221
|
+
if [[ -n "$QUALITY_CHECKS" ]]; then
|
|
222
|
+
RALPH_ARGS+=" --quality-checks '$QUALITY_CHECKS'"
|
|
223
|
+
fi
|
|
224
|
+
|
|
225
|
+
if [[ -f "tasks/prd.json" ]]; then
|
|
226
|
+
RALPH_ARGS+=" --prd tasks/prd.json"
|
|
227
|
+
fi
|
|
228
|
+
|
|
229
|
+
echo " Running: /ralph-loop $RALPH_ARGS"
|
|
230
|
+
echo ""
|
|
231
|
+
echo " Monitor progress:"
|
|
232
|
+
echo " head -15 .claude/ralph-loop.local.md"
|
|
233
|
+
echo " cat progress.txt"
|
|
234
|
+
echo " jq '.[].passes' tasks/prd.json"
|
|
235
|
+
echo ""
|
|
236
|
+
|
|
237
|
+
# Launch Claude with Ralph loop
|
|
238
|
+
claude "/ralph-loop $RALPH_ARGS"
|
|
239
|
+
fi
|
|
240
|
+
echo ""
|
|
241
|
+
|
|
242
|
+
# Step 6: Push and create PR
|
|
243
|
+
echo "📤 Step 6: Pushing and creating PR..."
|
|
244
|
+
if [[ "$DRY_RUN" == "true" ]]; then
|
|
245
|
+
echo " [dry-run] Would push $BRANCH_NAME and create PR"
|
|
246
|
+
else
|
|
247
|
+
if ! git push -u origin "$BRANCH_NAME" 2>&1; then
|
|
248
|
+
echo "ERROR: git push failed for branch $BRANCH_NAME" >&2
|
|
249
|
+
echo " Check: authentication, remote availability, branch protection rules" >&2
|
|
250
|
+
exit 1
|
|
251
|
+
fi
|
|
252
|
+
|
|
253
|
+
# Create PR
|
|
254
|
+
PR_BODY="## Summary
|
|
255
|
+
Auto-generated by Code Factory pipeline.
|
|
256
|
+
|
|
257
|
+
**Priority:** $PRIORITY
|
|
258
|
+
**Analysis:** See analysis.json
|
|
259
|
+
**Tasks:** See tasks/prd.json
|
|
260
|
+
|
|
261
|
+
## Quality Checks
|
|
262
|
+
$QUALITY_CHECKS
|
|
263
|
+
|
|
264
|
+
## Generated by
|
|
265
|
+
\`auto-compound.sh\` → \`analyze-report.sh\` → \`/create-prd\` → \`/ralph-loop\`"
|
|
266
|
+
|
|
267
|
+
gh pr create --title "compound: $PRIORITY" --body "$PR_BODY" 2>/dev/null || echo "PR creation skipped (may already exist)"
|
|
268
|
+
fi
|
|
269
|
+
|
|
270
|
+
echo ""
|
|
271
|
+
echo "═══════════════════════════════════════════════"
|
|
272
|
+
echo " Pipeline complete!"
|
|
273
|
+
echo "═══════════════════════════════════════════════"
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Batch audit across all project repos
|
|
3
|
+
# Usage: batch-audit.sh <projects-dir> [focus]
|
|
4
|
+
# Focus: stale-refs | security | test-coverage | naming | lessons | full (default: stale-refs)
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
PROJECTS_DIR="${1:-}"
|
|
9
|
+
FOCUS="${2:-stale-refs}"
|
|
10
|
+
|
|
11
|
+
if [[ -z "$PROJECTS_DIR" || ! -d "$PROJECTS_DIR" ]]; then
|
|
12
|
+
echo "Usage: batch-audit.sh <projects-dir> [focus]" >&2
|
|
13
|
+
echo "Focus options: stale-refs | security | test-coverage | naming | lessons | full" >&2
|
|
14
|
+
exit 1
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
RESULTS_DIR="/tmp/batch-audit-$(date +%Y%m%d-%H%M%S)"
|
|
18
|
+
mkdir -p "$RESULTS_DIR"
|
|
19
|
+
|
|
20
|
+
echo "=== Batch Audit: $FOCUS ==="
|
|
21
|
+
echo "Results: $RESULTS_DIR"
|
|
22
|
+
echo ""
|
|
23
|
+
|
|
24
|
+
for PROJECT_DIR in "$PROJECTS_DIR"/*/; do
|
|
25
|
+
[[ ! -d "$PROJECT_DIR" ]] && continue
|
|
26
|
+
project="$(basename "$PROJECT_DIR")"
|
|
27
|
+
|
|
28
|
+
echo "--- $project ---"
|
|
29
|
+
RESULT_FILE="$RESULTS_DIR/$project.txt"
|
|
30
|
+
|
|
31
|
+
claude -p "Run /audit $FOCUS on this project. Output the audit report only, no fixes." \
|
|
32
|
+
--allowedTools "Bash,Read,Grep,Glob" \
|
|
33
|
+
--cwd "$PROJECT_DIR" \
|
|
34
|
+
--output-format text > "$RESULT_FILE" 2>&1 || true
|
|
35
|
+
|
|
36
|
+
echo " Findings saved to $RESULT_FILE"
|
|
37
|
+
echo ""
|
|
38
|
+
done
|
|
39
|
+
|
|
40
|
+
echo "=== Complete ==="
|
|
41
|
+
echo "All results in: $RESULTS_DIR"
|
|
42
|
+
echo "Quick view: cat $RESULTS_DIR/*.txt"
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Run tests across all projects with memory awareness
|
|
3
|
+
# Usage: batch-test.sh <projects-dir> [project-name]
|
|
4
|
+
#
|
|
5
|
+
# Auto-detects test runner (pytest, npm test, make test) for each project.
|
|
6
|
+
# Checks available memory before running — skips full suite if < 4GB available.
|
|
7
|
+
# Exits non-zero if any project's tests fail. Reports summary.
|
|
8
|
+
|
|
9
|
+
set -euo pipefail
|
|
10
|
+
|
|
11
|
+
PROJECTS_DIR="${1:-}"
|
|
12
|
+
TARGET="${2:-}"
|
|
13
|
+
|
|
14
|
+
if [[ -z "$PROJECTS_DIR" || ! -d "$PROJECTS_DIR" ]]; then
|
|
15
|
+
echo "Usage: batch-test.sh <projects-dir> [project-name]" >&2
|
|
16
|
+
exit 1
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
PASS_COUNT=0
|
|
20
|
+
FAIL_COUNT=0
|
|
21
|
+
SKIP_COUNT=0
|
|
22
|
+
FAILED_PROJECTS=()
|
|
23
|
+
|
|
24
|
+
check_memory() {
|
|
25
|
+
local avail_mb
|
|
26
|
+
avail_mb=$(free -m 2>/dev/null | awk '/Mem:/{print $7}') || avail_mb=0
|
|
27
|
+
if [[ -z "$avail_mb" || "$avail_mb" -lt 4000 ]]; then
|
|
28
|
+
echo "WARNING: Low memory (${avail_mb:-unknown}MB). Consider running targeted tests."
|
|
29
|
+
return 1
|
|
30
|
+
fi
|
|
31
|
+
return 0
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
run_project_tests() {
|
|
35
|
+
local project_dir="$1"
|
|
36
|
+
local project
|
|
37
|
+
project="$(basename "$project_dir")"
|
|
38
|
+
|
|
39
|
+
if [ ! -d "$project_dir" ]; then
|
|
40
|
+
echo "SKIP: $project (not found)"
|
|
41
|
+
SKIP_COUNT=$((SKIP_COUNT + 1))
|
|
42
|
+
return 0
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
echo "=== $project ==="
|
|
46
|
+
local exit_code=0
|
|
47
|
+
(
|
|
48
|
+
cd "$project_dir"
|
|
49
|
+
|
|
50
|
+
# Auto-detect test runner
|
|
51
|
+
if [[ -f pyproject.toml || -f setup.py || -f pytest.ini ]]; then
|
|
52
|
+
if check_memory; then
|
|
53
|
+
.venv/bin/python -m pytest --timeout=120 -x -q 2>&1
|
|
54
|
+
else
|
|
55
|
+
echo "Low memory — running with reduced parallelism"
|
|
56
|
+
.venv/bin/python -m pytest --timeout=120 -x -q -n 0 2>&1
|
|
57
|
+
fi
|
|
58
|
+
elif [[ -f package.json ]] && grep -q '"test"' package.json 2>/dev/null; then
|
|
59
|
+
npm test 2>&1
|
|
60
|
+
elif [[ -f Makefile ]] && grep -q '^test:' Makefile 2>/dev/null; then
|
|
61
|
+
make test 2>&1
|
|
62
|
+
else
|
|
63
|
+
echo " No test runner detected — skipped"
|
|
64
|
+
exit 2 # Signal "skipped" to caller
|
|
65
|
+
fi
|
|
66
|
+
) || exit_code=$?
|
|
67
|
+
|
|
68
|
+
if [[ $exit_code -eq 2 ]]; then
|
|
69
|
+
SKIP_COUNT=$((SKIP_COUNT + 1))
|
|
70
|
+
elif [[ $exit_code -ne 0 ]]; then
|
|
71
|
+
FAIL_COUNT=$((FAIL_COUNT + 1))
|
|
72
|
+
FAILED_PROJECTS+=("$project")
|
|
73
|
+
echo " FAILED (exit $exit_code)"
|
|
74
|
+
else
|
|
75
|
+
PASS_COUNT=$((PASS_COUNT + 1))
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
echo ""
|
|
79
|
+
return 0 # Don't abort the loop — continue to next project
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if [[ -n "$TARGET" ]]; then
|
|
83
|
+
run_project_tests "$PROJECTS_DIR/$TARGET"
|
|
84
|
+
else
|
|
85
|
+
for d in "$PROJECTS_DIR"/*/; do
|
|
86
|
+
[[ -d "$d" ]] && run_project_tests "$d"
|
|
87
|
+
done
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
echo "=== Summary ==="
|
|
91
|
+
echo " Passed: $PASS_COUNT"
|
|
92
|
+
echo " Failed: $FAIL_COUNT"
|
|
93
|
+
echo " Skipped: $SKIP_COUNT"
|
|
94
|
+
if [[ ${#FAILED_PROJECTS[@]} -gt 0 ]]; then
|
|
95
|
+
echo " Failed projects: ${FAILED_PROJECTS[*]}"
|
|
96
|
+
fi
|
|
97
|
+
echo "=== Done ==="
|
|
98
|
+
|
|
99
|
+
if [[ $FAIL_COUNT -gt 0 ]]; then
|
|
100
|
+
exit 1
|
|
101
|
+
fi
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# shellcheck disable=SC2034 # FIX_MODE parsed but reserved for future auto-fix mode
|
|
3
|
+
# entropy-audit.sh — Detect documentation drift, naming inconsistencies, and stale conventions
|
|
4
|
+
#
|
|
5
|
+
# Usage: entropy-audit.sh [--project <name>] [--all] [--fix]
|
|
6
|
+
#
|
|
7
|
+
# Checks:
|
|
8
|
+
# 1. CLAUDE.md freshness — file references that no longer exist
|
|
9
|
+
# 2. Naming drift — files/functions that violate project conventions
|
|
10
|
+
# 3. Dead code — unreferenced exports and unused imports
|
|
11
|
+
# 4. File size violations — files exceeding 300-line taste invariant
|
|
12
|
+
# 5. Doc staleness — CLAUDE.md mentions of removed features
|
|
13
|
+
#
|
|
14
|
+
# Designed to run as a systemd timer for continuous entropy management.
|
|
15
|
+
|
|
16
|
+
set -euo pipefail
|
|
17
|
+
|
|
18
|
+
SCRIPT_DIR="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)"
|
|
19
|
+
source "$SCRIPT_DIR/lib/common.sh"
|
|
20
|
+
|
|
21
|
+
PROJECTS_DIR="${PROJECTS_DIR:-$HOME/Documents/projects}"
|
|
22
|
+
ALL_PROJECTS=false
|
|
23
|
+
FIX_MODE=false # reserved for auto-fix mode
|
|
24
|
+
TARGET_PROJECT=""
|
|
25
|
+
RESULTS_DIR="/tmp/entropy-audit-$(date +%Y%m%d-%H%M%S)"
|
|
26
|
+
|
|
27
|
+
while [[ $# -gt 0 ]]; do
|
|
28
|
+
case $1 in
|
|
29
|
+
--project) TARGET_PROJECT="$2"; shift 2 ;;
|
|
30
|
+
--all) ALL_PROJECTS=true; shift ;;
|
|
31
|
+
--fix) FIX_MODE=true; shift ;;
|
|
32
|
+
--projects-dir) PROJECTS_DIR="$2"; shift 2 ;;
|
|
33
|
+
-h|--help)
|
|
34
|
+
echo "entropy-audit.sh — Detect and report codebase entropy"
|
|
35
|
+
echo ""
|
|
36
|
+
echo "Usage: entropy-audit.sh [--project <name>] [--all] [--fix]"
|
|
37
|
+
echo ""
|
|
38
|
+
echo "Options:"
|
|
39
|
+
echo " --project <name> Audit a specific project"
|
|
40
|
+
echo " --all Audit all projects"
|
|
41
|
+
echo " --fix Auto-fix simple issues (dead refs in CLAUDE.md)"
|
|
42
|
+
exit 0
|
|
43
|
+
;;
|
|
44
|
+
*) echo "Unknown: $1" >&2; exit 1 ;;
|
|
45
|
+
esac
|
|
46
|
+
done
|
|
47
|
+
|
|
48
|
+
mkdir -p "$RESULTS_DIR"
|
|
49
|
+
|
|
50
|
+
audit_project() {
|
|
51
|
+
local project_dir="$1"
|
|
52
|
+
local project_name
|
|
53
|
+
project_name="$(basename "$project_dir")"
|
|
54
|
+
local report="$RESULTS_DIR/$project_name.md"
|
|
55
|
+
|
|
56
|
+
echo "Auditing $project_name..."
|
|
57
|
+
|
|
58
|
+
{
|
|
59
|
+
echo "# Entropy Audit: $project_name"
|
|
60
|
+
echo "Date: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
61
|
+
echo ""
|
|
62
|
+
|
|
63
|
+
# Check 1: CLAUDE.md references to nonexistent files
|
|
64
|
+
echo "## 1. Dead References in CLAUDE.md"
|
|
65
|
+
local claude_md="$project_dir/CLAUDE.md"
|
|
66
|
+
local dead_count=0
|
|
67
|
+
if [[ -f "$claude_md" ]]; then
|
|
68
|
+
# Extract file paths mentioned in backticks — collect into array to avoid subshell
|
|
69
|
+
local refs
|
|
70
|
+
refs=$(grep -oE '`[^`]+\.(py|ts|js|sh|json|md|yaml|yml)`' "$claude_md" 2>/dev/null | tr -d '`' || true)
|
|
71
|
+
if [[ -n "$refs" ]]; then
|
|
72
|
+
while IFS= read -r ref; do
|
|
73
|
+
# Skip paths with placeholders
|
|
74
|
+
if echo "$ref" | grep -qE '<|>|\*|\$|~'; then continue; fi
|
|
75
|
+
# Check relative to project dir
|
|
76
|
+
if [[ ! -f "$project_dir/$ref" ]] && [[ ! -f "$ref" ]]; then
|
|
77
|
+
echo "- ❌ Referenced but missing: \`$ref\`"
|
|
78
|
+
dead_count=$((dead_count + 1))
|
|
79
|
+
fi
|
|
80
|
+
done <<< "$refs"
|
|
81
|
+
fi
|
|
82
|
+
if [[ $dead_count -eq 0 ]]; then
|
|
83
|
+
echo "- ✅ All references valid"
|
|
84
|
+
else
|
|
85
|
+
echo "- Found $dead_count dead reference(s)"
|
|
86
|
+
fi
|
|
87
|
+
else
|
|
88
|
+
echo "- ⚠️ No CLAUDE.md found"
|
|
89
|
+
fi
|
|
90
|
+
echo ""
|
|
91
|
+
|
|
92
|
+
# Check 2: File size violations (>300 lines)
|
|
93
|
+
echo "## 2. File Size Violations (>300 lines)"
|
|
94
|
+
local size_count=0
|
|
95
|
+
local code_files
|
|
96
|
+
code_files=$(find "$project_dir" \( -name '*.py' -o -name '*.ts' -o -name '*.js' -o -name '*.sh' \) \
|
|
97
|
+
-not -path '*/node_modules/*' -not -path '*/__pycache__/*' -not -path '*/.git/*' -not -path '*/.venv/*' -not -path '*/venv/*' -not -path '*/site-packages/*' -not -path '*/.tox/*' 2>/dev/null || true)
|
|
98
|
+
code_files=$(echo "$code_files" | sed '/^[[:space:]]*$/d')
|
|
99
|
+
if [[ -n "$code_files" ]]; then
|
|
100
|
+
while IFS= read -r f; do
|
|
101
|
+
[[ -z "$f" ]] && continue
|
|
102
|
+
local lines
|
|
103
|
+
lines=$(wc -l < "$f" 2>/dev/null || echo 0)
|
|
104
|
+
if [[ $lines -gt 300 ]]; then
|
|
105
|
+
echo "- ⚠️ \`$(basename "$f")\`: $lines lines"
|
|
106
|
+
size_count=$((size_count + 1))
|
|
107
|
+
fi
|
|
108
|
+
done <<< "$code_files"
|
|
109
|
+
fi
|
|
110
|
+
if [[ $size_count -eq 0 ]]; then
|
|
111
|
+
echo "- ✅ All files within limit"
|
|
112
|
+
else
|
|
113
|
+
echo "- Found $size_count file(s) over 300 lines"
|
|
114
|
+
fi
|
|
115
|
+
echo ""
|
|
116
|
+
|
|
117
|
+
# Check 3: Naming convention drift
|
|
118
|
+
echo "## 3. Naming Convention Check"
|
|
119
|
+
local naming_count=0
|
|
120
|
+
local py_files
|
|
121
|
+
py_files=$(find "$project_dir" -name '*.py' \
|
|
122
|
+
-not -path '*/node_modules/*' -not -path '*/__pycache__/*' -not -path '*/.git/*' -not -path '*/.venv/*' -not -path '*/venv/*' -not -path '*/site-packages/*' -not -path '*/.tox/*' 2>/dev/null || true)
|
|
123
|
+
py_files=$(echo "$py_files" | sed '/^[[:space:]]*$/d')
|
|
124
|
+
if [[ -n "$py_files" ]]; then
|
|
125
|
+
while IFS= read -r f; do
|
|
126
|
+
[[ -z "$f" ]] && continue
|
|
127
|
+
local camel_funcs
|
|
128
|
+
camel_funcs=$(grep -nE '^def [a-z]+[A-Z]' "$f" 2>/dev/null || true)
|
|
129
|
+
if [[ -n "$camel_funcs" ]]; then
|
|
130
|
+
echo "- ⚠️ \`$(basename "$f")\`: camelCase functions found (should be snake_case)"
|
|
131
|
+
naming_count=$((naming_count + 1))
|
|
132
|
+
fi
|
|
133
|
+
done <<< "$py_files"
|
|
134
|
+
fi
|
|
135
|
+
if [[ $naming_count -eq 0 ]]; then
|
|
136
|
+
echo "- ✅ No naming drift detected"
|
|
137
|
+
fi
|
|
138
|
+
echo ""
|
|
139
|
+
|
|
140
|
+
# Check 4: Unused imports (Python only, basic check — first 20 files)
|
|
141
|
+
echo "## 4. Import Hygiene"
|
|
142
|
+
local import_count=0
|
|
143
|
+
local py_sample
|
|
144
|
+
py_sample=$(find "$project_dir" -name '*.py' -not -path '*__pycache__*' -not -path '*.git*' 2>/dev/null | head -20 || true)
|
|
145
|
+
py_sample=$(echo "$py_sample" | sed '/^[[:space:]]*$/d')
|
|
146
|
+
if [[ -n "$py_sample" ]]; then
|
|
147
|
+
while IFS= read -r f; do
|
|
148
|
+
[[ -z "$f" ]] && continue
|
|
149
|
+
local imports
|
|
150
|
+
imports=$(grep -E '^(from .+ import .+|import .+)' "$f" 2>/dev/null || true)
|
|
151
|
+
if [[ -n "$imports" ]]; then
|
|
152
|
+
while IFS= read -r imp; do
|
|
153
|
+
local name
|
|
154
|
+
name=$(echo "$imp" | grep -oE 'import (\w+)' | tail -1 | awk '{print $2}' || true)
|
|
155
|
+
if [[ -n "$name" ]]; then
|
|
156
|
+
local count
|
|
157
|
+
count=$(grep -c "$name" "$f" 2>/dev/null || echo 0)
|
|
158
|
+
if [[ $count -le 1 ]]; then
|
|
159
|
+
echo "- ⚠️ \`$(basename "$f")\`: possibly unused import: \`$name\`"
|
|
160
|
+
import_count=$((import_count + 1))
|
|
161
|
+
fi
|
|
162
|
+
fi
|
|
163
|
+
done <<< "$imports"
|
|
164
|
+
fi
|
|
165
|
+
done <<< "$py_sample"
|
|
166
|
+
fi
|
|
167
|
+
if [[ $import_count -eq 0 ]]; then
|
|
168
|
+
echo "- ✅ No obvious unused imports"
|
|
169
|
+
fi
|
|
170
|
+
echo ""
|
|
171
|
+
|
|
172
|
+
# Check 5: Git status (uncommitted work)
|
|
173
|
+
echo "## 5. Uncommitted Work"
|
|
174
|
+
if [[ -d "$project_dir/.git" ]]; then
|
|
175
|
+
local untracked
|
|
176
|
+
untracked=$(cd "$project_dir" && git status --porcelain 2>/dev/null | wc -l || echo 0)
|
|
177
|
+
if [[ $untracked -gt 0 ]]; then
|
|
178
|
+
echo "- ⚠️ $untracked uncommitted files"
|
|
179
|
+
else
|
|
180
|
+
echo "- ✅ Working tree clean"
|
|
181
|
+
fi
|
|
182
|
+
fi
|
|
183
|
+
echo ""
|
|
184
|
+
|
|
185
|
+
} > "$report"
|
|
186
|
+
|
|
187
|
+
echo " Report: $report"
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
# Determine which projects to audit
|
|
191
|
+
if [[ -n "$TARGET_PROJECT" ]]; then
|
|
192
|
+
audit_project "$PROJECTS_DIR/$TARGET_PROJECT"
|
|
193
|
+
elif [[ "$ALL_PROJECTS" == "true" ]]; then
|
|
194
|
+
for d in "$PROJECTS_DIR"/*/; do
|
|
195
|
+
[[ -d "$d" ]] && audit_project "$d"
|
|
196
|
+
done
|
|
197
|
+
# Also audit workspace-level CLAUDE.md
|
|
198
|
+
echo ""
|
|
199
|
+
echo "Workspace CLAUDE.md audit:"
|
|
200
|
+
if [[ -f "$HOME/Documents/CLAUDE.md" ]]; then
|
|
201
|
+
local_refs=$(grep -oE '`[^`]+\.(py|ts|js|sh|json|md|yaml|yml)`' "$HOME/Documents/CLAUDE.md" 2>/dev/null | tr -d '`' || true)
|
|
202
|
+
if [[ -n "$local_refs" ]]; then
|
|
203
|
+
while IFS= read -r ref; do
|
|
204
|
+
if echo "$ref" | grep -qE '<|>|\*|\$|~'; then continue; fi
|
|
205
|
+
if [[ ! -f "$HOME/Documents/$ref" ]] && [[ ! -f "$ref" ]]; then
|
|
206
|
+
echo " ❌ Dead ref: $ref"
|
|
207
|
+
fi
|
|
208
|
+
done <<< "$local_refs"
|
|
209
|
+
fi
|
|
210
|
+
fi
|
|
211
|
+
else
|
|
212
|
+
echo "Usage: entropy-audit.sh --project <name> | --all" >&2
|
|
213
|
+
echo "Projects available:" >&2
|
|
214
|
+
ls "$PROJECTS_DIR" 2>/dev/null | while read -r p; do echo " $p"; done >&2
|
|
215
|
+
exit 1
|
|
216
|
+
fi
|
|
217
|
+
|
|
218
|
+
echo ""
|
|
219
|
+
echo "═══════════════════════════════════════════════"
|
|
220
|
+
echo "Results: $RESULTS_DIR/"
|
|
221
|
+
echo "═══════════════════════════════════════════════"
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# failure-digest.sh — Parse failed batch logs into structured failure digest
|
|
3
|
+
#
|
|
4
|
+
# Usage: failure-digest.sh <log-file>
|
|
5
|
+
#
|
|
6
|
+
# Extracts:
|
|
7
|
+
# - Failed test names (FAILED pattern)
|
|
8
|
+
# - Error types and messages (Traceback, Error:, Exception:)
|
|
9
|
+
# - Test summary line (N failed, M passed)
|
|
10
|
+
#
|
|
11
|
+
# Output: Structured text digest suitable for retry prompts
|
|
12
|
+
set -euo pipefail
|
|
13
|
+
|
|
14
|
+
LOG_FILE="${1:-}"
|
|
15
|
+
|
|
16
|
+
if [[ "$LOG_FILE" == "--help" || "$LOG_FILE" == "-h" ]]; then
|
|
17
|
+
echo "failure-digest.sh — Parse batch log into structured failure digest"
|
|
18
|
+
echo "Usage: failure-digest.sh <log-file>"
|
|
19
|
+
exit 0
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
if [[ -z "$LOG_FILE" || ! -f "$LOG_FILE" ]]; then
|
|
23
|
+
echo "Error: Log file required" >&2
|
|
24
|
+
exit 1
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
echo "=== Failure Digest ==="
|
|
28
|
+
echo "Log: $(basename "$LOG_FILE")"
|
|
29
|
+
echo ""
|
|
30
|
+
|
|
31
|
+
# Extract failed test names
|
|
32
|
+
echo "--- Failed Tests ---"
|
|
33
|
+
grep -E '^FAILED ' "$LOG_FILE" 2>/dev/null | sed 's/^FAILED / /' || echo " (none found)"
|
|
34
|
+
echo ""
|
|
35
|
+
|
|
36
|
+
# Extract error types and messages
|
|
37
|
+
echo "--- Errors ---"
|
|
38
|
+
grep -E '(Error|Exception|FAIL):' "$LOG_FILE" 2>/dev/null | grep -v '^FAILED ' | head -20 | sed 's/^/ /' || echo " (none found)"
|
|
39
|
+
echo ""
|
|
40
|
+
|
|
41
|
+
# Extract tracebacks (last frame + error line)
|
|
42
|
+
echo "--- Stack Traces (last frame) ---"
|
|
43
|
+
grep -B1 -E '^\w+Error:|^\w+Exception:' "$LOG_FILE" 2>/dev/null | head -20 | sed 's/^/ /' || echo " (none found)"
|
|
44
|
+
echo ""
|
|
45
|
+
|
|
46
|
+
# Extract test summary
|
|
47
|
+
echo "--- Summary ---"
|
|
48
|
+
grep -E '[0-9]+ (failed|passed|error)' "$LOG_FILE" 2>/dev/null | tail -1 | sed 's/^/ /' || echo " (no summary found)"
|
|
49
|
+
echo ""
|
|
50
|
+
|
|
51
|
+
echo "=== End Digest ==="
|