@loom-framework/core 0.1.0-alpha.151 → 0.1.0-alpha.153
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/builtin-skills/app-skill/SKILL.md +15 -5
- package/builtin-skills/app-skill/references/auth.md +23 -19
- package/builtin-skills/app-skill/references/evolution.md +90 -0
- package/builtin-skills/app-skill/references/process-builder.md +140 -0
- package/builtin-skills/app-skill/references/process-metrics.md +93 -0
- package/builtin-skills/app-skill/references/process.md +222 -0
- package/builtin-skills/loom/SKILL.md +9 -7
- package/dist/backend/index.d.ts +4 -0
- package/dist/backend/index.d.ts.map +1 -1
- package/dist/backend/index.js +52 -2
- package/dist/backend/index.js.map +1 -1
- package/dist/backend/process/engine.d.ts +84 -0
- package/dist/backend/process/engine.d.ts.map +1 -0
- package/dist/backend/process/engine.js +511 -0
- package/dist/backend/process/engine.js.map +1 -0
- package/dist/backend/process/index.d.ts +7 -0
- package/dist/backend/process/index.d.ts.map +1 -0
- package/dist/backend/process/index.js +6 -0
- package/dist/backend/process/index.js.map +1 -0
- package/dist/backend/process/logger.d.ts +30 -0
- package/dist/backend/process/logger.d.ts.map +1 -0
- package/dist/backend/process/logger.js +132 -0
- package/dist/backend/process/logger.js.map +1 -0
- package/dist/backend/process/queue.d.ts +31 -0
- package/dist/backend/process/queue.d.ts.map +1 -0
- package/dist/backend/process/queue.js +80 -0
- package/dist/backend/process/queue.js.map +1 -0
- package/dist/backend/process/registry.d.ts +25 -0
- package/dist/backend/process/registry.d.ts.map +1 -0
- package/dist/backend/process/registry.js +98 -0
- package/dist/backend/process/registry.js.map +1 -0
- package/dist/backend/process/trigger.d.ts +29 -0
- package/dist/backend/process/trigger.d.ts.map +1 -0
- package/dist/backend/process/trigger.js +108 -0
- package/dist/backend/process/trigger.js.map +1 -0
- package/dist/backend/routes/auth-routes.d.ts +5 -0
- package/dist/backend/routes/auth-routes.d.ts.map +1 -1
- package/dist/backend/routes/auth-routes.js +221 -1
- package/dist/backend/routes/auth-routes.js.map +1 -1
- package/dist/backend/routes/index.d.ts +2 -0
- package/dist/backend/routes/index.d.ts.map +1 -1
- package/dist/backend/routes/index.js +1 -0
- package/dist/backend/routes/index.js.map +1 -1
- package/dist/backend/routes/process-routes.d.ts +15 -0
- package/dist/backend/routes/process-routes.d.ts.map +1 -0
- package/dist/backend/routes/process-routes.js +237 -0
- package/dist/backend/routes/process-routes.js.map +1 -0
- package/dist/cli/commands/auth.d.ts.map +1 -1
- package/dist/cli/commands/auth.js +30 -22
- package/dist/cli/commands/auth.js.map +1 -1
- package/dist/cli/commands/data.d.ts.map +1 -1
- package/dist/cli/commands/data.js +36 -47
- package/dist/cli/commands/data.js.map +1 -1
- package/dist/cli/commands/generate-system-settings.d.ts +3 -2
- package/dist/cli/commands/generate-system-settings.d.ts.map +1 -1
- package/dist/cli/commands/generate-system-settings.js +50 -7
- package/dist/cli/commands/generate-system-settings.js.map +1 -1
- package/dist/cli/commands/init.js +2 -2
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/process.d.ts +8 -0
- package/dist/cli/commands/process.d.ts.map +1 -0
- package/dist/cli/commands/process.js +444 -0
- package/dist/cli/commands/process.js.map +1 -0
- package/dist/cli/commands/role.d.ts +5 -2
- package/dist/cli/commands/role.d.ts.map +1 -1
- package/dist/cli/commands/role.js +145 -18
- package/dist/cli/commands/role.js.map +1 -1
- package/dist/cli/commands/user-cmd.d.ts.map +1 -1
- package/dist/cli/commands/user-cmd.js +41 -50
- package/dist/cli/commands/user-cmd.js.map +1 -1
- package/dist/cli/generators/capability-generator.d.ts.map +1 -1
- package/dist/cli/generators/capability-generator.js +121 -6
- package/dist/cli/generators/capability-generator.js.map +1 -1
- package/dist/cli/helpers/app-tsx-wiring.d.ts.map +1 -1
- package/dist/cli/helpers/app-tsx-wiring.js +21 -14
- package/dist/cli/helpers/app-tsx-wiring.js.map +1 -1
- package/dist/cli/helpers/auth-client.d.ts +19 -0
- package/dist/cli/helpers/auth-client.d.ts.map +1 -0
- package/dist/cli/helpers/auth-client.js +42 -0
- package/dist/cli/helpers/auth-client.js.map +1 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/templates/index.d.ts +1 -0
- package/dist/cli/templates/index.d.ts.map +1 -1
- package/dist/cli/templates/index.js +1 -0
- package/dist/cli/templates/index.js.map +1 -1
- package/dist/cli/templates/process-management-page.d.ts +8 -0
- package/dist/cli/templates/process-management-page.d.ts.map +1 -0
- package/dist/cli/templates/process-management-page.js +824 -0
- package/dist/cli/templates/process-management-page.js.map +1 -0
- package/dist/cli/templates/user-management-page.d.ts +2 -1
- package/dist/cli/templates/user-management-page.d.ts.map +1 -1
- package/dist/cli/templates/user-management-page.js +321 -62
- package/dist/cli/templates/user-management-page.js.map +1 -1
- package/dist/config.d.ts +43 -23
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +8 -2
- package/dist/config.js.map +1 -1
- package/dist/types/auth.d.ts +0 -2
- package/dist/types/auth.d.ts.map +1 -1
- package/dist/types/config.d.ts +2 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/process.d.ts +106 -0
- package/dist/types/process.d.ts.map +1 -0
- package/dist/types/process.js +5 -0
- package/dist/types/process.js.map +1 -0
- package/package.json +3 -1
|
@@ -0,0 +1,511 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProcessEngine - Core orchestration engine
|
|
3
|
+
*
|
|
4
|
+
* Manages process definitions, triggers, concurrent execution, AI calls, and logging.
|
|
5
|
+
*/
|
|
6
|
+
import fs from 'fs/promises';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
import { ClaudeCodeEngine } from '../ai/engine.js';
|
|
9
|
+
import { generateId } from '../../utils/id.js';
|
|
10
|
+
import { parseDuration } from '../../utils/duration.js';
|
|
11
|
+
import { ProcessRegistry } from './registry.js';
|
|
12
|
+
import { TriggerManager } from './trigger.js';
|
|
13
|
+
import { ExecutionQueue } from './queue.js';
|
|
14
|
+
import { ProcessLogger } from './logger.js';
|
|
15
|
+
import { issueServiceToken } from '../auth/service-token.js';
|
|
16
|
+
import { mergeContentBlock } from '../ai/content-blocks.js';
|
|
17
|
+
const FILE_SIZE_INLINE_LIMIT = 10 * 1024; // 10KB
|
|
18
|
+
export class ProcessEngine {
|
|
19
|
+
registry;
|
|
20
|
+
triggerManager;
|
|
21
|
+
queue;
|
|
22
|
+
logger;
|
|
23
|
+
engine;
|
|
24
|
+
sessionManager;
|
|
25
|
+
config;
|
|
26
|
+
eventBus;
|
|
27
|
+
eventRegistry;
|
|
28
|
+
authConfig;
|
|
29
|
+
userStore;
|
|
30
|
+
projectRoot;
|
|
31
|
+
isShutdown = false;
|
|
32
|
+
constructor(options) {
|
|
33
|
+
this.config = options.config;
|
|
34
|
+
this.engine = options.engine;
|
|
35
|
+
this.sessionManager = options.sessionManager;
|
|
36
|
+
this.projectRoot = options.projectRoot;
|
|
37
|
+
this.eventBus = options.eventBus;
|
|
38
|
+
this.eventRegistry = options.eventRegistry;
|
|
39
|
+
this.authConfig = options.authConfig;
|
|
40
|
+
this.userStore = options.userStore;
|
|
41
|
+
this.registry = new ProcessRegistry(options.projectRoot);
|
|
42
|
+
this.logger = new ProcessLogger(options.projectRoot);
|
|
43
|
+
this.queue = new ExecutionQueue(options.config.maxConcurrent);
|
|
44
|
+
this.triggerManager = new TriggerManager((name, type, payload) => {
|
|
45
|
+
void this.runProcess(name, payload).catch(err => {
|
|
46
|
+
console.error(`[ProcessEngine] Error triggering process "${name}":`, err);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
async initialize() {
|
|
51
|
+
await this.registry.initialize();
|
|
52
|
+
await this.logger.initialize();
|
|
53
|
+
// Crash recovery: mark stale 'running' entries as 'failed'
|
|
54
|
+
const recovered = await this.logger.recoverCrashedEntries();
|
|
55
|
+
if (recovered > 0) {
|
|
56
|
+
console.warn(`[ProcessEngine] Recovered ${recovered} crashed execution(s)`);
|
|
57
|
+
}
|
|
58
|
+
// Restore triggers from registry
|
|
59
|
+
await this.triggerManager.restoreFromRegistry(this.registry, this.eventBus);
|
|
60
|
+
// Register process event patterns for discoverability
|
|
61
|
+
if (this.eventRegistry) {
|
|
62
|
+
const processes = await this.registry.listProcesses();
|
|
63
|
+
for (const proc of processes) {
|
|
64
|
+
this.registerEventPatterns(proc.name);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const processes = await this.registry.listProcesses();
|
|
68
|
+
const cronCount = processes.filter(p => p.cron).length;
|
|
69
|
+
const eventCount = processes.filter(p => p.onEvent).length;
|
|
70
|
+
console.log(`[ProcessEngine] Started, ${processes.length} process(es) registered, ${cronCount} cron trigger(s), ${eventCount} event trigger(s)`);
|
|
71
|
+
}
|
|
72
|
+
registerEventPatterns(name) {
|
|
73
|
+
if (!this.eventRegistry)
|
|
74
|
+
return;
|
|
75
|
+
this.eventRegistry.register(`process:started:${name}`, 'process', `Process ${name} started execution`, '{ runId, processName, triggerType }');
|
|
76
|
+
this.eventRegistry.register(`process:completed:${name}`, 'process', `Process ${name} completed successfully`, '{ runId, processName, durationMs }');
|
|
77
|
+
this.eventRegistry.register(`process:failed:${name}`, 'process', `Process ${name} failed`, '{ runId, processName, error }');
|
|
78
|
+
}
|
|
79
|
+
async addProcess(def) {
|
|
80
|
+
// Validate: exactly one of prompt or hasProcessFile must be set
|
|
81
|
+
if (!def.prompt && !def.hasProcessFile) {
|
|
82
|
+
throw new Error('Process must have either "prompt" (lightweight) or "hasProcessFile" (full)');
|
|
83
|
+
}
|
|
84
|
+
if (def.prompt && def.hasProcessFile) {
|
|
85
|
+
throw new Error('Process cannot have both "prompt" and "hasProcessFile" — choose one mode');
|
|
86
|
+
}
|
|
87
|
+
// Validate: if hasProcessFile, check PROCESS.md exists
|
|
88
|
+
if (def.hasProcessFile) {
|
|
89
|
+
const valid = await this.registry.validateProcessFile(def.name);
|
|
90
|
+
if (!valid) {
|
|
91
|
+
throw new Error(`PROCESS.md not found at .claude/processes/${def.name}/PROCESS.md — run 'loom process generate ${def.name}' first`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const process = await this.registry.addProcess(def);
|
|
95
|
+
// Start triggers
|
|
96
|
+
if (process.cron) {
|
|
97
|
+
this.triggerManager.startCron(process.name, process.cron, process.cronTimezone);
|
|
98
|
+
}
|
|
99
|
+
if (process.onEvent && this.eventBus) {
|
|
100
|
+
this.triggerManager.startEventSubscription(process.name, this.eventBus, process.onEvent, process.eventFilter, process.eventDebounceMs);
|
|
101
|
+
}
|
|
102
|
+
// Register event patterns
|
|
103
|
+
this.registerEventPatterns(process.name);
|
|
104
|
+
return process;
|
|
105
|
+
}
|
|
106
|
+
async removeProcess(name) {
|
|
107
|
+
const process = await this.registry.getProcess(name);
|
|
108
|
+
if (!process)
|
|
109
|
+
return false;
|
|
110
|
+
// Cancel queued entries
|
|
111
|
+
this.queue.cancelForProcess(name);
|
|
112
|
+
// Stop triggers
|
|
113
|
+
if (process.cron)
|
|
114
|
+
this.triggerManager.stopCron(name);
|
|
115
|
+
if (process.onEvent)
|
|
116
|
+
this.triggerManager.stopEventSubscription(name);
|
|
117
|
+
return this.registry.removeProcess(name);
|
|
118
|
+
}
|
|
119
|
+
async pauseProcess(name) {
|
|
120
|
+
const process = await this.registry.getProcess(name);
|
|
121
|
+
if (!process)
|
|
122
|
+
throw new Error(`Process "${name}" not found`);
|
|
123
|
+
if (process.paused)
|
|
124
|
+
return;
|
|
125
|
+
const updated = await this.registry.updateProcess(name, { paused: true });
|
|
126
|
+
if (updated?.cron)
|
|
127
|
+
this.triggerManager.stopCron(name);
|
|
128
|
+
if (updated?.onEvent)
|
|
129
|
+
this.triggerManager.stopEventSubscription(name);
|
|
130
|
+
}
|
|
131
|
+
async resumeProcess(name) {
|
|
132
|
+
const process = await this.registry.getProcess(name);
|
|
133
|
+
if (!process)
|
|
134
|
+
throw new Error(`Process "${name}" not found`);
|
|
135
|
+
if (!process.paused)
|
|
136
|
+
return;
|
|
137
|
+
const updated = await this.registry.updateProcess(name, { paused: false });
|
|
138
|
+
if (updated?.cron)
|
|
139
|
+
this.triggerManager.startCron(name, updated.cron, updated.cronTimezone);
|
|
140
|
+
if (updated?.onEvent && this.eventBus) {
|
|
141
|
+
this.triggerManager.startEventSubscription(name, this.eventBus, updated.onEvent, updated.eventFilter, updated.eventDebounceMs);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
async updateProcess(name, updates) {
|
|
145
|
+
const existing = await this.registry.getProcess(name);
|
|
146
|
+
if (!existing)
|
|
147
|
+
return undefined;
|
|
148
|
+
const updated = await this.registry.updateProcess(name, updates);
|
|
149
|
+
if (!updated)
|
|
150
|
+
return undefined;
|
|
151
|
+
// Re-register triggers if cron/onEvent changed
|
|
152
|
+
if ('cron' in updates || 'cronTimezone' in updates) {
|
|
153
|
+
if (existing.cron)
|
|
154
|
+
this.triggerManager.stopCron(name);
|
|
155
|
+
if (updated.cron)
|
|
156
|
+
this.triggerManager.startCron(name, updated.cron, updated.cronTimezone);
|
|
157
|
+
}
|
|
158
|
+
if ('onEvent' in updates || 'eventFilter' in updates || 'eventDebounceMs' in updates) {
|
|
159
|
+
if (existing.onEvent)
|
|
160
|
+
this.triggerManager.stopEventSubscription(name);
|
|
161
|
+
if (updated.onEvent && this.eventBus) {
|
|
162
|
+
this.triggerManager.startEventSubscription(name, this.eventBus, updated.onEvent, updated.eventFilter, updated.eventDebounceMs);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return updated;
|
|
166
|
+
}
|
|
167
|
+
async runProcess(name, eventPayload) {
|
|
168
|
+
const definition = await this.registry.getProcess(name);
|
|
169
|
+
if (!definition)
|
|
170
|
+
throw new Error(`Process "${name}" not found`);
|
|
171
|
+
// Manual run overrides pause, but we still queue it
|
|
172
|
+
const runId = generateId('proc-run');
|
|
173
|
+
const entry = {
|
|
174
|
+
runId,
|
|
175
|
+
processName: name,
|
|
176
|
+
enqueuedAt: new Date().toISOString(),
|
|
177
|
+
triggerType: eventPayload ? 'event' : 'manual',
|
|
178
|
+
eventPayload,
|
|
179
|
+
state: 'queued',
|
|
180
|
+
};
|
|
181
|
+
this.queue.enqueue(entry);
|
|
182
|
+
// Try to execute if slot available
|
|
183
|
+
this.tryExecuteNext();
|
|
184
|
+
return runId;
|
|
185
|
+
}
|
|
186
|
+
/** Build AI prompt from process definition */
|
|
187
|
+
async buildPrompt(definition, eventPayload) {
|
|
188
|
+
let prompt = '';
|
|
189
|
+
const files = [];
|
|
190
|
+
if (definition.hasProcessFile) {
|
|
191
|
+
// Full process: read PROCESS.md
|
|
192
|
+
const processDir = path.join(this.projectRoot, '.claude', 'processes', definition.name);
|
|
193
|
+
const processMd = path.join(processDir, 'PROCESS.md');
|
|
194
|
+
try {
|
|
195
|
+
prompt = await fs.readFile(processMd, 'utf-8');
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
throw new Error(`PROCESS.md not found at ${processMd}`);
|
|
199
|
+
}
|
|
200
|
+
// Read references directory
|
|
201
|
+
const refsDir = path.join(processDir, 'references');
|
|
202
|
+
try {
|
|
203
|
+
const refFiles = await fs.readdir(refsDir);
|
|
204
|
+
for (const file of refFiles) {
|
|
205
|
+
const refPath = path.join(refsDir, file);
|
|
206
|
+
const stat = await fs.stat(refPath);
|
|
207
|
+
if (stat.isFile()) {
|
|
208
|
+
if (stat.size > FILE_SIZE_INLINE_LIMIT) {
|
|
209
|
+
files.push({ name: file, path: refPath });
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
const content = await fs.readFile(refPath, 'utf-8');
|
|
213
|
+
prompt += `\n\n--- Reference: ${file} ---\n${content}`;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
// references dir doesn't exist, that's fine
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
else if (definition.prompt) {
|
|
223
|
+
// Lightweight process: use inline prompt
|
|
224
|
+
prompt = definition.prompt;
|
|
225
|
+
}
|
|
226
|
+
// Append event payload context
|
|
227
|
+
if (eventPayload && Object.keys(eventPayload).length > 0) {
|
|
228
|
+
prompt += `\n\n--- Event Context ---\n${JSON.stringify(eventPayload, null, 2)}`;
|
|
229
|
+
}
|
|
230
|
+
return { prompt, files: files.length > 0 ? files : undefined };
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Consume AsyncGenerator<AIChunk> until completion or error.
|
|
234
|
+
* Timeout is handled by engine.call() internally.
|
|
235
|
+
* Returns claudeSessionId, usage, and contentBlocks for session persistence.
|
|
236
|
+
*/
|
|
237
|
+
async consumeAIStream(stream) {
|
|
238
|
+
let resultSummary = '';
|
|
239
|
+
let claudeSessionId;
|
|
240
|
+
let usage;
|
|
241
|
+
let contentBlocks = [];
|
|
242
|
+
try {
|
|
243
|
+
for await (const chunk of stream) {
|
|
244
|
+
if (chunk.type === 'done') {
|
|
245
|
+
return { success: true, timedOut: false, resultSummary: resultSummary.substring(0, 500), claudeSessionId, usage, contentBlocks };
|
|
246
|
+
}
|
|
247
|
+
if (chunk.type === 'error') {
|
|
248
|
+
const msg = chunk.error ?? 'Unknown error';
|
|
249
|
+
const timedOut = msg.toLowerCase().includes('timed out');
|
|
250
|
+
return { success: false, timedOut, resultSummary: resultSummary.substring(0, 500), error: msg, claudeSessionId, usage, contentBlocks };
|
|
251
|
+
}
|
|
252
|
+
// Merge chunk into content blocks for session persistence
|
|
253
|
+
contentBlocks = mergeContentBlock(contentBlocks, chunk);
|
|
254
|
+
if (chunk.type === 'content') {
|
|
255
|
+
const text = chunk.content ?? '';
|
|
256
|
+
if (resultSummary.length < 500) {
|
|
257
|
+
resultSummary += text;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
else if (chunk.type === 'session_info') {
|
|
261
|
+
if (chunk.sessionId)
|
|
262
|
+
claudeSessionId = chunk.sessionId;
|
|
263
|
+
if (chunk.usage)
|
|
264
|
+
usage = chunk.usage;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
// Generator ended without 'done' — treat as success
|
|
268
|
+
return { success: true, timedOut: false, resultSummary: resultSummary.substring(0, 500), claudeSessionId, usage, contentBlocks };
|
|
269
|
+
}
|
|
270
|
+
catch (err) {
|
|
271
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
272
|
+
const timedOut = msg.toLowerCase().includes('timed out');
|
|
273
|
+
return { success: false, timedOut, resultSummary: resultSummary.substring(0, 500), error: msg, claudeSessionId, usage, contentBlocks };
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
tryExecuteNext() {
|
|
277
|
+
while (this.queue.hasSlot()) {
|
|
278
|
+
const entry = this.queue.dequeue();
|
|
279
|
+
if (!entry)
|
|
280
|
+
break;
|
|
281
|
+
void this.executeEntry(entry).catch(err => {
|
|
282
|
+
console.error(`[ProcessEngine] Unhandled error executing ${entry.runId}:`, err);
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
async executeEntry(entry) {
|
|
287
|
+
const definition = await this.registry.getProcess(entry.processName);
|
|
288
|
+
if (!definition) {
|
|
289
|
+
this.queue.markFailed(entry.runId, `Process "${entry.processName}" not found`);
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
// Build prompt
|
|
293
|
+
let prompt;
|
|
294
|
+
let files;
|
|
295
|
+
try {
|
|
296
|
+
const built = await this.buildPrompt(definition, entry.eventPayload);
|
|
297
|
+
prompt = built.prompt;
|
|
298
|
+
files = built.files;
|
|
299
|
+
}
|
|
300
|
+
catch (err) {
|
|
301
|
+
this.queue.markFailed(entry.runId, err instanceof Error ? err.message : String(err));
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
const promptSummary = prompt.substring(0, 200);
|
|
305
|
+
// Resolve owner service token
|
|
306
|
+
let userToken;
|
|
307
|
+
if (definition.ownerToken) {
|
|
308
|
+
userToken = definition.ownerToken;
|
|
309
|
+
}
|
|
310
|
+
else if (this.authConfig && this.userStore) {
|
|
311
|
+
try {
|
|
312
|
+
const user = await this.userStore.findByUsername(definition.owner);
|
|
313
|
+
if (!user) {
|
|
314
|
+
this.queue.markFailed(entry.runId, `Owner user "${definition.owner}" not found`);
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
userToken = issueServiceToken(user.userId, user.username, user.role, this.authConfig);
|
|
318
|
+
}
|
|
319
|
+
catch (err) {
|
|
320
|
+
this.queue.markFailed(entry.runId, `Failed to resolve service token: ${err instanceof Error ? err.message : String(err)}`);
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
// Create session and mark running (each execution gets an isolated session)
|
|
325
|
+
let session;
|
|
326
|
+
try {
|
|
327
|
+
session = await this.sessionManager.createSession();
|
|
328
|
+
}
|
|
329
|
+
catch (err) {
|
|
330
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
331
|
+
this.queue.markFailed(entry.runId, `Failed to create session: ${msg}`);
|
|
332
|
+
this.tryExecuteNext();
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
const sessionId = session.id;
|
|
336
|
+
this.queue.markRunning(entry.runId, sessionId);
|
|
337
|
+
// Persist user message to session (so the session has conversation history)
|
|
338
|
+
const userMsgId = generateId('msg');
|
|
339
|
+
const userMsg = {
|
|
340
|
+
id: userMsgId,
|
|
341
|
+
role: 'user',
|
|
342
|
+
content: prompt,
|
|
343
|
+
timestamp: new Date().toISOString(),
|
|
344
|
+
};
|
|
345
|
+
await this.sessionManager.addMessages(sessionId, [userMsg]);
|
|
346
|
+
// Write START log for crash recovery
|
|
347
|
+
const startLog = {
|
|
348
|
+
runId: entry.runId,
|
|
349
|
+
processName: entry.processName,
|
|
350
|
+
triggerType: entry.triggerType,
|
|
351
|
+
promptSummary,
|
|
352
|
+
sessionId,
|
|
353
|
+
owner: definition.owner,
|
|
354
|
+
status: 'running',
|
|
355
|
+
startedAt: new Date().toISOString(),
|
|
356
|
+
endedAt: '',
|
|
357
|
+
durationMs: 0,
|
|
358
|
+
eventPayload: entry.eventPayload,
|
|
359
|
+
};
|
|
360
|
+
await this.logger.writeLog(startLog);
|
|
361
|
+
// Emit process started event
|
|
362
|
+
this.eventBus?.emit(`process:started:${entry.processName}`, {
|
|
363
|
+
runId: entry.runId,
|
|
364
|
+
processName: entry.processName,
|
|
365
|
+
triggerType: entry.triggerType,
|
|
366
|
+
}, { source: 'server' });
|
|
367
|
+
// Execute AI call
|
|
368
|
+
const startTime = Date.now();
|
|
369
|
+
const timeout = parseDuration(this.config.executionTimeout);
|
|
370
|
+
try {
|
|
371
|
+
const options = {
|
|
372
|
+
sessionId,
|
|
373
|
+
// Each process execution creates a fresh session, so claudeSessionId is always
|
|
374
|
+
// undefined on the first run. Subsequent runs of the same process still start
|
|
375
|
+
// fresh sessions. This is by design: process executions are isolated.
|
|
376
|
+
resumeSessionId: session.claudeSessionId,
|
|
377
|
+
userToken,
|
|
378
|
+
timeout,
|
|
379
|
+
};
|
|
380
|
+
if (files && files.length > 0) {
|
|
381
|
+
options.files = files;
|
|
382
|
+
}
|
|
383
|
+
const stream = this.engine.call(prompt, options);
|
|
384
|
+
const result = await this.consumeAIStream(stream);
|
|
385
|
+
const durationMs = Date.now() - startTime;
|
|
386
|
+
const endedAt = new Date().toISOString();
|
|
387
|
+
// Persist assistant message to session (so the session has AI response history)
|
|
388
|
+
if (result.resultSummary || result.contentBlocks.length > 0) {
|
|
389
|
+
const assistantMsg = {
|
|
390
|
+
id: `resp_${userMsgId}`,
|
|
391
|
+
role: 'assistant',
|
|
392
|
+
content: result.resultSummary || '(empty response)',
|
|
393
|
+
timestamp: endedAt,
|
|
394
|
+
...(result.contentBlocks.length > 0 ? { contentBlocks: result.contentBlocks } : {}),
|
|
395
|
+
};
|
|
396
|
+
await this.sessionManager.addMessages(sessionId, [assistantMsg], result.claudeSessionId, result.usage);
|
|
397
|
+
}
|
|
398
|
+
else if (result.claudeSessionId || result.usage) {
|
|
399
|
+
// Even without content, update claudeSessionId/usage if available
|
|
400
|
+
await this.sessionManager.addMessages(sessionId, [], result.claudeSessionId, result.usage);
|
|
401
|
+
}
|
|
402
|
+
if (result.timedOut) {
|
|
403
|
+
// Safety net: kill session on timeout
|
|
404
|
+
if (this.engine instanceof ClaudeCodeEngine) {
|
|
405
|
+
try {
|
|
406
|
+
this.engine.killSession(sessionId);
|
|
407
|
+
}
|
|
408
|
+
catch { /* ignore */ }
|
|
409
|
+
}
|
|
410
|
+
this.queue.markTimeout(entry.runId);
|
|
411
|
+
await this.logger.writeLog({ ...startLog, status: 'timeout', endedAt, durationMs, error: result.error });
|
|
412
|
+
this.eventBus?.emit(`process:failed:${entry.processName}`, {
|
|
413
|
+
runId: entry.runId, processName: entry.processName, error: result.error, timedOut: true,
|
|
414
|
+
}, { source: 'server' });
|
|
415
|
+
}
|
|
416
|
+
else if (!result.success) {
|
|
417
|
+
this.queue.markFailed(entry.runId, result.error ?? 'Unknown error');
|
|
418
|
+
await this.logger.writeLog({ ...startLog, status: 'failed', endedAt, durationMs, error: result.error });
|
|
419
|
+
this.eventBus?.emit(`process:failed:${entry.processName}`, {
|
|
420
|
+
runId: entry.runId, processName: entry.processName, error: result.error,
|
|
421
|
+
}, { source: 'server' });
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
this.queue.markCompleted(entry.runId);
|
|
425
|
+
await this.logger.writeLog({ ...startLog, status: 'completed', endedAt, durationMs });
|
|
426
|
+
this.eventBus?.emit(`process:completed:${entry.processName}`, {
|
|
427
|
+
runId: entry.runId, processName: entry.processName, durationMs,
|
|
428
|
+
}, { source: 'server' });
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
catch (err) {
|
|
432
|
+
const durationMs = Date.now() - startTime;
|
|
433
|
+
const endedAt = new Date().toISOString();
|
|
434
|
+
const error = err instanceof Error ? err.message : String(err);
|
|
435
|
+
this.queue.markFailed(entry.runId, error);
|
|
436
|
+
await this.logger.writeLog({ ...startLog, status: 'failed', endedAt, durationMs, error });
|
|
437
|
+
this.eventBus?.emit(`process:failed:${entry.processName}`, {
|
|
438
|
+
runId: entry.runId, processName: entry.processName, error,
|
|
439
|
+
}, { source: 'server' });
|
|
440
|
+
}
|
|
441
|
+
// Try to execute next queued entry
|
|
442
|
+
this.tryExecuteNext();
|
|
443
|
+
}
|
|
444
|
+
// --- Public getters for routes ---
|
|
445
|
+
getQueueStatus() {
|
|
446
|
+
return this.queue.getQueueStatus();
|
|
447
|
+
}
|
|
448
|
+
getProcessStatus(name) {
|
|
449
|
+
const running = this.queue.getRunning().find(e => e.processName === name);
|
|
450
|
+
if (running)
|
|
451
|
+
return 'running';
|
|
452
|
+
// Check if paused (sync lookup from registry cache)
|
|
453
|
+
const process = this.registry.getProcessSync(name);
|
|
454
|
+
if (!process)
|
|
455
|
+
return 'idle';
|
|
456
|
+
if (process.paused)
|
|
457
|
+
return 'paused';
|
|
458
|
+
return 'idle';
|
|
459
|
+
}
|
|
460
|
+
listProcesses(options) {
|
|
461
|
+
return this.registry.listProcesses(options);
|
|
462
|
+
}
|
|
463
|
+
getProcess(name) {
|
|
464
|
+
return this.registry.getProcess(name);
|
|
465
|
+
}
|
|
466
|
+
getRunning() {
|
|
467
|
+
return this.queue.getRunning();
|
|
468
|
+
}
|
|
469
|
+
getLogger() {
|
|
470
|
+
return this.logger;
|
|
471
|
+
}
|
|
472
|
+
async getLogs(processName, options) {
|
|
473
|
+
return this.logger.listLogs(processName, options);
|
|
474
|
+
}
|
|
475
|
+
async getLog(processName, runId) {
|
|
476
|
+
return this.logger.readLog(processName, runId);
|
|
477
|
+
}
|
|
478
|
+
async getMetrics(processName) {
|
|
479
|
+
return this.logger.aggregateMetrics(processName);
|
|
480
|
+
}
|
|
481
|
+
async shutdown() {
|
|
482
|
+
this.isShutdown = true;
|
|
483
|
+
this.triggerManager.stopAll();
|
|
484
|
+
// Wait for running executions to complete (with 5s timeout)
|
|
485
|
+
const running = this.queue.getRunning();
|
|
486
|
+
if (running.length > 0) {
|
|
487
|
+
const timeout = new Promise(resolve => setTimeout(resolve, 5000));
|
|
488
|
+
await Promise.race([
|
|
489
|
+
Promise.all(running.map(async (entry) => {
|
|
490
|
+
// Mark as failed since we're shutting down
|
|
491
|
+
this.queue.markFailed(entry.runId, 'Server shutting down');
|
|
492
|
+
await this.logger.writeLog({
|
|
493
|
+
runId: entry.runId,
|
|
494
|
+
processName: entry.processName,
|
|
495
|
+
triggerType: entry.triggerType,
|
|
496
|
+
promptSummary: entry.promptSummary ?? '',
|
|
497
|
+
sessionId: entry.sessionId ?? '',
|
|
498
|
+
owner: '',
|
|
499
|
+
status: 'failed',
|
|
500
|
+
startedAt: entry.startedAt ?? new Date().toISOString(),
|
|
501
|
+
endedAt: new Date().toISOString(),
|
|
502
|
+
durationMs: 0,
|
|
503
|
+
error: 'Server shutting down',
|
|
504
|
+
});
|
|
505
|
+
})),
|
|
506
|
+
timeout,
|
|
507
|
+
]);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/backend/process/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { ProcessEngine } from './engine.js';
|
|
2
|
+
export type { ProcessEngineOptions } from './engine.js';
|
|
3
|
+
export { ProcessRegistry } from './registry.js';
|
|
4
|
+
export { TriggerManager } from './trigger.js';
|
|
5
|
+
export { ExecutionQueue } from './queue.js';
|
|
6
|
+
export { ProcessLogger } from './logger.js';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/backend/process/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { ProcessEngine } from './engine.js';
|
|
2
|
+
export { ProcessRegistry } from './registry.js';
|
|
3
|
+
export { TriggerManager } from './trigger.js';
|
|
4
|
+
export { ExecutionQueue } from './queue.js';
|
|
5
|
+
export { ProcessLogger } from './logger.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/backend/process/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProcessLogger - Execution log I/O with crash recovery and aggregate metrics
|
|
3
|
+
*
|
|
4
|
+
* Logs stored in .loom/process-logs/{processName}/{runId}.json
|
|
5
|
+
* Uses atomic write (temp file + rename) for safety.
|
|
6
|
+
*/
|
|
7
|
+
import type { ProcessLogEntry, ProcessMetricsAggregate } from '../../types/process.js';
|
|
8
|
+
export declare class ProcessLogger {
|
|
9
|
+
private logsDir;
|
|
10
|
+
constructor(projectRoot: string);
|
|
11
|
+
initialize(): Promise<void>;
|
|
12
|
+
writeLog(entry: ProcessLogEntry): Promise<void>;
|
|
13
|
+
readLog(processName: string, runId: string): Promise<ProcessLogEntry | null>;
|
|
14
|
+
listLogs(processName: string, options?: {
|
|
15
|
+
limit?: number;
|
|
16
|
+
offset?: number;
|
|
17
|
+
}): Promise<ProcessLogEntry[]>;
|
|
18
|
+
listProcessNames(): Promise<string[]>;
|
|
19
|
+
/**
|
|
20
|
+
* Crash recovery: find log entries with status='running' and mark them as failed.
|
|
21
|
+
* Called during ProcessEngine.initialize().
|
|
22
|
+
*/
|
|
23
|
+
recoverCrashedEntries(): Promise<number>;
|
|
24
|
+
/**
|
|
25
|
+
* Aggregate metrics from log entries for a process.
|
|
26
|
+
* Groups by date, computes totals and averages.
|
|
27
|
+
*/
|
|
28
|
+
aggregateMetrics(processName: string): Promise<ProcessMetricsAggregate[]>;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/backend/process/logger.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEvF,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAS;gBAEZ,WAAW,EAAE,MAAM;IAIzB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,QAAQ,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAW/C,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAU5E,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IA4BxG,gBAAgB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAS3C;;;OAGG;IACG,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC;IAuB9C;;;OAGG;IACG,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,EAAE,CAAC;CAoChF"}
|