@cryptiklemur/lattice 1.37.2 → 1.38.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 (2) hide show
  1. package/package.json +1 -1
  2. package/server/src/index.ts +154 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cryptiklemur/lattice",
3
- "version": "1.37.2",
3
+ "version": "1.38.0",
4
4
  "description": "Multi-machine agentic dashboard for Claude Code. Monitor sessions, manage MCP servers and skills, orchestrate across mesh-networked nodes.",
5
5
  "license": "MIT",
6
6
  "author": "Aaron Scherer <me@aaronscherer.me>",
@@ -72,15 +72,35 @@ switch (command) {
72
72
  case "stop":
73
73
  runStop();
74
74
  break;
75
+ case "restart":
76
+ runRestart();
77
+ break;
75
78
  case "status":
76
79
  runStatus();
77
80
  break;
78
81
  case "update":
79
82
  await runUpdate();
80
83
  break;
84
+ case "version":
85
+ await runVersion();
86
+ break;
87
+ case "logs":
88
+ runLogs();
89
+ break;
90
+ case "open":
91
+ runOpen();
92
+ break;
93
+ case "config":
94
+ runConfigInfo();
95
+ break;
96
+ case "help":
97
+ case "--help":
98
+ case "-h":
99
+ runHelp();
100
+ break;
81
101
  default:
82
102
  console.log("[lattice] Unknown command: " + command);
83
- console.log("[lattice] Usage: lattice [start|stop|status|update|daemon]");
103
+ runHelp();
84
104
  process.exit(1);
85
105
  }
86
106
 
@@ -180,6 +200,139 @@ function runStop(): void {
180
200
  }
181
201
  }
182
202
 
203
+ function runHelp(): void {
204
+ console.log("");
205
+ console.log(" lattice — Multi-machine agentic dashboard for Claude Code");
206
+ console.log("");
207
+ console.log(" Usage: lattice [command] [options]");
208
+ console.log("");
209
+ console.log(" Commands:");
210
+ console.log(" start Start the daemon and open the UI (default)");
211
+ console.log(" stop Stop the running daemon");
212
+ console.log(" restart Stop and restart the daemon");
213
+ console.log(" status Show daemon status and connection info");
214
+ console.log(" update Check for updates and install the latest version");
215
+ console.log(" version Show current and latest version");
216
+ console.log(" logs Tail the daemon log");
217
+ console.log(" open Open the UI in the browser");
218
+ console.log(" config Show configuration paths and settings");
219
+ console.log(" help Show this help message");
220
+ console.log("");
221
+ console.log(" Options:");
222
+ console.log(" --port=N Override the server port");
223
+ console.log("");
224
+ console.log(" Environment:");
225
+ console.log(" LATTICE_HOME Data directory (default: ~/.lattice)");
226
+ console.log(" LATTICE_PORT Server port (default: 7654)");
227
+ console.log("");
228
+ }
229
+
230
+ function runRestart(): void {
231
+ var pid = readPid();
232
+ if (pid !== null && isDaemonRunning(pid)) {
233
+ console.log("[lattice] Stopping daemon (PID " + pid + ")...");
234
+ try {
235
+ process.kill(pid, "SIGTERM");
236
+ } catch {}
237
+ removePid();
238
+
239
+ var waited = 0;
240
+ while (waited < 5000) {
241
+ try {
242
+ process.kill(pid, 0);
243
+ Bun.sleepSync(200);
244
+ waited += 200;
245
+ } catch {
246
+ break;
247
+ }
248
+ }
249
+ }
250
+
251
+ console.log("[lattice] Starting daemon...");
252
+ var logPath = join(getLatticeHome(), "daemon.log");
253
+
254
+ var spawnArgs = IS_COMPILED
255
+ ? [process.execPath, "daemon"]
256
+ : ["bun", import.meta.path, "daemon"];
257
+
258
+ if (portOverride) {
259
+ spawnArgs.push("--port", String(portOverride));
260
+ }
261
+
262
+ var child = Bun.spawn(spawnArgs, {
263
+ detached: true,
264
+ stdio: ["ignore", Bun.file(logPath), Bun.file(logPath)],
265
+ });
266
+
267
+ child.unref();
268
+ writePid(child.pid);
269
+ console.log("[lattice] Daemon started (PID " + child.pid + ")");
270
+ }
271
+
272
+ async function runVersion(): Promise<void> {
273
+ var { checkForUpdate } = await import("./update-checker");
274
+ var info = await checkForUpdate(true);
275
+ console.log("[lattice] Current: v" + info.currentVersion);
276
+ if (info.latestVersion) {
277
+ if (info.updateAvailable) {
278
+ console.log("[lattice] Latest: v" + info.latestVersion + " (update available)");
279
+ console.log("[lattice] Run 'lattice update' to install");
280
+ } else {
281
+ console.log("[lattice] Latest: v" + info.latestVersion + " (up to date)");
282
+ }
283
+ }
284
+ console.log("[lattice] Mode: " + info.installMode);
285
+ }
286
+
287
+ function runLogs(): void {
288
+ var logPath = join(getLatticeHome(), "daemon.log");
289
+ if (!existsSync(logPath)) {
290
+ console.log("[lattice] No log file found at " + logPath);
291
+ process.exit(1);
292
+ }
293
+ console.log("[lattice] Tailing " + logPath + " (Ctrl+C to stop)");
294
+ var proc = Bun.spawn(["tail", "-f", "-n", "50", logPath], {
295
+ stdout: "inherit",
296
+ stderr: "inherit",
297
+ });
298
+ process.on("SIGINT", function () {
299
+ proc.kill();
300
+ process.exit(0);
301
+ });
302
+ }
303
+
304
+ function runOpen(): void {
305
+ var config = loadConfig();
306
+ var pid = readPid();
307
+ if (pid === null || !isDaemonRunning(pid)) {
308
+ console.log("[lattice] Daemon is not running. Start it with 'lattice start'");
309
+ process.exit(1);
310
+ }
311
+ var url = (config.tls ? "https" : "http") + "://localhost:" + config.port;
312
+ console.log("[lattice] Opening " + url);
313
+ openBrowser(url);
314
+ }
315
+
316
+ function runConfigInfo(): void {
317
+ var config = loadConfig();
318
+ var home = getLatticeHome();
319
+ console.log("[lattice] Home: " + home);
320
+ console.log("[lattice] Config: " + join(home, "config.json"));
321
+ console.log("[lattice] Port: " + config.port);
322
+ console.log("[lattice] Name: " + config.name);
323
+ console.log("[lattice] TLS: " + (config.tls ? "enabled" : "disabled"));
324
+ console.log("[lattice] Projects: " + config.projects.length);
325
+ for (var i = 0; i < config.projects.length; i++) {
326
+ console.log(" " + config.projects[i].slug + " → " + config.projects[i].path);
327
+ }
328
+ if (config.passphraseHash) {
329
+ console.log("[lattice] Passphrase: set");
330
+ }
331
+ if (config.costBudget) {
332
+ console.log("[lattice] Budget: $" + config.costBudget.dailyLimit + "/day (" + config.costBudget.enforcement + ")");
333
+ }
334
+ }
335
+
183
336
  function runStatus(): void {
184
337
  var pid = readPid();
185
338
  if (pid === null) {