@proletariat/cli 0.3.76 → 0.3.78

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.
Files changed (49) hide show
  1. package/bin/validate-better-sqlite3.cjs +14 -1
  2. package/dist/commands/orchestrator/start.js +51 -52
  3. package/dist/commands/orchestrator/start.js.map +1 -1
  4. package/dist/commands/pr/create.js +3 -0
  5. package/dist/commands/pr/create.js.map +1 -1
  6. package/dist/commands/repo/add.d.ts +6 -0
  7. package/dist/commands/repo/add.js +52 -0
  8. package/dist/commands/repo/add.js.map +1 -1
  9. package/dist/commands/work/ready.js +3 -0
  10. package/dist/commands/work/ready.js.map +1 -1
  11. package/dist/commands/work/start.js +2 -1
  12. package/dist/commands/work/start.js.map +1 -1
  13. package/dist/lib/database/migrations/0005_provider_status_mapping.d.ts +2 -0
  14. package/dist/lib/database/migrations/0005_provider_status_mapping.js +35 -0
  15. package/dist/lib/database/migrations/0005_provider_status_mapping.js.map +1 -0
  16. package/dist/lib/database/migrations/index.js +2 -0
  17. package/dist/lib/database/migrations/index.js.map +1 -1
  18. package/dist/lib/execution/runners/shared.d.ts +5 -0
  19. package/dist/lib/execution/runners/shared.js +18 -0
  20. package/dist/lib/execution/runners/shared.js.map +1 -1
  21. package/dist/lib/pmo/storage/tickets.d.ts +0 -8
  22. package/dist/lib/pmo/storage/tickets.js +6 -52
  23. package/dist/lib/pmo/storage/tickets.js.map +1 -1
  24. package/dist/lib/pmo/sync-manager.js +13 -2
  25. package/dist/lib/pmo/sync-manager.js.map +1 -1
  26. package/dist/lib/providers/event-emitting-provider.d.ts +64 -0
  27. package/dist/lib/providers/event-emitting-provider.js +129 -0
  28. package/dist/lib/providers/event-emitting-provider.js.map +1 -0
  29. package/dist/lib/providers/index.d.ts +3 -0
  30. package/dist/lib/providers/index.js +3 -0
  31. package/dist/lib/providers/index.js.map +1 -1
  32. package/dist/lib/providers/resolver.d.ts +11 -0
  33. package/dist/lib/providers/resolver.js +85 -6
  34. package/dist/lib/providers/resolver.js.map +1 -1
  35. package/dist/lib/providers/status-mapping.d.ts +64 -0
  36. package/dist/lib/providers/status-mapping.js +136 -0
  37. package/dist/lib/providers/status-mapping.js.map +1 -0
  38. package/dist/lib/providers/trigger-config.d.ts +98 -0
  39. package/dist/lib/providers/trigger-config.js +204 -0
  40. package/dist/lib/providers/trigger-config.js.map +1 -0
  41. package/dist/lib/repos/git.d.ts +68 -0
  42. package/dist/lib/repos/git.js +134 -0
  43. package/dist/lib/repos/git.js.map +1 -1
  44. package/dist/lib/repos/index.js.map +1 -1
  45. package/dist/lib/work-lifecycle/adapter.d.ts +45 -10
  46. package/dist/lib/work-lifecycle/adapter.js +52 -58
  47. package/dist/lib/work-lifecycle/adapter.js.map +1 -1
  48. package/oclif.manifest.json +3642 -3634
  49. package/package.json +2 -2
@@ -4,6 +4,11 @@
4
4
  * Determines which provider should handle ticket operations based on the
5
5
  * ticket's external source metadata or workspace configuration.
6
6
  *
7
+ * All resolved providers are wrapped with EventEmittingProvider, making
8
+ * the adapter layer the central event hub. Every provider (PMO, Linear,
9
+ * Jira, Shortcut, Asana) is an equal peer that emits events through
10
+ * the same mechanism.
11
+ *
7
12
  * Two resolution modes:
8
13
  * 1. Ticket-level: resolveTicketProvider() — for operations on a specific ticket
