@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
@@ -2,10 +2,10 @@ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync, watch }
2
2
  import { join, dirname } from "node:path";
3
3
  import { randomBytes } from "node:crypto";
4
4
  import { getLatticeHome } from "../config.js";
5
- var specsFile = "";
6
- var specs = [];
7
- var lastSaveTime = 0;
8
- var onReloadCallback = null;
5
+ let specsFile = "";
6
+ let specs = [];
7
+ let lastSaveTime = 0;
8
+ let onReloadCallback = null;
9
9
  function getSpecsPath() {
10
10
  if (!specsFile) {
11
11
  specsFile = join(getLatticeHome(), "specs.json");
@@ -13,10 +13,10 @@ function getSpecsPath() {
13
13
  return specsFile;
14
14
  }
15
15
  export function loadSpecs() {
16
- var path = getSpecsPath();
16
+ const path = getSpecsPath();
17
17
  if (existsSync(path)) {
18
18
  try {
19
- var raw = readFileSync(path, "utf-8");
19
+ const raw = readFileSync(path, "utf-8");
20
20
  specs = JSON.parse(raw);
21
21
  }
22
22
  catch (err) {
@@ -32,12 +32,12 @@ export function loadSpecs() {
32
32
  export function onSpecsReloaded(callback) {
33
33
  onReloadCallback = callback;
34
34
  }
35
- var watcher = null;
36
- var reloadTimer = null;
35
+ let watcher = null;
36
+ let reloadTimer = null;
37
37
  function reloadFromDisk() {
38
- var path = getSpecsPath();
38
+ const path = getSpecsPath();
39
39
  try {
40
- var raw = readFileSync(path, "utf-8");
40
+ const raw = readFileSync(path, "utf-8");
41
41
  specs = JSON.parse(raw);
42
42
  if (onReloadCallback)
43
43
  onReloadCallback();
@@ -49,9 +49,9 @@ function reloadFromDisk() {
49
49
  function watchSpecsFile() {
50
50
  if (watcher)
51
51
  return;
52
- var path = getSpecsPath();
53
- var dir = dirname(path);
54
- var filename = path.slice(dir.length + 1);
52
+ const path = getSpecsPath();
53
+ const dir = dirname(path);
54
+ const filename = path.slice(dir.length + 1);
55
55
  if (!existsSync(dir)) {
56
56
  mkdirSync(dir, { recursive: true });
57
57
  }
@@ -75,12 +75,12 @@ function watchSpecsFile() {
75
75
  catch { }
76
76
  }
77
77
  function saveSpecs() {
78
- var path = getSpecsPath();
79
- var dir = join(path, "..");
78
+ const path = getSpecsPath();
79
+ const dir = join(path, "..");
80
80
  if (!existsSync(dir)) {
81
81
  mkdirSync(dir, { recursive: true });
82
82
  }
83
- var tmp = path + ".tmp";
83
+ const tmp = path + ".tmp";
84
84
  try {
85
85
  lastSaveTime = Date.now();
86
86
  writeFileSync(tmp, JSON.stringify(specs, null, 2));
@@ -96,15 +96,15 @@ export function listSpecs(projectSlug) {
96
96
  return specs.filter(function (s) { return s.projectSlug === projectSlug; });
97
97
  }
98
98
  export function getSpec(id) {
99
- for (var i = 0; i < specs.length; i++) {
99
+ for (let i = 0; i < specs.length; i++) {
100
100
  if (specs[i].id === id)
101
101
  return specs[i];
102
102
  }
103
103
  return null;
104
104
  }
105
105
  export function createSpec(opts) {
106
- var now = Date.now();
107
- var spec = {
106
+ const now = Date.now();
107
+ const spec = {
108
108
  id: "spec_" + now + "_" + randomBytes(3).toString("hex"),
109
109
  projectSlug: opts.projectSlug,
110
110
  title: opts.title,
@@ -139,11 +139,11 @@ export function createSpec(opts) {
139
139
  return spec;
140
140
  }
141
141
  export function updateSpec(id, updates) {
142
- for (var i = 0; i < specs.length; i++) {
142
+ for (let i = 0; i < specs.length; i++) {
143
143
  if (specs[i].id !== id)
144
144
  continue;
145
- var spec = specs[i];
146
- var now = Date.now();
145
+ const spec = specs[i];
146
+ const now = Date.now();
147
147
  if (updates.status && updates.status !== spec.status) {
148
148
  spec.activity.push({
149
149
  timestamp: now,
@@ -173,9 +173,9 @@ export function updateSpec(id, updates) {
173
173
  if (updates.blockedBy !== undefined)
174
174
  spec.blockedBy = updates.blockedBy;
175
175
  if (updates.sections) {
176
- var keys = Object.keys(updates.sections);
177
- for (var k = 0; k < keys.length; k++) {
178
- var key = keys[k];
176
+ const keys = Object.keys(updates.sections);
177
+ for (let k = 0; k < keys.length; k++) {
178
+ const key = keys[k];
179
179
  if (updates.sections[key] !== undefined) {
180
180
  spec.sections[key] = updates.sections[key];
181
181
  }
@@ -188,7 +188,7 @@ export function updateSpec(id, updates) {
188
188
  return null;
189
189
  }
190
190
  export function deleteSpec(id) {
191
- for (var i = 0; i < specs.length; i++) {
191
+ for (let i = 0; i < specs.length; i++) {
192
192
  if (specs[i].id === id) {
193
193
  specs.splice(i, 1);
194
194
  saveSpecs();
@@ -198,10 +198,10 @@ export function deleteSpec(id) {
198
198
  return false;
199
199
  }
200
200
  export function populateSpec(id, fields, sessionId) {
201
- for (var i = 0; i < specs.length; i++) {
201
+ for (let i = 0; i < specs.length; i++) {
202
202
  if (specs[i].id !== id)
203
203
  continue;
204
- var spec = specs[i];
204
+ const spec = specs[i];
205
205
  if (fields.title && typeof fields.title === "string")
206
206
  spec.title = fields.title;
207
207
  if (fields.tagline && typeof fields.tagline === "string")
@@ -235,13 +235,13 @@ export function populateSpec(id, fields, sessionId) {
235
235
  return null;
236
236
  }
237
237
  export function parseSpecPopulate(text) {
238
- var startTag = "<spec-populate>";
239
- var endTag = "</spec-populate>";
240
- var startIdx = text.indexOf(startTag);
241
- var endIdx = text.indexOf(endTag);
238
+ const startTag = "<spec-populate>";
239
+ const endTag = "</spec-populate>";
240
+ const startIdx = text.indexOf(startTag);
241
+ const endIdx = text.indexOf(endTag);
242
242
  if (startIdx === -1 || endIdx === -1 || endIdx <= startIdx)
243
243
  return null;
244
- var jsonStr = text.slice(startIdx + startTag.length, endIdx).trim();
244
+ const jsonStr = text.slice(startIdx + startTag.length, endIdx).trim();
245
245
  try {
246
246
  return JSON.parse(jsonStr);
247
247
  }
@@ -250,22 +250,22 @@ export function parseSpecPopulate(text) {
250
250
  }
251
251
  }
252
252
  export function parsePlanContent(text) {
253
- var startTag = "<plan-content>";
254
- var endTag = "</plan-content>";
255
- var startIdx = text.indexOf(startTag);
256
- var endIdx = text.indexOf(endTag);
253
+ const startTag = "<plan-content>";
254
+ const endTag = "</plan-content>";
255
+ const startIdx = text.indexOf(startTag);
256
+ const endIdx = text.indexOf(endTag);
257
257
  if (startIdx === -1 || endIdx === -1 || endIdx <= startIdx)
258
258
  return null;
259
259
  return text.slice(startIdx + startTag.length, endIdx).trim();
260
260
  }
261
261
  export function parseSpecActivity(text) {
262
- var startTag = "<spec-activity>";
263
- var endTag = "</spec-activity>";
264
- var startIdx = text.indexOf(startTag);
265
- var endIdx = text.indexOf(endTag);
262
+ const startTag = "<spec-activity>";
263
+ const endTag = "</spec-activity>";
264
+ const startIdx = text.indexOf(startTag);
265
+ const endIdx = text.indexOf(endTag);
266
266
  if (startIdx === -1 || endIdx === -1 || endIdx <= startIdx)
267
267
  return null;
268
- var jsonStr = text.slice(startIdx + startTag.length, endIdx).trim();
268
+ const jsonStr = text.slice(startIdx + startTag.length, endIdx).trim();
269
269
  try {
270
270
  return JSON.parse(jsonStr);
271
271
  }
@@ -274,8 +274,8 @@ export function parseSpecActivity(text) {
274
274
  }
275
275
  }
276
276
  export function findSpecBySession(sessionId) {
277
- for (var i = 0; i < specs.length; i++) {
278
- for (var j = 0; j < specs[i].linkedSessions.length; j++) {
277
+ for (let i = 0; i < specs.length; i++) {
278
+ for (let j = 0; j < specs[i].linkedSessions.length; j++) {
279
279
  if (specs[i].linkedSessions[j].sessionId === sessionId)
280
280
  return specs[i];
281
281
  }
@@ -283,11 +283,11 @@ export function findSpecBySession(sessionId) {
283
283
  return null;
284
284
  }
285
285
  export function linkSession(specId, sessionId, note, sessionType) {
286
- for (var i = 0; i < specs.length; i++) {
286
+ for (let i = 0; i < specs.length; i++) {
287
287
  if (specs[i].id !== specId)
288
288
  continue;
289
- var spec = specs[i];
290
- var now = Date.now();
289
+ const spec = specs[i];
290
+ const now = Date.now();
291
291
  spec.linkedSessions.push({
292
292
  sessionId,
293
293
  linkedAt: now,
@@ -307,12 +307,12 @@ export function linkSession(specId, sessionId, note, sessionType) {
307
307
  return null;
308
308
  }
309
309
  export function unlinkSession(specId, sessionId) {
310
- for (var i = 0; i < specs.length; i++) {
310
+ for (let i = 0; i < specs.length; i++) {
311
311
  if (specs[i].id !== specId)
312
312
  continue;
313
- var spec = specs[i];
314
- var idx = -1;
315
- for (var j = 0; j < spec.linkedSessions.length; j++) {
313
+ const spec = specs[i];
314
+ let idx = -1;
315
+ for (let j = 0; j < spec.linkedSessions.length; j++) {
316
316
  if (spec.linkedSessions[j].sessionId === sessionId) {
317
317
  idx = j;
318
318
  break;
@@ -328,11 +328,11 @@ export function unlinkSession(specId, sessionId) {
328
328
  return null;
329
329
  }
330
330
  export function addActivity(specId, activityType, detail, sessionId) {
331
- for (var i = 0; i < specs.length; i++) {
331
+ for (let i = 0; i < specs.length; i++) {
332
332
  if (specs[i].id !== specId)
333
333
  continue;
334
- var spec = specs[i];
335
- var now = Date.now();
334
+ const spec = specs[i];
335
+ const now = Date.now();
336
336
  spec.activity.push({
337
337
  timestamp: now,
338
338
  type: activityType,
@@ -2,8 +2,8 @@ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "
2
2
  import { join } from "node:path";
3
3
  import { randomBytes } from "node:crypto";
4
4
  import { getLatticeHome } from "../config.js";
5
- var notesFile = "";
6
- var notes = [];
5
+ let notesFile = "";
6
+ let notes = [];
7
7
  function getNotesPath() {
8
8
  if (!notesFile) {
9
9
  notesFile = join(getLatticeHome(), "notes.jsonl");
@@ -11,22 +11,22 @@ function getNotesPath() {
11
11
  return notesFile;
12
12
  }
13
13
  export function loadNotes() {
14
- var path = getNotesPath();
14
+ const path = getNotesPath();
15
15
  if (!existsSync(path)) {
16
16
  notes = [];
17
17
  return;
18
18
  }
19
19
  try {
20
- var raw = readFileSync(path, "utf-8");
21
- var lines = raw.trim().split("\n");
20
+ const raw = readFileSync(path, "utf-8");
21
+ const lines = raw.trim().split("\n");
22
22
  notes = [];
23
- for (var i = 0; i < lines.length; i++) {
24
- var line = lines[i].trim();
23
+ for (let i = 0; i < lines.length; i++) {
24
+ const line = lines[i].trim();
25
25
  if (!line) {
26
26
  continue;
27
27
  }
28
28
  try {
29
- var note = JSON.parse(line);
29
+ const note = JSON.parse(line);
30
30
  notes.push(note);
31
31
  }
32
32
  catch {
@@ -40,15 +40,15 @@ export function loadNotes() {
40
40
  }
41
41
  }
42
42
  function saveNotes() {
43
- var path = getNotesPath();
44
- var dir = join(path, "..");
43
+ const path = getNotesPath();
44
+ const dir = join(path, "..");
45
45
  if (!existsSync(dir)) {
46
46
  mkdirSync(dir, { recursive: true });
47
47
  }
48
- var tmp = path + ".tmp";
48
+ const tmp = path + ".tmp";
49
49
  try {
50
- var lines = [];
51
- for (var i = 0; i < notes.length; i++) {
50
+ const lines = [];
51
+ for (let i = 0; i < notes.length; i++) {
52
52
  lines.push(JSON.stringify(notes[i]));
53
53
  }
54
54
  writeFileSync(tmp, lines.join("\n") + (lines.length > 0 ? "\n" : ""));
@@ -64,8 +64,8 @@ export function listNotes(projectSlug) {
64
64
  return notes.filter(function (n) { return n.projectSlug === projectSlug; });
65
65
  }
66
66
  export function createNote(content, projectSlug) {
67
- var now = Date.now();
68
- var note = {
67
+ const now = Date.now();
68
+ const note = {
69
69
  id: "note_" + now + "_" + randomBytes(3).toString("hex"),
70
70
  content,
71
71
  createdAt: now,
@@ -77,7 +77,7 @@ export function createNote(content, projectSlug) {
77
77
  return note;
78
78
  }
79
79
  export function updateNote(id, content) {
80
- for (var i = 0; i < notes.length; i++) {
80
+ for (let i = 0; i < notes.length; i++) {
81
81
  if (notes[i].id === id) {
82
82
  notes[i].content = content;
83
83
  notes[i].updatedAt = Date.now();
@@ -88,7 +88,7 @@ export function updateNote(id, content) {
88
88
  return null;
89
89
  }
90
90
  export function deleteNote(id) {
91
- for (var i = 0; i < notes.length; i++) {
91
+ for (let i = 0; i < notes.length; i++) {
92
92
  if (notes[i].id === id) {
93
93
  notes.splice(i, 1);
94
94
  saveNotes();
@@ -2,22 +2,22 @@ import { existsSync, readFileSync, watch } from "node:fs";
2
2
  import { join } from "node:path";
3
3
  import { homedir } from "node:os";
4
4
  import { log } from "../logger.js";
5
- var TRACKED_SKILLS = [
5
+ const TRACKED_SKILLS = [
6
6
  "brainstorming",
7
7
  "writing-plans",
8
8
  "subagent-driven-development",
9
9
  "executing-plans",
10
10
  ];
11
- var installed = false;
12
- var version = null;
13
- var installPath = null;
14
- var skillContent = new Map();
15
- var watcher = null;
11
+ let installed = false;
12
+ let version = null;
13
+ let installPath = null;
14
+ const skillContent = new Map();
15
+ let watcher = null;
16
16
  function getPluginsFilePath() {
17
17
  return join(homedir(), ".claude", "plugins", "installed_plugins.json");
18
18
  }
19
19
  function detectSuperpowers() {
20
- var pluginsFile = getPluginsFilePath();
20
+ const pluginsFile = getPluginsFilePath();
21
21
  if (!existsSync(pluginsFile)) {
22
22
  installed = false;
23
23
  version = null;
@@ -26,15 +26,15 @@ function detectSuperpowers() {
26
26
  return;
27
27
  }
28
28
  try {
29
- var raw = readFileSync(pluginsFile, "utf-8");
30
- var data = JSON.parse(raw);
31
- var plugins = data.plugins || {};
32
- var found = false;
33
- for (var key of Object.keys(plugins)) {
29
+ const raw = readFileSync(pluginsFile, "utf-8");
30
+ const data = JSON.parse(raw);
31
+ const plugins = data.plugins || {};
32
+ let found = false;
33
+ for (const key of Object.keys(plugins)) {
34
34
  if (key.startsWith("superpowers@")) {
35
- var entries = plugins[key];
35
+ const entries = plugins[key];
36
36
  if (Array.isArray(entries) && entries.length > 0) {
37
- var entry = entries[0];
37
+ const entry = entries[0];
38
38
  installed = true;
39
39
  version = entry.version || null;
40
40
  installPath = entry.installPath || null;
@@ -64,11 +64,11 @@ function loadSkills() {
64
64
  skillContent.clear();
65
65
  if (!installPath)
66
66
  return;
67
- for (var name of TRACKED_SKILLS) {
68
- var skillPath = join(installPath, "skills", name, "SKILL.md");
67
+ for (const name of TRACKED_SKILLS) {
68
+ const skillPath = join(installPath, "skills", name, "SKILL.md");
69
69
  if (existsSync(skillPath)) {
70
70
  try {
71
- var content = readFileSync(skillPath, "utf-8");
71
+ const content = readFileSync(skillPath, "utf-8");
72
72
  skillContent.set(name, content);
73
73
  }
74
74
  catch (err) {
@@ -80,7 +80,7 @@ function loadSkills() {
80
80
  }
81
81
  export function initSuperpowers() {
82
82
  detectSuperpowers();
83
- var pluginsDir = join(homedir(), ".claude", "plugins");
83
+ const pluginsDir = join(homedir(), ".claude", "plugins");
84
84
  if (existsSync(pluginsDir)) {
85
85
  try {
86
86
  watcher = watch(pluginsDir, function (_eventType, filename) {
@@ -107,10 +107,10 @@ export function getAvailableSkills() {
107
107
  return Array.from(skillContent.keys());
108
108
  }
109
109
  export function buildBrainstormPrompt(spec, projectSlug) {
110
- var content = getSkillContent("brainstorming");
110
+ const content = getSkillContent("brainstorming");
111
111
  if (!content)
112
112
  return "";
113
- var append = content + "\n\n---\n\n";
113
+ let append = content + "\n\n---\n\n";
114
114
  append += "## Lattice Integration Instructions\n\n";
115
115
  append += "You are helping design a spec in the Lattice project management tool.\n\n";
116
116
  append += "**Project:** " + projectSlug + "\n";
@@ -133,10 +133,10 @@ export function buildBrainstormPrompt(spec, projectSlug) {
133
133
  return append;
134
134
  }
135
135
  export function buildWritePlanPrompt(spec, projectSlug) {
136
- var content = getSkillContent("writing-plans");
136
+ const content = getSkillContent("writing-plans");
137
137
  if (!content)
138
138
  return "";
139
- var append = content + "\n\n---\n\n";
139
+ let append = content + "\n\n---\n\n";
140
140
  append += "## Lattice Integration Instructions\n\n";
141
141
  append += "You are writing an implementation plan for a spec in Lattice.\n\n";
142
142
  append += "**Project:** " + projectSlug + "\n";
@@ -155,10 +155,10 @@ export function buildWritePlanPrompt(spec, projectSlug) {
155
155
  return append;
156
156
  }
157
157
  export function buildExecutePrompt(spec, projectSlug) {
158
- var content = getSkillContent("subagent-driven-development") || getSkillContent("executing-plans");
158
+ const content = getSkillContent("subagent-driven-development") || getSkillContent("executing-plans");
159
159
  if (!content)
160
160
  return "";
161
- var append = content + "\n\n---\n\n";
161
+ let append = content + "\n\n---\n\n";
162
162
  append += "## Lattice Integration Instructions\n\n";
163
163
  append += "You are executing an implementation plan from a Lattice spec.\n\n";
164
164
  append += "**Project:** " + projectSlug + "\n";
@@ -3,7 +3,7 @@ import { sendTo } from "../ws/broadcast.js";
3
3
  import { streamAnalyticsSections } from "../analytics/engine.js";
4
4
  registerHandler("analytics", function (clientId, message) {
5
5
  if (message.type === "analytics:request") {
6
- var msg = message;
6
+ const msg = message;
7
7
  streamAnalyticsSections(msg.scope, msg.period, msg.projectSlug, msg.sessionId, msg.forceRefresh, function (sectionName, sectionData) {
8
8
  sendTo(clientId, {
9
9
  type: "analytics:section",
@@ -5,13 +5,13 @@ import { tmpdir } from "node:os";
5
5
  import { registerHandler } from "../ws/router.js";
6
6
  import { sendTo } from "../ws/broadcast.js";
7
7
  import { log } from "../logger.js";
8
- var MAX_ATTACHMENT_SIZE = 10 * 1024 * 1024;
9
- var stores = new Map();
10
- var completed = new Map();
11
- var TTL_MS = 5 * 60 * 1000;
12
- var CLEANUP_INTERVAL_MS = 60 * 1000;
8
+ const MAX_ATTACHMENT_SIZE = 10 * 1024 * 1024;
9
+ const stores = new Map();
10
+ const completed = new Map();
11
+ const TTL_MS = 5 * 60 * 1000;
12
+ const CLEANUP_INTERVAL_MS = 60 * 1000;
13
13
  function getClientStore(clientId) {
14
- var store = stores.get(clientId);
14
+ let store = stores.get(clientId);
15
15
  if (!store) {
16
16
  store = new Map();
17
17
  stores.set(clientId, store);
@@ -19,7 +19,7 @@ function getClientStore(clientId) {
19
19
  return store;
20
20
  }
21
21
  function getClientCompleted(clientId) {
22
- var store = completed.get(clientId);
22
+ let store = completed.get(clientId);
23
23
  if (!store) {
24
24
  store = new Map();
25
25
  completed.set(clientId, store);
@@ -36,12 +36,12 @@ async function cleanupPending(pending) {
36
36
  }
37
37
  registerHandler("attachment", async function (clientId, message) {
38
38
  if (message.type === "attachment:chunk") {
39
- var msg = message;
40
- var store = getClientStore(clientId);
41
- var pending = store.get(msg.attachmentId);
39
+ const msg = message;
40
+ const store = getClientStore(clientId);
41
+ let pending = store.get(msg.attachmentId);
42
42
  if (!pending) {
43
- var tempDir = await mkdtemp(join(tmpdir(), "lattice-attach-"));
44
- var tempPath = join(tempDir, "data.bin");
43
+ const tempDir = await mkdtemp(join(tmpdir(), "lattice-attach-"));
44
+ const tempPath = join(tempDir, "data.bin");
45
45
  pending = {
46
46
  tempDir: tempDir,
47
47
  tempPath: tempPath,
@@ -62,7 +62,7 @@ registerHandler("attachment", async function (clientId, message) {
62
62
  });
63
63
  return;
64
64
  }
65
- var chunkBuffer = Buffer.from(msg.data, "base64");
65
+ const chunkBuffer = Buffer.from(msg.data, "base64");
66
66
  if (pending.totalBytes + chunkBuffer.length > MAX_ATTACHMENT_SIZE) {
67
67
  await cleanupPending(pending);
68
68
  store.delete(msg.attachmentId);
@@ -86,9 +86,9 @@ registerHandler("attachment", async function (clientId, message) {
86
86
  return;
87
87
  }
88
88
  if (message.type === "attachment:complete") {
89
- var completeMsg = message;
90
- var completeStore = getClientStore(clientId);
91
- var completePending = completeStore.get(completeMsg.attachmentId);
89
+ const completeMsg = message;
90
+ const completeStore = getClientStore(clientId);
91
+ const completePending = completeStore.get(completeMsg.attachmentId);
92
92
  if (!completePending) {
93
93
  sendTo(clientId, {
94
94
  type: "attachment:error",
@@ -109,10 +109,10 @@ registerHandler("attachment", async function (clientId, message) {
109
109
  completePending.writeStream.end(function () { resolve(); });
110
110
  });
111
111
  try {
112
- var assembled = await readTempFile(completePending.tempPath);
113
- var isText = completeMsg.attachmentType === "paste" || isTextMimeType(completeMsg.mimeType);
114
- var content = isText ? assembled.toString("utf-8") : assembled.toString("base64");
115
- var attachment = {
112
+ const assembled = await readTempFile(completePending.tempPath);
113
+ const isText = completeMsg.attachmentType === "paste" || isTextMimeType(completeMsg.mimeType);
114
+ const content = isText ? assembled.toString("utf-8") : assembled.toString("base64");
115
+ const attachment = {
116
116
  type: completeMsg.attachmentType,
117
117
  name: completeMsg.name,
118
118
  content,
@@ -120,7 +120,7 @@ registerHandler("attachment", async function (clientId, message) {
120
120
  size: completeMsg.size,
121
121
  lineCount: completeMsg.lineCount,
122
122
  };
123
- var finishedStore = getClientCompleted(clientId);
123
+ const finishedStore = getClientCompleted(clientId);
124
124
  finishedStore.set(completeMsg.attachmentId, attachment);
125
125
  }
126
126
  catch (err) {
@@ -138,8 +138,8 @@ registerHandler("attachment", async function (clientId, message) {
138
138
  });
139
139
  function readTempFile(path) {
140
140
  return new Promise(function (resolve, reject) {
141
- var chunks = [];
142
- var stream = createReadStream(path);
141
+ const chunks = [];
142
+ const stream = createReadStream(path);
143
143
  stream.on("data", function (chunk) { chunks.push(chunk); });
144
144
  stream.on("end", function () { resolve(Buffer.concat(chunks)); });
145
145
  stream.on("error", reject);
@@ -148,7 +148,7 @@ function readTempFile(path) {
148
148
  function isTextMimeType(mime) {
149
149
  if (mime.startsWith("text/"))
150
150
  return true;
151
- var textTypes = [
151
+ const textTypes = [
152
152
  "application/json",
153
153
  "application/xml",
154
154
  "application/javascript",
@@ -160,10 +160,10 @@ function isTextMimeType(mime) {
160
160
  return textTypes.indexOf(mime) !== -1;
161
161
  }
162
162
  export function getAttachments(clientId, ids) {
163
- var store = getClientCompleted(clientId);
164
- var result = [];
165
- for (var i = 0; i < ids.length; i++) {
166
- var att = store.get(ids[i]);
163
+ const store = getClientCompleted(clientId);
164
+ const result = [];
165
+ for (let i = 0; i < ids.length; i++) {
166
+ const att = store.get(ids[i]);
167
167
  if (att) {
168
168
  result.push(att);
169
169
  store.delete(ids[i]);
@@ -172,17 +172,17 @@ export function getAttachments(clientId, ids) {
172
172
  return result;
173
173
  }
174
174
  export function cleanupClient(clientId) {
175
- var clientStore = stores.get(clientId);
175
+ const clientStore = stores.get(clientId);
176
176
  if (clientStore) {
177
- for (var [, pending] of clientStore) {
177
+ for (const [, pending] of clientStore) {
178
178
  void cleanupPending(pending);
179
179
  }
180
180
  }
181
181
  stores.delete(clientId);
182
182
  completed.delete(clientId);
183
183
  }
184
- var ttlCleanupInterval = setInterval(function () {
185
- var now = Date.now();
184
+ const ttlCleanupInterval = setInterval(function () {
185
+ const now = Date.now();
186
186
  stores.forEach(function (store) {
187
187
  store.forEach(function (pending, id) {
188
188
  if (now - pending.createdAt > TTL_MS) {
@@ -3,8 +3,8 @@ import { sendTo } from "../ws/broadcast.js";
3
3
  import { listBookmarks, addBookmark, removeBookmark } from "../project/bookmarks.js";
4
4
  registerHandler("bookmark", function (clientId, message) {
5
5
  if (message.type === "bookmark:list") {
6
- var listMsg = message;
7
- var isSessionScoped = Boolean(listMsg.sessionId);
6
+ const listMsg = message;
7
+ const isSessionScoped = Boolean(listMsg.sessionId);
8
8
  sendTo(clientId, {
9
9
  type: "bookmark:list_result",
10
10
  scope: isSessionScoped ? "session" : "all",
@@ -13,7 +13,7 @@ registerHandler("bookmark", function (clientId, message) {
13
13
  return;
14
14
  }
15
15
  if (message.type === "bookmark:add") {
16
- var addMsg = message;
16
+ const addMsg = message;
17
17
  addBookmark({
18
18
  sessionId: addMsg.sessionId,
19
19
  projectSlug: addMsg.projectSlug,
@@ -29,7 +29,7 @@ registerHandler("bookmark", function (clientId, message) {
29
29
  return;
30
30
  }
31
31
  if (message.type === "bookmark:remove") {
32
- var removeMsg = message;
32
+ const removeMsg = message;
33
33
  removeBookmark(removeMsg.id);
34
34
  sendTo(clientId, {
35
35
  type: "bookmark:list_result",
@@ -4,7 +4,7 @@ import { getActiveBrainstorm, getAnyActiveBrainstorm, writeBrainstormEvent, stop
4
4
  import { getActiveProjectForClient } from "./fs.js";
5
5
  registerHandler("brainstorm", function (clientId, message) {
6
6
  if (message.type === "brainstorm:select") {
7
- var selectMsg = message;
7
+ const selectMsg = message;
8
8
  writeBrainstormEvent(selectMsg.sessionDir, {
9
9
  type: "click",
10
10
  choice: selectMsg.choice,
@@ -14,13 +14,13 @@ registerHandler("brainstorm", function (clientId, message) {
14
14
  return;
15
15
  }
16
16
  if (message.type === "brainstorm:stop") {
17
- var stopProjectSlug = getActiveProjectForClient(clientId);
17
+ const stopProjectSlug = getActiveProjectForClient(clientId);
18
18
  stopBrainstorm(stopProjectSlug || undefined);
19
19
  return;
20
20
  }
21
21
  if (message.type === "brainstorm:status_request") {
22
- var projectSlug = getActiveProjectForClient(clientId);
23
- var active = projectSlug ? getActiveBrainstorm(projectSlug) : getAnyActiveBrainstorm();
22
+ const projectSlug = getActiveProjectForClient(clientId);
23
+ const active = projectSlug ? getActiveBrainstorm(projectSlug) : getAnyActiveBrainstorm();
24
24
  if (active) {
25
25
  sendTo(clientId, {
26
26
  type: "brainstorm:status",