@hasna/recordings 0.2.5 → 0.2.6
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/cli/index.js +72 -41
- package/dist/db/agents.d.ts.map +1 -1
- package/dist/db/errors.d.ts +15 -0
- package/dist/db/errors.d.ts.map +1 -0
- package/dist/db/projects.d.ts.map +1 -1
- package/dist/index.js +72 -41
- package/dist/mcp/index.js +72 -41
- package/dist/server/index.js +110 -51
- package/dist/server/repo.d.ts +2 -0
- package/dist/server/repo.d.ts.map +1 -1
- package/dist/server/v1.d.ts.map +1 -1
- package/dist/storage.js +72 -41
- package/dist/store.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -1397,6 +1397,59 @@ function getRecordingStats(db) {
|
|
|
1397
1397
|
};
|
|
1398
1398
|
}
|
|
1399
1399
|
|
|
1400
|
+
// src/db/projects.ts
|
|
1401
|
+
function parseProject(row) {
|
|
1402
|
+
return {
|
|
1403
|
+
id: row["id"],
|
|
1404
|
+
name: row["name"],
|
|
1405
|
+
path: row["path"],
|
|
1406
|
+
description: row["description"] || null,
|
|
1407
|
+
created_at: row["created_at"],
|
|
1408
|
+
updated_at: row["updated_at"]
|
|
1409
|
+
};
|
|
1410
|
+
}
|
|
1411
|
+
function registerProject(name, path, description, db) {
|
|
1412
|
+
const d = db || getDatabase();
|
|
1413
|
+
const now2 = new Date().toISOString();
|
|
1414
|
+
const existing = d.query("SELECT * FROM projects WHERE path = ?").get(path);
|
|
1415
|
+
if (existing) {
|
|
1416
|
+
d.query("UPDATE projects SET updated_at = ? WHERE id = ?").run(now2, existing["id"]);
|
|
1417
|
+
return getProject(existing["id"], d);
|
|
1418
|
+
}
|
|
1419
|
+
const id = crypto.randomUUID();
|
|
1420
|
+
d.query("INSERT INTO projects (id, name, path, description, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)").run(id, name, path, description || null, now2, now2);
|
|
1421
|
+
return getProject(id, d);
|
|
1422
|
+
}
|
|
1423
|
+
function getProject(idOrPath, db) {
|
|
1424
|
+
const d = db || getDatabase();
|
|
1425
|
+
let row = d.query("SELECT * FROM projects WHERE id = ?").get(idOrPath);
|
|
1426
|
+
if (!row) {
|
|
1427
|
+
row = d.query("SELECT * FROM projects WHERE path = ?").get(idOrPath);
|
|
1428
|
+
}
|
|
1429
|
+
if (!row) {
|
|
1430
|
+
row = d.query("SELECT * FROM projects WHERE name = ?").get(idOrPath);
|
|
1431
|
+
}
|
|
1432
|
+
if (!row && idOrPath) {
|
|
1433
|
+
row = d.query("SELECT * FROM projects WHERE id LIKE ? || '%'").get(idOrPath);
|
|
1434
|
+
}
|
|
1435
|
+
return row ? parseProject(row) : null;
|
|
1436
|
+
}
|
|
1437
|
+
function listProjects(db) {
|
|
1438
|
+
const d = db || getDatabase();
|
|
1439
|
+
const rows = d.query("SELECT * FROM projects ORDER BY updated_at DESC").all();
|
|
1440
|
+
return rows.map(parseProject);
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
// src/db/errors.ts
|
|
1444
|
+
class ProjectNotFoundError extends Error {
|
|
1445
|
+
ref;
|
|
1446
|
+
constructor(ref) {
|
|
1447
|
+
super(`project not found: ${ref}`);
|
|
1448
|
+
this.name = "ProjectNotFoundError";
|
|
1449
|
+
this.ref = ref;
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1400
1453
|
// src/db/agents.ts
|
|
1401
1454
|
function parseAgent(row) {
|
|
1402
1455
|
return {
|
|
@@ -1450,49 +1503,19 @@ function setAgentFocus(idOrName, projectId, db) {
|
|
|
1450
1503
|
const agent = getAgent(idOrName, d);
|
|
1451
1504
|
if (!agent)
|
|
1452
1505
|
return null;
|
|
1453
|
-
|
|
1506
|
+
let resolvedProjectId = null;
|
|
1507
|
+
if (projectId) {
|
|
1508
|
+
const project = getProject(projectId, d);
|
|
1509
|
+
if (!project)
|
|
1510
|
+
throw new ProjectNotFoundError(projectId);
|
|
1511
|
+
resolvedProjectId = project.id;
|
|
1512
|
+
}
|
|
1513
|
+
d.query("UPDATE agents SET active_project_id = ?, last_seen_at = ? WHERE id = ?").run(resolvedProjectId, new Date().toISOString(), agent.id);
|
|
1454
1514
|
return getAgent(agent.id, d);
|
|
1455
1515
|
}
|
|
1456
1516
|
|
|
1457
|
-
// src/db/projects.ts
|
|
1458
|
-
function parseProject(row) {
|
|
1459
|
-
return {
|
|
1460
|
-
id: row["id"],
|
|
1461
|
-
name: row["name"],
|
|
1462
|
-
path: row["path"],
|
|
1463
|
-
description: row["description"] || null,
|
|
1464
|
-
created_at: row["created_at"],
|
|
1465
|
-
updated_at: row["updated_at"]
|
|
1466
|
-
};
|
|
1467
|
-
}
|
|
1468
|
-
function registerProject(name, path, description, db) {
|
|
1469
|
-
const d = db || getDatabase();
|
|
1470
|
-
const now2 = new Date().toISOString();
|
|
1471
|
-
const existing = d.query("SELECT * FROM projects WHERE path = ?").get(path);
|
|
1472
|
-
if (existing) {
|
|
1473
|
-
d.query("UPDATE projects SET updated_at = ? WHERE id = ?").run(now2, existing["id"]);
|
|
1474
|
-
return getProject(existing["id"], d);
|
|
1475
|
-
}
|
|
1476
|
-
const id = crypto.randomUUID();
|
|
1477
|
-
d.query("INSERT INTO projects (id, name, path, description, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)").run(id, name, path, description || null, now2, now2);
|
|
1478
|
-
return getProject(id, d);
|
|
1479
|
-
}
|
|
1480
|
-
function getProject(idOrPath, db) {
|
|
1481
|
-
const d = db || getDatabase();
|
|
1482
|
-
let row = d.query("SELECT * FROM projects WHERE id = ?").get(idOrPath);
|
|
1483
|
-
if (!row) {
|
|
1484
|
-
row = d.query("SELECT * FROM projects WHERE path = ?").get(idOrPath);
|
|
1485
|
-
}
|
|
1486
|
-
return row ? parseProject(row) : null;
|
|
1487
|
-
}
|
|
1488
|
-
function listProjects(db) {
|
|
1489
|
-
const d = db || getDatabase();
|
|
1490
|
-
const rows = d.query("SELECT * FROM projects ORDER BY updated_at DESC").all();
|
|
1491
|
-
return rows.map(parseProject);
|
|
1492
|
-
}
|
|
1493
|
-
|
|
1494
1517
|
// src/version.ts
|
|
1495
|
-
var VERSION = "0.2.
|
|
1518
|
+
var VERSION = "0.2.6";
|
|
1496
1519
|
|
|
1497
1520
|
// src/db/feedback.ts
|
|
1498
1521
|
function saveFeedback(input) {
|
|
@@ -1923,8 +1946,16 @@ function apiStore(client) {
|
|
|
1923
1946
|
const res = await client.transport.post(`/agents/${encodeURIComponent(idOrName)}/focus`, { project_id: projectId });
|
|
1924
1947
|
return res ? unwrap(res, "agent") : null;
|
|
1925
1948
|
} catch (error) {
|
|
1926
|
-
if (error && typeof error === "object"
|
|
1927
|
-
|
|
1949
|
+
if (error && typeof error === "object") {
|
|
1950
|
+
const status = error.status;
|
|
1951
|
+
if (status === 404)
|
|
1952
|
+
return null;
|
|
1953
|
+
if (status === 400) {
|
|
1954
|
+
const body = error.body;
|
|
1955
|
+
const msg = body && typeof body === "object" && typeof body.error === "string" ? body.error : "invalid focus request";
|
|
1956
|
+
throw new Error(msg);
|
|
1957
|
+
}
|
|
1958
|
+
}
|
|
1928
1959
|
throw error;
|
|
1929
1960
|
}
|
|
1930
1961
|
},
|
package/dist/db/agents.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/db/agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/db/agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAI3C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAc/C,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,WAAW,CAAC,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,MAAM,EACb,EAAE,CAAC,EAAE,QAAQ,GACZ,KAAK,CAuBP;AAED,wBAAgB,QAAQ,CACtB,QAAQ,EAAE,MAAM,EAChB,EAAE,CAAC,EAAE,QAAQ,GACZ,KAAK,GAAG,IAAI,CAuBd;AAED,wBAAgB,UAAU,CAAC,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,EAAE,CAMjD;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,IAAI,CAS5E;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,IAAI,CAoBrG"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared domain errors for the storage layer.
|
|
3
|
+
*
|
|
4
|
+
* `ProjectNotFoundError` is thrown when a focus request references a project
|
|
5
|
+
* that cannot be resolved to a real row. It exists so both backends (LocalStore
|
|
6
|
+
* SQLite and the server Postgres repo) fail focus the SAME clean way — and so
|
|
7
|
+
* the `/v1` route can translate it into a 400 instead of leaking the raw
|
|
8
|
+
* foreign-key error (`agents_active_project_id_fkey` / "FOREIGN KEY constraint
|
|
9
|
+
* failed").
|
|
10
|
+
*/
|
|
11
|
+
export declare class ProjectNotFoundError extends Error {
|
|
12
|
+
readonly ref: string;
|
|
13
|
+
constructor(ref: string);
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/db/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;gBACT,GAAG,EAAE,MAAM;CAKxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/db/projects.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAajD,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,WAAW,CAAC,EAAE,MAAM,EACpB,EAAE,CAAC,EAAE,QAAQ,GACZ,OAAO,CAuBT;AAED,wBAAgB,UAAU,CACxB,QAAQ,EAAE,MAAM,EAChB,EAAE,CAAC,EAAE,QAAQ,GACZ,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/db/projects.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAajD,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,WAAW,CAAC,EAAE,MAAM,EACpB,EAAE,CAAC,EAAE,QAAQ,GACZ,OAAO,CAuBT;AAED,wBAAgB,UAAU,CACxB,QAAQ,EAAE,MAAM,EAChB,EAAE,CAAC,EAAE,QAAQ,GACZ,OAAO,GAAG,IAAI,CA4BhB;AAED,wBAAgB,YAAY,CAAC,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO,EAAE,CAMrD"}
|
package/dist/index.js
CHANGED
|
@@ -656,6 +656,59 @@ function getRecordingStats(db) {
|
|
|
656
656
|
};
|
|
657
657
|
}
|
|
658
658
|
|
|
659
|
+
// src/db/projects.ts
|
|
660
|
+
function parseProject(row) {
|
|
661
|
+
return {
|
|
662
|
+
id: row["id"],
|
|
663
|
+
name: row["name"],
|
|
664
|
+
path: row["path"],
|
|
665
|
+
description: row["description"] || null,
|
|
666
|
+
created_at: row["created_at"],
|
|
667
|
+
updated_at: row["updated_at"]
|
|
668
|
+
};
|
|
669
|
+
}
|
|
670
|
+
function registerProject(name, path, description, db) {
|
|
671
|
+
const d = db || getDatabase();
|
|
672
|
+
const now = new Date().toISOString();
|
|
673
|
+
const existing = d.query("SELECT * FROM projects WHERE path = ?").get(path);
|
|
674
|
+
if (existing) {
|
|
675
|
+
d.query("UPDATE projects SET updated_at = ? WHERE id = ?").run(now, existing["id"]);
|
|
676
|
+
return getProject(existing["id"], d);
|
|
677
|
+
}
|
|
678
|
+
const id = crypto.randomUUID();
|
|
679
|
+
d.query("INSERT INTO projects (id, name, path, description, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)").run(id, name, path, description || null, now, now);
|
|
680
|
+
return getProject(id, d);
|
|
681
|
+
}
|
|
682
|
+
function getProject(idOrPath, db) {
|
|
683
|
+
const d = db || getDatabase();
|
|
684
|
+
let row = d.query("SELECT * FROM projects WHERE id = ?").get(idOrPath);
|
|
685
|
+
if (!row) {
|
|
686
|
+
row = d.query("SELECT * FROM projects WHERE path = ?").get(idOrPath);
|
|
687
|
+
}
|
|
688
|
+
if (!row) {
|
|
689
|
+
row = d.query("SELECT * FROM projects WHERE name = ?").get(idOrPath);
|
|
690
|
+
}
|
|
691
|
+
if (!row && idOrPath) {
|
|
692
|
+
row = d.query("SELECT * FROM projects WHERE id LIKE ? || '%'").get(idOrPath);
|
|
693
|
+
}
|
|
694
|
+
return row ? parseProject(row) : null;
|
|
695
|
+
}
|
|
696
|
+
function listProjects(db) {
|
|
697
|
+
const d = db || getDatabase();
|
|
698
|
+
const rows = d.query("SELECT * FROM projects ORDER BY updated_at DESC").all();
|
|
699
|
+
return rows.map(parseProject);
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
// src/db/errors.ts
|
|
703
|
+
class ProjectNotFoundError extends Error {
|
|
704
|
+
ref;
|
|
705
|
+
constructor(ref) {
|
|
706
|
+
super(`project not found: ${ref}`);
|
|
707
|
+
this.name = "ProjectNotFoundError";
|
|
708
|
+
this.ref = ref;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
|
|
659
712
|
// src/db/agents.ts
|
|
660
713
|
function parseAgent(row) {
|
|
661
714
|
return {
|
|
@@ -709,49 +762,19 @@ function setAgentFocus(idOrName, projectId, db) {
|
|
|
709
762
|
const agent = getAgent(idOrName, d);
|
|
710
763
|
if (!agent)
|
|
711
764
|
return null;
|
|
712
|
-
|
|
765
|
+
let resolvedProjectId = null;
|
|
766
|
+
if (projectId) {
|
|
767
|
+
const project = getProject(projectId, d);
|
|
768
|
+
if (!project)
|
|
769
|
+
throw new ProjectNotFoundError(projectId);
|
|
770
|
+
resolvedProjectId = project.id;
|
|
771
|
+
}
|
|
772
|
+
d.query("UPDATE agents SET active_project_id = ?, last_seen_at = ? WHERE id = ?").run(resolvedProjectId, new Date().toISOString(), agent.id);
|
|
713
773
|
return getAgent(agent.id, d);
|
|
714
774
|
}
|
|
715
775
|
|
|
716
|
-
// src/db/projects.ts
|
|
717
|
-
function parseProject(row) {
|
|
718
|
-
return {
|
|
719
|
-
id: row["id"],
|
|
720
|
-
name: row["name"],
|
|
721
|
-
path: row["path"],
|
|
722
|
-
description: row["description"] || null,
|
|
723
|
-
created_at: row["created_at"],
|
|
724
|
-
updated_at: row["updated_at"]
|
|
725
|
-
};
|
|
726
|
-
}
|
|
727
|
-
function registerProject(name, path, description, db) {
|
|
728
|
-
const d = db || getDatabase();
|
|
729
|
-
const now = new Date().toISOString();
|
|
730
|
-
const existing = d.query("SELECT * FROM projects WHERE path = ?").get(path);
|
|
731
|
-
if (existing) {
|
|
732
|
-
d.query("UPDATE projects SET updated_at = ? WHERE id = ?").run(now, existing["id"]);
|
|
733
|
-
return getProject(existing["id"], d);
|
|
734
|
-
}
|
|
735
|
-
const id = crypto.randomUUID();
|
|
736
|
-
d.query("INSERT INTO projects (id, name, path, description, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)").run(id, name, path, description || null, now, now);
|
|
737
|
-
return getProject(id, d);
|
|
738
|
-
}
|
|
739
|
-
function getProject(idOrPath, db) {
|
|
740
|
-
const d = db || getDatabase();
|
|
741
|
-
let row = d.query("SELECT * FROM projects WHERE id = ?").get(idOrPath);
|
|
742
|
-
if (!row) {
|
|
743
|
-
row = d.query("SELECT * FROM projects WHERE path = ?").get(idOrPath);
|
|
744
|
-
}
|
|
745
|
-
return row ? parseProject(row) : null;
|
|
746
|
-
}
|
|
747
|
-
function listProjects(db) {
|
|
748
|
-
const d = db || getDatabase();
|
|
749
|
-
const rows = d.query("SELECT * FROM projects ORDER BY updated_at DESC").all();
|
|
750
|
-
return rows.map(parseProject);
|
|
751
|
-
}
|
|
752
|
-
|
|
753
776
|
// src/version.ts
|
|
754
|
-
var VERSION = "0.2.
|
|
777
|
+
var VERSION = "0.2.6";
|
|
755
778
|
|
|
756
779
|
// src/db/feedback.ts
|
|
757
780
|
function saveFeedback(input) {
|
|
@@ -1182,8 +1205,16 @@ function apiStore(client) {
|
|
|
1182
1205
|
const res = await client.transport.post(`/agents/${encodeURIComponent(idOrName)}/focus`, { project_id: projectId });
|
|
1183
1206
|
return res ? unwrap(res, "agent") : null;
|
|
1184
1207
|
} catch (error) {
|
|
1185
|
-
if (error && typeof error === "object"
|
|
1186
|
-
|
|
1208
|
+
if (error && typeof error === "object") {
|
|
1209
|
+
const status = error.status;
|
|
1210
|
+
if (status === 404)
|
|
1211
|
+
return null;
|
|
1212
|
+
if (status === 400) {
|
|
1213
|
+
const body = error.body;
|
|
1214
|
+
const msg = body && typeof body === "object" && typeof body.error === "string" ? body.error : "invalid focus request";
|
|
1215
|
+
throw new Error(msg);
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1187
1218
|
throw error;
|
|
1188
1219
|
}
|
|
1189
1220
|
},
|
package/dist/mcp/index.js
CHANGED
|
@@ -4530,6 +4530,59 @@ function getRecordingStats(db) {
|
|
|
4530
4530
|
};
|
|
4531
4531
|
}
|
|
4532
4532
|
|
|
4533
|
+
// src/db/projects.ts
|
|
4534
|
+
function parseProject(row) {
|
|
4535
|
+
return {
|
|
4536
|
+
id: row["id"],
|
|
4537
|
+
name: row["name"],
|
|
4538
|
+
path: row["path"],
|
|
4539
|
+
description: row["description"] || null,
|
|
4540
|
+
created_at: row["created_at"],
|
|
4541
|
+
updated_at: row["updated_at"]
|
|
4542
|
+
};
|
|
4543
|
+
}
|
|
4544
|
+
function registerProject(name, path, description, db) {
|
|
4545
|
+
const d = db || getDatabase();
|
|
4546
|
+
const now = new Date().toISOString();
|
|
4547
|
+
const existing = d.query("SELECT * FROM projects WHERE path = ?").get(path);
|
|
4548
|
+
if (existing) {
|
|
4549
|
+
d.query("UPDATE projects SET updated_at = ? WHERE id = ?").run(now, existing["id"]);
|
|
4550
|
+
return getProject(existing["id"], d);
|
|
4551
|
+
}
|
|
4552
|
+
const id = crypto.randomUUID();
|
|
4553
|
+
d.query("INSERT INTO projects (id, name, path, description, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)").run(id, name, path, description || null, now, now);
|
|
4554
|
+
return getProject(id, d);
|
|
4555
|
+
}
|
|
4556
|
+
function getProject(idOrPath, db) {
|
|
4557
|
+
const d = db || getDatabase();
|
|
4558
|
+
let row = d.query("SELECT * FROM projects WHERE id = ?").get(idOrPath);
|
|
4559
|
+
if (!row) {
|
|
4560
|
+
row = d.query("SELECT * FROM projects WHERE path = ?").get(idOrPath);
|
|
4561
|
+
}
|
|
4562
|
+
if (!row) {
|
|
4563
|
+
row = d.query("SELECT * FROM projects WHERE name = ?").get(idOrPath);
|
|
4564
|
+
}
|
|
4565
|
+
if (!row && idOrPath) {
|
|
4566
|
+
row = d.query("SELECT * FROM projects WHERE id LIKE ? || '%'").get(idOrPath);
|
|
4567
|
+
}
|
|
4568
|
+
return row ? parseProject(row) : null;
|
|
4569
|
+
}
|
|
4570
|
+
function listProjects(db) {
|
|
4571
|
+
const d = db || getDatabase();
|
|
4572
|
+
const rows = d.query("SELECT * FROM projects ORDER BY updated_at DESC").all();
|
|
4573
|
+
return rows.map(parseProject);
|
|
4574
|
+
}
|
|
4575
|
+
|
|
4576
|
+
// src/db/errors.ts
|
|
4577
|
+
class ProjectNotFoundError extends Error {
|
|
4578
|
+
ref;
|
|
4579
|
+
constructor(ref) {
|
|
4580
|
+
super(`project not found: ${ref}`);
|
|
4581
|
+
this.name = "ProjectNotFoundError";
|
|
4582
|
+
this.ref = ref;
|
|
4583
|
+
}
|
|
4584
|
+
}
|
|
4585
|
+
|
|
4533
4586
|
// src/db/agents.ts
|
|
4534
4587
|
function parseAgent(row) {
|
|
4535
4588
|
return {
|
|
@@ -4583,49 +4636,19 @@ function setAgentFocus(idOrName, projectId, db) {
|
|
|
4583
4636
|
const agent = getAgent(idOrName, d);
|
|
4584
4637
|
if (!agent)
|
|
4585
4638
|
return null;
|
|
4586
|
-
|
|
4639
|
+
let resolvedProjectId = null;
|
|
4640
|
+
if (projectId) {
|
|
4641
|
+
const project = getProject(projectId, d);
|
|
4642
|
+
if (!project)
|
|
4643
|
+
throw new ProjectNotFoundError(projectId);
|
|
4644
|
+
resolvedProjectId = project.id;
|
|
4645
|
+
}
|
|
4646
|
+
d.query("UPDATE agents SET active_project_id = ?, last_seen_at = ? WHERE id = ?").run(resolvedProjectId, new Date().toISOString(), agent.id);
|
|
4587
4647
|
return getAgent(agent.id, d);
|
|
4588
4648
|
}
|
|
4589
4649
|
|
|
4590
|
-
// src/db/projects.ts
|
|
4591
|
-
function parseProject(row) {
|
|
4592
|
-
return {
|
|
4593
|
-
id: row["id"],
|
|
4594
|
-
name: row["name"],
|
|
4595
|
-
path: row["path"],
|
|
4596
|
-
description: row["description"] || null,
|
|
4597
|
-
created_at: row["created_at"],
|
|
4598
|
-
updated_at: row["updated_at"]
|
|
4599
|
-
};
|
|
4600
|
-
}
|
|
4601
|
-
function registerProject(name, path, description, db) {
|
|
4602
|
-
const d = db || getDatabase();
|
|
4603
|
-
const now = new Date().toISOString();
|
|
4604
|
-
const existing = d.query("SELECT * FROM projects WHERE path = ?").get(path);
|
|
4605
|
-
if (existing) {
|
|
4606
|
-
d.query("UPDATE projects SET updated_at = ? WHERE id = ?").run(now, existing["id"]);
|
|
4607
|
-
return getProject(existing["id"], d);
|
|
4608
|
-
}
|
|
4609
|
-
const id = crypto.randomUUID();
|
|
4610
|
-
d.query("INSERT INTO projects (id, name, path, description, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)").run(id, name, path, description || null, now, now);
|
|
4611
|
-
return getProject(id, d);
|
|
4612
|
-
}
|
|
4613
|
-
function getProject(idOrPath, db) {
|
|
4614
|
-
const d = db || getDatabase();
|
|
4615
|
-
let row = d.query("SELECT * FROM projects WHERE id = ?").get(idOrPath);
|
|
4616
|
-
if (!row) {
|
|
4617
|
-
row = d.query("SELECT * FROM projects WHERE path = ?").get(idOrPath);
|
|
4618
|
-
}
|
|
4619
|
-
return row ? parseProject(row) : null;
|
|
4620
|
-
}
|
|
4621
|
-
function listProjects(db) {
|
|
4622
|
-
const d = db || getDatabase();
|
|
4623
|
-
const rows = d.query("SELECT * FROM projects ORDER BY updated_at DESC").all();
|
|
4624
|
-
return rows.map(parseProject);
|
|
4625
|
-
}
|
|
4626
|
-
|
|
4627
4650
|
// src/version.ts
|
|
4628
|
-
var VERSION = "0.2.
|
|
4651
|
+
var VERSION = "0.2.6";
|
|
4629
4652
|
|
|
4630
4653
|
// src/db/feedback.ts
|
|
4631
4654
|
function saveFeedback(input) {
|
|
@@ -5056,8 +5079,16 @@ function apiStore(client) {
|
|
|
5056
5079
|
const res = await client.transport.post(`/agents/${encodeURIComponent(idOrName)}/focus`, { project_id: projectId });
|
|
5057
5080
|
return res ? unwrap(res, "agent") : null;
|
|
5058
5081
|
} catch (error) {
|
|
5059
|
-
if (error && typeof error === "object"
|
|
5060
|
-
|
|
5082
|
+
if (error && typeof error === "object") {
|
|
5083
|
+
const status = error.status;
|
|
5084
|
+
if (status === 404)
|
|
5085
|
+
return null;
|
|
5086
|
+
if (status === 400) {
|
|
5087
|
+
const body = error.body;
|
|
5088
|
+
const msg = body && typeof body === "object" && typeof body.error === "string" ? body.error : "invalid focus request";
|
|
5089
|
+
throw new Error(msg);
|
|
5090
|
+
}
|
|
5091
|
+
}
|
|
5061
5092
|
throw error;
|
|
5062
5093
|
}
|
|
5063
5094
|
},
|
package/dist/server/index.js
CHANGED
|
@@ -18,7 +18,7 @@ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
|
18
18
|
var __require = import.meta.require;
|
|
19
19
|
|
|
20
20
|
// src/version.ts
|
|
21
|
-
var VERSION = "0.2.
|
|
21
|
+
var VERSION = "0.2.6";
|
|
22
22
|
|
|
23
23
|
// src/db/remote-storage.ts
|
|
24
24
|
import pg from "pg";
|
|
@@ -261,6 +261,19 @@ var init_cloud = __esm(() => {
|
|
|
261
261
|
init_pg_migrations();
|
|
262
262
|
});
|
|
263
263
|
|
|
264
|
+
// src/db/errors.ts
|
|
265
|
+
var ProjectNotFoundError;
|
|
266
|
+
var init_errors = __esm(() => {
|
|
267
|
+
ProjectNotFoundError = class ProjectNotFoundError extends Error {
|
|
268
|
+
ref;
|
|
269
|
+
constructor(ref) {
|
|
270
|
+
super(`project not found: ${ref}`);
|
|
271
|
+
this.name = "ProjectNotFoundError";
|
|
272
|
+
this.ref = ref;
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
});
|
|
276
|
+
|
|
264
277
|
// src/server/repo.ts
|
|
265
278
|
function shortUuid() {
|
|
266
279
|
return crypto.randomUUID().slice(0, 8);
|
|
@@ -446,7 +459,14 @@ async function setAgentFocus(pg2, idOrName, projectId) {
|
|
|
446
459
|
const agent = await getAgent(pg2, idOrName);
|
|
447
460
|
if (!agent)
|
|
448
461
|
return null;
|
|
449
|
-
|
|
462
|
+
let resolvedProjectId = null;
|
|
463
|
+
if (projectId) {
|
|
464
|
+
const project = await getProject(pg2, projectId);
|
|
465
|
+
if (!project)
|
|
466
|
+
throw new ProjectNotFoundError(projectId);
|
|
467
|
+
resolvedProjectId = project.id;
|
|
468
|
+
}
|
|
469
|
+
await pg2.run("UPDATE agents SET active_project_id = ?, last_seen_at = ? WHERE id = ?", resolvedProjectId, new Date().toISOString(), agent.id);
|
|
450
470
|
return getAgent(pg2, agent.id);
|
|
451
471
|
}
|
|
452
472
|
async function registerProject(pg2, name, path, description) {
|
|
@@ -467,6 +487,12 @@ async function getProject(pg2, idOrPath) {
|
|
|
467
487
|
if (!row) {
|
|
468
488
|
row = await pg2.get("SELECT * FROM projects WHERE path = ?", idOrPath);
|
|
469
489
|
}
|
|
490
|
+
if (!row) {
|
|
491
|
+
row = await pg2.get("SELECT * FROM projects WHERE name = ?", idOrPath);
|
|
492
|
+
}
|
|
493
|
+
if (!row && idOrPath) {
|
|
494
|
+
row = await pg2.get("SELECT * FROM projects WHERE id LIKE ? || '%'", idOrPath);
|
|
495
|
+
}
|
|
470
496
|
return row ? parseProject(row) : null;
|
|
471
497
|
}
|
|
472
498
|
async function listProjects(pg2) {
|
|
@@ -480,6 +506,9 @@ async function saveFeedback(pg2, input) {
|
|
|
480
506
|
await pg2.run("INSERT INTO feedback (message, email, category, version) VALUES (?, ?, ?, ?)", input.message, input.email || null, input.category || "general", input.version || null);
|
|
481
507
|
return { saved: true };
|
|
482
508
|
}
|
|
509
|
+
var init_repo = __esm(() => {
|
|
510
|
+
init_errors();
|
|
511
|
+
});
|
|
483
512
|
|
|
484
513
|
// src/server/v1.ts
|
|
485
514
|
function json(body, status = 200) {
|
|
@@ -592,8 +621,14 @@ async function handleV1Request(req, url) {
|
|
|
592
621
|
if (method !== "POST")
|
|
593
622
|
return error(405, `method ${method} not allowed on /v1/agents/:id/focus`);
|
|
594
623
|
const body = await readJson(req);
|
|
595
|
-
|
|
596
|
-
|
|
624
|
+
try {
|
|
625
|
+
const agent = await setAgentFocus(pg2, id, body?.project_id ?? null);
|
|
626
|
+
return agent ? json({ agent }) : error(404, "agent not found");
|
|
627
|
+
} catch (e) {
|
|
628
|
+
if (e instanceof ProjectNotFoundError)
|
|
629
|
+
return error(400, e.message);
|
|
630
|
+
throw e;
|
|
631
|
+
}
|
|
597
632
|
}
|
|
598
633
|
if (action)
|
|
599
634
|
return error(404, `unknown agent action: ${action}`);
|
|
@@ -650,6 +685,7 @@ async function handleV1Request(req, url) {
|
|
|
650
685
|
var JSON_HEADERS;
|
|
651
686
|
var init_v1 = __esm(() => {
|
|
652
687
|
init_cloud();
|
|
688
|
+
init_repo();
|
|
653
689
|
JSON_HEADERS = { "Content-Type": "application/json" };
|
|
654
690
|
});
|
|
655
691
|
|
|
@@ -1430,7 +1466,7 @@ function getErrorMap() {
|
|
|
1430
1466
|
return overrideErrorMap;
|
|
1431
1467
|
}
|
|
1432
1468
|
var overrideErrorMap;
|
|
1433
|
-
var
|
|
1469
|
+
var init_errors2 = __esm(() => {
|
|
1434
1470
|
init_en();
|
|
1435
1471
|
overrideErrorMap = en_default;
|
|
1436
1472
|
});
|
|
@@ -1532,7 +1568,7 @@ var makeIssue = (params) => {
|
|
|
1532
1568
|
};
|
|
1533
1569
|
}, EMPTY_PATH, INVALID, DIRTY = (value) => ({ status: "dirty", value }), OK = (value) => ({ status: "valid", value }), isAborted = (x) => x.status === "aborted", isDirty = (x) => x.status === "dirty", isValid = (x) => x.status === "valid", isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise;
|
|
1534
1570
|
var init_parseUtil = __esm(() => {
|
|
1535
|
-
|
|
1571
|
+
init_errors2();
|
|
1536
1572
|
init_en();
|
|
1537
1573
|
EMPTY_PATH = [];
|
|
1538
1574
|
INVALID = Object.freeze({
|
|
@@ -2100,7 +2136,7 @@ var handleResult = (ctx, result) => {
|
|
|
2100
2136
|
}) => custom((data) => data instanceof cls, params), stringType, numberType, nanType, bigIntType, booleanType, dateType, symbolType, undefinedType, nullType, anyType, unknownType, neverType, voidType, arrayType, objectType, strictObjectType, unionType, discriminatedUnionType, intersectionType, tupleType, recordType, mapType, setType, functionType, lazyType, literalType, enumType, nativeEnumType, promiseType, effectsType, optionalType, nullableType, preprocessType, pipelineType, ostring = () => stringType().optional(), onumber = () => numberType().optional(), oboolean = () => booleanType().optional(), coerce, NEVER;
|
|
2101
2137
|
var init_types = __esm(() => {
|
|
2102
2138
|
init_ZodError();
|
|
2103
|
-
|
|
2139
|
+
init_errors2();
|
|
2104
2140
|
init_errorUtil();
|
|
2105
2141
|
init_parseUtil();
|
|
2106
2142
|
init_util();
|
|
@@ -5015,7 +5051,7 @@ __export(exports_external, {
|
|
|
5015
5051
|
BRAND: () => BRAND
|
|
5016
5052
|
});
|
|
5017
5053
|
var init_external = __esm(() => {
|
|
5018
|
-
|
|
5054
|
+
init_errors2();
|
|
5019
5055
|
init_parseUtil();
|
|
5020
5056
|
init_typeAliases();
|
|
5021
5057
|
init_util();
|
|
@@ -5531,6 +5567,52 @@ var init_recordings = __esm(() => {
|
|
|
5531
5567
|
init_database();
|
|
5532
5568
|
});
|
|
5533
5569
|
|
|
5570
|
+
// src/db/projects.ts
|
|
5571
|
+
function parseProject2(row) {
|
|
5572
|
+
return {
|
|
5573
|
+
id: row["id"],
|
|
5574
|
+
name: row["name"],
|
|
5575
|
+
path: row["path"],
|
|
5576
|
+
description: row["description"] || null,
|
|
5577
|
+
created_at: row["created_at"],
|
|
5578
|
+
updated_at: row["updated_at"]
|
|
5579
|
+
};
|
|
5580
|
+
}
|
|
5581
|
+
function registerProject2(name, path, description, db) {
|
|
5582
|
+
const d = db || getDatabase();
|
|
5583
|
+
const now = new Date().toISOString();
|
|
5584
|
+
const existing = d.query("SELECT * FROM projects WHERE path = ?").get(path);
|
|
5585
|
+
if (existing) {
|
|
5586
|
+
d.query("UPDATE projects SET updated_at = ? WHERE id = ?").run(now, existing["id"]);
|
|
5587
|
+
return getProject2(existing["id"], d);
|
|
5588
|
+
}
|
|
5589
|
+
const id = crypto.randomUUID();
|
|
5590
|
+
d.query("INSERT INTO projects (id, name, path, description, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)").run(id, name, path, description || null, now, now);
|
|
5591
|
+
return getProject2(id, d);
|
|
5592
|
+
}
|
|
5593
|
+
function getProject2(idOrPath, db) {
|
|
5594
|
+
const d = db || getDatabase();
|
|
5595
|
+
let row = d.query("SELECT * FROM projects WHERE id = ?").get(idOrPath);
|
|
5596
|
+
if (!row) {
|
|
5597
|
+
row = d.query("SELECT * FROM projects WHERE path = ?").get(idOrPath);
|
|
5598
|
+
}
|
|
5599
|
+
if (!row) {
|
|
5600
|
+
row = d.query("SELECT * FROM projects WHERE name = ?").get(idOrPath);
|
|
5601
|
+
}
|
|
5602
|
+
if (!row && idOrPath) {
|
|
5603
|
+
row = d.query("SELECT * FROM projects WHERE id LIKE ? || '%'").get(idOrPath);
|
|
5604
|
+
}
|
|
5605
|
+
return row ? parseProject2(row) : null;
|
|
5606
|
+
}
|
|
5607
|
+
function listProjects2(db) {
|
|
5608
|
+
const d = db || getDatabase();
|
|
5609
|
+
const rows = d.query("SELECT * FROM projects ORDER BY updated_at DESC").all();
|
|
5610
|
+
return rows.map(parseProject2);
|
|
5611
|
+
}
|
|
5612
|
+
var init_projects = __esm(() => {
|
|
5613
|
+
init_database();
|
|
5614
|
+
});
|
|
5615
|
+
|
|
5534
5616
|
// src/db/agents.ts
|
|
5535
5617
|
function parseAgent2(row) {
|
|
5536
5618
|
return {
|
|
@@ -5584,51 +5666,20 @@ function setAgentFocus2(idOrName, projectId, db) {
|
|
|
5584
5666
|
const agent = getAgent2(idOrName, d);
|
|
5585
5667
|
if (!agent)
|
|
5586
5668
|
return null;
|
|
5587
|
-
|
|
5669
|
+
let resolvedProjectId = null;
|
|
5670
|
+
if (projectId) {
|
|
5671
|
+
const project = getProject2(projectId, d);
|
|
5672
|
+
if (!project)
|
|
5673
|
+
throw new ProjectNotFoundError(projectId);
|
|
5674
|
+
resolvedProjectId = project.id;
|
|
5675
|
+
}
|
|
5676
|
+
d.query("UPDATE agents SET active_project_id = ?, last_seen_at = ? WHERE id = ?").run(resolvedProjectId, new Date().toISOString(), agent.id);
|
|
5588
5677
|
return getAgent2(agent.id, d);
|
|
5589
5678
|
}
|
|
5590
5679
|
var init_agents = __esm(() => {
|
|
5591
5680
|
init_database();
|
|
5592
|
-
|
|
5593
|
-
|
|
5594
|
-
// src/db/projects.ts
|
|
5595
|
-
function parseProject2(row) {
|
|
5596
|
-
return {
|
|
5597
|
-
id: row["id"],
|
|
5598
|
-
name: row["name"],
|
|
5599
|
-
path: row["path"],
|
|
5600
|
-
description: row["description"] || null,
|
|
5601
|
-
created_at: row["created_at"],
|
|
5602
|
-
updated_at: row["updated_at"]
|
|
5603
|
-
};
|
|
5604
|
-
}
|
|
5605
|
-
function registerProject2(name, path, description, db) {
|
|
5606
|
-
const d = db || getDatabase();
|
|
5607
|
-
const now = new Date().toISOString();
|
|
5608
|
-
const existing = d.query("SELECT * FROM projects WHERE path = ?").get(path);
|
|
5609
|
-
if (existing) {
|
|
5610
|
-
d.query("UPDATE projects SET updated_at = ? WHERE id = ?").run(now, existing["id"]);
|
|
5611
|
-
return getProject2(existing["id"], d);
|
|
5612
|
-
}
|
|
5613
|
-
const id = crypto.randomUUID();
|
|
5614
|
-
d.query("INSERT INTO projects (id, name, path, description, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)").run(id, name, path, description || null, now, now);
|
|
5615
|
-
return getProject2(id, d);
|
|
5616
|
-
}
|
|
5617
|
-
function getProject2(idOrPath, db) {
|
|
5618
|
-
const d = db || getDatabase();
|
|
5619
|
-
let row = d.query("SELECT * FROM projects WHERE id = ?").get(idOrPath);
|
|
5620
|
-
if (!row) {
|
|
5621
|
-
row = d.query("SELECT * FROM projects WHERE path = ?").get(idOrPath);
|
|
5622
|
-
}
|
|
5623
|
-
return row ? parseProject2(row) : null;
|
|
5624
|
-
}
|
|
5625
|
-
function listProjects2(db) {
|
|
5626
|
-
const d = db || getDatabase();
|
|
5627
|
-
const rows = d.query("SELECT * FROM projects ORDER BY updated_at DESC").all();
|
|
5628
|
-
return rows.map(parseProject2);
|
|
5629
|
-
}
|
|
5630
|
-
var init_projects = __esm(() => {
|
|
5631
|
-
init_database();
|
|
5681
|
+
init_projects();
|
|
5682
|
+
init_errors();
|
|
5632
5683
|
});
|
|
5633
5684
|
|
|
5634
5685
|
// src/db/feedback.ts
|
|
@@ -6014,8 +6065,16 @@ function apiStore(client) {
|
|
|
6014
6065
|
const res = await client.transport.post(`/agents/${encodeURIComponent(idOrName)}/focus`, { project_id: projectId });
|
|
6015
6066
|
return res ? unwrap(res, "agent") : null;
|
|
6016
6067
|
} catch (error2) {
|
|
6017
|
-
if (error2 && typeof error2 === "object"
|
|
6018
|
-
|
|
6068
|
+
if (error2 && typeof error2 === "object") {
|
|
6069
|
+
const status = error2.status;
|
|
6070
|
+
if (status === 404)
|
|
6071
|
+
return null;
|
|
6072
|
+
if (status === 400) {
|
|
6073
|
+
const body = error2.body;
|
|
6074
|
+
const msg = body && typeof body === "object" && typeof body.error === "string" ? body.error : "invalid focus request";
|
|
6075
|
+
throw new Error(msg);
|
|
6076
|
+
}
|
|
6077
|
+
}
|
|
6019
6078
|
throw error2;
|
|
6020
6079
|
}
|
|
6021
6080
|
},
|
package/dist/server/repo.d.ts
CHANGED
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
* stubs — every operation executes real SQL.
|
|
13
13
|
*/
|
|
14
14
|
import type { PgAdapterAsync } from "../db/remote-storage.js";
|
|
15
|
+
import { ProjectNotFoundError } from "../db/errors.js";
|
|
15
16
|
import type { Recording, CreateRecordingInput, RecordingFilter, Agent, Project } from "../types/index.js";
|
|
17
|
+
export { ProjectNotFoundError };
|
|
16
18
|
export declare function createRecording(pg: PgAdapterAsync, input: CreateRecordingInput): Promise<Recording>;
|
|
17
19
|
export declare function getRecording(pg: PgAdapterAsync, id: string): Promise<Recording | null>;
|
|
18
20
|
export declare function listRecordings(pg: PgAdapterAsync, filter?: RecordingFilter): Promise<Recording[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../src/server/repo.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EACV,SAAS,EACT,oBAAoB,EACpB,eAAe,EACf,KAAK,EACL,OAAO,EACR,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../src/server/repo.ts"],"names":[],"mappings":"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"}
|
package/dist/server/v1.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"v1.d.ts","sourceRoot":"","sources":["../../src/server/v1.ts"],"names":[],"mappings":"AAkCA;;;GAGG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"v1.d.ts","sourceRoot":"","sources":["../../src/server/v1.ts"],"names":[],"mappings":"AAkCA;;;GAGG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CA6KtF"}
|
package/dist/storage.js
CHANGED
|
@@ -495,6 +495,59 @@ function getRecordingStats(db) {
|
|
|
495
495
|
};
|
|
496
496
|
}
|
|
497
497
|
|
|
498
|
+
// src/db/projects.ts
|
|
499
|
+
function parseProject(row) {
|
|
500
|
+
return {
|
|
501
|
+
id: row["id"],
|
|
502
|
+
name: row["name"],
|
|
503
|
+
path: row["path"],
|
|
504
|
+
description: row["description"] || null,
|
|
505
|
+
created_at: row["created_at"],
|
|
506
|
+
updated_at: row["updated_at"]
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
function registerProject(name, path, description, db) {
|
|
510
|
+
const d = db || getDatabase();
|
|
511
|
+
const now = new Date().toISOString();
|
|
512
|
+
const existing = d.query("SELECT * FROM projects WHERE path = ?").get(path);
|
|
513
|
+
if (existing) {
|
|
514
|
+
d.query("UPDATE projects SET updated_at = ? WHERE id = ?").run(now, existing["id"]);
|
|
515
|
+
return getProject(existing["id"], d);
|
|
516
|
+
}
|
|
517
|
+
const id = crypto.randomUUID();
|
|
518
|
+
d.query("INSERT INTO projects (id, name, path, description, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)").run(id, name, path, description || null, now, now);
|
|
519
|
+
return getProject(id, d);
|
|
520
|
+
}
|
|
521
|
+
function getProject(idOrPath, db) {
|
|
522
|
+
const d = db || getDatabase();
|
|
523
|
+
let row = d.query("SELECT * FROM projects WHERE id = ?").get(idOrPath);
|
|
524
|
+
if (!row) {
|
|
525
|
+
row = d.query("SELECT * FROM projects WHERE path = ?").get(idOrPath);
|
|
526
|
+
}
|
|
527
|
+
if (!row) {
|
|
528
|
+
row = d.query("SELECT * FROM projects WHERE name = ?").get(idOrPath);
|
|
529
|
+
}
|
|
530
|
+
if (!row && idOrPath) {
|
|
531
|
+
row = d.query("SELECT * FROM projects WHERE id LIKE ? || '%'").get(idOrPath);
|
|
532
|
+
}
|
|
533
|
+
return row ? parseProject(row) : null;
|
|
534
|
+
}
|
|
535
|
+
function listProjects(db) {
|
|
536
|
+
const d = db || getDatabase();
|
|
537
|
+
const rows = d.query("SELECT * FROM projects ORDER BY updated_at DESC").all();
|
|
538
|
+
return rows.map(parseProject);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// src/db/errors.ts
|
|
542
|
+
class ProjectNotFoundError extends Error {
|
|
543
|
+
ref;
|
|
544
|
+
constructor(ref) {
|
|
545
|
+
super(`project not found: ${ref}`);
|
|
546
|
+
this.name = "ProjectNotFoundError";
|
|
547
|
+
this.ref = ref;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
|
|
498
551
|
// src/db/agents.ts
|
|
499
552
|
function parseAgent(row) {
|
|
500
553
|
return {
|
|
@@ -548,49 +601,19 @@ function setAgentFocus(idOrName, projectId, db) {
|
|
|
548
601
|
const agent = getAgent(idOrName, d);
|
|
549
602
|
if (!agent)
|
|
550
603
|
return null;
|
|
551
|
-
|
|
604
|
+
let resolvedProjectId = null;
|
|
605
|
+
if (projectId) {
|
|
606
|
+
const project = getProject(projectId, d);
|
|
607
|
+
if (!project)
|
|
608
|
+
throw new ProjectNotFoundError(projectId);
|
|
609
|
+
resolvedProjectId = project.id;
|
|
610
|
+
}
|
|
611
|
+
d.query("UPDATE agents SET active_project_id = ?, last_seen_at = ? WHERE id = ?").run(resolvedProjectId, new Date().toISOString(), agent.id);
|
|
552
612
|
return getAgent(agent.id, d);
|
|
553
613
|
}
|
|
554
614
|
|
|
555
|
-
// src/db/projects.ts
|
|
556
|
-
function parseProject(row) {
|
|
557
|
-
return {
|
|
558
|
-
id: row["id"],
|
|
559
|
-
name: row["name"],
|
|
560
|
-
path: row["path"],
|
|
561
|
-
description: row["description"] || null,
|
|
562
|
-
created_at: row["created_at"],
|
|
563
|
-
updated_at: row["updated_at"]
|
|
564
|
-
};
|
|
565
|
-
}
|
|
566
|
-
function registerProject(name, path, description, db) {
|
|
567
|
-
const d = db || getDatabase();
|
|
568
|
-
const now = new Date().toISOString();
|
|
569
|
-
const existing = d.query("SELECT * FROM projects WHERE path = ?").get(path);
|
|
570
|
-
if (existing) {
|
|
571
|
-
d.query("UPDATE projects SET updated_at = ? WHERE id = ?").run(now, existing["id"]);
|
|
572
|
-
return getProject(existing["id"], d);
|
|
573
|
-
}
|
|
574
|
-
const id = crypto.randomUUID();
|
|
575
|
-
d.query("INSERT INTO projects (id, name, path, description, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)").run(id, name, path, description || null, now, now);
|
|
576
|
-
return getProject(id, d);
|
|
577
|
-
}
|
|
578
|
-
function getProject(idOrPath, db) {
|
|
579
|
-
const d = db || getDatabase();
|
|
580
|
-
let row = d.query("SELECT * FROM projects WHERE id = ?").get(idOrPath);
|
|
581
|
-
if (!row) {
|
|
582
|
-
row = d.query("SELECT * FROM projects WHERE path = ?").get(idOrPath);
|
|
583
|
-
}
|
|
584
|
-
return row ? parseProject(row) : null;
|
|
585
|
-
}
|
|
586
|
-
function listProjects(db) {
|
|
587
|
-
const d = db || getDatabase();
|
|
588
|
-
const rows = d.query("SELECT * FROM projects ORDER BY updated_at DESC").all();
|
|
589
|
-
return rows.map(parseProject);
|
|
590
|
-
}
|
|
591
|
-
|
|
592
615
|
// src/version.ts
|
|
593
|
-
var VERSION = "0.2.
|
|
616
|
+
var VERSION = "0.2.6";
|
|
594
617
|
|
|
595
618
|
// src/db/feedback.ts
|
|
596
619
|
function saveFeedback(input) {
|
|
@@ -1021,8 +1044,16 @@ function apiStore(client) {
|
|
|
1021
1044
|
const res = await client.transport.post(`/agents/${encodeURIComponent(idOrName)}/focus`, { project_id: projectId });
|
|
1022
1045
|
return res ? unwrap(res, "agent") : null;
|
|
1023
1046
|
} catch (error) {
|
|
1024
|
-
if (error && typeof error === "object"
|
|
1025
|
-
|
|
1047
|
+
if (error && typeof error === "object") {
|
|
1048
|
+
const status = error.status;
|
|
1049
|
+
if (status === 404)
|
|
1050
|
+
return null;
|
|
1051
|
+
if (status === 400) {
|
|
1052
|
+
const body = error.body;
|
|
1053
|
+
const msg = body && typeof body === "object" && typeof body.error === "string" ? body.error : "invalid focus request";
|
|
1054
|
+
throw new Error(msg);
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1026
1057
|
throw error;
|
|
1027
1058
|
}
|
|
1028
1059
|
},
|
package/dist/store.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EACV,SAAS,EACT,oBAAoB,EACpB,eAAe,EACf,KAAK,EACL,OAAO,EACR,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EAAqC,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGzF,eAAO,MAAM,GAAG,eAAe,CAAC;AAEhC,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAGhC,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IACjE,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IACpD,cAAc,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAC/D,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAChF,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,iBAAiB,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;IAG7C,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACjF,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAClD,UAAU,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IAC/B,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IACxD,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAGjF,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACpF,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACtD,YAAY,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAGnC,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnD;
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EACV,SAAS,EACT,oBAAoB,EACpB,eAAe,EACf,KAAK,EACL,OAAO,EACR,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EAAqC,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGzF,eAAO,MAAM,GAAG,eAAe,CAAC;AAEhC,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAGhC,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IACjE,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IACpD,cAAc,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAC/D,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAChF,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,iBAAiB,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;IAG7C,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACjF,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAClD,UAAU,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IAC/B,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IACxD,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAGjF,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACpF,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACtD,YAAY,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAGnC,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnD;AAoLD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,GAAG,GAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,KAAK,CAMzG;AAED,2CAA2C;AAC3C,wBAAgB,YAAY,IAAI,IAAI,CAEnC"}
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.2.
|
|
1
|
+
export declare const VERSION = "0.2.6";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/package.json
CHANGED