@posthog/wizard 2.80.0 → 2.80.1

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 (227) hide show
  1. package/README.md +187 -57
  2. package/dist/{PickerMenu-m4CCPX4f.js → PickerMenu-BGGeYqd-.js} +104 -4
  3. package/dist/PickerMenu-BGGeYqd-.js.map +1 -0
  4. package/dist/README.md +9 -6
  5. package/dist/{agent-interface-CzyCmp7q.js → agent-interface-CemBvTAA.js} +115 -346
  6. package/dist/agent-interface-CemBvTAA.js.map +1 -0
  7. package/dist/{agent-prompt-loader-4wMxlYSX.js → agent-prompt-loader-DPnj6SwU.js} +6 -5
  8. package/dist/agent-prompt-loader-DPnj6SwU.js.map +1 -0
  9. package/dist/analytics-B3ROGuIr.js +2 -0
  10. package/dist/analytics-D21z3E5l.js +732 -0
  11. package/dist/analytics-D21z3E5l.js.map +1 -0
  12. package/dist/{api-C3Dc4LFl.js → api-DtGIqQ2U.js} +2 -3
  13. package/dist/api-DtGIqQ2U.js.map +1 -0
  14. package/dist/api-IhROOQNv.js +2 -0
  15. package/dist/api-key-login-OEntFvu5.js +2 -0
  16. package/dist/api-key-login-h3E2G3zu.js +55 -0
  17. package/dist/api-key-login-h3E2G3zu.js.map +1 -0
  18. package/dist/bin.js +2 -2
  19. package/dist/bin.js.map +1 -1
  20. package/dist/{bounded-fs-CC_NDtoP.js → bounded-fs-CAsuF6al.js} +3 -3
  21. package/dist/{bounded-fs-CC_NDtoP.js.map → bounded-fs-CAsuF6al.js.map} +1 -1
  22. package/dist/{ci-install-DfcAMhlu.js → ci-install-CEYE02t-.js} +21 -25
  23. package/dist/ci-install-CEYE02t-.js.map +1 -0
  24. package/dist/console-log-O828zyiq.js +32 -0
  25. package/dist/console-log-O828zyiq.js.map +1 -0
  26. package/dist/{debug-DyARf5TF.js → debug-BfQPD2Hg.js} +18 -52
  27. package/dist/debug-BfQPD2Hg.js.map +1 -0
  28. package/dist/{defaults-DpfMnH2q.js → defaults-DDVl3tKN.js} +2 -51
  29. package/dist/defaults-DDVl3tKN.js.map +1 -0
  30. package/dist/{emit-BSetXzDV.js → emit-RfAewcWv.js} +1 -1
  31. package/dist/{emit-BSetXzDV.js.map → emit-RfAewcWv.js.map} +1 -1
  32. package/dist/{errors-C2domSkK.js → errors-CHrJzAZb.js} +4 -4
  33. package/dist/{errors-C2domSkK.js.map → errors-CHrJzAZb.js.map} +1 -1
  34. package/dist/family-picker-BKs-tTyu.js +46 -0
  35. package/dist/family-picker-BKs-tTyu.js.map +1 -0
  36. package/dist/{gateway-BmjYUSua.js → gateway-D3gIlR6b.js} +122 -11
  37. package/dist/gateway-D3gIlR6b.js.map +1 -0
  38. package/dist/headless-BJjhP0SI.js +10 -0
  39. package/dist/headless-BJjhP0SI.js.map +1 -0
  40. package/dist/headless-DIX68UUA.js +3 -0
  41. package/dist/{host-resolution-DVSb7kXb.js → host-resolution-D8GhEVoX.js} +4 -4
  42. package/dist/{host-resolution-DVSb7kXb.js.map → host-resolution-D8GhEVoX.js.map} +1 -1
  43. package/dist/install-Bw8tvDvS.js +2 -0
  44. package/dist/{install-Bk5TNk27.js → install-paPCzPHI.js} +26 -93
  45. package/dist/install-paPCzPHI.js.map +1 -0
  46. package/dist/interactive-tdxZKWax.js +11 -0
  47. package/dist/interactive-tdxZKWax.js.map +1 -0
  48. package/dist/{links-9LWZPSCq.js → links-Cyj6v8kg.js} +3 -3
  49. package/dist/{links-9LWZPSCq.js.map → links-Cyj6v8kg.js.map} +1 -1
  50. package/dist/{main-DKPjFHEV.js → main-0p-YxUNa.js} +204 -469
  51. package/dist/main-0p-YxUNa.js.map +1 -0
  52. package/dist/{mcp-Co8VRF62.js → mcp-D3Z5MXhA.js} +3 -4
  53. package/dist/{mcp-Co8VRF62.js.map → mcp-D3Z5MXhA.js.map} +1 -1
  54. package/dist/mcp-install-smoke-test.ts +2 -2
  55. package/dist/{mcp-prompt-streaming-ljCVoQ9I.js → mcp-prompt-streaming-COVbWnHt.js} +12 -12
  56. package/dist/mcp-prompt-streaming-COVbWnHt.js.map +1 -0
  57. package/dist/mode-label-DB3ol_sj.js +9 -0
  58. package/dist/mode-label-DB3ol_sj.js.map +1 -0
  59. package/dist/{models-Dba8ITeo.js → models-D1SnCzvl.js} +2 -2
  60. package/dist/{models-Dba8ITeo.js.map → models-D1SnCzvl.js.map} +1 -1
  61. package/dist/non-interactive-DxRBc73O.js +18 -0
  62. package/dist/non-interactive-DxRBc73O.js.map +1 -0
  63. package/dist/{oauth-session-D-RfcVmr.js → oauth-session-Dde79Ycm.js} +3 -3
  64. package/dist/{oauth-session-D-RfcVmr.js.map → oauth-session-Dde79Ycm.js.map} +1 -1
  65. package/dist/{orchestrator-tools-CVJ1F9Ub.js → orchestrator-tools-BSNhzzkT.js} +3 -3
  66. package/dist/{orchestrator-tools-CVJ1F9Ub.js.map → orchestrator-tools-BSNhzzkT.js.map} +1 -1
  67. package/dist/{package-json-Cowya9-3.js → package-json-2UrhE6kP.js} +1 -1
  68. package/dist/{package-json-Cowya9-3.js.map → package-json-2UrhE6kP.js.map} +1 -1
  69. package/dist/package-json-Dblip2_X.js +2 -0
  70. package/dist/package-manager-BRXlXo0p.js +105 -0
  71. package/dist/package-manager-BRXlXo0p.js.map +1 -0
  72. package/dist/{pi-B5YTBRDv.js → pi-cM_4Gd_9.js} +16 -18
  73. package/dist/pi-cM_4Gd_9.js.map +1 -0
  74. package/dist/playground-DTKy0XHT.js +12 -0
  75. package/dist/playground-DTKy0XHT.js.map +1 -0
  76. package/dist/posthog-integration-bwHwE87a.js +10291 -0
  77. package/dist/posthog-integration-bwHwE87a.js.map +1 -0
  78. package/dist/programs-BhtyA3lE.js +3 -0
  79. package/dist/programs-SeT1qNik.js +5348 -0
  80. package/dist/programs-SeT1qNik.js.map +1 -0
  81. package/dist/provisioning-BcXfeCMc.js +2 -0
  82. package/dist/{provisioning-CLhuKqXH.js → provisioning-JbJtq7hq.js} +4 -5
  83. package/dist/{provisioning-CLhuKqXH.js.map → provisioning-JbJtq7hq.js.map} +1 -1
  84. package/dist/{queue-tools-knnPQP0e.js → queue-tools-BIZSJyt6.js} +6 -8
  85. package/dist/queue-tools-BIZSJyt6.js.map +1 -0
  86. package/dist/results-DtKICAdz.js +55 -0
  87. package/dist/results-DtKICAdz.js.map +1 -0
  88. package/dist/run-CDurA5tO.js +248 -0
  89. package/dist/run-CDurA5tO.js.map +1 -0
  90. package/dist/run-DDCvLILJ.js +246 -0
  91. package/dist/run-DDCvLILJ.js.map +1 -0
  92. package/dist/run-tool-CTq9OOdT.js +2 -0
  93. package/dist/run-tool-DML8JJvt.js +2420 -0
  94. package/dist/run-tool-DML8JJvt.js.map +1 -0
  95. package/dist/runners-Dhu4pZTN.js +253 -0
  96. package/dist/runners-Dhu4pZTN.js.map +1 -0
  97. package/dist/{security-BvdSFDuM.js → security-DEH8Rn0_.js} +5 -5
  98. package/dist/security-DEH8Rn0_.js.map +1 -0
  99. package/dist/setup-utils-C5-WM-hS.js +118 -0
  100. package/dist/setup-utils-C5-WM-hS.js.map +1 -0
  101. package/dist/smoke-test.sh +1 -1
  102. package/dist/{playground-BLsCfHmQ.js → start-playground-DL4mVEUx.js} +43 -34
  103. package/dist/start-playground-DL4mVEUx.js.map +1 -0
  104. package/dist/{subagent-D_Sqak94.js → subagent-CnFvAq6E.js} +3 -3
  105. package/dist/{subagent-D_Sqak94.js.map → subagent-CnFvAq6E.js.map} +1 -1
  106. package/dist/{task-DiTI6Sak.js → task-BOScSm4W.js} +16 -17
  107. package/dist/task-BOScSm4W.js.map +1 -0
  108. package/dist/{tasks-ChZ_F1YP.js → tasks-BfJhVky2.js} +1 -1
  109. package/dist/tasks-BfJhVky2.js.map +1 -0
  110. package/dist/{telemetry-BNKsDxNS.js → telemetry-CP4rGicd.js} +2 -2
  111. package/dist/{telemetry-BNKsDxNS.js.map → telemetry-CP4rGicd.js.map} +1 -1
  112. package/dist/terminal-J3OD3dN0.js +16162 -0
  113. package/dist/terminal-J3OD3dN0.js.map +1 -0
  114. package/dist/tools-CCMV3DmB.js +544 -0
  115. package/dist/tools-CCMV3DmB.js.map +1 -0
  116. package/dist/{tools-C8LQ8QFz.js → tools-Cz8tDptL.js} +9 -9
  117. package/dist/tools-Cz8tDptL.js.map +1 -0
  118. package/dist/tui-BUZ2PWqN.js +2 -0
  119. package/dist/tui-Csf7VJxt.js +25 -0
  120. package/dist/tui-Csf7VJxt.js.map +1 -0
  121. package/dist/{steps-Hc28zVc_.js → upload-step-CEacB2RV.js} +14 -16
  122. package/dist/upload-step-CEacB2RV.js.map +1 -0
  123. package/dist/{urls-BI4kJ4qQ.js → urls-BDELGZHq.js} +2 -2
  124. package/dist/{urls-BI4kJ4qQ.js.map → urls-BDELGZHq.js.map} +1 -1
  125. package/dist/warlock-smoke-test.ts +1 -2
  126. package/dist/{wizard-abort-DBKtfnBR.js → wizard-abort-D3-75KyV.js} +40 -33
  127. package/dist/wizard-abort-D3-75KyV.js.map +1 -0
  128. package/dist/yara-hooks-CZ1tKxy_.js +2 -0
  129. package/dist/{yara-hooks-C3L6lBij.js → yara-hooks-D8YDyX7o.js} +283 -21
  130. package/dist/yara-hooks-D8YDyX7o.js.map +1 -0
  131. package/package.json +6 -6
  132. package/dist/PickerMenu-m4CCPX4f.js.map +0 -1
  133. package/dist/agent-BkBbVuNq.js +0 -3189
  134. package/dist/agent-BkBbVuNq.js.map +0 -1
  135. package/dist/agent-QGK2YzlX.js +0 -6
  136. package/dist/agent-interface-CzyCmp7q.js.map +0 -1
  137. package/dist/agent-prompt-loader-4wMxlYSX.js.map +0 -1
  138. package/dist/analytics-B6q5PN7a.js +0 -301
  139. package/dist/analytics-B6q5PN7a.js.map +0 -1
  140. package/dist/analytics-BXtfK9o7.js +0 -2
  141. package/dist/api-C3Dc4LFl.js.map +0 -1
  142. package/dist/api-yNjrfZs2.js +0 -2
  143. package/dist/check-screens.tsx +0 -190
  144. package/dist/ci-install-DfcAMhlu.js.map +0 -1
  145. package/dist/constants-DO4X70po.js +0 -260
  146. package/dist/constants-DO4X70po.js.map +0 -1
  147. package/dist/debug-BueK5mRR.js +0 -2
  148. package/dist/debug-DyARf5TF.js.map +0 -1
  149. package/dist/defaults-DpfMnH2q.js.map +0 -1
  150. package/dist/endpoints-D-4KxZiB.js +0 -108
  151. package/dist/endpoints-D-4KxZiB.js.map +0 -1
  152. package/dist/env-api-key-CHGLe0iz.js +0 -2
  153. package/dist/env-api-key-COf0U-Au.js +0 -17
  154. package/dist/env-api-key-COf0U-Au.js.map +0 -1
  155. package/dist/environment-DrLaSsA8.js +0 -39
  156. package/dist/environment-DrLaSsA8.js.map +0 -1
  157. package/dist/environment-hBj7ngmO.js +0 -2
  158. package/dist/file-CVA9ocIC.js +0 -60
  159. package/dist/file-CVA9ocIC.js.map +0 -1
  160. package/dist/file-CmoKK_Pp.js +0 -2
  161. package/dist/file-watcher-C3Su8vXm.js +0 -123
  162. package/dist/file-watcher-C3Su8vXm.js.map +0 -1
  163. package/dist/gateway-BmjYUSua.js.map +0 -1
  164. package/dist/headless-ui-CUbv12Yx.js +0 -44
  165. package/dist/headless-ui-CUbv12Yx.js.map +0 -1
  166. package/dist/install-Bk5TNk27.js.map +0 -1
  167. package/dist/install-F4wm3RSl.js +0 -2
  168. package/dist/interactive-C5LNvDj6.js +0 -11
  169. package/dist/interactive-C5LNvDj6.js.map +0 -1
  170. package/dist/local-dev-McsurOC-.js +0 -135
  171. package/dist/local-dev-McsurOC-.js.map +0 -1
  172. package/dist/logging-ui-p6XKVmTx.js +0 -226
  173. package/dist/logging-ui-p6XKVmTx.js.map +0 -1
  174. package/dist/main-DKPjFHEV.js.map +0 -1
  175. package/dist/mcp-prompt-streaming-ljCVoQ9I.js.map +0 -1
  176. package/dist/mint-failure-C0HyvEwO.js +0 -6403
  177. package/dist/mint-failure-C0HyvEwO.js.map +0 -1
  178. package/dist/non-interactive-CLMJrj_7.js +0 -18
  179. package/dist/non-interactive-CLMJrj_7.js.map +0 -1
  180. package/dist/package-json--ppioh2F.js +0 -2
  181. package/dist/pi-B5YTBRDv.js.map +0 -1
  182. package/dist/playground-BLsCfHmQ.js.map +0 -1
  183. package/dist/posthog-B2E0hpZt.js +0 -2
  184. package/dist/posthog-B42rt_1S.js +0 -124
  185. package/dist/posthog-B42rt_1S.js.map +0 -1
  186. package/dist/project-data--L-WZyvj.js +0 -2
  187. package/dist/project-data-BO9IXn9y.js +0 -1131
  188. package/dist/project-data-BO9IXn9y.js.map +0 -1
  189. package/dist/provisioning-C01REIU2.js +0 -2
  190. package/dist/queue-tools-knnPQP0e.js.map +0 -1
  191. package/dist/registry-B3rC5U4b.js +0 -3464
  192. package/dist/registry-B3rC5U4b.js.map +0 -1
  193. package/dist/registry-BamsM7J9.js +0 -2
  194. package/dist/run-agent-legacy-CwUmPfQF.js +0 -2
  195. package/dist/run-agent-legacy-DWBajsMh.js +0 -3467
  196. package/dist/run-agent-legacy-DWBajsMh.js.map +0 -1
  197. package/dist/runners-D1PqqpjA.js +0 -834
  198. package/dist/runners-D1PqqpjA.js.map +0 -1
  199. package/dist/security-BvdSFDuM.js.map +0 -1
  200. package/dist/setup-utils-ChXXTi1m.js +0 -301
  201. package/dist/setup-utils-ChXXTi1m.js.map +0 -1
  202. package/dist/start-tui-DicLfgsj.js +0 -6964
  203. package/dist/start-tui-DicLfgsj.js.map +0 -1
  204. package/dist/steps-Hc28zVc_.js.map +0 -1
  205. package/dist/store-COCO6U0P.js +0 -5
  206. package/dist/store-D3509G87.js +0 -1030
  207. package/dist/store-D3509G87.js.map +0 -1
  208. package/dist/task-DiTI6Sak.js.map +0 -1
  209. package/dist/task-status-CmrrR7zo.js +0 -16
  210. package/dist/task-status-CmrrR7zo.js.map +0 -1
  211. package/dist/task-stream-BckhG_cB.js +0 -363
  212. package/dist/task-stream-BckhG_cB.js.map +0 -1
  213. package/dist/tasks-ChZ_F1YP.js.map +0 -1
  214. package/dist/terminal-PK9bCLRi.js +0 -7222
  215. package/dist/terminal-PK9bCLRi.js.map +0 -1
  216. package/dist/tools-C8LQ8QFz.js.map +0 -1
  217. package/dist/ui-tPNpM6vj.js +0 -15
  218. package/dist/ui-tPNpM6vj.js.map +0 -1
  219. package/dist/version-5_ydHkM6.js +0 -6
  220. package/dist/version-5_ydHkM6.js.map +0 -1
  221. package/dist/wizard-abort-BVjqLyeA.js +0 -3
  222. package/dist/wizard-abort-DBKtfnBR.js.map +0 -1
  223. package/dist/wizard-session-B7BHnay0.js +0 -2
  224. package/dist/wizard-session-BYw6LzpS.js +0 -133
  225. package/dist/wizard-session-BYw6LzpS.js.map +0 -1
  226. package/dist/yara-hooks-C3L6lBij.js.map +0 -1
  227. package/dist/yara-hooks-CF_IsoaA.js +0 -2
