fleetlens 1.0.0 → 1.0.2
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/app-path-routes-manifest.json +1 -0
- 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/routes-manifest.json +6 -0
- 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.js.nft.json +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/agent/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/agent/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/api/agent/chats/[id]/messages/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/agent/index/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/agent/mcp/route.js +3 -3
- package/app/apps/web/.next/server/app/api/agent/mcp/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/agent/suggestions/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/ask/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/day/[date]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/month/[yearMonth]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/month-index/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/week/[startDate]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/week-index/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/health/route/app-paths-manifest.json +3 -0
- package/app/apps/web/.next/server/app/api/health/route/build-manifest.json +9 -0
- package/app/apps/web/.next/server/app/api/health/route/server-reference-manifest.json +4 -0
- package/app/apps/web/.next/server/app/api/health/route.js +7 -0
- package/app/apps/web/.next/server/app/api/health/route.js.map +5 -0
- package/app/apps/web/.next/server/app/api/health/route.js.nft.json +1 -0
- package/app/apps/web/.next/server/app/api/health/route_client-reference-manifest.js +3 -0
- package/app/apps/web/.next/server/app/api/pdf/[key]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/projects/open-folder/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/runs/[runId]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/runs/[runId]/stream/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/settings/credentials/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/settings/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/changelog/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/changelog/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/day/[date]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/day/[date]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/day/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/day/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/digest/[date]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/digest/[date]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/digest/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/digest/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/insights/[key]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/insights/[key]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/insights/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/insights/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/page.js.nft.json +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.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/parallelism/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/print/[key]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/print/[key]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/projects/[slug]/page.js.nft.json +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.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/runs/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/runs/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/sessions/[id]/page.js.nft.json +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.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/team/onboarding/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/team/onboarding/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/team/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/team/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/usage/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/usage/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app-paths-manifest.json +1 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__02.51sr._.js +3 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__06irs4z._.js +3 -0
- package/app/apps/web/.next/server/chunks/apps_web__next-internal_server_app_api_health_route_actions_08i7v0h.js +3 -0
- package/app/apps/web/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_0sr4wr_.js +3 -3
- package/app/apps/web/.next/server/chunks/ssr/_0k8yioi._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_changelog_ts_0n7_p1d._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_changelog_ts_0nb5_-s._.js +1 -1
- package/app/apps/web/.next/server/functions-config-manifest.json +1 -0
- package/app/apps/web/.next/server/middleware-build-manifest.js +3 -3
- package/app/apps/web/.next/server/middleware-manifest.json +5 -5
- 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/0dqhn7-3.038l.js +14 -0
- package/app/apps/web/app/api/health/route.ts +12 -0
- package/app/apps/web/lib/changelog-data.generated.ts +1 -1
- package/app/apps/web/package.json +1 -1
- package/app/apps/web/tsconfig.tsbuildinfo +1 -1
- package/dist/daemon-worker.js +296 -18
- package/dist/index.js +46 -15
- package/menubar/Fleetlens.app/Contents/Info.plist +2 -2
- package/menubar/Fleetlens.app/Contents/MacOS/FleetlensMenubar +0 -0
- package/package.json +1 -1
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0sbhe0s._.js +0 -3
- package/app/apps/web/.next/static/chunks/18c7gd5.b8gfc.js +0 -14
- /package/app/apps/web/.next/static/{mSM83A_ktoKiZ6y_p7wNk → zyhoVMC9iNC5vofPFRY6z}/_buildManifest.js +0 -0
- /package/app/apps/web/.next/static/{mSM83A_ktoKiZ6y_p7wNk → zyhoVMC9iNC5vofPFRY6z}/_clientMiddlewareManifest.js +0 -0
- /package/app/apps/web/.next/static/{mSM83A_ktoKiZ6y_p7wNk → zyhoVMC9iNC5vofPFRY6z}/_ssgManifest.js +0 -0
package/dist/daemon-worker.js
CHANGED
|
@@ -6860,11 +6860,204 @@ var init_file_probe = __esm({
|
|
|
6860
6860
|
}
|
|
6861
6861
|
});
|
|
6862
6862
|
|
|
6863
|
-
// src/
|
|
6863
|
+
// src/pid.ts
|
|
6864
|
+
import { readFileSync as readFileSync21, writeFileSync as writeFileSync15, mkdirSync as mkdirSync14, unlinkSync as unlinkSync5 } from "node:fs";
|
|
6865
|
+
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
6866
|
+
import { dirname as dirname12 } from "node:path";
|
|
6867
|
+
function writePid(filePath, pid, port, version) {
|
|
6868
|
+
mkdirSync14(dirname12(filePath), { recursive: true });
|
|
6869
|
+
let content = String(pid);
|
|
6870
|
+
if (port != null) {
|
|
6871
|
+
content += `:${port}`;
|
|
6872
|
+
if (version) content += `:${version}`;
|
|
6873
|
+
}
|
|
6874
|
+
writeFileSync15(filePath, content, "utf8");
|
|
6875
|
+
}
|
|
6876
|
+
function readPid(filePath) {
|
|
6877
|
+
try {
|
|
6878
|
+
const content = readFileSync21(filePath, "utf8").trim();
|
|
6879
|
+
const [pidStr, portStr, versionStr] = content.split(":");
|
|
6880
|
+
const pid = parseInt(pidStr, 10);
|
|
6881
|
+
if (Number.isNaN(pid)) return null;
|
|
6882
|
+
const port = portStr ? parseInt(portStr, 10) : void 0;
|
|
6883
|
+
return {
|
|
6884
|
+
pid,
|
|
6885
|
+
port: Number.isNaN(port) ? void 0 : port,
|
|
6886
|
+
version: versionStr || void 0
|
|
6887
|
+
};
|
|
6888
|
+
} catch {
|
|
6889
|
+
return null;
|
|
6890
|
+
}
|
|
6891
|
+
}
|
|
6892
|
+
function isProcessAlive(pid, markers) {
|
|
6893
|
+
try {
|
|
6894
|
+
process.kill(pid, 0);
|
|
6895
|
+
} catch {
|
|
6896
|
+
return false;
|
|
6897
|
+
}
|
|
6898
|
+
if (!markers || markers.length === 0) return true;
|
|
6899
|
+
try {
|
|
6900
|
+
const cmd = execFileSync3("ps", ["-p", String(pid), "-o", "command="], {
|
|
6901
|
+
encoding: "utf8"
|
|
6902
|
+
}).trim();
|
|
6903
|
+
return markers.some((m) => cmd.includes(m));
|
|
6904
|
+
} catch {
|
|
6905
|
+
return false;
|
|
6906
|
+
}
|
|
6907
|
+
}
|
|
6908
|
+
function cleanStalePid(filePath, markers) {
|
|
6909
|
+
const entry = readPid(filePath);
|
|
6910
|
+
if (entry === null) return false;
|
|
6911
|
+
if (isProcessAlive(entry.pid, markers)) return false;
|
|
6912
|
+
try {
|
|
6913
|
+
unlinkSync5(filePath);
|
|
6914
|
+
} catch {
|
|
6915
|
+
}
|
|
6916
|
+
return true;
|
|
6917
|
+
}
|
|
6918
|
+
function removePid(filePath) {
|
|
6919
|
+
try {
|
|
6920
|
+
unlinkSync5(filePath);
|
|
6921
|
+
} catch {
|
|
6922
|
+
}
|
|
6923
|
+
}
|
|
6924
|
+
var init_pid = __esm({
|
|
6925
|
+
"src/pid.ts"() {
|
|
6926
|
+
"use strict";
|
|
6927
|
+
}
|
|
6928
|
+
});
|
|
6929
|
+
|
|
6930
|
+
// src/server.ts
|
|
6864
6931
|
import { spawn as spawn3 } from "node:child_process";
|
|
6865
|
-
import {
|
|
6866
|
-
import { dirname as dirname12, join as join13 } from "node:path";
|
|
6932
|
+
import { join as join13, dirname as dirname13 } from "node:path";
|
|
6867
6933
|
import { fileURLToPath } from "node:url";
|
|
6934
|
+
import { existsSync as existsSync19, realpathSync as realpathSync3, readFileSync as readFileSync22 } from "node:fs";
|
|
6935
|
+
import { homedir as homedir6 } from "node:os";
|
|
6936
|
+
function appDir() {
|
|
6937
|
+
const here = dirname13(fileURLToPath(import.meta.url));
|
|
6938
|
+
return join13(here, "..", "app", "apps", "web");
|
|
6939
|
+
}
|
|
6940
|
+
function cliBinRealPath() {
|
|
6941
|
+
const argv1 = process.argv[1] ?? "";
|
|
6942
|
+
try {
|
|
6943
|
+
return realpathSync3(argv1);
|
|
6944
|
+
} catch {
|
|
6945
|
+
return argv1;
|
|
6946
|
+
}
|
|
6947
|
+
}
|
|
6948
|
+
function onDiskVersion() {
|
|
6949
|
+
try {
|
|
6950
|
+
const here = dirname13(fileURLToPath(import.meta.url));
|
|
6951
|
+
const pkg = JSON.parse(readFileSync22(join13(here, "..", "package.json"), "utf8"));
|
|
6952
|
+
return pkg.version ?? "1.0.2";
|
|
6953
|
+
} catch {
|
|
6954
|
+
return "1.0.2";
|
|
6955
|
+
}
|
|
6956
|
+
}
|
|
6957
|
+
function getServerStatus() {
|
|
6958
|
+
cleanStalePid(PID_FILE, SERVER_MARKERS);
|
|
6959
|
+
const entry = readPid(PID_FILE);
|
|
6960
|
+
if (entry !== null && isProcessAlive(entry.pid, SERVER_MARKERS)) {
|
|
6961
|
+
return { running: true, pid: entry.pid, port: entry.port ?? DEFAULT_PORT, version: entry.version };
|
|
6962
|
+
}
|
|
6963
|
+
return { running: false };
|
|
6964
|
+
}
|
|
6965
|
+
async function startServer(opts = {}) {
|
|
6966
|
+
const port = opts.port ?? (parseInt(process.env.CCLENS_PORT ?? "", 10) || DEFAULT_PORT);
|
|
6967
|
+
const serverJs = join13(appDir(), "server.js");
|
|
6968
|
+
if (!existsSync19(serverJs)) {
|
|
6969
|
+
throw new Error(`Server not found at ${serverJs}. Reinstall with: npm install -g fleetlens`);
|
|
6970
|
+
}
|
|
6971
|
+
const portInUse = await checkPort(port);
|
|
6972
|
+
if (portInUse) {
|
|
6973
|
+
throw new Error(`Port ${port} is in use. Use --port to specify a different port.`);
|
|
6974
|
+
}
|
|
6975
|
+
const dataDir = join13(homedir6(), ".claude", "projects");
|
|
6976
|
+
const child = spawn3(process.execPath, [serverJs], {
|
|
6977
|
+
detached: true,
|
|
6978
|
+
stdio: "ignore",
|
|
6979
|
+
env: {
|
|
6980
|
+
...process.env,
|
|
6981
|
+
PORT: String(port),
|
|
6982
|
+
HOSTNAME: "localhost",
|
|
6983
|
+
CCLENS_DATA_DIR: dataDir,
|
|
6984
|
+
FLEETLENS_CLI_BIN: cliBinRealPath(),
|
|
6985
|
+
FLEETLENS_WEB_START_DAEMON: opts.autoStartDaemon === false ? "0" : "1"
|
|
6986
|
+
},
|
|
6987
|
+
cwd: appDir()
|
|
6988
|
+
});
|
|
6989
|
+
child.unref();
|
|
6990
|
+
const pid = child.pid;
|
|
6991
|
+
writePid(PID_FILE, pid, port, onDiskVersion());
|
|
6992
|
+
await waitForHealth(`http://localhost:${port}`, 3e4);
|
|
6993
|
+
return { pid, port };
|
|
6994
|
+
}
|
|
6995
|
+
async function probeServerHealth(port, timeoutMs) {
|
|
6996
|
+
try {
|
|
6997
|
+
await fetch(`http://localhost:${port}/api/health`, {
|
|
6998
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
6999
|
+
});
|
|
7000
|
+
return true;
|
|
7001
|
+
} catch {
|
|
7002
|
+
return false;
|
|
7003
|
+
}
|
|
7004
|
+
}
|
|
7005
|
+
async function restartWedgedServer(pid, port) {
|
|
7006
|
+
try {
|
|
7007
|
+
process.kill(pid, "SIGKILL");
|
|
7008
|
+
} catch {
|
|
7009
|
+
}
|
|
7010
|
+
removePid(PID_FILE);
|
|
7011
|
+
await waitForPortFree(port, 5e3);
|
|
7012
|
+
return startServer({ port });
|
|
7013
|
+
}
|
|
7014
|
+
async function checkPort(port) {
|
|
7015
|
+
const { createServer } = await import("node:net");
|
|
7016
|
+
return new Promise((resolve4) => {
|
|
7017
|
+
const server = createServer();
|
|
7018
|
+
server.once("error", () => resolve4(true));
|
|
7019
|
+
server.once("listening", () => {
|
|
7020
|
+
server.close(() => resolve4(false));
|
|
7021
|
+
});
|
|
7022
|
+
server.listen(port, "localhost");
|
|
7023
|
+
});
|
|
7024
|
+
}
|
|
7025
|
+
async function waitForPortFree(port, timeoutMs) {
|
|
7026
|
+
const start = Date.now();
|
|
7027
|
+
while (Date.now() - start < timeoutMs) {
|
|
7028
|
+
if (!await checkPort(port)) return;
|
|
7029
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
7030
|
+
}
|
|
7031
|
+
}
|
|
7032
|
+
async function waitForHealth(url, timeoutMs) {
|
|
7033
|
+
const start = Date.now();
|
|
7034
|
+
while (Date.now() - start < timeoutMs) {
|
|
7035
|
+
try {
|
|
7036
|
+
const res = await fetch(url);
|
|
7037
|
+
if (res.ok) return;
|
|
7038
|
+
} catch {
|
|
7039
|
+
}
|
|
7040
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
7041
|
+
}
|
|
7042
|
+
throw new Error(`Server did not become healthy within ${timeoutMs / 1e3}s`);
|
|
7043
|
+
}
|
|
7044
|
+
var PID_FILE, DEFAULT_PORT, SERVER_MARKERS;
|
|
7045
|
+
var init_server = __esm({
|
|
7046
|
+
"src/server.ts"() {
|
|
7047
|
+
"use strict";
|
|
7048
|
+
init_pid();
|
|
7049
|
+
init_fs();
|
|
7050
|
+
PID_FILE = cclensPath("pid");
|
|
7051
|
+
DEFAULT_PORT = 3321;
|
|
7052
|
+
SERVER_MARKERS = ["next-server", "server.js"];
|
|
7053
|
+
}
|
|
7054
|
+
});
|
|
7055
|
+
|
|
7056
|
+
// src/daemon-worker.ts
|
|
7057
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
7058
|
+
import { closeSync, existsSync as existsSync20, mkdirSync as mkdirSync15, openSync, readFileSync as readFileSync23, writeFileSync as writeFileSync16 } from "node:fs";
|
|
7059
|
+
import { dirname as dirname14, join as join14 } from "node:path";
|
|
7060
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
6868
7061
|
|
|
6869
7062
|
// src/usage/token.ts
|
|
6870
7063
|
import { execFileSync } from "node:child_process";
|
|
@@ -7192,8 +7385,8 @@ async function refreshAccessToken(entry) {
|
|
|
7192
7385
|
break;
|
|
7193
7386
|
}
|
|
7194
7387
|
}
|
|
7195
|
-
const { writeFileSync:
|
|
7196
|
-
|
|
7388
|
+
const { writeFileSync: writeFileSync17 } = await import("node:fs");
|
|
7389
|
+
writeFileSync17(p, JSON.stringify(raw, null, 2), "utf8");
|
|
7197
7390
|
} catch {
|
|
7198
7391
|
}
|
|
7199
7392
|
return j.access_token;
|
|
@@ -9111,7 +9304,7 @@ function buildIngestPayload(inputs) {
|
|
|
9111
9304
|
return {
|
|
9112
9305
|
ingestId: randomUUID(),
|
|
9113
9306
|
observedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9114
|
-
cliVersion: "1.0.
|
|
9307
|
+
cliVersion: "1.0.2",
|
|
9115
9308
|
...richRollup || inputs.enrichedExtras || inputs.artifactSignals ? { schemaVersion: RICH_ROLLUP_SCHEMA_VERSION } : {},
|
|
9116
9309
|
...inputs.rollup ? { dailyRollup: inputs.rollup } : {},
|
|
9117
9310
|
...richRollup ? { richRollup } : {},
|
|
@@ -14492,10 +14685,10 @@ exec ${shellEscape(claudeBin)} \\
|
|
|
14492
14685
|
"$USR"
|
|
14493
14686
|
`, { mode: 493 });
|
|
14494
14687
|
const existingBefore = snapshotAllTranscripts();
|
|
14495
|
-
const
|
|
14496
|
-
if (
|
|
14688
|
+
const spawn5 = spawnSync(tmuxBin, ["new-session", "-d", "-s", sessionName, "-x", "140", "-y", "50", "-c", cwd, wrapper], { encoding: "utf8" });
|
|
14689
|
+
if (spawn5.status !== 0) {
|
|
14497
14690
|
cleanup(cwd, runId, tmuxBin, sessionName);
|
|
14498
|
-
throw new TmuxRunError(`tmux new-session failed: ${
|
|
14691
|
+
throw new TmuxRunError(`tmux new-session failed: ${spawn5.stderr.trim()}`);
|
|
14499
14692
|
}
|
|
14500
14693
|
const onAbort = () => {
|
|
14501
14694
|
try {
|
|
@@ -18045,30 +18238,73 @@ async function getUpdateAvailability() {
|
|
|
18045
18238
|
if (isDevMode()) return null;
|
|
18046
18239
|
const latest = await fetchLatestVersion();
|
|
18047
18240
|
if (latest === null) return {
|
|
18048
|
-
current: "1.0.
|
|
18241
|
+
current: "1.0.2",
|
|
18049
18242
|
latest: null,
|
|
18050
18243
|
updateAvailable: false
|
|
18051
18244
|
};
|
|
18052
18245
|
return {
|
|
18053
|
-
current: "1.0.
|
|
18246
|
+
current: "1.0.2",
|
|
18054
18247
|
latest,
|
|
18055
|
-
updateAvailable: shouldUpdate("1.0.
|
|
18248
|
+
updateAvailable: shouldUpdate("1.0.2", latest)
|
|
18056
18249
|
};
|
|
18057
18250
|
}
|
|
18058
18251
|
|
|
18252
|
+
// src/daemon-worker.ts
|
|
18253
|
+
init_server();
|
|
18254
|
+
|
|
18255
|
+
// src/watchdog.ts
|
|
18256
|
+
var FAILURE_THRESHOLD = 3;
|
|
18257
|
+
var MAX_RESTARTS_PER_WINDOW = 3;
|
|
18258
|
+
var WINDOW_MS = 60 * 60 * 1e3;
|
|
18259
|
+
var ServerWatchdog = class {
|
|
18260
|
+
failures = 0;
|
|
18261
|
+
restartsAt = [];
|
|
18262
|
+
/** A different pid is serving now. The failure run belongs to the old
|
|
18263
|
+
* process — a fresh server gets full grace — but the restart cap stays:
|
|
18264
|
+
* watchdog restarts change the pid too, and clearing the cap on every
|
|
18265
|
+
* one would disarm the flap guard entirely. */
|
|
18266
|
+
noteNewInstance() {
|
|
18267
|
+
this.failures = 0;
|
|
18268
|
+
}
|
|
18269
|
+
/** No tracked server at all (pid file gone). Watchdog restarts never pass
|
|
18270
|
+
* through this state — only an operator stop (or a cycle the watchdog
|
|
18271
|
+
* happens to observe mid-gap) does — so a human is at the wheel and the
|
|
18272
|
+
* restart budget re-arms in full. */
|
|
18273
|
+
noteServerGone() {
|
|
18274
|
+
this.failures = 0;
|
|
18275
|
+
this.restartsAt = [];
|
|
18276
|
+
}
|
|
18277
|
+
onProbe(ok, nowMs) {
|
|
18278
|
+
if (ok) {
|
|
18279
|
+
this.failures = 0;
|
|
18280
|
+
return "ok";
|
|
18281
|
+
}
|
|
18282
|
+
this.failures = Math.min(this.failures + 1, FAILURE_THRESHOLD);
|
|
18283
|
+
if (this.failures < FAILURE_THRESHOLD) return "failing";
|
|
18284
|
+
this.restartsAt = this.restartsAt.filter((t) => nowMs - t < WINDOW_MS);
|
|
18285
|
+
if (this.restartsAt.length >= MAX_RESTARTS_PER_WINDOW) return "gave-up";
|
|
18286
|
+
this.restartsAt.push(nowMs);
|
|
18287
|
+
this.failures = 0;
|
|
18288
|
+
return "restart";
|
|
18289
|
+
}
|
|
18290
|
+
};
|
|
18291
|
+
|
|
18059
18292
|
// src/daemon-worker.ts
|
|
18060
18293
|
var USAGE_LOG3 = cclensPath("usage.jsonl");
|
|
18061
18294
|
var DAEMON_LOG = cclensPath("daemon.log");
|
|
18062
18295
|
var UPDATE_STATE = cclensPath("daemon-update.json");
|
|
18063
18296
|
var WATCHDOG_INTERVAL_MS = 5 * 1e3;
|
|
18064
18297
|
var AUTO_UPDATE_INTERVAL_MS = 6 * 60 * 60 * 1e3;
|
|
18065
|
-
|
|
18298
|
+
var SERVER_HEALTH_INTERVAL_MS = 60 * 1e3;
|
|
18299
|
+
var SERVER_HEALTH_TIMEOUT_MS = 10 * 1e3;
|
|
18300
|
+
mkdirSync15(dirname14(USAGE_LOG3), { recursive: true });
|
|
18066
18301
|
function log2(level, message) {
|
|
18067
18302
|
appendDaemonLogLine(level, message);
|
|
18068
18303
|
}
|
|
18069
18304
|
var nextPollAtMs = 0;
|
|
18070
18305
|
var nextAuxPollAtMs = 0;
|
|
18071
18306
|
var nextTeamSyncAtMs = 0;
|
|
18307
|
+
var nextServerHealthAtMs = 0;
|
|
18072
18308
|
var firstTeamSync = true;
|
|
18073
18309
|
var currentIntervalMs = BASE_INTERVAL_MS;
|
|
18074
18310
|
var waitingForRefresh = false;
|
|
@@ -18101,14 +18337,14 @@ var perceptionHandle = setInterval(async () => {
|
|
|
18101
18337
|
}, PERCEPTION_INTERVAL_MS);
|
|
18102
18338
|
function readUpdateState() {
|
|
18103
18339
|
try {
|
|
18104
|
-
return JSON.parse(
|
|
18340
|
+
return JSON.parse(readFileSync23(UPDATE_STATE, "utf8"));
|
|
18105
18341
|
} catch {
|
|
18106
18342
|
return null;
|
|
18107
18343
|
}
|
|
18108
18344
|
}
|
|
18109
18345
|
function writeUpdateState(state) {
|
|
18110
18346
|
try {
|
|
18111
|
-
|
|
18347
|
+
writeFileSync16(UPDATE_STATE, JSON.stringify(state, null, 2), { mode: 384 });
|
|
18112
18348
|
} catch {
|
|
18113
18349
|
}
|
|
18114
18350
|
}
|
|
@@ -18121,7 +18357,7 @@ function nextUpdateCheckFromState(nowMs) {
|
|
|
18121
18357
|
}
|
|
18122
18358
|
var nextUpdateCheckAtMs = nextUpdateCheckFromState(Date.now());
|
|
18123
18359
|
function cliEntryPath() {
|
|
18124
|
-
return
|
|
18360
|
+
return join14(dirname14(fileURLToPath2(import.meta.url)), "index.js");
|
|
18125
18361
|
}
|
|
18126
18362
|
async function runDaemonUpdateCheck() {
|
|
18127
18363
|
if (process.env.FLEETLENS_DAEMON_AUTO_UPDATE === "0") {
|
|
@@ -18153,7 +18389,7 @@ async function runDaemonUpdateCheck() {
|
|
|
18153
18389
|
return;
|
|
18154
18390
|
}
|
|
18155
18391
|
const entry = cliEntryPath();
|
|
18156
|
-
if (!
|
|
18392
|
+
if (!existsSync20(entry)) {
|
|
18157
18393
|
log2("warn", `update check found ${availability.latest}, but CLI entry is missing at ${entry}`);
|
|
18158
18394
|
return;
|
|
18159
18395
|
}
|
|
@@ -18162,7 +18398,7 @@ async function runDaemonUpdateCheck() {
|
|
|
18162
18398
|
logFd = openSync(DAEMON_LOG, "a");
|
|
18163
18399
|
} catch {
|
|
18164
18400
|
}
|
|
18165
|
-
const child =
|
|
18401
|
+
const child = spawn4(process.execPath, [entry, "update"], {
|
|
18166
18402
|
detached: true,
|
|
18167
18403
|
stdio: ["ignore", logFd, logFd],
|
|
18168
18404
|
env: { ...process.env, FLEETLENS_UPDATE_SOURCE: "daemon" }
|
|
@@ -18192,6 +18428,44 @@ async function runDaemonUpdateCheck() {
|
|
|
18192
18428
|
nextUpdateCheckAtMs = Date.now() + AUTO_UPDATE_INTERVAL_MS;
|
|
18193
18429
|
}
|
|
18194
18430
|
}
|
|
18431
|
+
var serverWatchdog = new ServerWatchdog();
|
|
18432
|
+
var lastServerVerdict = "ok";
|
|
18433
|
+
var lastServerPid = null;
|
|
18434
|
+
async function runServerHealthCheck() {
|
|
18435
|
+
const status = getServerStatus();
|
|
18436
|
+
if (!status.running) {
|
|
18437
|
+
if (lastServerPid !== null) {
|
|
18438
|
+
serverWatchdog.noteServerGone();
|
|
18439
|
+
lastServerPid = null;
|
|
18440
|
+
}
|
|
18441
|
+
return;
|
|
18442
|
+
}
|
|
18443
|
+
if (status.pid !== lastServerPid) {
|
|
18444
|
+
serverWatchdog.noteNewInstance();
|
|
18445
|
+
lastServerPid = status.pid;
|
|
18446
|
+
}
|
|
18447
|
+
const ok = await probeServerHealth(status.port, SERVER_HEALTH_TIMEOUT_MS);
|
|
18448
|
+
const verdict = serverWatchdog.onProbe(ok, Date.now());
|
|
18449
|
+
if (verdict === "failing") {
|
|
18450
|
+
log2("warn", `[watchdog] server pid=${status.pid} not answering on port ${status.port}`);
|
|
18451
|
+
} else if (verdict === "restart") {
|
|
18452
|
+
log2("warn", `[watchdog] server pid=${status.pid} wedged; force-restarting on port ${status.port}`);
|
|
18453
|
+
try {
|
|
18454
|
+
const fresh = await restartWedgedServer(status.pid, status.port);
|
|
18455
|
+
log2("info", `[watchdog] server restarted (pid=${fresh.pid}, port=${fresh.port})`);
|
|
18456
|
+
} catch (err) {
|
|
18457
|
+
log2("error", `[watchdog] restart failed: ${err.message}`);
|
|
18458
|
+
}
|
|
18459
|
+
} else if (verdict === "gave-up" && lastServerVerdict !== "gave-up") {
|
|
18460
|
+
log2(
|
|
18461
|
+
"error",
|
|
18462
|
+
`[watchdog] server keeps wedging after 3 restarts within the hour; standing down \u2014 run 'fleetlens start' to restart manually`
|
|
18463
|
+
);
|
|
18464
|
+
} else if (verdict === "ok" && lastServerVerdict !== "ok") {
|
|
18465
|
+
log2("info", `[watchdog] server responding again (pid=${status.pid})`);
|
|
18466
|
+
}
|
|
18467
|
+
lastServerVerdict = verdict;
|
|
18468
|
+
}
|
|
18195
18469
|
async function pollAuxiliaryUsage() {
|
|
18196
18470
|
for (const source of agentSources) {
|
|
18197
18471
|
if (source.kind === "claude-code") continue;
|
|
@@ -18353,6 +18627,10 @@ async function runLoop() {
|
|
|
18353
18627
|
if (Date.now() >= nextUpdateCheckAtMs) {
|
|
18354
18628
|
await runDaemonUpdateCheck();
|
|
18355
18629
|
}
|
|
18630
|
+
if (Date.now() >= nextServerHealthAtMs) {
|
|
18631
|
+
await runServerHealthCheck();
|
|
18632
|
+
nextServerHealthAtMs = Date.now() + SERVER_HEALTH_INTERVAL_MS;
|
|
18633
|
+
}
|
|
18356
18634
|
await sleep2(WATCHDOG_INTERVAL_MS);
|
|
18357
18635
|
}
|
|
18358
18636
|
}
|
package/dist/index.js
CHANGED
|
@@ -6217,6 +6217,8 @@ __export(server_exports, {
|
|
|
6217
6217
|
getServerStatus: () => getServerStatus,
|
|
6218
6218
|
isServerStale: () => isServerStale,
|
|
6219
6219
|
openBrowser: () => openBrowser,
|
|
6220
|
+
probeServerHealth: () => probeServerHealth,
|
|
6221
|
+
restartWedgedServer: () => restartWedgedServer,
|
|
6220
6222
|
startServer: () => startServer,
|
|
6221
6223
|
stopServer: () => stopServer
|
|
6222
6224
|
});
|
|
@@ -6241,9 +6243,9 @@ function onDiskVersion() {
|
|
|
6241
6243
|
try {
|
|
6242
6244
|
const here = dirname3(fileURLToPath(import.meta.url));
|
|
6243
6245
|
const pkg = JSON.parse(readFileSync5(join3(here, "..", "package.json"), "utf8"));
|
|
6244
|
-
return pkg.version ?? "1.0.
|
|
6246
|
+
return pkg.version ?? "1.0.2";
|
|
6245
6247
|
} catch {
|
|
6246
|
-
return "1.0.
|
|
6248
|
+
return "1.0.2";
|
|
6247
6249
|
}
|
|
6248
6250
|
}
|
|
6249
6251
|
function getServerStatus() {
|
|
@@ -6255,7 +6257,7 @@ function getServerStatus() {
|
|
|
6255
6257
|
return { running: false };
|
|
6256
6258
|
}
|
|
6257
6259
|
function isServerStale(status2) {
|
|
6258
|
-
return status2.running === true && status2.version !== "1.0.
|
|
6260
|
+
return status2.running === true && status2.version !== "1.0.2";
|
|
6259
6261
|
}
|
|
6260
6262
|
async function ensureCurrentServer(opts = {}) {
|
|
6261
6263
|
const status2 = getServerStatus();
|
|
@@ -6316,6 +6318,25 @@ async function startServer(opts = {}) {
|
|
|
6316
6318
|
await waitForHealth(`http://localhost:${port}`, 3e4);
|
|
6317
6319
|
return { pid, port };
|
|
6318
6320
|
}
|
|
6321
|
+
async function probeServerHealth(port, timeoutMs) {
|
|
6322
|
+
try {
|
|
6323
|
+
await fetch(`http://localhost:${port}/api/health`, {
|
|
6324
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
6325
|
+
});
|
|
6326
|
+
return true;
|
|
6327
|
+
} catch {
|
|
6328
|
+
return false;
|
|
6329
|
+
}
|
|
6330
|
+
}
|
|
6331
|
+
async function restartWedgedServer(pid, port) {
|
|
6332
|
+
try {
|
|
6333
|
+
process.kill(pid, "SIGKILL");
|
|
6334
|
+
} catch {
|
|
6335
|
+
}
|
|
6336
|
+
removePid(PID_FILE);
|
|
6337
|
+
await waitForPortFree(port, 5e3);
|
|
6338
|
+
return startServer({ port });
|
|
6339
|
+
}
|
|
6319
6340
|
function stopServer() {
|
|
6320
6341
|
cleanStalePid(PID_FILE, SERVER_MARKERS);
|
|
6321
6342
|
const entry = readPid(PID_FILE);
|
|
@@ -6617,10 +6638,12 @@ function runNpmInstall() {
|
|
|
6617
6638
|
try {
|
|
6618
6639
|
execSync(`npm install -g ${PACKAGE_NAME}@latest --prefer-online`, {
|
|
6619
6640
|
stdio: "pipe",
|
|
6620
|
-
timeout:
|
|
6641
|
+
timeout: 3e5
|
|
6621
6642
|
});
|
|
6622
6643
|
return true;
|
|
6623
|
-
} catch {
|
|
6644
|
+
} catch (err) {
|
|
6645
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6646
|
+
console.error(` (npm install failed: ${msg.split("\n")[0]})`);
|
|
6624
6647
|
return false;
|
|
6625
6648
|
}
|
|
6626
6649
|
}
|
|
@@ -6695,9 +6718,9 @@ Installed: ${PACKAGE_NAME}@${verify.installedVersion} at ${verify.installedPath
|
|
|
6695
6718
|
console.warn(
|
|
6696
6719
|
` \u2022 reinstall in the correct Node env: 'npm install -g ${PACKAGE_NAME}@latest'`
|
|
6697
6720
|
);
|
|
6698
|
-
} else if (verify.installedVersion !== "1.0.
|
|
6721
|
+
} else if (verify.installedVersion !== "1.0.2") {
|
|
6699
6722
|
console.log(
|
|
6700
|
-
` \u2192 This process is still running ${"1.0.
|
|
6723
|
+
` \u2192 This process is still running ${"1.0.2"}. Next invocation will use ${verify.installedVersion}.`
|
|
6701
6724
|
);
|
|
6702
6725
|
}
|
|
6703
6726
|
}
|
|
@@ -6732,14 +6755,14 @@ async function getUpdateAvailability() {
|
|
|
6732
6755
|
if (isDevMode()) return null;
|
|
6733
6756
|
const latest = await fetchLatestVersion();
|
|
6734
6757
|
if (latest === null) return {
|
|
6735
|
-
current: "1.0.
|
|
6758
|
+
current: "1.0.2",
|
|
6736
6759
|
latest: null,
|
|
6737
6760
|
updateAvailable: false
|
|
6738
6761
|
};
|
|
6739
6762
|
return {
|
|
6740
|
-
current: "1.0.
|
|
6763
|
+
current: "1.0.2",
|
|
6741
6764
|
latest,
|
|
6742
|
-
updateAvailable: shouldUpdate("1.0.
|
|
6765
|
+
updateAvailable: shouldUpdate("1.0.2", latest)
|
|
6743
6766
|
};
|
|
6744
6767
|
}
|
|
6745
6768
|
async function checkForUpdate() {
|
|
@@ -6829,7 +6852,7 @@ async function restartServices(state) {
|
|
|
6829
6852
|
}
|
|
6830
6853
|
async function forceUpdate() {
|
|
6831
6854
|
const latest = await fetchLatestVersion();
|
|
6832
|
-
const current = "1.0.
|
|
6855
|
+
const current = "1.0.2";
|
|
6833
6856
|
if (latest === null) {
|
|
6834
6857
|
console.error("Could not reach npm registry. Check your network.");
|
|
6835
6858
|
process.exit(1);
|
|
@@ -7239,10 +7262,18 @@ async function status() {
|
|
|
7239
7262
|
if (server.running) {
|
|
7240
7263
|
const url = `http://localhost:${server.port}`;
|
|
7241
7264
|
const ver = server.version ?? "unknown";
|
|
7242
|
-
|
|
7265
|
+
const responsive = await probeServerHealth(server.port, 3e3);
|
|
7266
|
+
if (responsive) {
|
|
7267
|
+
console.log(`Server: running on ${url} (PID ${server.pid}, v${ver})`);
|
|
7268
|
+
} else {
|
|
7269
|
+
console.log(`Server: running but UNRESPONSIVE on ${url} (PID ${server.pid}, v${ver})`);
|
|
7270
|
+
console.log(
|
|
7271
|
+
" \u26A0 process is alive but not answering HTTP \u2014 a running daemon's watchdog force-restarts a wedged server ('fleetlens daemon logs' shows its verdicts), or run 'fleetlens start' now"
|
|
7272
|
+
);
|
|
7273
|
+
}
|
|
7243
7274
|
if (isServerStale(server)) {
|
|
7244
7275
|
console.log(
|
|
7245
|
-
` \u26A0 serving stale ${ver} (CLI is ${"1.0.
|
|
7276
|
+
` \u26A0 serving stale ${ver} (CLI is ${"1.0.2"}) \u2014 run 'fleetlens start' to restart on the current version`
|
|
7246
7277
|
);
|
|
7247
7278
|
}
|
|
7248
7279
|
} else {
|
|
@@ -19935,7 +19966,7 @@ function buildIngestPayload(inputs) {
|
|
|
19935
19966
|
return {
|
|
19936
19967
|
ingestId: randomUUID2(),
|
|
19937
19968
|
observedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
19938
|
-
cliVersion: "1.0.
|
|
19969
|
+
cliVersion: "1.0.2",
|
|
19939
19970
|
...richRollup || inputs.enrichedExtras || inputs.artifactSignals ? { schemaVersion: RICH_ROLLUP_SCHEMA_VERSION } : {},
|
|
19940
19971
|
...inputs.rollup ? { dailyRollup: inputs.rollup } : {},
|
|
19941
19972
|
...richRollup ? { richRollup } : {},
|
|
@@ -21979,7 +22010,7 @@ async function main() {
|
|
|
21979
22010
|
case "version":
|
|
21980
22011
|
case "--version":
|
|
21981
22012
|
case "-v":
|
|
21982
|
-
console.log(`fleetlens ${"1.0.
|
|
22013
|
+
console.log(`fleetlens ${"1.0.2"}`);
|
|
21983
22014
|
break;
|
|
21984
22015
|
case "help":
|
|
21985
22016
|
case "--help":
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
<key>CFBundleName</key><string>Fleetlens</string>
|
|
11
11
|
<key>CFBundleDisplayName</key><string>Fleetlens</string>
|
|
12
12
|
<key>CFBundlePackageType</key><string>APPL</string>
|
|
13
|
-
<key>CFBundleShortVersionString</key><string>1.0.
|
|
14
|
-
<key>CFBundleVersion</key><string>1.0.
|
|
13
|
+
<key>CFBundleShortVersionString</key><string>1.0.2</string>
|
|
14
|
+
<key>CFBundleVersion</key><string>1.0.2</string>
|
|
15
15
|
<key>LSApplicationCategoryType</key><string>public.app-category.developer-tools</string>
|
|
16
16
|
<key>LSMinimumSystemVersion</key><string>14.0</string>
|
|
17
17
|
<key>LSUIElement</key><true/>
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
module.exports=[93695,(e,t,s)=>{t.exports=e.x("next/dist/shared/lib/no-fallback-error.external.js",()=>require("next/dist/shared/lib/no-fallback-error.external.js"))},18622,(e,t,s)=>{t.exports=e.x("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js"))},56704,(e,t,s)=>{t.exports=e.x("next/dist/server/app-render/work-async-storage.external.js",()=>require("next/dist/server/app-render/work-async-storage.external.js"))},32319,(e,t,s)=>{t.exports=e.x("next/dist/server/app-render/work-unit-async-storage.external.js",()=>require("next/dist/server/app-render/work-unit-async-storage.external.js"))},70406,(e,t,s)=>{t.exports=e.x("next/dist/compiled/@opentelemetry/api",()=>require("next/dist/compiled/@opentelemetry/api"))},50227,(e,t,s)=>{t.exports=e.x("node:path",()=>require("node:path"))},2157,(e,t,s)=>{t.exports=e.x("node:fs",()=>require("node:fs"))},60526,(e,t,s)=>{t.exports=e.x("node:os",()=>require("node:os"))},66680,(e,t,s)=>{t.exports=e.x("node:crypto",()=>require("node:crypto"))},27174,e=>{"use strict";e.i(39587),e.s([])},86040,e=>{"use strict";e.i(27174);var t=e.i(36521);let s=/\[request interrupted|interrupted by user/i,r=/rate.?limit|overloaded_error|api error|Error sending message/i,n=/<command-name>(\/[^<\s]+)<\/command-name>(?:[\s\S]*?<command-args>([\s\S]*?)<\/command-args>)?/,o=/<task-notification>/;function i(e){for(let t of e)if(t?.type==="text")return t.text}function a(e){return e<1e3?String(e):e<1e4?(e/1e3).toFixed(1)+"k":e<1e6?Math.round(e/1e3)+"k":e<1e7?(e/1e6).toFixed(2)+"M":(e/1e6).toFixed(1)+"M"}function u(e){if(void 0===e||e<0)return"—";let t=Math.floor(e/1e3),s=Math.floor(t/3600),r=String(Math.floor(t%3600/60)).padStart(2,"0"),n=String(t%60).padStart(2,"0");return`${s}:${r}:${n}`}function l(e){if(void 0===e)return"—";if(e<1e3)return`${e}ms`;let t=Math.round(e/1e3);if(t<60)return`${t}s`;let s=Math.floor(t/60),r=t%60;if(s<60)return r?`${s}m ${r}s`:`${s}m`;let n=Math.floor(s/60),o=s%60;return o?`${n}h ${o}m`:`${n}h`}function f(e,t){if(!e)return"";let s=e.replace(/\s+/g," ").trim();return s.length>t?s.slice(0,t-1)+"…":s}e.s(["summarizeSessionForAI",0,function(e){let p,d=function(e){let a=new Map;for(let t of e){if(!t.messageId)continue;let e=a.get(t.messageId)??[];e.push(t),a.set(t.messageId,e)}let u=e.filter(e=>{if("system"===e.role||"meta"===e.role||"tool-result"===e.role||"agent-thinking"===e.role)return!1;if("user"===e.role){let s=i(e.blocks)??"";if(0===e.blocks.length||!s.trim())return!1;if(n.test(s)||o.test(s))return!0;if((0,t.isFrameworkInjectedUserInput)(s))return!1}return!0}),l=[];for(let e=0;e<u.length;e++){let t=u[e];if("tool-call"===t.role){let t=e;for(;e+1<u.length&&"tool-call"===u[e+1].role;)e++;let s=u.slice(t,e+1),r=[],n=new Map;for(let e of s){let t=e.toolName??"tool";n.has(t)||r.push(t),n.set(t,(n.get(t)??0)+1)}let o=r.map(e=>({name:e,count:n.get(e)??1}));l.push({kind:"tool-group",toolNames:o,count:s.length,events:s,tOffsetMs:s[0].tOffsetMs,gapMs:s[0].gapMs});continue}if("user"===t.role){let e=i(t.blocks)??"",r=function(e){if(!o.test(e))return null;let t=t=>{let s=e.match(RegExp(`<${t}>([\\s\\S]*?)<\\/${t}>`));return s?s[1].trim():void 0},s=(t("status")??"").toLowerCase(),r="unknown";return"success"===s||"ok"===s||"done"===s||"completed"===s?r="success":"failed"===s||"error"===s||"fail"===s?r="failed":("running"===s||"in_progress"===s)&&(r="running"),{status:r,summary:t("summary")??"Background task notification",taskId:t("task-id"),toolUseId:t("tool-use-id"),outputFile:t("output-file")}}(e);if(r){l.push({kind:"task-notification",event:t,status:r.status,summary:r.summary,taskId:r.taskId,toolUseId:r.toolUseId,outputFile:r.outputFile,tOffsetMs:t.tOffsetMs,gapMs:t.gapMs});continue}if(s.test(e)){l.push({kind:"interrupt",event:t,tOffsetMs:t.tOffsetMs,gapMs:t.gapMs});continue}let a=e.match(n);if(a){let e=a[1],s=(a[2]??"").trim(),r=s?`${e} ${s}`:e;l.push({kind:"user",event:t,displayPreview:r,displayBlocks:[{type:"text",text:r}],tOffsetMs:t.tOffsetMs,gapMs:t.gapMs});continue}l.push({kind:"user",event:t,tOffsetMs:t.tOffsetMs,gapMs:t.gapMs});continue}if("agent"===t.role){let e=i(t.blocks)??"";if(function(e){if(!e.usage)return!1;let t=e.usage;return 0===t.input&&0===t.output&&0===t.cacheRead&&0===t.cacheWrite}(t)){l.push({kind:"model",event:t,tOffsetMs:t.tOffsetMs,gapMs:t.gapMs}),r.test(e)&&e.length<500&&l.push({kind:"error",event:t,message:e,tOffsetMs:t.tOffsetMs,gapMs:0});continue}if(r.test(e)&&e.length<500){l.push({kind:"error",event:t,message:e,tOffsetMs:t.tOffsetMs,gapMs:t.gapMs});continue}let s=t.messageId?a.get(t.messageId)??[t]:[t];l.push({kind:"agent",event:t,groupedEvents:s,tOffsetMs:t.tOffsetMs,gapMs:t.gapMs});continue}}return l}(e.events),c=function(e){let t=[],s=[],r=null,n=()=>{let e,n;if(0===s.length)return;let o=0,i=0,a=0,u=new Map,l=new Set,f={input:0,output:0,cacheRead:0,cacheWrite:0};for(let t=0;t<s.length;t++){let r=s[t];if("agent"===r.kind){o++,void 0===e&&(e=t);let s=r.event.messageId,n=r.event.usage;s&&!l.has(s)&&n&&(l.add(s),f.input+=n.input,f.output+=n.output,f.cacheRead+=n.cacheRead,f.cacheWrite+=n.cacheWrite)}else if("tool-group"===r.kind)for(let e of(i+=r.count,r.toolNames))u.set(e.name,(u.get(e.name)??0)+e.count);else"error"===r.kind&&a++}for(let e=s.length-1;e>=0;e--){if("agent"!==s[e].kind)continue;let t=s[e-1];if(t?.kind!=="task-notification"){n=e;break}}if(void 0===n){for(let e=s.length-1;e>=0;e--)if("agent"===s[e].kind){n=e;break}}let p=void 0!==e&&"agent"===s[e].kind?s[e].event.preview:void 0,d=void 0!==n&&"agent"===s[n].kind?s[n].event.preview:void 0,c=Array.from(u.entries()).sort((e,t)=>t[1]-e[1]).map(([e,t])=>({name:e,count:t})),m=s[0],g=s[s.length-1],h=r?.tOffsetMs??m.tOffsetMs,k=g.tOffsetMs;t.push({kind:"turn",rows:s,firstPrimaryIndex:"tool-group"===m.kind?m.events[0].index:m.event.index,tOffsetMs:h,durationMs:void 0!==h&&void 0!==k&&k>=h?k-h:void 0,summary:{agentMessages:o,toolCalls:i,errors:a,firstAgentPreview:p,finalAgentPreview:d,firstAgentIndex:e,finalAgentIndex:n,toolNames:c,totalTokens:f}}),s=[]};for(let o of e)"user"===o.kind||"interrupt"===o.kind?(n(),t.push(o),r=o):s.push(o);return n(),t}(d),m=e.totalUsage.input+e.totalUsage.cacheRead+e.totalUsage.cacheWrite,g=e.totalUsage.cacheRead+e.totalUsage.cacheWrite,h=new Map;for(let e of d)if("tool-group"===e.kind)for(let t of e.toolNames)h.set(t.name,(h.get(t.name)??0)+t.count);let k=Array.from(h.entries()).sort((e,t)=>t[1]-e[1]).slice(0,8).map(([e,t])=>`${e}\xd7${t}`).join(", "),v=d.find(e=>"user"===e.kind&&!e.event.preview.startsWith("<command-name>")&&!e.event.preview.startsWith("Base directory for this skill:")),M=v?.kind==="user"?v.displayBlocks?.[0]?.type==="text"?v.displayBlocks[0].text:(p=v.event.blocks.find(e=>e?.type==="text"),p?.text??v.event.preview):"",x=d.filter(e=>"error"===e.kind),$=x.length>0?`${x.length} errors, first: "${f(x[0].message,160)}"`:"none",y=[],w=e.durationMs??0;for(let t of e.events){if("tool-call"!==t.role||"Bash"!==t.toolName)continue;let e=t.blocks.find(e=>e&&"tool_use"===e.type),s="string"==typeof e?.input?.command?e.input.command:"";if(!/gh\s+pr\s+create\b/i.test(s))continue;let r=s.match(/--title\s+["']([^"']+)["']/),n=r?.[1]??s.replace(/^gh pr create /,"").slice(0,120),o=w>0&&void 0!==t.tOffsetMs?Math.round(t.tOffsetMs/w*100):0;y.push({offsetPct:o,titleOrCmd:n})}let O="";for(let e=c.length-1;e>=0;e--){let t=c[e];if("turn"!==t.kind)continue;let s=t.summary.finalAgentIndex;if(void 0!==s){let e=t.rows[s];if(e?.kind==="agent"){let t=e.event.blocks.find(e=>e&&"text"===e.type);O=t?.text??e.event.preview;break}}}let b=[];for(let e of c){if(b.length>=40){b.push({offset:"...",line:`(+${c.length-b.length} more rows)`});break}if("user"===e.kind){let t=f(function(e){switch(e.kind){case"user":return e.displayPreview??e.event.preview;case"agent":return e.event.preview;case"tool-group":return e.toolNames.slice(0,4).map(e=>e.count>1?`${e.name} \xd7${e.count}`:e.name).join(", ");case"interrupt":return"[interrupted]";case"model":return"[zero-usage response]";case"error":return`ERROR: ${e.message}`;case"task-notification":return`BG task ${e.status}: ${e.summary}`;default:return""}}(e),180);t.startsWith("<command-name>")||b.push({offset:u(e.tOffsetMs),line:`USER: ${t}`})}else if("turn"===e.kind){let t=e.summary,s=t.firstAgentPreview?f(t.firstAgentPreview,180):"",r=t.finalAgentPreview?f(t.finalAgentPreview,180):"",n=s&&r&&s===r,o=t.toolNames.slice(0,3).map(e=>e.count>1?`${e.name}\xd7${e.count}`:e.name).join(", "),i=`${t.agentMessages} msg, ${t.toolCalls} tools${t.errors>0?`, ${t.errors} err`:""}`,a=n||!r?s:`${s} → ${r}`;b.push({offset:u(e.tOffsetMs),line:`TURN (${i}${o?`, ${o}`:""}): ${a}`})}else"interrupt"===e.kind&&b.push({offset:u(e.tOffsetMs),line:"INTERRUPT"})}let I=[];for(let t of(I.push(`# Session ${e.id}`),I.push(`project: ${e.projectName}`),e.model&&I.push(`model: ${e.model}`),I.push(`duration: ${l(e.durationMs)} | active: ${l(e.airTimeMs??e.durationMs)}`),I.push(`events: ${e.eventCount} | tokens: ${a(m)} in / ${a(e.totalUsage.output)} out${g>0?` (+${a(g)} cached)`:""}`),I.push(`tool calls: ${e.toolCallCount??0}${k?` (${k})`:""}`),I.push(`turns: ${e.turnCount??0}`),e.firstTimestamp&&I.push(`started: ${e.firstTimestamp}`),I.push(""),M&&(I.push("## First user message"),I.push(f(M,1200)),I.push("")),I.push("## Timeline"),b))I.push(`[${t.offset}] ${t.line}`);if(I.push(""),y.length>0){for(let e of(I.push("## PRs shipped"),y))I.push(`- at ${e.offsetPct}% into session: ${f(e.titleOrCmd,160)}`);I.push("")}return I.push("## Errors encountered"),I.push($),I.push(""),O&&(I.push("## Final agent message"),I.push(f(O,800))),I.join("\n")}],86040)}];
|
|
2
|
-
|
|
3
|
-
//# sourceMappingURL=%5Broot-of-the-server%5D__0sbhe0s._.js.map
|