@dyyz1993/pi-coding-agent 0.70.5 → 0.74.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.
Files changed (301) hide show
  1. package/CHANGELOG.md +266 -80
  2. package/README.md +48 -20
  3. package/dist/bun/cli.d.ts.map +1 -1
  4. package/dist/bun/cli.js +4 -2
  5. package/dist/bun/cli.js.map +1 -1
  6. package/dist/bun/restore-sandbox-env.d.ts +13 -0
  7. package/dist/bun/restore-sandbox-env.d.ts.map +1 -0
  8. package/dist/bun/restore-sandbox-env.js +32 -0
  9. package/dist/bun/restore-sandbox-env.js.map +1 -0
  10. package/dist/cli/args.d.ts +2 -1
  11. package/dist/cli/args.d.ts.map +1 -1
  12. package/dist/cli/args.js +34 -22
  13. package/dist/cli/args.js.map +1 -1
  14. package/dist/cli/list-models.d.ts.map +1 -1
  15. package/dist/cli/list-models.js +2 -1
  16. package/dist/cli/list-models.js.map +1 -1
  17. package/dist/cli.d.ts.map +1 -1
  18. package/dist/cli.js +9 -4
  19. package/dist/cli.js.map +1 -1
  20. package/dist/config.d.ts +16 -8
  21. package/dist/config.d.ts.map +1 -1
  22. package/dist/config.js +238 -66
  23. package/dist/config.js.map +1 -1
  24. package/dist/core/agent-session-runtime.d.ts +10 -0
  25. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  26. package/dist/core/agent-session-runtime.js +14 -0
  27. package/dist/core/agent-session-runtime.js.map +1 -1
  28. package/dist/core/agent-session-services.d.ts +2 -1
  29. package/dist/core/agent-session-services.d.ts.map +1 -1
  30. package/dist/core/agent-session-services.js +1 -0
  31. package/dist/core/agent-session-services.js.map +1 -1
  32. package/dist/core/agent-session.d.ts +25 -26
  33. package/dist/core/agent-session.d.ts.map +1 -1
  34. package/dist/core/agent-session.js +1042 -1116
  35. package/dist/core/agent-session.js.map +1 -1
  36. package/dist/core/agent-types.d.ts +58 -0
  37. package/dist/core/agent-types.d.ts.map +1 -0
  38. package/dist/core/agent-types.js +203 -0
  39. package/dist/core/agent-types.js.map +1 -0
  40. package/dist/core/auth-guidance.d.ts +5 -0
  41. package/dist/core/auth-guidance.d.ts.map +1 -0
  42. package/dist/core/auth-guidance.js +21 -0
  43. package/dist/core/auth-guidance.js.map +1 -0
  44. package/dist/core/auth-storage.d.ts +9 -0
  45. package/dist/core/auth-storage.d.ts.map +1 -1
  46. package/dist/core/auth-storage.js +20 -1
  47. package/dist/core/auth-storage.js.map +1 -1
  48. package/dist/core/bash-executor.d.ts.map +1 -1
  49. package/dist/core/bash-executor.js +9 -6
  50. package/dist/core/bash-executor.js.map +1 -1
  51. package/dist/core/compaction/compaction.d.ts +0 -1
  52. package/dist/core/compaction/compaction.d.ts.map +1 -1
  53. package/dist/core/compaction/compaction.js.map +1 -1
  54. package/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
  55. package/dist/core/export-html/ansi-to-html.js +1 -1
  56. package/dist/core/export-html/ansi-to-html.js.map +1 -1
  57. package/dist/core/export-html/template.css +53 -4
  58. package/dist/core/export-html/template.js +84 -20
  59. package/dist/core/export-html/tool-renderer.d.ts +0 -6
  60. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  61. package/dist/core/export-html/tool-renderer.js +15 -2
  62. package/dist/core/export-html/tool-renderer.js.map +1 -1
  63. package/dist/core/extensions/channel-factory.d.ts +13 -0
  64. package/dist/core/extensions/channel-factory.d.ts.map +1 -0
  65. package/dist/core/extensions/channel-factory.js +19 -0
  66. package/dist/core/extensions/channel-factory.js.map +1 -0
  67. package/dist/core/extensions/channel-registry.d.ts +28 -0
  68. package/dist/core/extensions/channel-registry.d.ts.map +1 -0
  69. package/dist/core/extensions/channel-registry.js +12 -0
  70. package/dist/core/extensions/channel-registry.js.map +1 -0
  71. package/dist/core/extensions/index.d.ts +4 -1
  72. package/dist/core/extensions/index.d.ts.map +1 -1
  73. package/dist/core/extensions/index.js +1 -0
  74. package/dist/core/extensions/index.js.map +1 -1
  75. package/dist/core/extensions/loader.d.ts +0 -1
  76. package/dist/core/extensions/loader.d.ts.map +1 -1
  77. package/dist/core/extensions/loader.js +49 -137
  78. package/dist/core/extensions/loader.js.map +1 -1
  79. package/dist/core/extensions/runner.d.ts +24 -20
  80. package/dist/core/extensions/runner.d.ts.map +1 -1
  81. package/dist/core/extensions/runner.js +128 -253
  82. package/dist/core/extensions/runner.js.map +1 -1
  83. package/dist/core/extensions/server-channel.d.ts +8 -8
  84. package/dist/core/extensions/server-channel.d.ts.map +1 -1
  85. package/dist/core/extensions/server-channel.js.map +1 -1
  86. package/dist/core/extensions/types.d.ts +88 -60
  87. package/dist/core/extensions/types.d.ts.map +1 -1
  88. package/dist/core/extensions/types.js +10 -0
  89. package/dist/core/extensions/types.js.map +1 -1
  90. package/dist/core/file-store/file-snapshot-manager.d.ts +95 -0
  91. package/dist/core/file-store/file-snapshot-manager.d.ts.map +1 -0
  92. package/dist/core/file-store/file-snapshot-manager.js +508 -0
  93. package/dist/core/file-store/file-snapshot-manager.js.map +1 -0
  94. package/dist/core/file-store/index.d.ts +5 -0
  95. package/dist/core/file-store/index.d.ts.map +1 -0
  96. package/dist/core/file-store/index.js +3 -0
  97. package/dist/core/file-store/index.js.map +1 -0
  98. package/dist/core/messages.d.ts +10 -2
  99. package/dist/core/messages.d.ts.map +1 -1
  100. package/dist/core/messages.js +23 -6
  101. package/dist/core/messages.js.map +1 -1
  102. package/dist/core/model-registry.d.ts +19 -1
  103. package/dist/core/model-registry.d.ts.map +1 -1
  104. package/dist/core/model-registry.js +97 -16
  105. package/dist/core/model-registry.js.map +1 -1
  106. package/dist/core/model-resolver.d.ts.map +1 -1
  107. package/dist/core/model-resolver.js +24 -15
  108. package/dist/core/model-resolver.js.map +1 -1
  109. package/dist/core/package-manager.d.ts +1 -0
  110. package/dist/core/package-manager.d.ts.map +1 -1
  111. package/dist/core/package-manager.js +61 -35
  112. package/dist/core/package-manager.js.map +1 -1
  113. package/dist/core/provider-display-names.d.ts +2 -0
  114. package/dist/core/provider-display-names.d.ts.map +1 -0
  115. package/dist/core/provider-display-names.js +32 -0
  116. package/dist/core/provider-display-names.js.map +1 -0
  117. package/dist/core/resource-loader.d.ts.map +1 -1
  118. package/dist/core/resource-loader.js +9 -21
  119. package/dist/core/resource-loader.js.map +1 -1
  120. package/dist/core/sdk.d.ts +9 -1
  121. package/dist/core/sdk.d.ts.map +1 -1
  122. package/dist/core/sdk.js +39 -18
  123. package/dist/core/sdk.js.map +1 -1
  124. package/dist/core/session-manager.d.ts +27 -17
  125. package/dist/core/session-manager.d.ts.map +1 -1
  126. package/dist/core/session-manager.js +133 -47
  127. package/dist/core/session-manager.js.map +1 -1
  128. package/dist/core/settings-manager.d.ts +21 -3
  129. package/dist/core/settings-manager.d.ts.map +1 -1
  130. package/dist/core/settings-manager.js +51 -6
  131. package/dist/core/settings-manager.js.map +1 -1
  132. package/dist/core/skills.d.ts.map +1 -1
  133. package/dist/core/skills.js +3 -8
  134. package/dist/core/skills.js.map +1 -1
  135. package/dist/core/slash-commands.d.ts.map +1 -1
  136. package/dist/core/slash-commands.js +4 -3
  137. package/dist/core/slash-commands.js.map +1 -1
  138. package/dist/core/tools/bash.d.ts +0 -2
  139. package/dist/core/tools/bash.d.ts.map +1 -1
  140. package/dist/core/tools/bash.js +108 -154
  141. package/dist/core/tools/bash.js.map +1 -1
  142. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  143. package/dist/core/tools/edit-diff.js +3 -2
  144. package/dist/core/tools/edit-diff.js.map +1 -1
  145. package/dist/core/tools/edit.d.ts.map +1 -1
  146. package/dist/core/tools/edit.js +4 -3
  147. package/dist/core/tools/edit.js.map +1 -1
  148. package/dist/core/tools/find.d.ts.map +1 -1
  149. package/dist/core/tools/find.js +1 -1
  150. package/dist/core/tools/find.js.map +1 -1
  151. package/dist/core/tools/grep.d.ts.map +1 -1
  152. package/dist/core/tools/grep.js +1 -1
  153. package/dist/core/tools/grep.js.map +1 -1
  154. package/dist/core/tools/output-accumulator.d.ts +50 -0
  155. package/dist/core/tools/output-accumulator.d.ts.map +1 -0
  156. package/dist/core/tools/output-accumulator.js +178 -0
  157. package/dist/core/tools/output-accumulator.js.map +1 -0
  158. package/dist/core/tools/output-collector.d.ts +35 -0
  159. package/dist/core/tools/output-collector.d.ts.map +1 -0
  160. package/dist/core/tools/output-collector.js +79 -0
  161. package/dist/core/tools/output-collector.js.map +1 -0
  162. package/dist/core/tools/read.d.ts.map +1 -1
  163. package/dist/core/tools/read.js +70 -13
  164. package/dist/core/tools/read.js.map +1 -1
  165. package/dist/core/tools/spawn-managed.d.ts +18 -0
  166. package/dist/core/tools/spawn-managed.d.ts.map +1 -0
  167. package/dist/core/tools/spawn-managed.js +52 -0
  168. package/dist/core/tools/spawn-managed.js.map +1 -0
  169. package/dist/index.d.ts +7 -4
  170. package/dist/index.d.ts.map +1 -1
  171. package/dist/index.js +6 -2
  172. package/dist/index.js.map +1 -1
  173. package/dist/main.d.ts.map +1 -1
  174. package/dist/main.js +17 -39
  175. package/dist/main.js.map +1 -1
  176. package/dist/migrations.d.ts +1 -1
  177. package/dist/migrations.d.ts.map +1 -1
  178. package/dist/migrations.js +3 -3
  179. package/dist/migrations.js.map +1 -1
  180. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  181. package/dist/modes/interactive/components/config-selector.js +3 -1
  182. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  183. package/dist/modes/interactive/components/extension-selector.d.ts +1 -4
  184. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  185. package/dist/modes/interactive/components/extension-selector.js +14 -56
  186. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  187. package/dist/modes/interactive/components/login-dialog.d.ts +5 -1
  188. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  189. package/dist/modes/interactive/components/login-dialog.js +19 -4
  190. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  191. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  192. package/dist/modes/interactive/components/model-selector.js +1 -1
  193. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  194. package/dist/modes/interactive/components/oauth-selector.d.ts +18 -6
  195. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  196. package/dist/modes/interactive/components/oauth-selector.js +93 -25
  197. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  198. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  199. package/dist/modes/interactive/components/scoped-models-selector.js +1 -1
  200. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  201. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  202. package/dist/modes/interactive/components/session-selector.js +3 -7
  203. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  204. package/dist/modes/interactive/components/settings-selector.d.ts +5 -0
  205. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  206. package/dist/modes/interactive/components/settings-selector.js +53 -1
  207. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  208. package/dist/modes/interactive/interactive-mode.d.ts +20 -4
  209. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  210. package/dist/modes/interactive/interactive-mode.js +423 -186
  211. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  212. package/dist/modes/interactive/theme/dark.json +1 -1
  213. package/dist/modes/interactive/theme/light.json +1 -1
  214. package/dist/modes/print-mode.d.ts +3 -0
  215. package/dist/modes/print-mode.d.ts.map +1 -1
  216. package/dist/modes/print-mode.js +62 -19
  217. package/dist/modes/print-mode.js.map +1 -1
  218. package/dist/modes/rpc/rpc-client.d.ts +80 -60
  219. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  220. package/dist/modes/rpc/rpc-client.js +108 -93
  221. package/dist/modes/rpc/rpc-client.js.map +1 -1
  222. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  223. package/dist/modes/rpc/rpc-mode.js +106 -0
  224. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  225. package/dist/modes/rpc/rpc-types.d.ts +115 -0
  226. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  227. package/dist/modes/rpc/rpc-types.js.map +1 -1
  228. package/dist/package-manager-cli.d.ts.map +1 -1
  229. package/dist/package-manager-cli.js +238 -12
  230. package/dist/package-manager-cli.js.map +1 -1
  231. package/dist/utils/child-process.d.ts +1 -0
  232. package/dist/utils/child-process.d.ts.map +1 -1
  233. package/dist/utils/child-process.js +8 -0
  234. package/dist/utils/child-process.js.map +1 -1
  235. package/dist/utils/clipboard-image.d.ts.map +1 -1
  236. package/dist/utils/clipboard-image.js +2 -2
  237. package/dist/utils/clipboard-image.js.map +1 -1
  238. package/dist/utils/clipboard.d.ts.map +1 -1
  239. package/dist/utils/clipboard.js +84 -45
  240. package/dist/utils/clipboard.js.map +1 -1
  241. package/dist/utils/paths.d.ts +9 -0
  242. package/dist/utils/paths.d.ts.map +1 -1
  243. package/dist/utils/paths.js +31 -0
  244. package/dist/utils/paths.js.map +1 -1
  245. package/dist/utils/pi-user-agent.d.ts +2 -0
  246. package/dist/utils/pi-user-agent.d.ts.map +1 -0
  247. package/dist/utils/pi-user-agent.js +5 -0
  248. package/dist/utils/pi-user-agent.js.map +1 -0
  249. package/dist/utils/structured-output.d.ts +10 -0
  250. package/dist/utils/structured-output.d.ts.map +1 -0
  251. package/dist/utils/structured-output.js +57 -0
  252. package/dist/utils/structured-output.js.map +1 -0
  253. package/dist/utils/tools-manager.d.ts.map +1 -1
  254. package/dist/utils/tools-manager.js +6 -2
  255. package/dist/utils/tools-manager.js.map +1 -1
  256. package/dist/utils/version-check.d.ts +14 -0
  257. package/dist/utils/version-check.d.ts.map +1 -0
  258. package/dist/utils/version-check.js +77 -0
  259. package/dist/utils/version-check.js.map +1 -0
  260. package/docs/compaction.md +14 -14
  261. package/docs/custom-provider.md +40 -31
  262. package/docs/development.md +1 -1
  263. package/docs/docs.json +148 -0
  264. package/docs/extensions.md +116 -56
  265. package/docs/index.md +70 -0
  266. package/docs/json.md +4 -4
  267. package/docs/models.md +150 -3
  268. package/docs/packages.md +10 -5
  269. package/docs/providers.md +62 -17
  270. package/docs/quickstart.md +142 -0
  271. package/docs/rollback-architecture.md +693 -0
  272. package/docs/rollback-test-cases.md +412 -0
  273. package/docs/rpc.md +1 -1
  274. package/docs/sdk.md +26 -26
  275. package/docs/{session.md → session-format.md} +6 -6
  276. package/docs/sessions.md +137 -0
  277. package/docs/settings.md +52 -9
  278. package/docs/termux.md +1 -1
  279. package/docs/themes.md +2 -2
  280. package/docs/tui.md +20 -20
  281. package/docs/usage.md +277 -0
  282. package/examples/extensions/README.md +2 -4
  283. package/examples/extensions/border-status-editor.ts +150 -0
  284. package/examples/extensions/commands.ts +2 -2
  285. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  286. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  287. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  288. package/examples/extensions/custom-provider-qwen-cli/package.json +1 -1
  289. package/examples/extensions/dynamic-resources/dynamic.json +1 -1
  290. package/examples/extensions/git-checkpoint.ts +1 -1
  291. package/examples/extensions/handoff.ts +49 -11
  292. package/examples/extensions/plan-mode/index.ts +1 -1
  293. package/examples/extensions/sandbox/package-lock.json +5 -5
  294. package/examples/extensions/sandbox/package.json +1 -1
  295. package/examples/extensions/subagent/agents.ts +126 -0
  296. package/examples/extensions/with-deps/package-lock.json +2 -2
  297. package/examples/extensions/with-deps/package.json +1 -1
  298. package/examples/sdk/README.md +2 -2
  299. package/package.json +7 -15
  300. package/docs/tree.md +0 -233
  301. package/examples/extensions/antigravity-image-gen.ts +0 -418
