@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
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: Loom
3
3
  description: |
4
- Use this skill when the user asks to "create a new loom project", "用loom开发一个系统",
4
+ This skill should be used when the user asks to "create a new loom project", "用loom开发一个系统",
5
5
  "开发一个AI平台应用", "为系统添加页面", "为项目配置 AI 按钮功能",
6
6
  "添加功能", "新增功能", "添加管理", "新增管理", "添加页面", "新增页面",
7
7
  "生成页面", "添加数据模型", "新增数据模型", or any Loom framework task.
@@ -23,6 +23,8 @@ Loom 是**配置驱动的 AI 平台开发框架**——你描述需求,AI 通
23
23
 
24
24
  核心能力:`loom generate page` 生成 CRUD 页面,`loom generate capabilities` 生成应用 Skill(让 AI 理解项目业务),`loom generate dashboard` 生成数据概览。后端 API 由 `loom dev` 根据配置动态注册,无需手动编写。生成的页面自带 AI 助手,支持流式对话和多会话。
25
25
 
26
+ > **运行时操作**:项目创建后,日常运营(数据 CRUD、过程管理、事件订阅、通知操作)由 **App-Skill** 提供指引。App-Skill 在 `loom generate capabilities` 后自动生成于 `.claude/skills/<projectName>/`,与本 Skill 互补。
27
+
26
28
  完整使用手册见 `references/README.md`。
27
29
 
28
30
  ## 开发流程
@@ -45,7 +47,7 @@ npx -p @loom-framework/core loom init <name> --description <desc> --adapter <fil
45
47
 
46
48
  `loom init` 时**必须显式指定两个端口**。如果启动时报 `EADDRINUSE`,说明端口被占用,请换端口重新 `init`。
47
49
 
48
- 项目初始化时自动生成系统管理页面(模型管理、技能管理、用户管理、过程管理、通知中心),并以子菜单形式接入导航。同时自动安装以下内置 Skill:
50
+ 项目初始化时自动生成系统管理页面(模型管理、技能管理、用户管理、过程管理、事件管理、通知中心),并以子菜单形式接入导航。同时自动安装以下内置 Skill:
49
51
 
50
52
  | Skill | 触发场景 | 说明 |
51
53
  |-------|---------|------|
@@ -94,10 +96,10 @@ loom generate capabilities
94
96
 
95
97
  首次生成项目SKILL后,需要补充其 `SKILL.md` 主文档中的 TODO 内容,AI 对话时才能正确理解项目业务语义:
96
98
 
97
- 1. **frontmatter `description`**:写入用户在 AI 对话中会说的触发短语。格式参考:
99
+ 1. **frontmatter `description`**:系统操作触发短语已自动生成,只需补全数据模型相关的 `[TODO]` 占位部分(如 `'查看告警'`, `'添加任务'`)。格式参考:
98
100
  ```
99
- This skill should be used when the user asks to "创建XXX", "查看XXX", "删除XXX",
100
- or any request about managing XXX in the <项目名> project.
101
+ This skill should be used when the user asks to "[TODO: 补全数据模型相关短语]", '用户管理', '事件订阅', ...,
102
+ or any request about managing data, processes, events, or notifications in the <项目名> project.
101
103
  ```
102
104
  2. **Overview 部分**:用 2-3 句话描述项目做什么、有哪些数据、用户如何与数据交互
103
105
  3. **Usage Scenarios 部分**:列出 5-10 个典型用户请求,格式为 `- "用户说的话" → 对应的 CLI 命令`
@@ -162,7 +164,7 @@ loom dev --frontend-port 8080 # 临时覆盖前端端口
162
164
  - 需要在 Dashboard 追加图表 → 参考 `references/dashboard.md` + `/antv-g2-chart` 生成代码
163
165
  - 对话中需展示数据可视化 → 用 `/chart-visualization` 生成图片
164
166
 
165
- ### 9. CLI 命令速查
167
+ ### 10. CLI 命令速查
166
168
 
167
169
  | 命令 | 说明 |
168
170
  |------|------|
@@ -173,9 +175,9 @@ loom dev --frontend-port 8080 # 临时覆盖前端端口
173
175
  | `loom generate capabilities` | 生成应用 Skill(`references/models.md` + `references/data-semantics.md`,`SKILL.md` 仅首次创建不覆盖) |
174
176
  | `loom generate dashboard <name>` | 从 loom.config.ts dashboards 生成 Dashboard 页面 |
175
177
  | `loom generate dashboard <name> --force` | 重建 Dashboard 页面(自动备份旧文件到 `.loom/backup/`) |
176
- | `loom generate system-settings <type>` | 将系统页面接入 App.tsx(npm import 接线),type: `model`/`skill`/`user`/`login`/`process`/`notification`;`user` 同时接入 AuthProvider 路由守卫,`notification` 同时接入 NotificationCenterProvider |
178
+ | `loom generate system-settings <type>` | 将系统页面接入 App.tsx(npm import 接线),type: `model`/`skill`/`user`/`login`/`process`/`notification`/`event`;`user` 同时接入 AuthProvider 路由守卫,`notification` 同时接入 NotificationCenterProvider |
177
179
  | `loom generate skill <name>` | 生成自定义 Skill 脚架 |
