@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
@@ -6,24 +6,24 @@ import { registerHandler } from "../ws/router.js";
6
6
  import { sendTo } from "../ws/broadcast.js";
7
7
  import { loadConfig } from "../config.js";
8
8
  import { readGlobalMcpServers, readGlobalSkills } from "../project/project-files.js";
9
- var searchCache = new Map();
10
- var skillsCache = null;
11
- var lastScanTime = 0;
12
- var CACHE_TTL_MS = 60000;
9
+ const searchCache = new Map();
10
+ let skillsCache = null;
11
+ let lastScanTime = 0;
12
+ const CACHE_TTL_MS = 60000;
13
13
  function parseFrontmatter(content) {
14
- var match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
14
+ const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
15
15
  if (!match)
16
16
  return { name: "", description: "" };
17
- var yaml = match[1];
18
- var name = "";
19
- var desc = "";
20
- var lines = yaml.split(/\r?\n/);
21
- for (var i = 0; i < lines.length; i++) {
22
- var line = lines[i];
23
- var nameMatch = line.match(/^name:\s*(.+)/);
17
+ const yaml = match[1];
18
+ let name = "";
19
+ let desc = "";
20
+ const lines = yaml.split(/\r?\n/);
21
+ for (let i = 0; i < lines.length; i++) {
22
+ const line = lines[i];
23
+ const nameMatch = line.match(/^name:\s*(.+)/);
24
24
  if (nameMatch)
25
25
  name = nameMatch[1].trim().replace(/^["']|["']$/g, "");
26
- var descMatch = line.match(/^description:\s*(.+)/);
26
+ const descMatch = line.match(/^description:\s*(.+)/);
27
27
  if (descMatch)
28
28
  desc = descMatch[1].trim().replace(/^["']|["']$/g, "");
29
29
  }
@@ -33,7 +33,7 @@ function findSkillFiles(rootDir) {
33
33
  if (!existsSync(rootDir))
34
34
  return [];
35
35
  try {
36
- var output = execSync("find " + JSON.stringify(rootDir) + " -name SKILL.md -type f 2>/dev/null", { encoding: "utf-8", timeout: 5000 });
36
+ const output = execSync("find " + JSON.stringify(rootDir) + " -name SKILL.md -type f 2>/dev/null", { encoding: "utf-8", timeout: 5000 });
37
37
  return output.trim().split("\n").filter(function (l) { return l.length > 0; });
38
38
  }
39
39
  catch {
@@ -42,12 +42,12 @@ function findSkillFiles(rootDir) {
42
42
  }
43
43
  function parseCommandFile(filePath, fileName) {
44
44
  try {
45
- var content = readFileSync(filePath, "utf-8");
46
- var name = fileName.replace(/\.md$/, "");
47
- var desc = "";
48
- var lines = content.split(/\r?\n/);
49
- for (var i = 0; i < Math.min(lines.length, 10); i++) {
50
- var line = lines[i].trim();
45
+ const content = readFileSync(filePath, "utf-8");
46
+ const name = fileName.replace(/\.md$/, "");
47
+ let desc = "";
48
+ const lines = content.split(/\r?\n/);
49
+ for (let i = 0; i < Math.min(lines.length, 10); i++) {
50
+ const line = lines[i].trim();
51
51
  if (line.length > 0 && !line.startsWith("#") && !line.startsWith("---")) {
52
52
  desc = line.slice(0, 120);
53
53
  break;
@@ -60,16 +60,16 @@ function parseCommandFile(filePath, fileName) {
60
60
  }
61
61
  }
62
62
  function scanCommandsDir(dirPath) {
63
- var results = [];
63
+ const results = [];
64
64
  if (!existsSync(dirPath))
65
65
  return results;
66
66
  try {
67
- var entries = readdirSync(dirPath);
68
- for (var i = 0; i < entries.length; i++) {
67
+ const entries = readdirSync(dirPath);
68
+ for (let i = 0; i < entries.length; i++) {
69
69
  if (!entries[i].endsWith(".md"))
70
70
  continue;
71
- var filePath = join(dirPath, entries[i]);
72
- var info = parseCommandFile(filePath, entries[i]);
71
+ const filePath = join(dirPath, entries[i]);
72
+ const info = parseCommandFile(filePath, entries[i]);
73
73
  if (info)
74
74
  results.push(info);
75
75
  }
@@ -78,46 +78,46 @@ function scanCommandsDir(dirPath) {
78
78
  return results;
79
79
  }
80
80
  function getSkills() {
81
- var now = Date.now();
81
+ const now = Date.now();
82
82
  if (skillsCache && now - lastScanTime < CACHE_TTL_MS) {
83
83
  return skillsCache;
84
84
  }
85
- var home = homedir();
86
- var skills = [];
87
- var skillDirs = [
85
+ const home = homedir();
86
+ const skills = [];
87
+ const skillDirs = [
88
88
  join(home, ".claude"),
89
89
  join(home, ".agents"),
90
90
  join(home, ".superpowers"),
91
91
  ];
92
- for (var d = 0; d < skillDirs.length; d++) {
93
- var files = findSkillFiles(skillDirs[d]);
94
- for (var f = 0; f < files.length; f++) {
92
+ for (let d = 0; d < skillDirs.length; d++) {
93
+ const files = findSkillFiles(skillDirs[d]);
94
+ for (let f = 0; f < files.length; f++) {
95
95
  try {
96
- var content = readFileSync(files[f], "utf-8");
97
- var meta = parseFrontmatter(content);
96
+ const content = readFileSync(files[f], "utf-8");
97
+ const meta = parseFrontmatter(content);
98
98
  if (meta.name) {
99
- var skillName = meta.name;
100
- var filePath = files[f];
101
- var pluginMatch = filePath.match(/plugins\/([^/]+)\/skills\/([^/]+)\/SKILL\.md$/);
99
+ let skillName = meta.name;
100
+ const filePath = files[f];
101
+ const pluginMatch = filePath.match(/plugins\/([^/]+)\/skills\/([^/]+)\/SKILL\.md$/);
102
102
  if (pluginMatch) {
103
- var pluginName = pluginMatch[1];
104
- var rawSkillName = pluginMatch[2];
103
+ const pluginName = pluginMatch[1];
104
+ const rawSkillName = pluginMatch[2];
105
105
  if (skillName.indexOf(":") === -1 && skillName === rawSkillName) {
106
106
  skillName = pluginName + ":" + skillName;
107
107
  }
108
108
  }
109
- var extPluginMatch = filePath.match(/external_plugins\/([^/]+)\/skills\/([^/]+)\/SKILL\.md$/);
109
+ const extPluginMatch = filePath.match(/external_plugins\/([^/]+)\/skills\/([^/]+)\/SKILL\.md$/);
110
110
  if (extPluginMatch) {
111
- var extPluginName = extPluginMatch[1];
112
- var extSkillName = extPluginMatch[2];
111
+ const extPluginName = extPluginMatch[1];
112
+ const extSkillName = extPluginMatch[2];
113
113
  if (skillName.indexOf(":") === -1 && skillName === extSkillName) {
114
114
  skillName = extPluginName + ":" + skillName;
115
115
  }
116
116
  }
117
- var marketplaceSkillMatch = filePath.match(/marketplaces\/([^/]+)\/.claude\/skills\/([^/]+)\/SKILL\.md$/);
117
+ const marketplaceSkillMatch = filePath.match(/marketplaces\/([^/]+)\/.claude\/skills\/([^/]+)\/SKILL\.md$/);
118
118
  if (marketplaceSkillMatch) {
119
- var mktName = marketplaceSkillMatch[1];
120
- var mktSkill = marketplaceSkillMatch[2];
119
+ const mktName = marketplaceSkillMatch[1];
120
+ const mktSkill = marketplaceSkillMatch[2];
121
121
  if (skillName.indexOf(":") === -1 && skillName === mktSkill) {
122
122
  skillName = mktName + ":" + skillName;
123
123
  }
@@ -132,26 +132,26 @@ function getSkills() {
132
132
  catch { }
133
133
  }
134
134
  }
135
- var config = loadConfig();
136
- for (var p = 0; p < config.projects.length; p++) {
137
- var projectPath = config.projects[p].path;
138
- var projectSkillDirs = [
135
+ const config = loadConfig();
136
+ for (let p = 0; p < config.projects.length; p++) {
137
+ const projectPath = config.projects[p].path;
138
+ const projectSkillDirs = [
139
139
  join(projectPath, ".claude", "skills"),
140
140
  join(projectPath, ".claude", "commands"),
141
141
  join(projectPath, ".superpowers", "skills"),
142
142
  ];
143
- for (var pd = 0; pd < projectSkillDirs.length; pd++) {
143
+ for (let pd = 0; pd < projectSkillDirs.length; pd++) {
144
144
  if (projectSkillDirs[pd].endsWith("commands")) {
145
- var cmds = scanCommandsDir(projectSkillDirs[pd]);
146
- for (var c = 0; c < cmds.length; c++)
145
+ const cmds = scanCommandsDir(projectSkillDirs[pd]);
146
+ for (let c = 0; c < cmds.length; c++)
147
147
  skills.push(cmds[c]);
148
148
  }
149
149
  else {
150
- var projFiles = findSkillFiles(projectSkillDirs[pd]);
151
- for (var pf = 0; pf < projFiles.length; pf++) {
150
+ const projFiles = findSkillFiles(projectSkillDirs[pd]);
151
+ for (let pf = 0; pf < projFiles.length; pf++) {
152
152
  try {
153
- var projContent = readFileSync(projFiles[pf], "utf-8");
154
- var projMeta = parseFrontmatter(projContent);
153
+ const projContent = readFileSync(projFiles[pf], "utf-8");
154
+ const projMeta = parseFrontmatter(projContent);
155
155
  if (projMeta.name) {
156
156
  skills.push({
157
157
  name: projMeta.name,
@@ -165,28 +165,28 @@ function getSkills() {
165
165
  }
166
166
  }
167
167
  }
168
- var globalCommands = scanCommandsDir(join(home, ".claude", "commands"));
169
- for (var gc = 0; gc < globalCommands.length; gc++) {
168
+ const globalCommands = scanCommandsDir(join(home, ".claude", "commands"));
169
+ for (let gc = 0; gc < globalCommands.length; gc++) {
170
170
  skills.push(globalCommands[gc]);
171
171
  }
172
- var namespacedBareNames = new Set();
173
- for (var n = 0; n < skills.length; n++) {
174
- var colonIdx = skills[n].name.indexOf(":");
172
+ const namespacedBareNames = new Set();
173
+ for (let n = 0; n < skills.length; n++) {
174
+ const colonIdx = skills[n].name.indexOf(":");
175
175
  if (colonIdx !== -1) {
176
176
  namespacedBareNames.add(skills[n].name.slice(colonIdx + 1));
177
177
  }
178
178
  }
179
- var filtered = [];
180
- for (var fi = 0; fi < skills.length; fi++) {
179
+ const filtered = [];
180
+ for (let fi = 0; fi < skills.length; fi++) {
181
181
  if (skills[fi].name.indexOf(":") === -1 && namespacedBareNames.has(skills[fi].name)) {
182
182
  continue;
183
183
  }
184
184
  filtered.push(skills[fi]);
185
185
  }
186
186
  filtered.sort(function (a, b) { return a.name.localeCompare(b.name); });
187
- var seen = new Set();
188
- var unique = [];
189
- for (var i = 0; i < filtered.length; i++) {
187
+ const seen = new Set();
188
+ const unique = [];
189
+ for (let i = 0; i < filtered.length; i++) {
190
190
  if (!seen.has(filtered[i].name)) {
191
191
  seen.add(filtered[i].name);
192
192
  unique.push(filtered[i]);
@@ -197,8 +197,8 @@ function getSkills() {
197
197
  return unique;
198
198
  }
199
199
  export function resolveSkillContent(skillName) {
200
- var skills = getSkills();
201
- var match = skills.find(function (s) { return s.name === skillName; });
200
+ const skills = getSkills();
201
+ const match = skills.find(function (s) { return s.name === skillName; });
202
202
  if (!match)
203
203
  return null;
204
204
  try {
@@ -210,19 +210,19 @@ export function resolveSkillContent(skillName) {
210
210
  }
211
211
  registerHandler("skills", function (clientId, message) {
212
212
  if (message.type === "skills:list_request") {
213
- var skills = getSkills();
213
+ const skills = getSkills();
214
214
  sendTo(clientId, { type: "skills:list", skills: skills });
215
215
  return;
216
216
  }
217
217
  if (message.type === "skills:search") {
218
- var searchMsg = message;
219
- var query = searchMsg.query.trim();
218
+ const searchMsg = message;
219
+ const query = searchMsg.query.trim();
220
220
  if (!query) {
221
221
  sendTo(clientId, { type: "skills:search_results", query: query, skills: [], count: 0 });
222
222
  return;
223
223
  }
224
- var cacheKey = "search:" + query;
225
- var cached = searchCache.get(cacheKey);
224
+ const cacheKey = "search:" + query;
225
+ const cached = searchCache.get(cacheKey);
226
226
  if (cached && Date.now() - cached.time < 60000) {
227
227
  sendTo(clientId, { type: "skills:search_results", query: query, skills: cached.skills, count: cached.count });
228
228
  return;
@@ -230,10 +230,10 @@ registerHandler("skills", function (clientId, message) {
230
230
  void fetch("https://skills.sh/api/search?q=" + encodeURIComponent(query))
231
231
  .then(function (res) { return res.json(); })
232
232
  .then(function (data) {
233
- var skills = (data.skills ?? []).map(function (s) {
233
+ const skills = (data.skills ?? []).map(function (s) {
234
234
  return { id: s.id, skillId: s.skillId, name: s.name, source: s.source, installs: s.installs };
235
235
  });
236
- var count = data.count ?? skills.length;
236
+ const count = data.count ?? skills.length;
237
237
  searchCache.set(cacheKey, { skills: skills, count: count, time: Date.now() });
238
238
  sendTo(clientId, { type: "skills:search_results", query: query, skills: skills, count: count });
239
239
  })
@@ -243,21 +243,21 @@ registerHandler("skills", function (clientId, message) {
243
243
  return;
244
244
  }
245
245
  if (message.type === "skills:install") {
246
- var installMsg = message;
247
- var cwd = homedir();
246
+ const installMsg = message;
247
+ let cwd = homedir();
248
248
  if (installMsg.scope === "project" && installMsg.projectSlug) {
249
- var installConfig = loadConfig();
250
- var installProject = installConfig.projects.find(function (p) { return p.slug === installMsg.projectSlug; });
249
+ const installConfig = loadConfig();
250
+ const installProject = installConfig.projects.find(function (p) { return p.slug === installMsg.projectSlug; });
251
251
  if (installProject) {
252
252
  cwd = installProject.path;
253
253
  }
254
254
  }
255
255
  try {
256
- var proc = spawn("npx", ["skillsadd", installMsg.source], {
256
+ const proc = spawn("npx", ["skillsadd", installMsg.source], {
257
257
  cwd: cwd,
258
258
  stdio: ["ignore", "pipe", "pipe"],
259
259
  });
260
- var timeout = setTimeout(function () {
260
+ const timeout = setTimeout(function () {
261
261
  proc.kill();
262
262
  }, 60000);
263
263
  proc.on("close", function (code) {
@@ -270,7 +270,7 @@ registerHandler("skills", function (clientId, message) {
270
270
  sendTo(clientId, { type: "skills:install_result", success: false, message: "Install failed (exit code " + code + ")" });
271
271
  }
272
272
  if (installMsg.scope === "global") {
273
- var globalConfig = loadConfig();
273
+ const globalConfig = loadConfig();
274
274
  sendTo(clientId, {
275
275
  type: "settings:data",
276
276
  config: globalConfig,
@@ -286,13 +286,13 @@ registerHandler("skills", function (clientId, message) {
286
286
  return;
287
287
  }
288
288
  if (message.type === "skills:view") {
289
- var viewMsg = message;
289
+ const viewMsg = message;
290
290
  try {
291
291
  if (!existsSync(viewMsg.path)) {
292
292
  sendTo(clientId, { type: "skills:view_result", path: viewMsg.path, content: "File not found." });
293
293
  return;
294
294
  }
295
- var viewContent = readFileSync(viewMsg.path, "utf-8");
295
+ const viewContent = readFileSync(viewMsg.path, "utf-8");
296
296
  sendTo(clientId, { type: "skills:view_result", path: viewMsg.path, content: viewContent });
297
297
  }
298
298
  catch {
@@ -301,9 +301,9 @@ registerHandler("skills", function (clientId, message) {
301
301
  return;
302
302
  }
303
303
  if (message.type === "skills:delete") {
304
- var deleteMsg = message;
304
+ const deleteMsg = message;
305
305
  try {
306
- var skillDir = dirname(deleteMsg.path);
306
+ const skillDir = dirname(deleteMsg.path);
307
307
  if (!existsSync(deleteMsg.path)) {
308
308
  sendTo(clientId, { type: "skills:delete_result", success: false, message: "Skill not found." });
309
309
  return;
@@ -311,7 +311,7 @@ registerHandler("skills", function (clientId, message) {
311
311
  rmSync(skillDir, { recursive: true, force: true });
312
312
  skillsCache = null;
313
313
  sendTo(clientId, { type: "skills:delete_result", success: true, message: "Skill deleted." });
314
- var delConfig = loadConfig();
314
+ const delConfig = loadConfig();
315
315
  sendTo(clientId, {
316
316
  type: "settings:data",
317
317
  config: delConfig,
@@ -325,13 +325,13 @@ registerHandler("skills", function (clientId, message) {
325
325
  return;
326
326
  }
327
327
  if (message.type === "skills:update") {
328
- var updateMsg = message;
328
+ const updateMsg = message;
329
329
  try {
330
- var updateProc = spawn("npx", ["skillsadd", updateMsg.source], {
330
+ const updateProc = spawn("npx", ["skillsadd", updateMsg.source], {
331
331
  cwd: homedir(),
332
332
  stdio: ["ignore", "pipe", "pipe"],
333
333
  });
334
- var updateTimeout = setTimeout(function () {
334
+ const updateTimeout = setTimeout(function () {
335
335
  updateProc.kill();
336
336
  }, 60000);
337
337
  updateProc.on("close", function (code) {
@@ -343,7 +343,7 @@ registerHandler("skills", function (clientId, message) {
343
343
  else {
344
344
  sendTo(clientId, { type: "skills:install_result", success: false, message: "Update failed (exit code " + code + ")" });
345
345
  }
346
- var updConfig = loadConfig();
346
+ const updConfig = loadConfig();
347
347
  sendTo(clientId, {
348
348
  type: "settings:data",
349
349
  config: updConfig,
@@ -5,13 +5,13 @@ import { createSession, updateSessionInIndex } from "../project/session.js";
5
5
  import { buildBrainstormPrompt, buildWritePlanPrompt, buildExecutePrompt } from "../features/superpowers.js";
6
6
  registerHandler("specs", function (clientId, message) {
7
7
  if (message.type === "specs:list") {
8
- var listMsg = message;
8
+ const listMsg = message;
9
9
  sendTo(clientId, { type: "specs:list_result", specs: listSpecs(listMsg.projectSlug) });
10
10
  return;
11
11
  }
12
12
  if (message.type === "specs:get") {
13
- var getMsg = message;
14
- var spec = getSpec(getMsg.id);
13
+ const getMsg = message;
14
+ const spec = getSpec(getMsg.id);
15
15
  if (!spec) {
16
16
  sendTo(clientId, { type: "chat:error", message: "Spec not found" });
17
17
  return;
@@ -20,8 +20,8 @@ registerHandler("specs", function (clientId, message) {
20
20
  return;
21
21
  }
22
22
  if (message.type === "specs:create") {
23
- var createMsg = message;
24
- var created = createSpec({
23
+ const createMsg = message;
24
+ const created = createSpec({
25
25
  projectSlug: createMsg.projectSlug,
26
26
  title: createMsg.title,
27
27
  tagline: createMsg.tagline,
@@ -34,13 +34,13 @@ registerHandler("specs", function (clientId, message) {
34
34
  return;
35
35
  }
36
36
  if (message.type === "specs:create-with-brainstorm") {
37
- var brainstormMsg = message;
38
- var slug = brainstormMsg.projectSlug;
39
- var newSpec = createSpec({ projectSlug: slug, title: "New Spec" });
40
- var brainstormSession = createSession(slug, "brainstorm");
37
+ const brainstormMsg = message;
38
+ const slug = brainstormMsg.projectSlug;
39
+ const newSpec = createSpec({ projectSlug: slug, title: "New Spec" });
40
+ const brainstormSession = createSession(slug, "brainstorm");
41
41
  updateSessionInIndex(slug, brainstormSession);
42
42
  linkSession(newSpec.id, brainstormSession.id, "Brainstorm session", "brainstorm");
43
- var brainstormPrompt = buildBrainstormPrompt(newSpec, slug);
43
+ const brainstormPrompt = buildBrainstormPrompt(newSpec, slug);
44
44
  sendTo(clientId, {
45
45
  type: "specs:brainstorm-started",
46
46
  spec: newSpec,
@@ -48,49 +48,72 @@ registerHandler("specs", function (clientId, message) {
48
48
  systemPrompt: { type: "preset", preset: "claude_code", append: brainstormPrompt },
49
49
  });
50
50
  broadcastToProject(slug, { type: "specs:created", spec: newSpec });
51
+ broadcastToProject(slug, {
52
+ type: "session:list",
53
+ projectSlug: slug,
54
+ sessions: [brainstormSession],
55
+ totalCount: undefined,
56
+ offset: 0,
57
+ });
51
58
  return;
52
59
  }
53
60
  if (message.type === "specs:start-plan") {
54
- var planMsg = message;
55
- var planSpec = getSpec(planMsg.specId);
61
+ const planMsg = message;
62
+ const planSpec = getSpec(planMsg.specId);
56
63
  if (!planSpec) {
57
64
  sendTo(clientId, { type: "chat:error", message: "Spec not found" });
58
65
  return;
59
66
  }
60
- var planSession = createSession(planMsg.projectSlug, "write-plan");
67
+ const planSession = createSession(planMsg.projectSlug, "write-plan");
68
+ planSession.title = "Plan: " + planSpec.title;
61
69
  updateSessionInIndex(planMsg.projectSlug, planSession);
62
70
  linkSession(planSpec.id, planSession.id, "Write plan session", "write-plan");
63
- var planPrompt = buildWritePlanPrompt(planSpec, planMsg.projectSlug);
71
+ const planPrompt = buildWritePlanPrompt(planSpec, planMsg.projectSlug);
64
72
  sendTo(clientId, {
65
73
  type: "specs:plan-started",
66
74
  spec: planSpec,
67
75
  sessionId: planSession.id,
68
76
  systemPrompt: { type: "preset", preset: "claude_code", append: planPrompt },
69
77
  });
78
+ broadcastToProject(planMsg.projectSlug, {
79
+ type: "session:list",
80
+ projectSlug: planMsg.projectSlug,
81
+ sessions: [planSession],
82
+ totalCount: undefined,
83
+ offset: 0,
84
+ });
70
85
  return;
71
86
  }
72
87
  if (message.type === "specs:start-execute") {
73
- var execMsg = message;
74
- var execSpec = getSpec(execMsg.specId);
88
+ const execMsg = message;
89
+ const execSpec = getSpec(execMsg.specId);
75
90
  if (!execSpec) {
76
91
  sendTo(clientId, { type: "chat:error", message: "Spec not found" });
77
92
  return;
78
93
  }
79
- var execSession = createSession(execMsg.projectSlug, "execute");
94
+ const execSession = createSession(execMsg.projectSlug, "execute");
95
+ execSession.title = "Execute: " + execSpec.title;
80
96
  updateSessionInIndex(execMsg.projectSlug, execSession);
81
97
  linkSession(execSpec.id, execSession.id, "Execute session", "execute");
82
- var execPrompt = buildExecutePrompt(execSpec, execMsg.projectSlug);
98
+ const execPrompt = buildExecutePrompt(execSpec, execMsg.projectSlug);
83
99
  sendTo(clientId, {
84
100
  type: "specs:execute-started",
85
101
  spec: execSpec,
86
102
  sessionId: execSession.id,
87
103
  systemPrompt: { type: "preset", preset: "claude_code", append: execPrompt },
88
104
  });
105
+ broadcastToProject(execMsg.projectSlug, {
106
+ type: "session:list",
107
+ projectSlug: execMsg.projectSlug,
108
+ sessions: [execSession],
109
+ totalCount: undefined,
110
+ offset: 0,
111
+ });
89
112
  return;
90
113
  }
91
114
  if (message.type === "specs:update") {
92
- var updateMsg = message;
93
- var updated = updateSpec(updateMsg.id, {
115
+ const updateMsg = message;
116
+ const updated = updateSpec(updateMsg.id, {
94
117
  title: updateMsg.title,
95
118
  tagline: updateMsg.tagline,
96
119
  status: updateMsg.status,
@@ -110,8 +133,8 @@ registerHandler("specs", function (clientId, message) {
110
133
  return;
111
134
  }
112
135
  if (message.type === "specs:delete") {
113
- var deleteMsg = message;
114
- var toDelete = getSpec(deleteMsg.id);
136
+ const deleteMsg = message;
137
+ const toDelete = getSpec(deleteMsg.id);
115
138
  if (!toDelete) {
116
139
  sendTo(clientId, { type: "chat:error", message: "Spec not found" });
117
140
  return;
@@ -121,8 +144,8 @@ registerHandler("specs", function (clientId, message) {
121
144
  return;
122
145
  }
123
146
  if (message.type === "specs:link-session") {
124
- var linkMsg = message;
125
- var linked = linkSession(linkMsg.id, linkMsg.sessionId, linkMsg.note);
147
+ const linkMsg = message;
148
+ const linked = linkSession(linkMsg.id, linkMsg.sessionId, linkMsg.note);
126
149
  if (!linked) {
127
150
  sendTo(clientId, { type: "chat:error", message: "Spec not found" });
128
151
  return;
@@ -131,8 +154,8 @@ registerHandler("specs", function (clientId, message) {
131
154
  return;
132
155
  }
133
156
  if (message.type === "specs:unlink-session") {
134
- var unlinkMsg = message;
135
- var unlinked = unlinkSession(unlinkMsg.id, unlinkMsg.sessionId);
157
+ const unlinkMsg = message;
158
+ const unlinked = unlinkSession(unlinkMsg.id, unlinkMsg.sessionId);
136
159
  if (!unlinked) {
137
160
  sendTo(clientId, { type: "chat:error", message: "Spec not found" });
138
161
  return;
@@ -141,8 +164,8 @@ registerHandler("specs", function (clientId, message) {
141
164
  return;
142
165
  }
143
166
  if (message.type === "specs:activity") {
144
- var actMsg = message;
145
- var withActivity = addActivity(actMsg.id, actMsg.activityType, actMsg.detail, actMsg.sessionId);
167
+ const actMsg = message;
168
+ const withActivity = addActivity(actMsg.id, actMsg.activityType, actMsg.detail, actMsg.sessionId);
146
169
  if (!withActivity) {
147
170
  sendTo(clientId, { type: "chat:error", message: "Spec not found" });
148
171
  return;
@@ -4,9 +4,9 @@ import { createTerminal, destroyTerminal, writeToTerminal, resizeTerminal } from
4
4
  import { getActiveSession } from "./chat.js";
5
5
  import { getProjectBySlug } from "../project/registry.js";
6
6
  import { homedir } from "node:os";
7
- var clientTerminals = new Map();
7
+ const clientTerminals = new Map();
8
8
  function getOrCreateClientSet(clientId) {
9
- var set = clientTerminals.get(clientId);
9
+ let set = clientTerminals.get(clientId);
10
10
  if (!set) {
11
11
  set = new Set();
12
12
  clientTerminals.set(clientId, set);
@@ -14,7 +14,7 @@ function getOrCreateClientSet(clientId) {
14
14
  return set;
15
15
  }
16
16
  export function cleanupClientTerminals(clientId) {
17
- var set = clientTerminals.get(clientId);
17
+ const set = clientTerminals.get(clientId);
18
18
  if (set) {
19
19
  set.forEach(function (termId) {
20
20
  destroyTerminal(termId);
@@ -24,24 +24,24 @@ export function cleanupClientTerminals(clientId) {
24
24
  }
25
25
  registerHandler("terminal", function (clientId, message) {
26
26
  if (message.type === "terminal:create") {
27
- var createMsg = message;
28
- var cwd = homedir();
27
+ const createMsg = message;
28
+ let cwd = homedir();
29
29
  if (createMsg.projectSlug) {
30
- var slugProject = getProjectBySlug(createMsg.projectSlug);
30
+ const slugProject = getProjectBySlug(createMsg.projectSlug);
31
31
  if (slugProject) {
32
32
  cwd = slugProject.path;
33
33
  }
34
34
  }
35
35
  else {
36
- var active = getActiveSession(clientId);
36
+ const active = getActiveSession(clientId);
37
37
  if (active) {
38
- var project = getProjectBySlug(active.projectSlug);
38
+ const project = getProjectBySlug(active.projectSlug);
39
39
  if (project) {
40
40
  cwd = project.path;
41
41
  }
42
42
  }
43
43
  }
44
- var termId = createTerminal(cwd, function (data) {
44
+ const termId = createTerminal(cwd, function (data) {
45
45
  sendTo(clientId, { type: "terminal:output", termId: termId, data: data });
46
46
  }, function (code) {
47
47
  sendTo(clientId, { type: "terminal:exited", termId: termId, code: code });
@@ -52,8 +52,8 @@ registerHandler("terminal", function (clientId, message) {
52
52
  return;
53
53
  }
54
54
  if (message.type === "terminal:input") {
55
- var inputMsg = message;
56
- var clientSet = clientTerminals.get(clientId);
55
+ const inputMsg = message;
56
+ const clientSet = clientTerminals.get(clientId);
57
57
  if (!clientSet || !clientSet.has(inputMsg.termId)) {
58
58
  return;
59
59
  }
@@ -64,8 +64,8 @@ registerHandler("terminal", function (clientId, message) {
64
64
  return;
65
65
  }
66
66
  if (message.type === "terminal:resize") {
67
- var resizeMsg = message;
68
- var resizeClientSet = clientTerminals.get(clientId);
67
+ const resizeMsg = message;
68
+ const resizeClientSet = clientTerminals.get(clientId);
69
69
  if (!resizeClientSet || !resizeClientSet.has(resizeMsg.termId)) {
70
70
  return;
71
71
  }