@proletariat/cli 0.3.16 → 0.3.18
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/action/create.d.ts +1 -0
- package/dist/commands/action/create.js +74 -38
- package/dist/commands/action/delete.d.ts +1 -0
- package/dist/commands/action/delete.js +23 -24
- package/dist/commands/action/index.d.ts +1 -0
- package/dist/commands/action/index.js +5 -10
- package/dist/commands/action/list.d.ts +1 -0
- package/dist/commands/action/list.js +3 -1
- package/dist/commands/action/run.d.ts +1 -0
- package/dist/commands/action/run.js +44 -32
- package/dist/commands/action/show.d.ts +2 -0
- package/dist/commands/action/update.d.ts +1 -0
- package/dist/commands/action/update.js +80 -39
- package/dist/commands/agent/auth.d.ts +2 -0
- package/dist/commands/agent/auth.js +44 -3
- package/dist/commands/agent/discover.d.ts +2 -0
- package/dist/commands/agent/discover.js +35 -3
- package/dist/commands/agent/index.d.ts +1 -0
- package/dist/commands/agent/index.js +25 -45
- package/dist/commands/agent/list.d.ts +8 -3
- package/dist/commands/agent/list.js +16 -29
- package/dist/commands/agent/login.d.ts +1 -0
- package/dist/commands/agent/login.js +14 -32
- package/dist/commands/agent/rebuild.d.ts +1 -0
- package/dist/commands/agent/rebuild.js +2 -2
- package/dist/commands/agent/remove.d.ts +17 -0
- package/dist/commands/agent/remove.js +144 -0
- package/dist/commands/agent/restart.d.ts +1 -0
- package/dist/commands/agent/restart.js +2 -2
- package/dist/commands/agent/shell.d.ts +1 -0
- package/dist/commands/agent/shell.js +63 -76
- package/dist/commands/agent/staff/add.d.ts +1 -0
- package/dist/commands/agent/staff/add.js +7 -1
- package/dist/commands/agent/staff/index.d.ts +1 -0
- package/dist/commands/agent/staff/index.js +5 -4
- package/dist/commands/agent/staff/remove.d.ts +1 -0
- package/dist/commands/agent/status.d.ts +1 -0
- package/dist/commands/agent/status.js +11 -23
- package/dist/commands/agent/temp/cleanup.d.ts +1 -0
- package/dist/commands/agent/temp/index.d.ts +1 -0
- package/dist/commands/agent/temp/index.js +4 -3
- package/dist/commands/agent/themes/index.d.ts +1 -0
- package/dist/commands/agent/themes/index.js +9 -3
- package/dist/commands/agent/themes/set.d.ts +1 -0
- package/dist/commands/agent/themes/set.js +7 -1
- package/dist/commands/agent/visit.d.ts +1 -0
- package/dist/commands/agent/visit.js +11 -23
- package/dist/commands/autocomplete/setup.d.ts +11 -0
- package/dist/commands/autocomplete/setup.js +113 -8
- package/dist/commands/board/index.d.ts +4 -0
- package/dist/commands/board/index.js +32 -30
- package/dist/commands/board/watch.d.ts +2 -0
- package/dist/commands/branch/create.d.ts +1 -0
- package/dist/commands/branch/create.js +33 -41
- package/dist/commands/branch/index.d.ts +1 -0
- package/dist/commands/branch/list.d.ts +2 -0
- package/dist/commands/branch/validate.d.ts +2 -0
- package/dist/commands/branch/where.d.ts +1 -0
- package/dist/commands/claude.d.ts +6 -0
- package/dist/commands/claude.js +166 -116
- package/dist/commands/commit.d.ts +6 -0
- package/dist/commands/commit.js +68 -73
- package/dist/commands/config/index.d.ts +13 -0
- package/dist/commands/config/index.js +142 -98
- package/dist/commands/docker/clean.d.ts +2 -1
- package/dist/commands/docker/clean.js +20 -29
- package/dist/commands/docker/index.d.ts +1 -0
- package/dist/commands/docker/index.js +37 -41
- package/dist/commands/docker/prune.d.ts +2 -1
- package/dist/commands/docker/prune.js +20 -27
- package/dist/commands/docker/restart.d.ts +2 -1
- package/dist/commands/docker/restart.js +20 -29
- package/dist/commands/docker/stop.d.ts +2 -1
- package/dist/commands/docker/stop.js +20 -29
- package/dist/commands/epic/activate.d.ts +1 -0
- package/dist/commands/epic/archive.d.ts +1 -0
- package/dist/commands/epic/create.d.ts +1 -0
- package/dist/commands/epic/index.d.ts +1 -0
- package/dist/commands/epic/link/block.d.ts +1 -0
- package/dist/commands/epic/link/duplicates.d.ts +1 -0
- package/dist/commands/epic/link/index.d.ts +1 -0
- package/dist/commands/epic/link/relates.d.ts +1 -0
- package/dist/commands/epic/link/remove.d.ts +1 -0
- package/dist/commands/epic/list.d.ts +2 -0
- package/dist/commands/epic/move.d.ts +1 -0
- package/dist/commands/epic/progress.d.ts +1 -0
- package/dist/commands/epic/project.d.ts +1 -0
- package/dist/commands/epic/reorder.d.ts +1 -0
- package/dist/commands/epic/spec.d.ts +1 -0
- package/dist/commands/epic/ticket.d.ts +1 -0
- package/dist/commands/epic/view.d.ts +1 -0
- package/dist/commands/execution/index.d.ts +1 -0
- package/dist/commands/execution/index.js +9 -25
- package/dist/commands/execution/list.d.ts +2 -0
- package/dist/commands/execution/logs.d.ts +1 -0
- package/dist/commands/execution/logs.js +6 -16
- package/dist/commands/execution/stop.d.ts +1 -0
- package/dist/commands/execution/stop.js +4 -15
- package/dist/commands/gh/index.d.ts +1 -0
- package/dist/commands/gh/index.js +27 -27
- package/dist/commands/gh/login.d.ts +4 -0
- package/dist/commands/gh/login.js +31 -0
- package/dist/commands/gh/status.d.ts +4 -0
- package/dist/commands/gh/status.js +27 -4
- package/dist/commands/gh/token.d.ts +4 -0
- package/dist/commands/gh/token.js +49 -5
- package/dist/commands/phase/create.d.ts +1 -1
- package/dist/commands/phase/create.js +116 -74
- package/dist/commands/phase/delete.d.ts +1 -0
- package/dist/commands/phase/delete.js +23 -22
- package/dist/commands/phase/list.d.ts +1 -0
- package/dist/commands/phase/list.js +3 -5
- package/dist/commands/phase/move.d.ts +1 -0
- package/dist/commands/phase/move.js +39 -39
- package/dist/commands/phase/template/apply.d.ts +1 -0
- package/dist/commands/phase/template/create.d.ts +2 -0
- package/dist/commands/phase/template/delete.d.ts +1 -0
- package/dist/commands/phase/template/index.d.ts +1 -0
- package/dist/commands/phase/template/list.d.ts +1 -0
- package/dist/commands/phase/template/update.d.ts +2 -0
- package/dist/commands/phase/update.d.ts +1 -1
- package/dist/commands/phase/update.js +89 -55
- package/dist/commands/pmo/init.d.ts +2 -0
- package/dist/commands/pmo/init.js +84 -22
- package/dist/commands/pr/create.d.ts +12 -3
- package/dist/commands/pr/create.js +130 -147
- package/dist/commands/pr/index.d.ts +6 -3
- package/dist/commands/pr/index.js +41 -39
- package/dist/commands/pr/link.d.ts +7 -3
- package/dist/commands/pr/link.js +126 -150
- package/dist/commands/pr/status.d.ts +6 -3
- package/dist/commands/pr/status.js +101 -126
- package/dist/commands/project/archive.d.ts +1 -0
- package/dist/commands/project/archive.js +15 -20
- package/dist/commands/project/create.d.ts +1 -0
- package/dist/commands/project/create.js +13 -5
- package/dist/commands/project/delete.d.ts +1 -0
- package/dist/commands/project/delete.js +14 -28
- package/dist/commands/project/index.d.ts +1 -0
- package/dist/commands/project/index.js +0 -5
- package/dist/commands/project/list.d.ts +2 -0
- package/dist/commands/project/list.js +21 -3
- package/dist/commands/project/spec.d.ts +1 -0
- package/dist/commands/project/spec.js +17 -23
- package/dist/commands/project/unarchive.d.ts +2 -0
- package/dist/commands/project/unarchive.js +21 -2
- package/dist/commands/project/view.d.ts +1 -0
- package/dist/commands/project/view.js +34 -22
- package/dist/commands/repo/add.d.ts +2 -0
- package/dist/commands/repo/add.js +44 -1
- package/dist/commands/repo/index.d.ts +1 -0
- package/dist/commands/repo/index.js +20 -38
- package/dist/commands/repo/list.d.ts +2 -0
- package/dist/commands/repo/remove.d.ts +1 -0
- package/dist/commands/repo/remove.js +45 -63
- package/dist/commands/repo/view.d.ts +2 -0
- package/dist/commands/repo/view.js +30 -5
- package/dist/commands/roadmap/add-project.d.ts +1 -0
- package/dist/commands/roadmap/create.d.ts +1 -0
- package/dist/commands/roadmap/delete.d.ts +1 -0
- package/dist/commands/roadmap/generate.d.ts +1 -0
- package/dist/commands/roadmap/index.d.ts +1 -0
- package/dist/commands/roadmap/list.d.ts +2 -0
- package/dist/commands/roadmap/remove-project.d.ts +1 -0
- package/dist/commands/roadmap/reorder.d.ts +1 -0
- package/dist/commands/roadmap/update.d.ts +1 -0
- package/dist/commands/roadmap/view.d.ts +1 -0
- package/dist/commands/session/attach.d.ts +1 -0
- package/dist/commands/session/index.d.ts +1 -0
- package/dist/commands/session/index.js +8 -25
- package/dist/commands/session/list.d.ts +2 -0
- package/dist/commands/spec/create.d.ts +1 -1
- package/dist/commands/spec/create.js +64 -65
- package/dist/commands/spec/index.d.ts +1 -0
- package/dist/commands/spec/index.js +36 -22
- package/dist/commands/spec/link/depends.d.ts +1 -0
- package/dist/commands/spec/link/depends.js +6 -6
- package/dist/commands/spec/link/duplicates.d.ts +1 -0
- package/dist/commands/spec/link/duplicates.js +6 -6
- package/dist/commands/spec/link/index.d.ts +2 -1
- package/dist/commands/spec/link/index.js +0 -4
- package/dist/commands/spec/link/relates.d.ts +1 -0
- package/dist/commands/spec/link/relates.js +6 -6
- package/dist/commands/spec/link/remove.d.ts +2 -1
- package/dist/commands/spec/link/remove.js +6 -6
- package/dist/commands/spec/list.d.ts +2 -0
- package/dist/commands/spec/list.js +25 -0
- package/dist/commands/spec/plan.d.ts +2 -1
- package/dist/commands/spec/plan.js +19 -26
- package/dist/commands/spec/ticket.d.ts +2 -1
- package/dist/commands/spec/ticket.js +48 -34
- package/dist/commands/spec/view.d.ts +2 -1
- package/dist/commands/spec/view.js +25 -16
- package/dist/commands/status/create.d.ts +1 -1
- package/dist/commands/status/create.js +80 -64
- package/dist/commands/status/delete.d.ts +2 -1
- package/dist/commands/status/delete.js +26 -22
- package/dist/commands/status/index.d.ts +1 -0
- package/dist/commands/status/index.js +26 -19
- package/dist/commands/status/list.d.ts +1 -0
- package/dist/commands/status/list.js +12 -7
- package/dist/commands/status/move.d.ts +2 -1
- package/dist/commands/status/move.js +62 -61
- package/dist/commands/status/update.d.ts +2 -2
- package/dist/commands/status/update.js +110 -77
- package/dist/commands/template/delete.d.ts +1 -0
- package/dist/commands/template/delete.js +47 -48
- package/dist/commands/template/index.d.ts +1 -0
- package/dist/commands/template/index.js +26 -33
- package/dist/commands/template/list.d.ts +1 -0
- package/dist/commands/template/phase/create.d.ts +1 -0
- package/dist/commands/template/phase/create.js +6 -0
- package/dist/commands/template/phase/index.d.ts +1 -0
- package/dist/commands/template/phase/index.js +27 -26
- package/dist/commands/template/phase/update.d.ts +1 -0
- package/dist/commands/template/phase/update.js +6 -0
- package/dist/commands/template/ticket/index.d.ts +1 -0
- package/dist/commands/template/ticket/index.js +27 -26
- package/dist/commands/template/ticket/save.d.ts +1 -0
- package/dist/commands/template/ticket/save.js +6 -0
- package/dist/commands/terminal/title.d.ts +26 -0
- package/dist/commands/terminal/title.js +37 -3
- package/dist/commands/ticket/bulk.d.ts +1 -0
- package/dist/commands/ticket/complete.d.ts +1 -0
- package/dist/commands/ticket/complete.js +18 -14
- package/dist/commands/ticket/create.d.ts +1 -0
- package/dist/commands/ticket/create.js +45 -41
- package/dist/commands/ticket/delete.d.ts +1 -0
- package/dist/commands/ticket/delete.js +1 -1
- package/dist/commands/ticket/edit.d.ts +1 -0
- package/dist/commands/ticket/edit.js +1 -1
- package/dist/commands/ticket/epic.d.ts +1 -0
- package/dist/commands/ticket/epic.js +2 -2
- package/dist/commands/ticket/index.d.ts +1 -0
- package/dist/commands/ticket/link/block.d.ts +1 -0
- package/dist/commands/ticket/link/block.js +1 -1
- package/dist/commands/ticket/link/duplicates.d.ts +1 -0
- package/dist/commands/ticket/link/duplicates.js +1 -1
- package/dist/commands/ticket/link/index.d.ts +1 -0
- package/dist/commands/ticket/link/index.js +9 -8
- package/dist/commands/ticket/link/relates.d.ts +1 -0
- package/dist/commands/ticket/link/relates.js +1 -1
- package/dist/commands/ticket/link/remove.d.ts +1 -0
- package/dist/commands/ticket/link/remove.js +1 -1
- package/dist/commands/ticket/list.d.ts +2 -0
- package/dist/commands/ticket/move.d.ts +1 -0
- package/dist/commands/ticket/move.js +27 -19
- package/dist/commands/ticket/project.d.ts +1 -0
- package/dist/commands/ticket/project.js +3 -3
- package/dist/commands/ticket/reassign.d.ts +1 -0
- package/dist/commands/ticket/reassign.js +1 -1
- package/dist/commands/ticket/spec.d.ts +1 -0
- package/dist/commands/ticket/spec.js +3 -3
- package/dist/commands/ticket/status.d.ts +1 -0
- package/dist/commands/ticket/status.js +1 -1
- package/dist/commands/ticket/template/apply.d.ts +1 -0
- package/dist/commands/ticket/template/create.d.ts +2 -0
- package/dist/commands/ticket/template/delete.d.ts +1 -0
- package/dist/commands/ticket/template/index.d.ts +1 -0
- package/dist/commands/ticket/template/list.d.ts +1 -0
- package/dist/commands/ticket/template/save.d.ts +2 -0
- package/dist/commands/ticket/update.d.ts +1 -0
- package/dist/commands/ticket/update.js +1 -1
- package/dist/commands/ticket/view.d.ts +1 -0
- package/dist/commands/ticket/view.js +1 -1
- package/dist/commands/work/complete.d.ts +1 -0
- package/dist/commands/work/index.d.ts +1 -0
- package/dist/commands/work/ready.d.ts +1 -0
- package/dist/commands/work/revise.d.ts +1 -0
- package/dist/commands/work/spawn-all.d.ts +2 -0
- package/dist/commands/work/spawn-all.js +11 -4
- package/dist/commands/work/spawn.d.ts +1 -0
- package/dist/commands/work/spawn.js +261 -166
- package/dist/commands/work/start.d.ts +1 -0
- package/dist/commands/work/start.js +270 -189
- package/dist/commands/work/watch.d.ts +1 -0
- package/dist/commands/work/watch.js +63 -58
- package/dist/commands/workflow/create.d.ts +1 -0
- package/dist/commands/workflow/create.js +2 -4
- package/dist/commands/workflow/delete.d.ts +1 -0
- package/dist/commands/workflow/delete.js +21 -33
- package/dist/commands/workflow/index.d.ts +1 -0
- package/dist/commands/workflow/list.d.ts +1 -0
- package/dist/commands/workflow/list.js +3 -6
- package/dist/commands/workflow/switch.d.ts +2 -0
- package/dist/commands/workflow/switch.js +46 -21
- package/dist/commands/workflow/view.d.ts +1 -0
- package/dist/commands/workflow/view.js +18 -27
- package/dist/commands/workspace/remove.d.ts +2 -2
- package/dist/commands/workspace/remove.js +16 -21
- package/dist/commands/workspace/use.d.ts +2 -2
- package/dist/commands/workspace/use.js +12 -18
- package/dist/lib/agents/commands.d.ts +1 -1
- package/dist/lib/agents/commands.js +4 -4
- package/dist/lib/database/drizzle-schema.d.ts +5009 -0
- package/dist/lib/database/drizzle-schema.js +699 -0
- package/dist/lib/database/drizzle.d.ts +29 -0
- package/dist/lib/database/drizzle.js +37 -0
- package/dist/lib/database/index.d.ts +1 -0
- package/dist/lib/database/index.js +1 -1
- package/dist/lib/execution/config.d.ts +6 -0
- package/dist/lib/execution/config.js +31 -13
- package/dist/lib/execution/devcontainer.js +13 -7
- package/dist/lib/execution/runners.js +24 -7
- package/dist/lib/execution/spawner.js +19 -0
- package/dist/lib/flags/index.d.ts +4 -0
- package/dist/lib/flags/index.js +4 -0
- package/dist/lib/flags/resolver.d.ts +224 -0
- package/dist/lib/flags/resolver.js +313 -0
- package/dist/lib/pmo/base-command.d.ts +53 -3
- package/dist/lib/pmo/base-command.js +92 -13
- package/dist/lib/pmo/find-pmo.d.ts +1 -1
- package/dist/lib/pmo/find-pmo.js +4 -4
- package/dist/lib/pmo/index.d.ts +1 -1
- package/dist/lib/pmo/index.js +1 -1
- package/dist/lib/pmo/storage/helpers.js +2 -1
- package/dist/lib/pmo/storage/index.d.ts +9 -0
- package/dist/lib/pmo/storage/index.js +14 -0
- package/dist/lib/pmo/storage/projects.d.ts +28 -13
- package/dist/lib/pmo/storage/projects.js +110 -34
- package/dist/lib/pmo/storage/roadmaps.d.ts +2 -0
- package/dist/lib/pmo/storage/roadmaps.js +182 -111
- package/dist/lib/pmo/storage/specs.js +13 -16
- package/dist/lib/pmo/storage/subtasks.js +17 -2
- package/dist/lib/pmo/storage/tickets.d.ts +12 -2
- package/dist/lib/pmo/storage/tickets.js +63 -5
- package/dist/lib/pmo/storage/types.d.ts +7 -3
- package/dist/lib/pmo/storage/views.d.ts +12 -1
- package/dist/lib/pmo/storage/views.js +61 -6
- package/dist/lib/prompt-command.d.ts +90 -0
- package/dist/lib/prompt-command.js +102 -0
- package/dist/lib/prompt-json.d.ts +34 -4
- package/dist/lib/prompt-json.js +35 -3
- package/dist/lib/repos/index.js +15 -15
- package/dist/lib/workspace.d.ts +4 -3
- package/dist/lib/workspace.js +3 -3
- package/oclif.manifest.json +4610 -2997
- package/package.json +13 -5
|
@@ -3,8 +3,12 @@
|
|
|
3
3
|
*
|
|
4
4
|
* This is the main facade that delegates to domain-specific storage modules.
|
|
5
5
|
* Uses the unified workspace.db database with pmo_ prefixed tables.
|
|
6
|
+
*
|
|
7
|
+
* This module now supports Drizzle ORM for type-safe queries while maintaining
|
|
8
|
+
* backward compatibility with raw SQL queries during the migration period.
|
|
6
9
|
*/
|
|
7
10
|
import Database from 'better-sqlite3';
|
|
11
|
+
import { createDrizzleConnection } from '../../database/drizzle.js';
|
|
8
12
|
import { PMO_TABLES, PMO_SCHEMA_SQL, validateTicketSchema } from '../schema.js';
|
|
9
13
|
import { runMigrations, seedBuiltinWorkflows, seedBuiltinPhases, seedBuiltinPhaseTemplates, seedBuiltinActions, seedBuiltinTicketTemplates, updateBoardTimestamp, } from './base.js';
|
|
10
14
|
import { ProjectStorage } from './projects.js';
|
|
@@ -23,6 +27,7 @@ const T = PMO_TABLES;
|
|
|
23
27
|
export class SQLiteStorage {
|
|
24
28
|
type = 'sqlite';
|
|
25
29
|
db;
|
|
30
|
+
drizzle;
|
|
26
31
|
dbPath;
|
|
27
32
|
// Domain-specific storage modules
|
|
28
33
|
projectStorage;
|
|
@@ -43,10 +48,13 @@ export class SQLiteStorage {
|
|
|
43
48
|
// Open database (creates if doesn't exist)
|
|
44
49
|
this.db = new Database(dbPath);
|
|
45
50
|
this.db.pragma('foreign_keys = ON');
|
|
51
|
+
// Create Drizzle ORM connection wrapping the same database
|
|
52
|
+
this.drizzle = createDrizzleConnection(this.db);
|
|
46
53
|
// Create the storage context shared by all modules
|
|
47
54
|
// Note: projectId is passed explicitly to operations, not stored in context
|
|
48
55
|
const ctx = {
|
|
49
56
|
db: this.db,
|
|
57
|
+
drizzle: this.drizzle,
|
|
50
58
|
updateBoardTimestamp: (projectId) => updateBoardTimestamp(this.db, projectId),
|
|
51
59
|
};
|
|
52
60
|
// Initialize domain-specific storage modules
|
|
@@ -72,6 +80,12 @@ export class SQLiteStorage {
|
|
|
72
80
|
getDatabase() {
|
|
73
81
|
return this.db;
|
|
74
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Get the Drizzle ORM database connection for type-safe queries.
|
|
85
|
+
*/
|
|
86
|
+
getDrizzle() {
|
|
87
|
+
return this.drizzle;
|
|
88
|
+
}
|
|
75
89
|
/**
|
|
76
90
|
* Ensure PMO tables exist in the database.
|
|
77
91
|
*/
|
|
@@ -7,6 +7,19 @@ import { StorageContext } from './types.js';
|
|
|
7
7
|
export declare class ProjectStorage {
|
|
8
8
|
private ctx;
|
|
9
9
|
constructor(ctx: StorageContext);
|
|
10
|
+
/**
|
|
11
|
+
* Resolve a project identifier to its actual ID.
|
|
12
|
+
* Tries multiple strategies:
|
|
13
|
+
* 1. Exact ID match
|
|
14
|
+
* 2. Case-insensitive ID match
|
|
15
|
+
* 3. Exact name match
|
|
16
|
+
* 4. Case-insensitive name match
|
|
17
|
+
* 5. Slugified name match (matches slug of project name)
|
|
18
|
+
*
|
|
19
|
+
* @param identifier - Project ID, name, or slug to resolve
|
|
20
|
+
* @returns The actual project ID, or null if not found
|
|
21
|
+
*/
|
|
22
|
+
resolveProjectId(identifier: string): string | null;
|
|
10
23
|
/**
|
|
11
24
|
* Initialize a project with a workflow.
|
|
12
25
|
* @deprecated Use createProject with a template instead.
|
|
@@ -16,8 +29,10 @@ export declare class ProjectStorage {
|
|
|
16
29
|
* Get the project board.
|
|
17
30
|
* Columns are derived from the project's workflow statuses.
|
|
18
31
|
* Tickets are sorted by priority (P0 first) then created_at (oldest first).
|
|
32
|
+
*
|
|
33
|
+
* @param projectIdOrName - Project ID, name, or slug. Will be resolved to actual ID.
|
|
19
34
|
*/
|
|
20
|
-
getBoard(
|
|
35
|
+
getBoard(projectIdOrName: string): Promise<Board>;
|
|
21
36
|
/**
|
|
22
37
|
* Get the board as markdown.
|
|
23
38
|
*/
|
|
@@ -33,9 +48,9 @@ export declare class ProjectStorage {
|
|
|
33
48
|
description?: string;
|
|
34
49
|
}): Promise<Board>;
|
|
35
50
|
/**
|
|
36
|
-
* Get project board by ID.
|
|
51
|
+
* Get project board by ID, name, or slug.
|
|
37
52
|
*/
|
|
38
|
-
getProjectBoard(
|
|
53
|
+
getProjectBoard(projectIdOrName: string): Promise<Board | null>;
|
|
39
54
|
/**
|
|
40
55
|
* Get tickets for a status (column).
|
|
41
56
|
* Tickets are sorted by priority (P0 first) then created_at (oldest first).
|
|
@@ -52,28 +67,28 @@ export declare class ProjectStorage {
|
|
|
52
67
|
ticketCount: number;
|
|
53
68
|
}>>;
|
|
54
69
|
/**
|
|
55
|
-
* Delete a project.
|
|
70
|
+
* Delete a project by ID, name, or slug.
|
|
56
71
|
*/
|
|
57
|
-
deleteProject(
|
|
72
|
+
deleteProject(projectIdOrName: string): Promise<void>;
|
|
58
73
|
/**
|
|
59
|
-
* Get a project by ID.
|
|
74
|
+
* Get a project by ID, name, or slug.
|
|
60
75
|
*/
|
|
61
|
-
getProject(
|
|
76
|
+
getProject(idOrName: string): Promise<Project | null>;
|
|
62
77
|
/**
|
|
63
|
-
* Update a project.
|
|
78
|
+
* Update a project by ID, name, or slug.
|
|
64
79
|
*/
|
|
65
|
-
updateProject(
|
|
80
|
+
updateProject(idOrName: string, changes: Partial<Project>): Promise<Project>;
|
|
66
81
|
/**
|
|
67
82
|
* List projects with optional filter.
|
|
68
83
|
*/
|
|
69
84
|
listProjects(filter?: ProjectFilter): Promise<Project[]>;
|
|
70
85
|
/**
|
|
71
|
-
* Archive a project.
|
|
86
|
+
* Archive a project by ID, name, or slug.
|
|
72
87
|
*/
|
|
73
|
-
archiveProject(
|
|
88
|
+
archiveProject(idOrName: string): Promise<Project>;
|
|
74
89
|
/**
|
|
75
|
-
* Unarchive a project.
|
|
90
|
+
* Unarchive a project by ID, name, or slug.
|
|
76
91
|
*/
|
|
77
|
-
unarchiveProject(
|
|
92
|
+
unarchiveProject(idOrName: string): Promise<Project>;
|
|
78
93
|
private rowToProject;
|
|
79
94
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { PMO_TABLES } from '../schema.js';
|
|
6
6
|
import { PMOError, } from '../types.js';
|
|
7
|
-
import { generateEntityId } from '../utils.js';
|
|
7
|
+
import { generateEntityId, slugify } from '../utils.js';
|
|
8
8
|
import { generateBoardMarkdown } from '../markdown.js';
|
|
9
9
|
import { rowToTicket } from './helpers.js';
|
|
10
10
|
const T = PMO_TABLES;
|
|
@@ -13,6 +13,59 @@ export class ProjectStorage {
|
|
|
13
13
|
constructor(ctx) {
|
|
14
14
|
this.ctx = ctx;
|
|
15
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Resolve a project identifier to its actual ID.
|
|
18
|
+
* Tries multiple strategies:
|
|
19
|
+
* 1. Exact ID match
|
|
20
|
+
* 2. Case-insensitive ID match
|
|
21
|
+
* 3. Exact name match
|
|
22
|
+
* 4. Case-insensitive name match
|
|
23
|
+
* 5. Slugified name match (matches slug of project name)
|
|
24
|
+
*
|
|
25
|
+
* @param identifier - Project ID, name, or slug to resolve
|
|
26
|
+
* @returns The actual project ID, or null if not found
|
|
27
|
+
*/
|
|
28
|
+
resolveProjectId(identifier) {
|
|
29
|
+
if (!identifier)
|
|
30
|
+
return null;
|
|
31
|
+
// 1. Exact ID match
|
|
32
|
+
const exactMatch = this.ctx.db.prepare(`
|
|
33
|
+
SELECT id FROM ${T.projects} WHERE id = ?
|
|
34
|
+
`).get(identifier);
|
|
35
|
+
if (exactMatch)
|
|
36
|
+
return exactMatch.id;
|
|
37
|
+
// 2. Case-insensitive ID match
|
|
38
|
+
const caseInsensitiveId = this.ctx.db.prepare(`
|
|
39
|
+
SELECT id FROM ${T.projects} WHERE LOWER(id) = LOWER(?)
|
|
40
|
+
`).get(identifier);
|
|
41
|
+
if (caseInsensitiveId)
|
|
42
|
+
return caseInsensitiveId.id;
|
|
43
|
+
// 3. Exact name match
|
|
44
|
+
const nameMatch = this.ctx.db.prepare(`
|
|
45
|
+
SELECT id FROM ${T.projects} WHERE name = ?
|
|
46
|
+
`).get(identifier);
|
|
47
|
+
if (nameMatch)
|
|
48
|
+
return nameMatch.id;
|
|
49
|
+
// 4. Case-insensitive name match
|
|
50
|
+
const caseInsensitiveName = this.ctx.db.prepare(`
|
|
51
|
+
SELECT id FROM ${T.projects} WHERE LOWER(name) = LOWER(?)
|
|
52
|
+
`).get(identifier);
|
|
53
|
+
if (caseInsensitiveName)
|
|
54
|
+
return caseInsensitiveName.id;
|
|
55
|
+
// 5. Slugified name match - check if identifier is a slug of any project name
|
|
56
|
+
// Get all projects and compare slugified names
|
|
57
|
+
const allProjects = this.ctx.db.prepare(`
|
|
58
|
+
SELECT id, name FROM ${T.projects}
|
|
59
|
+
`).all();
|
|
60
|
+
const identifierLower = identifier.toLowerCase();
|
|
61
|
+
for (const project of allProjects) {
|
|
62
|
+
const projectSlug = slugify(project.name);
|
|
63
|
+
if (projectSlug === identifierLower || projectSlug === identifier) {
|
|
64
|
+
return project.id;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
16
69
|
/**
|
|
17
70
|
* Initialize a project with a workflow.
|
|
18
71
|
* @deprecated Use createProject with a template instead.
|
|
@@ -31,14 +84,21 @@ export class ProjectStorage {
|
|
|
31
84
|
* Get the project board.
|
|
32
85
|
* Columns are derived from the project's workflow statuses.
|
|
33
86
|
* Tickets are sorted by priority (P0 first) then created_at (oldest first).
|
|
87
|
+
*
|
|
88
|
+
* @param projectIdOrName - Project ID, name, or slug. Will be resolved to actual ID.
|
|
34
89
|
*/
|
|
35
|
-
async getBoard(
|
|
36
|
-
//
|
|
90
|
+
async getBoard(projectIdOrName) {
|
|
91
|
+
// Resolve project identifier to actual ID
|
|
92
|
+
const resolvedId = this.resolveProjectId(projectIdOrName);
|
|
93
|
+
if (!resolvedId) {
|
|
94
|
+
throw new PMOError('NOT_FOUND', `Project not found: ${projectIdOrName}. Run init() first.`);
|
|
95
|
+
}
|
|
96
|
+
// Get project metadata with workflow using resolved ID
|
|
37
97
|
const projectRow = this.ctx.db.prepare(`
|
|
38
98
|
SELECT id, name, workflow_id, updated_at FROM ${T.projects} WHERE id = ?
|
|
39
|
-
`).get(
|
|
99
|
+
`).get(resolvedId);
|
|
40
100
|
if (!projectRow) {
|
|
41
|
-
throw new PMOError('NOT_FOUND', `Project not found: ${
|
|
101
|
+
throw new PMOError('NOT_FOUND', `Project not found: ${projectIdOrName}. Run init() first.`);
|
|
42
102
|
}
|
|
43
103
|
// Get workflow statuses as columns
|
|
44
104
|
const workflowId = projectRow.workflow_id || 'default';
|
|
@@ -53,7 +113,7 @@ export class ProjectStorage {
|
|
|
53
113
|
name: status.name,
|
|
54
114
|
position: status.position,
|
|
55
115
|
status: status.category,
|
|
56
|
-
tickets: await this.getTicketsForStatus(status.id,
|
|
116
|
+
tickets: await this.getTicketsForStatus(status.id, resolvedId),
|
|
57
117
|
})));
|
|
58
118
|
return {
|
|
59
119
|
id: projectRow.id,
|
|
@@ -91,12 +151,17 @@ export class ProjectStorage {
|
|
|
91
151
|
return this.getBoard(id);
|
|
92
152
|
}
|
|
93
153
|
/**
|
|
94
|
-
* Get project board by ID.
|
|
154
|
+
* Get project board by ID, name, or slug.
|
|
95
155
|
*/
|
|
96
|
-
async getProjectBoard(
|
|
156
|
+
async getProjectBoard(projectIdOrName) {
|
|
157
|
+
// Resolve project identifier to actual ID
|
|
158
|
+
const resolvedId = this.resolveProjectId(projectIdOrName);
|
|
159
|
+
if (!resolvedId) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
97
162
|
const projectRow = this.ctx.db.prepare(`
|
|
98
163
|
SELECT id, name, template, description, workflow_id, updated_at FROM ${T.projects} WHERE id = ?
|
|
99
|
-
`).get(
|
|
164
|
+
`).get(resolvedId);
|
|
100
165
|
if (!projectRow) {
|
|
101
166
|
return null;
|
|
102
167
|
}
|
|
@@ -112,7 +177,7 @@ export class ProjectStorage {
|
|
|
112
177
|
name: status.name,
|
|
113
178
|
position: status.position,
|
|
114
179
|
status: status.category,
|
|
115
|
-
tickets: await this.getTicketsForStatus(status.id,
|
|
180
|
+
tickets: await this.getTicketsForStatus(status.id, resolvedId),
|
|
116
181
|
})));
|
|
117
182
|
return {
|
|
118
183
|
id: projectRow.id,
|
|
@@ -165,35 +230,46 @@ export class ProjectStorage {
|
|
|
165
230
|
}));
|
|
166
231
|
}
|
|
167
232
|
/**
|
|
168
|
-
* Delete a project.
|
|
233
|
+
* Delete a project by ID, name, or slug.
|
|
169
234
|
*/
|
|
170
|
-
async deleteProject(
|
|
171
|
-
|
|
235
|
+
async deleteProject(projectIdOrName) {
|
|
236
|
+
// Resolve project identifier to actual ID
|
|
237
|
+
const resolvedId = this.resolveProjectId(projectIdOrName);
|
|
238
|
+
if (!resolvedId) {
|
|
239
|
+
throw new PMOError('NOT_FOUND', `Project not found: ${projectIdOrName}`);
|
|
240
|
+
}
|
|
241
|
+
if (resolvedId === 'default') {
|
|
172
242
|
throw new PMOError('INVALID', 'Cannot delete the default project');
|
|
173
243
|
}
|
|
174
|
-
const result = this.ctx.db.prepare(`DELETE FROM ${T.projects} WHERE id = ?`).run(
|
|
244
|
+
const result = this.ctx.db.prepare(`DELETE FROM ${T.projects} WHERE id = ?`).run(resolvedId);
|
|
175
245
|
if (result.changes === 0) {
|
|
176
|
-
throw new PMOError('NOT_FOUND', `Project not found: ${
|
|
246
|
+
throw new PMOError('NOT_FOUND', `Project not found: ${projectIdOrName}`);
|
|
177
247
|
}
|
|
178
248
|
// Tickets are deleted via CASCADE
|
|
179
249
|
}
|
|
180
250
|
/**
|
|
181
|
-
* Get a project by ID.
|
|
251
|
+
* Get a project by ID, name, or slug.
|
|
182
252
|
*/
|
|
183
|
-
async getProject(
|
|
184
|
-
|
|
253
|
+
async getProject(idOrName) {
|
|
254
|
+
// Resolve project identifier to actual ID
|
|
255
|
+
const resolvedId = this.resolveProjectId(idOrName);
|
|
256
|
+
if (!resolvedId)
|
|
257
|
+
return null;
|
|
258
|
+
const row = this.ctx.db.prepare(`SELECT * FROM ${T.projects} WHERE id = ?`).get(resolvedId);
|
|
185
259
|
if (!row)
|
|
186
260
|
return null;
|
|
187
261
|
return this.rowToProject(row);
|
|
188
262
|
}
|
|
189
263
|
/**
|
|
190
|
-
* Update a project.
|
|
264
|
+
* Update a project by ID, name, or slug.
|
|
191
265
|
*/
|
|
192
|
-
async updateProject(
|
|
193
|
-
const existing = await this.getProject(
|
|
266
|
+
async updateProject(idOrName, changes) {
|
|
267
|
+
const existing = await this.getProject(idOrName);
|
|
194
268
|
if (!existing) {
|
|
195
|
-
throw new PMOError('NOT_FOUND', `Project not found: ${
|
|
269
|
+
throw new PMOError('NOT_FOUND', `Project not found: ${idOrName}`);
|
|
196
270
|
}
|
|
271
|
+
// Use the resolved ID for the update
|
|
272
|
+
const resolvedId = existing.id;
|
|
197
273
|
const updates = ['updated_at = ?'];
|
|
198
274
|
const params = [Date.now()];
|
|
199
275
|
if (changes.name !== undefined) {
|
|
@@ -224,9 +300,9 @@ export class ProjectStorage {
|
|
|
224
300
|
updates.push('target_date = ?');
|
|
225
301
|
params.push(changes.targetDate ? changes.targetDate.toISOString() : null);
|
|
226
302
|
}
|
|
227
|
-
params.push(
|
|
303
|
+
params.push(resolvedId);
|
|
228
304
|
this.ctx.db.prepare(`UPDATE ${T.projects} SET ${updates.join(', ')} WHERE id = ?`).run(...params);
|
|
229
|
-
return (await this.getProject(
|
|
305
|
+
return (await this.getProject(resolvedId));
|
|
230
306
|
}
|
|
231
307
|
/**
|
|
232
308
|
* List projects with optional filter.
|
|
@@ -259,30 +335,30 @@ export class ProjectStorage {
|
|
|
259
335
|
return rows.map((row) => this.rowToProject(row));
|
|
260
336
|
}
|
|
261
337
|
/**
|
|
262
|
-
* Archive a project.
|
|
338
|
+
* Archive a project by ID, name, or slug.
|
|
263
339
|
*/
|
|
264
|
-
async archiveProject(
|
|
265
|
-
const existing = await this.getProject(
|
|
340
|
+
async archiveProject(idOrName) {
|
|
341
|
+
const existing = await this.getProject(idOrName);
|
|
266
342
|
if (!existing) {
|
|
267
|
-
throw new PMOError('NOT_FOUND', `Project not found: ${
|
|
343
|
+
throw new PMOError('NOT_FOUND', `Project not found: ${idOrName}`);
|
|
268
344
|
}
|
|
269
345
|
if (existing.isArchived) {
|
|
270
346
|
return existing;
|
|
271
347
|
}
|
|
272
|
-
return this.updateProject(id, { isArchived: true });
|
|
348
|
+
return this.updateProject(existing.id, { isArchived: true });
|
|
273
349
|
}
|
|
274
350
|
/**
|
|
275
|
-
* Unarchive a project.
|
|
351
|
+
* Unarchive a project by ID, name, or slug.
|
|
276
352
|
*/
|
|
277
|
-
async unarchiveProject(
|
|
278
|
-
const existing = await this.getProject(
|
|
353
|
+
async unarchiveProject(idOrName) {
|
|
354
|
+
const existing = await this.getProject(idOrName);
|
|
279
355
|
if (!existing) {
|
|
280
|
-
throw new PMOError('NOT_FOUND', `Project not found: ${
|
|
356
|
+
throw new PMOError('NOT_FOUND', `Project not found: ${idOrName}`);
|
|
281
357
|
}
|
|
282
358
|
if (!existing.isArchived) {
|
|
283
359
|
return existing;
|
|
284
360
|
}
|
|
285
|
-
return this.updateProject(id, { isArchived: false });
|
|
361
|
+
return this.updateProject(existing.id, { isArchived: false });
|
|
286
362
|
}
|
|
287
363
|
rowToProject(row) {
|
|
288
364
|
return {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Roadmap operations for PMO.
|
|
3
3
|
* Roadmaps are curated collections of projects for documentation/visualization.
|
|
4
|
+
*
|
|
5
|
+
* This module uses Drizzle ORM for type-safe database queries.
|
|
4
6
|
*/
|
|
5
7
|
import { Roadmap, RoadmapProject, RoadmapFilter, Project } from '../types.js';
|
|
6
8
|
import { StorageContext } from './types.js';
|