@earendil-works/pi-coding-agent 0.82.0 → 0.83.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/README.md +1 -1
  3. package/dist/cli/args.d.ts.map +1 -1
  4. package/dist/cli/args.js +9 -1
  5. package/dist/cli/args.js.map +1 -1
  6. package/dist/cli/credential-print.d.ts +23 -0
  7. package/dist/cli/credential-print.d.ts.map +1 -0
  8. package/dist/cli/credential-print.js +116 -0
  9. package/dist/cli/credential-print.js.map +1 -0
  10. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  11. package/dist/core/agent-session-runtime.js +3 -0
  12. package/dist/core/agent-session-runtime.js.map +1 -1
  13. package/dist/core/agent-session.d.ts +1 -1
  14. package/dist/core/agent-session.d.ts.map +1 -1
  15. package/dist/core/agent-session.js +15 -13
  16. package/dist/core/agent-session.js.map +1 -1
  17. package/dist/core/extensions/runner.d.ts +1 -0
  18. package/dist/core/extensions/runner.d.ts.map +1 -1
  19. package/dist/core/extensions/runner.js +7 -0
  20. package/dist/core/extensions/runner.js.map +1 -1
  21. package/dist/core/extensions/types.d.ts +9 -0
  22. package/dist/core/extensions/types.d.ts.map +1 -1
  23. package/dist/core/extensions/types.js.map +1 -1
  24. package/dist/core/footer-data-provider.d.ts +10 -0
  25. package/dist/core/footer-data-provider.d.ts.map +1 -1
  26. package/dist/core/footer-data-provider.js +1 -1
  27. package/dist/core/footer-data-provider.js.map +1 -1
  28. package/dist/core/model-resolver.d.ts +1 -0
  29. package/dist/core/model-resolver.d.ts.map +1 -1
  30. package/dist/core/model-resolver.js +13 -3
  31. package/dist/core/model-resolver.js.map +1 -1
  32. package/dist/core/model-runtime.d.ts +2 -0
  33. package/dist/core/model-runtime.d.ts.map +1 -1
  34. package/dist/core/model-runtime.js.map +1 -1
  35. package/dist/core/package-manager.d.ts.map +1 -1
  36. package/dist/core/package-manager.js +13 -6
  37. package/dist/core/package-manager.js.map +1 -1
  38. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  39. package/dist/core/remote-catalog-provider.js +19 -1
  40. package/dist/core/remote-catalog-provider.js.map +1 -1
  41. package/dist/core/resource-loader.d.ts +15 -0
  42. package/dist/core/resource-loader.d.ts.map +1 -1
  43. package/dist/core/resource-loader.js +66 -9
  44. package/dist/core/resource-loader.js.map +1 -1
  45. package/dist/extensions/llama/provider.d.ts.map +1 -1
  46. package/dist/extensions/llama/provider.js +7 -1
  47. package/dist/extensions/llama/provider.js.map +1 -1
  48. package/dist/main.d.ts.map +1 -1
  49. package/dist/main.js +43 -0
  50. package/dist/main.js.map +1 -1
  51. package/dist/modes/interactive/components/custom-message.d.ts +3 -1
  52. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  53. package/dist/modes/interactive/components/custom-message.js +10 -2
  54. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  55. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  56. package/dist/modes/interactive/components/model-selector.js +4 -1
  57. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  58. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  59. package/dist/modes/interactive/components/scoped-models-selector.js +22 -13
  60. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  61. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  62. package/dist/modes/interactive/interactive-mode.js +48 -22
  63. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  64. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  65. package/dist/modes/rpc/rpc-mode.js +13 -0
  66. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  67. package/docs/custom-provider.md +9 -3
  68. package/docs/extensions.md +5 -3
  69. package/docs/providers.md +1 -0
  70. package/docs/session-format.md +2 -0
  71. package/examples/extensions/custom-provider-anthropic/index.ts +8 -2
  72. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  73. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  74. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  75. package/examples/extensions/gondolin/package-lock.json +2 -2
  76. package/examples/extensions/gondolin/package.json +1 -1
  77. package/examples/extensions/message-renderer.ts +2 -2
  78. package/examples/extensions/sandbox/package-lock.json +2 -2
  79. package/examples/extensions/sandbox/package.json +1 -1
  80. package/examples/extensions/with-deps/package-lock.json +2 -2
  81. package/examples/extensions/with-deps/package.json +1 -1
  82. package/examples/sdk/12-full-control.ts +2 -0
  83. package/npm-shrinkwrap.json +18 -18
  84. package/package.json +5 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,77 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.83.0] - 2026-07-29
