@code-yeongyu/senpi 2026.6.6-3 → 2026.6.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 (255) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +113 -111
  3. package/dist/cli/args.d.ts.map +1 -1
  4. package/dist/cli/args.js +1 -2
  5. package/dist/cli/args.js.map +1 -1
  6. package/dist/cli/project-trust.d.ts +10 -0
  7. package/dist/cli/project-trust.d.ts.map +1 -0
  8. package/dist/cli/project-trust.js +48 -0
  9. package/dist/cli/project-trust.js.map +1 -0
  10. package/dist/cli/startup-ui.d.ts +7 -0
  11. package/dist/cli/startup-ui.d.ts.map +1 -0
  12. package/dist/cli/startup-ui.js +59 -0
  13. package/dist/cli/startup-ui.js.map +1 -0
  14. package/dist/cli.js +10 -1
  15. package/dist/cli.js.map +1 -1
  16. package/dist/core/agent-session-runtime.d.ts +3 -1
  17. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  18. package/dist/core/agent-session-runtime.js +4 -1
  19. package/dist/core/agent-session-runtime.js.map +1 -1
  20. package/dist/core/agent-session-services.d.ts +2 -1
  21. package/dist/core/agent-session-services.d.ts.map +1 -1
  22. package/dist/core/agent-session-services.js +2 -2
  23. package/dist/core/agent-session-services.js.map +1 -1
  24. package/dist/core/agent-session.d.ts +1 -0
  25. package/dist/core/agent-session.d.ts.map +1 -1
  26. package/dist/core/agent-session.js +6 -0
  27. package/dist/core/agent-session.js.map +1 -1
  28. package/dist/core/compaction/utils.d.ts +1 -1
  29. package/dist/core/compaction/utils.d.ts.map +1 -1
  30. package/dist/core/compaction/utils.js +1 -1
  31. package/dist/core/compaction/utils.js.map +1 -1
  32. package/dist/core/experimental.d.ts +2 -0
  33. package/dist/core/experimental.d.ts.map +1 -0
  34. package/dist/core/experimental.js +4 -0
  35. package/dist/core/experimental.js.map +1 -0
  36. package/dist/core/extensions/builtin/todotools/index.d.ts.map +1 -1
  37. package/dist/core/extensions/builtin/todotools/index.js +0 -2
  38. package/dist/core/extensions/builtin/todotools/index.js.map +1 -1
  39. package/dist/core/extensions/builtin/todotools/prompt.d.ts +1 -1
  40. package/dist/core/extensions/builtin/todotools/prompt.d.ts.map +1 -1
  41. package/dist/core/extensions/builtin/todotools/prompt.js +0 -2
  42. package/dist/core/extensions/builtin/todotools/prompt.js.map +1 -1
  43. package/dist/core/extensions/index.d.ts +1 -1
  44. package/dist/core/extensions/index.d.ts.map +1 -1
  45. package/dist/core/extensions/index.js.map +1 -1
  46. package/dist/core/extensions/loader.d.ts +1 -1
  47. package/dist/core/extensions/loader.d.ts.map +1 -1
  48. package/dist/core/extensions/loader.js +4 -4
  49. package/dist/core/extensions/loader.js.map +1 -1
  50. package/dist/core/extensions/runner.d.ts +7 -2
  51. package/dist/core/extensions/runner.d.ts.map +1 -1
  52. package/dist/core/extensions/runner.js +34 -0
  53. package/dist/core/extensions/runner.js.map +1 -1
  54. package/dist/core/extensions/types.d.ts +21 -1
  55. package/dist/core/extensions/types.d.ts.map +1 -1
  56. package/dist/core/extensions/types.js.map +1 -1
  57. package/dist/core/index.d.ts +1 -0
  58. package/dist/core/index.d.ts.map +1 -1
  59. package/dist/core/index.js +1 -0
  60. package/dist/core/index.js.map +1 -1
  61. package/dist/core/model-registry.d.ts +3 -1
  62. package/dist/core/model-registry.d.ts.map +1 -1
  63. package/dist/core/model-registry.js +22 -3
  64. package/dist/core/model-registry.js.map +1 -1
  65. package/dist/core/project-trust.d.ts +15 -0
  66. package/dist/core/project-trust.d.ts.map +1 -0
  67. package/dist/core/project-trust.js +58 -0
  68. package/dist/core/project-trust.js.map +1 -0
  69. package/dist/core/prompt-templates.d.ts +2 -1
  70. package/dist/core/prompt-templates.d.ts.map +1 -1
  71. package/dist/core/prompt-templates.js +24 -26
  72. package/dist/core/prompt-templates.js.map +1 -1
  73. package/dist/core/resource-loader.d.ts +14 -3
  74. package/dist/core/resource-loader.d.ts.map +1 -1
  75. package/dist/core/resource-loader.js +128 -58
  76. package/dist/core/resource-loader.js.map +1 -1
  77. package/dist/core/session-manager.d.ts +3 -0
  78. package/dist/core/session-manager.d.ts.map +1 -1
  79. package/dist/core/session-manager.js +34 -17
  80. package/dist/core/session-manager.js.map +1 -1
  81. package/dist/core/session-resident-store.d.ts +16 -0
  82. package/dist/core/session-resident-store.d.ts.map +1 -0
  83. package/dist/core/session-resident-store.js +48 -0
  84. package/dist/core/session-resident-store.js.map +1 -0
  85. package/dist/core/settings-manager.d.ts +4 -0
  86. package/dist/core/settings-manager.d.ts.map +1 -1
  87. package/dist/core/settings-manager.js +9 -0
  88. package/dist/core/settings-manager.js.map +1 -1
  89. package/dist/core/trust-manager.d.ts +22 -0
  90. package/dist/core/trust-manager.d.ts.map +1 -1
  91. package/dist/core/trust-manager.js +75 -22
  92. package/dist/core/trust-manager.js.map +1 -1
  93. package/dist/index.d.ts +5 -5
  94. package/dist/index.d.ts.map +1 -1
  95. package/dist/index.js +2 -2
  96. package/dist/index.js.map +1 -1
  97. package/dist/main.d.ts.map +1 -1
  98. package/dist/main.js +92 -129
  99. package/dist/main.js.map +1 -1
  100. package/dist/migrations.d.ts.map +1 -1
  101. package/dist/migrations.js +39 -34
  102. package/dist/migrations.js.map +1 -1
  103. package/dist/modes/index.d.ts +1 -1
  104. package/dist/modes/index.d.ts.map +1 -1
  105. package/dist/modes/index.js.map +1 -1
  106. package/dist/modes/interactive/components/login-dialog.d.ts +1 -0
  107. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  108. package/dist/modes/interactive/components/login-dialog.js +7 -1
  109. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  110. package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
  111. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  112. package/dist/modes/interactive/components/settings-selector.js +20 -0
  113. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  114. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  115. package/dist/modes/interactive/components/tool-execution.js +26 -4
  116. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  117. package/dist/modes/interactive/components/trust-selector.d.ts +6 -3
  118. package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -1
  119. package/dist/modes/interactive/components/trust-selector.js +22 -18
  120. package/dist/modes/interactive/components/trust-selector.js.map +1 -1
  121. package/dist/modes/interactive/interactive-mode.d.ts +15 -0
  122. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  123. package/dist/modes/interactive/interactive-mode.js +158 -19
  124. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  125. package/dist/modes/interactive/working-status.d.ts +2 -0
  126. package/dist/modes/interactive/working-status.d.ts.map +1 -1
  127. package/dist/modes/interactive/working-status.js +34 -0
  128. package/dist/modes/interactive/working-status.js.map +1 -1
  129. package/dist/package-manager-cli.d.ts +6 -2
  130. package/dist/package-manager-cli.d.ts.map +1 -1
  131. package/dist/package-manager-cli.js +58 -11
  132. package/dist/package-manager-cli.js.map +1 -1
  133. package/dist/senpi +10 -1
  134. package/dist/utils/changelog.d.ts +1 -0
  135. package/dist/utils/changelog.d.ts.map +1 -1
  136. package/dist/utils/changelog.js +78 -0
  137. package/dist/utils/changelog.js.map +1 -1
  138. package/docs/docs.json +4 -0
  139. package/docs/extensions.md +30 -1
  140. package/docs/index.md +1 -0
  141. package/docs/models.md +6 -39
  142. package/docs/packages.md +0 -2
  143. package/docs/prompt-templates.md +8 -1
  144. package/docs/sdk.md +5 -0
  145. package/docs/security.md +55 -0
  146. package/docs/settings.md +7 -4
  147. package/docs/terminal-setup.md +36 -2
  148. package/docs/tmux.md +4 -2
  149. package/docs/usage.md +12 -7
  150. package/examples/extensions/README.md +1 -0
  151. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  152. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  153. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  154. package/examples/extensions/gondolin/package-lock.json +2 -2
  155. package/examples/extensions/gondolin/package.json +1 -1
  156. package/examples/extensions/project-trust.ts +64 -0
  157. package/examples/extensions/sandbox/package-lock.json +2 -2
  158. package/examples/extensions/sandbox/package.json +1 -1
  159. package/examples/extensions/with-deps/package-lock.json +2 -2
  160. package/examples/extensions/with-deps/package.json +1 -1
  161. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +125 -77
  162. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  163. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.d.ts +1 -1
  164. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.d.ts.map +1 -1
  165. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.js +1 -1
  166. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.js.map +1 -1
  167. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +6 -3
  168. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
  169. package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
  170. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  171. package/node_modules/@earendil-works/pi-ai/README.md +2 -1
  172. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts +2 -2
  173. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +6 -6
  174. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
  175. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +373 -116
  176. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
  177. package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +353 -202
  178. package/node_modules/@earendil-works/pi-ai/dist/models.generated.js.map +1 -1
  179. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.d.ts.map +1 -1
  180. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js +15 -7
  181. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  182. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.d.ts +1 -1
  183. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  184. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js +17 -7
  185. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js.map +1 -1
  186. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.js +1 -0
  187. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
  188. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  189. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js +4 -3
  190. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js.map +1 -1
  191. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses-shared.d.ts.map +1 -1
  192. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses-shared.js +2 -1
  193. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses-shared.js.map +1 -1
  194. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
  195. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.js +3 -2
  196. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.js.map +1 -1
  197. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.d.ts +1 -1
  198. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  199. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.js +2 -2
  200. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.js.map +1 -1
  201. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +5 -1
  202. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  203. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  204. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  205. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts +2 -0
  206. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts.map +1 -1
  207. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.js.map +1 -1
  208. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts +6 -1
  209. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +1 -1
  210. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +89 -39
  211. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +1 -1
  212. package/node_modules/@earendil-works/pi-tui/dist/components/loader.d.ts +5 -0
  213. package/node_modules/@earendil-works/pi-tui/dist/components/loader.d.ts.map +1 -1
  214. package/node_modules/@earendil-works/pi-tui/dist/components/loader.js +18 -4
  215. package/node_modules/@earendil-works/pi-tui/dist/components/loader.js.map +1 -1
  216. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.d.ts.map +1 -1
  217. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js +131 -61
  218. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js.map +1 -1
  219. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts +4 -7
  220. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
  221. package/node_modules/@earendil-works/pi-tui/dist/terminal.js +38 -76
  222. package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -1
  223. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +1 -1
  224. package/node_modules/@earendil-works/pi-tui/dist/tui.js +14 -4
  225. package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
  226. package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts.map +1 -1
  227. package/node_modules/@earendil-works/pi-tui/dist/utils.js +43 -15
  228. package/node_modules/@earendil-works/pi-tui/dist/utils.js.map +1 -1
  229. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  230. package/npm-shrinkwrap.json +12 -12
  231. package/package.json +4 -8
  232. package/dist/core/extensions/builtin/todotools/continuation/config.d.ts +0 -10
  233. package/dist/core/extensions/builtin/todotools/continuation/config.d.ts.map +0 -1
  234. package/dist/core/extensions/builtin/todotools/continuation/config.js +0 -33
  235. package/dist/core/extensions/builtin/todotools/continuation/config.js.map +0 -1
  236. package/dist/core/extensions/builtin/todotools/continuation/index.d.ts +0 -2
  237. package/dist/core/extensions/builtin/todotools/continuation/index.d.ts.map +0 -1
  238. package/dist/core/extensions/builtin/todotools/continuation/index.js +0 -2
  239. package/dist/core/extensions/builtin/todotools/continuation/index.js.map +0 -1
  240. package/dist/core/extensions/builtin/todotools/continuation/prompt.d.ts +0 -5
  241. package/dist/core/extensions/builtin/todotools/continuation/prompt.d.ts.map +0 -1
  242. package/dist/core/extensions/builtin/todotools/continuation/prompt.js +0 -34
  243. package/dist/core/extensions/builtin/todotools/continuation/prompt.js.map +0 -1
  244. package/dist/core/extensions/builtin/todotools/continuation/runtime.d.ts +0 -11
  245. package/dist/core/extensions/builtin/todotools/continuation/runtime.d.ts.map +0 -1
  246. package/dist/core/extensions/builtin/todotools/continuation/runtime.js +0 -201
  247. package/dist/core/extensions/builtin/todotools/continuation/runtime.js.map +0 -1
  248. package/dist/core/extensions/builtin/todotools/settings.d.ts +0 -6
  249. package/dist/core/extensions/builtin/todotools/settings.d.ts.map +0 -1
  250. package/dist/core/extensions/builtin/todotools/settings.js +0 -58
  251. package/dist/core/extensions/builtin/todotools/settings.js.map +0 -1
  252. package/dist/core/extensions/builtin/todotools/system-messages.d.ts +0 -34
  253. package/dist/core/extensions/builtin/todotools/system-messages.d.ts.map +0 -1
  254. package/dist/core/extensions/builtin/todotools/system-messages.js +0 -82
  255. package/dist/core/extensions/builtin/todotools/system-messages.js.map +0 -1
