swarmkit 0.0.1 → 0.0.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 (85) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +194 -1
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +33 -0
  5. package/dist/commands/add.d.ts +2 -0
  6. package/dist/commands/add.js +55 -0
  7. package/dist/commands/doctor.d.ts +2 -0
  8. package/dist/commands/doctor.js +100 -0
  9. package/dist/commands/hive.d.ts +2 -0
  10. package/dist/commands/hive.js +248 -0
  11. package/dist/commands/init/phases/configure.d.ts +2 -0
  12. package/dist/commands/init/phases/configure.js +85 -0
  13. package/dist/commands/init/phases/global-setup.d.ts +2 -0
  14. package/dist/commands/init/phases/global-setup.js +81 -0
  15. package/dist/commands/init/phases/packages.d.ts +2 -0
  16. package/dist/commands/init/phases/packages.js +30 -0
  17. package/dist/commands/init/phases/project.d.ts +2 -0
  18. package/dist/commands/init/phases/project.js +54 -0
  19. package/dist/commands/init/phases/use-case.d.ts +2 -0
  20. package/dist/commands/init/phases/use-case.js +41 -0
  21. package/dist/commands/init/state.d.ts +11 -0
  22. package/dist/commands/init/state.js +8 -0
  23. package/dist/commands/init/state.test.d.ts +1 -0
  24. package/dist/commands/init/state.test.js +20 -0
  25. package/dist/commands/init/wizard.d.ts +1 -0
  26. package/dist/commands/init/wizard.js +56 -0
  27. package/dist/commands/init.d.ts +2 -0
  28. package/dist/commands/init.js +10 -0
  29. package/dist/commands/login.d.ts +2 -0
  30. package/dist/commands/login.js +91 -0
  31. package/dist/commands/logout.d.ts +2 -0
  32. package/dist/commands/logout.js +19 -0
  33. package/dist/commands/remove.d.ts +2 -0
  34. package/dist/commands/remove.js +49 -0
  35. package/dist/commands/status.d.ts +2 -0
  36. package/dist/commands/status.js +87 -0
  37. package/dist/commands/update.d.ts +2 -0
  38. package/dist/commands/update.js +54 -0
  39. package/dist/commands/whoami.d.ts +2 -0
  40. package/dist/commands/whoami.js +40 -0
  41. package/dist/config/global.d.ts +24 -0
  42. package/dist/config/global.js +71 -0
  43. package/dist/config/global.test.d.ts +1 -0
  44. package/dist/config/global.test.js +167 -0
  45. package/dist/config/keys.d.ts +10 -0
  46. package/dist/config/keys.js +47 -0
  47. package/dist/config/keys.test.d.ts +1 -0
  48. package/dist/config/keys.test.js +87 -0
  49. package/dist/doctor/checks.d.ts +31 -0
  50. package/dist/doctor/checks.js +210 -0
  51. package/dist/doctor/checks.test.d.ts +1 -0
  52. package/dist/doctor/checks.test.js +276 -0
  53. package/dist/doctor/types.d.ts +29 -0
  54. package/dist/doctor/types.js +1 -0
  55. package/dist/hub/auth-flow.d.ts +16 -0
  56. package/dist/hub/auth-flow.js +118 -0
  57. package/dist/hub/auth-flow.test.d.ts +1 -0
  58. package/dist/hub/auth-flow.test.js +98 -0
  59. package/dist/hub/client.d.ts +51 -0
  60. package/dist/hub/client.js +107 -0
  61. package/dist/hub/client.test.d.ts +1 -0
  62. package/dist/hub/client.test.js +177 -0
  63. package/dist/hub/credentials.d.ts +14 -0
  64. package/dist/hub/credentials.js +41 -0
  65. package/dist/hub/credentials.test.d.ts +1 -0
  66. package/dist/hub/credentials.test.js +102 -0
  67. package/dist/index.d.ts +16 -1
  68. package/dist/index.js +9 -2
  69. package/dist/packages/installer.d.ts +33 -0
  70. package/dist/packages/installer.js +127 -0
  71. package/dist/packages/installer.test.d.ts +1 -0
  72. package/dist/packages/installer.test.js +200 -0
  73. package/dist/packages/registry.d.ts +37 -0
  74. package/dist/packages/registry.js +179 -0
  75. package/dist/packages/registry.test.d.ts +1 -0
  76. package/dist/packages/registry.test.js +199 -0
  77. package/dist/packages/setup.d.ts +48 -0
  78. package/dist/packages/setup.js +309 -0
  79. package/dist/packages/setup.test.d.ts +1 -0
  80. package/dist/packages/setup.test.js +717 -0
  81. package/dist/utils/ui.d.ts +10 -0
  82. package/dist/utils/ui.js +47 -0
  83. package/dist/utils/ui.test.d.ts +1 -0
  84. package/dist/utils/ui.test.js +102 -0
  85. package/package.json +29 -6
