@posthog/wizard 1.25.0 → 1.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/dist/src/django/django-wizard-agent.d.ts +5 -0
  2. package/dist/src/django/django-wizard-agent.js +159 -0
  3. package/dist/src/django/django-wizard-agent.js.map +1 -0
  4. package/dist/src/django/utils.d.ts +31 -0
  5. package/dist/src/django/utils.js +325 -0
  6. package/dist/src/django/utils.js.map +1 -0
  7. package/dist/src/lib/agent-interface.d.ts +7 -1
  8. package/dist/src/lib/agent-interface.js +114 -20
  9. package/dist/src/lib/agent-interface.js.map +1 -1
  10. package/dist/src/lib/agent-runner.js +50 -13
  11. package/dist/src/lib/agent-runner.js.map +1 -1
  12. package/dist/src/lib/config.d.ts +12 -1
  13. package/dist/src/lib/config.js +126 -12
  14. package/dist/src/lib/config.js.map +1 -1
  15. package/dist/src/lib/constants.d.ts +2 -1
  16. package/dist/src/lib/constants.js +3 -0
  17. package/dist/src/lib/constants.js.map +1 -1
  18. package/dist/src/lib/framework-config.d.ts +16 -0
  19. package/dist/src/lib/framework-config.js.map +1 -1
  20. package/dist/src/mcp.d.ts +0 -3
  21. package/dist/src/mcp.js +2 -32
  22. package/dist/src/mcp.js.map +1 -1
  23. package/dist/src/nextjs/nextjs-wizard-agent.js +2 -0
  24. package/dist/src/nextjs/nextjs-wizard-agent.js.map +1 -1
  25. package/dist/src/react-router/react-router-wizard-agent.js +2 -0
  26. package/dist/src/react-router/react-router-wizard-agent.js.map +1 -1
  27. package/dist/src/run.js +8 -1
  28. package/dist/src/run.js.map +1 -1
  29. package/dist/src/steps/add-mcp-server-to-clients/MCPClient.d.ts +5 -4
  30. package/dist/src/steps/add-mcp-server-to-clients/MCPClient.js +6 -6
  31. package/dist/src/steps/add-mcp-server-to-clients/MCPClient.js.map +1 -1
  32. package/dist/src/steps/add-mcp-server-to-clients/__tests__/defaults.test.d.ts +1 -0
  33. package/dist/src/steps/add-mcp-server-to-clients/__tests__/defaults.test.js +92 -0
  34. package/dist/src/steps/add-mcp-server-to-clients/__tests__/defaults.test.js.map +1 -0
  35. package/dist/src/steps/add-mcp-server-to-clients/clients/__tests__/claude.test.js +11 -1
  36. package/dist/src/steps/add-mcp-server-to-clients/clients/__tests__/claude.test.js.map +1 -1
  37. package/dist/src/steps/add-mcp-server-to-clients/clients/claude-code.d.ts +8 -7
  38. package/dist/src/steps/add-mcp-server-to-clients/clients/claude-code.js +5 -3
  39. package/dist/src/steps/add-mcp-server-to-clients/clients/claude-code.js.map +1 -1
  40. package/dist/src/steps/add-mcp-server-to-clients/clients/claude.d.ts +6 -6
  41. package/dist/src/steps/add-mcp-server-to-clients/clients/codex.d.ts +8 -7
  42. package/dist/src/steps/add-mcp-server-to-clients/clients/codex.js +2 -2
  43. package/dist/src/steps/add-mcp-server-to-clients/clients/codex.js.map +1 -1
  44. package/dist/src/steps/add-mcp-server-to-clients/clients/cursor.d.ts +9 -8
  45. package/dist/src/steps/add-mcp-server-to-clients/clients/cursor.js +4 -4
  46. package/dist/src/steps/add-mcp-server-to-clients/clients/cursor.js.map +1 -1
  47. package/dist/src/steps/add-mcp-server-to-clients/clients/visual-studio-code.d.ts +9 -8
  48. package/dist/src/steps/add-mcp-server-to-clients/clients/visual-studio-code.js +4 -4
  49. package/dist/src/steps/add-mcp-server-to-clients/clients/visual-studio-code.js.map +1 -1
  50. package/dist/src/steps/add-mcp-server-to-clients/clients/zed.d.ts +9 -8
  51. package/dist/src/steps/add-mcp-server-to-clients/clients/zed.js +4 -4
  52. package/dist/src/steps/add-mcp-server-to-clients/clients/zed.js.map +1 -1
  53. package/dist/src/steps/add-mcp-server-to-clients/defaults.d.ts +14 -14
  54. package/dist/src/steps/add-mcp-server-to-clients/defaults.js +34 -13
  55. package/dist/src/steps/add-mcp-server-to-clients/defaults.js.map +1 -1
  56. package/dist/src/steps/add-mcp-server-to-clients/index.d.ts +1 -1
  57. package/dist/src/steps/add-mcp-server-to-clients/index.js +4 -5
  58. package/dist/src/steps/add-mcp-server-to-clients/index.js.map +1 -1
  59. package/dist/src/utils/clack-utils.d.ts +5 -0
  60. package/dist/src/utils/clack-utils.js +14 -0
  61. package/dist/src/utils/clack-utils.js.map +1 -1
  62. package/package.json +1 -1
