@jingyi0605/codingns 0.1.4 → 0.1.5

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 (209) hide show
  1. package/dist/public/assets/{TerminalPage-4ulgBhv9.js → TerminalPage-4p6EBqrR.js} +1 -1
  2. package/dist/public/assets/gemini-D4G1NbrE.png +0 -0
  3. package/dist/public/assets/index-CxeghocY.css +1 -0
  4. package/dist/public/assets/index-DXusStl0.js +108 -0
  5. package/dist/public/assets/kimi-BWNNSh7e.png +0 -0
  6. package/dist/public/index.html +2 -2
  7. package/dist/server/config/env.d.ts +6 -0
  8. package/dist/server/config/env.js +145 -0
  9. package/dist/server/config/env.js.map +1 -1
  10. package/dist/server/config/opencode-system-probe-helper-process.d.ts +24 -0
  11. package/dist/server/config/opencode-system-probe-helper-process.js +70 -5
  12. package/dist/server/config/opencode-system-probe-helper-process.js.map +1 -1
  13. package/dist/server/modules/butler/butler-action-context-service.d.ts +30 -0
  14. package/dist/server/modules/butler/butler-action-context-service.js +108 -0
  15. package/dist/server/modules/butler/butler-action-context-service.js.map +1 -0
  16. package/dist/server/modules/butler/butler-auth-service.d.ts +17 -0
  17. package/dist/server/modules/butler/butler-auth-service.js +91 -0
  18. package/dist/server/modules/butler/butler-auth-service.js.map +1 -0
  19. package/dist/server/modules/butler/butler-control-action-service.d.ts +65 -0
  20. package/dist/server/modules/butler/butler-control-action-service.js +296 -0
  21. package/dist/server/modules/butler/butler-control-action-service.js.map +1 -0
  22. package/dist/server/modules/butler/butler-control-session-service.d.ts +55 -0
  23. package/dist/server/modules/butler/butler-control-session-service.js +367 -0
  24. package/dist/server/modules/butler/butler-control-session-service.js.map +1 -0
  25. package/dist/server/modules/butler/butler-controller.d.ts +367 -0
  26. package/dist/server/modules/butler/butler-controller.js +475 -0
  27. package/dist/server/modules/butler/butler-controller.js.map +1 -0
  28. package/dist/server/modules/butler/butler-follow-up-evaluation-instruction-adapter.d.ts +34 -0
  29. package/dist/server/modules/butler/butler-follow-up-evaluation-instruction-adapter.js +77 -0
  30. package/dist/server/modules/butler/butler-follow-up-evaluation-instruction-adapter.js.map +1 -0
  31. package/dist/server/modules/butler/butler-follow-up-scheduler.d.ts +23 -0
  32. package/dist/server/modules/butler/butler-follow-up-scheduler.js +57 -0
  33. package/dist/server/modules/butler/butler-follow-up-scheduler.js.map +1 -0
  34. package/dist/server/modules/butler/butler-follow-up-service.d.ts +86 -0
  35. package/dist/server/modules/butler/butler-follow-up-service.js +948 -0
  36. package/dist/server/modules/butler/butler-follow-up-service.js.map +1 -0
  37. package/dist/server/modules/butler/butler-inbox-service.d.ts +35 -0
  38. package/dist/server/modules/butler/butler-inbox-service.js +136 -0
  39. package/dist/server/modules/butler/butler-inbox-service.js.map +1 -0
  40. package/dist/server/modules/butler/butler-notification-service.d.ts +12 -0
  41. package/dist/server/modules/butler/butler-notification-service.js +45 -0
  42. package/dist/server/modules/butler/butler-notification-service.js.map +1 -0
  43. package/dist/server/modules/butler/butler-profile-service.d.ts +26 -0
  44. package/dist/server/modules/butler/butler-profile-service.js +529 -0
  45. package/dist/server/modules/butler/butler-profile-service.js.map +1 -0
  46. package/dist/server/modules/butler/butler-project-service.d.ts +48 -0
  47. package/dist/server/modules/butler/butler-project-service.js +253 -0
  48. package/dist/server/modules/butler/butler-project-service.js.map +1 -0
  49. package/dist/server/modules/butler/butler-session-service.d.ts +79 -0
  50. package/dist/server/modules/butler/butler-session-service.js +503 -0
  51. package/dist/server/modules/butler/butler-session-service.js.map +1 -0
  52. package/dist/server/modules/butler/butler-session-summary-service.d.ts +55 -0
  53. package/dist/server/modules/butler/butler-session-summary-service.js +382 -0
  54. package/dist/server/modules/butler/butler-session-summary-service.js.map +1 -0
  55. package/dist/server/modules/butler/context-aggregator.d.ts +187 -0
  56. package/dist/server/modules/butler/context-aggregator.js +807 -0
  57. package/dist/server/modules/butler/context-aggregator.js.map +1 -0
  58. package/dist/server/modules/butler/instruction-adapter.d.ts +28 -0
  59. package/dist/server/modules/butler/instruction-adapter.js +101 -0
  60. package/dist/server/modules/butler/instruction-adapter.js.map +1 -0
  61. package/dist/server/modules/butler/patrol-execution-service.d.ts +47 -0
  62. package/dist/server/modules/butler/patrol-execution-service.js +347 -0
  63. package/dist/server/modules/butler/patrol-execution-service.js.map +1 -0
  64. package/dist/server/modules/butler/patrol-plan-service.d.ts +54 -0
  65. package/dist/server/modules/butler/patrol-plan-service.js +272 -0
  66. package/dist/server/modules/butler/patrol-plan-service.js.map +1 -0
  67. package/dist/server/modules/butler/patrol-run-service.d.ts +60 -0
  68. package/dist/server/modules/butler/patrol-run-service.js +185 -0
  69. package/dist/server/modules/butler/patrol-run-service.js.map +1 -0
  70. package/dist/server/modules/butler/patrol-scheduler.d.ts +36 -0
  71. package/dist/server/modules/butler/patrol-scheduler.js +99 -0
  72. package/dist/server/modules/butler/patrol-scheduler.js.map +1 -0
  73. package/dist/server/modules/butler/project-memory-service.d.ts +30 -0
  74. package/dist/server/modules/butler/project-memory-service.js +103 -0
  75. package/dist/server/modules/butler/project-memory-service.js.map +1 -0
  76. package/dist/server/modules/butler/provider-adapter-registry.d.ts +61 -0
  77. package/dist/server/modules/butler/provider-adapter-registry.js +430 -0
  78. package/dist/server/modules/butler/provider-adapter-registry.js.map +1 -0
  79. package/dist/server/modules/butler/session-summary-instruction-adapter.d.ts +28 -0
  80. package/dist/server/modules/butler/session-summary-instruction-adapter.js +79 -0
  81. package/dist/server/modules/butler/session-summary-instruction-adapter.js.map +1 -0
  82. package/dist/server/modules/butler/session-summary-scheduler.d.ts +23 -0
  83. package/dist/server/modules/butler/session-summary-scheduler.js +57 -0
  84. package/dist/server/modules/butler/session-summary-scheduler.js.map +1 -0
  85. package/dist/server/modules/butler/verification-run-service.d.ts +73 -0
  86. package/dist/server/modules/butler/verification-run-service.js +633 -0
  87. package/dist/server/modules/butler/verification-run-service.js.map +1 -0
  88. package/dist/server/modules/preferences/profile-service.js +8 -2
  89. package/dist/server/modules/preferences/profile-service.js.map +1 -1
  90. package/dist/server/modules/sessions/claude-runtime-helper-process.js +1 -1
  91. package/dist/server/modules/sessions/claude-runtime-helper-process.js.map +1 -1
  92. package/dist/server/modules/sessions/codex-app-server-helper-client.d.ts +5 -1
  93. package/dist/server/modules/sessions/codex-app-server-helper-client.js +10 -2
  94. package/dist/server/modules/sessions/codex-app-server-helper-client.js.map +1 -1
  95. package/dist/server/modules/sessions/session-controller.d.ts +3 -1
  96. package/dist/server/modules/sessions/session-controller.js +11 -2
  97. package/dist/server/modules/sessions/session-controller.js.map +1 -1
  98. package/dist/server/modules/sessions/session-history-service.d.ts +14 -1
  99. package/dist/server/modules/sessions/session-history-service.js +291 -30
  100. package/dist/server/modules/sessions/session-history-service.js.map +1 -1
  101. package/dist/server/modules/sessions/session-live-runtime-service.d.ts +25 -2
  102. package/dist/server/modules/sessions/session-live-runtime-service.js +526 -158
  103. package/dist/server/modules/sessions/session-live-runtime-service.js.map +1 -1
  104. package/dist/server/modules/sessions/session-provider-error-mapper.js +28 -0
  105. package/dist/server/modules/sessions/session-provider-error-mapper.js.map +1 -1
  106. package/dist/server/modules/workbench/workbench-service.d.ts +7 -1
  107. package/dist/server/modules/workbench/workbench-service.js +31 -7
  108. package/dist/server/modules/workbench/workbench-service.js.map +1 -1
  109. package/dist/server/routes/butler.d.ts +3 -0
  110. package/dist/server/routes/butler.js +54 -0
  111. package/dist/server/routes/butler.js.map +1 -0
  112. package/dist/server/server/create-server.d.ts +61 -0
  113. package/dist/server/server/create-server.js +148 -4
  114. package/dist/server/server/create-server.js.map +1 -1
  115. package/dist/server/storage/repositories/butler-control-event-repository.d.ts +8 -0
  116. package/dist/server/storage/repositories/butler-control-event-repository.js +78 -0
  117. package/dist/server/storage/repositories/butler-control-event-repository.js.map +1 -0
  118. package/dist/server/storage/repositories/butler-control-session-repository.d.ts +11 -0
  119. package/dist/server/storage/repositories/butler-control-session-repository.js +86 -0
  120. package/dist/server/storage/repositories/butler-control-session-repository.js.map +1 -0
  121. package/dist/server/storage/repositories/butler-follow-up-task-repository.d.ts +16 -0
  122. package/dist/server/storage/repositories/butler-follow-up-task-repository.js +252 -0
  123. package/dist/server/storage/repositories/butler-follow-up-task-repository.js.map +1 -0
  124. package/dist/server/storage/repositories/butler-inbox-item-repository.d.ts +15 -0
  125. package/dist/server/storage/repositories/butler-inbox-item-repository.js +111 -0
  126. package/dist/server/storage/repositories/butler-inbox-item-repository.js.map +1 -0
  127. package/dist/server/storage/repositories/butler-notification-archive-repository.d.ts +9 -0
  128. package/dist/server/storage/repositories/butler-notification-archive-repository.js +48 -0
  129. package/dist/server/storage/repositories/butler-notification-archive-repository.js.map +1 -0
  130. package/dist/server/storage/repositories/butler-profile-repository.d.ts +9 -0
  131. package/dist/server/storage/repositories/butler-profile-repository.js +86 -0
  132. package/dist/server/storage/repositories/butler-profile-repository.js.map +1 -0
  133. package/dist/server/storage/repositories/butler-project-repository.d.ts +14 -0
  134. package/dist/server/storage/repositories/butler-project-repository.js +140 -0
  135. package/dist/server/storage/repositories/butler-project-repository.js.map +1 -0
  136. package/dist/server/storage/repositories/butler-session-repository.d.ts +11 -0
  137. package/dist/server/storage/repositories/butler-session-repository.js +106 -0
  138. package/dist/server/storage/repositories/butler-session-repository.js.map +1 -0
  139. package/dist/server/storage/repositories/butler-session-summary-state-repository.d.ts +8 -0
  140. package/dist/server/storage/repositories/butler-session-summary-state-repository.js +62 -0
  141. package/dist/server/storage/repositories/butler-session-summary-state-repository.js.map +1 -0
  142. package/dist/server/storage/repositories/patrol-plan-repository.d.ts +27 -0
  143. package/dist/server/storage/repositories/patrol-plan-repository.js +119 -0
  144. package/dist/server/storage/repositories/patrol-plan-repository.js.map +1 -0
  145. package/dist/server/storage/repositories/patrol-run-repository.d.ts +28 -0
  146. package/dist/server/storage/repositories/patrol-run-repository.js +121 -0
  147. package/dist/server/storage/repositories/patrol-run-repository.js.map +1 -0
  148. package/dist/server/storage/repositories/project-memory-repository.d.ts +15 -0
  149. package/dist/server/storage/repositories/project-memory-repository.js +150 -0
  150. package/dist/server/storage/repositories/project-memory-repository.js.map +1 -0
  151. package/dist/server/storage/repositories/session-checkpoint-repository.d.ts +9 -0
  152. package/dist/server/storage/repositories/session-checkpoint-repository.js +72 -0
  153. package/dist/server/storage/repositories/session-checkpoint-repository.js.map +1 -0
  154. package/dist/server/storage/repositories/session-message-origin-repository.d.ts +10 -0
  155. package/dist/server/storage/repositories/session-message-origin-repository.js +93 -0
  156. package/dist/server/storage/repositories/session-message-origin-repository.js.map +1 -0
  157. package/dist/server/storage/repositories/verification-run-repository.d.ts +29 -0
  158. package/dist/server/storage/repositories/verification-run-repository.js +125 -0
  159. package/dist/server/storage/repositories/verification-run-repository.js.map +1 -0
  160. package/dist/server/storage/sqlite/client.js +39 -0
  161. package/dist/server/storage/sqlite/client.js.map +1 -1
  162. package/dist/server/storage/sqlite/schema.sql +324 -0
  163. package/dist/server/types/domain.d.ts +261 -1
  164. package/dist/server/ws/ws-server.d.ts +2 -1
  165. package/dist/server/ws/ws-server.js +2 -1
  166. package/dist/server/ws/ws-server.js.map +1 -1
  167. package/node_modules/@codingns/session-sync-core/dist/index.d.ts +4 -0
  168. package/node_modules/@codingns/session-sync-core/dist/index.js +4 -0
  169. package/node_modules/@codingns/session-sync-core/dist/index.js.map +1 -1
  170. package/node_modules/@codingns/session-sync-core/dist/kimi-message-normalizer.d.ts +18 -0
  171. package/node_modules/@codingns/session-sync-core/dist/kimi-message-normalizer.js +659 -0
  172. package/node_modules/@codingns/session-sync-core/dist/kimi-message-normalizer.js.map +1 -0
  173. package/node_modules/@codingns/session-sync-core/dist/kimi-shared.d.ts +11 -0
  174. package/node_modules/@codingns/session-sync-core/dist/kimi-shared.js +72 -0
  175. package/node_modules/@codingns/session-sync-core/dist/kimi-shared.js.map +1 -0
  176. package/node_modules/@codingns/session-sync-core/dist/patch-builder.d.ts +8 -0
  177. package/node_modules/@codingns/session-sync-core/dist/patch-builder.js +89 -0
  178. package/node_modules/@codingns/session-sync-core/dist/patch-builder.js.map +1 -1
  179. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js +4 -1
  180. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js.map +1 -1
  181. package/node_modules/@codingns/session-sync-core/dist/providers/gemini.d.ts +41 -0
  182. package/node_modules/@codingns/session-sync-core/dist/providers/gemini.js +1086 -0
  183. package/node_modules/@codingns/session-sync-core/dist/providers/gemini.js.map +1 -0
  184. package/node_modules/@codingns/session-sync-core/dist/providers/kimi.d.ts +29 -0
  185. package/node_modules/@codingns/session-sync-core/dist/providers/kimi.js +578 -0
  186. package/node_modules/@codingns/session-sync-core/dist/providers/kimi.js.map +1 -0
  187. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js +2 -1
  188. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js.map +1 -1
  189. package/node_modules/@codingns/session-sync-core/dist/providers/utils.js +30 -2
  190. package/node_modules/@codingns/session-sync-core/dist/providers/utils.js.map +1 -1
  191. package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.d.ts +2 -0
  192. package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.js +43 -5
  193. package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.js.map +1 -1
  194. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.d.ts +2 -0
  195. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js +320 -69
  196. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js.map +1 -1
  197. package/node_modules/@codingns/session-sync-core/dist/runtime/gemini-runtime.d.ts +21 -0
  198. package/node_modules/@codingns/session-sync-core/dist/runtime/gemini-runtime.js +537 -0
  199. package/node_modules/@codingns/session-sync-core/dist/runtime/gemini-runtime.js.map +1 -0
  200. package/node_modules/@codingns/session-sync-core/dist/runtime/kimi-runtime.d.ts +38 -0
  201. package/node_modules/@codingns/session-sync-core/dist/runtime/kimi-runtime.js +911 -0
  202. package/node_modules/@codingns/session-sync-core/dist/runtime/kimi-runtime.js.map +1 -0
  203. package/node_modules/@codingns/session-sync-core/dist/sqlite/node-sqlite.d.ts +6 -0
  204. package/node_modules/@codingns/session-sync-core/dist/sqlite/node-sqlite.js +9 -0
  205. package/node_modules/@codingns/session-sync-core/dist/sqlite/node-sqlite.js.map +1 -0
  206. package/node_modules/@codingns/session-sync-core/package.json +8 -0
  207. package/package.json +1 -1
  208. package/dist/public/assets/index-C5lu52cQ.css +0 -1
  209. package/dist/public/assets/index-WpdUo_Vs.js +0 -108
