@proletariat/cli 0.3.87 → 0.3.89
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/commands/db/repair.d.ts +14 -0
- package/dist/commands/db/repair.js +186 -0
- package/dist/commands/db/repair.js.map +1 -0
- package/dist/commands/init.d.ts +6 -1
- package/dist/commands/init.js +44 -89
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/new.d.ts +30 -2
- package/dist/commands/new.js +141 -9
- package/dist/commands/new.js.map +1 -1
- package/dist/commands/session/list.js +42 -0
- package/dist/commands/session/list.js.map +1 -1
- package/dist/commands/session/poke.d.ts +6 -0
- package/dist/commands/session/poke.js +40 -0
- package/dist/commands/session/poke.js.map +1 -1
- package/dist/commands/work/start.d.ts +1 -0
- package/dist/commands/work/start.js +20 -1
- package/dist/commands/work/start.js.map +1 -1
- package/dist/hooks/init.js +3 -6
- package/dist/hooks/init.js.map +1 -1
- package/dist/lib/asana/config.d.ts +1 -1
- package/dist/lib/asana/config.js +18 -30
- package/dist/lib/asana/config.js.map +1 -1
- package/dist/lib/asana/mapper.d.ts +4 -3
- package/dist/lib/asana/mapper.js +17 -10
- package/dist/lib/asana/mapper.js.map +1 -1
- package/dist/lib/dashboard/data.js +2 -2
- package/dist/lib/dashboard/data.js.map +1 -1
- package/dist/lib/database/agents.d.ts +73 -0
- package/dist/lib/database/agents.js +341 -0
- package/dist/lib/database/agents.js.map +1 -0
- package/dist/lib/database/db-safety.d.ts +59 -0
- package/dist/lib/database/db-safety.js +295 -0
- package/dist/lib/database/db-safety.js.map +1 -0
- package/dist/lib/database/driver.d.ts +115 -0
- package/dist/lib/database/driver.js +110 -0
- package/dist/lib/database/driver.js.map +1 -0
- package/dist/lib/database/index.d.ts +26 -287
- package/dist/lib/database/index.js +37 -1067
- package/dist/lib/database/index.js.map +1 -1
- package/dist/lib/database/media.d.ts +53 -0
- package/dist/lib/database/media.js +118 -0
- package/dist/lib/database/media.js.map +1 -0
- package/dist/lib/database/migrations/0012_add_action_network_allowlist.d.ts +9 -0
- package/dist/lib/database/migrations/0012_add_action_network_allowlist.js +22 -0
- package/dist/lib/database/migrations/0012_add_action_network_allowlist.js.map +1 -0
- package/dist/lib/database/migrations/index.js +2 -0
- package/dist/lib/database/migrations/index.js.map +1 -1
- package/dist/lib/database/pmo-bootstrap.d.ts +30 -0
- package/dist/lib/database/pmo-bootstrap.js +105 -0
- package/dist/lib/database/pmo-bootstrap.js.map +1 -0
- package/dist/lib/database/repositories.d.ts +26 -0
- package/dist/lib/database/repositories.js +56 -0
- package/dist/lib/database/repositories.js.map +1 -0
- package/dist/lib/database/settings-store.d.ts +60 -0
- package/dist/lib/database/settings-store.js +87 -0
- package/dist/lib/database/settings-store.js.map +1 -0
- package/dist/lib/database/themes.d.ts +59 -0
- package/dist/lib/database/themes.js +212 -0
- package/dist/lib/database/themes.js.map +1 -0
- package/dist/lib/database/workspace.d.ts +51 -0
- package/dist/lib/database/workspace.js +194 -0
- package/dist/lib/database/workspace.js.map +1 -0
- package/dist/lib/database/worktrees.d.ts +33 -0
- package/dist/lib/database/worktrees.js +60 -0
- package/dist/lib/database/worktrees.js.map +1 -0
- package/dist/lib/execution/config.d.ts +14 -1
- package/dist/lib/execution/config.js +67 -17
- package/dist/lib/execution/config.js.map +1 -1
- package/dist/lib/execution/devcontainer.d.ts +2 -0
- package/dist/lib/execution/devcontainer.js +6 -1
- package/dist/lib/execution/devcontainer.js.map +1 -1
- package/dist/lib/execution/runners/docker-management.d.ts +6 -0
- package/dist/lib/execution/runners/docker-management.js +28 -12
- package/dist/lib/execution/runners/docker-management.js.map +1 -1
- package/dist/lib/execution/runners/sandbox.js +2 -1
- package/dist/lib/execution/runners/sandbox.js.map +1 -1
- package/dist/lib/execution/spawner.d.ts +3 -1
- package/dist/lib/execution/spawner.js +1 -0
- package/dist/lib/execution/spawner.js.map +1 -1
- package/dist/lib/execution/storage.d.ts +47 -12
- package/dist/lib/execution/storage.js +69 -47
- package/dist/lib/execution/storage.js.map +1 -1
- package/dist/lib/execution/types.d.ts +1 -0
- package/dist/lib/execution/types.js.map +1 -1
- package/dist/lib/external-issues/mapping-store.d.ts +4 -3
- package/dist/lib/external-issues/mapping-store.js +21 -13
- package/dist/lib/external-issues/mapping-store.js.map +1 -1
- package/dist/lib/external-issues/outbound-sync.d.ts +1 -1
- package/dist/lib/jira/config.d.ts +1 -6
- package/dist/lib/jira/config.js +16 -33
- package/dist/lib/jira/config.js.map +1 -1
- package/dist/lib/linear/config.d.ts +1 -1
- package/dist/lib/linear/config.js +16 -38
- package/dist/lib/linear/config.js.map +1 -1
- package/dist/lib/linear/mapper.d.ts +4 -3
- package/dist/lib/linear/mapper.js +20 -13
- package/dist/lib/linear/mapper.js.map +1 -1
- package/dist/lib/monday/config.d.ts +1 -1
- package/dist/lib/monday/config.js +16 -32
- package/dist/lib/monday/config.js.map +1 -1
- package/dist/lib/monday/mapper.d.ts +4 -3
- package/dist/lib/monday/mapper.js +19 -12
- package/dist/lib/monday/mapper.js.map +1 -1
- package/dist/lib/onboarding/wizard.d.ts +2 -2
- package/dist/lib/onboarding/wizard.js +32 -24
- package/dist/lib/onboarding/wizard.js.map +1 -1
- package/dist/lib/pmo/diet.d.ts +1 -1
- package/dist/lib/pmo/find-pmo.js +10 -10
- package/dist/lib/pmo/find-pmo.js.map +1 -1
- package/dist/lib/pmo/schema.d.ts +1 -1
- package/dist/lib/pmo/schema.js +1 -0
- package/dist/lib/pmo/schema.js.map +1 -1
- package/dist/lib/pmo/storage/actions.js +9 -3
- package/dist/lib/pmo/storage/actions.js.map +1 -1
- package/dist/lib/pmo/storage/index.d.ts +8 -0
- package/dist/lib/pmo/storage/index.js +13 -1
- package/dist/lib/pmo/storage/index.js.map +1 -1
- package/dist/lib/pmo/storage/types.d.ts +5 -1
- package/dist/lib/pmo/types.d.ts +1 -0
- package/dist/lib/pmo/types.js.map +1 -1
- package/dist/lib/registry/index.d.ts +2 -2
- package/dist/lib/registry/index.js +5 -6
- package/dist/lib/registry/index.js.map +1 -1
- package/dist/lib/session-store.js +2 -2
- package/dist/lib/session-store.js.map +1 -1
- package/dist/lib/shortcut/config.d.ts +1 -7
- package/dist/lib/shortcut/config.js +13 -32
- package/dist/lib/shortcut/config.js.map +1 -1
- package/dist/lib/trello/config.d.ts +1 -26
- package/dist/lib/trello/config.js +23 -64
- package/dist/lib/trello/config.js.map +1 -1
- package/dist/lib/trello/mapper.d.ts +4 -3
- package/dist/lib/trello/mapper.js +17 -10
- package/dist/lib/trello/mapper.js.map +1 -1
- package/dist/lib/work-lifecycle/action-chaining.js +4 -0
- package/dist/lib/work-lifecycle/action-chaining.js.map +1 -1
- package/dist/lib/work-lifecycle/post-execution.d.ts +1 -1
- package/dist/lib/work-source/config.d.ts +1 -1
- package/dist/lib/work-source/config.js +14 -24
- package/dist/lib/work-source/config.js.map +1 -1
- package/dist/lib/work-source/provider-sources.d.ts +1 -1
- package/dist/lib/work-source/provider-sources.js +8 -20
- package/dist/lib/work-source/provider-sources.js.map +1 -1
- package/oclif.manifest.json +1111 -1001
- package/package.json +1 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import Database from 'better-sqlite3';
|
|
1
|
+
import type Database from 'better-sqlite3';
|
|
2
2
|
import type { AsanaTaskMap } from './types.js';
|
|
3
|
+
import { type DatabaseDriver } from '../database/driver.js';
|
|
3
4
|
export declare class AsanaMapper {
|
|
4
|
-
private
|
|
5
|
-
constructor(
|
|
5
|
+
private driver;
|
|
6
|
+
constructor(dbOrDriver: DatabaseDriver | Database.Database);
|
|
6
7
|
private ensureTable;
|
|
7
8
|
createOrUpdateMapping(pmoTicketId: string, asanaTaskGid: string, asanaProjectGid?: string): void;
|
|
8
9
|
getByTicketId(ticketId: string): AsanaTaskMap | null;
|
package/dist/lib/asana/mapper.js
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import { PMO_TABLES } from '../pmo/schema.js';
|
|
2
|
+
import { wrapDatabase } from '../database/driver.js';
|
|
3
|
+
function toDriver(dbOrDriver) {
|
|
4
|
+
if ('prepare' in dbOrDriver && 'pragma' in dbOrDriver && !('raw' in dbOrDriver)) {
|
|
5
|
+
return wrapDatabase(dbOrDriver);
|
|
6
|
+
}
|
|
7
|
+
return dbOrDriver;
|
|
8
|
+
}
|
|
2
9
|
export class AsanaMapper {
|
|
3
|
-
|
|
4
|
-
constructor(
|
|
5
|
-
this.
|
|
10
|
+
driver;
|
|
11
|
+
constructor(dbOrDriver) {
|
|
12
|
+
this.driver = toDriver(dbOrDriver);
|
|
6
13
|
this.ensureTable();
|
|
7
14
|
}
|
|
8
15
|
ensureTable() {
|
|
9
|
-
this.
|
|
16
|
+
this.driver.exec(`
|
|
10
17
|
CREATE TABLE IF NOT EXISTS ${PMO_TABLES.asana_task_map} (
|
|
11
18
|
pmo_ticket_id TEXT NOT NULL REFERENCES ${PMO_TABLES.tickets}(id) ON DELETE CASCADE,
|
|
12
19
|
asana_task_gid TEXT NOT NULL,
|
|
@@ -17,13 +24,13 @@ export class AsanaMapper {
|
|
|
17
24
|
UNIQUE (asana_task_gid)
|
|
18
25
|
)
|
|
19
26
|
`);
|
|
20
|
-
this.
|
|
27
|
+
this.driver.exec(`
|
|
21
28
|
CREATE INDEX IF NOT EXISTS idx_pmo_asana_task_map_task_gid
|
|
22
29
|
ON ${PMO_TABLES.asana_task_map}(asana_task_gid)
|
|
23
30
|
`);
|
|
24
31
|
}
|
|
25
32
|
createOrUpdateMapping(pmoTicketId, asanaTaskGid, asanaProjectGid) {
|
|
26
|
-
this.
|
|
33
|
+
this.driver.prepare(`
|
|
27
34
|
INSERT INTO ${PMO_TABLES.asana_task_map}
|
|
28
35
|
(pmo_ticket_id, asana_task_gid, asana_project_gid, last_synced_at, created_at)
|
|
29
36
|
VALUES (?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
|
|
@@ -34,25 +41,25 @@ export class AsanaMapper {
|
|
|
34
41
|
`).run(pmoTicketId, asanaTaskGid, asanaProjectGid ?? null);
|
|
35
42
|
}
|
|
36
43
|
getByTicketId(ticketId) {
|
|
37
|
-
const row = this.
|
|
44
|
+
const row = this.driver.prepare(`
|
|
38
45
|
SELECT * FROM ${PMO_TABLES.asana_task_map} WHERE pmo_ticket_id = ?
|
|
39
46
|
`).get(ticketId);
|
|
40
47
|
return row ? this.rowToMap(row) : null;
|
|
41
48
|
}
|
|
42
49
|
getByTaskGid(asanaTaskGid) {
|
|
43
|
-
const row = this.
|
|
50
|
+
const row = this.driver.prepare(`
|
|
44
51
|
SELECT * FROM ${PMO_TABLES.asana_task_map} WHERE asana_task_gid = ?
|
|
45
52
|
`).get(asanaTaskGid);
|
|
46
53
|
return row ? this.rowToMap(row) : null;
|
|
47
54
|
}
|
|
48
55
|
listMappings() {
|
|
49
|
-
const rows = this.
|
|
56
|
+
const rows = this.driver.prepare(`
|
|
50
57
|
SELECT * FROM ${PMO_TABLES.asana_task_map} ORDER BY created_at DESC
|
|
51
58
|
`).all();
|
|
52
59
|
return rows.map((row) => this.rowToMap(row));
|
|
53
60
|
}
|
|
54
61
|
updateSyncTimestamp(ticketId) {
|
|
55
|
-
this.
|
|
62
|
+
this.driver.prepare(`
|
|
56
63
|
UPDATE ${PMO_TABLES.asana_task_map}
|
|
57
64
|
SET last_synced_at = CURRENT_TIMESTAMP
|
|
58
65
|
WHERE pmo_ticket_id = ?
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mapper.js","sourceRoot":"","sources":["../../../src/lib/asana/mapper.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"mapper.js","sourceRoot":"","sources":["../../../src/lib/asana/mapper.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,OAAO,EAAuB,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAEzE,SAAS,QAAQ,CAAC,UAA8C;IAC9D,IAAI,SAAS,IAAI,UAAU,IAAI,QAAQ,IAAI,UAAU,IAAI,CAAC,CAAC,KAAK,IAAI,UAAU,CAAC,EAAE,CAAC;QAChF,OAAO,YAAY,CAAC,UAA+B,CAAC,CAAA;IACtD,CAAC;IACD,OAAO,UAA4B,CAAA;AACrC,CAAC;AAED,MAAM,OAAO,WAAW;IACd,MAAM,CAAgB;IAE9B,YAAY,UAA8C;QACxD,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAA;QAClC,IAAI,CAAC,WAAW,EAAE,CAAA;IACpB,CAAC;IAEO,WAAW;QACjB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;mCACc,UAAU,CAAC,cAAc;iDACX,UAAU,CAAC,OAAO;;;;;;;;KAQ9D,CAAC,CAAA;QAEF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;;aAER,UAAU,CAAC,cAAc;KACjC,CAAC,CAAA;IACJ,CAAC;IAED,qBAAqB,CAAC,WAAmB,EAAE,YAAoB,EAAE,eAAwB;QACvF,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;oBACJ,UAAU,CAAC,cAAc;;;;;;;KAOxC,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,YAAY,EAAE,eAAe,IAAI,IAAI,CAAC,CAAA;IAC5D,CAAC;IAED,aAAa,CAAC,QAAgB;QAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAA0B;sBACvC,UAAU,CAAC,cAAc;KAC1C,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAEhB,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACxC,CAAC;IAED,YAAY,CAAC,YAAoB;QAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAA0B;sBACvC,UAAU,CAAC,cAAc;KAC1C,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;QAEpB,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACxC,CAAC;IAED,YAAY;QACV,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAA0B;sBACxC,UAAU,CAAC,cAAc;KAC1C,CAAC,CAAC,GAAG,EAAE,CAAA;QAER,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAA;IAC9C,CAAC;IAED,mBAAmB,CAAC,QAAgB;QAClC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;eACT,UAAU,CAAC,cAAc;;;KAGnC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAClB,CAAC;IAEO,QAAQ,CAAC,GAA4B;QAC3C,OAAO;YACL,WAAW,EAAE,GAAG,CAAC,aAAuB;YACxC,YAAY,EAAE,GAAG,CAAC,cAAwB;YAC1C,eAAe,EAAG,GAAG,CAAC,iBAAmC,IAAI,SAAS;YACtE,YAAY,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,cAAwB,CAAC,CAAC,CAAC,CAAC,SAAS;YACrF,SAAS,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,UAAoB,CAAC;SAC9C,CAAA;IACH,CAAC;CACF"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import * as path from 'node:path';
|
|
8
8
|
import { execSync } from 'node:child_process';
|
|
9
|
-
import
|
|
9
|
+
import { openDriver } from '../database/driver.js';
|
|
10
10
|
import { getWorkspaceInfo, getAllAgentsStatus, getAgentTmuxSessions } from '../agents/commands.js';
|
|
11
11
|
import { ExecutionStorage } from '../execution/index.js';
|
|
12
12
|
import { getHostTmuxSessionNames, parseSessionName, getContainerTmuxSessionMap, flattenContainerSessions, findContainerSessionsByPrefix, findSessionForExecution, } from '../execution/session-utils.js';
|
|
@@ -75,7 +75,7 @@ export function gatherSessionData() {
|
|
|
75
75
|
try {
|
|
76
76
|
const workspaceInfo = getWorkspaceInfo();
|
|
77
77
|
const dbPath = path.join(workspaceInfo.path, '.proletariat', 'workspace.db');
|
|
78
|
-
db =
|
|
78
|
+
db = openDriver(dbPath, { foreignKeys: false });
|
|
79
79
|
executionStorage = new ExecutionStorage(db);
|
|
80
80
|
}
|
|
81
81
|
catch {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data.js","sourceRoot":"","sources":["../../../src/lib/dashboard/data.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,
|
|
1
|
+
{"version":3,"file":"data.js","sourceRoot":"","sources":["../../../src/lib/dashboard/data.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,EAAuB,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAEvE,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAElG,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,0BAA0B,EAC1B,wBAAwB,EACxB,6BAA6B,EAC7B,uBAAuB,GACxB,MAAM,+BAA+B,CAAA;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAgE5C,gFAAgF;AAChF,sCAAsC;AACtC,gFAAgF;AAEhF,IAAI,WAAW,GAAqD,IAAI,CAAA;AACxE,MAAM,eAAe,GAAG,MAAM,CAAA;AAE9B,gFAAgF;AAChF,2BAA2B;AAC3B,gFAAgF;AAEhF,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAmB,EACnB,SAAiB;IAEjB,IAAI,CAAC;QACH,MAAM,KAAK,GAAU,MAAM,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;QACtD,MAAM,OAAO,GAAsB,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAW,EAAE,EAAE,CAAC,CAAC;YACrE,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,OAAO,EAAE,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC;gBAC/C,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,UAAU,EAAE,CAAC,CAAC,UAAU;gBACxB,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE;aACvB,CAAC,CAAC;SACJ,CAAC,CAAC,CAAA;QACH,OAAO,EAAE,OAAO,EAAE,CAAA;IACpB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CAAA;IACxB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC;QACH,MAAM,aAAa,GAAkB,gBAAgB,EAAE,CAAA;QACvD,MAAM,QAAQ,GAAkB,kBAAkB,CAAC,aAAa,CAAC,CAAA;QACjE,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACxB,IAAI,iBAAiB,GAAG,KAAK,CAAA;YAC7B,IAAI,CAAC;gBACH,iBAAiB,GAAG,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAA;YAC7D,CAAC;YAAC,MAAM,CAAC;gBACP,qBAAqB;YACvB,CAAC;YACD,OAAO;gBACL,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,eAAe,EAAE,CAAC,CAAC,eAAe;gBAClC,gBAAgB,EAAE,CAAC,CAAC,gBAAgB;gBACpC,iBAAiB;aAClB,CAAA;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,IAAI,gBAAgB,GAA4B,IAAI,CAAA;IACpD,IAAI,EAAE,GAA0B,IAAI,CAAA;IACpC,MAAM,QAAQ,GAAuB,EAAE,CAAA;IAEvC,IAAI,CAAC;QACH,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAA;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,cAAc,EAAE,cAAc,CAAC,CAAA;QAC5E,EAAE,GAAG,UAAU,CAAC,MAAM,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAA;QAC/C,gBAAgB,GAAG,IAAI,gBAAgB,CAAC,EAAE,CAAC,CAAA;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,wDAAwD;IAC1D,CAAC;IAED,IAAI,CAAC;QACH,MAAM,iBAAiB,GAAG,gBAAgB,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,IAAI,EAAE,CAAA;QACvF,MAAM,kBAAkB,GAAG,gBAAgB,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,IAAI,EAAE,CAAA;QACzF,MAAM,gBAAgB,GAAG,CAAC,GAAG,iBAAiB,EAAE,GAAG,kBAAkB,CAAC,CAAA;QAEtE,gBAAgB,EAAE,sBAAsB,EAAE,CAAA;QAE1C,MAAM,gBAAgB,GAAG,uBAAuB,EAAE,CAAA;QAClD,MAAM,qBAAqB,GAAG,0BAA0B,EAAE,CAAA;QAC1D,MAAM,oBAAoB,GAAG,wBAAwB,CAAC,qBAAqB,CAAC,CAAA;QAE5E,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAU,CAAA;QAC7C,MAAM,wBAAwB,GAAG,IAAI,GAAG,EAAU,CAAA;QAElD,KAAK,MAAM,IAAI,IAAI,gBAAgB,EAAE,CAAC;YACpC,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,KAAK,cAAc,CAAA;YACvD,IAAI,MAAM,GAAG,KAAK,CAAA;YAClB,IAAI,WAA+B,CAAA;YACnC,IAAI,eAAe,GAAG,IAAI,CAAC,SAAS,CAAA;YAEpC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;gBACpB,IAAI,WAAW,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;oBACpC,MAAM,iBAAiB,GAAG,6BAA6B,CAAC,qBAAqB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAA;oBAChG,MAAM,KAAK,GAAG,uBAAuB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAA;oBACvF,IAAI,KAAK,EAAE,CAAC;wBAAC,eAAe,GAAG,KAAK,CAAC;wBAAC,MAAM,GAAG,IAAI,CAAC;wBAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAA;oBAAC,CAAC;gBACvF,CAAC;qBAAM,CAAC;oBACN,MAAM,KAAK,GAAG,uBAAuB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAA;oBACtF,IAAI,KAAK,EAAE,CAAC;wBAAC,eAAe,GAAG,KAAK,CAAC;wBAAC,MAAM,GAAG,IAAI,CAAA;oBAAC,CAAC;gBACvD,CAAC;gBACD,IAAI,CAAC,eAAe;oBAAE,SAAQ;YAChC,CAAC;iBAAM,CAAC;gBACN,IAAI,WAAW,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;oBACpC,MAAM,iBAAiB,GAAG,6BAA6B,CAAC,qBAAqB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAA;oBAChG,MAAM,GAAG,iBAAiB,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;oBACnD,WAAW,GAAG,IAAI,CAAC,WAAW,CAAA;gBAChC,CAAC;qBAAM,CAAC;oBACN,MAAM,GAAG,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;gBACpD,CAAC;YACH,CAAC;YAED,IAAI,MAAM,IAAI,eAAe,EAAE,CAAC;gBAC9B,IAAI,WAAW,IAAI,WAAW,EAAE,CAAC;oBAC/B,wBAAwB,CAAC,GAAG,CAAC,GAAG,WAAW,IAAI,eAAe,EAAE,CAAC,CAAA;gBACnE,CAAC;qBAAM,CAAC;oBACN,mBAAmB,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;gBAC1C,CAAC;YACH,CAAC;YAED,IAAI,eAAe,IAAI,MAAM,EAAE,CAAC;gBAC9B,QAAQ,CAAC,IAAI,CAAC;oBACZ,SAAS,EAAE,eAAe;oBAC1B,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,SAAS,EAAE,IAAI,CAAC,SAAS;oBACzB,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM;oBAC/C,MAAM,EAAE,IAAI;iBACb,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QAED,2BAA2B;QAC3B,KAAK,MAAM,WAAW,IAAI,gBAAgB,EAAE,CAAC;YAC3C,IAAI,mBAAmB,CAAC,GAAG,CAAC,WAAW,CAAC;gBAAE,SAAQ;YAClD,MAAM,MAAM,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAA;YAC5C,IAAI,MAAM,EAAE,CAAC;gBACX,QAAQ,CAAC,IAAI,CAAC;oBACZ,SAAS,EAAE,WAAW;oBACtB,QAAQ,EAAE,MAAM,CAAC,QAAQ;oBACzB,SAAS,EAAE,MAAM,CAAC,SAAS;oBAC3B,MAAM,EAAE,QAAQ;oBAChB,WAAW,EAAE,MAAM;oBACnB,MAAM,EAAE,YAAY;iBACrB,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QAED,KAAK,MAAM,EAAE,WAAW,EAAE,IAAI,oBAAoB,EAAE,CAAC;YACnD,MAAM,GAAG,GAAG,GAAG,WAAW,EAAE,CAAA;YAC5B,sCAAsC;YACtC,IAAI,OAAO,GAAG,KAAK,CAAA;YACnB,KAAK,MAAM,CAAC,IAAI,wBAAwB,EAAE,CAAC;gBACzC,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,WAAW,EAAE,CAAC,EAAE,CAAC;oBAAC,OAAO,GAAG,IAAI,CAAC;oBAAC,MAAK;gBAAC,CAAC;YAC9D,CAAC;YACD,IAAI,OAAO;gBAAE,SAAQ;YACrB,MAAM,MAAM,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAA;YAC5C,IAAI,MAAM,EAAE,CAAC;gBACX,QAAQ,CAAC,IAAI,CAAC;oBACZ,SAAS,EAAE,WAAW;oBACtB,QAAQ,EAAE,MAAM,CAAC,QAAQ;oBACzB,SAAS,EAAE,MAAM,CAAC,SAAS;oBAC3B,MAAM,EAAE,QAAQ;oBAChB,WAAW,EAAE,WAAW;oBACxB,MAAM,EAAE,YAAY;iBACrB,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;IACH,CAAC;YAAS,CAAC;QACT,EAAE,EAAE,KAAK,EAAE,CAAA;IACb,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IACtB,IAAI,WAAW,IAAI,CAAC,GAAG,GAAG,WAAW,CAAC,SAAS,CAAC,GAAG,eAAe,EAAE,CAAC;QACnE,OAAO,WAAW,CAAC,GAAG,CAAA;IACxB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAa,WAAW,EAAE,CAAA;QAEvC,uBAAuB;QACvB,IAAI,KAAK,GAAwB,IAAI,GAAG,EAAE,CAAA;QAC1C,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,QAAQ,CACvB,4CAA4C,EAC5C,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CACxE,CAAA;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAGhC,CAAA;YACF,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;gBACxB,IAAI,CAAC,EAAE,CAAC,iBAAiB,IAAI,EAAE,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC/D,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;oBAC/B,SAAQ;gBACV,CAAC;gBACD,MAAM,UAAU,GAAG,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAC1C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,SAAS,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,CAC3D,CAAA;gBACD,MAAM,UAAU,GAAG,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAC3C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,SAAS,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,CAC3D,CAAA;gBACD,MAAM,UAAU,GAAG,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAC1C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,UAAU,KAAK,EAAE,CACpD,CAAA;gBACD,IAAI,UAAU;oBAAE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;qBAC1C,IAAI,UAAU;oBAAE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;qBAC/C,IAAI,UAAU;oBAAE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;;oBAC/C,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;YACtC,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,wBAAwB;QAC1B,CAAC;QAED,MAAM,GAAG,GAAkB,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YAC9C,MAAM,EAAE,EAAE,CAAC,MAAM;YACjB,GAAG,EAAE,EAAE,CAAC,GAAG;YACX,KAAK,EAAE,EAAE,CAAC,KAAK;YACf,UAAU,EAAE,EAAE,CAAC,UAAU;YACzB,OAAO,EAAE,EAAE,CAAC,OAAO;YACnB,QAAQ,EAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAA6B,IAAI,SAAS;SACzE,CAAC,CAAC,CAAA;QAEH,WAAW,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,CAAA;QACrC,OAAO,GAAG,CAAA;IACZ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,WAAW,EAAE,GAAG,IAAI,EAAE,CAAA;IAC/B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,OAAmB,EACnB,SAAiB,EACjB,WAAmB;IAEnB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACvD,eAAe,CAAC,OAAO,EAAE,SAAS,CAAC;QACnC,OAAO,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;QAClC,OAAO,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC;QACpC,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;KAChC,CAAC,CAAA;IAEF,OAAO;QACL,SAAS;QACT,WAAW;QACX,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,KAAK;QACL,MAAM;QACN,QAAQ;QACR,GAAG;KACJ,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Database Operations
|
|
3
|
+
*
|
|
4
|
+
* CRUD operations for agents in the workspace database.
|
|
5
|
+
*/
|
|
6
|
+
export type AgentType = 'persistent' | 'ephemeral';
|
|
7
|
+
export type AgentStatus = 'active' | 'cleaned';
|
|
8
|
+
export type MountMode = 'worktree' | 'clone';
|
|
9
|
+
export interface Agent {
|
|
10
|
+
name: string;
|
|
11
|
+
type: AgentType;
|
|
12
|
+
status: AgentStatus;
|
|
13
|
+
base_name: string | null;
|
|
14
|
+
theme_id: string | null;
|
|
15
|
+
worktree_path: string | null;
|
|
16
|
+
mount_mode: MountMode;
|
|
17
|
+
created_at: string;
|
|
18
|
+
cleaned_at: string | null;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Add agents to database (case-insensitive uniqueness)
|
|
22
|
+
*/
|
|
23
|
+
export declare function addAgentsToDatabase(workspacePath: string, agentNames: string[], themeId?: string, mountMode?: MountMode): void;
|
|
24
|
+
/**
|
|
25
|
+
* Add an ephemeral agent to the database.
|
|
26
|
+
* Throws on name collision.
|
|
27
|
+
*/
|
|
28
|
+
export declare function addEphemeralAgentToDatabase(workspacePath: string, agentName: string, baseName: string, themeId?: string, mountMode?: MountMode): Agent;
|
|
29
|
+
/**
|
|
30
|
+
* Try to add an ephemeral agent to the database.
|
|
31
|
+
* Returns null if the name already exists (concurrency-safe).
|
|
32
|
+
*/
|
|
33
|
+
export declare function tryAddEphemeralAgentToDatabase(workspacePath: string, agentName: string, baseName: string, themeId?: string, mountMode?: MountMode): Agent | null;
|
|
34
|
+
/**
|
|
35
|
+
* Get all ephemeral agent names from the database
|
|
36
|
+
*/
|
|
37
|
+
export declare function getEphemeralAgentNames(workspacePath: string): Set<string>;
|
|
38
|
+
/**
|
|
39
|
+
* Remove an ephemeral agent from the database
|
|
40
|
+
*/
|
|
41
|
+
export declare function removeEphemeralAgent(workspacePath: string, agentName: string): void;
|
|
42
|
+
/**
|
|
43
|
+
* Get all agents in workspace
|
|
44
|
+
*/
|
|
45
|
+
export declare function getWorkspaceAgents(workspacePath: string, includeCleanedUp?: boolean): Agent[];
|
|
46
|
+
/**
|
|
47
|
+
* Get an agent by directory path.
|
|
48
|
+
*/
|
|
49
|
+
export declare function getAgentByPath(workspacePath: string, absolutePath: string): Agent | null;
|
|
50
|
+
/**
|
|
51
|
+
* Mark an agent as cleaned up
|
|
52
|
+
*/
|
|
53
|
+
export declare function markAgentCleaned(workspacePath: string, agentName: string): void;
|
|
54
|
+
/**
|
|
55
|
+
* Sync agents in database with what exists on disk.
|
|
56
|
+
*/
|
|
57
|
+
export declare function syncAgentsWithDisk(workspacePath: string): string[];
|
|
58
|
+
export interface DiscoverResult {
|
|
59
|
+
discovered: {
|
|
60
|
+
name: string;
|
|
61
|
+
type: AgentType;
|
|
62
|
+
path: string;
|
|
63
|
+
}[];
|
|
64
|
+
cleaned: string[];
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Discover agents on disk that aren't in the database and register them.
|
|
68
|
+
*/
|
|
69
|
+
export declare function discoverAgentsOnDisk(workspacePath: string): DiscoverResult;
|
|
70
|
+
/**
|
|
71
|
+
* Remove agents from database
|
|
72
|
+
*/
|
|
73
|
+
export declare function removeAgentsFromDatabase(workspacePath: string, agentNames: string[]): void;
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Database Operations
|
|
3
|
+
*
|
|
4
|
+
* CRUD operations for agents in the workspace database.
|
|
5
|
+
*/
|
|
6
|
+
import * as fs from 'node:fs';
|
|
7
|
+
import * as path from 'node:path';
|
|
8
|
+
import { eq, and, or, isNull, sql, asc } from 'drizzle-orm';
|
|
9
|
+
import { getThemePersistentDir } from '../themes.js';
|
|
10
|
+
import { createDrizzleConnection } from './drizzle.js';
|
|
11
|
+
import { workspace as workspaceTable, repositories as repositoriesTable, agents as agentsTable, agentWorktrees as agentWorktreesTable, } from './drizzle-schema.js';
|
|
12
|
+
import { withDrizzle, openWorkspaceDatabase } from './workspace.js';
|
|
13
|
+
/**
|
|
14
|
+
* Map a Drizzle agent row to the Agent interface.
|
|
15
|
+
*/
|
|
16
|
+
function toAgent(row) {
|
|
17
|
+
return {
|
|
18
|
+
name: row.name,
|
|
19
|
+
type: (row.type || 'persistent'),
|
|
20
|
+
status: (row.status || 'active'),
|
|
21
|
+
base_name: row.baseName,
|
|
22
|
+
theme_id: row.themeId,
|
|
23
|
+
worktree_path: row.worktreePath,
|
|
24
|
+
mount_mode: (row.mountMode || 'worktree'),
|
|
25
|
+
created_at: row.createdAt,
|
|
26
|
+
cleaned_at: row.cleanedAt,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Add agents to database (case-insensitive uniqueness)
|
|
31
|
+
*/
|
|
32
|
+
export function addAgentsToDatabase(workspacePath, agentNames, themeId, mountMode = 'worktree') {
|
|
33
|
+
withDrizzle(workspacePath, (ddb, sqliteDb) => {
|
|
34
|
+
const wsRow = ddb.select().from(workspaceTable).get();
|
|
35
|
+
if (!wsRow)
|
|
36
|
+
throw new Error('No workspace config found');
|
|
37
|
+
const repos = ddb.select({ name: repositoriesTable.name }).from(repositoriesTable).all();
|
|
38
|
+
const effectiveThemeId = themeId || wsRow.activeThemeId || undefined;
|
|
39
|
+
const persistentDir = getThemePersistentDir(effectiveThemeId);
|
|
40
|
+
const transaction = sqliteDb.transaction(() => {
|
|
41
|
+
for (const agentName of agentNames) {
|
|
42
|
+
const existing = ddb.select({ name: agentsTable.name })
|
|
43
|
+
.from(agentsTable)
|
|
44
|
+
.where(sql `LOWER(${agentsTable.name}) = LOWER(${agentName})`)
|
|
45
|
+
.get();
|
|
46
|
+
if (existing) {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
const now = new Date().toISOString();
|
|
50
|
+
const agentWorktreePath = wsRow.type === 'hq'
|
|
51
|
+
? `agents/${persistentDir}/${agentName}`
|
|
52
|
+
: agentName;
|
|
53
|
+
ddb.insert(agentsTable).values({
|
|
54
|
+
name: agentName,
|
|
55
|
+
type: 'persistent',
|
|
56
|
+
baseName: null,
|
|
57
|
+
themeId: effectiveThemeId || null,
|
|
58
|
+
worktreePath: agentWorktreePath,
|
|
59
|
+
mountMode,
|
|
60
|
+
createdAt: now,
|
|
61
|
+
}).onConflictDoUpdate({
|
|
62
|
+
target: agentsTable.name,
|
|
63
|
+
set: {
|
|
64
|
+
type: 'persistent',
|
|
65
|
+
baseName: null,
|
|
66
|
+
themeId: effectiveThemeId || null,
|
|
67
|
+
worktreePath: agentWorktreePath,
|
|
68
|
+
mountMode,
|
|
69
|
+
createdAt: now,
|
|
70
|
+
},
|
|
71
|
+
}).run();
|
|
72
|
+
for (const repo of repos) {
|
|
73
|
+
const worktreePath = wsRow.type === 'hq'
|
|
74
|
+
? `agents/${persistentDir}/${agentName}/${repo.name}`
|
|
75
|
+
: `${agentName}/${repo.name}`;
|
|
76
|
+
ddb.insert(agentWorktreesTable).values({
|
|
77
|
+
agentName,
|
|
78
|
+
repoName: repo.name,
|
|
79
|
+
worktreePath,
|
|
80
|
+
branch: `agent-${agentName}`,
|
|
81
|
+
createdAt: now,
|
|
82
|
+
}).onConflictDoUpdate({
|
|
83
|
+
target: [agentWorktreesTable.agentName, agentWorktreesTable.repoName],
|
|
84
|
+
set: {
|
|
85
|
+
worktreePath,
|
|
86
|
+
branch: `agent-${agentName}`,
|
|
87
|
+
createdAt: now,
|
|
88
|
+
},
|
|
89
|
+
}).run();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
transaction();
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Add an ephemeral agent to the database.
|
|
98
|
+
* Throws on name collision.
|
|
99
|
+
*/
|
|
100
|
+
export function addEphemeralAgentToDatabase(workspacePath, agentName, baseName, themeId, mountMode = 'worktree') {
|
|
101
|
+
const result = tryAddEphemeralAgentToDatabase(workspacePath, agentName, baseName, themeId, mountMode);
|
|
102
|
+
if (!result) {
|
|
103
|
+
throw new Error(`Agent name "${agentName}" already exists (UNIQUE constraint failed: agents.name)`);
|
|
104
|
+
}
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Try to add an ephemeral agent to the database.
|
|
109
|
+
* Returns null if the name already exists (concurrency-safe).
|
|
110
|
+
*/
|
|
111
|
+
export function tryAddEphemeralAgentToDatabase(workspacePath, agentName, baseName, themeId, mountMode = 'worktree') {
|
|
112
|
+
const sqliteDb = openWorkspaceDatabase(workspacePath);
|
|
113
|
+
const ddb = createDrizzleConnection(sqliteDb);
|
|
114
|
+
try {
|
|
115
|
+
const now = new Date().toISOString();
|
|
116
|
+
const worktreePath = `agents/temp/${agentName}`;
|
|
117
|
+
ddb.insert(agentsTable).values({
|
|
118
|
+
name: agentName,
|
|
119
|
+
type: 'ephemeral',
|
|
120
|
+
status: 'active',
|
|
121
|
+
baseName,
|
|
122
|
+
themeId: themeId || null,
|
|
123
|
+
worktreePath,
|
|
124
|
+
mountMode,
|
|
125
|
+
createdAt: now,
|
|
126
|
+
}).run();
|
|
127
|
+
const agent = ddb.select().from(agentsTable)
|
|
128
|
+
.where(eq(agentsTable.name, agentName))
|
|
129
|
+
.get();
|
|
130
|
+
if (!agent)
|
|
131
|
+
return null;
|
|
132
|
+
return toAgent(agent);
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
const sqliteErr = err;
|
|
136
|
+
if (sqliteErr.code === 'SQLITE_CONSTRAINT_PRIMARYKEY' || sqliteErr.code === 'SQLITE_CONSTRAINT_UNIQUE') {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
throw err;
|
|
140
|
+
}
|
|
141
|
+
finally {
|
|
142
|
+
sqliteDb.close();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Get all ephemeral agent names from the database
|
|
147
|
+
*/
|
|
148
|
+
export function getEphemeralAgentNames(workspacePath) {
|
|
149
|
+
return withDrizzle(workspacePath, (ddb) => {
|
|
150
|
+
const rows = ddb.select({ name: agentsTable.name })
|
|
151
|
+
.from(agentsTable)
|
|
152
|
+
.where(eq(agentsTable.type, 'ephemeral'))
|
|
153
|
+
.all();
|
|
154
|
+
return new Set(rows.map(a => a.name.toLowerCase()));
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Remove an ephemeral agent from the database
|
|
159
|
+
*/
|
|
160
|
+
export function removeEphemeralAgent(workspacePath, agentName) {
|
|
161
|
+
withDrizzle(workspacePath, (ddb) => {
|
|
162
|
+
ddb.delete(agentsTable)
|
|
163
|
+
.where(and(eq(agentsTable.name, agentName), eq(agentsTable.type, 'ephemeral')))
|
|
164
|
+
.run();
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Get all agents in workspace
|
|
169
|
+
*/
|
|
170
|
+
export function getWorkspaceAgents(workspacePath, includeCleanedUp = false) {
|
|
171
|
+
return withDrizzle(workspacePath, (ddb) => {
|
|
172
|
+
let rows;
|
|
173
|
+
if (includeCleanedUp) {
|
|
174
|
+
rows = ddb.select().from(agentsTable)
|
|
175
|
+
.orderBy(asc(agentsTable.createdAt))
|
|
176
|
+
.all();
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
rows = ddb.select().from(agentsTable)
|
|
180
|
+
.where(or(eq(agentsTable.status, 'active'), isNull(agentsTable.status)))
|
|
181
|
+
.orderBy(asc(agentsTable.createdAt))
|
|
182
|
+
.all();
|
|
183
|
+
}
|
|
184
|
+
return rows.map(toAgent);
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Get an agent by directory path.
|
|
189
|
+
*/
|
|
190
|
+
export function getAgentByPath(workspacePath, absolutePath) {
|
|
191
|
+
const normalizedWorkspace = path.resolve(workspacePath);
|
|
192
|
+
const normalizedPath = path.resolve(absolutePath);
|
|
193
|
+
if (!normalizedPath.startsWith(normalizedWorkspace)) {
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
const relativePath = path.relative(normalizedWorkspace, normalizedPath);
|
|
197
|
+
return withDrizzle(workspacePath, (ddb) => {
|
|
198
|
+
const rows = ddb.select().from(agentsTable)
|
|
199
|
+
.where(or(eq(agentsTable.status, 'active'), isNull(agentsTable.status)))
|
|
200
|
+
.all();
|
|
201
|
+
for (const row of rows) {
|
|
202
|
+
if (row.worktreePath) {
|
|
203
|
+
if (relativePath === row.worktreePath || relativePath.startsWith(row.worktreePath + '/')) {
|
|
204
|
+
return toAgent(row);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return null;
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Mark an agent as cleaned up
|
|
213
|
+
*/
|
|
214
|
+
export function markAgentCleaned(workspacePath, agentName) {
|
|
215
|
+
withDrizzle(workspacePath, (ddb) => {
|
|
216
|
+
ddb.update(agentsTable)
|
|
217
|
+
.set({ status: 'cleaned', cleanedAt: new Date().toISOString() })
|
|
218
|
+
.where(eq(agentsTable.name, agentName))
|
|
219
|
+
.run();
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Sync agents in database with what exists on disk.
|
|
224
|
+
*/
|
|
225
|
+
export function syncAgentsWithDisk(workspacePath) {
|
|
226
|
+
const agentList = getWorkspaceAgents(workspacePath, false);
|
|
227
|
+
const cleanedAgents = [];
|
|
228
|
+
for (const agent of agentList) {
|
|
229
|
+
let agentDir;
|
|
230
|
+
if (agent.worktree_path) {
|
|
231
|
+
agentDir = path.join(workspacePath, agent.worktree_path);
|
|
232
|
+
}
|
|
233
|
+
else if (agent.type === 'ephemeral') {
|
|
234
|
+
agentDir = path.join(workspacePath, 'agents', 'temp', agent.name);
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
agentDir = path.join(workspacePath, 'agents', 'staff', agent.name);
|
|
238
|
+
}
|
|
239
|
+
if (!fs.existsSync(agentDir)) {
|
|
240
|
+
markAgentCleaned(workspacePath, agent.name);
|
|
241
|
+
cleanedAgents.push(agent.name);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return cleanedAgents;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Discover agents on disk that aren't in the database and register them.
|
|
248
|
+
*/
|
|
249
|
+
export function discoverAgentsOnDisk(workspacePath) {
|
|
250
|
+
const result = { discovered: [], cleaned: [] };
|
|
251
|
+
result.cleaned = syncAgentsWithDisk(workspacePath);
|
|
252
|
+
const activeAgents = getWorkspaceAgents(workspacePath, false);
|
|
253
|
+
const activeNames = new Set(activeAgents.map(a => a.name.toLowerCase()));
|
|
254
|
+
const allAgents = getWorkspaceAgents(workspacePath, true);
|
|
255
|
+
const cleanedAgentsMap = new Map(allAgents.filter(a => a.status === 'cleaned').map(a => [a.name.toLowerCase(), a]));
|
|
256
|
+
withDrizzle(workspacePath, (ddb) => {
|
|
257
|
+
// Scan staff directory
|
|
258
|
+
const staffDir = path.join(workspacePath, 'agents', 'staff');
|
|
259
|
+
if (fs.existsSync(staffDir)) {
|
|
260
|
+
const staffEntries = fs.readdirSync(staffDir, { withFileTypes: true });
|
|
261
|
+
for (const entry of staffEntries) {
|
|
262
|
+
if (entry.isDirectory() && !entry.name.startsWith('.')) {
|
|
263
|
+
const nameLower = entry.name.toLowerCase();
|
|
264
|
+
if (!activeNames.has(nameLower)) {
|
|
265
|
+
const worktreePath = `agents/staff/${entry.name}`;
|
|
266
|
+
const now = new Date().toISOString();
|
|
267
|
+
const cleanedAgent = cleanedAgentsMap.get(nameLower);
|
|
268
|
+
if (cleanedAgent) {
|
|
269
|
+
ddb.update(agentsTable)
|
|
270
|
+
.set({ status: 'active', cleanedAt: null, worktreePath })
|
|
271
|
+
.where(sql `LOWER(${agentsTable.name}) = LOWER(${entry.name})`)
|
|
272
|
+
.run();
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
ddb.insert(agentsTable).values({
|
|
276
|
+
name: entry.name,
|
|
277
|
+
type: 'persistent',
|
|
278
|
+
status: 'active',
|
|
279
|
+
worktreePath,
|
|
280
|
+
mountMode: 'worktree',
|
|
281
|
+
createdAt: now,
|
|
282
|
+
}).run();
|
|
283
|
+
}
|
|
284
|
+
result.discovered.push({ name: entry.name, type: 'persistent', path: worktreePath });
|
|
285
|
+
activeNames.add(nameLower);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
// Scan temp directory
|
|
291
|
+
const tempDir = path.join(workspacePath, 'agents', 'temp');
|
|
292
|
+
if (fs.existsSync(tempDir)) {
|
|
293
|
+
const tempEntries = fs.readdirSync(tempDir, { withFileTypes: true });
|
|
294
|
+
for (const entry of tempEntries) {
|
|
295
|
+
if (entry.isDirectory() && !entry.name.startsWith('.')) {
|
|
296
|
+
const nameLower = entry.name.toLowerCase();
|
|
297
|
+
if (!activeNames.has(nameLower)) {
|
|
298
|
+
const worktreePath = `agents/temp/${entry.name}`;
|
|
299
|
+
const now = new Date().toISOString();
|
|
300
|
+
const cleanedAgent = cleanedAgentsMap.get(nameLower);
|
|
301
|
+
if (cleanedAgent) {
|
|
302
|
+
ddb.update(agentsTable)
|
|
303
|
+
.set({ status: 'active', cleanedAt: null, worktreePath })
|
|
304
|
+
.where(sql `LOWER(${agentsTable.name}) = LOWER(${entry.name})`)
|
|
305
|
+
.run();
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
ddb.insert(agentsTable).values({
|
|
309
|
+
name: entry.name,
|
|
310
|
+
type: 'ephemeral',
|
|
311
|
+
status: 'active',
|
|
312
|
+
worktreePath,
|
|
313
|
+
mountMode: 'worktree',
|
|
314
|
+
createdAt: now,
|
|
315
|
+
}).run();
|
|
316
|
+
}
|
|
317
|
+
result.discovered.push({ name: entry.name, type: 'ephemeral', path: worktreePath });
|
|
318
|
+
activeNames.add(nameLower);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
return result;
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Remove agents from database
|
|
328
|
+
*/
|
|
329
|
+
export function removeAgentsFromDatabase(workspacePath, agentNames) {
|
|
330
|
+
withDrizzle(workspacePath, (ddb, sqliteDb) => {
|
|
331
|
+
const transaction = sqliteDb.transaction(() => {
|
|
332
|
+
for (const agentName of agentNames) {
|
|
333
|
+
ddb.delete(agentsTable)
|
|
334
|
+
.where(eq(agentsTable.name, agentName))
|
|
335
|
+
.run();
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
transaction();
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
//# sourceMappingURL=agents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../../src/lib/database/agents.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database Safety — WAL mode, auto-backup, corruption recovery.
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* - WAL journal mode configuration
|
|
6
|
+
* - Rotating backup (keeps last 5 copies)
|
|
7
|
+
* - Integrity check on open with auto-recovery
|
|
8
|
+
* - Manual repair via dump/reimport
|
|
9
|
+
*
|
|
10
|
+
* See: PRLT-1081
|
|
11
|
+
*/
|
|
12
|
+
import Database from 'better-sqlite3';
|
|
13
|
+
/**
|
|
14
|
+
* Enable WAL journal mode on a database connection.
|
|
15
|
+
* WAL allows concurrent readers with one writer and is significantly
|
|
16
|
+
* more resistant to corruption than the default journal_mode=delete.
|
|
17
|
+
*/
|
|
18
|
+
export declare function enableWALMode(db: Database.Database): void;
|
|
19
|
+
/**
|
|
20
|
+
* Get the backup path for a given database path and backup number.
|
|
21
|
+
*/
|
|
22
|
+
export declare function getBackupPath(dbPath: string, n: number): string;
|
|
23
|
+
/**
|
|
24
|
+
* Create a rotating backup of the database file.
|
|
25
|
+
* Keeps the last MAX_BACKUPS copies, numbered 1 (newest) through MAX_BACKUPS (oldest).
|
|
26
|
+
* Rotates existing backups before copying the current database.
|
|
27
|
+
*
|
|
28
|
+
* Returns true if backup was created, false if source didn't exist.
|
|
29
|
+
*/
|
|
30
|
+
export declare function createRotatingBackup(dbPath: string): boolean;
|
|
31
|
+
export interface IntegrityCheckResult {
|
|
32
|
+
ok: boolean;
|
|
33
|
+
errors: string[];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Run PRAGMA integrity_check on a database.
|
|
37
|
+
* Returns { ok: true } if the database is healthy, or { ok: false, errors } with details.
|
|
38
|
+
*/
|
|
39
|
+
export declare function checkIntegrity(db: Database.Database): IntegrityCheckResult;
|
|
40
|
+
/**
|
|
41
|
+
* Quick integrity check using PRAGMA quick_check (faster than full integrity_check).
|
|
42
|
+
* Skips checking that the contents of table rows match the indexes.
|
|
43
|
+
*/
|
|
44
|
+
export declare function quickCheckIntegrity(db: Database.Database): IntegrityCheckResult;
|
|
45
|
+
export interface RepairResult {
|
|
46
|
+
success: boolean;
|
|
47
|
+
method: 'dump-reimport' | 'backup-restore' | 'none';
|
|
48
|
+
message: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Attempt to repair a corrupted database.
|
|
52
|
+
*
|
|
53
|
+
* Strategy:
|
|
54
|
+
* 1. Try dump/reimport — opens the corrupt DB, dumps all SQL, creates a new DB
|
|
55
|
+
* 2. If dump fails, fall back to the most recent backup
|
|
56
|
+
*
|
|
57
|
+
* The original corrupt file is preserved as dbPath.corrupt for forensics.
|
|
58
|
+
*/
|
|
59
|
+
export declare function repairDatabase(dbPath: string): RepairResult;
|