@selesai/code 0.13.8 → 0.13.10

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 (52) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/core/agent-session.d.ts +6 -0
  3. package/dist/core/agent-session.js +5 -3
  4. package/dist/core/settings-manager.d.ts +11 -0
  5. package/dist/core/settings-manager.js +48 -0
  6. package/dist/extensions/auto-session-name.test.ts +13 -1
  7. package/dist/extensions/auto-session-name.ts +8 -4
  8. package/dist/extensions/handoff-new.test.ts +26 -1
  9. package/dist/extensions/handoff-new.ts +5 -0
  10. package/dist/extensions/pi-subagents/README.md +0 -6
  11. package/dist/extensions/pi-subagents/docs/agents.md +1 -114
  12. package/dist/extensions/pi-subagents/src/agents/builtin-names.ts +1 -12
  13. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +1 -1
  14. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +3 -19
  15. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-contract.ts +8 -37
  16. package/dist/extensions/pi-subagents/src/shared/types.ts +2 -2
  17. package/dist/extensions/pi-subagents/src/workflows/workflow-receipt.ts +2 -38
  18. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +0 -49
  19. package/dist/extensions/pi-subagents/test/unit/runtime-agent-registration.test.ts +0 -18
  20. package/dist/modes/rpc/rpc-client.d.ts +180 -10
  21. package/dist/modes/rpc/rpc-client.js +211 -13
  22. package/dist/modes/rpc/rpc-mode.d.ts +1 -1
  23. package/dist/modes/rpc/rpc-mode.js +682 -3
  24. package/dist/modes/rpc/rpc-types.d.ts +340 -2
  25. package/dist/skills/improve-codebase/SKILL.md +1 -1
  26. package/dist/skills/planger/SKILL.md +1 -1
  27. package/dist/skills/workflow/SKILL.md +9 -15
  28. package/docs/rpc.md +171 -1
  29. package/package.json +1 -1
  30. package/dist/extensions/pi-subagents/agents/architect.md +0 -170
  31. package/dist/extensions/pi-subagents/agents/builder.md +0 -37
  32. package/dist/extensions/pi-subagents/agents/claude-code-writer.md +0 -15
  33. package/dist/extensions/pi-subagents/agents/claude-code.md +0 -15
  34. package/dist/extensions/pi-subagents/agents/codex-exec-writer.md +0 -15
  35. package/dist/extensions/pi-subagents/agents/codex-exec.md +0 -15
  36. package/dist/extensions/pi-subagents/agents/commentator.md +0 -37
  37. package/dist/extensions/pi-subagents/agents/cursor-agent-writer.md +0 -14
  38. package/dist/extensions/pi-subagents/agents/cursor-agent.md +0 -14
  39. package/dist/extensions/pi-subagents/agents/explorer.md +0 -32
  40. package/dist/extensions/pi-subagents/agents/recapper.md +0 -31
  41. package/dist/extensions/pi-subagents/src/runs/shared/claude-code-adapter.ts +0 -129
  42. package/dist/extensions/pi-subagents/src/runs/shared/codex-exec-adapter.ts +0 -129
  43. package/dist/extensions/pi-subagents/src/runs/shared/cursor-agent-adapter.ts +0 -114
  44. package/dist/extensions/pi-subagents/test/integration/claude-code-smoke.test.ts +0 -52
  45. package/dist/extensions/pi-subagents/test/integration/claude-code-writer-smoke.test.ts +0 -55
  46. package/dist/extensions/pi-subagents/test/integration/codex-exec-smoke.test.ts +0 -53
  47. package/dist/extensions/pi-subagents/test/integration/codex-exec-writer-smoke.test.ts +0 -57
  48. package/dist/extensions/pi-subagents/test/integration/cursor-agent-smoke.test.ts +0 -59
  49. package/dist/extensions/pi-subagents/test/integration/cursor-agent-writer-smoke.test.ts +0 -62
  50. package/dist/extensions/pi-subagents/test/unit/claude-code-adapter.test.ts +0 -245
  51. package/dist/extensions/pi-subagents/test/unit/codex-exec-adapter.test.ts +0 -192
  52. package/dist/extensions/pi-subagents/test/unit/cursor-agent-adapter.test.ts +0 -259
