@dobby.ai/dobby 0.1.0 → 0.1.2

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 (156) hide show
  1. package/README.md +84 -39
  2. package/dist/src/agent/event-forwarder.js +185 -16
  3. package/dist/src/cli/commands/cron.js +39 -35
  4. package/dist/src/cli/commands/doctor.js +81 -2
  5. package/dist/src/cli/commands/extension.js +3 -1
  6. package/dist/src/cli/commands/init.js +43 -173
  7. package/dist/src/cli/commands/topology.js +38 -14
  8. package/dist/src/cli/program.js +15 -137
  9. package/dist/src/cli/shared/config-io.js +3 -31
  10. package/dist/src/cli/shared/config-mutators.js +33 -9
  11. package/dist/src/cli/shared/configure-sections.js +52 -12
  12. package/dist/src/cli/shared/init-catalog.js +89 -46
  13. package/dist/src/cli/shared/local-extension-specs.js +85 -0
  14. package/dist/src/cli/shared/schema-prompts.js +26 -2
  15. package/dist/src/core/gateway.js +3 -1
  16. package/dist/src/core/routing.js +53 -38
  17. package/dist/src/core/types.js +2 -0
  18. package/dist/src/cron/config.js +2 -2
  19. package/dist/src/cron/service.js +87 -23
  20. package/dist/src/cron/store.js +1 -1
  21. package/dist/src/main.js +0 -0
  22. package/dist/src/shared/dobby-repo.js +40 -0
  23. package/package.json +11 -4
  24. package/.env.example +0 -9
  25. package/AGENTS.md +0 -267
  26. package/ROADMAP.md +0 -34
  27. package/config/cron.example.json +0 -9
  28. package/config/gateway.example.json +0 -128
  29. package/config/models.custom.example.json +0 -27
  30. package/dist/src/agent/tests/event-forwarder.test.js +0 -113
  31. package/dist/src/cli/shared/config-path.js +0 -207
  32. package/dist/src/cli/shared/init-models-file.js +0 -65
  33. package/dist/src/cli/shared/presets.js +0 -86
  34. package/dist/src/cli/tests/config-command.test.js +0 -42
  35. package/dist/src/cli/tests/config-io.test.js +0 -64
  36. package/dist/src/cli/tests/config-mutators.test.js +0 -47
  37. package/dist/src/cli/tests/config-path.test.js +0 -21
  38. package/dist/src/cli/tests/discord-config.test.js +0 -23
  39. package/dist/src/cli/tests/doctor.test.js +0 -107
  40. package/dist/src/cli/tests/init-catalog.test.js +0 -87
  41. package/dist/src/cli/tests/presets.test.js +0 -41
  42. package/dist/src/cli/tests/program-options.test.js +0 -92
  43. package/dist/src/cli/tests/routing-config.test.js +0 -199
  44. package/dist/src/cli/tests/routing-legacy.test.js +0 -191
  45. package/dist/src/core/tests/control-command.test.js +0 -17
  46. package/dist/src/core/tests/gateway-update-strategy.test.js +0 -167
  47. package/dist/src/core/tests/runtime-registry.test.js +0 -116
  48. package/dist/src/core/tests/typing-controller.test.js +0 -103
  49. package/docs/BOXLITE_SANDBOX_FEASIBILITY.md +0 -175
  50. package/docs/CRON_SCHEDULER_DESIGN.md +0 -374
  51. package/docs/DOCKER_SANDBOX_vs_BOXLITE.md +0 -77
  52. package/docs/EXTENSION_SYSTEM_ARCHITECTURE.md +0 -119
  53. package/docs/MVP.md +0 -135
  54. package/docs/RUNBOOK.md +0 -242
  55. package/docs/TEAMWORK_HANDOFF_DESIGN.md +0 -440
  56. package/plugins/connector-discord/dobby.manifest.json +0 -18
  57. package/plugins/connector-discord/index.js +0 -1
  58. package/plugins/connector-discord/package-lock.json +0 -360
  59. package/plugins/connector-discord/package.json +0 -38
  60. package/plugins/connector-discord/src/connector.ts +0 -350
  61. package/plugins/connector-discord/src/contribution.ts +0 -21
  62. package/plugins/connector-discord/src/mapper.ts +0 -102
  63. package/plugins/connector-discord/tsconfig.json +0 -19
  64. package/plugins/connector-feishu/dobby.manifest.json +0 -18
  65. package/plugins/connector-feishu/index.js +0 -1
  66. package/plugins/connector-feishu/package-lock.json +0 -618
  67. package/plugins/connector-feishu/package.json +0 -38
  68. package/plugins/connector-feishu/src/connector.ts +0 -343
  69. package/plugins/connector-feishu/src/contribution.ts +0 -26
  70. package/plugins/connector-feishu/src/mapper.ts +0 -401
  71. package/plugins/connector-feishu/tsconfig.json +0 -19
  72. package/plugins/plugin-sdk/index.d.ts +0 -261
  73. package/plugins/plugin-sdk/index.js +0 -1
  74. package/plugins/plugin-sdk/package-lock.json +0 -12
  75. package/plugins/plugin-sdk/package.json +0 -22
  76. package/plugins/provider-claude/dobby.manifest.json +0 -17
  77. package/plugins/provider-claude/index.js +0 -1
  78. package/plugins/provider-claude/package-lock.json +0 -3398
  79. package/plugins/provider-claude/package.json +0 -39
  80. package/plugins/provider-claude/src/contribution.ts +0 -1018
  81. package/plugins/provider-claude/tsconfig.json +0 -19
  82. package/plugins/provider-claude-cli/dobby.manifest.json +0 -17
  83. package/plugins/provider-claude-cli/index.js +0 -1
  84. package/plugins/provider-claude-cli/package-lock.json +0 -2898
  85. package/plugins/provider-claude-cli/package.json +0 -38
  86. package/plugins/provider-claude-cli/src/contribution.ts +0 -1673
  87. package/plugins/provider-claude-cli/tsconfig.json +0 -19
  88. package/plugins/provider-pi/dobby.manifest.json +0 -17
  89. package/plugins/provider-pi/index.js +0 -1
  90. package/plugins/provider-pi/package-lock.json +0 -3877
  91. package/plugins/provider-pi/package.json +0 -40
  92. package/plugins/provider-pi/src/contribution.ts +0 -476
  93. package/plugins/provider-pi/tsconfig.json +0 -19
  94. package/plugins/sandbox-core/boxlite.js +0 -1
  95. package/plugins/sandbox-core/dobby.manifest.json +0 -17
  96. package/plugins/sandbox-core/docker.js +0 -1
  97. package/plugins/sandbox-core/package-lock.json +0 -136
  98. package/plugins/sandbox-core/package.json +0 -39
  99. package/plugins/sandbox-core/src/boxlite-context.ts +0 -2
  100. package/plugins/sandbox-core/src/boxlite-contribution.ts +0 -53
  101. package/plugins/sandbox-core/src/boxlite-executor.ts +0 -911
  102. package/plugins/sandbox-core/src/docker-contribution.ts +0 -43
  103. package/plugins/sandbox-core/src/docker-executor.ts +0 -217
  104. package/plugins/sandbox-core/tsconfig.json +0 -19
  105. package/scripts/local-extensions.mjs +0 -168
  106. package/src/agent/event-forwarder.ts +0 -414
  107. package/src/cli/commands/config.ts +0 -328
  108. package/src/cli/commands/configure.ts +0 -92
  109. package/src/cli/commands/cron.ts +0 -410
  110. package/src/cli/commands/doctor.ts +0 -230
  111. package/src/cli/commands/extension.ts +0 -205
  112. package/src/cli/commands/init.ts +0 -396
  113. package/src/cli/commands/start.ts +0 -223
  114. package/src/cli/commands/topology.ts +0 -383
  115. package/src/cli/index.ts +0 -9
  116. package/src/cli/program.ts +0 -465
  117. package/src/cli/shared/config-io.ts +0 -277
  118. package/src/cli/shared/config-mutators.ts +0 -440
  119. package/src/cli/shared/config-schema.ts +0 -228
  120. package/src/cli/shared/config-types.ts +0 -121
  121. package/src/cli/shared/configure-sections.ts +0 -551
  122. package/src/cli/shared/discord-config.ts +0 -14
  123. package/src/cli/shared/init-catalog.ts +0 -189
  124. package/src/cli/shared/init-models-file.ts +0 -77
  125. package/src/cli/shared/runtime.ts +0 -33
  126. package/src/cli/shared/schema-prompts.ts +0 -414
  127. package/src/cli/tests/config-command.test.ts +0 -56
  128. package/src/cli/tests/config-io.test.ts +0 -92
  129. package/src/cli/tests/config-mutators.test.ts +0 -59
  130. package/src/cli/tests/doctor.test.ts +0 -120
  131. package/src/cli/tests/init-catalog.test.ts +0 -96
  132. package/src/cli/tests/program-options.test.ts +0 -113
  133. package/src/cli/tests/routing-config.test.ts +0 -209
  134. package/src/core/control-command.ts +0 -12
  135. package/src/core/dedup-store.ts +0 -103
  136. package/src/core/gateway.ts +0 -607
  137. package/src/core/routing.ts +0 -379
  138. package/src/core/runtime-registry.ts +0 -141
  139. package/src/core/tests/control-command.test.ts +0 -20
  140. package/src/core/tests/runtime-registry.test.ts +0 -140
  141. package/src/core/tests/typing-controller.test.ts +0 -129
  142. package/src/core/types.ts +0 -318
  143. package/src/core/typing-controller.ts +0 -119
  144. package/src/cron/config.ts +0 -154
  145. package/src/cron/schedule.ts +0 -61
  146. package/src/cron/service.ts +0 -249
  147. package/src/cron/store.ts +0 -155
  148. package/src/cron/types.ts +0 -60
  149. package/src/extension/loader.ts +0 -145
  150. package/src/extension/manager.ts +0 -355
  151. package/src/extension/manifest.ts +0 -26
  152. package/src/extension/registry.ts +0 -229
  153. package/src/main.ts +0 -8
  154. package/src/sandbox/executor.ts +0 -44
  155. package/src/sandbox/host-executor.ts +0 -118
  156. package/tsconfig.json +0 -18
