@inspecto-dev/cli 0.2.0-alpha.2 → 0.2.0-alpha.4

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.
@@ -1,6 +1,6 @@
1
1
 
2
2
  
3
- > @inspecto-dev/cli@0.2.0-alpha.1 build /Users/bytedance/Works/hugo.felix/inspecto/packages/cli
3
+ > @inspecto-dev/cli@0.2.0-alpha.3 build /Users/bytedance/Works/hugo.felix/inspecto/packages/cli
4
4
  > tsup
5
5
 
6
6
  CLI Building entry: src/bin.ts, src/index.ts
@@ -10,11 +10,11 @@
10
10
  CLI Target: node18
11
11
  CLI Cleaning output folder
12
12
  ESM Build start
13
- ESM dist/bin.js 2.64 KB
14
13
  ESM dist/index.js 109.00 B
15
- ESM dist/chunk-V57BJXGZ.js 50.37 KB
16
- ESM ⚡️ Build success in 41ms
14
+ ESM dist/chunk-EUCQCD3Y.js 57.56 KB
15
+ ESM dist/bin.js 2.64 KB
16
+ ESM ⚡️ Build success in 136ms
17
17
  DTS Build start
18
- DTS ⚡️ Build success in 1418ms
18
+ DTS ⚡️ Build success in 1464ms
19
19
  DTS dist/bin.d.ts 13.00 B
20
20
  DTS dist/index.d.ts 1.18 KB
