@code-yeongyu/senpi 2026.11.2-1 → 2026.11.2-2

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 (67) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/bundle/chunks/{chunk-AMCDEC5A.js → chunk-B2LRAXQU.js} +2 -2
  3. package/dist/bundle/chunks/{chunk-D22YF34L.js → chunk-CQ3G57HE.js} +1 -1
  4. package/dist/bundle/chunks/{chunk-ZUVGFXCS.js → chunk-FVYWSBX3.js} +3 -3
  5. package/dist/bundle/chunks/{chunk-665UPAKG.js → chunk-H3BTMIH5.js} +6 -6
  6. package/dist/bundle/chunks/{chunk-KEJWNCLN.js → chunk-HUSQY3ID.js} +1 -1
  7. package/dist/bundle/chunks/{chunk-IBV4OVXQ.js → chunk-N6OHYIJR.js} +1 -1
  8. package/dist/bundle/chunks/{chunk-XZR4J6HM.js → chunk-PP52OWBB.js} +1 -1
  9. package/dist/bundle/chunks/{chunk-XVQISKHL.js → chunk-QV2IEA3B.js} +4 -4
  10. package/dist/bundle/chunks/{chunk-2V6BR24J.js → chunk-VEWJSPOZ.js} +1 -1
  11. package/dist/bundle/chunks/{cli-main-REFQSP6S.js → cli-main-6ZI4QO2Z.js} +1 -1
  12. package/dist/bundle/chunks/{host-command-Y3ZT6YLD.js → host-command-O3ALG2O3.js} +1 -1
  13. package/dist/bundle/chunks/{host-lifecycle-VW73K4WA.js → host-lifecycle-SGTVODHB.js} +1 -1
  14. package/dist/bundle/chunks/host-lifecycle.js +5 -5
  15. package/dist/bundle/chunks/{host-session-command-YDEUZBTX.js → host-session-command-4WRR5JSB.js} +1 -1
  16. package/dist/bundle/chunks/{interactive-mode-UZXPNJ4V.js → interactive-mode-TF7R35GK.js} +1 -1
  17. package/dist/bundle/chunks/{main-O5G75MYS.js → main-XLUYSOXP.js} +1 -1
  18. package/dist/bundle/chunks/{multi-session-host-AZKJYA2X.js → multi-session-host-CADYC2BS.js} +4 -3
  19. package/dist/bundle/chunks/{package-manager-cli-2YDUGJNR.js → package-manager-cli-I62KMIWK.js} +1 -1
  20. package/dist/bundle/chunks/{rpc-mode-KZD5HZNI.js → rpc-mode-T5GVMUBQ.js} +1 -1
  21. package/dist/bundle/chunks/{schedule-command-7LSJAINZ.js → schedule-command-YXGRN5CM.js} +1 -1
  22. package/dist/bundle/chunks/{session-control-endpoint-BG2KQ6MJ.js → session-control-endpoint-PREVS5UO.js} +1 -1
  23. package/dist/bundle/chunks/session-worker.js +63 -62
  24. package/dist/bundle/cli.js +2 -2
  25. package/dist/bundle/host-supervisor.js +5 -5
  26. package/dist/bundle/index.js +1 -1
  27. package/dist/bundle/rpc-entry.js +1 -1
  28. package/dist/bundle/runtime-manifest.json +1 -1
  29. package/dist/core/session-recovery-identity.d.ts +12 -1
  30. package/dist/modes/rpc/compact-call-fold.d.ts +3 -1
  31. package/dist/modes/rpc/compact-call-fold.js +17 -6
  32. package/dist/modes/rpc/compact-call-identity.d.ts +13 -0
  33. package/dist/modes/rpc/compact-call-identity.js +30 -0
  34. package/dist/modes/rpc/compact-call-model.d.ts +14 -0
  35. package/dist/modes/rpc/compact-call-model.js +4 -0
  36. package/dist/modes/rpc/compact-call-table.d.ts +9 -0
  37. package/dist/modes/rpc/compact-call-table.js +20 -0
  38. package/dist/modes/rpc/compact-catalog-settled.d.ts +5 -0
  39. package/dist/modes/rpc/compact-catalog-settled.js +9 -2
  40. package/dist/modes/rpc/compact-lane-current.d.ts +2 -0
  41. package/dist/modes/rpc/compact-lane-current.js +4 -0
  42. package/dist/modes/rpc/compact-message-identity.d.ts +74 -0
  43. package/dist/modes/rpc/compact-message-identity.js +101 -0
  44. package/dist/modes/rpc/compact-session-calls.d.ts +5 -4
  45. package/dist/modes/rpc/compact-session-calls.js +13 -8
  46. package/dist/modes/rpc/compact-session-state.d.ts +2 -0
  47. package/dist/modes/rpc/compact-session-state.js +4 -0
  48. package/dist/modes/rpc/compact-settled-messages.d.ts +12 -4
  49. package/dist/modes/rpc/compact-settled-messages.js +18 -10
  50. package/dist/modes/rpc/connection-handler.js +1 -1
  51. package/dist/modes/rpc/connection-question-bridge.d.ts +2 -1
  52. package/dist/modes/rpc/connection-question-bridge.js +3 -1
  53. package/dist/modes/rpc/host-lifecycle-proxy.d.ts +9 -0
  54. package/dist/modes/rpc/host-lifecycle-proxy.js +29 -7
  55. package/dist/modes/rpc/rpc-question-types.d.ts +2 -0
  56. package/dist/modes/rpc/session-acceptance-compact.d.ts +17 -7
  57. package/dist/modes/rpc/session-acceptance-compact.js +20 -8
  58. package/dist/modes/rpc/session-acceptance-lane.d.ts +5 -0
  59. package/dist/modes/rpc/session-acceptance-lane.js +12 -11
  60. package/dist/modes/rpc/session-event-writer-destinations.d.ts +2 -1
  61. package/dist/modes/rpc/session-event-writer-destinations.js +24 -9
  62. package/dist/utils/version-check.js +9 -3
  63. package/docs/engine-socket/fixtures/admission-routes/i-live-identity.json +716 -0
  64. package/docs/engine-socket/fixtures/admission-routes/index.json +3 -1
  65. package/docs/engine-socket/fixtures/admission-routes/j-live-call-identity.json +1020 -0
  66. package/docs/rpc.md +66 -0
  67. package/package.json +6 -6
