@psnext/slingcli 2.5.20260607-2 → 2.5.20260615-2

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 (205) hide show
  1. package/node_modules/@aws-sdk/core/dist-cjs/index.js +47 -2297
  2. package/node_modules/@aws-sdk/core/dist-es/index.js +3 -3
  3. package/node_modules/@aws-sdk/core/dist-types/index.d.ts +5 -5
  4. package/node_modules/@aws-sdk/core/dist-types/ts3.4/index.d.ts +5 -5
  5. package/node_modules/@aws-sdk/core/package.json +8 -8
  6. package/node_modules/@aws-sdk/credential-provider-env/package.json +4 -4
  7. package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/package.json +7 -7
  8. package/node_modules/@aws-sdk/credential-provider-http/package.json +6 -5
  9. package/node_modules/@aws-sdk/credential-provider-ini/package.json +11 -11
  10. package/node_modules/@aws-sdk/credential-provider-login/package.json +5 -5
  11. package/node_modules/@aws-sdk/credential-provider-node/package.json +9 -9
  12. package/node_modules/@aws-sdk/credential-provider-process/package.json +4 -4
  13. package/node_modules/@aws-sdk/credential-provider-sso/dist-cjs/index.js +4 -1
  14. package/node_modules/@aws-sdk/credential-provider-sso/dist-es/resolveSSOCredentials.js +4 -1
  15. package/node_modules/@aws-sdk/credential-provider-sso/node_modules/@aws-sdk/token-providers/package.json +5 -5
  16. package/node_modules/@aws-sdk/credential-provider-sso/package.json +9 -7
  17. package/node_modules/@aws-sdk/credential-provider-web-identity/package.json +5 -5
  18. package/node_modules/@aws-sdk/eventstream-handler-node/package.json +3 -3
  19. package/node_modules/@aws-sdk/middleware-eventstream/package.json +3 -3
  20. package/node_modules/@aws-sdk/middleware-websocket/package.json +5 -5
  21. package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/cognito-identity/index.js +1 -1
  22. package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/signin/index.js +1 -1
  23. package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sso/index.js +1 -1
  24. package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sso-oidc/index.js +1 -1
  25. package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sts/index.js +1 -1
  26. package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/package.json +7 -7
  27. package/node_modules/@aws-sdk/nested-clients/package.json +6 -6
  28. package/node_modules/@aws-sdk/signature-v4-multi-region/package.json +7 -6
  29. package/node_modules/@aws-sdk/types/package.json +2 -2
  30. package/node_modules/@aws-sdk/util-locate-window/package.json +2 -2
  31. package/node_modules/@aws-sdk/xml-builder/package.json +2 -2
  32. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +8 -0
  33. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.js +1 -1
  34. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  35. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +6 -6
  36. package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +906 -873
  37. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js +25 -8
  38. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js +19 -12
  39. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.js +1 -0
  40. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js +8 -4
  41. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js +2 -1
  42. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses-shared.js +2 -1
  43. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.js +1 -0
  44. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.js +1 -1
  45. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +3 -2
  46. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  47. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/args.js +3 -5
  48. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/project-trust.js +48 -0
  49. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/startup-ui.js +133 -0
  50. package/node_modules/@earendil-works/pi-coding-agent/dist/config.js +14 -3
  51. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-runtime.js +4 -1
  52. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-services.js +2 -2
  53. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.js +9 -2
  54. package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/utils.js +1 -1
  55. package/node_modules/@earendil-works/pi-coding-agent/dist/core/experimental.js +4 -0
  56. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/loader.js +4 -4
  57. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/runner.js +34 -0
  58. package/node_modules/@earendil-works/pi-coding-agent/dist/core/index.js +1 -0
  59. package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-registry.js +5 -57
  60. package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-resolver.js +41 -5
  61. package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.js +31 -17
  62. package/node_modules/@earendil-works/pi-coding-agent/dist/core/project-trust.js +58 -0
  63. package/node_modules/@earendil-works/pi-coding-agent/dist/core/prompt-templates.js +24 -26
  64. package/node_modules/@earendil-works/pi-coding-agent/dist/core/resolve-config-value.js +0 -4
  65. package/node_modules/@earendil-works/pi-coding-agent/dist/core/resource-loader.js +121 -54
  66. package/node_modules/@earendil-works/pi-coding-agent/dist/core/session-manager.js +11 -2
  67. package/node_modules/@earendil-works/pi-coding-agent/dist/core/settings-manager.js +26 -0
  68. package/node_modules/@earendil-works/pi-coding-agent/dist/core/trust-manager.js +89 -17
  69. package/node_modules/@earendil-works/pi-coding-agent/dist/index.js +2 -2
  70. package/node_modules/@earendil-works/pi-coding-agent/dist/main.js +65 -76
  71. package/node_modules/@earendil-works/pi-coding-agent/dist/migrations.js +1 -118
  72. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/first-time-setup.js +103 -0
  73. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/index.js +1 -0
  74. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +7 -1
  75. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +20 -0
  76. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/tree-selector.js +87 -12
  77. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/trust-selector.js +23 -18
  78. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js +104 -30
  79. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/theme.js +19 -41
  80. package/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.js +72 -18
  81. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/changelog.js +78 -0
  82. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/version-check.js +4 -27
  83. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/LICENSE +15 -0
  84. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/bin/semver.js +195 -0
  85. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/classes/comparator.js +143 -0
  86. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/classes/index.js +7 -0
  87. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/classes/range.js +557 -0
  88. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/classes/semver.js +333 -0
  89. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/clean.js +8 -0
  90. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/cmp.js +54 -0
  91. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/coerce.js +62 -0
  92. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/compare-build.js +9 -0
  93. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/compare-loose.js +5 -0
  94. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/compare.js +7 -0
  95. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/diff.js +60 -0
  96. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/eq.js +5 -0
  97. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/gt.js +5 -0
  98. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/gte.js +5 -0
  99. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/inc.js +21 -0
  100. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/lt.js +5 -0
  101. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/lte.js +5 -0
  102. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/major.js +5 -0
  103. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/minor.js +5 -0
  104. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/neq.js +5 -0
  105. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/parse.js +18 -0
  106. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/patch.js +5 -0
  107. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/prerelease.js +8 -0
  108. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/rcompare.js +5 -0
  109. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/rsort.js +5 -0
  110. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/satisfies.js +12 -0
  111. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/sort.js +5 -0
  112. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/truncate.js +48 -0
  113. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/valid.js +8 -0
  114. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/index.js +93 -0
  115. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/internal/constants.js +37 -0
  116. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/internal/debug.js +11 -0
  117. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/internal/identifiers.js +29 -0
  118. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/internal/lrucache.js +42 -0
  119. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/internal/parse-options.js +17 -0
  120. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/internal/re.js +223 -0
  121. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/package.json +78 -0
  122. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/preload.js +4 -0
  123. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/range.bnf +17 -0
  124. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/gtr.js +6 -0
  125. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/intersects.js +9 -0
  126. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/ltr.js +6 -0
  127. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/max-satisfying.js +27 -0
  128. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/min-satisfying.js +26 -0
  129. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/min-version.js +63 -0
  130. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/outside.js +82 -0
  131. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/simplify.js +49 -0
  132. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/subset.js +249 -0
  133. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/to-comparators.js +10 -0
  134. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/valid.js +13 -0
  135. package/node_modules/@earendil-works/pi-coding-agent/npm-shrinkwrap.json +25 -12
  136. package/node_modules/@earendil-works/pi-coding-agent/package.json +6 -8
  137. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +102 -43
  138. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js +11 -1
  139. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js +2 -2
  140. package/node_modules/@earendil-works/pi-tui/dist/index.js +2 -0
  141. package/node_modules/@earendil-works/pi-tui/dist/terminal-colors.js +51 -0
  142. package/node_modules/@earendil-works/pi-tui/dist/terminal.js +38 -77
  143. package/node_modules/@earendil-works/pi-tui/dist/tui.js +145 -21
  144. package/node_modules/@earendil-works/pi-tui/dist/utils.js +44 -16
  145. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  146. package/node_modules/@nodable/entities/package.json +4 -1
  147. package/node_modules/@nodable/entities/src/EntityDecoder.js +104 -3
  148. package/node_modules/@nodable/entities/src/index.d.ts +77 -0
  149. package/node_modules/@nodable/entities/src/index.js +1 -1
  150. package/node_modules/@smithy/core/dist-cjs/submodules/retry/index.browser.js +3 -3
  151. package/node_modules/@smithy/core/dist-cjs/submodules/retry/index.js +3 -3
  152. package/node_modules/@smithy/core/dist-es/submodules/retry/middleware-retry/retry-pre-sra-deprecated/StandardRetryStrategy.js +2 -2
  153. package/node_modules/@smithy/core/dist-es/submodules/retry/util-retry/DefaultRateLimiter.js +1 -1
  154. package/node_modules/@smithy/core/package.json +17 -17
  155. package/node_modules/@smithy/credential-provider-imds/package.json +6 -6
  156. package/node_modules/@smithy/fetch-http-handler/package.json +9 -9
  157. package/node_modules/@smithy/signature-v4/package.json +6 -6
  158. package/node_modules/@smithy/types/package.json +9 -9
  159. package/node_modules/@types/node/README.md +1 -1
  160. package/node_modules/@types/node/http2.d.ts +1 -0
  161. package/node_modules/@types/node/package.json +2 -2
  162. package/node_modules/anynum/LICENSE +21 -0
  163. package/node_modules/anynum/README.md +142 -0
  164. package/node_modules/anynum/anynum.js +135 -0
  165. package/node_modules/anynum/digitTable.js +116 -0
  166. package/node_modules/anynum/package.json +42 -0
  167. package/node_modules/protobufjs/dist/light/protobuf.js +161 -203
  168. package/node_modules/protobufjs/dist/light/protobuf.js.map +1 -1
  169. package/node_modules/protobufjs/dist/light/protobuf.min.js +3 -3
  170. package/node_modules/protobufjs/dist/light/protobuf.min.js.map +1 -1
  171. package/node_modules/protobufjs/dist/minimal/protobuf.js +34 -77
  172. package/node_modules/protobufjs/dist/minimal/protobuf.js.map +1 -1
  173. package/node_modules/protobufjs/dist/minimal/protobuf.min.js +3 -3
  174. package/node_modules/protobufjs/dist/minimal/protobuf.min.js.map +1 -1
  175. package/node_modules/protobufjs/dist/protobuf.js +181 -223
  176. package/node_modules/protobufjs/dist/protobuf.js.map +1 -1
  177. package/node_modules/protobufjs/dist/protobuf.min.js +3 -3
  178. package/node_modules/protobufjs/dist/protobuf.min.js.map +1 -1
  179. package/node_modules/protobufjs/index.d.ts +0 -8
  180. package/node_modules/protobufjs/package.json +2 -3
  181. package/node_modules/protobufjs/src/converter.js +5 -4
  182. package/node_modules/protobufjs/src/decoder.js +1 -1
  183. package/node_modules/protobufjs/src/service.js +5 -7
  184. package/node_modules/protobufjs/src/type.js +3 -1
  185. package/node_modules/protobufjs/src/util/minimal.js +1 -4
  186. package/node_modules/protobufjs/src/verifier.js +1 -1
  187. package/node_modules/semver/classes/range.js +11 -2
  188. package/node_modules/semver/package.json +2 -2
  189. package/node_modules/strnum/CHANGELOG.md +8 -0
  190. package/node_modules/strnum/README.md +9 -0
  191. package/node_modules/strnum/package.json +4 -1
  192. package/node_modules/strnum/strnum.js +9 -1
  193. package/package.json +6 -6
  194. package/slingshot/index.js +260 -258
  195. package/node_modules/@protobufjs/inquire/CHANGELOG.md +0 -8
  196. package/node_modules/@protobufjs/inquire/LICENSE +0 -26
  197. package/node_modules/@protobufjs/inquire/README.md +0 -13
  198. package/node_modules/@protobufjs/inquire/index.d.ts +0 -10
  199. package/node_modules/@protobufjs/inquire/index.js +0 -38
  200. package/node_modules/@protobufjs/inquire/package.json +0 -21
  201. package/node_modules/@protobufjs/inquire/tests/data/array.js +0 -1
  202. package/node_modules/@protobufjs/inquire/tests/data/emptyArray.js +0 -1
  203. package/node_modules/@protobufjs/inquire/tests/data/emptyObject.js +0 -1
  204. package/node_modules/@protobufjs/inquire/tests/data/object.js +0 -1
  205. package/node_modules/@protobufjs/inquire/tests/index.js +0 -20