@@ -6,6 +6,7 @@ import { createInterface } from "readline";
6
6
  import { StringDecoder } from "string_decoder";
7
7
  import { getAgentDir as getDefaultAgentDir, getSessionsDir } from "../config.js";
8
8
  import { normalizePath, resolvePath } from "../utils/paths.js";
9
+ import { ResidentStringStore } from "./session-resident-store.js";
9
10
  // Fork change: inlined UUIDv7 (upstream uses the `uuid` npm package). Keeps this
10
11
  // package self-contained so consumers don't need a transitive `uuid` install.
11
12
  function uuidv7() {
@@ -529,6 +530,7 @@ export class SessionManager {
529
530
  this.labelsById = new Map();
530
531
  this.labelTimestampsById = new Map();
531
532
  this.leafId = null;
533
+ this.residentStore = new ResidentStringStore();
532
534
  this.cwd = resolvePath(cwd);
533
535
  this.sessionDir = normalizePath(sessionDir);
534
536
  this.persist = persist;
@@ -545,6 +547,7 @@ export class SessionManager {
545
547
  /** Switch to a different session file (used for resume and branching) */
546
548
  setSessionFile(sessionFile) {
547
549
  this.sessionFile = resolvePath(sessionFile);
550
+ this.residentStore.clear();
548
551
  if (existsSync(this.sessionFile)) {
549
552
  this.fileEntries = loadEntriesFromFile(this.sessionFile);
550
553
  // If file was empty or corrupted (no valid header), truncate and start fresh
@@ -562,6 +565,7 @@ export class SessionManager {
562
565
  if (migrateToCurrentVersion(this.fileEntries)) {
563
566
  this._rewriteFile();
564
567
  }
568
+ this.fileEntries = this.fileEntries.map((entry) => this.residentStore.externalize(entry));
565
569
  this._buildIndex();
566
570
  this.flushed = true;
567
571
  }
@@ -586,8 +590,10 @@ export class SessionManager {
586
590
  parentSession: options?.parentSession,
587
591
  };
588
592
  this.fileEntries = [header];
593
+ this.residentStore.clear();
589
594
  this.byId.clear();
590
595
  this.labelsById.clear();
596
+ this.labelTimestampsById.clear();
591
597
  this.leafId = null;
592
598
  this.flushed = false;
593
599
  if (this.persist) {
@@ -624,7 +630,7 @@ export class SessionManager {
624
630
  const fd = openSync(this.sessionFile, "w");
625
631
  try {
626
632
  for (const entry of this.fileEntries) {
627
- writeFileSync(fd, `${JSON.stringify(entry)}\n`);
633
+ writeFileSync(fd, `${JSON.stringify(this.residentStore.materialize(entry))}\n`);
628
634
  }
629
635
  }
630
636
  finally {
@@ -649,13 +655,17 @@ export class SessionManager {
649
655
  getSessionFile() {
650
656
  return this.sessionFile;
651
657
  }
658
+ getResidentStoreStats() {
659
+ return this.residentStore.stats();
660
+ }
652
661
  _persist(entry) {
653
662
  if (!this.persist || !this.sessionFile)
654
663
  return;
664
+ const persistedEntry = this.residentStore.materialize(entry);
655
665
  const hasAssistant = this.fileEntries.some((e) => e.type === "message" && e.message.role === "assistant");
656
666
  if (!hasAssistant) {
657
667
  if (this.flushed) {
658
- appendFileSync(this.sessionFile, `${JSON.stringify(entry)}\n`);
668
+ appendFileSync(this.sessionFile, `${JSON.stringify(persistedEntry)}\n`);
659
669
  }
660
670
  else {
661
671
  // Mark as not flushed so when assistant arrives, all entries get written
@@ -667,7 +677,7 @@ export class SessionManager {
667
677
  const fd = openSync(this.sessionFile, "wx");
668
678
  try {
669
679
  for (const e of this.fileEntries) {
670
- writeFileSync(fd, `${JSON.stringify(e)}\n`);
680
+ writeFileSync(fd, `${JSON.stringify(this.residentStore.materialize(e))}\n`);
671
681
  }
672
682
  }
673
683
  finally {
@@ -676,14 +686,15 @@ export class SessionManager {
676
686
  this.flushed = true;
677
687
  }
678
688
  else {
679
- appendFileSync(this.sessionFile, `${JSON.stringify(entry)}\n`);
689
+ appendFileSync(this.sessionFile, `${JSON.stringify(persistedEntry)}\n`);
680
690
  }
681
691
  }
682
692
  _appendEntry(entry) {
683
- this.fileEntries.push(entry);
684
- this.byId.set(entry.id, entry);
685
- this.leafId = entry.id;
686
- this._persist(entry);
693
+ const residentEntry = this.residentStore.externalize(entry);
694
+ this.fileEntries.push(residentEntry);
695
+ this.byId.set(residentEntry.id, residentEntry);
696
+ this.leafId = residentEntry.id;
697
+ this._persist(residentEntry);
687
698
  }
688
699
  /** Append a message as child of current leaf, then advance leaf. Returns entry id.
689
700
  * Does not allow writing CompactionSummaryMessage and BranchSummaryMessage directly.
@@ -810,10 +821,12 @@ export class SessionManager {
810
821
  return this.leafId;
811
822
  }
812
823
  getLeafEntry() {
813
- return this.leafId ? this.byId.get(this.leafId) : undefined;
824
+ const entry = this.leafId ? this.byId.get(this.leafId) : undefined;
825
+ return entry ? this.residentStore.materialize(entry) : undefined;
814
826
  }
815
827
  getEntry(id) {
816
- return this.byId.get(id);
828
+ const entry = this.byId.get(id);
829
+ return entry ? this.residentStore.materialize(entry) : undefined;
817
830
  }
818
831
  /**
819
832
  * Get all direct children of an entry.
@@ -822,7 +835,7 @@ export class SessionManager {
822
835
  const children = [];
823
836
  for (const entry of this.byId.values()) {
824
837
  if (entry.parentId === parentId) {
825
- children.push(entry);
838
+ children.push(this.residentStore.materialize(entry));
826
839
  }
827
840
  }
828
841
  return children;
@@ -871,7 +884,7 @@ export class SessionManager {
871
884
  const startId = fromId ?? this.leafId;
872
885
  let current = startId ? this.byId.get(startId) : undefined;
873
886
  while (current) {
874
- path.unshift(current);
887
+ path.unshift(this.residentStore.materialize(current));
875
888
  current = current.parentId ? this.byId.get(current.parentId) : undefined;
876
889
  }
877
890
  return path;
@@ -881,14 +894,14 @@ export class SessionManager {
881
894
  * Uses tree traversal from current leaf.
882
895
  */
883
896
  buildSessionContext() {
884
- return buildSessionContext(this.getEntries(), this.leafId, this.byId);
897
+ return buildSessionContext(this.getEntries(), this.leafId);
885
898
  }
886
899
  /**
887
900
  * Get session header.
888
901
  */
889
902
  getHeader() {
890
903
  const h = this.fileEntries.find((e) => e.type === "session");
891
- return h ? h : null;
904
+ return h ? this.residentStore.materialize(h) : null;
892
905
  }
893
906
  /**
894
907
  * Get all session entries (excludes header). Returns a shallow copy.
@@ -896,7 +909,9 @@ export class SessionManager {
896
909
  * change the leaf pointer. Entries cannot be modified or deleted.
897
910
  */
898
911
  getEntries() {
899
- return this.fileEntries.filter((e) => e.type !== "session");
912
+ return this.fileEntries
913
+ .filter((e) => e.type !== "session")
914
+ .map((entry) => this.residentStore.materialize(entry));
900
915
  }
901
916
  /**
902
917
  * Get the session as a tree structure. Returns a shallow defensive copy of all entries.
@@ -1037,7 +1052,8 @@ export class SessionManager {
1037
1052
  labelEntries.push(labelEntry);
1038
1053
  parentId = labelEntry.id;
1039
1054
  }
1040
- this.fileEntries = [header, ...pathWithoutLabels, ...labelEntries];
1055
+ this.residentStore.clear();
1056
+ this.fileEntries = [header, ...pathWithoutLabels, ...labelEntries].map((entry) => this.residentStore.externalize(entry));
1041
1057
  this.sessionId = newSessionId;
1042
1058
  this.sessionFile = newSessionFile;
1043
1059
  this._buildIndex();
@@ -1071,7 +1087,8 @@ export class SessionManager {
1071
1087
  labelEntries.push(labelEntry);
1072
1088
  parentId = labelEntry.id;
1073
1089
  }
1074
- this.fileEntries = [header, ...pathWithoutLabels, ...labelEntries];
1090
+ this.residentStore.clear();
1091
+ this.fileEntries = [header, ...pathWithoutLabels, ...labelEntries].map((entry) => this.residentStore.externalize(entry));
1075
1092
  this.sessionId = newSessionId;
1076
1093
  this._buildIndex();
1077
1094
  return undefined;