@mariozechner/pi-coding-agent 0.48.0 → 0.49.1

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 (101) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +29 -2
  3. package/dist/core/agent-session.d.ts +2 -1
  4. package/dist/core/agent-session.d.ts.map +1 -1
  5. package/dist/core/agent-session.js +19 -1
  6. package/dist/core/agent-session.js.map +1 -1
  7. package/dist/core/compaction/compaction.d.ts +11 -0
  8. package/dist/core/compaction/compaction.d.ts.map +1 -1
  9. package/dist/core/compaction/compaction.js +50 -3
  10. package/dist/core/compaction/compaction.js.map +1 -1
  11. package/dist/core/extensions/index.d.ts +1 -1
  12. package/dist/core/extensions/index.d.ts.map +1 -1
  13. package/dist/core/extensions/index.js.map +1 -1
  14. package/dist/core/extensions/loader.d.ts.map +1 -1
  15. package/dist/core/extensions/loader.js +4 -0
  16. package/dist/core/extensions/loader.js.map +1 -1
  17. package/dist/core/extensions/runner.d.ts +4 -2
  18. package/dist/core/extensions/runner.d.ts.map +1 -1
  19. package/dist/core/extensions/runner.js +56 -24
  20. package/dist/core/extensions/runner.js.map +1 -1
  21. package/dist/core/extensions/types.d.ts +23 -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/model-registry.d.ts +2 -0
  25. package/dist/core/model-registry.d.ts.map +1 -1
  26. package/dist/core/model-registry.js +38 -5
  27. package/dist/core/model-registry.js.map +1 -1
  28. package/dist/core/settings-manager.d.ts +3 -0
  29. package/dist/core/settings-manager.d.ts.map +1 -1
  30. package/dist/core/settings-manager.js +7 -0
  31. package/dist/core/settings-manager.js.map +1 -1
  32. package/dist/core/system-prompt.d.ts.map +1 -1
  33. package/dist/core/system-prompt.js +16 -21
  34. package/dist/core/system-prompt.js.map +1 -1
  35. package/dist/core/tools/path-utils.d.ts +0 -1
  36. package/dist/core/tools/path-utils.d.ts.map +1 -1
  37. package/dist/core/tools/path-utils.js +0 -7
  38. package/dist/core/tools/path-utils.js.map +1 -1
  39. package/dist/core/tools/read.d.ts.map +1 -1
  40. package/dist/core/tools/read.js +2 -12
  41. package/dist/core/tools/read.js.map +1 -1
  42. package/dist/index.d.ts +3 -3
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +2 -2
  45. package/dist/index.js.map +1 -1
  46. package/dist/modes/interactive/components/extension-input.d.ts +5 -2
  47. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  48. package/dist/modes/interactive/components/extension-input.js +9 -0
  49. package/dist/modes/interactive/components/extension-input.js.map +1 -1
  50. package/dist/modes/interactive/components/login-dialog.d.ts +5 -2
  51. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  52. package/dist/modes/interactive/components/login-dialog.js +9 -0
  53. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  54. package/dist/modes/interactive/components/model-selector.d.ts +5 -2
  55. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  56. package/dist/modes/interactive/components/model-selector.js +10 -1
  57. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  58. package/dist/modes/interactive/components/scoped-models-selector.d.ts +5 -2
  59. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  60. package/dist/modes/interactive/components/scoped-models-selector.js +9 -0
  61. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  62. package/dist/modes/interactive/components/session-selector.d.ts +23 -5
  63. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  64. package/dist/modes/interactive/components/session-selector.js +327 -55
  65. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  66. package/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  67. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  68. package/dist/modes/interactive/components/settings-selector.js +13 -1
  69. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  70. package/dist/modes/interactive/components/tree-selector.d.ts +5 -2
  71. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  72. package/dist/modes/interactive/components/tree-selector.js +23 -0
  73. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  74. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  75. package/dist/modes/interactive/interactive-mode.js +54 -6
  76. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  77. package/dist/modes/print-mode.d.ts.map +1 -1
  78. package/dist/modes/print-mode.js +16 -0
  79. package/dist/modes/print-mode.js.map +1 -1
  80. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  81. package/dist/modes/rpc/rpc-mode.js +16 -0
  82. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  83. package/dist/utils/image-convert.d.ts.map +1 -1
  84. package/dist/utils/image-convert.js +4 -3
  85. package/dist/utils/image-convert.js.map +1 -1
  86. package/dist/utils/image-resize.d.ts.map +1 -1
  87. package/dist/utils/image-resize.js +2 -2
  88. package/dist/utils/image-resize.js.map +1 -1
  89. package/dist/utils/photon.d.ts +6 -13
  90. package/dist/utils/photon.d.ts.map +1 -1
  91. package/dist/utils/photon.js +99 -29
  92. package/dist/utils/photon.js.map +1 -1
  93. package/docs/extensions.md +67 -1
  94. package/docs/session.md +6 -0
  95. package/docs/tui.md +30 -0
  96. package/examples/extensions/README.md +1 -0
  97. package/examples/extensions/custom-header.ts +2 -1
  98. package/examples/extensions/trigger-compact.ts +40 -0
  99. package/examples/extensions/with-deps/package-lock.json +2 -2
  100. package/examples/extensions/with-deps/package.json +1 -1
  101. package/package.json +5 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,54 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.49.1] - 2026-01-18
