@swestash/agent-lens 0.9.0 → 0.9.1
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/dist/agent-lens.js +147 -57
- package/dist/agent-lens.js.map +1 -1
- package/package.json +1 -1
package/dist/agent-lens.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { existsSync as
|
|
5
|
-
import { dirname as
|
|
4
|
+
import { existsSync as existsSync10, readFileSync as readFileSync8, writeFileSync as writeFileSync3 } from "fs";
|
|
5
|
+
import { dirname as dirname7, join as join13 } from "path";
|
|
6
6
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
7
7
|
|
|
8
8
|
// ../../node_modules/.pnpm/cac@6.7.14/node_modules/cac/dist/index.mjs
|
|
@@ -2077,8 +2077,8 @@ function runService(action, params) {
|
|
|
2077
2077
|
}
|
|
2078
2078
|
|
|
2079
2079
|
// ../ingest/dist/run.js
|
|
2080
|
-
import { readFileSync as readFileSync7, statSync as statSync5, mkdirSync as mkdirSync4, existsSync as
|
|
2081
|
-
import { dirname as
|
|
2080
|
+
import { readFileSync as readFileSync7, statSync as statSync5, mkdirSync as mkdirSync4, existsSync as existsSync5 } from "fs";
|
|
2081
|
+
import { dirname as dirname5, join as join10 } from "path";
|
|
2082
2082
|
|
|
2083
2083
|
// ../ingest/dist/db.js
|
|
2084
2084
|
import Database from "better-sqlite3";
|
|
@@ -3323,8 +3323,96 @@ function deriveFileChanges(db, dirty) {
|
|
|
3323
3323
|
return { count, version: FILECHANGES_VERSION };
|
|
3324
3324
|
}
|
|
3325
3325
|
|
|
3326
|
-
// ../ingest/dist/
|
|
3326
|
+
// ../ingest/dist/canonicalize.js
|
|
3327
|
+
import { existsSync as existsSync4 } from "fs";
|
|
3328
|
+
import { homedir as homedir3 } from "os";
|
|
3327
3329
|
import { createHash as createHash4 } from "crypto";
|
|
3330
|
+
import { dirname as dirname4, join as join6 } from "path";
|
|
3331
|
+
function projectId(agentId, path3) {
|
|
3332
|
+
return createHash4("sha1").update(`${agentId}\0${path3}`).digest("hex").slice(0, 16);
|
|
3333
|
+
}
|
|
3334
|
+
var strip = (p) => p.length > 1 ? p.replace(/\/$/, "") : p;
|
|
3335
|
+
function nearestGitRoot(path3, home) {
|
|
3336
|
+
let cur = strip(path3);
|
|
3337
|
+
while (cur !== home && cur !== "/" && cur.length > 0) {
|
|
3338
|
+
if (existsSync4(join6(cur, ".git")))
|
|
3339
|
+
return cur;
|
|
3340
|
+
const next = dirname4(cur);
|
|
3341
|
+
if (next === cur)
|
|
3342
|
+
break;
|
|
3343
|
+
cur = next;
|
|
3344
|
+
}
|
|
3345
|
+
return null;
|
|
3346
|
+
}
|
|
3347
|
+
function canonicalizeProjects(db, opts = {}) {
|
|
3348
|
+
const home = strip(opts.homeDir ?? homedir3());
|
|
3349
|
+
const rows = db.prepare("SELECT id, agent_id, path FROM projects").all();
|
|
3350
|
+
const byPath = /* @__PURE__ */ new Map();
|
|
3351
|
+
for (const r of rows)
|
|
3352
|
+
byPath.set(strip(r.path), { id: r.id, agent_id: r.agent_id });
|
|
3353
|
+
const withMains = new Set(db.prepare("SELECT DISTINCT project_id FROM sessions WHERE is_sidechain = 0 AND project_id IS NOT NULL").all().map((r) => r.project_id));
|
|
3354
|
+
const memo = /* @__PURE__ */ new Map();
|
|
3355
|
+
function canon(path3) {
|
|
3356
|
+
const p = strip(path3);
|
|
3357
|
+
const hit = memo.get(p);
|
|
3358
|
+
if (hit)
|
|
3359
|
+
return hit;
|
|
3360
|
+
memo.set(p, p);
|
|
3361
|
+
let out = p;
|
|
3362
|
+
if (p !== home) {
|
|
3363
|
+
const git = nearestGitRoot(p, home);
|
|
3364
|
+
if (git) {
|
|
3365
|
+
out = git;
|
|
3366
|
+
} else if (existsSync4(p) || !withMains.has(byPath.get(p)?.id ?? "")) {
|
|
3367
|
+
for (let cur = dirname4(p); cur !== "/" && cur !== home && cur.length > 0; cur = dirname4(cur)) {
|
|
3368
|
+
if (byPath.has(cur)) {
|
|
3369
|
+
out = canon(cur);
|
|
3370
|
+
break;
|
|
3371
|
+
}
|
|
3372
|
+
if (dirname4(cur) === cur)
|
|
3373
|
+
break;
|
|
3374
|
+
}
|
|
3375
|
+
}
|
|
3376
|
+
}
|
|
3377
|
+
memo.set(p, out);
|
|
3378
|
+
return out;
|
|
3379
|
+
}
|
|
3380
|
+
let merged = 0;
|
|
3381
|
+
const upsertProject = db.prepare(`INSERT INTO projects (id, agent_id, path, encoded_dir, first_seen, last_seen)
|
|
3382
|
+
VALUES (?, ?, ?, NULL, NULL, NULL) ON CONFLICT(agent_id, path) DO NOTHING`);
|
|
3383
|
+
const repointSessions = db.prepare("UPDATE sessions SET project_id = ? WHERE project_id = ?");
|
|
3384
|
+
const repointFileChanges = db.prepare("UPDATE file_changes SET project_id = ? WHERE project_id = ?");
|
|
3385
|
+
const touched = /* @__PURE__ */ new Set();
|
|
3386
|
+
db.transaction(() => {
|
|
3387
|
+
for (const r of rows) {
|
|
3388
|
+
const target = canon(r.path);
|
|
3389
|
+
if (target === strip(r.path))
|
|
3390
|
+
continue;
|
|
3391
|
+
const targetId = byPath.get(target)?.id ?? projectId(r.agent_id, target);
|
|
3392
|
+
if (targetId === r.id)
|
|
3393
|
+
continue;
|
|
3394
|
+
if (!byPath.has(target)) {
|
|
3395
|
+
upsertProject.run(targetId, r.agent_id, target);
|
|
3396
|
+
byPath.set(target, { id: targetId, agent_id: r.agent_id });
|
|
3397
|
+
}
|
|
3398
|
+
repointSessions.run(targetId, r.id);
|
|
3399
|
+
repointFileChanges.run(targetId, r.id);
|
|
3400
|
+
touched.add(targetId);
|
|
3401
|
+
merged++;
|
|
3402
|
+
}
|
|
3403
|
+
const refresh = db.prepare(`UPDATE projects SET
|
|
3404
|
+
first_seen = (SELECT MIN(started_at) FROM sessions WHERE project_id = projects.id),
|
|
3405
|
+
last_seen = (SELECT MAX(COALESCE(ended_at, started_at)) FROM sessions WHERE project_id = projects.id)
|
|
3406
|
+
WHERE id = ?`);
|
|
3407
|
+
for (const id of touched)
|
|
3408
|
+
refresh.run(id);
|
|
3409
|
+
})();
|
|
3410
|
+
const removed = db.prepare("DELETE FROM projects WHERE id NOT IN (SELECT DISTINCT project_id FROM sessions WHERE project_id IS NOT NULL)").run().changes;
|
|
3411
|
+
return { merged, removed };
|
|
3412
|
+
}
|
|
3413
|
+
|
|
3414
|
+
// ../ingest/dist/pipeline.js
|
|
3415
|
+
import { createHash as createHash5 } from "crypto";
|
|
3328
3416
|
function newStats() {
|
|
3329
3417
|
return { files: 0, skipped: 0, malformed: 0, newEvents: 0 };
|
|
3330
3418
|
}
|
|
@@ -3362,7 +3450,7 @@ function skillSummary(body) {
|
|
|
3362
3450
|
return null;
|
|
3363
3451
|
}
|
|
3364
3452
|
function skillVersionId(name, body) {
|
|
3365
|
-
return
|
|
3453
|
+
return createHash5("sha1").update(name).update("\0").update(body).digest("hex").slice(0, 16);
|
|
3366
3454
|
}
|
|
3367
3455
|
function pruneExcluded(db, excludedPaths) {
|
|
3368
3456
|
if (!excludedPaths.length)
|
|
@@ -3744,11 +3832,11 @@ function ingestFile(db, stmts, adapter, file, lines, meta, now2, stats) {
|
|
|
3744
3832
|
result_summary: tr.result_summary ?? null
|
|
3745
3833
|
});
|
|
3746
3834
|
}
|
|
3747
|
-
let
|
|
3835
|
+
let projectId2 = null;
|
|
3748
3836
|
if (sessionMeta.cwd) {
|
|
3749
|
-
|
|
3837
|
+
projectId2 = createHash5("sha1").update(`${adapter.agentId}\0${sessionMeta.cwd}`).digest("hex").slice(0, 16);
|
|
3750
3838
|
stmts.upsertProject.run({
|
|
3751
|
-
id:
|
|
3839
|
+
id: projectId2,
|
|
3752
3840
|
agent_id: adapter.agentId,
|
|
3753
3841
|
path: sessionMeta.cwd,
|
|
3754
3842
|
encoded_dir: file.encodedDir || null,
|
|
@@ -3759,7 +3847,7 @@ function ingestFile(db, stmts, adapter, file, lines, meta, now2, stats) {
|
|
|
3759
3847
|
id: file.sessionId,
|
|
3760
3848
|
agent_id: adapter.agentId,
|
|
3761
3849
|
source_id: file.sourceId,
|
|
3762
|
-
project_id:
|
|
3850
|
+
project_id: projectId2,
|
|
3763
3851
|
slug: sessionMeta.slug ?? null,
|
|
3764
3852
|
ai_title: sessionMeta.ai_title ?? null,
|
|
3765
3853
|
cli_version: sessionMeta.cli_version ?? null,
|
|
@@ -3782,10 +3870,10 @@ function ingestFile(db, stmts, adapter, file, lines, meta, now2, stats) {
|
|
|
3782
3870
|
|
|
3783
3871
|
// ../ingest/dist/workflows.js
|
|
3784
3872
|
import { readdirSync as readdirSync3, readFileSync as readFileSync4, statSync as statSync2 } from "fs";
|
|
3785
|
-
import { basename as basename3, join as
|
|
3873
|
+
import { basename as basename3, join as join7 } from "path";
|
|
3786
3874
|
|
|
3787
3875
|
// ../ingest/dist/redact.js
|
|
3788
|
-
import { createHash as
|
|
3876
|
+
import { createHash as createHash6, randomBytes } from "crypto";
|
|
3789
3877
|
function parseExcludes(csv) {
|
|
3790
3878
|
return (csv ?? "").split(",").map((s) => s.trim()).filter(Boolean).map(encodeProjectPath);
|
|
3791
3879
|
}
|
|
@@ -3794,17 +3882,17 @@ function isExcludedArchivePath(filePath, excluded) {
|
|
|
3794
3882
|
}
|
|
3795
3883
|
|
|
3796
3884
|
// ../ingest/dist/fileread.js
|
|
3797
|
-
import { createHash as
|
|
3885
|
+
import { createHash as createHash7 } from "crypto";
|
|
3798
3886
|
import { openSync as openSync2, readSync as readSync2, closeSync as closeSync2 } from "fs";
|
|
3799
3887
|
import { StringDecoder } from "string_decoder";
|
|
3800
3888
|
var STREAM_THRESHOLD = 8 * 1024 * 1024;
|
|
3801
3889
|
var CHUNK2 = 64 * 1024;
|
|
3802
3890
|
function sha256(buf) {
|
|
3803
|
-
return
|
|
3891
|
+
return createHash7("sha256").update(buf).digest("hex");
|
|
3804
3892
|
}
|
|
3805
3893
|
function sha256File(path3) {
|
|
3806
3894
|
const fd = openSync2(path3, "r");
|
|
3807
|
-
const h =
|
|
3895
|
+
const h = createHash7("sha256");
|
|
3808
3896
|
const buf = Buffer.allocUnsafe(CHUNK2);
|
|
3809
3897
|
try {
|
|
3810
3898
|
let n;
|
|
@@ -3850,7 +3938,7 @@ function walkSidecars(dir, inWorkflows, out) {
|
|
|
3850
3938
|
return;
|
|
3851
3939
|
}
|
|
3852
3940
|
for (const e of entries) {
|
|
3853
|
-
const p =
|
|
3941
|
+
const p = join7(dir, e.name);
|
|
3854
3942
|
if (e.isDirectory())
|
|
3855
3943
|
walkSidecars(p, inWorkflows || e.name === "workflows", out);
|
|
3856
3944
|
else if (e.isFile() && inWorkflows && /^wf_.+\.json$/.test(e.name))
|
|
@@ -3859,11 +3947,11 @@ function walkSidecars(dir, inWorkflows, out) {
|
|
|
3859
3947
|
}
|
|
3860
3948
|
function discoverSidecars(sourceArchiveDir) {
|
|
3861
3949
|
const out = [];
|
|
3862
|
-
walkSidecars(
|
|
3950
|
+
walkSidecars(join7(sourceArchiveDir, "projects"), false, out);
|
|
3863
3951
|
try {
|
|
3864
|
-
for (const ts of readdirSync3(
|
|
3952
|
+
for (const ts of readdirSync3(join7(sourceArchiveDir, ".versions"), { withFileTypes: true }))
|
|
3865
3953
|
if (ts.isDirectory())
|
|
3866
|
-
walkSidecars(
|
|
3954
|
+
walkSidecars(join7(sourceArchiveDir, ts.name, "projects"), false, out);
|
|
3867
3955
|
} catch {
|
|
3868
3956
|
}
|
|
3869
3957
|
return out;
|
|
@@ -3981,7 +4069,7 @@ function ingestWorkflowResults(db, sourceArchiveDir, sourceId, excludedDirs, now
|
|
|
3981
4069
|
|
|
3982
4070
|
// ../ingest/dist/meta.js
|
|
3983
4071
|
import { readdirSync as readdirSync4, readFileSync as readFileSync5, statSync as statSync3 } from "fs";
|
|
3984
|
-
import { basename as basename4, join as
|
|
4072
|
+
import { basename as basename4, join as join8 } from "path";
|
|
3985
4073
|
function newMetaStats() {
|
|
3986
4074
|
return { files: 0, upserted: 0, skipped: 0, malformed: 0 };
|
|
3987
4075
|
}
|
|
@@ -3993,7 +4081,7 @@ function walkMeta(dir, inSubagents, out) {
|
|
|
3993
4081
|
return;
|
|
3994
4082
|
}
|
|
3995
4083
|
for (const e of entries) {
|
|
3996
|
-
const p =
|
|
4084
|
+
const p = join8(dir, e.name);
|
|
3997
4085
|
if (e.isDirectory())
|
|
3998
4086
|
walkMeta(p, inSubagents || e.name === "subagents", out);
|
|
3999
4087
|
else if (e.isFile() && inSubagents && /^agent-.+\.meta\.json$/.test(e.name))
|
|
@@ -4002,11 +4090,11 @@ function walkMeta(dir, inSubagents, out) {
|
|
|
4002
4090
|
}
|
|
4003
4091
|
function discoverMeta(sourceArchiveDir) {
|
|
4004
4092
|
const out = [];
|
|
4005
|
-
walkMeta(
|
|
4093
|
+
walkMeta(join8(sourceArchiveDir, "projects"), false, out);
|
|
4006
4094
|
try {
|
|
4007
|
-
for (const ts of readdirSync4(
|
|
4095
|
+
for (const ts of readdirSync4(join8(sourceArchiveDir, ".versions"), { withFileTypes: true }))
|
|
4008
4096
|
if (ts.isDirectory())
|
|
4009
|
-
walkMeta(
|
|
4097
|
+
walkMeta(join8(sourceArchiveDir, ts.name, "projects"), false, out);
|
|
4010
4098
|
} catch {
|
|
4011
4099
|
}
|
|
4012
4100
|
return out;
|
|
@@ -4080,7 +4168,7 @@ function ingestSubagentMeta(db, sourceArchiveDir, sourceId, excludedDirs, now2,
|
|
|
4080
4168
|
|
|
4081
4169
|
// ../ingest/dist/toolResults.js
|
|
4082
4170
|
import { readdirSync as readdirSync5, readFileSync as readFileSync6, statSync as statSync4 } from "fs";
|
|
4083
|
-
import { basename as basename5, join as
|
|
4171
|
+
import { basename as basename5, join as join9 } from "path";
|
|
4084
4172
|
function newToolResultStats() {
|
|
4085
4173
|
return { files: 0, upserted: 0, skipped: 0, malformed: 0 };
|
|
4086
4174
|
}
|
|
@@ -4092,7 +4180,7 @@ function walkResults(dir, inResults, out) {
|
|
|
4092
4180
|
return;
|
|
4093
4181
|
}
|
|
4094
4182
|
for (const e of entries) {
|
|
4095
|
-
const p =
|
|
4183
|
+
const p = join9(dir, e.name);
|
|
4096
4184
|
if (e.isDirectory())
|
|
4097
4185
|
walkResults(p, inResults || e.name === "tool-results", out);
|
|
4098
4186
|
else if (e.isFile() && inResults && e.name.endsWith(".txt"))
|
|
@@ -4101,11 +4189,11 @@ function walkResults(dir, inResults, out) {
|
|
|
4101
4189
|
}
|
|
4102
4190
|
function discoverResults(sourceArchiveDir) {
|
|
4103
4191
|
const out = [];
|
|
4104
|
-
walkResults(
|
|
4192
|
+
walkResults(join9(sourceArchiveDir, "projects"), false, out);
|
|
4105
4193
|
try {
|
|
4106
|
-
for (const ts of readdirSync5(
|
|
4194
|
+
for (const ts of readdirSync5(join9(sourceArchiveDir, ".versions"), { withFileTypes: true }))
|
|
4107
4195
|
if (ts.isDirectory())
|
|
4108
|
-
walkResults(
|
|
4196
|
+
walkResults(join9(sourceArchiveDir, ts.name, "projects"), false, out);
|
|
4109
4197
|
} catch {
|
|
4110
4198
|
}
|
|
4111
4199
|
return out;
|
|
@@ -4183,11 +4271,11 @@ function runIngest(argv = process.argv.slice(2)) {
|
|
|
4183
4271
|
const args = parseIngestArgs(argv);
|
|
4184
4272
|
const archiveRoot = args.archive || resolveArchiveDir();
|
|
4185
4273
|
const { path: dbPath } = resolveDbPath(args.db);
|
|
4186
|
-
if (!
|
|
4274
|
+
if (!existsSync5(archiveRoot)) {
|
|
4187
4275
|
console.error(`agent-lens-ingest: archive not found: ${archiveRoot} (run 'agent-lens collect' first)`);
|
|
4188
4276
|
process.exit(1);
|
|
4189
4277
|
}
|
|
4190
|
-
mkdirSync4(
|
|
4278
|
+
mkdirSync4(dirname5(dbPath), { recursive: true });
|
|
4191
4279
|
const db = args.full ? openRaw(dbPath) : openDb(dbPath);
|
|
4192
4280
|
if (args.full) {
|
|
4193
4281
|
resetSchema(db);
|
|
@@ -4220,7 +4308,7 @@ function runIngest(argv = process.argv.slice(2)) {
|
|
|
4220
4308
|
}
|
|
4221
4309
|
stmts.insAgent.run(adapter.agentId, adapter.agentName);
|
|
4222
4310
|
stmts.insSource.run({ id: source.label, label: source.label, agent_id: adapter.agentId, config_dir: source.configDir });
|
|
4223
|
-
let files = adapter.discover(
|
|
4311
|
+
let files = adapter.discover(join10(archiveRoot, source.label), source.label);
|
|
4224
4312
|
if (excludedDirs.length)
|
|
4225
4313
|
files = files.filter((f) => !isExcludedArchivePath(f.path, excludedDirs));
|
|
4226
4314
|
files.sort((a, b) => Number(a.isVersion) - Number(b.isVersion));
|
|
@@ -4252,11 +4340,12 @@ function runIngest(argv = process.argv.slice(2)) {
|
|
|
4252
4340
|
ingestFile(db, stmts, adapter, file, lines, { size: st.size, mtimeMs, hash: hash2 }, now2, stats);
|
|
4253
4341
|
dirty.add(file.sessionId);
|
|
4254
4342
|
}
|
|
4255
|
-
ingestWorkflowResults(db,
|
|
4256
|
-
ingestSubagentMeta(db,
|
|
4257
|
-
ingestToolResults(db,
|
|
4343
|
+
ingestWorkflowResults(db, join10(archiveRoot, source.label), source.label, excludedDirs, now2, wfStats, args.full);
|
|
4344
|
+
ingestSubagentMeta(db, join10(archiveRoot, source.label), source.label, excludedDirs, now2, metaStats, args.full);
|
|
4345
|
+
ingestToolResults(db, join10(archiveRoot, source.label), excludedDirs, now2, trStats, args.full);
|
|
4258
4346
|
}
|
|
4259
4347
|
const expanded = rebuildDerived(db, args.full ? null : dirty);
|
|
4348
|
+
canonicalizeProjects(db);
|
|
4260
4349
|
const classified = classify(db, args.full ? null : expanded);
|
|
4261
4350
|
const detected = detect(db, args.full ? null : expanded);
|
|
4262
4351
|
classifyErrors(db, args.full ? null : expanded);
|
|
@@ -4295,11 +4384,12 @@ function runMetrics(argv = process.argv.slice(2)) {
|
|
|
4295
4384
|
if (argv[i] === "--db")
|
|
4296
4385
|
dbArg = argv[++i] ?? "";
|
|
4297
4386
|
const { path: dbPath } = resolveDbPath(dbArg);
|
|
4298
|
-
if (!
|
|
4387
|
+
if (!existsSync5(dbPath)) {
|
|
4299
4388
|
console.error(`agent-lens-metrics: db not found: ${dbPath} (run ingest first)`);
|
|
4300
4389
|
process.exit(1);
|
|
4301
4390
|
}
|
|
4302
4391
|
const db = openDb(dbPath);
|
|
4392
|
+
canonicalizeProjects(db);
|
|
4303
4393
|
const r = classify(db);
|
|
4304
4394
|
const d = detect(db);
|
|
4305
4395
|
const e = classifyErrors(db);
|
|
@@ -4309,8 +4399,8 @@ function runMetrics(argv = process.argv.slice(2)) {
|
|
|
4309
4399
|
}
|
|
4310
4400
|
|
|
4311
4401
|
// ../server/dist/run.js
|
|
4312
|
-
import { existsSync as
|
|
4313
|
-
import { dirname as
|
|
4402
|
+
import { existsSync as existsSync8 } from "fs";
|
|
4403
|
+
import { dirname as dirname6 } from "path";
|
|
4314
4404
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
4315
4405
|
|
|
4316
4406
|
// ../server/dist/db.js
|
|
@@ -4816,13 +4906,13 @@ function listFiles(db, f = {}) {
|
|
|
4816
4906
|
ORDER BY ${col} ${dir}, g.file_path ASC LIMIT ? OFFSET ?`).all(...params, limit, offset);
|
|
4817
4907
|
return { total, files };
|
|
4818
4908
|
}
|
|
4819
|
-
function getFileTimeline(db, filePath,
|
|
4909
|
+
function getFileTimeline(db, filePath, projectId2) {
|
|
4820
4910
|
if (!tableExists(db, "file_changes"))
|
|
4821
4911
|
return null;
|
|
4822
4912
|
const params = [filePath];
|
|
4823
4913
|
let scope = "fc.file_path = ?";
|
|
4824
|
-
if (
|
|
4825
|
-
scope += " AND fc.project_id = ?", params.push(
|
|
4914
|
+
if (projectId2)
|
|
4915
|
+
scope += " AND fc.project_id = ?", params.push(projectId2);
|
|
4826
4916
|
const rows = db.prepare(`SELECT fc.id, fc.session_id, fc.turn_id, fc.event_uuid, fc.tool_name, fc.lines_added,
|
|
4827
4917
|
fc.lines_removed, fc.timestamp, fc.project_id,
|
|
4828
4918
|
s.ai_title, s.slug, s.source_id, s.started_at, t.seq AS turn_seq, t.prompt_preview,
|
|
@@ -4996,7 +5086,7 @@ function securitySummary(db) {
|
|
|
4996
5086
|
}
|
|
4997
5087
|
|
|
4998
5088
|
// ../server/dist/app.js
|
|
4999
|
-
import { existsSync as
|
|
5089
|
+
import { existsSync as existsSync7 } from "fs";
|
|
5000
5090
|
import Fastify from "fastify";
|
|
5001
5091
|
import fastifyStatic from "@fastify/static";
|
|
5002
5092
|
|
|
@@ -5272,8 +5362,8 @@ function dashboardBreakdowns(db, f) {
|
|
|
5272
5362
|
}
|
|
5273
5363
|
|
|
5274
5364
|
// ../server/dist/refresh.js
|
|
5275
|
-
import { existsSync as
|
|
5276
|
-
import { join as
|
|
5365
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync5 } from "fs";
|
|
5366
|
+
import { join as join11 } from "path";
|
|
5277
5367
|
function originAllowed(origin) {
|
|
5278
5368
|
if (!origin)
|
|
5279
5369
|
return true;
|
|
@@ -5294,13 +5384,13 @@ function writeBlocked(headers) {
|
|
|
5294
5384
|
}
|
|
5295
5385
|
function runRefresh() {
|
|
5296
5386
|
const dataDir = resolveDataDir(findRepoRoot());
|
|
5297
|
-
const lock = acquireLock(
|
|
5387
|
+
const lock = acquireLock(join11(dataDir, ".agent-lens.lock"));
|
|
5298
5388
|
if (!lock)
|
|
5299
5389
|
return null;
|
|
5300
5390
|
try {
|
|
5301
5391
|
const collected = collectAll();
|
|
5302
5392
|
const archiveRoot = resolveArchiveDir();
|
|
5303
|
-
if (!
|
|
5393
|
+
if (!existsSync6(archiveRoot))
|
|
5304
5394
|
mkdirSync5(archiveRoot, { recursive: true });
|
|
5305
5395
|
runIngest([]);
|
|
5306
5396
|
return { ok: true, collected };
|
|
@@ -5625,7 +5715,7 @@ async function createApp(db, opts = {}) {
|
|
|
5625
5715
|
return reply.code(404).send({ error: "not found" });
|
|
5626
5716
|
reply.header("content-type", "text/markdown; charset=utf-8").header("content-disposition", `attachment; filename="${out.filename}"`).send(out.markdown);
|
|
5627
5717
|
});
|
|
5628
|
-
if (opts.webDist &&
|
|
5718
|
+
if (opts.webDist && existsSync7(opts.webDist)) {
|
|
5629
5719
|
await app.register(fastifyStatic, { root: opts.webDist });
|
|
5630
5720
|
app.setNotFoundHandler((req, reply) => {
|
|
5631
5721
|
if (req.url.startsWith("/api/"))
|
|
@@ -5638,7 +5728,7 @@ async function createApp(db, opts = {}) {
|
|
|
5638
5728
|
|
|
5639
5729
|
// ../server/dist/run.js
|
|
5640
5730
|
async function startServer(overrides = {}) {
|
|
5641
|
-
const here =
|
|
5731
|
+
const here = dirname6(fileURLToPath2(import.meta.url));
|
|
5642
5732
|
const repoRoot = findRepoRoot(here);
|
|
5643
5733
|
const { path: dbPath } = resolveDbPath(overrides.db);
|
|
5644
5734
|
const { host, port } = resolveServerConfig({ port: overrides.port, host: overrides.host });
|
|
@@ -5647,7 +5737,7 @@ async function startServer(overrides = {}) {
|
|
|
5647
5737
|
console.error(`agent-lens-server: refusing to bind non-loopback host '${host}' (privacy). Set AGENT_LENS_ALLOW_NONLOCAL=1 to override.`);
|
|
5648
5738
|
process.exit(1);
|
|
5649
5739
|
}
|
|
5650
|
-
if (!
|
|
5740
|
+
if (!existsSync8(dbPath)) {
|
|
5651
5741
|
console.error(`agent-lens-server: db not found: ${dbPath} (run ingest first)`);
|
|
5652
5742
|
process.exit(1);
|
|
5653
5743
|
}
|
|
@@ -5658,7 +5748,7 @@ async function startServer(overrides = {}) {
|
|
|
5658
5748
|
try {
|
|
5659
5749
|
await app.listen({ host, port });
|
|
5660
5750
|
console.log(`agent-lens-server: http://${host}:${port} (db: ${dbPath})`);
|
|
5661
|
-
if (!
|
|
5751
|
+
if (!existsSync8(webDist))
|
|
5662
5752
|
console.log(" note: web SPA not built \u2014 run `pnpm --filter @agent-lens/web build`");
|
|
5663
5753
|
} catch (err) {
|
|
5664
5754
|
console.error(err);
|
|
@@ -5667,12 +5757,12 @@ async function startServer(overrides = {}) {
|
|
|
5667
5757
|
}
|
|
5668
5758
|
|
|
5669
5759
|
// src/watch.ts
|
|
5670
|
-
import { existsSync as
|
|
5671
|
-
import { join as
|
|
5760
|
+
import { existsSync as existsSync9 } from "fs";
|
|
5761
|
+
import { join as join12 } from "path";
|
|
5672
5762
|
import chokidar from "chokidar";
|
|
5673
5763
|
async function runWatch(opts = {}) {
|
|
5674
5764
|
const sources = loadSources();
|
|
5675
|
-
const lockPath =
|
|
5765
|
+
const lockPath = join12(resolveDataDir(findRepoRoot()), ".agent-lens.lock");
|
|
5676
5766
|
let running = false;
|
|
5677
5767
|
let pending = false;
|
|
5678
5768
|
const cycle = () => {
|
|
@@ -5705,7 +5795,7 @@ async function runWatch(opts = {}) {
|
|
|
5705
5795
|
}
|
|
5706
5796
|
};
|
|
5707
5797
|
cycle();
|
|
5708
|
-
const watchPaths = sources.map((s) =>
|
|
5798
|
+
const watchPaths = sources.map((s) => join12(s.configDir, "projects")).filter((p) => existsSync9(p));
|
|
5709
5799
|
if (watchPaths.length === 0) {
|
|
5710
5800
|
console.error("agent-lens watch: no source 'projects' directories found \u2014 nothing to watch");
|
|
5711
5801
|
}
|
|
@@ -5733,14 +5823,14 @@ async function runWatch(opts = {}) {
|
|
|
5733
5823
|
// src/index.ts
|
|
5734
5824
|
function version() {
|
|
5735
5825
|
try {
|
|
5736
|
-
const pkg = JSON.parse(readFileSync8(
|
|
5826
|
+
const pkg = JSON.parse(readFileSync8(join13(dirname7(fileURLToPath3(import.meta.url)), "../package.json"), "utf8"));
|
|
5737
5827
|
return pkg.version ?? "0.0.0";
|
|
5738
5828
|
} catch {
|
|
5739
5829
|
return "0.0.0";
|
|
5740
5830
|
}
|
|
5741
5831
|
}
|
|
5742
5832
|
function withLock(fn) {
|
|
5743
|
-
const lockPath =
|
|
5833
|
+
const lockPath = join13(resolveDataDir(findRepoRoot()), ".agent-lens.lock");
|
|
5744
5834
|
const lock = acquireLock(lockPath);
|
|
5745
5835
|
if (!lock) {
|
|
5746
5836
|
console.error("agent-lens: another collect/ingest run is in progress \u2014 skipping");
|
|
@@ -5785,7 +5875,7 @@ cli.command("metrics", "Re-run classification over an already-ingested DB").opti
|
|
|
5785
5875
|
});
|
|
5786
5876
|
cli.command("export <sessionId>", "Write a session to a shareable Markdown file (redacted by default)").option("--out <file>", "Write to this file (default: stdout)").option("--level <level>", "Redaction level: secrets (default) | structure").option("--no-redact", "Verbatim, UNREDACTED output (opt-out)").option("--db <path>", "SQLite DB path (overrides AGENT_LENS_DB / config db)").action((sessionId, opts) => {
|
|
5787
5877
|
const { path: dbPath } = resolveDbPath(opts.db);
|
|
5788
|
-
if (!
|
|
5878
|
+
if (!existsSync10(dbPath)) {
|
|
5789
5879
|
console.error(`agent-lens: db not found: ${dbPath} (run ingest first)`);
|
|
5790
5880
|
process.exit(1);
|
|
5791
5881
|
}
|