@jingyi0605/codingns 0.3.6 → 0.4.0

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 (185) hide show
  1. package/README.md +3 -0
  2. package/bin/codingns.mjs +489 -1
  3. package/dist/public/assets/{TerminalPage-D00S4KM6.js → TerminalPage-6jHZV9Mh.js} +17 -17
  4. package/dist/public/assets/index-CSVhg7I8.js +123 -0
  5. package/dist/public/assets/index-Ce1VX19m.css +1 -0
  6. package/dist/public/index.html +2 -2
  7. package/dist/server/modules/assistant-capability/assistant-capability-controller.d.ts +173 -0
  8. package/dist/server/modules/assistant-capability/assistant-capability-controller.js +307 -0
  9. package/dist/server/modules/assistant-capability/assistant-capability-controller.js.map +1 -1
  10. package/dist/server/modules/assistant-capability/assistant-capability-service.d.ts +199 -2
  11. package/dist/server/modules/assistant-capability/assistant-capability-service.js +565 -3
  12. package/dist/server/modules/assistant-capability/assistant-capability-service.js.map +1 -1
  13. package/dist/server/modules/butler/assistant-automation-service.d.ts +110 -0
  14. package/dist/server/modules/butler/assistant-automation-service.js +786 -0
  15. package/dist/server/modules/butler/assistant-automation-service.js.map +1 -0
  16. package/dist/server/modules/butler/assistant-automation-trigger.d.ts +94 -0
  17. package/dist/server/modules/butler/assistant-automation-trigger.js +400 -0
  18. package/dist/server/modules/butler/assistant-automation-trigger.js.map +1 -0
  19. package/dist/server/modules/butler/assistant-sandbox-service.d.ts +55 -0
  20. package/dist/server/modules/butler/assistant-sandbox-service.js +266 -0
  21. package/dist/server/modules/butler/assistant-sandbox-service.js.map +1 -0
  22. package/dist/server/modules/butler/butler-action-context-service.d.ts +4 -1
  23. package/dist/server/modules/butler/butler-action-context-service.js +8 -2
  24. package/dist/server/modules/butler/butler-action-context-service.js.map +1 -1
  25. package/dist/server/modules/butler/butler-control-session-service.d.ts +8 -1
  26. package/dist/server/modules/butler/butler-control-session-service.js +154 -40
  27. package/dist/server/modules/butler/butler-control-session-service.js.map +1 -1
  28. package/dist/server/modules/butler/butler-control-timer-scheduler.d.ts +32 -0
  29. package/dist/server/modules/butler/butler-control-timer-scheduler.js +93 -0
  30. package/dist/server/modules/butler/butler-control-timer-scheduler.js.map +1 -0
  31. package/dist/server/modules/butler/butler-control-timer-service.d.ts +42 -0
  32. package/dist/server/modules/butler/butler-control-timer-service.js +132 -0
  33. package/dist/server/modules/butler/butler-control-timer-service.js.map +1 -0
  34. package/dist/server/modules/butler/butler-controller.d.ts +42 -2
  35. package/dist/server/modules/butler/butler-controller.js +79 -12
  36. package/dist/server/modules/butler/butler-controller.js.map +1 -1
  37. package/dist/server/modules/butler/butler-follow-up-service.d.ts +9 -1
  38. package/dist/server/modules/butler/butler-follow-up-service.js +273 -181
  39. package/dist/server/modules/butler/butler-follow-up-service.js.map +1 -1
  40. package/dist/server/modules/butler/butler-inbox-analysis-service.d.ts +4 -1
  41. package/dist/server/modules/butler/butler-inbox-analysis-service.js +18 -4
  42. package/dist/server/modules/butler/butler-inbox-analysis-service.js.map +1 -1
  43. package/dist/server/modules/butler/butler-profile-service.js +2 -5
  44. package/dist/server/modules/butler/butler-profile-service.js.map +1 -1
  45. package/dist/server/modules/butler/butler-project-service.d.ts +3 -1
  46. package/dist/server/modules/butler/butler-project-service.js +7 -1
  47. package/dist/server/modules/butler/butler-project-service.js.map +1 -1
  48. package/dist/server/modules/butler/butler-session-service.d.ts +3 -1
  49. package/dist/server/modules/butler/butler-session-service.js +12 -1
  50. package/dist/server/modules/butler/butler-session-service.js.map +1 -1
  51. package/dist/server/modules/butler/butler-session-summary-service.js +2 -1
  52. package/dist/server/modules/butler/butler-session-summary-service.js.map +1 -1
  53. package/dist/server/modules/butler/butler-workspace-context.d.ts +3 -0
  54. package/dist/server/modules/butler/butler-workspace-context.js +164 -44
  55. package/dist/server/modules/butler/butler-workspace-context.js.map +1 -1
  56. package/dist/server/modules/butler/patrol-execution-service.js +2 -1
  57. package/dist/server/modules/butler/patrol-execution-service.js.map +1 -1
  58. package/dist/server/modules/butler/provider-adapter-registry.d.ts +3 -0
  59. package/dist/server/modules/butler/provider-adapter-registry.js +18 -1
  60. package/dist/server/modules/butler/provider-adapter-registry.js.map +1 -1
  61. package/dist/server/modules/butler/verification-run-service.d.ts +9 -2
  62. package/dist/server/modules/butler/verification-run-service.js +188 -34
  63. package/dist/server/modules/butler/verification-run-service.js.map +1 -1
  64. package/dist/server/modules/debug-target/debug-target-controller.js +1 -1
  65. package/dist/server/modules/debug-target/debug-target-controller.js.map +1 -1
  66. package/dist/server/modules/debug-target/debug-target-service.d.ts +7 -2
  67. package/dist/server/modules/debug-target/debug-target-service.js +563 -100
  68. package/dist/server/modules/debug-target/debug-target-service.js.map +1 -1
  69. package/dist/server/modules/git/git-command-helper-client.d.ts +1 -0
  70. package/dist/server/modules/git/git-command-helper-client.js +19 -26
  71. package/dist/server/modules/git/git-command-helper-client.js.map +1 -1
  72. package/dist/server/modules/git/git-command-runner.js +19 -1
  73. package/dist/server/modules/git/git-command-runner.js.map +1 -1
  74. package/dist/server/modules/preferences/profile-service.d.ts +3 -1
  75. package/dist/server/modules/preferences/profile-service.js +74 -3
  76. package/dist/server/modules/preferences/profile-service.js.map +1 -1
  77. package/dist/server/modules/provider/provider-discovery-helper-client.d.ts +5 -3
  78. package/dist/server/modules/provider/provider-discovery-helper-client.js +129 -43
  79. package/dist/server/modules/provider/provider-discovery-helper-client.js.map +1 -1
  80. package/dist/server/modules/provider/provider-discovery-helper-process.js +44 -0
  81. package/dist/server/modules/provider/provider-discovery-helper-process.js.map +1 -1
  82. package/dist/server/modules/provider/provider-discovery-runtime.js +83 -3
  83. package/dist/server/modules/provider/provider-discovery-runtime.js.map +1 -1
  84. package/dist/server/modules/sessions/claude-runtime-helper-client.js +23 -1
  85. package/dist/server/modules/sessions/claude-runtime-helper-client.js.map +1 -1
  86. package/dist/server/modules/sessions/session-history-service.d.ts +7 -1
  87. package/dist/server/modules/sessions/session-history-service.js +251 -41
  88. package/dist/server/modules/sessions/session-history-service.js.map +1 -1
  89. package/dist/server/modules/sessions/session-live-runtime-service.d.ts +6 -0
  90. package/dist/server/modules/sessions/session-live-runtime-service.js +97 -11
  91. package/dist/server/modules/sessions/session-live-runtime-service.js.map +1 -1
  92. package/dist/server/modules/sessions/session-message-origin-utils.d.ts +12 -0
  93. package/dist/server/modules/sessions/session-message-origin-utils.js +45 -0
  94. package/dist/server/modules/sessions/session-message-origin-utils.js.map +1 -0
  95. package/dist/server/modules/sessions/session-permission-request-service.js +167 -0
  96. package/dist/server/modules/sessions/session-permission-request-service.js.map +1 -1
  97. package/dist/server/modules/skills/builtin-skill-service.js +1 -1
  98. package/dist/server/modules/skills/builtin-skill-service.js.map +1 -1
  99. package/dist/server/modules/skills/builtin-skills/codingns-assistant/SKILL.md +19 -12
  100. package/dist/server/modules/skills/builtin-skills/codingns-assistant/references/cli-workflow.md +9 -3
  101. package/dist/server/modules/tasks/task-helper-client.d.ts +5 -2
  102. package/dist/server/modules/tasks/task-helper-client.js +118 -38
  103. package/dist/server/modules/tasks/task-helper-client.js.map +1 -1
  104. package/dist/server/modules/tasks/task-helper-process.js +94 -3
  105. package/dist/server/modules/tasks/task-helper-process.js.map +1 -1
  106. package/dist/server/modules/tasks/task-types.d.ts +3 -0
  107. package/dist/server/modules/tasks/task-types.js +4 -1
  108. package/dist/server/modules/tasks/task-types.js.map +1 -1
  109. package/dist/server/modules/terminal/command-template-service.d.ts +9 -0
  110. package/dist/server/modules/terminal/command-template-service.js +87 -5
  111. package/dist/server/modules/terminal/command-template-service.js.map +1 -1
  112. package/dist/server/modules/terminal/terminal-controller.d.ts +3 -0
  113. package/dist/server/modules/terminal/terminal-controller.js +41 -0
  114. package/dist/server/modules/terminal/terminal-controller.js.map +1 -1
  115. package/dist/server/modules/workbench/workbench-service.d.ts +3 -0
  116. package/dist/server/modules/workbench/workbench-service.js +4 -3
  117. package/dist/server/modules/workbench/workbench-service.js.map +1 -1
  118. package/dist/server/modules/workbench/workspace-file-watcher.d.ts +14 -6
  119. package/dist/server/modules/workbench/workspace-file-watcher.js +267 -57
  120. package/dist/server/modules/workbench/workspace-file-watcher.js.map +1 -1
  121. package/dist/server/modules/workbench/workspace-panel-snapshot-service.d.ts +2 -0
  122. package/dist/server/modules/workbench/workspace-panel-snapshot-service.js +32 -3
  123. package/dist/server/modules/workbench/workspace-panel-snapshot-service.js.map +1 -1
  124. package/dist/server/modules/worktree/worktree-manager.d.ts +9 -1
  125. package/dist/server/modules/worktree/worktree-manager.js +9 -1
  126. package/dist/server/modules/worktree/worktree-manager.js.map +1 -1
  127. package/dist/server/routes/assistant.js +19 -0
  128. package/dist/server/routes/assistant.js.map +1 -1
  129. package/dist/server/routes/butler.js +5 -0
  130. package/dist/server/routes/butler.js.map +1 -1
  131. package/dist/server/server/create-server.d.ts +8 -0
  132. package/dist/server/server/create-server.js +36 -13
  133. package/dist/server/server/create-server.js.map +1 -1
  134. package/dist/server/storage/repositories/assistant-automation-run-repository.d.ts +12 -0
  135. package/dist/server/storage/repositories/assistant-automation-run-repository.js +139 -0
  136. package/dist/server/storage/repositories/assistant-automation-run-repository.js.map +1 -0
  137. package/dist/server/storage/repositories/assistant-automation-task-repository.d.ts +15 -0
  138. package/dist/server/storage/repositories/assistant-automation-task-repository.js +173 -0
  139. package/dist/server/storage/repositories/assistant-automation-task-repository.js.map +1 -0
  140. package/dist/server/storage/repositories/assistant-sandbox-workspace-repository.d.ts +17 -0
  141. package/dist/server/storage/repositories/assistant-sandbox-workspace-repository.js +164 -0
  142. package/dist/server/storage/repositories/assistant-sandbox-workspace-repository.js.map +1 -0
  143. package/dist/server/storage/repositories/butler-control-session-repository.js +27 -3
  144. package/dist/server/storage/repositories/butler-control-session-repository.js.map +1 -1
  145. package/dist/server/storage/repositories/butler-control-timer-repository.d.ts +15 -0
  146. package/dist/server/storage/repositories/butler-control-timer-repository.js +157 -0
  147. package/dist/server/storage/repositories/butler-control-timer-repository.js.map +1 -0
  148. package/dist/server/storage/repositories/user-preference-profile-repository.js +6 -3
  149. package/dist/server/storage/repositories/user-preference-profile-repository.js.map +1 -1
  150. package/dist/server/storage/sqlite/client.js +239 -2
  151. package/dist/server/storage/sqlite/client.js.map +1 -1
  152. package/dist/server/storage/sqlite/schema.sql +107 -1
  153. package/dist/server/types/domain.d.ts +89 -2
  154. package/dist/server/ws/workbench-ws-hub.d.ts +14 -8
  155. package/dist/server/ws/workbench-ws-hub.js +299 -163
  156. package/dist/server/ws/workbench-ws-hub.js.map +1 -1
  157. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.d.ts +4 -1
  158. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js +111 -3
  159. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js.map +1 -1
  160. package/node_modules/@codingns/session-sync-core/dist/providers/codex.d.ts +6 -1
  161. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js +306 -31
  162. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js.map +1 -1
  163. package/node_modules/@codingns/session-sync-core/dist/providers/gemini.d.ts +5 -1
  164. package/node_modules/@codingns/session-sync-core/dist/providers/gemini.js +187 -26
  165. package/node_modules/@codingns/session-sync-core/dist/providers/gemini.js.map +1 -1
  166. package/node_modules/@codingns/session-sync-core/dist/providers/kimi.d.ts +4 -1
  167. package/node_modules/@codingns/session-sync-core/dist/providers/kimi.js +98 -1
  168. package/node_modules/@codingns/session-sync-core/dist/providers/kimi.js.map +1 -1
  169. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.d.ts +2 -0
  170. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js +71 -8
  171. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js.map +1 -1
  172. package/node_modules/@codingns/session-sync-core/dist/providers/utils.d.ts +1 -0
  173. package/node_modules/@codingns/session-sync-core/dist/providers/utils.js +4 -1
  174. package/node_modules/@codingns/session-sync-core/dist/providers/utils.js.map +1 -1
  175. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js +44 -0
  176. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js.map +1 -1
  177. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js +9 -3
  178. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js.map +1 -1
  179. package/node_modules/@codingns/session-sync-core/dist/runtime/types.d.ts +1 -0
  180. package/node_modules/@codingns/session-sync-core/dist/services.js +17 -8
  181. package/node_modules/@codingns/session-sync-core/dist/services.js.map +1 -1
  182. package/node_modules/@codingns/session-sync-core/dist/types.d.ts +4 -0
  183. package/package.json +1 -1
  184. package/dist/public/assets/index-BlOinYqR.js +0 -122
  185. package/dist/public/assets/index-Dg_7g6lA.css +0 -1