4
+
5
+ ### Added
6
+
7
+ - Added `strictResponsesPairing` compat option for custom OpenAI Responses models on Azure ([#768](https://github.com/badlogic/pi-mono/pull/768) by [@nicobako](https://github.com/nicobako))
8
+ - Session selector (`/resume`) now supports path display toggle (`Ctrl+P`) and session deletion (`Ctrl+D`) with inline confirmation ([#816](https://github.com/badlogic/pi-mono/pull/816) by [@w-winter](https://github.com/w-winter))
9
+ - Added undo support in interactive mode with Ctrl+- hotkey. ([#831](https://github.com/badlogic/pi-mono/pull/831) by [@Perlence](https://github.com/Perlence))
10
+
11
+ ### Changed
12
+
13
+ - Share URLs now use hash fragments (`#`) instead of query strings (`?`) to prevent session IDs from being sent to buildwithpi.ai ([#829](https://github.com/badlogic/pi-mono/pull/829) by [@terrorobe](https://github.com/terrorobe))
14
+ - API keys in `models.json` can now be retrieved via shell command using `!` prefix (e.g., `"apiKey": "!security find-generic-password -ws 'anthropic'"` for macOS Keychain) ([#762](https://github.com/badlogic/pi-mono/pull/762) by [@cv](https://github.com/cv))
15
+
16
+ ### Fixed
17
+
18
+ - Fixed IME candidate window appearing in wrong position when filtering menus with Input Method Editor (e.g., Chinese IME). Components with search inputs now properly propagate focus state for cursor positioning. ([#827](https://github.com/badlogic/pi-mono/issues/827))
19
+ - Fixed extension shortcut conflicts to respect user keybindings when built-in actions are remapped. ([#826](https://github.com/badlogic/pi-mono/pull/826) by [@richardgill](https://github.com/richardgill))
20
+ - Fixed photon WASM loading in standalone compiled binaries.
21
+ - Fixed tool call ID normalization for cross-provider handoffs (e.g., Codex to Antigravity Claude) ([#821](https://github.com/badlogic/pi-mono/issues/821))
22
+
23
+ ## [0.49.0] - 2026-01-17
24
+
25
+ ### Added
26
+
27
+ - `pi.setLabel(entryId, label)` in ExtensionAPI for setting per-entry labels from extensions ([#806](https://github.com/badlogic/pi-mono/issues/806))
28
+ - Export `keyHint`, `appKeyHint`, `editorKey`, `appKey`, `rawKeyHint` for extensions to format keybinding hints consistently ([#802](https://github.com/badlogic/pi-mono/pull/802) by [@dannote](https://github.com/dannote))
29
+ - Exported `VERSION` from the package index and updated the custom-header example. ([#798](https://github.com/badlogic/pi-mono/pull/798) by [@tallshort](https://github.com/tallshort))
30
+ - Added `showHardwareCursor` setting to control cursor visibility while still positioning it for IME support. ([#800](https://github.com/badlogic/pi-mono/pull/800) by [@ghoulr](https://github.com/ghoulr))
31
+ - Added Emacs-style kill ring editing with yank and yank-pop keybindings, plus legacy Alt+letter handling and Alt+D delete word forward support in the interactive editor. ([#810](https://github.com/badlogic/pi-mono/pull/810) by [@Perlence](https://github.com/Perlence))
32
+ - Added `ctx.compact()` and `ctx.getContextUsage()` to extension contexts for programmatic compaction and context usage checks.
33
+ - Added documentation for delete word forward and kill ring keybindings in interactive mode. ([#810](https://github.com/badlogic/pi-mono/pull/810) by [@Perlence](https://github.com/Perlence))
34
+
35
+ ### Changed
36
+
37
+ - Updated the default system prompt wording to clarify the pi harness and documentation scope.
38
+ - Simplified Codex system prompt handling to use the default system prompt directly for Codex instructions.
39
+
40
+ ### Fixed
41
+
42
+ - Fixed photon module failing to load in ESM context with "require is not defined" error ([#795](https://github.com/badlogic/pi-mono/pull/795) by [@dannote](https://github.com/dannote))
43
+ - Fixed compaction UI not showing when extensions trigger compaction.
44
+ - Fixed orphaned tool results after errored assistant messages causing Codex API errors. When an assistant message has `stopReason: "error"`, its tool calls are now excluded from pending tool tracking, preventing synthetic tool results from being generated for calls that will be dropped by provider-specific converters. ([#812](https://github.com/badlogic/pi-mono/issues/812))
45
+ - Fixed Bedrock Claude max_tokens handling to always exceed thinking budget tokens, preventing compaction failures. ([#797](https://github.com/badlogic/pi-mono/pull/797) by [@pjtf93](https://github.com/pjtf93))
46
+ - Fixed Claude Code tool name normalization to match the Claude Code tool list case-insensitively and remove invalid mappings.
47
+
48
+ ### Removed
49
+
50
+ - Removed `pi-internal://` path resolution from the read tool.
51
+
3
52
  ## [0.48.0] - 2026-01-16
4
53
 
5
54
  ### Added
package/README.md CHANGED
@@ -11,7 +11,7 @@
11
11
 
12
12
  A terminal-based coding agent with multi-model support, mid-session model switching, and a simple CLI for headless coding tasks.
13
13
 
14
- Works on Linux, macOS, and Windows (requires bash; see [Windows Setup](#windows-setup)).
14
+ Works on Linux, macOS, and Windows (requires bash; see [Windows Setup](#windows-setup)). [Separately maintained port](https://github.com/VaclavSynacek/pi-coding-agent-termux) works on Termux/Android.
15
15
 
16
16
  ## Table of Contents
17
17
 
@@ -350,8 +350,12 @@ Both modes are configurable via `/settings`: "one-at-a-time" delivers messages o
350
350
  | Enter | Send message |
351
351
  | Shift+Enter | New line (Ctrl+Enter on Windows Terminal) |
352
352
  | Ctrl+W / Option+Backspace | Delete word backwards |
353
+ | Alt+D | Delete word forwards |
353
354
  | Ctrl+U | Delete to start of line |
354
355
  | Ctrl+K | Delete to end of line |
356
+ | Ctrl+Y | Paste most recently deleted text |
357
+ | Alt+Y | Cycle through deleted text after pasting |
358
+ | Ctrl+- | Undo |
355
359
 
356
360
  **Other:**
357
361
 
@@ -397,8 +401,12 @@ All keyboard shortcuts can be customized via `~/.pi/agent/keybindings.json`. Eac
397
401
  | `deleteCharBackward` | `backspace` | Delete char backward |
398
402
  | `deleteCharForward` | `delete` | Delete char forward |
399
403
  | `deleteWordBackward` | `ctrl+w`, `alt+backspace` | Delete word backward |
404
+ | `deleteWordForward` | `alt+d` | Delete word forward |
400
405
  | `deleteToLineStart` | `ctrl+u` | Delete to line start |
401
406
  | `deleteToLineEnd` | `ctrl+k` | Delete to line end |
407
+ | `yank` | `ctrl+y` | Paste most recently deleted text |
408
+ | `yankPop` | `alt+y` | Cycle through deleted text after pasting |
409
+ | `undo` | `ctrl+-` | Undo last edit |
402
410
  | `newLine` | `shift+enter` | Insert new line |
403
411
  | `submit` | `enter` | Submit input |
404
412
  | `tab` | `tab` | Tab/autocomplete |
@@ -535,6 +543,10 @@ pi --session /path/to/file.jsonl # Use specific session file
535
543
  pi --session a8ec1c2a # Resume by session ID (partial UUID)
536
544
  ```
537
545
 
546
+ In the `/resume` picker:
547
+ - `Ctrl+P` toggles display of the session `.jsonl` file path
548
+ - `Ctrl+D` deletes the selected session (inline confirmation; uses `trash` if available and cannot delete the active session)
549
+
538
550
  **Resuming by session ID:** The `--session` flag accepts a session UUID (or prefix). Session IDs are visible in filenames under `~/.pi/agent/sessions/<project>/` (e.g., `2025-12-13T17-47-46-817Z_a8ec1c2a-5a5f-4699-88cb-03e7d3cb9292.jsonl`). The UUID is the part after the underscore. You can also search by session ID in the `pi -r` picker.
539
551
 
540
552
  ### Context Compaction
@@ -668,7 +680,10 @@ Add custom models (Ollama, vLLM, LM Studio, etc.) via `~/.pi/agent/models.json`:
668
680
 
669
681
  **Supported APIs:** `openai-completions`, `openai-responses`, `openai-codex-responses`, `anthropic-messages`, `google-generative-ai`
670
682
 
671
- **API key resolution:** The `apiKey` field is checked as environment variable name first, then used as literal value.
683
+ **API key resolution:** The `apiKey` field supports three formats:
684
+ - `"!command"` - Executes the command and uses stdout (e.g., `"!security find-generic-password -ws 'anthropic'"` for macOS Keychain, `"!op read 'op://vault/item/credential'"` for 1Password)
685
+ - Environment variable name (e.g., `"MY_API_KEY"`) - Uses the value of the environment variable
686
+ - Literal value - Used directly as the API key
672
687
 
673
688
  **API override:** Set `api` at provider level (default for all models) or model level (override per model).
674
689
 
@@ -726,6 +741,8 @@ To fully replace a built-in provider with custom models, include the `models` ar
726
741
 
727
742
  **OpenAI compatibility (`compat` field):**
728
743
 
744
+ **OpenAI Completions (`openai-completions`):**
745
+
729
746
  | Field | Description |
730
747
  |-------|-------------|
731
748
  | `supportsStore` | Whether provider supports `store` field |
@@ -734,6 +751,14 @@ To fully replace a built-in provider with custom models, include the `models` ar
734
751
  | `supportsUsageInStreaming` | Whether provider supports `stream_options: { include_usage: true }`. Default: `true` |
735
752
  | `maxTokensField` | Use `max_completion_tokens` or `max_tokens` |
736
753
 
754
+ **OpenAI Responses (`openai-responses`):**
755
+
756
+ | Field | Description |
757
+ |-------|-------------|
758
+ | `strictResponsesPairing` | Enforce strict reasoning/message pairing when replaying OpenAI Responses history on providers like Azure (default: `false`) |
759
+
760
+ If you see 400 errors like "item of type 'reasoning' was provided without its required following item" or "message/function_call was provided without its required reasoning item", set `compat.strictResponsesPairing: true` on the affected model in `models.json`.
761
+
737
762
  **Live reload:** The file reloads each time you open `/model`. Edit during session; no restart needed.
738
763
 
739
764
  **Model selection priority:**
@@ -789,6 +814,7 @@ Global `~/.pi/agent/settings.json` stores persistent preferences:
789
814
  "autoResize": true,
790
815
  "blockImages": false
791
816
  },
817
+ "showHardwareCursor": false,
792
818
  "extensions": ["/path/to/extension.ts"]
793
819
  }
794
820
  ```
@@ -816,6 +842,7 @@ Global `~/.pi/agent/settings.json` stores persistent preferences:
816
842
  | `terminal.showImages` | Render images inline (supported terminals) | `true` |
817
843
  | `images.autoResize` | Auto-resize images to 2000x2000 max for better model compatibility | `true` |
818
844
  | `images.blockImages` | Prevent images from being sent to LLM providers | `false` |
845
+ | `showHardwareCursor` | Show terminal cursor while still positioning it for IME support | `false` |
819
846
  | `doubleEscapeAction` | Action for double-escape with empty editor: `tree` or `branch` | `tree` |
820
847
  | `editorPaddingX` | Horizontal padding for input editor (0-3) | `0` |
821
848
  | `extensions` | Additional extension file paths | `[]` |
@@ -16,7 +16,7 @@ import type { Agent, AgentEvent, AgentMessage, AgentState, AgentTool, ThinkingLe
16
16
  import type { ImageContent, Model, TextContent } from "@mariozechner/pi-ai";
17
17
  import { type BashResult } from "./bash-executor.js";
18
18
  import { type CompactionResult } from "./compaction/index.js";
19
- import type { ExtensionRunner, InputSource } from "./extensions/index.js";
19
+ import type { ContextUsage, ExtensionRunner, InputSource } from "./extensions/index.js";
20
20
  import type { CustomMessage } from "./messages.js";
21
21
  import type { ModelRegistry } from "./model-registry.js";
22
22
  import { type PromptTemplate } from "./prompt-templates.js";
@@ -512,6 +512,7 @@ export declare class AgentSession {
512
512
  * Get session statistics.
513
513
  */
514
514
  getSessionStats(): SessionStats;
515
+ getContextUsage(): ContextUsage | undefined;
515
516
  /**
516
517
  * Export session to HTML.
517
518
  * @param outputPath Optional output path (defaults to session directory)