vellum 0.2.12 → 0.2.14

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/README.md +32 -0
  2. package/bun.lock +2 -2
  3. package/docs/skills.md +4 -4
  4. package/package.json +2 -2
  5. package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +213 -3
  6. package/src/__tests__/app-git-history.test.ts +176 -0
  7. package/src/__tests__/app-git-service.test.ts +169 -0
  8. package/src/__tests__/assistant-events-sse-hardening.test.ts +315 -0
  9. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +8 -8
  10. package/src/__tests__/browser-skill-endstate.test.ts +6 -6
  11. package/src/__tests__/call-bridge.test.ts +105 -13
  12. package/src/__tests__/call-domain.test.ts +163 -0
  13. package/src/__tests__/call-orchestrator.test.ts +171 -0
  14. package/src/__tests__/call-routes-http.test.ts +246 -6
  15. package/src/__tests__/channel-approval-routes.test.ts +438 -0
  16. package/src/__tests__/channel-approval.test.ts +266 -0
  17. package/src/__tests__/channel-approvals.test.ts +393 -0
  18. package/src/__tests__/channel-delivery-store.test.ts +447 -0
  19. package/src/__tests__/checker.test.ts +607 -1048
  20. package/src/__tests__/cli.test.ts +1 -56
  21. package/src/__tests__/config-schema.test.ts +402 -5
  22. package/src/__tests__/conflict-intent-tokenization.test.ts +141 -0
  23. package/src/__tests__/conflict-policy.test.ts +121 -0
  24. package/src/__tests__/conflict-store.test.ts +2 -0
  25. package/src/__tests__/contacts-tools.test.ts +3 -3
  26. package/src/__tests__/contradiction-checker.test.ts +99 -1
  27. package/src/__tests__/credential-security-invariants.test.ts +22 -6
  28. package/src/__tests__/credential-vault-unit.test.ts +780 -0
  29. package/src/__tests__/elevenlabs-client.test.ts +271 -0
  30. package/src/__tests__/ephemeral-permissions.test.ts +73 -23
  31. package/src/__tests__/filesystem-tools.test.ts +579 -0
  32. package/src/__tests__/gateway-only-enforcement.test.ts +114 -4
  33. package/src/__tests__/handlers-add-trust-rule-metadata.test.ts +202 -0
  34. package/src/__tests__/handlers-cu-observation-blob.test.ts +2 -1
  35. package/src/__tests__/handlers-ipc-blob-probe.test.ts +2 -1
  36. package/src/__tests__/handlers-slack-config.test.ts +2 -1
  37. package/src/__tests__/handlers-telegram-config.test.ts +855 -0
  38. package/src/__tests__/handlers-twitter-config.test.ts +141 -1
  39. package/src/__tests__/hooks-runner.test.ts +6 -2
  40. package/src/__tests__/host-file-edit-tool.test.ts +124 -0
  41. package/src/__tests__/host-file-read-tool.test.ts +62 -0
  42. package/src/__tests__/host-file-write-tool.test.ts +59 -0
  43. package/src/__tests__/host-shell-tool.test.ts +251 -0
  44. package/src/__tests__/ingress-reconcile.test.ts +581 -0
  45. package/src/__tests__/ipc-snapshot.test.ts +100 -41
  46. package/src/__tests__/ipc-validate.test.ts +50 -0
  47. package/src/__tests__/key-migration.test.ts +23 -0
  48. package/src/__tests__/memory-regressions.test.ts +99 -0
  49. package/src/__tests__/memory-retrieval.benchmark.test.ts +1 -1
  50. package/src/__tests__/oauth-callback-registry.test.ts +11 -4
  51. package/src/__tests__/playbook-execution.test.ts +502 -0
  52. package/src/__tests__/playbook-tools.test.ts +4 -6
  53. package/src/__tests__/public-ingress-urls.test.ts +34 -0
  54. package/src/__tests__/qdrant-manager.test.ts +267 -0
  55. package/src/__tests__/recurrence-engine-rruleset.test.ts +97 -0
  56. package/src/__tests__/recurrence-engine.test.ts +9 -0
  57. package/src/__tests__/recurrence-types.test.ts +8 -0
  58. package/src/__tests__/registry.test.ts +1 -1
  59. package/src/__tests__/runtime-runs.test.ts +1 -25
  60. package/src/__tests__/schedule-store.test.ts +16 -14
  61. package/src/__tests__/schedule-tools.test.ts +83 -0
  62. package/src/__tests__/scheduler-recurrence.test.ts +111 -10
  63. package/src/__tests__/secret-allowlist.test.ts +18 -17
  64. package/src/__tests__/secret-ingress-handler.test.ts +11 -0
  65. package/src/__tests__/secret-scanner.test.ts +43 -0
  66. package/src/__tests__/session-conflict-gate.test.ts +442 -6
  67. package/src/__tests__/session-init.benchmark.test.ts +3 -0
  68. package/src/__tests__/session-process-bridge.test.ts +242 -0
  69. package/src/__tests__/session-skill-tools.test.ts +1 -1
  70. package/src/__tests__/shell-identity.test.ts +256 -0
  71. package/src/__tests__/skill-projection.benchmark.test.ts +11 -1
  72. package/src/__tests__/subagent-tools.test.ts +637 -54
  73. package/src/__tests__/task-management-tools.test.ts +936 -0
  74. package/src/__tests__/task-runner.test.ts +2 -2
  75. package/src/__tests__/terminal-tools.test.ts +840 -0
  76. package/src/__tests__/tool-executor-shell-integration.test.ts +301 -0
  77. package/src/__tests__/tool-executor.test.ts +85 -151
  78. package/src/__tests__/tool-permission-simulate-handler.test.ts +336 -0
  79. package/src/__tests__/trust-store.test.ts +28 -453
  80. package/src/__tests__/twilio-provider.test.ts +153 -3
  81. package/src/__tests__/twilio-routes-elevenlabs.test.ts +375 -0
  82. package/src/__tests__/twilio-routes-twiml.test.ts +127 -0
  83. package/src/__tests__/twilio-routes.test.ts +17 -262
  84. package/src/__tests__/twitter-auth-handler.test.ts +2 -1
  85. package/src/__tests__/twitter-cli-error-shaping.test.ts +208 -0
  86. package/src/__tests__/twitter-cli-routing.test.ts +252 -0
  87. package/src/__tests__/twitter-oauth-client.test.ts +209 -0
  88. package/src/__tests__/workspace-policy.test.ts +213 -0
  89. package/src/calls/call-bridge.ts +92 -19
  90. package/src/calls/call-domain.ts +157 -5
  91. package/src/calls/call-orchestrator.ts +96 -8
  92. package/src/calls/call-store.ts +6 -0
  93. package/src/calls/elevenlabs-client.ts +97 -0
  94. package/src/calls/elevenlabs-config.ts +31 -0
  95. package/src/calls/twilio-provider.ts +91 -0
  96. package/src/calls/twilio-routes.ts +50 -6
  97. package/src/calls/types.ts +3 -1
  98. package/src/calls/voice-quality.ts +114 -0
  99. package/src/cli/twitter.ts +200 -21
  100. package/src/cli.ts +1 -20
  101. package/src/config/bundled-skills/contacts/tools/contact-merge.ts +52 -4
  102. package/src/config/bundled-skills/contacts/tools/contact-search.ts +55 -4
  103. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +61 -4
  104. package/src/config/bundled-skills/messaging/SKILL.md +17 -2
  105. package/src/config/bundled-skills/messaging/tools/messaging-reply.ts +4 -1
  106. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +5 -1
  107. package/src/config/bundled-skills/messaging/tools/shared.ts +5 -0
  108. package/src/config/bundled-skills/phone-calls/SKILL.md +207 -19
  109. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +95 -6
  110. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +51 -6
  111. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +73 -6
  112. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +110 -6
  113. package/src/config/bundled-skills/public-ingress/SKILL.md +22 -5
  114. package/src/config/bundled-skills/twitter/SKILL.md +103 -17
  115. package/src/config/defaults.ts +26 -2
  116. package/src/config/schema.ts +178 -9
  117. package/src/config/types.ts +3 -0
  118. package/src/config/vellum-skills/telegram-setup/SKILL.md +56 -61
  119. package/src/daemon/assistant-attachments.ts +4 -2
  120. package/src/daemon/handlers/apps.ts +69 -0
  121. package/src/daemon/handlers/config.ts +543 -24
  122. package/src/daemon/handlers/index.ts +1 -0
  123. package/src/daemon/handlers/sessions.ts +22 -6
  124. package/src/daemon/handlers/shared.ts +2 -1
  125. package/src/daemon/handlers/skills.ts +5 -20
  126. package/src/daemon/ipc-contract-inventory.json +28 -0
  127. package/src/daemon/ipc-contract.ts +168 -10
  128. package/src/daemon/ipc-validate.ts +17 -0
  129. package/src/daemon/lifecycle.ts +2 -0
  130. package/src/daemon/server.ts +78 -72
  131. package/src/daemon/session-attachments.ts +1 -1
  132. package/src/daemon/session-conflict-gate.ts +62 -6
  133. package/src/daemon/session-notifiers.ts +1 -1
  134. package/src/daemon/session-process.ts +62 -3
  135. package/src/daemon/session-tool-setup.ts +1 -2
  136. package/src/daemon/tls-certs.ts +189 -0
  137. package/src/daemon/video-thumbnail.ts +5 -3
  138. package/src/hooks/manager.ts +5 -9
  139. package/src/memory/app-git-service.ts +295 -0
  140. package/src/memory/app-store.ts +21 -0
  141. package/src/memory/conflict-intent.ts +47 -4
  142. package/src/memory/conflict-policy.ts +73 -0
  143. package/src/memory/conflict-store.ts +9 -1
  144. package/src/memory/contradiction-checker.ts +28 -0
  145. package/src/memory/conversation-key-store.ts +15 -0
  146. package/src/memory/db.ts +81 -0
  147. package/src/memory/embedding-local.ts +3 -13
  148. package/src/memory/external-conversation-store.ts +234 -0
  149. package/src/memory/job-handlers/conflict.ts +22 -2
  150. package/src/memory/jobs-worker.ts +67 -28
  151. package/src/memory/runs-store.ts +54 -7
  152. package/src/memory/schema.ts +20 -0
  153. package/src/messaging/provider.ts +9 -0
  154. package/src/messaging/providers/telegram-bot/adapter.ts +162 -0
  155. package/src/messaging/providers/telegram-bot/client.ts +104 -0
  156. package/src/messaging/providers/telegram-bot/types.ts +15 -0
  157. package/src/messaging/registry.ts +1 -0
  158. package/src/permissions/checker.ts +48 -44
  159. package/src/permissions/defaults.ts +11 -0
  160. package/src/permissions/prompter.ts +0 -4
  161. package/src/permissions/shell-identity.ts +227 -0
  162. package/src/permissions/trust-store.ts +76 -53
  163. package/src/permissions/types.ts +0 -19
  164. package/src/permissions/workspace-policy.ts +114 -0
  165. package/src/providers/retry.ts +12 -37
  166. package/src/runtime/assistant-event-hub.ts +41 -4
  167. package/src/runtime/channel-approval-parser.ts +60 -0
  168. package/src/runtime/channel-approval-types.ts +71 -0
  169. package/src/runtime/channel-approvals.ts +145 -0
  170. package/src/runtime/gateway-client.ts +16 -0
  171. package/src/runtime/http-server.ts +29 -9
  172. package/src/runtime/routes/call-routes.ts +52 -2
  173. package/src/runtime/routes/channel-routes.ts +296 -16
  174. package/src/runtime/routes/conversation-routes.ts +12 -5
  175. package/src/runtime/routes/events-routes.ts +97 -28
  176. package/src/runtime/routes/run-routes.ts +2 -7
  177. package/src/runtime/run-orchestrator.ts +0 -3
  178. package/src/schedule/recurrence-engine.ts +26 -2
  179. package/src/schedule/recurrence-types.ts +1 -1
  180. package/src/schedule/schedule-store.ts +12 -3
  181. package/src/security/secret-scanner.ts +7 -0
  182. package/src/tasks/ephemeral-permissions.ts +0 -2
  183. package/src/tasks/task-scheduler.ts +2 -1
  184. package/src/tools/calls/call-start.ts +8 -0
  185. package/src/tools/execution-target.ts +21 -0
  186. package/src/tools/execution-timeout.ts +49 -0
  187. package/src/tools/executor.ts +6 -135
  188. package/src/tools/network/web-search.ts +9 -32
  189. package/src/tools/policy-context.ts +29 -0
  190. package/src/tools/schedule/update.ts +8 -1
  191. package/src/tools/terminal/parser.ts +16 -18
  192. package/src/tools/types.ts +4 -11
  193. package/src/twitter/oauth-client.ts +102 -0
  194. package/src/twitter/router.ts +101 -0
  195. package/src/util/debounce.ts +88 -0
  196. package/src/util/network-info.ts +47 -0
  197. package/src/util/platform.ts +29 -4
  198. package/src/util/promise-guard.ts +37 -0
  199. package/src/util/retry.ts +98 -0
  200. package/src/util/truncate.ts +1 -1
  201. package/src/workspace/git-service.ts +129 -112
  202. package/src/tools/contacts/contact-merge.ts +0 -55
  203. package/src/tools/contacts/contact-search.ts +0 -58
  204. package/src/tools/contacts/contact-upsert.ts +0 -64
  205. package/src/tools/playbooks/index.ts +0 -4
  206. package/src/tools/playbooks/playbook-create.ts +0 -96
  207. package/src/tools/playbooks/playbook-delete.ts +0 -52
  208. package/src/tools/playbooks/playbook-list.ts +0 -74
  209. package/src/tools/playbooks/playbook-update.ts +0 -111
