@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
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Settings Store
|
|
3
|
+
*
|
|
4
|
+
* Centralized access to the workspace_settings key-value table.
|
|
5
|
+
* Replaces the duplicated getSetting/setSetting/deleteSetting helpers
|
|
6
|
+
* that were copied across linear/config.ts, jira/config.ts, etc.
|
|
7
|
+
*
|
|
8
|
+
* All workspace settings access should go through this store.
|
|
9
|
+
*/
|
|
10
|
+
import Database from 'better-sqlite3';
|
|
11
|
+
import { wrapDatabase } from './driver.js';
|
|
12
|
+
const SETTINGS_TABLE = 'workspace_settings';
|
|
13
|
+
/**
|
|
14
|
+
* Provides CRUD access to the workspace_settings key-value table.
|
|
15
|
+
*
|
|
16
|
+
* Usage:
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const settings = new SettingsStore(driver)
|
|
19
|
+
* settings.set('linear.api_key', 'sk-...')
|
|
20
|
+
* const key = settings.get('linear.api_key')
|
|
21
|
+
* settings.delete('linear.api_key')
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export class SettingsStore {
|
|
25
|
+
driver;
|
|
26
|
+
/**
|
|
27
|
+
* Create a SettingsStore.
|
|
28
|
+
* Accepts either a DatabaseDriver or a raw better-sqlite3 Database
|
|
29
|
+
* (for backward compatibility during migration).
|
|
30
|
+
*/
|
|
31
|
+
constructor(driverOrDb) {
|
|
32
|
+
if (driverOrDb instanceof Database) {
|
|
33
|
+
this.driver = wrapDatabase(driverOrDb);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
this.driver = driverOrDb;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get a setting value by key. Returns null if not found.
|
|
41
|
+
*/
|
|
42
|
+
get(key) {
|
|
43
|
+
const row = this.driver
|
|
44
|
+
.prepare(`SELECT value FROM ${SETTINGS_TABLE} WHERE key = ?`)
|
|
45
|
+
.get(key);
|
|
46
|
+
return row?.value ?? null;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Set a setting value. Inserts or updates (upserts) the key.
|
|
50
|
+
*/
|
|
51
|
+
set(key, value) {
|
|
52
|
+
this.driver.prepare(`
|
|
53
|
+
INSERT INTO ${SETTINGS_TABLE} (key, value)
|
|
54
|
+
VALUES (?, ?)
|
|
55
|
+
ON CONFLICT(key) DO UPDATE SET value = excluded.value
|
|
56
|
+
`).run(key, value);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Delete a setting by key.
|
|
60
|
+
*/
|
|
61
|
+
delete(key) {
|
|
62
|
+
this.driver.prepare(`DELETE FROM ${SETTINGS_TABLE} WHERE key = ?`).run(key);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Check if a setting exists.
|
|
66
|
+
*/
|
|
67
|
+
has(key) {
|
|
68
|
+
return this.get(key) !== null;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get all settings matching a key prefix.
|
|
72
|
+
* E.g., getByPrefix('linear.') returns all Linear settings.
|
|
73
|
+
*/
|
|
74
|
+
getByPrefix(prefix) {
|
|
75
|
+
return this.driver
|
|
76
|
+
.prepare(`SELECT key, value FROM ${SETTINGS_TABLE} WHERE key LIKE ?`)
|
|
77
|
+
.all(`${prefix}%`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Create a SettingsStore from a raw better-sqlite3 Database.
|
|
82
|
+
* Convenience function for backward compatibility.
|
|
83
|
+
*/
|
|
84
|
+
export function createSettingsStore(db) {
|
|
85
|
+
return new SettingsStore(db);
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=settings-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings-store.js","sourceRoot":"","sources":["../../../src/lib/database/settings-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,QAAQ,MAAM,gBAAgB,CAAA;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,MAAM,cAAc,GAAG,oBAAoB,CAAA;AAE3C;;;;;;;;;;GAUG;AACH,MAAM,OAAO,aAAa;IAChB,MAAM,CAAgB;IAE9B;;;;OAIG;IACH,YAAY,UAA8C;QACxD,IAAI,UAAU,YAAY,QAAQ,EAAE,CAAC;YACnC,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC,UAAU,CAAC,CAAA;QACxC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,GAAG,UAAU,CAAA;QAC1B,CAAC;IACH,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,GAAW;QACb,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM;aACpB,OAAO,CAAoB,qBAAqB,cAAc,gBAAgB,CAAC;aAC/E,GAAG,CAAC,GAAG,CAAC,CAAA;QACX,OAAO,GAAG,EAAE,KAAK,IAAI,IAAI,CAAA;IAC3B,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,GAAW,EAAE,KAAa;QAC5B,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;oBACJ,cAAc;;;KAG7B,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IACpB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,GAAW;QAChB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,cAAc,gBAAgB,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC7E,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,CAAA;IAC/B,CAAC;IAED;;;OAGG;IACH,WAAW,CAAC,MAAc;QACxB,OAAO,IAAI,CAAC,MAAM;aACf,OAAO,CAAiC,0BAA0B,cAAc,mBAAmB,CAAC;aACpG,GAAG,CAAC,GAAG,MAAM,GAAG,CAAC,CAAA;IACtB,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,EAAqB;IACvD,OAAO,IAAI,aAAa,CAAC,EAAE,CAAC,CAAA;AAC9B,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme Database Operations
|
|
3
|
+
*
|
|
4
|
+
* CRUD operations for agent naming themes.
|
|
5
|
+
*/
|
|
6
|
+
export interface AgentTheme {
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
display_name: string;
|
|
10
|
+
description: string | null;
|
|
11
|
+
builtin: boolean;
|
|
12
|
+
created_at: string;
|
|
13
|
+
}
|
|
14
|
+
export interface AgentThemeName {
|
|
15
|
+
theme_id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Get the active theme for a workspace
|
|
20
|
+
*/
|
|
21
|
+
export declare function getActiveTheme(workspacePath: string): AgentTheme | null;
|
|
22
|
+
/**
|
|
23
|
+
* Set the active theme for a workspace
|
|
24
|
+
*/
|
|
25
|
+
export declare function setActiveTheme(workspacePath: string, themeId: string | null): void;
|
|
26
|
+
/**
|
|
27
|
+
* Get all themes
|
|
28
|
+
*/
|
|
29
|
+
export declare function getThemes(workspacePath: string): AgentTheme[];
|
|
30
|
+
/**
|
|
31
|
+
* Get a theme by ID
|
|
32
|
+
*/
|
|
33
|
+
export declare function getTheme(workspacePath: string, themeId: string): AgentTheme | null;
|
|
34
|
+
/**
|
|
35
|
+
* Create a new theme
|
|
36
|
+
*/
|
|
37
|
+
export declare function createTheme(workspacePath: string, theme: {
|
|
38
|
+
id: string;
|
|
39
|
+
name: string;
|
|
40
|
+
displayName: string;
|
|
41
|
+
description?: string;
|
|
42
|
+
builtin?: boolean;
|
|
43
|
+
}): AgentTheme;
|
|
44
|
+
/**
|
|
45
|
+
* Delete a theme (cannot delete builtin themes)
|
|
46
|
+
*/
|
|
47
|
+
export declare function deleteTheme(workspacePath: string, themeId: string): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Get names for a theme
|
|
50
|
+
*/
|
|
51
|
+
export declare function getThemeNames(workspacePath: string, themeId: string): AgentThemeName[];
|
|
52
|
+
/**
|
|
53
|
+
* Get available names for a theme.
|
|
54
|
+
*/
|
|
55
|
+
export declare function getAvailableThemeNames(workspacePath: string, themeId: string): string[];
|
|
56
|
+
/**
|
|
57
|
+
* Add names to a theme (case-insensitive uniqueness)
|
|
58
|
+
*/
|
|
59
|
+
export declare function addThemeNames(workspacePath: string, themeId: string, names: string[]): void;
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme Database Operations
|
|
3
|
+
*
|
|
4
|
+
* CRUD operations for agent naming themes.
|
|
5
|
+
*/
|
|
6
|
+
import * as fs from 'node:fs';
|
|
7
|
+
import * as path from 'node:path';
|
|
8
|
+
import { eq, and, or, isNull, sql, asc, desc } from 'drizzle-orm';
|
|
9
|
+
import { workspace as workspaceTable, agents as agentsTable, agentThemes as agentThemesTable, agentThemeNames as agentThemeNamesTable, } from './drizzle-schema.js';
|
|
10
|
+
import { withDrizzle, getWorkspaceConfig } from './workspace.js';
|
|
11
|
+
import { getWorkspaceAgents } from './agents.js';
|
|
12
|
+
/**
|
|
13
|
+
* Map a Drizzle theme row to the AgentTheme interface.
|
|
14
|
+
*/
|
|
15
|
+
function toAgentTheme(row) {
|
|
16
|
+
return {
|
|
17
|
+
id: row.id,
|
|
18
|
+
name: row.name,
|
|
19
|
+
display_name: row.displayName,
|
|
20
|
+
description: row.description,
|
|
21
|
+
builtin: Boolean(row.builtin),
|
|
22
|
+
created_at: row.createdAt,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get the active theme for a workspace
|
|
27
|
+
*/
|
|
28
|
+
export function getActiveTheme(workspacePath) {
|
|
29
|
+
const config = getWorkspaceConfig(workspacePath);
|
|
30
|
+
if (config?.active_theme_id) {
|
|
31
|
+
return getTheme(workspacePath, config.active_theme_id);
|
|
32
|
+
}
|
|
33
|
+
const agentList = getWorkspaceAgents(workspacePath);
|
|
34
|
+
if (agentList.length === 0) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
const themedAgent = agentList.find(a => a.theme_id);
|
|
38
|
+
if (themedAgent?.theme_id) {
|
|
39
|
+
const theme = getTheme(workspacePath, themedAgent.theme_id);
|
|
40
|
+
if (theme) {
|
|
41
|
+
setActiveTheme(workspacePath, themedAgent.theme_id);
|
|
42
|
+
return theme;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const themes = getThemes(workspacePath);
|
|
46
|
+
for (const theme of themes) {
|
|
47
|
+
const themeNames = getThemeNames(workspacePath, theme.id);
|
|
48
|
+
const themeNameSet = new Set(themeNames.map(n => n.name.toLowerCase()));
|
|
49
|
+
const matchingAgent = agentList.find(a => themeNameSet.has(a.name.toLowerCase()));
|
|
50
|
+
if (matchingAgent) {
|
|
51
|
+
setActiveTheme(workspacePath, theme.id);
|
|
52
|
+
return theme;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Set the active theme for a workspace
|
|
59
|
+
*/
|
|
60
|
+
export function setActiveTheme(workspacePath, themeId) {
|
|
61
|
+
withDrizzle(workspacePath, (ddb) => {
|
|
62
|
+
if (themeId) {
|
|
63
|
+
const theme = ddb.select({ id: agentThemesTable.id })
|
|
64
|
+
.from(agentThemesTable)
|
|
65
|
+
.where(eq(agentThemesTable.id, themeId))
|
|
66
|
+
.get();
|
|
67
|
+
if (!theme) {
|
|
68
|
+
throw new Error(`Theme "${themeId}" not found`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
ddb.update(workspaceTable)
|
|
72
|
+
.set({ activeThemeId: themeId })
|
|
73
|
+
.where(eq(workspaceTable.id, 1))
|
|
74
|
+
.run();
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Get all themes
|
|
79
|
+
*/
|
|
80
|
+
export function getThemes(workspacePath) {
|
|
81
|
+
return withDrizzle(workspacePath, (ddb) => {
|
|
82
|
+
const rows = ddb.select().from(agentThemesTable)
|
|
83
|
+
.orderBy(desc(agentThemesTable.builtin), asc(agentThemesTable.name))
|
|
84
|
+
.all();
|
|
85
|
+
return rows.map(toAgentTheme);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Get a theme by ID
|
|
90
|
+
*/
|
|
91
|
+
export function getTheme(workspacePath, themeId) {
|
|
92
|
+
return withDrizzle(workspacePath, (ddb) => {
|
|
93
|
+
const row = ddb.select().from(agentThemesTable)
|
|
94
|
+
.where(eq(agentThemesTable.id, themeId))
|
|
95
|
+
.get();
|
|
96
|
+
return row ? toAgentTheme(row) : null;
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Create a new theme
|
|
101
|
+
*/
|
|
102
|
+
export function createTheme(workspacePath, theme) {
|
|
103
|
+
return withDrizzle(workspacePath, (ddb) => {
|
|
104
|
+
const now = new Date().toISOString();
|
|
105
|
+
ddb.insert(agentThemesTable).values({
|
|
106
|
+
id: theme.id,
|
|
107
|
+
name: theme.name,
|
|
108
|
+
displayName: theme.displayName,
|
|
109
|
+
description: theme.description || null,
|
|
110
|
+
builtin: theme.builtin || false,
|
|
111
|
+
createdAt: now,
|
|
112
|
+
}).run();
|
|
113
|
+
const created = ddb.select().from(agentThemesTable)
|
|
114
|
+
.where(eq(agentThemesTable.id, theme.id))
|
|
115
|
+
.get();
|
|
116
|
+
return toAgentTheme(created);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Delete a theme (cannot delete builtin themes)
|
|
121
|
+
*/
|
|
122
|
+
export function deleteTheme(workspacePath, themeId) {
|
|
123
|
+
return withDrizzle(workspacePath, (ddb) => {
|
|
124
|
+
const theme = ddb.select({ builtin: agentThemesTable.builtin })
|
|
125
|
+
.from(agentThemesTable)
|
|
126
|
+
.where(eq(agentThemesTable.id, themeId))
|
|
127
|
+
.get();
|
|
128
|
+
if (!theme) {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
if (theme.builtin) {
|
|
132
|
+
throw new Error('Cannot delete built-in themes');
|
|
133
|
+
}
|
|
134
|
+
ddb.delete(agentThemesTable)
|
|
135
|
+
.where(eq(agentThemesTable.id, themeId))
|
|
136
|
+
.run();
|
|
137
|
+
return true;
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Get names for a theme
|
|
142
|
+
*/
|
|
143
|
+
export function getThemeNames(workspacePath, themeId) {
|
|
144
|
+
return withDrizzle(workspacePath, (ddb) => {
|
|
145
|
+
const rows = ddb.select().from(agentThemeNamesTable)
|
|
146
|
+
.where(eq(agentThemeNamesTable.themeId, themeId))
|
|
147
|
+
.orderBy(asc(agentThemeNamesTable.name))
|
|
148
|
+
.all();
|
|
149
|
+
return rows.map(row => ({
|
|
150
|
+
theme_id: row.themeId,
|
|
151
|
+
name: row.name,
|
|
152
|
+
}));
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Get available names for a theme.
|
|
157
|
+
*/
|
|
158
|
+
export function getAvailableThemeNames(workspacePath, themeId) {
|
|
159
|
+
return withDrizzle(workspacePath, (ddb) => {
|
|
160
|
+
const names = ddb.select({ name: agentThemeNamesTable.name })
|
|
161
|
+
.from(agentThemeNamesTable)
|
|
162
|
+
.where(eq(agentThemeNamesTable.themeId, themeId))
|
|
163
|
+
.orderBy(asc(agentThemeNamesTable.name))
|
|
164
|
+
.all();
|
|
165
|
+
const existingAgents = ddb.select({
|
|
166
|
+
name: sql `LOWER(${agentsTable.name})`,
|
|
167
|
+
worktreePath: agentsTable.worktreePath,
|
|
168
|
+
})
|
|
169
|
+
.from(agentsTable)
|
|
170
|
+
.where(and(eq(agentsTable.type, 'persistent'), or(eq(agentsTable.status, 'active'), isNull(agentsTable.status))))
|
|
171
|
+
.all();
|
|
172
|
+
const inUseNames = new Set();
|
|
173
|
+
for (const agent of existingAgents) {
|
|
174
|
+
if (agent.worktreePath) {
|
|
175
|
+
const fullPath = path.join(workspacePath, agent.worktreePath);
|
|
176
|
+
if (fs.existsSync(fullPath)) {
|
|
177
|
+
inUseNames.add(agent.name);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
inUseNames.add(agent.name);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return names
|
|
185
|
+
.map(n => n.name)
|
|
186
|
+
.filter(name => !inUseNames.has(name.toLowerCase()));
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Add names to a theme (case-insensitive uniqueness)
|
|
191
|
+
*/
|
|
192
|
+
export function addThemeNames(workspacePath, themeId, names) {
|
|
193
|
+
withDrizzle(workspacePath, (ddb, sqliteDb) => {
|
|
194
|
+
const transaction = sqliteDb.transaction(() => {
|
|
195
|
+
for (const name of names) {
|
|
196
|
+
const existing = ddb.select({ name: agentThemeNamesTable.name })
|
|
197
|
+
.from(agentThemeNamesTable)
|
|
198
|
+
.where(and(eq(agentThemeNamesTable.themeId, themeId), sql `LOWER(${agentThemeNamesTable.name}) = LOWER(${name})`))
|
|
199
|
+
.get();
|
|
200
|
+
if (existing) {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
ddb.insert(agentThemeNamesTable).values({
|
|
204
|
+
themeId,
|
|
205
|
+
name,
|
|
206
|
+
}).run();
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
transaction();
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=themes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"themes.js","sourceRoot":"","sources":["../../../src/lib/database/themes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace Database Operations
|
|
3
|
+
*
|
|
4
|
+
* Core database lifecycle: open, create, get config, path resolution.
|
|
5
|
+
*/
|
|
6
|
+
import Database from 'better-sqlite3';
|
|
7
|
+
import { type DrizzleDB } from './drizzle.js';
|
|
8
|
+
import type { DatabaseDriver } from './driver.js';
|
|
9
|
+
export interface WorkspaceConfig {
|
|
10
|
+
id: number;
|
|
11
|
+
type: 'hq' | 'workspace';
|
|
12
|
+
workspace_name: string;
|
|
13
|
+
has_pmo: boolean;
|
|
14
|
+
active_theme_id: string | null;
|
|
15
|
+
created_at: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Open the workspace database, wrap it with Drizzle, run a function,
|
|
19
|
+
* and close the connection. Handles the open/close lifecycle.
|
|
20
|
+
*/
|
|
21
|
+
export declare function withDrizzle<T>(workspacePath: string, fn: (ddb: DrizzleDB, sqliteDb: Database.Database) => T): T;
|
|
22
|
+
/**
|
|
23
|
+
* Get the database path for a workspace
|
|
24
|
+
*/
|
|
25
|
+
export declare function getDatabasePath(workspacePath: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Get the config path for a workspace
|
|
28
|
+
*/
|
|
29
|
+
export declare function getConfigPath(workspacePath: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* Open workspace database connection.
|
|
32
|
+
*
|
|
33
|
+
* Safety features (PRLT-1081):
|
|
34
|
+
* - Creates a rotating backup before opening (keeps last 5)
|
|
35
|
+
* - Enables WAL journal mode for corruption resistance
|
|
36
|
+
* - Runs a quick integrity check; auto-repairs if corruption detected
|
|
37
|
+
*/
|
|
38
|
+
export declare function openWorkspaceDatabase(workspacePath: string): Database.Database;
|
|
39
|
+
/**
|
|
40
|
+
* Open workspace database and return a DatabaseDriver.
|
|
41
|
+
* Preferred over openWorkspaceDatabase for new code.
|
|
42
|
+
*/
|
|
43
|
+
export declare function openWorkspaceDriver(workspacePath: string): DatabaseDriver;
|
|
44
|
+
/**
|
|
45
|
+
* Create and initialize workspace database
|
|
46
|
+
*/
|
|
47
|
+
export declare function createWorkspaceDatabase(workspacePath: string, type: 'hq' | 'workspace', workspaceName: string, hasPMO?: boolean): Database.Database;
|
|
48
|
+
/**
|
|
49
|
+
* Get workspace configuration
|
|
50
|
+
*/
|
|
51
|
+
export declare function getWorkspaceConfig(workspacePath: string): WorkspaceConfig | null;
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace Database Operations
|
|
3
|
+
*
|
|
4
|
+
* Core database lifecycle: open, create, get config, path resolution.
|
|
5
|
+
*/
|
|
6
|
+
import Database from 'better-sqlite3';
|
|
7
|
+
import * as fs from 'node:fs';
|
|
8
|
+
import * as path from 'node:path';
|
|
9
|
+
import { isEphemeralAgentName } from '../themes.js';
|
|
10
|
+
import { throwIfNativeBindingError } from './native-validation.js';
|
|
11
|
+
import { runDrizzleMigrations } from './migrator.js';
|
|
12
|
+
import { ALL_MIGRATIONS } from './migrations/index.js';
|
|
13
|
+
import { createDrizzleConnection } from './drizzle.js';
|
|
14
|
+
import { workspace as workspaceTable, } from './drizzle-schema.js';
|
|
15
|
+
import { BetterSqlite3Driver } from './driver.js';
|
|
16
|
+
import { enableWALMode, createRotatingBackup, quickCheckIntegrity, repairDatabase, } from './db-safety.js';
|
|
17
|
+
/**
|
|
18
|
+
* Open the workspace database, wrap it with Drizzle, run a function,
|
|
19
|
+
* and close the connection. Handles the open/close lifecycle.
|
|
20
|
+
*/
|
|
21
|
+
export function withDrizzle(workspacePath, fn) {
|
|
22
|
+
const sqliteDb = openWorkspaceDatabase(workspacePath);
|
|
23
|
+
const ddb = createDrizzleConnection(sqliteDb);
|
|
24
|
+
try {
|
|
25
|
+
return fn(ddb, sqliteDb);
|
|
26
|
+
}
|
|
27
|
+
finally {
|
|
28
|
+
sqliteDb.close();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Ensure ephemeral agents are correctly typed based on their worktree path or naming pattern.
|
|
33
|
+
* Uses raw SQL because it relies on SQLite-specific GLOB operator and sqlite_master introspection.
|
|
34
|
+
*/
|
|
35
|
+
function ensureEphemeralAgentTypes(db) {
|
|
36
|
+
const tableExists = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='agents'").get();
|
|
37
|
+
if (!tableExists) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
db.exec("UPDATE agents SET type = 'ephemeral' WHERE worktree_path LIKE 'agents/temp/%' AND type != 'ephemeral'");
|
|
41
|
+
db.exec(`
|
|
42
|
+
UPDATE agents SET type = 'ephemeral'
|
|
43
|
+
WHERE type != 'ephemeral'
|
|
44
|
+
AND name GLOB '*-*-[0-9]*'
|
|
45
|
+
`);
|
|
46
|
+
const potentialEphemeral = db.prepare(`
|
|
47
|
+
SELECT name FROM agents
|
|
48
|
+
WHERE type != 'ephemeral'
|
|
49
|
+
AND name LIKE '%-%'
|
|
50
|
+
AND name NOT GLOB '*-*-[0-9]*'
|
|
51
|
+
`).all();
|
|
52
|
+
const updateStmt = db.prepare("UPDATE agents SET type = 'ephemeral' WHERE name = ?");
|
|
53
|
+
for (const agent of potentialEphemeral) {
|
|
54
|
+
if (isEphemeralAgentName(agent.name)) {
|
|
55
|
+
updateStmt.run(agent.name);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Get the database path for a workspace
|
|
61
|
+
*/
|
|
62
|
+
export function getDatabasePath(workspacePath) {
|
|
63
|
+
return path.join(workspacePath, '.proletariat', 'workspace.db');
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get the config path for a workspace
|
|
67
|
+
*/
|
|
68
|
+
export function getConfigPath(workspacePath) {
|
|
69
|
+
return path.join(workspacePath, '.proletariat', 'config.json');
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Open workspace database connection.
|
|
73
|
+
*
|
|
74
|
+
* Safety features (PRLT-1081):
|
|
75
|
+
* - Creates a rotating backup before opening (keeps last 5)
|
|
76
|
+
* - Enables WAL journal mode for corruption resistance
|
|
77
|
+
* - Runs a quick integrity check; auto-repairs if corruption detected
|
|
78
|
+
*/
|
|
79
|
+
export function openWorkspaceDatabase(workspacePath) {
|
|
80
|
+
const dbPath = getDatabasePath(workspacePath);
|
|
81
|
+
if (!fs.existsSync(dbPath)) {
|
|
82
|
+
throw new Error(`Database not found: ${dbPath}. Run 'prlt new' first.`);
|
|
83
|
+
}
|
|
84
|
+
// Auto-backup before opening (cheap insurance against corruption)
|
|
85
|
+
createRotatingBackup(dbPath);
|
|
86
|
+
let db;
|
|
87
|
+
try {
|
|
88
|
+
db = new Database(dbPath);
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
throwIfNativeBindingError(error, 'openWorkspaceDatabase');
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
// Enable WAL mode — allows concurrent readers with one writer,
|
|
95
|
+
// significantly more resistant to corruption than journal_mode=delete
|
|
96
|
+
enableWALMode(db);
|
|
97
|
+
db.pragma('foreign_keys = ON');
|
|
98
|
+
db.pragma('busy_timeout = 5000');
|
|
99
|
+
// Quick integrity check on startup
|
|
100
|
+
const integrity = quickCheckIntegrity(db);
|
|
101
|
+
if (!integrity.ok) {
|
|
102
|
+
db.close();
|
|
103
|
+
// Attempt auto-repair
|
|
104
|
+
const repair = repairDatabase(dbPath);
|
|
105
|
+
if (!repair.success) {
|
|
106
|
+
throw new Error(`Database corruption detected in ${dbPath}.\n` +
|
|
107
|
+
`Integrity errors: ${integrity.errors.join('; ')}\n` +
|
|
108
|
+
`Auto-repair failed: ${repair.message}\n` +
|
|
109
|
+
`Run 'prlt db repair' for manual recovery options.`);
|
|
110
|
+
}
|
|
111
|
+
// Re-open the repaired database
|
|
112
|
+
try {
|
|
113
|
+
db = new Database(dbPath);
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
throwIfNativeBindingError(error, 'openWorkspaceDatabase (post-repair)');
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
enableWALMode(db);
|
|
120
|
+
db.pragma('foreign_keys = ON');
|
|
121
|
+
db.pragma('busy_timeout = 5000');
|
|
122
|
+
}
|
|
123
|
+
runDrizzleMigrations(db, ALL_MIGRATIONS);
|
|
124
|
+
ensureEphemeralAgentTypes(db);
|
|
125
|
+
return db;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Open workspace database and return a DatabaseDriver.
|
|
129
|
+
* Preferred over openWorkspaceDatabase for new code.
|
|
130
|
+
*/
|
|
131
|
+
export function openWorkspaceDriver(workspacePath) {
|
|
132
|
+
const db = openWorkspaceDatabase(workspacePath);
|
|
133
|
+
return new BetterSqlite3Driver(db);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Create and initialize workspace database
|
|
137
|
+
*/
|
|
138
|
+
export function createWorkspaceDatabase(workspacePath, type, workspaceName, hasPMO = false) {
|
|
139
|
+
const dbPath = getDatabasePath(workspacePath);
|
|
140
|
+
const configPath = getConfigPath(workspacePath);
|
|
141
|
+
const proletariatDir = path.dirname(dbPath);
|
|
142
|
+
if (!fs.existsSync(proletariatDir)) {
|
|
143
|
+
fs.mkdirSync(proletariatDir, { recursive: true });
|
|
144
|
+
}
|
|
145
|
+
const bootstrapConfig = {
|
|
146
|
+
version: "1.0.0",
|
|
147
|
+
schemaVersion: 1
|
|
148
|
+
};
|
|
149
|
+
fs.writeFileSync(configPath, JSON.stringify(bootstrapConfig, null, 2));
|
|
150
|
+
let db;
|
|
151
|
+
try {
|
|
152
|
+
db = new Database(dbPath);
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
throwIfNativeBindingError(error, 'createWorkspaceDatabase');
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
enableWALMode(db);
|
|
159
|
+
db.pragma('foreign_keys = ON');
|
|
160
|
+
runDrizzleMigrations(db, ALL_MIGRATIONS);
|
|
161
|
+
const ddb = createDrizzleConnection(db);
|
|
162
|
+
ddb.insert(workspaceTable).values({
|
|
163
|
+
id: 1,
|
|
164
|
+
type,
|
|
165
|
+
workspaceName,
|
|
166
|
+
hasPmo: hasPMO,
|
|
167
|
+
createdAt: new Date().toISOString(),
|
|
168
|
+
}).run();
|
|
169
|
+
return db;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Get workspace configuration
|
|
173
|
+
*/
|
|
174
|
+
export function getWorkspaceConfig(workspacePath) {
|
|
175
|
+
try {
|
|
176
|
+
return withDrizzle(workspacePath, (ddb) => {
|
|
177
|
+
const row = ddb.select().from(workspaceTable).limit(1).get();
|
|
178
|
+
if (!row)
|
|
179
|
+
return null;
|
|
180
|
+
return {
|
|
181
|
+
id: row.id ?? 1,
|
|
182
|
+
type: row.type,
|
|
183
|
+
workspace_name: row.workspaceName,
|
|
184
|
+
has_pmo: Boolean(row.hasPmo),
|
|
185
|
+
active_theme_id: row.activeThemeId,
|
|
186
|
+
created_at: row.createdAt,
|
|
187
|
+
};
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../../src/lib/database/workspace.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worktree Database Operations
|
|
3
|
+
*
|
|
4
|
+
* Query operations for agent worktrees.
|
|
5
|
+
*/
|
|
6
|
+
export interface AgentWorktree {
|
|
7
|
+
agent_name: string;
|
|
8
|
+
repo_name: string;
|
|
9
|
+
worktree_path: string;
|
|
10
|
+
branch: string;
|
|
11
|
+
created_at: string;
|
|
12
|
+
last_commit_hash?: string;
|
|
13
|
+
commits_ahead: number;
|
|
14
|
+
is_clean: boolean;
|
|
15
|
+
last_checked?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Get worktrees for a specific agent
|
|
19
|
+
*/
|
|
20
|
+
export declare function getAgentWorktrees(workspacePath: string, agentName: string): AgentWorktree[];
|
|
21
|
+
/**
|
|
22
|
+
* Find agent worktrees matching a branch pattern (case-insensitive LIKE).
|
|
23
|
+
*/
|
|
24
|
+
export declare function findWorktreesByBranch(workspacePath: string, branchPattern: string): AgentWorktree[];
|
|
25
|
+
/**
|
|
26
|
+
* Get agent worktrees for a specific repository.
|
|
27
|
+
*/
|
|
28
|
+
export declare function getWorktreesForRepo(workspacePath: string, repoName: string): Array<{
|
|
29
|
+
agent_name: string;
|
|
30
|
+
is_clean: number;
|
|
31
|
+
commits_ahead: number;
|
|
32
|
+
branch: string;
|
|
33
|
+
}>;
|