code-ai-installer 4.0.0 → 4.0.1-b
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/README.md +83 -67
- package/dist/index.js +2 -0
- package/dist/mcp/audit_ledger.d.ts +12 -0
- package/dist/mcp/audit_ledger.js +82 -0
- package/dist/mcp/cli.js +7 -1
- package/dist/mcp/config.d.ts +23 -0
- package/dist/mcp/config.js +44 -6
- package/dist/mcp/index.d.ts +1 -2
- package/dist/mcp/index.js +1 -2
- package/dist/mcp/paths.d.ts +20 -2
- package/dist/mcp/paths.js +29 -5
- package/dist/mcp/proposal_dedup.d.ts +32 -0
- package/dist/mcp/proposal_dedup.js +102 -0
- package/dist/mcp/proposal_store.d.ts +18 -0
- package/dist/mcp/proposal_store.js +74 -0
- package/dist/mcp/scorecard.d.ts +140 -0
- package/dist/mcp/scorecard.js +103 -0
- package/dist/mcp/skill_invocations.d.ts +15 -0
- package/dist/mcp/skill_invocations.js +28 -0
- package/dist/mcp/task_state.d.ts +77 -2
- package/dist/mcp/tools/_subprocess.d.ts +16 -0
- package/dist/mcp/tools/_subprocess.js +56 -0
- package/dist/mcp/tools/advance_gate.js +2 -2
- package/dist/mcp/tools/aggregate_run_metrics.d.ts +19 -0
- package/dist/mcp/tools/aggregate_run_metrics.js +139 -0
- package/dist/mcp/tools/apply_diff.d.ts +2 -0
- package/dist/mcp/tools/apply_diff.js +29 -0
- package/dist/mcp/tools/audit_bilocale_parity.d.ts +2 -0
- package/dist/mcp/tools/audit_bilocale_parity.js +146 -0
- package/dist/mcp/tools/audit_budget_compliance.d.ts +35 -0
- package/dist/mcp/tools/audit_budget_compliance.js +172 -0
- package/dist/mcp/tools/build.d.ts +2 -0
- package/dist/mcp/tools/build.js +47 -0
- package/dist/mcp/tools/check_lint.d.ts +2 -0
- package/dist/mcp/tools/check_lint.js +23 -0
- package/dist/mcp/tools/classify_gate.js +2 -2
- package/dist/mcp/tools/current_gate.js +2 -2
- package/dist/mcp/tools/dependency_supply_chain.d.ts +2 -0
- package/dist/mcp/tools/dependency_supply_chain.js +59 -0
- package/dist/mcp/tools/docker_compose.d.ts +2 -0
- package/dist/mcp/tools/docker_compose.js +24 -0
- package/dist/mcp/tools/e2e_playwright.d.ts +2 -0
- package/dist/mcp/tools/e2e_playwright.js +88 -0
- package/dist/mcp/tools/get_skill.js +17 -0
- package/dist/mcp/tools/git_commit.d.ts +2 -0
- package/dist/mcp/tools/git_commit.js +30 -0
- package/dist/mcp/tools/list_proposals.d.ts +6 -0
- package/dist/mcp/tools/list_proposals.js +16 -0
- package/dist/mcp/tools/list_skills.js +9 -1
- package/dist/mcp/tools/load_role.d.ts +3 -4
- package/dist/mcp/tools/load_role.js +11 -13
- package/dist/mcp/tools/propose_change.d.ts +8 -0
- package/dist/mcp/tools/propose_change.js +36 -0
- package/dist/mcp/tools/record_decision.js +25 -25
- package/dist/mcp/tools/review_proposal.d.ts +17 -0
- package/dist/mcp/tools/review_proposal.js +99 -0
- package/dist/mcp/tools/run_drift_audit.d.ts +11 -0
- package/dist/mcp/tools/run_drift_audit.js +79 -0
- package/dist/mcp/tools/run_tests.d.ts +2 -0
- package/dist/mcp/tools/run_tests.js +92 -0
- package/dist/mcp/tools/sign_off.js +14 -2
- package/dist/mcp/tools/stubs.js +30 -9
- package/dist/mcp/tools/verify_claim.js +33 -6
- package/dist/mcp_setup.d.ts +14 -3
- package/dist/mcp_setup.js +15 -6
- package/dist/shared/frontmatter.d.ts +44 -2
- package/dist/shared/frontmatter.js +54 -6
- package/dist/shared/index.d.ts +0 -5
- package/dist/shared/index.js +0 -5
- package/dist/shared/persona.d.ts +2 -2
- package/dist/shared/persona.js +1 -1
- package/dist/shared/pipeline.d.ts +46 -1
- package/dist/shared/tools.d.ts +1382 -16
- package/dist/shared/tools.js +229 -0
- package/dist/shared/vocabulary.d.ts +99 -4
- package/dist/shared/vocabulary.js +94 -5
- package/domains/analytics/.agents/skills/ansoff-matrix/SKILL.md +316 -300
- package/domains/analytics/.agents/skills/bcg-matrix/SKILL.md +345 -329
- package/domains/analytics/.agents/skills/blue-ocean-strategy/SKILL.md +432 -416
- package/domains/analytics/.agents/skills/board/SKILL.md +22 -0
- package/domains/analytics/.agents/skills/cohort-analysis/SKILL.md +338 -322
- package/domains/analytics/.agents/skills/competitive-analysis/SKILL.md +413 -395
- package/domains/analytics/.agents/skills/customer-journey-mapping/SKILL.md +347 -331
- package/domains/analytics/.agents/skills/gates/SKILL.md +388 -366
- package/domains/analytics/.agents/skills/handoff/SKILL.md +402 -380
- package/domains/analytics/.agents/skills/html-pdf-report/SKILL.md +21 -289
- package/domains/analytics/.agents/skills/html-pdf-report-reference/SKILL.md +325 -0
- package/domains/analytics/.agents/skills/html-pdf-report-reference/agents/claude.json +17 -0
- package/domains/analytics/.agents/skills/html-pdf-report-reference/agents/copilot.json +17 -0
- package/domains/analytics/.agents/skills/html-pdf-report-reference/agents/gemini.json +17 -0
- package/domains/analytics/.agents/skills/html-pdf-report-reference/agents/kimi.yaml +15 -0
- package/domains/analytics/.agents/skills/html-pdf-report-reference/agents/openai.yaml +10 -0
- package/domains/analytics/.agents/skills/html-pdf-report-reference/agents/qwen.json +17 -0
- package/domains/analytics/.agents/skills/html-pdf-report-reference/agents/skill.yaml +23 -0
- package/domains/analytics/.agents/skills/icp-buyer-persona/SKILL.md +407 -390
- package/domains/analytics/.agents/skills/jtbd-analysis/SKILL.md +357 -341
- package/domains/analytics/.agents/skills/karpathy-guidelines/SKILL.md +32 -0
- package/domains/analytics/.agents/skills/pest-analysis/SKILL.md +324 -305
- package/domains/analytics/.agents/skills/porters-five-forces/SKILL.md +377 -361
- package/domains/analytics/.agents/skills/report-design/SKILL.md +416 -398
- package/domains/analytics/.agents/skills/rfm-analysis/SKILL.md +330 -314
- package/domains/analytics/.agents/skills/session-prompt-generator/SKILL.md +400 -378
- package/domains/analytics/.agents/skills/swot-analysis/SKILL.md +340 -324
- package/domains/analytics/.agents/skills/tam-sam-som/SKILL.md +329 -312
- package/domains/analytics/.agents/skills/trend-analysis/SKILL.md +347 -331
- package/domains/analytics/.agents/skills/unit-economics/SKILL.md +430 -413
- package/domains/analytics/.agents/skills/value-chain-analysis/SKILL.md +346 -330
- package/domains/analytics/.agents/skills/web-research/SKILL.md +323 -308
- package/domains/analytics/AGENTS.md +1 -0
- package/domains/analytics/agents/auditor.md +76 -0
- package/domains/analytics/agents/conductor.md +11 -0
- package/domains/analytics/agents/data_analyst.md +11 -0
- package/domains/analytics/agents/designer.md +11 -0
- package/domains/analytics/agents/interviewer.md +11 -0
- package/domains/analytics/agents/layouter.md +11 -0
- package/domains/analytics/agents/mediator.md +11 -0
- package/domains/analytics/agents/researcher.md +11 -0
- package/domains/analytics/agents/strategist.md +11 -0
- package/domains/analytics/locales/en/.agents/skills/ansoff-matrix/SKILL.md +316 -300
- package/domains/analytics/locales/en/.agents/skills/bcg-matrix/SKILL.md +345 -329
- package/domains/analytics/locales/en/.agents/skills/blue-ocean-strategy/SKILL.md +432 -416
- package/domains/analytics/locales/en/.agents/skills/board/SKILL.md +22 -0
- package/domains/analytics/locales/en/.agents/skills/cohort-analysis/SKILL.md +338 -322
- package/domains/analytics/locales/en/.agents/skills/competitive-analysis/SKILL.md +413 -395
- package/domains/analytics/locales/en/.agents/skills/customer-journey-mapping/SKILL.md +347 -331
- package/domains/analytics/locales/en/.agents/skills/gates/SKILL.md +388 -366
- package/domains/analytics/locales/en/.agents/skills/handoff/SKILL.md +402 -380
- package/domains/analytics/locales/en/.agents/skills/html-pdf-report/SKILL.md +21 -289
- package/domains/analytics/locales/en/.agents/skills/html-pdf-report-reference/SKILL.md +325 -0
- package/domains/analytics/locales/en/.agents/skills/html-pdf-report-reference/agents/claude.json +17 -0
- package/domains/analytics/locales/en/.agents/skills/html-pdf-report-reference/agents/copilot.json +17 -0
- package/domains/analytics/locales/en/.agents/skills/html-pdf-report-reference/agents/gemini.json +17 -0
- package/domains/analytics/locales/en/.agents/skills/html-pdf-report-reference/agents/kimi.yaml +15 -0
- package/domains/analytics/locales/en/.agents/skills/html-pdf-report-reference/agents/openai.yaml +10 -0
- package/domains/analytics/locales/en/.agents/skills/html-pdf-report-reference/agents/qwen.json +17 -0
- package/domains/analytics/locales/en/.agents/skills/html-pdf-report-reference/agents/skill.yaml +29 -0
- package/domains/analytics/locales/en/.agents/skills/icp-buyer-persona/SKILL.md +407 -390
- package/domains/analytics/locales/en/.agents/skills/jtbd-analysis/SKILL.md +357 -341
- package/domains/analytics/locales/en/.agents/skills/karpathy-guidelines/SKILL.md +32 -0
- package/domains/analytics/locales/en/.agents/skills/pest-analysis/SKILL.md +324 -305
- package/domains/analytics/locales/en/.agents/skills/porters-five-forces/SKILL.md +377 -361
- package/domains/analytics/locales/en/.agents/skills/report-design/SKILL.md +416 -398
- package/domains/analytics/locales/en/.agents/skills/rfm-analysis/SKILL.md +330 -314
- package/domains/analytics/locales/en/.agents/skills/session-prompt-generator/SKILL.md +400 -378
- package/domains/analytics/locales/en/.agents/skills/swot-analysis/SKILL.md +340 -324
- package/domains/analytics/locales/en/.agents/skills/tam-sam-som/SKILL.md +329 -312
- package/domains/analytics/locales/en/.agents/skills/trend-analysis/SKILL.md +347 -331
- package/domains/analytics/locales/en/.agents/skills/unit-economics/SKILL.md +430 -413
- package/domains/analytics/locales/en/.agents/skills/value-chain-analysis/SKILL.md +366 -350
- package/domains/analytics/locales/en/.agents/skills/web-research/SKILL.md +324 -309
- package/domains/analytics/locales/en/AGENTS.md +1 -0
- package/domains/analytics/locales/en/agents/auditor.md +76 -0
- package/domains/analytics/locales/en/agents/conductor.md +27 -0
- package/domains/analytics/locales/en/agents/data_analyst.md +29 -0
- package/domains/analytics/locales/en/agents/designer.md +27 -0
- package/domains/analytics/locales/en/agents/interviewer.md +11 -0
- package/domains/analytics/locales/en/agents/layouter.md +11 -0
- package/domains/analytics/locales/en/agents/mediator.md +11 -0
- package/domains/analytics/locales/en/agents/researcher.md +11 -0
- package/domains/analytics/locales/en/agents/strategist.md +11 -0
- package/domains/analytics/persona/persona-base.md +94 -0
- package/domains/analytics/pipeline.yaml +102 -0
- package/domains/content/.agents/skills/audience-analysis/SKILL.md +15 -0
- package/domains/content/.agents/skills/board/SKILL.md +20 -0
- package/domains/content/.agents/skills/brand-compliance/SKILL.md +15 -0
- package/domains/content/.agents/skills/brand-guidelines/SKILL.md +17 -0
- package/domains/content/.agents/skills/competitor-content-analysis/SKILL.md +15 -0
- package/domains/content/.agents/skills/content-brief/SKILL.md +15 -0
- package/domains/content/.agents/skills/content-calendar/SKILL.md +15 -0
- package/domains/content/.agents/skills/content-release-gate/SKILL.md +15 -0
- package/domains/content/.agents/skills/content-review-checklist/SKILL.md +15 -0
- package/domains/content/.agents/skills/cta-optimization/SKILL.md +15 -0
- package/domains/content/.agents/skills/data-storytelling/SKILL.md +15 -0
- package/domains/content/.agents/skills/email-copywriting/SKILL.md +15 -0
- package/domains/content/.agents/skills/email-engagement-tiers/SKILL.md +15 -0
- package/domains/content/.agents/skills/fact-checking/SKILL.md +15 -0
- package/domains/content/.agents/skills/gates/SKILL.md +20 -0
- package/domains/content/.agents/skills/google-stitch-content/SKILL.md +15 -0
- package/domains/content/.agents/skills/handoff/SKILL.md +24 -0
- package/domains/content/.agents/skills/headline-formulas/SKILL.md +15 -0
- package/domains/content/.agents/skills/image-prompt-engineering/SKILL.md +15 -0
- package/domains/content/.agents/skills/karpathy-guidelines/SKILL.md +28 -0
- package/domains/content/.agents/skills/mailerlite-email-ops/SKILL.md +15 -0
- package/domains/content/.agents/skills/marketing-psychology/SKILL.md +15 -0
- package/domains/content/.agents/skills/moodboard/SKILL.md +15 -0
- package/domains/content/.agents/skills/platform-compliance/SKILL.md +15 -0
- package/domains/content/.agents/skills/platform-strategy/SKILL.md +15 -0
- package/domains/content/.agents/skills/platform-visual-specs/SKILL.md +15 -0
- package/domains/content/.agents/skills/readability-scoring/SKILL.md +15 -0
- package/domains/content/.agents/skills/seo-copywriting/SKILL.md +15 -0
- package/domains/content/.agents/skills/social-media-formats/SKILL.md +15 -0
- package/domains/content/.agents/skills/source-verification/SKILL.md +15 -0
- package/domains/content/.agents/skills/storytelling-framework/SKILL.md +15 -0
- package/domains/content/.agents/skills/tone-of-voice/SKILL.md +15 -0
- package/domains/content/.agents/skills/topic-research/SKILL.md +15 -0
- package/domains/content/.agents/skills/trend-research/SKILL.md +15 -0
- package/domains/content/.agents/skills/visual-brief/SKILL.md +15 -0
- package/domains/content/AGENTS.md +4 -0
- package/domains/content/agents/auditor.md +76 -0
- package/domains/content/agents/conductor.md +11 -0
- package/domains/content/agents/copywriter.md +11 -0
- package/domains/content/agents/researcher.md +11 -0
- package/domains/content/agents/reviewer.md +11 -0
- package/domains/content/agents/strategist.md +11 -0
- package/domains/content/agents/visual_concept.md +11 -0
- package/domains/content/locales/en/.agents/skills/audience-analysis/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/board/SKILL.md +20 -0
- package/domains/content/locales/en/.agents/skills/brand-compliance/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/brand-guidelines/SKILL.md +17 -0
- package/domains/content/locales/en/.agents/skills/competitor-content-analysis/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/content-brief/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/content-calendar/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/content-release-gate/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/content-review-checklist/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/cta-optimization/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/data-storytelling/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/email-copywriting/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/email-engagement-tiers/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/fact-checking/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/gates/SKILL.md +20 -0
- package/domains/content/locales/en/.agents/skills/google-stitch-content/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/handoff/SKILL.md +24 -0
- package/domains/content/locales/en/.agents/skills/headline-formulas/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/image-prompt-engineering/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/karpathy-guidelines/SKILL.md +30 -1
- package/domains/content/locales/en/.agents/skills/mailerlite-email-ops/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/marketing-psychology/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/moodboard/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/platform-compliance/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/platform-strategy/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/platform-visual-specs/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/readability-scoring/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/seo-copywriting/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/social-media-formats/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/source-verification/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/storytelling-framework/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/tone-of-voice/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/topic-research/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/trend-research/SKILL.md +15 -0
- package/domains/content/locales/en/.agents/skills/visual-brief/SKILL.md +15 -0
- package/domains/content/locales/en/AGENTS.md +4 -0
- package/domains/content/locales/en/agents/auditor.md +76 -0
- package/domains/content/locales/en/agents/conductor.md +12 -0
- package/domains/content/locales/en/agents/copywriter.md +12 -0
- package/domains/content/locales/en/agents/researcher.md +12 -0
- package/domains/content/locales/en/agents/reviewer.md +12 -0
- package/domains/content/locales/en/agents/strategist.md +12 -0
- package/domains/content/locales/en/agents/visual_concept.md +12 -0
- package/domains/content/persona/persona-base.md +94 -0
- package/domains/content/pipeline.yaml +96 -0
- package/domains/development/.agents/skills/adr-log/SKILL.md +1 -0
- package/domains/development/.agents/skills/design-intake/SKILL.md +0 -4
- package/domains/development/.agents/skills/karpathy-guidelines/SKILL.md +2 -1
- package/domains/development/.agents/skills/lava-flow-legacy-detection/SKILL.md +15 -1
- package/domains/development/.agents/skills/mcp-integration/SKILL.md +211 -0
- package/domains/development/.agents/skills/mcp-integration/agents/claude.json +22 -0
- package/domains/development/.agents/skills/mcp-integration/agents/copilot.json +22 -0
- package/domains/development/.agents/skills/mcp-integration/agents/gemini.json +22 -0
- package/domains/development/.agents/skills/mcp-integration/agents/kimi.yaml +18 -0
- package/domains/development/.agents/skills/mcp-integration/agents/openai.yaml +8 -0
- package/domains/development/.agents/skills/mcp-integration/agents/qwen.json +22 -0
- package/domains/development/.agents/skills/mcp-integration/agents/skill.yaml +26 -0
- package/domains/development/.agents/skills/qa-ui-a11y-smoke/SKILL.md +1 -1
- package/domains/development/.agents/skills/ui-a11y-smoke-review/SKILL.md +1 -1
- package/domains/development/AGENTS.md +1 -0
- package/domains/development/AGENTS.yaml +1 -0
- package/domains/development/agents/architect.md +13 -1
- package/domains/development/agents/auditor.md +74 -0
- package/domains/development/agents/conductor.md +14 -3
- package/domains/development/agents/devops.md +8 -9
- package/domains/development/agents/reviewer.md +12 -0
- package/domains/development/agents/senior_full_stack.md +12 -0
- package/domains/development/agents/tester.md +10 -16
- package/domains/development/locales/en/.agents/skills/adr-log/SKILL.md +1 -0
- package/domains/development/locales/en/.agents/skills/current-state-analysis/SKILL.md +256 -172
- package/domains/development/locales/en/.agents/skills/karpathy-guidelines/SKILL.md +2 -1
- package/domains/development/locales/en/.agents/skills/lava-flow-legacy-detection/SKILL.md +15 -1
- package/domains/development/locales/en/.agents/skills/mcp-integration/SKILL.md +211 -0
- package/domains/development/locales/en/.agents/skills/mcp-integration/agents/claude.json +22 -0
- package/domains/development/locales/en/.agents/skills/mcp-integration/agents/copilot.json +22 -0
- package/domains/development/locales/en/.agents/skills/mcp-integration/agents/gemini.json +22 -0
- package/domains/development/locales/en/.agents/skills/mcp-integration/agents/kimi.yaml +18 -0
- package/domains/development/locales/en/.agents/skills/mcp-integration/agents/openai.yaml +8 -0
- package/domains/development/locales/en/.agents/skills/mcp-integration/agents/qwen.json +22 -0
- package/domains/development/locales/en/.agents/skills/mcp-integration/agents/skill.yaml +26 -0
- package/domains/development/locales/en/.agents/skills/qa-ui-a11y-smoke/SKILL.md +1 -1
- package/domains/development/locales/en/.agents/skills/ui-a11y-smoke-review/SKILL.md +1 -1
- package/domains/development/locales/en/AGENTS.md +5 -0
- package/domains/development/locales/en/AGENTS.yaml +1 -0
- package/domains/development/locales/en/agents/architect.md +13 -1
- package/domains/development/locales/en/agents/auditor.md +74 -0
- package/domains/development/locales/en/agents/conductor.md +14 -3
- package/domains/development/locales/en/agents/devops.md +8 -9
- package/domains/development/locales/en/agents/reviewer.md +12 -0
- package/domains/development/locales/en/agents/senior_full_stack.md +12 -0
- package/domains/development/locales/en/agents/tester.md +10 -16
- package/domains/development/persona/persona-base.md +94 -0
- package/domains/product/.agents/skills/aarrr-metrics/SKILL.md +451 -433
- package/domains/product/.agents/skills/ab-test-design/SKILL.md +428 -412
- package/domains/product/.agents/skills/acceptance-criteria/SKILL.md +422 -406
- package/domains/product/.agents/skills/assumption-mapping/SKILL.md +323 -307
- package/domains/product/.agents/skills/board/SKILL.md +24 -0
- package/domains/product/.agents/skills/design-brief/SKILL.md +433 -418
- package/domains/product/.agents/skills/epic-breakdown/SKILL.md +435 -420
- package/domains/product/.agents/skills/gates/SKILL.md +470 -446
- package/domains/product/.agents/skills/gtm-brief/SKILL.md +18 -321
- package/domains/product/.agents/skills/gtm-brief-reference/SKILL.md +348 -0
- package/domains/product/.agents/skills/gtm-brief-reference/agents/claude.json +17 -0
- package/domains/product/.agents/skills/gtm-brief-reference/agents/copilot.json +17 -0
- package/domains/product/.agents/skills/gtm-brief-reference/agents/gemini.json +17 -0
- package/domains/product/.agents/skills/gtm-brief-reference/agents/kimi.yaml +15 -0
- package/domains/product/.agents/skills/gtm-brief-reference/agents/openai.yaml +10 -0
- package/domains/product/.agents/skills/gtm-brief-reference/agents/qwen.json +17 -0
- package/domains/product/.agents/skills/gtm-brief-reference/agents/skill.yaml +22 -0
- package/domains/product/.agents/skills/handoff/SKILL.md +463 -439
- package/domains/product/.agents/skills/html-pdf-report/SKILL.md +21 -663
- package/domains/product/.agents/skills/html-pdf-report-reference/SKILL.md +699 -0
- package/domains/product/.agents/skills/html-pdf-report-reference/agents/claude.json +17 -0
- package/domains/product/.agents/skills/html-pdf-report-reference/agents/copilot.json +17 -0
- package/domains/product/.agents/skills/html-pdf-report-reference/agents/gemini.json +17 -0
- package/domains/product/.agents/skills/html-pdf-report-reference/agents/kimi.yaml +15 -0
- package/domains/product/.agents/skills/html-pdf-report-reference/agents/openai.yaml +10 -0
- package/domains/product/.agents/skills/html-pdf-report-reference/agents/qwen.json +17 -0
- package/domains/product/.agents/skills/html-pdf-report-reference/agents/skill.yaml +22 -0
- package/domains/product/.agents/skills/hypothesis-template/SKILL.md +484 -469
- package/domains/product/.agents/skills/jtbd-canvas/SKILL.md +274 -258
- package/domains/product/.agents/skills/kano-model/SKILL.md +370 -355
- package/domains/product/.agents/skills/karpathy-guidelines/SKILL.md +36 -0
- package/domains/product/.agents/skills/launch-checklist/SKILL.md +434 -419
- package/domains/product/.agents/skills/moscow-prioritization/SKILL.md +407 -392
- package/domains/product/.agents/skills/north-star-metric/SKILL.md +317 -301
- package/domains/product/.agents/skills/okr-framework/SKILL.md +299 -284
- package/domains/product/.agents/skills/opportunity-solution-tree/SKILL.md +472 -456
- package/domains/product/.agents/skills/prd-template/SKILL.md +18 -258
- package/domains/product/.agents/skills/prd-template-reference/SKILL.md +285 -0
- package/domains/product/.agents/skills/prd-template-reference/agents/claude.json +17 -0
- package/domains/product/.agents/skills/prd-template-reference/agents/copilot.json +17 -0
- package/domains/product/.agents/skills/prd-template-reference/agents/gemini.json +17 -0
- package/domains/product/.agents/skills/prd-template-reference/agents/kimi.yaml +16 -0
- package/domains/product/.agents/skills/prd-template-reference/agents/openai.yaml +10 -0
- package/domains/product/.agents/skills/prd-template-reference/agents/qwen.json +17 -0
- package/domains/product/.agents/skills/prd-template-reference/agents/skill.yaml +23 -0
- package/domains/product/.agents/skills/problem-statement/SKILL.md +327 -312
- package/domains/product/.agents/skills/product-roadmap/SKILL.md +320 -304
- package/domains/product/.agents/skills/product-vision/SKILL.md +409 -394
- package/domains/product/.agents/skills/release-notes/SKILL.md +18 -258
- package/domains/product/.agents/skills/release-notes-reference/SKILL.md +285 -0
- package/domains/product/.agents/skills/release-notes-reference/agents/claude.json +17 -0
- package/domains/product/.agents/skills/release-notes-reference/agents/copilot.json +17 -0
- package/domains/product/.agents/skills/release-notes-reference/agents/gemini.json +17 -0
- package/domains/product/.agents/skills/release-notes-reference/agents/kimi.yaml +15 -0
- package/domains/product/.agents/skills/release-notes-reference/agents/openai.yaml +10 -0
- package/domains/product/.agents/skills/release-notes-reference/agents/qwen.json +17 -0
- package/domains/product/.agents/skills/release-notes-reference/agents/skill.yaml +22 -0
- package/domains/product/.agents/skills/report-design/SKILL.md +17 -307
- package/domains/product/.agents/skills/report-design-reference/SKILL.md +331 -0
- package/domains/product/.agents/skills/report-design-reference/agents/claude.json +17 -0
- package/domains/product/.agents/skills/report-design-reference/agents/copilot.json +17 -0
- package/domains/product/.agents/skills/report-design-reference/agents/gemini.json +17 -0
- package/domains/product/.agents/skills/report-design-reference/agents/kimi.yaml +15 -0
- package/domains/product/.agents/skills/report-design-reference/agents/openai.yaml +10 -0
- package/domains/product/.agents/skills/report-design-reference/agents/qwen.json +17 -0
- package/domains/product/.agents/skills/report-design-reference/agents/skill.yaml +22 -0
- package/domains/product/.agents/skills/rice-scoring/SKILL.md +266 -251
- package/domains/product/.agents/skills/saas-metrics/SKILL.md +422 -404
- package/domains/product/.agents/skills/session-prompt-generator/SKILL.md +474 -450
- package/domains/product/.agents/skills/user-flow/SKILL.md +491 -476
- package/domains/product/.agents/skills/user-interview-script/SKILL.md +315 -298
- package/domains/product/.agents/skills/user-story/SKILL.md +401 -385
- package/domains/product/.agents/skills/wsjf-scoring/SKILL.md +333 -315
- package/domains/product/AGENTS.md +5 -0
- package/domains/product/AGENTS.yaml +1 -0
- package/domains/product/agents/auditor.md +76 -0
- package/domains/product/agents/conductor.md +11 -0
- package/domains/product/agents/data_analyst.md +11 -0
- package/domains/product/agents/designer.md +11 -0
- package/domains/product/agents/discovery.md +11 -0
- package/domains/product/agents/layouter.md +11 -0
- package/domains/product/agents/mediator.md +11 -0
- package/domains/product/agents/pm.md +11 -0
- package/domains/product/agents/product_strategist.md +11 -0
- package/domains/product/agents/tech_lead.md +11 -0
- package/domains/product/agents/ux_designer.md +11 -0
- package/domains/product/locales/en/.agents/skills/aarrr-metrics/SKILL.md +451 -433
- package/domains/product/locales/en/.agents/skills/ab-test-design/SKILL.md +428 -412
- package/domains/product/locales/en/.agents/skills/acceptance-criteria/SKILL.md +422 -406
- package/domains/product/locales/en/.agents/skills/assumption-mapping/SKILL.md +323 -307
- package/domains/product/locales/en/.agents/skills/board/SKILL.md +24 -0
- package/domains/product/locales/en/.agents/skills/design-brief/SKILL.md +433 -418
- package/domains/product/locales/en/.agents/skills/epic-breakdown/SKILL.md +435 -420
- package/domains/product/locales/en/.agents/skills/gates/SKILL.md +470 -446
- package/domains/product/locales/en/.agents/skills/gtm-brief/SKILL.md +18 -321
- package/domains/product/locales/en/.agents/skills/gtm-brief-reference/SKILL.md +348 -0
- package/domains/product/locales/en/.agents/skills/gtm-brief-reference/agents/claude.json +17 -0
- package/domains/product/locales/en/.agents/skills/gtm-brief-reference/agents/copilot.json +17 -0
- package/domains/product/locales/en/.agents/skills/gtm-brief-reference/agents/gemini.json +17 -0
- package/domains/product/locales/en/.agents/skills/gtm-brief-reference/agents/kimi.yaml +15 -0
- package/domains/product/locales/en/.agents/skills/gtm-brief-reference/agents/openai.yaml +10 -0
- package/domains/product/locales/en/.agents/skills/gtm-brief-reference/agents/qwen.json +17 -0
- package/domains/product/locales/en/.agents/skills/gtm-brief-reference/agents/skill.yaml +22 -0
- package/domains/product/locales/en/.agents/skills/handoff/SKILL.md +463 -439
- package/domains/product/locales/en/.agents/skills/html-pdf-report/SKILL.md +21 -663
- package/domains/product/locales/en/.agents/skills/html-pdf-report-reference/SKILL.md +699 -0
- package/domains/product/locales/en/.agents/skills/html-pdf-report-reference/agents/claude.json +17 -0
- package/domains/product/locales/en/.agents/skills/html-pdf-report-reference/agents/copilot.json +17 -0
- package/domains/product/locales/en/.agents/skills/html-pdf-report-reference/agents/gemini.json +17 -0
- package/domains/product/locales/en/.agents/skills/html-pdf-report-reference/agents/kimi.yaml +15 -0
- package/domains/product/locales/en/.agents/skills/html-pdf-report-reference/agents/openai.yaml +10 -0
- package/domains/product/locales/en/.agents/skills/html-pdf-report-reference/agents/qwen.json +17 -0
- package/domains/product/locales/en/.agents/skills/html-pdf-report-reference/agents/skill.yaml +22 -0
- package/domains/product/locales/en/.agents/skills/hypothesis-template/SKILL.md +484 -469
- package/domains/product/locales/en/.agents/skills/jtbd-canvas/SKILL.md +273 -257
- package/domains/product/locales/en/.agents/skills/kano-model/SKILL.md +370 -355
- package/domains/product/locales/en/.agents/skills/karpathy-guidelines/SKILL.md +36 -0
- package/domains/product/locales/en/.agents/skills/launch-checklist/SKILL.md +434 -419
- package/domains/product/locales/en/.agents/skills/moscow-prioritization/SKILL.md +407 -392
- package/domains/product/locales/en/.agents/skills/north-star-metric/SKILL.md +317 -301
- package/domains/product/locales/en/.agents/skills/okr-framework/SKILL.md +299 -284
- package/domains/product/locales/en/.agents/skills/opportunity-solution-tree/SKILL.md +472 -456
- package/domains/product/locales/en/.agents/skills/prd-template/SKILL.md +18 -258
- package/domains/product/locales/en/.agents/skills/prd-template-reference/SKILL.md +285 -0
- package/domains/product/locales/en/.agents/skills/prd-template-reference/agents/claude.json +16 -0
- package/domains/product/locales/en/.agents/skills/prd-template-reference/agents/copilot.json +16 -0
- package/domains/product/locales/en/.agents/skills/prd-template-reference/agents/gemini.json +16 -0
- package/domains/product/locales/en/.agents/skills/prd-template-reference/agents/kimi.yaml +15 -0
- package/domains/product/locales/en/.agents/skills/prd-template-reference/agents/openai.yaml +10 -0
- package/domains/product/locales/en/.agents/skills/prd-template-reference/agents/qwen.json +16 -0
- package/domains/product/locales/en/.agents/skills/prd-template-reference/agents/skill.yaml +22 -0
- package/domains/product/locales/en/.agents/skills/problem-statement/SKILL.md +327 -312
- package/domains/product/locales/en/.agents/skills/product-roadmap/SKILL.md +321 -305
- package/domains/product/locales/en/.agents/skills/product-vision/SKILL.md +410 -395
- package/domains/product/locales/en/.agents/skills/release-notes/SKILL.md +18 -258
- package/domains/product/locales/en/.agents/skills/release-notes-reference/SKILL.md +285 -0
- package/domains/product/locales/en/.agents/skills/release-notes-reference/agents/claude.json +16 -0
- package/domains/product/locales/en/.agents/skills/release-notes-reference/agents/copilot.json +16 -0
- package/domains/product/locales/en/.agents/skills/release-notes-reference/agents/gemini.json +16 -0
- package/domains/product/locales/en/.agents/skills/release-notes-reference/agents/kimi.yaml +14 -0
- package/domains/product/locales/en/.agents/skills/release-notes-reference/agents/openai.yaml +10 -0
- package/domains/product/locales/en/.agents/skills/release-notes-reference/agents/qwen.json +16 -0
- package/domains/product/locales/en/.agents/skills/release-notes-reference/agents/skill.yaml +21 -0
- package/domains/product/locales/en/.agents/skills/report-design/SKILL.md +17 -307
- package/domains/product/locales/en/.agents/skills/report-design-reference/SKILL.md +331 -0
- package/domains/product/locales/en/.agents/skills/report-design-reference/agents/claude.json +17 -0
- package/domains/product/locales/en/.agents/skills/report-design-reference/agents/copilot.json +17 -0
- package/domains/product/locales/en/.agents/skills/report-design-reference/agents/gemini.json +17 -0
- package/domains/product/locales/en/.agents/skills/report-design-reference/agents/kimi.yaml +15 -0
- package/domains/product/locales/en/.agents/skills/report-design-reference/agents/openai.yaml +10 -0
- package/domains/product/locales/en/.agents/skills/report-design-reference/agents/qwen.json +17 -0
- package/domains/product/locales/en/.agents/skills/report-design-reference/agents/skill.yaml +22 -0
- package/domains/product/locales/en/.agents/skills/rice-scoring/SKILL.md +266 -251
- package/domains/product/locales/en/.agents/skills/saas-metrics/SKILL.md +422 -404
- package/domains/product/locales/en/.agents/skills/session-prompt-generator/SKILL.md +474 -450
- package/domains/product/locales/en/.agents/skills/user-flow/SKILL.md +491 -476
- package/domains/product/locales/en/.agents/skills/user-interview-script/SKILL.md +314 -297
- package/domains/product/locales/en/.agents/skills/user-story/SKILL.md +401 -385
- package/domains/product/locales/en/.agents/skills/wsjf-scoring/SKILL.md +333 -315
- package/domains/product/locales/en/AGENTS.md +5 -0
- package/domains/product/locales/en/agents/auditor.md +76 -0
- package/domains/product/locales/en/agents/conductor.md +11 -0
- package/domains/product/locales/en/agents/data_analyst.md +11 -0
- package/domains/product/locales/en/agents/designer.md +11 -0
- package/domains/product/locales/en/agents/discovery.md +11 -0
- package/domains/product/locales/en/agents/layouter.md +11 -0
- package/domains/product/locales/en/agents/mediator.md +11 -0
- package/domains/product/locales/en/agents/pm.md +11 -0
- package/domains/product/locales/en/agents/product_strategist.md +11 -0
- package/domains/product/locales/en/agents/tech_lead.md +11 -0
- package/domains/product/locales/en/agents/ux_designer.md +11 -0
- package/domains/product/persona/persona-base.md +94 -0
- package/domains/product/pipeline.yaml +115 -0
- package/package.json +72 -70
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { performance } from "node:perf_hooks";
|
|
3
|
+
export function npmCommand() {
|
|
4
|
+
return process.platform === "win32" ? "npm.cmd" : "npm";
|
|
5
|
+
}
|
|
6
|
+
export async function spawnWithOutput(command, args, opts) {
|
|
7
|
+
return new Promise((resolve) => {
|
|
8
|
+
const start = performance.now();
|
|
9
|
+
let stdout = "";
|
|
10
|
+
let stderr = "";
|
|
11
|
+
const env = opts.env ? { ...process.env, ...opts.env } : process.env;
|
|
12
|
+
// Windows: Node 20+ refuses to spawn .cmd/.bat without a shell (CVE-2024-27980).
|
|
13
|
+
// `npm` and `npx` are .cmd shims on Windows, so we run through cmd.exe there.
|
|
14
|
+
// We control args (no untrusted user input), so shell: true is safe here.
|
|
15
|
+
const useShell = process.platform === "win32";
|
|
16
|
+
const stdinMode = opts.stdin !== undefined ? "pipe" : "ignore";
|
|
17
|
+
const proc = spawn(command, args, {
|
|
18
|
+
cwd: opts.cwd,
|
|
19
|
+
env,
|
|
20
|
+
stdio: [stdinMode, "pipe", "pipe"],
|
|
21
|
+
shell: useShell,
|
|
22
|
+
});
|
|
23
|
+
if (opts.stdin !== undefined && proc.stdin) {
|
|
24
|
+
proc.stdin.write(opts.stdin);
|
|
25
|
+
proc.stdin.end();
|
|
26
|
+
}
|
|
27
|
+
proc.stdout?.on("data", (chunk) => {
|
|
28
|
+
stdout += chunk.toString("utf8");
|
|
29
|
+
});
|
|
30
|
+
proc.stderr?.on("data", (chunk) => {
|
|
31
|
+
stderr += chunk.toString("utf8");
|
|
32
|
+
});
|
|
33
|
+
proc.on("error", (err) => {
|
|
34
|
+
resolve({
|
|
35
|
+
exitCode: null,
|
|
36
|
+
stdout,
|
|
37
|
+
stderr,
|
|
38
|
+
durationMs: Math.round(performance.now() - start),
|
|
39
|
+
spawnError: err,
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
proc.on("close", (code) => {
|
|
43
|
+
resolve({
|
|
44
|
+
exitCode: code,
|
|
45
|
+
stdout,
|
|
46
|
+
stderr,
|
|
47
|
+
durationMs: Math.round(performance.now() - start),
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
export function tail(text, maxBytes) {
|
|
53
|
+
if (text.length <= maxBytes)
|
|
54
|
+
return text;
|
|
55
|
+
return "…" + text.slice(text.length - maxBytes);
|
|
56
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getGateConfig, getNextGate, loadPipeline } from "../pipeline.js";
|
|
2
2
|
import { latestSignoff, readTaskState, writeTaskState } from "../task_state.js";
|
|
3
|
-
|
|
3
|
+
import { resolveActiveDomain } from "../config.js";
|
|
4
4
|
/**
|
|
5
5
|
* Advances the task from `from_gate` to `to_gate`.
|
|
6
6
|
*
|
|
@@ -20,7 +20,7 @@ const DEFAULT_DOMAIN = "development";
|
|
|
20
20
|
* Future call resets dev_rollback_count if pipeline.reset_on includes rg_pass.
|
|
21
21
|
*/
|
|
22
22
|
export async function advanceGate(input) {
|
|
23
|
-
const pipeline = await loadPipeline(
|
|
23
|
+
const pipeline = await loadPipeline(await resolveActiveDomain());
|
|
24
24
|
const state = await readTaskState(input.task_id);
|
|
25
25
|
if (!state) {
|
|
26
26
|
throw new Error(`advance_gate: no task state for ${input.task_id}`);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { AggregateRunMetricsInput, AggregateRunMetricsOutput } from "../../shared/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Aggregate run scorecards from the local ledger into deterministic per-agent
|
|
4
|
+
* and per-workflow statistics. Read-only surfacing tool (like
|
|
5
|
+
* audit_budget_compliance): it reports numbers, it does not judge — judgment is
|
|
6
|
+
* the Auditor agent's job (a later ADR).
|
|
7
|
+
*
|
|
8
|
+
* Attribution: per-AGENT via gate→produced_by[0] from pipeline.yaml (single
|
|
9
|
+
* source); per-WORKFLOW via mode. Only COMPLETED runs (RG signed) are
|
|
10
|
+
* aggregated; `min_runs` (default 3) is the design's small-sample guard — below
|
|
11
|
+
* it `met_threshold=false` and the Auditor should stay silent.
|
|
12
|
+
*
|
|
13
|
+
* Honest gaps surfaced in `notes`, not faked: skill invocations ARE captured as
|
|
14
|
+
* per_skill (incl. the gates a skill was pulled at) via get_skill instrumentation
|
|
15
|
+
* (ADR-DEV-121) — the remaining gap is trigger_accuracy (relevant-vs-invoked),
|
|
16
|
+
* which needs a relevance oracle; no explicit human-rejection signal; completed =
|
|
17
|
+
* RG signed (completed_at unset).
|
|
18
|
+
*/
|
|
19
|
+
export declare function aggregateRunMetrics(input: AggregateRunMetricsInput): Promise<AggregateRunMetricsOutput>;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { loadPipeline } from "../pipeline.js";
|
|
2
|
+
import { readLedger } from "../audit_ledger.js";
|
|
3
|
+
import { resolveActiveDomain } from "../config.js";
|
|
4
|
+
/**
|
|
5
|
+
* Aggregate run scorecards from the local ledger into deterministic per-agent
|
|
6
|
+
* and per-workflow statistics. Read-only surfacing tool (like
|
|
7
|
+
* audit_budget_compliance): it reports numbers, it does not judge — judgment is
|
|
8
|
+
* the Auditor agent's job (a later ADR).
|
|
9
|
+
*
|
|
10
|
+
* Attribution: per-AGENT via gate→produced_by[0] from pipeline.yaml (single
|
|
11
|
+
* source); per-WORKFLOW via mode. Only COMPLETED runs (RG signed) are
|
|
12
|
+
* aggregated; `min_runs` (default 3) is the design's small-sample guard — below
|
|
13
|
+
* it `met_threshold=false` and the Auditor should stay silent.
|
|
14
|
+
*
|
|
15
|
+
* Honest gaps surfaced in `notes`, not faked: skill invocations ARE captured as
|
|
16
|
+
* per_skill (incl. the gates a skill was pulled at) via get_skill instrumentation
|
|
17
|
+
* (ADR-DEV-121) — the remaining gap is trigger_accuracy (relevant-vs-invoked),
|
|
18
|
+
* which needs a relevance oracle; no explicit human-rejection signal; completed =
|
|
19
|
+
* RG signed (completed_at unset).
|
|
20
|
+
*/
|
|
21
|
+
export async function aggregateRunMetrics(input) {
|
|
22
|
+
const minRuns = input.min_runs;
|
|
23
|
+
const cards = await readLedger();
|
|
24
|
+
const completed = cards.filter((c) => c.completed);
|
|
25
|
+
// gate → owning role, from pipeline.yaml (first produced_by per gate).
|
|
26
|
+
const pipeline = await loadPipeline(await resolveActiveDomain());
|
|
27
|
+
const gateRole = new Map();
|
|
28
|
+
for (const m of pipeline.modes) {
|
|
29
|
+
for (const g of m.gates) {
|
|
30
|
+
if (!gateRole.has(g.gate) && g.produced_by.length > 0) {
|
|
31
|
+
gateRole.set(g.gate, g.produced_by[0]);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// ── per-workflow (mode) ──
|
|
36
|
+
const wf = new Map();
|
|
37
|
+
for (const c of completed) {
|
|
38
|
+
const e = wf.get(c.mode) ?? { runs: 0, completed: 0, rollbacks: 0, cb: 0, exceptions: 0 };
|
|
39
|
+
e.runs++;
|
|
40
|
+
e.completed++;
|
|
41
|
+
e.rollbacks += c.dev_rollback_count;
|
|
42
|
+
e.cb += c.circuit_breaker_tripped ? 1 : 0;
|
|
43
|
+
e.exceptions += c.exceptions_count;
|
|
44
|
+
wf.set(c.mode, e);
|
|
45
|
+
}
|
|
46
|
+
const per_workflow = [...wf.entries()].sort().map(([mode, e]) => ({
|
|
47
|
+
mode: mode,
|
|
48
|
+
runs: e.runs,
|
|
49
|
+
completed: e.completed,
|
|
50
|
+
avg_dev_rollbacks: round2(e.rollbacks / e.runs),
|
|
51
|
+
circuit_breaker_trips: e.cb,
|
|
52
|
+
total_exceptions: e.exceptions,
|
|
53
|
+
}));
|
|
54
|
+
const agents = new Map();
|
|
55
|
+
for (const c of completed) {
|
|
56
|
+
for (const g of c.gates) {
|
|
57
|
+
const role = gateRole.get(g.gate) ?? "unknown";
|
|
58
|
+
const key = `${role}|${g.gate}`;
|
|
59
|
+
const a = agents.get(key) ??
|
|
60
|
+
{
|
|
61
|
+
role,
|
|
62
|
+
gate: g.gate,
|
|
63
|
+
runs_involved: 0,
|
|
64
|
+
reworked: 0,
|
|
65
|
+
exceptions: 0,
|
|
66
|
+
auto_resolve: 0,
|
|
67
|
+
fork: 0,
|
|
68
|
+
exception: 0,
|
|
69
|
+
};
|
|
70
|
+
a.runs_involved++;
|
|
71
|
+
if (g.signoff_count > 1)
|
|
72
|
+
a.reworked++;
|
|
73
|
+
a.exceptions += g.exceptions_count;
|
|
74
|
+
if (g.classification === "auto_resolve")
|
|
75
|
+
a.auto_resolve++;
|
|
76
|
+
else if (g.classification === "fork")
|
|
77
|
+
a.fork++;
|
|
78
|
+
else if (g.classification === "exception")
|
|
79
|
+
a.exception++;
|
|
80
|
+
agents.set(key, a);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const per_agent = [...agents.values()]
|
|
84
|
+
.sort((x, y) => (x.role + x.gate).localeCompare(y.role + y.gate))
|
|
85
|
+
.map((a) => ({
|
|
86
|
+
role: a.role,
|
|
87
|
+
gate: a.gate,
|
|
88
|
+
runs_involved: a.runs_involved,
|
|
89
|
+
reworked: a.reworked,
|
|
90
|
+
first_try_rate: round2((a.runs_involved - a.reworked) / a.runs_involved),
|
|
91
|
+
exceptions: a.exceptions,
|
|
92
|
+
classification_breakdown: {
|
|
93
|
+
auto_resolve: a.auto_resolve,
|
|
94
|
+
fork: a.fork,
|
|
95
|
+
exception: a.exception,
|
|
96
|
+
},
|
|
97
|
+
}));
|
|
98
|
+
// ── per-skill (invocation frequency + gate/run co-occurrence) ──
|
|
99
|
+
const skills = new Map();
|
|
100
|
+
for (const c of completed) {
|
|
101
|
+
for (const s of c.skill_invocations) {
|
|
102
|
+
const a = skills.get(s.skill) ??
|
|
103
|
+
{ skill: s.skill, invocations: 0, runs: new Set(), gates: new Set() };
|
|
104
|
+
a.invocations += s.count;
|
|
105
|
+
a.runs.add(c.task_id);
|
|
106
|
+
if (s.gate)
|
|
107
|
+
a.gates.add(s.gate);
|
|
108
|
+
skills.set(s.skill, a);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
const per_skill = [...skills.values()]
|
|
112
|
+
.sort((x, y) => x.skill.localeCompare(y.skill))
|
|
113
|
+
.map((a) => ({
|
|
114
|
+
skill: a.skill,
|
|
115
|
+
invocations: a.invocations,
|
|
116
|
+
runs_invoked_in: a.runs.size,
|
|
117
|
+
gates: [...a.gates].sort(),
|
|
118
|
+
}));
|
|
119
|
+
const notes = [
|
|
120
|
+
"completed = RG sign-off present (state machine does not populate completed_at).",
|
|
121
|
+
"Skill invocations ARE captured (get_skill instrumentation, ADR-DEV-121): per_skill carries invocation counts + the gates each skill was pulled at, so skill.gates can be tuned to observed usage. The remaining gap is trigger_accuracy (relevant-vs-invoked), which needs a relevance oracle — not this data layer.",
|
|
122
|
+
"No explicit human gate-rejection signal; rejections manifest as rollbacks/exceptions.",
|
|
123
|
+
"Per-agent attribution uses gate→produced_by[0] from the active domain's pipeline.yaml.",
|
|
124
|
+
"Skill invocation = a get_skill fetch tied to a run (proxy: a skill applied from memory without re-fetching is invisible). trigger_accuracy (relevant-vs-invoked) is the Auditor agent's judgment — needs a relevance oracle, not in this data layer.",
|
|
125
|
+
];
|
|
126
|
+
return {
|
|
127
|
+
runs_in_ledger: cards.length,
|
|
128
|
+
runs_completed: completed.length,
|
|
129
|
+
min_runs: minRuns,
|
|
130
|
+
met_threshold: completed.length >= minRuns,
|
|
131
|
+
per_workflow,
|
|
132
|
+
per_agent,
|
|
133
|
+
per_skill,
|
|
134
|
+
notes,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
function round2(n) {
|
|
138
|
+
return Number.isFinite(n) ? Math.round(n * 100) / 100 : 0;
|
|
139
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { spawnWithOutput, tail } from "./_subprocess.js";
|
|
2
|
+
const GIT = process.platform === "win32" ? "git.exe" : "git";
|
|
3
|
+
export async function applyDiff(input) {
|
|
4
|
+
const cwd = input.cwd ?? process.cwd();
|
|
5
|
+
const apply = await spawnWithOutput(GIT, ["apply", "--whitespace=nowarn", "-"], {
|
|
6
|
+
cwd,
|
|
7
|
+
stdin: input.diff,
|
|
8
|
+
});
|
|
9
|
+
if (apply.exitCode !== 0) {
|
|
10
|
+
throw new Error(`git apply failed (exit=${apply.exitCode}): ${tail(apply.stderr, 2000) || tail(apply.stdout, 2000)}`);
|
|
11
|
+
}
|
|
12
|
+
const status = await spawnWithOutput(GIT, ["status", "--porcelain"], { cwd });
|
|
13
|
+
if (status.exitCode !== 0) {
|
|
14
|
+
throw new Error(`git status failed after apply (exit=${status.exitCode}): ${tail(status.stderr, 1000)}`);
|
|
15
|
+
}
|
|
16
|
+
const files = parsePorcelain(status.stdout);
|
|
17
|
+
return { files_changed: files };
|
|
18
|
+
}
|
|
19
|
+
function parsePorcelain(out) {
|
|
20
|
+
const lines = out.split(/\r?\n/).filter((l) => l.length > 0);
|
|
21
|
+
const seen = new Set();
|
|
22
|
+
for (const line of lines) {
|
|
23
|
+
const rest = line.slice(3);
|
|
24
|
+
const arrow = rest.indexOf(" -> ");
|
|
25
|
+
const path = arrow >= 0 ? rest.slice(arrow + 4) : rest;
|
|
26
|
+
seen.add(path);
|
|
27
|
+
}
|
|
28
|
+
return [...seen].sort();
|
|
29
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { DomainId, } from "../../shared/index.js";
|
|
4
|
+
import { resolveDomainRoot } from "../paths.js";
|
|
5
|
+
import { countLines, parseDeclaredBudget } from "./audit_budget_compliance.js";
|
|
6
|
+
export async function auditBilocaleParity(input) {
|
|
7
|
+
const domains = input.domain === "*" ? [...DomainId.options] : [input.domain];
|
|
8
|
+
const declared_mismatches = [];
|
|
9
|
+
const actual_mismatches = [];
|
|
10
|
+
const orphans = [];
|
|
11
|
+
let pairsScanned = 0;
|
|
12
|
+
let agentsScanned = 0;
|
|
13
|
+
let skillsScanned = 0;
|
|
14
|
+
for (const domain of domains) {
|
|
15
|
+
const r = await scanDomain(domain);
|
|
16
|
+
declared_mismatches.push(...r.declared_mismatches);
|
|
17
|
+
actual_mismatches.push(...r.actual_mismatches);
|
|
18
|
+
orphans.push(...r.orphans);
|
|
19
|
+
pairsScanned += r.pairs;
|
|
20
|
+
agentsScanned += r.agents;
|
|
21
|
+
skillsScanned += r.skills;
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
declared_mismatches,
|
|
25
|
+
actual_mismatches,
|
|
26
|
+
orphans,
|
|
27
|
+
scanned: { pairs: pairsScanned, agents: agentsScanned, skills: skillsScanned },
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
async function scanDomain(domain) {
|
|
31
|
+
const domainRoot = resolveDomainRoot(domain);
|
|
32
|
+
const pairs = await collectPairs(domainRoot);
|
|
33
|
+
const declared_mismatches = [];
|
|
34
|
+
const actual_mismatches = [];
|
|
35
|
+
const orphans = [];
|
|
36
|
+
let agentsScanned = 0;
|
|
37
|
+
let skillsScanned = 0;
|
|
38
|
+
for (const p of pairs) {
|
|
39
|
+
if (p.kind === "agent")
|
|
40
|
+
agentsScanned++;
|
|
41
|
+
else
|
|
42
|
+
skillsScanned++;
|
|
43
|
+
if (p.ru_abs === null || p.en_abs === null) {
|
|
44
|
+
const present_locale = p.ru_abs === null ? "en" : "ru";
|
|
45
|
+
const present_path = p.ru_abs === null ? p.en_rel_path : p.ru_rel_path;
|
|
46
|
+
const missing_locale = p.ru_abs === null ? "ru" : "en";
|
|
47
|
+
orphans.push({
|
|
48
|
+
domain,
|
|
49
|
+
id: p.id,
|
|
50
|
+
file_type: p.kind,
|
|
51
|
+
present_locale,
|
|
52
|
+
present_path,
|
|
53
|
+
missing_locale,
|
|
54
|
+
message: `${p.kind} '${p.id}' exists only in ${present_locale} (${present_path}); no ${missing_locale} sibling`,
|
|
55
|
+
});
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
const ruRaw = await readFile(p.ru_abs, "utf8").catch(() => null);
|
|
59
|
+
const enRaw = await readFile(p.en_abs, "utf8").catch(() => null);
|
|
60
|
+
if (ruRaw === null || enRaw === null)
|
|
61
|
+
continue;
|
|
62
|
+
const ruDeclared = parseDeclaredBudget(ruRaw);
|
|
63
|
+
const enDeclared = parseDeclaredBudget(enRaw);
|
|
64
|
+
if (ruDeclared !== null && enDeclared !== null && ruDeclared !== enDeclared) {
|
|
65
|
+
declared_mismatches.push({
|
|
66
|
+
domain,
|
|
67
|
+
id: p.id,
|
|
68
|
+
file_type: p.kind,
|
|
69
|
+
ru_path: p.ru_rel_path,
|
|
70
|
+
en_path: p.en_rel_path,
|
|
71
|
+
ru_declared: ruDeclared,
|
|
72
|
+
en_declared: enDeclared,
|
|
73
|
+
message: `${p.kind} '${p.id}' declares budget_lines=${ruDeclared} (ru) vs ${enDeclared} (en)`,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
const ruActual = countLines(ruRaw);
|
|
77
|
+
const enActual = countLines(enRaw);
|
|
78
|
+
if (ruActual !== enActual) {
|
|
79
|
+
actual_mismatches.push({
|
|
80
|
+
domain,
|
|
81
|
+
id: p.id,
|
|
82
|
+
file_type: p.kind,
|
|
83
|
+
ru_path: p.ru_rel_path,
|
|
84
|
+
en_path: p.en_rel_path,
|
|
85
|
+
ru_actual: ruActual,
|
|
86
|
+
en_actual: enActual,
|
|
87
|
+
diff: ruActual - enActual,
|
|
88
|
+
message: `${p.kind} '${p.id}' has ${ruActual} lines (ru) vs ${enActual} lines (en) (diff=${ruActual - enActual})`,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
declared_mismatches,
|
|
94
|
+
actual_mismatches,
|
|
95
|
+
orphans,
|
|
96
|
+
pairs: pairs.length,
|
|
97
|
+
agents: agentsScanned,
|
|
98
|
+
skills: skillsScanned,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
async function collectPairs(domainRoot) {
|
|
102
|
+
const pairs = [];
|
|
103
|
+
// Agents: pair by filename across agents/ (ru) and locales/en/agents/ (en).
|
|
104
|
+
const ruAgentsDir = join(domainRoot, "agents");
|
|
105
|
+
const enAgentsDir = join(domainRoot, "locales", "en", "agents");
|
|
106
|
+
const ruAgents = new Set(await listMdFiles(ruAgentsDir));
|
|
107
|
+
const enAgents = new Set(await listMdFiles(enAgentsDir));
|
|
108
|
+
for (const f of union(ruAgents, enAgents)) {
|
|
109
|
+
pairs.push({
|
|
110
|
+
kind: "agent",
|
|
111
|
+
id: f,
|
|
112
|
+
ru_rel_path: `agents/${f}`,
|
|
113
|
+
en_rel_path: `locales/en/agents/${f}`,
|
|
114
|
+
ru_abs: ruAgents.has(f) ? join(ruAgentsDir, f) : null,
|
|
115
|
+
en_abs: enAgents.has(f) ? join(enAgentsDir, f) : null,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
// Skills: pair by skill-dir name across .agents/skills/ (ru) and
|
|
119
|
+
// locales/en/.agents/skills/ (en). SKILL.md is the file inside each dir.
|
|
120
|
+
const ruSkillsRoot = join(domainRoot, ".agents", "skills");
|
|
121
|
+
const enSkillsRoot = join(domainRoot, "locales", "en", ".agents", "skills");
|
|
122
|
+
const ruSkills = new Set(await listSubdirs(ruSkillsRoot));
|
|
123
|
+
const enSkills = new Set(await listSubdirs(enSkillsRoot));
|
|
124
|
+
for (const d of union(ruSkills, enSkills)) {
|
|
125
|
+
pairs.push({
|
|
126
|
+
kind: "skill",
|
|
127
|
+
id: d,
|
|
128
|
+
ru_rel_path: `.agents/skills/${d}/SKILL.md`,
|
|
129
|
+
en_rel_path: `locales/en/.agents/skills/${d}/SKILL.md`,
|
|
130
|
+
ru_abs: ruSkills.has(d) ? join(ruSkillsRoot, d, "SKILL.md") : null,
|
|
131
|
+
en_abs: enSkills.has(d) ? join(enSkillsRoot, d, "SKILL.md") : null,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
return pairs;
|
|
135
|
+
}
|
|
136
|
+
function union(a, b) {
|
|
137
|
+
return [...new Set([...a, ...b])].sort();
|
|
138
|
+
}
|
|
139
|
+
async function listMdFiles(dir) {
|
|
140
|
+
const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
141
|
+
return entries.filter((e) => e.isFile() && e.name.endsWith(".md")).map((e) => e.name);
|
|
142
|
+
}
|
|
143
|
+
async function listSubdirs(dir) {
|
|
144
|
+
const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
145
|
+
return entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
146
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type AuditBudgetComplianceInput, type AuditBudgetComplianceOutput } from "../../shared/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Audit two classes of budget violations across agent.md + SKILL.md files:
|
|
4
|
+
*
|
|
5
|
+
* 1. SCHEMA CAP — declared `budget_lines` in frontmatter exceeds the schema
|
|
6
|
+
* maximum (RoleFrontmatter: 500, SkillFrontmatter: 800). When this
|
|
7
|
+
* happens, RoleFrontmatter / SkillFrontmatter safeParse silently rejects
|
|
8
|
+
* the whole frontmatter; load_role / list_skills / get_skill then fall
|
|
9
|
+
* back to H1-synthesized stubs. This was the DEV-107 latent bug.
|
|
10
|
+
*
|
|
11
|
+
* 2. BUDGET EXCEEDED — actual file line count exceeds the declared
|
|
12
|
+
* `budget_lines`. Nothing enforces this today; files can silently grow.
|
|
13
|
+
*
|
|
14
|
+
* Scans both RU canonical and EN sidecar locales. Each file declares its own
|
|
15
|
+
* budget_lines, so they are audited independently.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Count lines the way an editor / `wc -l` does: a trailing newline terminates
|
|
19
|
+
* the final line, it does not create a phantom empty line. A file with no
|
|
20
|
+
* trailing newline still counts its final unterminated line.
|
|
21
|
+
*
|
|
22
|
+
* Fixes an off-by-one where `raw.split(/\r?\n/).length` counted the empty
|
|
23
|
+
* segment after the final newline — inflating every file's line count by 1 and
|
|
24
|
+
* falsely flagging files that sit exactly at their declared budget.
|
|
25
|
+
*/
|
|
26
|
+
export declare function countLines(raw: string): number;
|
|
27
|
+
/**
|
|
28
|
+
* Parse the declared `budget_lines` from a file's frontmatter. Returns null when
|
|
29
|
+
* there is no frontmatter block, the YAML is malformed, or budget_lines is
|
|
30
|
+
* absent / non-numeric — callers skip such files. Shared with
|
|
31
|
+
* audit_bilocale_parity so both tools read declared budgets identically
|
|
32
|
+
* (single source, ADR-DEV-116; same spirit as the DEV-115 schema-cap exports).
|
|
33
|
+
*/
|
|
34
|
+
export declare function parseDeclaredBudget(raw: string): number | null;
|
|
35
|
+
export declare function auditBudgetCompliance(input: AuditBudgetComplianceInput): Promise<AuditBudgetComplianceOutput>;
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { parse as parseYaml } from "yaml";
|
|
4
|
+
import { DomainId, ROLE_BUDGET_LINES_MAX, SKILL_BUDGET_LINES_MAX, } from "../../shared/index.js";
|
|
5
|
+
import { resolveDomainRoot } from "../paths.js";
|
|
6
|
+
/**
|
|
7
|
+
* Audit two classes of budget violations across agent.md + SKILL.md files:
|
|
8
|
+
*
|
|
9
|
+
* 1. SCHEMA CAP — declared `budget_lines` in frontmatter exceeds the schema
|
|
10
|
+
* maximum (RoleFrontmatter: 500, SkillFrontmatter: 800). When this
|
|
11
|
+
* happens, RoleFrontmatter / SkillFrontmatter safeParse silently rejects
|
|
12
|
+
* the whole frontmatter; load_role / list_skills / get_skill then fall
|
|
13
|
+
* back to H1-synthesized stubs. This was the DEV-107 latent bug.
|
|
14
|
+
*
|
|
15
|
+
* 2. BUDGET EXCEEDED — actual file line count exceeds the declared
|
|
16
|
+
* `budget_lines`. Nothing enforces this today; files can silently grow.
|
|
17
|
+
*
|
|
18
|
+
* Scans both RU canonical and EN sidecar locales. Each file declares its own
|
|
19
|
+
* budget_lines, so they are audited independently.
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Count lines the way an editor / `wc -l` does: a trailing newline terminates
|
|
23
|
+
* the final line, it does not create a phantom empty line. A file with no
|
|
24
|
+
* trailing newline still counts its final unterminated line.
|
|
25
|
+
*
|
|
26
|
+
* Fixes an off-by-one where `raw.split(/\r?\n/).length` counted the empty
|
|
27
|
+
* segment after the final newline — inflating every file's line count by 1 and
|
|
28
|
+
* falsely flagging files that sit exactly at their declared budget.
|
|
29
|
+
*/
|
|
30
|
+
export function countLines(raw) {
|
|
31
|
+
if (raw === "")
|
|
32
|
+
return 0;
|
|
33
|
+
const body = raw.replace(/\r?\n$/, "");
|
|
34
|
+
return body.split(/\r?\n/).length;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Parse the declared `budget_lines` from a file's frontmatter. Returns null when
|
|
38
|
+
* there is no frontmatter block, the YAML is malformed, or budget_lines is
|
|
39
|
+
* absent / non-numeric — callers skip such files. Shared with
|
|
40
|
+
* audit_bilocale_parity so both tools read declared budgets identically
|
|
41
|
+
* (single source, ADR-DEV-116; same spirit as the DEV-115 schema-cap exports).
|
|
42
|
+
*/
|
|
43
|
+
export function parseDeclaredBudget(raw) {
|
|
44
|
+
const stripped = raw.startsWith("") ? raw.slice(1) : raw;
|
|
45
|
+
const m = stripped.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
46
|
+
if (!m)
|
|
47
|
+
return null;
|
|
48
|
+
let parsedYaml;
|
|
49
|
+
try {
|
|
50
|
+
parsedYaml = parseYaml(m[1]);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
const declaredRaw = parsedYaml?.budget_lines;
|
|
56
|
+
return typeof declaredRaw === "number" ? declaredRaw : null;
|
|
57
|
+
}
|
|
58
|
+
export async function auditBudgetCompliance(input) {
|
|
59
|
+
const domains = input.domain === "*" ? [...DomainId.options] : [input.domain];
|
|
60
|
+
const schema_violations = [];
|
|
61
|
+
const budget_violations = [];
|
|
62
|
+
let agentsScanned = 0;
|
|
63
|
+
let skillsScanned = 0;
|
|
64
|
+
for (const domain of domains) {
|
|
65
|
+
const r = await scanDomain(domain);
|
|
66
|
+
schema_violations.push(...r.schema_violations);
|
|
67
|
+
budget_violations.push(...r.budget_violations);
|
|
68
|
+
agentsScanned += r.agents;
|
|
69
|
+
skillsScanned += r.skills;
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
schema_violations,
|
|
73
|
+
budget_violations,
|
|
74
|
+
scanned: { agents: agentsScanned, skills: skillsScanned },
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
async function scanDomain(domain) {
|
|
78
|
+
const domainRoot = resolveDomainRoot(domain);
|
|
79
|
+
const targets = await collectTargets(domainRoot);
|
|
80
|
+
const schema_violations = [];
|
|
81
|
+
const budget_violations = [];
|
|
82
|
+
let agentsScanned = 0;
|
|
83
|
+
let skillsScanned = 0;
|
|
84
|
+
for (const t of targets) {
|
|
85
|
+
const raw = await readFile(t.abs_path, "utf8").catch(() => null);
|
|
86
|
+
if (raw === null)
|
|
87
|
+
continue;
|
|
88
|
+
if (t.kind === "agent")
|
|
89
|
+
agentsScanned++;
|
|
90
|
+
else
|
|
91
|
+
skillsScanned++;
|
|
92
|
+
const declared = parseDeclaredBudget(raw);
|
|
93
|
+
if (declared === null)
|
|
94
|
+
continue;
|
|
95
|
+
const schemaMax = t.kind === "agent" ? ROLE_BUDGET_LINES_MAX : SKILL_BUDGET_LINES_MAX;
|
|
96
|
+
if (declared > schemaMax) {
|
|
97
|
+
schema_violations.push({
|
|
98
|
+
domain,
|
|
99
|
+
file: t.rel_path,
|
|
100
|
+
file_type: t.kind,
|
|
101
|
+
declared_budget: declared,
|
|
102
|
+
schema_max: schemaMax,
|
|
103
|
+
message: `${t.kind} '${t.rel_path}' declares budget_lines=${declared} which exceeds schema cap ${schemaMax}; safeParse will silently fall back`,
|
|
104
|
+
});
|
|
105
|
+
// Skip budget-exceeded check when declared itself is rejected.
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
const actual = countLines(raw);
|
|
109
|
+
if (actual > declared) {
|
|
110
|
+
budget_violations.push({
|
|
111
|
+
domain,
|
|
112
|
+
file: t.rel_path,
|
|
113
|
+
file_type: t.kind,
|
|
114
|
+
declared_budget: declared,
|
|
115
|
+
actual_lines: actual,
|
|
116
|
+
overage: actual - declared,
|
|
117
|
+
message: `${t.kind} '${t.rel_path}' has ${actual} lines but declares budget_lines=${declared} (overage=${actual - declared})`,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return { schema_violations, budget_violations, agents: agentsScanned, skills: skillsScanned };
|
|
122
|
+
}
|
|
123
|
+
async function collectTargets(domainRoot) {
|
|
124
|
+
const result = [];
|
|
125
|
+
const ruAgentsDir = join(domainRoot, "agents");
|
|
126
|
+
for (const f of await listMdFiles(ruAgentsDir)) {
|
|
127
|
+
result.push({
|
|
128
|
+
locale: "ru",
|
|
129
|
+
kind: "agent",
|
|
130
|
+
abs_path: join(ruAgentsDir, f),
|
|
131
|
+
rel_path: `agents/${f}`,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
const enAgentsDir = join(domainRoot, "locales", "en", "agents");
|
|
135
|
+
for (const f of await listMdFiles(enAgentsDir)) {
|
|
136
|
+
result.push({
|
|
137
|
+
locale: "en",
|
|
138
|
+
kind: "agent",
|
|
139
|
+
abs_path: join(enAgentsDir, f),
|
|
140
|
+
rel_path: `locales/en/agents/${f}`,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
const ruSkillsRoot = join(domainRoot, ".agents", "skills");
|
|
144
|
+
for (const d of await listSubdirs(ruSkillsRoot)) {
|
|
145
|
+
result.push({
|
|
146
|
+
locale: "ru",
|
|
147
|
+
kind: "skill",
|
|
148
|
+
abs_path: join(ruSkillsRoot, d, "SKILL.md"),
|
|
149
|
+
rel_path: `.agents/skills/${d}/SKILL.md`,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
const enSkillsRoot = join(domainRoot, "locales", "en", ".agents", "skills");
|
|
153
|
+
for (const d of await listSubdirs(enSkillsRoot)) {
|
|
154
|
+
result.push({
|
|
155
|
+
locale: "en",
|
|
156
|
+
kind: "skill",
|
|
157
|
+
abs_path: join(enSkillsRoot, d, "SKILL.md"),
|
|
158
|
+
rel_path: `locales/en/.agents/skills/${d}/SKILL.md`,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
return result;
|
|
162
|
+
}
|
|
163
|
+
async function listMdFiles(dir) {
|
|
164
|
+
const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
165
|
+
return entries
|
|
166
|
+
.filter((e) => e.isFile() && e.name.endsWith(".md"))
|
|
167
|
+
.map((e) => e.name);
|
|
168
|
+
}
|
|
169
|
+
async function listSubdirs(dir) {
|
|
170
|
+
const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
171
|
+
return entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
172
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { npmCommand, spawnWithOutput, tail } from "./_subprocess.js";
|
|
2
|
+
const TSC_LINE = /^(.+?)\((\d+),(\d+)\):\s+error\s+(TS\d+):\s+(.+)$/gm;
|
|
3
|
+
export async function build(input) {
|
|
4
|
+
const cwd = input.cwd ?? process.cwd();
|
|
5
|
+
const result = await spawnWithOutput(npmCommand(), ["run", "build"], { cwd });
|
|
6
|
+
if (result.exitCode === 0) {
|
|
7
|
+
return { succeeded: true, errors: [] };
|
|
8
|
+
}
|
|
9
|
+
const tscErrors = parseTscErrors(`${result.stdout}\n${result.stderr}`);
|
|
10
|
+
if (tscErrors.length > 0) {
|
|
11
|
+
return { succeeded: false, errors: tscErrors };
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
succeeded: false,
|
|
15
|
+
errors: [
|
|
16
|
+
{
|
|
17
|
+
code: "build-failure",
|
|
18
|
+
message: `build exited with code ${result.exitCode}`,
|
|
19
|
+
evidence: {
|
|
20
|
+
stdout: tail(result.stdout, 4000),
|
|
21
|
+
stderr: tail(result.stderr, 4000),
|
|
22
|
+
duration_ms: result.durationMs,
|
|
23
|
+
spawnError: result.spawnError?.message,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function parseTscErrors(text) {
|
|
30
|
+
const out = [];
|
|
31
|
+
TSC_LINE.lastIndex = 0;
|
|
32
|
+
for (const m of text.matchAll(TSC_LINE)) {
|
|
33
|
+
const [, file, line, col, code, msg] = m;
|
|
34
|
+
const normalizedFile = file.replace(/\\/g, "/");
|
|
35
|
+
out.push({
|
|
36
|
+
code: `${code}-${normalizedFile}-L${line}`,
|
|
37
|
+
message: `${file}(${line},${col}) ${code}: ${msg}`,
|
|
38
|
+
evidence: {
|
|
39
|
+
file: normalizedFile,
|
|
40
|
+
line: Number(line),
|
|
41
|
+
column: Number(col),
|
|
42
|
+
tsCode: code,
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
}
|