@posthog/wizard 1.29.0 → 1.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/laravel/laravel-wizard-agent.d.ts +5 -0
- package/dist/src/laravel/laravel-wizard-agent.js +183 -0
- package/dist/src/laravel/laravel-wizard-agent.js.map +1 -0
- package/dist/src/laravel/utils.d.ts +38 -0
- package/dist/src/laravel/utils.js +257 -0
- package/dist/src/laravel/utils.js.map +1 -0
- package/dist/src/lib/agent-interface.d.ts +2 -0
- package/dist/src/lib/agent-interface.js +37 -0
- package/dist/src/lib/agent-interface.js.map +1 -1
- package/dist/src/lib/agent-runner.js +6 -1
- package/dist/src/lib/agent-runner.js.map +1 -1
- package/dist/src/lib/config.d.ts +12 -1
- package/dist/src/lib/config.js +53 -0
- package/dist/src/lib/config.js.map +1 -1
- package/dist/src/lib/constants.d.ts +3 -1
- package/dist/src/lib/constants.js +5 -1
- package/dist/src/lib/constants.js.map +1 -1
- package/dist/src/run.js +6 -0
- package/dist/src/run.js.map +1 -1
- package/dist/src/steps/add-mcp-server-to-clients/__tests__/defaults.test.js +8 -8
- package/dist/src/steps/add-mcp-server-to-clients/__tests__/defaults.test.js.map +1 -1
- package/dist/src/steps/add-mcp-server-to-clients/defaults.js +8 -7
- package/dist/src/steps/add-mcp-server-to-clients/defaults.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,183 @@
|
|
|
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.runLaravelWizardAgent = runLaravelWizardAgent;
|
|
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
|
+
* Laravel framework configuration for the universal agent runner
|
|
49
|
+
*/
|
|
50
|
+
const MINIMUM_LARAVEL_VERSION = '9.0.0';
|
|
51
|
+
const LARAVEL_AGENT_CONFIG = {
|
|
52
|
+
metadata: {
|
|
53
|
+
name: 'Laravel',
|
|
54
|
+
integration: constants_1.Integration.laravel,
|
|
55
|
+
docsUrl: 'https://posthog.com/docs/libraries/php',
|
|
56
|
+
unsupportedVersionDocsUrl: 'https://posthog.com/docs/libraries/php',
|
|
57
|
+
gatherContext: async (options) => {
|
|
58
|
+
const projectType = await (0, utils_1.getLaravelProjectType)(options);
|
|
59
|
+
const serviceProvider = await (0, utils_1.findLaravelServiceProvider)(options);
|
|
60
|
+
const bootstrapFile = (0, utils_1.findLaravelBootstrapFile)(options);
|
|
61
|
+
const laravelStructure = (0, utils_1.detectLaravelStructure)(options);
|
|
62
|
+
return {
|
|
63
|
+
projectType,
|
|
64
|
+
serviceProvider,
|
|
65
|
+
bootstrapFile,
|
|
66
|
+
laravelStructure,
|
|
67
|
+
};
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
detection: {
|
|
71
|
+
packageName: 'laravel/framework',
|
|
72
|
+
packageDisplayName: 'Laravel',
|
|
73
|
+
usesPackageJson: false,
|
|
74
|
+
getVersion: (_packageJson) => {
|
|
75
|
+
// For Laravel, we don't use package.json. Version is extracted separately
|
|
76
|
+
// from composer.json in the wizard entry point
|
|
77
|
+
return undefined;
|
|
78
|
+
},
|
|
79
|
+
getVersionBucket: utils_1.getLaravelVersionBucket,
|
|
80
|
+
},
|
|
81
|
+
environment: {
|
|
82
|
+
uploadToHosting: false,
|
|
83
|
+
getEnvVars: (apiKey, host) => ({
|
|
84
|
+
POSTHOG_API_KEY: apiKey,
|
|
85
|
+
POSTHOG_HOST: host,
|
|
86
|
+
}),
|
|
87
|
+
},
|
|
88
|
+
analytics: {
|
|
89
|
+
getTags: (context) => {
|
|
90
|
+
const projectType = context.projectType;
|
|
91
|
+
return {
|
|
92
|
+
projectType: projectType || 'unknown',
|
|
93
|
+
laravelStructure: context.laravelStructure || 'unknown',
|
|
94
|
+
};
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
prompts: {
|
|
98
|
+
projectTypeDetection: 'This is a PHP/Laravel project. Look for composer.json, artisan CLI, and app/ directory structure to confirm. Check for Laravel-specific packages like laravel/framework.',
|
|
99
|
+
packageInstallation: 'Use Composer to install packages. Run `composer require posthog/posthog-php` without pinning a specific version.',
|
|
100
|
+
getAdditionalContextLines: (context) => {
|
|
101
|
+
const projectType = context.projectType;
|
|
102
|
+
const projectTypeName = projectType
|
|
103
|
+
? (0, utils_1.getLaravelProjectTypeName)(projectType)
|
|
104
|
+
: 'unknown';
|
|
105
|
+
const lines = [
|
|
106
|
+
`Project type: ${projectTypeName}`,
|
|
107
|
+
`Framework docs ID: php (use posthog://docs/frameworks/php for documentation)`,
|
|
108
|
+
`Laravel structure: ${context.laravelStructure} (affects where to add configuration)`,
|
|
109
|
+
];
|
|
110
|
+
if (context.serviceProvider) {
|
|
111
|
+
lines.push(`Service provider: ${context.serviceProvider}`);
|
|
112
|
+
}
|
|
113
|
+
if (context.bootstrapFile) {
|
|
114
|
+
lines.push(`Bootstrap file: ${context.bootstrapFile}`);
|
|
115
|
+
}
|
|
116
|
+
// Add Laravel-specific guidance based on version structure
|
|
117
|
+
if (context.laravelStructure === 'latest') {
|
|
118
|
+
lines.push('Note: Laravel 11+ uses simplified bootstrap/app.php for middleware and providers');
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
lines.push('Note: Use app/Http/Kernel.php for middleware, app/Providers for service providers');
|
|
122
|
+
}
|
|
123
|
+
return lines;
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
ui: {
|
|
127
|
+
successMessage: 'PostHog integration complete',
|
|
128
|
+
estimatedDurationMinutes: 5,
|
|
129
|
+
getOutroChanges: (context) => {
|
|
130
|
+
const projectType = context.projectType;
|
|
131
|
+
const projectTypeName = projectType
|
|
132
|
+
? (0, utils_1.getLaravelProjectTypeName)(projectType)
|
|
133
|
+
: 'Laravel';
|
|
134
|
+
const changes = [
|
|
135
|
+
`Analyzed your ${projectTypeName} project structure`,
|
|
136
|
+
`Installed the PostHog PHP package via Composer`,
|
|
137
|
+
`Configured PostHog in your Laravel application`,
|
|
138
|
+
];
|
|
139
|
+
if (context.laravelStructure === 'latest') {
|
|
140
|
+
changes.push('Added PostHog initialization to bootstrap/app.php');
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
changes.push('Created a PostHog service provider for initialization');
|
|
144
|
+
}
|
|
145
|
+
if (projectType === utils_1.LaravelProjectType.INERTIA) {
|
|
146
|
+
changes.push('Configured PostHog to work with Inertia.js');
|
|
147
|
+
}
|
|
148
|
+
if (projectType === utils_1.LaravelProjectType.LIVEWIRE) {
|
|
149
|
+
changes.push('Configured PostHog to work with Livewire');
|
|
150
|
+
}
|
|
151
|
+
return changes;
|
|
152
|
+
},
|
|
153
|
+
getOutroNextSteps: () => [
|
|
154
|
+
'Start your Laravel development server with `php artisan serve`',
|
|
155
|
+
'Visit your PostHog dashboard to see incoming events',
|
|
156
|
+
'Use PostHog::capture() to track custom events',
|
|
157
|
+
'Use PostHog::identify() to associate events with users',
|
|
158
|
+
],
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* Laravel wizard powered by the universal agent runner.
|
|
163
|
+
*/
|
|
164
|
+
async function runLaravelWizardAgent(options) {
|
|
165
|
+
if (options.debug) {
|
|
166
|
+
(0, debug_1.enableDebugLogs)();
|
|
167
|
+
}
|
|
168
|
+
// Check Laravel version - agent wizard requires >= 9.0.0
|
|
169
|
+
const laravelVersion = (0, utils_1.getLaravelVersion)(options);
|
|
170
|
+
if (laravelVersion) {
|
|
171
|
+
const coercedVersion = semver.coerce(laravelVersion);
|
|
172
|
+
if (coercedVersion && semver.lt(coercedVersion, MINIMUM_LARAVEL_VERSION)) {
|
|
173
|
+
const docsUrl = LARAVEL_AGENT_CONFIG.metadata.unsupportedVersionDocsUrl ??
|
|
174
|
+
LARAVEL_AGENT_CONFIG.metadata.docsUrl;
|
|
175
|
+
clack_1.default.log.warn(`Sorry: the wizard can't help you with Laravel ${laravelVersion}. Upgrade to Laravel ${MINIMUM_LARAVEL_VERSION} or later, or check out the manual setup guide.`);
|
|
176
|
+
clack_1.default.log.info(`Setup Laravel manually: ${chalk_1.default.cyan(docsUrl)}`);
|
|
177
|
+
clack_1.default.outro('PostHog wizard will see you next time!');
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
await (0, agent_runner_1.runAgentWizard)(LARAVEL_AGENT_CONFIG, options);
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=laravel-wizard-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"laravel-wizard-agent.js","sourceRoot":"","sources":["../../../src/laravel/laravel-wizard-agent.ts"],"names":[],"mappings":"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","sourcesContent":["/* Laravel 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 getLaravelVersion,\n getLaravelProjectType,\n getLaravelProjectTypeName,\n getLaravelVersionBucket,\n LaravelProjectType,\n findLaravelServiceProvider,\n findLaravelBootstrapFile,\n detectLaravelStructure,\n} from './utils';\n\n/**\n * Laravel framework configuration for the universal agent runner\n */\nconst MINIMUM_LARAVEL_VERSION = '9.0.0';\n\nconst LARAVEL_AGENT_CONFIG: FrameworkConfig = {\n metadata: {\n name: 'Laravel',\n integration: Integration.laravel,\n docsUrl: 'https://posthog.com/docs/libraries/php',\n unsupportedVersionDocsUrl: 'https://posthog.com/docs/libraries/php',\n gatherContext: async (options: WizardOptions) => {\n const projectType = await getLaravelProjectType(options);\n const serviceProvider = await findLaravelServiceProvider(options);\n const bootstrapFile = findLaravelBootstrapFile(options);\n const laravelStructure = detectLaravelStructure(options);\n\n return {\n projectType,\n serviceProvider,\n bootstrapFile,\n laravelStructure,\n };\n },\n },\n\n detection: {\n packageName: 'laravel/framework',\n packageDisplayName: 'Laravel',\n usesPackageJson: false,\n getVersion: (_packageJson: any) => {\n // For Laravel, we don't use package.json. Version is extracted separately\n // from composer.json in the wizard entry point\n return undefined;\n },\n getVersionBucket: getLaravelVersionBucket,\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 LaravelProjectType;\n return {\n projectType: projectType || 'unknown',\n laravelStructure: context.laravelStructure || 'unknown',\n };\n },\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a PHP/Laravel project. Look for composer.json, artisan CLI, and app/ directory structure to confirm. Check for Laravel-specific packages like laravel/framework.',\n packageInstallation:\n 'Use Composer to install packages. Run `composer require posthog/posthog-php` without pinning a specific version.',\n getAdditionalContextLines: (context: any) => {\n const projectType = context.projectType as LaravelProjectType;\n const projectTypeName = projectType\n ? getLaravelProjectTypeName(projectType)\n : 'unknown';\n\n const lines = [\n `Project type: ${projectTypeName}`,\n `Framework docs ID: php (use posthog://docs/frameworks/php for documentation)`,\n `Laravel structure: ${context.laravelStructure} (affects where to add configuration)`,\n ];\n\n if (context.serviceProvider) {\n lines.push(`Service provider: ${context.serviceProvider}`);\n }\n\n if (context.bootstrapFile) {\n lines.push(`Bootstrap file: ${context.bootstrapFile}`);\n }\n\n // Add Laravel-specific guidance based on version structure\n if (context.laravelStructure === 'latest') {\n lines.push(\n 'Note: Laravel 11+ uses simplified bootstrap/app.php for middleware and providers',\n );\n } else {\n lines.push(\n 'Note: Use app/Http/Kernel.php for middleware, app/Providers for service providers',\n );\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 LaravelProjectType;\n const projectTypeName = projectType\n ? getLaravelProjectTypeName(projectType)\n : 'Laravel';\n\n const changes = [\n `Analyzed your ${projectTypeName} project structure`,\n `Installed the PostHog PHP package via Composer`,\n `Configured PostHog in your Laravel application`,\n ];\n\n if (context.laravelStructure === 'latest') {\n changes.push('Added PostHog initialization to bootstrap/app.php');\n } else {\n changes.push('Created a PostHog service provider for initialization');\n }\n\n if (projectType === LaravelProjectType.INERTIA) {\n changes.push('Configured PostHog to work with Inertia.js');\n }\n\n if (projectType === LaravelProjectType.LIVEWIRE) {\n changes.push('Configured PostHog to work with Livewire');\n }\n\n return changes;\n },\n getOutroNextSteps: () => [\n 'Start your Laravel development server with `php artisan serve`',\n 'Visit your PostHog dashboard to see incoming events',\n 'Use PostHog::capture() to track custom events',\n 'Use PostHog::identify() to associate events with users',\n ],\n },\n};\n\n/**\n * Laravel wizard powered by the universal agent runner.\n */\nexport async function runLaravelWizardAgent(\n options: WizardOptions,\n): Promise<void> {\n if (options.debug) {\n enableDebugLogs();\n }\n\n // Check Laravel version - agent wizard requires >= 9.0.0\n const laravelVersion = getLaravelVersion(options);\n\n if (laravelVersion) {\n const coercedVersion = semver.coerce(laravelVersion);\n if (coercedVersion && semver.lt(coercedVersion, MINIMUM_LARAVEL_VERSION)) {\n const docsUrl =\n LARAVEL_AGENT_CONFIG.metadata.unsupportedVersionDocsUrl ??\n LARAVEL_AGENT_CONFIG.metadata.docsUrl;\n\n clack.log.warn(\n `Sorry: the wizard can't help you with Laravel ${laravelVersion}. Upgrade to Laravel ${MINIMUM_LARAVEL_VERSION} or later, or check out the manual setup guide.`,\n );\n clack.log.info(`Setup Laravel manually: ${chalk.cyan(docsUrl)}`);\n clack.outro('PostHog wizard will see you next time!');\n return;\n }\n }\n\n await runAgentWizard(LARAVEL_AGENT_CONFIG, options);\n}\n"]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { WizardOptions } from '../utils/types';
|
|
2
|
+
export declare enum LaravelProjectType {
|
|
3
|
+
STANDARD = "standard",// Basic Laravel app
|
|
4
|
+
INERTIA = "inertia",// Inertia.js (Vue/React SPA) - may need JS SDK too
|
|
5
|
+
LIVEWIRE = "livewire"
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Get Laravel version bucket for analytics
|
|
9
|
+
*/
|
|
10
|
+
export declare function getLaravelVersionBucket(version: string | undefined): string;
|
|
11
|
+
/**
|
|
12
|
+
* Read and parse composer.json
|
|
13
|
+
*/
|
|
14
|
+
export declare function getComposerJson(options: Pick<WizardOptions, 'installDir'>): Record<string, any> | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* Get Laravel version from composer.json
|
|
17
|
+
*/
|
|
18
|
+
export declare function getLaravelVersion(options: Pick<WizardOptions, 'installDir'>): string | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Get human-readable name for Laravel project type
|
|
21
|
+
*/
|
|
22
|
+
export declare function getLaravelProjectTypeName(projectType: LaravelProjectType): string;
|
|
23
|
+
/**
|
|
24
|
+
* Detect Laravel project type
|
|
25
|
+
*/
|
|
26
|
+
export declare function getLaravelProjectType(options: WizardOptions): Promise<LaravelProjectType>;
|
|
27
|
+
/**
|
|
28
|
+
* Find the main service provider file
|
|
29
|
+
*/
|
|
30
|
+
export declare function findLaravelServiceProvider(options: Pick<WizardOptions, 'installDir'>): Promise<string | undefined>;
|
|
31
|
+
/**
|
|
32
|
+
* Find the bootstrap file (differs between Laravel versions)
|
|
33
|
+
*/
|
|
34
|
+
export declare function findLaravelBootstrapFile(options: Pick<WizardOptions, 'installDir'>): string | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* Detect Laravel version structure for configuration guidance
|
|
37
|
+
*/
|
|
38
|
+
export declare function detectLaravelStructure(options: Pick<WizardOptions, 'installDir'>): 'legacy' | 'modern' | 'latest';
|
|
@@ -0,0 +1,257 @@
|
|
|
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.LaravelProjectType = void 0;
|
|
40
|
+
exports.getLaravelVersionBucket = getLaravelVersionBucket;
|
|
41
|
+
exports.getComposerJson = getComposerJson;
|
|
42
|
+
exports.getLaravelVersion = getLaravelVersion;
|
|
43
|
+
exports.getLaravelProjectTypeName = getLaravelProjectTypeName;
|
|
44
|
+
exports.getLaravelProjectType = getLaravelProjectType;
|
|
45
|
+
exports.findLaravelServiceProvider = findLaravelServiceProvider;
|
|
46
|
+
exports.findLaravelBootstrapFile = findLaravelBootstrapFile;
|
|
47
|
+
exports.detectLaravelStructure = detectLaravelStructure;
|
|
48
|
+
const semver_1 = require("semver");
|
|
49
|
+
const fast_glob_1 = __importDefault(require("fast-glob"));
|
|
50
|
+
const clack_1 = __importDefault(require("../utils/clack"));
|
|
51
|
+
const fs = __importStar(require("node:fs"));
|
|
52
|
+
const path = __importStar(require("node:path"));
|
|
53
|
+
var LaravelProjectType;
|
|
54
|
+
(function (LaravelProjectType) {
|
|
55
|
+
LaravelProjectType["STANDARD"] = "standard";
|
|
56
|
+
LaravelProjectType["INERTIA"] = "inertia";
|
|
57
|
+
LaravelProjectType["LIVEWIRE"] = "livewire";
|
|
58
|
+
})(LaravelProjectType || (exports.LaravelProjectType = LaravelProjectType = {}));
|
|
59
|
+
/**
|
|
60
|
+
* Ignore patterns for Laravel projects
|
|
61
|
+
*/
|
|
62
|
+
const LARAVEL_IGNORE_PATTERNS = [
|
|
63
|
+
'**/node_modules/**',
|
|
64
|
+
'**/vendor/**',
|
|
65
|
+
'**/storage/**',
|
|
66
|
+
'**/bootstrap/cache/**',
|
|
67
|
+
'**/.phpunit.cache/**',
|
|
68
|
+
'**/public/build/**',
|
|
69
|
+
'**/public/hot/**',
|
|
70
|
+
];
|
|
71
|
+
/**
|
|
72
|
+
* Get Laravel version bucket for analytics
|
|
73
|
+
*/
|
|
74
|
+
function getLaravelVersionBucket(version) {
|
|
75
|
+
if (!version) {
|
|
76
|
+
return 'none';
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
const minVer = (0, semver_1.minVersion)(version);
|
|
80
|
+
if (!minVer) {
|
|
81
|
+
return 'invalid';
|
|
82
|
+
}
|
|
83
|
+
const majorVersion = (0, semver_1.major)(minVer);
|
|
84
|
+
if (majorVersion >= 9) {
|
|
85
|
+
return `${majorVersion}.x`;
|
|
86
|
+
}
|
|
87
|
+
return '<9.0.0';
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return 'unknown';
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Read and parse composer.json
|
|
95
|
+
*/
|
|
96
|
+
function getComposerJson(options) {
|
|
97
|
+
const { installDir } = options;
|
|
98
|
+
const composerPath = path.join(installDir, 'composer.json');
|
|
99
|
+
try {
|
|
100
|
+
const content = fs.readFileSync(composerPath, 'utf-8');
|
|
101
|
+
return JSON.parse(content);
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Check if a package is installed (present in composer.json)
|
|
109
|
+
*/
|
|
110
|
+
function hasComposerPackage(packageName, options) {
|
|
111
|
+
const composer = getComposerJson(options);
|
|
112
|
+
if (!composer)
|
|
113
|
+
return false;
|
|
114
|
+
return !!(composer.require?.[packageName] || composer['require-dev']?.[packageName]);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Extract version for a package from composer.json
|
|
118
|
+
*/
|
|
119
|
+
function getComposerPackageVersion(packageName, options) {
|
|
120
|
+
const composer = getComposerJson(options);
|
|
121
|
+
if (!composer)
|
|
122
|
+
return undefined;
|
|
123
|
+
const version = composer.require?.[packageName] || composer['require-dev']?.[packageName];
|
|
124
|
+
if (version) {
|
|
125
|
+
// Clean version string (remove ^, ~, >=, etc.)
|
|
126
|
+
return version.replace(/^[\^~>=<]+/, '');
|
|
127
|
+
}
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Check if a pattern exists in PHP source files
|
|
132
|
+
*/
|
|
133
|
+
async function hasLaravelCodePattern(pattern, options, filePatterns = ['**/*.php']) {
|
|
134
|
+
const { installDir } = options;
|
|
135
|
+
const phpFiles = await (0, fast_glob_1.default)(filePatterns, {
|
|
136
|
+
cwd: installDir,
|
|
137
|
+
ignore: LARAVEL_IGNORE_PATTERNS,
|
|
138
|
+
});
|
|
139
|
+
const searchPattern = typeof pattern === 'string' ? new RegExp(pattern) : pattern;
|
|
140
|
+
for (const phpFile of phpFiles) {
|
|
141
|
+
try {
|
|
142
|
+
const content = fs.readFileSync(path.join(installDir, phpFile), 'utf-8');
|
|
143
|
+
if (searchPattern.test(content))
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Get Laravel version from composer.json
|
|
154
|
+
*/
|
|
155
|
+
function getLaravelVersion(options) {
|
|
156
|
+
return getComposerPackageVersion('laravel/framework', options);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Get human-readable name for Laravel project type
|
|
160
|
+
*/
|
|
161
|
+
function getLaravelProjectTypeName(projectType) {
|
|
162
|
+
switch (projectType) {
|
|
163
|
+
case LaravelProjectType.STANDARD:
|
|
164
|
+
return 'Standard Laravel';
|
|
165
|
+
case LaravelProjectType.INERTIA:
|
|
166
|
+
return 'Laravel with Inertia.js';
|
|
167
|
+
case LaravelProjectType.LIVEWIRE:
|
|
168
|
+
return 'Laravel with Livewire';
|
|
169
|
+
default:
|
|
170
|
+
return 'Laravel';
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Check for Inertia.js
|
|
175
|
+
*/
|
|
176
|
+
async function hasInertia(options) {
|
|
177
|
+
return (hasComposerPackage('inertiajs/inertia-laravel', options) ||
|
|
178
|
+
(await hasLaravelCodePattern(/Inertia::render|inertia\(/, options)));
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Check for Livewire
|
|
182
|
+
*/
|
|
183
|
+
async function hasLivewire(options) {
|
|
184
|
+
return (hasComposerPackage('livewire/livewire', options) ||
|
|
185
|
+
(await hasLaravelCodePattern(/extends\s+Component|@livewire/, options)));
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Detect Laravel project type
|
|
189
|
+
*/
|
|
190
|
+
async function getLaravelProjectType(options) {
|
|
191
|
+
// Check for SPA/Reactive frameworks (important to detect - affects SDK needs)
|
|
192
|
+
if (await hasInertia(options)) {
|
|
193
|
+
clack_1.default.log.info('Detected Laravel with Inertia.js');
|
|
194
|
+
return LaravelProjectType.INERTIA;
|
|
195
|
+
}
|
|
196
|
+
if (await hasLivewire(options)) {
|
|
197
|
+
clack_1.default.log.info('Detected Laravel with Livewire');
|
|
198
|
+
return LaravelProjectType.LIVEWIRE;
|
|
199
|
+
}
|
|
200
|
+
// Default to standard
|
|
201
|
+
clack_1.default.log.info('Detected standard Laravel project');
|
|
202
|
+
return LaravelProjectType.STANDARD;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Find the main service provider file
|
|
206
|
+
*/
|
|
207
|
+
async function findLaravelServiceProvider(options) {
|
|
208
|
+
const { installDir } = options;
|
|
209
|
+
// Look for AppServiceProvider first (most common place for setup)
|
|
210
|
+
const appServiceProvider = path.join(installDir, 'app/Providers/AppServiceProvider.php');
|
|
211
|
+
if (fs.existsSync(appServiceProvider)) {
|
|
212
|
+
return 'app/Providers/AppServiceProvider.php';
|
|
213
|
+
}
|
|
214
|
+
// Fall back to searching for any service provider
|
|
215
|
+
const providers = await (0, fast_glob_1.default)(['**/app/Providers/*ServiceProvider.php'], {
|
|
216
|
+
cwd: installDir,
|
|
217
|
+
ignore: LARAVEL_IGNORE_PATTERNS,
|
|
218
|
+
});
|
|
219
|
+
return providers[0];
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Find the bootstrap file (differs between Laravel versions)
|
|
223
|
+
*/
|
|
224
|
+
function findLaravelBootstrapFile(options) {
|
|
225
|
+
const { installDir } = options;
|
|
226
|
+
// Laravel 11+ uses bootstrap/app.php with new structure
|
|
227
|
+
const bootstrapApp = path.join(installDir, 'bootstrap/app.php');
|
|
228
|
+
if (fs.existsSync(bootstrapApp)) {
|
|
229
|
+
return 'bootstrap/app.php';
|
|
230
|
+
}
|
|
231
|
+
// Older Laravel uses app/Http/Kernel.php
|
|
232
|
+
const httpKernel = path.join(installDir, 'app/Http/Kernel.php');
|
|
233
|
+
if (fs.existsSync(httpKernel)) {
|
|
234
|
+
return 'app/Http/Kernel.php';
|
|
235
|
+
}
|
|
236
|
+
return undefined;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Detect Laravel version structure for configuration guidance
|
|
240
|
+
*/
|
|
241
|
+
function detectLaravelStructure(options) {
|
|
242
|
+
const version = getLaravelVersion(options);
|
|
243
|
+
if (!version)
|
|
244
|
+
return 'modern';
|
|
245
|
+
try {
|
|
246
|
+
const majorVersion = parseInt(version.split('.')[0], 10);
|
|
247
|
+
if (majorVersion >= 11)
|
|
248
|
+
return 'latest'; // Laravel 11+ (new structure)
|
|
249
|
+
if (majorVersion >= 9)
|
|
250
|
+
return 'modern'; // Laravel 9-10
|
|
251
|
+
return 'legacy'; // Laravel 8 and below
|
|
252
|
+
}
|
|
253
|
+
catch {
|
|
254
|
+
return 'modern';
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/laravel/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 LaravelProjectType {\n STANDARD = 'standard', // Basic Laravel app\n INERTIA = 'inertia', // Inertia.js (Vue/React SPA) - may need JS SDK too\n LIVEWIRE = 'livewire', // Livewire (reactive components, includes Filament)\n}\n\n/**\n * Ignore patterns for Laravel projects\n */\nconst LARAVEL_IGNORE_PATTERNS = [\n '**/node_modules/**',\n '**/vendor/**',\n '**/storage/**',\n '**/bootstrap/cache/**',\n '**/.phpunit.cache/**',\n '**/public/build/**',\n '**/public/hot/**',\n];\n\n/**\n * Get Laravel version bucket for analytics\n */\nexport function getLaravelVersionBucket(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 >= 9) {\n return `${majorVersion}.x`;\n }\n return '<9.0.0';\n } catch {\n return 'unknown';\n }\n}\n\n/**\n * Read and parse composer.json\n */\nexport function getComposerJson(\n options: Pick<WizardOptions, 'installDir'>,\n): Record<string, any> | undefined {\n const { installDir } = options;\n\n const composerPath = path.join(installDir, 'composer.json');\n try {\n const content = fs.readFileSync(composerPath, 'utf-8');\n return JSON.parse(content);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Check if a package is installed (present in composer.json)\n */\nfunction hasComposerPackage(\n packageName: string,\n options: Pick<WizardOptions, 'installDir'>,\n): boolean {\n const composer = getComposerJson(options);\n if (!composer) return false;\n\n return !!(\n composer.require?.[packageName] || composer['require-dev']?.[packageName]\n );\n}\n\n/**\n * Extract version for a package from composer.json\n */\nfunction getComposerPackageVersion(\n packageName: string,\n options: Pick<WizardOptions, 'installDir'>,\n): string | undefined {\n const composer = getComposerJson(options);\n if (!composer) return undefined;\n\n const version =\n composer.require?.[packageName] || composer['require-dev']?.[packageName];\n if (version) {\n // Clean version string (remove ^, ~, >=, etc.)\n return version.replace(/^[\\^~>=<]+/, '');\n }\n\n return undefined;\n}\n\n/**\n * Check if a pattern exists in PHP source files\n */\nasync function hasLaravelCodePattern(\n pattern: RegExp | string,\n options: Pick<WizardOptions, 'installDir'>,\n filePatterns: string[] = ['**/*.php'],\n): Promise<boolean> {\n const { installDir } = options;\n\n const phpFiles = await fg(filePatterns, {\n cwd: installDir,\n ignore: LARAVEL_IGNORE_PATTERNS,\n });\n\n const searchPattern =\n typeof pattern === 'string' ? new RegExp(pattern) : pattern;\n\n for (const phpFile of phpFiles) {\n try {\n const content = fs.readFileSync(path.join(installDir, phpFile), 'utf-8');\n if (searchPattern.test(content)) return true;\n } catch {\n continue;\n }\n }\n\n return false;\n}\n\n/**\n * Get Laravel version from composer.json\n */\nexport function getLaravelVersion(\n options: Pick<WizardOptions, 'installDir'>,\n): string | undefined {\n return getComposerPackageVersion('laravel/framework', options);\n}\n\n/**\n * Get human-readable name for Laravel project type\n */\nexport function getLaravelProjectTypeName(\n projectType: LaravelProjectType,\n): string {\n switch (projectType) {\n case LaravelProjectType.STANDARD:\n return 'Standard Laravel';\n case LaravelProjectType.INERTIA:\n return 'Laravel with Inertia.js';\n case LaravelProjectType.LIVEWIRE:\n return 'Laravel with Livewire';\n default:\n return 'Laravel';\n }\n}\n\n/**\n * Check for Inertia.js\n */\nasync function hasInertia(\n options: Pick<WizardOptions, 'installDir'>,\n): Promise<boolean> {\n return (\n hasComposerPackage('inertiajs/inertia-laravel', options) ||\n (await hasLaravelCodePattern(/Inertia::render|inertia\\(/, options))\n );\n}\n\n/**\n * Check for Livewire\n */\nasync function hasLivewire(\n options: Pick<WizardOptions, 'installDir'>,\n): Promise<boolean> {\n return (\n hasComposerPackage('livewire/livewire', options) ||\n (await hasLaravelCodePattern(/extends\\s+Component|@livewire/, options))\n );\n}\n\n/**\n * Detect Laravel project type\n */\nexport async function getLaravelProjectType(\n options: WizardOptions,\n): Promise<LaravelProjectType> {\n // Check for SPA/Reactive frameworks (important to detect - affects SDK needs)\n if (await hasInertia(options)) {\n clack.log.info('Detected Laravel with Inertia.js');\n return LaravelProjectType.INERTIA;\n }\n if (await hasLivewire(options)) {\n clack.log.info('Detected Laravel with Livewire');\n return LaravelProjectType.LIVEWIRE;\n }\n\n // Default to standard\n clack.log.info('Detected standard Laravel project');\n return LaravelProjectType.STANDARD;\n}\n\n/**\n * Find the main service provider file\n */\nexport async function findLaravelServiceProvider(\n options: Pick<WizardOptions, 'installDir'>,\n): Promise<string | undefined> {\n const { installDir } = options;\n\n // Look for AppServiceProvider first (most common place for setup)\n const appServiceProvider = path.join(\n installDir,\n 'app/Providers/AppServiceProvider.php',\n );\n\n if (fs.existsSync(appServiceProvider)) {\n return 'app/Providers/AppServiceProvider.php';\n }\n\n // Fall back to searching for any service provider\n const providers = await fg(['**/app/Providers/*ServiceProvider.php'], {\n cwd: installDir,\n ignore: LARAVEL_IGNORE_PATTERNS,\n });\n\n return providers[0];\n}\n\n/**\n * Find the bootstrap file (differs between Laravel versions)\n */\nexport function findLaravelBootstrapFile(\n options: Pick<WizardOptions, 'installDir'>,\n): string | undefined {\n const { installDir } = options;\n\n // Laravel 11+ uses bootstrap/app.php with new structure\n const bootstrapApp = path.join(installDir, 'bootstrap/app.php');\n if (fs.existsSync(bootstrapApp)) {\n return 'bootstrap/app.php';\n }\n\n // Older Laravel uses app/Http/Kernel.php\n const httpKernel = path.join(installDir, 'app/Http/Kernel.php');\n if (fs.existsSync(httpKernel)) {\n return 'app/Http/Kernel.php';\n }\n\n return undefined;\n}\n\n/**\n * Detect Laravel version structure for configuration guidance\n */\nexport function detectLaravelStructure(\n options: Pick<WizardOptions, 'installDir'>,\n): 'legacy' | 'modern' | 'latest' {\n const version = getLaravelVersion(options);\n if (!version) return 'modern';\n\n try {\n const majorVersion = parseInt(version.split('.')[0], 10);\n if (majorVersion >= 11) return 'latest'; // Laravel 11+ (new structure)\n if (majorVersion >= 9) return 'modern'; // Laravel 9-10\n return 'legacy'; // Laravel 8 and below\n } catch {\n return 'modern';\n }\n}\n"]}
|
|
@@ -12,6 +12,8 @@ export declare const AgentSignals: {
|
|
|
12
12
|
readonly ERROR_MCP_MISSING: "[ERROR-MCP-MISSING]";
|
|
13
13
|
/** Signal emitted when the agent cannot access the setup resource */
|
|
14
14
|
readonly ERROR_RESOURCE_MISSING: "[ERROR-RESOURCE-MISSING]";
|
|
15
|
+
/** Signal emitted when the agent provides a remark about its run */
|
|
16
|
+
readonly WIZARD_REMARK: "[WIZARD-REMARK]";
|
|
15
17
|
};
|
|
16
18
|
export type AgentSignal = (typeof AgentSignals)[keyof typeof AgentSignals];
|
|
17
19
|
/**
|
|
@@ -42,6 +42,8 @@ exports.AgentSignals = {
|
|
|
42
42
|
ERROR_MCP_MISSING: '[ERROR-MCP-MISSING]',
|
|
43
43
|
/** Signal emitted when the agent cannot access the setup resource */
|
|
44
44
|
ERROR_RESOURCE_MISSING: '[ERROR-RESOURCE-MISSING]',
|
|
45
|
+
/** Signal emitted when the agent provides a remark about its run */
|
|
46
|
+
WIZARD_REMARK: '[WIZARD-REMARK]',
|
|
45
47
|
};
|
|
46
48
|
/**
|
|
47
49
|
* Error types that can be returned from agent execution.
|
|
@@ -339,6 +341,16 @@ async function runAgent(agentConfig, prompt, options, spinner, config) {
|
|
|
339
341
|
else {
|
|
340
342
|
(0, debug_1.logToFile)(`Agent run completed in ${durationSeconds}s`);
|
|
341
343
|
}
|
|
344
|
+
// Extract and capture the agent's reflection on the run
|
|
345
|
+
const outputText = collectedText.join('\n');
|
|
346
|
+
const remarkRegex = new RegExp(`${exports.AgentSignals.WIZARD_REMARK.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\s*(.+?)(?:\\n|$)`, 's');
|
|
347
|
+
const remarkMatch = outputText.match(remarkRegex);
|
|
348
|
+
if (remarkMatch && remarkMatch[1]) {
|
|
349
|
+
const remark = remarkMatch[1].trim();
|
|
350
|
+
if (remark) {
|
|
351
|
+
analytics_1.analytics.capture(constants_1.WIZARD_REMARK_EVENT_NAME, { remark });
|
|
352
|
+
}
|
|
353
|
+
}
|
|
342
354
|
analytics_1.analytics.capture(constants_1.WIZARD_INTERACTION_EVENT_NAME, {
|
|
343
355
|
action: 'agent integration completed',
|
|
344
356
|
duration_ms: durationMs,
|
|
@@ -395,6 +407,31 @@ async function runAgent(agentConfig, prompt, options, spinner, config) {
|
|
|
395
407
|
(0, debug_1.debug)('CLI stderr:', data);
|
|
396
408
|
}
|
|
397
409
|
},
|
|
410
|
+
// Stop hook to have the agent reflect on its run
|
|
411
|
+
hooks: {
|
|
412
|
+
Stop: [
|
|
413
|
+
{
|
|
414
|
+
hooks: [
|
|
415
|
+
(input) => {
|
|
416
|
+
(0, debug_1.logToFile)('Stop hook triggered', {
|
|
417
|
+
stop_hook_active: input.stop_hook_active,
|
|
418
|
+
});
|
|
419
|
+
// Only ask for reflection on first stop (not after reflection is provided)
|
|
420
|
+
if (input.stop_hook_active) {
|
|
421
|
+
(0, debug_1.logToFile)('Stop hook: allowing stop (already reflected)');
|
|
422
|
+
return {}; // Allow stopping
|
|
423
|
+
}
|
|
424
|
+
(0, debug_1.logToFile)('Stop hook: requesting reflection');
|
|
425
|
+
return {
|
|
426
|
+
decision: 'block',
|
|
427
|
+
reason: `Before concluding, provide a brief remark about what information or guidance would have been useful to have in the integration prompt or documentation for this run. Specifically cite anything that would have prevented tool failures, erroneous edits, or other wasted turns. Format your response exactly as: ${exports.AgentSignals.WIZARD_REMARK} Your remark here`,
|
|
428
|
+
};
|
|
429
|
+
},
|
|
430
|
+
],
|
|
431
|
+
timeout: 30,
|
|
432
|
+
},
|
|
433
|
+
],
|
|
434
|
+
},
|
|
398
435
|
},
|
|
399
436
|
});
|
|
400
437
|
// Process the async generator
|