@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,43 +0,0 @@
1
- import { resolve } from "node:path";
2
- import { z } from "zod";
3
- import type { SandboxContributionModule } from "@dobby.ai/plugin-sdk";
4
- import { DockerExecutor } from "./docker-executor.js";
5
-
6
- const dockerSandboxConfigSchema = z.object({
7
- container: z.string().min(1),
8
- hostWorkspaceRoot: z.string().min(1),
9
- containerWorkspaceRoot: z.string().min(1).default("/workspace"),
10
- });
11
-
12
- function resolveMaybeAbsolute(baseDir: string, value: string): string {
13
- if (value === "~") {
14
- return resolve(process.env.HOME ?? "", ".");
15
- }
16
- if (value.startsWith("~/") || value.startsWith("~\\")) {
17
- return resolve(process.env.HOME ?? "", value.slice(2));
18
- }
19
- return resolve(baseDir, value);
20
- }
21
-
22
- export const sandboxDockerContribution: SandboxContributionModule = {
23
- kind: "sandbox",
24
- configSchema: z.toJSONSchema(dockerSandboxConfigSchema),
25
- async createInstance(options) {
26
- const parsed = dockerSandboxConfigSchema.parse(options.config);
27
- const executor = await DockerExecutor.create(
28
- {
29
- container: parsed.container,
30
- hostWorkspaceRoot: resolveMaybeAbsolute(options.host.configBaseDir, parsed.hostWorkspaceRoot),
31
- containerWorkspaceRoot: parsed.containerWorkspaceRoot,
32
- },
33
- options.host.logger,
34
- );
35
-
36
- return {
37
- id: options.instanceId,
38
- executor,
39
- };
40
- },
41
- };
42
-
43
- export default sandboxDockerContribution;
@@ -1,217 +0,0 @@
1
- import { spawn } from "node:child_process";
2
- import { resolve, sep } from "node:path";
3
- import type { GatewayLogger } from "@dobby.ai/plugin-sdk";
4
- import type { ExecOptions, ExecResult, Executor, SpawnOptions, SpawnedProcess } from "@dobby.ai/plugin-sdk";
5
-
6
- export interface DockerConfig {
7
- container: string;
8
- hostWorkspaceRoot: string;
9
- containerWorkspaceRoot: string;
10
- }
11
-
12
- function shellEscape(value: string): string {
13
- return `'${value.replace(/'/g, "'\\''")}'`;
14
- }
15
-
16
- function normalizePrefix(path: string): string {
17
- return path.endsWith(sep) ? path : `${path}${sep}`;
18
- }
19
-
20
- export class DockerExecutor implements Executor {
21
- private readonly normalizedHostRoot: string;
22
-
23
- private constructor(
24
- private readonly config: DockerConfig,
25
- private readonly logger: GatewayLogger,
26
- ) {
27
- this.normalizedHostRoot = normalizePrefix(resolve(config.hostWorkspaceRoot));
28
- }
29
-
30
- static async create(config: DockerConfig, logger: GatewayLogger): Promise<DockerExecutor> {
31
- const instance = new DockerExecutor(config, logger);
32
- await instance.validate();
33
- return instance;
34
- }
35
-
36
- async exec(command: string, cwd: string, options: ExecOptions = {}): Promise<ExecResult> {
37
- const containerCwd = this.toContainerPath(cwd);
38
- const wrapped = `cd ${shellEscape(containerCwd)} && ${command}`;
39
-
40
- const args = ["exec", "-i"];
41
- if (options.env) {
42
- for (const [key, value] of Object.entries(options.env)) {
43
- if (value !== undefined) {
44
- args.push("-e", `${key}=${value}`);
45
- }
46
- }
47
- }
48
- args.push(this.config.container, "sh", "-lc", wrapped);
49
-
50
- return new Promise<ExecResult>((resolveResult, reject) => {
51
- const child = spawn("docker", args, {
52
- stdio: ["ignore", "pipe", "pipe"],
53
- });
54
-
55
- let stdout = "";
56
- let stderr = "";
57
- let killed = false;
58
-
59
- const onAbort = () => {
60
- killed = true;
61
- child.kill("SIGKILL");
62
- };
63
-
64
- let timeoutHandle: NodeJS.Timeout | undefined;
65
- if (options.timeoutSeconds && options.timeoutSeconds > 0) {
66
- timeoutHandle = setTimeout(onAbort, options.timeoutSeconds * 1000);
67
- }
68
-
69
- if (options.signal) {
70
- if (options.signal.aborted) {
71
- onAbort();
72
- } else {
73
- options.signal.addEventListener("abort", onAbort, { once: true });
74
- }
75
- }
76
-
77
- child.stdout.on("data", (chunk) => {
78
- stdout += String(chunk);
79
- });
80
- child.stderr.on("data", (chunk) => {
81
- stderr += String(chunk);
82
- });
83
-
84
- child.on("error", (error) => {
85
- if (timeoutHandle) clearTimeout(timeoutHandle);
86
- if (options.signal) options.signal.removeEventListener("abort", onAbort);
87
- reject(error);
88
- });
89
-
90
- child.on("close", (code) => {
91
- if (timeoutHandle) clearTimeout(timeoutHandle);
92
- if (options.signal) options.signal.removeEventListener("abort", onAbort);
93
- resolveResult({ stdout, stderr, code: code ?? 0, killed });
94
- });
95
- });
96
- }
97
-
98
- spawn(options: SpawnOptions): SpawnedProcess {
99
- const cwd = options.cwd ?? this.config.hostWorkspaceRoot;
100
- const containerCwd = this.toContainerPath(cwd);
101
- const argv = [options.command, ...options.args].map(shellEscape).join(" ");
102
- const wrapped = `cd ${shellEscape(containerCwd)} && exec ${argv}`;
103
-
104
- const args = ["exec", "-i"];
105
- if (options.tty) {
106
- args.push("-t");
107
- }
108
- if (options.env) {
109
- for (const [key, value] of Object.entries(options.env)) {
110
- if (value !== undefined) {
111
- args.push("-e", `${key}=${value}`);
112
- }
113
- }
114
- }
115
- args.push(this.config.container, "sh", "-lc", wrapped);
116
-
117
- const child = spawn("docker", args, {
118
- stdio: ["pipe", "pipe", "pipe"],
119
- });
120
-
121
- const onAbort = () => {
122
- child.kill("SIGKILL");
123
- };
124
-
125
- if (options.signal) {
126
- if (options.signal.aborted) {
127
- onAbort();
128
- } else {
129
- options.signal.addEventListener("abort", onAbort, { once: true });
130
- child.once("exit", () => {
131
- options.signal?.removeEventListener("abort", onAbort);
132
- });
133
- }
134
- }
135
-
136
- if (!child.stdin || !child.stdout || !child.stderr) {
137
- child.kill("SIGKILL");
138
- throw new Error("Docker executor failed to create stdio pipes for spawned process");
139
- }
140
-
141
- const spawned: SpawnedProcess = {
142
- stdin: child.stdin,
143
- stdout: child.stdout,
144
- stderr: child.stderr,
145
- get killed() {
146
- return child.killed;
147
- },
148
- get exitCode() {
149
- return child.exitCode;
150
- },
151
- kill(signal = "SIGKILL") {
152
- return child.kill(signal);
153
- },
154
- on(event, listener) {
155
- child.on(event, listener as (...args: unknown[]) => void);
156
- },
157
- once(event, listener) {
158
- child.once(event, listener as (...args: unknown[]) => void);
159
- },
160
- off(event, listener) {
161
- child.off(event, listener as (...args: unknown[]) => void);
162
- },
163
- };
164
-
165
- return spawned;
166
- }
167
-
168
- async close(): Promise<void> {
169
- this.logger.debug({ container: this.config.container }, "DockerExecutor closed");
170
- }
171
-
172
- private async validate(): Promise<void> {
173
- await this.execSimple("docker", ["--version"]);
174
-
175
- const inspect = await this.execSimple("docker", ["inspect", "-f", "{{.State.Running}}", this.config.container]);
176
- if (inspect.trim() !== "true") {
177
- throw new Error(`Docker container '${this.config.container}' is not running`);
178
- }
179
- }
180
-
181
- private toContainerPath(hostPath: string): string {
182
- const resolved = resolve(hostPath);
183
- if (!resolved.startsWith(this.normalizedHostRoot) && resolved !== this.normalizedHostRoot.slice(0, -1)) {
184
- throw new Error(`Path '${resolved}' is outside docker hostWorkspaceRoot '${this.config.hostWorkspaceRoot}'`);
185
- }
186
-
187
- const relative = resolved.slice(this.normalizedHostRoot.length).replaceAll("\\", "/");
188
- const base = this.config.containerWorkspaceRoot.endsWith("/")
189
- ? this.config.containerWorkspaceRoot.slice(0, -1)
190
- : this.config.containerWorkspaceRoot;
191
-
192
- return relative.length > 0 ? `${base}/${relative}` : base;
193
- }
194
-
195
- private execSimple(command: string, args: string[]): Promise<string> {
196
- return new Promise((resolveOutput, reject) => {
197
- const child = spawn(command, args, { stdio: ["ignore", "pipe", "pipe"] });
198
- let stdout = "";
199
- let stderr = "";
200
-
201
- child.stdout.on("data", (chunk) => {
202
- stdout += String(chunk);
203
- });
204
- child.stderr.on("data", (chunk) => {
205
- stderr += String(chunk);
206
- });
207
- child.on("error", reject);
208
- child.on("close", (code) => {
209
- if (code === 0) {
210
- resolveOutput(stdout);
211
- } else {
212
- reject(new Error(stderr || `Command failed: ${command} ${args.join(" ")}`));
213
- }
214
- });
215
- });
216
- }
217
- }
@@ -1,19 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "NodeNext",
5
- "moduleResolution": "NodeNext",
6
- "outDir": "./dist",
7
- "rootDir": "./src",
8
- "types": ["node"],
9
- "strict": true,
10
- "esModuleInterop": true,
11
- "forceConsistentCasingInFileNames": true,
12
- "skipLibCheck": true,
13
- "noUncheckedIndexedAccess": true,
14
- "exactOptionalPropertyTypes": true,
15
- "resolveJsonModule": true
16
- },
17
- "include": ["src/**/*.ts"],
18
- "exclude": ["dist", "node_modules"]
19
- }
@@ -1,168 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { spawn } from "node:child_process";
4
- import { access, readdir, readFile } from "node:fs/promises";
5
- import { dirname, resolve } from "node:path";
6
- import { fileURLToPath } from "node:url";
7
-
8
- const scriptDir = dirname(fileURLToPath(import.meta.url));
9
- const projectRoot = resolve(scriptDir, "..");
10
-
11
- const npmCommand = process.platform === "win32" ? "npm.cmd" : "npm";
12
- const nodeCommand = process.execPath;
13
-
14
- const pluginsRootDir = resolve(projectRoot, "plugins");
15
- const pluginSdkDir = "plugins/plugin-sdk";
16
-
17
- async function discoverLocalExtensionPackages() {
18
- const entries = await readdir(pluginsRootDir, { withFileTypes: true });
19
- const discovered = [];
20
-
21
- for (const entry of entries) {
22
- if (!entry.isDirectory()) {
23
- continue;
24
- }
25
- if (entry.name === "plugin-sdk") {
26
- continue;
27
- }
28
-
29
- const relativeDir = `plugins/${entry.name}`;
30
- const packageJsonPath = resolve(projectRoot, relativeDir, "package.json");
31
- const manifestPath = resolve(projectRoot, relativeDir, "dobby.manifest.json");
32
-
33
- try {
34
- await access(packageJsonPath);
35
- await access(manifestPath);
36
- const rawPackageJson = await readFile(packageJsonPath, "utf-8");
37
- const parsedPackageJson = JSON.parse(rawPackageJson);
38
- if (typeof parsedPackageJson?.name !== "string" || parsedPackageJson.name.length === 0) {
39
- throw new Error(`Missing package name in ${packageJsonPath}`);
40
- }
41
-
42
- discovered.push({
43
- name: parsedPackageJson.name,
44
- dir: relativeDir,
45
- });
46
- } catch {
47
- continue;
48
- }
49
- }
50
-
51
- discovered.sort((a, b) => a.dir.localeCompare(b.dir));
52
- return discovered;
53
- }
54
-
55
- function printUsage() {
56
- console.log("Usage: node scripts/local-extensions.mjs <command>");
57
- console.log("");
58
- console.log("Commands:");
59
- console.log(" install Install local plugin development dependencies");
60
- console.log(" check Type-check local extension plugins");
61
- console.log(" build Build local extension plugins");
62
- console.log(" install-store Install local extension plugins into extension store");
63
- console.log(" list-store List installed extensions from extension store");
64
- console.log(" setup Run install + build + install-store");
65
- }
66
-
67
- async function run(command, args) {
68
- const pretty = [command, ...args].join(" ");
69
- console.log(`$ ${pretty}`);
70
-
71
- await new Promise((resolvePromise, rejectPromise) => {
72
- const child = spawn(command, args, {
73
- cwd: projectRoot,
74
- stdio: "inherit",
75
- env: process.env,
76
- });
77
-
78
- child.once("error", (error) => rejectPromise(error));
79
- child.once("exit", (code) => {
80
- if (code === 0) {
81
- resolvePromise();
82
- return;
83
- }
84
- rejectPromise(new Error(`Command failed (${code ?? "unknown"}): ${pretty}`));
85
- });
86
- });
87
- }
88
-
89
- async function installLocalPluginDeps(localExtensionPackages) {
90
- await run(npmCommand, ["install", "--prefix", pluginSdkDir]);
91
- for (const item of localExtensionPackages) {
92
- await run(npmCommand, ["install", "--prefix", item.dir]);
93
- }
94
- }
95
-
96
- async function checkLocalPlugins(localExtensionPackages) {
97
- for (const item of localExtensionPackages) {
98
- await run(npmCommand, ["run", "check", "--prefix", item.dir]);
99
- }
100
- }
101
-
102
- async function buildLocalPlugins(localExtensionPackages) {
103
- for (const item of localExtensionPackages) {
104
- await run(npmCommand, ["run", "build", "--prefix", item.dir]);
105
- }
106
- }
107
-
108
- async function installToExtensionStore(localExtensionPackages) {
109
- for (const item of localExtensionPackages) {
110
- await run(nodeCommand, [
111
- "--import",
112
- "tsx",
113
- "src/main.ts",
114
- "extension",
115
- "install",
116
- `file:./${item.dir}`,
117
- ]);
118
- }
119
- }
120
-
121
- async function listExtensionStore() {
122
- await run(nodeCommand, ["--import", "tsx", "src/main.ts", "extension", "list"]);
123
- }
124
-
125
- async function main() {
126
- const [command] = process.argv.slice(2);
127
-
128
- if (!command || command === "--help" || command === "-h") {
129
- printUsage();
130
- process.exit(command ? 0 : 1);
131
- }
132
-
133
- const needsLocalPackages = command !== "list-store";
134
- const localExtensionPackages = needsLocalPackages ? await discoverLocalExtensionPackages() : [];
135
- if (needsLocalPackages && localExtensionPackages.length === 0) {
136
- throw new Error("No local extension packages found under ./plugins");
137
- }
138
-
139
- switch (command) {
140
- case "install":
141
- await installLocalPluginDeps(localExtensionPackages);
142
- return;
143
- case "check":
144
- await checkLocalPlugins(localExtensionPackages);
145
- return;
146
- case "build":
147
- await buildLocalPlugins(localExtensionPackages);
148
- return;
149
- case "install-store":
150
- await installToExtensionStore(localExtensionPackages);
151
- return;
152
- case "list-store":
153
- await listExtensionStore();
154
- return;
155
- case "setup":
156
- await installLocalPluginDeps(localExtensionPackages);
157
- await buildLocalPlugins(localExtensionPackages);
158
- await installToExtensionStore(localExtensionPackages);
159
- return;
160
- default:
161
- throw new Error(`Unknown command '${command}'`);
162
- }
163
- }
164
-
165
- main().catch((error) => {
166
- console.error(error instanceof Error ? error.message : String(error));
167
- process.exit(1);
168
- });