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,159 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# scope-infer.sh — Infer scope tags for lessons missing them
|
|
3
|
+
# Reads lesson content and applies heuristics to propose scope tags.
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
SCRIPT_DIR="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)"
|
|
7
|
+
|
|
8
|
+
# Defaults
|
|
9
|
+
LESSONS_DIR="$SCRIPT_DIR/../docs/lessons"
|
|
10
|
+
DRY_RUN=true
|
|
11
|
+
APPLY=false
|
|
12
|
+
|
|
13
|
+
usage() {
|
|
14
|
+
cat <<USAGE
|
|
15
|
+
Usage: scope-infer.sh [--dir <lessons-dir>] [--dry-run] [--apply]
|
|
16
|
+
|
|
17
|
+
Infer scope tags for lesson files that don't have a scope: field.
|
|
18
|
+
|
|
19
|
+
Options:
|
|
20
|
+
--dir <path> Lessons directory (default: docs/lessons/)
|
|
21
|
+
--dry-run Show proposed scope without modifying files (default)
|
|
22
|
+
--apply Write scope field into lesson files
|
|
23
|
+
--help, -h Show this help
|
|
24
|
+
USAGE
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
while [[ $# -gt 0 ]]; do
|
|
28
|
+
case "$1" in
|
|
29
|
+
--dir) LESSONS_DIR="$2"; shift 2 ;;
|
|
30
|
+
--dry-run) DRY_RUN=true; APPLY=false; shift ;;
|
|
31
|
+
--apply) APPLY=true; DRY_RUN=false; shift ;;
|
|
32
|
+
--help|-h) usage; exit 0 ;;
|
|
33
|
+
*) echo "Unknown flag: $1" >&2; usage >&2; exit 1 ;;
|
|
34
|
+
esac
|
|
35
|
+
done
|
|
36
|
+
|
|
37
|
+
# Counters
|
|
38
|
+
total=0
|
|
39
|
+
inferred=0
|
|
40
|
+
skipped=0
|
|
41
|
+
count_universal=0
|
|
42
|
+
count_language=0
|
|
43
|
+
count_domain=0
|
|
44
|
+
count_project=0
|
|
45
|
+
|
|
46
|
+
infer_scope() {
|
|
47
|
+
local file="$1"
|
|
48
|
+
local content
|
|
49
|
+
content=$(cat "$file")
|
|
50
|
+
|
|
51
|
+
# Domain signals (check title + body)
|
|
52
|
+
local title_and_body
|
|
53
|
+
title_and_body=$(echo "$content" | tr '[:upper:]' '[:lower:]')
|
|
54
|
+
|
|
55
|
+
# Domain: ha-aria
|
|
56
|
+
if echo "$title_and_body" | grep -qE '(home assistant|\bha\b|entity.*area|automation.*trigger|hass|ha-aria)'; then
|
|
57
|
+
echo "domain:ha-aria"
|
|
58
|
+
return
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
# Domain: telegram
|
|
62
|
+
if echo "$title_and_body" | grep -qE '(telegram|bot.*poll|getupdates|chat_id|telegram-brief|telegram-capture)'; then
|
|
63
|
+
echo "domain:telegram"
|
|
64
|
+
return
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
# Domain: notion
|
|
68
|
+
if echo "$title_and_body" | grep -qE '(\bnotion\b|notion.*sync|notion.*database|notion-tools|notion_api)'; then
|
|
69
|
+
echo "domain:notion"
|
|
70
|
+
return
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
# Domain: ollama
|
|
74
|
+
if echo "$title_and_body" | grep -qE '(\bollama\b|ollama.*queue|local.*llm|ollama-queue)'; then
|
|
75
|
+
echo "domain:ollama"
|
|
76
|
+
return
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
# Framework: systemd
|
|
80
|
+
if echo "$title_and_body" | grep -qE '(systemd|systemctl|\.service|\.timer|journalctl|envfile)'; then
|
|
81
|
+
echo "framework:systemd"
|
|
82
|
+
return
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
# Framework: pytest
|
|
86
|
+
if echo "$title_and_body" | grep -qE '(\bpytest\b|conftest|fixture|parametrize)'; then
|
|
87
|
+
echo "framework:pytest"
|
|
88
|
+
return
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
# Framework: preact/jsx
|
|
92
|
+
if echo "$title_and_body" | grep -qE '(\bpreact\b|\bjsx\b|esbuild.*jsx|jsx.*factory)'; then
|
|
93
|
+
echo "framework:preact"
|
|
94
|
+
return
|
|
95
|
+
fi
|
|
96
|
+
|
|
97
|
+
# Project-specific: autonomous-coding-toolkit
|
|
98
|
+
if echo "$title_and_body" | grep -qE '(run-plan|quality.gate|lesson-check|mab-run|batch.*audit|ralph.*loop|headless.*mode)'; then
|
|
99
|
+
echo "project:autonomous-coding-toolkit"
|
|
100
|
+
return
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
# Language: check the languages field
|
|
104
|
+
local languages
|
|
105
|
+
languages=$(sed -n '/^---$/,/^---$/{ /^languages:/p; }' "$file" 2>/dev/null | head -1)
|
|
106
|
+
languages=$(echo "$languages" | sed 's/languages:[[:space:]]*//' | tr -d '[]' | tr ',' ' ' | xargs)
|
|
107
|
+
|
|
108
|
+
if [[ "$languages" == "python" ]]; then
|
|
109
|
+
echo "language:python"
|
|
110
|
+
return
|
|
111
|
+
elif [[ "$languages" == "shell" ]]; then
|
|
112
|
+
echo "language:bash"
|
|
113
|
+
return
|
|
114
|
+
elif [[ "$languages" == "javascript" || "$languages" == "typescript" ]]; then
|
|
115
|
+
echo "language:javascript"
|
|
116
|
+
return
|
|
117
|
+
fi
|
|
118
|
+
|
|
119
|
+
# No signals → universal
|
|
120
|
+
echo "universal"
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
for lesson_file in "$LESSONS_DIR"/[0-9]*.md; do
|
|
124
|
+
[[ -f "$lesson_file" ]] || continue
|
|
125
|
+
total=$((total + 1))
|
|
126
|
+
|
|
127
|
+
# Check if scope already present
|
|
128
|
+
if sed -n '/^---$/,/^---$/p' "$lesson_file" | grep -q '^scope:'; then
|
|
129
|
+
skipped=$((skipped + 1))
|
|
130
|
+
continue
|
|
131
|
+
fi
|
|
132
|
+
|
|
133
|
+
scope=$(infer_scope "$lesson_file")
|
|
134
|
+
inferred=$((inferred + 1))
|
|
135
|
+
|
|
136
|
+
# Count by type
|
|
137
|
+
case "$scope" in
|
|
138
|
+
universal) count_universal=$((count_universal + 1)) ;;
|
|
139
|
+
language:*) count_language=$((count_language + 1)) ;;
|
|
140
|
+
domain:*) count_domain=$((count_domain + 1)) ;;
|
|
141
|
+
project:*) count_project=$((count_project + 1)) ;;
|
|
142
|
+
framework:*) count_language=$((count_language + 1)) ;; # group with language
|
|
143
|
+
esac
|
|
144
|
+
|
|
145
|
+
basename_file=$(basename "$lesson_file")
|
|
146
|
+
|
|
147
|
+
if [[ "$APPLY" == true ]]; then
|
|
148
|
+
# Insert scope: [$scope] after the languages: line in YAML frontmatter
|
|
149
|
+
sed -i "/^languages:/a scope: [$scope]" "$lesson_file"
|
|
150
|
+
echo " APPLIED: $basename_file → scope: [$scope]"
|
|
151
|
+
else
|
|
152
|
+
echo " PROPOSED: $basename_file → scope: [$scope]"
|
|
153
|
+
fi
|
|
154
|
+
done
|
|
155
|
+
|
|
156
|
+
echo ""
|
|
157
|
+
echo "Inferred scope for $inferred lessons: $count_universal universal, $count_domain domain-specific, $count_language language/framework, $count_project project-specific"
|
|
158
|
+
echo "Skipped $skipped lessons (already have scope)"
|
|
159
|
+
echo "Total: $total lessons scanned"
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# Ralph Loop Setup Script
|
|
4
|
+
# Creates state file for in-session Ralph loop
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
# Parse arguments
|
|
9
|
+
PROMPT_PARTS=()
|
|
10
|
+
MAX_ITERATIONS=0
|
|
11
|
+
COMPLETION_PROMISE="null"
|
|
12
|
+
|
|
13
|
+
# Parse options and positional arguments
|
|
14
|
+
while [[ $# -gt 0 ]]; do
|
|
15
|
+
case $1 in
|
|
16
|
+
-h|--help)
|
|
17
|
+
cat << 'HELP_EOF'
|
|
18
|
+
Ralph Loop - Interactive self-referential development loop
|
|
19
|
+
|
|
20
|
+
USAGE:
|
|
21
|
+
/ralph-loop [PROMPT...] [OPTIONS]
|
|
22
|
+
|
|
23
|
+
ARGUMENTS:
|
|
24
|
+
PROMPT... Initial prompt to start the loop (can be multiple words without quotes)
|
|
25
|
+
|
|
26
|
+
OPTIONS:
|
|
27
|
+
--max-iterations <n> Maximum iterations before auto-stop (default: unlimited)
|
|
28
|
+
--completion-promise '<text>' Promise phrase (USE QUOTES for multi-word)
|
|
29
|
+
-h, --help Show this help message
|
|
30
|
+
|
|
31
|
+
DESCRIPTION:
|
|
32
|
+
Starts a Ralph Loop in your CURRENT session. The stop hook prevents
|
|
33
|
+
exit and feeds your output back as input until completion or iteration limit.
|
|
34
|
+
|
|
35
|
+
To signal completion, you must output: <promise>YOUR_PHRASE</promise>
|
|
36
|
+
|
|
37
|
+
EXAMPLES:
|
|
38
|
+
/ralph-loop Build a todo API --completion-promise 'DONE' --max-iterations 20
|
|
39
|
+
/ralph-loop --max-iterations 10 Fix the auth bug
|
|
40
|
+
/ralph-loop Refactor cache layer (runs forever)
|
|
41
|
+
|
|
42
|
+
STOPPING:
|
|
43
|
+
Only by reaching --max-iterations or detecting --completion-promise
|
|
44
|
+
No manual stop - Ralph runs infinitely by default!
|
|
45
|
+
HELP_EOF
|
|
46
|
+
exit 0
|
|
47
|
+
;;
|
|
48
|
+
--max-iterations)
|
|
49
|
+
if [[ -z "${2:-}" ]]; then
|
|
50
|
+
echo "Error: --max-iterations requires a number argument" >&2
|
|
51
|
+
exit 1
|
|
52
|
+
fi
|
|
53
|
+
if ! [[ "$2" =~ ^[0-9]+$ ]]; then
|
|
54
|
+
echo "Error: --max-iterations must be a positive integer or 0, got: $2" >&2
|
|
55
|
+
exit 1
|
|
56
|
+
fi
|
|
57
|
+
MAX_ITERATIONS="$2"
|
|
58
|
+
shift 2
|
|
59
|
+
;;
|
|
60
|
+
--completion-promise)
|
|
61
|
+
if [[ -z "${2:-}" ]]; then
|
|
62
|
+
echo "Error: --completion-promise requires a text argument" >&2
|
|
63
|
+
exit 1
|
|
64
|
+
fi
|
|
65
|
+
COMPLETION_PROMISE="$2"
|
|
66
|
+
shift 2
|
|
67
|
+
;;
|
|
68
|
+
*)
|
|
69
|
+
PROMPT_PARTS+=("$1")
|
|
70
|
+
shift
|
|
71
|
+
;;
|
|
72
|
+
esac
|
|
73
|
+
done
|
|
74
|
+
|
|
75
|
+
# Join all prompt parts with spaces
|
|
76
|
+
PROMPT="${PROMPT_PARTS[*]}"
|
|
77
|
+
|
|
78
|
+
# Validate prompt is non-empty
|
|
79
|
+
if [[ -z "$PROMPT" ]]; then
|
|
80
|
+
echo "Error: No prompt provided" >&2
|
|
81
|
+
echo "Usage: /ralph-loop PROMPT [--max-iterations N] [--completion-promise TEXT]" >&2
|
|
82
|
+
exit 1
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
# Create state file for stop hook (markdown with YAML frontmatter)
|
|
86
|
+
mkdir -p .claude
|
|
87
|
+
|
|
88
|
+
# Quote completion promise for YAML safely via jq JSON encoding.
|
|
89
|
+
# Note: jq produces JSON-escaped output (\n, \t become literal two-char sequences).
|
|
90
|
+
# This is correct for YAML scalar values parsed by the stop hook's sed-based reader.
|
|
91
|
+
if [[ -n "$COMPLETION_PROMISE" ]] && [[ "$COMPLETION_PROMISE" != "null" ]]; then
|
|
92
|
+
COMPLETION_PROMISE_YAML=$(jq -n --arg cp "$COMPLETION_PROMISE" '$cp')
|
|
93
|
+
else
|
|
94
|
+
COMPLETION_PROMISE_YAML="null"
|
|
95
|
+
fi
|
|
96
|
+
|
|
97
|
+
cat > .claude/ralph-loop.local.md <<EOF
|
|
98
|
+
---
|
|
99
|
+
active: true
|
|
100
|
+
iteration: 1
|
|
101
|
+
max_iterations: $MAX_ITERATIONS
|
|
102
|
+
completion_promise: $COMPLETION_PROMISE_YAML
|
|
103
|
+
started_at: "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
$PROMPT
|
|
107
|
+
EOF
|
|
108
|
+
|
|
109
|
+
# Output setup message
|
|
110
|
+
cat <<EOF
|
|
111
|
+
Ralph loop activated in this session!
|
|
112
|
+
|
|
113
|
+
Iteration: 1
|
|
114
|
+
Max iterations: $(if [[ $MAX_ITERATIONS -gt 0 ]]; then echo $MAX_ITERATIONS; else echo "unlimited"; fi)
|
|
115
|
+
Completion promise: $(if [[ "$COMPLETION_PROMISE" != "null" ]]; then echo "$COMPLETION_PROMISE (ONLY output when TRUE - do not lie!)"; else echo "none (runs forever)"; fi)
|
|
116
|
+
|
|
117
|
+
The stop hook is now active. When you try to exit, the SAME PROMPT will be
|
|
118
|
+
fed back to you. You'll see your previous work in files, creating a
|
|
119
|
+
self-referential loop where you iteratively improve on the same task.
|
|
120
|
+
|
|
121
|
+
To monitor: head -10 .claude/ralph-loop.local.md
|
|
122
|
+
|
|
123
|
+
WARNING: This loop cannot be stopped manually! It will run infinitely
|
|
124
|
+
unless you set --max-iterations or --completion-promise.
|
|
125
|
+
EOF
|
|
126
|
+
|
|
127
|
+
# Output the initial prompt if provided
|
|
128
|
+
if [[ -n "$PROMPT" ]]; then
|
|
129
|
+
echo ""
|
|
130
|
+
echo "$PROMPT"
|
|
131
|
+
fi
|
|
132
|
+
|
|
133
|
+
# Display completion promise requirements if set
|
|
134
|
+
if [[ "$COMPLETION_PROMISE" != "null" ]]; then
|
|
135
|
+
echo ""
|
|
136
|
+
echo "======================================================="
|
|
137
|
+
echo "CRITICAL - Ralph Loop Completion Promise"
|
|
138
|
+
echo "======================================================="
|
|
139
|
+
echo ""
|
|
140
|
+
echo "To complete this loop, output this EXACT text:"
|
|
141
|
+
echo " <promise>$COMPLETION_PROMISE</promise>"
|
|
142
|
+
echo ""
|
|
143
|
+
echo "STRICT REQUIREMENTS (DO NOT VIOLATE):"
|
|
144
|
+
echo " - Use <promise> XML tags EXACTLY as shown above"
|
|
145
|
+
echo " - The statement MUST be completely and unequivocally TRUE"
|
|
146
|
+
echo " - Do NOT output false statements to exit the loop"
|
|
147
|
+
echo " - Do NOT lie even if you think you should exit"
|
|
148
|
+
echo ""
|
|
149
|
+
echo "IMPORTANT - Do not circumvent the loop:"
|
|
150
|
+
echo " Even if you believe you're stuck, the task is impossible,"
|
|
151
|
+
echo " or you've been running too long - you MUST NOT output a"
|
|
152
|
+
echo " false promise statement. The loop is designed to continue"
|
|
153
|
+
echo " until the promise is GENUINELY TRUE. Trust the process."
|
|
154
|
+
echo "======================================================="
|
|
155
|
+
fi
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# telemetry.sh — Local telemetry capture, dashboard, export, and import
|
|
3
|
+
#
|
|
4
|
+
# Usage:
|
|
5
|
+
# telemetry.sh record --project-root <dir> [--batch-number N] [--passed true|false] ...
|
|
6
|
+
# telemetry.sh show --project-root <dir>
|
|
7
|
+
# telemetry.sh export --project-root <dir>
|
|
8
|
+
# telemetry.sh import --project-root <dir> <file>
|
|
9
|
+
# telemetry.sh reset --project-root <dir> --yes
|
|
10
|
+
set -euo pipefail
|
|
11
|
+
|
|
12
|
+
SCRIPT_DIR="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)"
|
|
13
|
+
source "$SCRIPT_DIR/lib/common.sh"
|
|
14
|
+
|
|
15
|
+
PROJECT_ROOT=""
|
|
16
|
+
SUBCOMMAND=""
|
|
17
|
+
|
|
18
|
+
# --- Parse top-level ---
|
|
19
|
+
SUBCOMMAND="${1:-}"
|
|
20
|
+
shift || true
|
|
21
|
+
|
|
22
|
+
# Parse remaining args
|
|
23
|
+
BATCH_NUMBER=""
|
|
24
|
+
PASSED=""
|
|
25
|
+
STRATEGY=""
|
|
26
|
+
DURATION=""
|
|
27
|
+
COST=""
|
|
28
|
+
TEST_DELTA=""
|
|
29
|
+
LESSONS_TRIGGERED=""
|
|
30
|
+
PLAN_QUALITY=""
|
|
31
|
+
BATCH_TYPE=""
|
|
32
|
+
CONFIRM_YES=false
|
|
33
|
+
|
|
34
|
+
while [[ $# -gt 0 ]]; do
|
|
35
|
+
case "$1" in
|
|
36
|
+
--project-root) PROJECT_ROOT="${2:-}"; shift 2 ;;
|
|
37
|
+
--batch-number) BATCH_NUMBER="${2:-}"; shift 2 ;;
|
|
38
|
+
--passed) PASSED="${2:-}"; shift 2 ;;
|
|
39
|
+
--strategy) STRATEGY="${2:-}"; shift 2 ;;
|
|
40
|
+
--duration) DURATION="${2:-}"; shift 2 ;;
|
|
41
|
+
--cost) COST="${2:-}"; shift 2 ;;
|
|
42
|
+
--test-delta) TEST_DELTA="${2:-}"; shift 2 ;;
|
|
43
|
+
--lessons-triggered) LESSONS_TRIGGERED="${2:-}"; shift 2 ;;
|
|
44
|
+
--plan-quality) PLAN_QUALITY="${2:-}"; shift 2 ;;
|
|
45
|
+
--batch-type) BATCH_TYPE="${2:-}"; shift 2 ;;
|
|
46
|
+
--yes) CONFIRM_YES=true; shift ;;
|
|
47
|
+
--help|-h) echo "Usage: telemetry.sh <record|show|export|import|reset> --project-root <dir> [options]"; exit 0 ;;
|
|
48
|
+
*)
|
|
49
|
+
# Positional arg (for import file)
|
|
50
|
+
if [[ -z "${IMPORT_FILE:-}" ]]; then
|
|
51
|
+
IMPORT_FILE="$1"
|
|
52
|
+
fi
|
|
53
|
+
shift ;;
|
|
54
|
+
esac
|
|
55
|
+
done
|
|
56
|
+
|
|
57
|
+
if [[ -z "$PROJECT_ROOT" ]]; then
|
|
58
|
+
echo "telemetry: --project-root is required" >&2
|
|
59
|
+
exit 1
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
TELEMETRY_FILE="$PROJECT_ROOT/logs/telemetry.jsonl"
|
|
63
|
+
|
|
64
|
+
case "$SUBCOMMAND" in
|
|
65
|
+
record)
|
|
66
|
+
mkdir -p "$PROJECT_ROOT/logs"
|
|
67
|
+
# Coerce numeric fields to prevent jq tonumber failures on empty strings
|
|
68
|
+
BATCH_NUMBER="${BATCH_NUMBER:-0}"; BATCH_NUMBER="${BATCH_NUMBER:-0}"
|
|
69
|
+
DURATION="${DURATION:-0}"; COST="${COST:-0}"; TEST_DELTA="${TEST_DELTA:-0}"
|
|
70
|
+
jq -cn \
|
|
71
|
+
--arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
72
|
+
--arg bn "${BATCH_NUMBER:-0}" \
|
|
73
|
+
--arg passed "${PASSED:-false}" \
|
|
74
|
+
--arg strategy "${STRATEGY:-unknown}" \
|
|
75
|
+
--arg duration "${DURATION:-0}" \
|
|
76
|
+
--arg cost "${COST:-0}" \
|
|
77
|
+
--arg td "${TEST_DELTA:-0}" \
|
|
78
|
+
--arg lt "${LESSONS_TRIGGERED:-}" \
|
|
79
|
+
--arg pq "${PLAN_QUALITY:-}" \
|
|
80
|
+
--arg bt "${BATCH_TYPE:-unknown}" \
|
|
81
|
+
--arg pt "$(detect_project_type "$PROJECT_ROOT")" \
|
|
82
|
+
'{
|
|
83
|
+
timestamp: $ts,
|
|
84
|
+
project_type: $pt,
|
|
85
|
+
batch_type: $bt,
|
|
86
|
+
batch_number: ($bn | tonumber),
|
|
87
|
+
passed_gate: ($passed == "true"),
|
|
88
|
+
strategy: $strategy,
|
|
89
|
+
duration_seconds: ($duration | tonumber),
|
|
90
|
+
cost_usd: ($cost | tonumber),
|
|
91
|
+
test_count_delta: ($td | tonumber),
|
|
92
|
+
lessons_triggered: (if $lt == "" then [] else ($lt | split(",")) end),
|
|
93
|
+
plan_quality_score: (if $pq == "" then null else ($pq | tonumber) end)
|
|
94
|
+
}' >> "$TELEMETRY_FILE"
|
|
95
|
+
echo "telemetry: recorded batch $BATCH_NUMBER"
|
|
96
|
+
;;
|
|
97
|
+
|
|
98
|
+
show)
|
|
99
|
+
echo "Autonomous Coding Toolkit — Telemetry Dashboard"
|
|
100
|
+
echo "════════════════════════════════════════════════"
|
|
101
|
+
echo ""
|
|
102
|
+
|
|
103
|
+
if [[ ! -f "$TELEMETRY_FILE" ]] || [[ ! -s "$TELEMETRY_FILE" ]]; then
|
|
104
|
+
echo "No telemetry data yet. Run some batches first."
|
|
105
|
+
exit 0
|
|
106
|
+
fi
|
|
107
|
+
|
|
108
|
+
# Summary stats
|
|
109
|
+
total=$(wc -l < "$TELEMETRY_FILE")
|
|
110
|
+
passed=$(jq -s '[.[] | select(.passed_gate == true)] | length' "$TELEMETRY_FILE")
|
|
111
|
+
total_cost=$(jq -s '[.[].cost_usd] | add // 0' "$TELEMETRY_FILE")
|
|
112
|
+
total_duration=$(jq -s '[.[].duration_seconds] | add // 0' "$TELEMETRY_FILE")
|
|
113
|
+
avg_cost=$(jq -s 'if length > 0 then ([.[].cost_usd] | add) / length else 0 end' "$TELEMETRY_FILE")
|
|
114
|
+
|
|
115
|
+
echo "Runs: $total batches"
|
|
116
|
+
if [[ "$total" -gt 0 ]]; then
|
|
117
|
+
pct=$((passed * 100 / total))
|
|
118
|
+
echo "Success rate: ${pct}% ($passed/$total passed gate on first attempt)"
|
|
119
|
+
fi
|
|
120
|
+
printf "Total cost: \$%.2f (\$%.2f/batch average)\n" "$total_cost" "$avg_cost"
|
|
121
|
+
hours=$(awk "BEGIN {printf \"%.1f\", $total_duration / 3600}")
|
|
122
|
+
echo "Total time: ${hours} hours"
|
|
123
|
+
|
|
124
|
+
# Strategy performance
|
|
125
|
+
echo ""
|
|
126
|
+
echo "Strategy Performance:"
|
|
127
|
+
jq -s '
|
|
128
|
+
group_by(.strategy) | .[] |
|
|
129
|
+
{
|
|
130
|
+
strategy: .[0].strategy,
|
|
131
|
+
wins: [.[] | select(.passed_gate == true)] | length,
|
|
132
|
+
total: length
|
|
133
|
+
} |
|
|
134
|
+
" \(.strategy): \(.wins)/\(.total) (\(if .total > 0 then (.wins * 100 / .total) else 0 end)% win rate)"
|
|
135
|
+
' "$TELEMETRY_FILE" 2>/dev/null || echo " (no strategy data)"
|
|
136
|
+
|
|
137
|
+
# Top lesson hits
|
|
138
|
+
echo ""
|
|
139
|
+
echo "Top Lesson Hits:"
|
|
140
|
+
jq -s '
|
|
141
|
+
[.[].lessons_triggered | arrays | .[]] |
|
|
142
|
+
group_by(.) | map({lesson: .[0], count: length}) |
|
|
143
|
+
sort_by(-.count) | .[:5] |
|
|
144
|
+
.[] | " \(.lesson): \(.count) hits"
|
|
145
|
+
' "$TELEMETRY_FILE" 2>/dev/null || echo " (no lesson data)"
|
|
146
|
+
;;
|
|
147
|
+
|
|
148
|
+
export)
|
|
149
|
+
if [[ ! -f "$TELEMETRY_FILE" ]]; then
|
|
150
|
+
echo "No telemetry data to export." >&2
|
|
151
|
+
exit 1
|
|
152
|
+
fi
|
|
153
|
+
# Anonymize: remove timestamps precision, no file paths
|
|
154
|
+
jq -s '
|
|
155
|
+
[.[] | {
|
|
156
|
+
project_type,
|
|
157
|
+
batch_type,
|
|
158
|
+
passed_gate,
|
|
159
|
+
strategy,
|
|
160
|
+
duration_seconds,
|
|
161
|
+
cost_usd,
|
|
162
|
+
test_count_delta,
|
|
163
|
+
lessons_triggered,
|
|
164
|
+
plan_quality_score
|
|
165
|
+
}]
|
|
166
|
+
' "$TELEMETRY_FILE"
|
|
167
|
+
;;
|
|
168
|
+
|
|
169
|
+
import)
|
|
170
|
+
if [[ -z "${IMPORT_FILE:-}" || ! -f "${IMPORT_FILE:-}" ]]; then
|
|
171
|
+
echo "telemetry: import requires a file argument" >&2
|
|
172
|
+
exit 1
|
|
173
|
+
fi
|
|
174
|
+
echo "telemetry: import not yet implemented (planned for community sync)"
|
|
175
|
+
;;
|
|
176
|
+
|
|
177
|
+
reset)
|
|
178
|
+
if [[ "$CONFIRM_YES" != true ]]; then
|
|
179
|
+
echo "telemetry: use --yes to confirm reset" >&2
|
|
180
|
+
exit 1
|
|
181
|
+
fi
|
|
182
|
+
if [[ -f "$TELEMETRY_FILE" ]]; then
|
|
183
|
+
> "$TELEMETRY_FILE"
|
|
184
|
+
echo "telemetry: cleared $TELEMETRY_FILE"
|
|
185
|
+
else
|
|
186
|
+
echo "telemetry: no telemetry file to reset"
|
|
187
|
+
fi
|
|
188
|
+
;;
|
|
189
|
+
|
|
190
|
+
trust)
|
|
191
|
+
if [[ ! -f "$TELEMETRY_FILE" ]] || [[ ! -s "$TELEMETRY_FILE" ]]; then
|
|
192
|
+
echo '{"score":0,"level":"new","runs":0,"message":"No telemetry data yet"}'
|
|
193
|
+
exit 0
|
|
194
|
+
fi
|
|
195
|
+
|
|
196
|
+
jq -s '
|
|
197
|
+
def trust_level(score; runs):
|
|
198
|
+
if runs < 10 then "new"
|
|
199
|
+
elif score < 30 then "new"
|
|
200
|
+
elif score < 70 then "growing"
|
|
201
|
+
elif score < 90 then "trusted"
|
|
202
|
+
else "autonomous"
|
|
203
|
+
end;
|
|
204
|
+
|
|
205
|
+
length as $total |
|
|
206
|
+
([.[] | select(.passed_gate == true)] | length) as $passed |
|
|
207
|
+
(if $total > 0 then ($passed * 100 / $total) else 0 end) as $gate_rate |
|
|
208
|
+
$gate_rate as $score |
|
|
209
|
+
trust_level($score; $total) as $level |
|
|
210
|
+
{
|
|
211
|
+
score: $score,
|
|
212
|
+
level: $level,
|
|
213
|
+
runs: $total,
|
|
214
|
+
gate_pass_rate: $gate_rate,
|
|
215
|
+
default_mode: (
|
|
216
|
+
if $level == "new" then "human checkpoint every batch"
|
|
217
|
+
elif $level == "growing" then "headless with checkpoint every 3rd batch"
|
|
218
|
+
elif $level == "trusted" then "headless with notification on failures only"
|
|
219
|
+
else "full headless, post-run summary only"
|
|
220
|
+
end
|
|
221
|
+
)
|
|
222
|
+
}
|
|
223
|
+
' "$TELEMETRY_FILE"
|
|
224
|
+
;;
|
|
225
|
+
|
|
226
|
+
*)
|
|
227
|
+
echo "Usage: telemetry.sh <record|show|export|import|reset|trust> --project-root <dir>" >&2
|
|
228
|
+
exit 1
|
|
229
|
+
;;
|
|
230
|
+
esac
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# Test runner that executes all test-*.sh files in the same directory
|
|
5
|
+
# Reports per-file pass/fail and exits non-zero if any fail.
|
|
6
|
+
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
|
+
TOTAL=0
|
|
9
|
+
PASSED=0
|
|
10
|
+
FAILED=0
|
|
11
|
+
|
|
12
|
+
# Collect all test files
|
|
13
|
+
mapfile -t TEST_FILES < <(find "$SCRIPT_DIR" -maxdepth 1 -name "test-*.sh" -type f | sort)
|
|
14
|
+
|
|
15
|
+
if [[ ${#TEST_FILES[@]} -eq 0 ]]; then
|
|
16
|
+
echo "No test files found matching test-*.sh" >&2
|
|
17
|
+
exit 1
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
# Run each test
|
|
21
|
+
for test_file in "${TEST_FILES[@]}"; do
|
|
22
|
+
test_name="$(basename "$test_file")"
|
|
23
|
+
TOTAL=$((TOTAL + 1))
|
|
24
|
+
|
|
25
|
+
# Print header
|
|
26
|
+
echo "═══════════════════════════════════════════"
|
|
27
|
+
echo " Running: $test_name"
|
|
28
|
+
echo "═══════════════════════════════════════════"
|
|
29
|
+
|
|
30
|
+
# Run test and capture exit code
|
|
31
|
+
if bash "$test_file"; then
|
|
32
|
+
PASSED=$((PASSED + 1))
|
|
33
|
+
echo ""
|
|
34
|
+
else
|
|
35
|
+
FAILED=$((FAILED + 1))
|
|
36
|
+
echo ""
|
|
37
|
+
fi
|
|
38
|
+
done
|
|
39
|
+
|
|
40
|
+
# Print summary
|
|
41
|
+
echo "═══════════════════════════════════════════"
|
|
42
|
+
echo " TOTAL: $TOTAL test files"
|
|
43
|
+
echo " PASSED: $PASSED"
|
|
44
|
+
echo " FAILED: $FAILED"
|
|
45
|
+
echo "═══════════════════════════════════════════"
|
|
46
|
+
|
|
47
|
+
# Exit non-zero if any failed
|
|
48
|
+
if [[ $FAILED -gt 0 ]]; then
|
|
49
|
+
exit 1
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
exit 0
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# test-act-cli.sh — Tests for bin/act.js CLI router
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
7
|
+
source "$SCRIPT_DIR/test-helpers.sh"
|
|
8
|
+
|
|
9
|
+
ACT="$REPO_ROOT/bin/act.js"
|
|
10
|
+
|
|
11
|
+
# ---------------------------------------------------------------------------
|
|
12
|
+
# version command
|
|
13
|
+
# ---------------------------------------------------------------------------
|
|
14
|
+
version_output=$(node "$ACT" version 2>&1)
|
|
15
|
+
assert_contains "version outputs 'act v'" "act v" "$version_output"
|
|
16
|
+
|
|
17
|
+
# ---------------------------------------------------------------------------
|
|
18
|
+
# help command
|
|
19
|
+
# ---------------------------------------------------------------------------
|
|
20
|
+
help_output=$(node "$ACT" help 2>&1)
|
|
21
|
+
assert_contains "help outputs usage line" "Usage: act <command>" "$help_output"
|
|
22
|
+
assert_contains "help lists 'plan' command" "plan" "$help_output"
|
|
23
|
+
assert_contains "help lists 'gate' command" "gate" "$help_output"
|
|
24
|
+
|
|
25
|
+
# ---------------------------------------------------------------------------
|
|
26
|
+
# unknown command exits non-zero
|
|
27
|
+
# ---------------------------------------------------------------------------
|
|
28
|
+
assert_exit "nonexistent command exits 1" 1 node "$ACT" nonexistent-command
|
|
29
|
+
|
|
30
|
+
# ---------------------------------------------------------------------------
|
|
31
|
+
# validate routes to validate-all.sh (output contains "validate")
|
|
32
|
+
# ---------------------------------------------------------------------------
|
|
33
|
+
# validate-all.sh runs validators — we just confirm it was reached by checking
|
|
34
|
+
# that output contains "validate" (the script name / summary line).
|
|
35
|
+
validate_output=$(node "$ACT" validate 2>&1 || true)
|
|
36
|
+
assert_contains "validate routes to validate-all.sh" "validate" "$validate_output"
|
|
37
|
+
|
|
38
|
+
# ---------------------------------------------------------------------------
|
|
39
|
+
# lessons without subcommand exits non-zero and shows usage hint
|
|
40
|
+
# ---------------------------------------------------------------------------
|
|
41
|
+
lessons_exit=0
|
|
42
|
+
lessons_output=$(node "$ACT" lessons 2>&1) || lessons_exit=$?
|
|
43
|
+
assert_exit "lessons without subcommand exits 1" 1 node "$ACT" lessons
|
|
44
|
+
assert_contains "lessons shows usage hint" "lessons" "$lessons_output"
|
|
45
|
+
|
|
46
|
+
report_results
|