@@ -7,16 +7,21 @@
7
7
  import type { AgentMessage, ThinkingLevel } from "@earendil-works/pi-agent-core";
8
8
  import type { ImageContent, Model } from "@earendil-works/pi-ai";
9
9
  import type { SessionStats } from "../../core/agent-session.ts";
10
+ import type { KeybindingsConfig } from "../../core/keybindings.ts";
11
+ import type { Settings, SettingsScope } from "../../core/settings-manager.ts";
10
12
  import type { BashResult } from "../../core/bash-executor.ts";
11
13
  import type { CompactionResult } from "../../core/compaction/index.ts";
12
- import type { SessionEntry, SessionTreeNode } from "../../core/session-manager.ts";
14
+ import type { BranchSummaryEntry, SessionEntry, SessionTreeNode } from "../../core/session-manager.ts";
13
15
  import type { SourceInfo } from "../../core/source-info.ts";
16
+ import type { ChangelogEntry } from "../../utils/changelog.ts";
14
17
  export type RpcCommand = {
15
18
  id?: string;
16
19
  type: "prompt";
17
20
  message: string;
18
21
  images?: ImageContent[];
19
22
  streamingBehavior?: "steer" | "followUp";
23
+ /** Buffer the prompt during compaction and auto-send it after compaction_end (mirrors TUI compaction queue). */
24
+ queueWhileCompacting?: boolean;
20
25
  } | {
21
26
  id?: string;
22
27
  type: "steer";
@@ -52,9 +57,11 @@ export type RpcCommand = {
52
57
  } | {
53
58
  id?: string;
54
59
  type: "cycle_model";
60
+ direction?: "forward" | "backward";
55
61
  } | {
56
62
  id?: string;
57
63
  type: "get_available_models";
64
+ refresh?: boolean;
58
65
  } | {
59
66
  id?: string;
60
67
  type: "set_thinking_level";
@@ -116,6 +123,7 @@ export type RpcCommand = {
116
123
  id?: string;
117
124
  type: "export_html";
118
125
  outputPath?: string;
126
+ themeName?: string;
119
127
  } | {
120
128
  id?: string;
121
129
  type: "switch_session";
@@ -137,6 +145,7 @@ export type RpcCommand = {
137
145
  } | {
138
146
  id?: string;
139
147
  type: "get_tree";
148
+ filter?: "default" | "no-tools" | "user-only" | "labeled-only" | "all";
140
149
  } | {
141
150
  id?: string;
142
151
  type: "get_last_assistant_text";
@@ -144,6 +153,104 @@ export type RpcCommand = {
144
153
  id?: string;
145
154
  type: "set_session_name";
146
155
  name: string;
156
+ } | {
157
+ id?: string;
158
+ type: "get_settings";
159
+ scope?: "global" | "project" | "effective";
160
+ } | {
161
+ id?: string;
162
+ type: "set_settings";
163
+ scope?: SettingsScope;
164
+ values: Partial<Settings>;
165
+ } | {
166
+ id?: string;
167
+ type: "factory_reset_settings";
168
+ } | {
169
+ id?: string;
170
+ type: "get_auth_providers";
171
+ } | {
172
+ id?: string;
173
+ type: "login";
174
+ providerId: string;
175
+ authType: "oauth" | "api_key";
176
+ } | {
177
+ id?: string;
178
+ type: "logout";
179
+ providerId: string;
180
+ } | {
181
+ id?: string;
182
+ type: "get_auth_state";
183
+ } | {
184
+ id?: string;
185
+ type: "get_scoped_models";
186
+ } | {
187
+ id?: string;
188
+ type: "set_scoped_models";
189
+ enabled?: string[];
190
+ reorder?: string[];
191
+ } | {
192
+ id?: string;
193
+ type: "import_jsonl";
194
+ path: string;
195
+ } | {
196
+ id?: string;
197
+ type: "navigate_tree";
198
+ targetId: string;
199
+ summarize?: boolean;
200
+ customInstructions?: string;
201
+ replaceInstructions?: boolean;
202
+ label?: string;
203
+ } | {
204
+ id?: string;
205
+ type: "list_sessions";
206
+ scope?: "current" | "all";
207
+ } | {
208
+ id?: string;
209
+ type: "rename_session";
210
+ path: string;
211
+ name: string;
212
+ } | {
213
+ id?: string;
214
+ type: "delete_session";
215
+ path: string;
216
+ } | {
217
+ id?: string;
218
+ type: "set_session_models";
219
+ enabled?: string[];
220
+ reorder?: string[];
221
+ } | {
222
+ id?: string;
223
+ type: "git";
224
+ command: string;
225
+ } | {
226
+ id?: string;
227
+ type: "reload";
228
+ } | {
229
+ id?: string;
230
+ type: "set_entry_label";
231
+ entryId: string;
232
+ label?: string;
233
+ } | {
234
+ id?: string;
235
+ type: "get_trust";
236
+ } | {
237
+ id?: string;
238
+ type: "set_trust";
239
+ decision: boolean | null;
240
+ } | {
241
+ id?: string;
242
+ type: "get_hotkeys";
243
+ } | {
244
+ id?: string;
245
+ type: "get_available_themes";
246
+ } | {
247
+ id?: string;
248
+ type: "get_version_info";
249
+ } | {
250
+ id?: string;
251
+ type: "share_gist";
252
+ public?: boolean;
253
+ themeName?: string;
147
254
  } | {
148
255
  id?: string;
149
256
  type: "get_messages";
@@ -158,9 +265,23 @@ export interface RpcSlashCommand {
158
265
  /** Human-readable description */
159
266
  description?: string;
160
267
  /** What kind of command this is */
161
- source: "extension" | "prompt" | "skill";
268
+ source: "extension" | "prompt" | "skill" | "builtin";
162
269
  /** Source metadata for the owning resource */
163
270
  sourceInfo: SourceInfo;
271
+ /** True for interactive-TUI-only builtins that cannot be invoked via prompt */
272
+ interactiveOnly?: boolean;
273
+ }
274
+ /** Session listing entry (SessionInfo with transcript text stripped). */
275
+ export interface RpcSessionInfo {
276
+ path: string;
277
+ id: string;
278
+ cwd: string;
279
+ name?: string;
280
+ parentSessionPath?: string;
281
+ created: string;
282
+ modified: string;
283
+ messageCount: number;
284
+ firstMessage: string;
164
285
  }
165
286
  export interface RpcSessionState {
166
287
  model?: Model<any>;
@@ -434,6 +555,221 @@ export type RpcResponse = {
434
555
  data: {
435
556
  commands: RpcSlashCommand[];
436
557
  };
558
+ } | {
559
+ id?: string;
560
+ type: "response";
561
+ command: "get_settings";
562
+ success: true;
563
+ data: {
564
+ scope: "global" | "project" | "effective";
565
+ settings: Settings;
566
+ };
567
+ } | {
568
+ id?: string;
569
+ type: "response";
570
+ command: "set_settings";
571
+ success: true;
572
+ data: {
573
+ scope: SettingsScope;
574
+ values: Partial<Settings>;
575
+ };
576
+ } | {
577
+ id?: string;
578
+ type: "response";
579
+ command: "factory_reset_settings";
580
+ success: true;
581
+ } | {
582
+ id?: string;
583
+ type: "response";
584
+ command: "get_auth_providers";
585
+ success: true;
586
+ data: {
587
+ providers: Array<{
588
+ providerId: string;
589
+ name: string;
590
+ authTypes: Array<"oauth" | "api_key">;
591
+ }>;
592
+ };
593
+ } | {
594
+ id?: string;
595
+ type: "response";
596
+ command: "login";
597
+ success: true;
598
+ data: {
599
+ providerId: string;
600
+ authType: "oauth" | "api_key";
601
+ message: string;
602
+ };
603
+ } | {
604
+ id?: string;
605
+ type: "response";
606
+ command: "logout";
607
+ success: true;
608
+ data: {
609
+ providerId: string;
610
+ };
611
+ } | {
612
+ id?: string;
613
+ type: "response";
614
+ command: "get_auth_state";
615
+ success: true;
616
+ data: {
617
+ providers: Array<{
618
+ providerId: string;
619
+ authType: "oauth" | "api_key";
620
+ source: string;
621
+ }>;
622
+ };
623
+ } | {
624
+ id?: string;
625
+ type: "response";
626
+ command: "get_scoped_models";
627
+ success: true;
628
+ data: {
629
+ enabled: string[];
630
+ models: Model<any>[];
631
+ };
632
+ } | {
633
+ id?: string;
634
+ type: "response";
635
+ command: "set_scoped_models";
636
+ success: true;
637
+ data: {
638
+ enabled: string[];
639
+ };
640
+ } | {
641
+ id?: string;
642
+ type: "response";
643
+ command: "import_jsonl";
644
+ success: true;
645
+ data: {
646
+ sessionPath: string;
647
+ };
648
+ } | {
649
+ id?: string;
650
+ type: "response";
651
+ command: "navigate_tree";
652
+ success: true;
653
+ data: {
654
+ editorText?: string;
655
+ cancelled: boolean;
656
+ aborted?: boolean;
657
+ summaryEntry?: BranchSummaryEntry | null;
658
+ };
659
+ } | {
660
+ id?: string;
661
+ type: "response";
662
+ command: "list_sessions";
663
+ success: true;
664
+ data: {
665
+ sessions: RpcSessionInfo[];
666
+ };
667
+ } | {
668
+ id?: string;
669
+ type: "response";
670
+ command: "rename_session";
671
+ success: true;
672
+ data: {
673
+ path: string;
674
+ name: string;
675
+ };
676
+ } | {
677
+ id?: string;
678
+ type: "response";
679
+ command: "delete_session";
680
+ success: true;
681
+ data: {
682
+ path: string;
683
+ method: "trash" | "unlink";
684
+ };
685
+ } | {
686
+ id?: string;
687
+ type: "response";
688
+ command: "set_session_models";
689
+ success: true;
690
+ data: {
691
+ enabled: string[];
692
+ models: Model<any>[];
693
+ };
694
+ } | {
695
+ id?: string;
696
+ type: "response";
697
+ command: "git";
698
+ success: true;
699
+ } | {
700
+ id?: string;
701
+ type: "response";
702
+ command: "reload";
703
+ success: true;
704
+ } | {
705
+ id?: string;
706
+ type: "response";
707
+ command: "set_entry_label";
708
+ success: true;
709
+ data: {
710
+ labelId: string;
711
+ };
712
+ } | {
713
+ id?: string;
714
+ type: "response";
715
+ command: "get_trust";
716
+ success: true;
717
+ data: {
718
+ cwd: string;
719
+ savedDecision: {
720
+ path: string;
721
+ decision: boolean;
722
+ } | null;
723
+ projectTrusted: boolean;
724
+ trustRequired: boolean;
725
+ };
726
+ } | {
727
+ id?: string;
728
+ type: "response";
729
+ command: "set_trust";
730
+ success: true;
731
+ data: {
732
+ decision: boolean | null;
733
+ restartRequired: boolean;
734
+ };
735
+ } | {
736
+ id?: string;
737
+ type: "response";
738
+ command: "get_hotkeys";
739
+ success: true;
740
+ data: {
741
+ hotkeys: KeybindingsConfig;
742
+ };
743
+ } | {
744
+ id?: string;
745
+ type: "response";
746
+ command: "get_available_themes";
747
+ success: true;
748
+ data: {
749
+ themes: Array<{
750
+ name: string;
751
+ path?: string;
752
+ }>;
753
+ current: string | undefined;
754
+ };
755
+ } | {
756
+ id?: string;
757
+ type: "response";
758
+ command: "get_version_info";
759
+ success: true;
760
+ data: {
761
+ version: string;
762
+ changelog: ChangelogEntry[];
763
+ };
764
+ } | {
765
+ id?: string;
766
+ type: "response";
767
+ command: "share_gist";
768
+ success: true;
769
+ data: {
770
+ url: string;
771
+ gistUrl: string;
772
+ };
437
773
  } | {
438
774
  id?: string;
439
775
  type: "response";
@@ -469,6 +805,8 @@ export type RpcExtensionUIRequest = {
469
805
  method: "input";
470
806
  title: string;
471
807
  placeholder?: string;
808
+ /** "secret": render as single-line password (e.g. API key entry). Defaults to "text". */
809
+ inputKind?: "text" | "secret";
472
810
  timeout?: number;
473
811
  } | {
474
812
  type: "extension_ui_request";
@@ -29,7 +29,7 @@ Your goal:
29
29
 
30
30
  ### 1. Explore the context
31
31
 
32
- Call the subagent tool with `{ agent: "explorer", task: "..." }` (do not pass a model) when possible.
32
+ Call the subagent tool with `{ agent: "scout", task: "..." }` (do not pass a model) when possible.
33
33
 
34
34
  If the context is partial:
35
35
  - Infer surrounding architecture cautiously
@@ -52,7 +52,7 @@ Choose the lowest-complexity solution that works.
52
52
 
53
53
  ## Reuse Before Build
54
54
 
55
- Before creating anything new (use explorer agent):
55
+ Before creating anything new (use scout agent):
56
56
 
57
57
  - Search for existing implementations
58
58
  - Search for existing utilities
@@ -22,12 +22,11 @@ Read `../pi-subagents/SKILL.md` and its references to pick builtin/custom agents
22
22
 
23
23
  | Subtask | Agent |
24
24
  | --- | --- |
25
- | Codebase recon / find seams | `scout` or `explorer` |
25
+ | Codebase recon / find seams | `scout` |
26
26
  | External/uncertain research | `researcher` |
27
- | Implementation planning | `architect` |
28
- | Scoped implementation | `worker` or `builder` |
29
- | Independent review | `reviewer` or `commentator` |
30
- | Parent-synthesized fixes | `worker` |
27
+ | Scoped implementation | `worker` or `delegate` |
28
+ | Independent review | `reviewer` |
29
+ | Material architecture/product tradeoffs | `oracle` or Council Mode |
31
30
 
32
31
  For material architecture/product tradeoffs, resolve them first with an `oracle` or Council Mode before implementation.
33
32
 
@@ -52,21 +51,16 @@ const scout = await runs.run("scout", {
52
51
  agent: "scout",
53
52
  task: "Find the code seams, existing helpers, and constraints involved. Do not edit."
54
53
  });
55
- const plan = await runs.run("plan", {
56
- agent: "architect",
57
- reads: [scout.outputReference],
58
- task: "Plan the change from the scout findings. Return files, order, checks, non-goals."
59
- });
60
54
  const worker = await runs.run("implement", {
61
55
  agent: "worker",
62
- reads: [plan.outputReference],
63
- task: "Implement the approved plan. Return changed files, checks run, residual risks, decisions needing approval."
56
+ reads: [scout.outputReference],
57
+ task: "Implement the requested change from the scout findings. Return changed files, checks run, residual risks, decisions needing approval."
64
58
  });
65
59
  const reviews = await runs.all([
66
- { key: "correctness", agent: "reviewer", reads: [plan.outputReference, worker.outputReference], task: "Inspect the current diff for correctness and regressions. Do not edit." },
67
- { key: "simplicity", agent: "reviewer", reads: [plan.outputReference, worker.outputReference], task: "Inspect the current diff for unnecessary complexity. Do not edit." }
60
+ { key: "correctness", agent: "reviewer", reads: [scout.outputReference, worker.outputReference], task: "Inspect the current diff for correctness and regressions. Do not edit." },
61
+ { key: "simplicity", agent: "reviewer", reads: [scout.outputReference, worker.outputReference], task: "Inspect the current diff for unnecessary complexity. Do not edit." }
68
62
  ]);
69
- return { plan: plan.outputReference, worker: worker.outputReference, reviews: reviews.map((result) => result.outputReference) };
63
+ return { worker: worker.outputReference, reviews: reviews.map((result) => result.outputReference) };
70
64
  ```
71
65
 
72
66
  ### Parallel independent subtasks
package/docs/rpc.md CHANGED
@@ -64,6 +64,14 @@ With images:
64
64
 
65
65
  If the agent is streaming and no `streamingBehavior` is specified, the command returns an error.
66
66
 
67
+ **During compaction**: If the agent is compacting, the command is rejected unless `queueWhileCompacting` is set:
68
+
69
+ ```json
70
+ {"type": "prompt", "message": "Follow-up", "queueWhileCompacting": true}
71
+ ```
72
+
73
+ With `queueWhileCompacting: true` the prompt is accepted into a buffer (`success: true` is returned immediately) and auto-replayed in order after `compaction_end`. If compaction aborts or errors, the buffer is discarded.
74
+
67
75
  **Extension commands**: If the message is an extension command (e.g., `/mycommand`), it executes immediately even during streaming. Extension commands manage their own LLM interaction via `pi.sendMessage()`.
68
76
 
69
77
  **Input expansion**: Skill commands (`/skill:name`) and prompt templates (`/template`) are expanded before sending/queueing.
@@ -240,6 +248,14 @@ Cycle to the next available model. Returns `null` data if only one model availab
240
248
  {"type": "cycle_model"}
241
249
  ```
242
250
 
251
+ Optional `direction` (defaults to `"forward"`):
252
+
253
+ ```json
254
+ {"type": "cycle_model", "direction": "backward"}
255
+ ```
256
+
257
+ `direction` is `"forward"` or `"backward"`.
258
+
243
259
  Response:
244
260
  ```json
245
261
  {
@@ -264,6 +280,12 @@ List all configured models.
264
280
  {"type": "get_available_models"}
265
281
  ```
266
282
 
283
+ Optional `refresh` flag (TUI parity) re-fetches model catalogs before listing; a small timeout applies and the current snapshot is used if the network refresh fails:
284
+
285
+ ```json
286
+ {"type": "get_available_models", "refresh": true}
287
+ ```
288
+
267
289
  Response contains an array of full [Model](#model) objects:
268
290
  ```json
269
291
  {
@@ -556,6 +578,11 @@ With custom path:
556
578
  {"type": "export_html", "outputPath": "/tmp/session.html"}
557
579
  ```
558
580
 
581
+ Optional `themeName` selects the export theme (otherwise the current theme is used):
582
+ ```json
583
+ {"type": "export_html", "outputPath": "/tmp/session.html", "themeName": "dark"}
584
+ ```
585
+
559
586
  Response:
560
587
  ```json
561
588
  {
@@ -702,6 +729,134 @@ Response:
702
729
 
703
730
  The current session name is available via `get_state` in the `sessionName` field. To set the initial name when starting RPC mode, pass `--name <name>` or `-n <name>` to the `pi --mode rpc` process.
704
731
 
732
+ #### navigate_tree
733
+
734
+ Navigate the session tree to a different entry (the TUI tree selector equivalent). Rejects while the agent is streaming; emits a `session_tree` event on success.
735
+
736
+ ```json
737
+ {"type": "navigate_tree", "targetId": "abc123"}
738
+ ```
739
+
740
+ Optional fields:
741
+ - `summarize`: summarize the branch between the old leaf and the target before navigating.
742
+ - `customInstructions`: custom summary instructions (with `summarize`).
743
+ - `replaceInstructions`: replace (rather than append to) the default summary instructions.
744
+ - `label`: attach the given label to the target entry.
745
+
746
+ Response:
747
+ ```json
748
+ {
749
+ "type": "response",
750
+ "command": "navigate_tree",
751
+ "success": true,
752
+ "data": {
753
+ "editorText": "...",
754
+ "cancelled": false,
755
+ "aborted": false,
756
+ "summaryEntry": null
757
+ }
758
+ }
759
+ ```
760
+
761
+ `editorText` is present when the target is a user message (it becomes the editor prefill). `aborted` is set when a `session_before_navigate`-style extension handler cancels the navigation. Fails with `Entry <id> not found` for unknown targets and `No model available for summarization` when `summarize` is requested but no model is configured.
762
+
763
+ #### list_sessions
764
+
765
+ List sessions. `scope` defaults to `"current"` (sessions in the current cwd/session dir); `"all"` searches the full session store.
766
+
767
+ ```json
768
+ {"type": "list_sessions"}
769
+ {"type": "list_sessions", "scope": "all"}
770
+ ```
771
+
772
+ Response:
773
+ ```json
774
+ {
775
+ "type": "response",
776
+ "command": "list_sessions",
777
+ "success": true,
778
+ "data": {
779
+ "sessions": [
780
+ {
781
+ "path": "/path/to/session.jsonl",
782
+ "id": "abc123",
783
+ "cwd": "/path/to/project",
784
+ "name": "my-feature-work",
785
+ "parentSessionPath": null,
786
+ "created": "2026-09-01T00:00:00.000Z",
787
+ "modified": "2026-09-01T01:00:00.000Z",
788
+ "messageCount": 42,
789
+ "firstMessage": "First user prompt..."
790
+ }
791
+ ]
792
+ }
793
+ }
794
+ ```
795
+
796
+ `name` is omitted when unset. `created`/`modified` are ISO strings; sessions with invalid timestamps (e.g. hand-written JSONL) are reported as epoch (`1970-01-01T00:00:00.000Z`).
797
+
798
+ #### rename_session
799
+
800
+ Rename a session by writing the name into its JSONL header. The file must exist; an empty name is rejected.
801
+
802
+ ```json
803
+ {"type": "rename_session", "path": "/path/to/session.jsonl", "name": "my-feature-work"}
804
+ ```
805
+
806
+ Response: `{"command": "rename_session", "success": true, "data": {"path": "/path/to/session.jsonl", "name": "my-feature-work"}}`
807
+
808
+ #### delete_session
809
+
810
+ Delete a session. Moves it to the operating system trash when available, else unlinks the file directly. Refuses to delete the currently active session.
811
+
812
+ ```json
813
+ {"type": "delete_session", "path": "/path/to/session.jsonl"}
814
+ ```
815
+
816
+ Response: `{"command": "delete_session", "success": true, "data": {"path": "/path/to/session.jsonl", "method": "trash"}}`
817
+
818
+ `method` is `"trash"` or `"unlink"`.
819
+
820
+ #### set_session_models
821
+
822
+ Scope the session to a subset of models (mirrors the TUI session-only model scoping). Ephemeral: never writes settings files and does not affect the persistent scoped-model configuration. Pass an empty array to clear the session scope.
823
+
824
+ ```json
825
+ {"type": "set_session_models", "enabled": ["anthropic/claude-sonnet-4-20250514", "anthropic/*"]}
826
+ ```
827
+
828
+ `enabled` entries are concrete `provider/id` identifiers or scope/wildcard patterns (e.g. `"anthropic/*"`). `reorder` (a reordered pattern list) rebuilds the scope without changing which models are enabled. At least one of the two must be present.
829
+
830
+ Response:
831
+ ```json
832
+ {
833
+ "type": "response",
834
+ "command": "set_session_models",
835
+ "success": true,
836
+ "data": {
837
+ "enabled": ["anthropic/claude-sonnet-4-20250514"],
838
+ "models": [{...}]
839
+ }
840
+ }
841
+ ```
842
+
843
+ `enabled` is the resolved list of `provider/id` strings; `models` is the matching array of [Model](#model) objects.
844
+
845
+ #### share_gist
846
+
847
+ Export the session to HTML and share it as a private GitHub gist (requires the GitHub CLI authenticated via `gh auth login`).
848
+
849
+ ```json
850
+ {"type": "share_gist"}
851
+ ```
852
+
853
+ Optional `themeName` selects the export theme:
854
+ ```json
855
+ {"type": "share_gist", "themeName": "dark"}
856
+ ```
857
+
858
+ Response: `{"command": "share_gist", "success": true, "data": {"url": "https://github.com/user/...", "gistUrl": "https://gist.github.com/..."}}`
859
+
705
860
  ### Commands
706
861
 
707
862
  #### get_commands
@@ -740,7 +895,7 @@ Each command has:
740
895
  - `"path"`: Explicit path via CLI or settings
741
896
  - `path`: Absolute file path to the command source (optional)
742
897
 
743
- **Note**: Built-in TUI commands (`/settings`, `/hotkeys`, etc.) are not included. They are handled only in interactive mode and would not execute if sent via `prompt`.
898
+ **Note**: Built-in TUI commands (`/settings`, `/hotkeys`, etc.) are included with `source: "builtin"` and `interactiveOnly: true`. They are display-only: they are handled only in interactive mode and would not execute if sent via `prompt`.
744
899
 
745
900
  ## Events
746
901
 
@@ -766,6 +921,7 @@ Events are streamed to stdout as JSON lines during agent operation. Events do no
766
921
  | `compaction_end` | Compaction completes |
767
922
  | `auto_retry_start` | Auto-retry begins (after transient error) |
768
923
  | `auto_retry_end` | Auto-retry completes (success or final failure) |
924
+ | `session_tree` | Session tree navigated (new leaf, old leaf, optional summary entry) |
769
925
  | `extension_error` | Extension threw an error |
770
926
 
771
927
  ### agent_start
@@ -957,6 +1113,20 @@ If compaction was aborted, `result` is `null` and `aborted` is `true`.
957
1113
 
958
1114
  If compaction failed (e.g., API quota exceeded), `result` is `null`, `aborted` is `false`, and `errorMessage` contains the error description.
959
1115
 
1116
+ ### session_tree
1117
+
1118
+ Emitted after a `navigate_tree` (or an extension-initiated tree navigation) moves the session to a new leaf. `oldLeafId`/`newLeafId` are the session tree leaves before and after the navigation; `summaryEntry` is present when the navigation summarized the branch. `fromExtension` is true when the navigation was initiated by an extension.
1119
+
1120
+ ```json
1121
+ {
1122
+ "type": "session_tree",
1123
+ "oldLeafId": "def456",
1124
+ "newLeafId": "abc123",
1125
+ "summaryEntry": null,
1126
+ "fromExtension": false
1127
+ }
1128
+ ```
1129
+
960
1130
  ### auto_retry_start / auto_retry_end
961
1131
 
962
1132
  Emitted when automatic retry is triggered after a transient error (overloaded, rate limit, 5xx).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@selesai/code",
3
- "version": "0.13.8",
3
+ "version": "0.13.10",
4
4
  "description": "Maintained, extension-first Pi coding agent with built-in workflows, subagents, web research, questions, skills, and an enhanced terminal UI.",
5
5
  "type": "module",
6
6
  "repository": {