@event4u/agent-config 9.9.0 → 9.11.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.
Files changed (479) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +212 -194
  3. package/README.md +13 -16
  4. package/agents/templates/.ai-council.yml.example +481 -0
  5. package/agents/templates/.ai-video.xml.example +247 -0
  6. package/dist/agent-src/commands/agent-status.md +12 -11
  7. package/dist/agent-src/commands/agents/user/accept.md +115 -30
  8. package/dist/agent-src/commands/agents/user/delete.md +147 -0
  9. package/dist/agent-src/commands/agents/user/review.md +65 -28
  10. package/dist/agent-src/commands/agents/user/show.md +82 -29
  11. package/dist/agent-src/commands/agents/user/update.md +2 -2
  12. package/dist/agent-src/commands/agents/user.md +16 -3
  13. package/dist/agent-src/commands/check-current-md.md +0 -10
  14. package/dist/agent-src/commands/condense.md +28 -97
  15. package/dist/agent-src/commands/cost/report.md +7 -0
  16. package/dist/agent-src/commands/fix/portability.md +0 -8
  17. package/dist/agent-src/commands/fix/refs.md +0 -8
  18. package/dist/agent-src/commands/humanize.md +2 -2
  19. package/dist/agent-src/commands/jira-ticket.md +1 -1
  20. package/dist/agent-src/commands/memory/load.md +11 -0
  21. package/dist/agent-src/commands/optimize/skills.md +1 -1
  22. package/dist/agent-src/commands/pr/create.md +4 -4
  23. package/dist/agent-src/commands/profile/show.md +3 -3
  24. package/dist/agent-src/commands/rule-compliance-audit.md +5 -4
  25. package/dist/agent-src/commands/security-audit-config.md +1 -1
  26. package/dist/agent-src/commands/sync/gitignore/fix.md +1 -1
  27. package/dist/agent-src/commands/tdd.md +21 -0
  28. package/dist/agent-src/commands/team/delegate.md +2 -2
  29. package/dist/agent-src/commands/team-knowledge/bootstrap.md +9 -8
  30. package/dist/agent-src/commands/team-knowledge/consolidate.md +8 -7
  31. package/dist/agent-src/commands/team.md +4 -1
  32. package/dist/agent-src/commands/upstream-contribute.md +0 -1
  33. package/dist/agent-src/contexts/authority/commit-mechanics.md +7 -0
  34. package/dist/agent-src/contexts/authority/destructive-mechanics.md +16 -0
  35. package/dist/agent-src/contexts/authority/scope-mechanics.md +61 -0
  36. package/dist/agent-src/contexts/communication/rules-auto/reply-close-mechanics.md +20 -18
  37. package/dist/agent-src/contexts/communication/rules-auto/skill-quality-mechanics.md +1 -1
  38. package/dist/agent-src/contexts/communication/rules-auto/slash-command-routing-policy-mechanics.md +1 -1
  39. package/dist/agent-src/contexts/communication/rules-auto/source-of-truth-mechanics.md +9 -10
  40. package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +1 -1
  41. package/dist/agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +11 -0
  42. package/dist/agent-src/contexts/contracts/artifact-engagement-flow.md +26 -15
  43. package/dist/agent-src/contexts/contracts/command-suggestion-flow.md +3 -0
  44. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +67 -37
  45. package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +1 -1
  46. package/dist/agent-src/contexts/execution/autonomy-examples.md +1 -1
  47. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +7 -6
  48. package/dist/agent-src/contexts/execution/evidence-discipline.md +92 -77
  49. package/dist/agent-src/contexts/execution/orchestration-benchmark-gate.md +22 -21
  50. package/dist/agent-src/contexts/execution/orchestration-telemetry.md +24 -0
  51. package/dist/agent-src/contexts/execution/project-intelligence.md +122 -103
  52. package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +23 -21
  53. package/dist/agent-src/contexts/execution/subagent-response-contract.md +5 -5
  54. package/dist/agent-src/contexts/execution/subagent-routing.md +11 -0
  55. package/dist/agent-src/contexts/execution/subagent-spawn-contract.md +13 -13
  56. package/dist/agent-src/contexts/execution/subagent-steering.md +36 -34
  57. package/dist/agent-src/contexts/execution/toolchain-resolver.md +1 -1
  58. package/dist/agent-src/contexts/execution/user-memory-channels.md +189 -0
  59. package/dist/agent-src/contexts/execution/verification-mechanics.md +9 -0
  60. package/dist/agent-src/contexts/model-recommendations.md +3 -2
  61. package/dist/agent-src/contexts/subagent-configuration.md +3 -3
  62. package/dist/agent-src/ghostwriter/README.md +2 -2
  63. package/dist/agent-src/packs/README.md +1 -1
  64. package/dist/agent-src/personas/README.md +5 -5
  65. package/dist/agent-src/personas/_template-specialist/persona.md +3 -3
  66. package/dist/agent-src/personas/backend-architect.md +24 -23
  67. package/dist/agent-src/personas/eloquent-tamer.md +30 -30
  68. package/dist/agent-src/personas/frontend-engineer.md +30 -30
  69. package/dist/agent-src/personas/product-owner.md +41 -38
  70. package/dist/agent-src/personas/qa.md +13 -13
  71. package/dist/agent-src/personas/security-engineer.md +22 -22
  72. package/dist/agent-src/presets/README.md +3 -3
  73. package/dist/agent-src/profiles/README.md +3 -3
  74. package/dist/agent-src/rules/active-remediation.md +2 -2
  75. package/dist/agent-src/rules/artifact-engagement-recording.md +4 -4
  76. package/dist/agent-src/rules/ask-when-uncertain.md +0 -4
  77. package/dist/agent-src/rules/augment-edit-discipline.md +1 -1
  78. package/dist/agent-src/rules/broken-access-control.md +4 -4
  79. package/dist/agent-src/rules/code-comment-discipline.md +1 -1
  80. package/dist/agent-src/rules/code-provenance.md +2 -2
  81. package/dist/agent-src/rules/commit-policy.md +4 -9
  82. package/dist/agent-src/rules/communication-through-line.md +5 -5
  83. package/dist/agent-src/rules/decision-revisit-gate.md +1 -1
  84. package/dist/agent-src/rules/design-fidelity.md +1 -1
  85. package/dist/agent-src/rules/doc-screenshot-hygiene.md +1 -1
  86. package/dist/agent-src/rules/domain-adoption-policy.md +1 -1
  87. package/dist/agent-src/rules/domain-safety-pii.md +1 -1
  88. package/dist/agent-src/rules/external-code-graph-interop.md +1 -1
  89. package/dist/agent-src/rules/fast-path-marker-visibility.md +43 -7
  90. package/dist/agent-src/rules/finance-safety-floor.md +1 -1
  91. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +3 -3
  92. package/dist/agent-src/rules/history-discipline.md +1 -1
  93. package/dist/agent-src/rules/legal-safety-floor.md +1 -1
  94. package/dist/agent-src/rules/lethal-trifecta-guard.md +5 -5
  95. package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +10 -8
  96. package/dist/agent-src/rules/media-governance-routing.md +13 -13
  97. package/dist/agent-src/rules/media-sync-ground-truth.md +29 -11
  98. package/dist/agent-src/rules/no-cheap-questions.md +7 -7
  99. package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +29 -18
  100. package/dist/agent-src/rules/non-destructive-by-default.md +5 -23
  101. package/dist/agent-src/rules/onboarding-gate.md +14 -4
  102. package/dist/agent-src/rules/persona-governance.md +2 -2
  103. package/dist/agent-src/rules/prefer-enums-over-literals.md +9 -9
  104. package/dist/agent-src/rules/preservation-guard.md +10 -2
  105. package/dist/agent-src/rules/question-not-instruction.md +1 -1
  106. package/dist/agent-src/rules/roadmap-progress-sync.md +6 -6
  107. package/dist/agent-src/rules/rule-type-governance.md +1 -1
  108. package/dist/agent-src/rules/scale-discipline.md +1 -1
  109. package/dist/agent-src/rules/scope-control.md +1 -1
  110. package/dist/agent-src/rules/secret-vcs-guard.md +1 -1
  111. package/dist/agent-src/rules/security-sensitive-stop.md +17 -11
  112. package/dist/agent-src/rules/senior-engineering-discipline.md +17 -17
  113. package/dist/agent-src/rules/session-canary.md +1 -1
  114. package/dist/agent-src/rules/skill-quality.md +1 -1
  115. package/dist/agent-src/rules/source-confidentiality.md +21 -19
  116. package/dist/agent-src/rules/source-of-truth.md +6 -5
  117. package/dist/agent-src/rules/spreadsheet-source-quality.md +2 -2
  118. package/dist/agent-src/rules/strategy-safety-floor.md +1 -1
  119. package/dist/agent-src/rules/think-before-action.md +5 -5
  120. package/dist/agent-src/rules/token-budget-discipline.md +5 -3
  121. package/dist/agent-src/rules/token-efficiency.md +2 -2
  122. package/dist/agent-src/rules/untrusted-input-defense.md +4 -4
  123. package/dist/agent-src/rules/user-interaction.md +12 -0
  124. package/dist/agent-src/rules/verify-before-complete.md +4 -24
  125. package/dist/agent-src/skills/adversarial-review/SKILL.md +2 -2
  126. package/dist/agent-src/skills/agent-security-review/SKILL.md +52 -45
  127. package/dist/agent-src/skills/agents-md-thin-root/SKILL.md +2 -2
  128. package/dist/agent-src/skills/ai-code-blindspots/SKILL.md +20 -20
  129. package/dist/agent-src/skills/ai-council/SKILL.md +185 -128
  130. package/dist/agent-src/skills/analysis-skill-router/SKILL.md +3 -3
  131. package/dist/agent-src/skills/api-endpoint/SKILL.md +2 -2
  132. package/dist/agent-src/skills/artisan-commands/SKILL.md +2 -2
  133. package/dist/agent-src/skills/async-python-patterns/SKILL.md +8 -7
  134. package/dist/agent-src/skills/authz-review/SKILL.md +16 -15
  135. package/dist/agent-src/skills/aws-infrastructure/SKILL.md +5 -5
  136. package/dist/agent-src/skills/blade-ui/SKILL.md +1 -1
  137. package/dist/agent-src/skills/bug-analyzer/SKILL.md +30 -12
  138. package/dist/agent-src/skills/code-intelligence/SKILL.md +0 -1
  139. package/dist/agent-src/skills/code-intelligence/evals/triggers.json +52 -0
  140. package/dist/agent-src/skills/code-review/SKILL.md +6 -6
  141. package/dist/agent-src/skills/command-routing/SKILL.md +5 -4
  142. package/dist/agent-src/skills/composer-packages/SKILL.md +2 -2
  143. package/dist/agent-src/skills/condense-memory/SKILL.md +43 -41
  144. package/dist/agent-src/skills/context-document/SKILL.md +23 -21
  145. package/dist/agent-src/skills/copilot-config/SKILL.md +6 -1
  146. package/dist/agent-src/skills/decision-record/SKILL.md +20 -18
  147. package/dist/agent-src/skills/design-intelligence/SKILL.md +4 -4
  148. package/dist/agent-src/skills/design-review/SKILL.md +15 -14
  149. package/dist/agent-src/skills/design-system-capture/reference/design-system-json.md +28 -25
  150. package/dist/agent-src/skills/devcontainer/SKILL.md +2 -2
  151. package/dist/agent-src/skills/docker/SKILL.md +1 -1
  152. package/dist/agent-src/skills/docx-authoring/evals/triggers.json +52 -0
  153. package/dist/agent-src/skills/emit-tickets/SKILL.md +2 -2
  154. package/dist/agent-src/skills/error-handling-patterns/SKILL.md +1 -1
  155. package/dist/agent-src/skills/estimate-ticket/SKILL.md +2 -2
  156. package/dist/agent-src/skills/evaluate-llm-feature/SKILL.md +0 -1
  157. package/dist/agent-src/skills/evaluate-llm-feature/evals/triggers.json +52 -0
  158. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +21 -7
  159. package/dist/agent-src/skills/fe-design/SKILL.md +10 -0
  160. package/dist/agent-src/skills/feature-planning/SKILL.md +2 -2
  161. package/dist/agent-src/skills/finishing-a-development-branch/SKILL.md +3 -3
  162. package/dist/agent-src/skills/flux/SKILL.md +1 -1
  163. package/dist/agent-src/skills/frontend-render-security/SKILL.md +13 -13
  164. package/dist/agent-src/skills/git-workflow/SKILL.md +33 -33
  165. package/dist/agent-src/skills/grafana/SKILL.md +5 -0
  166. package/dist/agent-src/skills/humanizer/SKILL.md +83 -66
  167. package/dist/agent-src/skills/humanizer/data/patterns.md +14 -14
  168. package/dist/agent-src/skills/humanizer/references/anti-aiisms.md +4 -4
  169. package/dist/agent-src/skills/judge-artifact-completeness/SKILL.md +82 -37
  170. package/dist/agent-src/skills/judge-bug-hunter/SKILL.md +17 -5
  171. package/dist/agent-src/skills/judge-injection-defense/SKILL.md +63 -25
  172. package/dist/agent-src/skills/judge-security-auditor/SKILL.md +2 -0
  173. package/dist/agent-src/skills/judge-synthesis/SKILL.md +72 -28
  174. package/dist/agent-src/skills/laravel-horizon/SKILL.md +5 -0
  175. package/dist/agent-src/skills/laravel-mail/SKILL.md +5 -4
  176. package/dist/agent-src/skills/laravel-middleware/SKILL.md +5 -4
  177. package/dist/agent-src/skills/laravel-notifications/SKILL.md +10 -9
  178. package/dist/agent-src/skills/laravel-pennant/SKILL.md +1 -1
  179. package/dist/agent-src/skills/laravel-pulse/SKILL.md +9 -8
  180. package/dist/agent-src/skills/laravel-reverb/SKILL.md +6 -5
  181. package/dist/agent-src/skills/laravel-scheduling/SKILL.md +6 -1
  182. package/dist/agent-src/skills/laravel-validation/SKILL.md +12 -0
  183. package/dist/agent-src/skills/launch-readiness/SKILL.md +1 -1
  184. package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +7 -7
  185. package/dist/agent-src/skills/learning-tutor/SKILL.md +44 -43
  186. package/dist/agent-src/skills/learning-tutor/evals/triggers.json +52 -0
  187. package/dist/agent-src/skills/license-compliance-audit/SKILL.md +7 -7
  188. package/dist/agent-src/skills/license-compliance-borrow-check/SKILL.md +3 -3
  189. package/dist/agent-src/skills/license-compliance-credits/SKILL.md +4 -4
  190. package/dist/agent-src/skills/llm-provider-knowledge/SKILL.md +0 -1
  191. package/dist/agent-src/skills/memory-consolidation/SKILL.md +69 -64
  192. package/dist/agent-src/skills/motion-choreographer/SKILL.md +6 -6
  193. package/dist/agent-src/skills/pdf-tools/evals/triggers.json +52 -0
  194. package/dist/agent-src/skills/performance-analysis/SKILL.md +7 -3
  195. package/dist/agent-src/skills/persona-improvement/SKILL.md +0 -2
  196. package/dist/agent-src/skills/persona-improvement/evals/triggers.json +52 -0
  197. package/dist/agent-src/skills/php-coder/SKILL.md +10 -0
  198. package/dist/agent-src/skills/prediction-pool-optimizer/SKILL.md +129 -120
  199. package/dist/agent-src/skills/prediction-pool-optimizer/reference/ev-fixtures.md +36 -35
  200. package/dist/agent-src/skills/prediction-pool-optimizer/reference/odds-and-bonus.md +45 -41
  201. package/dist/agent-src/skills/project-analysis-core/SKILL.md +4 -4
  202. package/dist/agent-src/skills/project-analysis-hypothesis-driven/SKILL.md +3 -3
  203. package/dist/agent-src/skills/project-analysis-react/SKILL.md +1 -1
  204. package/dist/agent-src/skills/project-analysis-symfony/SKILL.md +1 -1
  205. package/dist/agent-src/skills/project-analysis-zend-laminas/SKILL.md +2 -2
  206. package/dist/agent-src/skills/prompt-engineering-patterns/SKILL.md +1 -1
  207. package/dist/agent-src/skills/prompt-validator/SKILL.md +39 -39
  208. package/dist/agent-src/skills/quality-tools/SKILL.md +15 -15
  209. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +55 -19
  210. package/dist/agent-src/skills/react-shadcn-ui/reference/registry.md +29 -27
  211. package/dist/agent-src/skills/readme-writing-package/SKILL.md +2 -2
  212. package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +25 -25
  213. package/dist/agent-src/skills/recursive-verification/SKILL.md +6 -5
  214. package/dist/agent-src/skills/refine-prompt/SKILL.md +1 -1
  215. package/dist/agent-src/skills/refine-ticket/SKILL.md +20 -2
  216. package/dist/agent-src/skills/repomix-packer/SKILL.md +1 -1
  217. package/dist/agent-src/skills/requesting-code-review/SKILL.md +2 -2
  218. package/dist/agent-src/skills/roadmap-management/SKILL.md +80 -66
  219. package/dist/agent-src/skills/roadmap-writing/SKILL.md +84 -77
  220. package/dist/agent-src/skills/rule-refactor/SKILL.md +1 -1
  221. package/dist/agent-src/skills/screenshot-hygiene/evals/triggers.json +52 -0
  222. package/dist/agent-src/skills/security-audit/SKILL.md +26 -9
  223. package/dist/agent-src/skills/security-maturity-assessment/SKILL.md +38 -16
  224. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +14 -11
  225. package/dist/agent-src/skills/skill-writing/SKILL.md +9 -8
  226. package/dist/agent-src/skills/song-to-script/SKILL.md +93 -85
  227. package/dist/agent-src/skills/sql-writing/SKILL.md +2 -2
  228. package/dist/agent-src/skills/stakeholder-tradeoff/SKILL.md +4 -3
  229. package/dist/agent-src/skills/standards-from-config/SKILL.md +61 -43
  230. package/dist/agent-src/skills/subagent-orchestration/SKILL.md +22 -8
  231. package/dist/agent-src/skills/subagent-orchestration/prompts/README.md +28 -2
  232. package/dist/agent-src/skills/supply-chain-intake/SKILL.md +13 -13
  233. package/dist/agent-src/skills/systematic-debugging/SKILL.md +22 -21
  234. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +1 -1
  235. package/dist/agent-src/skills/technical-specification/SKILL.md +5 -0
  236. package/dist/agent-src/skills/terraform/SKILL.md +2 -2
  237. package/dist/agent-src/skills/terragrunt/SKILL.md +8 -8
  238. package/dist/agent-src/skills/testing-anti-patterns/process-anti-patterns.md +1 -1
  239. package/dist/agent-src/skills/threat-modeling/SKILL.md +19 -13
  240. package/dist/agent-src/skills/universal-project-analysis/SKILL.md +1 -1
  241. package/dist/agent-src/skills/upstream-contribute/SKILL.md +0 -1
  242. package/dist/agent-src/skills/using-git-worktrees/SKILL.md +9 -9
  243. package/dist/agent-src/skills/validate-feature-fit/SKILL.md +3 -1
  244. package/dist/agent-src/skills/verify-completion-evidence/SKILL.md +4 -6
  245. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +67 -61
  246. package/dist/agent-src/skills/video-director/SKILL.md +7 -7
  247. package/dist/agent-src/skills/worktree-lifecycle/SKILL.md +3 -3
  248. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  249. package/dist/agent-src/templates/contexts/knowledge-pages.md +47 -45
  250. package/dist/agent-src/templates/contexts/lesson-card.md +2 -2
  251. package/dist/agent-src/templates/contexts/tenant-boundaries.md +2 -2
  252. package/dist/agent-src/templates/contexts.md +1 -1
  253. package/dist/agent-src/templates/features.md +1 -1
  254. package/dist/agent-src/templates/roadmaps.md +125 -116
  255. package/dist/agent-src/templates/rule.md +2 -1
  256. package/dist/agent-src/templates/scripts/pr_risk_review.ts +0 -0
  257. package/dist/agent-src/templates/scripts/telemetry/aggregator.ts +0 -0
  258. package/dist/agent-src/templates/scripts/tier_usage_report.ts +2 -2
  259. package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +30 -30
  260. package/dist/agent-src/templates/scripts/work_engine/directives/ui/design.ts +88 -33
  261. package/dist/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +22 -2
  262. package/dist/agent-src/templates/scripts/work_engine/directives/ui/review.ts +21 -2
  263. package/dist/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +179 -0
  264. package/dist/agent-src/templates/scripts/work_engine/stack/detect.ts +155 -4
  265. package/dist/agent-src/templates/scripts/work_engine/state.ts +21 -4
  266. package/dist/agent-src/user-types/README.md +8 -8
  267. package/dist/agent-src/user-types/galabau-field-crew.md +34 -33
  268. package/dist/agent-src/user-types/metalworking-shop.md +35 -34
  269. package/dist/agent-src/user-types/truck-driver.md +22 -20
  270. package/dist/cli/initRouting.js +74 -11
  271. package/dist/cli/initRouting.js.map +1 -1
  272. package/dist/cli/main.js +14 -3
  273. package/dist/cli/main.js.map +1 -1
  274. package/dist/cli/python/workspace_roles.js +2 -2
  275. package/dist/cli/python/workspace_roles.js.map +1 -1
  276. package/dist/cli-delegate/chunk-4SV3XGFA.js +6910 -0
  277. package/dist/cli-delegate/chunk-736JCWLM.js +1104 -0
  278. package/dist/cli-delegate/chunk-7DSAMZFU.js +356 -0
  279. package/dist/cli-delegate/chunk-7HQ52DHU.js +74 -0
  280. package/dist/cli-delegate/chunk-BJGXZNPM.js +266 -0
  281. package/dist/cli-delegate/chunk-FTAISGDQ.js +117 -0
  282. package/dist/cli-delegate/chunk-GME3Q44L.js +82 -0
  283. package/dist/cli-delegate/chunk-GRRPEPRN.js +336 -0
  284. package/dist/cli-delegate/chunk-HJ6DAJHR.js +502 -0
  285. package/dist/cli-delegate/chunk-IR7P7JWA.js +872 -0
  286. package/dist/cli-delegate/chunk-J55WI3RR.js +47 -0
  287. package/dist/cli-delegate/chunk-MCJYCQPF.js +35 -0
  288. package/dist/cli-delegate/chunk-NDJLNC6Q.js +169 -0
  289. package/dist/cli-delegate/chunk-OMIVVCG2.js +26 -0
  290. package/dist/cli-delegate/chunk-OY53J6II.js +7336 -0
  291. package/dist/cli-delegate/chunk-RDGRHAAB.js +259 -0
  292. package/dist/cli-delegate/chunk-TFG57JJM.js +1969 -0
  293. package/dist/cli-delegate/chunk-XX6TOPD7.js +715 -0
  294. package/dist/cli-delegate/chunk-YMFO6FDN.js +10603 -0
  295. package/dist/cli-delegate/cmd_analyze_session.js +294 -0
  296. package/dist/cli-delegate/cmd_conformance.js +646 -0
  297. package/dist/cli-delegate/cmd_converge.js +326 -0
  298. package/dist/cli-delegate/cmd_doctor.js +144 -0
  299. package/dist/cli-delegate/cmd_explain.js +2508 -0
  300. package/dist/cli-delegate/cmd_export.js +296 -0
  301. package/dist/cli-delegate/cmd_fleet.js +332 -0
  302. package/dist/cli-delegate/cmd_memory_get.js +3878 -0
  303. package/dist/cli-delegate/cmd_migrate.js +11 -0
  304. package/dist/cli-delegate/cmd_preflight.js +270 -0
  305. package/dist/cli-delegate/cmd_prune.js +444 -0
  306. package/dist/cli-delegate/cmd_refresh.js +28 -0
  307. package/dist/cli-delegate/cmd_settings_check.js +574 -0
  308. package/dist/cli-delegate/cmd_settings_migrate.js +223 -0
  309. package/dist/cli-delegate/cmd_sync.js +264 -0
  310. package/dist/cli-delegate/cmd_uninstall.js +656 -0
  311. package/dist/cli-delegate/cmd_update.js +425 -0
  312. package/dist/cli-delegate/cmd_upgrade.js +444 -0
  313. package/dist/cli-delegate/cmd_validate.js +305 -0
  314. package/dist/cli-delegate/cmd_versions.js +370 -0
  315. package/dist/discovery/deprecation-report.md +1 -1
  316. package/dist/discovery/discovery-manifest.json +100 -67
  317. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  318. package/dist/discovery/discovery-manifest.summary.md +4 -4
  319. package/dist/discovery/orphan-report.md +1 -1
  320. package/dist/discovery/packs.json +16 -10
  321. package/dist/discovery/trust-report.md +2 -2
  322. package/dist/discovery/workspaces.json +7 -5
  323. package/dist/hooks/dispatch.js +186 -12
  324. package/dist/install/emit_host_rules_cli.js +2 -1
  325. package/dist/install/emit_host_rules_cli.js.map +1 -1
  326. package/dist/install/install.mjs +418 -378
  327. package/dist/install/rule_scope.js +5 -1
  328. package/dist/install/rule_scope.js.map +1 -1
  329. package/dist/install/toolDetection.js +40 -12
  330. package/dist/install/toolDetection.js.map +1 -1
  331. package/dist/install/wizard-plan.js +2 -2
  332. package/dist/install/wizard-plan.js.map +1 -1
  333. package/dist/mcp/registry-manifest.json +3 -3
  334. package/dist/mcp/server.json +2 -2
  335. package/dist/mcp/server.mjs +2194 -1003
  336. package/dist/router.json +1 -1
  337. package/dist/scripts/_lib/compile_time_toggles.js +48 -0
  338. package/dist/scripts/_lib/compile_time_toggles.js.map +1 -0
  339. package/dist/scripts/condense.js +234 -217
  340. package/dist/scripts/condense.js.map +1 -1
  341. package/dist/server/schemas/settings.js +4 -0
  342. package/dist/server/schemas/settings.js.map +1 -1
  343. package/dist/shared/userMd/utils.js +30 -0
  344. package/dist/shared/userMd/utils.js.map +1 -1
  345. package/dist/ui/assets/index-BpSQt5vm.js.map +1 -1
  346. package/docs/guidelines/agent-infra/api-cost-levers.md +56 -5
  347. package/docs/guidelines/agent-infra/simplicity-and-goal-demos.md +93 -33
  348. package/package.json +4 -2
  349. package/src/agent-src/templates/scripts/pr_risk_review.ts +0 -0
  350. package/src/agent-src/templates/scripts/telemetry/aggregator.ts +0 -0
  351. package/src/agent-src/templates/scripts/tier_usage_report.ts +2 -2
  352. package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +30 -30
  353. package/src/agent-src/templates/scripts/work_engine/directives/ui/design.ts +88 -33
  354. package/src/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +22 -2
  355. package/src/agent-src/templates/scripts/work_engine/directives/ui/review.ts +21 -2
  356. package/src/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +179 -0
  357. package/src/agent-src/templates/scripts/work_engine/stack/detect.ts +155 -4
  358. package/src/agent-src/templates/scripts/work_engine/state.ts +21 -4
  359. package/src/config/agent-settings.template.yml +32 -2
  360. package/src/config/ci-local-parity.yml +142 -0
  361. package/src/config/discovery/packs.yml +7 -0
  362. package/src/config/evaluator-budgets.json +1 -1
  363. package/src/config/gate-coverage.yml +127 -0
  364. package/src/config/pack-size-budget.json +27 -0
  365. package/src/config/preamble-payload-budget.json +44 -0
  366. package/src/install/emit_host_rules_cli.ts +2 -1
  367. package/src/install/rule_scope.ts +5 -1
  368. package/src/install/toolDetection.ts +39 -8
  369. package/src/install/wizard-plan.ts +2 -2
  370. package/src/scripts/_cli/cmd_conformance.ts +2 -1
  371. package/src/scripts/_cli/cmd_converge.ts +2 -1
  372. package/src/scripts/_cli/cmd_doctor.ts +292 -15
  373. package/src/scripts/_cli/cmd_export.ts +2 -1
  374. package/src/scripts/_cli/cmd_fleet.ts +2 -1
  375. package/src/scripts/_cli/cmd_migrate.ts +2 -1
  376. package/src/scripts/_cli/cmd_preflight.ts +2 -1
  377. package/src/scripts/_cli/cmd_refresh.ts +2 -1
  378. package/src/scripts/_cli/cmd_update.ts +2 -1
  379. package/src/scripts/_cli/cmd_upgrade.ts +2 -1
  380. package/src/scripts/_cli/cmd_versions.ts +2 -1
  381. package/src/scripts/_cli/detection_report.ts +480 -0
  382. package/src/scripts/_dispatch.bash +52 -14
  383. package/src/scripts/_lib/agent_user_profile.ts +381 -0
  384. package/src/scripts/_lib/agents_overlay.ts +9 -0
  385. package/src/scripts/_lib/anchor_eval.ts +311 -0
  386. package/src/scripts/_lib/cc_transcript.ts +316 -0
  387. package/src/scripts/_lib/changelog_eras.ts +103 -9
  388. package/src/scripts/_lib/compile_time_toggles.ts +79 -0
  389. package/src/scripts/_lib/confusables.ts +101 -0
  390. package/src/scripts/_lib/duplicate_scope_census.ts +77 -0
  391. package/src/scripts/_lib/environment_detector.ts +441 -0
  392. package/src/scripts/_lib/managed_agents_folder.ts +181 -0
  393. package/src/scripts/_lib/package_root.ts +72 -0
  394. package/src/scripts/_lib/payload_hash_drift.ts +126 -0
  395. package/src/scripts/_lib/preservation_migration.ts +291 -0
  396. package/src/scripts/_lib/retrieval_sanitize.ts +166 -2
  397. package/src/scripts/_lib/scan_scope.ts +115 -0
  398. package/src/scripts/_lib/user_global_memory_audit.ts +187 -0
  399. package/src/scripts/_lib/user_global_observations.ts +830 -0
  400. package/src/scripts/_lib/user_global_revocations.ts +110 -0
  401. package/src/scripts/_lib/user_memory_gate_counters.ts +291 -0
  402. package/src/scripts/ai_council/blind_review.ts +0 -0
  403. package/src/scripts/ai_council/budget_guard.ts +90 -11
  404. package/src/scripts/ai_council/bundler.ts +2 -2
  405. package/src/scripts/ai_council/clients.ts +59 -3
  406. package/src/scripts/ai_council/config.ts +53 -7
  407. package/src/scripts/ai_council/modes.ts +68 -2
  408. package/src/scripts/ai_council/orchestrator.ts +54 -9
  409. package/src/scripts/ai_council/transport_resolver.ts +331 -0
  410. package/src/scripts/ai_team/team_dispatch.ts +17 -6
  411. package/src/scripts/anchor_eval_falsify.ts +198 -0
  412. package/src/scripts/anchor_scoring_run.ts +239 -0
  413. package/src/scripts/annotate_discovery.ts +1 -65
  414. package/src/scripts/bench_quality_run.ts +168 -4
  415. package/src/scripts/cache_realization_report.ts +782 -0
  416. package/src/scripts/check_artefact_count_messaging.ts +5 -1
  417. package/src/scripts/check_augment_description_cap.ts +15 -4
  418. package/src/scripts/check_bundle_path_leakage.ts +10 -4
  419. package/src/scripts/check_ci_local_parity.ts +317 -0
  420. package/src/scripts/check_condensation.ts +96 -191
  421. package/src/scripts/check_context_paths.ts +38 -9
  422. package/src/scripts/check_dependency_floors.ts +153 -0
  423. package/src/scripts/check_gate_coverage.ts +299 -0
  424. package/src/scripts/check_iron_law_prominence.ts +22 -1
  425. package/src/scripts/check_kernel_prefix_stability.ts +0 -0
  426. package/src/scripts/check_no_new_legacy_path.ts +16 -6
  427. package/src/scripts/check_no_roadmap_refs.ts +22 -9
  428. package/src/scripts/check_originality_freshness.ts +167 -0
  429. package/src/scripts/check_pack_size.ts +188 -0
  430. package/src/scripts/check_preamble_payload_budget.ts +130 -0
  431. package/src/scripts/check_proposal.ts +0 -0
  432. package/src/scripts/check_references.ts +0 -1
  433. package/src/scripts/check_safety_floor_untouched.ts +171 -24
  434. package/src/scripts/check_site_links.ts +62 -3
  435. package/src/scripts/ci_status.ts +0 -0
  436. package/src/scripts/cluster_near_miss_patterns.ts +0 -0
  437. package/src/scripts/code_graph/build.ts +0 -0
  438. package/src/scripts/command_suggester/types.ts +0 -0
  439. package/src/scripts/compile_router.ts +10 -14
  440. package/src/scripts/condense.sh +3 -4
  441. package/src/scripts/condense.ts +247 -228
  442. package/src/scripts/cost/track.mjs +168 -33
  443. package/src/scripts/cost_summary.ts +33 -1
  444. package/src/scripts/council_cli.ts +51 -5
  445. package/src/scripts/discovery_graph.ts +0 -0
  446. package/src/scripts/encoding_corpus.ts +500 -0
  447. package/src/scripts/encoding_corpus_report.ts +216 -0
  448. package/src/scripts/evaluator_umbrella.sh +34 -1
  449. package/src/scripts/generate_index.ts +19 -2
  450. package/src/scripts/install-hooks.sh +2 -2
  451. package/src/scripts/learning_sidecar.ts +0 -0
  452. package/src/scripts/lint_confusables.ts +10 -72
  453. package/src/scripts/lint_eval_fixture_citations.ts +113 -0
  454. package/src/scripts/lint_featured_skills.ts +0 -0
  455. package/src/scripts/lint_hidden_unicode.ts +208 -0
  456. package/src/scripts/lint_load_context.ts +17 -5
  457. package/src/scripts/lint_new_skill_gate.ts +9 -3
  458. package/src/scripts/lint_no_python_twin_rationale.ts +17 -2
  459. package/src/scripts/lint_originality.ts +1 -1
  460. package/src/scripts/lint_skill_originality.ts +1 -1
  461. package/src/scripts/lint_ticket_buildable.ts +1 -1
  462. package/src/scripts/lint_ui_stack_bundles.ts +170 -0
  463. package/src/scripts/mcp_server/tools.ts +4 -4
  464. package/src/scripts/measure_scope_dedup.ts +224 -0
  465. package/src/scripts/memory_lookup.ts +0 -0
  466. package/src/scripts/mine_session.ts +98 -0
  467. package/src/scripts/orchestration_payload_hash_drift.ts +145 -0
  468. package/src/scripts/preamble_byte_census.ts +574 -0
  469. package/src/scripts/probe_skill_registration.ts +2 -2
  470. package/src/scripts/redact_hook_capture.ts +13 -0
  471. package/src/scripts/release.ts +65 -10
  472. package/src/scripts/router_telemetry.ts +1 -1
  473. package/src/scripts/second_brain_retrieval.ts +14 -4
  474. package/src/scripts/skill_linter.ts +5 -0
  475. package/src/scripts/surface-tiers.yml +2 -0
  476. package/src/scripts/validate_pack_yaml.ts +0 -0
  477. package/src/server/schemas/settings.ts +8 -0
  478. package/src/shared/userMd/utils.ts +31 -0
  479. package/dist/agent-src/rules/telegraph-speak.md +0 -87
