pi2dsh 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +29 -19
  2. package/README.zh.md +29 -19
  3. package/dist/build-DsGYAgiT.mjs +4416 -0
  4. package/dist/build-DsGYAgiT.mjs.map +1 -0
  5. package/dist/cli.mjs +2 -2
  6. package/dist/compat/pi-ai.d.mts +186 -2435
  7. package/dist/compat/pi-ai.d.mts.map +1 -1
  8. package/dist/compat/pi-ai.mjs +2771 -4520
  9. package/dist/compat/pi-ai.mjs.map +1 -1
  10. package/dist/compat/pi-coding-agent.d.mts +333 -14
  11. package/dist/compat/pi-coding-agent.d.mts.map +1 -1
  12. package/dist/compat/pi-coding-agent.mjs +2 -2
  13. package/dist/compat/pi-tui.mjs +1 -3620
  14. package/dist/host.mjs +2 -2
  15. package/dist/index.d.mts.map +1 -1
  16. package/dist/index.mjs +2 -2
  17. package/dist/{mcp-config-jL9w70It.mjs → mcp-config-gqg7GJEE.mjs} +115 -51
  18. package/dist/mcp-config-gqg7GJEE.mjs.map +1 -0
  19. package/dist/pi-coding-agent-Z1hTs61i.mjs +5203 -0
  20. package/dist/pi-coding-agent-Z1hTs61i.mjs.map +1 -0
  21. package/dist/pi-tui-5CYLcj-_.mjs +4512 -0
  22. package/dist/pi-tui-5CYLcj-_.mjs.map +1 -0
  23. package/dist/pi-types-BLt46jaf.d.mts +2494 -0
  24. package/dist/pi-types-BLt46jaf.d.mts.map +1 -0
  25. package/dist/{rolldown-runtime-C2Q2p085.mjs → rolldown-runtime-D-uZhY3_.mjs} +3 -2
  26. package/dist/{runtime-D84Hv_3m.mjs → runtime-oLd2EInK.mjs} +690 -25
  27. package/dist/runtime-oLd2EInK.mjs.map +1 -0
  28. package/dist/runtime.d.mts.map +1 -1
  29. package/dist/runtime.mjs +1 -1
  30. package/dist/{source-D7Ir-rPT.mjs → source-0sA5z08z.mjs} +6 -2
  31. package/dist/source-0sA5z08z.mjs.map +1 -0
  32. package/package.json +4 -1
  33. package/dist/compat/pi-tui.mjs.map +0 -1
  34. package/dist/mcp-config-jL9w70It.mjs.map +0 -1
  35. package/dist/pi-coding-agent-Dsg6_0ua.mjs +0 -2060
  36. package/dist/pi-coding-agent-Dsg6_0ua.mjs.map +0 -1
  37. package/dist/pi-tui-utils-CcaVtm-3.mjs +0 -895
  38. package/dist/pi-tui-utils-CcaVtm-3.mjs.map +0 -1
  39. package/dist/pi-types-KazmR2O5.d.mts +0 -62
  40. package/dist/pi-types-KazmR2O5.d.mts.map +0 -1
  41. package/dist/pi-uuid-Db8ShZsK.mjs +0 -47
  42. package/dist/pi-uuid-Db8ShZsK.mjs.map +0 -1
  43. package/dist/runtime-D84Hv_3m.mjs.map +0 -1
  44. package/dist/source-D7Ir-rPT.mjs.map +0 -1
package/dist/host.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
- import { t as applyPiPackage } from "./runtime-D84Hv_3m.mjs";
3
- import { t as resolvePiPackage } from "./source-D7Ir-rPT.mjs";
2
+ import { t as applyPiPackage } from "./runtime-oLd2EInK.mjs";
3
+ import { t as resolvePiPackage } from "./source-0sA5z08z.mjs";
4
4
  import { createRequire } from "node:module";
5
5
  import { cp, mkdir, readFile, readdir, stat, writeFile } from "node:fs/promises";
