@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,2508 @@
1
+ #!/usr/bin/env tsx
2
+ import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url);
3
+ import {
4
+ StateLoadError,
5
+ load_state
6
+ } from "./chunk-GME3Q44L.js";
7
+ import {
8
+ artefact_roots
9
+ } from "./chunk-BJGXZNPM.js";
10
+ import {
11
+ DEFAULT_PROJECT_FILE,
12
+ ProjectRootError,
13
+ load_agent_settings,
14
+ logger,
15
+ resolve_project_root
16
+ } from "./chunk-HJ6DAJHR.js";
17
+ import "./chunk-NDJLNC6Q.js";
18
+ import {
19
+ __export
20
+ } from "./chunk-J55WI3RR.js";
21
+
22
+ // src/scripts/_cli/cmd_explain.ts
23
+ import * as fs8 from "node:fs";
24
+ import * as path7 from "node:path";
25
+ import process2 from "node:process";
26
+ import { fileURLToPath, pathToFileURL } from "node:url";
27
+
28
+ // src/scripts/config/presets.ts
29
+ import * as fs from "node:fs";
30
+ import { createRequire } from "node:module";
31
+ import * as path from "node:path";
32
+ var _require = createRequire(import.meta.url);
33
+ var PRESET_ID_ENV = "AGENT_CONFIG_PRESET_ID";
34
+ var DEFAULT_PRESET_ID = "balanced";
35
+ var PRESETS_DIRNAME = ".agent-src.uncondensed/presets";
36
+ var SOURCE_PACK = "pack";
37
+ var SOURCE_PROFILE = "profile";
38
+ var SOURCE_USER = "user-settings";
39
+ var SOURCE_ENV = "env";
40
+ var SOURCE_RUNTIME = "runtime";
41
+ var SOURCE_DEFAULT = "default";
42
+ var ENV_KNOB_MAP = {
43
+ AGENT_CONFIG_PRESET_COST_DAILY_MAX_USD: ["cost", "daily_max_usd"],
44
+ AGENT_CONFIG_PRESET_COST_WEEKLY_MAX_USD: ["cost", "weekly_max_usd"],
45
+ AGENT_CONFIG_PRESET_COST_MONTHLY_MAX_USD: ["cost", "monthly_max_usd"],
46
+ AGENT_CONFIG_PRESET_MCP_PER_CALL_MAX_USD: ["mcp", "per_call_max_usd"],
47
+ AGENT_CONFIG_PRESET_MCP_PER_SESSION_MAX_USD: ["mcp", "per_session_max_usd"],
48
+ AGENT_CONFIG_PRESET_COUNCIL_CAP_PER_CONSULT_USD: ["council", "cap_per_consult_usd"],
49
+ AGENT_CONFIG_PRESET_AUTONOMY_DEFAULT: ["autonomy", "default"],
50
+ AGENT_CONFIG_PRESET_CONFIDENCE_MIN_BAND: ["confidence", "min_band"]
51
+ };
52
+ var ResolvedPreset = class {
53
+ id;
54
+ knobs;
55
+ source;
56
+ overrides;
57
+ warning;
58
+ constructor(params) {
59
+ this.id = params.id;
60
+ this.knobs = params.knobs ?? {};
61
+ this.source = params.source ?? SOURCE_DEFAULT;
62
+ this.overrides = params.overrides ?? [];
63
+ this.warning = params.warning ?? null;
64
+ }
65
+ };
66
+ var PresetError = class extends Error {
67
+ constructor(message) {
68
+ super(message);
69
+ this.name = "PresetError";
70
+ }
71
+ };
72
+ function _load_yaml(p) {
73
+ let YAML;
74
+ try {
75
+ YAML = _require("yaml");
76
+ } catch {
77
+ logger.info("PyYAML unavailable; preset %s returned empty", p);
78
+ return {};
79
+ }
80
+ let text;
81
+ try {
82
+ text = fs.readFileSync(p, "utf-8");
83
+ } catch (exc) {
84
+ logger.warning("preset read failed for %s: %s", p, String(exc));
85
+ return {};
86
+ }
87
+ let data;
88
+ try {
89
+ data = YAML.parse(text, { version: "1.1" });
90
+ if (data === null || data === void 0) {
91
+ data = {};
92
+ }
93
+ } catch (exc) {
94
+ logger.warning("preset parse failed for %s: %s", p, String(exc));
95
+ return {};
96
+ }
97
+ return _isPlainDict(data) ? data : {};
98
+ }
99
+ function _preset_file(project_root, preset_id) {
100
+ const legacy = path.join(project_root, PRESETS_DIRNAME, `${preset_id}.yml`);
101
+ if (_exists(legacy)) {
102
+ return legacy;
103
+ }
104
+ let roots;
105
+ try {
106
+ roots = artefact_roots();
107
+ } catch {
108
+ return legacy;
109
+ }
110
+ for (const root of roots) {
111
+ const candidate = path.join(root, "presets", `${preset_id}.yml`);
112
+ if (_exists(candidate)) {
113
+ return candidate;
114
+ }
115
+ }
116
+ return legacy;
117
+ }
118
+ function _coerce_scalar(raw) {
119
+ const asInt = _pyInt(raw);
120
+ if (asInt !== null) {
121
+ return asInt;
122
+ }
123
+ const asFloat = _pyFloat(raw);
124
+ if (asFloat !== null) {
125
+ return asFloat;
126
+ }
127
+ const lowered = raw.toLowerCase();
128
+ if (lowered === "true" || lowered === "false") {
129
+ return lowered === "true";
130
+ }
131
+ return raw;
132
+ }
133
+ function _deep_merge(base, override) {
134
+ const paths = [];
135
+ function walk(b, o, prefix) {
136
+ for (const key of Object.keys(o)) {
137
+ const value = o[key];
138
+ const dotted = `${prefix}${key}`;
139
+ if (_isPlainDict(value) && _isPlainDict(b[key])) {
140
+ walk(b[key], value, `${dotted}.`);
141
+ } else {
142
+ b[key] = _deepCopy(value);
143
+ paths.push(dotted);
144
+ }
145
+ }
146
+ }
147
+ walk(base, override, "");
148
+ return paths;
149
+ }
150
+ function _pick_id(pack_preset_id, profile_preset_id, user_settings, runtime_id) {
151
+ if (runtime_id) {
152
+ return [runtime_id, SOURCE_RUNTIME];
153
+ }
154
+ const env_id = process.env[PRESET_ID_ENV];
155
+ if (env_id) {
156
+ return [env_id, SOURCE_ENV];
157
+ }
158
+ const block = _isPlainDict(user_settings) ? user_settings["preset"] : void 0;
159
+ if (_isPlainDict(block) && block["id"]) {
160
+ return [String(block["id"]), SOURCE_USER];
161
+ }
162
+ if (pack_preset_id) {
163
+ return [pack_preset_id, SOURCE_PACK];
164
+ }
165
+ if (profile_preset_id) {
166
+ return [profile_preset_id, SOURCE_PROFILE];
167
+ }
168
+ return [null, SOURCE_DEFAULT];
169
+ }
170
+ function resolve_preset(params) {
171
+ const settings = params.user_settings ?? {};
172
+ let [preset_id, source] = _pick_id(
173
+ params.pack_preset_id ?? null,
174
+ params.profile_preset_id ?? null,
175
+ settings,
176
+ params.runtime_id ?? null
177
+ );
178
+ if (preset_id === null) {
179
+ preset_id = DEFAULT_PRESET_ID;
180
+ source = SOURCE_DEFAULT;
181
+ }
182
+ const yaml_path = _preset_file(params.project_root, preset_id);
183
+ if (!_exists(yaml_path)) {
184
+ throw new PresetError(
185
+ `preset.id=${_repr(preset_id)} (${source}) but ${yaml_path} not found`
186
+ );
187
+ }
188
+ const raw = _load_yaml(yaml_path);
189
+ let knobs = raw["preset"] ?? {};
190
+ if (!_isPlainDict(knobs)) {
191
+ throw new PresetError(`${yaml_path} has no top-level 'preset:' mapping`);
192
+ }
193
+ knobs = _deepCopy(knobs);
194
+ delete knobs["id"];
195
+ const overrides = [];
196
+ const settingsPreset = settings["preset"];
197
+ const user_block = _isPlainDict(settingsPreset) ? settingsPreset : null;
198
+ if (_isPlainDict(user_block)) {
199
+ const user_overrides = {};
200
+ for (const k of Object.keys(user_block)) {
201
+ if (k !== "id") {
202
+ user_overrides[k] = user_block[k];
203
+ }
204
+ }
205
+ if (Object.keys(user_overrides).length > 0) {
206
+ overrides.push(..._deep_merge(knobs, user_overrides));
207
+ }
208
+ }
209
+ for (const env_key of Object.keys(ENV_KNOB_MAP)) {
210
+ const keyPath = ENV_KNOB_MAP[env_key];
211
+ const raw_value = process.env[env_key];
212
+ if (raw_value === void 0) {
213
+ continue;
214
+ }
215
+ let cursor = knobs;
216
+ for (const part of keyPath.slice(0, -1)) {
217
+ if (!_isPlainDict(cursor[part])) {
218
+ cursor[part] = {};
219
+ }
220
+ cursor = cursor[part];
221
+ }
222
+ cursor[keyPath[keyPath.length - 1]] = _coerce_scalar(raw_value);
223
+ overrides.push(keyPath.join("."));
224
+ }
225
+ if (params.runtime_overrides) {
226
+ for (const [keyPath, value] of params.runtime_overrides) {
227
+ let cursor = knobs;
228
+ for (const part of keyPath.slice(0, -1)) {
229
+ if (!_isPlainDict(cursor[part])) {
230
+ cursor[part] = {};
231
+ }
232
+ cursor = cursor[part];
233
+ }
234
+ cursor[keyPath[keyPath.length - 1]] = value;
235
+ overrides.push(keyPath.join("."));
236
+ }
237
+ }
238
+ return new ResolvedPreset({
239
+ id: preset_id,
240
+ knobs,
241
+ source,
242
+ overrides
243
+ });
244
+ }
245
+ function _exists(p) {
246
+ try {
247
+ fs.statSync(p);
248
+ return true;
249
+ } catch {
250
+ return false;
251
+ }
252
+ }
253
+ function _isPlainDict(value) {
254
+ return typeof value === "object" && value !== null && !Array.isArray(value) && !(value instanceof Map);
255
+ }
256
+ function _deepCopy(value) {
257
+ if (Array.isArray(value)) {
258
+ return value.map((v) => _deepCopy(v));
259
+ }
260
+ if (_isPlainDict(value)) {
261
+ const out = {};
262
+ for (const k of Object.keys(value)) {
263
+ out[k] = _deepCopy(value[k]);
264
+ }
265
+ return out;
266
+ }
267
+ return value;
268
+ }
269
+ function _pyInt(raw) {
270
+ const s = raw.trim();
271
+ if (!/^[+-]?\d+(?:_\d+)*$/.test(s)) {
272
+ return null;
273
+ }
274
+ const n = Number(s.replace(/_/g, ""));
275
+ return Number.isFinite(n) ? n : null;
276
+ }
277
+ function _pyFloat(raw) {
278
+ const s = raw.trim();
279
+ if (s === "") {
280
+ return null;
281
+ }
282
+ const lowered = s.toLowerCase().replace("+", "").replace("-", "");
283
+ if (lowered === "inf" || lowered === "infinity") {
284
+ return s.trim().startsWith("-") ? -Infinity : Infinity;
285
+ }
286
+ if (lowered === "nan") {
287
+ return NaN;
288
+ }
289
+ if (!/^[+-]?(?:\d+(?:_\d+)*\.?\d*(?:_\d+)*|\.\d+(?:_\d+)*)(?:[eE][+-]?\d+)?$/.test(s)) {
290
+ return null;
291
+ }
292
+ const n = Number(s.replace(/_/g, ""));
293
+ return Number.isFinite(n) ? n : null;
294
+ }
295
+ function _repr(s) {
296
+ return `'${s.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
297
+ }
298
+
299
+ // src/scripts/config/profiles.ts
300
+ import * as fs2 from "node:fs";
301
+ import { createRequire as createRequire2 } from "node:module";
302
+ import * as path2 from "node:path";
303
+ var _require2 = createRequire2(import.meta.url);
304
+ var PROFILE_ID_ENV = "AGENT_CONFIG_PROFILE_ID";
305
+ var DEFAULT_PROFILE_ID = "developer";
306
+ var PROFILES_DIRNAME = ".agent-src.uncondensed/profiles";
307
+ var SOURCE_PACK2 = "pack";
308
+ var SOURCE_USER2 = "user-settings";
309
+ var SOURCE_ENV2 = "env";
310
+ var SOURCE_RUNTIME2 = "runtime";
311
+ var SOURCE_DEFAULT2 = "default";
312
+ var SOURCE_MISSING = "missing";
313
+ var ResolvedProfile = class {
314
+ id;
315
+ audience;
316
+ preset_id;
317
+ packs;
318
+ personas;
319
+ skills_hint;
320
+ commands_hint;
321
+ docs_first_pointer;
322
+ source;
323
+ warning;
324
+ constructor(params) {
325
+ this.id = params.id;
326
+ this.audience = params.audience ?? {};
327
+ this.preset_id = params.preset_id ?? null;
328
+ this.packs = params.packs ?? [];
329
+ this.personas = params.personas ?? [];
330
+ this.skills_hint = params.skills_hint ?? [];
331
+ this.commands_hint = params.commands_hint ?? [];
332
+ this.docs_first_pointer = params.docs_first_pointer ?? null;
333
+ this.source = params.source ?? SOURCE_DEFAULT2;
334
+ this.warning = params.warning ?? null;
335
+ }
336
+ };
337
+ var ProfileError = class extends Error {
338
+ constructor(message) {
339
+ super(message);
340
+ this.name = "ProfileError";
341
+ }
342
+ };
343
+ function _load_yaml2(p) {
344
+ let YAML;
345
+ try {
346
+ YAML = _require2("yaml");
347
+ } catch {
348
+ logger.info("PyYAML unavailable; profile %s returned empty", p);
349
+ return {};
350
+ }
351
+ let text;
352
+ try {
353
+ text = fs2.readFileSync(p, "utf-8");
354
+ } catch (exc) {
355
+ logger.warning("profile read failed for %s: %s", p, String(exc));
356
+ return {};
357
+ }
358
+ let data;
359
+ try {
360
+ data = YAML.parse(text, { version: "1.1" });
361
+ if (data === null || data === void 0) {
362
+ data = {};
363
+ }
364
+ } catch (exc) {
365
+ logger.warning("profile parse failed for %s: %s", p, String(exc));
366
+ return {};
367
+ }
368
+ return _isPlainDict2(data) ? data : {};
369
+ }
370
+ function _profile_file(project_root, profile_id) {
371
+ const legacy = path2.join(project_root, PROFILES_DIRNAME, `${profile_id}.yml`);
372
+ if (_exists2(legacy)) {
373
+ return legacy;
374
+ }
375
+ let roots;
376
+ try {
377
+ roots = artefact_roots();
378
+ } catch {
379
+ return legacy;
380
+ }
381
+ for (const root of roots) {
382
+ const candidate = path2.join(root, "profiles", `${profile_id}.yml`);
383
+ if (_exists2(candidate)) {
384
+ return candidate;
385
+ }
386
+ }
387
+ return legacy;
388
+ }
389
+ function _build_resolved(profile_id, raw, options) {
390
+ const block = _isPlainDict2(raw["profile"]) ? raw["profile"] : {};
391
+ const audience_raw = _isPlainDict2(block["audience"]) ? block["audience"] : {};
392
+ const defaults = _isPlainDict2(block["defaults"]) ? block["defaults"] : {};
393
+ const surface = _isPlainDict2(block["surface"]) ? block["surface"] : {};
394
+ const audience = {};
395
+ for (const k of Object.keys(audience_raw)) {
396
+ audience[String(k)] = String(audience_raw[k]);
397
+ }
398
+ const packs = _strTuple(block["packs"]);
399
+ const personas = _strTuple(defaults["personas"]);
400
+ const skills_hint = _strTuple(defaults["skills_hint"]);
401
+ const commands_hint = _strTuple(surface["commands_hint"]);
402
+ const docs_pointer = surface["docs_first_pointer"];
403
+ return new ResolvedProfile({
404
+ id: profile_id,
405
+ audience,
406
+ preset_id: defaults["preset_id"] ?? null,
407
+ packs,
408
+ personas,
409
+ skills_hint,
410
+ commands_hint,
411
+ docs_first_pointer: docs_pointer ? String(docs_pointer) : null,
412
+ source: options.source,
413
+ warning: options.warning ?? null
414
+ });
415
+ }
416
+ function _pick_id2(pack_profile_id, user_settings, runtime_id) {
417
+ if (runtime_id) {
418
+ return [runtime_id, SOURCE_RUNTIME2];
419
+ }
420
+ const env_id = process.env[PROFILE_ID_ENV];
421
+ if (env_id) {
422
+ return [env_id, SOURCE_ENV2];
423
+ }
424
+ const block = _isPlainDict2(user_settings) ? user_settings["profile"] : void 0;
425
+ if (_isPlainDict2(block) && block["id"]) {
426
+ return [String(block["id"]), SOURCE_USER2];
427
+ }
428
+ if (pack_profile_id) {
429
+ return [pack_profile_id, SOURCE_PACK2];
430
+ }
431
+ return [null, SOURCE_MISSING];
432
+ }
433
+ function resolve_profile(params) {
434
+ const settings = params.user_settings ?? {};
435
+ const settings_file = path2.join(params.project_root, DEFAULT_PROJECT_FILE);
436
+ const [profile_id, source] = _pick_id2(
437
+ params.pack_profile_id ?? null,
438
+ settings,
439
+ params.runtime_id ?? null
440
+ );
441
+ if (profile_id === null) {
442
+ if (_exists2(settings_file)) {
443
+ return new ResolvedProfile({
444
+ id: DEFAULT_PROFILE_ID,
445
+ source: SOURCE_MISSING,
446
+ warning: "no profile.id in .agent-settings.yml \u2014 run /onboard to pick an audience deliberately"
447
+ });
448
+ }
449
+ return _build_resolved(
450
+ DEFAULT_PROFILE_ID,
451
+ _load_yaml2(_profile_file(params.project_root, DEFAULT_PROFILE_ID)),
452
+ { source: SOURCE_DEFAULT2 }
453
+ );
454
+ }
455
+ const yaml_path = _profile_file(params.project_root, profile_id);
456
+ if (!_exists2(yaml_path)) {
457
+ throw new ProfileError(
458
+ `profile.id=${_repr2(profile_id)} (${source}) but ${yaml_path} not found`
459
+ );
460
+ }
461
+ return _build_resolved(profile_id, _load_yaml2(yaml_path), { source });
462
+ }
463
+ function _exists2(p) {
464
+ try {
465
+ fs2.statSync(p);
466
+ return true;
467
+ } catch {
468
+ return false;
469
+ }
470
+ }
471
+ function _isPlainDict2(value) {
472
+ return typeof value === "object" && value !== null && !Array.isArray(value) && !(value instanceof Map);
473
+ }
474
+ function _strTuple(value) {
475
+ if (!Array.isArray(value)) {
476
+ return [];
477
+ }
478
+ return value.map((v) => String(v));
479
+ }
480
+ function _repr2(s) {
481
+ return `'${s.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
482
+ }
483
+
484
+ // src/scripts/_cli/explain_last/index.ts
485
+ import * as fs7 from "node:fs";
486
+
487
+ // src/scripts/_cli/explain_last/scrubber.ts
488
+ var LONG_STRING_THRESHOLD = 200;
489
+ var _RAW_KEY_PREFIXES = [
490
+ "sk_live_",
491
+ "sk_test_",
492
+ "ghp_",
493
+ "github_pat_",
494
+ "gho_",
495
+ "ghs_",
496
+ "ghu_",
497
+ "xoxb-",
498
+ "xoxp-",
499
+ "AIza",
500
+ "AKIA"
501
+ ];
502
+ function _reEscape(literal) {
503
+ return literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").replace(/-/g, "\\u002d");
504
+ }
505
+ var _W = "\\p{L}\\p{N}_";
506
+ var _RAW_KEY_RE = new RegExp(
507
+ "(?:" + _RAW_KEY_PREFIXES.map(_reEscape).join("|") + ")[A-Za-z0-9_-]{6,}",
508
+ "gu"
509
+ );
510
+ var _API_KEY_RE = new RegExp(
511
+ "\\bapi[_-]?key\\b\\s*[:=]\\s*[A-Za-z0-9+/=_-]{12,}",
512
+ "giu"
513
+ );
514
+ var _EMAIL_RE = new RegExp(
515
+ `(?<![${_W}.+-])[${_W}.+-]+@[${_W}-]+\\.[${_W}.-]+(?![${_W}.-])`,
516
+ "gu"
517
+ );
518
+ var _PATH_RE = new RegExp(
519
+ `(?:/Users/|/home/|/opt/|/private/|[A-Z]:\\\\)[${_W}./\\\\-]+`,
520
+ "gu"
521
+ );
522
+ var _URL_RE = new RegExp(
523
+ "(?<![\\p{L}\\p{N}_])(?<scheme>https?|ftp|ws|wss)://(?<host>[^\\s/:?#]+)(?:[^\\s]*)?",
524
+ "gu"
525
+ );
526
+ var _INTERNAL_HOST_RE = new RegExp(
527
+ `(?<![${_W}])[a-zA-Z0-9][${_W}.-]*\\.(?:internal|local)(?![${_W}])`,
528
+ "giu"
529
+ );
530
+ var _MONEY_RE = new RegExp(
531
+ "(?:[$\u20AC\xA3\xA5]\\s?\\d{1,3}(?:[,.]\\d{3})*(?:\\.\\d+)?|\\b(?:USD|EUR|GBP|JPY)\\s?\\d+(?:[,.]\\d+)?)",
532
+ "gu"
533
+ );
534
+ function pyLen(s) {
535
+ let n = 0;
536
+ for (const _ch of s) {
537
+ n += 1;
538
+ }
539
+ return n;
540
+ }
541
+ function _stripUrl(_match, scheme, host) {
542
+ return `${scheme}://${host}/\u2026`;
543
+ }
544
+ function scrub_string(value) {
545
+ if (typeof value !== "string" || value === "") {
546
+ return value;
547
+ }
548
+ let out = value.replace(_RAW_KEY_RE, "<secret>");
549
+ out = out.replace(_API_KEY_RE, "api_key=<secret>");
550
+ out = out.replace(_EMAIL_RE, "<email>");
551
+ out = out.replace(_URL_RE, _stripUrl);
552
+ out = out.replace(_PATH_RE, "<path>");
553
+ out = out.replace(_INTERNAL_HOST_RE, "<host>");
554
+ out = out.replace(_MONEY_RE, "<money>");
555
+ if (pyLen(out) > LONG_STRING_THRESHOLD) {
556
+ return `<${pyLen(out)} chars>`;
557
+ }
558
+ return out;
559
+ }
560
+
561
+ // src/scripts/_cli/explain_last/assumptions.ts
562
+ function _pySlice(s, n) {
563
+ return Array.from(s).slice(0, n).join("");
564
+ }
565
+ function _pyTruthy(value) {
566
+ if (value === null || value === void 0) {
567
+ return false;
568
+ }
569
+ if (typeof value === "string") {
570
+ return value.length > 0;
571
+ }
572
+ if (typeof value === "number") {
573
+ return value !== 0 && !Number.isNaN(value);
574
+ }
575
+ if (typeof value === "boolean") {
576
+ return value;
577
+ }
578
+ if (Array.isArray(value)) {
579
+ return value.length > 0;
580
+ }
581
+ if (typeof value === "object") {
582
+ return Object.keys(value).length > 0;
583
+ }
584
+ return true;
585
+ }
586
+ function _normalise(raw, fallback_idx) {
587
+ if (typeof raw === "string") {
588
+ const text = raw.trim();
589
+ if (!text) {
590
+ return null;
591
+ }
592
+ const scrubbed = scrub_string(text);
593
+ const sliced = typeof scrubbed === "string" ? _pySlice(scrubbed, 120) : scrubbed;
594
+ return {
595
+ id: _pyTruthy(sliced) ? sliced : `assumption-${fallback_idx}`,
596
+ accepted: true,
597
+ source: "refine"
598
+ };
599
+ }
600
+ if (typeof raw === "object" && raw !== null && !Array.isArray(raw)) {
601
+ const r = raw;
602
+ let ident = _pyTruthy(r.id) ? r.id : _pyTruthy(r.text) ? r.text : `assumption-${fallback_idx}`;
603
+ if (typeof ident !== "string") {
604
+ ident = String(ident);
605
+ }
606
+ const scrubbed = scrub_string(ident.trim());
607
+ ident = _pyTruthy(scrubbed) ? scrubbed : `assumption-${fallback_idx}`;
608
+ const acceptedRaw = "accepted" in r ? r.accepted : true;
609
+ const accepted = _pyBool(acceptedRaw);
610
+ const source = _pyTruthy(r.source) ? r.source : _pyTruthy(r.step) ? r.step : "refine";
611
+ return {
612
+ id: ident,
613
+ accepted,
614
+ source: scrub_string(String(source))
615
+ };
616
+ }
617
+ return null;
618
+ }
619
+ function _pyBool(value) {
620
+ return _pyTruthy(value);
621
+ }
622
+ function build(state) {
623
+ const input = _pyTruthy(state.input) ? state.input : {};
624
+ const dataRaw = input.data;
625
+ const data = _pyTruthy(dataRaw) ? dataRaw : {};
626
+ const rawListRaw = data.assumptions;
627
+ if (!Array.isArray(rawListRaw)) {
628
+ return [];
629
+ }
630
+ const out = [];
631
+ rawListRaw.forEach((raw, idx) => {
632
+ const entry = _normalise(raw, idx);
633
+ if (entry !== null) {
634
+ out.push(entry);
635
+ }
636
+ });
637
+ return out;
638
+ }
639
+
640
+ // src/scripts/_cli/explain_last/council.ts
641
+ import * as fs3 from "node:fs";
642
+ import * as path3 from "node:path";
643
+ var RUN_WINDOW_SECONDS = 3600;
644
+ function _pySlice200(s) {
645
+ const cps = Array.from(s);
646
+ return cps.slice(0, 200).join("");
647
+ }
648
+ function _firstLine(s) {
649
+ const m = s.split(/\r\n|[\n\r\v\f\x1c\x1d\x1e\x85]/);
650
+ return m.length > 0 ? m[0] : void 0;
651
+ }
652
+ function _candidate_files(project_root) {
653
+ const sessions_root = path3.join(
654
+ project_root,
655
+ "agents",
656
+ "runtime",
657
+ "council",
658
+ "sessions"
659
+ );
660
+ const tmp_root = path3.join(project_root, "tmp");
661
+ const candidates = [];
662
+ if (_isDir(sessions_root)) {
663
+ for (const sub of _iterdir(sessions_root)) {
664
+ if (_isDir(sub)) {
665
+ const candidate = path3.join(sub, "council-responses.json");
666
+ if (fs3.existsSync(candidate)) {
667
+ candidates.push(candidate);
668
+ }
669
+ }
670
+ }
671
+ }
672
+ if (fs3.existsSync(tmp_root)) {
673
+ candidates.push(..._glob(tmp_root, "council-", ".json").sort());
674
+ }
675
+ return candidates;
676
+ }
677
+ function _pick_recent(candidates, anchor_mtime) {
678
+ let best = null;
679
+ for (const p of candidates) {
680
+ let mtime;
681
+ try {
682
+ mtime = fs3.statSync(p).mtimeMs / 1e3;
683
+ } catch {
684
+ continue;
685
+ }
686
+ if (Math.abs(mtime - anchor_mtime) > RUN_WINDOW_SECONDS) {
687
+ continue;
688
+ }
689
+ if (best === null || mtime > best[0]) {
690
+ best = [mtime, p];
691
+ }
692
+ }
693
+ return best ? best[1] : null;
694
+ }
695
+ function _extract_member(entry) {
696
+ const provider = _pyTruthy2(entry.provider) ? String(entry.provider) : "";
697
+ const model = _pyTruthy2(entry.model) ? String(entry.model) : "";
698
+ const parts = [provider, model].filter((p) => p !== "");
699
+ const member_id = parts.length > 0 ? parts.join("/") : "unknown";
700
+ const text = entry.text;
701
+ if (typeof text !== "string" || text.trim() === "") {
702
+ return null;
703
+ }
704
+ const firstLine = _firstLine(text.trim()) ?? "";
705
+ const verdict = scrub_string(_pySlice200(firstLine));
706
+ const citations = [];
707
+ for (const cite of entry.citations ?? []) {
708
+ if (typeof cite === "string") {
709
+ citations.push(scrub_string(cite));
710
+ }
711
+ }
712
+ return {
713
+ member_id: scrub_string(member_id),
714
+ verdict,
715
+ citations
716
+ };
717
+ }
718
+ function build2(project_root, state_file) {
719
+ let anchor;
720
+ try {
721
+ anchor = fs3.statSync(state_file).mtimeMs / 1e3;
722
+ } catch {
723
+ return null;
724
+ }
725
+ const candidates = _candidate_files(project_root);
726
+ if (candidates.length === 0) {
727
+ return null;
728
+ }
729
+ const picked = _pick_recent(candidates, anchor);
730
+ if (picked === null) {
731
+ return null;
732
+ }
733
+ let raw;
734
+ try {
735
+ raw = JSON.parse(fs3.readFileSync(picked, "utf-8"));
736
+ } catch {
737
+ return null;
738
+ }
739
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
740
+ return null;
741
+ }
742
+ const members = [];
743
+ for (const entry of raw.responses ?? []) {
744
+ if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
745
+ continue;
746
+ }
747
+ const member = _extract_member(entry);
748
+ if (member !== null) {
749
+ members.push(member);
750
+ }
751
+ }
752
+ return members.length > 0 ? members : null;
753
+ }
754
+ function _isDir(p) {
755
+ try {
756
+ return fs3.statSync(p).isDirectory();
757
+ } catch {
758
+ return false;
759
+ }
760
+ }
761
+ function _iterdir(p) {
762
+ let names;
763
+ try {
764
+ names = fs3.readdirSync(p);
765
+ } catch {
766
+ return [];
767
+ }
768
+ return names.map((n) => path3.join(p, n));
769
+ }
770
+ function _glob(dir, prefix, suffix) {
771
+ let names;
772
+ try {
773
+ names = fs3.readdirSync(dir);
774
+ } catch {
775
+ return [];
776
+ }
777
+ return names.filter((n) => n.startsWith(prefix) && n.endsWith(suffix)).map((n) => path3.join(dir, n));
778
+ }
779
+ function _pyTruthy2(value) {
780
+ if (value === null || value === void 0) {
781
+ return false;
782
+ }
783
+ if (typeof value === "string") {
784
+ return value.length > 0;
785
+ }
786
+ if (typeof value === "number") {
787
+ return value !== 0 && !Number.isNaN(value);
788
+ }
789
+ if (typeof value === "boolean") {
790
+ return value;
791
+ }
792
+ if (Array.isArray(value)) {
793
+ return value.length > 0;
794
+ }
795
+ if (typeof value === "object") {
796
+ return Object.keys(value).length > 0;
797
+ }
798
+ return true;
799
+ }
800
+
801
+ // src/scripts/_cli/explain_last/halt.ts
802
+ function _pyTruthy3(value) {
803
+ if (value === null || value === void 0) {
804
+ return false;
805
+ }
806
+ if (typeof value === "string") {
807
+ return value.length > 0;
808
+ }
809
+ if (typeof value === "number") {
810
+ return value !== 0 && !Number.isNaN(value);
811
+ }
812
+ if (typeof value === "boolean") {
813
+ return value;
814
+ }
815
+ if (Array.isArray(value)) {
816
+ return value.length > 0;
817
+ }
818
+ if (typeof value === "object") {
819
+ return Object.keys(value).length > 0;
820
+ }
821
+ return true;
822
+ }
823
+ function build3(state) {
824
+ const haltsRaw = _pyTruthy3(state.halts) ? state.halts : [];
825
+ if (!Array.isArray(haltsRaw) || haltsRaw.length === 0) {
826
+ return null;
827
+ }
828
+ const last = haltsRaw[haltsRaw.length - 1];
829
+ if (typeof last !== "object" || last === null || Array.isArray(last)) {
830
+ return null;
831
+ }
832
+ const lastDict = last;
833
+ const reason = lastDict.reason;
834
+ if (typeof reason !== "string" || !reason) {
835
+ return null;
836
+ }
837
+ const step = lastDict.step;
838
+ const surfaceRaw = _pyTruthy3(lastDict.surface) ? lastDict.surface : [];
839
+ const scrubbed_surface = [];
840
+ if (Array.isArray(surfaceRaw)) {
841
+ for (const line of surfaceRaw) {
842
+ if (typeof line === "string") {
843
+ scrubbed_surface.push(scrub_string(line));
844
+ }
845
+ }
846
+ }
847
+ return {
848
+ reason: scrub_string(reason),
849
+ step: typeof step === "string" && step ? scrub_string(step) : "",
850
+ surface: scrubbed_surface
851
+ };
852
+ }
853
+
854
+ // src/scripts/_cli/explain_last/inputs.ts
855
+ import { createRequire as createRequire3 } from "node:module";
856
+ import * as fs4 from "node:fs";
857
+ import * as path4 from "node:path";
858
+ var _require3 = createRequire3(import.meta.url);
859
+ var _DEFAULT_RULE_LOADING_TIER = "balanced";
860
+ var _SILENCED_LOGGERS = [
861
+ "scripts.config.profiles",
862
+ "scripts.config.presets"
863
+ ];
864
+ function _silence_resolver_warnings(body) {
865
+ void _SILENCED_LOGGERS;
866
+ void logger;
867
+ return body();
868
+ }
869
+ function _load_settings(project_root) {
870
+ const p = path4.join(project_root, DEFAULT_PROJECT_FILE);
871
+ if (!fs4.existsSync(p)) {
872
+ return {};
873
+ }
874
+ return load_agent_settings({ project_path: p }) ?? {};
875
+ }
876
+ function _pyTruthy4(value) {
877
+ if (value === null || value === void 0) {
878
+ return false;
879
+ }
880
+ if (typeof value === "string") {
881
+ return value.length > 0;
882
+ }
883
+ if (typeof value === "number") {
884
+ return value !== 0;
885
+ }
886
+ if (typeof value === "boolean") {
887
+ return value;
888
+ }
889
+ if (Array.isArray(value)) {
890
+ return value.length > 0;
891
+ }
892
+ if (typeof value === "object") {
893
+ return Object.keys(value).length > 0;
894
+ }
895
+ return true;
896
+ }
897
+ function build4(project_root) {
898
+ let resolved_profile;
899
+ let resolved_preset;
900
+ let settings;
901
+ try {
902
+ const result = _silence_resolver_warnings(() => {
903
+ const s = _load_settings(project_root);
904
+ const rp = resolve_profile({
905
+ project_root,
906
+ user_settings: s
907
+ });
908
+ const rpre = resolve_preset({
909
+ project_root,
910
+ user_settings: s,
911
+ profile_preset_id: rp.preset_id
912
+ });
913
+ return { settings: s, resolved_profile: rp, resolved_preset: rpre };
914
+ });
915
+ settings = result.settings;
916
+ resolved_profile = result.resolved_profile;
917
+ resolved_preset = result.resolved_preset;
918
+ } catch (exc) {
919
+ if (exc instanceof ProfileError || exc instanceof PresetError || _isOsError(exc)) {
920
+ return null;
921
+ }
922
+ throw exc;
923
+ }
924
+ const isDict = typeof settings === "object" && settings !== null;
925
+ let rule_loading_tier;
926
+ if (isDict) {
927
+ const primary = settings.rule_loading_tier ?? null;
928
+ rule_loading_tier = _pyTruthy4(primary) ? primary : settings.cost_profile ?? null;
929
+ } else {
930
+ rule_loading_tier = null;
931
+ }
932
+ let rule_loading_tier_source = _pyTruthy4(rule_loading_tier) ? "user" : "default";
933
+ if (!_pyTruthy4(rule_loading_tier) || rule_loading_tier === "__RULE_LOADING_TIER__") {
934
+ rule_loading_tier = _DEFAULT_RULE_LOADING_TIER;
935
+ rule_loading_tier_source = "default";
936
+ }
937
+ return {
938
+ profile: scrub_string(resolved_profile.id),
939
+ preset: scrub_string(resolved_preset.id),
940
+ rule_loading_tier: scrub_string(String(rule_loading_tier)),
941
+ source_per_knob: {
942
+ profile: resolved_profile.source,
943
+ preset: resolved_preset.source,
944
+ rule_loading_tier: rule_loading_tier_source
945
+ }
946
+ };
947
+ }
948
+ function _pack_marker(project_root) {
949
+ for (const candidate of [
950
+ path4.join(project_root, ".agent-pack.yml"),
951
+ path4.join(project_root, ".agent-src.uncondensed", ".agent-pack.yml")
952
+ ]) {
953
+ if (fs4.existsSync(candidate)) {
954
+ return candidate;
955
+ }
956
+ }
957
+ return null;
958
+ }
959
+ function build_pack(project_root) {
960
+ const marker = _pack_marker(project_root);
961
+ if (marker === null) {
962
+ return null;
963
+ }
964
+ let YAML;
965
+ try {
966
+ YAML = _require3("yaml");
967
+ } catch {
968
+ return null;
969
+ }
970
+ let raw;
971
+ try {
972
+ const text = fs4.readFileSync(marker, "utf-8");
973
+ raw = YAML.parse(text, { version: "1.1" });
974
+ if (raw === null || raw === void 0) {
975
+ raw = {};
976
+ }
977
+ } catch {
978
+ return null;
979
+ }
980
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
981
+ return null;
982
+ }
983
+ const rawDict = raw;
984
+ const pack_id = _pyTruthy4(rawDict.id) ? rawDict.id : rawDict.pack ?? null;
985
+ if (typeof pack_id !== "string" || pack_id.trim() === "") {
986
+ return null;
987
+ }
988
+ const reasonRaw = _pyTruthy4(rawDict.reason) ? rawDict.reason : `declared in ${path4.basename(marker)}`;
989
+ return {
990
+ id: scrub_string(pack_id.trim()),
991
+ reason: scrub_string(String(reasonRaw))
992
+ };
993
+ }
994
+ function _isOsError(exc) {
995
+ return exc instanceof Error && typeof exc.code === "string";
996
+ }
997
+
998
+ // src/scripts/_cli/explain_last/memory.ts
999
+ import * as fs5 from "node:fs";
1000
+ import * as path5 from "node:path";
1001
+ var PyFloat = class {
1002
+ constructor(value) {
1003
+ this.value = value;
1004
+ }
1005
+ value;
1006
+ };
1007
+ var MEMORY_SIDECAR = path5.join(".agent-memory", "hits.jsonl");
1008
+ function _pyTruthy5(value) {
1009
+ if (value === null || value === void 0) {
1010
+ return false;
1011
+ }
1012
+ if (typeof value === "string") {
1013
+ return value.length > 0;
1014
+ }
1015
+ if (typeof value === "number") {
1016
+ return value !== 0 && !Number.isNaN(value);
1017
+ }
1018
+ if (typeof value === "boolean") {
1019
+ return value;
1020
+ }
1021
+ if (Array.isArray(value)) {
1022
+ return value.length > 0;
1023
+ }
1024
+ if (typeof value === "object") {
1025
+ return Object.keys(value).length > 0;
1026
+ }
1027
+ return true;
1028
+ }
1029
+ function _coerceFloat(value) {
1030
+ if (typeof value === "number") {
1031
+ return value;
1032
+ }
1033
+ if (typeof value === "boolean") {
1034
+ return value ? 1 : 0;
1035
+ }
1036
+ if (typeof value === "string") {
1037
+ const trimmed = value.trim();
1038
+ if (trimmed === "") {
1039
+ return null;
1040
+ }
1041
+ const lowered = trimmed.toLowerCase();
1042
+ if (["inf", "infinity", "+inf", "+infinity"].includes(lowered)) {
1043
+ return Infinity;
1044
+ }
1045
+ if (["-inf", "-infinity"].includes(lowered)) {
1046
+ return -Infinity;
1047
+ }
1048
+ if (["nan", "+nan", "-nan"].includes(lowered)) {
1049
+ return NaN;
1050
+ }
1051
+ if (!/^[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/.test(trimmed)) {
1052
+ return null;
1053
+ }
1054
+ const n = Number(trimmed);
1055
+ return Number.isNaN(n) ? null : n;
1056
+ }
1057
+ return null;
1058
+ }
1059
+ function _coerce_entry(raw) {
1060
+ const entry_id = _pyTruthy5(raw.entry_id) ? raw.entry_id : raw.id ?? null;
1061
+ if (typeof entry_id !== "string" || entry_id.trim() === "") {
1062
+ return null;
1063
+ }
1064
+ let hitRaw = raw.hit_score ?? null;
1065
+ if (hitRaw === null || hitRaw === void 0) {
1066
+ hitRaw = "score" in raw ? raw.score : 0;
1067
+ }
1068
+ const coerced = _coerceFloat(hitRaw);
1069
+ const hit_score = new PyFloat(coerced === null ? 0 : coerced);
1070
+ const used_in = _pyTruthy5(raw.used_in) ? raw.used_in : _pyTruthy5(raw.step) ? raw.step : "unspecified";
1071
+ return {
1072
+ entry_id: scrub_string(entry_id.trim()),
1073
+ hit_score,
1074
+ used_in: scrub_string(String(used_in))
1075
+ };
1076
+ }
1077
+ function _from_state(state) {
1078
+ const entries = [];
1079
+ for (const raw of state.memory ?? []) {
1080
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
1081
+ continue;
1082
+ }
1083
+ const entry = _coerce_entry(raw);
1084
+ if (entry !== null) {
1085
+ entries.push(entry);
1086
+ }
1087
+ }
1088
+ return entries;
1089
+ }
1090
+ function _splitlines(s) {
1091
+ if (s === "") {
1092
+ return [];
1093
+ }
1094
+ const breaks = /* @__PURE__ */ new Set([
1095
+ "\n",
1096
+ "\r",
1097
+ "\v",
1098
+ "\f",
1099
+ "",
1100
+ "",
1101
+ "",
1102
+ "\x85",
1103
+ "\u2028",
1104
+ "\u2029"
1105
+ ]);
1106
+ const out = [];
1107
+ let cur = "";
1108
+ for (let i = 0; i < s.length; i += 1) {
1109
+ const ch = s[i];
1110
+ if (ch === "\r" && s[i + 1] === "\n") {
1111
+ out.push(cur);
1112
+ cur = "";
1113
+ i += 1;
1114
+ continue;
1115
+ }
1116
+ if (breaks.has(ch)) {
1117
+ out.push(cur);
1118
+ cur = "";
1119
+ continue;
1120
+ }
1121
+ cur += ch;
1122
+ }
1123
+ if (cur !== "") {
1124
+ out.push(cur);
1125
+ }
1126
+ return out;
1127
+ }
1128
+ function _from_sidecar(project_root, run_id) {
1129
+ const p = path5.join(project_root, MEMORY_SIDECAR);
1130
+ if (!fs5.existsSync(p)) {
1131
+ return [];
1132
+ }
1133
+ const entries = [];
1134
+ let content;
1135
+ try {
1136
+ content = fs5.readFileSync(p, "utf-8");
1137
+ } catch {
1138
+ return [];
1139
+ }
1140
+ for (let line of _splitlines(content)) {
1141
+ line = line.trim();
1142
+ if (!line) {
1143
+ continue;
1144
+ }
1145
+ let raw;
1146
+ try {
1147
+ raw = JSON.parse(line);
1148
+ } catch {
1149
+ continue;
1150
+ }
1151
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
1152
+ continue;
1153
+ }
1154
+ const rawDict = raw;
1155
+ if (run_id) {
1156
+ const got = rawDict.run_id ?? null;
1157
+ if (got !== null && got !== run_id) {
1158
+ continue;
1159
+ }
1160
+ }
1161
+ const entry = _coerce_entry(rawDict);
1162
+ if (entry !== null) {
1163
+ entries.push(entry);
1164
+ }
1165
+ }
1166
+ return entries;
1167
+ }
1168
+ function build5(project_root, state) {
1169
+ const input = _pyTruthy5(state.input) ? state.input : {};
1170
+ const dataRaw = "data" in input ? input.data : {};
1171
+ const data = typeof dataRaw === "object" && dataRaw !== null && !Array.isArray(dataRaw) ? dataRaw : {};
1172
+ const run_id = data.id;
1173
+ const entries = _from_state(state);
1174
+ entries.push(
1175
+ ..._from_sidecar(project_root, typeof run_id === "string" ? run_id : null)
1176
+ );
1177
+ return entries.length > 0 ? entries : null;
1178
+ }
1179
+
1180
+ // src/scripts/_cli/explain_last/provider.ts
1181
+ function _isDict(value) {
1182
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1183
+ }
1184
+ function _extract(state) {
1185
+ const direct = state.video_provider;
1186
+ if (_isDict(direct)) {
1187
+ return direct;
1188
+ }
1189
+ const contract = state.contract;
1190
+ if (_isDict(contract)) {
1191
+ const nested = contract.video_provider;
1192
+ if (_isDict(nested)) {
1193
+ return nested;
1194
+ }
1195
+ }
1196
+ return null;
1197
+ }
1198
+ function _pyTruthy6(value) {
1199
+ if (value === null || value === void 0) {
1200
+ return false;
1201
+ }
1202
+ if (typeof value === "string") {
1203
+ return value.length > 0;
1204
+ }
1205
+ if (typeof value === "number") {
1206
+ return value !== 0 && !Number.isNaN(value);
1207
+ }
1208
+ if (typeof value === "boolean") {
1209
+ return value;
1210
+ }
1211
+ if (Array.isArray(value)) {
1212
+ return value.length > 0;
1213
+ }
1214
+ if (typeof value === "object") {
1215
+ return Object.keys(value).length > 0;
1216
+ }
1217
+ return true;
1218
+ }
1219
+ function build6(state) {
1220
+ const ds = state.directive_set;
1221
+ const dsStr = _pyTruthy6(ds) ? ds : "";
1222
+ if (dsStr !== "video") {
1223
+ return null;
1224
+ }
1225
+ const payload = _extract(state);
1226
+ if (payload === null) {
1227
+ return null;
1228
+ }
1229
+ const pid = payload.id;
1230
+ let reason = payload.selection_reason;
1231
+ if (typeof pid !== "string" || !pid) {
1232
+ return null;
1233
+ }
1234
+ if (typeof reason !== "string" || !reason) {
1235
+ reason = "";
1236
+ }
1237
+ return {
1238
+ id: scrub_string(pid),
1239
+ selection_reason: scrub_string(reason)
1240
+ };
1241
+ }
1242
+
1243
+ // src/scripts/_cli/explain_last/route.ts
1244
+ import * as fs6 from "node:fs";
1245
+ import * as path6 from "node:path";
1246
+ var ROUTER_FILENAME = "router.json";
1247
+ var ROUTER_RELATIVE = path6.join("dist", ROUTER_FILENAME);
1248
+ function _load_router(project_root) {
1249
+ const p = path6.join(project_root, ROUTER_RELATIVE);
1250
+ if (!fs6.existsSync(p)) {
1251
+ return null;
1252
+ }
1253
+ try {
1254
+ const parsed = JSON.parse(fs6.readFileSync(p, "utf-8"));
1255
+ return parsed;
1256
+ } catch {
1257
+ return null;
1258
+ }
1259
+ }
1260
+ function build7(project_root, state) {
1261
+ const router = _load_router(project_root);
1262
+ if (router === null) {
1263
+ return null;
1264
+ }
1265
+ const kernel = [];
1266
+ for (const rid of router.kernel ?? []) {
1267
+ kernel.push(scrub_string(String(rid)));
1268
+ }
1269
+ const tier_1 = [];
1270
+ for (const entry of router.tier_1 ?? []) {
1271
+ if (typeof entry === "object" && entry !== null && !Array.isArray(entry)) {
1272
+ const rid = entry.id;
1273
+ if (typeof rid === "string") {
1274
+ tier_1.push(scrub_string(rid));
1275
+ }
1276
+ }
1277
+ }
1278
+ const persona = state.persona;
1279
+ const persona_str = typeof persona === "string" && persona ? scrub_string(persona) : null;
1280
+ return {
1281
+ matched_rules: tier_1,
1282
+ kernel_rules: kernel,
1283
+ persona: persona_str
1284
+ };
1285
+ }
1286
+
1287
+ // src/scripts/_cli/explain_last/index.ts
1288
+ var TRACE_VERSION = 1;
1289
+ var SUBJECT_BY_KIND = {
1290
+ ticket: "implement-ticket",
1291
+ prompt: "work",
1292
+ diff: "work",
1293
+ file: "work"
1294
+ };
1295
+ function _pyTruthy7(value) {
1296
+ if (value === null || value === void 0) {
1297
+ return false;
1298
+ }
1299
+ if (typeof value === "string") {
1300
+ return value.length > 0;
1301
+ }
1302
+ if (typeof value === "number") {
1303
+ return value !== 0 && !Number.isNaN(value);
1304
+ }
1305
+ if (typeof value === "boolean") {
1306
+ return value;
1307
+ }
1308
+ if (Array.isArray(value)) {
1309
+ return value.length > 0;
1310
+ }
1311
+ if (typeof value === "object") {
1312
+ return Object.keys(value).length > 0;
1313
+ }
1314
+ return true;
1315
+ }
1316
+ function _derive_subject(state) {
1317
+ const directive_set = _pyTruthy7(state.directive_set) ? state.directive_set : "";
1318
+ if (directive_set === "video") {
1319
+ return "video";
1320
+ }
1321
+ if (directive_set === "council") {
1322
+ return "council";
1323
+ }
1324
+ const input = _pyTruthy7(state.input) ? state.input : {};
1325
+ const kind = input.kind;
1326
+ const key = typeof kind === "string" && kind ? kind : "";
1327
+ const mapped = SUBJECT_BY_KIND[key];
1328
+ return mapped ?? "unknown";
1329
+ }
1330
+ function _utcIsoFromEpochSeconds(epochSeconds) {
1331
+ const totalMicros = Math.round(epochSeconds * 1e6);
1332
+ const wholeSeconds = Math.floor(totalMicros / 1e6);
1333
+ const micros = totalMicros - wholeSeconds * 1e6;
1334
+ const d = new Date(wholeSeconds * 1e3);
1335
+ const yyyy = String(d.getUTCFullYear()).padStart(4, "0");
1336
+ const mm = String(d.getUTCMonth() + 1).padStart(2, "0");
1337
+ const dd = String(d.getUTCDate()).padStart(2, "0");
1338
+ const hh = String(d.getUTCHours()).padStart(2, "0");
1339
+ const mi = String(d.getUTCMinutes()).padStart(2, "0");
1340
+ const ss = String(d.getUTCSeconds()).padStart(2, "0");
1341
+ let base = `${yyyy}-${mm}-${dd}T${hh}:${mi}:${ss}`;
1342
+ if (micros !== 0) {
1343
+ base += `.${String(micros).padStart(6, "0")}`;
1344
+ }
1345
+ return `${base}+00:00`;
1346
+ }
1347
+ function _derive_run_id(state, state_file) {
1348
+ const input = _pyTruthy7(state.input) ? state.input : {};
1349
+ const dataRaw = _pyTruthy7(input.data) ? input.data : {};
1350
+ const data = typeof dataRaw === "object" && dataRaw !== null && !Array.isArray(dataRaw) ? dataRaw : {};
1351
+ const raw_id = data.id;
1352
+ if (typeof raw_id === "string" && raw_id.trim()) {
1353
+ return scrub_string(raw_id.trim());
1354
+ }
1355
+ let mtime = 0;
1356
+ try {
1357
+ mtime = fs7.statSync(state_file).mtimeMs / 1e3;
1358
+ } catch {
1359
+ mtime = 0;
1360
+ }
1361
+ return _utcIsoFromEpochSeconds(mtime);
1362
+ }
1363
+ function build_trace(project_root, state_file, options = {}) {
1364
+ const state = load_state(state_file);
1365
+ const now = options.now ?? null;
1366
+ const generated_at = _utcIsoFromEpochSeconds((now ?? /* @__PURE__ */ new Date()).getTime() / 1e3);
1367
+ return {
1368
+ version: TRACE_VERSION,
1369
+ generated_at,
1370
+ run_id: _derive_run_id(state, state_file),
1371
+ subject: _derive_subject(state),
1372
+ inputs: build4(project_root),
1373
+ route: build7(project_root, state),
1374
+ council: build2(project_root, state_file),
1375
+ memory: build5(project_root, state),
1376
+ pack: build_pack(project_root),
1377
+ assumptions: build(state),
1378
+ halt: build3(state),
1379
+ provider: build6(state)
1380
+ };
1381
+ }
1382
+
1383
+ // src/scripts/_cli/explain_last/sections/assumptions.ts
1384
+ var assumptions_exports2 = {};
1385
+ __export(assumptions_exports2, {
1386
+ render: () => render
1387
+ });
1388
+ function _pyTruthy8(value) {
1389
+ if (value === null || value === void 0) {
1390
+ return false;
1391
+ }
1392
+ if (typeof value === "string") {
1393
+ return value.length > 0;
1394
+ }
1395
+ if (typeof value === "number") {
1396
+ return value !== 0 && !Number.isNaN(value);
1397
+ }
1398
+ if (typeof value === "boolean") {
1399
+ return value;
1400
+ }
1401
+ if (Array.isArray(value)) {
1402
+ return value.length > 0;
1403
+ }
1404
+ if (typeof value === "object") {
1405
+ return Object.keys(value).length > 0;
1406
+ }
1407
+ return true;
1408
+ }
1409
+ function render(trace) {
1410
+ const out = ["## Assumptions", ""];
1411
+ const items = _pyTruthy8(trace.assumptions) ? trace.assumptions : [];
1412
+ if (items.length === 0) {
1413
+ out.push("- (none captured)");
1414
+ out.push("");
1415
+ return out.join("\n");
1416
+ }
1417
+ for (const itemRaw of items) {
1418
+ const item = itemRaw;
1419
+ const ident = _pyTruthy8(item.id) ? item.id : "(unknown)";
1420
+ const accepted = "accepted" in item ? item.accepted : true;
1421
+ const source = _pyTruthy8(item.source) ? item.source : "unspecified";
1422
+ const marker = accepted ? "[x]" : "[ ]";
1423
+ out.push(`- ${marker} ${ident} \u2014 recorded in step \`${source}\``);
1424
+ }
1425
+ out.push("");
1426
+ return out.join("\n");
1427
+ }
1428
+
1429
+ // src/scripts/_cli/explain_last/sections/council.ts
1430
+ var council_exports2 = {};
1431
+ __export(council_exports2, {
1432
+ render: () => render2
1433
+ });
1434
+ function _pyTruthy9(value) {
1435
+ if (value === null || value === void 0) {
1436
+ return false;
1437
+ }
1438
+ if (typeof value === "string") {
1439
+ return value.length > 0;
1440
+ }
1441
+ if (typeof value === "number") {
1442
+ return value !== 0 && !Number.isNaN(value);
1443
+ }
1444
+ if (typeof value === "boolean") {
1445
+ return value;
1446
+ }
1447
+ if (Array.isArray(value)) {
1448
+ return value.length > 0;
1449
+ }
1450
+ if (typeof value === "object") {
1451
+ return Object.keys(value).length > 0;
1452
+ }
1453
+ return true;
1454
+ }
1455
+ function render2(trace) {
1456
+ const out = ["## Council", ""];
1457
+ const members = _pyTruthy9(trace.council) ? trace.council : [];
1458
+ if (members.length === 0) {
1459
+ out.push("(none recorded for this run)");
1460
+ out.push("");
1461
+ return out.join("\n");
1462
+ }
1463
+ for (const memberRaw of members) {
1464
+ const member = memberRaw;
1465
+ const mid = _pyTruthy9(member.member_id) ? member.member_id : "(unknown)";
1466
+ const verdict = _pyTruthy9(member.verdict) ? member.verdict : "(no verdict)";
1467
+ out.push(`### ${mid}`);
1468
+ out.push("");
1469
+ out.push(`> ${verdict}`);
1470
+ const citations = _pyTruthy9(member.citations) ? member.citations : [];
1471
+ if (citations.length > 0) {
1472
+ out.push("");
1473
+ out.push("Citations:");
1474
+ for (const cite of citations) {
1475
+ out.push(`- ${cite}`);
1476
+ }
1477
+ }
1478
+ out.push("");
1479
+ }
1480
+ return out.join("\n");
1481
+ }
1482
+
1483
+ // src/scripts/_cli/explain_last/sections/halt.ts
1484
+ var halt_exports2 = {};
1485
+ __export(halt_exports2, {
1486
+ render: () => render3
1487
+ });
1488
+ function _pyTruthy10(value) {
1489
+ if (value === null || value === void 0) {
1490
+ return false;
1491
+ }
1492
+ if (typeof value === "string") {
1493
+ return value.length > 0;
1494
+ }
1495
+ if (typeof value === "number") {
1496
+ return value !== 0 && !Number.isNaN(value);
1497
+ }
1498
+ if (typeof value === "boolean") {
1499
+ return value;
1500
+ }
1501
+ if (Array.isArray(value)) {
1502
+ return value.length > 0;
1503
+ }
1504
+ if (typeof value === "object") {
1505
+ return Object.keys(value).length > 0;
1506
+ }
1507
+ return true;
1508
+ }
1509
+ function render3(trace) {
1510
+ const out = ["## Why halted?", ""];
1511
+ const halt = trace.halt;
1512
+ if (!_pyTruthy10(halt)) {
1513
+ out.push("(clean run \u2014 no halt recorded)");
1514
+ out.push("");
1515
+ return out.join("\n");
1516
+ }
1517
+ const h = halt;
1518
+ const reason = _pyTruthy10(h.reason) ? h.reason : "(unknown)";
1519
+ const step = _pyTruthy10(h.step) ? h.step : "(unspecified)";
1520
+ out.push(`- **Reason:** \`${reason}\``);
1521
+ out.push(`- **Hook event:** \`${step}\``);
1522
+ const surface = _pyTruthy10(h.surface) ? h.surface : [];
1523
+ if (surface.length > 0) {
1524
+ out.push("");
1525
+ out.push("Surface emitted to the user:");
1526
+ out.push("");
1527
+ for (const line of surface) {
1528
+ out.push(` ${line}`);
1529
+ }
1530
+ }
1531
+ out.push("");
1532
+ return out.join("\n");
1533
+ }
1534
+
1535
+ // src/scripts/_cli/explain_last/sections/header.ts
1536
+ var header_exports = {};
1537
+ __export(header_exports, {
1538
+ render: () => render4
1539
+ });
1540
+ function _pyTruthy11(value) {
1541
+ if (value === null || value === void 0) {
1542
+ return false;
1543
+ }
1544
+ if (typeof value === "string") {
1545
+ return value.length > 0;
1546
+ }
1547
+ if (typeof value === "number") {
1548
+ return value !== 0 && !Number.isNaN(value);
1549
+ }
1550
+ if (typeof value === "boolean") {
1551
+ return value;
1552
+ }
1553
+ if (Array.isArray(value)) {
1554
+ return value.length > 0;
1555
+ }
1556
+ if (typeof value === "object") {
1557
+ return Object.keys(value).length > 0;
1558
+ }
1559
+ return true;
1560
+ }
1561
+ var _SUBJECT_LABELS = {
1562
+ work: "/work",
1563
+ "implement-ticket": "/implement-ticket",
1564
+ council: "/council",
1565
+ video: "/video",
1566
+ unknown: "(unknown)"
1567
+ };
1568
+ function render4(trace) {
1569
+ const run_id = _pyTruthy11(trace.run_id) ? trace.run_id : "(unknown)";
1570
+ const subject = _pyTruthy11(trace.subject) ? trace.subject : "unknown";
1571
+ const label = Object.prototype.hasOwnProperty.call(_SUBJECT_LABELS, subject) ? _SUBJECT_LABELS[subject] : subject;
1572
+ const started = _pyTruthy11(trace.generated_at) ? trace.generated_at : "";
1573
+ return `# explain last \u2014 run ${run_id}
1574
+
1575
+ **Subject:** ${label} \xB7 **Started:** ${started}
1576
+ `;
1577
+ }
1578
+
1579
+ // src/scripts/_cli/explain_last/sections/inputs.ts
1580
+ var inputs_exports2 = {};
1581
+ __export(inputs_exports2, {
1582
+ render: () => render5
1583
+ });
1584
+ function _pyTruthy12(value) {
1585
+ if (value === null || value === void 0) {
1586
+ return false;
1587
+ }
1588
+ if (typeof value === "string") {
1589
+ return value.length > 0;
1590
+ }
1591
+ if (typeof value === "number") {
1592
+ return value !== 0 && !Number.isNaN(value);
1593
+ }
1594
+ if (typeof value === "boolean") {
1595
+ return value;
1596
+ }
1597
+ if (Array.isArray(value)) {
1598
+ return value.length > 0;
1599
+ }
1600
+ if (typeof value === "object") {
1601
+ return Object.keys(value).length > 0;
1602
+ }
1603
+ return true;
1604
+ }
1605
+ function _pyStr(value) {
1606
+ if (typeof value === "boolean") {
1607
+ return value ? "True" : "False";
1608
+ }
1609
+ return String(value);
1610
+ }
1611
+ function render5(trace) {
1612
+ const out = ["## Why this profile / preset?", ""];
1613
+ const inputs = trace.inputs;
1614
+ if (!_pyTruthy12(inputs)) {
1615
+ out.push("- (none) \u2014 settings could not be resolved");
1616
+ out.push("");
1617
+ return out.join("\n");
1618
+ }
1619
+ const inp = inputs;
1620
+ const sources = _pyTruthy12(inp.source_per_knob) ? inp.source_per_knob : {};
1621
+ const rows = [
1622
+ ["profile.id", inp.profile, sources.profile],
1623
+ ["preset.id", inp.preset, sources.preset],
1624
+ ["rule_loading_tier", inp.rule_loading_tier, sources.rule_loading_tier]
1625
+ ];
1626
+ out.push("| knob | value | source |");
1627
+ out.push("|---|---|---|");
1628
+ for (const [knob, value, source] of rows) {
1629
+ const value_str = value === null || value === void 0 ? "(none)" : _pyStr(value);
1630
+ const source_str = _pyTruthy12(source) ? source : "default";
1631
+ out.push(`| ${knob} | ${value_str} | ${source_str} |`);
1632
+ }
1633
+ out.push("");
1634
+ return out.join("\n");
1635
+ }
1636
+
1637
+ // src/scripts/_cli/explain_last/sections/memory.ts
1638
+ var memory_exports2 = {};
1639
+ __export(memory_exports2, {
1640
+ render: () => render6
1641
+ });
1642
+ function _pyTruthy13(value) {
1643
+ if (value === null || value === void 0) {
1644
+ return false;
1645
+ }
1646
+ if (typeof value === "string") {
1647
+ return value.length > 0;
1648
+ }
1649
+ if (typeof value === "number") {
1650
+ return value !== 0 && !Number.isNaN(value);
1651
+ }
1652
+ if (typeof value === "boolean") {
1653
+ return value;
1654
+ }
1655
+ if (Array.isArray(value)) {
1656
+ return value.length > 0;
1657
+ }
1658
+ if (typeof value === "object") {
1659
+ return Object.keys(value).length > 0;
1660
+ }
1661
+ return true;
1662
+ }
1663
+ function _fmt2(x) {
1664
+ if (!Number.isFinite(x)) {
1665
+ if (Number.isNaN(x)) {
1666
+ return "nan";
1667
+ }
1668
+ return x > 0 ? "inf" : "-inf";
1669
+ }
1670
+ const nd = 2;
1671
+ const neg = x < 0 || Object.is(x, -0);
1672
+ const ax = Math.abs(x);
1673
+ const buf = new DataView(new ArrayBuffer(8));
1674
+ buf.setFloat64(0, ax);
1675
+ const bits = buf.getBigUint64(0);
1676
+ const expo = Number(bits >> 52n & 0x7ffn);
1677
+ const mant = bits & 0xfffffffffffffn;
1678
+ let num;
1679
+ let den;
1680
+ if (expo === 0) {
1681
+ num = mant;
1682
+ den = 1n << 1074n;
1683
+ } else {
1684
+ num = mant | 0x10000000000000n;
1685
+ const e = BigInt(expo) - 1075n;
1686
+ if (e >= 0n) {
1687
+ num <<= e;
1688
+ den = 1n;
1689
+ } else {
1690
+ den = 1n << -e;
1691
+ }
1692
+ }
1693
+ const scale = 10n ** BigInt(nd);
1694
+ const numS = num * scale;
1695
+ let q = numS / den;
1696
+ const r = numS % den;
1697
+ const twice = r * 2n;
1698
+ if (twice > den) {
1699
+ q += 1n;
1700
+ } else if (twice === den && q % 2n === 1n) {
1701
+ q += 1n;
1702
+ }
1703
+ const s = q.toString().padStart(nd + 1, "0");
1704
+ const ip = s.slice(0, s.length - nd) || "0";
1705
+ const fp = s.slice(s.length - nd);
1706
+ const out = `${ip}.${fp}`;
1707
+ return neg ? `-${out}` : out;
1708
+ }
1709
+ function render6(trace) {
1710
+ const out = ["## Memory hits influencing this run", ""];
1711
+ const entries = _pyTruthy13(trace.memory) ? trace.memory : [];
1712
+ if (entries.length === 0) {
1713
+ out.push("- (none)");
1714
+ out.push("");
1715
+ return out.join("\n");
1716
+ }
1717
+ for (const entryRaw of entries) {
1718
+ const entry = entryRaw;
1719
+ const entry_id = _pyTruthy13(entry.entry_id) ? entry.entry_id : "(unknown)";
1720
+ const score = entry.hit_score;
1721
+ const used_in = _pyTruthy13(entry.used_in) ? entry.used_in : "unspecified";
1722
+ let score_str;
1723
+ if (score instanceof PyFloat) {
1724
+ score_str = `score ${_fmt2(score.value)}`;
1725
+ } else if (typeof score === "boolean") {
1726
+ score_str = `score ${_fmt2(score ? 1 : 0)}`;
1727
+ } else if (typeof score === "number") {
1728
+ score_str = `score ${_fmt2(score)}`;
1729
+ } else {
1730
+ score_str = "score n/a";
1731
+ }
1732
+ out.push(`- ${entry_id} (${score_str}) \u2014 used in ${used_in}`);
1733
+ }
1734
+ out.push("");
1735
+ return out.join("\n");
1736
+ }
1737
+
1738
+ // src/scripts/_cli/explain_last/sections/pack.ts
1739
+ var pack_exports = {};
1740
+ __export(pack_exports, {
1741
+ render: () => render7
1742
+ });
1743
+ function _pyTruthy14(value) {
1744
+ if (value === null || value === void 0) {
1745
+ return false;
1746
+ }
1747
+ if (typeof value === "string") {
1748
+ return value.length > 0;
1749
+ }
1750
+ if (typeof value === "number") {
1751
+ return value !== 0 && !Number.isNaN(value);
1752
+ }
1753
+ if (typeof value === "boolean") {
1754
+ return value;
1755
+ }
1756
+ if (Array.isArray(value)) {
1757
+ return value.length > 0;
1758
+ }
1759
+ if (typeof value === "object") {
1760
+ return Object.keys(value).length > 0;
1761
+ }
1762
+ return true;
1763
+ }
1764
+ function render7(trace) {
1765
+ const pack = trace.pack;
1766
+ if (!_pyTruthy14(pack)) {
1767
+ return "";
1768
+ }
1769
+ const p = pack;
1770
+ const pack_id = _pyTruthy14(p.id) ? p.id : "(unknown)";
1771
+ const reason = _pyTruthy14(p.reason) ? p.reason : "";
1772
+ const out = ["## Active pack", ""];
1773
+ out.push(_pyTruthy14(reason) ? `- ${pack_id} \u2014 ${reason}` : `- ${pack_id}`);
1774
+ out.push("");
1775
+ return out.join("\n");
1776
+ }
1777
+
1778
+ // src/scripts/_cli/explain_last/sections/provider.ts
1779
+ var provider_exports2 = {};
1780
+ __export(provider_exports2, {
1781
+ render: () => render8
1782
+ });
1783
+ function _pyTruthy15(value) {
1784
+ if (value === null || value === void 0) {
1785
+ return false;
1786
+ }
1787
+ if (typeof value === "string") {
1788
+ return value.length > 0;
1789
+ }
1790
+ if (typeof value === "number") {
1791
+ return value !== 0 && !Number.isNaN(value);
1792
+ }
1793
+ if (typeof value === "boolean") {
1794
+ return value;
1795
+ }
1796
+ if (Array.isArray(value)) {
1797
+ return value.length > 0;
1798
+ }
1799
+ if (typeof value === "object") {
1800
+ return Object.keys(value).length > 0;
1801
+ }
1802
+ return true;
1803
+ }
1804
+ function render8(trace) {
1805
+ const provider = trace.provider;
1806
+ if (!_pyTruthy15(provider)) {
1807
+ return "";
1808
+ }
1809
+ const p = provider;
1810
+ const pid = _pyTruthy15(p.id) ? p.id : "(unknown)";
1811
+ const reason = _pyTruthy15(p.selection_reason) ? p.selection_reason : "(no reason recorded)";
1812
+ const out = [
1813
+ "## Why this provider?",
1814
+ "",
1815
+ `- **Provider:** \`${pid}\``,
1816
+ `- **Selection reason:** ${reason}`,
1817
+ ""
1818
+ ];
1819
+ return out.join("\n");
1820
+ }
1821
+
1822
+ // src/scripts/_cli/explain_last/sections/route.ts
1823
+ var route_exports2 = {};
1824
+ __export(route_exports2, {
1825
+ render: () => render9
1826
+ });
1827
+ function _pyTruthy16(value) {
1828
+ if (value === null || value === void 0) {
1829
+ return false;
1830
+ }
1831
+ if (typeof value === "string") {
1832
+ return value.length > 0;
1833
+ }
1834
+ if (typeof value === "number") {
1835
+ return value !== 0 && !Number.isNaN(value);
1836
+ }
1837
+ if (typeof value === "boolean") {
1838
+ return value;
1839
+ }
1840
+ if (Array.isArray(value)) {
1841
+ return value.length > 0;
1842
+ }
1843
+ if (typeof value === "object") {
1844
+ return Object.keys(value).length > 0;
1845
+ }
1846
+ return true;
1847
+ }
1848
+ function render9(trace) {
1849
+ const out = ["## Why this route?", ""];
1850
+ const route = trace.route;
1851
+ if (!_pyTruthy16(route)) {
1852
+ out.push("- (none) \u2014 router.json missing or unreadable");
1853
+ out.push("");
1854
+ return out.join("\n");
1855
+ }
1856
+ const r = route;
1857
+ const matched = _pyTruthy16(r.matched_rules) ? r.matched_rules : [];
1858
+ const kernel = _pyTruthy16(r.kernel_rules) ? r.kernel_rules : [];
1859
+ const persona = _pyTruthy16(r.persona) ? r.persona : "(none)";
1860
+ const matched_str = matched.length > 0 ? matched.join(", ") : "(none)";
1861
+ out.push(`- Active rules: ${matched_str}`);
1862
+ out.push(`- Kernel rules: ${kernel.length}`);
1863
+ out.push(`- Persona: ${persona}`);
1864
+ out.push("");
1865
+ return out.join("\n");
1866
+ }
1867
+
1868
+ // src/scripts/_cli/explain_last/render.ts
1869
+ var _SECTION_ORDER = [
1870
+ header_exports.render,
1871
+ route_exports2.render,
1872
+ inputs_exports2.render,
1873
+ memory_exports2.render,
1874
+ council_exports2.render,
1875
+ halt_exports2.render,
1876
+ provider_exports2.render,
1877
+ assumptions_exports2.render,
1878
+ pack_exports.render
1879
+ ];
1880
+ var TIP_FOOTER = "_tip: pass `--json` to emit machine-readable trace; `--quiet` to drop this footer._\n";
1881
+ function _rstrip(s) {
1882
+ return s.replace(/\s+$/u, "");
1883
+ }
1884
+ function render10(trace, options = {}) {
1885
+ const with_footer = options.with_footer ?? true;
1886
+ const parts = [];
1887
+ for (const section of _SECTION_ORDER) {
1888
+ const chunk = section(trace);
1889
+ if (chunk) {
1890
+ parts.push(chunk);
1891
+ }
1892
+ }
1893
+ let body = `${_rstrip(parts.join("\n"))}
1894
+ `;
1895
+ if (with_footer) {
1896
+ body += `
1897
+ ${TIP_FOOTER}`;
1898
+ }
1899
+ return body;
1900
+ }
1901
+
1902
+ // src/scripts/_cli/cmd_explain.ts
1903
+ var ROUTER_FILENAME2 = "router.json";
1904
+ var ROUTER_RELATIVE2 = path7.join("dist", ROUTER_FILENAME2);
1905
+ var _HERE = fileURLToPath(import.meta.url);
1906
+ var ArgparseExit = class extends Error {
1907
+ constructor(code) {
1908
+ super(`argparse-exit-${code}`);
1909
+ this.code = code;
1910
+ }
1911
+ code;
1912
+ };
1913
+ var SystemExitError = class extends Error {
1914
+ constructor(code) {
1915
+ super(`system-exit-${code}`);
1916
+ this.code = code;
1917
+ }
1918
+ code;
1919
+ };
1920
+ function print(line = "") {
1921
+ process2.stdout.write(line + "\n");
1922
+ }
1923
+ function eprint(line = "") {
1924
+ process2.stderr.write(line + "\n");
1925
+ }
1926
+ function _jsonStrAscii(s) {
1927
+ let out = '"';
1928
+ for (const ch of s) {
1929
+ const code = ch.codePointAt(0);
1930
+ switch (ch) {
1931
+ case '"':
1932
+ out += '\\"';
1933
+ break;
1934
+ case "\\":
1935
+ out += "\\\\";
1936
+ break;
1937
+ case "\n":
1938
+ out += "\\n";
1939
+ break;
1940
+ case "\r":
1941
+ out += "\\r";
1942
+ break;
1943
+ case " ":
1944
+ out += "\\t";
1945
+ break;
1946
+ case "\b":
1947
+ out += "\\b";
1948
+ break;
1949
+ case "\f":
1950
+ out += "\\f";
1951
+ break;
1952
+ default:
1953
+ if (code < 32) {
1954
+ out += "\\u" + code.toString(16).padStart(4, "0");
1955
+ } else if (code < 127) {
1956
+ out += ch;
1957
+ } else if (code <= 65535) {
1958
+ out += "\\u" + code.toString(16).padStart(4, "0");
1959
+ } else {
1960
+ const v = code - 65536;
1961
+ const hi = 55296 + (v >> 10);
1962
+ const lo = 56320 + (v & 1023);
1963
+ out += "\\u" + hi.toString(16).padStart(4, "0") + "\\u" + lo.toString(16).padStart(4, "0");
1964
+ }
1965
+ }
1966
+ }
1967
+ return out + '"';
1968
+ }
1969
+ function _jsonScalarAscii(value) {
1970
+ if (value === null || value === void 0) return "null";
1971
+ if (typeof value === "boolean") return value ? "true" : "false";
1972
+ if (typeof value === "number") {
1973
+ if (!Number.isFinite(value)) {
1974
+ if (Number.isNaN(value)) return "NaN";
1975
+ return value > 0 ? "Infinity" : "-Infinity";
1976
+ }
1977
+ return String(value);
1978
+ }
1979
+ if (typeof value === "string") return _jsonStrAscii(value);
1980
+ return null;
1981
+ }
1982
+ function _dumpSortedAscii(value, indent, depth) {
1983
+ const scalar = _jsonScalarAscii(value);
1984
+ if (scalar !== null) return scalar;
1985
+ const pad = " ".repeat(indent * (depth + 1));
1986
+ const closePad = " ".repeat(indent * depth);
1987
+ if (Array.isArray(value)) {
1988
+ if (value.length === 0) return "[]";
1989
+ const items = value.map((v) => pad + _dumpSortedAscii(v, indent, depth + 1));
1990
+ return `[
1991
+ ${items.join(",\n")}
1992
+ ${closePad}]`;
1993
+ }
1994
+ if (typeof value === "object" && value !== null) {
1995
+ const obj = value;
1996
+ const keys = Object.keys(obj).sort();
1997
+ if (keys.length === 0) return "{}";
1998
+ const items = keys.map(
1999
+ (k) => `${pad}${_jsonStrAscii(k)}: ${_dumpSortedAscii(obj[k], indent, depth + 1)}`
2000
+ );
2001
+ return `{
2002
+ ${items.join(",\n")}
2003
+ ${closePad}}`;
2004
+ }
2005
+ return _jsonStrAscii(String(value));
2006
+ }
2007
+ function _jsonDumpsIndentSortedAscii(value) {
2008
+ return _dumpSortedAscii(value, 2, 0);
2009
+ }
2010
+ function _dumpJson(payload) {
2011
+ process2.stdout.write(_jsonDumpsIndentSortedAscii(payload));
2012
+ process2.stdout.write("\n");
2013
+ }
2014
+ function _exists3(p) {
2015
+ try {
2016
+ fs8.statSync(p);
2017
+ return true;
2018
+ } catch {
2019
+ return false;
2020
+ }
2021
+ }
2022
+ function pyReprStr(value) {
2023
+ if (value.includes("'") && !value.includes('"')) {
2024
+ return `"${value}"`;
2025
+ }
2026
+ const escaped = value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
2027
+ return `'${escaped}'`;
2028
+ }
2029
+ function _resolve_root(arg) {
2030
+ try {
2031
+ return resolve_project_root(arg, { cwd: process2.cwd() });
2032
+ } catch (exc) {
2033
+ if (exc instanceof ProjectRootError) {
2034
+ eprint(`\u274C explain: ${exc.message}`);
2035
+ throw new SystemExitError(2);
2036
+ }
2037
+ throw exc;
2038
+ }
2039
+ }
2040
+ function _load_user_settings(project_root) {
2041
+ const p = path7.join(project_root, DEFAULT_PROJECT_FILE);
2042
+ if (!_exists3(p)) {
2043
+ return {};
2044
+ }
2045
+ return load_agent_settings({ project_path: p }) || {};
2046
+ }
2047
+ function _load_router2(project_root) {
2048
+ const p = path7.join(project_root, ROUTER_RELATIVE2);
2049
+ if (!_exists3(p)) {
2050
+ return {};
2051
+ }
2052
+ try {
2053
+ return JSON.parse(fs8.readFileSync(p, { encoding: "utf-8" }));
2054
+ } catch (exc) {
2055
+ eprint(`\u274C explain: cannot read ${p}: ${osErrorStr(exc)}`);
2056
+ throw new SystemExitError(2);
2057
+ }
2058
+ }
2059
+ function osErrorStr(exc) {
2060
+ if (exc instanceof Error) {
2061
+ return exc.message;
2062
+ }
2063
+ return String(exc);
2064
+ }
2065
+ function _explain_config(project_root, as_json) {
2066
+ const settings = _load_user_settings(project_root);
2067
+ const resolved_profile = resolve_profile({
2068
+ project_root,
2069
+ user_settings: settings
2070
+ });
2071
+ const resolved_preset = resolve_preset({
2072
+ project_root,
2073
+ user_settings: settings,
2074
+ profile_preset_id: resolved_profile.preset_id
2075
+ });
2076
+ const payload = {
2077
+ project_root: String(project_root),
2078
+ profile: {
2079
+ id: resolved_profile.id,
2080
+ source: resolved_profile.source,
2081
+ preset_id: resolved_profile.preset_id,
2082
+ warning: resolved_profile.warning
2083
+ },
2084
+ preset: {
2085
+ id: resolved_preset.id,
2086
+ source: resolved_preset.source,
2087
+ overrides: [...resolved_preset.overrides],
2088
+ knobs: resolved_preset.knobs
2089
+ },
2090
+ env: {
2091
+ [PROFILE_ID_ENV]: process2.env[PROFILE_ID_ENV] ?? null,
2092
+ [PRESET_ID_ENV]: process2.env[PRESET_ID_ENV] ?? null
2093
+ }
2094
+ };
2095
+ if (as_json) {
2096
+ _dumpJson(payload);
2097
+ return 0;
2098
+ }
2099
+ print(` \u{1F4CD} project_root: ${project_root}`);
2100
+ print();
2101
+ print(` profile.id: ${resolved_profile.id} (source: ${resolved_profile.source})`);
2102
+ if (resolved_profile.warning) {
2103
+ print(` \u26A0\uFE0F ${resolved_profile.warning}`);
2104
+ }
2105
+ print(` preset.id: ${resolved_preset.id} (source: ${resolved_preset.source})`);
2106
+ if (resolved_preset.overrides.length > 0) {
2107
+ print(` overrides: ${resolved_preset.overrides.join(", ")}`);
2108
+ }
2109
+ const knobs = resolved_preset.knobs;
2110
+ const cost = isPlainObject(knobs["cost"]) ? knobs["cost"] : {};
2111
+ if (Object.keys(cost).length > 0) {
2112
+ print(
2113
+ ` cost caps: daily $${fmt(cost["daily_max_usd"])} \xB7 weekly $${fmt(cost["weekly_max_usd"])} \xB7 monthly $${fmt(cost["monthly_max_usd"])}`
2114
+ );
2115
+ }
2116
+ const autonomy = isPlainObject(knobs["autonomy"]) ? knobs["autonomy"] : {};
2117
+ if (Object.keys(autonomy).length > 0) {
2118
+ print(` autonomy: default=${fmt(autonomy["default"])}`);
2119
+ }
2120
+ return 0;
2121
+ }
2122
+ function fmt(value) {
2123
+ if (value === null || value === void 0) return "None";
2124
+ if (typeof value === "boolean") return value ? "True" : "False";
2125
+ return String(value);
2126
+ }
2127
+ function isPlainObject(value) {
2128
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2129
+ }
2130
+ function _find_rule(router, name) {
2131
+ const kernel = router["kernel"] || [];
2132
+ if (kernel.includes(name)) {
2133
+ return ["kernel", { id: name, triggers: [{ always: true }] }];
2134
+ }
2135
+ for (const tier of ["tier_1", "tier_2"]) {
2136
+ const entries = router[tier] || [];
2137
+ for (const entry of entries) {
2138
+ if (entry["id"] === name) {
2139
+ return [tier, entry];
2140
+ }
2141
+ }
2142
+ }
2143
+ return null;
2144
+ }
2145
+ function _explain_rule(project_root, name, as_json) {
2146
+ const router = _load_router2(project_root);
2147
+ const found = _find_rule(router, name);
2148
+ if (found === null) {
2149
+ eprint(`\u274C explain: rule ${pyReprStr(name)} not found in router`);
2150
+ return 1;
2151
+ }
2152
+ const [tier, entry] = found;
2153
+ const payload = { rule: name, tier, entry };
2154
+ if (as_json) {
2155
+ _dumpJson(payload);
2156
+ return 0;
2157
+ }
2158
+ print(` rule: ${name}`);
2159
+ print(` tier: ${tier}`);
2160
+ const triggers = entry["triggers"] || [];
2161
+ print(` triggers (${triggers.length}):`);
2162
+ for (const trig of triggers) {
2163
+ print(` \xB7 ${pyStr(trig)}`);
2164
+ }
2165
+ const routes = entry["routes_to"] || [];
2166
+ if (routes.length > 0) {
2167
+ print(` routes_to: ${routes.join(", ")}`);
2168
+ }
2169
+ return 0;
2170
+ }
2171
+ function pyStr(value) {
2172
+ if (value === null || value === void 0) return "None";
2173
+ if (typeof value === "boolean") return value ? "True" : "False";
2174
+ if (typeof value === "string") return value;
2175
+ if (typeof value === "number") return String(value);
2176
+ if (Array.isArray(value)) {
2177
+ return "[" + value.map((v) => pyReprAny(v)).join(", ") + "]";
2178
+ }
2179
+ if (typeof value === "object") {
2180
+ const obj = value;
2181
+ const parts = Object.keys(obj).map((k) => `${pyReprAny(k)}: ${pyReprAny(obj[k])}`);
2182
+ return "{" + parts.join(", ") + "}";
2183
+ }
2184
+ return String(value);
2185
+ }
2186
+ function pyReprAny(value) {
2187
+ if (value === null || value === void 0) return "None";
2188
+ if (typeof value === "boolean") return value ? "True" : "False";
2189
+ if (typeof value === "string") return pyReprStr(value);
2190
+ if (typeof value === "number") return String(value);
2191
+ if (Array.isArray(value)) {
2192
+ return "[" + value.map((v) => pyReprAny(v)).join(", ") + "]";
2193
+ }
2194
+ if (typeof value === "object") {
2195
+ const obj = value;
2196
+ const parts = Object.keys(obj).map((k) => `${pyReprAny(k)}: ${pyReprAny(obj[k])}`);
2197
+ return "{" + parts.join(", ") + "}";
2198
+ }
2199
+ return String(value);
2200
+ }
2201
+ function _matches_trigger(trigger, text, lowered) {
2202
+ if ("keyword" in trigger) {
2203
+ const kw = String(trigger["keyword"]).toLowerCase();
2204
+ if (kw && lowered.includes(kw)) {
2205
+ return `keyword: ${kw}`;
2206
+ }
2207
+ }
2208
+ if ("phrase" in trigger) {
2209
+ const ph = String(trigger["phrase"]).toLowerCase();
2210
+ if (ph && lowered.includes(ph)) {
2211
+ return `phrase: ${ph}`;
2212
+ }
2213
+ }
2214
+ if ("path_prefix" in trigger) {
2215
+ const prefix = String(trigger["path_prefix"]);
2216
+ if (prefix && text.includes(prefix)) {
2217
+ return `path_prefix: ${prefix}`;
2218
+ }
2219
+ }
2220
+ return null;
2221
+ }
2222
+ function _explain_route(project_root, text, as_json) {
2223
+ const router = _load_router2(project_root);
2224
+ const lowered = text.toLowerCase();
2225
+ const matches = [];
2226
+ const tier_1 = router["tier_1"] || [];
2227
+ for (const entry of tier_1) {
2228
+ const triggers = entry["triggers"] || [];
2229
+ for (const trig of triggers) {
2230
+ const reason = _matches_trigger(trig, text, lowered);
2231
+ if (reason !== null) {
2232
+ matches.push({ id: entry["id"], tier: "tier_1", reason });
2233
+ break;
2234
+ }
2235
+ }
2236
+ }
2237
+ const kernel_always = [...router["kernel"] || []];
2238
+ const payload = {
2239
+ input: text,
2240
+ kernel_always,
2241
+ tier_1_matches: matches
2242
+ };
2243
+ if (as_json) {
2244
+ _dumpJson(payload);
2245
+ return 0;
2246
+ }
2247
+ print(` input: ${pyReprStr(text)}`);
2248
+ print();
2249
+ print(` kernel (always active, ${kernel_always.length}):`);
2250
+ for (const kid of kernel_always) {
2251
+ print(` \xB7 ${pyStr(kid)}`);
2252
+ }
2253
+ print();
2254
+ print(` tier-1 matches (${matches.length}):`);
2255
+ if (matches.length === 0) {
2256
+ print(" \xB7 (no trigger matched \u2014 only kernel rules active)");
2257
+ return 1;
2258
+ }
2259
+ for (const match of matches) {
2260
+ print(` \xB7 ${match["id"]} (${match["reason"]})`);
2261
+ }
2262
+ return 0;
2263
+ }
2264
+ function _explain_last(project_root, state_file, as_json, quiet) {
2265
+ const settings = _load_user_settings(project_root);
2266
+ const explain_raw = settings["explain"];
2267
+ const explain_cfg = isPlainObject(explain_raw) ? explain_raw : {};
2268
+ if (explain_cfg["enable_last"] === false) {
2269
+ print("explain last disabled by settings (explain.enable_last)");
2270
+ return 0;
2271
+ }
2272
+ const target_state = state_file || path7.join(project_root, ".work-state.json");
2273
+ let trace;
2274
+ try {
2275
+ trace = build_trace(project_root, target_state);
2276
+ } catch (exc) {
2277
+ if (exc instanceof StateLoadError) {
2278
+ let rel;
2279
+ const relativeTo = relativeToOrNull(target_state, project_root);
2280
+ if (relativeTo !== null) {
2281
+ rel = relativeTo;
2282
+ } else {
2283
+ rel = path7.basename(target_state);
2284
+ }
2285
+ const msg = exc.message.split(target_state).join(rel);
2286
+ eprint(`\u274C explain last: ${msg}`);
2287
+ return exc.exitCode;
2288
+ }
2289
+ throw exc;
2290
+ }
2291
+ if (as_json) {
2292
+ _dumpJson(trace);
2293
+ return 0;
2294
+ }
2295
+ process2.stdout.write(render10(trace, { with_footer: !quiet }));
2296
+ return 0;
2297
+ }
2298
+ function relativeToOrNull(p, base) {
2299
+ const rel = path7.relative(base, p);
2300
+ if (rel === "") return rel;
2301
+ if (rel.startsWith("..") || path7.isAbsolute(rel)) {
2302
+ return null;
2303
+ }
2304
+ return rel;
2305
+ }
2306
+ var _LAST_HELP = `usage: agent-config explain last [--project PATH] [--state-file PATH]
2307
+ [--json] [--quiet]
2308
+
2309
+ Reconstruct the execution trace for the most recent /work,
2310
+ /implement-ticket, /council, or /video run. Read-only; never
2311
+ makes network calls. Output is the ExplainTrace v1 contract:
2312
+ docs/contracts/explain-trace.schema.json
2313
+
2314
+ why-slots answered (Markdown sections; JSON keys in parens):
2315
+
2316
+ inputs \u2014 profile / preset / rule_loading_tier with per-knob source
2317
+ (pack | profile | preset | user | env | runtime |
2318
+ default)
2319
+ route \u2014 matched tier-1 rules \xB7 kernel rules \xB7 active persona
2320
+ (route)
2321
+ memory \u2014 memory-MCP entries that influenced this run, with
2322
+ hit-score + step-id (memory)
2323
+ council \u2014 council members consulted with per-member verdict
2324
+ (council)
2325
+ assumptions \u2014 assumptions recorded during refine + per-halt
2326
+ (assumptions)
2327
+ pack \u2014 discovery-manifest pack selection rationale (pack)
2328
+ halt \u2014 reason \xB7 step \xB7 surface for the most recent halt
2329
+ (halt; Phase 3)
2330
+ provider \u2014 /video provider selection rationale; omitted for
2331
+ non-video runs (provider; Phase 3)
2332
+
2333
+ options:
2334
+ --project PATH project root (defaults to anchor walk from cwd)
2335
+ --state-file PATH .work-state.json path (default <root>/.work-state.json)
2336
+ --json emit ExplainTrace JSON instead of Markdown
2337
+ --quiet suppress the trailing tip footer
2338
+
2339
+ exit codes:
2340
+ 0 trace rendered, or disabled by settings (explain.enable_last)
2341
+ 1 no recent run found (state file missing or unreadable)
2342
+ 2 invocation error (bad project root, bad --state-file path)
2343
+ `;
2344
+ var PROG = "agent-config explain";
2345
+ var SUBJECT_CHOICES = ["config", "rule", "route", "last"];
2346
+ var USAGE = `usage: ${PROG} [-h] [--project PROJECT] [--state-file STATE_FILE]
2347
+ [--json] [--quiet]
2348
+ {config,rule,route,last} [target]
2349
+ `;
2350
+ function _argError(msg) {
2351
+ process2.stderr.write(USAGE);
2352
+ process2.stderr.write(`${PROG}: error: ${msg}
2353
+ `);
2354
+ throw new ArgparseExit(2);
2355
+ }
2356
+ function _parse(argv) {
2357
+ const opts = {
2358
+ subject: "",
2359
+ target: null,
2360
+ project: null,
2361
+ state_file: null,
2362
+ as_json: false,
2363
+ quiet: false
2364
+ };
2365
+ const positionals = [];
2366
+ let i = 0;
2367
+ while (i < argv.length) {
2368
+ const a = argv[i];
2369
+ if (a === "-h" || a === "--help") {
2370
+ process2.stdout.write(USAGE);
2371
+ throw new ArgparseExit(0);
2372
+ }
2373
+ const eq = a.startsWith("--") ? a.indexOf("=") : -1;
2374
+ const flag = eq >= 0 ? a.slice(0, eq) : a;
2375
+ const inlineVal = eq >= 0 ? a.slice(eq + 1) : null;
2376
+ if (flag === "--json") {
2377
+ if (inlineVal !== null) {
2378
+ _argError(`argument --json: ignored explicit argument '${inlineVal}'`);
2379
+ }
2380
+ opts.as_json = true;
2381
+ i += 1;
2382
+ continue;
2383
+ }
2384
+ if (flag === "--quiet") {
2385
+ if (inlineVal !== null) {
2386
+ _argError(`argument --quiet: ignored explicit argument '${inlineVal}'`);
2387
+ }
2388
+ opts.quiet = true;
2389
+ i += 1;
2390
+ continue;
2391
+ }
2392
+ if (flag === "--project" || flag === "--state-file") {
2393
+ const dest = flag === "--project" ? "project" : "state_file";
2394
+ let value;
2395
+ if (inlineVal !== null) {
2396
+ value = inlineVal;
2397
+ } else {
2398
+ if (i + 1 >= argv.length) {
2399
+ _argError(`argument ${flag}: expected one argument`);
2400
+ }
2401
+ value = argv[i + 1];
2402
+ i += 1;
2403
+ }
2404
+ opts[dest] = value;
2405
+ i += 1;
2406
+ continue;
2407
+ }
2408
+ if (a.startsWith("-") && a !== "-") {
2409
+ _argError(`unrecognized arguments: ${a}`);
2410
+ }
2411
+ positionals.push(a);
2412
+ i += 1;
2413
+ }
2414
+ if (positionals.length === 0) {
2415
+ _argError("the following arguments are required: subject");
2416
+ }
2417
+ const subject = positionals[0];
2418
+ if (!SUBJECT_CHOICES.includes(subject)) {
2419
+ _argError(
2420
+ `argument subject: invalid choice: '${subject}' (choose from ${SUBJECT_CHOICES.map((c) => `'${c}'`).join(", ")})`
2421
+ );
2422
+ }
2423
+ opts.subject = subject;
2424
+ if (positionals.length >= 2) {
2425
+ opts.target = positionals[1];
2426
+ }
2427
+ if (positionals.length > 2) {
2428
+ _argError(`unrecognized arguments: ${positionals.slice(2).join(" ")}`);
2429
+ }
2430
+ return opts;
2431
+ }
2432
+ function main(argv = null) {
2433
+ const argv_list = argv !== null ? Array.from(argv) : process2.argv.slice(2);
2434
+ if (argv_list.slice(0, 1).length === 1 && argv_list[0] === "last" && argv_list.slice(1).some((a) => a === "-h" || a === "--help")) {
2435
+ process2.stdout.write(_LAST_HELP);
2436
+ return 0;
2437
+ }
2438
+ const opts = _parse(argv_list);
2439
+ let project_root;
2440
+ try {
2441
+ [project_root] = _resolve_root(opts.project);
2442
+ } catch (exc) {
2443
+ if (exc instanceof SystemExitError) {
2444
+ return exc.code;
2445
+ }
2446
+ throw exc;
2447
+ }
2448
+ if (opts.subject === "config") {
2449
+ return _explain_config(project_root, opts.as_json);
2450
+ }
2451
+ if (opts.subject === "last") {
2452
+ const state_path = opts.state_file ? opts.state_file : null;
2453
+ return _explain_last(project_root, state_path, opts.as_json, opts.quiet);
2454
+ }
2455
+ if (opts.target === null) {
2456
+ eprint(`\u274C explain: '${opts.subject}' requires a target argument`);
2457
+ return 2;
2458
+ }
2459
+ if (opts.subject === "rule") {
2460
+ return _explain_rule(project_root, opts.target, opts.as_json);
2461
+ }
2462
+ return _explain_route(project_root, opts.target, opts.as_json);
2463
+ }
2464
+ function _isCliEntry() {
2465
+ if (process2.argv[1] === void 0) {
2466
+ return false;
2467
+ }
2468
+ const argvUrl = pathToFileURL(path7.resolve(process2.argv[1])).href;
2469
+ if (import.meta.url === argvUrl) {
2470
+ return true;
2471
+ }
2472
+ try {
2473
+ const here = fs8.realpathSync(fileURLToPath(import.meta.url));
2474
+ const argv = fs8.realpathSync(path7.resolve(process2.argv[1]));
2475
+ return here === argv;
2476
+ } catch {
2477
+ return false;
2478
+ }
2479
+ }
2480
+ if (_isCliEntry() || process2.argv[1] === _HERE) {
2481
+ try {
2482
+ process2.exitCode = main(process2.argv.slice(2));
2483
+ } catch (e) {
2484
+ if (e instanceof ArgparseExit) {
2485
+ process2.exitCode = e.code;
2486
+ } else if (e instanceof SystemExitError) {
2487
+ process2.exitCode = e.code;
2488
+ } else {
2489
+ throw e;
2490
+ }
2491
+ }
2492
+ }
2493
+ export {
2494
+ ArgparseExit,
2495
+ SystemExitError,
2496
+ _LAST_HELP,
2497
+ _explain_config,
2498
+ _explain_last,
2499
+ _explain_route,
2500
+ _explain_rule,
2501
+ _find_rule,
2502
+ _load_router2 as _load_router,
2503
+ _load_user_settings,
2504
+ _matches_trigger,
2505
+ _parse,
2506
+ _resolve_root,
2507
+ main
2508
+ };