@tyroneross/build-loop 0.30.3
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/.agents/plugins/marketplace.json +10 -0
- package/.claude-plugin/marketplace.json +38 -0
- package/.claude-plugin/plugin.json +30 -0
- package/.codex-plugin/plugin.json +41 -0
- package/.cursor/rules/build-loop-surface.mdc +22 -0
- package/AGENTS.md +498 -0
- package/LICENSE +202 -0
- package/README.md +403 -0
- package/agents/alignment-checker.md +124 -0
- package/agents/api-assessor.md +136 -0
- package/agents/architecture-scout.md +185 -0
- package/agents/assessment-orchestrator.md +163 -0
- package/agents/build-orchestrator.md +198 -0
- package/agents/database-assessor.md +133 -0
- package/agents/design-contract-specialist.md +239 -0
- package/agents/fact-checker.md +69 -0
- package/agents/fix-critique.md +161 -0
- package/agents/frontend-assessor.md +136 -0
- package/agents/implementer.md +185 -0
- package/agents/independent-auditor.md +143 -0
- package/agents/mock-scanner.md +78 -0
- package/agents/optimize-runner.md +112 -0
- package/agents/overfitting-reviewer.md +96 -0
- package/agents/performance-assessor.md +159 -0
- package/agents/plan-critic.md +85 -0
- package/agents/promotion-reviewer.md +121 -0
- package/agents/recurring-pattern-detector.md +248 -0
- package/agents/retrospective-synthesizer.md +109 -0
- package/agents/root-cause-investigator.md +285 -0
- package/agents/scope-auditor.md +121 -0
- package/agents/security-reviewer.md +151 -0
- package/agents/self-improvement-architect.md +125 -0
- package/agents/synthesis-critic.md +99 -0
- package/agents/transcript-pattern-miner.md +165 -0
- package/agents/ui-validator.md +193 -0
- package/codex-skills/build-loop/SKILL.md +20 -0
- package/codex-skills/debug-loop/SKILL.md +18 -0
- package/codex-skills/handoff/SKILL.md +22 -0
- package/codex-skills/knowledge/SKILL.md +21 -0
- package/codex-skills/optimize/SKILL.md +18 -0
- package/codex-skills/research/SKILL.md +18 -0
- package/commands/agent-rally-point.md +301 -0
- package/commands/assess.md +41 -0
- package/commands/debug.md +20 -0
- package/commands/debugger-detail.md +34 -0
- package/commands/debugger-scan.md +15 -0
- package/commands/debugger-status.md +20 -0
- package/commands/debugger.md +32 -0
- package/commands/handoff.md +113 -0
- package/commands/knowledge-review.md +16 -0
- package/commands/optimize.md +31 -0
- package/commands/plan-verify.md +39 -0
- package/commands/promote-experiment.md +129 -0
- package/commands/research.md +22 -0
- package/commands/run.md +12 -0
- package/commands/self-review.md +51 -0
- package/commands/start-prd.md +57 -0
- package/commands/test.md +34 -0
- package/dist/src/assessment-orchestrator.d.ts +78 -0
- package/dist/src/assessment-orchestrator.d.ts.map +1 -0
- package/dist/src/assessment-orchestrator.js +304 -0
- package/dist/src/assessment-orchestrator.js.map +1 -0
- package/dist/src/audit-miner.d.ts +21 -0
- package/dist/src/audit-miner.d.ts.map +1 -0
- package/dist/src/audit-miner.js +421 -0
- package/dist/src/audit-miner.js.map +1 -0
- package/dist/src/batch-operations.d.ts +30 -0
- package/dist/src/batch-operations.d.ts.map +1 -0
- package/dist/src/batch-operations.js +339 -0
- package/dist/src/batch-operations.js.map +1 -0
- package/dist/src/config.d.ts +83 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +176 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/context-engine.d.ts +45 -0
- package/dist/src/context-engine.d.ts.map +1 -0
- package/dist/src/context-engine.js +135 -0
- package/dist/src/context-engine.js.map +1 -0
- package/dist/src/debug-wrapper.d.ts +58 -0
- package/dist/src/debug-wrapper.d.ts.map +1 -0
- package/dist/src/debug-wrapper.js +285 -0
- package/dist/src/debug-wrapper.js.map +1 -0
- package/dist/src/index.d.ts +31 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +149 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/interactive-verifier.d.ts +26 -0
- package/dist/src/interactive-verifier.d.ts.map +1 -0
- package/dist/src/interactive-verifier.js +435 -0
- package/dist/src/interactive-verifier.js.map +1 -0
- package/dist/src/lessons.d.ts +59 -0
- package/dist/src/lessons.d.ts.map +1 -0
- package/dist/src/lessons.js +172 -0
- package/dist/src/lessons.js.map +1 -0
- package/dist/src/log-reader.d.ts +39 -0
- package/dist/src/log-reader.d.ts.map +1 -0
- package/dist/src/log-reader.js +291 -0
- package/dist/src/log-reader.js.map +1 -0
- package/dist/src/logger.d.ts +59 -0
- package/dist/src/logger.d.ts.map +1 -0
- package/dist/src/logger.js +328 -0
- package/dist/src/logger.js.map +1 -0
- package/dist/src/parallel-retrieval.d.ts +52 -0
- package/dist/src/parallel-retrieval.d.ts.map +1 -0
- package/dist/src/parallel-retrieval.js +309 -0
- package/dist/src/parallel-retrieval.js.map +1 -0
- package/dist/src/pattern-extractor.d.ts +30 -0
- package/dist/src/pattern-extractor.d.ts.map +1 -0
- package/dist/src/pattern-extractor.js +386 -0
- package/dist/src/pattern-extractor.js.map +1 -0
- package/dist/src/result-aggregator.d.ts +44 -0
- package/dist/src/result-aggregator.d.ts.map +1 -0
- package/dist/src/result-aggregator.js +315 -0
- package/dist/src/result-aggregator.js.map +1 -0
- package/dist/src/retrieval.d.ts +139 -0
- package/dist/src/retrieval.d.ts.map +1 -0
- package/dist/src/retrieval.js +724 -0
- package/dist/src/retrieval.js.map +1 -0
- package/dist/src/setup/auto-setup.d.ts +15 -0
- package/dist/src/setup/auto-setup.d.ts.map +1 -0
- package/dist/src/setup/auto-setup.js +157 -0
- package/dist/src/setup/auto-setup.js.map +1 -0
- package/dist/src/setup/configure-hooks.d.ts +8 -0
- package/dist/src/setup/configure-hooks.d.ts.map +1 -0
- package/dist/src/setup/configure-hooks.js +16 -0
- package/dist/src/setup/configure-hooks.js.map +1 -0
- package/dist/src/setup/create-slash-commands.d.ts +8 -0
- package/dist/src/setup/create-slash-commands.d.ts.map +1 -0
- package/dist/src/setup/create-slash-commands.js +101 -0
- package/dist/src/setup/create-slash-commands.js.map +1 -0
- package/dist/src/setup/index.d.ts +8 -0
- package/dist/src/setup/index.d.ts.map +1 -0
- package/dist/src/setup/index.js +17 -0
- package/dist/src/setup/index.js.map +1 -0
- package/dist/src/setup/inject-claude-md.d.ts +10 -0
- package/dist/src/setup/inject-claude-md.d.ts.map +1 -0
- package/dist/src/setup/inject-claude-md.js +150 -0
- package/dist/src/setup/inject-claude-md.js.map +1 -0
- package/dist/src/setup/uninstall.d.ts +22 -0
- package/dist/src/setup/uninstall.d.ts.map +1 -0
- package/dist/src/setup/uninstall.js +235 -0
- package/dist/src/setup/uninstall.js.map +1 -0
- package/dist/src/storage.d.ts +192 -0
- package/dist/src/storage.d.ts.map +1 -0
- package/dist/src/storage.js +1037 -0
- package/dist/src/storage.js.map +1 -0
- package/dist/src/string-similarity.d.ts +8 -0
- package/dist/src/string-similarity.d.ts.map +1 -0
- package/dist/src/string-similarity.js +57 -0
- package/dist/src/string-similarity.js.map +1 -0
- package/dist/src/traces/adapters/browser.d.ts +69 -0
- package/dist/src/traces/adapters/browser.d.ts.map +1 -0
- package/dist/src/traces/adapters/browser.js +280 -0
- package/dist/src/traces/adapters/browser.js.map +1 -0
- package/dist/src/traces/adapters/index.d.ts +23 -0
- package/dist/src/traces/adapters/index.d.ts.map +1 -0
- package/dist/src/traces/adapters/index.js +67 -0
- package/dist/src/traces/adapters/index.js.map +1 -0
- package/dist/src/traces/adapters/langchain.d.ts +42 -0
- package/dist/src/traces/adapters/langchain.d.ts.map +1 -0
- package/dist/src/traces/adapters/langchain.js +151 -0
- package/dist/src/traces/adapters/langchain.js.map +1 -0
- package/dist/src/traces/adapters/opentelemetry.d.ts +46 -0
- package/dist/src/traces/adapters/opentelemetry.d.ts.map +1 -0
- package/dist/src/traces/adapters/opentelemetry.js +164 -0
- package/dist/src/traces/adapters/opentelemetry.js.map +1 -0
- package/dist/src/traces/adapters/sentry.d.ts +58 -0
- package/dist/src/traces/adapters/sentry.d.ts.map +1 -0
- package/dist/src/traces/adapters/sentry.js +212 -0
- package/dist/src/traces/adapters/sentry.js.map +1 -0
- package/dist/src/traces/index.d.ts +10 -0
- package/dist/src/traces/index.d.ts.map +1 -0
- package/dist/src/traces/index.js +45 -0
- package/dist/src/traces/index.js.map +1 -0
- package/dist/src/traces/storage.d.ts +78 -0
- package/dist/src/traces/storage.d.ts.map +1 -0
- package/dist/src/traces/storage.js +399 -0
- package/dist/src/traces/storage.js.map +1 -0
- package/dist/src/traces/summarizer.d.ts +83 -0
- package/dist/src/traces/summarizer.d.ts.map +1 -0
- package/dist/src/traces/summarizer.js +247 -0
- package/dist/src/traces/summarizer.js.map +1 -0
- package/dist/src/traces/types.d.ts +365 -0
- package/dist/src/traces/types.d.ts.map +1 -0
- package/dist/src/traces/types.js +14 -0
- package/dist/src/traces/types.js.map +1 -0
- package/dist/src/types.d.ts +495 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +27 -0
- package/dist/src/types.js.map +1 -0
- package/docs/agent-surface-policy.md +45 -0
- package/docs/memory-setup.md +226 -0
- package/hooks/_arch_scan_bg.py +88 -0
- package/hooks/_plugin_drift_check_bg.py +85 -0
- package/hooks/_session_start_lib.sh +42 -0
- package/hooks/git/pre-push +141 -0
- package/hooks/hooks.json +126 -0
- package/hooks/post-commit +30 -0
- package/hooks/pre-commit +29 -0
- package/hooks/pre-edit-apppulse.sh +6 -0
- package/hooks/pre-edit-architecture.sh +106 -0
- package/hooks/pre-edit-rally-point.sh +92 -0
- package/hooks/session-start-apppulse.sh +6 -0
- package/hooks/session-start-architecture.sh +10 -0
- package/hooks/session-start-git-hooks.sh +12 -0
- package/hooks/session-start-plugin-drift.sh +27 -0
- package/hooks/session-start-rally-point.sh +44 -0
- package/hooks/session-start-retrieval.sh +24 -0
- package/hooks/session-start-worktree-gc.sh +105 -0
- package/hooks/test_apppulse_hooks.sh +6 -0
- package/hooks/test_rally_point_hooks.sh +388 -0
- package/hooks/test_sec008_hooks.sh +66 -0
- package/package.json +111 -0
- package/scripts/README.md +301 -0
- package/scripts/_db_url.py +61 -0
- package/scripts/_paths.py +445 -0
- package/scripts/blm.py +162 -0
- package/scripts/blm_api.py +263 -0
- package/scripts/check_cache_sync.py +490 -0
- package/scripts/embed_backend.py +475 -0
- package/scripts/install_memory.py +556 -0
- package/scripts/lessons_index/__init__.py +77 -0
- package/scripts/lessons_index/__main__.py +135 -0
- package/scripts/lessons_index/ingest.py +288 -0
- package/scripts/lessons_index/query.py +285 -0
- package/scripts/lessons_index/schema.py +114 -0
- package/scripts/memory_context/__init__.py +610 -0
- package/scripts/memory_graph/__init__.py +393 -0
- package/scripts/project_resolver.py +172 -0
- package/scripts/prune_codex_plugin_cache.py +23 -0
- package/scripts/prune_plugin_cache.py +359 -0
- package/scripts/semantic_index/__init__.py +482 -0
- package/scripts/semantic_index/_bench_hybrid.py +175 -0
- package/scripts/semantic_index/backfill.py +263 -0
- package/scripts/semantic_index/hybrid.py +174 -0
- package/scripts/semantic_index/test_backfill.py +292 -0
- package/scripts/semantic_index/test_hybrid.py +541 -0
- package/scripts/sync_navgator_lessons.py +666 -0
- package/scripts/sync_plugin_cache.py +388 -0
- package/skills/agent-rally-point/SKILL.md +165 -0
- package/skills/agent-rally-watcher/SKILL.md +83 -0
- package/skills/api-registry-bridge/SKILL.md +59 -0
- package/skills/architecture/dead/SKILL.md +56 -0
- package/skills/architecture/impact/SKILL.md +88 -0
- package/skills/architecture/review/SKILL.md +227 -0
- package/skills/architecture/rules/SKILL.md +72 -0
- package/skills/architecture/scan/SKILL.md +79 -0
- package/skills/architecture/trace/SKILL.md +65 -0
- package/skills/attribution-standard/SKILL.md +122 -0
- package/skills/authentication/SKILL.md +81 -0
- package/skills/authentication/references/better-auth-magic-link.md +135 -0
- package/skills/authentication/references/better-auth-setup.md +224 -0
- package/skills/authentication/references/google-calendar-sync.md +278 -0
- package/skills/authentication/references/google-cloud-console.md +159 -0
- package/skills/authentication/references/google-geocoding-directions.md +126 -0
- package/skills/authentication/references/google-lessons-example-web-app.md +177 -0
- package/skills/authentication/references/google-maps.md +162 -0
- package/skills/authentication/references/google-oauth-setup.md +343 -0
- package/skills/authentication/references/google-places.md +173 -0
- package/skills/authentication/references/lessons-example-web-app-better-auth.md +126 -0
- package/skills/authentication/references/resend-email.md +227 -0
- package/skills/authentication/references/resend-otp-magic-link.md +153 -0
- package/skills/authentication/references/supabase-auth.md +172 -0
- package/skills/auto-decision-capture/SKILL.md +419 -0
- package/skills/build-loop/SKILL.md +516 -0
- package/skills/build-loop/detect-plugins.mjs +82 -0
- package/skills/build-loop/eval-guide.md +65 -0
- package/skills/build-loop/fallbacks.md +549 -0
- package/skills/build-loop/phases/fact-check.md +42 -0
- package/skills/build-loop/phases/ui-validation.md +267 -0
- package/skills/build-loop/references/apple-native-planning.md +439 -0
- package/skills/build-loop/references/capability-routing.md +181 -0
- package/skills/build-loop/references/codex-subagents.md +98 -0
- package/skills/build-loop/references/coordination.md +161 -0
- package/skills/build-loop/references/correction-aware-capture.md +177 -0
- package/skills/build-loop/references/independent-auditor.md +72 -0
- package/skills/build-loop/references/intent-capability-pack.md +170 -0
- package/skills/build-loop/references/intent-exploration-prompts.md +96 -0
- package/skills/build-loop/references/leadership.md +72 -0
- package/skills/build-loop/references/memory.md +284 -0
- package/skills/build-loop/references/modular-systems-pack.md +96 -0
- package/skills/build-loop/references/output-style.md +129 -0
- package/skills/build-loop/references/pay-it-forward-arch.md +98 -0
- package/skills/build-loop/references/phase-1-assess.md +218 -0
- package/skills/build-loop/references/phase-2-plan.md +77 -0
- package/skills/build-loop/references/phase-3-execute.md +47 -0
- package/skills/build-loop/references/phase-4-review.md +310 -0
- package/skills/build-loop/references/phase-5-iterate.md +71 -0
- package/skills/build-loop/references/phase-6-learn.md +56 -0
- package/skills/build-loop/references/recent-design-structures.md +274 -0
- package/skills/build-loop/references/refactor-history/ASSESSMENT.md +85 -0
- package/skills/build-loop/references/refactor-history/STANDALONE_TEST_RUN.md +149 -0
- package/skills/build-loop/references/refactor-history/scenarios/01-simple-bugfix.md +32 -0
- package/skills/build-loop/references/refactor-history/scenarios/02-ui-build-with-iteration.md +48 -0
- package/skills/build-loop/references/refactor-history/scenarios/03-multi-failure-escalation.md +60 -0
- package/skills/build-loop/references/refactor-history/scenarios/04-ui-build-ibr-absent.md +51 -0
- package/skills/build-loop/references/refactor-history/scenarios/05-refactor-navgator-absent.md +71 -0
- package/skills/build-loop/references/refactor-history/scenarios/06-recurring-bug-debugger-absent.md +52 -0
- package/skills/build-loop/references/refactor-history/trace-comparison.md +202 -0
- package/skills/build-loop/references/self-recursive-dev.md +77 -0
- package/skills/build-loop/references/self-review.md +232 -0
- package/skills/build-loop/references/ui-io-contract.md +116 -0
- package/skills/build-loop/scanners/audit-design-rules.mjs +476 -0
- package/skills/build-loop/scanners/require-visual-evidence.mjs +239 -0
- package/skills/build-loop/templates/backlog-item.md +35 -0
- package/skills/build-loop/templates/codex-worker-prompt.md +89 -0
- package/skills/build-loop/templates/ui-subagent-prompt.md +179 -0
- package/skills/build-loop/templates/ux-fix-plan.md +40 -0
- package/skills/building-with-deepagents/SKILL.md +195 -0
- package/skills/building-with-deepagents/references/anti-patterns.md +141 -0
- package/skills/building-with-deepagents/references/api-quick-reference.md +184 -0
- package/skills/capabilities/SKILL.md +91 -0
- package/skills/debug-loop/SKILL.md +278 -0
- package/skills/debug-loop/references/convergence-rules.md +145 -0
- package/skills/debug-loop/references/swiftui-macos-clunky-ui-debugger.html +823 -0
- package/skills/debugging/assess/SKILL.md +111 -0
- package/skills/debugging/debug-loop/SKILL.md +231 -0
- package/skills/debugging/memory/SKILL.md +147 -0
- package/skills/debugging/store/SKILL.md +153 -0
- package/skills/debugging-memory/SKILL.md +440 -0
- package/skills/debugging-memory/examples/incident-example.json +67 -0
- package/skills/debugging-memory/references/incident-documentation.md +280 -0
- package/skills/debugging-memory/references/ios-notification-alarm-playbook.md +300 -0
- package/skills/debugging-memory/references/pattern-extraction.md +163 -0
- package/skills/debugging-memory/references/subagent-integration.md +312 -0
- package/skills/defenseclaw-bridge/SKILL.md +156 -0
- package/skills/defenseclaw-bridge/references/dc-config-mapping.md +162 -0
- package/skills/defenseclaw-bridge/references/output-format.md +108 -0
- package/skills/handoff/SKILL.md +94 -0
- package/skills/ibr-bridge/SKILL.md +68 -0
- package/skills/knowledge/SKILL.md +127 -0
- package/skills/knowledge/references/recall-integration.md +83 -0
- package/skills/knowledge/templates/madr-minimal.md +56 -0
- package/skills/knowledge-review/SKILL.md +112 -0
- package/skills/logging-tracer/SKILL.md +202 -0
- package/skills/logging-tracer/references/log-analysis.md +128 -0
- package/skills/logging-tracer/references/stack-templates.md +274 -0
- package/skills/logging-tracer-bridge/SKILL.md +70 -0
- package/skills/mcp-builder/SKILL.md +278 -0
- package/skills/mcp-builder/references/mcp-security.md +106 -0
- package/skills/model-tiering/SKILL.md +216 -0
- package/skills/native-ax-driver/SKILL.md +220 -0
- package/skills/native-ax-driver/scripts/layout_fill.py +222 -0
- package/skills/native-ax-driver/scripts/native_driver.py +495 -0
- package/skills/native-ax-driver/swift/bl-ax-driver/Package.swift +20 -0
- package/skills/native-ax-driver/swift/bl-ax-driver/Sources/main.swift +542 -0
- package/skills/optimize/SKILL.md +202 -0
- package/skills/optimize/profiles.md +61 -0
- package/skills/plan-verify/SKILL.md +115 -0
- package/skills/plan-verify/test-fixtures/example-app-v20-findings.json +27 -0
- package/skills/plan-verify/test-fixtures/example-app-v20.md +42 -0
- package/skills/plan-verify/test-fixtures/example-app-v22-findings.json +15 -0
- package/skills/plan-verify/test-fixtures/example-app-v22.md +1608 -0
- package/skills/plan-verify/test-fixtures/unrelated-good-plan-findings.json +15 -0
- package/skills/plan-verify/test-fixtures/unrelated-good-plan.md +55 -0
- package/skills/plugin-builder/SKILL.md +329 -0
- package/skills/plugin-builder/references/authoritative-sources.md +104 -0
- package/skills/plugin-builder/references/build-loop-phase-guidance.md +94 -0
- package/skills/plugin-builder/references/components-guide.md +221 -0
- package/skills/plugin-builder/references/distribution.md +317 -0
- package/skills/plugin-builder/references/dual-host-claude-codex.md +220 -0
- package/skills/plugin-builder/references/hooks-reference.md +210 -0
- package/skills/plugin-builder/references/manifest-schema.md +111 -0
- package/skills/plugin-builder/references/plugin-hygiene-lessons.md +307 -0
- package/skills/plugin-tests/SKILL.md +94 -0
- package/skills/prd-bridge/SKILL.md +135 -0
- package/skills/research/SKILL.md +80 -0
- package/skills/security-methodology/SKILL.md +105 -0
- package/skills/security-methodology/references/cross-source-matrix.md +77 -0
- package/skills/security-methodology/references/mitre-atlas-starter.md +83 -0
- package/skills/security-methodology/references/nist-600-1-mapping.md +119 -0
- package/skills/security-methodology/references/owasp-agentic-top-10.md +157 -0
- package/skills/security-methodology/references/owasp-llm-top-10.md +144 -0
- package/skills/security-methodology/references/owasp-web-top-10.md +65 -0
- package/skills/self-improve/SKILL.md +298 -0
- package/skills/spec-writing/SKILL.md +548 -0
- package/skills/spec-writing/scripts/check_checklist.py +478 -0
- package/skills/sync-skills/SKILL.md +132 -0
- package/skills/telemetry/SKILL.md +66 -0
- package/skills/ui-design/SKILL.md +75 -0
- package/skills/ui-design/references/design-patterns-multi.md +165 -0
- package/skills/ui-design/references/design-preferences-from-owned-apps.md +150 -0
- package/skills/ui-design/references/evidence-capture-policy.md +55 -0
- package/skills/ui-design/references/ui-guidance-sources.md +330 -0
- package/skills/ui-design/references/universal-design-principles.alt.md +182 -0
- package/skills/ui-design/references/universal-design-principles.md +419 -0
- package/templates/memory/MEMORY.md.template +55 -0
- package/templates/memory/constitution.md.template +64 -0
- package/templates/memory/manifest.json +47 -0
package/hooks/hooks.json
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"SessionStart": [
|
|
4
|
+
{
|
|
5
|
+
"matcher": "",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "command",
|
|
9
|
+
"command": "bash \"${CLAUDE_PLUGIN_ROOT:-$CLAUDE_PROJECT_DIR}/hooks/session-start-architecture.sh\" </dev/null >/dev/null 2>&1; exit 0",
|
|
10
|
+
"timeout": 2000
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"type": "command",
|
|
14
|
+
"command": "bash \"${CLAUDE_PLUGIN_ROOT:-$CLAUDE_PROJECT_DIR}/hooks/session-start-retrieval.sh\" </dev/null >/dev/null 2>&1; exit 0",
|
|
15
|
+
"timeout": 2000
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"type": "command",
|
|
19
|
+
"command": "bash \"${CLAUDE_PLUGIN_ROOT:-$CLAUDE_PROJECT_DIR}/hooks/session-start-rally-point.sh\" </dev/null 2>/dev/null; exit 0",
|
|
20
|
+
"timeout": 2000
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"type": "command",
|
|
24
|
+
"command": "bash \"${CLAUDE_PLUGIN_ROOT:-$CLAUDE_PROJECT_DIR}/hooks/session-start-worktree-gc.sh\" </dev/null >/dev/null 2>&1; exit 0",
|
|
25
|
+
"timeout": 2000
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"type": "command",
|
|
29
|
+
"command": "bash \"${CLAUDE_PLUGIN_ROOT:-$CLAUDE_PROJECT_DIR}/hooks/session-start-git-hooks.sh\" </dev/null >/dev/null 2>&1; exit 0",
|
|
30
|
+
"timeout": 2000
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"type": "command",
|
|
34
|
+
"command": "bash \"${CLAUDE_PLUGIN_ROOT:-$CLAUDE_PROJECT_DIR}/hooks/session-start-plugin-drift.sh\" </dev/null >/dev/null 2>&1; exit 0",
|
|
35
|
+
"timeout": 2000
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"PreToolUse": [
|
|
41
|
+
{
|
|
42
|
+
"matcher": "Edit|Write",
|
|
43
|
+
"hooks": [
|
|
44
|
+
{
|
|
45
|
+
"type": "command",
|
|
46
|
+
"command": "bash \"${CLAUDE_PLUGIN_ROOT:-$CLAUDE_PROJECT_DIR}/hooks/pre-edit-architecture.sh\" >/dev/null 2>&1; exit 0",
|
|
47
|
+
"timeout": 2000
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"type": "command",
|
|
51
|
+
"command": "bash \"${CLAUDE_PLUGIN_ROOT:-$CLAUDE_PROJECT_DIR}/hooks/pre-edit-rally-point.sh\"; exit 0",
|
|
52
|
+
"timeout": 2000
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"matcher": "Bash",
|
|
58
|
+
"hooks": [
|
|
59
|
+
{
|
|
60
|
+
"type": "command",
|
|
61
|
+
"command": "root=\"${CLAUDE_PLUGIN_ROOT:-$CLAUDE_PROJECT_DIR}\"; hook=\"$root/scripts/hooks/pre_bash_autonomy.sh\"; if [ -x \"$hook\" ]; then \"$hook\"; else printf '{}'; fi",
|
|
62
|
+
"timeout": 2000
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"type": "command",
|
|
66
|
+
"command": "root=\"${CLAUDE_PLUGIN_ROOT:-$CLAUDE_PROJECT_DIR}\"; hook=\"$root/scripts/hooks/pre_bash_dependency_cooldown.sh\"; if [ -x \"$hook\" ]; then \"$hook\"; else printf '{}'; fi",
|
|
67
|
+
"timeout": 2000
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"type": "command",
|
|
71
|
+
"command": "root=\"${CLAUDE_PLUGIN_ROOT:-$CLAUDE_PROJECT_DIR}\"; hook=\"$root/scripts/audit_before_commit.py\"; if [ -f \"$hook\" ]; then python3 \"$hook\"; else printf '{}'; fi",
|
|
72
|
+
"timeout": 5000
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"type": "command",
|
|
76
|
+
"command": "bash \"${CLAUDE_PLUGIN_ROOT:-$CLAUDE_PROJECT_DIR}/hooks/pre-edit-rally-point.sh\"; exit 0",
|
|
77
|
+
"timeout": 2000
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
}
|
|
81
|
+
],
|
|
82
|
+
"PostToolUse": [
|
|
83
|
+
{
|
|
84
|
+
"matcher": "Bash",
|
|
85
|
+
"hooks": [
|
|
86
|
+
{
|
|
87
|
+
"type": "command",
|
|
88
|
+
"command": "[ -f .build-loop/state.json ] || exit 0; python3 -c \"import json,sys; s=json.load(open('.build-loop/state.json')); p7=s.get('phases',{}).get('fact_check',{}).get('completed',False); active=s.get('active',False); sys.exit(0 if (not active or p7) else 1)\" 2>/dev/null && exit 0; echo \"$TOOL_INPUT\" | grep -qE '\\b(git\\s+push|npm\\s+publish|vercel\\s+deploy|gh\\s+release)\\b' && echo 'Build loop Phase 7 (fact-check) has not completed. Run fact-check before deploying.'; exit 0"
|
|
89
|
+
}
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
],
|
|
93
|
+
"Stop": [
|
|
94
|
+
{
|
|
95
|
+
"matcher": "",
|
|
96
|
+
"hooks": [
|
|
97
|
+
{
|
|
98
|
+
"type": "command",
|
|
99
|
+
"command": "if [ -n \"$CLAUDE_TRANSCRIPT_PATH\" ]; then nohup python3 \"${CLAUDE_PLUGIN_ROOT:-$CLAUDE_PROJECT_DIR}/scripts/scan_transcript_for_decisions.py\" --workdir \"$CLAUDE_PROJECT_DIR\" --transcript \"$CLAUDE_TRANSCRIPT_PATH\" --log-file \"${XDG_STATE_HOME:-$HOME/.local/state}/build-loop/scan.log\" </dev/null >/dev/null 2>&1 & fi; printf '{}'",
|
|
100
|
+
"timeout": 5000
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"type": "command",
|
|
104
|
+
"command": "if [ -n \"$CLAUDE_TRANSCRIPT_PATH\" ]; then root=\"${CLAUDE_PLUGIN_ROOT:-$CLAUDE_PROJECT_DIR}\"; nohup env PYTHONPATH=\"$root/scripts\" python3 -m scan_corrections --workdir \"$CLAUDE_PROJECT_DIR\" --transcript \"$CLAUDE_TRANSCRIPT_PATH\" --source stop-hook </dev/null >/dev/null 2>&1 & fi; printf '{}'",
|
|
105
|
+
"timeout": 5000
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"type": "command",
|
|
109
|
+
"command": "python3 \"${CLAUDE_PLUGIN_ROOT:-$CLAUDE_PROJECT_DIR}/scripts/state_finalize.py\" --workdir \"$CLAUDE_PROJECT_DIR\" --mark-incomplete-as-crashed </dev/null >/dev/null 2>&1; printf '{}'",
|
|
110
|
+
"timeout": 2000
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"type": "command",
|
|
114
|
+
"command": "root=\"${CLAUDE_PLUGIN_ROOT:-$CLAUDE_PROJECT_DIR}\"; hook=\"$root/scripts/hooks/stop_finalize.sh\"; if [ -x \"$hook\" ]; then \"$hook\"; else printf '{}'; fi",
|
|
115
|
+
"timeout": 30000
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"type": "command",
|
|
119
|
+
"command": "if [ -f \"${CLAUDE_PLUGIN_ROOT:-$CLAUDE_PROJECT_DIR}/scripts/commit_state_check.py\" ]; then python3 \"${CLAUDE_PLUGIN_ROOT:-$CLAUDE_PROJECT_DIR}/scripts/commit_state_check.py\" --workdir \"${CLAUDE_PROJECT_DIR}\" --hook; else printf '{}'; fi",
|
|
120
|
+
"timeout": 5000
|
|
121
|
+
}
|
|
122
|
+
]
|
|
123
|
+
}
|
|
124
|
+
]
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Rally Point post-commit capture (cross-tool).
|
|
3
|
+
#
|
|
4
|
+
# git fires this regardless of which tool (Claude / Codex / plain git)
|
|
5
|
+
# made the commit, so it is the durable cross-tool capture boundary.
|
|
6
|
+
# Fire-and-forget: all real work is backgrounded and the hook returns 0
|
|
7
|
+
# immediately so it can NEVER slow down or fail a commit.
|
|
8
|
+
#
|
|
9
|
+
# Identity comes from the environment when present:
|
|
10
|
+
# RALLY_POINT_TOOL (default: unknown; APP_PULSE_TOOL fallback supported)
|
|
11
|
+
# RALLY_POINT_RUN_ID (default: unknown; APP_PULSE_RUN_ID fallback supported)
|
|
12
|
+
# RALLY_POINT_MODEL (default: unknown; APP_PULSE_MODEL fallback supported)
|
|
13
|
+
#
|
|
14
|
+
# Idempotent installer chains this after any pre-existing post-commit;
|
|
15
|
+
# this body is the Rally Point segment only.
|
|
16
|
+
|
|
17
|
+
# --- BEGIN rally-point post-commit ---
|
|
18
|
+
RALLY_POINT_TOPLEVEL="$(git rev-parse --show-toplevel 2>/dev/null)"
|
|
19
|
+
if [ -z "$RALLY_POINT_TOPLEVEL" ]; then
|
|
20
|
+
echo "rally-point post-commit: cannot resolve repo toplevel" >&2
|
|
21
|
+
exit 2
|
|
22
|
+
fi
|
|
23
|
+
RALLY_POINT_CAPTURE="$RALLY_POINT_TOPLEVEL/.git/hooks/.rally-point-capture.py"
|
|
24
|
+
if [ -f "$RALLY_POINT_CAPTURE" ]; then
|
|
25
|
+
(
|
|
26
|
+
python3 "$RALLY_POINT_CAPTURE" >/dev/null 2>&1
|
|
27
|
+
) </dev/null >/dev/null 2>&1 &
|
|
28
|
+
fi
|
|
29
|
+
# --- END rally-point post-commit ---
|
|
30
|
+
exit 0
|
package/hooks/pre-commit
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Public-repo hygiene pre-commit hook.
|
|
3
|
+
#
|
|
4
|
+
# build-loop is open source. This hook blocks a commit that stages a
|
|
5
|
+
# private app slug (see scripts/check_private_slugs.py for the editable
|
|
6
|
+
# denylist) or runtime memory/state files. Unlike post-commit, this hook
|
|
7
|
+
# MUST be able to fail the commit, so it is NOT fire-and-forget — a
|
|
8
|
+
# non-zero exit aborts the commit by design.
|
|
9
|
+
#
|
|
10
|
+
# Idempotent installer chains this after any pre-existing pre-commit;
|
|
11
|
+
# this body is the private-slug-guard segment only.
|
|
12
|
+
|
|
13
|
+
# --- BEGIN private-slug-guard pre-commit ---
|
|
14
|
+
RALLY_POINT_TOPLEVEL="$(git rev-parse --show-toplevel 2>/dev/null)"
|
|
15
|
+
if [ -z "$RALLY_POINT_TOPLEVEL" ]; then
|
|
16
|
+
echo "private-slug-guard: cannot resolve repo toplevel — refusing to skip the guard" >&2
|
|
17
|
+
exit 2
|
|
18
|
+
fi
|
|
19
|
+
PRIVATE_SLUG_GUARD="$RALLY_POINT_TOPLEVEL/.git/hooks/.private-slug-check.py"
|
|
20
|
+
if [ -f "$PRIVATE_SLUG_GUARD" ]; then
|
|
21
|
+
python3 "$PRIVATE_SLUG_GUARD" || exit 1
|
|
22
|
+
fi
|
|
23
|
+
RUNTIME_MEMORY_GUARD="$RALLY_POINT_TOPLEVEL/.git/hooks/.runtime-memory-tracking-check.py"
|
|
24
|
+
if [ -f "$RUNTIME_MEMORY_GUARD" ]; then
|
|
25
|
+
python3 "$RUNTIME_MEMORY_GUARD" || exit 1
|
|
26
|
+
fi
|
|
27
|
+
# --- END private-slug-guard pre-commit ---
|
|
28
|
+
|
|
29
|
+
exit 0
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com>
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
# Deprecated alias; use pre-edit-rally-point.sh.
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
exec bash "$SCRIPT_DIR/pre-edit-rally-point.sh" "$@"
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com>
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
# PreToolUse hook (matcher: Edit|Write) — incremental scan trigger.
|
|
5
|
+
#
|
|
6
|
+
# Contract:
|
|
7
|
+
# - command-type only (NEVER prompt-type)
|
|
8
|
+
# - no stdout, no stderr (exit 0 always — never blocks the Edit/Write)
|
|
9
|
+
# - fire-and-forget via `nohup ... &`; hook returns in <100ms
|
|
10
|
+
# - tool input arrives on stdin as JSON: {"tool_input": {"file_path": "..."}}
|
|
11
|
+
#
|
|
12
|
+
# Behavior:
|
|
13
|
+
# 1. Bail silently if `.build-loop/architecture/file_map.json` does not exist
|
|
14
|
+
# (engine not initialized).
|
|
15
|
+
# 2. Parse `file_path` from stdin JSON; bail on missing/invalid input.
|
|
16
|
+
# 3. Dependency-manifest edit (package.json, requirements.txt, uv.lock, …):
|
|
17
|
+
# mark `.build-loop/architecture/.enrich-needed` and EXIT — DEFER the
|
|
18
|
+
# actual enriched scan to the scout pass (OQ3); never run it inline.
|
|
19
|
+
# 4. Else bail silently if file extension is not in the source-code
|
|
20
|
+
# allowlist (.py .ts .tsx .js .jsx .mjs .cjs). Doc-only edits (.md,
|
|
21
|
+
# .txt, plain .json, images) never mark architecture stale or fire a scan.
|
|
22
|
+
# 5. Resolve to repo-relative path; bail if not in file_map.
|
|
23
|
+
# 5. Mark stale (always — even if a scan is in flight, orchestrator must see
|
|
24
|
+
# stale=true before reading ACP).
|
|
25
|
+
# 6. Fire `_arch_scan_bg.py` (single-flight flock inside the worker).
|
|
26
|
+
|
|
27
|
+
WORKDIR="${CLAUDE_PROJECT_DIR:-$PWD}"
|
|
28
|
+
ARCH_DIR="$WORKDIR/.build-loop/architecture"
|
|
29
|
+
FILE_MAP="$ARCH_DIR/file_map.json"
|
|
30
|
+
FRESHNESS_SCRIPT="$WORKDIR/scripts/architecture_freshness.py"
|
|
31
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
32
|
+
WORKER="$SCRIPT_DIR/_arch_scan_bg.py"
|
|
33
|
+
|
|
34
|
+
# Fast bail-out: arch engine not initialized.
|
|
35
|
+
[ -f "$FILE_MAP" ] || exit 0
|
|
36
|
+
[ -f "$FRESHNESS_SCRIPT" ] || exit 0
|
|
37
|
+
[ -f "$WORKER" ] || exit 0
|
|
38
|
+
|
|
39
|
+
# Read stdin (may be empty — bail cleanly).
|
|
40
|
+
STDIN_JSON=$(cat 2>/dev/null)
|
|
41
|
+
[ -n "$STDIN_JSON" ] || exit 0
|
|
42
|
+
|
|
43
|
+
# Classify the edited path. Emits one of:
|
|
44
|
+
# "MANIFEST" → dependency manifest changed: mark enrich-needed, DEFER the
|
|
45
|
+
# actual enrich to the scout pass (OQ3) — do NOT scan inline.
|
|
46
|
+
# "<rel>" → tracked source file: the existing mark-stale + bg-scan path.
|
|
47
|
+
# "" → bail (doc-only, untracked, unparseable).
|
|
48
|
+
# The manifest check runs BEFORE the source-extension allowlist so a
|
|
49
|
+
# package.json / requirements.txt edit is no longer excluded.
|
|
50
|
+
REL_PATH=$(WORKDIR="$WORKDIR" FILE_MAP="$FILE_MAP" STDIN_JSON="$STDIN_JSON" python3 - <<'PYEOF' 2>/dev/null
|
|
51
|
+
import json, os, sys
|
|
52
|
+
from pathlib import Path
|
|
53
|
+
ALLOWED_EXTS = {".py", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"}
|
|
54
|
+
MANIFESTS = {
|
|
55
|
+
"package.json", "package-lock.json", "pnpm-lock.yaml", "requirements.txt",
|
|
56
|
+
"pyproject.toml", "uv.lock", "Cargo.toml", "Cargo.lock", "go.mod", "Gemfile",
|
|
57
|
+
}
|
|
58
|
+
try:
|
|
59
|
+
payload = json.loads(os.environ["STDIN_JSON"])
|
|
60
|
+
except (KeyError, json.JSONDecodeError):
|
|
61
|
+
sys.exit(0)
|
|
62
|
+
ti = payload.get("tool_input") or {}
|
|
63
|
+
fp = ti.get("file_path") or ti.get("path") or ti.get("filename")
|
|
64
|
+
if not fp:
|
|
65
|
+
sys.exit(0)
|
|
66
|
+
# Dependency-manifest unblock (OQ3) — runs before the extension allowlist.
|
|
67
|
+
if Path(fp).name in MANIFESTS:
|
|
68
|
+
print("MANIFEST")
|
|
69
|
+
sys.exit(0)
|
|
70
|
+
# Extension allowlist gate — bail on .md/.txt/.json/etc. before any I/O.
|
|
71
|
+
ext = Path(fp).suffix.lower()
|
|
72
|
+
if ext not in ALLOWED_EXTS:
|
|
73
|
+
sys.exit(0)
|
|
74
|
+
workdir = Path(os.environ["WORKDIR"]).resolve()
|
|
75
|
+
abs_path = (workdir / fp).resolve() if not os.path.isabs(fp) else Path(fp).resolve()
|
|
76
|
+
try:
|
|
77
|
+
rel = abs_path.relative_to(workdir).as_posix()
|
|
78
|
+
except ValueError:
|
|
79
|
+
sys.exit(0)
|
|
80
|
+
try:
|
|
81
|
+
file_map = json.loads(Path(os.environ["FILE_MAP"]).read_text(encoding="utf-8"))
|
|
82
|
+
except (OSError, json.JSONDecodeError):
|
|
83
|
+
sys.exit(0)
|
|
84
|
+
files = file_map.get("files") or {}
|
|
85
|
+
if rel in files:
|
|
86
|
+
print(rel)
|
|
87
|
+
PYEOF
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
[ -n "$REL_PATH" ] || exit 0
|
|
91
|
+
|
|
92
|
+
# Dependency-manifest edit: mark enrich-needed and EXIT. The actual enriched
|
|
93
|
+
# scan is deferred to the scout pass (OQ3) — never run inline here.
|
|
94
|
+
if [ "$REL_PATH" = "MANIFEST" ]; then
|
|
95
|
+
: > "$ARCH_DIR/.enrich-needed" 2>/dev/null || true
|
|
96
|
+
exit 0
|
|
97
|
+
fi
|
|
98
|
+
|
|
99
|
+
# Mark stale immediately (cheap, atomic).
|
|
100
|
+
python3 "$FRESHNESS_SCRIPT" --mark-stale --file "$REL_PATH" --workdir "$WORKDIR" >/dev/null 2>&1 || true
|
|
101
|
+
|
|
102
|
+
# Fire the background worker. Single-flight handled inside the worker.
|
|
103
|
+
nohup python3 "$WORKER" --workdir "$WORKDIR" </dev/null >/dev/null 2>&1 &
|
|
104
|
+
disown 2>/dev/null || true
|
|
105
|
+
|
|
106
|
+
exit 0
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com>
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
# PreToolUse(Edit|Write|Bash) hook — Rally Point throttled per-tool-use re-join
|
|
5
|
+
# + cheap revision-stat hint.
|
|
6
|
+
#
|
|
7
|
+
# Contract:
|
|
8
|
+
# - command-type only (NEVER prompt-type)
|
|
9
|
+
# - exit 0 ALWAYS — NEVER blocks the tool use
|
|
10
|
+
# - cheap: a single `revision` stat+read for the legacy hint, a single
|
|
11
|
+
# presence stat+read for the throttled re-join, NO tail read, NO lock
|
|
12
|
+
# - prints one short hint ONLY when the channel revision is ahead of
|
|
13
|
+
# this reader's last-seen revision; silent otherwise
|
|
14
|
+
# - graceful absence: no channel -> silent exit 0
|
|
15
|
+
#
|
|
16
|
+
# Codex-parity hardening (2026-06-07):
|
|
17
|
+
# Beyond the legacy revision hint, this hook now ALSO resolves the
|
|
18
|
+
# OPERATIVE repo from the tool event (Edit/Write file_path, Bash leading
|
|
19
|
+
# ``cd <path>``) and writes a throttled heartbeat presence in THAT repo's
|
|
20
|
+
# room. SessionStart misregisters (or no-ops) when the agent launches
|
|
21
|
+
# outside the repo it actually edits; this re-join recovers presence on
|
|
22
|
+
# the first tool-use without a flock on the hot path.
|
|
23
|
+
|
|
24
|
+
WORKDIR="${CLAUDE_PROJECT_DIR:-$PWD}"
|
|
25
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
26
|
+
PKG="$SCRIPT_DIR/../scripts/rally_point"
|
|
27
|
+
|
|
28
|
+
[ -d "$PKG" ] || exit 0
|
|
29
|
+
|
|
30
|
+
# Read stdin (Claude Code PreToolUse JSON event). Best-effort; an empty
|
|
31
|
+
# or malformed payload simply means "no operative-repo hint" — the legacy
|
|
32
|
+
# revision-stat hint still fires using the workdir's channel.
|
|
33
|
+
# Cap at 64 KB: a pathological Bash command must not exhaust ARG_MAX when
|
|
34
|
+
# the payload is forwarded to Python via the environment.
|
|
35
|
+
STDIN_JSON=""
|
|
36
|
+
if [ ! -t 0 ]; then
|
|
37
|
+
STDIN_JSON=$(cat 2>/dev/null || true)
|
|
38
|
+
STDIN_JSON=$(printf '%s' "$STDIN_JSON" | head -c 65536)
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# Extract file_path (Edit/Write) and command (Bash) from the event JSON.
|
|
42
|
+
# Both are optional; pre-edit treats them as resolution hints, not gates.
|
|
43
|
+
# Print them on two separate lines so the shell does not have to deal
|
|
44
|
+
# with NUL handling across portable awk/read.
|
|
45
|
+
FILE_PATH=""
|
|
46
|
+
TOOL_CMD=""
|
|
47
|
+
if [ -n "$STDIN_JSON" ]; then
|
|
48
|
+
EXTRACTED=$(STDIN_JSON="$STDIN_JSON" python3 - <<'PYEOF' 2>/dev/null
|
|
49
|
+
import json, os, sys
|
|
50
|
+
raw = os.environ.get("STDIN_JSON") or ""
|
|
51
|
+
try:
|
|
52
|
+
d = json.loads(raw)
|
|
53
|
+
except (ValueError, TypeError):
|
|
54
|
+
sys.exit(0)
|
|
55
|
+
ti = (d.get("tool_input") or {}) if isinstance(d.get("tool_input"), dict) else {}
|
|
56
|
+
fp = ti.get("file_path") or ti.get("path") or ti.get("filename") or ""
|
|
57
|
+
cmd = ti.get("command") or ""
|
|
58
|
+
# Emit fp as base64 (single line, no newlines), then cmd as base64. The
|
|
59
|
+
# bash side decodes; this avoids embedded-newline parsing entirely.
|
|
60
|
+
import base64
|
|
61
|
+
b64 = lambda s: base64.b64encode(s.encode("utf-8", "replace")).decode("ascii") if s else ""
|
|
62
|
+
sys.stdout.write(b64(fp) + "\n" + b64(cmd) + "\n")
|
|
63
|
+
PYEOF
|
|
64
|
+
)
|
|
65
|
+
if [ -n "$EXTRACTED" ]; then
|
|
66
|
+
FILE_PATH_B64=$(printf '%s\n' "$EXTRACTED" | sed -n '1p')
|
|
67
|
+
TOOL_CMD_B64=$(printf '%s\n' "$EXTRACTED" | sed -n '2p')
|
|
68
|
+
if [ -n "$FILE_PATH_B64" ]; then
|
|
69
|
+
FILE_PATH=$(printf '%s' "$FILE_PATH_B64" | base64 --decode 2>/dev/null || true)
|
|
70
|
+
fi
|
|
71
|
+
if [ -n "$TOOL_CMD_B64" ]; then
|
|
72
|
+
TOOL_CMD=$(printf '%s' "$TOOL_CMD_B64" | base64 --decode 2>/dev/null || true)
|
|
73
|
+
fi
|
|
74
|
+
fi
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# Single call: pre_edit_hint (legacy, workdir channel) + pre_edit_join
|
|
78
|
+
# (throttled, operative-repo channel). Both are advisory and fail-open.
|
|
79
|
+
# Empty strings on the Python side are treated as "no hint" (falsy).
|
|
80
|
+
#
|
|
81
|
+
# Stderr routing (f1): quiet on the happy path; let stderr through only
|
|
82
|
+
# when BUILD_LOOP_RALLY_DEBUG=1 so diagnostics are available on demand
|
|
83
|
+
# without polluting the terminal by default.
|
|
84
|
+
if [ "${BUILD_LOOP_RALLY_DEBUG:-0}" = "1" ]; then
|
|
85
|
+
python3 "$PKG/hooks.py" pre-edit --workdir "$WORKDIR" --tool claude_code \
|
|
86
|
+
--file-path "$FILE_PATH" --command "$TOOL_CMD" || exit 0
|
|
87
|
+
else
|
|
88
|
+
python3 "$PKG/hooks.py" pre-edit --workdir "$WORKDIR" --tool claude_code \
|
|
89
|
+
--file-path "$FILE_PATH" --command "$TOOL_CMD" 2>/dev/null || exit 0
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
exit 0
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com>
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
# Deprecated alias; use session-start-rally-point.sh.
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
exec bash "$SCRIPT_DIR/session-start-rally-point.sh" "$@"
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
# Incremental architecture scan when manifest is missing or >24h old.
|
|
4
|
+
D="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
5
|
+
. "$D/_session_start_lib.sh"
|
|
6
|
+
W="${CLAUDE_PROJECT_DIR:-$PWD}"
|
|
7
|
+
[ -d "$W/.build-loop/architecture" ] && [ -f "$D/_arch_scan_bg.py" ] || exit 0
|
|
8
|
+
[ "$(bl_stale "$W/.build-loop/architecture/manifest.json" 86400)" = "yes" ] || exit 0
|
|
9
|
+
bl_fire_bg "$D/_arch_scan_bg.py" --workdir "$W"
|
|
10
|
+
exit 0
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
# Auto-install build-loop git hooks on session start (idempotent).
|
|
4
|
+
# Installs: pre-push (push-HOLD gate).
|
|
5
|
+
# Skips silently when: not inside a git repo, Python unavailable, hook
|
|
6
|
+
# source not found, or a foreign (non-build-loop) pre-push is already
|
|
7
|
+
# installed (requires --force to overwrite; we never force on auto-install).
|
|
8
|
+
PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-${CLAUDE_PROJECT_DIR:-$PWD}}"
|
|
9
|
+
cd "${CLAUDE_PROJECT_DIR:-$PWD}" 2>/dev/null || exit 0
|
|
10
|
+
git rev-parse --git-dir >/dev/null 2>&1 || exit 0
|
|
11
|
+
python3 "${PLUGIN_ROOT}/scripts/install_git_hooks.py" --install >/dev/null 2>&1 || true
|
|
12
|
+
exit 0
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
# Plugin-cache maintenance, fire-and-forget, HOST-AWARE. This hook runs on BOTH
|
|
4
|
+
# hosts — Claude (SessionStart) and Codex (hooks/hooks.json session_start); both
|
|
5
|
+
# set CLAUDE_PLUGIN_ROOT, but Codex's resolves under ~/.codex. So derive the host
|
|
6
|
+
# from that path and prune the RUNNING host's cache (never the other host's).
|
|
7
|
+
# 1. DRIFT — cached-install-behind-upstream check. Claude only (worker keys on
|
|
8
|
+
# ~/.claude/plugins).
|
|
9
|
+
# 2. PRUNE — auto-remove stale cache versions for the running host via the
|
|
10
|
+
# canonical engine scripts/prune_plugin_cache.py. Engine protects the
|
|
11
|
+
# in-use dir (CLAUDE_PLUGIN_ROOT, default-on) + installed pins
|
|
12
|
+
# (--protect-installed); re-fetched on demand, so prunes are
|
|
13
|
+
# reversible. Opt out: BUILDLOOP_NO_CACHE_GC=1.
|
|
14
|
+
D="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
15
|
+
. "$D/_session_start_lib.sh"
|
|
16
|
+
ROOT="${CLAUDE_PLUGIN_ROOT:-$D/..}"
|
|
17
|
+
case "$ROOT" in
|
|
18
|
+
*/.codex/*) HOST=codex ;;
|
|
19
|
+
*) HOST=claude ;;
|
|
20
|
+
esac
|
|
21
|
+
if [ "$HOST" = claude ] && [ -d "$HOME/.claude/plugins" ] && [ -f "$D/_plugin_drift_check_bg.py" ]; then
|
|
22
|
+
bl_fire_bg "$D/_plugin_drift_check_bg.py"
|
|
23
|
+
fi
|
|
24
|
+
if [ "${BUILDLOOP_NO_CACHE_GC:-}" != "1" ] && [ -f "$ROOT/scripts/prune_plugin_cache.py" ]; then
|
|
25
|
+
bl_fire_bg "$ROOT/scripts/prune_plugin_cache.py" --source "$ROOT" --host "$HOST" --apply --protect-installed
|
|
26
|
+
fi
|
|
27
|
+
exit 0
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
# Rally Point R2 announce + listen. Surfaces deltas/peers, then advances cursor.
|
|
4
|
+
#
|
|
5
|
+
# Codex-parity hardening (2026-06-07):
|
|
6
|
+
# When ``CLAUDE_PROJECT_DIR`` is unset AND ``$PWD`` is NOT a git repo
|
|
7
|
+
# (e.g. ``$HOME`` for a Claude Code launched outside a repo), do NOT
|
|
8
|
+
# write presence to the launch dir's room. The per-tool-use rally hook
|
|
9
|
+
# (pre-edit-rally-point.sh, also registered on the Bash matcher) joins
|
|
10
|
+
# the OPERATIVE repo's room on the first tool-use, recovering from a
|
|
11
|
+
# cross-repo launch without polluting the home / ``_unscoped`` room.
|
|
12
|
+
D="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
13
|
+
. "$D/_session_start_lib.sh"
|
|
14
|
+
W="${CLAUDE_PROJECT_DIR:-$PWD}"
|
|
15
|
+
PKG="$(dirname "$D")/scripts/rally_point"
|
|
16
|
+
[ -d "$PKG" ] || exit 0
|
|
17
|
+
|
|
18
|
+
# Guard: if CLAUDE_PROJECT_DIR is unset and $PWD is not a git repo, the
|
|
19
|
+
# launch cwd is not a rally room — defer the join to pre-edit (operative
|
|
20
|
+
# repo resolution from the first Edit/Write/Bash). This is the no-op path.
|
|
21
|
+
if [ -z "${CLAUDE_PROJECT_DIR:-}" ]; then
|
|
22
|
+
if ! git -C "$W" rev-parse --git-dir >/dev/null 2>&1; then
|
|
23
|
+
exit 0
|
|
24
|
+
fi
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
# Step 1: checkpoint_read restore line (verbose: surface delta if any).
|
|
28
|
+
# ``session-start-safe`` no-ops cleanly when the resolved workdir is not a
|
|
29
|
+
# git repo (belt-and-braces — the shell guard above already filters).
|
|
30
|
+
python3 "$PKG/hooks.py" session-start-safe --workdir "$W" --verbose 2>/dev/null || true
|
|
31
|
+
|
|
32
|
+
# Step 2: probe announce + listen (fully detached watcher).
|
|
33
|
+
if [ "${BUILD_LOOP_RALLY_POINT_SKIP_WATCH:-}" = "1" ]; then
|
|
34
|
+
[ -f "$PKG/session_probe.py" ] && WORKDIR="$W" python3 "$PKG/session_probe.py" \
|
|
35
|
+
--workdir "$W" --tool claude_code --mode hook >/dev/null 2>&1 || true
|
|
36
|
+
else
|
|
37
|
+
[ -f "$PKG/session_probe.py" ] && WORKDIR="$W" python3 "$PKG/session_probe.py" \
|
|
38
|
+
--workdir "$W" --tool claude_code --mode hook --start-watch >/dev/null 2>&1 || true
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# Step 3: advance cursor past probe's own writes (silent; same script, no VERBOSE).
|
|
42
|
+
python3 "$PKG/hooks.py" session-start-advance --workdir "$W" 2>/dev/null || true
|
|
43
|
+
|
|
44
|
+
exit 0
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
# Retrieval warmup + silent-failure canary. Fire-and-forget.
|
|
4
|
+
set +e
|
|
5
|
+
D="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
. "$D/_session_start_lib.sh"
|
|
7
|
+
W="${CLAUDE_PROJECT_DIR:-$PWD}"
|
|
8
|
+
S="${CLAUDE_PLUGIN_ROOT:-$W}/scripts"
|
|
9
|
+
LD="${XDG_STATE_HOME:-$HOME/.local/state}/build-loop"
|
|
10
|
+
mkdir -p "$LD" 2>/dev/null
|
|
11
|
+
|
|
12
|
+
# Ollama daemon ping (warms loaded models in RAM).
|
|
13
|
+
( command -v ollama >/dev/null 2>&1 && nohup ollama list </dev/null >/dev/null 2>&1 & )
|
|
14
|
+
|
|
15
|
+
# Long-running rerank + embed daemons (single-flight).
|
|
16
|
+
bl_spawn_daemon "$S/rerank_daemon.py" "${RERANK_DAEMON_PORT:-8765}" rerank-daemon rerank-daemon "$LD"
|
|
17
|
+
bl_spawn_daemon "$S/embed_daemon.py" "${EMBED_DAEMON_PORT:-8766}" embed-daemon embed-daemon "$LD"
|
|
18
|
+
|
|
19
|
+
# Health canary -> state.json + rotating log.
|
|
20
|
+
[ -f "$S/backend_health.py" ] && nohup python3 "$S/backend_health.py" \
|
|
21
|
+
--workdir "$W" --include-retrieval --quiet \
|
|
22
|
+
</dev/null >>"$LD/retrieval-health.log" 2>&1 & disown 2>/dev/null || true
|
|
23
|
+
|
|
24
|
+
exit 0
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
# Worktree GC: remove merged+clean stale worktrees/branches, AUTO-PRUNE orphans.
|
|
4
|
+
# ACT mode (bundle-first removal of merged worktrees + branches) is ON by default
|
|
5
|
+
# so cross-run residue self-heals (intent.md A5); set BUILDLOOP_GC_ACT=0 to opt out
|
|
6
|
+
# (report-only). Locked, dirty, or unmerged worktrees are never removed either way.
|
|
7
|
+
cd "${CLAUDE_PROJECT_DIR:-$PWD}" 2>/dev/null || exit 0
|
|
8
|
+
git rev-parse --git-dir >/dev/null 2>&1 || exit 0
|
|
9
|
+
R=".build-loop/worktree-gc-last.txt"
|
|
10
|
+
mkdir -p "$(dirname "$R")"
|
|
11
|
+
_bundle_done=0
|
|
12
|
+
|
|
13
|
+
# Rally exclusion (defense-in-depth, optional). If `rally` is on PATH and
|
|
14
|
+
# `rally sessions --json` returns a list of live sessions, collect their
|
|
15
|
+
# `cwd` paths so we can skip any worktree owned by an active session in
|
|
16
|
+
# addition to the path-prefix guard below. Rally owns its own worktree
|
|
17
|
+
# lifecycle; build-loop's GC must never reap a rally-owned worktree (force-
|
|
18
|
+
# removing it deletes the cwd of a live agent process and every subsequent
|
|
19
|
+
# hook fails with posix_spawn ENOENT). The path-prefix exclusion is the
|
|
20
|
+
# PRIMARY guard and works even when `rally` is not installed.
|
|
21
|
+
_rally_cwds=""
|
|
22
|
+
if command -v rally >/dev/null 2>&1; then
|
|
23
|
+
_rally_cwds=$(rally sessions --json 2>/dev/null \
|
|
24
|
+
| awk 'match($0, /"cwd"[[:space:]]*:[[:space:]]*"[^"]+"/){
|
|
25
|
+
s=substr($0,RSTART,RLENGTH);
|
|
26
|
+
sub(/^"cwd"[[:space:]]*:[[:space:]]*"/,"",s);
|
|
27
|
+
sub(/"$/,"",s);
|
|
28
|
+
print s
|
|
29
|
+
}' 2>/dev/null || true)
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
{
|
|
33
|
+
printf '# Worktree GC report — %s\n\n## Stale candidates (REPORT-ONLY)\n' "$(date -u +%FT%TZ)"
|
|
34
|
+
|
|
35
|
+
# Collect candidates; in ACT mode, acted-on items are echoed inline (ACT:removed)
|
|
36
|
+
# and split into their own report section by the awk pass below.
|
|
37
|
+
git worktree list --porcelain 2>/dev/null \
|
|
38
|
+
| awk '/^worktree /{p=$2} /^branch /{b=$2; sub("refs/heads/","",b); if(p && b){print p" "b}; p=""; b=""}' \
|
|
39
|
+
| while read -r path branch; do
|
|
40
|
+
[ "$branch" = main ] && continue
|
|
41
|
+
# Rally-owned worktrees are NEVER touched by build-loop's GC.
|
|
42
|
+
# Primary guard: path-prefix exclusion (works without rally on PATH).
|
|
43
|
+
case "$path" in
|
|
44
|
+
*/.rally/worktrees/*)
|
|
45
|
+
echo " SKIP:rally-owned $path branch=$branch"
|
|
46
|
+
continue
|
|
47
|
+
;;
|
|
48
|
+
esac
|
|
49
|
+
# Defense-in-depth: live rally session cwd cross-check.
|
|
50
|
+
if [ -n "$_rally_cwds" ]; then
|
|
51
|
+
_skip=0
|
|
52
|
+
while IFS= read -r _cwd; do
|
|
53
|
+
[ -z "$_cwd" ] && continue
|
|
54
|
+
if [ "$_cwd" = "$path" ]; then
|
|
55
|
+
_skip=1
|
|
56
|
+
break
|
|
57
|
+
fi
|
|
58
|
+
done <<EOF
|
|
59
|
+
$_rally_cwds
|
|
60
|
+
EOF
|
|
61
|
+
if [ "$_skip" = "1" ]; then
|
|
62
|
+
echo " SKIP:rally-live-session $path branch=$branch"
|
|
63
|
+
continue
|
|
64
|
+
fi
|
|
65
|
+
fi
|
|
66
|
+
git merge-base --is-ancestor "$branch" main 2>/dev/null || continue
|
|
67
|
+
dirty=$(git -C "$path" status --porcelain 2>/dev/null | wc -l | tr -d ' ')
|
|
68
|
+
locked=unlocked
|
|
69
|
+
[ -f "$path/.git" ] && grep -q locked "$path/.git" 2>/dev/null && locked=locked
|
|
70
|
+
echo " $path branch=$branch merged=yes dirty=$dirty $locked"
|
|
71
|
+
|
|
72
|
+
if [ "${BUILDLOOP_GC_ACT:-1}" = "1" ] && [ "$dirty" = "0" ] && [ "$locked" = "unlocked" ]; then
|
|
73
|
+
# Reversibility: one bundle per run, created before first removal.
|
|
74
|
+
if [ "$_bundle_done" = "0" ]; then
|
|
75
|
+
mkdir -p ".build-loop/bundles"
|
|
76
|
+
git bundle create ".build-loop/bundles/gc-$(date -u +%Y%m%dT%H%M%SZ).bundle" --all >/dev/null 2>&1
|
|
77
|
+
_bundle_done=1
|
|
78
|
+
fi
|
|
79
|
+
git worktree remove -f -f "$path" >/dev/null 2>&1
|
|
80
|
+
git branch -D "$branch" >/dev/null 2>&1
|
|
81
|
+
echo " ACT:removed $path branch=$branch"
|
|
82
|
+
fi
|
|
83
|
+
done
|
|
84
|
+
|
|
85
|
+
printf '\n## Auto-prune (Git-proven orphans only)\n'
|
|
86
|
+
git worktree prune -v 2>/dev/null
|
|
87
|
+
} > "$R" 2>&1
|
|
88
|
+
|
|
89
|
+
# Rewrite report to split REPORT-ONLY from Auto-removed sections cleanly.
|
|
90
|
+
if [ "${BUILDLOOP_GC_ACT:-1}" = "1" ] && grep -q 'ACT:removed' "$R" 2>/dev/null; then
|
|
91
|
+
tmp=$(mktemp)
|
|
92
|
+
awk '
|
|
93
|
+
/^## Stale candidates/ { in_stale=1 }
|
|
94
|
+
in_stale && / ACT:removed / {
|
|
95
|
+
sub(" ACT:removed ", " ")
|
|
96
|
+
if (!printed_hdr) { removed=removed "\n## Auto-removed (merged, bundled)\n"; printed_hdr=1 }
|
|
97
|
+
removed=removed $0 "\n"
|
|
98
|
+
next
|
|
99
|
+
}
|
|
100
|
+
{ print }
|
|
101
|
+
END { printf "%s", removed }
|
|
102
|
+
' "$R" > "$tmp" && mv "$tmp" "$R"
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
exit 0
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com>
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
# Deprecated alias; use test_rally_point_hooks.sh.
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
exec bash "$SCRIPT_DIR/test_rally_point_hooks.sh" "$@"
|