@@ -0,0 +1,5 @@
1
+ import type { WizardOptions } from '../utils/types';
2
+ /**
3
+ * Django wizard powered by the universal agent runner.
4
+ */
5
+ export declare function runDjangoWizardAgent(options: WizardOptions): Promise<void>;
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.runDjangoWizardAgent = runDjangoWizardAgent;
40
+ const debug_1 = require("../utils/debug");
41
+ const agent_runner_1 = require("../lib/agent-runner");
42
+ const constants_1 = require("../lib/constants");
43
+ const clack_1 = __importDefault(require("../utils/clack"));
44
+ const chalk_1 = __importDefault(require("chalk"));
45
+ const semver = __importStar(require("semver"));
46
+ const utils_1 = require("./utils");
47
+ /**
48
+ * Django framework configuration for the universal agent runner
49
+ */
50
+ const MINIMUM_DJANGO_VERSION = '3.0.0';
51
+ const DJANGO_AGENT_CONFIG = {
52
+ metadata: {
53
+ name: 'Django',
54
+ integration: constants_1.Integration.django,
55
+ docsUrl: 'https://posthog.com/docs/libraries/django',
56
+ unsupportedVersionDocsUrl: 'https://posthog.com/docs/libraries/python',
57
+ gatherContext: async (options) => {
58
+ const projectType = await (0, utils_1.getDjangoProjectType)(options);
59
+ const settingsFile = await (0, utils_1.findDjangoSettingsFile)(options);
60
+ return { projectType, settingsFile };
61
+ },
62
+ },
63
+ detection: {
64
+ packageName: 'django',
65
+ packageDisplayName: 'Django',
66
+ usesPackageJson: false,
67
+ getVersion: (_packageJson) => {
68
+ // For Django, we don't use package.json. Version is extracted separately
69
+ // from requirements.txt or pyproject.toml in the wizard entry point
70
+ return undefined;
71
+ },
72
+ getVersionBucket: utils_1.getDjangoVersionBucket,
73
+ },
74
+ environment: {
75
+ uploadToHosting: false,
76
+ getEnvVars: (apiKey, host) => ({
77
+ POSTHOG_API_KEY: apiKey,
78
+ POSTHOG_HOST: host,
79
+ }),
80
+ },
81
+ analytics: {
82
+ getTags: (context) => {
83
+ const projectType = context.projectType;
84
+ return {
85
+ projectType: projectType || 'unknown',
86
+ };
87
+ },
88
+ },
89
+ prompts: {
90
+ projectTypeDetection: 'This is a Python/Django project. Look for requirements.txt, pyproject.toml, setup.py, Pipfile, or manage.py to confirm.',
91
+ packageInstallation: 'Use pip, poetry, or pipenv based on existing config files (requirements.txt, pyproject.toml, Pipfile). Do not pin the posthog version - just add "posthog" without version constraints.',
92
+ getAdditionalContextLines: (context) => {
93
+ const projectType = context.projectType;
94
+ const projectTypeName = projectType
95
+ ? (0, utils_1.getDjangoProjectTypeName)(projectType)
96
+ : 'unknown';
97
+ // Map project type to framework ID for MCP docs resource
98
+ const frameworkIdMap = {
99
+ [utils_1.DjangoProjectType.STANDARD]: 'django',
100
+ [utils_1.DjangoProjectType.DRF]: 'django',
101
+ [utils_1.DjangoProjectType.WAGTAIL]: 'django',
102
+ [utils_1.DjangoProjectType.CHANNELS]: 'django',
103
+ };
104
+ const frameworkId = projectType ? frameworkIdMap[projectType] : 'django';
105
+ const lines = [
106
+ `Project type: ${projectTypeName}`,
107
+ `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,
108
+ ];
109
+ if (context.settingsFile) {
110
+ lines.push(`Settings file: ${context.settingsFile}`);
111
+ }
112
+ return lines;
113
+ },
114
+ },
115
+ ui: {
116
+ successMessage: 'PostHog integration complete',
117
+ estimatedDurationMinutes: 5,
118
+ getOutroChanges: (context) => {
119
+ const projectType = context.projectType;
120
+ const projectTypeName = projectType
121
+ ? (0, utils_1.getDjangoProjectTypeName)(projectType)
122
+ : 'Django';
123
+ return [
124
+ `Analyzed your ${projectTypeName} project structure`,
125
+ `Installed the PostHog Python package`,
126
+ `Configured PostHog in your Django settings`,
127
+ `Added PostHog middleware for automatic event tracking`,
128
+ ];
129
+ },
130
+ getOutroNextSteps: () => [
131
+ 'Start your Django development server to see PostHog in action',
132
+ 'Visit your PostHog dashboard to see incoming events',
133
+ 'Use identify_context() within new_context() to associate events with users',
134
+ ],
135
+ },
136
+ };
137
+ /**
138
+ * Django wizard powered by the universal agent runner.
139
+ */
140
+ async function runDjangoWizardAgent(options) {
141
+ if (options.debug) {
142
+ (0, debug_1.enableDebugLogs)();
143
+ }
144
+ // Check Django version - agent wizard requires >= 3.0.0
145
+ const djangoVersion = await (0, utils_1.getDjangoVersion)(options);
146
+ if (djangoVersion) {
147
+ const coercedVersion = semver.coerce(djangoVersion);
148
+ if (coercedVersion && semver.lt(coercedVersion, MINIMUM_DJANGO_VERSION)) {
149
+ const docsUrl = DJANGO_AGENT_CONFIG.metadata.unsupportedVersionDocsUrl ??
150
+ DJANGO_AGENT_CONFIG.metadata.docsUrl;
151
+ clack_1.default.log.warn(`Sorry: the wizard can't help you with Django ${djangoVersion}. Upgrade to Django ${MINIMUM_DJANGO_VERSION} or later, or check out the manual setup guide.`);
152
+ clack_1.default.log.info(`Setup Django manually: ${chalk_1.default.cyan(docsUrl)}`);
153
+ clack_1.default.outro('PostHog wizard will see you next time!');
154
+ return;
155
+ }
156
+ }
157
+ await (0, agent_runner_1.runAgentWizard)(DJANGO_AGENT_CONFIG, options);
158
+ }
159
+ //# sourceMappingURL=django-wizard-agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"django-wizard-agent.js","sourceRoot":"","sources":["../../../src/django/django-wizard-agent.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6HA,oDA2BC;AArJD,0CAAiD;AACjD,sDAAqD;AACrD,gDAA+C;AAC/C,2DAAmC;AACnC,kDAA0B;AAC1B,+CAAiC;AACjC,mCAOiB;AAEjB;;GAEG;AACH,MAAM,sBAAsB,GAAG,OAAO,CAAC;AAEvC,MAAM,mBAAmB,GAAoB;IAC3C,QAAQ,EAAE;QACR,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,uBAAW,CAAC,MAAM;QAC/B,OAAO,EAAE,2CAA2C;QACpD,yBAAyB,EAAE,2CAA2C;QACtE,aAAa,EAAE,KAAK,EAAE,OAAsB,EAAE,EAAE;YAC9C,MAAM,WAAW,GAAG,MAAM,IAAA,4BAAoB,EAAC,OAAO,CAAC,CAAC;YACxD,MAAM,YAAY,GAAG,MAAM,IAAA,8BAAsB,EAAC,OAAO,CAAC,CAAC;YAC3D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;QACvC,CAAC;KACF;IAED,SAAS,EAAE;QACT,WAAW,EAAE,QAAQ;QACrB,kBAAkB,EAAE,QAAQ;QAC5B,eAAe,EAAE,KAAK;QACtB,UAAU,EAAE,CAAC,YAAiB,EAAE,EAAE;YAChC,yEAAyE;YACzE,oEAAoE;YACpE,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,gBAAgB,EAAE,8BAAsB;KACzC;IAED,WAAW,EAAE;QACX,eAAe,EAAE,KAAK;QACtB,UAAU,EAAE,CAAC,MAAc,EAAE,IAAY,EAAE,EAAE,CAAC,CAAC;YAC7C,eAAe,EAAE,MAAM;YACvB,YAAY,EAAE,IAAI;SACnB,CAAC;KACH;IAED,SAAS,EAAE;QACT,OAAO,EAAE,CAAC,OAAY,EAAE,EAAE;YACxB,MAAM,WAAW,GAAG,OAAO,CAAC,WAAgC,CAAC;YAC7D,OAAO;gBACL,WAAW,EAAE,WAAW,IAAI,SAAS;aACtC,CAAC;QACJ,CAAC;KACF;IAED,OAAO,EAAE;QACP,oBAAoB,EAClB,yHAAyH;QAC3H,mBAAmB,EACjB,yLAAyL;QAC3L,yBAAyB,EAAE,CAAC,OAAY,EAAE,EAAE;YAC1C,MAAM,WAAW,GAAG,OAAO,CAAC,WAAgC,CAAC;YAC7D,MAAM,eAAe,GAAG,WAAW;gBACjC,CAAC,CAAC,IAAA,gCAAwB,EAAC,WAAW,CAAC;gBACvC,CAAC,CAAC,SAAS,CAAC;YAEd,yDAAyD;YACzD,MAAM,cAAc,GAAsC;gBACxD,CAAC,yBAAiB,CAAC,QAAQ,CAAC,EAAE,QAAQ;gBACtC,CAAC,yBAAiB,CAAC,GAAG,CAAC,EAAE,QAAQ;gBACjC,CAAC,yBAAiB,CAAC,OAAO,CAAC,EAAE,QAAQ;gBACrC,CAAC,yBAAiB,CAAC,QAAQ,CAAC,EAAE,QAAQ;aACvC,CAAC;YAEF,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;YAEzE,MAAM,KAAK,GAAG;gBACZ,iBAAiB,eAAe,EAAE;gBAClC,sBAAsB,WAAW,mCAAmC,WAAW,qBAAqB;aACrG,CAAC;YAEF,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;gBACzB,KAAK,CAAC,IAAI,CAAC,kBAAkB,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;YACvD,CAAC;YAED,OAAO,KAAK,CAAC;QACf,CAAC;KACF;IAED,EAAE,EAAE;QACF,cAAc,EAAE,8BAA8B;QAC9C,wBAAwB,EAAE,CAAC;QAC3B,eAAe,EAAE,CAAC,OAAY,EAAE,EAAE;YAChC,MAAM,WAAW,GAAG,OAAO,CAAC,WAAgC,CAAC;YAC7D,MAAM,eAAe,GAAG,WAAW;gBACjC,CAAC,CAAC,IAAA,gCAAwB,EAAC,WAAW,CAAC;gBACvC,CAAC,CAAC,QAAQ,CAAC;YACb,OAAO;gBACL,iBAAiB,eAAe,oBAAoB;gBACpD,sCAAsC;gBACtC,4CAA4C;gBAC5C,uDAAuD;aACxD,CAAC;QACJ,CAAC;QACD,iBAAiB,EAAE,GAAG,EAAE,CAAC;YACvB,+DAA+D;YAC/D,qDAAqD;YACrD,4EAA4E;SAC7E;KACF;CACF,CAAC;AAEF;;GAEG;AACI,KAAK,UAAU,oBAAoB,CACxC,OAAsB;IAEtB,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,IAAA,uBAAe,GAAE,CAAC;IACpB,CAAC;IAED,wDAAwD;IACxD,MAAM,aAAa,GAAG,MAAM,IAAA,wBAAgB,EAAC,OAAO,CAAC,CAAC;IAEtD,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QACpD,IAAI,cAAc,IAAI,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,sBAAsB,CAAC,EAAE,CAAC;YACxE,MAAM,OAAO,GACX,mBAAmB,CAAC,QAAQ,CAAC,yBAAyB;gBACtD,mBAAmB,CAAC,QAAQ,CAAC,OAAO,CAAC;YAEvC,eAAK,CAAC,GAAG,CAAC,IAAI,CACZ,gDAAgD,aAAa,uBAAuB,sBAAsB,iDAAiD,CAC5J,CAAC;YACF,eAAK,CAAC,GAAG,CAAC,IAAI,CAAC,0BAA0B,eAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAChE,eAAK,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;YACtD,OAAO;QACT,CAAC;IACH,CAAC;IAED,MAAM,IAAA,6BAAc,EAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;AACrD,CAAC","sourcesContent":["/* Django wizard using posthog-agent with PostHog MCP */\nimport type { WizardOptions } from '../utils/types';\nimport type { FrameworkConfig } from '../lib/framework-config';\nimport { enableDebugLogs } from '../utils/debug';\nimport { runAgentWizard } from '../lib/agent-runner';\nimport { Integration } from '../lib/constants';\nimport clack from '../utils/clack';\nimport chalk from 'chalk';\nimport * as semver from 'semver';\nimport {\n getDjangoVersion,\n getDjangoProjectType,\n getDjangoProjectTypeName,\n getDjangoVersionBucket,\n DjangoProjectType,\n findDjangoSettingsFile,\n} from './utils';\n\n/**\n * Django framework configuration for the universal agent runner\n */\nconst MINIMUM_DJANGO_VERSION = '3.0.0';\n\nconst DJANGO_AGENT_CONFIG: FrameworkConfig = {\n metadata: {\n name: 'Django',\n integration: Integration.django,\n docsUrl: 'https://posthog.com/docs/libraries/django',\n unsupportedVersionDocsUrl: 'https://posthog.com/docs/libraries/python',\n gatherContext: async (options: WizardOptions) => {\n const projectType = await getDjangoProjectType(options);\n const settingsFile = await findDjangoSettingsFile(options);\n return { projectType, settingsFile };\n },\n },\n\n detection: {\n packageName: 'django',\n packageDisplayName: 'Django',\n usesPackageJson: false,\n getVersion: (_packageJson: any) => {\n // For Django, we don't use package.json. Version is extracted separately\n // from requirements.txt or pyproject.toml in the wizard entry point\n return undefined;\n },\n getVersionBucket: getDjangoVersionBucket,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_API_KEY: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context: any) => {\n const projectType = context.projectType as DjangoProjectType;\n return {\n projectType: projectType || 'unknown',\n };\n },\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a Python/Django project. Look for requirements.txt, pyproject.toml, setup.py, Pipfile, or manage.py to confirm.',\n packageInstallation:\n 'Use pip, poetry, or pipenv based on existing config files (requirements.txt, pyproject.toml, Pipfile). Do not pin the posthog version - just add \"posthog\" without version constraints.',\n getAdditionalContextLines: (context: any) => {\n const projectType = context.projectType as DjangoProjectType;\n const projectTypeName = projectType\n ? getDjangoProjectTypeName(projectType)\n : 'unknown';\n\n // Map project type to framework ID for MCP docs resource\n const frameworkIdMap: Record<DjangoProjectType, string> = {\n [DjangoProjectType.STANDARD]: 'django',\n [DjangoProjectType.DRF]: 'django',\n [DjangoProjectType.WAGTAIL]: 'django',\n [DjangoProjectType.CHANNELS]: 'django',\n };\n\n const frameworkId = projectType ? frameworkIdMap[projectType] : 'django';\n\n const lines = [\n `Project type: ${projectTypeName}`,\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n ];\n\n if (context.settingsFile) {\n lines.push(`Settings file: ${context.settingsFile}`);\n }\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context: any) => {\n const projectType = context.projectType as DjangoProjectType;\n const projectTypeName = projectType\n ? getDjangoProjectTypeName(projectType)\n : 'Django';\n return [\n `Analyzed your ${projectTypeName} project structure`,\n `Installed the PostHog Python package`,\n `Configured PostHog in your Django settings`,\n `Added PostHog middleware for automatic event tracking`,\n ];\n },\n getOutroNextSteps: () => [\n 'Start your Django development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n 'Use identify_context() within new_context() to associate events with users',\n ],\n },\n};\n\n/**\n * Django wizard powered by the universal agent runner.\n */\nexport async function runDjangoWizardAgent(\n options: WizardOptions,\n): Promise<void> {\n if (options.debug) {\n enableDebugLogs();\n }\n\n // Check Django version - agent wizard requires >= 3.0.0\n const djangoVersion = await getDjangoVersion(options);\n\n if (djangoVersion) {\n const coercedVersion = semver.coerce(djangoVersion);\n if (coercedVersion && semver.lt(coercedVersion, MINIMUM_DJANGO_VERSION)) {\n const docsUrl =\n DJANGO_AGENT_CONFIG.metadata.unsupportedVersionDocsUrl ??\n DJANGO_AGENT_CONFIG.metadata.docsUrl;\n\n clack.log.warn(\n `Sorry: the wizard can't help you with Django ${djangoVersion}. Upgrade to Django ${MINIMUM_DJANGO_VERSION} or later, or check out the manual setup guide.`,\n );\n clack.log.info(`Setup Django manually: ${chalk.cyan(docsUrl)}`);\n clack.outro('PostHog wizard will see you next time!');\n return;\n }\n }\n\n await runAgentWizard(DJANGO_AGENT_CONFIG, options);\n}\n"]}
@@ -0,0 +1,31 @@
1
+ import type { WizardOptions } from '../utils/types';
2
+ export declare enum DjangoProjectType {
3
+ STANDARD = "standard",// Traditional Django project (django-admin startproject)
4
+ DRF = "drf",// Django REST Framework API
5
+ WAGTAIL = "wagtail",// Wagtail CMS
6
+ CHANNELS = "channels"
7
+ }
8
+ /**
9
+ * Get Django version bucket for analytics
10
+ */
11
+ export declare function getDjangoVersionBucket(version: string | undefined): string;
12
+ /**
13
+ * Extract Django version from requirements files or pyproject.toml
14
+ */
15
+ export declare function getDjangoVersion(options: Pick<WizardOptions, 'installDir'>): Promise<string | undefined>;
16
+ /**
17
+ * Detect Django project type
18
+ */
19
+ export declare function getDjangoProjectType(options: WizardOptions): Promise<DjangoProjectType>;
20
+ /**
21
+ * Get human-readable name for Django project type
22
+ */
23
+ export declare function getDjangoProjectTypeName(projectType: DjangoProjectType): string;
24
+ /**
25
+ * Find the main Django settings file
26
+ */
27
+ export declare function findDjangoSettingsFile(options: Pick<WizardOptions, 'installDir'>): Promise<string | undefined>;
28
+ /**
29
+ * Find the main Django urls.py file
30
+ */
31
+ export declare function findDjangoUrlsFile(options: Pick<WizardOptions, 'installDir'>): Promise<string | undefined>;
@@ -0,0 +1,325 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.DjangoProjectType = void 0;
40
+ exports.getDjangoVersionBucket = getDjangoVersionBucket;
41
+ exports.getDjangoVersion = getDjangoVersion;
42
+ exports.getDjangoProjectType = getDjangoProjectType;
43
+ exports.getDjangoProjectTypeName = getDjangoProjectTypeName;
44
+ exports.findDjangoSettingsFile = findDjangoSettingsFile;
45
+ exports.findDjangoUrlsFile = findDjangoUrlsFile;
46
+ const semver_1 = require("semver");
47
+ const fast_glob_1 = __importDefault(require("fast-glob"));
48
+ const clack_1 = __importDefault(require("../utils/clack"));
49
+ const fs = __importStar(require("node:fs"));
50
+ const path = __importStar(require("node:path"));
51
+ var DjangoProjectType;
52
+ (function (DjangoProjectType) {
53
+ DjangoProjectType["STANDARD"] = "standard";
54
+ DjangoProjectType["DRF"] = "drf";
55
+ DjangoProjectType["WAGTAIL"] = "wagtail";
56
+ DjangoProjectType["CHANNELS"] = "channels";
57
+ })(DjangoProjectType || (exports.DjangoProjectType = DjangoProjectType = {}));
58
+ const IGNORE_PATTERNS = [
59
+ '**/node_modules/**',
60
+ '**/dist/**',
61
+ '**/build/**',
62
+ '**/venv/**',
63
+ '**/.venv/**',
64
+ '**/env/**',
65
+ '**/.env/**',
66
+ '**/__pycache__/**',
67
+ '**/migrations/**',
68
+ ];
69
+ /**
70
+ * Get Django version bucket for analytics
71
+ */
72
+ function getDjangoVersionBucket(version) {
73
+ if (!version) {
74
+ return 'none';
75
+ }
76
+ try {
77
+ const minVer = (0, semver_1.minVersion)(version);
78
+ if (!minVer) {
79
+ return 'invalid';
80
+ }
81
+ const majorVersion = (0, semver_1.major)(minVer);
82
+ if (majorVersion >= 3) {
83
+ return `${majorVersion}.x`;
84
+ }
85
+ return `<3.0.0`;
86
+ }
87
+ catch {
88
+ return 'unknown';
89
+ }
90
+ }
91
+ /**
92
+ * Extract Django version from requirements files or pyproject.toml
93
+ */
94
+ async function getDjangoVersion(options) {
95
+ const { installDir } = options;
96
+ // Check requirements files
97
+ const requirementsFiles = await (0, fast_glob_1.default)(['**/requirements*.txt', '**/pyproject.toml', '**/setup.py', '**/Pipfile'], {
98
+ cwd: installDir,
99
+ ignore: IGNORE_PATTERNS,
100
+ });
101
+ for (const reqFile of requirementsFiles) {
102
+ try {
103
+ const content = fs.readFileSync(path.join(installDir, reqFile), 'utf-8');
104
+ // Try to extract version from requirements.txt format (Django==4.2.0 or Django>=4.0)
105
+ const requirementsMatch = content.match(/[Dd]jango[=<>~!]+([0-9]+\.[0-9]+(?:\.[0-9]+)?)/);
106
+ if (requirementsMatch) {
107
+ return requirementsMatch[1];
108
+ }
109
+ // Try to extract from pyproject.toml format
110
+ const pyprojectMatch = content.match(/[Dd]jango["\s]*[=<>~!]+\s*["']?([0-9]+\.[0-9]+(?:\.[0-9]+)?)/);
111
+ if (pyprojectMatch) {
112
+ return pyprojectMatch[1];
113
+ }
114
+ }
115
+ catch {
116
+ // Skip files that can't be read
117
+ continue;
118
+ }
119
+ }
120
+ return undefined;
121
+ }
122
+ /**
123
+ * Check if Django REST Framework is installed
124
+ */
125
+ async function hasDRF({ installDir, }) {
126
+ const requirementsFiles = await (0, fast_glob_1.default)(['**/requirements*.txt', '**/pyproject.toml', '**/Pipfile'], {
127
+ cwd: installDir,
128
+ ignore: IGNORE_PATTERNS,
129
+ });
130
+ for (const reqFile of requirementsFiles) {
131
+ try {
132
+ const content = fs.readFileSync(path.join(installDir, reqFile), 'utf-8');
133
+ if (content.includes('djangorestframework')) {
134
+ return true;
135
+ }
136
+ }
137
+ catch {
138
+ continue;
139
+ }
140
+ }
141
+ // Also check INSTALLED_APPS in settings
142
+ const settingsFiles = await (0, fast_glob_1.default)('**/settings.py', {
143
+ cwd: installDir,
144
+ ignore: IGNORE_PATTERNS,
145
+ });
146
+ for (const settingsFile of settingsFiles) {
147
+ try {
148
+ const content = fs.readFileSync(path.join(installDir, settingsFile), 'utf-8');
149
+ if (content.includes('rest_framework')) {
150
+ return true;
151
+ }
152
+ }
153
+ catch {
154
+ continue;
155
+ }
156
+ }
157
+ return false;
158
+ }
159
+ /**
160
+ * Check if Wagtail is installed
161
+ */
162
+ async function hasWagtail({ installDir, }) {
163
+ const requirementsFiles = await (0, fast_glob_1.default)(['**/requirements*.txt', '**/pyproject.toml', '**/Pipfile'], {
164
+ cwd: installDir,
165
+ ignore: IGNORE_PATTERNS,
166
+ });
167
+ for (const reqFile of requirementsFiles) {
168
+ try {
169
+ const content = fs.readFileSync(path.join(installDir, reqFile), 'utf-8');
170
+ if (content.includes('wagtail')) {
171
+ return true;
172
+ }
173
+ }
174
+ catch {
175
+ continue;
176
+ }
177
+ }
178
+ return false;
179
+ }
180
+ /**
181
+ * Check if Django Channels is installed
182
+ */
183
+ async function hasChannels({ installDir, }) {
184
+ const requirementsFiles = await (0, fast_glob_1.default)(['**/requirements*.txt', '**/pyproject.toml', '**/Pipfile'], {
185
+ cwd: installDir,
186
+ ignore: IGNORE_PATTERNS,
187
+ });
188
+ for (const reqFile of requirementsFiles) {
189
+ try {
190
+ const content = fs.readFileSync(path.join(installDir, reqFile), 'utf-8');
191
+ if (content.includes('channels')) {
192
+ return true;
193
+ }
194
+ }
195
+ catch {
196
+ continue;
197
+ }
198
+ }
199
+ return false;
200
+ }
201
+ /**
202
+ * Detect Django project type
203
+ */
204
+ async function getDjangoProjectType(options) {
205
+ const { installDir } = options;
206
+ // Check for Wagtail first (CMS)
207
+ if (await hasWagtail({ installDir })) {
208
+ clack_1.default.log.info('Detected Django with Wagtail CMS');
209
+ return DjangoProjectType.WAGTAIL;
210
+ }
211
+ // Check for Django REST Framework
212
+ if (await hasDRF({ installDir })) {
213
+ clack_1.default.log.info('Detected Django REST Framework project');
214
+ return DjangoProjectType.DRF;
215
+ }
216
+ // Check for Django Channels
217
+ if (await hasChannels({ installDir })) {
218
+ clack_1.default.log.info('Detected Django Channels project');
219
+ return DjangoProjectType.CHANNELS;
220
+ }
221
+ // Default to standard Django
222
+ clack_1.default.log.info('Detected standard Django project');
223
+ return DjangoProjectType.STANDARD;
224
+ }
225
+ /**
226
+ * Get human-readable name for Django project type
227
+ */
228
+ function getDjangoProjectTypeName(projectType) {
229
+ switch (projectType) {
230
+ case DjangoProjectType.STANDARD:
231
+ return 'Standard Django';
232
+ case DjangoProjectType.DRF:
233
+ return 'Django REST Framework';
234
+ case DjangoProjectType.WAGTAIL:
235
+ return 'Wagtail CMS';
236
+ case DjangoProjectType.CHANNELS:
237
+ return 'Django Channels';
238
+ }
239
+ }
240
+ /**
241
+ * Find the main Django settings file
242
+ */
243
+ async function findDjangoSettingsFile(options) {
244
+ const { installDir } = options;
245
+ // Look for settings.py files
246
+ const settingsFiles = await (0, fast_glob_1.default)('**/settings.py', {
247
+ cwd: installDir,
248
+ ignore: IGNORE_PATTERNS,
249
+ });
250
+ if (settingsFiles.length === 0) {
251
+ // Try settings/__init__.py for split settings
252
+ const splitSettingsFiles = await (0, fast_glob_1.default)('**/settings/__init__.py', {
253
+ cwd: installDir,
254
+ ignore: IGNORE_PATTERNS,
255
+ });
256
+ if (splitSettingsFiles.length > 0) {
257
+ return splitSettingsFiles[0];
258
+ }
259
+ return undefined;
260
+ }
261
+ // If multiple settings files, prefer the one next to manage.py or in root
262
+ if (settingsFiles.length === 1) {
263
+ return settingsFiles[0];
264
+ }
265
+ // Try to find the main settings file by looking for ROOT_URLCONF
266
+ for (const settingsFile of settingsFiles) {
267
+ try {
268
+ const content = fs.readFileSync(path.join(installDir, settingsFile), 'utf-8');
269
+ if (content.includes('ROOT_URLCONF')) {
270
+ return settingsFile;
271
+ }
272
+ }
273
+ catch {
274
+ continue;
275
+ }
276
+ }
277
+ // Default to first found
278
+ return settingsFiles[0];
279
+ }
280
+ /**
281
+ * Find the main Django urls.py file
282
+ */
283
+ async function findDjangoUrlsFile(options) {
284
+ const { installDir } = options;
285
+ // First, try to find the root urls.py referenced in settings
286
+ const settingsFile = await findDjangoSettingsFile(options);
287
+ if (settingsFile) {
288
+ try {
289
+ const settingsContent = fs.readFileSync(path.join(installDir, settingsFile), 'utf-8');
290
+ const urlconfMatch = settingsContent.match(/ROOT_URLCONF\s*=\s*['"]([^'"]+)['"]/);
291
+ if (urlconfMatch) {
292
+ const urlconfPath = urlconfMatch[1].replace(/\./g, '/') + '.py';
293
+ const fullPath = path.join(installDir, urlconfPath);
294
+ if (fs.existsSync(fullPath)) {
295
+ return urlconfPath;
296
+ }
297
+ }
298
+ }
299
+ catch {
300
+ // Fall through to glob search
301
+ }
302
+ }
303
+ // Fallback to glob search
304
+ const urlsFiles = await (0, fast_glob_1.default)('**/urls.py', {
305
+ cwd: installDir,
306
+ ignore: [...IGNORE_PATTERNS, '**/admin/**'],
307
+ });
308
+ if (urlsFiles.length === 0) {
309
+ return undefined;
310
+ }
311
+ // Prefer urls.py files that contain urlpatterns
312
+ for (const urlsFile of urlsFiles) {
313
+ try {
314
+ const content = fs.readFileSync(path.join(installDir, urlsFile), 'utf-8');
315
+ if (content.includes('urlpatterns')) {
316
+ return urlsFile;
317
+ }
318
+ }
319
+ catch {
320
+ continue;
321
+ }
322
+ }
323
+ return urlsFiles[0];
324
+ }
325
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/django/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { major, minVersion } from 'semver';\nimport fg from 'fast-glob';\nimport clack from '../utils/clack';\nimport type { WizardOptions } from '../utils/types';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nexport enum DjangoProjectType {\n STANDARD = 'standard', // Traditional Django project (django-admin startproject)\n DRF = 'drf', // Django REST Framework API\n WAGTAIL = 'wagtail', // Wagtail CMS\n CHANNELS = 'channels', // Django Channels (async/websockets)\n}\n\nconst IGNORE_PATTERNS = [\n '**/node_modules/**',\n '**/dist/**',\n '**/build/**',\n '**/venv/**',\n '**/.venv/**',\n '**/env/**',\n '**/.env/**',\n '**/__pycache__/**',\n '**/migrations/**',\n];\n\n/**\n * Get Django version bucket for analytics\n */\nexport function getDjangoVersionBucket(version: string | undefined): string {\n if (!version) {\n return 'none';\n }\n\n try {\n const minVer = minVersion(version);\n if (!minVer) {\n return 'invalid';\n }\n const majorVersion = major(minVer);\n if (majorVersion >= 3) {\n return `${majorVersion}.x`;\n }\n return `<3.0.0`;\n } catch {\n return 'unknown';\n }\n}\n\n/**\n * Extract Django version from requirements files or pyproject.toml\n */\nexport async function getDjangoVersion(\n options: Pick<WizardOptions, 'installDir'>,\n): Promise<string | undefined> {\n const { installDir } = options;\n\n // Check requirements files\n const requirementsFiles = await fg(\n ['**/requirements*.txt', '**/pyproject.toml', '**/setup.py', '**/Pipfile'],\n {\n cwd: installDir,\n ignore: IGNORE_PATTERNS,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n try {\n const content = fs.readFileSync(path.join(installDir, reqFile), 'utf-8');\n\n // Try to extract version from requirements.txt format (Django==4.2.0 or Django>=4.0)\n const requirementsMatch = content.match(\n /[Dd]jango[=<>~!]+([0-9]+\\.[0-9]+(?:\\.[0-9]+)?)/,\n );\n if (requirementsMatch) {\n return requirementsMatch[1];\n }\n\n // Try to extract from pyproject.toml format\n const pyprojectMatch = content.match(\n /[Dd]jango[\"\\s]*[=<>~!]+\\s*[\"']?([0-9]+\\.[0-9]+(?:\\.[0-9]+)?)/,\n );\n if (pyprojectMatch) {\n return pyprojectMatch[1];\n }\n } catch {\n // Skip files that can't be read\n continue;\n }\n }\n\n return undefined;\n}\n\n/**\n * Check if Django REST Framework is installed\n */\nasync function hasDRF({\n installDir,\n}: Pick<WizardOptions, 'installDir'>): Promise<boolean> {\n const requirementsFiles = await fg(\n ['**/requirements*.txt', '**/pyproject.toml', '**/Pipfile'],\n {\n cwd: installDir,\n ignore: IGNORE_PATTERNS,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n try {\n const content = fs.readFileSync(path.join(installDir, reqFile), 'utf-8');\n if (content.includes('djangorestframework')) {\n return true;\n }\n } catch {\n continue;\n }\n }\n\n // Also check INSTALLED_APPS in settings\n const settingsFiles = await fg('**/settings.py', {\n cwd: installDir,\n ignore: IGNORE_PATTERNS,\n });\n\n for (const settingsFile of settingsFiles) {\n try {\n const content = fs.readFileSync(\n path.join(installDir, settingsFile),\n 'utf-8',\n );\n if (content.includes('rest_framework')) {\n return true;\n }\n } catch {\n continue;\n }\n }\n\n return false;\n}\n\n/**\n * Check if Wagtail is installed\n */\nasync function hasWagtail({\n installDir,\n}: Pick<WizardOptions, 'installDir'>): Promise<boolean> {\n const requirementsFiles = await fg(\n ['**/requirements*.txt', '**/pyproject.toml', '**/Pipfile'],\n {\n cwd: installDir,\n ignore: IGNORE_PATTERNS,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n try {\n const content = fs.readFileSync(path.join(installDir, reqFile), 'utf-8');\n if (content.includes('wagtail')) {\n return true;\n }\n } catch {\n continue;\n }\n }\n\n return false;\n}\n\n/**\n * Check if Django Channels is installed\n */\nasync function hasChannels({\n installDir,\n}: Pick<WizardOptions, 'installDir'>): Promise<boolean> {\n const requirementsFiles = await fg(\n ['**/requirements*.txt', '**/pyproject.toml', '**/Pipfile'],\n {\n cwd: installDir,\n ignore: IGNORE_PATTERNS,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n try {\n const content = fs.readFileSync(path.join(installDir, reqFile), 'utf-8');\n if (content.includes('channels')) {\n return true;\n }\n } catch {\n continue;\n }\n }\n\n return false;\n}\n\n/**\n * Detect Django project type\n */\nexport async function getDjangoProjectType(\n options: WizardOptions,\n): Promise<DjangoProjectType> {\n const { installDir } = options;\n\n // Check for Wagtail first (CMS)\n if (await hasWagtail({ installDir })) {\n clack.log.info('Detected Django with Wagtail CMS');\n return DjangoProjectType.WAGTAIL;\n }\n\n // Check for Django REST Framework\n if (await hasDRF({ installDir })) {\n clack.log.info('Detected Django REST Framework project');\n return DjangoProjectType.DRF;\n }\n\n // Check for Django Channels\n if (await hasChannels({ installDir })) {\n clack.log.info('Detected Django Channels project');\n return DjangoProjectType.CHANNELS;\n }\n\n // Default to standard Django\n clack.log.info('Detected standard Django project');\n return DjangoProjectType.STANDARD;\n}\n\n/**\n * Get human-readable name for Django project type\n */\nexport function getDjangoProjectTypeName(\n projectType: DjangoProjectType,\n): string {\n switch (projectType) {\n case DjangoProjectType.STANDARD:\n return 'Standard Django';\n case DjangoProjectType.DRF:\n return 'Django REST Framework';\n case DjangoProjectType.WAGTAIL:\n return 'Wagtail CMS';\n case DjangoProjectType.CHANNELS:\n return 'Django Channels';\n }\n}\n\n/**\n * Find the main Django settings file\n */\nexport async function findDjangoSettingsFile(\n options: Pick<WizardOptions, 'installDir'>,\n): Promise<string | undefined> {\n const { installDir } = options;\n\n // Look for settings.py files\n const settingsFiles = await fg('**/settings.py', {\n cwd: installDir,\n ignore: IGNORE_PATTERNS,\n });\n\n if (settingsFiles.length === 0) {\n // Try settings/__init__.py for split settings\n const splitSettingsFiles = await fg('**/settings/__init__.py', {\n cwd: installDir,\n ignore: IGNORE_PATTERNS,\n });\n\n if (splitSettingsFiles.length > 0) {\n return splitSettingsFiles[0];\n }\n\n return undefined;\n }\n\n // If multiple settings files, prefer the one next to manage.py or in root\n if (settingsFiles.length === 1) {\n return settingsFiles[0];\n }\n\n // Try to find the main settings file by looking for ROOT_URLCONF\n for (const settingsFile of settingsFiles) {\n try {\n const content = fs.readFileSync(\n path.join(installDir, settingsFile),\n 'utf-8',\n );\n if (content.includes('ROOT_URLCONF')) {\n return settingsFile;\n }\n } catch {\n continue;\n }\n }\n\n // Default to first found\n return settingsFiles[0];\n}\n\n/**\n * Find the main Django urls.py file\n */\nexport async function findDjangoUrlsFile(\n options: Pick<WizardOptions, 'installDir'>,\n): Promise<string | undefined> {\n const { installDir } = options;\n\n // First, try to find the root urls.py referenced in settings\n const settingsFile = await findDjangoSettingsFile(options);\n if (settingsFile) {\n try {\n const settingsContent = fs.readFileSync(\n path.join(installDir, settingsFile),\n 'utf-8',\n );\n const urlconfMatch = settingsContent.match(\n /ROOT_URLCONF\\s*=\\s*['\"]([^'\"]+)['\"]/,\n );\n if (urlconfMatch) {\n const urlconfPath = urlconfMatch[1].replace(/\\./g, '/') + '.py';\n const fullPath = path.join(installDir, urlconfPath);\n if (fs.existsSync(fullPath)) {\n return urlconfPath;\n }\n }\n } catch {\n // Fall through to glob search\n }\n }\n\n // Fallback to glob search\n const urlsFiles = await fg('**/urls.py', {\n cwd: installDir,\n ignore: [...IGNORE_PATTERNS, '**/admin/**'],\n });\n\n if (urlsFiles.length === 0) {\n return undefined;\n }\n\n // Prefer urls.py files that contain urlpatterns\n for (const urlsFile of urlsFiles) {\n try {\n const content = fs.readFileSync(path.join(installDir, urlsFile), 'utf-8');\n if (content.includes('urlpatterns')) {\n return urlsFile;\n }\n } catch {\n continue;\n }\n }\n\n return urlsFiles[0];\n}\n"]}
@@ -22,7 +22,11 @@ export declare enum AgentErrorType {
22
22
  /** Agent could not access the PostHog MCP server */
23
23
  MCP_MISSING = "WIZARD_MCP_MISSING",
24
24
  /** Agent could not access the setup resource */
25
- RESOURCE_MISSING = "WIZARD_RESOURCE_MISSING"
25
+ RESOURCE_MISSING = "WIZARD_RESOURCE_MISSING",
26
+ /** API rate limit exceeded */
27
+ RATE_LIMIT = "WIZARD_RATE_LIMIT",
28
+ /** Generic API error */
29
+ API_ERROR = "WIZARD_API_ERROR"
26
30
  }
27
31
  export type AgentConfig = {
28
32
  workingDirectory: string;
@@ -44,6 +48,7 @@ type AgentRunConfig = {
44
48
  * - Build/typecheck/lint commands for verification
45
49
  * - Piping to tail/head for output limiting is allowed
46
50
  * - Stderr redirection (2>&1) is allowed
51
+ * - PostHog skill installation commands from MCP
47
52
  */
48
53
  export declare function wizardCanUseTool(toolName: string, input: Record<string, unknown>): {
49
54
  behavior: 'allow';
@@ -69,5 +74,6 @@ export declare function runAgent(agentConfig: AgentRunConfig, prompt: string, op
69
74
  errorMessage?: string;
70
75
  }): Promise<{
71
76
  error?: AgentErrorType;
77
+ message?: string;
72
78
  }>;
73
79
  export {};