pi-crew 0.9.68 → 0.10.2

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 (253) hide show
  1. package/CHANGELOG.md +222 -0
  2. package/NOTICE.md +21 -0
  3. package/README.md +44 -2
  4. package/agents/analyst.md +1 -1
  5. package/agents/cold-verifier.md +3 -1
  6. package/agents/critic.md +1 -1
  7. package/agents/executor.md +1 -1
  8. package/agents/explorer.md +1 -1
  9. package/agents/planner.md +1 -1
  10. package/agents/reviewer.md +1 -1
  11. package/agents/security-reviewer.md +1 -1
  12. package/agents/test-engineer.md +1 -1
  13. package/agents/verifier.md +1 -1
  14. package/agents/writer.md +1 -1
  15. package/dist/index.mjs +68113 -60774
  16. package/docs/README.md +2 -0
  17. package/docs/actions-reference.md +31 -0
  18. package/docs/commands-reference.md +17 -6
  19. package/docs/resource-formats.md +13 -0
  20. package/package.json +4 -2
  21. package/schema.json +503 -91
  22. package/scripts/resource-sampler.mjs +36 -2
  23. package/skills/requirements-to-task-packet/SKILL.md +26 -0
  24. package/skills/widget-rendering/SKILL.md +7 -7
  25. package/src/agents/agent-config.ts +2 -1
  26. package/src/agents/discover-agents.ts +23 -14
  27. package/src/config/config-merge.ts +183 -0
  28. package/src/config/config-validation.ts +687 -0
  29. package/src/config/config.ts +22 -864
  30. package/src/config/defaults.ts +43 -2
  31. package/src/config/drift-detector.ts +1 -1
  32. package/src/config/env-vars.ts +691 -0
  33. package/src/config/role-tools.ts +11 -9
  34. package/src/config/sanitize-project-config.ts +172 -0
  35. package/src/config/types.ts +49 -1
  36. package/src/extension/async-notifier.ts +25 -2
  37. package/src/extension/crew-cleanup.ts +13 -0
  38. package/src/extension/crew-vibes/config.ts +2 -1
  39. package/src/extension/crew-vibes/footer.ts +19 -0
  40. package/src/extension/crew-vibes/index.ts +11 -1
  41. package/src/extension/plan-orchestrate.ts +132 -0
  42. package/src/extension/register.ts +8 -0
  43. package/src/extension/registration/command-registration.ts +1 -0
  44. package/src/extension/registration/commands/dashboard.ts +158 -0
  45. package/src/extension/registration/commands/index.ts +35 -0
  46. package/src/extension/registration/commands/manage.ts +303 -0
  47. package/src/extension/registration/commands/run.ts +228 -0
  48. package/src/extension/registration/commands/shared.ts +639 -0
  49. package/src/extension/registration/commands/status.ts +60 -0
  50. package/src/extension/registration/commands.ts +13 -1224
  51. package/src/extension/registration/foreground-run-controller.ts +10 -2
  52. package/src/extension/registration/lifecycle-handlers.ts +178 -17
  53. package/src/extension/registration/runtime-cleanup.ts +23 -5
  54. package/src/extension/registration/subagent-tools.ts +218 -9
  55. package/src/extension/registration/team-tool.ts +5 -1
  56. package/src/extension/registration/ui.ts +5 -4
  57. package/src/extension/rpc-hmac.ts +5 -3
  58. package/src/extension/team-tool/api/heartbeat.ts +47 -10
  59. package/src/extension/team-tool/api/plan-approval.ts +9 -0
  60. package/src/extension/team-tool/api/task-claims.ts +109 -40
  61. package/src/extension/team-tool/cancel.ts +84 -50
  62. package/src/extension/team-tool/dispatch/index.ts +1 -0
  63. package/src/extension/team-tool/dispatch/run.ts +4 -1
  64. package/src/extension/team-tool/doctor.ts +103 -1
  65. package/src/extension/team-tool/orchestrate.ts +66 -1
  66. package/src/extension/team-tool/plans.ts +192 -0
  67. package/src/extension/team-tool/respond.ts +197 -65
  68. package/src/extension/team-tool/run-deadline.ts +35 -3
  69. package/src/extension/team-tool/run-intent.ts +63 -0
  70. package/src/extension/team-tool/run.ts +74 -20
  71. package/src/extension/team-tool/status.ts +84 -26
  72. package/src/extension/team-tool.ts +11 -2
  73. package/src/hooks/registry.ts +1 -6
  74. package/src/i18n.ts +9 -0
  75. package/src/prompt/prompt-runtime.ts +521 -2
  76. package/src/prompt/worker-events-channel.ts +173 -0
  77. package/src/runtime/README.md +8 -8
  78. package/src/runtime/async-runner.ts +7 -3
  79. package/src/runtime/background-runner.ts +42 -14
  80. package/src/runtime/broker/broker-issuer.ts +9 -2
  81. package/src/runtime/broker/crew-broker-tokens.ts +43 -6
  82. package/src/runtime/broker/crew-broker.ts +838 -10
  83. package/src/runtime/broker/wait-status-cache.ts +157 -0
  84. package/src/runtime/budget-enforcement.ts +281 -0
  85. package/src/runtime/child-pi/child-pi-constants.ts +8 -0
  86. package/src/runtime/child-pi/child-pi-spawn.ts +60 -14
  87. package/src/runtime/child-pi/child-pi-streams.ts +21 -1
  88. package/src/runtime/child-pi/child-pi-timers.ts +324 -0
  89. package/src/runtime/child-pi/child-pi.ts +97 -201
  90. package/src/runtime/child-pi/mock-fixtures.ts +16 -2
  91. package/src/runtime/crew-agent-records.ts +259 -14
  92. package/src/runtime/delegate-spawn.ts +148 -0
  93. package/src/runtime/detached-run-results.ts +90 -0
  94. package/src/runtime/deterministic-ast.ts +2 -1
  95. package/src/runtime/dispatch-batch.ts +945 -0
  96. package/src/runtime/finalize-run.ts +557 -0
  97. package/src/runtime/goal-workflow/adaptive-plan.ts +116 -15
  98. package/src/runtime/goal-workflow/dynamic-workflow-runner.ts +8 -3
  99. package/src/runtime/goal-workflow/goal-state-store.ts +1 -1
  100. package/src/runtime/group-join.ts +11 -125
  101. package/src/runtime/live-session/live-session-runtime.ts +26 -1
  102. package/src/runtime/merge-gate.ts +32 -10
  103. package/src/runtime/merge-loop.ts +130 -0
  104. package/src/runtime/model/model-budget-summary.ts +53 -0
  105. package/src/runtime/model/model-fallback.ts +36 -2
  106. package/src/runtime/model/pi-args.ts +10 -0
  107. package/src/runtime/model/provider-extensions.ts +10 -0
  108. package/src/runtime/orphan-worker-registry.ts +1 -1
  109. package/src/runtime/output/output-validator.ts +45 -0
  110. package/src/runtime/parent-guard.ts +3 -1
  111. package/src/runtime/peer-dep.ts +2 -1
  112. package/src/runtime/per-write-validator.ts +0 -5
  113. package/src/runtime/pi-spawn.ts +61 -15
  114. package/src/runtime/plan-approval.ts +125 -0
  115. package/src/runtime/plan-replan.ts +151 -0
  116. package/src/runtime/process-status.ts +16 -1
  117. package/src/runtime/recovery/checkpoint.ts +0 -18
  118. package/src/runtime/recovery/crash-recovery.ts +111 -46
  119. package/src/runtime/run-tracker.ts +77 -10
  120. package/src/runtime/scheduler-context.ts +98 -0
  121. package/src/runtime/scheduling/coalesce-tasks.ts +5 -0
  122. package/src/runtime/scheduling/global-worker-cap.ts +2 -1
  123. package/src/runtime/scheduling/nested-slots.ts +70 -0
  124. package/src/runtime/scheduling/run-coalesced-task-group.ts +64 -13
  125. package/src/runtime/scheduling/task-graph-scheduler.ts +0 -10
  126. package/src/runtime/settings-store.ts +219 -0
  127. package/src/runtime/spawn-policy.ts +217 -0
  128. package/src/runtime/stale-reconciler.ts +87 -6
  129. package/src/runtime/subagent-manager.ts +25 -1
  130. package/src/runtime/task-output-context.ts +230 -9
  131. package/src/runtime/task-packet.ts +23 -1
  132. package/src/runtime/task-runner/child-executor.ts +106 -7
  133. package/src/runtime/task-runner/post-execution.ts +125 -1
  134. package/src/runtime/task-runner/pre-execution.ts +39 -1
  135. package/src/runtime/task-runner/prompt-builder.ts +51 -1
  136. package/src/runtime/task-runner/retrieval-orchestrator.ts +72 -18
  137. package/src/runtime/task-runner/spec-evidence.ts +403 -0
  138. package/src/runtime/task-runner/state-helpers.ts +26 -24
  139. package/src/runtime/task-runner.ts +11 -0
  140. package/src/runtime/team-runner.ts +132 -1673
  141. package/src/runtime/verification/spec-sandbox.ts +255 -0
  142. package/src/runtime/verification/verification-gates.ts +3 -2
  143. package/src/runtime/verification/verification-worktree.ts +2 -1
  144. package/src/runtime/workflow-phase-advance.ts +100 -0
  145. package/src/runtime/workspace-tree.ts +9 -0
  146. package/src/schema/config-schema.ts +66 -26
  147. package/src/schema/sensitive-config-paths.ts +64 -0
  148. package/src/schema/team-tool-schema.ts +13 -3
  149. package/src/state/README.md +4 -10
  150. package/src/state/atomic-write.ts +20 -3
  151. package/src/state/contracts.ts +38 -0
  152. package/src/state/coordination/mailbox.ts +12 -2
  153. package/src/state/event-log/cursor.ts +223 -0
  154. package/src/state/event-log/event-log-rotation.ts +12 -4
  155. package/src/state/event-log/event-log.ts +152 -369
  156. package/src/state/event-log/sequence-cache.ts +373 -0
  157. package/src/state/event-log/worker-atomic-writer.ts +2 -1
  158. package/src/state/stores/active-run-registry.ts +3 -2
  159. package/src/state/stores/manifest-io.ts +237 -0
  160. package/src/state/stores/ownership-map.ts +162 -0
  161. package/src/state/stores/plan-store.ts +241 -0
  162. package/src/state/stores/run-cache.ts +0 -90
  163. package/src/state/stores/spec-store.ts +189 -0
  164. package/src/state/stores/state-store.ts +139 -232
  165. package/src/state/types.ts +199 -0
  166. package/src/ui/dashboard-panes/plan-pane.ts +136 -0
  167. package/src/ui/dashboard-panes/progress-pane.ts +6 -0
  168. package/src/ui/dashboard-panes/transcript-pane.ts +31 -0
  169. package/src/ui/dock-footer.ts +49 -0
  170. package/src/ui/heartbeat-aggregator.ts +9 -1
  171. package/src/ui/inline-panel/agent-pane.ts +375 -0
  172. package/src/ui/inline-panel/agent-transcript.ts +338 -0
  173. package/src/ui/inline-panel/agent-view-overlay.ts +225 -0
  174. package/src/ui/inline-panel/crew-editor.ts +192 -0
  175. package/src/ui/inline-panel/index.ts +290 -0
  176. package/src/ui/inline-panel/panel-rows.ts +37 -0
  177. package/src/ui/inline-panel/panel-selection.ts +157 -0
  178. package/src/ui/inline-panel/panel-store.ts +111 -0
  179. package/src/ui/inline-panel/view-session-store.ts +36 -0
  180. package/src/ui/keybinding-map.ts +54 -13
  181. package/src/ui/pi-ui-compat.ts +9 -0
  182. package/src/ui/powerbar-publisher.ts +52 -1
  183. package/src/ui/run-dashboard.ts +31 -5
  184. package/src/ui/run-snapshot-cache.ts +57 -30
  185. package/src/ui/snapshot-types.ts +6 -1
  186. package/src/ui/widget/index.ts +176 -22
  187. package/src/ui/widget/task-list.ts +198 -0
  188. package/src/ui/widget/widget-formatters.ts +240 -4
  189. package/src/ui/widget/widget-renderer.ts +243 -38
  190. package/src/ui/widget/widget-types.ts +11 -0
  191. package/src/utils/child-process-shield.ts +106 -0
  192. package/src/utils/file-coalescer.ts +0 -4
  193. package/src/utils/fs-errno.ts +66 -0
  194. package/src/utils/fs-watch.ts +1 -1
  195. package/src/utils/internal-error.ts +3 -1
  196. package/src/utils/paths.ts +11 -3
  197. package/src/utils/redaction.ts +7 -0
  198. package/src/utils/safe-abort.ts +45 -0
  199. package/src/utils/task-name-generator.ts +1 -8
  200. package/src/workflows/discover-workflows.ts +20 -2
  201. package/src/workflows/validate-workflow.ts +7 -1
  202. package/src/workflows/workflow-config.ts +17 -0
  203. package/src/workflows/workflow-serializer.ts +3 -0
  204. package/src/worktree/worktree-manager.ts +22 -0
  205. package/workflows/default.workflow.md +36 -26
  206. package/workflows/strict-fast-fix.workflow.md +26 -0
  207. package/src/agents/agent-search.ts +0 -98
  208. package/src/benchmark/benchmark-runner.ts +0 -313
  209. package/src/benchmark/feedback-loop.ts +0 -73
  210. package/src/config/resilient-parser.ts +0 -117
  211. package/src/extension/crew-vibes/cat-frames.ts +0 -18
  212. package/src/extension/result-watcher.ts +0 -139
  213. package/src/observability/exporters/prometheus-exporter.ts +0 -54
  214. package/src/observability/metric-retention.ts +0 -64
  215. package/src/runtime/compaction/compaction-summary.ts +0 -278
  216. package/src/runtime/errors/crew-errors.ts +0 -162
  217. package/src/runtime/live-session/intercom-bridge.ts +0 -187
  218. package/src/runtime/loop-gates.ts +0 -128
  219. package/src/runtime/metric-parser.ts +0 -36
  220. package/src/runtime/output/stream-preview.ts +0 -184
  221. package/src/runtime/output/tool-progress.ts +0 -278
  222. package/src/runtime/phase-tracker.ts +0 -385
  223. package/src/runtime/pipeline-runner.ts +0 -523
  224. package/src/runtime/process/process-lifecycle.ts +0 -491
  225. package/src/runtime/recovery/retry-runner.ts +0 -330
  226. package/src/runtime/run-drift.ts +0 -219
  227. package/src/runtime/task-quality.ts +0 -199
  228. package/src/runtime/task-runner/run-projection.ts +0 -128
  229. package/src/runtime/verification/post-checks.ts +0 -142
  230. package/src/state/coordination/schedule.ts +0 -166
  231. package/src/state/event-log/jsonl-writer.ts +0 -115
  232. package/src/state/hook-instinct-bridge.ts +0 -94
  233. package/src/state/hook-integrations.ts +0 -51
  234. package/src/state/session-state-map.ts +0 -51
  235. package/src/state/stores/blob-store.ts +0 -308
  236. package/src/state/stores/instinct-store.ts +0 -275
  237. package/src/state/stores/observation-store.ts +0 -176
  238. package/src/state/tiered-eval.ts +0 -480
  239. package/src/state/types-eval.ts +0 -58
  240. package/src/tools/safe-bash-extension.ts +0 -54
  241. package/src/tools/safe-bash.ts +0 -505
  242. package/src/ui/agent-management-overlay.ts +0 -160
  243. package/src/ui/crew-footer.ts +0 -102
  244. package/src/ui/crew-select-list.ts +0 -114
  245. package/src/ui/dashboard-panes/capability-pane.ts +0 -77
  246. package/src/ui/transcript-entries.ts +0 -256
  247. package/src/utils/conflict-detect.ts +0 -721
  248. package/src/utils/fingerprint.ts +0 -180
  249. package/src/utils/gh-protocol.ts +0 -556
  250. package/src/utils/project-detector.ts +0 -160
  251. package/src/utils/sse-parser.ts +0 -131
  252. package/src/workflows/cost-estimator.ts +0 -34
  253. package/src/workflows/intermediate-store.ts +0 -166