@@ -54,25 +54,23 @@ export function loadProjectContextFiles(options) {
54
54
  contextFiles.push(globalContext);
55
55
  seenPaths.add(globalContext.path);
56
56
  }
57
- if (options.projectTrusted !== false) {
58
- const ancestorContextFiles = [];
59
- let currentDir = resolvedCwd;
60
- const root = resolve("/");
61
- while (true) {
62
- const contextFile = loadContextFileFromDir(currentDir);
63
- if (contextFile && !seenPaths.has(contextFile.path)) {
64
- ancestorContextFiles.unshift(contextFile);
65
- seenPaths.add(contextFile.path);
66
- }
67
- if (currentDir === root)
68
- break;
69
- const parentDir = resolve(currentDir, "..");
70
- if (parentDir === currentDir)
71
- break;
72
- currentDir = parentDir;
73
- }
74
- contextFiles.push(...ancestorContextFiles);
75
- }
57
+ const ancestorContextFiles = [];
58
+ let currentDir = resolvedCwd;
59
+ const root = resolve("/");
60
+ while (true) {
61
+ const contextFile = loadContextFileFromDir(currentDir);
62
+ if (contextFile && !seenPaths.has(contextFile.path)) {
63
+ ancestorContextFiles.unshift(contextFile);
64
+ seenPaths.add(contextFile.path);
65
+ }
66
+ if (currentDir === root)
67
+ break;
68
+ const parentDir = resolve(currentDir, "..");
69
+ if (parentDir === currentDir)
70
+ break;
71
+ currentDir = parentDir;
72
+ }
73
+ contextFiles.push(...ancestorContextFiles);
76
74
  return contextFiles;
