@posthog/wizard 2.78.0 → 2.79.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 (163) hide show
  1. package/README.md +20 -11
  2. package/dist/PickerMenu-dG5DQCZA.js +758 -0
  3. package/dist/PickerMenu-dG5DQCZA.js.map +1 -0
  4. package/dist/{add-mcp-server-to-clients-JMv8LP-O.js → add-mcp-server-to-clients-DIaTRWMY.js} +7 -18
  5. package/dist/{add-mcp-server-to-clients-JMv8LP-O.js.map → add-mcp-server-to-clients-DIaTRWMY.js.map} +1 -1
  6. package/dist/add-mcp-server-to-clients-artmN7mz.js +2 -0
  7. package/dist/agent-BEjARD2a.js +6 -0
  8. package/dist/{agent-bCZ3i3fh.js → agent-BWFhuLgo.js} +131 -38
  9. package/dist/agent-BWFhuLgo.js.map +1 -0
  10. package/dist/{agent-interface-BAOIHuXS.js → agent-interface-FkbaBJwz.js} +66 -28
  11. package/dist/agent-interface-FkbaBJwz.js.map +1 -0
  12. package/dist/{agent-prompt-loader-7Pd4CfZO.js → agent-prompt-loader-D0weQ-7k.js} +5 -5
  13. package/dist/{agent-prompt-loader-7Pd4CfZO.js.map → agent-prompt-loader-D0weQ-7k.js.map} +1 -1
  14. package/dist/analytics-DFtbRjYh.js +2 -0
  15. package/dist/{analytics-CHCZ_qUR.js → analytics-DXK1gc12.js} +4 -4
  16. package/dist/{analytics-CHCZ_qUR.js.map → analytics-DXK1gc12.js.map} +1 -1
  17. package/dist/api-Cm9UtKZh.js +2 -0
  18. package/dist/{api-Diy_2fp8.js → api-CrbCIQOz.js} +4 -16
  19. package/dist/{api-Diy_2fp8.js.map → api-CrbCIQOz.js.map} +1 -1
  20. package/dist/bin.js +5 -2957
  21. package/dist/bin.js.map +1 -1
  22. package/dist/{bounded-fs-Bx9zTe6m.js → bounded-fs-vAq-T-K7.js} +3 -3
  23. package/dist/{bounded-fs-Bx9zTe6m.js.map → bounded-fs-vAq-T-K7.js.map} +1 -1
  24. package/dist/{ci-install-CDdQYsPe.js → ci-install-COcV8SY2.js} +8 -7
  25. package/dist/ci-install-COcV8SY2.js.map +1 -0
  26. package/dist/{constants-jFI2SaE1.js → constants-DHCBSfnx.js} +3 -3
  27. package/dist/{constants-jFI2SaE1.js.map → constants-DHCBSfnx.js.map} +1 -1
  28. package/dist/{debug-M2gV2iDq.js → debug-BuYHGr6_.js} +1 -1
  29. package/dist/{debug-Ch4BDOtD.js → debug-kAHwWGg7.js} +2 -2
  30. package/dist/{debug-Ch4BDOtD.js.map → debug-kAHwWGg7.js.map} +1 -1
  31. package/dist/{defaults-C6J7yL4O.js → defaults-a9TelDhJ.js} +1 -1
  32. package/dist/{defaults-C6J7yL4O.js.map → defaults-a9TelDhJ.js.map} +1 -1
  33. package/dist/emit-BSetXzDV.js +69 -0
  34. package/dist/emit-BSetXzDV.js.map +1 -0
  35. package/dist/{endpoints-DCVbM06L.js → endpoints-BVMYm9F4.js} +3 -3
  36. package/dist/{endpoints-DCVbM06L.js.map → endpoints-BVMYm9F4.js.map} +1 -1
  37. package/dist/{env-api-key-Qx8NnYHm.js → env-api-key-BP-NFFXt.js} +3 -5
  38. package/dist/{env-api-key-Qx8NnYHm.js.map → env-api-key-BP-NFFXt.js.map} +1 -1
  39. package/dist/env-api-key-CaWEDj_9.js +2 -0
  40. package/dist/{environment-B07Bmxae.js → environment-BATlQxcQ.js} +5 -10
  41. package/dist/{environment-B07Bmxae.js.map → environment-BATlQxcQ.js.map} +1 -1
  42. package/dist/environment-CwD8OPYj.js +2 -0
  43. package/dist/errors-C2domSkK.js +79 -0
  44. package/dist/errors-C2domSkK.js.map +1 -0
  45. package/dist/file-C5JMsyR1.js +2 -0
  46. package/dist/{file-BcLTjU16.js → file-DcRKycV8.js} +4 -4
  47. package/dist/file-DcRKycV8.js.map +1 -0
  48. package/dist/{file-watcher-DWc_bTs6.js → file-watcher-Brq2nnHV.js} +2 -2
  49. package/dist/{file-watcher-DWc_bTs6.js.map → file-watcher-Brq2nnHV.js.map} +1 -1
  50. package/dist/{gateway-CjoShdLa.js → gateway-C9-GlLO9.js} +39 -8
  51. package/dist/gateway-C9-GlLO9.js.map +1 -0
  52. package/dist/{headless-ui-BFFmYC4v.js → headless-ui-CqI2gXlD.js} +2 -2
  53. package/dist/{headless-ui-BFFmYC4v.js.map → headless-ui-CqI2gXlD.js.map} +1 -1
  54. package/dist/{interactive-D6zV7brJ.js → interactive-B_Ti_CsS.js} +3 -3
  55. package/dist/interactive-B_Ti_CsS.js.map +1 -0
  56. package/dist/{logging-ui-_TwoMNbG.js → logging-ui-Dza4D0MK.js} +5 -5
  57. package/dist/{logging-ui-_TwoMNbG.js.map → logging-ui-Dza4D0MK.js.map} +1 -1
  58. package/dist/main-CgKxbwMP.js +1396 -0
  59. package/dist/main-CgKxbwMP.js.map +1 -0
  60. package/dist/{mcp-DAgaoGk5.js → mcp-DnAyW0-w.js} +4 -4
  61. package/dist/{mcp-DAgaoGk5.js.map → mcp-DnAyW0-w.js.map} +1 -1
  62. package/dist/{mcp-prompt-streaming-I2U_X7BC.js → mcp-prompt-streaming-DDWQ-FCA.js} +6 -6
  63. package/dist/mcp-prompt-streaming-DDWQ-FCA.js.map +1 -0
  64. package/dist/{mint-failure-D4nd2XmZ.js → mint-failure-u8xQKNOn.js} +689 -126
  65. package/dist/mint-failure-u8xQKNOn.js.map +1 -0
  66. package/dist/{models-DDdBJKwT.js → models-WcwUnSKb.js} +2 -2
  67. package/dist/{models-DDdBJKwT.js.map → models-WcwUnSKb.js.map} +1 -1
  68. package/dist/{non-interactive-Dzow7YKY.js → non-interactive-DyVC1AGc.js} +4 -3
  69. package/dist/{non-interactive-Dzow7YKY.js.map → non-interactive-DyVC1AGc.js.map} +1 -1
  70. package/dist/{oauth-session-DJ8h6GFa.js → oauth-session-DYM2Hrl2.js} +2 -2
  71. package/dist/{oauth-session-DJ8h6GFa.js.map → oauth-session-DYM2Hrl2.js.map} +1 -1
  72. package/dist/{orchestrator-tools-szcdscwn.js → orchestrator-tools-DbgNBFGA.js} +3 -3
  73. package/dist/{orchestrator-tools-szcdscwn.js.map → orchestrator-tools-DbgNBFGA.js.map} +1 -1
  74. package/dist/{package-json-DY70kkNp.js → package-json-Atg34fa4.js} +2 -8
  75. package/dist/{package-json-DY70kkNp.js.map → package-json-Atg34fa4.js.map} +1 -1
  76. package/dist/package-json-D8Ga03tK.js +2 -0
  77. package/dist/{pi-D3h5Ok0i.js → pi-8KsYsPmM.js} +145 -45
  78. package/dist/pi-8KsYsPmM.js.map +1 -0
  79. package/dist/{playground-5AB4WgNF.js → playground-BlYRBMj7.js} +11 -11
  80. package/dist/playground-BlYRBMj7.js.map +1 -0
  81. package/dist/{posthog-DNn574nW.js → posthog-Bt0Aplb8.js} +4 -9
  82. package/dist/posthog-Bt0Aplb8.js.map +1 -0
  83. package/dist/posthog-CUgCEhH0.js +2 -0
  84. package/dist/{provisioning-B8uSqRZk.js → provisioning-Bo2NRxFz.js} +5 -11
  85. package/dist/{provisioning-B8uSqRZk.js.map → provisioning-Bo2NRxFz.js.map} +1 -1
  86. package/dist/provisioning-OGFGlzf7.js +2 -0
  87. package/dist/{queue-tools-9OOVx5TE.js → queue-tools-C8mXOh7e.js} +3 -3
  88. package/dist/{queue-tools-9OOVx5TE.js.map → queue-tools-C8mXOh7e.js.map} +1 -1
  89. package/dist/registry-C06e_x-p.js +2 -0
  90. package/dist/{registry-8YG-kuXk.js → registry-CD5RQt38.js} +51 -53
  91. package/dist/registry-CD5RQt38.js.map +1 -0
  92. package/dist/run-agent-legacy-ChacZImU.js +2 -0
  93. package/dist/{run-agent-legacy-d7rWlzQR.js → run-agent-legacy-DOlM6DQu.js} +823 -1022
  94. package/dist/run-agent-legacy-DOlM6DQu.js.map +1 -0
  95. package/dist/runners-ov3EXF1n.js +834 -0
  96. package/dist/runners-ov3EXF1n.js.map +1 -0
  97. package/dist/{security-Cg_4a7vB.js → security-C71pkwqH.js} +16 -6
  98. package/dist/security-C71pkwqH.js.map +1 -0
  99. package/dist/{setup-utils-CmTCTPkX.js → setup-utils-B26Lf2yF.js} +12 -22
  100. package/dist/setup-utils-B26Lf2yF.js.map +1 -0
  101. package/dist/setup-utils-CVS86NYR.js +2 -0
  102. package/dist/{start-tui-CB2PZs1x.js → start-tui-Bo2L0bar.js} +30 -28
  103. package/dist/start-tui-Bo2L0bar.js.map +1 -0
  104. package/dist/{steps-BZcXRJNY.js → steps-BPcg3_3Q.js} +7 -7
  105. package/dist/{steps-BZcXRJNY.js.map → steps-BPcg3_3Q.js.map} +1 -1
  106. package/dist/{store-UN7c-ASf.js → store-BTzcvRGT.js} +12 -18
  107. package/dist/store-BTzcvRGT.js.map +1 -0
  108. package/dist/store-BpqySPXm.js +5 -0
  109. package/dist/{subagent-BofIDK-O.js → subagent-D1TrTchE.js} +3 -3
  110. package/dist/{subagent-BofIDK-O.js.map → subagent-D1TrTchE.js.map} +1 -1
  111. package/dist/{task-r9t1UhQP.js → task-DqRlQBfs.js} +18 -16
  112. package/dist/task-DqRlQBfs.js.map +1 -0
  113. package/dist/{task-stream-CMUilu54.js → task-stream-Bw6JaLCX.js} +10 -10
  114. package/dist/task-stream-Bw6JaLCX.js.map +1 -0
  115. package/dist/{tasks-Bbv_lOBG.js → tasks-ChWufsdO.js} +1 -1
  116. package/dist/{tasks-Bbv_lOBG.js.map → tasks-ChWufsdO.js.map} +1 -1
  117. package/dist/{telemetry-D6ruCtnv.js → telemetry-B7zJdRmA.js} +3 -3
  118. package/dist/{telemetry-D6ruCtnv.js.map → telemetry-B7zJdRmA.js.map} +1 -1
  119. package/dist/{terminal-DrGyci_a.js → terminal-zgkEfoCL.js} +17 -17
  120. package/dist/terminal-zgkEfoCL.js.map +1 -0
  121. package/dist/{tools-Dyfh9aCD.js → tools-CkJ2y9Wt.js} +9 -9
  122. package/dist/tools-CkJ2y9Wt.js.map +1 -0
  123. package/dist/{ui-BBVuTM1v.js → ui-Q6-RvERF.js} +3 -3
  124. package/dist/{ui-BBVuTM1v.js.map → ui-Q6-RvERF.js.map} +1 -1
  125. package/dist/{version-aXxpgRKx.js → version-CHhJjz_H.js} +2 -2
  126. package/dist/{version-aXxpgRKx.js.map → version-CHhJjz_H.js.map} +1 -1
  127. package/dist/{wizard-abort-BBkiUxfS.js → wizard-abort-BPdv07np.js} +7 -6
  128. package/dist/{wizard-abort-BBkiUxfS.js.map → wizard-abort-BPdv07np.js.map} +1 -1
  129. package/dist/wizard-abort-Br1qMDNa.js +3 -0
  130. package/dist/wizard-session-2w4Ru-Wz.js.map +1 -1
  131. package/dist/{wizard-ui-DoyOZxK8.js → wizard-ui-DVqrYaOM.js} +1 -1
  132. package/dist/{wizard-ui-DoyOZxK8.js.map → wizard-ui-DVqrYaOM.js.map} +1 -1
  133. package/dist/{yara-hooks-DCeMDd1o.js → yara-hooks-BnxejtXK.js} +5 -5
  134. package/dist/{yara-hooks-DCeMDd1o.js.map → yara-hooks-BnxejtXK.js.map} +1 -1
  135. package/dist/yara-hooks-DSuExwb4.js +2 -0
  136. package/package.json +2 -1
  137. package/dist/agent-bCZ3i3fh.js.map +0 -1
  138. package/dist/agent-interface-BAOIHuXS.js.map +0 -1
  139. package/dist/analytics-BcV-WCM4.js +0 -2
  140. package/dist/ci-install-CDdQYsPe.js.map +0 -1
  141. package/dist/errors-CQ9kttJD.js +0 -185
  142. package/dist/errors-CQ9kttJD.js.map +0 -1
  143. package/dist/file-BcLTjU16.js.map +0 -1
  144. package/dist/gateway-CjoShdLa.js.map +0 -1
  145. package/dist/interactive-D6zV7brJ.js.map +0 -1
  146. package/dist/mcp-prompt-streaming-I2U_X7BC.js.map +0 -1
  147. package/dist/mint-failure-D4nd2XmZ.js.map +0 -1
  148. package/dist/pi-D3h5Ok0i.js.map +0 -1
  149. package/dist/playground-5AB4WgNF.js.map +0 -1
  150. package/dist/posthog-DNn574nW.js.map +0 -1
  151. package/dist/registry-8YG-kuXk.js.map +0 -1
  152. package/dist/rolldown-runtime-B_-DWIq7.js +0 -15
  153. package/dist/run-agent-legacy-d7rWlzQR.js.map +0 -1
  154. package/dist/security-Cg_4a7vB.js.map +0 -1
  155. package/dist/setup-utils-CmTCTPkX.js.map +0 -1
  156. package/dist/start-tui-CB2PZs1x.js.map +0 -1
  157. package/dist/store-UN7c-ASf.js.map +0 -1
  158. package/dist/task-r9t1UhQP.js.map +0 -1
  159. package/dist/task-stream-CMUilu54.js.map +0 -1
  160. package/dist/terminal-DrGyci_a.js.map +0 -1
  161. package/dist/tools-Dyfh9aCD.js.map +0 -1
  162. package/dist/wizard-abort-BU4aLyvh.js +0 -3
  163. package/dist/yara-hooks-DSGuCU9A.js +0 -2
