@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.
- package/CHANGELOG.md +19 -0
- package/dist/bundle/chunks/{chunk-AMCDEC5A.js → chunk-B2LRAXQU.js} +2 -2
- package/dist/bundle/chunks/{chunk-D22YF34L.js → chunk-CQ3G57HE.js} +1 -1
- package/dist/bundle/chunks/{chunk-ZUVGFXCS.js → chunk-FVYWSBX3.js} +3 -3
- package/dist/bundle/chunks/{chunk-665UPAKG.js → chunk-H3BTMIH5.js} +6 -6
- package/dist/bundle/chunks/{chunk-KEJWNCLN.js → chunk-HUSQY3ID.js} +1 -1
- package/dist/bundle/chunks/{chunk-IBV4OVXQ.js → chunk-N6OHYIJR.js} +1 -1
- package/dist/bundle/chunks/{chunk-XZR4J6HM.js → chunk-PP52OWBB.js} +1 -1
- package/dist/bundle/chunks/{chunk-XVQISKHL.js → chunk-QV2IEA3B.js} +4 -4
- package/dist/bundle/chunks/{chunk-2V6BR24J.js → chunk-VEWJSPOZ.js} +1 -1
- package/dist/bundle/chunks/{cli-main-REFQSP6S.js → cli-main-6ZI4QO2Z.js} +1 -1
- package/dist/bundle/chunks/{host-command-Y3ZT6YLD.js → host-command-O3ALG2O3.js} +1 -1
- package/dist/bundle/chunks/{host-lifecycle-VW73K4WA.js → host-lifecycle-SGTVODHB.js} +1 -1
- package/dist/bundle/chunks/host-lifecycle.js +5 -5
- package/dist/bundle/chunks/{host-session-command-YDEUZBTX.js → host-session-command-4WRR5JSB.js} +1 -1
- package/dist/bundle/chunks/{interactive-mode-UZXPNJ4V.js → interactive-mode-TF7R35GK.js} +1 -1
- package/dist/bundle/chunks/{main-O5G75MYS.js → main-XLUYSOXP.js} +1 -1
- package/dist/bundle/chunks/{multi-session-host-AZKJYA2X.js → multi-session-host-CADYC2BS.js} +4 -3
- package/dist/bundle/chunks/{package-manager-cli-2YDUGJNR.js → package-manager-cli-I62KMIWK.js} +1 -1
- package/dist/bundle/chunks/{rpc-mode-KZD5HZNI.js → rpc-mode-T5GVMUBQ.js} +1 -1
- package/dist/bundle/chunks/{schedule-command-7LSJAINZ.js → schedule-command-YXGRN5CM.js} +1 -1
- package/dist/bundle/chunks/{session-control-endpoint-BG2KQ6MJ.js → session-control-endpoint-PREVS5UO.js} +1 -1
- package/dist/bundle/chunks/session-worker.js +63 -62
- package/dist/bundle/cli.js +2 -2
- package/dist/bundle/host-supervisor.js +5 -5
- 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/session-recovery-identity.d.ts +12 -1
- package/dist/modes/rpc/compact-call-fold.d.ts +3 -1
- package/dist/modes/rpc/compact-call-fold.js +17 -6
- package/dist/modes/rpc/compact-call-identity.d.ts +13 -0
- package/dist/modes/rpc/compact-call-identity.js +30 -0
- package/dist/modes/rpc/compact-call-model.d.ts +14 -0
- package/dist/modes/rpc/compact-call-model.js +4 -0
- package/dist/modes/rpc/compact-call-table.d.ts +9 -0
- package/dist/modes/rpc/compact-call-table.js +20 -0
- package/dist/modes/rpc/compact-catalog-settled.d.ts +5 -0
- package/dist/modes/rpc/compact-catalog-settled.js +9 -2
- package/dist/modes/rpc/compact-lane-current.d.ts +2 -0
- package/dist/modes/rpc/compact-lane-current.js +4 -0
- package/dist/modes/rpc/compact-message-identity.d.ts +74 -0
- package/dist/modes/rpc/compact-message-identity.js +101 -0
- package/dist/modes/rpc/compact-session-calls.d.ts +5 -4
- package/dist/modes/rpc/compact-session-calls.js +13 -8
- package/dist/modes/rpc/compact-session-state.d.ts +2 -0
- package/dist/modes/rpc/compact-session-state.js +4 -0
- package/dist/modes/rpc/compact-settled-messages.d.ts +12 -4
- package/dist/modes/rpc/compact-settled-messages.js +18 -10
- package/dist/modes/rpc/connection-handler.js +1 -1
- package/dist/modes/rpc/connection-question-bridge.d.ts +2 -1
- package/dist/modes/rpc/connection-question-bridge.js +3 -1
- package/dist/modes/rpc/host-lifecycle-proxy.d.ts +9 -0
- package/dist/modes/rpc/host-lifecycle-proxy.js +29 -7
- package/dist/modes/rpc/rpc-question-types.d.ts +2 -0
- package/dist/modes/rpc/session-acceptance-compact.d.ts +17 -7
- package/dist/modes/rpc/session-acceptance-compact.js +20 -8
- package/dist/modes/rpc/session-acceptance-lane.d.ts +5 -0
- package/dist/modes/rpc/session-acceptance-lane.js +12 -11
- package/dist/modes/rpc/session-event-writer-destinations.d.ts +2 -1
- package/dist/modes/rpc/session-event-writer-destinations.js +24 -9
- package/dist/utils/version-check.js +9 -3
- package/docs/engine-socket/fixtures/admission-routes/i-live-identity.json +716 -0
- package/docs/engine-socket/fixtures/admission-routes/index.json +3 -1
- package/docs/engine-socket/fixtures/admission-routes/j-live-call-identity.json +1020 -0
- package/docs/rpc.md +66 -0
- package/package.json +6 -6
|
@@ -8,6 +8,7 @@ import { SessionEventWriterRecovery } from "./session-event-writer-recovery.js";
|
|
|
8
8
|
import { isCorrelatedReply } from "./socket-peer-recovery.js";
|
|
9
9
|
import { materializerLine } from "./compact-materializer-line.js";
|
|
10
10
|
import { declarationReply } from "./compact-negotiation.js";
|
|
11
|
+
import { unvouchedCall } from "./compact-call-identity.js";
|
|
11
12
|
/** A record's legacy line, encoded on first use: a record no legacy destination needs never builds it (RULING-81 X06). */
|
|
12
13
|
export class RecordLine {
|
|
13
14
|
constructor(record, encoded) {
|
|
@@ -39,15 +40,16 @@ export class SessionEventWriterDestinations extends SessionEventWriterRecovery {
|
|
|
39
40
|
const placeholder = new RecordLine(redacted, placeholderLine);
|
|
40
41
|
if (!isTargeted && !this.fanout.acceptance.has(sessionId))
|
|
41
42
|
this.fanout.rememberSnapshot(sessionId, tagged, line.text, placeholderLine);
|
|
43
|
+
const copies = new Map();
|
|
42
44
|
for (const target of targets) {
|
|
43
45
|
if (target !== undefined && !this.fanout.get(target))
|
|
44
46
|
continue;
|
|
45
47
|
const registered = target === undefined ? undefined : this.fanout.get(target);
|
|
46
48
|
const wants = placeholderLine !== undefined && this.fanout.connectionHas(target, MEDIA_PLACEHOLDERS_CAPABILITY);
|
|
47
49
|
if (registered && target !== undefined) {
|
|
48
|
-
const out = this.eventLine(target, sessionId, wants ? redacted : tagged, wants ? placeholder : line);
|
|
50
|
+
const out = this.eventLine(target, sessionId, wants ? redacted : tagged, wants ? placeholder : line, copies);
|
|
49
51
|
const keyed = !out.atomic && compactDelta(tagged) !== undefined && tagged.message !== null;
|
|
50
|
-
registered.actor.enqueue(out.line, keyed ? MESSAGE_KEY : undefined, out.undelivered, keyed ? serializeJsonLine(demoteToDeltaOnly(tagged)) : undefined, isCorrelatedReply(tagged), mirrors.includes(target)
|
|
52
|
+
registered.actor.enqueue(out.line, keyed ? MESSAGE_KEY : undefined, out.undelivered, keyed ? serializeJsonLine(demoteToDeltaOnly(out.record ?? tagged)) : undefined, isCorrelatedReply(tagged), mirrors.includes(target)
|
|
51
53
|
? undefined
|
|
52
54
|
: this.fanout.attachmentOf(target, sessionId, isTargeted, record.type), current);
|
|
53
55
|
}
|
|
@@ -60,9 +62,10 @@ export class SessionEventWriterDestinations extends SessionEventWriterRecovery {
|
|
|
60
62
|
* holds this lane-owned session, becomes an `eventLease` envelope at the record's accepted sequence, its content
|
|
61
63
|
* staged from the line another destination built or else streamed from the record (never one legacy line); every
|
|
62
64
|
* other destination gets the legacy line. Past the peer's lease bound, or when the record cannot be staged, the peer
|
|
63
|
-
* gets a typed refusal and its connection closes (fail closed, like a plain peer's overflow).
|
|
65
|
+
* gets a typed refusal and its connection closes (fail closed, like a plain peer's overflow). A stamped copy is
|
|
66
|
+
* built once per delivery (`copies`), so every compact peer leases the same staged text.
|
|
64
67
|
*/
|
|
65
|
-
eventLine(target, sessionId, record, line) {
|
|
68
|
+
eventLine(target, sessionId, record, line, copies) {
|
|
66
69
|
const reply = declarationReply(record, this.compactSelection(target));
|
|
67
70
|
if (reply !== undefined && reply !== record)
|
|
68
71
|
return { line: serializeJsonLine(reply) };
|
|
@@ -81,17 +84,28 @@ export class SessionEventWriterDestinations extends SessionEventWriterRecovery {
|
|
|
81
84
|
return { line: line.text };
|
|
82
85
|
if (!this.fanout.connectionHas(target, COMPACT_EVENTS_CAPABILITY))
|
|
83
86
|
return { line: line.text };
|
|
84
|
-
|
|
87
|
+
// RULING-120 (#5331): only this compact peer's copy carries the ids the settled overlay pages for its message;
|
|
88
|
+
// RULING-123 (#5346): and a live call record's snapshot key, or `callUnknown` when the lane vouched for none.
|
|
89
|
+
let copy = copies.get(record);
|
|
90
|
+
if (!copy) {
|
|
91
|
+
const identity = lane.identities.of(record.type, lane.acceptedSequence) ?? unvouchedCall(record);
|
|
92
|
+
const stamped = identity ? { ...record, ...identity } : record;
|
|
93
|
+
copy = { stamped, line: identity ? new RecordLine(stamped) : line };
|
|
94
|
+
copies.set(record, copy);
|
|
95
|
+
}
|
|
96
|
+
const { stamped, line: stampedLine } = copy;
|
|
97
|
+
const identity = stamped !== record;
|
|
98
|
+
const materializer = materializerLine(this.fanout, this.required, target, sessionId, stamped);
|
|
85
99
|
if (materializer)
|
|
86
100
|
return materializer;
|
|
87
|
-
const built =
|
|
88
|
-
const size = built === undefined ? jsonSize(
|
|
101
|
+
const built = stampedLine.built;
|
|
102
|
+
const size = built === undefined ? jsonSize(stamped) : { bytes: Buffer.byteLength(built) - 1, units: built.length - 1 };
|
|
89
103
|
if (size.bytes + 1 <= COMPACT_RECORD_MAX_BYTES)
|
|
90
|
-
return { line:
|
|
104
|
+
return { line: stampedLine.text, ...(identity ? { record: stamped } : {}) };
|
|
91
105
|
const at = { sessionEpoch: lane.sessionEpoch, sequence: lane.acceptedSequence };
|
|
92
106
|
const routes = this.ordinaryRoute(target, sessionId)?.routes ?? [];
|
|
93
107
|
const owner = routes[0] ?? admissionId;
|
|
94
|
-
const minted = events.mint({ socketEpoch, sessionId, admissionId: owner }, at,
|
|
108
|
+
const minted = events.mint({ socketEpoch, sessionId, admissionId: owner }, at, stamped, built ?? size);
|
|
95
109
|
if (minted.ok) {
|
|
96
110
|
const { id } = minted.value;
|
|
97
111
|
const held = events.claim({ socketEpoch, sessionId }, id, owner);
|
|
@@ -100,6 +114,7 @@ export class SessionEventWriterDestinations extends SessionEventWriterRecovery {
|
|
|
100
114
|
held.value.admissions.add(route);
|
|
101
115
|
return {
|
|
102
116
|
line: serializeJsonLine({ type: Reflect.get(record, "type"), sessionId, eventLease: minted.value }),
|
|
117
|
+
...(identity ? { record: stamped } : {}),
|
|
103
118
|
// The lease lives only if its envelope is written: every drop path of the socket actor ends it unseen.
|
|
104
119
|
undelivered: (written) => {
|
|
105
120
|
if (!written)
|
|
@@ -22,7 +22,9 @@ export function readAvailableVersion(payload, channel) {
|
|
|
22
22
|
const DEFAULT_VERSION_CHECK_TIMEOUT_MS = 10000;
|
|
23
23
|
const RELEASE_CHANGELOG_BASE_URL = "https://github.com/code-yeongyu/senpi/blob";
|
|
24
24
|
const RELEASE_CHANGELOG_PATH = "packages/coding-agent/CHANGELOG.md";
|
|
25
|
-
|
|
25
|
+
// Month and day may be zero-padded (`2026.11.02-1` as stamped in package.json) or not (npm's normalized
|
|
26
|
+
// `2026.11.2-1`); a `-1` revision is the same release as the bare date.
|
|
27
|
+
const SENPI_CALVER_PATTERN = /^(\d{4})\.(\d{1,2})\.(\d{1,2})(?:-([1-9]\d*))?$/;
|
|
26
28
|
function parseSenpiCalVer(version) {
|
|
27
29
|
const match = SENPI_CALVER_PATTERN.exec(version);
|
|
28
30
|
if (!match) {
|
|
@@ -30,6 +32,10 @@ function parseSenpiCalVer(version) {
|
|
|
30
32
|
}
|
|
31
33
|
return [Number(match[1]), Number(match[2]), Number(match[3]), Number(match[4] ?? 1)];
|
|
32
34
|
}
|
|
35
|
+
/** Unpadded form semver accepts, used when a CalVer version is compared with a plain semver version. */
|
|
36
|
+
function canonicalCalVer([year, month, day, revision]) {
|
|
37
|
+
return revision > 1 ? `${year}.${month}.${day}-${revision}` : `${year}.${month}.${day}`;
|
|
38
|
+
}
|
|
33
39
|
/** Include useful errno details hidden behind Node's generic "fetch failed" error. */
|
|
34
40
|
export function formatVersionCheckError(error) {
|
|
35
41
|
const rootMessage = error instanceof Error && error.message ? error.message : String(error);
|
|
@@ -58,8 +64,8 @@ export function comparePackageVersions(leftVersion, rightVersion) {
|
|
|
58
64
|
}
|
|
59
65
|
return 0;
|
|
60
66
|
}
|
|
61
|
-
const left = valid(leftTrimmed);
|
|
62
|
-
const right = valid(rightTrimmed);
|
|
67
|
+
const left = valid(leftCalVer ? canonicalCalVer(leftCalVer) : leftTrimmed);
|
|
68
|
+
const right = valid(rightCalVer ? canonicalCalVer(rightCalVer) : rightTrimmed);
|
|
63
69
|
if (!left || !right) {
|
|
64
70
|
return undefined;
|
|
65
71
|
}
|