@posthog/wizard 2.45.0 → 2.46.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/README.md +5 -1
- package/dist/{add-mcp-server-to-clients-CNzZMSat.js → add-mcp-server-to-clients-Bv2CBSil.js} +53 -6
- package/dist/add-mcp-server-to-clients-Bv2CBSil.js.map +1 -0
- package/dist/{agent-interface-CF7GsdFf.js → agent-interface-B8roB2UP.js} +833 -8
- package/dist/agent-interface-B8roB2UP.js.map +1 -0
- package/dist/{agent-runner-B0LTVFfw.js → agent-runner-CV3qh_2p.js} +204 -48
- package/dist/agent-runner-CV3qh_2p.js.map +1 -0
- package/dist/analytics-D7vUZgzf.js +2 -0
- package/dist/{analytics-DQEuL6qS.js → analytics-k76OWsl0.js} +20 -6
- package/dist/analytics-k76OWsl0.js.map +1 -0
- package/dist/{api-uCMvDII5.js → api-CmIWcW-U.js} +3 -3
- package/dist/{api-uCMvDII5.js.map → api-CmIWcW-U.js.map} +1 -1
- package/dist/bin.js +228 -985
- package/dist/bin.js.map +1 -1
- package/dist/{ci-install-Bow8-f0j.js → ci-install-CNEJxdHf.js} +4 -4
- package/dist/{ci-install-Bow8-f0j.js.map → ci-install-CNEJxdHf.js.map} +1 -1
- package/dist/{commandments-CyB7Icr1.js → commandments-DSNrOeOC.js} +1 -1
- package/dist/{commandments-CyB7Icr1.js.map → commandments-DSNrOeOC.js.map} +1 -1
- package/dist/commandments-qTW7pwaT.js +2 -0
- package/dist/{debug-BixHZmHv.js → debug-BwIo7nwn.js} +1 -1
- package/dist/{debug-DBmxx59Q.js → debug-C9HmIrwx.js} +19 -5
- package/dist/debug-C9HmIrwx.js.map +1 -0
- package/dist/{defaults-8zjNjGGi.js → defaults-CtWMmC8s.js} +1 -1
- package/dist/{defaults-8zjNjGGi.js.map → defaults-CtWMmC8s.js.map} +1 -1
- package/dist/{env-api-key-AcC_tz8G.js → env-api-key-C3LzH8Lr.js} +1 -1
- package/dist/{env-api-key-AcC_tz8G.js.map → env-api-key-C3LzH8Lr.js.map} +1 -1
- package/dist/{environment-kZtkp7eG.js → environment-NJykOp33.js} +3 -3
- package/dist/{environment-kZtkp7eG.js.map → environment-NJykOp33.js.map} +1 -1
- package/dist/{file-utils-BAhYy5vC.js → file-utils-CLMcNIKi.js} +2 -2
- package/dist/{file-utils-BAhYy5vC.js.map → file-utils-CLMcNIKi.js.map} +1 -1
- package/dist/{file-watcher-BL-IRbR7.js → file-watcher-CBDCNQVV.js} +2 -2
- package/dist/{file-watcher-BL-IRbR7.js.map → file-watcher-CBDCNQVV.js.map} +1 -1
- package/dist/{headless-ui-DWmMyhaP.js → headless-ui-B3QKxbz8.js} +2 -2
- package/dist/{headless-ui-DWmMyhaP.js.map → headless-ui-B3QKxbz8.js.map} +1 -1
- package/dist/{interactive-Cyic0bGL.js → interactive-CIJRex02.js} +2 -2
- package/dist/{interactive-Cyic0bGL.js.map → interactive-CIJRex02.js.map} +1 -1
- package/dist/{mcp-prompt-streaming-C227vG1X.js → mcp-prompt-streaming-D6OgW3lC.js} +3 -3
- package/dist/{mcp-prompt-streaming-C227vG1X.js.map → mcp-prompt-streaming-D6OgW3lC.js.map} +1 -1
- package/dist/{mcp-BSGmEWjt.js → mcp-qTjKHqXN.js} +2 -2
- package/dist/{mcp-BSGmEWjt.js.map → mcp-qTjKHqXN.js.map} +1 -1
- package/dist/{non-interactive-DQA9vn9f.js → non-interactive-8Eypq_h-.js} +2 -2
- package/dist/{non-interactive-DQA9vn9f.js.map → non-interactive-8Eypq_h-.js.map} +1 -1
- package/dist/{orchestrator-tools-NuWONNkF.js → orchestrator-tools-DVXOV-kz.js} +3 -3
- package/dist/{orchestrator-tools-NuWONNkF.js.map → orchestrator-tools-DVXOV-kz.js.map} +1 -1
- package/dist/{package-manager-DKtR3xzM.js → package-manager-CAD9Uklp.js} +2 -2
- package/dist/{package-manager-DKtR3xzM.js.map → package-manager-CAD9Uklp.js.map} +1 -1
- package/dist/{pi-DJCln9jJ.js → pi-C9iHv5uG.js} +48 -32
- package/dist/pi-C9iHv5uG.js.map +1 -0
- package/dist/{playground-CbEndzc8.js → playground-C-9Q3ETa.js} +7 -7
- package/dist/{playground-CbEndzc8.js.map → playground-C-9Q3ETa.js.map} +1 -1
- package/dist/{posthog-DFyux4Vw.js → posthog-DZZbziJ1.js} +1 -1
- package/dist/{posthog-DFyux4Vw.js.map → posthog-DZZbziJ1.js.map} +1 -1
- package/dist/{posthog-integration-dmWJZ8mj.js → posthog-integration-Do997QON.js} +2006 -17
- package/dist/posthog-integration-Do997QON.js.map +1 -0
- package/dist/{provisioning-CcxCry5p.js → provisioning-DpqnGk3z.js} +3 -3
- package/dist/{provisioning-CcxCry5p.js.map → provisioning-DpqnGk3z.js.map} +1 -1
- package/dist/{queue-tools-Bw-AANLM.js → queue-tools-CTUgbOU8.js} +2 -2
- package/dist/{queue-tools-Bw-AANLM.js.map → queue-tools-CTUgbOU8.js.map} +1 -1
- package/dist/{registry-D2V88NoC.js → registry-DT58jEYr.js} +4 -4
- package/dist/{registry-D2V88NoC.js.map → registry-DT58jEYr.js.map} +1 -1
- package/dist/{security-DOtBCBvx.js → security-CTigdAWm.js} +10 -8
- package/dist/security-CTigdAWm.js.map +1 -0
- package/dist/{setup-utils-Qp-u6BZk.js → setup-utils-Cb5uACEO.js} +31 -9
- package/dist/setup-utils-Cb5uACEO.js.map +1 -0
- package/dist/{start-tui-DHa_9aiB.js → start-tui-Cwc-PFma.js} +36 -30
- package/dist/start-tui-Cwc-PFma.js.map +1 -0
- package/dist/{steps-D07HUQyE.js → steps-DyEKYM4I.js} +7 -7
- package/dist/{steps-D07HUQyE.js.map → steps-DyEKYM4I.js.map} +1 -1
- package/dist/{store-DSwsITKX.js → store-4sj-vWr5.js} +4 -4
- package/dist/{store-DSwsITKX.js.map → store-4sj-vWr5.js.map} +1 -1
- package/dist/{subagent-Dk4K5MDa.js → subagent-D8_yDgCB.js} +2 -2
- package/dist/{subagent-Dk4K5MDa.js.map → subagent-D8_yDgCB.js.map} +1 -1
- package/dist/{task-CQnV9Qd2.js → task-D8Y8pkzd.js} +12 -13
- package/dist/task-D8Y8pkzd.js.map +1 -0
- package/dist/{task-stream-B7qia9eW.js → task-stream-DQT3vjwS.js} +4 -4
- package/dist/{task-stream-B7qia9eW.js.map → task-stream-DQT3vjwS.js.map} +1 -1
- package/dist/{tasks-C7BQp659.js → tasks-D2WKssA5.js} +2 -2
- package/dist/{tasks-C7BQp659.js.map → tasks-D2WKssA5.js.map} +1 -1
- package/dist/{telemetry-DgahJGSx.js → telemetry-CYr4HgS2.js} +3 -3
- package/dist/{telemetry-DgahJGSx.js.map → telemetry-CYr4HgS2.js.map} +1 -1
- package/dist/{terminal-Bb6tZkf-.js → terminal-1RfyHQC2.js} +12 -12
- package/dist/{terminal-Bb6tZkf-.js.map → terminal-1RfyHQC2.js.map} +1 -1
- package/dist/tools-DQCUOQZX.js +199 -0
- package/dist/tools-DQCUOQZX.js.map +1 -0
- package/dist/{wizard-abort-DpDmuCfA.js → wizard-abort-D_-v1zvS.js} +1 -1
- package/dist/{wizard-abort-BxtdkgI-.js → wizard-abort-FuyIaI_0.js} +3 -3
- package/dist/{wizard-abort-BxtdkgI-.js.map → wizard-abort-FuyIaI_0.js.map} +1 -1
- package/dist/yara-hooks-6gNnPFPo.js +2 -0
- package/dist/{yara-hooks-pw86rZ8y.js → yara-hooks-DdYRRxfH.js} +82 -21
- package/dist/yara-hooks-DdYRRxfH.js.map +1 -0
- package/package.json +1 -1
- package/dist/add-mcp-server-to-clients-CNzZMSat.js.map +0 -1
- package/dist/agent-interface-CF7GsdFf.js.map +0 -1
- package/dist/agent-runner-B0LTVFfw.js.map +0 -1
- package/dist/analytics-DQEuL6qS.js.map +0 -1
- package/dist/analytics-YD3D38z2.js +0 -2
- package/dist/commandments-DguPfCX8.js +0 -2
- package/dist/debug-DBmxx59Q.js.map +0 -1
- package/dist/pi-DJCln9jJ.js.map +0 -1
- package/dist/posthog-integration-dmWJZ8mj.js.map +0 -1
- package/dist/security-DOtBCBvx.js.map +0 -1
- package/dist/setup-utils-Qp-u6BZk.js.map +0 -1
- package/dist/start-tui-DHa_9aiB.js.map +0 -1
- package/dist/task-CQnV9Qd2.js.map +0 -1
- package/dist/tools-BJEvSUWN.js +0 -122
- package/dist/tools-BJEvSUWN.js.map +0 -1
- package/dist/types-BRe_EzTW.js +0 -46
- package/dist/types-BRe_EzTW.js.map +0 -1
- package/dist/wizard-tools-Dg8o2lcH.js +0 -783
- package/dist/wizard-tools-Dg8o2lcH.js.map +0 -1
- package/dist/yara-hooks-CncaWRuC.js +0 -2
- package/dist/yara-hooks-pw86rZ8y.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"task-CQnV9Qd2.js","names":[],"sources":["../src/lib/agent/runner/harness/pi/task.ts"],"sourcesContent":["/**\n * Orchestrator-mode execution on pi: one fresh pi session per unit of work —\n * the seed plan, or one drained task. The linear pipeline's concerns (skill\n * menu, todo panel, event-plan cleanup) stay in `index.ts`; this module builds\n * the leaner per-task session: gateway model, security fence, the task's\n * allowed coding tools, the wizard env tools, and the in-process orchestrator\n * queue tools.\n *\n * The task's `allowedTools` / `disallowedTools` arrive in the wizard's tool\n * vocabulary (`Read`, `Edit`, `Glob`, …, plus MCP-qualified orchestrator names\n * from `agentRunTools`). pi is where they become real: allowed names decide\n * which pi tool definitions get registered at all, and the disallow list is\n * ALSO handed to the security fence, so a name that never got registered stays\n * blocked even if the model hallucinates it.\n *\n * Loaded lazily from `index.ts` (typebox/ESM constraint, same as tools.ts).\n */\n\nimport { getUI } from '@ui';\nimport { logToFile } from '@utils/debug';\nimport { analytics } from '@utils/analytics';\nimport { WIZARD_REMARK_EVENT_NAME, WIZARD_USER_AGENT } from '@lib/constants';\nimport { AgentErrorType } from '@lib/agent/agent-interface';\nimport { REMARK_INSTRUCTION } from '@lib/agent/signals';\nimport { AgentOutputSignals } from '@lib/agent/output-signals';\nimport { TaskStatus } from '../../sequence/orchestrator/queue';\nimport type { OrchestratorToolsContext } from '../../sequence/orchestrator/queue-tools';\nimport type { AgentResult, TaskRunInputs } from '../types';\nimport { buildGatewayProvider, GATEWAY_PROVIDER } from './gateway';\nimport {\n applyOutroMarkers,\n buildScrubbedEnv,\n extractText,\n lastStatusLine,\n withMode,\n} from './index';\n\n/** wizard tool vocabulary → the pi tool definitions it unlocks. */\nconst CODING_TOOL_MAP: Record<string, readonly string[]> = {\n Read: ['read'],\n Edit: ['edit'],\n Write: ['write'],\n Bash: ['bash'],\n Glob: ['find', 'ls'],\n Grep: ['grep'],\n};\n\n/** `mcp__posthog-wizard__enqueue_task` → `enqueue_task`; native names pass through. */\nfunction shortToolName(name: string): string {\n return name.replace(/^mcp__posthog-wizard__/, '');\n}\n\n/**\n * The pi coding tools a task may use. An empty allow list means \"no\n * restriction\" (mirrors the SDK), so every coding tool registers.\n */\nexport function allowedPiCodingTools(\n allowedTools: readonly string[] | undefined,\n): Set<string> {\n const allowed = (allowedTools ?? []).map(shortToolName);\n const names = allowed.length\n ? allowed.flatMap((name) => CODING_TOOL_MAP[name] ?? [])\n : Object.values(CODING_TOOL_MAP).flat();\n return new Set(names);\n}\n\n/**\n * The orchestrator queue tools this agent gets. Everything not disallowed:\n * the seed's frontmatter disallows `complete_task` (it is not a task), a\n * task's disallows `enqueue_task` (the seed owns the graph).\n */\nexport function allowedOrchestratorTools(\n disallowedTools: readonly string[] | undefined,\n): Set<string> {\n const disallowed = new Set((disallowedTools ?? []).map(shortToolName));\n return new Set(\n ['enqueue_task', 'complete_task', 'read_handoffs'].filter(\n (name) => !disallowed.has(name),\n ),\n );\n}\n\n/**\n * The disallow list for the security fence: the wizard-vocabulary names as\n * given (the fence translates pi built-ins to the same vocabulary) plus the\n * short names, so a disallowed orchestrator tool is blocked under the name pi\n * would call it by.\n */\nexport function fenceDisallowList(\n disallowedTools: readonly string[] | undefined,\n): string[] {\n const names = disallowedTools ?? [];\n return [...new Set([...names, ...names.map(shortToolName)])];\n}\n\n/** Nudges when the session returns without the work reaching a terminal state. */\nconst MAX_TASK_NUDGES = 3;\n\nconst TASK_NUDGE =\n 'You have not called complete_task yet. Finish your task now: if the work is done, call complete_task with your handoff; if it cannot be done, call it with status \"failed\" or \"skipped\" and say why.';\n\nconst SEED_NUDGE =\n 'The queue is still empty. Seed it now with enqueue_task calls for the task graph you planned.';\n\n/** Task-mode runtime notes — the harness constraints that survive into task mode. */\nfunction taskRuntimeNotes(opts: {\n bash: boolean;\n posthogMcp: boolean;\n}): string {\n const lines = [\n '## This runtime',\n 'Below are important guidance on the harness constraints you are bound to. Follow them as commandments.',\n '- When you need several INDEPENDENT operations — reading or searching multiple files — issue them as multiple tool calls in a SINGLE turn. They run in parallel and save round-trips. Only sequence calls when one needs a previous call’s output.',\n '- Explore with the `ls`, `find`, and `grep` tools. `read` is for FILES only — reading a directory errors. NEVER inspect files through `bash`.',\n '- If a tool call is blocked, do NOT retry it or a reworded variant — the fence is deterministic. Change approach or note it in your handoff and move on.',\n '- A `[YARA]` block from the security scanner caught a real problem in the edit you just tried (PII in a `capture()`, a hardcoded secret or host URL). Read the block reason and change the CODE to comply — e.g. move PII off the event and onto the person via `identify()`/`$set`. Never write a PostHog URL or token as a literal in source; read them from environment variables.',\n \"- To inspect or change a project's `.env` files use `check_env_keys` and `set_env_values` — a plain `read`, `edit`, or `write` of any `.env*` file is blocked.\",\n '- Status updates are PLAIN TEXT you write in your reply, NOT a tool call. When you begin a new action, put a line starting with the literal marker [STATUS] and a short present-tense phrase in the SAME turn as a tool call. Never send a turn that is ONLY a [STATUS] line — a turn with no tool call ends the run.',\n '- When you are done, call `complete_task` exactly once with your structured handoff, in the same turn as your closing words. Do not stop before calling it.',\n '- Name events in snake_case (e.g. todo_created), never with spaces.',\n ];\n if (opts.bash) {\n lines.push(\n '- `bash` is ONLY for install/build/typecheck/lint/format commands the project itself defines. Run commands BARE and synchronously: no `cd`, no `&`, `&&`, or pipes, no output redirection. Its full output is returned to you.',\n );\n }\n if (opts.posthogMcp) {\n lines.push(\n '- The PostHog dashboard and insight tools are in your tool list directly, named `posthog_<tool>` (e.g. `posthog_dashboard-create`, `posthog_insight-create`). Use the ones present in your tool list; do not guess names.',\n );\n }\n return lines.join('\\n');\n}\n\n/** Whether this unit of work has reached its terminal state. */\nfunction isSettled(ctx: OrchestratorToolsContext): boolean {\n if (!ctx.currentTaskId) {\n // The seed's job is a seeded queue, not a complete_task call.\n return ctx.store.list().length > 0;\n }\n const task = ctx.store.get(ctx.currentTaskId);\n return (\n !!task &&\n (task.status === TaskStatus.Done ||\n task.status === TaskStatus.Failed ||\n task.status === TaskStatus.Skipped)\n );\n}\n\nexport async function runPiTask(inputs: TaskRunInputs): Promise<AgentResult> {\n const {\n session,\n boot,\n prompt,\n spinner,\n model: modelId,\n effort,\n allowedTools,\n disallowedTools,\n orchestrator,\n spinnerMessage,\n successMessage,\n errorMessage,\n requestRemark,\n analyticsProperties,\n } = inputs;\n\n if (spinnerMessage) spinner.start(spinnerMessage);\n\n const startTime = Date.now();\n const signals = new AgentOutputSignals();\n let assistantTurns = 0;\n const runDurations = () => {\n const durationMs = Date.now() - startTime;\n return {\n duration_ms: durationMs,\n duration_seconds: Math.round(durationMs / 1000),\n };\n };\n const captureAborted = () =>\n analytics.wizardCapture('agent aborted', {\n ...runDurations(),\n model: modelId,\n ...analyticsProperties,\n });\n\n try {\n const sdk = await import('@earendil-works/pi-coding-agent');\n const {\n createAgentSession,\n DefaultResourceLoader,\n SessionManager,\n AuthStorage,\n ModelRegistry,\n getAgentDir,\n createLsToolDefinition,\n createFindToolDefinition,\n createGrepToolDefinition,\n createBashToolDefinition,\n createReadToolDefinition,\n createEditToolDefinition,\n createWriteToolDefinition,\n } = sdk;\n\n const { provider, caps, gatewayUrl } = buildGatewayProvider({\n gatewayUrl: boot.credentials.host.gatewayUrl,\n accessToken: boot.credentials.accessToken,\n wizardMetadata: boot.wizardMetadata,\n wizardFlags: boot.wizardFlags,\n modelId,\n // Per-task agents own their effort via the prompt frontmatter (falling back\n // to the model table), not the run-wide wizard-pi-effort flag.\n applyEffortFlag: false,\n effort,\n });\n const registry = ModelRegistry.inMemory(AuthStorage.create());\n registry.registerProvider(GATEWAY_PROVIDER, provider as never);\n const model = registry.find(GATEWAY_PROVIDER, modelId);\n if (!model) {\n return {\n error: AgentErrorType.API_ERROR,\n message: 'pi: gateway model could not be resolved',\n };\n }\n\n // The same fail-closed fence as the linear run, with the task's disallow\n // list layered in (both the wizard-vocabulary and pi-short names).\n const { createSecurityExtension } = await import('./security');\n const security = createSecurityExtension({\n disallowedTools: fenceDisallowList(disallowedTools),\n triageAuth: {\n baseURL: gatewayUrl,\n authToken: boot.credentials.accessToken,\n },\n });\n const { prewarmYaraScanner } = await import('@lib/yara-hooks');\n void prewarmYaraScanner();\n\n // PostHog MCP, best-effort — the dashboard task creates real dashboards\n // through it; every other task simply never calls a posthog_* tool.\n const extensionFactories = [security.factory] as Array<\n (pi: unknown) => void\n >;\n let mcpCleanup: (() => void) | undefined;\n let posthogMcp = false;\n try {\n const { setupPostHogMcp } = await import('./mcp');\n const mcp = await setupPostHogMcp({\n agentDir: getAgentDir(),\n mcpUrl: boot.credentials.host.mcpUrl,\n accessToken: boot.credentials.accessToken,\n userAgent: WIZARD_USER_AGENT,\n });\n extensionFactories.push(mcp.extensionFactory);\n mcpCleanup = mcp.cleanup;\n posthogMcp = true;\n } catch (err) {\n logToFile(`[pi-task] PostHog MCP setup skipped: ${String(err)}`);\n }\n\n const codingTools = allowedPiCodingTools(allowedTools);\n const orchestratorTools = allowedOrchestratorTools(disallowedTools);\n\n const { getWizardCommandments } = await import('@lib/agent/commandments');\n const resourceLoader = new DefaultResourceLoader({\n cwd: session.installDir,\n agentDir: getAgentDir(),\n systemPrompt:\n getWizardCommandments() +\n '\\n' +\n taskRuntimeNotes({ bash: codingTools.has('bash'), posthogMcp }),\n noExtensions: true,\n noSkills: true,\n noContextFiles: true,\n noPromptTemplates: true,\n noThemes: true,\n extensionFactories,\n });\n await resourceLoader.reload();\n\n // The task's coding tools, gated by its allow list. Reads and searches run\n // in parallel; mutating tools stay sequential. Bash subprocesses get the\n // scrubbed env, same as the linear run.\n const dir = session.installDir;\n const codingToolFactories = {\n read: () => withMode(createReadToolDefinition(dir), 'parallel'),\n edit: () => withMode(createEditToolDefinition(dir), 'sequential'),\n write: () => withMode(createWriteToolDefinition(dir), 'sequential'),\n bash: () =>\n withMode(\n createBashToolDefinition(dir, {\n spawnHook: (ctx) => ({ ...ctx, env: buildScrubbedEnv() }),\n }),\n 'sequential',\n ),\n ls: () => withMode(createLsToolDefinition(dir), 'parallel'),\n find: () => withMode(createFindToolDefinition(dir), 'parallel'),\n grep: () => withMode(createGrepToolDefinition(dir), 'parallel'),\n } as const;\n const codingToolDefs = Object.entries(codingToolFactories)\n .filter(([name]) => codingTools.has(name))\n .map(([, make]) => make());\n\n // Wizard env + package-manager tools are always on — their handlers are\n // fenced, and init/build tasks depend on them.\n const { createWizardPiTools } = await import('./tools');\n const wizardTools = createWizardPiTools({\n workingDirectory: dir,\n skillsBaseUrl: boot.skillsBaseUrl,\n }).filter((t) =>\n ['check_env_keys', 'set_env_values', 'detect_package_manager'].includes(\n t.name,\n ),\n );\n\n const { createPiOrchestratorTools } = await import('./orchestrator-tools');\n const queueTools = createPiOrchestratorTools(orchestrator).filter((t) =>\n orchestratorTools.has(t.name),\n );\n\n const { session: agentSession } = await createAgentSession({\n model,\n modelRegistry: registry,\n thinkingLevel: caps.thinkingLevel,\n cwd: dir,\n sessionManager: SessionManager.inMemory(dir),\n resourceLoader,\n noTools: 'builtin',\n customTools: [...codingToolDefs, ...wizardTools, ...queueTools],\n });\n await agentSession.bindExtensions({});\n\n const unsubscribe = agentSession.subscribe((event) => {\n switch (event.type) {\n case 'message_end': {\n // User prompts also emit message_end; only assistant turns count.\n if ((event.message as { role?: string })?.role !== 'assistant') {\n break;\n }\n assistantTurns += 1;\n const assistant = extractText(event.message).trim();\n if (assistant) {\n logToFile(`[pi-task] assistant: ${assistant.slice(0, 1000)}`);\n applyOutroMarkers(assistant);\n const statusText = lastStatusLine(assistant);\n if (statusText) {\n getUI().pushStatus(statusText);\n spinner.message(statusText);\n }\n for (const line of assistant.split('\\n')) signals.push(line);\n }\n break;\n }\n case 'tool_execution_start': {\n const args = JSON.stringify(event.args ?? {}).slice(0, 200);\n logToFile(`[pi-task] → ${event.toolName} ${args}`);\n break;\n }\n case 'tool_execution_end': {\n if (event.isError) {\n logToFile(\n `[pi-task] ✗ ${event.toolName}: ${String(event.result).slice(\n 0,\n 300,\n )}`,\n );\n }\n break;\n }\n default:\n break;\n }\n });\n\n try {\n await agentSession.prompt(prompt);\n\n // pi's prompt() resolves the moment a turn carries no tool call — which\n // an agent mid-plan does emit. While the work has not reached its\n // terminal state (task not reported, seed queue still empty), nudge.\n let nudges = 0;\n while (\n nudges < MAX_TASK_NUDGES &&\n !security.state.criticalViolation &&\n !isSettled(orchestrator)\n ) {\n nudges += 1;\n logToFile(\n `[pi-task] completion guard: not settled, nudge ${nudges}/${MAX_TASK_NUDGES}`,\n );\n await agentSession.prompt(\n orchestrator.currentTaskId ? TASK_NUDGE : SEED_NUDGE,\n );\n }\n\n if (requestRemark && !security.state.criticalViolation) {\n try {\n await agentSession.prompt(REMARK_INSTRUCTION);\n } catch (err) {\n logToFile(`[pi-task] remark request failed: ${String(err)}`);\n }\n }\n } finally {\n unsubscribe();\n mcpCleanup?.();\n }\n\n if (security.state.criticalViolation) {\n spinner.stop('Security violation detected');\n logToFile(\n `[pi-task] terminated: YARA violation (blocked ${security.state.blockedCount} call(s))`,\n );\n captureAborted();\n return { error: AgentErrorType.YARA_VIOLATION };\n }\n\n const remark = signals.remark();\n if (remark) {\n analytics.capture(WIZARD_REMARK_EVENT_NAME, { remark });\n }\n\n const stats = agentSession.getSessionStats();\n const durations = runDurations();\n analytics.wizardCapture('agent completed', {\n ...durations,\n model: modelId,\n num_turns: assistantTurns,\n input_tokens: stats.tokens.input,\n output_tokens: stats.tokens.output,\n cache_creation_input_tokens: stats.tokens.cacheWrite,\n cache_read_input_tokens: stats.tokens.cacheRead,\n ...analyticsProperties,\n });\n // Per-task usage on one parseable line so a run's per-task time and cost are\n // observable from the log, not only from analytics.\n const taskType =\n typeof (analyticsProperties as { task_type?: unknown })?.task_type ===\n 'string'\n ? (analyticsProperties as { task_type: string }).task_type\n : modelId;\n logToFile(\n `[pi-task] usage task=${taskType} model=${modelId} dur=${durations.duration_seconds}s turns=${assistantTurns} in=${stats.tokens.input} out=${stats.tokens.output} cacheR=${stats.tokens.cacheRead} cacheW=${stats.tokens.cacheWrite}`,\n );\n if (successMessage) spinner.stop(successMessage);\n return {};\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n logToFile(`[pi-task] run error: ${message}`);\n if (errorMessage || spinnerMessage) {\n spinner.stop(errorMessage ?? 'Task failed');\n }\n captureAborted();\n const lower = message.toLowerCase();\n if (lower.includes('rate limit') || lower.includes('429')) {\n return { error: AgentErrorType.RATE_LIMIT, message };\n }\n return { error: AgentErrorType.API_ERROR, message };\n }\n}\n"],"mappings":"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"}
|
package/dist/tools-BJEvSUWN.js
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import { s as logToFile } from "./debug-DBmxx59Q.js";
|
|
2
|
-
import { a as installSkillById, c as resolveEnvPath, i as fetchSkillMenu, o as mergeEnvValues, s as parseEnvKeys } from "./wizard-tools-Dg8o2lcH.js";
|
|
3
|
-
import { r as detectNodePackageManagers } from "./package-manager-DKtR3xzM.js";
|
|
4
|
-
import fs from "fs";
|
|
5
|
-
import path from "path";
|
|
6
|
-
import { Type } from "typebox";
|
|
7
|
-
import { defineTool } from "@earendil-works/pi-coding-agent";
|
|
8
|
-
//#region src/lib/agent/runner/harness/pi/tools.ts
|
|
9
|
-
/**
|
|
10
|
-
* Wizard capabilities as pi custom tools (#5). pi does not mount MCP servers,
|
|
11
|
-
* so the tools the wizard prompt depends on — skill discovery/install and
|
|
12
|
-
* fenced `.env` edits — are exposed to pi as native `defineTool` tools backed
|
|
13
|
-
* by the same helpers the claude-agent-sdk path uses (`fetchSkillMenu`,
|
|
14
|
-
* `installSkillById`, `parseEnvKeys`, `mergeEnvValues`). Same tool names as the
|
|
15
|
-
* MCP server so the shared prompt is unchanged.
|
|
16
|
-
*
|
|
17
|
-
* v1 covers the four tools a framework integration needs. `wizard_ask` is
|
|
18
|
-
* interactive-only (disabled in CI) and the secret-vault `secretRef` path is a
|
|
19
|
-
* follow-up — CI passes literal values.
|
|
20
|
-
*/
|
|
21
|
-
function text(s) {
|
|
22
|
-
return {
|
|
23
|
-
content: [{
|
|
24
|
-
type: "text",
|
|
25
|
-
text: s
|
|
26
|
-
}],
|
|
27
|
-
details: {}
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
function createWizardPiTools(ctx) {
|
|
31
|
-
const { workingDirectory, skillsBaseUrl } = ctx;
|
|
32
|
-
const detectPackageManager = ctx.detectPackageManager ?? detectNodePackageManagers;
|
|
33
|
-
let menuPromise;
|
|
34
|
-
const getSkillMenu = () => menuPromise ??= fetchSkillMenu(skillsBaseUrl);
|
|
35
|
-
return [
|
|
36
|
-
defineTool({
|
|
37
|
-
name: "load_skill_menu",
|
|
38
|
-
label: "Load skill menu",
|
|
39
|
-
description: "Load available PostHog skills for a category. Returns skill IDs and names. Call this first, then install_skill with the chosen ID.",
|
|
40
|
-
promptSnippet: "load_skill_menu(category) — list installable PostHog skills",
|
|
41
|
-
parameters: Type.Object({ category: Type.String({ description: "Skill category, e.g. \"integration\"" }) }),
|
|
42
|
-
async execute(_id, args) {
|
|
43
|
-
const menu = await getSkillMenu();
|
|
44
|
-
if (!menu) return text("Error: could not load the skill menu.");
|
|
45
|
-
const skills = menu.categories[args.category] ?? [];
|
|
46
|
-
if (skills.length === 0) return text(`No skills found for category "${args.category}".`);
|
|
47
|
-
logToFile(`[pi] load_skill_menu: ${skills.length} skills`);
|
|
48
|
-
return text(skills.map((s) => `- ${s.id}: ${s.name}`).join("\n"));
|
|
49
|
-
}
|
|
50
|
-
}),
|
|
51
|
-
defineTool({
|
|
52
|
-
name: "install_skill",
|
|
53
|
-
label: "Install skill",
|
|
54
|
-
description: "Download and install a PostHog skill by ID into .claude/skills/<skillId>/. Call load_skill_menu first. Then read the installed SKILL.md and follow it.",
|
|
55
|
-
promptSnippet: "install_skill(skillId) — install a skill, then read its SKILL.md",
|
|
56
|
-
parameters: Type.Object({ skillId: Type.String({ description: "Skill ID from load_skill_menu" }) }),
|
|
57
|
-
async execute(_id, args) {
|
|
58
|
-
const result = await installSkillById(args.skillId, workingDirectory, skillsBaseUrl);
|
|
59
|
-
if (result.kind !== "ok") {
|
|
60
|
-
logToFile(`[pi] install_skill ${args.skillId}: ${result.kind}`);
|
|
61
|
-
return text(`Error installing skill "${args.skillId}": ${result.kind}. Use load_skill_menu to see valid IDs.`);
|
|
62
|
-
}
|
|
63
|
-
logToFile(`[pi] install_skill ${args.skillId} -> ${result.path}`);
|
|
64
|
-
return text(`Installed "${args.skillId}" at ${result.path}. Read ${result.path}/SKILL.md and follow it.`);
|
|
65
|
-
}
|
|
66
|
-
}),
|
|
67
|
-
defineTool({
|
|
68
|
-
name: "check_env_keys",
|
|
69
|
-
label: "Check env keys",
|
|
70
|
-
description: "Check which environment variable keys are present or missing in a .env file. Never reveals values.",
|
|
71
|
-
promptSnippet: "check_env_keys(filePath, keys) — see which .env keys exist",
|
|
72
|
-
parameters: Type.Object({
|
|
73
|
-
filePath: Type.String({ description: "Path to the .env file, relative to the project root" }),
|
|
74
|
-
keys: Type.Array(Type.String(), { description: "Environment variable key names to check" })
|
|
75
|
-
}),
|
|
76
|
-
async execute(_id, args) {
|
|
77
|
-
const resolved = resolveEnvPath(workingDirectory, args.filePath);
|
|
78
|
-
const existing = fs.existsSync(resolved) ? parseEnvKeys(await fs.promises.readFile(resolved, "utf8")) : /* @__PURE__ */ new Set();
|
|
79
|
-
const results = {};
|
|
80
|
-
for (const key of args.keys) results[key] = existing.has(key) ? "present" : "missing";
|
|
81
|
-
return text(JSON.stringify(results, null, 2));
|
|
82
|
-
}
|
|
83
|
-
}),
|
|
84
|
-
defineTool({
|
|
85
|
-
name: "set_env_values",
|
|
86
|
-
label: "Set env values",
|
|
87
|
-
description: "Create or update environment variable keys in a .env file (creates the file if missing). Pass literal string values.",
|
|
88
|
-
promptSnippet: "set_env_values(filePath, values) — write .env keys (never hardcode secrets in source)",
|
|
89
|
-
parameters: Type.Object({
|
|
90
|
-
filePath: Type.String({ description: "Path to the .env file, relative to the project root" }),
|
|
91
|
-
values: Type.Record(Type.String(), Type.String(), { description: "Key → literal value" })
|
|
92
|
-
}),
|
|
93
|
-
async execute(_id, args) {
|
|
94
|
-
const forbidden = Object.keys(args.values).find((k) => k.toUpperCase() === "POSTHOG_KEY");
|
|
95
|
-
if (forbidden) return text(`Error: "${forbidden}" is not a valid PostHog env var name. Use the framework-specific key (e.g. NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN).`);
|
|
96
|
-
const resolved = resolveEnvPath(workingDirectory, args.filePath);
|
|
97
|
-
const merged = mergeEnvValues(fs.existsSync(resolved) ? await fs.promises.readFile(resolved, "utf8") : "", args.values);
|
|
98
|
-
const dir = path.dirname(resolved);
|
|
99
|
-
if (!fs.existsSync(dir)) await fs.promises.mkdir(dir, { recursive: true });
|
|
100
|
-
await fs.promises.writeFile(resolved, merged, "utf8");
|
|
101
|
-
logToFile(`[pi] set_env_values: ${resolved} keys=${Object.keys(args.values).join(",")}`);
|
|
102
|
-
return text(`Wrote ${Object.keys(args.values).length} key(s) to ${args.filePath}.`);
|
|
103
|
-
}
|
|
104
|
-
}),
|
|
105
|
-
defineTool({
|
|
106
|
-
name: "detect_package_manager",
|
|
107
|
-
label: "Detect package manager",
|
|
108
|
-
description: "Detect the project's package manager(s). Returns the name and the install command for each. Call this before installing a dependency, then RUN the returned install command (with the posthog package) via bash — the SDK package must end up in the project manifest, or the app will not build.",
|
|
109
|
-
promptSnippet: "detect_package_manager() — find the PM + install command, then run it via bash to add the SDK",
|
|
110
|
-
parameters: Type.Object({}),
|
|
111
|
-
async execute() {
|
|
112
|
-
const result = await detectPackageManager(workingDirectory);
|
|
113
|
-
logToFile(`[pi] detect_package_manager: ${result.detected.length} detected`);
|
|
114
|
-
return text(JSON.stringify(result, null, 2));
|
|
115
|
-
}
|
|
116
|
-
})
|
|
117
|
-
];
|
|
118
|
-
}
|
|
119
|
-
//#endregion
|
|
120
|
-
export { createWizardPiTools };
|
|
121
|
-
|
|
122
|
-
//# sourceMappingURL=tools-BJEvSUWN.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tools-BJEvSUWN.js","names":[],"sources":["../src/lib/agent/runner/harness/pi/tools.ts"],"sourcesContent":["/**\n * Wizard capabilities as pi custom tools (#5). pi does not mount MCP servers,\n * so the tools the wizard prompt depends on — skill discovery/install and\n * fenced `.env` edits — are exposed to pi as native `defineTool` tools backed\n * by the same helpers the claude-agent-sdk path uses (`fetchSkillMenu`,\n * `installSkillById`, `parseEnvKeys`, `mergeEnvValues`). Same tool names as the\n * MCP server so the shared prompt is unchanged.\n *\n * v1 covers the four tools a framework integration needs. `wizard_ask` is\n * interactive-only (disabled in CI) and the secret-vault `secretRef` path is a\n * follow-up — CI passes literal values.\n */\n\nimport fs from 'fs';\nimport path from 'path';\nimport { Type } from 'typebox';\nimport { defineTool } from '@earendil-works/pi-coding-agent';\nimport type { ToolDefinition } from '@earendil-works/pi-coding-agent';\nimport { logToFile } from '@utils/debug';\nimport {\n fetchSkillMenu,\n installSkillById,\n mergeEnvValues,\n parseEnvKeys,\n resolveEnvPath,\n} from '@lib/wizard-tools';\nimport {\n detectNodePackageManagers,\n type PackageManagerDetector,\n} from '@lib/detection/package-manager';\n\nfunction text(s: string): {\n content: [{ type: 'text'; text: string }];\n details: unknown;\n} {\n return { content: [{ type: 'text', text: s }], details: {} };\n}\n\nexport interface PiToolsContext {\n workingDirectory: string;\n skillsBaseUrl: string;\n /** Framework's package-manager detector. Defaults to Node detection. */\n detectPackageManager?: PackageManagerDetector;\n}\n\nexport function createWizardPiTools(ctx: PiToolsContext): ToolDefinition[] {\n const { workingDirectory, skillsBaseUrl } = ctx;\n const detectPackageManager =\n ctx.detectPackageManager ?? detectNodePackageManagers;\n\n // Fetch the skill menu at most once per run — the agent calls load_skill_menu\n // 2-3× otherwise, each a fresh HTTP round-trip (profiled slowness).\n let menuPromise: ReturnType<typeof fetchSkillMenu> | undefined;\n const getSkillMenu = () => (menuPromise ??= fetchSkillMenu(skillsBaseUrl));\n\n const loadSkillMenu = defineTool({\n name: 'load_skill_menu',\n label: 'Load skill menu',\n description:\n 'Load available PostHog skills for a category. Returns skill IDs and names. Call this first, then install_skill with the chosen ID.',\n promptSnippet:\n 'load_skill_menu(category) — list installable PostHog skills',\n parameters: Type.Object({\n category: Type.String({\n description: 'Skill category, e.g. \"integration\"',\n }),\n }),\n async execute(_id, args) {\n const menu = await getSkillMenu();\n if (!menu) return text('Error: could not load the skill menu.');\n const skills = menu.categories[args.category] ?? [];\n if (skills.length === 0) {\n return text(`No skills found for category \"${args.category}\".`);\n }\n logToFile(`[pi] load_skill_menu: ${skills.length} skills`);\n return text(skills.map((s) => `- ${s.id}: ${s.name}`).join('\\n'));\n },\n });\n\n const installSkill = defineTool({\n name: 'install_skill',\n label: 'Install skill',\n description:\n 'Download and install a PostHog skill by ID into .claude/skills/<skillId>/. Call load_skill_menu first. Then read the installed SKILL.md and follow it.',\n promptSnippet:\n 'install_skill(skillId) — install a skill, then read its SKILL.md',\n parameters: Type.Object({\n skillId: Type.String({ description: 'Skill ID from load_skill_menu' }),\n }),\n async execute(_id, args) {\n const result = await installSkillById(\n args.skillId,\n workingDirectory,\n skillsBaseUrl,\n );\n if (result.kind !== 'ok') {\n logToFile(`[pi] install_skill ${args.skillId}: ${result.kind}`);\n return text(\n `Error installing skill \"${args.skillId}\": ${result.kind}. Use load_skill_menu to see valid IDs.`,\n );\n }\n logToFile(`[pi] install_skill ${args.skillId} -> ${result.path}`);\n return text(\n `Installed \"${args.skillId}\" at ${result.path}. Read ${result.path}/SKILL.md and follow it.`,\n );\n },\n });\n\n const checkEnvKeys = defineTool({\n name: 'check_env_keys',\n label: 'Check env keys',\n description:\n 'Check which environment variable keys are present or missing in a .env file. Never reveals values.',\n promptSnippet: 'check_env_keys(filePath, keys) — see which .env keys exist',\n parameters: Type.Object({\n filePath: Type.String({\n description: 'Path to the .env file, relative to the project root',\n }),\n keys: Type.Array(Type.String(), {\n description: 'Environment variable key names to check',\n }),\n }),\n async execute(_id, args) {\n const resolved = resolveEnvPath(workingDirectory, args.filePath);\n const existing = fs.existsSync(resolved)\n ? parseEnvKeys(await fs.promises.readFile(resolved, 'utf8'))\n : new Set<string>();\n const results: Record<string, 'present' | 'missing'> = {};\n for (const key of args.keys) {\n results[key] = existing.has(key) ? 'present' : 'missing';\n }\n return text(JSON.stringify(results, null, 2));\n },\n });\n\n const setEnvValues = defineTool({\n name: 'set_env_values',\n label: 'Set env values',\n description:\n 'Create or update environment variable keys in a .env file (creates the file if missing). Pass literal string values.',\n promptSnippet:\n 'set_env_values(filePath, values) — write .env keys (never hardcode secrets in source)',\n parameters: Type.Object({\n filePath: Type.String({\n description: 'Path to the .env file, relative to the project root',\n }),\n values: Type.Record(Type.String(), Type.String(), {\n description: 'Key → literal value',\n }),\n }),\n async execute(_id, args) {\n const forbidden = Object.keys(args.values).find(\n (k) => k.toUpperCase() === 'POSTHOG_KEY',\n );\n if (forbidden) {\n return text(\n `Error: \"${forbidden}\" is not a valid PostHog env var name. Use the framework-specific key (e.g. NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN).`,\n );\n }\n const resolved = resolveEnvPath(workingDirectory, args.filePath);\n const existing = fs.existsSync(resolved)\n ? await fs.promises.readFile(resolved, 'utf8')\n : '';\n const merged = mergeEnvValues(existing, args.values);\n const dir = path.dirname(resolved);\n if (!fs.existsSync(dir))\n await fs.promises.mkdir(dir, { recursive: true });\n await fs.promises.writeFile(resolved, merged, 'utf8');\n logToFile(\n `[pi] set_env_values: ${resolved} keys=${Object.keys(args.values).join(\n ',',\n )}`,\n );\n return text(\n `Wrote ${Object.keys(args.values).length} key(s) to ${args.filePath}.`,\n );\n },\n });\n\n const detectPm = defineTool({\n name: 'detect_package_manager',\n label: 'Detect package manager',\n description:\n \"Detect the project's package manager(s). Returns the name and the install command for each. Call this before installing a dependency, then RUN the returned install command (with the posthog package) via bash — the SDK package must end up in the project manifest, or the app will not build.\",\n promptSnippet:\n 'detect_package_manager() — find the PM + install command, then run it via bash to add the SDK',\n parameters: Type.Object({}),\n async execute() {\n const result = await detectPackageManager(workingDirectory);\n logToFile(\n `[pi] detect_package_manager: ${result.detected.length} detected`,\n );\n return text(JSON.stringify(result, null, 2));\n },\n });\n\n return [loadSkillMenu, installSkill, checkEnvKeys, setEnvValues, detectPm];\n}\n"],"mappings":"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"}
|
package/dist/types-BRe_EzTW.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
//#region src/lib/programs/audit/types.ts
|
|
2
|
-
/** Single source of truth for status glyph + color across audit views. */
|
|
3
|
-
const AUDIT_SEVERITY_STYLE = {
|
|
4
|
-
pending: {
|
|
5
|
-
glyph: "◌",
|
|
6
|
-
color: "gray"
|
|
7
|
-
},
|
|
8
|
-
pass: {
|
|
9
|
-
glyph: "✔",
|
|
10
|
-
color: "green"
|
|
11
|
-
},
|
|
12
|
-
error: {
|
|
13
|
-
glyph: "✘",
|
|
14
|
-
color: "red"
|
|
15
|
-
},
|
|
16
|
-
warning: {
|
|
17
|
-
glyph: "⚠",
|
|
18
|
-
color: "yellow"
|
|
19
|
-
},
|
|
20
|
-
suggestion: {
|
|
21
|
-
glyph: "•",
|
|
22
|
-
color: "cyan"
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
const AUDIT_CHECKS_FILE = ".posthog-audit-checks.json";
|
|
26
|
-
const AUDIT_REPORT_FILE = "posthog-audit-report.md";
|
|
27
|
-
const AUDIT_CHECKS_KEY = "auditChecks";
|
|
28
|
-
function getAuditChecks(session) {
|
|
29
|
-
const raw = session.frameworkContext[AUDIT_CHECKS_KEY];
|
|
30
|
-
return Array.isArray(raw) ? raw : [];
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Read the audit checks ledger off disk. Validation lives at write time —
|
|
34
|
-
* every writer (`audit_seed_checks` / `audit_add_checks` / `audit_resolve_checks`
|
|
35
|
-
* MCP tools, `seedAuditLedger`) zod-parses entries before the atomic write,
|
|
36
|
-
* so by the time the file watcher fires we trust the shape and only guard
|
|
37
|
-
* against the file not being a JSON array (corrupted / hand-edited / not yet
|
|
38
|
-
* seeded).
|
|
39
|
-
*/
|
|
40
|
-
function coerceAuditChecks(parsed) {
|
|
41
|
-
return Array.isArray(parsed) ? parsed : [];
|
|
42
|
-
}
|
|
43
|
-
//#endregion
|
|
44
|
-
export { coerceAuditChecks as a, AUDIT_SEVERITY_STYLE as i, AUDIT_CHECKS_KEY as n, getAuditChecks as o, AUDIT_REPORT_FILE as r, AUDIT_CHECKS_FILE as t };
|
|
45
|
-
|
|
46
|
-
//# sourceMappingURL=types-BRe_EzTW.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types-BRe_EzTW.js","names":[],"sources":["../src/lib/programs/audit/types.ts"],"sourcesContent":["import type { WizardSession } from '@lib/wizard-session';\n\nexport type AuditStatus =\n | 'pending'\n | 'pass'\n | 'error'\n | 'warning'\n | 'suggestion';\n\nexport interface AuditCheck {\n id: string;\n area: string;\n label: string;\n status: AuditStatus;\n file?: string;\n details?: string;\n}\n\nexport interface AuditSeverityStyle {\n glyph: string;\n color: string;\n}\n\n/** Single source of truth for status glyph + color across audit views. */\nexport const AUDIT_SEVERITY_STYLE: Record<AuditStatus, AuditSeverityStyle> = {\n pending: { glyph: '◌', color: 'gray' },\n pass: { glyph: '✔', color: 'green' },\n error: { glyph: '✘', color: 'red' },\n warning: { glyph: '⚠', color: 'yellow' },\n suggestion: { glyph: '•', color: 'cyan' },\n};\n\nexport const AUDIT_CHECKS_FILE = '.posthog-audit-checks.json';\nexport const AUDIT_REPORT_FILE = 'posthog-audit-report.md';\nexport const AUDIT_CHECKS_KEY = 'auditChecks';\n\nexport function getAuditChecks(session: WizardSession): AuditCheck[] {\n const raw = session.frameworkContext[AUDIT_CHECKS_KEY];\n return Array.isArray(raw) ? (raw as AuditCheck[]) : [];\n}\n\n/**\n * Read the audit checks ledger off disk. Validation lives at write time —\n * every writer (`audit_seed_checks` / `audit_add_checks` / `audit_resolve_checks`\n * MCP tools, `seedAuditLedger`) zod-parses entries before the atomic write,\n * so by the time the file watcher fires we trust the shape and only guard\n * against the file not being a JSON array (corrupted / hand-edited / not yet\n * seeded).\n */\nexport function coerceAuditChecks(parsed: unknown): AuditCheck[] {\n return Array.isArray(parsed) ? (parsed as AuditCheck[]) : [];\n}\n"],"mappings":";;AAwBA,MAAa,uBAAgE;CAC3E,SAAS;EAAE,OAAO;EAAK,OAAO;EAAQ;CACtC,MAAM;EAAE,OAAO;EAAK,OAAO;EAAS;CACpC,OAAO;EAAE,OAAO;EAAK,OAAO;EAAO;CACnC,SAAS;EAAE,OAAO;EAAK,OAAO;EAAU;CACxC,YAAY;EAAE,OAAO;EAAK,OAAO;EAAQ;CAC1C;AAED,MAAa,oBAAoB;AACjC,MAAa,oBAAoB;AACjC,MAAa,mBAAmB;AAEhC,SAAgB,eAAe,SAAsC;CACnE,MAAM,MAAM,QAAQ,iBAAiB;AACrC,QAAO,MAAM,QAAQ,IAAI,GAAI,MAAuB,EAAE;;;;;;;;;;AAWxD,SAAgB,kBAAkB,QAA+B;AAC/D,QAAO,MAAM,QAAQ,OAAO,GAAI,SAA0B,EAAE"}
|