@@ -0,0 +1,441 @@
1
+ /**
2
+ * Read-only environment detection — one report, no spend (Phase 1 of
3
+ * `road-to-zero-ceremony-detection`).
4
+ *
5
+ * Answers "what does this machine already have?" in a single pass so the
6
+ * `doctor` surface and the council's transport resolution read the SAME
7
+ * facts instead of each probing on its own. Three record kinds:
8
+ *
9
+ * - `hosts` — which AI hosts are installed, their resolved binary, version.
10
+ * - `auth` — which provider credentials are PRESENT, and of which source.
11
+ * - `keys` — the `api_key_ref`-shaped reference for each present key.
12
+ *
13
+ * ## Guarantees
14
+ *
15
+ * - **Zero network.** Nothing here opens a socket. Enforced by the static
16
+ * import check in the test suite, not by convention.
17
+ * - **Zero spend.** The only subprocess is `<binary> --version`, which no
18
+ * provider bills. No completion, no token, ever — the roadmap's
19
+ * install-time-completion item was cut for exactly this reason.
20
+ * - **Presence, never validity.** An `auth` record says "a credential of this
21
+ * shape exists at this path". It does NOT say the credential works, is
22
+ * unexpired, or is accepted by the provider. Runtime auth failure stays
23
+ * authoritative (`CliClient._AUTH_FAILURE_PATTERNS`).
24
+ * - **Read-only.** Reads the filesystem and the injected env map; writes
25
+ * nothing, creates no directory.
26
+ *
27
+ * ## No third probe shape — what each field absorbs
28
+ *
29
+ * Auth probing already existed in two shapes before this module and a third
30
+ * must not appear. This module composes; it re-implements nothing:
31
+ *
32
+ * | Field | Absorbed from |
33
+ * |---|---|
34
+ * | `hosts[].installed` | `install/toolDetection.ts::detectInstalledTools` (the 23-host signal table) |
35
+ * | `hosts[].binary` | `install/toolDetection.ts::resolveToolBinary` (same table, path-returning) |
36
+ * | `hosts[].version` | `install/agentSwitchDetection.ts::parseVersionOutput` (the first-dotted-number parser) |
37
+ * | `auth` (`openai`, `cli-*`) | `_cli/cmd_doctor.ts`'s read-only `$CODEX_HOME/auth.json` probe — `codexHome()` moved HERE and imported back, so there is one definition |
38
+ * | `auth` (`anthropic`, `cli-subscription`) | `_lib/claude_plugin.ts::claude_config_dir` (`CLAUDE_CONFIG_DIR` override incl.) |
39
+ * | `auth` (`key-file`) | `_lib/user_global_paths.ts::resolve_with_fallback` (new namespace, legacy read-fallback) |
40
+ *
41
+ * The council's TTL'd `AuthCache` (`ai_council/solo_dispatch.ts`) is the third
42
+ * existing shape and is deliberately NOT absorbed: it caches a *liveness*
43
+ * verdict from an injected probe that may spend a call. This module only
44
+ * reports presence, so it needs no TTL — a per-process memo is enough.
45
+ *
46
+ * ## Known limitation — CLI logins the filesystem does not reveal
47
+ *
48
+ * A vendor CLI that stores its subscription credential OUTSIDE the filesystem
49
+ * is undetectable here. Measured case: on macOS the `claude` CLI keeps its
50
+ * OAuth credential in the system Keychain, so `~/.claude/.credentials.json`
51
+ * is absent even for a logged-in Claude Pro user. The detector reports
52
+ * `cli-subscription` only where a credential FILE exists (Linux, and the
53
+ * `CLAUDE_CONFIG_DIR` profile layouts).
54
+ *
55
+ * Consequence, stated because it costs money: with no detectable CLI login,
56
+ * `mode: auto` skips the cli rung and resolves to `api` — metered — for a user
57
+ * who does hold a subscription. This is a FALSE NEGATIVE, which is the
58
+ * direction this module is built to fail in (a false positive would claim a
59
+ * subscription that is not there and switch the USD gate off). The remedy is an
60
+ * explicit `mode: cli` on the member; `doctor` shows the detected source so the
61
+ * gap is visible rather than silent. Reading the Keychain would require a
62
+ * `security(1)` subprocess against a credential store — a spend-free but
63
+ * privacy-relevant probe, and out of scope here.
64
+ *
65
+ * @see docs/contracts/ai-council-config.md § Transport modes — the billing rules
66
+ * `classifyBilling` implements.
67
+ */
68
+
69
+ import { spawnSync } from 'node:child_process';
70
+ import * as fs from 'node:fs';
71
+ import * as os from 'node:os';
72
+ import * as path from 'node:path';
73
+
74
+ import {
75
+ detectInstalledTools,
76
+ knownToolIds,
77
+ resolveToolBinary,
78
+ } from '../../install/toolDetection.js';
79
+ import { parseVersionOutput } from '../../install/agentSwitchDetection.js';
80
+ import { claude_config_dir } from './claude_plugin.js';
81
+ import { hardenedSpawnEnv } from './spawn_env.js';
82
+ import { resolve_with_fallback, type EnvMap } from './user_global_paths.js';
83
+
84
+ /** Where a present credential was found. Never a claim that it works. */
85
+ export type AuthSource = 'cli-subscription' | 'cli-api-key' | 'key-file' | 'env-key';
86
+
87
+ /**
88
+ * How a call against this provider is paid for.
89
+ *
90
+ * `subscription` — covered by a flat-rate plan the user already pays; the USD
91
+ * cost gate does not apply (`cli_call_budget` guards the quota instead).
92
+ * `per-token` — metered spend; the full `cost_budget` applies.
93
+ */
94
+ export type BillingClass = 'subscription' | 'per-token';
95
+
96
+ /** Version string when parseable, the literal `'unknown'` when not, `null` when unprobed. */
97
+ export type HostVersion = string | 'unknown' | null;
98
+
99
+ export interface DetectedHost {
100
+ readonly id: string;
101
+ readonly installed: boolean;
102
+ /** Resolved executable path, or `null` when the host has no binary on `$PATH`. */
103
+ readonly binary: string | null;
104
+ readonly version: HostVersion;
105
+ }
106
+
107
+ export interface DetectedAuth {
108
+ readonly provider: string;
109
+ readonly source: AuthSource;
110
+ /** A filesystem path, or `env:<VAR>` — presence evidence only. */
111
+ readonly evidence: string;
112
+ }
113
+
114
+ export interface DetectedKey {
115
+ readonly provider: string;
116
+ /** `api_key_ref`-shaped: `file:<name>.key` or `env:<VAR>`. */
117
+ readonly ref: string;
118
+ }
119
+
120
+ export interface EnvironmentReport {
121
+ readonly hosts: readonly DetectedHost[];
122
+ readonly auth: readonly DetectedAuth[];
123
+ readonly keys: readonly DetectedKey[];
124
+ }
125
+
126
+ /**
127
+ * Provider → (default CLI binary, community-wrapper flag).
128
+ *
129
+ * Mirrors the `CliClient` subclass attributes without importing the client
130
+ * layer. The boolean is the load-bearing billing input: a VENDOR-OFFICIAL CLI
131
+ * (`false`) runs under the user's subscription; a COMMUNITY wrapper (`true`)
132
+ * shells out to the same paid API and stays metered. Canonical here so
133
+ * `cmd_doctor` and this module cannot drift.
134
+ */
135
+ export const PROVIDER_CLI_META: Readonly<Record<string, readonly [string, boolean]>> = {
136
+ anthropic: ['claude', false],
137
+ openai: ['codex', false],
138
+ gemini: ['gemini', false],
139
+ xai: ['grok', true],
140
+ perplexity: ['perplexity', true],
141
+ };
142
+
143
+ /** Provider → environment variable carrying a raw API key. */
144
+ const PROVIDER_ENV_KEY: Readonly<Record<string, string>> = {
145
+ anthropic: 'ANTHROPIC_API_KEY',
146
+ openai: 'OPENAI_API_KEY',
147
+ gemini: 'GEMINI_API_KEY',
148
+ xai: 'XAI_API_KEY',
149
+ perplexity: 'PERPLEXITY_API_KEY',
150
+ };
151
+
152
+ /** Provider → key-file name under the user-global root (`file:` ref target). */
153
+ const PROVIDER_KEY_FILE: Readonly<Record<string, string>> = {
154
+ anthropic: 'anthropic.key',
155
+ openai: 'openai.key',
156
+ gemini: 'gemini.key',
157
+ xai: 'xai.key',
158
+ perplexity: 'perplexity.key',
159
+ };
160
+
161
+ /** Providers this module knows how to classify, in a stable order. */
162
+ export function knownProviders(): readonly string[] {
163
+ return Object.keys(PROVIDER_CLI_META);
164
+ }
165
+
166
+ /** True when `provider`'s CLI is a community wrapper around the paid API. */
167
+ export function isCommunityCli(provider: string): boolean {
168
+ return PROVIDER_CLI_META[provider]?.[1] ?? false;
169
+ }
170
+
171
+ /**
172
+ * Billing class from (provider, detected auth source) — NEVER from transport.
173
+ *
174
+ * This signature is the invariant: there is no transport / mode parameter, so
175
+ * no caller can make billing depend on which transport was chosen. That is
176
+ * what keeps the per-provider rules intact when `auto` picks a transport at
177
+ * invocation time: a vendor-official CLI logged in under a subscription is
178
+ * unmetered; everything else — including a community CLI and including an
179
+ * unknown source — is metered, i.e. deliberately over-gated.
180
+ *
181
+ * `null` source means "nothing detected" and classifies as `per-token`: the
182
+ * safe direction is to keep the USD gate on.
183
+ */
184
+ export function classifyBilling(provider: string, source: AuthSource | null): BillingClass {
185
+ if (source !== 'cli-subscription') return 'per-token';
186
+ if (isCommunityCli(provider)) return 'per-token';
187
+ return 'subscription';
188
+ }
189
+
190
+ /**
191
+ * Codex CLI home — `CODEX_HOME` env override (the codex CLI's own
192
+ * convention), else `~/.codex`. Single definition; `cmd_doctor` imports it.
193
+ */
194
+ export function codexHome(env?: EnvMap | null): string {
195
+ const map = env ?? process.env;
196
+ const override = (map['CODEX_HOME'] ?? '').trim();
197
+ return override !== '' ? override : path.join(homeOf(env), '.codex');
198
+ }
199
+
200
+ function homeOf(env?: EnvMap | null): string {
201
+ const map = env ?? process.env;
202
+ const injected = (map['HOME'] ?? '').trim();
203
+ return injected !== '' ? injected : os.homedir();
204
+ }
205
+
206
+ const VERSION_PROBE_TIMEOUT_MS = 2000;
207
+
208
+ /** Injected `<binary> --version` runner. Returns raw combined output, or `null`. */
209
+ export type VersionProbe = (binary: string) => string | null;
210
+
211
+ export interface DetectEnvironmentOptions {
212
+ /** Home directory override (tests / fixture machines). */
213
+ readonly home?: string;
214
+ /** `$PATH` override (tests / fixture machines). */
215
+ readonly pathEnv?: string;
216
+ /** Environment map override; also carries `CODEX_HOME` / `EVENT4U_CONFIG_HOME`. */
217
+ readonly env?: EnvMap;
218
+ /**
219
+ * Version probe override. Omit to spawn `<binary> --version` with a
220
+ * hardened env and a 2s timeout; pass `() => null` to skip probing.
221
+ */
222
+ readonly probeVersion?: VersionProbe;
223
+ }
224
+
225
+ /**
226
+ * `<binary> --version` under a hardened env. Never throws — a spawn error,
227
+ * timeout, signal, or unparseable output all collapse to `null`, which the
228
+ * caller degrades to `'unknown'`.
229
+ *
230
+ * Hardened per `docs/spawn-site-policy.md` (this runs on the consumer runtime
231
+ * via `doctor`). Note the env scrub deliberately does NOT strip
232
+ * `CLAUDE_CONFIG_DIR` — see `docs/threat-model.md` row i.
233
+ */
234
+ function defaultProbeVersion(binary: string): string | null {
235
+ try {
236
+ const res = spawnSync(binary, ['--version'], {
237
+ timeout: VERSION_PROBE_TIMEOUT_MS,
238
+ encoding: 'utf-8',
239
+ windowsHide: true,
240
+ env: hardenedSpawnEnv(),
241
+ });
242
+ if (res.error !== undefined || res.signal !== null) return null;
243
+ return `${res.stdout ?? ''}\n${res.stderr ?? ''}`;
244
+ } catch {
245
+ return null;
246
+ }
247
+ }
248
+
249
+ function isFile(p: string): boolean {
250
+ try {
251
+ return fs.statSync(p).isFile();
252
+ } catch {
253
+ return false;
254
+ }
255
+ }
256
+
257
+ function exists(p: string): boolean {
258
+ try {
259
+ return fs.existsSync(p);
260
+ } catch {
261
+ return false;
262
+ }
263
+ }
264
+
265
+ /**
266
+ * Classify a codex `auth.json` by which credential shape it carries.
267
+ *
268
+ * OAuth tokens ⇒ the user logged in with a ChatGPT plan (`cli-subscription`);
269
+ * anything else ⇒ metered (`cli-api-key`). A present-but-unreadable or
270
+ * malformed file also reports `cli-api-key` — the over-gated direction, since
271
+ * assuming a plan would switch the USD gate off on no evidence.
272
+ */
273
+ function classifyCodexAuth(authPath: string): AuthSource {
274
+ let data: unknown;
275
+ try {
276
+ data = JSON.parse(fs.readFileSync(authPath, 'utf-8'));
277
+ } catch {
278
+ // Present but unreadable: over-gate (metered) rather than assume a plan.
279
+ return 'cli-api-key';
280
+ }
281
+ if (typeof data !== 'object' || data === null || Array.isArray(data)) {
282
+ return 'cli-api-key';
283
+ }
284
+ const d = data as Record<string, unknown>;
285
+ const tokens = d['tokens'];
286
+ const hasOauth =
287
+ typeof tokens === 'object' &&
288
+ tokens !== null &&
289
+ !Array.isArray(tokens) &&
290
+ Object.keys(tokens as Record<string, unknown>).length > 0;
291
+ if (hasOauth) return 'cli-subscription';
292
+ return 'cli-api-key';
293
+ }
294
+
295
+ /** Provider-specific `cli-subscription` evidence path, or `null` when none applies. */
296
+ function cliSubscriptionEvidence(
297
+ provider: string,
298
+ home: string,
299
+ env: EnvMap,
300
+ claudeConfigDir: string,
301
+ ): { source: AuthSource; evidence: string } | null {
302
+ if (provider === 'anthropic') {
303
+ const configDir = claudeConfigDir;
304
+ for (const rel of ['.credentials.json', 'credentials.json']) {
305
+ const p = path.join(configDir, rel);
306
+ if (isFile(p)) return { source: 'cli-subscription', evidence: p };
307
+ }
308
+ return null;
309
+ }
310
+ if (provider === 'openai') {
311
+ const p = path.join(codexHome(env), 'auth.json');
312
+ if (isFile(p)) return { source: classifyCodexAuth(p), evidence: p };
313
+ return null;
314
+ }
315
+ if (provider === 'gemini') {
316
+ const p = path.join(home, '.gemini', 'oauth_creds.json');
317
+ if (isFile(p)) return { source: 'cli-subscription', evidence: p };
318
+ return null;
319
+ }
320
+ // xai / perplexity ship no subscription login — their CLIs read an API key.
321
+ return null;
322
+ }
323
+
324
+ function detectHosts(opts: DetectEnvironmentOptions): DetectedHost[] {
325
+ const installedMap = detectInstalledTools({
326
+ ...(opts.home !== undefined ? { home: opts.home } : {}),
327
+ pathEnv: opts.pathEnv,
328
+ });
329
+ const probe = opts.probeVersion ?? defaultProbeVersion;
330
+ const out: DetectedHost[] = [];
331
+ for (const id of knownToolIds()) {
332
+ const binary = resolveToolBinary(id, opts.pathEnv);
333
+ let version: HostVersion = null;
334
+ if (binary !== null) {
335
+ let raw: string | null;
336
+ try {
337
+ raw = probe(binary);
338
+ } catch {
339
+ raw = null;
340
+ }
341
+ // An unparseable version degrades to 'unknown' — never throws,
342
+ // never omits the host from the report.
343
+ version = raw === null ? 'unknown' : (parseVersionOutput(raw) ?? 'unknown');
344
+ }
345
+ out.push({ id, installed: installedMap[id] ?? false, binary, version });
346
+ }
347
+ return out;
348
+ }
349
+
350
+ function detectAuth(opts: DetectEnvironmentOptions): {
351
+ auth: DetectedAuth[];
352
+ keys: DetectedKey[];
353
+ } {
354
+ const env = opts.env ?? process.env;
355
+ const home = opts.home ?? homeOf(opts.env);
356
+ // Delegate to claude_plugin's resolver on the live path (it owns the
357
+ // CLAUDE_CONFIG_DIR override); derive from the injected home otherwise.
358
+ const claudeConfigDir =
359
+ opts.home === undefined && opts.env === undefined
360
+ ? claude_config_dir()
361
+ : ((env['CLAUDE_CONFIG_DIR'] ?? '').trim() || path.join(home, '.claude'));
362
+ const auth: DetectedAuth[] = [];
363
+ const keys: DetectedKey[] = [];
364
+
365
+ for (const provider of knownProviders()) {
366
+ const cli = cliSubscriptionEvidence(provider, home, env, claudeConfigDir);
367
+ if (cli !== null) {
368
+ auth.push({ provider, source: cli.source, evidence: cli.evidence });
369
+ }
370
+
371
+ const keyFile = PROVIDER_KEY_FILE[provider];
372
+ if (keyFile !== undefined) {
373
+ let resolved: string | null = null;
374
+ try {
375
+ resolved = resolve_with_fallback(keyFile, { env });
376
+ } catch {
377
+ resolved = null;
378
+ }
379
+ if (resolved !== null && exists(resolved)) {
380
+ auth.push({ provider, source: 'key-file', evidence: resolved });
381
+ keys.push({ provider, ref: `file:${keyFile}` });
382
+ }
383
+ }
384
+
385
+ const envVar = PROVIDER_ENV_KEY[provider];
386
+ if (envVar !== undefined && (env[envVar] ?? '').trim() !== '') {
387
+ auth.push({ provider, source: 'env-key', evidence: `env:${envVar}` });
388
+ keys.push({ provider, ref: `env:${envVar}` });
389
+ }
390
+ }
391
+ return { auth, keys };
392
+ }
393
+
394
+ /**
395
+ * Strongest auth source detected for `provider`, or `null`.
396
+ *
397
+ * "Strongest" is the transport-preference order `auto` walks: a vendor CLI
398
+ * login beats a stored key. Pure over an already-built report.
399
+ */
400
+ export function strongestAuth(
401
+ report: EnvironmentReport,
402
+ provider: string,
403
+ ): DetectedAuth | null {
404
+ const order: readonly AuthSource[] = [
405
+ 'cli-subscription',
406
+ 'cli-api-key',
407
+ 'key-file',
408
+ 'env-key',
409
+ ];
410
+ for (const source of order) {
411
+ const hit = report.auth.find((a) => a.provider === provider && a.source === source);
412
+ if (hit !== undefined) return hit;
413
+ }
414
+ return null;
415
+ }
416
+
417
+ let _cached: EnvironmentReport | null = null;
418
+
419
+ /**
420
+ * Build the environment report.
421
+ *
422
+ * Cached per process for the no-argument call (the production shape) so
423
+ * `doctor` and transport resolution observe one consistent snapshot; any call
424
+ * that injects options bypasses the cache and returns a fresh read, so tests
425
+ * and fixture machines never poison each other. Reset with
426
+ * `resetEnvironmentCache()`.
427
+ */
428
+ export function detectEnvironment(opts: DetectEnvironmentOptions = {}): EnvironmentReport {
429
+ const isDefaultCall = Object.keys(opts).length === 0;
430
+ if (isDefaultCall && _cached !== null) return _cached;
431
+ const hosts = detectHosts(opts);
432
+ const { auth, keys } = detectAuth(opts);
433
+ const report: EnvironmentReport = { hosts, auth, keys };
434
+ if (isDefaultCall) _cached = report;
435
+ return report;
436
+ }
437
+
438
+ /** Drop the per-process memo. Tests only. */
439
+ export function resetEnvironmentCache(): void {
440
+ _cached = null;
441
+ }
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Detect whether a directory is a project whose `agents/` folder is managed
3
+ * by this package.
4
+ *
5
+ * `.agent-settings.yml` resolution and settings-cascade routing already have
6
+ * a project-root walker (`find_project_root_with_anchor` in
7
+ * `_lib/agent_settings.ts`), but that walker answers a different question —
8
+ * "where does the settings cascade start reading from" — and its `agents/`
9
+ * check exists only to pick a boundary anchor for that walk (its marker list
10
+ * mixes package-source-repo-only paths, e.g. `settings/.ai-council.yml`, with
11
+ * consumer-only paths). It also treats a bare `.git` anywhere in the ancestor
12
+ * chain as "a project was found", which is the right answer for "where do
13
+ * settings live" but the wrong answer for "is this THIS package's managed
14
+ * `agents/` folder" — a third-party repo with an unrelated `agents/`
15
+ * directory and its own `.git` would resolve to a root there too. No
16
+ * existing helper answers the narrower managed/unmanaged/not-a-project
17
+ * question this module exists for.
18
+ *
19
+ * Contract — pure, read-only, tolerant:
20
+ *
21
+ * - Never writes, never mutates, never touches the network.
22
+ * - Operates on the given `start` directory directly — it does not walk
23
+ * ancestors looking for a project root (that is the caller's job, e.g.
24
+ * via `find_project_root` when the caller only has a subdirectory).
25
+ * Keeping this helper non-walking keeps it a distinct primitive from the
26
+ * settings-root walker above rather than a second, subtly different copy
27
+ * of the same walk.
28
+ * - Silently tolerant of a missing/unreadable `start` — every check falls
29
+ * through to `false`, which resolves to `'not-a-project'`.
30
+ */
31
+ import * as fs from 'node:fs';
32
+ import * as path from 'node:path';
33
+
34
+ import { SECTION_HEADER as _MANAGED_GITIGNORE_HEADER } from '../sync_gitignore.js';
35
+
36
+ /**
37
+ * Three-state answer — never a boolean, because "no `agents/` folder" and
38
+ * "no project at all" route differently downstream (an unmanaged repo is a
39
+ * candidate for adoption; a bare directory outside any repo is not a
40
+ * project the P-routing question even applies to).
41
+ */
42
+ export type ManagedAgentsFolderStatus = 'managed' | 'unmanaged' | 'not-a-project';
43
+
44
+ /**
45
+ * Detection predicate — chosen after inspecting what the installer actually
46
+ * writes into a consumer project (verified against source, not invented):
47
+ *
48
+ * is_project := <start>/.git exists (file or directory — worktrees and
49
+ * submodules use a `.git` file, not a directory).
50
+ * has_agents := <start>/agents is a directory.
51
+ * has_marker := ANY of —
52
+ * (a) <start>/.gitignore contains the managed-block header line
53
+ * `# event4u/agent-config` (`SECTION_HEADER` in
54
+ * `sync_gitignore.ts`) — installed by `refresh --project` /
55
+ * `sync:gitignore`. Strongest signal: the literal package name, so
56
+ * a third-party repo carries it only if it also runs this package.
57
+ * (b) <start>/agents/overrides/ is a directory — scaffolded by
58
+ * `install.ts` for every consumer project (the "guaranteed
59
+ * minimal-consumer surface", ADR-020).
60
+ * (c) a resolvable `.agent-settings.yml` exists — canonical
61
+ * `<start>/agents/settings/.agent-settings.yml`, or the legacy
62
+ * `<start>/.agent-settings.yml` fallback (see
63
+ * `project_settings_path` in `_lib/agent_settings.ts`).
64
+ *
65
+ * status := has_agents && has_marker → 'managed'
66
+ * is_project (else) → 'unmanaged'
67
+ * otherwise → 'not-a-project'
68
+ *
69
+ * Rejected alternatives:
70
+ *
71
+ * - `agents/` existence alone (no marker). Rejected: this is exactly the
72
+ * false positive the roadmap phase calls out — an unrelated multi-agent
73
+ * framework repo, or any project that happens to name a directory
74
+ * `agents/`, would read as managed with zero package-specific evidence.
75
+ * - Reusing `find_project_root_with_anchor`'s `_AGENTS_DIR_MARKERS` list
76
+ * verbatim (`roadmaps`, `settings/.ai-council.yml`,
77
+ * `roadmaps-progress.md`, `overrides`). Rejected: two of those four
78
+ * (`settings/.ai-council.yml`, `roadmaps-progress.md`) are `pkg`-scope
79
+ * only per `docs/contracts/agents-layout.md`'s consumer-slim-profile
80
+ * table — they never appear in an installed consumer project, so
81
+ * requiring "any one" would under-detect nothing (they're just dead
82
+ * weight for the consumer case) but reusing the *function* would also
83
+ * inherit its `.git`-anchor and `.agent-settings.yml`-layer-fallback
84
+ * semantics, which answer "where is the settings root" rather than
85
+ * "is `agents/` managed" (see module docblock).
86
+ * - `agents/roadmaps/` as a marker. Rejected: it is listed as "Optional"
87
+ * even in the consumer-slim profile — a managed project with zero
88
+ * roadmaps yet (the common case right after install) would false-
89
+ * negative.
90
+ */
91
+ function _existsAt(dir: string, ...segments: readonly string[]): boolean {
92
+ try {
93
+ fs.statSync(path.join(dir, ...segments));
94
+ return true;
95
+ } catch {
96
+ return false;
97
+ }
98
+ }
99
+
100
+ function _isDirAt(dir: string, ...segments: readonly string[]): boolean {
101
+ try {
102
+ return fs.statSync(path.join(dir, ...segments)).isDirectory();
103
+ } catch {
104
+ return false;
105
+ }
106
+ }
107
+
108
+ function _isFileAt(dir: string, ...segments: readonly string[]): boolean {
109
+ try {
110
+ return fs.statSync(path.join(dir, ...segments)).isFile();
111
+ } catch {
112
+ return false;
113
+ }
114
+ }
115
+
116
+ /** `true` when `start` sits at the root of a git repository (or worktree). */
117
+ function _isGitProject(start: string): boolean {
118
+ // `.git` is a directory in a normal clone, a file in a worktree or
119
+ // submodule checkout — `statSync` (not `lstatSync`) is deliberate so a
120
+ // broken symlink named `.git` does not count as present.
121
+ return _existsAt(start, '.git');
122
+ }
123
+
124
+ /** `true` when `<start>/.gitignore` carries the managed-block header line. */
125
+ function _hasManagedGitignoreBlock(start: string): boolean {
126
+ if (!_isFileAt(start, '.gitignore')) {
127
+ return false;
128
+ }
129
+ let text: string;
130
+ try {
131
+ text = fs.readFileSync(path.join(start, '.gitignore'), 'utf-8');
132
+ } catch {
133
+ return false;
134
+ }
135
+ return text
136
+ .split(/\r\n|\r|\n/)
137
+ .some((line) => line.trim() === _MANAGED_GITIGNORE_HEADER);
138
+ }
139
+
140
+ /** `true` when `<start>/agents/overrides` exists as a directory. */
141
+ function _hasOverridesDir(start: string): boolean {
142
+ return _isDirAt(start, 'agents', 'overrides');
143
+ }
144
+
145
+ /**
146
+ * `true` when a resolvable `.agent-settings.yml` exists — canonical
147
+ * `agents/settings/.agent-settings.yml`, or the legacy repo-root
148
+ * `.agent-settings.yml`.
149
+ */
150
+ function _hasResolvableAgentSettings(start: string): boolean {
151
+ return (
152
+ _isFileAt(start, 'agents', 'settings', '.agent-settings.yml') ||
153
+ _isFileAt(start, '.agent-settings.yml')
154
+ );
155
+ }
156
+
157
+ /**
158
+ * Classify `start` as `'managed'` (an `agents/` folder this package
159
+ * installed and can safely write project facts into), `'unmanaged'` (a real
160
+ * project — has a `.git` — with no such folder, or an `agents/` folder this
161
+ * package did not install), or `'not-a-project'` (no `.git` at `start` at
162
+ * all — e.g. a bare directory outside any repo).
163
+ *
164
+ * Read-only. Does not walk ancestors — `start` is checked directly; pass a
165
+ * project root (e.g. from `find_project_root`) when the caller only has a
166
+ * subdirectory.
167
+ */
168
+ export function detect_managed_agents_folder(start: string): ManagedAgentsFolderStatus {
169
+ if (!_isGitProject(start)) {
170
+ return 'not-a-project';
171
+ }
172
+ const hasAgentsDir = _isDirAt(start, 'agents');
173
+ const hasMarker =
174
+ _hasManagedGitignoreBlock(start) ||
175
+ _hasOverridesDir(start) ||
176
+ _hasResolvableAgentSettings(start);
177
+ if (hasAgentsDir && hasMarker) {
178
+ return 'managed';
179
+ }
180
+ return 'unmanaged';
181
+ }
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Layout-independent package-root resolution for the `_cli` delegate commands.
3
+ *
4
+ * `src/scripts/_cli/*.ts` sits three levels below the package root, so every
5
+ * delegate command derived the root with three hard-coded parent hops. Then the
6
+ * delegate precompile (`fa51c5a54`) started bundling those same modules into
7
+ * `dist/cli-delegate/*.js` — **two** levels below the root. Fixed hop counts are
8
+ * correct in exactly one of the two layouts, and nothing failed loudly: three
9
+ * hops from the bundle lands on `<pkg>/..`, which for a scoped install is
10
+ * `node_modules/@event4u`. `conformance` then reported `dist/router.json` and
11
+ * `src/scripts/hook_manifest.yaml` as missing — files that ship fine — and the
12
+ * 9.11.0 release PR's `tarball E2E` went red on both Node majors.
13
+ *
14
+ * The fix is to stop counting hops. Anchor on the marker that actually defines
15
+ * the root: the `package.json` whose `name` is this package. That answer holds
16
+ * for the source tree, for any bundle depth, for npm-global, npx, and
17
+ * vendor/bin symlink invocations — and it keeps holding if either directory
18
+ * ever moves.
19
+ */
20
+
21
+ import * as fs from 'node:fs';
22
+ import * as path from 'node:path';
23
+ import { fileURLToPath } from 'node:url';
24
+
25
+ /** `name` in this package's own package.json — the root marker. */
26
+ export const PACKAGE_NAME = '@event4u/agent-config';
27
+
28
+ /**
29
+ * Bound on the upward walk. Deep enough for any real install path, finite so a
30
+ * malformed start value can never spin.
31
+ */
32
+ const MAX_ASCENT = 16;
33
+
34
+ /**
35
+ * Absolute package root for the module at `fromUrlOrPath` (pass
36
+ * `import.meta.url`).
37
+ *
38
+ * Walks up looking for the package.json whose `name` is {@link PACKAGE_NAME}.
39
+ * A consumer's own package.json encountered on the way is skipped by that name
40
+ * check, so an install nested under another project resolves correctly.
41
+ *
42
+ * `legacyHops` is the pre-existing hop count for the *source* layout and is
43
+ * used only if no marker is found. Falling back beats throwing during CLI
44
+ * startup: a wrong path yields one actionable "missing file" message, while an
45
+ * exception takes down every command in the delegate.
46
+ */
47
+ export function resolvePackageRoot(fromUrlOrPath: string, legacyHops = 3): string {
48
+ const start = fromUrlOrPath.startsWith('file:') ? fileURLToPath(fromUrlOrPath) : fromUrlOrPath;
49
+ const startDir = path.dirname(start);
50
+
51
+ let dir = startDir;
52
+ for (let i = 0; i < MAX_ASCENT; i++) {
53
+ const manifest = path.join(dir, 'package.json');
54
+ if (fs.existsSync(manifest)) {
55
+ try {
56
+ const parsed = JSON.parse(fs.readFileSync(manifest, 'utf8')) as { name?: unknown };
57
+ if (parsed.name === PACKAGE_NAME) {
58
+ return dir;
59
+ }
60
+ } catch {
61
+ // Unreadable / unparseable manifest — not our marker; keep ascending.
62
+ }
63
+ }
64
+ const parent = path.dirname(dir);
65
+ if (parent === dir) {
66
+ break; // filesystem root
67
+ }
68
+ dir = parent;
69
+ }
70
+
71
+ return path.resolve(startDir, ...(Array.from({ length: legacyHops }, () => '..') as string[]));
72
+ }