@code-yeongyu/senpi 2026.10.10-3 → 2026.10.10-4
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.
- package/CHANGELOG.md +20 -0
- package/dist/bundle/chunks/{app-server-command-DVWM37GF.js → app-server-command-N3L2LNP7.js} +1 -1
- package/dist/bundle/chunks/{chunk-MT2C4I5R.js → chunk-MP2DMTI7.js} +38 -37
- package/dist/bundle/chunks/chunk-USRAHAW4.js +14 -0
- package/dist/bundle/chunks/{chunk-CTERKXVZ.js → chunk-ZSYRWQWG.js} +2 -2
- package/dist/bundle/chunks/{cli-main-B4S4DGBX.js → cli-main-CHDR33FZ.js} +1 -1
- package/dist/bundle/chunks/{interactive-mode-QOFA64JL.js → interactive-mode-RVEM62WX.js} +1 -1
- package/dist/bundle/chunks/{multi-session-host-E5RDPWQN.js → multi-session-host-CFND7CXH.js} +1 -1
- package/dist/bundle/chunks/{package-manager-cli-YGTWXRG5.js → package-manager-cli-NWNECBF7.js} +1 -1
- package/dist/bundle/chunks/{rpc-mode-HDAGQ4X3.js → rpc-mode-JQFUDLNB.js} +1 -1
- package/dist/bundle/chunks/session-control-endpoint-HMB5T5VD.js +3 -0
- package/dist/bundle/chunks/session-worker.js +53 -52
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/bundle/runtime-manifest.json +1 -1
- package/dist/core/extensions/session-control-types.d.ts +25 -0
- package/dist/core/extensions/session-control-types.js +16 -0
- package/dist/core/external-admission.js +7 -1
- package/dist/core/resource-loader.js +63 -2
- package/dist/core/session-rebind.js +16 -1
- package/dist/modes/interactive/components/extension-editor.js +4 -0
- package/dist/modes/interactive/components/remote-delivery-message.d.ts +6 -3
- package/dist/modes/interactive/components/remote-delivery-message.js +32 -3
- package/dist/modes/interactive/interactive-mode.d.ts +17 -0
- package/dist/modes/interactive/interactive-mode.js +58 -29
- package/dist/modes/interactive/interactive-stderr-guard.d.ts +8 -0
- package/dist/modes/interactive/interactive-stderr-guard.js +70 -0
- package/dist/modes/interactive/session-control-commands.d.ts +2 -1
- package/dist/modes/interactive/session-control-commands.js +21 -7
- package/dist/modes/interactive/session-control-session-commands.d.ts +22 -0
- package/dist/modes/interactive/session-control-session-commands.js +47 -0
- package/dist/modes/interactive/stdout-fd-redirect.d.ts +12 -0
- package/dist/modes/interactive/stdout-fd-redirect.js +114 -0
- package/dist/modes/rpc/connection-handler.js +6 -15
- package/dist/modes/rpc/rpc-types.d.ts +13 -0
- package/dist/modes/rpc/session-control-actions-data.d.ts +17 -0
- package/dist/modes/rpc/session-control-actions-data.js +38 -0
- package/docs/extensions.md +1 -1
- package/docs/rpc.md +38 -4
- package/package.json +6 -6
- package/dist/bundle/chunks/chunk-PDSG6VER.js +0 -14
- package/dist/bundle/chunks/session-control-endpoint-NABTZHCZ.js +0 -3
package/docs/extensions.md
CHANGED
|
@@ -1684,7 +1684,7 @@ runtime's steering or follow-up queue like the user's queued input. The protocol
|
|
|
1684
1684
|
|---|---|---|
|
|
1685
1685
|
| `registerControlEndpoint({ inboxDir, drain, isSessionReferenced? })` | `Promise<SessionControlRegistration>` | POSIX interactive session: binds the `tui` control endpoint and answers `{ status: "registered", socket, dispose }`. On a multi-session host with a public socket it binds nothing and `socket` is the host's. Otherwise `{ status: "unsupported", reason: "unsupported_platform" \| "unsupported_mode" }`, or `{ status: "failed", reason }` when a registration step failed. `drain(event)` runs on every [`session_control_wake`](#session_control_wake) edge and answers `{ admitted: [{ delivery_id, kind }] }`. `inboxDir` is created 0700 and its entry creations and deletions wake the drain. At clean exit a header-only session file is removed unless `isSessionReferenced()` answers `true`. |
|
|
1686
1686
|
| `admissionGate()` | `{ can_admit, hold_reason?, editor_revision, turn_epoch }` | Read-only pre-check; `hold_reason` is `draft` while the user composes or their submission is still on its way into the runtime. |
|
|
1687
|
-
| `admitExternalMessage({ delivery_id, text, deliverAs, expected_turn_id? })` | `{ kind, turn_epoch }` | Decides and acts in one synchronous call. `kind` is `started`, `queued`, `steered`, `turn_conflict` (stale epoch, or a steer without one), `held_draft` (nothing enqueued; retry on the next wake) or `already_admitted` (also for a delivery whose entry the file refused, until the run that refused it has settled and the file's last write succeeded). The delivery becomes a `custom` entry `session_control_delivery` whose `details.delivery_id` proves it was applied. Throws once a host started handing the session over (`release_session`). |
|
|
1687
|
+
| `admitExternalMessage({ delivery_id, text, deliverAs, expected_turn_id?, sender?, display_text? })` | `{ kind, turn_epoch }` | Decides and acts in one synchronous call. `kind` is `started`, `queued`, `steered`, `turn_conflict` (stale epoch, or a steer without one), `held_draft` (nothing enqueued; retry on the next wake) or `already_admitted` (also for a delivery whose entry the file refused, until the run that refused it has settled and the file's last write succeeded). The delivery becomes a `custom` entry `session_control_delivery` whose `details.delivery_id` proves it was applied. Throws once a host started handing the session over (`release_session`). `sender` (`{ kind: "agent", session_id, name? }`, `{ kind: "command_line", user? }` or `{ kind: "external", platform, author? }`) and `display_text` (the message as written) go to the entry's `details`: the terminal labels the message by its sender over `display_text`, while the model reads `text`. |
|
|
1688
1688
|
| `listAdmittedDeliveries()` | `{ pending, emitted, failed? }` | The process-lifetime ledger: `pending` is held by the runtime, `emitted` has its transcript entry written, `failed` (present only when non-empty, `[{ delivery_id, error }]`) had its entry refused by the session file: no longer held, still with its sender, admissible again once the run that refused it has settled and the file's last write succeeded. |
|
|
1689
1689
|
| `persistHeaderNow()` | `Promise<void>` | Writes the session header now, so the session id is durable before anything exposes it. |
|
|
1690
1690
|
|
package/docs/rpc.md
CHANGED
|
@@ -1147,10 +1147,11 @@ registrant opens no socket and writes no registry directory.
|
|
|
1147
1147
|
`endpoint_kind: "tui"`, `owner` and `alive`, probing it for at most 1.5 s. `senpi host gc` reaps a dead one on
|
|
1148
1148
|
the same evidence as a host. `ensure`, `handoff` and `stop` refuse it with `unsupported_endpoint_kind` (exit 3)
|
|
1149
1149
|
before connecting, because a terminal endpoint is owned by its terminal process.
|
|
1150
|
-
- **Commands.**
|
|
1151
|
-
|
|
1152
|
-
- `get_protocol_info`: `mode: "tui"`, `capabilities: ["tui_control"]`, `generation: 0
|
|
1153
|
-
`instanceId
|
|
1150
|
+
- **Commands.** Anything not listed below is answered `unsupported` as data. No command can prompt, steer, queue a
|
|
1151
|
+
follow-up, open a session or run a command.
|
|
1152
|
+
- `get_protocol_info`: `mode: "tui"`, `capabilities: ["tui_control"]`, `generation: 0`, the endpoint's
|
|
1153
|
+
`instanceId`, and `commands`: every command this endpoint accepts. A terminal from before the session
|
|
1154
|
+
controls below lists no `commands`.
|
|
1154
1155
|
- `list_sessions`: exactly one row, `kind: "interactive"`, `surface: "tui"`, `attachments: 1`.
|
|
1155
1156
|
- `get_state`: the RPC session state plus `turn_epoch`, `blocking_question`, `compacting`,
|
|
1156
1157
|
`editor_has_draft` and `state_version`.
|
|
@@ -1166,6 +1167,21 @@ registrant opens no socket and writes no registry directory.
|
|
|
1166
1167
|
question (a pending question id from the `question` feed); without it, `id` does. The answer settles by
|
|
1167
1168
|
the host's rule (see `question`) and the reply carries the frame's `id`, as on a host (see "Extension
|
|
1168
1169
|
UI Responses").
|
|
1170
|
+
- The session controls run the pane's own paths, so validation, the footer and persistence are the ones the
|
|
1171
|
+
user gets doing it in that terminal:
|
|
1172
|
+
- `get_available_models` and `get_available_thinking_levels`: the same answers as a host's.
|
|
1173
|
+
- `set_model { provider, modelId }`: the `/model` switch (the footer, the remembered default model, the
|
|
1174
|
+
pane's status line). An unknown model is refused `Model not found: <provider>/<modelId>`; a switch the
|
|
1175
|
+
session refuses answers its reason. Success answers the model, as on a host.
|
|
1176
|
+
- `set_thinking_level { level, scope? }`: the thinking-level selector. `scope: "turn"` sets this session's
|
|
1177
|
+
level; otherwise the level is also remembered for the model (the selector's Ctrl+S). A level the active
|
|
1178
|
+
model cannot run is refused `Thinking level <level> is not supported by the active model.` and nothing
|
|
1179
|
+
changes, for either scope. A host refuses it only for `scope: "turn"`; for the default scope a host clamps it
|
|
1180
|
+
to a level the model runs.
|
|
1181
|
+
- `interrupt { turnId? }`: Esc on a running turn - queued input returns to the editor, the turn aborts and
|
|
1182
|
+
settles before the answer. Answers `{ interrupted: true, turnId }` with the `turn_epoch` it stopped. An idle
|
|
1183
|
+
session answers `{ interrupted: false }`; a `turnId` that is not the running turn answers
|
|
1184
|
+
`{ interrupted: false, turnId }` with the running one and leaves it alone. The session stays open.
|
|
1169
1185
|
- `prompt`, `steer` and `follow_up` are `unsupported`.
|
|
1170
1186
|
- **Admission.** A message from another session enters only through the registrant's drain, which calls
|
|
1171
1187
|
`pi.session.admitExternalMessage({ delivery_id, text, deliverAs, expected_turn_id? })`. One synchronous call
|
|
@@ -1726,6 +1742,24 @@ Response:
|
|
|
1726
1742
|
{"type": "response", "command": "abort", "success": true}
|
|
1727
1743
|
```
|
|
1728
1744
|
|
|
1745
|
+
|
|
1746
|
+
#### interrupt
|
|
1747
|
+
|
|
1748
|
+
Stop the running turn and only that one, with the terminal control endpoint's contract (see "Interactive sessions
|
|
1749
|
+
expose a control endpoint"). `turnId` (the `turn_epoch` of `get_state`) is optional.
|
|
1750
|
+
|
|
1751
|
+
```json
|
|
1752
|
+
{"type": "interrupt", "turnId": "3"}
|
|
1753
|
+
```
|
|
1754
|
+
|
|
1755
|
+
Response: `{ interrupted: true, turnId }` once the turn has stopped; `{ interrupted: false }` when the session is
|
|
1756
|
+
idle; `{ interrupted: false, turnId }` (the running turn) when `turnId` names another turn. Unlike `abort`, it
|
|
1757
|
+
answers after the turn settled.
|
|
1758
|
+
|
|
1759
|
+
```json
|
|
1760
|
+
{"type": "response", "command": "interrupt", "success": true, "data": {"interrupted": true, "turnId": "3"}}
|
|
1761
|
+
```
|
|
1762
|
+
|
|
1729
1763
|
#### clear_queue
|
|
1730
1764
|
|
|
1731
1765
|
Remove queued steering and follow-up messages and return their text.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-yeongyu/senpi",
|
|
3
|
-
"version": "2026.10.10-
|
|
3
|
+
"version": "2026.10.10-4",
|
|
4
4
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"piConfig": {
|
|
@@ -57,9 +57,9 @@
|
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"@earendil-works/chord": "0.99.1",
|
|
60
|
-
"@earendil-works/pi-agent-core": "npm:@code-yeongyu/senpi-agent-core@2026.10.10-
|
|
61
|
-
"@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.10.10-
|
|
62
|
-
"@earendil-works/pi-tui": "npm:@code-yeongyu/senpi-tui@2026.10.10-
|
|
60
|
+
"@earendil-works/pi-agent-core": "npm:@code-yeongyu/senpi-agent-core@2026.10.10-4",
|
|
61
|
+
"@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.10.10-4",
|
|
62
|
+
"@earendil-works/pi-tui": "npm:@code-yeongyu/senpi-tui@2026.10.10-4",
|
|
63
63
|
"@silvia-odwyer/photon-node": "0.3.4",
|
|
64
64
|
"chalk": "6.0.0",
|
|
65
65
|
"cross-spawn": "7.0.6",
|
|
@@ -78,8 +78,8 @@
|
|
|
78
78
|
"yaml": "2.9.1",
|
|
79
79
|
"@anthropic-ai/claude-agent-sdk": "0.3.289",
|
|
80
80
|
"@anthropic-ai/sdk": "0.127.0",
|
|
81
|
-
"@code-yeongyu/senpi-codemode": "2026.10.10-
|
|
82
|
-
"@earendil-works/pi-pty": "npm:@code-yeongyu/senpi-pty@2026.10.10-
|
|
81
|
+
"@code-yeongyu/senpi-codemode": "2026.10.10-4",
|
|
82
|
+
"@earendil-works/pi-pty": "npm:@code-yeongyu/senpi-pty@2026.10.10-4",
|
|
83
83
|
"@modelcontextprotocol/sdk": "1.30.0",
|
|
84
84
|
"@mozilla/readability": "0.6.0",
|
|
85
85
|
"linkedom": "0.18.13",
|