@posthog/wizard 2.7.0 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/dist/bin.js +289 -162
- package/dist/bin.js.map +1 -1
- package/dist/src/__tests__/cli.test.js +92 -59
- package/dist/src/__tests__/cli.test.js.map +1 -1
- package/dist/src/__tests__/wizard-abort.test.js +34 -13
- package/dist/src/__tests__/wizard-abort.test.js.map +1 -1
- package/dist/src/frameworks/android/android-wizard-agent.js +2 -2
- package/dist/src/frameworks/android/android-wizard-agent.js.map +1 -1
- package/dist/src/frameworks/angular/angular-wizard-agent.js +2 -2
- package/dist/src/frameworks/angular/angular-wizard-agent.js.map +1 -1
- package/dist/src/frameworks/astro/astro-wizard-agent.js +2 -2
- package/dist/src/frameworks/astro/astro-wizard-agent.js.map +1 -1
- package/dist/src/frameworks/django/django-wizard-agent.js +2 -2
- package/dist/src/frameworks/django/django-wizard-agent.js.map +1 -1
- package/dist/src/frameworks/fastapi/fastapi-wizard-agent.js +2 -2
- package/dist/src/frameworks/fastapi/fastapi-wizard-agent.js.map +1 -1
- package/dist/src/frameworks/flask/flask-wizard-agent.js +2 -2
- package/dist/src/frameworks/flask/flask-wizard-agent.js.map +1 -1
- package/dist/src/frameworks/javascript-node/javascript-node-wizard-agent.js +2 -2
- package/dist/src/frameworks/javascript-node/javascript-node-wizard-agent.js.map +1 -1
- package/dist/src/frameworks/javascript-web/javascript-web-wizard-agent.js +2 -2
- package/dist/src/frameworks/javascript-web/javascript-web-wizard-agent.js.map +1 -1
- package/dist/src/frameworks/laravel/laravel-wizard-agent.js +2 -2
- package/dist/src/frameworks/laravel/laravel-wizard-agent.js.map +1 -1
- package/dist/src/frameworks/nextjs/nextjs-wizard-agent.js +2 -2
- package/dist/src/frameworks/nextjs/nextjs-wizard-agent.js.map +1 -1
- package/dist/src/frameworks/nuxt/nuxt-wizard-agent.js +2 -2
- package/dist/src/frameworks/nuxt/nuxt-wizard-agent.js.map +1 -1
- package/dist/src/frameworks/python/python-wizard-agent.js +2 -2
- package/dist/src/frameworks/python/python-wizard-agent.js.map +1 -1
- package/dist/src/frameworks/rails/rails-wizard-agent.js +2 -2
- package/dist/src/frameworks/rails/rails-wizard-agent.js.map +1 -1
- package/dist/src/frameworks/react-native/react-native-wizard-agent.js +2 -2
- package/dist/src/frameworks/react-native/react-native-wizard-agent.js.map +1 -1
- package/dist/src/frameworks/react-router/react-router-wizard-agent.js +2 -2
- package/dist/src/frameworks/react-router/react-router-wizard-agent.js.map +1 -1
- package/dist/src/frameworks/ruby/ruby-wizard-agent.js +2 -2
- package/dist/src/frameworks/ruby/ruby-wizard-agent.js.map +1 -1
- package/dist/src/frameworks/svelte/svelte-wizard-agent.js +2 -2
- package/dist/src/frameworks/svelte/svelte-wizard-agent.js.map +1 -1
- package/dist/src/frameworks/swift/swift-wizard-agent.js +2 -2
- package/dist/src/frameworks/swift/swift-wizard-agent.js.map +1 -1
- package/dist/src/frameworks/tanstack-router/tanstack-router-wizard-agent.js +2 -2
- package/dist/src/frameworks/tanstack-router/tanstack-router-wizard-agent.js.map +1 -1
- package/dist/src/frameworks/tanstack-start/tanstack-start-wizard-agent.js +2 -2
- package/dist/src/frameworks/tanstack-start/tanstack-start-wizard-agent.js.map +1 -1
- package/dist/src/frameworks/vue/vue-wizard-agent.js +2 -2
- package/dist/src/frameworks/vue/vue-wizard-agent.js.map +1 -1
- package/dist/src/lib/__tests__/agent-interface.test.js +29 -1
- package/dist/src/lib/__tests__/agent-interface.test.js.map +1 -1
- package/dist/src/lib/agent/__tests__/agent-prompt.test.js +57 -0
- package/dist/src/lib/agent/__tests__/agent-prompt.test.js.map +1 -0
- package/dist/src/lib/{agent-interface.d.ts → agent/agent-interface.d.ts} +18 -6
- package/dist/src/lib/{agent-interface.js → agent/agent-interface.js} +63 -13
- package/dist/src/lib/agent/agent-interface.js.map +1 -0
- package/dist/src/lib/agent/agent-prompt.d.ts +23 -0
- package/dist/src/lib/agent/agent-prompt.js +47 -0
- package/dist/src/lib/agent/agent-prompt.js.map +1 -0
- package/dist/src/lib/agent/agent-runner.d.ts +78 -0
- package/dist/src/lib/agent/agent-runner.js +323 -0
- package/dist/src/lib/agent/agent-runner.js.map +1 -0
- package/dist/src/lib/agent/commandments.js.map +1 -0
- package/dist/src/lib/constants.d.ts +10 -1
- package/dist/src/lib/constants.js +13 -1
- package/dist/src/lib/constants.js.map +1 -1
- package/dist/src/lib/detection/__tests__/context.test.js +72 -0
- package/dist/src/lib/detection/__tests__/context.test.js.map +1 -0
- package/dist/src/lib/detection/__tests__/features.test.d.ts +1 -0
- package/dist/src/lib/detection/__tests__/features.test.js +75 -0
- package/dist/src/lib/detection/__tests__/features.test.js.map +1 -0
- package/dist/src/lib/detection/__tests__/package-manager.test.d.ts +1 -0
- package/dist/src/lib/{__tests__/package-manager-detection.test.js → detection/__tests__/package-manager.test.js} +25 -25
- package/dist/src/lib/detection/__tests__/package-manager.test.js.map +1 -0
- package/dist/src/lib/detection/context.d.ts +31 -0
- package/dist/src/lib/detection/context.js +92 -0
- package/dist/src/lib/detection/context.js.map +1 -0
- package/dist/src/lib/detection/features.d.ts +16 -0
- package/dist/src/lib/detection/features.js +56 -0
- package/dist/src/lib/detection/features.js.map +1 -0
- package/dist/src/lib/detection/framework.d.ts +14 -0
- package/dist/src/lib/detection/framework.js +35 -0
- package/dist/src/lib/detection/framework.js.map +1 -0
- package/dist/src/lib/detection/index.d.ts +3 -0
- package/dist/src/lib/detection/index.js +11 -0
- package/dist/src/lib/detection/index.js.map +1 -0
- package/dist/src/lib/{package-manager-detection.js → detection/package-manager.js} +3 -3
- package/dist/src/lib/detection/package-manager.js.map +1 -0
- package/dist/src/lib/framework-config.d.ts +1 -1
- package/dist/src/lib/framework-config.js.map +1 -1
- package/dist/src/lib/health-checks/endpoints.js +2 -1
- package/dist/src/lib/health-checks/endpoints.js.map +1 -1
- package/dist/src/lib/middleware/benchmark.js +1 -1
- package/dist/src/lib/middleware/benchmark.js.map +1 -1
- package/dist/src/lib/middleware/benchmarks/compaction-tracker.js +1 -1
- package/dist/src/lib/middleware/benchmarks/compaction-tracker.js.map +1 -1
- package/dist/src/lib/middleware/benchmarks/json-writer.js +1 -1
- package/dist/src/lib/middleware/benchmarks/json-writer.js.map +1 -1
- package/dist/src/lib/middleware/benchmarks/summary.js +1 -1
- package/dist/src/lib/middleware/benchmarks/summary.js.map +1 -1
- package/dist/src/lib/middleware/config.js +1 -1
- package/dist/src/lib/middleware/config.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-session.d.ts +20 -7
- package/dist/src/lib/wizard-session.js +4 -0
- package/dist/src/lib/wizard-session.js.map +1 -1
- package/dist/src/lib/wizard-tools.d.ts +28 -1
- package/dist/src/lib/wizard-tools.js +24 -0
- package/dist/src/lib/wizard-tools.js.map +1 -1
- package/dist/src/lib/workflows/__tests__/agent-skill.test.d.ts +1 -0
- package/dist/src/lib/workflows/__tests__/agent-skill.test.js +66 -0
- package/dist/src/lib/workflows/__tests__/agent-skill.test.js.map +1 -0
- package/dist/src/lib/workflows/__tests__/revenue-analytics-detect.test.d.ts +1 -0
- package/dist/src/lib/workflows/__tests__/revenue-analytics-detect.test.js +101 -0
- package/dist/src/lib/workflows/__tests__/revenue-analytics-detect.test.js.map +1 -0
- package/dist/src/lib/workflows/__tests__/workflow-registry.test.d.ts +1 -0
- package/dist/src/lib/workflows/__tests__/workflow-registry.test.js +32 -0
- package/dist/src/lib/workflows/__tests__/workflow-registry.test.js.map +1 -0
- package/dist/src/lib/workflows/__tests__/workflow-step.test.d.ts +1 -0
- package/dist/src/lib/workflows/__tests__/workflow-step.test.js +54 -0
- package/dist/src/lib/workflows/__tests__/workflow-step.test.js.map +1 -0
- package/dist/src/lib/workflows/agent-skill/index.d.ts +44 -0
- package/dist/src/lib/workflows/agent-skill/index.js +47 -0
- package/dist/src/lib/workflows/agent-skill/index.js.map +1 -0
- package/dist/src/lib/workflows/agent-skill/steps.d.ts +8 -0
- package/dist/src/lib/workflows/agent-skill/steps.js +32 -0
- package/dist/src/lib/workflows/agent-skill/steps.js.map +1 -0
- package/dist/src/lib/workflows/posthog-integration/detect.d.ts +12 -0
- package/dist/src/lib/workflows/posthog-integration/detect.js +57 -0
- package/dist/src/lib/workflows/posthog-integration/detect.js.map +1 -0
- package/dist/src/lib/workflows/posthog-integration/index.d.ts +3 -0
- package/dist/src/lib/workflows/posthog-integration/index.js +152 -0
- package/dist/src/lib/workflows/posthog-integration/index.js.map +1 -0
- package/dist/src/lib/workflows/posthog-integration/steps.d.ts +9 -0
- package/dist/src/lib/workflows/posthog-integration/steps.js +100 -0
- package/dist/src/lib/workflows/posthog-integration/steps.js.map +1 -0
- package/dist/src/lib/workflows/revenue-analytics/detect.d.ts +40 -0
- package/dist/src/lib/workflows/revenue-analytics/detect.js +156 -0
- package/dist/src/lib/workflows/revenue-analytics/detect.js.map +1 -0
- package/dist/src/lib/workflows/revenue-analytics/index.d.ts +4 -0
- package/dist/src/lib/workflows/revenue-analytics/index.js +30 -0
- package/dist/src/lib/workflows/revenue-analytics/index.js.map +1 -0
- package/dist/src/lib/workflows/revenue-analytics/steps.d.ts +8 -0
- package/dist/src/lib/workflows/revenue-analytics/steps.js +48 -0
- package/dist/src/lib/workflows/revenue-analytics/steps.js.map +1 -0
- package/dist/src/lib/workflows/workflow-registry.d.ts +18 -0
- package/dist/src/lib/workflows/workflow-registry.js +32 -0
- package/dist/src/lib/workflows/workflow-registry.js.map +1 -0
- package/dist/src/lib/workflows/workflow-step.d.ts +126 -0
- package/dist/src/lib/workflows/workflow-step.js +28 -0
- package/dist/src/lib/workflows/workflow-step.js.map +1 -0
- package/dist/src/steps/add-mcp-server-to-clients/index.d.ts +2 -1
- package/dist/src/steps/add-mcp-server-to-clients/index.js.map +1 -1
- package/dist/src/ui/logging-ui.d.ts +6 -3
- package/dist/src/ui/logging-ui.js +7 -0
- package/dist/src/ui/logging-ui.js.map +1 -1
- package/dist/src/ui/tui/__tests__/flows.test.d.ts +1 -0
- package/dist/src/ui/tui/__tests__/flows.test.js +115 -0
- package/dist/src/ui/tui/__tests__/flows.test.js.map +1 -0
- package/dist/src/ui/tui/__tests__/router.test.d.ts +1 -0
- package/dist/src/ui/tui/__tests__/router.test.js +87 -0
- package/dist/src/ui/tui/__tests__/router.test.js.map +1 -0
- package/dist/src/ui/tui/__tests__/store.test.js +100 -10
- package/dist/src/ui/tui/__tests__/store.test.js.map +1 -1
- package/dist/src/ui/tui/flows.d.ts +17 -6
- package/dist/src/ui/tui/flows.js +28 -52
- package/dist/src/ui/tui/flows.js.map +1 -1
- package/dist/src/ui/tui/ink-ui.d.ts +6 -3
- package/dist/src/ui/tui/ink-ui.js +7 -0
- package/dist/src/ui/tui/ink-ui.js.map +1 -1
- package/dist/src/ui/tui/primitives/ProgressList.d.ts +3 -1
- package/dist/src/ui/tui/primitives/ProgressList.js +2 -2
- package/dist/src/ui/tui/primitives/ProgressList.js.map +1 -1
- package/dist/src/ui/tui/router.js +1 -1
- package/dist/src/ui/tui/router.js.map +1 -1
- package/dist/src/ui/tui/screen-registry.js +2 -0
- package/dist/src/ui/tui/screen-registry.js.map +1 -1
- package/dist/src/ui/tui/screens/ManagedSettingsScreen.js.map +1 -1
- package/dist/src/ui/tui/screens/OutroScreen.js +1 -1
- package/dist/src/ui/tui/screens/OutroScreen.js.map +1 -1
- package/dist/src/ui/tui/screens/RevenueIntroScreen.d.ts +16 -0
- package/dist/src/ui/tui/screens/RevenueIntroScreen.js +64 -0
- package/dist/src/ui/tui/screens/RevenueIntroScreen.js.map +1 -0
- package/dist/src/ui/tui/screens/RunScreen.js +1 -1
- package/dist/src/ui/tui/screens/RunScreen.js.map +1 -1
- package/dist/src/ui/tui/screens/SettingsOverrideScreen.js.map +1 -1
- package/dist/src/ui/tui/screens/health/HealthCheckScreen.js +2 -2
- package/dist/src/ui/tui/screens/health/HealthCheckScreen.js.map +1 -1
- package/dist/src/ui/tui/start-tui.js +2 -2
- package/dist/src/ui/tui/start-tui.js.map +1 -1
- package/dist/src/ui/tui/store.d.ts +46 -21
- package/dist/src/ui/tui/store.js +105 -47
- package/dist/src/ui/tui/store.js.map +1 -1
- package/dist/src/ui/wizard-ui.d.ts +13 -3
- package/dist/src/ui/wizard-ui.js.map +1 -1
- package/dist/src/utils/__tests__/provisioning.test.d.ts +1 -0
- package/dist/src/utils/__tests__/provisioning.test.js +192 -0
- package/dist/src/utils/__tests__/provisioning.test.js.map +1 -0
- package/dist/src/utils/file-utils.d.ts +8 -0
- package/dist/src/utils/file-utils.js +32 -0
- package/dist/src/utils/file-utils.js.map +1 -1
- package/dist/src/utils/provisioning.d.ts +25 -0
- package/dist/src/utils/provisioning.js +191 -0
- package/dist/src/utils/provisioning.js.map +1 -0
- package/dist/src/utils/setup-utils.d.ts +4 -1
- package/dist/src/utils/setup-utils.js +46 -2
- package/dist/src/utils/setup-utils.js.map +1 -1
- package/dist/src/utils/types.d.ts +4 -0
- package/dist/src/utils/types.js.map +1 -1
- package/dist/src/utils/wizard-abort.d.ts +3 -0
- package/dist/src/utils/wizard-abort.js +5 -3
- package/dist/src/utils/wizard-abort.js.map +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/dist/src/__tests__/run.test.js +0 -95
- package/dist/src/__tests__/run.test.js.map +0 -1
- package/dist/src/lib/__tests__/package-manager-detection.test.js.map +0 -1
- package/dist/src/lib/agent-interface.js.map +0 -1
- package/dist/src/lib/agent-runner.d.ts +0 -9
- package/dist/src/lib/agent-runner.js +0 -383
- package/dist/src/lib/agent-runner.js.map +0 -1
- package/dist/src/lib/commandments.js.map +0 -1
- package/dist/src/lib/package-manager-detection.js.map +0 -1
- package/dist/src/run.d.ts +0 -22
- package/dist/src/run.js +0 -152
- package/dist/src/run.js.map +0 -1
- /package/dist/src/{__tests__/run.test.d.ts → lib/agent/__tests__/agent-prompt.test.d.ts} +0 -0
- /package/dist/src/lib/{commandments.d.ts → agent/commandments.d.ts} +0 -0
- /package/dist/src/lib/{commandments.js → agent/commandments.js} +0 -0
- /package/dist/src/lib/{__tests__/package-manager-detection.test.d.ts → detection/__tests__/context.test.d.ts} +0 -0
- /package/dist/src/lib/{package-manager-detection.d.ts → detection/package-manager.d.ts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tanstack-router-wizard-agent.js","sourceRoot":"","sources":["../../../../src/frameworks/tanstack-router/tanstack-router-wizard-agent.ts"],"names":[],"mappings":";;;AAGA,
|
|
1
|
+
{"version":3,"file":"tanstack-router-wizard-agent.js","sourceRoot":"","sources":["../../../../src/frameworks/tanstack-router/tanstack-router-wizard-agent.ts"],"names":[],"mappings":"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","sourcesContent":["/* TanStack Router wizard using posthog-agent with PostHog MCP */\nimport type { WizardOptions } from '../../utils/types';\nimport type { FrameworkConfig } from '../../lib/framework-config';\nimport { detectNodePackageManagers } from '../../lib/detection/package-manager';\nimport { Integration } from '../../lib/constants';\nimport {\n getPackageVersion,\n getInstalledPackageVersion,\n hasPackageInstalled,\n type PackageDotJson,\n} from '../../utils/package-json';\nimport { tryGetPackageJson } from '../../utils/setup-utils';\nimport { getUI } from '../../ui';\nimport {\n getTanStackRouterMode,\n getTanStackRouterModeName,\n getTanStackRouterVersionBucket,\n TanStackRouterMode,\n} from './utils';\n\ntype TanStackRouterContext = {\n routerMode?: TanStackRouterMode;\n};\n\nexport const TANSTACK_ROUTER_AGENT_CONFIG: FrameworkConfig<TanStackRouterContext> =\n {\n metadata: {\n name: 'React (TanStack Router)',\n integration: Integration.tanstackRouter,\n docsUrl: 'https://posthog.com/docs/libraries/react',\n gatherContext: async (options: WizardOptions) => {\n const routerMode = await getTanStackRouterMode(options);\n if (routerMode) {\n getUI().setDetectedFramework(\n `TanStack Router ${getTanStackRouterModeName(routerMode)}`,\n );\n return { routerMode };\n }\n return {};\n },\n },\n\n detection: {\n packageName: '@tanstack/react-router',\n packageDisplayName: 'TanStack Router',\n getVersion: (packageJson: unknown) =>\n getPackageVersion(\n '@tanstack/react-router',\n packageJson as PackageDotJson,\n ),\n getVersionBucket: getTanStackRouterVersionBucket,\n minimumVersion: '1.0.0',\n getInstalledVersion: (options: WizardOptions) =>\n Promise.resolve(\n getInstalledPackageVersion(\n '@tanstack/react-router',\n options.installDir,\n ),\n ),\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n if (!packageJson) {\n return false;\n }\n // Exclude TanStack Start projects (they have their own integration)\n if (hasPackageInstalled('@tanstack/react-start', packageJson)) {\n return false;\n }\n return hasPackageInstalled('@tanstack/react-router', packageJson);\n },\n detectPackageManager: detectNodePackageManagers,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n VITE_PUBLIC_POSTHOG_PROJECT_TOKEN: apiKey,\n VITE_PUBLIC_POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n routerMode: context.routerMode || 'unknown',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.',\n getAdditionalContextLines: (context) => {\n const routerMode = context.routerMode;\n const modeName = routerMode\n ? getTanStackRouterModeName(routerMode)\n : 'unknown';\n\n // Map router mode to framework ID for MCP docs resource\n const frameworkIdMap: Record<TanStackRouterMode, string> = {\n [TanStackRouterMode.FILE_BASED]: 'react-tanstack-router-file-based',\n [TanStackRouterMode.CODE_BASED]: 'react-tanstack-router-code-based',\n };\n\n const frameworkId = routerMode\n ? frameworkIdMap[routerMode]\n : 'react-tanstack-router-file-based';\n\n return [\n `Router mode: ${modeName}`,\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n ];\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 8,\n getOutroChanges: (context) => {\n const modeName = context.routerMode\n ? getTanStackRouterModeName(context.routerMode)\n : 'TanStack Router';\n return [\n `Analyzed your React (TanStack Router) project structure (${modeName})`,\n `Created and configured PostHog initializers`,\n `Integrated PostHog into your application`,\n ];\n },\n getOutroNextSteps: () => [\n 'Start your development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n };\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.TANSTACK_START_AGENT_CONFIG = void 0;
|
|
4
|
-
const
|
|
4
|
+
const package_manager_1 = require("../../lib/detection/package-manager");
|
|
5
5
|
const constants_1 = require("../../lib/constants");
|
|
6
6
|
const package_json_1 = require("../../utils/package-json");
|
|
7
7
|
const setup_utils_1 = require("../../utils/setup-utils");
|
|
@@ -25,7 +25,7 @@ exports.TANSTACK_START_AGENT_CONFIG = {
|
|
|
25
25
|
? (0, package_json_1.hasPackageInstalled)('@tanstack/react-start', packageJson)
|
|
26
26
|
: false;
|
|
27
27
|
},
|
|
28
|
-
detectPackageManager:
|
|
28
|
+
detectPackageManager: package_manager_1.detectNodePackageManagers,
|
|
29
29
|
},
|
|
30
30
|
environment: {
|
|
31
31
|
uploadToHosting: false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tanstack-start-wizard-agent.js","sourceRoot":"","sources":["../../../../src/frameworks/tanstack-start/tanstack-start-wizard-agent.ts"],"names":[],"mappings":";;;AAGA,
|
|
1
|
+
{"version":3,"file":"tanstack-start-wizard-agent.js","sourceRoot":"","sources":["../../../../src/frameworks/tanstack-start/tanstack-start-wizard-agent.ts"],"names":[],"mappings":";;;AAGA,yEAAgF;AAChF,mDAAkD;AAClD,2DAKkC;AAClC,yDAA4D;AAC5D,mCAAwD;AAI3C,QAAA,2BAA2B,GACtC;IACE,QAAQ,EAAE;QACR,IAAI,EAAE,gBAAgB;QACtB,WAAW,EAAE,uBAAW,CAAC,aAAa;QACtC,OAAO,EAAE,0CAA0C;KACpD;IAED,SAAS,EAAE;QACT,WAAW,EAAE,uBAAuB;QACpC,kBAAkB,EAAE,gBAAgB;QACpC,UAAU,EAAE,CAAC,WAAoB,EAAE,EAAE,CACnC,IAAA,gCAAiB,EACf,uBAAuB,EACvB,WAA6B,CAC9B;QACH,gBAAgB,EAAE,qCAA6B;QAC/C,cAAc,EAAE,OAAO;QACvB,mBAAmB,EAAE,CAAC,OAAsB,EAAE,EAAE,CAC9C,OAAO,CAAC,OAAO,CACb,IAAA,yCAA0B,EACxB,uBAAuB,EACvB,OAAO,CAAC,UAAU,CACnB,CACF;QACH,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACxB,MAAM,WAAW,GAAG,MAAM,IAAA,+BAAiB,EAAC,OAAO,CAAC,CAAC;YACrD,OAAO,WAAW;gBAChB,CAAC,CAAC,IAAA,kCAAmB,EAAC,uBAAuB,EAAE,WAAW,CAAC;gBAC3D,CAAC,CAAC,KAAK,CAAC;QACZ,CAAC;QACD,oBAAoB,EAAE,2CAAyB;KAChD;IAED,WAAW,EAAE;QACX,eAAe,EAAE,KAAK;QACtB,UAAU,EAAE,CAAC,MAAc,EAAE,IAAY,EAAE,EAAE,CAAC,CAAC;YAC7C,iCAAiC,EAAE,MAAM;YACzC,wBAAwB,EAAE,IAAI;SAC/B,CAAC;KACH;IAED,SAAS,EAAE;QACT,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;KACpB;IAED,OAAO,EAAE;QACP,oBAAoB,EAClB,oJAAoJ;QACtJ,yBAAyB,EAAE,GAAG,EAAE;YAC9B,uGAAuG;YACvG,MAAM,WAAW,GAAG,sBAAsB,CAAC;YAE3C,OAAO;gBACL,sBAAsB,WAAW,mCAAmC,WAAW,qBAAqB;aACrG,CAAC;QACJ,CAAC;KACF;IAED,EAAE,EAAE;QACF,cAAc,EAAE,8BAA8B;QAC9C,wBAAwB,EAAE,CAAC;QAC3B,eAAe,EAAE,GAAG,EAAE,CAAC;YACrB,gDAAgD;YAChD,6CAA6C;YAC7C,0CAA0C;SAC3C;QACD,iBAAiB,EAAE,GAAG,EAAE,CAAC;YACvB,wDAAwD;YACxD,qDAAqD;SACtD;KACF;CACF,CAAC","sourcesContent":["/* TanStack Start wizard using posthog-agent with PostHog MCP */\nimport type { WizardOptions } from '../../utils/types';\nimport type { FrameworkConfig } from '../../lib/framework-config';\nimport { detectNodePackageManagers } from '../../lib/detection/package-manager';\nimport { Integration } from '../../lib/constants';\nimport {\n getPackageVersion,\n getInstalledPackageVersion,\n hasPackageInstalled,\n type PackageDotJson,\n} from '../../utils/package-json';\nimport { tryGetPackageJson } from '../../utils/setup-utils';\nimport { getTanStackStartVersionBucket } from './utils';\n\ntype TanStackStartContext = Record<string, unknown>;\n\nexport const TANSTACK_START_AGENT_CONFIG: FrameworkConfig<TanStackStartContext> =\n {\n metadata: {\n name: 'TanStack Start',\n integration: Integration.tanstackStart,\n docsUrl: 'https://posthog.com/docs/libraries/react',\n },\n\n detection: {\n packageName: '@tanstack/react-start',\n packageDisplayName: 'TanStack Start',\n getVersion: (packageJson: unknown) =>\n getPackageVersion(\n '@tanstack/react-start',\n packageJson as PackageDotJson,\n ),\n getVersionBucket: getTanStackStartVersionBucket,\n minimumVersion: '1.0.0',\n getInstalledVersion: (options: WizardOptions) =>\n Promise.resolve(\n getInstalledPackageVersion(\n '@tanstack/react-start',\n options.installDir,\n ),\n ),\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n return packageJson\n ? hasPackageInstalled('@tanstack/react-start', packageJson)\n : false;\n },\n detectPackageManager: detectNodePackageManagers,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n VITE_PUBLIC_POSTHOG_PROJECT_TOKEN: apiKey,\n VITE_PUBLIC_POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: () => ({}),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.',\n getAdditionalContextLines: () => {\n // TanStack Start always uses file-based routing (it's a full-stack framework built on TanStack Router)\n const frameworkId = 'react-tanstack-start';\n\n return [\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n ];\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 8,\n getOutroChanges: () => [\n `Analyzed your TanStack Start project structure`,\n `Created and configured PostHog initializers`,\n `Integrated PostHog into your application`,\n ],\n getOutroNextSteps: () => [\n 'Start your development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n };\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.VUE_AGENT_CONFIG = void 0;
|
|
4
|
-
const
|
|
4
|
+
const package_manager_1 = require("../../lib/detection/package-manager");
|
|
5
5
|
const constants_1 = require("../../lib/constants");
|
|
6
6
|
const package_json_1 = require("../../utils/package-json");
|
|
7
7
|
const setup_utils_1 = require("../../utils/setup-utils");
|
|
@@ -24,7 +24,7 @@ exports.VUE_AGENT_CONFIG = {
|
|
|
24
24
|
const packageJson = await (0, setup_utils_1.tryGetPackageJson)(options);
|
|
25
25
|
return packageJson ? (0, package_json_1.hasPackageInstalled)('vue', packageJson) : false;
|
|
26
26
|
},
|
|
27
|
-
detectPackageManager:
|
|
27
|
+
detectPackageManager: package_manager_1.detectNodePackageManagers,
|
|
28
28
|
},
|
|
29
29
|
environment: {
|
|
30
30
|
uploadToHosting: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vue-wizard-agent.js","sourceRoot":"","sources":["../../../../src/frameworks/vue/vue-wizard-agent.ts"],"names":[],"mappings":";;;AAEA,
|
|
1
|
+
{"version":3,"file":"vue-wizard-agent.js","sourceRoot":"","sources":["../../../../src/frameworks/vue/vue-wizard-agent.ts"],"names":[],"mappings":";;;AAEA,yEAAgF;AAChF,mDAAkD;AAClD,2DAKkC;AAClC,yDAA4D;AAC5D,+CAAyD;AAEzD,MAAM,mBAAmB,GAAG,IAAA,4BAAmB,GAAE,CAAC;AAIrC,QAAA,gBAAgB,GAAgC;IAC3D,QAAQ,EAAE;QACR,IAAI,EAAE,KAAK;QACX,WAAW,EAAE,uBAAW,CAAC,GAAG;QAC5B,OAAO,EAAE,wCAAwC;QACjD,IAAI,EAAE,IAAI;KACX;IAED,SAAS,EAAE;QACT,WAAW,EAAE,KAAK;QAClB,kBAAkB,EAAE,KAAK;QACzB,UAAU,EAAE,CAAC,WAAoB,EAAE,EAAE,CACnC,IAAA,gCAAiB,EAAC,KAAK,EAAE,WAA6B,CAAC;QACzD,gBAAgB,EAAE,mBAAmB;QACrC,mBAAmB,EAAE,CAAC,OAAO,EAAE,EAAE,CAC/B,OAAO,CAAC,OAAO,CAAC,IAAA,yCAA0B,EAAC,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;QACxE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACxB,MAAM,WAAW,GAAG,MAAM,IAAA,+BAAiB,EAAC,OAAO,CAAC,CAAC;YACrD,OAAO,WAAW,CAAC,CAAC,CAAC,IAAA,kCAAmB,EAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACvE,CAAC;QACD,oBAAoB,EAAE,2CAAyB;KAChD;IAED,WAAW,EAAE;QACX,eAAe,EAAE,IAAI;QACrB,UAAU,EAAE,CAAC,MAAc,EAAE,IAAY,EAAE,EAAE,CAAC,CAAC;YAC7C,0BAA0B,EAAE,MAAM;YAClC,iBAAiB,EAAE,IAAI;SACxB,CAAC;KACH;IAED,SAAS,EAAE;QACT,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;KACpB;IAED,OAAO,EAAE;QACP,oBAAoB,EAClB,oJAAoJ;QACtJ,yBAAyB,EAAE,GAAG,EAAE;YAC9B,MAAM,WAAW,GAAG,KAAK,CAAC;YAC1B,OAAO;gBACL,sBAAsB,WAAW,mCAAmC,WAAW,qBAAqB;aACrG,CAAC;QACJ,CAAC;KACF;IAED,EAAE,EAAE;QACF,cAAc,EAAE,8BAA8B;QAC9C,wBAAwB,EAAE,CAAC;QAC3B,eAAe,EAAE,GAAG,EAAE,CAAC;YACrB,qCAAqC;YACrC,6CAA6C;YAC7C,0CAA0C;SAC3C;QACD,iBAAiB,EAAE,GAAG,EAAE,CAAC;YACvB,wDAAwD;YACxD,qDAAqD;SACtD;KACF;CACF,CAAC","sourcesContent":["/* Vue wizard using posthog-agent with PostHog MCP */\nimport type { FrameworkConfig } from '../../lib/framework-config';\nimport { detectNodePackageManagers } from '../../lib/detection/package-manager';\nimport { Integration } from '../../lib/constants';\nimport {\n getPackageVersion,\n getInstalledPackageVersion,\n hasPackageInstalled,\n type PackageDotJson,\n} from '../../utils/package-json';\nimport { tryGetPackageJson } from '../../utils/setup-utils';\nimport { createVersionBucket } from '../../utils/semver';\n\nconst getVueVersionBucket = createVersionBucket();\n\ntype VueContext = Record<string, unknown>;\n\nexport const VUE_AGENT_CONFIG: FrameworkConfig<VueContext> = {\n metadata: {\n name: 'Vue',\n integration: Integration.vue,\n docsUrl: 'https://posthog.com/docs/libraries/vue',\n beta: true,\n },\n\n detection: {\n packageName: 'vue',\n packageDisplayName: 'Vue',\n getVersion: (packageJson: unknown) =>\n getPackageVersion('vue', packageJson as PackageDotJson),\n getVersionBucket: getVueVersionBucket,\n getInstalledVersion: (options) =>\n Promise.resolve(getInstalledPackageVersion('vue', options.installDir)),\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n return packageJson ? hasPackageInstalled('vue', packageJson) : false;\n },\n detectPackageManager: detectNodePackageManagers,\n },\n\n environment: {\n uploadToHosting: true,\n getEnvVars: (apiKey: string, host: string) => ({\n VITE_POSTHOG_PROJECT_TOKEN: apiKey,\n VITE_POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: () => ({}),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.',\n getAdditionalContextLines: () => {\n const frameworkId = 'vue';\n return [\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n ];\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: () => [\n 'Analyzed your Vue project structure',\n 'Created and configured PostHog initializers',\n 'Integrated PostHog into your application',\n ],\n getOutroNextSteps: () => [\n 'Start your development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n};\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const agent_interface_1 = require("../agent-interface");
|
|
3
|
+
const agent_interface_1 = require("../agent/agent-interface");
|
|
4
4
|
const wizard_session_1 = require("../wizard-session");
|
|
5
5
|
// Mock dependencies
|
|
6
6
|
jest.mock('../../utils/analytics');
|
|
@@ -209,6 +209,34 @@ describe('runAgent', () => {
|
|
|
209
209
|
// ui.log.error should NOT have been called (errors suppressed for user)
|
|
210
210
|
expect(mockUIInstance.log.error).not.toHaveBeenCalled();
|
|
211
211
|
});
|
|
212
|
+
it('should ignore abort requests when no abort cases are registered', async () => {
|
|
213
|
+
function* mockGeneratorWithAbortText() {
|
|
214
|
+
yield {
|
|
215
|
+
type: 'assistant',
|
|
216
|
+
message: {
|
|
217
|
+
content: [
|
|
218
|
+
{
|
|
219
|
+
type: 'text',
|
|
220
|
+
text: '[ABORT] Could not find a Stripe integration',
|
|
221
|
+
},
|
|
222
|
+
],
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
yield {
|
|
226
|
+
type: 'result',
|
|
227
|
+
subtype: 'success',
|
|
228
|
+
is_error: false,
|
|
229
|
+
result: 'Agent completed successfully',
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
mockQuery.mockReturnValue(mockGeneratorWithAbortText());
|
|
233
|
+
const result = await (0, agent_interface_1.runAgent)(defaultAgentConfig, 'test prompt', defaultOptions, mockSpinner, {
|
|
234
|
+
successMessage: 'Test success',
|
|
235
|
+
errorMessage: 'Test error',
|
|
236
|
+
});
|
|
237
|
+
expect(result).toEqual({});
|
|
238
|
+
expect(mockSpinner.stop).toHaveBeenCalledWith('Test success');
|
|
239
|
+
});
|
|
212
240
|
});
|
|
213
241
|
});
|
|
214
242
|
describe('createStopHook', () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-interface.test.js","sourceRoot":"","sources":["../../../../src/lib/__tests__/agent-interface.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { runAgent, createStopHook } from '../agent-interface';\nimport type { WizardOptions } from '../../utils/types';\nimport type { SpinnerHandle } from '../../ui';\nimport {\n AdditionalFeature,\n ADDITIONAL_FEATURE_PROMPTS,\n} from '../wizard-session';\n\n// Mock dependencies\njest.mock('../../utils/analytics');\njest.mock('../../utils/debug');\n\n// Mock the SDK module\nconst mockQuery = jest.fn();\njest.mock('@anthropic-ai/claude-agent-sdk', () => ({\n query: (...args: unknown[]) => mockQuery(...args),\n}));\n\n// Mock the UI layer\nconst mockUIInstance = {\n log: {\n step: jest.fn(),\n success: jest.fn(),\n error: jest.fn(),\n warn: jest.fn(),\n info: jest.fn(),\n },\n spinner: jest.fn(),\n select: jest.fn(),\n confirm: jest.fn(),\n text: jest.fn(),\n intro: jest.fn(),\n outro: jest.fn(),\n cancel: jest.fn(),\n note: jest.fn(),\n isCancel: jest.fn(),\n setDetectedFramework: jest.fn(),\n setCredentials: jest.fn(),\n pushStatus: jest.fn(),\n setLoginUrl: jest.fn(),\n showBlockingOutage: jest.fn(),\n setReadinessWarnings: jest.fn(),\n showSettingsOverride: jest.fn(),\n startRun: jest.fn(),\n syncTodos: jest.fn(),\n groupMultiselect: jest.fn(),\n multiselect: jest.fn(),\n};\njest.mock('../../ui', () => ({\n getUI: () => mockUIInstance,\n}));\n\ndescribe('runAgent', () => {\n let mockSpinner: {\n start: jest.Mock;\n stop: jest.Mock;\n message: jest.Mock;\n };\n\n const defaultOptions: WizardOptions = {\n debug: false,\n installDir: '/test/dir',\n forceInstall: false,\n default: false,\n signup: false,\n localMcp: false,\n ci: false,\n menu: false,\n benchmark: false,\n yaraReport: false,\n };\n\n const defaultAgentConfig = {\n workingDirectory: '/test/dir',\n mcpServers: {},\n model: 'claude-opus-4-5-20251101',\n };\n\n beforeEach(() => {\n jest.clearAllMocks();\n\n mockSpinner = {\n start: jest.fn(),\n stop: jest.fn(),\n message: jest.fn(),\n };\n\n mockUIInstance.spinner.mockReturnValue(mockSpinner);\n // Reset log mocks\n Object.values(mockUIInstance.log).forEach((fn) => fn.mockReset());\n });\n\n describe('race condition handling', () => {\n it('should return success when agent completes successfully then SDK cleanup fails', async () => {\n // This simulates the race condition:\n // 1. Agent completes with success result\n // 2. signalDone() is called, completing the prompt generator\n // 3. SDK tries to send cleanup command while streaming is active\n // 4. SDK throws an error\n // The fix should recognize we already got a success and return success anyway\n\n function* mockGeneratorWithCleanupError() {\n yield {\n type: 'system',\n subtype: 'init',\n model: 'claude-opus-4-5-20251101',\n tools: [],\n mcp_servers: [],\n };\n\n yield {\n type: 'result',\n subtype: 'success',\n is_error: false,\n result: 'Agent completed successfully',\n };\n\n // Simulate the SDK cleanup error that occurs after success\n throw new Error('only prompt commands are supported in streaming mode');\n }\n\n mockQuery.mockReturnValue(mockGeneratorWithCleanupError());\n\n const result = await runAgent(\n defaultAgentConfig,\n 'test prompt',\n defaultOptions,\n mockSpinner as unknown as SpinnerHandle,\n {\n successMessage: 'Test success',\n errorMessage: 'Test error',\n },\n );\n\n // Should return success (empty object), not throw\n expect(result).toEqual({});\n expect(mockSpinner.stop).toHaveBeenCalledWith('Test success');\n });\n\n it('should still throw when no success result was received before error', async () => {\n // If we never got a success result, errors should propagate normally\n\n function* mockGeneratorWithOnlyError() {\n yield {\n type: 'system',\n subtype: 'init',\n model: 'claude-opus-4-5-20251101',\n tools: [],\n mcp_servers: [],\n };\n\n // No success result, just an error\n throw new Error('Actual SDK error');\n }\n\n mockQuery.mockReturnValue(mockGeneratorWithOnlyError());\n\n await expect(\n runAgent(\n defaultAgentConfig,\n 'test prompt',\n defaultOptions,\n mockSpinner as unknown as SpinnerHandle,\n {\n successMessage: 'Test success',\n errorMessage: 'Test error',\n },\n ),\n ).rejects.toThrow('Actual SDK error');\n\n expect(mockSpinner.stop).toHaveBeenCalledWith('Test error');\n });\n\n it('should not treat error results as success', async () => {\n // A result with is_error: true should not count as success\n // Even if subtype is 'success', the is_error flag takes precedence\n\n function* mockGeneratorWithErrorResult() {\n yield {\n type: 'system',\n subtype: 'init',\n model: 'claude-opus-4-5-20251101',\n tools: [],\n mcp_servers: [],\n };\n\n yield {\n type: 'result',\n subtype: 'success', // subtype can be success but is_error true\n is_error: true,\n result: 'API Error: 500 Internal Server Error',\n };\n\n throw new Error('Process exited with code 1');\n }\n\n mockQuery.mockReturnValue(mockGeneratorWithErrorResult());\n\n const result = await runAgent(\n defaultAgentConfig,\n 'test prompt',\n defaultOptions,\n mockSpinner as unknown as SpinnerHandle,\n {\n successMessage: 'Test success',\n errorMessage: 'Test error',\n },\n );\n\n // Should return API error, not success\n expect(result.error).toBe('WIZARD_API_ERROR');\n expect(result.message).toContain('API Error');\n });\n\n it('should suppress user-facing errors when SDK yields error result after success', async () => {\n // This test models actual SDK behavior where the SDK emits TWO result messages:\n // 1. SDK yields success result (num_turns: 105, is_error: false)\n // 2. SDK yields a SECOND result with is_error: true containing\n // accumulated cleanup/telemetry errors\n // 3. The errors should be logged to file but NOT shown to the user\n //\n // This differs from the thrown exception test above - here the SDK YIELDS\n // an error result message instead of THROWING an exception.\n\n function* mockGeneratorWithYieldedErrorAfterSuccess() {\n yield {\n type: 'system',\n subtype: 'init',\n model: 'claude-opus-4-5-20251101',\n tools: [],\n mcp_servers: [],\n };\n\n // First result: success (this is the real completion)\n yield {\n type: 'result',\n subtype: 'success',\n is_error: false,\n num_turns: 105,\n result: '[WIZARD-REMARK] Integration completed successfully',\n session_id: '2ce14bda-6d86-4220-b5bb-ab24f7004290',\n total_cost_usd: 5.83,\n };\n\n // Second result: error (SDK cleanup noise - yielded, not thrown)\n yield {\n type: 'result',\n subtype: 'error_during_execution',\n is_error: true,\n num_turns: 0,\n session_id: '2ce14bda-6d86-4220-b5bb-ab24f7004290',\n total_cost_usd: 0,\n errors: [\n 'only prompt commands are supported in streaming mode',\n 'Error: 1P event logging: 14 events failed to export',\n 'Error: 1P event logging: 13 events failed to export',\n 'Error: Failed to export 14 events',\n ],\n };\n }\n\n mockQuery.mockReturnValue(mockGeneratorWithYieldedErrorAfterSuccess());\n\n const result = await runAgent(\n defaultAgentConfig,\n 'test prompt',\n defaultOptions,\n mockSpinner as unknown as SpinnerHandle,\n {\n successMessage: 'Test success',\n errorMessage: 'Test error',\n },\n );\n\n // Should return success (empty object), not error\n expect(result).toEqual({});\n expect(mockSpinner.stop).toHaveBeenCalledWith('Test success');\n\n // ui.log.error should NOT have been called (errors suppressed for user)\n expect(mockUIInstance.log.error).not.toHaveBeenCalled();\n });\n });\n});\n\ndescribe('createStopHook', () => {\n const hookInput = { stop_hook_active: false };\n\n it('empty queue: first call blocks for remark, second allows stop', () => {\n const hook = createStopHook([]);\n\n // First call → remark prompt\n const first = hook(hookInput);\n expect(first).toHaveProperty('decision', 'block');\n expect((first as { reason: string }).reason).toContain('WIZARD-REMARK');\n\n // Second call → allow stop\n const second = hook(hookInput);\n expect(second).toEqual({});\n });\n\n it('single feature: feature prompt, then remark, then allow stop', () => {\n const hook = createStopHook([AdditionalFeature.LLM]);\n\n // First call → LLM feature prompt\n const first = hook(hookInput);\n expect(first).toHaveProperty('decision', 'block');\n expect((first as { reason: string }).reason).toBe(\n ADDITIONAL_FEATURE_PROMPTS[AdditionalFeature.LLM],\n );\n\n // Second call → remark prompt\n const second = hook(hookInput);\n expect(second).toHaveProperty('decision', 'block');\n expect((second as { reason: string }).reason).toContain('WIZARD-REMARK');\n\n // Third call → allow stop\n const third = hook(hookInput);\n expect(third).toEqual({});\n });\n\n it('multiple queue entries: drains all, then remark, then allow stop', () => {\n // Queue the same feature twice to exercise multi-item draining\n const hook = createStopHook([AdditionalFeature.LLM, AdditionalFeature.LLM]);\n\n // First call → LLM prompt\n const first = hook(hookInput);\n expect(first).toHaveProperty('decision', 'block');\n expect((first as { reason: string }).reason).toBe(\n ADDITIONAL_FEATURE_PROMPTS[AdditionalFeature.LLM],\n );\n\n // Second call → LLM prompt again\n const second = hook(hookInput);\n expect(second).toHaveProperty('decision', 'block');\n expect((second as { reason: string }).reason).toBe(\n ADDITIONAL_FEATURE_PROMPTS[AdditionalFeature.LLM],\n );\n\n // Third call → remark prompt\n const third = hook(hookInput);\n expect(third).toHaveProperty('decision', 'block');\n expect((third as { reason: string }).reason).toContain('WIZARD-REMARK');\n\n // Fourth call → allow stop\n const fourth = hook(hookInput);\n expect(fourth).toEqual({});\n });\n\n it('allow stop is idempotent after all phases complete', () => {\n const hook = createStopHook([]);\n\n hook(hookInput); // remark\n hook(hookInput); // allow\n const extra = hook(hookInput); // still allow\n expect(extra).toEqual({});\n });\n\n it('allows stop immediately on API error (401)', () => {\n const collectedText = [\n 'Failed to authenticate. API Error: 401 {\"detail\":\"Authentication required\"}',\n ];\n const hook = createStopHook([AdditionalFeature.LLM], collectedText);\n\n const result = hook(hookInput);\n expect(result).toEqual({});\n });\n\n it('allows stop immediately on generic API error', () => {\n const collectedText = ['API Error: 500 Internal Server Error'];\n const hook = createStopHook([AdditionalFeature.LLM], collectedText);\n\n const result = hook(hookInput);\n expect(result).toEqual({});\n });\n\n it('proceeds normally when collectedText has no API error', () => {\n const collectedText = ['Some normal agent output'];\n const hook = createStopHook([], collectedText);\n\n // First call → remark prompt (normal behavior)\n const first = hook(hookInput);\n expect(first).toHaveProperty('decision', 'block');\n expect((first as { reason: string }).reason).toContain('WIZARD-REMARK');\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"agent-interface.test.js","sourceRoot":"","sources":["../../../../src/lib/__tests__/agent-interface.test.ts"],"names":[],"mappings":";;AAAA,8DAAoE;AAGpE,sDAG2B;AAE3B,oBAAoB;AACpB,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;AACnC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;AAE/B,sBAAsB;AACtB,MAAM,SAAS,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;AAC5B,IAAI,CAAC,IAAI,CAAC,gCAAgC,EAAE,GAAG,EAAE,CAAC,CAAC;IACjD,KAAK,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;CAClD,CAAC,CAAC,CAAC;AAEJ,oBAAoB;AACpB,MAAM,cAAc,GAAG;IACrB,GAAG,EAAE;QACH,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE;QACf,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE;QAClB,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;QAChB,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE;QACf,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE;KAChB;IACD,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE;IAClB,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE;IACjB,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE;IAClB,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE;IACf,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;IAChB,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;IAChB,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE;IACjB,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE;IACf,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE;IACnB,oBAAoB,EAAE,IAAI,CAAC,EAAE,EAAE;IAC/B,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;IACzB,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;IACrB,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE;IACtB,kBAAkB,EAAE,IAAI,CAAC,EAAE,EAAE;IAC7B,oBAAoB,EAAE,IAAI,CAAC,EAAE,EAAE;IAC/B,oBAAoB,EAAE,IAAI,CAAC,EAAE,EAAE;IAC/B,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE;IACnB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE;IACpB,gBAAgB,EAAE,IAAI,CAAC,EAAE,EAAE;IAC3B,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE;CACvB,CAAC;AACF,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;IAC3B,KAAK,EAAE,GAAG,EAAE,CAAC,cAAc;CAC5B,CAAC,CAAC,CAAC;AAEJ,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;IACxB,IAAI,WAIH,CAAC;IAEF,MAAM,cAAc,GAAkB;QACpC,KAAK,EAAE,KAAK;QACZ,UAAU,EAAE,WAAW;QACvB,YAAY,EAAE,KAAK;QACnB,OAAO,EAAE,KAAK;QACd,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,KAAK;QACf,EAAE,EAAE,KAAK;QACT,IAAI,EAAE,KAAK;QACX,SAAS,EAAE,KAAK;QAChB,UAAU,EAAE,KAAK;KAClB,CAAC;IAEF,MAAM,kBAAkB,GAAG;QACzB,gBAAgB,EAAE,WAAW;QAC7B,UAAU,EAAE,EAAE;QACd,KAAK,EAAE,0BAA0B;KAClC,CAAC;IAEF,UAAU,CAAC,GAAG,EAAE;QACd,IAAI,CAAC,aAAa,EAAE,CAAC;QAErB,WAAW,GAAG;YACZ,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;YAChB,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE;YACf,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE;SACnB,CAAC;QAEF,cAAc,CAAC,OAAO,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;QACpD,kBAAkB;QAClB,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACvC,EAAE,CAAC,gFAAgF,EAAE,KAAK,IAAI,EAAE;YAC9F,qCAAqC;YACrC,yCAAyC;YACzC,6DAA6D;YAC7D,iEAAiE;YACjE,yBAAyB;YACzB,8EAA8E;YAE9E,QAAQ,CAAC,CAAC,6BAA6B;gBACrC,MAAM;oBACJ,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,MAAM;oBACf,KAAK,EAAE,0BAA0B;oBACjC,KAAK,EAAE,EAAE;oBACT,WAAW,EAAE,EAAE;iBAChB,CAAC;gBAEF,MAAM;oBACJ,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,KAAK;oBACf,MAAM,EAAE,8BAA8B;iBACvC,CAAC;gBAEF,2DAA2D;gBAC3D,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;YAC1E,CAAC;YAED,SAAS,CAAC,eAAe,CAAC,6BAA6B,EAAE,CAAC,CAAC;YAE3D,MAAM,MAAM,GAAG,MAAM,IAAA,0BAAQ,EAC3B,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,WAAuC,EACvC;gBACE,cAAc,EAAE,cAAc;gBAC9B,YAAY,EAAE,YAAY;aAC3B,CACF,CAAC;YAEF,kDAAkD;YAClD,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC3B,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,oBAAoB,CAAC,cAAc,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qEAAqE,EAAE,KAAK,IAAI,EAAE;YACnF,qEAAqE;YAErE,QAAQ,CAAC,CAAC,0BAA0B;gBAClC,MAAM;oBACJ,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,MAAM;oBACf,KAAK,EAAE,0BAA0B;oBACjC,KAAK,EAAE,EAAE;oBACT,WAAW,EAAE,EAAE;iBAChB,CAAC;gBAEF,mCAAmC;gBACnC,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;YACtC,CAAC;YAED,SAAS,CAAC,eAAe,CAAC,0BAA0B,EAAE,CAAC,CAAC;YAExD,MAAM,MAAM,CACV,IAAA,0BAAQ,EACN,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,WAAuC,EACvC;gBACE,cAAc,EAAE,cAAc;gBAC9B,YAAY,EAAE,YAAY;aAC3B,CACF,CACF,CAAC,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;YAEtC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,oBAAoB,CAAC,YAAY,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;YACzD,2DAA2D;YAC3D,mEAAmE;YAEnE,QAAQ,CAAC,CAAC,4BAA4B;gBACpC,MAAM;oBACJ,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,MAAM;oBACf,KAAK,EAAE,0BAA0B;oBACjC,KAAK,EAAE,EAAE;oBACT,WAAW,EAAE,EAAE;iBAChB,CAAC;gBAEF,MAAM;oBACJ,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,SAAS,EAAE,2CAA2C;oBAC/D,QAAQ,EAAE,IAAI;oBACd,MAAM,EAAE,sCAAsC;iBAC/C,CAAC;gBAEF,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;YAChD,CAAC;YAED,SAAS,CAAC,eAAe,CAAC,4BAA4B,EAAE,CAAC,CAAC;YAE1D,MAAM,MAAM,GAAG,MAAM,IAAA,0BAAQ,EAC3B,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,WAAuC,EACvC;gBACE,cAAc,EAAE,cAAc;gBAC9B,YAAY,EAAE,YAAY;aAC3B,CACF,CAAC;YAEF,uCAAuC;YACvC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YAC9C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+EAA+E,EAAE,KAAK,IAAI,EAAE;YAC7F,gFAAgF;YAChF,iEAAiE;YACjE,+DAA+D;YAC/D,0CAA0C;YAC1C,mEAAmE;YACnE,EAAE;YACF,0EAA0E;YAC1E,4DAA4D;YAE5D,QAAQ,CAAC,CAAC,yCAAyC;gBACjD,MAAM;oBACJ,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,MAAM;oBACf,KAAK,EAAE,0BAA0B;oBACjC,KAAK,EAAE,EAAE;oBACT,WAAW,EAAE,EAAE;iBAChB,CAAC;gBAEF,sDAAsD;gBACtD,MAAM;oBACJ,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,KAAK;oBACf,SAAS,EAAE,GAAG;oBACd,MAAM,EAAE,oDAAoD;oBAC5D,UAAU,EAAE,sCAAsC;oBAClD,cAAc,EAAE,IAAI;iBACrB,CAAC;gBAEF,iEAAiE;gBACjE,MAAM;oBACJ,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,wBAAwB;oBACjC,QAAQ,EAAE,IAAI;oBACd,SAAS,EAAE,CAAC;oBACZ,UAAU,EAAE,sCAAsC;oBAClD,cAAc,EAAE,CAAC;oBACjB,MAAM,EAAE;wBACN,sDAAsD;wBACtD,qDAAqD;wBACrD,qDAAqD;wBACrD,mCAAmC;qBACpC;iBACF,CAAC;YACJ,CAAC;YAED,SAAS,CAAC,eAAe,CAAC,yCAAyC,EAAE,CAAC,CAAC;YAEvE,MAAM,MAAM,GAAG,MAAM,IAAA,0BAAQ,EAC3B,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,WAAuC,EACvC;gBACE,cAAc,EAAE,cAAc;gBAC9B,YAAY,EAAE,YAAY;aAC3B,CACF,CAAC;YAEF,kDAAkD;YAClD,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC3B,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,oBAAoB,CAAC,cAAc,CAAC,CAAC;YAE9D,wEAAwE;YACxE,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAC1D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;YAC/E,QAAQ,CAAC,CAAC,0BAA0B;gBAClC,MAAM;oBACJ,IAAI,EAAE,WAAW;oBACjB,OAAO,EAAE;wBACP,OAAO,EAAE;4BACP;gCACE,IAAI,EAAE,MAAM;gCACZ,IAAI,EAAE,6CAA6C;6BACpD;yBACF;qBACF;iBACF,CAAC;gBAEF,MAAM;oBACJ,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,KAAK;oBACf,MAAM,EAAE,8BAA8B;iBACvC,CAAC;YACJ,CAAC;YAED,SAAS,CAAC,eAAe,CAAC,0BAA0B,EAAE,CAAC,CAAC;YAExD,MAAM,MAAM,GAAG,MAAM,IAAA,0BAAQ,EAC3B,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,WAAuC,EACvC;gBACE,cAAc,EAAE,cAAc;gBAC9B,YAAY,EAAE,YAAY;aAC3B,CACF,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC3B,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,oBAAoB,CAAC,cAAc,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,MAAM,SAAS,GAAG,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC;IAE9C,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,MAAM,IAAI,GAAG,IAAA,gCAAc,EAAC,EAAE,CAAC,CAAC;QAEhC,6BAA6B;QAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QAC9B,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAClD,MAAM,CAAE,KAA4B,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QAExE,2BAA2B;QAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,MAAM,IAAI,GAAG,IAAA,gCAAc,EAAC,CAAC,kCAAiB,CAAC,GAAG,CAAC,CAAC,CAAC;QAErD,kCAAkC;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QAC9B,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAClD,MAAM,CAAE,KAA4B,CAAC,MAAM,CAAC,CAAC,IAAI,CAC/C,2CAA0B,CAAC,kCAAiB,CAAC,GAAG,CAAC,CAClD,CAAC;QAEF,8BAA8B;QAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,CAAE,MAA6B,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QAEzE,0BAA0B;QAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QAC9B,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;QAC1E,+DAA+D;QAC/D,MAAM,IAAI,GAAG,IAAA,gCAAc,EAAC,CAAC,kCAAiB,CAAC,GAAG,EAAE,kCAAiB,CAAC,GAAG,CAAC,CAAC,CAAC;QAE5E,0BAA0B;QAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QAC9B,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAClD,MAAM,CAAE,KAA4B,CAAC,MAAM,CAAC,CAAC,IAAI,CAC/C,2CAA0B,CAAC,kCAAiB,CAAC,GAAG,CAAC,CAClD,CAAC;QAEF,iCAAiC;QACjC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,CAAE,MAA6B,CAAC,MAAM,CAAC,CAAC,IAAI,CAChD,2CAA0B,CAAC,kCAAiB,CAAC,GAAG,CAAC,CAClD,CAAC;QAEF,6BAA6B;QAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QAC9B,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAClD,MAAM,CAAE,KAA4B,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QAExE,2BAA2B;QAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,IAAI,GAAG,IAAA,gCAAc,EAAC,EAAE,CAAC,CAAC;QAEhC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;QAC1B,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc;QAC7C,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,aAAa,GAAG;YACpB,6EAA6E;SAC9E,CAAC;QACF,MAAM,IAAI,GAAG,IAAA,gCAAc,EAAC,CAAC,kCAAiB,CAAC,GAAG,CAAC,EAAE,aAAa,CAAC,CAAC;QAEpE,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,aAAa,GAAG,CAAC,sCAAsC,CAAC,CAAC;QAC/D,MAAM,IAAI,GAAG,IAAA,gCAAc,EAAC,CAAC,kCAAiB,CAAC,GAAG,CAAC,EAAE,aAAa,CAAC,CAAC;QAEpE,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,aAAa,GAAG,CAAC,0BAA0B,CAAC,CAAC;QACnD,MAAM,IAAI,GAAG,IAAA,gCAAc,EAAC,EAAE,EAAE,aAAa,CAAC,CAAC;QAE/C,+CAA+C;QAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QAC9B,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAClD,MAAM,CAAE,KAA4B,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { runAgent, createStopHook } from '../agent/agent-interface';\nimport type { WizardOptions } from '../../utils/types';\nimport type { SpinnerHandle } from '../../ui';\nimport {\n AdditionalFeature,\n ADDITIONAL_FEATURE_PROMPTS,\n} from '../wizard-session';\n\n// Mock dependencies\njest.mock('../../utils/analytics');\njest.mock('../../utils/debug');\n\n// Mock the SDK module\nconst mockQuery = jest.fn();\njest.mock('@anthropic-ai/claude-agent-sdk', () => ({\n query: (...args: unknown[]) => mockQuery(...args),\n}));\n\n// Mock the UI layer\nconst mockUIInstance = {\n log: {\n step: jest.fn(),\n success: jest.fn(),\n error: jest.fn(),\n warn: jest.fn(),\n info: jest.fn(),\n },\n spinner: jest.fn(),\n select: jest.fn(),\n confirm: jest.fn(),\n text: jest.fn(),\n intro: jest.fn(),\n outro: jest.fn(),\n cancel: jest.fn(),\n note: jest.fn(),\n isCancel: jest.fn(),\n setDetectedFramework: jest.fn(),\n setCredentials: jest.fn(),\n pushStatus: jest.fn(),\n setLoginUrl: jest.fn(),\n showBlockingOutage: jest.fn(),\n setReadinessWarnings: jest.fn(),\n showSettingsOverride: jest.fn(),\n startRun: jest.fn(),\n syncTodos: jest.fn(),\n groupMultiselect: jest.fn(),\n multiselect: jest.fn(),\n};\njest.mock('../../ui', () => ({\n getUI: () => mockUIInstance,\n}));\n\ndescribe('runAgent', () => {\n let mockSpinner: {\n start: jest.Mock;\n stop: jest.Mock;\n message: jest.Mock;\n };\n\n const defaultOptions: WizardOptions = {\n debug: false,\n installDir: '/test/dir',\n forceInstall: false,\n default: false,\n signup: false,\n localMcp: false,\n ci: false,\n menu: false,\n benchmark: false,\n yaraReport: false,\n };\n\n const defaultAgentConfig = {\n workingDirectory: '/test/dir',\n mcpServers: {},\n model: 'claude-opus-4-5-20251101',\n };\n\n beforeEach(() => {\n jest.clearAllMocks();\n\n mockSpinner = {\n start: jest.fn(),\n stop: jest.fn(),\n message: jest.fn(),\n };\n\n mockUIInstance.spinner.mockReturnValue(mockSpinner);\n // Reset log mocks\n Object.values(mockUIInstance.log).forEach((fn) => fn.mockReset());\n });\n\n describe('race condition handling', () => {\n it('should return success when agent completes successfully then SDK cleanup fails', async () => {\n // This simulates the race condition:\n // 1. Agent completes with success result\n // 2. signalDone() is called, completing the prompt generator\n // 3. SDK tries to send cleanup command while streaming is active\n // 4. SDK throws an error\n // The fix should recognize we already got a success and return success anyway\n\n function* mockGeneratorWithCleanupError() {\n yield {\n type: 'system',\n subtype: 'init',\n model: 'claude-opus-4-5-20251101',\n tools: [],\n mcp_servers: [],\n };\n\n yield {\n type: 'result',\n subtype: 'success',\n is_error: false,\n result: 'Agent completed successfully',\n };\n\n // Simulate the SDK cleanup error that occurs after success\n throw new Error('only prompt commands are supported in streaming mode');\n }\n\n mockQuery.mockReturnValue(mockGeneratorWithCleanupError());\n\n const result = await runAgent(\n defaultAgentConfig,\n 'test prompt',\n defaultOptions,\n mockSpinner as unknown as SpinnerHandle,\n {\n successMessage: 'Test success',\n errorMessage: 'Test error',\n },\n );\n\n // Should return success (empty object), not throw\n expect(result).toEqual({});\n expect(mockSpinner.stop).toHaveBeenCalledWith('Test success');\n });\n\n it('should still throw when no success result was received before error', async () => {\n // If we never got a success result, errors should propagate normally\n\n function* mockGeneratorWithOnlyError() {\n yield {\n type: 'system',\n subtype: 'init',\n model: 'claude-opus-4-5-20251101',\n tools: [],\n mcp_servers: [],\n };\n\n // No success result, just an error\n throw new Error('Actual SDK error');\n }\n\n mockQuery.mockReturnValue(mockGeneratorWithOnlyError());\n\n await expect(\n runAgent(\n defaultAgentConfig,\n 'test prompt',\n defaultOptions,\n mockSpinner as unknown as SpinnerHandle,\n {\n successMessage: 'Test success',\n errorMessage: 'Test error',\n },\n ),\n ).rejects.toThrow('Actual SDK error');\n\n expect(mockSpinner.stop).toHaveBeenCalledWith('Test error');\n });\n\n it('should not treat error results as success', async () => {\n // A result with is_error: true should not count as success\n // Even if subtype is 'success', the is_error flag takes precedence\n\n function* mockGeneratorWithErrorResult() {\n yield {\n type: 'system',\n subtype: 'init',\n model: 'claude-opus-4-5-20251101',\n tools: [],\n mcp_servers: [],\n };\n\n yield {\n type: 'result',\n subtype: 'success', // subtype can be success but is_error true\n is_error: true,\n result: 'API Error: 500 Internal Server Error',\n };\n\n throw new Error('Process exited with code 1');\n }\n\n mockQuery.mockReturnValue(mockGeneratorWithErrorResult());\n\n const result = await runAgent(\n defaultAgentConfig,\n 'test prompt',\n defaultOptions,\n mockSpinner as unknown as SpinnerHandle,\n {\n successMessage: 'Test success',\n errorMessage: 'Test error',\n },\n );\n\n // Should return API error, not success\n expect(result.error).toBe('WIZARD_API_ERROR');\n expect(result.message).toContain('API Error');\n });\n\n it('should suppress user-facing errors when SDK yields error result after success', async () => {\n // This test models actual SDK behavior where the SDK emits TWO result messages:\n // 1. SDK yields success result (num_turns: 105, is_error: false)\n // 2. SDK yields a SECOND result with is_error: true containing\n // accumulated cleanup/telemetry errors\n // 3. The errors should be logged to file but NOT shown to the user\n //\n // This differs from the thrown exception test above - here the SDK YIELDS\n // an error result message instead of THROWING an exception.\n\n function* mockGeneratorWithYieldedErrorAfterSuccess() {\n yield {\n type: 'system',\n subtype: 'init',\n model: 'claude-opus-4-5-20251101',\n tools: [],\n mcp_servers: [],\n };\n\n // First result: success (this is the real completion)\n yield {\n type: 'result',\n subtype: 'success',\n is_error: false,\n num_turns: 105,\n result: '[WIZARD-REMARK] Integration completed successfully',\n session_id: '2ce14bda-6d86-4220-b5bb-ab24f7004290',\n total_cost_usd: 5.83,\n };\n\n // Second result: error (SDK cleanup noise - yielded, not thrown)\n yield {\n type: 'result',\n subtype: 'error_during_execution',\n is_error: true,\n num_turns: 0,\n session_id: '2ce14bda-6d86-4220-b5bb-ab24f7004290',\n total_cost_usd: 0,\n errors: [\n 'only prompt commands are supported in streaming mode',\n 'Error: 1P event logging: 14 events failed to export',\n 'Error: 1P event logging: 13 events failed to export',\n 'Error: Failed to export 14 events',\n ],\n };\n }\n\n mockQuery.mockReturnValue(mockGeneratorWithYieldedErrorAfterSuccess());\n\n const result = await runAgent(\n defaultAgentConfig,\n 'test prompt',\n defaultOptions,\n mockSpinner as unknown as SpinnerHandle,\n {\n successMessage: 'Test success',\n errorMessage: 'Test error',\n },\n );\n\n // Should return success (empty object), not error\n expect(result).toEqual({});\n expect(mockSpinner.stop).toHaveBeenCalledWith('Test success');\n\n // ui.log.error should NOT have been called (errors suppressed for user)\n expect(mockUIInstance.log.error).not.toHaveBeenCalled();\n });\n\n it('should ignore abort requests when no abort cases are registered', async () => {\n function* mockGeneratorWithAbortText() {\n yield {\n type: 'assistant',\n message: {\n content: [\n {\n type: 'text',\n text: '[ABORT] Could not find a Stripe integration',\n },\n ],\n },\n };\n\n yield {\n type: 'result',\n subtype: 'success',\n is_error: false,\n result: 'Agent completed successfully',\n };\n }\n\n mockQuery.mockReturnValue(mockGeneratorWithAbortText());\n\n const result = await runAgent(\n defaultAgentConfig,\n 'test prompt',\n defaultOptions,\n mockSpinner as unknown as SpinnerHandle,\n {\n successMessage: 'Test success',\n errorMessage: 'Test error',\n },\n );\n\n expect(result).toEqual({});\n expect(mockSpinner.stop).toHaveBeenCalledWith('Test success');\n });\n });\n});\n\ndescribe('createStopHook', () => {\n const hookInput = { stop_hook_active: false };\n\n it('empty queue: first call blocks for remark, second allows stop', () => {\n const hook = createStopHook([]);\n\n // First call → remark prompt\n const first = hook(hookInput);\n expect(first).toHaveProperty('decision', 'block');\n expect((first as { reason: string }).reason).toContain('WIZARD-REMARK');\n\n // Second call → allow stop\n const second = hook(hookInput);\n expect(second).toEqual({});\n });\n\n it('single feature: feature prompt, then remark, then allow stop', () => {\n const hook = createStopHook([AdditionalFeature.LLM]);\n\n // First call → LLM feature prompt\n const first = hook(hookInput);\n expect(first).toHaveProperty('decision', 'block');\n expect((first as { reason: string }).reason).toBe(\n ADDITIONAL_FEATURE_PROMPTS[AdditionalFeature.LLM],\n );\n\n // Second call → remark prompt\n const second = hook(hookInput);\n expect(second).toHaveProperty('decision', 'block');\n expect((second as { reason: string }).reason).toContain('WIZARD-REMARK');\n\n // Third call → allow stop\n const third = hook(hookInput);\n expect(third).toEqual({});\n });\n\n it('multiple queue entries: drains all, then remark, then allow stop', () => {\n // Queue the same feature twice to exercise multi-item draining\n const hook = createStopHook([AdditionalFeature.LLM, AdditionalFeature.LLM]);\n\n // First call → LLM prompt\n const first = hook(hookInput);\n expect(first).toHaveProperty('decision', 'block');\n expect((first as { reason: string }).reason).toBe(\n ADDITIONAL_FEATURE_PROMPTS[AdditionalFeature.LLM],\n );\n\n // Second call → LLM prompt again\n const second = hook(hookInput);\n expect(second).toHaveProperty('decision', 'block');\n expect((second as { reason: string }).reason).toBe(\n ADDITIONAL_FEATURE_PROMPTS[AdditionalFeature.LLM],\n );\n\n // Third call → remark prompt\n const third = hook(hookInput);\n expect(third).toHaveProperty('decision', 'block');\n expect((third as { reason: string }).reason).toContain('WIZARD-REMARK');\n\n // Fourth call → allow stop\n const fourth = hook(hookInput);\n expect(fourth).toEqual({});\n });\n\n it('allow stop is idempotent after all phases complete', () => {\n const hook = createStopHook([]);\n\n hook(hookInput); // remark\n hook(hookInput); // allow\n const extra = hook(hookInput); // still allow\n expect(extra).toEqual({});\n });\n\n it('allows stop immediately on API error (401)', () => {\n const collectedText = [\n 'Failed to authenticate. API Error: 401 {\"detail\":\"Authentication required\"}',\n ];\n const hook = createStopHook([AdditionalFeature.LLM], collectedText);\n\n const result = hook(hookInput);\n expect(result).toEqual({});\n });\n\n it('allows stop immediately on generic API error', () => {\n const collectedText = ['API Error: 500 Internal Server Error'];\n const hook = createStopHook([AdditionalFeature.LLM], collectedText);\n\n const result = hook(hookInput);\n expect(result).toEqual({});\n });\n\n it('proceeds normally when collectedText has no API error', () => {\n const collectedText = ['Some normal agent output'];\n const hook = createStopHook([], collectedText);\n\n // First call → remark prompt (normal behavior)\n const first = hook(hookInput);\n expect(first).toHaveProperty('decision', 'block');\n expect((first as { reason: string }).reason).toContain('WIZARD-REMARK');\n });\n});\n"]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const agent_prompt_js_1 = require("../agent-prompt.js");
|
|
4
|
+
function makeRunDef(overrides = {}) {
|
|
5
|
+
return {
|
|
6
|
+
integrationLabel: 'test',
|
|
7
|
+
spinnerMessage: 'Working...',
|
|
8
|
+
successMessage: 'Done!',
|
|
9
|
+
estimatedDurationMinutes: 5,
|
|
10
|
+
reportFile: 'test-report.md',
|
|
11
|
+
docsUrl: 'https://example.com/docs',
|
|
12
|
+
...overrides,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
const baseCtx = {
|
|
16
|
+
projectId: 42,
|
|
17
|
+
projectApiKey: 'phc_test123',
|
|
18
|
+
host: 'https://app.posthog.com',
|
|
19
|
+
};
|
|
20
|
+
describe('assemblePrompt', () => {
|
|
21
|
+
it('always includes project credentials in the default section', () => {
|
|
22
|
+
const prompt = (0, agent_prompt_js_1.assemblePrompt)(makeRunDef(), baseCtx);
|
|
23
|
+
expect(prompt).toContain('42');
|
|
24
|
+
expect(prompt).toContain('phc_test123');
|
|
25
|
+
expect(prompt).toContain('https://app.posthog.com');
|
|
26
|
+
});
|
|
27
|
+
it('composes three sections in order: default → custom → skill', () => {
|
|
28
|
+
const customFn = jest.fn(() => 'CUSTOM_INSTRUCTIONS');
|
|
29
|
+
const runDef = makeRunDef({ customPrompt: customFn });
|
|
30
|
+
const ctx = { ...baseCtx, skillPath: '/skills/test' };
|
|
31
|
+
const prompt = (0, agent_prompt_js_1.assemblePrompt)(runDef, ctx);
|
|
32
|
+
// All three sections present
|
|
33
|
+
expect(prompt).toContain('PostHog MCP server');
|
|
34
|
+
expect(prompt).toContain('CUSTOM_INSTRUCTIONS');
|
|
35
|
+
expect(prompt).toContain('SKILL.md');
|
|
36
|
+
// Ordering is enforced
|
|
37
|
+
const order = [
|
|
38
|
+
prompt.indexOf('PostHog MCP server'),
|
|
39
|
+
prompt.indexOf('CUSTOM_INSTRUCTIONS'),
|
|
40
|
+
prompt.indexOf('SKILL.md'),
|
|
41
|
+
];
|
|
42
|
+
expect(order).toEqual([...order].sort((a, b) => a - b));
|
|
43
|
+
// customPrompt receives the context
|
|
44
|
+
expect(customFn).toHaveBeenCalledWith(ctx);
|
|
45
|
+
});
|
|
46
|
+
it('omits custom and skill sections when not configured', () => {
|
|
47
|
+
const prompt = (0, agent_prompt_js_1.assemblePrompt)(makeRunDef(), baseCtx);
|
|
48
|
+
expect(prompt).not.toContain('SKILL.md');
|
|
49
|
+
// Only the default section — should be shorter than a full 3-section prompt
|
|
50
|
+
const full = (0, agent_prompt_js_1.assemblePrompt)(makeRunDef({ customPrompt: () => 'X' }), {
|
|
51
|
+
...baseCtx,
|
|
52
|
+
skillPath: '/s',
|
|
53
|
+
});
|
|
54
|
+
expect(prompt.length).toBeLessThan(full.length);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
//# sourceMappingURL=agent-prompt.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-prompt.test.js","sourceRoot":"","sources":["../../../../../src/lib/agent/__tests__/agent-prompt.test.ts"],"names":[],"mappings":";;AAAA,wDAAwE;AAGxE,SAAS,UAAU,CAAC,YAAkC,EAAE;IACtD,OAAO;QACL,gBAAgB,EAAE,MAAM;QACxB,cAAc,EAAE,YAAY;QAC5B,cAAc,EAAE,OAAO;QACvB,wBAAwB,EAAE,CAAC;QAC3B,UAAU,EAAE,gBAAgB;QAC5B,OAAO,EAAE,0BAA0B;QACnC,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,GAAkB;IAC7B,SAAS,EAAE,EAAE;IACb,aAAa,EAAE,aAAa;IAC5B,IAAI,EAAE,yBAAyB;CAChC,CAAC;AAEF,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,MAAM,GAAG,IAAA,gCAAc,EAAC,UAAU,EAAE,EAAE,OAAO,CAAC,CAAC;QAErD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,yBAAyB,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,qBAAqB,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,UAAU,CAAC,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC;QACtD,MAAM,GAAG,GAAkB,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC;QAErE,MAAM,MAAM,GAAG,IAAA,gCAAc,EAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAE3C,6BAA6B;QAC7B,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;QAChD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAErC,uBAAuB;QACvB,MAAM,KAAK,GAAG;YACZ,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC;YACpC,MAAM,CAAC,OAAO,CAAC,qBAAqB,CAAC;YACrC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC;SAC3B,CAAC;QACF,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAExD,oCAAoC;QACpC,MAAM,CAAC,QAAQ,CAAC,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,MAAM,GAAG,IAAA,gCAAc,EAAC,UAAU,EAAE,EAAE,OAAO,CAAC,CAAC;QAErD,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACzC,4EAA4E;QAC5E,MAAM,IAAI,GAAG,IAAA,gCAAc,EAAC,UAAU,CAAC,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE;YACnE,GAAG,OAAO;YACV,SAAS,EAAE,IAAI;SAChB,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { assemblePrompt, type PromptContext } from '../agent-prompt.js';\nimport type { WorkflowRun } from '../agent-runner.js';\n\nfunction makeRunDef(overrides: Partial<WorkflowRun> = {}): WorkflowRun {\n return {\n integrationLabel: 'test',\n spinnerMessage: 'Working...',\n successMessage: 'Done!',\n estimatedDurationMinutes: 5,\n reportFile: 'test-report.md',\n docsUrl: 'https://example.com/docs',\n ...overrides,\n };\n}\n\nconst baseCtx: PromptContext = {\n projectId: 42,\n projectApiKey: 'phc_test123',\n host: 'https://app.posthog.com',\n};\n\ndescribe('assemblePrompt', () => {\n it('always includes project credentials in the default section', () => {\n const prompt = assemblePrompt(makeRunDef(), baseCtx);\n\n expect(prompt).toContain('42');\n expect(prompt).toContain('phc_test123');\n expect(prompt).toContain('https://app.posthog.com');\n });\n\n it('composes three sections in order: default → custom → skill', () => {\n const customFn = jest.fn(() => 'CUSTOM_INSTRUCTIONS');\n const runDef = makeRunDef({ customPrompt: customFn });\n const ctx: PromptContext = { ...baseCtx, skillPath: '/skills/test' };\n\n const prompt = assemblePrompt(runDef, ctx);\n\n // All three sections present\n expect(prompt).toContain('PostHog MCP server');\n expect(prompt).toContain('CUSTOM_INSTRUCTIONS');\n expect(prompt).toContain('SKILL.md');\n\n // Ordering is enforced\n const order = [\n prompt.indexOf('PostHog MCP server'),\n prompt.indexOf('CUSTOM_INSTRUCTIONS'),\n prompt.indexOf('SKILL.md'),\n ];\n expect(order).toEqual([...order].sort((a, b) => a - b));\n\n // customPrompt receives the context\n expect(customFn).toHaveBeenCalledWith(ctx);\n });\n\n it('omits custom and skill sections when not configured', () => {\n const prompt = assemblePrompt(makeRunDef(), baseCtx);\n\n expect(prompt).not.toContain('SKILL.md');\n // Only the default section — should be shorter than a full 3-section prompt\n const full = assemblePrompt(makeRunDef({ customPrompt: () => 'X' }), {\n ...baseCtx,\n skillPath: '/s',\n });\n expect(prompt.length).toBeLessThan(full.length);\n });\n});\n"]}
|
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
* Shared agent interface for PostHog wizards
|
|
3
3
|
* Uses Claude Agent SDK directly with PostHog LLM gateway
|
|
4
4
|
*/
|
|
5
|
-
import { type SpinnerHandle } from '
|
|
6
|
-
import type { WizardOptions } from '
|
|
7
|
-
import { type AdditionalFeature } from '
|
|
8
|
-
import type { PackageManagerDetector } from '
|
|
5
|
+
import { type SpinnerHandle } from '../../ui';
|
|
6
|
+
import type { WizardOptions } from '../../utils/types';
|
|
7
|
+
import { type AdditionalFeature } from '../wizard-session';
|
|
8
|
+
import type { PackageManagerDetector } from '../detection/package-manager';
|
|
9
9
|
type McpServersConfig = any;
|
|
10
|
+
type AbortCaseMatcher = {
|
|
11
|
+
match: RegExp;
|
|
12
|
+
};
|
|
10
13
|
export declare const AgentSignals: {
|
|
11
14
|
/** Signal emitted when the agent reports progress to the user */
|
|
12
15
|
readonly STATUS: "[STATUS]";
|
|
@@ -14,6 +17,12 @@ export declare const AgentSignals: {
|
|
|
14
17
|
readonly ERROR_MCP_MISSING: "[ERROR-MCP-MISSING]";
|
|
15
18
|
/** Signal emitted when the agent cannot access the setup resource */
|
|
16
19
|
readonly ERROR_RESOURCE_MISSING: "[ERROR-RESOURCE-MISSING]";
|
|
20
|
+
/**
|
|
21
|
+
* Signal emitted when the agent cannot complete the workflow and is
|
|
22
|
+
* aborting intentionally (distinct from errors). Format: "[ABORT] <reason>".
|
|
23
|
+
* Workflows can declare an onAbort handler to render a custom screen.
|
|
24
|
+
*/
|
|
25
|
+
readonly ABORT: "[ABORT]";
|
|
17
26
|
/** Signal emitted when the agent provides a remark about its run */
|
|
18
27
|
readonly WIZARD_REMARK: "[WIZARD-REMARK]";
|
|
19
28
|
/** Signal prefix for benchmark logging */
|
|
@@ -34,7 +43,9 @@ export declare enum AgentErrorType {
|
|
|
34
43
|
/** Generic API error */
|
|
35
44
|
API_ERROR = "WIZARD_API_ERROR",
|
|
36
45
|
/** YARA scanner detected a security violation */
|
|
37
|
-
YARA_VIOLATION = "WIZARD_YARA_VIOLATION"
|
|
46
|
+
YARA_VIOLATION = "WIZARD_YARA_VIOLATION",
|
|
47
|
+
/** Agent intentionally aborted the workflow (emitted [ABORT] <reason>) */
|
|
48
|
+
ABORT = "WIZARD_ABORT"
|
|
38
49
|
}
|
|
39
50
|
/** Where a settings conflict was found. */
|
|
40
51
|
export type SettingsConflictSource = 'project' | 'managed';
|
|
@@ -119,7 +130,7 @@ type AgentRunConfig = {
|
|
|
119
130
|
* If the flag is missing or the value is not in config, returns the "base" variant (VARIANT: "base").
|
|
120
131
|
*/
|
|
121
132
|
export declare function buildWizardMetadata(flags?: Record<string, string>): Record<string, string>;
|
|
122
|
-
export { isSkillInstallCommand } from '
|
|
133
|
+
export { isSkillInstallCommand } from '../skill-install';
|
|
123
134
|
/**
|
|
124
135
|
* Permission hook that allows only safe commands.
|
|
125
136
|
* - Package manager install commands
|
|
@@ -150,6 +161,7 @@ export declare function runAgent(agentConfig: AgentRunConfig, prompt: string, op
|
|
|
150
161
|
successMessage?: string;
|
|
151
162
|
errorMessage?: string;
|
|
152
163
|
additionalFeatureQueue?: readonly AdditionalFeature[];
|
|
164
|
+
abortCases?: readonly AbortCaseMatcher[];
|
|
153
165
|
}, middleware?: {
|
|
154
166
|
onMessage(message: any): void;
|
|
155
167
|
finalize(resultMessage: any, totalDurationMs: number): any;
|
|
@@ -52,17 +52,17 @@ exports.initializeAgent = initializeAgent;
|
|
|
52
52
|
exports.runAgent = runAgent;
|
|
53
53
|
const path_1 = __importDefault(require("path"));
|
|
54
54
|
const fs = __importStar(require("fs"));
|
|
55
|
-
const ui_1 = require("
|
|
56
|
-
const debug_1 = require("
|
|
57
|
-
const analytics_1 = require("
|
|
58
|
-
const constants_1 = require("
|
|
59
|
-
const wizard_session_1 = require("
|
|
60
|
-
const wizard_abort_1 = require("
|
|
61
|
-
const custom_headers_1 = require("
|
|
62
|
-
const urls_1 = require("
|
|
63
|
-
const safe_tools_1 = require("
|
|
64
|
-
const wizard_tools_1 = require("
|
|
65
|
-
const yara_hooks_1 = require("
|
|
55
|
+
const ui_1 = require("../../ui");
|
|
56
|
+
const debug_1 = require("../../utils/debug");
|
|
57
|
+
const analytics_1 = require("../../utils/analytics");
|
|
58
|
+
const constants_1 = require("../constants");
|
|
59
|
+
const wizard_session_1 = require("../wizard-session");
|
|
60
|
+
const wizard_abort_1 = require("../../utils/wizard-abort");
|
|
61
|
+
const custom_headers_1 = require("../../utils/custom-headers");
|
|
62
|
+
const urls_1 = require("../../utils/urls");
|
|
63
|
+
const safe_tools_1 = require("../safe-tools");
|
|
64
|
+
const wizard_tools_1 = require("../wizard-tools");
|
|
65
|
+
const yara_hooks_1 = require("../yara-hooks");
|
|
66
66
|
const commandments_1 = require("./commandments");
|
|
67
67
|
// Dynamic import cache for ESM module
|
|
68
68
|
let _sdkModule = null;
|
|
@@ -88,6 +88,12 @@ exports.AgentSignals = {
|
|
|
88
88
|
ERROR_MCP_MISSING: '[ERROR-MCP-MISSING]',
|
|
89
89
|
/** Signal emitted when the agent cannot access the setup resource */
|
|
90
90
|
ERROR_RESOURCE_MISSING: '[ERROR-RESOURCE-MISSING]',
|
|
91
|
+
/**
|
|
92
|
+
* Signal emitted when the agent cannot complete the workflow and is
|
|
93
|
+
* aborting intentionally (distinct from errors). Format: "[ABORT] <reason>".
|
|
94
|
+
* Workflows can declare an onAbort handler to render a custom screen.
|
|
95
|
+
*/
|
|
96
|
+
ABORT: '[ABORT]',
|
|
91
97
|
/** Signal emitted when the agent provides a remark about its run */
|
|
92
98
|
WIZARD_REMARK: '[WIZARD-REMARK]',
|
|
93
99
|
/** Signal prefix for benchmark logging */
|
|
@@ -109,6 +115,8 @@ var AgentErrorType;
|
|
|
109
115
|
AgentErrorType["API_ERROR"] = "WIZARD_API_ERROR";
|
|
110
116
|
/** YARA scanner detected a security violation */
|
|
111
117
|
AgentErrorType["YARA_VIOLATION"] = "WIZARD_YARA_VIOLATION";
|
|
118
|
+
/** Agent intentionally aborted the workflow (emitted [ABORT] <reason>) */
|
|
119
|
+
AgentErrorType["ABORT"] = "WIZARD_ABORT";
|
|
112
120
|
})(AgentErrorType || (exports.AgentErrorType = AgentErrorType = {}));
|
|
113
121
|
const BLOCKING_ENV_KEYS = [
|
|
114
122
|
'ANTHROPIC_API_KEY',
|
|
@@ -362,7 +370,7 @@ const SAFE_SCRIPTS = [
|
|
|
362
370
|
*/
|
|
363
371
|
const DANGEROUS_OPERATORS = /[;`$()]/;
|
|
364
372
|
// Re-export for backwards compatibility — canonical source is skill-install.ts
|
|
365
|
-
var skill_install_1 = require("
|
|
373
|
+
var skill_install_1 = require("../skill-install");
|
|
366
374
|
Object.defineProperty(exports, "isSkillInstallCommand", { enumerable: true, get: function () { return skill_install_1.isSkillInstallCommand; } });
|
|
367
375
|
/**
|
|
368
376
|
* Check if command is an allowed package manager command.
|
|
@@ -582,7 +590,7 @@ function checkYaraViolation(outputText, spinner) {
|
|
|
582
590
|
* @returns An object containing any error detected in the agent's output
|
|
583
591
|
*/
|
|
584
592
|
async function runAgent(agentConfig, prompt, options, spinner, config, middleware) {
|
|
585
|
-
const { spinnerMessage = 'Customizing your PostHog setup...', successMessage = 'PostHog integration complete', errorMessage = 'Integration failed', } = config ?? {};
|
|
593
|
+
const { spinnerMessage = 'Customizing your PostHog setup...', successMessage = 'PostHog integration complete', errorMessage = 'Integration failed', abortCases = [], } = config ?? {};
|
|
586
594
|
const { query } = await getSDKModule();
|
|
587
595
|
spinner.start(spinnerMessage);
|
|
588
596
|
const cliPath = getClaudeCodeExecutablePath();
|
|
@@ -650,6 +658,11 @@ async function runAgent(agentConfig, prompt, options, spinner, config, middlewar
|
|
|
650
658
|
// Event plan file watcher — cleaned up in finally block
|
|
651
659
|
let eventPlanWatcher;
|
|
652
660
|
let eventPlanInterval;
|
|
661
|
+
// Abort controller — lets us force-kill the SDK query when we detect an
|
|
662
|
+
// [ABORT] signal in the agent's output. Also stashes the reason so the
|
|
663
|
+
// runner can surface it via outroData after we unwind.
|
|
664
|
+
const abortController = new AbortController();
|
|
665
|
+
let abortReason = null;
|
|
653
666
|
try {
|
|
654
667
|
// Tools needed for the wizard:
|
|
655
668
|
// - File operations: Read, Write, Edit
|
|
@@ -672,6 +685,7 @@ async function runAgent(agentConfig, prompt, options, spinner, config, middlewar
|
|
|
672
685
|
const response = query({
|
|
673
686
|
prompt: createPromptStream(),
|
|
674
687
|
options: {
|
|
688
|
+
abortController,
|
|
675
689
|
model: agentConfig.model,
|
|
676
690
|
cwd: agentConfig.workingDirectory,
|
|
677
691
|
permissionMode: 'acceptEdits',
|
|
@@ -819,6 +833,30 @@ async function runAgent(agentConfig, prompt, options, spinner, config, middlewar
|
|
|
819
833
|
// Pass receivedSuccessResult so handleSDKMessage can suppress user-facing error
|
|
820
834
|
// output for post-success cleanup errors while still logging them to file
|
|
821
835
|
handleSDKMessage(message, options, spinner, collectedText, receivedSuccessResult);
|
|
836
|
+
// [ABORT] detection: the skill emits "[ABORT] <reason>" when it
|
|
837
|
+
// cannot complete the workflow. Kill the SDK query immediately —
|
|
838
|
+
// the prompt doesn't need to cooperate with "and exit" because the
|
|
839
|
+
// abort is enforced here. The reason is surfaced via the returned
|
|
840
|
+
// AgentErrorType.ABORT so the runner can render a custom screen.
|
|
841
|
+
if (abortCases.length > 0 &&
|
|
842
|
+
!abortReason &&
|
|
843
|
+
message.type === 'assistant') {
|
|
844
|
+
const content = message.message?.content;
|
|
845
|
+
if (Array.isArray(content)) {
|
|
846
|
+
for (const block of content) {
|
|
847
|
+
if (block.type === 'text' && typeof block.text === 'string') {
|
|
848
|
+
const match = block.text.match(/\[ABORT\]\s*(.+?)(?:\n|$)/);
|
|
849
|
+
if (match) {
|
|
850
|
+
abortReason = match[1].trim();
|
|
851
|
+
(0, debug_1.logToFile)(`Agent emitted [ABORT]: ${abortReason}`);
|
|
852
|
+
abortController.abort();
|
|
853
|
+
signalDone();
|
|
854
|
+
break;
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
}
|
|
822
860
|
// 401: show auth error screen and exit immediately
|
|
823
861
|
if (message.type === 'assistant' &&
|
|
824
862
|
collectedText.join('\n').includes('API Error: 401')) {
|
|
@@ -848,6 +886,12 @@ async function runAgent(agentConfig, prompt, options, spinner, config, middlewar
|
|
|
848
886
|
signalDone();
|
|
849
887
|
}
|
|
850
888
|
}
|
|
889
|
+
// If the middleware caught an [ABORT] and aborted the SDK query, surface
|
|
890
|
+
// it as a structured error before checking other signals.
|
|
891
|
+
if (abortReason) {
|
|
892
|
+
spinner.stop('Wizard aborted');
|
|
893
|
+
return { error: AgentErrorType.ABORT, message: abortReason };
|
|
894
|
+
}
|
|
851
895
|
const outputText = collectedText.join('\n');
|
|
852
896
|
// Check for YARA scanner violations
|
|
853
897
|
const yaraResult = checkYaraViolation(outputText, spinner);
|
|
@@ -885,6 +929,12 @@ async function runAgent(agentConfig, prompt, options, spinner, config, middlewar
|
|
|
885
929
|
catch (error) {
|
|
886
930
|
// Signal done to unblock the async generator
|
|
887
931
|
signalDone();
|
|
932
|
+
// If the middleware caught an [ABORT] and triggered abortController.abort(),
|
|
933
|
+
// the SDK will throw an AbortError — surface it as a clean abort result.
|
|
934
|
+
if (abortReason) {
|
|
935
|
+
spinner.stop('Wizard aborted');
|
|
936
|
+
return { error: AgentErrorType.ABORT, message: abortReason };
|
|
937
|
+
}
|
|
888
938
|
// If we already received a successful result, the error is from SDK cleanup
|
|
889
939
|
// This happens due to a race condition: the SDK tries to send a cleanup command
|
|
890
940
|
// after the prompt stream closes, but streaming mode is still active.
|