4
+
5
+ ### New Features
6
+
7
+ - **Credential export for external clients** — `pi auth print-api-key` and `pi auth print-bearer-token` export configured credentials with automatic OAuth refresh and minimum-validity enforcement.
8
+ - **Headless OpenRouter sign-in** — Complete `/login` over SSH by pasting the redirect URL or authorization code when the loopback callback is unavailable. See [OpenRouter](docs/providers.md#openrouter).
9
+ - **Claude Opus 5 on GitHub Copilot** — Use Claude Opus 5 through GitHub Copilot with adaptive thinking and a 1M context window. See [GitHub Copilot](docs/providers.md#github-copilot).
10
+
11
+ ### Breaking Changes
12
+
13
+ - Upgraded bundled TypeBox aliases to 1.3.7, removing deprecated APIs including `Type.Base`, `Type.Awaited`, `Type.Promise`, `Type.AsyncIterator`, `Type.Iterator`, `Type.Options`, and `Value.Mutate`, while fixing compiled validation of nullable array tool arguments. Extensions using removed APIs must migrate to supported TypeBox APIs. See [Package Dependencies](docs/packages.md#dependencies) ([#7243](https://github.com/earendil-works/pi/pull/7243) by [@petrroll](https://github.com/petrroll)).
14
+
15
+ ### Added
16
+
17
+ - Added `pi auth print-api-key` and `pi auth print-bearer-token` commands for exporting configured credentials to external clients, including automatic OAuth refresh and configurable minimum token validity ([#7168](https://github.com/earendil-works/pi/pull/7168)).
18
+ - Exposed the session's resolved model scope as `ctx.scopedModels` to extensions. See [Extension Context](docs/extensions.md#ctxmodelregistry--ctxmodel--ctxthinkinglevel--ctxscopedmodels) ([#7191](https://github.com/earendil-works/pi/pull/7191) by [@pungggi](https://github.com/pungggi), [#7215](https://github.com/earendil-works/pi/pull/7215)).
19
+ - Added inherited per-request `fetch` injection for supported text and image provider transports.
20
+ - Added the inherited `"pending"` stop reason for partial streaming messages. See [Custom Provider Stream Pattern](docs/custom-provider.md#stream-pattern) ([#7151](https://github.com/earendil-works/pi/pull/7151) by [@lucasmeijer](https://github.com/lucasmeijer)).
21
+ - Added inherited raw provider stop reasons across Google, Anthropic, Amazon Bedrock, Mistral, and OpenAI streams; unmapped terminal reasons now surface as provider errors instead of successful stops ([#7272](https://github.com/earendil-works/pi/pull/7272)).
22
+ - Added manual redirect URL and authorization-code entry to OpenRouter login for remote and headless environments. See [OpenRouter](docs/providers.md#openrouter) ([#7114](https://github.com/earendil-works/pi/pull/7114) by [@rgarcia](https://github.com/rgarcia)).
23
+ - Added inherited Claude Opus 5 support for GitHub Copilot with adaptive thinking and a 1M context window. See [GitHub Copilot](docs/providers.md#github-copilot) ([#7158](https://github.com/earendil-works/pi/pull/7158) by [@jay-aye-see-kay](https://github.com/jay-aye-see-kay)).
24
+
25
+ ### Changed
26
+
27
+ - Changed inherited OAuth credential resolution to refresh tokens with less than five minutes of validity remaining instead of waiting until expiration ([#7168](https://github.com/earendil-works/pi/pull/7168)).
28
+
29
+ ### Fixed
30
+
31
+ - Added a status line when the tool output expansion is toggled ([#7180](https://github.com/earendil-works/pi/issues/7180)).
32
+ - Fixed file-backed `SYSTEM.md` and `APPEND_SYSTEM.md` prompts being omitted from the interactive startup context listing. See [System Prompt Files](docs/usage.md#system-prompt-files) ([#7096](https://github.com/earendil-works/pi/issues/7096)).
33
+ - Fixed context files loading twice when a linked Git worktree is nested under its main repository. See [Context Files](docs/usage.md#context-files) ([#7221](https://github.com/earendil-works/pi/pull/7221) by [@arajkumar](https://github.com/arajkumar)).
34
+ - Fixed llama.cpp streamed responses reporting zero token usage and leaving session context accounting empty. See [llama.cpp](docs/llama-cpp.md) ([#7258](https://github.com/earendil-works/pi/pull/7258) by [@SteveImmanuel](https://github.com/SteveImmanuel)).
35
+ - Fixed session replacement and committed tree navigation during an active response to abort and persist the outgoing turn instead of leaving dangling tool calls. See [Sessions](docs/usage.md#sessions) ([#7022](https://github.com/earendil-works/pi/pull/7022) by [@tmustier](https://github.com/tmustier)).
36
+ - Fixed failed Git package installs leaving partial directories that blocked clean retries. See [Install and Manage](docs/packages.md#install-and-manage) ([#7210](https://github.com/earendil-works/pi/pull/7210) by [@haoqixu](https://github.com/haoqixu)).
37
+ - Fixed the `/model` selector retaining a stale selection while filtering instead of highlighting the top match ([#7211](https://github.com/earendil-works/pi/pull/7211) by [@christianbasch](https://github.com/christianbasch)).
38
+ - Fixed direct RPC bash commands bypassing extension `user_bash` handlers. See [User Bash Events](docs/extensions.md#user-bash-events) ([#7214](https://github.com/earendil-works/pi/pull/7214)).
39
+ - Fixed skills, prompts, and themes losing package source metadata after extensions reload resources. See [Resource Events](docs/extensions.md#resource-events) ([#6968](https://github.com/earendil-works/pi/issues/6968)).
40
+ - Fixed cancellation of concurrently running user bash commands so every active command is aborted ([#7103](https://github.com/earendil-works/pi/pull/7103) by [@yzhg1983](https://github.com/yzhg1983)).
41
+ - Fixed duplicate messages appearing when extensions switch sessions during interactive startup ([#7110](https://github.com/earendil-works/pi/pull/7110) by [@yzhg1983](https://github.com/yzhg1983)).
42
+ - Fixed inherited Qwen Token Plan reasoning models to send their service-specific thinking controls and supported reasoning-effort levels ([#6951](https://github.com/earendil-works/pi/issues/6951), [#6998](https://github.com/earendil-works/pi/issues/6998)).
43
+ - Fixed inherited Z.AI output limits being sent through an unsupported parameter. See [Providers](docs/providers.md) ([#7174](https://github.com/earendil-works/pi/pull/7174) by [@HyeokjaeLee](https://github.com/HyeokjaeLee)).
44
+ - Fixed explicitly configured Amazon Bedrock profiles being overridden by ambient AWS access keys. See [Amazon Bedrock](docs/providers.md#amazon-bedrock) ([#7176](https://github.com/earendil-works/pi/pull/7176) by [@christianbasch](https://github.com/christianbasch)).
45
+ - Fixed inherited image fallback paths overflowing narrow terminals, shortened home-directory paths, and made absolute paths clickable when terminal hyperlinks are available ([#7262](https://github.com/earendil-works/pi/pull/7262)).
46
+ - Fixed inherited OpenAI-compatible tool calls losing their function arguments when malformed deltas also contain an empty `custom` object ([#7288](https://github.com/earendil-works/pi/pull/7288) by [@sunnyyoung](https://github.com/sunnyyoung)).
47
+
48
+ ## [0.82.1] - 2026-07-25
49
+
50
+ ### New Features
51
+
52
+ - **Claude Opus 5** — Available on Anthropic and Amazon Bedrock with adaptive thinking (including `xhigh`), inference profiles, and prompt caching. See [Providers](docs/providers.md#api-keys).
53
+ - **Anthropic gateway bearer auth** — `ANTHROPIC_AUTH_TOKEN` authenticates against Anthropic-compatible gateways that require `Authorization: Bearer`, including compaction and branch summaries. See [Environment Variables or Auth File](docs/providers.md#environment-variables-or-auth-file).
54
+ - **Faster, more resilient model catalogs** — pi.dev catalogs revalidate with `If-None-Match` so unchanged providers answer with an empty `304`, and llama.cpp models stay listed across restarts. See [llama.cpp](docs/llama-cpp.md).
55
+
56
+ ### Added
57
+
58
+ - Exposed the `outputPad` setting to custom message renderers. See [Extensions](docs/extensions.md) ([#7045](https://github.com/earendil-works/pi/pull/7045) by [@xl0](https://github.com/xl0)).
59
+ - Added inherited `ANTHROPIC_AUTH_TOKEN` bearer authentication for Anthropic-compatible gateways. See [Providers](docs/providers.md#environment-variables-or-auth-file) ([#5871](https://github.com/earendil-works/pi/issues/5871)).
60
+ - Added inherited Claude Opus 5 support for Anthropic and Amazon Bedrock with adaptive thinking, inference profiles, prompt caching, and preserved AWS validation messages ([#7081](https://github.com/earendil-works/pi/pull/7081) by [@unexge](https://github.com/unexge), [#7083](https://github.com/earendil-works/pi/pull/7083) by [@davidbrai](https://github.com/davidbrai)).
61
+
62
+ ### Changed
63
+
64
+ - Changed pi.dev model catalog refreshes to revalidate with `If-None-Match`, so unchanged provider catalogs answer with an empty `304` instead of a full download.
65
+ - Changed inherited Radius OAuth device authorization, token exchange, and refresh requests to use the configured gateway directly.
66
+ - Changed inherited model loading errors to append the underlying cause, so auth failures such as `OAuth refresh failed for openai-codex` report the provider response instead of a bare wrapper message.
67
+
68
+ ### Fixed
69
+
70
+ - Fixed compaction and branch summaries for providers whose authentication resolves entirely to request headers ([#5871](https://github.com/earendil-works/pi/issues/5871))
71
+ - Fixed unavailable scoped models being hidden from `/models`, allowing them to be removed without editing settings manually ([#6949](https://github.com/earendil-works/pi/issues/6949), [#7032](https://github.com/earendil-works/pi/pull/7032) by [@christianklotz](https://github.com/christianklotz)).
72
+ - Fixed startup context file discovery to skip directories that match context file names such as `AGENTS.md`, which produced `EISDIR` warnings ([#7106](https://github.com/earendil-works/pi/pull/7106) by [@mrexodia](https://github.com/mrexodia)).
73
+ - Fixed the llama.cpp extension to persist its model catalog, so llama.cpp models stay listed before the first successful refresh. See [llama.cpp](docs/llama-cpp.md) ([#7072](https://github.com/earendil-works/pi/pull/7072) by [@davidbrai](https://github.com/davidbrai)).
74
+
3
75
  ## [0.82.0] - 2026-07-24
4
76
 
5
77
  ### New Features
package/README.md CHANGED
@@ -16,7 +16,7 @@ Pi is a minimal terminal coding harness. Adapt pi to your workflows, not the oth
16
16
 
17
17
  Pi ships with powerful defaults but skips features like sub agents and plan mode. Instead, you can ask pi to build what you want or install a third party pi package that matches your workflow.
18
18
 
19
- Pi runs in four modes: interactive, print or JSON, RPC for process integration, and an SDK for embedding in your own apps. See [openclaw/openclaw](https://github.com/openclaw/openclaw) for a real-world SDK integration.
19
+ Pi runs in four modes: interactive, print or JSON, RPC for process integration, and an SDK for embedding in your own apps.
20
20
 
21
21
  ## Share your OSS coding agent sessions
22
22
 
@@ -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,CAoLhE","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 QWEN_TOKEN_PLAN_API_KEY - Qwen Token Plan API key (international region)\n QWEN_TOKEN_PLAN_CN_API_KEY - Qwen Token Plan API key (China region)\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,CA4LhE","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} auth <command> Print credentials for external clients\n ${APP_NAME} <command> --help Show help for install/remove/uninstall/update/list/config/auth\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 # Print a provider API key for an external client\n ${APP_NAME} auth print-api-key --provider openai --model gpt-5.5\n\n # Print an OAuth bearer token for an external client (refreshes if expired)\n ${APP_NAME} auth print-bearer-token --provider openai-codex --model gpt-5.5\n\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_AUTH_TOKEN - Anthropic bearer auth token\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 QWEN_TOKEN_PLAN_API_KEY - Qwen Token Plan API key (international region)\n QWEN_TOKEN_PLAN_CN_API_KEY - Qwen Token Plan API key (China region)\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
@@ -220,7 +220,8 @@ ${chalk.bold("Commands:")}
220
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
- ${APP_NAME} <command> --help Show help for install/remove/uninstall/update/list/config
223
+ ${APP_NAME} auth <command> Print credentials for external clients
224
+ ${APP_NAME} <command> --help Show help for install/remove/uninstall/update/list/config/auth
224
225
 
225
226
  ${chalk.bold("Options:")}
226
227
  --provider <name> Provider name (default: google)
@@ -268,6 +269,12 @@ ${chalk.bold("Options:")}
268
269
  Extensions can register additional flags (e.g., --plan from plan-mode extension).${extensionFlagsText}
269
270
 
270
271
  ${chalk.bold("Examples:")}
272
+ # Print a provider API key for an external client
273
+ ${APP_NAME} auth print-api-key --provider openai --model gpt-5.5
274
+
275
+ # Print an OAuth bearer token for an external client (refreshes if expired)
276
+ ${APP_NAME} auth print-bearer-token --provider openai-codex --model gpt-5.5
277
+
271
278
  # Interactive mode
272
279
  ${APP_NAME}
273
280
 
@@ -321,6 +328,7 @@ ${chalk.bold("Examples:")}
321
328
  ${APP_NAME} --export session.jsonl output.html
322
329
 
323
330
  ${chalk.bold("Environment Variables:")}
331
+ ANTHROPIC_AUTH_TOKEN - Anthropic bearer auth token
324
332
  ANTHROPIC_API_KEY - Anthropic Claude API key
325
333
  ANTHROPIC_OAUTH_TOKEN - Anthropic OAuth token (alternative to API key)
326
334
  ANT_LING_API_KEY - Ant Ling API key
@@ -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, 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 QWEN_TOKEN_PLAN_API_KEY - Qwen Token Plan API key (international region)\n QWEN_TOKEN_PLAN_CN_API_KEY - Qwen Token Plan API key (China region)\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} auth <command> Print credentials for external clients\n ${APP_NAME} <command> --help Show help for install/remove/uninstall/update/list/config/auth\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 # Print a provider API key for an external client\n ${APP_NAME} auth print-api-key --provider openai --model gpt-5.5\n\n # Print an OAuth bearer token for an external client (refreshes if expired)\n ${APP_NAME} auth print-bearer-token --provider openai-codex --model gpt-5.5\n\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_AUTH_TOKEN - Anthropic bearer auth token\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 QWEN_TOKEN_PLAN_API_KEY - Qwen Token Plan API key (international region)\n QWEN_TOKEN_PLAN_CN_API_KEY - Qwen Token Plan API key (China region)\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"]}
@@ -0,0 +1,23 @@
1
+ import type { ModelRuntime } from "../core/model-runtime.ts";
2
+ import type { Args } from "./args.ts";
3
+ export type CredentialPrintKind = "api_key" | "bearer_token";
4
+ export interface CredentialPrintCommand {
5
+ kind: CredentialPrintKind;
6
+ args: string[];
7
+ minExpiryMs?: number;
8
+ }
9
+ export declare class CredentialPrintError extends Error {
10
+ }
11
+ export declare function isCredentialPrintHelp(args: string[]): boolean;
12
+ export declare function printCredentialPrintHelp(): void;
13
+ /** Parse the small, extensible `pi auth` command surface before normal startup. */
14
+ export declare function parseCredentialPrintCommand(args: string[]): CredentialPrintCommand | undefined;
15
+ export declare function validateCredentialPrintArgs(args: Args): void;
16
+ /**
17
+ * Resolve one request credential for a specific provider/model pair.
18
+ *
19
+ * This intentionally calls ModelRuntime.getAuth(), which refreshes and persists
20
+ * OAuth credentials with less than five minutes remaining through the normal request-auth path.
21
+ */
22
+ export declare function resolveCredentialForPrint(args: Args, modelRuntime: ModelRuntime, kind: CredentialPrintKind, minExpiryMs?: number): Promise<string>;
23
+ //# sourceMappingURL=credential-print.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credential-print.d.ts","sourceRoot":"","sources":["../../src/cli/credential-print.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,cAAc,CAAC;AAI7D,MAAM,WAAW,sBAAsB;IACtC,IAAI,EAAE,mBAAmB,CAAC;IAC1B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,oBAAqB,SAAQ,KAAK;CAAG;AAElD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAI7D;AAED,wBAAgB,wBAAwB,IAAI,IAAI,CAM/C;AAED,mFAAmF;AACnF,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,sBAAsB,GAAG,SAAS,CA+B9F;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAU5D;AAED;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC9C,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,YAAY,EAC1B,IAAI,EAAE,mBAAmB,EACzB,WAAW,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC,CA+DjB","sourcesContent":["import type { Api, CredentialInfo, Model } from \"@earendil-works/pi-ai\";\nimport { resolveCliModel } from \"../core/model-resolver.ts\";\nimport type { ModelRuntime } from \"../core/model-runtime.ts\";\nimport type { Args } from \"./args.ts\";\n\nexport type CredentialPrintKind = \"api_key\" | \"bearer_token\";\n\nconst DEFAULT_BEARER_TOKEN_MIN_EXPIRY_MS = 30 * 60_000;\n\nexport interface CredentialPrintCommand {\n\tkind: CredentialPrintKind;\n\targs: string[];\n\tminExpiryMs?: number;\n}\n\nexport class CredentialPrintError extends Error {}\n\nexport function isCredentialPrintHelp(args: string[]): boolean {\n\treturn (\n\t\targs[0] === \"auth\" && (args[1] === undefined || args[1] === \"help\" || args[1] === \"--help\" || args[1] === \"-h\")\n\t);\n}\n\nexport function printCredentialPrintHelp(): void {\n\tconsole.log(`Usage:\n pi auth print-api-key --model <model> [--provider <provider>]\n pi auth print-bearer-token --model <model> [--provider <provider>] [--min-expiry <duration>]\n\nPrints the configured credential alone on stdout. Provider inference uses configured credentials; specify --provider to select explicitly. Bearer tokens have a 30-minute minimum expiry by default. --min-expiry accepts ms, s, m, or h (for example, 30m).`);\n}\n\n/** Parse the small, extensible `pi auth` command surface before normal startup. */\nexport function parseCredentialPrintCommand(args: string[]): CredentialPrintCommand | undefined {\n\tif (args[0] !== \"auth\") return undefined;\n\n\tconst kind = args[1] === \"print-api-key\" ? \"api_key\" : args[1] === \"print-bearer-token\" ? \"bearer_token\" : undefined;\n\tif (!kind) {\n\t\tthrow new CredentialPrintError(\n\t\t\t`Unknown auth command \"${args[1] ?? \"\"}\". Use \"pi auth print-api-key\" or \"pi auth print-bearer-token\".`,\n\t\t);\n\t}\n\n\tconst commandArgs: string[] = [];\n\tlet minExpiryMs: number | undefined;\n\tfor (let index = 2; index < args.length; index++) {\n\t\tif (args[index] !== \"--min-expiry\") {\n\t\t\tcommandArgs.push(args[index]);\n\t\t\tcontinue;\n\t\t}\n\t\tif (kind !== \"bearer_token\") {\n\t\t\tthrow new CredentialPrintError(\"--min-expiry is only supported by print-bearer-token\");\n\t\t}\n\t\tconst value = args[++index];\n\t\tconst match = value ? /^(\\d+)(ms|s|m|h)$/iu.exec(value) : undefined;\n\t\tif (!match) {\n\t\t\tthrow new CredentialPrintError(\"--min-expiry must use a duration such as 30m or 1h\");\n\t\t}\n\t\tconst amount = Number(match[1]);\n\t\tconst unit = match[2];\n\t\tminExpiryMs = amount * (unit === \"ms\" ? 1 : unit === \"s\" ? 1_000 : unit === \"m\" ? 60_000 : 3_600_000);\n\t}\n\n\treturn minExpiryMs === undefined ? { kind, args: commandArgs } : { kind, args: commandArgs, minExpiryMs };\n}\n\nexport function validateCredentialPrintArgs(args: Args): void {\n\tif (!args.model?.trim()) {\n\t\tthrow new CredentialPrintError(\"Credential printing requires --model <model>\");\n\t}\n\tif (args.apiKey !== undefined) {\n\t\tthrow new CredentialPrintError(\"Credential printing reads configured credentials; --api-key is not supported\");\n\t}\n\tif (args.messages.length > 0 || args.fileArgs.length > 0 || args.unknownFlags.size > 0) {\n\t\tthrow new CredentialPrintError(\"Credential printing only accepts --provider and --model\");\n\t}\n}\n\n/**\n * Resolve one request credential for a specific provider/model pair.\n *\n * This intentionally calls ModelRuntime.getAuth(), which refreshes and persists\n * OAuth credentials with less than five minutes remaining through the normal request-auth path.\n */\nexport async function resolveCredentialForPrint(\n\targs: Args,\n\tmodelRuntime: ModelRuntime,\n\tkind: CredentialPrintKind,\n\tminExpiryMs?: number,\n): Promise<string> {\n\tvalidateCredentialPrintArgs(args);\n\n\tconst credentialTypes = new Map<string, CredentialInfo[\"type\"]>(\n\t\t(await modelRuntime.listCredentials()).map((credential) => [credential.providerId, credential.type]),\n\t);\n\tconst models: Model<Api>[] = [];\n\tif (args.provider) {\n\t\tconst resolved = resolveCliModel({ cliProvider: args.provider, cliModel: args.model, modelRuntime });\n\t\tif (resolved.error || !resolved.model) {\n\t\t\tthrow new CredentialPrintError(resolved.error ?? \"Unable to resolve the requested provider/model\");\n\t\t}\n\t\tmodels.push(resolved.model);\n\t} else {\n\t\tfor (const provider of modelRuntime.getProviders()) {\n\t\t\tif (!credentialTypes.has(provider.id)) continue;\n\t\t\tconst resolved = resolveCliModel({ cliProvider: provider.id, cliModel: args.model, modelRuntime });\n\t\t\tif (resolved.model && !resolved.error && !resolved.warning?.includes(\"Using custom model id\")) {\n\t\t\t\tmodels.push(resolved.model);\n\t\t\t}\n\t\t}\n\t\tif (models.length === 0) {\n\t\t\tthrow new CredentialPrintError(`Model \"${args.model}\" not found. Use --list-models to see available models.`);\n\t\t}\n\t}\n\n\tconst credentials: Array<{ providerId: string; value: string }> = [];\n\tfor (const model of models) {\n\t\tconst type = credentialTypes.get(model.provider);\n\t\tif (kind === \"api_key\" && type === \"oauth\") continue;\n\t\tif (kind === \"bearer_token\" && type !== \"oauth\") continue;\n\n\t\tconst auth = await modelRuntime.getAuth(\n\t\t\tmodel,\n\t\t\tkind === \"bearer_token\"\n\t\t\t\t? { minOAuthValidityMs: minExpiryMs ?? DEFAULT_BEARER_TOKEN_MIN_EXPIRY_MS }\n\t\t\t\t: undefined,\n\t\t);\n\t\tconst authorization = Object.entries(auth?.auth.headers ?? {}).find(\n\t\t\t([name]) => name.toLowerCase() === \"authorization\",\n\t\t)?.[1];\n\t\tconst bearerToken = typeof authorization === \"string\" ? /^Bearer\\s+(.+)$/iu.exec(authorization)?.[1] : undefined;\n\t\tconst value = kind === \"bearer_token\" ? (auth?.auth.apiKey ?? bearerToken) : auth?.auth.apiKey;\n\t\tif (value) credentials.push({ providerId: model.provider, value });\n\t}\n\n\tif (credentials.length === 1) return credentials[0].value;\n\tif (credentials.length === 0) {\n\t\tconst providerId = models[0]?.provider;\n\t\tconst type = providerId ? credentialTypes.get(providerId) : undefined;\n\t\tif (args.provider && kind === \"api_key\" && type === \"oauth\") {\n\t\t\tthrow new CredentialPrintError(`Provider \"${providerId}\" is configured with OAuth, not an API key`);\n\t\t}\n\t\tif (args.provider && kind === \"bearer_token\" && type !== \"oauth\") {\n\t\t\tthrow new CredentialPrintError(`Provider \"${providerId}\" is not configured with an OAuth bearer token`);\n\t\t}\n\t\tthrow new CredentialPrintError(\n\t\t\t`No usable ${kind === \"api_key\" ? \"API key\" : \"OAuth bearer token\"} is configured`,\n\t\t);\n\t}\n\tthrow new CredentialPrintError(\n\t\t`Model \"${args.model}\" has multiple configured providers (${credentials.map(({ providerId }) => providerId).join(\", \")}). Specify --provider.`,\n\t);\n}\n"]}
@@ -0,0 +1,116 @@
1
+ import { resolveCliModel } from "../core/model-resolver.js";
2
+ const DEFAULT_BEARER_TOKEN_MIN_EXPIRY_MS = 30 * 60_000;
3
+ export class CredentialPrintError extends Error {
4
+ }
5
+ export function isCredentialPrintHelp(args) {
6
+ return (args[0] === "auth" && (args[1] === undefined || args[1] === "help" || args[1] === "--help" || args[1] === "-h"));
7
+ }
8
+ export function printCredentialPrintHelp() {
9
+ console.log(`Usage:
10
+ pi auth print-api-key --model <model> [--provider <provider>]
11
+ pi auth print-bearer-token --model <model> [--provider <provider>] [--min-expiry <duration>]
12
+
13
+ Prints the configured credential alone on stdout. Provider inference uses configured credentials; specify --provider to select explicitly. Bearer tokens have a 30-minute minimum expiry by default. --min-expiry accepts ms, s, m, or h (for example, 30m).`);
14
+ }
15
+ /** Parse the small, extensible `pi auth` command surface before normal startup. */
16
+ export function parseCredentialPrintCommand(args) {
17
+ if (args[0] !== "auth")
18
+ return undefined;
19
+ const kind = args[1] === "print-api-key" ? "api_key" : args[1] === "print-bearer-token" ? "bearer_token" : undefined;
20
+ if (!kind) {
21
+ throw new CredentialPrintError(`Unknown auth command "${args[1] ?? ""}". Use "pi auth print-api-key" or "pi auth print-bearer-token".`);
22
+ }
23
+ const commandArgs = [];
24
+ let minExpiryMs;
25
+ for (let index = 2; index < args.length; index++) {
26
+ if (args[index] !== "--min-expiry") {
27
+ commandArgs.push(args[index]);
28
+ continue;
29
+ }
30
+ if (kind !== "bearer_token") {
31
+ throw new CredentialPrintError("--min-expiry is only supported by print-bearer-token");
32
+ }
33
+ const value = args[++index];
34
+ const match = value ? /^(\d+)(ms|s|m|h)$/iu.exec(value) : undefined;
35
+ if (!match) {
36
+ throw new CredentialPrintError("--min-expiry must use a duration such as 30m or 1h");
37
+ }
38
+ const amount = Number(match[1]);
39
+ const unit = match[2];
40
+ minExpiryMs = amount * (unit === "ms" ? 1 : unit === "s" ? 1_000 : unit === "m" ? 60_000 : 3_600_000);
41
+ }
42
+ return minExpiryMs === undefined ? { kind, args: commandArgs } : { kind, args: commandArgs, minExpiryMs };
43
+ }
44
+ export function validateCredentialPrintArgs(args) {
45
+ if (!args.model?.trim()) {
46
+ throw new CredentialPrintError("Credential printing requires --model <model>");
47
+ }
48
+ if (args.apiKey !== undefined) {
49
+ throw new CredentialPrintError("Credential printing reads configured credentials; --api-key is not supported");
50
+ }
51
+ if (args.messages.length > 0 || args.fileArgs.length > 0 || args.unknownFlags.size > 0) {
52
+ throw new CredentialPrintError("Credential printing only accepts --provider and --model");
53
+ }
54
+ }
55
+ /**
56
+ * Resolve one request credential for a specific provider/model pair.
57
+ *
58
+ * This intentionally calls ModelRuntime.getAuth(), which refreshes and persists
59
+ * OAuth credentials with less than five minutes remaining through the normal request-auth path.
60
+ */
61
+ export async function resolveCredentialForPrint(args, modelRuntime, kind, minExpiryMs) {
62
+ validateCredentialPrintArgs(args);
63
+ const credentialTypes = new Map((await modelRuntime.listCredentials()).map((credential) => [credential.providerId, credential.type]));
64
+ const models = [];
65
+ if (args.provider) {
66
+ const resolved = resolveCliModel({ cliProvider: args.provider, cliModel: args.model, modelRuntime });
67
+ if (resolved.error || !resolved.model) {
68
+ throw new CredentialPrintError(resolved.error ?? "Unable to resolve the requested provider/model");
69
+ }
70
+ models.push(resolved.model);
71
+ }
72
+ else {
73
+ for (const provider of modelRuntime.getProviders()) {
74
+ if (!credentialTypes.has(provider.id))
75
+ continue;
76
+ const resolved = resolveCliModel({ cliProvider: provider.id, cliModel: args.model, modelRuntime });
77
+ if (resolved.model && !resolved.error && !resolved.warning?.includes("Using custom model id")) {
78
+ models.push(resolved.model);
79
+ }
80
+ }
81
+ if (models.length === 0) {
82
+ throw new CredentialPrintError(`Model "${args.model}" not found. Use --list-models to see available models.`);
83
+ }
84
+ }
85
+ const credentials = [];
86
+ for (const model of models) {
87
+ const type = credentialTypes.get(model.provider);
88
+ if (kind === "api_key" && type === "oauth")
89
+ continue;
90
+ if (kind === "bearer_token" && type !== "oauth")
91
+ continue;
92
+ const auth = await modelRuntime.getAuth(model, kind === "bearer_token"
93
+ ? { minOAuthValidityMs: minExpiryMs ?? DEFAULT_BEARER_TOKEN_MIN_EXPIRY_MS }
94
+ : undefined);
95
+ const authorization = Object.entries(auth?.auth.headers ?? {}).find(([name]) => name.toLowerCase() === "authorization")?.[1];
96
+ const bearerToken = typeof authorization === "string" ? /^Bearer\s+(.+)$/iu.exec(authorization)?.[1] : undefined;
97
+ const value = kind === "bearer_token" ? (auth?.auth.apiKey ?? bearerToken) : auth?.auth.apiKey;
98
+ if (value)
99
+ credentials.push({ providerId: model.provider, value });
100
+ }
101
+ if (credentials.length === 1)
102
+ return credentials[0].value;
103
+ if (credentials.length === 0) {
104
+ const providerId = models[0]?.provider;
105
+ const type = providerId ? credentialTypes.get(providerId) : undefined;
106
+ if (args.provider && kind === "api_key" && type === "oauth") {
107
+ throw new CredentialPrintError(`Provider "${providerId}" is configured with OAuth, not an API key`);
108
+ }
109
+ if (args.provider && kind === "bearer_token" && type !== "oauth") {
110
+ throw new CredentialPrintError(`Provider "${providerId}" is not configured with an OAuth bearer token`);
111
+ }
112
+ throw new CredentialPrintError(`No usable ${kind === "api_key" ? "API key" : "OAuth bearer token"} is configured`);
113
+ }
114
+ throw new CredentialPrintError(`Model "${args.model}" has multiple configured providers (${credentials.map(({ providerId }) => providerId).join(", ")}). Specify --provider.`);
115
+ }
116
+ //# sourceMappingURL=credential-print.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credential-print.js","sourceRoot":"","sources":["../../src/cli/credential-print.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Api, CredentialInfo, Model } from \"@earendil-works/pi-ai\";\nimport { resolveCliModel } from \"../core/model-resolver.ts\";\nimport type { ModelRuntime } from \"../core/model-runtime.ts\";\nimport type { Args } from \"./args.ts\";\n\nexport type CredentialPrintKind = \"api_key\" | \"bearer_token\";\n\nconst DEFAULT_BEARER_TOKEN_MIN_EXPIRY_MS = 30 * 60_000;\n\nexport interface CredentialPrintCommand {\n\tkind: CredentialPrintKind;\n\targs: string[];\n\tminExpiryMs?: number;\n}\n\nexport class CredentialPrintError extends Error {}\n\nexport function isCredentialPrintHelp(args: string[]): boolean {\n\treturn (\n\t\targs[0] === \"auth\" && (args[1] === undefined || args[1] === \"help\" || args[1] === \"--help\" || args[1] === \"-h\")\n\t);\n}\n\nexport function printCredentialPrintHelp(): void {\n\tconsole.log(`Usage:\n pi auth print-api-key --model <model> [--provider <provider>]\n pi auth print-bearer-token --model <model> [--provider <provider>] [--min-expiry <duration>]\n\nPrints the configured credential alone on stdout. Provider inference uses configured credentials; specify --provider to select explicitly. Bearer tokens have a 30-minute minimum expiry by default. --min-expiry accepts ms, s, m, or h (for example, 30m).`);\n}\n\n/** Parse the small, extensible `pi auth` command surface before normal startup. */\nexport function parseCredentialPrintCommand(args: string[]): CredentialPrintCommand | undefined {\n\tif (args[0] !== \"auth\") return undefined;\n\n\tconst kind = args[1] === \"print-api-key\" ? \"api_key\" : args[1] === \"print-bearer-token\" ? \"bearer_token\" : undefined;\n\tif (!kind) {\n\t\tthrow new CredentialPrintError(\n\t\t\t`Unknown auth command \"${args[1] ?? \"\"}\". Use \"pi auth print-api-key\" or \"pi auth print-bearer-token\".`,\n\t\t);\n\t}\n\n\tconst commandArgs: string[] = [];\n\tlet minExpiryMs: number | undefined;\n\tfor (let index = 2; index < args.length; index++) {\n\t\tif (args[index] !== \"--min-expiry\") {\n\t\t\tcommandArgs.push(args[index]);\n\t\t\tcontinue;\n\t\t}\n\t\tif (kind !== \"bearer_token\") {\n\t\t\tthrow new CredentialPrintError(\"--min-expiry is only supported by print-bearer-token\");\n\t\t}\n\t\tconst value = args[++index];\n\t\tconst match = value ? /^(\\d+)(ms|s|m|h)$/iu.exec(value) : undefined;\n\t\tif (!match) {\n\t\t\tthrow new CredentialPrintError(\"--min-expiry must use a duration such as 30m or 1h\");\n\t\t}\n\t\tconst amount = Number(match[1]);\n\t\tconst unit = match[2];\n\t\tminExpiryMs = amount * (unit === \"ms\" ? 1 : unit === \"s\" ? 1_000 : unit === \"m\" ? 60_000 : 3_600_000);\n\t}\n\n\treturn minExpiryMs === undefined ? { kind, args: commandArgs } : { kind, args: commandArgs, minExpiryMs };\n}\n\nexport function validateCredentialPrintArgs(args: Args): void {\n\tif (!args.model?.trim()) {\n\t\tthrow new CredentialPrintError(\"Credential printing requires --model <model>\");\n\t}\n\tif (args.apiKey !== undefined) {\n\t\tthrow new CredentialPrintError(\"Credential printing reads configured credentials; --api-key is not supported\");\n\t}\n\tif (args.messages.length > 0 || args.fileArgs.length > 0 || args.unknownFlags.size > 0) {\n\t\tthrow new CredentialPrintError(\"Credential printing only accepts --provider and --model\");\n\t}\n}\n\n/**\n * Resolve one request credential for a specific provider/model pair.\n *\n * This intentionally calls ModelRuntime.getAuth(), which refreshes and persists\n * OAuth credentials with less than five minutes remaining through the normal request-auth path.\n */\nexport async function resolveCredentialForPrint(\n\targs: Args,\n\tmodelRuntime: ModelRuntime,\n\tkind: CredentialPrintKind,\n\tminExpiryMs?: number,\n): Promise<string> {\n\tvalidateCredentialPrintArgs(args);\n\n\tconst credentialTypes = new Map<string, CredentialInfo[\"type\"]>(\n\t\t(await modelRuntime.listCredentials()).map((credential) => [credential.providerId, credential.type]),\n\t);\n\tconst models: Model<Api>[] = [];\n\tif (args.provider) {\n\t\tconst resolved = resolveCliModel({ cliProvider: args.provider, cliModel: args.model, modelRuntime });\n\t\tif (resolved.error || !resolved.model) {\n\t\t\tthrow new CredentialPrintError(resolved.error ?? \"Unable to resolve the requested provider/model\");\n\t\t}\n\t\tmodels.push(resolved.model);\n\t} else {\n\t\tfor (const provider of modelRuntime.getProviders()) {\n\t\t\tif (!credentialTypes.has(provider.id)) continue;\n\t\t\tconst resolved = resolveCliModel({ cliProvider: provider.id, cliModel: args.model, modelRuntime });\n\t\t\tif (resolved.model && !resolved.error && !resolved.warning?.includes(\"Using custom model id\")) {\n\t\t\t\tmodels.push(resolved.model);\n\t\t\t}\n\t\t}\n\t\tif (models.length === 0) {\n\t\t\tthrow new CredentialPrintError(`Model \"${args.model}\" not found. Use --list-models to see available models.`);\n\t\t}\n\t}\n\n\tconst credentials: Array<{ providerId: string; value: string }> = [];\n\tfor (const model of models) {\n\t\tconst type = credentialTypes.get(model.provider);\n\t\tif (kind === \"api_key\" && type === \"oauth\") continue;\n\t\tif (kind === \"bearer_token\" && type !== \"oauth\") continue;\n\n\t\tconst auth = await modelRuntime.getAuth(\n\t\t\tmodel,\n\t\t\tkind === \"bearer_token\"\n\t\t\t\t? { minOAuthValidityMs: minExpiryMs ?? DEFAULT_BEARER_TOKEN_MIN_EXPIRY_MS }\n\t\t\t\t: undefined,\n\t\t);\n\t\tconst authorization = Object.entries(auth?.auth.headers ?? {}).find(\n\t\t\t([name]) => name.toLowerCase() === \"authorization\",\n\t\t)?.[1];\n\t\tconst bearerToken = typeof authorization === \"string\" ? /^Bearer\\s+(.+)$/iu.exec(authorization)?.[1] : undefined;\n\t\tconst value = kind === \"bearer_token\" ? (auth?.auth.apiKey ?? bearerToken) : auth?.auth.apiKey;\n\t\tif (value) credentials.push({ providerId: model.provider, value });\n\t}\n\n\tif (credentials.length === 1) return credentials[0].value;\n\tif (credentials.length === 0) {\n\t\tconst providerId = models[0]?.provider;\n\t\tconst type = providerId ? credentialTypes.get(providerId) : undefined;\n\t\tif (args.provider && kind === \"api_key\" && type === \"oauth\") {\n\t\t\tthrow new CredentialPrintError(`Provider \"${providerId}\" is configured with OAuth, not an API key`);\n\t\t}\n\t\tif (args.provider && kind === \"bearer_token\" && type !== \"oauth\") {\n\t\t\tthrow new CredentialPrintError(`Provider \"${providerId}\" is not configured with an OAuth bearer token`);\n\t\t}\n\t\tthrow new CredentialPrintError(\n\t\t\t`No usable ${kind === \"api_key\" ? \"API key\" : \"OAuth bearer token\"} is configured`,\n\t\t);\n\t}\n\tthrow new CredentialPrintError(\n\t\t`Model \"${args.model}\" has multiple configured providers (${credentials.map(({ providerId }) => providerId).join(\", \")}). Specify --provider.`,\n\t);\n}\n"]}