178
- | `loom eject system-settings <type>` | 将系统页面从 npm 组件切换为本地文件(可自由编辑),type: `model`/`skill`/`user`/`login`/`process`/`notification`。详见 `references/eject.md` |
180
+ | `loom eject system-settings <type>` | 将系统页面从 npm 组件切换为本地文件(可自由编辑),type: `model`/`skill`/`user`/`login`/`process`/`notification`/`event`。详见 `references/eject.md` |
179
181
  | `loom uneject system-settings <type>` | 删除本地文件,恢复为 npm 组件(修改过的需 `--force`,操作前自动备份)。详见 `references/eject.md` |
180
182
  | `loom data read <model>` | 查询数据(`--filter` 筛选、`--limit` 限制条数、`--sort` 排序) |
181
183
  | `loom data write <model> --data '<json>'` | 创建记录 |
@@ -266,11 +268,16 @@ export default defineConfig({
266
268
  },
267
269
  events: { // 可选:事件系统
268
270
  enabled: true, // 可选,是否启用(默认 true),设为 false 可禁用
269
- subscriptions: [ // 可选:声明式事件订阅
271
+ subscriptions: [ // 可选:声明式事件订阅(服务启动时自动注册,修改后需重启生效)
272
+ { pattern: 'data:create:modelName', handler: 'process', config: { process: 'my-process', debounceMs: 1000 } }, // 触发 Process
270
273
  { pattern: 'data:create:modelName', handler: 'log' }, // 记日志
271
274
  { pattern: 'data:update:modelName', handler: 'webhook', config: { url: 'https://...', method?: 'POST', headers?: {} } }, // 推送外部
272
275
  { pattern: 'data:create:modelName', handler: 'notify', config: { type: 'info', title: '标题' } }, // 创建站内通知
273
- ], // 注意:Process 的事件绑定走 `loom process add --on-event`,不需要在 subscriptions 中用 handler: 'process' 重复声明,否则会双重触发
276
+ ],
277
+ // 声明式(config)与命令式(CLI)两种方式均可绑定事件:
278
+ // - 声明式:写在 subscriptions 中,重启后自动注册,适合固定不变的订阅
279
+ // - 命令式:`loom process add --subscribe` 或 `loom event subscribe`,即时生效,适合运行时动态管理
280
+ // 避免对同一 pattern + process 同时使用两种方式,否则会双重触发
274
281
  },
275
282
  });
276
283
  ```
@@ -176,7 +176,7 @@ events: {
176
176
  }
177
177
  ```
178
178
 
179
- Note: Process event bindings use `loom process add --on-event`. Avoid duplicate `handler: 'process'` subscriptions to prevent double-triggers.
179
+ Note: 声明式配置在服务启动时自动注册,修改后需重启生效。运行时 CLI/API 管理见 App-Skill(`references/events.md`)。避免对同一 pattern + process 同时使用声明式和命令式绑定,否则会双重触发。
180
180
 
181
181
  ## ProcessesConfig
182
182
 
@@ -186,10 +186,26 @@ processes: {
186
186
  maxConcurrent: 5, // Optional: max concurrent executions, 1-50 (default: 5)
187
187
  defaultOwner: 'admin', // Required: default owner username
188
188
  executionTimeout: '30m', // Optional: execution timeout (default: '30m')
189
+ definitions: [ // Optional: declarative process definitions (auto-registered on start)
190
+ {
191
+ name: 'daily-report',
192
+ description: 'Daily summary report',
193
+ cron: '0 9 * * 1-5',
194
+ prompt: 'Summarize yesterday data and report',
195
+ owner: 'admin',
196
+ },
197
+ {
198
+ name: 'on-alert',
199
+ cron: '*/5 * * * *',
200
+ hasProcessFile: true, // expects .loom/processes/{name}/PROCESS.md
201
+ owner: 'admin',
202
+ model: 'claude-sonnet-4-6', // AI model for this process
203
+ },
204
+ ],
189
205
  }
190
206
  ```
191
207
 
192
- Note: `enabled`, `maxConcurrent`, and `executionTimeout` are populated by Zod defaults. Only `defaultOwner` is typically set manually.
208
+ Note: `enabled`, `maxConcurrent`, and `executionTimeout` are populated by Zod defaults. Only `defaultOwner` is typically set manually. Process definitions in `definitions[]` are auto-registered on server start. 运行时 CLI 管理(创建/运行/暂停/日志等)见 App-Skill(`references/process.md`)。
193
209
 
194
210
  ## LifecycleConfig
195
211
 
@@ -209,7 +225,7 @@ lifecycle: {
209
225
  }
210
226
  ```
211
227
 
