@cryptiklemur/lattice 5.10.0 → 5.11.0

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 (142) hide show
  1. package/dist/client/assets/{angular-html-BDIcxkJq.js → angular-html-BoFzmWT8.js} +1 -1
  2. package/dist/client/assets/{angular-ts-Bt22ouNH.js → angular-ts-DZnI8rKE.js} +1 -1
  3. package/dist/client/assets/{apl-p8qkxzEK.js → apl-DstVmncE.js} +1 -1
  4. package/dist/client/assets/{astro-CIaMc49M.js → astro-DTPCjzEx.js} +1 -1
  5. package/dist/client/assets/{blade-BR56EAMD.js → blade-6q42Ss3F.js} +1 -1
  6. package/dist/client/assets/{c-Dli0HzAh.js → c-BQDGJ-nQ.js} +1 -1
  7. package/dist/client/assets/{cobol-Cad15ECy.js → cobol-Dlh0WvsZ.js} +1 -1
  8. package/dist/client/assets/{coffee-DpyATEbF.js → coffee-DdQv129j.js} +1 -1
  9. package/dist/client/assets/{cpp-KN8_NFsf.js → cpp-DhbQJIv4.js} +1 -1
  10. package/dist/client/assets/{crystal-CuyGv0kh.js → crystal-C22kERUB.js} +1 -1
  11. package/dist/client/assets/{css-Cm3q4bxn.js → css-n31O5kHj.js} +1 -1
  12. package/dist/client/assets/{dist-BjxsMc4u.js → dist-D8okl7lw.js} +2 -2
  13. package/dist/client/assets/{edge-B6S7CSbx.js → edge-Cgwx-o_7.js} +1 -1
  14. package/dist/client/assets/{elixir-CNUy9H8T.js → elixir-DAGM2WKD.js} +1 -1
  15. package/dist/client/assets/{elm-CNfcWmb9.js → elm-BLw_7oO9.js} +1 -1
  16. package/dist/client/assets/{erb-DWebzDaI.js → erb-DCaNhYa7.js} +1 -1
  17. package/dist/client/assets/{git-rebase-B_Pt2ZBK.js → git-rebase-CNNhb8-g.js} +1 -1
  18. package/dist/client/assets/{glimmer-js-CVwoOd72.js → glimmer-js-BnZd88Wi.js} +1 -1
  19. package/dist/client/assets/{glimmer-ts-CjtFSxjz.js → glimmer-ts-DvFNbZu-.js} +1 -1
  20. package/dist/client/assets/{glsl-CP4rggAA.js → glsl-Dnrk_Jnx.js} +1 -1
  21. package/dist/client/assets/{graphql-Dbm6sAtp.js → graphql-DlWTPvCG.js} +1 -1
  22. package/dist/client/assets/{hack-Bj9y3SGf.js → hack-DQg1Ek33.js} +1 -1
  23. package/dist/client/assets/{haml-DRGrdf3f.js → haml-DSk45qIE.js} +1 -1
  24. package/dist/client/assets/{handlebars-CFKjcBMg.js → handlebars-DuLvATB2.js} +1 -1
  25. package/dist/client/assets/{html-Vcd4eHHg.js → html-D4DiUnLg.js} +1 -1
  26. package/dist/client/assets/{html-derivative-BF0YbD4L.js → html-derivative-CS5MZ6d9.js} +1 -1
  27. package/dist/client/assets/{http-CGVTa2NT.js → http-CkDncfer.js} +1 -1
  28. package/dist/client/assets/{hurl-B0GrsGqd.js → hurl-DU39oO3U.js} +1 -1
  29. package/dist/client/assets/{index-CX1tudsF.js → index-CHPfE1Zl.js} +129 -129
  30. package/dist/client/assets/index-DHUKmLLC.css +2 -0
  31. package/dist/client/assets/{java-BJHQqHsm.js → java-lntACKEu.js} +1 -1
  32. package/dist/client/assets/{javascript-CmuMsKrc.js → javascript-CxkFc6nV.js} +1 -1
  33. package/dist/client/assets/{jinja-JxCLeq1j.js → jinja-DolO2zO7.js} +1 -1
  34. package/dist/client/assets/{jison-BdgAUhei.js → jison-Cok5FPev.js} +1 -1
  35. package/dist/client/assets/{json-DtPissHL.js → json-BebuQPrq.js} +1 -1
  36. package/dist/client/assets/{jsx-DUAxxDkP.js → jsx-iLBaUyXr.js} +1 -1
  37. package/dist/client/assets/{julia-DxDlbL6e.js → julia-C5Dsc7cH.js} +1 -1
  38. package/dist/client/assets/{just-CVmAAx2R.js → just-DJYqq_9R.js} +1 -1
  39. package/dist/client/assets/{latex-uwxggTWA.js → latex-BTTYiKj1.js} +1 -1
  40. package/dist/client/assets/{liquid-xsETAJJy.js → liquid-DpAKCrOB.js} +1 -1
  41. package/dist/client/assets/{lua-B2Hh8PgD.js → lua-BZ6b1hko.js} +1 -1
  42. package/dist/client/assets/{marko-yDeGxD87.js → marko-D8VK6iGt.js} +1 -1
  43. package/dist/client/assets/{mdc-QMp4ieYR.js → mdc-Paa3XzwY.js} +1 -1
  44. package/dist/client/assets/{nginx-7gmRmcqz.js → nginx-C5k9mWtJ.js} +1 -1
  45. package/dist/client/assets/{nim-CA8SNY_7.js → nim-Dst6YSnE.js} +1 -1
  46. package/dist/client/assets/{perl-lx5nW4VC.js → perl-XhiCjgBp.js} +1 -1
  47. package/dist/client/assets/{php-DgHiW953.js → php-BcsPLnLU.js} +1 -1
  48. package/dist/client/assets/{pug-CbbB1vwb.js → pug-GLH9-eAJ.js} +1 -1
  49. package/dist/client/assets/{qml-COrzwCIh.js → qml-Cj_lJioE.js} +1 -1
  50. package/dist/client/assets/{r-Dv7pZJDH.js → r-B70aGYK5.js} +1 -1
  51. package/dist/client/assets/{razor-D2m8EDP5.js → razor-R3gub_zy.js} +1 -1
  52. package/dist/client/assets/{regexp-BXLT-jPc.js → regexp-itC0dIUJ.js} +1 -1
  53. package/dist/client/assets/{rst-_S6rrUYh.js → rst-DdyoV8E2.js} +1 -1
  54. package/dist/client/assets/{ruby-C3XO7tYY.js → ruby-BYBZsv66.js} +1 -1
  55. package/dist/client/assets/{sas-DP2k4iuN.js → sas-fqfqXqj1.js} +1 -1
  56. package/dist/client/assets/{scss-lhLFMXGn.js → scss-B-ELv6mu.js} +1 -1
  57. package/dist/client/assets/{shellscript-BYlBPHen.js → shellscript-BgB8TNw6.js} +1 -1
  58. package/dist/client/assets/{shellsession-CbVyQKWZ.js → shellsession-BLK2Dgkm.js} +1 -1
  59. package/dist/client/assets/{soy-Be8a0lHq.js → soy-C7_RmNrp.js} +1 -1
  60. package/dist/client/assets/{sql-2KxvU9YS.js → sql-AUgbUJq4.js} +1 -1
  61. package/dist/client/assets/{stata-BxlWftTS.js → stata-CIVqSIOr.js} +1 -1
  62. package/dist/client/assets/{surrealql-CJ-q86nR.js → surrealql-BzRQzc5S.js} +1 -1
  63. package/dist/client/assets/{svelte-Q1ml0OiY.js → svelte-BCIwEwtb.js} +1 -1
  64. package/dist/client/assets/{templ-BbfPZhtu.js → templ-C1hbwe4u.js} +1 -1
  65. package/dist/client/assets/{tex-Dcth4Gi6.js → tex-CI4tIsaP.js} +1 -1
  66. package/dist/client/assets/{ts-tags-BKhSOXI3.js → ts-tags-SUeikhEp.js} +1 -1
  67. package/dist/client/assets/{tsx-CS6iQ0XH.js → tsx-xkp7aIZs.js} +1 -1
  68. package/dist/client/assets/{twig-BHp31ZxS.js → twig-CGgBSAyc.js} +1 -1
  69. package/dist/client/assets/{typescript-16YJBTaO.js → typescript-O2YMTl_s.js} +1 -1
  70. package/dist/client/assets/{vue-CMKwTi4r.js → vue-DsNRxos1.js} +1 -1
  71. package/dist/client/assets/{vue-html-Dr8VUA2G.js → vue-html-CuY3t7bs.js} +1 -1
  72. package/dist/client/assets/{vue-vine-DZUqDerl.js → vue-vine-C6kSCKwY.js} +1 -1
  73. package/dist/client/assets/{xml-CBbBKKDC.js → xml-DafwzOLY.js} +1 -1
  74. package/dist/client/assets/{xsl-DWEX6PKX.js → xsl-1SGGZibr.js} +1 -1
  75. package/dist/client/assets/{yaml-DvKvvh3X.js → yaml-DSVhzmhr.js} +1 -1
  76. package/dist/client/index.html +2 -2
  77. package/dist/client/sw.js +1 -1
  78. package/dist/server/analytics/engine.js +241 -241
  79. package/dist/server/assets.js +4 -4
  80. package/dist/server/auth/passphrase.js +13 -13
  81. package/dist/server/config.js +7 -7
  82. package/dist/server/daemon.js +93 -93
  83. package/dist/server/features/brainstorm.js +42 -42
  84. package/dist/server/features/ralph-loop.js +33 -33
  85. package/dist/server/features/scheduler.js +53 -53
  86. package/dist/server/features/specs.js +54 -54
  87. package/dist/server/features/sticky-notes.js +17 -17
  88. package/dist/server/features/superpowers.js +24 -24
  89. package/dist/server/handlers/analytics.js +1 -1
  90. package/dist/server/handlers/attachment.js +32 -32
  91. package/dist/server/handlers/bookmarks.js +4 -4
  92. package/dist/server/handlers/brainstorm.js +4 -4
  93. package/dist/server/handlers/chat.js +54 -54
  94. package/dist/server/handlers/editor.js +13 -13
  95. package/dist/server/handlers/fs.js +51 -51
  96. package/dist/server/handlers/hooks.js +20 -20
  97. package/dist/server/handlers/loop.js +6 -6
  98. package/dist/server/handlers/memory.js +44 -44
  99. package/dist/server/handlers/mesh.js +60 -60
  100. package/dist/server/handlers/notes.js +7 -7
  101. package/dist/server/handlers/plugins.js +174 -174
  102. package/dist/server/handlers/project-settings.js +26 -26
  103. package/dist/server/handlers/scheduler.js +6 -6
  104. package/dist/server/handlers/session.js +24 -24
  105. package/dist/server/handlers/settings.js +21 -21
  106. package/dist/server/handlers/skills.js +91 -91
  107. package/dist/server/handlers/specs.js +51 -28
  108. package/dist/server/handlers/terminal.js +13 -13
  109. package/dist/server/handlers/themes.js +21 -21
  110. package/dist/server/handlers/update.js +17 -17
  111. package/dist/server/hooks/event_forward.sh +34 -0
  112. package/dist/server/hooks/post_tool_use.sh +26 -0
  113. package/dist/server/hooks/statusline.sh +26 -0
  114. package/dist/server/identity.js +6 -6
  115. package/dist/server/index.js +111 -111
  116. package/dist/server/logger.js +1 -1
  117. package/dist/server/mesh/connector.js +78 -78
  118. package/dist/server/mesh/crypto.js +20 -20
  119. package/dist/server/mesh/discovery.js +14 -14
  120. package/dist/server/mesh/pairing.js +30 -30
  121. package/dist/server/mesh/peers.js +10 -10
  122. package/dist/server/mesh/proxy.js +14 -14
  123. package/dist/server/mesh/session-sync.js +23 -23
  124. package/dist/server/project/bookmarks.js +11 -11
  125. package/dist/server/project/context-breakdown.js +70 -70
  126. package/dist/server/project/file-browser.js +17 -17
  127. package/dist/server/project/project-files.js +68 -68
  128. package/dist/server/project/registry.js +10 -10
  129. package/dist/server/project/sdk-bridge.js +157 -157
  130. package/dist/server/project/session.js +201 -199
  131. package/dist/server/project/terminal.js +15 -15
  132. package/dist/server/project/warmup.js +37 -37
  133. package/dist/server/push.js +11 -11
  134. package/dist/server/runtime.js +1 -1
  135. package/dist/server/tls.js +15 -15
  136. package/dist/server/tui.js +15 -15
  137. package/dist/server/update-checker.js +21 -21
  138. package/dist/server/ws/broadcast.js +18 -18
  139. package/dist/server/ws/router.js +17 -17
  140. package/dist/shared/constants.js +8 -8
  141. package/package.json +2 -2
  142. package/dist/client/assets/index-DlfI20Gn.css +0 -2