@@ -1,13 +1,11 @@
1
- import { a as getLogFilePath, o as initLogFile, r as debug, s as logToFile, v as runtimeEnv } from "./debug-DyARf5TF.js";
2
- import { Y as WIZARD_REMARK_EVENT_NAME, c as CONTEXT_MILL_URL, et as wizardUserAgentForProgram, o as AWS_SKILLS_BASE_URL } from "./constants-DO4X70po.js";
3
- import { n as analytics } from "./analytics-B6q5PN7a.js";
4
- import { i as classifyAuthFailure } from "./errors-C2domSkK.js";
5
- import { a as safeReadFile, i as readProjectFile, o as walkProjectFiles } from "./bounded-fs-CC_NDtoP.js";
6
- import { t as registerCleanup } from "./wizard-abort-DBKtfnBR.js";
7
- import { c as REMARK_INSTRUCTION, f as gatewayAuth, i as gatewayApiFor, l as RESUME_INSTRUCTION, n as buildGatewayModel, p as isPastRefresh, s as AgentSignals, u as buildWizardPropertiesBlob } from "./gateway-BmjYUSua.js";
8
- import { i as modelCapabilities, o as triageModelFor } from "./models-Dba8ITeo.js";
9
- import { _ as coerceAuditChecks, h as AUDIT_CHECKS_FILE, l as prewarmYaraScanner, n as createPostToolUseYaraHooks, p as scanInstalledSkill, r as createPreToolUseYaraHooks } from "./yara-hooks-C3L6lBij.js";
10
- import { l as buildOrchestratorTools, v as makeMutex, y as writeJsonAtomic } from "./queue-tools-knnPQP0e.js";
1
+ import { a as initLogFile, i as getLogFilePath, o as logToFile, r as formatLogLine, v as runtimeEnv } from "./debug-BfQPD2Hg.js";
2
+ import { $ as WIZARD_REMARK_EVENT_NAME, it as wizardUserAgentForProgram, l as AWS_SKILLS_BASE_URL, n as analytics } from "./analytics-D21z3E5l.js";
3
+ import { i as classifyAuthFailure } from "./errors-CHrJzAZb.js";
4
+ import { a as safeReadFile, i as readProjectFile, o as walkProjectFiles } from "./bounded-fs-CAsuF6al.js";
5
+ import { c as REMARK_INSTRUCTION, d as gatewayAuth, f as isPastRefresh, i as gatewayApiFor, l as RESUME_INSTRUCTION, n as buildGatewayModel, s as AgentSignals, u as buildWizardPropertiesBlob } from "./gateway-D3gIlR6b.js";
6
+ import { i as modelCapabilities, o as triageModelFor } from "./models-D1SnCzvl.js";
7
+ import { _ as makeMutex, l as buildOrchestratorTools, v as writeJsonAtomic } from "./queue-tools-BIZSJyt6.js";
8
+ import { C as coerceAuditChecks, _ as downloadSkill, l as prewarmYaraScanner, n as createPostToolUseYaraHooks, p as scanInstalledSkill, r as createPreToolUseYaraHooks, x as AUDIT_CHECKS_FILE, y as fetchSkillMenu } from "./yara-hooks-D8YDyX7o.js";
11
9
  import { createRequire } from "node:module";
