@dobby.ai/dobby 0.1.1 → 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 (136) hide show
  1. package/README.md +20 -7
  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/program.js +0 -6
  5. package/dist/src/core/types.js +2 -0
  6. package/dist/src/cron/config.js +2 -2
  7. package/dist/src/cron/service.js +87 -23
  8. package/dist/src/cron/store.js +1 -1
  9. package/package.json +9 -3
  10. package/.env.example +0 -8
  11. package/AGENTS.md +0 -267
  12. package/ROADMAP.md +0 -34
  13. package/config/cron.example.json +0 -9
  14. package/config/gateway.example.json +0 -132
  15. package/dist/plugins/connector-discord/src/mapper.js +0 -75
  16. package/dist/src/cli/tests/config-command.test.js +0 -42
  17. package/dist/src/cli/tests/config-io.test.js +0 -64
  18. package/dist/src/cli/tests/config-mutators.test.js +0 -47
  19. package/dist/src/cli/tests/discord-mapper.test.js +0 -90
  20. package/dist/src/cli/tests/doctor.test.js +0 -252
  21. package/dist/src/cli/tests/init-catalog.test.js +0 -134
  22. package/dist/src/cli/tests/program-options.test.js +0 -78
  23. package/dist/src/cli/tests/routing-config.test.js +0 -254
  24. package/dist/src/core/tests/control-command.test.js +0 -17
  25. package/dist/src/core/tests/runtime-registry.test.js +0 -116
  26. package/dist/src/core/tests/typing-controller.test.js +0 -103
  27. package/docs/BOXLITE_SANDBOX_FEASIBILITY.md +0 -175
  28. package/docs/CRON_SCHEDULER_DESIGN.md +0 -374
  29. package/docs/DOCKER_SANDBOX_vs_BOXLITE.md +0 -77
  30. package/docs/EXTENSION_SYSTEM_ARCHITECTURE.md +0 -119
  31. package/docs/MVP.md +0 -135
  32. package/docs/RUNBOOK.md +0 -243
  33. package/docs/TEAMWORK_HANDOFF_DESIGN.md +0 -440
  34. package/plugins/connector-discord/dobby.manifest.json +0 -18
  35. package/plugins/connector-discord/index.js +0 -1
  36. package/plugins/connector-discord/package-lock.json +0 -360
  37. package/plugins/connector-discord/package.json +0 -38
  38. package/plugins/connector-discord/src/connector.ts +0 -345
  39. package/plugins/connector-discord/src/contribution.ts +0 -21
  40. package/plugins/connector-discord/src/mapper.ts +0 -101
  41. package/plugins/connector-discord/tsconfig.json +0 -19
  42. package/plugins/connector-feishu/dobby.manifest.json +0 -18
  43. package/plugins/connector-feishu/index.js +0 -1
  44. package/plugins/connector-feishu/package-lock.json +0 -618
  45. package/plugins/connector-feishu/package.json +0 -38
  46. package/plugins/connector-feishu/src/connector.ts +0 -343
  47. package/plugins/connector-feishu/src/contribution.ts +0 -26
  48. package/plugins/connector-feishu/src/mapper.ts +0 -401
  49. package/plugins/connector-feishu/tsconfig.json +0 -19
  50. package/plugins/plugin-sdk/index.d.ts +0 -261
  51. package/plugins/plugin-sdk/index.js +0 -1
  52. package/plugins/plugin-sdk/package-lock.json +0 -12
  53. package/plugins/plugin-sdk/package.json +0 -22
  54. package/plugins/provider-claude/dobby.manifest.json +0 -17
  55. package/plugins/provider-claude/index.js +0 -1
  56. package/plugins/provider-claude/package-lock.json +0 -3398
  57. package/plugins/provider-claude/package.json +0 -39
  58. package/plugins/provider-claude/src/contribution.ts +0 -1018
  59. package/plugins/provider-claude/tsconfig.json +0 -19
  60. package/plugins/provider-claude-cli/dobby.manifest.json +0 -17
  61. package/plugins/provider-claude-cli/index.js +0 -1
  62. package/plugins/provider-claude-cli/package-lock.json +0 -2898
  63. package/plugins/provider-claude-cli/package.json +0 -38
  64. package/plugins/provider-claude-cli/src/contribution.ts +0 -1673
  65. package/plugins/provider-claude-cli/tsconfig.json +0 -19
  66. package/plugins/provider-pi/dobby.manifest.json +0 -17
  67. package/plugins/provider-pi/index.js +0 -1
  68. package/plugins/provider-pi/package-lock.json +0 -3877
  69. package/plugins/provider-pi/package.json +0 -40
  70. package/plugins/provider-pi/src/contribution.ts +0 -606
  71. package/plugins/provider-pi/tsconfig.json +0 -19
  72. package/plugins/sandbox-core/boxlite.js +0 -1
  73. package/plugins/sandbox-core/dobby.manifest.json +0 -17
  74. package/plugins/sandbox-core/docker.js +0 -1
  75. package/plugins/sandbox-core/package-lock.json +0 -136
  76. package/plugins/sandbox-core/package.json +0 -39
  77. package/plugins/sandbox-core/src/boxlite-context.ts +0 -2
  78. package/plugins/sandbox-core/src/boxlite-contribution.ts +0 -53
  79. package/plugins/sandbox-core/src/boxlite-executor.ts +0 -911
  80. package/plugins/sandbox-core/src/docker-contribution.ts +0 -43
  81. package/plugins/sandbox-core/src/docker-executor.ts +0 -217
  82. package/plugins/sandbox-core/tsconfig.json +0 -19
  83. package/scripts/local-extensions.mjs +0 -168
  84. package/src/agent/event-forwarder.ts +0 -414
  85. package/src/cli/commands/config.ts +0 -328
  86. package/src/cli/commands/configure.ts +0 -92
  87. package/src/cli/commands/cron.ts +0 -410
  88. package/src/cli/commands/doctor.ts +0 -331
  89. package/src/cli/commands/extension.ts +0 -207
  90. package/src/cli/commands/init.ts +0 -211
  91. package/src/cli/commands/start.ts +0 -223
  92. package/src/cli/commands/topology.ts +0 -415
  93. package/src/cli/index.ts +0 -9
  94. package/src/cli/program.ts +0 -314
  95. package/src/cli/shared/config-io.ts +0 -245
  96. package/src/cli/shared/config-mutators.ts +0 -470
  97. package/src/cli/shared/config-schema.ts +0 -228
  98. package/src/cli/shared/config-types.ts +0 -129
  99. package/src/cli/shared/configure-sections.ts +0 -595
  100. package/src/cli/shared/discord-config.ts +0 -14
  101. package/src/cli/shared/init-catalog.ts +0 -249
  102. package/src/cli/shared/local-extension-specs.ts +0 -108
  103. package/src/cli/shared/runtime.ts +0 -33
  104. package/src/cli/shared/schema-prompts.ts +0 -443
  105. package/src/cli/tests/config-command.test.ts +0 -56
  106. package/src/cli/tests/config-io.test.ts +0 -92
  107. package/src/cli/tests/config-mutators.test.ts +0 -59
  108. package/src/cli/tests/discord-mapper.test.ts +0 -128
  109. package/src/cli/tests/doctor.test.ts +0 -269
  110. package/src/cli/tests/init-catalog.test.ts +0 -144
  111. package/src/cli/tests/program-options.test.ts +0 -95
  112. package/src/cli/tests/routing-config.test.ts +0 -281
  113. package/src/core/control-command.ts +0 -12
  114. package/src/core/dedup-store.ts +0 -103
  115. package/src/core/gateway.ts +0 -609
  116. package/src/core/routing.ts +0 -404
  117. package/src/core/runtime-registry.ts +0 -141
  118. package/src/core/tests/control-command.test.ts +0 -20
  119. package/src/core/tests/runtime-registry.test.ts +0 -140
  120. package/src/core/tests/typing-controller.test.ts +0 -129
  121. package/src/core/types.ts +0 -324
  122. package/src/core/typing-controller.ts +0 -119
  123. package/src/cron/config.ts +0 -154
  124. package/src/cron/schedule.ts +0 -61
  125. package/src/cron/service.ts +0 -249
  126. package/src/cron/store.ts +0 -155
  127. package/src/cron/types.ts +0 -60
  128. package/src/extension/loader.ts +0 -145
  129. package/src/extension/manager.ts +0 -355
  130. package/src/extension/manifest.ts +0 -26
  131. package/src/extension/registry.ts +0 -229
  132. package/src/main.ts +0 -8
  133. package/src/sandbox/executor.ts +0 -44
  134. package/src/sandbox/host-executor.ts +0 -118
  135. package/src/shared/dobby-repo.ts +0 -48
  136. package/tsconfig.json +0 -18
