@posthog/wizard 2.78.0 → 2.79.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/README.md +20 -11
  2. package/dist/{add-mcp-server-to-clients-JMv8LP-O.js → add-mcp-server-to-clients-amlJWW7W.js} +5 -5
  3. package/dist/{add-mcp-server-to-clients-JMv8LP-O.js.map → add-mcp-server-to-clients-amlJWW7W.js.map} +1 -1
  4. package/dist/{agent-bCZ3i3fh.js → agent-CNrEC-9v.js} +130 -31
  5. package/dist/agent-CNrEC-9v.js.map +1 -0
  6. package/dist/{agent-interface-BAOIHuXS.js → agent-interface-BXvmAm4c.js} +48 -22
  7. package/dist/agent-interface-BXvmAm4c.js.map +1 -0
  8. package/dist/{agent-prompt-loader-7Pd4CfZO.js → agent-prompt-loader-DiKUbhi_.js} +5 -5
  9. package/dist/{agent-prompt-loader-7Pd4CfZO.js.map → agent-prompt-loader-DiKUbhi_.js.map} +1 -1
  10. package/dist/analytics-DxwRi2Hf.js +2 -0
  11. package/dist/{analytics-CHCZ_qUR.js → analytics-VRYdebXW.js} +4 -4
  12. package/dist/{analytics-CHCZ_qUR.js.map → analytics-VRYdebXW.js.map} +1 -1
  13. package/dist/{api-Diy_2fp8.js → api-DGuJTzjr.js} +3 -3
  14. package/dist/{api-Diy_2fp8.js.map → api-DGuJTzjr.js.map} +1 -1
  15. package/dist/bin.js +56 -53
  16. package/dist/bin.js.map +1 -1
  17. package/dist/{bounded-fs-Bx9zTe6m.js → bounded-fs-Cpn129A4.js} +3 -3
  18. package/dist/{bounded-fs-Bx9zTe6m.js.map → bounded-fs-Cpn129A4.js.map} +1 -1
  19. package/dist/{ci-install-CDdQYsPe.js → ci-install-BPA6gzEq.js} +6 -6
  20. package/dist/ci-install-BPA6gzEq.js.map +1 -0
  21. package/dist/{constants-jFI2SaE1.js → constants-CuJfQEcC.js} +3 -3
  22. package/dist/{constants-jFI2SaE1.js.map → constants-CuJfQEcC.js.map} +1 -1
  23. package/dist/{debug-M2gV2iDq.js → debug-B9k4ideV.js} +1 -1
  24. package/dist/{debug-Ch4BDOtD.js → debug-Cj-8vfXY.js} +2 -2
  25. package/dist/{debug-Ch4BDOtD.js.map → debug-Cj-8vfXY.js.map} +1 -1
  26. package/dist/{endpoints-DCVbM06L.js → endpoints-DnIX0pZH.js} +3 -3
  27. package/dist/{endpoints-DCVbM06L.js.map → endpoints-DnIX0pZH.js.map} +1 -1
  28. package/dist/{env-api-key-Qx8NnYHm.js → env-api-key-BWdKpGEr.js} +2 -2
  29. package/dist/{env-api-key-Qx8NnYHm.js.map → env-api-key-BWdKpGEr.js.map} +1 -1
  30. package/dist/{environment-B07Bmxae.js → environment-DZYUSCpV.js} +4 -4
  31. package/dist/{environment-B07Bmxae.js.map → environment-DZYUSCpV.js.map} +1 -1
  32. package/dist/{errors-CQ9kttJD.js → errors-ddDE6MbA.js} +4 -46
  33. package/dist/errors-ddDE6MbA.js.map +1 -0
  34. package/dist/{file-BcLTjU16.js → file-dEhr-l3n.js} +3 -3
  35. package/dist/file-dEhr-l3n.js.map +1 -0
  36. package/dist/{file-watcher-DWc_bTs6.js → file-watcher-CPM-Nn9L.js} +2 -2
  37. package/dist/{file-watcher-DWc_bTs6.js.map → file-watcher-CPM-Nn9L.js.map} +1 -1
  38. package/dist/{gateway-CjoShdLa.js → gateway-CVU1G0H3.js} +38 -8
  39. package/dist/gateway-CVU1G0H3.js.map +1 -0
  40. package/dist/{headless-ui-BFFmYC4v.js → headless-ui-pY2xB5ug.js} +2 -2
  41. package/dist/{headless-ui-BFFmYC4v.js.map → headless-ui-pY2xB5ug.js.map} +1 -1
  42. package/dist/{interactive-D6zV7brJ.js → interactive-BOGlinZe.js} +2 -2
  43. package/dist/interactive-BOGlinZe.js.map +1 -0
  44. package/dist/{logging-ui-_TwoMNbG.js → logging-ui-CUxNYF2t.js} +4 -4
  45. package/dist/{logging-ui-_TwoMNbG.js.map → logging-ui-CUxNYF2t.js.map} +1 -1
  46. package/dist/{mcp-DAgaoGk5.js → mcp-JcsBBnWv.js} +4 -4
  47. package/dist/{mcp-DAgaoGk5.js.map → mcp-JcsBBnWv.js.map} +1 -1
  48. package/dist/{mcp-prompt-streaming-I2U_X7BC.js → mcp-prompt-streaming-B-p_Pvb2.js} +6 -6
  49. package/dist/mcp-prompt-streaming-B-p_Pvb2.js.map +1 -0
  50. package/dist/{mint-failure-D4nd2XmZ.js → mint-failure-CZFZpHpW.js} +687 -125
  51. package/dist/mint-failure-CZFZpHpW.js.map +1 -0
  52. package/dist/{models-DDdBJKwT.js → models-DnAY67Lg.js} +2 -2
  53. package/dist/{models-DDdBJKwT.js.map → models-DnAY67Lg.js.map} +1 -1
  54. package/dist/{non-interactive-Dzow7YKY.js → non-interactive-DR1CWXY1.js} +3 -3
  55. package/dist/{non-interactive-Dzow7YKY.js.map → non-interactive-DR1CWXY1.js.map} +1 -1
  56. package/dist/{oauth-session-DJ8h6GFa.js → oauth-session-CQTFOk-I.js} +2 -2
  57. package/dist/{oauth-session-DJ8h6GFa.js.map → oauth-session-CQTFOk-I.js.map} +1 -1
  58. package/dist/{orchestrator-tools-szcdscwn.js → orchestrator-tools-CBdt-SXO.js} +3 -3
  59. package/dist/{orchestrator-tools-szcdscwn.js.map → orchestrator-tools-CBdt-SXO.js.map} +1 -1
  60. package/dist/{pi-D3h5Ok0i.js → pi-BtqcLX3y.js} +143 -44
  61. package/dist/pi-BtqcLX3y.js.map +1 -0
  62. package/dist/{playground-5AB4WgNF.js → playground-Dz-ZVjBk.js} +9 -9
  63. package/dist/playground-Dz-ZVjBk.js.map +1 -0
  64. package/dist/{posthog-DNn574nW.js → posthog-6Uqw_Eux.js} +3 -3
  65. package/dist/posthog-6Uqw_Eux.js.map +1 -0
  66. package/dist/{provisioning-B8uSqRZk.js → provisioning-Zf7yPcEs.js} +4 -4
  67. package/dist/{provisioning-B8uSqRZk.js.map → provisioning-Zf7yPcEs.js.map} +1 -1
  68. package/dist/{queue-tools-9OOVx5TE.js → queue-tools-B7_aCyd-.js} +3 -3
  69. package/dist/{queue-tools-9OOVx5TE.js.map → queue-tools-B7_aCyd-.js.map} +1 -1
  70. package/dist/{registry-8YG-kuXk.js → registry-B6iLGorH.js} +49 -49
  71. package/dist/registry-B6iLGorH.js.map +1 -0
  72. package/dist/{run-agent-legacy-d7rWlzQR.js → run-agent-legacy-6WcYMaR9.js} +822 -1020
  73. package/dist/run-agent-legacy-6WcYMaR9.js.map +1 -0
  74. package/dist/{security-Cg_4a7vB.js → security-lkBwWbrK.js} +16 -6
  75. package/dist/security-lkBwWbrK.js.map +1 -0
  76. package/dist/{setup-utils-CmTCTPkX.js → setup-utils-dCViCC6s.js} +11 -11
  77. package/dist/setup-utils-dCViCC6s.js.map +1 -0
  78. package/dist/{start-tui-CB2PZs1x.js → start-tui-oCWMgsDP.js} +26 -26
  79. package/dist/start-tui-oCWMgsDP.js.map +1 -0
  80. package/dist/{steps-BZcXRJNY.js → steps-gx0Pq4I4.js} +7 -7
  81. package/dist/{steps-BZcXRJNY.js.map → steps-gx0Pq4I4.js.map} +1 -1
  82. package/dist/{store-UN7c-ASf.js → store-xYy_6Ruv.js} +10 -10
  83. package/dist/store-xYy_6Ruv.js.map +1 -0
  84. package/dist/{subagent-BofIDK-O.js → subagent-Bfy0sfhU.js} +3 -3
  85. package/dist/{subagent-BofIDK-O.js.map → subagent-Bfy0sfhU.js.map} +1 -1
  86. package/dist/{task-r9t1UhQP.js → task-BOfw7GPc.js} +16 -16
  87. package/dist/{task-r9t1UhQP.js.map → task-BOfw7GPc.js.map} +1 -1
  88. package/dist/{task-stream-CMUilu54.js → task-stream-kYlm9qd0.js} +9 -9
  89. package/dist/task-stream-kYlm9qd0.js.map +1 -0
  90. package/dist/{telemetry-D6ruCtnv.js → telemetry-Bpv-Mh5B.js} +3 -3
  91. package/dist/{telemetry-D6ruCtnv.js.map → telemetry-Bpv-Mh5B.js.map} +1 -1
  92. package/dist/{terminal-DrGyci_a.js → terminal-D07EQ2y0.js} +15 -15
  93. package/dist/terminal-D07EQ2y0.js.map +1 -0
  94. package/dist/{tools-Dyfh9aCD.js → tools-Cc41af5W.js} +8 -8
  95. package/dist/{tools-Dyfh9aCD.js.map → tools-Cc41af5W.js.map} +1 -1
  96. package/dist/{ui-BBVuTM1v.js → ui-CGXtC7Vn.js} +3 -3
  97. package/dist/{ui-BBVuTM1v.js.map → ui-CGXtC7Vn.js.map} +1 -1
  98. package/dist/{version-aXxpgRKx.js → version-Cadof0Z_.js} +2 -2
  99. package/dist/{version-aXxpgRKx.js.map → version-Cadof0Z_.js.map} +1 -1
  100. package/dist/{wizard-abort-BBkiUxfS.js → wizard-abort-HDbP3YcS.js} +6 -6
  101. package/dist/{wizard-abort-BBkiUxfS.js.map → wizard-abort-HDbP3YcS.js.map} +1 -1
  102. package/dist/wizard-abort-Y-Ip2K4z.js +3 -0
  103. package/dist/wizard-session-2w4Ru-Wz.js.map +1 -1
  104. package/dist/yara-hooks-B49RIk5d.js +2 -0
  105. package/dist/{yara-hooks-DCeMDd1o.js → yara-hooks-DCfROpZt.js} +5 -5
  106. package/dist/{yara-hooks-DCeMDd1o.js.map → yara-hooks-DCfROpZt.js.map} +1 -1
  107. package/package.json +2 -1
  108. package/dist/agent-bCZ3i3fh.js.map +0 -1
  109. package/dist/agent-interface-BAOIHuXS.js.map +0 -1
  110. package/dist/analytics-BcV-WCM4.js +0 -2
  111. package/dist/ci-install-CDdQYsPe.js.map +0 -1
  112. package/dist/errors-CQ9kttJD.js.map +0 -1
  113. package/dist/file-BcLTjU16.js.map +0 -1
  114. package/dist/gateway-CjoShdLa.js.map +0 -1
  115. package/dist/interactive-D6zV7brJ.js.map +0 -1
  116. package/dist/mcp-prompt-streaming-I2U_X7BC.js.map +0 -1
  117. package/dist/mint-failure-D4nd2XmZ.js.map +0 -1
  118. package/dist/pi-D3h5Ok0i.js.map +0 -1
  119. package/dist/playground-5AB4WgNF.js.map +0 -1
  120. package/dist/posthog-DNn574nW.js.map +0 -1
  121. package/dist/registry-8YG-kuXk.js.map +0 -1
  122. package/dist/run-agent-legacy-d7rWlzQR.js.map +0 -1
  123. package/dist/security-Cg_4a7vB.js.map +0 -1
  124. package/dist/setup-utils-CmTCTPkX.js.map +0 -1
  125. package/dist/start-tui-CB2PZs1x.js.map +0 -1
  126. package/dist/store-UN7c-ASf.js.map +0 -1
  127. package/dist/task-stream-CMUilu54.js.map +0 -1
  128. package/dist/terminal-DrGyci_a.js.map +0 -1
  129. package/dist/wizard-abort-BU4aLyvh.js +0 -3
  130. 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-CuJfQEcC.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-DnAY67Lg.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-DnAY67Lg.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,5 @@
