@lensmcp/nx-plugin 1.18.3 → 1.18.6
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/executors/agent-build/agent-build.d.ts +0 -1
- package/executors/agent-build/agent-build.js +2 -86
- package/executors/agent-dev/agent-dev.d.ts +0 -1
- package/executors/agent-dev/agent-dev.js +4 -425
- package/executors/agent-verify/agent-verify.d.ts +0 -1
- package/executors/agent-verify/agent-verify.js +3 -166
- package/generators/init/init.d.ts +0 -1
- package/generators/init/init.js +9 -167
- package/generators/setup-nest/setup-nest.d.ts +0 -1
- package/generators/setup-nest/setup-nest.js +8 -281
- package/generators/setup-vite/setup-vite.d.ts +0 -1
- package/generators/setup-vite/setup-vite.js +5 -125
- package/index.d.ts +0 -1
- package/index.js +1 -21
- package/lens-frontend.d.ts +0 -1
- package/lens-frontend.js +1 -205
- package/package.json +1 -1
- package/executors/agent-build/agent-build.d.ts.map +0 -1
- package/executors/agent-dev/agent-dev.d.ts.map +0 -1
- package/executors/agent-verify/agent-verify.d.ts.map +0 -1
- package/generators/init/init.d.ts.map +0 -1
- package/generators/setup-nest/setup-nest.d.ts.map +0 -1
- package/generators/setup-vite/setup-vite.d.ts.map +0 -1
- package/index.d.ts.map +0 -1
- package/lens-frontend.d.ts.map +0 -1
|
@@ -1,281 +1,8 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
exports.setupNestGenerator =
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
// Legacy module-style wiring, kept for the manual-fallback hint.
|
|
10
|
-
const IMPORT_LINE = `import { LensmcpModule } from '@lensmcp/nest-instrumentation';`;
|
|
11
|
-
const MODULE_CALL = "LensmcpModule.forRoot({ projectName: '__PROJECT__' })";
|
|
12
|
-
/**
|
|
13
|
-
* Wires LensMCP into a host NestJS project with **no app-code edits**.
|
|
14
|
-
* Idempotent.
|
|
15
|
-
*
|
|
16
|
-
* Zero-config strategy (Phase 8): rewrite the bootstrap in `src/main.ts`
|
|
17
|
-
* so `NestFactory.create(AppModule, opts)` becomes
|
|
18
|
-
* `createLensmcpNestApp(AppModule, { projectName: '<project>', nestOptions: opts })`.
|
|
19
|
-
* `createLensmcpNestApp` wires `LensmcpModule` + the provider tracker +
|
|
20
|
-
* auto-instruments every provider's methods under the hood, so the app
|
|
21
|
-
* module and the providers stay untouched.
|
|
22
|
-
*
|
|
23
|
-
* 1. Find the project's `src/main.ts` (the conventional Nest entry).
|
|
24
|
-
* 2. Replace the `NestFactory.create(...)` call with
|
|
25
|
-
* `createLensmcpNestApp(...)`, threading the original 2nd arg through
|
|
26
|
-
* as `nestOptions` and adding the `@lensmcp/nest-instrumentation`
|
|
27
|
-
* import (dropping the now-unused `NestFactory` import when nothing
|
|
28
|
-
* else uses it). String/AST-lite — if the file doesn't follow the
|
|
29
|
-
* canonical shape we print a precise hint and exit non-zero.
|
|
30
|
-
* 3. Add an `agent-dev` Nx target.
|
|
31
|
-
*/
|
|
32
|
-
async function setupNestGenerator(tree, rawOptions) {
|
|
33
|
-
const options = {
|
|
34
|
-
project: rawOptions.project,
|
|
35
|
-
skipFormat: rawOptions.skipFormat ?? false,
|
|
36
|
-
};
|
|
37
|
-
const project = (0, devkit_1.readProjectConfiguration)(tree, options.project);
|
|
38
|
-
const mainPath = findMain(tree, project.root);
|
|
39
|
-
if (!mainPath) {
|
|
40
|
-
throw new Error(`setup-nest: no main.ts found under ${project.root}/src.`);
|
|
41
|
-
}
|
|
42
|
-
const original = tree.read(mainPath, 'utf-8') ?? '';
|
|
43
|
-
const patched = patchMainBootstrap(original, options.project);
|
|
44
|
-
if (patched === null) {
|
|
45
|
-
throw new Error(`setup-nest: could not safely patch ${mainPath}.\n` +
|
|
46
|
-
`Expected a \`NestFactory.create(AppModule)\` bootstrap call. ` +
|
|
47
|
-
`Edit manually: replace it with \`createLensmcpNestApp(AppModule, ` +
|
|
48
|
-
`{ projectName: '${options.project}' })\` and import it from ` +
|
|
49
|
-
`'@lensmcp/nest-instrumentation'.\n` +
|
|
50
|
-
`(Or use the module form: add \`${IMPORT_LINE}\` and push ` +
|
|
51
|
-
`${MODULE_CALL.replace('__PROJECT__', options.project)} into the ` +
|
|
52
|
-
`@Module imports array.)`);
|
|
53
|
-
}
|
|
54
|
-
if (patched !== original) {
|
|
55
|
-
tree.write(mainPath, patched);
|
|
56
|
-
}
|
|
57
|
-
const targets = { ...(project.targets ?? {}) };
|
|
58
|
-
if (!targets['agent-dev']) {
|
|
59
|
-
targets['agent-dev'] = {
|
|
60
|
-
executor: '@lensmcp/nx-plugin:agent-dev',
|
|
61
|
-
options: {
|
|
62
|
-
kind: 'nestjs',
|
|
63
|
-
},
|
|
64
|
-
};
|
|
65
|
-
project.targets = targets;
|
|
66
|
-
(0, devkit_1.updateProjectConfiguration)(tree, options.project, project);
|
|
67
|
-
}
|
|
68
|
-
if (!options.skipFormat) {
|
|
69
|
-
await (0, devkit_1.formatFiles)(tree);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
exports.default = setupNestGenerator;
|
|
73
|
-
// ---------- helpers ----------
|
|
74
|
-
function findMain(tree, root) {
|
|
75
|
-
for (const name of ['src/main.ts', 'main.ts', 'src/index.ts']) {
|
|
76
|
-
const p = (0, devkit_1.joinPathFragments)(root, name);
|
|
77
|
-
if (tree.exists(p))
|
|
78
|
-
return p;
|
|
79
|
-
}
|
|
80
|
-
return undefined;
|
|
81
|
-
}
|
|
82
|
-
function findAppModule(tree, root) {
|
|
83
|
-
for (const name of ['src/app.module.ts', 'app.module.ts']) {
|
|
84
|
-
const p = (0, devkit_1.joinPathFragments)(root, name);
|
|
85
|
-
if (tree.exists(p))
|
|
86
|
-
return p;
|
|
87
|
-
}
|
|
88
|
-
return undefined;
|
|
89
|
-
}
|
|
90
|
-
const CREATE_CALL_RE = /NestFactory\s*\.\s*create\s*(?:<[\s\S]*?>)?\s*\(/;
|
|
91
|
-
/**
|
|
92
|
-
* Rewrite a Nest `main.ts` bootstrap to the zero-config form. Returns the
|
|
93
|
-
* original string unchanged when already converted (idempotent), `null`
|
|
94
|
-
* when no `NestFactory.create(...)` call is present (caller decides), or
|
|
95
|
-
* the rewritten source otherwise.
|
|
96
|
-
*/
|
|
97
|
-
function patchMainBootstrap(src, projectName) {
|
|
98
|
-
// Already zero-config — nothing to do.
|
|
99
|
-
if (/createLensmcpNestApp\s*\(/.test(src))
|
|
100
|
-
return src;
|
|
101
|
-
const m = CREATE_CALL_RE.exec(src);
|
|
102
|
-
if (!m)
|
|
103
|
-
return null;
|
|
104
|
-
const openParen = m.index + m[0].length - 1; // index of the '('
|
|
105
|
-
const closeParen = matchingParen(src, openParen);
|
|
106
|
-
if (closeParen === -1)
|
|
107
|
-
return null;
|
|
108
|
-
const argsStr = src.slice(openParen + 1, closeParen);
|
|
109
|
-
const { moduleArg, restArg } = splitTopLevelArgs(argsStr);
|
|
110
|
-
if (!moduleArg.trim())
|
|
111
|
-
return null;
|
|
112
|
-
const proj = projectName.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
|
113
|
-
const rest = restArg.trim();
|
|
114
|
-
const optsObject = rest
|
|
115
|
-
? `{ projectName: '${proj}', nestOptions: ${rest} }`
|
|
116
|
-
: `{ projectName: '${proj}' }`;
|
|
117
|
-
const replacement = `createLensmcpNestApp(${moduleArg.trim()}, ${optsObject})`;
|
|
118
|
-
let out = src.slice(0, m.index) + replacement + src.slice(closeParen + 1);
|
|
119
|
-
out = addBootstrapImport(out);
|
|
120
|
-
out = dropUnusedNestFactoryImport(out);
|
|
121
|
-
return out;
|
|
122
|
-
}
|
|
123
|
-
/** Insert the `createLensmcpNestApp` import after the last import, unless
|
|
124
|
-
* the symbol is already imported from `@lensmcp/nest-instrumentation`. */
|
|
125
|
-
function addBootstrapImport(src) {
|
|
126
|
-
const already = /createLensmcpNestApp[\s\S]*?from\s*['"]@lensmcp\/nest-instrumentation['"]/.test(src);
|
|
127
|
-
if (already)
|
|
128
|
-
return src;
|
|
129
|
-
const importLines = [...src.matchAll(/^\s*import .+;?\s*$/gm)];
|
|
130
|
-
const last = importLines.length ? importLines[importLines.length - 1] : null;
|
|
131
|
-
if (last && last.index !== undefined) {
|
|
132
|
-
const at = last.index + last[0].length;
|
|
133
|
-
return src.slice(0, at) + `\n${BOOTSTRAP_IMPORT}` + src.slice(at);
|
|
134
|
-
}
|
|
135
|
-
return `${BOOTSTRAP_IMPORT}\n${src}`;
|
|
136
|
-
}
|
|
137
|
-
/** Strip `NestFactory` from its `@nestjs/core` named import when nothing
|
|
138
|
-
* in the file references `NestFactory` any more. */
|
|
139
|
-
function dropUnusedNestFactoryImport(src) {
|
|
140
|
-
// Reference check excludes the import statement itself.
|
|
141
|
-
if (/\bNestFactory\b/.test(stripNestFactoryImportSpan(src).rest))
|
|
142
|
-
return src;
|
|
143
|
-
const { match } = stripNestFactoryImportSpan(src);
|
|
144
|
-
if (!match)
|
|
145
|
-
return src;
|
|
146
|
-
const names = match.names.filter((n) => n !== 'NestFactory');
|
|
147
|
-
if (names.length === 0) {
|
|
148
|
-
// Remove the whole import statement (and its trailing newline).
|
|
149
|
-
return src.slice(0, match.start) + src.slice(match.end).replace(/^\n/, '');
|
|
150
|
-
}
|
|
151
|
-
const rebuilt = `import { ${names.join(', ')} } from '@nestjs/core';`;
|
|
152
|
-
return src.slice(0, match.start) + rebuilt + src.slice(match.end);
|
|
153
|
-
}
|
|
154
|
-
/** Locate the `@nestjs/core` named import; return its span + names and the
|
|
155
|
-
* source with that span removed (so the caller can test references that
|
|
156
|
-
* live *outside* the import). */
|
|
157
|
-
function stripNestFactoryImportSpan(src) {
|
|
158
|
-
const re = /import\s*\{([^}]*)\}\s*from\s*['"]@nestjs\/core['"];?/;
|
|
159
|
-
const m = re.exec(src);
|
|
160
|
-
if (!m)
|
|
161
|
-
return { match: null, rest: src };
|
|
162
|
-
const names = m[1]
|
|
163
|
-
.split(',')
|
|
164
|
-
.map((s) => s.trim())
|
|
165
|
-
.filter(Boolean);
|
|
166
|
-
const start = m.index;
|
|
167
|
-
const end = m.index + m[0].length;
|
|
168
|
-
const rest = src.slice(0, start) + src.slice(end);
|
|
169
|
-
return { match: { start, end, names }, rest };
|
|
170
|
-
}
|
|
171
|
-
/** Index of the `)` matching the `(` at `openIdx`, skipping strings,
|
|
172
|
-
* template literals and comments. Returns -1 if unbalanced. */
|
|
173
|
-
function matchingParen(src, openIdx) {
|
|
174
|
-
let depth = 0;
|
|
175
|
-
for (let i = openIdx; i < src.length; i++) {
|
|
176
|
-
const skip = skipNonCode(src, i);
|
|
177
|
-
if (skip > i) {
|
|
178
|
-
i = skip - 1;
|
|
179
|
-
continue;
|
|
180
|
-
}
|
|
181
|
-
const ch = src[i];
|
|
182
|
-
if (ch === '(')
|
|
183
|
-
depth++;
|
|
184
|
-
else if (ch === ')') {
|
|
185
|
-
depth--;
|
|
186
|
-
if (depth === 0)
|
|
187
|
-
return i;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
return -1;
|
|
191
|
-
}
|
|
192
|
-
/** Split call arguments at the first top-level comma. */
|
|
193
|
-
function splitTopLevelArgs(argsStr) {
|
|
194
|
-
let depth = 0;
|
|
195
|
-
for (let i = 0; i < argsStr.length; i++) {
|
|
196
|
-
const skip = skipNonCode(argsStr, i);
|
|
197
|
-
if (skip > i) {
|
|
198
|
-
i = skip - 1;
|
|
199
|
-
continue;
|
|
200
|
-
}
|
|
201
|
-
const ch = argsStr[i];
|
|
202
|
-
if (ch === '(' || ch === '[' || ch === '{')
|
|
203
|
-
depth++;
|
|
204
|
-
else if (ch === ')' || ch === ']' || ch === '}')
|
|
205
|
-
depth--;
|
|
206
|
-
else if (ch === ',' && depth === 0) {
|
|
207
|
-
return {
|
|
208
|
-
moduleArg: argsStr.slice(0, i),
|
|
209
|
-
restArg: argsStr.slice(i + 1),
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
return { moduleArg: argsStr, restArg: '' };
|
|
214
|
-
}
|
|
215
|
-
/** If position `i` starts a string/template/comment, return the index just
|
|
216
|
-
* past it; otherwise return `i`. */
|
|
217
|
-
function skipNonCode(src, i) {
|
|
218
|
-
const ch = src[i];
|
|
219
|
-
if (ch === '"' || ch === "'" || ch === '`') {
|
|
220
|
-
for (let j = i + 1; j < src.length; j++) {
|
|
221
|
-
if (src[j] === '\\') {
|
|
222
|
-
j++;
|
|
223
|
-
continue;
|
|
224
|
-
}
|
|
225
|
-
if (src[j] === ch)
|
|
226
|
-
return j + 1;
|
|
227
|
-
}
|
|
228
|
-
return src.length;
|
|
229
|
-
}
|
|
230
|
-
if (ch === '/' && src[i + 1] === '/') {
|
|
231
|
-
const nl = src.indexOf('\n', i);
|
|
232
|
-
return nl === -1 ? src.length : nl;
|
|
233
|
-
}
|
|
234
|
-
if (ch === '/' && src[i + 1] === '*') {
|
|
235
|
-
const end = src.indexOf('*/', i + 2);
|
|
236
|
-
return end === -1 ? src.length : end + 2;
|
|
237
|
-
}
|
|
238
|
-
return i;
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* Legacy module-style wiring. Adds `LensmcpModule.forRoot(...)` into the
|
|
242
|
-
* `@Module({ imports: [...] })` array. Superseded by the `main.ts`
|
|
243
|
-
* bootstrap rewrite ({@link patchMainBootstrap}) but kept for hosts whose
|
|
244
|
-
* entry file doesn't follow the canonical `NestFactory.create` shape.
|
|
245
|
-
* Idempotent. Returns `null` when no `@Module` imports array is found.
|
|
246
|
-
*/
|
|
247
|
-
function patchAppModule(src, projectName) {
|
|
248
|
-
const hasImport = src.includes("from '@lensmcp/nest-instrumentation'") ||
|
|
249
|
-
src.includes('from "@lensmcp/nest-instrumentation"');
|
|
250
|
-
const hasModuleCall = /LensmcpModule\s*\.\s*forRoot\s*\(/.test(src);
|
|
251
|
-
if (hasImport && hasModuleCall)
|
|
252
|
-
return src;
|
|
253
|
-
const importsAnchor = src.indexOf('imports:');
|
|
254
|
-
if (importsAnchor === -1)
|
|
255
|
-
return null;
|
|
256
|
-
const bracketStart = src.indexOf('[', importsAnchor);
|
|
257
|
-
if (bracketStart === -1)
|
|
258
|
-
return null;
|
|
259
|
-
let withImport = src;
|
|
260
|
-
if (!hasImport) {
|
|
261
|
-
const importLines = [...src.matchAll(/^\s*import .+;?\s*$/gm)];
|
|
262
|
-
const lastImport = importLines.length > 0 ? importLines[importLines.length - 1] : null;
|
|
263
|
-
if (lastImport && lastImport.index !== undefined) {
|
|
264
|
-
const insertAt = lastImport.index + lastImport[0].length;
|
|
265
|
-
withImport = src.slice(0, insertAt) + `\n${IMPORT_LINE}` + src.slice(insertAt);
|
|
266
|
-
}
|
|
267
|
-
else {
|
|
268
|
-
withImport = `${IMPORT_LINE}\n` + src;
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
if (hasModuleCall)
|
|
272
|
-
return withImport;
|
|
273
|
-
const adjBracket = withImport.indexOf('[', withImport.indexOf('imports:'));
|
|
274
|
-
const before = withImport.slice(0, adjBracket + 1);
|
|
275
|
-
const after = withImport.slice(adjBracket + 1);
|
|
276
|
-
const trimmedAfter = after.replace(/^\s*/, '');
|
|
277
|
-
const startsClosed = trimmedAfter.startsWith(']');
|
|
278
|
-
const separator = startsClosed ? '' : ', ';
|
|
279
|
-
const call = MODULE_CALL.replace('__PROJECT__', projectName);
|
|
280
|
-
return `${before}${call}${separator}${after}`;
|
|
281
|
-
}
|
|
1
|
+
"use strict";var h=Object.defineProperty;var c=(e,r)=>h(e,"name",{value:r,configurable:!0});var A=Object.defineProperty,i=c((e,r)=>A(e,"name",{value:r,configurable:!0}),"i");Object.defineProperty(exports,"__esModule",{value:!0}),exports.setupNestGenerator=setupNestGenerator,exports.findAppModule=findAppModule,exports.patchMainBootstrap=patchMainBootstrap,exports.patchAppModule=patchAppModule;const devkit_1=require("@nx/devkit"),BOOTSTRAP_IMPORT="import { createLensmcpNestApp } from '@lensmcp/nest-instrumentation';",IMPORT_LINE="import { LensmcpModule } from '@lensmcp/nest-instrumentation';",MODULE_CALL="LensmcpModule.forRoot({ projectName: '__PROJECT__' })";async function setupNestGenerator(e,r){const n={project:r.project,skipFormat:r.skipFormat??!1},t=(0,devkit_1.readProjectConfiguration)(e,n.project),s=findMain(e,t.root);if(!s)throw new Error(`setup-nest: no main.ts found under ${t.root}/src.`);const o=e.read(s,"utf-8")??"",p=patchMainBootstrap(o,n.project);if(p===null)throw new Error(`setup-nest: could not safely patch ${s}.
|
|
2
|
+
Expected a \`NestFactory.create(AppModule)\` bootstrap call. Edit manually: replace it with \`createLensmcpNestApp(AppModule, { projectName: '${n.project}' })\` and import it from '@lensmcp/nest-instrumentation'.
|
|
3
|
+
(Or use the module form: add \`${IMPORT_LINE}\` and push ${MODULE_CALL.replace("__PROJECT__",n.project)} into the @Module imports array.)`);p!==o&&e.write(s,p);const a={...t.targets??{}};a["agent-dev"]||(a["agent-dev"]={executor:"@lensmcp/nx-plugin:agent-dev",options:{kind:"nestjs"}},t.targets=a,(0,devkit_1.updateProjectConfiguration)(e,n.project,t)),n.skipFormat||await(0,devkit_1.formatFiles)(e)}c(setupNestGenerator,"setupNestGenerator"),i(setupNestGenerator,"setupNestGenerator"),exports.default=setupNestGenerator;function findMain(e,r){for(const n of["src/main.ts","main.ts","src/index.ts"]){const t=(0,devkit_1.joinPathFragments)(r,n);if(e.exists(t))return t}}c(findMain,"findMain"),i(findMain,"findMain");function findAppModule(e,r){for(const n of["src/app.module.ts","app.module.ts"]){const t=(0,devkit_1.joinPathFragments)(r,n);if(e.exists(t))return t}}c(findAppModule,"findAppModule"),i(findAppModule,"findAppModule");const CREATE_CALL_RE=/NestFactory\s*\.\s*create\s*(?:<[\s\S]*?>)?\s*\(/;function patchMainBootstrap(e,r){if(/createLensmcpNestApp\s*\(/.test(e))return e;const n=CREATE_CALL_RE.exec(e);if(!n)return null;const t=n.index+n[0].length-1,s=matchingParen(e,t);if(s===-1)return null;const o=e.slice(t+1,s),{moduleArg:p,restArg:a}=splitTopLevelArgs(o);if(!p.trim())return null;const u=r.replace(/\\/g,"\\\\").replace(/'/g,"\\'"),m=a.trim(),d=m?`{ projectName: '${u}', nestOptions: ${m} }`:`{ projectName: '${u}' }`,f=`createLensmcpNestApp(${p.trim()}, ${d})`;let l=e.slice(0,n.index)+f+e.slice(s+1);return l=addBootstrapImport(l),l=dropUnusedNestFactoryImport(l),l}c(patchMainBootstrap,"patchMainBootstrap"),i(patchMainBootstrap,"patchMainBootstrap");function addBootstrapImport(e){if(/createLensmcpNestApp[\s\S]*?from\s*['"]@lensmcp\/nest-instrumentation['"]/.test(e))return e;const r=[...e.matchAll(/^\s*import .+;?\s*$/gm)],n=r.length?r[r.length-1]:null;if(n&&n.index!==void 0){const t=n.index+n[0].length;return e.slice(0,t)+`
|
|
4
|
+
${BOOTSTRAP_IMPORT}`+e.slice(t)}return`${BOOTSTRAP_IMPORT}
|
|
5
|
+
${e}`}c(addBootstrapImport,"addBootstrapImport"),i(addBootstrapImport,"addBootstrapImport");function dropUnusedNestFactoryImport(e){if(/\bNestFactory\b/.test(stripNestFactoryImportSpan(e).rest))return e;const{match:r}=stripNestFactoryImportSpan(e);if(!r)return e;const n=r.names.filter(s=>s!=="NestFactory");if(n.length===0)return e.slice(0,r.start)+e.slice(r.end).replace(/^\n/,"");const t=`import { ${n.join(", ")} } from '@nestjs/core';`;return e.slice(0,r.start)+t+e.slice(r.end)}c(dropUnusedNestFactoryImport,"dropUnusedNestFactoryImport"),i(dropUnusedNestFactoryImport,"dropUnusedNestFactoryImport");function stripNestFactoryImportSpan(e){const r=/import\s*\{([^}]*)\}\s*from\s*['"]@nestjs\/core['"];?/.exec(e);if(!r)return{match:null,rest:e};const n=r[1].split(",").map(p=>p.trim()).filter(Boolean),t=r.index,s=r.index+r[0].length,o=e.slice(0,t)+e.slice(s);return{match:{start:t,end:s,names:n},rest:o}}c(stripNestFactoryImportSpan,"stripNestFactoryImportSpan"),i(stripNestFactoryImportSpan,"stripNestFactoryImportSpan");function matchingParen(e,r){let n=0;for(let t=r;t<e.length;t++){const s=skipNonCode(e,t);if(s>t){t=s-1;continue}const o=e[t];if(o==="(")n++;else if(o===")"&&(n--,n===0))return t}return-1}c(matchingParen,"matchingParen"),i(matchingParen,"matchingParen");function splitTopLevelArgs(e){let r=0;for(let n=0;n<e.length;n++){const t=skipNonCode(e,n);if(t>n){n=t-1;continue}const s=e[n];if(s==="("||s==="["||s==="{")r++;else if(s===")"||s==="]"||s==="}")r--;else if(s===","&&r===0)return{moduleArg:e.slice(0,n),restArg:e.slice(n+1)}}return{moduleArg:e,restArg:""}}c(splitTopLevelArgs,"splitTopLevelArgs"),i(splitTopLevelArgs,"splitTopLevelArgs");function skipNonCode(e,r){const n=e[r];if(n==='"'||n==="'"||n==="`"){for(let t=r+1;t<e.length;t++){if(e[t]==="\\"){t++;continue}if(e[t]===n)return t+1}return e.length}if(n==="/"&&e[r+1]==="/"){const t=e.indexOf(`
|
|
6
|
+
`,r);return t===-1?e.length:t}if(n==="/"&&e[r+1]==="*"){const t=e.indexOf("*/",r+2);return t===-1?e.length:t+2}return r}c(skipNonCode,"skipNonCode"),i(skipNonCode,"skipNonCode");function patchAppModule(e,r){const n=e.includes("from '@lensmcp/nest-instrumentation'")||e.includes('from "@lensmcp/nest-instrumentation"'),t=/LensmcpModule\s*\.\s*forRoot\s*\(/.test(e);if(n&&t)return e;const s=e.indexOf("imports:");if(s===-1||e.indexOf("[",s)===-1)return null;let o=e;if(!n){const f=[...e.matchAll(/^\s*import .+;?\s*$/gm)],l=f.length>0?f[f.length-1]:null;if(l&&l.index!==void 0){const g=l.index+l[0].length;o=e.slice(0,g)+`
|
|
7
|
+
${IMPORT_LINE}`+e.slice(g)}else o=`${IMPORT_LINE}
|
|
8
|
+
`+e}if(t)return o;const p=o.indexOf("[",o.indexOf("imports:")),a=o.slice(0,p+1),u=o.slice(p+1),m=u.replace(/^\s*/,"").startsWith("]")?"":", ",d=MODULE_CALL.replace("__PROJECT__",r);return`${a}${d}${m}${u}`}c(patchAppModule,"patchAppModule"),i(patchAppModule,"patchAppModule");
|
|
@@ -1,125 +1,5 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
exports.setupViteGenerator =
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
const IMPORT_LINE = `import { lensmcpVitePlugin } from '@lensmcp/vite-plugin';`;
|
|
7
|
-
/**
|
|
8
|
-
* Wires LensMCP into a host Vite project. Idempotent on every step.
|
|
9
|
-
*
|
|
10
|
-
* 1. Locate the project's vite.config.{ts,mts,js,mjs,cts,cjs}.
|
|
11
|
-
* 2. Add `import { lensmcpVitePlugin } from '@lensmcp/vite-plugin'`
|
|
12
|
-
* near the top (after the last existing import).
|
|
13
|
-
* 3. Insert `lensmcpVitePlugin({ enabled: mode !== 'production' })`
|
|
14
|
-
* into the `plugins` array if not already present. We do *not*
|
|
15
|
-
* AST-edit — we use string heuristics on the standard
|
|
16
|
-
* `defineConfig({ plugins: [...] })` shape. If the file is too
|
|
17
|
-
* custom for the heuristics, we print a diff hint and bail.
|
|
18
|
-
* 4. Add Nx targets: agent-dev, agent-build, agent-verify.
|
|
19
|
-
*/
|
|
20
|
-
async function setupViteGenerator(tree, rawOptions) {
|
|
21
|
-
const options = {
|
|
22
|
-
project: rawOptions.project,
|
|
23
|
-
skipFormat: rawOptions.skipFormat ?? false,
|
|
24
|
-
};
|
|
25
|
-
const project = (0, devkit_1.readProjectConfiguration)(tree, options.project);
|
|
26
|
-
const viteConfigPath = findViteConfig(tree, project.root);
|
|
27
|
-
if (!viteConfigPath) {
|
|
28
|
-
throw new Error(`setup-vite: no vite.config.{ts,mts,js,mjs,cts,cjs} found under ${project.root}.`);
|
|
29
|
-
}
|
|
30
|
-
const original = tree.read(viteConfigPath, 'utf-8') ?? '';
|
|
31
|
-
const patched = patchViteConfig(original);
|
|
32
|
-
if (patched === null) {
|
|
33
|
-
throw new Error(`setup-vite: could not safely patch ${viteConfigPath}.\n` +
|
|
34
|
-
`Expected a defineConfig({ plugins: [...] }) or defineConfig(({ mode }) => ({ plugins: [...] })) shape.\n` +
|
|
35
|
-
`Edit manually: add \`${IMPORT_LINE}\` and push \`lensmcpVitePlugin({ enabled: mode !== 'production' })\` into the plugins array.`);
|
|
36
|
-
}
|
|
37
|
-
if (patched !== original) {
|
|
38
|
-
tree.write(viteConfigPath, patched);
|
|
39
|
-
}
|
|
40
|
-
// Idempotent Nx target additions.
|
|
41
|
-
const targets = { ...(project.targets ?? {}) };
|
|
42
|
-
if (!targets['agent-dev']) {
|
|
43
|
-
targets['agent-dev'] = {
|
|
44
|
-
executor: '@lensmcp/nx-plugin:agent-dev',
|
|
45
|
-
options: {
|
|
46
|
-
kind: 'vite-react',
|
|
47
|
-
chrome: true,
|
|
48
|
-
headless: true,
|
|
49
|
-
},
|
|
50
|
-
};
|
|
51
|
-
project.targets = targets;
|
|
52
|
-
(0, devkit_1.updateProjectConfiguration)(tree, options.project, project);
|
|
53
|
-
}
|
|
54
|
-
if (!options.skipFormat) {
|
|
55
|
-
await (0, devkit_1.formatFiles)(tree);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
exports.default = setupViteGenerator;
|
|
59
|
-
// ---------- helpers ----------
|
|
60
|
-
function findViteConfig(tree, root) {
|
|
61
|
-
// Nx generates `vite.config.mts` for ESM workspaces — cover every Vite-supported extension.
|
|
62
|
-
for (const name of [
|
|
63
|
-
'vite.config.ts',
|
|
64
|
-
'vite.config.mts',
|
|
65
|
-
'vite.config.js',
|
|
66
|
-
'vite.config.mjs',
|
|
67
|
-
'vite.config.cts',
|
|
68
|
-
'vite.config.cjs',
|
|
69
|
-
]) {
|
|
70
|
-
const p = (0, devkit_1.joinPathFragments)(root, name);
|
|
71
|
-
if (tree.exists(p))
|
|
72
|
-
return p;
|
|
73
|
-
}
|
|
74
|
-
return undefined;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* String-heuristic patch:
|
|
78
|
-
*
|
|
79
|
-
* 1. If the file already imports `@lensmcp/vite-plugin` and mentions
|
|
80
|
-
* `lensmcpVitePlugin(` in the plugins array, return unchanged.
|
|
81
|
-
* 2. Otherwise insert the import near the top (after the last
|
|
82
|
-
* `import …` line) and add the plugin call to the plugins array
|
|
83
|
-
* declared by `plugins: [` (first occurrence).
|
|
84
|
-
*
|
|
85
|
-
* If neither anchor is found, return `null` so the generator can ask
|
|
86
|
-
* the user to patch manually.
|
|
87
|
-
*/
|
|
88
|
-
function patchViteConfig(src) {
|
|
89
|
-
const hasImport = src.includes("from '@lensmcp/vite-plugin'") || src.includes('from "@lensmcp/vite-plugin"');
|
|
90
|
-
const hasPluginCall = /lensmcpVitePlugin\s*\(/.test(src);
|
|
91
|
-
if (hasImport && hasPluginCall)
|
|
92
|
-
return src;
|
|
93
|
-
const pluginsAnchor = src.indexOf('plugins:');
|
|
94
|
-
if (pluginsAnchor === -1)
|
|
95
|
-
return null;
|
|
96
|
-
const bracketStart = src.indexOf('[', pluginsAnchor);
|
|
97
|
-
if (bracketStart === -1)
|
|
98
|
-
return null;
|
|
99
|
-
let withImport = src;
|
|
100
|
-
if (!hasImport) {
|
|
101
|
-
const importLines = [...src.matchAll(/^\s*import .+;?\s*$/gm)];
|
|
102
|
-
const lastImport = importLines.length > 0 ? importLines[importLines.length - 1] : null;
|
|
103
|
-
if (lastImport && lastImport.index !== undefined) {
|
|
104
|
-
const insertAt = lastImport.index + lastImport[0].length;
|
|
105
|
-
withImport = src.slice(0, insertAt) + `\n${IMPORT_LINE}` + src.slice(insertAt);
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
withImport = `${IMPORT_LINE}\n` + src;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
if (hasPluginCall)
|
|
112
|
-
return withImport;
|
|
113
|
-
const adjBracket = withImport.indexOf('[', withImport.indexOf('plugins:'));
|
|
114
|
-
const before = withImport.slice(0, adjBracket + 1);
|
|
115
|
-
const after = withImport.slice(adjBracket + 1);
|
|
116
|
-
// Insert at the start of the array with a trailing comma if the array isn't empty.
|
|
117
|
-
const trimmedAfter = after.replace(/^\s*/, '');
|
|
118
|
-
const startsClosed = trimmedAfter.startsWith(']');
|
|
119
|
-
const separator = startsClosed ? '' : ', ';
|
|
120
|
-
// `mode` is only in scope for the function-form config (`defineConfig(({ mode }) => …)`).
|
|
121
|
-
// For the object form, gate on NODE_ENV instead of emitting code that doesn't compile.
|
|
122
|
-
const hasModeInScope = /defineConfig\s*\(\s*(?:async\s*)?\(\s*\{[^}]*\bmode\b[^}]*\}/.test(withImport);
|
|
123
|
-
const enabledExpr = hasModeInScope ? "mode !== 'production'" : "process.env.NODE_ENV !== 'production'";
|
|
124
|
-
return `${before}lensmcpVitePlugin({ enabled: ${enabledExpr} })${separator}${after}`;
|
|
125
|
-
}
|
|
1
|
+
"use strict";var v=Object.defineProperty;var p=(e,t)=>v(e,"name",{value:t,configurable:!0});var m=Object.defineProperty,l=p((e,t)=>m(e,"name",{value:t,configurable:!0}),"l");Object.defineProperty(exports,"__esModule",{value:!0}),exports.setupViteGenerator=setupViteGenerator,exports.patchViteConfig=patchViteConfig;const devkit_1=require("@nx/devkit"),IMPORT_LINE="import { lensmcpVitePlugin } from '@lensmcp/vite-plugin';";async function setupViteGenerator(e,t){const o={project:t.project,skipFormat:t.skipFormat??!1},i=(0,devkit_1.readProjectConfiguration)(e,o.project),n=findViteConfig(e,i.root);if(!n)throw new Error(`setup-vite: no vite.config.{ts,mts,js,mjs,cts,cjs} found under ${i.root}.`);const r=e.read(n,"utf-8")??"",c=patchViteConfig(r);if(c===null)throw new Error(`setup-vite: could not safely patch ${n}.
|
|
2
|
+
Expected a defineConfig({ plugins: [...] }) or defineConfig(({ mode }) => ({ plugins: [...] })) shape.
|
|
3
|
+
Edit manually: add \`${IMPORT_LINE}\` and push \`lensmcpVitePlugin({ enabled: mode !== 'production' })\` into the plugins array.`);c!==r&&e.write(n,c);const s={...i.targets??{}};s["agent-dev"]||(s["agent-dev"]={executor:"@lensmcp/nx-plugin:agent-dev",options:{kind:"vite-react",chrome:!0,headless:!0}},i.targets=s,(0,devkit_1.updateProjectConfiguration)(e,o.project,i)),o.skipFormat||await(0,devkit_1.formatFiles)(e)}p(setupViteGenerator,"setupViteGenerator"),l(setupViteGenerator,"setupViteGenerator"),exports.default=setupViteGenerator;function findViteConfig(e,t){for(const o of["vite.config.ts","vite.config.mts","vite.config.js","vite.config.mjs","vite.config.cts","vite.config.cjs"]){const i=(0,devkit_1.joinPathFragments)(t,o);if(e.exists(i))return i}}p(findViteConfig,"findViteConfig"),l(findViteConfig,"findViteConfig");function patchViteConfig(e){const t=e.includes("from '@lensmcp/vite-plugin'")||e.includes('from "@lensmcp/vite-plugin"'),o=/lensmcpVitePlugin\s*\(/.test(e);if(t&&o)return e;const i=e.indexOf("plugins:");if(i===-1||e.indexOf("[",i)===-1)return null;let n=e;if(!t){const a=[...e.matchAll(/^\s*import .+;?\s*$/gm)],u=a.length>0?a[a.length-1]:null;if(u&&u.index!==void 0){const f=u.index+u[0].length;n=e.slice(0,f)+`
|
|
4
|
+
${IMPORT_LINE}`+e.slice(f)}else n=`${IMPORT_LINE}
|
|
5
|
+
`+e}if(o)return n;const r=n.indexOf("[",n.indexOf("plugins:")),c=n.slice(0,r+1),s=n.slice(r+1),d=s.replace(/^\s*/,"").startsWith("]")?"":", ",g=/defineConfig\s*\(\s*(?:async\s*)?\(\s*\{[^}]*\bmode\b[^}]*\}/.test(n)?"mode !== 'production'":"process.env.NODE_ENV !== 'production'";return`${c}lensmcpVitePlugin({ enabled: ${g} })${d}${s}`}p(patchViteConfig,"patchViteConfig"),l(patchViteConfig,"patchViteConfig");
|
package/index.d.ts
CHANGED
|
@@ -11,4 +11,3 @@ export type { AgentDevExecutorSchema } from './executors/agent-dev/schema.js';
|
|
|
11
11
|
export type { AgentBuildExecutorSchema } from './executors/agent-build/schema.js';
|
|
12
12
|
export type { AgentVerifyExecutorSchema } from './executors/agent-verify/schema.js';
|
|
13
13
|
export { initGenerator as default } from './generators/init/init.js';
|
|
14
|
-
//# sourceMappingURL=index.d.ts.map
|
package/index.js
CHANGED
|
@@ -1,21 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.default = exports.agentVerifyExecutor = exports.agentBuildExecutor = exports.agentDevExecutor = exports.patchAppModule = exports.patchMainBootstrap = exports.setupNestGenerator = exports.patchViteConfig = exports.setupViteGenerator = exports.initGenerator = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
var init_js_1 = require("./generators/init/init.js");
|
|
6
|
-
Object.defineProperty(exports, "initGenerator", { enumerable: true, get: function () { return init_js_1.initGenerator; } });
|
|
7
|
-
var setup_vite_js_1 = require("./generators/setup-vite/setup-vite.js");
|
|
8
|
-
Object.defineProperty(exports, "setupViteGenerator", { enumerable: true, get: function () { return setup_vite_js_1.setupViteGenerator; } });
|
|
9
|
-
Object.defineProperty(exports, "patchViteConfig", { enumerable: true, get: function () { return setup_vite_js_1.patchViteConfig; } });
|
|
10
|
-
var setup_nest_js_1 = require("./generators/setup-nest/setup-nest.js");
|
|
11
|
-
Object.defineProperty(exports, "setupNestGenerator", { enumerable: true, get: function () { return setup_nest_js_1.setupNestGenerator; } });
|
|
12
|
-
Object.defineProperty(exports, "patchMainBootstrap", { enumerable: true, get: function () { return setup_nest_js_1.patchMainBootstrap; } });
|
|
13
|
-
Object.defineProperty(exports, "patchAppModule", { enumerable: true, get: function () { return setup_nest_js_1.patchAppModule; } });
|
|
14
|
-
var agent_dev_js_1 = require("./executors/agent-dev/agent-dev.js");
|
|
15
|
-
Object.defineProperty(exports, "agentDevExecutor", { enumerable: true, get: function () { return tslib_1.__importDefault(agent_dev_js_1).default; } });
|
|
16
|
-
var agent_build_js_1 = require("./executors/agent-build/agent-build.js");
|
|
17
|
-
Object.defineProperty(exports, "agentBuildExecutor", { enumerable: true, get: function () { return tslib_1.__importDefault(agent_build_js_1).default; } });
|
|
18
|
-
var agent_verify_js_1 = require("./executors/agent-verify/agent-verify.js");
|
|
19
|
-
Object.defineProperty(exports, "agentVerifyExecutor", { enumerable: true, get: function () { return tslib_1.__importDefault(agent_verify_js_1).default; } });
|
|
20
|
-
var init_js_2 = require("./generators/init/init.js");
|
|
21
|
-
Object.defineProperty(exports, "default", { enumerable: true, get: function () { return init_js_2.initGenerator; } });
|
|
1
|
+
"use strict";var i=Object.defineProperty;var o=(t,r)=>i(t,"name",{value:r,configurable:!0});var n=Object.defineProperty,e=o((t,r)=>n(t,"name",{value:r,configurable:!0}),"e");Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=exports.agentVerifyExecutor=exports.agentBuildExecutor=exports.agentDevExecutor=exports.patchAppModule=exports.patchMainBootstrap=exports.setupNestGenerator=exports.patchViteConfig=exports.setupViteGenerator=exports.initGenerator=void 0;const tslib_1=require("tslib");var init_js_1=require("./generators/init/init.js");Object.defineProperty(exports,"initGenerator",{enumerable:!0,get:e(function(){return init_js_1.initGenerator},"get")});var setup_vite_js_1=require("./generators/setup-vite/setup-vite.js");Object.defineProperty(exports,"setupViteGenerator",{enumerable:!0,get:e(function(){return setup_vite_js_1.setupViteGenerator},"get")}),Object.defineProperty(exports,"patchViteConfig",{enumerable:!0,get:e(function(){return setup_vite_js_1.patchViteConfig},"get")});var setup_nest_js_1=require("./generators/setup-nest/setup-nest.js");Object.defineProperty(exports,"setupNestGenerator",{enumerable:!0,get:e(function(){return setup_nest_js_1.setupNestGenerator},"get")}),Object.defineProperty(exports,"patchMainBootstrap",{enumerable:!0,get:e(function(){return setup_nest_js_1.patchMainBootstrap},"get")}),Object.defineProperty(exports,"patchAppModule",{enumerable:!0,get:e(function(){return setup_nest_js_1.patchAppModule},"get")});var agent_dev_js_1=require("./executors/agent-dev/agent-dev.js");Object.defineProperty(exports,"agentDevExecutor",{enumerable:!0,get:e(function(){return tslib_1.__importDefault(agent_dev_js_1).default},"get")});var agent_build_js_1=require("./executors/agent-build/agent-build.js");Object.defineProperty(exports,"agentBuildExecutor",{enumerable:!0,get:e(function(){return tslib_1.__importDefault(agent_build_js_1).default},"get")});var agent_verify_js_1=require("./executors/agent-verify/agent-verify.js");Object.defineProperty(exports,"agentVerifyExecutor",{enumerable:!0,get:e(function(){return tslib_1.__importDefault(agent_verify_js_1).default},"get")});var init_js_2=require("./generators/init/init.js");Object.defineProperty(exports,"default",{enumerable:!0,get:e(function(){return init_js_2.initGenerator},"get")});
|
package/lens-frontend.d.ts
CHANGED
|
@@ -73,4 +73,3 @@ export declare function findCaptureRunner(workspaceRoot: string): string | undef
|
|
|
73
73
|
* `lensmcp` package's `bundled/bridge.js`, else the in-repo dev build.
|
|
74
74
|
*/
|
|
75
75
|
export declare function findBridgeBundle(workspaceRoot: string): string | undefined;
|
|
76
|
-
//# sourceMappingURL=lens-frontend.d.ts.map
|