@posthog/wizard 2.2.0 → 2.4.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.
Files changed (65) hide show
  1. package/dist/src/lib/__tests__/agent-interface.test.js +22 -0
  2. package/dist/src/lib/__tests__/agent-interface.test.js.map +1 -1
  3. package/dist/src/lib/agent-interface.d.ts +20 -2
  4. package/dist/src/lib/agent-interface.js +97 -14
  5. package/dist/src/lib/agent-interface.js.map +1 -1
  6. package/dist/src/lib/agent-runner.js +21 -9
  7. package/dist/src/lib/agent-runner.js.map +1 -1
  8. package/dist/src/lib/api.d.ts +4 -4
  9. package/dist/src/lib/constants.d.ts +1 -1
  10. package/dist/src/lib/health-checks/__tests__/health-checks.test.js +11 -4
  11. package/dist/src/lib/health-checks/__tests__/health-checks.test.js.map +1 -1
  12. package/dist/src/lib/health-checks/endpoints.d.ts +1 -0
  13. package/dist/src/lib/health-checks/endpoints.js +3 -1
  14. package/dist/src/lib/health-checks/endpoints.js.map +1 -1
  15. package/dist/src/lib/health-checks/index.d.ts +1 -1
  16. package/dist/src/lib/health-checks/index.js +2 -1
  17. package/dist/src/lib/health-checks/index.js.map +1 -1
  18. package/dist/src/lib/health-checks/readiness.js +12 -3
  19. package/dist/src/lib/health-checks/readiness.js.map +1 -1
  20. package/dist/src/lib/health-checks/types.d.ts +1 -0
  21. package/dist/src/lib/health-checks/types.js.map +1 -1
  22. package/dist/src/lib/version.d.ts +1 -1
  23. package/dist/src/lib/version.js +1 -1
  24. package/dist/src/lib/version.js.map +1 -1
  25. package/dist/src/lib/wizard-session.d.ts +2 -0
  26. package/dist/src/lib/wizard-session.js +1 -0
  27. package/dist/src/lib/wizard-session.js.map +1 -1
  28. package/dist/src/lib/wizard-tools.d.ts +22 -0
  29. package/dist/src/lib/wizard-tools.js +71 -39
  30. package/dist/src/lib/wizard-tools.js.map +1 -1
  31. package/dist/src/steps/add-mcp-server-to-clients/clients/zed.d.ts +6 -6
  32. package/dist/src/ui/logging-ui.d.ts +3 -1
  33. package/dist/src/ui/logging-ui.js +6 -6
  34. package/dist/src/ui/logging-ui.js.map +1 -1
  35. package/dist/src/ui/tui/ink-ui.d.ts +3 -1
  36. package/dist/src/ui/tui/ink-ui.js +5 -2
  37. package/dist/src/ui/tui/ink-ui.js.map +1 -1
  38. package/dist/src/ui/tui/playground/demos/HealthCheckDemo.js +1 -0
  39. package/dist/src/ui/tui/playground/demos/HealthCheckDemo.js.map +1 -1
  40. package/dist/src/ui/tui/router.d.ts +3 -1
  41. package/dist/src/ui/tui/router.js +2 -0
  42. package/dist/src/ui/tui/router.js.map +1 -1
  43. package/dist/src/ui/tui/screen-registry.js +4 -0
  44. package/dist/src/ui/tui/screen-registry.js.map +1 -1
  45. package/dist/src/ui/tui/screens/AuthErrorScreen.d.ts +7 -0
  46. package/dist/src/ui/tui/screens/AuthErrorScreen.js +16 -0
  47. package/dist/src/ui/tui/screens/AuthErrorScreen.js.map +1 -0
  48. package/dist/src/ui/tui/screens/ManagedSettingsScreen.d.ts +13 -0
  49. package/dist/src/ui/tui/screens/ManagedSettingsScreen.js +32 -0
  50. package/dist/src/ui/tui/screens/ManagedSettingsScreen.js.map +1 -0
  51. package/dist/src/ui/tui/screens/SettingsOverrideScreen.d.ts +0 -4
  52. package/dist/src/ui/tui/screens/SettingsOverrideScreen.js +13 -7
  53. package/dist/src/ui/tui/screens/SettingsOverrideScreen.js.map +1 -1
  54. package/dist/src/ui/tui/screens/health/HealthCheckScreen.js +50 -5
  55. package/dist/src/ui/tui/screens/health/HealthCheckScreen.js.map +1 -1
  56. package/dist/src/ui/tui/store.d.ts +4 -1
  57. package/dist/src/ui/tui/store.js +16 -3
  58. package/dist/src/ui/tui/store.js.map +1 -1
  59. package/dist/src/ui/wizard-ui.d.ts +4 -2
  60. package/dist/src/ui/wizard-ui.js.map +1 -1
  61. package/dist/src/utils/__tests__/semver.test.js +45 -3
  62. package/dist/src/utils/__tests__/semver.test.js.map +1 -1
  63. package/dist/src/utils/semver.js +25 -0
  64. package/dist/src/utils/semver.js.map +1 -1
  65. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"wizard-session.js","sourceRoot":"","sources":["../../../src/lib/wizard-session.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * WizardSession — single source of truth for every decision the wizard needs.\n *\n * Populated in layers:\n * CLI args / env vars → populate fields directly\n * Auto-detection → framework, typescript, package manager\n * TUI screens → region, framework disambiguation, etc.\n * OAuth → credentials\n *\n * Business logic reads from the session. Never calls a prompt.\n */\n\nimport type { Integration } from './constants';\nimport type { FrameworkConfig } from './framework-config';\nimport type { WizardReadinessResult } from './health-checks/readiness';\n\nfunction parseProjectIdArg(value: string | undefined): number | undefined {\n if (value === undefined || value === '') return undefined;\n const n = Number(value);\n return Number.isInteger(n) && n > 0 ? n : undefined;\n}\n\nexport type CloudRegion = 'us' | 'eu';\n\n/** Lifecycle phase of the main work (agent run, MCP install, etc.) */\nexport enum RunPhase {\n /** Still gathering input (intro, setup screens) */\n Idle = 'idle',\n /** Main work is in progress */\n Running = 'running',\n /** Main work finished successfully */\n Completed = 'completed',\n /** Main work finished with an error */\n Error = 'error',\n}\n\n/** Features discovered by the feature-discovery subagent */\nexport enum DiscoveredFeature {\n Stripe = 'stripe',\n LLM = 'llm',\n}\n\n/** Additional features the agent can integrate after the main setup */\nexport enum AdditionalFeature {\n LLM = 'llm',\n}\n\n/** Human-readable labels for additional features (used in TUI progress) */\nexport const ADDITIONAL_FEATURE_LABELS: Record<AdditionalFeature, string> = {\n [AdditionalFeature.LLM]: 'LLM analytics',\n};\n\n/** Agent prompts for each additional feature, injected via the stop hook */\nexport const ADDITIONAL_FEATURE_PROMPTS: Record<AdditionalFeature, string> = {\n [AdditionalFeature.LLM]: `Now integrate LLM analytics with PostHog. Use the PostHog MCP server to find the appropriate LLM analytics skill, install it, and follow its workflow. PostHog basics are already installed. Update the setup report markdown file when complete with additions from this task. `,\n};\n\n/** Outcome of the MCP server installation step */\nexport enum McpOutcome {\n NoClients = 'no_clients',\n Skipped = 'skipped',\n Installed = 'installed',\n Failed = 'failed',\n}\n\n/** Outcome kind for the outro screen */\nexport enum OutroKind {\n Success = 'success',\n Error = 'error',\n Cancel = 'cancel',\n}\n\nexport interface OutroData {\n kind: OutroKind;\n message?: string;\n changes?: string[];\n docsUrl?: string;\n continueUrl?: string;\n}\n\nexport interface WizardSession {\n // From CLI args\n debug: boolean;\n forceInstall: boolean;\n installDir: string;\n ci: boolean;\n signup: boolean;\n localMcp: boolean;\n apiKey?: string;\n menu: boolean;\n benchmark: boolean;\n yaraReport: boolean;\n projectId?: number;\n\n // From detection + screens\n setupConfirmed: boolean;\n integration: Integration | null;\n frameworkContext: Record<string, unknown>;\n typescript: boolean;\n\n /** Human-readable label for the detected framework variant (e.g., \"Django with Wagtail CMS\") */\n detectedFrameworkLabel: string | null;\n\n /** True once framework detection has run (whether it found something or not) */\n detectionComplete: boolean;\n\n /** Set when the detected framework version is too old for the wizard */\n unsupportedVersion: {\n current: string;\n minimum: string;\n docsUrl: string;\n } | null;\n\n // From OAuth\n credentials: {\n accessToken: string;\n projectApiKey: string;\n host: string;\n projectId: number;\n } | null;\n\n // Lifecycle\n runPhase: RunPhase;\n loginUrl: string | null;\n\n // Feature discovery\n discoveredFeatures: DiscoveredFeature[];\n llmOptIn: boolean;\n\n // Screen completion\n mcpComplete: boolean;\n mcpOutcome: McpOutcome | null;\n mcpInstalledClients: string[];\n\n // Runtime\n readinessResult: WizardReadinessResult | null;\n outageDismissed: boolean;\n settingsOverrideKeys: string[] | null;\n portConflictProcess: { command: string; pid: string; user: string } | null;\n outroData: OutroData | null;\n\n // Additional features queue (drained via stop hook after main integration)\n additionalFeatureQueue: AdditionalFeature[];\n\n // Resolved framework config (set after integration is known)\n frameworkConfig: FrameworkConfig | null;\n}\n\n/**\n * Build a WizardSession from CLI args, pre-populating whatever is known.\n */\nexport function buildSession(args: {\n debug?: boolean;\n forceInstall?: boolean;\n installDir?: string;\n ci?: boolean;\n signup?: boolean;\n localMcp?: boolean;\n apiKey?: string;\n menu?: boolean;\n integration?: Integration;\n benchmark?: boolean;\n yaraReport?: boolean;\n projectId?: string;\n}): WizardSession {\n return {\n debug: args.debug ?? false,\n forceInstall: args.forceInstall ?? false,\n installDir: args.installDir ?? process.cwd(),\n ci: args.ci ?? false,\n signup: args.signup ?? false,\n localMcp: args.localMcp ?? false,\n apiKey: args.apiKey,\n menu: args.menu ?? false,\n benchmark: args.benchmark ?? false,\n yaraReport: args.yaraReport ?? false,\n projectId: parseProjectIdArg(args.projectId),\n\n setupConfirmed: false,\n integration: args.integration ?? null,\n frameworkContext: {},\n typescript: false,\n detectedFrameworkLabel: null,\n detectionComplete: false,\n unsupportedVersion: null,\n\n runPhase: RunPhase.Idle,\n discoveredFeatures: [],\n llmOptIn: false,\n mcpComplete: false,\n mcpOutcome: null,\n mcpInstalledClients: [],\n loginUrl: null,\n credentials: null,\n readinessResult: null,\n outageDismissed: false,\n settingsOverrideKeys: null,\n portConflictProcess: null,\n outroData: null,\n additionalFeatureQueue: [],\n frameworkConfig: null,\n };\n}\n"]}