@@ -3,7 +3,7 @@ import { appendFileSync, closeSync, existsSync, mkdirSync, openSync, readdirSync
3
3
  import { readdir, readFile, stat } from "fs/promises";
4
4
  import { join, resolve } from "path";
5
5
  import { v7 as uuidv7 } from "uuid";
6
- import { findCanonicalGitRoot, getAgentDir as getDefaultAgentDir, getSessionsDir } from "../config.js";
6
+ import { getAgentDir as getDefaultAgentDir, getSessionsDir } from "../config.js";
7
7
  import { createBranchSummaryMessage, createCompactionSummaryMessage, createCustomMessage, createFoldSummaryMessage, } from "./messages.js";
8
8
  export const CURRENT_SESSION_VERSION = 3;
9
9
  function createSessionId() {
@@ -158,27 +158,97 @@ export function buildSessionContext(entries, leafId, byId) {
158
158
  compaction = entry;
159
159
  }
160
160
  }
161
- // Build fold index: targetId -> FoldEntry
162
161
  const folds = new Map();
163
162
  for (const entry of path) {
164
163
  if (entry.type === "fold") {
165
164
  folds.set(entry.targetId, entry);
166
165
  }
167
166
  }
168
- // Build messages and collect corresponding entries
169
- // When there's a compaction, we need to:
170
- // 1. Emit summary first (entry = compaction)
171
- // 2. Emit kept messages (from firstKeptEntryId up to compaction)
172
- // 3. Emit messages after compaction
167
+ const deletedIds = new Set();
168
+ for (const entry of path) {
169
+ if (entry.type === "deletion") {
170
+ for (const targetId of entry.targetIds) {
171
+ deletedIds.add(targetId);
172
+ }
173
+ }
174
+ }
175
+ const deletedToolCallIds = new Set();
176
+ for (const entry of path) {
177
+ if (entry.type === "message" && deletedIds.has(entry.id)) {
178
+ const msg = entry.message;
179
+ if (msg.role === "assistant" && Array.isArray(msg.content)) {
180
+ for (const part of msg.content) {
181
+ if (part.type === "toolCall" && part.id) {
182
+ deletedToolCallIds.add(part.id);
183
+ }
184
+ }
185
+ }
186
+ }
187
+ }
188
+ for (const entry of path) {
189
+ if (entry.type === "message" && entry.message.role === "toolResult") {
190
+ if (deletedToolCallIds.has(entry.message.toolCallId)) {
191
+ deletedIds.add(entry.id);
192
+ }
193
+ }
194
+ }
195
+ const strippedToolCallIds = new Set();
196
+ for (const entry of path) {
197
+ if (entry.type === "message" && deletedIds.has(entry.id) && entry.message.role === "toolResult") {
198
+ strippedToolCallIds.add(entry.message.toolCallId);
199
+ }
200
+ }
201
+ const segmentTargets = new Map();
202
+ for (const entry of path) {
203
+ if (entry.type === "segment_summary") {
204
+ const seg = entry;
205
+ if (seg.targetIds.length === 0)
206
+ continue;
207
+ for (let i = 0; i < seg.targetIds.length; i++) {
208
+ const targetId = seg.targetIds[i];
209
+ if (deletedIds.has(targetId))
210
+ continue;
211
+ if (segmentTargets.has(targetId))
212
+ continue;
213
+ segmentTargets.set(targetId, {
214
+ summary: seg.summary,
215
+ isFirst: i === 0,
216
+ timestamp: entry.timestamp,
217
+ });
218
+ }
219
+ }
220
+ }
173
221
  const messages = [];
174
222
  const appendMessage = (entry) => {
175
223
  if (entry.type === "message") {
224
+ if (deletedIds.has(entry.id))
225
+ return;
226
+ const segInfo = segmentTargets.get(entry.id);
227
+ if (segInfo) {
228
+ if (segInfo.isFirst) {
229
+ messages.push({
230
+ role: "segmentSummary",
231
+ summary: segInfo.summary,
232
+ timestamp: new Date(segInfo.timestamp).getTime(),
233
+ });
234
+ }
235
+ return;
236
+ }
176
237
  const fold = folds.get(entry.id);
177
238
  if (fold) {
178
239
  messages.push(createFoldSummaryMessage(fold.summary, fold.originalTokens, entry.timestamp));
179
240
  }
180
241
  else {
181
- messages.push(entry.message);
242
+ let msg = entry.message;
243
+ if (msg.role === "assistant" && Array.isArray(msg.content) && strippedToolCallIds.size > 0) {
244
+ const content = msg.content;
245
+ const needsStrip = content.some((part) => part.type === "toolCall" && part.id !== undefined && strippedToolCallIds.has(part.id));
246
+ if (needsStrip) {
247
+ const filteredContent = content.filter((part) => !(part.type === "toolCall" && part.id !== undefined && strippedToolCallIds.has(part.id)));
248
+ msg = { ...msg, content: filteredContent };
249
+ }
250
+ }
251
+ messages.push(msg);
182
252
  }
183
253
  }
184
254
  else if (entry.type === "custom_message") {
@@ -221,12 +291,9 @@ export function buildSessionContext(entries, leafId, byId) {
221
291
  /**
222
292
  * Compute the default session directory for a cwd.
223
293
  * Encodes cwd into a safe directory name under ~/.pi/agent/sessions/.
224
- * If the cwd is inside a git worktree, uses the canonical git root
225
- * so all worktrees of the same repo share session history.
226
294
  */
227
295
  export function getDefaultSessionDir(cwd, agentDir = getDefaultAgentDir()) {
228
- const projectRoot = findCanonicalGitRoot(cwd) ?? cwd;
229
- const safePath = `--${projectRoot.replace(/^[/\\]/, "").replace(/[/\\:]/g, "-")}--`;
296
+ const safePath = `--${cwd.replace(/^[/\\]/, "").replace(/[/\\:]/g, "-")}--`;
230
297
  const sessionDir = join(agentDir, "sessions", safePath);
231
298
  if (!existsSync(sessionDir)) {
232
299
  mkdirSync(sessionDir, { recursive: true });
@@ -362,15 +429,11 @@ async function buildSessionInfo(filePath) {
362
429
  let firstMessage = "";
363
430
  const allMessages = [];
364
431
  let name;
365
- let effectiveCwd;
366
432
  for (const entry of entries) {
367
- // Extract session name and cwd override (use latest, including explicit clears)
433
+ // Extract session name (use latest, including explicit clears)
368
434
  if (entry.type === "session_info") {
369
435
  const infoEntry = entry;
370
436
  name = infoEntry.name?.trim() || undefined;
371
- if (infoEntry.cwd) {
372
- effectiveCwd = infoEntry.cwd;
373
- }
374
437
  }
375
438
  if (entry.type !== "message")
376
439
  continue;
@@ -388,7 +451,7 @@ async function buildSessionInfo(filePath) {
388
451
  firstMessage = textContent;
389
452
  }
390
453
  }
391
- const cwd = effectiveCwd ?? (typeof header.cwd === "string" ? header.cwd : "");
454
+ const cwd = typeof header.cwd === "string" ? header.cwd : "";
392
455
  const parentSessionPath = header.parentSession;
393
456
  const modified = getSessionModifiedDate(entries, header, stats.mtime);
394
457
  return {
@@ -554,14 +617,8 @@ export class SessionManager {
554
617
  isPersisted() {
555
618
  return this.persist;
556
619
  }
557
- flush() {
558
- if (!this.persist || !this.sessionFile)
559
- return;
560
- this._rewriteFile();
561
- this.flushed = true;
562
- }
563
620
  getCwd() {
564
- return this.getEffectiveCwd();
621
+ return this.cwd;
565
622
  }
566
623
  getSessionDir() {
567
624
  return this.sessionDir;
@@ -591,6 +648,15 @@ export class SessionManager {
591
648
  appendFileSync(this.sessionFile, `${JSON.stringify(entry)}\n`);
592
649
  }
593
650
  }
651
+ /** Force-flush all pending file entries to disk. */
652
+ flush() {
653
+ if (!this.persist || !this.sessionFile || this.flushed)
654
+ return;
655
+ for (const e of this.fileEntries) {
656
+ appendFileSync(this.sessionFile, `${JSON.stringify(e)}\n`);
657
+ }
658
+ this.flushed = true;
659
+ }
594
660
  _appendEntry(entry) {
595
661
  this.fileEntries.push(entry);
596
662
  this.byId.set(entry.id, entry);
@@ -639,6 +705,18 @@ export class SessionManager {
639
705
  this._appendEntry(entry);
640
706
  return entry.id;
641
707
  }
708
+ /** Append a tier models change as child of current leaf, then advance leaf. Returns entry id. */
709
+ appendTierModelsChange(tierModels) {
710
+ const entry = {
711
+ type: "tier_models_change",
712
+ id: generateId(this.byId),
713
+ parentId: this.leafId,
714
+ timestamp: new Date().toISOString(),
715
+ tierModels,
716
+ };
717
+ this._appendEntry(entry);
718
+ return entry.id;
719
+ }
642
720
  /** Append a compaction summary as child of current leaf, then advance leaf. Returns entry id. */
643
721
  appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromHook) {
644
722
  const entry = {
@@ -656,12 +734,11 @@ export class SessionManager {
656
734
  return entry.id;
657
735
  }
658
736
  /** Append a custom entry (for extensions) as child of current leaf, then advance leaf. Returns entry id. */
659
- appendCustomEntry(customType, data, options) {
737
+ appendCustomEntry(customType, data, _options) {
660
738
  const entry = {
661
739
  type: "custom",
662
740
  customType,
663
741
  data,
664
- display: options?.display,
665
742
  id: generateId(this.byId),
666
743
  parentId: this.leafId,
667
744
  timestamp: new Date().toISOString(),
@@ -683,8 +760,33 @@ export class SessionManager {
683
760
  this._appendEntry(entry);
684
761
  return entry.id;
685
762
  }
686
- /** Append a session info entry (e.g., display name, cwd override). Returns entry id. */
687
- appendSessionInfo(name, cwd) {
763
+ /** Append a deletion entry that excludes target messages from LLM context. Returns entry id. */
764
+ appendDeletion(targetIds) {
765
+ const entry = {
766
+ type: "deletion",
767
+ targetIds,
768
+ id: generateId(this.byId),
769
+ parentId: this.leafId,
770
+ timestamp: new Date().toISOString(),
771
+ };
772
+ this._appendEntry(entry);
773
+ return entry.id;
774
+ }
775
+ /** Append a segment summary entry that replaces target messages with a summary in LLM context. Returns entry id. */
776
+ appendSegmentSummary(targetIds, summary) {
777
+ const entry = {
778
+ type: "segment_summary",
779
+ targetIds,
780
+ summary,
781
+ id: generateId(this.byId),
782
+ parentId: this.leafId,
783
+ timestamp: new Date().toISOString(),
784
+ };
785
+ this._appendEntry(entry);
786
+ return entry.id;
787
+ }
788
+ /** Append a session info entry (e.g., display name). Returns entry id. */
789
+ appendSessionInfo(name) {
688
790
  const entry = {
689
791
  type: "session_info",
690
792
  id: generateId(this.byId),
@@ -694,26 +796,9 @@ export class SessionManager {
694
796
  if (name !== undefined) {
695
797
  entry.name = name.trim();
696
798
  }
697
- if (cwd !== undefined) {
698
- entry.cwd = cwd;
699
- }
700
799
  this._appendEntry(entry);
701
800
  return entry.id;
702
801
  }
703
- /** Get the effective cwd, considering session_info overrides. */
704
- getEffectiveCwd() {
705
- const entries = this.getEntries();
706
- for (let i = entries.length - 1; i >= 0; i--) {
707
- const entry = entries[i];
708
- if (entry.type === "session_info") {
709
- const infoEntry = entry;
710
- if (infoEntry.cwd) {
711
- return infoEntry.cwd;
712
- }
713
- }
714
- }
715
- return this.cwd;
716
- }
717
802
  /** Get the current session name from the latest session_info entry, if any. */
718
803
  getSessionName() {
719
804
  // Walk entries in reverse to find the latest session_info entry.
@@ -938,7 +1023,7 @@ export class SessionManager {
938
1023
  * Returns the new session file path, or undefined if not persisting.
939
1024
  */
940
1025
  createBranchedSession(leafId) {
941
- const _previousSessionFile = this.sessionFile;
1026
+ const previousSessionFile = this.sessionFile;
942
1027
  const path = this.getBranch(leafId);
943
1028
  if (path.length === 0) {
944
1029
  throw new Error(`Entry ${leafId} not found`);
@@ -955,6 +1040,7 @@ export class SessionManager {
955
1040
  id: newSessionId,
956
1041
  timestamp,
957
1042
  cwd: this.cwd,
1043
+ parentSession: this.persist ? previousSessionFile : undefined,
958
1044
  };
959
1045
  // Collect labels for entries in the path
960
1046
  const pathEntryIds = new Set(pathWithoutLabels.map((e) => e.id));