@@ -163,6 +163,24 @@ CREATE INDEX IF NOT EXISTS idx_session_message_attachments_message
163
163
  CREATE INDEX IF NOT EXISTS idx_session_message_attachments_client_request
164
164
  ON session_message_attachments(session_id, client_request_id);
165
165
 
166
+ CREATE TABLE IF NOT EXISTS session_message_origins (
167
+ session_id TEXT NOT NULL,
168
+ client_request_id TEXT NOT NULL,
169
+ message_id TEXT,
170
+ origin TEXT NOT NULL CHECK (origin IN ('butler_proxy', 'system')),
171
+ origin_ref TEXT,
172
+ content TEXT NOT NULL,
173
+ created_at TEXT NOT NULL,
174
+ updated_at TEXT NOT NULL,
175
+ PRIMARY KEY (session_id, client_request_id),
176
+ FOREIGN KEY (session_id) REFERENCES session_bindings(session_id)
177
+ );
178
+
179
+ CREATE INDEX IF NOT EXISTS idx_session_message_origins_message
180
+ ON session_message_origins(session_id, message_id);
181
+ CREATE INDEX IF NOT EXISTS idx_session_message_origins_origin
182
+ ON session_message_origins(session_id, origin, updated_at DESC);
183
+
166
184
  CREATE TABLE IF NOT EXISTS session_send_queue (
167
185
  id TEXT PRIMARY KEY,
168
186
  session_id TEXT NOT NULL,
@@ -367,6 +385,312 @@ CREATE TABLE IF NOT EXISTS terminal_command_templates (
367
385
  CREATE INDEX IF NOT EXISTS idx_terminal_templates_workspace_id
368
386
  ON terminal_command_templates(workspace_id);
369
387
 
388
+ CREATE TABLE IF NOT EXISTS butler_profiles (
389
+ id TEXT PRIMARY KEY CHECK (id = 'default'),
390
+ display_name TEXT NOT NULL,
391
+ provider_id TEXT NOT NULL CHECK (provider_id IN ('codex', 'claude-code')),
392
+ workspace_path TEXT NOT NULL,
393
+ agents_mode TEXT NOT NULL CHECK (agents_mode IN ('inline', 'file')),
394
+ agents_file_path TEXT,
395
+ agents_content TEXT NOT NULL,
396
+ persona_json TEXT NOT NULL,
397
+ focus_json TEXT NOT NULL,
398
+ initialized_at TEXT NOT NULL,
399
+ updated_at TEXT NOT NULL
400
+ );
401
+
402
+ CREATE TABLE IF NOT EXISTS butler_control_sessions (
403
+ id TEXT PRIMARY KEY,
404
+ provider_id TEXT NOT NULL CHECK (provider_id IN ('codex', 'claude-code')),
405
+ session_id TEXT NOT NULL UNIQUE,
406
+ status TEXT NOT NULL CHECK (status IN ('idle', 'running', 'failed', 'closed')),
407
+ last_context_version TEXT,
408
+ last_summary TEXT,
409
+ created_at TEXT NOT NULL,
410
+ updated_at TEXT NOT NULL,
411
+ FOREIGN KEY (session_id) REFERENCES session_bindings(session_id)
412
+ );
413
+
414
+ CREATE INDEX IF NOT EXISTS idx_butler_control_sessions_provider
415
+ ON butler_control_sessions(provider_id, updated_at DESC, created_at DESC);
416
+
417
+ CREATE TABLE IF NOT EXISTS butler_control_events (
418
+ id TEXT PRIMARY KEY,
419
+ control_session_id TEXT NOT NULL,
420
+ kind TEXT NOT NULL CHECK (kind IN ('action')),
421
+ action_type TEXT NOT NULL CHECK (
422
+ action_type IN ('open-project', 'resume-session', 'start-patrol', 'start-verification')
423
+ ),
424
+ status TEXT NOT NULL CHECK (status IN ('succeeded', 'failed')),
425
+ title TEXT NOT NULL,
426
+ content TEXT NOT NULL,
427
+ related_refs_json TEXT NOT NULL,
428
+ created_at TEXT NOT NULL,
429
+ FOREIGN KEY (control_session_id) REFERENCES butler_control_sessions(id) ON DELETE CASCADE
430
+ );
431
+
432
+ CREATE INDEX IF NOT EXISTS idx_butler_control_events_session_created_at
433
+ ON butler_control_events(control_session_id, created_at ASC);
434
+
435
+ CREATE TABLE IF NOT EXISTS butler_inbox_items (
436
+ id TEXT PRIMARY KEY,
437
+ project_id TEXT NOT NULL,
438
+ item_type TEXT NOT NULL CHECK (item_type IN ('bug', 'feature', 'change', 'task')),
439
+ title TEXT NOT NULL,
440
+ content TEXT NOT NULL,
441
+ priority TEXT NOT NULL CHECK (priority IN ('low', 'medium', 'high')),
442
+ status TEXT NOT NULL CHECK (status IN ('pending', 'in_progress', 'closed')),
443
+ created_at TEXT NOT NULL,
444
+ updated_at TEXT NOT NULL,
445
+ closed_at TEXT,
446
+ FOREIGN KEY (project_id) REFERENCES butler_projects(id) ON DELETE CASCADE
447
+ );
448
+
449
+ CREATE INDEX IF NOT EXISTS idx_butler_inbox_items_project_updated_at
450
+ ON butler_inbox_items(project_id, updated_at DESC, created_at DESC);
451
+ CREATE INDEX IF NOT EXISTS idx_butler_inbox_items_status_updated_at
452
+ ON butler_inbox_items(status, updated_at DESC, created_at DESC);
453
+
454
+ CREATE TABLE IF NOT EXISTS butler_notification_archives (
455
+ user_id TEXT NOT NULL,
456
+ notification_id TEXT NOT NULL,
457
+ archived_at TEXT NOT NULL,
458
+ updated_at TEXT NOT NULL,
459
+ PRIMARY KEY (user_id, notification_id),
460
+ FOREIGN KEY (user_id) REFERENCES auth_users(id) ON DELETE CASCADE
461
+ );
462
+
463
+ CREATE INDEX IF NOT EXISTS idx_butler_notification_archives_user_updated_at
464
+ ON butler_notification_archives(user_id, updated_at DESC);
465
+
466
+ CREATE TABLE IF NOT EXISTS butler_projects (
467
+ id TEXT PRIMARY KEY,
468
+ workspace_id TEXT NOT NULL,
469
+ name TEXT NOT NULL,
470
+ repo_root TEXT NOT NULL,
471
+ default_provider TEXT,
472
+ instruction_profile_id TEXT,
473
+ approval_mode TEXT NOT NULL CHECK (approval_mode IN ('readonly', 'controlled', 'auto')),
474
+ lifecycle_status TEXT NOT NULL CHECK (lifecycle_status IN ('active', 'paused', 'archived')),
475
+ risk_level TEXT NOT NULL CHECK (risk_level IN ('low', 'medium', 'high')),
476
+ config_json TEXT NOT NULL,
477
+ last_patrol_at TEXT,
478
+ last_verification_at TEXT,
479
+ created_at TEXT NOT NULL,
480
+ updated_at TEXT NOT NULL,
481
+ archived_at TEXT,
482
+ FOREIGN KEY (workspace_id) REFERENCES workspaces(id),
483
+ UNIQUE (workspace_id, repo_root)
484
+ );
485
+
486
+ CREATE INDEX IF NOT EXISTS idx_butler_projects_workspace_id
487
+ ON butler_projects(workspace_id);
488
+ CREATE INDEX IF NOT EXISTS idx_butler_projects_status
489
+ ON butler_projects(lifecycle_status, updated_at DESC);
490
+
491
+ CREATE TABLE IF NOT EXISTS butler_sessions (
492
+ id TEXT PRIMARY KEY,
493
+ project_id TEXT NOT NULL,
494
+ session_id TEXT NOT NULL UNIQUE,
495
+ role TEXT NOT NULL CHECK (role IN ('patrol', 'execution', 'verification', 'adhoc')),
496
+ ownership_mode TEXT NOT NULL CHECK (ownership_mode IN ('managed', 'observed')),
497
+ status TEXT NOT NULL CHECK (status IN ('idle', 'running', 'blocked', 'failed', 'closed')),
498
+ last_summary TEXT,
499
+ last_checkpoint_at TEXT,
500
+ created_at TEXT NOT NULL,
501
+ updated_at TEXT NOT NULL,
502
+ FOREIGN KEY (project_id) REFERENCES butler_projects(id) ON DELETE CASCADE,
503
+ FOREIGN KEY (session_id) REFERENCES session_bindings(session_id)
504
+ );
505
+
506
+ CREATE INDEX IF NOT EXISTS idx_butler_sessions_project_id
507
+ ON butler_sessions(project_id, updated_at DESC);
508
+ CREATE INDEX IF NOT EXISTS idx_butler_sessions_status
509
+ ON butler_sessions(status, updated_at DESC);
510
+
511
+ CREATE TABLE IF NOT EXISTS butler_follow_up_tasks (
512
+ id TEXT PRIMARY KEY,
513
+ project_id TEXT NOT NULL,
514
+ butler_session_id TEXT NOT NULL,
515
+ session_id TEXT NOT NULL,
516
+ created_by_user_id TEXT NOT NULL,
517
+ objective TEXT NOT NULL,
518
+ completion_criteria TEXT NOT NULL DEFAULT '',
519
+ max_auto_continue_count INTEGER NOT NULL DEFAULT 5,
520
+ status TEXT NOT NULL CHECK (
521
+ status IN ('active', 'waiting_user', 'completed', 'failed', 'cancelled')
522
+ ),
523
+ check_interval_seconds INTEGER NOT NULL,
524
+ last_checked_at TEXT,
525
+ next_check_at TEXT,
526
+ last_observed_running_state TEXT,
527
+ last_observed_message_at TEXT,
528
+ last_observed_message_count INTEGER NOT NULL DEFAULT 0,
529
+ last_automation_summary TEXT,
530
+ last_automation_at TEXT,
531
+ auto_continue_count INTEGER NOT NULL DEFAULT 0,
532
+ waiting_reason TEXT,
533
+ rounds_json TEXT NOT NULL DEFAULT '[]',
534
+ created_at TEXT NOT NULL,
535
+ updated_at TEXT NOT NULL,
536
+ completed_at TEXT,
537
+ FOREIGN KEY (project_id) REFERENCES butler_projects(id) ON DELETE CASCADE,
538
+ FOREIGN KEY (butler_session_id) REFERENCES butler_sessions(id) ON DELETE CASCADE,
539
+ FOREIGN KEY (session_id) REFERENCES session_bindings(session_id) ON DELETE CASCADE,
540
+ FOREIGN KEY (created_by_user_id) REFERENCES auth_users(id)
541
+ );
542
+
543
+ CREATE INDEX IF NOT EXISTS idx_butler_follow_up_tasks_status
544
+ ON butler_follow_up_tasks(status, next_check_at ASC, updated_at DESC);
545
+ CREATE INDEX IF NOT EXISTS idx_butler_follow_up_tasks_session
546
+ ON butler_follow_up_tasks(butler_session_id, status, updated_at DESC);
547
+
548
+ CREATE TABLE IF NOT EXISTS butler_session_summary_states (
549
+ butler_session_id TEXT PRIMARY KEY,
550
+ source_message_count INTEGER NOT NULL DEFAULT 0,
551
+ source_last_message_at TEXT,
552
+ last_summarized_at TEXT,
553
+ last_summarized_sequence INTEGER,
554
+ debounce_until TEXT,
555
+ status TEXT NOT NULL CHECK (status IN ('idle', 'scheduled', 'running', 'failed')),
556
+ error_detail TEXT,
557
+ updated_at TEXT NOT NULL,
558
+ FOREIGN KEY (butler_session_id) REFERENCES butler_sessions(id) ON DELETE CASCADE
559
+ );
560
+
561
+ CREATE INDEX IF NOT EXISTS idx_butler_session_summary_states_status
562
+ ON butler_session_summary_states(status, debounce_until ASC, updated_at ASC);
563
+
564
+ CREATE TABLE IF NOT EXISTS session_checkpoints (
565
+ id TEXT PRIMARY KEY,
566
+ butler_session_id TEXT NOT NULL,
567
+ checkpoint_seq INTEGER NOT NULL,
568
+ source_kind TEXT NOT NULL CHECK (
569
+ source_kind IN ('snapshot', 'summary', 'verification', 'manual')
570
+ ),
571
+ progress_state TEXT NOT NULL CHECK (
572
+ progress_state IN ('unknown', 'working', 'blocked', 'done')
573
+ ),
574
+ summary TEXT NOT NULL,
575
+ risk_flags_json TEXT NOT NULL,
576
+ next_action_json TEXT NOT NULL,
577
+ captured_at TEXT NOT NULL,
578
+ FOREIGN KEY (butler_session_id) REFERENCES butler_sessions(id) ON DELETE CASCADE,
579
+ UNIQUE (butler_session_id, checkpoint_seq)
580
+ );
581
+
582
+ CREATE INDEX IF NOT EXISTS idx_session_checkpoints_session_id
583
+ ON session_checkpoints(butler_session_id, checkpoint_seq DESC);
584
+ CREATE INDEX IF NOT EXISTS idx_session_checkpoints_captured_at
585
+ ON session_checkpoints(captured_at DESC);
586
+
587
+ CREATE TABLE IF NOT EXISTS project_memories (
588
+ id TEXT PRIMARY KEY,
589
+ project_id TEXT NOT NULL,
590
+ source_butler_session_id TEXT,
591
+ source_checkpoint_id TEXT,
592
+ memory_type TEXT NOT NULL CHECK (
593
+ memory_type IN ('arch', 'rule', 'decision', 'incident', 'verify', 'note')
594
+ ),
595
+ title TEXT NOT NULL,
596
+ scope_path TEXT,
597
+ content TEXT NOT NULL,
598
+ tags_json TEXT NOT NULL,
599
+ confidence REAL NOT NULL CHECK (confidence >= 0 AND confidence <= 1),
600
+ status TEXT NOT NULL CHECK (
601
+ status IN ('candidate', 'active', 'superseded', 'archived')
602
+ ),
603
+ evidence_json TEXT NOT NULL,
604
+ superseded_by TEXT,
605
+ created_at TEXT NOT NULL,
606
+ updated_at TEXT NOT NULL,
607
+ FOREIGN KEY (project_id) REFERENCES butler_projects(id) ON DELETE CASCADE,
608
+ FOREIGN KEY (source_butler_session_id) REFERENCES butler_sessions(id),
609
+ FOREIGN KEY (source_checkpoint_id) REFERENCES session_checkpoints(id)
610
+ );
611
+
612
+ CREATE INDEX IF NOT EXISTS idx_project_memories_project_id
613
+ ON project_memories(project_id, updated_at DESC);
614
+ CREATE INDEX IF NOT EXISTS idx_project_memories_project_status
615
+ ON project_memories(project_id, status, updated_at DESC);
616
+ CREATE INDEX IF NOT EXISTS idx_project_memories_project_scope
617
+ ON project_memories(project_id, scope_path, updated_at DESC);
618
+
619
+ CREATE TABLE IF NOT EXISTS patrol_plans (
620
+ id TEXT PRIMARY KEY,
621
+ project_id TEXT NOT NULL,
622
+ name TEXT NOT NULL,
623
+ trigger_type TEXT NOT NULL CHECK (trigger_type IN ('manual', 'interval', 'cron')),
624
+ trigger_config_json TEXT NOT NULL,
625
+ execution_mode TEXT NOT NULL CHECK (execution_mode IN ('readonly', 'controlled')),
626
+ patrol_scope_json TEXT NOT NULL,
627
+ enabled INTEGER NOT NULL CHECK (enabled IN (0, 1)),
628
+ last_scheduled_at TEXT,
629
+ next_run_at TEXT,
630
+ created_at TEXT NOT NULL,
631
+ updated_at TEXT NOT NULL,
632
+ FOREIGN KEY (project_id) REFERENCES butler_projects(id) ON DELETE CASCADE
633
+ );
634
+
635
+ CREATE INDEX IF NOT EXISTS idx_patrol_plans_project_id
636
+ ON patrol_plans(project_id, updated_at DESC);
637
+ CREATE INDEX IF NOT EXISTS idx_patrol_plans_enabled_next_run_at
638
+ ON patrol_plans(enabled, next_run_at);
639
+
640
+ CREATE TABLE IF NOT EXISTS patrol_runs (
641
+ id TEXT PRIMARY KEY,
642
+ project_id TEXT NOT NULL,
643
+ plan_id TEXT,
644
+ triggered_by TEXT NOT NULL CHECK (triggered_by IN ('scheduler', 'user', 'system')),
645
+ trigger_ref TEXT,
646
+ butler_session_id TEXT,
647
+ status TEXT NOT NULL CHECK (
648
+ status IN ('queued', 'running', 'succeeded', 'failed', 'cancelled')
649
+ ),
650
+ summary TEXT,
651
+ risk_level TEXT CHECK (risk_level IS NULL OR risk_level IN ('low', 'medium', 'high')),
652
+ suggestions_json TEXT NOT NULL,
653
+ started_at TEXT,
654
+ finished_at TEXT,
655
+ created_at TEXT NOT NULL,
656
+ FOREIGN KEY (project_id) REFERENCES butler_projects(id) ON DELETE CASCADE,
657
+ FOREIGN KEY (plan_id) REFERENCES patrol_plans(id),
658
+ FOREIGN KEY (butler_session_id) REFERENCES butler_sessions(id)
659
+ );
660
+
661
+ CREATE INDEX IF NOT EXISTS idx_patrol_runs_project_started_at
662
+ ON patrol_runs(project_id, created_at DESC);
663
+ CREATE INDEX IF NOT EXISTS idx_patrol_runs_project_status
664
+ ON patrol_runs(project_id, status, created_at DESC);
665
+
666
+ CREATE TABLE IF NOT EXISTS verification_runs (
667
+ id TEXT PRIMARY KEY,
668
+ project_id TEXT NOT NULL,
669
+ butler_session_id TEXT,
670
+ source_patrol_run_id TEXT,
671
+ verification_type TEXT NOT NULL CHECK (
672
+ verification_type IN ('test', 'health', 'browser', 'visual', 'metric')
673
+ ),
674
+ status TEXT NOT NULL CHECK (
675
+ status IN ('queued', 'running', 'passed', 'failed', 'skipped')
676
+ ),
677
+ target_ref TEXT,
678
+ spec_json TEXT NOT NULL,
679
+ artifact_refs_json TEXT NOT NULL,
680
+ result_json TEXT NOT NULL,
681
+ summary TEXT,
682
+ started_at TEXT,
683
+ finished_at TEXT,
684
+ created_at TEXT NOT NULL,
685
+ FOREIGN KEY (project_id) REFERENCES butler_projects(id) ON DELETE CASCADE,
686
+ FOREIGN KEY (butler_session_id) REFERENCES butler_sessions(id)
687
+ );
688
+
689
+ CREATE INDEX IF NOT EXISTS idx_verification_runs_project_created_at
690
+ ON verification_runs(project_id, created_at DESC);
691
+ CREATE INDEX IF NOT EXISTS idx_verification_runs_project_status
692
+ ON verification_runs(project_id, status, created_at DESC);
693
+
370
694
  INSERT INTO bootstrap_state (id, initialized)
371
695
  VALUES ('default', 0)
372
696
  ON CONFLICT(id) DO NOTHING;
@@ -107,6 +107,17 @@ export interface SessionMessageAttachmentRecord {
107
107
  storagePath: string;
108
108
  createdAt: string;
109
109
  }
110
+ export type SessionMessageOrigin = "butler_proxy" | "system";
111
+ export interface SessionMessageOriginRecord {
112
+ sessionId: string;
113
+ clientRequestId: string;
114
+ messageId: string | null;
115
+ origin: SessionMessageOrigin;
116
+ originRef: string | null;
117
+ content: string;
118
+ createdAt: string;
119
+ updatedAt: string;
120
+ }
110
121
  export type SessionSendQueueStatus = "queued" | "dispatching" | "failed";
111
122
  export interface SessionSendQueueItemRecord {
112
123
  id: string;
@@ -198,7 +209,7 @@ export interface UserQuickPhrasePreferenceRecord {
198
209
  createdAt: string;
199
210
  updatedAt: string;
200
211
  }
201
- export type PreferenceProviderId = "claude-code" | "codex" | "opencode";
212
+ export type PreferenceProviderId = "claude-code" | "codex" | "opencode" | "gemini" | "kimi";
202
213
  export type UserPreferenceLanguage = "zh-CN" | "en-US";
203
214
  export type UserPreferenceTheme = "light" | "dark" | "sky-blue" | "eye-green";
204
215
  export type UserPreferencePermissionMode = "default" | "acceptEdits" | "bypassPermissions";
@@ -218,6 +229,255 @@ export interface UserPreferenceProfileRecord extends UserPreferenceProfile {
218
229
  createdAt: string;
219
230
  updatedAt: string;
220
231
  }
232
+ export type ButlerProfileProviderId = "codex" | "claude-code";
233
+ export type ButlerAgentsMode = "inline" | "file";
234
+ export type ButlerControlSessionStatus = "idle" | "running" | "failed" | "closed";
235
+ export type ButlerControlEventKind = "action";
236
+ export type ButlerControlActionType = "open-project" | "resume-session" | "start-patrol" | "start-verification";
237
+ export type ButlerControlEventStatus = "succeeded" | "failed";
238
+ export interface ButlerPersonaProfile {
239
+ tone: string;
240
+ language: string;
241
+ summaryStyle: string;
242
+ [key: string]: unknown;
243
+ }
244
+ export interface ButlerFocusProfile {
245
+ projectIds: string[];
246
+ riskPreference: string;
247
+ reportPriority: string[];
248
+ summaryDebounceSeconds: number;
249
+ [key: string]: unknown;
250
+ }
251
+ export type ButlerApprovalMode = "readonly" | "controlled" | "auto";
252
+ export type ButlerLifecycleStatus = "active" | "paused" | "archived";
253
+ export type ButlerRiskLevel = "low" | "medium" | "high";
254
+ export type ButlerSessionRole = "patrol" | "execution" | "verification" | "adhoc";
255
+ export type ButlerSessionOwnershipMode = "managed" | "observed";
256
+ export type ButlerSessionStatus = "idle" | "running" | "blocked" | "failed" | "closed";
257
+ export type ButlerSessionSummaryStatus = "idle" | "scheduled" | "running" | "failed";
258
+ export type ButlerCheckpointSourceKind = "snapshot" | "summary" | "verification" | "manual";
259
+ export type ButlerCheckpointProgressState = "unknown" | "working" | "blocked" | "done";
260
+ export type ButlerInboxItemType = "bug" | "feature" | "change" | "task";
261
+ export type ButlerInboxItemStatus = "pending" | "in_progress" | "closed";
262
+ export type ButlerInboxItemPriority = "low" | "medium" | "high";
263
+ export type ButlerFollowUpTaskStatus = "active" | "waiting_user" | "completed" | "failed" | "cancelled";
264
+ export type ProjectMemoryType = "arch" | "rule" | "decision" | "incident" | "verify" | "note";
265
+ export type ProjectMemoryStatus = "candidate" | "active" | "superseded" | "archived";
266
+ export type PatrolTriggerType = "manual" | "interval" | "cron";
267
+ export type PatrolExecutionMode = "readonly" | "controlled";
268
+ export type PatrolRunTriggeredBy = "scheduler" | "user" | "system";
269
+ export type PatrolRunStatus = "queued" | "running" | "succeeded" | "failed" | "cancelled";
270
+ export type VerificationType = "test" | "health" | "browser" | "visual" | "metric";
271
+ export type VerificationRunStatus = "queued" | "running" | "passed" | "failed" | "skipped";
272
+ export interface ButlerProfile {
273
+ id: "default";
274
+ displayName: string;
275
+ providerId: ButlerProfileProviderId;
276
+ workspacePath: string;
277
+ agentsMode: ButlerAgentsMode;
278
+ agentsFilePath: string | null;
279
+ agentsContent: string;
280
+ persona: ButlerPersonaProfile;
281
+ focus: ButlerFocusProfile;
282
+ initializedAt: string;
283
+ updatedAt: string;
284
+ }
285
+ export interface ButlerControlSession {
286
+ id: string;
287
+ providerId: ButlerProfileProviderId;
288
+ sessionId: string;
289
+ status: ButlerControlSessionStatus;
290
+ lastContextVersion: string | null;
291
+ lastSummary: string | null;
292
+ createdAt: string;
293
+ updatedAt: string;
294
+ }
295
+ export interface ButlerControlRelatedRef {
296
+ kind: "project" | "butler-session" | "session" | "patrol-run" | "verification-run" | "workspace";
297
+ id: string;
298
+ label: string;
299
+ routePath: string | null;
300
+ workspaceId: string | null;
301
+ projectId: string | null;
302
+ }
303
+ export interface ButlerControlEvent {
304
+ id: string;
305
+ controlSessionId: string;
306
+ kind: ButlerControlEventKind;
307
+ actionType: ButlerControlActionType;
308
+ status: ButlerControlEventStatus;
309
+ title: string;
310
+ content: string;
311
+ relatedRefs: ButlerControlRelatedRef[];
312
+ createdAt: string;
313
+ }
314
+ export interface ButlerProject {
315
+ id: string;
316
+ workspaceId: string;
317
+ name: string;
318
+ repoRoot: string;
319
+ defaultProvider: ProviderId | null;
320
+ instructionProfileId: string | null;
321
+ approvalMode: ButlerApprovalMode;
322
+ lifecycleStatus: ButlerLifecycleStatus;
323
+ riskLevel: ButlerRiskLevel;
324
+ config: Record<string, unknown>;
325
+ lastPatrolAt: string | null;
326
+ lastVerificationAt: string | null;
327
+ createdAt: string;
328
+ updatedAt: string;
329
+ archivedAt: string | null;
330
+ }
331
+ export interface ButlerSession {
332
+ id: string;
333
+ projectId: string;
334
+ sessionId: string;
335
+ role: ButlerSessionRole;
336
+ ownershipMode: ButlerSessionOwnershipMode;
337
+ status: ButlerSessionStatus;
338
+ lastSummary: string | null;
339
+ lastCheckpointAt: string | null;
340
+ createdAt: string;
341
+ updatedAt: string;
342
+ }
343
+ export interface ButlerInboxItem {
344
+ id: string;
345
+ projectId: string;
346
+ itemType: ButlerInboxItemType;
347
+ title: string;
348
+ content: string;
349
+ priority: ButlerInboxItemPriority;
350
+ status: ButlerInboxItemStatus;
351
+ createdAt: string;
352
+ updatedAt: string;
353
+ closedAt: string | null;
354
+ }
355
+ export interface ButlerNotificationArchiveRecord {
356
+ userId: string;
357
+ notificationId: string;
358
+ archivedAt: string;
359
+ updatedAt: string;
360
+ }
361
+ export interface ButlerFollowUpTask {
362
+ id: string;
363
+ projectId: string;
364
+ butlerSessionId: string;
365
+ sessionId: string;
366
+ createdByUserId: string;
367
+ objective: string;
368
+ completionCriteria: string;
369
+ maxAutoContinueCount: number;
370
+ status: ButlerFollowUpTaskStatus;
371
+ checkIntervalSeconds: number;
372
+ lastCheckedAt: string | null;
373
+ nextCheckAt: string | null;
374
+ lastObservedRunningState: SessionRunningState | null;
375
+ lastObservedMessageAt: string | null;
376
+ lastObservedMessageCount: number;
377
+ lastAutomationSummary: string | null;
378
+ lastAutomationAt: string | null;
379
+ autoContinueCount: number;
380
+ waitingReason: string | null;
381
+ rounds: ButlerFollowUpRound[];
382
+ createdAt: string;
383
+ updatedAt: string;
384
+ completedAt: string | null;
385
+ }
386
+ export type ButlerFollowUpRoundKind = "started" | "continue" | "queued" | "waiting_user" | "completed" | "failed" | "cancelled" | "limit_reached";
387
+ export interface ButlerFollowUpRound {
388
+ roundNumber: number;
389
+ kind: ButlerFollowUpRoundKind;
390
+ status: ButlerFollowUpTaskStatus;
391
+ summary: string;
392
+ waitingReason: string | null;
393
+ continuePrompt: string | null;
394
+ observedRunningState: SessionRunningState | null;
395
+ autoContinueCount: number;
396
+ createdAt: string;
397
+ }
398
+ export interface ButlerSessionSummaryState {
399
+ butlerSessionId: string;
400
+ sourceMessageCount: number;
401
+ sourceLastMessageAt: string | null;
402
+ lastSummarizedAt: string | null;
403
+ lastSummarizedSequence: number | null;
404
+ debounceUntil: string | null;
405
+ status: ButlerSessionSummaryStatus;
406
+ errorDetail: string | null;
407
+ updatedAt: string;
408
+ }
409
+ export interface SessionCheckpoint {
410
+ id: string;
411
+ butlerSessionId: string;
412
+ checkpointSeq: number;
413
+ sourceKind: ButlerCheckpointSourceKind;
414
+ progressState: ButlerCheckpointProgressState;
415
+ summary: string;
416
+ riskFlags: string[];
417
+ nextActions: string[];
418
+ capturedAt: string;
419
+ }
420
+ export interface ProjectMemory {
421
+ id: string;
422
+ projectId: string;
423
+ sourceButlerSessionId: string | null;
424
+ sourceCheckpointId: string | null;
425
+ memoryType: ProjectMemoryType;
426
+ title: string;
427
+ scopePath: string | null;
428
+ content: string;
429
+ tags: string[];
430
+ confidence: number;
431
+ status: ProjectMemoryStatus;
432
+ evidence: Record<string, unknown>;
433
+ supersededBy: string | null;
434
+ createdAt: string;
435
+ updatedAt: string;
436
+ }
437
+ export interface PatrolPlan {
438
+ id: string;
439
+ projectId: string;
440
+ name: string;
441
+ triggerType: PatrolTriggerType;
442
+ triggerConfig: Record<string, unknown>;
443
+ executionMode: PatrolExecutionMode;
444
+ patrolScope: Record<string, unknown>;
445
+ enabled: boolean;
446
+ lastScheduledAt: string | null;
447
+ nextRunAt: string | null;
448
+ createdAt: string;
449
+ updatedAt: string;
450
+ }
451
+ export interface PatrolRun {
452
+ id: string;
453
+ projectId: string;
454
+ planId: string | null;
455
+ triggeredBy: PatrolRunTriggeredBy;
456
+ triggerRef: string | null;
457
+ butlerSessionId: string | null;
458
+ status: PatrolRunStatus;
459
+ summary: string | null;
460
+ riskLevel: ButlerRiskLevel | null;
461
+ suggestions: string[];
462
+ startedAt: string | null;
463
+ finishedAt: string | null;
464
+ createdAt: string;
465
+ }
466
+ export interface VerificationRun {
467
+ id: string;
468
+ projectId: string;
469
+ butlerSessionId: string | null;
470
+ sourcePatrolRunId: string | null;
471
+ verificationType: VerificationType;
472
+ status: VerificationRunStatus;
473
+ targetRef: string | null;
474
+ summary: string | null;
475
+ artifactRefs: Array<Record<string, unknown>>;
476
+ result: Record<string, unknown>;
477
+ startedAt: string | null;
478
+ finishedAt: string | null;
479
+ createdAt: string;
480
+ }
221
481
  export interface FileContextBinding {
222
482
  id: string;
223
483
  sessionId: string;
@@ -2,6 +2,7 @@ import type { IncomingMessage, Server } from "node:http";
2
2
  import { type WebSocket } from "ws";
3
3
  import type { SessionHistoryEnvelope, SessionHistoryService } from "../modules/sessions/session-history-service.js";
4
4
  import type { SessionLiveRuntimeService } from "../modules/sessions/session-live-runtime-service.js";
5
+ import type { ButlerActionContextService } from "../modules/butler/butler-action-context-service.js";
5
6
  import type { TerminalWsHub } from "./terminal-ws-hub.js";
6
7
  import type { WorkbenchWsHub } from "./workbench-ws-hub.js";
7
8
  import type { WsAuthGuard } from "./ws-auth-guard.js";
@@ -13,7 +14,7 @@ interface SeenMessageEntry {
13
14
  contentPreview: string;
14
15
  toolCallStatus: "running" | "completed" | "failed" | null;
15
16
  }
16
- export declare function createWsServer(server: Server, wsAuthGuard: WsAuthGuard, sessionHistoryService: SessionHistoryService, sessionLiveRuntimeService: SessionLiveRuntimeService, terminalWsHub: TerminalWsHub, workbenchWsHub: WorkbenchWsHub): {
17
+ export declare function createWsServer(server: Server, wsAuthGuard: WsAuthGuard, sessionHistoryService: SessionHistoryService, sessionLiveRuntimeService: SessionLiveRuntimeService, terminalWsHub: TerminalWsHub, workbenchWsHub: WorkbenchWsHub, butlerActionContextService?: Pick<ButlerActionContextService, "preloadSessionActionContext">): {
17
18
  wss: import("ws").Server<typeof WebSocket, typeof IncomingMessage>;
18
19
  close: () => Promise<void>;
19
20
  };
@@ -3,7 +3,7 @@ import { AppError } from "../shared/errors/app-error.js";
3
3
  import { hashContent } from "../shared/utils/hash.js";
4
4
  const MAX_TRACKED_MESSAGES_PER_SUBSCRIPTION = 2_048;
5
5
  const MAX_STORED_MESSAGE_PREVIEW_CHARS = 2_048;
6
- export function createWsServer(server, wsAuthGuard, sessionHistoryService, sessionLiveRuntimeService, terminalWsHub, workbenchWsHub) {
6
+ export function createWsServer(server, wsAuthGuard, sessionHistoryService, sessionLiveRuntimeService, terminalWsHub, workbenchWsHub, butlerActionContextService) {
7
7
  const wss = new WebSocketServer({
8
8
  noServer: true
9
9
  });
@@ -95,6 +95,7 @@ export function createWsServer(server, wsAuthGuard, sessionHistoryService, sessi
95
95
  type: "session.subscribed",
96
96
  sessionId: payload.sessionId
97
97
  }));
98
+ butlerActionContextService?.preloadSessionActionContext(payload.sessionId, authContext.user.userId);
98
99
  const seenMessages = new Map();
99
100
  const forwardEnvelope = async (envelope) => {
100
101
  const deduped = dedupeEnvelopeMessages(envelope, seenMessages);