@posthog/wizard 2.65.0 → 2.67.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{add-mcp-server-to-clients-ArtlMX9-.js → add-mcp-server-to-clients-DHTRbyJX.js} +228 -64
- package/dist/add-mcp-server-to-clients-DHTRbyJX.js.map +1 -0
- package/dist/{agent-interface-ORzGEFNM.js → agent-interface-tM_b0l__.js} +458 -76
- package/dist/agent-interface-tM_b0l__.js.map +1 -0
- package/dist/{agent-prompt-loader-D3w6sc34.js → agent-prompt-loader-BSMh5bfD.js} +5 -5
- package/dist/{agent-prompt-loader-D3w6sc34.js.map → agent-prompt-loader-BSMh5bfD.js.map} +1 -1
- package/dist/{agent-runner-Ca-e2TOQ.js → agent-runner-DD65OMkB.js} +153 -71
- package/dist/agent-runner-DD65OMkB.js.map +1 -0
- package/dist/analytics-B4Igh5nv.js +2 -0
- package/dist/{analytics-zBrIVjMV.js → analytics-CtIYzkK4.js} +2 -2
- package/dist/{analytics-zBrIVjMV.js.map → analytics-CtIYzkK4.js.map} +1 -1
- package/dist/{api-Wgb7AhrP.js → api-BJft9v6K.js} +3 -3
- package/dist/{api-Wgb7AhrP.js.map → api-BJft9v6K.js.map} +1 -1
- package/dist/bin.js +245 -102
- package/dist/bin.js.map +1 -1
- package/dist/{bounded-fs-DqsVmh4r.js → bounded-fs-BWqoFQvQ.js} +3 -3
- package/dist/{bounded-fs-DqsVmh4r.js.map → bounded-fs-BWqoFQvQ.js.map} +1 -1
- package/dist/{ci-install-D1QqmJIc.js → ci-install-BXGnVI7T.js} +18 -9
- package/dist/ci-install-BXGnVI7T.js.map +1 -0
- package/dist/{debug-Cm1hvkVy.js → debug-BsHD83Vy.js} +4 -4
- package/dist/debug-BsHD83Vy.js.map +1 -0
- package/dist/{debug-CtQ13sCW.js → debug-mO3yg4Z7.js} +1 -1
- package/dist/{defaults-BHhXrX9F.js → defaults-DI642M3n.js} +1 -1
- package/dist/{defaults-BHhXrX9F.js.map → defaults-DI642M3n.js.map} +1 -1
- package/dist/{env-api-key-CdI2XZIz.js → env-api-key-DS0ghlcO.js} +2 -2
- package/dist/{env-api-key-CdI2XZIz.js.map → env-api-key-DS0ghlcO.js.map} +1 -1
- package/dist/{environment-BhFvfkQg.js → environment-C7CKGIOE.js} +4 -4
- package/dist/{environment-BhFvfkQg.js.map → environment-C7CKGIOE.js.map} +1 -1
- package/dist/errors-BHervYGs.js +156 -0
- package/dist/errors-BHervYGs.js.map +1 -0
- package/dist/{file-watcher-Dciz09Rr.js → file-watcher-D1bdo9mq.js} +2 -2
- package/dist/{file-watcher-Dciz09Rr.js.map → file-watcher-D1bdo9mq.js.map} +1 -1
- package/dist/{headless-ui-B4FnKm11.js → headless-ui-6QuByWZ_.js} +2 -2
- package/dist/{headless-ui-B4FnKm11.js.map → headless-ui-6QuByWZ_.js.map} +1 -1
- package/dist/{interactive-DxHFVYr2.js → interactive-DUpW84WU.js} +2 -2
- package/dist/{interactive-DxHFVYr2.js.map → interactive-DUpW84WU.js.map} +1 -1
- package/dist/{local-dev-BN6NKQ0B.js → local-dev-DPZiIPCK.js} +1 -1
- package/dist/{local-dev-BN6NKQ0B.js.map → local-dev-DPZiIPCK.js.map} +1 -1
- package/dist/{mcp-t0UxAPur.js → mcp-CHo9h-WV.js} +2 -2
- package/dist/{mcp-t0UxAPur.js.map → mcp-CHo9h-WV.js.map} +1 -1
- package/dist/mcp-install-smoke-test.ts +477 -0
- package/dist/{mcp-prompt-streaming-ro98iUDc.js → mcp-prompt-streaming-CHRPxxd0.js} +4 -4
- package/dist/{mcp-prompt-streaming-ro98iUDc.js.map → mcp-prompt-streaming-CHRPxxd0.js.map} +1 -1
- package/dist/{non-interactive-BA2L_jDT.js → non-interactive-Cr-chffe.js} +7 -2
- package/dist/non-interactive-Cr-chffe.js.map +1 -0
- package/dist/{orchestrator-tools-vZmNsHy9.js → orchestrator-tools-Tx18_TMb.js} +3 -3
- package/dist/{orchestrator-tools-vZmNsHy9.js.map → orchestrator-tools-Tx18_TMb.js.map} +1 -1
- package/dist/{package-json-D0DCWpe5.js → package-json-GEU2VZlS.js} +1 -1
- package/dist/{package-json-D0DCWpe5.js.map → package-json-GEU2VZlS.js.map} +1 -1
- package/dist/{package-manager-DgqJdAQk.js → package-manager-CLfc31yf.js} +4 -4
- package/dist/package-manager-CLfc31yf.js.map +1 -0
- package/dist/{pi-nwrCARRp.js → pi-RlnYUHdb.js} +12 -11
- package/dist/{pi-nwrCARRp.js.map → pi-RlnYUHdb.js.map} +1 -1
- package/dist/{playground-xkEke_h0.js → playground-DQ633rje.js} +7 -7
- package/dist/{playground-xkEke_h0.js.map → playground-DQ633rje.js.map} +1 -1
- package/dist/{posthog-9To56cSd.js → posthog-DSn9bIZc.js} +2 -2
- package/dist/{posthog-9To56cSd.js.map → posthog-DSn9bIZc.js.map} +1 -1
- package/dist/{posthog-integration-CoPvN6YZ.js → posthog-integration-DFfBRGOC.js} +667 -37
- package/dist/posthog-integration-DFfBRGOC.js.map +1 -0
- package/dist/{provisioning-BYFSHSHY.js → provisioning-Cvy_vQHV.js} +3 -3
- package/dist/{provisioning-BYFSHSHY.js.map → provisioning-Cvy_vQHV.js.map} +1 -1
- package/dist/{queue-tools-BREbgGSC.js → queue-tools-BC9HxOV6.js} +33 -7
- package/dist/queue-tools-BC9HxOV6.js.map +1 -0
- package/dist/{registry-DGJQ_8QI.js → registry-DCAElOyj.js} +81 -81
- package/dist/{registry-DGJQ_8QI.js.map → registry-DCAElOyj.js.map} +1 -1
- package/dist/{security-wc-naGq5.js → security-CuSX3XVo.js} +21 -9
- package/dist/security-CuSX3XVo.js.map +1 -0
- package/dist/{setup-utils-Cz0wPLsQ.js → setup-utils-D1tv0v_R.js} +13 -13
- package/dist/{setup-utils-Cz0wPLsQ.js.map → setup-utils-D1tv0v_R.js.map} +1 -1
- package/dist/{start-tui-DDW9uVnD.js → start-tui-B5YfmqNr.js} +57 -25
- package/dist/start-tui-B5YfmqNr.js.map +1 -0
- package/dist/{steps-CZI0B24_.js → steps-CLaSMwfR.js} +7 -7
- package/dist/{steps-CZI0B24_.js.map → steps-CLaSMwfR.js.map} +1 -1
- package/dist/{store-xMkU8xAa.js → store-DzEgsAPN.js} +7 -6
- package/dist/{store-xMkU8xAa.js.map → store-DzEgsAPN.js.map} +1 -1
- package/dist/{subagent-BztacyoV.js → subagent-BUV6aD7p.js} +2 -2
- package/dist/{subagent-BztacyoV.js.map → subagent-BUV6aD7p.js.map} +1 -1
- package/dist/{task-CJ7x3McC.js → task-GnWId75q.js} +13 -12
- package/dist/{task-CJ7x3McC.js.map → task-GnWId75q.js.map} +1 -1
- package/dist/{task-stream-BK7JQ27G.js → task-stream-DSzvwJrD.js} +16 -9
- package/dist/task-stream-DSzvwJrD.js.map +1 -0
- package/dist/{tasks-FGzp_zBd.js → tasks-BO0W8ocx.js} +2 -2
- package/dist/{tasks-FGzp_zBd.js.map → tasks-BO0W8ocx.js.map} +1 -1
- package/dist/{telemetry-By56gAtF.js → telemetry-Vi9dWddJ.js} +3 -3
- package/dist/{telemetry-By56gAtF.js.map → telemetry-Vi9dWddJ.js.map} +1 -1
- package/dist/{terminal-C_rmkaku.js → terminal-B5wZK7aS.js} +73 -80
- package/dist/terminal-B5wZK7aS.js.map +1 -0
- package/dist/{tools-BpCJgMez.js → tools-C9cNluqc.js} +54 -47
- package/dist/tools-C9cNluqc.js.map +1 -0
- package/dist/{wizard-abort-BlDla_Jd.js → wizard-abort-BsNbguJt.js} +1 -1
- package/dist/wizard-abort-CGv3lVxw.js +71 -0
- package/dist/wizard-abort-CGv3lVxw.js.map +1 -0
- package/dist/{wizard-session-Bn6dO1gE.js → wizard-session-Cex1BiXs.js} +3 -2
- package/dist/wizard-session-Cex1BiXs.js.map +1 -0
- package/dist/{wizard-session-UxA_A0cA.js → wizard-session-DHbUcjI7.js} +1 -1
- package/dist/yara-hooks-C3Vm2Gow.js +2 -0
- package/dist/{yara-hooks-BrisBebM.js → yara-hooks-DZIVzhA6.js} +57 -8
- package/dist/yara-hooks-DZIVzhA6.js.map +1 -0
- package/package.json +2 -1
- package/dist/add-mcp-server-to-clients-ArtlMX9-.js.map +0 -1
- package/dist/agent-interface-ORzGEFNM.js.map +0 -1
- package/dist/agent-runner-Ca-e2TOQ.js.map +0 -1
- package/dist/analytics-C4j6grao.js +0 -2
- package/dist/ci-install-D1QqmJIc.js.map +0 -1
- package/dist/debug-Cm1hvkVy.js.map +0 -1
- package/dist/non-interactive-BA2L_jDT.js.map +0 -1
- package/dist/package-manager-DgqJdAQk.js.map +0 -1
- package/dist/posthog-integration-CoPvN6YZ.js.map +0 -1
- package/dist/queue-tools-BREbgGSC.js.map +0 -1
- package/dist/security-wc-naGq5.js.map +0 -1
- package/dist/start-tui-DDW9uVnD.js.map +0 -1
- package/dist/task-stream-BK7JQ27G.js.map +0 -1
- package/dist/terminal-C_rmkaku.js.map +0 -1
- package/dist/tools-BpCJgMez.js.map +0 -1
- package/dist/wizard-abort-CzwID162.js +0 -49
- package/dist/wizard-abort-CzwID162.js.map +0 -1
- package/dist/wizard-session-Bn6dO1gE.js.map +0 -1
- package/dist/yara-hooks-BrisBebM.js.map +0 -1
- package/dist/yara-hooks-D2B7Fd9G.js +0 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { s as logToFile } from "./debug-
|
|
2
|
-
import { n as analytics } from "./analytics-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { s as logToFile } from "./debug-BsHD83Vy.js";
|
|
2
|
+
import { n as analytics } from "./analytics-CtIYzkK4.js";
|
|
3
|
+
import { h as isThinkingLevel } from "./queue-tools-BC9HxOV6.js";
|
|
4
|
+
import { I as fetchWithRetry, T as WIZARD_TOOL_NAMES } from "./agent-interface-tM_b0l__.js";
|
|
5
5
|
//#region src/lib/agent/agent-prompt-loader.ts
|
|
6
6
|
function projectContext(ctx) {
|
|
7
7
|
return `You have access to the PostHog MCP server and the wizard tools.
|
|
@@ -312,4 +312,4 @@ const EMPTY_PROMPT = {};
|
|
|
312
312
|
//#endregion
|
|
313
313
|
export { assembleTaskPrompt as a, queueTools as c, taskModelSpec as d, assembleSeedPrompt as i, renderToolInventory as l, agentRunTools as n, loadAgentRegistry as o, allowsPostHogMcp as r, promptModelFor as s, ASK_TOOL as t, resolveTask as u };
|
|
314
314
|
|
|
315
|
-
//# sourceMappingURL=agent-prompt-loader-
|
|
315
|
+
//# sourceMappingURL=agent-prompt-loader-BSMh5bfD.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-prompt-loader-D3w6sc34.js","names":[],"sources":["../src/lib/agent/agent-prompt-loader.ts"],"sourcesContent":["/**\n * Agent-prompt loader + registry.\n *\n * Agent prompts are the WHAT of a task: a markdown file per type, served from\n * context-mill as the `agents` content type (parallel to skills). The frontmatter\n * carries the artifacts the executor needs — model, the mini-skills to load (the\n * HOW), the tools the task may use, and its dependencies — and the body is the\n * instruction the agent reads.\n *\n * The registry is fetched once at startup and scoped to one flow — agents\n * declare `flow` and (for the planner) `seed: true` in frontmatter, so each\n * program (integration, audit, migration, ...) ships its own agent set and the\n * loader stays generic. Every prompt is downloaded and parsed up front, so\n * resolving a task to its run config is synchronous and adds no mid-drain\n * network latency. The registry's type list also drives `enqueue_task`\n * validation.\n */\nimport type {\n QueueStore,\n QueuedTask,\n} from './runner/sequence/orchestrator/queue';\nimport type { ResolvedTask } from './runner/sequence/orchestrator/executor';\nimport type { HostResolution } from '@lib/host-resolution';\nimport {\n isThinkingLevel,\n type ThinkingLevel,\n} from './runner/switchboard/models';\nimport { logToFile } from '@utils/debug';\nimport { analytics } from '@utils/analytics';\nimport { fetchWithRetry } from '@lib/fetch-retry';\nimport { WIZARD_TOOL_NAMES } from '@lib/wizard-tools/tools';\n\n/**\n * The basics the client injects around every agent-prompt body. The `/agents/`\n * files carry intent only (goal, success criteria); the wizard owns the I/O\n * contract — who the agent is, how it reports, how it surfaces progress — so the\n * authored prompts never restate it.\n */\nexport interface OrchestratorPromptContext {\n projectId: number;\n projectApiKey: string;\n host: HostResolution;\n /** Path to the framework's reference implementation (EXAMPLE.md), if available. */\n examplePath?: string;\n /** Path to the framework's rules (COMMANDMENTS.md), if available. */\n commandmentsPath?: string;\n}\n\nfunction projectContext(ctx: OrchestratorPromptContext): string {\n // Both hosts, distinctly labelled: `apiHost` is the ingestion/API origin the\n // SDK talks to, `appHost` the user-facing web app. A task that hands the user\n // a link (e.g. the data-warehouse new-source fallback) must build it from the\n // app host — the ingestion host does not serve those pages.\n return `You have access to the PostHog MCP server and the wizard tools.\n\nProject context:\n- PostHog Project ID: ${ctx.projectId}\n- PostHog public token: ${ctx.projectApiKey}\n- PostHog Host: ${ctx.host.apiHost}\n- PostHog app URL (base for any link you show the user in a browser): ${ctx.host.appHost}`;\n}\n\n/** Points the agent at the framework's reference integration to learn patterns from. */\nfunction exampleReference(ctx: OrchestratorPromptContext): string | null {\n if (!ctx.examplePath) return null;\n return `A reference PostHog integration for this framework is at \\`${ctx.examplePath}\\`. It shows the target implementation pattern. Reference its patterns and conventions, adapting them to this codebase.`;\n}\n\n/** The framework's rules ship with the reference skill; every task follows them. */\nfunction commandmentsReference(ctx: OrchestratorPromptContext): string | null {\n if (!ctx.commandmentsPath) return null;\n return `Framework rules for this integration are at \\`${ctx.commandmentsPath}\\`. Read them before you edit and follow them.`;\n}\n\n/**\n * The task's own tool list, injected so an agent never has to discover a tool's\n * absence by trying it — and never reports that absence as a finding. Later\n * tasks hold tools this one does not, so work it cannot do is handed on rather\n * than attempted.\n */\n/** Renders the inventory from the tool names a harness actually registered for\n * the run — the one complete list, in the vocabulary the agent will call. */\nexport function renderToolInventory(toolNames: readonly string[]): string {\n if (toolNames.length === 0) return '';\n return `Your tools for this task: ${toolNames.join(\n ', ',\n )}. Do not look for a tool that is not listed or treat its absence as a problem to report. Later tasks in this run hold tools you do not: when your task needs one, hand that work off in your handoff for the task that can do it, or note it for the final report.`;\n}\n\nconst TASK_BASICS = `You are one step in a larger PostHog workflow made of several tasks, run as a fresh agent with no memory of the other tasks beyond the context you are given. Other tasks — before and after you — own the rest of the work, so stay strictly on your own task: do not do a neighbouring step's job, redo what an upstream handoff already did, or reach beyond what you were asked. Do only your task, then report exactly once by calling complete_task with a structured handoff: what your goal was, what you did, and what the next agent should know. When you are given context from previous steps, trust it — those agents already did their work, so do not re-verify or re-read what their handoffs tell you. Build on it and move fast. Read a file before you edit it, so your own changes do not duplicate what is already there. Work only inside this project's own directory: never read, list, or search (find, ls, grep, glob) outside it — not the OS, not other projects, not global package caches. If your task seems to need something outside this directory, it does not — skip that part and say so in your handoff rather than hunting across the filesystem. If your task does not apply to this project — there is genuinely nothing for it to do — report it with status \\`not needed\\` and say why, rather than marking it done.`;\n\nconst SEED_BASICS = `You are the orchestrator. Plan the work and seed the queue with enqueue_task — each call returns an id you can pass as a dependency to a later task. Give each task a short label for the UI — the action in a few words, not file names, class names, or other specifics. The last task you queue, the one that reports on the run, must depend on every other task in the queue — directly, or through a task it already depends on. You are not a task yourself: do not call complete_task and do not edit the project.`;\n\n/**\n * Tasks the wizard queued before the planner ran. It has to see them: they are\n * part of the run it is planning around, and the task that reports last has to\n * depend on them. Their ids are real, so it can wire the edge directly.\n *\n * The one-way rule matters as much as the sink edge. These tasks are deferred to\n * the end of the drain after planning (`seeded-deps.ts`) and may block on a\n * person, so a task the planner hangs off one would wait on the user too — which\n * is the interruption deferring them removed. The resolver drops such a task\n * from the seeded task's own dependencies to stay acyclic, so the damage is\n * silent; saying so here is what prevents it.\n */\nfunction preQueuedTasks(\n tasks: readonly { id: string; type: string }[],\n): string | null {\n if (tasks.length === 0) return null;\n const lines = tasks.map((t) => `- ${t.type} (id: ${t.id})`);\n return `The queue already holds these tasks, placed by the wizard from what it found in this project. Do not queue them again. They run late — after every task you queue — and one may stop to ask the user for input, so make the reporting task depend on each one and hang nothing else off them: any other task you made depend on one would end up waiting on a person.\\n${lines.join(\n '\\n',\n )}`;\n}\n\n/**\n * Points the agent at its installed task instructions (the HOW). They live under\n * the wizard's run dir, not `.claude/skills/`, so the SDK does not auto-load\n * them — the prompt has to name them.\n */\nfunction skillReference(paths: readonly string[]): string | null {\n if (paths.length === 0) return null;\n const list = paths.map((p) => `\\`${p}\\``).join(', ');\n return `Your task instructions are at ${list}. Read them before you start and follow them. They are wizard scaffolding, not part of the project.`;\n}\n\n/** A task agent's full prompt: injected basics, then the authored intent. */\nexport function assembleTaskPrompt(\n ctx: OrchestratorPromptContext,\n body: string,\n skillPaths: readonly string[] = [],\n): string {\n return [\n projectContext(ctx),\n exampleReference(ctx),\n commandmentsReference(ctx),\n skillReference(skillPaths),\n TASK_BASICS,\n body,\n ]\n .filter(Boolean)\n .join('\\n\\n');\n}\n\n/** The seed agent's full prompt: injected basics, then the authored intent. */\nexport function assembleSeedPrompt(\n ctx: OrchestratorPromptContext,\n body: string,\n preQueued: readonly { id: string; type: string }[] = [],\n): string {\n return [projectContext(ctx), SEED_BASICS, preQueuedTasks(preQueued), body]\n .filter(Boolean)\n .join('\\n\\n');\n}\n\n/** Orchestrator tools are MCP tools under the `posthog-wizard` server. Frontmatter\n * names them short (e.g. `enqueue_task`); the SDK gates on the full name. */\nconst ORCHESTRATOR_TOOL_PREFIX = 'mcp__posthog-wizard__';\nconst ORCHESTRATOR_TOOLS = new Set([\n 'enqueue_task',\n 'complete_task',\n 'read_handoffs',\n]);\n\n/** The one tool that stops a task until a person answers. Named short in frontmatter. */\nexport const ASK_TOOL = 'wizard_ask';\n\n/** The skill-menu tools, as agents ask for them in frontmatter. */\nconst SKILL_MENU_TOOL = 'load_skill_menu';\nconst INSTALL_SKILL_TOOL = 'install_skill';\n\n/**\n * The PostHog MCP, as an agent asks for it in frontmatter. Every tool a task\n * gets is granted by its own prompt, this one included: a task that never names\n * it never has the server wired in, and one that does gets it under this name\n * on both harnesses.\n */\nexport const POSTHOG_MCP_TOOL = 'posthog_exec';\n/** The same tool as the anthropic SDK names it, on the hosted PostHog server. */\nconst POSTHOG_MCP_SDK_TOOL = 'mcp__posthog-wizard__exec';\n\n/** Whether a task asked for the PostHog MCP — accepts either spelling. */\nexport function allowsPostHogMcp(\n allowedTools: readonly string[] | undefined,\n): boolean {\n return (allowedTools ?? []).some(\n (name) => name === POSTHOG_MCP_TOOL || name === POSTHOG_MCP_SDK_TOOL,\n );\n}\n\n/** The queue tools a task holds — all of them minus its disallows. Short names.\n * Single source for both the injected inventory and the harness's tool grant. */\nexport function queueTools(disallowedTools: readonly string[]): string[] {\n const disallowed = new Set(\n disallowedTools.map((n) => n.replace(ORCHESTRATOR_TOOL_PREFIX, '')),\n );\n return [...ORCHESTRATOR_TOOLS].filter((t) => !disallowed.has(t));\n}\n\n/** A parsed agent prompt. The frontmatter fields plus the markdown body. */\nexport interface AgentPrompt {\n type: string;\n /** Human-readable title for the TUI; falls back to `type` when absent. */\n label?: string;\n /** The flow this agent belongs to (the program id, e.g. \\`posthog-integration\\`). */\n flow?: string;\n /** Marks the flow's planner: it seeds the queue and is not an enqueueable task. */\n seed: boolean;\n /** Marks a task that runs last: it must depend on every other task in the queue. */\n sink: boolean;\n /**\n * Marks a task only the wizard may queue. The planner never sees the type, so\n * whether it runs is a decision the client makes from what it detected, not\n * one an agent can reach — it can neither invent the task nor forget it.\n */\n runnerSeeded: boolean;\n /** Per-profile model + effort. `pi` = the gpt/pi harness, `sdk` = the anthropic\n * harness. The mapping is not 1:1 across providers, so each agent names both. */\n modelPi?: string;\n effortPi?: ThinkingLevel;\n modelSdk?: string;\n effortSdk?: ThinkingLevel;\n skills: string[];\n allowedTools: string[];\n disallowedTools: string[];\n /**\n * Task types this one runs after. Read differently by the two kinds of task:\n *\n * - **Enqueueable types**: advisory. The planner authors the real graph with\n * `enqueue_task`, passing ids, and its seed prompt describes the shape it\n * should build. Nothing resolves this field for them.\n * - **`runnerSeeded` types**: authoritative. Such a task is queued before the\n * planner runs, so it cannot name ids; the runner resolves these types to\n * the ids the planner produced and applies them (see `seeded-deps.ts`).\n * Empty means \"after everything that is not the sink\".\n */\n dependsOn: string[];\n body: string;\n}\n\n/** The model + effort an agent runs on for a given harness — `pi` picks the gpt\n * column, anything else the sdk (anthropic) column. */\nexport function promptModelFor(\n prompt: AgentPrompt,\n harness: string,\n): { model?: string; effort?: ThinkingLevel } {\n const pi = harness === 'pi';\n return {\n model: pi ? prompt.modelPi : prompt.modelSdk,\n effort: pi ? prompt.effortPi : prompt.effortSdk,\n };\n}\n\nexport interface AgentRegistry {\n /** The flow's task types — every prompt except the seed. */\n readonly types: string[];\n /** The types an agent may enqueue: `types` minus the runner-seeded ones. */\n readonly enqueueableTypes: string[];\n /** The types that run last and must depend on the whole queue. */\n readonly sinkTypes: string[];\n /** The types only the wizard queues, from what it detected before the run. */\n readonly runnerSeededTypes: string[];\n /** The flow's planner, the one prompt marked `seed: true` in its frontmatter. */\n readonly seed?: AgentPrompt;\n get(type: string): AgentPrompt | undefined;\n}\n\n/** The registry for one flow's prompts. Pure; the loader feeds it the fetched set. */\nexport function buildRegistry(\n prompts: readonly AgentPrompt[],\n flow: string,\n opts?: {\n exclude?: readonly string[];\n /** Per-stage pi model/effort overlays, keyed by task type ('seed' for the planner). Applied here — the one place prompts enter the wizard — so every downstream read sees the effective spec. */\n overrides?: Record<\n string,\n { model?: string; effort?: ThinkingLevel } | undefined\n >;\n },\n): AgentRegistry {\n // The harness can exclude task types (CI excludes dashboards). An excluded\n // type does not exist for the run: the seed cannot enqueue it and no agent\n // is ever spun up for it.\n const excluded = new Set(opts?.exclude ?? []);\n const inFlow = prompts\n .filter((p) => p.flow === flow && !excluded.has(p.type))\n .map((p) => {\n const o = opts?.overrides?.[p.seed ? 'seed' : p.type];\n if (!o) return p;\n return {\n ...p,\n modelPi: o.model ?? p.modelPi,\n effortPi: o.effort ?? p.effortPi,\n };\n });\n const byType = new Map(inFlow.map((p) => [p.type, p]));\n const tasks = inFlow.filter((p) => !p.seed);\n return {\n types: tasks.map((p) => p.type),\n enqueueableTypes: tasks.filter((p) => !p.runnerSeeded).map((p) => p.type),\n sinkTypes: tasks.filter((p) => p.sink).map((p) => p.type),\n runnerSeededTypes: tasks.filter((p) => p.runnerSeeded).map((p) => p.type),\n seed: inFlow.find((p) => p.seed),\n get: (type) => byType.get(type),\n };\n}\n\ninterface AgentMenu {\n /** `flow` arrived with context-mill's flow-scoped agents folder; older menus omit it. */\n agents: { id: string; flow?: string; downloadUrl: string }[];\n}\n\n/** A native tool passes through; an MCP tool gets its fully-qualified name. */\nfunction expandToolName(name: string): string {\n if (name === ASK_TOOL) return WIZARD_TOOL_NAMES.wizardAsk;\n if (name === SKILL_MENU_TOOL) return WIZARD_TOOL_NAMES.loadSkillMenu;\n if (name === INSTALL_SKILL_TOOL) return WIZARD_TOOL_NAMES.installSkill;\n if (name === POSTHOG_MCP_TOOL) return POSTHOG_MCP_SDK_TOOL;\n return ORCHESTRATOR_TOOLS.has(name)\n ? `${ORCHESTRATOR_TOOL_PREFIX}${name}`\n : name;\n}\n\n/** A prompt's allow/disallow lists with orchestrator tool names MCP-qualified. */\nexport function agentRunTools(prompt: AgentPrompt): {\n allowedTools: string[];\n disallowedTools: string[];\n} {\n return {\n allowedTools: prompt.allowedTools.map(expandToolName),\n disallowedTools: prompt.disallowedTools.map(expandToolName),\n };\n}\n\nfunction toStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.filter((v): v is string => typeof v === 'string');\n}\n\n/**\n * Parse the leading `---` frontmatter block and the markdown body. The\n * frontmatter is a small, known schema (scalars and inline `[a, b]` arrays), so\n * a tiny parser covers it without a YAML dependency. Inline `# comments` after a\n * value are stripped. `fallbackType` (the menu id) and `fallbackFlow` (the\n * menu entry's flow) apply when the frontmatter omits `type:`/`flow:`.\n */\nexport function parseAgentPrompt(\n text: string,\n fallbackType: string,\n fallbackFlow?: string,\n): AgentPrompt {\n const match = text.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n?([\\s\\S]*)$/);\n const frontmatter = match ? match[1] : '';\n const body = (match ? match[2] : text).trim();\n\n const fields: Record<string, unknown> = {};\n for (const rawLine of frontmatter.split(/\\r?\\n/)) {\n const line = rawLine.replace(/\\s+#.*$/, '').trim();\n if (!line || line.startsWith('#')) continue;\n const kv = line.match(/^([\\w-]+):\\s*(.*)$/);\n if (!kv) continue;\n const [, key, raw] = kv;\n if (raw.startsWith('[') && raw.endsWith(']')) {\n fields[key] = raw\n .slice(1, -1)\n .split(',')\n .map((s) => s.trim().replace(/^['\"]|['\"]$/g, ''))\n .filter(Boolean);\n } else {\n fields[key] = raw.replace(/^['\"]|['\"]$/g, '');\n }\n }\n\n const str = (v: unknown) => (typeof v === 'string' ? v : undefined);\n // Effort is remote data — reject typos here so downstream carries ThinkingLevel.\n const effort = (v: unknown, key: string): ThinkingLevel | undefined => {\n if (v === undefined) return undefined;\n if (isThinkingLevel(v)) return v;\n logToFile(\n `[agent-prompt] ${fallbackType}: ignoring invalid ${key} \"${String(v)}\"`,\n );\n analytics.wizardCapture('agent prompt invalid effort', {\n task_type: fallbackType,\n key,\n value: String(v),\n });\n return undefined;\n };\n return {\n type: typeof fields.type === 'string' ? fields.type : fallbackType,\n label: typeof fields.label === 'string' ? fields.label : undefined,\n flow: typeof fields.flow === 'string' ? fields.flow : fallbackFlow,\n seed: fields.seed === 'true',\n sink: fields.sink === 'true',\n runnerSeeded: fields.runnerSeeded === 'true',\n modelPi: str(fields.model_pi),\n effortPi: effort(fields.effort_pi, 'effort_pi'),\n modelSdk: str(fields.model_sdk),\n effortSdk: effort(fields.effort_sdk, 'effort_sdk'),\n skills: toStringArray(fields.skills),\n allowedTools: toStringArray(fields.allowedTools),\n disallowedTools: toStringArray(fields.disallowedTools),\n dependsOn: toStringArray(fields.dependsOn),\n body,\n };\n}\n\nasync function fetchText(url: string): Promise<string> {\n const res = await fetchWithRetry(url);\n return res.text();\n}\n\n/**\n * Fetch the agent menu and every agent prompt it lists, parse them, and build\n * the registry for one flow. Throws if the menu cannot be fetched — the\n * orchestrator cannot run without its prompts.\n */\nexport async function loadAgentRegistry(\n skillsBaseUrl: string,\n flow: string,\n opts?: Parameters<typeof buildRegistry>[2],\n): Promise<AgentRegistry> {\n const menuRaw = await fetchText(`${skillsBaseUrl}/agent-menu.json`);\n const menu = JSON.parse(menuRaw) as AgentMenu;\n\n // Menus that carry a flow per entry let us skip other flows' prompts before\n // fetching them; entries without one are fetched and filtered by their\n // frontmatter in buildRegistry, as before.\n const entries = (menu.agents ?? []).filter(\n (entry) => !entry.flow || entry.flow === flow,\n );\n const prompts = await Promise.all(\n entries.map(async (entry) => {\n const text = await fetchText(entry.downloadUrl);\n return parseAgentPrompt(text, entry.id, entry.flow);\n }),\n );\n\n return buildRegistry(prompts, flow, opts);\n}\n\n/**\n * Render a task's own inputs into a section, so a fanned-out task (e.g. one\n * `capture` per event) sees the specific thing it owns. Empty when there are none.\n */\nfunction renderInputs(task: QueuedTask): string {\n const entries = Object.entries(task.inputs ?? {});\n if (entries.length === 0) return '';\n const lines = entries.map(([k, v]) => `- ${k}: ${formatInputValue(v)}`);\n return `## Your task input\\n\\n${lines.join('\\n')}`;\n}\n\nfunction formatInputValue(value: unknown): string {\n if (typeof value === 'string') return value;\n return JSON.stringify(value);\n}\n\n/**\n * The ids of every task `task` transitively depends on — the full upstream\n * chain, not just direct dependencies — ordered roots-first, each once. A `seen`\n * set dedupes diamonds and guards against cycles.\n */\nfunction ancestorIds(task: QueuedTask, store: QueueStore): string[] {\n const seen = new Set<string>();\n const ordered: string[] = [];\n const visit = (id: string): void => {\n if (seen.has(id)) return;\n seen.add(id);\n const t = store.get(id);\n if (!t) return;\n for (const dep of t.dependsOn) visit(dep); // ancestors before dependents\n ordered.push(id);\n };\n for (const dep of task.dependsOn) visit(dep);\n return ordered;\n}\n\n/**\n * Render the handoffs of every step `task` transitively depends on into a context\n * section, so a fresh agent sees the whole upstream chain — not just its direct\n * dependencies. Reliability over token economy: a step must never have to\n * re-discover what any ancestor already established just because an intermediate\n * handoff happened to omit it. Empty when there are no completed ancestors.\n */\nfunction renderHandoffContext(task: QueuedTask, store: QueueStore): string {\n const lines: string[] = [];\n for (const id of ancestorIds(task, store)) {\n const dep = store.get(id);\n const handoff = store.readHandoff(id);\n if (!dep || !handoff) continue;\n lines.push(`### ${dep.type}`);\n lines.push(`- did: ${handoff.did}`);\n lines.push(`- for you: ${handoff.forNextAgent}`);\n if (handoff.filesTouched?.length) {\n lines.push(`- files: ${handoff.filesTouched.join(', ')}`);\n }\n if (handoff.evidence) {\n lines.push(`- evidence: ${handoff.evidence}`);\n }\n if (handoff.assumptions) {\n lines.push(`- assumed: ${handoff.assumptions}`);\n }\n if (handoff.reportSection) {\n lines.push(`- report section:\\n${handoff.reportSection}`);\n }\n lines.push('');\n }\n if (lines.length === 0) return '';\n return `## Context from previous steps\\n\\n${lines.join('\\n')}`.trim();\n}\n\n/**\n * Resolve a queued task to its run config: the prompt body (with upstream\n * handoffs appended), the model, and the tool lists with orchestrator tool names\n * MCP-qualified. The model precedence is enqueue override, then prompt, then\n * default. Throws if no prompt is registered for the task's type.\n */\nexport function resolveTask(\n registry: AgentRegistry,\n task: QueuedTask,\n store: QueueStore,\n): ResolvedTask {\n const prompt = registry.get(task.type);\n if (!prompt) {\n throw new Error(`No agent prompt registered for task type \"${task.type}\"`);\n }\n\n const body = [\n renderInputs(task),\n prompt.body,\n renderHandoffContext(task, store),\n ]\n .filter(Boolean)\n .join('\\n\\n');\n\n return {\n ...agentRunTools(prompt),\n prompt: body,\n skills: prompt.skills,\n };\n}\n\n/** The model + effort a task runs on for a harness: enqueue override, then the\n * prompt's per-profile frontmatter; the caller's switchboard pick is the fallback. */\nexport function taskModelSpec(\n registry: AgentRegistry,\n task: QueuedTask,\n harness: string,\n): { model?: string; effort?: ThinkingLevel } {\n const picked = promptModelFor(\n registry.get(task.type) ?? EMPTY_PROMPT,\n harness,\n );\n return {\n model: task.model ?? picked.model,\n effort: picked.effort,\n };\n}\n\nconst EMPTY_PROMPT = {} as AgentPrompt;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"agent-prompt-loader-BSMh5bfD.js","names":[],"sources":["../src/lib/agent/agent-prompt-loader.ts"],"sourcesContent":["/**\n * Agent-prompt loader + registry.\n *\n * Agent prompts are the WHAT of a task: a markdown file per type, served from\n * context-mill as the `agents` content type (parallel to skills). The frontmatter\n * carries the artifacts the executor needs — model, the mini-skills to load (the\n * HOW), the tools the task may use, and its dependencies — and the body is the\n * instruction the agent reads.\n *\n * The registry is fetched once at startup and scoped to one flow — agents\n * declare `flow` and (for the planner) `seed: true` in frontmatter, so each\n * program (integration, audit, migration, ...) ships its own agent set and the\n * loader stays generic. Every prompt is downloaded and parsed up front, so\n * resolving a task to its run config is synchronous and adds no mid-drain\n * network latency. The registry's type list also drives `enqueue_task`\n * validation.\n */\nimport type {\n QueueStore,\n QueuedTask,\n} from './runner/sequence/orchestrator/queue';\nimport type { ResolvedTask } from './runner/sequence/orchestrator/executor';\nimport type { HostResolution } from '@lib/host-resolution';\nimport {\n isThinkingLevel,\n type ThinkingLevel,\n} from './runner/switchboard/models';\nimport { logToFile } from '@utils/debug';\nimport { analytics } from '@utils/analytics';\nimport { fetchWithRetry } from '@lib/fetch-retry';\nimport { WIZARD_TOOL_NAMES } from '@lib/wizard-tools/tools';\n\n/**\n * The basics the client injects around every agent-prompt body. The `/agents/`\n * files carry intent only (goal, success criteria); the wizard owns the I/O\n * contract — who the agent is, how it reports, how it surfaces progress — so the\n * authored prompts never restate it.\n */\nexport interface OrchestratorPromptContext {\n projectId: number;\n projectApiKey: string;\n host: HostResolution;\n /** Path to the framework's reference implementation (EXAMPLE.md), if available. */\n examplePath?: string;\n /** Path to the framework's rules (COMMANDMENTS.md), if available. */\n commandmentsPath?: string;\n}\n\nfunction projectContext(ctx: OrchestratorPromptContext): string {\n // Both hosts, distinctly labelled: `apiHost` is the ingestion/API origin the\n // SDK talks to, `appHost` the user-facing web app. A task that hands the user\n // a link (e.g. the data-warehouse new-source fallback) must build it from the\n // app host — the ingestion host does not serve those pages.\n return `You have access to the PostHog MCP server and the wizard tools.\n\nProject context:\n- PostHog Project ID: ${ctx.projectId}\n- PostHog public token: ${ctx.projectApiKey}\n- PostHog Host: ${ctx.host.apiHost}\n- PostHog app URL (base for any link you show the user in a browser): ${ctx.host.appHost}`;\n}\n\n/** Points the agent at the framework's reference integration to learn patterns from. */\nfunction exampleReference(ctx: OrchestratorPromptContext): string | null {\n if (!ctx.examplePath) return null;\n return `A reference PostHog integration for this framework is at \\`${ctx.examplePath}\\`. It shows the target implementation pattern. Reference its patterns and conventions, adapting them to this codebase.`;\n}\n\n/** The framework's rules ship with the reference skill; every task follows them. */\nfunction commandmentsReference(ctx: OrchestratorPromptContext): string | null {\n if (!ctx.commandmentsPath) return null;\n return `Framework rules for this integration are at \\`${ctx.commandmentsPath}\\`. Read them before you edit and follow them.`;\n}\n\n/**\n * The task's own tool list, injected so an agent never has to discover a tool's\n * absence by trying it — and never reports that absence as a finding. Later\n * tasks hold tools this one does not, so work it cannot do is handed on rather\n * than attempted.\n */\n/** Renders the inventory from the tool names a harness actually registered for\n * the run — the one complete list, in the vocabulary the agent will call. */\nexport function renderToolInventory(toolNames: readonly string[]): string {\n if (toolNames.length === 0) return '';\n return `Your tools for this task: ${toolNames.join(\n ', ',\n )}. Do not look for a tool that is not listed or treat its absence as a problem to report. Later tasks in this run hold tools you do not: when your task needs one, hand that work off in your handoff for the task that can do it, or note it for the final report.`;\n}\n\nconst TASK_BASICS = `You are one step in a larger PostHog workflow made of several tasks, run as a fresh agent with no memory of the other tasks beyond the context you are given. Other tasks — before and after you — own the rest of the work, so stay strictly on your own task: do not do a neighbouring step's job, redo what an upstream handoff already did, or reach beyond what you were asked. Do only your task, then report exactly once by calling complete_task with a structured handoff: what your goal was, what you did, and what the next agent should know. When you are given context from previous steps, trust it — those agents already did their work, so do not re-verify or re-read what their handoffs tell you. Build on it and move fast. Read a file before you edit it, so your own changes do not duplicate what is already there. Work only inside this project's own directory: never read, list, or search (find, ls, grep, glob) outside it — not the OS, not other projects, not global package caches. If your task seems to need something outside this directory, it does not — skip that part and say so in your handoff rather than hunting across the filesystem. If your task does not apply to this project — there is genuinely nothing for it to do — report it with status \\`not needed\\` and say why, rather than marking it done.`;\n\nconst SEED_BASICS = `You are the orchestrator. Plan the work and seed the queue with enqueue_task — each call returns an id you can pass as a dependency to a later task. Give each task a short label for the UI — the action in a few words, not file names, class names, or other specifics. The last task you queue, the one that reports on the run, must depend on every other task in the queue — directly, or through a task it already depends on. You are not a task yourself: do not call complete_task and do not edit the project.`;\n\n/**\n * Tasks the wizard queued before the planner ran. It has to see them: they are\n * part of the run it is planning around, and the task that reports last has to\n * depend on them. Their ids are real, so it can wire the edge directly.\n *\n * The one-way rule matters as much as the sink edge. These tasks are deferred to\n * the end of the drain after planning (`seeded-deps.ts`) and may block on a\n * person, so a task the planner hangs off one would wait on the user too — which\n * is the interruption deferring them removed. The resolver drops such a task\n * from the seeded task's own dependencies to stay acyclic, so the damage is\n * silent; saying so here is what prevents it.\n */\nfunction preQueuedTasks(\n tasks: readonly { id: string; type: string }[],\n): string | null {\n if (tasks.length === 0) return null;\n const lines = tasks.map((t) => `- ${t.type} (id: ${t.id})`);\n return `The queue already holds these tasks, placed by the wizard from what it found in this project. Do not queue them again. They run late — after every task you queue — and one may stop to ask the user for input, so make the reporting task depend on each one and hang nothing else off them: any other task you made depend on one would end up waiting on a person.\\n${lines.join(\n '\\n',\n )}`;\n}\n\n/**\n * Points the agent at its installed task instructions (the HOW). They live under\n * the wizard's run dir, not `.claude/skills/`, so the SDK does not auto-load\n * them — the prompt has to name them.\n */\nfunction skillReference(paths: readonly string[]): string | null {\n if (paths.length === 0) return null;\n const list = paths.map((p) => `\\`${p}\\``).join(', ');\n return `Your task instructions are at ${list}. Read them before you start and follow them. They are wizard scaffolding, not part of the project.`;\n}\n\n/** A task agent's full prompt: injected basics, then the authored intent. */\nexport function assembleTaskPrompt(\n ctx: OrchestratorPromptContext,\n body: string,\n skillPaths: readonly string[] = [],\n): string {\n return [\n projectContext(ctx),\n exampleReference(ctx),\n commandmentsReference(ctx),\n skillReference(skillPaths),\n TASK_BASICS,\n body,\n ]\n .filter(Boolean)\n .join('\\n\\n');\n}\n\n/** The seed agent's full prompt: injected basics, then the authored intent. */\nexport function assembleSeedPrompt(\n ctx: OrchestratorPromptContext,\n body: string,\n preQueued: readonly { id: string; type: string }[] = [],\n): string {\n return [projectContext(ctx), SEED_BASICS, preQueuedTasks(preQueued), body]\n .filter(Boolean)\n .join('\\n\\n');\n}\n\n/** Orchestrator tools are MCP tools under the `posthog-wizard` server. Frontmatter\n * names them short (e.g. `enqueue_task`); the SDK gates on the full name. */\nconst ORCHESTRATOR_TOOL_PREFIX = 'mcp__posthog-wizard__';\nconst ORCHESTRATOR_TOOLS = new Set([\n 'enqueue_task',\n 'complete_task',\n 'read_handoffs',\n]);\n\n/** The one tool that stops a task until a person answers. Named short in frontmatter. */\nexport const ASK_TOOL = 'wizard_ask';\n\n/** The skill-menu tools, as agents ask for them in frontmatter. */\nconst SKILL_MENU_TOOL = 'load_skill_menu';\nconst INSTALL_SKILL_TOOL = 'install_skill';\n\n/**\n * The PostHog MCP, as an agent asks for it in frontmatter. Every tool a task\n * gets is granted by its own prompt, this one included: a task that never names\n * it never has the server wired in, and one that does gets it under this name\n * on both harnesses.\n */\nexport const POSTHOG_MCP_TOOL = 'posthog_exec';\n/** The same tool as the anthropic SDK names it, on the hosted PostHog server. */\nconst POSTHOG_MCP_SDK_TOOL = 'mcp__posthog-wizard__exec';\n\n/** Whether a task asked for the PostHog MCP — accepts either spelling. */\nexport function allowsPostHogMcp(\n allowedTools: readonly string[] | undefined,\n): boolean {\n return (allowedTools ?? []).some(\n (name) => name === POSTHOG_MCP_TOOL || name === POSTHOG_MCP_SDK_TOOL,\n );\n}\n\n/** The queue tools a task holds — all of them minus its disallows. Short names.\n * Single source for both the injected inventory and the harness's tool grant. */\nexport function queueTools(disallowedTools: readonly string[]): string[] {\n const disallowed = new Set(\n disallowedTools.map((n) => n.replace(ORCHESTRATOR_TOOL_PREFIX, '')),\n );\n return [...ORCHESTRATOR_TOOLS].filter((t) => !disallowed.has(t));\n}\n\n/** A parsed agent prompt. The frontmatter fields plus the markdown body. */\nexport interface AgentPrompt {\n type: string;\n /** Human-readable title for the TUI; falls back to `type` when absent. */\n label?: string;\n /** The flow this agent belongs to (the program id, e.g. \\`posthog-integration\\`). */\n flow?: string;\n /** Marks the flow's planner: it seeds the queue and is not an enqueueable task. */\n seed: boolean;\n /** Marks a task that runs last: it must depend on every other task in the queue. */\n sink: boolean;\n /**\n * Marks a task only the wizard may queue. The planner never sees the type, so\n * whether it runs is a decision the client makes from what it detected, not\n * one an agent can reach — it can neither invent the task nor forget it.\n */\n runnerSeeded: boolean;\n /** Per-profile model + effort. `pi` = the gpt/pi harness, `sdk` = the anthropic\n * harness. The mapping is not 1:1 across providers, so each agent names both. */\n modelPi?: string;\n effortPi?: ThinkingLevel;\n modelSdk?: string;\n effortSdk?: ThinkingLevel;\n skills: string[];\n allowedTools: string[];\n disallowedTools: string[];\n /**\n * Task types this one runs after. Read differently by the two kinds of task:\n *\n * - **Enqueueable types**: advisory. The planner authors the real graph with\n * `enqueue_task`, passing ids, and its seed prompt describes the shape it\n * should build. Nothing resolves this field for them.\n * - **`runnerSeeded` types**: authoritative. Such a task is queued before the\n * planner runs, so it cannot name ids; the runner resolves these types to\n * the ids the planner produced and applies them (see `seeded-deps.ts`).\n * Empty means \"after everything that is not the sink\".\n */\n dependsOn: string[];\n body: string;\n}\n\n/** The model + effort an agent runs on for a given harness — `pi` picks the gpt\n * column, anything else the sdk (anthropic) column. */\nexport function promptModelFor(\n prompt: AgentPrompt,\n harness: string,\n): { model?: string; effort?: ThinkingLevel } {\n const pi = harness === 'pi';\n return {\n model: pi ? prompt.modelPi : prompt.modelSdk,\n effort: pi ? prompt.effortPi : prompt.effortSdk,\n };\n}\n\nexport interface AgentRegistry {\n /** The flow's task types — every prompt except the seed. */\n readonly types: string[];\n /** The types an agent may enqueue: `types` minus the runner-seeded ones. */\n readonly enqueueableTypes: string[];\n /** The types that run last and must depend on the whole queue. */\n readonly sinkTypes: string[];\n /** The types only the wizard queues, from what it detected before the run. */\n readonly runnerSeededTypes: string[];\n /** The flow's planner, the one prompt marked `seed: true` in its frontmatter. */\n readonly seed?: AgentPrompt;\n get(type: string): AgentPrompt | undefined;\n}\n\n/** The registry for one flow's prompts. Pure; the loader feeds it the fetched set. */\nexport function buildRegistry(\n prompts: readonly AgentPrompt[],\n flow: string,\n opts?: {\n exclude?: readonly string[];\n /** Per-stage pi model/effort overlays, keyed by task type ('seed' for the planner). Applied here — the one place prompts enter the wizard — so every downstream read sees the effective spec. */\n overrides?: Record<\n string,\n { model?: string; effort?: ThinkingLevel } | undefined\n >;\n },\n): AgentRegistry {\n // The harness can exclude task types (CI excludes dashboards). An excluded\n // type does not exist for the run: the seed cannot enqueue it and no agent\n // is ever spun up for it.\n const excluded = new Set(opts?.exclude ?? []);\n const inFlow = prompts\n .filter((p) => p.flow === flow && !excluded.has(p.type))\n .map((p) => {\n const o = opts?.overrides?.[p.seed ? 'seed' : p.type];\n if (!o) return p;\n return {\n ...p,\n modelPi: o.model ?? p.modelPi,\n effortPi: o.effort ?? p.effortPi,\n };\n });\n const byType = new Map(inFlow.map((p) => [p.type, p]));\n const tasks = inFlow.filter((p) => !p.seed);\n return {\n types: tasks.map((p) => p.type),\n enqueueableTypes: tasks.filter((p) => !p.runnerSeeded).map((p) => p.type),\n sinkTypes: tasks.filter((p) => p.sink).map((p) => p.type),\n runnerSeededTypes: tasks.filter((p) => p.runnerSeeded).map((p) => p.type),\n seed: inFlow.find((p) => p.seed),\n get: (type) => byType.get(type),\n };\n}\n\ninterface AgentMenu {\n /** `flow` arrived with context-mill's flow-scoped agents folder; older menus omit it. */\n agents: { id: string; flow?: string; downloadUrl: string }[];\n}\n\n/** A native tool passes through; an MCP tool gets its fully-qualified name. */\nfunction expandToolName(name: string): string {\n if (name === ASK_TOOL) return WIZARD_TOOL_NAMES.wizardAsk;\n if (name === SKILL_MENU_TOOL) return WIZARD_TOOL_NAMES.loadSkillMenu;\n if (name === INSTALL_SKILL_TOOL) return WIZARD_TOOL_NAMES.installSkill;\n if (name === POSTHOG_MCP_TOOL) return POSTHOG_MCP_SDK_TOOL;\n return ORCHESTRATOR_TOOLS.has(name)\n ? `${ORCHESTRATOR_TOOL_PREFIX}${name}`\n : name;\n}\n\n/** A prompt's allow/disallow lists with orchestrator tool names MCP-qualified. */\nexport function agentRunTools(prompt: AgentPrompt): {\n allowedTools: string[];\n disallowedTools: string[];\n} {\n return {\n allowedTools: prompt.allowedTools.map(expandToolName),\n disallowedTools: prompt.disallowedTools.map(expandToolName),\n };\n}\n\nfunction toStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.filter((v): v is string => typeof v === 'string');\n}\n\n/**\n * Parse the leading `---` frontmatter block and the markdown body. The\n * frontmatter is a small, known schema (scalars and inline `[a, b]` arrays), so\n * a tiny parser covers it without a YAML dependency. Inline `# comments` after a\n * value are stripped. `fallbackType` (the menu id) and `fallbackFlow` (the\n * menu entry's flow) apply when the frontmatter omits `type:`/`flow:`.\n */\nexport function parseAgentPrompt(\n text: string,\n fallbackType: string,\n fallbackFlow?: string,\n): AgentPrompt {\n const match = text.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n?([\\s\\S]*)$/);\n const frontmatter = match ? match[1] : '';\n const body = (match ? match[2] : text).trim();\n\n const fields: Record<string, unknown> = {};\n for (const rawLine of frontmatter.split(/\\r?\\n/)) {\n const line = rawLine.replace(/\\s+#.*$/, '').trim();\n if (!line || line.startsWith('#')) continue;\n const kv = line.match(/^([\\w-]+):\\s*(.*)$/);\n if (!kv) continue;\n const [, key, raw] = kv;\n if (raw.startsWith('[') && raw.endsWith(']')) {\n fields[key] = raw\n .slice(1, -1)\n .split(',')\n .map((s) => s.trim().replace(/^['\"]|['\"]$/g, ''))\n .filter(Boolean);\n } else {\n fields[key] = raw.replace(/^['\"]|['\"]$/g, '');\n }\n }\n\n const str = (v: unknown) => (typeof v === 'string' ? v : undefined);\n // Effort is remote data — reject typos here so downstream carries ThinkingLevel.\n const effort = (v: unknown, key: string): ThinkingLevel | undefined => {\n if (v === undefined) return undefined;\n if (isThinkingLevel(v)) return v;\n logToFile(\n `[agent-prompt] ${fallbackType}: ignoring invalid ${key} \"${String(v)}\"`,\n );\n analytics.wizardCapture('agent prompt invalid effort', {\n task_type: fallbackType,\n key,\n value: String(v),\n });\n return undefined;\n };\n return {\n type: typeof fields.type === 'string' ? fields.type : fallbackType,\n label: typeof fields.label === 'string' ? fields.label : undefined,\n flow: typeof fields.flow === 'string' ? fields.flow : fallbackFlow,\n seed: fields.seed === 'true',\n sink: fields.sink === 'true',\n runnerSeeded: fields.runnerSeeded === 'true',\n modelPi: str(fields.model_pi),\n effortPi: effort(fields.effort_pi, 'effort_pi'),\n modelSdk: str(fields.model_sdk),\n effortSdk: effort(fields.effort_sdk, 'effort_sdk'),\n skills: toStringArray(fields.skills),\n allowedTools: toStringArray(fields.allowedTools),\n disallowedTools: toStringArray(fields.disallowedTools),\n dependsOn: toStringArray(fields.dependsOn),\n body,\n };\n}\n\nasync function fetchText(url: string): Promise<string> {\n const res = await fetchWithRetry(url);\n return res.text();\n}\n\n/**\n * Fetch the agent menu and every agent prompt it lists, parse them, and build\n * the registry for one flow. Throws if the menu cannot be fetched — the\n * orchestrator cannot run without its prompts.\n */\nexport async function loadAgentRegistry(\n skillsBaseUrl: string,\n flow: string,\n opts?: Parameters<typeof buildRegistry>[2],\n): Promise<AgentRegistry> {\n const menuRaw = await fetchText(`${skillsBaseUrl}/agent-menu.json`);\n const menu = JSON.parse(menuRaw) as AgentMenu;\n\n // Menus that carry a flow per entry let us skip other flows' prompts before\n // fetching them; entries without one are fetched and filtered by their\n // frontmatter in buildRegistry, as before.\n const entries = (menu.agents ?? []).filter(\n (entry) => !entry.flow || entry.flow === flow,\n );\n const prompts = await Promise.all(\n entries.map(async (entry) => {\n const text = await fetchText(entry.downloadUrl);\n return parseAgentPrompt(text, entry.id, entry.flow);\n }),\n );\n\n return buildRegistry(prompts, flow, opts);\n}\n\n/**\n * Render a task's own inputs into a section, so a fanned-out task (e.g. one\n * `capture` per event) sees the specific thing it owns. Empty when there are none.\n */\nfunction renderInputs(task: QueuedTask): string {\n const entries = Object.entries(task.inputs ?? {});\n if (entries.length === 0) return '';\n const lines = entries.map(([k, v]) => `- ${k}: ${formatInputValue(v)}`);\n return `## Your task input\\n\\n${lines.join('\\n')}`;\n}\n\nfunction formatInputValue(value: unknown): string {\n if (typeof value === 'string') return value;\n return JSON.stringify(value);\n}\n\n/**\n * The ids of every task `task` transitively depends on — the full upstream\n * chain, not just direct dependencies — ordered roots-first, each once. A `seen`\n * set dedupes diamonds and guards against cycles.\n */\nfunction ancestorIds(task: QueuedTask, store: QueueStore): string[] {\n const seen = new Set<string>();\n const ordered: string[] = [];\n const visit = (id: string): void => {\n if (seen.has(id)) return;\n seen.add(id);\n const t = store.get(id);\n if (!t) return;\n for (const dep of t.dependsOn) visit(dep); // ancestors before dependents\n ordered.push(id);\n };\n for (const dep of task.dependsOn) visit(dep);\n return ordered;\n}\n\n/**\n * Render the handoffs of every step `task` transitively depends on into a context\n * section, so a fresh agent sees the whole upstream chain — not just its direct\n * dependencies. Reliability over token economy: a step must never have to\n * re-discover what any ancestor already established just because an intermediate\n * handoff happened to omit it. Empty when there are no completed ancestors.\n */\nfunction renderHandoffContext(task: QueuedTask, store: QueueStore): string {\n const lines: string[] = [];\n for (const id of ancestorIds(task, store)) {\n const dep = store.get(id);\n const handoff = store.readHandoff(id);\n if (!dep || !handoff) continue;\n lines.push(`### ${dep.type}`);\n lines.push(`- did: ${handoff.did}`);\n lines.push(`- for you: ${handoff.forNextAgent}`);\n if (handoff.filesTouched?.length) {\n lines.push(`- files: ${handoff.filesTouched.join(', ')}`);\n }\n if (handoff.evidence) {\n lines.push(`- evidence: ${handoff.evidence}`);\n }\n if (handoff.assumptions) {\n lines.push(`- assumed: ${handoff.assumptions}`);\n }\n if (handoff.reportSection) {\n lines.push(`- report section:\\n${handoff.reportSection}`);\n }\n lines.push('');\n }\n if (lines.length === 0) return '';\n return `## Context from previous steps\\n\\n${lines.join('\\n')}`.trim();\n}\n\n/**\n * Resolve a queued task to its run config: the prompt body (with upstream\n * handoffs appended), the model, and the tool lists with orchestrator tool names\n * MCP-qualified. The model precedence is enqueue override, then prompt, then\n * default. Throws if no prompt is registered for the task's type.\n */\nexport function resolveTask(\n registry: AgentRegistry,\n task: QueuedTask,\n store: QueueStore,\n): ResolvedTask {\n const prompt = registry.get(task.type);\n if (!prompt) {\n throw new Error(`No agent prompt registered for task type \"${task.type}\"`);\n }\n\n const body = [\n renderInputs(task),\n prompt.body,\n renderHandoffContext(task, store),\n ]\n .filter(Boolean)\n .join('\\n\\n');\n\n return {\n ...agentRunTools(prompt),\n prompt: body,\n skills: prompt.skills,\n };\n}\n\n/** The model + effort a task runs on for a harness: enqueue override, then the\n * prompt's per-profile frontmatter; the caller's switchboard pick is the fallback. */\nexport function taskModelSpec(\n registry: AgentRegistry,\n task: QueuedTask,\n harness: string,\n): { model?: string; effort?: ThinkingLevel } {\n const picked = promptModelFor(\n registry.get(task.type) ?? EMPTY_PROMPT,\n harness,\n );\n return {\n model: task.model ?? picked.model,\n effort: picked.effort,\n };\n}\n\nconst EMPTY_PROMPT = {} as AgentPrompt;\n"],"mappings":";;;;;AAgDA,SAAS,eAAe,KAAwC;AAK9D,QAAO;;;wBAGe,IAAI,UAAU;0BACZ,IAAI,cAAc;kBAC1B,IAAI,KAAK,QAAQ;wEACqC,IAAI,KAAK;;;AAIjF,SAAS,iBAAiB,KAA+C;AACvE,KAAI,CAAC,IAAI,YAAa,QAAO;AAC7B,QAAO,8DAA8D,IAAI,YAAY;;;AAIvF,SAAS,sBAAsB,KAA+C;AAC5E,KAAI,CAAC,IAAI,iBAAkB,QAAO;AAClC,QAAO,iDAAiD,IAAI,iBAAiB;;;;;;;;;;AAW/E,SAAgB,oBAAoB,WAAsC;AACxE,KAAI,UAAU,WAAW,EAAG,QAAO;AACnC,QAAO,6BAA6B,UAAU,KAC5C,KACD,CAAC;;AAGJ,MAAM,cAAc;AAEpB,MAAM,cAAc;;;;;;;;;;;;;AAcpB,SAAS,eACP,OACe;AACf,KAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,QAAO,0WADO,MAAM,KAAK,MAAM,KAAK,EAAE,KAAK,QAAQ,EAAE,GAAG,GAAG,CAC4T,KACrX,KACD;;;;;;;AAQH,SAAS,eAAe,OAAyC;AAC/D,KAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,QAAO,iCADM,MAAM,KAAK,MAAM,KAAK,EAAE,IAAI,CAAC,KAAK,KAAK,CACP;;;AAI/C,SAAgB,mBACd,KACA,MACA,aAAgC,EAAE,EAC1B;AACR,QAAO;EACL,eAAe,IAAI;EACnB,iBAAiB,IAAI;EACrB,sBAAsB,IAAI;EAC1B,eAAe,WAAW;EAC1B;EACA;EACD,CACE,OAAO,QAAQ,CACf,KAAK,OAAO;;;AAIjB,SAAgB,mBACd,KACA,MACA,YAAqD,EAAE,EAC/C;AACR,QAAO;EAAC,eAAe,IAAI;EAAE;EAAa,eAAe,UAAU;EAAE;EAAK,CACvE,OAAO,QAAQ,CACf,KAAK,OAAO;;;;AAKjB,MAAM,2BAA2B;AACjC,MAAM,qBAAqB,IAAI,IAAI;CACjC;CACA;CACA;CACD,CAAC;;AAGF,MAAa,WAAW;;AAGxB,MAAM,kBAAkB;AACxB,MAAM,qBAAqB;;AAU3B,MAAM,uBAAuB;;AAG7B,SAAgB,iBACd,cACS;AACT,SAAQ,gBAAgB,EAAE,EAAE,MACzB,SAAS,SAAA,kBAA6B,SAAS,qBACjD;;;;AAKH,SAAgB,WAAW,iBAA8C;CACvE,MAAM,aAAa,IAAI,IACrB,gBAAgB,KAAK,MAAM,EAAE,QAAQ,0BAA0B,GAAG,CAAC,CACpE;AACD,QAAO,CAAC,GAAG,mBAAmB,CAAC,QAAQ,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;;;;AA8ClE,SAAgB,eACd,QACA,SAC4C;CAC5C,MAAM,KAAK,YAAY;AACvB,QAAO;EACL,OAAO,KAAK,OAAO,UAAU,OAAO;EACpC,QAAQ,KAAK,OAAO,WAAW,OAAO;EACvC;;;AAkBH,SAAgB,cACd,SACA,MACA,MAQe;CAIf,MAAM,WAAW,IAAI,IAAI,MAAM,WAAW,EAAE,CAAC;CAC7C,MAAM,SAAS,QACZ,QAAQ,MAAM,EAAE,SAAS,QAAQ,CAAC,SAAS,IAAI,EAAE,KAAK,CAAC,CACvD,KAAK,MAAM;EACV,MAAM,IAAI,MAAM,YAAY,EAAE,OAAO,SAAS,EAAE;AAChD,MAAI,CAAC,EAAG,QAAO;AACf,SAAO;GACL,GAAG;GACH,SAAS,EAAE,SAAS,EAAE;GACtB,UAAU,EAAE,UAAU,EAAE;GACzB;GACD;CACJ,MAAM,SAAS,IAAI,IAAI,OAAO,KAAK,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;CACtD,MAAM,QAAQ,OAAO,QAAQ,MAAM,CAAC,EAAE,KAAK;AAC3C,QAAO;EACL,OAAO,MAAM,KAAK,MAAM,EAAE,KAAK;EAC/B,kBAAkB,MAAM,QAAQ,MAAM,CAAC,EAAE,aAAa,CAAC,KAAK,MAAM,EAAE,KAAK;EACzE,WAAW,MAAM,QAAQ,MAAM,EAAE,KAAK,CAAC,KAAK,MAAM,EAAE,KAAK;EACzD,mBAAmB,MAAM,QAAQ,MAAM,EAAE,aAAa,CAAC,KAAK,MAAM,EAAE,KAAK;EACzE,MAAM,OAAO,MAAM,MAAM,EAAE,KAAK;EAChC,MAAM,SAAS,OAAO,IAAI,KAAK;EAChC;;;AASH,SAAS,eAAe,MAAsB;AAC5C,KAAI,SAAA,aAAmB,QAAO,kBAAkB;AAChD,KAAI,SAAS,gBAAiB,QAAO,kBAAkB;AACvD,KAAI,SAAS,mBAAoB,QAAO,kBAAkB;AAC1D,KAAI,SAAA,eAA2B,QAAO;AACtC,QAAO,mBAAmB,IAAI,KAAK,GAC/B,GAAG,2BAA2B,SAC9B;;;AAIN,SAAgB,cAAc,QAG5B;AACA,QAAO;EACL,cAAc,OAAO,aAAa,IAAI,eAAe;EACrD,iBAAiB,OAAO,gBAAgB,IAAI,eAAe;EAC5D;;AAGH,SAAS,cAAc,OAA0B;AAC/C,KAAI,CAAC,MAAM,QAAQ,MAAM,CAAE,QAAO,EAAE;AACpC,QAAO,MAAM,QAAQ,MAAmB,OAAO,MAAM,SAAS;;;;;;;;;AAUhE,SAAgB,iBACd,MACA,cACA,cACa;CACb,MAAM,QAAQ,KAAK,MAAM,8CAA8C;CACvE,MAAM,cAAc,QAAQ,MAAM,KAAK;CACvC,MAAM,QAAQ,QAAQ,MAAM,KAAK,MAAM,MAAM;CAE7C,MAAM,SAAkC,EAAE;AAC1C,MAAK,MAAM,WAAW,YAAY,MAAM,QAAQ,EAAE;EAChD,MAAM,OAAO,QAAQ,QAAQ,WAAW,GAAG,CAAC,MAAM;AAClD,MAAI,CAAC,QAAQ,KAAK,WAAW,IAAI,CAAE;EACnC,MAAM,KAAK,KAAK,MAAM,qBAAqB;AAC3C,MAAI,CAAC,GAAI;EACT,MAAM,GAAG,KAAK,OAAO;AACrB,MAAI,IAAI,WAAW,IAAI,IAAI,IAAI,SAAS,IAAI,CAC1C,QAAO,OAAO,IACX,MAAM,GAAG,GAAG,CACZ,MAAM,IAAI,CACV,KAAK,MAAM,EAAE,MAAM,CAAC,QAAQ,gBAAgB,GAAG,CAAC,CAChD,OAAO,QAAQ;MAElB,QAAO,OAAO,IAAI,QAAQ,gBAAgB,GAAG;;CAIjD,MAAM,OAAO,MAAgB,OAAO,MAAM,WAAW,IAAI,KAAA;CAEzD,MAAM,UAAU,GAAY,QAA2C;AACrE,MAAI,MAAM,KAAA,EAAW,QAAO,KAAA;AAC5B,MAAI,gBAAgB,EAAE,CAAE,QAAO;AAC/B,YACE,kBAAkB,aAAa,qBAAqB,IAAI,IAAI,OAAO,EAAE,CAAC,GACvE;AACD,YAAU,cAAc,+BAA+B;GACrD,WAAW;GACX;GACA,OAAO,OAAO,EAAE;GACjB,CAAC;;AAGJ,QAAO;EACL,MAAM,OAAO,OAAO,SAAS,WAAW,OAAO,OAAO;EACtD,OAAO,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ,KAAA;EACzD,MAAM,OAAO,OAAO,SAAS,WAAW,OAAO,OAAO;EACtD,MAAM,OAAO,SAAS;EACtB,MAAM,OAAO,SAAS;EACtB,cAAc,OAAO,iBAAiB;EACtC,SAAS,IAAI,OAAO,SAAS;EAC7B,UAAU,OAAO,OAAO,WAAW,YAAY;EAC/C,UAAU,IAAI,OAAO,UAAU;EAC/B,WAAW,OAAO,OAAO,YAAY,aAAa;EAClD,QAAQ,cAAc,OAAO,OAAO;EACpC,cAAc,cAAc,OAAO,aAAa;EAChD,iBAAiB,cAAc,OAAO,gBAAgB;EACtD,WAAW,cAAc,OAAO,UAAU;EAC1C;EACD;;AAGH,eAAe,UAAU,KAA8B;AAErD,SADY,MAAM,eAAe,IAAI,EAC1B,MAAM;;;;;;;AAQnB,eAAsB,kBACpB,eACA,MACA,MACwB;CACxB,MAAM,UAAU,MAAM,UAAU,GAAG,cAAc,kBAAkB;CAMnE,MAAM,WALO,KAAK,MAAM,QAAQ,CAKV,UAAU,EAAE,EAAE,QACjC,UAAU,CAAC,MAAM,QAAQ,MAAM,SAAS,KAC1C;AAQD,QAAO,cAPS,MAAM,QAAQ,IAC5B,QAAQ,IAAI,OAAO,UAAU;AAE3B,SAAO,iBADM,MAAM,UAAU,MAAM,YAAY,EACjB,MAAM,IAAI,MAAM,KAAK;GACnD,CACH,EAE6B,MAAM,KAAK;;;;;;AAO3C,SAAS,aAAa,MAA0B;CAC9C,MAAM,UAAU,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;AACjD,KAAI,QAAQ,WAAW,EAAG,QAAO;AAEjC,QAAO,yBADO,QAAQ,KAAK,CAAC,GAAG,OAAO,KAAK,EAAE,IAAI,iBAAiB,EAAE,GAAG,CACjC,KAAK,KAAK;;AAGlD,SAAS,iBAAiB,OAAwB;AAChD,KAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAO,KAAK,UAAU,MAAM;;;;;;;AAQ9B,SAAS,YAAY,MAAkB,OAA6B;CAClE,MAAM,uBAAO,IAAI,KAAa;CAC9B,MAAM,UAAoB,EAAE;CAC5B,MAAM,SAAS,OAAqB;AAClC,MAAI,KAAK,IAAI,GAAG,CAAE;AAClB,OAAK,IAAI,GAAG;EACZ,MAAM,IAAI,MAAM,IAAI,GAAG;AACvB,MAAI,CAAC,EAAG;AACR,OAAK,MAAM,OAAO,EAAE,UAAW,OAAM,IAAI;AACzC,UAAQ,KAAK,GAAG;;AAElB,MAAK,MAAM,OAAO,KAAK,UAAW,OAAM,IAAI;AAC5C,QAAO;;;;;;;;;AAUT,SAAS,qBAAqB,MAAkB,OAA2B;CACzE,MAAM,QAAkB,EAAE;AAC1B,MAAK,MAAM,MAAM,YAAY,MAAM,MAAM,EAAE;EACzC,MAAM,MAAM,MAAM,IAAI,GAAG;EACzB,MAAM,UAAU,MAAM,YAAY,GAAG;AACrC,MAAI,CAAC,OAAO,CAAC,QAAS;AACtB,QAAM,KAAK,OAAO,IAAI,OAAO;AAC7B,QAAM,KAAK,UAAU,QAAQ,MAAM;AACnC,QAAM,KAAK,cAAc,QAAQ,eAAe;AAChD,MAAI,QAAQ,cAAc,OACxB,OAAM,KAAK,YAAY,QAAQ,aAAa,KAAK,KAAK,GAAG;AAE3D,MAAI,QAAQ,SACV,OAAM,KAAK,eAAe,QAAQ,WAAW;AAE/C,MAAI,QAAQ,YACV,OAAM,KAAK,cAAc,QAAQ,cAAc;AAEjD,MAAI,QAAQ,cACV,OAAM,KAAK,sBAAsB,QAAQ,gBAAgB;AAE3D,QAAM,KAAK,GAAG;;AAEhB,KAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,QAAO,qCAAqC,MAAM,KAAK,KAAK,GAAG,MAAM;;;;;;;;AASvE,SAAgB,YACd,UACA,MACA,OACc;CACd,MAAM,SAAS,SAAS,IAAI,KAAK,KAAK;AACtC,KAAI,CAAC,OACH,OAAM,IAAI,MAAM,6CAA6C,KAAK,KAAK,GAAG;CAG5E,MAAM,OAAO;EACX,aAAa,KAAK;EAClB,OAAO;EACP,qBAAqB,MAAM,MAAM;EAClC,CACE,OAAO,QAAQ,CACf,KAAK,OAAO;AAEf,QAAO;EACL,GAAG,cAAc,OAAO;EACxB,QAAQ;EACR,QAAQ,OAAO;EAChB;;;;AAKH,SAAgB,cACd,UACA,MACA,SAC4C;CAC5C,MAAM,SAAS,eACb,SAAS,IAAI,KAAK,KAAK,IAAI,cAC3B,QACD;AACD,QAAO;EACL,OAAO,KAAK,SAAS,OAAO;EAC5B,QAAQ,OAAO;EAChB;;AAGH,MAAM,eAAe,EAAE"}
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-B_-DWIq7.js";
|
|
2
|
-
import {
|
|
3
|
-
import { a as
|
|
4
|
-
import {
|
|
5
|
-
import "./
|
|
6
|
-
import
|
|
7
|
-
import { n as
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { a as
|
|
12
|
-
import { a as
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
2
|
+
import { a as AgentSignals, i as AGENT_ERROR_CODE, l as ErrorCodes, n as skillErrorCode } from "./errors-BHervYGs.js";
|
|
3
|
+
import { A as GPT5_6_LUNA_MODEL, D as DEFAULT_AGENT_MODEL, F as Harness, M as GPT5_6_TERRA_MODEL, _ as evaluateWizardReadiness, a as getLogFilePath, c as WIZARD_BENCHMARK_FILE, ct as WIZARD_ORCHESTRATOR_OVERRIDE_FLAG_KEY, et as SONNET_5_MODEL, f as getUI, ft as WIZARD_SELF_DRIVING_USE_PI_HARNESS_FLAG_KEY, g as SIGNUP_WIZARD_READINESS_CONFIG, gt as VERSION, h as SERVICE_LABELS, i as enableDebugLogs, j as GPT5_6_SOL_MODEL, l as WIZARD_LOG_FILE, lt as WIZARD_ORCHESTRATOR_SEEDED_TASKS_FLAG_KEY, mt as getSkillsBaseUrl, o as initLogFile, rt as WIZARD_CONTACT_EMAIL, s as logToFile, st as WIZARD_ORCHESTRATOR_FLAG_KEY, t as configureLogFile, tt as Sequence, v as getBlockingServiceKeys, vt as RUN_SURFACE, xt as runtimeEnv } from "./debug-BsHD83Vy.js";
|
|
4
|
+
import { a as ciExcludedTaskTypes, n as analytics, r as groupsFromUser } from "./analytics-CtIYzkK4.js";
|
|
5
|
+
import { c as mcpUrlFor, t as getOrAskForProjectData } from "./setup-utils-D1tv0v_R.js";
|
|
6
|
+
import "./wizard-session-Cex1BiXs.js";
|
|
7
|
+
import { i as wizardAbort, n as registerCleanup, t as WizardError } from "./wizard-abort-CGv3lVxw.js";
|
|
8
|
+
import { n as isNonInteractiveEnvironment } from "./environment-C7CKGIOE.js";
|
|
9
|
+
import { c as uncoveredBySink, d as SkipReason, f as TaskStatus, g as isValidModel, l as QUEUE_DIR_NAME, s as dependencyClosure, u as QueueStore, v as requireKnownModel } from "./queue-tools-BC9HxOV6.js";
|
|
10
|
+
import { A as installSkillById, L as createWizardAskBridge, U as createTriageLLMProvider, c as classifySettingsConflicts, i as runAgent$1, k as fetchSkillMenu, n as buildRunTags, o as backupAndFixClaudeSettings, r as initializeAgent, s as checkAllSettingsConflicts, u as restoreClaudeSettings } from "./agent-interface-tM_b0l__.js";
|
|
11
|
+
import { a as flushScanReport, m as writeScanReport, o as formatScanReport, s as formatYaraAbortMessage } from "./yara-hooks-DZIVzhA6.js";
|
|
12
|
+
import { a as piBackend, s as createAioCapture } from "./pi-RlnYUHdb.js";
|
|
13
|
+
import { a as detectNodePackageManagers } from "./package-manager-CLfc31yf.js";
|
|
14
|
+
import { t as FRAMEWORK_REGISTRY } from "./registry-DCAElOyj.js";
|
|
15
|
+
import { a as assembleTaskPrompt, d as taskModelSpec, i as assembleSeedPrompt, n as agentRunTools, o as loadAgentRegistry, s as promptModelFor, t as ASK_TOOL, u as resolveTask } from "./agent-prompt-loader-BSMh5bfD.js";
|
|
15
16
|
import fs, { cpSync, existsSync, mkdirSync, readdirSync, rmSync, writeFileSync } from "fs";
|
|
16
17
|
import * as path$1 from "path";
|
|
17
18
|
import path from "path";
|
|
@@ -1357,6 +1358,7 @@ function assemblePrompt(runDef, ctx) {
|
|
|
1357
1358
|
//#region src/lib/agent/runner/shared/errors.ts
|
|
1358
1359
|
async function abortOnInstallFailure(integrationLabel, result) {
|
|
1359
1360
|
if (result.kind === "ok") return;
|
|
1361
|
+
const code = skillErrorCode(result) ?? void 0;
|
|
1360
1362
|
await wizardAbort({
|
|
1361
1363
|
message: (() => {
|
|
1362
1364
|
switch (result.kind) {
|
|
@@ -1365,12 +1367,13 @@ async function abortOnInstallFailure(integrationLabel, result) {
|
|
|
1365
1367
|
case "download-failed": return `Failed to install skill: ${result.message}\nPlease try again.`;
|
|
1366
1368
|
}
|
|
1367
1369
|
})(),
|
|
1370
|
+
code,
|
|
1368
1371
|
error: new WizardError(`Skill install failed: ${result.kind}`, {
|
|
1369
1372
|
integration: integrationLabel,
|
|
1370
1373
|
error_type: result.kind,
|
|
1371
1374
|
platform: process.platform,
|
|
1372
1375
|
...result.kind === "download-failed" ? { error_detail: result.message.slice(0, 500) } : {}
|
|
1373
|
-
})
|
|
1376
|
+
}, code)
|
|
1374
1377
|
});
|
|
1375
1378
|
}
|
|
1376
1379
|
//#endregion
|
|
@@ -1444,16 +1447,21 @@ async function runLinearProgram(session, config, programConfig, boot, composed =
|
|
|
1444
1447
|
if (agentResult.error === "WIZARD_ABORT") {
|
|
1445
1448
|
const reason = agentResult.message ?? "";
|
|
1446
1449
|
const matched = config.abortCases?.find((c) => c.match.test(reason));
|
|
1450
|
+
const abortCode = matched?.errorCode ?? ErrorCodes.AgentAbort;
|
|
1447
1451
|
const outroData = matched ? {
|
|
1448
1452
|
kind: "error",
|
|
1449
1453
|
message: matched.message,
|
|
1450
1454
|
body: matched.body,
|
|
1451
|
-
docsUrl: matched.docsUrl
|
|
1455
|
+
docsUrl: matched.docsUrl,
|
|
1456
|
+
errorCode: abortCode,
|
|
1457
|
+
errorDetail: { reason }
|
|
1452
1458
|
} : {
|
|
1453
1459
|
kind: "error",
|
|
1454
1460
|
message: `${config.integrationLabel} aborted`,
|
|
1455
1461
|
body: reason || "The agent aborted the program.",
|
|
1456
|
-
docsUrl: config.docsUrl
|
|
1462
|
+
docsUrl: config.docsUrl,
|
|
1463
|
+
errorCode: abortCode,
|
|
1464
|
+
errorDetail: { reason }
|
|
1457
1465
|
};
|
|
1458
1466
|
analytics.wizardCapture("agent aborted", {
|
|
1459
1467
|
integration: config.integrationLabel,
|
|
@@ -1462,14 +1470,16 @@ async function runLinearProgram(session, config, programConfig, boot, composed =
|
|
|
1462
1470
|
});
|
|
1463
1471
|
await wizardAbort({
|
|
1464
1472
|
outroData,
|
|
1473
|
+
code: abortCode,
|
|
1465
1474
|
error: new WizardError(`Agent aborted: ${reason}`, {
|
|
1466
1475
|
integration: config.integrationLabel,
|
|
1467
1476
|
error_type: "WIZARD_ABORT",
|
|
1468
1477
|
reason
|
|
1469
|
-
})
|
|
1478
|
+
}, abortCode)
|
|
1470
1479
|
});
|
|
1471
1480
|
}
|
|
1472
1481
|
if (agentResult.error === "WIZARD_MCP_MISSING") await wizardAbort({
|
|
1482
|
+
code: AGENT_ERROR_CODE["WIZARD_MCP_MISSING"],
|
|
1473
1483
|
message: `Could not access the PostHog MCP server
|
|
1474
1484
|
|
|
1475
1485
|
The wizard was unable to connect to the PostHog MCP server.
|
|
@@ -1480,9 +1490,10 @@ Please try again, or check the documentation:\n${config.docsUrl}`,
|
|
|
1480
1490
|
integration: config.integrationLabel,
|
|
1481
1491
|
error_type: "WIZARD_MCP_MISSING",
|
|
1482
1492
|
signal: AgentSignals.ERROR_MCP_MISSING
|
|
1483
|
-
})
|
|
1493
|
+
}, AGENT_ERROR_CODE["WIZARD_MCP_MISSING"])
|
|
1484
1494
|
});
|
|
1485
1495
|
if (agentResult.error === "WIZARD_RESOURCE_MISSING") await wizardAbort({
|
|
1496
|
+
code: AGENT_ERROR_CODE["WIZARD_RESOURCE_MISSING"],
|
|
1486
1497
|
message: `Could not access the setup resource
|
|
1487
1498
|
|
|
1488
1499
|
This may indicate a version mismatch or a temporary service issue.
|
|
@@ -1492,14 +1503,15 @@ Please try again, or check the documentation:\n${config.docsUrl}`,
|
|
|
1492
1503
|
integration: config.integrationLabel,
|
|
1493
1504
|
error_type: "WIZARD_RESOURCE_MISSING",
|
|
1494
1505
|
signal: AgentSignals.ERROR_RESOURCE_MISSING
|
|
1495
|
-
})
|
|
1506
|
+
}, AGENT_ERROR_CODE["WIZARD_RESOURCE_MISSING"])
|
|
1496
1507
|
});
|
|
1497
1508
|
if (agentResult.error === "WIZARD_YARA_VIOLATION") await wizardAbort({
|
|
1509
|
+
code: AGENT_ERROR_CODE["WIZARD_YARA_VIOLATION"],
|
|
1498
1510
|
message: formatYaraAbortMessage(),
|
|
1499
1511
|
error: new WizardError("YARA scanner terminated session", {
|
|
1500
1512
|
integration: config.integrationLabel,
|
|
1501
1513
|
error_type: "WIZARD_YARA_VIOLATION"
|
|
1502
|
-
})
|
|
1514
|
+
}, AGENT_ERROR_CODE["WIZARD_YARA_VIOLATION"])
|
|
1503
1515
|
});
|
|
1504
1516
|
if (agentResult.error === "WIZARD_NO_PROGRESS") {
|
|
1505
1517
|
analytics.wizardCapture("agent no progress", {
|
|
@@ -1507,11 +1519,12 @@ Please try again, or check the documentation:\n${config.docsUrl}`,
|
|
|
1507
1519
|
error_type: "WIZARD_NO_PROGRESS"
|
|
1508
1520
|
});
|
|
1509
1521
|
await wizardAbort({
|
|
1522
|
+
code: AGENT_ERROR_CODE["WIZARD_NO_PROGRESS"],
|
|
1510
1523
|
message: "The Wizard exited without changing your project. Please contact the PostHog team with wizard@posthog.com about this error.",
|
|
1511
1524
|
error: new WizardError("Agent made no progress", {
|
|
1512
1525
|
integration: config.integrationLabel,
|
|
1513
1526
|
error_type: "WIZARD_NO_PROGRESS"
|
|
1514
|
-
})
|
|
1527
|
+
}, AGENT_ERROR_CODE["WIZARD_NO_PROGRESS"])
|
|
1515
1528
|
});
|
|
1516
1529
|
}
|
|
1517
1530
|
if (agentResult.error === "WIZARD_INCOMPLETE_TASKS") {
|
|
@@ -1520,11 +1533,12 @@ Please try again, or check the documentation:\n${config.docsUrl}`,
|
|
|
1520
1533
|
error_type: "WIZARD_INCOMPLETE_TASKS"
|
|
1521
1534
|
});
|
|
1522
1535
|
await wizardAbort({
|
|
1536
|
+
code: AGENT_ERROR_CODE["WIZARD_INCOMPLETE_TASKS"],
|
|
1523
1537
|
message: "The Wizard exited without completing its planned tasks. Please contact the PostHog team with wizard@posthog.com about this error.",
|
|
1524
1538
|
error: new WizardError("Agent left planned tasks incomplete", {
|
|
1525
1539
|
integration: config.integrationLabel,
|
|
1526
1540
|
error_type: "WIZARD_INCOMPLETE_TASKS"
|
|
1527
|
-
})
|
|
1541
|
+
}, AGENT_ERROR_CODE["WIZARD_INCOMPLETE_TASKS"])
|
|
1528
1542
|
});
|
|
1529
1543
|
}
|
|
1530
1544
|
if (agentResult.error === "WIZARD_RATE_LIMIT" || agentResult.error === "WIZARD_API_ERROR") {
|
|
@@ -1534,11 +1548,12 @@ Please try again, or check the documentation:\n${config.docsUrl}`,
|
|
|
1534
1548
|
error_message: agentResult.message
|
|
1535
1549
|
});
|
|
1536
1550
|
await wizardAbort({
|
|
1551
|
+
code: AGENT_ERROR_CODE[agentResult.error],
|
|
1537
1552
|
message: `API Error\n\n${agentResult.message || "Unknown error"}\n\nPlease report this to: wizard@posthog.com`,
|
|
1538
1553
|
error: new WizardError(`API error: ${agentResult.message}`, {
|
|
1539
1554
|
integration: config.integrationLabel,
|
|
1540
1555
|
error_type: agentResult.error
|
|
1541
|
-
})
|
|
1556
|
+
}, AGENT_ERROR_CODE[agentResult.error])
|
|
1542
1557
|
});
|
|
1543
1558
|
}
|
|
1544
1559
|
if (config.postRun) await config.postRun(session, credentials);
|
|
@@ -1555,6 +1570,27 @@ Please try again, or check the documentation:\n${config.docsUrl}`,
|
|
|
1555
1570
|
await analytics.shutdown("success");
|
|
1556
1571
|
}
|
|
1557
1572
|
//#endregion
|
|
1573
|
+
//#region src/utils/terminal-bell.ts
|
|
1574
|
+
/**
|
|
1575
|
+
* Ring the terminal bell (BEL, U+0007).
|
|
1576
|
+
*
|
|
1577
|
+
* The orchestrator takes consent for the warehouse step at the top of the run
|
|
1578
|
+
* and asks for the credentials at the end of it, several autonomous minutes
|
|
1579
|
+
* later. The person who agreed is often looking at something else by then. A
|
|
1580
|
+
* bell is the one attention signal a terminal in a background tab can still
|
|
1581
|
+
* deliver, and it costs a user who is watching nothing.
|
|
1582
|
+
*
|
|
1583
|
+
* Written to stderr, not stdout: Ink owns stdout and repaints whole frames, so
|
|
1584
|
+
* a byte written there can land inside one. Silent when stderr is not a TTY —
|
|
1585
|
+
* a pipe or a CI log cannot ring, and the byte would only pollute the capture.
|
|
1586
|
+
*/
|
|
1587
|
+
function ringTerminalBell() {
|
|
1588
|
+
if (!process.stderr.isTTY) return;
|
|
1589
|
+
try {
|
|
1590
|
+
process.stderr.write("\x07");
|
|
1591
|
+
} catch {}
|
|
1592
|
+
}
|
|
1593
|
+
//#endregion
|
|
1558
1594
|
//#region src/lib/agent/runner/sequence/orchestrator/executor.ts
|
|
1559
1595
|
/**
|
|
1560
1596
|
* The executor drains the queue. It starts every runnable task (dependencies
|
|
@@ -1830,9 +1866,15 @@ const TASK_ASK_TIMEOUT_MS = 1200 * 1e3;
|
|
|
1830
1866
|
*
|
|
1831
1867
|
* Much shorter than the ask timeout above, because it is asking for something
|
|
1832
1868
|
* much smaller: one keypress to accept or decline, not "go mint a restricted
|
|
1833
|
-
* Stripe key".
|
|
1834
|
-
*
|
|
1835
|
-
*
|
|
1869
|
+
* Stripe key". It cannot be unbounded either — the notice is a modal, and a run
|
|
1870
|
+
* that stops forever behind one nobody is looking at is worse than one that
|
|
1871
|
+
* takes the safe answer and carries on.
|
|
1872
|
+
*
|
|
1873
|
+
* The offer is made at seed time, seconds into the run, so five minutes is a
|
|
1874
|
+
* generous allowance for a person who is by then still watching the wizard
|
|
1875
|
+
* start. It was not: from 2.63.0 to 2.65.0 the offer was made at the moment the
|
|
1876
|
+
* step became runnable — a median seven minutes in, after every coding task —
|
|
1877
|
+
* and this timeout became the answer for about a quarter of all runs.
|
|
1836
1878
|
*/
|
|
1837
1879
|
const TASK_NOTICE_TIMEOUT_MS = 300 * 1e3;
|
|
1838
1880
|
/**
|
|
@@ -1862,6 +1904,45 @@ async function offerSeededTask(notice, timeoutMs = TASK_NOTICE_TIMEOUT_MS) {
|
|
|
1862
1904
|
if (timer) clearTimeout(timer);
|
|
1863
1905
|
}
|
|
1864
1906
|
}
|
|
1907
|
+
/** Which skip reason a negative {@link SeededConsent} carries onto the event. */
|
|
1908
|
+
function consentSkipReason(consent) {
|
|
1909
|
+
if (consent.errored) return SkipReason.NoticeError;
|
|
1910
|
+
return consent.timedOut ? SkipReason.NoticeTimeout : SkipReason.UserDeclined;
|
|
1911
|
+
}
|
|
1912
|
+
/**
|
|
1913
|
+
* Ask for one seeded task's consent, and record how the answer came about.
|
|
1914
|
+
*
|
|
1915
|
+
* Consent and execution are separate concerns, and this is the consent half.
|
|
1916
|
+
* It runs at seed time — seconds into the run, with the user still watching —
|
|
1917
|
+
* while `seeded-deps.ts` keeps the work itself at the end of the queue. Asking
|
|
1918
|
+
* at the moment of execution instead, as 2.63.0 did, put the question in front
|
|
1919
|
+
* of a user who had long since tabbed away.
|
|
1920
|
+
*
|
|
1921
|
+
* Fails closed. The step this gates goes on to ask for live database and API
|
|
1922
|
+
* credentials, so a question that could not be put to the user is never read as
|
|
1923
|
+
* a yes.
|
|
1924
|
+
*/
|
|
1925
|
+
async function askSeededConsent(type, notice, timeoutMs) {
|
|
1926
|
+
const consent = await offerSeededTask(notice, timeoutMs).then((answer) => ({
|
|
1927
|
+
...answer,
|
|
1928
|
+
errored: false
|
|
1929
|
+
}), (err) => {
|
|
1930
|
+
logToFile(`[orchestrator] notice failed for ${type}, declining: ${String(err)}`);
|
|
1931
|
+
analytics.captureException(err instanceof Error ? err : new Error(String(err)), { step: "orchestrator_task_notice" });
|
|
1932
|
+
return {
|
|
1933
|
+
keep: false,
|
|
1934
|
+
timedOut: false,
|
|
1935
|
+
errored: true
|
|
1936
|
+
};
|
|
1937
|
+
});
|
|
1938
|
+
analytics.wizardCapture("orchestrator task notice answered", {
|
|
1939
|
+
type,
|
|
1940
|
+
kept: consent.keep,
|
|
1941
|
+
timed_out: consent.timedOut,
|
|
1942
|
+
errored: consent.errored
|
|
1943
|
+
});
|
|
1944
|
+
return consent;
|
|
1945
|
+
}
|
|
1865
1946
|
/** Whether a task's prompt lets it ask the user, and so needs the ask bridge. */
|
|
1866
1947
|
function canAsk(prompt) {
|
|
1867
1948
|
return (prompt?.allowedTools ?? []).includes(ASK_TOOL);
|
|
@@ -1966,7 +2047,8 @@ async function runOrchestrator(session, config, programConfig, boot) {
|
|
|
1966
2047
|
metrics.recordTerminal(Date.now());
|
|
1967
2048
|
analytics.wizardCapture("orchestrator task skipped", {
|
|
1968
2049
|
...base,
|
|
1969
|
-
duration_ms: durationMs(task)
|
|
2050
|
+
duration_ms: durationMs(task),
|
|
2051
|
+
reason: task.skipReason
|
|
1970
2052
|
});
|
|
1971
2053
|
break;
|
|
1972
2054
|
case "fail":
|
|
@@ -2010,19 +2092,23 @@ async function runOrchestrator(session, config, programConfig, boot) {
|
|
|
2010
2092
|
framework
|
|
2011
2093
|
});
|
|
2012
2094
|
}
|
|
2013
|
-
if (missingVariants.length > 0)
|
|
2014
|
-
|
|
2095
|
+
if (missingVariants.length > 0) {
|
|
2096
|
+
const docsUrl = framework ? FRAMEWORK_REGISTRY[framework]?.metadata.docsUrl : void 0;
|
|
2097
|
+
await wizardAbort({
|
|
2098
|
+
code: ErrorCodes.AgentOrchestratorSkillVariantMissing,
|
|
2099
|
+
message: `Setup instructions for this project failed to download.
|
|
2015
2100
|
Please try again, or contact wizard@posthog.com.
|
|
2016
2101
|
|
|
2017
2102
|
You can also set up with your agent by downloading the skills here:
|
|
2018
2103
|
https://github.com/PostHog/context-mill/releases
|
|
2019
2104
|
or integrate manually here:
|
|
2020
|
-
${
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2105
|
+
${docsUrl ?? "https://posthog.com/docs"}`,
|
|
2106
|
+
error: new WizardError("Orchestrator preflight: skill variant missing", {
|
|
2107
|
+
missing: missingVariants.join(", "),
|
|
2108
|
+
framework
|
|
2109
|
+
}, ErrorCodes.AgentOrchestratorSkillVariantMissing)
|
|
2110
|
+
});
|
|
2111
|
+
}
|
|
2026
2112
|
const promptContext = {
|
|
2027
2113
|
projectId: boot.credentials.projectId,
|
|
2028
2114
|
projectApiKey: boot.credentials.projectApiKey,
|
|
@@ -2049,7 +2135,7 @@ or integrate manually here:
|
|
|
2049
2135
|
const seedEntries = areSeededTasksEnabled(boot.wizardFlags) ? programConfig.seedTasks?.(session) ?? [] : [];
|
|
2050
2136
|
const seededTypes = [];
|
|
2051
2137
|
const seededTasks = [];
|
|
2052
|
-
const
|
|
2138
|
+
const seededConsent = /* @__PURE__ */ new Map();
|
|
2053
2139
|
for (const seeded of seedEntries) {
|
|
2054
2140
|
if (!registry.runnerSeededTypes.includes(seeded.type)) {
|
|
2055
2141
|
logToFile(`[orchestrator] skipping runner-seeded task "${seeded.type}": not a runner-seeded type in this flow`);
|
|
@@ -2064,10 +2150,10 @@ or integrate manually here:
|
|
|
2064
2150
|
});
|
|
2065
2151
|
seededTypes.push(seeded.type);
|
|
2066
2152
|
seededTasks.push(task);
|
|
2067
|
-
if (seeded.notice)
|
|
2153
|
+
if (seeded.notice) seededConsent.set(task.id, await askSeededConsent(seeded.type, seeded.notice));
|
|
2068
2154
|
logToFile(`[orchestrator] runner-seeded task ${seeded.type}`);
|
|
2069
2155
|
}
|
|
2070
|
-
const askingTypes =
|
|
2156
|
+
const askingTypes = seededTasks.filter((task) => seededConsent.get(task.id)?.keep !== false).map((task) => task.type).filter((type) => canAsk(registry.get(type)));
|
|
2071
2157
|
analytics.setTag("orchestrator_awaits_user", askingTypes.length > 0);
|
|
2072
2158
|
analytics.setTag("orchestrator_runner_seeded_types", seededTypes.join(",") || "none");
|
|
2073
2159
|
if (askingTypes.length > 0) analytics.wizardCapture("orchestrator awaits user", {
|
|
@@ -2078,6 +2164,7 @@ or integrate manually here:
|
|
|
2078
2164
|
getSource: () => session.skillId ?? programConfig.id,
|
|
2079
2165
|
showQuestion: (q) => {
|
|
2080
2166
|
metrics.recordAsk(Date.now());
|
|
2167
|
+
ringTerminalBell();
|
|
2081
2168
|
return getUI().requestQuestion(q);
|
|
2082
2169
|
},
|
|
2083
2170
|
cancelQuestion: () => getUI().cancelPendingQuestion(),
|
|
@@ -2101,6 +2188,7 @@ or integrate manually here:
|
|
|
2101
2188
|
spinnerMessage: "Planning the integration...",
|
|
2102
2189
|
successMessage: "Planned the integration",
|
|
2103
2190
|
additionalFeatureQueue: [],
|
|
2191
|
+
requestRemark: false,
|
|
2104
2192
|
analyticsProperties: {
|
|
2105
2193
|
task_type: "seed",
|
|
2106
2194
|
harness: seedPick.harness
|
|
@@ -2145,47 +2233,31 @@ or integrate manually here:
|
|
|
2145
2233
|
if (unwaited.length > 0) {
|
|
2146
2234
|
analytics.wizardCapture("orchestrator sink invariant violated", { uncovered_types: unwaited.map((t) => t.type) });
|
|
2147
2235
|
await wizardAbort({
|
|
2236
|
+
code: ErrorCodes.AgentOrchestratorSinkInvariant,
|
|
2148
2237
|
message: `The wizard could not plan this setup: the final step would have skipped ${unwaited.map((t) => t.type).join(", ")}.\n\nPlease report this to: ${WIZARD_CONTACT_EMAIL}`,
|
|
2149
2238
|
error: new WizardError("orchestrator sink does not cover the queue", {
|
|
2150
2239
|
uncovered: unwaited.map((t) => `${t.type} (${t.id})`).join(", "),
|
|
2151
2240
|
queue_state: JSON.stringify(store.list())
|
|
2152
|
-
})
|
|
2241
|
+
}, ErrorCodes.AgentOrchestratorSinkInvariant)
|
|
2153
2242
|
});
|
|
2154
2243
|
}
|
|
2155
2244
|
const taskSkillsRoot = path$1.join(QUEUE_DIR_NAME, "skills");
|
|
2156
2245
|
const claudeSkillsDir = path$1.join(session.installDir, ".claude", "skills");
|
|
2157
2246
|
const preexistingSkills = new Set(existsSync(claudeSkillsDir) ? readdirSync(claudeSkillsDir) : []);
|
|
2158
|
-
let noticeGate = Promise.resolve();
|
|
2159
2247
|
const runTask = async (task) => {
|
|
2160
2248
|
renderQueue();
|
|
2161
|
-
const
|
|
2162
|
-
if (
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
keep: false,
|
|
2171
|
-
timedOut: false
|
|
2172
|
-
};
|
|
2173
|
-
});
|
|
2174
|
-
analytics.wizardCapture("orchestrator task notice answered", {
|
|
2175
|
-
type: task.type,
|
|
2176
|
-
kept: keep,
|
|
2177
|
-
timed_out: timedOut
|
|
2249
|
+
const consent = seededConsent.get(task.id);
|
|
2250
|
+
if (consent && !consent.keep) {
|
|
2251
|
+
const reason = consentSkipReason(consent);
|
|
2252
|
+
logToFile(`[orchestrator] runner-seeded ${task.type} skipped: ${reason}`);
|
|
2253
|
+
const declinedByUser = reason === SkipReason.UserDeclined;
|
|
2254
|
+
store.skip(task.id, reason, {
|
|
2255
|
+
goals: labelFor(task),
|
|
2256
|
+
did: declinedByUser ? "Nothing — the user chose to skip this step when offered it." : "Nothing — the step was offered at the start of the run and never accepted.",
|
|
2257
|
+
forNextAgent: declinedByUser ? "This step was offered and declined, so it did no work. Report it as skipped at the user’s request, not as failed." : "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."
|
|
2178
2258
|
});
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
store.skip(task.id, {
|
|
2182
|
-
goals: notice.title,
|
|
2183
|
-
did: timedOut ? "Nothing — the step was offered and the offer timed out with no answer." : "Nothing — the user chose to skip this step when offered it.",
|
|
2184
|
-
forNextAgent: timedOut ? "This step was offered and nobody answered, so it did no work. Report it as not set up, and point the user at how to do it later." : "This step was offered and declined, so it did no work. Report it as skipped at the user’s request, not as failed."
|
|
2185
|
-
});
|
|
2186
|
-
renderQueue();
|
|
2187
|
-
return;
|
|
2188
|
-
}
|
|
2259
|
+
renderQueue();
|
|
2260
|
+
return;
|
|
2189
2261
|
}
|
|
2190
2262
|
try {
|
|
2191
2263
|
const resolved = resolveTask(registry, task, store);
|
|
@@ -2224,6 +2296,7 @@ or integrate manually here:
|
|
|
2224
2296
|
spinnerMessage: "",
|
|
2225
2297
|
successMessage: "",
|
|
2226
2298
|
additionalFeatureQueue: [],
|
|
2299
|
+
requestRemark: false,
|
|
2227
2300
|
analyticsProperties: {
|
|
2228
2301
|
task_type: task.type,
|
|
2229
2302
|
task_id: task.id,
|
|
@@ -2283,15 +2356,17 @@ or integrate manually here:
|
|
|
2283
2356
|
const failedTypes = verdict.requiredFailedTypes.join(", ");
|
|
2284
2357
|
const whatFailed = failedTypes ? `the ${failedTypes} step failed` : `${blocked} steps never ran`;
|
|
2285
2358
|
const missingScopes = boot.credentials.missingScopes ?? [];
|
|
2359
|
+
const message = missingScopes.length > 0 ? `The wizard could not finish setup: ${whatFailed}, and this run was authorized without the following permission${missingScopes.length === 1 ? "" : "s"}: ${missingScopes.join(", ")}.\n\nPlease try again, approving all permissions on the PostHog authorization screen. If it still fails, report it to: ${WIZARD_CONTACT_EMAIL}` : `The wizard was unable to set up PostHog: ${whatFailed}.\n\nPlease report this to: ${WIZARD_CONTACT_EMAIL}`;
|
|
2286
2360
|
await wizardAbort({
|
|
2287
|
-
|
|
2361
|
+
code: ErrorCodes.AgentOrchestratorTasksFailed,
|
|
2362
|
+
message,
|
|
2288
2363
|
error: new WizardError("orchestrator drain ended with failed tasks", {
|
|
2289
2364
|
tasks_failed: summary.failed,
|
|
2290
2365
|
tasks_blocked: blocked,
|
|
2291
2366
|
failed_types: failedTypes,
|
|
2292
2367
|
missing_oauth_scopes: missingScopes.join(" "),
|
|
2293
2368
|
queue_state: JSON.stringify(store.list())
|
|
2294
|
-
})
|
|
2369
|
+
}, ErrorCodes.AgentOrchestratorTasksFailed)
|
|
2295
2370
|
});
|
|
2296
2371
|
}
|
|
2297
2372
|
const optionalFailedCount = verdict.optionalFailedTypes.length;
|
|
@@ -2517,7 +2592,10 @@ async function bootstrapProgram(session, config, programConfig) {
|
|
|
2517
2592
|
const blockingLabels = getBlockingServiceKeys(readiness.health, readinessConfig).map((k) => `${SERVICE_LABELS[k]} (${readiness.health[k].status})`);
|
|
2518
2593
|
logToFile(`[agent-runner] blocked by: ${blockingLabels.join(", ")}`);
|
|
2519
2594
|
await getUI().showBlockingOutage(readiness);
|
|
2520
|
-
if (!isNonInteractiveEnvironment()) await wizardAbort({
|
|
2595
|
+
if (!isNonInteractiveEnvironment()) await wizardAbort({
|
|
2596
|
+
code: ErrorCodes.EnvServiceOutage,
|
|
2597
|
+
message: "Cannot start — external services are down:\n" + blockingLabels.map((l) => ` - ${l}`).join("\n") + "\n\nPlease try again later."
|
|
2598
|
+
});
|
|
2521
2599
|
} else if (readiness.decision === "yes_with_warnings") getUI().setReadinessWarnings(readiness);
|
|
2522
2600
|
}
|
|
2523
2601
|
const settingsConflicts = checkAllSettingsConflicts(session.installDir);
|
|
@@ -2547,6 +2625,10 @@ async function bootstrapProgram(session, config, programConfig) {
|
|
|
2547
2625
|
unfixable = [...failClosed, ...autoFix];
|
|
2548
2626
|
}
|
|
2549
2627
|
if (unfixable.length > 0) {
|
|
2628
|
+
if (isNonInteractiveEnvironment()) await wizardAbort({
|
|
2629
|
+
code: ErrorCodes.SettingsUnfixableConflict,
|
|
2630
|
+
message: "Cannot start — a Claude settings file redirects the agent away from the PostHog gateway and cannot be neutralized automatically:\n" + unfixable.map((c) => ` - ${c.source} (${c.path}): ${c.keys.join(", ")}`).join("\n") + "\n\nRemove the conflicting keys and re-run the wizard."
|
|
2631
|
+
});
|
|
2550
2632
|
await getUI().showSettingsOverride(unfixable, () => backupAndFixClaudeSettings(session.installDir));
|
|
2551
2633
|
logToFile("[agent-runner] settings override resolved");
|
|
2552
2634
|
}
|
|
@@ -2701,4 +2783,4 @@ var agent_runner_exports = /* @__PURE__ */ __exportAll({ runAgent: () => runAgen
|
|
|
2701
2783
|
//#endregion
|
|
2702
2784
|
export { formatCostUsd as a, computeTokenCostUsd as i, runAgent as n, formatTokenCount as o, shouldDisableAsk as r, authenticate as s, agent_runner_exports as t };
|
|
2703
2785
|
|
|
2704
|
-
//# sourceMappingURL=agent-runner-
|
|
2786
|
+
//# sourceMappingURL=agent-runner-DD65OMkB.js.map
|