212
- Note: The `onReady` array has been removed. Use `loom process add --source <command> --on-event <pattern>` to register Feeder scripts, which are automatically managed by LifecycleManager using these global parameters.
228
+ Note: The `onReady` array has been removed. Use `loom process add --source <command> --subscribe <pattern>` to register Feeder scripts, which are automatically managed by LifecycleManager using these global parameters. Feeder 脚本的事件绑定详情见 App-Skill(`references/events.md`)。
213
229
 
214
230
  ## RelationConfig
215
231
 
@@ -38,7 +38,7 @@ const EXEMPT_PATHS = [
38
38
  '/api/v1/auth/login',
39
39
  '/api/v1/auth/register',
40
40
  '/api/v1/auth/refresh',
41
- '/api/v1/events/notify',
41
+ '/api/v1/events/emit',
42
42
  ];
43
43
  /** Resolve effective permission for a model given user role and config */
44
44
  export function resolvePermission(model, roleName, config) {
@@ -1 +1 @@
1
- {"version":3,"file":"rbac.js","sourceRoot":"","sources":["../../../src/backend/auth/rbac.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,WAAW,EAAqB,MAAM,UAAU,CAAC;AAE1D,wDAAwD;AACxD,MAAM,eAAe,GAAwC;IAC3D,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;IACR,KAAK,EAAE,CAAC;CACT,CAAC;AAEF,0GAA0G;AAC1G,MAAM,iBAAiB,GAAwC;IAC7D,GAAG,EAAE,MAAM;IACX,IAAI,EAAE,OAAO;IACb,GAAG,EAAE,OAAO;IACZ,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,OAAO;CAChB,CAAC;AAEF,4FAA4F;AAC5F,MAAM,UAAU,gBAAgB,CAAC,MAAc,EAAE,MAAkB;IACjE,MAAM,IAAI,GAAG,iBAAiB,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC;IACjD,mGAAmG;IACnG,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,mBAAmB,KAAK,IAAI,EAAE,CAAC;QACpF,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,sCAAsC;AACtC,MAAM,YAAY,GAAG;IACnB,gBAAgB;IAChB,oBAAoB;IACpB,uBAAuB;IACvB,sBAAsB;IACtB,uBAAuB;CACxB,CAAC;AAEF,0EAA0E;AAC1E,MAAM,UAAU,iBAAiB,CAC/B,KAAa,EACb,QAAgB,EAChB,MAAkB;IAElB,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IACzD,IAAI,CAAC,IAAI;QAAE,OAAO,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC;IAEnD,kCAAkC;IAClC,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;IAChE,IAAI,SAAS;QAAE,OAAO,SAAS,CAAC,KAAK,CAAC;IAEtC,4BAA4B;IAC5B,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,GAAG,CAAC,CAAC;IACjE,IAAI,YAAY;QAAE,OAAO,YAAY,CAAC,KAAK,CAAC;IAE5C,wCAAwC;IACxC,OAAO,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC;AAC1C,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,aAAa,CAAC,SAA8B,EAAE,aAAkC;IAC9F,OAAO,eAAe,CAAC,SAAS,CAAC,IAAI,eAAe,CAAC,aAAa,CAAC,CAAC;AACtE,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,OAAO,CAAC,IAAY,EAAE,MAAkB;IACtD,OAAO,aAAa,CAAC,iBAAiB,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;AACtE,CAAC;AAmBD,MAAM,UAAU,oBAAoB,CAAC,OAA8B;IACjE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAE3B,OAAO,KAAK,EAAE,OAAuB,EAAE,KAAmB,EAAE,EAAE;QAC5D,mDAAmD;QACnD,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;YACxB,IAAI,OAAO,CAAC,GAAG,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAC;YACnC,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,GAAG,GAAG,CAAC;gBAAE,OAAO,IAAI,CAAC;YACpF,OAAO,KAAK,CAAC;QACf,CAAC,CAAC,EAAE,CAAC;YACH,OAAO;QACT,CAAC;QAED,2BAA2B;QAC3B,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC;QACjD,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACvC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC,CAAC;YAC3D,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAClC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC3C,4CAA4C;YAC5C,IAAK,OAA4C,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBACrE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,8CAA8C,EAAE,CAAC,CAAC;gBAChF,OAAO;YACT,CAAC;YACD,OAAO,CAAC,IAAI,GAAG;gBACb,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,KAAK;aACN,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,0BAA0B,EAAE,CAAC,CAAC;YAC5D,OAAO;QACT,CAAC;QAED,8DAA8D;QAC9D,MAAM,KAAK,GAAI,OAAO,CAAC,MAA6C,EAAE,KAAK,CAAC;QAC5E,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAC9B,MAAM,aAAa,GAAG,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAEvD,MAAM,SAAS,GAAG,iBAAiB,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAEtE,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,aAAa,CAAC,EAAE,CAAC;gBAC7C,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;oBACf,MAAM,EAAE,OAAO,CAAC,IAAI,EAAE,MAAM;oBAC5B,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI;oBACxB,KAAK;oBACL,MAAM,EAAE,OAAO,CAAC,MAAM;oBACtB,QAAQ,EAAE,aAAa;oBACvB,MAAM,EAAE,SAAS;iBAClB,EAAE,yBAAyB,CAAC,CAAC;gBAC9B,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBACnB,KAAK,EAAE,0BAA0B;oBACjC,QAAQ,EAAE,aAAa;oBACvB,MAAM,EAAE,SAAS;iBAClB,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;QACH,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"rbac.js","sourceRoot":"","sources":["../../../src/backend/auth/rbac.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * SubscriptionService — Business logic for event subscription CRUD.
3
+ *
4
+ * Centralises the read-modify-write config cycle + runtime registration/unregistration
5
+ * that was previously duplicated across event-routes.ts and process-routes.ts.
6
+ */
7
+ import type { EventBus } from './event-bus.js';
8
+ import type { ProcessEngine } from '../process/engine.js';
9
+ import type { LifecycleManager } from '../lifecycle/index.js';
10
+ import type { EventSubscription } from '../../types/event.js';
11
+ export interface SubscriptionServiceOptions {
12
+ processEngine?: ProcessEngine;
13
+ eventBus?: EventBus;
14
+ lifecycleManager?: LifecycleManager;
15
+ projectRoot?: string;
16
+ }
17
+ export declare class SubscriptionService {
18
+ private processEngine?;
19
+ private eventBus?;
20
+ private lifecycleManager?;
21
+ private projectRoot?;
22
+ constructor(options: SubscriptionServiceOptions);
23
+ /** Read all subscriptions from config, optionally enriched with active status. */
24
+ listSubscriptions(enrich?: boolean): Promise<EventSubscription[]>;
25
+ /** Get subscriptions for a specific process, enriched with active status. */
26
+ listSubscriptionsForProcess(processName: string): Promise<Array<EventSubscription & {
27
+ active?: boolean;
28
+ }>>;
29
+ /** Add a new subscription: persist to config + runtime registration. */
30
+ addSubscription(sub: {
31
+ pattern: string;
32
+ handler: string;
33
+ config: Record<string, unknown>;
34
+ }): Promise<EventSubscription>;
35
+ /** Update a subscription (partial update): persist + runtime re-registration. */
36
+ updateSubscription(id: string, updates: {
37
+ pattern?: string;
38
+ handler?: string;
39
+ config?: Record<string, unknown>;
40
+ }): Promise<EventSubscription>;
41
+ /** Remove a subscription by ID: persist + runtime cleanup. */
42
+ removeSubscription(id: string): Promise<EventSubscription>;
43
+ /** Remove all subscriptions for a process (used by process delete cascade). */
44
+ removeSubscriptionsForProcess(processName: string): Promise<string[]>;
45
+ }
46
+ //# sourceMappingURL=subscription-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription-service.d.ts","sourceRoot":"","sources":["../../../src/backend/events/subscription-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAI9D,MAAM,WAAW,0BAA0B;IACzC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAID,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,aAAa,CAAC,CAAgB;IACtC,OAAO,CAAC,QAAQ,CAAC,CAAW;IAC5B,OAAO,CAAC,gBAAgB,CAAC,CAAmB;IAC5C,OAAO,CAAC,WAAW,CAAC,CAAS;gBAEjB,OAAO,EAAE,0BAA0B;IAO/C,kFAAkF;IAC5E,iBAAiB,CAAC,MAAM,UAAQ,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAcrE,6EAA6E;IACvE,2BAA2B,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,iBAAiB,GAAG;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAWhH,wEAAwE;IAClE,eAAe,CAAC,GAAG,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAoD7H,iFAAiF;IAC3E,kBAAkB,CACtB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAChF,OAAO,CAAC,iBAAiB,CAAC;IA6E7B,8DAA8D;IACxD,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAiChE,+EAA+E;IACzE,6BAA6B,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;CAmB5E"}
@@ -0,0 +1,209 @@
1
+ /**
2
+ * SubscriptionService — Business logic for event subscription CRUD.
3
+ *
4
+ * Centralises the read-modify-write config cycle + runtime registration/unregistration
5
+ * that was previously duplicated across event-routes.ts and process-routes.ts.
6
+ */
7
+ import { generateId } from '../../utils/id.js';
8
+ import { readEventSubscriptions, writeEventSubscriptionsToConfig } from '../routes/config-writer.js';
9
+ const VALID_HANDLERS = ['process', 'webhook', 'log', 'notify'];
10
+ export class SubscriptionService {
11
+ processEngine;
12
+ eventBus;
13
+ lifecycleManager;
14
+ projectRoot;
15
+ constructor(options) {
16
+ this.processEngine = options.processEngine;
17
+ this.eventBus = options.eventBus;
18
+ this.lifecycleManager = options.lifecycleManager;
19
+ this.projectRoot = options.projectRoot;
20
+ }
21
+ /** Read all subscriptions from config, optionally enriched with active status. */
22
+ async listSubscriptions(enrich = false) {
23
+ if (!this.projectRoot)
24
+ return [];
25
+ const subscriptions = await readEventSubscriptions(this.projectRoot);
26
+ if (!enrich)
27
+ return subscriptions;
28
+ return subscriptions.map(sub => {
29
+ if (sub.handler === 'process' && this.processEngine) {
30
+ const procName = sub.config.process;
31
+ const isActive = this.processEngine.getEventSubscriptions(procName).length > 0;
32
+ return { ...sub, active: isActive };
33
+ }
34
+ return { ...sub, active: !!this.eventBus };
35
+ });
36
+ }
37
+ /** Get subscriptions for a specific process, enriched with active status. */
38
+ async listSubscriptionsForProcess(processName) {
39
+ if (!this.projectRoot)
40
+ return [];
41
+ const allSubs = await readEventSubscriptions(this.projectRoot);
42
+ if (!this.processEngine)
43
+ return allSubs.filter(s => s.handler === 'process' && s.config.process === processName);
44
+ const runtimeSubs = this.processEngine.getEventSubscriptions(processName);
45
+ const runtimePatterns = new Set(runtimeSubs.map(s => s.pattern));
46
+ return allSubs
47
+ .filter(s => s.handler === 'process' && s.config.process === processName)
48
+ .map(s => ({ ...s, active: runtimePatterns.has(s.pattern) }));
49
+ }
50
+ /** Add a new subscription: persist to config + runtime registration. */
51
+ async addSubscription(sub) {
52
+ if (!this.projectRoot)
53
+ throw new Error('Project root not configured');
54
+ const { pattern, handler, config } = sub;
55
+ if (!pattern || typeof pattern !== 'string')
56
+ throw new Error('pattern is required');
57
+ if (!handler || !VALID_HANDLERS.includes(handler)) {
58
+ throw new Error(`handler must be one of: ${VALID_HANDLERS.join(', ')}`);
59
+ }
60
+ if (!config || typeof config !== 'object')
61
+ throw new Error('config is required');
62
+ if (handler === 'process') {
63
+ const procCfg = config;
64
+ if (!procCfg.process || typeof procCfg.process !== 'string') {
65
+ throw new Error('process handler requires config.process (process name)');
66
+ }
67
+ if (this.processEngine) {
68
+ const exists = await this.processEngine.getProcess(procCfg.process);
69
+ if (!exists)
70
+ throw new Error(`Process "${procCfg.process}" not found`);
71
+ }
72
+ }
73
+ else if (handler === 'webhook') {
74
+ const webhookCfg = config;
75
+ if (!webhookCfg.url || typeof webhookCfg.url !== 'string') {
76
+ throw new Error('webhook handler requires config.url');
77
+ }
78
+ }
79
+ const subscriptions = await readEventSubscriptions(this.projectRoot);
80
+ const newSub = { id: generateId('sub'), pattern, handler, config };
81
+ subscriptions.push(newSub);
82
+ await writeEventSubscriptionsToConfig(this.projectRoot, subscriptions);
83
+ // Runtime registration for process handler
84
+ if (handler === 'process' && this.processEngine && this.eventBus) {
85
+ const procCfg = config;
86
+ const proc = await this.processEngine.getProcess(procCfg.process);
87
+ this.processEngine.registerEventSubscription(procCfg.process, this.eventBus, pattern, procCfg.filter, procCfg.debounceMs, !proc?.paused);
88
+ // Start feeder if process has source and is not paused
89
+ if (this.lifecycleManager && proc?.source && !proc.paused) {
90
+ const scriptName = `${procCfg.process}-feeder`;
91
+ this.lifecycleManager.addScript({ name: scriptName, command: proc.source.command, env: proc.source.env });
92
+ await this.lifecycleManager.start(scriptName);
93
+ }
94
+ }
95
+ return newSub;
96
+ }
97
+ /** Update a subscription (partial update): persist + runtime re-registration. */
98
+ async updateSubscription(id, updates) {
99
+ if (!this.projectRoot)
100
+ throw new Error('Project root not configured');
101
+ const subscriptions = await readEventSubscriptions(this.projectRoot);
102
+ const idx = subscriptions.findIndex(s => s.id === id);
103
+ if (idx === -1)
104
+ throw new Error(`Subscription ${id} not found`);
105
+ const oldSub = subscriptions[idx];
106
+ const newPattern = typeof updates.pattern === 'string' ? updates.pattern : oldSub.pattern;
107
+ const newHandler = typeof updates.handler === 'string' ? updates.handler : oldSub.handler;
108
+ const newConfig = (updates.config && typeof updates.config === 'object') ? updates.config : oldSub.config;
109
+ // Validate handler-specific config
110
+ if (newHandler === 'process') {
111
+ const procCfg = newConfig;
112
+ if (!procCfg.process || typeof procCfg.process !== 'string') {
113
+ throw new Error('process handler requires config.process (process name)');
114
+ }
115
+ if (this.processEngine) {
116
+ const exists = await this.processEngine.getProcess(procCfg.process);
117
+ if (!exists)
118
+ throw new Error(`Process "${procCfg.process}" not found`);
119
+ }
120
+ }
121
+ else if (newHandler === 'webhook') {
122
+ const webhookCfg = newConfig;
123
+ if (!webhookCfg.url || typeof webhookCfg.url !== 'string') {
124
+ throw new Error('webhook handler requires config.url');
125
+ }
126
+ }
127
+ const handlerChanged = oldSub.handler !== newHandler;
128
+ const patternChanged = oldSub.pattern !== newPattern;
129
+ // Unregister old runtime subscription if handler or pattern changed
130
+ if (oldSub.handler === 'process' && this.processEngine && (handlerChanged || patternChanged)) {
131
+ const oldCfg = oldSub.config;
132
+ this.processEngine.unregisterEventSubscription(oldCfg.process, oldSub.pattern);
133
+ }
134
+ const updatedSub = {
135
+ ...oldSub,
136
+ id: oldSub.id ?? generateId('sub'),
137
+ pattern: newPattern,
138
+ handler: newHandler,
139
+ config: newConfig,
140
+ };
141
+ subscriptions[idx] = updatedSub;
142
+ await writeEventSubscriptionsToConfig(this.projectRoot, subscriptions);
143
+ // Register new runtime subscription if process handler and something changed
144
+ if (updatedSub.handler === 'process' && this.processEngine && this.eventBus && (handlerChanged || patternChanged)) {
145
+ const procCfg = updatedSub.config;
146
+ const proc = await this.processEngine.getProcess(procCfg.process);
147
+ this.processEngine.registerEventSubscription(procCfg.process, this.eventBus, updatedSub.pattern, procCfg.filter, procCfg.debounceMs, !proc?.paused);
148
+ }
149
+ // If process handler config changed (but handler+pattern same), re-register
150
+ if (updatedSub.handler === 'process' && this.processEngine && this.eventBus && !handlerChanged && !patternChanged) {
151
+ const oldProcCfg = oldSub.config;
152
+ const newProcCfg = updatedSub.config;
153
+ if (JSON.stringify(oldProcCfg) !== JSON.stringify(newProcCfg)) {
154
+ this.processEngine.unregisterEventSubscription(oldProcCfg.process, oldSub.pattern);
155
+ const proc = await this.processEngine.getProcess(newProcCfg.process);
156
+ this.processEngine.registerEventSubscription(newProcCfg.process, this.eventBus, updatedSub.pattern, newProcCfg.filter, newProcCfg.debounceMs, !proc?.paused);
157
+ }
158
+ }
159
+ return updatedSub;
160
+ }
161
+ /** Remove a subscription by ID: persist + runtime cleanup. */
162
+ async removeSubscription(id) {
163
+ if (!this.projectRoot)
164
+ throw new Error('Project root not configured');
165
+ const subscriptions = await readEventSubscriptions(this.projectRoot);
166
+ const idx = subscriptions.findIndex(s => s.id === id);
167
+ if (idx === -1)
168
+ throw new Error(`Subscription ${id} not found`);
169
+ const removed = subscriptions.splice(idx, 1)[0];
170
+ await writeEventSubscriptionsToConfig(this.projectRoot, subscriptions);
171
+ // Runtime cleanup for process handler
172
+ if (removed.handler === 'process' && this.processEngine) {
173
+ const procCfg = removed.config;
174
+ this.processEngine.unregisterEventSubscription(procCfg.process, removed.pattern);
175
+ // Stop feeder if this was the last subscription for the process with source
176
+ if (this.lifecycleManager) {
177
+ const remainingSubsForProcess = subscriptions.filter(s => s.handler === 'process' && s.config.process === procCfg.process);
178
+ if (remainingSubsForProcess.length === 0) {
179
+ const proc = await this.processEngine.getProcess(procCfg.process);
180
+ if (proc?.source) {
181
+ const scriptName = `${procCfg.process}-feeder`;
182
+ try {
183
+ await this.lifecycleManager.removeScript(scriptName);
184
+ }
185
+ catch { /* may not exist */ }
186
+ }
187
+ }
188
+ }
189
+ }
190
+ return removed;
191
+ }
192
+ /** Remove all subscriptions for a process (used by process delete cascade). */
193
+ async removeSubscriptionsForProcess(processName) {
194
+ if (!this.projectRoot)
195
+ return [];
196
+ const subscriptions = await readEventSubscriptions(this.projectRoot);
197
+ const removedPatterns = subscriptions
198
+ .filter(s => s.handler === 'process' && s.config.process === processName)
199
+ .map(s => s.pattern);
200
+ const remainingSubs = subscriptions.filter(s => !(s.handler === 'process' && s.config.process === processName));
201
+ await writeEventSubscriptionsToConfig(this.projectRoot, remainingSubs);
202
+ // Runtime cleanup
203
+ if (this.processEngine) {
204
+ this.processEngine.unregisterEventSubscription(processName);
205
+ }
206
+ return removedPatterns;
207
+ }
208
+ }
209
+ //# sourceMappingURL=subscription-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription-service.js","sourceRoot":"","sources":["../../../src/backend/events/subscription-service.ts"],"names":[],"mappings":"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"}
@@ -44,6 +44,7 @@ export declare class LoomServer {
44
44
  private processEngine?;
45
45
  private lifecycleManager?;
46
46
  private notificationStorage?;
47
+ private subscriptionService?;
47
48
  private projectRoot;
48
49
  private options;
49
50
  constructor(options: LoomServerOptions);
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/backend/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,OAAO,MAAM,SAAS,CAAC;AAM9B,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAUvD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAK9E,MAAM,WAAW,iBAAiB;IAChC,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,YAAY,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACrC,kEAAkE;IAClE,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,qEAAqE;IACrE,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,mBAAmB;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,iBAAiB,CAAuB;IAChD,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,SAAS,CAAC,CAAY;IAC9B,OAAO,CAAC,UAAU,CAAC,CAAa;IAChC,OAAO,CAAC,QAAQ,CAAC,CAAW;IAC5B,OAAO,CAAC,aAAa,CAAC,CAAgB;IACtC,OAAO,CAAC,aAAa,CAAC,CAAgB;IACtC,OAAO,CAAC,gBAAgB,CAAC,CAAmB;IAC5C,OAAO,CAAC,mBAAmB,CAAC,CAAsB;IAClD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,OAAO,CAAoB;gBAEvB,OAAO,EAAE,iBAAiB;IAKtC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA2UjC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAa5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAe3B,0CAA0C;IAC1C,UAAU,IAAI,UAAU,CAAC,OAAO,OAAO,CAAC;IAIxC,gCAAgC;IAChC,SAAS,IAAI,UAAU;IAIvB,iCAAiC;IACjC,UAAU,IAAI,WAAW;IAIzB,oCAAoC;IACpC,YAAY,IAAI,SAAS,GAAG,SAAS;IAIrC,qCAAqC;IACrC,aAAa,IAAI,UAAU,GAAG,SAAS;IAIvC,mCAAmC;IACnC,WAAW,IAAI,QAAQ,GAAG,SAAS;IAInC,wCAAwC;IACxC,gBAAgB,IAAI,aAAa,GAAG,SAAS;IAI7C,wCAAwC;IACxC,gBAAgB,IAAI,aAAa,GAAG,SAAS;IAI7C,2CAA2C;IAC3C,mBAAmB,IAAI,gBAAgB,GAAG,SAAS;IAInD,8CAA8C;IAC9C,sBAAsB,IAAI,mBAAmB,GAAG,SAAS;IAIzD;;;OAGG;YACW,WAAW;CAqB1B;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAK1E"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/backend/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,OAAO,MAAM,SAAS,CAAC;AAM9B,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAUvD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAK9E,MAAM,WAAW,iBAAiB;IAChC,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,YAAY,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACrC,kEAAkE;IAClE,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,qEAAqE;IACrE,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,mBAAmB;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,iBAAiB,CAAuB;IAChD,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,SAAS,CAAC,CAAY;IAC9B,OAAO,CAAC,UAAU,CAAC,CAAa;IAChC,OAAO,CAAC,QAAQ,CAAC,CAAW;IAC5B,OAAO,CAAC,aAAa,CAAC,CAAgB;IACtC,OAAO,CAAC,aAAa,CAAC,CAAgB;IACtC,OAAO,CAAC,gBAAgB,CAAC,CAAmB;IAC5C,OAAO,CAAC,mBAAmB,CAAC,CAAsB;IAClD,OAAO,CAAC,mBAAmB,CAAC,CAAsB;IAClD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,OAAO,CAAoB;gBAEvB,OAAO,EAAE,iBAAiB;IAKtC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA0VjC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAa5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAe3B,0CAA0C;IAC1C,UAAU,IAAI,UAAU,CAAC,OAAO,OAAO,CAAC;IAIxC,gCAAgC;IAChC,SAAS,IAAI,UAAU;IAIvB,iCAAiC;IACjC,UAAU,IAAI,WAAW;IAIzB,oCAAoC;IACpC,YAAY,IAAI,SAAS,GAAG,SAAS;IAIrC,qCAAqC;IACrC,aAAa,IAAI,UAAU,GAAG,SAAS;IAIvC,mCAAmC;IACnC,WAAW,IAAI,QAAQ,GAAG,SAAS;IAInC,wCAAwC;IACxC,gBAAgB,IAAI,aAAa,GAAG,SAAS;IAI7C,wCAAwC;IACxC,gBAAgB,IAAI,aAAa,GAAG,SAAS;IAI7C,2CAA2C;IAC3C,mBAAmB,IAAI,gBAAgB,GAAG,SAAS;IAInD,8CAA8C;IAC9C,sBAAsB,IAAI,mBAAmB,GAAG,SAAS;IAIzD;;;OAGG;YACW,WAAW;CAqB1B;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAK1E"}
@@ -25,6 +25,7 @@ import { getRequestContext, setRequestContext } from './auth/request-context.js'
25
25
  import { EventBus } from './events/event-bus.js';
26
26
  import { EventEmittingAdapter } from './events/event-emitting-adapter.js';
27
27
  import { EventRegistry } from './events/event-registry.js';
28
+ import { SubscriptionService } from './events/subscription-service.js';
28
29
  import { ProcessEngine } from './process/engine.js';
29
30
  import { LifecycleManager } from './lifecycle/index.js';
30
31
  import { NotificationStorage } from './notifications/notification-storage.js';
@@ -44,6 +45,7 @@ export class LoomServer {
44
45
  processEngine;
45
46
  lifecycleManager;
46
47
  notificationStorage;
48
+ subscriptionService;
47
49
  projectRoot;
48
50
  options;
49
51
  constructor(options) {
@@ -213,10 +215,6 @@ export class LoomServer {
213
215
  projectRoot: this.projectRoot,
214
216
  eventBus: this.eventBus,
215
217
  });
216
- // Register event routes (only when EventBus is active)
217
- if (this.eventBus) {
218
- registerEventRoutes(this.fastify, { eventBus: this.eventBus, eventRegistry: this.eventRegistry });
219
- }
220
218
  // Initialize LifecycleManager when lifecycle config exists or processes are enabled
221
219
  // (--source dynamically adds scripts, so LifecycleManager must exist even with empty config)
222
220
  const lifecycleEnabled = !this.config.lifecycle || this.config.lifecycle.enabled !== false;
@@ -240,16 +238,38 @@ export class LoomServer {
240
238
  serverUrl: `http://localhost:${this.config.server?.backendPort || 3000}`,
241
239
  });
242
240
  await this.processEngine.initialize();
241
+ // Create SubscriptionService (shared by event and process routes)
242
+ this.subscriptionService = new SubscriptionService({
243
+ processEngine: this.processEngine,
244
+ eventBus: this.eventBus,
245
+ lifecycleManager: this.lifecycleManager,
246
+ projectRoot: this.projectRoot,
247
+ });
243
248
  registerProcessRoutes(this.fastify, {
244
249
  engine: this.processEngine,
245
250
  paths,
246
251
  eventBus: this.eventBus,
247
252
  lifecycleManager: this.lifecycleManager,
253
+ projectRoot: this.projectRoot,
254
+ subscriptionService: this.subscriptionService,
248
255
  });
249
256
  // Auto-register feeder scripts from ProcessRegistry into LifecycleManager
250
257
  if (this.lifecycleManager) {
251
258
  const allProcesses = await this.processEngine.listProcesses();
252
- this.lifecycleManager.syncFromProcessRegistry(allProcesses);
259
+ this.lifecycleManager.syncFromProcessRegistry(allProcesses, this.config.events?.subscriptions ?? []);
260
+ }
261
+ }
262
+ // Register event routes (must be after ProcessEngine and LifecycleManager init)
263
+ if (this.eventBus) {
264
+ registerEventRoutes(this.fastify, {
265
+ eventBus: this.eventBus,
266
+ eventRegistry: this.eventRegistry,
267
+ subscriptionService: this.subscriptionService,
268
+ });
269
+ // Assign stable IDs to any subscriptions that lack them (one-time migration on startup)
270
+ if (this.projectRoot) {
271
+ const { ensureSubscriptionIds } = await import('./routes/config-writer.js');
272
+ await ensureSubscriptionIds(this.projectRoot);
253
273
  }
254
274
  }
255
275
  // Register declarative subscriptions from events config
@@ -260,14 +280,8 @@ export class LoomServer {
260
280
  if (this.processEngine) {
261
281
  const proc = await this.processEngine.getProcess(procCfg.process);
262
282
  if (proc) {
263
- if (proc.onEvent && proc.onEvent === sub.pattern) {
264
- // onEvent already handles this pattern skip subscription to avoid duplicate triggers
265
- this.fastify.log.info(`Process "${procCfg.process}" already binds onEvent for "${sub.pattern}" — skipping config subscription`);
266
- continue;
267
- }
268
- this.eventBus.on(sub.pattern, (event) => {
269
- void this.processEngine.runProcess(procCfg.process, 'event', event.payload);
270
- });
283
+ // Paused processes: populate eventSubscriptionMap but don't start trigger (resumeProcess can reactivate)
284
+ this.processEngine.registerEventSubscription(procCfg.process, this.eventBus, sub.pattern, procCfg.filter, procCfg.debounceMs, !proc.paused);
271
285
  }
272
286
  }
273
287
  }