package/docs/rpc.md CHANGED
@@ -840,6 +840,69 @@ most 32 live event leases; past that it receives `{"type": "event_lease_refused"
840
840
  "lease_limit"}` and is closed, and a record the host cannot stage is refused the same way with
841
841
  `"storage_unavailable"`. Its end releases every lease it holds. Leases are released only by `release_recovery`.
842
842
 
843
+ **Live message identity (senpi#5331, RULING-120).** A session record never carries its recovery identity as a
844
+ property: legacy connections, and every connection with the flag off, receive exactly the bytes they always did.
845
+ The one exception is the copy a `compact_events` connection receives behind the flag, so it can join a live record to
846
+ the settled overlay it pages after a reconnect or a recovery cut without a second derivation of its own:
847
+
848
+ - `message_end` gains `messageId` and `terminalSequence`: the `messageId` and `terminalSequence` of the message's
849
+ settled row, which a pending or failed terminal pages as the `settled` member `message-<terminalSequence>`
850
+ (sixteen digits) and a joined message pages as the `messageId` of its `identity` member `join-<n>`.
851
+ - `entry_appended` carries the entry's ownership as a tri-state (senpi#5337, RULING-122):
852
+ - `owningMessageId` present: the entry joined a message, and this is that join member's `messageId`. The owner is
853
+ captured when the append is applied and kept for that entry, so transcript batches applied before its
854
+ `entry_appended` cannot drop it.
855
+ - `ownerUnknown: true`: the host cannot vouch for the entry's ownership. An owned entry the settled store never
856
+ joined (the epoch's transcript component was unavailable, or the store refused the join) carries it. At most 1,024
857
+ joins wait for their `entry_appended` at once; a join dropped at that bound is remembered by entry id. Both kinds
858
+ share one memory (up to 4,096 ids per epoch), and once that memory itself overflows, every entry of the epoch with
859
+ no join carries `ownerUnknown` until the next bootstrap, including entries no message owns (conservative by
860
+ design: never a false "not owned"). Resolve a dropped join through recovery's `identity` member `join-<n>` for
861
+ that entry id; an entry the store never joined has no such member.
862
+ - both absent: the entry is not message-owned, never a lost or pending join. This absence is normative only because
863
+ the host marks every entry it cannot vouch for with `ownerUnknown`.
864
+
865
+ The lane's status counts dropped joins (`ownerJoinsEvicted`) and ids dropped from that memory
866
+ (`ownerJoinsOverflowed`), and the host writes one stderr line at an epoch's first overflow. An `entry_appended`
867
+ carries its tri-state even when the host refused its canonical record at the protocol depth limit: the record is
868
+ still delivered, and it takes its entry's join like any other.
869
+ - `transcript_write_failed` gains `messageId`: the failed terminal row's `messageId`.
870
+
871
+ The host appends the fields after the record's own (`{"type": "message_end", ..., "sessionId": "rpc-1", "messageId":
872
+ "...", "terminalSequence": 12}`; a leased record carries them inside its `record` component). They come from the
873
+ settled store that writes those rows, not a parallel derivation. `messageId` is an opaque id with no message content,
874
+ the same live and after recovery for the message's lifetime, and never reused in the session; `terminalSequence` is
875
+ the record's accepted sequence in its `sessionEpoch`. A record with no settled row (an end the store refused, an entry
876
+ no message owns) carries none of them; an entry whose ownership the host cannot vouch for carries `ownerUnknown: true`
877
+ instead.
878
+
879
+ **Live call identity (senpi#5346, RULING-123).** The same compact copy of a live call record names the call it
880
+ belongs to, so a client can join it to that call's snapshot entry after a reconnect or a recovery cut. This covers
881
+ `message_update` records whose `assistantMessageEvent` is `toolcall_start`, `toolcall_delta` or `toolcall_end`, and
882
+ `tool_execution_start`, `tool_execution_update`, `tool_execution_end` and `tool_hook_status`:
883
+
884
+ - `runtimeItemKey`: the key of the outstanding call the host changed with this record, the same key the call's
885
+ `calls` member and, once it settles, its terminal row and call projection carry. A `toolcall_*` update names the call
886
+ that owns the streamed block. The key is opaque, fixed for the call's lifetime (live and after recovery), and never
887
+ reused in the session, so it tells apart calls that share a `toolCallId` (providers reuse them across turns). It is
888
+ unique on its own; no `turnId` is needed beside it.
889
+ - `callUnknown: true`: the host changed no call with this record, so it cannot vouch for one. Every `tool_hook_status`
890
+ names a `toolCallId` (there are no session-level hook records), but a hook can run for a call the session never
891
+ announced, such as a nested call inside another tool; that record, a record for a call that already ended, a record
892
+ refused at the protocol depth limit, and a record arriving while the epoch's compact state is unavailable all carry
893
+ `callUnknown: true`. So does an execution or hook record (`tool_execution_*`, `tool_hook_status`) whose
894
+ `toolCallId` more than one call inside one assistant message took: those records name only the `toolCallId`, so the
895
+ host cannot tell which of those calls a record is about, and it never picks one by order. The mark lasts while any
896
+ call of that message and id is live. A `toolcall_*` update names its block by `contentIndex`, so it keeps the exact
897
+ key of its own call even then.
898
+
899
+ A compact live call record carries exactly one of the two fields, `runtimeItemKey` or `callUnknown: true`, never both
900
+ and never neither; that holds for its delta-only form too, when a newer `toolcall_delta` supersedes a queued one.
901
+
902
+ The host appends the field after the record's own, like the message ids above (`{"type": "tool_execution_end", ...,
903
+ "sessionId": "rpc-1", "runtimeItemKey": "..."}`); legacy connections and every connection with the flag off receive
904
+ the same bytes as before.
905
+
843
906
  #### release_recovery
844
907
 
845
908
  Behind the same flag, the consumer's receipt for an event lease (senpi#4272, S13). Send it only once the leased
@@ -6450,6 +6513,8 @@ Set the text in the input editor. Fire-and-forget.
6450
6513
 
6451
6514
  Present one or more questions to the user. Requires the `question` client capability (advertised in `set_client_info`). Questions are broadcast to all attached connections, not just the requester. Pending questions survive the assistant message and are replayed to connections that attach later via `open_session` state.
6452
6515
 
6516
+ Every `question` frame carries `raisedBy`: the `connectionId` whose command raised it (the same connection a `select`, `confirm`, `input` or `editor` raised at that point is delivered to; for a model tool call, the connection whose prompt started the turn), or `"agent"` when no connection's command started the work (for example a goal continuation, or a classic stdio session). A client uses it to tell a question it raised from one another connection raised; the frame still reaches every attached connection, and any of them may answer. The field is optional and additive: a client that ignores it is unaffected, and frames from older hosts omit it. The replayed frames in `pendingQuestions` carry the same value.
6517
+
6453
6518
  ```json
6454
6519
  {
6455
6520
  "type": "extension_ui_request",
@@ -6458,6 +6523,7 @@ Present one or more questions to the user. Requires the `question` client capabi
6458
6523
  "requestId": "ask-user-1",
6459
6524
  "toolCallId": "call_abc123",
6460
6525
  "waitForAnswer": true,
6526
+ "raisedBy": "socket-1",
6461
6527
  "questions": [
6462
6528
  {
6463
6529
  "id": "q1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/senpi",
3
- "version": "2026.11.02-1",
3
+ "version": "2026.11.2-2",
4
4
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "piConfig": {
@@ -83,9 +83,9 @@
83
83
  },
84
84
  "dependencies": {
85
85
  "@earendil-works/chord": "0.99.1",
86
- "@earendil-works/pi-agent-core": "npm:@code-yeongyu/senpi-agent-core@2026.11.02-1",
87
- "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.11.02-1",
88
- "@earendil-works/pi-tui": "npm:@code-yeongyu/senpi-tui@2026.11.02-1",
86
+ "@earendil-works/pi-agent-core": "npm:@code-yeongyu/senpi-agent-core@2026.11.2-2",
87
+ "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.11.2-2",
88
+ "@earendil-works/pi-tui": "npm:@code-yeongyu/senpi-tui@2026.11.2-2",
89
89
  "@silvia-odwyer/photon-node": "0.3.4",
90
90
  "ajv": "8.20.0",
91
91
  "chalk": "6.0.0",
@@ -106,8 +106,8 @@
106
106
  "yaml": "2.9.1",
107
107
  "@anthropic-ai/claude-agent-sdk": "0.3.306",
108
108
  "@anthropic-ai/sdk": "0.127.0",
109
- "@code-yeongyu/senpi-codemode": "2026.11.02-1",
110
- "@earendil-works/pi-pty": "npm:@code-yeongyu/senpi-pty@2026.11.02-1",
109
+ "@code-yeongyu/senpi-codemode": "2026.11.2-2",
110
+ "@earendil-works/pi-pty": "npm:@code-yeongyu/senpi-pty@2026.11.2-2",
111
111
  "@modelcontextprotocol/sdk": "1.32.1",
112
112
  "@mozilla/readability": "0.6.0",
113
113
  "linkedom": "0.18.13",