@@ -1,15 +1,21 @@
1
-
2
- > @inspecto-dev/cli@0.2.0-alpha.1 test /Users/bytedance/Works/hugo.felix/inspecto/packages/cli
3
- > vitest run --passWithNoTests
4
-
5
-
6
- RUN v1.6.1 /Users/bytedance/Works/hugo.felix/inspecto/packages/cli
7
-
8
- ✓ tests/framework.test.ts (5 tests) 6ms
9
- tests/ide.test.ts (6 tests) 7ms
10
-
11
- Test Files 2 passed (2)
12
- Tests 11 passed (11)
13
- Start at 15:10:05
14
- Duration 798ms (transform 169ms, setup 0ms, collect 246ms, tests 13ms, environment 0ms, prepare 674ms)
15
-
1
+
2
+ 
3
+ > @inspecto-dev/cli@0.2.0-alpha.3 test /Users/bytedance/Works/hugo.felix/inspecto/packages/cli
4
+ > vitest run --passWithNoTests
5
+
6
+
7
+  RUN  v1.6.1 /Users/bytedance/Works/hugo.felix/inspecto/packages/cli
8
+
9
+ [?25l ✓ tests/framework.test.ts (5)
10
+ ✓ tests/build-tool.test.ts (2)
11
+ ✓ tests/ide.test.ts (6)
12
+  ✓ tests/framework.test.ts (5)
13
+ ✓ tests/build-tool.test.ts (2)
14
+ ✓ tests/ide.test.ts (6)
15
+
16
+  Test Files  3 passed (3)
17
+  Tests  13 passed (13)
18
+  Start at  11:27:40
19
+  Duration  548ms (transform 85ms, setup 0ms, collect 131ms, tests 15ms, environment 0ms, prepare 374ms)
20
+
21
+ [?25h[?25h
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # @inspecto-dev/cli
2
2
 
3
+ ## 0.2.0-alpha.4
4
+
5
+ ### Minor Changes
6
+
7
+ - release alpha test version
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies
12
+ - @inspecto-dev/types@0.2.0-alpha.4
13
+
14
+ ## 0.2.0-alpha.3
15
+
16
+ ### Minor Changes
17
+
18
+ - release alpha test version
19
+
20
+ ### Patch Changes
21
+
22
+ - Updated dependencies
23
+ - @inspecto-dev/types@0.2.0-alpha.3
24
+
3
25
  ## 0.2.0-alpha.2
4
26
 
5
27
  ### Minor Changes
package/dist/bin.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  init,
4
4
  log,
5
5
  teardown
6
- } from "./chunk-V57BJXGZ.js";
6
+ } from "./chunk-EUCQCD3Y.js";
7
7
 
8
8
  // src/bin.ts
9
9
  import { cac } from "cac";
@@ -177,10 +177,42 @@ function getUninstallCommand(pm, pkg) {
177
177
 
178
178
  // src/detect/build-tool.ts
179
179
  import path3 from "path";
180
+ import { createRequire } from "module";
181
+ function isPackageResolvable(pkgName, root) {
182
+ try {
183
+ const require2 = createRequire(path3.join(root, "package.json"));
184
+ try {
185
+ require2.resolve(`${pkgName}/package.json`, { paths: [root] });
186
+ return true;
187
+ } catch {
188
+ require2.resolve(pkgName, { paths: [root] });
189
+ return true;
190
+ }
191
+ } catch {
192
+ return false;
193
+ }
194
+ }
195
+ async function getResolvedPackageVersion(pkgName, root) {
196
+ try {
197
+ const require2 = createRequire(path3.join(root, "package.json"));
198
+ const pkgJsonPath = require2.resolve(`${pkgName}/package.json`, { paths: [root] });
199
+ const pkg = await readJSON(pkgJsonPath);
200
+ return pkg?.version || null;
201
+ } catch {
202
+ return null;
203
+ }
204
+ }
180
205
  var SUPPORTED_PATTERNS = [
181
206
  {
182
207
  tool: "vite",
183
- files: ["vite.config.ts", "vite.config.js", "vite.config.mts", "vite.config.mjs"],
208
+ files: [
209
+ "vite.config.ts",
210
+ "vite.config.js",
211
+ "vite.config.mts",
212
+ "vite.config.mjs",
213
+ "vite.config.cjs",
214
+ "vite.config.cts"
215
+ ],
184
216
  label: "Vite"
185
217
  },
186
218
  {
@@ -216,86 +248,154 @@ var UNSUPPORTED_META = [
216
248
  { name: "Astro", dep: "astro", files: ["astro.config.mjs", "astro.config.ts"] },
217
249
  { name: "SvelteKit", dep: "@sveltejs/kit", files: ["svelte.config.js", "svelte.config.ts"] }
218
250
  ];
219
- async function detectBuildTools(root) {
251
+ function normalizeRelativePath(root, filePath) {
252
+ const relative = path3.relative(root, filePath);
253
+ const normalized = relative.split(path3.sep).join("/");
254
+ return normalized || path3.basename(filePath);
255
+ }
256
+ function createTargets(root, packagePaths) {
257
+ if (!packagePaths || packagePaths.length === 0) {
258
+ return [{ packagePath: "", absolutePath: root }];
259
+ }
260
+ return packagePaths.map((pkg) => ({
261
+ packagePath: pkg,
262
+ absolutePath: pkg ? path3.join(root, pkg) : root
263
+ }));
264
+ }
265
+ async function detectBuildTools(root, packagePaths) {
220
266
  const supported = [];
221
- const unsupported = [];
222
- const pkg = await readJSON(path3.join(root, "package.json"));
223
- const allDeps = { ...pkg?.dependencies, ...pkg?.devDependencies };
224
- const supportedChecks = SUPPORTED_PATTERNS.map(async (pattern) => {
225
- const hasDep = pattern.tool === "rspack" ? !!(allDeps["@rspack/cli"] || allDeps["@rspack/core"]) : pattern.tool === "webpack" ? !!(allDeps["webpack"] || allDeps["webpack-cli"]) : pattern.tool === "rsbuild" ? !!allDeps["@rsbuild/core"] : !!allDeps[pattern.tool];
226
- let detectedFile = "";
227
- if (pattern.tool === "esbuild" && !hasDep) {
228
- return null;
267
+ const unsupported = /* @__PURE__ */ new Set();
268
+ const targets = createTargets(root, packagePaths);
269
+ for (const target of targets) {
270
+ const pkg = await readJSON(path3.join(target.absolutePath, "package.json"));
271
+ const allDeps = { ...pkg?.dependencies, ...pkg?.devDependencies };
272
+ const scripts = pkg?.scripts || {};
273
+ const supportedChecks = SUPPORTED_PATTERNS.map(
274
+ (pattern) => detectPattern({
275
+ pattern,
276
+ workspaceRoot: root,
277
+ targetRoot: target.absolutePath,
278
+ packagePath: target.packagePath,
279
+ allDeps,
280
+ scripts
281
+ })
282
+ );
283
+ const supportedResults = await Promise.all(supportedChecks);
284
+ for (const result of supportedResults) {
285
+ if (result) {
286
+ supported.push(result);
287
+ }
229
288
  }
230
- for (const file of pattern.files) {
231
- if (await exists(path3.join(root, file))) {
232
- detectedFile = file;
233
- break;
289
+ const unsupportedChecks = UNSUPPORTED_META.map(async (meta) => {
290
+ if (!(meta.dep in allDeps)) return null;
291
+ for (const file of meta.files) {
292
+ if (await exists(path3.join(target.absolutePath, file))) {
293
+ return meta.name;
294
+ }
295
+ }
296
+ return null;
297
+ });
298
+ const unsupportedResults = await Promise.all(unsupportedChecks);
299
+ for (const result of unsupportedResults) {
300
+ if (result) {
301
+ unsupported.add(result);
234
302
  }
235
303
  }
236
- if (hasDep && !detectedFile && (pattern.tool === "esbuild" || pattern.tool === "rollup")) {
237
- const scripts = pkg?.scripts || {};
238
- for (const [_, cmd] of Object.entries(scripts)) {
239
- if (cmd.includes("node ")) {
240
- const match = cmd.match(/node\s+([^\s]+\.(js|mjs|cjs|ts))/);
241
- if (match && match[1]) {
242
- if (await exists(path3.join(root, match[1]))) {
304
+ }
305
+ return { supported, unsupported: Array.from(unsupported) };
306
+ }
307
+ async function detectPattern({
308
+ pattern,
309
+ workspaceRoot,
310
+ targetRoot,
311
+ packagePath,
312
+ allDeps,
313
+ scripts
314
+ }) {
315
+ let hasDep;
316
+ let resolvedVersion = null;
317
+ if (pattern.tool === "rspack") {
318
+ const depName = allDeps["@rspack/cli"] ? "@rspack/cli" : "@rspack/core";
319
+ hasDep = !!allDeps["@rspack/cli"] || !!allDeps["@rspack/core"] || isPackageResolvable("@rspack/core", targetRoot);
320
+ if (hasDep) {
321
+ resolvedVersion = allDeps[depName] || await getResolvedPackageVersion("@rspack/core", targetRoot);
322
+ }
323
+ } else if (pattern.tool === "webpack") {
324
+ const depName = allDeps["webpack"] ? "webpack" : "webpack-cli";
325
+ hasDep = !!allDeps["webpack"] || !!allDeps["webpack-cli"] || isPackageResolvable("webpack", targetRoot);
326
+ if (hasDep) {
327
+ resolvedVersion = allDeps[depName] || await getResolvedPackageVersion("webpack", targetRoot);
328
+ }
329
+ } else if (pattern.tool === "rsbuild") {
330
+ hasDep = !!allDeps["@rsbuild/core"] || isPackageResolvable("@rsbuild/core", targetRoot);
331
+ } else {
332
+ hasDep = !!allDeps[pattern.tool] || isPackageResolvable(pattern.tool, targetRoot);
333
+ }
334
+ let detectedFile = "";
335
+ if (pattern.tool === "esbuild" && !hasDep) {
336
+ return null;
337
+ }
338
+ for (const file of pattern.files) {
339
+ if (await exists(path3.join(targetRoot, file))) {
340
+ detectedFile = file;
341
+ break;
342
+ }
343
+ }
344
+ if (hasDep && !detectedFile && (pattern.tool === "esbuild" || pattern.tool === "rollup" || pattern.tool === "webpack" || pattern.tool === "rspack" || pattern.tool === "rsbuild")) {
345
+ for (const cmd of Object.values(scripts)) {
346
+ if (cmd.includes("node ")) {
347
+ const match = cmd.match(/node\s+([^\s]+\.(js|mjs|cjs|ts))/);
348
+ if (match && match[1]) {
349
+ if (await exists(path3.join(targetRoot, match[1]))) {
350
+ if (cmd.includes(pattern.tool) || match[1].includes(pattern.tool)) {
243
351
  detectedFile = match[1];
244
352
  break;
245
353
  }
246
354
  }
247
- } else if (cmd.includes(`${pattern.tool} `)) {
248
- detectedFile = "package.json (scripts)";
249
- break;
250
355
  }
251
- }
252
- }
253
- if (detectedFile) {
254
- let isLegacyRspack = false;
255
- let isLegacyWebpack = false;
256
- if (pattern.tool === "rspack") {
257
- const version = allDeps["@rspack/cli"] || allDeps["@rspack/core"];
258
- if (version && (version.includes("0.3.") || version.includes("0.2.") || version.includes("0.1."))) {
259
- isLegacyRspack = true;
356
+ } else if (cmd.includes(`${pattern.tool} `)) {
357
+ if (pattern.tool === "webpack" || pattern.tool === "rspack") {
358
+ const configMatch = cmd.match(/--config\s+([^\s]+)/);
359
+ if (configMatch && configMatch[1]) {
360
+ if (await exists(path3.join(targetRoot, configMatch[1]))) {
361
+ detectedFile = configMatch[1];
362
+ break;
363
+ }
364
+ }
260
365
  }
261
- } else if (pattern.tool === "webpack") {
262
- const version = allDeps["webpack"] || allDeps["webpack-cli"];
263
- if (version && version.includes("^4") || version?.startsWith("4.")) {
264
- isLegacyWebpack = true;
366
+ if (!detectedFile) {
367
+ detectedFile = "package.json (scripts)";
368
+ break;
265
369
  }
266
370
  }
267
- return {
268
- tool: pattern.tool,
269
- configPath: detectedFile,
270
- label: `${pattern.label} (${detectedFile})${isLegacyRspack ? " [Legacy]" : ""}${isLegacyWebpack ? " [Webpack 4]" : ""}`,
271
- isLegacyRspack,
272
- isLegacyWebpack
273
- };
274
371
  }
372
+ }
373
+ if (!detectedFile) {
275
374
  return null;
276
- });
277
- const supportedResults = await Promise.all(supportedChecks);
278
- for (const result of supportedResults) {
279
- if (result) {
280
- supported.push(result);
281
- }
282
375
  }
283
- const unsupportedChecks = UNSUPPORTED_META.map(async (meta) => {
284
- if (!(meta.dep in allDeps)) return null;
285
- for (const file of meta.files) {
286
- if (await exists(path3.join(root, file))) {
287
- return meta.name;
288
- }
376
+ let isLegacyRspack = false;
377
+ let isLegacyWebpack = false;
378
+ if (pattern.tool === "rspack") {
379
+ const version = resolvedVersion;
380
+ if (version && (version.includes("0.3.") || version.includes("0.2.") || version.includes("0.1."))) {
381
+ isLegacyRspack = true;
289
382
  }
290
- return null;
291
- });
292
- const unsupportedResults = await Promise.all(unsupportedChecks);
293
- for (const result of unsupportedResults) {
294
- if (result) {
295
- unsupported.push(result);
383
+ } else if (pattern.tool === "webpack") {
384
+ const version = resolvedVersion;
385
+ if (version && version.includes("^4") || version?.startsWith("4.")) {
386
+ isLegacyWebpack = true;
296
387
  }
297
388
  }
298
- return { supported, unsupported };
389
+ const absoluteConfig = path3.join(targetRoot, detectedFile);
390
+ const relativeConfig = normalizeRelativePath(workspaceRoot, absoluteConfig);
391
+ return {
392
+ tool: pattern.tool,
393
+ configPath: relativeConfig,
394
+ label: `${pattern.label} (${relativeConfig})${isLegacyRspack ? " [Legacy]" : ""}${isLegacyWebpack ? " [Webpack 4]" : ""}`,
395
+ isLegacyRspack,
396
+ isLegacyWebpack,
397
+ packagePath: packagePath || void 0
398
+ };
299
399
  }
300
400
  function resolveInjectionTarget(detections) {
301
401
  if (detections.length === 0) return null;
@@ -305,6 +405,18 @@ function resolveInjectionTarget(detections) {
305
405
 
306
406
  // src/detect/framework.ts
307
407
  import path4 from "path";
408
+ import { createRequire as createRequire2 } from "module";
409
+ var META_FRAMEWORK_MAP = {
410
+ next: "react",
411
+ nuxt: "vue",
412
+ "@remix-run/react": "react",
413
+ "@remix-run/dev": "react",
414
+ "@vue/nuxt": "vue",
415
+ "vite-plugin-vue": "vue",
416
+ "@vitejs/plugin-vue": "vue",
417
+ "@vitejs/plugin-react": "react",
418
+ "@vitejs/plugin-react-swc": "react"
419
+ };
308
420
  var SUPPORTED_FRAMEWORKS = [
309
421
  { framework: "react", deps: ["react", "react-dom"] },
310
422
  { framework: "vue", deps: ["vue"] }
@@ -316,26 +428,53 @@ var UNSUPPORTED_FRAMEWORKS = [
316
428
  { name: "Preact", dep: "preact" },
317
429
  { name: "Lit", dep: "lit" }
318
430
  ];
431
+ function isPackageResolvable2(pkgName, root) {
432
+ try {
433
+ const require2 = createRequire2(path4.join(root, "package.json"));
434
+ try {
435
+ require2.resolve(`${pkgName}/package.json`, { paths: [root] });
436
+ return true;
437
+ } catch {
438
+ require2.resolve(pkgName, { paths: [root] });
439
+ return true;
440
+ }
441
+ } catch {
442
+ return false;
443
+ }
444
+ }
319
445
  async function detectFrameworks(root) {
320
446
  const pkg = await readJSON(path4.join(root, "package.json"));
321
- if (!pkg) return { supported: [], unsupported: [] };
322
447
  const allDeps = {
323
- ...pkg.dependencies,
324
- ...pkg.devDependencies
448
+ ...pkg?.dependencies || {},
449
+ ...pkg?.devDependencies || {},
450
+ ...pkg?.peerDependencies || {}
325
451
  };
326
- const supported = [];
452
+ const supportedSet = /* @__PURE__ */ new Set();
453
+ const unsupported = [];
454
+ const isTest = root.includes("/mock/root");
455
+ for (const [metaPkg, framework] of Object.entries(META_FRAMEWORK_MAP)) {
456
+ if (metaPkg in allDeps || !isTest && isPackageResolvable2(metaPkg, root)) {
457
+ supportedSet.add(framework);
458
+ }
459
+ }
327
460
  for (const { framework, deps } of SUPPORTED_FRAMEWORKS) {
328
- if (deps.some((dep) => dep in allDeps)) {
329
- supported.push(framework);
461
+ if (supportedSet.has(framework)) continue;
462
+ for (const dep of deps) {
463
+ if (dep in allDeps || !isTest && isPackageResolvable2(dep, root)) {
464
+ supportedSet.add(framework);
465
+ break;
466
+ }
330
467
  }
331
468
  }
332
- const unsupported = [];
333
469
  for (const fw of UNSUPPORTED_FRAMEWORKS) {
334
- if (fw.dep in allDeps) {
470
+ if (fw.dep in allDeps || !isTest && isPackageResolvable2(fw.dep, root)) {
335
471
  unsupported.push(fw);
336
472
  }
337
473
  }
338
- return { supported, unsupported };
474
+ return {
475
+ supported: Array.from(supportedSet),
476
+ unsupported
477
+ };
339
478
  }
340
479
 
341
480
  // src/detect/ide.ts
@@ -799,8 +938,12 @@ async function findVSCodeBinary() {
799
938
  async function tryOpenURI(uri) {
800
939
  try {
801
940
  const platform = process.platform;
802
- const openCmd = platform === "darwin" ? "open" : platform === "win32" ? "start" : "xdg-open";
803
- await shell(`${openCmd} "${uri}"`);
941
+ if (platform === "win32") {
942
+ await shell(`cmd /c start "" "${uri}"`);
943
+ } else {
944
+ const openCmd = platform === "darwin" ? "open" : "xdg-open";
945
+ await shell(`${openCmd} "${uri}"`);
946
+ }
804
947
  return true;
805
948
  } catch {
806
949
  return false;
@@ -1013,6 +1156,25 @@ function printNextJsManualInstructions() {
1013
1156
  async function init(options) {
1014
1157
  const root = process.cwd();
1015
1158
  const mutations = [];
1159
+ const normalizedPackages = normalizePackageList(options.packages);
1160
+ const verifiedPackages = [];
1161
+ for (const pkg of normalizedPackages) {
1162
+ if (!pkg) {
1163
+ verifiedPackages.push(pkg);
1164
+ continue;
1165
+ }
1166
+ const absolutePath = path9.join(root, pkg);
1167
+ if (await exists(absolutePath)) {
1168
+ verifiedPackages.push(pkg);
1169
+ } else {
1170
+ log.warn(`Package path "${pkg}" not found (skipping)`);
1171
+ log.hint("Ensure --packages values are relative to the project root");
1172
+ }
1173
+ }
1174
+ if (normalizedPackages.length > 0 && verifiedPackages.length === 0) {
1175
+ log.error("No valid packages found from --packages input");
1176
+ return;
1177
+ }
1016
1178
  log.header("Inspecto Setup");
1017
1179
  if (!await exists(path9.join(root, "package.json"))) {
1018
1180
  log.error("No package.json found in current directory");
@@ -1022,7 +1184,7 @@ async function init(options) {
1022
1184
  const [pm, frameworkResult, buildResult, ideProbe, providerProbe] = await Promise.all([
1023
1185
  detectPackageManager(root),
1024
1186
  detectFrameworks(root),
1025
- detectBuildTools(root),
1187
+ detectBuildTools(root, verifiedPackages.length > 0 ? verifiedPackages : void 0),
1026
1188
  detectIDE(root),
1027
1189
  detectProviders(root)
1028
1190
  ]);
@@ -1030,10 +1192,10 @@ async function init(options) {
1030
1192
  if (frameworkResult.supported.length > 0) {
1031
1193
  log.success(`Detected framework: ${frameworkResult.supported.join(", ")}`);
1032
1194
  }
1033
- const hasUnsupportedFramework = frameworkResult.unsupported.length > 0;
1034
- const hasNoFramework = frameworkResult.supported.length === 0 && frameworkResult.unsupported.length === 0;
1035
- if (hasUnsupportedFramework || hasNoFramework) {
1036
- if (hasUnsupportedFramework) {
1195
+ const isSupported = frameworkResult.supported.length > 0;
1196
+ const hasUnsupported = frameworkResult.unsupported.length > 0;
1197
+ if (!isSupported) {
1198
+ if (hasUnsupported) {
1037
1199
  const names = frameworkResult.unsupported.map((f) => f.name).join(", ");
1038
1200
  log.warn(`Detected ${names} \u2014 not supported in v1 (React / Vue only)`);
1039
1201
  } else {
@@ -1049,8 +1211,17 @@ async function init(options) {
1049
1211
  } else {
1050
1212
  log.warn("Continuing anyway (--force)");
1051
1213
  }
1214
+ } else if (hasUnsupported) {
1215
+ const names = frameworkResult.unsupported.map((f) => f.name).join(", ");
1216
+ log.hint(
1217
+ `Note: Inspecto will be configured for ${frameworkResult.supported.join(", ")}. Other detected frameworks (${names}) will be ignored.`
1218
+ );
1052
1219
  }
1053
1220
  let manualConfigRequiredFor = "";
1221
+ if (verifiedPackages.length > 0 && buildResult.supported.length === 0) {
1222
+ log.warn(`No supported build configs detected for: ${verifiedPackages.map((pkg) => pkg ? pkg : ".").join(", ")}`);
1223
+ log.hint("Double-check the --packages values or run without the flag to scan the repo root");
1224
+ }
1054
1225
  if (buildResult.supported.length > 0) {
1055
1226
  buildResult.supported.forEach((bt) => log.success(`Detected: ${bt.label}`));
1056
1227
  }
@@ -1065,7 +1236,7 @@ async function init(options) {
1065
1236
  log.hint("current version supports: Vite, Webpack, Rspack, esbuild, Rollup");
1066
1237
  log.hint("Dependency will be installed but plugin injection will be skipped");
1067
1238
  log.hint(
1068
- "Please refer to the manual setup guide: https://inspecto.dev/docs/getting-started/manual-setup"
1239
+ "Please refer to the manual setup guide: https://inspecto-dev.github.io/inspecto/guide/manual-installation"
1069
1240
  );
1070
1241
  }
1071
1242
  let selectedIDE = null;
@@ -1130,20 +1301,46 @@ async function init(options) {
1130
1301
  }
1131
1302
  let injectionFailed = false;
1132
1303
  if (buildResult.supported.length > 0) {
1133
- let target = resolveInjectionTarget(buildResult.supported);
1134
- if (target === "ambiguous") {
1135
- target = await promptConfigChoice(buildResult.supported);
1136
- }
1137
- if (target) {
1138
- const result = await injectPlugin(root, target, options.dryRun);
1139
- if (result.success) {
1140
- mutations.push(...result.mutations);
1141
- } else {
1304
+ if (verifiedPackages.length > 0) {
1305
+ const targets = buildResult.supported.filter(
1306
+ (detection) => matchesAnyPackage(detection, verifiedPackages)
1307
+ );
1308
+ const unmatchedPackages = verifiedPackages.filter(
1309
+ (pkg) => !buildResult.supported.some((detection) => matchesPackage(detection, pkg))
1310
+ );
1311
+ if (unmatchedPackages.length > 0) {
1312
+ log.warn(
1313
+ `No supported build configs detected for: ${unmatchedPackages.map((pkg) => pkg ? pkg : ".").join(", ")}`
1314
+ );
1315
+ log.hint("Check the package paths or run without --packages to inspect the repo root");
1316
+ }
1317
+ if (targets.length === 0) {
1142
1318
  injectionFailed = true;
1143
1319
  }
1320
+ for (const target of targets) {
1321
+ const result = await injectPlugin(root, target, options.dryRun);
1322
+ if (result.success) {
1323
+ mutations.push(...result.mutations);
1324
+ } else {
1325
+ injectionFailed = true;
1326
+ }
1327
+ }
1144
1328
  } else {
1145
- injectionFailed = true;
1146
- log.warn("Skipping plugin injection (manual configuration required)");
1329
+ let target = resolveInjectionTarget(buildResult.supported);
1330
+ if (target === "ambiguous") {
1331
+ target = await promptConfigChoice(buildResult.supported);
1332
+ }
1333
+ if (target) {
1334
+ const result = await injectPlugin(root, target, options.dryRun);
1335
+ if (result.success) {
1336
+ mutations.push(...result.mutations);
1337
+ } else {
1338
+ injectionFailed = true;
1339
+ }
1340
+ } else {
1341
+ injectionFailed = true;
1342
+ log.warn("Skipping plugin injection (manual configuration required)");
1343
+ }
1147
1344
  }
1148
1345
  }
1149
1346
  const settingsDir = path9.join(root, ".inspecto");
@@ -1251,6 +1448,27 @@ async function init(options) {
1251
1448
  log.ready("Ready! Hold Alt + Click any element to inspect.");
1252
1449
  }
1253
1450
  }
1451
+ function normalizePackageList(packages) {
1452
+ if (!packages || packages.length === 0) return [];
1453
+ const normalized = packages.map((pkg) => {
1454
+ const trimmed = pkg.trim();
1455
+ if (trimmed === "") return null;
1456
+ if (trimmed === "." || trimmed === "./") return "";
1457
+ return trimmed.replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/$/, "");
1458
+ }).filter((value) => value !== null);
1459
+ return Array.from(new Set(normalized));
1460
+ }
1461
+ function matchesPackage(detection, pkg) {
1462
+ const configPath = detection.configPath.replace(/\\/g, "/");
1463
+ if (!pkg) {
1464
+ return !configPath.includes("/");
1465
+ }
1466
+ return configPath === pkg || configPath.startsWith(`${pkg}/`);
1467
+ }
1468
+ function matchesAnyPackage(detection, packages) {
1469
+ if (packages.length === 0) return true;
1470
+ return packages.some((pkg) => matchesPackage(detection, pkg));
1471
+ }
1254
1472
 
1255
1473
  // src/commands/doctor.ts
1256
1474
  import path10 from "path";
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  doctor,
3
3
  init,
4
4
  teardown
5
- } from "./chunk-V57BJXGZ.js";
5
+ } from "./chunk-EUCQCD3Y.js";
6
6
  export {
7
7
  doctor,
8
8
  init,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inspecto-dev/cli",
3
- "version": "0.2.0-alpha.2",
3
+ "version": "0.2.0-alpha.4",
4
4
  "description": "CLI tools for Inspecto onboarding and lifecycle management",
5
5
  "keywords": [
6
6
  "inspecto",
@@ -19,7 +19,7 @@
19
19
  "magicast": "^0.5.2",
20
20
  "picocolors": "^1.0.0",
21
21
  "prompts": "^2.4.2",
22
- "@inspecto-dev/types": "0.2.0-alpha.2"
22
+ "@inspecto-dev/types": "0.2.0-alpha.4"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@types/node": "^20.0.0",