9
14
  * (move, delete). Uses the ticket's metadata to find the source of truth.
@@ -16,6 +21,68 @@ import { isLinearConfigured } from '../linear/config.js';
16
21
  import { LinearMapper } from '../linear/mapper.js';
17
22
  import { PMOTicketProvider } from './pmo-provider.js';
18
23
  import { LinearTicketProvider } from './linear-provider.js';
24
+ import { EventEmittingProvider } from './event-emitting-provider.js';
25
+ /**
26
+ * Create a StatusResolver backed by the database.
27
+ * Used by EventEmittingProvider to resolve status names/categories
28
+ * for event emission.
29
+ */
30
+ function createDbStatusResolver(db, storage) {
31
+ return {
32
+ resolveStatusByName(projectId, statusName) {
33
+ try {
34
+ const row = db.prepare(`
35
+ SELECT ws.id, ws.name, ws.category
36
+ FROM pmo_workflow_statuses ws
37
+ JOIN pmo_projects p ON p.workflow_id = ws.workflow_id
38
+ WHERE p.id = ? AND LOWER(ws.name) = LOWER(?)
39
+ `).get(projectId, statusName);
40
+ if (row) {
41
+ return { id: row.id, name: row.name, category: row.category };
42
+ }
43
+ // Fallback: search by status ID
44
+ const byId = db.prepare(`
45
+ SELECT id, name, category FROM pmo_workflow_statuses WHERE id = ?
46
+ `).get(statusName);
47
+ if (byId) {
48
+ return { id: byId.id, name: byId.name, category: byId.category };
49
+ }
50
+ }
51
+ catch {
52
+ // Non-fatal: status resolution is best-effort
53
+ }
54
+ return null;
55
+ },
56
+ getTicketStatus(ticketId) {
57
+ try {
58
+ const row = db.prepare(`
59
+ SELECT t.status_id, ws.name, ws.category
60
+ FROM pmo_tickets t
61
+ LEFT JOIN pmo_workflow_statuses ws ON t.status_id = ws.id
62
+ WHERE t.id = ?
63
+ `).get(ticketId);
64
+ if (row) {
65
+ return {
66
+ statusId: row.status_id,
67
+ statusName: row.name,
68
+ statusCategory: row.category ?? null,
69
+ };
70
+ }
71
+ }
72
+ catch {
73
+ // Non-fatal: status resolution is best-effort
74
+ }
75
+ return null;
76
+ },
77
+ };
78
+ }
79
+ /**
80
+ * Wrap a provider with EventEmittingProvider for event emission.
81
+ */
82
+ function wrapWithEvents(provider, db, storage, projectId) {
83
+ const resolver = createDbStatusResolver(db, storage);
84
+ return new EventEmittingProvider(provider, resolver, projectId);
85
+ }
19
86
  /**
20
87
  * Resolve the correct provider for a given ticket.
21
88
  *
@@ -23,6 +90,9 @@ import { LinearTicketProvider } from './linear-provider.js';
23
90
  * - external_source = 'linear' + configured + inbound/bidirectional → Linear
24
91
  * - Otherwise → PMO
25
92
  *
93
+ * The resolved provider is wrapped with EventEmittingProvider so that
94
+ * events are emitted at the adapter layer, not the storage layer.
95
+ *
26
96
  * @param ticketId - The PMO ticket ID
27
97
  * @param projectId - The PMO project ID
28
98
  * @param db - Database handle for config/mapping lookups
@@ -42,12 +112,14 @@ export function resolveTicketProvider(ticketId, projectId, db, storage, metadata
42
112
  // - 'bidirectional' = both directions synced → write to Linear directly
43
113
  // - 'outbound' = ticket was created in PMO and pushed to Linear → PMO is source of truth
44
114
  if (mapping.syncDirection !== 'outbound') {
45
- return new LinearTicketProvider(db, storage, projectId, null);
115
+ const inner = new LinearTicketProvider(db, storage, projectId, null);
116
+ return wrapWithEvents(inner, db, storage, projectId);
46
117
  }
47
118
  }
48
119
  }
49
120
  // Default: local PMO
50
- return new PMOTicketProvider(storage, projectId);
121
+ const inner = new PMOTicketProvider(storage, projectId);
122
+ return wrapWithEvents(inner, db, storage, projectId);
51
123
  }
52
124
  /**
53
125
  * Resolve the correct provider for project-level operations (list, create).
@@ -55,6 +127,9 @@ export function resolveTicketProvider(ticketId, projectId, db, storage, metadata
55
127
  * Unlike resolveTicketProvider, this doesn't require a specific ticket.
56
128
  * It checks workspace configuration to determine the active provider.
57
129
  *
130
+ * The resolved provider is wrapped with EventEmittingProvider so that
131
+ * events are emitted at the adapter layer, not the storage layer.
132
+ *
58
133
  * @param db - Database handle for config lookups
59
134
  * @param storage - Storage instance
60
135
  * @param projectId - The PMO project ID
@@ -63,20 +138,24 @@ export function resolveTicketProvider(ticketId, projectId, db, storage, metadata
63
138
  */