1
- import { d as ErrorCodes, u as emitWizardError } from "./errors-CQ9kttJD.js";
2
- import { t as getUI } from "./ui-BBVuTM1v.js";
1
+ import { o as emitWizardError, s as ErrorCodes } from "./errors-ddDE6MbA.js";
2
+ import { t as getUI } from "./ui-CGXtC7Vn.js";
3
3
  //#region src/commands/basic-integration/non-interactive.ts
4
4
  /** Print the "needs a TTY" error and exit. Used when no `--ci` flag and no TTY. */
5
5
  function failNonInteractive() {
@@ -14,4 +14,4 @@ function failNonInteractive() {
14
14
  //#endregion
15
15
  export { failNonInteractive };
16
16
 
17
- //# sourceMappingURL=non-interactive-Dzow7YKY.js.map
17
+ //# sourceMappingURL=non-interactive-DR1CWXY1.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-DR1CWXY1.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-Cj-8vfXY.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-CQTFOk-I.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-CQTFOk-I.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-VRYdebXW.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-B7_aCyd-.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-CBdt-SXO.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-CBdt-SXO.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,11 +1,11 @@
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 { s as ErrorCodes, t as classifyRunFailure } from "./errors-ddDE6MbA.js";
2
+ import { a as getLogFilePath, s as logToFile } from "./debug-Cj-8vfXY.js";
3
+ import { t as VERSION } from "./version-Cadof0Z_.js";
4
+ import { Q as WIZARD_USER_AGENT, Y as WIZARD_REMARK_EVENT_NAME } from "./constants-CuJfQEcC.js";
5
+ import { n as analytics } from "./analytics-VRYdebXW.js";
6
+ import { n as currentAccessToken } from "./oauth-session-CQTFOk-I.js";
7
+ import { c as REMARK_INSTRUCTION, f as gatewayAuth, o as withGatewayRemint, r as buildGatewayProvider, s as AgentSignals, t as GATEWAY_PROVIDER } from "./gateway-CVU1G0H3.js";
8
+ import { g as assembleCommandments, p as AgentOutputSignals } from "./agent-interface-BXvmAm4c.js";
9
9
  import fs from "fs";
10
10
  import path from "path";
11
11
  function appendStatus(messages, message) {
@@ -378,6 +378,41 @@ function bindPiCancellation(signal, session, onAbortError) {
378
378
  } };
379
379
  }
380
380
  //#endregion
381
+ //#region src/agent/runner/harness/pi/structured-output.ts
382
+ /** Apply the output contract at the provider boundary on every agent turn. */
383
+ function structuredOutputExtension(schema, api) {
384
+ return (pi) => {
385
+ pi.on("before_provider_request", (event) => {
386
+ const payload = event.payload;
387
+ const format = {
388
+ type: "json_schema",
389
+ schema
390
+ };
391
+ switch (api) {
392
+ case "anthropic-messages": return {
393
+ ...payload,
394
+ output_config: {
395
+ ...payload.output_config,
396
+ format
397
+ }
398
+ };
399
+ case "openai-responses": return {
400
+ ...payload,
401
+ text: {
402
+ ...payload.text,
403
+ format: {
404
+ ...format,
405
+ name: "wizard_result",
406
+ strict: true
407
+ }
408
+ }
409
+ };
410
+ case "openai-completions": throw new Error("Structured output is not supported on Chat Completions");
411
+ }
412
+ });
413
+ };
414
+ }
415
+ //#endregion
381
416
  //#region src/agent/runner/harness/pi/index.ts
382
417
  /**
383
418
  * The `pi` backend — the challenger. Drives pi.dev's coding agent
@@ -461,15 +496,23 @@ function withMode(tool, mode) {
461
496
  tool.executionMode = mode;
462
497
  return tool;
463
498
  }
464
- /** Pull plain text out of a pi AgentMessage (content is text/image blocks). */
465
- function extractText(message) {
499
+ /**
500
+ * The text blocks of a pi AgentMessage (content is text/image blocks). A
501
+ * Responses model can send several message items in one turn, commentary
502
+ * before its answer, and each becomes its own block.
503
+ */
504
+ function textBlocks(message) {
466
505
  const content = message?.content;
467
- if (typeof content === "string") return content;
506
+ if (typeof content === "string") return [content];
468
507
  if (Array.isArray(content)) return content.filter((c) => {
469
508
  const block = c;
470
509
  return block?.type === "text" && typeof block.text === "string";
471
- }).map((c) => c.text).join("");
472
- return "";
510
+ }).map((c) => c.text);
511
+ return [];
512
+ }
513
+ /** Pull plain text out of a pi AgentMessage. */
514
+ function extractText(message) {
515
+ return textBlocks(message).join("");
473
516
  }