@@ -1,4 +1,4 @@
1
- import { L as SONNET_5_MODEL, _ as GPT5_6_LUNA_MODEL, b as HAIKU_MODEL, v as GPT5_6_SOL_MODEL, x as HAIKU_TRIAGE_MODEL, y as GPT5_6_TERRA_MODEL } from "./constants-jFI2SaE1.js";
1
+ import { L as SONNET_5_MODEL, _ as GPT5_6_LUNA_MODEL, b as HAIKU_MODEL, v as GPT5_6_SOL_MODEL, x as HAIKU_TRIAGE_MODEL, y as GPT5_6_TERRA_MODEL } from "./constants-DHCBSfnx.js";
2
2
  //#region src/agent/runner/switchboard/models.ts
3
3
  /** Reasoning effort, mapped by each harness to its provider transport. */
4
4
  const THINKING_LEVELS = [
@@ -80,4 +80,4 @@ function modelCapabilities(modelId, effortOverride) {
80
80
  //#endregion
81
81
  export { requireKnownModel as a, modelCapabilities as i, isThinkingLevel as n, triageModelFor as o, isValidModel as r, VALID_MODELS as t };
82
82
 
83
- //# sourceMappingURL=models-DDdBJKwT.js.map
83
+ //# sourceMappingURL=models-WcwUnSKb.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"models-DDdBJKwT.js","names":[],"sources":["../src/agent/runner/switchboard/models.ts"],"sourcesContent":["// Local capabilities inform transport parameters; gateway policy independently admits models and efforts.\nimport {\n SONNET_5_MODEL,\n HAIKU_MODEL,\n GPT5_6_LUNA_MODEL,\n GPT5_6_SOL_MODEL,\n GPT5_6_TERRA_MODEL,\n HAIKU_TRIAGE_MODEL,\n Harness,\n} from '@shared/constants';\n\n/** Reasoning effort, mapped by each harness to its provider transport. */\nconst THINKING_LEVELS = [\n 'off',\n 'minimal',\n 'low',\n 'medium',\n 'high',\n 'xhigh',\n] as const;\nexport type ThinkingLevel = (typeof THINKING_LEVELS)[number];\n\n/** Whether a value (e.g. remote prompt frontmatter) names a valid effort. */\nexport function isThinkingLevel(value: unknown): value is ThinkingLevel {\n return (THINKING_LEVELS as readonly unknown[]).includes(value);\n}\n\n/**\n * An effort *override* is always a positive level — `'off'` is a model trait\n * (`reasoning: false`), not something a flag may force onto a reasoning model.\n */\nexport type EffortLevel = Exclude<ThinkingLevel, 'off'>;\n\nexport interface ModelCapabilities {\n /** Model supports reasoning; safe to request reasoning effort. */\n reasoning: boolean;\n /** Effort to request when reasoning. Omit for the harness/provider default. */\n thinkingLevel?: ThinkingLevel;\n}\n\n/**\n * Explicit per-model traits. Anything absent falls back to `defaultCaps`.\n *\n * A reasoning model without a `thinkingLevel` leaves the effort to the harness,\n * and the mint pins effort per model (posthog `WIZARD_MODEL_ALLOWLIST`), so an\n * unpinned reasoning model is refused with no tool calls. Every level below is\n * one the mint allows for that model.\n */\nexport const MODEL_CAPABILITIES: Record<string, ModelCapabilities> = {\n // The mint takes sonnet 5 at `none` or `high`; high is the only level it\n // serves once reasoning is on.\n [SONNET_5_MODEL]: { reasoning: true, thinkingLevel: 'high' },\n // The mint takes haiku with no effort parameter at all, which is `off`.\n [HAIKU_MODEL]: { reasoning: true, thinkingLevel: 'off' },\n // The openai 5.6 line; all reasoning models, so they must opt in past the\n // openai-completions default (reasoning off). Luna stays low for cheap,\n // short-context mechanical work; terra runs medium as the sonnet-tier parallel\n // — enough reasoning depth for the judgment tasks without high's latency blowup.\n [GPT5_6_LUNA_MODEL]: { reasoning: true, thinkingLevel: 'low' },\n [GPT5_6_TERRA_MODEL]: { reasoning: true, thinkingLevel: 'medium' },\n [GPT5_6_SOL_MODEL]: { reasoning: true, thinkingLevel: 'medium' },\n};\n\n/**\n * The mint's per-model effort pin, mirrored from posthog\n * `WIZARD_MODEL_ALLOWLIST`. `'off'` is the CLI's spelling of the mint's\n * `\"none\"` — a call carrying no effort parameter.\n */\nexport const MINT_ALLOWED_EFFORTS: Record<string, readonly ThinkingLevel[]> = {\n [SONNET_5_MODEL]: ['off', 'high'],\n [HAIKU_MODEL]: ['off'],\n [GPT5_6_LUNA_MODEL]: ['low'],\n [GPT5_6_SOL_MODEL]: ['medium'],\n [GPT5_6_TERRA_MODEL]: ['low', 'medium', 'high'],\n};\n\n// Local model choices; gateway admission also requires allowed models, efforts, and prompt compatibility.\nexport const VALID_MODELS: ReadonlySet<string> = new Set(\n Object.keys(MODEL_CAPABILITIES),\n);\n\n/** Whether the value is an allow-listed model. */\nexport function isValidModel(model: unknown): model is string {\n return typeof model === 'string' && VALID_MODELS.has(model);\n}\n\n/** First allow-listed candidate, else throw so a bad id fails loud. */\nexport function requireKnownModel(\n ...candidates: (string | undefined)[]\n): string {\n for (const c of candidates) if (isValidModel(c)) return c;\n throw new Error(\n `No valid model to dispatch on (tried ${JSON.stringify(candidates)}). ` +\n `Allowed: ${[...VALID_MODELS].join(', ')}.`,\n );\n}\n\n// Unknown Anthropic models default to reasoning; OpenAI models must opt in through the local table.\nfunction defaultCaps(modelId: string): ModelCapabilities {\n return { reasoning: !modelId.startsWith('openai/') };\n}\n\n// Triage requests must satisfy gateway safety policy and preserve Warlock’s classifier format.\nexport const TRIAGE_MODELS: Record<Harness, string> = {\n [Harness.anthropic]: HAIKU_TRIAGE_MODEL,\n [Harness.pi]: GPT5_6_LUNA_MODEL,\n};\n\nexport function triageModelFor(harness: Harness): string {\n return TRIAGE_MODELS[harness];\n}\n\n/**\n * Capabilities for a gateway model id, table override then transport default.\n * `effortOverride` is a switchboard-resolved effort (e.g. from a pi effort\n * flag); it applies only when the model reasons at all — a non-reasoning model\n * rejects reasoning effort, so the override is dropped.\n */\nexport function modelCapabilities(\n modelId: string,\n effortOverride?: EffortLevel,\n): ModelCapabilities {\n const caps = MODEL_CAPABILITIES[modelId] ?? defaultCaps(modelId);\n if (caps.reasoning && effortOverride) {\n return { ...caps, thinkingLevel: effortOverride };\n }\n return caps;\n}\n"],"mappings":";;;AAYA,MAAM,kBAAkB;CACtB;CACA;CACA;CACA;CACA;CACA;CACD;;AAID,SAAgB,gBAAgB,OAAwC;AACtE,QAAQ,gBAAuC,SAAS,MAAM;;;;;;;;;;AAwBhE,MAAa,qBAAwD;EAGlE,iBAAiB;EAAE,WAAW;EAAM,eAAe;EAAQ;EAE3D,cAAc;EAAE,WAAW;EAAM,eAAe;EAAO;EAKvD,oBAAoB;EAAE,WAAW;EAAM,eAAe;EAAO;EAC7D,qBAAqB;EAAE,WAAW;EAAM,eAAe;EAAU;EACjE,mBAAmB;EAAE,WAAW;EAAM,eAAe;EAAU;CACjE;AAgBD,MAAa,eAAoC,IAAI,IACnD,OAAO,KAAK,mBAAmB,CAChC;;AAGD,SAAgB,aAAa,OAAiC;AAC5D,QAAO,OAAO,UAAU,YAAY,aAAa,IAAI,MAAM;;;AAI7D,SAAgB,kBACd,GAAG,YACK;AACR,MAAK,MAAM,KAAK,WAAY,KAAI,aAAa,EAAE,CAAE,QAAO;AACxD,OAAM,IAAI,MACR,wCAAwC,KAAK,UAAU,WAAW,CAAC,cACrD,CAAC,GAAG,aAAa,CAAC,KAAK,KAAK,CAAC,GAC5C;;AAIH,SAAS,YAAY,SAAoC;AACvD,QAAO,EAAE,WAAW,CAAC,QAAQ,WAAW,UAAU,EAAE;;AAItD,MAAa,gBAAyC;gBAC/B;SACP;CACf;AAED,SAAgB,eAAe,SAA0B;AACvD,QAAO,cAAc;;;;;;;;AASvB,SAAgB,kBACd,SACA,gBACmB;CACnB,MAAM,OAAO,mBAAmB,YAAY,YAAY,QAAQ;AAChE,KAAI,KAAK,aAAa,eACpB,QAAO;EAAE,GAAG;EAAM,eAAe;EAAgB;AAEnD,QAAO"}
1
+ {"version":3,"file":"models-WcwUnSKb.js","names":[],"sources":["../src/agent/runner/switchboard/models.ts"],"sourcesContent":["// Local capabilities inform transport parameters; gateway policy independently admits models and efforts.\nimport {\n SONNET_5_MODEL,\n HAIKU_MODEL,\n GPT5_6_LUNA_MODEL,\n GPT5_6_SOL_MODEL,\n GPT5_6_TERRA_MODEL,\n HAIKU_TRIAGE_MODEL,\n Harness,\n} from '@shared/constants';\n\n/** Reasoning effort, mapped by each harness to its provider transport. */\nconst THINKING_LEVELS = [\n 'off',\n 'minimal',\n 'low',\n 'medium',\n 'high',\n 'xhigh',\n] as const;\nexport type ThinkingLevel = (typeof THINKING_LEVELS)[number];\n\n/** Whether a value (e.g. remote prompt frontmatter) names a valid effort. */\nexport function isThinkingLevel(value: unknown): value is ThinkingLevel {\n return (THINKING_LEVELS as readonly unknown[]).includes(value);\n}\n\n/**\n * An effort *override* is always a positive level — `'off'` is a model trait\n * (`reasoning: false`), not something a flag may force onto a reasoning model.\n */\nexport type EffortLevel = Exclude<ThinkingLevel, 'off'>;\n\nexport interface ModelCapabilities {\n /** Model supports reasoning; safe to request reasoning effort. */\n reasoning: boolean;\n /** Effort to request when reasoning. Omit for the harness/provider default. */\n thinkingLevel?: ThinkingLevel;\n}\n\n/**\n * Explicit per-model traits. Anything absent falls back to `defaultCaps`.\n *\n * A reasoning model without a `thinkingLevel` leaves the effort to the harness,\n * and the mint pins effort per model (posthog `WIZARD_MODEL_ALLOWLIST`), so an\n * unpinned reasoning model is refused with no tool calls. Every level below is\n * one the mint allows for that model.\n */\nexport const MODEL_CAPABILITIES: Record<string, ModelCapabilities> = {\n // The mint takes sonnet 5 at `none` or `high`; high is the only level it\n // serves once reasoning is on.\n [SONNET_5_MODEL]: { reasoning: true, thinkingLevel: 'high' },\n // The mint takes haiku with no effort parameter at all, which is `off`.\n [HAIKU_MODEL]: { reasoning: true, thinkingLevel: 'off' },\n // The openai 5.6 line; all reasoning models, so they must opt in past the\n // openai-completions default (reasoning off). Luna stays low for cheap,\n // short-context mechanical work; terra runs medium as the sonnet-tier parallel\n // — enough reasoning depth for the judgment tasks without high's latency blowup.\n [GPT5_6_LUNA_MODEL]: { reasoning: true, thinkingLevel: 'low' },\n [GPT5_6_TERRA_MODEL]: { reasoning: true, thinkingLevel: 'medium' },\n [GPT5_6_SOL_MODEL]: { reasoning: true, thinkingLevel: 'medium' },\n};\n\n/**\n * The mint's per-model effort pin, mirrored from posthog\n * `WIZARD_MODEL_ALLOWLIST`. `'off'` is the CLI's spelling of the mint's\n * `\"none\"` — a call carrying no effort parameter.\n */\nexport const MINT_ALLOWED_EFFORTS: Record<string, readonly ThinkingLevel[]> = {\n [SONNET_5_MODEL]: ['off', 'high'],\n [HAIKU_MODEL]: ['off'],\n [GPT5_6_LUNA_MODEL]: ['low'],\n [GPT5_6_SOL_MODEL]: ['medium'],\n [GPT5_6_TERRA_MODEL]: ['low', 'medium', 'high'],\n};\n\n// Local model choices; gateway admission also requires allowed models, efforts, and prompt compatibility.\nexport const VALID_MODELS: ReadonlySet<string> = new Set(\n Object.keys(MODEL_CAPABILITIES),\n);\n\n/** Whether the value is an allow-listed model. */\nexport function isValidModel(model: unknown): model is string {\n return typeof model === 'string' && VALID_MODELS.has(model);\n}\n\n/** First allow-listed candidate, else throw so a bad id fails loud. */\nexport function requireKnownModel(\n ...candidates: (string | undefined)[]\n): string {\n for (const c of candidates) if (isValidModel(c)) return c;\n throw new Error(\n `No valid model to dispatch on (tried ${JSON.stringify(candidates)}). ` +\n `Allowed: ${[...VALID_MODELS].join(', ')}.`,\n );\n}\n\n// Unknown Anthropic models default to reasoning; OpenAI models must opt in through the local table.\nfunction defaultCaps(modelId: string): ModelCapabilities {\n return { reasoning: !modelId.startsWith('openai/') };\n}\n\n// Triage requests must satisfy gateway safety policy and preserve Warlock’s classifier format.\nexport const TRIAGE_MODELS: Record<Harness, string> = {\n [Harness.anthropic]: HAIKU_TRIAGE_MODEL,\n [Harness.pi]: GPT5_6_LUNA_MODEL,\n};\n\nexport function triageModelFor(harness: Harness): string {\n return TRIAGE_MODELS[harness];\n}\n\n/**\n * Capabilities for a gateway model id, table override then transport default.\n * `effortOverride` is a switchboard-resolved effort (e.g. from a pi effort\n * flag); it applies only when the model reasons at all — a non-reasoning model\n * rejects reasoning effort, so the override is dropped.\n */\nexport function modelCapabilities(\n modelId: string,\n effortOverride?: EffortLevel,\n): ModelCapabilities {\n const caps = MODEL_CAPABILITIES[modelId] ?? defaultCaps(modelId);\n if (caps.reasoning && effortOverride) {\n return { ...caps, thinkingLevel: effortOverride };\n }\n return caps;\n}\n"],"mappings":";;;AAYA,MAAM,kBAAkB;CACtB;CACA;CACA;CACA;CACA;CACA;CACD;;AAID,SAAgB,gBAAgB,OAAwC;AACtE,QAAQ,gBAAuC,SAAS,MAAM;;;;;;;;;;AAwBhE,MAAa,qBAAwD;EAGlE,iBAAiB;EAAE,WAAW;EAAM,eAAe;EAAQ;EAE3D,cAAc;EAAE,WAAW;EAAM,eAAe;EAAO;EAKvD,oBAAoB;EAAE,WAAW;EAAM,eAAe;EAAO;EAC7D,qBAAqB;EAAE,WAAW;EAAM,eAAe;EAAU;EACjE,mBAAmB;EAAE,WAAW;EAAM,eAAe;EAAU;CACjE;AAgBD,MAAa,eAAoC,IAAI,IACnD,OAAO,KAAK,mBAAmB,CAChC;;AAGD,SAAgB,aAAa,OAAiC;AAC5D,QAAO,OAAO,UAAU,YAAY,aAAa,IAAI,MAAM;;;AAI7D,SAAgB,kBACd,GAAG,YACK;AACR,MAAK,MAAM,KAAK,WAAY,KAAI,aAAa,EAAE,CAAE,QAAO;AACxD,OAAM,IAAI,MACR,wCAAwC,KAAK,UAAU,WAAW,CAAC,cACrD,CAAC,GAAG,aAAa,CAAC,KAAK,KAAK,CAAC,GAC5C;;AAIH,SAAS,YAAY,SAAoC;AACvD,QAAO,EAAE,WAAW,CAAC,QAAQ,WAAW,UAAU,EAAE;;AAItD,MAAa,gBAAyC;gBAC/B;SACP;CACf;AAED,SAAgB,eAAe,SAA0B;AACvD,QAAO,cAAc;;;;;;;;AASvB,SAAgB,kBACd,SACA,gBACmB;CACnB,MAAM,OAAO,mBAAmB,YAAY,YAAY,QAAQ;AAChE,KAAI,KAAK,aAAa,eACpB,QAAO;EAAE,GAAG;EAAM,eAAe;EAAgB;AAEnD,QAAO"}
@@ -1,5 +1,6 @@
1
- import { d as ErrorCodes, u as emitWizardError } from "./errors-CQ9kttJD.js";
2
- import { t as getUI } from "./ui-BBVuTM1v.js";
1
+ import { n as ErrorCodes, t as emitWizardError } from "./emit-BSetXzDV.js";
2
+ import "./errors-C2domSkK.js";
3
+ import { t as getUI } from "./ui-Q6-RvERF.js";
3
4
  //#region src/commands/basic-integration/non-interactive.ts
4
5
  /** Print the "needs a TTY" error and exit. Used when no `--ci` flag and no TTY. */
5
6
  function failNonInteractive() {
@@ -14,4 +15,4 @@ function failNonInteractive() {
14
15
  //#endregion
15
16
  export { failNonInteractive };
16
17
 
17
- //# sourceMappingURL=non-interactive-Dzow7YKY.js.map
18
+ //# sourceMappingURL=non-interactive-DyVC1AGc.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"non-interactive-Dzow7YKY.js","names":[],"sources":["../src/commands/basic-integration/non-interactive.ts"],"sourcesContent":["import { getUI } from '@ui';\nimport { ErrorCodes } from '@shared/errors';\nimport { emitWizardError } from '@shared/errors';\n\n/** Print the \"needs a TTY\" error and exit. Used when no `--ci` flag and no TTY. */\nexport function failNonInteractive(): void {\n getUI().intro('PostHog Wizard');\n getUI().log.error(\n 'This installer requires an interactive terminal (TTY) to run.\\n' +\n 'It appears you are running in a non-interactive environment.\\n' +\n 'Please run the wizard in an interactive terminal.\\n\\n' +\n 'For CI/CD environments, use --ci mode:\\n' +\n ' npx @posthog/wizard --ci --region us --api-key phx_xxx',\n );\n emitWizardError({\n code: ErrorCodes.CliInteractiveRequired,\n message: 'This installer requires an interactive terminal (TTY) to run.',\n });\n process.exit(1);\n}\n"],"mappings":";;;;AAKA,SAAgB,qBAA2B;AACzC,QAAO,CAAC,MAAM,iBAAiB;AAC/B,QAAO,CAAC,IAAI,MACV,qRAKD;AACD,iBAAgB;EACd,MAAM,WAAW;EACjB,SAAS;EACV,CAAC;AACF,SAAQ,KAAK,EAAE"}
1
+ {"version":3,"file":"non-interactive-DyVC1AGc.js","names":[],"sources":["../src/commands/basic-integration/non-interactive.ts"],"sourcesContent":["import { getUI } from '@ui';\nimport { ErrorCodes } from '@shared/errors';\nimport { emitWizardError } from '@shared/errors';\n\n/** Print the \"needs a TTY\" error and exit. Used when no `--ci` flag and no TTY. */\nexport function failNonInteractive(): void {\n getUI().intro('PostHog Wizard');\n getUI().log.error(\n 'This installer requires an interactive terminal (TTY) to run.\\n' +\n 'It appears you are running in a non-interactive environment.\\n' +\n 'Please run the wizard in an interactive terminal.\\n\\n' +\n 'For CI/CD environments, use --ci mode:\\n' +\n ' npx @posthog/wizard --ci --region us --api-key phx_xxx',\n );\n emitWizardError({\n code: ErrorCodes.CliInteractiveRequired,\n message: 'This installer requires an interactive terminal (TTY) to run.',\n });\n process.exit(1);\n}\n"],"mappings":";;;;;AAKA,SAAgB,qBAA2B;AACzC,QAAO,CAAC,MAAM,iBAAiB;AAC/B,QAAO,CAAC,IAAI,MACV,qRAKD;AACD,iBAAgB;EACd,MAAM,WAAW;EACjB,SAAS;EACV,CAAC;AACF,SAAQ,KAAK,EAAE"}
@@ -1,4 +1,4 @@
1
- import { s as logToFile } from "./debug-Ch4BDOtD.js";
1
+ import { s as logToFile } from "./debug-kAHwWGg7.js";
2
2
  //#region src/shared/oauth-session.ts
3
3
  const REFRESH_WHEN_REMAINING_MS = 3e3 * 1e3;
4
4
  let current = null;
@@ -71,4 +71,4 @@ async function refresh(rotateWith, credentials) {
71
71
  //#endregion
72
72
  export { oauthLoginKey as a, oauthCredentials as i, currentAccessToken as n, onAccessTokenRotated as o, currentCredentials as r, configureOAuthSession as t };
73
73
 
74
- //# sourceMappingURL=oauth-session-DJ8h6GFa.js.map
74
+ //# sourceMappingURL=oauth-session-DYM2Hrl2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-session-DJ8h6GFa.js","names":[],"sources":["../src/shared/oauth-session.ts"],"sourcesContent":["// The run's one OAuth token, shaped like gateway-session. The host supplies the rotation.\n\nimport type { Credentials } from '@shared/api';\nimport { logToFile } from '@utils/debug';\n\n// Below this remaining lifetime a run risks outliving its token; just-minted and 7-day tokens skip.\nconst REFRESH_WHEN_REMAINING_MS = 50 * 60 * 1000;\n\n/** Returns the rotated credentials, or the same object when the rotation failed. Never throws. */\nexport type RotateCredentials = (\n credentials: Credentials,\n) => Promise<Credentials>;\n\nlet current: Credentials | null = null;\nlet rotate: RotateCredentials | undefined;\nlet onRefreshed: ((credentials: Credentials) => void) | undefined;\n// Shared so concurrent callers rotate once: a second rotation would spend the refresh token the first replaced.\nlet inFlight: Promise<Credentials> | null = null;\nconst listeners = new Set<(accessToken: string) => void>();\n// Every access token this login has held; the first one names the login.\nlet lineage = new Set<string>();\nlet lineageRoot: string | undefined;\n\n/** Adopt the run's credentials; a stale copy of the held login gets the newer one back through `onRefreshed`. */\nexport function configureOAuthSession(\n credentials: Credentials,\n options: {\n rotate: RotateCredentials;\n onRefreshed?: (credentials: Credentials) => void;\n },\n): void {\n rotate = options.rotate;\n onRefreshed = options.onRefreshed;\n if (\n current &&\n sameLogin(current, credentials) &&\n (current.expiresAt ?? 0) > (credentials.expiresAt ?? 0)\n ) {\n onRefreshed?.(current);\n return;\n }\n if (!current || !sameLogin(current, credentials)) {\n lineage = new Set();\n lineageRoot = credentials.accessToken;\n }\n lineage.add(credentials.accessToken);\n current = credentials;\n}\n\n/** A key that stays the same across this login's rotations, so caches keyed on it survive one. */\nexport function oauthLoginKey(accessToken: string): string {\n return lineageRoot && lineage.has(accessToken) ? lineageRoot : accessToken;\n}\n\n/** The current credentials, refreshed first when near expiry or when `force` is set. */\nexport async function oauthCredentials(\n force = false,\n): Promise<Credentials | null> {\n if (!current) return null;\n if (!rotate || !current.refreshToken || (!force && !nearExpiry(current)))\n return current;\n inFlight ??= refresh(rotate, current).finally(() => {\n inFlight = null;\n });\n return inFlight;\n}\n\n/** The credentials to use now for this login, or the fallback when another login is held. */\nexport async function currentCredentials(\n fallback: Credentials,\n force = false,\n): Promise<Credentials> {\n if (!current || !sameLogin(current, fallback)) return fallback;\n return (await oauthCredentials(force)) ?? fallback;\n}\n\n/** The access token to use now for this login. */\nexport async function currentAccessToken(\n fallback: Credentials,\n): Promise<string> {\n return (await currentCredentials(fallback)).accessToken;\n}\n\n/** Called with each new access token after a rotation. Returns the unsubscribe. */\nexport function onAccessTokenRotated(\n listener: (accessToken: string) => void,\n): () => void {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n\n/** Test hook: drop the held credentials so the next run configures afresh. */\nexport function resetOAuthSession(): void {\n current = null;\n rotate = undefined;\n onRefreshed = undefined;\n inFlight = null;\n listeners.clear();\n lineage = new Set();\n lineageRoot = undefined;\n}\n\nfunction sameLogin(a: Credentials, b: Credentials): boolean {\n return a.host.apiHost === b.host.apiHost && a.projectId === b.projectId;\n}\n\nfunction nearExpiry(credentials: Credentials): boolean {\n // No expiry means we cannot tell how much life is left, so leave it alone.\n return (\n credentials.expiresAt !== undefined &&\n credentials.expiresAt - Date.now() < REFRESH_WHEN_REMAINING_MS\n );\n}\n\nasync function refresh(\n rotateWith: RotateCredentials,\n credentials: Credentials,\n): Promise<Credentials> {\n const refreshed = await rotateWith(credentials);\n if (refreshed === credentials) return credentials;\n logToFile('[oauth-session] token rotated');\n lineage.add(refreshed.accessToken);\n current = refreshed;\n onRefreshed?.(refreshed);\n for (const listener of listeners) listener(refreshed.accessToken);\n return refreshed;\n}\n"],"mappings":";;AAMA,MAAM,4BAA4B,MAAU;AAO5C,IAAI,UAA8B;AAClC,IAAI;AACJ,IAAI;AAEJ,IAAI,WAAwC;AAC5C,MAAM,4BAAY,IAAI,KAAoC;AAE1D,IAAI,0BAAU,IAAI,KAAa;AAC/B,IAAI;;AAGJ,SAAgB,sBACd,aACA,SAIM;AACN,UAAS,QAAQ;AACjB,eAAc,QAAQ;AACtB,KACE,WACA,UAAU,SAAS,YAAY,KAC9B,QAAQ,aAAa,MAAM,YAAY,aAAa,IACrD;AACA,gBAAc,QAAQ;AACtB;;AAEF,KAAI,CAAC,WAAW,CAAC,UAAU,SAAS,YAAY,EAAE;AAChD,4BAAU,IAAI,KAAK;AACnB,gBAAc,YAAY;;AAE5B,SAAQ,IAAI,YAAY,YAAY;AACpC,WAAU;;;AAIZ,SAAgB,cAAc,aAA6B;AACzD,QAAO,eAAe,QAAQ,IAAI,YAAY,GAAG,cAAc;;;AAIjE,eAAsB,iBACpB,QAAQ,OACqB;AAC7B,KAAI,CAAC,QAAS,QAAO;AACrB,KAAI,CAAC,UAAU,CAAC,QAAQ,gBAAiB,CAAC,SAAS,CAAC,WAAW,QAAQ,CACrE,QAAO;AACT,cAAa,QAAQ,QAAQ,QAAQ,CAAC,cAAc;AAClD,aAAW;GACX;AACF,QAAO;;;AAIT,eAAsB,mBACpB,UACA,QAAQ,OACc;AACtB,KAAI,CAAC,WAAW,CAAC,UAAU,SAAS,SAAS,CAAE,QAAO;AACtD,QAAQ,MAAM,iBAAiB,MAAM,IAAK;;;AAI5C,eAAsB,mBACpB,UACiB;AACjB,SAAQ,MAAM,mBAAmB,SAAS,EAAE;;;AAI9C,SAAgB,qBACd,UACY;AACZ,WAAU,IAAI,SAAS;AACvB,cAAa;AACX,YAAU,OAAO,SAAS;;;AAe9B,SAAS,UAAU,GAAgB,GAAyB;AAC1D,QAAO,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,cAAc,EAAE;;AAGhE,SAAS,WAAW,aAAmC;AAErD,QACE,YAAY,cAAc,KAAA,KAC1B,YAAY,YAAY,KAAK,KAAK,GAAG;;AAIzC,eAAe,QACb,YACA,aACsB;CACtB,MAAM,YAAY,MAAM,WAAW,YAAY;AAC/C,KAAI,cAAc,YAAa,QAAO;AACtC,WAAU,gCAAgC;AAC1C,SAAQ,IAAI,UAAU,YAAY;AAClC,WAAU;AACV,eAAc,UAAU;AACxB,MAAK,MAAM,YAAY,UAAW,UAAS,UAAU,YAAY;AACjE,QAAO"}
1
+ {"version":3,"file":"oauth-session-DYM2Hrl2.js","names":[],"sources":["../src/shared/oauth-session.ts"],"sourcesContent":["// The run's one OAuth token, shaped like gateway-session. The host supplies the rotation.\n\nimport type { Credentials } from '@shared/api';\nimport { logToFile } from '@utils/debug';\n\n// Below this remaining lifetime a run risks outliving its token; just-minted and 7-day tokens skip.\nconst REFRESH_WHEN_REMAINING_MS = 50 * 60 * 1000;\n\n/** Returns the rotated credentials, or the same object when the rotation failed. Never throws. */\nexport type RotateCredentials = (\n credentials: Credentials,\n) => Promise<Credentials>;\n\nlet current: Credentials | null = null;\nlet rotate: RotateCredentials | undefined;\nlet onRefreshed: ((credentials: Credentials) => void) | undefined;\n// Shared so concurrent callers rotate once: a second rotation would spend the refresh token the first replaced.\nlet inFlight: Promise<Credentials> | null = null;\nconst listeners = new Set<(accessToken: string) => void>();\n// Every access token this login has held; the first one names the login.\nlet lineage = new Set<string>();\nlet lineageRoot: string | undefined;\n\n/** Adopt the run's credentials; a stale copy of the held login gets the newer one back through `onRefreshed`. */\nexport function configureOAuthSession(\n credentials: Credentials,\n options: {\n rotate: RotateCredentials;\n onRefreshed?: (credentials: Credentials) => void;\n },\n): void {\n rotate = options.rotate;\n onRefreshed = options.onRefreshed;\n if (\n current &&\n sameLogin(current, credentials) &&\n (current.expiresAt ?? 0) > (credentials.expiresAt ?? 0)\n ) {\n onRefreshed?.(current);\n return;\n }\n if (!current || !sameLogin(current, credentials)) {\n lineage = new Set();\n lineageRoot = credentials.accessToken;\n }\n lineage.add(credentials.accessToken);\n current = credentials;\n}\n\n/** A key that stays the same across this login's rotations, so caches keyed on it survive one. */\nexport function oauthLoginKey(accessToken: string): string {\n return lineageRoot && lineage.has(accessToken) ? lineageRoot : accessToken;\n}\n\n/** The current credentials, refreshed first when near expiry or when `force` is set. */\nexport async function oauthCredentials(\n force = false,\n): Promise<Credentials | null> {\n if (!current) return null;\n if (!rotate || !current.refreshToken || (!force && !nearExpiry(current)))\n return current;\n inFlight ??= refresh(rotate, current).finally(() => {\n inFlight = null;\n });\n return inFlight;\n}\n\n/** The credentials to use now for this login, or the fallback when another login is held. */\nexport async function currentCredentials(\n fallback: Credentials,\n force = false,\n): Promise<Credentials> {\n if (!current || !sameLogin(current, fallback)) return fallback;\n return (await oauthCredentials(force)) ?? fallback;\n}\n\n/** The access token to use now for this login. */\nexport async function currentAccessToken(\n fallback: Credentials,\n): Promise<string> {\n return (await currentCredentials(fallback)).accessToken;\n}\n\n/** Called with each new access token after a rotation. Returns the unsubscribe. */\nexport function onAccessTokenRotated(\n listener: (accessToken: string) => void,\n): () => void {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n\n/** Test hook: drop the held credentials so the next run configures afresh. */\nexport function resetOAuthSession(): void {\n current = null;\n rotate = undefined;\n onRefreshed = undefined;\n inFlight = null;\n listeners.clear();\n lineage = new Set();\n lineageRoot = undefined;\n}\n\nfunction sameLogin(a: Credentials, b: Credentials): boolean {\n return a.host.apiHost === b.host.apiHost && a.projectId === b.projectId;\n}\n\nfunction nearExpiry(credentials: Credentials): boolean {\n // No expiry means we cannot tell how much life is left, so leave it alone.\n return (\n credentials.expiresAt !== undefined &&\n credentials.expiresAt - Date.now() < REFRESH_WHEN_REMAINING_MS\n );\n}\n\nasync function refresh(\n rotateWith: RotateCredentials,\n credentials: Credentials,\n): Promise<Credentials> {\n const refreshed = await rotateWith(credentials);\n if (refreshed === credentials) return credentials;\n logToFile('[oauth-session] token rotated');\n lineage.add(refreshed.accessToken);\n current = refreshed;\n onRefreshed?.(refreshed);\n for (const listener of listeners) listener(refreshed.accessToken);\n return refreshed;\n}\n"],"mappings":";;AAMA,MAAM,4BAA4B,MAAU;AAO5C,IAAI,UAA8B;AAClC,IAAI;AACJ,IAAI;AAEJ,IAAI,WAAwC;AAC5C,MAAM,4BAAY,IAAI,KAAoC;AAE1D,IAAI,0BAAU,IAAI,KAAa;AAC/B,IAAI;;AAGJ,SAAgB,sBACd,aACA,SAIM;AACN,UAAS,QAAQ;AACjB,eAAc,QAAQ;AACtB,KACE,WACA,UAAU,SAAS,YAAY,KAC9B,QAAQ,aAAa,MAAM,YAAY,aAAa,IACrD;AACA,gBAAc,QAAQ;AACtB;;AAEF,KAAI,CAAC,WAAW,CAAC,UAAU,SAAS,YAAY,EAAE;AAChD,4BAAU,IAAI,KAAK;AACnB,gBAAc,YAAY;;AAE5B,SAAQ,IAAI,YAAY,YAAY;AACpC,WAAU;;;AAIZ,SAAgB,cAAc,aAA6B;AACzD,QAAO,eAAe,QAAQ,IAAI,YAAY,GAAG,cAAc;;;AAIjE,eAAsB,iBACpB,QAAQ,OACqB;AAC7B,KAAI,CAAC,QAAS,QAAO;AACrB,KAAI,CAAC,UAAU,CAAC,QAAQ,gBAAiB,CAAC,SAAS,CAAC,WAAW,QAAQ,CACrE,QAAO;AACT,cAAa,QAAQ,QAAQ,QAAQ,CAAC,cAAc;AAClD,aAAW;GACX;AACF,QAAO;;;AAIT,eAAsB,mBACpB,UACA,QAAQ,OACc;AACtB,KAAI,CAAC,WAAW,CAAC,UAAU,SAAS,SAAS,CAAE,QAAO;AACtD,QAAQ,MAAM,iBAAiB,MAAM,IAAK;;;AAI5C,eAAsB,mBACpB,UACiB;AACjB,SAAQ,MAAM,mBAAmB,SAAS,EAAE;;;AAI9C,SAAgB,qBACd,UACY;AACZ,WAAU,IAAI,SAAS;AACvB,cAAa;AACX,YAAU,OAAO,SAAS;;;AAe9B,SAAS,UAAU,GAAgB,GAAyB;AAC1D,QAAO,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,cAAc,EAAE;;AAGhE,SAAS,WAAW,aAAmC;AAErD,QACE,YAAY,cAAc,KAAA,KAC1B,YAAY,YAAY,KAAK,KAAK,GAAG;;AAIzC,eAAe,QACb,YACA,aACsB;CACtB,MAAM,YAAY,MAAM,WAAW,YAAY;AAC/C,KAAI,cAAc,YAAa,QAAO;AACtC,WAAU,gCAAgC;AAC1C,SAAQ,IAAI,UAAU,YAAY;AAClC,WAAU;AACV,eAAc,UAAU;AACxB,MAAK,MAAM,YAAY,UAAW,UAAS,UAAU,YAAY;AACjE,QAAO"}
@@ -1,5 +1,5 @@
1
- import { n as analytics } from "./analytics-CHCZ_qUR.js";
2
- import { a as REMARK_ASK, c as applyReadHandoffs, f as NotNeededReason, i as NOT_NEEDED_REASON_ASK, n as ENQUEUE_MODEL_DESCRIPTION, o as applyComplete, r as HANDOFF_FIELDS, s as applyEnqueue, t as COMPLETE_TASK_DESCRIPTION } from "./queue-tools-9OOVx5TE.js";
1
+ import { n as analytics } from "./analytics-DXK1gc12.js";
2
+ import { a as REMARK_ASK, c as applyReadHandoffs, f as NotNeededReason, i as NOT_NEEDED_REASON_ASK, n as ENQUEUE_MODEL_DESCRIPTION, o as applyComplete, r as HANDOFF_FIELDS, s as applyEnqueue, t as COMPLETE_TASK_DESCRIPTION } from "./queue-tools-C8mXOh7e.js";
3
3
  import { Type } from "typebox";
4
4
  import { defineTool } from "@earendil-works/pi-coding-agent";
5
5
  //#region src/agent/runner/harness/pi/orchestrator-tools.ts
@@ -110,4 +110,4 @@ function createPiOrchestratorTools(ctx) {
110
110
  //#endregion
111
111
  export { createPiOrchestratorTools };
112
112
 
113
- //# sourceMappingURL=orchestrator-tools-szcdscwn.js.map
113
+ //# sourceMappingURL=orchestrator-tools-DbgNBFGA.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrator-tools-szcdscwn.js","names":[],"sources":["../src/agent/runner/harness/pi/orchestrator-tools.ts"],"sourcesContent":["/**\n * Orchestrator queue tools as pi custom tools. The queue lives in-process, and\n * `applyEnqueue` / `applyComplete` / `applyReadHandoffs` are plain exported\n * functions — so pi needs no MCP transport, just `defineTool` wrappers around\n * the same guards and apply logic the anthropic path mounts through the\n * wizard-tools MCP server. Tool names match the MCP short names so the shared\n * agent prompts are unchanged.\n *\n * Lazily imported (typebox is ESM and must stay out of the static module graph\n * so CommonJS unit tests can load the backend seam without parsing it).\n */\n\nimport { Type } from 'typebox';\nimport { defineTool } from '@earendil-works/pi-coding-agent';\nimport type { ToolDefinition } from '@earendil-works/pi-coding-agent';\nimport { analytics } from '@utils/analytics';\nimport {\n applyComplete,\n applyEnqueue,\n applyReadHandoffs,\n COMPLETE_TASK_DESCRIPTION,\n ENQUEUE_MODEL_DESCRIPTION,\n HANDOFF_FIELDS,\n NOT_NEEDED_REASON_ASK,\n REMARK_ASK,\n type CompleteArgs,\n type EnqueueArgs,\n type OrchestratorToolsContext,\n} from '../../sequence/orchestrator/queue-tools';\nimport { NotNeededReason } from '../../sequence/orchestrator/queue';\n\nfunction text(s: string): {\n content: [{ type: 'text'; text: string }];\n details: unknown;\n} {\n return { content: [{ type: 'text', text: s }], details: {} };\n}\n\n/** Mirrors the zod `HANDOFF_SHAPE`; both read their text from HANDOFF_FIELDS. */\nconst HANDOFF_PARAMS = Type.Object({\n goals: Type.String({ description: HANDOFF_FIELDS.goals }),\n did: Type.String({ description: HANDOFF_FIELDS.did }),\n forNextAgent: Type.String({ description: HANDOFF_FIELDS.forNextAgent }),\n filesTouched: Type.Optional(\n Type.Array(Type.String(), { description: HANDOFF_FIELDS.filesTouched }),\n ),\n evidence: Type.Optional(\n Type.String({ description: HANDOFF_FIELDS.evidence }),\n ),\n assumptions: Type.Optional(\n Type.String({ description: HANDOFF_FIELDS.assumptions }),\n ),\n conflict: Type.Optional(\n Type.String({ description: HANDOFF_FIELDS.conflict }),\n ),\n reportSection: Type.Optional(\n Type.String({ description: HANDOFF_FIELDS.reportSection }),\n ),\n});\n\n/** Exported so the parity test can compare both harnesses' field sets. */\nexport const PI_HANDOFF_PARAM_KEYS: readonly string[] = Object.keys(\n HANDOFF_PARAMS.properties,\n);\n\n/** Mirrors the zod `COMPLETE_SHAPE`; ctx-independent, so it lives out here. */\nconst COMPLETE_PARAMS = Type.Object({\n status: Type.Union([\n Type.Literal('done'),\n Type.Literal('failed'),\n Type.Literal('not needed'),\n ]),\n handoff: HANDOFF_PARAMS,\n remark: Type.Optional(Type.String({ description: REMARK_ASK })),\n notNeededReason: Type.Optional(\n Type.Union(\n [\n Type.Literal(NotNeededReason.NotApplicable),\n Type.Literal(NotNeededReason.UserDeclined),\n Type.Literal(NotNeededReason.Blocked),\n ],\n { description: NOT_NEEDED_REASON_ASK },\n ),\n ),\n});\n\n/** Exported so the parity test can compare both harnesses' field sets. */\nexport const PI_COMPLETE_PARAM_KEYS: readonly string[] = Object.keys(\n COMPLETE_PARAMS.properties,\n);\n\n/** The three queue tools bound to one agent's orchestrator context. */\nexport function createPiOrchestratorTools(\n ctx: OrchestratorToolsContext,\n): ToolDefinition[] {\n const enqueueTask = defineTool({\n name: 'enqueue_task',\n label: 'Enqueue task',\n description:\n 'Add a task to the orchestrator queue. Use it to seed work and to enqueue follow-up work you discover. Keep tasks small and discrete.',\n promptSnippet:\n 'enqueue_task({type, label, dependsOn, reason}) — add a task to the queue; the task type goes in the \"type\" field, and it returns the task id',\n parameters: Type.Object({\n type: Type.String({\n description: `The task type. One of: ${ctx.validTypes.join(', ')}.`,\n }),\n label: Type.Optional(\n Type.String({\n description:\n 'A short label for the UI — the action in a few words (e.g. \"Add the PostHog SDK\", \"Initialize PostHog\"). Leave out file names, class names, and other specifics.',\n }),\n ),\n inputs: Type.Optional(Type.Record(Type.String(), Type.Unknown())),\n dependsOn: Type.Optional(\n Type.Array(Type.String(), {\n description: 'Task ids that must be done before this task runs.',\n }),\n ),\n model: Type.Optional(\n Type.String({ description: ENQUEUE_MODEL_DESCRIPTION }),\n ),\n reason: Type.String({\n description: 'One line on why this task is needed.',\n }),\n }),\n execute(_id, args) {\n const res = applyEnqueue(ctx, args as EnqueueArgs);\n if (!res.ok) {\n analytics.wizardCapture('orchestrator guard tripped', {\n guard: res.guard,\n type: (args as EnqueueArgs).type,\n });\n return Promise.resolve(text(`Error: ${res.message}`));\n }\n return Promise.resolve(text(JSON.stringify({ id: res.task.id })));\n },\n });\n\n const completeTask = defineTool({\n name: 'complete_task',\n label: 'Complete task',\n description: COMPLETE_TASK_DESCRIPTION,\n promptSnippet:\n 'complete_task(status, handoff) — report your outcome exactly once when done, with goals/did/forNextAgent nested inside handoff',\n parameters: COMPLETE_PARAMS,\n execute(_id, args) {\n const res = applyComplete(ctx, args as CompleteArgs);\n if (!res.ok) return Promise.resolve(text(`Error: ${res.message}`));\n return Promise.resolve(text('ok'));\n },\n });\n\n const readHandoffs = defineTool({\n name: 'read_handoffs',\n label: 'Read handoffs',\n description:\n 'Read structured handoffs from earlier tasks. With no argument, returns the handoffs of your dependencies.',\n promptSnippet:\n 'read_handoffs() — read what earlier tasks handed off (defaults to your dependencies)',\n parameters: Type.Object({\n type: Type.Optional(Type.String()),\n taskId: Type.Optional(Type.String()),\n }),\n execute(_id, args) {\n const handoffs = applyReadHandoffs(\n ctx,\n args as { type?: string; taskId?: string },\n );\n return Promise.resolve(text(JSON.stringify(handoffs, null, 2)));\n },\n });\n\n return [enqueueTask, completeTask, readHandoffs];\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"orchestrator-tools-DbgNBFGA.js","names":[],"sources":["../src/agent/runner/harness/pi/orchestrator-tools.ts"],"sourcesContent":["/**\n * Orchestrator queue tools as pi custom tools. The queue lives in-process, and\n * `applyEnqueue` / `applyComplete` / `applyReadHandoffs` are plain exported\n * functions — so pi needs no MCP transport, just `defineTool` wrappers around\n * the same guards and apply logic the anthropic path mounts through the\n * wizard-tools MCP server. Tool names match the MCP short names so the shared\n * agent prompts are unchanged.\n *\n * Lazily imported (typebox is ESM and must stay out of the static module graph\n * so CommonJS unit tests can load the backend seam without parsing it).\n */\n\nimport { Type } from 'typebox';\nimport { defineTool } from '@earendil-works/pi-coding-agent';\nimport type { ToolDefinition } from '@earendil-works/pi-coding-agent';\nimport { analytics } from '@utils/analytics';\nimport {\n applyComplete,\n applyEnqueue,\n applyReadHandoffs,\n COMPLETE_TASK_DESCRIPTION,\n ENQUEUE_MODEL_DESCRIPTION,\n HANDOFF_FIELDS,\n NOT_NEEDED_REASON_ASK,\n REMARK_ASK,\n type CompleteArgs,\n type EnqueueArgs,\n type OrchestratorToolsContext,\n} from '../../sequence/orchestrator/queue-tools';\nimport { NotNeededReason } from '../../sequence/orchestrator/queue';\n\nfunction text(s: string): {\n content: [{ type: 'text'; text: string }];\n details: unknown;\n} {\n return { content: [{ type: 'text', text: s }], details: {} };\n}\n\n/** Mirrors the zod `HANDOFF_SHAPE`; both read their text from HANDOFF_FIELDS. */\nconst HANDOFF_PARAMS = Type.Object({\n goals: Type.String({ description: HANDOFF_FIELDS.goals }),\n did: Type.String({ description: HANDOFF_FIELDS.did }),\n forNextAgent: Type.String({ description: HANDOFF_FIELDS.forNextAgent }),\n filesTouched: Type.Optional(\n Type.Array(Type.String(), { description: HANDOFF_FIELDS.filesTouched }),\n ),\n evidence: Type.Optional(\n Type.String({ description: HANDOFF_FIELDS.evidence }),\n ),\n assumptions: Type.Optional(\n Type.String({ description: HANDOFF_FIELDS.assumptions }),\n ),\n conflict: Type.Optional(\n Type.String({ description: HANDOFF_FIELDS.conflict }),\n ),\n reportSection: Type.Optional(\n Type.String({ description: HANDOFF_FIELDS.reportSection }),\n ),\n});\n\n/** Exported so the parity test can compare both harnesses' field sets. */\nexport const PI_HANDOFF_PARAM_KEYS: readonly string[] = Object.keys(\n HANDOFF_PARAMS.properties,\n);\n\n/** Mirrors the zod `COMPLETE_SHAPE`; ctx-independent, so it lives out here. */\nconst COMPLETE_PARAMS = Type.Object({\n status: Type.Union([\n Type.Literal('done'),\n Type.Literal('failed'),\n Type.Literal('not needed'),\n ]),\n handoff: HANDOFF_PARAMS,\n remark: Type.Optional(Type.String({ description: REMARK_ASK })),\n notNeededReason: Type.Optional(\n Type.Union(\n [\n Type.Literal(NotNeededReason.NotApplicable),\n Type.Literal(NotNeededReason.UserDeclined),\n Type.Literal(NotNeededReason.Blocked),\n ],\n { description: NOT_NEEDED_REASON_ASK },\n ),\n ),\n});\n\n/** Exported so the parity test can compare both harnesses' field sets. */\nexport const PI_COMPLETE_PARAM_KEYS: readonly string[] = Object.keys(\n COMPLETE_PARAMS.properties,\n);\n\n/** The three queue tools bound to one agent's orchestrator context. */\nexport function createPiOrchestratorTools(\n ctx: OrchestratorToolsContext,\n): ToolDefinition[] {\n const enqueueTask = defineTool({\n name: 'enqueue_task',\n label: 'Enqueue task',\n description:\n 'Add a task to the orchestrator queue. Use it to seed work and to enqueue follow-up work you discover. Keep tasks small and discrete.',\n promptSnippet:\n 'enqueue_task({type, label, dependsOn, reason}) — add a task to the queue; the task type goes in the \"type\" field, and it returns the task id',\n parameters: Type.Object({\n type: Type.String({\n description: `The task type. One of: ${ctx.validTypes.join(', ')}.`,\n }),\n label: Type.Optional(\n Type.String({\n description:\n 'A short label for the UI — the action in a few words (e.g. \"Add the PostHog SDK\", \"Initialize PostHog\"). Leave out file names, class names, and other specifics.',\n }),\n ),\n inputs: Type.Optional(Type.Record(Type.String(), Type.Unknown())),\n dependsOn: Type.Optional(\n Type.Array(Type.String(), {\n description: 'Task ids that must be done before this task runs.',\n }),\n ),\n model: Type.Optional(\n Type.String({ description: ENQUEUE_MODEL_DESCRIPTION }),\n ),\n reason: Type.String({\n description: 'One line on why this task is needed.',\n }),\n }),\n execute(_id, args) {\n const res = applyEnqueue(ctx, args as EnqueueArgs);\n if (!res.ok) {\n analytics.wizardCapture('orchestrator guard tripped', {\n guard: res.guard,\n type: (args as EnqueueArgs).type,\n });\n return Promise.resolve(text(`Error: ${res.message}`));\n }\n return Promise.resolve(text(JSON.stringify({ id: res.task.id })));\n },\n });\n\n const completeTask = defineTool({\n name: 'complete_task',\n label: 'Complete task',\n description: COMPLETE_TASK_DESCRIPTION,\n promptSnippet:\n 'complete_task(status, handoff) — report your outcome exactly once when done, with goals/did/forNextAgent nested inside handoff',\n parameters: COMPLETE_PARAMS,\n execute(_id, args) {\n const res = applyComplete(ctx, args as CompleteArgs);\n if (!res.ok) return Promise.resolve(text(`Error: ${res.message}`));\n return Promise.resolve(text('ok'));\n },\n });\n\n const readHandoffs = defineTool({\n name: 'read_handoffs',\n label: 'Read handoffs',\n description:\n 'Read structured handoffs from earlier tasks. With no argument, returns the handoffs of your dependencies.',\n promptSnippet:\n 'read_handoffs() — read what earlier tasks handed off (defaults to your dependencies)',\n parameters: Type.Object({\n type: Type.Optional(Type.String()),\n taskId: Type.Optional(Type.String()),\n }),\n execute(_id, args) {\n const handoffs = applyReadHandoffs(\n ctx,\n args as { type?: string; taskId?: string },\n );\n return Promise.resolve(text(JSON.stringify(handoffs, null, 2)));\n },\n });\n\n return [enqueueTask, completeTask, readHandoffs];\n}\n"],"mappings":"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"}
@@ -1,12 +1,6 @@
1
- import { t as __exportAll } from "./rolldown-runtime-B_-DWIq7.js";
2
1
  import { readFileSync } from "fs";
3
2
  import path from "path";
4
3
  //#region src/shared/utils/package-json.ts
5
- var package_json_exports = /* @__PURE__ */ __exportAll({
6
- getDeclaredVersion: () => getDeclaredVersion,
7
- getInstalledPackageVersion: () => getInstalledPackageVersion,
8
- hasDeclaredDependency: () => hasDeclaredDependency
9
- });
10
4
  /**
11
5
  * Returns the raw version spec for `packageName` as written in
12
6
  * `package.json` (range, pinned version, workspace ref, URL, etc.).
@@ -36,6 +30,6 @@ function getInstalledPackageVersion(packageName, installDir) {
36
30
  }
37
31
  }
38
32
  //#endregion
39
- export { package_json_exports as i, getInstalledPackageVersion as n, hasDeclaredDependency as r, getDeclaredVersion as t };
33
+ export { getInstalledPackageVersion as n, hasDeclaredDependency as r, getDeclaredVersion as t };
40
34
 
41
- //# sourceMappingURL=package-json-DY70kkNp.js.map
35
+ //# sourceMappingURL=package-json-Atg34fa4.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"package-json-DY70kkNp.js","names":[],"sources":["../src/shared/utils/package-json.ts"],"sourcesContent":["import { readFileSync } from 'fs';\nimport path from 'path';\n\nexport type PackageJson = {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n scripts?: Record<string, string | undefined>;\n version?: string;\n overrides?: Record<string, string>;\n resolutions?: Record<string, string>;\n pnpm?: {\n overrides?: Record<string, string>;\n };\n};\n\ntype InstalledPackage = {\n name: string;\n version: string;\n};\n\n/**\n * Returns the raw version spec for `packageName` as written in\n * `package.json` (range, pinned version, workspace ref, URL, etc.).\n * `dependencies` wins over `devDependencies`. An empty-string value in\n * either slot falls through, matching the previous behaviour.\n */\nexport function getDeclaredVersion(\n packageName: string,\n packageJson: PackageJson,\n): string | undefined {\n const fromDeps = packageJson?.dependencies?.[packageName];\n if (fromDeps) return fromDeps;\n const fromDevDeps = packageJson?.devDependencies?.[packageName];\n if (fromDevDeps) return fromDevDeps;\n return undefined;\n}\n\nexport function hasDeclaredDependency(\n packageName: string,\n packageJson: PackageJson,\n): boolean {\n return getDeclaredVersion(packageName, packageJson) !== undefined;\n}\n\nexport function findDeclaredPackage(\n packageNamesList: string[],\n packageJson: PackageJson,\n): InstalledPackage | undefined {\n for (const name of packageNamesList) {\n const version = getDeclaredVersion(name, packageJson);\n if (version) {\n return { name, version };\n }\n }\n return undefined;\n}\n\n/**\n * Returns the resolved version from `node_modules/<pkg>/package.json`,\n * not the range declared in the project's `package.json`. Use this when\n * you need to know what npm actually installed.\n */\nexport function getInstalledPackageVersion(\n packageName: string,\n installDir: string,\n): string | undefined {\n try {\n const manifestPath = path.join(\n installDir,\n 'node_modules',\n packageName,\n 'package.json',\n );\n const manifest = JSON.parse(readFileSync(manifestPath, 'utf-8')) as {\n version?: string;\n };\n return manifest.version;\n } catch {\n return undefined;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AA0BA,SAAgB,mBACd,aACA,aACoB;CACpB,MAAM,WAAW,aAAa,eAAe;AAC7C,KAAI,SAAU,QAAO;CACrB,MAAM,cAAc,aAAa,kBAAkB;AACnD,KAAI,YAAa,QAAO;;AAI1B,SAAgB,sBACd,aACA,aACS;AACT,QAAO,mBAAmB,aAAa,YAAY,KAAK,KAAA;;;;;;;AAqB1D,SAAgB,2BACd,aACA,YACoB;AACpB,KAAI;EACF,MAAM,eAAe,KAAK,KACxB,YACA,gBACA,aACA,eACD;AAID,SAHiB,KAAK,MAAM,aAAa,cAAc,QAAQ,CAAC,CAGhD;SACV;AACN"}
1
+ {"version":3,"file":"package-json-Atg34fa4.js","names":[],"sources":["../src/shared/utils/package-json.ts"],"sourcesContent":["import { readFileSync } from 'fs';\nimport path from 'path';\n\nexport type PackageJson = {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n scripts?: Record<string, string | undefined>;\n version?: string;\n overrides?: Record<string, string>;\n resolutions?: Record<string, string>;\n pnpm?: {\n overrides?: Record<string, string>;\n };\n};\n\ntype InstalledPackage = {\n name: string;\n version: string;\n};\n\n/**\n * Returns the raw version spec for `packageName` as written in\n * `package.json` (range, pinned version, workspace ref, URL, etc.).\n * `dependencies` wins over `devDependencies`. An empty-string value in\n * either slot falls through, matching the previous behaviour.\n */\nexport function getDeclaredVersion(\n packageName: string,\n packageJson: PackageJson,\n): string | undefined {\n const fromDeps = packageJson?.dependencies?.[packageName];\n if (fromDeps) return fromDeps;\n const fromDevDeps = packageJson?.devDependencies?.[packageName];\n if (fromDevDeps) return fromDevDeps;\n return undefined;\n}\n\nexport function hasDeclaredDependency(\n packageName: string,\n packageJson: PackageJson,\n): boolean {\n return getDeclaredVersion(packageName, packageJson) !== undefined;\n}\n\nexport function findDeclaredPackage(\n packageNamesList: string[],\n packageJson: PackageJson,\n): InstalledPackage | undefined {\n for (const name of packageNamesList) {\n const version = getDeclaredVersion(name, packageJson);\n if (version) {\n return { name, version };\n }\n }\n return undefined;\n}\n\n/**\n * Returns the resolved version from `node_modules/<pkg>/package.json`,\n * not the range declared in the project's `package.json`. Use this when\n * you need to know what npm actually installed.\n */\nexport function getInstalledPackageVersion(\n packageName: string,\n installDir: string,\n): string | undefined {\n try {\n const manifestPath = path.join(\n installDir,\n 'node_modules',\n packageName,\n 'package.json',\n );\n const manifest = JSON.parse(readFileSync(manifestPath, 'utf-8')) as {\n version?: string;\n };\n return manifest.version;\n } catch {\n return undefined;\n }\n}\n"],"mappings":";;;;;;;;;AA0BA,SAAgB,mBACd,aACA,aACoB;CACpB,MAAM,WAAW,aAAa,eAAe;AAC7C,KAAI,SAAU,QAAO;CACrB,MAAM,cAAc,aAAa,kBAAkB;AACnD,KAAI,YAAa,QAAO;;AAI1B,SAAgB,sBACd,aACA,aACS;AACT,QAAO,mBAAmB,aAAa,YAAY,KAAK,KAAA;;;;;;;AAqB1D,SAAgB,2BACd,aACA,YACoB;AACpB,KAAI;EACF,MAAM,eAAe,KAAK,KACxB,YACA,gBACA,aACA,eACD;AAID,SAHiB,KAAK,MAAM,aAAa,cAAc,QAAQ,CAAC,CAGhD;SACV;AACN"}
@@ -0,0 +1,2 @@
1
+ import { r as hasDeclaredDependency } from "./package-json-Atg34fa4.js";
2
+ export { hasDeclaredDependency };
@@ -1,11 +1,12 @@
1
- import { a as AgentSignals, d as ErrorCodes, o as REMARK_INSTRUCTION, t as classifyRunFailure } from "./errors-CQ9kttJD.js";
2
- import { a as getLogFilePath, s as logToFile } from "./debug-Ch4BDOtD.js";
3
- import { t as VERSION } from "./version-aXxpgRKx.js";
4
- import { Q as WIZARD_USER_AGENT, Y as WIZARD_REMARK_EVENT_NAME } from "./constants-jFI2SaE1.js";
5
- import { n as analytics } from "./analytics-CHCZ_qUR.js";
6
- import { n as currentAccessToken } from "./oauth-session-DJ8h6GFa.js";
7
- import { l as gatewayAuth, o as withGatewayRemint, r as buildGatewayProvider, t as GATEWAY_PROVIDER } from "./gateway-CjoShdLa.js";
8
- import { g as assembleCommandments, p as AgentOutputSignals } from "./agent-interface-BAOIHuXS.js";
1
+ import { g as assembleCommandments, p as AgentOutputSignals } from "./agent-interface-FkbaBJwz.js";
2
+ import { n as ErrorCodes } from "./emit-BSetXzDV.js";
3
+ import { a as getLogFilePath, s as logToFile } from "./debug-kAHwWGg7.js";
4
+ import { t as VERSION } from "./version-CHhJjz_H.js";
5
+ import { Q as WIZARD_USER_AGENT, Y as WIZARD_REMARK_EVENT_NAME } from "./constants-DHCBSfnx.js";
6
+ import { n as analytics } from "./analytics-DXK1gc12.js";
7
+ import { t as classifyRunFailure } from "./errors-C2domSkK.js";
8
+ import { n as currentAccessToken } from "./oauth-session-DYM2Hrl2.js";
9
+ import { c as REMARK_INSTRUCTION, f as gatewayAuth, o as withGatewayRemint, r as buildGatewayProvider, s as AgentSignals, t as GATEWAY_PROVIDER } from "./gateway-C9-GlLO9.js";
9
10
  import fs from "fs";
10
11
  import path from "path";
11
12
  function appendStatus(messages, message) {
@@ -378,6 +379,41 @@ function bindPiCancellation(signal, session, onAbortError) {
378
379
  } };
379
380
  }
380
381
  //#endregion
382
+ //#region src/agent/runner/harness/pi/structured-output.ts
383
+ /** Apply the output contract at the provider boundary on every agent turn. */
384
+ function structuredOutputExtension(schema, api) {
385
+ return (pi) => {
386
+ pi.on("before_provider_request", (event) => {
387
+ const payload = event.payload;
388
+ const format = {
389
+ type: "json_schema",
390
+ schema
391
+ };
392
+ switch (api) {
393
+ case "anthropic-messages": return {
394
+ ...payload,
395
+ output_config: {
396
+ ...payload.output_config,
397
+ format
398
+ }
399
+ };
400
+ case "openai-responses": return {
401
+ ...payload,
402
+ text: {
403
+ ...payload.text,
404
+ format: {
405
+ ...format,
406
+ name: "wizard_result",
407
+ strict: true
408
+ }
409
+ }
410
+ };
411
+ case "openai-completions": throw new Error("Structured output is not supported on Chat Completions");
412
+ }
413
+ });
414
+ };
415
+ }
416
+ //#endregion
381
417
  //#region src/agent/runner/harness/pi/index.ts
382
418
  /**
383
419
  * The `pi` backend — the challenger. Drives pi.dev's coding agent
@@ -461,15 +497,23 @@ function withMode(tool, mode) {
461
497
  tool.executionMode = mode;
462
498
  return tool;
463
499
  }
464
- /** Pull plain text out of a pi AgentMessage (content is text/image blocks). */
465
- function extractText(message) {
500
+ /**
501
+ * The text blocks of a pi AgentMessage (content is text/image blocks). A
502
+ * Responses model can send several message items in one turn, commentary
503
+ * before its answer, and each becomes its own block.
504
+ */
505
+ function textBlocks(message) {
466
506
  const content = message?.content;
467
- if (typeof content === "string") return content;
507
+ if (typeof content === "string") return [content];
468
508
  if (Array.isArray(content)) return content.filter((c) => {
469
509
  const block = c;
470
510
  return block?.type === "text" && typeof block.text === "string";
471
- }).map((c) => c.text).join("");
472
- return "";
511
+ }).map((c) => c.text);
512
+ return [];
513
+ }
514
+ /** Pull plain text out of a pi AgentMessage. */
515
+ function extractText(message) {
516
+ return textBlocks(message).join("");
473
517
  }
474
518
  /**
475
519
  * Surface `[DASHBOARD_URL]` / `[NOTEBOOK_URL]` markers the agent prints (after
@@ -522,7 +566,7 @@ const piBackend = {
522
566
  classification: "WIZARD_ABORT",
523
567
  message: "Agent run cancelled"
524
568
  };
525
- const { config: runConfig, input, boot, emit, prompt, spinner } = inputs;
569
+ const { config: runConfig, input, boot, emit, prompt, spinner, structured } = inputs;
526
570
  const config = runConfig.run;
527
571
  const modelId = inputs.model;
528
572
  const log = createEmitLog(emit);
@@ -532,13 +576,16 @@ const piBackend = {
532
576
  apiHost: boot.credentials.host.apiHost,
533
577
  runTags: boot.wizardMetadata
534
578
  });
535
- log.step("Initializing Wizard agent...");
536
- log.step(`Verbose logs: ${getLogFilePath()}`);
537
- log.success("Agent initialized. Let's get cooking!");
579
+ if (!structured) {
580
+ log.step("Initializing Wizard agent...");
581
+ log.step(`Verbose logs: ${getLogFilePath()}`);
582
+ log.success("Agent initialized. Let's get cooking!");
583
+ }
538
584
  spinner.start(config.spinnerMessage ?? "Customizing your PostHog setup...");
539
585
  const startTime = Date.now();
540
586
  const signals = new AgentOutputSignals();
541
587
  let assistantTurns = 0;
588
+ let lastAssistantText = "";
542
589
  let toolCalls = 0;
543
590
  const runDurations = () => {
544
591
  const durationMs = Date.now() - startTime;
@@ -552,9 +599,30 @@ const piBackend = {
552
599
  ...runDurations(),
553
600
  model: modelId
554
601
  });
602
+ const timedOutResult = (timeoutMs) => {
603
+ spinner.stop("Agent run timed out");
604
+ captureAborted("WIZARD_AGENTIC_DETECTION_TIMEOUT");
605
+ return {
606
+ kind: "failure",
607
+ classification: "WIZARD_AGENTIC_DETECTION_TIMEOUT",
608
+ message: `Agent run timed out after ${timeoutMs / 1e3}s`
609
+ };
610
+ };
555
611
  let mcpCleanup;
556
612
  let aioFailed = true;
557
613
  let cancellation;
614
+ let timedOut = false;
615
+ let timeoutAbort;
616
+ let securityState;
617
+ const yaraViolationResult = () => {
618
+ spinner.stop("Security violation detected");
619
+ logToFile(`[pi] terminated: YARA violation (blocked ${securityState?.blockedCount} call(s))`);
620
+ captureAborted("WIZARD_YARA_VIOLATION");
621
+ return {
622
+ kind: "failure",
623
+ classification: "WIZARD_YARA_VIOLATION"
624
+ };
625
+ };
558
626
  try {
559
627
  const { createAgentSession, DefaultResourceLoader, SessionManager, AuthStorage, ModelRegistry, getAgentDir, createLsToolDefinition, createFindToolDefinition, createGrepToolDefinition, createBashToolDefinition, createReadToolDefinition, createEditToolDefinition, createWriteToolDefinition } = await import("@earendil-works/pi-coding-agent");
560
628
  const refreshAuth = async () => gatewayAuth(boot.credentials.host, await currentAccessToken(boot.credentials), boot.programId);
@@ -568,7 +636,7 @@ const piBackend = {
568
636
  modelId,
569
637
  effort: inputs.thinkingLevel
570
638
  });
571
- const { provider, caps } = buildGatewayProvider(providerInputs(auth));
639
+ const { provider, caps, api } = buildGatewayProvider(providerInputs(auth));
572
640
  const registry = ModelRegistry.inMemory(AuthStorage.create());
573
641
  registry.registerProvider(GATEWAY_PROVIDER, provider);
574
642
  const model = registry.find(GATEWAY_PROVIDER, modelId);
@@ -578,20 +646,22 @@ const piBackend = {
578
646
  message: "pi: gateway model could not be resolved"
579
647
  };
580
648
  const askState = { pending: false };
581
- const { createSecurityExtension } = await import("./security-Cg_4a7vB.js");
649
+ const { createSecurityExtension, READ_ONLY_PI_TOOLS } = await import("./security-C71pkwqH.js");
582
650
  const security = createSecurityExtension({
651
+ readOnly: config.readOnly,
583
652
  disallowedTools: runConfig.disallowedTools,
584
653
  getWizardAskPending: () => askState.pending,
585
654
  triageProvider: boot.triageProvider,
586
655
  workingDirectory: input.installDir
587
656
  });
588
- const { prewarmYaraScanner } = await import("./yara-hooks-DSGuCU9A.js");
657
+ securityState = security.state;
658
+ const { prewarmYaraScanner } = await import("./yara-hooks-DSuExwb4.js");
589
659
  prewarmYaraScanner();
590
660
  const extensionFactories = [security.factory];
591
661
  let mcpInstructions;
592
662
  let posthogMcp = false;
593
- try {
594
- const { setupPostHogMcp, fetchInstructions } = await import("./mcp-DAgaoGk5.js");
663
+ if (!config.readOnly) try {
664
+ const { setupPostHogMcp, fetchInstructions } = await import("./mcp-DnAyW0-w.js");
595
665
  const mcpToken = await currentAccessToken(boot.credentials);
596
666
  const instructionsPromise = fetchInstructions(boot.credentials.host.mcpUrl, mcpToken, WIZARD_USER_AGENT);
597
667
  const mcp = await setupPostHogMcp({
@@ -615,6 +685,7 @@ const piBackend = {
615
685
  error: String(err).slice(0, 300)
616
686
  });
617
687
  }
688
+ if (structured) extensionFactories.push(structuredOutputExtension(structured.schema, api));
618
689
  const resourceLoader = new DefaultResourceLoader({
619
690
  cwd: input.installDir,
620
691
  agentDir: getAgentDir(),
@@ -635,9 +706,9 @@ const piBackend = {
635
706
  extensionFactories
636
707
  });
637
708
  await resourceLoader.reload();
638
- const { createWizardPiTools } = await import("./tools-Dyfh9aCD.js");
639
- const { createWizardPiTaskTools } = await import("./tasks-Bbv_lOBG.js");
640
- const { createDispatchAgentTool } = await import("./subagent-BofIDK-O.js");
709
+ const { createWizardPiTools } = await import("./tools-CkJ2y9Wt.js");
710
+ const { createWizardPiTaskTools } = await import("./tasks-ChWufsdO.js");
711
+ const { createDispatchAgentTool } = await import("./subagent-D1TrTchE.js");
641
712
  const wizardTaskTools = createWizardPiTaskTools((tasks) => emit({
642
713
  kind: "tasks",
643
714
  tasks
@@ -681,7 +752,7 @@ const piBackend = {
681
752
  SessionManager
682
753
  }
683
754
  })
684
- ];
755
+ ].filter((tool) => !config.readOnly || READ_ONLY_PI_TOOLS.has(tool.name));
685
756
  const { session: agentSession } = await createAgentSession({
686
757
  model,
687
758
  modelRegistry: registry,
@@ -716,7 +787,16 @@ const piBackend = {
716
787
  if (event.message?.role !== "assistant") break;
717
788
  assistantTurns += 1;
718
789
  turns.noteAssistantTurn(event.message);
719
- const assistant = extractText(event.message).trim();
790
+ const blocks = textBlocks(event.message);
791
+ const assistant = blocks.join("").trim();
792
+ lastAssistantText = (blocks.at(-1) ?? "").trim();
793
+ if (structured) inputs.middleware?.onMessage({
794
+ type: "assistant",
795
+ message: { content: blocks.map((text) => ({
796
+ type: "text",
797
+ text
798
+ })) }
799
+ });
720
800
  if (assistant) {
721
801
  logToFile(`[pi] assistant: ${assistant.slice(0, 1e3)}`);
722
802
  applyOutroMarkers(assistant, emit);
@@ -736,6 +816,14 @@ const piBackend = {
736
816
  toolCalls += 1;
737
817
  const args = JSON.stringify(event.args ?? {}).slice(0, 200);
738
818
  logToFile(`[pi] → ${event.toolName} ${args}`);
819
+ if (structured) inputs.middleware?.onMessage({
820
+ type: "assistant",
821
+ message: { content: [{
822
+ type: "tool_use",
823
+ name: event.toolName,
824
+ input: event.args
825
+ }] }
826
+ });
739
827
  break;
740
828
  }
741
829
  case "tool_execution_end":
@@ -749,6 +837,12 @@ const piBackend = {
749
837
  });
750
838
  capture.setInitialPrompt(prompt);
751
839
  let terminal = turns.terminalFailure();
840
+ const timeout = structured && setTimeout(() => {
841
+ timedOut = true;
842
+ timeoutAbort = agentSession.abort().catch((error) => {
843
+ logToFile(`[pi] timeout abort failed: ${String(error)}`);
844
+ });
845
+ }, structured.timeoutMs);
752
846
  try {
753
847
  if (inputs.signal?.aborted) return {
754
848
  kind: "abort",
@@ -758,18 +852,19 @@ const piBackend = {
758
852
  await turns.prompt(prompt);
759
853
  terminal = turns.terminalFailure();
760
854
  let continueNudges = 0;
761
- while (continueNudges < MAX_CONTINUE_NUDGES && !security.state.criticalViolation && !inputs.signal?.aborted && !terminal && hasOpenTasks(wizardTaskTools.store)) {
855
+ while (!structured && continueNudges < MAX_CONTINUE_NUDGES && !security.state.criticalViolation && !inputs.signal?.aborted && !terminal && hasOpenTasks(wizardTaskTools.store)) {
762
856
  continueNudges += 1;
763
857
  logToFile(`[pi] completion guard: tasks still open, nudge ${continueNudges}/${MAX_CONTINUE_NUDGES}`);
764
858
  await turns.prompt(CONTINUE_INSTRUCTION);
765
859
  terminal = turns.terminalFailure();
766
860
  }
767
- if (!security.state.criticalViolation && !terminal && !inputs.signal?.aborted) try {
861
+ if (!structured && !security.state.criticalViolation && !terminal && !inputs.signal?.aborted) try {
768
862
  await agentSession.prompt(REMARK_INSTRUCTION);
769
863
  } catch (err) {
770
864
  logToFile(`[pi] remark request failed: ${String(err)}`);
771
865
  }
772
866
  } finally {
867
+ if (timeout) clearTimeout(timeout);
773
868
  try {
774
869
  unsubscribe();
775
870
  } catch {}
@@ -779,6 +874,7 @@ const piBackend = {
779
874
  classification: "WIZARD_ABORT",
780
875
  message: "Agent run cancelled"
781
876
  };
877
+ if (timedOut && structured && !security.state.criticalViolation) return timedOutResult(structured.timeoutMs);
782
878
  if (terminal && !security.state.criticalViolation) {
783
879
  spinner.stop(config.errorMessage ?? `${config.integrationLabel} failed`);
784
880
  captureAborted(terminal.classification);
@@ -800,16 +896,8 @@ const piBackend = {
800
896
  message: terminal.message
801
897
  };
802
898
  }
803
- if (security.state.criticalViolation) {
804
- spinner.stop("Security violation detected");
805
- logToFile(`[pi] terminated: YARA violation (blocked ${security.state.blockedCount} call(s))`);
806
- captureAborted("WIZARD_YARA_VIOLATION");
807
- return {
808
- kind: "failure",
809
- classification: "WIZARD_YARA_VIOLATION"
810
- };
811
- }
812
- const openTasks = hasOpenTasks(wizardTaskTools.store);
899
+ if (security.state.criticalViolation) return yaraViolationResult();
900
+ const openTasks = !structured && hasOpenTasks(wizardTaskTools.store);
813
901
  const failure = completionFailure({
814
902
  toolCalls,
815
903
  openTasks
@@ -818,10 +906,11 @@ const piBackend = {
818
906
  spinner.stop("Agent made no changes");
819
907
  logToFile(`[pi] no progress: ${assistantTurns} assistant turn(s), 0 tool calls`);
820
908
  analytics.wizardCapture("agent no progress", { assistant_turns: assistantTurns });
821
- captureAborted(failure);
909
+ const classification = structured ? "WIZARD_INVALID_STRUCTURED_OUTPUT" : failure;
910
+ captureAborted(classification);
822
911
  return {
823
912
  kind: "failure",
824
- classification: failure
913
+ classification
825
914
  };
826
915
  }
827
916
  if (failure === "WIZARD_INCOMPLETE_TASKS") {
@@ -840,7 +929,7 @@ const piBackend = {
840
929
  if (skillFailure !== void 0) analytics.wizardCapture("agent continued without skill", { detail: skillFailure });
841
930
  try {
842
931
  const planFile = path.join(input.installDir, ".posthog-events.json");
843
- if (fs.existsSync(planFile)) await fs.promises.rm(planFile);
932
+ if (!structured && fs.existsSync(planFile)) await fs.promises.rm(planFile);
844
933
  } catch (err) {
845
934
  logToFile(`[pi] .posthog-events.json cleanup skipped: ${String(err)}`);
846
935
  }
@@ -856,13 +945,23 @@ const piBackend = {
856
945
  });
857
946
  spinner.stop(config.successMessage ?? "PostHog integration complete");
858
947
  aioFailed = false;
859
- return { kind: "success" };
948
+ if (!structured) return { kind: "success" };
949
+ try {
950
+ return {
951
+ kind: "success",
952
+ structuredOutput: JSON.parse(lastAssistantText)
953
+ };
954
+ } catch {
955
+ return { kind: "success" };
956
+ }
860
957
  } catch (err) {
861
958
  if (inputs.signal?.aborted) return {
862
959
  kind: "abort",
863
960
  classification: "WIZARD_ABORT",
864
961
  message: "Agent run cancelled"
865
962
  };
963
+ if (securityState?.criticalViolation) return yaraViolationResult();
964
+ if (timedOut && structured) return timedOutResult(structured.timeoutMs);
866
965
  const message = err instanceof Error ? err.message : String(err);
867
966
  logToFile(`[pi] run error: ${message}`);
868
967
  spinner.stop(config.errorMessage ?? `${config.integrationLabel} failed`);
@@ -889,6 +988,7 @@ const piBackend = {
889
988
  };
890
989
  } finally {
891
990
  await cancellation?.settle();
991
+ await timeoutAbort;
892
992
  try {
893
993
  mcpCleanup?.();
894
994
  } catch {}
@@ -898,11 +998,11 @@ const piBackend = {
898
998
  }
899
999
  },
900
1000
  async runTask(inputs) {
901
- const { runPiTask } = await import("./task-r9t1UhQP.js");
1001
+ const { runPiTask } = await import("./task-DqRlQBfs.js");
902
1002
  return runPiTask(inputs);
903
1003
  }
904
1004
  };
905
1005
  //#endregion
906
1006
  export { piBackend as a, runErrorType as c, createEmitSpinner as d, createProgressCollector as f, lastStatusLine as i, createAioCapture as l, buildScrubbedEnv as n, withMode as o, appendStatus as p, extractText as r, bindPiCancellation as s, applyOutroMarkers as t, createEmitLog as u };
907
1007
 
908
- //# sourceMappingURL=pi-D3h5Ok0i.js.map
1008
+ //# sourceMappingURL=pi-8KsYsPmM.js.map