1
+ {"version":3,"file":"wizard-session.js","sourceRoot":"","sources":["../../../src/lib/wizard-session.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * WizardSession — single source of truth for every decision the wizard needs.\n *\n * Populated in layers:\n * CLI args / env vars → populate fields directly\n * Auto-detection → framework, typescript, package manager\n * TUI screens → region, framework disambiguation, etc.\n * OAuth → credentials\n *\n * Business logic reads from the session. Never calls a prompt.\n */\n\nimport type { Integration } from './constants';\nimport type { FrameworkConfig } from './framework-config';\nimport type { WizardReadinessResult } from './health-checks/readiness';\nimport type { SettingsConflict } from './agent-interface';\n\nfunction parseProjectIdArg(value: string | undefined): number | undefined {\n if (value === undefined || value === '') return undefined;\n const n = Number(value);\n return Number.isInteger(n) && n > 0 ? n : undefined;\n}\n\nexport type CloudRegion = 'us' | 'eu';\n\n/** Lifecycle phase of the main work (agent run, MCP install, etc.) */\nexport enum RunPhase {\n /** Still gathering input (intro, setup screens) */\n Idle = 'idle',\n /** Main work is in progress */\n Running = 'running',\n /** Main work finished successfully */\n Completed = 'completed',\n /** Main work finished with an error */\n Error = 'error',\n}\n\n/** Features discovered by the feature-discovery subagent */\nexport enum DiscoveredFeature {\n Stripe = 'stripe',\n LLM = 'llm',\n}\n\n/** Additional features the agent can integrate after the main setup */\nexport enum AdditionalFeature {\n LLM = 'llm',\n}\n\n/** Human-readable labels for additional features (used in TUI progress) */\nexport const ADDITIONAL_FEATURE_LABELS: Record<AdditionalFeature, string> = {\n [AdditionalFeature.LLM]: 'LLM analytics',\n};\n\n/** Agent prompts for each additional feature, injected via the stop hook */\nexport const ADDITIONAL_FEATURE_PROMPTS: Record<AdditionalFeature, string> = {\n [AdditionalFeature.LLM]: `Now integrate LLM analytics with PostHog. Use the PostHog MCP server to find the appropriate LLM analytics skill, install it, and follow its workflow. PostHog basics are already installed. Update the setup report markdown file when complete with additions from this task. `,\n};\n\n/** Outcome of the MCP server installation step */\nexport enum McpOutcome {\n NoClients = 'no_clients',\n Skipped = 'skipped',\n Installed = 'installed',\n Failed = 'failed',\n}\n\n/** Outcome kind for the outro screen */\nexport enum OutroKind {\n Success = 'success',\n Error = 'error',\n Cancel = 'cancel',\n}\n\nexport interface OutroData {\n kind: OutroKind;\n message?: string;\n changes?: string[];\n docsUrl?: string;\n continueUrl?: string;\n}\n\nexport interface WizardSession {\n // From CLI args\n debug: boolean;\n forceInstall: boolean;\n installDir: string;\n ci: boolean;\n signup: boolean;\n localMcp: boolean;\n apiKey?: string;\n menu: boolean;\n benchmark: boolean;\n yaraReport: boolean;\n projectId?: number;\n\n // From detection + screens\n setupConfirmed: boolean;\n integration: Integration | null;\n frameworkContext: Record<string, unknown>;\n typescript: boolean;\n\n /** Human-readable label for the detected framework variant (e.g., \"Django with Wagtail CMS\") */\n detectedFrameworkLabel: string | null;\n\n /** True once framework detection has run (whether it found something or not) */\n detectionComplete: boolean;\n\n /** Set when the detected framework version is too old for the wizard */\n unsupportedVersion: {\n current: string;\n minimum: string;\n docsUrl: string;\n } | null;\n\n // From OAuth\n credentials: {\n accessToken: string;\n projectApiKey: string;\n host: string;\n projectId: number;\n } | null;\n\n // Lifecycle\n runPhase: RunPhase;\n loginUrl: string | null;\n\n // Feature discovery\n discoveredFeatures: DiscoveredFeature[];\n llmOptIn: boolean;\n\n // Screen completion\n mcpComplete: boolean;\n mcpOutcome: McpOutcome | null;\n mcpInstalledClients: string[];\n\n // Runtime\n readinessResult: WizardReadinessResult | null;\n outageDismissed: boolean;\n settingsOverrideKeys: string[] | null;\n settingsConflicts: SettingsConflict[] | null;\n portConflictProcess: { command: string; pid: string; user: string } | null;\n outroData: OutroData | null;\n\n // Additional features queue (drained via stop hook after main integration)\n additionalFeatureQueue: AdditionalFeature[];\n\n // Resolved framework config (set after integration is known)\n frameworkConfig: FrameworkConfig | null;\n}\n\n/**\n * Build a WizardSession from CLI args, pre-populating whatever is known.\n */\nexport function buildSession(args: {\n debug?: boolean;\n forceInstall?: boolean;\n installDir?: string;\n ci?: boolean;\n signup?: boolean;\n localMcp?: boolean;\n apiKey?: string;\n menu?: boolean;\n integration?: Integration;\n benchmark?: boolean;\n yaraReport?: boolean;\n projectId?: string;\n}): WizardSession {\n return {\n debug: args.debug ?? false,\n forceInstall: args.forceInstall ?? false,\n installDir: args.installDir ?? process.cwd(),\n ci: args.ci ?? false,\n signup: args.signup ?? false,\n localMcp: args.localMcp ?? false,\n apiKey: args.apiKey,\n menu: args.menu ?? false,\n benchmark: args.benchmark ?? false,\n yaraReport: args.yaraReport ?? false,\n projectId: parseProjectIdArg(args.projectId),\n\n setupConfirmed: false,\n integration: args.integration ?? null,\n frameworkContext: {},\n typescript: false,\n detectedFrameworkLabel: null,\n detectionComplete: false,\n unsupportedVersion: null,\n\n runPhase: RunPhase.Idle,\n discoveredFeatures: [],\n llmOptIn: false,\n mcpComplete: false,\n mcpOutcome: null,\n mcpInstalledClients: [],\n loginUrl: null,\n credentials: null,\n readinessResult: null,\n outageDismissed: false,\n settingsOverrideKeys: null,\n settingsConflicts: null,\n portConflictProcess: null,\n outroData: null,\n additionalFeatureQueue: [],\n frameworkConfig: null,\n };\n}\n"]}
@@ -7,6 +7,28 @@
7
7
  * - detect_package_manager: Detect the project's package manager(s)
8
8
  */
9
9
  import type { PackageManagerDetector } from './package-manager-detection';
10
+ export type SkillEntry = {
11
+ id: string;
12
+ name: string;
13
+ downloadUrl: string;
14
+ };
15
+ export interface SkillMenu {
16
+ categories: Record<string, SkillEntry[]>;
17
+ }
18
+ /**
19
+ * Fetch the skill menu from the skills server.
20
+ * Returns parsed data on success, `null` on failure.
21
+ */
22
+ export declare function fetchSkillMenu(skillsBaseUrl: string): Promise<SkillMenu | null>;
23
+ /**
24
+ * Download and extract a skill.
25
+ * By default installs to `<installDir>/.claude/skills/<id>/`.
26
+ * Pass `skillsRoot` to override the base directory (e.g. `.posthog/skills`).
27
+ */
28
+ export declare function downloadSkill(skillEntry: SkillEntry, installDir: string, skillsRoot?: string): {
29
+ success: boolean;
30
+ error?: string;
31
+ };
10
32
  export interface WizardToolsOptions {
11
33
  /** Root directory of the project being analyzed */
12
34
  workingDirectory: string;
@@ -12,6 +12,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  };
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
14
  exports.WIZARD_TOOL_NAMES = void 0;
15
+ exports.fetchSkillMenu = fetchSkillMenu;
16
+ exports.downloadSkill = downloadSkill;
15
17
  exports.resolveEnvPath = resolveEnvPath;
16
18
  exports.ensureGitignoreCoverage = ensureGitignoreCoverage;
17
19
  exports.parseEnvKeys = parseEnvKeys;
@@ -33,6 +35,63 @@ async function getSDKModule() {
33
35
  return _sdkModule;
34
36
  }
35
37
  // ---------------------------------------------------------------------------
38
+ // Standalone skill helpers (usable before the MCP server is created)
39
+ // ---------------------------------------------------------------------------
40
+ /**
41
+ * Fetch the skill menu from the skills server.
42
+ * Returns parsed data on success, `null` on failure.
43
+ */
44
+ async function fetchSkillMenu(skillsBaseUrl) {
45
+ try {
46
+ const menuUrl = `${skillsBaseUrl}/skill-menu.json`;
47
+ (0, debug_1.logToFile)(`fetchSkillMenu: fetching from ${menuUrl}`);
48
+ const resp = await fetch(menuUrl);
49
+ if (resp.ok) {
50
+ const data = (await resp.json());
51
+ (0, debug_1.logToFile)(`fetchSkillMenu: loaded (${Object.keys(data.categories).length} categories)`);
52
+ return data;
53
+ }
54
+ (0, debug_1.logToFile)(`fetchSkillMenu: failed with HTTP ${resp.status}`);
55
+ return null;
56
+ }
57
+ catch (err) {
58
+ (0, debug_1.logToFile)(`fetchSkillMenu: error: ${err.message}`);
59
+ return null;
60
+ }
61
+ }
62
+ /**
63
+ * Download and extract a skill.
64
+ * By default installs to `<installDir>/.claude/skills/<id>/`.
65
+ * Pass `skillsRoot` to override the base directory (e.g. `.posthog/skills`).
66
+ */
67
+ function downloadSkill(skillEntry, installDir, skillsRoot) {
68
+ const skillDir = skillsRoot
69
+ ? path_1.default.join(installDir, skillsRoot, skillEntry.id)
70
+ : path_1.default.join(installDir, '.claude', 'skills', skillEntry.id);
71
+ const tmpFile = `/tmp/posthog-skill-${skillEntry.id}.zip`;
72
+ try {
73
+ fs_1.default.mkdirSync(skillDir, { recursive: true });
74
+ (0, child_process_1.execFileSync)('curl', ['-sL', skillEntry.downloadUrl, '-o', tmpFile], {
75
+ timeout: 30000,
76
+ });
77
+ (0, child_process_1.execFileSync)('unzip', ['-o', tmpFile, '-d', skillDir], {
78
+ timeout: 30000,
79
+ });
80
+ try {
81
+ fs_1.default.unlinkSync(tmpFile);
82
+ }
83
+ catch {
84
+ /* ignore cleanup errors */
85
+ }
86
+ (0, debug_1.logToFile)(`downloadSkill: installed ${skillEntry.id} from ${skillEntry.downloadUrl}`);
87
+ return { success: true };
88
+ }
89
+ catch (err) {
90
+ (0, debug_1.logToFile)(`downloadSkill: error: ${err.message}`);
91
+ return { success: false, error: err.message };
92
+ }
93
+ }
94
+ // ---------------------------------------------------------------------------
36
95
  // Env file helpers
