@earendil-works/pi-coding-agent 0.80.7 → 0.80.8

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 (140) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +6 -6
  3. package/dist/bun/cli.d.ts.map +1 -1
  4. package/dist/bun/cli.js +2 -0
  5. package/dist/bun/cli.js.map +1 -1
  6. package/dist/cli/args.d.ts.map +1 -1
  7. package/dist/cli/args.js +1 -1
  8. package/dist/cli/args.js.map +1 -1
  9. package/dist/cli/list-models.d.ts +2 -2
  10. package/dist/cli/list-models.d.ts.map +1 -1
  11. package/dist/cli/list-models.js +3 -3
  12. package/dist/cli/list-models.js.map +1 -1
  13. package/dist/core/agent-session-services.d.ts +3 -6
  14. package/dist/core/agent-session-services.d.ts.map +1 -1
  15. package/dist/core/agent-session-services.js +10 -9
  16. package/dist/core/agent-session-services.js.map +1 -1
  17. package/dist/core/agent-session.d.ts +5 -6
  18. package/dist/core/agent-session.d.ts.map +1 -1
  19. package/dist/core/agent-session.js +57 -30
  20. package/dist/core/agent-session.js.map +1 -1
  21. package/dist/core/auth-storage.d.ts +15 -99
  22. package/dist/core/auth-storage.d.ts.map +1 -1
  23. package/dist/core/auth-storage.js +46 -259
  24. package/dist/core/auth-storage.js.map +1 -1
  25. package/dist/core/cache-stats.d.ts +2 -2
  26. package/dist/core/cache-stats.d.ts.map +1 -1
  27. package/dist/core/cache-stats.js +1 -1
  28. package/dist/core/cache-stats.js.map +1 -1
  29. package/dist/core/extensions/loader.d.ts.map +1 -1
  30. package/dist/core/extensions/loader.js +8 -2
  31. package/dist/core/extensions/loader.js.map +1 -1
  32. package/dist/core/extensions/runner.d.ts +1 -0
  33. package/dist/core/extensions/runner.d.ts.map +1 -1
  34. package/dist/core/extensions/runner.js +3 -0
  35. package/dist/core/extensions/runner.js.map +1 -1
  36. package/dist/core/extensions/types.d.ts +9 -2
  37. package/dist/core/extensions/types.d.ts.map +1 -1
  38. package/dist/core/extensions/types.js.map +1 -1
  39. package/dist/core/model-config.d.ts +507 -0
  40. package/dist/core/model-config.d.ts.map +1 -0
  41. package/dist/core/model-config.js +242 -0
  42. package/dist/core/model-config.js.map +1 -0
  43. package/dist/core/model-registry.d.ts +13 -123
  44. package/dist/core/model-registry.d.ts.map +1 -1
  45. package/dist/core/model-registry.js +44 -747
  46. package/dist/core/model-registry.js.map +1 -1
  47. package/dist/core/model-resolver.d.ts +6 -6
  48. package/dist/core/model-resolver.d.ts.map +1 -1
  49. package/dist/core/model-resolver.js +17 -17
  50. package/dist/core/model-resolver.js.map +1 -1
  51. package/dist/core/model-runtime.d.ts +77 -0
  52. package/dist/core/model-runtime.d.ts.map +1 -0
  53. package/dist/core/model-runtime.js +418 -0
  54. package/dist/core/model-runtime.js.map +1 -0
  55. package/dist/core/models-store.d.ts +17 -0
  56. package/dist/core/models-store.d.ts.map +1 -0
  57. package/dist/core/models-store.js +45 -0
  58. package/dist/core/models-store.js.map +1 -0
  59. package/dist/core/provider-composer.d.ts +55 -0
  60. package/dist/core/provider-composer.d.ts.map +1 -0
  61. package/dist/core/provider-composer.js +375 -0
  62. package/dist/core/provider-composer.js.map +1 -0
  63. package/dist/core/radius.d.ts +0 -19
  64. package/dist/core/radius.d.ts.map +1 -1
  65. package/dist/core/radius.js +0 -28
  66. package/dist/core/radius.js.map +1 -1
  67. package/dist/core/remote-catalog-provider.d.ts +5 -0
  68. package/dist/core/remote-catalog-provider.d.ts.map +1 -0
  69. package/dist/core/remote-catalog-provider.js +83 -0
  70. package/dist/core/remote-catalog-provider.js.map +1 -0
  71. package/dist/core/runtime-credentials.d.ts +15 -0
  72. package/dist/core/runtime-credentials.d.ts.map +1 -0
  73. package/dist/core/runtime-credentials.js +36 -0
  74. package/dist/core/runtime-credentials.js.map +1 -0
  75. package/dist/core/sdk.d.ts +3 -6
  76. package/dist/core/sdk.d.ts.map +1 -1
  77. package/dist/core/sdk.js +14 -25
  78. package/dist/core/sdk.js.map +1 -1
  79. package/dist/index.d.ts +2 -1
  80. package/dist/index.d.ts.map +1 -1
  81. package/dist/index.js +2 -2
  82. package/dist/index.js.map +1 -1
  83. package/dist/main.d.ts.map +1 -1
  84. package/dist/main.js +11 -13
  85. package/dist/main.js.map +1 -1
  86. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  87. package/dist/modes/interactive/components/assistant-message.js +22 -10
  88. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  89. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  90. package/dist/modes/interactive/components/footer.js +1 -1
  91. package/dist/modes/interactive/components/footer.js.map +1 -1
  92. package/dist/modes/interactive/components/login-dialog.d.ts +4 -8
  93. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  94. package/dist/modes/interactive/components/login-dialog.js +14 -12
  95. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  96. package/dist/modes/interactive/components/model-selector.d.ts +11 -4
  97. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  98. package/dist/modes/interactive/components/model-selector.js +72 -41
  99. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  100. package/dist/modes/interactive/components/oauth-selector.d.ts +4 -4
  101. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  102. package/dist/modes/interactive/components/oauth-selector.js +14 -27
  103. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  104. package/dist/modes/interactive/interactive-mode.d.ts +6 -3
  105. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  106. package/dist/modes/interactive/interactive-mode.js +154 -142
  107. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  108. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  109. package/dist/modes/rpc/rpc-mode.js +2 -2
  110. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  111. package/dist/package-manager-cli.d.ts.map +1 -1
  112. package/dist/package-manager-cli.js +67 -5
  113. package/dist/package-manager-cli.js.map +1 -1
  114. package/docs/custom-provider.md +6 -11
  115. package/docs/extensions.md +22 -1
  116. package/docs/models.md +1 -0
  117. package/docs/packages.md +1 -0
  118. package/docs/providers.md +13 -1
  119. package/docs/sdk.md +40 -50
  120. package/docs/usage.md +1 -0
  121. package/examples/extensions/custom-provider-anthropic/index.ts +1 -1
  122. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  123. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  124. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  125. package/examples/extensions/gondolin/package-lock.json +2 -2
  126. package/examples/extensions/gondolin/package.json +1 -1
  127. package/examples/extensions/sandbox/package-lock.json +2 -2
  128. package/examples/extensions/sandbox/package.json +1 -1
  129. package/examples/extensions/with-deps/package-lock.json +2 -2
  130. package/examples/extensions/with-deps/package.json +1 -1
  131. package/examples/sdk/02-custom-model.ts +5 -8
  132. package/examples/sdk/09-api-keys-and-oauth.ts +13 -31
  133. package/examples/sdk/12-full-control.ts +7 -12
  134. package/examples/sdk/README.md +14 -18
  135. package/npm-shrinkwrap.json +12 -12
  136. package/package.json +4 -4
  137. package/dist/core/provider-display-names.d.ts +0 -2
  138. package/dist/core/provider-display-names.d.ts.map +0 -1
  139. package/dist/core/provider-display-names.js +0 -37
  140. package/dist/core/provider-display-names.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,45 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.80.8] - 2026-07-16
