@posthog/wizard 2.80.0 → 2.80.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +187 -57
- package/dist/{PickerMenu-m4CCPX4f.js → PickerMenu-BGGeYqd-.js} +104 -4
- package/dist/PickerMenu-BGGeYqd-.js.map +1 -0
- package/dist/README.md +9 -6
- package/dist/{agent-interface-CzyCmp7q.js → agent-interface-CemBvTAA.js} +115 -346
- package/dist/agent-interface-CemBvTAA.js.map +1 -0
- package/dist/{agent-prompt-loader-4wMxlYSX.js → agent-prompt-loader-DPnj6SwU.js} +6 -5
- package/dist/agent-prompt-loader-DPnj6SwU.js.map +1 -0
- package/dist/analytics-B3ROGuIr.js +2 -0
- package/dist/analytics-D21z3E5l.js +732 -0
- package/dist/analytics-D21z3E5l.js.map +1 -0
- package/dist/{api-C3Dc4LFl.js → api-DtGIqQ2U.js} +2 -3
- package/dist/api-DtGIqQ2U.js.map +1 -0
- package/dist/api-IhROOQNv.js +2 -0
- package/dist/api-key-login-OEntFvu5.js +2 -0
- package/dist/api-key-login-h3E2G3zu.js +55 -0
- package/dist/api-key-login-h3E2G3zu.js.map +1 -0
- package/dist/bin.js +2 -2
- package/dist/bin.js.map +1 -1
- package/dist/{bounded-fs-CC_NDtoP.js → bounded-fs-CAsuF6al.js} +3 -3
- package/dist/{bounded-fs-CC_NDtoP.js.map → bounded-fs-CAsuF6al.js.map} +1 -1
- package/dist/{ci-install-DfcAMhlu.js → ci-install-CEYE02t-.js} +21 -25
- package/dist/ci-install-CEYE02t-.js.map +1 -0
- package/dist/console-log-O828zyiq.js +32 -0
- package/dist/console-log-O828zyiq.js.map +1 -0
- package/dist/{debug-DyARf5TF.js → debug-BfQPD2Hg.js} +18 -52
- package/dist/debug-BfQPD2Hg.js.map +1 -0
- package/dist/{defaults-DpfMnH2q.js → defaults-DDVl3tKN.js} +2 -51
- package/dist/defaults-DDVl3tKN.js.map +1 -0
- package/dist/{emit-BSetXzDV.js → emit-RfAewcWv.js} +1 -1
- package/dist/{emit-BSetXzDV.js.map → emit-RfAewcWv.js.map} +1 -1
- package/dist/{errors-C2domSkK.js → errors-CHrJzAZb.js} +4 -4
- package/dist/{errors-C2domSkK.js.map → errors-CHrJzAZb.js.map} +1 -1
- package/dist/family-picker-BKs-tTyu.js +46 -0
- package/dist/family-picker-BKs-tTyu.js.map +1 -0
- package/dist/{gateway-BmjYUSua.js → gateway-D3gIlR6b.js} +122 -11
- package/dist/gateway-D3gIlR6b.js.map +1 -0
- package/dist/headless-BJjhP0SI.js +10 -0
- package/dist/headless-BJjhP0SI.js.map +1 -0
- package/dist/headless-DIX68UUA.js +3 -0
- package/dist/{host-resolution-DVSb7kXb.js → host-resolution-D8GhEVoX.js} +4 -4
- package/dist/{host-resolution-DVSb7kXb.js.map → host-resolution-D8GhEVoX.js.map} +1 -1
- package/dist/install-Bw8tvDvS.js +2 -0
- package/dist/{install-Bk5TNk27.js → install-paPCzPHI.js} +26 -93
- package/dist/install-paPCzPHI.js.map +1 -0
- package/dist/interactive-tdxZKWax.js +11 -0
- package/dist/interactive-tdxZKWax.js.map +1 -0
- package/dist/{links-9LWZPSCq.js → links-Cyj6v8kg.js} +3 -3
- package/dist/{links-9LWZPSCq.js.map → links-Cyj6v8kg.js.map} +1 -1
- package/dist/{main-DKPjFHEV.js → main-0p-YxUNa.js} +204 -469
- package/dist/main-0p-YxUNa.js.map +1 -0
- package/dist/{mcp-Co8VRF62.js → mcp-D3Z5MXhA.js} +3 -4
- package/dist/{mcp-Co8VRF62.js.map → mcp-D3Z5MXhA.js.map} +1 -1
- package/dist/mcp-install-smoke-test.ts +2 -2
- package/dist/{mcp-prompt-streaming-ljCVoQ9I.js → mcp-prompt-streaming-COVbWnHt.js} +12 -12
- package/dist/mcp-prompt-streaming-COVbWnHt.js.map +1 -0
- package/dist/mode-label-DB3ol_sj.js +9 -0
- package/dist/mode-label-DB3ol_sj.js.map +1 -0
- package/dist/{models-Dba8ITeo.js → models-D1SnCzvl.js} +2 -2
- package/dist/{models-Dba8ITeo.js.map → models-D1SnCzvl.js.map} +1 -1
- package/dist/non-interactive-DxRBc73O.js +18 -0
- package/dist/non-interactive-DxRBc73O.js.map +1 -0
- package/dist/{oauth-session-D-RfcVmr.js → oauth-session-Dde79Ycm.js} +3 -3
- package/dist/{oauth-session-D-RfcVmr.js.map → oauth-session-Dde79Ycm.js.map} +1 -1
- package/dist/{orchestrator-tools-CVJ1F9Ub.js → orchestrator-tools-BSNhzzkT.js} +3 -3
- package/dist/{orchestrator-tools-CVJ1F9Ub.js.map → orchestrator-tools-BSNhzzkT.js.map} +1 -1
- package/dist/{package-json-Cowya9-3.js → package-json-2UrhE6kP.js} +1 -1
- package/dist/{package-json-Cowya9-3.js.map → package-json-2UrhE6kP.js.map} +1 -1
- package/dist/package-json-Dblip2_X.js +2 -0
- package/dist/package-manager-BRXlXo0p.js +105 -0
- package/dist/package-manager-BRXlXo0p.js.map +1 -0
- package/dist/{pi-B5YTBRDv.js → pi-cM_4Gd_9.js} +16 -18
- package/dist/pi-cM_4Gd_9.js.map +1 -0
- package/dist/playground-DTKy0XHT.js +12 -0
- package/dist/playground-DTKy0XHT.js.map +1 -0
- package/dist/posthog-integration-bwHwE87a.js +10291 -0
- package/dist/posthog-integration-bwHwE87a.js.map +1 -0
- package/dist/programs-BhtyA3lE.js +3 -0
- package/dist/programs-SeT1qNik.js +5348 -0
- package/dist/programs-SeT1qNik.js.map +1 -0
- package/dist/provisioning-BcXfeCMc.js +2 -0
- package/dist/{provisioning-CLhuKqXH.js → provisioning-JbJtq7hq.js} +4 -5
- package/dist/{provisioning-CLhuKqXH.js.map → provisioning-JbJtq7hq.js.map} +1 -1
- package/dist/{queue-tools-knnPQP0e.js → queue-tools-BIZSJyt6.js} +6 -8
- package/dist/queue-tools-BIZSJyt6.js.map +1 -0
- package/dist/results-DtKICAdz.js +55 -0
- package/dist/results-DtKICAdz.js.map +1 -0
- package/dist/run-CDurA5tO.js +248 -0
- package/dist/run-CDurA5tO.js.map +1 -0
- package/dist/run-DDCvLILJ.js +246 -0
- package/dist/run-DDCvLILJ.js.map +1 -0
- package/dist/run-tool-CTq9OOdT.js +2 -0
- package/dist/run-tool-DML8JJvt.js +2420 -0
- package/dist/run-tool-DML8JJvt.js.map +1 -0
- package/dist/runners-Dhu4pZTN.js +253 -0
- package/dist/runners-Dhu4pZTN.js.map +1 -0
- package/dist/{security-BvdSFDuM.js → security-DEH8Rn0_.js} +5 -5
- package/dist/security-DEH8Rn0_.js.map +1 -0
- package/dist/setup-utils-C5-WM-hS.js +118 -0
- package/dist/setup-utils-C5-WM-hS.js.map +1 -0
- package/dist/smoke-test.sh +1 -1
- package/dist/{playground-BLsCfHmQ.js → start-playground-DL4mVEUx.js} +43 -34
- package/dist/start-playground-DL4mVEUx.js.map +1 -0
- package/dist/{subagent-D_Sqak94.js → subagent-CnFvAq6E.js} +3 -3
- package/dist/{subagent-D_Sqak94.js.map → subagent-CnFvAq6E.js.map} +1 -1
- package/dist/{task-DiTI6Sak.js → task-BOScSm4W.js} +16 -17
- package/dist/task-BOScSm4W.js.map +1 -0
- package/dist/{tasks-ChZ_F1YP.js → tasks-BfJhVky2.js} +1 -1
- package/dist/tasks-BfJhVky2.js.map +1 -0
- package/dist/{telemetry-BNKsDxNS.js → telemetry-CP4rGicd.js} +2 -2
- package/dist/{telemetry-BNKsDxNS.js.map → telemetry-CP4rGicd.js.map} +1 -1
- package/dist/terminal-J3OD3dN0.js +16162 -0
- package/dist/terminal-J3OD3dN0.js.map +1 -0
- package/dist/tools-CCMV3DmB.js +544 -0
- package/dist/tools-CCMV3DmB.js.map +1 -0
- package/dist/{tools-C8LQ8QFz.js → tools-Cz8tDptL.js} +9 -9
- package/dist/tools-Cz8tDptL.js.map +1 -0
- package/dist/tui-BUZ2PWqN.js +2 -0
- package/dist/tui-Csf7VJxt.js +25 -0
- package/dist/tui-Csf7VJxt.js.map +1 -0
- package/dist/{steps-Hc28zVc_.js → upload-step-CEacB2RV.js} +14 -16
- package/dist/upload-step-CEacB2RV.js.map +1 -0
- package/dist/{urls-BI4kJ4qQ.js → urls-BDELGZHq.js} +2 -2
- package/dist/{urls-BI4kJ4qQ.js.map → urls-BDELGZHq.js.map} +1 -1
- package/dist/warlock-smoke-test.ts +1 -2
- package/dist/{wizard-abort-DBKtfnBR.js → wizard-abort-D3-75KyV.js} +40 -33
- package/dist/wizard-abort-D3-75KyV.js.map +1 -0
- package/dist/yara-hooks-CZ1tKxy_.js +2 -0
- package/dist/{yara-hooks-C3L6lBij.js → yara-hooks-D8YDyX7o.js} +283 -21
- package/dist/yara-hooks-D8YDyX7o.js.map +1 -0
- package/package.json +6 -6
- package/dist/PickerMenu-m4CCPX4f.js.map +0 -1
- package/dist/agent-BkBbVuNq.js +0 -3189
- package/dist/agent-BkBbVuNq.js.map +0 -1
- package/dist/agent-QGK2YzlX.js +0 -6
- package/dist/agent-interface-CzyCmp7q.js.map +0 -1
- package/dist/agent-prompt-loader-4wMxlYSX.js.map +0 -1
- package/dist/analytics-B6q5PN7a.js +0 -301
- package/dist/analytics-B6q5PN7a.js.map +0 -1
- package/dist/analytics-BXtfK9o7.js +0 -2
- package/dist/api-C3Dc4LFl.js.map +0 -1
- package/dist/api-yNjrfZs2.js +0 -2
- package/dist/check-screens.tsx +0 -190
- package/dist/ci-install-DfcAMhlu.js.map +0 -1
- package/dist/constants-DO4X70po.js +0 -260
- package/dist/constants-DO4X70po.js.map +0 -1
- package/dist/debug-BueK5mRR.js +0 -2
- package/dist/debug-DyARf5TF.js.map +0 -1
- package/dist/defaults-DpfMnH2q.js.map +0 -1
- package/dist/endpoints-D-4KxZiB.js +0 -108
- package/dist/endpoints-D-4KxZiB.js.map +0 -1
- package/dist/env-api-key-CHGLe0iz.js +0 -2
- package/dist/env-api-key-COf0U-Au.js +0 -17
- package/dist/env-api-key-COf0U-Au.js.map +0 -1
- package/dist/environment-DrLaSsA8.js +0 -39
- package/dist/environment-DrLaSsA8.js.map +0 -1
- package/dist/environment-hBj7ngmO.js +0 -2
- package/dist/file-CVA9ocIC.js +0 -60
- package/dist/file-CVA9ocIC.js.map +0 -1
- package/dist/file-CmoKK_Pp.js +0 -2
- package/dist/file-watcher-C3Su8vXm.js +0 -123
- package/dist/file-watcher-C3Su8vXm.js.map +0 -1
- package/dist/gateway-BmjYUSua.js.map +0 -1
- package/dist/headless-ui-CUbv12Yx.js +0 -44
- package/dist/headless-ui-CUbv12Yx.js.map +0 -1
- package/dist/install-Bk5TNk27.js.map +0 -1
- package/dist/install-F4wm3RSl.js +0 -2
- package/dist/interactive-C5LNvDj6.js +0 -11
- package/dist/interactive-C5LNvDj6.js.map +0 -1
- package/dist/local-dev-McsurOC-.js +0 -135
- package/dist/local-dev-McsurOC-.js.map +0 -1
- package/dist/logging-ui-p6XKVmTx.js +0 -226
- package/dist/logging-ui-p6XKVmTx.js.map +0 -1
- package/dist/main-DKPjFHEV.js.map +0 -1
- package/dist/mcp-prompt-streaming-ljCVoQ9I.js.map +0 -1
- package/dist/mint-failure-C0HyvEwO.js +0 -6403
- package/dist/mint-failure-C0HyvEwO.js.map +0 -1
- package/dist/non-interactive-CLMJrj_7.js +0 -18
- package/dist/non-interactive-CLMJrj_7.js.map +0 -1
- package/dist/package-json--ppioh2F.js +0 -2
- package/dist/pi-B5YTBRDv.js.map +0 -1
- package/dist/playground-BLsCfHmQ.js.map +0 -1
- package/dist/posthog-B2E0hpZt.js +0 -2
- package/dist/posthog-B42rt_1S.js +0 -124
- package/dist/posthog-B42rt_1S.js.map +0 -1
- package/dist/project-data--L-WZyvj.js +0 -2
- package/dist/project-data-BO9IXn9y.js +0 -1131
- package/dist/project-data-BO9IXn9y.js.map +0 -1
- package/dist/provisioning-C01REIU2.js +0 -2
- package/dist/queue-tools-knnPQP0e.js.map +0 -1
- package/dist/registry-B3rC5U4b.js +0 -3464
- package/dist/registry-B3rC5U4b.js.map +0 -1
- package/dist/registry-BamsM7J9.js +0 -2
- package/dist/run-agent-legacy-CwUmPfQF.js +0 -2
- package/dist/run-agent-legacy-DWBajsMh.js +0 -3467
- package/dist/run-agent-legacy-DWBajsMh.js.map +0 -1
- package/dist/runners-D1PqqpjA.js +0 -834
- package/dist/runners-D1PqqpjA.js.map +0 -1
- package/dist/security-BvdSFDuM.js.map +0 -1
- package/dist/setup-utils-ChXXTi1m.js +0 -301
- package/dist/setup-utils-ChXXTi1m.js.map +0 -1
- package/dist/start-tui-DicLfgsj.js +0 -6964
- package/dist/start-tui-DicLfgsj.js.map +0 -1
- package/dist/steps-Hc28zVc_.js.map +0 -1
- package/dist/store-COCO6U0P.js +0 -5
- package/dist/store-D3509G87.js +0 -1030
- package/dist/store-D3509G87.js.map +0 -1
- package/dist/task-DiTI6Sak.js.map +0 -1
- package/dist/task-status-CmrrR7zo.js +0 -16
- package/dist/task-status-CmrrR7zo.js.map +0 -1
- package/dist/task-stream-BckhG_cB.js +0 -363
- package/dist/task-stream-BckhG_cB.js.map +0 -1
- package/dist/tasks-ChZ_F1YP.js.map +0 -1
- package/dist/terminal-PK9bCLRi.js +0 -7222
- package/dist/terminal-PK9bCLRi.js.map +0 -1
- package/dist/tools-C8LQ8QFz.js.map +0 -1
- package/dist/ui-tPNpM6vj.js +0 -15
- package/dist/ui-tPNpM6vj.js.map +0 -1
- package/dist/version-5_ydHkM6.js +0 -6
- package/dist/version-5_ydHkM6.js.map +0 -1
- package/dist/wizard-abort-BVjqLyeA.js +0 -3
- package/dist/wizard-abort-DBKtfnBR.js.map +0 -1
- package/dist/wizard-session-B7BHnay0.js +0 -2
- package/dist/wizard-session-BYw6LzpS.js +0 -133
- package/dist/wizard-session-BYw6LzpS.js.map +0 -1
- package/dist/yara-hooks-C3L6lBij.js.map +0 -1
- package/dist/yara-hooks-CF_IsoaA.js +0 -2
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { n as ErrorCodes, t as emitWizardError } from "./emit-BSetXzDV.js";
|
|
2
|
-
import "./errors-C2domSkK.js";
|
|
3
|
-
import { t as getUI } from "./ui-tPNpM6vj.js";
|
|
4
|
-
//#region src/cli/commands/basic-integration/non-interactive.ts
|
|
5
|
-
/** Print the "needs a TTY" error and exit. Used when no `--ci` flag and no TTY. */
|
|
6
|
-
function failNonInteractive() {
|
|
7
|
-
getUI().intro("PostHog Wizard");
|
|
8
|
-
getUI().log.error("This installer requires an interactive terminal (TTY) to run.\nIt appears you are running in a non-interactive environment.\nPlease run the wizard in an interactive terminal.\n\nFor CI/CD environments, use --ci mode:\n npx @posthog/wizard --ci --region us --api-key phx_xxx");
|
|
9
|
-
emitWizardError({
|
|
10
|
-
code: ErrorCodes.CliInteractiveRequired,
|
|
11
|
-
message: "This installer requires an interactive terminal (TTY) to run."
|
|
12
|
-
});
|
|
13
|
-
process.exit(1);
|
|
14
|
-
}
|
|
15
|
-
//#endregion
|
|
16
|
-
export { failNonInteractive };
|
|
17
|
-
|
|
18
|
-
//# sourceMappingURL=non-interactive-CLMJrj_7.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"non-interactive-CLMJrj_7.js","names":[],"sources":["../src/cli/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"}
|
package/dist/pi-B5YTBRDv.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pi-B5YTBRDv.js","names":[],"sources":["../src/shared/status-history.ts","../src/agent/runner/shared/progress-collector.ts","../src/agent/aio-capture.ts","../src/agent/runner/harness/pi/completion.ts","../src/agent/runner/harness/pi/cancellation.ts","../src/agent/runner/harness/pi/structured-output.ts","../src/agent/runner/harness/pi/index.ts"],"sourcesContent":["/** Shared FIFO window for agent snapshots and the terminal status panel. */\nexport const MAX_STATUS_MESSAGES = 10;\n\nexport function appendStatus(messages: string[], message: string): string[] {\n if (messages.length > 0 && messages[messages.length - 1] === message) {\n return messages;\n }\n return [...messages.slice(-(MAX_STATUS_MESSAGES - 1)), message];\n}\n","/**\n * The agent's own record of what it reported.\n *\n * `runAgent` accumulates its final `RunSnapshot` here, independently of any\n * observer, so a missing or throwing `onProgress` never makes the result\n * incomplete. The emitter wraps the caller's callback: it applies the event\n * here first, then hands a copy to the observer, and logs rather than\n * propagates anything the observer throws.\n */\n\nimport { logToFile } from '@utils/debug';\nimport { appendStatus } from '@shared/status-history';\nimport type {\n AgentProgress,\n ProgressEmitter,\n SpinnerHandle,\n} from '@agent/progress';\nimport type { RunSnapshot } from './types';\n\nexport interface ProgressCollector {\n emit: ProgressEmitter;\n snapshot(): RunSnapshot;\n}\n\nexport function createProgressCollector(\n onProgress?: (event: AgentProgress) => unknown,\n): ProgressCollector {\n const snapshot: RunSnapshot = {\n tasks: [],\n statusMessages: [],\n usage: {\n inputTokens: 0,\n outputTokens: 0,\n cacheReadTokens: 0,\n cacheCreationTokens: 0,\n },\n };\n\n const apply = (event: AgentProgress): void => {\n switch (event.kind) {\n case 'tasks':\n snapshot.tasks = event.tasks.map((t) => ({ ...t }));\n break;\n case 'status':\n snapshot.statusMessages = appendStatus(\n snapshot.statusMessages,\n event.message,\n );\n break;\n case 'stage':\n snapshot.stage = event.stage;\n break;\n case 'url':\n if (event.which === 'dashboard') snapshot.dashboardUrl = event.url;\n else snapshot.notebookUrl = event.url;\n break;\n case 'usage':\n snapshot.usage.inputTokens += event.delta.inputTokens;\n snapshot.usage.outputTokens += event.delta.outputTokens;\n snapshot.usage.cacheReadTokens += event.delta.cacheReadTokens;\n snapshot.usage.cacheCreationTokens += event.delta.cacheCreationTokens;\n break;\n case 'finalCost':\n snapshot.finalCostUsd = event.usd;\n break;\n case 'handoff':\n snapshot.handoffText = event.text;\n break;\n default:\n break;\n }\n };\n\n const emit: ProgressEmitter = (event) => {\n apply(event);\n if (!onProgress) return;\n try {\n const observed = onProgress(structuredClone(event));\n if (\n observed &&\n typeof (observed as PromiseLike<unknown>).then === 'function'\n ) {\n void Promise.resolve(observed).catch((error: unknown) => {\n try {\n logToFile(\n `[agent] progress observer rejected on ${event.kind}:`,\n error,\n );\n } catch {\n // Logging is best effort.\n }\n });\n }\n } catch (error) {\n // A broken projection is the host's problem, not the run's. Say so in\n // the log and carry on; the snapshot above is the source of truth.\n try {\n logToFile(\n `[agent] progress observer threw on ${event.kind}:`,\n error instanceof Error ? error.message : error,\n );\n } catch {\n // Logging is best effort.\n }\n }\n };\n\n return {\n emit,\n snapshot: () => ({\n ...snapshot,\n tasks: snapshot.tasks.map((t) => ({ ...t })),\n statusMessages: [...snapshot.statusMessages],\n usage: { ...snapshot.usage },\n }),\n };\n}\n\n/** The run spinner as a progress emitter. One per run, like `getUI().spinner()`. */\nexport function createEmitSpinner(emit: ProgressEmitter): SpinnerHandle {\n return {\n start: (message) => emit({ kind: 'spinner', action: 'start', message }),\n stop: (message) => emit({ kind: 'spinner', action: 'stop', message }),\n message: (message) => emit({ kind: 'spinner', action: 'message', message }),\n };\n}\n\n/** `WizardUI.log` as a progress emitter. */\nexport function createEmitLog(emit: ProgressEmitter): {\n info(message: string): void;\n warn(message: string): void;\n error(message: string): void;\n success(message: string): void;\n step(message: string): void;\n} {\n return {\n info: (message) => emit({ kind: 'log', level: 'info', message }),\n warn: (message) => emit({ kind: 'log', level: 'warn', message }),\n error: (message) => emit({ kind: 'log', level: 'error', message }),\n success: (message) => emit({ kind: 'log', level: 'success', message }),\n step: (message) => emit({ kind: 'log', level: 'step', message }),\n };\n}\n","/**\n * aio-capture — mirror wizard LLM calls into the authenticated project's\n * AI Observability tab as `$ai_generation` events. Gated on `--capture-aio`\n * (dev/test builds only); returns a no-op instance when disabled so the\n * wire-in points stay a no-op with zero overhead.\n *\n * The wizard's LLM calls happen inside subprocesses we don't own (the\n * claude-agent-sdk CLI on the anthropic path, pi's own runtime on pi), so we\n * can't wrap the client with `posthog-node`'s `wrapAnthropic`. Instead, each\n * harness surfaces assistant turns on the way back — the SDK message stream\n * on anthropic, `agentSession.subscribe(message_end)` on pi — and this module\n * composes an `$ai_generation` event from either shape.\n *\n * For the Conversation tab in AIO to render anything, each generation needs\n * `$ai_input` (the messages the model saw when it produced this turn). The\n * initial prompt is passed to the SDK subprocess and never echoed back on\n * the stream, so callers must hand it to `setInitialPrompt` before the run\n * starts. From there we track user/assistant turns as they flow through the\n * stream, snapshotting the running conversation into each generation's\n * `$ai_input` and firing `$ai_input_state` / `$ai_output_state` on the\n * terminal `$ai_trace` event.\n *\n * POSTs are fire-and-forget: failures are debug-logged and never surfaced to\n * the main agent flow. Losing an AIO event must never break a run.\n */\n\nimport { logToFile } from '@utils/debug';\nimport { VERSION } from '@shared/version';\n\n/** Conversation turn shape both harnesses normalize to. Matches Anthropic\n * message role/content conventions, which is also what AIO's Conversation\n * tab knows how to render. */\ntype Turn = { role: 'user' | 'assistant'; content: unknown };\n\n/** Common shape both harness transforms emit; fed to the shared POST. */\ntype LLMTurn = {\n provider: 'anthropic' | 'openai';\n model: string;\n /** Conversation up to (but not including) this assistant turn — the\n * messages the model saw. Sent as `$ai_input`. */\n input: Turn[];\n /** Content blocks (text + tool_use), passed through as $ai_output_choices. */\n outputChoices: unknown[];\n inputTokens?: number;\n outputTokens?: number;\n cacheReadTokens?: number;\n cacheCreationTokens?: number;\n /** Wall-clock ms since the previous assistant turn on this stream. */\n latencyMs: number;\n generationId?: string;\n isError: boolean;\n};\n\nexport type AioCapture = {\n /** Set the initial prompt the harness is about to send to the LLM. The\n * wizard passes this into the SDK subprocess out-of-band, so it never\n * appears on the return message stream — the caller must hand it to us\n * explicitly if we want `$ai_input` to include it. Safe to call multiple\n * times: latest wins, prior conversation state resets. */\n setInitialPrompt(prompt: string): void;\n /** Called for every SDK message on the anthropic harness stream. */\n captureFromAnthropicSDKMessage(msg: unknown): void;\n /** Called for every subscribe event on the pi harness. */\n captureFromPiMessageEndEvent(event: unknown): void;\n finishPiRun(isError: boolean): void;\n};\n\nconst noop = (_: unknown): void => undefined;\nconst NOOP: AioCapture = {\n setInitialPrompt: noop,\n captureFromAnthropicSDKMessage: noop,\n captureFromPiMessageEndEvent: noop,\n finishPiRun: noop,\n};\n\nexport function createAioCapture(args: {\n enabled: boolean;\n projectApiKey: string;\n apiHost: string;\n /** Trace tags from `buildRunTags` (program_id, integration, run_id, build, skill_id). */\n runTags: Record<string, string>;\n}): AioCapture {\n if (!args.enabled || !args.projectApiKey || !args.apiHost) return NOOP;\n\n const { projectApiKey, apiHost, runTags } = args;\n const distinctId = `wizard-cli-${VERSION}`;\n const captureUrl = `${apiHost.replace(/\\/$/, '')}/capture/`;\n const runStartAt = Date.now();\n // Latency is measured against the previous assistant turn on this stream —\n // a rough proxy for time-to-first-token that doesn't require SDK-internal\n // timings. Reset per createAioCapture (once per agent run).\n let prevTurnAt = runStartAt;\n // Fire the top-level `$ai_trace` event at most once per instance. Both\n // harnesses can emit terminal signals, and pi in particular may emit\n // multiple `agent_end` events across nudges — first-wins keeps trace\n // metadata stable in AIO.\n let traceEnded = false;\n\n // Running conversation state — grows as user and assistant turns flow\n // through the stream. Snapshotted into `$ai_input` on each generation.\n let initialPrompt: string | undefined;\n let conversation: Turn[] = [];\n let lastAssistantContent: unknown[] | undefined;\n\n const postEvent = (\n event: string,\n properties: Record<string, unknown>,\n ): void => {\n const body = {\n api_key: projectApiKey,\n event,\n distinct_id: distinctId,\n properties: {\n $ai_trace_id: runTags.run_id ?? '',\n ...runTags,\n ...properties,\n },\n timestamp: new Date().toISOString(),\n };\n\n // Fire-and-forget. `.then` + `.catch` (not `await`) so the caller returns\n // immediately; both branches only log. Errors must never propagate into\n // the agent stream loop.\n fetch(captureUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n })\n .then((res) => {\n if (!res.ok) {\n logToFile(`[aio-capture] POST failed status=${res.status}`);\n }\n })\n .catch((err) => {\n logToFile(\n `[aio-capture] POST error: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n });\n };\n\n const postGeneration = (turn: LLMTurn): void => {\n postEvent('$ai_generation', {\n $ai_provider: turn.provider,\n $ai_model: turn.model,\n $ai_input: turn.input,\n $ai_output_choices: turn.outputChoices,\n $ai_input_tokens: turn.inputTokens ?? 0,\n $ai_output_tokens: turn.outputTokens ?? 0,\n $ai_cache_read_input_tokens: turn.cacheReadTokens ?? 0,\n $ai_cache_creation_input_tokens: turn.cacheCreationTokens ?? 0,\n $ai_latency: turn.latencyMs / 1000,\n $ai_generation_id: turn.generationId ?? '',\n $ai_is_error: turn.isError,\n });\n };\n\n // Emit the top-level `$ai_trace` event. Without this, PostHog builds a\n // pseudo-trace from the generations — the timeline and aggregates still\n // work, but the trace has no readable name and the Conversation tab shows\n // \"No top-level trace event\". Sending this once per run fills that in,\n // and `$ai_input_state` / `$ai_output_state` populate the trace-level\n // Conversation view.\n const sendTraceEnd = (opts: { isError: boolean }): void => {\n if (traceEnded) return;\n traceEnded = true;\n postEvent('$ai_trace', {\n $ai_span_name: runTags.program_id ?? 'wizard-run',\n $ai_latency: (Date.now() - runStartAt) / 1000,\n $ai_is_error: opts.isError,\n $ai_input_state: initialPrompt\n ? [{ role: 'user', content: [{ type: 'text', text: initialPrompt }] }]\n : [],\n $ai_output_state: lastAssistantContent ?? [],\n });\n };\n\n const anthropicAssistantTurn = (msg: unknown): LLMTurn | null => {\n const m = msg as {\n type?: string;\n message?: {\n id?: string;\n model?: string;\n content?: unknown;\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n };\n };\n };\n if (m?.type !== 'assistant' || !m.message) return null;\n const now = Date.now();\n const latencyMs = now - prevTurnAt;\n prevTurnAt = now;\n return {\n provider: 'anthropic',\n model: m.message.model ?? 'unknown',\n input: [...conversation],\n outputChoices: Array.isArray(m.message.content) ? m.message.content : [],\n inputTokens: m.message.usage?.input_tokens,\n outputTokens: m.message.usage?.output_tokens,\n cacheReadTokens: m.message.usage?.cache_read_input_tokens,\n cacheCreationTokens: m.message.usage?.cache_creation_input_tokens,\n latencyMs,\n generationId: m.message.id,\n isError: false,\n };\n };\n\n const piAssistantTurn = (event: unknown): LLMTurn | null => {\n const e = event as {\n type?: string;\n message?: {\n id?: string;\n role?: string;\n model?: string;\n content?: unknown;\n stopReason?: string;\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n };\n };\n };\n // Pi emits message_end for user prompts too — filter to assistant only,\n // mirroring the existing role guard at harness/pi/index.ts:434.\n if (e?.type !== 'message_end' || e.message?.role !== 'assistant') {\n return null;\n }\n const now = Date.now();\n const latencyMs = now - prevTurnAt;\n prevTurnAt = now;\n return {\n provider: 'anthropic',\n model: e.message.model ?? 'unknown',\n input: [...conversation],\n outputChoices: Array.isArray(e.message.content) ? e.message.content : [],\n inputTokens: e.message.usage?.input_tokens,\n outputTokens: e.message.usage?.output_tokens,\n cacheReadTokens: e.message.usage?.cache_read_input_tokens,\n cacheCreationTokens: e.message.usage?.cache_creation_input_tokens,\n latencyMs,\n generationId: e.message.id,\n isError:\n e.message.stopReason === 'error' || e.message.stopReason === 'aborted',\n };\n };\n\n return {\n setInitialPrompt(prompt) {\n initialPrompt = prompt;\n // Reset conversation to the initial user turn — this is the only way\n // the initial prompt gets into `$ai_input` for the first generation,\n // since the SDK subprocess consumes it internally and doesn't echo it\n // on the return stream.\n conversation = [\n { role: 'user', content: [{ type: 'text', text: prompt }] },\n ];\n lastAssistantContent = undefined;\n },\n captureFromAnthropicSDKMessage(msg) {\n try {\n // User turns (tool_result blocks between assistant turns) accumulate\n // in the conversation so the next assistant generation carries the\n // full context the model actually saw.\n const m = msg as {\n type?: string;\n message?: { role?: string; content?: unknown };\n is_error?: boolean;\n };\n if (m?.type === 'user' && m.message) {\n conversation.push({\n role: 'user',\n content: m.message.content ?? [],\n });\n }\n const turn = anthropicAssistantTurn(msg);\n if (turn) {\n postGeneration(turn);\n // Push the assistant turn AFTER posting so the current generation's\n // $ai_input is the conversation as the model saw it (not including\n // its own response), and later turns include this one.\n conversation.push({\n role: 'assistant',\n content: turn.outputChoices,\n });\n lastAssistantContent = turn.outputChoices;\n }\n // Terminal: SDK emits a `result` message at end of run.\n if (m?.type === 'result') {\n sendTraceEnd({ isError: !!m.is_error });\n }\n } catch (err) {\n logToFile(\n `[aio-capture] anthropic compose failed: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n },\n captureFromPiMessageEndEvent(event) {\n try {\n // Pi's subscribe callback surfaces both user and assistant\n // message_end events. Accumulate user turns the same way as the\n // anthropic path so `$ai_input` matches the model's view.\n const e = event as {\n type?: string;\n message?: { role?: string; content?: unknown };\n willRetry?: boolean;\n };\n if (\n e?.type === 'message_end' &&\n e.message?.role === 'user' &&\n e.message\n ) {\n conversation.push({\n role: 'user',\n content: e.message.content ?? [],\n });\n }\n const turn = piAssistantTurn(event);\n if (turn) {\n postGeneration(turn);\n conversation.push({\n role: 'assistant',\n content: turn.outputChoices,\n });\n lastAssistantContent = turn.outputChoices;\n }\n // The harness decides whether a final turn recovered before ending the trace.\n } catch (err) {\n logToFile(\n `[aio-capture] pi compose failed: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n },\n finishPiRun(isError) {\n sendTraceEnd({ isError });\n },\n };\n}\n","import { AgentErrorType } from '@agent/signals';\n\n/** Which completion guard should fail a pi run, or undefined for a clean finish. */\nexport function completionFailure(args: {\n toolCalls: number;\n openTasks: boolean;\n}): AgentErrorType | undefined {\n // No tool call at all — the project was never touched.\n if (args.toolCalls === 0) return AgentErrorType.NO_PROGRESS;\n // Acted but left tasks in its own plan unfinished (skill install not required).\n if (args.openTasks) return AgentErrorType.INCOMPLETE_TASKS;\n return undefined;\n}\n\n/**\n * Which error type a thrown pi run reports.\n *\n * Both pi entry points classified the caught message inline with the same two\n * needles, and both did it *after* firing `agent aborted` — so the event that\n * announces the abort could not name it. Pulling the classification out lets\n * each entry point decide the type first and hand it to the event, and keeps\n * the one rule in one place.\n */\nexport function runErrorType(\n message: string,\n): AgentErrorType.RATE_LIMIT | AgentErrorType.API_ERROR {\n const lower = message.toLowerCase();\n if (lower.includes('rate limit') || lower.includes('429')) {\n return AgentErrorType.RATE_LIMIT;\n }\n return AgentErrorType.API_ERROR;\n}\n","/** Bind a host signal to Pi's abort-and-wait-for-idle operation. */\nexport function bindPiCancellation(\n signal: AbortSignal | undefined,\n session: { abort(): Promise<void> },\n onAbortError?: (error: unknown) => void,\n): { settle(): Promise<void> } {\n let abortPromise: Promise<void> | undefined;\n const onAbort = () => {\n abortPromise ??= Promise.resolve()\n .then(() => session.abort())\n .catch((error: unknown) => {\n try {\n onAbortError?.(error);\n } catch {\n /* Abort diagnostics are best effort. */\n }\n });\n };\n signal?.addEventListener('abort', onAbort, { once: true });\n if (signal?.aborted) onAbort();\n\n return {\n async settle() {\n signal?.removeEventListener('abort', onAbort);\n await abortPromise;\n },\n };\n}\n","import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\nimport type { GatewayApi } from './gateway';\n\n/** Apply the output contract at the provider boundary on every agent turn. */\nexport function structuredOutputExtension(\n schema: Record<string, unknown>,\n api: GatewayApi,\n): (pi: ExtensionAPI) => void {\n return (pi) => {\n pi.on('before_provider_request', (event) => {\n const payload = event.payload as Record<string, unknown>;\n const format = { type: 'json_schema', schema };\n switch (api) {\n case 'anthropic-messages':\n return {\n ...payload,\n output_config: { ...(payload.output_config as object), format },\n };\n case 'openai-responses':\n return {\n ...payload,\n text: {\n ...(payload.text as object),\n format: { ...format, name: 'wizard_result', strict: true },\n },\n };\n case 'openai-completions':\n // `gatewayApiFor` never routes here, so no envelope is defined for it.\n throw new Error(\n 'Structured output is not supported on Chat Completions',\n );\n }\n });\n };\n}\n","/**\n * The `pi` backend — the challenger. Drives pi.dev's coding agent\n * (`@earendil-works/pi-coding-agent`) against the PostHog LLM gateway, behind\n * `wizard-orchestrator`. It owns the agent loop and model transport; prompt\n * assembly, error routing, and the outro stay in `linear.ts`, shared with the\n * `anthropic` control.\n *\n * Transport: the gateway is registered as an `anthropic-messages` provider\n * (same protocol the claude-agent-sdk path uses), bearer auth, Bedrock-fallback\n * + wizard metadata/flag headers, model id matched to `anthropic` for a clean\n * A/B. Security parity (canUseTool + YARA) and skills/MCP discovery are\n * follow-ups (#525, #524 skills) — v1 uses pi's built-in coding tools.\n */\n\nimport fs from 'fs';\nimport path from 'path';\nimport { getLogFilePath, logToFile } from '@utils/debug';\nimport {\n Harness,\n Sequence,\n WIZARD_REMARK_EVENT_NAME,\n wizardUserAgentForProgram,\n} from '@shared/constants';\nimport { analytics } from '@utils/analytics';\nimport { AgentErrorType } from '@agent/agent-interface';\nimport { AgentSignals, REMARK_INSTRUCTION } from '@agent/signals';\nimport { AgentOutputSignals } from '@agent/output-signals';\nimport { assembleCommandments } from '../../switchboard/commandments';\nimport { gatewayAuth, type GatewayAuth } from '@agent/gateway-session';\nimport { currentAccessToken } from '@shared/oauth-session';\nimport {\n buildGatewayProvider,\n GATEWAY_PROVIDER,\n withGatewayRemint,\n} from './gateway';\nimport { createAioCapture } from '@agent/aio-capture';\nimport type {\n AgentResult,\n AgentHarness,\n BackendRunInputs,\n TaskRunInputs,\n} from '../types';\nimport type { BootstrapResult } from '@agent/runner/shared/types';\nimport type { ProgressEmitter } from '@agent/progress';\nimport { createEmitLog } from '@agent/runner/shared/progress-collector';\nimport type { TaskStore } from './tasks';\nimport type { SecurityState } from './security';\nimport { completionFailure, runErrorType } from './completion';\nimport { bindPiCancellation } from './cancellation';\nimport { structuredOutputExtension } from './structured-output';\nimport { classifyRunFailure, ErrorCodes } from '@shared/errors';\n\n/** Injects the MCP server `instructions` pi-mcp-adapter drops (project env, skill steer, tool domains) into the system prompt, falling back to a bootstrap-derived project block when the warm-connect captured none. */\nfunction piMcpContext(\n boot: BootstrapResult,\n instructions?: string,\n posthogMcp = true,\n): string {\n // No tool, no block. The fallback below names `posthog_exec`, so emitting it\n // after a failed handshake points the agent at a tool that is not registered.\n if (!posthogMcp) return '';\n if (instructions) {\n // Heading + verbatim server instructions (see PR #862 for a full sample).\n return ['', '## PostHog MCP server', instructions].join('\\n');\n }\n const project = boot.project?.name\n ? `${boot.project.name} (id ${boot.credentials.projectId})`\n : `id ${boot.credentials.projectId}`;\n // Fallback: a `## PostHog project` block with name/id, host, region.\n return [\n '',\n '## PostHog project',\n 'Your `posthog_exec` calls run against this project:',\n `- Project: ${project}`,\n `- Host: ${boot.credentials.host.apiHost}`,\n `- Region: ${boot.credentials.host.region}`,\n ].join('\\n');\n}\n\n/**\n * The ONLY environment variables pi's tool subprocesses (bash → npm/pip/…) are\n * allowed to see. Everything else — every secret (POSTHOG_PERSONAL_API_KEY,\n * ANTHROPIC_*, AWS_*), every ambient credential, the parent process's whole env\n * — is dropped before a child is spawned. pi's own gateway auth is programmatic\n * (the access token never lives in env), so a minimal env costs the agent\n * nothing while closing the leak that exposed the key before. Kept to what a\n * package manager genuinely needs to run.\n */\nconst ALLOWED_SUBPROCESS_ENV_KEYS = [\n 'PATH',\n 'HOME',\n 'SHELL',\n 'USER',\n 'LOGNAME',\n 'TMPDIR',\n 'TMP',\n 'TEMP',\n 'TERM',\n 'LANG',\n 'LC_ALL',\n 'LC_CTYPE',\n 'NODE_EXTRA_CA_CERTS',\n 'SSL_CERT_FILE',\n 'SSL_CERT_DIR',\n 'HTTP_PROXY',\n 'HTTPS_PROXY',\n 'NO_PROXY',\n 'http_proxy',\n 'https_proxy',\n 'no_proxy',\n];\n\n/** A fresh subprocess env holding only the allowlisted keys present in process.env. */\nexport function buildScrubbedEnv(): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = {};\n for (const key of ALLOWED_SUBPROCESS_ENV_KEYS) {\n const value = process.env[key];\n if (value !== undefined) env[key] = value;\n }\n return env;\n}\n\n/**\n * Tag a tool with an execution mode (mutates + returns it). Read-only tools are\n * `parallel` so a single turn that batches independent reads/searches runs them\n * at once; mutating/install tools are `sequential` so a batch never races writes\n * or concurrent installs. pi-agent-core runs a batch in parallel only when no\n * tool in it is `sequential`.\n */\nexport function withMode<T>(tool: T, mode: 'sequential' | 'parallel'): T {\n (tool as { executionMode?: 'sequential' | 'parallel' }).executionMode = mode;\n return tool;\n}\n\n/**\n * The text blocks of a pi AgentMessage (content is text/image blocks). A\n * Responses model can send several message items in one turn, commentary\n * before its answer, and each becomes its own block.\n */\nfunction textBlocks(message: unknown): string[] {\n const content = (message as { content?: unknown })?.content;\n if (typeof content === 'string') return [content];\n if (Array.isArray(content)) {\n return content\n .filter((c): c is { type: string; text: string } => {\n const block = c as { type?: string; text?: unknown };\n return block?.type === 'text' && typeof block.text === 'string';\n })\n .map((c) => c.text);\n }\n return [];\n}\n\n/** Pull plain text out of a pi AgentMessage. */\nexport function extractText(message: unknown): string {\n return textBlocks(message).join('');\n}\n\n/**\n * Surface `[DASHBOARD_URL]` / `[NOTEBOOK_URL]` markers the agent prints (after\n * the MCP creates them) into the outro link, mirroring the anthropic path's\n * signal parsing (#9). The marker carries the URL the MCP returned.\n */\nexport function applyOutroMarkers(\n textBlock: string,\n emit: ProgressEmitter,\n): void {\n const markers: Array<[string, (url: string) => void]> = [\n [\n AgentSignals.DASHBOARD_URL,\n (url) => emit({ kind: 'url', which: 'dashboard', url }),\n ],\n [\n AgentSignals.NOTEBOOK_URL,\n (url) => emit({ kind: 'url', which: 'notebook', url }),\n ],\n ];\n for (const [marker, apply] of markers) {\n const idx = textBlock.indexOf(marker);\n if (idx === -1) continue;\n const url = textBlock\n .slice(idx + marker.length)\n .trim()\n .split(/\\s/)[0];\n if (url) apply(url);\n }\n}\n\n/**\n * The text of the last `[STATUS] …` line in a block, if any. Last wins so the\n * spinner shows the most recent action when a turn prints several.\n */\nexport function lastStatusLine(textBlock: string): string | undefined {\n let status: string | undefined;\n for (const line of textBlock.split('\\n')) {\n const idx = line.indexOf(AgentSignals.STATUS);\n if (idx !== -1) {\n status = line.slice(idx + AgentSignals.STATUS.length).trim();\n }\n }\n return status || undefined;\n}\n\n/** Cap on completion-guard re-prompts while tasks remain open (see the run loop). */\nconst MAX_CONTINUE_NUDGES = 20;\n\n/** Nudge re-sent when the agent stops early with tasks still open. */\nconst CONTINUE_INSTRUCTION =\n 'You still have open tasks in your list (not all are marked `completed`). Do not stop — pick up the next `in_progress` or `pending` task and keep working until every task is `completed`. Continue now.';\n\n/** True while any task in the store is not yet `completed`. */\nfunction hasOpenTasks(store: TaskStore): boolean {\n for (const t of store.values()) if (t.status !== 'completed') return true;\n return false;\n}\n\nexport const piBackend: AgentHarness = {\n name: Harness.pi,\n\n async run(inputs: BackendRunInputs): Promise<AgentResult> {\n if (inputs.signal?.aborted) {\n return {\n kind: 'abort',\n classification: AgentErrorType.ABORT,\n message: 'Agent run cancelled',\n };\n }\n const {\n config: runConfig,\n input,\n boot,\n emit,\n prompt,\n spinner,\n structured,\n } = inputs;\n const config = runConfig.run;\n const modelId = inputs.model;\n const log = createEmitLog(emit);\n\n const capture = createAioCapture({\n enabled: input.flags.captureAio,\n projectApiKey: boot.credentials.projectApiKey,\n apiHost: boot.credentials.host.apiHost,\n runTags: boot.wizardMetadata,\n });\n\n // Init banner (parity #5).\n if (!structured) {\n log.step('Initializing Wizard agent...');\n log.step(`Verbose logs: ${getLogFilePath()}`);\n log.success(\"Agent initialized. Let's get cooking!\");\n }\n\n spinner.start(config.spinnerMessage ?? 'Customizing your PostHog setup...');\n\n // Same `agent completed`/`agent aborted` shape as anthropic.\n const startTime = Date.now();\n const signals = new AgentOutputSignals();\n let assistantTurns = 0;\n let lastAssistantText = '';\n // Tool calls across the whole run. Zero means the agent only ever produced\n // text and never acted — a no-op that leaves the project untouched.\n let toolCalls = 0;\n const runDurations = () => {\n const durationMs = Date.now() - startTime;\n return {\n duration_ms: durationMs,\n duration_seconds: Math.round(durationMs / 1000),\n };\n };\n // How this run failed: the closed AgentErrorType it is about to return.\n // Without it every terminal path below — a security termination, a no-op\n // run, a plan left open, a rate limit, a gateway error — arrived as the\n // same unlabelled event, so a run that died could be counted but not\n // diagnosed. Only two of those are errors; the rest are an enforcement\n // stop and two agent behaviours, hence \"failure mode\" over \"error\".\n //\n // Not `reason`: the linear sequence emits this same event with a `reason`\n // holding the agent's free-text [ABORT] string, and one property cannot be\n // both a closed enum and unbounded prose without making either unreadable.\n const captureAborted = (failureMode: AgentErrorType) =>\n analytics.wizardCapture('agent aborted', {\n failure_mode: failureMode,\n ...runDurations(),\n model: modelId,\n });\n const timedOutResult = (timeoutMs: number): AgentResult => {\n spinner.stop('Agent run timed out');\n captureAborted(AgentErrorType.AGENTIC_DETECTION_TIMEOUT);\n return {\n kind: 'failure',\n classification: AgentErrorType.AGENTIC_DETECTION_TIMEOUT,\n message: `Agent run timed out after ${timeoutMs / 1000}s`,\n };\n };\n\n let mcpCleanup: (() => void) | undefined;\n let aioFailed = true;\n let cancellation: ReturnType<typeof bindPiCancellation> | undefined;\n let timedOut = false;\n let timeoutAbort: Promise<void> | undefined;\n // Read by the catch path; undefined until setup creates the extension.\n let securityState: SecurityState | undefined;\n // A latched violation outranks the timer on both the success and catch paths.\n const yaraViolationResult = (): AgentResult => {\n spinner.stop('Security violation detected');\n logToFile(\n `[pi] terminated: YARA violation (blocked ${securityState?.blockedCount} call(s))`,\n );\n captureAborted(AgentErrorType.YARA_VIOLATION);\n return {\n kind: 'failure',\n classification: AgentErrorType.YARA_VIOLATION,\n };\n };\n try {\n const {\n createAgentSession,\n DefaultResourceLoader,\n SessionManager,\n AuthStorage,\n ModelRegistry,\n getAgentDir,\n createLsToolDefinition,\n createFindToolDefinition,\n createGrepToolDefinition,\n createBashToolDefinition,\n createReadToolDefinition,\n createEditToolDefinition,\n createWriteToolDefinition,\n } = await import('@earendil-works/pi-coding-agent');\n\n // the claude-agent-sdk path. The provider spec is shared with the\n // orchestrator's per-task sessions (gateway.ts). gatewayAuth mints the\n // run's scoped token.\n // Reads the live OAuth token, so a mid-run rotation re-mints on the new one.\n const refreshAuth = async () =>\n gatewayAuth(\n boot.credentials.host,\n await currentAccessToken(boot.credentials),\n boot.programId,\n );\n const auth = await refreshAuth();\n const providerInputs = (current: GatewayAuth) => ({\n gatewayUrl: current.gatewayUrl,\n accessToken: current.token,\n teamId: current.teamId,\n wizardMetadata: boot.wizardMetadata,\n wizardFlags: boot.wizardFlags,\n modelId,\n effort: inputs.thinkingLevel,\n });\n const { provider, caps, api } = buildGatewayProvider(\n providerInputs(auth),\n );\n const registry = ModelRegistry.inMemory(AuthStorage.create());\n registry.registerProvider(GATEWAY_PROVIDER, provider as never);\n\n const model = registry.find(GATEWAY_PROVIDER, modelId);\n if (!model) {\n return {\n kind: 'failure',\n classification: AgentErrorType.API_ERROR,\n message: 'pi: gateway model could not be resolved',\n };\n }\n\n // System prompt = wizard commandments. Skip project context files /\n // user extensions / skills so the run is hermetic; skills discovery is a\n // follow-up (#524).\n //\n // Fail-closed security (#525): an extension intercepts EVERY tool call —\n // built-in and custom — and reuses the anthropic policy (canUseTool\n // allowlist + .env fencing + YARA). `noExtensions: true` only suppresses\n // disk-discovered extensions; explicit `extensionFactories` still load,\n // so the fence is on while the target project can't inject its own.\n // Shared flag: true while a wizard_ask overlay is open. The ask tool\n // flips it; the security gate reads it to block Write/Edit meanwhile.\n const askState = { pending: false };\n\n const { createSecurityExtension, READ_ONLY_PI_TOOLS } = await import(\n './security'\n );\n const security = createSecurityExtension({\n readOnly: config.readOnly,\n disallowedTools: runConfig.disallowedTools,\n getWizardAskPending: () => askState.pending,\n triageProvider: boot.triageProvider,\n // Where pi's bash runs; the rm allowance is confined to this tree.\n workingDirectory: input.installDir,\n });\n securityState = security.state;\n\n // Pay warlock's WASM-init + rule-compile cost now, off the tool-call\n // path, so the first scanned call doesn't eat cold-start latency.\n const { prewarmYaraScanner } = await import('@agent/yara-hooks');\n void prewarmYaraScanner();\n\n // Wire the real PostHog MCP into pi (#10): load pi's MCP adapter and point\n // it at the hosted MCP the anthropic path uses, so dashboards/insights are\n // created through the sanctioned MCP. Best-effort — if it can't load or\n // connect, the run continues (minus the dashboard step) rather than failing\n // the whole integration. The security factory is always first.\n const extensionFactories = [security.factory] as Array<\n (pi: unknown) => void\n >;\n let mcpInstructions: string | undefined;\n // Whether the agent really got the tool. The commandments below claim\n // `posthog_exec` exists when this is true, so it must track the setup and\n // not the intent — a hardcoded `true` told the agent to call a tool the\n // failed handshake never registered. `task.ts` has always done this.\n let posthogMcp = false;\n if (!config.readOnly) {\n try {\n const { setupPostHogMcp, fetchInstructions } = await import('./mcp');\n const mcpToken = await currentAccessToken(boot.credentials);\n // The backend reads the `program:` marker off this UA to attribute what the run\n // creates (a self-driving run's warehouse sources become created_via=self_driving).\n // A plain WIZARD_USER_AGENT here records them as generic wizard work.\n const mcpUserAgent = wizardUserAgentForProgram(\n config.integrationLabel,\n );\n // Overlaps the network handshake with the adapter's jiti load.\n const instructionsPromise = fetchInstructions(\n boot.credentials.host.mcpUrl,\n mcpToken,\n mcpUserAgent,\n );\n const mcp = await setupPostHogMcp({\n mcpUrl: boot.credentials.host.mcpUrl,\n accessToken: mcpToken,\n userAgent: mcpUserAgent,\n });\n extensionFactories.push(mcp.extensionFactory);\n mcpCleanup = mcp.cleanup;\n mcpInstructions = await instructionsPromise;\n posthogMcp = true;\n } catch (err) {\n try {\n mcpCleanup?.();\n } catch {\n /* Setup cleanup is best effort. */\n }\n mcpCleanup = undefined;\n logToFile(`[pi] PostHog MCP setup skipped: ${String(err)}`);\n analytics.wizardCapture('mcp setup failed', {\n harness: 'pi',\n scope: 'run',\n error: String(err).slice(0, 300),\n });\n }\n }\n\n if (structured) {\n extensionFactories.push(\n structuredOutputExtension(structured.schema, api),\n );\n }\n\n const resourceLoader = new DefaultResourceLoader({\n cwd: input.installDir,\n agentDir: getAgentDir(),\n systemPrompt:\n assembleCommandments({\n program: runConfig.programId,\n sequence: Sequence.linear,\n harness: Harness.pi,\n caps: { bash: true, posthogMcp },\n }) +\n '\\n' +\n piMcpContext(boot, mcpInstructions, posthogMcp),\n noExtensions: true,\n noSkills: true,\n noContextFiles: true,\n noPromptTemplates: true,\n noThemes: true,\n extensionFactories,\n });\n await resourceLoader.reload();\n\n // Wizard capabilities as custom tools (pi has no MCP): skill\n // discovery/install + fenced .env edits, same names as the MCP server so\n // the shared prompt is unchanged. pi's built-in Read/Write/Edit/Bash do\n // the code changes. Loaded lazily — it pulls in typebox (ESM), which must\n // stay out of the static module graph so CommonJS unit tests can load the\n // backend seam without parsing it.\n const { createWizardPiTools } = await import('./tools');\n const { createWizardPiTaskTools } = await import('./tasks');\n const { createDispatchAgentTool } = await import('./subagent');\n // Created once so the run loop can read the store for the completion guard.\n const wizardTaskTools = createWizardPiTaskTools((tasks) =>\n emit({ kind: 'tasks', tasks }),\n );\n // The one bash the agent (and its subagents) may use: every subprocess it\n // spawns gets a scrubbed env, so no secret or ambient variable reaches an\n // `npm install`. Shared with the subagent so the lockdown is inherited.\n const scrubbedBash = withMode(\n createBashToolDefinition(input.installDir, {\n spawnHook: (ctx) => ({ ...ctx, env: buildScrubbedEnv() }),\n }),\n 'sequential',\n );\n\n const customTools = [\n // Built-ins re-registered explicitly. `noTools: 'builtin'` disables pi's\n // defaults so we can supply the env-scrubbed bash above; read/edit/write\n // are the stock definitions. Reads run in parallel so a batched turn of\n // independent reads executes at once; edit/write/bash stay sequential.\n withMode(createReadToolDefinition(input.installDir), 'parallel'),\n withMode(createEditToolDefinition(input.installDir), 'sequential'),\n withMode(createWriteToolDefinition(input.installDir), 'sequential'),\n scrubbedBash,\n // Native ls/find/grep so the agent explores with proper tools instead\n // of fence-blocked `bash {ls/find}` (the profiled retry-spirals came\n // from this gap). Parallel — exploration batches cleanly.\n withMode(createLsToolDefinition(input.installDir), 'parallel'),\n withMode(createFindToolDefinition(input.installDir), 'parallel'),\n withMode(createGrepToolDefinition(input.installDir), 'parallel'),\n ...createWizardPiTools({\n workingDirectory: input.installDir,\n skillsBaseUrl: boot.skillsBaseUrl,\n triageProvider: boot.triageProvider,\n emit,\n detectPackageManager: config.detectPackageManager,\n // The host ask bridge — lets interactive programs (self-driving) ask\n // the user through pi. Threaded from the runner, same path as the\n // anthropic harness. Absent in CI → the tool errors on call.\n askBridge: inputs.askBridge,\n maxQuestions: config.maxQuestions,\n onAskPendingChange: (pending) => {\n askState.pending = pending;\n },\n // Skip wizard_ask when the program disallows it (bare pi tool names\n // don't match the MCP-prefixed disallow list at the security gate).\n disallowedTools: runConfig.disallowedTools,\n }),\n // Task/todo tools (#526): render the todo list live in the TUI, parity\n // with the anthropic path.\n ...wizardTaskTools.tools,\n // Controlled subagent dispatch (#526): a nested fenced session with a\n // read-only toolset and no dispatch_agent of its own, so it can't\n // escape the fence or recurse.\n createDispatchAgentTool({\n model,\n modelRegistry: registry,\n cwd: input.installDir,\n agentDir: getAgentDir(),\n securityFactory: security.factory as (pi: unknown) => void,\n bashTool: scrubbedBash,\n sdk: { createAgentSession, DefaultResourceLoader, SessionManager },\n }),\n ].filter((tool) => !config.readOnly || READ_ONLY_PI_TOOLS.has(tool.name));\n\n const { session: agentSession } = await createAgentSession({\n model,\n modelRegistry: registry,\n // Reasoning effort from the switchboard capability matrix (undefined =\n // pi's default). Sent as `reasoning_effort` for openai-completions.\n thinkingLevel: caps.thinkingLevel,\n cwd: input.installDir,\n sessionManager: SessionManager.inMemory(input.installDir),\n resourceLoader,\n // Disable the default built-in tools; `customTools` re-registers\n // read/edit/write + an env-scrubbed bash, so no subprocess inherits the\n // host env. Custom + extension tools stay enabled.\n noTools: 'builtin',\n customTools,\n });\n\n // Fire the extension lifecycle — what interactive mode does via\n // rebindCurrentSession. createAgentSession builds the session but does not\n // emit session_start on its own, and the MCP adapter connects on that\n // event; without this its tools report \"MCP not initialized\".\n cancellation = bindPiCancellation(\n inputs.signal,\n agentSession,\n (error) => {\n logToFile(`[pi] abort failed: ${String(error)}`);\n },\n );\n await agentSession.bindExtensions({});\n\n // A turn that ends on a 401 from an aged bearer re-mints once and\n // continues; pi resolves the provider's apiKey per request, so\n // re-registering is enough.\n const turns = withGatewayRemint({\n signal: inputs.signal,\n session: agentSession,\n registry,\n auth,\n refreshAuth,\n providerInputs,\n continueText: CONTINUE_INSTRUCTION,\n onRemint: () => {\n logToFile('[pi] gateway token renewed after a 401; continuing');\n analytics.wizardCapture('gateway token reminted', { harness: 'pi' });\n },\n });\n\n // Map pi events onto the run spinner + the log file, mirroring the\n // anthropic path's log shape (assistant turns + tool I/O) and driving the\n // single run spinner with one stable status at a time (no overlap).\n const unsubscribe = agentSession.subscribe((event) => {\n // Mirror the turn into AIO. No-op when --capture-aio is off. Runs\n // before the role guard so the module's own filter (assistant-only)\n // stays the single source of truth for what's captured.\n capture.captureFromPiMessageEndEvent(event);\n\n switch (event.type) {\n case 'message_end': {\n // User prompts also emit message_end; only assistant turns count.\n if ((event.message as { role?: string })?.role !== 'assistant') {\n break;\n }\n assistantTurns += 1;\n turns.noteAssistantTurn(event.message);\n const blocks = textBlocks(event.message);\n const assistant = blocks.join('').trim();\n // A schema-bound answer is the turn's last block, not the joined text.\n lastAssistantText = (blocks.at(-1) ?? '').trim();\n if (structured) {\n // One block per transcript line, so recovery can parse each.\n inputs.middleware?.onMessage({\n type: 'assistant',\n message: {\n content: blocks.map((text) => ({ type: 'text', text })),\n },\n });\n }\n if (assistant) {\n logToFile(`[pi] assistant: ${assistant.slice(0, 1000)}`);\n applyOutroMarkers(assistant, emit);\n // Surface [STATUS] lines into the live spinner + status history,\n // mirroring the anthropic path — pi otherwise drops them.\n const statusText = lastStatusLine(assistant);\n if (statusText) {\n emit({ kind: 'status', message: statusText });\n spinner.message(statusText);\n }\n for (const line of assistant.split('\\n')) signals.push(line);\n }\n break;\n }\n case 'tool_execution_start': {\n toolCalls += 1;\n const args = JSON.stringify(event.args ?? {}).slice(0, 200);\n logToFile(`[pi] → ${event.toolName} ${args}`);\n if (structured) {\n inputs.middleware?.onMessage({\n type: 'assistant',\n message: {\n content: [\n {\n type: 'tool_use',\n name: event.toolName,\n input: event.args,\n },\n ],\n },\n });\n }\n // Don't surface raw tool names in the spinner — the anthropic path\n // doesn't, and it reads as noise. The Task panel (syncTodos) is the\n // visible progress, matching the anthropic presentation.\n break;\n }\n case 'tool_execution_end': {\n // Log every result in full, matching the anthropic path's\n // SDK-message logging. Call-only logs make failed runs\n // undiagnosable: a tool can fail (or return something the model\n // misreads) with no trace of what came back.\n logToFile(\n `[pi] ${event.isError ? '✗' : '←'} ${event.toolName}: ${\n typeof event.result === 'string'\n ? event.result\n : JSON.stringify(event.result ?? '')\n }`,\n );\n break;\n }\n case 'agent_end': {\n logToFile(`[pi] agent_end (willRetry=${String(event.willRetry)})`);\n break;\n }\n default:\n break;\n }\n });\n\n // Seed AIO capture with the initial prompt so the first assistant\n // turn's `$ai_input` includes it — pi's subscribe stream doesn't emit\n // a message_end for the initial prompt, only for tool_result user\n // turns that follow.\n capture.setInitialPrompt(prompt);\n\n let terminal = turns.terminalFailure();\n // A structured run's budget starts once setup is done.\n const timeout =\n structured &&\n setTimeout(() => {\n timedOut = true;\n timeoutAbort = agentSession.abort().catch((error: unknown) => {\n logToFile(`[pi] timeout abort failed: ${String(error)}`);\n });\n }, structured.timeoutMs);\n try {\n if (inputs.signal?.aborted)\n return {\n kind: 'abort',\n classification: AgentErrorType.ABORT,\n message: 'Agent run cancelled',\n };\n // Non-streaming: resolves when the agent run completes. Throws if no\n // model/api key, or on a transport error.\n await turns.prompt(prompt);\n terminal = turns.terminalFailure();\n\n // Completion guard: pi's prompt() resolves the moment the model returns\n // a turn with no tool call (e.g. a lone [STATUS] line), even mid-plan.\n // While tasks remain open and we're under the cap, nudge it to continue.\n // A schema-bound scan has no plan to finish, so it never gets nudged.\n let continueNudges = 0;\n while (\n !structured &&\n continueNudges < MAX_CONTINUE_NUDGES &&\n !security.state.criticalViolation &&\n !inputs.signal?.aborted &&\n !terminal &&\n hasOpenTasks(wizardTaskTools.store)\n ) {\n continueNudges += 1;\n logToFile(\n `[pi] completion guard: tasks still open, nudge ${continueNudges}/${MAX_CONTINUE_NUDGES}`,\n );\n await turns.prompt(CONTINUE_INSTRUCTION);\n terminal = turns.terminalFailure();\n }\n\n // Best-effort remark ask — a failed turn never fails a successful run.\n if (\n !structured &&\n !security.state.criticalViolation &&\n !terminal &&\n !inputs.signal?.aborted\n ) {\n try {\n await agentSession.prompt(REMARK_INSTRUCTION);\n } catch (err) {\n logToFile(`[pi] remark request failed: ${String(err)}`);\n }\n }\n } finally {\n if (timeout) clearTimeout(timeout);\n try {\n unsubscribe();\n } catch {\n /* Keep the terminal result. */\n }\n }\n\n if (inputs.signal?.aborted) {\n return {\n kind: 'abort',\n classification: AgentErrorType.ABORT,\n message: 'Agent run cancelled',\n };\n }\n if (timedOut && structured && !security.state.criticalViolation)\n return timedOutResult(structured.timeoutMs);\n\n if (terminal && !security.state.criticalViolation) {\n spinner.stop(\n config.errorMessage ?? `${config.integrationLabel} failed`,\n );\n captureAborted(terminal.classification);\n if (terminal.status === 401) {\n return {\n kind: 'decided_failure',\n failure: {\n code: ErrorCodes.AuthInvalidOrExpired,\n message: 'Authentication failed (401)',\n detail: { providerMessage: terminal.message },\n },\n };\n }\n return terminal.classification === AgentErrorType.ABORT\n ? {\n kind: 'abort',\n classification: AgentErrorType.ABORT,\n message: terminal.message,\n }\n : {\n kind: 'failure',\n classification: terminal.classification,\n message: terminal.message,\n };\n }\n\n // A latched post-scan violation terminates the run as a YARA violation,\n // matching the anthropic path's AgentErrorType.YARA_VIOLATION.\n if (security.state.criticalViolation) return yaraViolationResult();\n\n // pi ends a run on any tool-call-less turn, so guard against a hollow\n // success reaching the outro (nothing done, or stopped mid-plan).\n const openTasks = !structured && hasOpenTasks(wizardTaskTools.store);\n const failure = completionFailure({ toolCalls, openTasks });\n if (failure === AgentErrorType.NO_PROGRESS) {\n spinner.stop('Agent made no changes');\n logToFile(\n `[pi] no progress: ${assistantTurns} assistant turn(s), 0 tool calls`,\n );\n analytics.wizardCapture('agent no progress', {\n assistant_turns: assistantTurns,\n });\n // A schema-bound run with no tool calls produced no typed result.\n const classification = structured\n ? AgentErrorType.INVALID_STRUCTURED_OUTPUT\n : failure;\n captureAborted(classification);\n return { kind: 'failure', classification };\n }\n if (failure === AgentErrorType.INCOMPLETE_TASKS) {\n spinner.stop('Agent stopped before finishing');\n logToFile('[pi] incomplete: tasks left open');\n analytics.wizardCapture('agent incomplete tasks', { open_tasks: true });\n captureAborted(failure);\n return { kind: 'failure', classification: failure };\n }\n\n const remark = signals.remark();\n if (remark) {\n analytics.capture(WIZARD_REMARK_EVENT_NAME, { remark });\n }\n\n // A failed install_skill is non-fatal — the agent continues best-effort\n // without the skill — but every such run must be measurable.\n const skillFailure = signals.skillInstallFailure();\n if (skillFailure !== undefined) {\n analytics.wizardCapture('agent continued without skill', {\n detail: skillFailure,\n });\n }\n\n // The skill plans events into .posthog-events.json then asks to remove it\n // on completion; pi's `rm` is fence-blocked, so the agent can't — clean it\n // up host-side rather than leave a stale (often empty) artifact (#15).\n try {\n const planFile = path.join(input.installDir, '.posthog-events.json');\n if (!structured && fs.existsSync(planFile))\n await fs.promises.rm(planFile);\n } catch (err) {\n logToFile(`[pi] .posthog-events.json cleanup skipped: ${String(err)}`);\n }\n\n const stats = agentSession.getSessionStats();\n analytics.wizardCapture('agent completed', {\n ...runDurations(),\n model: modelId,\n num_turns: assistantTurns,\n // API-reported tokens only; no total_cost_usd — the API returns no\n // cost, and $ai_generation already prices the run authoritatively.\n input_tokens: stats.tokens.input,\n output_tokens: stats.tokens.output,\n cache_creation_input_tokens: stats.tokens.cacheWrite,\n cache_read_input_tokens: stats.tokens.cacheRead,\n });\n spinner.stop(config.successMessage ?? 'PostHog integration complete');\n aioFailed = false;\n if (!structured) return { kind: 'success' };\n try {\n return {\n kind: 'success',\n structuredOutput: JSON.parse(lastAssistantText),\n };\n } catch {\n // The caller validates the result and owns its bounded retry.\n return { kind: 'success' };\n }\n } catch (err) {\n if (inputs.signal?.aborted) {\n return {\n kind: 'abort',\n classification: AgentErrorType.ABORT,\n message: 'Agent run cancelled',\n };\n }\n if (securityState?.criticalViolation) return yaraViolationResult();\n if (timedOut && structured) return timedOutResult(structured.timeoutMs);\n const message = err instanceof Error ? err.message : String(err);\n logToFile(`[pi] run error: ${message}`);\n spinner.stop(config.errorMessage ?? `${config.integrationLabel} failed`);\n log.error(`pi backend error: ${message}`);\n const coded = classifyRunFailure(err);\n if (coded.coded && err instanceof Error) {\n captureAborted(AgentErrorType.API_ERROR);\n return {\n kind: 'decided_failure',\n failure: { code: coded.code, message: coded.message, error: err },\n };\n }\n const classification = runErrorType(message);\n captureAborted(classification);\n return {\n kind: 'failure',\n classification,\n message,\n error: err instanceof Error ? err : undefined,\n };\n } finally {\n await cancellation?.settle();\n await timeoutAbort;\n try {\n mcpCleanup?.();\n } catch {\n /* Keep the terminal result. */\n }\n try {\n capture.finishPiRun(aioFailed);\n } catch {\n /* Telemetry is best effort. */\n }\n }\n },\n\n // Orchestrator mode: one fresh pi session per seed plan / drained task, with\n // the in-process queue tools registered as pi custom tools. Lazily imported —\n // task.ts pulls in typebox (ESM), which must stay out of the static module\n // graph so CommonJS unit tests can load the backend seam without parsing it.\n async runTask(inputs: TaskRunInputs): Promise<AgentResult> {\n const { runPiTask } = await import('./task');\n return runPiTask(inputs);\n },\n};\n"],"mappings":";;;;;;;;;;;AAGA,SAAgB,aAAa,UAAoB,SAA2B;AAC1E,KAAI,SAAS,SAAS,KAAK,SAAS,SAAS,SAAS,OAAO,QAC3D,QAAO;AAET,QAAO,CAAC,GAAG,SAAS,MAAM,GAA2B,EAAE,QAAQ;;;;;;;;;;;;;ACiBjE,SAAgB,wBACd,YACmB;CACnB,MAAM,WAAwB;EAC5B,OAAO,EAAE;EACT,gBAAgB,EAAE;EAClB,OAAO;GACL,aAAa;GACb,cAAc;GACd,iBAAiB;GACjB,qBAAqB;GACtB;EACF;CAED,MAAM,SAAS,UAA+B;AAC5C,UAAQ,MAAM,MAAd;GACE,KAAK;AACH,aAAS,QAAQ,MAAM,MAAM,KAAK,OAAO,EAAE,GAAG,GAAG,EAAE;AACnD;GACF,KAAK;AACH,aAAS,iBAAiB,aACxB,SAAS,gBACT,MAAM,QACP;AACD;GACF,KAAK;AACH,aAAS,QAAQ,MAAM;AACvB;GACF,KAAK;AACH,QAAI,MAAM,UAAU,YAAa,UAAS,eAAe,MAAM;QAC1D,UAAS,cAAc,MAAM;AAClC;GACF,KAAK;AACH,aAAS,MAAM,eAAe,MAAM,MAAM;AAC1C,aAAS,MAAM,gBAAgB,MAAM,MAAM;AAC3C,aAAS,MAAM,mBAAmB,MAAM,MAAM;AAC9C,aAAS,MAAM,uBAAuB,MAAM,MAAM;AAClD;GACF,KAAK;AACH,aAAS,eAAe,MAAM;AAC9B;GACF,KAAK;AACH,aAAS,cAAc,MAAM;AAC7B;GACF,QACE;;;CAIN,MAAM,QAAyB,UAAU;AACvC,QAAM,MAAM;AACZ,MAAI,CAAC,WAAY;AACjB,MAAI;GACF,MAAM,WAAW,WAAW,gBAAgB,MAAM,CAAC;AACnD,OACE,YACA,OAAQ,SAAkC,SAAS,WAE9C,SAAQ,QAAQ,SAAS,CAAC,OAAO,UAAmB;AACvD,QAAI;AACF,eACE,yCAAyC,MAAM,KAAK,IACpD,MACD;YACK;KAGR;WAEG,OAAO;AAGd,OAAI;AACF,cACE,sCAAsC,MAAM,KAAK,IACjD,iBAAiB,QAAQ,MAAM,UAAU,MAC1C;WACK;;;AAMZ,QAAO;EACL;EACA,iBAAiB;GACf,GAAG;GACH,OAAO,SAAS,MAAM,KAAK,OAAO,EAAE,GAAG,GAAG,EAAE;GAC5C,gBAAgB,CAAC,GAAG,SAAS,eAAe;GAC5C,OAAO,EAAE,GAAG,SAAS,OAAO;GAC7B;EACF;;;AAIH,SAAgB,kBAAkB,MAAsC;AACtE,QAAO;EACL,QAAQ,YAAY,KAAK;GAAE,MAAM;GAAW,QAAQ;GAAS;GAAS,CAAC;EACvE,OAAO,YAAY,KAAK;GAAE,MAAM;GAAW,QAAQ;GAAQ;GAAS,CAAC;EACrE,UAAU,YAAY,KAAK;GAAE,MAAM;GAAW,QAAQ;GAAW;GAAS,CAAC;EAC5E;;;AAIH,SAAgB,cAAc,MAM5B;AACA,QAAO;EACL,OAAO,YAAY,KAAK;GAAE,MAAM;GAAO,OAAO;GAAQ;GAAS,CAAC;EAChE,OAAO,YAAY,KAAK;GAAE,MAAM;GAAO,OAAO;GAAQ;GAAS,CAAC;EAChE,QAAQ,YAAY,KAAK;GAAE,MAAM;GAAO,OAAO;GAAS;GAAS,CAAC;EAClE,UAAU,YAAY,KAAK;GAAE,MAAM;GAAO,OAAO;GAAW;GAAS,CAAC;EACtE,OAAO,YAAY,KAAK;GAAE,MAAM;GAAO,OAAO;GAAQ;GAAS,CAAC;EACjE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC1EH,MAAM,QAAQ,MAAqB,KAAA;AACnC,MAAM,OAAmB;CACvB,kBAAkB;CAClB,gCAAgC;CAChC,8BAA8B;CAC9B,aAAa;CACd;AAED,SAAgB,iBAAiB,MAMlB;AACb,KAAI,CAAC,KAAK,WAAW,CAAC,KAAK,iBAAiB,CAAC,KAAK,QAAS,QAAO;CAElE,MAAM,EAAE,eAAe,SAAS,YAAY;CAC5C,MAAM,aAAa,cAAc;CACjC,MAAM,aAAa,GAAG,QAAQ,QAAQ,OAAO,GAAG,CAAC;CACjD,MAAM,aAAa,KAAK,KAAK;CAI7B,IAAI,aAAa;CAKjB,IAAI,aAAa;CAIjB,IAAI;CACJ,IAAI,eAAuB,EAAE;CAC7B,IAAI;CAEJ,MAAM,aACJ,OACA,eACS;EACT,MAAM,OAAO;GACX,SAAS;GACT;GACA,aAAa;GACb,YAAY;IACV,cAAc,QAAQ,UAAU;IAChC,GAAG;IACH,GAAG;IACJ;GACD,4BAAW,IAAI,MAAM,EAAC,aAAa;GACpC;AAKD,QAAM,YAAY;GAChB,QAAQ;GACR,SAAS,EAAE,gBAAgB,oBAAoB;GAC/C,MAAM,KAAK,UAAU,KAAK;GAC3B,CAAC,CACC,MAAM,QAAQ;AACb,OAAI,CAAC,IAAI,GACP,WAAU,oCAAoC,IAAI,SAAS;IAE7D,CACD,OAAO,QAAQ;AACd,aACE,6BACE,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAEnD;IACD;;CAGN,MAAM,kBAAkB,SAAwB;AAC9C,YAAU,kBAAkB;GAC1B,cAAc,KAAK;GACnB,WAAW,KAAK;GAChB,WAAW,KAAK;GAChB,oBAAoB,KAAK;GACzB,kBAAkB,KAAK,eAAe;GACtC,mBAAmB,KAAK,gBAAgB;GACxC,6BAA6B,KAAK,mBAAmB;GACrD,iCAAiC,KAAK,uBAAuB;GAC7D,aAAa,KAAK,YAAY;GAC9B,mBAAmB,KAAK,gBAAgB;GACxC,cAAc,KAAK;GACpB,CAAC;;CASJ,MAAM,gBAAgB,SAAqC;AACzD,MAAI,WAAY;AAChB,eAAa;AACb,YAAU,aAAa;GACrB,eAAe,QAAQ,cAAc;GACrC,cAAc,KAAK,KAAK,GAAG,cAAc;GACzC,cAAc,KAAK;GACnB,iBAAiB,gBACb,CAAC;IAAE,MAAM;IAAQ,SAAS,CAAC;KAAE,MAAM;KAAQ,MAAM;KAAe,CAAC;IAAE,CAAC,GACpE,EAAE;GACN,kBAAkB,wBAAwB,EAAE;GAC7C,CAAC;;CAGJ,MAAM,0BAA0B,QAAiC;EAC/D,MAAM,IAAI;AAcV,MAAI,GAAG,SAAS,eAAe,CAAC,EAAE,QAAS,QAAO;EAClD,MAAM,MAAM,KAAK,KAAK;EACtB,MAAM,YAAY,MAAM;AACxB,eAAa;AACb,SAAO;GACL,UAAU;GACV,OAAO,EAAE,QAAQ,SAAS;GAC1B,OAAO,CAAC,GAAG,aAAa;GACxB,eAAe,MAAM,QAAQ,EAAE,QAAQ,QAAQ,GAAG,EAAE,QAAQ,UAAU,EAAE;GACxE,aAAa,EAAE,QAAQ,OAAO;GAC9B,cAAc,EAAE,QAAQ,OAAO;GAC/B,iBAAiB,EAAE,QAAQ,OAAO;GAClC,qBAAqB,EAAE,QAAQ,OAAO;GACtC;GACA,cAAc,EAAE,QAAQ;GACxB,SAAS;GACV;;CAGH,MAAM,mBAAmB,UAAmC;EAC1D,MAAM,IAAI;AAkBV,MAAI,GAAG,SAAS,iBAAiB,EAAE,SAAS,SAAS,YACnD,QAAO;EAET,MAAM,MAAM,KAAK,KAAK;EACtB,MAAM,YAAY,MAAM;AACxB,eAAa;AACb,SAAO;GACL,UAAU;GACV,OAAO,EAAE,QAAQ,SAAS;GAC1B,OAAO,CAAC,GAAG,aAAa;GACxB,eAAe,MAAM,QAAQ,EAAE,QAAQ,QAAQ,GAAG,EAAE,QAAQ,UAAU,EAAE;GACxE,aAAa,EAAE,QAAQ,OAAO;GAC9B,cAAc,EAAE,QAAQ,OAAO;GAC/B,iBAAiB,EAAE,QAAQ,OAAO;GAClC,qBAAqB,EAAE,QAAQ,OAAO;GACtC;GACA,cAAc,EAAE,QAAQ;GACxB,SACE,EAAE,QAAQ,eAAe,WAAW,EAAE,QAAQ,eAAe;GAChE;;AAGH,QAAO;EACL,iBAAiB,QAAQ;AACvB,mBAAgB;AAKhB,kBAAe,CACb;IAAE,MAAM;IAAQ,SAAS,CAAC;KAAE,MAAM;KAAQ,MAAM;KAAQ,CAAC;IAAE,CAC5D;AACD,0BAAuB,KAAA;;EAEzB,+BAA+B,KAAK;AAClC,OAAI;IAIF,MAAM,IAAI;AAKV,QAAI,GAAG,SAAS,UAAU,EAAE,QAC1B,cAAa,KAAK;KAChB,MAAM;KACN,SAAS,EAAE,QAAQ,WAAW,EAAE;KACjC,CAAC;IAEJ,MAAM,OAAO,uBAAuB,IAAI;AACxC,QAAI,MAAM;AACR,oBAAe,KAAK;AAIpB,kBAAa,KAAK;MAChB,MAAM;MACN,SAAS,KAAK;MACf,CAAC;AACF,4BAAuB,KAAK;;AAG9B,QAAI,GAAG,SAAS,SACd,cAAa,EAAE,SAAS,CAAC,CAAC,EAAE,UAAU,CAAC;YAElC,KAAK;AACZ,cACE,2CACE,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAEnD;;;EAGL,6BAA6B,OAAO;AAClC,OAAI;IAIF,MAAM,IAAI;AAKV,QACE,GAAG,SAAS,iBACZ,EAAE,SAAS,SAAS,UACpB,EAAE,QAEF,cAAa,KAAK;KAChB,MAAM;KACN,SAAS,EAAE,QAAQ,WAAW,EAAE;KACjC,CAAC;IAEJ,MAAM,OAAO,gBAAgB,MAAM;AACnC,QAAI,MAAM;AACR,oBAAe,KAAK;AACpB,kBAAa,KAAK;MAChB,MAAM;MACN,SAAS,KAAK;MACf,CAAC;AACF,4BAAuB,KAAK;;YAGvB,KAAK;AACZ,cACE,oCACE,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAEnD;;;EAGL,YAAY,SAAS;AACnB,gBAAa,EAAE,SAAS,CAAC;;EAE5B;;;;;ACvVH,SAAgB,kBAAkB,MAGH;AAE7B,KAAI,KAAK,cAAc,EAAG,QAAA;AAE1B,KAAI,KAAK,UAAW,QAAA;;;;;;;;;;;AAatB,SAAgB,aACd,SACsD;CACtD,MAAM,QAAQ,QAAQ,aAAa;AACnC,KAAI,MAAM,SAAS,aAAa,IAAI,MAAM,SAAS,MAAM,CACvD,QAAA;AAEF,QAAA;;;;;AC7BF,SAAgB,mBACd,QACA,SACA,cAC6B;CAC7B,IAAI;CACJ,MAAM,gBAAgB;AACpB,mBAAiB,QAAQ,SAAS,CAC/B,WAAW,QAAQ,OAAO,CAAC,CAC3B,OAAO,UAAmB;AACzB,OAAI;AACF,mBAAe,MAAM;WACf;IAGR;;AAEN,SAAQ,iBAAiB,SAAS,SAAS,EAAE,MAAM,MAAM,CAAC;AAC1D,KAAI,QAAQ,QAAS,UAAS;AAE9B,QAAO,EACL,MAAM,SAAS;AACb,UAAQ,oBAAoB,SAAS,QAAQ;AAC7C,QAAM;IAET;;;;;ACtBH,SAAgB,0BACd,QACA,KAC4B;AAC5B,SAAQ,OAAO;AACb,KAAG,GAAG,4BAA4B,UAAU;GAC1C,MAAM,UAAU,MAAM;GACtB,MAAM,SAAS;IAAE,MAAM;IAAe;IAAQ;AAC9C,WAAQ,KAAR;IACE,KAAK,qBACH,QAAO;KACL,GAAG;KACH,eAAe;MAAE,GAAI,QAAQ;MAA0B;MAAQ;KAChE;IACH,KAAK,mBACH,QAAO;KACL,GAAG;KACH,MAAM;MACJ,GAAI,QAAQ;MACZ,QAAQ;OAAE,GAAG;OAAQ,MAAM;OAAiB,QAAQ;OAAM;MAC3D;KACF;IACH,KAAK,qBAEH,OAAM,IAAI,MACR,yDACD;;IAEL;;;;;;;;;;;;;;;;;;;ACqBN,SAAS,aACP,MACA,cACA,aAAa,MACL;AAGR,KAAI,CAAC,WAAY,QAAO;AACxB,KAAI,aAEF,QAAO;EAAC;EAAI;EAAyB;EAAa,CAAC,KAAK,KAAK;AAM/D,QAAO;EACL;EACA;EACA;EACA,cARc,KAAK,SAAS,OAC1B,GAAG,KAAK,QAAQ,KAAK,OAAO,KAAK,YAAY,UAAU,KACvD,MAAM,KAAK,YAAY;EAOzB,WAAW,KAAK,YAAY,KAAK;EACjC,aAAa,KAAK,YAAY,KAAK;EACpC,CAAC,KAAK,KAAK;;;;;;;;;;;AAYd,MAAM,8BAA8B;CAClC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;AAGD,SAAgB,mBAAsC;CACpD,MAAM,MAAyB,EAAE;AACjC,MAAK,MAAM,OAAO,6BAA6B;EAC7C,MAAM,QAAQ,QAAQ,IAAI;AAC1B,MAAI,UAAU,KAAA,EAAW,KAAI,OAAO;;AAEtC,QAAO;;;;;;;;;AAUT,SAAgB,SAAY,MAAS,MAAoC;AACtE,MAAuD,gBAAgB;AACxE,QAAO;;;;;;;AAQT,SAAS,WAAW,SAA4B;CAC9C,MAAM,UAAW,SAAmC;AACpD,KAAI,OAAO,YAAY,SAAU,QAAO,CAAC,QAAQ;AACjD,KAAI,MAAM,QAAQ,QAAQ,CACxB,QAAO,QACJ,QAAQ,MAA2C;EAClD,MAAM,QAAQ;AACd,SAAO,OAAO,SAAS,UAAU,OAAO,MAAM,SAAS;GACvD,CACD,KAAK,MAAM,EAAE,KAAK;AAEvB,QAAO,EAAE;;;AAIX,SAAgB,YAAY,SAA0B;AACpD,QAAO,WAAW,QAAQ,CAAC,KAAK,GAAG;;;;;;;AAQrC,SAAgB,kBACd,WACA,MACM;CACN,MAAM,UAAkD,CACtD,CACE,aAAa,gBACZ,QAAQ,KAAK;EAAE,MAAM;EAAO,OAAO;EAAa;EAAK,CAAC,CACxD,EACD,CACE,aAAa,eACZ,QAAQ,KAAK;EAAE,MAAM;EAAO,OAAO;EAAY;EAAK,CAAC,CACvD,CACF;AACD,MAAK,MAAM,CAAC,QAAQ,UAAU,SAAS;EACrC,MAAM,MAAM,UAAU,QAAQ,OAAO;AACrC,MAAI,QAAQ,GAAI;EAChB,MAAM,MAAM,UACT,MAAM,MAAM,OAAO,OAAO,CAC1B,MAAM,CACN,MAAM,KAAK,CAAC;AACf,MAAI,IAAK,OAAM,IAAI;;;;;;;AAQvB,SAAgB,eAAe,WAAuC;CACpE,IAAI;AACJ,MAAK,MAAM,QAAQ,UAAU,MAAM,KAAK,EAAE;EACxC,MAAM,MAAM,KAAK,QAAQ,aAAa,OAAO;AAC7C,MAAI,QAAQ,GACV,UAAS,KAAK,MAAM,MAAM,aAAa,OAAO,OAAO,CAAC,MAAM;;AAGhE,QAAO,UAAU,KAAA;;;AAInB,MAAM,sBAAsB;;AAG5B,MAAM,uBACJ;;AAGF,SAAS,aAAa,OAA2B;AAC/C,MAAK,MAAM,KAAK,MAAM,QAAQ,CAAE,KAAI,EAAE,WAAW,YAAa,QAAO;AACrE,QAAO;;AAGT,MAAa,YAA0B;CACrC,MAAA;CAEA,MAAM,IAAI,QAAgD;AACxD,MAAI,OAAO,QAAQ,QACjB,QAAO;GACL,MAAM;GACN,gBAAA;GACA,SAAS;GACV;EAEH,MAAM,EACJ,QAAQ,WACR,OACA,MACA,MACA,QACA,SACA,eACE;EACJ,MAAM,SAAS,UAAU;EACzB,MAAM,UAAU,OAAO;EACvB,MAAM,MAAM,cAAc,KAAK;EAE/B,MAAM,UAAU,iBAAiB;GAC/B,SAAS,MAAM,MAAM;GACrB,eAAe,KAAK,YAAY;GAChC,SAAS,KAAK,YAAY,KAAK;GAC/B,SAAS,KAAK;GACf,CAAC;AAGF,MAAI,CAAC,YAAY;AACf,OAAI,KAAK,+BAA+B;AACxC,OAAI,KAAK,iBAAiB,gBAAgB,GAAG;AAC7C,OAAI,QAAQ,wCAAwC;;AAGtD,UAAQ,MAAM,OAAO,kBAAkB,oCAAoC;EAG3E,MAAM,YAAY,KAAK,KAAK;EAC5B,MAAM,UAAU,IAAI,oBAAoB;EACxC,IAAI,iBAAiB;EACrB,IAAI,oBAAoB;EAGxB,IAAI,YAAY;EAChB,MAAM,qBAAqB;GACzB,MAAM,aAAa,KAAK,KAAK,GAAG;AAChC,UAAO;IACL,aAAa;IACb,kBAAkB,KAAK,MAAM,aAAa,IAAK;IAChD;;EAYH,MAAM,kBAAkB,gBACtB,UAAU,cAAc,iBAAiB;GACvC,cAAc;GACd,GAAG,cAAc;GACjB,OAAO;GACR,CAAC;EACJ,MAAM,kBAAkB,cAAmC;AACzD,WAAQ,KAAK,sBAAsB;AACnC,kBAAA,mCAAwD;AACxD,UAAO;IACL,MAAM;IACN,gBAAA;IACA,SAAS,6BAA6B,YAAY,IAAK;IACxD;;EAGH,IAAI;EACJ,IAAI,YAAY;EAChB,IAAI;EACJ,IAAI,WAAW;EACf,IAAI;EAEJ,IAAI;EAEJ,MAAM,4BAAyC;AAC7C,WAAQ,KAAK,8BAA8B;AAC3C,aACE,4CAA4C,eAAe,aAAa,WACzE;AACD,kBAAA,wBAA6C;AAC7C,UAAO;IACL,MAAM;IACN,gBAAA;IACD;;AAEH,MAAI;GACF,MAAM,EACJ,oBACA,uBACA,gBACA,aACA,eACA,aACA,wBACA,0BACA,0BACA,0BACA,0BACA,0BACA,8BACE,MAAM,OAAO;GAMjB,MAAM,cAAc,YAClB,YACE,KAAK,YAAY,MACjB,MAAM,mBAAmB,KAAK,YAAY,EAC1C,KAAK,UACN;GACH,MAAM,OAAO,MAAM,aAAa;GAChC,MAAM,kBAAkB,aAA0B;IAChD,YAAY,QAAQ;IACpB,aAAa,QAAQ;IACrB,QAAQ,QAAQ;IAChB,gBAAgB,KAAK;IACrB,aAAa,KAAK;IAClB;IACA,QAAQ,OAAO;IAChB;GACD,MAAM,EAAE,UAAU,MAAM,QAAQ,qBAC9B,eAAe,KAAK,CACrB;GACD,MAAM,WAAW,cAAc,SAAS,YAAY,QAAQ,CAAC;AAC7D,YAAS,iBAAiB,kBAAkB,SAAkB;GAE9D,MAAM,QAAQ,SAAS,KAAK,kBAAkB,QAAQ;AACtD,OAAI,CAAC,MACH,QAAO;IACL,MAAM;IACN,gBAAA;IACA,SAAS;IACV;GAcH,MAAM,WAAW,EAAE,SAAS,OAAO;GAEnC,MAAM,EAAE,yBAAyB,uBAAuB,MAAM,OAC5D;GAEF,MAAM,WAAW,wBAAwB;IACvC,UAAU,OAAO;IACjB,iBAAiB,UAAU;IAC3B,2BAA2B,SAAS;IACpC,gBAAgB,KAAK;IAErB,kBAAkB,MAAM;IACzB,CAAC;AACF,mBAAgB,SAAS;GAIzB,MAAM,EAAE,uBAAuB,MAAM,OAAO;AACvC,uBAAoB;GAOzB,MAAM,qBAAqB,CAAC,SAAS,QAAQ;GAG7C,IAAI;GAKJ,IAAI,aAAa;AACjB,OAAI,CAAC,OAAO,SACV,KAAI;IACF,MAAM,EAAE,iBAAiB,sBAAsB,MAAM,OAAO;IAC5D,MAAM,WAAW,MAAM,mBAAmB,KAAK,YAAY;IAI3D,MAAM,eAAe,0BACnB,OAAO,iBACR;IAED,MAAM,sBAAsB,kBAC1B,KAAK,YAAY,KAAK,QACtB,UACA,aACD;IACD,MAAM,MAAM,MAAM,gBAAgB;KAChC,QAAQ,KAAK,YAAY,KAAK;KAC9B,aAAa;KACb,WAAW;KACZ,CAAC;AACF,uBAAmB,KAAK,IAAI,iBAAiB;AAC7C,iBAAa,IAAI;AACjB,sBAAkB,MAAM;AACxB,iBAAa;YACN,KAAK;AACZ,QAAI;AACF,mBAAc;YACR;AAGR,iBAAa,KAAA;AACb,cAAU,mCAAmC,OAAO,IAAI,GAAG;AAC3D,cAAU,cAAc,oBAAoB;KAC1C,SAAS;KACT,OAAO;KACP,OAAO,OAAO,IAAI,CAAC,MAAM,GAAG,IAAI;KACjC,CAAC;;AAIN,OAAI,WACF,oBAAmB,KACjB,0BAA0B,WAAW,QAAQ,IAAI,CAClD;GAGH,MAAM,iBAAiB,IAAI,sBAAsB;IAC/C,KAAK,MAAM;IACX,UAAU,aAAa;IACvB,cACE,qBAAqB;KACnB,SAAS,UAAU;KACnB,UAAA;KACA,SAAA;KACA,MAAM;MAAE,MAAM;MAAM;MAAY;KACjC,CAAC,GACF,OACA,aAAa,MAAM,iBAAiB,WAAW;IACjD,cAAc;IACd,UAAU;IACV,gBAAgB;IAChB,mBAAmB;IACnB,UAAU;IACV;IACD,CAAC;AACF,SAAM,eAAe,QAAQ;GAQ7B,MAAM,EAAE,wBAAwB,MAAM,OAAO;GAC7C,MAAM,EAAE,4BAA4B,MAAM,OAAO;GACjD,MAAM,EAAE,4BAA4B,MAAM,OAAO;GAEjD,MAAM,kBAAkB,yBAAyB,UAC/C,KAAK;IAAE,MAAM;IAAS;IAAO,CAAC,CAC/B;GAID,MAAM,eAAe,SACnB,yBAAyB,MAAM,YAAY,EACzC,YAAY,SAAS;IAAE,GAAG;IAAK,KAAK,kBAAkB;IAAE,GACzD,CAAC,EACF,aACD;GAED,MAAM,cAAc;IAKlB,SAAS,yBAAyB,MAAM,WAAW,EAAE,WAAW;IAChE,SAAS,yBAAyB,MAAM,WAAW,EAAE,aAAa;IAClE,SAAS,0BAA0B,MAAM,WAAW,EAAE,aAAa;IACnE;IAIA,SAAS,uBAAuB,MAAM,WAAW,EAAE,WAAW;IAC9D,SAAS,yBAAyB,MAAM,WAAW,EAAE,WAAW;IAChE,SAAS,yBAAyB,MAAM,WAAW,EAAE,WAAW;IAChE,GAAG,oBAAoB;KACrB,kBAAkB,MAAM;KACxB,eAAe,KAAK;KACpB,gBAAgB,KAAK;KACrB;KACA,sBAAsB,OAAO;KAI7B,WAAW,OAAO;KAClB,cAAc,OAAO;KACrB,qBAAqB,YAAY;AAC/B,eAAS,UAAU;;KAIrB,iBAAiB,UAAU;KAC5B,CAAC;IAGF,GAAG,gBAAgB;IAInB,wBAAwB;KACtB;KACA,eAAe;KACf,KAAK,MAAM;KACX,UAAU,aAAa;KACvB,iBAAiB,SAAS;KAC1B,UAAU;KACV,KAAK;MAAE;MAAoB;MAAuB;MAAgB;KACnE,CAAC;IACH,CAAC,QAAQ,SAAS,CAAC,OAAO,YAAY,mBAAmB,IAAI,KAAK,KAAK,CAAC;GAEzE,MAAM,EAAE,SAAS,iBAAiB,MAAM,mBAAmB;IACzD;IACA,eAAe;IAGf,eAAe,KAAK;IACpB,KAAK,MAAM;IACX,gBAAgB,eAAe,SAAS,MAAM,WAAW;IACzD;IAIA,SAAS;IACT;IACD,CAAC;AAMF,kBAAe,mBACb,OAAO,QACP,eACC,UAAU;AACT,cAAU,sBAAsB,OAAO,MAAM,GAAG;KAEnD;AACD,SAAM,aAAa,eAAe,EAAE,CAAC;GAKrC,MAAM,QAAQ,kBAAkB;IAC9B,QAAQ,OAAO;IACf,SAAS;IACT;IACA;IACA;IACA;IACA,cAAc;IACd,gBAAgB;AACd,eAAU,qDAAqD;AAC/D,eAAU,cAAc,0BAA0B,EAAE,SAAS,MAAM,CAAC;;IAEvE,CAAC;GAKF,MAAM,cAAc,aAAa,WAAW,UAAU;AAIpD,YAAQ,6BAA6B,MAAM;AAE3C,YAAQ,MAAM,MAAd;KACE,KAAK,eAAe;AAElB,UAAK,MAAM,SAA+B,SAAS,YACjD;AAEF,wBAAkB;AAClB,YAAM,kBAAkB,MAAM,QAAQ;MACtC,MAAM,SAAS,WAAW,MAAM,QAAQ;MACxC,MAAM,YAAY,OAAO,KAAK,GAAG,CAAC,MAAM;AAExC,2BAAqB,OAAO,GAAG,GAAG,IAAI,IAAI,MAAM;AAChD,UAAI,WAEF,QAAO,YAAY,UAAU;OAC3B,MAAM;OACN,SAAS,EACP,SAAS,OAAO,KAAK,UAAU;QAAE,MAAM;QAAQ;QAAM,EAAE,EACxD;OACF,CAAC;AAEJ,UAAI,WAAW;AACb,iBAAU,mBAAmB,UAAU,MAAM,GAAG,IAAK,GAAG;AACxD,yBAAkB,WAAW,KAAK;OAGlC,MAAM,aAAa,eAAe,UAAU;AAC5C,WAAI,YAAY;AACd,aAAK;SAAE,MAAM;SAAU,SAAS;SAAY,CAAC;AAC7C,gBAAQ,QAAQ,WAAW;;AAE7B,YAAK,MAAM,QAAQ,UAAU,MAAM,KAAK,CAAE,SAAQ,KAAK,KAAK;;AAE9D;;KAEF,KAAK,wBAAwB;AAC3B,mBAAa;MACb,MAAM,OAAO,KAAK,UAAU,MAAM,QAAQ,EAAE,CAAC,CAAC,MAAM,GAAG,IAAI;AAC3D,gBAAU,UAAU,MAAM,SAAS,GAAG,OAAO;AAC7C,UAAI,WACF,QAAO,YAAY,UAAU;OAC3B,MAAM;OACN,SAAS,EACP,SAAS,CACP;QACE,MAAM;QACN,MAAM,MAAM;QACZ,OAAO,MAAM;QACd,CACF,EACF;OACF,CAAC;AAKJ;;KAEF,KAAK;AAKH,gBACE,QAAQ,MAAM,UAAU,MAAM,IAAI,GAAG,MAAM,SAAS,IAClD,OAAO,MAAM,WAAW,WACpB,MAAM,SACN,KAAK,UAAU,MAAM,UAAU,GAAG,GAEzC;AACD;KAEF,KAAK;AACH,gBAAU,6BAA6B,OAAO,MAAM,UAAU,CAAC,GAAG;AAClE;KAEF,QACE;;KAEJ;AAMF,WAAQ,iBAAiB,OAAO;GAEhC,IAAI,WAAW,MAAM,iBAAiB;GAEtC,MAAM,UACJ,cACA,iBAAiB;AACf,eAAW;AACX,mBAAe,aAAa,OAAO,CAAC,OAAO,UAAmB;AAC5D,eAAU,8BAA8B,OAAO,MAAM,GAAG;MACxD;MACD,WAAW,UAAU;AAC1B,OAAI;AACF,QAAI,OAAO,QAAQ,QACjB,QAAO;KACL,MAAM;KACN,gBAAA;KACA,SAAS;KACV;AAGH,UAAM,MAAM,OAAO,OAAO;AAC1B,eAAW,MAAM,iBAAiB;IAMlC,IAAI,iBAAiB;AACrB,WACE,CAAC,cACD,iBAAiB,uBACjB,CAAC,SAAS,MAAM,qBAChB,CAAC,OAAO,QAAQ,WAChB,CAAC,YACD,aAAa,gBAAgB,MAAM,EACnC;AACA,uBAAkB;AAClB,eACE,kDAAkD,eAAe,GAAG,sBACrE;AACD,WAAM,MAAM,OAAO,qBAAqB;AACxC,gBAAW,MAAM,iBAAiB;;AAIpC,QACE,CAAC,cACD,CAAC,SAAS,MAAM,qBAChB,CAAC,YACD,CAAC,OAAO,QAAQ,QAEhB,KAAI;AACF,WAAM,aAAa,OAAO,mBAAmB;aACtC,KAAK;AACZ,eAAU,+BAA+B,OAAO,IAAI,GAAG;;aAGnD;AACR,QAAI,QAAS,cAAa,QAAQ;AAClC,QAAI;AACF,kBAAa;YACP;;AAKV,OAAI,OAAO,QAAQ,QACjB,QAAO;IACL,MAAM;IACN,gBAAA;IACA,SAAS;IACV;AAEH,OAAI,YAAY,cAAc,CAAC,SAAS,MAAM,kBAC5C,QAAO,eAAe,WAAW,UAAU;AAE7C,OAAI,YAAY,CAAC,SAAS,MAAM,mBAAmB;AACjD,YAAQ,KACN,OAAO,gBAAgB,GAAG,OAAO,iBAAiB,SACnD;AACD,mBAAe,SAAS,eAAe;AACvC,QAAI,SAAS,WAAW,IACtB,QAAO;KACL,MAAM;KACN,SAAS;MACP,MAAM,WAAW;MACjB,SAAS;MACT,QAAQ,EAAE,iBAAiB,SAAS,SAAS;MAC9C;KACF;AAEH,WAAO,SAAS,mBAAA,iBACZ;KACE,MAAM;KACN,gBAAA;KACA,SAAS,SAAS;KACnB,GACD;KACE,MAAM;KACN,gBAAgB,SAAS;KACzB,SAAS,SAAS;KACnB;;AAKP,OAAI,SAAS,MAAM,kBAAmB,QAAO,qBAAqB;GAIlE,MAAM,YAAY,CAAC,cAAc,aAAa,gBAAgB,MAAM;GACpE,MAAM,UAAU,kBAAkB;IAAE;IAAW;IAAW,CAAC;AAC3D,OAAI,YAAA,sBAAwC;AAC1C,YAAQ,KAAK,wBAAwB;AACrC,cACE,qBAAqB,eAAe,kCACrC;AACD,cAAU,cAAc,qBAAqB,EAC3C,iBAAiB,gBAClB,CAAC;IAEF,MAAM,iBAAiB,aAAA,qCAEnB;AACJ,mBAAe,eAAe;AAC9B,WAAO;KAAE,MAAM;KAAW;KAAgB;;AAE5C,OAAI,YAAA,2BAA6C;AAC/C,YAAQ,KAAK,iCAAiC;AAC9C,cAAU,mCAAmC;AAC7C,cAAU,cAAc,0BAA0B,EAAE,YAAY,MAAM,CAAC;AACvE,mBAAe,QAAQ;AACvB,WAAO;KAAE,MAAM;KAAW,gBAAgB;KAAS;;GAGrD,MAAM,SAAS,QAAQ,QAAQ;AAC/B,OAAI,OACF,WAAU,QAAQ,0BAA0B,EAAE,QAAQ,CAAC;GAKzD,MAAM,eAAe,QAAQ,qBAAqB;AAClD,OAAI,iBAAiB,KAAA,EACnB,WAAU,cAAc,iCAAiC,EACvD,QAAQ,cACT,CAAC;AAMJ,OAAI;IACF,MAAM,WAAW,KAAK,KAAK,MAAM,YAAY,uBAAuB;AACpE,QAAI,CAAC,cAAc,GAAG,WAAW,SAAS,CACxC,OAAM,GAAG,SAAS,GAAG,SAAS;YACzB,KAAK;AACZ,cAAU,8CAA8C,OAAO,IAAI,GAAG;;GAGxE,MAAM,QAAQ,aAAa,iBAAiB;AAC5C,aAAU,cAAc,mBAAmB;IACzC,GAAG,cAAc;IACjB,OAAO;IACP,WAAW;IAGX,cAAc,MAAM,OAAO;IAC3B,eAAe,MAAM,OAAO;IAC5B,6BAA6B,MAAM,OAAO;IAC1C,yBAAyB,MAAM,OAAO;IACvC,CAAC;AACF,WAAQ,KAAK,OAAO,kBAAkB,+BAA+B;AACrE,eAAY;AACZ,OAAI,CAAC,WAAY,QAAO,EAAE,MAAM,WAAW;AAC3C,OAAI;AACF,WAAO;KACL,MAAM;KACN,kBAAkB,KAAK,MAAM,kBAAkB;KAChD;WACK;AAEN,WAAO,EAAE,MAAM,WAAW;;WAErB,KAAK;AACZ,OAAI,OAAO,QAAQ,QACjB,QAAO;IACL,MAAM;IACN,gBAAA;IACA,SAAS;IACV;AAEH,OAAI,eAAe,kBAAmB,QAAO,qBAAqB;AAClE,OAAI,YAAY,WAAY,QAAO,eAAe,WAAW,UAAU;GACvE,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAChE,aAAU,mBAAmB,UAAU;AACvC,WAAQ,KAAK,OAAO,gBAAgB,GAAG,OAAO,iBAAiB,SAAS;AACxE,OAAI,MAAM,qBAAqB,UAAU;GACzC,MAAM,QAAQ,mBAAmB,IAAI;AACrC,OAAI,MAAM,SAAS,eAAe,OAAO;AACvC,mBAAA,mBAAwC;AACxC,WAAO;KACL,MAAM;KACN,SAAS;MAAE,MAAM,MAAM;MAAM,SAAS,MAAM;MAAS,OAAO;MAAK;KAClE;;GAEH,MAAM,iBAAiB,aAAa,QAAQ;AAC5C,kBAAe,eAAe;AAC9B,UAAO;IACL,MAAM;IACN;IACA;IACA,OAAO,eAAe,QAAQ,MAAM,KAAA;IACrC;YACO;AACR,SAAM,cAAc,QAAQ;AAC5B,SAAM;AACN,OAAI;AACF,kBAAc;WACR;AAGR,OAAI;AACF,YAAQ,YAAY,UAAU;WACxB;;;CAUZ,MAAM,QAAQ,QAA6C;EACzD,MAAM,EAAE,cAAc,MAAM,OAAO;AACnC,SAAO,UAAU,OAAO;;CAE3B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"playground-BLsCfHmQ.js","names":["path","MOCK_TASKS","getSkillContentBlocks"],"sources":["../src/tui/playground/demos/WelcomeDemo.tsx","../src/tui/playground/demos/LayoutDemo.tsx","../src/tui/playground/demos/InputDemo.tsx","../src/tui/playground/demos/ProgressDemo.tsx","../src/tui/playground/demos/LogDemo.tsx","../src/tui/playground/demos/RunScreenDemo.tsx","../src/tui/playground/demos/HealthCheckDemo.tsx","../src/tui/playground/demos/DoctorReportDemo.tsx","../src/tui/playground/demos/ModalDemo.tsx","../src/tui/playground/demos/McpDemo.tsx","../src/tui/playground/demos/McpSuggestedPromptsDemo.tsx","../src/tui/playground/demos/KeyboardHintsDemo.tsx","../src/tui/playground/demos/AuditChecksDemo.tsx","../src/tui/playground/demos/LearnDeckDemo.tsx","../src/tui/playground/demos/EndScreensDemo.tsx","../src/tui/playground/demos/AiOptInDemo.tsx","../src/tui/playground/demos/AskModalDemo.tsx","../src/tui/playground/demos/ViewportGuardDemo.tsx","../src/tui/playground/PlaygroundApp.tsx","../src/tui/playground/start-playground.ts","../src/cli/commands/basic-integration/playground.ts"],"sourcesContent":["/**\n * WelcomeDemo — Splash screen. Press enter to push the tabbed view.\n */\n\nimport { Box, Text, useInput } from 'ink';\nimport type { WizardStore } from '@tui/store';\nimport { Colors, Icons } from '@tui/styles';\n\ninterface WelcomeDemoProps {\n store: WizardStore;\n}\n\nexport const WelcomeDemo = ({ store }: WelcomeDemoProps) => {\n useInput((_input, key) => {\n if (key.return) {\n store.completeSetup();\n }\n });\n\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n justifyContent=\"center\"\n alignItems=\"center\"\n >\n <Text bold color={Colors.accent}>\n {Icons.diamond} PostHog Setup Wizard layout primitives playground\n </Text>\n <Box height={1} />\n <Text>Layout primitives for the PostHog Setup Wizard TUI.</Text>\n <Text dimColor>\n CardLayout, SplitView, TabContainer, ProgressList, and more.\n </Text>\n <Box height={1} />\n <Text color={Colors.primary}>\n Press enter to continue {Icons.triangleRight}\n </Text>\n </Box>\n );\n};\n","/**\n * LayoutDemo — Demonstrates CardLayout + SplitView.\n * Cycles alignment enums with keyboard shortcuts.\n */\n\nimport { Box, Text, useInput } from 'ink';\nimport { useState } from 'react';\nimport { CardLayout, SplitView, ConfirmButton } from '@tui/primitives/index';\nimport { HAlign, VAlign, Colors } from '@tui/styles';\n\nconst hAligns = [HAlign.Left, HAlign.Center, HAlign.Right];\nconst vAligns = [VAlign.Top, VAlign.Center, VAlign.Bottom];\nconst hLabels = ['Left', 'Center', 'Right'];\nconst vLabels = ['Top', 'Center', 'Bottom'];\n\nexport const LayoutDemo = () => {\n const [hIdx, setHIdx] = useState(0);\n const [vIdx, setVIdx] = useState(0);\n\n useInput((input) => {\n if (input === 'h') setHIdx((i) => (i + 1) % hAligns.length);\n if (input === 'v') setVIdx((i) => (i + 1) % vAligns.length);\n });\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text bold color={Colors.accent}>\n Layout Demo\n </Text>\n <Text dimColor>\n Press [h] to cycle hAlign ({hLabels[hIdx]}), [v] to cycle vAlign (\n {vLabels[vIdx]})\n </Text>\n <Box height={1} />\n <SplitView\n left={\n <CardLayout hAlign={hAligns[hIdx]} vAlign={vAligns[vIdx]}>\n <Box borderStyle=\"single\" borderColor={Colors.primary} paddingX={1}>\n <Text color={Colors.primary}>Left Pane</Text>\n </Box>\n </CardLayout>\n }\n right={\n <CardLayout hAlign={HAlign.Center} vAlign={VAlign.Center}>\n <Box borderStyle=\"single\" borderColor={Colors.accent} paddingX={1}>\n <Text color={Colors.accent}>Right Pane</Text>\n </Box>\n </CardLayout>\n }\n />\n <Box height={1} />\n <Text dimColor>\n ConfirmButton — the focusable submit target for multi-select menus\n (focused / unfocused):\n </Text>\n <Box gap={2} marginTop={1}>\n <ConfirmButton focused count={3} />\n <ConfirmButton focused={false} />\n </Box>\n </Box>\n );\n};\n","/**\n * InputDemo — Demonstrates PickerMenu (single + multi) and ConfirmationInput.\n */\n\nimport { Box, Text } from 'ink';\nimport { useState } from 'react';\nimport { PickerMenu, ConfirmationInput } from '@tui/primitives/index';\nimport { Colors } from '@tui/styles';\n\nenum DemoStep {\n Single = 'single',\n Multi = 'multi',\n MultiLong = 'multi-long',\n Confirm = 'confirm',\n Done = 'done',\n}\n\n// A long single-column multi-select — more options than a normal terminal can\n// show at once — so the playground exercises PickerMenu's viewport paging\n// (the \"↑/↓ N more\" indicators and the n/p page keys). Shared with\n// AskModalDemo.\nexport const LONG_OPTIONS = [\n 'None of these',\n 'GitHub Issues',\n 'Linear',\n 'Jira',\n 'GitLab',\n 'Gitea',\n 'Shortcut',\n 'Sentry',\n 'Rollbar',\n 'Bugsnag',\n 'Honeybadger',\n 'Raygun',\n 'Zendesk',\n 'Freshdesk',\n 'Freshservice',\n 'Front',\n 'Gorgias',\n 'Kustomer',\n 'Dixa',\n 'Plain',\n 'pganalyze',\n 'Snyk',\n 'SonarQube',\n 'Semgrep',\n 'Rapid7 InsightVM',\n 'Featurebase',\n 'Frill',\n 'Aha',\n 'UserVoice',\n 'Productboard',\n 'Canny',\n 'AskNicely',\n 'Retently',\n 'Appfigures',\n 'AppFollow',\n 'Judge.me',\n 'Google Search Console',\n].map((label) => ({ label, value: label.toLowerCase().replace(/\\s+/g, '-') }));\n\nexport const InputDemo = () => {\n const [step, setStep] = useState<DemoStep>(DemoStep.Single);\n const [results, setResults] = useState<string[]>([]);\n\n if (step === DemoStep.Single) {\n return (\n <Box flexDirection=\"column\">\n <Text bold color={Colors.accent}>\n Input Demo — Single Select\n </Text>\n <Box height={1} />\n <PickerMenu\n message=\"Pick a color\"\n options={[\n { label: 'Red', value: 'red', hint: 'warm' },\n { label: 'Blue', value: 'blue', hint: 'cool' },\n { label: 'Green', value: 'green', hint: 'natural' },\n ]}\n onSelect={(value) => {\n setResults((prev) => [...prev, `Single: ${value}`]);\n setStep(DemoStep.Multi);\n }}\n />\n </Box>\n );\n }\n\n if (step === DemoStep.Multi) {\n return (\n <Box flexDirection=\"column\">\n <Text bold color={Colors.accent}>\n Input Demo — Multi Select\n </Text>\n <Box height={1} />\n <PickerMenu\n message=\"Pick toppings\"\n mode=\"multi\"\n options={[\n { label: 'Cheese', value: 'cheese' },\n { label: 'Pepperoni', value: 'pepperoni' },\n { label: 'Mushrooms', value: 'mushrooms' },\n { label: 'Onions', value: 'onions' },\n ]}\n onSelect={(values) => {\n const arr = Array.isArray(values) ? values : [values];\n setResults((prev) => [...prev, `Multi: ${arr.join(', ')}`]);\n setStep(DemoStep.MultiLong);\n }}\n />\n </Box>\n );\n }\n\n if (step === DemoStep.MultiLong) {\n return (\n <Box flexDirection=\"column\">\n <Text bold color={Colors.accent}>\n Input Demo — Multi Select (long, scrolls)\n </Text>\n <Box height={1} />\n <PickerMenu\n message=\"Which of these do you use? (↑/↓ to scroll)\"\n mode=\"multi\"\n options={LONG_OPTIONS}\n onSelect={(values) => {\n const arr = Array.isArray(values) ? values : [values];\n setResults((prev) => [\n ...prev,\n `Multi (long): ${arr.length} picked`,\n ]);\n setStep(DemoStep.Confirm);\n }}\n />\n </Box>\n );\n }\n\n if (step === DemoStep.Confirm) {\n return (\n <Box flexDirection=\"column\">\n <Text bold color={Colors.accent}>\n Input Demo — Confirmation\n </Text>\n <Box height={1} />\n <ConfirmationInput\n message=\"Are you satisfied with your choices?\"\n onConfirm={() => {\n setResults((prev) => [...prev, 'Confirmed: Yes']);\n setStep(DemoStep.Done);\n }}\n onCancel={() => {\n setResults((prev) => [...prev, 'Confirmed: No']);\n setStep(DemoStep.Done);\n }}\n />\n </Box>\n );\n }\n\n // done\n return (\n <Box flexDirection=\"column\">\n <Text bold color={Colors.accent}>\n Input Demo — Results\n </Text>\n <Box height={1} />\n {results.map((r, i) => (\n <Text key={i} color={Colors.success}>\n {'\\u2714'} {r}\n </Text>\n ))}\n <Box height={1} />\n <Text dimColor>Switch away from this tab and back to restart.</Text>\n </Box>\n );\n};\n","/**\n * ProgressDemo — Demonstrates ProgressList + LoadingBox.\n * Auto-animates task progression through states.\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useEffect } from 'react';\nimport { ProgressList, LoadingBox } from '@tui/primitives/index';\nimport type { ProgressItem } from '@tui/primitives/index';\nimport { Colors } from '@tui/styles';\n\nconst INITIAL_ITEMS: ProgressItem[] = [\n {\n label: 'Detect framework',\n activeForm: 'Detecting framework',\n status: 'pending',\n },\n {\n label: 'Install dependencies',\n activeForm: 'Installing dependencies',\n status: 'pending',\n },\n {\n label: 'Configure PostHog',\n activeForm: 'Configuring PostHog',\n status: 'pending',\n },\n {\n label: 'Add analytics provider',\n activeForm: 'Adding analytics provider',\n status: 'pending',\n },\n { label: 'Verify setup', activeForm: 'Verifying setup', status: 'pending' },\n];\n\nexport const ProgressDemo = () => {\n const [items, setItems] = useState<ProgressItem[]>(INITIAL_ITEMS);\n const [tick, setTick] = useState(0);\n\n useEffect(() => {\n const timer = setInterval(() => {\n setTick((t) => t + 1);\n }, 1500);\n return () => clearInterval(timer);\n }, []);\n\n useEffect(() => {\n // Cycle: each tick advances the \"active\" task\n const total = INITIAL_ITEMS.length;\n // After all tasks complete, restart\n const cycle = tick % (total + 2); // +2 for a pause at the end\n\n setItems(\n INITIAL_ITEMS.map((item, i) => {\n if (i < cycle) return { ...item, status: 'completed' as const };\n if (i === cycle) return { ...item, status: 'in_progress' as const };\n return { ...item, status: 'pending' as const };\n }),\n );\n }, [tick]);\n\n const allDone = items.every((i) => i.status === 'completed');\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text bold color={Colors.accent}>\n Progress Demo\n </Text>\n <Text dimColor>Tasks auto-advance every 1.5s (cycles continuously)</Text>\n <Box height={1} />\n <ProgressList items={items} title=\"Setup in progress:\" />\n <Box height={1} />\n {!allDone && <LoadingBox message=\"Working...\" />}\n {allDone && (\n <Text color={Colors.success} bold>\n {'\\u2714'} All tasks complete! Restarting...\n </Text>\n )}\n </Box>\n );\n};\n","/**\n * LogDemo — Demonstrates LogViewer.\n * Writes demo log lines to a temp file, then tails it.\n */\n\nimport { Box, Text } from 'ink';\nimport { useEffect, useState } from 'react';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { LogViewer } from '@tui/primitives/index';\nimport { Colors } from '@tui/styles';\n\nconst DEMO_LOG_PATH = path.join(os.tmpdir(), 'posthog-playground.log');\n\nconst LOG_MESSAGES = [\n '[info] Playground started',\n '[info] Initializing demo components...',\n '[debug] Loading primitives barrel export',\n '[info] ScreenContainer mounted',\n '[info] TabContainer initialized with 6 tabs',\n '[debug] LayoutDemo: hAlign=Left, vAlign=Top',\n '[info] NavigationDemo: screenStack depth = 1',\n '[warn] TabDemo: arrow key conflict with outer container',\n '[info] InputDemo: waiting for user selection',\n '[info] ProgressDemo: tick 0, cycling tasks',\n '[debug] LogViewer: watching file for changes',\n '[info] All demos loaded successfully',\n];\n\nexport const LogDemo = () => {\n const [ready, setReady] = useState(false);\n\n useEffect(() => {\n // Write initial log content\n fs.writeFileSync(DEMO_LOG_PATH, LOG_MESSAGES.join('\\n') + '\\n');\n setReady(true);\n\n // Append lines periodically\n let lineNum = LOG_MESSAGES.length;\n const timer = setInterval(() => {\n lineNum++;\n const msg = `[info] Demo log line #${lineNum} — ${new Date().toISOString()}\\n`;\n fs.appendFileSync(DEMO_LOG_PATH, msg);\n }, 2000);\n\n return () => {\n clearInterval(timer);\n try {\n fs.unlinkSync(DEMO_LOG_PATH);\n } catch {\n // ignore\n }\n };\n }, []);\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text bold color={Colors.accent}>\n Log Demo\n </Text>\n <Text dimColor>Tailing {DEMO_LOG_PATH} (new line every 2s)</Text>\n <Box height={1} />\n {ready && <LogViewer filePath={DEMO_LOG_PATH} height={15} />}\n </Box>\n );\n};\n","/**\n * RunScreenDemo — Playground demo for the agent run view.\n *\n * Renders RunScreen's tab panels directly (not RunScreen itself) and owns its\n * own tab navigation, the way HealthCheckDemo renders its components directly —\n * a nested TabContainer would fight the playground's outer one over the arrow\n * keys (Ink delivers every key to every handler), leaving the inner tabs\n * unreachable. So the outer playground keeps the arrows and this demo uses:\n *\n * n / p switch run-screen tab (Status, Event plan, Tail logs, Visualizer, HN)\n *\n * Tasks auto-advance every 1.5s and the visualizer stage cycles on its own.\n * Discovered features (Stripe, LLM) are pre-populated so conditional tips appear.\n */\n\nimport {\n useEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { WizardStore, TaskStatus } from '@tui/store';\nimport { DiscoveredFeature } from '@programs/session/wizard-session';\nimport { AgentPhase } from '@shared/agent-phase';\nimport {\n SplitView,\n ProgressList,\n LogViewer,\n EventPlanViewer,\n HNViewer,\n} from '@tui/primitives/index';\nimport type { ProgressItem, TabDefinition } from '@tui/primitives/index';\nimport { LearnCard } from '@tui/components/LearnCard';\nimport { TipsCard } from '@tui/components/TipsCard';\nimport { VisualizerTab } from '@tui/components/PhaseVisuals';\nimport { getProgramConfig } from '@programs';\nimport { getContentBlocks as getSkillContentBlocks } from '@tui/programs/shared/skill-deck';\nimport { Colors } from '@tui/styles';\nimport { WIZARD_LOG_FILE } from '@utils/paths';\n\nconst STAGE_CYCLE: AgentPhase[] = [\n AgentPhase.CodebaseScan,\n AgentPhase.SkillInstall,\n AgentPhase.DepInstall,\n AgentPhase.CodeEdits,\n AgentPhase.EnvSetup,\n AgentPhase.Dashboards,\n];\n\nconst MOCK_TASKS = [\n {\n label: 'Checking project structure and finding files for event tracking',\n activeForm: 'Checking project structure',\n status: TaskStatus.Pending,\n done: false,\n },\n {\n label: 'Load skill menu and install integration-nextjs-app-router skill',\n activeForm: 'Picking the right skill',\n status: TaskStatus.Pending,\n done: false,\n },\n {\n label: 'Verify PostHog dependencies',\n activeForm: 'Verifying PostHog dependencies',\n status: TaskStatus.Pending,\n done: false,\n },\n {\n label: 'Generate events plan (.posthog-events.json)',\n activeForm: 'Generating events plan',\n status: TaskStatus.Pending,\n done: false,\n },\n {\n label: 'Install posthog-js and posthog-node packages',\n activeForm: 'Installing packages',\n status: TaskStatus.Pending,\n done: false,\n },\n {\n label: 'Set up environment variables',\n activeForm: 'Setting up environment variables',\n status: TaskStatus.Pending,\n done: false,\n },\n {\n label: 'Create instrumentation-client.ts',\n activeForm: 'Creating instrumentation-client.ts',\n status: TaskStatus.Pending,\n done: false,\n },\n {\n label: 'Update next.config with rewrites',\n activeForm: 'Updating next.config',\n status: TaskStatus.Pending,\n done: false,\n },\n {\n label: 'Create posthog-server.ts',\n activeForm: 'Creating posthog-server.ts',\n status: TaskStatus.Pending,\n done: false,\n },\n {\n label: 'Add PostHog capture events to project files',\n activeForm: 'Adding capture events',\n status: TaskStatus.Pending,\n done: false,\n },\n {\n label: 'Create onboarding dashboard and insight',\n activeForm: 'Building dashboard',\n status: TaskStatus.Pending,\n done: false,\n },\n {\n label: 'Verify $pageview and $autocapture are arriving',\n activeForm: 'Watching events arrive',\n status: TaskStatus.Pending,\n done: false,\n },\n];\n\nconst MOCK_EVENTS = [\n { name: 'page_viewed', description: 'Fires when a user views any page' },\n {\n name: 'button_clicked',\n description: 'Fires when the CTA button is clicked',\n },\n {\n name: 'form_submitted',\n description: 'Fires when the contact form is submitted',\n },\n {\n name: 'signup_started',\n description: 'Fires when a user begins the signup flow',\n },\n];\n\ninterface RunScreenDemoProps {\n store: WizardStore;\n}\n\nexport const RunScreenDemo = ({ store }: RunScreenDemoProps) => {\n const tickRef = useRef(0);\n const lastStatusRef = useRef('');\n const [activeTab, setActiveTab] = useState(0);\n\n // Re-render whenever the mock timers mutate the store (tasks, stage, etc.).\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n // Seed the store with mock data on mount\n useEffect(() => {\n store.addDiscoveredFeature(DiscoveredFeature.Stripe);\n store.addDiscoveredFeature(DiscoveredFeature.LLM);\n store.setEventPlan(MOCK_EVENTS);\n store.pushStatus('Checking project structure.');\n lastStatusRef.current = 'Checking project structure.';\n\n // Set initial tasks\n const initial = MOCK_TASKS.map((t, i) =>\n i === 0 ? { ...t, status: TaskStatus.InProgress } : t,\n );\n store.setTasks(initial);\n }, []);\n\n // Auto-advance tasks every 1.5s\n useEffect(() => {\n const timer = setInterval(() => {\n tickRef.current += 1;\n const tick = tickRef.current;\n const total = MOCK_TASKS.length;\n const cycle = tick % (total + 3); // +3 for pause at end before restart\n\n const tasks = MOCK_TASKS.map((t, i) => {\n if (i < cycle)\n return { ...t, status: TaskStatus.Completed, done: true };\n if (i === cycle)\n return { ...t, status: TaskStatus.InProgress, done: false };\n return { ...t, status: TaskStatus.Pending, done: false };\n });\n\n store.setTasks(tasks);\n\n // Only push status when the message actually changes\n if (cycle < total) {\n const msg = MOCK_TASKS[cycle].activeForm + '...';\n if (msg !== lastStatusRef.current) {\n store.pushStatus(msg);\n lastStatusRef.current = msg;\n }\n }\n }, 1500);\n\n return () => clearInterval(timer);\n }, []);\n\n // Cycle through every Visualizer stage on a faster timer so the playground\n // exercises each ASCII visual without needing the real agent loop.\n useEffect(() => {\n let i = 0;\n store.setCurrentStage(STAGE_CYCLE[0]);\n const timer = setInterval(() => {\n i = (i + 1) % STAGE_CYCLE.length;\n store.setCurrentStage(STAGE_CYCLE[i]);\n }, 4000);\n return () => clearInterval(timer);\n }, [store]);\n\n // Mirror RunScreen's tab panels (built here so the demo can drive them with\n // n/p instead of the arrow keys the outer playground TabContainer owns).\n const progressItems: ProgressItem[] = store.tasks.map((t) => ({\n label: t.label,\n activeForm: t.activeForm,\n status: t.status,\n }));\n\n const learnBlocks = useMemo(() => {\n const getBlocks =\n getProgramConfig(store.router.activeProgram).getContentBlocks ??\n getSkillContentBlocks;\n return getBlocks(store);\n }, [store]);\n\n const leftPane = store.learnCardComplete ? (\n <TipsCard store={store} />\n ) : (\n <LearnCard\n store={store}\n blocks={learnBlocks}\n onComplete={() => store.setLearnCardComplete()}\n />\n );\n\n const tabs: TabDefinition[] = [\n {\n id: 'status',\n label: 'Status',\n component: (\n <SplitView\n left={leftPane}\n right={<ProgressList items={progressItems} title=\"Tasks\" />}\n />\n ),\n },\n ...(store.eventPlan.length > 0\n ? [\n {\n id: 'events',\n label: 'Event plan',\n component: <EventPlanViewer events={store.eventPlan} />,\n },\n ]\n : []),\n {\n id: 'logs',\n label: 'Tail logs',\n component: <LogViewer filePath={WIZARD_LOG_FILE} />,\n },\n {\n id: 'visualizer',\n label: 'Visualizer',\n component: <VisualizerTab store={store} />,\n },\n { id: 'hn', label: 'HN', component: <HNViewer /> },\n ];\n\n // The outer playground TabContainer owns the arrow keys, so navigate with n/p.\n useInput((input) => {\n if (input === 'n') {\n setActiveTab((i) => Math.min(tabs.length - 1, i + 1));\n } else if (input === 'p') {\n setActiveTab((i) => Math.max(0, i - 1));\n }\n });\n\n const current = tabs[Math.min(activeTab, tabs.length - 1)];\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box flexDirection=\"column\" flexGrow={1} flexShrink={1} overflow=\"hidden\">\n {current?.component}\n </Box>\n\n <Box height={1} />\n <Box gap={1} paddingX={1}>\n {tabs.map((tab, i) => (\n <Text\n key={tab.id}\n inverse={i === activeTab}\n color={i === activeTab ? Colors.accent : Colors.muted}\n bold={i === activeTab}\n >\n {` ${tab.label} `}\n </Text>\n ))}\n </Box>\n <Box paddingX={1}>\n <Text dimColor>n/p switch tab</Text>\n </Box>\n </Box>\n );\n};\n","// Preview the skills health-check states without handling input.\n\nimport { useEffect, useState } from 'react';\nimport { Box, Text } from 'ink';\nimport { LoadingBox, ModalOverlay } from '@tui/primitives/index';\nimport { Icons } from '@tui/styles';\nimport { ServiceHealthList } from '@tui/components/ServiceHealthList';\nimport { getBlockingServiceKeys } from '@shared/health-checks/readiness';\nimport { ServiceHealthStatus } from '@shared/health-checks/types';\nimport type { AllServicesHealth } from '@shared/health-checks/types';\n\nconst MOCK_CONFIRMED_OUTAGE: AllServicesHealth = {\n skillsOrigin: { status: ServiceHealthStatus.Down },\n};\n\nconst MOCK_NO_CONNECTION: AllServicesHealth = {\n skillsOrigin: { status: ServiceHealthStatus.NoConnection },\n};\n\ntype Phase = 'checking' | 'confirmed' | 'no-connection';\n\nexport const HealthCheckDemo = () => {\n const [phase, setPhase] = useState<Phase>('checking');\n\n useEffect(() => {\n const t1 = setTimeout(() => setPhase('confirmed'), 2000);\n const t2 = setTimeout(() => setPhase('no-connection'), 7000);\n const t3 = setTimeout(() => setPhase('checking'), 12000);\n return () => {\n clearTimeout(t1);\n clearTimeout(t2);\n clearTimeout(t3);\n };\n }, [phase]);\n\n if (phase === 'checking') {\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n <LoadingBox message=\"Checking service status...\" />\n </Box>\n );\n }\n\n const health =\n phase === 'confirmed' ? MOCK_CONFIRMED_OUTAGE : MOCK_NO_CONNECTION;\n const blockingKeys = getBlockingServiceKeys(health);\n const isNoConnection = phase === 'no-connection';\n\n return (\n <ModalOverlay\n borderColor={isNoConnection ? 'yellow' : 'red'}\n title={\n isNoConnection\n ? \"Couldn't reach skill downloads\"\n : `${Icons.warning} Skill downloads unavailable`\n }\n width={72}\n footer={\n <Box marginLeft={2}>\n <Text dimColor>Exit [Esc] (disabled in playground)</Text>\n </Box>\n }\n >\n <Box flexDirection=\"column\" marginBottom={1}>\n <Box marginBottom={1}>\n <Text>\n <Text color=\"red\">{Icons.squareFilled}</Text>\n <Text dimColor> Down </Text>\n <Text color=\"#DC9300\">{Icons.squareFilled}</Text>\n <Text dimColor> Degraded </Text>\n <Text color=\"gray\">{Icons.squareFilled}</Text>\n <Text dimColor> No connection</Text>\n </Text>\n </Box>\n\n <ServiceHealthList\n health={health}\n filterKeys={blockingKeys}\n showHealthy={false}\n />\n </Box>\n\n <Text dimColor>\n {isNoConnection\n ? \"We couldn't reach either skills source. Check your connection and try again.\"\n : 'Neither GitHub Releases nor the AWS mirror is available.'}\n </Text>\n </ModalOverlay>\n );\n};\n","import { Box, Text } from 'ink';\nimport { Colors, Icons } from '@tui/styles';\nimport { IssueTable } from '@tui/tools/doctor/screens/IssueTable';\nimport type { HealthIssue } from '@programs/posthog-doctor/index';\n\nconst NOW = '2026-04-27T15:00:00Z';\n\nconst MOCK_ISSUES: HealthIssue[] = [\n mock('1', 'ingestion_lag', 'critical'),\n mock('2', 'ingestion_warning', 'critical'),\n mock('3', 'materialized_view_failure', 'critical'),\n mock('4', 'sdk_outdated', 'warning'),\n mock('5', 'no_pageleave_events', 'warning'),\n mock('6', 'scroll_depth', 'warning'),\n mock('7', 'web_vitals', 'warning'),\n mock('8', 'reverse_proxy', 'info'),\n mock('9', 'authorized_urls', 'info'),\n mock('10', 'unrecognised_kind_with_a_long_slug_that_should_truncate', 'info'),\n];\n\nfunction mock(\n id: string,\n kind: string,\n severity: HealthIssue['severity'],\n): HealthIssue {\n return {\n id,\n kind,\n severity,\n status: 'active',\n dismissed: false,\n created_at: NOW,\n updated_at: NOW,\n };\n}\n\nexport const DoctorReportDemo = () => {\n return (\n <Box flexDirection=\"column\">\n <Text bold color={Colors.accent}>\n PostHog Doctor Report\n </Text>\n <Text dimColor>\n Project 12345 {Icons.bullet} https://us.i.posthog.com\n </Text>\n <Box marginTop={1}>\n <Text>\n {MOCK_ISSUES.length} active issues: 3 critical, 4 warning, 3 info\n </Text>\n </Box>\n <IssueTable issues={MOCK_ISSUES} />\n </Box>\n );\n};\n","/**\n * ModalDemo — Playground demo for the ModalOverlay primitive.\n *\n * Shows several modal variants: info, warning, error, and one with feedback text.\n */\n\nimport { Box, Text } from 'ink';\nimport { ModalOverlay } from '@tui/primitives/index';\nimport { Icons } from '@tui/styles';\n\nexport const ModalDemo = () => {\n return (\n <Box flexDirection=\"column\" gap={1} flexGrow={1}>\n <ModalOverlay borderColor=\"cyan\" title=\"Info Modal\" width={60}>\n <Text>A simple informational modal with default styling.</Text>\n </ModalOverlay>\n\n <ModalOverlay\n borderColor=\"#DC9300\"\n title={`${Icons.warning} Warning Modal`}\n width={60}\n feedback=\"Something needs your attention.\"\n >\n <Text>This modal includes a feedback message shown in yellow.</Text>\n </ModalOverlay>\n\n <ModalOverlay\n borderColor=\"red\"\n title={`${Icons.warning} Error Modal`}\n width={60}\n footer={\n <Box marginLeft={2}>\n <Text dimColor>\n Continue [Enter] / Exit [Esc] (disabled in playground)\n </Text>\n </Box>\n }\n >\n <Text>This modal has a footer section below a divider.</Text>\n </ModalOverlay>\n </Box>\n );\n};\n","/**\n * McpDemo — Playground demo for the MCP client selection screen.\n *\n * Uses a mock McpInstaller that simulates detecting three editors,\n * a short install delay, and a successful result.\n */\n\nimport { WizardStore } from '@tui/store';\nimport { McpScreen } from '@tui/screens/McpScreen';\nimport type { McpInstaller, McpClientInfo } from '@tui/services/mcp-installer';\nimport { McpClientStatus } from '@shared/mcp-clients/results';\n\nconst MOCK_CLIENTS: McpClientInfo[] = [\n { name: 'Claude Code', supportsPlugin: true, pluginBundlesMcp: false },\n { name: 'Cursor', supportsPlugin: true, pluginBundlesMcp: false },\n { name: 'VS Code', supportsPlugin: false, pluginBundlesMcp: false },\n {\n name: 'Claude Desktop/Web',\n supportsPlugin: false,\n pluginBundlesMcp: false,\n finish: {\n url: 'https://claude.ai/directory/connectors/posthog',\n instruction: 'Sign in and click \"Connect\" to finish.',\n },\n },\n];\n\nfunction createMockInstaller(): McpInstaller {\n return {\n async detectClients() {\n await new Promise((r) => setTimeout(r, 800));\n return MOCK_CLIENTS;\n },\n async install(clientNames) {\n await new Promise((r) => setTimeout(r, 1500));\n // Mixed outcomes so the demo shows every Done-phase section.\n return clientNames.map((name, i) => ({\n name,\n status: i === 1 ? McpClientStatus.Unchanged : McpClientStatus.Changed,\n }));\n },\n async installPlugins(clientNames) {\n await new Promise((r) => setTimeout(r, 800));\n return clientNames\n .filter(\n (name) => MOCK_CLIENTS.find((c) => c.name === name)?.supportsPlugin,\n )\n .map((name) => ({ name, status: McpClientStatus.Changed }));\n },\n async remove() {\n await new Promise((r) => setTimeout(r, 1000));\n // Mixed outcomes so the demo shows the removal failure copy too.\n return MOCK_CLIENTS.map((c, i) =>\n i === 2\n ? {\n name: c.name,\n status: McpClientStatus.Failed,\n detail: 'EACCES: permission denied',\n }\n : { name: c.name, status: McpClientStatus.Changed },\n );\n },\n };\n}\n\ninterface McpDemoProps {\n store: WizardStore;\n}\n\nexport const McpDemo = ({ store }: McpDemoProps) => {\n return (\n <McpScreen store={store} installer={createMockInstaller()} mode=\"install\" />\n );\n};\n","/**\n * McpSuggestedPromptsDemo — Playground demo for the post-MCP\n * suggested-prompts screen.\n *\n * Mounts the real McpSuggestedPromptsScreen with mock services so every\n * phase (Choose → Authenticating → Scouting → [SeedOffer → Seeding] →\n * Greeting → PromptPicker → Running → FollowUp → Goodbye) can be previewed\n * without touching the network. The Greeting phase auto-advances; FollowUp\n * re-enters Running when a follow-up is picked, building a conversation\n * tree up to MAX_PROMPT_RUNS deep.\n *\n * R cycle role (null → founder → product → ... → data → null)\n * F cycle framework (null → nextjs → vue → swift → django → null)\n * T cycle data tier (rich → sparse → empty) — drives the scout:\n * rich → generated quests from real events;\n * empty → seed-offer fork; sparse → safe read.\n * X remount the screen (useful after Exit)\n *\n * O OAuth outcome: success | error\n * L login delay: 0ms (skip UI) | 2000ms | 6000ms\n * S stream script: short-text | with-tools | mid-stream-error\n * C chunk delay: 50ms | 200ms | 800ms\n *\n * Tips:\n * - Set T to \"empty\" to walk the seed-events fork (SeedOffer → Seeding),\n * which lands on a rich seeded profile.\n * - Switch S to \"with-tools\" and the FollowUp picker after the run will\n * show context-aware suggestions based on the last tool. The mock\n * calls are CLI-mode `exec` chunks (`mcp__posthog-wizard__exec` + a\n * `call <tool> …` command), so they exercise getFollowUps' inner-tool\n * extraction.\n */\n\nimport { Box, Text, useInput } from 'ink';\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport type { WizardStore } from '@tui/store';\nimport { McpSuggestedPromptsScreen } from '@tui/tools/mcp/screens/McpSuggestedPromptsScreen';\nimport { Colors } from '@tui/styles';\nimport { Integration } from '@shared/constants';\nimport { McpOutcome } from '@programs/session/wizard-session';\nimport { HostResolution } from '@shared/host-resolution';\nimport { TAILORED_ROLES } from '@tui/tools/mcp/services/mcp-role-prompts';\nimport {\n assembleProfile,\n type ProjectDataProfile,\n} from '@tui/tools/mcp/services/mcp-project-profile';\nimport { seededProfile } from '@tui/tools/mcp/services/seed-events';\nimport type {\n AgentChunk,\n McpSuggestedPromptsServices,\n} from '@tui/tools/mcp/services/suggested-prompts';\n\n// One Integration per framework family so cycling exercises every\n// override bucket in mcp-role-prompts.ts.\nconst FAMILY_INTEGRATIONS: Array<Integration | null> = [\n null,\n Integration.nextjs, // fullstack\n Integration.vue, // frontend-web\n Integration.swift, // mobile\n Integration.django, // backend\n];\n\nconst ROLE_CYCLE: Array<string | null> = [null, ...TAILORED_ROLES];\n\nconst LOGIN_DELAYS_MS = [0, 2000, 6000] as const;\nconst CHUNK_DELAYS_MS = [50, 200, 800] as const;\n\n// Canned scout outcomes. 'rich' → generated quests from real events;\n// 'sparse' → safe read + a generated quest; 'empty' → seed-offer fork.\nconst PROBE_TIER_CYCLE = ['rich', 'sparse', 'empty'] as const;\ntype ProbeTier = (typeof PROBE_TIER_CYCLE)[number];\n\n// Every product absent, so activation cross-sells are eligible in the demo.\nconst NO_PRODUCTS = {\n sessionReplay: false,\n surveys: false,\n featureFlags: false,\n experiments: false,\n dataWarehouse: false,\n} as const;\n\nfunction mockProfile(tier: ProbeTier): ProjectDataProfile {\n if (tier === 'empty') {\n return assembleProfile([], NO_PRODUCTS);\n }\n if (tier === 'sparse') {\n return assembleProfile(\n [\n { name: '$pageview', count: 12 },\n { name: 'clicked', count: 5 },\n ],\n NO_PRODUCTS,\n );\n }\n return assembleProfile(\n [\n { name: '$pageview', count: 100 },\n { name: 'feature_used', count: 21 },\n { name: 'signed_up', count: 10 },\n { name: 'activated', count: 7 },\n { name: 'upgraded_to_paid', count: 3 },\n ],\n NO_PRODUCTS,\n );\n}\n\ntype LoginOutcome = 'success' | 'error';\ntype StreamScript = 'short-text' | 'with-tools' | 'mid-stream-error';\nconst LOGIN_OUTCOMES: LoginOutcome[] = ['success', 'error'];\nconst STREAM_SCRIPTS: StreamScript[] = [\n 'short-text',\n 'with-tools',\n 'mid-stream-error',\n];\n\nconst SCRIPTS: Record<StreamScript, AgentChunk[]> = {\n 'short-text': [\n { kind: 'text', text: 'Looking at your project…' },\n { kind: 'text', text: ' here is a quick read of the last 24 hours.' },\n {\n kind: 'text',\n text: ' You had 12,308 events from 2,144 distinct users.',\n },\n { kind: 'text', text: '\\n\\nNothing unusual stood out.' },\n { kind: 'done', sessionId: 'mock-session-aaa' },\n ],\n 'with-tools': [\n { kind: 'text', text: 'Looking up your project…' },\n {\n kind: 'tool-call',\n toolName: 'mcp__posthog-wizard__exec',\n detail: 'call query-trends { event: \"signup\", interval: \"day\" }',\n command:\n 'call query-trends {\"event\":\"signup\",\"interval\":\"day\",\"window\":\"7d\"}',\n },\n {\n kind: 'tool-result',\n toolName: 'mcp__posthog-wizard__exec',\n detail: '{ rows: 7, total: 482, change: +8.4% }',\n },\n {\n kind: 'text',\n text: '\\nSignups are up 8.4% week-over-week — 482 over the last 7 days.',\n },\n {\n kind: 'tool-call',\n toolName: 'mcp__posthog-wizard__exec',\n detail: 'call create-insight { name: \"Weekly signups\", save: true }',\n command:\n 'call create-insight {\"name\":\"Weekly signups\",\"query\":\"<trends>\",\"save\":true}',\n },\n {\n kind: 'tool-result',\n toolName: 'mcp__posthog-wizard__exec',\n detail:\n '{ id: \"ins_abc123\", url: \"https://app.posthog.com/i/ins_abc123\" }',\n },\n {\n kind: 'text',\n text: '\\nInsight saved as \"Weekly signups\" — pinned to your team dashboard.',\n },\n { kind: 'done', sessionId: 'mock-session-aaa' },\n ],\n 'mid-stream-error': [\n { kind: 'text', text: 'Looking at the most recent errors…' },\n {\n kind: 'tool-call',\n toolName: 'mcp__posthog-wizard__exec',\n detail: 'call query-error-tracking-issue { window: \"7d\", limit: 5 }',\n command: 'call query-error-tracking-issue {\"window\":\"7d\",\"limit\":5}',\n },\n {\n kind: 'error',\n text: 'MCP server returned 503 — try again in a moment.',\n },\n ],\n};\n\ninterface MockConfig {\n role: string | null;\n tier: ProbeTier;\n loginOutcome: LoginOutcome;\n loginDelayMs: number;\n script: StreamScript;\n chunkDelayMs: number;\n}\n\ninterface McpSuggestedPromptsDemoProps {\n store: WizardStore;\n}\n\nconst delay = (ms: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, ms));\n\n/**\n * Returns a McpSuggestedPromptsServices instance whose behavior is read\n * fresh from `configRef` on every call. Hotkey changes take effect on\n * the *next* invocation without remounting the screen.\n */\nfunction createMockServices(\n store: WizardStore,\n configRef: { current: MockConfig },\n): McpSuggestedPromptsServices {\n return {\n performLogin: async () => {\n const cfg = configRef.current;\n store.setLoginUrl('https://app.posthog.com/oauth/playground-mock');\n await delay(cfg.loginDelayMs);\n store.setLoginUrl(null);\n\n if (cfg.loginOutcome === 'error') {\n throw new Error('Mock OAuth rejected — exercising error path.');\n }\n\n return {\n credentials: {\n accessToken: 'phx_mock',\n projectApiKey: 'phc_mock',\n host: HostResolution.fromApiHost('http://127.0.0.1:1'),\n projectId: 1,\n },\n roleAtOrganization: cfg.role,\n user: {\n distinct_id: 'demo-distinct-id',\n uuid: 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',\n id: 1,\n email: 'joe@demo.example.com',\n first_name: 'Joe',\n last_name: 'Demo',\n role_at_organization: cfg.role,\n team: {\n id: 1,\n uuid: 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb',\n organization: 'cccccccc-cccc-cccc-cccc-cccccccccccc',\n api_token: 'phc_mock',\n project_id: 1,\n name: 'Demo team',\n timezone: 'UTC',\n },\n organization: {\n id: 'cccccccc-cccc-cccc-cccc-cccccccccccc',\n name: 'Demo org',\n slug: 'demo-org',\n membership_level: 1,\n },\n organizations: [\n {\n id: 'cccccccc-cccc-cccc-cccc-cccccccccccc',\n name: 'Demo org',\n membership_level: 1,\n },\n ],\n },\n };\n },\n\n runPromptStreaming: ({ signal }) => mockStream(configRef, signal),\n\n probeProjectData: async () => {\n // Brief delay so the Scouting spinner is visible.\n await delay(800);\n return mockProfile(configRef.current.tier);\n },\n\n seedDemoEvents: async ({ baseProfile }) => {\n // No real ingestion in the playground — just show the spinner and\n // return the same seeded profile the production seeder would yield.\n await delay(1500);\n return seededProfile(baseProfile, new Date());\n },\n };\n}\n\nasync function* mockStream(\n configRef: { current: MockConfig },\n signal: AbortSignal,\n): AsyncIterable<AgentChunk> {\n const cfg = configRef.current;\n const chunks = SCRIPTS[cfg.script];\n for (const chunk of chunks) {\n if (signal.aborted) return;\n await delay(cfg.chunkDelayMs);\n if (signal.aborted) return;\n yield chunk;\n }\n}\n\nexport const McpSuggestedPromptsDemo = ({\n store,\n}: McpSuggestedPromptsDemoProps) => {\n const [roleIdx, setRoleIdx] = useState(2); // 'product' — has overrides\n const [familyIdx, setFamilyIdx] = useState(1); // nextjs (fullstack)\n const [tierIdx, setTierIdx] = useState(0); // 'rich' — shows generated quests\n const [resetKey, setResetKey] = useState(0);\n const [loginOutcomeIdx, setLoginOutcomeIdx] = useState(0);\n const [loginDelayIdx, setLoginDelayIdx] = useState(1); // 2000ms default\n const [scriptIdx, setScriptIdx] = useState(1); // 'with-tools' default\n const [chunkDelayIdx, setChunkDelayIdx] = useState(1); // 200ms default\n\n const role = ROLE_CYCLE[roleIdx];\n const integration = FAMILY_INTEGRATIONS[familyIdx];\n const tier = PROBE_TIER_CYCLE[tierIdx];\n const loginOutcome = LOGIN_OUTCOMES[loginOutcomeIdx];\n const loginDelayMs = LOGIN_DELAYS_MS[loginDelayIdx];\n const script = STREAM_SCRIPTS[scriptIdx];\n const chunkDelayMs = CHUNK_DELAYS_MS[chunkDelayIdx];\n\n // Ref-based config so hotkeys can update behavior without remounting.\n const configRef = useRef<MockConfig>({\n role,\n tier,\n loginOutcome,\n loginDelayMs,\n script,\n chunkDelayMs,\n });\n configRef.current = {\n role,\n tier,\n loginOutcome,\n loginDelayMs,\n script,\n chunkDelayMs,\n };\n\n // Stable services instance — reads from configRef each call.\n const services = useMemo(() => createMockServices(store, configRef), [store]);\n\n // Seed framework + a fake \"installed\" MCP state. setMcpComplete here\n // is harmless — production would have set it from the McpScreen step\n // before this screen mounts.\n useEffect(() => {\n store.setMcpComplete(McpOutcome.Installed, ['Claude Code']);\n store.setFrameworkConfig(integration ?? null, null);\n }, [store, integration]);\n\n useInput((input) => {\n if (input === 'R' || input === 'r') {\n setRoleIdx((i) => (i + 1) % ROLE_CYCLE.length);\n setResetKey((k) => k + 1);\n } else if (input === 'F' || input === 'f') {\n setFamilyIdx((i) => (i + 1) % FAMILY_INTEGRATIONS.length);\n setResetKey((k) => k + 1);\n } else if (input === 'T' || input === 't') {\n // Remount so the new tier is re-probed from the Scouting phase.\n setTierIdx((i) => (i + 1) % PROBE_TIER_CYCLE.length);\n setResetKey((k) => k + 1);\n } else if (input === 'X' || input === 'x') {\n store.setCredentials(null);\n store.setRoleAtOrganization(null);\n setResetKey((k) => k + 1);\n } else if (input === 'O' || input === 'o') {\n setLoginOutcomeIdx((i) => (i + 1) % LOGIN_OUTCOMES.length);\n } else if (input === 'L' || input === 'l') {\n setLoginDelayIdx((i) => (i + 1) % LOGIN_DELAYS_MS.length);\n } else if (input === 'S' || input === 's') {\n setScriptIdx((i) => (i + 1) % STREAM_SCRIPTS.length);\n } else if (input === 'C' || input === 'c') {\n setChunkDelayIdx((i) => (i + 1) % CHUNK_DELAYS_MS.length);\n }\n });\n\n const familyLabel = integration ?? 'unknown';\n\n return (\n <Box flexDirection=\"column\" flexGrow={1} paddingX={1}>\n <Text dimColor>\n R role · F framework · T data-tier · X reset · O oauth · L login-delay ·\n S script · C chunk-delay\n </Text>\n <Text dimColor>\n role={String(role)} · integration={familyLabel} · tier={tier} · login=\n {loginOutcome}/{loginDelayMs}ms · script={script}/{chunkDelayMs}ms\n </Text>\n <Box marginTop={1} flexDirection=\"column\" flexGrow={1}>\n <McpSuggestedPromptsScreen\n key={resetKey}\n store={store}\n services={services}\n />\n </Box>\n <Box marginTop={1}>\n <Text color={Colors.muted} dimColor>\n (mock services — no real OAuth, no real LLM. Press R/F to preview\n different prompt kits; O/L/S/C to flip mock outcomes.)\n </Text>\n </Box>\n </Box>\n );\n};\n","/**\n * KeyboardHintsDemo — Demonstrates the KeyboardHintsBar with all input types.\n *\n * Cycles through SinglePicker, MultiPicker, GroupedPicker, and Confirmation\n * so the user can see the hints bar update automatically for each component.\n * The bar appears at the bottom of the screen and stays visible, updating to\n * match the active component.\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, type ReactNode } from 'react';\nimport {\n PickerMenu,\n GroupedPickerMenu,\n ConfirmationInput,\n} from '@tui/primitives/index';\nimport { Colors } from '@tui/styles';\n\nenum DemoStep {\n SingleSelect = 'single',\n MultiSelect = 'multi',\n GroupedSelect = 'grouped',\n Confirmation = 'confirm',\n Done = 'done',\n}\n\nconst STEP_LABELS: Record<DemoStep, string> = {\n [DemoStep.SingleSelect]: 'Single Select — hints: ↑↓ navigate, enter select',\n [DemoStep.MultiSelect]:\n 'Multi Select — hints: ↑↓ navigate, enter select, arrow to Confirm + enter to submit',\n [DemoStep.GroupedSelect]:\n 'Grouped Select — hints: ↑↓ navigate, enter select, a toggle all, arrow to Confirm + enter to submit',\n [DemoStep.Confirmation]:\n 'Confirmation — hints: ←→ switch, enter confirm, esc cancel',\n [DemoStep.Done]: 'Done',\n};\n\nexport const KeyboardHintsDemo = () => {\n const [step, setStep] = useState<DemoStep>(DemoStep.SingleSelect);\n const [log, setLog] = useState<string[]>([]);\n\n const addLog = (msg: string) => setLog((prev) => [...prev.slice(-4), msg]);\n\n if (step === DemoStep.SingleSelect) {\n return (\n <Wrapper step={step} log={log}>\n <PickerMenu\n message=\"Pick a framework\"\n options={[\n { label: 'Next.js', value: 'next' },\n { label: 'React', value: 'react' },\n { label: 'Vue', value: 'vue' },\n { label: 'Svelte', value: 'svelte' },\n ]}\n columns={2}\n onSelect={(v) => {\n addLog(`Single: ${String(v)}`);\n setStep(DemoStep.MultiSelect);\n }}\n />\n </Wrapper>\n );\n }\n\n if (step === DemoStep.MultiSelect) {\n return (\n <Wrapper step={step} log={log}>\n <PickerMenu\n message=\"Pick features to enable\"\n mode=\"multi\"\n options={[\n { label: 'Analytics', value: 'analytics' },\n { label: 'Session Replay', value: 'replay' },\n { label: 'Feature Flags', value: 'flags' },\n { label: 'Surveys', value: 'surveys' },\n ]}\n onSelect={(values) => {\n const arr = Array.isArray(values) ? values : [values];\n addLog(`Multi: ${arr.join(', ')}`);\n setStep(DemoStep.GroupedSelect);\n }}\n />\n </Wrapper>\n );\n }\n\n if (step === DemoStep.GroupedSelect) {\n return (\n <Wrapper step={step} log={log}>\n <GroupedPickerMenu\n message=\"Select integrations\"\n groups={{\n Frontend: [\n { label: 'React SDK', value: 'react-sdk' },\n { label: 'Web Analytics', value: 'web-analytics' },\n ],\n Backend: [\n { label: 'Node SDK', value: 'node-sdk' },\n { label: 'Python SDK', value: 'python-sdk' },\n ],\n Tooling: [\n { label: 'MCP Server', value: 'mcp' },\n { label: 'CLI', value: 'cli' },\n ],\n }}\n onSelect={(values) => {\n addLog(`Grouped: ${values.join(', ')}`);\n setStep(DemoStep.Confirmation);\n }}\n />\n </Wrapper>\n );\n }\n\n if (step === DemoStep.Confirmation) {\n return (\n <Wrapper step={step} log={log}>\n <ConfirmationInput\n message=\"Apply these settings?\"\n onConfirm={() => {\n addLog('Confirmed!');\n setStep(DemoStep.Done);\n }}\n onCancel={() => {\n addLog('Cancelled');\n setStep(DemoStep.Done);\n }}\n />\n </Wrapper>\n );\n }\n\n return (\n <Wrapper step={step} log={log}>\n <Text dimColor>\n All steps complete. Switch away from this tab and back to restart.\n </Text>\n </Wrapper>\n );\n};\n\nconst Wrapper = ({\n step,\n log,\n children,\n}: {\n step: DemoStep;\n log: string[];\n children: ReactNode;\n}) => (\n <Box flexDirection=\"column\">\n <Text bold color={Colors.accent}>\n Keyboard Hints Demo\n </Text>\n <Text dimColor>{STEP_LABELS[step]}</Text>\n <Box height={1} />\n {children}\n {log.length > 0 && (\n <>\n <Box height={1} />\n <Text dimColor>Log:</Text>\n {log.map((entry, i) => (\n <Text key={i} color={Colors.muted}>\n {' '}\n {entry}\n </Text>\n ))}\n </>\n )}\n </Box>\n);\n","/**\n * AuditChecksDemo — renders the AuditChecksViewer against a mock ledger so\n * the scroll/expand/sort behavior can be verified in the playground without\n * running the actual audit agent.\n */\n\nimport { Box } from 'ink';\nimport type { AuditCheck } from '@programs/audit/types';\nimport { AuditChecksViewer } from '@tui/programs/audit/screens/AuditChecksViewer/AuditChecksViewer';\n\nconst MOCK_CHECKS: AuditCheck[] = [\n {\n id: 'sdk-installed',\n area: 'Installation',\n label: 'PostHog SDK installed',\n status: 'pass',\n file: 'package.json',\n details: 'posthog-js@1.260.0 found in dependencies.',\n },\n {\n id: 'sdk-up-to-date',\n area: 'Installation',\n label: 'SDK version up to date',\n status: 'warning',\n details: 'installed 1.260.0, latest 1.372.6 — more than one minor behind.',\n },\n {\n id: 'init-correct',\n area: 'Installation',\n label: 'Initialization is correct',\n status: 'warning',\n file: 'index.js:12',\n details:\n 'Init runs at module load with no singleton guard; calling posthog.init() multiple times can cause duplicate events.',\n },\n {\n id: 'identify-stable-distinct-id',\n area: 'Identification',\n label: 'Stable distinct_id (not session UUID)',\n status: 'error',\n file: 'index.js:18',\n details:\n 'distinct_id is crypto.randomUUID() — a per-session ephemeral UUID that resets on every page load. Replace with an authenticated user id.',\n },\n {\n id: 'identify-not-late',\n area: 'Identification',\n label: 'identify() called before captures / flag evals',\n status: 'pass',\n file: 'index.js:18',\n details:\n 'posthog.identify() is called before any posthog.capture() calls in this module.',\n },\n {\n id: 'cross-runtime-distinct-id',\n area: 'Identification',\n label: 'Same distinct_id across client and server',\n status: 'pass',\n details: 'Single runtime — no cross-runtime check needed.',\n },\n {\n id: 'identify-reset-on-logout',\n area: 'Identification',\n label: 'reset() called on logout / account switch',\n status: 'error',\n file: 'auth.ts:44',\n details:\n 'signOut() clears app auth state but never calls posthog.reset(), so the next identify() on this device can merge into the prior user profile.',\n },\n {\n id: 'capture-event-names-static',\n area: 'Event Capture',\n label: 'Event names are static and consistent',\n status: 'pass',\n file: 'index.js:21',\n details:\n \"All posthog.capture() calls use static string literals ('pageview', 'cta_clicked'); no template literals or dynamic variables found.\",\n },\n {\n id: 'capture-uses-proxy',\n area: 'Event Capture',\n label: 'Captures route through a reverse proxy',\n status: 'warning',\n file: 'index.js:13',\n details:\n 'api_host is set to the default PostHog US ingest host (https://us.i.posthog.com) rather than a first-party reverse proxy — ad/tracking blockers can silently drop these events.',\n },\n {\n id: 'capture-growth-events',\n area: 'Event Capture',\n label: 'Key activation events captured',\n status: 'pending',\n },\n];\n\nexport const AuditChecksDemo = () => (\n <Box flexDirection=\"column\" flexGrow={1}>\n <AuditChecksViewer checks={MOCK_CHECKS} />\n </Box>\n);\n","/**\n * LearnDeckDemo — flip through every program's content deck one block at\n * a time so wording, pauses, and visual blocks can be reviewed without\n * waiting for the auto-advance timer.\n *\n * n / p step block (next / previous)\n * [ / ] switch deck\n * r replay current block (re-runs the reveal animation)\n *\n * Arrow keys are reserved for the playground's tab switcher, so this demo\n * uses letter keys.\n *\n * Decks are pulled from `PROGRAM_REGISTRY` so every program that ships a\n * deck is reviewable here. Migration also gets per-variant entries (one\n * per `--product=<id>` choice) so the variant composer in\n * `migration/content/index.tsx` can be exercised side-by-side with the\n * generic deck.\n */\n\nimport { Box, Text, useInput } from 'ink';\nimport { useMemo, useState } from 'react';\nimport {\n ContentSequencer,\n ProgressList,\n SplitView,\n TextRevealMode,\n} from '@tui/primitives/index';\nimport type { ContentBlock, ProgressItem } from '@tui/primitives/index';\nimport { Colors } from '@tui/styles';\nimport type { WizardStore } from '@tui/store';\nimport { PROGRAM_REGISTRY } from '@programs';\nimport { AUDIT_AREA_SLIDES } from '@tui/programs/audit/screens/slides/index';\nimport type { AreaSlide } from '@tui/programs/audit/screens/slides/shared';\n\ninterface Deck {\n id: string;\n label: string;\n blocks: ContentBlock[];\n}\n\n/**\n * Fake task list to fill the right-hand pane so the SplitView layout matches\n * what operators actually see during a real run. Mix of statuses so the\n * spinner glyph, the in-progress row, and completed rows all render.\n */\nconst MOCK_TASKS: ProgressItem[] = [\n {\n label: 'Confirm Statsig is in use',\n activeForm: 'Confirming Statsig is in use',\n status: 'completed',\n },\n {\n label: 'Install PostHog',\n activeForm: 'Installing PostHog',\n status: 'completed',\n },\n {\n label: 'Plan call site replacements',\n activeForm: 'Planning call site replacements',\n status: 'in_progress',\n },\n {\n label: 'Rewrite call sites',\n activeForm: 'Rewriting call sites',\n status: 'pending',\n },\n {\n label: 'Remove Statsig',\n activeForm: 'Removing Statsig',\n status: 'pending',\n },\n {\n label: 'Verify the project still builds',\n activeForm: 'Verifying the build',\n status: 'pending',\n },\n {\n label: 'Write migration report',\n activeForm: 'Writing migration report',\n status: 'pending',\n },\n];\n\ninterface LearnDeckDemoProps {\n store: WizardStore;\n}\n\nexport const LearnDeckDemo = ({ store }: LearnDeckDemoProps) => {\n const decks: Deck[] = useMemo(() => {\n const all: Deck[] = [];\n\n // Every program in the registry that ships a deck. Seed the store's\n // skillId from the program config so decks that template the skill\n // name (e.g. agent-skill's \"Running the <skill> skill...\") render the\n // real value instead of \"unknown\".\n for (const program of PROGRAM_REGISTRY) {\n if (!program.getContentBlocks) continue;\n const stub = program.skillId\n ? withSessionOverride(store, { skillId: program.skillId })\n : store;\n all.push({\n id: `program:${program.id}`,\n label: `${program.id} (${program.command ?? 'default'})${\n program.skillId ? ` · skill: ${program.skillId}` : ''\n }`,\n blocks: program.getContentBlocks(stub),\n });\n }\n\n // Audit ships its own per-area slide model (not the ContentBlock deck\n // most programs use). Adapt each AreaSlide into a flat ContentBlock\n // list so the flipper can review them the same way.\n all.push({\n id: 'audit:area-slides',\n label: 'audit · area slides',\n blocks: areaSlidesToBlocks(AUDIT_AREA_SLIDES),\n });\n\n return all;\n }, [store]);\n\n const [deckIdx, setDeckIdx] = useState(0);\n const [blockIdx, setBlockIdx] = useState(0);\n const [replayKey, setReplayKey] = useState(0);\n\n const deck = decks[deckIdx];\n const block = deck.blocks[blockIdx];\n\n useInput((input) => {\n if (input === 'p') {\n setBlockIdx((i) => Math.max(0, i - 1));\n } else if (input === 'n') {\n setBlockIdx((i) => Math.min(deck.blocks.length - 1, i + 1));\n } else if (input === '[') {\n setDeckIdx((i) => (i - 1 + decks.length) % decks.length);\n setBlockIdx(0);\n } else if (input === ']') {\n setDeckIdx((i) => (i + 1) % decks.length);\n setBlockIdx(0);\n } else if (input === 'r') {\n setReplayKey((k) => k + 1);\n }\n });\n\n const pauseMs =\n typeof block === 'object' && 'pause' in block ? block.pause : '—';\n const blockKind = describeBlockKind(block);\n\n return (\n <Box flexDirection=\"column\" flexGrow={1} paddingX={1}>\n <Text bold color={Colors.accent}>\n Learn deck flipper\n </Text>\n <Text dimColor>n/p step block · [ ] switch deck · r replay</Text>\n <Box height={1} />\n\n <Text>\n <Text bold>Deck:</Text> {deck.label}{' '}\n <Text dimColor>\n ({deckIdx + 1}/{decks.length})\n </Text>\n </Text>\n <Text>\n <Text bold>Block:</Text> {blockIdx + 1}/{deck.blocks.length}{' '}\n <Text dimColor>\n · kind: {blockKind} · pause: {String(pauseMs)}ms\n </Text>\n </Text>\n <Box height={1} />\n\n <Box flexGrow={1}>\n <SplitView\n left={\n <ContentSequencer\n key={`${deck.id}-${blockIdx}-${replayKey}`}\n blocks={deck.blocks.slice(0, blockIdx + 1)}\n mode={TextRevealMode.SentenceBySentence}\n startDelay={0}\n initialBlockIdx={blockIdx}\n />\n }\n right={<ProgressList items={MOCK_TASKS} title=\"Tasks\" />}\n />\n </Box>\n </Box>\n );\n};\n\n/**\n * Build a store proxy that exposes an overridden `session` while keeping\n * every prototype method (e.g. `setStatusExpanded`) and atom reference\n * intact. A plain `{...store, session: ...}` spread would drop the\n * prototype, so anything that called a store method on the result would\n * crash at render time.\n */\nfunction withSessionOverride(\n store: WizardStore,\n patch: Partial<WizardStore['session']>,\n): WizardStore {\n const stub = Object.create(Object.getPrototypeOf(store)) as WizardStore;\n Object.assign(stub, store);\n Object.defineProperty(stub, 'session', {\n value: { ...store.session, ...patch },\n writable: false,\n configurable: true,\n });\n return stub;\n}\n\n/**\n * Adapter: turn each audit AreaSlide into a sequence of ContentBlocks so it\n * fits the flipper's renderer. One block per intro paragraph, one for the\n * visual when present. Each slide is preceded by a heading block naming the\n * area so flipping between areas is obvious.\n */\nfunction areaSlidesToBlocks(slides: AreaSlide[]): ContentBlock[] {\n const out: ContentBlock[] = [];\n for (const slide of slides) {\n out.push({\n content: (\n <Text bold color={Colors.accent}>\n {slide.area}\n </Text>\n ),\n pause: 3000,\n });\n for (const paragraph of slide.intro) {\n out.push({ content: paragraph, pause: 5000 });\n }\n if (slide.visual) {\n out.push({\n content: slide.visual,\n pause: 8000,\n persist: true,\n });\n }\n out.push({ type: 'clear', pause: 1000 });\n }\n return out;\n}\n\nfunction describeBlockKind(block: ContentBlock): string {\n if (typeof block === 'string') return 'string';\n if (typeof block === 'object' && block !== null) {\n if ('type' in block && block.type === 'clear') return 'clear';\n if ('type' in block && block.type === 'lines') return 'lines';\n if ('content' in block) {\n return typeof block.content === 'string' ? 'text' : 'jsx';\n }\n }\n return 'unknown';\n}\n","/**\n * EndScreensDemo — Playground demo for the screens shown at the end of\n * a wizard run.\n *\n * Mounts the real SlackConnectScreen and OutroScreen against the shared\n * playground store so every variant can be previewed without a run:\n *\n * V switch view (slack-connect → outro)\n * K toggle Slack state (connected ↔ not connected) — simulates the\n * poll flipping the screen when the user finishes the browser OAuth\n * O cycle outro kind (success → error → cancel)\n *\n * The playground credentials are re-pointed at a localhost dead-end\n * while this demo is mounted, so SlackConnectScreen's poll fails fast\n * without real network traffic; `K` drives `session.slackConnected`\n * directly, which is the same store key the poll writes.\n *\n * KeepSkillsScreen is intentionally absent — it reads the install dir's\n * .claude/skills/ from disk and calls process.exit() when none are\n * found, which would kill the playground.\n */\n\nimport { Box, Text, useInput } from 'ink';\nimport { useEffect, useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@tui/store';\nimport { SlackConnectScreen } from '@tui/screens/SlackConnectScreen';\nimport { OutroScreen } from '@tui/screens/OutroScreen';\nimport { Colors } from '@tui/styles';\nimport { OutroKind, type OutroData } from '@programs/session/wizard-session';\nimport { HostResolution } from '@shared/host-resolution';\n\nconst VIEWS = ['slack-connect', 'outro'] as const;\ntype View = (typeof VIEWS)[number];\n\nconst OUTRO_KINDS = [OutroKind.Success, OutroKind.Error, OutroKind.Cancel];\n\nconst OUTRO_FIXTURES: Record<OutroKind, OutroData> = {\n [OutroKind.Success]: {\n kind: OutroKind.Success,\n message: 'PostHog is set up!',\n changes: [\n 'Installed posthog-js and wired the provider',\n 'Added pageview + pageleave capture',\n 'Instrumented 4 product events',\n ],\n reportFile: 'posthog-setup-report.md',\n dashboardUrl: 'https://us.posthog.com/project/1/dashboard/42',\n notebookUrl: 'https://us.posthog.com/project/1/notebooks/demo',\n docsUrl: 'https://posthog.com/docs/libraries/next-js',\n },\n [OutroKind.Error]: {\n kind: OutroKind.Error,\n message: 'The agent hit an error',\n body: 'The integration step failed before any files were changed.\\nRe-run the wizard to try again.',\n docsUrl: 'https://posthog.com/docs/ai-engineering/ai-wizard',\n },\n [OutroKind.Cancel]: {\n kind: OutroKind.Cancel,\n message: 'Cancelled — no changes were made',\n },\n};\n\ninterface EndScreensDemoProps {\n store: WizardStore;\n}\n\nexport const EndScreensDemo = ({ store }: EndScreensDemoProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [viewIdx, setViewIdx] = useState(0);\n const [outroKindIdx, setOutroKindIdx] = useState(0);\n\n const view: View = VIEWS[viewIdx];\n const outroKind = OUTRO_KINDS[outroKindIdx];\n\n // The playground pre-seeds fake credentials pointed at the real\n // PostHog host, which SlackConnectScreen's poll would hit. Swap the\n // host for a localhost dead-end while this demo is mounted (restore\n // on unmount — tab switches unmount). The credentials must stay\n // non-null: the router derives the active screen from session state,\n // and nulling them drops the playground out of the 'run' screen,\n // unmounting the tab bar and resetting it to the first tab.\n useEffect(() => {\n const previous = store.session.credentials;\n store.setCredentials({\n accessToken: 'playground',\n projectApiKey: 'playground',\n host: HostResolution.fromApiHost('http://127.0.0.1:9'),\n projectId: 0,\n });\n return () => {\n store.setCredentials(previous);\n };\n }, [store]);\n\n // Seed the outro fixture each screen reads. slackConnected starts\n // null (unknown) so the first paint shows the nudge variant, exactly\n // like a wizard run before the poll's first response.\n useEffect(() => {\n store.setOutroData(OUTRO_FIXTURES[outroKind]);\n }, [store, outroKind]);\n\n useInput((input) => {\n if (input === 'V' || input === 'v') {\n setViewIdx((i) => (i + 1) % VIEWS.length);\n } else if (input === 'K' || input === 'k') {\n store.setSlackConnected(store.session.slackConnected !== true);\n } else if (input === 'O' || input === 'o') {\n setOutroKindIdx((i) => (i + 1) % OUTRO_KINDS.length);\n }\n });\n\n const slackState =\n store.session.slackConnected === true ? 'connected' : 'not-connected';\n\n return (\n <Box flexDirection=\"column\" flexGrow={1} paddingX={1}>\n <Text dimColor>V view · K slack state · O outro kind</Text>\n <Text dimColor>\n view={view} · slack={slackState} · outro={outroKind}\n </Text>\n <Box marginTop={1} flexDirection=\"column\" flexGrow={1}>\n {view === 'slack-connect' ? (\n <SlackConnectScreen store={store} />\n ) : (\n <OutroScreen store={store} />\n )}\n </Box>\n <Box marginTop={1}>\n <Text color={Colors.muted} dimColor>\n (session-driven previews — the Slack poll points at a localhost\n dead-end; K flips the same store key the poll writes.)\n </Text>\n </Box>\n </Box>\n );\n};\n","/**\n * AiOptInDemo — Playground demo for AiOptInRequiredScreen.\n *\n * Mounts the real screen with a synthetic store pre-populated with an\n * apiUser whose org has `is_ai_data_processing_approved: false`.\n * Variant selection is driven by `membership_level` — admin (>= 8) vs\n * non-admin (< 8), matching what the screen reads in production.\n *\n * One demo function, used by two PlaygroundApp tabs. ⚠ keybindings on\n * the screen are LIVE — [E] exits the playground, [O] opens a real\n * browser URL, [R] fires a network request (which will fail with the\n * fake token, but won't be destructive).\n */\n\nimport { useEffect, useState } from 'react';\nimport { Box, Text } from 'ink';\nimport { WizardStore } from '@tui/store';\nimport { AiOptInRequiredScreen } from '@tui/screens/AiOptInRequiredScreen';\nimport { HostResolution } from '@shared/host-resolution';\n\ntype Variant = 'admin' | 'non-admin';\n\ninterface AiOptInDemoProps {\n variant: Variant;\n}\n\nexport const AiOptInDemo = ({ variant }: AiOptInDemoProps) => {\n const [store] = useState(() => {\n const s = new WizardStore();\n s.setCredentials({\n accessToken: 'demo-fake-token',\n projectApiKey: 'demo-fake-project-key',\n host: HostResolution.fromApiHost('https://us.posthog.com'),\n projectId: 0,\n });\n return s;\n });\n\n useEffect(() => {\n store.session.region = 'us';\n store.setApiUser({\n distinct_id: 'demo-distinct-id',\n email: 'sarah@example.com',\n organization: {\n id: '00000000-0000-0000-0000-000000000000',\n name: 'Demo Org',\n membership_level: variant === 'admin' ? 8 : 1,\n is_ai_data_processing_approved: false,\n } as never,\n organizations: [],\n team: {\n id: 0,\n organization: '00000000-0000-0000-0000-000000000000',\n } as never,\n } as never);\n }, [variant, store]);\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box marginBottom={1}>\n <Text dimColor>\n Playground —{' '}\n <Text bold>\n AiOptInRequiredScreen ({variant === 'admin' ? 'Admin' : 'Non-admin'}\n )\n </Text>\n . Keys are live: [E] exits the playground.\n </Text>\n </Box>\n <AiOptInRequiredScreen store={store} />\n </Box>\n );\n};\n","/**\n * AskModalDemo — Pickers rendered inside an ask-style ModalOverlay, the way\n * WizardAskScreen composes them: prompt paragraph in the modal body, then a\n * label-less PickerMenu. Exercises the viewport height cap (MAX_LIST_ROWS)\n * and the no-label spacing (no stray blank lines under the paragraph).\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, type ReactNode } from 'react';\nimport {\n ModalOverlay,\n PickerMenu,\n GroupedPickerMenu,\n} from '@tui/primitives/index';\nimport { Colors, Icons } from '@tui/styles';\nimport { LONG_OPTIONS } from './InputDemo.js';\n\nenum DemoStep {\n ScoutRepro = 'scout-repro',\n CountLabel100 = 'count-label-100',\n CountLabel10 = 'count-label-10',\n CountLabel2 = 'count-label-2',\n CountLabel1 = 'count-label-1',\n CountDesc100 = 'count-desc-100',\n CountDesc10 = 'count-desc-10',\n CountDesc2 = 'count-desc-2',\n CountDesc1 = 'count-desc-1',\n MultiLong = 'multi-long',\n MultiDescriptions = 'multi-descriptions',\n Single = 'single',\n Grouped = 'grouped',\n Done = 'done',\n}\n\n/** Label-only options at a given count, e.g. \"Option 1\" ... \"Option 100\". */\nconst countLabelOptions = (n: number) =>\n Array.from({ length: n }, (_, i) => ({\n label: `Option ${i + 1}`,\n value: `opt-${i + 1}`,\n }));\n\n/** Options at a given count, each with a wrapping description so rows are tall. */\nconst countDescOptions = (n: number) =>\n Array.from({ length: n }, (_, i) => ({\n label: `Option ${i + 1}`,\n value: `opt-${i + 1}`,\n description:\n 'A longer description that wraps onto multiple lines so each option row costs several terminal rows, exercising the viewport cap and the paging math at small counts.',\n }));\n\n/** Repro of the scout-proposal ask that paged 3 tall described options one per page. */\nconst SCOUT_REPRO_OPTIONS = [\n {\n label: 'None — keep the built-in troop',\n value: 'none',\n description:\n 'Skip custom scouts; the built-in troop already covers this project well enough, and adding more scheduled checks would mostly duplicate the coverage you already get out of the box.',\n },\n {\n label: 'Playground snapshot drift scout',\n value: 'snapshot-drift',\n description:\n 'Watches CI snapshot runs and flags visual drift in the playground demos before it reaches a release, so a rendering regression in a picker or overlay never ships to users unnoticed.',\n },\n {\n label: 'Benchmark regression scout',\n value: 'benchmark',\n description:\n 'Tracks wizard-benchmark timings week over week and opens an issue when a run regresses past the recorded baseline, catching slow drift in agent latency before customers feel it.',\n },\n];\n\nconst DESCRIBED_OPTIONS = [\n {\n label: 'Session replay',\n value: 'replay',\n description:\n 'Record and replay real user sessions to see exactly what happened before an error or a rage click.',\n },\n {\n label: 'Feature flags',\n value: 'flags',\n description:\n 'Roll features out gradually, target by cohort, and kill misbehaving code paths without a deploy.',\n },\n {\n label: 'Error tracking',\n value: 'errors',\n description: 'Capture exceptions with stack traces and source maps.',\n },\n];\n\nconst GROUPED = {\n 'Issue trackers': [\n { label: 'GitHub Issues', value: 'github' },\n { label: 'Linear', value: 'linear' },\n { label: 'Jira', value: 'jira' },\n { label: 'Shortcut', value: 'shortcut' },\n ],\n 'Error monitoring': [\n { label: 'Sentry', value: 'sentry' },\n { label: 'Rollbar', value: 'rollbar' },\n { label: 'Bugsnag', value: 'bugsnag' },\n { label: 'Honeybadger', value: 'honeybadger' },\n ],\n 'Support desks': [\n { label: 'Zendesk', value: 'zendesk' },\n { label: 'Freshdesk', value: 'freshdesk' },\n { label: 'Front', value: 'front' },\n { label: 'Intercom', value: 'intercom' },\n ],\n Observability: [\n { label: 'Datadog', value: 'datadog' },\n { label: 'New Relic', value: 'newrelic' },\n { label: 'Grafana', value: 'grafana' },\n { label: 'Splunk', value: 'splunk' },\n ],\n};\n\n/** Mirrors WizardAskScreen's shape: paragraph body, then a label-less input. */\nconst AskModal = ({\n prompt,\n children,\n}: {\n prompt: string;\n children: ReactNode;\n}) => (\n <ModalOverlay\n borderColor={Colors.accent}\n title={`${Icons.diamond} self-driving-setup`}\n titleColor={Colors.accent}\n width={72}\n >\n <Box flexDirection=\"column\">\n <Text>{prompt}</Text>\n </Box>\n <Box marginTop={1}>{children}</Box>\n </ModalOverlay>\n);\n\nexport const AskModalDemo = () => {\n const [step, setStep] = useState<DemoStep>(DemoStep.ScoutRepro);\n const [results, setResults] = useState<string[]>([]);\n\n const advance = (result: string, next: DemoStep) => {\n setResults((prev) => [...prev, result]);\n setStep(next);\n };\n\n const countLabelSteps: Partial<\n Record<DemoStep, { next: DemoStep; count: number }>\n > = {\n [DemoStep.CountLabel100]: {\n next: DemoStep.CountLabel10,\n count: 100,\n },\n [DemoStep.CountLabel10]: { next: DemoStep.CountLabel2, count: 10 },\n [DemoStep.CountLabel2]: { next: DemoStep.CountLabel1, count: 2 },\n [DemoStep.CountLabel1]: { next: DemoStep.CountDesc100, count: 1 },\n };\n\n const countDescSteps: Partial<\n Record<DemoStep, { next: DemoStep; count: number }>\n > = {\n [DemoStep.CountDesc100]: { next: DemoStep.CountDesc10, count: 100 },\n [DemoStep.CountDesc10]: { next: DemoStep.CountDesc2, count: 10 },\n [DemoStep.CountDesc2]: { next: DemoStep.CountDesc1, count: 2 },\n [DemoStep.CountDesc1]: { next: DemoStep.MultiLong, count: 1 },\n };\n\n if (step === DemoStep.ScoutRepro) {\n return (\n <AskModal prompt=\"Scouts are scheduled checks that watch your data and flag issues for your inbox. Based on your repo I found two gaps the built-in troop doesn't cover — add one, both, or none. (Repro: 3 described options must stay on ONE page even in a short terminal.)\">\n <PickerMenu\n key={step}\n mode=\"multi\"\n optionMarginBottom={1}\n options={SCOUT_REPRO_OPTIONS}\n onSelect={(values) => {\n const arr = Array.isArray(values) ? values : [values];\n advance(\n `Scout repro: ${arr.length} picked`,\n DemoStep.CountLabel100,\n );\n }}\n />\n </AskModal>\n );\n }\n\n const labelStep = countLabelSteps[step];\n if (labelStep) {\n const { count, next } = labelStep;\n return (\n <AskModal\n prompt={`Multi-select — ${count} label-only option${\n count === 1 ? '' : 's'\n }. Watch whether ${\n count <= 2 ? 'this tiny list still pages' : 'paging kicks in'\n }.`}\n >\n <PickerMenu\n key={step}\n mode=\"multi\"\n options={countLabelOptions(count)}\n onSelect={(values) => {\n const arr = Array.isArray(values) ? values : [values];\n advance(`Count label (${count}): ${arr.length} picked`, next);\n }}\n />\n </AskModal>\n );\n }\n\n const descStep = countDescSteps[step];\n if (descStep) {\n const { count, next } = descStep;\n return (\n <AskModal\n prompt={`Multi-select — ${count} option${\n count === 1 ? '' : 's'\n } with wrapping descriptions (tall rows). ${\n count <= 2\n ? 'This is where a tiny list can still split into multiple pages.'\n : ''\n }`}\n >\n <PickerMenu\n key={step}\n mode=\"multi\"\n optionMarginBottom={1}\n options={countDescOptions(count)}\n onSelect={(values) => {\n const arr = Array.isArray(values) ? values : [values];\n advance(`Count desc (${count}): ${arr.length} picked`, next);\n }}\n />\n </AskModal>\n );\n }\n\n if (step === DemoStep.MultiLong) {\n return (\n <AskModal prompt=\"Self-driving can also watch your other tools and investigate and fix the problems they surface. Which of these do you use?\">\n <PickerMenu\n key={step}\n mode=\"multi\"\n options={LONG_OPTIONS}\n onSelect={(values) => {\n const arr = Array.isArray(values) ? values : [values];\n advance(\n `Multi (long): ${arr.length} picked`,\n DemoStep.MultiDescriptions,\n );\n }}\n />\n </AskModal>\n );\n }\n\n if (step === DemoStep.MultiDescriptions) {\n return (\n <AskModal prompt=\"Besides analytics, which PostHog products should the agent set up while it's in the codebase?\">\n <PickerMenu\n key={step}\n mode=\"multi\"\n optionMarginBottom={1}\n options={DESCRIBED_OPTIONS}\n onSelect={(values) => {\n const arr = Array.isArray(values) ? values : [values];\n advance(\n `Multi (descriptions): ${arr.join(', ') || 'none'}`,\n DemoStep.Single,\n );\n }}\n />\n </AskModal>\n );\n }\n\n if (step === DemoStep.Single) {\n return (\n <AskModal prompt=\"Your project has both an app and a marketing site. Which one should the agent instrument first?\">\n <PickerMenu<string>\n options={[\n { label: 'The app', value: 'app', hint: 'src/app' },\n { label: 'The marketing site', value: 'marketing', hint: 'www/' },\n { label: 'Both, app first', value: 'both' },\n ]}\n onSelect={(value) => {\n advance(`Single: ${String(value)}`, DemoStep.Grouped);\n }}\n />\n </AskModal>\n );\n }\n\n if (step === DemoStep.Grouped) {\n return (\n <AskModal prompt=\"Grouped variant of the same ask — categories with headers, everything pre-selected:\">\n <GroupedPickerMenu\n groups={GROUPED}\n onSelect={(values) => {\n advance(`Grouped: ${values.length} kept`, DemoStep.Done);\n }}\n />\n </AskModal>\n );\n }\n\n return (\n <Box flexDirection=\"column\">\n <Text bold color={Colors.accent}>\n Ask Modal Demo — Results\n </Text>\n <Box height={1} />\n {results.map((r, i) => (\n <Text key={i} color={Colors.success}>\n {'✔'} {r}\n </Text>\n ))}\n <Box height={1} />\n <Text dimColor>Switch away from this tab and back to restart.</Text>\n </Box>\n );\n};\n","/**\n * ViewportGuardDemo — Playground demo for the ViewportTooSmall primitive.\n *\n * The real thing only appears when the terminal drops below the minimum, at\n * which point the playground itself is hidden behind it — so render it here at\n * a couple of fake sizes to see the copy and the wrapping.\n */\n\nimport { Box, Text } from 'ink';\nimport {\n ViewportTooSmall,\n MIN_VIEWPORT_COLUMNS,\n MIN_VIEWPORT_ROWS,\n} from '@tui/primitives/index';\n\nconst SAMPLES: Array<[number, number]> = [\n [70, 8],\n [40, 7],\n];\n\nexport const ViewportGuardDemo = () => {\n return (\n <Box flexDirection=\"column\" gap={1} flexGrow={1}>\n <Text dimColor>\n {`Shown full-screen whenever the terminal is under ${MIN_VIEWPORT_COLUMNS}×${MIN_VIEWPORT_ROWS} — shrink this window to see it for real.`}\n </Text>\n {SAMPLES.map(([columns, rows]) => (\n <Box key={`${columns}x${rows}`} flexDirection=\"column\">\n <Text dimColor>{`at ${columns}×${rows}:`}</Text>\n <ViewportTooSmall columns={columns} rows={rows} />\n </Box>\n ))}\n </Box>\n );\n};\n","/**\n * PlaygroundApp — Root component for the primitives playground.\n *\n * Two screens mirroring the real wizard flow:\n * intro → (press enter) → run (tabbed demo view)\n */\n\nimport { ScreenContainer, TabContainer } from '@tui/primitives/index';\nimport type { WizardStore } from '@tui/store';\nimport { WelcomeDemo } from './demos/WelcomeDemo.js';\nimport { LayoutDemo } from './demos/LayoutDemo.js';\nimport { InputDemo } from './demos/InputDemo.js';\nimport { ProgressDemo } from './demos/ProgressDemo.js';\nimport { LogDemo } from './demos/LogDemo.js';\nimport { RunScreenDemo } from './demos/RunScreenDemo.js';\nimport { HealthCheckDemo } from './demos/HealthCheckDemo.js';\nimport { DoctorReportDemo } from './demos/DoctorReportDemo.js';\nimport { ModalDemo } from './demos/ModalDemo.js';\nimport { McpDemo } from './demos/McpDemo.js';\nimport { McpSuggestedPromptsDemo } from './demos/McpSuggestedPromptsDemo.js';\nimport { KeyboardHintsDemo } from './demos/KeyboardHintsDemo.js';\nimport { AuditChecksDemo } from './demos/AuditChecksDemo.js';\nimport { LearnDeckDemo } from './demos/LearnDeckDemo.js';\nimport { EndScreensDemo } from './demos/EndScreensDemo.js';\nimport { AiOptInDemo } from './demos/AiOptInDemo.js';\nimport { AskModalDemo } from './demos/AskModalDemo.js';\nimport { ViewportGuardDemo } from './demos/ViewportGuardDemo.js';\n\ninterface PlaygroundAppProps {\n store: WizardStore;\n}\n\nexport const PlaygroundApp = ({ store }: PlaygroundAppProps) => {\n const tabs = [\n { id: 'layout', label: 'Layout', component: <LayoutDemo /> },\n { id: 'input', label: 'Input', component: <InputDemo /> },\n { id: 'ask-modal', label: 'Ask modal', component: <AskModalDemo /> },\n { id: 'progress', label: 'Progress', component: <ProgressDemo /> },\n { id: 'logs', label: 'Logs', component: <LogDemo /> },\n {\n id: 'run',\n label: 'RunScreen',\n component: <RunScreenDemo store={store} />,\n },\n {\n id: 'health',\n label: 'HealthCheck',\n component: <HealthCheckDemo />,\n },\n {\n id: 'doctor',\n label: 'Doctor',\n component: <DoctorReportDemo />,\n },\n {\n id: 'modal',\n label: 'Modal',\n component: <ModalDemo />,\n },\n {\n id: 'mcp',\n label: 'MCP',\n component: <McpDemo store={store} />,\n },\n {\n id: 'mcp-tutorial',\n label: 'MCP tutorial',\n component: <McpSuggestedPromptsDemo store={store} />,\n },\n {\n id: 'hints',\n label: 'KeyHints',\n component: <KeyboardHintsDemo />,\n },\n {\n id: 'audit-checks',\n label: 'Audit checks',\n component: <AuditChecksDemo />,\n },\n {\n id: 'learn-deck',\n label: 'Learn deck',\n component: <LearnDeckDemo store={store} />,\n },\n {\n id: 'end-screens',\n label: 'End screens',\n component: <EndScreensDemo store={store} />,\n },\n {\n id: 'ai-opt-in-admin',\n label: 'AI opt-in (admin)',\n component: <AiOptInDemo variant=\"admin\" />,\n },\n {\n id: 'ai-opt-in-nonadmin',\n label: 'AI opt-in (non-admin)',\n component: <AiOptInDemo variant=\"non-admin\" />,\n },\n {\n id: 'viewport-guard',\n label: 'Viewport guard',\n component: <ViewportGuardDemo />,\n },\n ];\n\n return (\n <ScreenContainer\n store={store}\n screens={{\n intro: <WelcomeDemo store={store} />,\n run: (\n <TabContainer\n tabs={tabs}\n statusMessage=\"Primitives Playground — use arrow keys to switch tabs\"\n />\n ),\n }}\n />\n );\n};\n","/**\n * start-playground.ts — Launches the TUI primitives playground.\n */\n\nimport { render } from 'ink';\nimport { createElement } from 'react';\nimport { WizardStore } from '@tui/store';\nimport { PlaygroundApp } from './PlaygroundApp.js';\nimport { HostResolution } from '@shared/host-resolution';\nimport { WizardReadiness } from '@shared/health-checks/readiness';\nimport { enterDarkTerminal, releaseTerminal } from '../terminal.js';\n\nexport function startPlayground(version: string): void {\n enterDarkTerminal();\n\n const store = new WizardStore();\n store.version = version;\n\n // Pre-fill session so the router skips health-check, auth, and setup,\n // landing on 'run' after the intro screen.\n // dismissOutage() guards against the onInit health-check async result\n // overwriting this with WizardReadiness.No before the user presses enter.\n store.setReadinessResult({\n decision: WizardReadiness.Yes,\n health: {} as never,\n reasons: [],\n });\n store.dismissOutage();\n store.setCredentials({\n accessToken: 'fake',\n projectApiKey: 'fake',\n host: HostResolution.fromApiHost('https://app.posthog.com'),\n projectId: 0,\n });\n\n const { unmount, waitUntilExit } = render(\n createElement(PlaygroundApp, { store }),\n );\n\n void waitUntilExit().then(() => {\n unmount();\n releaseTerminal();\n process.exit(0);\n });\n}\n","import { VERSION } from '@shared/version';\nimport { startPlayground } from '@tui/playground/start-playground';\n\n/** Launch the TUI primitives playground. */\nexport function runPlayground(): void {\n startPlayground(VERSION);\n}\n"],"mappings":"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"}
|
package/dist/posthog-B2E0hpZt.js
DELETED