@@ -0,0 +1,199 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { PACKAGES, BUNDLES, INTEGRATIONS, getBundlePackages, getActiveIntegrations, getNewIntegrations, getLostIntegrations, getNpmName, isKnownPackage, getAllPackageNames, } from "./registry.js";
3
+ describe("registry", () => {
4
+ describe("PACKAGES", () => {
5
+ it("contains all 12 packages", () => {
6
+ expect(Object.keys(PACKAGES)).toHaveLength(12);
7
+ });
8
+ it("every package has name, description, and category", () => {
9
+ for (const [key, pkg] of Object.entries(PACKAGES)) {
10
+ expect(pkg.name).toBe(key);
11
+ expect(pkg.description).toBeTruthy();
12
+ expect(pkg.category).toBeTruthy();
13
+ }
14
+ });
15
+ it("agent-iam is marked globalOnly", () => {
16
+ expect(PACKAGES["agent-iam"].globalOnly).toBe(true);
17
+ });
18
+ it("openteams and sessionlog are marked globalOnly", () => {
19
+ expect(PACKAGES["openteams"].globalOnly).toBe(true);
20
+ expect(PACKAGES["sessionlog"].globalOnly).toBe(true);
21
+ });
22
+ it("multi-agent-protocol has npmName override", () => {
23
+ expect(PACKAGES["multi-agent-protocol"].npmName).toBe("@multi-agent-protocol/sdk");
24
+ });
25
+ it("most packages do not have npmName", () => {
26
+ expect(PACKAGES["macro-agent"].npmName).toBeUndefined();
27
+ expect(PACKAGES["openteams"].npmName).toBeUndefined();
28
+ });
29
+ it("other packages are not globalOnly", () => {
30
+ expect(PACKAGES["macro-agent"].globalOnly).toBeUndefined();
31
+ expect(PACKAGES["opentasks"].globalOnly).toBeUndefined();
32
+ });
33
+ });
34
+ describe("BUNDLES", () => {
35
+ it("contains 4 bundles", () => {
36
+ expect(Object.keys(BUNDLES)).toHaveLength(4);
37
+ expect(Object.keys(BUNDLES)).toEqual(expect.arrayContaining(["solo", "team", "platform", "github"]));
38
+ });
39
+ it("solo bundle has the right packages", () => {
40
+ expect(BUNDLES.solo.packages).toEqual([
41
+ "macro-agent",
42
+ "opentasks",
43
+ "minimem",
44
+ "agent-iam",
45
+ ]);
46
+ });
47
+ it("team bundle is a superset of solo", () => {
48
+ for (const pkg of BUNDLES.solo.packages) {
49
+ expect(BUNDLES.team.packages).toContain(pkg);
50
+ }
51
+ expect(BUNDLES.team.packages).toContain("cognitive-core");
52
+ expect(BUNDLES.team.packages).toContain("skill-tree");
53
+ });
54
+ it("platform bundle is a superset of team", () => {
55
+ for (const pkg of BUNDLES.team.packages) {
56
+ expect(BUNDLES.platform.packages).toContain(pkg);
57
+ }
58
+ expect(BUNDLES.platform.packages).toContain("openswarm");
59
+ expect(BUNDLES.platform.packages).toContain("openhive");
60
+ });
61
+ it("github bundle has self-driving-repo", () => {
62
+ expect(BUNDLES.github.packages).toContain("self-driving-repo");
63
+ expect(BUNDLES.github.packages).toContain("opentasks");
64
+ expect(BUNDLES.github.packages).toContain("agent-iam");
65
+ });
66
+ it("all bundle packages reference known packages", () => {
67
+ for (const bundle of Object.values(BUNDLES)) {
68
+ for (const pkg of bundle.packages) {
69
+ expect(PACKAGES[pkg]).toBeDefined();
70
+ }
71
+ }
72
+ });
73
+ });
74
+ describe("INTEGRATIONS", () => {
75
+ it("all integrations reference known packages", () => {
76
+ for (const integration of INTEGRATIONS) {
77
+ expect(PACKAGES[integration.packages[0]]).toBeDefined();
78
+ expect(PACKAGES[integration.packages[1]]).toBeDefined();
79
+ }
80
+ });
81
+ it("all integrations have descriptions", () => {
82
+ for (const integration of INTEGRATIONS) {
83
+ expect(integration.description).toBeTruthy();
84
+ }
85
+ });
86
+ });
87
+ describe("getBundlePackages", () => {
88
+ it("returns packages for a known bundle", () => {
89
+ expect(getBundlePackages("solo")).toEqual(BUNDLES.solo.packages);
90
+ });
91
+ it("returns empty array for unknown bundle", () => {
92
+ expect(getBundlePackages("nonexistent")).toEqual([]);
93
+ });
94
+ it("returns a copy (not the original array)", () => {
95
+ const packages = getBundlePackages("solo");
96
+ packages.push("extra");
97
+ expect(getBundlePackages("solo")).not.toContain("extra");
98
+ });
99
+ });
100
+ describe("getActiveIntegrations", () => {
101
+ it("returns nothing for empty package list", () => {
102
+ expect(getActiveIntegrations([])).toEqual([]);
103
+ });
104
+ it("returns nothing for single package", () => {
105
+ expect(getActiveIntegrations(["macro-agent"])).toEqual([]);
106
+ });
107
+ it("returns integration when both packages are installed", () => {
108
+ const result = getActiveIntegrations(["macro-agent", "opentasks"]);
109
+ expect(result).toHaveLength(1);
110
+ expect(result[0].packages).toEqual(["macro-agent", "opentasks"]);
111
+ });
112
+ it("returns multiple integrations for the solo bundle", () => {
113
+ const result = getActiveIntegrations(BUNDLES.solo.packages);
114
+ expect(result.length).toBeGreaterThanOrEqual(2);
115
+ // Should include macro-agent+opentasks and agent-iam+macro-agent
116
+ const pairs = result.map((i) => i.packages.join("+"));
117
+ expect(pairs).toContain("macro-agent+opentasks");
118
+ expect(pairs).toContain("agent-iam+macro-agent");
119
+ });
120
+ it("returns all integrations for the platform bundle", () => {
121
+ const result = getActiveIntegrations(BUNDLES.platform.packages);
122
+ // platform has all packages except self-driving-repo and multi-agent-protocol
123
+ // so it should activate most integrations
124
+ expect(result.length).toBeGreaterThanOrEqual(5);
125
+ });
126
+ });
127
+ describe("getNewIntegrations", () => {
128
+ it("returns integrations that would activate with a new package", () => {
129
+ const current = ["macro-agent"];
130
+ const result = getNewIntegrations(current, "opentasks");
131
+ expect(result).toHaveLength(1);
132
+ expect(result[0].packages).toEqual(["macro-agent", "opentasks"]);
133
+ });
134
+ it("returns nothing if no new integrations would activate", () => {
135
+ const current = ["minimem"];
136
+ const result = getNewIntegrations(current, "opentasks");
137
+ expect(result).toEqual([]);
138
+ });
139
+ it("returns multiple integrations when package connects to several", () => {
140
+ const current = ["opentasks", "multi-agent-protocol", "agent-iam"];
141
+ const result = getNewIntegrations(current, "macro-agent");
142
+ expect(result.length).toBeGreaterThanOrEqual(2);
143
+ });
144
+ it("works regardless of package order in integration definition", () => {
145
+ // openswarm+macro-agent is defined as ["openswarm", "macro-agent"]
146
+ const current = ["macro-agent"];
147
+ const result = getNewIntegrations(current, "openswarm");
148
+ expect(result).toHaveLength(1);
149
+ });
150
+ });
151
+ describe("getLostIntegrations", () => {
152
+ it("returns integrations that would break when removing a package", () => {
153
+ const current = ["macro-agent", "opentasks", "agent-iam"];
154
+ const result = getLostIntegrations(current, "macro-agent");
155
+ // Removing macro-agent breaks macro-agent+opentasks and agent-iam+macro-agent
156
+ expect(result).toHaveLength(2);
157
+ });
158
+ it("returns nothing if removing a package with no active integrations", () => {
159
+ const current = ["minimem", "opentasks"];
160
+ const result = getLostIntegrations(current, "minimem");
161
+ expect(result).toEqual([]);
162
+ });
163
+ });
164
+ describe("isKnownPackage", () => {
165
+ it("returns true for known packages", () => {
166
+ expect(isKnownPackage("macro-agent")).toBe(true);
167
+ expect(isKnownPackage("minimem")).toBe(true);
168
+ expect(isKnownPackage("agent-iam")).toBe(true);
169
+ });
170
+ it("returns false for unknown packages", () => {
171
+ expect(isKnownPackage("not-a-package")).toBe(false);
172
+ expect(isKnownPackage("")).toBe(false);
173
+ });
174
+ });
175
+ describe("getNpmName", () => {
176
+ it("returns npmName when set", () => {
177
+ expect(getNpmName("multi-agent-protocol")).toBe("@multi-agent-protocol/sdk");
178
+ });
179
+ it("returns registry key when npmName is not set", () => {
180
+ expect(getNpmName("macro-agent")).toBe("macro-agent");
181
+ expect(getNpmName("openteams")).toBe("openteams");
182
+ expect(getNpmName("sessionlog")).toBe("sessionlog");
183
+ });
184
+ it("returns the input for unknown packages", () => {
185
+ expect(getNpmName("not-a-package")).toBe("not-a-package");
186
+ });
187
+ });
188
+ describe("getAllPackageNames", () => {
189
+ it("returns all 12 package names", () => {
190
+ const names = getAllPackageNames();
191
+ expect(names).toHaveLength(12);
192
+ expect(names).toContain("macro-agent");
193
+ expect(names).toContain("minimem");
194
+ expect(names).toContain("self-driving-repo");
195
+ expect(names).toContain("openteams");
196
+ expect(names).toContain("sessionlog");
197
+ });
198
+ });
199
+ });
@@ -0,0 +1,48 @@
1
+ export interface InitContext {
2
+ /** Project root directory */
3
+ cwd: string;
4
+ /** All selected packages (used for cross-package wiring) */
5
+ packages: string[];
6
+ /** Embedding provider chosen during wizard */
7
+ embeddingProvider: "openai" | "gemini" | "local" | null;
8
+ /** Stored API keys (provider → key) */
9
+ apiKeys: Record<string, string>;
10
+ }
11
+ export interface GlobalContext {
12
+ /** All selected packages */
13
+ packages: string[];
14
+ /** Embedding provider */
15
+ embeddingProvider: "openai" | "gemini" | "local" | null;
16
+ /** Stored API keys */
17
+ apiKeys: Record<string, string>;
18
+ }
19
+ export interface OpenhiveOptions {
20
+ name: string;
21
+ port: number;
22
+ authMode: string;
23
+ verification: string;
24
+ dataDir?: string;
25
+ }
26
+ export interface SetupResult {
27
+ package: string;
28
+ success: boolean;
29
+ message?: string;
30
+ }
31
+ /** Config directories each package creates at the project level */
32
+ export declare const PROJECT_CONFIG_DIRS: Record<string, string>;
33
+ /**
34
+ * Project-level packages in correct init order.
35
+ * Order matters: minimem before cognitive-core (runtime detection),
36
+ * opentasks before macro-agent (task backend wiring).
37
+ */
38
+ export declare const PROJECT_INIT_ORDER: string[];
39
+ /** Check whether a package is already initialized in a project */
40
+ export declare function isProjectInit(cwd: string, pkg: string): boolean;
41
+ /** Initialize a single project-level package */
42
+ export declare function initProjectPackage(pkg: string, ctx: InitContext): Promise<SetupResult>;
43
+ /** Config directories for global packages (relative to homedir) */
44
+ export declare const GLOBAL_CONFIG_DIRS: Record<string, string>;
45
+ /** Check whether a global package is already configured */
46
+ export declare function isGlobalInit(pkg: string): boolean;
47
+ /** Initialize a single global package */
48
+ export declare function initGlobalPackage(pkg: string, ctx: GlobalContext, openhiveOpts?: OpenhiveOptions): Promise<SetupResult>;
@@ -0,0 +1,309 @@
1
+ import { execFile } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, } from "node:fs";
4
+ import { basename, join } from "node:path";
5
+ import { homedir } from "node:os";
6
+ const execFileAsync = promisify(execFile);
7
+ // ─── Project-level setup ─────────────────────────────────────────────────────
8
+ /** Config directories each package creates at the project level */
9
+ export const PROJECT_CONFIG_DIRS = {
10
+ opentasks: ".opentasks",
11
+ minimem: ".minimem",
12
+ "cognitive-core": ".cognitive-core",
13
+ "macro-agent": ".multiagent",
14
+ "self-driving-repo": ".self-driving",
15
+ };
16
+ /**
17
+ * Project-level packages in correct init order.
18
+ * Order matters: minimem before cognitive-core (runtime detection),
19
+ * opentasks before macro-agent (task backend wiring).
20
+ */
21
+ export const PROJECT_INIT_ORDER = [
22
+ "opentasks",
23
+ "minimem",
24
+ "cognitive-core",
25
+ "macro-agent",
26
+ "self-driving-repo",
27
+ ];
28
+ /** Check whether a package is already initialized in a project */
29
+ export function isProjectInit(cwd, pkg) {
30
+ const dir = PROJECT_CONFIG_DIRS[pkg];
31
+ return dir ? existsSync(join(cwd, dir)) : false;
32
+ }
33
+ /** Initialize a single project-level package */
34
+ export async function initProjectPackage(pkg, ctx) {
35
+ switch (pkg) {
36
+ case "opentasks":
37
+ return shellInit("opentasks", ["init", "--name", getProjectName(ctx.cwd)], ctx.cwd);
38
+ case "minimem":
39
+ return initMinimem(ctx);
40
+ case "cognitive-core":
41
+ return shellInit("cognitive-core", ["init"], ctx.cwd);
42
+ case "macro-agent":
43
+ return initMacroAgent(ctx);
44
+ case "self-driving-repo":
45
+ return shellInit("sdr", ["init", "-t", "triage-only"], ctx.cwd);
46
+ default:
47
+ return { package: pkg, success: false, message: "Unknown package" };
48
+ }
49
+ }
50
+ // ─── Global-level setup ──────────────────────────────────────────────────────
51
+ /** Config directories for global packages (relative to homedir) */
52
+ export const GLOBAL_CONFIG_DIRS = {
53
+ "agent-iam": ".agent-credentials",
54
+ "skill-tree": ".skill-tree",
55
+ openswarm: ".openswarm",
56
+ openhive: ".openhive",
57
+ };
58
+ /** Check whether a global package is already configured */
59
+ export function isGlobalInit(pkg) {
60
+ const dir = GLOBAL_CONFIG_DIRS[pkg];
61
+ if (!dir)
62
+ return false;
63
+ return existsSync(join(homedir(), dir));
64
+ }
65
+ /** Initialize a single global package */
66
+ export async function initGlobalPackage(pkg, ctx, openhiveOpts) {
67
+ switch (pkg) {
68
+ case "agent-iam":
69
+ return initAgentIam(ctx);
70
+ case "skill-tree":
71
+ return initSkillTree();
72
+ case "openswarm":
73
+ return initOpenswarm(ctx);
74
+ case "openhive":
75
+ return openhiveOpts
76
+ ? initOpenhive(openhiveOpts)
77
+ : {
78
+ package: "openhive",
79
+ success: false,
80
+ message: "No openhive options provided",
81
+ };
82
+ case "openteams":
83
+ return { package: "openteams", success: true, message: "no setup required" };
84
+ case "sessionlog":
85
+ return { package: "sessionlog", success: true, message: "no setup required" };
86
+ default:
87
+ return { package: pkg, success: false, message: "Unknown package" };
88
+ }
89
+ }
90
+ // ─── Package-specific init functions ─────────────────────────────────────────
91
+ /** Build a clean env for child processes (strips test-runner vars like VITEST) */
92
+ function cleanEnv() {
93
+ const env = { ...process.env };
94
+ delete env.VITEST;
95
+ delete env.VITEST_POOL_ID;
96
+ delete env.VITEST_WORKER_ID;
97
+ return env;
98
+ }
99
+ /** Shell out to a package's CLI init command */
100
+ async function shellInit(command, args, cwd) {
101
+ const pkg = command === "sdr" ? "self-driving-repo" : command;
102
+ try {
103
+ await execFileAsync(command, args, { cwd, timeout: 30_000, env: cleanEnv() });
104
+ return { package: pkg, success: true };
105
+ }
106
+ catch (err) {
107
+ return { package: pkg, success: false, message: formatError(err) };
108
+ }
109
+ }
110
+ async function initMinimem(ctx) {
111
+ try {
112
+ await execFileAsync("minimem", ["init"], {
113
+ cwd: ctx.cwd,
114
+ timeout: 30_000,
115
+ env: cleanEnv(),
116
+ });
117
+ // Patch embedding provider if configured
118
+ if (ctx.embeddingProvider && ctx.embeddingProvider !== "local") {
119
+ const configPath = join(ctx.cwd, ".minimem", "config.json");
120
+ if (existsSync(configPath)) {
121
+ try {
122
+ const config = JSON.parse(readFileSync(configPath, "utf-8"));
123
+ config.embedding = config.embedding || {};
124
+ config.embedding.provider = ctx.embeddingProvider;
125
+ writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
126
+ }
127
+ catch {
128
+ // Non-fatal — user can configure manually
129
+ }
130
+ }
131
+ }
132
+ return { package: "minimem", success: true };
133
+ }
134
+ catch (err) {
135
+ return { package: "minimem", success: false, message: formatError(err) };
136
+ }
137
+ }
138
+ async function initMacroAgent(ctx) {
139
+ try {
140
+ const configDir = join(ctx.cwd, ".multiagent");
141
+ mkdirSync(configDir, { recursive: true });
142
+ const config = {
143
+ team: "default",
144
+ port: 3001,
145
+ host: "localhost",
146
+ };
147
+ // Wire up opentasks if selected
148
+ if (ctx.packages.includes("opentasks")) {
149
+ config.task = {
150
+ backend: "opentasks",
151
+ opentasks: { auto_start: true },
152
+ };
153
+ }
154
+ writeFileSync(join(configDir, "config.json"), JSON.stringify(config, null, 2) + "\n");
155
+ return { package: "macro-agent", success: true };
156
+ }
157
+ catch (err) {
158
+ return {
159
+ package: "macro-agent",
160
+ success: false,
161
+ message: formatError(err),
162
+ };
163
+ }
164
+ }
165
+ async function initAgentIam(ctx) {
166
+ try {
167
+ const credDir = join(homedir(), ".agent-credentials");
168
+ if (!existsSync(credDir)) {
169
+ mkdirSync(credDir, { recursive: true, mode: 0o700 });
170
+ }
171
+ // Register stored API keys with agent-iam
172
+ const env = { ...cleanEnv(), HOME: homedir() };
173
+ for (const [provider, key] of Object.entries(ctx.apiKeys)) {
174
+ if (["anthropic", "openai", "gemini"].includes(provider)) {
175
+ try {
176
+ await execFileAsync("agent-iam", [
177
+ "apikey",
178
+ "add",
179
+ "--name",
180
+ provider,
181
+ "--provider",
182
+ provider,
183
+ "--key",
184
+ key,
185
+ ], { timeout: 15_000, env });
186
+ }
187
+ catch {
188
+ // Non-fatal — agent-iam CLI may not be fully installed yet
189
+ }
190
+ }
191
+ }
192
+ return { package: "agent-iam", success: true };
193
+ }
194
+ catch (err) {
195
+ return {
196
+ package: "agent-iam",
197
+ success: false,
198
+ message: formatError(err),
199
+ };
200
+ }
201
+ }
202
+ async function initSkillTree() {
203
+ const configPath = join(homedir(), ".skill-tree", "config.yaml");
204
+ if (existsSync(configPath)) {
205
+ return {
206
+ package: "skill-tree",
207
+ success: true,
208
+ message: "already configured",
209
+ };
210
+ }
211
+ try {
212
+ const env = { ...cleanEnv(), HOME: homedir() };
213
+ await execFileAsync("skill-tree", ["config", "init"], {
214
+ timeout: 15_000,
215
+ env,
216
+ });
217
+ return { package: "skill-tree", success: true };
218
+ }
219
+ catch (err) {
220
+ return {
221
+ package: "skill-tree",
222
+ success: false,
223
+ message: formatError(err),
224
+ };
225
+ }
226
+ }
227
+ async function initOpenswarm(ctx) {
228
+ const configDir = join(homedir(), ".openswarm");
229
+ const configPath = join(configDir, "server.json");
230
+ if (existsSync(configPath)) {
231
+ return {
232
+ package: "openswarm",
233
+ success: true,
234
+ message: "already configured",
235
+ };
236
+ }
237
+ try {
238
+ mkdirSync(configDir, { recursive: true });
239
+ const config = {
240
+ host: "localhost",
241
+ port: 3000,
242
+ auth: { mode: "none" },
243
+ storage: { type: "memory" },
244
+ logging: { level: "info" },
245
+ };
246
+ // Configure macro-agent adapter if installed
247
+ if (ctx.packages.includes("macro-agent")) {
248
+ config.adapter = { id: "macro-agent" };
249
+ }
250
+ writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
251
+ return { package: "openswarm", success: true };
252
+ }
253
+ catch (err) {
254
+ return {
255
+ package: "openswarm",
256
+ success: false,
257
+ message: formatError(err),
258
+ };
259
+ }
260
+ }
261
+ async function initOpenhive(opts) {
262
+ try {
263
+ const args = [
264
+ "init",
265
+ "--name",
266
+ opts.name,
267
+ "--port",
268
+ String(opts.port),
269
+ "--auth-mode",
270
+ opts.authMode,
271
+ "--verification",
272
+ opts.verification,
273
+ ];
274
+ if (opts.dataDir) {
275
+ args.unshift("--data-dir", opts.dataDir);
276
+ }
277
+ const env = { ...cleanEnv(), HOME: homedir() };
278
+ await execFileAsync("openhive", args, { timeout: 60_000, env });
279
+ return { package: "openhive", success: true };
280
+ }
281
+ catch (err) {
282
+ return {
283
+ package: "openhive",
284
+ success: false,
285
+ message: formatError(err),
286
+ };
287
+ }
288
+ }
289
+ // ─── Helpers ─────────────────────────────────────────────────────────────────
290
+ function getProjectName(cwd) {
291
+ const pkgPath = join(cwd, "package.json");
292
+ if (existsSync(pkgPath)) {
293
+ try {
294
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
295
+ if (typeof pkg.name === "string" && pkg.name)
296
+ return pkg.name;
297
+ }
298
+ catch {
299
+ // Fall through
300
+ }
301
+ }
302
+ return basename(cwd) || "project";
303
+ }
304
+ function formatError(err) {
305
+ if (err instanceof Error) {
306
+ return err.message.split("\n")[0];
307
+ }
308
+ return String(err);
309
+ }
@@ -0,0 +1 @@
1
+ export {};