@posthog/wizard 2.2.0 → 2.3.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/src/lib/agent-runner.js +4 -4
- package/dist/src/lib/agent-runner.js.map +1 -1
- package/dist/src/lib/constants.d.ts +1 -1
- package/dist/src/lib/health-checks/__tests__/health-checks.test.js +11 -4
- package/dist/src/lib/health-checks/__tests__/health-checks.test.js.map +1 -1
- package/dist/src/lib/health-checks/endpoints.d.ts +1 -0
- package/dist/src/lib/health-checks/endpoints.js +3 -1
- package/dist/src/lib/health-checks/endpoints.js.map +1 -1
- package/dist/src/lib/health-checks/index.d.ts +1 -1
- package/dist/src/lib/health-checks/index.js +2 -1
- package/dist/src/lib/health-checks/index.js.map +1 -1
- package/dist/src/lib/health-checks/readiness.js +12 -3
- package/dist/src/lib/health-checks/readiness.js.map +1 -1
- package/dist/src/lib/health-checks/types.d.ts +1 -0
- package/dist/src/lib/health-checks/types.js.map +1 -1
- package/dist/src/lib/version.d.ts +1 -1
- package/dist/src/lib/version.js +1 -1
- package/dist/src/lib/version.js.map +1 -1
- package/dist/src/lib/wizard-tools.d.ts +22 -0
- package/dist/src/lib/wizard-tools.js +71 -39
- package/dist/src/lib/wizard-tools.js.map +1 -1
- package/dist/src/ui/tui/playground/demos/HealthCheckDemo.js +1 -0
- package/dist/src/ui/tui/playground/demos/HealthCheckDemo.js.map +1 -1
- package/dist/src/ui/tui/screens/health/HealthCheckScreen.js +50 -5
- package/dist/src/ui/tui/screens/health/HealthCheckScreen.js.map +1 -1
- package/dist/src/utils/__tests__/semver.test.js +45 -3
- package/dist/src/utils/__tests__/semver.test.js.map +1 -1
- package/dist/src/utils/semver.js +25 -0
- package/dist/src/utils/semver.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/lib/health-checks/index.ts"],"names":[],"mappings":";;;AAAA,iCAOiB;AANf,4GAAA,mBAAmB,OAAA;AAQrB,2CASsB;AARpB,kHAAA,oBAAoB,OAAA;AACpB,uHAAA,yBAAyB,OAAA;AACzB,yHAAA,2BAA2B,OAAA;AAC3B,+GAAA,iBAAiB,OAAA;AACjB,mHAAA,qBAAqB,OAAA;AACrB,qHAAA,uBAAuB,OAAA;AACvB,0HAAA,4BAA4B,OAAA;AAC5B,4HAAA,8BAA8B,OAAA;AAGhC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/lib/health-checks/index.ts"],"names":[],"mappings":";;;AAAA,iCAOiB;AANf,4GAAA,mBAAmB,OAAA;AAQrB,2CASsB;AARpB,kHAAA,oBAAoB,OAAA;AACpB,uHAAA,yBAAyB,OAAA;AACzB,yHAAA,2BAA2B,OAAA;AAC3B,+GAAA,iBAAiB,OAAA;AACjB,mHAAA,qBAAqB,OAAA;AACrB,qHAAA,uBAAuB,OAAA;AACvB,0HAAA,4BAA4B,OAAA;AAC5B,4HAAA,8BAA8B,OAAA;AAGhC,yCAIqB;AAHnB,kHAAA,qBAAqB,OAAA;AACrB,2GAAA,cAAc,OAAA;AACd,sHAAA,yBAAyB,OAAA;AAG3B,yCAOqB;AALnB,4HAAA,+BAA+B,OAAA;AAC/B,qHAAA,wBAAwB,OAAA;AACxB,4GAAA,eAAe,OAAA;AAEf,oHAAA,uBAAuB,OAAA","sourcesContent":["export {\n ServiceHealthStatus,\n type BaseHealthResult,\n type ComponentStatus,\n type ComponentHealthResult,\n type AllServicesHealth,\n type HealthCheckKey,\n} from './types';\n\nexport {\n checkAnthropicHealth,\n checkPosthogOverallHealth,\n checkPosthogComponentHealth,\n checkGithubHealth,\n checkNpmOverallHealth,\n checkNpmComponentHealth,\n checkCloudflareOverallHealth,\n checkCloudflareComponentHealth,\n} from './statuspage';\n\nexport {\n checkLlmGatewayHealth,\n checkMcpHealth,\n checkGithubReleasesHealth,\n} from './endpoints';\n\nexport {\n type WizardReadinessConfig,\n DEFAULT_WIZARD_READINESS_CONFIG,\n checkAllExternalServices,\n WizardReadiness,\n type WizardReadinessResult,\n evaluateWizardReadiness,\n} from './readiness';\n"]}
|
|
@@ -7,6 +7,7 @@ exports.getBlockingServiceKeys = getBlockingServiceKeys;
|
|
|
7
7
|
const types_1 = require("./types");
|
|
8
8
|
const statuspage_1 = require("./statuspage");
|
|
9
9
|
const endpoints_1 = require("./endpoints");
|
|
10
|
+
const debug_1 = require("../../utils/debug");
|
|
10
11
|
// ---------------------------------------------------------------------------
|
|
11
12
|
// Service labels (used in human-readable reason strings)
|
|
12
13
|
// ---------------------------------------------------------------------------
|
|
@@ -21,6 +22,7 @@ exports.SERVICE_LABELS = {
|
|
|
21
22
|
cloudflareComponents: 'Cloudflare (components)',
|
|
22
23
|
llmGateway: 'LLM Gateway',
|
|
23
24
|
mcp: 'MCP',
|
|
25
|
+
githubReleases: 'GitHub Releases',
|
|
24
26
|
};
|
|
25
27
|
/**
|
|
26
28
|
* See README section "Health checks" for the full rationale.
|
|
@@ -33,6 +35,7 @@ exports.DEFAULT_WIZARD_READINESS_CONFIG = {
|
|
|
33
35
|
'npmOverall',
|
|
34
36
|
'llmGateway',
|
|
35
37
|
'mcp',
|
|
38
|
+
'githubReleases',
|
|
36
39
|
],
|
|
37
40
|
degradedBlocksRun: ['anthropic'],
|
|
38
41
|
};
|
|
@@ -40,7 +43,7 @@ exports.DEFAULT_WIZARD_READINESS_CONFIG = {
|
|
|
40
43
|
// Aggregate check
|
|
41
44
|
// ---------------------------------------------------------------------------
|
|
42
45
|
async function checkAllExternalServices() {
|
|
43
|
-
const [anthropic, posthogOverall, posthogComponents, github, npmOverall, npmComponents, cloudflareOverall, cloudflareComponents, llmGateway, mcp,] = await Promise.all([
|
|
46
|
+
const [anthropic, posthogOverall, posthogComponents, github, npmOverall, npmComponents, cloudflareOverall, cloudflareComponents, llmGateway, mcp, githubReleases,] = await Promise.all([
|
|
44
47
|
(0, statuspage_1.checkAnthropicHealth)(),
|
|
45
48
|
(0, statuspage_1.checkPosthogOverallHealth)(),
|
|
46
49
|
(0, statuspage_1.checkPosthogComponentHealth)(),
|
|
@@ -51,6 +54,7 @@ async function checkAllExternalServices() {
|
|
|
51
54
|
(0, statuspage_1.checkCloudflareComponentHealth)(),
|
|
52
55
|
(0, endpoints_1.checkLlmGatewayHealth)(),
|
|
53
56
|
(0, endpoints_1.checkMcpHealth)(),
|
|
57
|
+
(0, endpoints_1.checkGithubReleasesHealth)(),
|
|
54
58
|
]);
|
|
55
59
|
return {
|
|
56
60
|
anthropic,
|
|
@@ -63,6 +67,7 @@ async function checkAllExternalServices() {
|
|
|
63
67
|
cloudflareComponents,
|
|
64
68
|
llmGateway,
|
|
65
69
|
mcp,
|
|
70
|
+
githubReleases,
|
|
66
71
|
};
|
|
67
72
|
}
|
|
68
73
|
// ---------------------------------------------------------------------------
|
|
@@ -111,7 +116,9 @@ async function evaluateWizardReadiness(config = exports.DEFAULT_WIZARD_READINESS
|
|
|
111
116
|
reasons.push(describeComponents(label, result));
|
|
112
117
|
}
|
|
113
118
|
}
|
|
114
|
-
|
|
119
|
+
const blockingKeys = getBlockingServiceKeys(health, config);
|
|
120
|
+
if (blockingKeys.length > 0) {
|
|
121
|
+
(0, debug_1.logToFile)(`[health-checks] blocked by: ${blockingKeys.join(', ')}`);
|
|
115
122
|
return { decision: WizardReadiness.No, health, reasons };
|
|
116
123
|
}
|
|
117
124
|
const hasWarnings = Object.values(health).some((h) => h.status !== types_1.ServiceHealthStatus.Healthy);
|
|
@@ -120,7 +127,8 @@ async function evaluateWizardReadiness(config = exports.DEFAULT_WIZARD_READINESS
|
|
|
120
127
|
}
|
|
121
128
|
return { decision: WizardReadiness.Yes, health, reasons };
|
|
122
129
|
}
|
|
123
|
-
catch {
|
|
130
|
+
catch (err) {
|
|
131
|
+
(0, debug_1.logToFile)(`[health-checks] error: ${err instanceof Error ? err.message : err}`);
|
|
124
132
|
// Health checks must never block the wizard run
|
|
125
133
|
return {
|
|
126
134
|
decision: WizardReadiness.Yes,
|
|
@@ -174,6 +182,7 @@ function allUnknown(error) {
|
|
|
174
182
|
cloudflareComponents: { ...base },
|
|
175
183
|
llmGateway: base,
|
|
176
184
|
mcp: base,
|
|
185
|
+
githubReleases: base,
|
|
177
186
|
};
|
|
178
187
|
}
|
|
179
188
|
//# sourceMappingURL=readiness.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readiness.js","sourceRoot":"","sources":["../../../../src/lib/health-checks/readiness.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ServiceHealthStatus,\n type AllServicesHealth,\n type BaseHealthResult,\n type ComponentHealthResult,\n type HealthCheckKey,\n} from './types';\nimport {\n checkAnthropicHealth,\n checkPosthogOverallHealth,\n checkPosthogComponentHealth,\n checkGithubHealth,\n checkNpmOverallHealth,\n checkNpmComponentHealth,\n checkCloudflareOverallHealth,\n checkCloudflareComponentHealth,\n} from './statuspage';\nimport { checkLlmGatewayHealth, checkMcpHealth } from './endpoints';\n\n// ---------------------------------------------------------------------------\n// Service labels (used in human-readable reason strings)\n// ---------------------------------------------------------------------------\n\nexport const SERVICE_LABELS: Record<HealthCheckKey, string> = {\n anthropic: 'Anthropic',\n posthogOverall: 'PostHog',\n posthogComponents: 'PostHog (components)',\n github: 'GitHub',\n npmOverall: 'npm',\n npmComponents: 'npm (components)',\n cloudflareOverall: 'Cloudflare',\n cloudflareComponents: 'Cloudflare (components)',\n llmGateway: 'LLM Gateway',\n mcp: 'MCP',\n};\n\n// ---------------------------------------------------------------------------\n// Readiness config\n// ---------------------------------------------------------------------------\n\nexport interface WizardReadinessConfig {\n /** Services where status=Down blocks the run (readiness=No). */\n downBlocksRun: HealthCheckKey[];\n /** Services where status=Degraded (or worse) blocks the run (readiness=No). */\n degradedBlocksRun?: HealthCheckKey[];\n}\n\n/**\n * See README section \"Health checks\" for the full rationale.\n * Adjust these arrays to change what blocks a wizard run.\n */\nexport const DEFAULT_WIZARD_READINESS_CONFIG: WizardReadinessConfig = {\n downBlocksRun: [\n 'anthropic',\n 'posthogOverall',\n 'npmOverall',\n 'llmGateway',\n 'mcp',\n ],\n degradedBlocksRun: ['anthropic'],\n};\n\n// ---------------------------------------------------------------------------\n// Aggregate check\n// ---------------------------------------------------------------------------\n\nexport async function checkAllExternalServices(): Promise<AllServicesHealth> {\n const [\n anthropic,\n posthogOverall,\n posthogComponents,\n github,\n npmOverall,\n npmComponents,\n cloudflareOverall,\n cloudflareComponents,\n llmGateway,\n mcp,\n ] = await Promise.all([\n checkAnthropicHealth(),\n checkPosthogOverallHealth(),\n checkPosthogComponentHealth(),\n checkGithubHealth(),\n checkNpmOverallHealth(),\n checkNpmComponentHealth(),\n checkCloudflareOverallHealth(),\n checkCloudflareComponentHealth(),\n checkLlmGatewayHealth(),\n checkMcpHealth(),\n ]);\n return {\n anthropic,\n posthogOverall,\n posthogComponents,\n github,\n npmOverall,\n npmComponents,\n cloudflareOverall,\n cloudflareComponents,\n llmGateway,\n mcp,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Wizard readiness evaluation\n// ---------------------------------------------------------------------------\n\nexport enum WizardReadiness {\n Yes = 'yes',\n No = 'no',\n YesWithWarnings = 'yes_with_warnings',\n}\n\nexport interface WizardReadinessResult {\n decision: WizardReadiness;\n health: AllServicesHealth;\n reasons: string[];\n}\n\nfunction describeResult(label: string, h: BaseHealthResult): string {\n const parts = [`${label}: ${h.status}`];\n if (h.rawIndicator) parts.push(`indicator=${h.rawIndicator}`);\n if (h.error) parts.push(h.error);\n return parts.join(' — ');\n}\n\nconst MAX_COMPONENT_NAMES = 8;\n\nfunction describeComponents(label: string, h: ComponentHealthResult): string {\n const affected = h.degradedOrDownComponents;\n if (!affected || affected.length === 0)\n return `${label} components: all operational`;\n const shown = affected\n .slice(0, MAX_COMPONENT_NAMES)\n .map((c) => `${c.name} (${c.status})`);\n const suffix =\n affected.length > MAX_COMPONENT_NAMES\n ? `, +${affected.length - MAX_COMPONENT_NAMES} more`\n : '';\n return `${label} components impacted: ${shown.join(', ')}${suffix}`;\n}\n\nconst READINESS_TIMEOUT_MS = 10_000;\n\nexport async function evaluateWizardReadiness(\n config: WizardReadinessConfig = DEFAULT_WIZARD_READINESS_CONFIG,\n): Promise<WizardReadinessResult> {\n try {\n const health = await Promise.race([\n checkAllExternalServices(),\n new Promise<AllServicesHealth>((resolve) =>\n setTimeout(\n () => resolve(allUnknown('Health check timed out')),\n READINESS_TIMEOUT_MS,\n ),\n ),\n ]);\n\n const reasons: string[] = [];\n\n for (const key of Object.keys(health) as HealthCheckKey[]) {\n const result = health[key];\n const label = SERVICE_LABELS[key];\n\n reasons.push(describeResult(label, result));\n\n if ('degradedOrDownComponents' in result) {\n reasons.push(describeComponents(label, result));\n }\n }\n\n if (getBlockingServiceKeys(health, config).length > 0) {\n return { decision: WizardReadiness.No, health, reasons };\n }\n\n const hasWarnings = Object.values(health).some(\n (h) => h.status !== ServiceHealthStatus.Healthy,\n );\n\n if (hasWarnings) {\n return { decision: WizardReadiness.YesWithWarnings, health, reasons };\n }\n\n return { decision: WizardReadiness.Yes, health, reasons };\n } catch {\n // Health checks must never block the wizard run\n return {\n decision: WizardReadiness.Yes,\n health: allUnknown('Unexpected error'),\n reasons: ['Health check failed unexpectedly — proceeding anyway'],\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Blocking service detection\n// ---------------------------------------------------------------------------\n\n/** Keys that are component-level detail, not top-level services. */\nconst COMPONENT_KEYS: HealthCheckKey[] = [\n 'posthogComponents',\n 'npmComponents',\n 'cloudflareComponents',\n];\n\n/**\n * Get the keys of services that would block a wizard run per the given config.\n */\nexport function getBlockingServiceKeys(\n health: AllServicesHealth,\n config: WizardReadinessConfig = DEFAULT_WIZARD_READINESS_CONFIG,\n): HealthCheckKey[] {\n return (Object.keys(health) as HealthCheckKey[]).filter((key) => {\n if (COMPONENT_KEYS.includes(key)) return false;\n const result = health[key];\n if (\n config.downBlocksRun.includes(key) &&\n result.status === ServiceHealthStatus.Down\n ) {\n return true;\n }\n if (\n (config.degradedBlocksRun ?? []).includes(key) &&\n result.status !== ServiceHealthStatus.Healthy\n ) {\n return true;\n }\n return false;\n });\n}\n\n/** Build an AllServicesHealth where every service is Degraded with the given error. */\nfunction allUnknown(error: string): AllServicesHealth {\n const base: BaseHealthResult = {\n status: ServiceHealthStatus.Degraded,\n error,\n };\n return {\n anthropic: base,\n posthogOverall: base,\n posthogComponents: { ...base },\n github: base,\n npmOverall: base,\n npmComponents: { ...base },\n cloudflareOverall: base,\n cloudflareComponents: { ...base },\n llmGateway: base,\n mcp: base,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"readiness.js","sourceRoot":"","sources":["../../../../src/lib/health-checks/readiness.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ServiceHealthStatus,\n type AllServicesHealth,\n type BaseHealthResult,\n type ComponentHealthResult,\n type HealthCheckKey,\n} from './types';\nimport {\n checkAnthropicHealth,\n checkPosthogOverallHealth,\n checkPosthogComponentHealth,\n checkGithubHealth,\n checkNpmOverallHealth,\n checkNpmComponentHealth,\n checkCloudflareOverallHealth,\n checkCloudflareComponentHealth,\n} from './statuspage';\nimport {\n checkLlmGatewayHealth,\n checkMcpHealth,\n checkGithubReleasesHealth,\n} from './endpoints';\nimport { logToFile } from '../../utils/debug';\n\n// ---------------------------------------------------------------------------\n// Service labels (used in human-readable reason strings)\n// ---------------------------------------------------------------------------\n\nexport const SERVICE_LABELS: Record<HealthCheckKey, string> = {\n anthropic: 'Anthropic',\n posthogOverall: 'PostHog',\n posthogComponents: 'PostHog (components)',\n github: 'GitHub',\n npmOverall: 'npm',\n npmComponents: 'npm (components)',\n cloudflareOverall: 'Cloudflare',\n cloudflareComponents: 'Cloudflare (components)',\n llmGateway: 'LLM Gateway',\n mcp: 'MCP',\n githubReleases: 'GitHub Releases',\n};\n\n// ---------------------------------------------------------------------------\n// Readiness config\n// ---------------------------------------------------------------------------\n\nexport interface WizardReadinessConfig {\n /** Services where status=Down blocks the run (readiness=No). */\n downBlocksRun: HealthCheckKey[];\n /** Services where status=Degraded (or worse) blocks the run (readiness=No). */\n degradedBlocksRun?: HealthCheckKey[];\n}\n\n/**\n * See README section \"Health checks\" for the full rationale.\n * Adjust these arrays to change what blocks a wizard run.\n */\nexport const DEFAULT_WIZARD_READINESS_CONFIG: WizardReadinessConfig = {\n downBlocksRun: [\n 'anthropic',\n 'posthogOverall',\n 'npmOverall',\n 'llmGateway',\n 'mcp',\n 'githubReleases',\n ],\n degradedBlocksRun: ['anthropic'],\n};\n\n// ---------------------------------------------------------------------------\n// Aggregate check\n// ---------------------------------------------------------------------------\n\nexport async function checkAllExternalServices(): Promise<AllServicesHealth> {\n const [\n anthropic,\n posthogOverall,\n posthogComponents,\n github,\n npmOverall,\n npmComponents,\n cloudflareOverall,\n cloudflareComponents,\n llmGateway,\n mcp,\n githubReleases,\n ] = await Promise.all([\n checkAnthropicHealth(),\n checkPosthogOverallHealth(),\n checkPosthogComponentHealth(),\n checkGithubHealth(),\n checkNpmOverallHealth(),\n checkNpmComponentHealth(),\n checkCloudflareOverallHealth(),\n checkCloudflareComponentHealth(),\n checkLlmGatewayHealth(),\n checkMcpHealth(),\n checkGithubReleasesHealth(),\n ]);\n\n return {\n anthropic,\n posthogOverall,\n posthogComponents,\n github,\n npmOverall,\n npmComponents,\n cloudflareOverall,\n cloudflareComponents,\n llmGateway,\n mcp,\n githubReleases,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Wizard readiness evaluation\n// ---------------------------------------------------------------------------\n\nexport enum WizardReadiness {\n Yes = 'yes',\n No = 'no',\n YesWithWarnings = 'yes_with_warnings',\n}\n\nexport interface WizardReadinessResult {\n decision: WizardReadiness;\n health: AllServicesHealth;\n reasons: string[];\n}\n\nfunction describeResult(label: string, h: BaseHealthResult): string {\n const parts = [`${label}: ${h.status}`];\n if (h.rawIndicator) parts.push(`indicator=${h.rawIndicator}`);\n if (h.error) parts.push(h.error);\n return parts.join(' — ');\n}\n\nconst MAX_COMPONENT_NAMES = 8;\n\nfunction describeComponents(label: string, h: ComponentHealthResult): string {\n const affected = h.degradedOrDownComponents;\n if (!affected || affected.length === 0)\n return `${label} components: all operational`;\n const shown = affected\n .slice(0, MAX_COMPONENT_NAMES)\n .map((c) => `${c.name} (${c.status})`);\n const suffix =\n affected.length > MAX_COMPONENT_NAMES\n ? `, +${affected.length - MAX_COMPONENT_NAMES} more`\n : '';\n return `${label} components impacted: ${shown.join(', ')}${suffix}`;\n}\n\nconst READINESS_TIMEOUT_MS = 10_000;\n\nexport async function evaluateWizardReadiness(\n config: WizardReadinessConfig = DEFAULT_WIZARD_READINESS_CONFIG,\n): Promise<WizardReadinessResult> {\n try {\n const health = await Promise.race([\n checkAllExternalServices(),\n new Promise<AllServicesHealth>((resolve) =>\n setTimeout(\n () => resolve(allUnknown('Health check timed out')),\n READINESS_TIMEOUT_MS,\n ),\n ),\n ]);\n\n const reasons: string[] = [];\n\n for (const key of Object.keys(health) as HealthCheckKey[]) {\n const result = health[key];\n const label = SERVICE_LABELS[key];\n\n reasons.push(describeResult(label, result));\n\n if ('degradedOrDownComponents' in result) {\n reasons.push(describeComponents(label, result));\n }\n }\n\n const blockingKeys = getBlockingServiceKeys(health, config);\n if (blockingKeys.length > 0) {\n logToFile(`[health-checks] blocked by: ${blockingKeys.join(', ')}`);\n return { decision: WizardReadiness.No, health, reasons };\n }\n\n const hasWarnings = Object.values(health).some(\n (h) => h.status !== ServiceHealthStatus.Healthy,\n );\n\n if (hasWarnings) {\n return { decision: WizardReadiness.YesWithWarnings, health, reasons };\n }\n\n return { decision: WizardReadiness.Yes, health, reasons };\n } catch (err) {\n logToFile(\n `[health-checks] error: ${err instanceof Error ? err.message : err}`,\n );\n // Health checks must never block the wizard run\n return {\n decision: WizardReadiness.Yes,\n health: allUnknown('Unexpected error'),\n reasons: ['Health check failed unexpectedly — proceeding anyway'],\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Blocking service detection\n// ---------------------------------------------------------------------------\n\n/** Keys that are component-level detail, not top-level services. */\nconst COMPONENT_KEYS: HealthCheckKey[] = [\n 'posthogComponents',\n 'npmComponents',\n 'cloudflareComponents',\n];\n\n/**\n * Get the keys of services that would block a wizard run per the given config.\n */\nexport function getBlockingServiceKeys(\n health: AllServicesHealth,\n config: WizardReadinessConfig = DEFAULT_WIZARD_READINESS_CONFIG,\n): HealthCheckKey[] {\n return (Object.keys(health) as HealthCheckKey[]).filter((key) => {\n if (COMPONENT_KEYS.includes(key)) return false;\n const result = health[key];\n if (\n config.downBlocksRun.includes(key) &&\n result.status === ServiceHealthStatus.Down\n ) {\n return true;\n }\n if (\n (config.degradedBlocksRun ?? []).includes(key) &&\n result.status !== ServiceHealthStatus.Healthy\n ) {\n return true;\n }\n return false;\n });\n}\n\n/** Build an AllServicesHealth where every service is Degraded with the given error. */\nfunction allUnknown(error: string): AllServicesHealth {\n const base: BaseHealthResult = {\n status: ServiceHealthStatus.Degraded,\n error,\n };\n return {\n anthropic: base,\n posthogOverall: base,\n posthogComponents: { ...base },\n github: base,\n npmOverall: base,\n npmComponents: { ...base },\n cloudflareOverall: base,\n cloudflareComponents: { ...base },\n llmGateway: base,\n mcp: base,\n githubReleases: base,\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/lib/health-checks/types.ts"],"names":[],"mappings":";;;AAAA,IAAY,mBAIX;AAJD,WAAY,mBAAmB;IAC7B,0CAAmB,CAAA;IACnB,4CAAqB,CAAA;IACrB,oCAAa,CAAA;AACf,CAAC,EAJW,mBAAmB,mCAAnB,mBAAmB,QAI9B","sourcesContent":["export enum ServiceHealthStatus {\n Healthy = 'healthy',\n Degraded = 'degraded',\n Down = 'down',\n}\n\nexport interface BaseHealthResult {\n status: ServiceHealthStatus;\n rawIndicator?: string;\n error?: string;\n}\n\nexport interface ComponentStatus {\n name: string;\n status: ServiceHealthStatus;\n rawStatus: string;\n}\n\nexport interface ComponentHealthResult extends BaseHealthResult {\n degradedOrDownComponents?: ComponentStatus[];\n}\n\nexport interface AllServicesHealth {\n anthropic: BaseHealthResult;\n posthogOverall: BaseHealthResult;\n posthogComponents: ComponentHealthResult;\n github: BaseHealthResult;\n npmOverall: BaseHealthResult;\n npmComponents: ComponentHealthResult;\n cloudflareOverall: BaseHealthResult;\n cloudflareComponents: ComponentHealthResult;\n llmGateway: BaseHealthResult;\n mcp: BaseHealthResult;\n}\n\nexport type HealthCheckKey = keyof AllServicesHealth;\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/lib/health-checks/types.ts"],"names":[],"mappings":";;;AAAA,IAAY,mBAIX;AAJD,WAAY,mBAAmB;IAC7B,0CAAmB,CAAA;IACnB,4CAAqB,CAAA;IACrB,oCAAa,CAAA;AACf,CAAC,EAJW,mBAAmB,mCAAnB,mBAAmB,QAI9B","sourcesContent":["export enum ServiceHealthStatus {\n Healthy = 'healthy',\n Degraded = 'degraded',\n Down = 'down',\n}\n\nexport interface BaseHealthResult {\n status: ServiceHealthStatus;\n rawIndicator?: string;\n error?: string;\n}\n\nexport interface ComponentStatus {\n name: string;\n status: ServiceHealthStatus;\n rawStatus: string;\n}\n\nexport interface ComponentHealthResult extends BaseHealthResult {\n degradedOrDownComponents?: ComponentStatus[];\n}\n\nexport interface AllServicesHealth {\n anthropic: BaseHealthResult;\n posthogOverall: BaseHealthResult;\n posthogComponents: ComponentHealthResult;\n github: BaseHealthResult;\n npmOverall: BaseHealthResult;\n npmComponents: ComponentHealthResult;\n cloudflareOverall: BaseHealthResult;\n cloudflareComponents: ComponentHealthResult;\n llmGateway: BaseHealthResult;\n mcp: BaseHealthResult;\n githubReleases: BaseHealthResult;\n}\n\nexport type HealthCheckKey = keyof AllServicesHealth;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "2.
|
|
1
|
+
export declare const VERSION = "2.3.0";
|
package/dist/src/lib/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/lib/version.ts"],"names":[],"mappings":";;;AAAA,8DAA8D;AACjD,QAAA,OAAO,GAAG,OAAO,CAAC","sourcesContent":["// Auto-generated by scripts/generate-version.js — do not edit\nexport const VERSION = '2.
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/lib/version.ts"],"names":[],"mappings":";;;AAAA,8DAA8D;AACjD,QAAA,OAAO,GAAG,OAAO,CAAC","sourcesContent":["// Auto-generated by scripts/generate-version.js — do not edit\nexport const VERSION = '2.3.0';\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
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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
|
-
|
|
140
|
-
|
|
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-
|
|
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
|
|
280
|
-
|
|
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
|
-
|
|
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: ${
|
|
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"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HealthCheckDemo.js","sourceRoot":"","sources":["../../../../../../src/ui/tui/playground/demos/HealthCheckDemo.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,sBAAsB,EAAE,MAAM,4CAA4C,CAAC;AACpF,OAAO,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAC;AAG7E,MAAM,OAAO,GAAG,EAAE,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAW,CAAC;AAEjE,MAAM,WAAW,GAAsB;IACrC,SAAS,EAAE,EAAE,MAAM,EAAE,mBAAmB,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE;IACtE,cAAc,EAAE,OAAO;IACvB,iBAAiB,EAAE,EAAE,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE;IAC1D,MAAM,EAAE,OAAO;IACf,UAAU,EAAE;QACV,MAAM,EAAE,mBAAmB,CAAC,QAAQ;QACpC,YAAY,EAAE,OAAO;KACtB;IACD,aAAa,EAAE;QACb,MAAM,EAAE,mBAAmB,CAAC,QAAQ;QACpC,wBAAwB,EAAE;YACxB;gBACE,IAAI,EAAE,cAAc;gBACpB,MAAM,EAAE,mBAAmB,CAAC,QAAQ;gBACpC,SAAS,EAAE,sBAAsB;aAClC;SACF;KACF;IACD,iBAAiB,EAAE,OAAO;IAC1B,oBAAoB,EAAE,EAAE,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE;IAC7D,UAAU,EAAE,OAAO;IACnB,GAAG,EAAE,OAAO;
|
|
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"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
/**
|
|
3
3
|
* HealthCheckScreen — Flow screen between Intro and Auth.
|
|
4
4
|
*
|
|
@@ -7,16 +7,30 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
7
7
|
* 2. Healthy: isComplete returns true, router auto-advances to Auth
|
|
8
8
|
* 3. Blocking outage: shows affected services with Continue/Exit
|
|
9
9
|
*/
|
|
10
|
-
import { Box, Text } from 'ink';
|
|
11
|
-
import { useSyncExternalStore } from 'react';
|
|
10
|
+
import { Box, Text, useInput } from 'ink';
|
|
11
|
+
import { useState, useSyncExternalStore } from 'react';
|
|
12
12
|
import { ConfirmationInput, LoadingBox, ModalOverlay, } from '../../primitives/index.js';
|
|
13
|
-
import { Icons } from '../../styles.js';
|
|
13
|
+
import { Colors, Icons } from '../../styles.js';
|
|
14
14
|
import { ServiceHealthList } from '../../components/ServiceHealthList.js';
|
|
15
15
|
import { getBlockingServiceKeys } from '../../../../lib/health-checks/readiness.js';
|
|
16
|
+
import { ServiceHealthStatus } from '../../../../lib/health-checks/types.js';
|
|
16
17
|
import { wizardAbort } from '../../../../utils/wizard-abort.js';
|
|
18
|
+
import { fetchSkillMenu, downloadSkill } from '../../../../lib/wizard-tools.js';
|
|
19
|
+
const EXAMPLE_PROMPT = 'Integrate PostHog into this project using the skill files in .posthog/skills/. Read SKILL.md first, then follow the numbered workflow files in order.';
|
|
20
|
+
const SkillsDownloadedScreen = () => {
|
|
21
|
+
useInput(() => {
|
|
22
|
+
process.exit(0);
|
|
23
|
+
});
|
|
24
|
+
return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsxs(Text, { color: "green", bold: true, children: [Icons.check, " Skills downloaded to .posthog/skills/"] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { children: "You can continue setup with another agent using this prompt:" }), _jsx(Box, { marginTop: 1, paddingLeft: 2, children: _jsx(Text, { color: "cyan", children: EXAMPLE_PROMPT }) })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: Colors.muted, children: "Press any key to exit" }) })] }));
|
|
25
|
+
};
|
|
17
26
|
export const HealthCheckScreen = ({ store }) => {
|
|
18
27
|
useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
|
|
28
|
+
const [downloaded, setDownloaded] = useState(false);
|
|
29
|
+
const [downloading, setDownloading] = useState(false);
|
|
19
30
|
const result = store.session.readinessResult;
|
|
31
|
+
if (downloaded) {
|
|
32
|
+
return _jsx(SkillsDownloadedScreen, {});
|
|
33
|
+
}
|
|
20
34
|
// Still checking — show spinner
|
|
21
35
|
if (!result) {
|
|
22
36
|
return (_jsx(Box, { flexDirection: "column", flexGrow: 1, alignItems: "center", justifyContent: "center", children: _jsx(LoadingBox, { message: "Checking service status..." }) }));
|
|
@@ -26,7 +40,38 @@ export const HealthCheckScreen = ({ store }) => {
|
|
|
26
40
|
const blockingKeys = getBlockingServiceKeys(result.health);
|
|
27
41
|
if (blockingKeys.length === 0)
|
|
28
42
|
return null;
|
|
43
|
+
const isGithubReleasesDown = blockingKeys.includes('githubReleases');
|
|
44
|
+
const canDownloadSkills = result.health.githubReleases.status === ServiceHealthStatus.Healthy;
|
|
45
|
+
const integration = store.session.integration;
|
|
46
|
+
const title = `Ongoing service disruptions`;
|
|
47
|
+
const docsUrl = store.session.frameworkConfig?.metadata.docsUrl;
|
|
48
|
+
const description = isGithubReleasesDown
|
|
49
|
+
? "The Wizard can't download necessary skills from GitHub Releases right now."
|
|
50
|
+
: 'The Wizard may not work reliably while services are affected.';
|
|
51
|
+
const handleDownloadAndExit = async () => {
|
|
52
|
+
if (downloading)
|
|
53
|
+
return;
|
|
54
|
+
setDownloading(true);
|
|
55
|
+
const skillsBaseUrl = 'https://github.com/PostHog/context-mill/releases/latest/download';
|
|
56
|
+
const menu = await fetchSkillMenu(skillsBaseUrl);
|
|
57
|
+
if (menu) {
|
|
58
|
+
const prefix = `integration-${integration}`;
|
|
59
|
+
const skills = (menu.categories['integration'] ?? []).filter((s) => s.id.startsWith(prefix));
|
|
60
|
+
for (const skill of skills) {
|
|
61
|
+
downloadSkill(skill, store.session.installDir, '.posthog/skills');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
setDownloaded(true);
|
|
65
|
+
};
|
|
66
|
+
const handleCancel = canDownloadSkills && !isGithubReleasesDown
|
|
67
|
+
? () => void handleDownloadAndExit()
|
|
68
|
+
: () => void wizardAbort({ message: 'Exited due to service outage.' });
|
|
69
|
+
const cancelLabel = canDownloadSkills && !isGithubReleasesDown
|
|
70
|
+
? downloading
|
|
71
|
+
? 'Downloading...'
|
|
72
|
+
: 'Download skills & Exit [Esc]'
|
|
73
|
+
: 'Exit [Esc]';
|
|
29
74
|
// Blocking outage — show service list with Continue/Exit
|
|
30
|
-
return (_jsxs(ModalOverlay, { borderColor: "red", title:
|
|
75
|
+
return (_jsxs(ModalOverlay, { borderColor: "red", title: title, width: 72, footer: isGithubReleasesDown ? (_jsx(ConfirmationInput, { message: "", confirmLabel: "", cancelLabel: "Exit [Esc]", onConfirm: () => void wizardAbort({ message: 'Exited due to service outage.' }), onCancel: () => void wizardAbort({ message: 'Exited due to service outage.' }) })) : (_jsx(ConfirmationInput, { message: "Continue anyway?", confirmLabel: "Continue [Enter]", cancelLabel: cancelLabel, onConfirm: () => store.dismissOutage(), onCancel: handleCancel })), children: [_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { children: [_jsx(Text, { color: "red", children: Icons.squareFilled }), _jsx(Text, { dimColor: true, children: " Down " }), _jsx(Text, { color: "#DC9300", children: Icons.squareFilled }), _jsx(Text, { dimColor: true, children: " Degraded" })] }) }), _jsx(ServiceHealthList, { health: result.health, filterKeys: blockingKeys, showHealthy: false })] }), _jsx(Text, { dimColor: true, children: description }), isGithubReleasesDown && docsUrl && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { children: ["Set up manually: ", _jsx(Text, { color: "cyan", children: docsUrl })] }) })), canDownloadSkills && !isGithubReleasesDown && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { children: "You can still download the PostHog integration skills and continue with another agent." }) }))] }));
|
|
31
76
|
};
|
|
32
77
|
//# sourceMappingURL=HealthCheckScreen.js.map
|