@posthog/wizard 2.41.0 → 2.42.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-Bvv6Vh5y.js → add-mcp-server-to-clients-fGAJ6wRG.js} +5 -5
- package/dist/{add-mcp-server-to-clients-Bvv6Vh5y.js.map → add-mcp-server-to-clients-fGAJ6wRG.js.map} +1 -1
- package/dist/{agent-interface-CFeI8jzW.js → agent-interface-dPcuJv8g.js} +8 -9
- package/dist/agent-interface-dPcuJv8g.js.map +1 -0
- package/dist/{agent-runner-B0pWHl5j.js → agent-runner-3bDJ_WLl.js} +120 -63
- package/dist/agent-runner-3bDJ_WLl.js.map +1 -0
- package/dist/analytics-B33Hy7zS.js +2 -0
- package/dist/{analytics-C1qxjbYZ.js → analytics-jQRtyqzG.js} +5 -2
- package/dist/analytics-jQRtyqzG.js.map +1 -0
- package/dist/{api-CEMR_Aa6.js → api-Bweisj9K.js} +3 -3
- package/dist/{api-CEMR_Aa6.js.map → api-Bweisj9K.js.map} +1 -1
- package/dist/bin.js +66 -65
- package/dist/bin.js.map +1 -1
- package/dist/{ci-install-BBZscv3z.js → ci-install-BoATzVVs.js} +4 -4
- package/dist/{ci-install-BBZscv3z.js.map → ci-install-BoATzVVs.js.map} +1 -1
- package/dist/{debug-BMkCmZdo.js → debug--QPXcpzv.js} +4 -5
- package/dist/{debug-BMkCmZdo.js.map → debug--QPXcpzv.js.map} +1 -1
- package/dist/{debug-DBrsvcym.js → debug-DCQHRXu9.js} +1 -1
- package/dist/{defaults-BxiMLkQY.js → defaults-CeNThA-1.js} +1 -1
- package/dist/{defaults-BxiMLkQY.js.map → defaults-CeNThA-1.js.map} +1 -1
- package/dist/{env-api-key-DDVkPQmo.js → env-api-key-cjD4yfGT.js} +1 -1
- package/dist/{env-api-key-DDVkPQmo.js.map → env-api-key-cjD4yfGT.js.map} +1 -1
- package/dist/{environment-B7DmpnXD.js → environment-Xdauxvph.js} +3 -3
- package/dist/{environment-B7DmpnXD.js.map → environment-Xdauxvph.js.map} +1 -1
- package/dist/{file-utils-BCxAu-vq.js → file-utils-BJhGBl-W.js} +2 -2
- package/dist/{file-utils-BCxAu-vq.js.map → file-utils-BJhGBl-W.js.map} +1 -1
- package/dist/{headless-ui-NFf-5XOW.js → headless-ui-XdCxxQ0b.js} +2 -2
- package/dist/{headless-ui-NFf-5XOW.js.map → headless-ui-XdCxxQ0b.js.map} +1 -1
- package/dist/{interactive-CBrzEFly.js → interactive-CwtUeGJT.js} +2 -2
- package/dist/{interactive-CBrzEFly.js.map → interactive-CwtUeGJT.js.map} +1 -1
- package/dist/{mcp-C7dn0DIC.js → mcp-DIuzSJ8f.js} +15 -19
- package/dist/mcp-DIuzSJ8f.js.map +1 -0
- package/dist/{mcp-prompt-streaming-uXF2xskx.js → mcp-prompt-streaming-CCS2EkfY.js} +8 -10
- package/dist/mcp-prompt-streaming-CCS2EkfY.js.map +1 -0
- package/dist/{non-interactive-CDYGf19o.js → non-interactive-Cjb5uLLn.js} +2 -2
- package/dist/{non-interactive-CDYGf19o.js.map → non-interactive-Cjb5uLLn.js.map} +1 -1
- package/dist/{package-manager-BHAvpGav.js → package-manager-D_05Bmr0.js} +2 -2
- package/dist/{package-manager-BHAvpGav.js.map → package-manager-D_05Bmr0.js.map} +1 -1
- package/dist/{playground-B8OhYzyc.js → playground-BtB7RvUT.js} +26 -21
- package/dist/playground-BtB7RvUT.js.map +1 -0
- package/dist/{posthog-BHbtnNQE.js → posthog-DwKlq0HM.js} +2 -2
- package/dist/posthog-DwKlq0HM.js.map +1 -0
- package/dist/{posthog-integration-G839iLK6.js → posthog-integration-Cw1QDMFi.js} +24 -25
- package/dist/posthog-integration-Cw1QDMFi.js.map +1 -0
- package/dist/{provisioning-BOhuDX6i.js → provisioning-CmpiiTaR.js} +67 -6
- package/dist/provisioning-CmpiiTaR.js.map +1 -0
- package/dist/{registry-CC26CjWO.js → registry-DPriFJQI.js} +4 -4
- package/dist/{registry-CC26CjWO.js.map → registry-DPriFJQI.js.map} +1 -1
- package/dist/{security-wlqqLk44.js → security-DJrWWO0M.js} +4 -4
- package/dist/{security-wlqqLk44.js.map → security-DJrWWO0M.js.map} +1 -1
- package/dist/{setup-utils-NwB2Qj6N.js → setup-utils-C8yipMUt.js} +137 -32
- package/dist/setup-utils-C8yipMUt.js.map +1 -0
- package/dist/{start-tui-DQndpyTU.js → start-tui-BMZL7mKh.js} +33 -30
- package/dist/start-tui-BMZL7mKh.js.map +1 -0
- package/dist/{steps-CC_Ge4sR.js → steps-Dhq5VReA.js} +7 -7
- package/dist/{steps-CC_Ge4sR.js.map → steps-Dhq5VReA.js.map} +1 -1
- package/dist/{store-1-pQpHlY.js → store-Bu1xO0_5.js} +5 -5
- package/dist/{store-1-pQpHlY.js.map → store-Bu1xO0_5.js.map} +1 -1
- package/dist/{subagent-FMDybA8X.js → subagent-mVY-kDU0.js} +2 -2
- package/dist/{subagent-FMDybA8X.js.map → subagent-mVY-kDU0.js.map} +1 -1
- package/dist/{task-stream-d-R9J0g4.js → task-stream-Ne-9ZOnf.js} +3 -3
- package/dist/{task-stream-d-R9J0g4.js.map → task-stream-Ne-9ZOnf.js.map} +1 -1
- package/dist/{tasks-BfDJpHgK.js → tasks-2af2kDE3.js} +2 -2
- package/dist/{tasks-BfDJpHgK.js.map → tasks-2af2kDE3.js.map} +1 -1
- package/dist/{telemetry-CcysC4ji.js → telemetry-wGk3UsDw.js} +3 -3
- package/dist/{telemetry-CcysC4ji.js.map → telemetry-wGk3UsDw.js.map} +1 -1
- package/dist/{terminal-CWpmzTgT.js → terminal-CnYduoIp.js} +49 -25
- package/dist/terminal-CnYduoIp.js.map +1 -0
- package/dist/{tools-BsOywKLp.js → tools-BTq5sLH9.js} +4 -4
- package/dist/{tools-BsOywKLp.js.map → tools-BTq5sLH9.js.map} +1 -1
- package/dist/{types-evL_rPob.js → types-y3HkjtSq.js} +1 -1
- package/dist/{types-evL_rPob.js.map → types-y3HkjtSq.js.map} +1 -1
- package/dist/{wizard-abort-56bo4Zhs.js → wizard-abort-CSMnla3D.js} +4 -4
- package/dist/{wizard-abort-56bo4Zhs.js.map → wizard-abort-CSMnla3D.js.map} +1 -1
- package/dist/{wizard-abort-7oUXxutu.js → wizard-abort-D8Lj609C.js} +1 -1
- package/dist/{wizard-session-BoXAZEOf.js → wizard-session-BudcixsA.js} +1 -2
- package/dist/wizard-session-BudcixsA.js.map +1 -0
- package/dist/{wizard-session-C8W_6X0j.js → wizard-session-DXivb7kv.js} +1 -1
- package/dist/{wizard-tools-BXd4PCO3.js → wizard-tools-BBLQk1YC.js} +4 -4
- package/dist/{wizard-tools-BXd4PCO3.js.map → wizard-tools-BBLQk1YC.js.map} +1 -1
- package/dist/wizard-ui-WZ48rUgr.js.map +1 -1
- package/dist/yara-hooks-B42cYxIF.js +2 -0
- package/dist/{yara-hooks-BZmYgr9V.js → yara-hooks-Ciy8d0ok.js} +4 -4
- package/dist/{yara-hooks-BZmYgr9V.js.map → yara-hooks-Ciy8d0ok.js.map} +1 -1
- package/package.json +1 -1
- package/dist/agent-interface-CFeI8jzW.js.map +0 -1
- package/dist/agent-runner-B0pWHl5j.js.map +0 -1
- package/dist/analytics-C1qxjbYZ.js.map +0 -1
- package/dist/analytics-_8xKpUAa.js +0 -2
- package/dist/host-resolution-UZELMVTQ.js +0 -115
- package/dist/host-resolution-UZELMVTQ.js.map +0 -1
- package/dist/mcp-C7dn0DIC.js.map +0 -1
- package/dist/mcp-prompt-streaming-uXF2xskx.js.map +0 -1
- package/dist/playground-B8OhYzyc.js.map +0 -1
- package/dist/posthog-BHbtnNQE.js.map +0 -1
- package/dist/posthog-integration-G839iLK6.js.map +0 -1
- package/dist/provisioning-BOhuDX6i.js.map +0 -1
- package/dist/setup-utils-NwB2Qj6N.js.map +0 -1
- package/dist/start-tui-DQndpyTU.js.map +0 -1
- package/dist/terminal-CWpmzTgT.js.map +0 -1
- package/dist/urls-PfZ1TYOf.js +0 -67
- package/dist/urls-PfZ1TYOf.js.map +0 -1
- package/dist/wizard-session-BoXAZEOf.js.map +0 -1
- package/dist/yara-hooks-D0h7Vu7A.js +0 -2
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"analytics-C1qxjbYZ.js","names":["uuidv4"],"sources":["../src/utils/ci-flag-overrides.ts","../src/utils/analytics.ts"],"sourcesContent":["/**\n * CI-only feature-flag overrides.\n *\n * CI must route deterministically: a run that tests the orchestrator arm says\n * so explicitly instead of depending on a live feature flag someone can edit\n * mid-week. The override env var (see the allowlist in `env.ts`) is a JSON\n * object of flag key → value, merged over whatever PostHog returned.\n *\n * The override path exists only in CI builds (`pnpm build:ci`). Published\n * builds inline NODE_ENV as the literal \"production\", the guards collapse,\n * and tsdown strips the rest from the bundle — and the smoke test asserts the\n * env var names are physically absent from production output (which is also\n * why no comment in this file may spell them out), so this can never quietly\n * become a production surface.\n */\nimport { runtimeEnv } from '@env';\nimport { logToFile } from './debug';\n\nexport function applyCiFlagOverrides(\n flags: Record<string, string>,\n): Record<string, string> {\n // Compared inline (not via env.ts's IS_PRODUCTION_BUILD) so tsdown replaces\n // it with a literal right here and the bundler can prove the rest of this\n // function unreachable in production builds. The smoke test enforces that.\n if (process.env.NODE_ENV === 'production') return flags;\n\n const raw = runtimeEnv('WIZARD_CI_FLAG_OVERRIDES');\n if (!raw) return flags;\n\n let overrides: Record<string, unknown>;\n try {\n overrides = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n // A malformed override is a CI misconfiguration. Fail the run loudly\n // rather than silently testing whatever the live flags happen to say.\n throw new Error(\n 'The CI flag-override env var is not valid JSON (expected {\"flag-key\": value, ...}).',\n );\n }\n\n const merged = { ...flags };\n for (const [key, value] of Object.entries(overrides)) {\n merged[key] = String(value);\n }\n logToFile('[flags] CI overrides applied', overrides);\n return merged;\n}\n\n/**\n * Task types excluded from this run. The exclusion env var (see the allowlist\n * in `env.ts`) is a comma-separated list (e.g. `dashboard`), set by the CI\n * harness that owns the policy — the wizard and the served content stay\n * run-mode agnostic. CI-build only, same as the flag overrides: published\n * builds strip this path.\n */\nexport function ciExcludedTaskTypes(): readonly string[] {\n if (process.env.NODE_ENV === 'production') return [];\n\n const raw = runtimeEnv('WIZARD_CI_EXCLUDE_TASKS');\n if (!raw) return [];\n const types = raw\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean);\n if (types.length > 0) logToFile('[flags] CI task exclusions', types);\n return types;\n}\n","import { PostHog } from 'posthog-node';\nimport {\n ANALYTICS_HOST_URL,\n ANALYTICS_POSTHOG_PUBLIC_PROJECT_WRITE_KEY,\n ANALYTICS_TEAM_TAG,\n} from '@lib/constants';\nimport type { WizardSession } from '@lib/wizard-session';\nimport type { ApiUser } from '@lib/api';\nimport { v4 as uuidv4 } from 'uuid';\nimport { IS_PRODUCTION_BUILD, RUN_SURFACE } from '@env';\nimport { debug, logToFile } from './debug';\nimport { applyCiFlagOverrides } from './ci-flag-overrides';\n\n/**\n * Extract a standard property bag from the current session.\n * Used by store-level analytics and available for ad-hoc captures.\n */\nexport function sessionProperties(\n session: WizardSession,\n): Record<string, unknown> {\n return {\n integration: session.integration,\n detected_framework: session.detectedFrameworkLabel,\n typescript: session.typescript,\n project_id: session.credentials?.projectId,\n discovered_features: session.discoveredFeatures,\n additional_features: session.additionalFeatureQueue,\n run_phase: session.runPhase,\n };\n}\n\nexport function groupsFromUser(\n user: ApiUser | null,\n host: string,\n): Record<string, string> {\n const groups: Record<string, string> = { instance: host };\n if (!user) return groups;\n\n const organizationId = user.organization?.id;\n if (organizationId) groups.organization = organizationId;\n\n const customerId = user.organization?.customer_id;\n if (customerId) groups.customer = customerId;\n\n const projectUuid = user.team?.uuid;\n if (projectUuid) groups.project = projectUuid;\n\n return groups;\n}\n\nexport class Analytics {\n private client: PostHog;\n private tags: Record<string, string | boolean | number | null | undefined> =\n {};\n private distinctId?: string;\n private anonymousId: string;\n private _runId: string;\n private sessionId: string | null = null;\n private appName = 'wizard';\n private activeFlags: Record<string, string> | null = null;\n private groups: Record<string, string> = {};\n private personProperties: Record<string, string> = {};\n\n constructor() {\n this.client = new PostHog(ANALYTICS_POSTHOG_PUBLIC_PROJECT_WRITE_KEY, {\n host: ANALYTICS_HOST_URL,\n flushAt: 1,\n flushInterval: 0,\n enableExceptionAutocapture: true,\n before_send: (event) => {\n if (!event) return event;\n if (Object.keys(this.groups).length > 0) {\n event.groups = { ...this.groups, ...event.groups };\n }\n // Autocaptured exceptions arrive with a random uuid and\n // `$process_person_profile: false` — reattach the run's identity\n // and tags so they land on the same person as everything else.\n if (event.event === '$exception') {\n event.distinctId = this.distinctId ?? this.anonymousId;\n const { $process_person_profile, ...properties } =\n event.properties ?? {};\n void $process_person_profile;\n event.properties = { ...this.tags, ...properties };\n }\n return event;\n },\n });\n\n this.tags = { $app_name: this.appName };\n // Tag every run with its build type so prod / dev / ci / headless segment\n // cleanly in analytics. tsdown inlines IS_PRODUCTION_BUILD to `true` in\n // published builds and `false` for dev/tsx/test runs. Non-interactive runs\n // upgrade this in runWizardCI: dev `--ci` runs to 'ci', published headless\n // runs to 'headless'.\n this.tags.build = IS_PRODUCTION_BUILD ? 'prod' : 'dev';\n\n this.tags.run_surface = RUN_SURFACE;\n\n this.anonymousId = uuidv4();\n\n // One id per process = one id per wizard run, registered in the tag bag\n // so it rides on every capture, exception, and autocaptured exception\n // (all of which merge `this.tags`). Lets you separate two runs by the\n // same logged-in user, who otherwise share one distinct id. Distinct\n // from `anonymousId`, the pre-login *person* id that gets aliased onto\n // the real user at login. `$session_id` is intentionally not set here —\n // it stays null until OAuth completes (see identifyUser).\n this._runId = uuidv4();\n this.tags.run_id = this._runId;\n\n this.distinctId = undefined;\n }\n\n /** Per-process run id, tagged on every event and gateway trace. */\n get runId(): string {\n return this._runId;\n }\n\n /** Build type for this run ('prod' | 'dev' | 'ci' | 'headless') — the same value tagged on every analytics event. */\n get build(): string {\n return String(this.tags.build ?? 'dev');\n }\n\n /**\n * Associate the run with the logged-in user, once per id. Identifies them\n * (email, name) and records those person properties so events carry them and\n * feature flags can target the individual user — without the email here the\n * wizard only sends `$app_name`, so email-targeted flags never match. Opens\n * the analytics session on first login, then aliases the run's anonymous id\n * onto the identified person so pre-login events merge in.\n */\n identifyUser(user: ApiUser) {\n const distinctId = user.distinct_id;\n if (this.distinctId === distinctId || distinctId === this.anonymousId) {\n return;\n }\n this.distinctId = distinctId;\n // Open the analytics session on first login. Null until here, so\n // pre-OAuth events carry only `run_id`; from now on every event also\n // carries `$session_id` and PostHog groups the authenticated run into a\n // native Session. Stored in the tag bag so it rides on every subsequent\n // capture and exception.\n if (!this.sessionId) {\n this.sessionId = uuidv4();\n this.tags.$session_id = this.sessionId;\n }\n const props: Record<string, string> = {};\n if (user.email) props.email = user.email;\n const name = [user.first_name, user.last_name]\n .filter(Boolean)\n .join(' ')\n .trim();\n if (name) props.name = name;\n this.personProperties = props;\n this.client.identify({ distinctId, properties: { $set: props } });\n this.client.alias({\n distinctId,\n alias: this.anonymousId,\n });\n // The flag snapshot is per identity. Anything evaluated before login (the\n // intro screen reads the tools-menu flag) was anonymous — drop it so the\n // next read re-evaluates as this user.\n this.activeFlags = null;\n }\n\n /** Person properties sent with flag evaluation: app name plus the user's. */\n private flagPersonProperties(): Record<string, string> {\n return { $app_name: this.appName, ...this.personProperties };\n }\n\n setTag(key: string, value: string | boolean | number | null | undefined) {\n this.tags[key] = value;\n }\n\n setGroups(groups: Record<string, string>) {\n this.groups = groups;\n }\n\n captureException(error: Error, properties: Record<string, unknown> = {}) {\n this.client.captureException(error, this.distinctId ?? this.anonymousId, {\n team: ANALYTICS_TEAM_TAG,\n ...this.tags,\n ...properties,\n });\n }\n\n capture(eventName: string, properties?: Record<string, unknown>) {\n this.client.capture({\n distinctId: this.distinctId ?? this.anonymousId,\n event: eventName,\n properties: {\n ...this.tags,\n ...properties,\n },\n });\n }\n\n /**\n * Capture a wizard-specific event. Automatically prepends \"wizard: \" to the event name.\n * All new wizard analytics should use this method instead of capture() directly.\n */\n wizardCapture(eventName: string, properties?: Record<string, unknown>): void {\n this.capture(`wizard: ${eventName}`, properties);\n }\n\n /**\n * Flush pending events without firing the \"setup wizard finished\" terminal\n * event. Use this from CLI error paths that exit before any wizard run\n * starts — `shutdown()` would inflate the run count with a \"finished\" event\n * for a parse error that never actually ran the wizard.\n */\n async flush(): Promise<void> {\n await this.client.shutdown();\n }\n\n async getFeatureFlag(flagKey: string): Promise<string | boolean | undefined> {\n try {\n const distinctId = this.distinctId ?? this.anonymousId;\n return await this.client.getFeatureFlag(flagKey, distinctId, {\n sendFeatureFlagEvents: true,\n personProperties: this.flagPersonProperties(),\n });\n } catch (error) {\n debug('Failed to get feature flag:', flagKey, error);\n return undefined;\n }\n }\n\n /**\n * Evaluate all feature flags for the current user at the start of a run.\n * Result is cached; subsequent calls in the same run return the same map.\n * Returns flag key -> string value (booleans become 'true'/'false').\n */\n async getAllFlagsForWizard(): Promise<Record<string, string>> {\n if (this.activeFlags !== null) {\n return this.activeFlags;\n }\n const out: Record<string, string> = {};\n try {\n const distinctId = this.distinctId ?? this.anonymousId;\n logToFile('[flags] evaluating as', {\n distinctId,\n identified: this.distinctId !== undefined,\n personProperties: this.flagPersonProperties(),\n });\n const result = await this.client.getAllFlagsAndPayloads(distinctId, {\n personProperties: this.flagPersonProperties(),\n });\n const flags = result.featureFlags ?? {};\n for (const [key, value] of Object.entries(flags)) {\n if (value === undefined) continue;\n out[key] = typeof value === 'boolean' ? String(value) : String(value);\n }\n } catch (error) {\n debug('Failed to get all feature flags:', error);\n this.captureException(\n error instanceof Error ? error : new Error(String(error)),\n { step: 'get_all_flags' },\n );\n }\n // Outside the fetch guard on purpose: a malformed CI override must fail\n // the run loudly, and a valid one applies even when the fetch failed —\n // CI routing stays deterministic either way.\n this.activeFlags = applyCiFlagOverrides(out);\n logToFile('[flags] evaluated', this.activeFlags);\n return this.activeFlags;\n }\n\n async shutdown(status: 'success' | 'error' | 'cancelled') {\n if (Object.keys(this.tags).length === 0) {\n return;\n }\n\n this.client.capture({\n distinctId: this.distinctId ?? this.anonymousId,\n event: 'setup wizard finished',\n properties: {\n // Flat for filtering; the nested `tags` snapshot stays for back-compat.\n ...this.tags,\n run_id: this._runId,\n ...(this.sessionId ? { $session_id: this.sessionId } : {}),\n status,\n tags: this.tags,\n },\n });\n\n await this.client.shutdown();\n }\n}\n\nexport const analytics = new Analytics();\n"],"mappings":"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"}
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import { pt as runtimeEnv } from "./debug-BMkCmZdo.js";
|
|
2
|
-
import { i as getLlmGatewayUrl, n as getCloudUrl, o as getUiHostFromHost, r as getHost, s as resolveBaseUrl, t as detectRegion } from "./urls-PfZ1TYOf.js";
|
|
3
|
-
//#region src/lib/host-resolution.ts
|
|
4
|
-
/**
|
|
5
|
-
* HostResolution — the single, immutable snapshot of where the wizard talks to
|
|
6
|
-
* PostHog for one run.
|
|
7
|
-
*
|
|
8
|
-
* One cloud region (or a pinned `--base-url`) implies a whole family of hosts:
|
|
9
|
-
* the event-ingestion/API host, the user-facing web app host, the CDN asset
|
|
10
|
-
* host, the LLM gateway, and the MCP server. Rather than re-deriving each of
|
|
11
|
-
* these at every call site and threading `region` + `baseUrl` around as loose
|
|
12
|
-
* params, resolve once at auth time and pass this frozen object around — read
|
|
13
|
-
* the property you need.
|
|
14
|
-
*
|
|
15
|
-
* The actual region→URL math (and the `--base-url` override) lives in
|
|
16
|
-
* `@utils/urls`; this class is a thin, immutable façade over those resolvers so
|
|
17
|
-
* the override flows through every field without callers having to know about
|
|
18
|
-
* it. The OAuth-server URL stays in `@utils/urls` (`getOAuthUrl`) because it is
|
|
19
|
-
* needed *before* a region is known, so it can't come from this post-auth object.
|
|
20
|
-
*/
|
|
21
|
-
const LOCAL_MCP_URL = "http://localhost:8787/mcp";
|
|
22
|
-
const PROD_MCP_URL = "https://mcp.posthog.com/mcp";
|
|
23
|
-
function assetHostFor(region, baseUrl) {
|
|
24
|
-
const override = resolveBaseUrl(baseUrl);
|
|
25
|
-
if (override) return override;
|
|
26
|
-
return region === "eu" ? "https://eu-assets.i.posthog.com" : "https://us-assets.i.posthog.com";
|
|
27
|
-
}
|
|
28
|
-
function assetHostFromApiHost(apiHost) {
|
|
29
|
-
if (apiHost.includes("us.i.posthog.com")) return "https://us-assets.i.posthog.com";
|
|
30
|
-
if (apiHost.includes("eu.i.posthog.com")) return "https://eu-assets.i.posthog.com";
|
|
31
|
-
return apiHost;
|
|
32
|
-
}
|
|
33
|
-
function mcpUrlFor(localMcp) {
|
|
34
|
-
if (localMcp) return LOCAL_MCP_URL;
|
|
35
|
-
return runtimeEnv("MCP_URL") || PROD_MCP_URL;
|
|
36
|
-
}
|
|
37
|
-
var HostResolution = class HostResolution {
|
|
38
|
-
/** The resolved cloud region. `'us'` when a base URL is pinned. */
|
|
39
|
-
region;
|
|
40
|
-
/**
|
|
41
|
-
* Event-ingestion / REST API host (e.g. `https://us.i.posthog.com`, or the
|
|
42
|
-
* pinned `--base-url`). The SDK `host` written into the user's `.env`, the
|
|
43
|
-
* base for the wizard-session REST calls, and the host shown to the agent.
|
|
44
|
-
*/
|
|
45
|
-
apiHost;
|
|
46
|
-
/**
|
|
47
|
-
* User-facing web app host (e.g. `https://us.posthog.com`). Use for any link
|
|
48
|
-
* we hand to the user or open in their browser (dashboards, settings, inbox,
|
|
49
|
-
* deep-link base).
|
|
50
|
-
*/
|
|
51
|
-
appHost;
|
|
52
|
-
/** CDN asset host (e.g. `https://us-assets.i.posthog.com`). */
|
|
53
|
-
assetHost;
|
|
54
|
-
/** PostHog LLM gateway URL the agent SDK authenticates its model calls against. */
|
|
55
|
-
gatewayUrl;
|
|
56
|
-
/**
|
|
57
|
-
* PostHog MCP server URL the agent connects to. Region-independent — the
|
|
58
|
-
* server resolves the user's region from the bearer token — so this is driven
|
|
59
|
-
* only by `--local-mcp` and the `MCP_URL` override, not by region/base-url.
|
|
60
|
-
*/
|
|
61
|
-
mcpUrl;
|
|
62
|
-
constructor(fields) {
|
|
63
|
-
this.region = fields.region;
|
|
64
|
-
this.apiHost = fields.apiHost;
|
|
65
|
-
this.appHost = fields.appHost;
|
|
66
|
-
this.assetHost = fields.assetHost;
|
|
67
|
-
this.gatewayUrl = fields.gatewayUrl;
|
|
68
|
-
this.mcpUrl = fields.mcpUrl;
|
|
69
|
-
Object.freeze(this);
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Canonical path: build the host family from a resolved region. A pinned
|
|
73
|
-
* `--base-url` (via `opts.baseUrl`) wins for every origin; otherwise the
|
|
74
|
-
* region's standard hosts are used. Honors IS_DEV through `resolveBaseUrl`.
|
|
75
|
-
*/
|
|
76
|
-
static fromRegion(region, opts = {}) {
|
|
77
|
-
const apiHost = getHost(region, opts.baseUrl);
|
|
78
|
-
return new HostResolution({
|
|
79
|
-
region,
|
|
80
|
-
apiHost,
|
|
81
|
-
appHost: getCloudUrl(region, opts.baseUrl),
|
|
82
|
-
assetHost: assetHostFor(region, opts.baseUrl),
|
|
83
|
-
gatewayUrl: getLlmGatewayUrl(apiHost),
|
|
84
|
-
mcpUrl: mcpUrlFor(opts.localMcp ?? false)
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Build from an ingestion host string (the provisioning API returns one). The
|
|
89
|
-
* given host is preserved verbatim as `apiHost`; the region and the derived
|
|
90
|
-
* app/asset/gateway hosts are inferred from it.
|
|
91
|
-
*/
|
|
92
|
-
static fromApiHost(apiHost, opts = {}) {
|
|
93
|
-
return new HostResolution({
|
|
94
|
-
region: apiHost.includes("eu.") ? "eu" : "us",
|
|
95
|
-
apiHost,
|
|
96
|
-
appHost: getUiHostFromHost(apiHost),
|
|
97
|
-
assetHost: assetHostFromApiHost(apiHost),
|
|
98
|
-
gatewayUrl: getLlmGatewayUrl(apiHost),
|
|
99
|
-
mcpUrl: mcpUrlFor(opts.localMcp ?? false)
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Resolve the region from an access token (the us/eu probe, skipped when a
|
|
104
|
-
* base URL is pinned), then build the host family. Used after OAuth and after
|
|
105
|
-
* CI-mode API-key auth.
|
|
106
|
-
*/
|
|
107
|
-
static async fromAccessToken(accessToken, opts = {}) {
|
|
108
|
-
const region = opts.region ?? await detectRegion(accessToken, opts.baseUrl);
|
|
109
|
-
return HostResolution.fromRegion(region, opts);
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
//#endregion
|
|
113
|
-
export { mcpUrlFor as n, HostResolution as t };
|
|
114
|
-
|
|
115
|
-
//# sourceMappingURL=host-resolution-UZELMVTQ.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"host-resolution-UZELMVTQ.js","names":[],"sources":["../src/lib/host-resolution.ts"],"sourcesContent":["/**\n * HostResolution — the single, immutable snapshot of where the wizard talks to\n * PostHog for one run.\n *\n * One cloud region (or a pinned `--base-url`) implies a whole family of hosts:\n * the event-ingestion/API host, the user-facing web app host, the CDN asset\n * host, the LLM gateway, and the MCP server. Rather than re-deriving each of\n * these at every call site and threading `region` + `baseUrl` around as loose\n * params, resolve once at auth time and pass this frozen object around — read\n * the property you need.\n *\n * The actual region→URL math (and the `--base-url` override) lives in\n * `@utils/urls`; this class is a thin, immutable façade over those resolvers so\n * the override flows through every field without callers having to know about\n * it. The OAuth-server URL stays in `@utils/urls` (`getOAuthUrl`) because it is\n * needed *before* a region is known, so it can't come from this post-auth object.\n */\n\nimport {\n getHost,\n getCloudUrl,\n getLlmGatewayUrl,\n getUiHostFromHost,\n detectRegion,\n resolveBaseUrl,\n} from '@utils/urls';\nimport { runtimeEnv } from '@env';\nimport type { CloudRegion } from '@utils/types';\n\n// The wizard's client gets CLI mode (a single `exec` tool) by server default,\n// so no mode is pinned; an `MCP_URL` override is taken verbatim.\nconst LOCAL_MCP_URL = 'http://localhost:8787/mcp';\nconst PROD_MCP_URL = 'https://mcp.posthog.com/mcp';\n\n/** Construction-time inputs that aren't implied by the region. */\nexport interface HostResolutionOptions {\n /** `--local-mcp`: point the agent's MCP url at the local dev server. */\n localMcp?: boolean;\n /** `--base-url`: pin every PostHog origin to one URL, bypassing region resolution. */\n baseUrl?: string;\n /** `--region`: trust the explicitly-provided region. */\n region?: CloudRegion;\n}\n\nfunction assetHostFor(region: CloudRegion, baseUrl?: string): string {\n const override = resolveBaseUrl(baseUrl);\n if (override) return override;\n return region === 'eu'\n ? 'https://eu-assets.i.posthog.com'\n : 'https://us-assets.i.posthog.com';\n}\n\nfunction assetHostFromApiHost(apiHost: string): string {\n if (apiHost.includes('us.i.posthog.com')) {\n return 'https://us-assets.i.posthog.com';\n }\n if (apiHost.includes('eu.i.posthog.com')) {\n return 'https://eu-assets.i.posthog.com';\n }\n return apiHost;\n}\n\nexport function mcpUrlFor(localMcp: boolean): string {\n if (localMcp) return LOCAL_MCP_URL;\n return runtimeEnv('MCP_URL') || PROD_MCP_URL;\n}\n\nexport class HostResolution {\n /** The resolved cloud region. `'us'` when a base URL is pinned. */\n readonly region: CloudRegion;\n /**\n * Event-ingestion / REST API host (e.g. `https://us.i.posthog.com`, or the\n * pinned `--base-url`). The SDK `host` written into the user's `.env`, the\n * base for the wizard-session REST calls, and the host shown to the agent.\n */\n readonly apiHost: string;\n /**\n * User-facing web app host (e.g. `https://us.posthog.com`). Use for any link\n * we hand to the user or open in their browser (dashboards, settings, inbox,\n * deep-link base).\n */\n readonly appHost: string;\n /** CDN asset host (e.g. `https://us-assets.i.posthog.com`). */\n readonly assetHost: string;\n /** PostHog LLM gateway URL the agent SDK authenticates its model calls against. */\n readonly gatewayUrl: string;\n /**\n * PostHog MCP server URL the agent connects to. Region-independent — the\n * server resolves the user's region from the bearer token — so this is driven\n * only by `--local-mcp` and the `MCP_URL` override, not by region/base-url.\n */\n readonly mcpUrl: string;\n\n private constructor(fields: {\n region: CloudRegion;\n apiHost: string;\n appHost: string;\n assetHost: string;\n gatewayUrl: string;\n mcpUrl: string;\n }) {\n this.region = fields.region;\n this.apiHost = fields.apiHost;\n this.appHost = fields.appHost;\n this.assetHost = fields.assetHost;\n this.gatewayUrl = fields.gatewayUrl;\n this.mcpUrl = fields.mcpUrl;\n Object.freeze(this);\n }\n\n /**\n * Canonical path: build the host family from a resolved region. A pinned\n * `--base-url` (via `opts.baseUrl`) wins for every origin; otherwise the\n * region's standard hosts are used. Honors IS_DEV through `resolveBaseUrl`.\n */\n static fromRegion(\n region: CloudRegion,\n opts: HostResolutionOptions = {},\n ): HostResolution {\n const apiHost = getHost(region, opts.baseUrl);\n return new HostResolution({\n region,\n apiHost,\n appHost: getCloudUrl(region, opts.baseUrl),\n assetHost: assetHostFor(region, opts.baseUrl),\n gatewayUrl: getLlmGatewayUrl(apiHost),\n mcpUrl: mcpUrlFor(opts.localMcp ?? false),\n });\n }\n\n /**\n * Build from an ingestion host string (the provisioning API returns one). The\n * given host is preserved verbatim as `apiHost`; the region and the derived\n * app/asset/gateway hosts are inferred from it.\n */\n static fromApiHost(\n apiHost: string,\n opts: Pick<HostResolutionOptions, 'localMcp'> = {},\n ): HostResolution {\n const region: CloudRegion = apiHost.includes('eu.') ? 'eu' : 'us';\n return new HostResolution({\n region,\n apiHost,\n appHost: getUiHostFromHost(apiHost),\n assetHost: assetHostFromApiHost(apiHost),\n gatewayUrl: getLlmGatewayUrl(apiHost),\n mcpUrl: mcpUrlFor(opts.localMcp ?? false),\n });\n }\n\n /**\n * Resolve the region from an access token (the us/eu probe, skipped when a\n * base URL is pinned), then build the host family. Used after OAuth and after\n * CI-mode API-key auth.\n */\n static async fromAccessToken(\n accessToken: string,\n opts: HostResolutionOptions = {},\n ): Promise<HostResolution> {\n const region =\n opts.region ?? (await detectRegion(accessToken, opts.baseUrl));\n return HostResolution.fromRegion(region, opts);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA+BA,MAAM,gBAAgB;AACtB,MAAM,eAAe;AAYrB,SAAS,aAAa,QAAqB,SAA0B;CACnE,MAAM,WAAW,eAAe,QAAQ;AACxC,KAAI,SAAU,QAAO;AACrB,QAAO,WAAW,OACd,oCACA;;AAGN,SAAS,qBAAqB,SAAyB;AACrD,KAAI,QAAQ,SAAS,mBAAmB,CACtC,QAAO;AAET,KAAI,QAAQ,SAAS,mBAAmB,CACtC,QAAO;AAET,QAAO;;AAGT,SAAgB,UAAU,UAA2B;AACnD,KAAI,SAAU,QAAO;AACrB,QAAO,WAAW,UAAU,IAAI;;AAGlC,IAAa,iBAAb,MAAa,eAAe;;CAE1B;;;;;;CAMA;;;;;;CAMA;;CAEA;;CAEA;;;;;;CAMA;CAEA,YAAoB,QAOjB;AACD,OAAK,SAAS,OAAO;AACrB,OAAK,UAAU,OAAO;AACtB,OAAK,UAAU,OAAO;AACtB,OAAK,YAAY,OAAO;AACxB,OAAK,aAAa,OAAO;AACzB,OAAK,SAAS,OAAO;AACrB,SAAO,OAAO,KAAK;;;;;;;CAQrB,OAAO,WACL,QACA,OAA8B,EAAE,EAChB;EAChB,MAAM,UAAU,QAAQ,QAAQ,KAAK,QAAQ;AAC7C,SAAO,IAAI,eAAe;GACxB;GACA;GACA,SAAS,YAAY,QAAQ,KAAK,QAAQ;GAC1C,WAAW,aAAa,QAAQ,KAAK,QAAQ;GAC7C,YAAY,iBAAiB,QAAQ;GACrC,QAAQ,UAAU,KAAK,YAAY,MAAM;GAC1C,CAAC;;;;;;;CAQJ,OAAO,YACL,SACA,OAAgD,EAAE,EAClC;AAEhB,SAAO,IAAI,eAAe;GACxB,QAF0B,QAAQ,SAAS,MAAM,GAAG,OAAO;GAG3D;GACA,SAAS,kBAAkB,QAAQ;GACnC,WAAW,qBAAqB,QAAQ;GACxC,YAAY,iBAAiB,QAAQ;GACrC,QAAQ,UAAU,KAAK,YAAY,MAAM;GAC1C,CAAC;;;;;;;CAQJ,aAAa,gBACX,aACA,OAA8B,EAAE,EACP;EACzB,MAAM,SACJ,KAAK,UAAW,MAAM,aAAa,aAAa,KAAK,QAAQ;AAC/D,SAAO,eAAe,WAAW,QAAQ,KAAK"}
|
package/dist/mcp-C7dn0DIC.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-C7dn0DIC.js","names":[],"sources":["../src/lib/agent/runner/harness/pi/mcp.ts"],"sourcesContent":["/**\n * Wire the real PostHog MCP into the pi backend (#10). pi has no built-in MCP,\n * but `pi-mcp-adapter` is pi's own MCP extension — we load it the way pi itself\n * does, with `jiti` (pi's runtime `.ts` loader, already a transitive dep). The\n * adapter connects to the same hosted MCP the anthropic path uses (`boot.mcpUrl`).\n *\n * To match the anthropic path (which has `dashboard-create` etc. as first-class\n * tools), we pre-warm the adapter's metadata cache by connecting once and then\n * register the dashboard/insight/query tools as DIRECT tools — so the agent\n * calls them in one step instead of through the fragile `mcp` proxy search.\n *\n * The bearer token is passed by env-var NAME (`bearerTokenEnv`), so it lives only\n * in the wizard process for the adapter's in-process client. It is never written\n * to disk and never reaches pi's (env-scrubbed) tool subprocesses.\n */\n\nimport fs from 'fs';\nimport path from 'path';\nimport { createJiti } from 'jiti';\nimport { logToFile } from '@utils/debug';\n\nconst MCP_TOKEN_ENV = 'POSTHOG_MCP_TOKEN';\n/**\n * Which PostHog MCP tools to surface as first-class tools. Only the few the\n * dashboard step needs — creating a dashboard and adding insights to it. The\n * broad `/dashboard|insight|query/` matched ~30 tools, which bloated context\n * (and tripped post-run compaction); the create/add verbs are enough.\n */\nconst DIRECT_TOOL_PATTERN =\n /(dashboard|insight)[-_]?(create)|(create)[-_]?(dashboard|insight)|add[-_]?insight|dashboard[-_]?add/i;\n\nexport interface PostHogMcpSetup {\n /** pi ExtensionFactory to add to the resource loader's `extensionFactories`. */\n extensionFactory: (pi: unknown) => void;\n /** Restore prior config + drop the token env var. Call after the run. */\n cleanup: () => void;\n}\n\nexport async function setupPostHogMcp(opts: {\n agentDir: string;\n mcpUrl: string;\n accessToken: string;\n userAgent: string;\n}): Promise<PostHogMcpSetup> {\n const { agentDir, mcpUrl, accessToken, userAgent } = opts;\n\n process.env[MCP_TOKEN_ENV] = accessToken;\n\n // The adapter discovers servers from <agentDir>/mcp.json. Merge our server in\n // and restore the prior file on cleanup so a user's own config is never lost.\n const configPath = path.join(agentDir, 'mcp.json');\n const previous = fs.existsSync(configPath)\n ? fs.readFileSync(configPath, 'utf8')\n : null;\n\n let config: { mcpServers: Record<string, Record<string, unknown>> } = {\n mcpServers: {},\n };\n if (previous) {\n try {\n config = JSON.parse(previous);\n config.mcpServers ??= {};\n } catch {\n config = { mcpServers: {} };\n }\n }\n const server: Record<string, unknown> = {\n url: mcpUrl,\n auth: 'bearer',\n bearerTokenEnv: MCP_TOKEN_ENV,\n headers: { 'User-Agent': userAgent },\n lifecycle: 'lazy',\n };\n config.mcpServers.posthog = server;\n // No proxy `mcp` tool: the PostHog MCP exposes ~30 tools, and the proxy's\n // search indirection both pollutes context and makes the agent fumble. We\n // register only the curated dashboard/insight tools as direct tools below.\n // (If the warm-connect fails and no direct tools resolve, the adapter\n // re-enables the proxy automatically as a fallback.)\n const settings = (config as { settings?: Record<string, unknown> }).settings;\n (config as { settings?: Record<string, unknown> }).settings = {\n ...settings,\n disableProxyTool: true,\n toolPrefix: 'posthog',\n };\n\n const writeConfig = (): void => {\n fs.mkdirSync(agentDir, { recursive: true });\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');\n };\n writeConfig();\n\n const jiti = createJiti(import.meta.url);\n\n // Pre-warm: connect once, pick the data tools, register them as direct tools.\n // Best-effort — if it fails the run still gets the `mcp` proxy as a fallback.\n try {\n const sm = await jiti.import('pi-mcp-adapter/server-manager.ts');\n const mc = await jiti.import('pi-mcp-adapter/metadata-cache.ts');\n const manager = new sm.McpServerManager();\n try {\n const conn = await manager.connect('posthog', server);\n if (conn.status === 'connected' && conn.tools.length > 0) {\n const direct = conn.tools\n .map((t) => t.name)\n .filter((n) => DIRECT_TOOL_PATTERN.test(n));\n server.directTools = direct.length > 0 ? direct : true;\n writeConfig();\n mc.saveMetadataCache({\n version: 1,\n servers: {\n posthog: {\n configHash: mc.computeServerHash(server),\n tools: mc.serializeTools(conn.tools),\n resources: mc.serializeResources(conn.resources ?? []),\n cachedAt: Date.now(),\n },\n },\n });\n logToFile(\n `[pi-mcp] warmed: ${conn.tools.length} tools, ${\n Array.isArray(server.directTools)\n ? server.directTools.length\n : 'all'\n } direct`,\n );\n }\n } finally {\n await manager.closeAll().catch(() => undefined);\n }\n } catch (err) {\n logToFile(`[pi-mcp] cache warm skipped (proxy fallback): ${String(err)}`);\n }\n\n const mod = await jiti.import('pi-mcp-adapter/index.ts');\n const extensionFactory = ((mod as { default?: unknown }).default ?? mod) as (\n pi: unknown,\n ) => void;\n logToFile(`[pi-mcp] adapter loaded; posthog MCP at ${mcpUrl}`);\n\n const cleanup = (): void => {\n try {\n if (previous != null) fs.writeFileSync(configPath, previous, 'utf8');\n else fs.rmSync(configPath, { force: true });\n } catch (err) {\n logToFile(`[pi-mcp] config cleanup skipped: ${String(err)}`);\n }\n delete process.env[MCP_TOKEN_ENV];\n };\n\n return { extensionFactory, cleanup };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAqBA,MAAM,gBAAgB;;;;;;;AAOtB,MAAM,sBACJ;AASF,eAAsB,gBAAgB,MAKT;CAC3B,MAAM,EAAE,UAAU,QAAQ,aAAa,cAAc;AAErD,SAAQ,IAAI,iBAAiB;CAI7B,MAAM,aAAa,KAAK,KAAK,UAAU,WAAW;CAClD,MAAM,WAAW,GAAG,WAAW,WAAW,GACtC,GAAG,aAAa,YAAY,OAAO,GACnC;CAEJ,IAAI,SAAkE,EACpE,YAAY,EAAE,EACf;AACD,KAAI,SACF,KAAI;AACF,WAAS,KAAK,MAAM,SAAS;AAC7B,SAAO,eAAe,EAAE;SAClB;AACN,WAAS,EAAE,YAAY,EAAE,EAAE;;CAG/B,MAAM,SAAkC;EACtC,KAAK;EACL,MAAM;EACN,gBAAgB;EAChB,SAAS,EAAE,cAAc,WAAW;EACpC,WAAW;EACZ;AACD,QAAO,WAAW,UAAU;CAM5B,MAAM,WAAY,OAAkD;AACnE,QAAkD,WAAW;EAC5D,GAAG;EACH,kBAAkB;EAClB,YAAY;EACb;CAED,MAAM,oBAA0B;AAC9B,KAAG,UAAU,UAAU,EAAE,WAAW,MAAM,CAAC;AAC3C,KAAG,cAAc,YAAY,KAAK,UAAU,QAAQ,MAAM,EAAE,EAAE,OAAO;;AAEvE,cAAa;CAEb,MAAM,OAAO,WAAW,OAAO,KAAK,IAAI;AAIxC,KAAI;EACF,MAAM,KAAK,MAAM,KAAK,OAAO,mCAAmC;EAChE,MAAM,KAAK,MAAM,KAAK,OAAO,mCAAmC;EAChE,MAAM,UAAU,IAAI,GAAG,kBAAkB;AACzC,MAAI;GACF,MAAM,OAAO,MAAM,QAAQ,QAAQ,WAAW,OAAO;AACrD,OAAI,KAAK,WAAW,eAAe,KAAK,MAAM,SAAS,GAAG;IACxD,MAAM,SAAS,KAAK,MACjB,KAAK,MAAM,EAAE,KAAK,CAClB,QAAQ,MAAM,oBAAoB,KAAK,EAAE,CAAC;AAC7C,WAAO,cAAc,OAAO,SAAS,IAAI,SAAS;AAClD,iBAAa;AACb,OAAG,kBAAkB;KACnB,SAAS;KACT,SAAS,EACP,SAAS;MACP,YAAY,GAAG,kBAAkB,OAAO;MACxC,OAAO,GAAG,eAAe,KAAK,MAAM;MACpC,WAAW,GAAG,mBAAmB,KAAK,aAAa,EAAE,CAAC;MACtD,UAAU,KAAK,KAAK;MACrB,EACF;KACF,CAAC;AACF,cACE,oBAAoB,KAAK,MAAM,OAAO,UACpC,MAAM,QAAQ,OAAO,YAAY,GAC7B,OAAO,YAAY,SACnB,MACL,SACF;;YAEK;AACR,SAAM,QAAQ,UAAU,CAAC,YAAY,KAAA,EAAU;;UAE1C,KAAK;AACZ,YAAU,iDAAiD,OAAO,IAAI,GAAG;;CAG3E,MAAM,MAAM,MAAM,KAAK,OAAO,0BAA0B;CACxD,MAAM,mBAAqB,IAA8B,WAAW;AAGpE,WAAU,2CAA2C,SAAS;CAE9D,MAAM,gBAAsB;AAC1B,MAAI;AACF,OAAI,YAAY,KAAM,IAAG,cAAc,YAAY,UAAU,OAAO;OAC/D,IAAG,OAAO,YAAY,EAAE,OAAO,MAAM,CAAC;WACpC,KAAK;AACZ,aAAU,oCAAoC,OAAO,IAAI,GAAG;;AAE9D,SAAO,QAAQ,IAAI;;AAGrB,QAAO;EAAE;EAAkB;EAAS"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-prompt-streaming-uXF2xskx.js","names":[],"sources":["../src/lib/agent/mcp-prompt-streaming.ts"],"sourcesContent":["/**\n * Streaming prompt runner for the McpSuggestedPromptsScreen.\n *\n * Calls the Claude Agent SDK's `query()` directly with just the PostHog\n * MCP server configured — no skills, no sandbox, no settings sources,\n * no wizard-tools. This is the lightweight cousin of `runAgent` in\n * `agent-interface.ts`: same SDK, much narrower surface, suitable for\n * \"user asked a question, show the answer\" interactions.\n *\n * The function is an async generator that yields `AgentChunk`s extracted\n * from the SDK's message stream. Callers (the screen) consume them via\n * `for await (...)` and render as they arrive.\n */\n\nimport type { AgentChunk } from '@ui/tui/services/mcp-suggested-prompts-services';\nimport type { Credentials } from '@lib/wizard-session';\nimport { DEFAULT_AGENT_MODEL, WIZARD_USER_AGENT } from '@lib/constants';\nimport { HostResolution, mcpUrlFor } from '@lib/host-resolution';\nimport { logToFile } from '@utils/debug';\nimport { buildAgentEnv } from '@lib/agent/agent-interface';\nimport { sanitizeAgentSubprocessEnv } from '@lib/agent/agent-env-isolation';\n\n// Cached SDK module — first call pays the dynamic-import cost; later\n// calls reuse the same module.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nlet _sdkModule: any | null = null;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nasync function loadSdk(): Promise<any> {\n if (!_sdkModule) {\n _sdkModule = await import('@anthropic-ai/claude-agent-sdk');\n }\n return _sdkModule;\n}\n\nconst MODEL = DEFAULT_AGENT_MODEL;\n\n// Bounded turn count so a single prompt can't loop forever on the\n// user's nickel. 20 gives the agent room for non-trivial multi-step\n// chains (multi-tool reads → reason → write → verify → summarize) while\n// still capping runaway loops. Worth tuning down once we see real\n// telemetry on average turn counts per prompt.\nconst MAX_TURNS = 30;\n\n// One MCP url for every region: the server resolves the user's region from\n// the bearer token, so the EU subdomain (a Claude Code OAuth workaround) is\n// not needed here.\nfunction resolveMcpUrl(): string {\n return mcpUrlFor(false);\n}\n\n/**\n * Extract a short, single-line summary from an arbitrary value. Used\n * for tool-call args and tool-result bodies so the screen has something\n * compact to render.\n */\nfunction summarize(value: unknown, maxLen = 120): string {\n if (value == null) return '';\n let text: string;\n if (typeof value === 'string') text = value;\n else {\n try {\n text = JSON.stringify(value);\n } catch {\n text = String(value);\n }\n }\n text = text.replace(/\\s+/g, ' ').trim();\n if (text.length > maxLen) text = text.slice(0, maxLen - 1) + '…';\n return text;\n}\n\n/**\n * Convert one SDK message into zero or more AgentChunks. Mirrors the\n * subset of message shapes the wizard's main runAgent middleware\n * handles, but narrowed to just the kinds the screen needs to render.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction messageToChunks(message: any): AgentChunk[] {\n const chunks: AgentChunk[] = [];\n\n if (message?.type === 'assistant') {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const content = message.message?.content;\n if (Array.isArray(content)) {\n for (const block of content) {\n if (!block || typeof block !== 'object') continue;\n const type = (block as { type?: string }).type;\n if (type === 'text') {\n const text = (block as { text?: string }).text ?? '';\n if (text) chunks.push({ kind: 'text', text });\n } else if (type === 'tool_use') {\n const name = (block as { name?: string }).name ?? 'tool';\n const input = (block as { input?: unknown }).input;\n chunks.push({\n kind: 'tool-call',\n toolName: name,\n detail: summarize(input),\n });\n }\n }\n }\n }\n\n if (message?.type === 'user') {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const content = message.message?.content;\n if (Array.isArray(content)) {\n for (const block of content) {\n if (!block || typeof block !== 'object') continue;\n const type = (block as { type?: string }).type;\n if (type === 'tool_result') {\n const detail = summarize((block as { content?: unknown }).content);\n chunks.push({ kind: 'tool-result', toolName: 'tool', detail });\n }\n }\n }\n }\n\n if (message?.type === 'result') {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const sessionId = (message as { session_id?: string }).session_id;\n chunks.push({ kind: 'done', sessionId });\n }\n\n return chunks;\n}\n\n/**\n * Build a system-prompt append that nudges the agent to fit its response\n * inside the current terminal window. We can't actually constrain Claude\n * — this is a soft cap that the model usually honors. The screen also\n * applies a hard truncation cap as a fallback for non-compliant runs.\n *\n * Core principle nudged at the model: TALL CONTENT IS BAD, WIDE CONTENT\n * IS GOOD. Default terminal is 120 columns × 24 rows — that's a lot of\n * horizontal space, not much vertical. Spread data across columns, never\n * stack it down rows when a horizontal layout would work.\n */\nfunction buildTerminalFitPrompt(): string {\n const cols = process.stdout.columns ?? 120;\n const rows = process.stdout.rows ?? 24;\n // Reserve rows for wizard chrome (title, status, hint, margins).\n const messageBudget = Math.max(8, rows - 10);\n\n return [\n `You are responding inside a CLI window that is exactly ${cols} columns wide and ${rows} rows tall. The user CAN'T SCROLL — your entire reply must fit on screen.`,\n ``,\n `LAYOUT PRINCIPLE: tall content is the enemy, wide content is your friend. You have ${cols} columns of horizontal space; use them. Spread data across columns instead of stacking it down rows.`,\n ``,\n `Tables:`,\n `- Max 5 body rows. The prompts the user picks already constrain results to 5 or fewer — honor that and do not pad with extra rows.`,\n `- If a tool result returns more than 5 items, show the top 5 and mention the rest count inline (e.g. \"...and 12 more\").`,\n `- Prefer transposing wide-but-short data (items across columns, metrics down rows) when labels are short.`,\n `- A two-column table with many rows is the tall layout to AVOID.`,\n ``,\n `Other limits:`,\n `- Aim for 3-5 lines of prose. Maximum ${messageBudget} lines total.`,\n `- DO NOT announce what you are about to do. Skip preamble like \"I'll query…\", \"Let me check…\", \"Now I'll…\", \"I'm going to…\". Go straight to running tools and then the answer.`,\n `- Lists: if there are 6+ short items, format them inline (comma-separated), not as a vertical bullet list.`,\n `- For tool results, summarize the 1-3 numbers that matter. Do NOT echo raw JSON or the full payload.`,\n `- Code blocks: no language tag, no leading blank lines.`,\n `- No closing pleasantries (\"let me know if…\", \"feel free to…\"). Stop when the answer is delivered.`,\n `- No section headers unless the response actually has multiple sections.`,\n ``,\n `Naming saved artifacts:`,\n `- Every dashboard, insight, notebook, or annotation you create MUST include \"(wizard MCP tutorial)\" at the end of its title or name field. Examples: \"Weekly signups (wizard MCP tutorial)\", \"Top errors this week (wizard MCP tutorial)\", \"Onboarding analysis (wizard MCP tutorial)\".`,\n `- This applies on both create AND rename calls. If the user asks you to rename a saved artifact, preserve the \"(wizard MCP tutorial)\" suffix unless they explicitly ask you to drop it.`,\n `- Reason: lets the user find / clean up everything this tutorial created from one search in PostHog. Don't skip it — it's the only signal they'll have that an artifact came from the wizard.`,\n ``,\n `Tone & framing:`,\n `- This is a tutorial demoing PostHog (the product the user just installed). You are showing it off, not auditing it. Stay constructive and neutral about PostHog throughout.`,\n `- Don't editorialize about PostHog's reliability, performance, or cost. Describe what the data shows; treat anomalies as the user's data, not a platform issue.`,\n `- If a tool call fails or returns nothing, say \"the query didn't return data — try a different angle\" or similar. Do NOT speculate about outages, gateway issues, MCP problems, or service health.`,\n `- Avoid value-laden phrases like \"worth investigating\", \"concerning\", \"red flag\", \"problematic\", \"suspicious\", \"alarming\" when describing the user's metrics. Stick to what the numbers show; the user draws conclusions.`,\n ].join('\\n');\n}\n\nexport async function* runMcpPromptViaSdk(args: {\n prompt: string;\n credentials: Credentials;\n signal: AbortSignal;\n /** When set, the SDK loads the named session's prior turns as\n * context so the follow-up prompt can reference what the agent\n * already showed. */\n resumeSessionId?: string;\n}): AsyncIterable<AgentChunk> {\n const { prompt, credentials, signal, resumeSessionId } = args;\n\n // Route the SDK's LLM calls through the PostHog LLM gateway, authed\n // with the user's OAuth access token. Set BEFORE loading the SDK in\n // case any in-process code reads env at module init (cached base\n // URLs, OAuth setup, etc.) — same reason `initializeAgent` does this\n // before its query() call. Without these the SDK tries to\n // authenticate directly against Anthropic and 401s with \"Invalid\n // authentication credentials\".\n process.env.CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS = 'true';\n\n // Route through the PostHog LLM gateway, authed with the user's OAuth token.\n // TODO: clean up in #755\n const gatewayUrl = HostResolution.fromApiHost(credentials.host).gatewayUrl;\n process.env.ANTHROPIC_BASE_URL = gatewayUrl;\n process.env.ANTHROPIC_AUTH_TOKEN = credentials.accessToken;\n process.env.CLAUDE_CODE_OAUTH_TOKEN = credentials.accessToken;\n\n logToFile(\n `[runMcpPromptViaSdk] gatewayUrl=${gatewayUrl} tokenPrefix=${\n credentials.accessToken\n ? credentials.accessToken.slice(0, 4) + '***'\n : '(missing)'\n }`,\n );\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const { query } = await loadSdk();\n\n // Bridge external AbortSignal → SDK AbortController.\n const abortController = new AbortController();\n if (signal.aborted) abortController.abort();\n else\n signal.addEventListener('abort', () => abortController.abort(), {\n once: true,\n });\n\n const mcpUrl = resolveMcpUrl();\n logToFile(\n `[runMcpPromptViaSdk] mcpUrl=${mcpUrl} model=${MODEL} resume=${\n resumeSessionId ?? '(none)'\n }`,\n );\n\n // The SDK expects an async generator for the prompt that stays open\n // until the result is received. For a single-turn prompt we yield one\n // user message and then await an abort (which fires when streaming\n // completes or the caller cancels).\n const createPromptStream = async function* () {\n yield {\n type: 'user' as const,\n session_id: '',\n message: { role: 'user' as const, content: prompt },\n parent_tool_use_id: null,\n };\n // Hold the stream open until abort. The SDK closes its end when it\n // sees a `result` message; we close ours via the abortController in\n // the finally block below.\n await new Promise<void>((resolve) => {\n if (abortController.signal.aborted) {\n resolve();\n return;\n }\n abortController.signal.addEventListener('abort', () => resolve(), {\n once: true,\n });\n });\n };\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n const response = query({\n prompt: createPromptStream(),\n options: {\n abortController,\n model: MODEL,\n cwd: process.cwd(),\n permissionMode: 'acceptEdits',\n maxTurns: MAX_TURNS,\n // Match agent-interface.ts — the 1M context beta is what keeps\n // resumed follow-up sessions from truncating after a few turns.\n betas: ['context-1m-2025-08-07'],\n // Only load project-level skills/settings. Without this the SDK\n // defaults to ['user', 'project'] and a user's\n // `~/.claude/settings.json` (apiKeyHelper / env block) can\n // override the OAuth routing we set above.\n settingSources: ['project'],\n // When set, the SDK replays the named session's turns into the\n // new query so the follow-up prompt has full conversation\n // context. Omit on the first prompt for a fresh session.\n ...(resumeSessionId ? { resume: resumeSessionId } : {}),\n // Without `canUseTool` the SDK falls back to \"ask the user\" on\n // every MCP tool call — `permissionMode: 'acceptEdits'` only\n // relaxes Edit/Write, not MCP. Our Ink TUI has no surface to\n // answer that prompt, so the agent would stall mid-stream\n // saying things like \"needs your approval to create dashboard\".\n // The tutorial's whole point is demoing the MCP tools against\n // the user's project, so we auto-allow everything that matches\n // the prefix and deny anything else (defense in depth — the\n // `allowedTools` filter above already enforces this).\n canUseTool: (toolName: string, input: unknown) => {\n if (toolName.startsWith('mcp__posthog-wizard__')) {\n return Promise.resolve({\n behavior: 'allow' as const,\n updatedInput: (input ?? {}) as Record<string, unknown>,\n });\n }\n logToFile(`[runMcpPromptViaSdk] denying non-MCP tool: ${toolName}`);\n return Promise.resolve({\n behavior: 'deny' as const,\n message: `${toolName} is not available in the MCP tutorial — only PostHog MCP tools are permitted.`,\n });\n },\n systemPrompt: {\n type: 'preset',\n preset: 'claude_code',\n append: buildTerminalFitPrompt(),\n },\n mcpServers: {\n 'posthog-wizard': {\n type: 'http',\n url: mcpUrl,\n headers: {\n Authorization: `Bearer ${credentials.accessToken}`,\n 'User-Agent': WIZARD_USER_AGENT,\n },\n // CLI mode's single `exec` tool carries the full command reference\n // on its schema — keep it in context, never deferred behind tool\n // search.\n alwaysLoad: true,\n },\n },\n // Only let the agent use MCP tools — no shell, no file I/O,\n // no Read/Edit/Write. This is a chat-with-MCP run, not a\n // wizard skill execution.\n allowedTools: ['mcp__posthog-wizard__*'],\n env: {\n // Drop the ENTIRE ANTHROPIC_*/CLAUDE_CODE_* namespace from the\n // inherited env so no shell/settings value can silently bypass the\n // PostHog gateway and defeat quota tracking / the OAuth flow; the\n // wizard's own gateway routing is injected fresh below. See\n // agent-env-isolation.ts.\n ...sanitizeAgentSubprocessEnv(process.env),\n // Gateway routing — injected explicitly (set on process.env above;\n // the strip removed them from the inherited copy, so re-add here).\n ANTHROPIC_BASE_URL: process.env.ANTHROPIC_BASE_URL,\n ANTHROPIC_AUTH_TOKEN: process.env.ANTHROPIC_AUTH_TOKEN,\n CLAUDE_CODE_OAUTH_TOKEN: process.env.CLAUDE_CODE_OAUTH_TOKEN,\n CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS: 'true',\n // SDK 0.3.142+ connects MCP servers in the background by\n // default; without this the agent may try to call tools\n // before posthog-wizard is connected on turn 1.\n MCP_CONNECTION_NONBLOCKING: '0',\n // Same Bedrock-fallback + telemetry-friendly headers as the\n // main runner. No wizard metadata or flags for the tutorial\n // — runs are distinguished downstream via posthog.capture\n // calls (program_id + event names), not SDK headers.\n ANTHROPIC_CUSTOM_HEADERS: buildAgentEnv({}, {}),\n },\n },\n });\n\n for await (const message of response as AsyncIterable<unknown>) {\n if (signal.aborted) return;\n for (const chunk of messageToChunks(message)) {\n yield chunk;\n if (chunk.kind === 'done') return;\n }\n }\n } catch (err) {\n const text = err instanceof Error ? err.message : String(err);\n logToFile(`[runMcpPromptViaSdk] error: ${text}`);\n yield { kind: 'error', text };\n } finally {\n // Closes the prompt stream so `query()` shuts down cleanly even if\n // we never saw a 'result' message.\n abortController.abort();\n }\n}\n"],"mappings":"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"}
|