pm-orchestrator-runner 1.0.7 → 1.0.8

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 (94) hide show
  1. package/README.md +20 -10
  2. package/dist/cli/index.js +36 -1
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/config/index.d.ts +9 -0
  5. package/dist/config/index.d.ts.map +1 -0
  6. package/dist/config/index.js +19 -0
  7. package/dist/config/index.js.map +1 -0
  8. package/dist/config/namespace.d.ts +86 -0
  9. package/dist/config/namespace.d.ts.map +1 -0
  10. package/dist/config/namespace.js +150 -0
  11. package/dist/config/namespace.js.map +1 -0
  12. package/dist/core/runner-core.d.ts +2 -0
  13. package/dist/core/runner-core.d.ts.map +1 -1
  14. package/dist/core/runner-core.js +27 -1
  15. package/dist/core/runner-core.js.map +1 -1
  16. package/dist/executor/claude-code-executor.d.ts +28 -0
  17. package/dist/executor/claude-code-executor.d.ts.map +1 -1
  18. package/dist/executor/claude-code-executor.js +184 -1
  19. package/dist/executor/claude-code-executor.js.map +1 -1
  20. package/dist/executor/deterministic-executor.d.ts +2 -1
  21. package/dist/executor/deterministic-executor.d.ts.map +1 -1
  22. package/dist/executor/deterministic-executor.js +7 -0
  23. package/dist/executor/deterministic-executor.js.map +1 -1
  24. package/dist/executor/recovery-executor.d.ts +2 -1
  25. package/dist/executor/recovery-executor.d.ts.map +1 -1
  26. package/dist/executor/recovery-executor.js +7 -0
  27. package/dist/executor/recovery-executor.js.map +1 -1
  28. package/dist/models/enums.d.ts +54 -0
  29. package/dist/models/enums.d.ts.map +1 -1
  30. package/dist/models/enums.js +59 -1
  31. package/dist/models/enums.js.map +1 -1
  32. package/dist/models/index.d.ts +4 -1
  33. package/dist/models/index.d.ts.map +1 -1
  34. package/dist/models/index.js +50 -2
  35. package/dist/models/index.js.map +1 -1
  36. package/dist/models/run.d.ts +82 -0
  37. package/dist/models/run.d.ts.map +1 -0
  38. package/dist/models/run.js +161 -0
  39. package/dist/models/run.js.map +1 -0
  40. package/dist/models/task-group.d.ts +164 -0
  41. package/dist/models/task-group.d.ts.map +1 -0
  42. package/dist/models/task-group.js +246 -0
  43. package/dist/models/task-group.js.map +1 -0
  44. package/dist/models/task.d.ts +7 -0
  45. package/dist/models/task.d.ts.map +1 -1
  46. package/dist/models/task.js.map +1 -1
  47. package/dist/models/thread.d.ts +53 -0
  48. package/dist/models/thread.d.ts.map +1 -0
  49. package/dist/models/thread.js +92 -0
  50. package/dist/models/thread.js.map +1 -0
  51. package/dist/pool/agent-pool.d.ts.map +1 -1
  52. package/dist/pool/agent-pool.js +2 -3
  53. package/dist/pool/agent-pool.js.map +1 -1
  54. package/dist/prompt/index.d.ts +8 -0
  55. package/dist/prompt/index.d.ts.map +1 -0
  56. package/dist/prompt/index.js +13 -0
  57. package/dist/prompt/index.js.map +1 -0
  58. package/dist/prompt/prompt-assembler.d.ts +145 -0
  59. package/dist/prompt/prompt-assembler.d.ts.map +1 -0
  60. package/dist/prompt/prompt-assembler.js +242 -0
  61. package/dist/prompt/prompt-assembler.js.map +1 -0
  62. package/dist/queue/index.d.ts +41 -0
  63. package/dist/queue/index.d.ts.map +1 -0
  64. package/dist/queue/index.js +42 -0
  65. package/dist/queue/index.js.map +1 -0
  66. package/dist/queue/queue-poller.d.ts +107 -0
  67. package/dist/queue/queue-poller.d.ts.map +1 -0
  68. package/dist/queue/queue-poller.js +181 -0
  69. package/dist/queue/queue-poller.js.map +1 -0
  70. package/dist/queue/queue-store.d.ts +163 -0
  71. package/dist/queue/queue-store.d.ts.map +1 -0
  72. package/dist/queue/queue-store.js +421 -0
  73. package/dist/queue/queue-store.js.map +1 -0
  74. package/dist/repl/index.d.ts +1 -0
  75. package/dist/repl/index.d.ts.map +1 -1
  76. package/dist/repl/index.js +3 -1
  77. package/dist/repl/index.js.map +1 -1
  78. package/dist/repl/repl-interface.d.ts +40 -5
  79. package/dist/repl/repl-interface.d.ts.map +1 -1
  80. package/dist/repl/repl-interface.js +95 -17
  81. package/dist/repl/repl-interface.js.map +1 -1
  82. package/dist/repl/two-pane-renderer.d.ts +148 -0
  83. package/dist/repl/two-pane-renderer.d.ts.map +1 -0
  84. package/dist/repl/two-pane-renderer.js +239 -0
  85. package/dist/repl/two-pane-renderer.js.map +1 -0
  86. package/dist/web/index.d.ts +45 -0
  87. package/dist/web/index.d.ts.map +1 -0
  88. package/dist/web/index.js +47 -0
  89. package/dist/web/index.js.map +1 -0
  90. package/dist/web/server.d.ts +71 -0
  91. package/dist/web/server.d.ts.map +1 -0
  92. package/dist/web/server.js +329 -0
  93. package/dist/web/server.js.map +1 -0
  94. package/package.json +11 -3
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Queue Poller - Polls queue and executes tasks
3
+ * Per spec/20_QUEUE_STORE.md
4
+ *
5
+ * Features:
6
+ * - Polling interval configurable (default 1000ms)
7
+ * - 1 task per tick
8
+ * - In-flight limit: 1 (no concurrent execution)
9
+ * - Fail-closed error handling
10
+ */
11
+ import { EventEmitter } from 'events';
12
+ import { QueueStore, QueueItem } from './queue-store';
13
+ /**
14
+ * Task executor function type
15
+ * Returns status and optional error message
16
+ */
17
+ export type TaskExecutor = (item: QueueItem) => Promise<{
18
+ status: 'COMPLETE' | 'ERROR';
19
+ errorMessage?: string;
20
+ }>;
21
+ /**
22
+ * Poller configuration
23
+ */
24
+ export interface QueuePollerConfig {
25
+ /** Polling interval in milliseconds (default: 1000) */
26
+ pollIntervalMs?: number;
27
+ /** Max stale task age in milliseconds (default: 5 minutes) */
28
+ maxStaleTaskAgeMs?: number;
29
+ /** Recover stale tasks on startup (default: true) */
30
+ recoverOnStartup?: boolean;
31
+ }
32
+ /**
33
+ * Poller state
34
+ */
35
+ export interface QueuePollerState {
36
+ isRunning: boolean;
37
+ inFlight: QueueItem | null;
38
+ lastPollAt: string | null;
39
+ tasksProcessed: number;
40
+ errors: number;
41
+ }
42
+ /**
43
+ * Poller events
44
+ */
45
+ export interface QueuePollerEvents {
46
+ started: [];
47
+ stopped: [];
48
+ poll: [{
49
+ queuedCount: number;
50
+ }];
51
+ claimed: [QueueItem];
52
+ completed: [QueueItem];
53
+ error: [QueueItem, Error];
54
+ 'no-task': [];
55
+ 'already-claimed': [string];
56
+ 'stale-recovered': [number];
57
+ }
58
+ /**
59
+ * Queue Poller
60
+ * Polls the queue store and executes tasks
61
+ */
62
+ export declare class QueuePoller extends EventEmitter {
63
+ private readonly store;
64
+ private readonly executor;
65
+ private readonly pollIntervalMs;
66
+ private readonly maxStaleTaskAgeMs;
67
+ private readonly recoverOnStartup;
68
+ private pollTimer;
69
+ private inFlight;
70
+ private isRunning;
71
+ private lastPollAt;
72
+ private tasksProcessed;
73
+ private errors;
74
+ constructor(store: QueueStore, executor: TaskExecutor, config?: QueuePollerConfig);
75
+ /**
76
+ * Start polling
77
+ */
78
+ start(): Promise<void>;
79
+ /**
80
+ * Stop polling
81
+ */
82
+ stop(): void;
83
+ /**
84
+ * Single poll iteration
85
+ * - Skip if task in-flight
86
+ * - Claim oldest QUEUED task
87
+ * - Execute and update status
88
+ */
89
+ poll(): Promise<void>;
90
+ /**
91
+ * Get current state
92
+ */
93
+ getState(): QueuePollerState;
94
+ /**
95
+ * Check if poller is running
96
+ */
97
+ isActive(): boolean;
98
+ /**
99
+ * Check if task is in-flight
100
+ */
101
+ hasInFlight(): boolean;
102
+ /**
103
+ * Get in-flight task
104
+ */
105
+ getInFlight(): QueueItem | null;
106
+ }
107
+ //# sourceMappingURL=queue-poller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue-poller.d.ts","sourceRoot":"","sources":["../../src/queue/queue-poller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAmB,MAAM,eAAe,CAAC;AAEvE;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,CACzB,IAAI,EAAE,SAAS,KACZ,OAAO,CAAC;IAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEtE;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,uDAAuD;IACvD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8DAA8D;IAC9D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,SAAS,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,EAAE,CAAC;IACZ,OAAO,EAAE,EAAE,CAAC;IACZ,IAAI,EAAE,CAAC;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChC,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC;IACrB,SAAS,EAAE,CAAC,SAAS,CAAC,CAAC;IACvB,KAAK,EAAE,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC1B,SAAS,EAAE,EAAE,CAAC;IACd,iBAAiB,EAAE,CAAC,MAAM,CAAC,CAAC;IAC5B,iBAAiB,EAAE,CAAC,MAAM,CAAC,CAAC;CAC7B;AAED;;;GAGG;AACH,qBAAa,WAAY,SAAQ,YAAY;IAC3C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAa;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;IACxC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAU;IAE3C,OAAO,CAAC,SAAS,CAA+C;IAChE,OAAO,CAAC,QAAQ,CAA0B;IAC1C,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,MAAM,CAAa;gBAGzB,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,YAAY,EACtB,MAAM,GAAE,iBAAsB;IAUhC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAmC5B;;OAEG;IACH,IAAI,IAAI,IAAI;IAeZ;;;;;OAKG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAoE3B;;OAEG;IACH,QAAQ,IAAI,gBAAgB;IAU5B;;OAEG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,WAAW,IAAI,SAAS,GAAG,IAAI;CAGhC"}
@@ -0,0 +1,181 @@
1
+ "use strict";
2
+ /**
3
+ * Queue Poller - Polls queue and executes tasks
4
+ * Per spec/20_QUEUE_STORE.md
5
+ *
6
+ * Features:
7
+ * - Polling interval configurable (default 1000ms)
8
+ * - 1 task per tick
9
+ * - In-flight limit: 1 (no concurrent execution)
10
+ * - Fail-closed error handling
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.QueuePoller = void 0;
14
+ const events_1 = require("events");
15
+ /**
16
+ * Queue Poller
17
+ * Polls the queue store and executes tasks
18
+ */
19
+ class QueuePoller extends events_1.EventEmitter {
20
+ store;
21
+ executor;
22
+ pollIntervalMs;
23
+ maxStaleTaskAgeMs;
24
+ recoverOnStartup;
25
+ pollTimer = null;
26
+ inFlight = null;
27
+ isRunning = false;
28
+ lastPollAt = null;
29
+ tasksProcessed = 0;
30
+ errors = 0;
31
+ constructor(store, executor, config = {}) {
32
+ super();
33
+ this.store = store;
34
+ this.executor = executor;
35
+ this.pollIntervalMs = config.pollIntervalMs ?? 1000;
36
+ this.maxStaleTaskAgeMs = config.maxStaleTaskAgeMs ?? 5 * 60 * 1000;
37
+ this.recoverOnStartup = config.recoverOnStartup ?? true;
38
+ }
39
+ /**
40
+ * Start polling
41
+ */
42
+ async start() {
43
+ if (this.isRunning) {
44
+ return;
45
+ }
46
+ this.isRunning = true;
47
+ // Recover stale tasks on startup (fail-closed)
48
+ if (this.recoverOnStartup) {
49
+ try {
50
+ const recovered = await this.store.recoverStaleTasks(this.maxStaleTaskAgeMs);
51
+ if (recovered > 0) {
52
+ this.emit('stale-recovered', recovered);
53
+ }
54
+ }
55
+ catch (error) {
56
+ // Log but don't fail startup
57
+ // eslint-disable-next-line no-console
58
+ console.error('[QueuePoller] Failed to recover stale tasks:', error);
59
+ }
60
+ }
61
+ this.emit('started');
62
+ // Start polling loop
63
+ this.pollTimer = setInterval(() => {
64
+ this.poll().catch(error => {
65
+ // eslint-disable-next-line no-console
66
+ console.error('[QueuePoller] Poll error:', error);
67
+ });
68
+ }, this.pollIntervalMs);
69
+ // Immediate first poll
70
+ await this.poll();
71
+ }
72
+ /**
73
+ * Stop polling
74
+ */
75
+ stop() {
76
+ if (!this.isRunning) {
77
+ return;
78
+ }
79
+ this.isRunning = false;
80
+ if (this.pollTimer) {
81
+ clearInterval(this.pollTimer);
82
+ this.pollTimer = null;
83
+ }
84
+ this.emit('stopped');
85
+ }
86
+ /**
87
+ * Single poll iteration
88
+ * - Skip if task in-flight
89
+ * - Claim oldest QUEUED task
90
+ * - Execute and update status
91
+ */
92
+ async poll() {
93
+ if (!this.isRunning) {
94
+ return;
95
+ }
96
+ this.lastPollAt = new Date().toISOString();
97
+ // In-flight limit: 1
98
+ if (this.inFlight) {
99
+ return;
100
+ }
101
+ // Try to claim a task
102
+ const claimResult = await this.store.claim();
103
+ if (!claimResult.success) {
104
+ if (claimResult.error) {
105
+ // Task was claimed by another process
106
+ this.emit('already-claimed', claimResult.error);
107
+ }
108
+ else {
109
+ // No tasks in queue
110
+ this.emit('no-task');
111
+ }
112
+ return;
113
+ }
114
+ const item = claimResult.item;
115
+ this.inFlight = item;
116
+ this.emit('claimed', item);
117
+ try {
118
+ // Execute the task
119
+ const result = await this.executor(item);
120
+ // Update status
121
+ await this.store.updateStatus(item.task_id, result.status, result.errorMessage);
122
+ if (result.status === 'COMPLETE') {
123
+ this.tasksProcessed++;
124
+ this.emit('completed', item);
125
+ }
126
+ else {
127
+ this.errors++;
128
+ this.emit('error', item, new Error(result.errorMessage || 'Task failed'));
129
+ }
130
+ }
131
+ catch (error) {
132
+ // Fail-closed: mark as ERROR
133
+ this.errors++;
134
+ const errorMessage = error instanceof Error ? error.message : String(error);
135
+ try {
136
+ await this.store.updateStatus(item.task_id, 'ERROR', errorMessage);
137
+ }
138
+ catch (updateError) {
139
+ // Log but don't throw - we've already failed
140
+ // eslint-disable-next-line no-console
141
+ console.error('[QueuePoller] Failed to update error status:', updateError);
142
+ }
143
+ this.emit('error', item, error instanceof Error ? error : new Error(String(error)));
144
+ }
145
+ finally {
146
+ this.inFlight = null;
147
+ }
148
+ }
149
+ /**
150
+ * Get current state
151
+ */
152
+ getState() {
153
+ return {
154
+ isRunning: this.isRunning,
155
+ inFlight: this.inFlight,
156
+ lastPollAt: this.lastPollAt,
157
+ tasksProcessed: this.tasksProcessed,
158
+ errors: this.errors,
159
+ };
160
+ }
161
+ /**
162
+ * Check if poller is running
163
+ */
164
+ isActive() {
165
+ return this.isRunning;
166
+ }
167
+ /**
168
+ * Check if task is in-flight
169
+ */
170
+ hasInFlight() {
171
+ return this.inFlight !== null;
172
+ }
173
+ /**
174
+ * Get in-flight task
175
+ */
176
+ getInFlight() {
177
+ return this.inFlight;
178
+ }
179
+ }
180
+ exports.QueuePoller = QueuePoller;
181
+ //# sourceMappingURL=queue-poller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue-poller.js","sourceRoot":"","sources":["../../src/queue/queue-poller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Queue Store - DynamoDB Local implementation
3
+ * Per spec/20_QUEUE_STORE.md
4
+ *
5
+ * Provides queue operations with:
6
+ * - Atomic QUEUED -> RUNNING transitions (conditional update)
7
+ * - Double execution prevention
8
+ * - Fail-closed error handling
9
+ */
10
+ /**
11
+ * Queue Item status
12
+ * Per spec/20: QUEUED / RUNNING / COMPLETE / ERROR
13
+ */
14
+ export type QueueItemStatus = 'QUEUED' | 'RUNNING' | 'COMPLETE' | 'ERROR';
15
+ /**
16
+ * Queue Item schema
17
+ * Per spec/20_QUEUE_STORE.md
18
+ */
19
+ export interface QueueItem {
20
+ task_id: string;
21
+ task_group_id: string;
22
+ session_id: string;
23
+ status: QueueItemStatus;
24
+ prompt: string;
25
+ created_at: string;
26
+ updated_at: string;
27
+ error_message?: string;
28
+ }
29
+ /**
30
+ * Queue Store configuration
31
+ */
32
+ export interface QueueStoreConfig {
33
+ /** DynamoDB endpoint (default: http://localhost:8000) */
34
+ endpoint?: string;
35
+ /** Table name (default: pm-runner-queue) */
36
+ tableName?: string;
37
+ /** AWS region (default: local) */
38
+ region?: string;
39
+ }
40
+ /**
41
+ * Claim result
42
+ */
43
+ export interface ClaimResult {
44
+ success: boolean;
45
+ item?: QueueItem;
46
+ error?: string;
47
+ }
48
+ /**
49
+ * Task Group summary for listing
50
+ * Per spec/19_WEB_UI.md: task group list view
51
+ */
52
+ export interface TaskGroupSummary {
53
+ task_group_id: string;
54
+ task_count: number;
55
+ created_at: string;
56
+ latest_updated_at: string;
57
+ }
58
+ /**
59
+ * Queue Store
60
+ * Manages task queue with DynamoDB Local
61
+ */
62
+ export declare class QueueStore {
63
+ private readonly client;
64
+ private readonly docClient;
65
+ private readonly tableName;
66
+ private readonly endpoint;
67
+ constructor(config?: QueueStoreConfig);
68
+ /**
69
+ * Get table name
70
+ */
71
+ getTableName(): string;
72
+ /**
73
+ * Get endpoint
74
+ */
75
+ getEndpoint(): string;
76
+ /**
77
+ * Check if table exists
78
+ */
79
+ tableExists(): Promise<boolean>;
80
+ /**
81
+ * Create table with required GSIs
82
+ * Per spec/20_QUEUE_STORE.md table definition
83
+ */
84
+ createTable(): Promise<void>;
85
+ /**
86
+ * Ensure table exists, create if not
87
+ */
88
+ ensureTable(): Promise<void>;
89
+ /**
90
+ * Wait for table to become active
91
+ */
92
+ private waitForTableActive;
93
+ /**
94
+ * Enqueue a new task
95
+ * Creates item with status=QUEUED
96
+ *
97
+ * @param sessionId - Session ID
98
+ * @param taskGroupId - Task Group ID
99
+ * @param prompt - User prompt
100
+ * @param taskId - Optional task ID (generates if not provided)
101
+ * @returns Created queue item
102
+ */
103
+ enqueue(sessionId: string, taskGroupId: string, prompt: string, taskId?: string): Promise<QueueItem>;
104
+ /**
105
+ * Get item by task_id
106
+ */
107
+ getItem(taskId: string): Promise<QueueItem | null>;
108
+ /**
109
+ * Claim the oldest QUEUED task (atomic QUEUED -> RUNNING)
110
+ * Per spec: Uses conditional update for double execution prevention
111
+ *
112
+ * @returns ClaimResult with success flag and item if claimed
113
+ */
114
+ claim(): Promise<ClaimResult>;
115
+ /**
116
+ * Update task status
117
+ * Per spec: RUNNING -> COMPLETE or RUNNING -> ERROR
118
+ *
119
+ * @param taskId - Task ID
120
+ * @param status - New status
121
+ * @param errorMessage - Optional error message (for ERROR status)
122
+ */
123
+ updateStatus(taskId: string, status: QueueItemStatus, errorMessage?: string): Promise<void>;
124
+ /**
125
+ * Get items by session ID
126
+ * Uses session-index GSI
127
+ */
128
+ getBySession(sessionId: string): Promise<QueueItem[]>;
129
+ /**
130
+ * Get items by status
131
+ * Uses status-index GSI
132
+ */
133
+ getByStatus(status: QueueItemStatus): Promise<QueueItem[]>;
134
+ /**
135
+ * Get items by task group ID
136
+ * Uses task-group-index GSI
137
+ * Per spec/19_WEB_UI.md: for listing tasks in a task group
138
+ */
139
+ getByTaskGroup(taskGroupId: string): Promise<QueueItem[]>;
140
+ /**
141
+ * Get all distinct task groups with summary
142
+ * Per spec/19_WEB_UI.md: for task group list view
143
+ * Note: Uses Scan - consider pagination for large datasets
144
+ */
145
+ getAllTaskGroups(): Promise<TaskGroupSummary[]>;
146
+ /**
147
+ * Delete item (for testing)
148
+ */
149
+ deleteItem(taskId: string): Promise<void>;
150
+ /**
151
+ * Mark stale RUNNING tasks as ERROR
152
+ * Per spec: fail-closed - don't leave tasks in "limbo"
153
+ *
154
+ * @param maxAgeMs - Max age in milliseconds for RUNNING tasks
155
+ * @returns Number of tasks marked as ERROR
156
+ */
157
+ recoverStaleTasks(maxAgeMs?: number): Promise<number>;
158
+ /**
159
+ * Close the client connection
160
+ */
161
+ destroy(): void;
162
+ }
163
+ //# sourceMappingURL=queue-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue-store.d.ts","sourceRoot":"","sources":["../../src/queue/queue-store.ts"],"names":[],"mappings":"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"}