@posthog/wizard 2.69.0 → 2.70.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/dist/{add-mcp-server-to-clients-Cl2HBuxp.js → add-mcp-server-to-clients-BCnjUqnW.js} +4 -4
- package/dist/{add-mcp-server-to-clients-Cl2HBuxp.js.map → add-mcp-server-to-clients-BCnjUqnW.js.map} +1 -1
- package/dist/{agent-interface-CI89BrWE.js → agent-interface-Lu7tnLr0.js} +8 -8
- package/dist/{agent-interface-CI89BrWE.js.map → agent-interface-Lu7tnLr0.js.map} +1 -1
- package/dist/{agent-prompt-loader-Dc1g5Oub.js → agent-prompt-loader-y5GxgEkc.js} +5 -5
- package/dist/{agent-prompt-loader-Dc1g5Oub.js.map → agent-prompt-loader-y5GxgEkc.js.map} +1 -1
- package/dist/{agent-runner-D5dhuE4z.js → agent-runner-vKtpgqVI.js} +21 -16
- package/dist/agent-runner-vKtpgqVI.js.map +1 -0
- package/dist/analytics-D-bMEYjD.js +2 -0
- package/dist/{analytics-D90QbLf5.js → analytics-DTyJClPr.js} +13 -3
- package/dist/analytics-DTyJClPr.js.map +1 -0
- package/dist/{api-BHhrT6wb.js → api-j-OfJ8Dz.js} +3 -3
- package/dist/{api-BHhrT6wb.js.map → api-j-OfJ8Dz.js.map} +1 -1
- package/dist/bin.js +61 -56
- package/dist/bin.js.map +1 -1
- package/dist/{bounded-fs-BhlVkP1r.js → bounded-fs-BWX25ixc.js} +3 -3
- package/dist/{bounded-fs-BhlVkP1r.js.map → bounded-fs-BWX25ixc.js.map} +1 -1
- package/dist/{ci-install-94wC3a4K.js → ci-install-zNWgp1TL.js} +4 -4
- package/dist/{ci-install-94wC3a4K.js.map → ci-install-zNWgp1TL.js.map} +1 -1
- package/dist/{debug-CifTS9lQ.js → debug-BM0fZaGl.js} +3 -3
- package/dist/{debug-CifTS9lQ.js.map → debug-BM0fZaGl.js.map} +1 -1
- package/dist/{debug-DtixqVEY.js → debug-xr2Pq5VA.js} +1 -1
- package/dist/{env-api-key-CwhtZrik.js → env-api-key-DlxCZWU0.js} +2 -2
- package/dist/{env-api-key-CwhtZrik.js.map → env-api-key-DlxCZWU0.js.map} +1 -1
- package/dist/{environment-DhacWZf7.js → environment-o-bTOuzK.js} +4 -4
- package/dist/{environment-DhacWZf7.js.map → environment-o-bTOuzK.js.map} +1 -1
- package/dist/{file-watcher-L28OpUV2.js → file-watcher-D7G4f5sP.js} +2 -2
- package/dist/{file-watcher-L28OpUV2.js.map → file-watcher-D7G4f5sP.js.map} +1 -1
- package/dist/{headless-ui-DNcOVJxU.js → headless-ui-C46DctKG.js} +2 -2
- package/dist/{headless-ui-DNcOVJxU.js.map → headless-ui-C46DctKG.js.map} +1 -1
- package/dist/{interactive-DlNrV77o.js → interactive-B5zy3Gxk.js} +2 -2
- package/dist/{interactive-DlNrV77o.js.map → interactive-B5zy3Gxk.js.map} +1 -1
- package/dist/{mcp-CJEem9qs.js → mcp-lJRwE-YW.js} +2 -2
- package/dist/{mcp-CJEem9qs.js.map → mcp-lJRwE-YW.js.map} +1 -1
- package/dist/{mcp-prompt-streaming-DER7MG3q.js → mcp-prompt-streaming-Dsos09hT.js} +4 -4
- package/dist/{mcp-prompt-streaming-DER7MG3q.js.map → mcp-prompt-streaming-Dsos09hT.js.map} +1 -1
- package/dist/{non-interactive-CbvniKHm.js → non-interactive-qcCCtiYQ.js} +2 -2
- package/dist/{non-interactive-CbvniKHm.js.map → non-interactive-qcCCtiYQ.js.map} +1 -1
- package/dist/{orchestrator-tools-Czf3Wo_y.js → orchestrator-tools-ezFTbAIp.js} +3 -3
- package/dist/{orchestrator-tools-Czf3Wo_y.js.map → orchestrator-tools-ezFTbAIp.js.map} +1 -1
- package/dist/{package-json-GEU2VZlS.js → package-json-xt3eeyBI.js} +1 -1
- package/dist/{package-json-GEU2VZlS.js.map → package-json-xt3eeyBI.js.map} +1 -1
- package/dist/{package-manager-CNNlFA2q.js → package-manager-CGfN9UhH.js} +2 -2
- package/dist/{package-manager-CNNlFA2q.js.map → package-manager-CGfN9UhH.js.map} +1 -1
- package/dist/{pi-kpN-bO9z.js → pi-DzQLHIcQ.js} +11 -11
- package/dist/{pi-kpN-bO9z.js.map → pi-DzQLHIcQ.js.map} +1 -1
- package/dist/{playground-ZYaQmfBa.js → playground-DLN31BPV.js} +7 -7
- package/dist/{playground-ZYaQmfBa.js.map → playground-DLN31BPV.js.map} +1 -1
- package/dist/{posthog-D1zHPgYJ.js → posthog-Dxr8XK4x.js} +2 -2
- package/dist/{posthog-D1zHPgYJ.js.map → posthog-Dxr8XK4x.js.map} +1 -1
- package/dist/{posthog-integration-DdeIUkYw.js → posthog-integration-MDfRO911.js} +93 -29
- package/dist/posthog-integration-MDfRO911.js.map +1 -0
- package/dist/{provisioning-e3roaLgp.js → provisioning-Di5GNV9k.js} +3 -3
- package/dist/{provisioning-e3roaLgp.js.map → provisioning-Di5GNV9k.js.map} +1 -1
- package/dist/{queue-tools-zrqCiy6q.js → queue-tools-KosDptd6.js} +3 -3
- package/dist/{queue-tools-zrqCiy6q.js.map → queue-tools-KosDptd6.js.map} +1 -1
- package/dist/{registry-C1t8v5tE.js → registry-BBdaIFWq.js} +6 -6
- package/dist/{registry-C1t8v5tE.js.map → registry-BBdaIFWq.js.map} +1 -1
- package/dist/{security-CIfhIscL.js → security-BwOvjMaq.js} +5 -5
- package/dist/{security-CIfhIscL.js.map → security-BwOvjMaq.js.map} +1 -1
- package/dist/{setup-utils-B_06xag2.js → setup-utils-Bo3WZt3a.js} +9 -9
- package/dist/{setup-utils-B_06xag2.js.map → setup-utils-Bo3WZt3a.js.map} +1 -1
- package/dist/{start-tui-BafJXVNT.js → start-tui-B1LrB7k1.js} +288 -133
- package/dist/start-tui-B1LrB7k1.js.map +1 -0
- package/dist/{steps-DR-Yo_IT.js → steps-BMrQJpQh.js} +7 -7
- package/dist/{steps-DR-Yo_IT.js.map → steps-BMrQJpQh.js.map} +1 -1
- package/dist/{store-DSUCWMRO.js → store-DhNTBWQR.js} +40 -6
- package/dist/store-DhNTBWQR.js.map +1 -0
- package/dist/{subagent-DjZM3G7y.js → subagent-q6M-mBHo.js} +2 -2
- package/dist/{subagent-DjZM3G7y.js.map → subagent-q6M-mBHo.js.map} +1 -1
- package/dist/{task-Czzz3tzt.js → task-CgAOxod7.js} +12 -12
- package/dist/{task-Czzz3tzt.js.map → task-CgAOxod7.js.map} +1 -1
- package/dist/{task-stream-uxG6wJfj.js → task-stream-rxR1IsdJ.js} +5 -5
- package/dist/{task-stream-uxG6wJfj.js.map → task-stream-rxR1IsdJ.js.map} +1 -1
- package/dist/{tasks-CVmG8qFw.js → tasks-lzvWF__k.js} +2 -2
- package/dist/{tasks-CVmG8qFw.js.map → tasks-lzvWF__k.js.map} +1 -1
- package/dist/{telemetry-B1VEXHpL.js → telemetry-CickTk_7.js} +3 -3
- package/dist/{telemetry-B1VEXHpL.js.map → telemetry-CickTk_7.js.map} +1 -1
- package/dist/{terminal-Czuo0x8i.js → terminal-BjUFxn_x.js} +12 -12
- package/dist/{terminal-Czuo0x8i.js.map → terminal-BjUFxn_x.js.map} +1 -1
- package/dist/{tools-DOZg9n3A.js → tools-MKXGXFSk.js} +6 -6
- package/dist/{tools-DOZg9n3A.js.map → tools-MKXGXFSk.js.map} +1 -1
- package/dist/{wizard-abort-BZOeapsf.js → wizard-abort-CW_C2EXr.js} +1 -1
- package/dist/{wizard-abort-CFMdj6sZ.js → wizard-abort-CooWEh9N.js} +4 -4
- package/dist/{wizard-abort-CFMdj6sZ.js.map → wizard-abort-CooWEh9N.js.map} +1 -1
- package/dist/{wizard-session-C_7r3-rO.js → wizard-session-Bki7dQhv.js} +12 -2
- package/dist/wizard-session-Bki7dQhv.js.map +1 -0
- package/dist/{wizard-session-D1KQqUml.js → wizard-session-gbYCXdBf.js} +1 -1
- package/dist/{yara-hooks-CmQT-oBy.js → yara-hooks-BpngckdZ.js} +4 -4
- package/dist/{yara-hooks-CmQT-oBy.js.map → yara-hooks-BpngckdZ.js.map} +1 -1
- package/dist/yara-hooks-C-qG6EJt.js +2 -0
- package/package.json +1 -1
- package/dist/agent-runner-D5dhuE4z.js.map +0 -1
- package/dist/analytics-D90QbLf5.js.map +0 -1
- package/dist/analytics-Dmf_Jm3K.js +0 -2
- package/dist/posthog-integration-DdeIUkYw.js.map +0 -1
- package/dist/start-tui-BafJXVNT.js.map +0 -1
- package/dist/store-DSUCWMRO.js.map +0 -1
- package/dist/wizard-session-C_7r3-rO.js.map +0 -1
- package/dist/yara-hooks-BhNAWw7W.js +0 -2
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agent-runner-D5dhuE4z.js","names":["executeAgent","path"],"sources":["../src/lib/agent/runner/shared/authenticate.ts","../src/lib/agent/runner/harness/anthropic/index.ts","../src/lib/agent/runner/switchboard/flags/orchestrator.ts","../src/lib/agent/runner/switchboard/flags/self-driving.ts","../src/lib/agent/runner/switchboard/flags/schemes.ts","../src/lib/agent/runner/switchboard/flags/index.ts","../src/lib/agent/runner/switchboard/harness.ts","../src/lib/middleware/phase-detector.ts","../src/lib/middleware/pipeline.ts","../src/lib/middleware/config.ts","../src/lib/middleware/benchmarks/turn-counter.ts","../src/lib/middleware/benchmarks/token-tracker.ts","../src/lib/middleware/benchmarks/cache-tracker.ts","../src/lib/middleware/benchmarks/compaction-tracker.ts","../src/lib/middleware/benchmarks/context-size-tracker.ts","../src/lib/agent/token-pricing.ts","../src/lib/middleware/benchmarks/cost-tracker.ts","../src/lib/middleware/benchmarks/duration-tracker.ts","../src/lib/middleware/benchmarks/summary.ts","../src/lib/middleware/benchmarks/json-writer.ts","../src/lib/middleware/benchmarks/index.ts","../src/lib/middleware/benchmark.ts","../src/lib/agent/agent-prompt.ts","../src/lib/agent/runner/shared/errors.ts","../src/lib/agent/runner/sequence/linear.ts","../src/utils/terminal-bell.ts","../src/lib/agent/runner/sequence/orchestrator/executor.ts","../src/lib/agent/runner/sequence/orchestrator/run-metrics.ts","../src/lib/agent/runner/sequence/orchestrator/seeded-deps.ts","../src/lib/agent/runner/sequence/orchestrator/orchestrator-runner.ts","../src/lib/agent/runner/switchboard/sequence.ts","../src/lib/agent/runner/switchboard/index.ts","../src/lib/agent/runner/shared/bootstrap.ts","../src/lib/agent/runner/index.ts","../src/lib/agent/agent-runner.ts"],"sourcesContent":["/**\n * Authenticate the wizard — once per invocation.\n *\n * Idempotent: when `session.credentials` is already set, this is a no-op. So a\n * second agent run in the same invocation (e.g. self-driving runs the\n * integration program as a phase, then the Self-driving run) reuses the first\n * login instead of launching another OAuth — a second OAuth re-prompts and\n * fails with a 400 (the first authorization code is already spent). The first\n * call stores the full result on the session so any later bootstrap reads it\n * back rather than fetching again.\n */\n\nimport type { WizardSession } from '@lib/wizard-session';\nimport type { ProgramId } from '@lib/programs/program-registry';\nimport { getOrAskForProjectData } from '@utils/setup-utils';\nimport { analytics, groupsFromUser } from '@utils/analytics';\nimport { getUI } from '@ui';\nimport { logToFile } from '@utils/debug';\n\nexport async function authenticate(\n session: WizardSession,\n programId: ProgramId,\n): Promise<void> {\n if (session.credentials) return;\n\n logToFile('[agent-runner] starting OAuth');\n const {\n projectApiKey,\n host,\n accessToken,\n projectId,\n roleAtOrganization,\n user,\n project,\n missingScopes,\n } = await getOrAskForProjectData({\n signup: session.signup,\n ci: session.ci,\n apiKey: session.apiKey,\n projectId: session.projectId,\n email: session.email,\n region: session.region,\n baseUrl: session.baseUrl,\n localMcp: session.localMcp,\n programId,\n });\n\n session.credentials = {\n accessToken,\n projectApiKey,\n host,\n projectId,\n missingScopes,\n };\n session.apiProject = project;\n session.roleAtOrganization = roleAtOrganization;\n session.apiUser = user;\n\n getUI().setCredentials(session.credentials);\n getUI().setRoleAtOrganization(roleAtOrganization);\n getUI().setApiUser(user);\n\n // Identify the user (email, name) before flags are evaluated, so flags can\n // target the individual user and not just $app_name.\n if (user) analytics.identifyUser(user);\n analytics.setGroups(groupsFromUser(user, host.apiHost));\n}\n","/**\n * The `anthropic` runner — the control. Wraps the claude-agent-sdk path\n * (`initializeAgent` + `runAgent`) that was inline in `linear.ts` before the\n * runner seam. Owns only the agent loop + model transport; the shared pipeline\n * (skill install, prompt, ask bridge, error routing, outro) stays in `linear.ts`.\n *\n * Implements both entry points:\n * - `run` for linear mode (one call per program)\n * - `runTask` for orchestrator mode (one call for the seed plan, one per\n * drained task). This is the only harness that supports\n * orchestrator today; pi omits `runTask` and the orchestrator\n * runner fails loudly when handed a harness without it.\n */\n\nimport { getUI } from '@ui';\nimport { Harness } from '@lib/constants';\nimport {\n initializeAgent,\n runAgent as executeAgent,\n} from '@lib/agent/agent-interface';\nimport { createAioCapture } from '@lib/agent/aio-capture';\nimport { getLogFilePath, logToFile } from '@utils/debug';\nimport { detectNodePackageManagers } from '@lib/detection/package-manager';\nimport { sessionToOptions } from '@lib/agent/runner/shared/bootstrap';\nimport type {\n AgentResult,\n AgentHarness,\n BackendRunInputs,\n TaskRunInputs,\n} from '../types';\n\nexport const anthropicBackend: AgentHarness = {\n name: Harness.anthropic,\n\n async run(inputs: BackendRunInputs): Promise<AgentResult> {\n const {\n session,\n config,\n programConfig,\n boot,\n prompt,\n spinner,\n askBridge,\n middleware,\n model,\n } = inputs;\n const { skillsBaseUrl, credentials, wizardFlags, wizardMetadata } = boot;\n const { accessToken, host, projectApiKey } = credentials;\n\n const capture = createAioCapture({\n enabled: session.captureAio,\n projectApiKey,\n apiHost: host.apiHost,\n runTags: wizardMetadata,\n });\n\n getUI().log.step('Initializing Claude agent...');\n const agent = await initializeAgent(\n {\n workingDirectory: session.installDir,\n posthogMcpUrl: host.mcpUrl,\n posthogApiKey: accessToken,\n host,\n additionalMcpServers: config.additionalMcpServers,\n detectPackageManager:\n config.detectPackageManager ?? detectNodePackageManagers,\n skillsBaseUrl,\n wizardFlags,\n wizardMetadata,\n programId: boot.programId,\n integrationLabel: config.integrationLabel,\n askBridge,\n askMaxQuestions: config.maxQuestions,\n allowedTools: programConfig.allowedTools,\n disallowedTools: programConfig.disallowedTools,\n getPendingQuestion: () => session.pendingQuestion,\n modelOverride: model,\n capture,\n },\n sessionToOptions(session),\n );\n getUI().log.step(`Verbose logs: ${getLogFilePath()}`);\n getUI().log.success(\"Agent initialized. Let's get cooking!\");\n logToFile('[agent-runner] agent initialized');\n\n return executeAgent(\n agent,\n prompt,\n sessionToOptions(session),\n spinner,\n {\n estimatedDurationMinutes: config.estimatedDurationMinutes,\n spinnerMessage: config.spinnerMessage,\n successMessage: config.successMessage,\n errorMessage:\n config.errorMessage ?? `${config.integrationLabel} failed`,\n additionalFeatureQueue: config.additionalFeatureQueue ?? [],\n abortCases: config.abortCases,\n emitStepEvents: config.trackStepProgress ?? false,\n resolveStepKey: config.resolveStepKey,\n triageProvider: boot.triageProvider,\n },\n middleware,\n );\n },\n\n async runTask(inputs: TaskRunInputs): Promise<AgentResult> {\n const {\n session,\n programConfig,\n boot,\n prompt,\n spinner,\n model,\n allowedTools,\n disallowedTools,\n askBridge,\n orchestrator,\n spinnerMessage,\n successMessage,\n errorMessage,\n additionalFeatureQueue,\n requestRemark,\n analyticsProperties,\n } = inputs;\n const options = sessionToOptions(session);\n\n const capture = createAioCapture({\n enabled: session.captureAio,\n projectApiKey: boot.credentials.projectApiKey,\n apiHost: boot.credentials.host.apiHost,\n runTags: boot.wizardMetadata,\n });\n\n // Per-task agent config — the wizard-tools MCP server is bound to the\n // orchestrator context (queue store + current task id) so complete_task /\n // enqueue_task attribute to the right agent when tasks run in parallel.\n const agent = await initializeAgent(\n {\n workingDirectory: session.installDir,\n posthogMcpUrl: boot.credentials.host.mcpUrl,\n posthogApiKey: boot.credentials.accessToken,\n host: boot.credentials.host,\n detectPackageManager: detectNodePackageManagers,\n skillsBaseUrl: boot.skillsBaseUrl,\n programId: boot.programId,\n wizardFlags: boot.wizardFlags,\n wizardMetadata: boot.wizardMetadata,\n integrationLabel: programConfig.id,\n // Only a task allowed to ask carries a bridge, so the Write/Edit pause\n // that rides on a pending question stays inside that task's agent.\n askBridge,\n orchestrator,\n capture,\n },\n options,\n );\n\n return executeAgent(\n { ...agent, model, allowedTools, disallowedTools },\n prompt,\n options,\n spinner,\n {\n spinnerMessage,\n successMessage,\n errorMessage,\n additionalFeatureQueue,\n requestRemark,\n analyticsProperties,\n },\n );\n },\n};\n","/** Orchestrator gate: wizard-orchestrator on/off. On routes the declared programs to the orchestrator on pi; every model/effort comes from prompt frontmatter. */\nimport {\n Harness,\n Sequence,\n WIZARD_ORCHESTRATOR_FLAG_KEY,\n WIZARD_ORCHESTRATOR_OVERRIDE_FLAG_KEY,\n WIZARD_ORCHESTRATOR_SEEDED_TASKS_FLAG_KEY,\n} from '@lib/constants';\nimport type { HarnessExperiment, SequenceExperiment } from './schemes';\n\nexport const ORCHESTRATOR_SEQUENCE_ROUTE: SequenceExperiment = {\n programs: ['posthog-integration'],\n flag: WIZARD_ORCHESTRATOR_FLAG_KEY,\n sequence: Sequence.orchestrator,\n};\n\n/** Same flag, harness axis: the orchestrator drives tasks through pi. */\nexport const ORCHESTRATOR_HARNESS_ROUTE: HarnessExperiment = {\n program: 'posthog-integration',\n flags: { useFlag: WIZARD_ORCHESTRATOR_FLAG_KEY, harness: Harness.pi },\n};\n\n/** Same programs, per-stage overrides: the variant payload (`{stage: {model?, effort?}}`) outranks prompt frontmatter for the stages it names. */\nexport const ORCHESTRATOR_STAGE_OVERRIDES = {\n programs: ORCHESTRATOR_SEQUENCE_ROUTE.programs,\n flag: WIZARD_ORCHESTRATOR_OVERRIDE_FLAG_KEY,\n} as const;\n\n/**\n * Kill switch for the runner-seeded task mechanism (the optional warehouse\n * step). Off or unset, the orchestrator queues nothing itself and the run is\n * identical to a project with no detected sources.\n */\nexport function areSeededTasksEnabled(\n flags: Record<string, string> = {},\n): boolean {\n return flags[WIZARD_ORCHESTRATOR_SEEDED_TASKS_FLAG_KEY] === 'true';\n}\n\n/** Raw flag read — for telemetry/log lines only, never for routing. */\nexport function isOrchestratorEnabled(\n flags: Record<string, string> = {},\n): boolean {\n return flags[ORCHESTRATOR_SEQUENCE_ROUTE.flag] === 'true';\n}\n","/**\n * Self-driving pi experiment.\n *\n * Flag: wizard-self-driving-use-pi-harness (bool; payload `{model, effort?,\n * harness?, sequence?}`)\n * Routes: ONLY `self-driving` — any axis the payload pins. A missing or\n * invalid payload keeps the non-flagged binding default.\n */\nimport { WIZARD_SELF_DRIVING_USE_PI_HARNESS_FLAG_KEY } from '@lib/constants';\nimport type { HarnessExperiment } from './schemes';\n\nexport const SELF_DRIVING_EXPERIMENT: HarnessExperiment = {\n program: 'self-driving',\n flags: {\n useFlag: WIZARD_SELF_DRIVING_USE_PI_HARNESS_FLAG_KEY,\n },\n};\n","/**\n * Flag config schemes — the shapes a PostHog flag set can take to route a\n * program to the pi harness, plus the shared vocabulary and the per-config\n * resolution. Experiment modules in this folder declare *which* flags they\n * use; this module owns *how* a config resolves to a route.\n */\nimport { z } from 'zod';\nimport {\n DEFAULT_AGENT_MODEL,\n GPT5_6_LUNA_MODEL,\n GPT5_6_SOL_MODEL,\n GPT5_6_TERRA_MODEL,\n Harness,\n Sequence,\n SONNET_5_MODEL,\n} from '@lib/constants';\nimport type { ProgramId } from '@lib/programs/program-registry';\nimport { logToFile } from '@utils/debug';\nimport type { EffortLevel } from '../models';\n\n// ── Shared vocabulary ─────────────────────────────────────────────────────\n\n/** Model variant key → gateway id. */\nconst MODEL_FLAG_VARIANTS: Record<string, string> = {\n 'gpt-5-6-luna': GPT5_6_LUNA_MODEL,\n 'gpt-5-6-terra': GPT5_6_TERRA_MODEL,\n 'gpt-5-6-sol': GPT5_6_SOL_MODEL,\n 'sonnet-4-6': DEFAULT_AGENT_MODEL,\n 'sonnet-5': SONNET_5_MODEL,\n};\n\n/** Valid effort variants; anything else leaves the model's table default. */\nconst EFFORT_FLAG_VARIANTS = [\n 'minimal',\n 'low',\n 'medium',\n 'high',\n 'xhigh',\n] as const satisfies readonly EffortLevel[];\n\n/** A resolved flag route. Absent fields keep the axis's default (pi harness, sequence resolved by its own chain, table effort). */\nexport interface FlagRoute {\n model?: string;\n thinkingLevel?: EffortLevel;\n harness?: Harness;\n sequence?: Sequence;\n}\n\n// ── Config schemes ────────────────────────────────────────────────────────\n\n/** Harness-only scheme: the useFlag routes the harness; model/effort stay at the binding default so prompt frontmatter governs. */\nexport interface HarnessConfigFlag {\n useFlag: string;\n harness: Harness;\n}\n\n/** Boolean-flag scheme: the useFlag's zod-validated `{model, effort?, harness?, sequence?}` payload picks the route; anything invalid keeps the non-flagged binding default. */\nexport interface PayloadConfigFlag {\n useFlag: string;\n harness?: never;\n}\n\nexport type ConfigFlag = HarnessConfigFlag | PayloadConfigFlag;\n\n/**\n * A harness-axis experiment: ONE program and the flags that route it. The\n * scope is part of the declaration — the flags are inert for every other\n * program.\n */\nexport interface HarnessExperiment {\n program: ProgramId;\n flags: ConfigFlag;\n}\n\n/** A sequence-axis experiment: one boolean flag, inert outside its listed programs. */\nexport interface SequenceExperiment {\n programs: readonly ProgramId[];\n flag: string;\n /** Sequence the flag routes covered programs to. */\n sequence: Sequence;\n}\n\n/** Variant key validated against the shared vocabulary, transformed to its gateway id. */\nconst modelVariantSchema = z\n .string()\n .refine((key) => key in MODEL_FLAG_VARIANTS)\n .transform((key) => MODEL_FLAG_VARIANTS[key]);\n\n/** `{model, effort?, harness?, sequence?}` payload shape; extra keys tolerated for forward compat. */\nconst payloadConfigFlagSchema = z.object({\n model: modelVariantSchema,\n effort: z.enum(EFFORT_FLAG_VARIANTS).optional(),\n harness: z.nativeEnum(Harness).optional(),\n sequence: z.nativeEnum(Sequence).optional(),\n});\n\n/**\n * PostHog serves a variant's payload as a JSON string, e.g. the\n * wizard-orchestrator-override `terra-review` variant arrives as\n * `'{\"review\":{\"model\":\"gpt-5-6-terra\",\"effort\":\"medium\"}}'`; local CI\n * overrides inject the same payloads as already-parsed objects. Coerce both\n * to the value; anything unparseable is undefined.\n */\nfunction coerceJson(raw: unknown): unknown {\n if (typeof raw !== 'string') return raw;\n try {\n return JSON.parse(raw) as unknown;\n } catch {\n return undefined;\n }\n}\n\n// ── Resolution ────────────────────────────────────────────────────────────\n\n/** Per-stage overrides keyed by stage; a whole-payload parse failure fails closed to frontmatter everywhere. */\nconst stageOverridesSchema = z.record(\n z.object({\n model: modelVariantSchema.optional(),\n effort: z.enum(EFFORT_FLAG_VARIANTS).optional(),\n }),\n);\n\nexport type StageOverride = { model?: string; effort?: EffortLevel };\n\n/** Validate a stage-override payload (object or JSON string); undefined on any unexpected shape. */\nexport function stageOverridesFromPayload(\n raw: unknown,\n): Record<string, StageOverride> | undefined {\n const parsed = stageOverridesSchema.safeParse(coerceJson(raw));\n return parsed.success ? parsed.data : undefined;\n}\n\n/** Validate a payload (object or JSON string) into a route; undefined on any unexpected shape. */\nfunction parseFlagPayload(raw: unknown): FlagRoute | undefined {\n const parsed = payloadConfigFlagSchema.safeParse(coerceJson(raw));\n if (!parsed.success) return undefined;\n return {\n model: parsed.data.model,\n thinkingLevel: parsed.data.effort,\n harness: parsed.data.harness,\n sequence: parsed.data.sequence,\n };\n}\n\n/**\n * Resolve one config against the flag snapshot, or undefined when it doesn't\n * validly route: use flag off, or a payload that fails validation — the\n * caller then keeps the non-flagged binding default.\n */\nexport function routeFromConfigFlag(\n cfg: ConfigFlag,\n flags: Record<string, string>,\n flagPayloads?: Record<string, unknown>,\n): FlagRoute | undefined {\n if (flags[cfg.useFlag] !== 'true') return undefined;\n if (cfg.harness) return { harness: cfg.harness };\n const route = parseFlagPayload(flagPayloads?.[cfg.useFlag]);\n if (!route) {\n logToFile(\n `[switchboard] ${cfg.useFlag} on but payload missing/invalid — keeping the non-flagged default`,\n );\n }\n return route;\n}\n","/**\n * Switchboard flags, one module per experiment. Every experiment declares its\n * own scope — which program(s) its flags route — so the flag→program mapping\n * is readable per file, never implied. `schemes.ts` owns the shared config\n * shapes and resolution.\n */\nimport { RUN_SURFACE } from '@env';\nimport { logToFile } from '@utils/debug';\nimport type { Sequence } from '@lib/constants';\nimport type { ProgramId } from '@lib/programs/program-registry';\nimport {\n ORCHESTRATOR_HARNESS_ROUTE,\n ORCHESTRATOR_SEQUENCE_ROUTE,\n ORCHESTRATOR_STAGE_OVERRIDES,\n} from './orchestrator';\nimport { SELF_DRIVING_EXPERIMENT } from './self-driving';\nimport {\n routeFromConfigFlag,\n stageOverridesFromPayload,\n type FlagRoute,\n type HarnessExperiment,\n type SequenceExperiment,\n type StageOverride,\n} from './schemes';\n\n/** Every experiment on each axis. An experiment routes ONLY by being listed here, and only for the programs it declares. */\nexport const HARNESS_EXPERIMENTS: readonly HarnessExperiment[] = [\n ORCHESTRATOR_HARNESS_ROUTE,\n SELF_DRIVING_EXPERIMENT,\n];\nexport const SEQUENCE_EXPERIMENTS: readonly SequenceExperiment[] = [\n ORCHESTRATOR_SEQUENCE_ROUTE,\n];\n\n/** The flag-driven route for a program, or undefined when no experiment covers it or its flags don't validly route. */\nexport function resolveFlagRoute(\n program: ProgramId,\n flags: Record<string, string>,\n flagPayloads?: Record<string, unknown>,\n): FlagRoute | undefined {\n const experiment = HARNESS_EXPERIMENTS.find((e) => e.program === program);\n return (\n experiment && routeFromConfigFlag(experiment.flags, flags, flagPayloads)\n );\n}\n\n/** The flag-driven sequence for a program, or undefined when no sequence experiment covers it with its flag on. Surface/build scoping is the flag's own job (see `flagPersonProperties`). */\nexport function resolveFlagSequence(\n program: ProgramId,\n flags: Record<string, string>,\n): Sequence | undefined {\n return SEQUENCE_EXPERIMENTS.find(\n (e) => e.programs.includes(program) && flags[e.flag] === 'true',\n )?.sequence;\n}\n\n/** The per-stage overrides for a program's run, or undefined (prompt frontmatter stays). Applied once, where the agent prompts are loaded. */\nexport function resolveStageOverrides(\n program: ProgramId,\n flags: Record<string, string>,\n flagPayloads?: Record<string, unknown>,\n): Record<string, StageOverride> | undefined {\n if (RUN_SURFACE === 'cloud') return undefined;\n const exp = ORCHESTRATOR_STAGE_OVERRIDES;\n if (!exp.programs.includes(program)) return undefined;\n const variant = flags[exp.flag];\n if (!variant || variant === 'false') return undefined;\n const overrides = stageOverridesFromPayload(flagPayloads?.[exp.flag]);\n if (!overrides) {\n logToFile(\n `[switchboard] ${exp.flag}=${variant} but payload missing/invalid — keeping frontmatter`,\n );\n }\n return overrides;\n}\n\nexport { isOrchestratorEnabled, areSeededTasksEnabled } from './orchestrator';\nexport type {\n ConfigFlag,\n FlagRoute,\n HarnessExperiment,\n SequenceExperiment,\n StageOverride,\n} from './schemes';\n","/**\n * Harness axis: registry, middleware, resolver. Mirrors `sequence.ts`.\n */\n\nimport { IS_PRODUCTION_BUILD } from '@env';\nimport { Harness } from '@lib/constants';\nimport { logToFile } from '@utils/debug';\nimport { anthropicBackend } from '../harness/anthropic';\nimport { piBackend } from '../harness/pi';\nimport type { AgentHarness } from '../harness/types';\nimport { resolveFlagRoute } from './flags';\nimport {\n DEFAULT_BINDING,\n PROGRAM_BINDINGS,\n runChain,\n type HarnessPick,\n type Middleware,\n type SwitchboardCtx,\n} from '.';\n\nexport const HARNESS_OPTIONS: Partial<Record<Harness, AgentHarness>> = {\n [Harness.anthropic]: anthropicBackend,\n [Harness.pi]: piBackend,\n};\n\nexport function getHarness(name: Harness): AgentHarness {\n const harness = HARNESS_OPTIONS[name];\n if (!harness) {\n throw new Error(`No harness registered for '${name}'.`);\n }\n return harness;\n}\n\n/**\n * PostHog-flag routing to pi (see `./flags`). No valid route — flag off, no\n * config, or an invalid payload — keeps the non-flagged binding default.\n */\nconst flagRunnerOverride: Middleware<HarnessPick> = (ctx, next) => {\n const pick = next();\n const route = resolveFlagRoute(ctx.program, ctx.flags, ctx.flagPayloads);\n if (!route) return pick;\n if (ctx.trace) {\n ctx.trace.harness = 'flag';\n // Harness-only routes keep the binding's model — trace it truthfully so\n // analytics never attributes the fallback model to the flag.\n if (route.model) ctx.trace.model = 'flag';\n }\n return {\n harness: route.harness ?? Harness.pi,\n model: route.model ?? pick.model,\n thinkingLevel: route.thinkingLevel ?? pick.thinkingLevel,\n };\n};\n\n/** `--harness` override. Dev/test only — the option is gated out of published builds. */\nconst cliHarnessOverride: Middleware<HarnessPick> = (ctx, next) => {\n const pick = next();\n if (!ctx.cliHarness) return pick;\n if (ctx.trace) ctx.trace.harness = 'cli';\n return { ...pick, harness: ctx.cliHarness };\n};\n\n/** `--model` override. Dev/test only — the option is gated out of published builds. */\nconst cliModelOverride: Middleware<HarnessPick> = (ctx, next) => {\n const pick = next();\n if (!ctx.cliModel) return pick;\n if (ctx.trace) ctx.trace.model = 'cli';\n return { ...pick, model: ctx.cliModel };\n};\n\n// Order = precedence: CLI > flag > binding default. The prod spread collapses\n// to [], dropping the CLI overrides from the chain.\nconst HARNESS_MIDDLEWARE: Middleware<HarnessPick>[] = [\n ...(IS_PRODUCTION_BUILD ? [] : [cliHarnessOverride, cliModelOverride]),\n flagRunnerOverride,\n];\n\n/**\n * Resolve the harness for a role. Linear callers omit `role`; orchestrator\n * callers pass `'seed'` or `task.type`. `contextMillOverride[role]` overlays.\n */\nexport function resolveHarness(\n ctx: SwitchboardCtx,\n role = 'default',\n): HarnessPick {\n const pick = runChain(HARNESS_MIDDLEWARE, ctx, () => {\n if (ctx.trace)\n Object.assign(ctx.trace, { harness: 'binding', model: 'binding' });\n const binding = PROGRAM_BINDINGS[ctx.program] ?? DEFAULT_BINDING;\n return {\n harness: binding.harness,\n model: binding.model,\n thinkingLevel: binding.thinkingLevel,\n ...binding.contextMillOverride?.[role],\n };\n });\n logToFile(\n `[switchboard] resolved: program=${ctx.program} harness=${pick.harness}` +\n `${ctx.trace?.harness ? ` (${ctx.trace.harness})` : ''} model=${\n pick.model\n }` +\n `${ctx.trace?.model ? ` (${ctx.trace.model})` : ''}`,\n );\n return pick;\n}\n","/** Phase transitions from [STATUS] in assistant text. Keep in sync with program \"Status to report\" bullets. */\n\nconst PHASES_ORDER = [\n '1.0-begin',\n '1.1-edit',\n '1.2-revise',\n '1.3-conclude',\n] as const;\n\nconst STATUS_PHRASES_BY_PHASE: Record<(typeof PHASES_ORDER)[number], string[]> =\n {\n '1.0-begin': [\n 'Checking project structure',\n 'Verifying PostHog dependencies',\n 'Generating events based on project',\n ],\n '1.1-edit': ['Inserting PostHog capture code'],\n '1.2-revise': [\n 'Finding and correcting errors',\n 'Report details of any errors you fix',\n 'Linting, building and prettying',\n ],\n '1.3-conclude': ['Configured dashboard', 'Created setup report'],\n };\n\nexport class PhaseDetector {\n private currentPhase: 'setup' | (typeof PHASES_ORDER)[number] = 'setup';\n\n detect(message: any): string | null {\n if (message.type !== 'assistant') return null;\n\n const nextPhase = this.getNextPhase();\n if (nextPhase === null) return null;\n\n const content = message.message?.content;\n if (!Array.isArray(content)) return null;\n\n for (const block of content) {\n if (block.type !== 'text' || typeof block.text !== 'string') continue;\n if (!block.text.includes('[STATUS]')) continue;\n\n const phrases = STATUS_PHRASES_BY_PHASE[nextPhase];\n for (const phrase of phrases) {\n if (block.text.includes(phrase)) {\n this.currentPhase = nextPhase;\n return nextPhase;\n }\n }\n }\n\n return null;\n }\n\n private getNextPhase(): (typeof PHASES_ORDER)[number] | null {\n if (this.currentPhase === 'setup') return '1.0-begin';\n const i = PHASES_ORDER.indexOf(this.currentPhase);\n if (i < 0 || i >= PHASES_ORDER.length - 1) return null;\n return PHASES_ORDER[i + 1];\n }\n\n reset(): void {\n this.currentPhase = 'setup';\n }\n}\n","/**\n * Middleware pipeline orchestrator.\n *\n * Implements the same { onMessage, finalize } interface that runAgent() expects,\n * while internally dispatching to an ordered list of middleware plugins.\n */\n\nimport { PhaseDetector } from './phase-detector';\nimport type {\n Middleware,\n MiddlewareContext,\n MiddlewareStore,\n SDKMessage,\n} from './types';\n\nexport class MiddlewarePipeline {\n private middlewares: Middleware[];\n private store = new Map<string, unknown>();\n private phaseDetector: PhaseDetector;\n private autoDetectPhases: boolean;\n private _currentPhase = 'setup';\n private _currentPhaseFreshContext = true;\n\n constructor(\n middlewares: Middleware[],\n opts?: { phaseDetector?: PhaseDetector; autoDetectPhases?: boolean },\n ) {\n this.middlewares = middlewares;\n this.phaseDetector = opts?.phaseDetector ?? new PhaseDetector();\n this.autoDetectPhases = opts?.autoDetectPhases ?? true;\n\n const ctx = this.createContext();\n for (const mw of this.middlewares) {\n mw.onInit?.(ctx);\n }\n }\n\n /** Feed an SDK message through all middleware (satisfies tracker.onMessage) */\n onMessage(message: SDKMessage): void {\n // Phase detection first — updates context before middleware sees it\n if (this.autoDetectPhases) {\n const newPhase = this.phaseDetector.detect(message);\n if (newPhase && newPhase !== this._currentPhase) {\n this.transitionPhase(newPhase, false);\n }\n }\n\n const ctx = this.createContext();\n const storeHandle = this.createStore();\n for (const mw of this.middlewares) {\n mw.onMessage?.(message, ctx, storeHandle);\n }\n }\n\n /** Finalize the run (satisfies tracker.finalize) */\n finalize(resultMessage: any, totalDurationMs: number): any {\n const ctx = this.createContext();\n const storeHandle = this.createStore();\n let result: any;\n for (const mw of this.middlewares) {\n const r = mw.onFinalize?.(\n resultMessage,\n totalDurationMs,\n ctx,\n storeHandle,\n );\n if (r !== undefined) result = r;\n }\n return result;\n }\n\n /** Explicit phase start (for phased runner support) */\n startPhase(name: string, freshContext: boolean): void {\n this.transitionPhase(name, freshContext);\n }\n\n private transitionPhase(newPhase: string, freshContext: boolean): void {\n const oldPhase = this._currentPhase;\n this._currentPhase = newPhase;\n this._currentPhaseFreshContext = freshContext;\n const ctx = this.createContext();\n const storeHandle = this.createStore();\n for (const mw of this.middlewares) {\n mw.onPhaseTransition?.(oldPhase, newPhase, ctx, storeHandle);\n }\n }\n\n private createContext(): MiddlewareContext {\n return {\n currentPhase: this._currentPhase,\n currentPhaseFreshContext: this._currentPhaseFreshContext,\n get: <T>(key: string) => this.store.get(key) as T | undefined,\n };\n }\n\n private createStore(): MiddlewareStore {\n return {\n set: (key: string, value: unknown) => this.store.set(key, value),\n };\n }\n}\n","/**\n * Benchmark configuration loader.\n *\n * Loads .benchmark-config.json from the working directory with sensible defaults.\n * All fields are optional — missing fields fall back to defaults.\n */\n\nimport fs from 'fs';\nimport path from 'path';\nimport { logToFile } from '@utils/debug';\nimport { AgentSignals } from '@lib/agent/agent-interface';\nimport { runtimeEnv } from '@env';\nimport { WIZARD_BENCHMARK_FILE, WIZARD_LOG_FILE } from '@utils/paths';\n\nexport interface BenchmarkConfig {\n /** Enable/disable individual metric plugins */\n plugins: Record<string, boolean>;\n output: {\n /** Path for the benchmark JSON output file */\n benchmarkPath: string;\n /** Whether to write the benchmark JSON file */\n benchmarkEnabled: boolean;\n /** Path for the main wizard debug log file */\n logPath: string;\n /** Whether to write the main wizard debug log */\n logEnabled: boolean;\n /** Suppress benchmark console output (disables the summary plugin) */\n suppressWizardLogs: boolean;\n };\n}\n\nconst DEFAULT_CONFIG: BenchmarkConfig = {\n plugins: {\n tokens: true,\n cache: true,\n turns: true,\n compactions: true,\n contextSize: true,\n cost: true,\n duration: true,\n summary: true,\n jsonWriter: true,\n },\n output: {\n benchmarkPath: WIZARD_BENCHMARK_FILE,\n benchmarkEnabled: true,\n logPath: WIZARD_LOG_FILE,\n logEnabled: true,\n suppressWizardLogs: false,\n },\n};\n\nexport function loadBenchmarkConfig(installDir: string): BenchmarkConfig {\n const configPath =\n runtimeEnv('POSTHOG_WIZARD_BENCHMARK_CONFIG') ??\n path.join(installDir, '.benchmark-config.json');\n try {\n const raw = fs.readFileSync(configPath, 'utf-8');\n const parsed = JSON.parse(raw);\n const config: BenchmarkConfig = {\n plugins: { ...DEFAULT_CONFIG.plugins, ...parsed.plugins },\n output: { ...DEFAULT_CONFIG.output, ...parsed.output },\n };\n\n // Env var overrides for parallel runs\n const benchFile = runtimeEnv('POSTHOG_WIZARD_BENCHMARK_FILE');\n if (benchFile) {\n config.output.benchmarkPath = benchFile;\n }\n const logDir = runtimeEnv('POSTHOG_WIZARD_LOG_DIR');\n if (logDir) {\n config.output.logPath = path.join(logDir, 'posthog-wizard.log');\n }\n\n // If benchmark output is disabled, disable the jsonWriter plugin\n if (!config.output.benchmarkEnabled) {\n config.plugins.jsonWriter = false;\n }\n\n logToFile(`${AgentSignals.BENCHMARK} Loaded config from ${configPath}`);\n return config;\n } catch {\n // No config file or invalid JSON — use defaults\n const config = structuredClone(DEFAULT_CONFIG);\n\n // Env var overrides\n const benchFile2 = runtimeEnv('POSTHOG_WIZARD_BENCHMARK_FILE');\n if (benchFile2) {\n config.output.benchmarkPath = benchFile2;\n }\n const logDir2 = runtimeEnv('POSTHOG_WIZARD_LOG_DIR');\n if (logDir2) {\n config.output.logPath = path.join(logDir2, 'posthog-wizard.log');\n }\n\n return config;\n }\n}\n\nexport function getDefaultConfig(): BenchmarkConfig {\n return structuredClone(DEFAULT_CONFIG);\n}\n","/**\n * Turn counting plugin with message deduplication.\n *\n * The SDK emits multiple assistant events per turn (one per content block)\n * with the same message ID. This plugin deduplicates and publishes turn\n * counts + a duplicate flag for downstream plugins.\n */\n\nimport type {\n Middleware,\n MiddlewareContext,\n MiddlewareStore,\n} from '@lib/middleware/types';\n\nexport interface TurnData {\n /** Whether the current message is a duplicate of the last processed turn */\n isDuplicate: boolean;\n /** Turns in the current phase */\n phaseTurns: number;\n /** Total turns across all phases */\n totalTurns: number;\n /** Per-phase turn snapshots: [{ phase, turns }] */\n phaseSnapshots: Array<{ phase: string; turns: number }>;\n}\n\nexport class TurnCounterPlugin implements Middleware {\n readonly name = 'turns';\n\n private lastMessageId: string | null = null;\n private phaseTurns = 0;\n private totalTurns = 0;\n private isDuplicate = false;\n private phaseSnapshots: Array<{ phase: string; turns: number }> = [];\n private currentPhase = 'setup';\n\n onMessage(\n message: any,\n _ctx: MiddlewareContext,\n store: MiddlewareStore,\n ): void {\n if (message.type !== 'assistant') {\n this.isDuplicate = false;\n store.set('turns', this.getData());\n return;\n }\n\n const msgId: string | undefined = message.message?.id;\n this.isDuplicate = msgId != null && msgId === this.lastMessageId;\n if (msgId) this.lastMessageId = msgId;\n\n if (!this.isDuplicate) {\n this.phaseTurns++;\n this.totalTurns++;\n }\n\n store.set('turns', this.getData());\n }\n\n onPhaseTransition(\n fromPhase: string,\n _toPhase: string,\n _ctx: MiddlewareContext,\n store: MiddlewareStore,\n ): void {\n this.phaseSnapshots.push({ phase: fromPhase, turns: this.phaseTurns });\n this.currentPhase = _toPhase;\n this.phaseTurns = 0;\n this.lastMessageId = null;\n store.set('turns', this.getData());\n }\n\n onFinalize(\n _resultMessage: any,\n _totalDurationMs: number,\n _ctx: MiddlewareContext,\n store: MiddlewareStore,\n ): void {\n this.phaseSnapshots.push({\n phase: this.currentPhase,\n turns: this.phaseTurns,\n });\n store.set('turns', this.getData());\n }\n\n private getData(): TurnData {\n return {\n isDuplicate: this.isDuplicate,\n phaseTurns: this.phaseTurns,\n totalTurns: this.totalTurns,\n phaseSnapshots: [...this.phaseSnapshots],\n };\n }\n}\n","/**\n * Token tracking plugin for input/output tokens.\n *\n * Accumulates per-turn token usage (input_tokens + cache_read_input_tokens\n * + cache_creation_input_tokens = total input; output_tokens = output).\n * Respects the dedup flag from TurnCounterPlugin. Cache breakdown (r/5m/1h)\n * is tracked by CacheTrackerPlugin for reporting and pricing.\n */\n\nimport type {\n Middleware,\n MiddlewareContext,\n MiddlewareStore,\n} from '@lib/middleware/types';\nimport type { TurnData } from './turn-counter';\n\nexport interface TokenData {\n phaseInput: number;\n phaseOutput: number;\n totalInput: number;\n totalOutput: number;\n /** The raw usage object from the last non-duplicate assistant message */\n lastUsage: any;\n /** Per-phase token snapshots */\n phaseSnapshots: Array<{\n phase: string;\n inputTokens: number;\n outputTokens: number;\n /** Number of turns in this phase that had usage (SDK may not report all) */\n messagesWithUsage: number;\n }>;\n}\n\nexport class TokenTrackerPlugin implements Middleware {\n readonly name = 'tokens';\n\n private phaseInput = 0;\n private phaseOutput = 0;\n private totalInput = 0;\n private totalOutput = 0;\n private lastUsage: any = null;\n private phaseSnapshots: Array<{\n phase: string;\n inputTokens: number;\n outputTokens: number;\n messagesWithUsage: number;\n }> = [];\n private currentPhase = 'setup';\n private phaseMessagesWithUsage = 0;\n\n onMessage(\n message: any,\n ctx: MiddlewareContext,\n store: MiddlewareStore,\n ): void {\n if (message.type !== 'assistant') return;\n\n const turns = ctx.get<TurnData>('turns');\n if (turns?.isDuplicate) return;\n\n const usage = message.message?.usage;\n if (usage) {\n const input =\n Number(usage.input_tokens ?? 0) +\n Number(usage.cache_read_input_tokens ?? 0) +\n Number(usage.cache_creation_input_tokens ?? 0);\n const output = Number(usage.output_tokens ?? 0);\n this.phaseInput += input;\n this.phaseOutput += output;\n this.totalInput += input;\n this.totalOutput += output;\n this.lastUsage = usage;\n this.phaseMessagesWithUsage += 1;\n }\n\n store.set('tokens', this.getData());\n }\n\n onPhaseTransition(\n fromPhase: string,\n toPhase: string,\n _ctx: MiddlewareContext,\n store: MiddlewareStore,\n ): void {\n this.phaseSnapshots.push({\n phase: fromPhase,\n inputTokens: this.phaseInput,\n outputTokens: this.phaseOutput,\n messagesWithUsage: this.phaseMessagesWithUsage,\n });\n this.currentPhase = toPhase;\n this.phaseInput = 0;\n this.phaseOutput = 0;\n this.phaseMessagesWithUsage = 0;\n store.set('tokens', this.getData());\n }\n\n onFinalize(\n _resultMessage: any,\n _totalDurationMs: number,\n _ctx: MiddlewareContext,\n store: MiddlewareStore,\n ): void {\n this.phaseSnapshots.push({\n phase: this.currentPhase,\n inputTokens: this.phaseInput,\n outputTokens: this.phaseOutput,\n messagesWithUsage: this.phaseMessagesWithUsage,\n });\n store.set('tokens', this.getData());\n }\n\n private getData(): TokenData {\n return {\n phaseInput: this.phaseInput,\n phaseOutput: this.phaseOutput,\n totalInput: this.totalInput,\n totalOutput: this.totalOutput,\n lastUsage: this.lastUsage,\n phaseSnapshots: [...this.phaseSnapshots],\n };\n }\n}\n","/**\n * Cache token tracking plugin (cache_read and cache_creation).\n *\n * Respects the dedup flag from TurnCounterPlugin.\n */\n\nimport type {\n Middleware,\n MiddlewareContext,\n MiddlewareStore,\n} from '@lib/middleware/types';\nimport type { TurnData } from './turn-counter';\n\n/** Matches SDK usage.cache_creation (ephemeral 5m vs 1h for pricing). */\nexport interface CacheCreationBreakdown {\n ephemeral_5m_input_tokens: number;\n ephemeral_1h_input_tokens: number;\n}\n\nexport interface CacheData {\n phaseRead: number;\n phaseCreation: number;\n totalRead: number;\n totalCreation: number;\n totalCreation5m: number;\n totalCreation1h: number;\n phaseSnapshots: Array<{\n phase: string;\n cacheReadTokens: number;\n cacheCreationTokens: number;\n /** When present, use for pricing (5m vs 1h rates). */\n cacheCreation5m: number;\n cacheCreation1h: number;\n }>;\n}\n\nexport class CacheTrackerPlugin implements Middleware {\n readonly name = 'cache';\n\n private phaseRead = 0;\n private phaseCreation = 0;\n private phaseCreation5m = 0;\n private phaseCreation1h = 0;\n private totalRead = 0;\n private totalCreation = 0;\n private totalCreation5m = 0;\n private totalCreation1h = 0;\n private phaseSnapshots: Array<{\n phase: string;\n cacheReadTokens: number;\n cacheCreationTokens: number;\n cacheCreation5m: number;\n cacheCreation1h: number;\n }> = [];\n private currentPhase = 'setup';\n\n onMessage(\n message: any,\n ctx: MiddlewareContext,\n store: MiddlewareStore,\n ): void {\n if (message.type !== 'assistant') return;\n\n const turns = ctx.get<TurnData>('turns');\n if (turns?.isDuplicate) return;\n\n const usage = message.message?.usage;\n if (usage) {\n const read = Number(usage.cache_read_input_tokens ?? 0);\n const creation = Number(usage.cache_creation_input_tokens ?? 0);\n const cc = usage.cache_creation;\n const creation5m = Number(cc?.ephemeral_5m_input_tokens ?? 0);\n const creation1h = Number(cc?.ephemeral_1h_input_tokens ?? 0);\n this.phaseRead += read;\n this.phaseCreation += creation;\n this.phaseCreation5m += creation5m;\n this.phaseCreation1h += creation1h;\n this.totalRead += read;\n this.totalCreation += creation;\n }\n\n store.set('cache', this.getData());\n }\n\n onPhaseTransition(\n fromPhase: string,\n toPhase: string,\n _ctx: MiddlewareContext,\n store: MiddlewareStore,\n ): void {\n this.phaseSnapshots.push({\n phase: fromPhase,\n cacheReadTokens: this.phaseRead,\n cacheCreationTokens: this.phaseCreation,\n cacheCreation5m: this.phaseCreation5m,\n cacheCreation1h: this.phaseCreation1h,\n });\n this.currentPhase = toPhase;\n this.phaseRead = 0;\n this.phaseCreation = 0;\n this.phaseCreation5m = 0;\n this.phaseCreation1h = 0;\n store.set('cache', this.getData());\n }\n\n onFinalize(\n _resultMessage: any,\n _totalDurationMs: number,\n _ctx: MiddlewareContext,\n store: MiddlewareStore,\n ): void {\n this.phaseSnapshots.push({\n phase: this.currentPhase,\n cacheReadTokens: this.phaseRead,\n cacheCreationTokens: this.phaseCreation,\n cacheCreation5m: this.phaseCreation5m,\n cacheCreation1h: this.phaseCreation1h,\n });\n store.set('cache', this.getData());\n }\n\n private getData(): CacheData {\n return {\n phaseRead: this.phaseRead,\n phaseCreation: this.phaseCreation,\n totalRead: this.totalRead,\n totalCreation: this.totalCreation,\n totalCreation5m: this.totalCreation5m,\n totalCreation1h: this.totalCreation1h,\n phaseSnapshots: [...this.phaseSnapshots],\n };\n }\n}\n","/**\n * Compaction event tracking plugin.\n *\n * Tracks context compaction events (compact_boundary system messages)\n * including pre-compaction token counts per phase.\n */\n\nimport type {\n Middleware,\n MiddlewareContext,\n MiddlewareStore,\n} from '@lib/middleware/types';\nimport { logToFile } from '@utils/debug';\nimport { AgentSignals } from '@lib/agent/agent-interface';\n\nexport interface CompactionData {\n phaseCompactions: number;\n phasePreTokens: number[];\n totalCompactions: number;\n phaseSnapshots: Array<{\n phase: string;\n compactions: number;\n preTokens: number[];\n }>;\n}\n\nexport class CompactionTrackerPlugin implements Middleware {\n readonly name = 'compactions';\n\n private phaseCompactions = 0;\n private phasePreTokens: number[] = [];\n private totalCompactions = 0;\n private phaseSnapshots: Array<{\n phase: string;\n compactions: number;\n preTokens: number[];\n }> = [];\n private currentPhase = 'setup';\n\n onMessage(\n message: any,\n ctx: MiddlewareContext,\n store: MiddlewareStore,\n ): void {\n if (message.type !== 'system' || message.subtype !== 'compact_boundary') {\n return;\n }\n\n const preTokens = message.compact_metadata?.pre_tokens ?? 0;\n const trigger = message.compact_metadata?.trigger ?? 'unknown';\n this.phaseCompactions++;\n this.totalCompactions++;\n this.phasePreTokens.push(preTokens);\n\n logToFile(\n `${AgentSignals.BENCHMARK} [COMPACTION] Context compacted during \"${ctx.currentPhase}\" (trigger: ${trigger}, pre_tokens: ${preTokens})`,\n );\n\n store.set('compactions', this.getData());\n }\n\n onPhaseTransition(\n fromPhase: string,\n toPhase: string,\n _ctx: MiddlewareContext,\n store: MiddlewareStore,\n ): void {\n this.phaseSnapshots.push({\n phase: fromPhase,\n compactions: this.phaseCompactions,\n preTokens: [...this.phasePreTokens],\n });\n this.currentPhase = toPhase;\n this.phaseCompactions = 0;\n this.phasePreTokens = [];\n store.set('compactions', this.getData());\n }\n\n onFinalize(\n _resultMessage: any,\n _totalDurationMs: number,\n _ctx: MiddlewareContext,\n store: MiddlewareStore,\n ): void {\n this.phaseSnapshots.push({\n phase: this.currentPhase,\n compactions: this.phaseCompactions,\n preTokens: [...this.phasePreTokens],\n });\n store.set('compactions', this.getData());\n }\n\n private getData(): CompactionData {\n return {\n phaseCompactions: this.phaseCompactions,\n phasePreTokens: [...this.phasePreTokens],\n totalCompactions: this.totalCompactions,\n phaseSnapshots: [...this.phaseSnapshots],\n };\n }\n}\n","/**\n * Context size tracking plugin (context tokens in/out per phase).\n *\n * Context tokens out = sum of input + cache_read + cache_creation from the\n * last assistant message's usage (per-turn, NOT aggregate).\n * Context tokens in = previous phase's context tokens out.\n */\n\nimport type {\n Middleware,\n MiddlewareContext,\n MiddlewareStore,\n} from '@lib/middleware/types';\nimport type { TokenData } from './token-tracker';\n\nexport interface ContextSizeData {\n /** Per-phase context size snapshots */\n phaseSnapshots: Array<{\n phase: string;\n contextTokensIn?: number;\n contextTokensOut?: number;\n freshContext: boolean;\n }>;\n}\n\nexport class ContextSizeTrackerPlugin implements Middleware {\n readonly name = 'contextSize';\n\n private phaseSnapshots: Array<{\n phase: string;\n contextTokensIn?: number;\n contextTokensOut?: number;\n freshContext: boolean;\n }> = [];\n private lastContextTokensOut?: number;\n\n onPhaseTransition(\n fromPhase: string,\n _toPhase: string,\n ctx: MiddlewareContext,\n store: MiddlewareStore,\n ): void {\n const tokens = ctx.get<TokenData>('tokens');\n const contextTokensOut = this.computeContextTokensOut(tokens?.lastUsage);\n\n this.phaseSnapshots.push({\n phase: fromPhase,\n contextTokensIn: ctx.currentPhaseFreshContext\n ? undefined\n : this.lastContextTokensOut,\n contextTokensOut,\n freshContext: ctx.currentPhaseFreshContext,\n });\n\n this.lastContextTokensOut = contextTokensOut;\n store.set('contextSize', this.getData());\n }\n\n onFinalize(\n _resultMessage: any,\n _totalDurationMs: number,\n ctx: MiddlewareContext,\n store: MiddlewareStore,\n ): void {\n const tokens = ctx.get<TokenData>('tokens');\n const contextTokensOut = this.computeContextTokensOut(tokens?.lastUsage);\n\n this.phaseSnapshots.push({\n phase: ctx.currentPhase,\n contextTokensIn: ctx.currentPhaseFreshContext\n ? undefined\n : this.lastContextTokensOut,\n contextTokensOut,\n freshContext: ctx.currentPhaseFreshContext,\n });\n\n store.set('contextSize', this.getData());\n }\n\n private computeContextTokensOut(usage: any): number | undefined {\n if (!usage) return undefined;\n return (\n Number(usage.input_tokens ?? 0) +\n Number(usage.cache_read_input_tokens ?? 0) +\n Number(usage.cache_creation_input_tokens ?? 0)\n );\n }\n\n private getData(): ContextSizeData {\n return {\n phaseSnapshots: [...this.phaseSnapshots],\n };\n }\n}\n","/**\n * Shared exact-match USD-per-token pricing by model id, and the cost formula\n * applied to a token usage delta.\n *\n * Single source of truth for both the benchmark's `CostTrackerPlugin`\n * (`@lib/middleware/benchmarks/cost-tracker`) and the live token/cost HUD\n * (`agent-interface.ts`'s per-turn usage accumulation), so the two estimates\n * never drift apart. Both reconcile against the SDK's own authoritative\n * `total_cost_usd` once the run finishes — this table only prices the\n * *live-updating* estimate shown while the agent is still running.\n *\n * Model-aware because a run's model isn't fixed: `AgentConfig.modelOverride`\n * switches specific programs to Haiku (e.g. source-map detection), and the\n * SDK reports a `model` string on every individual assistant turn (subagents\n * dispatched via the Agent tool can run on a different model than the main\n * session).\n *\n * Deliberately matched by *exact* model id, not family name (no\n * `model.includes('opus')`-style fallback): different versions of the same\n * family are priced differently — e.g. Claude Opus 4.5 ($5/$25 per Mtok) is\n * half of Opus 4.1's rate ($15/$75) — so matching on \"opus\" or \"sonnet\"\n * alone silently mis-prices a newer/older sibling at the wrong rate. The\n * only normalization applied is stripping a trailing release-date suffix\n * (`stripDateSuffix`), since Anthropic's dated and undated ids for the\n * *same* version always carry the same price (verified for every entry\n * below). Claude Sonnet 5 is the one exception with a *time-dependent*\n * price — see `sonnet5Price` — rather than a fixed table entry.\n *\n * Prices verified against https://models.dev/api.json (Anthropic section)\n * on 2026-07-01 — re-verify there when adding an entry or bumping\n * DEFAULT_AGENT_MODEL/HAIKU_MODEL, since this table isn't fetched live.\n */\n\nimport { DEFAULT_AGENT_MODEL } from '@lib/constants';\n\nexport interface PricePerMtok {\n input: number;\n output: number;\n cacheRead: number;\n cacheCreation5m: number;\n cacheCreation1h: number;\n}\n\n/**\n * `cacheCreation1h` isn't published by models.dev (it only has one\n * cache-write rate); extrapolated at `input × 2`, the ratio that holds for\n * every model below (mirrors `cacheCreation5m` = `input × 1.25`, `cacheRead`\n * = `input × 0.1` — Anthropic's standard prompt-caching multipliers).\n * Rounded to 6 decimal places to clean up binary float noise from the\n * multiplication (e.g. `3 * 0.1` is `0.30000000000000004`, not `0.3`) — well\n * past cent-level precision at the 1M-token scale these prices are quoted at.\n */\nfunction pricingFromInput(input: number, output: number): PricePerMtok {\n const round = (n: number): number => Math.round(n * 1e6) / 1e6;\n return {\n input,\n output,\n cacheRead: round(input * 0.1),\n cacheCreation5m: round(input * 1.25),\n cacheCreation1h: round(input * 2),\n };\n}\n\n/**\n * Exact-match price table, keyed by the *undated* model id prefix —\n * `pricePerMtokForModel` strips a dated suffix before falling back to this\n * table, so e.g. `HAIKU_MODEL` (`claude-haiku-4-5-20251001`) resolves via\n * the `'claude-haiku-4-5'` entry without needing its own duplicate key.\n * `DEFAULT_AGENT_MODEL` (`claude-sonnet-4-6`) has no date suffix, so it's\n * keyed directly. The rest are additional real Anthropic model ids kept\n * priced correctly in case a subagent or a future default ever reports one\n * (a turn on an id NOT in this table contributes $0 to the live estimate\n * rather than guessing — see `pricePerMtokForModel`).\n *\n * `'claude-sonnet-5'` is intentionally absent — its price is time-dependent\n * (promotional launch discount), so it's resolved separately by\n * `pricePerMtokForModel` via `SONNET_5_PRICE`.\n */\nconst PRICE_TABLE: Record<string, PricePerMtok> = {\n [DEFAULT_AGENT_MODEL]: pricingFromInput(3, 15),\n 'claude-haiku-4-5': pricingFromInput(1, 5), // HAIKU_MODEL + a date suffix\n 'claude-opus-4-5': pricingFromInput(5, 25),\n};\n\n/**\n * Claude Sonnet 5 launched at a promotional discount through 2026-08-31\n * UTC; from 2026-09-01 it reverts to the same rate as Sonnet 4.6 ($3/$15)\n * — not a coincidence, Anthropic prices it identically to 4.6 once the\n * promo ends. Re-verify against https://models.dev/api.json if this ever\n * looks off, and delete this special case once the promo window has\n * passed (its `PRICE_TABLE[DEFAULT_AGENT_MODEL]` price is the same anyway).\n */\nconst SONNET_5_PROMO_ENDS_UTC = new Date('2026-09-01T00:00:00Z');\n\nfunction sonnet5Price(now: Date): PricePerMtok {\n return now < SONNET_5_PROMO_ENDS_UTC\n ? pricingFromInput(2, 10)\n : pricingFromInput(3, 15);\n}\n\n/** Strips a trailing 8-digit release-date suffix (e.g. `-20251001`) — never\n * the version segment, so differently-versioned models are never conflated.\n * `claude-haiku-4-5-20251001` → `claude-haiku-4-5`; `claude-sonnet-4-6` (no\n * date suffix) is returned unchanged. */\nfunction stripDateSuffix(model: string): string {\n return model.replace(/-\\d{8}$/, '');\n}\n\n/**\n * Exact-match pricing lookup. `undefined` model (a caller with no model\n * context, e.g. the benchmark's `CostTrackerPlugin`) falls back to\n * `DEFAULT_AGENT_MODEL`'s price, the default for interactive runs. A\n * *given* but unrecognized model id returns `undefined` rather than\n * guessing from its family name — seeing `undefined` and skipping that\n * delta is strictly more accurate than the family-fallback this replaced,\n * which silently priced e.g. every Opus turn at Opus 4.1's rate.\n *\n * `now` is injectable (defaults to the real clock) only so\n * `sonnet5Price`'s promo-window check is deterministic in tests — no\n * other entry in this table is time-dependent.\n */\nexport function pricePerMtokForModel(\n model?: string,\n now: Date = new Date(),\n): PricePerMtok | undefined {\n if (!model) return PRICE_TABLE[DEFAULT_AGENT_MODEL];\n const undated = stripDateSuffix(model);\n if (undated === 'claude-sonnet-5') return sonnet5Price(now);\n return PRICE_TABLE[model] ?? PRICE_TABLE[undated];\n}\n\n/**\n * Cost in USD for one usage delta, priced at `usage.model`'s exact rates\n * (see `pricePerMtokForModel`) — 0 when `model` is given but not in the\n * table, rather than guessing. `cacheCreation5m`/`cacheCreation1h` come from\n * the SDK's `usage.cache_creation` breakdown, which is only reported on\n * some turns — when both are 0, `cacheCreationTokens` (the plain\n * `cache_creation_input_tokens` total) is priced at the 5m rate instead, so\n * a turn without the breakdown still gets a reasonable estimate rather than\n * being priced at $0.\n *\n * Takes the same shape as `TokenUsageDelta` (`@ui/wizard-ui`) so a caller\n * that already has one — `WizardStore.addTokenUsage` — can pass it straight\n * through instead of re-listing its fields in a fixed positional order.\n */\nexport function computeTokenCostUsd(usage: {\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens: number;\n cacheCreation5m: number;\n cacheCreation1h: number;\n cacheCreationTokens: number;\n model?: string;\n}): number {\n const price = pricePerMtokForModel(usage.model);\n if (!price) return 0;\n const hasBreakdown = usage.cacheCreation5m > 0 || usage.cacheCreation1h > 0;\n return (\n usage.inputTokens * (price.input / 1e6) +\n usage.outputTokens * (price.output / 1e6) +\n usage.cacheReadTokens * (price.cacheRead / 1e6) +\n (hasBreakdown\n ? usage.cacheCreation5m * (price.cacheCreation5m / 1e6) +\n usage.cacheCreation1h * (price.cacheCreation1h / 1e6)\n : usage.cacheCreationTokens * (price.cacheCreation5m / 1e6))\n );\n}\n\n/**\n * Shared display formatters for the hidden Ctrl+T HUD (`TokenCostHud`) and\n * the post-exit scrollback line (`exit-line.ts`) — kept here, not in either\n * of those files, since `exit-line.ts` is deliberately free of `ink`/React\n * imports (it must stay a pure, unit-testable function), and importing a\n * named export from a `.tsx` file would pull `ink` into its module graph\n * anyway. This module has no such dependency.\n */\nexport function formatTokenCount(n: number): string {\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(2)}M`;\n if (n >= 1_000) return `${(n / 1000).toFixed(1)}K`;\n return n.toLocaleString();\n}\n\nexport function formatCostUsd(usd: number): string {\n if (usd > 0 && usd < 0.01) return `$${usd.toFixed(4)}`;\n return `$${usd.toFixed(2)}`;\n}\n","import type {\n Middleware,\n MiddlewareContext,\n MiddlewareStore,\n} from '@lib/middleware/types';\nimport { computeTokenCostUsd } from '@lib/agent/token-pricing';\nimport type { TokenData } from './token-tracker';\nimport type { CacheData } from './cache-tracker';\n\nexport interface CostData {\n totalCost: number;\n phaseCosts: Array<{ phase: string; cost: number }>;\n}\n\n// Pricing table + formula moved to `@lib/agent/token-pricing` so the live\n// token/cost HUD's per-turn estimate can't drift from this benchmark's.\n// No model is passed to computeTokenCostUsd below (falls back to Sonnet\n// pricing) -- MiddlewareContext has no model field to thread through, and\n// `--benchmark` always measures the default flow, never a Haiku-overridden\n// program. Still reconciles to the SDK's authoritative total_cost_usd in\n// onFinalize below, same as the live HUD, so this only risks the\n// unreconciled per-phase breakdown.\n\nexport class CostTrackerPlugin implements Middleware {\n readonly name = 'cost';\n\n private phaseCosts: Array<{ phase: string; cost: number }> = [];\n private totalCost = 0;\n\n onPhaseTransition(\n fromPhase: string,\n _toPhase: string,\n ctx: MiddlewareContext,\n store: MiddlewareStore,\n ): void {\n const tokens = ctx.get<TokenData>('tokens');\n const cache = ctx.get<CacheData>('cache');\n const tokenSnap = tokens?.phaseSnapshots.at(-1);\n const cacheSnap = cache?.phaseSnapshots.at(-1);\n\n const totalIn = tokenSnap?.inputTokens ?? 0;\n const read = cacheSnap?.cacheReadTokens ?? 0;\n const creation = cacheSnap?.cacheCreationTokens ?? 0;\n const c5m = cacheSnap?.cacheCreation5m ?? 0;\n const c1h = cacheSnap?.cacheCreation1h ?? 0;\n const baseIn = Math.max(0, totalIn - read - creation);\n\n const phaseCost = computeTokenCostUsd({\n inputTokens: baseIn,\n outputTokens: tokenSnap?.outputTokens ?? 0,\n cacheReadTokens: read,\n cacheCreation5m: c5m,\n cacheCreation1h: c1h,\n cacheCreationTokens: creation,\n });\n\n this.phaseCosts.push({ phase: fromPhase, cost: phaseCost });\n this.totalCost += phaseCost;\n store.set('cost', this.getData());\n }\n\n onFinalize(\n resultMessage: any,\n _totalDurationMs: number,\n ctx: MiddlewareContext,\n store: MiddlewareStore,\n ): void {\n const tokens = ctx.get<TokenData>('tokens');\n const cache = ctx.get<CacheData>('cache');\n const tokenSnap = tokens?.phaseSnapshots.at(-1);\n const cacheSnap = cache?.phaseSnapshots.at(-1);\n\n const totalIn = tokenSnap?.inputTokens ?? 0;\n const read = cacheSnap?.cacheReadTokens ?? 0;\n const creation = cacheSnap?.cacheCreationTokens ?? 0;\n const c5m = cacheSnap?.cacheCreation5m ?? 0;\n const c1h = cacheSnap?.cacheCreation1h ?? 0;\n const baseIn = Math.max(0, totalIn - read - creation);\n\n const lastPhaseCost = computeTokenCostUsd({\n inputTokens: baseIn,\n outputTokens: tokenSnap?.outputTokens ?? 0,\n cacheReadTokens: read,\n cacheCreation5m: c5m,\n cacheCreation1h: c1h,\n cacheCreationTokens: creation,\n });\n\n this.phaseCosts.push({ phase: ctx.currentPhase, cost: lastPhaseCost });\n this.totalCost += lastPhaseCost;\n\n const sdkTotal =\n Number(resultMessage?.usage?.total_cost_usd ?? 0) ||\n Number(resultMessage?.total_cost_usd ?? 0);\n\n if (sdkTotal > 0 && this.totalCost > 0) {\n const scale = sdkTotal / this.totalCost;\n this.phaseCosts = this.phaseCosts.map((p) => ({\n phase: p.phase,\n cost: p.cost * scale,\n }));\n this.totalCost = sdkTotal;\n }\n\n store.set('cost', this.getData());\n }\n\n private getData(): CostData {\n return {\n totalCost: this.totalCost,\n phaseCosts: [...this.phaseCosts],\n };\n }\n}\n","/**\n * Duration tracking plugin (per-phase and total).\n */\n\nimport type {\n Middleware,\n MiddlewareContext,\n MiddlewareStore,\n} from '@lib/middleware/types';\n\nexport interface DurationData {\n phaseSnapshots: Array<{\n phase: string;\n startTime: number;\n endTime: number;\n durationMs: number;\n }>;\n totalDurationMs: number;\n}\n\nexport class DurationTrackerPlugin implements Middleware {\n readonly name = 'duration';\n\n private phaseStartTime = Date.now();\n private phaseSnapshots: Array<{\n phase: string;\n startTime: number;\n endTime: number;\n durationMs: number;\n }> = [];\n\n onPhaseTransition(\n fromPhase: string,\n _toPhase: string,\n _ctx: MiddlewareContext,\n store: MiddlewareStore,\n ): void {\n const now = Date.now();\n this.phaseSnapshots.push({\n phase: fromPhase,\n startTime: this.phaseStartTime,\n endTime: now,\n durationMs: now - this.phaseStartTime,\n });\n this.phaseStartTime = now;\n store.set('duration', {\n phaseSnapshots: [...this.phaseSnapshots],\n totalDurationMs: 0,\n } satisfies DurationData);\n }\n\n onFinalize(\n _resultMessage: any,\n totalDurationMs: number,\n ctx: MiddlewareContext,\n store: MiddlewareStore,\n ): void {\n const now = Date.now();\n this.phaseSnapshots.push({\n phase: ctx.currentPhase,\n startTime: this.phaseStartTime,\n endTime: now,\n durationMs: now - this.phaseStartTime,\n });\n\n store.set('duration', {\n phaseSnapshots: [...this.phaseSnapshots],\n totalDurationMs,\n } satisfies DurationData);\n }\n}\n","import { getUI, type SpinnerHandle } from '@ui';\nimport { AgentSignals } from '@lib/agent/agent-interface';\nimport type {\n Middleware,\n MiddlewareContext,\n MiddlewareStore,\n} from '@lib/middleware/types';\nimport type { TokenData } from './token-tracker';\nimport type { TurnData } from './turn-counter';\nimport type { CostData } from './cost-tracker';\nimport type { DurationData } from './duration-tracker';\nimport type { CompactionData } from './compaction-tracker';\nimport type { ContextSizeData } from './context-size-tracker';\nimport type { CacheData } from './cache-tracker';\n\nfunction fmtDuration(ms: number): string {\n const s = Math.round(ms / 1000);\n const m = Math.floor(s / 60);\n return m > 0 ? `${m}m ${s % 60}s` : `${s}s`;\n}\n\nfunction fmtTok(n: number): string {\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 1_000) return `${(n / 1000).toFixed(1)}K`;\n return n.toLocaleString();\n}\n\nfunction fmtCost(usd: number): string {\n if (usd > 0 && usd < 0.01) return `$${usd.toFixed(4)}`;\n return `$${usd.toFixed(2)}`;\n}\n\ninterface PhaseStats {\n phase: string;\n durationMs: number;\n turns: number;\n inputTokens: number;\n outputTokens: number;\n cacheRead: number;\n cacheCreation5m: number;\n cacheCreation1h: number;\n cost: number;\n compactions: number;\n contextOut: number | undefined;\n}\n\nfunction printPhase(s: PhaseStats): string {\n const baseIn = Math.max(\n 0,\n s.inputTokens - s.cacheRead - s.cacheCreation5m - s.cacheCreation1h,\n );\n return [\n `${s.phase}: ${fmtDuration(s.durationMs)}, ${\n s.turns\n } turns, cost: ${fmtCost(s.cost)}`,\n ` in: ${fmtTok(baseIn)}, out: ${fmtTok(\n s.outputTokens,\n )}, cache_read: ${fmtTok(s.cacheRead)}, cache_5m: ${fmtTok(\n s.cacheCreation5m,\n )}, cache_1h: ${fmtTok(s.cacheCreation1h)}`,\n s.compactions > 0 ? ` ${s.compactions} compaction(s)` : null,\n s.contextOut !== undefined ? ` ctx_out: ${fmtTok(s.contextOut)}` : null,\n ]\n .filter(Boolean)\n .join('\\n');\n}\n\nfunction getPhaseStats(i: number, ctx: MiddlewareContext): PhaseStats | null {\n const duration = ctx.get<DurationData>('duration');\n const dur = duration?.phaseSnapshots[i];\n if (!dur) return null;\n\n const tokens = ctx.get<TokenData>('tokens');\n const turns = ctx.get<TurnData>('turns');\n const cost = ctx.get<CostData>('cost');\n const compactions = ctx.get<CompactionData>('compactions');\n const contextSize = ctx.get<ContextSizeData>('contextSize');\n const cache = ctx.get<CacheData>('cache');\n\n return {\n phase: dur.phase,\n durationMs: dur.durationMs,\n turns: turns?.phaseSnapshots[i]?.turns ?? 0,\n inputTokens: tokens?.phaseSnapshots[i]?.inputTokens ?? 0,\n outputTokens: tokens?.phaseSnapshots[i]?.outputTokens ?? 0,\n cacheRead: cache?.phaseSnapshots[i]?.cacheReadTokens ?? 0,\n cacheCreation5m: cache?.phaseSnapshots[i]?.cacheCreation5m ?? 0,\n cacheCreation1h: cache?.phaseSnapshots[i]?.cacheCreation1h ?? 0,\n cost: cost?.phaseCosts[i]?.cost ?? 0,\n compactions: compactions?.phaseSnapshots[i]?.compactions ?? 0,\n contextOut: contextSize?.phaseSnapshots[i]?.contextTokensOut,\n };\n}\n\nexport class SummaryPlugin implements Middleware {\n readonly name = 'summary';\n\n private spinner: SpinnerHandle;\n\n constructor(spinner: SpinnerHandle) {\n this.spinner = spinner;\n }\n\n onPhaseTransition(\n fromPhase: string,\n toPhase: string,\n ctx: MiddlewareContext,\n _store: MiddlewareStore,\n ): void {\n const duration = ctx.get<DurationData>('duration');\n const idx = (duration?.phaseSnapshots.length ?? 1) - 1;\n const stats = getPhaseStats(idx, ctx);\n\n if (stats) {\n this.spinner.stop(`${AgentSignals.BENCHMARK} ${printPhase(stats)}`);\n } else {\n this.spinner.stop(`${AgentSignals.BENCHMARK} ${fromPhase}`);\n }\n\n getUI().log.info(`${AgentSignals.BENCHMARK} Starting phase: ${toPhase}`);\n this.spinner.start(`Integrating PostHog (${toPhase})...`);\n }\n\n onFinalize(\n _resultMessage: any,\n totalDurationMs: number,\n ctx: MiddlewareContext,\n _store: MiddlewareStore,\n ): void {\n const duration = ctx.get<DurationData>('duration');\n const cost = ctx.get<CostData>('cost');\n const tokens = ctx.get<TokenData>('tokens');\n const cache = ctx.get<CacheData>('cache');\n\n const phaseCount = duration?.phaseSnapshots.length ?? 0;\n const totalCost = cost?.totalCost ?? 0;\n\n getUI().log.info('');\n getUI().log.info(\n `◇ ${AgentSignals.BENCHMARK} ${phaseCount} phases in ${fmtDuration(\n totalDurationMs,\n )}, cost: ${fmtCost(totalCost)}`,\n );\n getUI().log.info(\n ` total in: ${fmtTok(tokens?.totalInput ?? 0)}, out: ${fmtTok(\n tokens?.totalOutput ?? 0,\n )}, cache_read: ${fmtTok(cache?.totalRead ?? 0)}, cache_5m: ${fmtTok(\n cache?.totalCreation5m ?? 0,\n )}, cache_1h: ${fmtTok(cache?.totalCreation1h ?? 0)}`,\n );\n getUI().log.info('');\n getUI().log.info(`● ${AgentSignals.BENCHMARK} Summary by phase:`);\n\n if (duration?.phaseSnapshots) {\n for (let i = 0; i < duration.phaseSnapshots.length; i++) {\n const stats = getPhaseStats(i, ctx);\n if (stats) {\n getUI().log.info(printPhase(stats));\n }\n }\n }\n\n getUI().log.info('');\n }\n}\n","/**\n * JSON file output plugin.\n *\n * Assembles the BenchmarkData structure from all upstream plugin data\n * and writes it to a JSON file. Returns the BenchmarkData for backward compat.\n */\n\nimport fs from 'fs';\nimport { getUI } from '@ui';\nimport { logToFile } from '@utils/debug';\nimport { AgentSignals } from '@lib/agent/agent-interface';\nimport type {\n Middleware,\n MiddlewareContext,\n MiddlewareStore,\n} from '@lib/middleware/types';\nimport type { TokenData } from './token-tracker';\nimport type { CacheData } from './cache-tracker';\nimport type { TurnData } from './turn-counter';\nimport type { CostData } from './cost-tracker';\nimport type { DurationData } from './duration-tracker';\nimport type { CompactionData } from './compaction-tracker';\nimport type { ContextSizeData } from './context-size-tracker';\nimport type { BenchmarkData, StepUsage } from '@lib/middleware/benchmark';\n\n/**\n * Sum token usage across all models from the SDK's modelUsage field.\n */\nfunction sumModelUsage(modelUsage: Record<string, any>): {\n input_tokens: number;\n output_tokens: number;\n cache_creation_input_tokens: number;\n cache_read_input_tokens: number;\n} {\n let input_tokens = 0;\n let output_tokens = 0;\n let cache_creation_input_tokens = 0;\n let cache_read_input_tokens = 0;\n\n for (const model of Object.values(modelUsage)) {\n input_tokens += model.inputTokens ?? 0;\n output_tokens += model.outputTokens ?? 0;\n cache_creation_input_tokens += model.cacheCreationInputTokens ?? 0;\n cache_read_input_tokens += model.cacheReadInputTokens ?? 0;\n }\n\n return {\n input_tokens,\n output_tokens,\n cache_creation_input_tokens,\n cache_read_input_tokens,\n };\n}\n\nexport class JsonWriterPlugin implements Middleware {\n readonly name = 'jsonWriter';\n\n private outputPath: string;\n\n constructor(outputPath: string) {\n this.outputPath = outputPath;\n }\n\n onFinalize(\n resultMessage: any,\n totalDurationMs: number,\n ctx: MiddlewareContext,\n _store: MiddlewareStore,\n ): BenchmarkData {\n const tokens = ctx.get<TokenData>('tokens');\n const cache = ctx.get<CacheData>('cache');\n const turns = ctx.get<TurnData>('turns');\n const cost = ctx.get<CostData>('cost');\n const duration = ctx.get<DurationData>('duration');\n const compactions = ctx.get<CompactionData>('compactions');\n const contextSize = ctx.get<ContextSizeData>('contextSize');\n\n const modelUsage = resultMessage?.modelUsage ?? {};\n const aggregateUsage = sumModelUsage(modelUsage);\n\n const phaseCount = duration?.phaseSnapshots.length ?? 0;\n const steps: StepUsage[] = [];\n\n for (let i = 0; i < phaseCount; i++) {\n const dur = duration!.phaseSnapshots[i];\n const tokenSnap = tokens?.phaseSnapshots[i];\n const cacheSnap = cache?.phaseSnapshots[i];\n const turnSnap = turns?.phaseSnapshots[i];\n const costSnap = cost?.phaseCosts[i];\n const compSnap = compactions?.phaseSnapshots[i];\n const ctxSnap = contextSize?.phaseSnapshots[i];\n\n const step: StepUsage = {\n name: dur.phase,\n usage: {\n input_tokens: tokenSnap?.inputTokens ?? 0,\n output_tokens: tokenSnap?.outputTokens ?? 0,\n cache_creation_input_tokens: cacheSnap?.cacheCreationTokens ?? 0,\n cache_read_input_tokens: cacheSnap?.cacheReadTokens ?? 0,\n ...((cacheSnap?.cacheCreation5m ?? 0) +\n (cacheSnap?.cacheCreation1h ?? 0) >\n 0 && {\n cache_creation: {\n ephemeral_5m_input_tokens: cacheSnap?.cacheCreation5m ?? 0,\n ephemeral_1h_input_tokens: cacheSnap?.cacheCreation1h ?? 0,\n },\n }),\n },\n modelUsage: {},\n totalCostUsd: costSnap?.cost ?? 0,\n durationMs: dur.durationMs,\n durationApiMs: 0,\n numTurns: turnSnap?.turns ?? 0,\n ...(ctxSnap?.contextTokensIn !== undefined && {\n contextTokensIn: ctxSnap.contextTokensIn,\n }),\n ...(ctxSnap?.contextTokensOut !== undefined && {\n contextTokensOut: ctxSnap.contextTokensOut,\n }),\n ...(compSnap && compSnap.compactions > 0\n ? {\n compactions: compSnap.compactions,\n compactionPreTokens: compSnap.preTokens,\n }\n : {}),\n };\n\n steps.push(step);\n }\n\n const totalTurns = turns?.totalTurns ?? 0;\n const totalCost = cost?.totalCost ?? 0;\n const totalCompactions = compactions?.totalCompactions ?? 0;\n const fromModelUsage =\n aggregateUsage.input_tokens +\n aggregateUsage.cache_read_input_tokens +\n aggregateUsage.cache_creation_input_tokens;\n const inputTokens =\n fromModelUsage > 0\n ? fromModelUsage\n : (tokens?.totalInput ?? 0) +\n (cache?.totalRead ?? 0) +\n (cache?.totalCreation ?? 0);\n const outputTokens =\n aggregateUsage.output_tokens > 0\n ? aggregateUsage.output_tokens\n : tokens?.totalOutput ?? 0;\n\n const benchmark: BenchmarkData = {\n timestamp: new Date().toISOString(),\n steps,\n totals: {\n totalCostUsd: totalCost,\n durationMs: totalDurationMs,\n inputTokens,\n outputTokens,\n numTurns: resultMessage?.num_turns ?? totalTurns,\n totalCompactions,\n totalCacheReadTokens: cache?.totalRead ?? 0,\n totalCacheCreation5mTokens: cache?.totalCreation5m ?? 0,\n totalCacheCreation1hTokens: cache?.totalCreation1h ?? 0,\n },\n };\n\n this.writeBenchmarkData(benchmark);\n return benchmark;\n }\n\n private writeBenchmarkData(data: BenchmarkData): void {\n try {\n fs.writeFileSync(this.outputPath, JSON.stringify(data, null, 2));\n logToFile(`Benchmark data written to ${this.outputPath}`);\n getUI().log.info(\n `● ${AgentSignals.BENCHMARK} Results written to ${this.outputPath}`,\n );\n } catch (error) {\n logToFile('Failed to write benchmark data:', error);\n }\n }\n}\n","/**\n * Plugin registry and factory.\n *\n * Maps plugin names to constructors and creates the ordered plugin list\n * from a BenchmarkConfig.\n */\n\nimport type {\n Middleware,\n MiddlewareFactoryOptions,\n} from '@lib/middleware/types';\nimport type { BenchmarkConfig } from '@lib/middleware/config';\nimport { TurnCounterPlugin } from './turn-counter';\nimport { TokenTrackerPlugin } from './token-tracker';\nimport { CacheTrackerPlugin } from './cache-tracker';\nimport { CompactionTrackerPlugin } from './compaction-tracker';\nimport { ContextSizeTrackerPlugin } from './context-size-tracker';\nimport { CostTrackerPlugin } from './cost-tracker';\nimport { DurationTrackerPlugin } from './duration-tracker';\nimport { SummaryPlugin } from './summary';\nimport { JsonWriterPlugin } from './json-writer';\n\ntype PluginFactory = (opts: MiddlewareFactoryOptions) => Middleware;\n\nconst PLUGIN_REGISTRY: Record<string, PluginFactory> = {\n turns: () => new TurnCounterPlugin(),\n tokens: () => new TokenTrackerPlugin(),\n cache: () => new CacheTrackerPlugin(),\n compactions: () => new CompactionTrackerPlugin(),\n contextSize: () => new ContextSizeTrackerPlugin(),\n cost: () => new CostTrackerPlugin(),\n duration: () => new DurationTrackerPlugin(),\n summary: (opts) => new SummaryPlugin(opts.spinner!),\n jsonWriter: (opts) => new JsonWriterPlugin(opts.outputPath!),\n};\n\n/**\n * Execution order — data producers before consumers:\n * turns (dedup) -> tokens -> cache -> compactions -> contextSize -> cost -> duration -> summary -> jsonWriter\n */\nconst PLUGIN_ORDER = [\n 'turns',\n 'tokens',\n 'cache',\n 'compactions',\n 'contextSize',\n 'cost',\n 'duration',\n 'summary',\n 'jsonWriter',\n];\n\nexport function createPluginsFromConfig(\n config: BenchmarkConfig,\n opts: MiddlewareFactoryOptions,\n): Middleware[] {\n const resolvedOpts: MiddlewareFactoryOptions = {\n ...opts,\n outputPath: opts.outputPath ?? config.output.benchmarkPath,\n };\n\n // If suppressWizardLogs is set, disable the summary plugin\n const effectivePlugins = { ...config.plugins };\n if (config.output.suppressWizardLogs) {\n effectivePlugins.summary = false;\n }\n\n return PLUGIN_ORDER.filter((name) => effectivePlugins[name] !== false)\n .map((name) => PLUGIN_REGISTRY[name])\n .filter(Boolean)\n .map((factory) => factory(resolvedOpts));\n}\n","/**\n * Benchmark tracking for wizard runs.\n *\n * Usage:\n * const pipeline = createBenchmarkPipeline(spinner, options);\n * pipeline.onMessage(message);\n * pipeline.finalize(resultMessage, durationMs);\n */\n\nimport { getUI, type SpinnerHandle } from '@ui';\nimport { logToFile, getLogFilePath, configureLogFile } from '@utils/debug';\nimport { MiddlewarePipeline } from './pipeline';\nimport { PhaseDetector } from './phase-detector';\nimport { loadBenchmarkConfig } from './config';\nimport { createPluginsFromConfig } from './benchmarks';\nimport type { BenchmarkConfig } from './config';\nimport type { WizardRunOptions } from '@utils/types';\nimport { AgentSignals } from '@lib/agent/agent-interface';\n\n// ── Types ──────────────────────────────────────────────────────────────\n\nexport interface StepUsage {\n name: string;\n usage: {\n input_tokens: number;\n output_tokens: number;\n cache_creation_input_tokens: number;\n cache_read_input_tokens: number;\n cache_creation?: {\n ephemeral_5m_input_tokens: number;\n ephemeral_1h_input_tokens: number;\n };\n };\n modelUsage: Record<string, unknown>;\n totalCostUsd: number;\n durationMs: number;\n durationApiMs: number;\n numTurns: number;\n contextTokensIn?: number;\n contextTokensOut?: number;\n compactions?: number;\n compactionPreTokens?: number[];\n}\n\nexport interface BenchmarkData {\n timestamp: string;\n steps: StepUsage[];\n totals: {\n totalCostUsd: number;\n durationMs: number;\n inputTokens: number;\n outputTokens: number;\n numTurns: number;\n totalCompactions: number;\n totalCacheReadTokens: number;\n totalCacheCreation5mTokens: number;\n totalCacheCreation1hTokens: number;\n };\n}\n\n// ── Factory ────────────────────────────────────────────────────────────\n\n/**\n * Create a middleware pipeline configured for benchmarking.\n * Loads .benchmark-config.json from the install dir, falls back to defaults.\n */\nexport function createBenchmarkPipeline(\n spinner: SpinnerHandle,\n options: WizardRunOptions,\n configOverride?: BenchmarkConfig,\n): MiddlewarePipeline {\n const config = configOverride ?? loadBenchmarkConfig(options.installDir);\n\n configureLogFile({\n path: config.output.logPath,\n enabled: config.output.logEnabled,\n });\n\n const plugins = createPluginsFromConfig(config, {\n spinner,\n phased: false,\n outputPath: config.output.benchmarkPath,\n });\n\n if (!config.output.suppressWizardLogs) {\n getUI().log.info(\n `${AgentSignals.BENCHMARK} Verbose logs: ${getLogFilePath()}`,\n );\n getUI().log.info(\n `${AgentSignals.BENCHMARK} Benchmark data will be written to: ${config.output.benchmarkPath}`,\n );\n }\n\n logToFile(\n `${AgentSignals.BENCHMARK} Tracking enabled, starting with setup phase`,\n );\n\n return new MiddlewarePipeline(plugins, {\n phaseDetector: new PhaseDetector(),\n autoDetectPhases: true,\n });\n}\n","/**\n * Agent prompt assembly.\n *\n * Three sections, always in this order:\n * 1. Default project prompt — credentials and base context (always included)\n * 2. Custom prompt — additional program-specific instructions (if set)\n * 3. Skill prompt — \"follow SKILL.md\" instructions (if a skill was installed)\n */\n\nimport type { ProgramRun } from './agent-runner.js';\nimport type { HostResolution } from '@lib/host-resolution';\n\n/**\n * Values available to prompt builders after OAuth completes.\n */\nexport interface PromptContext {\n projectId: number;\n projectApiKey: string;\n host: HostResolution;\n /** Set when skillId was provided and the skill was installed successfully. */\n skillPath?: string;\n /**\n * Org-level AI consent (`is_ai_data_processing_approved`) read from the\n * `/api/users/@me/` payload at auth time. `null` = unknown (older orgs,\n * or the user fetch failed). Lets prompts pre-resolve consent state so\n * agents only ask the user when it is actually off or unknown.\n */\n orgAiDataProcessingApproved?: boolean | null;\n /**\n * Team product opt-ins from the `/api/projects/:id/` payload at auth\n * time. Project-level truth for \"is this product enabled\" — products\n * can be instrumented from other repos or the snippet, so repo-local\n * evidence must never rule them out. `null` field = unknown.\n */\n teamProductOptIns?: {\n sessionReplay?: boolean | null;\n exceptionAutocapture?: boolean | null;\n surveys?: boolean | null;\n } | null;\n}\n\nfunction defaultProjectPrompt(ctx: PromptContext): string {\n return `You have access to the PostHog MCP server.\n\nProject context:\n- PostHog Project ID: ${ctx.projectId}\n- PostHog public token: ${ctx.projectApiKey}\n- PostHog Host: ${ctx.host.apiHost}`;\n}\n\nfunction skillPrompt(skillPath: string, reportFile: string): string {\n return `A PostHog skill has been installed at ${skillPath}/. Read ${skillPath}/SKILL.md and follow its instructions completely.\n\nAfter completing the skill workflow, write a brief markdown report to ./${reportFile} summarizing:\n- What changes were made to the project\n- Which files were modified or created\n- Any manual steps the user should take next\n\nImportant: You must read a file immediately before attempting to write it, even if you have previously read it; failure to do so will cause a tool failure.`;\n}\n\n/**\n * Assemble the final agent prompt from the program's run config.\n */\nexport function assemblePrompt(runDef: ProgramRun, ctx: PromptContext): string {\n const parts: string[] = [];\n\n // Always include the default project prompt\n parts.push(defaultProjectPrompt(ctx));\n\n // Additional program-specific instructions\n if (runDef.customPrompt) {\n parts.push(runDef.customPrompt(ctx));\n }\n\n // Skill prompt (appended when a skill was pre-installed)\n if (ctx.skillPath) {\n parts.push(skillPrompt(ctx.skillPath, runDef.reportFile));\n }\n\n return parts.join('\\n\\n');\n}\n","/**\n * Shared error helpers for the runner pipeline.\n */\n\nimport type { InstallSkillResult } from '@lib/wizard-tools';\nimport { skillErrorCode } from '@lib/errors';\nimport { wizardAbort, WizardError } from '@utils/wizard-abort';\n\nexport async function abortOnInstallFailure(\n integrationLabel: string,\n result: InstallSkillResult,\n): Promise<void> {\n if (result.kind === 'ok') return;\n\n const code = skillErrorCode(result) ?? undefined;\n\n const message = (() => {\n switch (result.kind) {\n case 'menu-fetch-failed':\n return 'Could not fetch the skill menu from context-mill.\\nCheck your network connection and try again.';\n case 'skill-not-found':\n return `Could not find the \"${result.skillId}\" skill in the context-mill menu.\\nPlease try again later.`;\n case 'download-failed':\n return `Failed to install skill: ${result.message}\\nPlease try again.`;\n }\n })();\n\n await wizardAbort({\n message,\n code,\n error: new WizardError(\n `Skill install failed: ${result.kind}`,\n {\n integration: integrationLabel,\n error_type: result.kind,\n platform: process.platform,\n ...(result.kind === 'download-failed'\n ? { error_detail: result.message.slice(0, 500) }\n : {}),\n },\n code,\n ),\n });\n}\n","/**\n * The linear pipeline. Single execution path for all non-orchestrator programs,\n * both skill-based (revenue analytics) and framework-based (core integration).\n * The `ProgramRun` controls what varies between them; `programConfig` carries the\n * program-level static metadata (tool allow/disallow lists, etc.).\n */\n\nimport type { WizardSession } from '../../../wizard-session';\nimport { OutroKind } from '../../../wizard-session';\nimport { getUI } from '../../../../ui';\nimport { AgentErrorType, AgentSignals } from '../../agent-interface';\nimport { restoreClaudeSettings } from '../../claude-settings';\nimport { logToFile } from '../../../../utils/debug';\nimport { createBenchmarkPipeline } from '../../../middleware/benchmark';\nimport {\n wizardAbort,\n WizardError,\n registerCleanup,\n} from '../../../../utils/wizard-abort';\nimport { ErrorCodes, AGENT_ERROR_CODE } from '@lib/errors';\nimport { analytics } from '../../../../utils/analytics';\nimport {\n formatScanReport,\n formatYaraAbortMessage,\n writeScanReport,\n} from '../../../yara-hooks';\nimport { installSkillById } from '../../../wizard-tools';\nimport { createWizardAskBridge } from '../../../wizard-ask-bridge';\nimport type { ProgramConfig } from '../../../programs/program-step';\nimport { assemblePrompt } from '../../agent-prompt';\nimport type { ProgramRun, BootstrapResult } from '../shared/types';\nimport { abortOnInstallFailure } from '../shared/errors';\nimport { shouldDisableAsk, sessionToOptions } from '../shared/bootstrap';\nimport { resolveHarness, getHarness } from '../switchboard';\n\nexport async function runLinearProgram(\n session: WizardSession,\n config: ProgramRun,\n programConfig: ProgramConfig,\n boot: BootstrapResult,\n composed = false,\n): Promise<void> {\n const { skillsBaseUrl, credentials, wizardFlags, project } = boot;\n const { projectApiKey, host, projectId } = credentials;\n\n // 5. Skill install (if skillId provided)\n let skillPath: string | undefined;\n if (config.skillId) {\n logToFile(`[agent-runner] installing skill ${config.skillId}`);\n const installResult = await installSkillById(\n config.skillId,\n session.installDir,\n skillsBaseUrl,\n { triage: boot.triageProvider },\n );\n if (installResult.kind !== 'ok') {\n await abortOnInstallFailure(config.integrationLabel, installResult);\n return;\n }\n skillPath = installResult.path;\n logToFile(`[agent-runner] skill installed at ${skillPath}`);\n }\n\n // 6. Initialize agent\n const spinner = getUI().spinner();\n\n const restoreSettings = () => restoreClaudeSettings(session.installDir);\n getUI().onEnterScreen('outro', restoreSettings);\n\n if (session.yaraReport) {\n registerCleanup(() => {\n const reportPath = writeScanReport();\n if (reportPath) {\n const summary = formatScanReport();\n getUI().log.info(`YARA scan report: ${reportPath}${summary ?? ''}`);\n }\n });\n }\n\n getUI().startRun();\n\n // wizard_ask is only available in interactive mode. CI/signup users have\n // no way to answer; we omit the bridge so the tool returns an actionable\n // error rather than hanging on a never-resolving prompt.\n const askDisabled = shouldDisableAsk(session);\n const askBridge = askDisabled\n ? undefined\n : createWizardAskBridge({\n getSource: () => session.skillId ?? config.integrationLabel,\n showQuestion: (q) => getUI().requestQuestion(q),\n cancelQuestion: () => getUI().cancelPendingQuestion(),\n richLinks: config.richLinks ?? false,\n timeoutMs: config.askTimeoutMs,\n });\n\n const middleware = session.benchmark\n ? createBenchmarkPipeline(spinner, sessionToOptions(session))\n : undefined;\n\n // 7. Build prompt\n const prompt = assemblePrompt(config, {\n projectId,\n projectApiKey,\n host,\n skillPath,\n orgAiDataProcessingApproved:\n session.apiUser?.organization?.is_ai_data_processing_approved ?? null,\n teamProductOptIns: project\n ? {\n sessionReplay: project.session_recording_opt_in ?? null,\n exceptionAutocapture: project.autocapture_exceptions_opt_in ?? null,\n surveys: project.surveys_opt_in ?? null,\n }\n : null,\n });\n logToFile(`[agent-runner] prompt assembled (${prompt.length} chars)`);\n\n // 8. Resolve the (runner, model) pair from the central plan and run the agent\n // through the selected runner. The runner owns the agent loop + model\n // transport; everything around it (skill install, prompt, ask bridge, error\n // routing, outro) stays here so every runner shares it.\n const pick = resolveHarness({\n program: programConfig.id,\n flags: wizardFlags,\n flagPayloads: boot.wizardFlagPayloads,\n cliHarness: session.harness,\n cliModel: session.model,\n });\n const agentResult = await getHarness(pick.harness).run({\n session,\n config,\n programConfig,\n boot,\n prompt,\n skillPath,\n spinner,\n askBridge,\n middleware,\n model: pick.model,\n thinkingLevel: pick.thinkingLevel,\n });\n\n // 9. Error handling (full set from both runners)\n if (agentResult.error === AgentErrorType.ABORT) {\n const reason = agentResult.message ?? '';\n const matched = config.abortCases?.find((c) => c.match.test(reason));\n const abortCode = matched?.errorCode ?? ErrorCodes.AgentAbort;\n const outroData: WizardSession['outroData'] = matched\n ? {\n kind: OutroKind.Error,\n message: matched.message,\n body: matched.body,\n docsUrl: matched.docsUrl,\n errorCode: abortCode,\n errorDetail: { reason },\n }\n : {\n kind: OutroKind.Error,\n message: `${config.integrationLabel} aborted`,\n body: reason || 'The agent aborted the program.',\n docsUrl: config.docsUrl,\n errorCode: abortCode,\n errorDetail: { reason },\n };\n analytics.wizardCapture('agent aborted', {\n integration: config.integrationLabel,\n reason,\n matched: matched?.message ?? null,\n });\n await wizardAbort({\n outroData,\n code: abortCode,\n error: new WizardError(\n `Agent aborted: ${reason}`,\n {\n integration: config.integrationLabel,\n error_type: AgentErrorType.ABORT,\n reason,\n },\n abortCode,\n ),\n });\n }\n\n if (agentResult.error === AgentErrorType.MCP_MISSING) {\n await wizardAbort({\n code: AGENT_ERROR_CODE[AgentErrorType.MCP_MISSING],\n message:\n 'Could not access the PostHog MCP server\\n\\n' +\n 'The wizard was unable to connect to the PostHog MCP server.\\n' +\n 'This could be due to a network issue or a configuration problem.\\n\\n' +\n `Please try again, or check the documentation:\\n${config.docsUrl}`,\n error: new WizardError(\n 'Agent could not access PostHog MCP server',\n {\n integration: config.integrationLabel,\n error_type: AgentErrorType.MCP_MISSING,\n signal: AgentSignals.ERROR_MCP_MISSING,\n },\n AGENT_ERROR_CODE[AgentErrorType.MCP_MISSING],\n ),\n });\n }\n\n if (agentResult.error === AgentErrorType.RESOURCE_MISSING) {\n await wizardAbort({\n code: AGENT_ERROR_CODE[AgentErrorType.RESOURCE_MISSING],\n message:\n 'Could not access the setup resource\\n\\n' +\n 'This may indicate a version mismatch or a temporary service issue.\\n\\n' +\n `Please try again, or check the documentation:\\n${config.docsUrl}`,\n error: new WizardError(\n 'Agent could not access setup resource',\n {\n integration: config.integrationLabel,\n error_type: AgentErrorType.RESOURCE_MISSING,\n signal: AgentSignals.ERROR_RESOURCE_MISSING,\n },\n AGENT_ERROR_CODE[AgentErrorType.RESOURCE_MISSING],\n ),\n });\n }\n\n if (agentResult.error === AgentErrorType.YARA_VIOLATION) {\n await wizardAbort({\n code: AGENT_ERROR_CODE[AgentErrorType.YARA_VIOLATION],\n message: formatYaraAbortMessage(),\n error: new WizardError(\n 'YARA scanner terminated session',\n {\n integration: config.integrationLabel,\n error_type: AgentErrorType.YARA_VIOLATION,\n },\n AGENT_ERROR_CODE[AgentErrorType.YARA_VIOLATION],\n ),\n });\n }\n\n if (agentResult.error === AgentErrorType.NO_PROGRESS) {\n analytics.wizardCapture('agent no progress', {\n integration: config.integrationLabel,\n error_type: AgentErrorType.NO_PROGRESS,\n });\n await wizardAbort({\n code: AGENT_ERROR_CODE[AgentErrorType.NO_PROGRESS],\n message:\n 'The Wizard exited without changing your project. Please contact the ' +\n 'PostHog team with wizard@posthog.com about this error.',\n error: new WizardError(\n 'Agent made no progress',\n {\n integration: config.integrationLabel,\n error_type: AgentErrorType.NO_PROGRESS,\n },\n AGENT_ERROR_CODE[AgentErrorType.NO_PROGRESS],\n ),\n });\n }\n\n if (agentResult.error === AgentErrorType.INCOMPLETE_TASKS) {\n analytics.wizardCapture('agent incomplete tasks', {\n integration: config.integrationLabel,\n error_type: AgentErrorType.INCOMPLETE_TASKS,\n });\n await wizardAbort({\n code: AGENT_ERROR_CODE[AgentErrorType.INCOMPLETE_TASKS],\n message:\n 'The Wizard exited without completing its planned tasks. Please contact ' +\n 'the PostHog team with wizard@posthog.com about this error.',\n error: new WizardError(\n 'Agent left planned tasks incomplete',\n {\n integration: config.integrationLabel,\n error_type: AgentErrorType.INCOMPLETE_TASKS,\n },\n AGENT_ERROR_CODE[AgentErrorType.INCOMPLETE_TASKS],\n ),\n });\n }\n\n if (\n agentResult.error === AgentErrorType.RATE_LIMIT ||\n agentResult.error === AgentErrorType.API_ERROR\n ) {\n analytics.wizardCapture('agent api error', {\n integration: config.integrationLabel,\n error_type: agentResult.error,\n error_message: agentResult.message,\n });\n\n await wizardAbort({\n code: AGENT_ERROR_CODE[agentResult.error],\n message: `API Error\\n\\n${\n agentResult.message || 'Unknown error'\n }\\n\\nPlease report this to: wizard@posthog.com`,\n error: new WizardError(\n `API error: ${agentResult.message}`,\n {\n integration: config.integrationLabel,\n error_type: agentResult.error,\n },\n AGENT_ERROR_CODE[agentResult.error],\n ),\n });\n }\n\n // 10. Post-run hooks\n if (config.postRun) {\n await config.postRun(session, credentials);\n }\n\n // A composed sub-run (integration inside self-driving) skips the terminal\n // outro + analytics shutdown so the shared client survives the host's run.\n if (composed) return;\n\n // 11. Outro\n // Push outro data through the UI (not via direct `session.outroData = ...`\n // mutation) so the live store gets the value. agent-runner's `session`\n // parameter is captured at runAgent() invocation time, and any `setKey`\n // call between then and here (e.g. setDashboardUrl, setNotebookUrl) forks\n // the session reference — direct mutation then lands on a stale snapshot\n // that the screen never reads. UI.setOutroData() goes through the store\n // and also merges in any post-snapshot URLs from the live session.\n const outroData = config.buildOutroData\n ? config.buildOutroData(session, credentials)\n : {\n kind: OutroKind.Success,\n message: config.successMessage,\n reportFile: config.reportFile,\n docsUrl: config.docsUrl,\n continueUrl: session.signup\n ? `${host.appHost}/products?source=wizard`\n : undefined,\n };\n if (outroData) {\n getUI().setOutroData(outroData);\n }\n\n getUI().outro(config.successMessage);\n\n // 12. Analytics shutdown\n await analytics.shutdown('success');\n}\n","/**\n * Ring the terminal bell (BEL, U+0007).\n *\n * The orchestrator takes consent for the warehouse step at the top of the run\n * and asks for the credentials at the end of it, several autonomous minutes\n * later. The person who agreed is often looking at something else by then. A\n * bell is the one attention signal a terminal in a background tab can still\n * deliver, and it costs a user who is watching nothing.\n *\n * Written to stderr, not stdout: Ink owns stdout and repaints whole frames, so\n * a byte written there can land inside one. Silent when stderr is not a TTY —\n * a pipe or a CI log cannot ring, and the byte would only pollute the capture.\n */\nexport function ringTerminalBell(): void {\n if (!process.stderr.isTTY) return;\n try {\n process.stderr.write('\\u0007');\n } catch {\n // A bell is a nicety. It must never be the thing that ends a run.\n }\n}\n","/**\n * The executor drains the queue. It starts every runnable task (dependencies\n * satisfied) as soon as it becomes runnable — parallelism is decided by the\n * task graph, not by an executor knob. Each task runs through an injected\n * `runTask` function and reports its outcome via `complete_task`; a task that\n * ends without reporting is retried while attempts remain, then failed. A\n * `maxStarts` backstop guarantees termination.\n *\n * The drain loop is independent of how a task actually runs. `runTask` is\n * injected: the real one spins up a fresh agent, the tests use a fake.\n */\nimport { analytics } from '@utils/analytics';\nimport { logToFile } from '@utils/debug';\nimport { TaskStatus, type QueueStore, type QueuedTask } from './queue';\n\n/** Per-task agent configuration the resolver produces from a task's type.\n * The model is resolved separately (per-harness profile), not here. */\nexport interface ResolvedTask {\n allowedTools: readonly string[];\n disallowedTools: readonly string[];\n /** Mini-skills to install before the task runs (the HOW). */\n skills: readonly string[];\n prompt: string;\n}\n\n/** Resolves a queued task to what the agent needs. The real one is markdown-backed. */\nexport type TaskResolver = (\n task: QueuedTask,\n store: QueueStore,\n) => ResolvedTask;\n\n/** Runs one task's agent. It is expected to drive the task to a terminal state\n * (via the task agent calling complete_task). */\nexport type RunTask = (task: QueuedTask) => Promise<void>;\n\nexport interface DrainOptions {\n /** Backstop against a pathological always-one-more-pending loop. */\n maxStarts: number;\n}\n\nexport const DEFAULT_DRAIN_OPTIONS: DrainOptions = {\n maxStarts: 200,\n};\n\nasync function runOne(\n store: QueueStore,\n runTask: RunTask,\n task: QueuedTask,\n): Promise<void> {\n store.start(task.id);\n try {\n await runTask(task);\n } catch (error) {\n // The task threw rather than reporting. The outcome check below handles\n // the queue; the exception itself should never be silent.\n logToFile(`[executor] runTask threw for ${task.type}:`, error);\n analytics.captureException(\n error instanceof Error ? error : new Error(String(error)),\n { step: 'orchestrator_run_task', task_type: task.type },\n );\n }\n\n const after = store.get(task.id);\n if (!after) return;\n\n if (after.status === TaskStatus.Running) {\n // The agent ended without calling complete_task. Retry or fail.\n if (after.attempts < after.maxAttempts) {\n store.requeue(task.id);\n } else {\n store.fail(task.id, {\n type: 'no-report',\n message: 'Task ended without calling complete_task.',\n });\n }\n return;\n }\n\n if (\n after.status === TaskStatus.Failed &&\n after.attempts < after.maxAttempts\n ) {\n store.requeue(task.id);\n }\n}\n\n/**\n * Drain the queue to a terminal state. Every runnable task starts the moment\n * its dependencies finish; independent branches run concurrently. Returns when\n * every task is done, failed, or blocked by a failed dependency, or when the\n * start backstop trips.\n */\nexport async function drainQueue(\n store: QueueStore,\n runTask: RunTask,\n opts: DrainOptions = DEFAULT_DRAIN_OPTIONS,\n): Promise<void> {\n const running = new Map<string, Promise<void>>();\n let starts = 0;\n\n for (;;) {\n for (const task of store.nextRunnable()) {\n if (++starts > opts.maxStarts) break;\n // runOne marks the task running synchronously, so the next\n // nextRunnable() call no longer offers it.\n const p = runOne(store, runTask, task).finally(() =>\n running.delete(task.id),\n );\n running.set(task.id, p);\n }\n if (running.size === 0) break;\n // Wake on the first finish; it may have unblocked dependents or requeued.\n await Promise.race(running.values());\n }\n}\n","/**\n * Responsiveness metrics for an orchestrator run.\n *\n * Responsiveness is the experiment's headline: how quickly the user sees the\n * first progress, and whether progress stays steady (no long silences). The math\n * is accumulated from queue transitions but kept here, pure and time-injected, so\n * it is unit-testable away from the runner. Wall-clock times are passed in as\n * milliseconds; the caller owns the clock.\n */\n\nexport interface RunMetricsSummary {\n /** Run start → first task started. */\n time_to_first_task_ms?: number;\n /** Run start → first task completed (the first visible \"done\"). */\n time_to_first_completion_ms?: number;\n /** Longest silence between two consecutive user-visible transitions. */\n max_gap_ms?: number;\n /**\n * Run start → the first question put to the user. The number that says whether\n * a task which waits on a person actually runs late: small means it interrupted\n * the autonomous work, large means it waited for it. `undefined` on a run that\n * asked nothing, which is most of them.\n */\n time_to_first_ask_ms?: number;\n}\n\n/** The per-event timing the `orchestrator task started` event reports. */\nexport interface StartTiming {\n ms_since_run_start: number;\n gap_since_prev_start_ms?: number;\n}\n\nexport class RunMetrics {\n private firstStartMs?: number;\n private lastStartMs?: number;\n private firstCompleteMs?: number;\n private firstAskMs?: number;\n private lastVisibleMs?: number;\n private maxGapMs = 0;\n\n constructor(private readonly runStartMs: number) {}\n\n /** A task started. Returns the per-start-event timing for the start event. */\n recordStart(nowMs: number): StartTiming {\n const timing: StartTiming = {\n ms_since_run_start: nowMs - this.runStartMs,\n gap_since_prev_start_ms:\n this.lastStartMs === undefined ? undefined : nowMs - this.lastStartMs,\n };\n this.firstStartMs ??= nowMs;\n this.lastStartMs = nowMs;\n this.markVisible(nowMs);\n return timing;\n }\n\n /** A task completed. */\n recordComplete(nowMs: number): void {\n this.firstCompleteMs ??= nowMs;\n this.markVisible(nowMs);\n }\n\n /** A task reached a terminal non-complete state the user sees (skip/fail). */\n recordTerminal(nowMs: number): void {\n this.markVisible(nowMs);\n }\n\n /**\n * A question was put to the user. Only the first matters here, and it is not a\n * queue transition — waiting on a person is not the silence `max_gap_ms`\n * measures, so this deliberately does not mark visible progress.\n */\n recordAsk(nowMs: number): void {\n this.firstAskMs ??= nowMs;\n }\n\n /**\n * The run-level responsiveness summary. Timings are `undefined` when the\n * relevant transition never happened (e.g. a run that started no task), so a\n * no-task run stays distinguishable from a genuine zero.\n */\n summary(): RunMetricsSummary {\n return {\n time_to_first_task_ms:\n this.firstStartMs === undefined\n ? undefined\n : this.firstStartMs - this.runStartMs,\n time_to_first_completion_ms:\n this.firstCompleteMs === undefined\n ? undefined\n : this.firstCompleteMs - this.runStartMs,\n max_gap_ms: this.lastVisibleMs === undefined ? undefined : this.maxGapMs,\n time_to_first_ask_ms:\n this.firstAskMs === undefined\n ? undefined\n : this.firstAskMs - this.runStartMs,\n };\n }\n\n /** requeue is not user-visible, so a retry stall counts as silence here. */\n private markVisible(nowMs: number): void {\n if (this.lastVisibleMs !== undefined) {\n this.maxGapMs = Math.max(this.maxGapMs, nowMs - this.lastVisibleMs);\n }\n this.lastVisibleMs = nowMs;\n }\n}\n","/**\n * Where a runner-seeded task sits in the planner's graph.\n *\n * A runner-seeded task is queued from what the wizard detected, before the\n * planner runs (see `ProgramConfig.seedTasks`). At that moment the tasks it\n * should wait for do not exist, so it cannot name them: it is enqueued with no\n * dependencies and is therefore runnable in the first drain tier, alongside the\n * first coding tasks. For a task that stops to ask the user for credentials that\n * is the wrong place — the questions land while the coding agents are still\n * mid-flight.\n *\n * This module answers \"what should it wait for?\" once the planner has seeded the\n * queue. The task's agent prompt names the types it follows (`dependsOn` in\n * frontmatter); a prompt that names none waits for everything that is not the\n * sink, which puts it last but still ahead of the reporting step.\n *\n * Pure and store-reading only — the runner applies what this returns, and the\n * queue enforces the DAG.\n */\nimport type { QueuedTask, QueueStore } from './queue';\nimport { dependencyClosure } from './queue-tools';\n\nexport interface SeededDepsResult {\n /** Ids the seeded task should be made to wait for. */\n depIds: string[];\n /**\n * Declared types with no task of that type in the queue — the planner chose\n * not to queue one. Not an error: the edge is simply dropped, and the task\n * still runs after whatever else was declared.\n */\n unresolvedTypes: string[];\n /** Whether the ids came from the prompt's declared types or from the default. */\n declared: boolean;\n}\n\n/**\n * Resolve a runner-seeded task's dependencies against the planned queue.\n *\n * Two exclusions apply to both the declared and the default path:\n *\n * - **Sinks are never dependencies.** A sink runs last and must depend on the\n * whole queue, this task included. Depending on it back would invert the edge\n * and cost the report this task's `reportSection`. Leaving sinks out means a\n * planner that forgot the sink→seeded edge is still caught by the sink\n * invariant check rather than silently papered over here.\n * - **Anything already downstream of this task is never a dependency**, which is\n * what makes the result cycle-free by construction rather than by the queue's\n * per-edge refusal.\n */\nexport function seededDependencies(\n store: QueueStore,\n seededTaskId: string,\n declaredTypes: readonly string[],\n sinkTypes: readonly string[],\n): SeededDepsResult {\n const eligible = store.list().filter((task) => {\n if (task.id === seededTaskId) return false;\n if (sinkTypes.includes(task.type)) return false;\n // Downstream of us already (the planner hung it off this task): depending on\n // it would close a loop.\n return !dependencyClosure(store, [task.id]).has(seededTaskId);\n });\n\n if (declaredTypes.length === 0) {\n return {\n depIds: eligible.map((t) => t.id),\n unresolvedTypes: [],\n declared: false,\n };\n }\n\n const depIds: string[] = [];\n const unresolvedTypes: string[] = [];\n for (const type of declaredTypes) {\n // Against the whole queue, not just `eligible` — a declared type that was\n // queued but is downstream of us was resolved, just not usable as an edge.\n // Only a type the planner never queued at all is unresolved.\n if (!store.list().some((t) => t.type === type)) {\n unresolvedTypes.push(type);\n continue;\n }\n for (const task of eligible) {\n // Every task of the type, so a fanned-out step (one `capture` per event)\n // is waited for in full rather than by its first task alone.\n if (task.type === type && !depIds.includes(task.id)) depIds.push(task.id);\n }\n }\n\n return { depIds, unresolvedTypes, declared: true };\n}\n\n/** What deferring one seeded task did, for the runner to log and report. */\nexport interface DeferredSeededTask {\n type: string;\n /** Types the prompt declared; empty when it fell back to the default. */\n declaredTypes: string[];\n declared: boolean;\n /** Edges actually added to the queue. */\n added: string[];\n /**\n * Edges the queue refused — a cycle or an unknown id. Always empty in a\n * healthy run: this resolver already excludes both, so anything here means the\n * two disagree and is worth a telemetry look.\n */\n refused: string[];\n unresolvedTypes: string[];\n}\n\n/**\n * Give every runner-seeded task the dependencies it could not name at enqueue,\n * and report what happened per task.\n *\n * The runner calls this once, after the planner has seeded the queue and before\n * the sink invariant is checked. Kept here rather than inline in the runner so\n * the wiring — which prompt's types feed which task — is testable without\n * standing up a whole run.\n */\nexport function deferSeededTasks(\n store: QueueStore,\n seededTasks: readonly QueuedTask[],\n declaredTypesFor: (type: string) => readonly string[],\n sinkTypes: readonly string[],\n): DeferredSeededTask[] {\n return seededTasks.map((seeded) => {\n const declaredTypes = [...declaredTypesFor(seeded.type)];\n const resolved = seededDependencies(\n store,\n seeded.id,\n declaredTypes,\n sinkTypes,\n );\n const { added, refused } = store.addDependencies(\n seeded.id,\n resolved.depIds,\n );\n return {\n type: seeded.type,\n declaredTypes,\n declared: resolved.declared,\n added,\n refused,\n unresolvedTypes: resolved.unresolvedTypes,\n };\n });\n}\n","/**\n * Experimental task-queue orchestrator runner.\n *\n * Branches from the linear runner when the `wizard-orchestrator` flag is on. An\n * orchestrator agent inspects the repo and seeds an in-memory task queue; an\n * executor drains it, running one fresh agent per task.\n *\n * Both the WHAT (agent prompts: model, goal, success criteria, tools) and the\n * HOW (mini-skills) are markdown served from context-mill — the seed and every\n * task resolve to a prompt fetched at startup into the registry. The wizard side\n * stays product-ignorant: it is the queue, the executor, and the loader.\n */\nimport { randomUUID } from 'crypto';\nimport {\n cpSync,\n existsSync,\n mkdirSync,\n readdirSync,\n rmSync,\n writeFileSync,\n} from 'fs';\nimport * as path from 'path';\nimport {\n OutroKind,\n type TaskNotice,\n type WizardSession,\n} from '@lib/wizard-session';\nimport {\n POSTHOG_DOCS_URL,\n WIZARD_CONTACT_EMAIL,\n type Integration,\n} from '@lib/constants';\nimport { FRAMEWORK_REGISTRY } from '@lib/registry';\nimport {\n installSkillById,\n fetchSkillMenu,\n type SkillEntry,\n} from '@lib/wizard-tools';\nimport { getUI } from '@ui';\nimport { analytics } from '@utils/analytics';\nimport { ciExcludedTaskTypes } from '@utils/ci-flag-overrides';\nimport { logToFile } from '@utils/debug';\nimport { ringTerminalBell } from '@utils/terminal-bell';\nimport { wizardAbort, WizardError } from '@utils/wizard-abort';\nimport { ErrorCodes } from '@lib/errors';\nimport type { ProgramConfig } from '@lib/programs/program-step';\nimport type { BootstrapResult, ProgramRun } from '../../shared/types';\nimport {\n areSeededTasksEnabled,\n getHarness,\n resolveHarness,\n resolveStageOverrides,\n type HarnessPick,\n} from '../../switchboard';\nimport { isValidModel, requireKnownModel } from '../../switchboard/models';\nimport type { AgentHarness } from '../../harness/types';\nimport {\n QueueStore,\n QUEUE_DIR_NAME,\n SkipReason,\n TaskStatus,\n type QueuedTask,\n} from './queue';\nimport { drainQueue, type RunTask } from './executor';\nimport { RunMetrics } from './run-metrics';\nimport { dependencyClosure, uncoveredBySink } from './queue-tools';\nimport { deferSeededTasks } from './seeded-deps';\nimport { createWizardAskBridge } from '@lib/wizard-ask-bridge';\nimport { shouldDisableAsk } from '../../shared/bootstrap';\nimport {\n agentRunTools,\n assembleSeedPrompt,\n assembleTaskPrompt,\n loadAgentRegistry,\n promptModelFor,\n resolveTask,\n taskModelSpec,\n ASK_TOOL,\n type AgentPrompt,\n type OrchestratorPromptContext,\n} from '@lib/agent/agent-prompt-loader';\n\n/** Docs page (`django.md`, `nuxt-js-3-6.md`) — steps start with a digit, agent artifacts (`SKILL.md`, `EXAMPLE*`, `COMMANDMENTS.md`) have uppercase. */\nconst isDocPage = (name: string): boolean =>\n name.endsWith('.md') && name === name.toLowerCase() && !/^\\d/.test(name);\n\n/** Copy only the framework docs pages out of the run cache into .claude/skills — the one durable artifact an orchestrator run leaves. Never clobbers an existing install. */\nexport function promoteReferenceSkill(\n referenceDir: string,\n claudeSkillsDir: string,\n referenceSkillId: string,\n): void {\n const target = path.join(claudeSkillsDir, referenceSkillId);\n const refs = path.join(referenceDir, 'references');\n if (!existsSync(refs) || existsSync(target)) return;\n const docs = readdirSync(refs).filter(isDocPage);\n if (docs.length === 0) return;\n mkdirSync(path.join(target, 'references'), { recursive: true });\n for (const f of docs) {\n cpSync(path.join(refs, f), path.join(target, 'references', f));\n }\n writeFileSync(path.join(target, '.posthog-wizard'), '');\n}\n\n/**\n * Remove skills that task agents installed durably mid-run (load_skill):\n * wizard-marked, new this run, and not the framework reference docs.\n * User-authored and pre-existing skills stay.\n */\nexport function sweepRunInstalledSkills(\n claudeSkillsDir: string,\n preexistingSkills: ReadonlySet<string>,\n referenceSkillId: string | undefined,\n): void {\n if (!existsSync(claudeSkillsDir)) return;\n for (const id of readdirSync(claudeSkillsDir)) {\n if (preexistingSkills.has(id) || id === referenceSkillId) continue;\n if (!existsSync(path.join(claudeSkillsDir, id, '.posthog-wizard'))) {\n continue;\n }\n rmSync(path.join(claudeSkillsDir, id), { recursive: true, force: true });\n logToFile(`[orchestrator] removed run-installed skill ${id}`);\n }\n}\n\nfunction toTodoStatus(status: TaskStatus): string {\n switch (status) {\n case TaskStatus.Running:\n return 'in_progress';\n case TaskStatus.Done:\n case TaskStatus.Failed:\n return 'completed';\n case TaskStatus.Skipped:\n return 'skipped';\n default:\n return 'pending';\n }\n}\n\n/**\n * Look up the harness impl for a resolved pick and enforce the `runTask`\n * capability. Pi trips this today with the honest impl-gap error instead of\n * silently downgrading to anthropic.\n */\nfunction requireTaskHarness(pick: HarnessPick): AgentHarness & {\n runTask: NonNullable<AgentHarness['runTask']>;\n} {\n const harness = getHarness(pick.harness);\n if (!harness.runTask) {\n throw new Error(\n `Harness \"${pick.harness}\" does not implement runTask; orchestrator mode requires it.`,\n );\n }\n return harness as AgentHarness & {\n runTask: NonNullable<AgentHarness['runTask']>;\n };\n}\n\n/** Every skill entry the menu knows, across categories. */\nasync function fetchSkillMenuEntries(\n skillsBaseUrl: string,\n): Promise<SkillEntry[]> {\n const menu = await fetchSkillMenu(skillsBaseUrl);\n if (!menu) return [];\n return Object.values(menu.categories).flat();\n}\n\n/** Menu id for a bare skill id + framework via the menu's declared group/framework/default fields; undefined when nothing matches. */\nexport function resolveSkillVariantId(\n entries: readonly SkillEntry[],\n skillId: string,\n framework: string | undefined,\n): string | undefined {\n if (entries.some((e) => e.id === skillId)) return skillId;\n if (!framework) return undefined;\n const family = entries.filter(\n (e) => e.group === skillId && e.framework === framework,\n );\n return (family.find((e) => e.default) ?? family[0])?.id;\n}\n\n/**\n * The framework reference is the full `integration` skill. `session.skillId` is\n * the bare framework (e.g. `django`), but the skill menu ids it as\n * `integration-<variant>`.\n */\nfunction resolveReferenceSkillId(\n entries: readonly SkillEntry[],\n framework: string,\n): string | undefined {\n return resolveSkillVariantId(entries, 'integration', framework);\n}\n\n/**\n * A task that asks the user waits on a person, not on a model: long enough to\n * open a database console or mint a restricted API key. The drain waits it out\n * — the executor holds the task's promise — so the only real limit is this one.\n */\nconst TASK_ASK_TIMEOUT_MS = 20 * 60 * 1000;\n\n/**\n * How long an optional step's notice waits for an answer.\n *\n * Much shorter than the ask timeout above, because it is asking for something\n * much smaller: one keypress to accept or decline, not \"go mint a restricted\n * Stripe key\". It cannot be unbounded either — the notice is a modal, and a run\n * that stops forever behind one nobody is looking at is worse than one that\n * takes the safe answer and carries on.\n *\n * The offer is made at seed time, seconds into the run, so five minutes is a\n * generous allowance for a person who is by then still watching the wizard\n * start. It was not: from 2.63.0 to 2.65.0 the offer was made at the moment the\n * step became runnable — a median seven minutes in, after every coding task —\n * and this timeout became the answer for about a quarter of all runs.\n */\nexport const TASK_NOTICE_TIMEOUT_MS = 5 * 60 * 1000;\n\n/**\n * Offer an optional step, defaulting to declining it if nobody answers.\n *\n * Skip is the right default on a timeout: continuing would send the step on to\n * ask for credentials that the same absent user cannot supply either, burning\n * {@link TASK_ASK_TIMEOUT_MS} per question before falling back to the same\n * links declining gives immediately.\n */\nexport async function offerSeededTask(\n notice: TaskNotice,\n timeoutMs: number = TASK_NOTICE_TIMEOUT_MS,\n): Promise<{ keep: boolean; timedOut: boolean }> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n let timedOut = false;\n const timeout = new Promise<boolean>((resolve) => {\n timer = setTimeout(() => {\n timedOut = true;\n // Dismisses the overlay and settles the showTaskNotice promise too, so\n // the losing side of the race cannot leave a modal on screen.\n getUI().cancelTaskNotice();\n resolve(false);\n }, timeoutMs);\n });\n try {\n const keep = await Promise.race([getUI().showTaskNotice(notice), timeout]);\n return { keep, timedOut };\n } finally {\n if (timer) clearTimeout(timer);\n }\n}\n\n/** One seeded task's answer to its notice, taken once, at seed time. */\nexport interface SeededConsent {\n keep: boolean;\n timedOut: boolean;\n /** The notice could not be shown at all. Read as a decline, never as a yes. */\n errored: boolean;\n}\n\n/** Which skip reason a negative {@link SeededConsent} carries onto the event. */\nexport function consentSkipReason(consent: SeededConsent): SkipReason {\n if (consent.errored) return SkipReason.NoticeError;\n return consent.timedOut ? SkipReason.NoticeTimeout : SkipReason.UserDeclined;\n}\n\n/**\n * Ask for one seeded task's consent, and record how the answer came about.\n *\n * Consent and execution are separate concerns, and this is the consent half.\n * It runs at seed time — seconds into the run, with the user still watching —\n * while `seeded-deps.ts` keeps the work itself at the end of the queue. Asking\n * at the moment of execution instead, as 2.63.0 did, put the question in front\n * of a user who had long since tabbed away.\n *\n * Fails closed. The step this gates goes on to ask for live database and API\n * credentials, so a question that could not be put to the user is never read as\n * a yes.\n */\nexport async function askSeededConsent(\n type: string,\n notice: TaskNotice,\n timeoutMs?: number,\n): Promise<SeededConsent> {\n const consent = await offerSeededTask(notice, timeoutMs).then(\n (answer): SeededConsent => ({ ...answer, errored: false }),\n (err: unknown): SeededConsent => {\n logToFile(\n `[orchestrator] notice failed for ${type}, declining: ${String(err)}`,\n );\n analytics.captureException(\n err instanceof Error ? err : new Error(String(err)),\n { step: 'orchestrator_task_notice' },\n );\n return { keep: false, timedOut: false, errored: true };\n },\n );\n analytics.wizardCapture('orchestrator task notice answered', {\n type,\n kept: consent.keep,\n timed_out: consent.timedOut,\n errored: consent.errored,\n });\n return consent;\n}\n\n/** Whether a task's prompt lets it ask the user, and so needs the ask bridge. */\nfunction canAsk(prompt: AgentPrompt | undefined): boolean {\n return (prompt?.allowedTools ?? []).includes(ASK_TOOL);\n}\n\n/** Splits terminal failures into run-failing (required) and reported-only (optional). */\nexport function drainVerdict(tasks: readonly QueuedTask[]): {\n requiredFailedTypes: string[];\n optionalFailedTypes: string[];\n blocked: number;\n} {\n const failed = tasks.filter((t) => t.status === TaskStatus.Failed);\n return {\n requiredFailedTypes: failed\n .filter((t) => t.optional !== true)\n .map((t) => t.type),\n optionalFailedTypes: failed\n .filter((t) => t.optional === true)\n .map((t) => t.type),\n blocked: tasks.filter((t) => t.status === TaskStatus.Pending).length,\n };\n}\n\n/** How many tasks deep in the graph a task sits — 0 when it depends on nothing. */\nfunction graphDepth(\n task: QueuedTask,\n byId: ReadonlyMap<string, QueuedTask>,\n memo: Map<string, number>,\n): number {\n const cached = memo.get(task.id);\n if (cached !== undefined) return cached;\n memo.set(task.id, 0); // breaks a cycle rather than recursing forever\n const depth = task.dependsOn.reduce((deepest, id) => {\n const dep = byId.get(id);\n return dep ? Math.max(deepest, graphDepth(dep, byId, memo) + 1) : deepest;\n }, 0);\n memo.set(task.id, depth);\n return depth;\n}\n\n/**\n * The queue in the order the user should read it, which is not the order tasks\n * were queued. Tasks the wizard seeded before the planner ran are queued first\n * but are optional side quests, so they sit at the end of the tier they run in\n * — the list reads as the run unfolds, and the first line is work that actually\n * started. Ordering only; nothing here changes what runs when.\n */\nexport function displayOrder(\n tasks: readonly QueuedTask[],\n isOptional: (task: QueuedTask) => boolean,\n): QueuedTask[] {\n const byId = new Map(tasks.map((t) => [t.id, t]));\n const memo = new Map<string, number>();\n const rank = tasks.map((task, index) => ({\n task,\n depth: graphDepth(task, byId, memo),\n optional: isOptional(task) ? 1 : 0,\n index,\n }));\n return rank\n .sort(\n (a, b) =>\n a.depth - b.depth || a.optional - b.optional || a.index - b.index,\n )\n .map((entry) => entry.task);\n}\n\nexport async function runOrchestrator(\n session: WizardSession,\n config: ProgramRun,\n programConfig: ProgramConfig,\n boot: BootstrapResult,\n): Promise<void> {\n const runId = randomUUID();\n\n // Switchboard context — reused for every per-role harness resolution below.\n const switchboardCtx = {\n program: programConfig.id,\n flags: boot.wizardFlags,\n flagPayloads: boot.wizardFlagPayloads,\n cliHarness: session.harness,\n cliSequence: session.sequence,\n cliModel: session.model,\n };\n\n // The WHAT (agent prompts) is served from context-mill. Fetch the registry\n // once up front: its types drive enqueue validation, and resolving a task to\n // its run config is then synchronous, with no mid-drain network latency.\n const flow = programConfig.agentFlow ?? programConfig.id;\n const registry = await loadAgentRegistry(boot.skillsBaseUrl, flow, {\n exclude: ciExcludedTaskTypes(),\n // Baked into the prompts at load, so enqueue, dispatch, and telemetry all read one effective spec.\n overrides: resolveStageOverrides(\n programConfig.id,\n boot.wizardFlags,\n boot.wizardFlagPayloads,\n ),\n });\n const seedPrompt = registry.seed;\n if (!seedPrompt) {\n throw new Error(\n `No seed agent prompt (frontmatter \\`seed: true\\`) for flow \"${flow}\" is available from ${boot.skillsBaseUrl}.`,\n );\n }\n\n // The end decision the switchboard event defers to: the model each task will actually run on.\n const taskModels = Object.fromEntries(\n ['seed', ...registry.types].map((type) => {\n const prompt = type === 'seed' ? seedPrompt : registry.get(type);\n const pick = resolveHarness(switchboardCtx, type);\n const specModel = prompt && promptModelFor(prompt, pick.harness).model;\n return [type, isValidModel(specModel) ? specModel : pick.model];\n }),\n );\n logToFile(\n `[orchestrator] task models: ${Object.entries(taskModels)\n .map(([t, m]) => `${t}=${m}`)\n .join(' ')}`,\n );\n analytics.wizardCapture('orchestrator task models', taskModels);\n\n // Responsiveness is the headline metric of the dark launch: time to first\n // visible progress, and no single step dominating wall-clock. Track it from\n // queue transitions, with the resolved model so cheap work is attributable\n // to cheap models.\n const runStartMs = Date.now();\n const metrics = new RunMetrics(runStartMs);\n const durationMs = (t: QueuedTask) =>\n t.startedAt && t.finishedAt\n ? Date.parse(t.finishedAt) - Date.parse(t.startedAt)\n : undefined;\n\n const store = new QueueStore(session.installDir, runId, {\n onTransition: (event, task) => {\n const pick = resolveHarness(switchboardCtx, task.type);\n // Mirror dispatch's allow-list fallback so attribution names the model that runs.\n const specModel = taskModelSpec(registry, task, pick.harness).model;\n const base = {\n type: task.type,\n model: isValidModel(specModel) ? specModel : pick.model,\n attempts: task.attempts,\n // A failed optional task aborts nothing (see drainVerdict).\n optional: task.optional === true,\n };\n switch (event) {\n case 'enqueue':\n analytics.wizardCapture('orchestrator task enqueued', {\n type: task.type,\n enqueued_by: task.enqueuedBy,\n dynamic: task.enqueuedBy !== 'orchestrator',\n });\n break;\n case 'start':\n analytics.wizardCapture('orchestrator task started', {\n ...base,\n ...metrics.recordStart(Date.now()),\n });\n break;\n case 'complete':\n metrics.recordComplete(Date.now());\n analytics.wizardCapture('orchestrator task completed', {\n ...base,\n duration_ms: durationMs(task),\n });\n break;\n case 'skip':\n metrics.recordTerminal(Date.now());\n analytics.wizardCapture('orchestrator task skipped', {\n ...base,\n duration_ms: durationMs(task),\n // Additive: the event's name and every other property are unchanged,\n // so existing dashboards keep reading. Without this a step the user\n // declined, a step nobody answered for, and a step the agent found\n // did not apply were one number — which is how a regression that\n // halved the warehouse completion rate stayed invisible for a week.\n reason: task.skipReason,\n });\n break;\n case 'fail':\n metrics.recordTerminal(Date.now());\n analytics.wizardCapture('orchestrator task failed', {\n ...base,\n duration_ms: durationMs(task),\n error: task.error?.type,\n });\n break;\n case 'requeue':\n break;\n }\n },\n });\n\n // Give task agents the framework's finished reference integration to match,\n // the same EXAMPLE.md the linear flow uses. Install it under the run dir rather\n // than .claude/skills so its \"do everything\" workflow is not auto-loaded as a\n // skill — only the example file is read, when the agent's prompt points at it.\n let examplePath: string | undefined;\n let commandmentsPath: string | undefined;\n let referenceInstallPath: string | undefined;\n const menuSkillEntries = await fetchSkillMenuEntries(boot.skillsBaseUrl);\n // The framework key for reference + variant resolution. `session.integration`\n // is the detected framework and always wins; `session.skillId` is the\n // fallback for the basic-integration path, where bootstrap sets it to the\n // framework label. Programs whose run config carries their own skill id\n // (agent-skill commands like replay-vision) would otherwise leak that id in\n // here as a bogus framework after bootstrap overwrites the detect result.\n const framework = session.integration ?? session.skillId ?? undefined;\n const referenceSkillId = framework\n ? resolveReferenceSkillId(menuSkillEntries, framework)\n : undefined;\n if (referenceSkillId) {\n const ref = await installSkillById(\n referenceSkillId,\n session.installDir,\n boot.skillsBaseUrl,\n {\n skillsRoot: path.join(QUEUE_DIR_NAME, 'reference'),\n triage: boot.triageProvider,\n },\n );\n if (ref.kind === 'ok') {\n referenceInstallPath = ref.path;\n const example = path.join(ref.path, 'references', 'EXAMPLE.md');\n if (existsSync(path.join(session.installDir, example))) {\n examplePath = example;\n }\n const commandments = path.join(ref.path, 'references', 'COMMANDMENTS.md');\n if (existsSync(path.join(session.installDir, commandments))) {\n commandmentsPath = commandments;\n }\n } else {\n logToFile(\n `[orchestrator] reference unavailable: ${ref.kind} (${referenceSkillId})`,\n );\n }\n } else if (framework) {\n logToFile(\n `[orchestrator] no integration skill for framework \"${framework}\"`,\n );\n }\n\n // Preflight every task's mini-skills: a miss would run tasks skill-less, so fail properly instead.\n const missingVariants: string[] = [];\n for (const type of registry.types) {\n for (const skillId of registry.get(type)?.skills ?? []) {\n if (resolveSkillVariantId(menuSkillEntries, skillId, framework)) {\n continue;\n }\n missingVariants.push(`${type}/${skillId}`);\n logToFile(\n `[orchestrator] no skill variant type=${type} skill=${skillId} framework=${\n framework ?? 'none'\n }`,\n );\n analytics.wizardCapture('orchestrator skill variant missing', {\n task_type: type,\n skill: skillId,\n framework,\n });\n }\n }\n if (missingVariants.length > 0) {\n // The framework's own docs page from its config; generic docs when detection found none.\n const docsUrl = framework\n ? FRAMEWORK_REGISTRY[framework as Integration]?.metadata.docsUrl\n : undefined;\n await wizardAbort({\n code: ErrorCodes.AgentOrchestratorSkillVariantMissing,\n message:\n 'Setup instructions for this project failed to download.\\n' +\n 'Please try again, or contact wizard@posthog.com.\\n\\n' +\n 'You can also set up with your agent by downloading the skills here:\\n' +\n ' https://github.com/PostHog/context-mill/releases\\n' +\n 'or integrate manually here:\\n' +\n ` ${docsUrl ?? POSTHOG_DOCS_URL}`,\n error: new WizardError(\n 'Orchestrator preflight: skill variant missing',\n {\n missing: missingVariants.join(', '),\n framework,\n },\n ErrorCodes.AgentOrchestratorSkillVariantMissing,\n ),\n });\n }\n\n // The client injects the basics (project context + the I/O contract) around\n // every authored agent-prompt body.\n const promptContext: OrchestratorPromptContext = {\n projectId: boot.credentials.projectId,\n projectApiKey: boot.credentials.projectApiKey,\n host: boot.credentials.host,\n examplePath,\n commandmentsPath,\n };\n\n logToFile(\n `[orchestrator] START program=${programConfig.id} dir=${session.installDir} run=${runId}`,\n );\n analytics.wizardCapture('orchestrator started', {\n program_id: programConfig.id,\n });\n getUI().startRun();\n\n // Label precedence: what the orchestrator set at enqueue, then the agent\n // prompt's default, then the bare type.\n const labelFor = (t: { type: string; label?: string }) =>\n t.label ?? registry.get(t.type)?.label ?? t.type;\n const renderQueue = () =>\n getUI().syncTodos(\n displayOrder(store.list(), (t) =>\n registry.runnerSeededTypes.includes(t.type),\n ).map((t) => ({\n content: labelFor(t),\n status: toTodoStatus(t.status),\n activeForm: labelFor(t),\n })),\n );\n\n // Each task's run binds the wizard-tools MCP server to a per-task\n // orchestrator context so complete_task / enqueue_task attribute correctly\n // when independent tasks run in parallel. The seed is not a task, so its\n // context has no task id.\n const orchestratorCtx = (currentTaskId?: string) => ({\n store,\n // The planner is offered only the types an agent may queue. A runner-seeded\n // type is not among them, so an attempt to queue one trips the unknown-type\n // guard instead of duplicating work the wizard already placed.\n validTypes: registry.enqueueableTypes,\n sinkTypes: registry.sinkTypes,\n // The edge to a runner-seeded task is one-way: the sink may wait for it,\n // nothing else may. Enforced at enqueue, because prose alone cannot hold it\n // — a single planner edge is enough to pull the task back to the front of\n // the drain and put its prompt in front of the code work again.\n runnerSeededTypes: registry.runnerSeededTypes,\n currentTaskId,\n });\n\n // Tasks the wizard queues itself, from what detection found. They exist\n // before the planner runs, so the sink guard forces the reporting task to\n // depend on them, and no prompt has to remember they are there.\n // Kill switch: off (or unset), the wizard queues nothing itself and the run\n // is byte-identical to a project with no detected sources.\n const seedEntries = areSeededTasksEnabled(boot.wizardFlags)\n ? programConfig.seedTasks?.(session) ?? []\n : [];\n const seededTypes: string[] = [];\n // Kept so their dependencies can be resolved once the planner has run — they\n // are queued before it, so they cannot name what they wait for yet.\n const seededTasks: QueuedTask[] = [];\n // Each seeded task's answer to its notice, taken here and applied later.\n //\n // Consent belongs at seed time: the user is at the keyboard, watching the run\n // start, and one keypress is all the question needs. The work does not — the\n // warehouse step asks for credentials, and those questions belong after the\n // autonomous coding, which is what `seeded-deps.ts` arranges. 2.63.0 collapsed\n // the two onto one modal at the moment of execution, a median seven minutes\n // in, by which time the user had gone; the five-minute timeout then answered\n // for them, and it answers \"skip\".\n //\n // The answer is recorded rather than acted on, so a declined task still enters\n // the queue as an ordinary pending task. The planner plans around it,\n // `deferSeededTasks` can still add its edges, and the sink invariant still\n // covers it — none of which is true of a task that was enqueued and skipped\n // before the planner ever ran. `runTask` applies the answer when the drain\n // reaches the task.\n const seededConsent = new Map<string, SeededConsent>();\n for (const seeded of seedEntries) {\n if (!registry.runnerSeededTypes.includes(seeded.type)) {\n logToFile(\n `[orchestrator] skipping runner-seeded task \"${seeded.type}\": not a runner-seeded type in this flow`,\n );\n continue;\n }\n const task = store.enqueue({\n type: seeded.type,\n label: seeded.label,\n inputs: seeded.inputs,\n enqueuedBy: 'orchestrator',\n // Terminal failure is reported per-task and never aborts the run.\n optional: true,\n });\n seededTypes.push(seeded.type);\n seededTasks.push(task);\n if (seeded.notice) {\n // Awaited inside the loop, so at most one notice is ever on screen. The\n // store holds a single pending-notice slot: a second `showTaskNotice`\n // overwrites the first's resolver, the first promise never settles, and\n // its task hangs for the rest of the run. A serial loop makes that\n // unreachable; the drain, which starts every runnable task at once, does\n // not, which is why the offer lives here and not there.\n seededConsent.set(\n task.id,\n await askSeededConsent(seeded.type, seeded.notice),\n );\n }\n logToFile(`[orchestrator] runner-seeded task ${seeded.type}`);\n }\n\n // A run that stops to ask a person is not comparable with one that does not\n // — its wall-clock is the user's, not the model's. Tag every event of the run\n // from here on, so those runs filter out cleanly.\n //\n // A declined step asks nothing, and the answer is known by now, so it leaves\n // the tag alone. While the offer was made mid-drain this was unknowable here,\n // and roughly a quarter of runs were tagged as waiting on a user who had in\n // fact already been auto-declined out of the only step that asks.\n const askingTypes = seededTasks\n .filter((task) => seededConsent.get(task.id)?.keep !== false)\n .map((task) => task.type)\n .filter((type) => canAsk(registry.get(type)));\n analytics.setTag('orchestrator_awaits_user', askingTypes.length > 0);\n analytics.setTag(\n 'orchestrator_runner_seeded_types',\n seededTypes.join(',') || 'none',\n );\n if (askingTypes.length > 0) {\n analytics.wizardCapture('orchestrator awaits user', {\n task_types: askingTypes,\n ask_timeout_ms: TASK_ASK_TIMEOUT_MS,\n });\n }\n\n // One bridge for the run, handed only to a task whose prompt allows asking.\n // Absent in CI and signup, where nobody can answer.\n const askBridge = shouldDisableAsk(session)\n ? undefined\n : createWizardAskBridge({\n getSource: () => session.skillId ?? programConfig.id,\n showQuestion: (q) => {\n // How late the first ask lands is the measure of this run shape: it\n // should follow the autonomous work, not interrupt it.\n metrics.recordAsk(Date.now());\n // Consent is taken in the first seconds of the run and these questions\n // arrive at the end of it, so the user who agreed may well be looking\n // at another window by now. Nothing here waits on the bell — an\n // unanswered ask still times out into the deep-link fallback — it just\n // gives a person who stepped away a chance to come back first.\n ringTerminalBell();\n return getUI().requestQuestion(q);\n },\n cancelQuestion: () => getUI().cancelPendingQuestion(),\n richLinks: config.richLinks ?? false,\n timeoutMs: TASK_ASK_TIMEOUT_MS,\n });\n\n const spinner = getUI().spinner();\n\n // 1. Seed the queue with the orchestrator agent. It is itself an agent prompt\n // (the WHAT), so its model and tools come from its frontmatter. The seed\n // plans the graph, it is not a task.\n //\n // Prompt-frontmatter model wins over the switchboard pick (§3.6 of the\n // switchboard plan) — the switchboard's model is the fallback when the\n // prompt is silent.\n const seedPick = resolveHarness(switchboardCtx, 'seed');\n const seedHarness = requireTaskHarness(seedPick);\n const seedModel = promptModelFor(seedPrompt, seedPick.harness);\n const seedResult = await seedHarness.runTask({\n session,\n programConfig,\n boot,\n prompt: assembleSeedPrompt(promptContext, seedPrompt.body, store.list()),\n spinner,\n model: requireKnownModel(seedModel.model, seedPick.model),\n effort: seedModel.effort,\n ...agentRunTools(seedPrompt),\n orchestrator: orchestratorCtx(),\n spinnerMessage: 'Planning the integration...',\n successMessage: 'Planned the integration',\n additionalFeatureQueue: [],\n requestRemark: false,\n analyticsProperties: { task_type: 'seed', harness: seedPick.harness },\n });\n if (seedResult.error) {\n logToFile(\n `[orchestrator] seed error: ${seedResult.error} ${\n seedResult.message ?? ''\n }`,\n );\n }\n analytics.wizardCapture('orchestrator seeded', {\n task_count: store.list().length,\n types: store.list().map((t) => t.type),\n });\n renderQueue();\n\n // Now that the graph exists, give each runner-seeded task the dependencies it\n // could not name when it was queued. Without this it sits at depth 0 and runs\n // in the first tier — which for the warehouse step means its credential\n // prompts arrive while the coding tasks are still writing files. Deferred, the\n // one step that waits on a person waits until the autonomous work is done.\n //\n // Before the sink check below on purpose: sinks are never added as\n // dependencies, so a planner that forgot to make its sink wait for a seeded\n // task is still caught there rather than masked here.\n const deferred = deferSeededTasks(\n store,\n seededTasks,\n (type) => registry.get(type)?.dependsOn ?? [],\n registry.sinkTypes,\n );\n for (const entry of deferred) {\n logToFile(\n `[orchestrator] deferred runner-seeded ${entry.type}: ` +\n `${entry.added.length} deps (${\n entry.declared\n ? `declared: ${entry.declaredTypes.join(', ')}`\n : 'default'\n })${\n entry.refused.length > 0 ? `, ${entry.refused.length} refused` : ''\n }${\n entry.unresolvedTypes.length > 0\n ? `, unresolved: ${entry.unresolvedTypes.join(', ')}`\n : ''\n }`,\n );\n analytics.wizardCapture('orchestrator seeded task deferred', {\n type: entry.type,\n dep_count: entry.added.length,\n declared: entry.declared,\n declared_types: entry.declaredTypes,\n unresolved_types: entry.unresolvedTypes,\n // Non-empty means a cycle or an unknown id was rejected — the resolver and\n // the queue disagreeing, never expected in a good run.\n refused_count: entry.refused.length,\n });\n }\n if (deferred.length > 0) renderQueue();\n\n // Canary for the one-way rule. The enqueue guard rejects the edge outright, so\n // this should never fire — but if it ever does, the seeded task has been\n // pulled back toward the front of the drain and its prompt lands mid-run\n // again, which is precisely the failure this whole step exists to prevent.\n // Silent regressions here would look like \"the ordering just stopped\n // working\", so make it visible rather than abort a run that is otherwise fine.\n for (const seeded of seededTasks) {\n const dependants = store\n .list()\n .filter(\n (t) =>\n !registry.sinkTypes.includes(t.type) &&\n t.id !== seeded.id &&\n dependencyClosure(store, [t.id]).has(seeded.id),\n );\n if (dependants.length === 0) continue;\n logToFile(\n `[orchestrator] one-way rule broken: ${dependants\n .map((t) => t.type)\n .join(', ')} depend on runner-seeded ${seeded.type}`,\n );\n analytics.wizardCapture('orchestrator seeded task depended on', {\n type: seeded.type,\n dependant_types: dependants.map((t) => t.type),\n });\n }\n\n // The enqueue guard rejects a sink that misses part of the queue, so a\n // planner that respected its errors cannot get here with a broken graph.\n // Check it again anyway: a run whose report never sees a task's handoff is\n // worse than a run that stops and says so.\n const unwaited = store\n .list()\n .filter((t) => registry.sinkTypes.includes(t.type))\n .flatMap((sink) =>\n uncoveredBySink(\n { store, validTypes: registry.types, sinkTypes: registry.sinkTypes },\n { type: sink.type, dependsOn: sink.dependsOn },\n ).filter((t) => t.id !== sink.id),\n );\n if (unwaited.length > 0) {\n analytics.wizardCapture('orchestrator sink invariant violated', {\n uncovered_types: unwaited.map((t) => t.type),\n });\n await wizardAbort({\n code: ErrorCodes.AgentOrchestratorSinkInvariant,\n message: `The wizard could not plan this setup: the final step would have skipped ${unwaited\n .map((t) => t.type)\n .join(', ')}.\\n\\nPlease report this to: ${WIZARD_CONTACT_EMAIL}`,\n error: new WizardError(\n 'orchestrator sink does not cover the queue',\n {\n uncovered: unwaited.map((t) => `${t.type} (${t.id})`).join(', '),\n queue_state: JSON.stringify(store.list()),\n },\n ErrorCodes.AgentOrchestratorSinkInvariant,\n ),\n });\n }\n\n // 2. Drain the queue, one fresh agent per task; independent tasks run in\n // parallel, the seed's graph being the only schedule. Each task resolves to\n // its agent prompt (the WHAT) and the mini-skills it needs (the HOW), then\n // runs on its own model and tools.\n const taskSkillsRoot = path.join(QUEUE_DIR_NAME, 'skills');\n // Task agents can install durable skills mid-run (load_skill), and only the\n // framework reference docs earn a place — snapshot what was already there so\n // the sweeps remove exactly what this run added.\n const claudeSkillsDir = path.join(session.installDir, '.claude', 'skills');\n const preexistingSkills = new Set(\n existsSync(claudeSkillsDir) ? readdirSync(claudeSkillsDir) : [],\n );\n const runTask: RunTask = async (task) => {\n renderQueue();\n\n // A task that stops for the user is offered, not imposed. The offer was\n // made at seed time; this applies the answer, now that the drain has\n // reached the task.\n //\n // A declined task is skipped here rather than dropped at seed time, for two\n // reasons. The graph the planner saw is then the graph that ran — the sink\n // already depends on this task, and `nextRunnable` treats a skipped\n // dependency as satisfied, so the report still runs and can say the step was\n // declined. And the decline stays in the funnel: it arrives as a `skipped`\n // event carrying the reason that caused it, rather than as a task that\n // silently never existed. `orchestrator task skipped` is only readable that\n // way because it now carries `reason`; without it, declines and timeouts and\n // agent no-ops were one indistinguishable number.\n const consent = seededConsent.get(task.id);\n if (consent && !consent.keep) {\n const reason = consentSkipReason(consent);\n logToFile(`[orchestrator] runner-seeded ${task.type} skipped: ${reason}`);\n const declinedByUser = reason === SkipReason.UserDeclined;\n store.skip(task.id, reason, {\n goals: labelFor(task),\n did: declinedByUser\n ? 'Nothing — the user chose to skip this step when offered it.'\n : 'Nothing — the step was offered at the start of the run and never accepted.',\n forNextAgent: declinedByUser\n ? 'This step was offered and declined, so it did no work. Report it as skipped at the user’s request, not as failed.'\n : 'This step was offered and never accepted, so it did no work. Report it as not set up, and point the user at how to do it later.',\n });\n renderQueue();\n return;\n }\n\n try {\n const resolved = resolveTask(registry, task, store);\n // Task instructions are one-run scaffolding, not durable skills, so they\n // install under the run dir rather than .claude/skills — the SDK must not\n // auto-load them and they must never land in the project (or a CI PR).\n // The prompt points the agent at them instead.\n const skillPaths: string[] = [];\n for (const skillId of resolved.skills) {\n // Agent prompts name the bare step-skill (`integration-v2-install`);\n // SDK-divergent steps ship per-framework variants, so resolve against\n // the menu with the session's framework before installing.\n const variantId = resolveSkillVariantId(\n menuSkillEntries,\n skillId,\n framework,\n );\n if (!variantId) {\n logToFile(\n `[orchestrator] no skill variant type=${\n task.type\n } skill=${skillId} framework=${framework ?? 'none'}`,\n );\n continue;\n }\n const result = await installSkillById(\n variantId,\n session.installDir,\n boot.skillsBaseUrl,\n { skillsRoot: taskSkillsRoot, triage: boot.triageProvider },\n );\n if (result.kind === 'ok') {\n skillPaths.push(path.join(result.path, 'SKILL.md'));\n } else {\n logToFile(\n `[orchestrator] skill install failed type=${task.type} skill=${variantId} ${result.kind}`,\n );\n // A task without its instructions must fail here, not run blind:\n // run 91cf40eb's report task started after two EACCES install\n // failures (unwritable external-volume cache) and died silently.\n // The executor catches this, captures the exception, and fails the\n // task through the normal outcome check.\n throw new Error(\n `Skill \"${variantId}\" for task \"${task.type}\" could not be installed (${result.kind}). ` +\n 'If this is a permissions error, check that the project directory is writable.',\n );\n }\n }\n // Empty spinner messages suppress the per-task spinner line (the queue\n // panel shows progress); errors still surface — the harness stops the\n // spinner with its own error text.\n //\n // Per-task role = task.type — the switchboard consults\n // PROGRAM_BINDINGS[id].contextMillOverride?.[task.type] for wizard-side\n // per-agent overrides. Prompt-frontmatter model still wins (§3.6).\n const taskPick = resolveHarness(switchboardCtx, task.type);\n const taskHarness = requireTaskHarness(taskPick);\n const taskModel = taskModelSpec(registry, task, taskPick.harness);\n await taskHarness.runTask({\n session,\n programConfig,\n boot,\n prompt: assembleTaskPrompt(promptContext, resolved.prompt, skillPaths),\n spinner,\n model: requireKnownModel(taskModel.model, taskPick.model),\n effort: taskModel.effort,\n allowedTools: resolved.allowedTools,\n disallowedTools: resolved.disallowedTools,\n askBridge: canAsk(registry.get(task.type)) ? askBridge : undefined,\n orchestrator: orchestratorCtx(task.id),\n spinnerMessage: '',\n successMessage: '',\n additionalFeatureQueue: [],\n requestRemark: false,\n analyticsProperties: {\n task_type: task.type,\n task_id: task.id,\n harness: taskPick.harness,\n },\n });\n } finally {\n // Durable skills a task installed are irrelevant to later tasks — and\n // the sdk harness auto-loads .claude/skills into every agent — so sweep\n // as each task ends, not only at run end.\n try {\n sweepRunInstalledSkills(\n claudeSkillsDir,\n preexistingSkills,\n referenceSkillId,\n );\n } catch (err) {\n logToFile(`[orchestrator] per-task skill sweep failed: ${String(err)}`);\n }\n renderQueue();\n }\n };\n try {\n await drainQueue(store, runTask);\n } finally {\n try {\n if (referenceSkillId && referenceInstallPath) {\n promoteReferenceSkill(\n path.join(session.installDir, referenceInstallPath),\n claudeSkillsDir,\n referenceSkillId,\n );\n }\n } catch (err) {\n analytics.captureException(\n err instanceof Error ? err : new Error(String(err)),\n { step: 'orchestrator_reference_promote' },\n );\n }\n // Success or failure, no run artifact outlives the run — wipe the whole\n // cache folder (queue, handoffs, reference example, installed task\n // instructions). The .DELETE-ME.md inside is the fallback if we don't.\n try {\n rmSync(path.join(session.installDir, QUEUE_DIR_NAME), {\n recursive: true,\n force: true,\n });\n } catch (err) {\n analytics.captureException(\n err instanceof Error ? err : new Error(String(err)),\n { step: 'orchestrator_cache_cleanup' },\n );\n }\n try {\n sweepRunInstalledSkills(\n claudeSkillsDir,\n preexistingSkills,\n referenceSkillId,\n );\n } catch (err) {\n analytics.captureException(\n err instanceof Error ? err : new Error(String(err)),\n { step: 'orchestrator_skill_sweep' },\n );\n }\n }\n\n renderQueue();\n\n const summary = store.summary();\n logToFile(\n `[orchestrator] DONE done=${summary.done} failed=${summary.failed} total=${summary.total}`,\n );\n\n analytics.wizardCapture('orchestrator run finished', {\n tasks_total: summary.total,\n tasks_done: summary.done,\n tasks_failed: summary.failed,\n tasks_skipped: summary[TaskStatus.Skipped],\n total_duration_ms: Date.now() - runStartMs,\n ...metrics.summary(),\n dynamic_enqueue_count: store\n .list()\n .filter((t) => t.enqueuedBy !== 'orchestrator').length,\n retried_task_count: store.list().filter((t) => t.attempts > 1).length,\n });\n\n // The review step flags any unresolved conflict in its handoff; surface the\n // one-liner here and point the user at the report for the detail.\n const reviewTask = store.list().find((t) => t.type === 'review');\n const conflict = reviewTask\n ? store.readHandoff(reviewTask.id)?.conflict\n : undefined;\n\n // Not-needed tasks were never work, so they leave the denominator too.\n const notRequired = summary[TaskStatus.Skipped];\n\n // A drain that ends with failed tasks (retries exhausted) or tasks still\n // pending (blocked behind a failed dependency) did NOT set PostHog up —\n // abort like a linear agent failure instead of claiming success.\n // A failed optional task is exempt: reported per-task, never run-failing.\n const verdict = drainVerdict(store.list());\n const blocked = verdict.blocked;\n if (verdict.requiredFailedTypes.length > 0 || blocked > 0) {\n const failedTypes = verdict.requiredFailedTypes.join(', ');\n const whatFailed = failedTypes\n ? `the ${failedTypes} step failed`\n : `${blocked} steps never ran`;\n // A grant narrowed at login is the one failure cause the user can fix\n // alone — lead with the fix, and only fall back to the report-a-bug line\n // when trying again doesn't work.\n const missingScopes = boot.credentials.missingScopes ?? [];\n const message =\n missingScopes.length > 0\n ? `The wizard could not finish setup: ${whatFailed}, and this run was authorized without the following permission${\n missingScopes.length === 1 ? '' : 's'\n }: ${missingScopes.join(\n ', ',\n )}.\\n\\nPlease try again, approving all permissions on the PostHog authorization screen. If it still fails, report it to: ${WIZARD_CONTACT_EMAIL}`\n : `The wizard was unable to set up PostHog: ${whatFailed}.\\n\\nPlease report this to: ${WIZARD_CONTACT_EMAIL}`;\n await wizardAbort({\n code: ErrorCodes.AgentOrchestratorTasksFailed,\n message,\n error: new WizardError(\n 'orchestrator drain ended with failed tasks',\n {\n tasks_failed: summary.failed,\n tasks_blocked: blocked,\n failed_types: failedTypes,\n missing_oauth_scopes: missingScopes.join(' '),\n queue_state: JSON.stringify(store.list()),\n },\n ErrorCodes.AgentOrchestratorTasksFailed,\n ),\n });\n }\n\n // A drain that produced no tasks at all means the seed step never got a\n // usable model response (e.g. the gateway returned empty completions).\n // \"0/0 completed\" is a dead run, not a success with an empty denominator.\n if (summary.total === 0) {\n await wizardAbort({\n code: ErrorCodes.AgentOrchestratorHollowRun,\n message: `The wizard was unable to set up PostHog: the planning step produced no work, so nothing ran.\\n\\nPlease try again — and if it happens again, report it to: ${WIZARD_CONTACT_EMAIL}`,\n error: new WizardError(\n 'orchestrator drain produced zero tasks',\n { queue_state: JSON.stringify(store.list()) },\n ErrorCodes.AgentOrchestratorHollowRun,\n ),\n });\n }\n\n // A failed optional step leaves the denominator and is named instead.\n const optionalFailedCount = verdict.optionalFailedTypes.length;\n const stepNotes = [\n notRequired > 0 ? `${notRequired} skipped as not required` : '',\n optionalFailedCount > 0\n ? `${optionalFailedCount} optional step failed`\n : '',\n ].filter(Boolean);\n const message = conflict\n ? 'PostHog set up, with one conflict to review.'\n : `PostHog set up: ${summary.done}/${\n summary.total - notRequired - optionalFailedCount\n } steps completed${\n stepNotes.length > 0 ? ` (${stepNotes.join(', ')})` : ''\n }.`;\n getUI().setOutroData({\n kind: OutroKind.Success,\n message,\n body: conflict\n ? `⚠ Build conflict: ${conflict}\\nFull details are in the setup report.`\n : undefined,\n docsUrl: 'https://posthog.com/docs/ai-engineering/ai-wizard',\n });\n getUI().outro(message);\n await analytics.shutdown('success');\n}\n","/**\n * Sequence axis: gate helpers, registry, middleware, resolver.\n * Percentage rollouts are PostHog-side — the gate just reads the resolved bool.\n */\n\nimport { IS_PRODUCTION_BUILD } from '@env';\nimport { Sequence } from '@lib/constants';\nimport { logToFile } from '@utils/debug';\nimport {\n isOrchestratorEnabled,\n resolveFlagRoute,\n resolveFlagSequence,\n} from './flags';\nimport { getHarness, resolveHarness } from './harness';\nimport type { WizardSession } from '@lib/wizard-session';\nimport type { ProgramConfig } from '@lib/programs/program-step';\nimport type { ProgramRun, BootstrapResult } from '../shared/types';\nimport { runLinearProgram } from '../sequence/linear';\nimport { runOrchestrator } from '../sequence/orchestrator/orchestrator-runner';\nimport {\n DEFAULT_BINDING,\n PROGRAM_BINDINGS,\n runChain,\n type Middleware,\n type SwitchboardCtx,\n} from '.';\n\n// ── Registry ────────────────────────────────────────────────────────────\n\nexport interface SequenceRunner {\n readonly name: Sequence;\n run(\n session: WizardSession,\n config: ProgramRun,\n programConfig: ProgramConfig,\n boot: BootstrapResult,\n /** Composed sub-run (integration inside self-driving); linear-only. */\n composed: boolean,\n ): Promise<void>;\n}\n\nexport const SEQUENCE_OPTIONS: Partial<Record<Sequence, SequenceRunner>> = {\n [Sequence.linear]: {\n name: Sequence.linear,\n run: (session, config, programConfig, boot, composed) =>\n runLinearProgram(session, config, programConfig, boot, composed),\n },\n [Sequence.orchestrator]: {\n name: Sequence.orchestrator,\n run: (session, config, programConfig, boot, _composed) =>\n runOrchestrator(session, config, programConfig, boot),\n },\n};\n\nexport function getSequence(name: Sequence): SequenceRunner {\n const sequence = SEQUENCE_OPTIONS[name];\n if (!sequence) {\n throw new Error(`No sequence registered for '${name}'.`);\n }\n return sequence;\n}\n\n// ── Middleware + resolver ───────────────────────────────────────────────\n\n/**\n * A composed sub-run (integration inside self-driving) is structurally\n * linear: the orchestrator owns the full run lifecycle (queue, outro) and\n * cannot nest. Sits above every override, including CLI.\n */\nconst composedClampMw: Middleware<Sequence> = (ctx, next) => {\n if (!ctx.composed) return next();\n if (ctx.trace) ctx.trace.sequence = 'composed';\n return Sequence.linear;\n};\n\n/** `--sequence` override. Dev/test only — the option is gated out of published builds. */\nconst cliSequenceMw: Middleware<Sequence> = (ctx, next) => {\n if (!ctx.cliSequence) return next();\n if (ctx.trace) ctx.trace.sequence = 'cli';\n return ctx.cliSequence;\n};\n\n/** A program's own flag route may pin the sequence; wins over the global orchestrator flag. Traced as 'payload' to stay distinguishable from sequence experiments ('flag'). */\nconst flagRouteSequenceMw: Middleware<Sequence> = (ctx, next) => {\n const route = resolveFlagRoute(ctx.program, ctx.flags, ctx.flagPayloads);\n if (!route?.sequence) return next();\n if (ctx.trace) ctx.trace.sequence = 'payload';\n return route.sequence;\n};\n\n/** Sequence experiments (e.g. wizard-orchestrator), each inert outside its declared programs. */\nconst sequenceExperimentMw: Middleware<Sequence> = (ctx, next) => {\n const sequence = resolveFlagSequence(ctx.program, ctx.flags);\n if (!sequence) return next();\n if (ctx.trace) ctx.trace.sequence = 'flag';\n return sequence;\n};\n\n/**\n * The orchestrator drives harnesses through `runTask`; a harness that has not\n * implemented it clamps the run to linear. A capability check, not a harness\n * identity check — a harness gains orchestrator support by implementing the\n * method, with no switchboard change. Sits below the CLI override so\n * `--sequence orchestrator` still reproduces the hard error in dev builds.\n */\nconst runTaskCapabilityClampMw: Middleware<Sequence> = (ctx, next) => {\n const pick = resolveHarness(ctx);\n if (getHarness(pick.harness).runTask) return next();\n if (isOrchestratorEnabled(ctx.flags)) {\n logToFile(\n `[switchboard] wizard-orchestrator ignored: ${pick.harness} has no runTask, clamping to linear`,\n );\n }\n if (ctx.trace) ctx.trace.sequence = 'runtask-clamp';\n return Sequence.linear;\n};\n\n// Order = precedence: CLI > capability clamp > flag > binding default. The\n// prod spread collapses to [], dropping cliSequenceMw from the chain.\nconst SEQUENCE_MIDDLEWARE: Middleware<Sequence>[] = [\n composedClampMw,\n ...(IS_PRODUCTION_BUILD ? [] : [cliSequenceMw]),\n runTaskCapabilityClampMw,\n flagRouteSequenceMw,\n sequenceExperimentMw,\n];\n\n/** CLI wins over `wizard-orchestrator` flag wins over binding default. */\nexport function resolveSequence(ctx: SwitchboardCtx): Sequence {\n const sequence = runChain(SEQUENCE_MIDDLEWARE, ctx, () => {\n if (ctx.trace) ctx.trace.sequence = 'binding';\n const binding = PROGRAM_BINDINGS[ctx.program] ?? DEFAULT_BINDING;\n return binding.sequence;\n });\n logToFile(\n `[switchboard] resolved: program=${ctx.program} sequence=${sequence}` +\n `${ctx.trace?.sequence ? ` (${ctx.trace.sequence})` : ''}`,\n );\n return sequence;\n}\n","/**\n * The switchboard — where a program's `(sequence, harness, model)` binding is\n * resolved. Two independent middleware chains, one per axis: CLI wins over\n * PostHog flag wins over per-program binding wins over `DEFAULT_BINDING`.\n *\n * Layout: `index.ts` (shared machinery + composer), `harness.ts`, `sequence.ts`.\n * Model ids are gateway strings — add new ones as constants in `@lib/constants`.\n */\n\nimport {\n DEFAULT_AGENT_MODEL,\n SONNET_5_MODEL,\n Harness,\n Sequence,\n} from '@lib/constants';\nimport type { ProgramId } from '@lib/programs/program-registry';\nimport { resolveHarness } from './harness';\nimport type { EffortLevel } from './models';\nimport { resolveSequence } from './sequence';\n\n// ── Shared machinery ────────────────────────────────────────────────────\n\n/** Which precedence rung decided each axis. Stamped by middlewares as they assert. */\nexport interface SwitchboardTrace {\n harness?: 'cli' | 'flag' | 'binding';\n model?: 'cli' | 'flag' | 'binding';\n sequence?:\n | 'cli'\n | 'composed'\n | 'runtask-clamp'\n | 'payload'\n | 'flag'\n | 'binding';\n}\n\n/** Everything a resolver middleware may branch on. Built once per run. */\nexport interface SwitchboardCtx {\n program: ProgramId;\n /** Composed sub-run (a dependency inside a parent program). Structurally linear — no override can orchestrate it. */\n composed?: boolean;\n flags: Record<string, string>;\n /** Flag payloads from the same snapshot (payload-carrying flags, e.g. self-driving pi). */\n flagPayloads?: Record<string, unknown>;\n /** CLI override (`--harness`). Wins over `flags`. */\n cliHarness?: Harness;\n /** CLI override (`--sequence`). Wins over `flags`. */\n cliSequence?: Sequence;\n /** CLI override (`--model`, gateway id). Wins over the binding's model. */\n cliModel?: string;\n /** Filled during resolution; read by the caller for telemetry. */\n trace?: SwitchboardTrace;\n}\n\n/** A resolver middleware: defer via `next()`, or assert by returning a value. */\nexport type Middleware<D> = (ctx: SwitchboardCtx, next: () => D) => D;\n\n/**\n * Run a middleware chain over `ctx`. Each middleware receives `next` (which\n * runs the rest of the chain) and can either:\n * - defer: call `next()` and optionally modify its result (overlay pattern)\n * - short-circuit: return a value without calling `next()` (skip the rest)\n *\n * **Earlier in the array = higher precedence.** Index 0 runs first and can\n * short-circuit the rest; index 1 only runs if index 0 deferred. So\n * `[cliSequenceMw, orchestratorFeatureFlagMw]` means CLI takes precedence over the\n * flag, not the other way around.\n *\n * `fallback` runs at the end — reached only when every middleware deferred.\n * Typically the map read for the base value.\n */\nexport function runChain<D>(\n chain: Middleware<D>[],\n ctx: SwitchboardCtx,\n fallback: () => D,\n): D {\n function step(index: number): D {\n if (index >= chain.length) return fallback();\n const middleware = chain[index];\n const next = () => step(index + 1);\n return middleware(ctx, next);\n }\n return step(0);\n}\n\n// ── Data model ──────────────────────────────────────────────────────────\n\n/** Harness + model for one leaf of agent work. */\nexport interface HarnessPick {\n harness: Harness;\n /** Gateway model id (string). */\n model: string;\n /** Reasoning-effort override. Absent → the model's table default. */\n thinkingLevel?: EffortLevel;\n}\n\nexport interface ProgramBinding {\n sequence: Sequence;\n harness: Harness;\n model: string;\n /** Reasoning-effort override for the model. Absent → the model's table default. */\n thinkingLevel?: EffortLevel;\n /**\n * Per-role overrides applied only in orchestrator mode — keys are\n * agent-prompt `type` values published by context-mill (`'seed'`,\n * `'install'`, `'capture'`, etc.). Linear runs use role `'default'` and\n * skip this map.\n */\n contextMillOverride?: Record<string, Partial<HarnessPick>>;\n}\n\n/** Default binding. Every program points here until it overrides. */\nexport const DEFAULT_BINDING: ProgramBinding = {\n sequence: Sequence.linear,\n harness: Harness.anthropic,\n model: DEFAULT_AGENT_MODEL,\n};\n\n/**\n * Per-program routing. Kept in lockstep with `PROGRAM_REGISTRY` by the\n * switchboard test. Anything absent falls back to `DEFAULT_BINDING`.\n */\nexport const PROGRAM_BINDINGS: Partial<Record<ProgramId, ProgramBinding>> = {\n 'posthog-integration': DEFAULT_BINDING,\n 'revenue-analytics-setup': DEFAULT_BINDING,\n 'warehouse-source': DEFAULT_BINDING,\n 'error-tracking-upload-source-maps': DEFAULT_BINDING,\n audit: DEFAULT_BINDING,\n 'events-audit': DEFAULT_BINDING,\n 'posthog-doctor': DEFAULT_BINDING,\n 'web-analytics-doctor': DEFAULT_BINDING,\n migration: DEFAULT_BINDING,\n 'self-driving': DEFAULT_BINDING,\n 'agent-skill': DEFAULT_BINDING,\n 'mcp-add': DEFAULT_BINDING,\n 'mcp-remove': DEFAULT_BINDING,\n 'mcp-tutorial': DEFAULT_BINDING,\n 'mcp-analytics': DEFAULT_BINDING,\n // Orchestrator on pi. The binding routes only; every stage's model and\n // effort are pinned context-mill side in the flow's frontmatter\n // (`model_pi`/`effort_pi`: terra seed, sol tasks, luna report).\n metrics: {\n sequence: Sequence.orchestrator,\n harness: Harness.pi,\n model: DEFAULT_AGENT_MODEL,\n },\n 'replay-vision': {\n sequence: Sequence.orchestrator,\n harness: Harness.anthropic,\n model: DEFAULT_AGENT_MODEL,\n },\n 'ai-observability': {\n sequence: Sequence.linear,\n harness: Harness.anthropic,\n model: SONNET_5_MODEL,\n },\n slack: DEFAULT_BINDING,\n};\n\n// ── Unified resolver ────────────────────────────────────────────────────\n\n/** Compose both axes. Callers needing only one axis use the per-axis resolver. */\nexport function resolveBinding(\n ctx: SwitchboardCtx,\n role = 'default',\n): ProgramBinding {\n ctx.trace ??= {};\n const sequence = resolveSequence(ctx);\n const { harness, model, thinkingLevel } = resolveHarness(ctx, role);\n return { sequence, harness, model, thinkingLevel };\n}\n\n// ── Unified re-export surface ───────────────────────────────────────────\nexport { HARNESS_OPTIONS, getHarness, resolveHarness } from './harness';\nexport {\n SEQUENCE_OPTIONS,\n getSequence,\n resolveSequence,\n type SequenceRunner,\n} from './sequence';\nexport {\n isOrchestratorEnabled,\n areSeededTasksEnabled,\n resolveStageOverrides,\n} from './flags';\n","/**\n * Shared bootstrap for the runner pipeline.\n *\n * Runs before the fork into the linear or orchestrator arm: logging, health\n * check, settings conflicts, OAuth and credentials, feature flags, variant\n * metadata, and MCP url. Sets `session.credentials`, role, and user as side\n * effects. Returns the values the arms still need.\n */\n\nimport type { WizardSession } from '@lib/wizard-session';\nimport { analytics } from '@utils/analytics';\nimport { getUI } from '@ui';\nimport { authenticate } from './authenticate';\nimport { createTriageLLMProvider } from '@lib/agent/triage-provider';\nimport { gatewayAuth } from '@lib/gateway-session';\nimport { resolveHarness } from '../switchboard';\nimport { buildRunTags } from '@lib/agent/agent-interface';\nimport {\n checkAllSettingsConflicts,\n backupAndFixClaudeSettings,\n classifySettingsConflicts,\n} from '@lib/agent/claude-settings';\nimport {\n evaluateWizardReadiness,\n WizardReadiness,\n SIGNUP_WIZARD_READINESS_CONFIG,\n getBlockingServiceKeys,\n SERVICE_LABELS,\n} from '@lib/health-checks/readiness';\nimport { enableDebugLogs, logToFile, initLogFile } from '@utils/debug';\nimport { wizardAbort } from '@utils/wizard-abort';\nimport { ErrorCodes } from '@lib/errors';\nimport { isNonInteractiveEnvironment } from '@utils/environment';\nimport { CallType, getSkillsBaseUrl, IS_DEV } from '@lib/constants';\nimport { VERSION } from '@lib/version';\nimport { mcpUrlFor } from '@lib/host-resolution';\nimport type { WizardRunOptions } from '@utils/types';\nimport type { ProgramConfig } from '@lib/programs/program-step';\nimport type { ProgramRun, BootstrapResult } from './types';\n\n// ── Helpers ──────────────────────────────────────────────────────────\n\n/**\n * Decide whether the `wizard_ask` overlay should be wired for this run.\n * Disabled in non-interactive modes (CI, signup) — there's no human to\n * answer. Per-program disabling is done by adding WIZARD_ASK_TOOL_NAME to\n * the program's `disallowedTools` so the SDK rejects calls outright.\n * Extracted so the policy can be unit-tested directly.\n *\n * `session.e2eAsk` is the one escape hatch. The e2e harness runs a `ci`\n * session, but it does have an answerer — the driver loop answers each\n * `wizard_ask` batch from the program's e2e profile. Without the flag the\n * agent-in-the-loop layer (the ask bridge in both sequence arms, and the\n * orchestrator's seeded warehouse task) stays unreachable from a test.\n *\n * Only the e2e TUI host sets the flag, from the `E2E_ASK` env var. No CLI flag\n * populates it, so plain `--ci` and `--signup` runs behave exactly as before.\n */\nexport function shouldDisableAsk(\n session: Pick<WizardSession, 'ci' | 'signup' | 'e2eAsk'>,\n): boolean {\n return (session.ci || session.signup) && !session.e2eAsk;\n}\n\nexport function sessionToOptions(session: WizardSession): WizardRunOptions {\n return {\n installDir: session.installDir,\n debug: session.debug,\n signup: session.signup,\n ci: session.ci,\n benchmark: session.benchmark,\n projectId: session.projectId,\n apiKey: session.apiKey,\n yaraReport: session.yaraReport,\n };\n}\n\n// ── Bootstrap ─────────────────────────────────────────────────────────\n\n/**\n * Shared setup for both arms: logging, health check, settings conflicts, OAuth\n * and credentials, then the feature flags, variant metadata, and MCP url. Sets\n * `session.credentials`, role, and user as a side effect. Returns the values the\n * arms still need.\n */\nexport async function bootstrapProgram(\n session: WizardSession,\n config: ProgramRun,\n programConfig: ProgramConfig,\n): Promise<BootstrapResult> {\n // 1. Init logging + debug\n initLogFile();\n session.skillId = config.skillId ?? config.integrationLabel;\n logToFile(\n `[agent-runner] START ${config.integrationLabel} build=${analytics.build}` +\n `${session.ci ? ' (non-interactive)' : ''}`,\n );\n\n if (session.debug) {\n enableDebugLogs();\n }\n\n const skillsBaseUrl = getSkillsBaseUrl();\n\n // Where this run actually points. The three services switch independently,\n // so otherwise \"why did it use prod skills?\" means reading three call sites.\n logToFile(\n `[agent-runner] targets build=${VERSION}${IS_DEV ? '/dev' : ''} ` +\n `skills=${skillsBaseUrl} ` +\n `mcp=${mcpUrlFor(session.localMcp)} ` +\n `posthog=${session.baseUrl ?? 'region-resolved'}`,\n );\n\n // 2. Health check (guarded — skip if TUI already ran it). Only\n // programs that declare a health-check screen get pre-flight checks;\n // for everything else the checks never fire and never block.\n const hasHealthCheckScreen = programConfig.steps.some(\n (s) => s.screenId === 'health-check',\n );\n if (session.readinessResult) {\n logToFile(\n `[agent-runner] readiness pre-computed by TUI: decision=${session.readinessResult.decision}` +\n `${\n session.outageDismissed ? ' (outage dismissed by user)' : ''\n } — skipping re-check`,\n );\n }\n if (hasHealthCheckScreen && !session.readinessResult) {\n logToFile('[agent-runner] evaluating wizard readiness');\n const readinessConfig = session.signup\n ? SIGNUP_WIZARD_READINESS_CONFIG\n : undefined;\n const readiness = await evaluateWizardReadiness(readinessConfig);\n logToFile(`[agent-runner] readiness=${readiness.decision}`);\n if (readiness.decision === WizardReadiness.No) {\n const blockingKeys = getBlockingServiceKeys(\n readiness.health,\n readinessConfig,\n );\n const blockingLabels = blockingKeys.map(\n (k) => `${SERVICE_LABELS[k]} (${readiness.health[k].status})`,\n );\n logToFile(`[agent-runner] blocked by: ${blockingLabels.join(', ')}`);\n\n await getUI().showBlockingOutage(readiness);\n\n // The TUI lets the user continue past an outage; non-interactive runs\n // (CI) do the same automatically — the degraded services are reported\n // above, but we proceed rather than aborting on a transient upstream blip.\n if (!isNonInteractiveEnvironment()) {\n await wizardAbort({\n code: ErrorCodes.EnvServiceOutage,\n message:\n 'Cannot start — external services are down:\\n' +\n blockingLabels.map((l) => ` - ${l}`).join('\\n') +\n '\\n\\nPlease try again later.',\n });\n }\n } else if (readiness.decision === WizardReadiness.YesWithWarnings) {\n getUI().setReadinessWarnings(readiness);\n }\n }\n\n // 3. Settings conflicts\n const settingsConflicts = checkAllSettingsConflicts(session.installDir);\n logToFile(\n `[agent-runner] settings conflicts: ${\n settingsConflicts.length > 0\n ? settingsConflicts\n .map((c) => `${c.source}(${c.keys.join(',')})`)\n .join('; ')\n : 'none'\n }`,\n );\n\n if (settingsConflicts.length > 0) {\n for (const conflict of settingsConflicts) {\n const level = conflict.source === 'managed' ? 'org' : conflict.source;\n analytics.wizardCapture('settings conflict detected', {\n level,\n keys: conflict.keys,\n });\n }\n\n const { autoFix, failClosed, warnOnly } =\n classifySettingsConflicts(settingsConflicts);\n\n // User-global and project-local files are already neutralized — the agent\n // runs with settingSources:['project'], so the SDK never reads them. Record\n // it and move on; don't make the user act on a setting that can't bite.\n for (const conflict of warnOnly) {\n logToFile(\n `[agent-runner] settings conflict in ${conflict.source} (${conflict.path}) ` +\n `neutralized by settingSources:['project'] — not blocking`,\n );\n analytics.wizardCapture('settings conflict neutralized', {\n level: conflict.source,\n keys: conflict.keys,\n });\n }\n\n // Writable project settings.json — the SDK *does* read it, but we can back\n // it up and remove it (restored at outro). Neutralize without prompting.\n let unfixable = failClosed;\n if (autoFix.length > 0) {\n const fixed = backupAndFixClaudeSettings(session.installDir);\n if (fixed) {\n logToFile('[agent-runner] auto-neutralized writable settings conflict');\n analytics.wizardCapture('settings conflict auto-neutralized', {\n keys: autoFix.flatMap((c) => c.keys),\n });\n } else {\n // Couldn't remove it — don't run into the redirect; fail closed instead.\n logToFile(\n '[agent-runner] could not back up writable settings conflict — failing closed',\n );\n unfixable = [...failClosed, ...autoFix];\n }\n }\n\n // What we cannot neutralize (org-managed, always read by the SDK; or a\n // writable file we failed to back up) must be fixed by the user. Fail\n // closed: the screen names the file + keys and exits.\n if (unfixable.length > 0) {\n if (isNonInteractiveEnvironment()) {\n await wizardAbort({\n code: ErrorCodes.SettingsUnfixableConflict,\n message:\n 'Cannot start — a Claude settings file redirects the agent away ' +\n 'from the PostHog gateway and cannot be neutralized automatically:\\n' +\n unfixable\n .map((c) => ` - ${c.source} (${c.path}): ${c.keys.join(', ')}`)\n .join('\\n') +\n '\\n\\nRemove the conflicting keys and re-run the wizard.',\n });\n }\n await getUI().showSettingsOverride(unfixable, () =>\n backupAndFixClaudeSettings(session.installDir),\n );\n logToFile('[agent-runner] settings override resolved');\n }\n }\n\n analytics.wizardCapture('agent started', {\n integration: config.integrationLabel,\n program_id: programConfig.id,\n skill_id: config.skillId ?? null,\n });\n\n // 4. Authenticate — idempotent within a run (see authenticate()). A second\n // agent run in the same invocation (self-driving's integration phase) reuses\n // the first login; it does not launch another OAuth. authenticate() also\n // identifies the user and sets analytics groups.\n await authenticate(session, programConfig.id);\n const project = session.apiProject;\n\n // 4.5. AI opt-in enforcement. Parks here while AiOptInRequiredScreen is\n // up if the org hasn't approved third-party AI — BEFORE the skill\n // install and agent start, so no source leaves the machine. The screen\n // alone is cosmetic; this await is the actual gate. Resolves\n // immediately when the program declared requiresAi: false or in CI.\n // In bootstrapProgram so both the linear and orchestrator arms gate.\n logToFile('[agent-runner] checking AI opt-in gate');\n await getUI().waitForAiOptIn();\n logToFile('[agent-runner] AI opt-in gate cleared');\n\n // Park for any interactive step the user must complete AFTER authenticating\n // but BEFORE the agent runs — e.g. the source-maps project picker, which\n // needs credentials to scan and writes its choice to frameworkContext that\n // the run prompt reads. Generic: await every gated step between auth and run.\n const authIndex = programConfig.steps.findIndex((s) => s.screenId === 'auth');\n const runIndex = programConfig.steps.findIndex((s) => s.screenId === 'run');\n if (authIndex !== -1 && runIndex > authIndex) {\n for (const step of programConfig.steps.slice(authIndex + 1, runIndex)) {\n if (step.gate) {\n logToFile(`[agent-runner] awaiting post-auth gate: ${step.id}`);\n await getUI().waitForGate(step.id);\n logToFile(`[agent-runner] post-auth gate cleared: ${step.id}`);\n }\n }\n }\n\n // Feature flags. Both arms need these, and the fork decision reads the flags.\n // This map is PostHog-side only — CLI `--harness` / `--sequence` precedence\n // lives at the resolution sites (`runner/index.ts` for sequence,\n // `resolveHarness` for harness), not here.\n const wizardFlags = await analytics.getAllFlagsForWizard();\n const wizardFlagPayloads = analytics.getWizardFlagPayloads();\n\n // Gateway trace tags for this run. The runner stamps its variant onto this\n // after the fork (see runProgram), so the value reflects which arm ran.\n const wizardMetadata = buildRunTags({\n programId: programConfig.id,\n integration: config.integrationLabel,\n runId: analytics.runId,\n build: analytics.build,\n skillId: config.skillId,\n });\n\n // Credentials (incl. the resolved host family and its MCP url) live on\n // `session.credentials`; narrow once at this boundary — `authenticate` above\n // set them — so downstream readers get a non-null type without asserting.\n const credentials = session.credentials!;\n\n // Resolve the gateway posture once for the boot: v2 scoped token when the\n // backend mints, legacy OAuth otherwise.\n const auth = await gatewayAuth(\n credentials.host,\n credentials.accessToken,\n programConfig.id,\n );\n\n return {\n skillsBaseUrl,\n credentials,\n // Carried so per-task sessions re-resolve against the same program the boot\n // minted for, rather than digging it back out of the metadata bag.\n programId: programConfig.id,\n wizardFlags,\n wizardFlagPayloads,\n wizardMetadata,\n project,\n // Resolved once, here: the only place holding both the switchboard inputs\n // and the gateway auth. Every skill install downstream reads it off boot.\n triageProvider: createTriageLLMProvider(\n {\n baseURL: auth.gatewayUrl,\n authToken: auth.token,\n edition: auth.edition,\n teamId: auth.teamId,\n // `call_type` splits scan spend out of the program's agent cost —\n // same tag the in-run triage provider carries.\n wizardMetadata: { ...wizardMetadata, call_type: CallType.yaraTriage },\n wizardFlags,\n },\n resolveHarness({\n program: programConfig.id,\n flags: wizardFlags,\n flagPayloads: wizardFlagPayloads,\n cliHarness: session.harness,\n cliModel: session.model,\n }).harness,\n ),\n };\n}\n","/**\n * Unified program runner — dispatcher.\n *\n * Single configurable pipeline for all programs. Each program\n * provides a ProgramRun (via the `run` field on ProgramConfig)\n * that controls:\n * - Whether a skill is pre-installed or discovered at runtime\n * - How the agent prompt is built\n * - What MCP servers and package manager detector to use\n * - What happens after the agent completes\n *\n * The pipeline runs a shared bootstrap (logging, health check, settings, OAuth,\n * flags, MCP url), then forks. The `orchestrator` variant routes to the\n * experimental task-queue runner. Every other variant runs the fixed linear\n * pipeline:\n * [skill install] → agent init → prompt → run → errors → [postRun] → outro\n */\n\nimport type { WizardSession } from '../../wizard-session';\nimport { analytics } from '@utils/analytics';\nimport {\n Sequence,\n WIZARD_ORCHESTRATOR_FLAG_KEY,\n WIZARD_SELF_DRIVING_USE_PI_HARNESS_FLAG_KEY,\n} from '@lib/constants';\nimport { logToFile } from '@utils/debug';\nimport { getUI } from '../../../ui';\nimport type { ProgramConfig } from '../../programs/program-step';\nimport type { ProgramRun, BootstrapResult } from './shared/types';\nimport { bootstrapProgram } from './shared/bootstrap';\nimport {\n getSequence,\n resolveBinding,\n type ProgramBinding,\n type SwitchboardCtx,\n} from './switchboard';\nimport { flushScanReport } from '../../yara-hooks';\nimport { registerCleanup } from '../../../utils/wizard-abort';\n\nexport type {\n ProgramRun,\n BootstrapResult,\n AbortCase,\n PromptContext,\n Credentials,\n} from './shared/types';\nexport { shouldDisableAsk } from './shared/bootstrap';\n\n/**\n * Resolve a ProgramConfig's agent run definition and execute the pipeline.\n * Entry point for bin.ts — handles buildRunConfig, bootstrap, and (future) run field.\n */\nexport async function runAgent(\n programConfig: ProgramConfig,\n session: WizardSession,\n options: { composed?: boolean } = {},\n): Promise<void> {\n if (!programConfig.run) {\n throw new Error(`Program \"${programConfig.id}\" has no run configuration.`);\n }\n\n const runDef =\n typeof programConfig.run === 'function'\n ? await programConfig.run(session)\n : programConfig.run;\n\n await runProgram(session, runDef, programConfig, options);\n}\n\n/**\n * Run a program's agent pipeline.\n *\n * Bootstrap → bind the program via the switchboard (resolve which sequence\n * and harness will run it, tag both axes) → dispatch to the resolved\n * sequence's runner.\n */\nexport async function runProgram(\n session: WizardSession,\n config: ProgramRun,\n programConfig: ProgramConfig,\n options: { composed?: boolean } = {},\n): Promise<void> {\n const boot = await bootstrapProgram(session, config, programConfig);\n\n // Flush the warlock scan report once, at this single seam, on every\n // termination path and for every harness (linear, orchestrator, or future):\n // - registerCleanup covers the abort/cancel path (wizardAbort runs the\n // registered cleanups; the success path never calls them)\n // - the finally covers normal completion and any direct throw that unwinds\n // through here\n // flushScanReport is idempotent (it zeroes scan state), so the overlap is a\n // harmless no-op. No harness has to know reporting exists.\n registerCleanup(() => flushScanReport(session));\n try {\n const binding = resolveProgramRunner(\n session,\n programConfig,\n boot,\n options.composed ?? false,\n );\n if (binding.sequence === Sequence.orchestrator) {\n getUI().log.info('Task-queue orchestrator enabled.');\n }\n return await getSequence(binding.sequence).run(\n session,\n config,\n programConfig,\n boot,\n options.composed ?? false,\n );\n } finally {\n flushScanReport(session);\n }\n}\n\n/**\n * Resolve which sequence and harness will run a program (CLI → PostHog flag →\n * per-program binding → default), tag both axes onto analytics, and return the\n * binding for downstream dispatch.\n *\n * The one place `runner/index.ts` reaches into the switchboard — every other\n * concern (bootstrap, cleanup, dispatch, per-task per-role harness picks) is\n * either upstream or downstream of this call.\n */\nfunction resolveProgramRunner(\n session: WizardSession,\n programConfig: ProgramConfig,\n boot: BootstrapResult,\n composed: boolean,\n): ProgramBinding {\n const ctx = {\n program: programConfig.id,\n composed,\n flags: boot.wizardFlags,\n flagPayloads: boot.wizardFlagPayloads,\n cliHarness: session.harness,\n cliSequence: session.sequence,\n cliModel: session.model,\n };\n const binding = resolveBinding(ctx);\n tagBinding(boot, binding);\n captureSwitchboardDecision(ctx, binding);\n return binding;\n}\n\n/**\n * One event + one log line per run: what entered the switchboard, which\n * precedence rung decided each axis, and the final pick.\n */\nfunction captureSwitchboardDecision(\n ctx: SwitchboardCtx,\n binding: ProgramBinding,\n): void {\n const trace = ctx.trace ?? {};\n // Unpinned orchestrator runs choose a model per task from the context-mill agent prompts; the orchestrator logs that map once the prompts load.\n const perTaskModel =\n binding.sequence === Sequence.orchestrator && trace.model === 'binding';\n const model = perTaskModel ? 'chosen-per-task' : binding.model;\n const modelSource = perTaskModel ? 'agent-prompts' : trace.model;\n analytics.wizardCapture('switchboard resolved', {\n program: ctx.program,\n flag_self_driving_use_pi_harness:\n ctx.flags[WIZARD_SELF_DRIVING_USE_PI_HARNESS_FLAG_KEY],\n flag_self_driving_pi_payload: JSON.stringify(\n ctx.flagPayloads?.[WIZARD_SELF_DRIVING_USE_PI_HARNESS_FLAG_KEY] ?? null,\n ),\n flag_orchestrator: ctx.flags[WIZARD_ORCHESTRATOR_FLAG_KEY],\n cli_harness: ctx.cliHarness,\n cli_sequence: ctx.cliSequence,\n cli_model: ctx.cliModel,\n harness_source: trace.harness,\n model_source: modelSource,\n sequence_source: trace.sequence,\n harness: binding.harness,\n model,\n thinking_level: binding.thinkingLevel,\n sequence: binding.sequence,\n });\n logToFile(\n `[switchboard] decision: program=${ctx.program}` +\n ` in(orchestrator=${ctx.flags[WIZARD_ORCHESTRATOR_FLAG_KEY] ?? '-'},` +\n ` cli=${ctx.cliHarness ?? '-'}/${ctx.cliSequence ?? '-'}/${\n ctx.cliModel ?? '-'\n })` +\n ` → harness=${binding.harness} (${trace.harness ?? '?'})` +\n ` model=${model} (${modelSource ?? '?'})` +\n ` sequence=${binding.sequence} (${trace.sequence ?? '?'})`,\n );\n}\n\n/**\n * Tag the run with its two routing axes. Sequence is stable for the whole\n * run; harness reflects the run-level (default-role) resolution — orchestrator\n * per-task calls emit their own `harness` property in their events so per-task\n * aggregations attribute correctly.\n */\nfunction tagBinding(boot: BootstrapResult, binding: ProgramBinding): void {\n analytics.setTag('sequence', binding.sequence);\n analytics.setTag('harness', binding.harness);\n boot.wizardMetadata.SEQUENCE = binding.sequence;\n boot.wizardMetadata.HARNESS = binding.harness;\n}\n","/**\n * Re-export shim. The runner has been split into agent/runner/.\n * Import from there directly; this shim keeps existing importers working.\n */\n\nexport {\n runAgent,\n runProgram,\n shouldDisableAsk,\n type ProgramRun,\n type BootstrapResult,\n type AbortCase,\n type PromptContext,\n type Credentials,\n} from './runner/index';\n"],"mappings":"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"}
|