12
10
  import * as fs$1 from "fs";
13
11
  import fs from "fs";
@@ -15,14 +13,10 @@ import path from "path";
15
13
  import path$1 from "node:path";
16
14
  import { spawnSync } from "node:child_process";
17
15
  import { closeSync, constants, fchmodSync, lstatSync, openSync, renameSync, unlinkSync, writeSync } from "node:fs";
18
- import { randomUUID } from "crypto";
19
- import { randomBytes, randomUUID as randomUUID$1 } from "node:crypto";
16
+ import { randomBytes, randomUUID } from "node:crypto";
20
17
  import * as os from "os";
21
- import { unzipSync } from "fflate";
18
+ import { randomUUID as randomUUID$1 } from "crypto";
22
19
  import { z } from "zod";
23
- //#region \0rolldown/runtime.js
24
- var __require = /* @__PURE__ */ createRequire(import.meta.url);
25
- //#endregion
26
20
  //#region src/agent/triage-provider.ts
27
21
  const TRIAGE_MAX_TOKENS = 16384;
28
22
  const TRIAGE_TIMEOUT_MS = 2e4;
@@ -73,40 +67,19 @@ function createTriageLLMProvider(auth, harness) {
73
67
  }
74
68
  };
75
69
  }
76
- //#endregion
77
- //#region src/shared/ask-policy.ts
78
- /**
79
- * Decide whether the `wizard_ask` overlay should be wired for this run.
80
- * Disabled in non-interactive modes (CI, signup) — there's no human to
81
- * answer. Per-program disabling is done by adding WIZARD_ASK_TOOL_NAME to
82
- * the program's `disallowedTools` so the SDK rejects calls outright.
83
- * Extracted so the policy can be unit-tested directly.
84
- *
85
- * `e2eAsk` is the one escape hatch. The e2e harness runs a `ci`
86
- * session, but it does have an answerer — the driver loop answers each
87
- * `wizard_ask` batch from the program's e2e profile. Without the flag the
88
- * agent-in-the-loop layer (the ask bridge in both sequence arms, and the
89
- * orchestrator's seeded warehouse task) stays unreachable from a test.
90
- *
91
- * Only the e2e TUI host sets the flag, from the `E2E_ASK` env var. No CLI flag
92
- * populates it, so plain `--ci` and `--signup` runs behave exactly as before.
93
- */
94
- function shouldDisableAsk(flags) {
95
- return (flags.ci || flags.signup) && !flags.e2eAsk;
96
- }
97
- /**
98
- * The longer per-question timeout, for asks that send the user on an errand —
99
- * open a database console, mint a restricted API key. The default above is
100
- * sized for a question answerable from memory and expires long before an
101
- * errand is done.
102
- */
103
- const LONGER_ASK_TIMEOUT_MS = 1200 * 1e3;
104
70
  /** A scan retains at most this many distinct key names. */
