@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
@@ -13,12 +13,12 @@ function formatSdkRule(rule) {
13
13
  if (!rule.ruleContent)
14
14
  return rule.toolName;
15
15
  if (rule.toolName === "Bash") {
16
- var firstWord = rule.ruleContent.split(/\s+/)[0].replace(/:.*$/, "");
16
+ const firstWord = rule.ruleContent.split(/\s+/)[0].replace(/:.*$/, "");
17
17
  if (firstWord === "curl" || firstWord === "wget") {
18
- var urlMatch = rule.ruleContent.match(/https?:\/\/[^\s"']+/);
18
+ const urlMatch = rule.ruleContent.match(/https?:\/\/[^\s"']+/);
19
19
  if (urlMatch) {
20
20
  try {
21
- var parsed = new URL(urlMatch[0]);
21
+ const parsed = new URL(urlMatch[0]);
22
22
  return rule.toolName + "(" + firstWord + ":" + parsed.hostname + ")";
23
23
  }
24
24
  catch { }
@@ -29,9 +29,9 @@ function formatSdkRule(rule) {
29
29
  return rule.toolName + "(" + rule.ruleContent + ")";
30
30
  }
31
31
  function addProjectAllowRules(projectPath, suggestions, fallbackToolName, fallbackInput) {
32
- var claudeDir = join(projectPath, ".claude");
33
- var settingsPath = join(claudeDir, "settings.json");
34
- var settings = {};
32
+ const claudeDir = join(projectPath, ".claude");
33
+ const settingsPath = join(claudeDir, "settings.json");
34
+ let settings = {};
35
35
  if (existsSync(settingsPath)) {
36
36
  try {
37
37
  settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
@@ -43,26 +43,26 @@ function addProjectAllowRules(projectPath, suggestions, fallbackToolName, fallba
43
43
  if (!settings.permissions) {
44
44
  settings.permissions = {};
45
45
  }
46
- var permissions = settings.permissions;
46
+ const permissions = settings.permissions;
47
47
  if (!Array.isArray(permissions.allow)) {
48
48
  permissions.allow = [];
49
49
  }
50
50
  if (!Array.isArray(permissions.additionalDirectories)) {
51
51
  permissions.additionalDirectories = [];
52
52
  }
53
- var allowList = permissions.allow;
54
- var additionalDirs = permissions.additionalDirectories;
53
+ const allowList = permissions.allow;
54
+ const additionalDirs = permissions.additionalDirectories;
55
55
  if (suggestions && suggestions.length > 0) {
56
- for (var si = 0; si < suggestions.length; si++) {
57
- var suggestion = suggestions[si];
56
+ for (let si = 0; si < suggestions.length; si++) {
57
+ const suggestion = suggestions[si];
58
58
  if (suggestion.type === "addRules" && suggestion.behavior === "allow" && suggestion.rules) {
59
- for (var ri = 0; ri < suggestion.rules.length; ri++) {
60
- var rule = formatSdkRule(suggestion.rules[ri]);
59
+ for (let ri = 0; ri < suggestion.rules.length; ri++) {
60
+ const rule = formatSdkRule(suggestion.rules[ri]);
61
61
  if (!allowList.includes(rule)) {
62
62
  allowList.push(rule);
63
63
  }
64
64
  if (suggestion.rules[ri].ruleContent) {
65
- var ruleDir = suggestion.rules[ri].ruleContent.replace(/\/\*\*$/, "").replace(/^\//, "");
65
+ const ruleDir = suggestion.rules[ri].ruleContent.replace(/\/\*\*$/, "").replace(/^\//, "");
66
66
  if (ruleDir.startsWith("/") && !additionalDirs.includes(ruleDir)) {
67
67
  additionalDirs.push(ruleDir);
68
68
  }
@@ -70,7 +70,7 @@ function addProjectAllowRules(projectPath, suggestions, fallbackToolName, fallba
70
70
  }
71
71
  }
72
72
  if (suggestion.type === "addDirectories" && suggestion.directories) {
73
- for (var di = 0; di < suggestion.directories.length; di++) {
73
+ for (let di = 0; di < suggestion.directories.length; di++) {
74
74
  if (!additionalDirs.includes(suggestion.directories[di])) {
75
75
  additionalDirs.push(suggestion.directories[di]);
76
76
  }
@@ -79,7 +79,7 @@ function addProjectAllowRules(projectPath, suggestions, fallbackToolName, fallba
79
79
  }
80
80
  }
81
81
  else {
82
- var fallbackRule = buildPermissionRule(fallbackToolName, fallbackInput);
82
+ const fallbackRule = buildPermissionRule(fallbackToolName, fallbackInput);
83
83
  if (!allowList.includes(fallbackRule)) {
84
84
  allowList.push(fallbackRule);
85
85
  }
@@ -89,13 +89,13 @@ function addProjectAllowRules(projectPath, suggestions, fallbackToolName, fallba
89
89
  }
90
90
  writeFileSync(settingsPath, JSON.stringify(settings, null, 2), "utf-8");
91
91
  }
92
- var activeSessionByClient = new Map();
93
- var pendingBudgetOverride = new Map();
92
+ const activeSessionByClient = new Map();
93
+ const pendingBudgetOverride = new Map();
94
94
  export function sendBudgetStatus(clientId) {
95
- var config = loadConfig();
95
+ const config = loadConfig();
96
96
  if (!config.costBudget)
97
97
  return;
98
- var dailySpend = getDailySpend();
98
+ const dailySpend = getDailySpend();
99
99
  sendTo(clientId, {
100
100
  type: "budget:status",
101
101
  dailySpend: dailySpend,
@@ -114,11 +114,11 @@ export function getActiveSession(clientId) {
114
114
  }
115
115
  registerHandler("budget", function (clientId, message) {
116
116
  if (message.type === "budget:override") {
117
- var pending = pendingBudgetOverride.get(clientId);
117
+ const pending = pendingBudgetOverride.get(clientId);
118
118
  if (!pending)
119
119
  return;
120
120
  pendingBudgetOverride.delete(clientId);
121
- var overrideAttachments = pending.sendMsg.attachmentIds
121
+ const overrideAttachments = pending.sendMsg.attachmentIds
122
122
  ? getAttachments(clientId, pending.sendMsg.attachmentIds)
123
123
  : [];
124
124
  startChatStream({
@@ -137,21 +137,21 @@ registerHandler("budget", function (clientId, message) {
137
137
  });
138
138
  registerHandler("chat", function (clientId, message) {
139
139
  if (message.type === "chat:send") {
140
- var sendMsg = message;
141
- var active = activeSessionByClient.get(clientId);
140
+ const sendMsg = message;
141
+ const active = activeSessionByClient.get(clientId);
142
142
  if (!active) {
143
143
  sendTo(clientId, { type: "chat:error", message: "No active session. Activate a session first." });
144
144
  return;
145
145
  }
146
- var project = getProjectBySlug(active.projectSlug);
146
+ const project = getProjectBySlug(active.projectSlug);
147
147
  if (!project) {
148
148
  sendTo(clientId, { type: "chat:error", message: `Project not found: ${active.projectSlug}` });
149
149
  return;
150
150
  }
151
- var config = loadConfig();
152
- var env = Object.assign({}, config.globalEnv, project.env);
151
+ const config = loadConfig();
152
+ const env = Object.assign({}, config.globalEnv, project.env);
153
153
  if (config.costBudget && config.costBudget.dailyLimit > 0) {
154
- var dailySpend = getDailySpend();
154
+ const dailySpend = getDailySpend();
155
155
  if (dailySpend >= config.costBudget.dailyLimit) {
156
156
  if (config.costBudget.enforcement === "hard-block") {
157
157
  sendTo(clientId, { type: "chat:error", message: "Daily cost budget exceeded ($" + dailySpend.toFixed(2) + " / $" + config.costBudget.dailyLimit.toFixed(2) + "). Sending is blocked until tomorrow." });
@@ -174,10 +174,10 @@ registerHandler("chat", function (clientId, message) {
174
174
  }
175
175
  }
176
176
  }
177
- var attachments = sendMsg.attachmentIds
177
+ const attachments = sendMsg.attachmentIds
178
178
  ? getAttachments(clientId, sendMsg.attachmentIds)
179
179
  : [];
180
- var linkedSpec = findSpecBySession(active.sessionId);
180
+ const linkedSpec = findSpecBySession(active.sessionId);
181
181
  startChatStream({
182
182
  projectSlug: active.projectSlug,
183
183
  sessionId: active.sessionId,
@@ -194,12 +194,12 @@ registerHandler("chat", function (clientId, message) {
194
194
  return;
195
195
  }
196
196
  if (message.type === "chat:cancel") {
197
- var active = activeSessionByClient.get(clientId);
197
+ const active = activeSessionByClient.get(clientId);
198
198
  if (!active) {
199
199
  sendTo(clientId, { type: "chat:error", message: "No active session." });
200
200
  return;
201
201
  }
202
- var stream = getActiveStream(active.sessionId);
202
+ const stream = getActiveStream(active.sessionId);
203
203
  if (!stream) {
204
204
  sendTo(clientId, { type: "chat:error", message: "No active stream to cancel." });
205
205
  return;
@@ -208,18 +208,18 @@ registerHandler("chat", function (clientId, message) {
208
208
  return;
209
209
  }
210
210
  if (message.type === "chat:permission_response") {
211
- var permMsg = message;
212
- var pending = getPendingPermission(permMsg.requestId);
211
+ const permMsg = message;
212
+ const pending = getPendingPermission(permMsg.requestId);
213
213
  if (!pending) {
214
214
  return;
215
215
  }
216
- var active = activeSessionByClient.get(clientId);
216
+ const active = activeSessionByClient.get(clientId);
217
217
  if (permMsg.allow) {
218
218
  if (permMsg.alwaysAllow && permMsg.alwaysAllowScope === "session" && active) {
219
219
  addAutoApprovedTool(active.sessionId, pending.toolName);
220
220
  }
221
221
  if (permMsg.alwaysAllow && permMsg.alwaysAllowScope === "project" && active) {
222
- var project = getProjectBySlug(active.projectSlug);
222
+ const project = getProjectBySlug(active.projectSlug);
223
223
  if (project) {
224
224
  addProjectAllowRules(project.path, pending.suggestions, pending.toolName, pending.input);
225
225
  }
@@ -228,7 +228,7 @@ registerHandler("chat", function (clientId, message) {
228
228
  else {
229
229
  pending.resolve({ behavior: "allow", updatedInput: pending.input, toolUseID: pending.toolUseID });
230
230
  }
231
- var resolvedStatus = permMsg.alwaysAllow ? "always_allowed" : "allowed";
231
+ const resolvedStatus = permMsg.alwaysAllow ? "always_allowed" : "allowed";
232
232
  sendTo(clientId, { type: "chat:permission_resolved", requestId: permMsg.requestId, status: resolvedStatus });
233
233
  }
234
234
  else {
@@ -239,12 +239,12 @@ registerHandler("chat", function (clientId, message) {
239
239
  return;
240
240
  }
241
241
  if (message.type === "chat:prompt_response") {
242
- var promptRespMsg = message;
243
- var pendingPrompt = getPendingPermission(promptRespMsg.requestId);
242
+ const promptRespMsg = message;
243
+ const pendingPrompt = getPendingPermission(promptRespMsg.requestId);
244
244
  if (!pendingPrompt || pendingPrompt.promptType !== "question") {
245
245
  return;
246
246
  }
247
- var updatedInput = Object.assign({}, pendingPrompt.input, {
247
+ const updatedInput = Object.assign({}, pendingPrompt.input, {
248
248
  answers: promptRespMsg.answers,
249
249
  });
250
250
  if (promptRespMsg.annotations) {
@@ -260,8 +260,8 @@ registerHandler("chat", function (clientId, message) {
260
260
  return;
261
261
  }
262
262
  if (message.type === "chat:elicitation_response") {
263
- var elicitMsg = message;
264
- var pendingElicit = getPendingElicitation(elicitMsg.requestId);
263
+ const elicitMsg = message;
264
+ const pendingElicit = getPendingElicitation(elicitMsg.requestId);
265
265
  if (!pendingElicit)
266
266
  return;
267
267
  resolveElicitation(elicitMsg.requestId, {
@@ -271,11 +271,11 @@ registerHandler("chat", function (clientId, message) {
271
271
  return;
272
272
  }
273
273
  if (message.type === "chat:rewind_preview") {
274
- var rewindMsg = message;
275
- var activeForRewind = activeSessionByClient.get(clientId);
274
+ const rewindMsg = message;
275
+ const activeForRewind = activeSessionByClient.get(clientId);
276
276
  if (!activeForRewind)
277
277
  return;
278
- var sessionStreamForRewind = getSessionStream(activeForRewind.sessionId);
278
+ const sessionStreamForRewind = getSessionStream(activeForRewind.sessionId);
279
279
  if (!sessionStreamForRewind) {
280
280
  sendTo(clientId, { type: "chat:rewind_preview_result", messageUuid: rewindMsg.messageUuid, canRewind: false, error: "No active stream for rewind" });
281
281
  return;
@@ -296,11 +296,11 @@ registerHandler("chat", function (clientId, message) {
296
296
  return;
297
297
  }
298
298
  if (message.type === "chat:rewind_execute") {
299
- var execRewindMsg = message;
300
- var activeForExec = activeSessionByClient.get(clientId);
299
+ const execRewindMsg = message;
300
+ const activeForExec = activeSessionByClient.get(clientId);
301
301
  if (!activeForExec)
302
302
  return;
303
- var sessionStreamForExec = getSessionStream(activeForExec.sessionId);
303
+ const sessionStreamForExec = getSessionStream(activeForExec.sessionId);
304
304
  if (!sessionStreamForExec) {
305
305
  sendTo(clientId, { type: "chat:rewind_execute_result", messageUuid: execRewindMsg.messageUuid, success: false, error: "No active stream" });
306
306
  return;
@@ -323,11 +323,11 @@ registerHandler("chat", function (clientId, message) {
323
323
  return;
324
324
  }
325
325
  if (message.type === "chat:set_model") {
326
- var modelMsg = message;
327
- var activeSession = activeSessionByClient.get(clientId);
326
+ const modelMsg = message;
327
+ const activeSession = activeSessionByClient.get(clientId);
328
328
  if (!activeSession)
329
329
  return;
330
- var sessionStream = getSessionStream(activeSession.sessionId);
330
+ const sessionStream = getSessionStream(activeSession.sessionId);
331
331
  if (sessionStream) {
332
332
  void sessionStream.queryInstance.setModel(modelMsg.model === "default" ? undefined : modelMsg.model).catch(function (err) {
333
333
  log.chat("Failed to switch model: %O", err);
@@ -337,12 +337,12 @@ registerHandler("chat", function (clientId, message) {
337
337
  return;
338
338
  }
339
339
  if (message.type === "chat:set_permission_mode") {
340
- var modeMsg = message;
341
- var activeSession = activeSessionByClient.get(clientId);
340
+ const modeMsg = message;
341
+ const activeSession = activeSessionByClient.get(clientId);
342
342
  if (!activeSession) {
343
343
  return;
344
344
  }
345
- var stream = getActiveStream(activeSession.sessionId);
345
+ const stream = getActiveStream(activeSession.sessionId);
346
346
  if (stream) {
347
347
  void stream.setPermissionMode(modeMsg.mode);
348
348
  }
@@ -7,7 +7,7 @@ import { loadConfig } from "../config.js";
7
7
  import { loadOrCreateIdentity } from "../identity.js";
8
8
  import { broadcast } from "../ws/broadcast.js";
9
9
  import { detectIdeProjectName } from "./settings.js";
10
- var binaryNames = {
10
+ const binaryNames = {
11
11
  "vscode": ["code"],
12
12
  "vscode-insiders": ["code-insiders"],
13
13
  "cursor": ["cursor"],
@@ -19,12 +19,12 @@ var binaryNames = {
19
19
  "sublime": ["subl", "sublime_text"],
20
20
  };
21
21
  function detectEditorPath(editorType) {
22
- var names = binaryNames[editorType];
22
+ const names = binaryNames[editorType];
23
23
  if (!names)
24
24
  return null;
25
- for (var i = 0; i < names.length; i++) {
25
+ for (let i = 0; i < names.length; i++) {
26
26
  try {
27
- var result = execSync("which " + names[i], { encoding: "utf-8", timeout: 3000 }).trim();
27
+ const result = execSync("which " + names[i], { encoding: "utf-8", timeout: 3000 }).trim();
28
28
  if (result)
29
29
  return result;
30
30
  }
@@ -35,11 +35,11 @@ function detectEditorPath(editorType) {
35
35
  return null;
36
36
  }
37
37
  function ensureIdeaProject(projectPath, projectTitle) {
38
- var ideaDir = join(projectPath, ".idea");
38
+ const ideaDir = join(projectPath, ".idea");
39
39
  if (!existsSync(ideaDir)) {
40
40
  mkdirSync(ideaDir, { recursive: true });
41
41
  }
42
- var nameFile = join(ideaDir, ".name");
42
+ const nameFile = join(ideaDir, ".name");
43
43
  if (!existsSync(nameFile)) {
44
44
  writeFileSync(nameFile, projectTitle, "utf-8");
45
45
  }
@@ -47,19 +47,19 @@ function ensureIdeaProject(projectPath, projectTitle) {
47
47
  }
48
48
  registerHandler("editor", function (clientId, message) {
49
49
  if (message.type === "editor:detect") {
50
- var detectMsg = message;
51
- var detectedPath = detectEditorPath(detectMsg.editorType);
50
+ const detectMsg = message;
51
+ const detectedPath = detectEditorPath(detectMsg.editorType);
52
52
  sendTo(clientId, { type: "editor:detect_result", editorType: detectMsg.editorType, path: detectedPath });
53
53
  return;
54
54
  }
55
55
  if (message.type === "editor:ensure-project") {
56
- var ensureMsg = message;
57
- var config = loadConfig();
58
- var project = config.projects.find(function (p) { return p.slug === ensureMsg.projectSlug; });
56
+ const ensureMsg = message;
57
+ const config = loadConfig();
58
+ const project = config.projects.find(function (p) { return p.slug === ensureMsg.projectSlug; });
59
59
  if (project) {
60
- var name = ensureIdeaProject(project.path, project.title);
60
+ const name = ensureIdeaProject(project.path, project.title);
61
61
  sendTo(clientId, { type: "editor:ensure-project_result", projectSlug: ensureMsg.projectSlug, ideProjectName: name });
62
- var identity = loadOrCreateIdentity();
62
+ const identity = loadOrCreateIdentity();
63
63
  broadcast({
64
64
  type: "projects:list",
65
65
  projects: config.projects.map(function (p) {
@@ -7,7 +7,7 @@ import { existsSync } from "node:fs";
7
7
  import { join } from "node:path";
8
8
  import { homedir } from "node:os";
9
9
  import { loadConfig } from "../config.js";
10
- var activeProjectByClient = new Map();
10
+ const activeProjectByClient = new Map();
11
11
  export function setActiveProject(clientId, projectSlug) {
12
12
  activeProjectByClient.set(clientId, projectSlug);
13
13
  subscribeClientToProject(clientId, projectSlug);
@@ -20,8 +20,8 @@ export function getActiveProjectForClient(clientId) {
20
20
  }
21
21
  registerHandler("fs", async function (clientId, message) {
22
22
  if (message.type === "fs:list") {
23
- var listMsg = message;
24
- var projectSlug = activeProjectByClient.get(clientId) || listMsg.projectSlug;
23
+ const listMsg = message;
24
+ let projectSlug = activeProjectByClient.get(clientId) || listMsg.projectSlug;
25
25
  if (listMsg.projectSlug) {
26
26
  setActiveProject(clientId, listMsg.projectSlug);
27
27
  projectSlug = listMsg.projectSlug;
@@ -30,18 +30,18 @@ registerHandler("fs", async function (clientId, message) {
30
30
  sendTo(clientId, { type: "chat:error", message: "No active project for fs:list" });
31
31
  return;
32
32
  }
33
- var project = getProjectBySlug(projectSlug);
33
+ const project = getProjectBySlug(projectSlug);
34
34
  if (!project) {
35
35
  sendTo(clientId, { type: "chat:error", message: "Project not found: " + projectSlug });
36
36
  return;
37
37
  }
38
- var entries = await listDirectory(project.path, listMsg.path);
38
+ const entries = await listDirectory(project.path, listMsg.path);
39
39
  sendTo(clientId, { type: "fs:list_result", path: listMsg.path, entries });
40
40
  return;
41
41
  }
42
42
  if (message.type === "fs:read") {
43
- var readMsg = message;
44
- var projectSlugRead = activeProjectByClient.get(clientId) || readMsg.projectSlug;
43
+ const readMsg = message;
44
+ let projectSlugRead = activeProjectByClient.get(clientId) || readMsg.projectSlug;
45
45
  if (readMsg.projectSlug) {
46
46
  setActiveProject(clientId, readMsg.projectSlug);
47
47
  projectSlugRead = readMsg.projectSlug;
@@ -50,12 +50,12 @@ registerHandler("fs", async function (clientId, message) {
50
50
  sendTo(clientId, { type: "chat:error", message: "No active project for fs:read" });
51
51
  return;
52
52
  }
53
- var projectRead = getProjectBySlug(projectSlugRead);
53
+ const projectRead = getProjectBySlug(projectSlugRead);
54
54
  if (!projectRead) {
55
55
  sendTo(clientId, { type: "chat:error", message: "Project not found: " + projectSlugRead });
56
56
  return;
57
57
  }
58
- var content = await readFile(projectRead.path, readMsg.path);
58
+ const content = await readFile(projectRead.path, readMsg.path);
59
59
  if (content === null) {
60
60
  sendTo(clientId, { type: "chat:error", message: "Cannot read file: " + readMsg.path });
61
61
  return;
@@ -64,18 +64,18 @@ registerHandler("fs", async function (clientId, message) {
64
64
  return;
65
65
  }
66
66
  if (message.type === "fs:write") {
67
- var writeMsg = message;
68
- var projectSlugWrite = activeProjectByClient.get(clientId);
67
+ const writeMsg = message;
68
+ const projectSlugWrite = activeProjectByClient.get(clientId);
69
69
  if (!projectSlugWrite) {
70
70
  sendTo(clientId, { type: "chat:error", message: "No active project for fs:write" });
71
71
  return;
72
72
  }
73
- var projectWrite = getProjectBySlug(projectSlugWrite);
73
+ const projectWrite = getProjectBySlug(projectSlugWrite);
74
74
  if (!projectWrite) {
75
75
  sendTo(clientId, { type: "chat:error", message: "Project not found: " + projectSlugWrite });
76
76
  return;
77
77
  }
78
- var ok = await writeFile(projectWrite.path, writeMsg.path, writeMsg.content);
78
+ const ok = await writeFile(projectWrite.path, writeMsg.path, writeMsg.content);
79
79
  if (!ok) {
80
80
  sendTo(clientId, { type: "chat:error", message: "Cannot write file: " + writeMsg.path });
81
81
  return;
@@ -93,48 +93,48 @@ function resolvePath(path) {
93
93
  }
94
94
  async function detectProjectName(dirPath) {
95
95
  try {
96
- var pkgPath = join(dirPath, "package.json");
97
- var pkg = JSON.parse(await fsReadFile(pkgPath, "utf-8"));
96
+ const pkgPath = join(dirPath, "package.json");
97
+ const pkg = JSON.parse(await fsReadFile(pkgPath, "utf-8"));
98
98
  if (pkg.name)
99
99
  return pkg.name;
100
100
  }
101
101
  catch { }
102
102
  try {
103
- var cargoPath = join(dirPath, "Cargo.toml");
104
- var cargo = await fsReadFile(cargoPath, "utf-8");
105
- var cargoMatch = cargo.match(/\[package\][\s\S]*?name\s*=\s*"([^"]+)"/);
103
+ const cargoPath = join(dirPath, "Cargo.toml");
104
+ const cargo = await fsReadFile(cargoPath, "utf-8");
105
+ const cargoMatch = cargo.match(/\[package\][\s\S]*?name\s*=\s*"([^"]+)"/);
106
106
  if (cargoMatch)
107
107
  return cargoMatch[1];
108
108
  }
109
109
  catch { }
110
110
  try {
111
- var composerPath = join(dirPath, "composer.json");
112
- var composer = JSON.parse(await fsReadFile(composerPath, "utf-8"));
111
+ const composerPath = join(dirPath, "composer.json");
112
+ const composer = JSON.parse(await fsReadFile(composerPath, "utf-8"));
113
113
  if (composer.name)
114
114
  return composer.name;
115
115
  }
116
116
  catch { }
117
117
  try {
118
- var pyprojectPath = join(dirPath, "pyproject.toml");
119
- var pyproject = await fsReadFile(pyprojectPath, "utf-8");
120
- var pyMatch = pyproject.match(/\[project\][\s\S]*?name\s*=\s*"([^"]+)"/);
118
+ const pyprojectPath = join(dirPath, "pyproject.toml");
119
+ const pyproject = await fsReadFile(pyprojectPath, "utf-8");
120
+ const pyMatch = pyproject.match(/\[project\][\s\S]*?name\s*=\s*"([^"]+)"/);
121
121
  if (pyMatch)
122
122
  return pyMatch[1];
123
123
  }
124
124
  catch { }
125
125
  try {
126
- var goModPath = join(dirPath, "go.mod");
127
- var goMod = await fsReadFile(goModPath, "utf-8");
128
- var goMatch = goMod.match(/^module\s+(\S+)/m);
126
+ const goModPath = join(dirPath, "go.mod");
127
+ const goMod = await fsReadFile(goModPath, "utf-8");
128
+ const goMatch = goMod.match(/^module\s+(\S+)/m);
129
129
  if (goMatch) {
130
- var parts = goMatch[1].split("/");
130
+ const parts = goMatch[1].split("/");
131
131
  return parts[parts.length - 1];
132
132
  }
133
133
  }
134
134
  catch { }
135
135
  try {
136
- var entries = await readdir(dirPath);
137
- for (var i = 0; i < entries.length; i++) {
136
+ const entries = await readdir(dirPath);
137
+ for (let i = 0; i < entries.length; i++) {
138
138
  if (entries[i].endsWith(".sln") || entries[i].endsWith(".csproj")) {
139
139
  return entries[i].replace(/\.[^.]+$/, "");
140
140
  }
@@ -145,11 +145,11 @@ async function detectProjectName(dirPath) {
145
145
  }
146
146
  registerHandler("browse", async function (clientId, message) {
147
147
  if (message.type === "browse:list") {
148
- var browseMsg = message;
149
- var resolvedPath = resolvePath(browseMsg.path);
150
- var home = homedir();
148
+ const browseMsg = message;
149
+ const resolvedPath = resolvePath(browseMsg.path);
150
+ const home = homedir();
151
151
  try {
152
- var pathStat = await stat(resolvedPath);
152
+ const pathStat = await stat(resolvedPath);
153
153
  if (!pathStat.isDirectory()) {
154
154
  sendTo(clientId, { type: "browse:list_result", path: resolvedPath, homedir: home, entries: [] });
155
155
  return;
@@ -160,15 +160,15 @@ registerHandler("browse", async function (clientId, message) {
160
160
  return;
161
161
  }
162
162
  try {
163
- var dirEntries = await readdir(resolvedPath, { withFileTypes: true });
164
- var results = [];
165
- for (var i = 0; i < dirEntries.length; i++) {
166
- var entry = dirEntries[i];
163
+ const dirEntries = await readdir(resolvedPath, { withFileTypes: true });
164
+ const results = [];
165
+ for (let i = 0; i < dirEntries.length; i++) {
166
+ const entry = dirEntries[i];
167
167
  if (!entry.isDirectory())
168
168
  continue;
169
- var entryPath = join(resolvedPath, entry.name);
170
- var hasClaudeMd = existsSync(join(entryPath, "CLAUDE.md"));
171
- var projectName = await detectProjectName(entryPath);
169
+ const entryPath = join(resolvedPath, entry.name);
170
+ const hasClaudeMd = existsSync(join(entryPath, "CLAUDE.md"));
171
+ const projectName = await detectProjectName(entryPath);
172
172
  results.push({
173
173
  name: entry.name,
174
174
  path: entryPath,
@@ -185,29 +185,29 @@ registerHandler("browse", async function (clientId, message) {
185
185
  return;
186
186
  }
187
187
  if (message.type === "browse:suggestions") {
188
- var claudeProjectsDir = join(homedir(), ".claude", "projects");
189
- var config = loadConfig();
190
- var existingPaths = new Set(config.projects.map(function (p) { return p.path; }));
191
- var suggestions = [];
188
+ const claudeProjectsDir = join(homedir(), ".claude", "projects");
189
+ const config = loadConfig();
190
+ const existingPaths = new Set(config.projects.map(function (p) { return p.path; }));
191
+ const suggestions = [];
192
192
  try {
193
- var hashDirs = await readdir(claudeProjectsDir);
194
- for (var i = 0; i < hashDirs.length; i++) {
195
- var hashDir = hashDirs[i];
196
- var candidatePath = "/" + hashDir.slice(1).replace(/-/g, "/");
193
+ const hashDirs = await readdir(claudeProjectsDir);
194
+ for (let i = 0; i < hashDirs.length; i++) {
195
+ const hashDir = hashDirs[i];
196
+ const candidatePath = "/" + hashDir.slice(1).replace(/-/g, "/");
197
197
  if (!existsSync(candidatePath))
198
198
  continue;
199
199
  if (existingPaths.has(candidatePath))
200
200
  continue;
201
201
  try {
202
- var candidateStat = await stat(candidatePath);
202
+ const candidateStat = await stat(candidatePath);
203
203
  if (!candidateStat.isDirectory())
204
204
  continue;
205
205
  }
206
206
  catch {
207
207
  continue;
208
208
  }
209
- var hasClaudeMd = existsSync(join(candidatePath, "CLAUDE.md"));
210
- var name = candidatePath.split("/").pop() || hashDir;
209
+ const hasClaudeMd = existsSync(join(candidatePath, "CLAUDE.md"));
210
+ const name = candidatePath.split("/").pop() || hashDir;
211
211
  suggestions.push({
212
212
  path: candidatePath,
213
213
  name: name,