@earendil-works/pi-coding-agent 0.75.4 → 0.76.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 (175) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/README.md +1 -1
  3. package/dist/cli/args.d.ts +1 -0
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +4 -0
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/cli/file-processor.d.ts.map +1 -1
  8. package/dist/cli/file-processor.js +2 -3
  9. package/dist/cli/file-processor.js.map +1 -1
  10. package/dist/config.d.ts.map +1 -1
  11. package/dist/config.js +18 -12
  12. package/dist/config.js.map +1 -1
  13. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  14. package/dist/core/agent-session-runtime.js +2 -1
  15. package/dist/core/agent-session-runtime.js.map +1 -1
  16. package/dist/core/agent-session-services.d.ts.map +1 -1
  17. package/dist/core/agent-session-services.js +3 -2
  18. package/dist/core/agent-session-services.js.map +1 -1
  19. package/dist/core/agent-session.d.ts +1 -0
  20. package/dist/core/agent-session.d.ts.map +1 -1
  21. package/dist/core/agent-session.js +8 -2
  22. package/dist/core/agent-session.js.map +1 -1
  23. package/dist/core/auth-storage.d.ts.map +1 -1
  24. package/dist/core/auth-storage.js +2 -1
  25. package/dist/core/auth-storage.js.map +1 -1
  26. package/dist/core/compaction/compaction.d.ts.map +1 -1
  27. package/dist/core/compaction/compaction.js +18 -24
  28. package/dist/core/compaction/compaction.js.map +1 -1
  29. package/dist/core/export-html/index.d.ts.map +1 -1
  30. package/dist/core/export-html/index.js +8 -6
  31. package/dist/core/export-html/index.js.map +1 -1
  32. package/dist/core/export-html/template.js +6 -3
  33. package/dist/core/extensions/loader.d.ts.map +1 -1
  34. package/dist/core/extensions/loader.js +12 -29
  35. package/dist/core/extensions/loader.js.map +1 -1
  36. package/dist/core/model-registry.d.ts.map +1 -1
  37. package/dist/core/model-registry.js +5 -1
  38. package/dist/core/model-registry.js.map +1 -1
  39. package/dist/core/output-guard.d.ts +1 -0
  40. package/dist/core/output-guard.d.ts.map +1 -1
  41. package/dist/core/output-guard.js +52 -22
  42. package/dist/core/output-guard.js.map +1 -1
  43. package/dist/core/package-manager.d.ts +1 -0
  44. package/dist/core/package-manager.d.ts.map +1 -1
  45. package/dist/core/package-manager.js +63 -36
  46. package/dist/core/package-manager.js.map +1 -1
  47. package/dist/core/prompt-templates.d.ts.map +1 -1
  48. package/dist/core/prompt-templates.js +6 -20
  49. package/dist/core/prompt-templates.js.map +1 -1
  50. package/dist/core/resource-loader.d.ts.map +1 -1
  51. package/dist/core/resource-loader.js +38 -31
  52. package/dist/core/resource-loader.js.map +1 -1
  53. package/dist/core/sdk.d.ts.map +1 -1
  54. package/dist/core/sdk.js +15 -5
  55. package/dist/core/sdk.js.map +1 -1
  56. package/dist/core/session-manager.d.ts +3 -2
  57. package/dist/core/session-manager.d.ts.map +1 -1
  58. package/dist/core/session-manager.js +65 -35
  59. package/dist/core/session-manager.js.map +1 -1
  60. package/dist/core/settings-manager.d.ts +2 -0
  61. package/dist/core/settings-manager.d.ts.map +1 -1
  62. package/dist/core/settings-manager.js +20 -22
  63. package/dist/core/settings-manager.js.map +1 -1
  64. package/dist/core/skills.d.ts.map +1 -1
  65. package/dist/core/skills.js +8 -22
  66. package/dist/core/skills.js.map +1 -1
  67. package/dist/core/tools/bash.d.ts.map +1 -1
  68. package/dist/core/tools/bash.js +54 -53
  69. package/dist/core/tools/bash.js.map +1 -1
  70. package/dist/core/tools/edit-diff.d.ts +3 -1
  71. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  72. package/dist/core/tools/edit-diff.js +8 -1
  73. package/dist/core/tools/edit-diff.js.map +1 -1
  74. package/dist/core/tools/edit.d.ts +3 -1
  75. package/dist/core/tools/edit.d.ts.map +1 -1
  76. package/dist/core/tools/edit.js +44 -81
  77. package/dist/core/tools/edit.js.map +1 -1
  78. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
  79. package/dist/core/tools/file-mutation-queue.js +27 -12
  80. package/dist/core/tools/file-mutation-queue.js.map +1 -1
  81. package/dist/core/tools/find.d.ts.map +1 -1
  82. package/dist/core/tools/find.js +2 -3
  83. package/dist/core/tools/find.js.map +1 -1
  84. package/dist/core/tools/grep.d.ts.map +1 -1
  85. package/dist/core/tools/grep.js +3 -3
  86. package/dist/core/tools/grep.js.map +1 -1
  87. package/dist/core/tools/ls.d.ts.map +1 -1
  88. package/dist/core/tools/ls.js +5 -5
  89. package/dist/core/tools/ls.js.map +1 -1
  90. package/dist/core/tools/output-accumulator.d.ts +2 -0
  91. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  92. package/dist/core/tools/output-accumulator.js +9 -3
  93. package/dist/core/tools/output-accumulator.js.map +1 -1
  94. package/dist/core/tools/path-utils.d.ts +2 -0
  95. package/dist/core/tools/path-utils.d.ts.map +1 -1
  96. package/dist/core/tools/path-utils.js +39 -21
  97. package/dist/core/tools/path-utils.js.map +1 -1
  98. package/dist/core/tools/read.d.ts.map +1 -1
  99. package/dist/core/tools/read.js +9 -8
  100. package/dist/core/tools/read.js.map +1 -1
  101. package/dist/core/tools/truncate.d.ts.map +1 -1
  102. package/dist/core/tools/truncate.js +12 -2
  103. package/dist/core/tools/truncate.js.map +1 -1
  104. package/dist/core/tools/write.d.ts.map +1 -1
  105. package/dist/core/tools/write.js +20 -35
  106. package/dist/core/tools/write.js.map +1 -1
  107. package/dist/main.d.ts.map +1 -1
  108. package/dist/main.js +59 -20
  109. package/dist/main.js.map +1 -1
  110. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  111. package/dist/modes/interactive/components/config-selector.js +1 -1
  112. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  113. package/dist/modes/interactive/components/footer.d.ts +1 -0
  114. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  115. package/dist/modes/interactive/components/footer.js +14 -5
  116. package/dist/modes/interactive/components/footer.js.map +1 -1
  117. package/dist/modes/interactive/components/login-dialog.d.ts +9 -1
  118. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  119. package/dist/modes/interactive/components/login-dialog.js +29 -4
  120. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  121. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  122. package/dist/modes/interactive/components/user-message.js +1 -1
  123. package/dist/modes/interactive/components/user-message.js.map +1 -1
  124. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  125. package/dist/modes/interactive/interactive-mode.js +4 -4
  126. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  127. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  128. package/dist/modes/interactive/theme/theme.js +37 -28
  129. package/dist/modes/interactive/theme/theme.js.map +1 -1
  130. package/dist/modes/rpc/rpc-client.d.ts +3 -0
  131. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  132. package/dist/modes/rpc/rpc-client.js +64 -7
  133. package/dist/modes/rpc/rpc-client.js.map +1 -1
  134. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  135. package/dist/modes/rpc/rpc-mode.js +18 -4
  136. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  137. package/dist/modes/rpc/rpc-types.d.ts +1 -0
  138. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  139. package/dist/modes/rpc/rpc-types.js.map +1 -1
  140. package/dist/utils/clipboard-native.d.ts +3 -1
  141. package/dist/utils/clipboard-native.d.ts.map +1 -1
  142. package/dist/utils/clipboard-native.js +14 -8
  143. package/dist/utils/clipboard-native.js.map +1 -1
  144. package/dist/utils/image-resize-core.d.ts +30 -0
  145. package/dist/utils/image-resize-core.d.ts.map +1 -0
  146. package/dist/utils/image-resize-core.js +124 -0
  147. package/dist/utils/image-resize-core.js.map +1 -0
  148. package/dist/utils/image-resize-worker.d.ts +2 -0
  149. package/dist/utils/image-resize-worker.d.ts.map +1 -0
  150. package/dist/utils/image-resize-worker.js +31 -0
  151. package/dist/utils/image-resize-worker.js.map +1 -0
  152. package/dist/utils/image-resize.d.ts +7 -27
  153. package/dist/utils/image-resize.d.ts.map +1 -1
  154. package/dist/utils/image-resize.js +75 -115
  155. package/dist/utils/image-resize.js.map +1 -1
  156. package/dist/utils/paths.d.ts +15 -1
  157. package/dist/utils/paths.d.ts.map +1 -1
  158. package/dist/utils/paths.js +33 -7
  159. package/dist/utils/paths.js.map +1 -1
  160. package/docs/custom-provider.md +44 -12
  161. package/docs/models.md +8 -2
  162. package/docs/packages.md +5 -4
  163. package/docs/sdk.md +2 -0
  164. package/docs/settings.md +6 -2
  165. package/docs/terminal-setup.md +6 -0
  166. package/docs/usage.md +2 -2
  167. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  168. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  169. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  170. package/examples/extensions/sandbox/package-lock.json +2 -2
  171. package/examples/extensions/sandbox/package.json +1 -1
  172. package/examples/extensions/with-deps/package-lock.json +2 -2
  173. package/examples/extensions/with-deps/package.json +1 -1
  174. package/npm-shrinkwrap.json +13 -26
  175. package/package.json +5 -5