105
71
  const MAX_ENV_KEY_SET = 5e3;
106
72
  /** Files whose names start with `.env` carry env keys (`.env.local`, `.env.production`, …). */
107
73
  function isEnvFileName(name) {
108
74
  return name.startsWith(".env");
109
75
  }
76
+ /** Committed template names; see {@link isTemplateEnvFileName}. */
77
+ const TEMPLATE_ENV_FILE_NAMES = [
78
+ ".env.example",
79
+ ".env.sample",
80
+ ".env.template",
81
+ ".env.dist"
82
+ ];
110
83
  /**
111
84
  * Committed template files: `.env.example` and its conventional siblings. They
112
85
  * document the keys a project expects and hold placeholders, not credentials,
@@ -120,7 +93,7 @@ function isEnvFileName(name) {
120
93
  * key, not a project that has it.
121
94
  */
122
95
  function isTemplateEnvFileName(name) {
123
- return /^\.env\.(example|sample|template|dist)$/.test(name);
96
+ return TEMPLATE_ENV_FILE_NAMES.includes(name);
124
97
  }
125
98
  /**
126
99
  * Extract KEY NAMES from a dotenv file's content. Values are intentionally
@@ -742,18 +715,46 @@ function evaluateBashCommand(rawCommand) {
742
715
  return commandDecision(normalized);
743
716
  }
744
717
  //#endregion
718
+ //#region src/shared/ask-policy.ts
719
+ /**
720
+ * Decide whether the `wizard_ask` overlay should be wired for this run.
721
+ * Disabled in non-interactive modes (CI, signup) — there's no human to
722
+ * answer. Per-program disabling is done by adding WIZARD_ASK_TOOL_NAME to
723
+ * the program's `disallowedTools` so the SDK rejects calls outright.
724
+ * Extracted so the policy can be unit-tested directly.
725
+ *
726
+ * `e2eAsk` is the one escape hatch. The e2e harness runs a `ci`
727
+ * session, but it does have an answerer — the driver loop answers each
728
+ * `wizard_ask` batch from the program's e2e profile. Without the flag the
729
+ * agent-in-the-loop layer (the ask bridge in both sequence arms, and the
730
+ * orchestrator's seeded warehouse task) stays unreachable from a test.
731
+ *
732
+ * Only the e2e TUI host sets the flag, from the `E2E_ASK` env var. No CLI flag
733
+ * populates it, so plain `--ci` and `--signup` runs behave exactly as before.
734
+ */
735
+ function shouldDisableAsk(flags) {
736
+ return (flags.ci || flags.signup) && !flags.e2eAsk;
737
+ }
738
+ /**
739
+ * The longer per-question timeout, for asks that send the user on an errand —
740
+ * open a database console, mint a restricted API key. The default above is
741
+ * sized for a question answerable from memory and expires long before an
742
+ * errand is done.
743
+ */
744
+ const LONGER_ASK_TIMEOUT_MS = 1200 * 1e3;
745
+ //#endregion
745
746
  //#region src/agent/wizard-ask-bridge.ts
746
747
  /**
747
748
  * WizardAskBridge — host-side promise broker for the `wizard_ask` MCP tool.
748
749
  *
749
- * The `wizard_ask` tool needs to (a) read information from the wizard
750
- * session (the active skill id, used as the analytics `source`) and
751
- * (b) drive the TUI overlay. Wiring `wizard-tools.ts` directly to either
752
- * would couple our pure-data MCP server to the runtime UI layer.
750
+ * The `wizard_ask` tool needs to (a) know the run's skill id, used as the
751
+ * analytics `source`, and (b) put questions to whoever answers them. Wiring
752
+ * the tools directly to either would couple our pure-data MCP server to its
753
+ * host.
753
754
  *
754
- * The bridge is the seam: `wizard-tools.ts` depends on this interface,
755
- * and `agent-runner.ts` constructs an implementation that knows about
756
- * both the session and `getUI()`.
755
+ * The bridge is the seam: the wizard tools depend on this interface, and
756
+ * the runner builds an implementation over the caller's `AgentInteraction`
757
+ * (see `runner/shared/ask.ts`).
757
758
  */
758
759
  /** Sentinel returned for unanswered fields on cancellation or timeout. */
759
760
  const CANCELLED_SENTINEL = "__cancelled__";
@@ -781,7 +782,7 @@ function createWizardAskBridge(opts) {
781
782
  timedOut: false
782
783
  };
783
784
  const pending = {
784
- id: randomUUID(),
785
+ id: randomUUID$1(),
785
786
  questions,
786
787
  source: opts.getSource(),
787
788
  richLinks: opts.richLinks ?? false,
@@ -855,277 +856,6 @@ function createWizardAskBridge(opts) {
855
856
  }
856
857
  };
857
858
  }