64
139
  export function resolveProjectProvider(db, storage, projectId, source) {
65
140
  if (source === 'pmo') {
66
- return new PMOTicketProvider(storage, projectId);
141
+ const inner = new PMOTicketProvider(storage, projectId);
142
+ return wrapWithEvents(inner, db, storage, projectId);
67
143
  }
68
144
  if (source === 'linear') {
69
- return new LinearTicketProvider(db, storage, projectId, null);
145
+ const inner = new LinearTicketProvider(db, storage, projectId, null);
146
+ return wrapWithEvents(inner, db, storage, projectId);
70
147
  }
71
148
  // auto: use Linear when it's configured in the workspace
72
149
  try {
73
150
  if (isLinearConfigured(db)) {
74
- return new LinearTicketProvider(db, storage, projectId, null);
151
+ const inner = new LinearTicketProvider(db, storage, projectId, null);
152
+ return wrapWithEvents(inner, db, storage, projectId);
75
153
  }
76
154
  }
77
155
  catch {
78
156
  // workspace_settings table may not exist in older/test databases
79
157
  }
80
- return new PMOTicketProvider(storage, projectId);
158
+ const inner = new PMOTicketProvider(storage, projectId);
159
+ return wrapWithEvents(inner, db, storage, projectId);
81
160
  }
82
161
  //# sourceMappingURL=resolver.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../../src/lib/providers/resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAElD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAE3D;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,qBAAqB,CACnC,QAAgB,EAChB,SAAiB,EACjB,EAAqB,EACrB,OAAwB,EACxB,QAAwC;IAExC,MAAM,cAAc,GAAG,QAAQ,EAAE,eAAe,CAAA;IAEhD,eAAe;IACf,IAAI,cAAc,KAAK,QAAQ,IAAI,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC;QAC1D,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,EAAE,CAAC,CAAA;QACnC,MAAM,OAAO,GAAG,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAA;QAE9C,IAAI,OAAO,EAAE,CAAC;YACZ,+DAA+D;YAC/D,4EAA4E;YAC5E,wEAAwE;YACxE,yFAAyF;YACzF,IAAI,OAAO,CAAC,aAAa,KAAK,UAAU,EAAE,CAAC;gBACzC,OAAO,IAAI,oBAAoB,CAAC,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,CAAA;YAC/D,CAAC;QACH,CAAC;IACH,CAAC;IAED,qBAAqB;IACrB,OAAO,IAAI,iBAAiB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;AAClD,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,sBAAsB,CACpC,EAAqB,EACrB,OAAwB,EACxB,SAAiB,EACjB,MAAe;IAEf,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACrB,OAAO,IAAI,iBAAiB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;IAClD,CAAC;IAED,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,OAAO,IAAI,oBAAoB,CAAC,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,CAAA;IAC/D,CAAC;IAED,yDAAyD;IACzD,IAAI,CAAC;QACH,IAAI,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC;YAC3B,OAAO,IAAI,oBAAoB,CAAC,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,CAAA;QAC/D,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,iEAAiE;IACnE,CAAC;IAED,OAAO,IAAI,iBAAiB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;AAClD,CAAC"}
