@posthog/wizard 2.76.1 → 2.78.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 (176) hide show
  1. package/README.md +30 -15
  2. package/dist/README.md +16 -15
  3. package/dist/{add-mcp-server-to-clients-4yHaRvOo.js → add-mcp-server-to-clients-JMv8LP-O.js} +429 -114
  4. package/dist/add-mcp-server-to-clients-JMv8LP-O.js.map +1 -0
  5. package/dist/agent-bCZ3i3fh.js +3085 -0
  6. package/dist/agent-bCZ3i3fh.js.map +1 -0
  7. package/dist/{agent-interface-DPaPdIjS.js → agent-interface-BAOIHuXS.js} +452 -377
  8. package/dist/agent-interface-BAOIHuXS.js.map +1 -0
  9. package/dist/{agent-prompt-loader-BlhabNM2.js → agent-prompt-loader-7Pd4CfZO.js} +24 -8
  10. package/dist/agent-prompt-loader-7Pd4CfZO.js.map +1 -0
  11. package/dist/analytics-BcV-WCM4.js +2 -0
  12. package/dist/{analytics-DSVyjIVF.js → analytics-CHCZ_qUR.js} +10 -6
  13. package/dist/analytics-CHCZ_qUR.js.map +1 -0
  14. package/dist/{api-Ci0dZWLR.js → api-Diy_2fp8.js} +4 -17
  15. package/dist/api-Diy_2fp8.js.map +1 -0
  16. package/dist/bin.js +410 -68
  17. package/dist/bin.js.map +1 -1
  18. package/dist/{bounded-fs-FbZJ_vJ_.js → bounded-fs-Bx9zTe6m.js} +4 -4
  19. package/dist/bounded-fs-Bx9zTe6m.js.map +1 -0
  20. package/dist/check-screens.tsx +1 -1
  21. package/dist/{ci-install-CEVCqahf.js → ci-install-CDdQYsPe.js} +6 -5
  22. package/dist/ci-install-CDdQYsPe.js.map +1 -0
  23. package/dist/constants-jFI2SaE1.js +260 -0
  24. package/dist/constants-jFI2SaE1.js.map +1 -0
  25. package/dist/debug-Ch4BDOtD.js +171 -0
  26. package/dist/debug-Ch4BDOtD.js.map +1 -0
  27. package/dist/{debug-C6KWXbQi.js → debug-M2gV2iDq.js} +1 -1
  28. package/dist/{defaults-DulzMJpN.js → defaults-C6J7yL4O.js} +26 -3
  29. package/dist/defaults-C6J7yL4O.js.map +1 -0
  30. package/dist/endpoints-DCVbM06L.js +108 -0
  31. package/dist/endpoints-DCVbM06L.js.map +1 -0
  32. package/dist/{env-api-key-DwmkB3fm.js → env-api-key-Qx8NnYHm.js} +3 -3
  33. package/dist/env-api-key-Qx8NnYHm.js.map +1 -0
  34. package/dist/{environment-1wA7uwAS.js → environment-B07Bmxae.js} +6 -6
  35. package/dist/environment-B07Bmxae.js.map +1 -0
  36. package/dist/{errors--OqLxmWR.js → errors-CQ9kttJD.js} +30 -35
  37. package/dist/errors-CQ9kttJD.js.map +1 -0
  38. package/dist/{file-C3HGL1IM.js → file-BcLTjU16.js} +2 -2
  39. package/dist/{file-C3HGL1IM.js.map → file-BcLTjU16.js.map} +1 -1
  40. package/dist/{file-watcher-D8s0b-VT.js → file-watcher-DWc_bTs6.js} +2 -2
  41. package/dist/{file-watcher-D8s0b-VT.js.map → file-watcher-DWc_bTs6.js.map} +1 -1
  42. package/dist/{gateway-session-OqzCMpZ9.js → gateway-CjoShdLa.js} +175 -20
  43. package/dist/gateway-CjoShdLa.js.map +1 -0
  44. package/dist/generate-version.cjs +1 -1
  45. package/dist/{headless-ui-DRGWDg9Z.js → headless-ui-BFFmYC4v.js} +13 -2
  46. package/dist/headless-ui-BFFmYC4v.js.map +1 -0
  47. package/dist/{interactive-B6OlvhSf.js → interactive-D6zV7brJ.js} +2 -2
  48. package/dist/{interactive-B6OlvhSf.js.map → interactive-D6zV7brJ.js.map} +1 -1
  49. package/dist/{local-dev-DPZiIPCK.js → local-dev-McsurOC-.js} +2 -2
  50. package/dist/local-dev-McsurOC-.js.map +1 -0
  51. package/dist/logging-ui-_TwoMNbG.js +226 -0
  52. package/dist/logging-ui-_TwoMNbG.js.map +1 -0
  53. package/dist/mcp-DAgaoGk5.js +97 -0
  54. package/dist/mcp-DAgaoGk5.js.map +1 -0
  55. package/dist/{mcp-prompt-streaming-E1d8DJcX.js → mcp-prompt-streaming-I2U_X7BC.js} +7 -6
  56. package/dist/mcp-prompt-streaming-I2U_X7BC.js.map +1 -0
  57. package/dist/{mint-failure-C82j0RMC.js → mint-failure-D4nd2XmZ.js} +134 -48
  58. package/dist/mint-failure-D4nd2XmZ.js.map +1 -0
  59. package/dist/models-DDdBJKwT.js +83 -0
  60. package/dist/models-DDdBJKwT.js.map +1 -0
  61. package/dist/{non-interactive-DGT2H_n4.js → non-interactive-Dzow7YKY.js} +3 -3
  62. package/dist/non-interactive-Dzow7YKY.js.map +1 -0
  63. package/dist/oauth-session-DJ8h6GFa.js +74 -0
  64. package/dist/oauth-session-DJ8h6GFa.js.map +1 -0
  65. package/dist/{orchestrator-tools-BBBNV1z5.js → orchestrator-tools-szcdscwn.js} +5 -5
  66. package/dist/orchestrator-tools-szcdscwn.js.map +1 -0
  67. package/dist/{package-json-xt3eeyBI.js → package-json-DY70kkNp.js} +2 -2
  68. package/dist/package-json-DY70kkNp.js.map +1 -0
  69. package/dist/{pi-fG5fT50Y.js → pi-D3h5Ok0i.js} +329 -65
  70. package/dist/pi-D3h5Ok0i.js.map +1 -0
  71. package/dist/{playground-UFSHP-Yn.js → playground-5AB4WgNF.js} +18 -10
  72. package/dist/playground-5AB4WgNF.js.map +1 -0
  73. package/dist/{posthog-O9kKcnda.js → posthog-DNn574nW.js} +8 -3
  74. package/dist/posthog-DNn574nW.js.map +1 -0
  75. package/dist/{provisioning-B-tzjG4r.js → provisioning-B8uSqRZk.js} +6 -5
  76. package/dist/provisioning-B8uSqRZk.js.map +1 -0
  77. package/dist/{queue-tools-7Oso-fpt.js → queue-tools-9OOVx5TE.js} +11 -86
  78. package/dist/queue-tools-9OOVx5TE.js.map +1 -0
  79. package/dist/{registry-D1L5e-WQ.js → registry-8YG-kuXk.js} +265 -6
  80. package/dist/registry-8YG-kuXk.js.map +1 -0
  81. package/dist/run-agent-legacy-d7rWlzQR.js +3739 -0
  82. package/dist/run-agent-legacy-d7rWlzQR.js.map +1 -0
  83. package/dist/{security-n3-xdINN.js → security-Cg_4a7vB.js} +6 -6
  84. package/dist/security-Cg_4a7vB.js.map +1 -0
  85. package/dist/{setup-utils-Bj0gejEf.js → setup-utils-CmTCTPkX.js} +46 -18
  86. package/dist/setup-utils-CmTCTPkX.js.map +1 -0
  87. package/dist/smoke-test.sh +1 -1
  88. package/dist/{start-tui-BowrTPXm.js → start-tui-CB2PZs1x.js} +42 -48
  89. package/dist/start-tui-CB2PZs1x.js.map +1 -0
  90. package/dist/{steps-CpNTGu9N.js → steps-BZcXRJNY.js} +7 -7
  91. package/dist/{steps-CpNTGu9N.js.map → steps-BZcXRJNY.js.map} +1 -1
  92. package/dist/{store-CVkJKlny.js → store-UN7c-ASf.js} +18 -55
  93. package/dist/store-UN7c-ASf.js.map +1 -0
  94. package/dist/{subagent-SxmvfDfp.js → subagent-BofIDK-O.js} +8 -3
  95. package/dist/subagent-BofIDK-O.js.map +1 -0
  96. package/dist/{task-nF7Ry8ff.js → task-r9t1UhQP.js} +124 -36
  97. package/dist/task-r9t1UhQP.js.map +1 -0
  98. package/dist/{task-stream-C9BLiAhz.js → task-stream-CMUilu54.js} +45 -15
  99. package/dist/task-stream-CMUilu54.js.map +1 -0
  100. package/dist/{tasks-BEEVIBcT.js → tasks-Bbv_lOBG.js} +17 -13
  101. package/dist/tasks-Bbv_lOBG.js.map +1 -0
  102. package/dist/{telemetry-PD7bhcda.js → telemetry-D6ruCtnv.js} +5 -5
  103. package/dist/telemetry-D6ruCtnv.js.map +1 -0
  104. package/dist/{terminal-NhNl-BIA.js → terminal-DrGyci_a.js} +63 -94
  105. package/dist/terminal-DrGyci_a.js.map +1 -0
  106. package/dist/{tools-BBdpgcIf.js → tools-Dyfh9aCD.js} +11 -11
  107. package/dist/tools-Dyfh9aCD.js.map +1 -0
  108. package/dist/ui-BBVuTM1v.js +15 -0
  109. package/dist/ui-BBVuTM1v.js.map +1 -0
  110. package/dist/version-aXxpgRKx.js +6 -0
  111. package/dist/version-aXxpgRKx.js.map +1 -0
  112. package/dist/warlock-smoke-test.ts +2 -2
  113. package/dist/{wizard-abort-hqHF-9xD.js → wizard-abort-BBkiUxfS.js} +23 -20
  114. package/dist/wizard-abort-BBkiUxfS.js.map +1 -0
  115. package/dist/wizard-abort-BU4aLyvh.js +3 -0
  116. package/dist/{wizard-session-FSJCkTcP.js → wizard-session-2w4Ru-Wz.js} +12 -16
  117. package/dist/wizard-session-2w4Ru-Wz.js.map +1 -0
  118. package/dist/wizard-session-DGaUHOF3.js +2 -0
  119. package/dist/wizard-ui-DoyOZxK8.js +16 -0
  120. package/dist/wizard-ui-DoyOZxK8.js.map +1 -0
  121. package/dist/{yara-hooks-BaPKsm-B.js → yara-hooks-DCeMDd1o.js} +19 -68
  122. package/dist/yara-hooks-DCeMDd1o.js.map +1 -0
  123. package/dist/yara-hooks-DSGuCU9A.js +2 -0
  124. package/package.json +8 -1
  125. package/dist/add-mcp-server-to-clients-4yHaRvOo.js.map +0 -1
  126. package/dist/agent-interface-DPaPdIjS.js.map +0 -1
  127. package/dist/agent-prompt-loader-BlhabNM2.js.map +0 -1
  128. package/dist/agent-runner-JFwQQj2k.js +0 -6100
  129. package/dist/agent-runner-JFwQQj2k.js.map +0 -1
  130. package/dist/analytics-CcHoyhE_.js +0 -2
  131. package/dist/analytics-DSVyjIVF.js.map +0 -1
  132. package/dist/api-Ci0dZWLR.js.map +0 -1
  133. package/dist/bounded-fs-FbZJ_vJ_.js.map +0 -1
  134. package/dist/ci-install-CEVCqahf.js.map +0 -1
  135. package/dist/debug-DWYDVp0B.js +0 -750
  136. package/dist/debug-DWYDVp0B.js.map +0 -1
  137. package/dist/defaults-DulzMJpN.js.map +0 -1
  138. package/dist/env-api-key-DwmkB3fm.js.map +0 -1
  139. package/dist/environment-1wA7uwAS.js.map +0 -1
  140. package/dist/errors--OqLxmWR.js.map +0 -1
  141. package/dist/gateway-session-OqzCMpZ9.js.map +0 -1
  142. package/dist/gateway-session-s1xr8b48.js +0 -2
  143. package/dist/headless-ui-DRGWDg9Z.js.map +0 -1
  144. package/dist/local-dev-DPZiIPCK.js.map +0 -1
  145. package/dist/mcp-BprhJJ2c.js +0 -64
  146. package/dist/mcp-BprhJJ2c.js.map +0 -1
  147. package/dist/mcp-prompt-streaming-E1d8DJcX.js.map +0 -1
  148. package/dist/mint-failure-C82j0RMC.js.map +0 -1
  149. package/dist/non-interactive-DGT2H_n4.js.map +0 -1
  150. package/dist/orchestrator-tools-BBBNV1z5.js.map +0 -1
  151. package/dist/package-json-xt3eeyBI.js.map +0 -1
  152. package/dist/package-manager-DU3aVif4.js +0 -290
  153. package/dist/package-manager-DU3aVif4.js.map +0 -1
  154. package/dist/pi-fG5fT50Y.js.map +0 -1
  155. package/dist/playground-UFSHP-Yn.js.map +0 -1
  156. package/dist/posthog-O9kKcnda.js.map +0 -1
  157. package/dist/provisioning-B-tzjG4r.js.map +0 -1
  158. package/dist/queue-tools-7Oso-fpt.js.map +0 -1
  159. package/dist/registry-D1L5e-WQ.js.map +0 -1
  160. package/dist/security-n3-xdINN.js.map +0 -1
  161. package/dist/setup-utils-Bj0gejEf.js.map +0 -1
  162. package/dist/start-tui-BowrTPXm.js.map +0 -1
  163. package/dist/store-CVkJKlny.js.map +0 -1
  164. package/dist/subagent-SxmvfDfp.js.map +0 -1
  165. package/dist/task-nF7Ry8ff.js.map +0 -1
  166. package/dist/task-stream-C9BLiAhz.js.map +0 -1
  167. package/dist/tasks-BEEVIBcT.js.map +0 -1
  168. package/dist/telemetry-PD7bhcda.js.map +0 -1
  169. package/dist/terminal-NhNl-BIA.js.map +0 -1
  170. package/dist/tools-BBdpgcIf.js.map +0 -1
  171. package/dist/wizard-abort-D3YA1hXX.js +0 -2
  172. package/dist/wizard-abort-hqHF-9xD.js.map +0 -1
  173. package/dist/wizard-session-CYvyYnti.js +0 -2
  174. package/dist/wizard-session-FSJCkTcP.js.map +0 -1
  175. package/dist/yara-hooks-BaPKsm-B.js.map +0 -1
  176. package/dist/yara-hooks-CwfQuEl3.js +0 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging-ui-_TwoMNbG.js","names":[],"sources":["../src/shared/health-checks/readiness.ts","../src/ui/logging-ui.ts"],"sourcesContent":["import {\n ServiceHealthStatus,\n type AllServicesHealth,\n type BaseHealthResult,\n type HealthCheckKey,\n} from './types';\nimport { checkSkillsOriginHealth } from './endpoints';\nimport { logToFile } from '@utils/debug';\n\n// ---------------------------------------------------------------------------\n// Service labels (used in human-readable reason strings)\n// ---------------------------------------------------------------------------\n\nexport const SERVICE_LABELS: Record<HealthCheckKey, string> = {\n skillsOrigin: 'Skills download',\n};\n\n// ---------------------------------------------------------------------------\n// Readiness config\n// ---------------------------------------------------------------------------\n\nexport interface WizardReadinessConfig {\n /** Services where status=Down blocks the run (readiness=No). */\n downBlocksRun: HealthCheckKey[];\n /** Services where status=Degraded (or worse) blocks the run (readiness=No). */\n degradedBlocksRun?: HealthCheckKey[];\n}\n\n// Skills gate startup; gateway readiness is checked against the minted URL.\nexport const DEFAULT_WIZARD_READINESS_CONFIG: WizardReadinessConfig = {\n downBlocksRun: ['skillsOrigin'],\n};\n\nexport const SIGNUP_WIZARD_READINESS_CONFIG = DEFAULT_WIZARD_READINESS_CONFIG;\n\n// ---------------------------------------------------------------------------\n// Aggregate check\n// ---------------------------------------------------------------------------\n\nexport async function checkAllExternalServices(): Promise<AllServicesHealth> {\n return { skillsOrigin: await checkSkillsOriginHealth() };\n}\n\n// ---------------------------------------------------------------------------\n// Wizard readiness evaluation\n// ---------------------------------------------------------------------------\n\nexport enum WizardReadiness {\n Yes = 'yes',\n No = 'no',\n YesWithWarnings = 'yes_with_warnings',\n}\n\nexport interface WizardReadinessResult {\n decision: WizardReadiness;\n health: AllServicesHealth;\n reasons: string[];\n}\n\nfunction describeResult(label: string, h: BaseHealthResult): string {\n const parts = [`${label}: ${h.status}`];\n if (h.rawIndicator) parts.push(`indicator=${h.rawIndicator}`);\n if (h.error) parts.push(h.error);\n return parts.join(' — ');\n}\n\n// Each probe can take up to one base timeout + two retries with the\n// 500ms / 2000ms backoffs in endpoints.ts (worst case ~17.5s for a\n// network failure that exhausts retries). Probes run in parallel so\n// the aggregate ceiling is one probe, not the sum.\nconst READINESS_TIMEOUT_MS = 20_000;\n\nexport async function evaluateWizardReadiness(\n config: WizardReadinessConfig = DEFAULT_WIZARD_READINESS_CONFIG,\n): Promise<WizardReadinessResult> {\n try {\n const health = await Promise.race([\n checkAllExternalServices(),\n new Promise<AllServicesHealth>((resolve) =>\n setTimeout(\n () => resolve(allUnknown('Health check timed out')),\n READINESS_TIMEOUT_MS,\n ),\n ),\n ]);\n\n const blockingKeys = getBlockingServiceKeys(health, config);\n const reasons = blockingKeys.map((key) =>\n describeResult(SERVICE_LABELS[key], health[key]),\n );\n if (blockingKeys.length > 0) {\n const blockingDetails = blockingKeys.map((key) => {\n const h = health[key];\n return `${key} (${h.status}${h.error ? ` — ${h.error}` : ''})`;\n });\n logToFile(`[health-checks] blocked by: ${blockingDetails.join(', ')}`);\n return { decision: WizardReadiness.No, health, reasons };\n }\n\n return { decision: WizardReadiness.Yes, health, reasons };\n } catch (err) {\n logToFile(\n `[health-checks] error: ${err instanceof Error ? err.message : err}`,\n );\n // Health checks must never block the wizard run\n return {\n decision: WizardReadiness.Yes,\n health: allUnknown('Unexpected error'),\n reasons: [],\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Blocking service detection\n// ---------------------------------------------------------------------------\n\n// Report only dependencies that prevent this run from starting.\nexport function getBlockingServiceKeys(\n health: AllServicesHealth,\n config: WizardReadinessConfig = DEFAULT_WIZARD_READINESS_CONFIG,\n): HealthCheckKey[] {\n return (Object.keys(health) as HealthCheckKey[]).filter((key) => {\n const result = health[key];\n if (\n config.downBlocksRun.includes(key) &&\n (result.status === ServiceHealthStatus.Down ||\n result.status === ServiceHealthStatus.NoConnection)\n ) {\n return true;\n }\n if (\n (config.degradedBlocksRun ?? []).includes(key) &&\n result.status !== ServiceHealthStatus.Healthy\n ) {\n return true;\n }\n return false;\n });\n}\n\n/** Build an AllServicesHealth where every service is Degraded with the given error. */\nfunction allUnknown(error: string): AllServicesHealth {\n const base: BaseHealthResult = {\n status: ServiceHealthStatus.Degraded,\n error,\n };\n return { skillsOrigin: base };\n}\n","/* eslint-disable no-console */\n/**\n * LoggingUI — Logging-only implementation for CI mode.\n * No prompts, no TUI, no interactivity. Just console output.\n */\n\nimport {\n TaskStatus,\n type WizardUI,\n type SpinnerHandle,\n type AuthErrorDetail,\n type TokenUsageDelta,\n} from './wizard-ui';\nimport type { SettingsConflict } from '@shared/claude-settings';\nimport type { ApiUser } from '@shared/api';\nimport { OAUTH_TIMEOUT_MS } from '@shared/constants';\nimport {\n type WizardReadinessResult,\n getBlockingServiceKeys,\n SERVICE_LABELS,\n} from '@shared/health-checks/readiness';\nimport type {\n AskAnswers,\n Credentials,\n OutroData,\n PendingQuestion,\n TaskNotice,\n} from '@lib/wizard-session';\n\nexport class LoggingUI implements WizardUI {\n intro(message: string): void {\n console.log(`┌ ${message}`);\n }\n\n outro(message: string): void {\n console.log(`└ ${message}`);\n }\n\n outroError(data: OutroData): void {\n console.log(`✖ ${data.message ?? 'Wizard aborted'}`);\n if (data.body) console.log(`│ ${data.body}`);\n if (data.docsUrl) console.log(`│ Docs: ${data.docsUrl}`);\n }\n\n waitForOutroDismissed(): Promise<void> {\n return Promise.resolve();\n }\n\n waitForAiOptIn(): Promise<void> {\n // Non-TUI runs are CI runs, which auto-consent to AI usage.\n return Promise.resolve();\n }\n\n cancel(message: string): void {\n console.log(`■ ${message}`);\n }\n\n log = {\n info(message: string): void {\n console.log(`│ ${message}`);\n },\n warn(message: string): void {\n console.log(`▲ ${message}`);\n },\n error(message: string): void {\n console.log(`✖ ${message}`);\n },\n success(message: string): void {\n console.log(`✔ ${message}`);\n },\n step(message: string): void {\n console.log(`◇ ${message}`);\n },\n };\n\n note(message: string): void {\n console.log(`│ ${message}`);\n }\n\n spinner(): SpinnerHandle {\n return {\n start(message?: string) {\n if (message) console.log(`◌ ${message}`);\n },\n stop(message?: string) {\n if (message) console.log(`● ${message}`);\n },\n message(msg?: string) {\n if (msg) console.log(`◌ ${msg}`);\n },\n };\n }\n\n pushStatus(message: string): void {\n console.log(`◇ ${message}`);\n }\n\n setDetectedFramework(label: string): void {\n console.log(`✔ Framework: ${label}`);\n }\n\n onEnterScreen(_screen: string, _fn: () => void): void {\n // No screen transitions in CI\n }\n\n setLoginUrl(url: string | null): void {\n if (url) {\n console.log(\n `│ If the browser didn't open automatically, use this link:`,\n );\n console.log(`│ ${url}`);\n }\n }\n\n setAuthorizeUrl(_url: string | null): void {\n // Manual-paste modal is TUI-only; CI/non-interactive runs don't use it.\n }\n\n showBlockingOutage(result: WizardReadinessResult): Promise<void> {\n console.log(`▲ Service health issues detected.`);\n const blockingKeys = getBlockingServiceKeys(result.health);\n if (blockingKeys.length > 0) {\n console.log(`│`);\n console.log(`│ Blocking services:`);\n for (const key of blockingKeys) {\n const status = result.health[key].status;\n const error = result.health[key].error;\n const label = SERVICE_LABELS[key];\n const detail = error ? ` — ${error}` : '';\n console.log(`│ ✖ ${label}: ${status}${detail}`);\n }\n console.log(`│`);\n }\n for (const reason of result.reasons) {\n console.log(`│ ${reason}`);\n }\n console.log(\n `│ Continuing anyway — health checks are advisory in non-interactive runs.`,\n );\n return Promise.resolve();\n }\n\n setReadinessWarnings(result: WizardReadinessResult): void {\n console.log(`▲ Service health warnings detected.`);\n for (const reason of result.reasons) {\n console.log(`│ ${reason}`);\n }\n }\n\n showPortConflict(_processInfo: {\n command: string;\n pid: string;\n port: number;\n user: string;\n }): Promise<void> {\n return Promise.resolve();\n }\n\n waitForManualAuthCode(): Promise<string> {\n // No interactive prompt in CI/logging mode — never resolves. CI bypasses\n // OAuth entirely, so this is only here to satisfy the interface.\n return new Promise<string>(() => {\n /* intentionally never resolves */\n });\n }\n\n showTaskNotice(_notice: TaskNotice): Promise<boolean> {\n return Promise.resolve(false);\n }\n\n cancelTaskNotice(): void {\n // Nothing to dismiss — showTaskNotice never opened anything.\n }\n\n showSettingsOverride(\n _conflicts: SettingsConflict[],\n _backupAndFix: () => boolean,\n ): Promise<void> {\n return Promise.resolve();\n }\n\n requestQuestion(_question: PendingQuestion): Promise<AskAnswers> {\n return Promise.reject(\n new Error(\n 'wizard_ask is not available in CI / non-interactive mode. ' +\n 'Re-run the wizard without --ci to answer interactively.',\n ),\n );\n }\n\n cancelPendingQuestion(): void {\n // Nothing to dismiss — requestQuestion never opens an overlay here.\n }\n\n showAuthError(detail?: AuthErrorDetail): void {\n console.log(`✖ Authentication failed (401)`);\n if (detail?.hasSettingsConflict) {\n console.log(\n `│ Claude Code auth is conflicting with the wizard. Please try again after logging out:`,\n );\n console.log(`│ claude auth logout`);\n } else {\n console.log(\n `│ The PostHog LLM Gateway rejected the API key. Common causes:`,\n );\n console.log(\n `│ - Wrong key type: pass a personal API key (phx_xxx). pha_ is an OAuth access token, phc_ is a project key.`,\n );\n console.log(\n `│ - Missing scope: the personal API key needs the \"llm_gateway:read\" scope.`,\n );\n console.log(`│ - Expired or revoked key.`);\n console.log(\n `│ - Region mismatch: --region must match the region the key was issued in (us vs eu).`,\n );\n }\n if (detail?.logFilePath) {\n console.log(`│ Verbose log: ${detail.logFilePath}`);\n }\n }\n\n showSessionTimeout(): void {\n const minutes = Math.round(OAUTH_TIMEOUT_MS / 60_000);\n console.log(\n `✖ Login timed out. The OAuth link timed out after ${minutes} minutes.`,\n );\n console.log(`│ Re-run the wizard to get a fresh link and try again.`);\n }\n\n startRun(): void {\n // No-op in CI mode\n }\n\n setCredentials(_credentials: Credentials): void {\n // No-op in CI mode — credentials are handled directly\n }\n\n setAccessToken(_credentials: Credentials): void {\n // No-op in CI mode — CI runs on a non-expiring key and never refreshes\n }\n\n setRoleAtOrganization(_role: string | null): void {\n // No-op in CI mode — there's no TUI to render role-tailored prompts\n }\n\n setApiUser(_user: ApiUser | null): void {\n // No-op in CI mode — there's no TUI to read account context from\n // the session.\n }\n\n private lastTodoLine = '';\n\n syncTodos(\n todos: Array<{\n id?: string;\n source?: string;\n content: string;\n status: string;\n activeForm?: string;\n }>,\n ): void {\n const completed = todos.filter(\n (t) => t.status === TaskStatus.Completed,\n ).length;\n const active = todos.filter((t) => t.status === TaskStatus.InProgress);\n if (active.length === 0) return;\n const labels = active.map((t) => t.activeForm || t.content).join(' · ');\n const line = `◌ [${completed}/${todos.length}] ${labels}`;\n // The queue re-renders on every transition; print only what changed.\n if (line === this.lastTodoLine) return;\n this.lastTodoLine = line;\n console.log(line);\n }\n\n setEventPlan(_events: Array<{ name: string; description: string }>): void {\n // No-op in CI mode\n }\n\n setDashboardUrl(_url: string): void {\n // No-op in CI mode\n }\n\n setStage(_stage: string): void {\n // No-op in CI mode\n }\n\n setNotebookUrl(_url: string): void {\n // No-op in CI mode\n }\n\n setHandoffText(_text: string): void {\n // No-op without a store — HeadlessUI overrides to feed the session sync\n }\n\n addTokenUsage(_delta: TokenUsageDelta): void {\n // No-op — the hidden Ctrl+T HUD is TUI-only\n }\n\n setFinalTokenCostUsd(_costUsd: number): void {\n // No-op — the hidden Ctrl+T HUD is TUI-only\n }\n\n setOutroData(_data: import('@lib/wizard-session').OutroData): void {\n // No-op in CI mode\n }\n\n setFrameworkContext(_key: string, _value: unknown): void {\n // No-op in CI mode\n }\n\n getFrameworkContext(_key: string): unknown {\n // No frameworkContext in CI mode\n return undefined;\n }\n\n waitForGate(_stepId: string): Promise<void> {\n // No interactive gates in CI mode\n return Promise.resolve();\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ import { s as logToFile } from "./debug-Ch4BDOtD.js";
