@loom-framework/core 0.1.0-alpha.180 → 0.1.0-alpha.181

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 (105) hide show
  1. package/builtin-skills/app-skill/SKILL.md +4 -5
  2. package/builtin-skills/app-skill/references/auth.md +79 -79
  3. package/builtin-skills/app-skill/references/events.md +237 -19
  4. package/builtin-skills/app-skill/references/evolution.md +59 -59
  5. package/builtin-skills/app-skill/references/model.md +48 -48
  6. package/builtin-skills/app-skill/references/notification.md +47 -47
  7. package/builtin-skills/app-skill/references/process-builder.md +173 -197
  8. package/builtin-skills/app-skill/references/process.md +274 -163
  9. package/builtin-skills/loom/SKILL.md +17 -10
  10. package/builtin-skills/loom/references/data-model.md +19 -3
  11. package/dist/backend/auth/rbac.js +1 -1
  12. package/dist/backend/auth/rbac.js.map +1 -1
  13. package/dist/backend/events/subscription-service.d.ts +46 -0
  14. package/dist/backend/events/subscription-service.d.ts.map +1 -0
  15. package/dist/backend/events/subscription-service.js +209 -0
  16. package/dist/backend/events/subscription-service.js.map +1 -0
  17. package/dist/backend/index.d.ts +1 -0
  18. package/dist/backend/index.d.ts.map +1 -1
  19. package/dist/backend/index.js +27 -13
  20. package/dist/backend/index.js.map +1 -1
  21. package/dist/backend/lifecycle/manager.d.ts +4 -2
  22. package/dist/backend/lifecycle/manager.d.ts.map +1 -1
  23. package/dist/backend/lifecycle/manager.js +9 -3
  24. package/dist/backend/lifecycle/manager.js.map +1 -1
  25. package/dist/backend/loom-paths.d.ts +3 -1
  26. package/dist/backend/loom-paths.d.ts.map +1 -1
  27. package/dist/backend/loom-paths.js +5 -1
  28. package/dist/backend/loom-paths.js.map +1 -1
  29. package/dist/backend/process/engine.d.ts +15 -1
  30. package/dist/backend/process/engine.d.ts.map +1 -1
  31. package/dist/backend/process/engine.js +79 -23
  32. package/dist/backend/process/engine.js.map +1 -1
  33. package/dist/backend/process/registry.d.ts +44 -9
  34. package/dist/backend/process/registry.d.ts.map +1 -1
  35. package/dist/backend/process/registry.js +208 -40
  36. package/dist/backend/process/registry.js.map +1 -1
  37. package/dist/backend/process/trigger.d.ts +18 -8
  38. package/dist/backend/process/trigger.d.ts.map +1 -1
  39. package/dist/backend/process/trigger.js +86 -32
  40. package/dist/backend/process/trigger.js.map +1 -1
  41. package/dist/backend/routes/ai-config.d.ts.map +1 -1
  42. package/dist/backend/routes/ai-config.js +1 -69
  43. package/dist/backend/routes/ai-config.js.map +1 -1
  44. package/dist/backend/routes/config-writer.d.ts +94 -0
  45. package/dist/backend/routes/config-writer.d.ts.map +1 -0
  46. package/dist/backend/routes/config-writer.js +522 -0
  47. package/dist/backend/routes/config-writer.js.map +1 -0
  48. package/dist/backend/routes/event-routes.d.ts +9 -2
  49. package/dist/backend/routes/event-routes.d.ts.map +1 -1
  50. package/dist/backend/routes/event-routes.js +101 -7
  51. package/dist/backend/routes/event-routes.js.map +1 -1
  52. package/dist/backend/routes/process-routes.d.ts +3 -0
  53. package/dist/backend/routes/process-routes.d.ts.map +1 -1
  54. package/dist/backend/routes/process-routes.js +120 -49
  55. package/dist/backend/routes/process-routes.js.map +1 -1
  56. package/dist/cli/commands/event.d.ts +12 -0
  57. package/dist/cli/commands/event.d.ts.map +1 -0
  58. package/dist/cli/commands/event.js +332 -0
  59. package/dist/cli/commands/event.js.map +1 -0
  60. package/dist/cli/commands/process.d.ts.map +1 -1
  61. package/dist/cli/commands/process.js +82 -44
  62. package/dist/cli/commands/process.js.map +1 -1
  63. package/dist/cli/generators/capability-generator.d.ts.map +1 -1
  64. package/dist/cli/generators/capability-generator.js +28 -32
  65. package/dist/cli/generators/capability-generator.js.map +1 -1
  66. package/dist/cli/helpers/system-page-config.d.ts +1 -1
  67. package/dist/cli/helpers/system-page-config.d.ts.map +1 -1
  68. package/dist/cli/helpers/system-page-config.js +9 -0
  69. package/dist/cli/helpers/system-page-config.js.map +1 -1
  70. package/dist/cli/index.d.ts.map +1 -1
  71. package/dist/cli/index.js +2 -0
  72. package/dist/cli/index.js.map +1 -1
  73. package/dist/cli/templates/event-management-page.d.ts +8 -0
  74. package/dist/cli/templates/event-management-page.d.ts.map +1 -0
  75. package/dist/cli/templates/event-management-page.js +598 -0
  76. package/dist/cli/templates/event-management-page.js.map +1 -0
  77. package/dist/cli/templates/login-page.d.ts +1 -1
  78. package/dist/cli/templates/login-page.js +1 -1
  79. package/dist/cli/templates/model-management-page.d.ts +1 -1
  80. package/dist/cli/templates/model-management-page.js +1 -1
  81. package/dist/cli/templates/notification-center-page.d.ts +1 -1
  82. package/dist/cli/templates/notification-center-page.js +1 -1
  83. package/dist/cli/templates/notification-detail-page.d.ts +1 -1
  84. package/dist/cli/templates/notification-detail-page.js +1 -1
  85. package/dist/cli/templates/process-management-page.d.ts +1 -1
  86. package/dist/cli/templates/process-management-page.js +1 -1
  87. package/dist/cli/templates/skill-management-page.d.ts +1 -1
  88. package/dist/cli/templates/skill-management-page.js +1 -1
  89. package/dist/cli/templates/user-management-page.d.ts +1 -1
  90. package/dist/cli/templates/user-management-page.js +1 -1
  91. package/dist/config.d.ts +327 -11
  92. package/dist/config.d.ts.map +1 -1
  93. package/dist/config.js +26 -7
  94. package/dist/config.js.map +1 -1
  95. package/dist/index.d.ts +1 -0
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.js.map +1 -1
  98. package/dist/types/event.d.ts +6 -0
  99. package/dist/types/event.d.ts.map +1 -1
  100. package/dist/types/index.d.ts +1 -1
  101. package/dist/types/index.d.ts.map +1 -1
  102. package/dist/types/process.d.ts +45 -7
  103. package/dist/types/process.d.ts.map +1 -1
  104. package/package.json +1 -1
  105. package/builtin-skills/app-skill/references/process-metrics.md +0 -93