474
517
  /**
475
518
  * Surface `[DASHBOARD_URL]` / `[NOTEBOOK_URL]` markers the agent prints (after
@@ -522,7 +565,7 @@ const piBackend = {
522
565
  classification: "WIZARD_ABORT",
523
566
  message: "Agent run cancelled"
524
567
  };
525
- const { config: runConfig, input, boot, emit, prompt, spinner } = inputs;
568
+ const { config: runConfig, input, boot, emit, prompt, spinner, structured } = inputs;
526
569
  const config = runConfig.run;
527
570
  const modelId = inputs.model;
528
571
  const log = createEmitLog(emit);
@@ -532,13 +575,16 @@ const piBackend = {
532
575
  apiHost: boot.credentials.host.apiHost,
533
576
  runTags: boot.wizardMetadata
534
577
  });
535
- log.step("Initializing Wizard agent...");
536
- log.step(`Verbose logs: ${getLogFilePath()}`);
537
- log.success("Agent initialized. Let's get cooking!");
578
+ if (!structured) {
579
+ log.step("Initializing Wizard agent...");
580
+ log.step(`Verbose logs: ${getLogFilePath()}`);
581
+ log.success("Agent initialized. Let's get cooking!");
582
+ }
538
583
  spinner.start(config.spinnerMessage ?? "Customizing your PostHog setup...");
539
584
  const startTime = Date.now();
540
585
  const signals = new AgentOutputSignals();
541
586
  let assistantTurns = 0;
587
+ let lastAssistantText = "";
542
588
  let toolCalls = 0;
543
589
  const runDurations = () => {
544
590
  const durationMs = Date.now() - startTime;
@@ -552,9 +598,30 @@ const piBackend = {
552
598
  ...runDurations(),
553
599
  model: modelId
554
600
  });
601
+ const timedOutResult = (timeoutMs) => {
602
+ spinner.stop("Agent run timed out");
603
+ captureAborted("WIZARD_AGENTIC_DETECTION_TIMEOUT");
604
+ return {
605
+ kind: "failure",
606
+ classification: "WIZARD_AGENTIC_DETECTION_TIMEOUT",
607
+ message: `Agent run timed out after ${timeoutMs / 1e3}s`
608
+ };
609
+ };
555
610
  let mcpCleanup;
556
611
  let aioFailed = true;
557
612
  let cancellation;
613
+ let timedOut = false;
614
+ let timeoutAbort;
615
+ let securityState;
616
+ const yaraViolationResult = () => {
617
+ spinner.stop("Security violation detected");
618
+ logToFile(`[pi] terminated: YARA violation (blocked ${securityState?.blockedCount} call(s))`);
619
+ captureAborted("WIZARD_YARA_VIOLATION");
620
+ return {
621
+ kind: "failure",
622
+ classification: "WIZARD_YARA_VIOLATION"
623
+ };
624
+ };
558
625
  try {
559
626
  const { createAgentSession, DefaultResourceLoader, SessionManager, AuthStorage, ModelRegistry, getAgentDir, createLsToolDefinition, createFindToolDefinition, createGrepToolDefinition, createBashToolDefinition, createReadToolDefinition, createEditToolDefinition, createWriteToolDefinition } = await import("@earendil-works/pi-coding-agent");
560
627
  const refreshAuth = async () => gatewayAuth(boot.credentials.host, await currentAccessToken(boot.credentials), boot.programId);
@@ -568,7 +635,7 @@ const piBackend = {
568
635
  modelId,
569
636
  effort: inputs.thinkingLevel
570
637
  });
571
- const { provider, caps } = buildGatewayProvider(providerInputs(auth));
638
+ const { provider, caps, api } = buildGatewayProvider(providerInputs(auth));
572
639
  const registry = ModelRegistry.inMemory(AuthStorage.create());
573
640
  registry.registerProvider(GATEWAY_PROVIDER, provider);
574
641
  const model = registry.find(GATEWAY_PROVIDER, modelId);
@@ -578,20 +645,22 @@ const piBackend = {
578
645
  message: "pi: gateway model could not be resolved"
579
646
  };
580
647
  const askState = { pending: false };
581
- const { createSecurityExtension } = await import("./security-Cg_4a7vB.js");
648
+ const { createSecurityExtension, READ_ONLY_PI_TOOLS } = await import("./security-lkBwWbrK.js");
582
649
  const security = createSecurityExtension({
650
+ readOnly: config.readOnly,
583
651
  disallowedTools: runConfig.disallowedTools,
584
652
  getWizardAskPending: () => askState.pending,
585
653
  triageProvider: boot.triageProvider,
586
654
  workingDirectory: input.installDir
587
655
  });
588
- const { prewarmYaraScanner } = await import("./yara-hooks-DSGuCU9A.js");
656
+ securityState = security.state;
657
+ const { prewarmYaraScanner } = await import("./yara-hooks-B49RIk5d.js");
589
658
  prewarmYaraScanner();
590
659
  const extensionFactories = [security.factory];
591
660
  let mcpInstructions;
592
661
  let posthogMcp = false;
593
- try {
594
- const { setupPostHogMcp, fetchInstructions } = await import("./mcp-DAgaoGk5.js");
662
+ if (!config.readOnly) try {
663
+ const { setupPostHogMcp, fetchInstructions } = await import("./mcp-JcsBBnWv.js");
595
664
  const mcpToken = await currentAccessToken(boot.credentials);
596
665
  const instructionsPromise = fetchInstructions(boot.credentials.host.mcpUrl, mcpToken, WIZARD_USER_AGENT);
597
666
  const mcp = await setupPostHogMcp({
@@ -615,6 +684,7 @@ const piBackend = {
615
684
  error: String(err).slice(0, 300)
616
685
  });
617
686
  }
687
+ if (structured) extensionFactories.push(structuredOutputExtension(structured.schema, api));
618
688
  const resourceLoader = new DefaultResourceLoader({
619
689
  cwd: input.installDir,
620
690
  agentDir: getAgentDir(),
@@ -635,9 +705,9 @@ const piBackend = {
635
705
  extensionFactories
636
706
  });
637
707
  await resourceLoader.reload();
638
- const { createWizardPiTools } = await import("./tools-Dyfh9aCD.js");
708
+ const { createWizardPiTools } = await import("./tools-Cc41af5W.js");
639
709
  const { createWizardPiTaskTools } = await import("./tasks-Bbv_lOBG.js");
640
- const { createDispatchAgentTool } = await import("./subagent-BofIDK-O.js");
710
+ const { createDispatchAgentTool } = await import("./subagent-Bfy0sfhU.js");
641
711
  const wizardTaskTools = createWizardPiTaskTools((tasks) => emit({
642
712
  kind: "tasks",
643
713
  tasks
@@ -681,7 +751,7 @@ const piBackend = {
681
751
  SessionManager
682
752
  }
683
753
  })
684
- ];
754
+ ].filter((tool) => !config.readOnly || READ_ONLY_PI_TOOLS.has(tool.name));
685
755
  const { session: agentSession } = await createAgentSession({
686
756
  model,
687
757
  modelRegistry: registry,
@@ -716,7 +786,16 @@ const piBackend = {
716
786
  if (event.message?.role !== "assistant") break;
717
787
  assistantTurns += 1;
718
788
  turns.noteAssistantTurn(event.message);
719
- const assistant = extractText(event.message).trim();
789
+ const blocks = textBlocks(event.message);
790
+ const assistant = blocks.join("").trim();
791
+ lastAssistantText = (blocks.at(-1) ?? "").trim();
792
+ if (structured) inputs.middleware?.onMessage({
793
+ type: "assistant",
794
+ message: { content: blocks.map((text) => ({
795
+ type: "text",
796
+ text
797
+ })) }
798
+ });
720
799
  if (assistant) {
721
800
  logToFile(`[pi] assistant: ${assistant.slice(0, 1e3)}`);
722
801
  applyOutroMarkers(assistant, emit);
@@ -736,6 +815,14 @@ const piBackend = {
736
815
  toolCalls += 1;
737
816
  const args = JSON.stringify(event.args ?? {}).slice(0, 200);
738
817
  logToFile(`[pi] → ${event.toolName} ${args}`);
818
+ if (structured) inputs.middleware?.onMessage({
819
+ type: "assistant",
820
+ message: { content: [{
821
+ type: "tool_use",
822
+ name: event.toolName,
823
+ input: event.args
824
+ }] }
825
+ });
739
826
  break;
740
827
  }
741
828
  case "tool_execution_end":
@@ -749,6 +836,12 @@ const piBackend = {
749
836
  });
750
837
  capture.setInitialPrompt(prompt);
751
838
  let terminal = turns.terminalFailure();
839
+ const timeout = structured && setTimeout(() => {
840
+ timedOut = true;
841
+ timeoutAbort = agentSession.abort().catch((error) => {
842
+ logToFile(`[pi] timeout abort failed: ${String(error)}`);
843
+ });
844
+ }, structured.timeoutMs);
752
845
  try {
753
846
  if (inputs.signal?.aborted) return {
754
847
  kind: "abort",
@@ -758,18 +851,19 @@ const piBackend = {
758
851
  await turns.prompt(prompt);
759
852
  terminal = turns.terminalFailure();
760
853
  let continueNudges = 0;
761
- while (continueNudges < MAX_CONTINUE_NUDGES && !security.state.criticalViolation && !inputs.signal?.aborted && !terminal && hasOpenTasks(wizardTaskTools.store)) {
854
+ while (!structured && continueNudges < MAX_CONTINUE_NUDGES && !security.state.criticalViolation && !inputs.signal?.aborted && !terminal && hasOpenTasks(wizardTaskTools.store)) {
762
855
  continueNudges += 1;
763
856
  logToFile(`[pi] completion guard: tasks still open, nudge ${continueNudges}/${MAX_CONTINUE_NUDGES}`);
764
857
  await turns.prompt(CONTINUE_INSTRUCTION);
765
858
  terminal = turns.terminalFailure();
766
859
  }
767
- if (!security.state.criticalViolation && !terminal && !inputs.signal?.aborted) try {
860
+ if (!structured && !security.state.criticalViolation && !terminal && !inputs.signal?.aborted) try {
768
861
  await agentSession.prompt(REMARK_INSTRUCTION);
769
862
  } catch (err) {
770
863
  logToFile(`[pi] remark request failed: ${String(err)}`);
771
864
  }
772
865
  } finally {
866
+ if (timeout) clearTimeout(timeout);
773
867
  try {
774
868
  unsubscribe();
775
869
  } catch {}
@@ -779,6 +873,7 @@ const piBackend = {
779
873
  classification: "WIZARD_ABORT",
780
874
  message: "Agent run cancelled"
781
875
  };
876
+ if (timedOut && structured && !security.state.criticalViolation) return timedOutResult(structured.timeoutMs);
782
877
  if (terminal && !security.state.criticalViolation) {
783
878
  spinner.stop(config.errorMessage ?? `${config.integrationLabel} failed`);
784
879
  captureAborted(terminal.classification);
@@ -800,16 +895,8 @@ const piBackend = {
800
895
  message: terminal.message
801
896
  };
802
897
  }
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);
898
+ if (security.state.criticalViolation) return yaraViolationResult();
899
+ const openTasks = !structured && hasOpenTasks(wizardTaskTools.store);
813
900
  const failure = completionFailure({
814
901
  toolCalls,
815
902
  openTasks
@@ -818,10 +905,11 @@ const piBackend = {
818
905
  spinner.stop("Agent made no changes");
819
906
  logToFile(`[pi] no progress: ${assistantTurns} assistant turn(s), 0 tool calls`);
820
907
  analytics.wizardCapture("agent no progress", { assistant_turns: assistantTurns });
821
- captureAborted(failure);
908
+ const classification = structured ? "WIZARD_INVALID_STRUCTURED_OUTPUT" : failure;
909
+ captureAborted(classification);
822
910
  return {
823
911
  kind: "failure",
824
- classification: failure
912
+ classification
825
913
  };
826
914
  }
827
915
  if (failure === "WIZARD_INCOMPLETE_TASKS") {
@@ -840,7 +928,7 @@ const piBackend = {
840
928
  if (skillFailure !== void 0) analytics.wizardCapture("agent continued without skill", { detail: skillFailure });
841
929
  try {
842
930
  const planFile = path.join(input.installDir, ".posthog-events.json");
843
- if (fs.existsSync(planFile)) await fs.promises.rm(planFile);
931
+ if (!structured && fs.existsSync(planFile)) await fs.promises.rm(planFile);
844
932
  } catch (err) {
845
933
  logToFile(`[pi] .posthog-events.json cleanup skipped: ${String(err)}`);
846
934
  }
@@ -856,13 +944,23 @@ const piBackend = {
856
944
  });
857
945
  spinner.stop(config.successMessage ?? "PostHog integration complete");
858
946
  aioFailed = false;
859
- return { kind: "success" };
947
+ if (!structured) return { kind: "success" };
948
+ try {
949
+ return {
950
+ kind: "success",
951
+ structuredOutput: JSON.parse(lastAssistantText)
952
+ };
953
+ } catch {
954
+ return { kind: "success" };
955
+ }
860
956
  } catch (err) {
861
957
  if (inputs.signal?.aborted) return {
862
958
  kind: "abort",
863
959
  classification: "WIZARD_ABORT",
864
960
  message: "Agent run cancelled"
865
961
  };
962
+ if (securityState?.criticalViolation) return yaraViolationResult();
963
+ if (timedOut && structured) return timedOutResult(structured.timeoutMs);
866
964
  const message = err instanceof Error ? err.message : String(err);
867
965
  logToFile(`[pi] run error: ${message}`);
868
966
  spinner.stop(config.errorMessage ?? `${config.integrationLabel} failed`);
@@ -889,6 +987,7 @@ const piBackend = {
889
987
  };
890
988
  } finally {
891
989
  await cancellation?.settle();
990
+ await timeoutAbort;
892
991
  try {
893
992
  mcpCleanup?.();
894
993
  } catch {}
@@ -898,11 +997,11 @@ const piBackend = {
898
997
  }
899
998
  },
900
999
  async runTask(inputs) {
901
- const { runPiTask } = await import("./task-r9t1UhQP.js");
1000
+ const { runPiTask } = await import("./task-BOfw7GPc.js");
902
1001
  return runPiTask(inputs);
903
1002
  }
904
1003
  };
905
1004
  //#endregion
906
1005
  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
1006
 
908
- //# sourceMappingURL=pi-D3h5Ok0i.js.map
1007
+ //# sourceMappingURL=pi-BtqcLX3y.js.map