2
+ import { t as VERSION } from "./version-aXxpgRKx.js";
3
+ import { o as onAccessTokenRotated } from "./oauth-session-DJ8h6GFa.js";
4
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
5
+ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
6
+ import { createJiti } from "jiti";
7
+ //#region src/agent/runner/harness/pi/mcp.ts
8
+ /**
9
+ * pi has no built-in MCP; `pi-mcp-adapter` — pi's own MCP extension, built here
10
+ * with its supported `createMcpAdapter` embedding API — bridges the same hosted
11
+ * MCP the anthropic path uses into the agent.
12
+ */
13
+ const MCP_TOKEN_ENV = "POSTHOG_MCP_TOKEN";
14
+ let mcpTokenOwners = 0;
15
+ let activeMcpToken;
16
+ let previousMcpToken;
17
+ let stopFollowingRotations;
18
+ function setMcpToken(token) {
19
+ activeMcpToken = token;
20
+ process.env[MCP_TOKEN_ENV] = token;
21
+ }
22
+ function acquireMcpToken(token) {
23
+ if (mcpTokenOwners === 0) {
24
+ previousMcpToken = process.env[MCP_TOKEN_ENV];
25
+ stopFollowingRotations = onAccessTokenRotated(setMcpToken);
26
+ }
27
+ if (activeMcpToken !== token) setMcpToken(token);
28
+ mcpTokenOwners += 1;
29
+ let released = false;
30
+ return () => {
31
+ if (released) return;
32
+ released = true;
33
+ mcpTokenOwners -= 1;
34
+ if (mcpTokenOwners > 0) return;
35
+ stopFollowingRotations?.();
36
+ stopFollowingRotations = void 0;
37
+ if (previousMcpToken === void 0) delete process.env[MCP_TOKEN_ENV];
38
+ else process.env[MCP_TOKEN_ENV] = previousMcpToken;
39
+ activeMcpToken = void 0;
40
+ previousMcpToken = void 0;
41
+ };
42
+ }
43
+ /** Server `instructions` for the system prompt — the adapter exposes no accessor, so one standard-SDK handshake; best-effort. */
44
+ async function fetchInstructions(mcpUrl, accessToken, userAgent) {
45
+ const client = new Client({
46
+ name: "posthog-wizard",
47
+ version: VERSION
48
+ });
49
+ try {
50
+ const transport = new StreamableHTTPClientTransport(new URL(mcpUrl), { requestInit: { headers: {
51
+ Authorization: `Bearer ${accessToken}`,
52
+ "User-Agent": userAgent
53
+ } } });
54
+ await client.connect(transport);
55
+ const instructions = client.getInstructions() || void 0;
56
+ logToFile(`[pi-mcp] instructions ${instructions?.length ?? 0} chars`);
57
+ return instructions;
58
+ } catch (err) {
59
+ logToFile(`[pi-mcp] instructions fetch skipped: ${String(err)}`);
60
+ return;
61
+ } finally {
62
+ await client.close().catch(() => void 0);
63
+ }
64
+ }
65
+ async function setupPostHogMcp(opts) {
66
+ const { mcpUrl, accessToken, userAgent } = opts;
67
+ const cleanup = acquireMcpToken(accessToken);
68
+ try {
69
+ const extensionFactory = (await createJiti(import.meta.url).import("pi-mcp-adapter")).createMcpAdapter({ config: {
70
+ mcpServers: { posthog: {
71
+ url: mcpUrl,
72
+ auth: "bearer",
73
+ bearerTokenEnv: MCP_TOKEN_ENV,
74
+ headers: { "User-Agent": userAgent },
75
+ lifecycle: "eager",
76
+ directTools: ["exec"],
77
+ exposeResources: false
78
+ } },
79
+ settings: {
80
+ disableProxyTool: true,
81
+ toolPrefix: "posthog"
82
+ }
83
+ } });
84
+ logToFile(`[pi-mcp] adapter loaded; posthog MCP at ${mcpUrl}`);
85
+ return {
86
+ extensionFactory,
87
+ cleanup
88
+ };
89
+ } catch (error) {
90
+ cleanup();
91
+ throw error;
92
+ }
93
+ }
94
+ //#endregion
95
+ export { fetchInstructions, setupPostHogMcp };
96
+
97
+ //# sourceMappingURL=mcp-DAgaoGk5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-DAgaoGk5.js","names":[],"sources":["../src/agent/runner/harness/pi/mcp.ts"],"sourcesContent":["/**\n * pi has no built-in MCP; `pi-mcp-adapter` — pi's own MCP extension, built here\n * with its supported `createMcpAdapter` embedding API — bridges the same hosted\n * MCP the anthropic path uses into the agent.\n */\n\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport { createJiti } from 'jiti';\nimport { VERSION } from '@shared/version';\nimport { logToFile } from '@utils/debug';\nimport { onAccessTokenRotated } from '@shared/oauth-session';\n\nconst MCP_TOKEN_ENV = 'POSTHOG_MCP_TOKEN';\nlet mcpTokenOwners = 0;\nlet activeMcpToken: string | undefined;\nlet previousMcpToken: string | undefined;\n\nlet stopFollowingRotations: (() => void) | undefined;\n\nfunction setMcpToken(token: string): void {\n activeMcpToken = token;\n process.env[MCP_TOKEN_ENV] = token;\n}\n\nfunction acquireMcpToken(token: string): () => void {\n if (mcpTokenOwners === 0) {\n previousMcpToken = process.env[MCP_TOKEN_ENV];\n // The adapter reads the env on each connect, so reconnects take the rotated token.\n stopFollowingRotations = onAccessTokenRotated(setMcpToken);\n }\n // A later session after a rotation carries the newer token of the same login.\n if (activeMcpToken !== token) setMcpToken(token);\n mcpTokenOwners += 1;\n let released = false;\n return () => {\n if (released) return;\n released = true;\n mcpTokenOwners -= 1;\n if (mcpTokenOwners > 0) return;\n stopFollowingRotations?.();\n stopFollowingRotations = undefined;\n if (previousMcpToken === undefined) delete process.env[MCP_TOKEN_ENV];\n else process.env[MCP_TOKEN_ENV] = previousMcpToken;\n activeMcpToken = undefined;\n previousMcpToken = undefined;\n };\n}\n\nexport interface PostHogMcpSetup {\n /** pi ExtensionFactory to add to the resource loader's `extensionFactories`. */\n extensionFactory: (pi: unknown) => void;\n /** Release this setup's token ownership. Call after the run. */\n cleanup: () => void;\n}\n\n/** Server `instructions` for the system prompt — the adapter exposes no accessor, so one standard-SDK handshake; best-effort. */\nexport async function fetchInstructions(\n mcpUrl: string,\n accessToken: string,\n userAgent: string,\n): Promise<string | undefined> {\n const client = new Client({ name: 'posthog-wizard', version: VERSION });\n try {\n const transport = new StreamableHTTPClientTransport(new URL(mcpUrl), {\n requestInit: {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'User-Agent': userAgent,\n },\n },\n });\n await client.connect(transport);\n const instructions = client.getInstructions() || undefined;\n logToFile(`[pi-mcp] instructions ${instructions?.length ?? 0} chars`);\n return instructions;\n } catch (err) {\n logToFile(`[pi-mcp] instructions fetch skipped: ${String(err)}`);\n return undefined;\n } finally {\n await client.close().catch(() => undefined);\n }\n}\n\nexport async function setupPostHogMcp(opts: {\n mcpUrl: string;\n accessToken: string;\n userAgent: string;\n}): Promise<PostHogMcpSetup> {\n const { mcpUrl, accessToken, userAgent } = opts;\n\n // By env NAME: the token stays in this process, off disk, and never reaches pi's env-scrubbed tool subprocesses.\n const cleanup = acquireMcpToken(accessToken);\n\n try {\n // The adapter ships raw TypeScript; loading through jiti is its documented requirement.\n const jiti = createJiti(import.meta.url);\n const mod = await jiti.import<{\n createMcpAdapter: (\n options: unknown,\n ) => PostHogMcpSetup['extensionFactory'];\n }>('pi-mcp-adapter');\n const extensionFactory = mod.createMcpAdapter({\n config: {\n mcpServers: {\n posthog: {\n url: mcpUrl,\n auth: 'bearer',\n bearerTokenEnv: MCP_TOKEN_ENV,\n headers: { 'User-Agent': userAgent },\n // Connect at extension load — direct tools register without a session_start.\n lifecycle: 'eager',\n // Register only `exec`: `directTools: true` also mints a `posthog_get_<name>` tool per MCP resource, whose sentence-length names overflow Anthropic's 128-char tool-name limit and 400 the whole request.\n directTools: ['exec'],\n exposeResources: false,\n },\n },\n // Disable the proxy `mcp` tool (its search indirection pollutes context); the adapter re-enables it only if no direct tools resolve.\n settings: { disableProxyTool: true, toolPrefix: 'posthog' },\n },\n });\n logToFile(`[pi-mcp] adapter loaded; posthog MCP at ${mcpUrl}`);\n return { extensionFactory, cleanup };\n } catch (error) {\n cleanup();\n throw error;\n }\n}\n"],"mappings":";;;;;;;;;;;;AAaA,MAAM,gBAAgB;AACtB,IAAI,iBAAiB;AACrB,IAAI;AACJ,IAAI;AAEJ,IAAI;AAEJ,SAAS,YAAY,OAAqB;AACxC,kBAAiB;AACjB,SAAQ,IAAI,iBAAiB;;AAG/B,SAAS,gBAAgB,OAA2B;AAClD,KAAI,mBAAmB,GAAG;AACxB,qBAAmB,QAAQ,IAAI;AAE/B,2BAAyB,qBAAqB,YAAY;;AAG5D,KAAI,mBAAmB,MAAO,aAAY,MAAM;AAChD,mBAAkB;CAClB,IAAI,WAAW;AACf,cAAa;AACX,MAAI,SAAU;AACd,aAAW;AACX,oBAAkB;AAClB,MAAI,iBAAiB,EAAG;AACxB,4BAA0B;AAC1B,2BAAyB,KAAA;AACzB,MAAI,qBAAqB,KAAA,EAAW,QAAO,QAAQ,IAAI;MAClD,SAAQ,IAAI,iBAAiB;AAClC,mBAAiB,KAAA;AACjB,qBAAmB,KAAA;;;;AAYvB,eAAsB,kBACpB,QACA,aACA,WAC6B;CAC7B,MAAM,SAAS,IAAI,OAAO;EAAE,MAAM;EAAkB,SAAS;EAAS,CAAC;AACvE,KAAI;EACF,MAAM,YAAY,IAAI,8BAA8B,IAAI,IAAI,OAAO,EAAE,EACnE,aAAa,EACX,SAAS;GACP,eAAe,UAAU;GACzB,cAAc;GACf,EACF,EACF,CAAC;AACF,QAAM,OAAO,QAAQ,UAAU;EAC/B,MAAM,eAAe,OAAO,iBAAiB,IAAI,KAAA;AACjD,YAAU,yBAAyB,cAAc,UAAU,EAAE,QAAQ;AACrE,SAAO;UACA,KAAK;AACZ,YAAU,wCAAwC,OAAO,IAAI,GAAG;AAChE;WACQ;AACR,QAAM,OAAO,OAAO,CAAC,YAAY,KAAA,EAAU;;;AAI/C,eAAsB,gBAAgB,MAIT;CAC3B,MAAM,EAAE,QAAQ,aAAa,cAAc;CAG3C,MAAM,UAAU,gBAAgB,YAAY;AAE5C,KAAI;EAQF,MAAM,oBALM,MADC,WAAW,OAAO,KAAK,IAAI,CACjB,OAIpB,iBAAiB,EACS,iBAAiB,EAC5C,QAAQ;GACN,YAAY,EACV,SAAS;IACP,KAAK;IACL,MAAM;IACN,gBAAgB;IAChB,SAAS,EAAE,cAAc,WAAW;IAEpC,WAAW;IAEX,aAAa,CAAC,OAAO;IACrB,iBAAiB;IAClB,EACF;GAED,UAAU;IAAE,kBAAkB;IAAM,YAAY;IAAW;GAC5D,EACF,CAAC;AACF,YAAU,2CAA2C,SAAS;AAC9D,SAAO;GAAE;GAAkB;GAAS;UAC7B,OAAO;AACd,WAAS;AACT,QAAM"}
@@ -1,8 +1,9 @@
1
- import { A as DEFAULT_AGENT_MODEL, pt as WIZARD_USER_AGENT, s as logToFile } from "./debug-DWYDVp0B.js";
2
- import { n as analytics } from "./analytics-DSVyjIVF.js";
3
- import { f as sanitizeAgentSubprocessEnv, n as buildRunTags, o as createIsolatedAgentConfigDir, t as buildAgentEnv } from "./agent-interface-DPaPdIjS.js";
4
- import { o as gatewayAuth } from "./gateway-session-OqzCMpZ9.js";
5
- //#region src/lib/agent/mcp-prompt-streaming.ts
1
+ import { s as logToFile } from "./debug-Ch4BDOtD.js";
2
+ import { Q as WIZARD_USER_AGENT, l as DEFAULT_AGENT_MODEL } from "./constants-jFI2SaE1.js";
3
+ import { n as analytics } from "./analytics-CHCZ_qUR.js";
4
+ import { l as gatewayAuth } from "./gateway-CjoShdLa.js";
5
+ import { f as sanitizeAgentSubprocessEnv, n as buildRunTags, o as createIsolatedAgentConfigDir, t as buildAgentEnv } from "./agent-interface-BAOIHuXS.js";
6
+ //#region src/agent/mcp-prompt-streaming.ts
6
7
  let _sdkModule = null;