37
96
  // ---------------------------------------------------------------------------
38
97
  /**
@@ -117,27 +176,16 @@ async function createWizardToolsServer(options) {
117
176
  const { workingDirectory, detectPackageManager, skillsBaseUrl } = options;
118
177
  const sdk = await getSDKModule();
119
178
  const { tool, createSdkMcpServer } = sdk;
179
+ // Pre-fetch skill menu so category names are available in the tool schema
120
180
  let cachedSkillMenu = {};
121
181
  let categoryNames = ['integration'];
122
- try {
123
- const menuUrl = `${skillsBaseUrl}/skill-menu.json`;
124
- (0, debug_1.logToFile)(`wizard-tools: pre-fetching skill menu from ${menuUrl}`);
125
- const resp = await fetch(menuUrl);
126
- if (resp.ok) {
127
- const data = (await resp.json());
128
- cachedSkillMenu = data.categories;
129
- const keys = Object.keys(cachedSkillMenu);
130
- if (keys.length > 0) {
131
- categoryNames = keys;
132
- }
133
- (0, debug_1.logToFile)(`wizard-tools: loaded skill menu (${keys.length} categories)`);
134
- }
135
- else {
136
- (0, debug_1.logToFile)(`wizard-tools: skill menu fetch failed: ${resp.status}`);
137
- }
182
+ const menu = await fetchSkillMenu(skillsBaseUrl);
183
+ if (menu) {
184
+ cachedSkillMenu = menu.categories;
138
185
  }
139
- catch (err) {
140
- (0, debug_1.logToFile)(`wizard-tools: skill menu fetch error: ${err.message}`);
186
+ const keys = Object.keys(cachedSkillMenu);
187
+ if (keys.length > 0) {
188
+ categoryNames = keys;
141
189
  }
142
190
  // -- check_env_keys -------------------------------------------------------
143
191
  const checkEnvKeys = tool('check_env_keys', 'Check which environment variable keys are present or missing in a .env file. Never reveals values.', {
@@ -251,7 +299,7 @@ async function createWizardToolsServer(options) {
251
299
  .string()
252
300
  .describe('Skill ID from the skill menu (e.g., "integration-nextjs-app-router")'),
253
301
  }, (args) => {
254
- if (!/^[a-z0-9][a-z0-9-]*$/.test(args.skillId)) {
302
+ if (!/^[a-z0-9][a-z0-9_-]*$/.test(args.skillId)) {
255
303
  return {
256
304
  content: [
257
305
  {
@@ -276,23 +324,8 @@ async function createWizardToolsServer(options) {
276
324
  isError: true,
277
325
  };
278
326
  }
279
- const skillDir = path_1.default.join(workingDirectory, '.claude', 'skills', args.skillId);
280
- const tmpFile = `/tmp/posthog-skill-${args.skillId}.zip`;
281
- try {
282
- fs_1.default.mkdirSync(skillDir, { recursive: true });
283
- (0, child_process_1.execFileSync)('curl', ['-sL', skill.downloadUrl, '-o', tmpFile], {
284
- timeout: 30000,
285
- });
286
- (0, child_process_1.execFileSync)('unzip', ['-o', tmpFile, '-d', skillDir], {
287
- timeout: 30000,
288
- });
289
- try {
290
- fs_1.default.unlinkSync(tmpFile);
291
- }
292
- catch {
293
- /* ignore cleanup errors */
294
- }
295
- (0, debug_1.logToFile)(`install_skill: installed ${args.skillId} from ${skill.downloadUrl}`);
327
+ const result = downloadSkill(skill, workingDirectory);
328
+ if (result.success) {
296
329
  return {
297
330
  content: [
298
331
  {
@@ -302,13 +335,12 @@ async function createWizardToolsServer(options) {
302
335
  ],
303
336
  };
304
337
  }
305
- catch (err) {
306
- (0, debug_1.logToFile)(`install_skill error: ${err.message}`);
338
+ else {
307
339
  return {
308
340
  content: [
309
341
  {
310
342
  type: 'text',
311
- text: `Error installing skill: ${err.message}`,
343
+ text: `Error installing skill: ${result.error}`,
312
344
  },
313
345
  ],
314
346
  isError: true,
@@ -1 +1 @@
1
- {"version":3,"file":"wizard-tools.js","sourceRoot":"","sources":["../../../src/lib/wizard-tools.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Unified in-process MCP server for the PostHog wizard.\n *\n * Provides tools that run locally (secret values never leave the machine):\n * - check_env_keys: Check which env var keys exist in a .env file\n * - set_env_values: Create/update env vars in a .env file\n * - detect_package_manager: Detect the project's package manager(s)\n */\n\nimport path from 'path';\nimport fs from 'fs';\nimport { execFileSync } from 'child_process';\nimport { z } from 'zod';\nimport { logToFile } from '../utils/debug';\nimport type { PackageManagerDetector } from './package-manager-detection';\n\n// ---------------------------------------------------------------------------\n// SDK dynamic import (ESM module loaded once, cached)\n// ---------------------------------------------------------------------------\n\nlet _sdkModule: any = null;\nasync function getSDKModule(): Promise<any> {\n if (!_sdkModule) {\n _sdkModule = await import('@anthropic-ai/claude-agent-sdk');\n }\n return _sdkModule;\n}\n\n// ---------------------------------------------------------------------------\n// Options for creating the wizard tools server\n// ---------------------------------------------------------------------------\n\nexport interface WizardToolsOptions {\n /** Root directory of the project being analyzed */\n workingDirectory: string;\n\n /** Framework-specific package manager detector */\n detectPackageManager: PackageManagerDetector;\n\n /** Base URL for the skills server (e.g. http://localhost:8765 or GitHub releases URL) */\n skillsBaseUrl: string;\n}\n\n// ---------------------------------------------------------------------------\n// Env file helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve filePath relative to workingDirectory, rejecting path traversal.\n */\nexport function resolveEnvPath(\n workingDirectory: string,\n filePath: string,\n): string {\n const resolved = path.resolve(workingDirectory, filePath);\n if (\n !resolved.startsWith(workingDirectory + path.sep) &&\n resolved !== workingDirectory\n ) {\n throw new Error(\n `Path traversal rejected: \"${filePath}\" resolves outside working directory`,\n );\n }\n return resolved;\n}\n\n/**\n * Ensure the given env file basename is covered by .gitignore in the working directory.\n * Creates .gitignore if it doesn't exist; appends the entry if missing.\n */\nexport function ensureGitignoreCoverage(\n workingDirectory: string,\n envFileName: string,\n): void {\n const gitignorePath = path.join(workingDirectory, '.gitignore');\n\n if (fs.existsSync(gitignorePath)) {\n const content = fs.readFileSync(gitignorePath, 'utf8');\n // Check if the file (or a glob covering it) is already listed\n if (content.split('\\n').some((line) => line.trim() === envFileName)) {\n return;\n }\n const newContent = content.endsWith('\\n')\n ? `${content}${envFileName}\\n`\n : `${content}\\n${envFileName}\\n`;\n fs.writeFileSync(gitignorePath, newContent, 'utf8');\n } else {\n fs.writeFileSync(gitignorePath, `${envFileName}\\n`, 'utf8');\n }\n}\n\n/**\n * Parse a .env file's content and return the set of defined key names.\n */\nexport function parseEnvKeys(content: string): Set<string> {\n const keys = new Set<string>();\n for (const line of content.split('\\n')) {\n const match = line.match(/^\\s*([A-Za-z_][A-Za-z0-9_]*)\\s*=/);\n if (match) {\n keys.add(match[1]);\n }\n }\n return keys;\n}\n\n/**\n * Merge key-value pairs into existing .env content.\n * Updates existing keys in-place, appends new keys at the end.\n */\nexport function mergeEnvValues(\n content: string,\n values: Record<string, string>,\n): string {\n let result = content;\n const updatedKeys = new Set<string>();\n\n for (const [key, value] of Object.entries(values)) {\n const regex = new RegExp(`^(\\\\s*${key}\\\\s*=).*$`, 'm');\n if (regex.test(result)) {\n result = result.replace(regex, `$1${value}`);\n updatedKeys.add(key);\n }\n }\n\n const newKeys = Object.entries(values).filter(\n ([key]) => !updatedKeys.has(key),\n );\n if (newKeys.length > 0) {\n if (result.length > 0 && !result.endsWith('\\n')) {\n result += '\\n';\n }\n for (const [key, value] of newKeys) {\n result += `${key}=${value}\\n`;\n }\n }\n\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Server factory\n// ---------------------------------------------------------------------------\n\nconst SERVER_NAME = 'wizard-tools';\n\n/**\n * Create the unified in-process MCP server with all wizard tools.\n * Must be called asynchronously because the SDK is an ESM module loaded via dynamic import.\n */\nexport async function createWizardToolsServer(options: WizardToolsOptions) {\n const { workingDirectory, detectPackageManager, skillsBaseUrl } = options;\n const sdk = await getSDKModule();\n const { tool, createSdkMcpServer } = sdk;\n\n // Pre-fetch skill menu so category names are available in the tool schema\n type SkillEntry = { id: string; name: string; downloadUrl: string };\n let cachedSkillMenu: Record<string, SkillEntry[]> = {};\n let categoryNames: [string, ...string[]] = ['integration'];\n\n try {\n const menuUrl = `${skillsBaseUrl}/skill-menu.json`;\n logToFile(`wizard-tools: pre-fetching skill menu from ${menuUrl}`);\n const resp = await fetch(menuUrl);\n if (resp.ok) {\n const data = (await resp.json()) as {\n categories: Record<string, SkillEntry[]>;\n };\n cachedSkillMenu = data.categories;\n const keys = Object.keys(cachedSkillMenu);\n if (keys.length > 0) {\n categoryNames = keys as [string, ...string[]];\n }\n logToFile(`wizard-tools: loaded skill menu (${keys.length} categories)`);\n } else {\n logToFile(`wizard-tools: skill menu fetch failed: ${resp.status}`);\n }\n } catch (err: any) {\n logToFile(`wizard-tools: skill menu fetch error: ${err.message}`);\n }\n\n // -- check_env_keys -------------------------------------------------------\n\n const checkEnvKeys = tool(\n 'check_env_keys',\n 'Check which environment variable keys are present or missing in a .env file. Never reveals values.',\n {\n filePath: z\n .string()\n .describe('Path to the .env file, relative to the project root'),\n keys: z\n .array(z.string())\n .describe('Environment variable key names to check'),\n },\n (args: { filePath: string; keys: string[] }) => {\n const resolved = resolveEnvPath(workingDirectory, args.filePath);\n logToFile(`check_env_keys: ${resolved}, keys: ${args.keys.join(', ')}`);\n\n const existingKeys: Set<string> = fs.existsSync(resolved)\n ? parseEnvKeys(fs.readFileSync(resolved, 'utf8'))\n : new Set<string>();\n\n const results: Record<string, 'present' | 'missing'> = {};\n for (const key of args.keys) {\n results[key] = existingKeys.has(key) ? 'present' : 'missing';\n }\n\n return {\n content: [\n { type: 'text' as const, text: JSON.stringify(results, null, 2) },\n ],\n };\n },\n );\n\n // -- set_env_values -------------------------------------------------------\n\n const setEnvValues = tool(\n 'set_env_values',\n 'Create or update environment variable keys in a .env file. Creates the file if it does not exist. Ensures .gitignore coverage.',\n {\n filePath: z\n .string()\n .describe('Path to the .env file, relative to the project root'),\n values: z\n .record(z.string(), z.string())\n .describe('Key-value pairs to set'),\n },\n (args: { filePath: string; values: Record<string, string> }) => {\n // Block the wrong key name — the correct key is NEXT_PUBLIC_POSTHOG_KEY or similar\n const forbidden = Object.keys(args.values).find(\n (k) => k.toUpperCase() === 'POSTHOG_API_KEY',\n );\n if (forbidden) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: \"${forbidden}\" is not a valid PostHog env var name. Use the project-specific key name from your framework's integration guide (e.g. NEXT_PUBLIC_POSTHOG_KEY).`,\n },\n ],\n isError: true,\n };\n }\n\n const resolved = resolveEnvPath(workingDirectory, args.filePath);\n logToFile(\n `set_env_values: ${resolved}, keys: ${Object.keys(args.values).join(\n ', ',\n )}`,\n );\n\n const existing = fs.existsSync(resolved)\n ? fs.readFileSync(resolved, 'utf8')\n : '';\n const content = mergeEnvValues(existing, args.values);\n\n // Ensure parent directory exists\n const dir = path.dirname(resolved);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n fs.writeFileSync(resolved, content, 'utf8');\n\n // Ensure .gitignore coverage for this env file\n const envFileName = path.basename(resolved);\n ensureGitignoreCoverage(workingDirectory, envFileName);\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Updated ${Object.keys(args.values).length} key(s) in ${\n args.filePath\n }`,\n },\n ],\n };\n },\n );\n\n // -- detect_package_manager -----------------------------------------------\n\n const detectPM = tool(\n 'detect_package_manager',\n 'Detect which package manager(s) the project uses. Returns the name, install command, and run command for each detected package manager. Call this before running any install commands.',\n {},\n async () => {\n logToFile(`detect_package_manager: scanning ${workingDirectory}`);\n\n const result = await detectPackageManager(workingDirectory);\n\n logToFile(\n `detect_package_manager: detected ${result.detected.length} package manager(s)`,\n );\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n },\n );\n\n // -- load_skill_menu ------------------------------------------------------\n\n const loadSkillMenu = tool(\n 'load_skill_menu',\n 'Load available PostHog skills for a category. Returns skill IDs and names. Call this first, then use install_skill with the chosen ID.',\n {\n category: z.enum(categoryNames).describe('Skill category'),\n },\n (args: { category: string }) => {\n const skills = cachedSkillMenu[args.category];\n if (!skills || skills.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `No skills found for category \"${args.category}\".`,\n },\n ],\n isError: true,\n };\n }\n\n const menuText = skills.map((s) => `- ${s.id}: ${s.name}`).join('\\n');\n\n logToFile(\n `load_skill_menu: returning ${skills.length} skills for \"${args.category}\"`,\n );\n\n return {\n content: [{ type: 'text' as const, text: menuText }],\n };\n },\n );\n\n // -- install_skill --------------------------------------------------------\n\n const installSkill = tool(\n 'install_skill',\n 'Download and install a PostHog skill by ID. Call load_skill_menu first to see available skills. Extracts the skill to .claude/skills/<skillId>/.',\n {\n skillId: z\n .string()\n .describe(\n 'Skill ID from the skill menu (e.g., \"integration-nextjs-app-router\")',\n ),\n },\n (args: { skillId: string }) => {\n if (!/^[a-z0-9][a-z0-9-]*$/.test(args.skillId)) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'Error: skillId must be lowercase alphanumeric with hyphens.',\n },\n ],\n isError: true,\n };\n }\n\n // Look up download URL from cached menu\n const allSkills: SkillEntry[] = Object.values(cachedSkillMenu).flat();\n const skill = allSkills.find((s) => s.id === args.skillId);\n if (!skill) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: skill \"${args.skillId}\" not found. Use load_skill_menu to see available skills.`,\n },\n ],\n isError: true,\n };\n }\n\n const skillDir = path.join(\n workingDirectory,\n '.claude',\n 'skills',\n args.skillId,\n );\n const tmpFile = `/tmp/posthog-skill-${args.skillId}.zip`;\n\n try {\n fs.mkdirSync(skillDir, { recursive: true });\n execFileSync('curl', ['-sL', skill.downloadUrl, '-o', tmpFile], {\n timeout: 30000,\n });\n execFileSync('unzip', ['-o', tmpFile, '-d', skillDir], {\n timeout: 30000,\n });\n try {\n fs.unlinkSync(tmpFile);\n } catch {\n /* ignore cleanup errors */\n }\n\n logToFile(\n `install_skill: installed ${args.skillId} from ${skill.downloadUrl}`,\n );\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Skill installed to .claude/skills/${args.skillId}/`,\n },\n ],\n };\n } catch (err: any) {\n logToFile(`install_skill error: ${err.message}`);\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error installing skill: ${err.message}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n\n // -- Assemble server ------------------------------------------------------\n\n return createSdkMcpServer({\n name: SERVER_NAME,\n version: '1.0.0',\n tools: [checkEnvKeys, setEnvValues, detectPM, loadSkillMenu, installSkill],\n });\n}\n\n/** Tool names exposed by the wizard-tools server, for use in allowedTools */\nexport const WIZARD_TOOL_NAMES = [\n `${SERVER_NAME}:check_env_keys`,\n `${SERVER_NAME}:set_env_values`,\n `${SERVER_NAME}:detect_package_manager`,\n `${SERVER_NAME}:load_skill_menu`,\n `${SERVER_NAME}:install_skill`,\n];\n"]}
1
+ {"version":3,"file":"wizard-tools.js","sourceRoot":"","sources":["../../../src/lib/wizard-tools.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Unified in-process MCP server for the PostHog wizard.\n *\n * Provides tools that run locally (secret values never leave the machine):\n * - check_env_keys: Check which env var keys exist in a .env file\n * - set_env_values: Create/update env vars in a .env file\n * - detect_package_manager: Detect the project's package manager(s)\n */\n\nimport path from 'path';\nimport fs from 'fs';\nimport { execFileSync } from 'child_process';\nimport { z } from 'zod';\nimport { logToFile } from '../utils/debug';\nimport type { PackageManagerDetector } from './package-manager-detection';\n\n// ---------------------------------------------------------------------------\n// SDK dynamic import (ESM module loaded once, cached)\n// ---------------------------------------------------------------------------\n\nlet _sdkModule: any = null;\nasync function getSDKModule(): Promise<any> {\n if (!_sdkModule) {\n _sdkModule = await import('@anthropic-ai/claude-agent-sdk');\n }\n return _sdkModule;\n}\n\n// ---------------------------------------------------------------------------\n// Skill types\n// ---------------------------------------------------------------------------\n\nexport type SkillEntry = { id: string; name: string; downloadUrl: string };\n\nexport interface SkillMenu {\n categories: Record<string, SkillEntry[]>;\n}\n\n// ---------------------------------------------------------------------------\n// Standalone skill helpers (usable before the MCP server is created)\n// ---------------------------------------------------------------------------\n\n/**\n * Fetch the skill menu from the skills server.\n * Returns parsed data on success, `null` on failure.\n */\nexport async function fetchSkillMenu(\n skillsBaseUrl: string,\n): Promise<SkillMenu | null> {\n try {\n const menuUrl = `${skillsBaseUrl}/skill-menu.json`;\n logToFile(`fetchSkillMenu: fetching from ${menuUrl}`);\n const resp = await fetch(menuUrl);\n if (resp.ok) {\n const data = (await resp.json()) as SkillMenu;\n logToFile(\n `fetchSkillMenu: loaded (${\n Object.keys(data.categories).length\n } categories)`,\n );\n return data;\n }\n logToFile(`fetchSkillMenu: failed with HTTP ${resp.status}`);\n return null;\n } catch (err: any) {\n logToFile(`fetchSkillMenu: error: ${err.message}`);\n return null;\n }\n}\n\n/**\n * Download and extract a skill.\n * By default installs to `<installDir>/.claude/skills/<id>/`.\n * Pass `skillsRoot` to override the base directory (e.g. `.posthog/skills`).\n */\nexport function downloadSkill(\n skillEntry: SkillEntry,\n installDir: string,\n skillsRoot?: string,\n): { success: boolean; error?: string } {\n const skillDir = skillsRoot\n ? path.join(installDir, skillsRoot, skillEntry.id)\n : path.join(installDir, '.claude', 'skills', skillEntry.id);\n const tmpFile = `/tmp/posthog-skill-${skillEntry.id}.zip`;\n\n try {\n fs.mkdirSync(skillDir, { recursive: true });\n execFileSync('curl', ['-sL', skillEntry.downloadUrl, '-o', tmpFile], {\n timeout: 30000,\n });\n execFileSync('unzip', ['-o', tmpFile, '-d', skillDir], {\n timeout: 30000,\n });\n try {\n fs.unlinkSync(tmpFile);\n } catch {\n /* ignore cleanup errors */\n }\n\n logToFile(\n `downloadSkill: installed ${skillEntry.id} from ${skillEntry.downloadUrl}`,\n );\n return { success: true };\n } catch (err: any) {\n logToFile(`downloadSkill: error: ${err.message}`);\n return { success: false, error: err.message };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Options for creating the wizard tools server\n// ---------------------------------------------------------------------------\n\nexport interface WizardToolsOptions {\n /** Root directory of the project being analyzed */\n workingDirectory: string;\n\n /** Framework-specific package manager detector */\n detectPackageManager: PackageManagerDetector;\n\n /** Base URL for the skills server (e.g. http://localhost:8765 or GitHub releases URL) */\n skillsBaseUrl: string;\n}\n\n// ---------------------------------------------------------------------------\n// Env file helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve filePath relative to workingDirectory, rejecting path traversal.\n */\nexport function resolveEnvPath(\n workingDirectory: string,\n filePath: string,\n): string {\n const resolved = path.resolve(workingDirectory, filePath);\n if (\n !resolved.startsWith(workingDirectory + path.sep) &&\n resolved !== workingDirectory\n ) {\n throw new Error(\n `Path traversal rejected: \"${filePath}\" resolves outside working directory`,\n );\n }\n return resolved;\n}\n\n/**\n * Ensure the given env file basename is covered by .gitignore in the working directory.\n * Creates .gitignore if it doesn't exist; appends the entry if missing.\n */\nexport function ensureGitignoreCoverage(\n workingDirectory: string,\n envFileName: string,\n): void {\n const gitignorePath = path.join(workingDirectory, '.gitignore');\n\n if (fs.existsSync(gitignorePath)) {\n const content = fs.readFileSync(gitignorePath, 'utf8');\n // Check if the file (or a glob covering it) is already listed\n if (content.split('\\n').some((line) => line.trim() === envFileName)) {\n return;\n }\n const newContent = content.endsWith('\\n')\n ? `${content}${envFileName}\\n`\n : `${content}\\n${envFileName}\\n`;\n fs.writeFileSync(gitignorePath, newContent, 'utf8');\n } else {\n fs.writeFileSync(gitignorePath, `${envFileName}\\n`, 'utf8');\n }\n}\n\n/**\n * Parse a .env file's content and return the set of defined key names.\n */\nexport function parseEnvKeys(content: string): Set<string> {\n const keys = new Set<string>();\n for (const line of content.split('\\n')) {\n const match = line.match(/^\\s*([A-Za-z_][A-Za-z0-9_]*)\\s*=/);\n if (match) {\n keys.add(match[1]);\n }\n }\n return keys;\n}\n\n/**\n * Merge key-value pairs into existing .env content.\n * Updates existing keys in-place, appends new keys at the end.\n */\nexport function mergeEnvValues(\n content: string,\n values: Record<string, string>,\n): string {\n let result = content;\n const updatedKeys = new Set<string>();\n\n for (const [key, value] of Object.entries(values)) {\n const regex = new RegExp(`^(\\\\s*${key}\\\\s*=).*$`, 'm');\n if (regex.test(result)) {\n result = result.replace(regex, `$1${value}`);\n updatedKeys.add(key);\n }\n }\n\n const newKeys = Object.entries(values).filter(\n ([key]) => !updatedKeys.has(key),\n );\n if (newKeys.length > 0) {\n if (result.length > 0 && !result.endsWith('\\n')) {\n result += '\\n';\n }\n for (const [key, value] of newKeys) {\n result += `${key}=${value}\\n`;\n }\n }\n\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Server factory\n// ---------------------------------------------------------------------------\n\nconst SERVER_NAME = 'wizard-tools';\n\n/**\n * Create the unified in-process MCP server with all wizard tools.\n * Must be called asynchronously because the SDK is an ESM module loaded via dynamic import.\n */\nexport async function createWizardToolsServer(options: WizardToolsOptions) {\n const { workingDirectory, detectPackageManager, skillsBaseUrl } = options;\n const sdk = await getSDKModule();\n const { tool, createSdkMcpServer } = sdk;\n\n // Pre-fetch skill menu so category names are available in the tool schema\n let cachedSkillMenu: Record<string, SkillEntry[]> = {};\n let categoryNames: [string, ...string[]] = ['integration'];\n\n const menu = await fetchSkillMenu(skillsBaseUrl);\n if (menu) {\n cachedSkillMenu = menu.categories;\n }\n\n const keys = Object.keys(cachedSkillMenu);\n if (keys.length > 0) {\n categoryNames = keys as [string, ...string[]];\n }\n\n // -- check_env_keys -------------------------------------------------------\n\n const checkEnvKeys = tool(\n 'check_env_keys',\n 'Check which environment variable keys are present or missing in a .env file. Never reveals values.',\n {\n filePath: z\n .string()\n .describe('Path to the .env file, relative to the project root'),\n keys: z\n .array(z.string())\n .describe('Environment variable key names to check'),\n },\n (args: { filePath: string; keys: string[] }) => {\n const resolved = resolveEnvPath(workingDirectory, args.filePath);\n logToFile(`check_env_keys: ${resolved}, keys: ${args.keys.join(', ')}`);\n\n const existingKeys: Set<string> = fs.existsSync(resolved)\n ? parseEnvKeys(fs.readFileSync(resolved, 'utf8'))\n : new Set<string>();\n\n const results: Record<string, 'present' | 'missing'> = {};\n for (const key of args.keys) {\n results[key] = existingKeys.has(key) ? 'present' : 'missing';\n }\n\n return {\n content: [\n { type: 'text' as const, text: JSON.stringify(results, null, 2) },\n ],\n };\n },\n );\n\n // -- set_env_values -------------------------------------------------------\n\n const setEnvValues = tool(\n 'set_env_values',\n 'Create or update environment variable keys in a .env file. Creates the file if it does not exist. Ensures .gitignore coverage.',\n {\n filePath: z\n .string()\n .describe('Path to the .env file, relative to the project root'),\n values: z\n .record(z.string(), z.string())\n .describe('Key-value pairs to set'),\n },\n (args: { filePath: string; values: Record<string, string> }) => {\n // Block the wrong key name — the correct key is NEXT_PUBLIC_POSTHOG_KEY or similar\n const forbidden = Object.keys(args.values).find(\n (k) => k.toUpperCase() === 'POSTHOG_API_KEY',\n );\n if (forbidden) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: \"${forbidden}\" is not a valid PostHog env var name. Use the project-specific key name from your framework's integration guide (e.g. NEXT_PUBLIC_POSTHOG_KEY).`,\n },\n ],\n isError: true,\n };\n }\n\n const resolved = resolveEnvPath(workingDirectory, args.filePath);\n logToFile(\n `set_env_values: ${resolved}, keys: ${Object.keys(args.values).join(\n ', ',\n )}`,\n );\n\n const existing = fs.existsSync(resolved)\n ? fs.readFileSync(resolved, 'utf8')\n : '';\n const content = mergeEnvValues(existing, args.values);\n\n // Ensure parent directory exists\n const dir = path.dirname(resolved);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n fs.writeFileSync(resolved, content, 'utf8');\n\n // Ensure .gitignore coverage for this env file\n const envFileName = path.basename(resolved);\n ensureGitignoreCoverage(workingDirectory, envFileName);\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Updated ${Object.keys(args.values).length} key(s) in ${\n args.filePath\n }`,\n },\n ],\n };\n },\n );\n\n // -- detect_package_manager -----------------------------------------------\n\n const detectPM = tool(\n 'detect_package_manager',\n 'Detect which package manager(s) the project uses. Returns the name, install command, and run command for each detected package manager. Call this before running any install commands.',\n {},\n async () => {\n logToFile(`detect_package_manager: scanning ${workingDirectory}`);\n\n const result = await detectPackageManager(workingDirectory);\n\n logToFile(\n `detect_package_manager: detected ${result.detected.length} package manager(s)`,\n );\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n },\n );\n\n // -- load_skill_menu ------------------------------------------------------\n\n const loadSkillMenu = tool(\n 'load_skill_menu',\n 'Load available PostHog skills for a category. Returns skill IDs and names. Call this first, then use install_skill with the chosen ID.',\n {\n category: z.enum(categoryNames).describe('Skill category'),\n },\n (args: { category: string }) => {\n const skills = cachedSkillMenu[args.category];\n if (!skills || skills.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `No skills found for category \"${args.category}\".`,\n },\n ],\n isError: true,\n };\n }\n\n const menuText = skills.map((s) => `- ${s.id}: ${s.name}`).join('\\n');\n\n logToFile(\n `load_skill_menu: returning ${skills.length} skills for \"${args.category}\"`,\n );\n\n return {\n content: [{ type: 'text' as const, text: menuText }],\n };\n },\n );\n\n // -- install_skill --------------------------------------------------------\n\n const installSkill = tool(\n 'install_skill',\n 'Download and install a PostHog skill by ID. Call load_skill_menu first to see available skills. Extracts the skill to .claude/skills/<skillId>/.',\n {\n skillId: z\n .string()\n .describe(\n 'Skill ID from the skill menu (e.g., \"integration-nextjs-app-router\")',\n ),\n },\n (args: { skillId: string }) => {\n if (!/^[a-z0-9][a-z0-9_-]*$/.test(args.skillId)) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'Error: skillId must be lowercase alphanumeric with hyphens.',\n },\n ],\n isError: true,\n };\n }\n\n // Look up download URL from cached menu\n const allSkills: SkillEntry[] = Object.values(cachedSkillMenu).flat();\n const skill = allSkills.find((s) => s.id === args.skillId);\n if (!skill) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: skill \"${args.skillId}\" not found. Use load_skill_menu to see available skills.`,\n },\n ],\n isError: true,\n };\n }\n\n const result = downloadSkill(skill, workingDirectory);\n if (result.success) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Skill installed to .claude/skills/${args.skillId}/`,\n },\n ],\n };\n } else {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error installing skill: ${result.error}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n\n // -- Assemble server ------------------------------------------------------\n\n return createSdkMcpServer({\n name: SERVER_NAME,\n version: '1.0.0',\n tools: [checkEnvKeys, setEnvValues, detectPM, loadSkillMenu, installSkill],\n });\n}\n\n/** Tool names exposed by the wizard-tools server, for use in allowedTools */\nexport const WIZARD_TOOL_NAMES = [\n `${SERVER_NAME}:check_env_keys`,\n `${SERVER_NAME}:set_env_values`,\n `${SERVER_NAME}:detect_package_manager`,\n `${SERVER_NAME}:load_skill_menu`,\n `${SERVER_NAME}:install_skill`,\n];\n"]}
@@ -9,16 +9,16 @@ export declare const ZedMCPConfig: z.ZodObject<{
9
9
  env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
10
10
  }, "strip", z.ZodTypeAny, {
11
11
  command?: string | undefined;
12
+ source?: string | undefined;
12
13
  args?: string[] | undefined;
13
14
  env?: Record<string, string> | undefined;
14
15
  enabled?: boolean | undefined;
15
- source?: string | undefined;
16
16
  }, {
17
17
  command?: string | undefined;
18
+ source?: string | undefined;
18
19
  args?: string[] | undefined;
19
20
  env?: Record<string, string> | undefined;
20
21
  enabled?: boolean | undefined;
21
- source?: string | undefined;
22
22
  }>, z.ZodObject<{
23
23
  enabled: z.ZodOptional<z.ZodBoolean>;
24
24
  url: z.ZodString;
@@ -41,16 +41,16 @@ export declare const ZedMCPConfig: z.ZodObject<{
41
41
  env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
42
42
  }, "strip", z.ZodTypeAny, {
43
43
  command?: string | undefined;
44
+ source?: string | undefined;
44
45
  args?: string[] | undefined;
45
46
  env?: Record<string, string> | undefined;
46
47
  enabled?: boolean | undefined;
47
- source?: string | undefined;
48
48
  }, {
49
49
  command?: string | undefined;
50
+ source?: string | undefined;
50
51
  args?: string[] | undefined;
51
52
  env?: Record<string, string> | undefined;
52
53
  enabled?: boolean | undefined;
53
- source?: string | undefined;
54
54
  }>, z.ZodObject<{
55
55
  enabled: z.ZodOptional<z.ZodBoolean>;
56
56
  url: z.ZodString;
@@ -73,16 +73,16 @@ export declare const ZedMCPConfig: z.ZodObject<{
73
73
  env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
74
74
  }, "strip", z.ZodTypeAny, {
75
75
  command?: string | undefined;
76
+ source?: string | undefined;
76
77
  args?: string[] | undefined;
77
78
  env?: Record<string, string> | undefined;
78
79
  enabled?: boolean | undefined;
79
- source?: string | undefined;
80
80
  }, {
81
81
  command?: string | undefined;
82
+ source?: string | undefined;
82
83
  args?: string[] | undefined;
83
84
  env?: Record<string, string> | undefined;
84
85
  enabled?: boolean | undefined;
85
- source?: string | undefined;
86
86
  }>, z.ZodObject<{
87
87
  enabled: z.ZodOptional<z.ZodBoolean>;
88
88
  url: z.ZodString;
@@ -3,6 +3,7 @@
3
3
  * No prompts, no TUI, no interactivity. Just console output.
4
4
  */
5
5
  import { type WizardUI, type SpinnerHandle } from './wizard-ui';
6
+ import type { SettingsConflict } from '../lib/agent-interface';
6
7
  export declare class LoggingUI implements WizardUI {
7
8
  intro(message: string): void;
8
9
  outro(message: string): void;
@@ -27,7 +28,8 @@ export declare class LoggingUI implements WizardUI {
27
28
  pid: string;
28
29
  user: string;
29
30
  }): Promise<void>;
30
- showSettingsOverride(keys: string[], _backupAndFix: () => boolean): Promise<void>;
31
+ showSettingsOverride(_conflicts: SettingsConflict[], _backupAndFix: () => boolean): Promise<void>;
32
+ showAuthError(): void;
31
33
  startRun(): void;
32
34
  setCredentials(_credentials: {
33
35
  accessToken: string;
@@ -85,14 +85,14 @@ class LoggingUI {
85
85
  showPortConflict(_processInfo) {
86
86
  return Promise.resolve();
87
87
  }
88
- showSettingsOverride(keys, _backupAndFix) {
89
- console.log(`▲ Security warning: .claude/settings.json overrides detected`);
90
- for (const key of keys) {
91
- console.log(`│ • ${key}`);
92
- }
93
- console.log(`│ These overrides prevent the Wizard from accessing the PostHog LLM Gateway.`);
88
+ showSettingsOverride(_conflicts, _backupAndFix) {
94
89
  return Promise.resolve();
95
90
  }
91
+ showAuthError() {
92
+ console.log(`✖ Authentication failed (401)`);
93
+ console.log(`│ Claude Code auth is conflicting with the wizard. Please try again after logging out:`);
94
+ console.log(`│ claude auth logout`);
95
+ }
96
96
  startRun() {
97
97
  // No-op in CI mode
98
98
  }
@@ -1 +1 @@
1
- {"version":3,"file":"logging-ui.js","sourceRoot":"","sources":["../../../src/ui/logging-ui.ts"],"names":[],"mappings":";AAAA,+BAA+B;AAC/B;;;GAGG;;;AAEH,2CAA4E;AAE5E,MAAa,SAAS;IACpB,KAAK,CAAC,OAAe;QACnB,OAAO,CAAC,GAAG,CAAC,MAAM,OAAO,EAAE,CAAC,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,OAAe;QACnB,OAAO,CAAC,GAAG,CAAC,MAAM,OAAO,EAAE,CAAC,CAAC;IAC/B,CAAC;IAED,MAAM,CAAC,OAAe;QACpB,OAAO,CAAC,GAAG,CAAC,MAAM,OAAO,EAAE,CAAC,CAAC;IAC/B,CAAC;IAED,GAAG,GAAG;QACJ,IAAI,CAAC,OAAe;YAClB,OAAO,CAAC,GAAG,CAAC,MAAM,OAAO,EAAE,CAAC,CAAC;QAC/B,CAAC;QACD,IAAI,CAAC,OAAe;YAClB,OAAO,CAAC,GAAG,CAAC,MAAM,OAAO,EAAE,CAAC,CAAC;QAC/B,CAAC;QACD,KAAK,CAAC,OAAe;YACnB,OAAO,CAAC,GAAG,CAAC,MAAM,OAAO,EAAE,CAAC,CAAC;QAC/B,CAAC;QACD,OAAO,CAAC,OAAe;YACrB,OAAO,CAAC,GAAG,CAAC,MAAM,OAAO,EAAE,CAAC,CAAC;QAC/B,CAAC;QACD,IAAI,CAAC,OAAe;YAClB,OAAO,CAAC,GAAG,CAAC,MAAM,OAAO,EAAE,CAAC,CAAC;QAC/B,CAAC;KACF,CAAC;IAEF,IAAI,CAAC,OAAe;QAClB,OAAO,CAAC,GAAG,CAAC,MAAM,OAAO,EAAE,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO;QACL,OAAO;YACL,KAAK,CAAC,OAAgB;gBACpB,IAAI,OAAO;oBAAE,OAAO,CAAC,GAAG,CAAC,MAAM,OAAO,EAAE,CAAC,CAAC;YAC5C,CAAC;YACD,IAAI,CAAC,OAAgB;gBACnB,IAAI,OAAO;oBAAE,OAAO,CAAC,GAAG,CAAC,MAAM,OAAO,EAAE,CAAC,CAAC;YAC5C,CAAC;YACD,OAAO,CAAC,GAAY;gBAClB,IAAI,GAAG;oBAAE,OAAO,CAAC,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;YACpC,CAAC;SACF,CAAC;IACJ,CAAC;IAED,UAAU,CAAC,OAAe;QACxB,OAAO,CAAC,GAAG,CAAC,MAAM,OAAO,EAAE,CAAC,CAAC;IAC/B,CAAC;IAED,oBAAoB,CAAC,KAAa;QAChC,OAAO,CAAC,GAAG,CAAC,iBAAiB,KAAK,EAAE,CAAC,CAAC;IACxC,CAAC;IAED,aAAa,CAAC,OAAe,EAAE,GAAe;QAC5C,8BAA8B;IAChC,CAAC;IAED,WAAW,CAAC,GAAkB;QAC5B,IAAI,GAAG,EAAE,CAAC;YACR,OAAO,CAAC,GAAG,CACT,6DAA6D,CAC9D,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,kBAAkB,CAChB,MAAyE;QAEzE,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;QACpE,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC;QAC9B,CAAC;QACD,OAAO,CAAC,GAAG,CACT,kEAAkE,CACnE,CAAC;QACF,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IAED,oBAAoB,CAClB,MAAyE;QAEzE,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;QACpD,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,gBAAgB,CAAC,YAIhB;QACC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IAED,oBAAoB,CAClB,IAAc,EACd,aAA4B;QAE5B,OAAO,CAAC,GAAG,CACT,+DAA+D,CAChE,CAAC;QACF,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC;QAC/B,CAAC;QACD,OAAO,CAAC,GAAG,CACT,+EAA+E,CAChF,CAAC;QACF,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IAED,QAAQ;QACN,mBAAmB;IACrB,CAAC;IAED,cAAc,CAAC,YAKd;QACC,sDAAsD;IACxD,CAAC;IAED,SAAS,CACP,KAAsE;QAEtE,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAC5B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,sBAAU,CAAC,SAAS,CACzC,CAAC,MAAM,CAAC;QACT,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,sBAAU,CAAC,UAAU,CAAC,CAAC;QACzE,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,CAAC,GAAG,CACT,OAAO,SAAS,IAAI,KAAK,CAAC,MAAM,KAC9B,UAAU,CAAC,UAAU,IAAI,UAAU,CAAC,OACtC,EAAE,CACH,CAAC;QACJ,CAAC;IACH,CAAC;IAED,YAAY,CAAC,OAAqD;QAChE,mBAAmB;IACrB,CAAC;CACF;AApJD,8BAoJC","sourcesContent":["/* eslint-disable no-console */\n/**\n * LoggingUI — Logging-only implementation for CI mode.\n * No prompts, no TUI, no interactivity. Just console output.\n */\n\nimport { TaskStatus, type WizardUI, type SpinnerHandle } from './wizard-ui';\n\nexport class LoggingUI implements WizardUI {\n intro(message: string): void {\n console.log(`┌ ${message}`);\n }\n\n outro(message: string): void {\n console.log(`└ ${message}`);\n }\n\n cancel(message: string): void {\n console.log(`■ ${message}`);\n }\n\n log = {\n info(message: string): void {\n console.log(`│ ${message}`);\n },\n warn(message: string): void {\n console.log(`▲ ${message}`);\n },\n error(message: string): void {\n console.log(`✖ ${message}`);\n },\n success(message: string): void {\n console.log(`✔ ${message}`);\n },\n step(message: string): void {\n console.log(`◇ ${message}`);\n },\n };\n\n note(message: string): void {\n console.log(`│ ${message}`);\n }\n\n spinner(): SpinnerHandle {\n return {\n start(message?: string) {\n if (message) console.log(`◌ ${message}`);\n },\n stop(message?: string) {\n if (message) console.log(`● ${message}`);\n },\n message(msg?: string) {\n if (msg) console.log(`◌ ${msg}`);\n },\n };\n }\n\n pushStatus(message: string): void {\n console.log(`◇ ${message}`);\n }\n\n setDetectedFramework(label: string): void {\n console.log(`✔ Framework: ${label}`);\n }\n\n onEnterScreen(_screen: string, _fn: () => void): void {\n // No screen transitions in CI\n }\n\n setLoginUrl(url: string | null): void {\n if (url) {\n console.log(\n `│ If the browser didn't open automatically, use this link:`,\n );\n console.log(`│ ${url}`);\n }\n }\n\n showBlockingOutage(\n result: import('../lib/health-checks/readiness.js').WizardReadinessResult,\n ): Promise<void> {\n console.log(`▲ Service health issues detected — blocking outage.`);\n for (const reason of result.reasons) {\n console.log(`│ ${reason}`);\n }\n console.log(\n `│ The wizard may not work reliably while services are affected.`,\n );\n return Promise.resolve();\n }\n\n setReadinessWarnings(\n result: import('../lib/health-checks/readiness.js').WizardReadinessResult,\n ): void {\n console.log(`▲ Service health warnings detected.`);\n for (const reason of result.reasons) {\n console.log(`│ ${reason}`);\n }\n }\n\n showPortConflict(_processInfo: {\n command: string;\n pid: string;\n user: string;\n }): Promise<void> {\n return Promise.resolve();\n }\n\n showSettingsOverride(\n keys: string[],\n _backupAndFix: () => boolean,\n ): Promise<void> {\n console.log(\n `▲ Security warning: .claude/settings.json overrides detected`,\n );\n for (const key of keys) {\n console.log(`│ • ${key}`);\n }\n console.log(\n `│ These overrides prevent the Wizard from accessing the PostHog LLM Gateway.`,\n );\n return Promise.resolve();\n }\n\n startRun(): void {\n // No-op in CI mode\n }\n\n setCredentials(_credentials: {\n accessToken: string;\n projectApiKey: string;\n host: string;\n projectId: number;\n }): void {\n // No-op in CI mode — credentials are handled directly\n }\n\n syncTodos(\n todos: Array<{ content: string; status: string; activeForm?: string }>,\n ): void {\n const completed = todos.filter(\n (t) => t.status === TaskStatus.Completed,\n ).length;\n const inProgress = todos.find((t) => t.status === TaskStatus.InProgress);\n if (inProgress) {\n console.log(\n `◌ [${completed}/${todos.length}] ${\n inProgress.activeForm || inProgress.content\n }`,\n );\n }\n }\n\n setEventPlan(_events: Array<{ name: string; description: string }>): void {\n // No-op in CI mode\n }\n}\n"]}
1
+ {"version":3,"file":"logging-ui.js","sourceRoot":"","sources":["../../../src/ui/logging-ui.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-console */\n/**\n * LoggingUI — Logging-only implementation for CI mode.\n * No prompts, no TUI, no interactivity. Just console output.\n */\n\nimport { TaskStatus, type WizardUI, type SpinnerHandle } from './wizard-ui';\nimport type { SettingsConflict } from '../lib/agent-interface';\n\nexport class LoggingUI implements WizardUI {\n intro(message: string): void {\n console.log(`┌ ${message}`);\n }\n\n outro(message: string): void {\n console.log(`└ ${message}`);\n }\n\n cancel(message: string): void {\n console.log(`■ ${message}`);\n }\n\n log = {\n info(message: string): void {\n console.log(`│ ${message}`);\n },\n warn(message: string): void {\n console.log(`▲ ${message}`);\n },\n error(message: string): void {\n console.log(`✖ ${message}`);\n },\n success(message: string): void {\n console.log(`✔ ${message}`);\n },\n step(message: string): void {\n console.log(`◇ ${message}`);\n },\n };\n\n note(message: string): void {\n console.log(`│ ${message}`);\n }\n\n spinner(): SpinnerHandle {\n return {\n start(message?: string) {\n if (message) console.log(`◌ ${message}`);\n },\n stop(message?: string) {\n if (message) console.log(`● ${message}`);\n },\n message(msg?: string) {\n if (msg) console.log(`◌ ${msg}`);\n },\n };\n }\n\n pushStatus(message: string): void {\n console.log(`◇ ${message}`);\n }\n\n setDetectedFramework(label: string): void {\n console.log(`✔ Framework: ${label}`);\n }\n\n onEnterScreen(_screen: string, _fn: () => void): void {\n // No screen transitions in CI\n }\n\n setLoginUrl(url: string | null): void {\n if (url) {\n console.log(\n `│ If the browser didn't open automatically, use this link:`,\n );\n console.log(`│ ${url}`);\n }\n }\n\n showBlockingOutage(\n result: import('../lib/health-checks/readiness.js').WizardReadinessResult,\n ): Promise<void> {\n console.log(`▲ Service health issues detected — blocking outage.`);\n for (const reason of result.reasons) {\n console.log(`│ ${reason}`);\n }\n console.log(\n `│ The wizard may not work reliably while services are affected.`,\n );\n return Promise.resolve();\n }\n\n setReadinessWarnings(\n result: import('../lib/health-checks/readiness.js').WizardReadinessResult,\n ): void {\n console.log(`▲ Service health warnings detected.`);\n for (const reason of result.reasons) {\n console.log(`│ ${reason}`);\n }\n }\n\n showPortConflict(_processInfo: {\n command: string;\n pid: string;\n user: string;\n }): Promise<void> {\n return Promise.resolve();\n }\n\n showSettingsOverride(\n _conflicts: SettingsConflict[],\n _backupAndFix: () => boolean,\n ): Promise<void> {\n return Promise.resolve();\n }\n\n showAuthError(): void {\n console.log(`✖ Authentication failed (401)`);\n console.log(\n `│ Claude Code auth is conflicting with the wizard. Please try again after logging out:`,\n );\n console.log(`│ claude auth logout`);\n }\n\n startRun(): void {\n // No-op in CI mode\n }\n\n setCredentials(_credentials: {\n accessToken: string;\n projectApiKey: string;\n host: string;\n projectId: number;\n }): void {\n // No-op in CI mode — credentials are handled directly\n }\n\n syncTodos(\n todos: Array<{ content: string; status: string; activeForm?: string }>,\n ): void {\n const completed = todos.filter(\n (t) => t.status === TaskStatus.Completed,\n ).length;\n const inProgress = todos.find((t) => t.status === TaskStatus.InProgress);\n if (inProgress) {\n console.log(\n `◌ [${completed}/${todos.length}] ${\n inProgress.activeForm || inProgress.content\n }`,\n );\n }\n }\n\n setEventPlan(_events: Array<{ name: string; description: string }>): void {\n // No-op in CI mode\n }\n}\n"]}
@@ -7,6 +7,7 @@
7
7
  */
8
8
  import type { WizardUI, SpinnerHandle } from '../wizard-ui.js';
9
9
  import type { WizardStore } from './store.js';
10
+ import type { SettingsConflict } from '../../lib/agent-interface.js';
10
11
  export declare class InkUI implements WizardUI {
11
12
  private store;
12
13
  constructor(store: WizardStore);
@@ -28,7 +29,8 @@ export declare class InkUI implements WizardUI {
28
29
  pid: string;
29
30
  user: string;
30
31
  }): Promise<void>;
31
- showSettingsOverride(keys: string[], backupAndFix: () => boolean): Promise<void>;
32
+ showSettingsOverride(conflicts: SettingsConflict[], backupAndFix: () => boolean): Promise<void>;
33
+ showAuthError(): void;
32
34
  startRun(): void;
33
35
  cancel(message: string): void;
34
36
  log: {
@@ -57,8 +57,11 @@ export class InkUI {
57
57
  showPortConflict(processInfo) {
58
58
  return this.store.showPortConflict(processInfo);
59
59
  }
60
- showSettingsOverride(keys, backupAndFix) {
61
- return this.store.showSettingsOverride(keys, backupAndFix);
60
+ showSettingsOverride(conflicts, backupAndFix) {
61
+ return this.store.showSettingsOverride(conflicts, backupAndFix);
62
+ }
63
+ showAuthError() {
64
+ this.store.showAuthError();
62
65
  }
63
66
  startRun() {
64
67
  this.store.setRunPhase(RunPhase.Running);
@@ -1 +1 @@
1
- {"version":3,"file":"ink-ui.js","sourceRoot":"","sources":["../../../../src/ui/tui/ink-ui.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * InkUI — Ink-backed implementation of WizardUI.\n *\n * Translates business logic calls into store setter calls.\n * No direct session mutation. No imperative screen transitions.\n * The router derives the active screen from session state.\n */\n\nimport type { WizardUI, SpinnerHandle } from '../wizard-ui.js';\nimport type { WizardStore } from './store.js';\nimport { RunPhase, OutroKind } from '../../lib/wizard-session.js';\n\n// Strip ANSI escape codes (chalk formatting) from strings\n// eslint-disable-next-line no-control-regex\nconst ANSI_RE = /\\x1b\\[[0-9;]*m/g;\nfunction stripAnsi(s: string): string {\n return s.replace(ANSI_RE, '');\n}\n\nexport class InkUI implements WizardUI {\n constructor(private store: WizardStore) {}\n\n intro(message: string): void {\n this.store.pushStatus(message);\n }\n\n outro(message: string): void {\n this.store.pushStatus(stripAnsi(message));\n\n if (!this.store.session.outroData) {\n this.store.setOutroData({\n kind: OutroKind.Success,\n message: stripAnsi(message),\n });\n }\n\n // Signal that the main work is done — router resolves to mcp or outro\n if (this.store.session.runPhase === RunPhase.Running) {\n this.store.setRunPhase(RunPhase.Completed);\n }\n }\n\n setCredentials(credentials: {\n accessToken: string;\n projectApiKey: string;\n host: string;\n projectId: number;\n }): void {\n this.store.setCredentials(credentials);\n }\n\n setDetectedFramework(label: string): void {\n this.store.setDetectedFramework(label);\n }\n\n onEnterScreen(screen: string, fn: () => void): void {\n this.store.onEnterScreen(\n screen as Parameters<WizardStore['onEnterScreen']>[0],\n fn,\n );\n }\n\n setLoginUrl(url: string | null): void {\n this.store.setLoginUrl(url);\n }\n\n showBlockingOutage(\n result: import('../../lib/health-checks/readiness.js').WizardReadinessResult,\n ): Promise<void> {\n // In the TUI, the HealthCheckScreen handles outage display.\n // This is only called from agent-runner for the CI fallback path.\n this.store.setReadinessResult(result);\n return Promise.resolve();\n }\n\n setReadinessWarnings(\n result: import('../../lib/health-checks/readiness.js').WizardReadinessResult,\n ): void {\n this.store.setReadinessResult(result);\n }\n\n showPortConflict(processInfo: {\n command: string;\n pid: string;\n user: string;\n }): Promise<void> {\n return this.store.showPortConflict(processInfo);\n }\n\n showSettingsOverride(\n keys: string[],\n backupAndFix: () => boolean,\n ): Promise<void> {\n return this.store.showSettingsOverride(keys, backupAndFix);\n }\n\n startRun(): void {\n this.store.setRunPhase(RunPhase.Running);\n }\n\n cancel(message: string): void {\n this.store.pushStatus(message);\n }\n\n log = {\n info: (message: string): void => {\n this.store.pushStatus(message);\n },\n warn: (message: string): void => {\n this.store.pushStatus(message);\n },\n error: (message: string): void => {\n this.store.pushStatus(message);\n },\n success: (message: string): void => {\n this.store.pushStatus(message);\n },\n step: (message: string): void => {\n this.store.pushStatus(message);\n },\n };\n\n note(message: string): void {\n this.store.pushStatus(message);\n }\n\n spinner(): SpinnerHandle {\n return {\n start: (message?: string) => {\n if (message) this.store.pushStatus(message);\n },\n stop: (message?: string) => {\n if (message) this.store.pushStatus(message);\n },\n message: (msg?: string) => {\n if (msg) this.store.pushStatus(msg);\n },\n };\n }\n\n pushStatus(message: string): void {\n this.store.pushStatus(message);\n }\n\n syncTodos(\n todos: Array<{ content: string; status: string; activeForm?: string }>,\n ): void {\n this.store.syncTodos(todos);\n }\n\n setEventPlan(events: Array<{ name: string; description: string }>): void {\n this.store.setEventPlan(events);\n }\n}\n"]}
1
+ {"version":3,"file":"ink-ui.js","sourceRoot":"","sources":["../../../../src/ui/tui/ink-ui.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * InkUI — Ink-backed implementation of WizardUI.\n *\n * Translates business logic calls into store setter calls.\n * No direct session mutation. No imperative screen transitions.\n * The router derives the active screen from session state.\n */\n\nimport type { WizardUI, SpinnerHandle } from '../wizard-ui.js';\nimport type { WizardStore } from './store.js';\nimport type { SettingsConflict } from '../../lib/agent-interface.js';\nimport { RunPhase, OutroKind } from '../../lib/wizard-session.js';\n\n// Strip ANSI escape codes (chalk formatting) from strings\n// eslint-disable-next-line no-control-regex\nconst ANSI_RE = /\\x1b\\[[0-9;]*m/g;\nfunction stripAnsi(s: string): string {\n return s.replace(ANSI_RE, '');\n}\n\nexport class InkUI implements WizardUI {\n constructor(private store: WizardStore) {}\n\n intro(message: string): void {\n this.store.pushStatus(message);\n }\n\n outro(message: string): void {\n this.store.pushStatus(stripAnsi(message));\n\n if (!this.store.session.outroData) {\n this.store.setOutroData({\n kind: OutroKind.Success,\n message: stripAnsi(message),\n });\n }\n\n // Signal that the main work is done — router resolves to mcp or outro\n if (this.store.session.runPhase === RunPhase.Running) {\n this.store.setRunPhase(RunPhase.Completed);\n }\n }\n\n setCredentials(credentials: {\n accessToken: string;\n projectApiKey: string;\n host: string;\n projectId: number;\n }): void {\n this.store.setCredentials(credentials);\n }\n\n setDetectedFramework(label: string): void {\n this.store.setDetectedFramework(label);\n }\n\n onEnterScreen(screen: string, fn: () => void): void {\n this.store.onEnterScreen(\n screen as Parameters<WizardStore['onEnterScreen']>[0],\n fn,\n );\n }\n\n setLoginUrl(url: string | null): void {\n this.store.setLoginUrl(url);\n }\n\n showBlockingOutage(\n result: import('../../lib/health-checks/readiness.js').WizardReadinessResult,\n ): Promise<void> {\n // In the TUI, the HealthCheckScreen handles outage display.\n // This is only called from agent-runner for the CI fallback path.\n this.store.setReadinessResult(result);\n return Promise.resolve();\n }\n\n setReadinessWarnings(\n result: import('../../lib/health-checks/readiness.js').WizardReadinessResult,\n ): void {\n this.store.setReadinessResult(result);\n }\n\n showPortConflict(processInfo: {\n command: string;\n pid: string;\n user: string;\n }): Promise<void> {\n return this.store.showPortConflict(processInfo);\n }\n\n showSettingsOverride(\n conflicts: SettingsConflict[],\n backupAndFix: () => boolean,\n ): Promise<void> {\n return this.store.showSettingsOverride(conflicts, backupAndFix);\n }\n\n showAuthError(): void {\n this.store.showAuthError();\n }\n\n startRun(): void {\n this.store.setRunPhase(RunPhase.Running);\n }\n\n cancel(message: string): void {\n this.store.pushStatus(message);\n }\n\n log = {\n info: (message: string): void => {\n this.store.pushStatus(message);\n },\n warn: (message: string): void => {\n this.store.pushStatus(message);\n },\n error: (message: string): void => {\n this.store.pushStatus(message);\n },\n success: (message: string): void => {\n this.store.pushStatus(message);\n },\n step: (message: string): void => {\n this.store.pushStatus(message);\n },\n };\n\n note(message: string): void {\n this.store.pushStatus(message);\n }\n\n spinner(): SpinnerHandle {\n return {\n start: (message?: string) => {\n if (message) this.store.pushStatus(message);\n },\n stop: (message?: string) => {\n if (message) this.store.pushStatus(message);\n },\n message: (msg?: string) => {\n if (msg) this.store.pushStatus(msg);\n },\n };\n }\n\n pushStatus(message: string): void {\n this.store.pushStatus(message);\n }\n\n syncTodos(\n todos: Array<{ content: string; status: string; activeForm?: string }>,\n ): void {\n this.store.syncTodos(todos);\n }\n\n setEventPlan(events: Array<{ name: string; description: string }>): void {\n this.store.setEventPlan(events);\n }\n}\n"]}
@@ -40,6 +40,7 @@ const MOCK_HEALTH = {
40
40
  cloudflareComponents: { status: ServiceHealthStatus.Healthy },
41
41
  llmGateway: HEALTHY,
42
42
  mcp: HEALTHY,
43
+ githubReleases: HEALTHY,
43
44
  };
44
45
  export const HealthCheckDemo = () => {
45
46
  const [showOutage, setShowOutage] = useState(false);
@@ -1 +1 @@
1
- {"version":3,"file":"HealthCheckDemo.js","sourceRoot":"","sources":["../../../../../../src/ui/tui/playground/demos/HealthCheckDemo.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * HealthCheckDemo — Playground demo for health check UI components.\n *\n * Shows the ModalOverlay with ServiceHealthList, cycling through states:\n * 1. Checking (spinner) — 2 seconds\n * 2. Blocking outage modal (Anthropic down, npm degraded)\n *\n * Renders components directly (not HealthCheckScreen) to avoid useInput\n * conflicts with TabContainer's key handling.\n */\n\nimport { useEffect, useState } from 'react';\nimport { Box, Text } from 'ink';\nimport { LoadingBox, ModalOverlay } from '../../primitives/index.js';\nimport { Icons } from '../../styles.js';\nimport { ServiceHealthList } from '../../components/ServiceHealthList.js';\nimport { getBlockingServiceKeys } from '../../../../lib/health-checks/readiness.js';\nimport { ServiceHealthStatus } from '../../../../lib/health-checks/types.js';\nimport type { AllServicesHealth } from '../../../../lib/health-checks/types.js';\n\nconst HEALTHY = { status: ServiceHealthStatus.Healthy } as const;\n\nconst MOCK_HEALTH: AllServicesHealth = {\n anthropic: { status: ServiceHealthStatus.Down, rawIndicator: 'major' },\n posthogOverall: HEALTHY,\n posthogComponents: { status: ServiceHealthStatus.Healthy },\n github: HEALTHY,\n npmOverall: {\n status: ServiceHealthStatus.Degraded,\n rawIndicator: 'minor',\n },\n npmComponents: {\n status: ServiceHealthStatus.Degraded,\n degradedOrDownComponents: [\n {\n name: 'Registry API',\n status: ServiceHealthStatus.Degraded,\n rawStatus: 'degraded_performance',\n },\n ],\n },\n cloudflareOverall: HEALTHY,\n cloudflareComponents: { status: ServiceHealthStatus.Healthy },\n llmGateway: HEALTHY,\n mcp: HEALTHY,\n};\n\nexport const HealthCheckDemo = () => {\n const [showOutage, setShowOutage] = useState(false);\n\n useEffect(() => {\n const timer = setTimeout(() => setShowOutage(true), 2000);\n return () => clearTimeout(timer);\n }, []);\n\n if (!showOutage) {\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n <LoadingBox message=\"Checking service status...\" />\n </Box>\n );\n }\n\n const blockingKeys = getBlockingServiceKeys(MOCK_HEALTH);\n\n return (\n <ModalOverlay\n borderColor=\"red\"\n title={`${Icons.warning} Ongoing service disruptions`}\n width={72}\n footer={\n <Box marginLeft={2}>\n <Text dimColor>\n Continue [Enter] / Exit [Esc] (disabled in playground)\n </Text>\n </Box>\n }\n >\n <Box flexDirection=\"column\" marginBottom={1}>\n <Box marginBottom={1}>\n <Text>\n <Text color=\"red\">{Icons.squareFilled}</Text>\n <Text dimColor> Down </Text>\n <Text color=\"#DC9300\">{Icons.squareFilled}</Text>\n <Text dimColor> Degraded</Text>\n </Text>\n </Box>\n\n <ServiceHealthList\n health={MOCK_HEALTH}\n filterKeys={blockingKeys}\n showHealthy={false}\n />\n </Box>\n\n <Text dimColor>\n The wizard may not work reliably while services are affected.\n </Text>\n </ModalOverlay>\n );\n};\n"]}
1
+ {"version":3,"file":"HealthCheckDemo.js","sourceRoot":"","sources":["../../../../../../src/ui/tui/playground/demos/HealthCheckDemo.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * HealthCheckDemo — Playground demo for health check UI components.\n *\n * Shows the ModalOverlay with ServiceHealthList, cycling through states:\n * 1. Checking (spinner) — 2 seconds\n * 2. Blocking outage modal (Anthropic down, npm degraded)\n *\n * Renders components directly (not HealthCheckScreen) to avoid useInput\n * conflicts with TabContainer's key handling.\n */\n\nimport { useEffect, useState } from 'react';\nimport { Box, Text } from 'ink';\nimport { LoadingBox, ModalOverlay } from '../../primitives/index.js';\nimport { Icons } from '../../styles.js';\nimport { ServiceHealthList } from '../../components/ServiceHealthList.js';\nimport { getBlockingServiceKeys } from '../../../../lib/health-checks/readiness.js';\nimport { ServiceHealthStatus } from '../../../../lib/health-checks/types.js';\nimport type { AllServicesHealth } from '../../../../lib/health-checks/types.js';\n\nconst HEALTHY = { status: ServiceHealthStatus.Healthy } as const;\n\nconst MOCK_HEALTH: AllServicesHealth = {\n anthropic: { status: ServiceHealthStatus.Down, rawIndicator: 'major' },\n posthogOverall: HEALTHY,\n posthogComponents: { status: ServiceHealthStatus.Healthy },\n github: HEALTHY,\n npmOverall: {\n status: ServiceHealthStatus.Degraded,\n rawIndicator: 'minor',\n },\n npmComponents: {\n status: ServiceHealthStatus.Degraded,\n degradedOrDownComponents: [\n {\n name: 'Registry API',\n status: ServiceHealthStatus.Degraded,\n rawStatus: 'degraded_performance',\n },\n ],\n },\n cloudflareOverall: HEALTHY,\n cloudflareComponents: { status: ServiceHealthStatus.Healthy },\n llmGateway: HEALTHY,\n mcp: HEALTHY,\n githubReleases: HEALTHY,\n};\n\nexport const HealthCheckDemo = () => {\n const [showOutage, setShowOutage] = useState(false);\n\n useEffect(() => {\n const timer = setTimeout(() => setShowOutage(true), 2000);\n return () => clearTimeout(timer);\n }, []);\n\n if (!showOutage) {\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n <LoadingBox message=\"Checking service status...\" />\n </Box>\n );\n }\n\n const blockingKeys = getBlockingServiceKeys(MOCK_HEALTH);\n\n return (\n <ModalOverlay\n borderColor=\"red\"\n title={`${Icons.warning} Ongoing service disruptions`}\n width={72}\n footer={\n <Box marginLeft={2}>\n <Text dimColor>\n Continue [Enter] / Exit [Esc] (disabled in playground)\n </Text>\n </Box>\n }\n >\n <Box flexDirection=\"column\" marginBottom={1}>\n <Box marginBottom={1}>\n <Text>\n <Text color=\"red\">{Icons.squareFilled}</Text>\n <Text dimColor> Down </Text>\n <Text color=\"#DC9300\">{Icons.squareFilled}</Text>\n <Text dimColor> Degraded</Text>\n </Text>\n </Box>\n\n <ServiceHealthList\n health={MOCK_HEALTH}\n filterKeys={blockingKeys}\n showHealthy={false}\n />\n </Box>\n\n <Text dimColor>\n The wizard may not work reliably while services are affected.\n </Text>\n </ModalOverlay>\n );\n};\n"]}
@@ -18,7 +18,9 @@ export type { FlowEntry };
18
18
  /** Screens that interrupt flows as overlays */
19
19
  export declare enum Overlay {
20
20
  SettingsOverride = "settings-override",
21
- PortConflict = "port-conflict"
21
+ ManagedSettings = "managed-settings",
22
+ PortConflict = "port-conflict",
23
+ AuthError = "auth-error"
22
24
  }
23
25
  /** Union of all screen names */
24
26
  export type ScreenName = Screen | Overlay;