@@ -0,0 +1,691 @@
1
+ /**
2
+ * Central env-var registry for the PI_CREW_* / PI_TEAMS_* families.
3
+ *
4
+ * Phase 3.2 (refactor-plan row 3.2) deliverable: a single place that
5
+ * enumerates every crew-family environment variable, its default, its
6
+ * parser family, and its mirror (PI_CREW_X ↔ PI_TEAMS_X) mapping, plus a
7
+ * single lookup function that preserves the exact read semantics of the
8
+ * original `process.env.X` sites.
9
+ *
10
+ * DESIGN NOTES (behavior-preservation contract):
11
+ * - `getCrewEnv(name)` returns the RAW string value (undefined when unset)
12
+ * so truthiness/existence checks (`if (getCrewEnv(...))`) and exact-string
13
+ * comparisons (`=== "1"`, `=== "success"`) behave identically to the
14
+ * original `process.env.X` reads. The registry `default` is applied by
15
+ * `getCrewEnvParsed` / the typed wrappers, NOT by the raw getter.
16
+ * - Mirror resolution: when a name has a `mirror`, `getCrewEnv` reproduces
17
+ * the original dual-read precedence:
18
+ * - `mirrorPrecedence: "teams"` → TEAMS ?? CREW (PI_TEAMS_HOME wins)
19
+ * - `mirrorPrecedence: "crew"` → CREW ?? TEAMS (PI_CREW wins)
20
+ * - `mirrorPrecedence: "or"` → no collapse — both names are read
21
+ * independently by the call site (e.g. `A === "0" || B === "0"`);
22
+ * `getCrewEnv` returns the raw value for the queried name only.
23
+ * - WRITE sites (e.g. `process.env.PI_CREW_BACKGROUND_MODE = "1"`) stay raw
24
+ * by design; the registry documents them via `doc`/`deprecated` notes.
25
+ *
26
+ * The CI gate `scripts/check-env-vars.mjs` fails on any raw
27
+ * `process.env.PI_CREW_*` / `PI_TEAMS_*` READ outside this file, so new
28
+ * reads must be routed through `getCrewEnv`.
29
+ */
30
+
31
+ export type CrewEnvParser = "string" | "int" | "number" | "boolean" | "json";
32
+ export type MirrorPrecedence = "crew" | "teams" | "or";
33
+
34
+ export interface CrewEnvVarSpec {
35
+ /** Canonical env var name (registry key == the literal env var name). */
36
+ name: string;
37
+ /**
38
+ * Default applied by `getCrewEnvParsed` / typed wrappers when the var is
39
+ * unset (or unparseable). The raw `getCrewEnv` returns undefined instead,
40
+ * preserving original existence/truthiness semantics.
41
+ */
42
+ default?: string | number | boolean;
43
+ /** Parser family used by `getCrewEnvParsed` (documentation + tests). */
44
+ parser?: CrewEnvParser;
45
+ /** Mirror name (the PI_CREW_ ↔ PI_TEAMS_ counterpart), if any. */
46
+ mirror?: string;
47
+ /** How dual PI_CREW_/PI_TEAMS_ reads resolve (see module doc). */
48
+ mirrorPrecedence?: MirrorPrecedence;
49
+ /** Value is (also) written via `process.env` at some site. */
50
+ writeOnly?: boolean;
51
+ /** Deprecation / status note. */
52
+ deprecated?: string;
53
+ /** Short doc: where it is read and what it controls. */
54
+ doc?: string;
55
+ }
56
+
57
+ /**
58
+ * The registry. Every name READ in src/ is mandatory; names found only in
59
+ * docs/tests are best-effort (marked with `deprecated`/`doc` notes).
60
+ */
61
+ export const CREW_ENV_VARS: Record<string, CrewEnvVarSpec> = {
62
+ // ── Mirror pairs — PI_TEAMS_HOME wins ────────────────────────────────
63
+ PI_CREW_HOME: {
64
+ name: "PI_CREW_HOME",
65
+ mirror: "PI_TEAMS_HOME",
66
+ mirrorPrecedence: "teams",
67
+ doc: "pi-crew home dir; PI_TEAMS_HOME wins (config.ts:174, paths.ts:58, crew-vibes/config.ts:16)",
68
+ },
69
+ PI_TEAMS_HOME: {
70
+ name: "PI_TEAMS_HOME",
71
+ mirror: "PI_CREW_HOME",
72
+ mirrorPrecedence: "teams",
73
+ doc: "pi-crew home dir — primary of the TEAMS??CREW pair",
74
+ },
75
+
76
+ // ── Mirror pairs — PI_CREW wins ──────────────────────────────────────
77
+ PI_CREW_DEPTH: {
78
+ name: "PI_CREW_DEPTH",
79
+ mirror: "PI_TEAMS_DEPTH",
80
+ mirrorPrecedence: "crew",
81
+ default: "0",
82
+ parser: "int",
83
+ doc: "current crew depth (pi-args.ts:72 reads CREW ?? TEAMS ?? '0')",
84
+ },
85
+ PI_TEAMS_DEPTH: {
86
+ name: "PI_TEAMS_DEPTH",
87
+ mirror: "PI_CREW_DEPTH",
88
+ mirrorPrecedence: "crew",
89
+ default: "0",
90
+ parser: "int",
91
+ doc: "crew depth mirror (fallback of PI_CREW_DEPTH)",
92
+ },
93
+ PI_CREW_MAX_DEPTH: {
94
+ name: "PI_CREW_MAX_DEPTH",
95
+ mirror: "PI_TEAMS_MAX_DEPTH",
96
+ mirrorPrecedence: "crew",
97
+ parser: "int",
98
+ doc: "max crew depth, clamped 1..10 (pi-args.ts:78)",
99
+ },
100
+ PI_TEAMS_MAX_DEPTH: {
101
+ name: "PI_TEAMS_MAX_DEPTH",
102
+ mirror: "PI_CREW_MAX_DEPTH",
103
+ mirrorPrecedence: "crew",
104
+ parser: "int",
105
+ doc: "max crew depth mirror (fallback of PI_CREW_MAX_DEPTH)",
106
+ },
107
+ PI_CREW_ROLE: {
108
+ name: "PI_CREW_ROLE",
109
+ mirror: "PI_TEAMS_ROLE",
110
+ mirrorPrecedence: "crew",
111
+ doc: "crew role name (role-permission.ts:46 reads CREW?.trim() || TEAMS?.trim())",
112
+ },
113
+ PI_TEAMS_ROLE: {
114
+ name: "PI_TEAMS_ROLE",
115
+ mirror: "PI_CREW_ROLE",
116
+ mirrorPrecedence: "crew",
117
+ doc: "crew role mirror (fallback of PI_CREW_ROLE)",
118
+ },
119
+ PI_CREW_VERIFICATION_PRESERVE_ENV: {
120
+ name: "PI_CREW_VERIFICATION_PRESERVE_ENV",
121
+ mirror: "PI_TEAMS_VERIFICATION_PRESERVE_ENV",
122
+ mirrorPrecedence: "crew",
123
+ doc: "extra env keys to preserve in verification commands (CREW ?? TEAMS ?? '')",
124
+ },
125
+ PI_TEAMS_VERIFICATION_PRESERVE_ENV: {
126
+ name: "PI_TEAMS_VERIFICATION_PRESERVE_ENV",
127
+ mirror: "PI_CREW_VERIFICATION_PRESERVE_ENV",
128
+ mirrorPrecedence: "crew",
129
+ doc: "verification preserve-env mirror (fallback of PI_CREW_...)",
130
+ },
131
+ PI_CREW_VERIFICATION_WORKTREE: {
132
+ name: "PI_CREW_VERIFICATION_WORKTREE",
133
+ mirror: "PI_TEAMS_VERIFICATION_WORKTREE",
134
+ mirrorPrecedence: "crew",
135
+ doc: "enable verification worktree sandbox; '1'/'true' (CREW ?? TEAMS)",
136
+ },
137
+ PI_TEAMS_VERIFICATION_WORKTREE: {
138
+ name: "PI_TEAMS_VERIFICATION_WORKTREE",
139
+ mirror: "PI_CREW_VERIFICATION_WORKTREE",
140
+ mirrorPrecedence: "crew",
141
+ doc: "verification worktree mirror (fallback of PI_CREW_...)",
142
+ },
143
+ PI_CREW_INHERIT_PROJECT_CONTEXT: {
144
+ name: "PI_CREW_INHERIT_PROJECT_CONTEXT",
145
+ mirror: "PI_TEAMS_INHERIT_PROJECT_CONTEXT",
146
+ mirrorPrecedence: "crew",
147
+ parser: "boolean",
148
+ doc: "inherit project context in worker prompts; CREW checked first (prompt-runtime.ts readBooleanEnvAny)",
149
+ },
150
+ PI_TEAMS_INHERIT_PROJECT_CONTEXT: {
151
+ name: "PI_TEAMS_INHERIT_PROJECT_CONTEXT",
152
+ mirror: "PI_CREW_INHERIT_PROJECT_CONTEXT",
153
+ mirrorPrecedence: "crew",
154
+ parser: "boolean",
155
+ doc: "inherit project context mirror (fallback of PI_CREW_...)",
156
+ },
157
+ PI_CREW_INHERIT_SKILLS: {
158
+ name: "PI_CREW_INHERIT_SKILLS",
159
+ mirror: "PI_TEAMS_INHERIT_SKILLS",
160
+ mirrorPrecedence: "crew",
161
+ parser: "boolean",
162
+ doc: "inherit skills in worker prompts; CREW checked first (prompt-runtime.ts readBooleanEnvAny)",
163
+ },
164
+ PI_TEAMS_INHERIT_SKILLS: {
165
+ name: "PI_TEAMS_INHERIT_SKILLS",
166
+ mirror: "PI_CREW_INHERIT_SKILLS",
167
+ mirrorPrecedence: "crew",
168
+ parser: "boolean",
169
+ doc: "inherit skills mirror (fallback of PI_CREW_...)",
170
+ },
171
+
172
+ // ── Mirror pairs — OR semantics (dual reads, no collapse) ─────────────
173
+ PI_CREW_ADAPTIVE_REPAIR: {
174
+ name: "PI_CREW_ADAPTIVE_REPAIR",
175
+ mirror: "PI_TEAMS_ADAPTIVE_REPAIR",
176
+ mirrorPrecedence: "or",
177
+ doc: "'0' disables adaptive-plan repair; either name may disable (adaptive-plan.ts:434)",
178
+ },
179
+ PI_TEAMS_ADAPTIVE_REPAIR: {
180
+ name: "PI_TEAMS_ADAPTIVE_REPAIR",
181
+ mirror: "PI_CREW_ADAPTIVE_REPAIR",
182
+ mirrorPrecedence: "or",
183
+ doc: "adaptive-repair mirror (read independently, OR'd with PI_CREW_...)",
184
+ },
185
+ PI_CREW_BG_REPORT_ON_FATAL: {
186
+ name: "PI_CREW_BG_REPORT_ON_FATAL",
187
+ mirror: "PI_TEAMS_BG_REPORT_ON_FATAL",
188
+ mirrorPrecedence: "or",
189
+ doc: "'0' disables --report-on-fatalerror; either name may disable (async-runner.ts:127)",
190
+ },
191
+ PI_TEAMS_BG_REPORT_ON_FATAL: {
192
+ name: "PI_TEAMS_BG_REPORT_ON_FATAL",
193
+ mirror: "PI_CREW_BG_REPORT_ON_FATAL",
194
+ mirrorPrecedence: "or",
195
+ doc: "bg-report mirror (read independently, OR'd with PI_CREW_...)",
196
+ },
197
+ PI_CREW_EXECUTE_WORKERS: {
198
+ name: "PI_CREW_EXECUTE_WORKERS",
199
+ mirror: "PI_TEAMS_EXECUTE_WORKERS",
200
+ mirrorPrecedence: "or",
201
+ doc: "'0' disables real worker execution; either name disables (team-tool.ts:376, run.ts, runtime-resolver.ts:91)",
202
+ },
203
+ PI_TEAMS_EXECUTE_WORKERS: {
204
+ name: "PI_TEAMS_EXECUTE_WORKERS",
205
+ mirror: "PI_CREW_EXECUTE_WORKERS",
206
+ mirrorPrecedence: "or",
207
+ doc: "execute-workers mirror (read independently, OR'd with PI_CREW_...)",
208
+ },
209
+ PI_CREW_VERIFICATION_SANITIZE_ENV: {
210
+ name: "PI_CREW_VERIFICATION_SANITIZE_ENV",
211
+ mirror: "PI_TEAMS_VERIFICATION_SANITIZE_ENV",
212
+ mirrorPrecedence: "or",
213
+ doc: "'0' disables verification env sanitization; either name disables (verification-gates.ts:69)",
214
+ },
215
+ PI_TEAMS_VERIFICATION_SANITIZE_ENV: {
216
+ name: "PI_TEAMS_VERIFICATION_SANITIZE_ENV",
217
+ mirror: "PI_CREW_VERIFICATION_SANITIZE_ENV",
218
+ mirrorPrecedence: "or",
219
+ doc: "verification sanitize mirror (read independently, OR'd with PI_CREW_...)",
220
+ },
221
+ PI_CREW_WORKER_ATOMIC_WRITER: {
222
+ name: "PI_CREW_WORKER_ATOMIC_WRITER",
223
+ mirror: "PI_TEAMS_WORKER_ATOMIC_WRITER",
224
+ mirrorPrecedence: "or",
225
+ doc: "'1' enables the worker-thread atomic writer; either name enables (worker-atomic-writer.ts:166)",
226
+ },
227
+ PI_TEAMS_WORKER_ATOMIC_WRITER: {
228
+ name: "PI_TEAMS_WORKER_ATOMIC_WRITER",
229
+ mirror: "PI_CREW_WORKER_ATOMIC_WRITER",
230
+ mirrorPrecedence: "or",
231
+ doc: "worker-atomic-writer mirror (read independently, OR'd with PI_CREW_...)",
232
+ },
233
+
234
+ // ── Single names read via process.env (dot notation) ──────────────────
235
+ PI_CREW_ALLOW_MOCK: {
236
+ name: "PI_CREW_ALLOW_MOCK",
237
+ parser: "boolean",
238
+ doc: "'1'/'true' allows PI_TEAMS_MOCK_CHILD_PI mock mode (mock-fixtures.ts:40)",
239
+ },
240
+ PI_CREW_ASYNC_EARLY_EXIT_GUARD: {
241
+ name: "PI_CREW_ASYNC_EARLY_EXIT_GUARD",
242
+ doc: "'0' skips the async-run early-exit guard (team-tool/run.ts:103)",
243
+ },
244
+ PI_CREW_BACKGROUND_MODE: {
245
+ name: "PI_CREW_BACKGROUND_MODE",
246
+ doc: "background-runner marker; READ at child-executor.ts:616 ('1'), WRITTEN at background-runner.ts:713/833 (= '1')",
247
+ },
248
+ PI_CREW_BROKER: {
249
+ name: "PI_CREW_BROKER",
250
+ doc: "'1'/'0' force broker enabled/disabled (defaults.ts:187, lifecycle-handlers.ts:908)",
251
+ },
252
+ PI_CREW_DEBUG: {
253
+ name: "PI_CREW_DEBUG",
254
+ doc: "truthiness enables background debug logging (background-runner.ts:63)",
255
+ },
256
+ PI_CREW_DEBUG_BUDGET: {
257
+ name: "PI_CREW_DEBUG_BUDGET",
258
+ doc: "'1' logs token budget (team-tool/run.ts:498)",
259
+ },
260
+ PI_CREW_DWF_SCRIPT_TIMEOUT_MS: {
261
+ name: "PI_CREW_DWF_SCRIPT_TIMEOUT_MS",
262
+ parser: "int",
263
+ default: 1_800_000,
264
+ doc: "dynamic-workflow script timeout; default 30 min (dynamic-workflow-runner.ts:226)",
265
+ },
266
+ PI_CREW_DWF_SKIP_DETERMINISM_CHECK: {
267
+ name: "PI_CREW_DWF_SKIP_DETERMINISM_CHECK",
268
+ doc: "'1' disables the DWF determinism check (deterministic-ast.ts:60)",
269
+ },
270
+ PI_CREW_INTERRUPT_GUARD_INTERVAL_MS: {
271
+ name: "PI_CREW_INTERRUPT_GUARD_INTERVAL_MS",
272
+ parser: "int",
273
+ default: 250,
274
+ doc: "interrupt-guard poll interval; default 250ms (background-runner.ts:217)",
275
+ },
276
+ PI_CREW_MAX_RUN_MS: {
277
+ name: "PI_CREW_MAX_RUN_MS",
278
+ parser: "int",
279
+ default: 7_200_000,
280
+ doc: "max background run duration; default 2h (background-runner.ts:31)",
281
+ },
282
+ PI_CREW_MAX_WORKERS: {
283
+ name: "PI_CREW_MAX_WORKERS",
284
+ parser: "int",
285
+ doc: "max concurrent workers; unset/empty/invalid → default max(2, cpus-2) (global-worker-cap.ts:33)",
286
+ },
287
+ PI_CREW_DISABLE_RESULT_READ_CACHE: {
288
+ name: "PI_CREW_DISABLE_RESULT_READ_CACHE",
289
+ doc: "'1' bypasses the per-run result-artifact read cache (R10-1 bypass control; task-output-context.ts createResultArtifactReadCache)",
290
+ },
291
+ PI_CREW_MOCK_LIVE_SESSION: {
292
+ name: "PI_CREW_MOCK_LIVE_SESSION",
293
+ doc: "'success' mocks a successful live-session (live-session-runtime.ts:558, runtime-resolver.ts:38/116)",
294
+ },
295
+ PI_CREW_PARENT_GUARD_INTERVAL_MS: {
296
+ name: "PI_CREW_PARENT_GUARD_INTERVAL_MS",
297
+ parser: "int",
298
+ default: 500,
299
+ doc: "parent-guard poll interval; default 500ms (parent-guard.ts:73)",
300
+ },
301
+ PI_CREW_PARENT_PID: {
302
+ name: "PI_CREW_PARENT_PID",
303
+ parser: "int",
304
+ doc: "parent process pid; >0 starts the parent guard (background-runner.ts:626)",
305
+ },
306
+ PI_CREW_SCRATCHPAD_DEMOTE_BASH: {
307
+ name: "PI_CREW_SCRATCHPAD_DEMOTE_BASH",
308
+ doc: "'1' demotes bash for scratchpad roles (agent-config.ts:199)",
309
+ },
310
+ PI_CREW_SKIP_HOME_CHECK: {
311
+ name: "PI_CREW_SKIP_HOME_CHECK",
312
+ doc: "'1' skips the PI_TEAMS_HOME escape check (config.ts:185)",
313
+ },
314
+ PI_CREW_SUPPRESS_RPC_WARNING: {
315
+ name: "PI_CREW_SUPPRESS_RPC_WARNING",
316
+ doc: "'1' suppresses the missing-RPC-secret warning (rpc-hmac.ts:145)",
317
+ },
318
+ PI_CREW_TRUST_PROJECT_AGENT_EXTENSIONS: {
319
+ name: "PI_CREW_TRUST_PROJECT_AGENT_EXTENSIONS",
320
+ doc: "'1' trusts project/.pi agent extensions (discover-agents.ts:445/544)",
321
+ },
322
+ PI_CREW_PLAN_UI: {
323
+ name: "PI_CREW_PLAN_UI",
324
+ doc: "'1' enables the Plan dashboard pane (7) + plans snapshot slice (WP-7/R7)",
325
+ },
326
+ PI_CREW_TRUST_PROJECT_DWF: {
327
+ name: "PI_CREW_TRUST_PROJECT_DWF",
328
+ doc: "'1' allows project-sourced .dwf.ts workflows (dynamic-workflow-runner.ts:154)",
329
+ },
330
+ PI_TEAMS_CHILD_RESPONSE_TIMEOUT_MS: {
331
+ name: "PI_TEAMS_CHILD_RESPONSE_TIMEOUT_MS",
332
+ parser: "int",
333
+ doc: "child Pi response timeout, bounded 1s..3.6M ms (child-pi.ts:356)",
334
+ },
335
+ PI_TEAMS_DEBUG: {
336
+ name: "PI_TEAMS_DEBUG",
337
+ doc: "truthiness gates debug-severity internal-error logging (internal-error.ts:4)",
338
+ },
339
+ PI_TEAMS_MOCK_CHILD_PI: {
340
+ name: "PI_TEAMS_MOCK_CHILD_PI",
341
+ doc: "mock child-pi mode; values 'success'/'json-success'/'adaptive-plan' (mock-fixtures.ts:35)",
342
+ },
343
+ PI_TEAMS_PI_BIN: {
344
+ name: "PI_TEAMS_PI_BIN",
345
+ doc: "explicit pi binary path for spawned children (pi-spawn.ts:262)",
346
+ },
347
+
348
+ // ── Single names read via process.env[...] (const/bracket sites) ──────
349
+ PI_CREW_MAX_OUTPUT: {
350
+ name: "PI_CREW_MAX_OUTPUT",
351
+ parser: "int",
352
+ doc: "max output tokens cap for background workers (prompt-runtime.ts:228)",
353
+ },
354
+ PI_CREW_STEERING_FILE: {
355
+ name: "PI_CREW_STEERING_FILE",
356
+ doc: "steering JSONL path polled by the worker (prompt-runtime.ts:260)",
357
+ },
358
+ PI_CREW_KEYBINDINGS: {
359
+ name: "PI_CREW_KEYBINDINGS",
360
+ parser: "json",
361
+ doc: "JSON keybinding override map (keybinding-map.ts:314/347)",
362
+ },
363
+ PI_CREW_RPC_SECRET: {
364
+ name: "PI_CREW_RPC_SECRET",
365
+ doc: "shared HMAC secret; READ at rpc-hmac.ts:26/41, WRITTEN/cleared at :31/:36",
366
+ },
367
+ PI_CREW_PEER_DEP_DIR: {
368
+ name: "PI_CREW_PEER_DEP_DIR",
369
+ doc: "parent-provided pi-coding-agent package dir hint (peer-dep.ts:81)",
370
+ },
371
+
372
+ // ── Names read from a passed-in env object (child-spawned env) ────────
373
+ PI_CREW_SCRATCHPAD: {
374
+ name: "PI_CREW_SCRATCHPAD",
375
+ doc: "'1' enables the scratchpad engine (scratchpad-lifecycle.ts:486/679, written by child-pi-spawn.ts)",
376
+ },
377
+ PI_CREW_KIND: {
378
+ name: "PI_CREW_KIND",
379
+ doc: "'subagent' marks child workers (scratchpad-lifecycle.ts:679, lifecycle-handlers.ts:892, zombie-scanner.ts:183)",
380
+ },
381
+ PI_CREW_TASK_ID: {
382
+ name: "PI_CREW_TASK_ID",
383
+ doc: "current task id for scratchpad/events (scratchpad-lifecycle.ts:90/227/280)",
384
+ },
385
+ PI_CREW_EVENTS_PATH: {
386
+ name: "PI_CREW_EVENTS_PATH",
387
+ doc: "events JSONL path for fire-and-forget metric events (scratchpad-lifecycle.ts:80)",
388
+ },
389
+ PI_CREW_ASK_ENABLED: {
390
+ name: "PI_CREW_ASK_ENABLED",
391
+ doc: "'1' enables the worker-side ask tool — dormant-until-env gate (written UNCONDITIONALLY by child-pi-spawn.ts, read by prompt-runtime.ts per ADR-0 WP-2 item 2)",
392
+ },
393
+ PI_CREW_STATE_ROOT: {
394
+ name: "PI_CREW_STATE_ROOT",
395
+ doc: "run stateRoot for the ask-tool mailbox poll (<stateRoot>/mailbox; written by child-pi-spawn.ts, read by prompt-runtime.ts per ADR-0 WP-2 item 2)",
396
+ },
397
+ PI_CREW_BROKER_RUN_ID: {
398
+ name: "PI_CREW_BROKER_RUN_ID",
399
+ doc: "broker run id; aliases PI_CREW_RUN_ID (scratchpad-lifecycle.ts:81, crew-broker-child.ts:51)",
400
+ },
401
+ PI_CREW_ARTIFACTS_ROOT: {
402
+ name: "PI_CREW_ARTIFACTS_ROOT",
403
+ doc: "artifacts root for scratchpad containment (scratchpad-lifecycle.ts:228/281)",
404
+ },
405
+ PI_CREW_SCRATCHPAD_SNAPSHOT: {
406
+ name: "PI_CREW_SCRATCHPAD_SNAPSHOT",
407
+ doc: "snapshot path for the post-cell snapshot (scratchpad-lifecycle.ts:229)",
408
+ },
409
+ PI_CREW_ATTEMPT: {
410
+ name: "PI_CREW_ATTEMPT",
411
+ default: "0",
412
+ doc: "current attempt number (scratchpad-lifecycle.ts:230 reads ?? '0')",
413
+ },
414
+ PI_CREW_SCRATCHPAD_RESTORE: {
415
+ name: "PI_CREW_SCRATCHPAD_RESTORE",
416
+ doc: "parent-set restore hint: previous attempt snapshot (scratchpad-lifecycle.ts:653)",
417
+ },
418
+ PI_CREW_SCRATCHPAD_RESTORE_MTIME: {
419
+ name: "PI_CREW_SCRATCHPAD_RESTORE_MTIME",
420
+ parser: "number",
421
+ doc: "swap-detection mtime pin for restore snapshots (scratchpad-lifecycle.ts:302)",
422
+ },
423
+ PI_CREW_MAX_AUTO_FALLBACKS: {
424
+ name: "PI_CREW_MAX_AUTO_FALLBACKS",
425
+ parser: "int",
426
+ doc: "max automatic model fallbacks (model-fallback.ts:527)",
427
+ },
428
+ PI_CREW_MODEL_FALLBACK_ORDER: {
429
+ name: "PI_CREW_MODEL_FALLBACK_ORDER",
430
+ doc: "'parentFirst' | 'asIs' fallback order (model-fallback.ts:555)",
431
+ },
432
+ PI_CREW_MODEL_REQUIRE_CREDENTIALS: {
433
+ name: "PI_CREW_MODEL_REQUIRE_CREDENTIALS",
434
+ parser: "boolean",
435
+ doc: "'1'/'0' override requireCredentials (model-fallback.ts:557/559)",
436
+ },
437
+ PI_CREW_MODEL: {
438
+ name: "PI_CREW_MODEL",
439
+ doc: "model override for subagents (model-fallback.ts:584)",
440
+ },
441
+ PI_CREW_BROKER_SOCKET: {
442
+ name: "PI_CREW_BROKER_SOCKET",
443
+ doc: "broker unix socket path for child handshake (crew-broker-child.ts:49)",
444
+ },
445
+ PI_CREW_BROKER_TOKEN: {
446
+ name: "PI_CREW_BROKER_TOKEN",
447
+ doc: "broker handshake token (crew-broker-child.ts:50)",
448
+ },
449
+ PI_CREW_BROKER_TASK_ID: {
450
+ name: "PI_CREW_BROKER_TASK_ID",
451
+ doc: "broker task id for child handshake (crew-broker-child.ts:51)",
452
+ },
453
+ PI_CREW_GUEST: {
454
+ name: "PI_CREW_GUEST",
455
+ doc: "'1' marks the guest scratchpad process (written by scratchpad-lifecycle.ts:167)",
456
+ },
457
+
458
+ // ── Docs/tests-only (best-effort; not read via process.env in src/) ───
459
+ PI_CREW_USE_BUNDLE: {
460
+ name: "PI_CREW_USE_BUNDLE",
461
+ doc: "read at root index.ts:78 (outside src/ gate scope): force strip-types loading when 0",
462
+ },
463
+ PI_CREW_SMOKE: {
464
+ name: "PI_CREW_SMOKE",
465
+ doc: "test-only: smoke-test helper flag (test/smoke/_helpers.ts)",
466
+ },
467
+ PI_CREW_RUN_PLATFORM_TESTS: {
468
+ name: "PI_CREW_RUN_PLATFORM_TESTS",
469
+ doc: "test-only: enables platform tests (test/platform)",
470
+ },
471
+ PI_CREW_HARD_KILL_GRACE_MS: {
472
+ name: "PI_CREW_HARD_KILL_GRACE_MS",
473
+ doc: "scripts-only: watchdog hard-kill grace (scripts/watchdog-harness.ts)",
474
+ },
475
+ PI_CREW_LIVE_MODEL: {
476
+ name: "PI_CREW_LIVE_MODEL",
477
+ doc: "docs/test-only: live-session model selection",
478
+ },
479
+ PI_CREW_ENABLE_EXPERIMENTAL_LIVE_SESSION: {
480
+ name: "PI_CREW_ENABLE_EXPERIMENTAL_LIVE_SESSION",
481
+ doc: "docs/test-only: experimental live-session opt-in",
482
+ },
483
+ PI_CREW_RUN_ID: {
484
+ name: "PI_CREW_RUN_ID",
485
+ doc: "test fixture name; src uses PI_CREW_BROKER_RUN_ID instead",
486
+ },
487
+ PI_TEAMS_CONFIG_KEYS: {
488
+ name: "PI_TEAMS_CONFIG_KEYS",
489
+ doc: "docs/test-only",
490
+ },
491
+ PI_TEAMS_MOCK: {
492
+ name: "PI_TEAMS_MOCK",
493
+ doc: "docs/test-only",
494
+ },
495
+ PI_CREW_VERIFICATION: {
496
+ name: "PI_CREW_VERIFICATION",
497
+ deprecated: "partial fixture name; real vars are PI_CREW_VERIFICATION_*",
498
+ doc: "docs/test-only",
499
+ },
500
+ PI_TEAMS_VERIFICATION: {
501
+ name: "PI_TEAMS_VERIFICATION",
502
+ deprecated: "partial fixture name; real vars are PI_TEAMS_VERIFICATION_*",
503
+ doc: "docs/test-only",
504
+ },
505
+ PI_CREW_ATOMIC_WRITER: {
506
+ name: "PI_CREW_ATOMIC_WRITER",
507
+ deprecated: "superseded by PI_CREW_WORKER_ATOMIC_WRITER",
508
+ doc: "docs/test-only",
509
+ },
510
+ PI_CREW_BROKER_DIAG_UI: {
511
+ name: "PI_CREW_BROKER_DIAG_UI",
512
+ deprecated: "removed",
513
+ doc: "docs/test-only",
514
+ },
515
+ PI_CREW_DEBUG_KILL: {
516
+ name: "PI_CREW_DEBUG_KILL",
517
+ doc: "docs/test-only",
518
+ },
519
+ PI_CREW_DWF_SANDBOX_DRY_RUN: {
520
+ name: "PI_CREW_DWF_SANDBOX_DRY_RUN",
521
+ doc: "docs/test-only",
522
+ },
523
+ PI_CREW_HOOK: {
524
+ name: "PI_CREW_HOOK",
525
+ doc: "docs/test-only",
526
+ },
527
+ PI_CREW_POOL_HEALTH: {
528
+ name: "PI_CREW_POOL_HEALTH",
529
+ doc: "docs/test-only",
530
+ },
531
+ PI_CREW_QUIET_PREFLIGHT: {
532
+ name: "PI_CREW_QUIET_PREFLIGHT",
533
+ doc: "docs/test-only",
534
+ },
535
+ PI_CREW_SAFE_BASH: {
536
+ name: "PI_CREW_SAFE_BASH",
537
+ deprecated: "dead",
538
+ doc: "docs/test-only",
539
+ },
540
+ PI_CREW_SCRATCHPAD_EXPERIMENT: {
541
+ name: "PI_CREW_SCRATCHPAD_EXPERIMENT",
542
+ doc: "docs/test-only",
543
+ },
544
+ PI_CREW_SESSION_DEPTH: {
545
+ name: "PI_CREW_SESSION_DEPTH",
546
+ deprecated: "legacy name; code uses PI_CREW_DEPTH (ADR drift history 2026-08-09)",
547
+ doc: "docs/test-only",
548
+ },
549
+ PI_CREW_SIG: {
550
+ name: "PI_CREW_SIG",
551
+ doc: "docs/test-only",
552
+ },
553
+ PI_CREW_SNAPSHOT_HMAC_KEY: {
554
+ name: "PI_CREW_SNAPSHOT_HMAC_KEY",
555
+ deprecated: "reverted (2026-08-13)",
556
+ doc: "docs/test-only",
557
+ },
558
+ PI_CREW_SNAPSHOT_HMAC_STRICT: {
559
+ name: "PI_CREW_SNAPSHOT_HMAC_STRICT",
560
+ deprecated: "reverted (2026-08-13)",
561
+ doc: "docs/test-only",
562
+ },
563
+ PI_CREW_TEST_REAL_MODEL: {
564
+ name: "PI_CREW_TEST_REAL_MODEL",
565
+ doc: "docs/test-only",
566
+ },
567
+ PI_CREW_TOOLING_429_NOTE: {
568
+ name: "PI_CREW_TOOLING_429_NOTE",
569
+ doc: "docs/test-only",
570
+ },
571
+ PI_CREW_MAX_OUTPUT_TOKENS: {
572
+ name: "PI_CREW_MAX_OUTPUT_TOKENS",
573
+ deprecated: "legacy name; actual var is PI_CREW_MAX_OUTPUT (comment-only in src)",
574
+ doc: "docs/test-only",
575
+ },
576
+ PI_CREW_GOAL_OSCILLATION_EMBEDDINGS: {
577
+ name: "PI_CREW_GOAL_OSCILLATION_EMBEDDINGS",
578
+ doc: "docs/test-only",
579
+ },
580
+ PI_CREW_OPENAI_API_KEY: {
581
+ name: "PI_CREW_OPENAI_API_KEY",
582
+ doc: "comment-only in src (env-filter secret-name example)",
583
+ },
584
+ PI_CREW_SECRET_TOKEN: {
585
+ name: "PI_CREW_SECRET_TOKEN",
586
+ doc: "comment-only in src (env-filter secret-name example)",
587
+ },
588
+ PI_CREW_REFUSE_GATE_PATTERNS: {
589
+ name: "PI_CREW_REFUSE_GATE_PATTERNS",
590
+ doc: "docs-only",
591
+ },
592
+ PI_CREW_PROCEED_PATTERNS: {
593
+ name: "PI_CREW_PROCEED_PATTERNS",
594
+ doc: "docs-only",
595
+ },
596
+ PI_CREW_ENFORCEMENT_PATTERNS: {
597
+ name: "PI_CREW_ENFORCEMENT_PATTERNS",
598
+ doc: "docs-only",
599
+ },
600
+ // Pure test fixtures (placeholder names used by tests to prove isolation).
601
+ PI_CREW_DIR: { name: "PI_CREW_DIR", doc: "test fixture" },
602
+ PI_CREW_ROOT: { name: "PI_CREW_ROOT", doc: "test fixture" },
603
+ PI_CREW_FOO: { name: "PI_CREW_FOO", doc: "test fixture" },
604
+ PI_CREW_VAR: { name: "PI_CREW_VAR", doc: "test fixture" },
605
+ PI_CREW_X: { name: "PI_CREW_X", doc: "test fixture" },
606
+ PI_CREW_TEST_SECRET_VALUE: { name: "PI_CREW_TEST_SECRET_VALUE", doc: "test fixture" },
607
+ PI_TEAMS_BAR: { name: "PI_TEAMS_BAR", doc: "test fixture" },
608
+ };
609
+
610
+ /**
611
+ * Raw crew-env lookup. Returns the raw string (undefined when unset) with
612
+ * mirror-alias fallback applied per the entry's `mirrorPrecedence`. This is
613
+ * the behavior-preserving replacement for `process.env.PI_CREW_X` reads.
614
+ */
615
+ export function getCrewEnv(name: string): string | undefined {
616
+ const spec = CREW_ENV_VARS[name];
617
+ if (!spec?.mirror || spec.mirrorPrecedence === "or") {
618
+ return process.env[name];
619
+ }
620
+ const crewName = name.startsWith("PI_TEAMS_") ? spec.mirror : name;
621
+ const teamsName = name.startsWith("PI_TEAMS_") ? name : spec.mirror;
622
+ if (spec.mirrorPrecedence === "teams") {
623
+ return process.env[teamsName] ?? process.env[crewName];
624
+ }
625
+ return process.env[crewName] ?? process.env[teamsName];
626
+ }
627
+
628
+ /**
629
+ * Parsed lookup: applies the registry parser + default. Returns the raw
630
+ * string for string/unparsed entries, `undefined` when unset with no
631
+ * default. Only use where the generic parse matches the call-site semantics;
632
+ * the raw `getCrewEnv` is the default choice for behavior preservation.
633
+ */
634
+ export function getCrewEnvParsed(name: string): unknown {
635
+ const spec = CREW_ENV_VARS[name];
636
+ const raw = getCrewEnv(name);
637
+ const fallback = (): unknown => spec?.default;
638
+ if (raw === undefined) return fallback();
639
+ if (!spec?.parser || spec.parser === "string") return raw;
640
+ switch (spec.parser) {
641
+ case "int": {
642
+ const n = Number.parseInt(raw, 10);
643
+ return Number.isNaN(n) ? fallback() : n;
644
+ }
645
+ case "number": {
646
+ const n = Number(raw);
647
+ return Number.isNaN(n) ? fallback() : n;
648
+ }
649
+ case "boolean": {
650
+ const normalized = raw.trim().toLowerCase();
651
+ if (normalized === "1" || normalized === "true" || normalized === "yes") return true;
652
+ if (normalized === "0" || normalized === "false" || normalized === "no") return false;
653
+ return fallback();
654
+ }
655
+ case "json": {
656
+ try {
657
+ return JSON.parse(raw);
658
+ } catch {
659
+ return fallback();
660
+ }
661
+ }
662
+ }
663
+ return raw;
664
+ }
665
+
666
+ /** Typed wrapper: boolean parse of a registered crew env var. */
667
+ export function getCrewEnvBool(name: string): boolean | undefined {
668
+ const value = getCrewEnvParsed(name);
669
+ return typeof value === "boolean" ? value : undefined;
670
+ }
671
+
672
+ /** Typed wrapper: integer parse of a registered crew env var. */
673
+ export function getCrewEnvInt(name: string): number | undefined {
674
+ const value = getCrewEnvParsed(name);
675
+ return typeof value === "number" ? value : undefined;
676
+ }
677
+
678
+ /** Typed wrapper: string value (raw, mirror-resolved). */
679
+ export function getCrewEnvString(name: string): string | undefined {
680
+ return getCrewEnv(name);
681
+ }
682
+
683
+ /** All registered crew env var names (for the gate + completeness tests). */
684
+ export function crewEnvNames(): string[] {
685
+ return Object.keys(CREW_ENV_VARS);
686
+ }
687
+
688
+ /** True when the registry covers `name` (mirror or not). */
689
+ export function isCrewEnvRegistered(name: string): boolean {
690
+ return Object.hasOwn(CREW_ENV_VARS, name);
691
+ }