@@ -86,6 +86,7 @@ const inlineHandlers = defineHandlers({
86
86
  });
87
87
  },
88
88
  integration_disconnect: () => { /* no-op — integration registry removed */ },
89
+
89
90
  });
90
91
 
91
92
  const handlers = {
@@ -1,6 +1,7 @@
1
1
  import * as net from 'node:net';
2
2
  import { v4 as uuid } from 'uuid';
3
3
  import * as conversationStore from '../../memory/conversation-store.js';
4
+ import * as externalConversationStore from '../../memory/external-conversation-store.js';
4
5
  import { checkIngressForSecrets } from '../../security/secret-ingress.js';
5
6
  import { classifySessionError, buildSessionErrorMessage } from '../session-error.js';
6
7
  import { getAttachmentsForMessage, setAttachmentThumbnail } from '../../memory/attachments-store.js';
@@ -199,14 +200,29 @@ export function handleSecretResponse(
199
200
 
200
201
  export function handleSessionList(socket: net.Socket, ctx: HandlerContext): void {
201
202
  const conversations = conversationStore.listConversations(50);
203
+ const bindings = externalConversationStore.getBindingsForConversations(
204
+ conversations.map((c) => c.id),
205
+ );
202
206
  ctx.send(socket, {
203
207
  type: 'session_list_response',
204
- sessions: conversations.map((c) => ({
205
- id: c.id,
206
- title: c.title ?? 'Untitled',
207
- updatedAt: c.updatedAt,
208
- threadType: normalizeThreadType(c.threadType),
209
- })),
208
+ sessions: conversations.map((c) => {
209
+ const binding = bindings.get(c.id);
210
+ return {
211
+ id: c.id,
212
+ title: c.title ?? 'Untitled',
213
+ updatedAt: c.updatedAt,
214
+ threadType: normalizeThreadType(c.threadType),
215
+ ...(binding ? {
216
+ channelBinding: {
217
+ sourceChannel: binding.sourceChannel,
218
+ externalChatId: binding.externalChatId,
219
+ externalUserId: binding.externalUserId,
220
+ displayName: binding.displayName,
221
+ username: binding.username,
222
+ },
223
+ } : {}),
224
+ };
225
+ }),
210
226
  });
211
227
  }
212
228
 
@@ -8,6 +8,7 @@ import { estimateBase64Bytes } from '../assistant-attachments.js';
8
8
  import type { ClientMessage, CuSessionCreate, ServerMessage, SessionTransportMetadata } from '../ipc-protocol.js';
9
9
  import type { SecretPromptResult } from '../../permissions/secret-prompter.js';
10
10
  import { getConfig } from '../../config/loader.js';
11
+ import type { DebouncerMap } from '../../util/debounce.js';
11
12
 
12
13
  const log = getLogger('handlers');
13
14
 
@@ -115,7 +116,7 @@ export interface HandlerContext {
115
116
  cuObservationParseSequence: Map<string, number>;
116
117
  socketSandboxOverride: Map<net.Socket, boolean>;
117
118
  sharedRequestTimestamps: number[];
118
- debounceTimers: Map<string, ReturnType<typeof setTimeout>>;
119
+ debounceTimers: DebouncerMap;
119
120
  suppressConfigReload: boolean;
120
121
  setSuppressConfigReload(value: boolean): void;
121
122
  updateConfigFingerprint(): void;
@@ -61,10 +61,7 @@ export function handleSkillsEnable(
61
61
  }
62
62
  invalidateConfigCache();
63
63
 
64
- const existingSuppressTimer = ctx.debounceTimers.get('__suppress_reset__');
65
- if (existingSuppressTimer) clearTimeout(existingSuppressTimer);
66
- const resetTimer = setTimeout(() => { ctx.setSuppressConfigReload(false); }, CONFIG_RELOAD_DEBOUNCE_MS);
67
- ctx.debounceTimers.set('__suppress_reset__', resetTimer);
64
+ ctx.debounceTimers.schedule('__suppress_reset__', () => { ctx.setSuppressConfigReload(false); }, CONFIG_RELOAD_DEBOUNCE_MS);
68
65
 
69
66
  ctx.updateConfigFingerprint();
70
67
 
@@ -108,10 +105,7 @@ export function handleSkillsDisable(
108
105
  }
109
106
  invalidateConfigCache();
110
107
 
111
- const existingSuppressTimer = ctx.debounceTimers.get('__suppress_reset__');
112
- if (existingSuppressTimer) clearTimeout(existingSuppressTimer);
113
- const resetTimer = setTimeout(() => { ctx.setSuppressConfigReload(false); }, CONFIG_RELOAD_DEBOUNCE_MS);
114
- ctx.debounceTimers.set('__suppress_reset__', resetTimer);
108
+ ctx.debounceTimers.schedule('__suppress_reset__', () => { ctx.setSuppressConfigReload(false); }, CONFIG_RELOAD_DEBOUNCE_MS);
115
109
 
116
110
  ctx.updateConfigFingerprint();
117
111
 
@@ -165,10 +159,7 @@ export function handleSkillsConfigure(
165
159
  }
166
160
  invalidateConfigCache();
167
161
 
168
- const existingSuppressTimer = ctx.debounceTimers.get('__suppress_reset__');
169
- if (existingSuppressTimer) clearTimeout(existingSuppressTimer);
170
- const resetTimer = setTimeout(() => { ctx.setSuppressConfigReload(false); }, CONFIG_RELOAD_DEBOUNCE_MS);
171
- ctx.debounceTimers.set('__suppress_reset__', resetTimer);
162
+ ctx.debounceTimers.schedule('__suppress_reset__', () => { ctx.setSuppressConfigReload(false); }, CONFIG_RELOAD_DEBOUNCE_MS);
172
163
 
173
164
  ctx.updateConfigFingerprint();
174
165
 
@@ -226,10 +217,7 @@ export async function handleSkillsInstall(
226
217
  throw err;
227
218
  }
228
219
  invalidateConfigCache();
229
- const existingSuppressTimer = ctx.debounceTimers.get('__suppress_reset__');
230
- if (existingSuppressTimer) clearTimeout(existingSuppressTimer);
231
- const resetTimer = setTimeout(() => { ctx.setSuppressConfigReload(false); }, CONFIG_RELOAD_DEBOUNCE_MS);
232
- ctx.debounceTimers.set('__suppress_reset__', resetTimer);
220
+ ctx.debounceTimers.schedule('__suppress_reset__', () => { ctx.setSuppressConfigReload(false); }, CONFIG_RELOAD_DEBOUNCE_MS);
233
221
  ctx.updateConfigFingerprint();
234
222
  } catch (err) {
235
223
  log.warn({ err, skillId }, 'Failed to auto-enable installed skill');
@@ -321,10 +309,7 @@ export async function handleSkillsUninstall(
321
309
  }
322
310
  invalidateConfigCache();
323
311
 
324
- const existingSuppressTimer = ctx.debounceTimers.get('__suppress_reset__');
325
- if (existingSuppressTimer) clearTimeout(existingSuppressTimer);
326
- const resetTimer = setTimeout(() => { ctx.setSuppressConfigReload(false); }, CONFIG_RELOAD_DEBOUNCE_MS);
327
- ctx.debounceTimers.set('__suppress_reset__', resetTimer);
312
+ ctx.debounceTimers.schedule('__suppress_reset__', () => { ctx.setSuppressConfigReload(false); }, CONFIG_RELOAD_DEBOUNCE_MS);
328
313
 
329
314
  ctx.updateConfigFingerprint();
330
315
  }
@@ -3,8 +3,12 @@
3
3
  "AcceptStarterBundle",
4
4
  "AddTrustRule",
5
5
  "AppDataRequest",
6
+ "AppDiffRequest",
7
+ "AppFileAtVersionRequest",
8
+ "AppHistoryRequest",
6
9
  "AppOpenRequest",
7
10
  "AppPreviewRequest",
11
+ "AppRestoreRequest",
8
12
  "AppUpdatePreviewRequest",
9
13
  "AppsListRequest",
10
14
  "AuthMessage",
@@ -82,6 +86,9 @@
82
86
  "SubagentStatusRequest",
83
87
  "SuggestionRequest",
84
88
  "TaskSubmit",
89
+ "TelegramConfigRequest",
90
+ "ToolNamesListRequest",
91
+ "ToolPermissionSimulateRequest",
85
92
  "TrustRulesList",
86
93
  "TwitterAuthStartRequest",
87
94
  "TwitterAuthStatusRequest",
@@ -112,8 +119,12 @@
112
119
  "AcceptStarterBundleResponse",
113
120
  "AgentHeartbeatAlert",
114
121
  "AppDataResponse",
122
+ "AppDiffResponse",
123
+ "AppFileAtVersionResponse",
115
124
  "AppFilesChanged",
125
+ "AppHistoryResponse",
116
126
  "AppPreviewResponse",
127
+ "AppRestoreResponse",
117
128
  "AppUpdatePreviewResponse",
118
129
  "AppsListResponse",
119
130
  "AssistantTextDelta",
@@ -193,8 +204,11 @@
193
204
  "TaskRouted",
194
205
  "TaskRunThreadCreated",
195
206
  "TasksChanged",
207
+ "TelegramConfigResponse",
196
208
  "ToolInputDelta",
209
+ "ToolNamesListResponse",
197
210
  "ToolOutputChunk",
211
+ "ToolPermissionSimulateResponse",
198
212
  "ToolResult",
199
213
  "ToolUseStart",
200
214
  "TraceEvent",
@@ -234,8 +248,12 @@
234
248
  "accept_starter_bundle",
235
249
  "add_trust_rule",
236
250
  "app_data_request",
251
+ "app_diff_request",
252
+ "app_file_at_version_request",
253
+ "app_history_request",
237
254
  "app_open_request",
238
255
  "app_preview_request",
256
+ "app_restore_request",
239
257
  "app_update_preview",
240
258
  "apps_list",
241
259
  "auth",
@@ -313,6 +331,9 @@
313
331
  "subagent_status",
314
332
  "suggestion_request",
315
333
  "task_submit",
334
+ "telegram_config",
335
+ "tool_names_list",
336
+ "tool_permission_simulate",
316
337
  "trust_rules_list",
317
338
  "twitter_auth_start",
318
339
  "twitter_auth_status",
@@ -343,8 +364,12 @@
343
364
  "accept_starter_bundle_response",
344
365
  "agent_heartbeat_alert",
345
366
  "app_data_response",
367
+ "app_diff_response",
368
+ "app_file_at_version_response",
346
369
  "app_files_changed",
370
+ "app_history_response",
347
371
  "app_preview_response",
372
+ "app_restore_response",
348
373
  "app_update_preview_response",
349
374
  "apps_list_response",
350
375
  "assistant_text_delta",
@@ -424,8 +449,11 @@
424
449
  "task_routed",
425
450
  "task_run_thread_created",
426
451
  "tasks_changed",
452
+ "telegram_config_response",
427
453
  "tool_input_delta",
454
+ "tool_names_list_response",
428
455
  "tool_output_chunk",
456
+ "tool_permission_simulate_response",
429
457
  "tool_result",
430
458
  "tool_use_start",
431
459
  "trace_event",
@@ -318,6 +318,10 @@ export interface AddTrustRule {
318
318
  pattern: string;
319
319
  scope: string;
320
320
  decision: 'allow' | 'deny' | 'ask';
321
+ /** When true, the rule also covers high-risk invocations. */
322
+ allowHighRisk?: boolean;
323
+ /** Execution target override for this rule. */
324
+ executionTarget?: 'host' | 'sandbox';
321
325
  }
322
326
 
323
327
  export interface TrustRulesList {
@@ -456,6 +460,32 @@ export interface GalleryInstallRequest {
456
460
  galleryAppId: string;
457
461
  }
458
462
 
463
+ export interface AppHistoryRequest {
464
+ type: 'app_history_request';
465
+ appId: string;
466
+ limit?: number;
467
+ }
468
+
469
+ export interface AppDiffRequest {
470
+ type: 'app_diff_request';
471
+ appId: string;
472
+ fromCommit: string;
473
+ toCommit?: string;
474
+ }
475
+
476
+ export interface AppFileAtVersionRequest {
477
+ type: 'app_file_at_version_request';
478
+ appId: string;
479
+ path: string;
480
+ commitHash: string;
481
+ }
482
+
483
+ export interface AppRestoreRequest {
484
+ type: 'app_restore_request';
485
+ appId: string;
486
+ commitHash: string;
487
+ }
488
+
459
489
  export interface ShareAppCloudRequest {
460
490
  type: 'share_app_cloud';
461
491
  appId: string;
@@ -494,10 +524,29 @@ export interface VercelApiConfigResponse {
494
524
 
495
525
  export interface TwitterIntegrationConfigRequest {
496
526
  type: 'twitter_integration_config';
497
- action: 'get' | 'set_mode' | 'set_local_client' | 'clear_local_client' | 'disconnect';
527
+ action: 'get' | 'set_mode' | 'set_local_client' | 'clear_local_client' | 'disconnect' | 'get_strategy' | 'set_strategy';
498
528
  mode?: 'local_byo' | 'managed';
499
529
  clientId?: string;
500
530
  clientSecret?: string;
531
+ strategy?: string;
532
+ }
533
+
534
+ export interface TelegramConfigRequest {
535
+ type: 'telegram_config';
536
+ action: 'get' | 'set' | 'clear' | 'set_commands';
537
+ botToken?: string; // Only for action: 'set'
538
+ commands?: Array<{ command: string; description: string }>; // Only for action: 'set_commands'
539
+ }
540
+
541
+ export interface TelegramConfigResponse {
542
+ type: 'telegram_config_response';
543
+ success: boolean;
544
+ hasBotToken: boolean;
545
+ botUsername?: string;
546
+ connected: boolean;
547
+ hasWebhookSecret: boolean;
548
+ lastError?: string;
549
+ error?: string;
501
550
  }
502
551
 
503
552
  export interface TwitterIntegrationConfigResponse {
@@ -508,6 +557,9 @@ export interface TwitterIntegrationConfigResponse {
508
557
  localClientConfigured: boolean;
509
558
  connected: boolean;
510
559
  accountInfo?: string;
560
+ strategy?: 'oauth' | 'browser' | 'auto';
561
+ /** Whether the user has explicitly set a strategy (vs. relying on the default 'auto'). */
562
+ strategyConfigured?: boolean;
511
563
  error?: string;
512
564
  }
513
565
 
@@ -892,6 +944,24 @@ export interface IdentityGetRequest {
892
944
  type: 'identity_get';
893
945
  }
894
946
 
947
+ export interface ToolPermissionSimulateRequest {
948
+ type: 'tool_permission_simulate';
949
+ /** Tool name to simulate (e.g. 'bash', 'file_write'). */
950
+ toolName: string;
951
+ /** Tool input record to simulate. */
952
+ input: Record<string, unknown>;
953
+ /** Working directory context; defaults to daemon cwd when omitted. */
954
+ workingDir?: string;
955
+ /** Whether the simulated context is interactive (default true). */
956
+ isInteractive?: boolean;
957
+ /** When true, side-effect tools that would normally be auto-allowed get promoted to prompt. */
958
+ forcePromptSideEffects?: boolean;
959
+ }
960
+
961
+ export interface ToolNamesListRequest {
962
+ type: 'tool_names_list';
963
+ }
964
+
895
965
  export type ClientMessage =
896
966
  | AuthMessage
897
967
  | UserMessage
@@ -961,11 +1031,16 @@ export type ClientMessage =
961
1031
  | IngressConfigRequest
962
1032
  | VercelApiConfigRequest
963
1033
  | TwitterIntegrationConfigRequest
1034
+ | TelegramConfigRequest
964
1035
  | TwitterAuthStartRequest
965
1036
  | TwitterAuthStatusRequest
966
1037
  | SessionsClearRequest
967
1038
  | GalleryListRequest
968
1039
  | GalleryInstallRequest
1040
+ | AppHistoryRequest
1041
+ | AppDiffRequest
1042
+ | AppFileAtVersionRequest
1043
+ | AppRestoreRequest
969
1044
  | AppUpdatePreviewRequest
970
1045
  | AppPreviewRequest
971
1046
  | PublishPageRequest
@@ -999,7 +1074,9 @@ export type ClientMessage =
999
1074
  | SubagentDetailRequest
1000
1075
  | WorkspaceFilesListRequest
1001
1076
  | WorkspaceFileReadRequest
1002
- | IdentityGetRequest;
1077
+ | IdentityGetRequest
1078
+ | ToolPermissionSimulateRequest
1079
+ | ToolNamesListRequest;
1003
1080
 
1004
1081
  export interface IntegrationListRequest {
1005
1082
  type: 'integration_list';
@@ -1106,12 +1183,6 @@ export interface ConfirmationRequest {
1106
1183
  diff?: { filePath: string; oldContent: string; newContent: string; isNewFile: boolean };
1107
1184
  sandboxed?: boolean;
1108
1185
  sessionId?: string;
1109
- /** Principal kind that initiated this tool use (e.g. 'core' or 'skill'). */
1110
- principalKind?: string;
1111
- /** Skill ID when principalKind is 'skill'. */
1112
- principalId?: string;
1113
- /** Content-hash of the skill source for version tracking. */
1114
- principalVersion?: string;
1115
1186
  /** When false, the client should hide "always allow" / trust-rule persistence affordances. */
1116
1187
  persistentDecisionsAllowed?: boolean;
1117
1188
  }
@@ -1149,9 +1220,18 @@ export interface SessionInfo {
1149
1220
  threadType?: ThreadType;
1150
1221
  }
1151
1222
 
1223
+ /** Channel binding metadata exposed in session/conversation list APIs. */
1224
+ export interface ChannelBinding {
1225
+ sourceChannel: string;
1226
+ externalChatId: string;
1227
+ externalUserId?: string | null;
1228
+ displayName?: string | null;
1229
+ username?: string | null;
1230
+ }
1231
+
1152
1232
  export interface SessionListResponse {
1153
1233
  type: 'session_list_response';
1154
- sessions: Array<{ id: string; title: string; updatedAt: number; threadType?: ThreadType }>;
1234
+ sessions: Array<{ id: string; title: string; updatedAt: number; threadType?: ThreadType; channelBinding?: ChannelBinding }>;
1155
1235
  }
1156
1236
 
1157
1237
  export interface SessionsClearResponse {
@@ -1695,6 +1775,35 @@ export interface GalleryInstallResponse {
1695
1775
  error?: string;
1696
1776
  }
1697
1777
 
1778
+ export interface AppHistoryResponse {
1779
+ type: 'app_history_response';
1780
+ appId: string;
1781
+ versions: Array<{
1782
+ commitHash: string;
1783
+ message: string;
1784
+ timestamp: number;
1785
+ }>;
1786
+ }
1787
+
1788
+ export interface AppDiffResponse {
1789
+ type: 'app_diff_response';
1790
+ appId: string;
1791
+ diff: string;
1792
+ }
1793
+
1794
+ export interface AppFileAtVersionResponse {
1795
+ type: 'app_file_at_version_response';
1796
+ appId: string;
1797
+ path: string;
1798
+ content: string;
1799
+ }
1800
+
1801
+ export interface AppRestoreResponse {
1802
+ type: 'app_restore_response';
1803
+ success: boolean;
1804
+ error?: string;
1805
+ }
1806
+
1698
1807
  export interface ShareToSlackResponse {
1699
1808
  type: 'share_to_slack_response';
1700
1809
  success: boolean;
@@ -2160,6 +2269,48 @@ export interface IdentityGetResponse {
2160
2269
  originSystem?: string;
2161
2270
  }
2162
2271
 
2272
+ export interface ToolPermissionSimulateResponse {
2273
+ type: 'tool_permission_simulate_response';
2274
+ success: boolean;
2275
+ /** The simulated permission decision. */
2276
+ decision?: 'allow' | 'deny' | 'prompt';
2277
+ /** Risk level of the simulated tool invocation. */
2278
+ riskLevel?: string;
2279
+ /** Human-readable reason for the decision. */
2280
+ reason?: string;
2281
+ /** When decision is 'prompt', the data needed to render a ToolConfirmationBubble. */
2282
+ promptPayload?: {
2283
+ allowlistOptions: Array<{ label: string; description: string; pattern: string }>;
2284
+ scopeOptions: Array<{ label: string; scope: string }>;
2285
+ persistentDecisionsAllowed: boolean;
2286
+ };
2287
+ /** Resolved execution target for the tool. */
2288
+ executionTarget?: 'host' | 'sandbox';
2289
+ /** ID of the trust rule that matched (if any). */
2290
+ matchedRuleId?: string;
2291
+ /** Error message when success is false. */
2292
+ error?: string;
2293
+ }
2294
+
2295
+ export interface ToolInputSchema {
2296
+ type: 'object';
2297
+ properties?: Record<string, {
2298
+ type?: string;
2299
+ description?: string;
2300
+ enum?: string[];
2301
+ [key: string]: unknown;
2302
+ }>;
2303
+ required?: string[];
2304
+ }
2305
+
2306
+ export interface ToolNamesListResponse {
2307
+ type: 'tool_names_list_response';
2308
+ /** Sorted list of all registered tool names. */
2309
+ names: string[];
2310
+ /** Input schemas keyed by tool name. */
2311
+ schemas?: Record<string, ToolInputSchema>;
2312
+ }
2313
+
2163
2314
  export type ServerMessage =
2164
2315
  | AuthResult
2165
2316
  | UserMessageEcho
@@ -2235,11 +2386,16 @@ export type ServerMessage =
2235
2386
  | TraceEvent
2236
2387
  | GalleryListResponse
2237
2388
  | GalleryInstallResponse
2389
+ | AppHistoryResponse
2390
+ | AppDiffResponse
2391
+ | AppFileAtVersionResponse
2392
+ | AppRestoreResponse
2238
2393
  | ShareToSlackResponse
2239
2394
  | SlackWebhookConfigResponse
2240
2395
  | IngressConfigResponse
2241
2396
  | VercelApiConfigResponse
2242
2397
  | TwitterIntegrationConfigResponse
2398
+ | TelegramConfigResponse
2243
2399
  | TwitterAuthResult
2244
2400
  | TwitterAuthStatusResponse
2245
2401
  | OpenUrl
@@ -2280,7 +2436,9 @@ export type ServerMessage =
2280
2436
  | SubagentDetailResponse
2281
2437
  | WorkspaceFilesListResponse
2282
2438
  | WorkspaceFileReadResponse
2283
- | IdentityGetResponse;
2439
+ | IdentityGetResponse
2440
+ | ToolPermissionSimulateResponse
2441
+ | ToolNamesListResponse;
2284
2442
 
2285
2443
  // === Subagent IPC ─────────────────────────────────────────────────────
2286
2444
 
@@ -150,6 +150,23 @@ const HIGH_RISK_VALIDATORS: Record<string, PropertyValidator> = {
150
150
  return null;
151
151
  },
152
152
 
153
+ add_trust_rule: (obj) => {
154
+ if (typeof obj.toolName !== 'string' || obj.toolName === '') {
155
+ return 'add_trust_rule requires a non-empty string "toolName"';
156
+ }
157
+ if (typeof obj.pattern !== 'string') {
158
+ return 'add_trust_rule requires a string "pattern"';
159
+ }
160
+ if (typeof obj.scope !== 'string') {
161
+ return 'add_trust_rule requires a string "scope"';
162
+ }
163
+ const validDecisions = ['allow', 'deny', 'ask'];
164
+ if (typeof obj.decision !== 'string' || !validDecisions.includes(obj.decision)) {
165
+ return `add_trust_rule "decision" must be one of: ${validDecisions.join(', ')}`;
166
+ }
167
+ return null;
168
+ },
169
+
153
170
  ui_surface_action: (obj) => {
154
171
  if (typeof obj.sessionId !== 'string' || obj.sessionId === '') {
155
172
  return 'ui_surface_action requires a non-empty string "sessionId"';
@@ -41,6 +41,7 @@ import { slackProvider as slackWatcherProvider } from '../watcher/providers/slac
41
41
  import { registerMessagingProvider } from '../messaging/registry.js';
42
42
  import { slackProvider as slackMessagingProvider } from '../messaging/providers/slack/adapter.js';
43
43
  import { gmailMessagingProvider } from '../messaging/providers/gmail/adapter.js';
44
+ import { telegramBotMessagingProvider } from '../messaging/providers/telegram-bot/adapter.js';
44
45
  import { browserManager } from '../tools/browser/browser-manager.js';
45
46
  import { RuntimeHttpServer } from '../runtime/http-server.js';
46
47
  import { getHookManager } from '../hooks/manager.js';
@@ -384,6 +385,7 @@ export async function runDaemon(): Promise<void> {
384
385
  // Register messaging providers
385
386
  registerMessagingProvider(slackMessagingProvider);
386
387
  registerMessagingProvider(gmailMessagingProvider);
388
+ registerMessagingProvider(telegramBotMessagingProvider);
387
389
 
388
390
  const scheduler = startScheduler(
389
391
  async (conversationId, message) => {