4
+
5
+ ### New Features
6
+
7
+ - **Unified model runtime and provider authentication** — `ModelRuntime` centralizes model configuration, provider-owned `/login`, and dynamic provider catalogs. See [Providers](docs/providers.md).
8
+ - **Live model catalog refresh** — `/model` refreshes configured providers in the background, and `pi update --models` forces an immediate refresh. See [Install and Manage](docs/packages.md#install-and-manage).
9
+ - **xAI device-code OAuth and Grok 4.5 Responses support** — Sign in to xAI with a device code and use Grok 4.5 with low, medium, or high thinking. See [xAI](docs/providers.md#xai-grokx-subscription).
10
+
11
+ ### Breaking Changes
12
+
13
+ - Replaced the SDK's `CreateAgentSessionOptions.authStorage` and `modelRegistry` options with the async `modelRuntime` option. `AuthStorage` and its storage backends are no longer exported; use `ModelRuntime` (or a custom pi-ai `CredentialStore`), or `readStoredCredential()` for one-off reads of auth.json.
14
+ - Removed redundant `ModelRuntime.getAll()`, `find()`, `getSnapshot()`, and `getAuthOptions()` projections. Use the pi-ai `Models` methods `getModels()`, `getModel()`, `getProviders()`, and `checkAuth()` directly.
15
+ - Replaced SDK request-auth assembly through `ModelRegistry.getApiKeyAndHeaders()` with `ModelRuntime.getAuth()`. Passing a provider ID returns provider-scoped auth; passing a model also resolves built-in, `models.json`, and extension model headers.
16
+ - Changed extension-facing `ModelRegistry.refresh()` from synchronous `void` to `Promise<void>` because `models.json` loading is asynchronous. Extensions must await it before making synchronous registry reads.
17
+ - Moved canonical dynamic catalog refresh to async `ModelRuntime.refresh()`/pi-ai `Models.refresh()`. Legacy extension OAuth `modifyModels` remains supported as a synchronous compatibility projection after credential initialization.
18
+
19
+ ### Added
20
+
21
+ - Added `ModelRuntime` as the canonical async SDK and internal model/auth facade while preserving the synchronous extension-facing `ModelRegistry` API. `ModelRuntime.create()` accepts any pi-ai `CredentialStore` through its `credentials` option.
22
+ - Added provider-owned `/login` discovery directly from registered pi-ai providers, including ambient auth status and informational links.
23
+ - Added file-backed dynamic catalogs in `models-store.json`, per-provider pi.dev catalog overlays, and Radius gateway support including offline migration from legacy credential-cached catalogs.
24
+ - Added extension provider `refreshModels(context)` support for dynamic model discovery with optional provider-controlled persistence.
25
+ - Added `pi update --models` to force an immediate model catalog refresh without updating pi or extensions.
26
+ - Added inherited xAI device-code OAuth login and Grok 4.5 OpenAI Responses support, with low, medium, and high thinking levels ([#6651](https://github.com/earendil-works/pi-mono/pull/6651) by [@Jaaneek](https://github.com/Jaaneek)).
27
+
28
+ ### Changed
29
+
30
+ - Changed `ModelRuntime` to compose built-in providers, immutable `models.json` configuration, and extension overlays through ad-hoc pi-ai provider methods.
31
+ - Changed `ModelRuntime` to own final request assembly: `getAuth(model)` includes configured model headers, stream methods resolve auth once, and `before_provider_headers` runs as the Models-only header transform before provider dispatch.
32
+ - Changed `/model` to render the current model snapshot immediately, refresh configured providers in the background, and update the open selector with partial results or timeout errors.
33
+
34
+ ### Fixed
35
+
36
+ - Fixed configured-provider catalog refresh to parse pi.dev's model-ID keyed responses, throttle checks to once per four hours, send the versioned pi user agent, treat unimplemented routes as unavailable overlays, and show concise refresh status in `/model`.
37
+ - Fixed adjacent assistant thinking blocks to render as one thinking section.
38
+ - Fixed inherited OpenAI Codex session IDs longer than 64 characters to meet the API limit ([#6630](https://github.com/earendil-works/pi-mono/issues/6630)).
39
+ - Fixed inherited terminal output to normalize tab characters consistently ([#6697](https://github.com/earendil-works/pi-mono/pull/6697) by [@xz-dev](https://github.com/xz-dev)).
40
+ - Fixed the Windows terminal title after checking npm packages ([#6629](https://github.com/earendil-works/pi-mono/issues/6629)).
41
+ - Fixed Bun standalone binaries to bundle OAuth adapters for interactive logins.
42
+
3
43
  ## [0.80.7] - 2026-07-14
4
44
 
5
45
  ### Breaking Changes
package/README.md CHANGED
@@ -96,7 +96,7 @@ Then just talk to pi. By default, pi gives the model four tools: `read`, `write`
96
96
 
97
97
  ## Providers & Models
98
98
 
99
- For each built-in provider, pi maintains a list of tool-capable models, updated with every release. Authenticate via subscription (`/login`) or API key, then select any model from that provider via `/model` (or Ctrl+L).
99
+ For each built-in provider, pi maintains a list of tool-capable models. Configured provider catalogs refresh automatically; run `pi update --models` to force an immediate refresh. Authenticate via subscription (`/login`) or API key, then select any model from that provider via `/model` (or Ctrl+L).
100
100
 
101
101
  **Subscriptions:**
102
102
  - Anthropic Claude Pro/Max
@@ -421,6 +421,7 @@ pi list
421
421
  pi update # update pi only
422
422
  pi update --all # update pi and packages
423
423
  pi update --extensions # update packages only
424
+ pi update --models # refresh model catalogs only
424
425
  pi update --self # update pi only
425
426
  pi update --self --force # reinstall pi even if current
426
427
  pi update npm:@foo/pi-tools # update one package
@@ -455,14 +456,12 @@ See [docs/packages.md](docs/packages.md).
455
456
  ### SDK
456
457
 
457
458
  ```typescript
458
- import { AuthStorage, createAgentSession, ModelRegistry, SessionManager } from "@earendil-works/pi-coding-agent";
459
+ import { createAgentSession, ModelRuntime, SessionManager } from "@earendil-works/pi-coding-agent";
459
460
 
460
- const authStorage = AuthStorage.create();
461
- const modelRegistry = ModelRegistry.create(authStorage);
461
+ const modelRuntime = await ModelRuntime.create();
462
462
  const { session } = await createAgentSession({
463
463
  sessionManager: SessionManager.inMemory(),
464
- authStorage,
465
- modelRegistry,
464
+ modelRuntime,
466
465
  });
467
466
 
468
467
  await session.prompt("What files are in the current directory?");
@@ -521,6 +520,7 @@ pi uninstall <source> [-l] # Alias for remove
521
520
  pi update [source|self|pi] # Update pi only, or one package source
522
521
  pi update --all # Update pi and packages
523
522
  pi update --extensions # Update packages only
523
+ pi update --models # Refresh model catalogs only
524
524
  pi update --self # Update pi only
525
525
  pi update --self --force # Reinstall pi even if current
526
526
  pi update --extension <src> # Update one package
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/bun/cli.ts"],"names":[],"mappings":"","sourcesContent":["#!/usr/bin/env node\nimport { APP_NAME } from \"../config.ts\";\n\nprocess.title = APP_NAME;\nprocess.emitWarning = (() => {}) as typeof process.emitWarning;\n\nimport { restoreSandboxEnv } from \"./restore-sandbox-env.ts\";\n\nrestoreSandboxEnv();\n\nawait import(\"./register-bedrock.ts\");\nawait import(\"../cli.ts\");\n"]}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/bun/cli.ts"],"names":[],"mappings":"","sourcesContent":["#!/usr/bin/env node\nimport { registerBunOAuthFlows } from \"@earendil-works/pi-ai/bun-oauth\";\nimport { APP_NAME } from \"../config.ts\";\n\nprocess.title = APP_NAME;\nprocess.emitWarning = (() => {}) as typeof process.emitWarning;\n\nregisterBunOAuthFlows();\n\nimport { restoreSandboxEnv } from \"./restore-sandbox-env.ts\";\n\nrestoreSandboxEnv();\n\nawait import(\"./register-bedrock.ts\");\nawait import(\"../cli.ts\");\n"]}
package/dist/bun/cli.js CHANGED
@@ -1,7 +1,9 @@
1
1
  #!/usr/bin/env node
2
+ import { registerBunOAuthFlows } from "@earendil-works/pi-ai/bun-oauth";
2
3
  import { APP_NAME } from "../config.js";
3
4
  process.title = APP_NAME;
4
5
  process.emitWarning = (() => { });
6
+ registerBunOAuthFlows();
5
7
  import { restoreSandboxEnv } from "./restore-sandbox-env.js";
6
8
  restoreSandboxEnv();
7
9
  await import("./register-bedrock.js");
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/bun/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC;AACzB,OAAO,CAAC,WAAW,GAAG,CAAC,GAAG,EAAE,CAAC,EAAC,CAAC,CAA+B,CAAC;AAE/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,iBAAiB,EAAE,CAAC;AAEpB,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;AACtC,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC","sourcesContent":["#!/usr/bin/env node\nimport { APP_NAME } from \"../config.ts\";\n\nprocess.title = APP_NAME;\nprocess.emitWarning = (() => {}) as typeof process.emitWarning;\n\nimport { restoreSandboxEnv } from \"./restore-sandbox-env.ts\";\n\nrestoreSandboxEnv();\n\nawait import(\"./register-bedrock.ts\");\nawait import(\"../cli.ts\");\n"]}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/bun/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC;AACzB,OAAO,CAAC,WAAW,GAAG,CAAC,GAAG,EAAE,CAAC,EAAC,CAAC,CAA+B,CAAC;AAE/D,qBAAqB,EAAE,CAAC;AAExB,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,iBAAiB,EAAE,CAAC;AAEpB,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;AACtC,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC","sourcesContent":["#!/usr/bin/env node\nimport { registerBunOAuthFlows } from \"@earendil-works/pi-ai/bun-oauth\";\nimport { APP_NAME } from \"../config.ts\";\n\nprocess.title = APP_NAME;\nprocess.emitWarning = (() => {}) as typeof process.emitWarning;\n\nregisterBunOAuthFlows();\n\nimport { restoreSandboxEnv } from \"./restore-sandbox-env.ts\";\n\nrestoreSandboxEnv();\n\nawait import(\"./register-bedrock.ts\");\nawait import(\"../cli.ts\");\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAGnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEjE,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAE3C,MAAM,WAAW,IAAI;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,8EAA8E;IAC9E,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC,CAAC;IAC5C,WAAW,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnE;AAID,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,aAAa,CAE1E;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAmJ9C;AAED,wBAAgB,SAAS,CAAC,cAAc,CAAC,EAAE,aAAa,EAAE,GAAG,IAAI,CAkLhE","sourcesContent":["/**\n * CLI argument parsing and help display\n */\n\nimport type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport chalk from \"chalk\";\nimport { APP_NAME, CONFIG_DIR_NAME, ENV_AGENT_DIR, ENV_SESSION_DIR } from \"../config.ts\";\nimport type { ExtensionFlag } from \"../core/extensions/types.ts\";\n\nexport type Mode = \"text\" | \"json\" | \"rpc\";\n\nexport interface Args {\n\tprovider?: string;\n\tmodel?: string;\n\tapiKey?: string;\n\tsystemPrompt?: string;\n\tappendSystemPrompt?: string[];\n\tthinking?: ThinkingLevel;\n\tcontinue?: boolean;\n\tresume?: boolean;\n\thelp?: boolean;\n\tversion?: boolean;\n\tmode?: Mode;\n\tname?: string;\n\tnoSession?: boolean;\n\tsession?: string;\n\tsessionId?: string;\n\tfork?: string;\n\tsessionDir?: string;\n\tmodels?: string[];\n\ttools?: string[];\n\texcludeTools?: string[];\n\tnoTools?: boolean;\n\tnoBuiltinTools?: boolean;\n\textensions?: string[];\n\tnoExtensions?: boolean;\n\tprint?: boolean;\n\texport?: string;\n\tnoSkills?: boolean;\n\tskills?: string[];\n\tpromptTemplates?: string[];\n\tnoPromptTemplates?: boolean;\n\tthemes?: string[];\n\tnoThemes?: boolean;\n\tnoContextFiles?: boolean;\n\tlistModels?: string | true;\n\toffline?: boolean;\n\tverbose?: boolean;\n\tprojectTrustOverride?: boolean;\n\tmessages: string[];\n\tfileArgs: string[];\n\t/** Unknown flags (potentially extension flags) - map of flag name to value */\n\tunknownFlags: Map<string, boolean | string>;\n\tdiagnostics: Array<{ type: \"warning\" | \"error\"; message: string }>;\n}\n\nconst VALID_THINKING_LEVELS = [\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\"] as const;\n\nexport function isValidThinkingLevel(level: string): level is ThinkingLevel {\n\treturn VALID_THINKING_LEVELS.includes(level as ThinkingLevel);\n}\n\nexport function parseArgs(args: string[]): Args {\n\tconst result: Args = {\n\t\tmessages: [],\n\t\tfileArgs: [],\n\t\tunknownFlags: new Map(),\n\t\tdiagnostics: [],\n\t};\n\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i];\n\n\t\tif (arg === \"--help\" || arg === \"-h\") {\n\t\t\tresult.help = true;\n\t\t} else if (arg === \"--version\" || arg === \"-v\") {\n\t\t\tresult.version = true;\n\t\t} else if (arg === \"--mode\" && i + 1 < args.length) {\n\t\t\tconst mode = args[++i];\n\t\t\tif (mode === \"text\" || mode === \"json\" || mode === \"rpc\") {\n\t\t\t\tresult.mode = mode;\n\t\t\t}\n\t\t} else if (arg === \"--continue\" || arg === \"-c\") {\n\t\t\tresult.continue = true;\n\t\t} else if (arg === \"--resume\" || arg === \"-r\") {\n\t\t\tresult.resume = true;\n\t\t} else if (arg === \"--provider\" && i + 1 < args.length) {\n\t\t\tresult.provider = args[++i];\n\t\t} else if (arg === \"--model\" && i + 1 < args.length) {\n\t\t\tresult.model = args[++i];\n\t\t} else if (arg === \"--api-key\" && i + 1 < args.length) {\n\t\t\tresult.apiKey = args[++i];\n\t\t} else if (arg === \"--system-prompt\" && i + 1 < args.length) {\n\t\t\tresult.systemPrompt = args[++i];\n\t\t} else if (arg === \"--append-system-prompt\" && i + 1 < args.length) {\n\t\t\tresult.appendSystemPrompt = result.appendSystemPrompt ?? [];\n\t\t\tresult.appendSystemPrompt.push(args[++i]);\n\t\t} else if (arg === \"--name\" || arg === \"-n\") {\n\t\t\tif (i + 1 < args.length) {\n\t\t\t\tresult.name = args[++i];\n\t\t\t} else {\n\t\t\t\tresult.diagnostics.push({ type: \"error\", message: \"--name requires a value\" });\n\t\t\t}\n\t\t} else if (arg === \"--no-session\") {\n\t\t\tresult.noSession = true;\n\t\t} else if (arg === \"--session\" && i + 1 < args.length) {\n\t\t\tresult.session = args[++i];\n\t\t} else if (arg === \"--session-id\" && i + 1 < args.length) {\n\t\t\tresult.sessionId = args[++i];\n\t\t} else if (arg === \"--fork\" && i + 1 < args.length) {\n\t\t\tresult.fork = args[++i];\n\t\t} else if (arg === \"--session-dir\" && i + 1 < args.length) {\n\t\t\tresult.sessionDir = args[++i];\n\t\t} else if (arg === \"--models\" && i + 1 < args.length) {\n\t\t\tresult.models = args[++i].split(\",\").map((s) => s.trim());\n\t\t} else if (arg === \"--no-tools\" || arg === \"-nt\") {\n\t\t\tresult.noTools = true;\n\t\t} else if (arg === \"--no-builtin-tools\" || arg === \"-nbt\") {\n\t\t\tresult.noBuiltinTools = true;\n\t\t} else if ((arg === \"--tools\" || arg === \"-t\") && i + 1 < args.length) {\n\t\t\tresult.tools = args[++i]\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim())\n\t\t\t\t.filter((name) => name.length > 0);\n\t\t} else if ((arg === \"--exclude-tools\" || arg === \"-xt\") && i + 1 < args.length) {\n\t\t\tresult.excludeTools = args[++i]\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim())\n\t\t\t\t.filter((name) => name.length > 0);\n\t\t} else if (arg === \"--thinking\" && i + 1 < args.length) {\n\t\t\tconst level = args[++i];\n\t\t\tif (isValidThinkingLevel(level)) {\n\t\t\t\tresult.thinking = level;\n\t\t\t} else {\n\t\t\t\tresult.diagnostics.push({\n\t\t\t\t\ttype: \"warning\",\n\t\t\t\t\tmessage: `Invalid thinking level \"${level}\". Valid values: ${VALID_THINKING_LEVELS.join(\", \")}`,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (arg === \"--print\" || arg === \"-p\") {\n\t\t\tresult.print = true;\n\t\t\tconst next = args[i + 1];\n\t\t\tif (next !== undefined && !next.startsWith(\"@\") && (!next.startsWith(\"-\") || next.startsWith(\"---\"))) {\n\t\t\t\tresult.messages.push(next);\n\t\t\t\ti++;\n\t\t\t}\n\t\t} else if (arg === \"--export\" && i + 1 < args.length) {\n\t\t\tresult.export = args[++i];\n\t\t} else if ((arg === \"--extension\" || arg === \"-e\") && i + 1 < args.length) {\n\t\t\tresult.extensions = result.extensions ?? [];\n\t\t\tresult.extensions.push(args[++i]);\n\t\t} else if (arg === \"--no-extensions\" || arg === \"-ne\") {\n\t\t\tresult.noExtensions = true;\n\t\t} else if (arg === \"--skill\" && i + 1 < args.length) {\n\t\t\tresult.skills = result.skills ?? [];\n\t\t\tresult.skills.push(args[++i]);\n\t\t} else if (arg === \"--prompt-template\" && i + 1 < args.length) {\n\t\t\tresult.promptTemplates = result.promptTemplates ?? [];\n\t\t\tresult.promptTemplates.push(args[++i]);\n\t\t} else if (arg === \"--theme\" && i + 1 < args.length) {\n\t\t\tresult.themes = result.themes ?? [];\n\t\t\tresult.themes.push(args[++i]);\n\t\t} else if (arg === \"--no-skills\" || arg === \"-ns\") {\n\t\t\tresult.noSkills = true;\n\t\t} else if (arg === \"--no-prompt-templates\" || arg === \"-np\") {\n\t\t\tresult.noPromptTemplates = true;\n\t\t} else if (arg === \"--no-themes\") {\n\t\t\tresult.noThemes = true;\n\t\t} else if (arg === \"--no-context-files\" || arg === \"-nc\") {\n\t\t\tresult.noContextFiles = true;\n\t\t} else if (arg === \"--list-models\") {\n\t\t\t// Check if next arg is a search pattern (not a flag or file arg)\n\t\t\tif (i + 1 < args.length && !args[i + 1].startsWith(\"-\") && !args[i + 1].startsWith(\"@\")) {\n\t\t\t\tresult.listModels = args[++i];\n\t\t\t} else {\n\t\t\t\tresult.listModels = true;\n\t\t\t}\n\t\t} else if (arg === \"--verbose\") {\n\t\t\tresult.verbose = true;\n\t\t} else if (arg === \"--approve\" || arg === \"-a\") {\n\t\t\tresult.projectTrustOverride = true;\n\t\t} else if (arg === \"--no-approve\" || arg === \"-na\") {\n\t\t\tresult.projectTrustOverride = false;\n\t\t} else if (arg === \"--offline\") {\n\t\t\tresult.offline = true;\n\t\t} else if (arg.startsWith(\"@\")) {\n\t\t\tresult.fileArgs.push(arg.slice(1)); // Remove @ prefix\n\t\t} else if (arg.startsWith(\"--\")) {\n\t\t\tconst eqIndex = arg.indexOf(\"=\");\n\t\t\tif (eqIndex !== -1) {\n\t\t\t\tresult.unknownFlags.set(arg.slice(2, eqIndex), arg.slice(eqIndex + 1));\n\t\t\t} else {\n\t\t\t\tconst flagName = arg.slice(2);\n\t\t\t\tconst next = args[i + 1];\n\t\t\t\tif (next !== undefined && !next.startsWith(\"-\") && !next.startsWith(\"@\")) {\n\t\t\t\t\tresult.unknownFlags.set(flagName, next);\n\t\t\t\t\ti++;\n\t\t\t\t} else {\n\t\t\t\t\tresult.unknownFlags.set(flagName, true);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (arg.startsWith(\"-\") && !arg.startsWith(\"--\")) {\n\t\t\tresult.diagnostics.push({ type: \"error\", message: `Unknown option: ${arg}` });\n\t\t} else if (!arg.startsWith(\"-\")) {\n\t\t\tresult.messages.push(arg);\n\t\t}\n\t}\n\n\treturn result;\n}\n\nexport function printHelp(extensionFlags?: ExtensionFlag[]): void {\n\tconst extensionFlagsText =\n\t\textensionFlags && extensionFlags.length > 0\n\t\t\t? `\\n${chalk.bold(\"Extension CLI Flags:\")}\\n${extensionFlags\n\t\t\t\t\t.map((flag) => {\n\t\t\t\t\t\tconst value = flag.type === \"string\" ? \" <value>\" : \"\";\n\t\t\t\t\t\tconst description = flag.description ?? `Registered by ${flag.extensionPath}`;\n\t\t\t\t\t\treturn ` --${flag.name}${value}`.padEnd(30) + description;\n\t\t\t\t\t})\n\t\t\t\t\t.join(\"\\n\")}\\n`\n\t\t\t: \"\";\n\tconsole.log(`${chalk.bold(APP_NAME)} - AI coding assistant with read, bash, edit, write tools\n\n${chalk.bold(\"Usage:\")}\n ${APP_NAME} [options] [@files...] [messages...]\n\n${chalk.bold(\"Commands:\")}\n ${APP_NAME} install <source> [-l] Install extension source and add to settings\n ${APP_NAME} remove <source> [-l] Remove extension source from settings\n ${APP_NAME} uninstall <source> [-l] Alias for remove\n ${APP_NAME} update [source|self|pi] Update pi (use --all for pi and extensions)\n ${APP_NAME} list List installed extensions from settings\n ${APP_NAME} config [-l] Open TUI to enable/disable package resources (Tab switches scope)\n ${APP_NAME} <command> --help Show help for install/remove/uninstall/update/list/config\n\n${chalk.bold(\"Options:\")}\n --provider <name> Provider name (default: google)\n --model <pattern> Model pattern or ID (supports \"provider/id\" and optional \":<thinking>\")\n --api-key <key> API key (defaults to env vars)\n --system-prompt <text> System prompt (default: coding assistant prompt)\n --append-system-prompt <text> Append text or file contents to the system prompt (can be used multiple times)\n --mode <mode> Output mode: text (default), json, or rpc\n --print, -p Non-interactive mode: process prompt and exit\n --continue, -c Continue previous session\n --resume, -r Select a session to resume\n --session <path|id> Use specific session file or partial UUID\n --session-id <id> Use exact project session ID, creating it if missing\n --fork <path|id> Fork specific session file or partial UUID into a new session\n --session-dir <dir> Directory for session storage and lookup\n --no-session Don't save session (ephemeral)\n --name, -n <name> Set session display name\n --models <patterns> Comma-separated model patterns for Ctrl+P cycling\n Supports globs (anthropic/*, *sonnet*) and fuzzy matching\n --no-tools, -nt Disable all tools by default (built-in and extension)\n --no-builtin-tools, -nbt Disable built-in tools by default but keep extension/custom tools enabled\n --tools, -t <tools> Comma-separated allowlist of tool names to enable\n Applies to built-in, extension, and custom tools\n --exclude-tools, -xt <tools> Comma-separated denylist of tool names to disable\n Applies to built-in, extension, and custom tools\n --thinking <level> Set thinking level: off, minimal, low, medium, high, xhigh, max\n --extension, -e <path> Load an extension file (can be used multiple times)\n --no-extensions, -ne Disable extension discovery (explicit -e paths still work)\n --skill <path> Load a skill file or directory (can be used multiple times)\n --no-skills, -ns Disable skills discovery and loading\n --prompt-template <path> Load a prompt template file or directory (can be used multiple times)\n --no-prompt-templates, -np Disable prompt template discovery and loading\n --theme <path> Load a theme file or directory (can be used multiple times)\n --no-themes Disable theme discovery and loading\n --no-context-files, -nc Disable AGENTS.md and CLAUDE.md discovery and loading\n --export <file> Export session file to HTML and exit\n --list-models [search] List available models (with optional fuzzy search)\n --verbose Force verbose startup (overrides quietStartup setting)\n --approve, -a Trust project-local files for this run\n --no-approve, -na Ignore project-local files for this run\n --offline Disable startup network operations (same as PI_OFFLINE=1)\n --help, -h Show this help\n --version, -v Show version number\n\nExtensions can register additional flags (e.g., --plan from plan-mode extension).${extensionFlagsText}\n\n${chalk.bold(\"Examples:\")}\n # Interactive mode\n ${APP_NAME}\n\n # Interactive mode with initial prompt\n ${APP_NAME} \"List all .ts files in src/\"\n\n # Include files in initial message\n ${APP_NAME} @prompt.md @image.png \"What color is the sky?\"\n\n # Non-interactive mode (process and exit)\n ${APP_NAME} -p \"List all .ts files in src/\"\n\n # Multiple messages (interactive)\n ${APP_NAME} \"Read package.json\" \"What dependencies do we have?\"\n\n # Continue previous session\n ${APP_NAME} --continue \"What did we discuss?\"\n\n # Start a named session\n ${APP_NAME} --name \"Refactor auth module\"\n\n # Use different model\n ${APP_NAME} --provider openai --model gpt-4o-mini \"Help me refactor this code\"\n\n # Use model with provider prefix (no --provider needed)\n ${APP_NAME} --model openai/gpt-4o \"Help me refactor this code\"\n\n # Use model with thinking level shorthand\n ${APP_NAME} --model sonnet:high \"Solve this complex problem\"\n\n # Limit model cycling to specific models\n ${APP_NAME} --models claude-sonnet,claude-haiku,gpt-4o\n\n # Limit to a specific provider with glob pattern\n ${APP_NAME} --models \"github-copilot/*\"\n\n # Cycle models with fixed thinking levels\n ${APP_NAME} --models sonnet:high,haiku:low\n\n # Start with a specific thinking level\n ${APP_NAME} --thinking high \"Solve this complex problem\"\n\n # Read-only mode (no file modifications possible)\n ${APP_NAME} --tools read,grep,find,ls -p \"Review the code in src/\"\n\n # Disable one tool while keeping the rest available\n ${APP_NAME} --exclude-tools ask_question\n\n # Export a session file to HTML\n ${APP_NAME} --export ~/${CONFIG_DIR_NAME}/agent/sessions/--path--/session.jsonl\n ${APP_NAME} --export session.jsonl output.html\n\n${chalk.bold(\"Environment Variables:\")}\n ANTHROPIC_API_KEY - Anthropic Claude API key\n ANTHROPIC_OAUTH_TOKEN - Anthropic OAuth token (alternative to API key)\n ANT_LING_API_KEY - Ant Ling API key\n OPENAI_API_KEY - OpenAI GPT API key\n AZURE_OPENAI_API_KEY - Azure OpenAI API key\n AZURE_OPENAI_BASE_URL - Azure OpenAI/Cognitive Services base URL (e.g. https://{resource}.openai.azure.com)\n AZURE_OPENAI_RESOURCE_NAME - Azure OpenAI resource name (alternative to base URL)\n AZURE_OPENAI_API_VERSION - Azure OpenAI API version (default: v1)\n AZURE_OPENAI_DEPLOYMENT_NAME_MAP - Azure OpenAI model=deployment map (comma-separated)\n DEEPSEEK_API_KEY - DeepSeek API key\n NVIDIA_API_KEY - NVIDIA NIM API key\n GEMINI_API_KEY - Google Gemini API key\n GROQ_API_KEY - Groq API key\n CEREBRAS_API_KEY - Cerebras API key\n XAI_API_KEY - xAI Grok API key\n FIREWORKS_API_KEY - Fireworks API key\n TOGETHER_API_KEY - Together AI API key\n OPENROUTER_API_KEY - OpenRouter API key\n AI_GATEWAY_API_KEY - Vercel AI Gateway API key\n ZAI_API_KEY - ZAI Coding Plan API key (Global)\n ZAI_CODING_CN_API_KEY - ZAI Coding Plan API key (China)\n MISTRAL_API_KEY - Mistral API key\n MINIMAX_API_KEY - MiniMax API key\n MOONSHOT_API_KEY - Moonshot AI API key\n OPENCODE_API_KEY - OpenCode Zen/OpenCode Go API key\n KIMI_API_KEY - Kimi For Coding API key\n CLOUDFLARE_API_KEY - Cloudflare API token (Workers AI and AI Gateway)\n CLOUDFLARE_ACCOUNT_ID - Cloudflare account id (required for both)\n CLOUDFLARE_GATEWAY_ID - Cloudflare AI Gateway slug (required for AI Gateway)\n XIAOMI_API_KEY - Xiaomi MiMo API key (api.xiaomimimo.com billing)\n XIAOMI_TOKEN_PLAN_CN_API_KEY - Xiaomi MiMo Token Plan API key (China region)\n XIAOMI_TOKEN_PLAN_AMS_API_KEY - Xiaomi MiMo Token Plan API key (Amsterdam region)\n XIAOMI_TOKEN_PLAN_SGP_API_KEY - Xiaomi MiMo Token Plan API key (Singapore region)\n AWS_PROFILE - AWS profile for Amazon Bedrock\n AWS_ACCESS_KEY_ID - AWS access key for Amazon Bedrock\n AWS_SECRET_ACCESS_KEY - AWS secret key for Amazon Bedrock\n AWS_BEARER_TOKEN_BEDROCK - Bedrock API key (bearer token)\n AWS_REGION - AWS region for Amazon Bedrock (e.g., us-east-1)\n ${ENV_AGENT_DIR.padEnd(32)} - Config directory (default: ~/${CONFIG_DIR_NAME}/agent)\n ${ENV_SESSION_DIR.padEnd(32)} - Session storage directory (overridden by --session-dir)\n PI_PACKAGE_DIR - Override package directory (for Nix/Guix store paths)\n PI_OFFLINE - Disable startup network operations when set to 1/true/yes\n PI_TELEMETRY - Override install telemetry when set to 1/true/yes or 0/false/no\n PI_SHARE_VIEWER_URL - Base URL for /share command (default: https://pi.dev/session/)\n\n${chalk.bold(\"Built-in Tool Names:\")}\n read - Read file contents\n bash - Execute bash commands\n edit - Edit files with find/replace\n write - Write files (creates/overwrites)\n grep - Search file contents (read-only, off by default)\n find - Find files by glob pattern (read-only, off by default)\n ls - List directory contents (read-only, off by default)\n`);\n}\n"]}
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAGnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEjE,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAE3C,MAAM,WAAW,IAAI;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,8EAA8E;IAC9E,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC,CAAC;IAC5C,WAAW,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnE;AAID,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,aAAa,CAE1E;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAmJ9C;AAED,wBAAgB,SAAS,CAAC,cAAc,CAAC,EAAE,aAAa,EAAE,GAAG,IAAI,CAkLhE","sourcesContent":["/**\n * CLI argument parsing and help display\n */\n\nimport type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport chalk from \"chalk\";\nimport { APP_NAME, CONFIG_DIR_NAME, ENV_AGENT_DIR, ENV_SESSION_DIR } from \"../config.ts\";\nimport type { ExtensionFlag } from \"../core/extensions/types.ts\";\n\nexport type Mode = \"text\" | \"json\" | \"rpc\";\n\nexport interface Args {\n\tprovider?: string;\n\tmodel?: string;\n\tapiKey?: string;\n\tsystemPrompt?: string;\n\tappendSystemPrompt?: string[];\n\tthinking?: ThinkingLevel;\n\tcontinue?: boolean;\n\tresume?: boolean;\n\thelp?: boolean;\n\tversion?: boolean;\n\tmode?: Mode;\n\tname?: string;\n\tnoSession?: boolean;\n\tsession?: string;\n\tsessionId?: string;\n\tfork?: string;\n\tsessionDir?: string;\n\tmodels?: string[];\n\ttools?: string[];\n\texcludeTools?: string[];\n\tnoTools?: boolean;\n\tnoBuiltinTools?: boolean;\n\textensions?: string[];\n\tnoExtensions?: boolean;\n\tprint?: boolean;\n\texport?: string;\n\tnoSkills?: boolean;\n\tskills?: string[];\n\tpromptTemplates?: string[];\n\tnoPromptTemplates?: boolean;\n\tthemes?: string[];\n\tnoThemes?: boolean;\n\tnoContextFiles?: boolean;\n\tlistModels?: string | true;\n\toffline?: boolean;\n\tverbose?: boolean;\n\tprojectTrustOverride?: boolean;\n\tmessages: string[];\n\tfileArgs: string[];\n\t/** Unknown flags (potentially extension flags) - map of flag name to value */\n\tunknownFlags: Map<string, boolean | string>;\n\tdiagnostics: Array<{ type: \"warning\" | \"error\"; message: string }>;\n}\n\nconst VALID_THINKING_LEVELS = [\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\"] as const;\n\nexport function isValidThinkingLevel(level: string): level is ThinkingLevel {\n\treturn VALID_THINKING_LEVELS.includes(level as ThinkingLevel);\n}\n\nexport function parseArgs(args: string[]): Args {\n\tconst result: Args = {\n\t\tmessages: [],\n\t\tfileArgs: [],\n\t\tunknownFlags: new Map(),\n\t\tdiagnostics: [],\n\t};\n\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i];\n\n\t\tif (arg === \"--help\" || arg === \"-h\") {\n\t\t\tresult.help = true;\n\t\t} else if (arg === \"--version\" || arg === \"-v\") {\n\t\t\tresult.version = true;\n\t\t} else if (arg === \"--mode\" && i + 1 < args.length) {\n\t\t\tconst mode = args[++i];\n\t\t\tif (mode === \"text\" || mode === \"json\" || mode === \"rpc\") {\n\t\t\t\tresult.mode = mode;\n\t\t\t}\n\t\t} else if (arg === \"--continue\" || arg === \"-c\") {\n\t\t\tresult.continue = true;\n\t\t} else if (arg === \"--resume\" || arg === \"-r\") {\n\t\t\tresult.resume = true;\n\t\t} else if (arg === \"--provider\" && i + 1 < args.length) {\n\t\t\tresult.provider = args[++i];\n\t\t} else if (arg === \"--model\" && i + 1 < args.length) {\n\t\t\tresult.model = args[++i];\n\t\t} else if (arg === \"--api-key\" && i + 1 < args.length) {\n\t\t\tresult.apiKey = args[++i];\n\t\t} else if (arg === \"--system-prompt\" && i + 1 < args.length) {\n\t\t\tresult.systemPrompt = args[++i];\n\t\t} else if (arg === \"--append-system-prompt\" && i + 1 < args.length) {\n\t\t\tresult.appendSystemPrompt = result.appendSystemPrompt ?? [];\n\t\t\tresult.appendSystemPrompt.push(args[++i]);\n\t\t} else if (arg === \"--name\" || arg === \"-n\") {\n\t\t\tif (i + 1 < args.length) {\n\t\t\t\tresult.name = args[++i];\n\t\t\t} else {\n\t\t\t\tresult.diagnostics.push({ type: \"error\", message: \"--name requires a value\" });\n\t\t\t}\n\t\t} else if (arg === \"--no-session\") {\n\t\t\tresult.noSession = true;\n\t\t} else if (arg === \"--session\" && i + 1 < args.length) {\n\t\t\tresult.session = args[++i];\n\t\t} else if (arg === \"--session-id\" && i + 1 < args.length) {\n\t\t\tresult.sessionId = args[++i];\n\t\t} else if (arg === \"--fork\" && i + 1 < args.length) {\n\t\t\tresult.fork = args[++i];\n\t\t} else if (arg === \"--session-dir\" && i + 1 < args.length) {\n\t\t\tresult.sessionDir = args[++i];\n\t\t} else if (arg === \"--models\" && i + 1 < args.length) {\n\t\t\tresult.models = args[++i].split(\",\").map((s) => s.trim());\n\t\t} else if (arg === \"--no-tools\" || arg === \"-nt\") {\n\t\t\tresult.noTools = true;\n\t\t} else if (arg === \"--no-builtin-tools\" || arg === \"-nbt\") {\n\t\t\tresult.noBuiltinTools = true;\n\t\t} else if ((arg === \"--tools\" || arg === \"-t\") && i + 1 < args.length) {\n\t\t\tresult.tools = args[++i]\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim())\n\t\t\t\t.filter((name) => name.length > 0);\n\t\t} else if ((arg === \"--exclude-tools\" || arg === \"-xt\") && i + 1 < args.length) {\n\t\t\tresult.excludeTools = args[++i]\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim())\n\t\t\t\t.filter((name) => name.length > 0);\n\t\t} else if (arg === \"--thinking\" && i + 1 < args.length) {\n\t\t\tconst level = args[++i];\n\t\t\tif (isValidThinkingLevel(level)) {\n\t\t\t\tresult.thinking = level;\n\t\t\t} else {\n\t\t\t\tresult.diagnostics.push({\n\t\t\t\t\ttype: \"warning\",\n\t\t\t\t\tmessage: `Invalid thinking level \"${level}\". Valid values: ${VALID_THINKING_LEVELS.join(\", \")}`,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (arg === \"--print\" || arg === \"-p\") {\n\t\t\tresult.print = true;\n\t\t\tconst next = args[i + 1];\n\t\t\tif (next !== undefined && !next.startsWith(\"@\") && (!next.startsWith(\"-\") || next.startsWith(\"---\"))) {\n\t\t\t\tresult.messages.push(next);\n\t\t\t\ti++;\n\t\t\t}\n\t\t} else if (arg === \"--export\" && i + 1 < args.length) {\n\t\t\tresult.export = args[++i];\n\t\t} else if ((arg === \"--extension\" || arg === \"-e\") && i + 1 < args.length) {\n\t\t\tresult.extensions = result.extensions ?? [];\n\t\t\tresult.extensions.push(args[++i]);\n\t\t} else if (arg === \"--no-extensions\" || arg === \"-ne\") {\n\t\t\tresult.noExtensions = true;\n\t\t} else if (arg === \"--skill\" && i + 1 < args.length) {\n\t\t\tresult.skills = result.skills ?? [];\n\t\t\tresult.skills.push(args[++i]);\n\t\t} else if (arg === \"--prompt-template\" && i + 1 < args.length) {\n\t\t\tresult.promptTemplates = result.promptTemplates ?? [];\n\t\t\tresult.promptTemplates.push(args[++i]);\n\t\t} else if (arg === \"--theme\" && i + 1 < args.length) {\n\t\t\tresult.themes = result.themes ?? [];\n\t\t\tresult.themes.push(args[++i]);\n\t\t} else if (arg === \"--no-skills\" || arg === \"-ns\") {\n\t\t\tresult.noSkills = true;\n\t\t} else if (arg === \"--no-prompt-templates\" || arg === \"-np\") {\n\t\t\tresult.noPromptTemplates = true;\n\t\t} else if (arg === \"--no-themes\") {\n\t\t\tresult.noThemes = true;\n\t\t} else if (arg === \"--no-context-files\" || arg === \"-nc\") {\n\t\t\tresult.noContextFiles = true;\n\t\t} else if (arg === \"--list-models\") {\n\t\t\t// Check if next arg is a search pattern (not a flag or file arg)\n\t\t\tif (i + 1 < args.length && !args[i + 1].startsWith(\"-\") && !args[i + 1].startsWith(\"@\")) {\n\t\t\t\tresult.listModels = args[++i];\n\t\t\t} else {\n\t\t\t\tresult.listModels = true;\n\t\t\t}\n\t\t} else if (arg === \"--verbose\") {\n\t\t\tresult.verbose = true;\n\t\t} else if (arg === \"--approve\" || arg === \"-a\") {\n\t\t\tresult.projectTrustOverride = true;\n\t\t} else if (arg === \"--no-approve\" || arg === \"-na\") {\n\t\t\tresult.projectTrustOverride = false;\n\t\t} else if (arg === \"--offline\") {\n\t\t\tresult.offline = true;\n\t\t} else if (arg.startsWith(\"@\")) {\n\t\t\tresult.fileArgs.push(arg.slice(1)); // Remove @ prefix\n\t\t} else if (arg.startsWith(\"--\")) {\n\t\t\tconst eqIndex = arg.indexOf(\"=\");\n\t\t\tif (eqIndex !== -1) {\n\t\t\t\tresult.unknownFlags.set(arg.slice(2, eqIndex), arg.slice(eqIndex + 1));\n\t\t\t} else {\n\t\t\t\tconst flagName = arg.slice(2);\n\t\t\t\tconst next = args[i + 1];\n\t\t\t\tif (next !== undefined && !next.startsWith(\"-\") && !next.startsWith(\"@\")) {\n\t\t\t\t\tresult.unknownFlags.set(flagName, next);\n\t\t\t\t\ti++;\n\t\t\t\t} else {\n\t\t\t\t\tresult.unknownFlags.set(flagName, true);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (arg.startsWith(\"-\") && !arg.startsWith(\"--\")) {\n\t\t\tresult.diagnostics.push({ type: \"error\", message: `Unknown option: ${arg}` });\n\t\t} else if (!arg.startsWith(\"-\")) {\n\t\t\tresult.messages.push(arg);\n\t\t}\n\t}\n\n\treturn result;\n}\n\nexport function printHelp(extensionFlags?: ExtensionFlag[]): void {\n\tconst extensionFlagsText =\n\t\textensionFlags && extensionFlags.length > 0\n\t\t\t? `\\n${chalk.bold(\"Extension CLI Flags:\")}\\n${extensionFlags\n\t\t\t\t\t.map((flag) => {\n\t\t\t\t\t\tconst value = flag.type === \"string\" ? \" <value>\" : \"\";\n\t\t\t\t\t\tconst description = flag.description ?? `Registered by ${flag.extensionPath}`;\n\t\t\t\t\t\treturn ` --${flag.name}${value}`.padEnd(30) + description;\n\t\t\t\t\t})\n\t\t\t\t\t.join(\"\\n\")}\\n`\n\t\t\t: \"\";\n\tconsole.log(`${chalk.bold(APP_NAME)} - AI coding assistant with read, bash, edit, write tools\n\n${chalk.bold(\"Usage:\")}\n ${APP_NAME} [options] [@files...] [messages...]\n\n${chalk.bold(\"Commands:\")}\n ${APP_NAME} install <source> [-l] Install extension source and add to settings\n ${APP_NAME} remove <source> [-l] Remove extension source from settings\n ${APP_NAME} uninstall <source> [-l] Alias for remove\n ${APP_NAME} update [source|self|pi] Update pi, extensions, or model catalogs\n ${APP_NAME} list List installed extensions from settings\n ${APP_NAME} config [-l] Open TUI to enable/disable package resources (Tab switches scope)\n ${APP_NAME} <command> --help Show help for install/remove/uninstall/update/list/config\n\n${chalk.bold(\"Options:\")}\n --provider <name> Provider name (default: google)\n --model <pattern> Model pattern or ID (supports \"provider/id\" and optional \":<thinking>\")\n --api-key <key> API key (defaults to env vars)\n --system-prompt <text> System prompt (default: coding assistant prompt)\n --append-system-prompt <text> Append text or file contents to the system prompt (can be used multiple times)\n --mode <mode> Output mode: text (default), json, or rpc\n --print, -p Non-interactive mode: process prompt and exit\n --continue, -c Continue previous session\n --resume, -r Select a session to resume\n --session <path|id> Use specific session file or partial UUID\n --session-id <id> Use exact project session ID, creating it if missing\n --fork <path|id> Fork specific session file or partial UUID into a new session\n --session-dir <dir> Directory for session storage and lookup\n --no-session Don't save session (ephemeral)\n --name, -n <name> Set session display name\n --models <patterns> Comma-separated model patterns for Ctrl+P cycling\n Supports globs (anthropic/*, *sonnet*) and fuzzy matching\n --no-tools, -nt Disable all tools by default (built-in and extension)\n --no-builtin-tools, -nbt Disable built-in tools by default but keep extension/custom tools enabled\n --tools, -t <tools> Comma-separated allowlist of tool names to enable\n Applies to built-in, extension, and custom tools\n --exclude-tools, -xt <tools> Comma-separated denylist of tool names to disable\n Applies to built-in, extension, and custom tools\n --thinking <level> Set thinking level: off, minimal, low, medium, high, xhigh, max\n --extension, -e <path> Load an extension file (can be used multiple times)\n --no-extensions, -ne Disable extension discovery (explicit -e paths still work)\n --skill <path> Load a skill file or directory (can be used multiple times)\n --no-skills, -ns Disable skills discovery and loading\n --prompt-template <path> Load a prompt template file or directory (can be used multiple times)\n --no-prompt-templates, -np Disable prompt template discovery and loading\n --theme <path> Load a theme file or directory (can be used multiple times)\n --no-themes Disable theme discovery and loading\n --no-context-files, -nc Disable AGENTS.md and CLAUDE.md discovery and loading\n --export <file> Export session file to HTML and exit\n --list-models [search] List available models (with optional fuzzy search)\n --verbose Force verbose startup (overrides quietStartup setting)\n --approve, -a Trust project-local files for this run\n --no-approve, -na Ignore project-local files for this run\n --offline Disable startup network operations (same as PI_OFFLINE=1)\n --help, -h Show this help\n --version, -v Show version number\n\nExtensions can register additional flags (e.g., --plan from plan-mode extension).${extensionFlagsText}\n\n${chalk.bold(\"Examples:\")}\n # Interactive mode\n ${APP_NAME}\n\n # Interactive mode with initial prompt\n ${APP_NAME} \"List all .ts files in src/\"\n\n # Include files in initial message\n ${APP_NAME} @prompt.md @image.png \"What color is the sky?\"\n\n # Non-interactive mode (process and exit)\n ${APP_NAME} -p \"List all .ts files in src/\"\n\n # Multiple messages (interactive)\n ${APP_NAME} \"Read package.json\" \"What dependencies do we have?\"\n\n # Continue previous session\n ${APP_NAME} --continue \"What did we discuss?\"\n\n # Start a named session\n ${APP_NAME} --name \"Refactor auth module\"\n\n # Use different model\n ${APP_NAME} --provider openai --model gpt-4o-mini \"Help me refactor this code\"\n\n # Use model with provider prefix (no --provider needed)\n ${APP_NAME} --model openai/gpt-4o \"Help me refactor this code\"\n\n # Use model with thinking level shorthand\n ${APP_NAME} --model sonnet:high \"Solve this complex problem\"\n\n # Limit model cycling to specific models\n ${APP_NAME} --models claude-sonnet,claude-haiku,gpt-4o\n\n # Limit to a specific provider with glob pattern\n ${APP_NAME} --models \"github-copilot/*\"\n\n # Cycle models with fixed thinking levels\n ${APP_NAME} --models sonnet:high,haiku:low\n\n # Start with a specific thinking level\n ${APP_NAME} --thinking high \"Solve this complex problem\"\n\n # Read-only mode (no file modifications possible)\n ${APP_NAME} --tools read,grep,find,ls -p \"Review the code in src/\"\n\n # Disable one tool while keeping the rest available\n ${APP_NAME} --exclude-tools ask_question\n\n # Export a session file to HTML\n ${APP_NAME} --export ~/${CONFIG_DIR_NAME}/agent/sessions/--path--/session.jsonl\n ${APP_NAME} --export session.jsonl output.html\n\n${chalk.bold(\"Environment Variables:\")}\n ANTHROPIC_API_KEY - Anthropic Claude API key\n ANTHROPIC_OAUTH_TOKEN - Anthropic OAuth token (alternative to API key)\n ANT_LING_API_KEY - Ant Ling API key\n OPENAI_API_KEY - OpenAI GPT API key\n AZURE_OPENAI_API_KEY - Azure OpenAI API key\n AZURE_OPENAI_BASE_URL - Azure OpenAI/Cognitive Services base URL (e.g. https://{resource}.openai.azure.com)\n AZURE_OPENAI_RESOURCE_NAME - Azure OpenAI resource name (alternative to base URL)\n AZURE_OPENAI_API_VERSION - Azure OpenAI API version (default: v1)\n AZURE_OPENAI_DEPLOYMENT_NAME_MAP - Azure OpenAI model=deployment map (comma-separated)\n DEEPSEEK_API_KEY - DeepSeek API key\n NVIDIA_API_KEY - NVIDIA NIM API key\n GEMINI_API_KEY - Google Gemini API key\n GROQ_API_KEY - Groq API key\n CEREBRAS_API_KEY - Cerebras API key\n XAI_API_KEY - xAI Grok API key\n FIREWORKS_API_KEY - Fireworks API key\n TOGETHER_API_KEY - Together AI API key\n OPENROUTER_API_KEY - OpenRouter API key\n AI_GATEWAY_API_KEY - Vercel AI Gateway API key\n ZAI_API_KEY - ZAI Coding Plan API key (Global)\n ZAI_CODING_CN_API_KEY - ZAI Coding Plan API key (China)\n MISTRAL_API_KEY - Mistral API key\n MINIMAX_API_KEY - MiniMax API key\n MOONSHOT_API_KEY - Moonshot AI API key\n OPENCODE_API_KEY - OpenCode Zen/OpenCode Go API key\n KIMI_API_KEY - Kimi For Coding API key\n CLOUDFLARE_API_KEY - Cloudflare API token (Workers AI and AI Gateway)\n CLOUDFLARE_ACCOUNT_ID - Cloudflare account id (required for both)\n CLOUDFLARE_GATEWAY_ID - Cloudflare AI Gateway slug (required for AI Gateway)\n XIAOMI_API_KEY - Xiaomi MiMo API key (api.xiaomimimo.com billing)\n XIAOMI_TOKEN_PLAN_CN_API_KEY - Xiaomi MiMo Token Plan API key (China region)\n XIAOMI_TOKEN_PLAN_AMS_API_KEY - Xiaomi MiMo Token Plan API key (Amsterdam region)\n XIAOMI_TOKEN_PLAN_SGP_API_KEY - Xiaomi MiMo Token Plan API key (Singapore region)\n AWS_PROFILE - AWS profile for Amazon Bedrock\n AWS_ACCESS_KEY_ID - AWS access key for Amazon Bedrock\n AWS_SECRET_ACCESS_KEY - AWS secret key for Amazon Bedrock\n AWS_BEARER_TOKEN_BEDROCK - Bedrock API key (bearer token)\n AWS_REGION - AWS region for Amazon Bedrock (e.g., us-east-1)\n ${ENV_AGENT_DIR.padEnd(32)} - Config directory (default: ~/${CONFIG_DIR_NAME}/agent)\n ${ENV_SESSION_DIR.padEnd(32)} - Session storage directory (overridden by --session-dir)\n PI_PACKAGE_DIR - Override package directory (for Nix/Guix store paths)\n PI_OFFLINE - Disable startup network operations when set to 1/true/yes\n PI_TELEMETRY - Override install telemetry when set to 1/true/yes or 0/false/no\n PI_SHARE_VIEWER_URL - Base URL for /share command (default: https://pi.dev/session/)\n\n${chalk.bold(\"Built-in Tool Names:\")}\n read - Read file contents\n bash - Execute bash commands\n edit - Edit files with find/replace\n write - Write files (creates/overwrites)\n grep - Search file contents (read-only, off by default)\n find - Find files by glob pattern (read-only, off by default)\n ls - List directory contents (read-only, off by default)\n`);\n}\n"]}
package/dist/cli/args.js CHANGED
@@ -217,7 +217,7 @@ ${chalk.bold("Commands:")}
217
217
  ${APP_NAME} install <source> [-l] Install extension source and add to settings
218
218
  ${APP_NAME} remove <source> [-l] Remove extension source from settings
219
219
  ${APP_NAME} uninstall <source> [-l] Alias for remove
220
- ${APP_NAME} update [source|self|pi] Update pi (use --all for pi and extensions)
220
+ ${APP_NAME} update [source|self|pi] Update pi, extensions, or model catalogs
221
221
  ${APP_NAME} list List installed extensions from settings
222
222
  ${APP_NAME} config [-l] Open TUI to enable/disable package resources (Tab switches scope)
223
223
  ${APP_NAME} <command> --help Show help for install/remove/uninstall/update/list/config
@@ -1 +1 @@
1
- {"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * CLI argument parsing and help display\n */\n\nimport type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport chalk from \"chalk\";\nimport { APP_NAME, CONFIG_DIR_NAME, ENV_AGENT_DIR, ENV_SESSION_DIR } from \"../config.ts\";\nimport type { ExtensionFlag } from \"../core/extensions/types.ts\";\n\nexport type Mode = \"text\" | \"json\" | \"rpc\";\n\nexport interface Args {\n\tprovider?: string;\n\tmodel?: string;\n\tapiKey?: string;\n\tsystemPrompt?: string;\n\tappendSystemPrompt?: string[];\n\tthinking?: ThinkingLevel;\n\tcontinue?: boolean;\n\tresume?: boolean;\n\thelp?: boolean;\n\tversion?: boolean;\n\tmode?: Mode;\n\tname?: string;\n\tnoSession?: boolean;\n\tsession?: string;\n\tsessionId?: string;\n\tfork?: string;\n\tsessionDir?: string;\n\tmodels?: string[];\n\ttools?: string[];\n\texcludeTools?: string[];\n\tnoTools?: boolean;\n\tnoBuiltinTools?: boolean;\n\textensions?: string[];\n\tnoExtensions?: boolean;\n\tprint?: boolean;\n\texport?: string;\n\tnoSkills?: boolean;\n\tskills?: string[];\n\tpromptTemplates?: string[];\n\tnoPromptTemplates?: boolean;\n\tthemes?: string[];\n\tnoThemes?: boolean;\n\tnoContextFiles?: boolean;\n\tlistModels?: string | true;\n\toffline?: boolean;\n\tverbose?: boolean;\n\tprojectTrustOverride?: boolean;\n\tmessages: string[];\n\tfileArgs: string[];\n\t/** Unknown flags (potentially extension flags) - map of flag name to value */\n\tunknownFlags: Map<string, boolean | string>;\n\tdiagnostics: Array<{ type: \"warning\" | \"error\"; message: string }>;\n}\n\nconst VALID_THINKING_LEVELS = [\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\"] as const;\n\nexport function isValidThinkingLevel(level: string): level is ThinkingLevel {\n\treturn VALID_THINKING_LEVELS.includes(level as ThinkingLevel);\n}\n\nexport function parseArgs(args: string[]): Args {\n\tconst result: Args = {\n\t\tmessages: [],\n\t\tfileArgs: [],\n\t\tunknownFlags: new Map(),\n\t\tdiagnostics: [],\n\t};\n\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i];\n\n\t\tif (arg === \"--help\" || arg === \"-h\") {\n\t\t\tresult.help = true;\n\t\t} else if (arg === \"--version\" || arg === \"-v\") {\n\t\t\tresult.version = true;\n\t\t} else if (arg === \"--mode\" && i + 1 < args.length) {\n\t\t\tconst mode = args[++i];\n\t\t\tif (mode === \"text\" || mode === \"json\" || mode === \"rpc\") {\n\t\t\t\tresult.mode = mode;\n\t\t\t}\n\t\t} else if (arg === \"--continue\" || arg === \"-c\") {\n\t\t\tresult.continue = true;\n\t\t} else if (arg === \"--resume\" || arg === \"-r\") {\n\t\t\tresult.resume = true;\n\t\t} else if (arg === \"--provider\" && i + 1 < args.length) {\n\t\t\tresult.provider = args[++i];\n\t\t} else if (arg === \"--model\" && i + 1 < args.length) {\n\t\t\tresult.model = args[++i];\n\t\t} else if (arg === \"--api-key\" && i + 1 < args.length) {\n\t\t\tresult.apiKey = args[++i];\n\t\t} else if (arg === \"--system-prompt\" && i + 1 < args.length) {\n\t\t\tresult.systemPrompt = args[++i];\n\t\t} else if (arg === \"--append-system-prompt\" && i + 1 < args.length) {\n\t\t\tresult.appendSystemPrompt = result.appendSystemPrompt ?? [];\n\t\t\tresult.appendSystemPrompt.push(args[++i]);\n\t\t} else if (arg === \"--name\" || arg === \"-n\") {\n\t\t\tif (i + 1 < args.length) {\n\t\t\t\tresult.name = args[++i];\n\t\t\t} else {\n\t\t\t\tresult.diagnostics.push({ type: \"error\", message: \"--name requires a value\" });\n\t\t\t}\n\t\t} else if (arg === \"--no-session\") {\n\t\t\tresult.noSession = true;\n\t\t} else if (arg === \"--session\" && i + 1 < args.length) {\n\t\t\tresult.session = args[++i];\n\t\t} else if (arg === \"--session-id\" && i + 1 < args.length) {\n\t\t\tresult.sessionId = args[++i];\n\t\t} else if (arg === \"--fork\" && i + 1 < args.length) {\n\t\t\tresult.fork = args[++i];\n\t\t} else if (arg === \"--session-dir\" && i + 1 < args.length) {\n\t\t\tresult.sessionDir = args[++i];\n\t\t} else if (arg === \"--models\" && i + 1 < args.length) {\n\t\t\tresult.models = args[++i].split(\",\").map((s) => s.trim());\n\t\t} else if (arg === \"--no-tools\" || arg === \"-nt\") {\n\t\t\tresult.noTools = true;\n\t\t} else if (arg === \"--no-builtin-tools\" || arg === \"-nbt\") {\n\t\t\tresult.noBuiltinTools = true;\n\t\t} else if ((arg === \"--tools\" || arg === \"-t\") && i + 1 < args.length) {\n\t\t\tresult.tools = args[++i]\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim())\n\t\t\t\t.filter((name) => name.length > 0);\n\t\t} else if ((arg === \"--exclude-tools\" || arg === \"-xt\") && i + 1 < args.length) {\n\t\t\tresult.excludeTools = args[++i]\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim())\n\t\t\t\t.filter((name) => name.length > 0);\n\t\t} else if (arg === \"--thinking\" && i + 1 < args.length) {\n\t\t\tconst level = args[++i];\n\t\t\tif (isValidThinkingLevel(level)) {\n\t\t\t\tresult.thinking = level;\n\t\t\t} else {\n\t\t\t\tresult.diagnostics.push({\n\t\t\t\t\ttype: \"warning\",\n\t\t\t\t\tmessage: `Invalid thinking level \"${level}\". Valid values: ${VALID_THINKING_LEVELS.join(\", \")}`,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (arg === \"--print\" || arg === \"-p\") {\n\t\t\tresult.print = true;\n\t\t\tconst next = args[i + 1];\n\t\t\tif (next !== undefined && !next.startsWith(\"@\") && (!next.startsWith(\"-\") || next.startsWith(\"---\"))) {\n\t\t\t\tresult.messages.push(next);\n\t\t\t\ti++;\n\t\t\t}\n\t\t} else if (arg === \"--export\" && i + 1 < args.length) {\n\t\t\tresult.export = args[++i];\n\t\t} else if ((arg === \"--extension\" || arg === \"-e\") && i + 1 < args.length) {\n\t\t\tresult.extensions = result.extensions ?? [];\n\t\t\tresult.extensions.push(args[++i]);\n\t\t} else if (arg === \"--no-extensions\" || arg === \"-ne\") {\n\t\t\tresult.noExtensions = true;\n\t\t} else if (arg === \"--skill\" && i + 1 < args.length) {\n\t\t\tresult.skills = result.skills ?? [];\n\t\t\tresult.skills.push(args[++i]);\n\t\t} else if (arg === \"--prompt-template\" && i + 1 < args.length) {\n\t\t\tresult.promptTemplates = result.promptTemplates ?? [];\n\t\t\tresult.promptTemplates.push(args[++i]);\n\t\t} else if (arg === \"--theme\" && i + 1 < args.length) {\n\t\t\tresult.themes = result.themes ?? [];\n\t\t\tresult.themes.push(args[++i]);\n\t\t} else if (arg === \"--no-skills\" || arg === \"-ns\") {\n\t\t\tresult.noSkills = true;\n\t\t} else if (arg === \"--no-prompt-templates\" || arg === \"-np\") {\n\t\t\tresult.noPromptTemplates = true;\n\t\t} else if (arg === \"--no-themes\") {\n\t\t\tresult.noThemes = true;\n\t\t} else if (arg === \"--no-context-files\" || arg === \"-nc\") {\n\t\t\tresult.noContextFiles = true;\n\t\t} else if (arg === \"--list-models\") {\n\t\t\t// Check if next arg is a search pattern (not a flag or file arg)\n\t\t\tif (i + 1 < args.length && !args[i + 1].startsWith(\"-\") && !args[i + 1].startsWith(\"@\")) {\n\t\t\t\tresult.listModels = args[++i];\n\t\t\t} else {\n\t\t\t\tresult.listModels = true;\n\t\t\t}\n\t\t} else if (arg === \"--verbose\") {\n\t\t\tresult.verbose = true;\n\t\t} else if (arg === \"--approve\" || arg === \"-a\") {\n\t\t\tresult.projectTrustOverride = true;\n\t\t} else if (arg === \"--no-approve\" || arg === \"-na\") {\n\t\t\tresult.projectTrustOverride = false;\n\t\t} else if (arg === \"--offline\") {\n\t\t\tresult.offline = true;\n\t\t} else if (arg.startsWith(\"@\")) {\n\t\t\tresult.fileArgs.push(arg.slice(1)); // Remove @ prefix\n\t\t} else if (arg.startsWith(\"--\")) {\n\t\t\tconst eqIndex = arg.indexOf(\"=\");\n\t\t\tif (eqIndex !== -1) {\n\t\t\t\tresult.unknownFlags.set(arg.slice(2, eqIndex), arg.slice(eqIndex + 1));\n\t\t\t} else {\n\t\t\t\tconst flagName = arg.slice(2);\n\t\t\t\tconst next = args[i + 1];\n\t\t\t\tif (next !== undefined && !next.startsWith(\"-\") && !next.startsWith(\"@\")) {\n\t\t\t\t\tresult.unknownFlags.set(flagName, next);\n\t\t\t\t\ti++;\n\t\t\t\t} else {\n\t\t\t\t\tresult.unknownFlags.set(flagName, true);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (arg.startsWith(\"-\") && !arg.startsWith(\"--\")) {\n\t\t\tresult.diagnostics.push({ type: \"error\", message: `Unknown option: ${arg}` });\n\t\t} else if (!arg.startsWith(\"-\")) {\n\t\t\tresult.messages.push(arg);\n\t\t}\n\t}\n\n\treturn result;\n}\n\nexport function printHelp(extensionFlags?: ExtensionFlag[]): void {\n\tconst extensionFlagsText =\n\t\textensionFlags && extensionFlags.length > 0\n\t\t\t? `\\n${chalk.bold(\"Extension CLI Flags:\")}\\n${extensionFlags\n\t\t\t\t\t.map((flag) => {\n\t\t\t\t\t\tconst value = flag.type === \"string\" ? \" <value>\" : \"\";\n\t\t\t\t\t\tconst description = flag.description ?? `Registered by ${flag.extensionPath}`;\n\t\t\t\t\t\treturn ` --${flag.name}${value}`.padEnd(30) + description;\n\t\t\t\t\t})\n\t\t\t\t\t.join(\"\\n\")}\\n`\n\t\t\t: \"\";\n\tconsole.log(`${chalk.bold(APP_NAME)} - AI coding assistant with read, bash, edit, write tools\n\n${chalk.bold(\"Usage:\")}\n ${APP_NAME} [options] [@files...] [messages...]\n\n${chalk.bold(\"Commands:\")}\n ${APP_NAME} install <source> [-l] Install extension source and add to settings\n ${APP_NAME} remove <source> [-l] Remove extension source from settings\n ${APP_NAME} uninstall <source> [-l] Alias for remove\n ${APP_NAME} update [source|self|pi] Update pi (use --all for pi and extensions)\n ${APP_NAME} list List installed extensions from settings\n ${APP_NAME} config [-l] Open TUI to enable/disable package resources (Tab switches scope)\n ${APP_NAME} <command> --help Show help for install/remove/uninstall/update/list/config\n\n${chalk.bold(\"Options:\")}\n --provider <name> Provider name (default: google)\n --model <pattern> Model pattern or ID (supports \"provider/id\" and optional \":<thinking>\")\n --api-key <key> API key (defaults to env vars)\n --system-prompt <text> System prompt (default: coding assistant prompt)\n --append-system-prompt <text> Append text or file contents to the system prompt (can be used multiple times)\n --mode <mode> Output mode: text (default), json, or rpc\n --print, -p Non-interactive mode: process prompt and exit\n --continue, -c Continue previous session\n --resume, -r Select a session to resume\n --session <path|id> Use specific session file or partial UUID\n --session-id <id> Use exact project session ID, creating it if missing\n --fork <path|id> Fork specific session file or partial UUID into a new session\n --session-dir <dir> Directory for session storage and lookup\n --no-session Don't save session (ephemeral)\n --name, -n <name> Set session display name\n --models <patterns> Comma-separated model patterns for Ctrl+P cycling\n Supports globs (anthropic/*, *sonnet*) and fuzzy matching\n --no-tools, -nt Disable all tools by default (built-in and extension)\n --no-builtin-tools, -nbt Disable built-in tools by default but keep extension/custom tools enabled\n --tools, -t <tools> Comma-separated allowlist of tool names to enable\n Applies to built-in, extension, and custom tools\n --exclude-tools, -xt <tools> Comma-separated denylist of tool names to disable\n Applies to built-in, extension, and custom tools\n --thinking <level> Set thinking level: off, minimal, low, medium, high, xhigh, max\n --extension, -e <path> Load an extension file (can be used multiple times)\n --no-extensions, -ne Disable extension discovery (explicit -e paths still work)\n --skill <path> Load a skill file or directory (can be used multiple times)\n --no-skills, -ns Disable skills discovery and loading\n --prompt-template <path> Load a prompt template file or directory (can be used multiple times)\n --no-prompt-templates, -np Disable prompt template discovery and loading\n --theme <path> Load a theme file or directory (can be used multiple times)\n --no-themes Disable theme discovery and loading\n --no-context-files, -nc Disable AGENTS.md and CLAUDE.md discovery and loading\n --export <file> Export session file to HTML and exit\n --list-models [search] List available models (with optional fuzzy search)\n --verbose Force verbose startup (overrides quietStartup setting)\n --approve, -a Trust project-local files for this run\n --no-approve, -na Ignore project-local files for this run\n --offline Disable startup network operations (same as PI_OFFLINE=1)\n --help, -h Show this help\n --version, -v Show version number\n\nExtensions can register additional flags (e.g., --plan from plan-mode extension).${extensionFlagsText}\n\n${chalk.bold(\"Examples:\")}\n # Interactive mode\n ${APP_NAME}\n\n # Interactive mode with initial prompt\n ${APP_NAME} \"List all .ts files in src/\"\n\n # Include files in initial message\n ${APP_NAME} @prompt.md @image.png \"What color is the sky?\"\n\n # Non-interactive mode (process and exit)\n ${APP_NAME} -p \"List all .ts files in src/\"\n\n # Multiple messages (interactive)\n ${APP_NAME} \"Read package.json\" \"What dependencies do we have?\"\n\n # Continue previous session\n ${APP_NAME} --continue \"What did we discuss?\"\n\n # Start a named session\n ${APP_NAME} --name \"Refactor auth module\"\n\n # Use different model\n ${APP_NAME} --provider openai --model gpt-4o-mini \"Help me refactor this code\"\n\n # Use model with provider prefix (no --provider needed)\n ${APP_NAME} --model openai/gpt-4o \"Help me refactor this code\"\n\n # Use model with thinking level shorthand\n ${APP_NAME} --model sonnet:high \"Solve this complex problem\"\n\n # Limit model cycling to specific models\n ${APP_NAME} --models claude-sonnet,claude-haiku,gpt-4o\n\n # Limit to a specific provider with glob pattern\n ${APP_NAME} --models \"github-copilot/*\"\n\n # Cycle models with fixed thinking levels\n ${APP_NAME} --models sonnet:high,haiku:low\n\n # Start with a specific thinking level\n ${APP_NAME} --thinking high \"Solve this complex problem\"\n\n # Read-only mode (no file modifications possible)\n ${APP_NAME} --tools read,grep,find,ls -p \"Review the code in src/\"\n\n # Disable one tool while keeping the rest available\n ${APP_NAME} --exclude-tools ask_question\n\n # Export a session file to HTML\n ${APP_NAME} --export ~/${CONFIG_DIR_NAME}/agent/sessions/--path--/session.jsonl\n ${APP_NAME} --export session.jsonl output.html\n\n${chalk.bold(\"Environment Variables:\")}\n ANTHROPIC_API_KEY - Anthropic Claude API key\n ANTHROPIC_OAUTH_TOKEN - Anthropic OAuth token (alternative to API key)\n ANT_LING_API_KEY - Ant Ling API key\n OPENAI_API_KEY - OpenAI GPT API key\n AZURE_OPENAI_API_KEY - Azure OpenAI API key\n AZURE_OPENAI_BASE_URL - Azure OpenAI/Cognitive Services base URL (e.g. https://{resource}.openai.azure.com)\n AZURE_OPENAI_RESOURCE_NAME - Azure OpenAI resource name (alternative to base URL)\n AZURE_OPENAI_API_VERSION - Azure OpenAI API version (default: v1)\n AZURE_OPENAI_DEPLOYMENT_NAME_MAP - Azure OpenAI model=deployment map (comma-separated)\n DEEPSEEK_API_KEY - DeepSeek API key\n NVIDIA_API_KEY - NVIDIA NIM API key\n GEMINI_API_KEY - Google Gemini API key\n GROQ_API_KEY - Groq API key\n CEREBRAS_API_KEY - Cerebras API key\n XAI_API_KEY - xAI Grok API key\n FIREWORKS_API_KEY - Fireworks API key\n TOGETHER_API_KEY - Together AI API key\n OPENROUTER_API_KEY - OpenRouter API key\n AI_GATEWAY_API_KEY - Vercel AI Gateway API key\n ZAI_API_KEY - ZAI Coding Plan API key (Global)\n ZAI_CODING_CN_API_KEY - ZAI Coding Plan API key (China)\n MISTRAL_API_KEY - Mistral API key\n MINIMAX_API_KEY - MiniMax API key\n MOONSHOT_API_KEY - Moonshot AI API key\n OPENCODE_API_KEY - OpenCode Zen/OpenCode Go API key\n KIMI_API_KEY - Kimi For Coding API key\n CLOUDFLARE_API_KEY - Cloudflare API token (Workers AI and AI Gateway)\n CLOUDFLARE_ACCOUNT_ID - Cloudflare account id (required for both)\n CLOUDFLARE_GATEWAY_ID - Cloudflare AI Gateway slug (required for AI Gateway)\n XIAOMI_API_KEY - Xiaomi MiMo API key (api.xiaomimimo.com billing)\n XIAOMI_TOKEN_PLAN_CN_API_KEY - Xiaomi MiMo Token Plan API key (China region)\n XIAOMI_TOKEN_PLAN_AMS_API_KEY - Xiaomi MiMo Token Plan API key (Amsterdam region)\n XIAOMI_TOKEN_PLAN_SGP_API_KEY - Xiaomi MiMo Token Plan API key (Singapore region)\n AWS_PROFILE - AWS profile for Amazon Bedrock\n AWS_ACCESS_KEY_ID - AWS access key for Amazon Bedrock\n AWS_SECRET_ACCESS_KEY - AWS secret key for Amazon Bedrock\n AWS_BEARER_TOKEN_BEDROCK - Bedrock API key (bearer token)\n AWS_REGION - AWS region for Amazon Bedrock (e.g., us-east-1)\n ${ENV_AGENT_DIR.padEnd(32)} - Config directory (default: ~/${CONFIG_DIR_NAME}/agent)\n ${ENV_SESSION_DIR.padEnd(32)} - Session storage directory (overridden by --session-dir)\n PI_PACKAGE_DIR - Override package directory (for Nix/Guix store paths)\n PI_OFFLINE - Disable startup network operations when set to 1/true/yes\n PI_TELEMETRY - Override install telemetry when set to 1/true/yes or 0/false/no\n PI_SHARE_VIEWER_URL - Base URL for /share command (default: https://pi.dev/session/)\n\n${chalk.bold(\"Built-in Tool Names:\")}\n read - Read file contents\n bash - Execute bash commands\n edit - Edit files with find/replace\n write - Write files (creates/overwrites)\n grep - Search file contents (read-only, off by default)\n find - Find files by glob pattern (read-only, off by default)\n ls - List directory contents (read-only, off by default)\n`);\n}\n"]}
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * CLI argument parsing and help display\n */\n\nimport type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport chalk from \"chalk\";\nimport { APP_NAME, CONFIG_DIR_NAME, ENV_AGENT_DIR, ENV_SESSION_DIR } from \"../config.ts\";\nimport type { ExtensionFlag } from \"../core/extensions/types.ts\";\n\nexport type Mode = \"text\" | \"json\" | \"rpc\";\n\nexport interface Args {\n\tprovider?: string;\n\tmodel?: string;\n\tapiKey?: string;\n\tsystemPrompt?: string;\n\tappendSystemPrompt?: string[];\n\tthinking?: ThinkingLevel;\n\tcontinue?: boolean;\n\tresume?: boolean;\n\thelp?: boolean;\n\tversion?: boolean;\n\tmode?: Mode;\n\tname?: string;\n\tnoSession?: boolean;\n\tsession?: string;\n\tsessionId?: string;\n\tfork?: string;\n\tsessionDir?: string;\n\tmodels?: string[];\n\ttools?: string[];\n\texcludeTools?: string[];\n\tnoTools?: boolean;\n\tnoBuiltinTools?: boolean;\n\textensions?: string[];\n\tnoExtensions?: boolean;\n\tprint?: boolean;\n\texport?: string;\n\tnoSkills?: boolean;\n\tskills?: string[];\n\tpromptTemplates?: string[];\n\tnoPromptTemplates?: boolean;\n\tthemes?: string[];\n\tnoThemes?: boolean;\n\tnoContextFiles?: boolean;\n\tlistModels?: string | true;\n\toffline?: boolean;\n\tverbose?: boolean;\n\tprojectTrustOverride?: boolean;\n\tmessages: string[];\n\tfileArgs: string[];\n\t/** Unknown flags (potentially extension flags) - map of flag name to value */\n\tunknownFlags: Map<string, boolean | string>;\n\tdiagnostics: Array<{ type: \"warning\" | \"error\"; message: string }>;\n}\n\nconst VALID_THINKING_LEVELS = [\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\"] as const;\n\nexport function isValidThinkingLevel(level: string): level is ThinkingLevel {\n\treturn VALID_THINKING_LEVELS.includes(level as ThinkingLevel);\n}\n\nexport function parseArgs(args: string[]): Args {\n\tconst result: Args = {\n\t\tmessages: [],\n\t\tfileArgs: [],\n\t\tunknownFlags: new Map(),\n\t\tdiagnostics: [],\n\t};\n\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i];\n\n\t\tif (arg === \"--help\" || arg === \"-h\") {\n\t\t\tresult.help = true;\n\t\t} else if (arg === \"--version\" || arg === \"-v\") {\n\t\t\tresult.version = true;\n\t\t} else if (arg === \"--mode\" && i + 1 < args.length) {\n\t\t\tconst mode = args[++i];\n\t\t\tif (mode === \"text\" || mode === \"json\" || mode === \"rpc\") {\n\t\t\t\tresult.mode = mode;\n\t\t\t}\n\t\t} else if (arg === \"--continue\" || arg === \"-c\") {\n\t\t\tresult.continue = true;\n\t\t} else if (arg === \"--resume\" || arg === \"-r\") {\n\t\t\tresult.resume = true;\n\t\t} else if (arg === \"--provider\" && i + 1 < args.length) {\n\t\t\tresult.provider = args[++i];\n\t\t} else if (arg === \"--model\" && i + 1 < args.length) {\n\t\t\tresult.model = args[++i];\n\t\t} else if (arg === \"--api-key\" && i + 1 < args.length) {\n\t\t\tresult.apiKey = args[++i];\n\t\t} else if (arg === \"--system-prompt\" && i + 1 < args.length) {\n\t\t\tresult.systemPrompt = args[++i];\n\t\t} else if (arg === \"--append-system-prompt\" && i + 1 < args.length) {\n\t\t\tresult.appendSystemPrompt = result.appendSystemPrompt ?? [];\n\t\t\tresult.appendSystemPrompt.push(args[++i]);\n\t\t} else if (arg === \"--name\" || arg === \"-n\") {\n\t\t\tif (i + 1 < args.length) {\n\t\t\t\tresult.name = args[++i];\n\t\t\t} else {\n\t\t\t\tresult.diagnostics.push({ type: \"error\", message: \"--name requires a value\" });\n\t\t\t}\n\t\t} else if (arg === \"--no-session\") {\n\t\t\tresult.noSession = true;\n\t\t} else if (arg === \"--session\" && i + 1 < args.length) {\n\t\t\tresult.session = args[++i];\n\t\t} else if (arg === \"--session-id\" && i + 1 < args.length) {\n\t\t\tresult.sessionId = args[++i];\n\t\t} else if (arg === \"--fork\" && i + 1 < args.length) {\n\t\t\tresult.fork = args[++i];\n\t\t} else if (arg === \"--session-dir\" && i + 1 < args.length) {\n\t\t\tresult.sessionDir = args[++i];\n\t\t} else if (arg === \"--models\" && i + 1 < args.length) {\n\t\t\tresult.models = args[++i].split(\",\").map((s) => s.trim());\n\t\t} else if (arg === \"--no-tools\" || arg === \"-nt\") {\n\t\t\tresult.noTools = true;\n\t\t} else if (arg === \"--no-builtin-tools\" || arg === \"-nbt\") {\n\t\t\tresult.noBuiltinTools = true;\n\t\t} else if ((arg === \"--tools\" || arg === \"-t\") && i + 1 < args.length) {\n\t\t\tresult.tools = args[++i]\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim())\n\t\t\t\t.filter((name) => name.length > 0);\n\t\t} else if ((arg === \"--exclude-tools\" || arg === \"-xt\") && i + 1 < args.length) {\n\t\t\tresult.excludeTools = args[++i]\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim())\n\t\t\t\t.filter((name) => name.length > 0);\n\t\t} else if (arg === \"--thinking\" && i + 1 < args.length) {\n\t\t\tconst level = args[++i];\n\t\t\tif (isValidThinkingLevel(level)) {\n\t\t\t\tresult.thinking = level;\n\t\t\t} else {\n\t\t\t\tresult.diagnostics.push({\n\t\t\t\t\ttype: \"warning\",\n\t\t\t\t\tmessage: `Invalid thinking level \"${level}\". Valid values: ${VALID_THINKING_LEVELS.join(\", \")}`,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (arg === \"--print\" || arg === \"-p\") {\n\t\t\tresult.print = true;\n\t\t\tconst next = args[i + 1];\n\t\t\tif (next !== undefined && !next.startsWith(\"@\") && (!next.startsWith(\"-\") || next.startsWith(\"---\"))) {\n\t\t\t\tresult.messages.push(next);\n\t\t\t\ti++;\n\t\t\t}\n\t\t} else if (arg === \"--export\" && i + 1 < args.length) {\n\t\t\tresult.export = args[++i];\n\t\t} else if ((arg === \"--extension\" || arg === \"-e\") && i + 1 < args.length) {\n\t\t\tresult.extensions = result.extensions ?? [];\n\t\t\tresult.extensions.push(args[++i]);\n\t\t} else if (arg === \"--no-extensions\" || arg === \"-ne\") {\n\t\t\tresult.noExtensions = true;\n\t\t} else if (arg === \"--skill\" && i + 1 < args.length) {\n\t\t\tresult.skills = result.skills ?? [];\n\t\t\tresult.skills.push(args[++i]);\n\t\t} else if (arg === \"--prompt-template\" && i + 1 < args.length) {\n\t\t\tresult.promptTemplates = result.promptTemplates ?? [];\n\t\t\tresult.promptTemplates.push(args[++i]);\n\t\t} else if (arg === \"--theme\" && i + 1 < args.length) {\n\t\t\tresult.themes = result.themes ?? [];\n\t\t\tresult.themes.push(args[++i]);\n\t\t} else if (arg === \"--no-skills\" || arg === \"-ns\") {\n\t\t\tresult.noSkills = true;\n\t\t} else if (arg === \"--no-prompt-templates\" || arg === \"-np\") {\n\t\t\tresult.noPromptTemplates = true;\n\t\t} else if (arg === \"--no-themes\") {\n\t\t\tresult.noThemes = true;\n\t\t} else if (arg === \"--no-context-files\" || arg === \"-nc\") {\n\t\t\tresult.noContextFiles = true;\n\t\t} else if (arg === \"--list-models\") {\n\t\t\t// Check if next arg is a search pattern (not a flag or file arg)\n\t\t\tif (i + 1 < args.length && !args[i + 1].startsWith(\"-\") && !args[i + 1].startsWith(\"@\")) {\n\t\t\t\tresult.listModels = args[++i];\n\t\t\t} else {\n\t\t\t\tresult.listModels = true;\n\t\t\t}\n\t\t} else if (arg === \"--verbose\") {\n\t\t\tresult.verbose = true;\n\t\t} else if (arg === \"--approve\" || arg === \"-a\") {\n\t\t\tresult.projectTrustOverride = true;\n\t\t} else if (arg === \"--no-approve\" || arg === \"-na\") {\n\t\t\tresult.projectTrustOverride = false;\n\t\t} else if (arg === \"--offline\") {\n\t\t\tresult.offline = true;\n\t\t} else if (arg.startsWith(\"@\")) {\n\t\t\tresult.fileArgs.push(arg.slice(1)); // Remove @ prefix\n\t\t} else if (arg.startsWith(\"--\")) {\n\t\t\tconst eqIndex = arg.indexOf(\"=\");\n\t\t\tif (eqIndex !== -1) {\n\t\t\t\tresult.unknownFlags.set(arg.slice(2, eqIndex), arg.slice(eqIndex + 1));\n\t\t\t} else {\n\t\t\t\tconst flagName = arg.slice(2);\n\t\t\t\tconst next = args[i + 1];\n\t\t\t\tif (next !== undefined && !next.startsWith(\"-\") && !next.startsWith(\"@\")) {\n\t\t\t\t\tresult.unknownFlags.set(flagName, next);\n\t\t\t\t\ti++;\n\t\t\t\t} else {\n\t\t\t\t\tresult.unknownFlags.set(flagName, true);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (arg.startsWith(\"-\") && !arg.startsWith(\"--\")) {\n\t\t\tresult.diagnostics.push({ type: \"error\", message: `Unknown option: ${arg}` });\n\t\t} else if (!arg.startsWith(\"-\")) {\n\t\t\tresult.messages.push(arg);\n\t\t}\n\t}\n\n\treturn result;\n}\n\nexport function printHelp(extensionFlags?: ExtensionFlag[]): void {\n\tconst extensionFlagsText =\n\t\textensionFlags && extensionFlags.length > 0\n\t\t\t? `\\n${chalk.bold(\"Extension CLI Flags:\")}\\n${extensionFlags\n\t\t\t\t\t.map((flag) => {\n\t\t\t\t\t\tconst value = flag.type === \"string\" ? \" <value>\" : \"\";\n\t\t\t\t\t\tconst description = flag.description ?? `Registered by ${flag.extensionPath}`;\n\t\t\t\t\t\treturn ` --${flag.name}${value}`.padEnd(30) + description;\n\t\t\t\t\t})\n\t\t\t\t\t.join(\"\\n\")}\\n`\n\t\t\t: \"\";\n\tconsole.log(`${chalk.bold(APP_NAME)} - AI coding assistant with read, bash, edit, write tools\n\n${chalk.bold(\"Usage:\")}\n ${APP_NAME} [options] [@files...] [messages...]\n\n${chalk.bold(\"Commands:\")}\n ${APP_NAME} install <source> [-l] Install extension source and add to settings\n ${APP_NAME} remove <source> [-l] Remove extension source from settings\n ${APP_NAME} uninstall <source> [-l] Alias for remove\n ${APP_NAME} update [source|self|pi] Update pi, extensions, or model catalogs\n ${APP_NAME} list List installed extensions from settings\n ${APP_NAME} config [-l] Open TUI to enable/disable package resources (Tab switches scope)\n ${APP_NAME} <command> --help Show help for install/remove/uninstall/update/list/config\n\n${chalk.bold(\"Options:\")}\n --provider <name> Provider name (default: google)\n --model <pattern> Model pattern or ID (supports \"provider/id\" and optional \":<thinking>\")\n --api-key <key> API key (defaults to env vars)\n --system-prompt <text> System prompt (default: coding assistant prompt)\n --append-system-prompt <text> Append text or file contents to the system prompt (can be used multiple times)\n --mode <mode> Output mode: text (default), json, or rpc\n --print, -p Non-interactive mode: process prompt and exit\n --continue, -c Continue previous session\n --resume, -r Select a session to resume\n --session <path|id> Use specific session file or partial UUID\n --session-id <id> Use exact project session ID, creating it if missing\n --fork <path|id> Fork specific session file or partial UUID into a new session\n --session-dir <dir> Directory for session storage and lookup\n --no-session Don't save session (ephemeral)\n --name, -n <name> Set session display name\n --models <patterns> Comma-separated model patterns for Ctrl+P cycling\n Supports globs (anthropic/*, *sonnet*) and fuzzy matching\n --no-tools, -nt Disable all tools by default (built-in and extension)\n --no-builtin-tools, -nbt Disable built-in tools by default but keep extension/custom tools enabled\n --tools, -t <tools> Comma-separated allowlist of tool names to enable\n Applies to built-in, extension, and custom tools\n --exclude-tools, -xt <tools> Comma-separated denylist of tool names to disable\n Applies to built-in, extension, and custom tools\n --thinking <level> Set thinking level: off, minimal, low, medium, high, xhigh, max\n --extension, -e <path> Load an extension file (can be used multiple times)\n --no-extensions, -ne Disable extension discovery (explicit -e paths still work)\n --skill <path> Load a skill file or directory (can be used multiple times)\n --no-skills, -ns Disable skills discovery and loading\n --prompt-template <path> Load a prompt template file or directory (can be used multiple times)\n --no-prompt-templates, -np Disable prompt template discovery and loading\n --theme <path> Load a theme file or directory (can be used multiple times)\n --no-themes Disable theme discovery and loading\n --no-context-files, -nc Disable AGENTS.md and CLAUDE.md discovery and loading\n --export <file> Export session file to HTML and exit\n --list-models [search] List available models (with optional fuzzy search)\n --verbose Force verbose startup (overrides quietStartup setting)\n --approve, -a Trust project-local files for this run\n --no-approve, -na Ignore project-local files for this run\n --offline Disable startup network operations (same as PI_OFFLINE=1)\n --help, -h Show this help\n --version, -v Show version number\n\nExtensions can register additional flags (e.g., --plan from plan-mode extension).${extensionFlagsText}\n\n${chalk.bold(\"Examples:\")}\n # Interactive mode\n ${APP_NAME}\n\n # Interactive mode with initial prompt\n ${APP_NAME} \"List all .ts files in src/\"\n\n # Include files in initial message\n ${APP_NAME} @prompt.md @image.png \"What color is the sky?\"\n\n # Non-interactive mode (process and exit)\n ${APP_NAME} -p \"List all .ts files in src/\"\n\n # Multiple messages (interactive)\n ${APP_NAME} \"Read package.json\" \"What dependencies do we have?\"\n\n # Continue previous session\n ${APP_NAME} --continue \"What did we discuss?\"\n\n # Start a named session\n ${APP_NAME} --name \"Refactor auth module\"\n\n # Use different model\n ${APP_NAME} --provider openai --model gpt-4o-mini \"Help me refactor this code\"\n\n # Use model with provider prefix (no --provider needed)\n ${APP_NAME} --model openai/gpt-4o \"Help me refactor this code\"\n\n # Use model with thinking level shorthand\n ${APP_NAME} --model sonnet:high \"Solve this complex problem\"\n\n # Limit model cycling to specific models\n ${APP_NAME} --models claude-sonnet,claude-haiku,gpt-4o\n\n # Limit to a specific provider with glob pattern\n ${APP_NAME} --models \"github-copilot/*\"\n\n # Cycle models with fixed thinking levels\n ${APP_NAME} --models sonnet:high,haiku:low\n\n # Start with a specific thinking level\n ${APP_NAME} --thinking high \"Solve this complex problem\"\n\n # Read-only mode (no file modifications possible)\n ${APP_NAME} --tools read,grep,find,ls -p \"Review the code in src/\"\n\n # Disable one tool while keeping the rest available\n ${APP_NAME} --exclude-tools ask_question\n\n # Export a session file to HTML\n ${APP_NAME} --export ~/${CONFIG_DIR_NAME}/agent/sessions/--path--/session.jsonl\n ${APP_NAME} --export session.jsonl output.html\n\n${chalk.bold(\"Environment Variables:\")}\n ANTHROPIC_API_KEY - Anthropic Claude API key\n ANTHROPIC_OAUTH_TOKEN - Anthropic OAuth token (alternative to API key)\n ANT_LING_API_KEY - Ant Ling API key\n OPENAI_API_KEY - OpenAI GPT API key\n AZURE_OPENAI_API_KEY - Azure OpenAI API key\n AZURE_OPENAI_BASE_URL - Azure OpenAI/Cognitive Services base URL (e.g. https://{resource}.openai.azure.com)\n AZURE_OPENAI_RESOURCE_NAME - Azure OpenAI resource name (alternative to base URL)\n AZURE_OPENAI_API_VERSION - Azure OpenAI API version (default: v1)\n AZURE_OPENAI_DEPLOYMENT_NAME_MAP - Azure OpenAI model=deployment map (comma-separated)\n DEEPSEEK_API_KEY - DeepSeek API key\n NVIDIA_API_KEY - NVIDIA NIM API key\n GEMINI_API_KEY - Google Gemini API key\n GROQ_API_KEY - Groq API key\n CEREBRAS_API_KEY - Cerebras API key\n XAI_API_KEY - xAI Grok API key\n FIREWORKS_API_KEY - Fireworks API key\n TOGETHER_API_KEY - Together AI API key\n OPENROUTER_API_KEY - OpenRouter API key\n AI_GATEWAY_API_KEY - Vercel AI Gateway API key\n ZAI_API_KEY - ZAI Coding Plan API key (Global)\n ZAI_CODING_CN_API_KEY - ZAI Coding Plan API key (China)\n MISTRAL_API_KEY - Mistral API key\n MINIMAX_API_KEY - MiniMax API key\n MOONSHOT_API_KEY - Moonshot AI API key\n OPENCODE_API_KEY - OpenCode Zen/OpenCode Go API key\n KIMI_API_KEY - Kimi For Coding API key\n CLOUDFLARE_API_KEY - Cloudflare API token (Workers AI and AI Gateway)\n CLOUDFLARE_ACCOUNT_ID - Cloudflare account id (required for both)\n CLOUDFLARE_GATEWAY_ID - Cloudflare AI Gateway slug (required for AI Gateway)\n XIAOMI_API_KEY - Xiaomi MiMo API key (api.xiaomimimo.com billing)\n XIAOMI_TOKEN_PLAN_CN_API_KEY - Xiaomi MiMo Token Plan API key (China region)\n XIAOMI_TOKEN_PLAN_AMS_API_KEY - Xiaomi MiMo Token Plan API key (Amsterdam region)\n XIAOMI_TOKEN_PLAN_SGP_API_KEY - Xiaomi MiMo Token Plan API key (Singapore region)\n AWS_PROFILE - AWS profile for Amazon Bedrock\n AWS_ACCESS_KEY_ID - AWS access key for Amazon Bedrock\n AWS_SECRET_ACCESS_KEY - AWS secret key for Amazon Bedrock\n AWS_BEARER_TOKEN_BEDROCK - Bedrock API key (bearer token)\n AWS_REGION - AWS region for Amazon Bedrock (e.g., us-east-1)\n ${ENV_AGENT_DIR.padEnd(32)} - Config directory (default: ~/${CONFIG_DIR_NAME}/agent)\n ${ENV_SESSION_DIR.padEnd(32)} - Session storage directory (overridden by --session-dir)\n PI_PACKAGE_DIR - Override package directory (for Nix/Guix store paths)\n PI_OFFLINE - Disable startup network operations when set to 1/true/yes\n PI_TELEMETRY - Override install telemetry when set to 1/true/yes or 0/false/no\n PI_SHARE_VIEWER_URL - Base URL for /share command (default: https://pi.dev/session/)\n\n${chalk.bold(\"Built-in Tool Names:\")}\n read - Read file contents\n bash - Execute bash commands\n edit - Edit files with find/replace\n write - Write files (creates/overwrites)\n grep - Search file contents (read-only, off by default)\n find - Find files by glob pattern (read-only, off by default)\n ls - List directory contents (read-only, off by default)\n`);\n}\n"]}
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * List available models with optional fuzzy search
3
3
  */
4
- import type { ModelRegistry } from "../core/model-registry.ts";
4
+ import type { ModelRuntime } from "../core/model-runtime.ts";
5
5
  /**
6
6
  * List available models, optionally filtered by search pattern
7
7
  */
8
- export declare function listModels(modelRegistry: ModelRegistry, searchPattern?: string): Promise<void>;
8
+ export declare function listModels(modelRuntime: ModelRuntime, searchPattern?: string): Promise<void>;
9
9
  //# sourceMappingURL=list-models.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"list-models.d.ts","sourceRoot":"","sources":["../../src/cli/list-models.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAiB/D;;GAEG;AACH,wBAAsB,UAAU,CAAC,aAAa,EAAE,aAAa,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkFpG","sourcesContent":["/**\n * List available models with optional fuzzy search\n */\n\nimport type { Api, Model } from \"@earendil-works/pi-ai\";\nimport { fuzzyFilter } from \"@earendil-works/pi-tui\";\nimport chalk from \"chalk\";\nimport { formatNoModelsAvailableMessage } from \"../core/auth-guidance.ts\";\nimport type { ModelRegistry } from \"../core/model-registry.ts\";\n\n/**\n * Format a number as human-readable (e.g., 200000 -> \"200K\", 1000000 -> \"1M\")\n */\nfunction formatTokenCount(count: number): string {\n\tif (count >= 1_000_000) {\n\t\tconst millions = count / 1_000_000;\n\t\treturn millions % 1 === 0 ? `${millions}M` : `${millions.toFixed(1)}M`;\n\t}\n\tif (count >= 1_000) {\n\t\tconst thousands = count / 1_000;\n\t\treturn thousands % 1 === 0 ? `${thousands}K` : `${thousands.toFixed(1)}K`;\n\t}\n\treturn count.toString();\n}\n\n/**\n * List available models, optionally filtered by search pattern\n */\nexport async function listModels(modelRegistry: ModelRegistry, searchPattern?: string): Promise<void> {\n\tconst loadError = modelRegistry.getError();\n\tif (loadError) {\n\t\tconsole.error(chalk.yellow(`Warning: errors loading models.json:\\n${loadError}`));\n\t}\n\n\tconst models = modelRegistry.getAvailable();\n\n\tif (models.length === 0) {\n\t\tconsole.log(formatNoModelsAvailableMessage());\n\t\treturn;\n\t}\n\n\t// Apply fuzzy filter if search pattern provided\n\tlet filteredModels: Model<Api>[] = models;\n\tif (searchPattern) {\n\t\tfilteredModels = fuzzyFilter(models, searchPattern, (m) => `${m.provider} ${m.id}`);\n\t}\n\n\tif (filteredModels.length === 0) {\n\t\tconsole.log(`No models matching \"${searchPattern}\"`);\n\t\treturn;\n\t}\n\n\t// Sort by provider, then by model id\n\tfilteredModels.sort((a, b) => {\n\t\tconst providerCmp = a.provider.localeCompare(b.provider);\n\t\tif (providerCmp !== 0) return providerCmp;\n\t\treturn a.id.localeCompare(b.id);\n\t});\n\n\t// Calculate column widths\n\tconst rows = filteredModels.map((m) => ({\n\t\tprovider: m.provider,\n\t\tmodel: m.id,\n\t\tcontext: formatTokenCount(m.contextWindow),\n\t\tmaxOut: formatTokenCount(m.maxTokens),\n\t\tthinking: m.reasoning ? \"yes\" : \"no\",\n\t\timages: m.input.includes(\"image\") ? \"yes\" : \"no\",\n\t}));\n\n\tconst headers = {\n\t\tprovider: \"provider\",\n\t\tmodel: \"model\",\n\t\tcontext: \"context\",\n\t\tmaxOut: \"max-out\",\n\t\tthinking: \"thinking\",\n\t\timages: \"images\",\n\t};\n\n\tconst widths = {\n\t\tprovider: Math.max(headers.provider.length, ...rows.map((r) => r.provider.length)),\n\t\tmodel: Math.max(headers.model.length, ...rows.map((r) => r.model.length)),\n\t\tcontext: Math.max(headers.context.length, ...rows.map((r) => r.context.length)),\n\t\tmaxOut: Math.max(headers.maxOut.length, ...rows.map((r) => r.maxOut.length)),\n\t\tthinking: Math.max(headers.thinking.length, ...rows.map((r) => r.thinking.length)),\n\t\timages: Math.max(headers.images.length, ...rows.map((r) => r.images.length)),\n\t};\n\n\t// Print header\n\tconst headerLine = [\n\t\theaders.provider.padEnd(widths.provider),\n\t\theaders.model.padEnd(widths.model),\n\t\theaders.context.padEnd(widths.context),\n\t\theaders.maxOut.padEnd(widths.maxOut),\n\t\theaders.thinking.padEnd(widths.thinking),\n\t\theaders.images.padEnd(widths.images),\n\t].join(\" \");\n\tconsole.log(headerLine);\n\n\t// Print rows\n\tfor (const row of rows) {\n\t\tconst line = [\n\t\t\trow.provider.padEnd(widths.provider),\n\t\t\trow.model.padEnd(widths.model),\n\t\t\trow.context.padEnd(widths.context),\n\t\t\trow.maxOut.padEnd(widths.maxOut),\n\t\t\trow.thinking.padEnd(widths.thinking),\n\t\t\trow.images.padEnd(widths.images),\n\t\t].join(\" \");\n\t\tconsole.log(line);\n\t}\n}\n"]}
1
+ {"version":3,"file":"list-models.d.ts","sourceRoot":"","sources":["../../src/cli/list-models.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAiB7D;;GAEG;AACH,wBAAsB,UAAU,CAAC,YAAY,EAAE,YAAY,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkFlG","sourcesContent":["/**\n * List available models with optional fuzzy search\n */\n\nimport type { Api, Model } from \"@earendil-works/pi-ai\";\nimport { fuzzyFilter } from \"@earendil-works/pi-tui\";\nimport chalk from \"chalk\";\nimport { formatNoModelsAvailableMessage } from \"../core/auth-guidance.ts\";\nimport type { ModelRuntime } from \"../core/model-runtime.ts\";\n\n/**\n * Format a number as human-readable (e.g., 200000 -> \"200K\", 1000000 -> \"1M\")\n */\nfunction formatTokenCount(count: number): string {\n\tif (count >= 1_000_000) {\n\t\tconst millions = count / 1_000_000;\n\t\treturn millions % 1 === 0 ? `${millions}M` : `${millions.toFixed(1)}M`;\n\t}\n\tif (count >= 1_000) {\n\t\tconst thousands = count / 1_000;\n\t\treturn thousands % 1 === 0 ? `${thousands}K` : `${thousands.toFixed(1)}K`;\n\t}\n\treturn count.toString();\n}\n\n/**\n * List available models, optionally filtered by search pattern\n */\nexport async function listModels(modelRuntime: ModelRuntime, searchPattern?: string): Promise<void> {\n\tconst loadError = modelRuntime.getError();\n\tif (loadError) {\n\t\tconsole.error(chalk.yellow(`Warning: errors loading models.json:\\n${loadError}`));\n\t}\n\n\tconst models = [...(await modelRuntime.getAvailable())];\n\n\tif (models.length === 0) {\n\t\tconsole.log(formatNoModelsAvailableMessage());\n\t\treturn;\n\t}\n\n\t// Apply fuzzy filter if search pattern provided\n\tlet filteredModels: Model<Api>[] = models;\n\tif (searchPattern) {\n\t\tfilteredModels = fuzzyFilter(models, searchPattern, (m) => `${m.provider} ${m.id}`);\n\t}\n\n\tif (filteredModels.length === 0) {\n\t\tconsole.log(`No models matching \"${searchPattern}\"`);\n\t\treturn;\n\t}\n\n\t// Sort by provider, then by model id\n\tfilteredModels.sort((a, b) => {\n\t\tconst providerCmp = a.provider.localeCompare(b.provider);\n\t\tif (providerCmp !== 0) return providerCmp;\n\t\treturn a.id.localeCompare(b.id);\n\t});\n\n\t// Calculate column widths\n\tconst rows = filteredModels.map((m) => ({\n\t\tprovider: m.provider,\n\t\tmodel: m.id,\n\t\tcontext: formatTokenCount(m.contextWindow),\n\t\tmaxOut: formatTokenCount(m.maxTokens),\n\t\tthinking: m.reasoning ? \"yes\" : \"no\",\n\t\timages: m.input.includes(\"image\") ? \"yes\" : \"no\",\n\t}));\n\n\tconst headers = {\n\t\tprovider: \"provider\",\n\t\tmodel: \"model\",\n\t\tcontext: \"context\",\n\t\tmaxOut: \"max-out\",\n\t\tthinking: \"thinking\",\n\t\timages: \"images\",\n\t};\n\n\tconst widths = {\n\t\tprovider: Math.max(headers.provider.length, ...rows.map((r) => r.provider.length)),\n\t\tmodel: Math.max(headers.model.length, ...rows.map((r) => r.model.length)),\n\t\tcontext: Math.max(headers.context.length, ...rows.map((r) => r.context.length)),\n\t\tmaxOut: Math.max(headers.maxOut.length, ...rows.map((r) => r.maxOut.length)),\n\t\tthinking: Math.max(headers.thinking.length, ...rows.map((r) => r.thinking.length)),\n\t\timages: Math.max(headers.images.length, ...rows.map((r) => r.images.length)),\n\t};\n\n\t// Print header\n\tconst headerLine = [\n\t\theaders.provider.padEnd(widths.provider),\n\t\theaders.model.padEnd(widths.model),\n\t\theaders.context.padEnd(widths.context),\n\t\theaders.maxOut.padEnd(widths.maxOut),\n\t\theaders.thinking.padEnd(widths.thinking),\n\t\theaders.images.padEnd(widths.images),\n\t].join(\" \");\n\tconsole.log(headerLine);\n\n\t// Print rows\n\tfor (const row of rows) {\n\t\tconst line = [\n\t\t\trow.provider.padEnd(widths.provider),\n\t\t\trow.model.padEnd(widths.model),\n\t\t\trow.context.padEnd(widths.context),\n\t\t\trow.maxOut.padEnd(widths.maxOut),\n\t\t\trow.thinking.padEnd(widths.thinking),\n\t\t\trow.images.padEnd(widths.images),\n\t\t].join(\" \");\n\t\tconsole.log(line);\n\t}\n}\n"]}
@@ -21,12 +21,12 @@ function formatTokenCount(count) {
21
21
  /**
22
22
  * List available models, optionally filtered by search pattern
23
23
  */
24
- export async function listModels(modelRegistry, searchPattern) {
25
- const loadError = modelRegistry.getError();
24
+ export async function listModels(modelRuntime, searchPattern) {
25
+ const loadError = modelRuntime.getError();
26
26
  if (loadError) {
27
27
  console.error(chalk.yellow(`Warning: errors loading models.json:\n${loadError}`));
28
28
  }
29
- const models = modelRegistry.getAvailable();
29
+ const models = [...(await modelRuntime.getAvailable())];
30
30
  if (models.length === 0) {
31
31
  console.log(formatNoModelsAvailableMessage());
32
32
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"list-models.js","sourceRoot":"","sources":["../../src/cli/list-models.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * List available models with optional fuzzy search\n */\n\nimport type { Api, Model } from \"@earendil-works/pi-ai\";\nimport { fuzzyFilter } from \"@earendil-works/pi-tui\";\nimport chalk from \"chalk\";\nimport { formatNoModelsAvailableMessage } from \"../core/auth-guidance.ts\";\nimport type { ModelRegistry } from \"../core/model-registry.ts\";\n\n/**\n * Format a number as human-readable (e.g., 200000 -> \"200K\", 1000000 -> \"1M\")\n */\nfunction formatTokenCount(count: number): string {\n\tif (count >= 1_000_000) {\n\t\tconst millions = count / 1_000_000;\n\t\treturn millions % 1 === 0 ? `${millions}M` : `${millions.toFixed(1)}M`;\n\t}\n\tif (count >= 1_000) {\n\t\tconst thousands = count / 1_000;\n\t\treturn thousands % 1 === 0 ? `${thousands}K` : `${thousands.toFixed(1)}K`;\n\t}\n\treturn count.toString();\n}\n\n/**\n * List available models, optionally filtered by search pattern\n */\nexport async function listModels(modelRegistry: ModelRegistry, searchPattern?: string): Promise<void> {\n\tconst loadError = modelRegistry.getError();\n\tif (loadError) {\n\t\tconsole.error(chalk.yellow(`Warning: errors loading models.json:\\n${loadError}`));\n\t}\n\n\tconst models = modelRegistry.getAvailable();\n\n\tif (models.length === 0) {\n\t\tconsole.log(formatNoModelsAvailableMessage());\n\t\treturn;\n\t}\n\n\t// Apply fuzzy filter if search pattern provided\n\tlet filteredModels: Model<Api>[] = models;\n\tif (searchPattern) {\n\t\tfilteredModels = fuzzyFilter(models, searchPattern, (m) => `${m.provider} ${m.id}`);\n\t}\n\n\tif (filteredModels.length === 0) {\n\t\tconsole.log(`No models matching \"${searchPattern}\"`);\n\t\treturn;\n\t}\n\n\t// Sort by provider, then by model id\n\tfilteredModels.sort((a, b) => {\n\t\tconst providerCmp = a.provider.localeCompare(b.provider);\n\t\tif (providerCmp !== 0) return providerCmp;\n\t\treturn a.id.localeCompare(b.id);\n\t});\n\n\t// Calculate column widths\n\tconst rows = filteredModels.map((m) => ({\n\t\tprovider: m.provider,\n\t\tmodel: m.id,\n\t\tcontext: formatTokenCount(m.contextWindow),\n\t\tmaxOut: formatTokenCount(m.maxTokens),\n\t\tthinking: m.reasoning ? \"yes\" : \"no\",\n\t\timages: m.input.includes(\"image\") ? \"yes\" : \"no\",\n\t}));\n\n\tconst headers = {\n\t\tprovider: \"provider\",\n\t\tmodel: \"model\",\n\t\tcontext: \"context\",\n\t\tmaxOut: \"max-out\",\n\t\tthinking: \"thinking\",\n\t\timages: \"images\",\n\t};\n\n\tconst widths = {\n\t\tprovider: Math.max(headers.provider.length, ...rows.map((r) => r.provider.length)),\n\t\tmodel: Math.max(headers.model.length, ...rows.map((r) => r.model.length)),\n\t\tcontext: Math.max(headers.context.length, ...rows.map((r) => r.context.length)),\n\t\tmaxOut: Math.max(headers.maxOut.length, ...rows.map((r) => r.maxOut.length)),\n\t\tthinking: Math.max(headers.thinking.length, ...rows.map((r) => r.thinking.length)),\n\t\timages: Math.max(headers.images.length, ...rows.map((r) => r.images.length)),\n\t};\n\n\t// Print header\n\tconst headerLine = [\n\t\theaders.provider.padEnd(widths.provider),\n\t\theaders.model.padEnd(widths.model),\n\t\theaders.context.padEnd(widths.context),\n\t\theaders.maxOut.padEnd(widths.maxOut),\n\t\theaders.thinking.padEnd(widths.thinking),\n\t\theaders.images.padEnd(widths.images),\n\t].join(\" \");\n\tconsole.log(headerLine);\n\n\t// Print rows\n\tfor (const row of rows) {\n\t\tconst line = [\n\t\t\trow.provider.padEnd(widths.provider),\n\t\t\trow.model.padEnd(widths.model),\n\t\t\trow.context.padEnd(widths.context),\n\t\t\trow.maxOut.padEnd(widths.maxOut),\n\t\t\trow.thinking.padEnd(widths.thinking),\n\t\t\trow.images.padEnd(widths.images),\n\t\t].join(\" \");\n\t\tconsole.log(line);\n\t}\n}\n"]}
1
+ {"version":3,"file":"list-models.js","sourceRoot":"","sources":["../../src/cli/list-models.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAG1E;;GAEG;AACH,SAAS,gBAAgB,CAAC,KAAa,EAAU;IAChD,IAAI,KAAK,IAAI,SAAS,EAAE,CAAC;QACxB,MAAM,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;QACnC,OAAO,QAAQ,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IACxE,CAAC;IACD,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;QACpB,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK,CAAC;QAChC,OAAO,SAAS,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IAC3E,CAAC;IACD,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;AAAA,CACxB;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,YAA0B,EAAE,aAAsB,EAAiB;IACnG,MAAM,SAAS,GAAG,YAAY,CAAC,QAAQ,EAAE,CAAC;IAC1C,IAAI,SAAS,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,yCAAyC,SAAS,EAAE,CAAC,CAAC,CAAC;IACnF,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,YAAY,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;IAExD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,8BAA8B,EAAE,CAAC,CAAC;QAC9C,OAAO;IACR,CAAC;IAED,gDAAgD;IAChD,IAAI,cAAc,GAAiB,MAAM,CAAC;IAC1C,IAAI,aAAa,EAAE,CAAC;QACnB,cAAc,GAAG,WAAW,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACrF,CAAC;IAED,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,uBAAuB,aAAa,GAAG,CAAC,CAAC;QACrD,OAAO;IACR,CAAC;IAED,qCAAqC;IACrC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7B,MAAM,WAAW,GAAG,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACzD,IAAI,WAAW,KAAK,CAAC;YAAE,OAAO,WAAW,CAAC;QAC1C,OAAO,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAAA,CAChC,CAAC,CAAC;IAEH,0BAA0B;IAC1B,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACvC,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,KAAK,EAAE,CAAC,CAAC,EAAE;QACX,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,aAAa,CAAC;QAC1C,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC;QACrC,QAAQ,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;QACpC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;KAChD,CAAC,CAAC,CAAC;IAEJ,MAAM,OAAO,GAAG;QACf,QAAQ,EAAE,UAAU;QACpB,KAAK,EAAE,OAAO;QACd,OAAO,EAAE,SAAS;QAClB,MAAM,EAAE,SAAS;QACjB,QAAQ,EAAE,UAAU;QACpB,MAAM,EAAE,QAAQ;KAChB,CAAC;IAEF,MAAM,MAAM,GAAG;QACd,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAClF,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACzE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC/E,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC5E,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAClF,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;KAC5E,CAAC;IAEF,eAAe;IACf,MAAM,UAAU,GAAG;QAClB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;QACxC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;QAClC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;QACtC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;QACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;QACxC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;KACpC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAExB,aAAa;IACb,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG;YACZ,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;YACpC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;YAC9B,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;YAClC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;YAChC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;YACpC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;SAChC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;AAAA,CACD","sourcesContent":["/**\n * List available models with optional fuzzy search\n */\n\nimport type { Api, Model } from \"@earendil-works/pi-ai\";\nimport { fuzzyFilter } from \"@earendil-works/pi-tui\";\nimport chalk from \"chalk\";\nimport { formatNoModelsAvailableMessage } from \"../core/auth-guidance.ts\";\nimport type { ModelRuntime } from \"../core/model-runtime.ts\";\n\n/**\n * Format a number as human-readable (e.g., 200000 -> \"200K\", 1000000 -> \"1M\")\n */\nfunction formatTokenCount(count: number): string {\n\tif (count >= 1_000_000) {\n\t\tconst millions = count / 1_000_000;\n\t\treturn millions % 1 === 0 ? `${millions}M` : `${millions.toFixed(1)}M`;\n\t}\n\tif (count >= 1_000) {\n\t\tconst thousands = count / 1_000;\n\t\treturn thousands % 1 === 0 ? `${thousands}K` : `${thousands.toFixed(1)}K`;\n\t}\n\treturn count.toString();\n}\n\n/**\n * List available models, optionally filtered by search pattern\n */\nexport async function listModels(modelRuntime: ModelRuntime, searchPattern?: string): Promise<void> {\n\tconst loadError = modelRuntime.getError();\n\tif (loadError) {\n\t\tconsole.error(chalk.yellow(`Warning: errors loading models.json:\\n${loadError}`));\n\t}\n\n\tconst models = [...(await modelRuntime.getAvailable())];\n\n\tif (models.length === 0) {\n\t\tconsole.log(formatNoModelsAvailableMessage());\n\t\treturn;\n\t}\n\n\t// Apply fuzzy filter if search pattern provided\n\tlet filteredModels: Model<Api>[] = models;\n\tif (searchPattern) {\n\t\tfilteredModels = fuzzyFilter(models, searchPattern, (m) => `${m.provider} ${m.id}`);\n\t}\n\n\tif (filteredModels.length === 0) {\n\t\tconsole.log(`No models matching \"${searchPattern}\"`);\n\t\treturn;\n\t}\n\n\t// Sort by provider, then by model id\n\tfilteredModels.sort((a, b) => {\n\t\tconst providerCmp = a.provider.localeCompare(b.provider);\n\t\tif (providerCmp !== 0) return providerCmp;\n\t\treturn a.id.localeCompare(b.id);\n\t});\n\n\t// Calculate column widths\n\tconst rows = filteredModels.map((m) => ({\n\t\tprovider: m.provider,\n\t\tmodel: m.id,\n\t\tcontext: formatTokenCount(m.contextWindow),\n\t\tmaxOut: formatTokenCount(m.maxTokens),\n\t\tthinking: m.reasoning ? \"yes\" : \"no\",\n\t\timages: m.input.includes(\"image\") ? \"yes\" : \"no\",\n\t}));\n\n\tconst headers = {\n\t\tprovider: \"provider\",\n\t\tmodel: \"model\",\n\t\tcontext: \"context\",\n\t\tmaxOut: \"max-out\",\n\t\tthinking: \"thinking\",\n\t\timages: \"images\",\n\t};\n\n\tconst widths = {\n\t\tprovider: Math.max(headers.provider.length, ...rows.map((r) => r.provider.length)),\n\t\tmodel: Math.max(headers.model.length, ...rows.map((r) => r.model.length)),\n\t\tcontext: Math.max(headers.context.length, ...rows.map((r) => r.context.length)),\n\t\tmaxOut: Math.max(headers.maxOut.length, ...rows.map((r) => r.maxOut.length)),\n\t\tthinking: Math.max(headers.thinking.length, ...rows.map((r) => r.thinking.length)),\n\t\timages: Math.max(headers.images.length, ...rows.map((r) => r.images.length)),\n\t};\n\n\t// Print header\n\tconst headerLine = [\n\t\theaders.provider.padEnd(widths.provider),\n\t\theaders.model.padEnd(widths.model),\n\t\theaders.context.padEnd(widths.context),\n\t\theaders.maxOut.padEnd(widths.maxOut),\n\t\theaders.thinking.padEnd(widths.thinking),\n\t\theaders.images.padEnd(widths.images),\n\t].join(\" \");\n\tconsole.log(headerLine);\n\n\t// Print rows\n\tfor (const row of rows) {\n\t\tconst line = [\n\t\t\trow.provider.padEnd(widths.provider),\n\t\t\trow.model.padEnd(widths.model),\n\t\t\trow.context.padEnd(widths.context),\n\t\t\trow.maxOut.padEnd(widths.maxOut),\n\t\t\trow.thinking.padEnd(widths.thinking),\n\t\t\trow.images.padEnd(widths.images),\n\t\t].join(\" \");\n\t\tconsole.log(line);\n\t}\n}\n"]}
@@ -1,8 +1,7 @@
1
1
  import type { ThinkingLevel } from "@earendil-works/pi-agent-core";
2
2
  import type { Model } from "@earendil-works/pi-ai";
3
- import { AuthStorage } from "./auth-storage.ts";
4
3
  import type { SessionStartEvent, ToolDefinition } from "./extensions/index.ts";
5
- import { ModelRegistry } from "./model-registry.ts";
4
+ import { ModelRuntime } from "./model-runtime.ts";
6
5
  import { type DefaultResourceLoaderOptions, type ResourceLoader, type ResourceLoaderReloadOptions } from "./resource-loader.ts";
7
6
  import { type CreateAgentSessionOptions, type CreateAgentSessionResult } from "./sdk.ts";
8
7
  import type { SessionManager } from "./session-manager.ts";
@@ -28,9 +27,8 @@ export interface AgentSessionRuntimeDiagnostic {
28
27
  export interface CreateAgentSessionServicesOptions {
29
28
  cwd: string;
30
29
  agentDir?: string;
31
- authStorage?: AuthStorage;
32
30
  settingsManager?: SettingsManager;
33
- modelRegistry?: ModelRegistry;
31
+ modelRuntime?: ModelRuntime;
34
32
  extensionFlagValues?: Map<string, boolean | string>;
35
33
  resourceLoaderOptions?: Omit<DefaultResourceLoaderOptions, "cwd" | "agentDir" | "settingsManager">;
36
34
  resourceLoaderReloadOptions?: ResourceLoaderReloadOptions;
@@ -65,9 +63,8 @@ export interface CreateAgentSessionFromServicesOptions {
65
63
  export interface AgentSessionServices {
66
64
  cwd: string;
67
65
  agentDir: string;
68
- authStorage: AuthStorage;
66
+ modelRuntime: ModelRuntime;
69
67
  settingsManager: SettingsManager;
70
- modelRegistry: ModelRegistry;
71
68
  resourceLoader: ResourceLoader;
72
69
  diagnostics: AgentSessionRuntimeDiagnostic[];
73
70
  }
@@ -1 +1 @@
1
- {"version":3,"file":"agent-session-services.d.ts","sourceRoot":"","sources":["../../src/core/agent-session-services.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAGnD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAEN,KAAK,4BAA4B,EACjC,KAAK,cAAc,EACnB,KAAK,2BAA2B,EAChC,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,KAAK,yBAAyB,EAAE,KAAK,wBAAwB,EAAsB,MAAM,UAAU,CAAC;AAC7G,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD;;;;;;GAMG;AACH,MAAM,WAAW,6BAA6B;IAC7C,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;IACnC,OAAO,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iCAAiC;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,mBAAmB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC,CAAC;IACpD,qBAAqB,CAAC,EAAE,IAAI,CAAC,4BAA4B,EAAE,KAAK,GAAG,UAAU,GAAG,iBAAiB,CAAC,CAAC;IACnG,2BAA2B,CAAC,EAAE,2BAA2B,CAAC;CAC1D;AAED;;;;;GAKG;AACH,MAAM,WAAW,qCAAqC;IACrD,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAAC,aAAa,CAAC,EAAE,aAAa,CAAA;KAAE,CAAC,CAAC;IAC3E,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,yBAAyB,CAAC,cAAc,CAAC,CAAC;IACzD,OAAO,CAAC,EAAE,yBAAyB,CAAC,SAAS,CAAC,CAAC;IAC/C,WAAW,CAAC,EAAE,cAAc,EAAE,CAAC;CAC/B;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;IACzB,eAAe,EAAE,eAAe,CAAC;IACjC,aAAa,EAAE,aAAa,CAAC;IAC7B,cAAc,EAAE,cAAc,CAAC;IAC/B,WAAW,EAAE,6BAA6B,EAAE,CAAC;CAC7C;AAkDD;;;;GAIG;AACH,wBAAsB,0BAA0B,CAC/C,OAAO,EAAE,iCAAiC,GACxC,OAAO,CAAC,oBAAoB,CAAC,CAuC/B;AAED;;;;;;GAMG;AACH,wBAAsB,8BAA8B,CACnD,OAAO,EAAE,qCAAqC,GAC5C,OAAO,CAAC,wBAAwB,CAAC,CAkBnC","sourcesContent":["import { join } from \"node:path\";\nimport type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport type { Model } from \"@earendil-works/pi-ai\";\nimport { getAgentDir } from \"../config.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { AuthStorage } from \"./auth-storage.ts\";\nimport type { SessionStartEvent, ToolDefinition } from \"./extensions/index.ts\";\nimport { ModelRegistry } from \"./model-registry.ts\";\nimport {\n\tDefaultResourceLoader,\n\ttype DefaultResourceLoaderOptions,\n\ttype ResourceLoader,\n\ttype ResourceLoaderReloadOptions,\n} from \"./resource-loader.ts\";\nimport { type CreateAgentSessionOptions, type CreateAgentSessionResult, createAgentSession } from \"./sdk.ts\";\nimport type { SessionManager } from \"./session-manager.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\n\n/**\n * Non-fatal issues collected while creating services or sessions.\n *\n * Runtime creation returns diagnostics to the caller instead of printing or\n * exiting. The app layer decides whether warnings should be shown and whether\n * errors should abort startup.\n */\nexport interface AgentSessionRuntimeDiagnostic {\n\ttype: \"info\" | \"warning\" | \"error\";\n\tmessage: string;\n}\n\n/**\n * Inputs for creating cwd-bound runtime services.\n *\n * These services are recreated whenever the effective session cwd changes.\n * CLI-provided resource paths should be resolved to absolute paths before they\n * reach this function, so later cwd switches do not reinterpret them.\n */\nexport interface CreateAgentSessionServicesOptions {\n\tcwd: string;\n\tagentDir?: string;\n\tauthStorage?: AuthStorage;\n\tsettingsManager?: SettingsManager;\n\tmodelRegistry?: ModelRegistry;\n\textensionFlagValues?: Map<string, boolean | string>;\n\tresourceLoaderOptions?: Omit<DefaultResourceLoaderOptions, \"cwd\" | \"agentDir\" | \"settingsManager\">;\n\tresourceLoaderReloadOptions?: ResourceLoaderReloadOptions;\n}\n\n/**\n * Inputs for creating an AgentSession from already-created services.\n *\n * Use this after services exist and any cwd-bound model/tool/session options\n * have been resolved against those services.\n */\nexport interface CreateAgentSessionFromServicesOptions {\n\tservices: AgentSessionServices;\n\tsessionManager: SessionManager;\n\tsessionStartEvent?: SessionStartEvent;\n\tmodel?: Model<any>;\n\tthinkingLevel?: ThinkingLevel;\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\ttools?: string[];\n\texcludeTools?: CreateAgentSessionOptions[\"excludeTools\"];\n\tnoTools?: CreateAgentSessionOptions[\"noTools\"];\n\tcustomTools?: ToolDefinition[];\n}\n\n/**\n * Coherent cwd-bound runtime services for one effective session cwd.\n *\n * This is infrastructure only. The AgentSession itself is created separately so\n * session options can be resolved against these services first.\n */\nexport interface AgentSessionServices {\n\tcwd: string;\n\tagentDir: string;\n\tauthStorage: AuthStorage;\n\tsettingsManager: SettingsManager;\n\tmodelRegistry: ModelRegistry;\n\tresourceLoader: ResourceLoader;\n\tdiagnostics: AgentSessionRuntimeDiagnostic[];\n}\n\nfunction applyExtensionFlagValues(\n\tresourceLoader: ResourceLoader,\n\textensionFlagValues: Map<string, boolean | string> | undefined,\n): AgentSessionRuntimeDiagnostic[] {\n\tif (!extensionFlagValues) {\n\t\treturn [];\n\t}\n\n\tconst diagnostics: AgentSessionRuntimeDiagnostic[] = [];\n\tconst extensionsResult = resourceLoader.getExtensions();\n\tconst registeredFlags = new Map<string, { type: \"boolean\" | \"string\" }>();\n\tfor (const extension of extensionsResult.extensions) {\n\t\tfor (const [name, flag] of extension.flags) {\n\t\t\tregisteredFlags.set(name, { type: flag.type });\n\t\t}\n\t}\n\n\tconst unknownFlags: string[] = [];\n\tfor (const [name, value] of extensionFlagValues) {\n\t\tconst flag = registeredFlags.get(name);\n\t\tif (!flag) {\n\t\t\tunknownFlags.push(name);\n\t\t\tcontinue;\n\t\t}\n\t\tif (flag.type === \"boolean\") {\n\t\t\textensionsResult.runtime.flagValues.set(name, true);\n\t\t\tcontinue;\n\t\t}\n\t\tif (typeof value === \"string\") {\n\t\t\textensionsResult.runtime.flagValues.set(name, value);\n\t\t\tcontinue;\n\t\t}\n\t\tdiagnostics.push({\n\t\t\ttype: \"error\",\n\t\t\tmessage: `Extension flag \"--${name}\" requires a value`,\n\t\t});\n\t}\n\n\tif (unknownFlags.length > 0) {\n\t\tdiagnostics.push({\n\t\t\ttype: \"error\",\n\t\t\tmessage: `Unknown option${unknownFlags.length === 1 ? \"\" : \"s\"}: ${unknownFlags.map((name) => `--${name}`).join(\", \")}`,\n\t\t});\n\t}\n\n\treturn diagnostics;\n}\n\n/**\n * Create cwd-bound runtime services.\n *\n * Returns services plus diagnostics. It does not create an AgentSession.\n */\nexport async function createAgentSessionServices(\n\toptions: CreateAgentSessionServicesOptions,\n): Promise<AgentSessionServices> {\n\tconst cwd = resolvePath(options.cwd);\n\tconst agentDir = options.agentDir ? resolvePath(options.agentDir) : getAgentDir();\n\tconst authStorage = options.authStorage ?? AuthStorage.create(join(agentDir, \"auth.json\"));\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\tconst modelRegistry = options.modelRegistry ?? ModelRegistry.create(authStorage, join(agentDir, \"models.json\"));\n\tconst resourceLoader = new DefaultResourceLoader({\n\t\t...(options.resourceLoaderOptions ?? {}),\n\t\tcwd,\n\t\tagentDir,\n\t\tsettingsManager,\n\t});\n\tawait resourceLoader.reload(options.resourceLoaderReloadOptions);\n\n\tconst diagnostics: AgentSessionRuntimeDiagnostic[] = [];\n\tconst extensionsResult = resourceLoader.getExtensions();\n\tfor (const { name, config, extensionPath } of extensionsResult.runtime.pendingProviderRegistrations) {\n\t\ttry {\n\t\t\tmodelRegistry.registerProvider(name, config);\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tdiagnostics.push({\n\t\t\t\ttype: \"error\",\n\t\t\t\tmessage: `Extension \"${extensionPath}\" error: ${message}`,\n\t\t\t});\n\t\t}\n\t}\n\textensionsResult.runtime.pendingProviderRegistrations = [];\n\tdiagnostics.push(...applyExtensionFlagValues(resourceLoader, options.extensionFlagValues));\n\n\treturn {\n\t\tcwd,\n\t\tagentDir,\n\t\tauthStorage,\n\t\tsettingsManager,\n\t\tmodelRegistry,\n\t\tresourceLoader,\n\t\tdiagnostics,\n\t};\n}\n\n/**\n * Create an AgentSession from previously created services.\n *\n * This keeps session creation separate from service creation so callers can\n * resolve model, thinking, tools, and other session inputs against the target\n * cwd before constructing the session.\n */\nexport async function createAgentSessionFromServices(\n\toptions: CreateAgentSessionFromServicesOptions,\n): Promise<CreateAgentSessionResult> {\n\treturn createAgentSession({\n\t\tcwd: options.services.cwd,\n\t\tagentDir: options.services.agentDir,\n\t\tauthStorage: options.services.authStorage,\n\t\tsettingsManager: options.services.settingsManager,\n\t\tmodelRegistry: options.services.modelRegistry,\n\t\tresourceLoader: options.services.resourceLoader,\n\t\tsessionManager: options.sessionManager,\n\t\tmodel: options.model,\n\t\tthinkingLevel: options.thinkingLevel,\n\t\tscopedModels: options.scopedModels,\n\t\ttools: options.tools,\n\t\texcludeTools: options.excludeTools,\n\t\tnoTools: options.noTools,\n\t\tcustomTools: options.customTools,\n\t\tsessionStartEvent: options.sessionStartEvent,\n\t});\n}\n"]}
1
+ {"version":3,"file":"agent-session-services.d.ts","sourceRoot":"","sources":["../../src/core/agent-session-services.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAGnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAEN,KAAK,4BAA4B,EACjC,KAAK,cAAc,EACnB,KAAK,2BAA2B,EAChC,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,KAAK,yBAAyB,EAAE,KAAK,wBAAwB,EAAsB,MAAM,UAAU,CAAC;AAC7G,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD;;;;;;GAMG;AACH,MAAM,WAAW,6BAA6B;IAC7C,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;IACnC,OAAO,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iCAAiC;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,mBAAmB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC,CAAC;IACpD,qBAAqB,CAAC,EAAE,IAAI,CAAC,4BAA4B,EAAE,KAAK,GAAG,UAAU,GAAG,iBAAiB,CAAC,CAAC;IACnG,2BAA2B,CAAC,EAAE,2BAA2B,CAAC;CAC1D;AAED;;;;;GAKG;AACH,MAAM,WAAW,qCAAqC;IACrD,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAAC,aAAa,CAAC,EAAE,aAAa,CAAA;KAAE,CAAC,CAAC;IAC3E,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,yBAAyB,CAAC,cAAc,CAAC,CAAC;IACzD,OAAO,CAAC,EAAE,yBAAyB,CAAC,SAAS,CAAC,CAAC;IAC/C,WAAW,CAAC,EAAE,cAAc,EAAE,CAAC;CAC/B;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,YAAY,CAAC;IAC3B,eAAe,EAAE,eAAe,CAAC;IACjC,cAAc,EAAE,cAAc,CAAC;IAC/B,WAAW,EAAE,6BAA6B,EAAE,CAAC;CAC7C;AAkDD;;;;GAIG;AACH,wBAAsB,0BAA0B,CAC/C,OAAO,EAAE,iCAAiC,GACxC,OAAO,CAAC,oBAAoB,CAAC,CA2C/B;AAED;;;;;;GAMG;AACH,wBAAsB,8BAA8B,CACnD,OAAO,EAAE,qCAAqC,GAC5C,OAAO,CAAC,wBAAwB,CAAC,CAiBnC","sourcesContent":["import { join } from \"node:path\";\nimport type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport type { Model } from \"@earendil-works/pi-ai\";\nimport { getAgentDir } from \"../config.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport type { SessionStartEvent, ToolDefinition } from \"./extensions/index.ts\";\nimport { ModelRuntime } from \"./model-runtime.ts\";\nimport {\n\tDefaultResourceLoader,\n\ttype DefaultResourceLoaderOptions,\n\ttype ResourceLoader,\n\ttype ResourceLoaderReloadOptions,\n} from \"./resource-loader.ts\";\nimport { type CreateAgentSessionOptions, type CreateAgentSessionResult, createAgentSession } from \"./sdk.ts\";\nimport type { SessionManager } from \"./session-manager.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\n\n/**\n * Non-fatal issues collected while creating services or sessions.\n *\n * Runtime creation returns diagnostics to the caller instead of printing or\n * exiting. The app layer decides whether warnings should be shown and whether\n * errors should abort startup.\n */\nexport interface AgentSessionRuntimeDiagnostic {\n\ttype: \"info\" | \"warning\" | \"error\";\n\tmessage: string;\n}\n\n/**\n * Inputs for creating cwd-bound runtime services.\n *\n * These services are recreated whenever the effective session cwd changes.\n * CLI-provided resource paths should be resolved to absolute paths before they\n * reach this function, so later cwd switches do not reinterpret them.\n */\nexport interface CreateAgentSessionServicesOptions {\n\tcwd: string;\n\tagentDir?: string;\n\tsettingsManager?: SettingsManager;\n\tmodelRuntime?: ModelRuntime;\n\textensionFlagValues?: Map<string, boolean | string>;\n\tresourceLoaderOptions?: Omit<DefaultResourceLoaderOptions, \"cwd\" | \"agentDir\" | \"settingsManager\">;\n\tresourceLoaderReloadOptions?: ResourceLoaderReloadOptions;\n}\n\n/**\n * Inputs for creating an AgentSession from already-created services.\n *\n * Use this after services exist and any cwd-bound model/tool/session options\n * have been resolved against those services.\n */\nexport interface CreateAgentSessionFromServicesOptions {\n\tservices: AgentSessionServices;\n\tsessionManager: SessionManager;\n\tsessionStartEvent?: SessionStartEvent;\n\tmodel?: Model<any>;\n\tthinkingLevel?: ThinkingLevel;\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\ttools?: string[];\n\texcludeTools?: CreateAgentSessionOptions[\"excludeTools\"];\n\tnoTools?: CreateAgentSessionOptions[\"noTools\"];\n\tcustomTools?: ToolDefinition[];\n}\n\n/**\n * Coherent cwd-bound runtime services for one effective session cwd.\n *\n * This is infrastructure only. The AgentSession itself is created separately so\n * session options can be resolved against these services first.\n */\nexport interface AgentSessionServices {\n\tcwd: string;\n\tagentDir: string;\n\tmodelRuntime: ModelRuntime;\n\tsettingsManager: SettingsManager;\n\tresourceLoader: ResourceLoader;\n\tdiagnostics: AgentSessionRuntimeDiagnostic[];\n}\n\nfunction applyExtensionFlagValues(\n\tresourceLoader: ResourceLoader,\n\textensionFlagValues: Map<string, boolean | string> | undefined,\n): AgentSessionRuntimeDiagnostic[] {\n\tif (!extensionFlagValues) {\n\t\treturn [];\n\t}\n\n\tconst diagnostics: AgentSessionRuntimeDiagnostic[] = [];\n\tconst extensionsResult = resourceLoader.getExtensions();\n\tconst registeredFlags = new Map<string, { type: \"boolean\" | \"string\" }>();\n\tfor (const extension of extensionsResult.extensions) {\n\t\tfor (const [name, flag] of extension.flags) {\n\t\t\tregisteredFlags.set(name, { type: flag.type });\n\t\t}\n\t}\n\n\tconst unknownFlags: string[] = [];\n\tfor (const [name, value] of extensionFlagValues) {\n\t\tconst flag = registeredFlags.get(name);\n\t\tif (!flag) {\n\t\t\tunknownFlags.push(name);\n\t\t\tcontinue;\n\t\t}\n\t\tif (flag.type === \"boolean\") {\n\t\t\textensionsResult.runtime.flagValues.set(name, true);\n\t\t\tcontinue;\n\t\t}\n\t\tif (typeof value === \"string\") {\n\t\t\textensionsResult.runtime.flagValues.set(name, value);\n\t\t\tcontinue;\n\t\t}\n\t\tdiagnostics.push({\n\t\t\ttype: \"error\",\n\t\t\tmessage: `Extension flag \"--${name}\" requires a value`,\n\t\t});\n\t}\n\n\tif (unknownFlags.length > 0) {\n\t\tdiagnostics.push({\n\t\t\ttype: \"error\",\n\t\t\tmessage: `Unknown option${unknownFlags.length === 1 ? \"\" : \"s\"}: ${unknownFlags.map((name) => `--${name}`).join(\", \")}`,\n\t\t});\n\t}\n\n\treturn diagnostics;\n}\n\n/**\n * Create cwd-bound runtime services.\n *\n * Returns services plus diagnostics. It does not create an AgentSession.\n */\nexport async function createAgentSessionServices(\n\toptions: CreateAgentSessionServicesOptions,\n): Promise<AgentSessionServices> {\n\tconst cwd = resolvePath(options.cwd);\n\tconst agentDir = options.agentDir ? resolvePath(options.agentDir) : getAgentDir();\n\tconst modelRuntime =\n\t\toptions.modelRuntime ??\n\t\t(await ModelRuntime.create({\n\t\t\tauthPath: join(agentDir, \"auth.json\"),\n\t\t\tmodelsPath: join(agentDir, \"models.json\"),\n\t\t}));\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\tconst resourceLoader = new DefaultResourceLoader({\n\t\t...(options.resourceLoaderOptions ?? {}),\n\t\tcwd,\n\t\tagentDir,\n\t\tsettingsManager,\n\t});\n\tawait resourceLoader.reload(options.resourceLoaderReloadOptions);\n\n\tconst diagnostics: AgentSessionRuntimeDiagnostic[] = [];\n\tconst extensionsResult = resourceLoader.getExtensions();\n\tfor (const { name, config, extensionPath } of extensionsResult.runtime.pendingProviderRegistrations) {\n\t\ttry {\n\t\t\tmodelRuntime.registerProvider(name, config);\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tdiagnostics.push({\n\t\t\t\ttype: \"error\",\n\t\t\t\tmessage: `Extension \"${extensionPath}\" error: ${message}`,\n\t\t\t});\n\t\t}\n\t}\n\textensionsResult.runtime.pendingProviderRegistrations = [];\n\tawait modelRuntime.refresh({ allowNetwork: false });\n\tdiagnostics.push(...applyExtensionFlagValues(resourceLoader, options.extensionFlagValues));\n\n\treturn {\n\t\tcwd,\n\t\tagentDir,\n\t\tmodelRuntime,\n\t\tsettingsManager,\n\t\tresourceLoader,\n\t\tdiagnostics,\n\t};\n}\n\n/**\n * Create an AgentSession from previously created services.\n *\n * This keeps session creation separate from service creation so callers can\n * resolve model, thinking, tools, and other session inputs against the target\n * cwd before constructing the session.\n */\nexport async function createAgentSessionFromServices(\n\toptions: CreateAgentSessionFromServicesOptions,\n): Promise<CreateAgentSessionResult> {\n\treturn createAgentSession({\n\t\tcwd: options.services.cwd,\n\t\tagentDir: options.services.agentDir,\n\t\tmodelRuntime: options.services.modelRuntime,\n\t\tsettingsManager: options.services.settingsManager,\n\t\tresourceLoader: options.services.resourceLoader,\n\t\tsessionManager: options.sessionManager,\n\t\tmodel: options.model,\n\t\tthinkingLevel: options.thinkingLevel,\n\t\tscopedModels: options.scopedModels,\n\t\ttools: options.tools,\n\t\texcludeTools: options.excludeTools,\n\t\tnoTools: options.noTools,\n\t\tcustomTools: options.customTools,\n\t\tsessionStartEvent: options.sessionStartEvent,\n\t});\n}\n"]}