6
6
  import { basename, dirname, join, relative } from "node:path";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/analyzer.ts","../src/compatibility.ts","../src/generator.ts","../src/mcp-config.ts","../src/source.ts"],"mappings":";;;;iBAgbsB,eAAe,KAAK,oBAAoB,QAAQ;;;UC9a5D;EACR,OAAO;EACP;;cAKW;cAKA;cAKA;cASA,mBAAmB,SAAS,eAAe,SAAS,eAAe;cAoMnE,eAAe,SAAS,eAAe;cA2BvC,kBAAkB,SAAS,eAAe;cA+B1C,WAAW,SAAS,eAAe;cAgHnC,aAAa,SAAS,eAAe;iBA6FlC,WAAW,iBAAiB;iBAI5B,aAAa,gBAAgB;iBAO7B,kBAAkB,qBAAqB,uBAAuB;iBAS9D,uBAAuB,mBAAmB;iBAI1C,yBAAyB,mBAAmB;;;iBChMtC,eACpB,KAAK,mBACL,SAAS,kBACR;EAAU;EAAgB,QAAQ;EAAqB;;;;KCrTrD,gBAAgB;UAEJ;EACf;EACA;EACA;EACA;EACA;EACA,MAAM;EACN;EACA;EACA,UAAU;EACV;;UAGe;EACf;EACA;;UAGe;EACf,SAAS;EACT,SAAS;EACT,UAAU;EACV;;iBA6Cc,oBAAoB,aAAa;EAA8B,SAAS,YAAY;EAAc;;iBAoElG,mBAAmB,aAAa,wBAA4B;;iBAsD5D,eAAe,QAAQ;;;iBClFjB,iBAAiB,gBAAgB,eAAsB,QAAQ"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/analyzer.ts","../src/compatibility.ts","../src/generator.ts","../src/mcp-config.ts","../src/source.ts"],"mappings":";;;;iBAgbsB,eAAe,KAAK,oBAAoB,QAAQ;;;UC9a5D;EACR,OAAO;EACP;;cAKW;cAKA;cAKA;cASA,mBAAmB,SAAS,eAAe,SAAS,eAAe;cAoMnE,eAAe,SAAS,eAAe;cA2BvC,kBAAkB,SAAS,eAAe;cA+B1C,WAAW,SAAS,eAAe;cAgHnC,aAAa,SAAS,eAAe;iBA6FlC,WAAW,iBAAiB;iBAI5B,aAAa,gBAAgB;iBAO7B,kBAAkB,qBAAqB,uBAAuB;iBAS9D,uBAAuB,mBAAmB;iBAI1C,yBAAyB,mBAAmB;;;iBC/KtC,eACpB,KAAK,mBACL,SAAS,kBACR;EAAU;EAAgB,QAAQ;EAAqB;;;;KCtUrD,gBAAgB;UAEJ;EACf;EACA;EACA;EACA;EACA;EACA,MAAM;EACN;EACA;EACA,UAAU;EACV;;UAGe;EACf;EACA;;UAGe;EACf,SAAS;EACT,SAAS;EACT,UAAU;EACV;;iBA6Cc,oBAAoB,aAAa;EAA8B,SAAS,YAAY;EAAc;;iBAoElG,mBAAmB,aAAa,wBAA4B;;iBAsD5D,eAAe,QAAQ;;;iBC5EjB,iBAAiB,gBAAgB,eAAsB,QAAQ"}
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- import { _ as ruleForHostImport, a as analyzePackage, c as EVENT_RULES, d as PI_CODING_AGENT_PACKAGES, f as PI_TUI_PACKAGES, g as ruleForEvent, h as ruleForContextProperty, i as generateBundle, l as HOST_IMPORT_RULES, m as ruleForApi, n as convertPiMcpConfig, o as API_RULES, p as UI_CONTEXT_RULES, r as renderMcpPatch, s as CONTEXT_RULES, t as collectPiMcpServers, u as PI_AI_PACKAGES, v as ruleForUiContextProperty } from "./mcp-config-jL9w70It.mjs";
3
- import { t as resolvePiPackage } from "./source-D7Ir-rPT.mjs";
2
+ import { _ as ruleForHostImport, a as analyzePackage, c as EVENT_RULES, d as PI_CODING_AGENT_PACKAGES, f as PI_TUI_PACKAGES, g as ruleForEvent, h as ruleForContextProperty, i as generateBundle, l as HOST_IMPORT_RULES, m as ruleForApi, n as convertPiMcpConfig, o as API_RULES, p as UI_CONTEXT_RULES, r as renderMcpPatch, s as CONTEXT_RULES, t as collectPiMcpServers, u as PI_AI_PACKAGES, v as ruleForUiContextProperty } from "./mcp-config-gqg7GJEE.mjs";
3
+ import { t as resolvePiPackage } from "./source-0sA5z08z.mjs";
4
4
  import { applyPiHost, generateHostBundle, manifestForInstalled } from "./host.mjs";