858
- //#endregion
859
- //#region src/shared/fetch-retry.ts
860
- /**
861
- * One retry + failover policy for every critical-path fetch. GitHub is primary,
862
- * AWS is the fallback. A status a retry can't heal (404, 403) spends no retry
863
- * budget at the origin that returned it — but it still costs the other origin
864
- * one try, because the two are published separately and GitHub 403s expired
865
- * asset redirects and blocked regions where the asset is present.
866
- */
867
- const DEFAULT_TIMEOUT_MS = 6e4;
868
- const DEFAULT_MAX_ATTEMPTS = 3;
869
- const DEFAULT_BACKOFF_MS = 500;
870
- const GITHUB_LATEST_PREFIX = `${CONTEXT_MILL_URL}/releases/latest/download/`;
871
- const GITHUB_PINNED_PREFIX = `${CONTEXT_MILL_URL}/releases/download/`;
872
- /** Version-pinned URLs name their own prefix, so they need the host alone. */
873
- const AWS_ORIGIN = new URL(AWS_SKILLS_BASE_URL).origin;
874
- function sleep(ms) {
875
- return new Promise((resolve) => setTimeout(resolve, ms));
876
- }
877
- /**
878
- * Maps a context-mill release URL onto AWS; null when there is no second origin.
879
- *
880
- * .../releases/latest/download/x.zip -> <aws>/latest/x.zip
881
- * .../releases/download/v1.50.0/x.zip -> <aws>/v1.50.0/x.zip
882
- */
883
- function awsUrlFor(url) {
884
- if (url.startsWith(GITHUB_LATEST_PREFIX)) return `${AWS_SKILLS_BASE_URL}/${url.slice(GITHUB_LATEST_PREFIX.length)}`;
885
- if (url.startsWith(GITHUB_PINNED_PREFIX)) return `${AWS_ORIGIN}/${url.slice(GITHUB_PINNED_PREFIX.length)}`;
886
- return null;
887
- }
888
- /** Sticky: without it every asset re-pays GitHub's retry budget during an outage. */
889
- let preferredOrigin = "github";
890
- /** A response status that retrying can't fix; propagates past the retry loop. */
891
- var NonRetryableFetchError = class extends Error {};
892
- /**
893
- * 5xx are transient; 408 (request timeout) and 429 (rate limit) explicitly ask
894
- * to retry. Every other 4xx is a client error a retry won't heal (404 missing
895
- * skill, 403 bad token) — retrying only burns the backoff before failing.
896
- */
897
- function isRetryableStatus(status) {
898
- return status >= 500 || status === 408 || status === 429;
899
- }
900
- function messageOf(err) {
901
- return err instanceof Error ? err.message : String(err);
902
- }
903
- /** Try one origin to exhaustion. */
904
- async function fetchOrigin(url, opts) {
905
- const failures = [];
906
- for (let attempt = 1; attempt <= opts.maxAttempts; attempt++) try {
907
- const resp = await opts.fetchImpl(url, { signal: AbortSignal.timeout(opts.timeoutMs) });
908
- if (resp.ok) return resp;
909
- const msg = `HTTP ${resp.status} ${resp.statusText}`.trim();
910
- if (!isRetryableStatus(resp.status)) throw new NonRetryableFetchError(msg);
911
- throw new Error(msg);
912
- } catch (err) {
913
- if (err instanceof NonRetryableFetchError) throw err;
914
- failures.push(`attempt ${attempt}: ${messageOf(err)}`);
915
- if (attempt < opts.maxAttempts) await opts.sleepImpl(opts.backoffMs * 2 ** (attempt - 1));
916
- }
917
- throw new Error(failures.join("; "));
918
- }
919
- /**
920
- * Retry with backoff, then fail over. Throws once every origin is exhausted.
921
- */
922
- async function fetchWithRetry(url, opts = {}) {
923
- const { fetchImpl = fetch, sleepImpl = sleep, timeoutMs = DEFAULT_TIMEOUT_MS, maxAttempts = DEFAULT_MAX_ATTEMPTS, backoffMs = DEFAULT_BACKOFF_MS, failover = true, onEvent = (event, props) => analytics.wizardCapture(event, props) } = opts;
924
- const originOpts = {
925
- fetchImpl,
926
- sleepImpl,
927
- timeoutMs,
928
- maxAttempts,
929
- backoffMs
930
- };
931
- const awsUrl = failover ? awsUrlFor(url) : null;
932
- if (!awsUrl) try {
933
- return await fetchOrigin(url, originOpts);
934
- } catch (err) {
935
- throw new Error(`fetch ${url} failed — ${messageOf(err)}`);
936
- }
937
- const order = preferredOrigin === "aws" ? [{
938
- origin: "aws",
939
- target: awsUrl
940
- }, {
941
- origin: "github",
942
- target: url
943
- }] : [{
944
- origin: "github",
945
- target: url
946
- }, {
947
- origin: "aws",
948
- target: awsUrl
949
- }];
950
- const failures = [];
951
- for (const [index, candidate] of order.entries()) try {
952
- const resp = await fetchOrigin(candidate.target, originOpts);
953
- if (candidate.origin !== preferredOrigin) {
954
- preferredOrigin = candidate.origin;
955
- logToFile(`fetchWithRetry: failed over to ${candidate.origin}`);
956
- onEvent("skills fetch failed over", {
957
- origin: candidate.origin,
958
- url: candidate.target
959
- });
960
- }
961
- return resp;
962
- } catch (err) {
963
- failures.push(`${candidate.origin}: ${messageOf(err)}`);
964
- if (index === order.length - 1) onEvent("skills fetch failed", {
965
- url,
966
- failures: failures.length
967
- });
968
- }
969
- throw new Error(`fetch ${url} failed — ${failures.join(" | ")}`);
970
- }
971
- //#endregion
972
- //#region src/shared/skill-menu.ts
973
- /**
974
- * The skill menu: what context-mill publishes as `skill-menu.json` and how the
975
- * wizard reads it. Skill-backed CLI commands, the family picker, the skill
976
- * source screen and the agent's install path all resolve skills through this
977
- * one fetch, so it lives in shared and depends on nothing in the agent.
978
- */
979
- /** Expand a bundle entry into one entry per variant, so the menu reads the same whether a group ships bundled or as zips. */
980
- function expandBundleEntry(entry) {
981
- if (!entry.bundle || !entry.variants) return [entry];
982
- return entry.variants.map((variant) => ({
983
- ...variant,
984
- name: entry.name,
985
- group: entry.group,
986
- bundle: true,
987
- downloadUrl: entry.downloadUrl
988
- }));
989
- }
990
- /**
991
- * Fetch the skill menu from the skills server.
992
- * Returns parsed data on success, `null` on failure.
993
- */
994
- async function fetchSkillMenu(skillsBaseUrl, opts = {}) {
995
- const menuUrl = `${skillsBaseUrl}/skill-menu.json`;
996
- try {
997
- logToFile(`fetchSkillMenu: fetching from ${menuUrl}`);
998
- const data = await (await fetchWithRetry(menuUrl, opts)).json();
999
- for (const [category, entries] of Object.entries(data.categories)) data.categories[category] = entries.flatMap(expandBundleEntry);
1000
- logToFile(`fetchSkillMenu: loaded (${Object.keys(data.categories).length} categories)`);
1001
- return data;
1002
- } catch (err) {
1003
- logToFile(`fetchSkillMenu: error: ${err.message}`);
1004
- return null;
1005
- }
1006
- }
1007
- //#endregion
1008
- //#region src/agent/tools/tools.ts
1009
- /**
1010
- * Shared wizard-tool behavior — skill discovery/install, env-file helpers,
1011
- * the wizard_ask cap policy, secret-vault plumbing, and the audit ledger.
1012
- * One implementation consumed by both protocol facades: the MCP server
1013
- * (`./mcp`) and the pi-native tools (`harness/pi/tools.ts`) — tool behavior
1014
- * cannot drift between harnesses.
1015
- */
1016
- /** Extract a zip buffer, refusing entries that escape destDir (zip-slip). */
1017
- function extractZipArchive(zip, destDir) {
1018
- const root = path.resolve(destDir);
1019
- let written = 0;
1020
- for (const [entryPath, data] of Object.entries(unzipSync(zip))) {
1021
- const target = path.resolve(root, entryPath);
1022
- if (target !== root && !target.startsWith(root + path.sep)) throw new Error(`zip entry escapes destination: ${entryPath}`);
1023
- if (entryPath.endsWith("/")) {
1024
- fs.mkdirSync(target, { recursive: true });
1025
- continue;
1026
- }
1027
- fs.mkdirSync(path.dirname(target), { recursive: true });
1028
- fs.writeFileSync(target, data);
1029
- written++;
1030
- }
1031
- return written;
1032
- }
1033
- /** Unpack the one variant this entry names out of a bundle; the rest is noise and never hits disk. */
1034
- function extractBundle(bundle, destDir, entryId) {
1035
- if (typeof bundle?.id !== "string" || typeof bundle?.variants !== "object" || bundle.variants === null) throw new Error("malformed bundle: expected { id, variants }");
1036
- const files = bundle.variants[entryId.slice(bundle.id.length + 1)];
1037
- if (!files) throw new Error(`bundle ${bundle.id} has no variant "${entryId}"`);
1038
- const root = path.resolve(destDir);
1039
- let written = 0;
1040
- for (const [entryPath, contents] of Object.entries(files)) {
1041
- const target = path.resolve(root, entryPath);
1042
- if (target !== root && !target.startsWith(root + path.sep)) throw new Error(`bundle entry escapes destination: ${entryPath}`);
1043
- fs.mkdirSync(path.dirname(target), { recursive: true });
1044
- fs.writeFileSync(target, contents);
1045
- written++;
1046
- }
1047
- return written;
1048
- }
1049
- /** Download a URL to a buffer, retrying transient failures with backoff. */
1050
- async function downloadWithRetry(url, opts = {}) {
1051
- const resp = await fetchWithRetry(url, opts);
1052
- return new Uint8Array(await resp.arrayBuffer());
1053
- }
1054
- /**
1055
- * Download and extract a skill.
1056
- * By default installs to `<installDir>/.claude/skills/<id>/`.
1057
- */
1058
- async function downloadSkill(skillEntry, installDir, { skillsRoot, triage }) {
1059
- const skillDir = skillsRoot ? path.join(installDir, skillsRoot, skillEntry.id) : path.join(installDir, ".claude", "skills", skillEntry.id);
1060
- let step = "download";
1061
- try {
1062
- fs.mkdirSync(skillDir, { recursive: true });
1063
- const data = await downloadWithRetry(skillEntry.downloadUrl);
1064
- step = "extract";
1065
- const fileCount = skillEntry.bundle ? extractBundle(JSON.parse(Buffer.from(data).toString("utf8")), skillDir, skillEntry.id) : extractZipArchive(data, skillDir);
1066
- fs.writeFileSync(path.join(skillDir, ".posthog-wizard"), "");
1067
- step = "scan";
1068
- const poisonReason = await scanInstalledSkill(skillDir, triage);
1069
- if (poisonReason) {
1070
- fs.rmSync(skillDir, {
1071
- recursive: true,
1072
- force: true
1073
- });
1074
- logToFile(`downloadSkill: ${poisonReason}`);
1075
- analytics.wizardCapture("skill install failed", {
1076
- skill_id: skillEntry.id,
1077
- step: "scan",
1078
- platform: process.platform,
1079
- error: poisonReason.slice(0, 500)
1080
- });
1081
- return {
1082
- success: false,
1083
- error: poisonReason
1084
- };
1085
- }
1086
- logToFile(`downloadSkill: installed ${skillEntry.id} from ${skillEntry.downloadUrl} (${fileCount} files)`);
1087
- analytics.wizardCapture("skill installed", {
1088
- skill_id: skillEntry.id,
1089
- platform: process.platform
1090
- });
1091
- return { success: true };
1092
- } catch (err) {
1093
- logToFile(`downloadSkill: error: ${err.message}`);
1094
- analytics.wizardCapture("skill install failed", {
1095
- skill_id: skillEntry.id,
1096
- step,
1097
- platform: process.platform,
1098
- error: String(err.message).slice(0, 500)
1099
- });
1100
- return {
1101
- success: false,
1102
- error: err.message
1103
- };
1104
- }
1105
- }
1106
- /**
1107
- * High-level "install a skill by ID" helper. Fetches the skill menu,
1108
- * finds the skill, downloads and extracts it. Programs should use this
1109
- * instead of composing fetchSkillMenu + downloadSkill themselves.
1110
- */
1111
- async function installSkillById(skillId, installDir, skillsBaseUrl, options) {
1112
- const menu = await fetchSkillMenu(skillsBaseUrl);
1113
- if (!menu) return { kind: "menu-fetch-failed" };
1114
- const skill = Object.values(menu.categories).flat().find((s) => s.id === skillId);
1115
- if (!skill) return {
1116
- kind: "skill-not-found",
1117
- skillId
1118
- };
1119
- const result = await downloadSkill(skill, installDir, options);
1120
- if (!result.success) return {
1121
- kind: "download-failed",
1122
- message: result.error ?? "unknown"
1123
- };
1124
- return {
1125
- kind: "ok",
1126
- path: options.skillsRoot ? `${options.skillsRoot}/${skillId}` : `.claude/skills/${skillId}`
1127
- };
1128
- }
1129
859
  /** Subject recorded for a `wizard_ask` call that declares none. */
