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.
- package/README.md +20 -10
- package/dist/cli/index.js +36 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/config/index.d.ts +9 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +19 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/namespace.d.ts +86 -0
- package/dist/config/namespace.d.ts.map +1 -0
- package/dist/config/namespace.js +150 -0
- package/dist/config/namespace.js.map +1 -0
- package/dist/core/runner-core.d.ts +2 -0
- package/dist/core/runner-core.d.ts.map +1 -1
- package/dist/core/runner-core.js +27 -1
- package/dist/core/runner-core.js.map +1 -1
- package/dist/executor/claude-code-executor.d.ts +28 -0
- package/dist/executor/claude-code-executor.d.ts.map +1 -1
- package/dist/executor/claude-code-executor.js +184 -1
- package/dist/executor/claude-code-executor.js.map +1 -1
- package/dist/executor/deterministic-executor.d.ts +2 -1
- package/dist/executor/deterministic-executor.d.ts.map +1 -1
- package/dist/executor/deterministic-executor.js +7 -0
- package/dist/executor/deterministic-executor.js.map +1 -1
- package/dist/executor/recovery-executor.d.ts +2 -1
- package/dist/executor/recovery-executor.d.ts.map +1 -1
- package/dist/executor/recovery-executor.js +7 -0
- package/dist/executor/recovery-executor.js.map +1 -1
- package/dist/models/enums.d.ts +54 -0
- package/dist/models/enums.d.ts.map +1 -1
- package/dist/models/enums.js +59 -1
- package/dist/models/enums.js.map +1 -1
- package/dist/models/index.d.ts +4 -1
- package/dist/models/index.d.ts.map +1 -1
- package/dist/models/index.js +50 -2
- package/dist/models/index.js.map +1 -1
- package/dist/models/run.d.ts +82 -0
- package/dist/models/run.d.ts.map +1 -0
- package/dist/models/run.js +161 -0
- package/dist/models/run.js.map +1 -0
- package/dist/models/task-group.d.ts +164 -0
- package/dist/models/task-group.d.ts.map +1 -0
- package/dist/models/task-group.js +246 -0
- package/dist/models/task-group.js.map +1 -0
- package/dist/models/task.d.ts +7 -0
- package/dist/models/task.d.ts.map +1 -1
- package/dist/models/task.js.map +1 -1
- package/dist/models/thread.d.ts +53 -0
- package/dist/models/thread.d.ts.map +1 -0
- package/dist/models/thread.js +92 -0
- package/dist/models/thread.js.map +1 -0
- package/dist/pool/agent-pool.d.ts.map +1 -1
- package/dist/pool/agent-pool.js +2 -3
- package/dist/pool/agent-pool.js.map +1 -1
- package/dist/prompt/index.d.ts +8 -0
- package/dist/prompt/index.d.ts.map +1 -0
- package/dist/prompt/index.js +13 -0
- package/dist/prompt/index.js.map +1 -0
- package/dist/prompt/prompt-assembler.d.ts +145 -0
- package/dist/prompt/prompt-assembler.d.ts.map +1 -0
- package/dist/prompt/prompt-assembler.js +242 -0
- package/dist/prompt/prompt-assembler.js.map +1 -0
- package/dist/queue/index.d.ts +41 -0
- package/dist/queue/index.d.ts.map +1 -0
- package/dist/queue/index.js +42 -0
- package/dist/queue/index.js.map +1 -0
- package/dist/queue/queue-poller.d.ts +107 -0
- package/dist/queue/queue-poller.d.ts.map +1 -0
- package/dist/queue/queue-poller.js +181 -0
- package/dist/queue/queue-poller.js.map +1 -0
- package/dist/queue/queue-store.d.ts +163 -0
- package/dist/queue/queue-store.d.ts.map +1 -0
- package/dist/queue/queue-store.js +421 -0
- package/dist/queue/queue-store.js.map +1 -0
- package/dist/repl/index.d.ts +1 -0
- package/dist/repl/index.d.ts.map +1 -1
- package/dist/repl/index.js +3 -1
- package/dist/repl/index.js.map +1 -1
- package/dist/repl/repl-interface.d.ts +40 -5
- package/dist/repl/repl-interface.d.ts.map +1 -1
- package/dist/repl/repl-interface.js +95 -17
- package/dist/repl/repl-interface.js.map +1 -1
- package/dist/repl/two-pane-renderer.d.ts +148 -0
- package/dist/repl/two-pane-renderer.d.ts.map +1 -0
- package/dist/repl/two-pane-renderer.js +239 -0
- package/dist/repl/two-pane-renderer.js.map +1 -0
- package/dist/web/index.d.ts +45 -0
- package/dist/web/index.d.ts.map +1 -0
- package/dist/web/index.js +47 -0
- package/dist/web/index.js.map +1 -0
- package/dist/web/server.d.ts +71 -0
- package/dist/web/server.d.ts.map +1 -0
- package/dist/web/server.js +329 -0
- package/dist/web/server.js.map +1 -0
- 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":"AAAA;;;;;;;;GAQG;AAmBH;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;AAE1E;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED;;;GAGG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IACnD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,MAAM,GAAE,gBAAqB;IAqBzC;;OAEG;IACH,YAAY,IAAI,MAAM;IAItB;;OAEG;IACH,WAAW,IAAI,MAAM;IAIrB;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAcrC;;;OAGG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IA0DlC;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IASlC;;OAEG;YACW,kBAAkB;IAkBhC;;;;;;;;;OASG;IACG,OAAO,CACX,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,SAAS,CAAC;IAsBrB;;OAEG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAWxD;;;;;OAKG;IACG,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC;IAgEnC;;;;;;;OAOG;IACG,YAAY,CAChB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,eAAe,EACvB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC;IA6BhB;;;OAGG;IACG,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAgB3D;;;OAGG;IACG,WAAW,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAmBhE;;;;OAIG;IACG,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAgB/D;;;;OAIG;IACG,gBAAgB,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAiDrD;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS/C;;;;;;OAMG;IACG,iBAAiB,CAAC,QAAQ,GAAE,MAAsB,GAAG,OAAO,CAAC,MAAM,CAAC;IAoB1E;;OAEG;IACH,OAAO,IAAI,IAAI;CAGhB"}
|