@@ -27,7 +27,7 @@ import { minimatch } from "minimatch";
27
27
  import { CONFIG_DIR_NAME } from "../config.js";
28
28
  import { spawnProcess, spawnProcessSync } from "../utils/child-process.js";
29
29
  import { parseGitUrl } from "../utils/git.js";
30
- import { canonicalizePath, isLocalPath, markPathIgnoredByCloudSync } from "../utils/paths.js";
30
+ import { canonicalizePath, isLocalPath, markPathIgnoredByCloudSync, resolvePath } from "../utils/paths.js";
31
31
  import { isStdoutTakenOver } from "./output-guard.js";
32
32
  const NETWORK_TIMEOUT_MS = 10000;
33
33
  const UPDATE_CHECK_CONCURRENCY = 4;
@@ -577,8 +577,8 @@ export class DefaultPackageManager {
577
577
  globalNpmRootCommandKey;
578
578
  progressCallback;
579
579
  constructor(options) {
580
- this.cwd = options.cwd;
581
- this.agentDir = options.agentDir;
580
+ this.cwd = resolvePath(options.cwd);
581
+ this.agentDir = resolvePath(options.agentDir);
582
582
  this.settingsManager = options.settingsManager;
583
583
  }
584
584
  setProgressCallback(callback) {
@@ -589,9 +589,22 @@ export class DefaultPackageManager {
589
589
  const currentSettings = scope === "project" ? this.settingsManager.getProjectSettings() : this.settingsManager.getGlobalSettings();
590
590
  const currentPackages = currentSettings.packages ?? [];
591
591
  const normalizedSource = this.normalizePackageSourceForSettings(source, scope);
592
- const exists = currentPackages.some((existing) => this.packageSourcesMatch(existing, source, scope));
593
- if (exists) {
594
- return false;
592
+ const matchIndex = currentPackages.findIndex((existing) => this.packageSourcesMatch(existing, source, scope));
593
+ if (matchIndex !== -1) {
594
+ const existing = currentPackages[matchIndex];
595
+ if (this.getPackageSourceString(existing) === normalizedSource) {
596
+ return false;
597
+ }
598
+ const nextPackages = [...currentPackages];
599
+ nextPackages[matchIndex] =
600
+ typeof existing === "string" ? normalizedSource : { ...existing, source: normalizedSource };
601
+ if (scope === "project") {
602
+ this.settingsManager.setProjectPackages(nextPackages);
603
+ }
604
+ else {
605
+ this.settingsManager.setPackages(nextPackages);
606
+ }
607
+ return true;
595
608
  }
596
609
  const nextPackages = [...currentPackages, normalizedSource];
597
610
  if (scope === "project") {
@@ -801,14 +814,16 @@ export class DefaultPackageManager {
801
814
  const gitCandidates = [];
802
815
  for (const entry of sources) {
803
816
  const parsed = this.parseSource(entry.source);
804
- if (parsed.type === "local" || parsed.pinned) {
805
- continue;
806
- }
817
+ // Pinned npm versions are fixed. Pinned git refs are configured checkout targets,
818
+ // so include them to reconcile an existing clone when the configured ref changes.
807
819
  if (parsed.type === "npm") {
808
- npmCandidates.push({ ...entry, parsed });
809
- continue;
820
+ if (!parsed.pinned) {
821
+ npmCandidates.push({ ...entry, parsed });
822
+ }
823
+ }
824
+ else if (parsed.type === "git") {
825
+ gitCandidates.push({ ...entry, parsed });
810
826
  }
811
- gitCandidates.push({ ...entry, parsed });
812
827
  }
813
828
  const npmCheckTasks = npmCandidates.map((entry) => async () => ({
814
829
  entry,
@@ -1383,13 +1398,25 @@ export class DefaultPackageManager {
1383
1398
  }
1384
1399
  getNpmInstallArgs(specs, installRoot) {
1385
1400
  const packageManagerName = this.getPackageManagerName();
1401
+ // Extension packages run inside pi and resolve pi APIs through loader aliases/virtual modules.
1402
+ // Disable peer dependency resolution for managed installs (npm's --legacy-peer-deps, and
1403
+ // equivalent bun/pnpm settings) so package managers do not install or solve host-provided
1404
+ // @earendil-works/pi-* peers. Stale auto-installed pi peers can otherwise block updates.
1386
1405
  if (packageManagerName === "bun") {
1387
- return ["install", ...specs, "--cwd", installRoot];
1406
+ return ["install", ...specs, "--cwd", installRoot, "--omit=peer"];
1388
1407
  }
1389
1408
  if (packageManagerName === "pnpm") {
1390
- return ["install", ...specs, "--prefix", installRoot, "--config.strict-dep-builds=false"];
1391
- }
1392
- return ["install", ...specs, "--prefix", installRoot];
1409
+ return [
1410
+ "install",
1411
+ ...specs,
1412
+ "--prefix",
1413
+ installRoot,
1414
+ "--config.auto-install-peers=false",
1415
+ "--config.strict-peer-dependencies=false",
1416
+ "--config.strict-dep-builds=false",
1417
+ ];
1418
+ }
1419
+ return ["install", ...specs, "--prefix", installRoot, "--legacy-peer-deps"];
1393
1420
  }
1394
1421
  async installNpm(source, scope, temporary) {
1395
1422
  const installRoot = this.getNpmInstallRoot(scope, temporary);
@@ -1410,6 +1437,12 @@ export class DefaultPackageManager {
1410
1437
  async installGit(source, scope) {
1411
1438
  const targetDir = this.getGitInstallPath(source, scope);
1412
1439
  if (existsSync(targetDir)) {
1440
+ if (source.ref) {
1441
+ await this.ensureGitRef(targetDir, ["fetch", "origin", source.ref], "FETCH_HEAD");
1442
+ return;
1443
+ }
1444
+ const target = await this.getLocalGitUpdateTarget(targetDir);
1445
+ await this.ensureGitRef(targetDir, target.fetchArgs, target.ref);
1413
1446
  return;
1414
1447
  }
1415
1448
  const gitRoot = this.getGitInstallRoot(scope);
@@ -1432,21 +1465,29 @@ export class DefaultPackageManager {
1432
1465
  await this.installGit(source, scope);
1433
1466
  return;
1434
1467
  }
1468
+ if (source.ref) {
1469
+ await this.ensureGitRef(targetDir, ["fetch", "origin", source.ref], "FETCH_HEAD");
1470
+ return;
1471
+ }
1435
1472
  const target = await this.getLocalGitUpdateTarget(targetDir);
1473
+ await this.ensureGitRef(targetDir, target.fetchArgs, target.ref);
1474
+ }
1475
+ async ensureGitRef(targetDir, fetchArgs, ref) {
1436
1476
  // Fetch only the ref we will reset to, avoiding unrelated branch/tag noise.
1437
- await this.runCommand("git", target.fetchArgs, { cwd: targetDir });
1477
+ await this.runCommand("git", fetchArgs, { cwd: targetDir });
1438
1478
  const localHead = await this.runCommandCapture("git", ["rev-parse", "HEAD"], {
1439
1479
  cwd: targetDir,
1440
1480
  timeoutMs: NETWORK_TIMEOUT_MS,
1441
1481
  });
1442
- const refreshedTargetHead = await this.runCommandCapture("git", ["rev-parse", target.ref], {
1482
+ const commitRef = `${ref}^{commit}`;
1483
+ const targetHead = await this.runCommandCapture("git", ["rev-parse", commitRef], {
1443
1484
  cwd: targetDir,
1444
1485
  timeoutMs: NETWORK_TIMEOUT_MS,
1445
1486
  });
1446
- if (localHead.trim() === refreshedTargetHead.trim()) {
1487
+ if (localHead.trim() === targetHead.trim()) {
1447
1488
  return;
1448
1489
  }
1449
- await this.runCommand("git", ["reset", "--hard", target.ref], { cwd: targetDir });
1490
+ await this.runCommand("git", ["reset", "--hard", commitRef], { cwd: targetDir });
1450
1491
  // Clean untracked files (extensions should be pristine)
1451
1492
  await this.runCommand("git", ["clean", "-fdx"], { cwd: targetDir });
1452
1493
  const packageJsonPath = join(targetDir, "package.json");
@@ -1616,24 +1657,10 @@ export class DefaultPackageManager {
1616
1657
  return this.cwd;
1617
1658
  }
1618
1659
  resolvePath(input) {
1619
- const trimmed = input.trim();
1620
- if (trimmed === "~")
1621
- return getHomeDir();
1622
- if (trimmed.startsWith("~/"))
1623
- return join(getHomeDir(), trimmed.slice(2));
1624
- if (trimmed.startsWith("~"))
1625
- return join(getHomeDir(), trimmed.slice(1));
1626
- return resolve(this.cwd, trimmed);
1660
+ return resolvePath(input, this.cwd, { homeDir: getHomeDir(), trim: true });
1627
1661
  }
1628
1662
  resolvePathFromBase(input, baseDir) {
1629
- const trimmed = input.trim();
1630
- if (trimmed === "~")
1631
- return getHomeDir();
1632
- if (trimmed.startsWith("~/"))
1633
- return join(getHomeDir(), trimmed.slice(2));
1634
- if (trimmed.startsWith("~"))
1635
- return join(getHomeDir(), trimmed.slice(1));
1636
- return resolve(baseDir, trimmed);
1663
+ return resolvePath(input, baseDir, { homeDir: getHomeDir(), trim: true });
1637
1664
  }
1638
1665
  collectPackageResources(packageRoot, accumulator, filter, metadata) {
1639
1666
  if (filter) {