@@ -1,415 +0,0 @@
1
- import { BUILTIN_HOST_SANDBOX_ID } from "../../core/types.js";
2
- import {
3
- ensureGatewayConfigShape,
4
- upsertBinding,
5
- upsertRoute,
6
- } from "../shared/config-mutators.js";
7
- import { DISCORD_CONNECTOR_CONTRIBUTION_ID } from "../shared/discord-config.js";
8
- import { requireRawConfig, resolveConfigPath, writeConfigWithValidation } from "../shared/config-io.js";
9
- import type { RawBindingConfig, RawGatewayConfig } from "../shared/config-types.js";
10
-
11
- interface DiscordConnectorView {
12
- connectorId: string;
13
- type: string;
14
- botName: string;
15
- hasToken: boolean;
16
- }
17
-
18
- interface BindingView {
19
- bindingId: string;
20
- connectorId: string;
21
- sourceType: string;
22
- sourceId: string;
23
- routeId: string;
24
- routeExists: boolean;
25
- projectRoot?: string;
26
- }
27
-
28
- interface RouteView {
29
- routeId: string;
30
- projectRoot: string;
31
- tools: "full" | "readonly";
32
- mentions: "required" | "optional";
33
- provider?: string;
34
- sandbox?: string;
35
- bindings: number;
36
- }
37
-
38
- function effectiveRouteProjectRoot(
39
- normalized: ReturnType<typeof ensureGatewayConfigShape>,
40
- routeId: string,
41
- ): string | undefined {
42
- const route = normalized.routes.items[routeId];
43
- if (!route) {
44
- return undefined;
45
- }
46
-
47
- return route.projectRoot ?? normalized.routes.default.projectRoot;
48
- }
49
-
50
- function listDiscordConnectors(rawConfig: unknown): DiscordConnectorView[] {
51
- const normalized = ensureGatewayConfigShape(rawConfig as RawGatewayConfig);
52
- const items: DiscordConnectorView[] = [];
53
-
54
- for (const [connectorId, connector] of Object.entries(normalized.connectors.items)) {
55
- if (connector.type !== DISCORD_CONNECTOR_CONTRIBUTION_ID) {
56
- continue;
57
- }
58
-
59
- const botName = typeof connector.botName === "string" ? connector.botName : "";
60
- const botToken = typeof connector.botToken === "string" ? connector.botToken.trim() : "";
61
- items.push({
62
- connectorId,
63
- type: connector.type,
64
- botName,
65
- hasToken: botToken.length > 0,
66
- });
67
- }
68
-
69
- return items.sort((a, b) => a.connectorId.localeCompare(b.connectorId));
70
- }
71
-
72
- function getDiscordConnectorOrThrow(
73
- rawConfig: unknown,
74
- connectorId: string,
75
- ): {
76
- normalized: ReturnType<typeof ensureGatewayConfigShape>;
77
- connector: Record<string, unknown> & { type: string };
78
- } {
79
- const normalized = ensureGatewayConfigShape(rawConfig as RawGatewayConfig);
80
- const connector = normalized.connectors.items[connectorId];
81
- if (!connector) {
82
- throw new Error(`Connector instance '${connectorId}' not found`);
83
- }
84
- if (connector.type !== DISCORD_CONNECTOR_CONTRIBUTION_ID) {
85
- throw new Error(
86
- `Connector '${connectorId}' uses contribution '${connector.type}'. This command currently supports only '${DISCORD_CONNECTOR_CONTRIBUTION_ID}'.`,
87
- );
88
- }
89
- return {
90
- normalized,
91
- connector,
92
- };
93
- }
94
-
95
- function listBindings(rawConfig: unknown, connectorFilter?: string): BindingView[] {
96
- const normalized = ensureGatewayConfigShape(rawConfig as RawGatewayConfig);
97
- const bindings: BindingView[] = Object.entries(normalized.bindings.items)
98
- .filter(([, binding]) => !connectorFilter || binding.connector === connectorFilter)
99
- .map(([bindingId, binding]) => {
100
- const route = normalized.routes.items[binding.route];
101
- const projectRoot = route ? effectiveRouteProjectRoot(normalized, binding.route) : undefined;
102
- return {
103
- bindingId,
104
- connectorId: binding.connector,
105
- sourceType: binding.source.type,
106
- sourceId: binding.source.id,
107
- routeId: binding.route,
108
- routeExists: Boolean(route),
109
- ...(projectRoot ? { projectRoot } : {}),
110
- };
111
- });
112
-
113
- if (!connectorFilter && normalized.bindings.default) {
114
- const projectRoot = effectiveRouteProjectRoot(normalized, normalized.bindings.default.route);
115
- bindings.push({
116
- bindingId: "bindings.default",
117
- connectorId: "*",
118
- sourceType: "direct_message",
119
- sourceId: "*",
120
- routeId: normalized.bindings.default.route,
121
- routeExists: Boolean(normalized.routes.items[normalized.bindings.default.route]),
122
- ...(projectRoot ? { projectRoot } : {}),
123
- });
124
- }
125
-
126
- return bindings.sort((a, b) => a.bindingId.localeCompare(b.bindingId));
127
- }
128
-
129
- function buildRouteBindingCounts(rawConfig: unknown): Map<string, number> {
130
- const normalized = ensureGatewayConfigShape(rawConfig as RawGatewayConfig);
131
- const counts = new Map<string, number>();
132
- for (const binding of listBindings(normalized)) {
133
- counts.set(binding.routeId, (counts.get(binding.routeId) ?? 0) + 1);
134
- }
135
- return counts;
136
- }
137
-
138
- function listRoutes(rawConfig: unknown): RouteView[] {
139
- const normalized = ensureGatewayConfigShape(rawConfig as RawGatewayConfig);
140
- const counts = buildRouteBindingCounts(normalized);
141
-
142
- return Object.entries(normalized.routes.items)
143
- .map(([routeId, route]): RouteView => ({
144
- routeId,
145
- projectRoot: effectiveRouteProjectRoot(normalized, routeId) ?? "(unset)",
146
- tools: route.tools === "readonly" ? "readonly" : "full",
147
- mentions: route.mentions === "optional" ? "optional" : "required",
148
- ...(route.provider ? { provider: route.provider } : {}),
149
- ...(route.sandbox ? { sandbox: route.sandbox } : {}),
150
- bindings: counts.get(routeId) ?? 0,
151
- }))
152
- .sort((a, b) => a.routeId.localeCompare(b.routeId));
153
- }
154
-
155
- async function saveConfig(configPath: string, normalized: ReturnType<typeof ensureGatewayConfigShape>): Promise<void> {
156
- await writeConfigWithValidation(configPath, normalized, {
157
- validate: true,
158
- createBackup: true,
159
- });
160
- }
161
-
162
- export async function runBotListCommand(options: {
163
- json?: boolean;
164
- }): Promise<void> {
165
- const configPath = resolveConfigPath();
166
- const rawConfig = await requireRawConfig(configPath);
167
- const bots = listDiscordConnectors(rawConfig);
168
-
169
- if (options.json) {
170
- console.log(JSON.stringify({ configPath, bots }, null, 2));
171
- return;
172
- }
173
-
174
- if (bots.length === 0) {
175
- console.log("No Discord connector instances configured.");
176
- return;
177
- }
178
-
179
- console.log(`Bots (${configPath}):`);
180
- for (const bot of bots) {
181
- console.log(
182
- `- ${bot.connectorId}: botName='${bot.botName || "(empty)"}', token=${bot.hasToken ? "set" : "missing"}`,
183
- );
184
- }
185
- }
186
-
187
- export async function runBotSetCommand(options: {
188
- connectorId: string;
189
- name?: string;
190
- token?: string;
191
- }): Promise<void> {
192
- const configPath = resolveConfigPath();
193
- const rawConfig = await requireRawConfig(configPath);
194
- const { normalized, connector } = getDiscordConnectorOrThrow(rawConfig, options.connectorId);
195
-
196
- const nextName = typeof options.name === "string" ? options.name.trim() : undefined;
197
- const nextToken = typeof options.token === "string" ? options.token.trim() : undefined;
198
- if (!nextName && !nextToken) {
199
- throw new Error("At least one of --name or --token must be provided");
200
- }
201
-
202
- normalized.connectors.items[options.connectorId] = {
203
- ...connector,
204
- ...(nextName !== undefined ? { botName: nextName } : {}),
205
- ...(nextToken !== undefined ? { botToken: nextToken } : {}),
206
- };
207
-
208
- await saveConfig(configPath, normalized);
209
- console.log(`Updated bot settings for connector '${options.connectorId}'`);
210
- }
211
-
212
- export async function runBindingListCommand(options: {
213
- connectorId?: string;
214
- json?: boolean;
215
- }): Promise<void> {
216
- const configPath = resolveConfigPath();
217
- const rawConfig = await requireRawConfig(configPath);
218
- const bindings = listBindings(rawConfig, options.connectorId);
219
-
220
- if (options.connectorId) {
221
- const normalized = ensureGatewayConfigShape(rawConfig);
222
- if (!normalized.connectors.items[options.connectorId]) {
223
- throw new Error(`Connector '${options.connectorId}' not found`);
224
- }
225
- }
226
-
227
- if (options.json) {
228
- console.log(JSON.stringify({ configPath, bindings }, null, 2));
229
- return;
230
- }
231
-
232
- if (bindings.length === 0) {
233
- console.log("No bindings configured.");
234
- return;
235
- }
236
-
237
- console.log(`Bindings (${configPath}):`);
238
- for (const binding of bindings) {
239
- const routeSuffix = binding.routeExists ? "" : " [missing route]";
240
- const projectSuffix = binding.projectRoot ? ` (${binding.projectRoot})` : "";
241
- console.log(
242
- `- ${binding.bindingId}: ${binding.connectorId}/${binding.sourceType}:${binding.sourceId} -> ${binding.routeId}${routeSuffix}${projectSuffix}`,
243
- );
244
- }
245
- }
246
-
247
- export async function runBindingSetCommand(options: {
248
- bindingId: string;
249
- connectorId: string;
250
- routeId: string;
251
- sourceType: "channel" | "chat";
252
- sourceId: string;
253
- }): Promise<void> {
254
- const configPath = resolveConfigPath();
255
- const rawConfig = await requireRawConfig(configPath);
256
- const normalized = ensureGatewayConfigShape(structuredClone(rawConfig));
257
-
258
- if (!normalized.connectors.items[options.connectorId]) {
259
- throw new Error(`Connector '${options.connectorId}' does not exist`);
260
- }
261
- if (!normalized.routes.items[options.routeId]) {
262
- throw new Error(`Route '${options.routeId}' does not exist`);
263
- }
264
-
265
- const duplicate = Object.entries(normalized.bindings.items).find(([bindingId, binding]) =>
266
- bindingId !== options.bindingId
267
- && binding.connector === options.connectorId
268
- && binding.source.type === options.sourceType
269
- && binding.source.id === options.sourceId
270
- );
271
- if (duplicate) {
272
- throw new Error(
273
- `Binding source '${options.connectorId}/${options.sourceType}:${options.sourceId}' is already used by '${duplicate[0]}'`,
274
- );
275
- }
276
-
277
- const binding: RawBindingConfig = {
278
- connector: options.connectorId,
279
- source: {
280
- type: options.sourceType,
281
- id: options.sourceId,
282
- },
283
- route: options.routeId,
284
- };
285
- upsertBinding(normalized, options.bindingId, binding);
286
-
287
- await saveConfig(configPath, normalized);
288
- console.log(`Upserted binding '${options.bindingId}'`);
289
- }
290
-
291
- export async function runBindingRemoveCommand(options: {
292
- bindingId: string;
293
- }): Promise<void> {
294
- const configPath = resolveConfigPath();
295
- const rawConfig = await requireRawConfig(configPath);
296
- const normalized = ensureGatewayConfigShape(structuredClone(rawConfig));
297
-
298
- if (!normalized.bindings.items[options.bindingId]) {
299
- throw new Error(`Binding '${options.bindingId}' not found`);
300
- }
301
-
302
- delete normalized.bindings.items[options.bindingId];
303
- await saveConfig(configPath, normalized);
304
- console.log(`Removed binding '${options.bindingId}'`);
305
- }
306
-
307
- export async function runRouteListCommand(options: {
308
- json?: boolean;
309
- }): Promise<void> {
310
- const configPath = resolveConfigPath();
311
- const rawConfig = await requireRawConfig(configPath);
312
- const routes = listRoutes(rawConfig);
313
-
314
- if (options.json) {
315
- console.log(JSON.stringify({ configPath, routes }, null, 2));
316
- return;
317
- }
318
-
319
- if (routes.length === 0) {
320
- console.log("No routes configured.");
321
- return;
322
- }
323
-
324
- console.log(`Routes (${configPath}):`);
325
- for (const route of routes) {
326
- const providerInfo = route.provider ? route.provider : "(route default)";
327
- const sandboxInfo = route.sandbox ? route.sandbox : BUILTIN_HOST_SANDBOX_ID;
328
- console.log(
329
- `- ${route.routeId}: ${route.projectRoot}, tools=${route.tools}, mentions=${route.mentions}, provider=${providerInfo}, sandbox=${sandboxInfo}, bindings=${route.bindings}`,
330
- );
331
- }
332
- }
333
-
334
- export async function runRouteSetCommand(options: {
335
- routeId: string;
336
- projectRoot?: string;
337
- tools?: string;
338
- providerId?: string;
339
- sandboxId?: string;
340
- mentions?: "required" | "optional";
341
- }): Promise<void> {
342
- const configPath = resolveConfigPath();
343
- const rawConfig = await requireRawConfig(configPath);
344
- const normalized = ensureGatewayConfigShape(structuredClone(rawConfig));
345
- const existing = normalized.routes.items[options.routeId];
346
-
347
- const projectRoot = options.projectRoot?.trim() || existing?.projectRoot;
348
- if (!projectRoot && !normalized.routes.default.projectRoot) {
349
- throw new Error("--project-root is required when creating a new route");
350
- }
351
-
352
- const toolsRaw = options.tools ?? existing?.tools;
353
- if (toolsRaw !== undefined && toolsRaw !== "full" && toolsRaw !== "readonly") {
354
- throw new Error(`Invalid --tools '${toolsRaw}'. Allowed: full, readonly`);
355
- }
356
-
357
- const provider = options.providerId ?? existing?.provider;
358
- if (provider && !normalized.providers.items[provider]) {
359
- throw new Error(`Provider '${provider}' does not exist`);
360
- }
361
-
362
- const sandbox = options.sandboxId ?? existing?.sandbox;
363
- if (sandbox && sandbox !== BUILTIN_HOST_SANDBOX_ID && !normalized.sandboxes.items[sandbox]) {
364
- throw new Error(`Sandbox '${sandbox}' does not exist`);
365
- }
366
-
367
- upsertRoute(normalized, options.routeId, {
368
- ...(projectRoot ? { projectRoot } : {}),
369
- ...(toolsRaw ? { tools: toolsRaw } : {}),
370
- ...((options.mentions ?? existing?.mentions) ? { mentions: (options.mentions ?? existing?.mentions)! } : {}),
371
- ...(provider ? { provider } : {}),
372
- ...(sandbox ? { sandbox } : {}),
373
- ...(typeof existing?.systemPromptFile === "string" ? { systemPromptFile: existing.systemPromptFile } : {}),
374
- });
375
-
376
- await saveConfig(configPath, normalized);
377
- console.log(`Upserted route '${options.routeId}'`);
378
- }
379
-
380
- export async function runRouteRemoveCommand(options: {
381
- routeId: string;
382
- cascadeBindings?: boolean;
383
- }): Promise<void> {
384
- const configPath = resolveConfigPath();
385
- const rawConfig = await requireRawConfig(configPath);
386
- const normalized = ensureGatewayConfigShape(structuredClone(rawConfig));
387
-
388
- if (!normalized.routes.items[options.routeId]) {
389
- throw new Error(`Route '${options.routeId}' not found`);
390
- }
391
-
392
- const bindingRefs = listBindings(normalized).filter(
393
- (binding) => binding.routeId === options.routeId && binding.bindingId !== "bindings.default",
394
- );
395
- const hasDefaultBindingRef = normalized.bindings.default?.route === options.routeId;
396
- if ((bindingRefs.length > 0 || hasDefaultBindingRef) && !options.cascadeBindings) {
397
- const refList = bindingRefs.map((binding) => binding.bindingId).join(", ");
398
- throw new Error(
399
- `Route '${options.routeId}' is referenced by bindings (${[refList, hasDefaultBindingRef ? "bindings.default" : ""].filter(Boolean).join(", ")}). Re-run with --cascade-bindings to remove these bindings automatically.`,
400
- );
401
- }
402
-
403
- if (options.cascadeBindings) {
404
- for (const binding of bindingRefs) {
405
- delete normalized.bindings.items[binding.bindingId];
406
- }
407
- if (hasDefaultBindingRef) {
408
- delete normalized.bindings.default;
409
- }
410
- }
411
-
412
- delete normalized.routes.items[options.routeId];
413
- await saveConfig(configPath, normalized);
414
- console.log(`Removed route '${options.routeId}'`);
415
- }
package/src/cli/index.ts DELETED
@@ -1,9 +0,0 @@
1
- import { buildProgram } from "./program.js";
2
-
3
- /**
4
- * Runs the CLI entrypoint with the provided argv vector.
5
- */
6
- export async function runCli(argv = process.argv): Promise<void> {
7
- const program = buildProgram();
8
- await program.parseAsync(argv);
9
- }