@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.
- package/README.md +20 -7
- package/dist/src/agent/event-forwarder.js +185 -16
- package/dist/src/cli/commands/cron.js +39 -35
- package/dist/src/cli/program.js +0 -6
- package/dist/src/core/types.js +2 -0
- package/dist/src/cron/config.js +2 -2
- package/dist/src/cron/service.js +87 -23
- package/dist/src/cron/store.js +1 -1
- package/package.json +9 -3
- package/.env.example +0 -8
- package/AGENTS.md +0 -267
- package/ROADMAP.md +0 -34
- package/config/cron.example.json +0 -9
- package/config/gateway.example.json +0 -132
- package/dist/plugins/connector-discord/src/mapper.js +0 -75
- package/dist/src/cli/tests/config-command.test.js +0 -42
- package/dist/src/cli/tests/config-io.test.js +0 -64
- package/dist/src/cli/tests/config-mutators.test.js +0 -47
- package/dist/src/cli/tests/discord-mapper.test.js +0 -90
- package/dist/src/cli/tests/doctor.test.js +0 -252
- package/dist/src/cli/tests/init-catalog.test.js +0 -134
- package/dist/src/cli/tests/program-options.test.js +0 -78
- package/dist/src/cli/tests/routing-config.test.js +0 -254
- package/dist/src/core/tests/control-command.test.js +0 -17
- package/dist/src/core/tests/runtime-registry.test.js +0 -116
- package/dist/src/core/tests/typing-controller.test.js +0 -103
- package/docs/BOXLITE_SANDBOX_FEASIBILITY.md +0 -175
- package/docs/CRON_SCHEDULER_DESIGN.md +0 -374
- package/docs/DOCKER_SANDBOX_vs_BOXLITE.md +0 -77
- package/docs/EXTENSION_SYSTEM_ARCHITECTURE.md +0 -119
- package/docs/MVP.md +0 -135
- package/docs/RUNBOOK.md +0 -243
- package/docs/TEAMWORK_HANDOFF_DESIGN.md +0 -440
- package/plugins/connector-discord/dobby.manifest.json +0 -18
- package/plugins/connector-discord/index.js +0 -1
- package/plugins/connector-discord/package-lock.json +0 -360
- package/plugins/connector-discord/package.json +0 -38
- package/plugins/connector-discord/src/connector.ts +0 -345
- package/plugins/connector-discord/src/contribution.ts +0 -21
- package/plugins/connector-discord/src/mapper.ts +0 -101
- package/plugins/connector-discord/tsconfig.json +0 -19
- package/plugins/connector-feishu/dobby.manifest.json +0 -18
- package/plugins/connector-feishu/index.js +0 -1
- package/plugins/connector-feishu/package-lock.json +0 -618
- package/plugins/connector-feishu/package.json +0 -38
- package/plugins/connector-feishu/src/connector.ts +0 -343
- package/plugins/connector-feishu/src/contribution.ts +0 -26
- package/plugins/connector-feishu/src/mapper.ts +0 -401
- package/plugins/connector-feishu/tsconfig.json +0 -19
- package/plugins/plugin-sdk/index.d.ts +0 -261
- package/plugins/plugin-sdk/index.js +0 -1
- package/plugins/plugin-sdk/package-lock.json +0 -12
- package/plugins/plugin-sdk/package.json +0 -22
- package/plugins/provider-claude/dobby.manifest.json +0 -17
- package/plugins/provider-claude/index.js +0 -1
- package/plugins/provider-claude/package-lock.json +0 -3398
- package/plugins/provider-claude/package.json +0 -39
- package/plugins/provider-claude/src/contribution.ts +0 -1018
- package/plugins/provider-claude/tsconfig.json +0 -19
- package/plugins/provider-claude-cli/dobby.manifest.json +0 -17
- package/plugins/provider-claude-cli/index.js +0 -1
- package/plugins/provider-claude-cli/package-lock.json +0 -2898
- package/plugins/provider-claude-cli/package.json +0 -38
- package/plugins/provider-claude-cli/src/contribution.ts +0 -1673
- package/plugins/provider-claude-cli/tsconfig.json +0 -19
- package/plugins/provider-pi/dobby.manifest.json +0 -17
- package/plugins/provider-pi/index.js +0 -1
- package/plugins/provider-pi/package-lock.json +0 -3877
- package/plugins/provider-pi/package.json +0 -40
- package/plugins/provider-pi/src/contribution.ts +0 -606
- package/plugins/provider-pi/tsconfig.json +0 -19
- package/plugins/sandbox-core/boxlite.js +0 -1
- package/plugins/sandbox-core/dobby.manifest.json +0 -17
- package/plugins/sandbox-core/docker.js +0 -1
- package/plugins/sandbox-core/package-lock.json +0 -136
- package/plugins/sandbox-core/package.json +0 -39
- package/plugins/sandbox-core/src/boxlite-context.ts +0 -2
- package/plugins/sandbox-core/src/boxlite-contribution.ts +0 -53
- package/plugins/sandbox-core/src/boxlite-executor.ts +0 -911
- package/plugins/sandbox-core/src/docker-contribution.ts +0 -43
- package/plugins/sandbox-core/src/docker-executor.ts +0 -217
- package/plugins/sandbox-core/tsconfig.json +0 -19
- package/scripts/local-extensions.mjs +0 -168
- package/src/agent/event-forwarder.ts +0 -414
- package/src/cli/commands/config.ts +0 -328
- package/src/cli/commands/configure.ts +0 -92
- package/src/cli/commands/cron.ts +0 -410
- package/src/cli/commands/doctor.ts +0 -331
- package/src/cli/commands/extension.ts +0 -207
- package/src/cli/commands/init.ts +0 -211
- package/src/cli/commands/start.ts +0 -223
- package/src/cli/commands/topology.ts +0 -415
- package/src/cli/index.ts +0 -9
- package/src/cli/program.ts +0 -314
- package/src/cli/shared/config-io.ts +0 -245
- package/src/cli/shared/config-mutators.ts +0 -470
- package/src/cli/shared/config-schema.ts +0 -228
- package/src/cli/shared/config-types.ts +0 -129
- package/src/cli/shared/configure-sections.ts +0 -595
- package/src/cli/shared/discord-config.ts +0 -14
- package/src/cli/shared/init-catalog.ts +0 -249
- package/src/cli/shared/local-extension-specs.ts +0 -108
- package/src/cli/shared/runtime.ts +0 -33
- package/src/cli/shared/schema-prompts.ts +0 -443
- package/src/cli/tests/config-command.test.ts +0 -56
- package/src/cli/tests/config-io.test.ts +0 -92
- package/src/cli/tests/config-mutators.test.ts +0 -59
- package/src/cli/tests/discord-mapper.test.ts +0 -128
- package/src/cli/tests/doctor.test.ts +0 -269
- package/src/cli/tests/init-catalog.test.ts +0 -144
- package/src/cli/tests/program-options.test.ts +0 -95
- package/src/cli/tests/routing-config.test.ts +0 -281
- package/src/core/control-command.ts +0 -12
- package/src/core/dedup-store.ts +0 -103
- package/src/core/gateway.ts +0 -609
- package/src/core/routing.ts +0 -404
- package/src/core/runtime-registry.ts +0 -141
- package/src/core/tests/control-command.test.ts +0 -20
- package/src/core/tests/runtime-registry.test.ts +0 -140
- package/src/core/tests/typing-controller.test.ts +0 -129
- package/src/core/types.ts +0 -324
- package/src/core/typing-controller.ts +0 -119
- package/src/cron/config.ts +0 -154
- package/src/cron/schedule.ts +0 -61
- package/src/cron/service.ts +0 -249
- package/src/cron/store.ts +0 -155
- package/src/cron/types.ts +0 -60
- package/src/extension/loader.ts +0 -145
- package/src/extension/manager.ts +0 -355
- package/src/extension/manifest.ts +0 -26
- package/src/extension/registry.ts +0 -229
- package/src/main.ts +0 -8
- package/src/sandbox/executor.ts +0 -44
- package/src/sandbox/host-executor.ts +0 -118
- package/src/shared/dobby-repo.ts +0 -48
- package/tsconfig.json +0 -18
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
RawBindingConfig,
|
|
3
|
-
RawDefaultBindingConfig,
|
|
4
|
-
RawRouteDefaults,
|
|
5
|
-
RawRouteProfile,
|
|
6
|
-
} from "./config-types.js";
|
|
7
|
-
import {
|
|
8
|
-
DEFAULT_DISCORD_BOT_NAME,
|
|
9
|
-
DEFAULT_DISCORD_CONNECTOR_INSTANCE_ID,
|
|
10
|
-
DISCORD_CONNECTOR_CONTRIBUTION_ID,
|
|
11
|
-
} from "./discord-config.js";
|
|
12
|
-
|
|
13
|
-
export type InitProviderChoiceId = "provider.pi" | "provider.claude-cli";
|
|
14
|
-
export type InitConnectorChoiceId = "connector.discord" | "connector.feishu";
|
|
15
|
-
|
|
16
|
-
export const DEFAULT_INIT_ROUTE_ID = "main";
|
|
17
|
-
export const DEFAULT_INIT_PROJECT_ROOT = "./REPLACE_WITH_PROJECT_ROOT";
|
|
18
|
-
|
|
19
|
-
interface ProviderCatalogEntry {
|
|
20
|
-
id: InitProviderChoiceId;
|
|
21
|
-
label: string;
|
|
22
|
-
package: string;
|
|
23
|
-
instanceId: string;
|
|
24
|
-
contributionId: string;
|
|
25
|
-
defaultConfig: Record<string, unknown>;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
interface ConnectorBindingTemplate {
|
|
29
|
-
sourceType: RawBindingConfig["source"]["type"];
|
|
30
|
-
sourceId: string;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
interface ConnectorCatalogEntry {
|
|
34
|
-
id: InitConnectorChoiceId;
|
|
35
|
-
label: string;
|
|
36
|
-
package: string;
|
|
37
|
-
instanceId: string;
|
|
38
|
-
contributionId: string;
|
|
39
|
-
defaultConfig: Record<string, unknown>;
|
|
40
|
-
bindingTemplate: ConnectorBindingTemplate;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface InitSelectionContext {
|
|
44
|
-
routeProviderChoiceId: InitProviderChoiceId;
|
|
45
|
-
defaultProjectRoot?: string;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export interface InitSelectionResult {
|
|
49
|
-
providerChoiceIds: InitProviderChoiceId[];
|
|
50
|
-
routeProviderChoiceId: InitProviderChoiceId;
|
|
51
|
-
connectorChoiceIds: InitConnectorChoiceId[];
|
|
52
|
-
extensionPackages: string[];
|
|
53
|
-
providerInstances: Array<{
|
|
54
|
-
choiceId: InitProviderChoiceId;
|
|
55
|
-
instanceId: string;
|
|
56
|
-
contributionId: string;
|
|
57
|
-
config: Record<string, unknown>;
|
|
58
|
-
}>;
|
|
59
|
-
connectorInstances: Array<{
|
|
60
|
-
choiceId: InitConnectorChoiceId;
|
|
61
|
-
instanceId: string;
|
|
62
|
-
contributionId: string;
|
|
63
|
-
config: Record<string, unknown>;
|
|
64
|
-
}>;
|
|
65
|
-
providerInstanceId: string;
|
|
66
|
-
routeId: string;
|
|
67
|
-
routeDefaults: RawRouteDefaults;
|
|
68
|
-
routeProfile: RawRouteProfile;
|
|
69
|
-
defaultBinding?: RawDefaultBindingConfig;
|
|
70
|
-
bindings: Array<{
|
|
71
|
-
id: string;
|
|
72
|
-
config: RawBindingConfig;
|
|
73
|
-
}>;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const PROVIDER_CATALOG: Record<InitProviderChoiceId, ProviderCatalogEntry> = {
|
|
77
|
-
"provider.pi": {
|
|
78
|
-
id: "provider.pi",
|
|
79
|
-
label: "Pi provider",
|
|
80
|
-
package: "@dobby.ai/provider-pi",
|
|
81
|
-
instanceId: "pi.main",
|
|
82
|
-
contributionId: "provider.pi",
|
|
83
|
-
defaultConfig: {
|
|
84
|
-
model: "REPLACE_WITH_PROVIDER_MODEL_ID",
|
|
85
|
-
baseUrl: "REPLACE_WITH_PROVIDER_BASE_URL",
|
|
86
|
-
apiKey: "REPLACE_WITH_PROVIDER_API_KEY_OR_ENV",
|
|
87
|
-
},
|
|
88
|
-
},
|
|
89
|
-
"provider.claude-cli": {
|
|
90
|
-
id: "provider.claude-cli",
|
|
91
|
-
label: "Claude CLI provider",
|
|
92
|
-
package: "@dobby.ai/provider-claude-cli",
|
|
93
|
-
instanceId: "claude-cli.main",
|
|
94
|
-
contributionId: "provider.claude-cli",
|
|
95
|
-
defaultConfig: {
|
|
96
|
-
model: "claude-sonnet-4-5",
|
|
97
|
-
maxTurns: 20,
|
|
98
|
-
command: "claude",
|
|
99
|
-
commandArgs: [],
|
|
100
|
-
authMode: "auto",
|
|
101
|
-
permissionMode: "bypassPermissions",
|
|
102
|
-
streamVerbose: true,
|
|
103
|
-
},
|
|
104
|
-
},
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
const CONNECTOR_CATALOG: Record<InitConnectorChoiceId, ConnectorCatalogEntry> = {
|
|
108
|
-
"connector.discord": {
|
|
109
|
-
id: "connector.discord",
|
|
110
|
-
label: "Discord connector",
|
|
111
|
-
package: "@dobby.ai/connector-discord",
|
|
112
|
-
instanceId: DEFAULT_DISCORD_CONNECTOR_INSTANCE_ID,
|
|
113
|
-
contributionId: DISCORD_CONNECTOR_CONTRIBUTION_ID,
|
|
114
|
-
defaultConfig: {
|
|
115
|
-
botName: DEFAULT_DISCORD_BOT_NAME,
|
|
116
|
-
botToken: "REPLACE_WITH_DISCORD_BOT_TOKEN",
|
|
117
|
-
reconnectStaleMs: 60_000,
|
|
118
|
-
reconnectCheckIntervalMs: 10_000,
|
|
119
|
-
},
|
|
120
|
-
bindingTemplate: {
|
|
121
|
-
sourceType: "channel",
|
|
122
|
-
sourceId: "YOUR_DISCORD_CHANNEL_ID",
|
|
123
|
-
},
|
|
124
|
-
},
|
|
125
|
-
"connector.feishu": {
|
|
126
|
-
id: "connector.feishu",
|
|
127
|
-
label: "Feishu connector",
|
|
128
|
-
package: "@dobby.ai/connector-feishu",
|
|
129
|
-
instanceId: "feishu.main",
|
|
130
|
-
contributionId: "connector.feishu",
|
|
131
|
-
defaultConfig: {
|
|
132
|
-
appId: "REPLACE_WITH_FEISHU_APP_ID",
|
|
133
|
-
appSecret: "REPLACE_WITH_FEISHU_APP_SECRET",
|
|
134
|
-
domain: "feishu",
|
|
135
|
-
messageFormat: "card_markdown",
|
|
136
|
-
replyMode: "direct",
|
|
137
|
-
downloadAttachments: true,
|
|
138
|
-
},
|
|
139
|
-
bindingTemplate: {
|
|
140
|
-
sourceType: "chat",
|
|
141
|
-
sourceId: "YOUR_FEISHU_CHAT_ID",
|
|
142
|
-
},
|
|
143
|
-
},
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
function dedupeChoiceIds<T extends string>(choiceIds: T[]): T[] {
|
|
147
|
-
const dedupedChoiceIds: T[] = [];
|
|
148
|
-
const seenChoiceIds = new Set<T>();
|
|
149
|
-
|
|
150
|
-
for (const choiceId of choiceIds) {
|
|
151
|
-
if (seenChoiceIds.has(choiceId)) {
|
|
152
|
-
continue;
|
|
153
|
-
}
|
|
154
|
-
seenChoiceIds.add(choiceId);
|
|
155
|
-
dedupedChoiceIds.push(choiceId);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
return dedupedChoiceIds;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export function listInitProviderChoices(): ProviderCatalogEntry[] {
|
|
162
|
-
return Object.values(PROVIDER_CATALOG);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
export function listInitConnectorChoices(): ConnectorCatalogEntry[] {
|
|
166
|
-
return Object.values(CONNECTOR_CATALOG);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
export function isInitProviderChoiceId(value: string): value is InitProviderChoiceId {
|
|
170
|
-
return Object.prototype.hasOwnProperty.call(PROVIDER_CATALOG, value);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
export function isInitConnectorChoiceId(value: string): value is InitConnectorChoiceId {
|
|
174
|
-
return Object.prototype.hasOwnProperty.call(CONNECTOR_CATALOG, value);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
export function createInitSelectionConfig(
|
|
178
|
-
providerChoiceIds: InitProviderChoiceId[],
|
|
179
|
-
connectorChoiceIds: InitConnectorChoiceId[],
|
|
180
|
-
context: InitSelectionContext,
|
|
181
|
-
): InitSelectionResult {
|
|
182
|
-
const dedupedProviderChoiceIds = dedupeChoiceIds(providerChoiceIds);
|
|
183
|
-
if (dedupedProviderChoiceIds.length === 0) {
|
|
184
|
-
throw new Error("At least one provider choice is required");
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
const dedupedConnectorChoiceIds = dedupeChoiceIds(connectorChoiceIds);
|
|
188
|
-
if (dedupedConnectorChoiceIds.length === 0) {
|
|
189
|
-
throw new Error("At least one connector choice is required");
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
if (!dedupedProviderChoiceIds.includes(context.routeProviderChoiceId)) {
|
|
193
|
-
throw new Error(
|
|
194
|
-
`route provider choice '${context.routeProviderChoiceId}' must be one of selected providers: ${dedupedProviderChoiceIds.join(", ")}`,
|
|
195
|
-
);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
const providerChoices = dedupedProviderChoiceIds.map((providerChoiceId) => PROVIDER_CATALOG[providerChoiceId]);
|
|
199
|
-
const connectorChoices = dedupedConnectorChoiceIds.map((connectorChoiceId) => CONNECTOR_CATALOG[connectorChoiceId]);
|
|
200
|
-
const primaryProviderChoice = PROVIDER_CATALOG[context.routeProviderChoiceId];
|
|
201
|
-
|
|
202
|
-
return {
|
|
203
|
-
providerChoiceIds: dedupedProviderChoiceIds,
|
|
204
|
-
routeProviderChoiceId: primaryProviderChoice.id,
|
|
205
|
-
connectorChoiceIds: dedupedConnectorChoiceIds,
|
|
206
|
-
extensionPackages: [
|
|
207
|
-
...new Set([
|
|
208
|
-
...providerChoices.map((item) => item.package),
|
|
209
|
-
...connectorChoices.map((item) => item.package),
|
|
210
|
-
]),
|
|
211
|
-
],
|
|
212
|
-
providerInstances: providerChoices.map((providerChoice) => ({
|
|
213
|
-
choiceId: providerChoice.id,
|
|
214
|
-
instanceId: providerChoice.instanceId,
|
|
215
|
-
contributionId: providerChoice.contributionId,
|
|
216
|
-
config: structuredClone(providerChoice.defaultConfig),
|
|
217
|
-
})),
|
|
218
|
-
connectorInstances: connectorChoices.map((connectorChoice) => ({
|
|
219
|
-
choiceId: connectorChoice.id,
|
|
220
|
-
instanceId: connectorChoice.instanceId,
|
|
221
|
-
contributionId: connectorChoice.contributionId,
|
|
222
|
-
config: structuredClone(connectorChoice.defaultConfig),
|
|
223
|
-
})),
|
|
224
|
-
providerInstanceId: primaryProviderChoice.instanceId,
|
|
225
|
-
routeId: DEFAULT_INIT_ROUTE_ID,
|
|
226
|
-
routeDefaults: {
|
|
227
|
-
projectRoot: context.defaultProjectRoot ?? DEFAULT_INIT_PROJECT_ROOT,
|
|
228
|
-
tools: "full",
|
|
229
|
-
mentions: "required",
|
|
230
|
-
provider: primaryProviderChoice.instanceId,
|
|
231
|
-
sandbox: "host.builtin",
|
|
232
|
-
},
|
|
233
|
-
routeProfile: {},
|
|
234
|
-
defaultBinding: {
|
|
235
|
-
route: DEFAULT_INIT_ROUTE_ID,
|
|
236
|
-
},
|
|
237
|
-
bindings: connectorChoices.map((connectorChoice) => ({
|
|
238
|
-
id: `${connectorChoice.instanceId}.${DEFAULT_INIT_ROUTE_ID}`,
|
|
239
|
-
config: {
|
|
240
|
-
connector: connectorChoice.instanceId,
|
|
241
|
-
source: {
|
|
242
|
-
type: connectorChoice.bindingTemplate.sourceType,
|
|
243
|
-
id: connectorChoice.bindingTemplate.sourceId,
|
|
244
|
-
},
|
|
245
|
-
route: DEFAULT_INIT_ROUTE_ID,
|
|
246
|
-
},
|
|
247
|
-
})),
|
|
248
|
-
};
|
|
249
|
-
}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import { access, readFile } from "node:fs/promises";
|
|
2
|
-
import { readdir } from "node:fs/promises";
|
|
3
|
-
import { resolve } from "node:path";
|
|
4
|
-
import { findDobbyRepoRoot } from "../../shared/dobby-repo.js";
|
|
5
|
-
|
|
6
|
-
interface LocalExtensionPackage {
|
|
7
|
-
packageName: string;
|
|
8
|
-
packageDir: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function isExplicitInstallSpec(value: string): boolean {
|
|
12
|
-
return value.startsWith("file:")
|
|
13
|
-
|| value.startsWith("git+")
|
|
14
|
-
|| value.startsWith("http://")
|
|
15
|
-
|| value.startsWith("https://")
|
|
16
|
-
|| value.startsWith("./")
|
|
17
|
-
|| value.startsWith("../")
|
|
18
|
-
|| value.startsWith("/");
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
async function listRepoLocalExtensionPackages(repoRoot: string): Promise<Map<string, LocalExtensionPackage>> {
|
|
22
|
-
const pluginsRoot = resolve(repoRoot, "plugins");
|
|
23
|
-
const entries = await readdir(pluginsRoot, { withFileTypes: true });
|
|
24
|
-
const packages = new Map<string, LocalExtensionPackage>();
|
|
25
|
-
|
|
26
|
-
for (const entry of entries) {
|
|
27
|
-
if (!entry.isDirectory() || entry.name === "plugin-sdk") {
|
|
28
|
-
continue;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const packageDir = resolve(pluginsRoot, entry.name);
|
|
32
|
-
const packageJsonPath = resolve(packageDir, "package.json");
|
|
33
|
-
const manifestPath = resolve(packageDir, "dobby.manifest.json");
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
await access(packageJsonPath);
|
|
37
|
-
await access(manifestPath);
|
|
38
|
-
const raw = await readFile(packageJsonPath, "utf-8");
|
|
39
|
-
const parsed = JSON.parse(raw) as { name?: unknown };
|
|
40
|
-
if (typeof parsed.name !== "string" || parsed.name.trim().length === 0) {
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
packages.set(parsed.name, {
|
|
45
|
-
packageName: parsed.name,
|
|
46
|
-
packageDir,
|
|
47
|
-
});
|
|
48
|
-
} catch {
|
|
49
|
-
continue;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return packages;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
async function assertLocalExtensionBuildReady(localPackage: LocalExtensionPackage): Promise<void> {
|
|
57
|
-
const manifestPath = resolve(localPackage.packageDir, "dobby.manifest.json");
|
|
58
|
-
const rawManifest = await readFile(manifestPath, "utf-8");
|
|
59
|
-
const parsed = JSON.parse(rawManifest) as {
|
|
60
|
-
contributions?: Array<{ id?: unknown; entry?: unknown }>;
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
for (const contribution of parsed.contributions ?? []) {
|
|
64
|
-
if (typeof contribution.entry !== "string" || contribution.entry.trim().length === 0) {
|
|
65
|
-
continue;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const entryPath = resolve(localPackage.packageDir, contribution.entry);
|
|
69
|
-
try {
|
|
70
|
-
await access(entryPath);
|
|
71
|
-
} catch {
|
|
72
|
-
const contributionId = typeof contribution.id === "string" ? contribution.id : "unknown";
|
|
73
|
-
throw new Error(
|
|
74
|
-
`Local extension '${localPackage.packageName}' is not built for contribution '${contributionId}'. `
|
|
75
|
-
+ `Missing '${entryPath}'. Run 'npm run build --prefix ${localPackage.packageDir}' first.`,
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export async function resolveExtensionInstallSpecs(packageSpecs: string[], cwd = process.cwd()): Promise<string[]> {
|
|
82
|
-
const repoRoot = findDobbyRepoRoot(cwd);
|
|
83
|
-
if (!repoRoot) {
|
|
84
|
-
return packageSpecs;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const repoPackages = await listRepoLocalExtensionPackages(repoRoot);
|
|
88
|
-
const resolvedSpecs: string[] = [];
|
|
89
|
-
|
|
90
|
-
for (const rawSpec of packageSpecs) {
|
|
91
|
-
const packageSpec = rawSpec.trim();
|
|
92
|
-
if (packageSpec.length === 0 || isExplicitInstallSpec(packageSpec)) {
|
|
93
|
-
resolvedSpecs.push(packageSpec);
|
|
94
|
-
continue;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const localPackage = repoPackages.get(packageSpec);
|
|
98
|
-
if (!localPackage) {
|
|
99
|
-
resolvedSpecs.push(packageSpec);
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
await assertLocalExtensionBuildReady(localPackage);
|
|
104
|
-
resolvedSpecs.push(`file:${localPackage.packageDir}`);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return resolvedSpecs;
|
|
108
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { mkdir } from "node:fs/promises";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import pino from "pino";
|
|
4
|
-
import type { GatewayConfig } from "../../core/types.js";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Creates the shared gateway logger instance used across CLI commands.
|
|
8
|
-
*/
|
|
9
|
-
export function createLogger() {
|
|
10
|
-
return pino({
|
|
11
|
-
name: "dobby",
|
|
12
|
-
level: process.env.LOG_LEVEL ?? "info",
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Returns the extension store directory from normalized gateway config.
|
|
18
|
-
*/
|
|
19
|
-
export function extensionStoreDir(config: GatewayConfig): string {
|
|
20
|
-
return join(config.data.rootDir, "extensions");
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Ensures required runtime data directories exist before start/doctor operations.
|
|
25
|
-
*/
|
|
26
|
-
export async function ensureDataDirs(rootDir: string): Promise<void> {
|
|
27
|
-
await mkdir(rootDir, { recursive: true });
|
|
28
|
-
await mkdir(join(rootDir, "sessions"), { recursive: true });
|
|
29
|
-
await mkdir(join(rootDir, "attachments"), { recursive: true });
|
|
30
|
-
await mkdir(join(rootDir, "logs"), { recursive: true });
|
|
31
|
-
await mkdir(join(rootDir, "state"), { recursive: true });
|
|
32
|
-
await mkdir(join(rootDir, "extensions"), { recursive: true });
|
|
33
|
-
}
|