5
5
  export { API_RULES, CONTEXT_RULES, EVENT_RULES, HOST_IMPORT_RULES, PI_AI_PACKAGES, PI_CODING_AGENT_PACKAGES, PI_TUI_PACKAGES, UI_CONTEXT_RULES, analyzePackage, applyPiHost, collectPiMcpServers, convertPiMcpConfig, generateBundle, generateHostBundle, manifestForInstalled, renderMcpPatch, resolvePiPackage, ruleForApi, ruleForContextProperty, ruleForEvent, ruleForHostImport, ruleForUiContextProperty };
@@ -555,11 +555,16 @@ function localReferences(path, text) {
555
555
  const values = /* @__PURE__ */ new Map();
556
556
  const createRequireNames = /* @__PURE__ */ new Set(["createRequire"]);
557
557
  const requireNames = /* @__PURE__ */ new Set(["require"]);
558
- const add = (kind, specifier) => {
559
- if (specifier.startsWith(".") || specifier.startsWith("#")) values.set(`${kind}:${specifier}`, {
558
+ const add = (kind, specifier, lazy) => {
559
+ if (!specifier.startsWith(".") && !specifier.startsWith("#")) return;
560
+ const key = `${kind}:${specifier}`;
561
+ const existing = values.get(key);
562
+ if (existing === void 0) values.set(key, {
560
563
  kind,
561
- specifier
564
+ specifier,
565
+ lazy
562
566
  });
567
+ else if (existing.lazy && !lazy) existing.lazy = false;
563
568
  };
564
569
  function collectRequireAliases(node) {
565
570
  if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier) && (node.moduleSpecifier.text === "node:module" || node.moduleSpecifier.text === "module") && node.importClause?.namedBindings !== void 0 && ts.isNamedImports(node.importClause.namedBindings)) {
@@ -569,14 +574,14 @@ function localReferences(path, text) {
569
574
  }
570
575
  collectRequireAliases(source);
571
576
  function visit(node) {
572
- if ((ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) && node.moduleSpecifier !== void 0 && ts.isStringLiteral(node.moduleSpecifier)) add("module", node.moduleSpecifier.text);
573
- else if (ts.isImportEqualsDeclaration(node) && ts.isExternalModuleReference(node.moduleReference) && ts.isStringLiteral(node.moduleReference.expression)) add("module", node.moduleReference.expression.text);
577
+ if ((ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) && node.moduleSpecifier !== void 0 && ts.isStringLiteral(node.moduleSpecifier)) add("module", node.moduleSpecifier.text, false);
578
+ else if (ts.isImportEqualsDeclaration(node) && ts.isExternalModuleReference(node.moduleReference) && ts.isStringLiteral(node.moduleReference.expression)) add("module", node.moduleReference.expression.text, false);
574
579
  else if (ts.isCallExpression(node) && node.arguments.length > 0 && (node.expression.kind === ts.SyntaxKind.ImportKeyword || ts.isIdentifier(node.expression) && requireNames.has(node.expression.text))) {
575
580
  const specifier = literalModule(node.arguments[0]);
576
- if (specifier !== void 0) add("module", specifier);
581
+ if (specifier !== void 0) add("module", specifier, insideFunctionBody(node));
577
582
  } else if (ts.isNewExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === "URL" && isImportMetaUrl(node.arguments?.[1])) {
578
583
  const specifier = literalModule(node.arguments?.[0]);
579
- if (specifier !== void 0) add("asset", specifier);
584
+ if (specifier !== void 0) add("asset", specifier, false);
580
585
  }
581
586
  ts.forEachChild(node, visit);
582
587
  }
@@ -584,18 +589,41 @@ function localReferences(path, text) {
584
589
  return [...values.values()];
585
590
  }
586
591
  function externalPackage(specifier) {
587
- if (specifier.startsWith(".") || specifier.startsWith("/") || specifier.startsWith("#") || specifier.startsWith("node:") || builtinModules.includes(specifier)) return void 0;
592
+ if (specifier.startsWith(".") || specifier.startsWith("/") || specifier.startsWith("#") || specifier.startsWith("node:") || specifier.startsWith("bun:") || builtinModules.includes(specifier)) return void 0;
588
593
  const parts = specifier.split("/");
589
594
  return specifier.startsWith("@") ? parts.slice(0, 2).join("/") : parts[0];
590
595
  }
596
+ function insideTry(node) {
597
+ let current = node.parent;
598
+ while (current !== void 0) {
599
+ if (ts.isTryStatement(current)) return true;
600
+ if (ts.isFunctionLike(current)) return false;
601
+ current = current.parent;
602
+ }
603
+ return false;
604
+ }
605
+ function insideFunctionBody(node) {
606
+ let current = node.parent;
607
+ while (current !== void 0) {
608
+ if (ts.isFunctionLike(current)) return true;
609
+ current = current.parent;
610
+ }
611
+ return false;
612
+ }
591
613
  function runtimeExternalPackages(path, text) {
592
614
  const source = ts.createSourceFile(path, text, ts.ScriptTarget.Latest, true, sourceKind(path));
593
- const packages = /* @__PURE__ */ new Set();
615
+ const packages = /* @__PURE__ */ new Map();
594
616
  const createRequireNames = /* @__PURE__ */ new Set(["createRequire"]);
595
617
  const requireNames = /* @__PURE__ */ new Set(["require"]);
596
- const add = (specifier) => {
618
+ const add = (specifier, lazy) => {
597
619
  const name = externalPackage(specifier);
598
- if (name !== void 0 && name.length > 0) packages.add(name);
620
+ if (name === void 0 || name.length === 0) return;
621
+ const existing = packages.get(name);
622
+ if (existing === void 0) packages.set(name, {
623
+ name,
624
+ lazy
625
+ });
626
+ else if (existing.lazy && !lazy) existing.lazy = false;
599
627
  };
600
628
  function collectRequireAliases(node) {
601
629
  if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier) && (node.moduleSpecifier.text === "node:module" || node.moduleSpecifier.text === "module") && node.importClause?.namedBindings !== void 0 && ts.isNamedImports(node.importClause.namedBindings)) {
@@ -609,17 +637,19 @@ function runtimeExternalPackages(path, text) {
609
637
  const clause = node.importClause;
610
638
  const named = clause?.namedBindings;
611
639
  const namedImportsAreTypeOnly = named !== void 0 && ts.isNamedImports(named) && named.elements.length > 0 && named.elements.every((element) => element.isTypeOnly);
612
- if (clause === void 0 || !clause.isTypeOnly && (clause.name !== void 0 || !namedImportsAreTypeOnly)) add(node.moduleSpecifier.text);
613
- } else if (ts.isExportDeclaration(node) && !node.isTypeOnly && node.moduleSpecifier !== void 0 && ts.isStringLiteral(node.moduleSpecifier)) add(node.moduleSpecifier.text);
614
- else if (ts.isImportEqualsDeclaration(node) && !node.isTypeOnly && ts.isExternalModuleReference(node.moduleReference) && ts.isStringLiteral(node.moduleReference.expression)) add(node.moduleReference.expression.text);
640
+ if (clause === void 0 || !clause.isTypeOnly && (clause.name !== void 0 || !namedImportsAreTypeOnly)) add(node.moduleSpecifier.text, false);
641
+ } else if (ts.isExportDeclaration(node) && !node.isTypeOnly && node.moduleSpecifier !== void 0 && ts.isStringLiteral(node.moduleSpecifier)) add(node.moduleSpecifier.text, false);
642
+ else if (ts.isImportEqualsDeclaration(node) && !node.isTypeOnly && ts.isExternalModuleReference(node.moduleReference) && ts.isStringLiteral(node.moduleReference.expression)) add(node.moduleReference.expression.text, false);
615
643
  else if (ts.isCallExpression(node) && node.arguments.length > 0 && (node.expression.kind === ts.SyntaxKind.ImportKeyword || ts.isIdentifier(node.expression) && requireNames.has(node.expression.text))) {
616
- const specifier = literalModule(node.arguments[0]);
617
- if (specifier !== void 0) add(specifier);
644
+ if (!insideTry(node)) {
645
+ const specifier = literalModule(node.arguments[0]);
646
+ if (specifier !== void 0) add(specifier, insideFunctionBody(node));
647
+ }
618
648
  }
619
649
  ts.forEachChild(node, visit);
620
650
  }
621
651
  visit(source);
622
- return [...packages];
652
+ return [...packages.values()];
623
653
  }
624
654
  function inside(rootDir, path) {
625
655
  const pathRelative = relative(rootDir, path);
@@ -714,34 +744,56 @@ async function expandAsset(path, rootDir) {
714
744
  return output;
715
745
  }
716
746
  async function collectLocalClosure(rootDir, entries) {
717
- const queue = entries.map((path) => resolve(path));
718
- const closure = /* @__PURE__ */ new Set();
719
- const issues = [];
720
747
  const importsMap = await packageImportsMap(rootDir);
748
+ const graph = /* @__PURE__ */ new Map();
749
+ const issues = [];
750
+ const queue = entries.map((path) => resolve(path));
721
751
  while (queue.length > 0) {
722
752
  const source = queue.shift();
723
- if (closure.has(source)) continue;
753
+ if (graph.has(source)) continue;
724
754
  if (!inside(rootDir, source)) throw new Error(`extension source escapes the Pi package: ${source}`);
725
755
  const info = await lstat(source);
726
756
  if (info.isSymbolicLink()) throw new Error(`refusing to copy symbolic link from Pi package: ${source}`);
727
757
  if (!info.isFile()) throw new Error(`extension closure contains a non-file path: ${source}`);
728
- closure.add(source);
758
+ const edges = [];
759
+ graph.set(source, edges);
729
760
  if (!SCRIPT_EXTENSIONS.has(extname(source))) continue;
730
761
  const text = await readFile(source, "utf8");
731
- for (const reference of localReferences(source, text)) try {
732
- if (reference.kind === "module") queue.push(await resolveModule(source, reference.specifier, rootDir, importsMap));
733
- else queue.push(...await expandAsset(resolve(dirname(source), reference.specifier), rootDir));
734
- } catch (error) {
735
- issues.push({
736
- file: source,
737
- kind: reference.kind,
738
- specifier: reference.specifier,
739
- detail: error instanceof Error ? error.message : String(error)
740
- });
762
+ for (const reference of localReferences(source, text)) {
763
+ const lazy = reference.lazy || reference.kind === "asset";
764
+ try {
765
+ const targets = reference.kind === "module" ? [await resolveModule(source, reference.specifier, rootDir, importsMap)] : await expandAsset(resolve(dirname(source), reference.specifier), rootDir);
766
+ edges.push({
767
+ lazy,
768
+ targets
769
+ });
770
+ queue.push(...targets);
771
+ } catch (error) {
772
+ issues.push({
773
+ file: source,
774
+ kind: reference.kind,
775
+ specifier: reference.specifier,
776
+ detail: error instanceof Error ? error.message : String(error),
777
+ lazy
778
+ });
779
+ }
741
780
  }
742
781
  }
782
+ const loadTimeFiles = /* @__PURE__ */ new Set();
783
+ const loadQueue = entries.map((path) => resolve(path)).filter((path) => graph.has(path));
784
+ while (loadQueue.length > 0) {
785
+ const source = loadQueue.shift();
786
+ if (loadTimeFiles.has(source)) continue;
787
+ loadTimeFiles.add(source);
788
+ for (const edge of graph.get(source) ?? []) {
789
+ if (edge.lazy) continue;
790
+ for (const target of edge.targets) if (!loadTimeFiles.has(target)) loadQueue.push(target);
791
+ }
792
+ }
793
+ for (const issue of issues) if (!loadTimeFiles.has(issue.file)) issue.lazy = true;
743
794
  return {
744
- files: [...closure].sort(),
795
+ files: [...graph.keys()].sort(),
796
+ loadTimeFiles,
745
797
  issues
746
798
  };
747
799
  }
@@ -1021,24 +1073,29 @@ async function analyzePackage(pkg) {
1021
1073
  line: 1,
1022
1074
  detail: "No ExtensionAPI use was statically proven across the local module closure; conversion fails closed instead of claiming compatibility."
1023
1075
  });
1024
- for (const issue of extensionClosure.issues) findings.push({
1025
- capability: `${issue.kind}(${issue.specifier})`,
1026
- level: "fatal",
1027
- file: relative(pkg.rootDir, issue.file).replaceAll("\\", "/"),
1028
- line: 1,
1029
- detail: `The local extension closure is incomplete: ${issue.detail}`
1030
- });
1076
+ for (const issue of extensionClosure.issues) {
1077
+ const lazyIssue = issue.lazy || issue.kind === "asset";
1078
+ findings.push({
1079
+ capability: `${issue.kind}(${issue.specifier})`,
1080
+ level: lazyIssue ? "partial" : "fatal",
1081
+ file: relative(pkg.rootDir, issue.file).replaceAll("\\", "/"),
1082
+ line: 1,
1083
+ detail: lazyIssue ? `Unresolved reference on a lazy path: ${issue.detail}. Extension load is unaffected; if the feature that evaluates it runs, it fails the same way under Pi (published file layout is preserved).` : `The local extension closure is incomplete: ${issue.detail}`
1084
+ });
1085
+ }
1031
1086
  const declaredDependencies = dependencyNames(pkg.packageJson);
1032
1087
  for (const file of extensionClosure.files.filter((candidate) => SCRIPT_EXTENSIONS.has(extname(candidate)))) {
1033
1088
  const text = await readFile(file, "utf8");
1034
- for (const packageName of runtimeExternalPackages(file, text)) {
1035
- if (PI_HOST_PACKAGES.has(packageName) || declaredDependencies.has(packageName)) continue;
1089
+ const lazyFile = !extensionClosure.loadTimeFiles.has(file);
1090
+ for (const use of runtimeExternalPackages(file, text)) {
1091
+ if (PI_HOST_PACKAGES.has(use.name) || declaredDependencies.has(use.name)) continue;
1092
+ const lazyUse = use.lazy || lazyFile;
1036
1093
  findings.push({
1037
- capability: `undeclared-runtime-dependency(${packageName})`,
1038
- level: "fatal",
1094
+ capability: lazyUse ? `optional-lazy-dependency(${use.name})` : `undeclared-runtime-dependency(${use.name})`,
1095
+ level: lazyUse ? "partial" : "fatal",
1039
1096
  file: relative(pkg.rootDir, file).replaceAll("\\", "/"),
1040
1097
  line: 1,
1041
- detail: `The extension imports ${JSON.stringify(packageName)} at runtime, but the Pi package does not declare it as a dependency.`
1098
+ detail: lazyUse ? `The extension imports ${JSON.stringify(use.name)} only on a lazily-evaluated path without declaring it; the feature that needs it asks for the module at call time, exactly as under Pi (install ${use.name} to use that feature).` : `The extension imports ${JSON.stringify(use.name)} at load time, but the Pi package does not declare it as a dependency.`
1042
1099
  });
1043
1100
  }
1044
1101
  }
@@ -1129,11 +1186,12 @@ async function copyExtensions(pkg, outDir) {
1129
1186
  const copied = [];
1130
1187
  const runtimePackages = /* @__PURE__ */ new Set();
1131
1188
  const closure = await collectLocalClosure(pkg.rootDir, pkg.resources.extensions);
1132
- if (closure.issues.length > 0) throw new Error(`cannot snapshot extension closure:\n${closure.issues.map((issue) => `- ${issue.file}: ${issue.detail}`).join("\n")}`);
1189
+ for (const issue of closure.issues) console.warn(`pi2dsh: unresolved ${issue.kind} reference ${JSON.stringify(issue.specifier)} from ${relative(pkg.rootDir, issue.file)} (${issue.lazy ? "lazy path — fails at feature use, as under Pi" : "load-time path"})`);
1133
1190
  for (const source of closure.files) {
1134
1191
  if (SCRIPT_EXTENSIONS.has(extname(source))) {
1135
1192
  const text = await readFile(source, "utf8");
1136
- for (const packageName of runtimeExternalPackages(source, text)) runtimePackages.add(packageName);
1193
+ const lazyFile = !closure.loadTimeFiles.has(source);
1194
+ for (const use of runtimeExternalPackages(source, text)) if (!use.lazy && !lazyFile || use.name in stringRecord$1(pkg.packageJson.dependencies)) runtimePackages.add(use.name);
1137
1195
  }
1138
1196
  const targetRelative = `vendor/${relative(pkg.rootDir, source).replaceAll("\\", "/")}`;
1139
1197
  const target = join(outDir, targetRelative);
@@ -1141,14 +1199,16 @@ async function copyExtensions(pkg, outDir) {
1141
1199
  await cp(source, target, { dereference: false });
1142
1200
  if (pkg.resources.extensions.map((entry) => resolve(entry)).includes(source)) copied.push(targetRelative);
1143
1201
  }
1202
+ const skillScriptPackages = /* @__PURE__ */ new Set();
1144
1203
  for (const source of pkg.resources.skills) {
1145
1204
  if (!SCRIPT_EXTENSIONS.has(extname(source))) continue;
1146
1205
  const text = await readFile(source, "utf8");
1147
- for (const packageName of runtimeExternalPackages(source, text)) runtimePackages.add(packageName);
1206
+ for (const use of runtimeExternalPackages(source, text)) skillScriptPackages.add(use.name);
1148
1207
  }
1149
1208
  return {
1150
1209
  entries: copied,
1151
- runtimePackages
1210
+ runtimePackages,
1211
+ skillScriptPackages
1152
1212
  };
1153
1213
  }
1154
1214
  async function copySkills(pkg, outDir) {
@@ -1230,7 +1290,9 @@ function generatedPackageJson(pkg, generatedName, runtimeSpec, runtimePackages,
1230
1290
  jiti: "^2.7.0",
1231
1291
  "get-east-asian-width": "^1.6.0",
1232
1292
  marked: "^16.4.1",
1233
- typebox: "^1.0.4"
1293
+ typebox: "^1.0.4",
1294
+ "cross-spawn": "^7.0.6",
1295
+ diff: "^9.0.0"
1234
1296
  } : {},
1235
1297
  ...hasSkills ? { "@deepseek-ai/dsh-skill-filesystem": "^0.1.0-rc.6" } : {},
1236
1298
  ...runtimeSpec !== void 0 ? { pi2dsh: runtimeSpec } : {}
@@ -1342,6 +1404,8 @@ async function generateBundle(pkg, options) {
1342
1404
  };
1343
1405
  const runtimeSpec = options.runtimeSpec;
1344
1406
  if (runtimeSpec === void 0) await copyEmbeddedRuntime(outDir);
1407
+ const optionalSkillDeps = [...extensionSnapshot.skillScriptPackages].filter((name) => !SHIMMED_PI_HOST_PACKAGES.has(name) && !(name in stringRecord$1(pkg.packageJson.dependencies)));
1408
+ if (optionalSkillDeps.length > 0) console.warn(`pi2dsh: skill helper scripts reference ${optionalSkillDeps.join(", ")}; install them only if you use those skills`);
1345
1409
  await Promise.all([
1346
1410
  writeFile(join(outDir, "package.json"), `${JSON.stringify(generatedPackageJson(pkg, packageName, runtimeSpec, extensionSnapshot.runtimePackages, skillDirs.length > 0), null, 2)}\n`),
1347
1411
  writeFile(join(outDir, "pi2dsh.manifest.json"), `${JSON.stringify(manifest, null, 2)}\n`),
@@ -1532,4 +1596,4 @@ function renderMcpPatch(result) {
1532
1596
  //#endregion
1533
1597
  export { ruleForHostImport as _, analyzePackage as a, EVENT_RULES as c, PI_CODING_AGENT_PACKAGES as d, PI_TUI_PACKAGES as f, ruleForEvent as g, ruleForContextProperty as h, generateBundle as i, HOST_IMPORT_RULES as l, ruleForApi as m, convertPiMcpConfig as n, API_RULES as o, UI_CONTEXT_RULES as p, renderMcpPatch as r, CONTEXT_RULES as s, collectPiMcpServers as t, PI_AI_PACKAGES as u, ruleForUiContextProperty as v };
1534
1598
 
1535
- //# sourceMappingURL=mcp-config-jL9w70It.mjs.map
1599
+ //# sourceMappingURL=mcp-config-gqg7GJEE.mjs.map