@@ -1,5 +1,7 @@
1
1
  import { createId } from "../../shared/utils/id.js";
2
+ import { AppError } from "../../shared/errors/app-error.js";
2
3
  import { nowIso } from "../../shared/utils/time.js";
4
+ import { recordButlerProxyMessageOrigin } from "../sessions/session-message-origin-utils.js";
3
5
  const ASSISTANT_CAPABILITIES = [
4
6
  {
5
7
  name: "capabilities.list",
@@ -25,6 +27,18 @@ const ASSISTANT_CAPABILITIES = [
25
27
  enabled: true,
26
28
  summary: "列出指定项目下可操作的会话"
27
29
  },
30
+ {
31
+ name: "projects.sessions.start",
32
+ mode: "proxy_execute",
33
+ enabled: true,
34
+ summary: "按当前助手配置为项目新建真实会话"
35
+ },
36
+ {
37
+ name: "sessions.start",
38
+ mode: "proxy_execute",
39
+ enabled: true,
40
+ summary: "按 project/workspace/sandbox 目标新建真实会话;未指定目标时自动创建沙箱"
41
+ },
28
42
  {
29
43
  name: "sessions.get",
30
44
  mode: "read",
@@ -55,6 +69,90 @@ const ASSISTANT_CAPABILITIES = [
55
69
  enabled: true,
56
70
  summary: "从指定会话或消息点 fork 新会话"
57
71
  },
72
+ {
73
+ name: "automations.list",
74
+ mode: "read",
75
+ enabled: true,
76
+ summary: "列出当前助手自动化任务"
77
+ },
78
+ {
79
+ name: "automations.get",
80
+ mode: "read",
81
+ enabled: true,
82
+ summary: "读取单个助手自动化任务详情"
83
+ },
84
+ {
85
+ name: "automations.create",
86
+ mode: "proxy_execute",
87
+ enabled: true,
88
+ summary: "创建正式助手自动化任务"
89
+ },
90
+ {
91
+ name: "automations.cancel",
92
+ mode: "proxy_execute",
93
+ enabled: true,
94
+ summary: "取消助手自动化任务"
95
+ },
96
+ {
97
+ name: "automations.runs.list",
98
+ mode: "read",
99
+ enabled: true,
100
+ summary: "读取助手自动化执行记录"
101
+ },
102
+ {
103
+ name: "sandboxes.list",
104
+ mode: "read",
105
+ enabled: true,
106
+ summary: "列出当前助手沙箱"
107
+ },
108
+ {
109
+ name: "sandboxes.create",
110
+ mode: "proxy_execute",
111
+ enabled: true,
112
+ summary: "创建新的助手沙箱"
113
+ },
114
+ {
115
+ name: "sandboxes.promote",
116
+ mode: "proxy_execute",
117
+ enabled: true,
118
+ summary: "保留或晋升助手沙箱"
119
+ },
120
+ {
121
+ name: "sandboxes.expire",
122
+ mode: "proxy_execute",
123
+ enabled: true,
124
+ summary: "标记助手沙箱过期"
125
+ },
126
+ {
127
+ name: "sandboxes.remove",
128
+ mode: "proxy_execute",
129
+ enabled: true,
130
+ summary: "清理助手沙箱"
131
+ },
132
+ {
133
+ name: "timers.list",
134
+ mode: "read",
135
+ enabled: true,
136
+ summary: "列出当前助手会话相关的计时器"
137
+ },
138
+ {
139
+ name: "timers.get",
140
+ mode: "read",
141
+ enabled: true,
142
+ summary: "读取单个助手计时器详情"
143
+ },
144
+ {
145
+ name: "timers.create",
146
+ mode: "proxy_execute",
147
+ enabled: true,
148
+ summary: "创建助手控制会话的定时继续任务"
149
+ },
150
+ {
151
+ name: "timers.cancel",
152
+ mode: "proxy_execute",
153
+ enabled: true,
154
+ summary: "取消助手控制会话计时器"
155
+ },
58
156
  {
59
157
  name: "terminals.list",
60
158
  mode: "read",
@@ -221,6 +319,10 @@ const ASSISTANT_CAPABILITIES = [
221
319
  export class AssistantCapabilityService {
222
320
  butlerProjectService;
223
321
  butlerSessionService;
322
+ butlerControlSessionService;
323
+ assistantAutomationService;
324
+ assistantSandboxService;
325
+ butlerControlTimerService;
224
326
  sessionHistoryService;
225
327
  sessionLiveRuntimeService;
226
328
  terminalService;
@@ -230,9 +332,14 @@ export class AssistantCapabilityService {
230
332
  worktreeSyncService;
231
333
  worktreeMergeService;
232
334
  worktreeCleanupService;
233
- constructor(butlerProjectService, butlerSessionService, sessionHistoryService, sessionLiveRuntimeService, terminalService, debugTargetService, workspaceService, worktreeManager, worktreeSyncService, worktreeMergeService, worktreeCleanupService) {
335
+ sessionMessageOriginRepository;
336
+ constructor(butlerProjectService, butlerSessionService, butlerControlSessionService, assistantAutomationService, assistantSandboxService, butlerControlTimerService, sessionHistoryService, sessionLiveRuntimeService, terminalService, debugTargetService, workspaceService, worktreeManager, worktreeSyncService, worktreeMergeService, worktreeCleanupService, sessionMessageOriginRepository = null) {
234
337
  this.butlerProjectService = butlerProjectService;
235
338
  this.butlerSessionService = butlerSessionService;
339
+ this.butlerControlSessionService = butlerControlSessionService;
340
+ this.assistantAutomationService = assistantAutomationService;
341
+ this.assistantSandboxService = assistantSandboxService;
342
+ this.butlerControlTimerService = butlerControlTimerService;
236
343
  this.sessionHistoryService = sessionHistoryService;
237
344
  this.sessionLiveRuntimeService = sessionLiveRuntimeService;
238
345
  this.terminalService = terminalService;
@@ -242,6 +349,7 @@ export class AssistantCapabilityService {
242
349
  this.worktreeSyncService = worktreeSyncService;
243
350
  this.worktreeMergeService = worktreeMergeService;
244
351
  this.worktreeCleanupService = worktreeCleanupService;
352
+ this.sessionMessageOriginRepository = sessionMessageOriginRepository;
245
353
  }
246
354
  listCapabilities() {
247
355
  return this.createReceipt("capabilities.list", {
@@ -289,6 +397,72 @@ export class AssistantCapabilityService {
289
397
  items
290
398
  });
291
399
  }
400
+ async startProjectSession(input) {
401
+ const config = this.resolveSessionLaunchConfig(input);
402
+ const session = await this.butlerSessionService.startSession(input.projectId, {
403
+ role: "adhoc",
404
+ ownershipMode: "managed",
405
+ content: input.content.trim(),
406
+ providerId: config.providerId,
407
+ model: config.model,
408
+ reasoningLevel: config.reasoningLevel,
409
+ permissionMode: config.permissionMode
410
+ }, input.userId);
411
+ return this.createReceipt("projects.sessions.start", {
412
+ kind: "project",
413
+ id: input.projectId
414
+ }, {
415
+ session
416
+ });
417
+ }
418
+ async startSession(input) {
419
+ const config = this.resolveSessionLaunchConfig(input);
420
+ const currentControlSession = this.butlerControlSessionService.getCurrentSession(input.userId);
421
+ const target = input.target
422
+ ? this.resolveAssistantSessionTarget(input.target, input.userId)
423
+ : await this.createAutomaticSandboxTarget(input, currentControlSession);
424
+ if (target.kind === "project") {
425
+ const session = await this.butlerSessionService.startSession(target.id, {
426
+ role: "adhoc",
427
+ ownershipMode: "managed",
428
+ content: input.content.trim(),
429
+ providerId: config.providerId,
430
+ model: config.model,
431
+ reasoningLevel: config.reasoningLevel,
432
+ permissionMode: config.permissionMode
433
+ }, input.userId);
434
+ return this.createReceipt("sessions.start", {
435
+ kind: "project",
436
+ id: target.id
437
+ }, {
438
+ session,
439
+ target
440
+ });
441
+ }
442
+ const session = await this.sessionLiveRuntimeService.startLiveSession({
443
+ workspaceId: target.workspaceId,
444
+ userId: input.userId,
445
+ provider: config.providerId,
446
+ content: input.content.trim(),
447
+ clientRequestId: null,
448
+ runtimeOptions: {
449
+ model: config.model,
450
+ reasoningLevel: config.reasoningLevel,
451
+ permissionMode: config.permissionMode,
452
+ attachments: []
453
+ }
454
+ });
455
+ if (target.kind === "sandbox") {
456
+ this.assistantSandboxService.markSandboxUsedByControlSession(target.id, input.userId, currentControlSession?.id ?? null);
457
+ }
458
+ return this.createReceipt("sessions.start", {
459
+ kind: target.kind,
460
+ id: target.id
461
+ }, {
462
+ session,
463
+ target
464
+ });
465
+ }
292
466
  getSession(sessionId, userId) {
293
467
  const session = this.sessionHistoryService.getSession(sessionId, userId);
294
468
  return this.createReceipt("sessions.get", {
@@ -317,11 +491,19 @@ export class AssistantCapabilityService {
317
491
  });
318
492
  }
319
493
  async sendSessionMessage(input) {
494
+ const requestedAt = nowIso();
495
+ const clientRequestId = recordButlerProxyMessageOrigin(this.sessionMessageOriginRepository, {
496
+ sessionId: input.sessionId,
497
+ clientRequestId: input.clientRequestId?.trim() || null,
498
+ content: input.content,
499
+ createdAt: requestedAt,
500
+ fallbackKey: `assistant-send:${input.sessionId}:${requestedAt}`
501
+ });
320
502
  const result = await this.sessionLiveRuntimeService.sendLiveMessage({
321
503
  sessionId: input.sessionId,
322
504
  userId: input.userId,
323
505
  content: input.content,
324
- clientRequestId: input.clientRequestId?.trim() || null,
506
+ clientRequestId,
325
507
  runtimeOptions: {
326
508
  model: input.model?.trim() || null,
327
509
  reasoningLevel: input.reasoningLevel?.trim() || null,
@@ -329,6 +511,14 @@ export class AssistantCapabilityService {
329
511
  attachments: []
330
512
  }
331
513
  });
514
+ recordButlerProxyMessageOrigin(this.sessionMessageOriginRepository, {
515
+ sessionId: input.sessionId,
516
+ clientRequestId,
517
+ messageId: result.message?.messageId ?? null,
518
+ content: input.content,
519
+ createdAt: result.acceptedAt,
520
+ fallbackKey: `assistant-send:${input.sessionId}:${result.acceptedAt}`
521
+ });
332
522
  return this.createReceipt("sessions.message.send", {
333
523
  kind: "session",
334
524
  id: input.sessionId
@@ -352,6 +542,229 @@ export class AssistantCapabilityService {
352
542
  session
353
543
  });
354
544
  }
545
+ listTimers(input) {
546
+ const items = this.butlerControlTimerService.listTimers({
547
+ userId: input.userId,
548
+ statuses: input.status ? [input.status] : undefined,
549
+ controlSessionId: input.controlSessionId ?? null,
550
+ limit: input.limit ?? undefined
551
+ });
552
+ return this.createReceipt("timers.list", {
553
+ kind: "none",
554
+ id: null
555
+ }, {
556
+ items
557
+ });
558
+ }
559
+ listAutomations(input) {
560
+ const items = this.assistantAutomationService.listTasks({
561
+ userId: input.userId,
562
+ statuses: input.status ? [input.status] : undefined,
563
+ controlSessionId: input.controlSessionId ?? null
564
+ });
565
+ return this.createReceipt("automations.list", {
566
+ kind: "none",
567
+ id: null
568
+ }, {
569
+ items
570
+ });
571
+ }
572
+ getAutomation(automationId, userId) {
573
+ const automation = this.assistantAutomationService.getTask(automationId, userId);
574
+ return this.createReceipt("automations.get", {
575
+ kind: "automation",
576
+ id: automationId
577
+ }, {
578
+ automation
579
+ });
580
+ }
581
+ createAutomation(input) {
582
+ const triggerType = input.triggerType ?? "once";
583
+ const automation = this.assistantAutomationService.createTask({
584
+ userId: input.userId,
585
+ controlSessionId: input.controlSessionId,
586
+ projectId: input.projectId,
587
+ title: input.title,
588
+ trigger: buildAssistantAutomationTriggerInput(triggerType, input),
589
+ action: {
590
+ type: "send_control_message",
591
+ content: input.content,
592
+ includeTriggerContext: input.includeTriggerContext ?? triggerType === "condition",
593
+ targetSessionId: input.targetSessionId ?? null
594
+ }
595
+ });
596
+ return this.createReceipt("automations.create", {
597
+ kind: "automation",
598
+ id: automation.id
599
+ }, {
600
+ automation
601
+ });
602
+ }
603
+ updateAutomation(input) {
604
+ const automation = this.assistantAutomationService.updateTask({
605
+ taskId: input.automationId,
606
+ userId: input.userId,
607
+ title: input.title,
608
+ content: input.content,
609
+ includeTriggerContext: input.includeTriggerContext,
610
+ dueAt: input.dueAt,
611
+ everySeconds: input.everySeconds,
612
+ everyMinutes: input.everyMinutes,
613
+ everyHours: input.everyHours,
614
+ stopAt: input.stopAt,
615
+ cronMinute: input.cronMinute,
616
+ cronHour: input.cronHour,
617
+ cronDaysOfWeek: input.cronDaysOfWeek,
618
+ pollIntervalSeconds: input.pollIntervalSeconds,
619
+ expiresAt: input.expiresAt,
620
+ maxChecks: input.maxChecks
621
+ });
622
+ return this.createReceipt("automations.update", {
623
+ kind: "automation",
624
+ id: input.automationId
625
+ }, {
626
+ automation
627
+ });
628
+ }
629
+ cancelAutomation(automationId, userId) {
630
+ const automation = this.assistantAutomationService.cancelTask(automationId, userId);
631
+ return this.createReceipt("automations.cancel", {
632
+ kind: "automation",
633
+ id: automationId
634
+ }, {
635
+ automation
636
+ });
637
+ }
638
+ skipAutomationWait(automationId, userId) {
639
+ const automation = this.assistantAutomationService.skipCurrentWait(automationId, userId);
640
+ return this.createReceipt("automations.wait.skip", {
641
+ kind: "automation",
642
+ id: automationId
643
+ }, {
644
+ automation
645
+ });
646
+ }
647
+ listAutomationRuns(automationId, userId) {
648
+ const items = this.assistantAutomationService.listRuns(automationId, userId);
649
+ return this.createReceipt("automations.runs.list", {
650
+ kind: "automation",
651
+ id: automationId
652
+ }, {
653
+ items
654
+ });
655
+ }
656
+ listRecentAutomationRuns(input) {
657
+ const items = this.assistantAutomationService.listRecentRuns({
658
+ userId: input.userId,
659
+ controlSessionId: input.controlSessionId ?? null,
660
+ limit: input.limit ?? undefined
661
+ });
662
+ return this.createReceipt("automations.runs.recent", {
663
+ kind: "none",
664
+ id: null
665
+ }, {
666
+ items
667
+ });
668
+ }
669
+ listSandboxes(input) {
670
+ const items = this.assistantSandboxService.listSandboxes({
671
+ userId: input.userId,
672
+ controlSessionId: input.controlSessionId ?? null,
673
+ statuses: input.status ? [input.status] : undefined
674
+ });
675
+ return this.createReceipt("sandboxes.list", {
676
+ kind: "none",
677
+ id: null
678
+ }, {
679
+ items
680
+ });
681
+ }
682
+ async createSandbox(input) {
683
+ const currentControlSession = this.butlerControlSessionService.getCurrentSession(input.userId);
684
+ const sandbox = await this.assistantSandboxService.createSandbox({
685
+ userId: input.userId,
686
+ controlSessionId: currentControlSession?.id ?? null,
687
+ title: input.title,
688
+ description: input.description,
689
+ purpose: input.purpose,
690
+ expiresAt: input.expiresAt,
691
+ source: input.sourceKind === "clone"
692
+ ? {
693
+ kind: "clone",
694
+ repositoryUrl: requireAssistantRepositoryUrl(input.repositoryUrl),
695
+ directoryName: input.directoryName,
696
+ auth: input.auth
697
+ }
698
+ : {
699
+ kind: "blank",
700
+ directoryName: input.directoryName
701
+ }
702
+ });
703
+ return this.createReceipt("sandboxes.create", {
704
+ kind: "sandbox",
705
+ id: sandbox.id
706
+ }, {
707
+ sandbox
708
+ });
709
+ }
710
+ promoteSandbox(input) {
711
+ const sandbox = this.assistantSandboxService.promoteSandbox(input.sandboxId, input.userId, {
712
+ mode: input.mode,
713
+ projectName: input.projectName,
714
+ defaultProvider: input.defaultProvider
715
+ });
716
+ return this.createReceipt("sandboxes.promote", {
717
+ kind: "sandbox",
718
+ id: input.sandboxId
719
+ }, {
720
+ sandbox
721
+ });
722
+ }
723
+ expireSandbox(sandboxId, userId) {
724
+ const sandbox = this.assistantSandboxService.expireSandbox(sandboxId, userId);
725
+ return this.createReceipt("sandboxes.expire", {
726
+ kind: "sandbox",
727
+ id: sandboxId
728
+ }, {
729
+ sandbox
730
+ });
731
+ }
732
+ removeSandbox(sandboxId, userId) {
733
+ const sandbox = this.assistantSandboxService.removeSandbox(sandboxId, userId);
734
+ return this.createReceipt("sandboxes.remove", {
735
+ kind: "sandbox",
736
+ id: sandboxId
737
+ }, {
738
+ sandbox
739
+ });
740
+ }
741
+ getTimer(timerId, userId) {
742
+ const timer = this.butlerControlTimerService.getTimer(timerId, userId);
743
+ return this.createReceipt("timers.get", {
744
+ kind: "timer",
745
+ id: timerId
746
+ }, {
747
+ timer
748
+ });
749
+ }
750
+ createTimer(input) {
751
+ const timer = this.butlerControlTimerService.createTimer(input);
752
+ return this.createReceipt("timers.create", {
753
+ kind: "timer",
754
+ id: timer.id
755
+ }, {
756
+ timer
757
+ });
758
+ }
759
+ cancelTimer(timerId, userId) {
760
+ const timer = this.butlerControlTimerService.cancelTimer(timerId, userId);
761
+ return this.createReceipt("timers.cancel", {
762
+ kind: "timer",
763
+ id: timerId
764
+ }, {
765
+ timer
766
+ });
767
+ }
355
768
  async listTerminals(input) {
356
769
  const workspaceId = input.projectId?.trim()
357
770
  ? this.butlerProjectService.getById(input.projectId).workspaceId
@@ -430,7 +843,7 @@ export class AssistantCapabilityService {
430
843
  });
431
844
  }
432
845
  async createDebugLaunchPlan(input) {
433
- const plan = await this.debugTargetService.createLaunchPlan(input.targetId, input.portRequests);
846
+ const plan = await this.debugTargetService.createLaunchPlan(input.targetId, input.portRequests, input.userId);
434
847
  return this.createReceipt("debug-targets.launch-plan.create", {
435
848
  kind: "debug_target",
436
849
  id: input.targetId
@@ -630,5 +1043,154 @@ export class AssistantCapabilityService {
630
1043
  payload
631
1044
  };
632
1045
  }
1046
+ resolveSessionLaunchConfig(input) {
1047
+ const controlSession = this.butlerControlSessionService.getCurrentSession(input.userId);
1048
+ const providerId = input.providerId?.trim()
1049
+ ?? controlSession?.providerId
1050
+ ?? undefined;
1051
+ if (!providerId) {
1052
+ throw new AppError({
1053
+ statusCode: 409,
1054
+ errorCode: "ASSISTANT_CONTROL_SESSION_NOT_FOUND",
1055
+ detail: "当前没有可用的助手控制会话,无法继承默认 provider"
1056
+ });
1057
+ }
1058
+ return {
1059
+ providerId,
1060
+ model: normalizeAssistantText(input.model) ?? controlSession?.model ?? null,
1061
+ reasoningLevel: normalizeAssistantText(input.reasoningLevel) ?? controlSession?.reasoningLevel ?? null,
1062
+ permissionMode: normalizeAssistantText(input.permissionMode) ?? controlSession?.permissionMode ?? null
1063
+ };
1064
+ }
1065
+ resolveAssistantSessionTarget(target, userId) {
1066
+ if (target.kind === "project") {
1067
+ const project = this.butlerProjectService.getById(target.projectId);
1068
+ return {
1069
+ kind: "project",
1070
+ id: project.id,
1071
+ workspaceId: project.workspaceId
1072
+ };
1073
+ }
1074
+ if (target.kind === "workspace") {
1075
+ return {
1076
+ kind: "workspace",
1077
+ id: target.workspaceId,
1078
+ workspaceId: target.workspaceId
1079
+ };
1080
+ }
1081
+ return {
1082
+ kind: "sandbox",
1083
+ id: target.sandboxId,
1084
+ workspaceId: this.assistantSandboxService.resolveWorkspaceId(target.sandboxId, userId)
1085
+ };
1086
+ }
1087
+ async createAutomaticSandboxTarget(input, controlSession) {
1088
+ const sandbox = await this.assistantSandboxService.createSandbox({
1089
+ userId: input.userId,
1090
+ controlSessionId: controlSession?.id ?? null,
1091
+ title: inferAutomaticSandboxTitle(controlSession, input.content),
1092
+ purpose: "当前任务未指定工作区,系统自动创建",
1093
+ source: {
1094
+ kind: "blank"
1095
+ }
1096
+ });
1097
+ return {
1098
+ kind: "sandbox",
1099
+ id: sandbox.id,
1100
+ workspaceId: sandbox.workspaceId
1101
+ };
1102
+ }
1103
+ }
1104
+ function normalizeAssistantText(value) {
1105
+ const normalized = value?.trim();
1106
+ return normalized ? normalized : null;
1107
+ }
1108
+ function inferAutomaticSandboxTitle(controlSession, content) {
1109
+ return normalizeAssistantText(controlSession?.title)
1110
+ ?? normalizeAssistantText(controlSession?.lastSummary)
1111
+ ?? summarizeAssistantText(content)
1112
+ ?? "助手临时沙箱";
1113
+ }
1114
+ function summarizeAssistantText(content) {
1115
+ const normalized = normalizeAssistantText(content);
1116
+ if (!normalized) {
1117
+ return null;
1118
+ }
1119
+ return normalized.length > 48 ? `${normalized.slice(0, 45)}...` : normalized;
1120
+ }
1121
+ function buildAssistantAutomationTriggerInput(triggerType, input) {
1122
+ switch (triggerType) {
1123
+ case "once":
1124
+ return {
1125
+ type: "once",
1126
+ dueAt: input.dueAt ?? null,
1127
+ afterSeconds: input.afterSeconds ?? null
1128
+ };
1129
+ case "interval":
1130
+ return {
1131
+ type: "interval",
1132
+ seconds: input.everySeconds ?? null,
1133
+ minutes: input.everyMinutes ?? null,
1134
+ hours: input.everyHours ?? null,
1135
+ stopAt: input.stopAt ?? null
1136
+ };
1137
+ case "cron":
1138
+ return {
1139
+ type: "cron",
1140
+ minute: input.cronMinute ?? null,
1141
+ hour: input.cronHour ?? null,
1142
+ daysOfWeek: input.cronDaysOfWeek ?? null,
1143
+ stopAt: input.stopAt ?? null
1144
+ };
1145
+ case "condition": {
1146
+ const conditionKind = input.conditionKind;
1147
+ if (conditionKind === "git.remote_tag_changed") {
1148
+ return {
1149
+ type: "condition",
1150
+ conditionKind,
1151
+ repositoryUrl: input.repositoryUrl ?? null,
1152
+ pollIntervalSeconds: input.pollIntervalSeconds ?? null,
1153
+ expiresAt: input.expiresAt ?? null,
1154
+ maxChecks: input.maxChecks ?? null
1155
+ };
1156
+ }
1157
+ return {
1158
+ type: "condition",
1159
+ conditionKind: requireAssistantConditionKind(conditionKind),
1160
+ sessionId: input.conditionSessionId ?? null,
1161
+ pollIntervalSeconds: input.pollIntervalSeconds ?? null,
1162
+ expiresAt: input.expiresAt ?? null,
1163
+ maxChecks: input.maxChecks ?? null
1164
+ };
1165
+ }
1166
+ default:
1167
+ return assertNeverAssistantAutomationTriggerType(triggerType);
1168
+ }
1169
+ }
1170
+ function requireAssistantRepositoryUrl(value) {
1171
+ const normalized = normalizeAssistantText(value);
1172
+ if (!normalized) {
1173
+ throw new AppError({
1174
+ statusCode: 400,
1175
+ errorCode: "INVALID_INPUT",
1176
+ detail: "clone 沙箱必须提供 repositoryUrl",
1177
+ field: "repositoryUrl"
1178
+ });
1179
+ }
1180
+ return normalized;
1181
+ }
1182
+ function requireAssistantConditionKind(value) {
1183
+ if (value === "git.remote_tag_changed" || value === "session.runtime_idle") {
1184
+ return value;
1185
+ }
1186
+ throw new AppError({
1187
+ statusCode: 400,
1188
+ errorCode: "INVALID_INPUT",
1189
+ detail: "condition 自动化必须提供 conditionKind",
1190
+ field: "conditionKind"
1191
+ });
1192
+ }
1193
+ function assertNeverAssistantAutomationTriggerType(value) {
1194
+ throw new Error(`Unexpected assistant automation triggerType: ${String(value)}`);
633
1195
  }
634
1196
  //# sourceMappingURL=assistant-capability-service.js.map