@kb-labs/cli-commands 2.89.0 → 2.94.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/{discover-Cz7X5bQp.d.ts → discover-CCE84_5E.d.ts} +16 -12
- package/dist/index.d.ts +2 -2
- package/dist/index.js +157 -124
- package/dist/index.js.map +1 -1
- package/dist/registry/index.d.ts +5 -6
- package/dist/registry/index.js +106 -76
- package/dist/registry/index.js.map +1 -1
- package/package.json +22 -22
package/dist/index.js
CHANGED
|
@@ -185,7 +185,7 @@ function ensureManifestLoader(manifest) {
|
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
function createUnavailableManifest(pkgName, error) {
|
|
188
|
-
const rawMsg = (error
|
|
188
|
+
const rawMsg = (error instanceof Error ? error.message : String(error) || "").toString();
|
|
189
189
|
let missing = null;
|
|
190
190
|
const m1 = rawMsg.match(/Cannot find (?:module|package) '([^']+)'/);
|
|
191
191
|
const m2 = rawMsg.match(/from ['"]([^'"]+)['"]/);
|
|
@@ -206,9 +206,13 @@ function createUnavailableManifest(pkgName, error) {
|
|
|
206
206
|
requires,
|
|
207
207
|
loader: async () => {
|
|
208
208
|
throw new Error(`Cannot load ${pkgName} CLI manifest. ${rawMsg}`);
|
|
209
|
-
}
|
|
209
|
+
},
|
|
210
|
+
// Mark as synthetic so saveCache can skip it — synthetic manifests must never
|
|
211
|
+
// be persisted to disk because they represent transient load failures.
|
|
212
|
+
// Caching them would make the error "stick" until the TTL expires even after
|
|
213
|
+
// the underlying problem (missing build artifact, broken dep) is resolved.
|
|
214
|
+
_synthetic: true
|
|
210
215
|
};
|
|
211
|
-
manifest._synthetic = true;
|
|
212
216
|
return manifest;
|
|
213
217
|
}
|
|
214
218
|
function resetInProcCache() {
|
|
@@ -294,7 +298,7 @@ async function detectNewWorkspacePackages(cwd, cachedPackages) {
|
|
|
294
298
|
}
|
|
295
299
|
}
|
|
296
300
|
} catch (error) {
|
|
297
|
-
log("debug", `[plugins][cache] Workspace scan skipped: ${error
|
|
301
|
+
log("debug", `[plugins][cache] Workspace scan skipped: ${error instanceof Error ? error.message : "unknown error"}`);
|
|
298
302
|
}
|
|
299
303
|
return false;
|
|
300
304
|
}
|
|
@@ -305,7 +309,7 @@ async function loadManifestWithTimeout(manifestPath, pkgName, pkgRoot) {
|
|
|
305
309
|
try {
|
|
306
310
|
return await Promise.race([loadManifest(manifestPath, pkgName, pkgRoot), timeout]);
|
|
307
311
|
} catch (err) {
|
|
308
|
-
if (err.message === "Timeout") {
|
|
312
|
+
if (err instanceof Error && err.message === "Timeout") {
|
|
309
313
|
log("warn", `Timeout loading manifest from ${pkgName}`);
|
|
310
314
|
return [];
|
|
311
315
|
}
|
|
@@ -325,10 +329,12 @@ function getNamespaceFromManifest(manifestV2, packageName) {
|
|
|
325
329
|
async function loadManifest(manifestPath, pkgName, pkgRoot) {
|
|
326
330
|
const fileUrl = pathToFileURL(manifestPath).href;
|
|
327
331
|
const mod = await import(fileUrl);
|
|
328
|
-
const
|
|
329
|
-
|
|
332
|
+
const modTyped = mod;
|
|
333
|
+
const rawManifest = modTyped.manifest || modTyped.default;
|
|
334
|
+
if (!rawManifest || typeof rawManifest !== "object" || rawManifest.schema !== "kb.plugin/3") {
|
|
330
335
|
throw new Error(`Unsupported manifest format in ${pkgName}. Only kb.plugin/3 schema is supported.`);
|
|
331
336
|
}
|
|
337
|
+
const manifest = rawManifest;
|
|
332
338
|
const namespace = getNamespaceFromManifest(manifest, pkgName);
|
|
333
339
|
const manifestDir = path.dirname(manifestPath);
|
|
334
340
|
const baseRoot = pkgRoot || manifestDir;
|
|
@@ -390,8 +396,9 @@ async function loadConfig(cwd) {
|
|
|
390
396
|
}
|
|
391
397
|
}
|
|
392
398
|
async function findManifestPath(pkgRoot, pkg) {
|
|
393
|
-
|
|
394
|
-
|
|
399
|
+
const kb = pkg.kb;
|
|
400
|
+
if (kb?.manifest) {
|
|
401
|
+
const manifestPath = path.join(pkgRoot, kb.manifest);
|
|
395
402
|
try {
|
|
396
403
|
await promises.access(manifestPath);
|
|
397
404
|
return { path: manifestPath, deprecated: false };
|
|
@@ -399,8 +406,9 @@ async function findManifestPath(pkgRoot, pkg) {
|
|
|
399
406
|
return { path: null, deprecated: false };
|
|
400
407
|
}
|
|
401
408
|
}
|
|
402
|
-
|
|
403
|
-
|
|
409
|
+
const exports$1 = pkg.exports;
|
|
410
|
+
if (exports$1?.["./kb/commands"]) {
|
|
411
|
+
const exportPath = exports$1["./kb/commands"];
|
|
404
412
|
const manifestPath = typeof exportPath === "string" ? exportPath : exportPath.default || exportPath.import;
|
|
405
413
|
if (manifestPath) {
|
|
406
414
|
const resolved = path.resolve(pkgRoot, manifestPath);
|
|
@@ -504,20 +512,21 @@ async function discoverProjectLocalPlugins(projectRoot) {
|
|
|
504
512
|
}
|
|
505
513
|
async function loadManifestsForPackages(packageInfos, source, scope) {
|
|
506
514
|
const loadPromises = packageInfos.map(async ({ pkgRoot, pkg, manifestPath }) => {
|
|
515
|
+
const pkgName = pkg.name;
|
|
507
516
|
const pkgStart = Date.now();
|
|
508
517
|
try {
|
|
509
|
-
const manifests = await loadManifestWithTimeout(manifestPath,
|
|
518
|
+
const manifests = await loadManifestWithTimeout(manifestPath, pkgName, pkgRoot);
|
|
510
519
|
const pkgTime = Date.now() - pkgStart;
|
|
511
520
|
if (pkgTime > 30) {
|
|
512
|
-
log("debug", `[plugins][perf] ${
|
|
521
|
+
log("debug", `[plugins][perf] ${pkgName} manifest parse: ${pkgTime}ms (budget: 30ms)`);
|
|
513
522
|
}
|
|
514
523
|
if (manifests.length > 0) {
|
|
515
|
-
validateUniqueIds(manifests,
|
|
524
|
+
validateUniqueIds(manifests, pkgName);
|
|
516
525
|
return {
|
|
517
526
|
manifests,
|
|
518
527
|
source,
|
|
519
528
|
scope,
|
|
520
|
-
packageName:
|
|
529
|
+
packageName: pkgName,
|
|
521
530
|
manifestPath: toPosixPath(manifestPath),
|
|
522
531
|
pkgRoot: toPosixPath(pkgRoot)
|
|
523
532
|
};
|
|
@@ -525,21 +534,23 @@ async function loadManifestsForPackages(packageInfos, source, scope) {
|
|
|
525
534
|
return null;
|
|
526
535
|
} catch (err) {
|
|
527
536
|
const pkgTime = Date.now() - pkgStart;
|
|
528
|
-
log("debug", `[plugins][perf] ${
|
|
537
|
+
log("debug", `[plugins][perf] ${pkgName} failed after ${pkgTime}ms`);
|
|
538
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
539
|
+
const errCode = err.code ?? "UNKNOWN";
|
|
529
540
|
log("warn", JSON.stringify({
|
|
530
541
|
code: "DISCOVERY_MANIFEST_LOAD_FAIL",
|
|
531
|
-
packageName:
|
|
542
|
+
packageName: pkgName,
|
|
532
543
|
manifestPath: toPosixPath(manifestPath),
|
|
533
|
-
errorCode:
|
|
534
|
-
errorMessage:
|
|
535
|
-
hint:
|
|
544
|
+
errorCode: errCode,
|
|
545
|
+
errorMessage: errMsg,
|
|
546
|
+
hint: errMsg.includes("Cannot find package") ? "Run: kb devlink apply && pnpm -w build" : "Check manifest syntax and dependencies"
|
|
536
547
|
}));
|
|
537
|
-
const synthetic = createUnavailableManifest(
|
|
548
|
+
const synthetic = createUnavailableManifest(pkgName, err);
|
|
538
549
|
return {
|
|
539
550
|
manifests: [synthetic],
|
|
540
551
|
source,
|
|
541
552
|
scope,
|
|
542
|
-
packageName:
|
|
553
|
+
packageName: pkgName,
|
|
543
554
|
manifestPath: toPosixPath(manifestPath),
|
|
544
555
|
pkgRoot: toPosixPath(pkgRoot)
|
|
545
556
|
};
|
|
@@ -560,29 +571,30 @@ async function discoverCurrentPackage(cwd) {
|
|
|
560
571
|
if (!pkg) {
|
|
561
572
|
return null;
|
|
562
573
|
}
|
|
574
|
+
const pkgName = pkg.name;
|
|
563
575
|
const manifestInfo = await findManifestPath(cwd, pkg);
|
|
564
576
|
if (manifestInfo.path) {
|
|
565
577
|
if (manifestInfo.deprecated) {
|
|
566
|
-
log("warn", `[DEPRECATED] ${
|
|
578
|
+
log("warn", `[DEPRECATED] ${pkgName} uses legacy manifest path: ${manifestInfo.path}`);
|
|
567
579
|
log("warn", ` \u2192 Migrate to exports["./kb/commands"] or set kb.commandsManifest in package.json`);
|
|
568
580
|
}
|
|
569
|
-
const manifests = await loadManifestWithTimeout(manifestInfo.path,
|
|
581
|
+
const manifests = await loadManifestWithTimeout(manifestInfo.path, pkgName, cwd);
|
|
570
582
|
if (manifests.length > 0) {
|
|
571
|
-
validateUniqueIds(manifests,
|
|
583
|
+
validateUniqueIds(manifests, pkgName);
|
|
572
584
|
return {
|
|
573
585
|
manifests,
|
|
574
586
|
source: "workspace",
|
|
575
587
|
// Current-package fallback fires in installed mode when the user's
|
|
576
588
|
// project itself exposes a manifest. That maps to the project scope.
|
|
577
589
|
scope: "project",
|
|
578
|
-
packageName:
|
|
590
|
+
packageName: pkgName,
|
|
579
591
|
manifestPath: toPosixPath(manifestInfo.path),
|
|
580
592
|
pkgRoot: toPosixPath(cwd)
|
|
581
593
|
};
|
|
582
594
|
}
|
|
583
595
|
}
|
|
584
596
|
} catch (err) {
|
|
585
|
-
log("debug", `No CLI manifest in current package: ${err.message}`);
|
|
597
|
+
log("debug", `No CLI manifest in current package: ${err instanceof Error ? err.message : String(err)}`);
|
|
586
598
|
}
|
|
587
599
|
return null;
|
|
588
600
|
}
|
|
@@ -599,7 +611,7 @@ async function discoverNodeModules(cwd) {
|
|
|
599
611
|
}
|
|
600
612
|
const scanEntry = async () => {
|
|
601
613
|
let pkgRoot;
|
|
602
|
-
let pkg;
|
|
614
|
+
let pkg = null;
|
|
603
615
|
if (entry.name.startsWith("@")) {
|
|
604
616
|
const scopeDir = path.join(nmDir, entry.name);
|
|
605
617
|
try {
|
|
@@ -610,29 +622,30 @@ async function discoverNodeModules(cwd) {
|
|
|
610
622
|
if (!pkg) {
|
|
611
623
|
continue;
|
|
612
624
|
}
|
|
625
|
+
const scopedPkgName = pkg.name;
|
|
613
626
|
const isPlugin = isPluginPackage(pkg);
|
|
614
|
-
if (
|
|
627
|
+
if (scopedPkgName?.startsWith("@kb-labs/")) {
|
|
615
628
|
const manifestInfo = await findManifestPath(pkgRoot, pkg);
|
|
616
629
|
if (manifestInfo.path) {
|
|
617
630
|
packageInfos.push({ pkgRoot, pkg, manifestPath: manifestInfo.path });
|
|
618
631
|
}
|
|
619
632
|
} else if (isPlugin) {
|
|
620
|
-
if (config.block?.includes(
|
|
621
|
-
log("debug", `Plugin ${
|
|
633
|
+
if (config.block?.includes(scopedPkgName ?? "")) {
|
|
634
|
+
log("debug", `Plugin ${scopedPkgName} blocked by config`);
|
|
622
635
|
return;
|
|
623
636
|
}
|
|
624
|
-
const isAllowlisted = config.allow?.includes(
|
|
637
|
+
const isAllowlisted = config.allow?.includes(scopedPkgName ?? "") || config.linked?.includes(scopedPkgName ?? "");
|
|
625
638
|
if (!isAllowlisted) {
|
|
626
|
-
log("debug", `Plugin ${
|
|
639
|
+
log("debug", `Plugin ${scopedPkgName} skipped (not allowlisted). Add to kb-labs.config.json plugins.allow or enable via 'kb marketplace enable'`);
|
|
627
640
|
return;
|
|
628
641
|
}
|
|
629
642
|
const manifestInfo = await findManifestPath(pkgRoot, pkg);
|
|
630
643
|
if (manifestInfo.path) {
|
|
631
644
|
if (manifestInfo.deprecated) {
|
|
632
|
-
log("warn", `[DEPRECATED] ${
|
|
645
|
+
log("warn", `[DEPRECATED] ${scopedPkgName} uses legacy manifest path: ${manifestInfo.path}`);
|
|
633
646
|
log("warn", ` \u2192 Migrate to exports["./kb/commands"] or set kb.commandsManifest in package.json`);
|
|
634
647
|
}
|
|
635
|
-
const isLinked = config.linked?.includes(
|
|
648
|
+
const isLinked = config.linked?.includes(scopedPkgName ?? "");
|
|
636
649
|
packageInfos.push({ pkgRoot, pkg, manifestPath: manifestInfo.path, isLinked });
|
|
637
650
|
}
|
|
638
651
|
}
|
|
@@ -645,24 +658,25 @@ async function discoverNodeModules(cwd) {
|
|
|
645
658
|
if (!pkg) {
|
|
646
659
|
return;
|
|
647
660
|
}
|
|
661
|
+
const unscopedPkgName = pkg.name;
|
|
648
662
|
const isPlugin = isPluginPackage(pkg);
|
|
649
663
|
if (isPlugin) {
|
|
650
|
-
if (config.block?.includes(
|
|
651
|
-
log("debug", `Plugin ${
|
|
664
|
+
if (config.block?.includes(unscopedPkgName ?? "")) {
|
|
665
|
+
log("debug", `Plugin ${unscopedPkgName} blocked by config`);
|
|
652
666
|
return;
|
|
653
667
|
}
|
|
654
|
-
const isAllowlisted = config.allow?.includes(
|
|
668
|
+
const isAllowlisted = config.allow?.includes(unscopedPkgName ?? "") || config.linked?.includes(unscopedPkgName ?? "");
|
|
655
669
|
if (!isAllowlisted) {
|
|
656
|
-
log("debug", `Plugin ${
|
|
670
|
+
log("debug", `Plugin ${unscopedPkgName} skipped (not allowlisted). Add to kb-labs.config.json plugins.allow or enable via 'kb marketplace enable'`);
|
|
657
671
|
return;
|
|
658
672
|
}
|
|
659
673
|
const manifestInfo = await findManifestPath(pkgRoot, pkg);
|
|
660
674
|
if (manifestInfo.path) {
|
|
661
675
|
if (manifestInfo.deprecated) {
|
|
662
|
-
log("warn", `[DEPRECATED] ${
|
|
676
|
+
log("warn", `[DEPRECATED] ${unscopedPkgName} uses legacy manifest path: ${manifestInfo.path}`);
|
|
663
677
|
log("warn", ` \u2192 Migrate to exports["./kb/commands"] or set kb.commandsManifest in package.json`);
|
|
664
678
|
}
|
|
665
|
-
const isLinked = config.linked?.includes(
|
|
679
|
+
const isLinked = config.linked?.includes(unscopedPkgName ?? "");
|
|
666
680
|
packageInfos.push({ pkgRoot, pkg, manifestPath: manifestInfo.path, isLinked });
|
|
667
681
|
}
|
|
668
682
|
}
|
|
@@ -672,10 +686,11 @@ async function discoverNodeModules(cwd) {
|
|
|
672
686
|
}
|
|
673
687
|
await Promise.allSettled(scanPromises);
|
|
674
688
|
const loadPromises = packageInfos.map(async ({ pkgRoot, pkg, manifestPath, isLinked }) => {
|
|
689
|
+
const pkgName = pkg.name;
|
|
675
690
|
try {
|
|
676
|
-
const manifests = await loadManifestWithTimeout(manifestPath,
|
|
691
|
+
const manifests = await loadManifestWithTimeout(manifestPath, pkgName, pkgRoot);
|
|
677
692
|
if (manifests.length > 0) {
|
|
678
|
-
validateUniqueIds(manifests,
|
|
693
|
+
validateUniqueIds(manifests, pkgName);
|
|
679
694
|
return {
|
|
680
695
|
manifests,
|
|
681
696
|
source: isLinked ? "linked" : "node_modules",
|
|
@@ -683,27 +698,29 @@ async function discoverNodeModules(cwd) {
|
|
|
683
698
|
// platformRoot === projectRoot so either label is correct; we use
|
|
684
699
|
// platform to reflect where the manifest physically lives.
|
|
685
700
|
scope: "platform",
|
|
686
|
-
packageName:
|
|
701
|
+
packageName: pkgName,
|
|
687
702
|
manifestPath: toPosixPath(manifestPath),
|
|
688
703
|
pkgRoot: toPosixPath(pkgRoot)
|
|
689
704
|
};
|
|
690
705
|
}
|
|
691
706
|
return null;
|
|
692
707
|
} catch (err) {
|
|
708
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
709
|
+
const errCode = err.code ?? "UNKNOWN";
|
|
693
710
|
log("warn", JSON.stringify({
|
|
694
711
|
code: "DISCOVERY_MANIFEST_LOAD_FAIL",
|
|
695
|
-
packageName:
|
|
712
|
+
packageName: pkgName,
|
|
696
713
|
manifestPath: toPosixPath(manifestPath),
|
|
697
|
-
errorCode:
|
|
698
|
-
errorMessage:
|
|
699
|
-
hint:
|
|
714
|
+
errorCode: errCode,
|
|
715
|
+
errorMessage: errMsg,
|
|
716
|
+
hint: errMsg.includes("Cannot find package") ? "Run: kb devlink apply && pnpm -w build" : "Check manifest syntax and dependencies"
|
|
700
717
|
}));
|
|
701
|
-
const synthetic = createUnavailableManifest(
|
|
718
|
+
const synthetic = createUnavailableManifest(pkgName, err);
|
|
702
719
|
return {
|
|
703
720
|
manifests: [synthetic],
|
|
704
721
|
source: isLinked ? "linked" : "node_modules",
|
|
705
722
|
scope: "platform",
|
|
706
|
-
packageName:
|
|
723
|
+
packageName: pkgName,
|
|
707
724
|
manifestPath: toPosixPath(manifestPath),
|
|
708
725
|
pkgRoot: toPosixPath(pkgRoot)
|
|
709
726
|
};
|
|
@@ -718,7 +735,7 @@ async function discoverNodeModules(cwd) {
|
|
|
718
735
|
}
|
|
719
736
|
return results;
|
|
720
737
|
} catch (err) {
|
|
721
|
-
log("debug", `Could not scan node_modules: ${err.message}`);
|
|
738
|
+
log("debug", `Could not scan node_modules: ${err instanceof Error ? err.message : String(err)}`);
|
|
722
739
|
return [];
|
|
723
740
|
}
|
|
724
741
|
}
|
|
@@ -742,14 +759,14 @@ function deduplicateManifests(all) {
|
|
|
742
759
|
byPackageName.set(result.packageName, projectEntry);
|
|
743
760
|
continue;
|
|
744
761
|
}
|
|
745
|
-
const winner = existing.scope === "
|
|
746
|
-
const loser = existing.scope === "
|
|
747
|
-
log("
|
|
748
|
-
code: "
|
|
762
|
+
const winner = existing.scope === "project" ? existing : result;
|
|
763
|
+
const loser = existing.scope === "project" ? result : existing;
|
|
764
|
+
log("debug", JSON.stringify({
|
|
765
|
+
code: "DISCOVERY_SCOPE_OVERRIDE",
|
|
749
766
|
packageName: result.packageName,
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
message: "Package exists in both platform and project scopes \u2014
|
|
767
|
+
projectPath: winner.pkgRoot,
|
|
768
|
+
platformPath: loser.pkgRoot,
|
|
769
|
+
message: "Package exists in both platform and project scopes \u2014 project wins."
|
|
753
770
|
}));
|
|
754
771
|
byPackageName.set(result.packageName, winner);
|
|
755
772
|
continue;
|
|
@@ -842,7 +859,7 @@ async function isPackageCacheStale(entry, options) {
|
|
|
842
859
|
return true;
|
|
843
860
|
}
|
|
844
861
|
} catch (error) {
|
|
845
|
-
log("debug", `Package cache invalidated: missing package.json for ${entry.result.packageName} (${error
|
|
862
|
+
log("debug", `Package cache invalidated: missing package.json for ${entry.result.packageName} (${error instanceof Error ? error.message : "unknown"})`);
|
|
846
863
|
return true;
|
|
847
864
|
}
|
|
848
865
|
let manifestStat;
|
|
@@ -853,7 +870,7 @@ async function isPackageCacheStale(entry, options) {
|
|
|
853
870
|
return true;
|
|
854
871
|
}
|
|
855
872
|
} catch (error) {
|
|
856
|
-
log("debug", `Package cache invalidated: manifest deleted for ${entry.result.packageName} (${error
|
|
873
|
+
log("debug", `Package cache invalidated: manifest deleted for ${entry.result.packageName} (${error instanceof Error ? error.message : "unknown"})`);
|
|
857
874
|
return true;
|
|
858
875
|
}
|
|
859
876
|
if (options.validateHash) {
|
|
@@ -864,7 +881,7 @@ async function isPackageCacheStale(entry, options) {
|
|
|
864
881
|
return true;
|
|
865
882
|
}
|
|
866
883
|
} catch (error) {
|
|
867
|
-
log("debug", `Package cache hash validation failed for ${entry.result.packageName}: ${error
|
|
884
|
+
log("debug", `Package cache hash validation failed for ${entry.result.packageName}: ${error instanceof Error ? error.message : "unknown"}`);
|
|
868
885
|
return true;
|
|
869
886
|
}
|
|
870
887
|
}
|
|
@@ -910,7 +927,7 @@ async function saveCache(cwd, results, roots) {
|
|
|
910
927
|
stateHasher.update(result.packageName);
|
|
911
928
|
stateHasher.update(manifestHash);
|
|
912
929
|
} catch (err) {
|
|
913
|
-
log("debug", `Failed to cache package ${result.packageName}: ${err.message}`);
|
|
930
|
+
log("debug", `Failed to cache package ${result.packageName}: ${err instanceof Error ? err.message : String(err)}`);
|
|
914
931
|
}
|
|
915
932
|
}
|
|
916
933
|
const lockfileHash = await computeLockfileHash(cwd);
|
|
@@ -953,7 +970,7 @@ async function saveCache(cwd, results, roots) {
|
|
|
953
970
|
try {
|
|
954
971
|
await promises.writeFile(cachePath, JSON.stringify(cache), "utf8");
|
|
955
972
|
} catch (err) {
|
|
956
|
-
log("debug", `Failed to save cache: ${err.message}`);
|
|
973
|
+
log("debug", `Failed to save cache: ${err instanceof Error ? err.message : String(err)}`);
|
|
957
974
|
}
|
|
958
975
|
}
|
|
959
976
|
async function discoverManifests(cwd, noCache = false, options = {}) {
|
|
@@ -1046,8 +1063,21 @@ async function discoverManifests(cwd, noCache = false, options = {}) {
|
|
|
1046
1063
|
if (projectLocal.length > 0) {
|
|
1047
1064
|
log("info", `Discovered ${projectLocal.length} project-local plugins`);
|
|
1048
1065
|
}
|
|
1066
|
+
let projectWorkspace = [];
|
|
1067
|
+
if (roots.projectRoot !== roots.platformRoot) {
|
|
1068
|
+
try {
|
|
1069
|
+
const pwStart = Date.now();
|
|
1070
|
+
const raw = await discoverWorkspace(roots.projectRoot);
|
|
1071
|
+
projectWorkspace = raw.map((r) => ({ ...r, scope: "project" }));
|
|
1072
|
+
timings.projectWorkspace = Date.now() - pwStart;
|
|
1073
|
+
if (projectWorkspace.length > 0) {
|
|
1074
|
+
log("info", `Discovered ${projectWorkspace.length} project workspace packages with CLI manifests`);
|
|
1075
|
+
}
|
|
1076
|
+
} catch {
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1049
1079
|
const dedupStart = Date.now();
|
|
1050
|
-
const results = deduplicateManifests([...workspace, ...installed, ...projectLocal]);
|
|
1080
|
+
const results = deduplicateManifests([...workspace, ...installed, ...projectLocal, ...projectWorkspace]);
|
|
1051
1081
|
timings.deduplicate = Date.now() - dedupStart;
|
|
1052
1082
|
const saveStart = Date.now();
|
|
1053
1083
|
await saveCache(cwd, results, roots);
|
|
@@ -1773,11 +1803,12 @@ var diag = defineSystemCommand({
|
|
|
1773
1803
|
}
|
|
1774
1804
|
});
|
|
1775
1805
|
} catch (err) {
|
|
1806
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
1776
1807
|
diagnostics.push({
|
|
1777
1808
|
category: "marketplace",
|
|
1778
1809
|
status: "error",
|
|
1779
|
-
message: `Discovery failed: ${
|
|
1780
|
-
details: { error:
|
|
1810
|
+
message: `Discovery failed: ${errMsg}`,
|
|
1811
|
+
details: { error: errMsg }
|
|
1781
1812
|
});
|
|
1782
1813
|
}
|
|
1783
1814
|
try {
|
|
@@ -1806,11 +1837,12 @@ var diag = defineSystemCommand({
|
|
|
1806
1837
|
});
|
|
1807
1838
|
}
|
|
1808
1839
|
} catch (err) {
|
|
1840
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
1809
1841
|
diagnostics.push({
|
|
1810
1842
|
category: "cache",
|
|
1811
1843
|
status: "warning",
|
|
1812
|
-
message: `Cache check failed: ${
|
|
1813
|
-
details: { error:
|
|
1844
|
+
message: `Cache check failed: ${errMsg}`,
|
|
1845
|
+
details: { error: errMsg }
|
|
1814
1846
|
});
|
|
1815
1847
|
}
|
|
1816
1848
|
try {
|
|
@@ -1833,11 +1865,12 @@ var diag = defineSystemCommand({
|
|
|
1833
1865
|
});
|
|
1834
1866
|
}
|
|
1835
1867
|
} catch (err) {
|
|
1868
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
1836
1869
|
diagnostics.push({
|
|
1837
1870
|
category: "marketplace-lock",
|
|
1838
1871
|
status: "error",
|
|
1839
|
-
message: `Marketplace lock check failed: ${
|
|
1840
|
-
details: { error:
|
|
1872
|
+
message: `Marketplace lock check failed: ${errMsg}`,
|
|
1873
|
+
details: { error: errMsg }
|
|
1841
1874
|
});
|
|
1842
1875
|
}
|
|
1843
1876
|
const versionIssues = [];
|
|
@@ -1877,11 +1910,12 @@ var diag = defineSystemCommand({
|
|
|
1877
1910
|
});
|
|
1878
1911
|
}
|
|
1879
1912
|
} catch (err) {
|
|
1913
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
1880
1914
|
diagnostics.push({
|
|
1881
1915
|
category: "versions",
|
|
1882
1916
|
status: "error",
|
|
1883
|
-
message: `Version check failed: ${
|
|
1884
|
-
details: { error:
|
|
1917
|
+
message: `Version check failed: ${errMsg}`,
|
|
1918
|
+
details: { error: errMsg }
|
|
1885
1919
|
});
|
|
1886
1920
|
}
|
|
1887
1921
|
const summary = {
|
|
@@ -1915,7 +1949,7 @@ var diag = defineSystemCommand({
|
|
|
1915
1949
|
const icon = diag2.status === "ok" ? safeSymbols.success : diag2.status === "warning" ? safeSymbols.warning : safeSymbols.error;
|
|
1916
1950
|
const colorize = diag2.status === "ok" ? safeColors.success : diag2.status === "warning" ? safeColors.warning : safeColors.error;
|
|
1917
1951
|
diagItems.push(`${icon} ${colorize(safeColors.bold(diag2.category))}: ${diag2.message}`);
|
|
1918
|
-
if (diag2.status === "warning" && diag2.details?.issues) {
|
|
1952
|
+
if (diag2.status === "warning" && Array.isArray(diag2.details?.issues)) {
|
|
1919
1953
|
for (const issue of diag2.details.issues) {
|
|
1920
1954
|
diagItems.push(
|
|
1921
1955
|
` ${safeColors.warning(`\u2192 ${issue.plugin}: requires ${issue.required}, found ${issue.current}`)}`
|
|
@@ -2492,44 +2526,42 @@ var logsDiagnose = defineSystemCommand({
|
|
|
2492
2526
|
ctx.ui.error("Log Diagnose", { sections: [{ header: "Error", items: [result.error ?? "Unknown"] }] });
|
|
2493
2527
|
return;
|
|
2494
2528
|
}
|
|
2495
|
-
const
|
|
2496
|
-
const { summary, topErrors, bySource, period } = data;
|
|
2529
|
+
const { summary, topErrors, bySource, period } = result;
|
|
2497
2530
|
const summaryItems = [
|
|
2498
|
-
`Period: ${period
|
|
2499
|
-
`Total logs: ${summary
|
|
2500
|
-
`Errors: ${summary
|
|
2501
|
-
`Warnings: ${summary
|
|
2502
|
-
`Sources: ${summary
|
|
2531
|
+
`Period: ${period?.from ?? "?"} to ${period?.to ?? "?"}`,
|
|
2532
|
+
`Total logs: ${summary?.total ?? 0}`,
|
|
2533
|
+
`Errors: ${summary?.errors ?? 0}`,
|
|
2534
|
+
`Warnings: ${summary?.warnings ?? 0}`,
|
|
2535
|
+
`Sources: ${summary?.sources.join(", ") || "none"}`
|
|
2503
2536
|
];
|
|
2504
2537
|
const sections = [
|
|
2505
2538
|
{ header: "Summary", items: summaryItems }
|
|
2506
2539
|
];
|
|
2507
|
-
if (topErrors
|
|
2540
|
+
if ((topErrors?.length ?? 0) > 0) {
|
|
2508
2541
|
sections.push({
|
|
2509
2542
|
header: "Top Errors",
|
|
2510
|
-
items: topErrors.slice(0, 5).map(
|
|
2543
|
+
items: (topErrors ?? []).slice(0, 5).map(
|
|
2511
2544
|
(e, i) => `${i + 1}. "${e.message}" (${e.count}x) [${e.source}]`
|
|
2512
2545
|
)
|
|
2513
2546
|
});
|
|
2514
2547
|
}
|
|
2515
2548
|
const sourceItems = [];
|
|
2516
|
-
for (const [src, breakdown] of Object.entries(bySource)) {
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
sourceItems.push(`${src}: ${b.errors} errors, ${b.warnings} warnings`);
|
|
2549
|
+
for (const [src, breakdown] of Object.entries(bySource ?? {})) {
|
|
2550
|
+
if (breakdown.errors > 0 || breakdown.warnings > 0) {
|
|
2551
|
+
sourceItems.push(`${src}: ${breakdown.errors} errors, ${breakdown.warnings} warnings`);
|
|
2520
2552
|
}
|
|
2521
2553
|
}
|
|
2522
2554
|
if (sourceItems.length > 0) {
|
|
2523
2555
|
sections.push({ header: "By Source", items: sourceItems });
|
|
2524
2556
|
}
|
|
2525
|
-
if (summary
|
|
2557
|
+
if ((summary?.errors ?? 0) === 0 && (summary?.warnings ?? 0) === 0) {
|
|
2526
2558
|
ctx.ui.success("Log Diagnosis", { sections });
|
|
2527
|
-
} else if (summary
|
|
2559
|
+
} else if ((summary?.errors ?? 0) > 0) {
|
|
2528
2560
|
ctx.ui.error("Log Diagnosis", { sections });
|
|
2529
2561
|
} else {
|
|
2530
2562
|
ctx.ui.warn("Log Diagnosis", { sections });
|
|
2531
2563
|
}
|
|
2532
|
-
const raw =
|
|
2564
|
+
const raw = result._raw ?? [];
|
|
2533
2565
|
const errorLogs = raw.filter((l) => l.level === "error" || l.level === "fatal").slice(0, 5);
|
|
2534
2566
|
if (errorLogs.length > 0) {
|
|
2535
2567
|
ctx.ui.write("\nRecent Errors:\n");
|
|
@@ -2610,8 +2642,9 @@ var logsContext = defineSystemCommand({
|
|
|
2610
2642
|
};
|
|
2611
2643
|
},
|
|
2612
2644
|
formatter(result, ctx, flags) {
|
|
2645
|
+
const data = result;
|
|
2613
2646
|
if (flags.json) {
|
|
2614
|
-
const { _raw, ...jsonResult } =
|
|
2647
|
+
const { _raw: _ignored, ...jsonResult } = data;
|
|
2615
2648
|
ctx.ui.json(jsonResult);
|
|
2616
2649
|
return;
|
|
2617
2650
|
}
|
|
@@ -2619,19 +2652,18 @@ var logsContext = defineSystemCommand({
|
|
|
2619
2652
|
ctx.ui.error("Log Context", { sections: [{ header: "Error", items: [result.error ?? "Unknown"] }] });
|
|
2620
2653
|
return;
|
|
2621
2654
|
}
|
|
2622
|
-
const data = result;
|
|
2623
2655
|
const { timeline, correlationKey, byLevel } = data;
|
|
2624
|
-
const raw = data._raw;
|
|
2625
|
-
const keyStr = Object.entries(correlationKey).map(([k, v]) => `${k}=${v}`).join(", ");
|
|
2626
|
-
const durationStr = timeline.durationMs > 0 ? `${timeline.durationMs}ms` : "instant";
|
|
2656
|
+
const raw = data._raw ?? [];
|
|
2657
|
+
const keyStr = correlationKey ? Object.entries(correlationKey).map(([k, v]) => `${k}=${v}`).join(", ") : "";
|
|
2658
|
+
const durationStr = timeline && timeline.durationMs > 0 ? `${timeline.durationMs}ms` : "instant";
|
|
2627
2659
|
ctx.ui.success("Execution Context", {
|
|
2628
2660
|
sections: [{
|
|
2629
2661
|
header: `${keyStr}`,
|
|
2630
2662
|
items: [
|
|
2631
|
-
`Total events: ${timeline
|
|
2663
|
+
`Total events: ${timeline?.total ?? 0}`,
|
|
2632
2664
|
`Duration: ${durationStr}`,
|
|
2633
|
-
`Time: ${timeline
|
|
2634
|
-
`Levels: ${Object.entries(byLevel).map(([k, v]) => `${k}=${v}`).join(", ")}`
|
|
2665
|
+
`Time: ${timeline?.from ?? "N/A"} \u2192 ${timeline?.to ?? "N/A"}`,
|
|
2666
|
+
`Levels: ${byLevel ? Object.entries(byLevel).map(([k, v]) => `${k}=${v}`).join(", ") : ""}`
|
|
2635
2667
|
]
|
|
2636
2668
|
}]
|
|
2637
2669
|
});
|
|
@@ -2801,13 +2833,12 @@ var logsSummarize = defineSystemCommand({
|
|
|
2801
2833
|
ctx.ui.error("Log Summarize", { sections: [{ header: "Error", items: [result.error ?? "Unknown"] }] });
|
|
2802
2834
|
return;
|
|
2803
2835
|
}
|
|
2804
|
-
|
|
2805
|
-
ctx.ui.write(`Question: ${data.question}
|
|
2836
|
+
ctx.ui.write(`Question: ${result.question}
|
|
2806
2837
|
`);
|
|
2807
|
-
ctx.ui.write(`${
|
|
2838
|
+
ctx.ui.write(`${result.llmUsed ? "(AI-powered)" : "(Statistical fallback)"}
|
|
2808
2839
|
|
|
2809
2840
|
`);
|
|
2810
|
-
ctx.ui.write(
|
|
2841
|
+
ctx.ui.write((result.summary ?? "") + "\n");
|
|
2811
2842
|
}
|
|
2812
2843
|
});
|
|
2813
2844
|
var logsQuery = defineSystemCommand({
|
|
@@ -3002,12 +3033,15 @@ var logsGet = defineSystemCommand({
|
|
|
3002
3033
|
const rawLog = result._rawLog;
|
|
3003
3034
|
const logJson = result.log;
|
|
3004
3035
|
const keys = result.correlationKeys;
|
|
3036
|
+
if (!rawLog || !logJson || !keys) {
|
|
3037
|
+
return;
|
|
3038
|
+
}
|
|
3005
3039
|
ctx.ui.write(formatLogLine(rawLog) + "\n\n");
|
|
3006
3040
|
const details = [
|
|
3007
|
-
`ID: ${logJson
|
|
3008
|
-
`Time: ${logJson
|
|
3009
|
-
`Level: ${logJson
|
|
3010
|
-
`Source: ${logJson
|
|
3041
|
+
`ID: ${logJson["id"]}`,
|
|
3042
|
+
`Time: ${logJson["time"]}`,
|
|
3043
|
+
`Level: ${logJson["level"]}`,
|
|
3044
|
+
`Source: ${logJson["source"]}`
|
|
3011
3045
|
];
|
|
3012
3046
|
if (keys.traceId) {
|
|
3013
3047
|
details.push(`Trace ID: ${keys.traceId}`);
|
|
@@ -3022,18 +3056,18 @@ var logsGet = defineSystemCommand({
|
|
|
3022
3056
|
details.push(`Session ID: ${keys.sessionId}`);
|
|
3023
3057
|
}
|
|
3024
3058
|
const fieldsToShow = { ...rawLog.fields };
|
|
3025
|
-
delete fieldsToShow
|
|
3026
|
-
delete fieldsToShow
|
|
3027
|
-
delete fieldsToShow
|
|
3028
|
-
delete fieldsToShow
|
|
3029
|
-
delete fieldsToShow
|
|
3030
|
-
delete fieldsToShow
|
|
3031
|
-
delete fieldsToShow
|
|
3059
|
+
delete fieldsToShow["level"];
|
|
3060
|
+
delete fieldsToShow["time"];
|
|
3061
|
+
delete fieldsToShow["traceId"];
|
|
3062
|
+
delete fieldsToShow["executionId"];
|
|
3063
|
+
delete fieldsToShow["requestId"];
|
|
3064
|
+
delete fieldsToShow["reqId"];
|
|
3065
|
+
delete fieldsToShow["sessionId"];
|
|
3032
3066
|
if (Object.keys(fieldsToShow).length > 0) {
|
|
3033
3067
|
details.push(`Fields: ${JSON.stringify(fieldsToShow, null, 2)}`);
|
|
3034
3068
|
}
|
|
3035
3069
|
ctx.ui.success("Log Detail", { sections: [{ header: "Info", items: details }] });
|
|
3036
|
-
const related = result
|
|
3070
|
+
const { related } = result;
|
|
3037
3071
|
if (related && related.length > 0) {
|
|
3038
3072
|
ctx.ui.write(`
|
|
3039
3073
|
Related Logs (${related.length}):
|
|
@@ -3606,7 +3640,7 @@ function checkRequires(manifest, options = {}) {
|
|
|
3606
3640
|
if (isInMonorepo) {
|
|
3607
3641
|
continue;
|
|
3608
3642
|
}
|
|
3609
|
-
const errorMessage = err.message || "";
|
|
3643
|
+
const errorMessage = (err instanceof Error ? err.message : "") || "";
|
|
3610
3644
|
const hasExportsError = errorMessage.includes("exports") || errorMessage.includes("main");
|
|
3611
3645
|
if (hasExportsError || errorMessage.includes("Cannot resolve")) {
|
|
3612
3646
|
const parts = dep.startsWith("@") ? dep.slice(1).split("/") : [dep];
|
|
@@ -3783,7 +3817,7 @@ function preflightManifests(discoveryResults, logger) {
|
|
|
3783
3817
|
validateManifestStructure(manifest);
|
|
3784
3818
|
allowed.push(manifest);
|
|
3785
3819
|
} catch (error) {
|
|
3786
|
-
const reason = error
|
|
3820
|
+
const reason = error instanceof Error ? error.message : "Validation failed";
|
|
3787
3821
|
const manifestId = manifest?.id || manifest?.group || result.packageName || "unknown";
|
|
3788
3822
|
skipped.push({
|
|
3789
3823
|
id: manifestId,
|
|
@@ -3828,7 +3862,7 @@ async function registerManifests(discoveryResults, registry2, options = {}) {
|
|
|
3828
3862
|
try {
|
|
3829
3863
|
validateManifestStructure(manifest);
|
|
3830
3864
|
} catch (err) {
|
|
3831
|
-
throw new Error(`Validation failed: ${err.message}`);
|
|
3865
|
+
throw new Error(`Validation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
3832
3866
|
}
|
|
3833
3867
|
const normalizedId = normalizeCommandId(manifest.id, namespace);
|
|
3834
3868
|
if (normalizedId !== manifest.id) {
|
|
@@ -3875,7 +3909,8 @@ async function registerManifests(discoveryResults, registry2, options = {}) {
|
|
|
3875
3909
|
cmd._disposeHook = manifestModule.dispose;
|
|
3876
3910
|
}
|
|
3877
3911
|
} catch (hookError) {
|
|
3878
|
-
|
|
3912
|
+
const hookMsg = hookError instanceof Error ? hookError.message : String(hookError);
|
|
3913
|
+
log3.debug(`Lifecycle hooks unavailable for ${manifest.id}: ${hookMsg}`);
|
|
3879
3914
|
}
|
|
3880
3915
|
const canonicalKey = manifest.group ? `${manifest.group}:${manifest.id}` : manifest.id;
|
|
3881
3916
|
const existing = globalIds.get(canonicalKey);
|
|
@@ -3945,7 +3980,7 @@ async function registerManifests(discoveryResults, registry2, options = {}) {
|
|
|
3945
3980
|
registered.push(cmd);
|
|
3946
3981
|
} catch (error) {
|
|
3947
3982
|
errors++;
|
|
3948
|
-
const reason = error
|
|
3983
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
3949
3984
|
skipped.push({
|
|
3950
3985
|
id: manifestId,
|
|
3951
3986
|
source: result.source,
|
|
@@ -3977,11 +4012,9 @@ async function disposeAllPlugins(registry2, logger) {
|
|
|
3977
4012
|
const disposeHook = cmd._disposeHook;
|
|
3978
4013
|
if (disposeHook && typeof disposeHook === "function") {
|
|
3979
4014
|
disposePromises.push(
|
|
3980
|
-
Promise.resolve(disposeHook({
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
})).catch((err) => {
|
|
3984
|
-
log3.warn(`Dispose hook failed for ${cmd.manifest.id}: ${err.message}`);
|
|
4015
|
+
Promise.resolve(disposeHook()).catch((err) => {
|
|
4016
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
4017
|
+
log3.warn(`Dispose hook failed for ${cmd.manifest.id}: ${errMsg}`);
|
|
3985
4018
|
})
|
|
3986
4019
|
);
|
|
3987
4020
|
}
|
|
@@ -4086,7 +4119,7 @@ async function registerBuiltinCommands(input = {}) {
|
|
|
4086
4119
|
registry.markPartial(false);
|
|
4087
4120
|
}
|
|
4088
4121
|
} catch (err) {
|
|
4089
|
-
log3.warn(`Discovery failed: ${err.message}`);
|
|
4122
|
+
log3.warn(`Discovery failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
4090
4123
|
registry.markPartial(true);
|
|
4091
4124
|
_registered = false;
|
|
4092
4125
|
return;
|