@@ -0,0 +1,522 @@
1
+ /**
2
+ * Config Writer — Surgically modify loom.config.ts
3
+ *
4
+ * Provides string/comment-aware bracket matching and section-level writes
5
+ * for processes.definitions, events.subscriptions, and ai.claudeCode.models.
6
+ *
7
+ * Key design decisions:
8
+ * - `findMatchingBracket()` tracks both `[]` and `{}` depth
9
+ * - `skipStringAndComment()` skips string literals, template literals, and comments
10
+ * - All writes are atomic: backup → modify → write → verify (failed writes restore from .bak)
11
+ * - `writeModelsToConfig()` refactored to use `findMatchingBracket()` for robustness
12
+ */
13
+ import fs from 'fs/promises';
14
+ import path from 'path';
15
+ import { generateId } from '../../utils/id.js';
16
+ // ---------------------------------------------------------------------------
17
+ // String/comment-aware scanner
18
+ // ---------------------------------------------------------------------------
19
+ /**
20
+ * Skip over a string literal, template literal, or comment starting at `pos`.
21
+ * Returns the position AFTER the closed string/comment.
22
+ * If the character at `pos` is not a string/comment opener, returns `pos` unchanged.
23
+ */
24
+ export function skipStringAndComment(text, pos) {
25
+ const ch = text[pos];
26
+ if (ch === undefined)
27
+ return pos;
28
+ // String literals: " or '
29
+ if (ch === '"' || ch === "'") {
30
+ const quote = ch;
31
+ let p = pos + 1;
32
+ while (p < text.length) {
33
+ if (text[p] === '\\') {
34
+ p += 2;
35
+ continue;
36
+ } // escape
37
+ if (text[p] === quote)
38
+ return p + 1; // closing quote
39
+ p++;
40
+ }
41
+ return p; // unclosed string — return end
42
+ }
43
+ // Template literals: `
44
+ if (ch === '`') {
45
+ let p = pos + 1;
46
+ while (p < text.length) {
47
+ if (text[p] === '\\') {
48
+ p += 2;
49
+ continue;
50
+ }
51
+ if (text[p] === '`')
52
+ return p + 1; // closing backtick
53
+ // Template literal interpolation: ${...}
54
+ if (text[p] === '$' && text[p + 1] === '{') {
55
+ p += 2;
56
+ let depth = 1;
57
+ while (p < text.length && depth > 0) {
58
+ const next = skipStringAndComment(text, p);
59
+ if (next > p) {
60
+ p = next;
61
+ continue;
62
+ }
63
+ if (text[p] === '{')
64
+ depth++;
65
+ else if (text[p] === '}')
66
+ depth--;
67
+ p++;
68
+ }
69
+ continue;
70
+ }
71
+ p++;
72
+ }
73
+ return p; // unclosed template
74
+ }
75
+ // Single-line comment: //
76
+ if (ch === '/' && text[pos + 1] === '/') {
77
+ const newline = text.indexOf('\n', pos);
78
+ return newline === -1 ? text.length : newline + 1;
79
+ }
80
+ // Multi-line comment: /* ... */
81
+ if (ch === '/' && text[pos + 1] === '*') {
82
+ const end = text.indexOf('*/', pos + 2);
83
+ return end === -1 ? text.length : end + 2;
84
+ }
85
+ return pos; // not a string/comment
86
+ }
87
+ /**
88
+ * Find the matching bracket for an open bracket at `start`.
89
+ * Skips strings, comments, and tracks depth for both `[]` and `{}`.
90
+ * Returns the position AFTER the closing bracket.
91
+ */
92
+ export function findMatchingBracket(text, start, open, close) {
93
+ let depth = 1;
94
+ let pos = start + 1;
95
+ while (pos < text.length && depth > 0) {
96
+ const nextPos = skipStringAndComment(text, pos);
97
+ if (nextPos > pos) {
98
+ pos = nextPos;
99
+ continue;
100
+ }
101
+ if (text[pos] === open)
102
+ depth++;
103
+ else if (text[pos] === close)
104
+ depth--;
105
+ pos++;
106
+ }
107
+ return pos;
108
+ }
109
+ /**
110
+ * Write one or more sections to loom.config.ts.
111
+ * Creates a .bak backup before writing and restores on failure.
112
+ */
113
+ export async function writeConfigSection(projectRoot, sections) {
114
+ const configPath = path.join(projectRoot, 'loom.config.ts');
115
+ const bakPath = configPath + '.bak';
116
+ // Read original — if missing, create a minimal config
117
+ let content;
118
+ try {
119
+ content = await fs.readFile(configPath, 'utf-8');
120
+ }
121
+ catch {
122
+ content = `import { defineConfig } from '@loom-framework/core';\n\nexport default defineConfig({\n});\n`;
123
+ await fs.mkdir(projectRoot, { recursive: true });
124
+ await fs.writeFile(configPath, content, 'utf-8');
125
+ }
126
+ // Backup
127
+ await fs.writeFile(bakPath, content, 'utf-8');
128
+ try {
129
+ for (const section of sections) {
130
+ content = applySectionEdit(content, section);
131
+ }
132
+ await fs.writeFile(configPath, content, 'utf-8');
133
+ }
134
+ catch (err) {
135
+ // Restore backup on failure
136
+ const original = await fs.readFile(bakPath, 'utf-8');
137
+ await fs.writeFile(configPath, original, 'utf-8');
138
+ throw err;
139
+ }
140
+ finally {
141
+ // Clean up backup
142
+ await fs.unlink(bakPath).catch(() => { });
143
+ }
144
+ }
145
+ /**
146
+ * Apply a single section edit in-memory.
147
+ */
148
+ function applySectionEdit(content, section) {
149
+ const indent = ' '.repeat(section.baseIndent);
150
+ // Try to find existing field inside parent
151
+ const parentMatch = section.parentRegex.exec(content);
152
+ if (parentMatch) {
153
+ // Found the parent object — look for the field inside it
154
+ const afterParent = parentMatch.index + parentMatch[0].length;
155
+ const fieldRegex = new RegExp(`(\\b${section.fieldKey}\\s*:\\s*)[\\[\\{]`);
156
+ const fieldMatch = fieldRegex.exec(content.slice(afterParent));
157
+ if (fieldMatch) {
158
+ // Existing field — replace it
159
+ const fieldAbsPos = afterParent + fieldMatch.index;
160
+ const fieldPrefixEnd = afterParent + fieldMatch.index + fieldMatch[1].length;
161
+ const openBracket = content[fieldPrefixEnd];
162
+ const closeBracket = openBracket === '[' ? ']' : '}';
163
+ const bracketEnd = findMatchingBracket(content, fieldPrefixEnd, openBracket, closeBracket);
164
+ // fieldValue already has correct indentation from toTsLiteral — use as-is
165
+ content = content.slice(0, fieldAbsPos) + `${section.fieldKey}: ${section.fieldValue}` + content.slice(bracketEnd);
166
+ }
167
+ else {
168
+ // Parent exists but field doesn't — insert into parent
169
+ const parentOpen = content.indexOf('{', afterParent - 1);
170
+ if (parentOpen === -1) {
171
+ throw new Error(`Cannot find opening brace for parent matching ${section.parentRegex}`);
172
+ }
173
+ const insertPos = parentOpen + 1;
174
+ const needsComma = !content.slice(insertPos).match(/^\s*\}/);
175
+ content = content.slice(0, insertPos) +
176
+ `\n${indent}${section.fieldKey}: ${section.fieldValue}${needsComma ? ',' : ''}` +
177
+ content.slice(insertPos);
178
+ }
179
+ }
180
+ else if (section.fallbackParent) {
181
+ // Try fallback: add parent with the field
182
+ const fallbackMatch = new RegExp(`(${section.fallbackParent.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')})`).exec(content);
183
+ if (fallbackMatch) {
184
+ const insertPos = fallbackMatch.index + fallbackMatch[0].length;
185
+ content = content.slice(0, insertPos) +
186
+ ` {\n${indent}${section.fieldKey}: ${section.fieldValue},\n }` +
187
+ content.slice(insertPos);
188
+ }
189
+ else if (section.fallbackSection) {
190
+ // No match at all — insert the full fallback section
191
+ const configEnd = content.lastIndexOf('});');
192
+ if (configEnd === -1) {
193
+ throw new Error(`Cannot find defineConfig closing '});' in ${path.basename(content)}`);
194
+ }
195
+ content = content.slice(0, configEnd) + section.fallbackSection + '\n' + content.slice(configEnd);
196
+ }
197
+ else {
198
+ throw new Error(`Cannot find parent for field "${section.fieldKey}" and no fallback provided`);
199
+ }
200
+ }
201
+ else if (section.fallbackSection) {
202
+ const configEnd = content.lastIndexOf('});');
203
+ if (configEnd === -1) {
204
+ throw new Error(`Cannot find defineConfig closing '});' in loom.config.ts`);
205
+ }
206
+ content = content.slice(0, configEnd) + section.fallbackSection + '\n' + content.slice(configEnd);
207
+ }
208
+ else {
209
+ throw new Error(`Cannot find target section for "${section.fieldKey}" in loom.config.ts and no fallback provided`);
210
+ }
211
+ return content;
212
+ }
213
+ // ---------------------------------------------------------------------------
214
+ // TS literal formatting (replaces JSON.stringify for loom.config.ts output)
215
+ // ---------------------------------------------------------------------------
216
+ /**
217
+ * Format a JS value as a TypeScript literal string (unquoted keys, single-quoted strings).
218
+ * Omits null/undefined values from objects. Compact one-line for short objects, multi-line otherwise.
219
+ */
220
+ function toTsLiteral(value, indent = 0) {
221
+ const pad = ' '.repeat(indent);
222
+ const innerPad = ' '.repeat(indent + 2);
223
+ if (value === null || value === undefined)
224
+ return 'null';
225
+ if (typeof value === 'boolean')
226
+ return value ? 'true' : 'false';
227
+ if (typeof value === 'number')
228
+ return String(value);
229
+ if (typeof value === 'string') {
230
+ return `'${value.replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`;
231
+ }
232
+ if (Array.isArray(value)) {
233
+ if (value.length === 0)
234
+ return '[]';
235
+ const items = value.map(v => `${innerPad}${toTsLiteral(v, indent + 2)}`);
236
+ return '[\n' + items.join(',\n') + ',\n' + pad + ']';
237
+ }
238
+ if (typeof value === 'object') {
239
+ const entries = Object.entries(value)
240
+ .filter(([, v]) => v !== null && v !== undefined);
241
+ if (entries.length === 0)
242
+ return '{}';
243
+ // Try compact one-line format
244
+ const oneLine = tsObjOneLine(entries);
245
+ if (oneLine.length <= 80)
246
+ return oneLine;
247
+ // Multi-line format
248
+ const lines = entries.map(([k, v]) => {
249
+ const keyStr = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(k) ? k : `'${k}'`;
250
+ return `${innerPad}${keyStr}: ${toTsLiteral(v, indent + 2)}`;
251
+ });
252
+ return '{\n' + lines.join(',\n') + ',\n' + pad + '}';
253
+ }
254
+ return String(value);
255
+ }
256
+ /** One-line format for an object, used when compact enough. */
257
+ function tsObjOneLine(entries) {
258
+ const parts = entries.map(([k, v]) => {
259
+ const keyStr = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(k) ? k : `'${k}'`;
260
+ return `${keyStr}: ${tsValueOneLine(v)}`;
261
+ });
262
+ return `{ ${parts.join(', ')} }`;
263
+ }
264
+ /** One-line format for a single value (recursive for nested objects). */
265
+ function tsValueOneLine(value) {
266
+ if (value === null || value === undefined)
267
+ return 'null';
268
+ if (typeof value === 'boolean')
269
+ return value ? 'true' : 'false';
270
+ if (typeof value === 'number')
271
+ return String(value);
272
+ if (typeof value === 'string')
273
+ return `'${value.replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`;
274
+ if (Array.isArray(value)) {
275
+ if (value.length === 0)
276
+ return '[]';
277
+ const items = value.map(v => tsValueOneLine(v));
278
+ return `[${items.join(', ')}]`;
279
+ }
280
+ if (typeof value === 'object') {
281
+ const entries = Object.entries(value)
282
+ .filter(([, v]) => v !== null && v !== undefined);
283
+ if (entries.length === 0)
284
+ return '{}';
285
+ return tsObjOneLine(entries);
286
+ }
287
+ return String(value);
288
+ }
289
+ // ---------------------------------------------------------------------------
290
+ // Convenience functions
291
+ // ---------------------------------------------------------------------------
292
+ /**
293
+ * Write models array to loom.config.ts.
294
+ * Refactored to use findMatchingBracket() for string/comment awareness.
295
+ */
296
+ export async function writeModelsToConfig(projectRoot, models) {
297
+ const configPath = path.join(projectRoot, 'loom.config.ts');
298
+ const bakPath = configPath + '.bak';
299
+ // Read original — if missing, create a minimal config
300
+ let content;
301
+ try {
302
+ content = await fs.readFile(configPath, 'utf-8');
303
+ }
304
+ catch {
305
+ content = `import { defineConfig } from '@loom-framework/core';\n\nexport default defineConfig({\n});\n`;
306
+ await fs.mkdir(projectRoot, { recursive: true });
307
+ await fs.writeFile(configPath, content, 'utf-8');
308
+ }
309
+ // Backup
310
+ await fs.writeFile(bakPath, content, 'utf-8');
311
+ try {
312
+ const modelsStr = toTsLiteral(models, 4);
313
+ const modelsText = `models: ${modelsStr}`;
314
+ // Try to replace existing models field inside claudeCode
315
+ const modelsStartRegex = /(\bclaudeCode:\s*\{[\s\S]*?)models:\s*\[/;
316
+ const match = modelsStartRegex.exec(content);
317
+ if (match) {
318
+ const arrayStart = match.index + match[0].length - 1;
319
+ const arrayEnd = findMatchingBracket(content, arrayStart, '[', ']');
320
+ const prefix = match[1];
321
+ content = content.slice(0, match.index) + prefix + modelsText + content.slice(arrayEnd);
322
+ }
323
+ else {
324
+ // No models field yet — check if claudeCode object exists
325
+ const claudeCodeMatch = content.match(/(claudeCode:\s*\{)/);
326
+ if (claudeCodeMatch) {
327
+ const insertPos = claudeCodeMatch.index + claudeCodeMatch[0].length;
328
+ const needsComma = !content.slice(insertPos).match(/^\s*\}/);
329
+ content = content.slice(0, insertPos) +
330
+ '\n ' + modelsText + (needsComma ? ',' : '') +
331
+ content.slice(insertPos);
332
+ }
333
+ else {
334
+ const aiMatch = content.match(/(ai:\s*\{)/);
335
+ if (aiMatch) {
336
+ const insertPos = aiMatch.index + aiMatch[0].length;
337
+ content = content.slice(0, insertPos) +
338
+ '\n claudeCode: {\n ' + modelsText + ',\n },' +
339
+ content.slice(insertPos);
340
+ }
341
+ else {
342
+ const configEnd = content.lastIndexOf('});');
343
+ if (configEnd !== -1) {
344
+ content = content.slice(0, configEnd) +
345
+ ' ai: {\n claudeCode: {\n ' + modelsText + ',\n },\n },\n' +
346
+ content.slice(configEnd);
347
+ }
348
+ }
349
+ }
350
+ }
351
+ await fs.writeFile(configPath, content, 'utf-8');
352
+ }
353
+ catch (err) {
354
+ const original = await fs.readFile(bakPath, 'utf-8');
355
+ await fs.writeFile(configPath, original, 'utf-8');
356
+ throw err;
357
+ }
358
+ finally {
359
+ await fs.unlink(bakPath).catch(() => { });
360
+ }
361
+ }
362
+ /**
363
+ * Write process definitions to loom.config.ts (processes.definitions).
364
+ */
365
+ export async function writeProcessesToConfig(projectRoot, definitions) {
366
+ // Remove runtime-only fields for config output
367
+ const clean = definitions.map(({ ownerToken, ...rest }) => rest);
368
+ const definitionsStr = toTsLiteral(clean, 4);
369
+ await writeConfigSection(projectRoot, [{
370
+ parentRegex: /processes:\s*\{/,
371
+ fieldKey: 'definitions',
372
+ fieldValue: definitionsStr,
373
+ baseIndent: 4,
374
+ fallbackParent: 'processes:',
375
+ fallbackSection: ' processes: {\n definitions: ' + definitionsStr + ',\n },',
376
+ }]);
377
+ }
378
+ /**
379
+ * Write event subscriptions to loom.config.ts (events.subscriptions).
380
+ */
381
+ export async function writeEventSubscriptionsToConfig(projectRoot, subscriptions) {
382
+ const subsStr = toTsLiteral(subscriptions, 4);
383
+ await writeConfigSection(projectRoot, [{
384
+ parentRegex: /events:\s*\{/,
385
+ fieldKey: 'subscriptions',
386
+ fieldValue: subsStr,
387
+ baseIndent: 4,
388
+ fallbackParent: 'events:',
389
+ fallbackSection: ' events: {\n subscriptions: ' + subsStr + ',\n },',
390
+ }]);
391
+ }
392
+ /**
393
+ * Atomically write a process definition and its event subscription at the same time.
394
+ * This ensures that a process with a source always has its subscription in the same write.
395
+ * Uses writeConfigSection with multiple sections for atomicity (single backup/restore cycle).
396
+ */
397
+ export async function writeProcessWithSubscription(projectRoot, definition, subscription, mode = 'add') {
398
+ // Read current definitions and subscriptions
399
+ const [currentDefs, currentSubs] = await Promise.all([
400
+ readProcessDefinitions(projectRoot),
401
+ readEventSubscriptions(projectRoot),
402
+ ]);
403
+ const sections = [];
404
+ if (mode === 'add') {
405
+ // Add/replace definition
406
+ const existingIdx = currentDefs.findIndex(d => d.name === definition.name);
407
+ const newDefs = [...currentDefs];
408
+ if (existingIdx !== -1) {
409
+ newDefs[existingIdx] = definition;
410
+ }
411
+ else {
412
+ newDefs.push(definition);
413
+ }
414
+ const defsStr = toTsLiteral(newDefs.map(({ ownerToken, ...rest }) => rest), 4);
415
+ sections.push({
416
+ parentRegex: /processes:\s*\{/,
417
+ fieldKey: 'definitions',
418
+ fieldValue: defsStr,
419
+ baseIndent: 4,
420
+ fallbackParent: 'processes:',
421
+ fallbackSection: ' processes: {\n definitions: ' + defsStr + ',\n },',
422
+ });
423
+ // Add subscription if provided
424
+ if (subscription) {
425
+ const subEntry = {
426
+ pattern: subscription.pattern,
427
+ handler: 'process',
428
+ config: subscription.config,
429
+ };
430
+ const newSubs = [...currentSubs, subEntry];
431
+ const subsStr = toTsLiteral(newSubs, 4);
432
+ sections.push({
433
+ parentRegex: /events:\s*\{/,
434
+ fieldKey: 'subscriptions',
435
+ fieldValue: subsStr,
436
+ baseIndent: 4,
437
+ fallbackParent: 'events:',
438
+ fallbackSection: ' events: {\n subscriptions: ' + subsStr + ',\n },',
439
+ });
440
+ }
441
+ }
442
+ else {
443
+ // Remove mode: remove definition and its subscriptions
444
+ const newDefs = currentDefs.filter(d => d.name !== definition.name);
445
+ const defsStr = toTsLiteral(newDefs.map(({ ownerToken, ...rest }) => rest), 4);
446
+ sections.push({
447
+ parentRegex: /processes:\s*\{/,
448
+ fieldKey: 'definitions',
449
+ fieldValue: defsStr,
450
+ baseIndent: 4,
451
+ fallbackParent: 'processes:',
452
+ fallbackSection: ' processes: {\n definitions: ' + defsStr + ',\n },',
453
+ });
454
+ // Remove subscriptions for this process
455
+ const newSubs = currentSubs.filter(s => !(s.handler === 'process' && s.config.process === definition.name));
456
+ const subsStr = toTsLiteral(newSubs, 4);
457
+ sections.push({
458
+ parentRegex: /events:\s*\{/,
459
+ fieldKey: 'subscriptions',
460
+ fieldValue: subsStr,
461
+ baseIndent: 4,
462
+ fallbackParent: 'events:',
463
+ fallbackSection: ' events: {\n subscriptions: ' + subsStr + ',\n },',
464
+ });
465
+ }
466
+ await writeConfigSection(projectRoot, sections);
467
+ }
468
+ /**
469
+ * Read process definitions from loom.config.ts.
470
+ */
471
+ export async function readProcessDefinitions(projectRoot) {
472
+ try {
473
+ const { loadConfig } = await import('../../config.js');
474
+ const config = await loadConfig(projectRoot);
475
+ return config.processes?.definitions ?? [];
476
+ }
477
+ catch {
478
+ return [];
479
+ }
480
+ }
481
+ /**
482
+ * Read event subscriptions from loom.config.ts.
483
+ */
484
+ export async function readEventSubscriptions(projectRoot) {
485
+ try {
486
+ const { loadConfig } = await import('../../config.js');
487
+ const config = await loadConfig(projectRoot);
488
+ return config.events?.subscriptions ?? [];
489
+ }
490
+ catch {
491
+ return [];
492
+ }
493
+ }
494
+ /**
495
+ * Find a subscription by its stable ID.
496
+ * Returns the subscription object or undefined if not found.
497
+ */
498
+ export function findSubscriptionById(subscriptions, id) {
499
+ return subscriptions.find(sub => sub.id === id);
500
+ }
501
+ /**
502
+ * Ensure every subscription has a stable `id`.
503
+ * Assigns IDs to any subscriptions missing one, then writes back if changed.
504
+ * Returns the subscriptions with all IDs populated.
505
+ *
506
+ * Should be called once at server startup, not on every read.
507
+ */
508
+ export async function ensureSubscriptionIds(projectRoot) {
509
+ const subscriptions = await readEventSubscriptions(projectRoot);
510
+ let changed = false;
511
+ for (const sub of subscriptions) {
512
+ if (!sub.id) {
513
+ sub.id = generateId('sub');
514
+ changed = true;
515
+ }
516
+ }
517
+ if (changed) {
518
+ await writeEventSubscriptionsToConfig(projectRoot, subscriptions);
519
+ }
520
+ return subscriptions;
521
+ }
522
+ //# sourceMappingURL=config-writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-writer.js","sourceRoot":"","sources":["../../../src/backend/routes/config-writer.ts"],"names":[],"mappings":"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"}
@@ -1,15 +1,22 @@
1
1
  /**
2
2
  * Event Routes - REST API for event system
3
3
  *
4
- * POST /api/v1/events/notify Re-emit an event from CLI or external source
5
- * GET /api/v1/events/patterns — List registered event patterns
4
+ * POST /api/v1/events/emit Emit an event from CLI or external source
5
+ * GET /api/v1/events/patterns — List registered event patterns
6
+ * GET /api/v1/events/subscriptions — List all event subscriptions
7
+ * POST /api/v1/events/subscriptions — Add a subscription
8
+ * PUT /api/v1/events/subscriptions/:id — Update a subscription (partial)
9
+ * DELETE /api/v1/events/subscriptions/:id — Remove a subscription
10
+ * POST /api/v1/events/test — Emit a test event (debug)
6
11
  */
7
12
  import type { FastifyInstance } from 'fastify';
8
13
  import type { EventBus } from '../events/event-bus.js';
9
14
  import type { EventRegistry } from '../events/event-registry.js';
15
+ import type { SubscriptionService } from '../events/subscription-service.js';
10
16
  export interface EventRouteOptions {
11
17
  eventBus: EventBus;
12
18
  eventRegistry?: EventRegistry;
19
+ subscriptionService?: SubscriptionService;
13
20
  }
14
21
  export declare function registerEventRoutes(fastify: FastifyInstance, options: EventRouteOptions): void;
15
22
  //# sourceMappingURL=event-routes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"event-routes.d.ts","sourceRoot":"","sources":["../../../src/backend/routes/event-routes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEjE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,QAAQ,CAAC;IACnB,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAYD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,iBAAiB,GAAG,IAAI,CA0B9F"}
1
+ {"version":3,"file":"event-routes.d.ts","sourceRoot":"","sources":["../../../src/backend/routes/event-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAG7E,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,QAAQ,CAAC;IACnB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;CAC3C;AAYD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAsI9F"}