@@ -1,465 +0,0 @@
1
- import { Command } from "commander";
2
- import {
3
- runConfigEditCommand,
4
- runConfigListCommand,
5
- runConfigSchemaListCommand,
6
- runConfigSchemaShowCommand,
7
- runConfigShowCommand,
8
- } from "./commands/config.js";
9
- import { runConfigureCommand } from "./commands/configure.js";
10
- import {
11
- runCronAddCommand,
12
- runCronListCommand,
13
- runCronPauseCommand,
14
- runCronRemoveCommand,
15
- runCronResumeCommand,
16
- runCronRunCommand,
17
- runCronStatusCommand,
18
- runCronUpdateCommand,
19
- } from "./commands/cron.js";
20
- import { runDoctorCommand } from "./commands/doctor.js";
21
- import {
22
- runExtensionInstallCommand,
23
- runExtensionListCommand,
24
- runExtensionUninstallCommand,
25
- } from "./commands/extension.js";
26
- import { runInitCommand } from "./commands/init.js";
27
- import { runStartCommand } from "./commands/start.js";
28
- import {
29
- runBindingListCommand,
30
- runBindingRemoveCommand,
31
- runBindingSetCommand,
32
- runBotListCommand,
33
- runBotSetCommand,
34
- runRouteListCommand,
35
- runRouteRemoveCommand,
36
- runRouteSetCommand,
37
- } from "./commands/topology.js";
38
-
39
- /**
40
- * Builds the top-level dobby CLI program and registers all subcommands.
41
- */
42
- export function buildProgram(): Command {
43
- const program = new Command();
44
- program
45
- .name("dobby")
46
- .description("Discord-first local agent gateway")
47
- .showHelpAfterError()
48
- .action(async () => {
49
- await runStartCommand();
50
- });
51
-
52
- program
53
- .command("start")
54
- .description("Start the gateway")
55
- .action(async () => {
56
- await runStartCommand();
57
- });
58
-
59
- program
60
- .command("init")
61
- .description("Initialize minimal runnable gateway config")
62
- .action(async () => {
63
- await runInitCommand();
64
- });
65
-
66
- program
67
- .command("configure")
68
- .description("Interactive configuration wizard")
69
- .option(
70
- "--section <section>",
71
- "Config section (repeatable): provider|connector|route|binding|sandbox|data",
72
- (value: string, previous: string[]) => [...previous, value],
73
- [] as string[],
74
- )
75
- .action(async (opts) => {
76
- await runConfigureCommand({
77
- sections: opts.section as string[],
78
- });
79
- });
80
-
81
- const botCommand = program.command("bot").description("Manage bot connector settings");
82
-
83
- botCommand
84
- .command("list")
85
- .description("List configured bot connectors")
86
- .option("--json", "Output JSON", false)
87
- .action(async (opts) => {
88
- await runBotListCommand({
89
- json: Boolean(opts.json),
90
- });
91
- });
92
-
93
- botCommand
94
- .command("set")
95
- .description("Update one bot connector")
96
- .argument("<connectorId>", "Connector instance ID")
97
- .option("--name <name>", "Discord botName")
98
- .option("--token <token>", "Discord botToken")
99
- .action(async (connectorId: string, opts) => {
100
- await runBotSetCommand({
101
- connectorId,
102
- ...(typeof opts.name === "string" ? { name: opts.name as string } : {}),
103
- ...(typeof opts.token === "string" ? { token: opts.token as string } : {}),
104
- });
105
- });
106
-
107
- const bindingCommand = program.command("binding").description("Manage connector source-route bindings");
108
-
109
- bindingCommand
110
- .command("list")
111
- .description("List bindings")
112
- .option("--connector <id>", "Filter by connector instance ID")
113
- .option("--json", "Output JSON", false)
114
- .action(async (opts) => {
115
- await runBindingListCommand({
116
- ...(typeof opts.connector === "string" ? { connectorId: opts.connector as string } : {}),
117
- json: Boolean(opts.json),
118
- });
119
- });
120
-
121
- bindingCommand
122
- .command("set")
123
- .description("Create or update one binding")
124
- .argument("<bindingId>", "Binding ID")
125
- .requiredOption("--connector <id>", "Connector instance ID")
126
- .requiredOption("--source-type <type>", "Source type: channel|chat")
127
- .requiredOption("--source-id <id>", "Source ID")
128
- .requiredOption("--route <id>", "Route ID")
129
- .action(async (bindingId: string, opts) => {
130
- if (opts.sourceType !== "channel" && opts.sourceType !== "chat") {
131
- throw new Error("--source-type must be channel or chat");
132
- }
133
-
134
- await runBindingSetCommand({
135
- bindingId,
136
- connectorId: opts.connector as string,
137
- sourceType: opts.sourceType as "channel" | "chat",
138
- sourceId: opts.sourceId as string,
139
- routeId: opts.route as string,
140
- });
141
- });
142
-
143
- bindingCommand
144
- .command("remove")
145
- .description("Remove one binding")
146
- .argument("<bindingId>", "Binding ID")
147
- .action(async (bindingId: string) => {
148
- await runBindingRemoveCommand({
149
- bindingId,
150
- });
151
- });
152
-
153
- const routeCommand = program.command("route").description("Manage route profiles");
154
-
155
- routeCommand
156
- .command("list")
157
- .description("List route profiles")
158
- .option("--json", "Output JSON", false)
159
- .action(async (opts) => {
160
- await runRouteListCommand({
161
- json: Boolean(opts.json),
162
- });
163
- });
164
-
165
- routeCommand
166
- .command("set")
167
- .description("Create or update one route")
168
- .argument("<routeId>", "Route ID")
169
- .option("--project-root <path>", "Route project root")
170
- .option("--tools <profile>", "Route tools profile: full|readonly")
171
- .option("--provider <id>", "Provider instance ID")
172
- .option("--sandbox <id>", "Sandbox instance ID")
173
- .option("--mentions <policy>", "Mention policy: required|optional")
174
- .action(async (routeId: string, opts) => {
175
- if (
176
- typeof opts.mentions === "string"
177
- && opts.mentions !== "required"
178
- && opts.mentions !== "optional"
179
- ) {
180
- throw new Error("--mentions must be required or optional");
181
- }
182
-
183
- await runRouteSetCommand({
184
- routeId,
185
- ...(typeof opts.projectRoot === "string" ? { projectRoot: opts.projectRoot as string } : {}),
186
- ...(typeof opts.tools === "string" ? { tools: opts.tools as string } : {}),
187
- ...(typeof opts.provider === "string" ? { providerId: opts.provider as string } : {}),
188
- ...(typeof opts.sandbox === "string" ? { sandboxId: opts.sandbox as string } : {}),
189
- ...(typeof opts.mentions === "string" ? { mentions: opts.mentions as "required" | "optional" } : {}),
190
- });
191
- });
192
-
193
- routeCommand
194
- .command("remove")
195
- .description("Remove one route")
196
- .argument("<routeId>", "Route ID")
197
- .option("--cascade-bindings", "Remove bindings that reference this route", false)
198
- .action(async (routeId: string, opts) => {
199
- await runRouteRemoveCommand({
200
- routeId,
201
- cascadeBindings: Boolean(opts.cascadeBindings),
202
- });
203
- });
204
-
205
- const configCommand = program.command("config").description("Inspect and edit config");
206
-
207
- configCommand
208
- .command("show")
209
- .description("Show full config or one section")
210
- .argument("[section]", "Section: providers|connectors|routes|bindings|sandboxes|data|extensions")
211
- .option("--json", "Output JSON", false)
212
- .action(async (section: string | undefined, opts) => {
213
- await runConfigShowCommand({
214
- ...(typeof section === "string" ? { section } : {}),
215
- json: Boolean(opts.json),
216
- });
217
- });
218
-
219
- configCommand
220
- .command("list")
221
- .description("List config keys with type and preview")
222
- .argument("[section]", "Section: providers|connectors|routes|bindings|sandboxes|data|extensions")
223
- .option("--json", "Output JSON", false)
224
- .action(async (section: string | undefined, opts) => {
225
- await runConfigListCommand({
226
- ...(typeof section === "string" ? { section } : {}),
227
- json: Boolean(opts.json),
228
- });
229
- });
230
-
231
- configCommand
232
- .command("edit")
233
- .description("Interactive edit for high-frequency sections")
234
- .option(
235
- "--section <section>",
236
- "Edit section (repeatable): provider|connector|route|binding",
237
- (value: string, previous: string[]) => [...previous, value],
238
- [] as string[],
239
- )
240
- .action(async (opts) => {
241
- await runConfigEditCommand({
242
- sections: opts.section as string[],
243
- });
244
- });
245
-
246
- const configSchemaCommand = configCommand.command("schema").description("Inspect extension config schemas");
247
-
248
- configSchemaCommand
249
- .command("list")
250
- .description("List loaded contributions and schema availability")
251
- .option("--json", "Output JSON", false)
252
- .action(async (opts) => {
253
- await runConfigSchemaListCommand({
254
- json: Boolean(opts.json),
255
- });
256
- });
257
-
258
- configSchemaCommand
259
- .command("show")
260
- .description("Show one contribution config schema")
261
- .argument("<contributionId>", "Contribution ID")
262
- .option("--json", "Output JSON", false)
263
- .action(async (contributionId: string, opts) => {
264
- await runConfigSchemaShowCommand({
265
- contributionId,
266
- json: Boolean(opts.json),
267
- });
268
- });
269
-
270
- const extensionCommand = program.command("extension").description("Manage extensions");
271
-
272
- extensionCommand
273
- .command("install")
274
- .description("Install extension package")
275
- .argument("<packageSpec>", "npm package spec")
276
- .option("--enable", "Enable extension in config after install", false)
277
- .option("--json", "Output JSON", false)
278
- .action(async (packageSpec: string, opts) => {
279
- await runExtensionInstallCommand({
280
- spec: packageSpec,
281
- enable: Boolean(opts.enable),
282
- json: Boolean(opts.json),
283
- });
284
- });
285
-
286
- extensionCommand
287
- .command("uninstall")
288
- .description("Uninstall extension package")
289
- .argument("<packageName>", "Package name")
290
- .action(async (packageName: string) => {
291
- await runExtensionUninstallCommand({
292
- packageName,
293
- });
294
- });
295
-
296
- extensionCommand
297
- .command("list")
298
- .description("List installed extension packages")
299
- .option("--json", "Output JSON", false)
300
- .action(async (opts) => {
301
- await runExtensionListCommand({
302
- json: Boolean(opts.json),
303
- });
304
- });
305
-
306
- program
307
- .command("doctor")
308
- .description("Validate configuration and common runtime risks")
309
- .option("--fix", "Apply conservative fixes", false)
310
- .action(async (opts) => {
311
- await runDoctorCommand({
312
- fix: Boolean(opts.fix),
313
- });
314
- });
315
-
316
- const cronCommand = program.command("cron").description("Manage scheduled cron jobs");
317
-
318
- cronCommand
319
- .command("add")
320
- .description("Create one cron job")
321
- .argument("<name>", "Job name")
322
- .requiredOption("--prompt <text>", "Prompt text for each run")
323
- .requiredOption("--connector <id>", "Connector instance ID")
324
- .requiredOption("--route <id>", "Route ID")
325
- .requiredOption("--channel <id>", "Delivery channel/chat ID")
326
- .option("--thread <id>", "Delivery thread ID")
327
- .option("--session-policy <policy>", "Session policy: stateless|shared-session", "stateless")
328
- .option("--at <iso>", "Run once at ISO timestamp")
329
- .option("--every-ms <ms>", "Run at fixed interval in milliseconds")
330
- .option("--cron <expr>", "Cron expression")
331
- .option("--tz <tz>", "Timezone for cron expression")
332
- .option("--cron-config <path>", "Override cron config path")
333
- .action(async (name: string, opts) => {
334
- const parsedEveryMs = typeof opts.everyMs === "string" ? Number(opts.everyMs) : null;
335
- await runCronAddCommand({
336
- name,
337
- prompt: opts.prompt as string,
338
- connectorId: opts.connector as string,
339
- routeId: opts.route as string,
340
- channelId: opts.channel as string,
341
- ...(typeof opts.thread === "string" ? { threadId: opts.thread as string } : {}),
342
- sessionPolicy: opts.sessionPolicy as "stateless" | "shared-session",
343
- ...(typeof opts.at === "string" ? { at: opts.at as string } : {}),
344
- ...(parsedEveryMs !== null && Number.isFinite(parsedEveryMs) ? { everyMs: parsedEveryMs } : {}),
345
- ...(typeof opts.cron === "string" ? { cronExpr: opts.cron as string } : {}),
346
- ...(typeof opts.tz === "string" ? { tz: opts.tz as string } : {}),
347
- ...(typeof opts.cronConfig === "string" ? { cronConfigPath: opts.cronConfig as string } : {}),
348
- });
349
- });
350
-
351
- cronCommand
352
- .command("list")
353
- .description("List cron jobs")
354
- .option("--json", "Output JSON", false)
355
- .option("--cron-config <path>", "Override cron config path")
356
- .action(async (opts) => {
357
- await runCronListCommand({
358
- json: Boolean(opts.json),
359
- ...(typeof opts.cronConfig === "string" ? { cronConfigPath: opts.cronConfig as string } : {}),
360
- });
361
- });
362
-
363
- cronCommand
364
- .command("status")
365
- .description("Show status for all jobs or one job")
366
- .argument("[jobId]", "Cron job ID")
367
- .option("--json", "Output JSON", false)
368
- .option("--cron-config <path>", "Override cron config path")
369
- .action(async (jobId: string | undefined, opts) => {
370
- await runCronStatusCommand({
371
- ...(typeof jobId === "string" ? { jobId } : {}),
372
- json: Boolean(opts.json),
373
- ...(typeof opts.cronConfig === "string" ? { cronConfigPath: opts.cronConfig as string } : {}),
374
- });
375
- });
376
-
377
- cronCommand
378
- .command("run")
379
- .description("Queue one cron job for immediate execution")
380
- .argument("<jobId>", "Cron job ID")
381
- .option("--cron-config <path>", "Override cron config path")
382
- .action(async (jobId: string, opts) => {
383
- await runCronRunCommand({
384
- jobId,
385
- ...(typeof opts.cronConfig === "string" ? { cronConfigPath: opts.cronConfig as string } : {}),
386
- });
387
- });
388
-
389
- cronCommand
390
- .command("update")
391
- .description("Update one cron job")
392
- .argument("<jobId>", "Cron job ID")
393
- .option("--name <name>", "Job name")
394
- .option("--prompt <text>", "Job prompt")
395
- .option("--connector <id>", "Connector instance ID")
396
- .option("--route <id>", "Route ID")
397
- .option("--channel <id>", "Delivery channel/chat ID")
398
- .option("--thread <id>", "Delivery thread ID")
399
- .option("--clear-thread", "Unset delivery thread", false)
400
- .option("--session-policy <policy>", "Session policy: stateless|shared-session")
401
- .option("--at <iso>", "Run once at ISO timestamp")
402
- .option("--every-ms <ms>", "Run at fixed interval in milliseconds")
403
- .option("--cron <expr>", "Cron expression")
404
- .option("--tz <tz>", "Timezone for cron expression")
405
- .option("--cron-config <path>", "Override cron config path")
406
- .action(async (jobId: string, opts) => {
407
- const parsedEveryMs = typeof opts.everyMs === "string" ? Number(opts.everyMs) : null;
408
- await runCronUpdateCommand({
409
- jobId,
410
- ...(typeof opts.name === "string" ? { name: opts.name as string } : {}),
411
- ...(typeof opts.prompt === "string" ? { prompt: opts.prompt as string } : {}),
412
- ...(typeof opts.connector === "string" ? { connectorId: opts.connector as string } : {}),
413
- ...(typeof opts.route === "string" ? { routeId: opts.route as string } : {}),
414
- ...(typeof opts.channel === "string" ? { channelId: opts.channel as string } : {}),
415
- ...(typeof opts.thread === "string" ? { threadId: opts.thread as string } : {}),
416
- clearThread: Boolean(opts.clearThread),
417
- ...(typeof opts.sessionPolicy === "string"
418
- ? { sessionPolicy: opts.sessionPolicy as "stateless" | "shared-session" }
419
- : {}),
420
- ...(typeof opts.at === "string" ? { at: opts.at as string } : {}),
421
- ...(parsedEveryMs !== null && Number.isFinite(parsedEveryMs) ? { everyMs: parsedEveryMs } : {}),
422
- ...(typeof opts.cron === "string" ? { cronExpr: opts.cron as string } : {}),
423
- ...(typeof opts.tz === "string" ? { tz: opts.tz as string } : {}),
424
- ...(typeof opts.cronConfig === "string" ? { cronConfigPath: opts.cronConfig as string } : {}),
425
- });
426
- });
427
-
428
- cronCommand
429
- .command("remove")
430
- .description("Remove one cron job")
431
- .argument("<jobId>", "Cron job ID")
432
- .option("--cron-config <path>", "Override cron config path")
433
- .action(async (jobId: string, opts) => {
434
- await runCronRemoveCommand({
435
- jobId,
436
- ...(typeof opts.cronConfig === "string" ? { cronConfigPath: opts.cronConfig as string } : {}),
437
- });
438
- });
439
-
440
- cronCommand
441
- .command("pause")
442
- .description("Pause one cron job")
443
- .argument("<jobId>", "Cron job ID")
444
- .option("--cron-config <path>", "Override cron config path")
445
- .action(async (jobId: string, opts) => {
446
- await runCronPauseCommand({
447
- jobId,
448
- ...(typeof opts.cronConfig === "string" ? { cronConfigPath: opts.cronConfig as string } : {}),
449
- });
450
- });
451
-
452
- cronCommand
453
- .command("resume")
454
- .description("Resume one cron job")
455
- .argument("<jobId>", "Cron job ID")
456
- .option("--cron-config <path>", "Override cron config path")
457
- .action(async (jobId: string, opts) => {
458
- await runCronResumeCommand({
459
- jobId,
460
- ...(typeof opts.cronConfig === "string" ? { cronConfigPath: opts.cronConfig as string } : {}),
461
- });
462
- });
463
-
464
- return program;
465
- }