@event4u/agent-config 8.12.0 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (284) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +164 -0
  3. package/README.md +1 -1
  4. package/dist/agent-src/commands/agent-handoff.md +35 -0
  5. package/dist/agent-src/commands/agents/init.md +1 -0
  6. package/dist/agent-src/commands/agents/optimize.md +1 -0
  7. package/dist/agent-src/commands/agents/user/accept.md +3 -2
  8. package/dist/agent-src/commands/agents/user/init.md +5 -4
  9. package/dist/agent-src/commands/agents/user/update.md +3 -2
  10. package/dist/agent-src/commands/agents/user.md +1 -0
  11. package/dist/agent-src/commands/agents.md +1 -0
  12. package/dist/agent-src/commands/analytics/show.md +1 -0
  13. package/dist/agent-src/commands/analytics.md +1 -0
  14. package/dist/agent-src/commands/analyze/decision.md +1 -0
  15. package/dist/agent-src/commands/analyze/incident.md +1 -0
  16. package/dist/agent-src/commands/analyze/near-miss.md +1 -0
  17. package/dist/agent-src/commands/analyze/postmortem.md +1 -0
  18. package/dist/agent-src/commands/analyze/premortem.md +1 -0
  19. package/dist/agent-src/commands/analyze/reference-repo.md +1 -0
  20. package/dist/agent-src/commands/analyze.md +3 -2
  21. package/dist/agent-src/commands/brand/identity.md +6 -5
  22. package/dist/agent-src/commands/brand/review.md +6 -5
  23. package/dist/agent-src/commands/brand/strategy.md +6 -4
  24. package/dist/agent-src/commands/brand/tokens.md +7 -6
  25. package/dist/agent-src/commands/brand/voice.md +5 -4
  26. package/dist/agent-src/commands/brand.md +9 -7
  27. package/dist/agent-src/commands/bug/fix.md +1 -0
  28. package/dist/agent-src/commands/bug/investigate.md +1 -0
  29. package/dist/agent-src/commands/bug.md +2 -1
  30. package/dist/agent-src/commands/challenge-me/vision.md +1 -0
  31. package/dist/agent-src/commands/challenge-me/with-docs.md +1 -0
  32. package/dist/agent-src/commands/challenge-me.md +28 -6
  33. package/dist/agent-src/commands/chat-history.md +1 -0
  34. package/dist/agent-src/commands/check-current-md.md +1 -0
  35. package/dist/agent-src/commands/commit.md +1 -0
  36. package/dist/agent-src/commands/context/create.md +3 -2
  37. package/dist/agent-src/commands/context.md +1 -0
  38. package/dist/agent-src/commands/cost/profile.md +1 -0
  39. package/dist/agent-src/commands/cost.md +2 -1
  40. package/dist/agent-src/commands/council/analysis.md +1 -0
  41. package/dist/agent-src/commands/council/debate.md +1 -0
  42. package/dist/agent-src/commands/council/default.md +21 -20
  43. package/dist/agent-src/commands/council/design.md +1 -0
  44. package/dist/agent-src/commands/council/optimize.md +1 -0
  45. package/dist/agent-src/commands/council/pr.md +1 -0
  46. package/dist/agent-src/commands/council.md +1 -0
  47. package/dist/agent-src/commands/estimate-ticket.md +1 -0
  48. package/dist/agent-src/commands/feature/dev.md +1 -0
  49. package/dist/agent-src/commands/feature/explore.md +1 -0
  50. package/dist/agent-src/commands/feature/plan.md +1 -0
  51. package/dist/agent-src/commands/feature/refactor.md +1 -0
  52. package/dist/agent-src/commands/feature/roadmap.md +1 -0
  53. package/dist/agent-src/commands/feature.md +2 -1
  54. package/dist/agent-src/commands/fix/pr-comments.md +19 -0
  55. package/dist/agent-src/commands/fix.md +2 -1
  56. package/dist/agent-src/commands/ghostwriter/delete.md +1 -0
  57. package/dist/agent-src/commands/ghostwriter/fetch.md +1 -0
  58. package/dist/agent-src/commands/ghostwriter/show.md +1 -0
  59. package/dist/agent-src/commands/ghostwriter/write.md +1 -0
  60. package/dist/agent-src/commands/ghostwriter.md +1 -0
  61. package/dist/agent-src/commands/grill-me.md +17 -12
  62. package/dist/agent-src/commands/humanize.md +1 -0
  63. package/dist/agent-src/commands/image/analyse.md +2 -1
  64. package/dist/agent-src/commands/image/create.md +1 -0
  65. package/dist/agent-src/commands/image/verify.md +1 -0
  66. package/dist/agent-src/commands/image.md +16 -12
  67. package/dist/agent-src/commands/implement-ticket.md +1 -0
  68. package/dist/agent-src/commands/judge/on-diff.md +1 -0
  69. package/dist/agent-src/commands/judge/solo.md +1 -0
  70. package/dist/agent-src/commands/judge/steps.md +1 -0
  71. package/dist/agent-src/commands/judge.md +1 -0
  72. package/dist/agent-src/commands/knowledge/cross-repo.md +1 -0
  73. package/dist/agent-src/commands/knowledge/forget.md +1 -0
  74. package/dist/agent-src/commands/knowledge/ingest.md +1 -0
  75. package/dist/agent-src/commands/knowledge/list.md +10 -0
  76. package/dist/agent-src/commands/knowledge.md +1 -0
  77. package/dist/agent-src/commands/memory/learn-low-impact.md +1 -0
  78. package/dist/agent-src/commands/memory/mine-session.md +1 -0
  79. package/dist/agent-src/commands/memory/promote.md +3 -2
  80. package/dist/agent-src/commands/memory.md +1 -0
  81. package/dist/agent-src/commands/mission/upgrade.md +45 -24
  82. package/dist/agent-src/commands/mode.md +1 -0
  83. package/dist/agent-src/commands/module/create.md +1 -0
  84. package/dist/agent-src/commands/module/explore.md +1 -0
  85. package/dist/agent-src/commands/module.md +1 -0
  86. package/dist/agent-src/commands/optimize/agents-dir.md +1 -0
  87. package/dist/agent-src/commands/optimize/project.md +1 -0
  88. package/dist/agent-src/commands/optimize/prompt.md +1 -0
  89. package/dist/agent-src/commands/optimize.md +2 -1
  90. package/dist/agent-src/commands/orchestrate.md +1 -0
  91. package/dist/agent-src/commands/override.md +1 -0
  92. package/dist/agent-src/commands/package.md +2 -1
  93. package/dist/agent-src/commands/post-as/ghostwriter.md +1 -0
  94. package/dist/agent-src/commands/post-as/me.md +1 -0
  95. package/dist/agent-src/commands/post-as.md +1 -0
  96. package/dist/agent-src/commands/pr/create/description-only.md +1 -0
  97. package/dist/agent-src/commands/pr/create.md +28 -0
  98. package/dist/agent-src/commands/prediction-pool.md +7 -6
  99. package/dist/agent-src/commands/prepare-for-review.md +1 -0
  100. package/dist/agent-src/commands/profile/activate.md +1 -0
  101. package/dist/agent-src/commands/profile/deactivate.md +1 -0
  102. package/dist/agent-src/commands/profile.md +1 -0
  103. package/dist/agent-src/commands/project.md +2 -1
  104. package/dist/agent-src/commands/refine-ticket.md +7 -0
  105. package/dist/agent-src/commands/research/deep.md +1 -0
  106. package/dist/agent-src/commands/research.md +1 -0
  107. package/dist/agent-src/commands/review/routing.md +1 -0
  108. package/dist/agent-src/commands/review.md +2 -1
  109. package/dist/agent-src/commands/roadmap/ai-council.md +1 -0
  110. package/dist/agent-src/commands/roadmap/materialize.md +1 -0
  111. package/dist/agent-src/commands/roadmap/process-full.md +1 -0
  112. package/dist/agent-src/commands/roadmap/process-phase.md +1 -0
  113. package/dist/agent-src/commands/roadmap/process-step.md +1 -0
  114. package/dist/agent-src/commands/roadmap.md +1 -0
  115. package/dist/agent-src/commands/security-audit-config.md +2 -1
  116. package/dist/agent-src/commands/skill/preview.md +1 -0
  117. package/dist/agent-src/commands/skill.md +1 -0
  118. package/dist/agent-src/commands/skills/discover.md +1 -0
  119. package/dist/agent-src/commands/skills.md +1 -0
  120. package/dist/agent-src/commands/sync/agent-settings.md +1 -0
  121. package/dist/agent-src/commands/sync.md +2 -1
  122. package/dist/agent-src/commands/team/adversarial.md +97 -0
  123. package/dist/agent-src/commands/team/delegate.md +110 -0
  124. package/dist/agent-src/commands/team/review.md +85 -0
  125. package/dist/agent-src/commands/team/status.md +123 -0
  126. package/dist/agent-src/commands/team-knowledge.md +8 -6
  127. package/dist/agent-src/commands/team.md +152 -0
  128. package/dist/agent-src/commands/tests/e2e-heal.md +1 -0
  129. package/dist/agent-src/commands/tests/e2e-plan.md +1 -0
  130. package/dist/agent-src/commands/tests/execute.md +1 -0
  131. package/dist/agent-src/commands/tests.md +2 -1
  132. package/dist/agent-src/commands/update-form-request-messages.md +1 -0
  133. package/dist/agent-src/commands/upstream-contribute.md +1 -0
  134. package/dist/agent-src/commands/video/from-script.md +3 -2
  135. package/dist/agent-src/commands/video/from-song.md +22 -21
  136. package/dist/agent-src/commands/video/scene.md +1 -0
  137. package/dist/agent-src/commands/video/stitch.md +2 -1
  138. package/dist/agent-src/commands/video/storyboard.md +1 -0
  139. package/dist/agent-src/commands/video.md +1 -0
  140. package/dist/agent-src/commands/work.md +1 -0
  141. package/dist/agent-src/commands/worktree/cleanup.md +8 -7
  142. package/dist/agent-src/commands/worktree/create.md +1 -0
  143. package/dist/agent-src/commands/worktree/verify.md +1 -0
  144. package/dist/agent-src/commands/worktree.md +1 -0
  145. package/dist/agent-src/rules/active-remediation.md +12 -36
  146. package/dist/agent-src/rules/artifact-drafting-protocol.md +7 -64
  147. package/dist/agent-src/rules/context-hygiene.md +19 -113
  148. package/dist/agent-src/rules/design-fidelity.md +4 -60
  149. package/dist/agent-src/rules/domain-adoption-policy.md +10 -106
  150. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +12 -60
  151. package/dist/agent-src/rules/improve-before-implement.md +6 -0
  152. package/dist/agent-src/rules/minimal-safe-diff.md +6 -86
  153. package/dist/agent-src/rules/size-enforcement.md +10 -0
  154. package/dist/agent-src/rules/tool-safety.md +17 -3
  155. package/dist/agent-src/skills/agent-security-review/SKILL.md +12 -1
  156. package/dist/agent-src/skills/ai-council/SKILL.md +11 -0
  157. package/dist/agent-src/skills/bug-analyzer/SKILL.md +24 -2
  158. package/dist/agent-src/skills/code-review/SKILL.md +105 -93
  159. package/dist/agent-src/skills/code-review/checklists/backend.md +50 -0
  160. package/dist/agent-src/skills/code-review/checklists/database.md +19 -0
  161. package/dist/agent-src/skills/code-review/checklists/dependency.md +18 -0
  162. package/dist/agent-src/skills/code-review/checklists/docs.md +14 -0
  163. package/dist/agent-src/skills/code-review/checklists/frontend.md +19 -0
  164. package/dist/agent-src/skills/code-review/checklists/infra.md +17 -0
  165. package/dist/agent-src/skills/code-review/checklists/producing-the-review.md +62 -0
  166. package/dist/agent-src/skills/code-review/checklists/test-only.md +13 -0
  167. package/dist/agent-src/skills/code-review/evals/evals.json +53 -15
  168. package/dist/agent-src/skills/condense-memory/SKILL.md +3 -2
  169. package/dist/agent-src/skills/conventional-commits-writing/evals/evals.json +15 -0
  170. package/dist/agent-src/skills/docker/SKILL.md +10 -0
  171. package/dist/agent-src/skills/docx-authoring/SKILL.md +102 -0
  172. package/dist/agent-src/skills/github-ci/evals/evals.json +25 -0
  173. package/dist/agent-src/skills/humanizer/SKILL.md +79 -3
  174. package/dist/agent-src/skills/humanizer/references/anti-aiisms.md +112 -0
  175. package/dist/agent-src/skills/humanizer/references/fixtures.md +70 -0
  176. package/dist/agent-src/skills/judge-bug-hunter/SKILL.md +7 -1
  177. package/dist/agent-src/skills/laravel/SKILL.md +10 -0
  178. package/dist/agent-src/skills/launch-readiness/SKILL.md +35 -0
  179. package/dist/agent-src/skills/merge-conflicts/SKILL.md +30 -0
  180. package/dist/agent-src/skills/pdf-tools/SKILL.md +101 -0
  181. package/dist/agent-src/skills/quality-tools/evals/evals.json +15 -0
  182. package/dist/agent-src/skills/security-audit/SKILL.md +29 -0
  183. package/dist/agent-src/skills/security-maturity-assessment/SKILL.md +90 -0
  184. package/dist/agent-src/skills/security-maturity-assessment/evals/triggers.json +52 -0
  185. package/dist/agent-src/skills/skill-writing/SKILL.md +79 -0
  186. package/dist/agent-src/skills/spreadsheet-authoring/SKILL.md +11 -3
  187. package/dist/agent-src/skills/subagent-orchestration/schemas/team-review-status.json +103 -0
  188. package/dist/agent-src/skills/terraform/SKILL.md +10 -0
  189. package/dist/agent-src/skills/test-driven-development/SKILL.md +31 -0
  190. package/dist/agent-src/skills/threat-modeling/SKILL.md +15 -0
  191. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  192. package/dist/agent-src/templates/scripts/telemetry/aggregator.ts +0 -0
  193. package/dist/agent-src/templates/scripts/telemetry/engagement.ts +30 -0
  194. package/dist/agent-src/templates/scripts/telemetry/report_renderer.ts +22 -9
  195. package/dist/agent-src/templates/scripts/telemetry_record.ts +5 -0
  196. package/dist/discovery/deprecation-report.md +1 -1
  197. package/dist/discovery/discovery-manifest.json +378 -174
  198. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  199. package/dist/discovery/discovery-manifest.summary.md +4 -4
  200. package/dist/discovery/orphan-report.md +1 -1
  201. package/dist/discovery/packs.json +16 -8
  202. package/dist/discovery/trust-report.md +3 -3
  203. package/dist/discovery/workspaces.json +14 -6
  204. package/dist/install/install.mjs +46 -0
  205. package/dist/mcp/registry-manifest.json +3 -3
  206. package/dist/router.json +1 -1
  207. package/dist/scripts/condense.js +5 -0
  208. package/dist/scripts/condense.js.map +1 -1
  209. package/dist/server/schemas/settings.js +11 -0
  210. package/dist/server/schemas/settings.js.map +1 -1
  211. package/docs/CLAIMS.md +9 -2
  212. package/docs/SKILL_CENSUS.md +8 -0
  213. package/docs/architecture.md +3 -3
  214. package/docs/benchmark.md +67 -2
  215. package/docs/catalog.md +10 -4
  216. package/docs/command-flows.md +6 -1
  217. package/docs/contracts/ai-council-config.md +9 -2
  218. package/docs/contracts/ai-team-config.md +224 -0
  219. package/docs/contracts/command-clusters.md +1 -0
  220. package/docs/contracts/prelaunch-diagnostics.md +151 -0
  221. package/docs/contracts/release-pr-gating.md +1 -0
  222. package/docs/decisions/ADR-049-configuration-trust-boundary.md +9 -1
  223. package/docs/featured-skills.md +2 -2
  224. package/docs/getting-started-by-role.md +3 -1
  225. package/docs/getting-started.md +42 -1
  226. package/docs/governance-advantage.md +1 -1
  227. package/docs/guidelines/agent-infra/active-remediation-mechanics.md +45 -0
  228. package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +28 -0
  229. package/docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +76 -0
  230. package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +90 -0
  231. package/docs/guidelines/agent-infra/domain-adoption-gates.md +112 -0
  232. package/docs/guidelines/agent-infra/framework-neutrality-patterns.md +66 -0
  233. package/docs/guidelines/agent-infra/minimal-safe-diff-mechanics.md +99 -0
  234. package/docs/guidelines/agent-infra/skill-quality-checklist.md +13 -0
  235. package/docs/guidelines/design-fidelity-mechanics.md +76 -0
  236. package/docs/maintainers/branch-protection.md +18 -0
  237. package/docs/parity/command-frontmatter.md +60 -0
  238. package/docs/proof.md +7 -6
  239. package/package.json +1 -1
  240. package/src/agent-src/templates/scripts/telemetry/aggregator.ts +0 -0
  241. package/src/agent-src/templates/scripts/telemetry/engagement.ts +30 -0
  242. package/src/agent-src/templates/scripts/telemetry/report_renderer.ts +22 -9
  243. package/src/agent-src/templates/scripts/telemetry_record.ts +5 -0
  244. package/src/config/agent-settings.template.yml +71 -7
  245. package/src/config/prelaunch-areas.yml +36 -0
  246. package/src/scripts/_cli/cmd_doctor.ts +288 -1
  247. package/src/scripts/_lib/claude_plugin.ts +114 -4
  248. package/src/scripts/_lib/orchestration_record.ts +5 -0
  249. package/src/scripts/_lib/tool_adapter_registry.ts +120 -0
  250. package/src/scripts/ai_team/config.ts +234 -0
  251. package/src/scripts/ai_team/review_gate.ts +636 -0
  252. package/src/scripts/ai_team/team_dispatch.ts +612 -0
  253. package/src/scripts/bench_ab_task_runner.ts +11 -1
  254. package/src/scripts/bench_parity_count.ts +279 -0
  255. package/src/scripts/build_linear_digest.ts +3 -1
  256. package/src/scripts/check_bridge_derivation.ts +172 -0
  257. package/src/scripts/check_consumer_scope_flip.ts +179 -0
  258. package/src/scripts/check_council_config_location.ts +115 -15
  259. package/src/scripts/check_host_loadability.ts +81 -0
  260. package/src/scripts/condense.ts +5 -0
  261. package/src/scripts/hook_manifest.yaml +12 -1
  262. package/src/scripts/install.ts +39 -0
  263. package/src/scripts/lint_handoffs.ts +42 -0
  264. package/src/scripts/lint_skill_descriptions.ts +228 -0
  265. package/src/scripts/lint_skill_descriptions_allowlist.json +1 -0
  266. package/src/scripts/lint_skill_scripts_readonly.ts +145 -0
  267. package/src/scripts/lint_skill_scripts_readonly_allowlist.json +8 -0
  268. package/src/scripts/lint_supported_tools_matrix.ts +35 -0
  269. package/src/scripts/optimize_skill_description.ts +144 -0
  270. package/src/scripts/orchestration_record.ts +2 -1
  271. package/src/scripts/prelaunch_diagnostics.ts +248 -0
  272. package/src/scripts/rule_backlinks.ts +0 -0
  273. package/src/scripts/run_skill_evals.ts +70 -4
  274. package/src/scripts/schemas/command.schema.json +7 -0
  275. package/src/scripts/schemas/evals.schema.json +105 -14
  276. package/src/scripts/schemas/prelaunch-report.schema.json +107 -0
  277. package/src/scripts/schemas/skill.schema.json +18 -1
  278. package/src/scripts/schemas/subagent.schema.json +6 -0
  279. package/src/scripts/skill_linter.ts +43 -3
  280. package/src/scripts/smoke_host_loadability.sh +73 -0
  281. package/src/scripts/team_review_gate_hook.ts +115 -0
  282. package/src/scripts/trigger_eval_grandfather.json +1 -2
  283. package/src/scripts/utilization_report.ts +225 -0
  284. package/src/server/schemas/settings.ts +25 -0
