fleetlens 0.2.2 → 0.2.4
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.
- package/app/apps/web/.next/BUILD_ID +1 -1
- package/app/apps/web/.next/build-manifest.json +3 -3
- package/app/apps/web/.next/prerender-manifest.json +3 -3
- package/app/apps/web/.next/server/app/_global-error.html +1 -1
- package/app/apps/web/.next/server/app/_global-error.rsc +1 -1
- package/app/apps/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/parallelism/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/usage/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/_0yyvgac._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_components_06j3c.0._.js +1 -1
- package/app/apps/web/.next/server/middleware-build-manifest.js +3 -3
- package/app/apps/web/.next/server/pages/500.html +1 -1
- package/app/apps/web/.next/server/server-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/server-reference-manifest.json +1 -1
- package/app/apps/web/.next/static/chunks/{0dtwmo5wu8b96.js → 16tz7r~m.q0sm.js} +1 -1
- package/app/apps/web/app/layout.tsx +7 -1
- package/app/apps/web/components/sidebar.tsx +26 -3
- package/app/apps/web/package.json +1 -1
- package/app/apps/web/tsconfig.tsbuildinfo +1 -1
- package/dist/index.js +223 -195
- package/package.json +1 -1
- /package/app/apps/web/.next/static/{l9d3RgXDImZ_d9fQSsqtK → ZmehRJTK-a8YUVMk6N8F1}/_buildManifest.js +0 -0
- /package/app/apps/web/.next/static/{l9d3RgXDImZ_d9fQSsqtK → ZmehRJTK-a8YUVMk6N8F1}/_clientMiddlewareManifest.js +0 -0
- /package/app/apps/web/.next/static/{l9d3RgXDImZ_d9fQSsqtK → ZmehRJTK-a8YUVMk6N8F1}/_ssgManifest.js +0 -0
package/dist/index.js
CHANGED
|
@@ -60,6 +60,13 @@ var init_pid = __esm({
|
|
|
60
60
|
});
|
|
61
61
|
|
|
62
62
|
// src/server.ts
|
|
63
|
+
var server_exports = {};
|
|
64
|
+
__export(server_exports, {
|
|
65
|
+
getServerStatus: () => getServerStatus,
|
|
66
|
+
openBrowser: () => openBrowser,
|
|
67
|
+
startServer: () => startServer,
|
|
68
|
+
stopServer: () => stopServer
|
|
69
|
+
});
|
|
63
70
|
import { spawn } from "node:child_process";
|
|
64
71
|
import { join, dirname as dirname2 } from "node:path";
|
|
65
72
|
import { fileURLToPath } from "node:url";
|
|
@@ -156,10 +163,191 @@ var init_server = __esm({
|
|
|
156
163
|
}
|
|
157
164
|
});
|
|
158
165
|
|
|
166
|
+
// src/usage/storage.ts
|
|
167
|
+
import { appendFileSync, mkdirSync as mkdirSync2, readFileSync as readFileSync2, existsSync as existsSync2 } from "node:fs";
|
|
168
|
+
import { dirname as dirname3 } from "node:path";
|
|
169
|
+
function appendSnapshot(filePath, snapshot) {
|
|
170
|
+
mkdirSync2(dirname3(filePath), { recursive: true });
|
|
171
|
+
appendFileSync(filePath, JSON.stringify(snapshot) + "\n", "utf8");
|
|
172
|
+
}
|
|
173
|
+
function readSnapshots(filePath) {
|
|
174
|
+
if (!existsSync2(filePath)) return [];
|
|
175
|
+
const content = readFileSync2(filePath, "utf8");
|
|
176
|
+
const snapshots = [];
|
|
177
|
+
for (const line of content.split("\n")) {
|
|
178
|
+
if (!line.trim()) continue;
|
|
179
|
+
try {
|
|
180
|
+
snapshots.push(JSON.parse(line));
|
|
181
|
+
} catch {
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return snapshots;
|
|
185
|
+
}
|
|
186
|
+
function latestSnapshot(filePath) {
|
|
187
|
+
const all = readSnapshots(filePath);
|
|
188
|
+
return all.length > 0 ? all[all.length - 1] : null;
|
|
189
|
+
}
|
|
190
|
+
var init_storage = __esm({
|
|
191
|
+
"src/usage/storage.ts"() {
|
|
192
|
+
"use strict";
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
// src/commands/daemon.ts
|
|
197
|
+
var daemon_exports = {};
|
|
198
|
+
__export(daemon_exports, {
|
|
199
|
+
daemon: () => daemon,
|
|
200
|
+
getDaemonStatusInfo: () => getDaemonStatusInfo,
|
|
201
|
+
startDaemonSilent: () => startDaemonSilent,
|
|
202
|
+
stopDaemonSilent: () => stopDaemonSilent
|
|
203
|
+
});
|
|
204
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
205
|
+
import { join as join2, dirname as dirname4 } from "node:path";
|
|
206
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
207
|
+
import { existsSync as existsSync3, statSync, readFileSync as readFileSync3 } from "node:fs";
|
|
208
|
+
import { homedir as homedir2 } from "node:os";
|
|
209
|
+
function startDaemonSilent() {
|
|
210
|
+
cleanStalePid(DAEMON_PID);
|
|
211
|
+
const existing = readPid(DAEMON_PID);
|
|
212
|
+
if (existing !== null && isProcessAlive(existing.pid)) {
|
|
213
|
+
return { started: false, pid: existing.pid, alreadyRunning: true };
|
|
214
|
+
}
|
|
215
|
+
const script = workerPath();
|
|
216
|
+
if (!existsSync3(script)) {
|
|
217
|
+
return {
|
|
218
|
+
started: false,
|
|
219
|
+
pid: null,
|
|
220
|
+
alreadyRunning: false,
|
|
221
|
+
error: `Daemon worker not found at ${script}. Rebuild with: pnpm -F fleetlens build`
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
const child = spawn2(process.execPath, [script], {
|
|
225
|
+
detached: true,
|
|
226
|
+
stdio: "ignore"
|
|
227
|
+
});
|
|
228
|
+
child.unref();
|
|
229
|
+
const pid = child.pid;
|
|
230
|
+
writePid(DAEMON_PID, pid);
|
|
231
|
+
return { started: true, pid, alreadyRunning: false };
|
|
232
|
+
}
|
|
233
|
+
function stopDaemonSilent() {
|
|
234
|
+
cleanStalePid(DAEMON_PID);
|
|
235
|
+
const entry = readPid(DAEMON_PID);
|
|
236
|
+
if (entry === null) return { stopped: false, pid: null };
|
|
237
|
+
try {
|
|
238
|
+
process.kill(entry.pid, "SIGTERM");
|
|
239
|
+
} catch {
|
|
240
|
+
}
|
|
241
|
+
removePid(DAEMON_PID);
|
|
242
|
+
return { stopped: true, pid: entry.pid };
|
|
243
|
+
}
|
|
244
|
+
function getDaemonStatusInfo() {
|
|
245
|
+
cleanStalePid(DAEMON_PID);
|
|
246
|
+
const entry = readPid(DAEMON_PID);
|
|
247
|
+
const running = entry !== null && isProcessAlive(entry.pid);
|
|
248
|
+
const latest = latestSnapshot(USAGE_LOG);
|
|
249
|
+
const lastSnapshotAgeMs = latest ? Date.now() - new Date(latest.captured_at).getTime() : null;
|
|
250
|
+
const usageLogSize = existsSync3(USAGE_LOG) ? statSync(USAGE_LOG).size : null;
|
|
251
|
+
return {
|
|
252
|
+
running,
|
|
253
|
+
pid: running ? entry.pid : null,
|
|
254
|
+
lastSnapshotAgeMs,
|
|
255
|
+
lastSnapshot: latest,
|
|
256
|
+
usageLogSize
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
function workerPath() {
|
|
260
|
+
const here = dirname4(fileURLToPath2(import.meta.url));
|
|
261
|
+
return join2(here, "daemon-worker.js");
|
|
262
|
+
}
|
|
263
|
+
async function daemon(args2) {
|
|
264
|
+
const sub = args2[0] ?? "status";
|
|
265
|
+
switch (sub) {
|
|
266
|
+
case "start":
|
|
267
|
+
await daemonStart();
|
|
268
|
+
break;
|
|
269
|
+
case "stop":
|
|
270
|
+
daemonStop();
|
|
271
|
+
break;
|
|
272
|
+
case "status":
|
|
273
|
+
daemonStatus();
|
|
274
|
+
break;
|
|
275
|
+
case "logs":
|
|
276
|
+
daemonLogs();
|
|
277
|
+
break;
|
|
278
|
+
default:
|
|
279
|
+
console.error(`Unknown daemon subcommand: ${sub}`);
|
|
280
|
+
console.error("Usage: fleetlens daemon <start|stop|status|logs>");
|
|
281
|
+
process.exit(1);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
async function daemonStart() {
|
|
285
|
+
const result = startDaemonSilent();
|
|
286
|
+
if (result.alreadyRunning) {
|
|
287
|
+
console.log(`Daemon is already running (PID ${result.pid})`);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
if (!result.started) {
|
|
291
|
+
console.error(result.error);
|
|
292
|
+
process.exit(1);
|
|
293
|
+
}
|
|
294
|
+
console.log(`Daemon started (PID ${result.pid})`);
|
|
295
|
+
console.log(`Polling every 5 minutes. Logs: ${DAEMON_LOG}`);
|
|
296
|
+
}
|
|
297
|
+
function daemonStop() {
|
|
298
|
+
const result = stopDaemonSilent();
|
|
299
|
+
if (!result.stopped) {
|
|
300
|
+
console.log("Daemon is not running.");
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
console.log(`Stopped daemon (PID ${result.pid})`);
|
|
304
|
+
}
|
|
305
|
+
function daemonStatus() {
|
|
306
|
+
const info = getDaemonStatusInfo();
|
|
307
|
+
if (info.running) {
|
|
308
|
+
console.log(`Daemon: running (PID ${info.pid})`);
|
|
309
|
+
} else {
|
|
310
|
+
console.log("Daemon: not running");
|
|
311
|
+
}
|
|
312
|
+
if (info.lastSnapshot && info.lastSnapshotAgeMs !== null) {
|
|
313
|
+
const age = Math.round(info.lastSnapshotAgeMs / 1e3);
|
|
314
|
+
const ageStr = age < 60 ? `${age}s` : age < 3600 ? `${Math.round(age / 60)}m` : `${Math.round(age / 3600)}h`;
|
|
315
|
+
console.log(`Last snapshot: ${ageStr} ago`);
|
|
316
|
+
console.log(` 5h: ${info.lastSnapshot.five_hour.utilization?.toFixed(1) ?? "\u2014"}%`);
|
|
317
|
+
console.log(` 7d: ${info.lastSnapshot.seven_day.utilization?.toFixed(1) ?? "\u2014"}%`);
|
|
318
|
+
} else {
|
|
319
|
+
console.log("Last snapshot: none yet");
|
|
320
|
+
}
|
|
321
|
+
if (info.usageLogSize !== null) {
|
|
322
|
+
console.log(`Usage log: ${USAGE_LOG} (${info.usageLogSize} bytes)`);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
function daemonLogs() {
|
|
326
|
+
if (!existsSync3(DAEMON_LOG)) {
|
|
327
|
+
console.log("No daemon logs yet.");
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
const content = readFileSync3(DAEMON_LOG, "utf8");
|
|
331
|
+
const lines = content.trim().split("\n").slice(-20);
|
|
332
|
+
for (const line of lines) process.stdout.write(line + "\n");
|
|
333
|
+
}
|
|
334
|
+
var STATE_DIR2, DAEMON_PID, USAGE_LOG, DAEMON_LOG;
|
|
335
|
+
var init_daemon = __esm({
|
|
336
|
+
"src/commands/daemon.ts"() {
|
|
337
|
+
"use strict";
|
|
338
|
+
init_pid();
|
|
339
|
+
init_storage();
|
|
340
|
+
STATE_DIR2 = join2(homedir2(), ".cclens");
|
|
341
|
+
DAEMON_PID = join2(STATE_DIR2, "daemon.pid");
|
|
342
|
+
USAGE_LOG = join2(STATE_DIR2, "usage.jsonl");
|
|
343
|
+
DAEMON_LOG = join2(STATE_DIR2, "daemon.log");
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
|
|
159
347
|
// src/updater.ts
|
|
160
348
|
import { execSync, spawnSync } from "node:child_process";
|
|
161
|
-
import { existsSync as
|
|
162
|
-
import { dirname as
|
|
349
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4, realpathSync } from "node:fs";
|
|
350
|
+
import { dirname as dirname5, join as join3 } from "node:path";
|
|
163
351
|
function shouldUpdate(local, remote) {
|
|
164
352
|
const l = local.split(".").map(Number);
|
|
165
353
|
const r = remote.split(".").map(Number);
|
|
@@ -201,15 +389,15 @@ function verifyInstalledVersion() {
|
|
|
201
389
|
encoding: "utf8",
|
|
202
390
|
timeout: 5e3
|
|
203
391
|
}).trim();
|
|
204
|
-
const pkgPath =
|
|
205
|
-
const pkg = JSON.parse(
|
|
392
|
+
const pkgPath = join3(globalRoot, PACKAGE_NAME, "package.json");
|
|
393
|
+
const pkg = JSON.parse(readFileSync4(pkgPath, "utf8"));
|
|
206
394
|
if (!pkg.version) {
|
|
207
395
|
return { ok: false, reason: `no version field in ${pkgPath}` };
|
|
208
396
|
}
|
|
209
397
|
return {
|
|
210
398
|
ok: true,
|
|
211
399
|
installedVersion: pkg.version,
|
|
212
|
-
installedPath:
|
|
400
|
+
installedPath: join3(globalRoot, PACKAGE_NAME)
|
|
213
401
|
};
|
|
214
402
|
} catch (err) {
|
|
215
403
|
return { ok: false, reason: err.message };
|
|
@@ -266,9 +454,9 @@ Installed: ${PACKAGE_NAME}@${verify.installedVersion} at ${verify.installedPath
|
|
|
266
454
|
console.warn(
|
|
267
455
|
` \u2022 reinstall in the correct Node env: 'npm install -g ${PACKAGE_NAME}@latest'`
|
|
268
456
|
);
|
|
269
|
-
} else {
|
|
457
|
+
} else if (verify.installedVersion !== "0.2.4") {
|
|
270
458
|
console.log(
|
|
271
|
-
` \u2192 This process is still running ${"0.2.
|
|
459
|
+
` \u2192 This process is still running ${"0.2.4"}. Next invocation will use ${verify.installedVersion}.`
|
|
272
460
|
);
|
|
273
461
|
}
|
|
274
462
|
}
|
|
@@ -278,16 +466,16 @@ function resolvesIntoPackage(binPath, packagePath) {
|
|
|
278
466
|
if (real.startsWith(packagePath)) return true;
|
|
279
467
|
} catch {
|
|
280
468
|
}
|
|
281
|
-
const binPrefix =
|
|
282
|
-
const installPrefix =
|
|
469
|
+
const binPrefix = dirname5(dirname5(binPath));
|
|
470
|
+
const installPrefix = dirname5(dirname5(dirname5(packagePath)));
|
|
283
471
|
return binPrefix === installPrefix;
|
|
284
472
|
}
|
|
285
473
|
function reExec() {
|
|
286
474
|
const verify = verifyInstalledVersion();
|
|
287
475
|
let script = process.argv[1] ?? "";
|
|
288
476
|
if (verify.ok) {
|
|
289
|
-
const candidate =
|
|
290
|
-
if (
|
|
477
|
+
const candidate = join3(verify.installedPath, "dist", "index.js");
|
|
478
|
+
if (existsSync4(candidate)) script = candidate;
|
|
291
479
|
}
|
|
292
480
|
const result = spawnSync(process.argv[0], [script, ...process.argv.slice(2)], {
|
|
293
481
|
stdio: "inherit",
|
|
@@ -304,9 +492,10 @@ async function checkForUpdate() {
|
|
|
304
492
|
if (process.env.__FLEETLENS_UPDATED === "1" || process.env.__CCLENS_UPDATED === "1") return;
|
|
305
493
|
const latest = await fetchLatestVersion();
|
|
306
494
|
if (latest === null) return;
|
|
307
|
-
const current = "0.2.
|
|
495
|
+
const current = "0.2.4";
|
|
308
496
|
if (!shouldUpdate(current, latest)) return;
|
|
309
497
|
console.log(`Updating ${PACKAGE_NAME} ${current} \u2192 ${latest}...`);
|
|
498
|
+
await stopRunningServices();
|
|
310
499
|
const ok = runNpmInstall();
|
|
311
500
|
if (ok) {
|
|
312
501
|
reportInstallOutcome(latest);
|
|
@@ -320,15 +509,35 @@ async function checkForUpdate() {
|
|
|
320
509
|
);
|
|
321
510
|
}
|
|
322
511
|
}
|
|
512
|
+
async function stopRunningServices() {
|
|
513
|
+
try {
|
|
514
|
+
const { getServerStatus: getServerStatus2, stopServer: stopServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
|
|
515
|
+
const status2 = getServerStatus2();
|
|
516
|
+
if (status2.running) {
|
|
517
|
+
stopServer2();
|
|
518
|
+
console.log(` \u2713 Stopped old server (PID ${status2.pid})`);
|
|
519
|
+
}
|
|
520
|
+
} catch {
|
|
521
|
+
}
|
|
522
|
+
try {
|
|
523
|
+
const { stopDaemonSilent: stopDaemonSilent2 } = await Promise.resolve().then(() => (init_daemon(), daemon_exports));
|
|
524
|
+
const result = stopDaemonSilent2();
|
|
525
|
+
if (result.stopped) {
|
|
526
|
+
console.log(` \u2713 Stopped old daemon (PID ${result.pid})`);
|
|
527
|
+
}
|
|
528
|
+
} catch {
|
|
529
|
+
}
|
|
530
|
+
}
|
|
323
531
|
async function forceUpdate() {
|
|
324
532
|
const latest = await fetchLatestVersion();
|
|
325
|
-
const current = "0.2.
|
|
533
|
+
const current = "0.2.4";
|
|
326
534
|
if (latest === null) {
|
|
327
535
|
console.error("Could not reach npm registry. Check your network.");
|
|
328
536
|
process.exit(1);
|
|
329
537
|
}
|
|
330
538
|
if (shouldUpdate(current, latest)) {
|
|
331
539
|
console.log(`Updating ${PACKAGE_NAME} ${current} \u2192 ${latest}...`);
|
|
540
|
+
await stopRunningServices();
|
|
332
541
|
} else {
|
|
333
542
|
console.log(`Already on latest (${current}). Reinstalling...`);
|
|
334
543
|
}
|
|
@@ -351,187 +560,6 @@ var init_updater = __esm({
|
|
|
351
560
|
}
|
|
352
561
|
});
|
|
353
562
|
|
|
354
|
-
// src/usage/storage.ts
|
|
355
|
-
import { appendFileSync, mkdirSync as mkdirSync2, readFileSync as readFileSync3, existsSync as existsSync3 } from "node:fs";
|
|
356
|
-
import { dirname as dirname4 } from "node:path";
|
|
357
|
-
function appendSnapshot(filePath, snapshot) {
|
|
358
|
-
mkdirSync2(dirname4(filePath), { recursive: true });
|
|
359
|
-
appendFileSync(filePath, JSON.stringify(snapshot) + "\n", "utf8");
|
|
360
|
-
}
|
|
361
|
-
function readSnapshots(filePath) {
|
|
362
|
-
if (!existsSync3(filePath)) return [];
|
|
363
|
-
const content = readFileSync3(filePath, "utf8");
|
|
364
|
-
const snapshots = [];
|
|
365
|
-
for (const line of content.split("\n")) {
|
|
366
|
-
if (!line.trim()) continue;
|
|
367
|
-
try {
|
|
368
|
-
snapshots.push(JSON.parse(line));
|
|
369
|
-
} catch {
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
return snapshots;
|
|
373
|
-
}
|
|
374
|
-
function latestSnapshot(filePath) {
|
|
375
|
-
const all = readSnapshots(filePath);
|
|
376
|
-
return all.length > 0 ? all[all.length - 1] : null;
|
|
377
|
-
}
|
|
378
|
-
var init_storage = __esm({
|
|
379
|
-
"src/usage/storage.ts"() {
|
|
380
|
-
"use strict";
|
|
381
|
-
}
|
|
382
|
-
});
|
|
383
|
-
|
|
384
|
-
// src/commands/daemon.ts
|
|
385
|
-
var daemon_exports = {};
|
|
386
|
-
__export(daemon_exports, {
|
|
387
|
-
daemon: () => daemon,
|
|
388
|
-
getDaemonStatusInfo: () => getDaemonStatusInfo,
|
|
389
|
-
startDaemonSilent: () => startDaemonSilent,
|
|
390
|
-
stopDaemonSilent: () => stopDaemonSilent
|
|
391
|
-
});
|
|
392
|
-
import { spawn as spawn2 } from "node:child_process";
|
|
393
|
-
import { join as join3, dirname as dirname5 } from "node:path";
|
|
394
|
-
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
395
|
-
import { existsSync as existsSync4, statSync, readFileSync as readFileSync4 } from "node:fs";
|
|
396
|
-
import { homedir as homedir2 } from "node:os";
|
|
397
|
-
function startDaemonSilent() {
|
|
398
|
-
cleanStalePid(DAEMON_PID);
|
|
399
|
-
const existing = readPid(DAEMON_PID);
|
|
400
|
-
if (existing !== null && isProcessAlive(existing.pid)) {
|
|
401
|
-
return { started: false, pid: existing.pid, alreadyRunning: true };
|
|
402
|
-
}
|
|
403
|
-
const script = workerPath();
|
|
404
|
-
if (!existsSync4(script)) {
|
|
405
|
-
return {
|
|
406
|
-
started: false,
|
|
407
|
-
pid: null,
|
|
408
|
-
alreadyRunning: false,
|
|
409
|
-
error: `Daemon worker not found at ${script}. Rebuild with: pnpm -F fleetlens build`
|
|
410
|
-
};
|
|
411
|
-
}
|
|
412
|
-
const child = spawn2(process.execPath, [script], {
|
|
413
|
-
detached: true,
|
|
414
|
-
stdio: "ignore"
|
|
415
|
-
});
|
|
416
|
-
child.unref();
|
|
417
|
-
const pid = child.pid;
|
|
418
|
-
writePid(DAEMON_PID, pid);
|
|
419
|
-
return { started: true, pid, alreadyRunning: false };
|
|
420
|
-
}
|
|
421
|
-
function stopDaemonSilent() {
|
|
422
|
-
cleanStalePid(DAEMON_PID);
|
|
423
|
-
const entry = readPid(DAEMON_PID);
|
|
424
|
-
if (entry === null) return { stopped: false, pid: null };
|
|
425
|
-
try {
|
|
426
|
-
process.kill(entry.pid, "SIGTERM");
|
|
427
|
-
} catch {
|
|
428
|
-
}
|
|
429
|
-
removePid(DAEMON_PID);
|
|
430
|
-
return { stopped: true, pid: entry.pid };
|
|
431
|
-
}
|
|
432
|
-
function getDaemonStatusInfo() {
|
|
433
|
-
cleanStalePid(DAEMON_PID);
|
|
434
|
-
const entry = readPid(DAEMON_PID);
|
|
435
|
-
const running = entry !== null && isProcessAlive(entry.pid);
|
|
436
|
-
const latest = latestSnapshot(USAGE_LOG);
|
|
437
|
-
const lastSnapshotAgeMs = latest ? Date.now() - new Date(latest.captured_at).getTime() : null;
|
|
438
|
-
const usageLogSize = existsSync4(USAGE_LOG) ? statSync(USAGE_LOG).size : null;
|
|
439
|
-
return {
|
|
440
|
-
running,
|
|
441
|
-
pid: running ? entry.pid : null,
|
|
442
|
-
lastSnapshotAgeMs,
|
|
443
|
-
lastSnapshot: latest,
|
|
444
|
-
usageLogSize
|
|
445
|
-
};
|
|
446
|
-
}
|
|
447
|
-
function workerPath() {
|
|
448
|
-
const here = dirname5(fileURLToPath2(import.meta.url));
|
|
449
|
-
return join3(here, "daemon-worker.js");
|
|
450
|
-
}
|
|
451
|
-
async function daemon(args2) {
|
|
452
|
-
const sub = args2[0] ?? "status";
|
|
453
|
-
switch (sub) {
|
|
454
|
-
case "start":
|
|
455
|
-
await daemonStart();
|
|
456
|
-
break;
|
|
457
|
-
case "stop":
|
|
458
|
-
daemonStop();
|
|
459
|
-
break;
|
|
460
|
-
case "status":
|
|
461
|
-
daemonStatus();
|
|
462
|
-
break;
|
|
463
|
-
case "logs":
|
|
464
|
-
daemonLogs();
|
|
465
|
-
break;
|
|
466
|
-
default:
|
|
467
|
-
console.error(`Unknown daemon subcommand: ${sub}`);
|
|
468
|
-
console.error("Usage: fleetlens daemon <start|stop|status|logs>");
|
|
469
|
-
process.exit(1);
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
async function daemonStart() {
|
|
473
|
-
const result = startDaemonSilent();
|
|
474
|
-
if (result.alreadyRunning) {
|
|
475
|
-
console.log(`Daemon is already running (PID ${result.pid})`);
|
|
476
|
-
return;
|
|
477
|
-
}
|
|
478
|
-
if (!result.started) {
|
|
479
|
-
console.error(result.error);
|
|
480
|
-
process.exit(1);
|
|
481
|
-
}
|
|
482
|
-
console.log(`Daemon started (PID ${result.pid})`);
|
|
483
|
-
console.log(`Polling every 5 minutes. Logs: ${DAEMON_LOG}`);
|
|
484
|
-
}
|
|
485
|
-
function daemonStop() {
|
|
486
|
-
const result = stopDaemonSilent();
|
|
487
|
-
if (!result.stopped) {
|
|
488
|
-
console.log("Daemon is not running.");
|
|
489
|
-
return;
|
|
490
|
-
}
|
|
491
|
-
console.log(`Stopped daemon (PID ${result.pid})`);
|
|
492
|
-
}
|
|
493
|
-
function daemonStatus() {
|
|
494
|
-
const info = getDaemonStatusInfo();
|
|
495
|
-
if (info.running) {
|
|
496
|
-
console.log(`Daemon: running (PID ${info.pid})`);
|
|
497
|
-
} else {
|
|
498
|
-
console.log("Daemon: not running");
|
|
499
|
-
}
|
|
500
|
-
if (info.lastSnapshot && info.lastSnapshotAgeMs !== null) {
|
|
501
|
-
const age = Math.round(info.lastSnapshotAgeMs / 1e3);
|
|
502
|
-
const ageStr = age < 60 ? `${age}s` : age < 3600 ? `${Math.round(age / 60)}m` : `${Math.round(age / 3600)}h`;
|
|
503
|
-
console.log(`Last snapshot: ${ageStr} ago`);
|
|
504
|
-
console.log(` 5h: ${info.lastSnapshot.five_hour.utilization?.toFixed(1) ?? "\u2014"}%`);
|
|
505
|
-
console.log(` 7d: ${info.lastSnapshot.seven_day.utilization?.toFixed(1) ?? "\u2014"}%`);
|
|
506
|
-
} else {
|
|
507
|
-
console.log("Last snapshot: none yet");
|
|
508
|
-
}
|
|
509
|
-
if (info.usageLogSize !== null) {
|
|
510
|
-
console.log(`Usage log: ${USAGE_LOG} (${info.usageLogSize} bytes)`);
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
function daemonLogs() {
|
|
514
|
-
if (!existsSync4(DAEMON_LOG)) {
|
|
515
|
-
console.log("No daemon logs yet.");
|
|
516
|
-
return;
|
|
517
|
-
}
|
|
518
|
-
const content = readFileSync4(DAEMON_LOG, "utf8");
|
|
519
|
-
const lines = content.trim().split("\n").slice(-20);
|
|
520
|
-
for (const line of lines) process.stdout.write(line + "\n");
|
|
521
|
-
}
|
|
522
|
-
var STATE_DIR2, DAEMON_PID, USAGE_LOG, DAEMON_LOG;
|
|
523
|
-
var init_daemon = __esm({
|
|
524
|
-
"src/commands/daemon.ts"() {
|
|
525
|
-
"use strict";
|
|
526
|
-
init_pid();
|
|
527
|
-
init_storage();
|
|
528
|
-
STATE_DIR2 = join3(homedir2(), ".cclens");
|
|
529
|
-
DAEMON_PID = join3(STATE_DIR2, "daemon.pid");
|
|
530
|
-
USAGE_LOG = join3(STATE_DIR2, "usage.jsonl");
|
|
531
|
-
DAEMON_LOG = join3(STATE_DIR2, "daemon.log");
|
|
532
|
-
}
|
|
533
|
-
});
|
|
534
|
-
|
|
535
563
|
// src/commands/start.ts
|
|
536
564
|
var start_exports = {};
|
|
537
565
|
__export(start_exports, {
|
|
@@ -1733,7 +1761,7 @@ async function main() {
|
|
|
1733
1761
|
case "version":
|
|
1734
1762
|
case "--version":
|
|
1735
1763
|
case "-v":
|
|
1736
|
-
console.log(`fleetlens ${"0.2.
|
|
1764
|
+
console.log(`fleetlens ${"0.2.4"}`);
|
|
1737
1765
|
break;
|
|
1738
1766
|
case "help":
|
|
1739
1767
|
case "--help":
|
package/package.json
CHANGED
/package/app/apps/web/.next/static/{l9d3RgXDImZ_d9fQSsqtK → ZmehRJTK-a8YUVMk6N8F1}/_buildManifest.js
RENAMED
|
File without changes
|
|
File without changes
|
/package/app/apps/web/.next/static/{l9d3RgXDImZ_d9fQSsqtK → ZmehRJTK-a8YUVMk6N8F1}/_ssgManifest.js
RENAMED
|
File without changes
|