@dobby.ai/dobby 0.1.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.
- package/.env.example +9 -0
- package/AGENTS.md +267 -0
- package/README.md +382 -0
- package/ROADMAP.md +34 -0
- package/config/cron.example.json +9 -0
- package/config/gateway.example.json +128 -0
- package/config/models.custom.example.json +27 -0
- package/dist/src/agent/event-forwarder.js +341 -0
- package/dist/src/agent/tests/event-forwarder.test.js +113 -0
- package/dist/src/cli/commands/config.js +243 -0
- package/dist/src/cli/commands/configure.js +61 -0
- package/dist/src/cli/commands/cron.js +288 -0
- package/dist/src/cli/commands/doctor.js +189 -0
- package/dist/src/cli/commands/extension.js +151 -0
- package/dist/src/cli/commands/init.js +286 -0
- package/dist/src/cli/commands/start.js +177 -0
- package/dist/src/cli/commands/topology.js +254 -0
- package/dist/src/cli/index.js +8 -0
- package/dist/src/cli/program.js +386 -0
- package/dist/src/cli/shared/config-io.js +223 -0
- package/dist/src/cli/shared/config-mutators.js +345 -0
- package/dist/src/cli/shared/config-path.js +207 -0
- package/dist/src/cli/shared/config-schema.js +159 -0
- package/dist/src/cli/shared/config-types.js +1 -0
- package/dist/src/cli/shared/configure-sections.js +429 -0
- package/dist/src/cli/shared/discord-config.js +12 -0
- package/dist/src/cli/shared/init-catalog.js +115 -0
- package/dist/src/cli/shared/init-models-file.js +65 -0
- package/dist/src/cli/shared/presets.js +86 -0
- package/dist/src/cli/shared/runtime.js +29 -0
- package/dist/src/cli/shared/schema-prompts.js +325 -0
- package/dist/src/cli/tests/config-command.test.js +42 -0
- package/dist/src/cli/tests/config-io.test.js +64 -0
- package/dist/src/cli/tests/config-mutators.test.js +47 -0
- package/dist/src/cli/tests/config-path.test.js +21 -0
- package/dist/src/cli/tests/discord-config.test.js +23 -0
- package/dist/src/cli/tests/doctor.test.js +107 -0
- package/dist/src/cli/tests/init-catalog.test.js +87 -0
- package/dist/src/cli/tests/presets.test.js +41 -0
- package/dist/src/cli/tests/program-options.test.js +92 -0
- package/dist/src/cli/tests/routing-config.test.js +199 -0
- package/dist/src/cli/tests/routing-legacy.test.js +191 -0
- package/dist/src/core/control-command.js +12 -0
- package/dist/src/core/dedup-store.js +92 -0
- package/dist/src/core/gateway.js +432 -0
- package/dist/src/core/routing.js +306 -0
- package/dist/src/core/runtime-registry.js +119 -0
- package/dist/src/core/tests/control-command.test.js +17 -0
- package/dist/src/core/tests/gateway-update-strategy.test.js +167 -0
- package/dist/src/core/tests/runtime-registry.test.js +116 -0
- package/dist/src/core/tests/typing-controller.test.js +103 -0
- package/dist/src/core/types.js +1 -0
- package/dist/src/core/typing-controller.js +88 -0
- package/dist/src/cron/config.js +114 -0
- package/dist/src/cron/schedule.js +49 -0
- package/dist/src/cron/service.js +196 -0
- package/dist/src/cron/store.js +142 -0
- package/dist/src/cron/types.js +1 -0
- package/dist/src/extension/loader.js +97 -0
- package/dist/src/extension/manager.js +269 -0
- package/dist/src/extension/manifest.js +21 -0
- package/dist/src/extension/registry.js +137 -0
- package/dist/src/main.js +6 -0
- package/dist/src/sandbox/executor.js +1 -0
- package/dist/src/sandbox/host-executor.js +111 -0
- package/docs/BOXLITE_SANDBOX_FEASIBILITY.md +175 -0
- package/docs/CRON_SCHEDULER_DESIGN.md +374 -0
- package/docs/DOCKER_SANDBOX_vs_BOXLITE.md +77 -0
- package/docs/EXTENSION_SYSTEM_ARCHITECTURE.md +119 -0
- package/docs/MVP.md +135 -0
- package/docs/RUNBOOK.md +242 -0
- package/docs/TEAMWORK_HANDOFF_DESIGN.md +440 -0
- package/package.json +43 -0
- package/plugins/connector-discord/dobby.manifest.json +18 -0
- package/plugins/connector-discord/index.js +1 -0
- package/plugins/connector-discord/package-lock.json +360 -0
- package/plugins/connector-discord/package.json +38 -0
- package/plugins/connector-discord/src/connector.ts +350 -0
- package/plugins/connector-discord/src/contribution.ts +21 -0
- package/plugins/connector-discord/src/mapper.ts +102 -0
- package/plugins/connector-discord/tsconfig.json +19 -0
- package/plugins/connector-feishu/dobby.manifest.json +18 -0
- package/plugins/connector-feishu/index.js +1 -0
- package/plugins/connector-feishu/package-lock.json +618 -0
- package/plugins/connector-feishu/package.json +38 -0
- package/plugins/connector-feishu/src/connector.ts +343 -0
- package/plugins/connector-feishu/src/contribution.ts +26 -0
- package/plugins/connector-feishu/src/mapper.ts +401 -0
- package/plugins/connector-feishu/tsconfig.json +19 -0
- package/plugins/plugin-sdk/index.d.ts +261 -0
- package/plugins/plugin-sdk/index.js +1 -0
- package/plugins/plugin-sdk/package-lock.json +12 -0
- package/plugins/plugin-sdk/package.json +22 -0
- package/plugins/provider-claude/dobby.manifest.json +17 -0
- package/plugins/provider-claude/index.js +1 -0
- package/plugins/provider-claude/package-lock.json +3398 -0
- package/plugins/provider-claude/package.json +39 -0
- package/plugins/provider-claude/src/contribution.ts +1018 -0
- package/plugins/provider-claude/tsconfig.json +19 -0
- package/plugins/provider-claude-cli/dobby.manifest.json +17 -0
- package/plugins/provider-claude-cli/index.js +1 -0
- package/plugins/provider-claude-cli/package-lock.json +2898 -0
- package/plugins/provider-claude-cli/package.json +38 -0
- package/plugins/provider-claude-cli/src/contribution.ts +1673 -0
- package/plugins/provider-claude-cli/tsconfig.json +19 -0
- package/plugins/provider-pi/dobby.manifest.json +17 -0
- package/plugins/provider-pi/index.js +1 -0
- package/plugins/provider-pi/package-lock.json +3877 -0
- package/plugins/provider-pi/package.json +40 -0
- package/plugins/provider-pi/src/contribution.ts +476 -0
- package/plugins/provider-pi/tsconfig.json +19 -0
- package/plugins/sandbox-core/boxlite.js +1 -0
- package/plugins/sandbox-core/dobby.manifest.json +17 -0
- package/plugins/sandbox-core/docker.js +1 -0
- package/plugins/sandbox-core/package-lock.json +136 -0
- package/plugins/sandbox-core/package.json +39 -0
- package/plugins/sandbox-core/src/boxlite-context.ts +2 -0
- package/plugins/sandbox-core/src/boxlite-contribution.ts +53 -0
- package/plugins/sandbox-core/src/boxlite-executor.ts +911 -0
- package/plugins/sandbox-core/src/docker-contribution.ts +43 -0
- package/plugins/sandbox-core/src/docker-executor.ts +217 -0
- package/plugins/sandbox-core/tsconfig.json +19 -0
- package/scripts/local-extensions.mjs +168 -0
- package/src/agent/event-forwarder.ts +414 -0
- package/src/cli/commands/config.ts +328 -0
- package/src/cli/commands/configure.ts +92 -0
- package/src/cli/commands/cron.ts +410 -0
- package/src/cli/commands/doctor.ts +230 -0
- package/src/cli/commands/extension.ts +205 -0
- package/src/cli/commands/init.ts +396 -0
- package/src/cli/commands/start.ts +223 -0
- package/src/cli/commands/topology.ts +383 -0
- package/src/cli/index.ts +9 -0
- package/src/cli/program.ts +465 -0
- package/src/cli/shared/config-io.ts +277 -0
- package/src/cli/shared/config-mutators.ts +440 -0
- package/src/cli/shared/config-schema.ts +228 -0
- package/src/cli/shared/config-types.ts +121 -0
- package/src/cli/shared/configure-sections.ts +551 -0
- package/src/cli/shared/discord-config.ts +14 -0
- package/src/cli/shared/init-catalog.ts +189 -0
- package/src/cli/shared/init-models-file.ts +77 -0
- package/src/cli/shared/runtime.ts +33 -0
- package/src/cli/shared/schema-prompts.ts +414 -0
- package/src/cli/tests/config-command.test.ts +56 -0
- package/src/cli/tests/config-io.test.ts +92 -0
- package/src/cli/tests/config-mutators.test.ts +59 -0
- package/src/cli/tests/doctor.test.ts +120 -0
- package/src/cli/tests/init-catalog.test.ts +96 -0
- package/src/cli/tests/program-options.test.ts +113 -0
- package/src/cli/tests/routing-config.test.ts +209 -0
- package/src/core/control-command.ts +12 -0
- package/src/core/dedup-store.ts +103 -0
- package/src/core/gateway.ts +607 -0
- package/src/core/routing.ts +379 -0
- package/src/core/runtime-registry.ts +141 -0
- package/src/core/tests/control-command.test.ts +20 -0
- package/src/core/tests/runtime-registry.test.ts +140 -0
- package/src/core/tests/typing-controller.test.ts +129 -0
- package/src/core/types.ts +318 -0
- package/src/core/typing-controller.ts +119 -0
- package/src/cron/config.ts +154 -0
- package/src/cron/schedule.ts +61 -0
- package/src/cron/service.ts +249 -0
- package/src/cron/store.ts +155 -0
- package/src/cron/types.ts +60 -0
- package/src/extension/loader.ts +145 -0
- package/src/extension/manager.ts +355 -0
- package/src/extension/manifest.ts +26 -0
- package/src/extension/registry.ts +229 -0
- package/src/main.ts +8 -0
- package/src/sandbox/executor.ts +44 -0
- package/src/sandbox/host-executor.ts +118 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,465 @@
|
|
|
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
|
+
}
|