@@ -0,0 +1,234 @@
1
+ /**
2
+ * ai_team configuration loader — single source of truth for the `/team`
3
+ * cross-model review family.
4
+ *
5
+ * Mirrors the fail-closed validation posture of the council loader
6
+ * (`src/scripts/ai_council/config.ts`) at a fraction of its surface: the
7
+ * `ai_team` block has five flat keys and no nested sub-schemas, so this
8
+ * loader is deliberately lean — defaults, per-key type checks, and hard
9
+ * unknown-key rejection. Contract: `docs/contracts/ai-team-config.md`.
10
+ *
11
+ * Unlike the council (ALWAYS user-global `.ai-council.yml`, ADR-104),
12
+ * `ai_team` lives in the PROJECT settings cascade (`.agent-settings.yml`
13
+ * via `load_agent_settings`) — team mode is a per-project posture
14
+ * (default-off), not a per-developer credential store; the codex CLI
15
+ * carries the subscription auth itself.
16
+ *
17
+ * Validation contract (all enforced at load time, fail-closed):
18
+ *
19
+ * 1. `ai_team` absent → defaults (feature off). Non-mapping → error.
20
+ * 2. Unknown keys under `ai_team` are rejected — a typo must never
21
+ * silently disable a gate (`allow_delegate` misspelled = delegation
22
+ * stays off AND the load fails loudly).
23
+ * 3. `enabled`, `allow_delegate`, `suppress_setup_hint` are booleans.
24
+ * 4. `model` is a non-empty string. `'auto'` = pass no `--model` flag
25
+ * (the codex CLI default applies); any other value passes through
26
+ * verbatim.
27
+ * 5. `max_calls_per_day` is a non-negative integer (bools rejected).
28
+ * 6. `review_gate` is a nested mapping with the same fail-closed posture:
29
+ * unknown keys inside it are rejected, `managed` is a boolean
30
+ * (default `false` = byte-identical pre-Phase-4 behavior), and
31
+ * `max_consecutive_blocks` is a POSITIVE integer (a loop bound of 0
32
+ * would mean "always tripped" — reject it, don't reinterpret it).
33
+ */
34
+ import { load_agent_settings, type SettingsDict } from '../_lib/agent_settings.js';
35
+
36
+ /** Raised when the `ai_team` block of `.agent-settings.yml` violates the schema. */
37
+ export class TeamConfigError extends Error {
38
+ constructor(message: string) {
39
+ super(message);
40
+ this.name = 'TeamConfigError';
41
+ }
42
+ }
43
+
44
+ export interface AiTeamReviewGateConfig {
45
+ readonly managed: boolean;
46
+ readonly max_consecutive_blocks: number;
47
+ }
48
+
49
+ export interface AiTeamConfig {
50
+ readonly enabled: boolean;
51
+ readonly model: string;
52
+ readonly allow_delegate: boolean;
53
+ readonly max_calls_per_day: number;
54
+ readonly suppress_setup_hint: boolean;
55
+ readonly review_gate: AiTeamReviewGateConfig;
56
+ }
57
+
58
+ /** Shipped `review_gate` defaults — `managed: false` = pre-Phase-4 behavior. */
59
+ export const AI_TEAM_REVIEW_GATE_DEFAULTS: AiTeamReviewGateConfig = Object.freeze({
60
+ managed: false,
61
+ max_consecutive_blocks: 3,
62
+ });
63
+
64
+ /** Shipped defaults — byte-parity with `src/config/agent-settings.template.yml`. */
65
+ export const AI_TEAM_DEFAULTS: AiTeamConfig = Object.freeze({
66
+ enabled: false,
67
+ model: 'auto',
68
+ allow_delegate: false,
69
+ max_calls_per_day: 50,
70
+ suppress_setup_hint: false,
71
+ review_gate: AI_TEAM_REVIEW_GATE_DEFAULTS,
72
+ });
73
+
74
+ /**
75
+ * Sentinel: `model: 'auto'` means "pass NO --model flag" so the codex
76
+ * CLI's own default applies (tracks the subscription's strongest model
77
+ * instead of pinning a stale ID).
78
+ */
79
+ export const AI_TEAM_MODEL_AUTO = 'auto';
80
+
81
+ const _KNOWN_KEYS: ReadonlySet<string> = new Set([
82
+ 'enabled',
83
+ 'model',
84
+ 'allow_delegate',
85
+ 'max_calls_per_day',
86
+ 'suppress_setup_hint',
87
+ 'review_gate',
88
+ ]);
89
+
90
+ const _KNOWN_REVIEW_GATE_KEYS: ReadonlySet<string> = new Set([
91
+ 'managed',
92
+ 'max_consecutive_blocks',
93
+ ]);
94
+
95
+ function _isDict(value: unknown): value is Record<string, unknown> {
96
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
97
+ }
98
+
99
+ function _isBool(value: unknown): value is boolean {
100
+ return typeof value === 'boolean';
101
+ }
102
+
103
+ function _requireBool(raw: Record<string, unknown>, key: string, fallback: boolean): boolean {
104
+ if (!(key in raw)) {
105
+ return fallback;
106
+ }
107
+ const value = raw[key];
108
+ if (!_isBool(value)) {
109
+ throw new TeamConfigError(
110
+ `\`ai_team.${key}\` must be a boolean (got ${JSON.stringify(value)}).`,
111
+ );
112
+ }
113
+ return value;
114
+ }
115
+
116
+ /**
117
+ * Validate the nested `ai_team.review_gate` mapping (fail-closed, same
118
+ * posture as the parent block). Absent / null → shipped defaults.
119
+ */
120
+ function _build_review_gate(raw: unknown): AiTeamReviewGateConfig {
121
+ if (raw === null || raw === undefined) {
122
+ return AI_TEAM_REVIEW_GATE_DEFAULTS;
123
+ }
124
+ if (!_isDict(raw)) {
125
+ throw new TeamConfigError('`ai_team.review_gate` must be a mapping.');
126
+ }
127
+ for (const key of Object.keys(raw)) {
128
+ if (!_KNOWN_REVIEW_GATE_KEYS.has(key)) {
129
+ throw new TeamConfigError(
130
+ `ai_team.review_gate.${key}: unknown key; valid: ` +
131
+ `[${[..._KNOWN_REVIEW_GATE_KEYS].map((k) => `'${k}'`).join(', ')}].`,
132
+ );
133
+ }
134
+ }
135
+
136
+ let managed = AI_TEAM_REVIEW_GATE_DEFAULTS.managed;
137
+ if ('managed' in raw) {
138
+ const value = raw['managed'];
139
+ if (!_isBool(value)) {
140
+ throw new TeamConfigError(
141
+ `\`ai_team.review_gate.managed\` must be a boolean (got ${JSON.stringify(value)}).`,
142
+ );
143
+ }
144
+ managed = value;
145
+ }
146
+
147
+ let max_consecutive_blocks = AI_TEAM_REVIEW_GATE_DEFAULTS.max_consecutive_blocks;
148
+ if ('max_consecutive_blocks' in raw) {
149
+ const value = raw['max_consecutive_blocks'];
150
+ if (_isBool(value) || typeof value !== 'number' || !Number.isInteger(value) || value < 1) {
151
+ throw new TeamConfigError(
152
+ '`ai_team.review_gate.max_consecutive_blocks` must be a positive integer ' +
153
+ `(got ${JSON.stringify(value)}).`,
154
+ );
155
+ }
156
+ max_consecutive_blocks = value;
157
+ }
158
+
159
+ return { managed, max_consecutive_blocks };
160
+ }
161
+
162
+ /**
163
+ * Validate a raw `ai_team` mapping and return the typed config.
164
+ *
165
+ * `raw = null | undefined` (block absent) returns the defaults — the
166
+ * feature is off, never an error. Every other shape is validated
167
+ * fail-closed per the module contract above.
168
+ */
169
+ export function build_ai_team_config(raw: unknown): AiTeamConfig {
170
+ if (raw === null || raw === undefined) {
171
+ return AI_TEAM_DEFAULTS;
172
+ }
173
+ if (!_isDict(raw)) {
174
+ throw new TeamConfigError('`ai_team` must be a mapping.');
175
+ }
176
+
177
+ for (const key of Object.keys(raw)) {
178
+ if (!_KNOWN_KEYS.has(key)) {
179
+ throw new TeamConfigError(
180
+ `ai_team.${key}: unknown key; valid: ` +
181
+ `[${[..._KNOWN_KEYS].map((k) => `'${k}'`).join(', ')}].`,
182
+ );
183
+ }
184
+ }
185
+
186
+ const enabled = _requireBool(raw, 'enabled', AI_TEAM_DEFAULTS.enabled);
187
+ const allow_delegate = _requireBool(raw, 'allow_delegate', AI_TEAM_DEFAULTS.allow_delegate);
188
+ const suppress_setup_hint = _requireBool(
189
+ raw,
190
+ 'suppress_setup_hint',
191
+ AI_TEAM_DEFAULTS.suppress_setup_hint,
192
+ );
193
+
194
+ let model = AI_TEAM_DEFAULTS.model;
195
+ if ('model' in raw) {
196
+ const value = raw['model'];
197
+ if (typeof value !== 'string' || value.trim() === '') {
198
+ throw new TeamConfigError(
199
+ `\`ai_team.model\` must be a non-empty string (got ${JSON.stringify(value)}).`,
200
+ );
201
+ }
202
+ model = value;
203
+ }
204
+
205
+ let max_calls_per_day = AI_TEAM_DEFAULTS.max_calls_per_day;
206
+ if ('max_calls_per_day' in raw) {
207
+ const value = raw['max_calls_per_day'];
208
+ if (_isBool(value) || typeof value !== 'number' || !Number.isInteger(value) || value < 0) {
209
+ throw new TeamConfigError(
210
+ '`ai_team.max_calls_per_day` must be a non-negative integer ' +
211
+ `(got ${JSON.stringify(value)}).`,
212
+ );
213
+ }
214
+ max_calls_per_day = value;
215
+ }
216
+
217
+ const review_gate = _build_review_gate('review_gate' in raw ? raw['review_gate'] : undefined);
218
+
219
+ return { enabled, model, allow_delegate, max_calls_per_day, suppress_setup_hint, review_gate };
220
+ }
221
+
222
+ /**
223
+ * Load the `ai_team` config from the merged project settings cascade.
224
+ *
225
+ * `opts.settings` injects a pre-merged settings dict (test seam — no
226
+ * filesystem access); otherwise `load_agent_settings` walks the normal
227
+ * `.agent-settings.yml` cascade from `opts.cwd` (default: process cwd).
228
+ */
229
+ export function load_ai_team_config(
230
+ opts: { settings?: SettingsDict | null; cwd?: string | null } = {},
231
+ ): AiTeamConfig {
232
+ const settings = opts.settings ?? load_agent_settings({ cwd: opts.cwd ?? process.cwd() });
233
+ return build_ai_team_config((settings as Record<string, unknown>)['ai_team']);
234
+ }