@@ -7,8 +7,8 @@ import { homedir } from "node:os";
7
7
  import { loadConfig, getLatticeHome } from "../config.js";
8
8
  import { log } from "../logger.js";
9
9
  function getProjectPath(projectSlug) {
10
- var config = loadConfig();
11
- var project = config.projects.find(function (p) { return p.slug === projectSlug; });
10
+ const config = loadConfig();
11
+ const project = config.projects.find(function (p) { return p.slug === projectSlug; });
12
12
  return project ? project.path : null;
13
13
  }
14
14
  export function projectPathToHash(projectPath) {
@@ -23,10 +23,10 @@ function mapSDKSession(info, projectSlug) {
23
23
  updatedAt: info.lastModified,
24
24
  };
25
25
  }
26
- var LITELLM_PRICING_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json";
27
- var pricingCache = {};
28
- var pricingLoaded = false;
29
- var FALLBACK_PRICING = {
26
+ const LITELLM_PRICING_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json";
27
+ const pricingCache = {};
28
+ let pricingLoaded = false;
29
+ const FALLBACK_PRICING = {
30
30
  "claude-opus-4-6": { input: 15, output: 75 },
31
31
  "claude-sonnet-4-6": { input: 3, output: 15 },
32
32
  "claude-haiku-4-5": { input: 0.80, output: 4 },
@@ -38,15 +38,15 @@ export function loadPricing() {
38
38
  fetch(LITELLM_PRICING_URL).then(function (res) {
39
39
  return res.json();
40
40
  }).then(function (data) {
41
- for (var key in data) {
41
+ for (const key in data) {
42
42
  if (!key.includes("claude"))
43
43
  continue;
44
- var entry = data[key];
45
- var inputCost = entry.input_cost_per_token;
46
- var outputCost = entry.output_cost_per_token;
44
+ const entry = data[key];
45
+ const inputCost = entry.input_cost_per_token;
46
+ const outputCost = entry.output_cost_per_token;
47
47
  if (inputCost == null || outputCost == null)
48
48
  continue;
49
- var modelId = key.replace("anthropic/", "").replace("claude-", "claude-");
49
+ const modelId = key.replace("anthropic/", "").replace("claude-", "claude-");
50
50
  pricingCache[modelId] = {
51
51
  input: inputCost * 1000000,
52
52
  output: outputCost * 1000000,
@@ -63,12 +63,12 @@ loadPricing();
63
63
  export function getPricing(model) {
64
64
  if (pricingCache[model])
65
65
  return pricingCache[model];
66
- for (var key in pricingCache) {
66
+ for (const key in pricingCache) {
67
67
  if (key.includes(model) || model.includes(key))
68
68
  return pricingCache[key];
69
69
  }
70
- var shortModel = model.replace("claude-", "").split("-")[0];
71
- for (var key2 in pricingCache) {
70
+ const shortModel = model.replace("claude-", "").split("-")[0];
71
+ for (const key2 in pricingCache) {
72
72
  if (key2.includes(shortModel))
73
73
  return pricingCache[key2];
74
74
  }
@@ -78,22 +78,22 @@ export function getPricing(model) {
78
78
  return FALLBACK_PRICING["claude-sonnet-4-6"];
79
79
  }
80
80
  export function estimateCost(model, inputTokens, outputTokens, cacheRead, cacheCreation) {
81
- var pricing = getPricing(model);
82
- var normalInput = inputTokens - cacheRead - cacheCreation;
83
- var inputCost = (normalInput * pricing.input) / 1000000;
84
- var cacheCost = pricing.cacheRead != null
81
+ const pricing = getPricing(model);
82
+ const normalInput = inputTokens - cacheRead - cacheCreation;
83
+ const inputCost = (normalInput * pricing.input) / 1000000;
84
+ const cacheCost = pricing.cacheRead != null
85
85
  ? (cacheRead * pricing.cacheRead) / 1000000
86
86
  : (cacheRead * pricing.input * 0.1) / 1000000;
87
- var cacheCreateCost = pricing.cacheCreation != null
87
+ const cacheCreateCost = pricing.cacheCreation != null
88
88
  ? (cacheCreation * pricing.cacheCreation) / 1000000
89
89
  : (cacheCreation * pricing.input * 1.25) / 1000000;
90
- var outputCost = (outputTokens * pricing.output) / 1000000;
90
+ const outputCost = (outputTokens * pricing.output) / 1000000;
91
91
  return Math.max(0, inputCost + cacheCost + cacheCreateCost + outputCost);
92
92
  }
93
93
  function parseTimestamp(msg) {
94
- var raw = msg.timestamp;
94
+ const raw = msg.timestamp;
95
95
  if (raw) {
96
- var parsed = new Date(raw).getTime();
96
+ const parsed = new Date(raw).getTime();
97
97
  if (!isNaN(parsed))
98
98
  return parsed;
99
99
  }
@@ -116,12 +116,12 @@ function extractUserText(content) {
116
116
  return stripXmlTags(content);
117
117
  }
118
118
  if (Array.isArray(content)) {
119
- for (var i = 0; i < content.length; i++) {
120
- var block = content[i];
119
+ for (let i = 0; i < content.length; i++) {
120
+ const block = content[i];
121
121
  if (block.type === "text" && typeof block.text === "string") {
122
122
  if (isSystemContent(block.text))
123
123
  continue;
124
- var cleaned = stripXmlTags(block.text);
124
+ const cleaned = stripXmlTags(block.text);
125
125
  if (cleaned)
126
126
  return cleaned;
127
127
  }
@@ -129,22 +129,22 @@ function extractUserText(content) {
129
129
  }
130
130
  return "";
131
131
  }
132
- var HIDDEN_TOOLS = new Set([
132
+ const HIDDEN_TOOLS = new Set([
133
133
  "TaskUpdate", "TaskCreate", "TaskGet", "TaskList", "TaskOutput", "TaskStop",
134
134
  "TodoWrite", "TodoRead",
135
135
  "EnterPlanMode", "ExitPlanMode",
136
136
  "ToolSearch",
137
137
  ]);
138
138
  function convertSessionMessages(messages) {
139
- var result = [];
140
- var hiddenToolIds = new Set();
141
- for (var i = 0; i < messages.length; i++) {
142
- var msg = messages[i];
143
- var ts = parseTimestamp(msg);
144
- var apiMsg = msg.message;
139
+ const result = [];
140
+ const hiddenToolIds = new Set();
141
+ for (let i = 0; i < messages.length; i++) {
142
+ const msg = messages[i];
143
+ const ts = parseTimestamp(msg);
144
+ const apiMsg = msg.message;
145
145
  if (msg.type === "user") {
146
146
  if (msg.isCompactSummary === true) {
147
- var summaryText = typeof apiMsg.content === "string" ? apiMsg.content : "";
147
+ const summaryText = typeof apiMsg.content === "string" ? apiMsg.content : "";
148
148
  if (summaryText) {
149
149
  result.push({
150
150
  type: "compact_summary",
@@ -156,21 +156,21 @@ function convertSessionMessages(messages) {
156
156
  continue;
157
157
  }
158
158
  if (Array.isArray(apiMsg.content)) {
159
- var hadToolResult = false;
160
- for (var j = 0; j < apiMsg.content.length; j++) {
161
- var block = apiMsg.content[j];
159
+ let hadToolResult = false;
160
+ for (let j = 0; j < apiMsg.content.length; j++) {
161
+ const block = apiMsg.content[j];
162
162
  if (block.type === "tool_result" && block.tool_use_id) {
163
163
  if (hiddenToolIds.has(block.tool_use_id))
164
164
  continue;
165
165
  hadToolResult = true;
166
- var resultContent = "";
166
+ let resultContent = "";
167
167
  if (typeof block.content === "string") {
168
168
  resultContent = block.content;
169
169
  }
170
170
  else if (Array.isArray(block.content)) {
171
- var texts = [];
172
- for (var ri = 0; ri < block.content.length; ri++) {
173
- var rb = block.content[ri];
171
+ const texts = [];
172
+ for (let ri = 0; ri < block.content.length; ri++) {
173
+ const rb = block.content[ri];
174
174
  if (rb.type === "text" && rb.text)
175
175
  texts.push(rb.text);
176
176
  }
@@ -189,7 +189,7 @@ function convertSessionMessages(messages) {
189
189
  else if (block.type === "text" && block.text) {
190
190
  if (isSystemContent(block.text))
191
191
  continue;
192
- var cleaned = stripXmlTags(block.text);
192
+ const cleaned = stripXmlTags(block.text);
193
193
  if (cleaned) {
194
194
  result.push({
195
195
  type: "user",
@@ -202,7 +202,7 @@ function convertSessionMessages(messages) {
202
202
  }
203
203
  }
204
204
  else {
205
- var text = extractUserText(apiMsg.content);
205
+ const text = extractUserText(apiMsg.content);
206
206
  if (text) {
207
207
  result.push({
208
208
  type: "user",
@@ -214,12 +214,12 @@ function convertSessionMessages(messages) {
214
214
  }
215
215
  }
216
216
  else if (msg.type === "assistant") {
217
- var msgUsage = apiMsg.usage;
218
- var msgModel = apiMsg.model || "";
219
- var lastAssistantIdx = -1;
217
+ const msgUsage = apiMsg.usage;
218
+ const msgModel = apiMsg.model || "";
219
+ let lastAssistantIdx = -1;
220
220
  if (Array.isArray(apiMsg.content)) {
221
- for (var k = 0; k < apiMsg.content.length; k++) {
222
- var aBlock = apiMsg.content[k];
221
+ for (let k = 0; k < apiMsg.content.length; k++) {
222
+ const aBlock = apiMsg.content[k];
223
223
  if (aBlock.type === "text" && aBlock.text) {
224
224
  lastAssistantIdx = result.length;
225
225
  result.push({
@@ -245,10 +245,10 @@ function convertSessionMessages(messages) {
245
245
  }
246
246
  }
247
247
  if (msgUsage && lastAssistantIdx >= 0) {
248
- var inTok = msgUsage.input_tokens || 0;
249
- var outTok = msgUsage.output_tokens || 0;
250
- var cacheRead = msgUsage.cache_read_input_tokens || 0;
251
- var cacheCreate = msgUsage.cache_creation_input_tokens || 0;
248
+ const inTok = msgUsage.input_tokens || 0;
249
+ const outTok = msgUsage.output_tokens || 0;
250
+ const cacheRead = msgUsage.cache_read_input_tokens || 0;
251
+ const cacheCreate = msgUsage.cache_creation_input_tokens || 0;
252
252
  result[lastAssistantIdx].inputTokens = inTok;
253
253
  result[lastAssistantIdx].outputTokens = outTok;
254
254
  result[lastAssistantIdx].model = msgModel;
@@ -256,7 +256,7 @@ function convertSessionMessages(messages) {
256
256
  }
257
257
  }
258
258
  else {
259
- var aText = typeof apiMsg.content === "string" ? apiMsg.content : "";
259
+ const aText = typeof apiMsg.content === "string" ? apiMsg.content : "";
260
260
  if (aText) {
261
261
  lastAssistantIdx = result.length;
262
262
  result.push({
@@ -266,10 +266,10 @@ function convertSessionMessages(messages) {
266
266
  timestamp: ts,
267
267
  });
268
268
  if (msgUsage) {
269
- var inTok2 = msgUsage.input_tokens || 0;
270
- var outTok2 = msgUsage.output_tokens || 0;
271
- var cacheRead2 = msgUsage.cache_read_input_tokens || 0;
272
- var cacheCreate2 = msgUsage.cache_creation_input_tokens || 0;
269
+ const inTok2 = msgUsage.input_tokens || 0;
270
+ const outTok2 = msgUsage.output_tokens || 0;
271
+ const cacheRead2 = msgUsage.cache_read_input_tokens || 0;
272
+ const cacheCreate2 = msgUsage.cache_creation_input_tokens || 0;
273
273
  result[lastAssistantIdx].inputTokens = inTok2;
274
274
  result[lastAssistantIdx].outputTokens = outTok2;
275
275
  result[lastAssistantIdx].model = msgModel;
@@ -281,7 +281,7 @@ function convertSessionMessages(messages) {
281
281
  }
282
282
  return result;
283
283
  }
284
- var MODEL_CONTEXT_WINDOWS = {
284
+ const MODEL_CONTEXT_WINDOWS = {
285
285
  "claude-opus-4-6": 1048576,
286
286
  "claude-sonnet-4-6": 1048576,
287
287
  "claude-sonnet-4-5-20250514": 1048576,
@@ -301,31 +301,31 @@ export function guessContextWindow(model) {
301
301
  return 200000;
302
302
  }
303
303
  export async function getSessionUsage(projectSlug, sessionId) {
304
- var projectPath = getProjectPath(projectSlug);
304
+ const projectPath = getProjectPath(projectSlug);
305
305
  if (!projectPath)
306
306
  return null;
307
- var hash = projectPathToHash(projectPath);
308
- var sessionFile = join(homedir(), ".claude", "projects", hash, sessionId + ".jsonl");
307
+ const hash = projectPathToHash(projectPath);
308
+ const sessionFile = join(homedir(), ".claude", "projects", hash, sessionId + ".jsonl");
309
309
  if (!existsSync(sessionFile))
310
310
  return null;
311
311
  try {
312
- var fhUsage = await fsPromises.open(sessionFile, "r");
313
- var statUsage = await fhUsage.stat();
314
- var tailSize = Math.min(statUsage.size, 512 * 1024);
315
- var bufUsage = Buffer.alloc(tailSize);
312
+ const fhUsage = await fsPromises.open(sessionFile, "r");
313
+ const statUsage = await fhUsage.stat();
314
+ const tailSize = Math.min(statUsage.size, 512 * 1024);
315
+ const bufUsage = Buffer.alloc(tailSize);
316
316
  await fhUsage.read(bufUsage, 0, tailSize, statUsage.size - tailSize);
317
317
  await fhUsage.close();
318
- var text = bufUsage.toString("utf-8");
319
- var lines = text.split("\n");
320
- for (var i = lines.length - 1; i >= 0; i--) {
321
- var line = lines[i].trim();
318
+ const text = bufUsage.toString("utf-8");
319
+ const lines = text.split("\n");
320
+ for (let i = lines.length - 1; i >= 0; i--) {
321
+ const line = lines[i].trim();
322
322
  if (!line)
323
323
  continue;
324
324
  try {
325
- var parsed = JSON.parse(line);
325
+ const parsed = JSON.parse(line);
326
326
  if (parsed.type === "assistant" && parsed.message && parsed.message.usage) {
327
- var usage = parsed.message.usage;
328
- var model = parsed.message.model || "";
327
+ const usage = parsed.message.usage;
328
+ const model = parsed.message.model || "";
329
329
  return {
330
330
  inputTokens: usage.input_tokens || 0,
331
331
  outputTokens: usage.output_tokens || 0,
@@ -344,32 +344,32 @@ export async function getSessionUsage(projectSlug, sessionId) {
344
344
  }
345
345
  }
346
346
  export async function getSessionPreview(projectSlug, sessionId) {
347
- var projectPath = getProjectPath(projectSlug);
347
+ const projectPath = getProjectPath(projectSlug);
348
348
  if (!projectPath)
349
349
  return null;
350
- var hash = projectPathToHash(projectPath);
351
- var sessionFile = join(homedir(), ".claude", "projects", hash, sessionId + ".jsonl");
350
+ const hash = projectPathToHash(projectPath);
351
+ const sessionFile = join(homedir(), ".claude", "projects", hash, sessionId + ".jsonl");
352
352
  if (!existsSync(sessionFile))
353
353
  return null;
354
354
  try {
355
- var content = readFileSync(sessionFile, "utf-8");
356
- var lines = content.trim().split("\n");
357
- var totalCost = 0;
358
- var messageCount = 0;
359
- var model = "";
360
- var lastMessage = "";
361
- var firstTimestamp = 0;
362
- var lastTimestamp = 0;
363
- for (var i = 0; i < lines.length; i++) {
364
- var line = lines[i].trim();
355
+ const content = readFileSync(sessionFile, "utf-8");
356
+ const lines = content.trim().split("\n");
357
+ let totalCost = 0;
358
+ let messageCount = 0;
359
+ let model = "";
360
+ let lastMessage = "";
361
+ let firstTimestamp = 0;
362
+ let lastTimestamp = 0;
363
+ for (let i = 0; i < lines.length; i++) {
364
+ const line = lines[i].trim();
365
365
  if (!line)
366
366
  continue;
367
367
  try {
368
- var parsed = JSON.parse(line);
369
- var ts = 0;
370
- var rawTs = parsed.timestamp;
368
+ const parsed = JSON.parse(line);
369
+ let ts = 0;
370
+ const rawTs = parsed.timestamp;
371
371
  if (rawTs) {
372
- var parsedTs = new Date(rawTs).getTime();
372
+ const parsedTs = new Date(rawTs).getTime();
373
373
  if (!isNaN(parsedTs))
374
374
  ts = parsedTs;
375
375
  }
@@ -379,26 +379,26 @@ export async function getSessionPreview(projectSlug, sessionId) {
379
379
  lastTimestamp = ts;
380
380
  if (parsed.type === "user") {
381
381
  messageCount++;
382
- var userText = extractUserText(parsed.message?.content);
382
+ const userText = extractUserText(parsed.message?.content);
383
383
  if (userText)
384
384
  lastMessage = userText;
385
385
  }
386
386
  else if (parsed.type === "assistant" && parsed.message) {
387
387
  messageCount++;
388
- var usage = parsed.message.usage;
389
- var msgModel = parsed.message.model || "";
388
+ const usage = parsed.message.usage;
389
+ const msgModel = parsed.message.model || "";
390
390
  if (msgModel)
391
391
  model = msgModel;
392
392
  if (usage) {
393
- var inTok = usage.input_tokens || 0;
394
- var outTok = usage.output_tokens || 0;
395
- var cacheRead = usage.cache_read_input_tokens || 0;
396
- var cacheCreate = usage.cache_creation_input_tokens || 0;
393
+ const inTok = usage.input_tokens || 0;
394
+ const outTok = usage.output_tokens || 0;
395
+ const cacheRead = usage.cache_read_input_tokens || 0;
396
+ const cacheCreate = usage.cache_creation_input_tokens || 0;
397
397
  totalCost += estimateCost(msgModel || model, inTok, outTok, cacheRead, cacheCreate);
398
398
  }
399
- var aContent = parsed.message.content;
399
+ const aContent = parsed.message.content;
400
400
  if (Array.isArray(aContent)) {
401
- for (var j = aContent.length - 1; j >= 0; j--) {
401
+ for (let j = aContent.length - 1; j >= 0; j--) {
402
402
  if (aContent[j].type === "text" && aContent[j].text) {
403
403
  lastMessage = aContent[j].text;
404
404
  break;
@@ -412,7 +412,7 @@ export async function getSessionPreview(projectSlug, sessionId) {
412
412
  }
413
413
  catch { }
414
414
  }
415
- var maxSnippet = 120;
415
+ const maxSnippet = 120;
416
416
  if (lastMessage.length > maxSnippet) {
417
417
  lastMessage = lastMessage.slice(0, maxSnippet) + "...";
418
418
  }
@@ -429,15 +429,15 @@ export async function getSessionPreview(projectSlug, sessionId) {
429
429
  return null;
430
430
  }
431
431
  }
432
- var sessionListCache = new Map();
433
- var SESSION_CACHE_TTL = 60000;
434
- var RECONCILE_INTERVAL = 5 * 60 * 1000;
435
- var lastReconcile = new Map();
432
+ const sessionListCache = new Map();
433
+ const SESSION_CACHE_TTL = 60000;
434
+ const RECONCILE_INTERVAL = 5 * 60 * 1000;
435
+ const lastReconcile = new Map();
436
436
  function getIndexPath() {
437
437
  return join(getLatticeHome(), "session-index.json");
438
438
  }
439
439
  function loadSessionIndex() {
440
- var indexPath = getIndexPath();
440
+ const indexPath = getIndexPath();
441
441
  if (!existsSync(indexPath))
442
442
  return {};
443
443
  try {
@@ -456,10 +456,10 @@ function saveSessionIndex(index) {
456
456
  }
457
457
  }
458
458
  export function updateSessionInIndex(projectSlug, session) {
459
- var index = loadSessionIndex();
460
- var sessions = index[projectSlug] || [];
461
- var existing = -1;
462
- for (var i = 0; i < sessions.length; i++) {
459
+ const index = loadSessionIndex();
460
+ const sessions = index[projectSlug] || [];
461
+ let existing = -1;
462
+ for (let i = 0; i < sessions.length; i++) {
463
463
  if (sessions[i].id === session.id) {
464
464
  existing = i;
465
465
  break;
@@ -477,22 +477,22 @@ export function updateSessionInIndex(projectSlug, session) {
477
477
  sessionListCache.set(projectSlug, { sessions, time: Date.now() });
478
478
  }
479
479
  export function removeSessionFromIndex(projectSlug, sessionId) {
480
- var index = loadSessionIndex();
481
- var sessions = index[projectSlug] || [];
480
+ const index = loadSessionIndex();
481
+ const sessions = index[projectSlug] || [];
482
482
  index[projectSlug] = sessions.filter(function (s) { return s.id !== sessionId; });
483
483
  saveSessionIndex(index);
484
484
  sessionListCache.set(projectSlug, { sessions: index[projectSlug], time: Date.now() });
485
485
  }
486
486
  async function reconcileWithSDK(projectSlug) {
487
- var projectPath = getProjectPath(projectSlug);
487
+ const projectPath = getProjectPath(projectSlug);
488
488
  if (!projectPath)
489
489
  return [];
490
- var sdkT0 = Date.now();
491
- var sdkSessions = await sdkListSessions({ dir: projectPath });
490
+ const sdkT0 = Date.now();
491
+ const sdkSessions = await sdkListSessions({ dir: projectPath });
492
492
  log.session("sdkListSessions for %s: %dms (%d sessions)", projectSlug, Date.now() - sdkT0, sdkSessions.length);
493
- var summaries = sdkSessions.map(function (s) { return mapSDKSession(s, projectSlug); });
493
+ const summaries = sdkSessions.map(function (s) { return mapSDKSession(s, projectSlug); });
494
494
  summaries.sort(function (a, b) { return b.updatedAt - a.updatedAt; });
495
- var index = loadSessionIndex();
495
+ const index = loadSessionIndex();
496
496
  index[projectSlug] = summaries;
497
497
  saveSessionIndex(index);
498
498
  sessionListCache.set(projectSlug, { sessions: summaries, time: Date.now() });
@@ -500,25 +500,25 @@ async function reconcileWithSDK(projectSlug) {
500
500
  return summaries;
501
501
  }
502
502
  function needsReconcile(projectSlug) {
503
- var last = lastReconcile.get(projectSlug);
503
+ const last = lastReconcile.get(projectSlug);
504
504
  if (!last)
505
505
  return true;
506
506
  return Date.now() - last > RECONCILE_INTERVAL;
507
507
  }
508
508
  export async function listSessions(projectSlug, options) {
509
- var projectPath = getProjectPath(projectSlug);
509
+ const projectPath = getProjectPath(projectSlug);
510
510
  if (!projectPath) {
511
511
  return { sessions: [], totalCount: 0 };
512
512
  }
513
- var cached = sessionListCache.get(projectSlug);
513
+ const cached = sessionListCache.get(projectSlug);
514
514
  if (cached && !options?.noCache && Date.now() - cached.time < SESSION_CACHE_TTL) {
515
- var offset = options?.offset ?? 0;
516
- var limit = options?.limit ?? 0;
517
- var sliced = limit > 0 ? cached.sessions.slice(offset, offset + limit) : cached.sessions;
515
+ const offset = options?.offset ?? 0;
516
+ const limit = options?.limit ?? 0;
517
+ const sliced = limit > 0 ? cached.sessions.slice(offset, offset + limit) : cached.sessions;
518
518
  return { sessions: sliced, totalCount: cached.sessions.length };
519
519
  }
520
- var index = loadSessionIndex();
521
- var indexed = index[projectSlug];
520
+ const index = loadSessionIndex();
521
+ const indexed = index[projectSlug];
522
522
  if (indexed && indexed.length > 0) {
523
523
  sessionListCache.set(projectSlug, { sessions: indexed, time: Date.now() });
524
524
  if (needsReconcile(projectSlug)) {
@@ -526,16 +526,16 @@ export async function listSessions(projectSlug, options) {
526
526
  log.session("Background reconcile failed: %O", err);
527
527
  });
528
528
  }
529
- var offset3 = options?.offset ?? 0;
530
- var limit3 = options?.limit ?? 0;
531
- var sliced3 = limit3 > 0 ? indexed.slice(offset3, offset3 + limit3) : indexed;
529
+ const offset3 = options?.offset ?? 0;
530
+ const limit3 = options?.limit ?? 0;
531
+ const sliced3 = limit3 > 0 ? indexed.slice(offset3, offset3 + limit3) : indexed;
532
532
  return { sessions: sliced3, totalCount: indexed.length };
533
533
  }
534
534
  try {
535
- var summaries = await reconcileWithSDK(projectSlug);
536
- var offset2 = options?.offset ?? 0;
537
- var limit2 = options?.limit ?? 0;
538
- var sliced2 = limit2 > 0 ? summaries.slice(offset2, offset2 + limit2) : summaries;
535
+ const summaries = await reconcileWithSDK(projectSlug);
536
+ const offset2 = options?.offset ?? 0;
537
+ const limit2 = options?.limit ?? 0;
538
+ const sliced2 = limit2 > 0 ? summaries.slice(offset2, offset2 + limit2) : summaries;
539
539
  return { sessions: sliced2, totalCount: summaries.length };
540
540
  }
541
541
  catch (err) {
@@ -548,61 +548,75 @@ export function invalidateSessionCache(projectSlug) {
548
548
  }
549
549
  export function invalidateHistoryCache(sessionId) {
550
550
  historyCache.delete(sessionId);
551
- var idx = historyCacheOrder.indexOf(sessionId);
551
+ const idx = historyCacheOrder.indexOf(sessionId);
552
552
  if (idx >= 0)
553
553
  historyCacheOrder.splice(idx, 1);
554
554
  }
555
555
  export async function getSessionTitle(projectSlug, sessionId) {
556
- var projectPath = getProjectPath(projectSlug);
557
- var options = projectPath ? { dir: projectPath } : undefined;
556
+ const filePath = getSessionFilePath(projectSlug, sessionId);
557
+ if (!filePath) {
558
+ const index = loadSessionIndex();
559
+ const sessions = index[projectSlug] || [];
560
+ const entry = sessions.find(function (s) { return s.id === sessionId; });
561
+ if (entry && entry.title && entry.title !== "Untitled")
562
+ return entry.title;
563
+ return "Untitled";
564
+ }
565
+ const projectPath = getProjectPath(projectSlug);
566
+ const options = projectPath ? { dir: projectPath } : undefined;
558
567
  try {
559
- var info = await getSessionInfo(sessionId, options);
568
+ const info = await getSessionInfo(sessionId, options);
560
569
  if (info) {
561
570
  return info.customTitle || info.summary || info.firstPrompt || "Untitled";
562
571
  }
563
572
  }
564
573
  catch { }
574
+ const index = loadSessionIndex();
575
+ const sessions = index[projectSlug] || [];
576
+ const entry = sessions.find(function (s) { return s.id === sessionId; });
577
+ if (entry && entry.title && entry.title !== "Untitled")
578
+ return entry.title;
565
579
  return "Untitled";
566
580
  }
567
- var historyCache = new Map();
568
- var historyCacheOrder = [];
569
- var MAX_HISTORY_CACHE = 50;
581
+ const historyCache = new Map();
582
+ const historyCacheOrder = [];
583
+ const MAX_HISTORY_CACHE = 50;
570
584
  function touchCache(sessionId) {
571
- var idx = historyCacheOrder.indexOf(sessionId);
585
+ const idx = historyCacheOrder.indexOf(sessionId);
572
586
  if (idx >= 0)
573
587
  historyCacheOrder.splice(idx, 1);
574
588
  historyCacheOrder.push(sessionId);
575
589
  }
576
590
  function evictOldest() {
577
591
  while (historyCacheOrder.length > MAX_HISTORY_CACHE) {
578
- var oldest = historyCacheOrder.shift();
592
+ const oldest = historyCacheOrder.shift();
579
593
  if (oldest)
580
594
  historyCache.delete(oldest);
581
595
  }
582
596
  }
583
597
  export function appendToHistoryCache(sessionId, message) {
584
- var cached = historyCache.get(sessionId);
598
+ const cached = historyCache.get(sessionId);
585
599
  if (!cached)
586
600
  return;
587
601
  cached.messages.push(message);
588
602
  touchCache(sessionId);
589
603
  }
590
- var INITIAL_MESSAGE_COUNT = 300;
591
- var TAIL_READ_BYTES = 512 * 1024;
604
+ const INITIAL_MESSAGE_COUNT = 300;
605
+ const TAIL_READ_BYTES = 512 * 1024;
592
606
  function getSessionFilePath(projectSlug, sessionId) {
593
- var projectPath = getProjectPath(projectSlug);
607
+ const projectPath = getProjectPath(projectSlug);
594
608
  if (!projectPath)
595
609
  return null;
596
- var hash = projectPathToHash(projectPath);
597
- var filePath = join(homedir(), ".claude", "projects", hash, sessionId + ".jsonl");
610
+ const hash = projectPathToHash(projectPath);
611
+ const filePath = join(homedir(), ".claude", "projects", hash, sessionId + ".jsonl");
598
612
  return existsSync(filePath) ? filePath : null;
599
613
  }
600
614
  export async function getSessionFileSizeBytes(projectSlug, sessionId) {
601
- var filePath = getSessionFilePath(projectSlug, sessionId);
615
+ const filePath = getSessionFilePath(projectSlug, sessionId);
602
616
  if (!filePath)
603
617
  return null;
604
618
  try {
605
- var fileStat = await fsPromises.stat(filePath);
619
+ const fileStat = await fsPromises.stat(filePath);
606
620
  return fileStat.size;
607
621
  }
608
622
  catch {
@@ -610,20 +624,20 @@ export async function getSessionFileSizeBytes(projectSlug, sessionId) {
610
624
  }
611
625
  }
612
626
  async function readTailLines(filePath, maxBytes) {
613
- var fh = await fsPromises.open(filePath, "r");
627
+ const fh = await fsPromises.open(filePath, "r");
614
628
  try {
615
- var stat = await fh.stat();
616
- var readStart = Math.max(0, stat.size - maxBytes);
617
- var length = stat.size - readStart;
618
- var buf = Buffer.alloc(length);
629
+ const stat = await fh.stat();
630
+ const readStart = Math.max(0, stat.size - maxBytes);
631
+ const length = stat.size - readStart;
632
+ const buf = Buffer.alloc(length);
619
633
  await fh.read(buf, 0, length, readStart);
620
- var text = buf.toString("utf-8");
634
+ let text = buf.toString("utf-8");
621
635
  if (readStart > 0) {
622
- var firstNewline = text.indexOf("\n");
636
+ const firstNewline = text.indexOf("\n");
623
637
  if (firstNewline >= 0)
624
638
  text = text.slice(firstNewline + 1);
625
639
  }
626
- var lines = text.split("\n").filter(function (l) { return l.length > 0; });
640
+ const lines = text.split("\n").filter(function (l) { return l.length > 0; });
627
641
  return { lines, isPartial: readStart > 0, fileSize: stat.size };
628
642
  }
629
643
  finally {
@@ -631,10 +645,10 @@ async function readTailLines(filePath, maxBytes) {
631
645
  }
632
646
  }
633
647
  function parseJsonlLines(lines) {
634
- var results = [];
635
- for (var i = 0; i < lines.length; i++) {
648
+ const results = [];
649
+ for (let i = 0; i < lines.length; i++) {
636
650
  try {
637
- var parsed = JSON.parse(lines[i]);
651
+ const parsed = JSON.parse(lines[i]);
638
652
  if (parsed.type === "user" || parsed.type === "assistant" || parsed.type === "system") {
639
653
  results.push(parsed);
640
654
  }
@@ -645,47 +659,35 @@ function parseJsonlLines(lines) {
645
659
  }
646
660
  export async function loadSessionHistory(projectSlug, sessionId) {
647
661
  try {
648
- var t0 = Date.now();
649
- var cached = historyCache.get(sessionId);
662
+ const t0 = Date.now();
663
+ const cached = historyCache.get(sessionId);
650
664
  if (cached) {
651
665
  touchCache(sessionId);
652
- var tail = cached.messages.length > INITIAL_MESSAGE_COUNT
666
+ const tail = cached.messages.length > INITIAL_MESSAGE_COUNT
653
667
  ? cached.messages.slice(cached.messages.length - INITIAL_MESSAGE_COUNT)
654
668
  : cached.messages;
655
669
  log.session("loadSessionHistory %s: %dms (cached, %d total)", sessionId.slice(0, 8), Date.now() - t0, cached.messages.length);
656
670
  return { messages: tail, totalMessages: cached.messages.length, hasMore: cached.messages.length > INITIAL_MESSAGE_COUNT };
657
671
  }
658
- var filePath = getSessionFilePath(projectSlug, sessionId);
672
+ const filePath = getSessionFilePath(projectSlug, sessionId);
659
673
  if (filePath) {
660
- var tailData = await readTailLines(filePath, TAIL_READ_BYTES);
661
- var tailRaw = parseJsonlLines(tailData.lines);
662
- var tailMessages = convertSessionMessages(tailRaw);
663
- var hasMore = tailData.isPartial;
674
+ const tailData = await readTailLines(filePath, TAIL_READ_BYTES);
675
+ const tailRaw = parseJsonlLines(tailData.lines);
676
+ const tailMessages = convertSessionMessages(tailRaw);
677
+ const hasMore = tailData.isPartial;
664
678
  log.session("loadSessionHistory %s: %dms (tail read, %d msgs, partial=%s)", sessionId.slice(0, 8), Date.now() - t0, tailMessages.length, hasMore);
665
679
  if (!hasMore && tailMessages.length > 0) {
666
680
  historyCache.set(sessionId, { messages: tailMessages, title: null });
667
681
  touchCache(sessionId);
668
682
  evictOldest();
669
683
  }
670
- var initialSlice = tailMessages.length > INITIAL_MESSAGE_COUNT
684
+ const initialSlice = tailMessages.length > INITIAL_MESSAGE_COUNT
671
685
  ? tailMessages.slice(tailMessages.length - INITIAL_MESSAGE_COUNT)
672
686
  : tailMessages;
673
687
  return { messages: initialSlice, totalMessages: tailMessages.length, hasMore: hasMore };
674
688
  }
675
- var projectPath = getProjectPath(projectSlug);
676
- var options = projectPath ? { dir: projectPath } : undefined;
677
- var rawMessages = await getSessionMessages(sessionId, options);
678
- var allMessages = convertSessionMessages(rawMessages);
679
- if (allMessages.length > 0) {
680
- historyCache.set(sessionId, { messages: allMessages, title: null });
681
- touchCache(sessionId);
682
- evictOldest();
683
- }
684
- log.session("loadSessionHistory %s: %dms (full SDK, %d msgs)", sessionId.slice(0, 8), Date.now() - t0, allMessages.length);
685
- var tailSlice = allMessages.length > INITIAL_MESSAGE_COUNT
686
- ? allMessages.slice(allMessages.length - INITIAL_MESSAGE_COUNT)
687
- : allMessages;
688
- return { messages: tailSlice, totalMessages: allMessages.length, hasMore: allMessages.length > INITIAL_MESSAGE_COUNT };
689
+ log.session("loadSessionHistory %s: %dms (no session file found)", sessionId.slice(0, 8), Date.now() - t0);
690
+ return { messages: [], totalMessages: 0, hasMore: false };
689
691
  }
690
692
  catch (err) {
691
693
  log.session("Failed to load session history: %O", err);
@@ -693,13 +695,13 @@ export async function loadSessionHistory(projectSlug, sessionId) {
693
695
  }
694
696
  }
695
697
  export async function getSessionHistoryPage(sessionId, beforeIndex, limit, projectSlug, loaded) {
696
- var cached = historyCache.get(sessionId);
698
+ let cached = historyCache.get(sessionId);
697
699
  if (!cached && projectSlug) {
698
- var projectPath = getProjectPath(projectSlug);
699
- var options = projectPath ? { dir: projectPath } : undefined;
700
+ const projectPath = getProjectPath(projectSlug);
701
+ const options = projectPath ? { dir: projectPath } : undefined;
700
702
  try {
701
- var rawMessages = await getSessionMessages(sessionId, options);
702
- var allMessages = convertSessionMessages(rawMessages);
703
+ const rawMessages = await getSessionMessages(sessionId, options);
704
+ const allMessages = convertSessionMessages(rawMessages);
703
705
  historyCache.set(sessionId, { messages: allMessages, title: null });
704
706
  touchCache(sessionId);
705
707
  evictOldest();
@@ -712,8 +714,8 @@ export async function getSessionHistoryPage(sessionId, beforeIndex, limit, proje
712
714
  }
713
715
  if (!cached)
714
716
  return { messages: [], hasMore: false, totalMessages: 0 };
715
- var total = cached.messages.length;
716
- var endIdx;
717
+ const total = cached.messages.length;
718
+ let endIdx;
717
719
  if (loaded !== undefined) {
718
720
  endIdx = Math.max(0, total - loaded);
719
721
  }
@@ -723,13 +725,13 @@ export async function getSessionHistoryPage(sessionId, beforeIndex, limit, proje
723
725
  else {
724
726
  endIdx = total;
725
727
  }
726
- var startIdx = Math.max(0, endIdx - limit);
727
- var page = cached.messages.slice(startIdx, endIdx);
728
+ const startIdx = Math.max(0, endIdx - limit);
729
+ const page = cached.messages.slice(startIdx, endIdx);
728
730
  return { messages: page, hasMore: startIdx > 0, totalMessages: total };
729
731
  }
730
732
  export function createSession(projectSlug, sessionType) {
731
- var sessionId = randomUUID();
732
- var now = Date.now();
733
+ const sessionId = randomUUID();
734
+ const now = Date.now();
733
735
  return {
734
736
  id: sessionId,
735
737
  projectSlug,
@@ -740,8 +742,8 @@ export function createSession(projectSlug, sessionType) {
740
742
  };
741
743
  }
742
744
  export async function renameSession(projectSlug, sessionId, title) {
743
- var projectPath = getProjectPath(projectSlug);
744
- var options = projectPath ? { dir: projectPath } : undefined;
745
+ const projectPath = getProjectPath(projectSlug);
746
+ const options = projectPath ? { dir: projectPath } : undefined;
745
747
  try {
746
748
  await sdkRenameSession(sessionId, title, options);
747
749
  return true;
@@ -752,12 +754,12 @@ export async function renameSession(projectSlug, sessionId, title) {
752
754
  }
753
755
  }
754
756
  export async function deleteSession(projectSlug, sessionId) {
755
- var projectPath = getProjectPath(projectSlug);
757
+ const projectPath = getProjectPath(projectSlug);
756
758
  if (!projectPath) {
757
759
  return false;
758
760
  }
759
- var hash = projectPathToHash(projectPath);
760
- var sessionFile = join(homedir(), ".claude", "projects", hash, sessionId + ".jsonl");
761
+ const hash = projectPathToHash(projectPath);
762
+ const sessionFile = join(homedir(), ".claude", "projects", hash, sessionId + ".jsonl");
761
763
  if (!existsSync(sessionFile)) {
762
764
  return false;
763
765
  }
@@ -772,12 +774,12 @@ export async function deleteSession(projectSlug, sessionId) {
772
774
  }
773
775
  export async function findProjectSlugForSession(sessionId) {
774
776
  try {
775
- var info = await getSessionInfo(sessionId);
777
+ const info = await getSessionInfo(sessionId);
776
778
  if (!info || !info.cwd) {
777
779
  return null;
778
780
  }
779
- var config = loadConfig();
780
- for (var i = 0; i < config.projects.length; i++) {
781
+ const config = loadConfig();
782
+ for (let i = 0; i < config.projects.length; i++) {
781
783
  if (info.cwd.startsWith(config.projects[i].path)) {
782
784
  return config.projects[i].slug;
783
785
  }