@posthog/wizard 2.61.0 → 2.62.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-KNIHRN_m.js → add-mcp-server-to-clients-Bzl7_wB3.js} +4 -4
- package/dist/{add-mcp-server-to-clients-KNIHRN_m.js.map → add-mcp-server-to-clients-Bzl7_wB3.js.map} +1 -1
- package/dist/{agent-interface-Bm4ZNGGV.js → agent-interface-C90hyvs1.js} +6 -6
- package/dist/{agent-interface-Bm4ZNGGV.js.map → agent-interface-C90hyvs1.js.map} +1 -1
- package/dist/{agent-prompt-loader-CsHNQXsY.js → agent-prompt-loader-CBj2DWAJ.js} +5 -5
- package/dist/{agent-prompt-loader-CsHNQXsY.js.map → agent-prompt-loader-CBj2DWAJ.js.map} +1 -1
- package/dist/{agent-runner-DLAvB67P.js → agent-runner-DA5YfjOD.js} +43 -20
- package/dist/agent-runner-DA5YfjOD.js.map +1 -0
- package/dist/{analytics-CkIyBHfd.js → analytics-BdKBzz4M.js} +2 -2
- package/dist/{analytics-CkIyBHfd.js.map → analytics-BdKBzz4M.js.map} +1 -1
- package/dist/analytics-CijpxQFN.js +2 -0
- package/dist/{api-XHQTOfIi.js → api-aTkzJ9vG.js} +3 -3
- package/dist/{api-XHQTOfIi.js.map → api-aTkzJ9vG.js.map} +1 -1
- package/dist/bin.js +39 -39
- package/dist/{bounded-fs-B-qlKB0h.js → bounded-fs-BU2L5mjO.js} +3 -3
- package/dist/{bounded-fs-B-qlKB0h.js.map → bounded-fs-BU2L5mjO.js.map} +1 -1
- package/dist/{ci-install-C9BAoO2n.js → ci-install-BnTAUOz8.js} +4 -4
- package/dist/{ci-install-C9BAoO2n.js.map → ci-install-BnTAUOz8.js.map} +1 -1
- package/dist/{debug-8-IIHr5f.js → debug-BTPYy9p7.js} +7 -4
- package/dist/debug-BTPYy9p7.js.map +1 -0
- package/dist/{debug-npp6DzBK.js → debug-D2L-fM_I.js} +1 -1
- package/dist/{environment-BffaZJRI.js → environment-lV2X1gS-.js} +4 -4
- package/dist/{environment-BffaZJRI.js.map → environment-lV2X1gS-.js.map} +1 -1
- package/dist/{file-watcher-BreVxzh0.js → file-watcher-qqQBl5Em.js} +2 -2
- package/dist/{file-watcher-BreVxzh0.js.map → file-watcher-qqQBl5Em.js.map} +1 -1
- package/dist/{headless-ui-Dy_l8hCT.js → headless-ui-TSoOsa3j.js} +2 -2
- package/dist/{headless-ui-Dy_l8hCT.js.map → headless-ui-TSoOsa3j.js.map} +1 -1
- package/dist/{interactive-C9vepji1.js → interactive-DMoXEiKo.js} +2 -2
- package/dist/{interactive-C9vepji1.js.map → interactive-DMoXEiKo.js.map} +1 -1
- package/dist/{mcp-C5Zheplw.js → mcp-Dqu0_QzN.js} +2 -2
- package/dist/{mcp-C5Zheplw.js.map → mcp-Dqu0_QzN.js.map} +1 -1
- package/dist/{mcp-prompt-streaming-DEerU5M3.js → mcp-prompt-streaming-B4cYVDVP.js} +3 -3
- package/dist/{mcp-prompt-streaming-DEerU5M3.js.map → mcp-prompt-streaming-B4cYVDVP.js.map} +1 -1
- package/dist/{non-interactive-C9vQaJF2.js → non-interactive-EG_lII4R.js} +2 -2
- package/dist/{non-interactive-C9vQaJF2.js.map → non-interactive-EG_lII4R.js.map} +1 -1
- package/dist/{orchestrator-tools-Bw97ahf6.js → orchestrator-tools-DrhpNOKK.js} +3 -3
- package/dist/{orchestrator-tools-Bw97ahf6.js.map → orchestrator-tools-DrhpNOKK.js.map} +1 -1
- package/dist/{package-manager-Cm5vbUDR.js → package-manager-z33XHEWO.js} +2 -2
- package/dist/{package-manager-Cm5vbUDR.js.map → package-manager-z33XHEWO.js.map} +1 -1
- package/dist/{pi-BocAqBQZ.js → pi-CVJB0Ban.js} +11 -11
- package/dist/{pi-BocAqBQZ.js.map → pi-CVJB0Ban.js.map} +1 -1
- package/dist/{playground-DmGHAiON.js → playground-BjWqoWhf.js} +6 -6
- package/dist/{playground-DmGHAiON.js.map → playground-BjWqoWhf.js.map} +1 -1
- package/dist/{posthog-BitL59Wc.js → posthog-3ijs_66W.js} +2 -2
- package/dist/{posthog-BitL59Wc.js.map → posthog-3ijs_66W.js.map} +1 -1
- package/dist/{posthog-integration-DbZ2oza2.js → posthog-integration-C3wuB5B1.js} +14 -14
- package/dist/{posthog-integration-DbZ2oza2.js.map → posthog-integration-C3wuB5B1.js.map} +1 -1
- package/dist/{provisioning-CzRepu4H.js → provisioning-IKacrvWB.js} +3 -3
- package/dist/{provisioning-CzRepu4H.js.map → provisioning-IKacrvWB.js.map} +1 -1
- package/dist/{queue-tools-OynU-m2F.js → queue-tools-zM8_mxx6.js} +5 -4
- package/dist/queue-tools-zM8_mxx6.js.map +1 -0
- package/dist/{registry-eXzDlt51.js → registry-DF_aKyS0.js} +5 -5
- package/dist/{registry-eXzDlt51.js.map → registry-DF_aKyS0.js.map} +1 -1
- package/dist/{security-DqByFEpl.js → security-CVFKNYBn.js} +5 -5
- package/dist/{security-DqByFEpl.js.map → security-CVFKNYBn.js.map} +1 -1
- package/dist/{setup-utils-C2rGcUFv.js → setup-utils-iINkc0xu.js} +8 -8
- package/dist/{setup-utils-C2rGcUFv.js.map → setup-utils-iINkc0xu.js.map} +1 -1
- package/dist/{start-tui-BYTQwgvK.js → start-tui-CjtL-ls7.js} +18 -18
- package/dist/{start-tui-BYTQwgvK.js.map → start-tui-CjtL-ls7.js.map} +1 -1
- package/dist/{steps-CMIyEySI.js → steps-DzUGHdfY.js} +7 -7
- package/dist/{steps-CMIyEySI.js.map → steps-DzUGHdfY.js.map} +1 -1
- package/dist/{store-pBYMaEuj.js → store-DtckpbSC.js} +4 -4
- package/dist/{store-pBYMaEuj.js.map → store-DtckpbSC.js.map} +1 -1
- package/dist/{subagent-ZDD6XCmm.js → subagent-cD_bF490.js} +2 -2
- package/dist/{subagent-ZDD6XCmm.js.map → subagent-cD_bF490.js.map} +1 -1
- package/dist/{task-1KHCdViK.js → task-eIt2iATF.js} +12 -12
- package/dist/{task-1KHCdViK.js.map → task-eIt2iATF.js.map} +1 -1
- package/dist/{task-stream-DAU6Z6u6.js → task-stream-DGBUveUD.js} +4 -4
- package/dist/{task-stream-DAU6Z6u6.js.map → task-stream-DGBUveUD.js.map} +1 -1
- package/dist/{tasks-BBo0_AZG.js → tasks-wQ3V6Ft6.js} +2 -2
- package/dist/{tasks-BBo0_AZG.js.map → tasks-wQ3V6Ft6.js.map} +1 -1
- package/dist/{telemetry-DSzPCPtQ.js → telemetry-BWYDFAwf.js} +3 -3
- package/dist/{telemetry-DSzPCPtQ.js.map → telemetry-BWYDFAwf.js.map} +1 -1
- package/dist/{terminal-DW8x0UNT.js → terminal-yKJZx1UC.js} +11 -11
- package/dist/{terminal-DW8x0UNT.js.map → terminal-yKJZx1UC.js.map} +1 -1
- package/dist/{tools-DCH7Ji4V.js → tools-CDlaJb_e.js} +6 -6
- package/dist/{tools-DCH7Ji4V.js.map → tools-CDlaJb_e.js.map} +1 -1
- package/dist/{wizard-abort-B_Sa9K3g.js → wizard-abort-Cjk5z73h.js} +1 -1
- package/dist/{wizard-abort-Cz916Qq5.js → wizard-abort-CztG5WTv.js} +3 -3
- package/dist/{wizard-abort-Cz916Qq5.js.map → wizard-abort-CztG5WTv.js.map} +1 -1
- package/dist/yara-hooks-DVGKhwaz.js +2 -0
- package/dist/{yara-hooks-DgScuNrT.js → yara-hooks-DeLjTIiJ.js} +4 -4
- package/dist/{yara-hooks-DgScuNrT.js.map → yara-hooks-DeLjTIiJ.js.map} +1 -1
- package/package.json +1 -1
- package/dist/agent-runner-DLAvB67P.js.map +0 -1
- package/dist/analytics-kxgLEv7U.js +0 -2
- package/dist/debug-8-IIHr5f.js.map +0 -1
- package/dist/queue-tools-OynU-m2F.js.map +0 -1
- package/dist/yara-hooks-BVEBOdMu.js +0 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-B_-DWIq7.js";
|
|
2
|
-
import { H as POSTHOG_DEV_CLIENT_ID, Q as POSTHOG_US_CLIENT_ID, W as POSTHOG_EU_CLIENT_ID,
|
|
3
|
-
import { n as analytics } from "./analytics-
|
|
2
|
+
import { H as POSTHOG_DEV_CLIENT_ID, Q as POSTHOG_US_CLIENT_ID, W as POSTHOG_EU_CLIENT_ID, pt as WIZARD_USER_AGENT, s as logToFile, ut as WIZARD_PROVISIONING_SCOPES } from "./debug-BTPYy9p7.js";
|
|
3
|
+
import { n as analytics } from "./analytics-BdKBzz4M.js";
|
|
4
4
|
import axios from "axios";
|
|
5
5
|
import * as crypto from "node:crypto";
|
|
6
6
|
import { z } from "zod";
|
|
@@ -356,4 +356,4 @@ async function requestDeepLink(accessToken, host, opts) {
|
|
|
356
356
|
//#endregion
|
|
357
357
|
export { detectRegion as a, getLlmGatewayUrl as c, resolveBaseUrl as d, requestDeepLink as i, getOAuthUrl as l, provisionNewAccount as n, getCloudUrl as o, provisioning_exports as r, getHost as s, ProvisionedAccountUnreadableError as t, getUiHostFromHost as u };
|
|
358
358
|
|
|
359
|
-
//# sourceMappingURL=provisioning-
|
|
359
|
+
//# sourceMappingURL=provisioning-IKacrvWB.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provisioning-CzRepu4H.js","names":[],"sources":["../src/utils/urls.ts","../src/utils/provisioning.ts"],"sourcesContent":["import axios from 'axios';\nimport { IS_DEV, WIZARD_USER_AGENT } from '@lib/constants';\nimport type { CloudRegion } from './types';\n\n/**\n * Resolve a pinned PostHog base URL from an optional override. When present, it\n * becomes the single source of truth for every PostHog origin — the\n * API/ingestion host, the cloud/app URL, and the OAuth server — bypassing\n * region resolution entirely.\n *\n * The override lives on the session (`session.baseUrl`, set by `--base-url`) and\n * is threaded in by callers, so there is no hidden module-level state. A `--base-url`\n * value wins; otherwise a dev/test build implies `localhost:8010`; otherwise the\n * result is `undefined`, meaning region-based resolution applies.\n *\n * This is the runtime equivalent of the `IS_DEV` localhost routing: `IS_DEV` is a\n * build-time constant that tsdown compiles out of production builds, so it can't\n * point a shipped wizard at a local stack — `--base-url` can. Both feed this one\n * resolver so every URL helper only asks the question once.\n */\nexport const resolveBaseUrl = (override?: string): string | undefined => {\n return override?.trim() || (IS_DEV ? 'http://localhost:8010' : undefined);\n};\n\nexport const getUiHostFromHost = (host: string) => {\n if (host.includes('us.i.posthog.com')) {\n return 'https://us.posthog.com';\n }\n\n if (host.includes('eu.i.posthog.com')) {\n return 'https://eu.posthog.com';\n }\n\n return host;\n};\n\nexport const getHost = (region: CloudRegion, baseUrl?: string) => {\n const override = resolveBaseUrl(baseUrl);\n if (override) {\n return override;\n }\n\n if (region === 'eu') {\n return 'https://eu.i.posthog.com';\n }\n\n return 'https://us.i.posthog.com';\n};\n\nexport const getCloudUrl = (region: CloudRegion, baseUrl?: string) => {\n const override = resolveBaseUrl(baseUrl);\n if (override) {\n return override;\n }\n\n if (region === 'eu') {\n return 'https://eu.posthog.com';\n }\n\n return 'https://us.posthog.com';\n};\n\nexport async function detectRegion(\n accessToken: string,\n baseUrl?: string,\n): Promise<CloudRegion> {\n // With a pinned base URL there is only one instance to talk to — skip the\n // us/eu probe and default the region label to 'us'. (Covers IS_DEV too, via\n // resolveBaseUrl.) The URLs themselves come from the override, not this label.\n if (resolveBaseUrl(baseUrl)) {\n return 'us';\n }\n\n const headers = {\n Authorization: `Bearer ${accessToken}`,\n 'User-Agent': WIZARD_USER_AGENT,\n };\n\n const [usResult, euResult] = await Promise.allSettled([\n axios.get('https://us.posthog.com/api/users/@me/', { headers }),\n axios.get('https://eu.posthog.com/api/users/@me/', { headers }),\n ]);\n\n if (usResult.status === 'fulfilled') return 'us';\n if (euResult.status === 'fulfilled') return 'eu';\n\n throw new Error(\n 'Could not determine cloud region from access token. Please check your PostHog account.',\n );\n}\n\nexport const getLlmGatewayUrl = (host: string) => {\n if (host.includes('host.docker.internal')) {\n return 'http://host.docker.internal:3308/wizard';\n }\n\n if (host.includes('localhost')) {\n return 'http://localhost:3308/wizard';\n }\n\n if (host.includes('eu.posthog.com') || host.includes('eu.i.posthog.com')) {\n return 'https://gateway.eu.posthog.com/wizard';\n }\n\n return 'https://gateway.us.posthog.com/wizard';\n};\n\n/** Region-agnostic prod OAuth server. Resolves to the right region server-side. */\nconst PROD_OAUTH_URL = 'https://oauth.posthog.com';\n\n/**\n * OAuth server URL. Follows the base-URL override (and thus IS_DEV → localhost),\n * otherwise the region-agnostic prod OAuth host.\n */\nexport const getOAuthUrl = (baseUrl?: string): string =>\n resolveBaseUrl(baseUrl) ?? PROD_OAUTH_URL;\n","/**\n * Provisioning API client for creating new PostHog accounts.\n *\n * Uses the agentic provisioning API with PKCE auth:\n * 1. POST /account_requests - create account, get auth code\n * 2. POST /oauth/token - exchange code for tokens (with PKCE)\n * 3. POST /resources - provision project, get API key\n */\n\nimport * as crypto from 'node:crypto';\nimport axios from 'axios';\nimport { z } from 'zod';\nimport {\n POSTHOG_DEV_CLIENT_ID,\n POSTHOG_EU_CLIENT_ID,\n POSTHOG_US_CLIENT_ID,\n WIZARD_PROVISIONING_SCOPES,\n WIZARD_USER_AGENT,\n} from '@lib/constants';\nimport { resolveBaseUrl } from './urls';\nimport { logToFile } from './debug';\nimport { analytics } from './analytics';\nimport type { HostResolution } from '@lib/host-resolution';\n\nconst API_VERSION = '0.1d';\n\n/**\n * Provisioning host. Follows a `--base-url` override (and IS_DEV → localhost),\n * else the prod provisioning host for the target region. Unlike the login OAuth\n * flow (which goes through the region-agnostic `oauth.posthog.com` proxy), the\n * provisioning API is region-specific: an EU account must be created against\n * `eu.posthog.com`, and the subsequent token-exchange / resources calls stay on\n * the same host (they carry the account's bearer token).\n */\nconst getProvisioningBaseUrl = (\n region: 'US' | 'EU',\n baseUrl?: string,\n): string => {\n const override = resolveBaseUrl(baseUrl);\n if (override) return override;\n return region === 'EU' ? 'https://eu.posthog.com' : 'https://us.posthog.com';\n};\n\n/**\n * OAuth client ID for provisioning. A pinned base URL means a dev-seeded stack\n * that registers the dev client; prod uses the client registered for the target\n * region (the wizard OAuth app is registered separately per region).\n *\n * TODO: same assumption as `getOAuthClientId` in oauth.ts — a pinned base URL is\n * treated as a dev-seeded instance. Make configurable if we ever point\n * `--base-url` at a non-dev instance with its own OAuth app.\n */\nconst getProvisioningClientId = (\n region: 'US' | 'EU',\n baseUrl?: string,\n): string => {\n if (resolveBaseUrl(baseUrl)) return POSTHOG_DEV_CLIENT_ID;\n return region === 'EU' ? POSTHOG_EU_CLIENT_ID : POSTHOG_US_CLIENT_ID;\n};\n\nfunction generateCodeVerifier(): string {\n return crypto.randomBytes(32).toString('base64url');\n}\n\nfunction generateCodeChallenge(verifier: string): string {\n return crypto.createHash('sha256').update(verifier).digest('base64url');\n}\n\n// --- Response schemas ---\n//\n// These schemas validate only the fields the wizard actually reads. The rule is load\n// bearing, not stylistic: the wizard ships to npm and old versions keep running against\n// a provisioning API that moves independently, so a field we require but never consume\n// is a crash we cannot fix in the field. `service_id` was exactly that — required here,\n// read nowhere, and every signup broke the day the API stopped echoing it. Zod strips\n// unknown keys, so fields the API adds are tolerated for free; the only way to break is\n// to demand something back.\n\nconst AccountRequestResponseSchema = z.object({\n id: z.string(),\n type: z.enum(['oauth', 'requires_auth', 'error']),\n oauth: z\n .object({\n code: z.string(),\n })\n .optional(),\n error: z\n .object({\n code: z.string(),\n message: z.string(),\n })\n .optional(),\n});\n\nconst TokenResponseSchema = z.object({\n token_type: z.string(),\n access_token: z.string(),\n refresh_token: z.string(),\n expires_in: z.number(),\n account: z\n .object({\n id: z.string(),\n })\n .optional(),\n});\n\nconst AccessConfigurationSchema = z.object({\n api_key: z.string(),\n host: z.string(),\n personal_api_key: z.string().optional(),\n});\n\nconst ResourceResponseSchema = z.object({\n status: z.string(),\n id: z.string(),\n complete: z\n .object({\n access_configuration: AccessConfigurationSchema,\n })\n .optional(),\n});\n\n/**\n * Teams the account can reach, from the token exchange. Parsed separately from\n * `TokenResponseSchema` and as loosely as possible: it is only used to recover from a\n * response we already failed to read, so it must never become a new way to fail.\n */\nconst AvailableTeamsSchema = z.array(\n z.object({ id: z.union([z.number(), z.string()]) }),\n);\n\n/**\n * Thrown when the provisioning API completed the work but the wizard could not read the\n * project back out of the response. The account, organization and project exist — callers\n * must not tell the user their account wasn't created.\n */\nexport class ProvisionedAccountUnreadableError extends Error {\n readonly accountCreated = true;\n\n constructor(message: string) {\n super(message);\n this.name = 'ProvisionedAccountUnreadableError';\n }\n}\n\n/** The field paths Zod rejected — never the values, which carry tokens and API keys. */\nfunction issuePaths(error: z.ZodError): string[] {\n return error.issues.map((issue) => issue.path.join('.') || '(root)');\n}\n\n/**\n * Report a response the wizard couldn't read. Silently degrading on a shape mismatch\n * turns the next contract change into a week of guesswork, so the rejected paths go to\n * the debug log and to error tracking before anything else happens.\n */\nfunction reportUnreadableResponse(step: string, error: z.ZodError): Error {\n const paths = issuePaths(error);\n const reported = new Error(\n `Unexpected ${step} response from the provisioning API (missing or invalid: ${paths.join(\n ', ',\n )})`,\n );\n\n logToFile(\n `[provisioning] unexpected ${step} response shape: ${paths.join(', ')}`,\n );\n analytics.captureException(reported, {\n step: `provisioning_${step}`,\n issue_paths: paths,\n });\n\n return reported;\n}\n\nfunction parseOrThrow<T extends z.ZodTypeAny>(\n schema: T,\n data: unknown,\n step: string,\n): z.infer<T> {\n const parsed = schema.safeParse(data);\n if (!parsed.success) {\n throw reportUnreadableResponse(step, parsed.error);\n }\n return parsed.data;\n}\n\ntype ResourceRead =\n | {\n ok: true;\n projectId: string;\n access: z.infer<typeof AccessConfigurationSchema>;\n }\n | { ok: false; reason: 'unreadable' | 'incomplete' };\n\nfunction readResource(data: unknown, step: string): ResourceRead {\n const parsed = ResourceResponseSchema.safeParse(data);\n if (!parsed.success) {\n reportUnreadableResponse(step, parsed.error);\n return { ok: false, reason: 'unreadable' };\n }\n\n if (parsed.data.status !== 'complete' || !parsed.data.complete) {\n logToFile(`[provisioning] ${step} returned status=${parsed.data.status}`);\n return { ok: false, reason: 'incomplete' };\n }\n\n return {\n ok: true,\n projectId: parsed.data.id,\n access: parsed.data.complete.access_configuration,\n };\n}\n\n/**\n * Recover the project after an unreadable `POST /resources` response.\n *\n * By the time that call returns 2xx the account, organization and project exist, so\n * aborting would abandon a provisioned account and leave the user with an orphaned\n * project. `GET /resources/:id` returns the same access configuration, so read it back\n * instead. Best-effort by design: any failure returns null and the caller reports the\n * original drift. The detail endpoint never mints a personal API key, so a recovered\n * result has none — `personalApiKey` is optional for every consumer.\n */\nasync function readBackResource(\n provisioningBaseUrl: string,\n accessToken: string,\n tokenPayload: unknown,\n): Promise<ResourceRead | null> {\n const teams = AvailableTeamsSchema.safeParse(\n (tokenPayload as { account?: { available_teams?: unknown } } | undefined)\n ?.account?.available_teams,\n );\n\n // A freshly provisioned account owns exactly one team. With any other count we can't\n // tell which team the create call made, and guessing would capture into the wrong one.\n if (!teams.success || teams.data.length !== 1) {\n logToFile(\n '[provisioning] no unambiguous team to read the resource back from',\n );\n return null;\n }\n\n const resourceId = String(teams.data[0].id);\n\n try {\n const res = await axios.get(\n `${provisioningBaseUrl}/api/agentic/provisioning/resources/${resourceId}`,\n {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'API-Version': API_VERSION,\n 'User-Agent': WIZARD_USER_AGENT,\n },\n timeout: 30_000,\n },\n );\n\n logToFile(\n `[provisioning] read resource ${resourceId} back after unreadable create`,\n );\n return readResource(res.data, 'resource_readback');\n } catch {\n logToFile(`[provisioning] read-back of resource ${resourceId} failed`);\n return null;\n }\n}\n\nexport interface ProvisioningResult {\n accessToken: string;\n refreshToken: string;\n projectApiKey: string;\n host: string;\n personalApiKey?: string;\n projectId: string;\n accountId: string;\n}\n\n/**\n * Create a new PostHog account and provision a project via the provisioning API.\n *\n * This is the \"no browser\" signup path: the wizard collects the email,\n * calls the provisioning API to create the account, and gets back\n * credentials without opening a browser.\n */\nexport async function provisionNewAccount(\n email: string,\n name: string,\n region: 'US' | 'EU' = 'US',\n opts?: { orgName?: string; projectName?: string; baseUrl?: string },\n): Promise<ProvisioningResult> {\n const codeVerifier = generateCodeVerifier();\n const codeChallenge = generateCodeChallenge(codeVerifier);\n const provisioningBaseUrl = getProvisioningBaseUrl(region, opts?.baseUrl);\n\n logToFile('[provisioning] starting account creation');\n\n // Step 1: Create account\n const accountRes = await axios.post(\n `${provisioningBaseUrl}/api/agentic/provisioning/account_requests`,\n {\n id: crypto.randomUUID(),\n email,\n name,\n client_id: getProvisioningClientId(region, opts?.baseUrl),\n code_challenge: codeChallenge,\n code_challenge_method: 'S256',\n scopes: WIZARD_PROVISIONING_SCOPES,\n configuration: {\n region,\n ...(opts?.orgName ? { organization_name: opts.orgName } : {}),\n },\n },\n {\n headers: {\n 'Content-Type': 'application/json',\n 'API-Version': API_VERSION,\n 'User-Agent': WIZARD_USER_AGENT,\n },\n timeout: 30_000,\n },\n );\n\n const accountData = parseOrThrow(\n AccountRequestResponseSchema,\n accountRes.data,\n 'account_requests',\n );\n\n if (accountData.type === 'error') {\n const msg = accountData.error?.message ?? 'Account creation failed';\n analytics.captureException(new Error(msg), {\n step: 'provisioning_account_request',\n error_code: accountData.error?.code,\n });\n throw new Error(msg);\n }\n\n if (accountData.type === 'requires_auth') {\n throw new Error(\n 'This email is already associated with a PostHog account. Please use the login flow instead.',\n );\n }\n\n const code = accountData.oauth?.code;\n if (!code) {\n throw new Error('No authorization code received from account creation');\n }\n\n logToFile('[provisioning] account created, exchanging code for tokens');\n\n // Step 2: Exchange code for tokens\n const tokenRes = await axios.post(\n `${provisioningBaseUrl}/api/agentic/oauth/token`,\n new URLSearchParams({\n grant_type: 'authorization_code',\n code,\n code_verifier: codeVerifier,\n }).toString(),\n {\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n 'API-Version': API_VERSION,\n 'User-Agent': WIZARD_USER_AGENT,\n },\n timeout: 30_000,\n },\n );\n\n const tokenData = parseOrThrow(\n TokenResponseSchema,\n tokenRes.data,\n 'oauth_token',\n );\n\n logToFile('[provisioning] tokens received, provisioning resources');\n\n // Step 3: Provision resources\n const resourceRes = await axios.post(\n `${provisioningBaseUrl}/api/agentic/provisioning/resources`,\n {\n ...(opts?.projectName\n ? { configuration: { project_name: opts.projectName } }\n : {}),\n },\n {\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${tokenData.access_token}`,\n 'API-Version': API_VERSION,\n 'User-Agent': WIZARD_USER_AGENT,\n },\n timeout: 30_000,\n },\n );\n\n // `/resources` is synchronous: it answers `status: \"complete\"` or an error envelope.\n // So an unreadable body means the contract moved, not that provisioning is still\n // running — and the project already exists either way, which is why this recovers\n // instead of aborting.\n let resource = readResource(resourceRes.data, 'resources');\n\n if (!resource.ok && resource.reason === 'unreadable') {\n resource =\n (await readBackResource(\n provisioningBaseUrl,\n tokenData.access_token,\n tokenRes.data,\n )) ?? resource;\n }\n\n if (!resource.ok) {\n if (resource.reason === 'incomplete') {\n throw new Error('Resource provisioning did not complete');\n }\n throw new ProvisionedAccountUnreadableError(\n 'Your PostHog project was created, but the provisioning API returned a response the wizard could not read',\n );\n }\n\n logToFile('[provisioning] resources provisioned successfully');\n\n return {\n accessToken: tokenData.access_token,\n refreshToken: tokenData.refresh_token,\n projectApiKey: resource.access.api_key,\n host: resource.access.host,\n personalApiKey: resource.access.personal_api_key,\n projectId: resource.projectId,\n accountId: tokenData.account?.id ?? '',\n };\n}\n\n/**\n * Request a one-time deep link URL that logs the user into PostHog\n * and redirects to their project dashboard — or, when `opts.path` is\n * given, to any safe in-app relative path (e.g. the Signals inbox).\n */\nexport async function requestDeepLink(\n accessToken: string,\n host: HostResolution,\n opts?: { purpose?: string; path?: string },\n): Promise<string | null> {\n try {\n const baseUrl = host.appHost;\n\n const res = await axios.post(\n `${baseUrl}/api/agentic/provisioning/deep_links`,\n {\n purpose: opts?.purpose ?? 'dashboard',\n ...(opts?.path ? { path: opts.path } : {}),\n },\n {\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n 'API-Version': API_VERSION,\n 'User-Agent': WIZARD_USER_AGENT,\n },\n timeout: 10_000,\n },\n );\n\n const url = res.data?.url;\n if (typeof url === 'string') {\n logToFile(`[provisioning] deep link created: ${url}`);\n return url;\n }\n return null;\n } catch {\n logToFile('[provisioning] deep link request failed, skipping');\n return null;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"provisioning-IKacrvWB.js","names":[],"sources":["../src/utils/urls.ts","../src/utils/provisioning.ts"],"sourcesContent":["import axios from 'axios';\nimport { IS_DEV, WIZARD_USER_AGENT } from '@lib/constants';\nimport type { CloudRegion } from './types';\n\n/**\n * Resolve a pinned PostHog base URL from an optional override. When present, it\n * becomes the single source of truth for every PostHog origin — the\n * API/ingestion host, the cloud/app URL, and the OAuth server — bypassing\n * region resolution entirely.\n *\n * The override lives on the session (`session.baseUrl`, set by `--base-url`) and\n * is threaded in by callers, so there is no hidden module-level state. A `--base-url`\n * value wins; otherwise a dev/test build implies `localhost:8010`; otherwise the\n * result is `undefined`, meaning region-based resolution applies.\n *\n * This is the runtime equivalent of the `IS_DEV` localhost routing: `IS_DEV` is a\n * build-time constant that tsdown compiles out of production builds, so it can't\n * point a shipped wizard at a local stack — `--base-url` can. Both feed this one\n * resolver so every URL helper only asks the question once.\n */\nexport const resolveBaseUrl = (override?: string): string | undefined => {\n return override?.trim() || (IS_DEV ? 'http://localhost:8010' : undefined);\n};\n\nexport const getUiHostFromHost = (host: string) => {\n if (host.includes('us.i.posthog.com')) {\n return 'https://us.posthog.com';\n }\n\n if (host.includes('eu.i.posthog.com')) {\n return 'https://eu.posthog.com';\n }\n\n return host;\n};\n\nexport const getHost = (region: CloudRegion, baseUrl?: string) => {\n const override = resolveBaseUrl(baseUrl);\n if (override) {\n return override;\n }\n\n if (region === 'eu') {\n return 'https://eu.i.posthog.com';\n }\n\n return 'https://us.i.posthog.com';\n};\n\nexport const getCloudUrl = (region: CloudRegion, baseUrl?: string) => {\n const override = resolveBaseUrl(baseUrl);\n if (override) {\n return override;\n }\n\n if (region === 'eu') {\n return 'https://eu.posthog.com';\n }\n\n return 'https://us.posthog.com';\n};\n\nexport async function detectRegion(\n accessToken: string,\n baseUrl?: string,\n): Promise<CloudRegion> {\n // With a pinned base URL there is only one instance to talk to — skip the\n // us/eu probe and default the region label to 'us'. (Covers IS_DEV too, via\n // resolveBaseUrl.) The URLs themselves come from the override, not this label.\n if (resolveBaseUrl(baseUrl)) {\n return 'us';\n }\n\n const headers = {\n Authorization: `Bearer ${accessToken}`,\n 'User-Agent': WIZARD_USER_AGENT,\n };\n\n const [usResult, euResult] = await Promise.allSettled([\n axios.get('https://us.posthog.com/api/users/@me/', { headers }),\n axios.get('https://eu.posthog.com/api/users/@me/', { headers }),\n ]);\n\n if (usResult.status === 'fulfilled') return 'us';\n if (euResult.status === 'fulfilled') return 'eu';\n\n throw new Error(\n 'Could not determine cloud region from access token. Please check your PostHog account.',\n );\n}\n\nexport const getLlmGatewayUrl = (host: string) => {\n if (host.includes('host.docker.internal')) {\n return 'http://host.docker.internal:3308/wizard';\n }\n\n if (host.includes('localhost')) {\n return 'http://localhost:3308/wizard';\n }\n\n if (host.includes('eu.posthog.com') || host.includes('eu.i.posthog.com')) {\n return 'https://gateway.eu.posthog.com/wizard';\n }\n\n return 'https://gateway.us.posthog.com/wizard';\n};\n\n/** Region-agnostic prod OAuth server. Resolves to the right region server-side. */\nconst PROD_OAUTH_URL = 'https://oauth.posthog.com';\n\n/**\n * OAuth server URL. Follows the base-URL override (and thus IS_DEV → localhost),\n * otherwise the region-agnostic prod OAuth host.\n */\nexport const getOAuthUrl = (baseUrl?: string): string =>\n resolveBaseUrl(baseUrl) ?? PROD_OAUTH_URL;\n","/**\n * Provisioning API client for creating new PostHog accounts.\n *\n * Uses the agentic provisioning API with PKCE auth:\n * 1. POST /account_requests - create account, get auth code\n * 2. POST /oauth/token - exchange code for tokens (with PKCE)\n * 3. POST /resources - provision project, get API key\n */\n\nimport * as crypto from 'node:crypto';\nimport axios from 'axios';\nimport { z } from 'zod';\nimport {\n POSTHOG_DEV_CLIENT_ID,\n POSTHOG_EU_CLIENT_ID,\n POSTHOG_US_CLIENT_ID,\n WIZARD_PROVISIONING_SCOPES,\n WIZARD_USER_AGENT,\n} from '@lib/constants';\nimport { resolveBaseUrl } from './urls';\nimport { logToFile } from './debug';\nimport { analytics } from './analytics';\nimport type { HostResolution } from '@lib/host-resolution';\n\nconst API_VERSION = '0.1d';\n\n/**\n * Provisioning host. Follows a `--base-url` override (and IS_DEV → localhost),\n * else the prod provisioning host for the target region. Unlike the login OAuth\n * flow (which goes through the region-agnostic `oauth.posthog.com` proxy), the\n * provisioning API is region-specific: an EU account must be created against\n * `eu.posthog.com`, and the subsequent token-exchange / resources calls stay on\n * the same host (they carry the account's bearer token).\n */\nconst getProvisioningBaseUrl = (\n region: 'US' | 'EU',\n baseUrl?: string,\n): string => {\n const override = resolveBaseUrl(baseUrl);\n if (override) return override;\n return region === 'EU' ? 'https://eu.posthog.com' : 'https://us.posthog.com';\n};\n\n/**\n * OAuth client ID for provisioning. A pinned base URL means a dev-seeded stack\n * that registers the dev client; prod uses the client registered for the target\n * region (the wizard OAuth app is registered separately per region).\n *\n * TODO: same assumption as `getOAuthClientId` in oauth.ts — a pinned base URL is\n * treated as a dev-seeded instance. Make configurable if we ever point\n * `--base-url` at a non-dev instance with its own OAuth app.\n */\nconst getProvisioningClientId = (\n region: 'US' | 'EU',\n baseUrl?: string,\n): string => {\n if (resolveBaseUrl(baseUrl)) return POSTHOG_DEV_CLIENT_ID;\n return region === 'EU' ? POSTHOG_EU_CLIENT_ID : POSTHOG_US_CLIENT_ID;\n};\n\nfunction generateCodeVerifier(): string {\n return crypto.randomBytes(32).toString('base64url');\n}\n\nfunction generateCodeChallenge(verifier: string): string {\n return crypto.createHash('sha256').update(verifier).digest('base64url');\n}\n\n// --- Response schemas ---\n//\n// These schemas validate only the fields the wizard actually reads. The rule is load\n// bearing, not stylistic: the wizard ships to npm and old versions keep running against\n// a provisioning API that moves independently, so a field we require but never consume\n// is a crash we cannot fix in the field. `service_id` was exactly that — required here,\n// read nowhere, and every signup broke the day the API stopped echoing it. Zod strips\n// unknown keys, so fields the API adds are tolerated for free; the only way to break is\n// to demand something back.\n\nconst AccountRequestResponseSchema = z.object({\n id: z.string(),\n type: z.enum(['oauth', 'requires_auth', 'error']),\n oauth: z\n .object({\n code: z.string(),\n })\n .optional(),\n error: z\n .object({\n code: z.string(),\n message: z.string(),\n })\n .optional(),\n});\n\nconst TokenResponseSchema = z.object({\n token_type: z.string(),\n access_token: z.string(),\n refresh_token: z.string(),\n expires_in: z.number(),\n account: z\n .object({\n id: z.string(),\n })\n .optional(),\n});\n\nconst AccessConfigurationSchema = z.object({\n api_key: z.string(),\n host: z.string(),\n personal_api_key: z.string().optional(),\n});\n\nconst ResourceResponseSchema = z.object({\n status: z.string(),\n id: z.string(),\n complete: z\n .object({\n access_configuration: AccessConfigurationSchema,\n })\n .optional(),\n});\n\n/**\n * Teams the account can reach, from the token exchange. Parsed separately from\n * `TokenResponseSchema` and as loosely as possible: it is only used to recover from a\n * response we already failed to read, so it must never become a new way to fail.\n */\nconst AvailableTeamsSchema = z.array(\n z.object({ id: z.union([z.number(), z.string()]) }),\n);\n\n/**\n * Thrown when the provisioning API completed the work but the wizard could not read the\n * project back out of the response. The account, organization and project exist — callers\n * must not tell the user their account wasn't created.\n */\nexport class ProvisionedAccountUnreadableError extends Error {\n readonly accountCreated = true;\n\n constructor(message: string) {\n super(message);\n this.name = 'ProvisionedAccountUnreadableError';\n }\n}\n\n/** The field paths Zod rejected — never the values, which carry tokens and API keys. */\nfunction issuePaths(error: z.ZodError): string[] {\n return error.issues.map((issue) => issue.path.join('.') || '(root)');\n}\n\n/**\n * Report a response the wizard couldn't read. Silently degrading on a shape mismatch\n * turns the next contract change into a week of guesswork, so the rejected paths go to\n * the debug log and to error tracking before anything else happens.\n */\nfunction reportUnreadableResponse(step: string, error: z.ZodError): Error {\n const paths = issuePaths(error);\n const reported = new Error(\n `Unexpected ${step} response from the provisioning API (missing or invalid: ${paths.join(\n ', ',\n )})`,\n );\n\n logToFile(\n `[provisioning] unexpected ${step} response shape: ${paths.join(', ')}`,\n );\n analytics.captureException(reported, {\n step: `provisioning_${step}`,\n issue_paths: paths,\n });\n\n return reported;\n}\n\nfunction parseOrThrow<T extends z.ZodTypeAny>(\n schema: T,\n data: unknown,\n step: string,\n): z.infer<T> {\n const parsed = schema.safeParse(data);\n if (!parsed.success) {\n throw reportUnreadableResponse(step, parsed.error);\n }\n return parsed.data;\n}\n\ntype ResourceRead =\n | {\n ok: true;\n projectId: string;\n access: z.infer<typeof AccessConfigurationSchema>;\n }\n | { ok: false; reason: 'unreadable' | 'incomplete' };\n\nfunction readResource(data: unknown, step: string): ResourceRead {\n const parsed = ResourceResponseSchema.safeParse(data);\n if (!parsed.success) {\n reportUnreadableResponse(step, parsed.error);\n return { ok: false, reason: 'unreadable' };\n }\n\n if (parsed.data.status !== 'complete' || !parsed.data.complete) {\n logToFile(`[provisioning] ${step} returned status=${parsed.data.status}`);\n return { ok: false, reason: 'incomplete' };\n }\n\n return {\n ok: true,\n projectId: parsed.data.id,\n access: parsed.data.complete.access_configuration,\n };\n}\n\n/**\n * Recover the project after an unreadable `POST /resources` response.\n *\n * By the time that call returns 2xx the account, organization and project exist, so\n * aborting would abandon a provisioned account and leave the user with an orphaned\n * project. `GET /resources/:id` returns the same access configuration, so read it back\n * instead. Best-effort by design: any failure returns null and the caller reports the\n * original drift. The detail endpoint never mints a personal API key, so a recovered\n * result has none — `personalApiKey` is optional for every consumer.\n */\nasync function readBackResource(\n provisioningBaseUrl: string,\n accessToken: string,\n tokenPayload: unknown,\n): Promise<ResourceRead | null> {\n const teams = AvailableTeamsSchema.safeParse(\n (tokenPayload as { account?: { available_teams?: unknown } } | undefined)\n ?.account?.available_teams,\n );\n\n // A freshly provisioned account owns exactly one team. With any other count we can't\n // tell which team the create call made, and guessing would capture into the wrong one.\n if (!teams.success || teams.data.length !== 1) {\n logToFile(\n '[provisioning] no unambiguous team to read the resource back from',\n );\n return null;\n }\n\n const resourceId = String(teams.data[0].id);\n\n try {\n const res = await axios.get(\n `${provisioningBaseUrl}/api/agentic/provisioning/resources/${resourceId}`,\n {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'API-Version': API_VERSION,\n 'User-Agent': WIZARD_USER_AGENT,\n },\n timeout: 30_000,\n },\n );\n\n logToFile(\n `[provisioning] read resource ${resourceId} back after unreadable create`,\n );\n return readResource(res.data, 'resource_readback');\n } catch {\n logToFile(`[provisioning] read-back of resource ${resourceId} failed`);\n return null;\n }\n}\n\nexport interface ProvisioningResult {\n accessToken: string;\n refreshToken: string;\n projectApiKey: string;\n host: string;\n personalApiKey?: string;\n projectId: string;\n accountId: string;\n}\n\n/**\n * Create a new PostHog account and provision a project via the provisioning API.\n *\n * This is the \"no browser\" signup path: the wizard collects the email,\n * calls the provisioning API to create the account, and gets back\n * credentials without opening a browser.\n */\nexport async function provisionNewAccount(\n email: string,\n name: string,\n region: 'US' | 'EU' = 'US',\n opts?: { orgName?: string; projectName?: string; baseUrl?: string },\n): Promise<ProvisioningResult> {\n const codeVerifier = generateCodeVerifier();\n const codeChallenge = generateCodeChallenge(codeVerifier);\n const provisioningBaseUrl = getProvisioningBaseUrl(region, opts?.baseUrl);\n\n logToFile('[provisioning] starting account creation');\n\n // Step 1: Create account\n const accountRes = await axios.post(\n `${provisioningBaseUrl}/api/agentic/provisioning/account_requests`,\n {\n id: crypto.randomUUID(),\n email,\n name,\n client_id: getProvisioningClientId(region, opts?.baseUrl),\n code_challenge: codeChallenge,\n code_challenge_method: 'S256',\n scopes: WIZARD_PROVISIONING_SCOPES,\n configuration: {\n region,\n ...(opts?.orgName ? { organization_name: opts.orgName } : {}),\n },\n },\n {\n headers: {\n 'Content-Type': 'application/json',\n 'API-Version': API_VERSION,\n 'User-Agent': WIZARD_USER_AGENT,\n },\n timeout: 30_000,\n },\n );\n\n const accountData = parseOrThrow(\n AccountRequestResponseSchema,\n accountRes.data,\n 'account_requests',\n );\n\n if (accountData.type === 'error') {\n const msg = accountData.error?.message ?? 'Account creation failed';\n analytics.captureException(new Error(msg), {\n step: 'provisioning_account_request',\n error_code: accountData.error?.code,\n });\n throw new Error(msg);\n }\n\n if (accountData.type === 'requires_auth') {\n throw new Error(\n 'This email is already associated with a PostHog account. Please use the login flow instead.',\n );\n }\n\n const code = accountData.oauth?.code;\n if (!code) {\n throw new Error('No authorization code received from account creation');\n }\n\n logToFile('[provisioning] account created, exchanging code for tokens');\n\n // Step 2: Exchange code for tokens\n const tokenRes = await axios.post(\n `${provisioningBaseUrl}/api/agentic/oauth/token`,\n new URLSearchParams({\n grant_type: 'authorization_code',\n code,\n code_verifier: codeVerifier,\n }).toString(),\n {\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n 'API-Version': API_VERSION,\n 'User-Agent': WIZARD_USER_AGENT,\n },\n timeout: 30_000,\n },\n );\n\n const tokenData = parseOrThrow(\n TokenResponseSchema,\n tokenRes.data,\n 'oauth_token',\n );\n\n logToFile('[provisioning] tokens received, provisioning resources');\n\n // Step 3: Provision resources\n const resourceRes = await axios.post(\n `${provisioningBaseUrl}/api/agentic/provisioning/resources`,\n {\n ...(opts?.projectName\n ? { configuration: { project_name: opts.projectName } }\n : {}),\n },\n {\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${tokenData.access_token}`,\n 'API-Version': API_VERSION,\n 'User-Agent': WIZARD_USER_AGENT,\n },\n timeout: 30_000,\n },\n );\n\n // `/resources` is synchronous: it answers `status: \"complete\"` or an error envelope.\n // So an unreadable body means the contract moved, not that provisioning is still\n // running — and the project already exists either way, which is why this recovers\n // instead of aborting.\n let resource = readResource(resourceRes.data, 'resources');\n\n if (!resource.ok && resource.reason === 'unreadable') {\n resource =\n (await readBackResource(\n provisioningBaseUrl,\n tokenData.access_token,\n tokenRes.data,\n )) ?? resource;\n }\n\n if (!resource.ok) {\n if (resource.reason === 'incomplete') {\n throw new Error('Resource provisioning did not complete');\n }\n throw new ProvisionedAccountUnreadableError(\n 'Your PostHog project was created, but the provisioning API returned a response the wizard could not read',\n );\n }\n\n logToFile('[provisioning] resources provisioned successfully');\n\n return {\n accessToken: tokenData.access_token,\n refreshToken: tokenData.refresh_token,\n projectApiKey: resource.access.api_key,\n host: resource.access.host,\n personalApiKey: resource.access.personal_api_key,\n projectId: resource.projectId,\n accountId: tokenData.account?.id ?? '',\n };\n}\n\n/**\n * Request a one-time deep link URL that logs the user into PostHog\n * and redirects to their project dashboard — or, when `opts.path` is\n * given, to any safe in-app relative path (e.g. the Signals inbox).\n */\nexport async function requestDeepLink(\n accessToken: string,\n host: HostResolution,\n opts?: { purpose?: string; path?: string },\n): Promise<string | null> {\n try {\n const baseUrl = host.appHost;\n\n const res = await axios.post(\n `${baseUrl}/api/agentic/provisioning/deep_links`,\n {\n purpose: opts?.purpose ?? 'dashboard',\n ...(opts?.path ? { path: opts.path } : {}),\n },\n {\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n 'API-Version': API_VERSION,\n 'User-Agent': WIZARD_USER_AGENT,\n },\n timeout: 10_000,\n },\n );\n\n const url = res.data?.url;\n if (typeof url === 'string') {\n logToFile(`[provisioning] deep link created: ${url}`);\n return url;\n }\n return null;\n } catch {\n logToFile('[provisioning] deep link request failed, skipping');\n return null;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as GPT5_6_LUNA_MODEL, B as OPUS_MODEL, D as DEFAULT_AGENT_MODEL, M as GPT5_6_TERRA_MODEL, N as HAIKU_MODEL, P as HAIKU_TRIAGE_MODEL, et as SONNET_5_MODEL, j as GPT5_6_SOL_MODEL } from "./debug-
|
|
2
|
-
import { n as analytics } from "./analytics-
|
|
1
|
+
import { A as GPT5_6_LUNA_MODEL, B as OPUS_MODEL, D as DEFAULT_AGENT_MODEL, M as GPT5_6_TERRA_MODEL, N as HAIKU_MODEL, P as HAIKU_TRIAGE_MODEL, et as SONNET_5_MODEL, j as GPT5_6_SOL_MODEL } from "./debug-BTPYy9p7.js";
|
|
2
|
+
import { n as analytics } from "./analytics-BdKBzz4M.js";
|
|
3
3
|
import * as fs$1 from "fs";
|
|
4
4
|
import * as path$1 from "path";
|
|
5
5
|
import { z } from "zod";
|
|
@@ -183,7 +183,7 @@ var QueueStore = class {
|
|
|
183
183
|
* `skipped`). A skipped dependency does not block downstream work.
|
|
184
184
|
*/
|
|
185
185
|
nextRunnable() {
|
|
186
|
-
const doneIds = new Set(this.tasks.filter((t) => t.status === TaskStatus.Done || t.status === TaskStatus.Skipped).map((t) => t.id));
|
|
186
|
+
const doneIds = new Set(this.tasks.filter((t) => t.status === TaskStatus.Done || t.status === TaskStatus.Skipped || t.status === TaskStatus.Failed && t.optional === true && t.attempts >= t.maxAttempts).map((t) => t.id));
|
|
187
187
|
return this.tasks.filter((t) => t.status === TaskStatus.Pending && t.dependsOn.every((d) => doneIds.has(d)));
|
|
188
188
|
}
|
|
189
189
|
/**
|
|
@@ -227,6 +227,7 @@ var QueueStore = class {
|
|
|
227
227
|
attempts: 0,
|
|
228
228
|
maxAttempts: input.maxAttempts ?? DEFAULT_MAX_ATTEMPTS,
|
|
229
229
|
enqueuedBy: input.enqueuedBy ?? "orchestrator",
|
|
230
|
+
optional: input.optional,
|
|
230
231
|
createdAt: nowIso()
|
|
231
232
|
};
|
|
232
233
|
this.tasks.push(task);
|
|
@@ -502,4 +503,4 @@ function buildOrchestratorTools(tool, ctx) {
|
|
|
502
503
|
//#endregion
|
|
503
504
|
export { buildOrchestratorTools as a, QueueStore as c, writeJsonAtomic as d, isThinkingLevel as f, triageModelFor as g, requireKnownModel as h, applyReadHandoffs as i, TaskStatus as l, modelCapabilities as m, applyComplete as n, uncoveredBySink as o, isValidModel as p, applyEnqueue as r, QUEUE_DIR_NAME as s, REMARK_ASK as t, makeMutex as u };
|
|
504
505
|
|
|
505
|
-
//# sourceMappingURL=queue-tools-
|
|
506
|
+
//# sourceMappingURL=queue-tools-zM8_mxx6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue-tools-zM8_mxx6.js","names":["path"],"sources":["../src/lib/agent/runner/switchboard/models.ts","../src/utils/atomic-ledger.ts","../src/lib/agent/runner/sequence/orchestrator/queue.ts","../src/lib/agent/runner/sequence/orchestrator/queue-tools.ts"],"sourcesContent":["/**\n * Model capabilities — the traits a harness needs that a bare gateway model id\n * doesn't carry. The switchboard resolves *which* model (harness.ts); this\n * resolves *what the model can do*, so a harness never hardcodes it.\n *\n * `reasoning` gates whether a harness requests reasoning at all; `thinkingLevel`\n * sets how much. Non-reasoning openai-completions models reject the reasoning\n * params (gpt-4o → gateway `UnsupportedParamsError` → the pi run no-ops), and\n * effort trades speed for depth (flagship gpt-5 at high effort runs long). Both\n * are silent when wrong, so they live here as one configurable table.\n */\nimport {\n DEFAULT_AGENT_MODEL,\n SONNET_5_MODEL,\n OPUS_MODEL,\n HAIKU_MODEL,\n GPT5_6_LUNA_MODEL,\n GPT5_6_SOL_MODEL,\n GPT5_6_TERRA_MODEL,\n HAIKU_TRIAGE_MODEL,\n Harness,\n} from '@lib/constants';\n\n/** Reasoning effort. pi maps it to `reasoning_effort` for openai-completions. */\nconst THINKING_LEVELS = [\n 'off',\n 'minimal',\n 'low',\n 'medium',\n 'high',\n 'xhigh',\n] as const;\nexport type ThinkingLevel = (typeof THINKING_LEVELS)[number];\n\n/** Whether a value (e.g. remote prompt frontmatter) names a valid effort. */\nexport function isThinkingLevel(value: unknown): value is ThinkingLevel {\n return (THINKING_LEVELS as readonly unknown[]).includes(value);\n}\n\n/**\n * An effort *override* is always a positive level — `'off'` is a model trait\n * (`reasoning: false`), not something a flag may force onto a reasoning model.\n */\nexport type EffortLevel = Exclude<ThinkingLevel, 'off'>;\n\nexport interface ModelCapabilities {\n /** Model supports reasoning; safe to request reasoning effort. */\n reasoning: boolean;\n /** Effort to request when reasoning. Omit for the harness/provider default. */\n thinkingLevel?: ThinkingLevel;\n}\n\n/** Explicit per-model traits. Anything absent falls back to `defaultCaps`. */\nexport const MODEL_CAPABILITIES: Record<string, ModelCapabilities> = {\n [DEFAULT_AGENT_MODEL]: { reasoning: true }, // claude-sonnet-4-6\n [SONNET_5_MODEL]: { reasoning: true },\n [OPUS_MODEL]: { reasoning: true },\n [HAIKU_MODEL]: { reasoning: true },\n // The openai 5.6 line; all reasoning models, so they must opt in past the\n // openai-completions default (reasoning off). Luna stays low for cheap,\n // short-context mechanical work; terra runs medium as the sonnet-tier parallel\n // — enough reasoning depth for the judgment tasks without high's latency blowup.\n [GPT5_6_LUNA_MODEL]: { reasoning: true, thinkingLevel: 'low' },\n [GPT5_6_TERRA_MODEL]: { reasoning: true, thinkingLevel: 'medium' },\n [GPT5_6_SOL_MODEL]: { reasoning: true, thinkingLevel: 'low' },\n};\n\n/** The only models the wizard may dispatch on. */\nexport const VALID_MODELS: ReadonlySet<string> = new Set(\n Object.keys(MODEL_CAPABILITIES),\n);\n\n/** Whether the value is an allow-listed model. */\nexport function isValidModel(model: unknown): model is string {\n return typeof model === 'string' && VALID_MODELS.has(model);\n}\n\n/** First allow-listed candidate, else throw so a bad id fails loud. */\nexport function requireKnownModel(\n ...candidates: (string | undefined)[]\n): string {\n for (const c of candidates) if (isValidModel(c)) return c;\n throw new Error(\n `No valid model to dispatch on (tried ${JSON.stringify(candidates)}). ` +\n `Allowed: ${[...VALID_MODELS].join(', ')}.`,\n );\n}\n\n/**\n * Default for a model not in the table: reasoning on for anthropic-messages\n * models, off for openai-completions — the non-reasoning openai models reject\n * reasoning effort, so off is the safe default (a reasoning openai model opts\n * back in via the table above). Transport is inferred the same way the pi\n * harness infers it (`openai/` prefix → openai-completions).\n */\nfunction defaultCaps(modelId: string): ModelCapabilities {\n return { reasoning: !modelId.startsWith('openai/') };\n}\n\n/**\n * Scan-triage classifier per harness: the cheapest tier of the line that harness\n * already speaks. Undated ids on purpose — triage is a boolean classifier, so it\n * should follow the current release rather than pin one, and these are not\n * dispatchable agent models (absent from MODEL_CAPABILITIES by design).\n */\nexport const TRIAGE_MODELS: Record<Harness, string> = {\n [Harness.anthropic]: HAIKU_TRIAGE_MODEL,\n [Harness.pi]: GPT5_6_LUNA_MODEL,\n};\n\nexport function triageModelFor(harness: Harness): string {\n return TRIAGE_MODELS[harness];\n}\n\n/**\n * Capabilities for a gateway model id, table override then transport default.\n * `effortOverride` is a switchboard-resolved effort (e.g. from a pi effort\n * flag); it applies only when the model reasons at all — a non-reasoning model\n * rejects reasoning effort, so the override is dropped.\n */\nexport function modelCapabilities(\n modelId: string,\n effortOverride?: EffortLevel,\n): ModelCapabilities {\n const caps = MODEL_CAPABILITIES[modelId] ?? defaultCaps(modelId);\n if (caps.reasoning && effortOverride) {\n return { ...caps, thinkingLevel: effortOverride };\n }\n return caps;\n}\n","/**\n * Small shared primitives for on-disk ledgers: an atomic JSON writer and a\n * single-chain async mutex. Used by the audit tools and by the orchestrator\n * queue. Lifted here so both share one implementation.\n */\nimport * as fs from 'fs';\n\n/**\n * Atomically write JSON: write to a `.tmp` file then rename over the target. The\n * rename bumps the file's mtime in one step, which is what a file watcher polls.\n */\nexport function writeJsonAtomic(targetPath: string, data: unknown): void {\n const tmpPath = `${targetPath}.tmp`;\n fs.writeFileSync(tmpPath, JSON.stringify(data, null, 2), 'utf8');\n fs.renameSync(tmpPath, targetPath);\n}\n\n/**\n * A single async mutex. Serializes read-modify-write cycles so concurrent callers\n * (parallel task agents, audit tool calls) never interleave a mutation.\n */\nexport function makeMutex() {\n let chain: Promise<unknown> = Promise.resolve();\n return async function run<T>(fn: () => Promise<T> | T): Promise<T> {\n const next = chain.then(() => fn());\n chain = next.catch(() => undefined);\n return next;\n };\n}\n","/**\n * The orchestrator task queue.\n *\n * In memory, synchronous, single-owner: one Node process drives the run, so\n * there is no locking. The queue imposes no execution policy — `nextRunnable`\n * returns every pending task whose dependencies are satisfied, and how many of\n * those run at once is decided by the task graph, not the queue.\n *\n * Every transition rewrites `<installDir>/.posthog-wizard-cache/queue.json`, a\n * small file holding the whole queue, handoffs included. It is the run's log\n * and the report's source. The whole cache folder is run-scoped and wiped when\n * the run ends.\n */\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { randomUUID } from 'crypto';\nimport { writeJsonAtomic } from '@utils/atomic-ledger';\nimport { analytics } from '@utils/analytics';\n\nexport const TaskStatus = {\n Pending: 'pending',\n Running: 'running',\n Done: 'done',\n Skipped: 'not needed',\n Failed: 'failed',\n} as const;\n\nexport type TaskStatus = (typeof TaskStatus)[keyof typeof TaskStatus];\n\nexport interface QueuedTask {\n id: string;\n type: string;\n /** Human-readable label for the TUI, set by the enqueuing agent. */\n label?: string;\n status: TaskStatus;\n /**\n * Ids of tasks that must finish before this one runs. Ids are generated at\n * enqueue and dependsOn is never mutated, so a task can only depend on tasks\n * created before it — the graph is a DAG by construction, cycles cannot\n * form. Unknown ids are rejected by the enqueue_task guard.\n */\n dependsOn: string[];\n inputs: Record<string, unknown>;\n model?: string;\n attempts: number;\n maxAttempts: number;\n /** The structured handoff the task reported on completion. */\n handoff?: TaskHandoff;\n /** 'orchestrator' for seeded tasks, or the id of the task that enqueued this one. */\n enqueuedBy: string;\n /** Wizard-seeded only: terminal failure unblocks dependents and never fails the run. */\n optional?: boolean;\n createdAt: string;\n startedAt?: string;\n finishedAt?: string;\n error?: { type: string; message: string };\n}\n\nexport interface QueueFile {\n version: 1;\n runId: string;\n tasks: QueuedTask[];\n}\n\n/** The structured handoff a task leaves for the next agent. */\nexport interface TaskHandoff {\n goals: string;\n did: string;\n forNextAgent: string;\n filesTouched?: string[];\n /** How the agent knows it worked — what it ran or observed. */\n evidence?: string;\n /** What the agent assumed about the app and could not verify. */\n assumptions?: string;\n /** A one-line summary of any unresolved conflict, surfaced in the outro. */\n conflict?: string;\n /** A finished section for the run's report, written by the task that owns the subject. */\n reportSection?: string;\n}\n\nexport interface EnqueueInput {\n type: string;\n label?: string;\n inputs?: Record<string, unknown>;\n dependsOn?: string[];\n model?: string;\n maxAttempts?: number;\n enqueuedBy?: string;\n optional?: boolean;\n}\n\nexport const QUEUE_DIR_NAME = '.posthog-wizard-cache';\nconst DEFAULT_MAX_ATTEMPTS = 2;\n\nfunction nowIso(): string {\n return new Date().toISOString();\n}\n\n/** Dropped in the cache folder so an orphaned copy explains itself. */\nconst DELETE_ME_FILE = '.DELETE-ME.md';\nconst DELETE_ME_BODY = `# Safe to delete\n\nThis folder contains run artifacts from the PostHog Wizard. This should have\nbeen deleted if the Wizard has finished running. If this wasn't deleted for\nsome reason, you can safely delete the entire \\`${QUEUE_DIR_NAME}/\\` folder.\n`;\n\n/** Every queue transition, in the order it is reflected. */\nexport type TransitionEvent =\n | 'enqueue'\n | 'start'\n | 'complete'\n | 'skip'\n | 'fail'\n | 'requeue';\n\nexport interface QueueStoreOptions {\n /**\n * Called on every transition with the task's post-transition state. The\n * runner uses it for telemetry; the store itself stays analytics-free.\n * Listener errors are reported but cannot break a transition.\n */\n onTransition?: (event: TransitionEvent, task: QueuedTask) => void;\n}\n\nexport class QueueStore {\n private tasks: QueuedTask[] = [];\n private readonly onTransition?: (\n event: TransitionEvent,\n task: QueuedTask,\n ) => void;\n\n readonly runId: string;\n readonly queuePath: string;\n\n constructor(installDir: string, runId: string, opts?: QueueStoreOptions) {\n this.onTransition = opts?.onTransition;\n this.runId = runId;\n const dir = path.join(installDir, QUEUE_DIR_NAME);\n this.queuePath = path.join(dir, 'queue.json');\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(path.join(dir, DELETE_ME_FILE), DELETE_ME_BODY);\n }\n\n // ── Reads ───────────────────────────────────────────────────────────\n\n list(): readonly QueuedTask[] {\n return this.tasks;\n }\n\n get(id: string): QueuedTask | undefined {\n return this.tasks.find((t) => t.id === id);\n }\n\n /**\n * Every pending task whose dependencies are all satisfied (`done` or\n * `skipped`). A skipped dependency does not block downstream work.\n */\n nextRunnable(): QueuedTask[] {\n // A TERMINALLY failed optional dep satisfies like skipped; retryable failure still blocks.\n const doneIds = new Set(\n this.tasks\n .filter(\n (t) =>\n t.status === TaskStatus.Done ||\n t.status === TaskStatus.Skipped ||\n (t.status === TaskStatus.Failed &&\n t.optional === true &&\n t.attempts >= t.maxAttempts),\n )\n .map((t) => t.id),\n );\n return this.tasks.filter(\n (t) =>\n t.status === TaskStatus.Pending &&\n t.dependsOn.every((d) => doneIds.has(d)),\n );\n }\n\n /**\n * True when no task is running and none can be started. Either everything\n * is terminal, or the only pending tasks are blocked by a failed dependency.\n */\n isDrained(): boolean {\n if (this.tasks.some((t) => t.status === TaskStatus.Running)) return false;\n return this.nextRunnable().length === 0;\n }\n\n summary(): Record<TaskStatus, number> & { total: number } {\n const counts: Record<TaskStatus, number> = {\n [TaskStatus.Pending]: 0,\n [TaskStatus.Running]: 0,\n [TaskStatus.Done]: 0,\n [TaskStatus.Skipped]: 0,\n [TaskStatus.Failed]: 0,\n };\n for (const t of this.tasks) counts[t.status] += 1;\n return { ...counts, total: this.tasks.length };\n }\n\n readHandoff(id: string): TaskHandoff | null {\n return this.get(id)?.handoff ?? null;\n }\n\n /** Handoffs of completed tasks of a given type, oldest first. */\n readHandoffsByType(type: string): TaskHandoff[] {\n return this.tasks\n .filter((t) => t.type === type && t.handoff)\n .map((t) => t.handoff as TaskHandoff);\n }\n\n // ── Transitions (each one reflected to queue.json) ──────────────────\n\n enqueue(input: EnqueueInput): QueuedTask {\n const task: QueuedTask = {\n id: randomUUID(),\n type: input.type,\n label: input.label,\n status: TaskStatus.Pending,\n dependsOn: input.dependsOn ?? [],\n inputs: input.inputs ?? {},\n model: input.model,\n attempts: 0,\n maxAttempts: input.maxAttempts ?? DEFAULT_MAX_ATTEMPTS,\n enqueuedBy: input.enqueuedBy ?? 'orchestrator',\n optional: input.optional,\n createdAt: nowIso(),\n };\n this.tasks.push(task);\n this.reflect();\n this.notify('enqueue', task);\n return task;\n }\n\n start(id: string): QueuedTask {\n const t = this.require(id);\n t.status = TaskStatus.Running;\n t.startedAt = nowIso();\n t.attempts += 1;\n this.reflect();\n this.notify('start', t);\n return t;\n }\n\n complete(id: string, handoff?: TaskHandoff): QueuedTask {\n return this.finish(id, TaskStatus.Done, handoff);\n }\n\n /** Terminal: the agent could not do the task. Not done, not failed. */\n skip(id: string, handoff?: TaskHandoff): QueuedTask {\n return this.finish(id, TaskStatus.Skipped, handoff);\n }\n\n fail(\n id: string,\n error: { type: string; message: string },\n handoff?: TaskHandoff,\n ): QueuedTask {\n const t = this.require(id);\n t.error = error;\n return this.finish(id, TaskStatus.Failed, handoff);\n }\n\n /** Put a failed/running task back to pending for a retry within the run. */\n requeue(id: string): QueuedTask {\n const t = this.require(id);\n t.status = TaskStatus.Pending;\n t.startedAt = undefined;\n t.finishedAt = undefined;\n this.reflect();\n this.notify('requeue', t);\n return t;\n }\n\n // ── Internals ───────────────────────────────────────────────────────\n\n private finish(\n id: string,\n status: 'done' | 'not needed' | 'failed',\n handoff?: TaskHandoff,\n ): QueuedTask {\n const t = this.require(id);\n if (handoff) t.handoff = handoff;\n t.status = status;\n t.finishedAt = nowIso();\n this.reflect();\n this.notify(\n status === TaskStatus.Done\n ? 'complete'\n : status === TaskStatus.Skipped\n ? 'skip'\n : 'fail',\n t,\n );\n return t;\n }\n\n private reflect(): void {\n const file: QueueFile = {\n version: 1,\n runId: this.runId,\n tasks: this.tasks,\n };\n writeJsonAtomic(this.queuePath, file);\n }\n\n private notify(event: TransitionEvent, task: QueuedTask): void {\n try {\n this.onTransition?.(event, task);\n } catch (error) {\n // A listener must never break a transition, but its failure is a bug.\n analytics.captureException(\n error instanceof Error ? error : new Error(String(error)),\n { step: 'orchestrator_queue_listener', event },\n );\n }\n }\n\n private require(id: string): QueuedTask {\n const t = this.get(id);\n if (!t) throw new Error(`No task ${id} in the queue`);\n return t;\n }\n}\n","/**\n * Orchestrator MCP tools, registered into the existing `wizard-tools` server when\n * a queue is present. They let the orchestrator agent and task agents grow the\n * queue, report completion with a structured handoff, and read prior handoffs.\n *\n * The guard logic and the apply functions are plain, exported, and unit-tested.\n * `buildOrchestratorTools` wraps them in the SDK `tool()` shape.\n */\nimport { z } from 'zod';\nimport { analytics } from '@utils/analytics';\nimport {\n isValidModel,\n VALID_MODELS,\n} from '@lib/agent/runner/switchboard/models';\nimport {\n TaskStatus,\n type QueueStore,\n type QueuedTask,\n type TaskHandoff,\n} from './queue';\n\n/** The per-task remark ask, shared by both harnesses' complete_task schemas. */\nexport const REMARK_ASK =\n 'What information or guidance would have been useful to have in the integration prompt or documentation for this task — specifically anything that would have prevented tool failures, erroneous edits, or other wasted turns.';\n\nexport interface OrchestratorToolsContext {\n store: QueueStore;\n /** Task types the registry knows about. enqueue_task rejects anything else. */\n validTypes: readonly string[];\n /**\n * Types marked `sink: true` — the ones that run last and must therefore\n * depend, transitively, on every other task in the queue. Enqueuing one with\n * an incomplete closure is rejected, so a task the runner seeded before the\n * planner ran can never be left un-awaited.\n */\n sinkTypes?: readonly string[];\n /**\n * The id of the task this tool server is bound to. Each task agent gets its\n * own wizard-tools server, so attribution holds when independent tasks run\n * in parallel. Absent for the seed, which is not a task.\n */\n currentTaskId?: string;\n}\n\nexport interface EnqueueArgs {\n type: string;\n label?: string;\n inputs?: Record<string, unknown>;\n dependsOn?: string[];\n model?: string;\n reason: string;\n}\n\nexport type GuardResult =\n | { ok: true }\n | { ok: false; guard: string; message: string };\n\nfunction stableStringify(value: unknown): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value);\n if (Array.isArray(value)) return `[${value.map(stableStringify).join(',')}]`;\n const entries = Object.entries(value as Record<string, unknown>).sort(\n ([a], [b]) => a.localeCompare(b),\n );\n return `{${entries\n .map(([k, v]) => `${JSON.stringify(k)}:${stableStringify(v)}`)\n .join(',')}}`;\n}\n\nfunction dedupKey(type: string, inputs: Record<string, unknown>): string {\n return `${type}::${stableStringify(inputs)}`;\n}\n\n/**\n * A backstop on total queue size. Tasks can enqueue tasks, so a misbehaving\n * type could grow the queue without bound. Keeping the graph small is the job\n * of good agent and skill design, not this number — it only stops a runaway.\n * The real flow is ~9 tasks, so this sits well clear of it.\n */\nconst MAX_QUEUE_TASKS = 30;\n\n/** Every task id reachable from `roots` through dependsOn edges, roots included. */\nexport function dependencyClosure(\n store: QueueStore,\n roots: readonly string[],\n): Set<string> {\n const seen = new Set<string>();\n const visit = (id: string): void => {\n if (seen.has(id)) return;\n seen.add(id);\n for (const dep of store.get(id)?.dependsOn ?? []) visit(dep);\n };\n for (const id of roots) visit(id);\n return seen;\n}\n\n/**\n * Tasks a sink would fail to wait for. A sink runs last by definition, so any\n * queued task outside its dependency closure is work whose handoff the sink\n * would miss — the exact failure mode of a task seeded before the planner ran.\n * Empty for a non-sink type, and for a sink that covers everything.\n */\nexport function uncoveredBySink(\n ctx: OrchestratorToolsContext,\n args: Pick<EnqueueArgs, 'type' | 'dependsOn'>,\n): QueuedTask[] {\n if (!ctx.sinkTypes?.includes(args.type)) return [];\n const covered = dependencyClosure(ctx.store, args.dependsOn ?? []);\n return ctx.store.list().filter((t) => !covered.has(t.id));\n}\n\n/**\n * Validate an enqueue. Structural checks only — a real type, real dependencies,\n * a sink that waits for everything, not a literal duplicate, and not past the\n * runaway backstop. How much runs, and in what shape, is the task graph's\n * business, not a knob's.\n */\nexport function checkEnqueueGuards(\n ctx: OrchestratorToolsContext,\n args: EnqueueArgs,\n): GuardResult {\n const tasks = ctx.store.list();\n\n if (tasks.length >= MAX_QUEUE_TASKS) {\n return {\n ok: false,\n guard: 'queue-full',\n message: `The queue already holds ${tasks.length} tasks (cap ${MAX_QUEUE_TASKS}). Refine the existing tasks rather than adding more.`,\n };\n }\n\n if (!ctx.validTypes.includes(args.type)) {\n return {\n ok: false,\n guard: 'unknown-type',\n message: `Unknown task type \"${\n args.type\n }\". Valid types: ${ctx.validTypes.join(', ')}.`,\n };\n }\n\n // Reject an agent pinning a task to a non-allow-listed model.\n if (args.model !== undefined && !isValidModel(args.model)) {\n return {\n ok: false,\n guard: 'invalid-model',\n message: `Model \"${\n args.model\n }\" is not allowed. Omit model to use the task default, or pick one of: ${[\n ...VALID_MODELS,\n ].join(', ')}.`,\n };\n }\n\n for (const dep of args.dependsOn ?? []) {\n if (!ctx.store.get(dep)) {\n return {\n ok: false,\n guard: 'unknown-dep',\n message: `Dependency \"${dep}\" is not a known task id.`,\n };\n }\n }\n\n const uncovered = uncoveredBySink(ctx, args);\n if (uncovered.length > 0) {\n return {\n ok: false,\n guard: 'sink-closure',\n message: `A \"${\n args.type\n }\" task runs last, so it must depend on every other task — directly or through its dependencies. These are not covered: ${uncovered\n .map((t) => `${t.type} (${t.id})`)\n .join(\n ', ',\n )}. Add them to dependsOn, or to a task already in dependsOn, and enqueue it again.`,\n };\n }\n\n const key = dedupKey(args.type, args.inputs ?? {});\n if (\n tasks.some(\n (t) =>\n t.status !== TaskStatus.Failed && dedupKey(t.type, t.inputs) === key,\n )\n ) {\n return {\n ok: false,\n guard: 'dedup',\n message: `A \"${args.type}\" task with these inputs already exists.`,\n };\n }\n\n return { ok: true };\n}\n\nexport type EnqueueResult =\n | { ok: true; task: QueuedTask }\n | { ok: false; guard: string; message: string };\n\nexport function applyEnqueue(\n ctx: OrchestratorToolsContext,\n args: EnqueueArgs,\n): EnqueueResult {\n const guard = checkEnqueueGuards(ctx, args);\n if (!guard.ok) return guard;\n\n const task = ctx.store.enqueue({\n type: args.type,\n label: args.label,\n inputs: args.inputs ?? {},\n dependsOn: args.dependsOn ?? [],\n model: args.model,\n enqueuedBy: ctx.currentTaskId ?? 'orchestrator',\n });\n return { ok: true, task };\n}\n\nexport type CompleteResult = { ok: true } | { ok: false; message: string };\n\nexport function applyComplete(\n ctx: OrchestratorToolsContext,\n args: {\n status: 'done' | 'failed' | 'not needed';\n handoff: TaskHandoff;\n remark?: string;\n },\n): CompleteResult {\n const id = ctx.currentTaskId;\n if (!id) {\n return {\n ok: false,\n message: 'complete_task can only be called by a running task agent.',\n };\n }\n if (args.remark) {\n analytics.wizardCapture('orchestrator remark', {\n task_type: ctx.store.get(id)?.type,\n remark: args.remark,\n });\n }\n if (args.status === TaskStatus.Failed) {\n ctx.store.fail(\n id,\n { type: 'self-reported', message: args.handoff.forNextAgent },\n args.handoff,\n );\n } else if (args.status === TaskStatus.Skipped) {\n ctx.store.skip(id, args.handoff);\n } else {\n ctx.store.complete(id, args.handoff);\n }\n return { ok: true };\n}\n\nexport function applyReadHandoffs(\n ctx: OrchestratorToolsContext,\n args: { type?: string; taskId?: string },\n): TaskHandoff[] {\n if (args.taskId) {\n const h = ctx.store.readHandoff(args.taskId);\n return h ? [h] : [];\n }\n if (args.type) {\n return ctx.store.readHandoffsByType(args.type);\n }\n // No filter: every handoff of a dependency of the current task.\n const currentId = ctx.currentTaskId;\n const current = currentId ? ctx.store.get(currentId) : undefined;\n if (!current) return [];\n return current.dependsOn\n .map((depId) => ctx.store.readHandoff(depId))\n .filter((h): h is TaskHandoff => h !== null);\n}\n\n// Caps each LLM-authored free-text field; queue.json rewrites whole per transition.\nconst HANDOFF_TEXT_MAX = 8_000;\n\nconst HANDOFF_SHAPE = {\n goals: z\n .string()\n .max(HANDOFF_TEXT_MAX)\n .describe('What this task was asked to achieve.'),\n did: z\n .string()\n .max(HANDOFF_TEXT_MAX)\n .describe(\n 'What you actually did — for each file you edited: the change, the intention behind it, and the analytics it should feed (the insight, funnel, or dashboard tile it becomes part of).',\n ),\n forNextAgent: z\n .string()\n .max(HANDOFF_TEXT_MAX)\n .describe('What the next agent should know.'),\n filesTouched: z\n .array(z.string().max(1_000))\n .max(200)\n .optional()\n .describe('Paths of every file you edited.'),\n evidence: z\n .string()\n .max(HANDOFF_TEXT_MAX)\n .optional()\n .describe(\n 'How you know it worked — what you ran or observed, not what you expect.',\n ),\n assumptions: z\n .string()\n .max(HANDOFF_TEXT_MAX)\n .optional()\n .describe('What you assumed about the app and could not verify.'),\n conflict: z\n .string()\n .max(HANDOFF_TEXT_MAX)\n .optional()\n .describe(\n 'A one-line summary of any conflict you could not cleanly resolve (e.g. a dependency or build conflict). Put full detail in your work; this line is surfaced to the user.',\n ),\n reportSection: z\n .string()\n .max(HANDOFF_TEXT_MAX)\n .optional()\n .describe(\n 'A finished markdown section about your work for the run report, written only when your task instructions ask for one. The reporting task includes it as its own section instead of rewriting it.',\n ),\n};\n\ntype SdkTool = (\n name: string,\n description: string,\n // The SDK accepts a plain object of zod fields as the schema.\n schema: Record<string, z.ZodTypeAny>,\n handler: (args: never) => unknown,\n) => unknown;\n\nfunction textResult(text: string, isError = false) {\n return { isError, content: [{ type: 'text' as const, text }] };\n}\n\n/**\n * Build the orchestrator tools in the SDK `tool()` shape. Called from\n * createWizardToolsServer only when a queue context is present.\n */\nexport function buildOrchestratorTools(\n tool: SdkTool,\n ctx: OrchestratorToolsContext,\n): unknown[] {\n const enqueueTask = tool(\n 'enqueue_task',\n 'Add a task to the orchestrator queue. Use it to seed work and to enqueue follow-up work you discover. Keep tasks small and discrete.',\n {\n type: z\n .string()\n .describe(`The task type. One of: ${ctx.validTypes.join(', ')}.`),\n label: z\n .string()\n .optional()\n .describe(\n 'A short label for the UI — the action in a few words (e.g. \"Add the PostHog SDK\", \"Initialize PostHog\"). Leave out file names, class names, and other specifics.',\n ),\n inputs: z.record(z.unknown()).optional(),\n dependsOn: z\n .array(z.string())\n .optional()\n .describe('Task ids that must be done before this task runs.'),\n model: z.string().optional(),\n reason: z.string().describe('One line on why this task is needed.'),\n },\n ((args: EnqueueArgs) => {\n const res = applyEnqueue(ctx, args);\n if (!res.ok) {\n analytics.wizardCapture('orchestrator guard tripped', {\n guard: res.guard,\n type: args.type,\n });\n return textResult(res.message, true);\n }\n return textResult(JSON.stringify({ id: res.task.id }));\n }) as (args: never) => unknown,\n );\n\n const completeTask = tool(\n 'complete_task',\n \"Report the outcome of your task. Always call this exactly once when you finish, with a structured handoff for the next agent. Use status 'not needed' when the task does not apply to this project and you cannot do it (say why in the handoff) — not 'done'.\",\n {\n status: z.enum(['done', 'failed', 'not needed']),\n handoff: z.object(HANDOFF_SHAPE),\n remark: z.string().optional().describe(REMARK_ASK),\n },\n ((args: {\n status: 'done' | 'failed' | 'not needed';\n handoff: TaskHandoff;\n remark?: string;\n }) => {\n const res = applyComplete(ctx, args);\n if (!res.ok) return textResult(res.message, true);\n return textResult('ok');\n }) as (args: never) => unknown,\n );\n\n const readHandoffs = tool(\n 'read_handoffs',\n 'Read structured handoffs from earlier tasks. With no argument, returns the handoffs of your dependencies.',\n {\n type: z.string().optional(),\n taskId: z.string().optional(),\n },\n ((args: { type?: string; taskId?: string }) => {\n const handoffs = applyReadHandoffs(ctx, args);\n return textResult(JSON.stringify(handoffs, null, 2));\n }) as (args: never) => unknown,\n );\n\n return [enqueueTask, completeTask, readHandoffs];\n}\n"],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-B_-DWIq7.js";
|
|
2
|
-
import { f as getUI } from "./debug-
|
|
3
|
-
import { i as readProjectFile, n as boundedGlob } from "./bounded-fs-
|
|
4
|
-
import { a as createVersionBucket, c as detectAllPackageManagers, i as tryGetPackageJson } from "./setup-utils-
|
|
2
|
+
import { f as getUI } from "./debug-BTPYy9p7.js";
|
|
3
|
+
import { i as readProjectFile, n as boundedGlob } from "./bounded-fs-BU2L5mjO.js";
|
|
4
|
+
import { a as createVersionBucket, c as detectAllPackageManagers, i as tryGetPackageJson } from "./setup-utils-iINkc0xu.js";
|
|
5
5
|
import { n as getInstalledPackageVersion, r as hasDeclaredDependency, t as getDeclaredVersion } from "./package-json-CDs1ZVKu.js";
|
|
6
|
-
import { a as gradlePackageManager, c as detectPackageManager$1, d as getPythonVersionBucket, i as detectPythonPackageManagers, l as getPackageManagerName$1, n as composerPackageManager, o as pubPackageManager, r as detectNodePackageManagers, s as swiftPackageManager, t as bundlerPackageManager, u as getPythonVersion } from "./package-manager-
|
|
6
|
+
import { a as gradlePackageManager, c as detectPackageManager$1, d as getPythonVersionBucket, i as detectPythonPackageManagers, l as getPackageManagerName$1, n as composerPackageManager, o as pubPackageManager, r as detectNodePackageManagers, s as swiftPackageManager, t as bundlerPackageManager, u as getPythonVersion } from "./package-manager-z33XHEWO.js";
|
|
7
7
|
import * as semver from "semver";
|
|
8
8
|
import { major, minVersion } from "semver";
|
|
9
9
|
import path from "path";
|
|
@@ -2901,4 +2901,4 @@ const FRAMEWORK_REGISTRY = {
|
|
|
2901
2901
|
//#endregion
|
|
2902
2902
|
export { SPINNER_MESSAGE as i, registry_exports as n, DEFAULT_PACKAGE_INSTALLATION as r, FRAMEWORK_REGISTRY as t };
|
|
2903
2903
|
|
|
2904
|
-
//# sourceMappingURL=registry-
|
|
2904
|
+
//# sourceMappingURL=registry-DF_aKyS0.js.map
|