77
75
  }
78
76
  export class DefaultResourceLoader {
@@ -208,7 +206,21 @@ export class DefaultResourceLoader {
208
206
  this.updateThemesFromPaths(this.lastThemePaths);
209
207
  }
210
208
  }
211
- async reload() {
209
+ async loadProjectTrustExtensions() {
210
+ // Force untrusted project settings for the bootstrap pass. This keeps project-local
211
+ // extensions/packages out while still loading user/global and temporary CLI extensions.
212
+ this.settingsManager.setProjectTrusted(false);
213
+ await this.settingsManager.reload();
214
+ return this.loadCurrentExtensionSet({ includeInlineFactories: true });
215
+ }
216
+ async reload(options) {
217
+ let preTrustExtensions;
218
+ if (options?.resolveProjectTrust) {
219
+ preTrustExtensions = await this.loadProjectTrustExtensions();
220
+ const projectTrusted = await options.resolveProjectTrust({ extensionsResult: preTrustExtensions });
221
+ this.settingsManager.setProjectTrusted(projectTrusted);
222
+ }
223
+ // reload() preserves SettingsManager.projectTrusted and reloads settings for that trust state.
212
224
  await this.settingsManager.reload();
213
225
  const resolvedPaths = await this.packageManager.resolve();
214
226
  const cliExtensionPaths = await this.packageManager.resolveExtensionSources(this.additionalExtensionPaths, {
@@ -232,29 +244,7 @@ export class DefaultResourceLoader {
232
244
  const enabledSkillResources = getEnabledResources(resolvedPaths.skills);
233
245
  const enabledPrompts = getEnabledPaths(resolvedPaths.prompts);
234
246
  const enabledThemes = getEnabledPaths(resolvedPaths.themes);
235
- const mapSkillPath = (resource) => {
236
- if (resource.metadata.source !== "auto" && resource.metadata.origin !== "package") {
237
- return resource.path;
238
- }
239
- try {
240
- const stats = statSync(resource.path);
241
- if (!stats.isDirectory()) {
242
- return resource.path;
243
- }
244
- }
245
- catch {
246
- return resource.path;
247
- }
248
- const skillFile = join(resource.path, "SKILL.md");
249
- if (existsSync(skillFile)) {
250
- if (!metadataByPath.has(skillFile)) {
251
- metadataByPath.set(skillFile, resource.metadata);
252
- }
253
- return skillFile;
254
- }
255
- return resource.path;
256
- };
257
- const enabledSkills = enabledSkillResources.map(mapSkillPath);
247
+ const enabledSkills = enabledSkillResources.map((resource) => this.mapSkillPath(resource, metadataByPath));
258
248
  // Add CLI paths metadata
259
249
  for (const r of cliExtensionPaths.extensions) {
260
250
  if (!metadataByPath.has(r.path)) {
@@ -273,16 +263,7 @@ export class DefaultResourceLoader {
273
263
  const extensionPaths = this.noExtensions
274
264
  ? cliEnabledExtensions
275
265
  : this.mergePaths(cliEnabledExtensions, enabledExtensions);
276
- const extensionsResult = await loadExtensions(extensionPaths, this.cwd, this.eventBus);
277
- const inlineExtensions = await this.loadExtensionFactories(extensionsResult.runtime);
278
- extensionsResult.extensions.push(...inlineExtensions.extensions);
279
- extensionsResult.errors.push(...inlineExtensions.errors);
280
- // Detect extension conflicts (tools, commands, flags with same names from different extensions)
281
- // Keep all extensions loaded. Conflicts are reported as diagnostics, and precedence is handled by load order.
282
- const conflicts = this.detectExtensionConflicts(extensionsResult.extensions);
283
- for (const conflict of conflicts) {
284
- extensionsResult.errors.push({ path: conflict.path, error: conflict.message });
285
- }
266
+ const extensionsResult = await this.loadFinalExtensionSet(extensionPaths, preTrustExtensions);
286
267
  for (const p of this.additionalExtensionPaths) {
287
268
  if (isLocalPath(p)) {
288
269
  const resolved = this.resolveResourcePath(p);
@@ -340,7 +321,6 @@ export class DefaultResourceLoader {
340
321
  : loadProjectContextFiles({
341
322
  cwd: this.cwd,
342
323
  agentDir: this.agentDir,
343
- projectTrusted: this.settingsManager.isProjectTrusted(),
344
324
  }),
345
325
  };
346
326
  const resolvedAgentsFiles = this.agentsFilesOverride ? this.agentsFilesOverride(agentsFiles) : agentsFiles;
@@ -356,6 +336,93 @@ export class DefaultResourceLoader {
356
336
  ? this.appendSystemPromptOverride(baseAppend)
357
337
  : baseAppend;
358
338
  }
339
+ async loadCurrentExtensionSet(options) {
340
+ const resolvedPaths = await this.packageManager.resolve();
341
+ const cliExtensionPaths = await this.packageManager.resolveExtensionSources(this.additionalExtensionPaths, {
342
+ temporary: true,
343
+ });
344
+ const enabledExtensions = resolvedPaths.extensions.filter((r) => r.enabled).map((r) => r.path);
345
+ const cliEnabledExtensions = cliExtensionPaths.extensions.filter((r) => r.enabled).map((r) => r.path);
346
+ const extensionPaths = this.noExtensions
347
+ ? cliEnabledExtensions
348
+ : this.mergePaths(cliEnabledExtensions, enabledExtensions);
349
+ const extensionsResult = await loadExtensions(extensionPaths, this.cwd, this.eventBus);
350
+ if (!options.includeInlineFactories) {
351
+ return extensionsResult;
352
+ }
353
+ const inlineExtensions = await this.loadExtensionFactories(extensionsResult.runtime);
354
+ extensionsResult.extensions.push(...inlineExtensions.extensions);
355
+ extensionsResult.errors.push(...inlineExtensions.errors);
356
+ return extensionsResult;
357
+ }
358
+ resolveExtensionLoadPath(path) {
359
+ return resolvePath(path, this.cwd, { normalizeUnicodeSpaces: true });
360
+ }
361
+ async loadFinalExtensionSet(extensionPaths, preTrustExtensions) {
362
+ if (!preTrustExtensions) {
363
+ const extensionsResult = await loadExtensions(extensionPaths, this.cwd, this.eventBus);
364
+ const inlineExtensions = await this.loadExtensionFactories(extensionsResult.runtime);
365
+ extensionsResult.extensions.push(...inlineExtensions.extensions);
366
+ extensionsResult.errors.push(...inlineExtensions.errors);
367
+ this.addExtensionConflictDiagnostics(extensionsResult);
368
+ return extensionsResult;
369
+ }
370
+ const preloadedByPath = new Map(preTrustExtensions.extensions
371
+ .filter((extension) => !extension.path.startsWith("<inline:"))
372
+ .map((extension) => [extension.resolvedPath, extension]));
373
+ const failedPreloadPaths = new Set(preTrustExtensions.errors.map((error) => this.resolveExtensionLoadPath(error.path)));
374
+ const remainingPaths = extensionPaths.filter((path) => {
375
+ const resolvedPath = this.resolveExtensionLoadPath(path);
376
+ return !preloadedByPath.has(resolvedPath) && !failedPreloadPaths.has(resolvedPath);
377
+ });
378
+ const remainingExtensions = await loadExtensions(remainingPaths, this.cwd, this.eventBus, preTrustExtensions.runtime);
379
+ const loadedByPath = new Map(preloadedByPath);
380
+ for (const extension of remainingExtensions.extensions) {
381
+ loadedByPath.set(extension.resolvedPath, extension);
382
+ }
383
+ const inlineExtensions = preTrustExtensions.extensions.filter((extension) => extension.path.startsWith("<inline:"));
384
+ const orderedExtensions = extensionPaths
385
+ .map((path) => loadedByPath.get(this.resolveExtensionLoadPath(path)))
386
+ .filter((extension) => extension !== undefined);
387
+ orderedExtensions.push(...inlineExtensions);
388
+ const extensionsResult = {
389
+ extensions: orderedExtensions,
390
+ errors: [...preTrustExtensions.errors, ...remainingExtensions.errors],
391
+ runtime: preTrustExtensions.runtime,
392
+ };
393
+ this.addExtensionConflictDiagnostics(extensionsResult);
394
+ return extensionsResult;
395
+ }
396
+ addExtensionConflictDiagnostics(extensionsResult) {
397
+ // Detect extension conflicts (tools, commands, flags with same names from different extensions)
398
+ // Keep all extensions loaded. Conflicts are reported as diagnostics, and precedence is handled by load order.
399
+ const conflicts = this.detectExtensionConflicts(extensionsResult.extensions);
400
+ for (const conflict of conflicts) {
401
+ extensionsResult.errors.push({ path: conflict.path, error: conflict.message });
402
+ }
403
+ }
404
+ mapSkillPath(resource, metadataByPath) {
405
+ if (resource.metadata.source !== "auto" && resource.metadata.origin !== "package") {
406
+ return resource.path;
407
+ }
408
+ try {
409
+ const stats = statSync(resource.path);
410
+ if (!stats.isDirectory()) {
411
+ return resource.path;
412
+ }
413
+ }
414
+ catch {
415
+ return resource.path;
416
+ }
417
+ const skillFile = join(resource.path, "SKILL.md");
418
+ if (existsSync(skillFile)) {
419
+ if (!metadataByPath.has(skillFile)) {
420
+ metadataByPath.set(skillFile, resource.metadata);
421
+ }
422
+ return skillFile;
423
+ }
424
+ return resource.path;
425
+ }
359
426
  normalizeExtensionPaths(entries) {
360
427
  return entries.map((entry) => {
361
428
  const metadata = entry.metadata.baseDir
@@ -982,8 +982,17 @@ export class SessionManager {
982
982
  if (path.length === 0) {
983
983
  throw new Error(`Entry ${leafId} not found`);
984
984
  }
985
- // Filter out LabelEntry from path - we'll recreate them from the resolved map
986
- const pathWithoutLabels = path.filter((e) => e.type !== "label");
985
+ // Filter out LabelEntry from path - we'll recreate them from the resolved map.
986
+ // Because labels are real tree entries, later entries can be children of labels;
987
+ // removing labels requires re-chaining the retained path to avoid orphaned subtrees.
988
+ const pathWithoutLabels = [];
989
+ let pathParentId = null;
990
+ for (const entry of path) {
991
+ if (entry.type === "label")
992
+ continue;
993
+ pathWithoutLabels.push({ ...entry, parentId: pathParentId });
994
+ pathParentId = entry.id;
995
+ }
987
996
  const newSessionId = createSessionId();
988
997
  const timestamp = new Date().toISOString();
989
998
  const fileTimestamp = timestamp.replace(/[:.]/g, "-");
@@ -1,3 +1,4 @@
1
+ import { randomUUID } from "crypto";
1
2
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
2
3
  import { dirname, join } from "path";
3
4
  import lockfile from "proper-lockfile";
@@ -594,6 +595,15 @@ export class SettingsManager {
594
595
  this.markModified("quietStartup");
595
596
  this.save();
596
597
  }
598
+ getDefaultProjectTrust() {
599
+ const value = this.globalSettings.defaultProjectTrust;
600
+ return value === "always" || value === "never" ? value : "ask";
601
+ }
602
+ setDefaultProjectTrust(defaultProjectTrust) {
603
+ this.globalSettings.defaultProjectTrust = defaultProjectTrust;
604
+ this.markModified("defaultProjectTrust");
605
+ this.save();
606
+ }
597
607
  getShellCommandPrefix() {
598
608
  return this.settings.shellCommandPrefix;
599
609
  }
@@ -626,6 +636,22 @@ export class SettingsManager {
626
636
  this.markModified("enableInstallTelemetry");
627
637
  this.save();
628
638
  }
639
+ getEnableAnalytics() {
640
+ return this.settings.enableAnalytics ?? false;
641
+ }
642
+ getTrackingId() {
643
+ return this.settings.trackingId;
644
+ }
645
+ /** Set the analytics opt-in preference; generates a tracking identifier on first opt-in */
646
+ setEnableAnalytics(enabled) {
647
+ this.globalSettings.enableAnalytics = enabled;
648
+ this.markModified("enableAnalytics");
649
+ if (enabled && !this.globalSettings.trackingId) {
650
+ this.globalSettings.trackingId = randomUUID();
651
+ this.markModified("trackingId");
652
+ }
653
+ this.save();
654
+ }
629
655
  getPackages() {
630
656
  return [...(this.settings.packages ?? [])];
631
657
  }
@@ -1,12 +1,71 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { homedir } from "node:os";
2
3
  import { dirname, join } from "node:path";
3
4
  import lockfile from "proper-lockfile";
4
5
  import { CONFIG_DIR_NAME } from "../config.js";
5
6
  import { canonicalizePath, resolvePath } from "../utils/paths.js";
6
- const CONTEXT_FILE_NAMES = ["AGENTS.md", "AGENTS.MD", "CLAUDE.md", "CLAUDE.MD"];
7
+ const TRUST_REQUIRING_PROJECT_CONFIG_RESOURCES = [
8
+ "settings.json",
9
+ "extensions",
10
+ "skills",
11
+ "prompts",
12
+ "themes",
13
+ "SYSTEM.md",
14
+ "APPEND_SYSTEM.md",
15
+ ];
7
16
  function normalizeCwd(cwd) {
8
17
  return canonicalizePath(resolvePath(cwd));
9
18
  }
19
+ function findNearestTrustEntry(data, cwd) {
20
+ let currentDir = normalizeCwd(cwd);
21
+ while (true) {
22
+ const value = data[currentDir];
23
+ if (value === true || value === false) {
24
+ return { path: currentDir, decision: value };
25
+ }
26
+ const parentDir = dirname(currentDir);
27
+ if (parentDir === currentDir) {
28
+ return null;
29
+ }
30
+ currentDir = parentDir;
31
+ }
32
+ }
33
+ export function getProjectTrustParentPath(cwd) {
34
+ const trustPath = normalizeCwd(cwd);
35
+ const parentDir = dirname(trustPath);
36
+ return parentDir === trustPath ? undefined : parentDir;
37
+ }
38
+ export function getProjectTrustOptions(cwd, options) {
39
+ const trustPath = normalizeCwd(cwd);
40
+ const trustOptions = [
41
+ { label: "Trust", trusted: true, updates: [{ path: trustPath, decision: true }], savedPath: trustPath },
42
+ ];
43
+ const parentPath = getProjectTrustParentPath(cwd);
44
+ if (parentPath !== undefined) {
45
+ trustOptions.push({
46
+ label: `Trust parent folder (${parentPath})`,
47
+ trusted: true,
48
+ updates: [
49
+ { path: parentPath, decision: true },
50
+ { path: trustPath, decision: null },
51
+ ],
52
+ savedPath: parentPath,
53
+ });
54
+ }
55
+ if (options?.includeSessionOnly) {
56
+ trustOptions.push({ label: "Trust (this session only)", trusted: true, updates: [] });
57
+ }
58
+ trustOptions.push({
59
+ label: "Do not trust",
60
+ trusted: false,
61
+ updates: [{ path: trustPath, decision: false }],
62
+ savedPath: trustPath,
63
+ });
64
+ if (options?.includeSessionOnly) {
65
+ trustOptions.push({ label: "Do not trust (this session only)", trusted: false, updates: [] });
66
+ }
67
+ return trustOptions;
68
+ }
10
69
  function readTrustFile(path) {
11
70
  if (!existsSync(path)) {
12
71
  return {};
@@ -80,18 +139,24 @@ function withTrustFileLock(path, fn) {
80
139
  release();
81
140
  }
82
141
  }
83
- export function hasProjectTrustInputs(cwd) {
142
+ /**
143
+ * Returns true when cwd has project-local resources that must be gated by
144
+ * project trust: trust-requiring entries under cwd/.pi, or .agents/skills in
145
+ * cwd or one of its ancestors. Returns false when no such project resources
146
+ * exist. The user/global ~/.agents/skills directory is always treated as a
147
+ * trusted user resource and is ignored here, even when cwd is $HOME.
148
+ */
149
+ export function hasTrustRequiringProjectResources(cwd) {
150
+ const homeDir = canonicalizePath(resolvePath(process.env.HOME || homedir()));
151
+ const userAgentsSkillsDir = join(homeDir, ".agents", "skills");
84
152
  let currentDir = canonicalizePath(resolvePath(cwd));
85
- if (existsSync(join(currentDir, CONFIG_DIR_NAME))) {
153
+ const configDir = join(currentDir, CONFIG_DIR_NAME);
154
+ if (TRUST_REQUIRING_PROJECT_CONFIG_RESOURCES.some((entry) => existsSync(join(configDir, entry)))) {
86
155
  return true;
87
156
  }
88
157
  while (true) {
89
- for (const filename of CONTEXT_FILE_NAMES) {
90
- if (existsSync(join(currentDir, filename))) {
91
- return true;
92
- }
93
- }
94
- if (existsSync(join(currentDir, ".agents", "skills"))) {
158
+ const agentsSkillsDir = join(currentDir, ".agents", "skills");
159
+ if (agentsSkillsDir !== userAgentsSkillsDir && existsSync(agentsSkillsDir)) {
95
160
  return true;
96
161
  }
97
162
  const parentDir = dirname(currentDir);
@@ -107,21 +172,28 @@ export class ProjectTrustStore {
107
172
  this.trustPath = join(resolvePath(agentDir), "trust.json");
108
173
  }
109
174
  get(cwd) {
175
+ return this.getEntry(cwd)?.decision ?? null;
176
+ }
177
+ getEntry(cwd) {
110
178
  return withTrustFileLock(this.trustPath, () => {
111
179
  const data = readTrustFile(this.trustPath);
112
- const value = data[normalizeCwd(cwd)];
113
- return value === true || value === false ? value : null;
180
+ return findNearestTrustEntry(data, cwd);
114
181
  });
115
182
  }
116
183
  set(cwd, decision) {
184
+ this.setMany([{ path: cwd, decision }]);
185
+ }
186
+ setMany(decisions) {
117
187
  withTrustFileLock(this.trustPath, () => {
118
188
  const data = readTrustFile(this.trustPath);
119
- const key = normalizeCwd(cwd);
120
- if (decision === null) {
121
- delete data[key];
122
- }
123
- else {
124
- data[key] = decision;
189
+ for (const { path, decision } of decisions) {
190
+ const key = normalizeCwd(path);
191
+ if (decision === null) {
192
+ delete data[key];
193
+ }
194
+ else {
195
+ data[key] = decision;
196
+ }
125
197
  }
126
198
  writeTrustFile(this.trustPath, data);
127
199
  });
@@ -1,7 +1,7 @@
1
1
  // Core session management
2
2
  export { parseArgs } from "./cli/args.js";
3
3
  // Config paths
4
- export { getAgentDir, VERSION } from "./config.js";
4
+ export { getAgentDir, getDocsPath, getExamplesPath, getPackageDir, getReadmePath, VERSION } from "./config.js";
5
5
  export { AgentSession, parseSkillBlock, } from "./core/agent-session.js";
6
6
  // Auth and model registry
7
7
  export { AuthStorage, FileAuthStorageBackend, InMemoryAuthStorageBackend, } from "./core/auth-storage.js";
@@ -26,7 +26,7 @@ export { formatSkillsForPrompt, loadSkills, loadSkillsFromDir, } from "./core/sk
26
26
  export { createSyntheticSourceInfo } from "./core/source-info.js";
27
27
  // Tools
28
28
  export { createBashToolDefinition, createEditToolDefinition, createFindToolDefinition, createGrepToolDefinition, createLocalBashOperations, createLsToolDefinition, createReadToolDefinition, createWriteToolDefinition, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, truncateHead, truncateLine, truncateTail, withFileMutationQueue, } from "./core/tools/index.js";
29
- export { hasProjectTrustInputs, ProjectTrustStore } from "./core/trust-manager.js";
29
+ export { hasTrustRequiringProjectResources, ProjectTrustStore, } from "./core/trust-manager.js";
30
30
  // Main entry point
31
31
  export { main } from "./main.js";
32
32
  // Run modes for programmatic SDK usage