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.
- package/LICENSE +21 -0
- package/README.md +194 -1
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +33 -0
- package/dist/commands/add.d.ts +2 -0
- package/dist/commands/add.js +55 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.js +100 -0
- package/dist/commands/hive.d.ts +2 -0
- package/dist/commands/hive.js +248 -0
- package/dist/commands/init/phases/configure.d.ts +2 -0
- package/dist/commands/init/phases/configure.js +85 -0
- package/dist/commands/init/phases/global-setup.d.ts +2 -0
- package/dist/commands/init/phases/global-setup.js +81 -0
- package/dist/commands/init/phases/packages.d.ts +2 -0
- package/dist/commands/init/phases/packages.js +30 -0
- package/dist/commands/init/phases/project.d.ts +2 -0
- package/dist/commands/init/phases/project.js +54 -0
- package/dist/commands/init/phases/use-case.d.ts +2 -0
- package/dist/commands/init/phases/use-case.js +41 -0
- package/dist/commands/init/state.d.ts +11 -0
- package/dist/commands/init/state.js +8 -0
- package/dist/commands/init/state.test.d.ts +1 -0
- package/dist/commands/init/state.test.js +20 -0
- package/dist/commands/init/wizard.d.ts +1 -0
- package/dist/commands/init/wizard.js +56 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +10 -0
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.js +91 -0
- package/dist/commands/logout.d.ts +2 -0
- package/dist/commands/logout.js +19 -0
- package/dist/commands/remove.d.ts +2 -0
- package/dist/commands/remove.js +49 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.js +87 -0
- package/dist/commands/update.d.ts +2 -0
- package/dist/commands/update.js +54 -0
- package/dist/commands/whoami.d.ts +2 -0
- package/dist/commands/whoami.js +40 -0
- package/dist/config/global.d.ts +24 -0
- package/dist/config/global.js +71 -0
- package/dist/config/global.test.d.ts +1 -0
- package/dist/config/global.test.js +167 -0
- package/dist/config/keys.d.ts +10 -0
- package/dist/config/keys.js +47 -0
- package/dist/config/keys.test.d.ts +1 -0
- package/dist/config/keys.test.js +87 -0
- package/dist/doctor/checks.d.ts +31 -0
- package/dist/doctor/checks.js +210 -0
- package/dist/doctor/checks.test.d.ts +1 -0
- package/dist/doctor/checks.test.js +276 -0
- package/dist/doctor/types.d.ts +29 -0
- package/dist/doctor/types.js +1 -0
- package/dist/hub/auth-flow.d.ts +16 -0
- package/dist/hub/auth-flow.js +118 -0
- package/dist/hub/auth-flow.test.d.ts +1 -0
- package/dist/hub/auth-flow.test.js +98 -0
- package/dist/hub/client.d.ts +51 -0
- package/dist/hub/client.js +107 -0
- package/dist/hub/client.test.d.ts +1 -0
- package/dist/hub/client.test.js +177 -0
- package/dist/hub/credentials.d.ts +14 -0
- package/dist/hub/credentials.js +41 -0
- package/dist/hub/credentials.test.d.ts +1 -0
- package/dist/hub/credentials.test.js +102 -0
- package/dist/index.d.ts +16 -1
- package/dist/index.js +9 -2
- package/dist/packages/installer.d.ts +33 -0
- package/dist/packages/installer.js +127 -0
- package/dist/packages/installer.test.d.ts +1 -0
- package/dist/packages/installer.test.js +200 -0
- package/dist/packages/registry.d.ts +37 -0
- package/dist/packages/registry.js +179 -0
- package/dist/packages/registry.test.d.ts +1 -0
- package/dist/packages/registry.test.js +199 -0
- package/dist/packages/setup.d.ts +48 -0
- package/dist/packages/setup.js +309 -0
- package/dist/packages/setup.test.d.ts +1 -0
- package/dist/packages/setup.test.js +717 -0
- package/dist/utils/ui.d.ts +10 -0
- package/dist/utils/ui.js +47 -0
- package/dist/utils/ui.test.d.ts +1 -0
- package/dist/utils/ui.test.js +102 -0
- package/package.json +29 -6
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
import { getNpmName } from "./registry.js";
|
|
4
|
+
const execFileAsync = promisify(execFile);
|
|
5
|
+
/**
|
|
6
|
+
* Install packages globally via npm.
|
|
7
|
+
*/
|
|
8
|
+
export async function installPackages(packages) {
|
|
9
|
+
const results = [];
|
|
10
|
+
for (const pkg of packages) {
|
|
11
|
+
const npmName = getNpmName(pkg);
|
|
12
|
+
try {
|
|
13
|
+
await execFileAsync("npm", ["install", "-g", npmName], {
|
|
14
|
+
timeout: 120_000,
|
|
15
|
+
});
|
|
16
|
+
const version = await getInstalledVersion(pkg);
|
|
17
|
+
results.push({ package: pkg, success: true, version: version ?? undefined });
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
21
|
+
results.push({ package: pkg, success: false, error: formatNpmError(message) });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return results;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Uninstall a package globally via npm.
|
|
28
|
+
*/
|
|
29
|
+
export async function uninstallPackage(packageName) {
|
|
30
|
+
const npmName = getNpmName(packageName);
|
|
31
|
+
await execFileAsync("npm", ["uninstall", "-g", npmName], {
|
|
32
|
+
timeout: 60_000,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get the currently installed global version of a package, or null if not installed.
|
|
37
|
+
*/
|
|
38
|
+
export async function getInstalledVersion(packageName) {
|
|
39
|
+
const npmName = getNpmName(packageName);
|
|
40
|
+
try {
|
|
41
|
+
const { stdout } = await execFileAsync("npm", ["list", "-g", npmName, "--json", "--depth=0"], { timeout: 15_000 });
|
|
42
|
+
const data = JSON.parse(stdout);
|
|
43
|
+
return data.dependencies?.[npmName]?.version ?? null;
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get the latest published version of a package from the registry.
|
|
51
|
+
*/
|
|
52
|
+
export async function getLatestVersion(packageName) {
|
|
53
|
+
const npmName = getNpmName(packageName);
|
|
54
|
+
try {
|
|
55
|
+
const { stdout } = await execFileAsync("npm", ["view", npmName, "version"], { timeout: 15_000 });
|
|
56
|
+
return stdout.trim() || null;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Update installed packages to their latest versions.
|
|
64
|
+
*/
|
|
65
|
+
export async function updatePackages(packages) {
|
|
66
|
+
const results = [];
|
|
67
|
+
for (const pkg of packages) {
|
|
68
|
+
const previousVersion = await getInstalledVersion(pkg);
|
|
69
|
+
const latestVersion = await getLatestVersion(pkg);
|
|
70
|
+
if (!latestVersion) {
|
|
71
|
+
results.push({
|
|
72
|
+
package: pkg,
|
|
73
|
+
previousVersion,
|
|
74
|
+
newVersion: null,
|
|
75
|
+
updated: false,
|
|
76
|
+
error: "Could not fetch latest version",
|
|
77
|
+
});
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (previousVersion === latestVersion) {
|
|
81
|
+
results.push({
|
|
82
|
+
package: pkg,
|
|
83
|
+
previousVersion,
|
|
84
|
+
newVersion: latestVersion,
|
|
85
|
+
updated: false,
|
|
86
|
+
});
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
const npmName = getNpmName(pkg);
|
|
90
|
+
try {
|
|
91
|
+
await execFileAsync("npm", ["install", "-g", `${npmName}@latest`], {
|
|
92
|
+
timeout: 120_000,
|
|
93
|
+
});
|
|
94
|
+
const newVersion = await getInstalledVersion(pkg);
|
|
95
|
+
results.push({
|
|
96
|
+
package: pkg,
|
|
97
|
+
previousVersion,
|
|
98
|
+
newVersion,
|
|
99
|
+
updated: true,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
104
|
+
results.push({
|
|
105
|
+
package: pkg,
|
|
106
|
+
previousVersion,
|
|
107
|
+
newVersion: null,
|
|
108
|
+
updated: false,
|
|
109
|
+
error: formatNpmError(message),
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return results;
|
|
114
|
+
}
|
|
115
|
+
function formatNpmError(message) {
|
|
116
|
+
if (message.includes("EACCES") || message.includes("permission")) {
|
|
117
|
+
return "Permission denied — try running with sudo or configure npm prefix";
|
|
118
|
+
}
|
|
119
|
+
if (message.includes("ENOTFOUND") || message.includes("network")) {
|
|
120
|
+
return "Network error — check your internet connection";
|
|
121
|
+
}
|
|
122
|
+
if (message.includes("404") || message.includes("Not Found")) {
|
|
123
|
+
return "Package not found in npm registry";
|
|
124
|
+
}
|
|
125
|
+
// Return first line of error to keep it concise
|
|
126
|
+
return message.split("\n")[0];
|
|
127
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
+
// Mock child_process.execFile
|
|
3
|
+
const mockExecFile = vi.fn();
|
|
4
|
+
vi.mock("node:child_process", () => ({
|
|
5
|
+
execFile: mockExecFile,
|
|
6
|
+
}));
|
|
7
|
+
// Mock promisify to return our mock
|
|
8
|
+
vi.mock("node:util", async () => {
|
|
9
|
+
const actual = await vi.importActual("node:util");
|
|
10
|
+
return {
|
|
11
|
+
...actual,
|
|
12
|
+
promisify: () => mockExecFile,
|
|
13
|
+
};
|
|
14
|
+
});
|
|
15
|
+
const { installPackages, uninstallPackage, getInstalledVersion, getLatestVersion, updatePackages, } = await import("./installer.js");
|
|
16
|
+
describe("installer", () => {
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
mockExecFile.mockReset();
|
|
19
|
+
});
|
|
20
|
+
describe("getInstalledVersion", () => {
|
|
21
|
+
it("returns version when package is installed", async () => {
|
|
22
|
+
mockExecFile.mockResolvedValueOnce({
|
|
23
|
+
stdout: JSON.stringify({
|
|
24
|
+
dependencies: { minimem: { version: "0.1.0" } },
|
|
25
|
+
}),
|
|
26
|
+
});
|
|
27
|
+
const version = await getInstalledVersion("minimem");
|
|
28
|
+
expect(version).toBe("0.1.0");
|
|
29
|
+
expect(mockExecFile).toHaveBeenCalledWith("npm", ["list", "-g", "minimem", "--json", "--depth=0"], { timeout: 15_000 });
|
|
30
|
+
});
|
|
31
|
+
it("returns null when package is not installed", async () => {
|
|
32
|
+
mockExecFile.mockRejectedValueOnce(new Error("not found"));
|
|
33
|
+
const version = await getInstalledVersion("not-installed");
|
|
34
|
+
expect(version).toBeNull();
|
|
35
|
+
});
|
|
36
|
+
it("returns null when dependencies field is missing", async () => {
|
|
37
|
+
mockExecFile.mockResolvedValueOnce({ stdout: JSON.stringify({}) });
|
|
38
|
+
const version = await getInstalledVersion("minimem");
|
|
39
|
+
expect(version).toBeNull();
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
describe("getLatestVersion", () => {
|
|
43
|
+
it("returns version from npm registry", async () => {
|
|
44
|
+
mockExecFile.mockResolvedValueOnce({ stdout: "0.2.0\n" });
|
|
45
|
+
const version = await getLatestVersion("minimem");
|
|
46
|
+
expect(version).toBe("0.2.0");
|
|
47
|
+
expect(mockExecFile).toHaveBeenCalledWith("npm", ["view", "minimem", "version"], { timeout: 15_000 });
|
|
48
|
+
});
|
|
49
|
+
it("returns null on network error", async () => {
|
|
50
|
+
mockExecFile.mockRejectedValueOnce(new Error("ENOTFOUND"));
|
|
51
|
+
const version = await getLatestVersion("minimem");
|
|
52
|
+
expect(version).toBeNull();
|
|
53
|
+
});
|
|
54
|
+
it("returns null for empty stdout", async () => {
|
|
55
|
+
mockExecFile.mockResolvedValueOnce({ stdout: "" });
|
|
56
|
+
const version = await getLatestVersion("minimem");
|
|
57
|
+
expect(version).toBeNull();
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
describe("installPackages", () => {
|
|
61
|
+
it("installs a single package successfully", async () => {
|
|
62
|
+
// First call: npm install -g
|
|
63
|
+
mockExecFile.mockResolvedValueOnce({ stdout: "", stderr: "" });
|
|
64
|
+
// Second call: npm list -g (getInstalledVersion)
|
|
65
|
+
mockExecFile.mockResolvedValueOnce({
|
|
66
|
+
stdout: JSON.stringify({
|
|
67
|
+
dependencies: { minimem: { version: "0.1.0" } },
|
|
68
|
+
}),
|
|
69
|
+
});
|
|
70
|
+
const results = await installPackages(["minimem"]);
|
|
71
|
+
expect(results).toHaveLength(1);
|
|
72
|
+
expect(results[0]).toEqual({
|
|
73
|
+
package: "minimem",
|
|
74
|
+
success: true,
|
|
75
|
+
version: "0.1.0",
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
it("reports failure on install error", async () => {
|
|
79
|
+
mockExecFile.mockRejectedValueOnce(new Error("EACCES permission denied"));
|
|
80
|
+
const results = await installPackages(["minimem"]);
|
|
81
|
+
expect(results).toHaveLength(1);
|
|
82
|
+
expect(results[0].success).toBe(false);
|
|
83
|
+
expect(results[0].error).toContain("Permission denied");
|
|
84
|
+
});
|
|
85
|
+
it("installs multiple packages sequentially", async () => {
|
|
86
|
+
// Package 1: success
|
|
87
|
+
mockExecFile.mockResolvedValueOnce({ stdout: "" });
|
|
88
|
+
mockExecFile.mockResolvedValueOnce({
|
|
89
|
+
stdout: JSON.stringify({
|
|
90
|
+
dependencies: { minimem: { version: "0.1.0" } },
|
|
91
|
+
}),
|
|
92
|
+
});
|
|
93
|
+
// Package 2: success
|
|
94
|
+
mockExecFile.mockResolvedValueOnce({ stdout: "" });
|
|
95
|
+
mockExecFile.mockResolvedValueOnce({
|
|
96
|
+
stdout: JSON.stringify({
|
|
97
|
+
dependencies: { opentasks: { version: "0.0.3" } },
|
|
98
|
+
}),
|
|
99
|
+
});
|
|
100
|
+
const results = await installPackages(["minimem", "opentasks"]);
|
|
101
|
+
expect(results).toHaveLength(2);
|
|
102
|
+
expect(results[0].success).toBe(true);
|
|
103
|
+
expect(results[1].success).toBe(true);
|
|
104
|
+
});
|
|
105
|
+
it("handles mixed success and failure", async () => {
|
|
106
|
+
// Package 1: success
|
|
107
|
+
mockExecFile.mockResolvedValueOnce({ stdout: "" });
|
|
108
|
+
mockExecFile.mockResolvedValueOnce({
|
|
109
|
+
stdout: JSON.stringify({
|
|
110
|
+
dependencies: { minimem: { version: "0.1.0" } },
|
|
111
|
+
}),
|
|
112
|
+
});
|
|
113
|
+
// Package 2: failure
|
|
114
|
+
mockExecFile.mockRejectedValueOnce(new Error("404 Not Found"));
|
|
115
|
+
const results = await installPackages(["minimem", "bad-package"]);
|
|
116
|
+
expect(results[0].success).toBe(true);
|
|
117
|
+
expect(results[1].success).toBe(false);
|
|
118
|
+
expect(results[1].error).toContain("not found");
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
describe("uninstallPackage", () => {
|
|
122
|
+
it("calls npm uninstall -g", async () => {
|
|
123
|
+
mockExecFile.mockResolvedValueOnce({ stdout: "" });
|
|
124
|
+
await uninstallPackage("minimem");
|
|
125
|
+
expect(mockExecFile).toHaveBeenCalledWith("npm", ["uninstall", "-g", "minimem"], { timeout: 60_000 });
|
|
126
|
+
});
|
|
127
|
+
it("throws on failure", async () => {
|
|
128
|
+
mockExecFile.mockRejectedValueOnce(new Error("failed"));
|
|
129
|
+
await expect(uninstallPackage("minimem")).rejects.toThrow("failed");
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
describe("updatePackages", () => {
|
|
133
|
+
it("reports package as up to date when versions match", async () => {
|
|
134
|
+
// getInstalledVersion
|
|
135
|
+
mockExecFile.mockResolvedValueOnce({
|
|
136
|
+
stdout: JSON.stringify({
|
|
137
|
+
dependencies: { minimem: { version: "0.1.0" } },
|
|
138
|
+
}),
|
|
139
|
+
});
|
|
140
|
+
// getLatestVersion
|
|
141
|
+
mockExecFile.mockResolvedValueOnce({ stdout: "0.1.0\n" });
|
|
142
|
+
const results = await updatePackages(["minimem"]);
|
|
143
|
+
expect(results).toHaveLength(1);
|
|
144
|
+
expect(results[0].updated).toBe(false);
|
|
145
|
+
expect(results[0].previousVersion).toBe("0.1.0");
|
|
146
|
+
expect(results[0].newVersion).toBe("0.1.0");
|
|
147
|
+
});
|
|
148
|
+
it("updates package when newer version is available", async () => {
|
|
149
|
+
// getInstalledVersion (before)
|
|
150
|
+
mockExecFile.mockResolvedValueOnce({
|
|
151
|
+
stdout: JSON.stringify({
|
|
152
|
+
dependencies: { minimem: { version: "0.1.0" } },
|
|
153
|
+
}),
|
|
154
|
+
});
|
|
155
|
+
// getLatestVersion
|
|
156
|
+
mockExecFile.mockResolvedValueOnce({ stdout: "0.2.0\n" });
|
|
157
|
+
// npm install -g minimem@latest
|
|
158
|
+
mockExecFile.mockResolvedValueOnce({ stdout: "" });
|
|
159
|
+
// getInstalledVersion (after)
|
|
160
|
+
mockExecFile.mockResolvedValueOnce({
|
|
161
|
+
stdout: JSON.stringify({
|
|
162
|
+
dependencies: { minimem: { version: "0.2.0" } },
|
|
163
|
+
}),
|
|
164
|
+
});
|
|
165
|
+
const results = await updatePackages(["minimem"]);
|
|
166
|
+
expect(results).toHaveLength(1);
|
|
167
|
+
expect(results[0].updated).toBe(true);
|
|
168
|
+
expect(results[0].previousVersion).toBe("0.1.0");
|
|
169
|
+
expect(results[0].newVersion).toBe("0.2.0");
|
|
170
|
+
});
|
|
171
|
+
it("reports error when latest version cannot be fetched", async () => {
|
|
172
|
+
// getInstalledVersion
|
|
173
|
+
mockExecFile.mockResolvedValueOnce({
|
|
174
|
+
stdout: JSON.stringify({
|
|
175
|
+
dependencies: { minimem: { version: "0.1.0" } },
|
|
176
|
+
}),
|
|
177
|
+
});
|
|
178
|
+
// getLatestVersion fails
|
|
179
|
+
mockExecFile.mockRejectedValueOnce(new Error("network error"));
|
|
180
|
+
const results = await updatePackages(["minimem"]);
|
|
181
|
+
expect(results[0].updated).toBe(false);
|
|
182
|
+
expect(results[0].error).toBe("Could not fetch latest version");
|
|
183
|
+
});
|
|
184
|
+
it("reports error when install fails during update", async () => {
|
|
185
|
+
// getInstalledVersion
|
|
186
|
+
mockExecFile.mockResolvedValueOnce({
|
|
187
|
+
stdout: JSON.stringify({
|
|
188
|
+
dependencies: { minimem: { version: "0.1.0" } },
|
|
189
|
+
}),
|
|
190
|
+
});
|
|
191
|
+
// getLatestVersion
|
|
192
|
+
mockExecFile.mockResolvedValueOnce({ stdout: "0.2.0\n" });
|
|
193
|
+
// npm install fails
|
|
194
|
+
mockExecFile.mockRejectedValueOnce(new Error("EACCES permission denied"));
|
|
195
|
+
const results = await updatePackages(["minimem"]);
|
|
196
|
+
expect(results[0].updated).toBe(false);
|
|
197
|
+
expect(results[0].error).toContain("Permission denied");
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export interface PackageDefinition {
|
|
2
|
+
/** npm package name */
|
|
3
|
+
name: string;
|
|
4
|
+
/** npm package name if different from `name` (e.g. scoped packages) */
|
|
5
|
+
npmName?: string;
|
|
6
|
+
/** Short description */
|
|
7
|
+
description: string;
|
|
8
|
+
/** Layer in the stack */
|
|
9
|
+
category: "orchestration" | "protocol" | "tasks" | "security" | "interface" | "learning" | "observability";
|
|
10
|
+
/** No per-project config — global only */
|
|
11
|
+
globalOnly?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface BundleDefinition {
|
|
14
|
+
name: string;
|
|
15
|
+
label: string;
|
|
16
|
+
description: string;
|
|
17
|
+
packages: string[];
|
|
18
|
+
}
|
|
19
|
+
export interface Integration {
|
|
20
|
+
packages: [string, string];
|
|
21
|
+
description: string;
|
|
22
|
+
}
|
|
23
|
+
export declare const PACKAGES: Record<string, PackageDefinition>;
|
|
24
|
+
export declare const BUNDLES: Record<string, BundleDefinition>;
|
|
25
|
+
export declare const INTEGRATIONS: Integration[];
|
|
26
|
+
/** Get all package names in a bundle */
|
|
27
|
+
export declare function getBundlePackages(bundleName: string): string[];
|
|
28
|
+
/** Get active integrations for a set of installed packages */
|
|
29
|
+
export declare function getActiveIntegrations(installedPackages: string[]): Integration[];
|
|
30
|
+
/** Get integrations that would activate if a new package were added */
|
|
31
|
+
export declare function getNewIntegrations(currentPackages: string[], newPackage: string): Integration[];
|
|
32
|
+
/** Get integrations that would break if a package were removed */
|
|
33
|
+
export declare function getLostIntegrations(currentPackages: string[], removedPackage: string): Integration[];
|
|
34
|
+
/** Get the npm package name for a registry key (resolves npmName override) */
|
|
35
|
+
export declare function getNpmName(registryKey: string): string;
|
|
36
|
+
export declare function isKnownPackage(name: string): boolean;
|
|
37
|
+
export declare function getAllPackageNames(): string[];
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
export const PACKAGES = {
|
|
2
|
+
"macro-agent": {
|
|
3
|
+
name: "macro-agent",
|
|
4
|
+
description: "Multi-agent orchestration for hierarchical Claude Code agents",
|
|
5
|
+
category: "orchestration",
|
|
6
|
+
},
|
|
7
|
+
"self-driving-repo": {
|
|
8
|
+
name: "self-driving-repo",
|
|
9
|
+
description: "Event-driven workflow engine for autonomous GitHub SDLC",
|
|
10
|
+
category: "orchestration",
|
|
11
|
+
},
|
|
12
|
+
"multi-agent-protocol": {
|
|
13
|
+
name: "multi-agent-protocol",
|
|
14
|
+
npmName: "@multi-agent-protocol/sdk",
|
|
15
|
+
description: "JSON-RPC protocol for observing and coordinating agent systems",
|
|
16
|
+
category: "protocol",
|
|
17
|
+
},
|
|
18
|
+
opentasks: {
|
|
19
|
+
name: "opentasks",
|
|
20
|
+
description: "Cross-system graph for tasks, specs, and relationships",
|
|
21
|
+
category: "tasks",
|
|
22
|
+
},
|
|
23
|
+
"agent-iam": {
|
|
24
|
+
name: "agent-iam",
|
|
25
|
+
description: "Capability-based credential broker for AI agents",
|
|
26
|
+
category: "security",
|
|
27
|
+
globalOnly: true,
|
|
28
|
+
},
|
|
29
|
+
openswarm: {
|
|
30
|
+
name: "openswarm",
|
|
31
|
+
description: "Multi-agent terminal UI and MAP server host",
|
|
32
|
+
category: "interface",
|
|
33
|
+
},
|
|
34
|
+
openhive: {
|
|
35
|
+
name: "openhive",
|
|
36
|
+
description: "Self-hostable social network and coordination hub for agents",
|
|
37
|
+
category: "interface",
|
|
38
|
+
},
|
|
39
|
+
"cognitive-core": {
|
|
40
|
+
name: "cognitive-core",
|
|
41
|
+
description: "Learning system — trajectories to playbooks to guidance",
|
|
42
|
+
category: "learning",
|
|
43
|
+
},
|
|
44
|
+
minimem: {
|
|
45
|
+
name: "minimem",
|
|
46
|
+
description: "File-based memory with hybrid vector + full-text search",
|
|
47
|
+
category: "learning",
|
|
48
|
+
},
|
|
49
|
+
"skill-tree": {
|
|
50
|
+
name: "skill-tree",
|
|
51
|
+
description: "Versioned skill extraction, evolution, and serving",
|
|
52
|
+
category: "learning",
|
|
53
|
+
},
|
|
54
|
+
openteams: {
|
|
55
|
+
name: "openteams",
|
|
56
|
+
description: "Team topology definitions and agent role generation",
|
|
57
|
+
category: "orchestration",
|
|
58
|
+
globalOnly: true,
|
|
59
|
+
},
|
|
60
|
+
sessionlog: {
|
|
61
|
+
name: "sessionlog",
|
|
62
|
+
description: "Git-integrated session capture with rewind and search",
|
|
63
|
+
category: "observability",
|
|
64
|
+
globalOnly: true,
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
export const BUNDLES = {
|
|
68
|
+
solo: {
|
|
69
|
+
name: "solo",
|
|
70
|
+
label: "Local agent development",
|
|
71
|
+
description: "Single developer running local agents",
|
|
72
|
+
packages: ["macro-agent", "opentasks", "minimem", "agent-iam"],
|
|
73
|
+
},
|
|
74
|
+
team: {
|
|
75
|
+
name: "team",
|
|
76
|
+
label: "Multi-agent team with learning",
|
|
77
|
+
description: "Agents that learn and share skills across a team",
|
|
78
|
+
packages: [
|
|
79
|
+
"macro-agent",
|
|
80
|
+
"opentasks",
|
|
81
|
+
"minimem",
|
|
82
|
+
"agent-iam",
|
|
83
|
+
"cognitive-core",
|
|
84
|
+
"skill-tree",
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
platform: {
|
|
88
|
+
name: "platform",
|
|
89
|
+
label: "Full self-hosted platform",
|
|
90
|
+
description: "Complete platform with UI, agent hub, and learning",
|
|
91
|
+
packages: [
|
|
92
|
+
"macro-agent",
|
|
93
|
+
"opentasks",
|
|
94
|
+
"minimem",
|
|
95
|
+
"agent-iam",
|
|
96
|
+
"cognitive-core",
|
|
97
|
+
"skill-tree",
|
|
98
|
+
"openswarm",
|
|
99
|
+
"openhive",
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
github: {
|
|
103
|
+
name: "github",
|
|
104
|
+
label: "Autonomous GitHub workflows",
|
|
105
|
+
description: "Event-driven agents for GitHub SDLC automation",
|
|
106
|
+
packages: ["self-driving-repo", "opentasks", "agent-iam"],
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
export const INTEGRATIONS = [
|
|
110
|
+
{
|
|
111
|
+
packages: ["macro-agent", "opentasks"],
|
|
112
|
+
description: "macro-agent uses opentasks as task backend",
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
packages: ["macro-agent", "multi-agent-protocol"],
|
|
116
|
+
description: "macro-agent implements MAP for agent observation",
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
packages: ["openswarm", "macro-agent"],
|
|
120
|
+
description: "openswarm's macro-agent plugin provides TUI management",
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
packages: ["openhive", "openswarm"],
|
|
124
|
+
description: "openhive hosts openswarm instances and acts as MAP Hub",
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
packages: ["cognitive-core", "minimem"],
|
|
128
|
+
description: "cognitive-core uses minimem as search layer",
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
packages: ["cognitive-core", "skill-tree"],
|
|
132
|
+
description: "skill-tree delegates to cognitive-core for batch learning",
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
packages: ["agent-iam", "macro-agent"],
|
|
136
|
+
description: "macro-agent uses agent-iam for agent credential management",
|
|
137
|
+
},
|
|
138
|
+
];
|
|
139
|
+
/** Get all package names in a bundle */
|
|
140
|
+
export function getBundlePackages(bundleName) {
|
|
141
|
+
const bundle = BUNDLES[bundleName];
|
|
142
|
+
if (!bundle)
|
|
143
|
+
return [];
|
|
144
|
+
return [...bundle.packages];
|
|
145
|
+
}
|
|
146
|
+
/** Get active integrations for a set of installed packages */
|
|
147
|
+
export function getActiveIntegrations(installedPackages) {
|
|
148
|
+
const installed = new Set(installedPackages);
|
|
149
|
+
return INTEGRATIONS.filter((i) => installed.has(i.packages[0]) && installed.has(i.packages[1]));
|
|
150
|
+
}
|
|
151
|
+
/** Get integrations that would activate if a new package were added */
|
|
152
|
+
export function getNewIntegrations(currentPackages, newPackage) {
|
|
153
|
+
const current = new Set(currentPackages);
|
|
154
|
+
return INTEGRATIONS.filter((i) => {
|
|
155
|
+
const [a, b] = i.packages;
|
|
156
|
+
return ((a === newPackage && current.has(b)) ||
|
|
157
|
+
(b === newPackage && current.has(a)));
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
/** Get integrations that would break if a package were removed */
|
|
161
|
+
export function getLostIntegrations(currentPackages, removedPackage) {
|
|
162
|
+
const remaining = new Set(currentPackages.filter((p) => p !== removedPackage));
|
|
163
|
+
return INTEGRATIONS.filter((i) => {
|
|
164
|
+
const [a, b] = i.packages;
|
|
165
|
+
return ((a === removedPackage && remaining.has(b)) ||
|
|
166
|
+
(b === removedPackage && remaining.has(a)));
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
/** Get the npm package name for a registry key (resolves npmName override) */
|
|
170
|
+
export function getNpmName(registryKey) {
|
|
171
|
+
const pkg = PACKAGES[registryKey];
|
|
172
|
+
return pkg?.npmName ?? registryKey;
|
|
173
|
+
}
|
|
174
|
+
export function isKnownPackage(name) {
|
|
175
|
+
return name in PACKAGES;
|
|
176
|
+
}
|
|
177
|
+
export function getAllPackageNames() {
|
|
178
|
+
return Object.keys(PACKAGES);
|
|
179
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|