@code-yeongyu/senpi 2026.8.30-3 → 2026.8.31
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 +34 -0
- package/README.md +3 -0
- package/dist/core/agent-session.d.ts +26 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +67 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.d.ts +9 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.js +10 -3
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js +4 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative-summary.d.ts +1 -0
- package/dist/core/extensions/builtin/compaction/speculative-summary.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative-summary.js +1 -0
- package/dist/core/extensions/builtin/compaction/speculative-summary.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative.js +14 -1
- package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/trust-state-json.d.ts +5 -0
- package/dist/core/extensions/builtin/hooks/trust-state-json.d.ts.map +1 -0
- package/dist/core/extensions/builtin/hooks/trust-state-json.js +76 -0
- package/dist/core/extensions/builtin/hooks/trust-state-json.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/trust-storage.d.ts +7 -1
- package/dist/core/extensions/builtin/hooks/trust-storage.d.ts.map +1 -1
- package/dist/core/extensions/builtin/hooks/trust-storage.js +60 -8
- package/dist/core/extensions/builtin/hooks/trust-storage.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/trust.d.ts +1 -2
- package/dist/core/extensions/builtin/hooks/trust.d.ts.map +1 -1
- package/dist/core/extensions/builtin/hooks/trust.js +1 -72
- package/dist/core/extensions/builtin/hooks/trust.js.map +1 -1
- package/dist/core/extensions/builtin/ttsr/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ttsr/index.js +4 -0
- package/dist/core/extensions/builtin/ttsr/index.js.map +1 -1
- package/dist/core/extensions/builtin/ttsr/manager.d.ts +2 -0
- package/dist/core/extensions/builtin/ttsr/manager.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ttsr/manager.js +28 -1
- package/dist/core/extensions/builtin/ttsr/manager.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +5 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +7 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/retry-fallback/controller.d.ts +14 -0
- package/dist/core/retry-fallback/controller.d.ts.map +1 -1
- package/dist/core/retry-fallback/controller.js +33 -3
- package/dist/core/retry-fallback/controller.js.map +1 -1
- package/dist/core/retry-fallback/log.js +1 -1
- package/dist/core/retry-fallback/log.js.map +1 -1
- package/dist/core/session-activity.d.ts +47 -0
- package/dist/core/session-activity.d.ts.map +1 -0
- package/dist/core/session-activity.js +58 -0
- package/dist/core/session-activity.js.map +1 -0
- package/dist/core/session-manager.d.ts +8 -12
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +118 -7
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-resident-store.d.ts +8 -1
- package/dist/core/session-resident-store.d.ts.map +1 -1
- package/dist/core/session-resident-store.js +12 -5
- package/dist/core/session-resident-store.js.map +1 -1
- package/dist/modes/app-server/daemon.js +3 -3
- package/dist/modes/app-server/daemon.js.map +1 -1
- package/dist/modes/interactive/interactive-host-runtime.d.ts +3 -1
- package/dist/modes/interactive/interactive-host-runtime.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-host-runtime.js +26 -4
- package/dist/modes/interactive/interactive-host-runtime.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +24 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/rpc/connection-handler.d.ts +12 -5
- package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
- package/dist/modes/rpc/connection-handler.js +149 -12
- package/dist/modes/rpc/connection-handler.js.map +1 -1
- package/dist/modes/rpc/custom-capability.d.ts +1 -0
- package/dist/modes/rpc/custom-capability.d.ts.map +1 -1
- package/dist/modes/rpc/custom-capability.js +1 -0
- package/dist/modes/rpc/custom-capability.js.map +1 -1
- package/dist/modes/rpc/host-ensure.d.ts.map +1 -1
- package/dist/modes/rpc/host-ensure.js +3 -3
- package/dist/modes/rpc/host-ensure.js.map +1 -1
- package/dist/modes/rpc/host-lifecycle.d.ts +10 -0
- package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -1
- package/dist/modes/rpc/host-lifecycle.js +15 -2
- package/dist/modes/rpc/host-lifecycle.js.map +1 -1
- package/dist/modes/rpc/multi-session-host.d.ts +38 -0
- package/dist/modes/rpc/multi-session-host.d.ts.map +1 -1
- package/dist/modes/rpc/multi-session-host.js +55 -5
- package/dist/modes/rpc/multi-session-host.js.map +1 -1
- package/dist/modes/rpc/ownership-safe-lock.d.ts +14 -0
- package/dist/modes/rpc/ownership-safe-lock.d.ts.map +1 -0
- package/dist/modes/rpc/ownership-safe-lock.js +87 -0
- package/dist/modes/rpc/ownership-safe-lock.js.map +1 -0
- package/dist/modes/rpc/rpc-client.d.ts +1 -0
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +3 -0
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +12 -1
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js +1 -0
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/modes/rpc/session-binding.d.ts +2 -1
- package/dist/modes/rpc/session-binding.d.ts.map +1 -1
- package/dist/modes/rpc/session-binding.js +1 -0
- package/dist/modes/rpc/session-binding.js.map +1 -1
- package/dist/modes/rpc/session-command-router.d.ts +54 -1
- package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
- package/dist/modes/rpc/session-command-router.js +174 -2
- package/dist/modes/rpc/session-command-router.js.map +1 -1
- package/dist/modes/rpc/session-event-writer.d.ts +18 -0
- package/dist/modes/rpc/session-event-writer.d.ts.map +1 -1
- package/dist/modes/rpc/session-event-writer.js +88 -8
- package/dist/modes/rpc/session-event-writer.js.map +1 -1
- package/dist/modes/rpc/session-registry.d.ts +11 -1
- package/dist/modes/rpc/session-registry.d.ts.map +1 -1
- package/dist/modes/rpc/session-registry.js +25 -0
- package/dist/modes/rpc/session-registry.js.map +1 -1
- package/dist/modes/rpc/widget-line-renderer.d.ts +17 -0
- package/dist/modes/rpc/widget-line-renderer.d.ts.map +1 -0
- package/dist/modes/rpc/widget-line-renderer.js +73 -0
- package/dist/modes/rpc/widget-line-renderer.js.map +1 -0
- package/dist/utils/fs-watch.d.ts.map +1 -1
- package/dist/utils/fs-watch.js +11 -2
- package/dist/utils/fs-watch.js.map +1 -1
- package/docs/app-server.md +2 -2
- package/docs/containerization.md +2 -2
- package/docs/development.md +7 -7
- package/docs/extensions.md +4 -4
- package/docs/grok-neo.md +1 -1
- package/docs/index.md +1 -1
- package/docs/packages.md +2 -2
- package/docs/quickstart.md +4 -4
- package/docs/release-guide.md +21 -21
- package/docs/rpc.md +59 -4
- package/docs/sdk.md +1 -1
- package/docs/skills.md +2 -2
- package/docs/terminal-tools.md +1 -1
- package/docs/termux.md +1 -1
- package/docs/tui.md +1 -1
- package/examples/AGENTS.md +1 -1
- package/examples/sdk/README.md +1 -1
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +16 -0
- package/node_modules/@code-yeongyu/senpi-codemode/README.md +2 -2
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/extension/skill-contribution.ts +71 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +3 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/SKILL.md +44 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/breaking-changes.md +75 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/build.md +114 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/dev-tooling.md +34 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/http-networking.md +113 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/install.md +93 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/node-compat-platforms.md +36 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/performance.md +33 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/runtime-apis.md +156 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/security.md +52 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/test.md +103 -0
- package/node_modules/@earendil-works/pi-agent-core/README.md +3 -0
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/README.md +6 -3
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +15 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts +7 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js +316 -2
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-conversation-rotation.d.ts +4 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-conversation-rotation.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-conversation-rotation.js +23 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-conversation-rotation.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts +24 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +20 -2
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +2 -2
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/README.md +6 -3
- package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/README.md +5 -4
- package/node_modules/@earendil-works/pi-tui/native/darwin/README.md +2 -2
- package/node_modules/@earendil-works/pi-tui/native/win32/README.md +2 -2
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +7 -7
|
@@ -497,6 +497,15 @@ export function findMostRecentSession(sessionDir, cwd) {
|
|
|
497
497
|
* Use buildSessionContext() to get the resolved message list for the LLM, which
|
|
498
498
|
* handles compaction summaries and follows the path from root to current leaf.
|
|
499
499
|
*/
|
|
500
|
+
let sessionEntryLoader = loadEntriesFromFile;
|
|
501
|
+
/** Test seam for observing disk reloads without mocking ESM filesystem exports. */
|
|
502
|
+
export function setSessionEntryLoaderForTesting(loader) {
|
|
503
|
+
const previous = sessionEntryLoader;
|
|
504
|
+
sessionEntryLoader = loader;
|
|
505
|
+
return () => {
|
|
506
|
+
sessionEntryLoader = previous;
|
|
507
|
+
};
|
|
508
|
+
}
|
|
500
509
|
export class SessionManager {
|
|
501
510
|
constructor(cwd, sessionDir, sessionFile, persist, newSessionOptions, preloadedFileEntries) {
|
|
502
511
|
this.sessionId = "";
|
|
@@ -513,6 +522,8 @@ export class SessionManager {
|
|
|
513
522
|
this.labelTimestampsById = new Map();
|
|
514
523
|
this.leafId = null;
|
|
515
524
|
this.residentStore = new ResidentStringStore();
|
|
525
|
+
this.mirrorTrimmed = false;
|
|
526
|
+
this.compactEntriesCache = null;
|
|
516
527
|
// Monotonic counter bumped by every mutator; memoized materialized views are
|
|
517
528
|
// keyed on it so read hot paths (footer, RPC) never re-materialize unchanged sessions.
|
|
518
529
|
this.mutationCount = 0;
|
|
@@ -567,6 +578,7 @@ export class SessionManager {
|
|
|
567
578
|
}
|
|
568
579
|
_setSessionFile(sessionFile, preloadedFileEntries) {
|
|
569
580
|
this.sessionFile = resolvePath(sessionFile);
|
|
581
|
+
this.mirrorTrimmed = false;
|
|
570
582
|
this.residentStore.clear();
|
|
571
583
|
if (existsSync(this.sessionFile)) {
|
|
572
584
|
this.fileEntries = preloadedFileEntries ?? loadEntriesFromFile(this.sessionFile);
|
|
@@ -614,6 +626,7 @@ export class SessionManager {
|
|
|
614
626
|
parentSession: options?.parentSession,
|
|
615
627
|
};
|
|
616
628
|
this.fileEntries = [header];
|
|
629
|
+
this.mirrorTrimmed = false;
|
|
617
630
|
this.residentStore.clear();
|
|
618
631
|
this.byId.clear();
|
|
619
632
|
this.entryOrdersById.clear();
|
|
@@ -776,7 +789,18 @@ export class SessionManager {
|
|
|
776
789
|
}
|
|
777
790
|
}
|
|
778
791
|
_materializeEntry(entry) {
|
|
779
|
-
|
|
792
|
+
let missingResidentString = false;
|
|
793
|
+
const materialized = this.residentStore.materialize(entry, () => {
|
|
794
|
+
missingResidentString = true;
|
|
795
|
+
return undefined;
|
|
796
|
+
});
|
|
797
|
+
// The resident store is a bounded cache. The JSONL remains authoritative
|
|
798
|
+
// when an evicted blob is needed by a branch or read operation.
|
|
799
|
+
if (missingResidentString && this.sessionFile) {
|
|
800
|
+
const persisted = loadEntriesFromFile(this.sessionFile).find((candidate) => candidate.id === entry.id);
|
|
801
|
+
if (persisted)
|
|
802
|
+
return persisted;
|
|
803
|
+
}
|
|
780
804
|
if (materialized.type === "message") {
|
|
781
805
|
const order = this.entryOrdersById.get(materialized.id);
|
|
782
806
|
if (order !== undefined) {
|
|
@@ -886,9 +910,36 @@ export class SessionManager {
|
|
|
886
910
|
fromHook,
|
|
887
911
|
};
|
|
888
912
|
this._appendEntry(entry);
|
|
913
|
+
this._trimMirrorAfterCompaction(entry);
|
|
889
914
|
return entry.id;
|
|
890
915
|
}
|
|
891
|
-
|
|
916
|
+
_trimMirrorAfterCompaction(compaction) {
|
|
917
|
+
if (!this.persist)
|
|
918
|
+
return;
|
|
919
|
+
const firstKeptIndex = this.fileEntries.findIndex((entry) => entry.id === compaction.firstKeptEntryId);
|
|
920
|
+
const compactionIndex = this.fileEntries.findIndex((entry) => entry.id === compaction.id);
|
|
921
|
+
if (firstKeptIndex < 0 || compactionIndex < firstKeptIndex)
|
|
922
|
+
return;
|
|
923
|
+
const header = this.fileEntries.find((entry) => entry.type === "session");
|
|
924
|
+
const retained = [
|
|
925
|
+
...this.fileEntries.slice(0, firstKeptIndex).filter((entry) => entry.type !== "message"),
|
|
926
|
+
...this.fileEntries.slice(firstKeptIndex, compactionIndex + 1),
|
|
927
|
+
];
|
|
928
|
+
let parentId = null;
|
|
929
|
+
for (const entry of retained) {
|
|
930
|
+
if (entry.type !== "session")
|
|
931
|
+
entry.parentId = parentId;
|
|
932
|
+
parentId = entry.type === "session" ? null : entry.id;
|
|
933
|
+
}
|
|
934
|
+
this.residentStore.clear();
|
|
935
|
+
this.mirrorTrimmed = true;
|
|
936
|
+
this.fileEntries = [header, ...retained]
|
|
937
|
+
.filter((entry) => entry !== undefined)
|
|
938
|
+
.map((entry) => this.residentStore.externalize(entry));
|
|
939
|
+
this._buildIndex();
|
|
940
|
+
this.mutationCount++;
|
|
941
|
+
}
|
|
942
|
+
/** Append a custom entry (for extensions) as child of current leaf, then advance leaf. */
|
|
892
943
|
appendCustomEntry(customType, data) {
|
|
893
944
|
const entry = {
|
|
894
945
|
type: "custom",
|
|
@@ -956,7 +1007,13 @@ export class SessionManager {
|
|
|
956
1007
|
}
|
|
957
1008
|
getEntry(id) {
|
|
958
1009
|
const entry = this.byId.get(id);
|
|
959
|
-
|
|
1010
|
+
if (entry)
|
|
1011
|
+
return this._materializeEntry(entry);
|
|
1012
|
+
if (this.mirrorTrimmed && this.sessionFile) {
|
|
1013
|
+
const persisted = this._loadFullHistoryEntries().find((candidate) => candidate.id === id);
|
|
1014
|
+
return persisted ? this.residentStore.materialize(persisted) : undefined;
|
|
1015
|
+
}
|
|
1016
|
+
return undefined;
|
|
960
1017
|
}
|
|
961
1018
|
/**
|
|
962
1019
|
* Get all direct children of an entry.
|
|
@@ -1020,10 +1077,16 @@ export class SessionManager {
|
|
|
1020
1077
|
}
|
|
1021
1078
|
const path = [];
|
|
1022
1079
|
const startId = fromId ?? this.leafId;
|
|
1023
|
-
let
|
|
1080
|
+
let entriesById = this.byId;
|
|
1081
|
+
if (fromId !== undefined && !entriesById.has(fromId) && this.mirrorTrimmed && this.sessionFile) {
|
|
1082
|
+
entriesById = new Map(this._loadFullHistoryEntries()
|
|
1083
|
+
.filter((entry) => entry.type !== "session")
|
|
1084
|
+
.map((entry) => [entry.id, this.residentStore.materialize(entry)]));
|
|
1085
|
+
}
|
|
1086
|
+
let current = startId ? entriesById.get(startId) : undefined;
|
|
1024
1087
|
while (current) {
|
|
1025
1088
|
path.unshift(this._materializeEntry(current));
|
|
1026
|
-
current = current.parentId ?
|
|
1089
|
+
current = current.parentId ? entriesById.get(current.parentId) : undefined;
|
|
1027
1090
|
}
|
|
1028
1091
|
if (fromId === undefined) {
|
|
1029
1092
|
this.branchCache = { leafId: this.leafId, mutation: this.mutationCount, entries: path };
|
|
@@ -1035,14 +1098,14 @@ export class SessionManager {
|
|
|
1035
1098
|
* Uses tree traversal from current leaf.
|
|
1036
1099
|
*/
|
|
1037
1100
|
buildContextEntries() {
|
|
1038
|
-
return buildContextEntries(this.
|
|
1101
|
+
return buildContextEntries(this._getCompactEntries(), this.leafId);
|
|
1039
1102
|
}
|
|
1040
1103
|
/**
|
|
1041
1104
|
* Build the session context (what gets sent to the LLM).
|
|
1042
1105
|
* Uses tree traversal from current leaf.
|
|
1043
1106
|
*/
|
|
1044
1107
|
buildSessionContext() {
|
|
1045
|
-
return buildSessionContext(this.
|
|
1108
|
+
return buildSessionContext(this._getCompactEntries(), this.leafId);
|
|
1046
1109
|
}
|
|
1047
1110
|
hasContextMessages() {
|
|
1048
1111
|
return this.hasBranchEntry((entry) => entry.type === "message" ||
|
|
@@ -1088,6 +1151,11 @@ export class SessionManager {
|
|
|
1088
1151
|
* you need to filter/reorder.
|
|
1089
1152
|
*/
|
|
1090
1153
|
getEntries() {
|
|
1154
|
+
if (this.mirrorTrimmed && this.sessionFile) {
|
|
1155
|
+
return this._loadFullHistoryEntries()
|
|
1156
|
+
.filter((e) => e.type !== "session")
|
|
1157
|
+
.map((entry) => this.residentStore.materialize(entry));
|
|
1158
|
+
}
|
|
1091
1159
|
if (this.entriesCache !== null && this.entriesCache.mutation === this.mutationCount) {
|
|
1092
1160
|
return this.entriesCache.entries;
|
|
1093
1161
|
}
|
|
@@ -1097,6 +1165,45 @@ export class SessionManager {
|
|
|
1097
1165
|
this.entriesCache = { mutation: this.mutationCount, entries };
|
|
1098
1166
|
return entries;
|
|
1099
1167
|
}
|
|
1168
|
+
_getCompactEntries() {
|
|
1169
|
+
if (this.compactEntriesCache?.mutation !== this.mutationCount) {
|
|
1170
|
+
this.compactEntriesCache = {
|
|
1171
|
+
mutation: this.mutationCount,
|
|
1172
|
+
entries: this.fileEntries.filter((e) => e.type !== "session"),
|
|
1173
|
+
};
|
|
1174
|
+
}
|
|
1175
|
+
const entries = this.compactEntriesCache.entries;
|
|
1176
|
+
const missingEntryIds = new Set();
|
|
1177
|
+
for (const entry of entries) {
|
|
1178
|
+
this.residentStore.materialize(entry, () => {
|
|
1179
|
+
missingEntryIds.add(entry.id);
|
|
1180
|
+
return undefined;
|
|
1181
|
+
});
|
|
1182
|
+
}
|
|
1183
|
+
if (missingEntryIds.size > 0 && this.sessionFile) {
|
|
1184
|
+
const persistedById = new Map(this._loadFullHistoryEntries().map((entry) => [entry.id, entry]));
|
|
1185
|
+
for (let index = 0; index < entries.length; index++) {
|
|
1186
|
+
const entry = entries[index];
|
|
1187
|
+
if (!missingEntryIds.has(entry.id))
|
|
1188
|
+
continue;
|
|
1189
|
+
const persisted = persistedById.get(entry.id);
|
|
1190
|
+
if (persisted)
|
|
1191
|
+
entries[index] = this.residentStore.externalize(persisted);
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
const materialized = entries.map((entry) => this.residentStore.materialize(entry));
|
|
1195
|
+
for (const entry of materialized) {
|
|
1196
|
+
if (entry.type !== "message")
|
|
1197
|
+
continue;
|
|
1198
|
+
const order = this.entryOrdersById.get(entry.id);
|
|
1199
|
+
if (order !== undefined)
|
|
1200
|
+
this.messageEntryPositions.set(entry.message, { entryId: entry.id, order });
|
|
1201
|
+
}
|
|
1202
|
+
return materialized;
|
|
1203
|
+
}
|
|
1204
|
+
_loadFullHistoryEntries() {
|
|
1205
|
+
return this.sessionFile ? sessionEntryLoader(this.sessionFile) : this.fileEntries;
|
|
1206
|
+
}
|
|
1100
1207
|
/**
|
|
1101
1208
|
* Get the session as a tree structure. Returns a shallow defensive copy of all entries.
|
|
1102
1209
|
* A well-formed session has exactly one root (first entry with parentId === null).
|
|
@@ -1149,6 +1256,9 @@ export class SessionManager {
|
|
|
1149
1256
|
* are not modified or deleted.
|
|
1150
1257
|
*/
|
|
1151
1258
|
branch(branchFromId) {
|
|
1259
|
+
if (!this.byId.has(branchFromId) && this.sessionFile) {
|
|
1260
|
+
this.reloadFromDisk();
|
|
1261
|
+
}
|
|
1152
1262
|
if (!this.byId.has(branchFromId)) {
|
|
1153
1263
|
throw new Error(`Entry ${branchFromId} not found`);
|
|
1154
1264
|
}
|
|
@@ -1250,6 +1360,7 @@ export class SessionManager {
|
|
|
1250
1360
|
parentId = labelEntry.id;
|
|
1251
1361
|
}
|
|
1252
1362
|
this.residentStore.clear();
|
|
1363
|
+
this.mirrorTrimmed = false;
|
|
1253
1364
|
this.fileEntries = [header, ...pathWithoutLabels, ...labelEntries].map((entry) => this.residentStore.externalize(entry));
|
|
1254
1365
|
this.sessionId = newSessionId;
|
|
1255
1366
|
this.sessionFile = newSessionFile;
|