1
+ {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../../src/lib/providers/resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Provider Status Mapping
3
+ *
4
+ * Configurable mapping between provider-specific status names and
5
+ * canonical workflow statuses. Each provider (Linear, Jira, Shortcut,
6
+ * Asana, etc.) may use different status vocabularies. This module
7
+ * translates between them.
8
+ *
9
+ * Example mappings:
10
+ * linear: "In Review" → canonical: "Review"
11
+ * jira: "Code Review" → canonical: "Review"
12
+ * asana: "QA" → canonical: "Review"
13
+ *
14
+ * When no mapping is configured, the system falls back to:
15
+ * 1. Exact name match
16
+ * 2. Category-based matching (e.g., 'started' category)
17
+ */
18
+ import type Database from 'better-sqlite3';
19
+ import type { StateCategory } from '../pmo/types.js';
20
+ export interface StatusMapping {
21
+ provider: string;
22
+ providerStatus: string;
23
+ canonicalStatus: string;
24
+ canonicalCategory: StateCategory | null;
25
+ }
26
+ /**
27
+ * ProviderStatusMappingStore manages the pmo_provider_status_map table.
28
+ * Provides CRUD operations for status mappings per provider.
29
+ */
30
+ export declare class ProviderStatusMappingStore {
31
+ private db;
32
+ constructor(db: Database.Database);
33
+ /**
34
+ * Get the canonical status for a provider-specific status.
35
+ * Returns null if no mapping is configured.
36
+ */
37
+ getCanonicalStatus(provider: string, providerStatus: string): StatusMapping | null;
38
+ /**
39
+ * Get the provider-specific status for a canonical status.
40
+ * Returns null if no mapping is configured.
41
+ */
42
+ getProviderStatus(provider: string, canonicalStatus: string): StatusMapping | null;
43
+ /**
44
+ * List all status mappings for a provider.
45
+ */
46
+ listMappings(provider: string): StatusMapping[];
47
+ /**
48
+ * Add or update a status mapping for a provider.
49
+ */
50
+ upsertMapping(mapping: StatusMapping): void;
51
+ /**
52
+ * Remove a specific status mapping.
53
+ */
54
+ removeMapping(provider: string, providerStatus: string): void;
55
+ /**
56
+ * Remove all status mappings for a provider.
57
+ */
58
+ clearMappings(provider: string): void;
59
+ /**
60
+ * Resolve a status name from a provider to its canonical equivalent.
61
+ * Falls back to the original name if no mapping is found.
62
+ */
63
+ resolveStatus(provider: string, statusName: string): string;
64
+ }
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Provider Status Mapping
3
+ *
4
+ * Configurable mapping between provider-specific status names and
5
+ * canonical workflow statuses. Each provider (Linear, Jira, Shortcut,
6
+ * Asana, etc.) may use different status vocabularies. This module
7
+ * translates between them.
8
+ *
9
+ * Example mappings:
10
+ * linear: "In Review" → canonical: "Review"
11
+ * jira: "Code Review" → canonical: "Review"
12
+ * asana: "QA" → canonical: "Review"
13
+ *
14
+ * When no mapping is configured, the system falls back to:
15
+ * 1. Exact name match
16
+ * 2. Category-based matching (e.g., 'started' category)
17
+ */
18
+ /**
19
+ * ProviderStatusMappingStore manages the pmo_provider_status_map table.
20
+ * Provides CRUD operations for status mappings per provider.
21
+ */
22
+ export class ProviderStatusMappingStore {
23
+ db;
24
+ constructor(db) {
25
+ this.db = db;
26
+ }
27
+ /**
28
+ * Get the canonical status for a provider-specific status.
29
+ * Returns null if no mapping is configured.
30
+ */
31
+ getCanonicalStatus(provider, providerStatus) {
32
+ try {
33
+ const row = this.db.prepare(`
34
+ SELECT provider, provider_status, canonical_status, canonical_category
35
+ FROM pmo_provider_status_map
36
+ WHERE provider = ? AND LOWER(provider_status) = LOWER(?)
37
+ `).get(provider, providerStatus);
38
+ if (!row)
39
+ return null;
40
+ return {
41
+ provider: row.provider,
42
+ providerStatus: row.provider_status,
43
+ canonicalStatus: row.canonical_status,
44
+ canonicalCategory: row.canonical_category,
45
+ };
46
+ }
47
+ catch {
48
+ return null;
49
+ }
50
+ }
51
+ /**
52
+ * Get the provider-specific status for a canonical status.
53
+ * Returns null if no mapping is configured.
54
+ */
55
+ getProviderStatus(provider, canonicalStatus) {
56
+ try {
57
+ const row = this.db.prepare(`
58
+ SELECT provider, provider_status, canonical_status, canonical_category
59
+ FROM pmo_provider_status_map
60
+ WHERE provider = ? AND LOWER(canonical_status) = LOWER(?)
61
+ `).get(provider, canonicalStatus);
62
+ if (!row)
63
+ return null;
64
+ return {
65
+ provider: row.provider,
66
+ providerStatus: row.provider_status,
67
+ canonicalStatus: row.canonical_status,
68
+ canonicalCategory: row.canonical_category,
69
+ };
70
+ }
71
+ catch {
72
+ return null;
73
+ }
74
+ }
75
+ /**
76
+ * List all status mappings for a provider.
77
+ */
78
+ listMappings(provider) {
79
+ try {
80
+ const rows = this.db.prepare(`
81
+ SELECT provider, provider_status, canonical_status, canonical_category
82
+ FROM pmo_provider_status_map
83
+ WHERE provider = ?
84
+ ORDER BY canonical_status
85
+ `).all(provider);
86
+ return rows.map(row => ({
87
+ provider: row.provider,
88
+ providerStatus: row.provider_status,
89
+ canonicalStatus: row.canonical_status,
90
+ canonicalCategory: row.canonical_category,
91
+ }));
92
+ }
93
+ catch {
94
+ return [];
95
+ }
96
+ }
97
+ /**
98
+ * Add or update a status mapping for a provider.
99
+ */
100
+ upsertMapping(mapping) {
101
+ this.db.prepare(`
102
+ INSERT INTO pmo_provider_status_map (provider, provider_status, canonical_status, canonical_category)
103
+ VALUES (?, ?, ?, ?)
104
+ ON CONFLICT(provider, provider_status) DO UPDATE SET
105
+ canonical_status = excluded.canonical_status,
106
+ canonical_category = excluded.canonical_category
107
+ `).run(mapping.provider, mapping.providerStatus, mapping.canonicalStatus, mapping.canonicalCategory);
108
+ }
109
+ /**
110
+ * Remove a specific status mapping.
111
+ */
112
+ removeMapping(provider, providerStatus) {
113
+ this.db.prepare(`
114
+ DELETE FROM pmo_provider_status_map
115
+ WHERE provider = ? AND provider_status = ?
116
+ `).run(provider, providerStatus);
117
+ }
118
+ /**
119
+ * Remove all status mappings for a provider.
120
+ */
121
+ clearMappings(provider) {
122
+ this.db.prepare(`
123
+ DELETE FROM pmo_provider_status_map
124
+ WHERE provider = ?
125
+ `).run(provider);
126
+ }
127
+ /**
128
+ * Resolve a status name from a provider to its canonical equivalent.
129
+ * Falls back to the original name if no mapping is found.
130
+ */
131
+ resolveStatus(provider, statusName) {
132
+ const mapping = this.getCanonicalStatus(provider, statusName);
133
+ return mapping?.canonicalStatus ?? statusName;
134
+ }
135
+ }
136
+ //# sourceMappingURL=status-mapping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-mapping.js","sourceRoot":"","sources":["../../../src/lib/providers/status-mapping.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Provider Trigger Configuration
3
+ *
4
+ * Configurable triggers that map work lifecycle events to automatic
5
+ * column/status transitions. When a trigger event fires, the system
6
+ * automatically moves the affected ticket to the configured target status.
7
+ *
8
+ * Supported trigger events:
9
+ * - agent_started: An agent begins working on a ticket
10
+ * - pr_created: A pull request is created or linked
11
+ * - pr_merged: A pull request is merged
12
+ * - tests_passed: Tests pass for the work item
13
+ * - work_completed: Work on the item is marked complete
14
+ *
15
+ * Triggers can be scoped per provider (or '*' for all providers)
16
+ * and per project (or null for all projects).
17
+ *
18
+ * Example:
19
+ * trigger_event: 'pr_created', target_status: 'Review'
20
+ * → When a PR is created, move the ticket to "Review"
21
+ *
22
+ * trigger_event: 'pr_merged', target_status: 'Done'
23
+ * → When a PR is merged, move the ticket to "Done"
24
+ */
25
+ import type Database from 'better-sqlite3';
26
+ /**
27
+ * Valid trigger event names that can be configured.
28
+ */
29
+ export type TriggerEvent = 'agent_started' | 'pr_created' | 'pr_merged' | 'tests_passed' | 'work_completed';
30
+ export declare const TRIGGER_EVENTS: readonly TriggerEvent[];
31
+ export interface TriggerConfig {
32
+ id?: number;
33
+ provider: string;
34
+ triggerEvent: TriggerEvent;
35
+ targetStatus: string;
36
+ projectId: string | null;
37
+ enabled: boolean;
38
+ }
39
+ /**
40
+ * ProviderTriggerStore manages the pmo_provider_triggers table.
41
+ * Provides CRUD operations for configurable triggers.
42
+ */
43
+ export declare class ProviderTriggerStore {
44
+ private db;
45
+ constructor(db: Database.Database);
46
+ /**
47
+ * Get all triggers for a specific event, optionally filtered by provider and project.
48
+ */
49
+ getTriggersForEvent(triggerEvent: TriggerEvent, provider?: string, projectId?: string | null): TriggerConfig[];
50
+ /**
51
+ * List all configured triggers.
52
+ */
53
+ listTriggers(): TriggerConfig[];
54
+ /**
55
+ * Add or update a trigger configuration.
56
+ */
57
+ upsertTrigger(config: TriggerConfig): void;
58
+ /**
59
+ * Remove a trigger by ID.
60
+ */
61
+ removeTrigger(id: number): void;
62
+ /**
63
+ * Enable or disable a trigger.
64
+ */
65
+ setEnabled(id: number, enabled: boolean): void;
66
+ }
67
+ /**
68
+ * TriggerHandler subscribes to work-lifecycle events on the EventBus
69
+ * and automatically transitions tickets based on configured triggers.
70
+ */
71
+ export declare class TriggerHandler {
72
+ private unsubscribers;
73
+ private store;
74
+ private moveTicket;
75
+ constructor(db: Database.Database, moveTicket: (ticketId: string, projectId: string, targetStatus: string) => Promise<void>);
76
+ /**
77
+ * Start listening for work-lifecycle events and applying triggers.
78
+ */
79
+ start(): void;
80
+ /**
81
+ * Stop listening for events.
82
+ */
83
+ stop(): void;
84
+ /**
85
+ * Apply a trigger: look up configured triggers for the event
86
+ * and move the ticket to the target status if a match is found.
87
+ */
88
+ private applyTrigger;
89
+ }
90
+ /**
91
+ * Initialize the trigger handler.
92
+ * Safe to call multiple times — subsequent calls are no-ops.
93
+ */
94
+ export declare function initTriggerHandler(db: Database.Database, moveTicket: (ticketId: string, projectId: string, targetStatus: string) => Promise<void>): TriggerHandler;
95
+ /**
96
+ * Stop the trigger handler (primarily for testing).
97
+ */
98
+ export declare function stopTriggerHandler(): void;
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Provider Trigger Configuration
3
+ *
4
+ * Configurable triggers that map work lifecycle events to automatic
5
+ * column/status transitions. When a trigger event fires, the system
6
+ * automatically moves the affected ticket to the configured target status.
7
+ *
8
+ * Supported trigger events:
9
+ * - agent_started: An agent begins working on a ticket
10
+ * - pr_created: A pull request is created or linked
11
+ * - pr_merged: A pull request is merged
12
+ * - tests_passed: Tests pass for the work item
13
+ * - work_completed: Work on the item is marked complete
14
+ *
15
+ * Triggers can be scoped per provider (or '*' for all providers)
16
+ * and per project (or null for all projects).
17
+ *
18
+ * Example:
19
+ * trigger_event: 'pr_created', target_status: 'Review'
20
+ * → When a PR is created, move the ticket to "Review"
21
+ *
22
+ * trigger_event: 'pr_merged', target_status: 'Done'
23
+ * → When a PR is merged, move the ticket to "Done"
24
+ */
25
+ import { getEventBus } from '../events/event-bus.js';
26
+ export const TRIGGER_EVENTS = [
27
+ 'agent_started',
28
+ 'pr_created',
29
+ 'pr_merged',
30
+ 'tests_passed',
31
+ 'work_completed',
32
+ ];
33
+ /**
34
+ * ProviderTriggerStore manages the pmo_provider_triggers table.
35
+ * Provides CRUD operations for configurable triggers.
36
+ */
37
+ export class ProviderTriggerStore {
38
+ db;
39
+ constructor(db) {
40
+ this.db = db;
41
+ }
42
+ /**
43
+ * Get all triggers for a specific event, optionally filtered by provider and project.
44
+ */
45
+ getTriggersForEvent(triggerEvent, provider, projectId) {
46
+ try {
47
+ const rows = this.db.prepare(`
48
+ SELECT id, provider, trigger_event, target_status, project_id, enabled
49
+ FROM pmo_provider_triggers
50
+ WHERE trigger_event = ?
51
+ AND enabled = 1
52
+ AND (provider = '*' OR provider = ?)
53
+ AND (project_id IS NULL OR project_id = ?)
54
+ ORDER BY
55
+ CASE WHEN provider != '*' THEN 0 ELSE 1 END,
56
+ CASE WHEN project_id IS NOT NULL THEN 0 ELSE 1 END
57
+ `).all(triggerEvent, provider ?? '*', projectId ?? null);
58
+ return rows.map(row => ({
59
+ id: row.id,
60
+ provider: row.provider,
61
+ triggerEvent: row.trigger_event,
62
+ targetStatus: row.target_status,
63
+ projectId: row.project_id,
64
+ enabled: row.enabled === 1,
65
+ }));
66
+ }
67
+ catch {
68
+ return [];
69
+ }
70
+ }
71
+ /**
72
+ * List all configured triggers.
73
+ */
74
+ listTriggers() {
75
+ try {
76
+ const rows = this.db.prepare(`
77
+ SELECT id, provider, trigger_event, target_status, project_id, enabled
78
+ FROM pmo_provider_triggers
79
+ ORDER BY trigger_event, provider
80
+ `).all();
81
+ return rows.map(row => ({
82
+ id: row.id,
83
+ provider: row.provider,
84
+ triggerEvent: row.trigger_event,
85
+ targetStatus: row.target_status,
86
+ projectId: row.project_id,
87
+ enabled: row.enabled === 1,
88
+ }));
89
+ }
90
+ catch {
91
+ return [];
92
+ }
93
+ }
94
+ /**
95
+ * Add or update a trigger configuration.
96
+ */
97
+ upsertTrigger(config) {
98
+ this.db.prepare(`
99
+ INSERT INTO pmo_provider_triggers (provider, trigger_event, target_status, project_id, enabled)
100
+ VALUES (?, ?, ?, ?, ?)
101
+ ON CONFLICT(provider, trigger_event, project_id) DO UPDATE SET
102
+ target_status = excluded.target_status,
103
+ enabled = excluded.enabled
104
+ `).run(config.provider, config.triggerEvent, config.targetStatus, config.projectId, config.enabled ? 1 : 0);
105
+ }
106
+ /**
107
+ * Remove a trigger by ID.
108
+ */
109
+ removeTrigger(id) {
110
+ this.db.prepare('DELETE FROM pmo_provider_triggers WHERE id = ?').run(id);
111
+ }
112
+ /**
113
+ * Enable or disable a trigger.
114
+ */
115
+ setEnabled(id, enabled) {
116
+ this.db.prepare('UPDATE pmo_provider_triggers SET enabled = ? WHERE id = ?').run(enabled ? 1 : 0, id);
117
+ }
118
+ }
119
+ /**
120
+ * TriggerHandler subscribes to work-lifecycle events on the EventBus
121
+ * and automatically transitions tickets based on configured triggers.
122
+ */
123
+ export class TriggerHandler {
124
+ unsubscribers = [];
125
+ store;
126
+ moveTicket;
127
+ constructor(db, moveTicket) {
128
+ this.store = new ProviderTriggerStore(db);
129
+ this.moveTicket = moveTicket;
130
+ }
131
+ /**
132
+ * Start listening for work-lifecycle events and applying triggers.
133
+ */
134
+ start() {
135
+ const bus = getEventBus();
136
+ // agent_started trigger: fires on work:started events
137
+ this.unsubscribers.push(bus.on('work:started', (event) => {
138
+ void this.applyTrigger('agent_started', event.source, event.workItemId, event.projectId ?? null);
139
+ }));
140
+ // pr_created trigger: fires on work:pr_created events
141
+ this.unsubscribers.push(bus.on('work:pr_created', (event) => {
142
+ void this.applyTrigger('pr_created', event.source, event.workItemId, event.projectId ?? null);
143
+ }));
144
+ // pr_merged trigger: fires on work:pr_merged events
145
+ this.unsubscribers.push(bus.on('work:pr_merged', (event) => {
146
+ void this.applyTrigger('pr_merged', event.source, event.workItemId, event.projectId ?? null);
147
+ }));
148
+ // work_completed trigger: fires on work:completed events
149
+ this.unsubscribers.push(bus.on('work:completed', (event) => {
150
+ void this.applyTrigger('work_completed', event.source, event.workItemId, event.projectId ?? null);
151
+ }));
152
+ }
153
+ /**
154
+ * Stop listening for events.
155
+ */
156
+ stop() {
157
+ for (const unsub of this.unsubscribers) {
158
+ unsub();
159
+ }
160
+ this.unsubscribers = [];
161
+ }
162
+ /**
163
+ * Apply a trigger: look up configured triggers for the event
164
+ * and move the ticket to the target status if a match is found.
165
+ */
166
+ async applyTrigger(triggerEvent, source, workItemId, projectId) {
167
+ const triggers = this.store.getTriggersForEvent(triggerEvent, source, projectId);
168
+ if (triggers.length === 0)
169
+ return;
170
+ // Use the most specific trigger (provider-specific + project-specific first)
171
+ const trigger = triggers[0];
172
+ try {
173
+ await this.moveTicket(workItemId, projectId ?? '', trigger.targetStatus);
174
+ }
175
+ catch {
176
+ // Trigger application is non-fatal
177
+ }
178
+ }
179
+ }
180
+ // =============================================================================
181
+ // Singleton
182
+ // =============================================================================
183
+ let _handler;
184
+ /**
185
+ * Initialize the trigger handler.
186
+ * Safe to call multiple times — subsequent calls are no-ops.
187
+ */
188
+ export function initTriggerHandler(db, moveTicket) {
189
+ if (!_handler) {
190
+ _handler = new TriggerHandler(db, moveTicket);
191
+ _handler.start();
192
+ }
193
+ return _handler;
194
+ }
195
+ /**
196
+ * Stop the trigger handler (primarily for testing).
197
+ */
198
+ export function stopTriggerHandler() {
199
+ if (_handler) {
200
+ _handler.stop();
201
+ _handler = undefined;
202
+ }
203
+ }
204
+ //# sourceMappingURL=trigger-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trigger-config.js","sourceRoot":"","sources":["../../../src/lib/providers/trigger-config.ts"],"names":[],"mappings":"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"}