@mmerterden/multi-agent-pipeline 12.6.0 → 12.8.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/CHANGELOG.md +209 -0
- package/README.md +18 -18
- package/docs/FIGMA_PIPELINE.md +34 -34
- package/docs/adr/0001-three-model-triage.md +12 -12
- package/docs/adr/0002-instruction-driven-flag.md +5 -5
- package/docs/adr/0003-unified-shared-skills.md +5 -5
- package/docs/adr/0004-zero-dependency-philosophy.md +5 -5
- package/docs/adr/0005-lazy-phase-docs.md +2 -2
- package/docs/adr/0006-skills-core-external-split.md +6 -6
- package/docs/adr/0007-multi-tool-adapter-framework.md +19 -19
- package/docs/adr/0008-installer-modularization-and-secret-leak-defense.md +19 -19
- package/docs/adr/README.md +1 -1
- package/docs/best-practices.md +3 -3
- package/docs/features.md +28 -28
- package/docs/performance.md +16 -16
- package/docs/recovery-guide.md +39 -39
- package/index.js +4 -4
- package/install/_common.mjs +53 -11
- package/install/_copilot-instructions.mjs +2 -2
- package/install/_dev-only-files.mjs +126 -6
- package/install/_platform-filter.mjs +1 -1
- package/install/_telemetry.mjs +1 -1
- package/install/claude.mjs +20 -13
- package/install/copilot.mjs +11 -23
- package/install/index.mjs +7 -15
- package/install/templates/copilot-instructions.md +54 -54
- package/install.js +1 -1
- package/package.json +29 -11
- package/pipeline/commands/multi-agent/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/analysis/SKILL.md +2 -2
- package/pipeline/commands/multi-agent/analysis-resolve/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/autopilot/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/build-optimize/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/create-jira/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/design-check/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/dev/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/dev-autopilot/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/dev-local/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/dev-local-autopilot/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/diff-explain/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/finish/SKILL.md +6 -6
- package/pipeline/commands/multi-agent/forget/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/garbage-collect/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/help/SKILL.md +3 -3
- package/pipeline/commands/multi-agent/issue/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/jira/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/kill/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/language/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/local/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/local-autopilot/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/log/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/manual-test/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/prune-logs/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/purge/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/refactor/SKILL.md +16 -8
- package/pipeline/commands/multi-agent/resume/SKILL.md +2 -2
- package/pipeline/commands/multi-agent/review/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/review-issue/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/review-jira/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/routines/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/save/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/scan/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/search/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/setup/SKILL.md +2 -2
- package/pipeline/commands/multi-agent/stack/SKILL.md +3 -3
- package/pipeline/commands/multi-agent/status/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/sync/SKILL.md +5 -5
- package/pipeline/commands/multi-agent/test/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/uninstall/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/update/SKILL.md +3 -3
- package/pipeline/lib/account-resolver.sh +1 -1
- package/pipeline/lib/channels-multi-repo.sh +1 -1
- package/pipeline/lib/context-link-extractor.sh +1 -1
- package/pipeline/lib/credential-store.sh +21 -1
- package/pipeline/lib/fetch-confluence.sh +1 -1
- package/pipeline/lib/fetch-crashlytics.sh +1 -1
- package/pipeline/lib/fetch-fortify.sh +1 -1
- package/pipeline/lib/fetch-graylog.sh +1 -1
- package/pipeline/lib/fetch-swagger.sh +1 -1
- package/pipeline/lib/issue-fetcher.sh +1 -1
- package/pipeline/lib/multi-repo-pipeline.sh +1 -1
- package/pipeline/lib/repo-cache.sh +1 -1
- package/pipeline/lib/submodule-detector.sh +1 -1
- package/pipeline/multi-agent-refs/_account-picker.md +1 -1
- package/pipeline/multi-agent-refs/_dev-context.md +1 -1
- package/pipeline/multi-agent-refs/_repo-picker.md +1 -1
- package/pipeline/multi-agent-refs/component-dispatch.md +1 -1
- package/pipeline/multi-agent-refs/component-generation.md +121 -0
- package/pipeline/multi-agent-refs/cross-cli-contract.md +1 -1
- package/pipeline/multi-agent-refs/features/model-fallback.md +2 -2
- package/pipeline/multi-agent-refs/phases/operations.md +28 -0
- package/pipeline/multi-agent-refs/phases/phase-0-init.md +1 -0
- package/pipeline/multi-agent-refs/phases/phase-2-planning.md +1 -1
- package/pipeline/multi-agent-refs/phases/phase-3-dev.md +1 -2
- package/pipeline/multi-agent-refs/phases/phase-4-review.md +50 -5
- package/pipeline/preferences-template.json +5 -11
- package/pipeline/schemas/agent-state.schema.json +39 -9
- package/pipeline/schemas/analysis-output.schema.json +18 -4
- package/pipeline/schemas/analysis-spec.schema.json +120 -32
- package/pipeline/schemas/clarify-output.schema.json +15 -5
- package/pipeline/schemas/design-check-config.schema.json +32 -11
- package/pipeline/schemas/dev-critic-output.schema.json +20 -5
- package/pipeline/schemas/figma-project-config.schema.json +42 -10
- package/pipeline/schemas/learnings-ledger.schema.json +10 -2
- package/pipeline/schemas/migrations/figma-config-1.0.0-to-2.0.0.mjs +1 -4
- package/pipeline/schemas/migrations/prefs-2.0.0-to-2.1.0.mjs +24 -7
- package/pipeline/schemas/plan-todos.schema.json +6 -3
- package/pipeline/schemas/planning-output.schema.json +5 -1
- package/pipeline/schemas/prefs.schema.json +97 -229
- package/pipeline/schemas/test-gap.schema.json +5 -5
- package/pipeline/schemas/token-budget.json +8 -8
- package/pipeline/schemas/triage-corpus.schema.json +1 -1
- package/pipeline/scripts/_smoke-root.sh +61 -0
- package/pipeline/scripts/aggregate-metrics.mjs +18 -6
- package/pipeline/scripts/audit-log.sh +25 -0
- package/pipeline/scripts/build-skills-index.mjs +6 -2
- package/pipeline/scripts/build-stack-plugins.mjs +142 -39
- package/pipeline/scripts/check-derived-drift.mjs +196 -0
- package/pipeline/scripts/classify-plan-safety.mjs +20 -7
- package/pipeline/scripts/cost-budget-check.mjs +2 -1
- package/pipeline/scripts/cost-table.json +1 -1
- package/pipeline/scripts/diff-explain.mjs +7 -3
- package/pipeline/scripts/diff-risk-score.mjs +13 -3
- package/pipeline/scripts/evidence-gate.mjs +7 -2
- package/pipeline/scripts/gen-mode-dispatch.mjs +38 -21
- package/pipeline/scripts/gen-skills-index.mjs +18 -3
- package/pipeline/scripts/learning-curve.mjs +13 -3
- package/pipeline/scripts/learnings-ledger.mjs +103 -36
- package/pipeline/scripts/localize-commands.mjs +6 -1
- package/pipeline/scripts/match-skills.mjs +15 -4
- package/pipeline/scripts/migrate-prefs.mjs +33 -16
- package/pipeline/scripts/phase-tracker.sh +3 -1
- package/pipeline/scripts/repo-map.mjs +110 -64
- package/pipeline/scripts/review-scope.mjs +7 -1
- package/pipeline/scripts/routine-registry.mjs +4 -9
- package/pipeline/scripts/run-aggregator.mjs +11 -5
- package/pipeline/scripts/run-metrics.mjs +13 -8
- package/pipeline/scripts/smoke-cross-cli-behavior.sh +21 -7
- package/pipeline/scripts/test-gap-scan.mjs +44 -12
- package/pipeline/scripts/test-integrity-gate.mjs +5 -1
- package/pipeline/scripts/token-budget-report.mjs +44 -21
- package/pipeline/scripts/triage-memory.mjs +126 -34
- package/pipeline/scripts/uninstall.mjs +74 -30
- package/pipeline/scripts/validate-analysis-doc.mjs +15 -5
- package/pipeline/scripts/validate-diff-risk.mjs +32 -18
- package/pipeline/scripts/validate-test-gap.mjs +17 -7
- package/pipeline/scripts/validate-triage.mjs +17 -5
- package/pipeline/scripts/write-state.mjs +32 -9
- package/pipeline/skills/.skills-index.json +91 -91
- package/pipeline/skills/shared/README.md +57 -57
- package/pipeline/skills/shared/core/apple-archive-compliance/SKILL.md +1 -1
- package/pipeline/skills/shared/core/google-play-compliance/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent/SKILL.md +26 -279
- package/pipeline/skills/shared/core/multi-agent-analysis/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-analysis-resolve/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-autopilot/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-build-optimize/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-create-jira/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-design-check/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-dev/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-dev-autopilot/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-dev-local/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-dev-local-autopilot/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-diff-explain/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-finish/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-forget/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-garbage-collect/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-help/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-issue/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-jira/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-kill/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-language/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-local/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-local-autopilot/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-log/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-manual-test/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-prune-logs/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-purge/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-refactor/SKILL.md +16 -8
- package/pipeline/skills/shared/core/multi-agent-resume/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-review/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-review-issue/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-review-jira/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-routines/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-save/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-scan/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-search/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-setup/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-stack/SKILL.md +3 -3
- package/pipeline/skills/shared/core/multi-agent-status/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-test/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-uninstall/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-update/SKILL.md +1 -1
- package/pipeline/skills/shared/external/accessibility-compliance-accessibility-audit/SKILL.md +1 -1
- package/pipeline/skills/shared/external/agent-introspection-debugging/SKILL.md +4 -4
- package/pipeline/skills/shared/external/agentflow/SKILL.md +1 -1
- package/pipeline/skills/shared/external/android-jetpack-compose-expert/SKILL.md +1 -1
- package/pipeline/skills/shared/external/android_ui_verification/SKILL.md +1 -1
- package/pipeline/skills/shared/external/api-patterns/SKILL.md +1 -1
- package/pipeline/skills/shared/external/api-security-best-practices/SKILL.md +1 -1
- package/pipeline/skills/shared/external/app-store-changelog/SKILL.md +1 -1
- package/pipeline/skills/shared/external/backlog/BACKLOG.md +1 -1
- package/pipeline/skills/shared/external/backlog/SKILL.md +12 -12
- package/pipeline/skills/shared/external/ci-cd-pipelines/SKILL.md +1 -1
- package/pipeline/skills/shared/external/context-compression/SKILL.md +1 -1
- package/pipeline/skills/shared/external/council/SKILL.md +3 -3
- package/pipeline/skills/shared/external/css-modern/SKILL.md +1 -1
- package/pipeline/skills/shared/external/database-patterns/SKILL.md +1 -1
- package/pipeline/skills/shared/external/debugging-strategies/SKILL.md +1 -1
- package/pipeline/skills/shared/external/docker-expert/SKILL.md +1 -1
- package/pipeline/skills/shared/external/fastapi-pro/SKILL.md +1 -1
- package/pipeline/skills/shared/external/firebase/SKILL.md +1 -1
- package/pipeline/skills/shared/external/github-actions-templates/SKILL.md +1 -1
- package/pipeline/skills/shared/external/help-skills/SKILL.md +1 -1
- package/pipeline/skills/shared/external/hig-components-content/SKILL.md +1 -1
- package/pipeline/skills/shared/external/hig-components-layout/SKILL.md +1 -1
- package/pipeline/skills/shared/external/hig-components-status/SKILL.md +1 -1
- package/pipeline/skills/shared/external/hig-components-system/SKILL.md +1 -1
- package/pipeline/skills/shared/external/hig-foundations/SKILL.md +1 -1
- package/pipeline/skills/shared/external/hig-inputs/SKILL.md +1 -1
- package/pipeline/skills/shared/external/hig-patterns/SKILL.md +1 -1
- package/pipeline/skills/shared/external/hig-platforms/SKILL.md +1 -1
- package/pipeline/skills/shared/external/hig-technologies/SKILL.md +1 -1
- package/pipeline/skills/shared/external/html-semantic/SKILL.md +1 -1
- package/pipeline/skills/shared/external/humanizer/SKILL.md +1 -1
- package/pipeline/skills/shared/external/ios-debugger-agent/SKILL.md +1 -1
- package/pipeline/skills/shared/external/ios-developer/SKILL.md +1 -1
- package/pipeline/skills/shared/external/kotlin-coroutines-expert/SKILL.md +1 -1
- package/pipeline/skills/shared/external/macos-menubar-tuist-app/SKILL.md +1 -1
- package/pipeline/skills/shared/external/macos-spm-app-packaging/SKILL.md +1 -1
- package/pipeline/skills/shared/external/monorepo-architect/SKILL.md +1 -1
- package/pipeline/skills/shared/external/nextjs-app-router/SKILL.md +1 -1
- package/pipeline/skills/shared/external/nodejs-backend-patterns/SKILL.md +1 -1
- package/pipeline/skills/shared/external/observability-engineer/SKILL.md +1 -1
- package/pipeline/skills/shared/external/python-patterns/SKILL.md +1 -1
- package/pipeline/skills/shared/external/react-best-practices/SKILL.md +1 -1
- package/pipeline/skills/shared/external/rest-api-design/SKILL.md +1 -1
- package/pipeline/skills/shared/external/search-first/SKILL.md +2 -2
- package/pipeline/skills/shared/external/skill-creator/SKILL.md +12 -12
- package/pipeline/skills/shared/external/skill-creator/audit.md +21 -21
- package/pipeline/skills/shared/external/skill-creator/checklist.md +3 -3
- package/pipeline/skills/shared/external/skill-creator/examples.md +10 -10
- package/pipeline/skills/shared/external/skill-creator/label-check.md +17 -17
- package/pipeline/skills/shared/external/skill-creator/scripts/audit-panel.js +86 -50
- package/pipeline/skills/shared/external/skill-creator/template.md +9 -9
- package/pipeline/skills/shared/external/swift-concurrency-expert/SKILL.md +1 -1
- package/pipeline/skills/shared/external/swiftui-performance-audit/SKILL.md +1 -1
- package/pipeline/skills/shared/external/swiftui-ui-patterns/SKILL.md +1 -1
- package/pipeline/skills/shared/external/swiftui-view-refactor/SKILL.md +1 -1
- package/pipeline/skills/shared/external/tailwind-css/SKILL.md +1 -1
- package/pipeline/skills/shared/external/testing-backend/SKILL.md +1 -1
- package/pipeline/skills/shared/external/typescript-patterns/SKILL.md +1 -1
- package/pipeline/skills/shared/external/vue-composition/SKILL.md +1 -1
- package/pipeline/skills/shared/external/web-accessibility/SKILL.md +1 -1
- package/pipeline/skills/shared/external/web-performance/SKILL.md +1 -1
- package/pipeline/skills/shared/external/web-testing/SKILL.md +1 -1
- package/pipeline/skills/shared/external/xcode-build-benchmark/schemas/build-benchmark.schema.json +9 -49
- package/pipeline/skills/skills-index.md +57 -57
- package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-1-analysis.json +0 -25
- package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-2-plan.json +0 -30
- package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-4-review.json +0 -20
- package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-4-triage.json +0 -15
- package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/metadata.json +0 -14
- package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/task.json +0 -12
- package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-1-analysis.json +0 -29
- package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-2-plan.json +0 -43
- package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-4-review.json +0 -35
- package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-4-triage.json +0 -35
- package/pipeline/eval/golden-tasks/02-android-feature-compose/metadata.json +0 -14
- package/pipeline/eval/golden-tasks/02-android-feature-compose/task.json +0 -12
- package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-1-analysis.json +0 -29
- package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-2-plan.json +0 -42
- package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-4-review.json +0 -20
- package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-4-triage.json +0 -15
- package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/metadata.json +0 -14
- package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/task.json +0 -12
- package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-1-analysis.json +0 -29
- package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-2-plan.json +0 -40
- package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-4-review.json +0 -20
- package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-4-triage.json +0 -15
- package/pipeline/eval/golden-tasks/04-frontend-next-hydration/metadata.json +0 -14
- package/pipeline/eval/golden-tasks/04-frontend-next-hydration/task.json +0 -12
- package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-1-analysis.json +0 -29
- package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-2-plan.json +0 -42
- package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-4-review.json +0 -28
- package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-4-triage.json +0 -27
- package/pipeline/eval/golden-tasks/05-ios-security-keychain/metadata.json +0 -14
- package/pipeline/eval/golden-tasks/05-ios-security-keychain/task.json +0 -12
- package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-1-analysis.json +0 -29
- package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-2-plan.json +0 -41
- package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-4-review.json +0 -12
- package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-4-triage.json +0 -6
- package/pipeline/eval/golden-tasks/06-android-refactor-usecase/metadata.json +0 -14
- package/pipeline/eval/golden-tasks/06-android-refactor-usecase/task.json +0 -12
- package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-1-analysis.json +0 -29
- package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-2-plan.json +0 -42
- package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-4-review.json +0 -28
- package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-4-triage.json +0 -27
- package/pipeline/eval/golden-tasks/07-backend-node-idempotency/metadata.json +0 -14
- package/pipeline/eval/golden-tasks/07-backend-node-idempotency/task.json +0 -12
- package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-1-analysis.json +0 -25
- package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-2-plan.json +0 -31
- package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-4-review.json +0 -12
- package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-4-triage.json +0 -18
- package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/metadata.json +0 -14
- package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/task.json +0 -12
- package/pipeline/eval/golden-tasks/README.md +0 -65
- package/pipeline/eval/intent-cases.json +0 -40
- package/pipeline/eval/run-metrics-fixture.json +0 -46
- package/pipeline/eval/triage/01-empty-findings/expected.json +0 -6
- package/pipeline/eval/triage/01-empty-findings/input.json +0 -5
- package/pipeline/eval/triage/01-empty-findings/notes.md +0 -7
- package/pipeline/eval/triage/02-real-blocker/expected.json +0 -15
- package/pipeline/eval/triage/02-real-blocker/input.json +0 -14
- package/pipeline/eval/triage/02-real-blocker/notes.md +0 -7
- package/pipeline/eval/triage/03-out-of-scope-defer/expected.json +0 -18
- package/pipeline/eval/triage/03-out-of-scope-defer/input.json +0 -14
- package/pipeline/eval/triage/03-out-of-scope-defer/notes.md +0 -10
- package/pipeline/eval/triage/04-false-positive-reject/expected.json +0 -18
- package/pipeline/eval/triage/04-false-positive-reject/input.json +0 -14
- package/pipeline/eval/triage/04-false-positive-reject/notes.md +0 -10
- package/pipeline/eval/triage/05-mixed-classification/expected.json +0 -43
- package/pipeline/eval/triage/05-mixed-classification/input.json +0 -38
- package/pipeline/eval/triage/05-mixed-classification/notes.md +0 -17
- package/pipeline/eval/triage/06-severity-mismatch/expected.json +0 -15
- package/pipeline/eval/triage/06-severity-mismatch/input.json +0 -14
- package/pipeline/eval/triage/06-severity-mismatch/notes.md +0 -9
- package/pipeline/eval/triage/07-duplicate-reviewers/expected.json +0 -27
- package/pipeline/eval/triage/07-duplicate-reviewers/input.json +0 -22
- package/pipeline/eval/triage/07-duplicate-reviewers/notes.md +0 -9
- package/pipeline/eval/triage/08-style-misclassified/expected.json +0 -18
- package/pipeline/eval/triage/08-style-misclassified/input.json +0 -14
- package/pipeline/eval/triage/08-style-misclassified/notes.md +0 -9
- package/pipeline/eval/triage/09-cascading-finding/expected.json +0 -23
- package/pipeline/eval/triage/09-cascading-finding/input.json +0 -22
- package/pipeline/eval/triage/09-cascading-finding/notes.md +0 -9
- package/pipeline/eval/triage/10-deferred-crossref/expected.json +0 -18
- package/pipeline/eval/triage/10-deferred-crossref/input.json +0 -14
- package/pipeline/eval/triage/10-deferred-crossref/notes.md +0 -9
- package/pipeline/eval/triage/11-vercel-token-leak-blocker/expected.json +0 -27
- package/pipeline/eval/triage/11-vercel-token-leak-blocker/input.json +0 -22
- package/pipeline/eval/triage/11-vercel-token-leak-blocker/notes.md +0 -14
- package/pipeline/eval/triage/README.md +0 -54
- package/pipeline/scripts/benchmark-phase-0.sh +0 -128
- package/pipeline/scripts/check-md-links.mjs +0 -84
- package/pipeline/scripts/eval-golden-tasks-live.mjs +0 -297
- package/pipeline/scripts/eval-golden-tasks.mjs +0 -212
- package/pipeline/scripts/eval-intent.mjs +0 -103
- package/pipeline/scripts/eval-mine-corpus.mjs +0 -201
- package/pipeline/scripts/eval-triage.mjs +0 -171
- package/pipeline/scripts/fixtures/diff-risk-android.diff +0 -40
- package/pipeline/scripts/fixtures/diff-risk-ios.diff +0 -48
- package/pipeline/scripts/fixtures/diff-risk-test-removal.diff +0 -40
- package/pipeline/scripts/fixtures/install-layout.tsv +0 -19
- package/pipeline/scripts/fixtures/pack-expected-count.txt +0 -1
- package/pipeline/scripts/fixtures/test-gap-node.diff +0 -30
- package/pipeline/scripts/fixtures/test-gap-python.diff +0 -32
- package/pipeline/scripts/lint-mcp-refs.mjs +0 -207
- package/pipeline/scripts/lint-skills.mjs +0 -143
- package/pipeline/scripts/run-smokes.mjs +0 -76
- package/pipeline/scripts/smoke-add-detail.sh +0 -137
- package/pipeline/scripts/smoke-agent-guard.sh +0 -74
- package/pipeline/scripts/smoke-agent-log-cost.sh +0 -262
- package/pipeline/scripts/smoke-agent-model-routing.sh +0 -87
- package/pipeline/scripts/smoke-ask-choice.sh +0 -42
- package/pipeline/scripts/smoke-autopilot-circuit-breaker.sh +0 -36
- package/pipeline/scripts/smoke-bitbucket-contract.sh +0 -255
- package/pipeline/scripts/smoke-changelog-version.sh +0 -47
- package/pipeline/scripts/smoke-channels-approval-gate.sh +0 -60
- package/pipeline/scripts/smoke-channels-flow.sh +0 -130
- package/pipeline/scripts/smoke-ci-workflows.sh +0 -88
- package/pipeline/scripts/smoke-clarify.sh +0 -148
- package/pipeline/scripts/smoke-command-inventory.sh +0 -81
- package/pipeline/scripts/smoke-commands-skills-parity.sh +0 -87
- package/pipeline/scripts/smoke-community-gates.sh +0 -75
- package/pipeline/scripts/smoke-compliance-skills.sh +0 -119
- package/pipeline/scripts/smoke-config-hygiene.sh +0 -58
- package/pipeline/scripts/smoke-cost-budget.sh +0 -70
- package/pipeline/scripts/smoke-cost-summary.sh +0 -139
- package/pipeline/scripts/smoke-cross-phase-cohesion.sh +0 -128
- package/pipeline/scripts/smoke-description-tr.sh +0 -82
- package/pipeline/scripts/smoke-dev-critic.sh +0 -144
- package/pipeline/scripts/smoke-diff-explain.sh +0 -147
- package/pipeline/scripts/smoke-diff-risk.sh +0 -190
- package/pipeline/scripts/smoke-dynamic-skill-loading.sh +0 -160
- package/pipeline/scripts/smoke-eval-live.sh +0 -136
- package/pipeline/scripts/smoke-evidence-gate.sh +0 -93
- package/pipeline/scripts/smoke-extract-conventions.sh +0 -163
- package/pipeline/scripts/smoke-fetchers-offline.sh +0 -448
- package/pipeline/scripts/smoke-figma-dispatch.sh +0 -112
- package/pipeline/scripts/smoke-gate-hooks.sh +0 -74
- package/pipeline/scripts/smoke-gc-tmp.sh +0 -130
- package/pipeline/scripts/smoke-gc-worktrees.sh +0 -125
- package/pipeline/scripts/smoke-generate-issue.sh +0 -120
- package/pipeline/scripts/smoke-handoff-contract.sh +0 -92
- package/pipeline/scripts/smoke-identity-isolation.sh +0 -70
- package/pipeline/scripts/smoke-install-layout.sh +0 -248
- package/pipeline/scripts/smoke-intent-guard.sh +0 -86
- package/pipeline/scripts/smoke-issue-comment-template.sh +0 -86
- package/pipeline/scripts/smoke-issue-jira-triad.sh +0 -120
- package/pipeline/scripts/smoke-keychain.sh +0 -158
- package/pipeline/scripts/smoke-language-axis.sh +0 -109
- package/pipeline/scripts/smoke-learning-curve.sh +0 -61
- package/pipeline/scripts/smoke-learnings-ledger.sh +0 -86
- package/pipeline/scripts/smoke-lib-scripts.sh +0 -448
- package/pipeline/scripts/smoke-mcp-gate.sh +0 -68
- package/pipeline/scripts/smoke-md-links.sh +0 -8
- package/pipeline/scripts/smoke-md2confluence.sh +0 -126
- package/pipeline/scripts/smoke-metrics-cache-ratio.sh +0 -72
- package/pipeline/scripts/smoke-migrate-state.sh +0 -102
- package/pipeline/scripts/smoke-mode-dispatch-drift.sh +0 -161
- package/pipeline/scripts/smoke-model-fallback.sh +0 -89
- package/pipeline/scripts/smoke-multi-repo-integration.sh +0 -116
- package/pipeline/scripts/smoke-multi-repo-worktree.sh +0 -61
- package/pipeline/scripts/smoke-no-mcp-in-dev-phases.sh +0 -115
- package/pipeline/scripts/smoke-no-token-prompt.sh +0 -85
- package/pipeline/scripts/smoke-pack-contents.sh +0 -140
- package/pipeline/scripts/smoke-pat-audit.sh +0 -128
- package/pipeline/scripts/smoke-per-repo-memory.sh +0 -156
- package/pipeline/scripts/smoke-phase-0-multi-repo.sh +0 -170
- package/pipeline/scripts/smoke-phase-6-multi.sh +0 -79
- package/pipeline/scripts/smoke-phase-banner.sh +0 -101
- package/pipeline/scripts/smoke-phase-tracker.sh +0 -324
- package/pipeline/scripts/smoke-phase0-bridge-contract.sh +0 -241
- package/pipeline/scripts/smoke-phase4-gates.sh +0 -45
- package/pipeline/scripts/smoke-phase4-triage.sh +0 -229
- package/pipeline/scripts/smoke-plan-approval-gate.sh +0 -71
- package/pipeline/scripts/smoke-plan-safety.sh +0 -139
- package/pipeline/scripts/smoke-plan-todos.sh +0 -196
- package/pipeline/scripts/smoke-plugin-validate.sh +0 -64
- package/pipeline/scripts/smoke-pr-review-actions.sh +0 -152
- package/pipeline/scripts/smoke-pre-commit.sh +0 -170
- package/pipeline/scripts/smoke-pref-migration.sh +0 -226
- package/pipeline/scripts/smoke-prefs-language.sh +0 -134
- package/pipeline/scripts/smoke-progress-contract.sh +0 -127
- package/pipeline/scripts/smoke-prune-logs.sh +0 -137
- package/pipeline/scripts/smoke-purge.sh +0 -138
- package/pipeline/scripts/smoke-push-retry.sh +0 -75
- package/pipeline/scripts/smoke-repo-map.sh +0 -300
- package/pipeline/scripts/smoke-review-readiness.sh +0 -92
- package/pipeline/scripts/smoke-review-watch.sh +0 -146
- package/pipeline/scripts/smoke-routines.sh +0 -84
- package/pipeline/scripts/smoke-run-aggregator.sh +0 -216
- package/pipeline/scripts/smoke-run-metrics.sh +0 -50
- package/pipeline/scripts/smoke-search.sh +0 -187
- package/pipeline/scripts/smoke-shadow-git.sh +0 -224
- package/pipeline/scripts/smoke-skill-authoring.sh +0 -137
- package/pipeline/scripts/smoke-skill-language.sh +0 -83
- package/pipeline/scripts/smoke-skill-manifest.sh +0 -138
- package/pipeline/scripts/smoke-skill-scan.sh +0 -198
- package/pipeline/scripts/smoke-source-parity.sh +0 -85
- package/pipeline/scripts/smoke-subagent-validators.sh +0 -108
- package/pipeline/scripts/smoke-sync-parity.sh +0 -92
- package/pipeline/scripts/smoke-tasklist-ordering.sh +0 -112
- package/pipeline/scripts/smoke-telemetry.sh +0 -147
- package/pipeline/scripts/smoke-test-gap.sh +0 -183
- package/pipeline/scripts/smoke-token-budget.sh +0 -67
- package/pipeline/scripts/smoke-token-preflight.sh +0 -82
- package/pipeline/scripts/smoke-tracker-contract.sh +0 -191
- package/pipeline/scripts/smoke-tracker-tokens-invocation.sh +0 -73
- package/pipeline/scripts/smoke-triage-memory.sh +0 -174
- package/pipeline/scripts/smoke-update-check.sh +0 -135
- package/pipeline/scripts/smoke-url-enrichment.sh +0 -70
- package/pipeline/scripts/smoke-validate-analysis-doc.sh +0 -161
- package/pipeline/scripts/smoke-validator-contradiction.sh +0 -67
- package/pipeline/scripts/smoke-validator-gates.sh +0 -164
- package/pipeline/scripts/smoke-vercel-deploy-redact.sh +0 -129
- package/pipeline/scripts/smoke-verify-by-test.sh +0 -148
- package/pipeline/scripts/smoke-wiki-integration.sh +0 -122
- package/pipeline/scripts/smoke-work-summary.sh +0 -163
- package/pipeline/scripts/smoke-workflow-audit.sh +0 -69
- package/pipeline/scripts/smoke-worktree-path-convention.sh +0 -86
- package/pipeline/scripts/smoke-wrapper-preservation.sh +0 -68
- package/pipeline/scripts/smoke-write-state.sh +0 -115
- package/pipeline/scripts/sync-parity-check.sh +0 -135
- package/pipeline/scripts/test-gap-rules/android.json +0 -25
- package/pipeline/scripts/test-gap-rules/ios.json +0 -29
- package/pipeline/scripts/test-gap-rules/node.json +0 -17
- package/pipeline/scripts/test-gap-rules/python.json +0 -19
- package/pipeline/scripts/validate-schemas.mjs +0 -88
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// check-derived-drift.mjs - resolve the upstream version for every entry in
|
|
3
|
+
// prefs `global.derivedSkillSources[]` and report drift.
|
|
4
|
+
//
|
|
5
|
+
// This exists because the resolution order is the whole correctness question,
|
|
6
|
+
// and prose in a skill file cannot be tested. The step used to read the
|
|
7
|
+
// installed plugin cache and call the answer authoritative. A cache is only as
|
|
8
|
+
// fresh as the last `claude marketplace update`, so it reported "up to date"
|
|
9
|
+
// for a derivation that was four releases behind, and the version it had been
|
|
10
|
+
// recorded from was the wrong manifest besides.
|
|
11
|
+
//
|
|
12
|
+
// Resolution order, first source that answers wins:
|
|
13
|
+
// 1. upstreamLocalClone a working copy of the upstream repo
|
|
14
|
+
// 2. upstreamRepoUrl the same manifest over `gh api`
|
|
15
|
+
// 3. the plugin cache a mirror; can only ever yield "unverified"
|
|
16
|
+
//
|
|
17
|
+
// Which manifest carries the version is `upstreamVersionSource`, default
|
|
18
|
+
// marketplace.json, because that is what a marketplace consumer resolves.
|
|
19
|
+
//
|
|
20
|
+
// Exit codes: 0 = no drift (or not configured), 1 = drift or unverified,
|
|
21
|
+
// 2 = a configured entry could not be resolved at all.
|
|
22
|
+
//
|
|
23
|
+
// Flags: --json machine-readable output for the scorecard gate.
|
|
24
|
+
|
|
25
|
+
import { Buffer } from "node:buffer";
|
|
26
|
+
import { execFileSync } from "node:child_process";
|
|
27
|
+
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
28
|
+
import { homedir } from "node:os";
|
|
29
|
+
import { join } from "node:path";
|
|
30
|
+
|
|
31
|
+
const asJson = process.argv.includes("--json");
|
|
32
|
+
// Overridable so the gate can be driven against fixtures. Real runs read the
|
|
33
|
+
// user's prefs; a test that had to write into $HOME to exercise this would be
|
|
34
|
+
// a test nobody runs.
|
|
35
|
+
const PREFS =
|
|
36
|
+
process.env.DERIVED_DRIFT_PREFS || join(homedir(), ".claude", "multi-agent-preferences.json");
|
|
37
|
+
const CACHE = process.env.DERIVED_DRIFT_CACHE || join(homedir(), ".claude", "plugins", "cache");
|
|
38
|
+
|
|
39
|
+
const expandHome = (p) => p.replace(/^\$HOME\b|^~/, homedir());
|
|
40
|
+
|
|
41
|
+
function readJson(path) {
|
|
42
|
+
try {
|
|
43
|
+
return JSON.parse(readFileSync(path, "utf-8"));
|
|
44
|
+
} catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// A manifest names its version either directly (plugin.json) or inside a
|
|
50
|
+
// plugins[] entry keyed by name (marketplace.json).
|
|
51
|
+
function versionFrom(manifest, pluginName) {
|
|
52
|
+
if (!manifest) return null;
|
|
53
|
+
if (Array.isArray(manifest.plugins)) {
|
|
54
|
+
const hit = manifest.plugins.find((p) => p.name === pluginName);
|
|
55
|
+
return hit?.version ?? null;
|
|
56
|
+
}
|
|
57
|
+
return manifest.version ?? null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function fromLocalClone(entry) {
|
|
61
|
+
if (!entry.upstreamLocalClone) return null;
|
|
62
|
+
const root = expandHome(entry.upstreamLocalClone);
|
|
63
|
+
const file =
|
|
64
|
+
entry.upstreamVersionSource === "plugin.json"
|
|
65
|
+
? join(root, "plugins", entry.upstreamPlugin, ".claude-plugin", "plugin.json")
|
|
66
|
+
: join(root, ".claude-plugin", "marketplace.json");
|
|
67
|
+
if (!existsSync(file)) return null;
|
|
68
|
+
const version = versionFrom(readJson(file), entry.upstreamPlugin);
|
|
69
|
+
if (!version) return null;
|
|
70
|
+
|
|
71
|
+
// A clone behind its own remote is still a stale answer, just a less stale
|
|
72
|
+
// one than the cache. Say so rather than presenting it as current.
|
|
73
|
+
let behind;
|
|
74
|
+
try {
|
|
75
|
+
const out = execFileSync("git", ["-C", root, "rev-list", "--count", "HEAD..@{u}"], {
|
|
76
|
+
encoding: "utf-8",
|
|
77
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
78
|
+
}).trim();
|
|
79
|
+
behind = Number(out) || 0;
|
|
80
|
+
} catch {
|
|
81
|
+
// No upstream branch configured, or not a git checkout at all.
|
|
82
|
+
behind = null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return { version, source: "local clone", authoritative: true, behind };
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function fromRepoApi(entry) {
|
|
89
|
+
if (!entry.upstreamRepoUrl) return null;
|
|
90
|
+
const m = entry.upstreamRepoUrl.match(/github\.com\/([^/]+)\/([^/.]+)/);
|
|
91
|
+
if (!m) return null;
|
|
92
|
+
const path =
|
|
93
|
+
entry.upstreamVersionSource === "plugin.json"
|
|
94
|
+
? `plugins/${entry.upstreamPlugin}/.claude-plugin/plugin.json`
|
|
95
|
+
: ".claude-plugin/marketplace.json";
|
|
96
|
+
try {
|
|
97
|
+
const raw = execFileSync(
|
|
98
|
+
"gh",
|
|
99
|
+
["api", `repos/${m[1]}/${m[2]}/contents/${path}`, "--jq", ".content"],
|
|
100
|
+
{ encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] },
|
|
101
|
+
).trim();
|
|
102
|
+
const version = versionFrom(
|
|
103
|
+
JSON.parse(Buffer.from(raw, "base64").toString("utf-8")),
|
|
104
|
+
entry.upstreamPlugin,
|
|
105
|
+
);
|
|
106
|
+
return version ? { version, source: "repo api", authoritative: true, behind: 0 } : null;
|
|
107
|
+
} catch {
|
|
108
|
+
// 404 here means unreachable for the active account, not "no drift".
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function fromCache(entry) {
|
|
114
|
+
if (!entry.upstreamMarketplace) return null;
|
|
115
|
+
const dir = join(CACHE, entry.upstreamMarketplace, entry.upstreamPlugin);
|
|
116
|
+
if (!existsSync(dir)) return null;
|
|
117
|
+
const versions = readdirSync(dir)
|
|
118
|
+
.filter((d) => /^\d+\.\d+\.\d+$/.test(d))
|
|
119
|
+
.sort();
|
|
120
|
+
const newest = versions[versions.length - 1];
|
|
121
|
+
return newest
|
|
122
|
+
? { version: newest, source: "plugin cache", authoritative: false, behind: null }
|
|
123
|
+
: null;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const prefs = readJson(PREFS);
|
|
127
|
+
const entries = prefs?.global?.derivedSkillSources ?? [];
|
|
128
|
+
|
|
129
|
+
if (entries.length === 0) {
|
|
130
|
+
const msg = "check-derived-drift: no derived-skill sources configured";
|
|
131
|
+
console.log(
|
|
132
|
+
asJson ? JSON.stringify({ configured: 0, drifted: 0, unverified: 0, entries: [] }) : msg,
|
|
133
|
+
);
|
|
134
|
+
process.exit(0);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const rows = [];
|
|
138
|
+
for (const entry of entries) {
|
|
139
|
+
const resolved = fromLocalClone(entry) || fromRepoApi(entry) || fromCache(entry);
|
|
140
|
+
if (!resolved) {
|
|
141
|
+
rows.push({
|
|
142
|
+
label: entry.label,
|
|
143
|
+
plugin: entry.upstreamPlugin,
|
|
144
|
+
from: entry.derivedFromVersion,
|
|
145
|
+
upstream: null,
|
|
146
|
+
source: "unreachable",
|
|
147
|
+
status: "unreachable",
|
|
148
|
+
});
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
const drifted = resolved.version !== entry.derivedFromVersion;
|
|
152
|
+
const status = drifted
|
|
153
|
+
? "drift"
|
|
154
|
+
: resolved.authoritative
|
|
155
|
+
? "up to date"
|
|
156
|
+
: "unverified (cache only)";
|
|
157
|
+
rows.push({
|
|
158
|
+
label: entry.label,
|
|
159
|
+
plugin: entry.upstreamPlugin,
|
|
160
|
+
from: entry.derivedFromVersion,
|
|
161
|
+
upstream: resolved.version,
|
|
162
|
+
source: resolved.source,
|
|
163
|
+
cloneBehind: resolved.behind,
|
|
164
|
+
status,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const drifted = rows.filter((r) => r.status === "drift").length;
|
|
169
|
+
const unverified = rows.filter((r) => r.status.startsWith("unverified")).length;
|
|
170
|
+
const unreachable = rows.filter((r) => r.status === "unreachable").length;
|
|
171
|
+
|
|
172
|
+
if (asJson) {
|
|
173
|
+
console.log(
|
|
174
|
+
JSON.stringify(
|
|
175
|
+
{ configured: rows.length, drifted, unverified, unreachable, entries: rows },
|
|
176
|
+
null,
|
|
177
|
+
2,
|
|
178
|
+
),
|
|
179
|
+
);
|
|
180
|
+
} else {
|
|
181
|
+
for (const r of rows) {
|
|
182
|
+
const behind = r.cloneBehind ? ` [clone ${r.cloneBehind} behind its remote]` : "";
|
|
183
|
+
console.log(
|
|
184
|
+
` ${r.status === "up to date" ? "✓" : "✗"} ${r.plugin}: recorded ${r.from}, ` +
|
|
185
|
+
`upstream ${r.upstream ?? "?"} (${r.source})${behind} -> ${r.status}`,
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
console.log("");
|
|
189
|
+
console.log(
|
|
190
|
+
`══ check-derived-drift: ${rows.length - drifted - unverified - unreachable} passed, ` +
|
|
191
|
+
`${drifted + unverified + unreachable} failed ══`,
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (unreachable > 0) process.exit(2);
|
|
196
|
+
process.exit(drifted + unverified > 0 ? 1 : 0);
|
|
@@ -74,9 +74,17 @@ const reasons = [];
|
|
|
74
74
|
// --- file-count ---
|
|
75
75
|
const fileCount = allFiles.size;
|
|
76
76
|
if (fileCount > 15) {
|
|
77
|
-
reasons.push({
|
|
77
|
+
reasons.push({
|
|
78
|
+
rule: "file-count-high",
|
|
79
|
+
weight: 30,
|
|
80
|
+
detail: `plan touches ${fileCount} files (threshold 15)`,
|
|
81
|
+
});
|
|
78
82
|
} else if (fileCount >= 8) {
|
|
79
|
-
reasons.push({
|
|
83
|
+
reasons.push({
|
|
84
|
+
rule: "file-count-medium",
|
|
85
|
+
weight: 10,
|
|
86
|
+
detail: `plan touches ${fileCount} files`,
|
|
87
|
+
});
|
|
80
88
|
}
|
|
81
89
|
|
|
82
90
|
// --- destructive verb ---
|
|
@@ -102,7 +110,8 @@ if (destructiveHits.length > 0) {
|
|
|
102
110
|
// mid-word hits like "Reauthorize" do not. A trailing anchor here would miss
|
|
103
111
|
// the common "AuthManager"/"TokenStore" suffix-naming and let sensitive files
|
|
104
112
|
// slip past the autopilot pause heuristic.
|
|
105
|
-
const securityRe =
|
|
113
|
+
const securityRe =
|
|
114
|
+
/(\/|^)(auth|keychain|credentials?|secret|security|tokens?|cert|encrypt|signing|privacy)/i;
|
|
106
115
|
const securityHits = [];
|
|
107
116
|
for (const f of allFiles) if (securityRe.test(f)) securityHits.push(f);
|
|
108
117
|
if (securityHits.length > 0) {
|
|
@@ -130,7 +139,11 @@ for (const t of tasks) {
|
|
|
130
139
|
if (!destructiveRe.test(t.title || "")) continue;
|
|
131
140
|
const taskDirs = new Set((t.files || []).map((f) => f.split("/").slice(0, -1).join("/")));
|
|
132
141
|
let covered = false;
|
|
133
|
-
for (const d of taskDirs)
|
|
142
|
+
for (const d of taskDirs)
|
|
143
|
+
if (testFileDirs.has(d)) {
|
|
144
|
+
covered = true;
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
134
147
|
if (!covered) deleteWithoutTest.push(t.id || t.title);
|
|
135
148
|
}
|
|
136
149
|
if (deleteWithoutTest.length > 0) {
|
|
@@ -157,7 +170,8 @@ if (schemaHits.length > 0) {
|
|
|
157
170
|
}
|
|
158
171
|
|
|
159
172
|
// --- infrastructure ---
|
|
160
|
-
const infraRe =
|
|
173
|
+
const infraRe =
|
|
174
|
+
/(^|\/)(Dockerfile|install\.js|package\.json|build\.gradle|settings\.gradle|Gemfile|pyproject\.toml|\.github\/workflows\/.*\.ya?ml|vercel\.(json|ts))$/i;
|
|
161
175
|
const infraHits = [];
|
|
162
176
|
for (const f of allFiles) if (infraRe.test(f)) infraHits.push(f);
|
|
163
177
|
if (infraHits.length > 0) {
|
|
@@ -172,8 +186,7 @@ if (infraHits.length > 0) {
|
|
|
172
186
|
const score = reasons.reduce((s, r) => s + r.weight, 0);
|
|
173
187
|
const heavyHits = reasons.filter((r) => r.weight >= 30);
|
|
174
188
|
const mediumOrAboveHits = reasons.filter((r) => r.weight >= 20);
|
|
175
|
-
const recommendPause =
|
|
176
|
-
heavyHits.length >= 1 || mediumOrAboveHits.length >= 2 || score >= 50;
|
|
189
|
+
const recommendPause = heavyHits.length >= 1 || mediumOrAboveHits.length >= 2 || score >= 50;
|
|
177
190
|
|
|
178
191
|
let summary;
|
|
179
192
|
if (recommendPause) {
|
|
@@ -153,7 +153,8 @@ const base =
|
|
|
153
153
|
`(${pctOfMax.toFixed(0)}%, ${totalTok.toLocaleString("en-US")} tok @ ${cfg.pricingModel})`;
|
|
154
154
|
|
|
155
155
|
if (usd > cfg.maxUsd) {
|
|
156
|
-
const action =
|
|
156
|
+
const action =
|
|
157
|
+
cfg.onExceed === "halt" ? "HALT - run multi-agent:resume to continue" : "over budget";
|
|
157
158
|
process.stdout.write(`EXCEEDED: ${base} - ${action}\n`);
|
|
158
159
|
process.exit(11);
|
|
159
160
|
}
|
|
@@ -83,7 +83,7 @@ function loadTriage() {
|
|
|
83
83
|
if (flags["task-id"]) {
|
|
84
84
|
die(
|
|
85
85
|
"--task-id resolution not implemented in this script - use --triage or --state directly. " +
|
|
86
|
-
|
|
86
|
+
"The slash command resolves task IDs via the orchestrator and passes --state to this script.",
|
|
87
87
|
);
|
|
88
88
|
}
|
|
89
89
|
die("one of --triage, --state, or --task-id is required");
|
|
@@ -239,7 +239,9 @@ lines.push("# Phase 4 Triage Diff Bridge");
|
|
|
239
239
|
lines.push("");
|
|
240
240
|
lines.push("## Summary");
|
|
241
241
|
lines.push("");
|
|
242
|
-
lines.push(
|
|
242
|
+
lines.push(
|
|
243
|
+
`- **Accepted:** ${counts.accepted} (🚫 ${counts.blocking} blocking · ⚠️ ${counts.important} important · 💡 ${counts.suggestion} suggestion)`,
|
|
244
|
+
);
|
|
243
245
|
lines.push(`- **Deferred:** ${counts.deferred} · **Rejected:** ${counts.rejected}`);
|
|
244
246
|
lines.push(`- **Approved:** ${triage.approved === true ? "✅ yes" : "❌ no"}`);
|
|
245
247
|
lines.push("");
|
|
@@ -252,7 +254,9 @@ for (const [file, items] of byFile) {
|
|
|
252
254
|
const icon = severityIcon(item.severity);
|
|
253
255
|
const bucketTag = bucketIcon(item._bucket);
|
|
254
256
|
const reviewer = item.reviewer ? ` _(${item.reviewer})_` : "";
|
|
255
|
-
lines.push(
|
|
257
|
+
lines.push(
|
|
258
|
+
`### ${bucketTag} ${icon} ${severityLabel(item.severity)} - line ${item.line ?? "?"}${reviewer}`,
|
|
259
|
+
);
|
|
256
260
|
lines.push("");
|
|
257
261
|
if (item._reason) lines.push(`> _${item._bucket}: ${item._reason}_`);
|
|
258
262
|
lines.push(`> ${item.issue}`);
|
|
@@ -71,11 +71,20 @@ function git(args) {
|
|
|
71
71
|
|
|
72
72
|
function resolveBase() {
|
|
73
73
|
if (BASE) return BASE;
|
|
74
|
-
for (const ref of [
|
|
74
|
+
for (const ref of [
|
|
75
|
+
"origin/main",
|
|
76
|
+
"main",
|
|
77
|
+
"origin/master",
|
|
78
|
+
"master",
|
|
79
|
+
"develop",
|
|
80
|
+
"origin/develop",
|
|
81
|
+
]) {
|
|
75
82
|
try {
|
|
76
83
|
execFileSync("git", ["-C", ROOT, "rev-parse", "--verify", ref], { stdio: "ignore" });
|
|
77
84
|
return ref;
|
|
78
|
-
} catch {
|
|
85
|
+
} catch {
|
|
86
|
+
/* try next */
|
|
87
|
+
}
|
|
79
88
|
}
|
|
80
89
|
throw new Error("no base ref found (tried origin/main, main, master, develop)");
|
|
81
90
|
}
|
|
@@ -210,7 +219,8 @@ function complexitySignal(addedLines) {
|
|
|
210
219
|
let count = 0;
|
|
211
220
|
for (const l of addedLines) {
|
|
212
221
|
if (/^\s*(if|guard|switch|case\s|while|for|do|try)\b/.test(l)) count++;
|
|
213
|
-
else if (/\b\?\s*:/.test(l))
|
|
222
|
+
else if (/\b\?\s*:/.test(l))
|
|
223
|
+
count++; // ternary
|
|
214
224
|
else if (/&&|\|\|/.test(l)) count++;
|
|
215
225
|
}
|
|
216
226
|
return count;
|
|
@@ -72,7 +72,10 @@ function parseArgs(argv) {
|
|
|
72
72
|
const body = a.slice(2);
|
|
73
73
|
// --key=value form accepts a value starting with "--" too.
|
|
74
74
|
const eq = body.indexOf("=");
|
|
75
|
-
if (eq !== -1) {
|
|
75
|
+
if (eq !== -1) {
|
|
76
|
+
out[body.slice(0, eq)] = body.slice(eq + 1);
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
76
79
|
const key = body;
|
|
77
80
|
const next = argv[i + 1];
|
|
78
81
|
if (next === undefined || next.startsWith("--")) {
|
|
@@ -158,7 +161,9 @@ if (showsFailure) {
|
|
|
158
161
|
}
|
|
159
162
|
// No failure, but also no success marker -> unproven -> default-FAIL.
|
|
160
163
|
if (!showsSuccess) {
|
|
161
|
-
fail(
|
|
164
|
+
fail(
|
|
165
|
+
`${claim} evidence does not contain a success marker - pass claim unverified by ${evidence}`,
|
|
166
|
+
);
|
|
162
167
|
}
|
|
163
168
|
|
|
164
169
|
ok(`${claim} pass claim substantiated by ${evidence}`);
|
|
@@ -53,15 +53,31 @@ const PHASE_NAMES_NO_TEST = PHASE_NAMES.filter((p) => p !== "5:Test");
|
|
|
53
53
|
* against its generator output.
|
|
54
54
|
*/
|
|
55
55
|
const MODES = {
|
|
56
|
-
dev:
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
56
|
+
dev: {
|
|
57
|
+
phases: ["0:Init", "3:Dev", "5:Test", "6:Commit", "7:Report"],
|
|
58
|
+
local: false,
|
|
59
|
+
autopilot: false,
|
|
60
|
+
},
|
|
61
|
+
"dev-autopilot": {
|
|
62
|
+
phases: ["0:Init", "3:Dev", "6:Commit", "7:Report"],
|
|
63
|
+
local: false,
|
|
64
|
+
autopilot: true,
|
|
65
|
+
},
|
|
66
|
+
"dev-local": {
|
|
67
|
+
phases: ["0:Init", "3:Dev", "6:Commit", "7:Report"],
|
|
68
|
+
local: true,
|
|
69
|
+
autopilot: false,
|
|
70
|
+
},
|
|
71
|
+
"dev-local-autopilot": {
|
|
72
|
+
phases: ["0:Init", "3:Dev", "6:Commit", "7:Report"],
|
|
73
|
+
local: true,
|
|
74
|
+
autopilot: true,
|
|
75
|
+
},
|
|
76
|
+
autopilot: { phases: PHASE_NAMES_NO_TEST, local: false, autopilot: true },
|
|
77
|
+
full: { phases: PHASE_NAMES, local: false, autopilot: false },
|
|
78
|
+
local: { phases: PHASE_NAMES_NO_TEST, local: true, autopilot: false },
|
|
79
|
+
"local-autopilot": { phases: PHASE_NAMES_NO_TEST, local: true, autopilot: true },
|
|
80
|
+
"full-local": { phases: PHASE_NAMES_NO_TEST, local: true, autopilot: false },
|
|
65
81
|
};
|
|
66
82
|
|
|
67
83
|
const spec = MODES[MODE];
|
|
@@ -80,22 +96,23 @@ const phaseSequence = activeIds.map((id) => `Phase ${id}`).join(" → ");
|
|
|
80
96
|
|
|
81
97
|
// Mode label for prose - how to refer to the mode in the TaskCreate paragraph.
|
|
82
98
|
const MODE_LABELS = {
|
|
83
|
-
|
|
84
|
-
"dev-autopilot":
|
|
85
|
-
"dev-local":
|
|
86
|
-
"dev-local-autopilot":
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
"local-autopilot":
|
|
91
|
-
"full-local":
|
|
99
|
+
dev: "`--dev`",
|
|
100
|
+
"dev-autopilot": "`--dev autopilot`",
|
|
101
|
+
"dev-local": "`--dev local`",
|
|
102
|
+
"dev-local-autopilot": "`--dev local autopilot`",
|
|
103
|
+
autopilot: "`autopilot`",
|
|
104
|
+
full: "full-pipeline",
|
|
105
|
+
local: "`--local`",
|
|
106
|
+
"local-autopilot": "`--local autopilot`",
|
|
107
|
+
"full-local": "full-pipeline + `--local`",
|
|
92
108
|
};
|
|
93
109
|
const modeLabel = MODE_LABELS[MODE] ?? `\`${MODE}\``;
|
|
94
110
|
|
|
95
111
|
// Prose for the skip-set + ordering paragraphs.
|
|
96
|
-
const skipNote =
|
|
97
|
-
|
|
98
|
-
|
|
112
|
+
const skipNote =
|
|
113
|
+
skippedIds.length > 0
|
|
114
|
+
? `${modeLabel} mode does NOT TaskCreate phases ${skippedIds.join("/")} - those are not part of the ${modeLabel} phase set (\`${spec.phases.join(" ")}\`). Only register tiles for the active set.`
|
|
115
|
+
: `${modeLabel} mode TaskCreates all 8 phases (no phase is skipped).`;
|
|
99
116
|
|
|
100
117
|
const orderingNote = `**All TaskCreate calls fire in strict phase-number order BEFORE any TaskUpdate is applied.** For ${modeLabel} that means: ${phaseSequence}. The native widget renders by creation order, not by phase number - out-of-order calls produce visually scrambled tile stacks. Full ordering contract in \`$HOME/.claude/multi-agent-refs/tracker-contract.md\` section "TaskCreate ordering (strict)".`;
|
|
101
118
|
|
|
@@ -28,11 +28,26 @@ function parseFrontmatter(md) {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
function categorize(name) {
|
|
31
|
-
if (
|
|
32
|
-
|
|
31
|
+
if (
|
|
32
|
+
name.startsWith("multi-agent") ||
|
|
33
|
+
name === "apple-archive-compliance" ||
|
|
34
|
+
name === "google-play-compliance"
|
|
35
|
+
)
|
|
36
|
+
return "pipeline";
|
|
37
|
+
if (
|
|
38
|
+
/^(swift|swiftui|swiftdata|ios|storekit|healthkit|mapkit|callkit|weatherkit|musickit|passkit|pencilkit|realitykit|cloudkit|apple-on-device-ai|permissionkit|metrickit|homekit-matter|coreml|core-bluetooth|core-motion|core-nfc|speech-recognition|natural-language|vision-framework|contacts-framework|eventkit|energykit|shareplay|background-processing|live-activities|push-notifications|tipkit|widgetkit|authentication|app-clips|app-intents|app-store|alarmkit|macos-|hig-|photos-camera|accessibility-compliance|firebase|device-integrity)/.test(
|
|
39
|
+
name,
|
|
40
|
+
)
|
|
41
|
+
)
|
|
42
|
+
return "ios";
|
|
33
43
|
if (/^(android|compose|gradle|kotlin|retrofit|room|play-store)/.test(name)) return "android";
|
|
34
44
|
if (/^(react|nextjs|vue|tailwind|css|html|typescript|web-|figma)/.test(name)) return "web";
|
|
35
|
-
if (
|
|
45
|
+
if (
|
|
46
|
+
/^(fastapi|nodejs|python|docker|rest-api|api-|database|testing-backend|observability|monorepo)/.test(
|
|
47
|
+
name,
|
|
48
|
+
)
|
|
49
|
+
)
|
|
50
|
+
return "backend";
|
|
36
51
|
return "misc";
|
|
37
52
|
}
|
|
38
53
|
|
|
@@ -66,12 +66,20 @@ for (const e of events) {
|
|
|
66
66
|
if (!id) continue;
|
|
67
67
|
let t = tasks.get(id);
|
|
68
68
|
if (!t) {
|
|
69
|
-
t = {
|
|
69
|
+
t = {
|
|
70
|
+
firstTs: e.ts,
|
|
71
|
+
reviewCycles: null,
|
|
72
|
+
rework: 0,
|
|
73
|
+
tokensIn: 0,
|
|
74
|
+
tokensOut: 0,
|
|
75
|
+
tokensCached: 0,
|
|
76
|
+
};
|
|
70
77
|
tasks.set(id, t);
|
|
71
78
|
}
|
|
72
79
|
if (e.ts && (!t.firstTs || e.ts < t.firstTs)) t.firstTs = e.ts;
|
|
73
80
|
const d = e.details || {};
|
|
74
|
-
if (e.event === "review.completed" && d.review_cycles != null)
|
|
81
|
+
if (e.event === "review.completed" && d.review_cycles != null)
|
|
82
|
+
t.reviewCycles = num(d.review_cycles);
|
|
75
83
|
if (e.event === "rework.started") t.rework += 1;
|
|
76
84
|
t.tokensIn += num(d.tokens_in);
|
|
77
85
|
t.tokensOut += num(d.tokens_out);
|
|
@@ -149,7 +157,9 @@ const arrow = (v, goodIsUp) => {
|
|
|
149
157
|
return `${up ? "+" : ""}${v} ${good ? "(better)" : "(worse)"}`;
|
|
150
158
|
};
|
|
151
159
|
console.log(`# Learning curve (${opts.bucketDays}-day buckets)\n`);
|
|
152
|
-
console.log(
|
|
160
|
+
console.log(
|
|
161
|
+
"| Bucket | Tasks | First-pass clean | Avg review cycles | Rework/task | Tokens/task | Cache ratio |",
|
|
162
|
+
);
|
|
153
163
|
console.log("|---|---|---|---|---|---|---|");
|
|
154
164
|
for (const b of buckets) {
|
|
155
165
|
console.log(
|