7
8
  async function loadSdk() {
8
9
  if (!_sdkModule) _sdkModule = await import("@anthropic-ai/claude-agent-sdk");
@@ -249,4 +250,4 @@ async function* runMcpPromptViaSdk(args) {
249
250
  //#endregion
250
251
  export { runMcpPromptViaSdk };
251
252
 
252
- //# sourceMappingURL=mcp-prompt-streaming-E1d8DJcX.js.map
253
+ //# sourceMappingURL=mcp-prompt-streaming-I2U_X7BC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-prompt-streaming-I2U_X7BC.js","names":[],"sources":["../src/agent/mcp-prompt-streaming.ts"],"sourcesContent":["/**\n * Streaming prompt runner for the McpSuggestedPromptsScreen.\n *\n * Calls the Claude Agent SDK's `query()` directly with just the PostHog\n * MCP server configured — no skills, no sandbox, no settings sources,\n * no wizard-tools. This is the lightweight cousin of `runAgent` in\n * `agent-interface.ts`: same SDK, much narrower surface, suitable for\n * \"user asked a question, show the answer\" interactions.\n *\n * The function is an async generator that yields `AgentChunk`s extracted\n * from the SDK's message stream. Callers (the screen) consume them via\n * `for await (...)` and render as they arrive.\n */\n\nimport type { Credentials } from '@shared/api';\nimport { DEFAULT_AGENT_MODEL, WIZARD_USER_AGENT } from '@shared/constants';\nimport { logToFile } from '@utils/debug';\nimport { gatewayAuth } from '@agent/gateway-session';\nimport { buildAgentEnv, buildRunTags } from '@agent/agent-interface';\nimport { sanitizeAgentSubprocessEnv } from '@agent/agent-env-isolation';\nimport { createIsolatedAgentConfigDir } from '@agent/stored-login';\nimport { analytics } from '@utils/analytics';\n\n/**\n * Discriminated union covering every kind of streamed event the screen\n * needs to render. Production yields these from Claude SDK messages;\n * the playground yields them from canned scripts.\n */\nexport type AgentChunk =\n | { kind: 'text'; text: string }\n /** `command` carries CLI mode's exec command string (`call <tool> …`) so the\n * screen can recover the inner tool for context-aware follow-ups. */\n | { kind: 'tool-call'; toolName: string; detail: string; command?: string }\n | { kind: 'tool-result'; toolName: string; detail: string }\n | { kind: 'error'; text: string }\n /** Stream completed. `sessionId` is the SDK session ID of the just-\n * completed turn; pass it back as `resumeSessionId` on a follow-up\n * call to continue the conversation with full history. */\n | { kind: 'done'; sessionId?: string };\n\n// Cached SDK module — first call pays the dynamic-import cost; later\n// calls reuse the same module.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nlet _sdkModule: any | null = null;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nasync function loadSdk(): Promise<any> {\n if (!_sdkModule) {\n _sdkModule = await import('@anthropic-ai/claude-agent-sdk');\n }\n return _sdkModule;\n}\n\nconst MODEL = DEFAULT_AGENT_MODEL;\n\n// Bounded turn count so a single prompt can't loop forever on the\n// user's nickel. 20 gives the agent room for non-trivial multi-step\n// chains (multi-tool reads → reason → write → verify → summarize) while\n// still capping runaway loops. Worth tuning down once we see real\n// telemetry on average turn counts per prompt.\nconst MAX_TURNS = 30;\n\n/**\n * Extract a short, single-line summary from an arbitrary value. Used\n * for tool-call args and tool-result bodies so the screen has something\n * compact to render.\n */\nfunction summarize(value: unknown, maxLen = 120): string {\n if (value == null) return '';\n let text: string;\n if (typeof value === 'string') text = value;\n else {\n try {\n text = JSON.stringify(value);\n } catch {\n text = String(value);\n }\n }\n text = text.replace(/\\s+/g, ' ').trim();\n if (text.length > maxLen) text = text.slice(0, maxLen - 1) + '…';\n return text;\n}\n\n/**\n * Convert one SDK message into zero or more AgentChunks. Mirrors the\n * subset of message shapes the wizard's main runAgent middleware\n * handles, but narrowed to just the kinds the screen needs to render.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction messageToChunks(message: any): AgentChunk[] {\n const chunks: AgentChunk[] = [];\n\n if (message?.type === 'assistant') {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const content = message.message?.content;\n if (Array.isArray(content)) {\n for (const block of content) {\n if (!block || typeof block !== 'object') continue;\n const type = (block as { type?: string }).type;\n if (type === 'text') {\n const text = (block as { text?: string }).text ?? '';\n if (text) chunks.push({ kind: 'text', text });\n } else if (type === 'tool_use') {\n const name = (block as { name?: string }).name ?? 'tool';\n const input = (block as { input?: unknown }).input;\n // CLI mode's exec tool takes a `command` string; keep it verbatim so\n // the screen can recover the inner tool name for follow-ups.\n const command = (input as { command?: unknown })?.command;\n chunks.push({\n kind: 'tool-call',\n toolName: name,\n detail: summarize(input),\n command: typeof command === 'string' ? command : undefined,\n });\n }\n }\n }\n }\n\n if (message?.type === 'user') {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const content = message.message?.content;\n if (Array.isArray(content)) {\n for (const block of content) {\n if (!block || typeof block !== 'object') continue;\n const type = (block as { type?: string }).type;\n if (type === 'tool_result') {\n const detail = summarize((block as { content?: unknown }).content);\n chunks.push({ kind: 'tool-result', toolName: 'tool', detail });\n }\n }\n }\n }\n\n if (message?.type === 'result') {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const sessionId = (message as { session_id?: string }).session_id;\n chunks.push({ kind: 'done', sessionId });\n }\n\n return chunks;\n}\n\n/**\n * Build a system-prompt append that nudges the agent to fit its response\n * inside the current terminal window. We can't actually constrain Claude\n * — this is a soft cap that the model usually honors. The screen also\n * applies a hard truncation cap as a fallback for non-compliant runs.\n *\n * Core principle nudged at the model: TALL CONTENT IS BAD, WIDE CONTENT\n * IS GOOD. Default terminal is 120 columns × 24 rows — that's a lot of\n * horizontal space, not much vertical. Spread data across columns, never\n * stack it down rows when a horizontal layout would work.\n */\nfunction buildTerminalFitPrompt(): string {\n const cols = process.stdout.columns ?? 120;\n const rows = process.stdout.rows ?? 24;\n // Reserve rows for wizard chrome (title, status, hint, margins).\n const messageBudget = Math.max(8, rows - 10);\n\n return [\n `You are responding inside a CLI window that is exactly ${cols} columns wide and ${rows} rows tall. The user CAN'T SCROLL — your entire reply must fit on screen.`,\n ``,\n `LAYOUT PRINCIPLE: tall content is the enemy, wide content is your friend. You have ${cols} columns of horizontal space; use them. Spread data across columns instead of stacking it down rows.`,\n ``,\n `Tables:`,\n `- Max 5 body rows. The prompts the user picks already constrain results to 5 or fewer — honor that and do not pad with extra rows.`,\n `- If a tool result returns more than 5 items, show the top 5 and mention the rest count inline (e.g. \"...and 12 more\").`,\n `- Prefer transposing wide-but-short data (items across columns, metrics down rows) when labels are short.`,\n `- A two-column table with many rows is the tall layout to AVOID.`,\n ``,\n `Other limits:`,\n `- Aim for 3-5 lines of prose. Maximum ${messageBudget} lines total.`,\n `- DO NOT announce what you are about to do. Skip preamble like \"I'll query…\", \"Let me check…\", \"Now I'll…\", \"I'm going to…\". Go straight to running tools and then the answer.`,\n `- Lists: if there are 6+ short items, format them inline (comma-separated), not as a vertical bullet list.`,\n `- For tool results, summarize the 1-3 numbers that matter. Do NOT echo raw JSON or the full payload.`,\n `- Code blocks: no language tag, no leading blank lines.`,\n `- No closing pleasantries (\"let me know if…\", \"feel free to…\"). Stop when the answer is delivered.`,\n `- No section headers unless the response actually has multiple sections.`,\n ``,\n `Naming saved artifacts:`,\n `- Every dashboard, insight, notebook, or annotation you create MUST include \"(wizard MCP tutorial)\" at the end of its title or name field. Examples: \"Weekly signups (wizard MCP tutorial)\", \"Top errors this week (wizard MCP tutorial)\", \"Onboarding analysis (wizard MCP tutorial)\".`,\n `- This applies on both create AND rename calls. If the user asks you to rename a saved artifact, preserve the \"(wizard MCP tutorial)\" suffix unless they explicitly ask you to drop it.`,\n `- Reason: lets the user find / clean up everything this tutorial created from one search in PostHog. Don't skip it — it's the only signal they'll have that an artifact came from the wizard.`,\n ``,\n `Tone & framing:`,\n `- This is a tutorial demoing PostHog (the product the user just installed). You are showing it off, not auditing it. Stay constructive and neutral about PostHog throughout.`,\n `- Don't editorialize about PostHog's reliability, performance, or cost. Describe what the data shows; treat anomalies as the user's data, not a platform issue.`,\n `- If a tool call fails or returns nothing, say \"the query didn't return data — try a different angle\" or similar. Do NOT speculate about outages, gateway issues, MCP problems, or service health.`,\n `- Avoid value-laden phrases like \"worth investigating\", \"concerning\", \"red flag\", \"problematic\", \"suspicious\", \"alarming\" when describing the user's metrics. Stick to what the numbers show; the user draws conclusions.`,\n ].join('\\n');\n}\n\n/**\n * Gateway trace tags for a tutorial prompt run — without them the gateway has\n * nothing to attribute its `$ai_generation` events to. Returns `{}` when no\n * program is supplied. Exported so the contract is testable without the SDK.\n */\nexport function buildTutorialRunTags(args: {\n programId?: string;\n integration?: string;\n}): Record<string, string> {\n if (!args.programId) return {};\n return buildRunTags({\n programId: args.programId,\n // The tutorial usually has no detected framework; fall back to the\n // program so the axis is never an empty string.\n integration: args.integration ?? args.programId,\n runId: analytics.runId,\n build: analytics.build,\n });\n}\n\nexport async function* runMcpPromptViaSdk(args: {\n prompt: string;\n credentials: Credentials;\n signal: AbortSignal;\n /** When set, the SDK loads the named session's prior turns as\n * context so the follow-up prompt can reference what the agent\n * already showed. */\n resumeSessionId?: string;\n /** Program this run's gateway spend attributes to. Omitting it fails the run\n * rather than going unattributed, so every caller must supply one. */\n programId?: string;\n /** Integration label for the trace tags; the tutorial usually has none. */\n integration?: string;\n}): AsyncIterable<AgentChunk> {\n const { prompt, credentials, signal, resumeSessionId } = args;\n\n // Assembled here rather than passed in so the TUI service layer doesn't\n // have to import this module's dependencies.\n const wizardMetadata = buildTutorialRunTags(args);\n\n // Route the SDK's LLM calls through the PostHog AI gateway, authed\n // with the run's minted token. Set BEFORE loading the SDK in\n // case any in-process code reads env at module init (cached base\n // URLs, OAuth setup, etc.) — same reason `initializeAgent` does this\n // before its query() call. Without these the SDK tries to\n // authenticate directly against Anthropic and 401s with \"Invalid\n // authentication credentials\".\n process.env.CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS = 'true';\n\n // The url and the bearer are one unit: a run must take both from the same\n // mint.\n const auth = await gatewayAuth(\n credentials.host,\n credentials.accessToken,\n args.programId,\n );\n const gatewayUrl = auth.gatewayUrl;\n process.env.ANTHROPIC_BASE_URL = gatewayUrl;\n process.env.ANTHROPIC_AUTH_TOKEN = auth.token;\n process.env.CLAUDE_CODE_OAUTH_TOKEN = auth.token;\n\n logToFile(\n `[runMcpPromptViaSdk] gatewayUrl=${gatewayUrl} tokenPrefix=${\n auth.token ? auth.token.slice(0, 4) + '***' : '(missing)'\n }`,\n );\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const { query } = await loadSdk();\n\n // Bridge external AbortSignal → SDK AbortController.\n const abortController = new AbortController();\n if (signal.aborted) abortController.abort();\n else\n signal.addEventListener('abort', () => abortController.abort(), {\n once: true,\n });\n\n const mcpUrl = credentials.host.mcpUrl;\n logToFile(\n `[runMcpPromptViaSdk] mcpUrl=${mcpUrl} model=${MODEL} resume=${\n resumeSessionId ?? '(none)'\n }`,\n );\n\n // The SDK expects an async generator for the prompt that stays open\n // until the result is received. For a single-turn prompt we yield one\n // user message and then await an abort (which fires when streaming\n // completes or the caller cancels).\n const createPromptStream = async function* () {\n yield {\n type: 'user' as const,\n session_id: '',\n message: { role: 'user' as const, content: prompt },\n parent_tool_use_id: null,\n };\n // Hold the stream open until abort. The SDK closes its end when it\n // sees a `result` message; we close ours via the abortController in\n // the finally block below.\n await new Promise<void>((resolve) => {\n if (abortController.signal.aborted) {\n resolve();\n return;\n }\n abortController.signal.addEventListener('abort', () => resolve(), {\n once: true,\n });\n });\n };\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n const response = query({\n prompt: createPromptStream(),\n options: {\n abortController,\n model: MODEL,\n cwd: process.cwd(),\n permissionMode: 'acceptEdits',\n maxTurns: MAX_TURNS,\n // Match agent-interface.ts — the 1M context beta is what keeps\n // resumed follow-up sessions from truncating after a few turns.\n betas: ['context-1m-2025-08-07'],\n // Only load project-level skills/settings. Without this the SDK\n // defaults to ['user', 'project'] and a user's\n // `~/.claude/settings.json` (apiKeyHelper / env block) can\n // override the OAuth routing we set above.\n settingSources: ['project'],\n // When set, the SDK replays the named session's turns into the\n // new query so the follow-up prompt has full conversation\n // context. Omit on the first prompt for a fresh session.\n ...(resumeSessionId ? { resume: resumeSessionId } : {}),\n // Without `canUseTool` the SDK falls back to \"ask the user\" on\n // every MCP tool call — `permissionMode: 'acceptEdits'` only\n // relaxes Edit/Write, not MCP. Our Ink TUI has no surface to\n // answer that prompt, so the agent would stall mid-stream\n // saying things like \"needs your approval to create dashboard\".\n // The tutorial's whole point is demoing the MCP tools against\n // the user's project, so we auto-allow everything that matches\n // the prefix and deny anything else (defense in depth — the\n // `allowedTools` filter above already enforces this).\n canUseTool: (toolName: string, input: unknown) => {\n if (toolName.startsWith('mcp__posthog-wizard__')) {\n return Promise.resolve({\n behavior: 'allow' as const,\n updatedInput: (input ?? {}) as Record<string, unknown>,\n });\n }\n logToFile(`[runMcpPromptViaSdk] denying non-MCP tool: ${toolName}`);\n return Promise.resolve({\n behavior: 'deny' as const,\n message: `${toolName} is not available in the MCP tutorial — only PostHog MCP tools are permitted.`,\n });\n },\n systemPrompt: {\n type: 'preset',\n preset: 'claude_code',\n append: buildTerminalFitPrompt(),\n },\n mcpServers: {\n 'posthog-wizard': {\n type: 'http',\n url: mcpUrl,\n headers: {\n // Env reference, not the token: the SDK puts this config on the\n // spawned CLI's argv, where `ps` shows it to any local process.\n Authorization: 'Bearer ${POSTHOG_MCP_TOKEN}',\n 'User-Agent': WIZARD_USER_AGENT,\n },\n // CLI mode's single `exec` tool carries the full command reference\n // on its schema — keep it in context, never deferred behind tool\n // search.\n alwaysLoad: true,\n },\n },\n // Only let the agent use MCP tools — no shell, no file I/O,\n // no Read/Edit/Write. This is a chat-with-MCP run, not a\n // wizard skill execution.\n allowedTools: ['mcp__posthog-wizard__*'],\n env: {\n // Drop the ENTIRE ANTHROPIC_*/CLAUDE_CODE_* namespace from the\n // inherited env so no shell/settings value can silently bypass the\n // PostHog gateway and defeat quota tracking / the OAuth flow; the\n // wizard's own gateway routing is injected fresh below. See\n // agent-env-isolation.ts.\n ...sanitizeAgentSubprocessEnv(process.env),\n // Gateway routing from this run's own auth, not process.env: a\n // concurrent run writes those globals too, and there is an await\n // between the write above and this read.\n ANTHROPIC_BASE_URL: auth.gatewayUrl,\n ANTHROPIC_AUTH_TOKEN: auth.token,\n CLAUDE_CODE_OAUTH_TOKEN: auth.token,\n // Point the binary at an empty config dir so it cannot resolve a\n // stored Claude login and send that to the gateway, which 401s it.\n // See stored-login.ts.\n CLAUDE_CONFIG_DIR: createIsolatedAgentConfigDir(),\n CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS: 'true',\n // The MCP config resolves this in the child; sending the value would\n // put it on the CLI's argv.\n POSTHOG_MCP_TOKEN: credentials.accessToken,\n // SDK 0.3.142+ connects MCP servers in the background by\n // default; without this the agent may try to call tools\n // before posthog-wizard is connected on turn 1.\n MCP_CONNECTION_NONBLOCKING: '0',\n // This run's trace tags, which the gateway reads to attribute its\n // `$ai_generation` events. Flags stay empty: the tutorial doesn't\n // fork on any.\n ANTHROPIC_CUSTOM_HEADERS: buildAgentEnv(\n wizardMetadata ?? {},\n {},\n auth.teamId,\n ),\n },\n },\n });\n\n for await (const message of response as AsyncIterable<unknown>) {\n if (signal.aborted) return;\n for (const chunk of messageToChunks(message)) {\n yield chunk;\n if (chunk.kind === 'done') return;\n }\n }\n } catch (err) {\n const text = err instanceof Error ? err.message : String(err);\n logToFile(`[runMcpPromptViaSdk] error: ${text}`);\n yield { kind: 'error', text };\n } finally {\n // Closes the prompt stream so `query()` shuts down cleanly even if\n // we never saw a 'result' message.\n abortController.abort();\n }\n}\n"],"mappings":"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"}
@@ -1,18 +1,22 @@
1
- import { d as ErrorCodes, o as AgentSignals } from "./errors--OqLxmWR.js";
2
- import { C as AGENTIC_DETECTION_TIMEOUT_MS, K as POSTHOG_DOCS_URL, St as headlessOption, V as Integration, _ as SIGNUP_WIZARD_READINESS_CONFIG, at as WIZARD_INTERACTION_EVENT_NAME, p as getUI, pt as WIZARD_USER_AGENT, r as debug, s as logToFile, v as evaluateWizardReadiness, wt as regionOption, y as getBlockingServiceKeys } from "./debug-DWYDVp0B.js";
3
- import { o as mayReportScanResults } from "./wizard-session-FSJCkTcP.js";
4
- import { n as analytics } from "./analytics-DSVyjIVF.js";
5
- import { i as withUtm, n as openTrackedLink } from "./telemetry-PD7bhcda.js";
6
- import "./bounded-fs-FbZJ_vJ_.js";
7
- import { i as tryGetPackageJson, n as isUsingTypeScript } from "./setup-utils-Bj0gejEf.js";
8
- import { i as requestDeepLink } from "./provisioning-B-tzjG4r.js";
9
- import { s as handleApiError } from "./api-Ci0dZWLR.js";
10
- import { i as wizardAbort } from "./wizard-abort-hqHF-9xD.js";
11
- import { R as WIZARD_TOOL_NAMES, it as LONGER_ASK_TIMEOUT_MS } from "./agent-interface-DPaPdIjS.js";
12
- import { _ as detectProjectsWithAgent, b as detectFramework, f as findPackageJsons, g as detectWarehouseSources, h as getDetectedWarehouseSources, m as detectWarehousePrerequisites, n as runAgent, p as WAREHOUSE_ABORT_CASES, r as shouldDisableAsk, s as detectPostHogIntegration, v as resolveProjectDir, x as authenticate, y as gatherFrameworkContext } from "./agent-runner-JFwQQj2k.js";
13
- import { i as SPINNER_MESSAGE, t as FRAMEWORK_REGISTRY } from "./registry-D1L5e-WQ.js";
14
- import { S as SETUP_REPORT_FILE$1, _ as AUDIT_CHECKS_KEY, g as AUDIT_CHECKS_FILE, h as EVENT_PLAN_FILE, v as AUDIT_REPORT_FILE } from "./yara-hooks-BaPKsm-B.js";
15
- import { C as writeJsonAtomic } from "./queue-tools-7Oso-fpt.js";
1
+ import { a as AgentSignals, d as ErrorCodes } from "./errors-CQ9kttJD.js";
2
+ import { r as debug, s as logToFile, x as regionOption, y as headlessOption } from "./debug-Ch4BDOtD.js";
3
+ import { Q as WIZARD_USER_AGENT, U as WIZARD_INTERACTION_EVENT_NAME, f as EVENTS_AUDIT_REPORT_FILE, h as EVENT_PLAN_FILE, k as POSTHOG_DOCS_URL, w as Integration } from "./constants-jFI2SaE1.js";
4
+ import { r as mayReportScanResults } from "./wizard-session-2w4Ru-Wz.js";
5
+ import { n as analytics } from "./analytics-CHCZ_qUR.js";
6
+ import { i as withUtm, n as openTrackedLink } from "./telemetry-D6ruCtnv.js";
7
+ import "./bounded-fs-Bx9zTe6m.js";
8
+ import { i as tryGetPackageJson, n as isUsingTypeScript } from "./setup-utils-CmTCTPkX.js";
9
+ import { a as getBlockingServiceKeys, i as evaluateWizardReadiness, r as SIGNUP_WIZARD_READINESS_CONFIG } from "./logging-ui-_TwoMNbG.js";
10
+ import { t as getUI } from "./ui-BBVuTM1v.js";
11
+ import { i as requestDeepLink } from "./provisioning-B8uSqRZk.js";
12
+ import { s as handleApiError } from "./api-Diy_2fp8.js";
13
+ import { i as wizardAbort } from "./wizard-abort-BBkiUxfS.js";
14
+ import { _ as detectProjectsWithAgent, b as detectFramework, d as findPackageJsons, f as WAREHOUSE_ABORT_CASES, g as AgenticDetectionTimeoutError, h as detectWarehouseSources, m as getDetectedWarehouseSources, o as detectPostHogIntegration, p as detectWarehousePrerequisites, r as AUDIT_CHECKS_KEY, t as runProgramAgent, v as resolveProjectDir, x as authenticate, y as gatherFrameworkContext } from "./run-agent-legacy-d7rWlzQR.js";
15
+ import { I as WIZARD_TOOL_NAMES, nt as LONGER_ASK_TIMEOUT_MS } from "./agent-interface-BAOIHuXS.js";
16
+ import { s as shouldDisableAsk } from "./agent-bCZ3i3fh.js";
17
+ import { g as AUDIT_REPORT_FILE, h as AUDIT_CHECKS_FILE } from "./yara-hooks-DCeMDd1o.js";
18
+ import { y as writeJsonAtomic } from "./queue-tools-9OOVx5TE.js";
19
+ import { i as SPINNER_MESSAGE, t as FRAMEWORK_REGISTRY } from "./registry-8YG-kuXk.js";
16
20
  import { existsSync, readFileSync, readdirSync, statSync } from "fs";
17
21
  import path, { join } from "path";
18
22
  import * as os from "node:os";
@@ -55,8 +59,6 @@ async function detectIntegrationProjects(session, options) {
55
59
  function chooseIntegrationProject(projects) {
56
60
  return projects.find((p) => p.recommended === true && p.targetId != null) ?? projects.find((p) => p.targetId != null && !p.hasPostHog);
57
61
  }
58
- /** Sentinel for a scan that outran AGENTIC_DETECTION_TIMEOUT_MS. */
59
- const TIMED_OUT = Symbol("timed-out");
60
62
  function captureOutcome(outcome, properties = {}) {
61
63
  analytics.wizardCapture("agentic detection", {
62
64
  outcome,
@@ -74,13 +76,18 @@ async function scopeInstallDirToProject(session) {
74
76
  const startedAt = Date.now();
75
77
  let report;
76
78
  try {
77
- report = await Promise.race([detectIntegrationProjects(session, {
79
+ report = await detectIntegrationProjects(session, {
78
80
  programId: "posthog-integration",
79
81
  recommend: true,
80
82
  onEvent: (line) => logToFile("[agentic detect]", line)
81
- }), new Promise((resolve) => setTimeout(() => resolve(TIMED_OUT), AGENTIC_DETECTION_TIMEOUT_MS))]);
83
+ });
82
84
  } catch (err) {
83
85
  const error = err instanceof Error ? err : new Error(String(err));
86
+ if (error instanceof AgenticDetectionTimeoutError) {
87
+ captureOutcome("timeout", { duration_ms: Date.now() - startedAt });
88
+ getUI().log.warn(`${error.message}; continuing with the install dir as-is.`);
89
+ return;
90
+ }
84
91
  analytics.captureException(error, { step: "agentic_detection" });
85
92
  captureOutcome("error", {
86
93
  duration_ms: Date.now() - startedAt,
@@ -89,11 +96,6 @@ async function scopeInstallDirToProject(session) {
89
96
  getUI().log.warn(`Project scan failed (${error.message}); continuing with the install dir as-is.`);
90
97
  return;
91
98
  }
92
- if (report === TIMED_OUT) {
93
- captureOutcome("timeout", { duration_ms: Date.now() - startedAt });
94
- getUI().log.warn(`Project scan timed out after ${AGENTIC_DETECTION_TIMEOUT_MS / 1e3}s; continuing with the install dir as-is.`);
95
- return;
96
- }
97
99
  const { projects } = report;
98
100
  const recommended = projects.find((p) => p.recommended === true);
99
101
  const scanProperties = {
@@ -757,7 +759,7 @@ const PRODUCT_SUITE_BLOCK = {
757
759
  color: "cyan",
758
760
  children: "◆ "
759
761
  }),
760
- "PostHog Code"
762
+ "PostHog Desktop"
761
763
  ] })
762
764
  ]
763
765
  };
@@ -1197,7 +1199,62 @@ const getContentBlocks$5 = (store) => [
1197
1199
  content: "PostHog has all the dev tools you need.",
1198
1200
  pause: 3e3
1199
1201
  },
1200
- PRODUCT_SUITE_BLOCK
1202
+ PRODUCT_SUITE_BLOCK,
1203
+ {
1204
+ type: "clear",
1205
+ pause: 2e3
1206
+ },
1207
+ {
1208
+ content: "The wizard is wiring up your PostHog stack with...",
1209
+ pause: 2500
1210
+ },
1211
+ {
1212
+ type: "lines",
1213
+ interval: 1e3,
1214
+ pause: 12e3,
1215
+ lines: [
1216
+ /* @__PURE__ */ jsxs(Text, { children: [
1217
+ /* @__PURE__ */ jsx(Text, {
1218
+ color: "cyan",
1219
+ children: " ◆ "
1220
+ }),
1221
+ "Product Analytics ",
1222
+ /* @__PURE__ */ jsx(Text, {
1223
+ color: "cyan",
1224
+ children: "◆ "
1225
+ }),
1226
+ "Web Analytics"
1227
+ ] }),
1228
+ /* @__PURE__ */ jsxs(Text, { children: [
1229
+ /* @__PURE__ */ jsx(Text, {
1230
+ color: "cyan",
1231
+ children: " ◆ "
1232
+ }),
1233
+ "Error Tracking ",
1234
+ /* @__PURE__ */ jsx(Text, {
1235
+ color: "cyan",
1236
+ children: "◆ "
1237
+ }),
1238
+ "Session Replay"
1239
+ ] }),
1240
+ /* @__PURE__ */ jsxs(Text, { children: [
1241
+ /* @__PURE__ */ jsx(Text, {
1242
+ color: "cyan",
1243
+ children: " ◆ "
1244
+ }),
1245
+ "AI Observability ",
1246
+ /* @__PURE__ */ jsx(Text, {
1247
+ color: "cyan",
1248
+ children: "◆ "
1249
+ }),
1250
+ "Logs"
1251
+ ] }),
1252
+ /* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
1253
+ color: "cyan",
1254
+ children: " ◆ "
1255
+ }), "Data Warehouse sources"] })
1256
+ ]
1257
+ }
1201
1258
  ];
1202
1259
  //#endregion
1203
1260
  //#region src/lib/programs/posthog-integration/handoff.ts
@@ -1227,6 +1284,24 @@ function resolveContinueUrl(sess, host, deepLink) {
1227
1284
  /** Sources listed with their own link before the outro falls back to a summary line. */
1228
1285
  const WAREHOUSE_LINK_LIMIT = 3;
1229
1286
  /**
1287
+ * How many detected sources the seeded step is allowed to collect credentials
1288
+ * for.
1289
+ *
1290
+ * The step's cost to the user is one credential prompt per source, and the
1291
+ * wizard knows the count at seed time: detection keys off dependency and
1292
+ * `.env` key names, so an ordinary app can match a dozen sources it has no
1293
+ * intention of importing. Offering all of them asks a person to agree, up
1294
+ * front, to an interrogation whose length they cannot see — and the runs
1295
+ * offered more than a handful answer none of the prompts at all, while the
1296
+ * short ones are where every connected source comes from.
1297
+ *
1298
+ * So the step takes the first few and the outro carries the rest as links,
1299
+ * which is the same trade {@link WAREHOUSE_LINK_LIMIT} already makes for a
1300
+ * list too long to read. Ordering is the registry's, which groups databases
1301
+ * ahead of the API-key SaaS that inflates the tail.
1302
+ */
1303
+ const WAREHOUSE_SEED_LIMIT = 3;
1304
+ /**
1230
1305
  * The app's new-source page, pre-selected to one source kind.
1231
1306
  *
1232
1307
  * `kind` is matched case-insensitively against the connector list, and a kind
@@ -1254,13 +1329,15 @@ function warehouseSourceUrl(host, projectId, kind) {
1254
1329
  *
1255
1330
  * Returns undefined when nothing was detected, so the outro is unchanged for
1256
1331
  * projects with no connectable source — and when the run's own warehouse step
1257
- * connected them, where every bullet here would ask the user to redo work the
1258
- * wizard just did and send them at a new-source form that would collide with
1259
- * the source already created.
1332
+ * connected everything it was given, where every bullet here would ask the
1333
+ * user to redo work the wizard just did and send them at a new-source form
1334
+ * that would collide with the source already created. A completed step is
1335
+ * only ever given the first {@link WAREHOUSE_SEED_LIMIT} sources, so anything
1336
+ * past that is still unconnected and still belongs here.
1260
1337
  */
1261
1338
  function buildWarehouseNextSteps(sess, host, projectId, completedSeededTypes) {
1262
- if (completedSeededTypes.includes(WAREHOUSE_SEED_TASK_TYPE)) return void 0;
1263
- const sources = getDetectedWarehouseSources(sess);
1339
+ const detected = getDetectedWarehouseSources(sess);
1340
+ const sources = completedSeededTypes.includes(WAREHOUSE_SEED_TASK_TYPE) ? detected.slice(WAREHOUSE_SEED_LIMIT) : detected;
1264
1341
  if (sources.length === 0) return void 0;
1265
1342
  const listed = sources.slice(0, WAREHOUSE_LINK_LIMIT);
1266
1343
  const items = listed.map((s) => `Connect ${s.label}: ${warehouseSourceUrl(host, projectId, s.kind)}`);
@@ -1301,19 +1378,24 @@ function warehouseReportInstruction(sess) {
1301
1378
  *
1302
1379
  * Empty when nothing was detected, and in CI, signup, and any other run where
1303
1380
  * `wizard_ask` is disabled — a credential prompt nobody can answer would burn
1304
- * the task's whole timeout and then fail the run.
1381
+ * the task's whole timeout and then fail the run. Capped at
1382
+ * {@link WAREHOUSE_SEED_LIMIT} sources, with the rest handed over as outro
1383
+ * links by {@link buildWarehouseNextSteps}.
1305
1384
  */
1306
1385
  const warehouseSeedTasks = (sess) => {
1307
1386
  if (shouldDisableAsk(sess)) return [];
1308
1387
  const sources = getDetectedWarehouseSources(sess);
1309
1388
  if (sources.length === 0) return [];
1389
+ const offered = sources.slice(0, WAREHOUSE_SEED_LIMIT);
1390
+ const deferred = sources.length - offered.length;
1310
1391
  if (mayReportScanResults(sess)) analytics.wizardCapture("orchestrator warehouse task queued", {
1311
1392
  warehouse_source_count: sources.length,
1312
- warehouse_source_kinds: sources.map((s) => s.kind)
1393
+ warehouse_source_kinds: sources.map((s) => s.kind),
1394
+ warehouse_offered_count: offered.length
1313
1395
  });
1314
1396
  return [{
1315
1397
  type: WAREHOUSE_SEED_TASK_TYPE,
1316
- inputs: { sources: sources.map((s) => ({
1398
+ inputs: { sources: offered.map((s) => ({
1317
1399
  kind: s.kind,
1318
1400
  label: s.label,
1319
1401
  mode: s.mode,
@@ -1321,8 +1403,12 @@ const warehouseSeedTasks = (sess) => {
1321
1403
  })) },
1322
1404
  notice: {
1323
1405
  title: "Connect your data sources",
1324
- body: ["We detected some warehouse sources we can connect to enrich your PostHog data. Answer now, and we connect them at the end of the run, after your code changes. We will ask you for the credentials at that point, and beep when we do.", "You can select [Skip] if you'd like to do this later in PostHog."],
1325
- items: sources.map((s) => s.label),
1406
+ body: [
1407
+ "We detected some warehouse sources we can connect to enrich your PostHog data. Answer now, and we connect them at the end of the run, after your code changes. We will ask you for the credentials at that point, and beep when we do.",
1408
+ ...deferred > 0 ? [`We found ${deferred} more we can connect. Those are listed with a link each at the end, so this step stays short.`] : [],
1409
+ "You can select [Skip] if you'd like to do this later in PostHog."
1410
+ ],
1411
+ items: offered.map((s) => s.label),
1326
1412
  docsLabel: "Learn more about warehouse sources",
1327
1413
  docsUrl: WAREHOUSE_SOURCES_DOCS_URL,
1328
1414
  prompt: "Connect these during setup?",
@@ -1341,6 +1427,7 @@ const posthogIntegrationConfig = {
1341
1427
  getContentBlocks: getContentBlocks$5,
1342
1428
  disallowedTools: [WIZARD_TOOL_NAMES.wizardAsk],
1343
1429
  seedTasks: warehouseSeedTasks,
1430
+ excludedTaskTypes: (flags) => flags["wizard-default-aio-logs"] === "false" ? ["ai-observability", "logs"] : [],
1344
1431
  ciPreRun: async (session) => {
1345
1432
  await scopeInstallDirToProject(session);
1346
1433
  const integration = await detectFramework(session.installDir);
@@ -1375,7 +1462,7 @@ const posthogIntegrationConfig = {
1375
1462
  if (usesPackageJson) {
1376
1463
  const packageJson = await tryGetPackageJson({ installDir: session.installDir });
1377
1464
  if (packageJson) {
1378
- const { hasDeclaredDependency } = await import("./package-json-xt3eeyBI.js").then((n) => n.i);
1465
+ const { hasDeclaredDependency } = await import("./package-json-DY70kkNp.js").then((n) => n.i);
1379
1466
  if (!hasDeclaredDependency(config.detection.packageName, packageJson)) getUI().log.warn(`${config.detection.packageDisplayName} does not seem to be installed. Continuing anyway — the agent will handle it.`);
1380
1467
  frameworkVersion = config.detection.getVersion(packageJson);
1381
1468
  } else getUI().log.warn("Could not find package.json. Continuing anyway — the agent will handle it.");
@@ -1384,6 +1471,7 @@ const posthogIntegrationConfig = {
1384
1471
  const versionBucket = config.detection.getVersionBucket(frameworkVersion);
1385
1472
  analytics.setTag(`${config.metadata.integration}-version`, versionBucket);
1386
1473
  }
1474
+ const skillCategoryInstruction = (await analytics.getAllFlagsForWizard())["wizard-default-aio-logs"] !== "false" ? `Choose a skill from the \`integration\` category that matches this project's framework. Start with this framework skill; load the AI Observability and Logs skills when its workflow calls for them, and follow each installed skill's own steps to completion — framework first, then AI Observability, then Logs — before verification and the setup report. Both are included by default where applicable; the skills define applicability and how to report skipped work. These three categories — \`integration\`, \`ai-observability\`, \`logs\` — are the only ones this run uses. Do NOT load or install skills from any other category (llm-analytics, error-tracking, feature-flags, audit, etc.) — those are handled separately. In particular, \`ai-observability\` is the category for AI Observability; do not substitute \`llm-analytics\`.` : `Choose a skill from the \`integration\` category that matches this project's framework. The \`integration\` category is the ONLY one this run uses. Do NOT load or install skills from any other category (ai-observability, logs, llm-analytics, error-tracking, feature-flags, audit, etc.) — those are handled separately. If the installed skill's workflow contains an "AI Observability and Logs" section, skip that entire section: this run excludes both products.`;
1387
1475
  const frameworkContext = session.frameworkContext;
1388
1476
  const contextTags = config.analytics.getTags(frameworkContext);
1389
1477
  Object.entries(contextTags).forEach(([key, value]) => {
@@ -1399,7 +1487,6 @@ const posthogIntegrationConfig = {
1399
1487
  reportFile: SETUP_REPORT_FILE,
1400
1488
  docsUrl: config.metadata.docsUrl,
1401
1489
  errorMessage: "Integration failed",
1402
- additionalFeatureQueue: session.additionalFeatureQueue,
1403
1490
  richLinks: true,
1404
1491
  customPrompt: (ctx) => {
1405
1492
  const additionalLines = config.prompts.getAdditionalContextLines ? config.prompts.getAdditionalContextLines(frameworkContext) : [];
@@ -1417,10 +1504,10 @@ Project context:
1417
1504
 
1418
1505
  Instructions (follow these steps IN ORDER - do not skip or reorder):
1419
1506
 
1420
- STEP 1: Call load_skill_menu (from the wizard-tools MCP server) to see available skills.
1507
+ STEP 1: Call load_skill_menu (from the wizard-tools MCP server) with category: "integration" to see available framework skills.
1421
1508
  If the tool fails, emit: ${AgentSignals.ERROR_MCP_MISSING} Could not load skill menu and halt.
1422
1509
 
1423
- Choose a skill from the \`integration\` category that matches this project's framework. Do NOT pick skills from other categories (llm-analytics, error-tracking, feature-flags, omnibus, etc.) — those are handled separately.
1510
+ ${skillCategoryInstruction}
1424
1511
  If no suitable integration skill is found, emit: ${AgentSignals.ERROR_RESOURCE_MISSING} Could not find a suitable skill for this project.
1425
1512
 
1426
1513
  STEP 2: Call install_skill (from the wizard-tools MCP server) with the chosen skill ID (e.g., "integration-nextjs-app-router").
@@ -1444,7 +1531,7 @@ ${warehouseReportInstruction(session)}
1444
1531
  postRun: async (sess, credentials) => {
1445
1532
  const envVars = config.environment.getEnvVars(credentials.projectApiKey, credentials.host.apiHost);
1446
1533
  if (config.environment.uploadToHosting) {
1447
- const { uploadEnvironmentVariablesStep } = await import("./steps-CpNTGu9N.js");
1534
+ const { uploadEnvironmentVariablesStep } = await import("./steps-BZcXRJNY.js");
1448
1535
  const uploadedEnvVars = await uploadEnvironmentVariablesStep(envVars, {
1449
1536
  integration: config.metadata.integration,
1450
1537
  session: sess
@@ -1495,7 +1582,7 @@ const integrationRunStep = {
1495
1582
  id: "run",
1496
1583
  label: "Integration",
1497
1584
  screenId: "run",
1498
- run: (session) => runAgent(posthogIntegrationConfig, session, { composed: true }),
1585
+ run: (session) => runProgramAgent(posthogIntegrationConfig, session, { composed: true }),
1499
1586
  isComplete: (session) => session.runPhase === "completed" || session.runPhase === "error"
1500
1587
  };
1501
1588
  //#endregion
@@ -2149,7 +2236,7 @@ const eventsAuditConfig = {
2149
2236
  id: "events-audit",
2150
2237
  skillId: "events-audit",
2151
2238
  steps: EVENTS_AUDIT_PROGRAM,
2152
- reportFile: SETUP_REPORT_FILE$1,
2239
+ reportFile: EVENTS_AUDIT_REPORT_FILE,
2153
2240
  auditLedgerFile: AUDIT_CHECKS_FILE,
2154
2241
  allowedTools: [
2155
2242
  "Agent",
@@ -2169,10 +2256,9 @@ const eventsAuditConfig = {
2169
2256
  spinnerMessage: SPINNER_MESSAGE,
2170
2257
  successMessage: "Events audit complete! You can view the report at ./posthog-events-audit-report.md",
2171
2258
  estimatedDurationMinutes: 5,
2172
- reportFile: SETUP_REPORT_FILE$1,
2259
+ reportFile: EVENTS_AUDIT_REPORT_FILE,
2173
2260
  docsUrl: DOCS_URL$3,
2174
2261
  errorMessage: "Events audit failed",
2175
- additionalFeatureQueue: session.additionalFeatureQueue,
2176
2262
  customPrompt: (ctx) => `Audit PostHog event capture in this project. Do not modify any project files — produce a read-only report only.
2177
2263
 
2178
2264
  Project context:
@@ -2186,7 +2272,7 @@ Project context:
2186
2272
  return {
2187
2273
  kind: "success",
2188
2274
  message: "Your events audit was successful",
2189
- reportFile: SETUP_REPORT_FILE$1,
2275
+ reportFile: EVENTS_AUDIT_REPORT_FILE,
2190
2276
  changes: [],
2191
2277
  docsUrl: DOCS_URL$3,
2192
2278
  continueUrl: sess.signup ? `${cloudUrl}/products?source=wizard` : void 0,
@@ -5497,7 +5583,7 @@ const AI_OBSERVABILITY_STEPS = AGENT_SKILL_STEPS.map((step) => step.id === "intr
5497
5583
  const AI_OBSERVABILITY_REPORT_FILE = "posthog-ai-observability-report.md";
5498
5584
  /**
5499
5585
  * `wizard ai-observability` — wrap the project's LLM client calls so they emit
5500
- * `$ai_generation` events into LLM Analytics.
5586
+ * `$ai_generation` events into AI Observability.
5501
5587
  *
5502
5588
  * No `run.skillId`: the context-mill `ai-observability` group ships one variant
5503
5589
  * per (LLM provider × language) and the wizard does no provider detection —
@@ -5740,4 +5826,4 @@ function isRunFailure(session) {
5740
5826
  //#endregion
5741
5827
  export { wordWrap as $, installOrUpdatePostHogCli as A, webAnalyticsDoctorConfig as B, ERROR_TRACKING_PROJECT_PATH_KEY as C, CLI_STEERING_TARGETS as D, errorTrackingUploadSourceMapsConfig as E, MANUAL_SDK_INSTALL as F, createSkillProgram as G, getKindMeta as H, MANUAL_SDK_VARIANTS as I, getContentBlocks$4 as J, warehouseSourceConfig as K, RUST_SDK_CRATE as L, AUTOMATABLE_VARIANTS as M, DISPLAY_NAME as N, detectTargets as O, GO_SDK_MODULE as P, computeVisibleRange as Q, SOURCE_MAPS_CONTEXT_KEYS as R, errorTrackingConfig as S, replayVisionConfig as T, fetchHealthIssues as U, posthogDoctorConfig as V, auditConfig as W, posthogIntegrationConfig as X, SETUP_REPORT_FILE as Y, TextBlock as Z, PRICING_SHORT as _, PROGRAM_REGISTRY as a, GITHUB_REQUIRED_MESSAGE as b, getCommandPath as c, metricsConfig as d, isClearBlock as et, aiObservabilityConfig as f, PRICING_LONG as g, NO_DEFAULT_LIMIT as h, isRunFailure as i, Icons as it, installSteeringSnippet as j, findTarget as k, getLaunchablePrograms as l, selfDrivingConfig as m, MINT_FAILURE_CONTACT as n, isObjectBlock as nt, Program as o, mcpAnalyticsConfig as p, revenueAnalyticsConfig as q, MINT_FAILURE_MESSAGE as r, Colors as rt, agentSkillConfig as s, MINT_FAILURE_BODY as t, isLinesBlock as tt, getProgramConfig as u, detectSelfDrivingIntegrationProjects as v, detectErrorTrackingProjects as w, SELF_DRIVING_INTEGRATE_PATH_KEY as x, GITHUB_REQUIRED_BODY as y, migrationConfig as z };
5742
5828
 
5743
- //# sourceMappingURL=mint-failure-C82j0RMC.js.map
5829
+ //# sourceMappingURL=mint-failure-D4nd2XmZ.js.map