1130
860
  const ASK_SUBJECT_UNSPECIFIED = "(unspecified)";
1131
861
  /** Longest subject we keep; anything longer is truncated, never rejected. */
@@ -1804,7 +1534,7 @@ function createSecretVault() {
1804
1534
  const store = /* @__PURE__ */ new Map();
1805
1535
  return {
1806
1536
  put(value, meta) {
1807
- const ref = `${REF_PREFIX}${randomUUID()}`;
1537
+ const ref = `${REF_PREFIX}${randomUUID$1()}`;
1808
1538
  store.set(ref, {
1809
1539
  value,
1810
1540
  meta: {
@@ -1980,7 +1710,7 @@ async function createWizardToolsServer(options) {
1980
1710
  }],
1981
1711
  isError: true
1982
1712
  };
1983
- const result = await downloadSkill(skill, workingDirectory, { triage: triageProvider });
1713
+ const result = await downloadSkill(skill, workingDirectory, { scan: (dir) => scanInstalledSkill(dir, triageProvider) });
1984
1714
  if (result.success) return { content: [{
1985
1715
  type: "text",
1986
1716
  text: `Skill installed to .claude/skills/${args.skillId}/`
@@ -2197,7 +1927,8 @@ const WIZARD_COMMANDMENTS = [
2197
1927
  " - For `single` and `multi`, extract the alternatives from the prose into `options` as `{ label, value }` pairs. Use the human phrase as `label` and a lowercase-hyphenated form as `value` (e.g., `label: \"Vanilla JS\"`, `value: \"vanilla-js\"`).",
2198
1928
  " - Use a kebab-case slug of the question label as `id` (e.g., \"Tech stack\" → `tech-stack`, \"Show frequency\" → `show-frequency`).",
2199
1929
  " - Do not invent fields the schema does not define (no `source`, `category`, `priority`, etc.) — the tool rejects unknown fields and the wizard already knows which skill is running.",
2200
- "After `wizard_ask` returns, use the answers directly — do not re-ask in text or call `wizard_ask` again for the same fields."
1930
+ "After `wizard_ask` returns, use the answers directly — do not re-ask in text, and do not call `wizard_ask` again to confirm a field the user already answered.",
1931
+ "Correcting a rejected value is the one exception, and it is expected: when whatever you handed an answer to rejects it — a connection that fails, a host or key the API calls invalid, a permission error — ask again for only the fields that were wrong, reuse the same `subject`, and say what was rejected and what a valid value looks like. A value the user could fix in one keystroke is never a reason to abandon the step for a link they have to follow themselves. Stop after a couple of attempts on one subject. A dismissed or timed-out ask is not this case — the result names the fields it did not collect and why, and that is a decline, so fall back instead of re-asking."
2201
1932
  ].join("\n")
2202
1933
  ];
2203
1934
  //#endregion
@@ -2454,6 +2185,25 @@ var AgentOutputSignals = class {
2454
2185
  }
2455
2186
  };
2456
2187
  //#endregion
2188
+ //#region src/shared/utils/cleanup.ts
2189
+ /** Synchronous work to run before the process exits, such as removing a temp file. */
2190
+ const cleanupFns = [];
2191
+ /** Register `fn` to run on exit; returns a function that unregisters it. */
2192
+ function registerCleanup(fn) {
2193
+ cleanupFns.push(fn);
2194
+ return () => {
2195
+ const index = cleanupFns.indexOf(fn);
2196
+ if (index !== -1) cleanupFns.splice(index, 1);
2197
+ };
2198
+ }
2199
+ /** Runs all registered cleanup functions and drains the array. */
2200
+ function runCleanups() {
2201
+ const fns = cleanupFns.splice(0);
2202
+ for (const fn of fns) try {
2203
+ fn();
2204
+ } catch {}
2205
+ }
2206
+ //#endregion
2457
2207
  //#region src/shared/agent-env-isolation.ts
2458
2208
  /**
2459
2209
  * Credential isolation for the Claude Agent SDK subprocess.
@@ -2609,7 +2359,7 @@ function sanitizeAgentSubprocessEnv(env = process.env) {
2609
2359
  * Claude Code settings handling: conflict detection, backup/restore, and
2610
2360
  * orphan recovery.
2611
2361
  *
2612
- * Lives apart from agent-interface so bin.ts can run orphan recovery at
2362
+ * Lives apart from agent-interface so main.ts can run orphan recovery at
2613
2363
  * process start without dragging in the agent stack (wizard-tools, yara
2614
2364
  * hooks, the SDK loader).
2615
2365
  */
@@ -2817,7 +2567,7 @@ function restoreClaudeSettings(workingDirectory) {
2817
2567
  * skips restore, so the user's settings stay silently gone. Detect that exact
2818
2568
  * state (backup present, original absent) and put the original back.
2819
2569
  *
2820
- * Runs once per process, from bin.ts, before anything reads Claude settings —
2570
+ * Runs once per process, from main.ts, before anything reads Claude settings —
2821
2571
  * conflict detection must see the user's real settings file, and a recovery
2822
2572
  * any later would resurface the conflicting overrides after the backup step
2823
2573
  * already moved them aside.
@@ -2930,7 +2680,7 @@ async function getSDKModule() {
2930
2680
  * This ensures we use the SDK's bundled version rather than the user's installed Claude Code.
2931
2681
  */
2932
2682
  function getClaudeCodeExecutablePath() {
2933
- const sdkPackagePath = (typeof __require !== "undefined" ? __require : createRequire(process.argv[1] ?? `${process.cwd()}/`)).resolve("@anthropic-ai/claude-agent-sdk");
2683
+ const sdkPackagePath = createRequire(import.meta.url).resolve("@anthropic-ai/claude-agent-sdk");
2934
2684
  return path.join(path.dirname(sdkPackagePath), "cli.js");
2935
2685
  }
2936
2686
  /** Region implied by the resolved gateway URL, for telemetry and display. */
@@ -3034,6 +2784,15 @@ function buildAgentEnv(wizardMetadata, wizardFlags, teamId) {
3034
2784
  logToFile("ANTHROPIC_CUSTOM_HEADERS", encoded);
3035
2785
  return encoded;
3036
2786
  }
2787
+ /** A debug run's diagnostic line, as info log progress; a run without `debug` emits nothing. */
2788
+ function debugLine(emit, options, ...args) {
2789
+ if (!options.debug) return;
2790
+ emit({
2791
+ kind: "log",
2792
+ level: "info",
2793
+ message: formatLogLine(...args)
2794
+ });
2795
+ }
3037
2796
  /**
3038
2797
  * Permission hook that allows only safe commands. Bash commands are gated by
3039
2798
  * the exact per-manager fence in bash-fence.ts (install/build/typecheck/lint
@@ -3101,14 +2860,14 @@ function wizardCanUseTool(toolName, input, context = {}) {
3101
2860
  const decision = evaluateBashCommand(command);
3102
2861
  if (decision.allowed) {
3103
2862
  logToFile(`Allowing bash command: ${command}`);
3104
- debug(`Allowing bash command: ${command}`);
2863
+ context.onDebug?.(`Allowing bash command: ${command}`);
3105
2864
  return {
3106
2865
  behavior: "allow",
3107
2866
  updatedInput: input
3108
2867
  };
3109
2868
  }
3110
2869
  logToFile(`Denying bash command (${decision.analyticsReason}): ${command}`);
3111
- debug(`Denying bash command (${decision.analyticsReason}): ${command}`);
2870
+ context.onDebug?.(`Denying bash command (${decision.analyticsReason}): ${command}`);
3112
2871
  analytics.wizardCapture("bash denied", {
3113
2872
  reason: decision.analyticsReason,
3114
2873
  command
@@ -3214,7 +2973,7 @@ async function initializeAgent(config, options) {
3214
2973
  gatewayUrl,
3215
2974
  apiKeyPresent: !!config.posthogApiKey
3216
2975
  });
3217
- if (options.debug) debug("Agent config:", {
2976
+ debugLine(emit, options, "Agent config:", {
3218
2977
  workingDirectory: agentRunConfig.workingDirectory,
3219
2978
  posthogMcpUrl: config.posthogMcpUrl,
3220
2979
  gatewayUrl,
@@ -3229,7 +2988,7 @@ async function initializeAgent(config, options) {
3229
2988
  message: `Failed to initialize agent: ${error.message}`
3230
2989
  });
3231
2990
  logToFile("Agent initialization error:", error);
3232
- debug("Agent initialization error:", error);
2991
+ debugLine(emit, options, "Agent initialization error:", error);
3233
2992
  throw error;
3234
2993
  }
3235
2994
  }
@@ -3371,7 +3130,7 @@ async function runAgent(agentConfig, prompt, options, spinner, config, middlewar
3371
3130
  }, timeoutMs) : void 0;
3372
3131
  try {
3373
3132
  const disallow = new Set(agentConfig.disallowedTools ?? []);
3374
- const allowedTools = (agentConfig.readOnly ? READ_ONLY_TOOLS : [...BASE_ALLOWED_TOOLS, ...agentConfig.allowedTools ?? []]).filter((t) => !disallow.has(t));
3133
+ const allowedTools = (agentConfig.readOnly ? READ_ONLY_TOOLS : [...BASE_ALLOWED_TOOLS, ...agentConfig.allowedTools ?? []]).filter((t) => !disallow.has(t) && !CAN_USE_TOOL_FILE_TOOLS.has(t));
3375
3134
  const inheritedMcpServerNames = Object.keys(agentConfig.mcpServers);
3376
3135
  const triageProvider = agentConfig.triageProvider;
3377
3136
  const onYaraTerminate = (reason) => {
@@ -3406,6 +3165,10 @@ async function runAgent(agentConfig, prompt, options, spinner, config, middlewar
3406
3165
  disallowedTools: agentConfig.disallowedTools ? [...agentConfig.disallowedTools] : void 0
3407
3166
  } },
3408
3167
  settingSources: agentConfig.readOnly ? [] : ["project"],
3168
+ settings: {
3169
+ disableAllHooks: true,
3170
+ permissions: { deny: [...ENV_FILE_DENY_RULES] }
3171
+ },
3409
3172
  skills: agentConfig.readOnly ? [] : "all",
3410
3173
  allowedTools,
3411
3174
  sandbox: {
@@ -3465,7 +3228,8 @@ async function runAgent(agentConfig, prompt, options, spinner, config, middlewar
3465
3228
  const result = wizardCanUseTool(toolName, input, {
3466
3229
  readOnly: agentConfig.readOnly,
3467
3230
  wizardAskPending: agentConfig.getPendingQuestion?.() != null,
3468
- disallowedTools: agentConfig.disallowedTools
3231
+ disallowedTools: agentConfig.disallowedTools,
3232
+ onDebug: (line) => debugLine(emit, options, line)
3469
3233
  });
3470
3234
  logToFile("canUseTool result:", result);
3471
3235
  return Promise.resolve(result);
@@ -3485,7 +3249,7 @@ async function runAgent(agentConfig, prompt, options, spinner, config, middlewar
3485
3249
  },
3486
3250
  stderr: (data) => {
3487
3251
  logToFile("CLI stderr:", data);
3488
- if (options.debug) debug("CLI stderr:", data);
3252
+ debugLine(emit, options, "CLI stderr:", data);
3489
3253
  },
3490
3254
  hooks: {
3491
3255
  PreToolUse: warlockDisabled ? [] : createPreToolUseYaraHooks(triageProvider, onYaraTerminate),
@@ -3786,7 +3550,7 @@ async function runAgent(agentConfig, prompt, options, spinner, config, middlewar
3786
3550
  message: `Error: ${error.message}`
3787
3551
  });
3788
3552
  logToFile("Agent run failed:", error);
3789
- debug("Full error:", error);
3553
+ debugLine(emit, options, "Full error:", error);
3790
3554
  throw error;
3791
3555
  } finally {
3792
3556
  agentConfig.signal?.removeEventListener("abort", onExternalAbort);
@@ -3839,12 +3603,17 @@ const READ_ONLY_TOOLS = [
3839
3603
  "Glob",
3840
3604
  "Grep"
3841
3605
  ];
3842
- const BASE_ALLOWED_TOOLS = [
3606
+ /** wizardCanUseTool's env-file rule as SDK deny rules for the project; outside it, canUseTool sees the file tools. */
3607
+ const ENV_FILE_DENY_RULES = ["Read", "Edit"].flatMap((tool) => [`${tool}(.env*)`, ...TEMPLATE_ENV_FILE_NAMES.map((name) => `${tool}(!${name})`)]);
3608
+ /** The SDK approves these itself inside the project; allowing them would hide calls outside it from canUseTool. */
3609
+ const CAN_USE_TOOL_FILE_TOOLS = new Set([
3843
3610
  "Read",
3844
3611
  "Write",
3845
3612
  "Edit",
3613
+ "Grep"
3614
+ ]);
3615
+ const BASE_ALLOWED_TOOLS = [
3846
3616
  "Glob",
3847
- "Grep",
3848
3617
  "Bash",
3849
3618
  ...Object.values(TaskTool),
3850
3619
  "ListMcpResourcesTool",
@@ -3856,11 +3625,11 @@ function handleTaskCreate(block, store) {
3856
3625
  if (!input?.subject) return;
3857
3626
  let source = taskSources.get(store.tasks);
3858
3627
  if (!source) {
3859
- source = randomUUID$1();
3628
+ source = randomUUID();
3860
3629
  taskSources.set(store.tasks, source);
3861
3630
  }
3862
3631
  store.tasks.set(block.id, {
3863
- id: randomUUID$1(),
3632
+ id: randomUUID(),
3864
3633
  source,
3865
3634
  content: input.subject,
3866
3635
  status: "pending",
@@ -4012,7 +3781,7 @@ function handleSDKMessage(message, options, spinner, signals, emit, receivedSucc
4012
3781
  });
4013
3782
  };
4014
3783
  logToFile(`SDK Message: ${message.type}`, JSON.stringify(message, null, 2));
4015
- if (options.debug) debug(`SDK Message type: ${message.type}`);
3784
+ debugLine(emit, options, `SDK Message type: ${message.type}`);
4016
3785
  switch (message.type) {
4017
3786
  case "assistant": {
4018
3787
  const tokenUsageDelta = extractTokenUsageDelta(message);
@@ -4119,11 +3888,11 @@ function handleSDKMessage(message, options, spinner, signals, emit, receivedSucc
4119
3888
  }
4120
3889
  break;
4121
3890
  default:
4122
- if (options.debug) debug(`Unhandled message type: ${message.type}`);
3891
+ debugLine(emit, options, `Unhandled message type: ${message.type}`);
4123
3892
  break;
4124
3893
  }
4125
3894
  }
4126
3895
  //#endregion
4127
- export { vaultSensitiveAnswers as $, CHECK_ENV_KEYS_FILE_PATH_DESCRIPTION as A, describeAskCancellation as B, AUDIT_ADD_CHECKS_PARAM_DESCRIPTION as C, AUDIT_SEED_CHECKS_PARAM_DESCRIPTION as D, AUDIT_SEED_CHECKS_DESCRIPTION as E, WIZARD_ASK_TOOL_DESCRIPTION as F, mergeEnvValues as G, ensureGitignoreCoverage as H, WIZARD_TOOL_NAMES as I, resolveAuditChecks as J, normaliseAskSubject as K, addAuditChecks as L, WIZARD_ASK_KIND_DESCRIPTION as M, WIZARD_ASK_SENSITIVE_DESCRIPTION as N, AUDIT_STATUSES as O, WIZARD_ASK_SUBJECT_DESCRIPTION as P, templateEnvWriteRefusal as Q, checkEnvKeys as R, AUDIT_ADD_CHECKS_DESCRIPTION as S, AUDIT_RESOLVE_CHECKS_PARAM_DESCRIPTION as T, installSkillById as U, downloadSkill as V, legacyKeyNameRefusal as W, resolveEnvSecretRefs as X, resolveEnvPath as Y, seedAuditChecks as Z, createSecretVault as _, wizardCanUseTool as a, isEnvFileName as at, PUBLISH_HANDOFF_TOOL_NAME as b, checkAllSettingsConflicts as c, LONGER_ASK_TIMEOUT_MS as ct, restoreClaudeSettings as d, fetchSkillMenu as et, sanitizeAgentSubprocessEnv as f, assembleCommandments as g, markGrantRevoked as h, runAgent as i, MAX_ENV_KEY_SET as it, ENV_FILE_PATH_DESCRIPTION as j, CHECK_ENV_KEYS_DESCRIPTION as k, classifySettingsConflicts as l, shouldDisableAsk as lt, isGrantRevoked as m, buildRunTags as n, createWizardAskBridge as nt, createIsolatedAgentConfigDir as o, parseEnvKeyNames as ot, AgentOutputSignals as p, resolveAskQuestionKinds as q, initializeAgent as r, isFullyCancelled as rt, backupAndFixClaudeSettings as s, toPromptSafeRelativePath as st, buildAgentEnv as t, fetchWithRetry as tt, recoverOrphanedSettingsBackups as u, createTriageLLMProvider as ut, PUBLISH_HANDOFF_CONTENT_DESCRIPTION as v, AUDIT_RESOLVE_CHECKS_DESCRIPTION as w, publishHandoff as x, PUBLISH_HANDOFF_DESCRIPTION as y, createAskAccounting as z };
3896
+ export { vaultSensitiveAnswers as $, AUDIT_STATUSES as A, checkEnvKeys as B, publishHandoff as C, AUDIT_RESOLVE_CHECKS_PARAM_DESCRIPTION as D, AUDIT_RESOLVE_CHECKS_DESCRIPTION as E, WIZARD_ASK_SENSITIVE_DESCRIPTION as F, mergeEnvValues as G, describeAskCancellation as H, WIZARD_ASK_SUBJECT_DESCRIPTION as I, resolveAuditChecks as J, normaliseAskSubject as K, WIZARD_ASK_TOOL_DESCRIPTION as L, CHECK_ENV_KEYS_FILE_PATH_DESCRIPTION as M, ENV_FILE_PATH_DESCRIPTION as N, AUDIT_SEED_CHECKS_DESCRIPTION as O, WIZARD_ASK_KIND_DESCRIPTION as P, templateEnvWriteRefusal as Q, WIZARD_TOOL_NAMES as R, PUBLISH_HANDOFF_TOOL_NAME as S, AUDIT_ADD_CHECKS_PARAM_DESCRIPTION as T, ensureGitignoreCoverage as U, createAskAccounting as V, legacyKeyNameRefusal as W, resolveEnvSecretRefs as X, resolveEnvPath as Y, seedAuditChecks as Z, markGrantRevoked as _, wizardCanUseTool as a, isEnvFileName as at, PUBLISH_HANDOFF_CONTENT_DESCRIPTION as b, checkAllSettingsConflicts as c, createTriageLLMProvider as ct, restoreClaudeSettings as d, createWizardAskBridge as et, sanitizeAgentSubprocessEnv as f, isGrantRevoked as g, AgentOutputSignals as h, runAgent as i, MAX_ENV_KEY_SET as it, CHECK_ENV_KEYS_DESCRIPTION as j, AUDIT_SEED_CHECKS_PARAM_DESCRIPTION as k, classifySettingsConflicts as l, runCleanups as m, buildRunTags as n, LONGER_ASK_TIMEOUT_MS as nt, createIsolatedAgentConfigDir as o, parseEnvKeyNames as ot, registerCleanup as p, resolveAskQuestionKinds as q, initializeAgent as r, shouldDisableAsk as rt, backupAndFixClaudeSettings as s, toPromptSafeRelativePath as st, buildAgentEnv as t, isFullyCancelled as tt, recoverOrphanedSettingsBackups as u, assembleCommandments as v, AUDIT_ADD_CHECKS_DESCRIPTION as w, PUBLISH_HANDOFF_DESCRIPTION as x, createSecretVault as y, addAuditChecks as z };
4128
3897
 
4129
- //# sourceMappingURL=agent-interface-CzyCmp7q.js.map
3898
+ //# sourceMappingURL=agent-interface-CemBvTAA.js.map