@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,228 +0,0 @@
1
- import { Ajv, type ErrorObject, type ValidateFunction } from "ajv";
2
- import { join } from "node:path";
3
- import pino from "pino";
4
- import type { ExtensionKind } from "../../core/types.js";
5
- import { ExtensionLoader } from "../../extension/loader.js";
6
- import { ExtensionRegistry } from "../../extension/registry.js";
7
- import { ensureGatewayConfigShape } from "./config-mutators.js";
8
- import { resolveDataRootDir } from "./config-io.js";
9
- import type { RawExtensionItemConfig, RawGatewayConfig } from "./config-types.js";
10
-
11
- export interface ContributionSchemaCatalogEntry {
12
- contributionId: string;
13
- packageName: string;
14
- kind: ExtensionKind;
15
- configSchema?: Record<string, unknown>;
16
- }
17
-
18
- export interface ContributionSchemaListItem {
19
- contributionId: string;
20
- packageName: string;
21
- kind: ExtensionKind;
22
- hasSchema: boolean;
23
- }
24
-
25
- interface InstanceValidationTask {
26
- section: "providers" | "connectors" | "sandboxes";
27
- instanceId: string;
28
- instance: RawExtensionItemConfig;
29
- }
30
-
31
- function isRecord(value: unknown): value is Record<string, unknown> {
32
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
33
- }
34
-
35
- function decodeJsonPointerSegment(value: string): string {
36
- return value.replaceAll("~1", "/").replaceAll("~0", "~");
37
- }
38
-
39
- function normalizeSchemaForValidation(schema: Record<string, unknown>): Record<string, unknown> {
40
- const cloned = structuredClone(schema);
41
- if (isRecord(cloned) && typeof cloned.$schema === "string") {
42
- delete cloned.$schema;
43
- }
44
- return cloned;
45
- }
46
-
47
- function formatErrorPath(instancePath: string): string {
48
- if (!instancePath) {
49
- return "";
50
- }
51
-
52
- const segments = instancePath
53
- .split("/")
54
- .slice(1)
55
- .map((segment) => decodeJsonPointerSegment(segment))
56
- .filter((segment) => segment.length > 0);
57
-
58
- if (segments.length === 0) {
59
- return "";
60
- }
61
-
62
- let formatted = "";
63
- for (const segment of segments) {
64
- if (/^\d+$/.test(segment)) {
65
- formatted += `[${segment}]`;
66
- continue;
67
- }
68
-
69
- if (/^[a-zA-Z_$][\w$]*$/.test(segment)) {
70
- formatted += `.${segment}`;
71
- continue;
72
- }
73
-
74
- formatted += `['${segment.replaceAll("'", "\\'")}']`;
75
- }
76
-
77
- return formatted;
78
- }
79
-
80
- function buildValidationErrorMessage(
81
- task: InstanceValidationTask,
82
- contributionId: string,
83
- errors: ErrorObject[] | null | undefined,
84
- ): string {
85
- const details = (errors ?? [])
86
- .slice(0, 5)
87
- .map((error) => {
88
- const suffix = formatErrorPath(error.instancePath);
89
- return `${task.section}.items['${task.instanceId}']${suffix}: ${error.message ?? "invalid"}`;
90
- })
91
- .join("; ");
92
-
93
- return (
94
- `Invalid config for instance '${task.instanceId}' (contribution '${contributionId}'). `
95
- + (details.length > 0 ? details : "Schema validation failed.")
96
- );
97
- }
98
-
99
- async function loadRegistryForConfig(
100
- configPath: string,
101
- rawConfig: RawGatewayConfig,
102
- ): Promise<ExtensionRegistry> {
103
- const normalized = ensureGatewayConfigShape(structuredClone(rawConfig));
104
- const rootDir = resolveDataRootDir(configPath, normalized);
105
- const loader = new ExtensionLoader(pino({ name: "dobby.config-schema", level: "silent" }), {
106
- extensionsDir: join(rootDir, "extensions"),
107
- });
108
- const loadedPackages = await loader.loadAllowList(normalized.extensions.allowList);
109
- const registry = new ExtensionRegistry();
110
- registry.registerPackages(loadedPackages);
111
- return registry;
112
- }
113
-
114
- /**
115
- * Loads contribution-level JSON Schema catalog from installed/allow-listed extensions.
116
- */
117
- export async function loadContributionSchemaCatalog(
118
- configPath: string,
119
- rawConfig: RawGatewayConfig,
120
- ): Promise<ContributionSchemaCatalogEntry[]> {
121
- const registry = await loadRegistryForConfig(configPath, rawConfig);
122
- return registry.listContributionSchemas();
123
- }
124
-
125
- /**
126
- * Lists available contribution schemas with lightweight flags for CLI display.
127
- */
128
- export async function listContributionSchemas(
129
- configPath: string,
130
- rawConfig: RawGatewayConfig,
131
- ): Promise<ContributionSchemaListItem[]> {
132
- const catalog = await loadContributionSchemaCatalog(configPath, rawConfig);
133
- return catalog.map((item) => ({
134
- contributionId: item.contributionId,
135
- packageName: item.packageName,
136
- kind: item.kind,
137
- hasSchema: Boolean(item.configSchema),
138
- }));
139
- }
140
-
141
- /**
142
- * Returns one contribution schema entry, or null when not found.
143
- */
144
- export async function getContributionSchema(
145
- configPath: string,
146
- rawConfig: RawGatewayConfig,
147
- contributionId: string,
148
- ): Promise<ContributionSchemaCatalogEntry | null> {
149
- const catalog = await loadContributionSchemaCatalog(configPath, rawConfig);
150
- return catalog.find((item) => item.contributionId === contributionId) ?? null;
151
- }
152
-
153
- /**
154
- * Applies extension config defaults and validates provider/connector/sandbox instance configs with Ajv.
155
- */
156
- export async function applyAndValidateContributionSchemas(
157
- configPath: string,
158
- rawConfig: RawGatewayConfig,
159
- ): Promise<RawGatewayConfig> {
160
- const next = ensureGatewayConfigShape(structuredClone(rawConfig));
161
- const catalog = await loadContributionSchemaCatalog(configPath, next);
162
-
163
- const schemaByContribution = new Map<string, Record<string, unknown>>();
164
- for (const entry of catalog) {
165
- if (!entry.configSchema) {
166
- continue;
167
- }
168
- schemaByContribution.set(entry.contributionId, normalizeSchemaForValidation(entry.configSchema));
169
- }
170
-
171
- const ajv = new Ajv({
172
- allErrors: true,
173
- strict: false,
174
- useDefaults: true,
175
- });
176
- const validators = new Map<string, ValidateFunction>();
177
-
178
- const tasks: InstanceValidationTask[] = [
179
- ...Object.entries(next.providers.items).map(([instanceId, instance]) => ({
180
- section: "providers" as const,
181
- instanceId,
182
- instance,
183
- })),
184
- ...Object.entries(next.connectors.items).map(([instanceId, instance]) => ({
185
- section: "connectors" as const,
186
- instanceId,
187
- instance,
188
- })),
189
- ...Object.entries(next.sandboxes.items).map(([instanceId, instance]) => ({
190
- section: "sandboxes" as const,
191
- instanceId,
192
- instance,
193
- })),
194
- ];
195
-
196
- for (const task of tasks) {
197
- const contributionId = task.instance.type;
198
- const schema = schemaByContribution.get(contributionId);
199
- if (!schema) {
200
- continue;
201
- }
202
-
203
- let validate = validators.get(contributionId);
204
- if (!validate) {
205
- const compiled = ajv.compile(schema) as ValidateFunction;
206
- validators.set(contributionId, compiled);
207
- validate = compiled;
208
- }
209
-
210
- const { type: _type, ...instanceConfig } = task.instance;
211
- const valid = validate(instanceConfig);
212
- if (!valid) {
213
- throw new Error(buildValidationErrorMessage(task, contributionId, validate.errors));
214
- }
215
-
216
- for (const key of Object.keys(task.instance)) {
217
- if (key !== "type") {
218
- delete task.instance[key];
219
- }
220
- }
221
- Object.assign(task.instance, {
222
- type: contributionId,
223
- ...instanceConfig,
224
- });
225
- }
226
-
227
- return next;
228
- }
@@ -1,121 +0,0 @@
1
- export interface RawExtensionPackageConfig {
2
- package: string;
3
- enabled?: boolean;
4
- }
5
-
6
- export interface RawExtensionItemConfig {
7
- type: string;
8
- [key: string]: unknown;
9
- }
10
-
11
- export interface RawRouteDefaults {
12
- provider?: string;
13
- sandbox?: string;
14
- tools?: "full" | "readonly";
15
- mentions?: "required" | "optional";
16
- [key: string]: unknown;
17
- }
18
-
19
- export interface RawRouteProfile {
20
- projectRoot: string;
21
- tools?: "full" | "readonly";
22
- systemPromptFile?: string;
23
- mentions?: "required" | "optional";
24
- provider?: string;
25
- sandbox?: string;
26
- [key: string]: unknown;
27
- }
28
-
29
- export interface RawBindingConfig {
30
- connector: string;
31
- source: {
32
- type: "channel" | "chat";
33
- id: string;
34
- [key: string]: unknown;
35
- };
36
- route: string;
37
- [key: string]: unknown;
38
- }
39
-
40
- export interface RawGatewayConfig {
41
- extensions?: {
42
- allowList?: RawExtensionPackageConfig[];
43
- [key: string]: unknown;
44
- };
45
- providers?: {
46
- default?: string;
47
- items?: Record<string, RawExtensionItemConfig>;
48
- [key: string]: unknown;
49
- };
50
- connectors?: {
51
- items?: Record<string, RawExtensionItemConfig>;
52
- [key: string]: unknown;
53
- };
54
- sandboxes?: {
55
- default?: string;
56
- items?: Record<string, RawExtensionItemConfig>;
57
- [key: string]: unknown;
58
- };
59
- routes?: {
60
- defaults?: RawRouteDefaults;
61
- items?: Record<string, RawRouteProfile>;
62
- [key: string]: unknown;
63
- };
64
- bindings?: {
65
- items?: Record<string, RawBindingConfig>;
66
- [key: string]: unknown;
67
- };
68
- data?: {
69
- rootDir?: string;
70
- dedupTtlMs?: number;
71
- [key: string]: unknown;
72
- };
73
- [key: string]: unknown;
74
- }
75
-
76
- export interface NormalizedGatewayConfig extends RawGatewayConfig {
77
- extensions: {
78
- allowList: RawExtensionPackageConfig[];
79
- [key: string]: unknown;
80
- };
81
- providers: {
82
- default: string;
83
- items: Record<string, RawExtensionItemConfig>;
84
- [key: string]: unknown;
85
- };
86
- connectors: {
87
- items: Record<string, RawExtensionItemConfig>;
88
- [key: string]: unknown;
89
- };
90
- sandboxes: {
91
- default: string;
92
- items: Record<string, RawExtensionItemConfig>;
93
- [key: string]: unknown;
94
- };
95
- routes: {
96
- defaults: RawRouteDefaults;
97
- items: Record<string, RawRouteProfile>;
98
- [key: string]: unknown;
99
- };
100
- bindings: {
101
- items: Record<string, RawBindingConfig>;
102
- [key: string]: unknown;
103
- };
104
- data: {
105
- rootDir: string;
106
- dedupTtlMs: number;
107
- [key: string]: unknown;
108
- };
109
- }
110
-
111
- export interface ContributionInstanceTemplate {
112
- id: string;
113
- type: string;
114
- config: Record<string, unknown>;
115
- }
116
-
117
- export interface ContributionTemplatesByKind {
118
- providers: ContributionInstanceTemplate[];
119
- connectors: ContributionInstanceTemplate[];
120
- sandboxes: ContributionInstanceTemplate[];
121
- }