@better-openclaw/core 1.0.24 → 1.0.26
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/dist/addon-stack.cjs +725 -0
- package/dist/addon-stack.cjs.map +1 -0
- package/dist/addon-stack.d.cts +23 -0
- package/dist/addon-stack.d.cts.map +1 -0
- package/dist/addon-stack.d.mts +23 -0
- package/dist/addon-stack.d.mts.map +1 -0
- package/dist/addon-stack.mjs +723 -0
- package/dist/addon-stack.mjs.map +1 -0
- package/dist/addon-stack.test.cjs +461 -0
- package/dist/addon-stack.test.cjs.map +1 -0
- package/dist/addon-stack.test.d.cts +1 -0
- package/dist/addon-stack.test.d.mts +1 -0
- package/dist/addon-stack.test.mjs +461 -0
- package/dist/addon-stack.test.mjs.map +1 -0
- package/dist/bare-metal-partition.test.cjs +20 -20
- package/dist/bare-metal-partition.test.cjs.map +1 -1
- package/dist/bare-metal-partition.test.mjs +2 -2
- package/dist/compose-validation.test.cjs +1 -1
- package/dist/composer.cjs +5 -1
- package/dist/composer.cjs.map +1 -1
- package/dist/composer.d.cts +24 -1
- package/dist/composer.d.cts.map +1 -1
- package/dist/composer.d.mts +24 -1
- package/dist/composer.d.mts.map +1 -1
- package/dist/composer.mjs +1 -1
- package/dist/composer.mjs.map +1 -1
- package/dist/composer.snapshot.test.cjs +20 -20
- package/dist/composer.snapshot.test.cjs.map +1 -1
- package/dist/composer.snapshot.test.mjs +2 -2
- package/dist/composer.test.cjs +54 -54
- package/dist/composer.test.cjs.map +1 -1
- package/dist/composer.test.mjs +2 -2
- package/dist/deployers/strip-host-ports.cjs +1 -1
- package/dist/deployers/strip-host-ports.test.cjs +26 -26
- package/dist/deployers/strip-host-ports.test.cjs.map +1 -1
- package/dist/deployers/strip-host-ports.test.mjs +1 -1
- package/dist/generate.cjs +3 -3
- package/dist/generate.mjs +3 -3
- package/dist/generate.test.cjs +56 -56
- package/dist/generate.test.cjs.map +1 -1
- package/dist/generate.test.mjs +1 -1
- package/dist/generators/bare-metal-install.test.cjs +18 -18
- package/dist/generators/bare-metal-install.test.cjs.map +1 -1
- package/dist/generators/bare-metal-install.test.mjs +1 -1
- package/dist/generators/caddy.test.cjs +13 -13
- package/dist/generators/caddy.test.cjs.map +1 -1
- package/dist/generators/caddy.test.mjs +1 -1
- package/dist/generators/clone-repos.test.cjs +27 -27
- package/dist/generators/clone-repos.test.cjs.map +1 -1
- package/dist/generators/clone-repos.test.mjs +1 -1
- package/dist/generators/env.cjs +1 -1
- package/dist/generators/env.test.cjs +17 -17
- package/dist/generators/env.test.cjs.map +1 -1
- package/dist/generators/env.test.mjs +1 -1
- package/dist/generators/health-check.test.cjs +39 -39
- package/dist/generators/health-check.test.cjs.map +1 -1
- package/dist/generators/health-check.test.mjs +1 -1
- package/dist/generators/postgres-init.cjs +5 -0
- package/dist/generators/postgres-init.cjs.map +1 -1
- package/dist/generators/postgres-init.d.cts.map +1 -1
- package/dist/generators/postgres-init.d.mts.map +1 -1
- package/dist/generators/postgres-init.mjs +5 -0
- package/dist/generators/postgres-init.mjs.map +1 -1
- package/dist/generators/scripts.test.cjs +39 -39
- package/dist/generators/scripts.test.cjs.map +1 -1
- package/dist/generators/scripts.test.mjs +1 -1
- package/dist/generators/skills.cjs +1 -1
- package/dist/generators/skills.d.cts.map +1 -1
- package/dist/generators/skills.d.mts.map +1 -1
- package/dist/generators/skills.mjs +141 -0
- package/dist/generators/skills.mjs.map +1 -1
- package/dist/generators/traefik.test.cjs +32 -32
- package/dist/generators/traefik.test.cjs.map +1 -1
- package/dist/generators/traefik.test.mjs +1 -1
- package/dist/index.cjs +21 -5
- package/dist/index.d.cts +5 -4
- package/dist/index.d.mts +5 -4
- package/dist/index.mjs +7 -6
- package/dist/migrations.test.cjs +16 -16
- package/dist/migrations.test.cjs.map +1 -1
- package/dist/migrations.test.mjs +1 -1
- package/dist/presets/presets.test.cjs +1 -1
- package/dist/presets/registry.test.cjs +14 -14
- package/dist/presets/registry.test.cjs.map +1 -1
- package/dist/presets/registry.test.mjs +1 -1
- package/dist/resolver.test.cjs +95 -95
- package/dist/resolver.test.cjs.map +1 -1
- package/dist/resolver.test.mjs +1 -1
- package/dist/{schema-eX44HhRp.d.mts → schema-BQnZrcw8.d.cts} +300 -2
- package/dist/schema-BQnZrcw8.d.cts.map +1 -0
- package/dist/{schema-tn5RK8CM.d.cts → schema-SBpL0bdI.d.mts} +300 -2
- package/dist/schema-SBpL0bdI.d.mts.map +1 -0
- package/dist/schema.cjs +148 -2
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.cts +2 -2
- package/dist/schema.d.mts +2 -2
- package/dist/schema.mjs +139 -2
- package/dist/schema.mjs.map +1 -1
- package/dist/schema.test.cjs +86 -86
- package/dist/schema.test.cjs.map +1 -1
- package/dist/schema.test.mjs +1 -1
- package/dist/services/definitions/browserless.cjs +4 -1
- package/dist/services/definitions/browserless.cjs.map +1 -1
- package/dist/services/definitions/browserless.mjs +4 -1
- package/dist/services/definitions/browserless.mjs.map +1 -1
- package/dist/services/definitions/burnlink.cjs +142 -0
- package/dist/services/definitions/burnlink.cjs.map +1 -0
- package/dist/services/definitions/burnlink.d.cts +7 -0
- package/dist/services/definitions/burnlink.d.cts.map +1 -0
- package/dist/services/definitions/burnlink.d.mts +7 -0
- package/dist/services/definitions/burnlink.d.mts.map +1 -0
- package/dist/services/definitions/burnlink.mjs +141 -0
- package/dist/services/definitions/burnlink.mjs.map +1 -0
- package/dist/services/definitions/convex.cjs +43 -1
- package/dist/services/definitions/convex.cjs.map +1 -1
- package/dist/services/definitions/convex.mjs +43 -1
- package/dist/services/definitions/convex.mjs.map +1 -1
- package/dist/services/definitions/grafana.cjs +11 -1
- package/dist/services/definitions/grafana.cjs.map +1 -1
- package/dist/services/definitions/grafana.mjs +11 -1
- package/dist/services/definitions/grafana.mjs.map +1 -1
- package/dist/services/definitions/hindsight.cjs +130 -0
- package/dist/services/definitions/hindsight.cjs.map +1 -0
- package/dist/services/definitions/hindsight.d.cts +7 -0
- package/dist/services/definitions/hindsight.d.cts.map +1 -0
- package/dist/services/definitions/hindsight.d.mts +7 -0
- package/dist/services/definitions/hindsight.d.mts.map +1 -0
- package/dist/services/definitions/hindsight.mjs +129 -0
- package/dist/services/definitions/hindsight.mjs.map +1 -0
- package/dist/services/definitions/index.cjs +9 -0
- package/dist/services/definitions/index.cjs.map +1 -1
- package/dist/services/definitions/index.d.cts +4 -1
- package/dist/services/definitions/index.d.cts.map +1 -1
- package/dist/services/definitions/index.d.mts +4 -1
- package/dist/services/definitions/index.d.mts.map +1 -1
- package/dist/services/definitions/index.mjs +7 -1
- package/dist/services/definitions/index.mjs.map +1 -1
- package/dist/services/definitions/meilisearch.cjs +11 -1
- package/dist/services/definitions/meilisearch.cjs.map +1 -1
- package/dist/services/definitions/meilisearch.mjs +11 -1
- package/dist/services/definitions/meilisearch.mjs.map +1 -1
- package/dist/services/definitions/minio.cjs +3 -1
- package/dist/services/definitions/minio.cjs.map +1 -1
- package/dist/services/definitions/minio.mjs +3 -1
- package/dist/services/definitions/minio.mjs.map +1 -1
- package/dist/services/definitions/n8n.cjs +11 -1
- package/dist/services/definitions/n8n.cjs.map +1 -1
- package/dist/services/definitions/n8n.mjs +11 -1
- package/dist/services/definitions/n8n.mjs.map +1 -1
- package/dist/services/definitions/ollama.cjs +3 -1
- package/dist/services/definitions/ollama.cjs.map +1 -1
- package/dist/services/definitions/ollama.mjs +3 -1
- package/dist/services/definitions/ollama.mjs.map +1 -1
- package/dist/services/definitions/opensandbox.cjs +149 -0
- package/dist/services/definitions/opensandbox.cjs.map +1 -0
- package/dist/services/definitions/opensandbox.d.cts +7 -0
- package/dist/services/definitions/opensandbox.d.cts.map +1 -0
- package/dist/services/definitions/opensandbox.d.mts +7 -0
- package/dist/services/definitions/opensandbox.d.mts.map +1 -0
- package/dist/services/definitions/opensandbox.mjs +148 -0
- package/dist/services/definitions/opensandbox.mjs.map +1 -0
- package/dist/services/definitions/qdrant.cjs +3 -1
- package/dist/services/definitions/qdrant.cjs.map +1 -1
- package/dist/services/definitions/qdrant.mjs +3 -1
- package/dist/services/definitions/qdrant.mjs.map +1 -1
- package/dist/services/definitions/searxng.cjs +8 -1
- package/dist/services/definitions/searxng.cjs.map +1 -1
- package/dist/services/definitions/searxng.mjs +8 -1
- package/dist/services/definitions/searxng.mjs.map +1 -1
- package/dist/services/definitions/uptime-kuma.cjs +8 -1
- package/dist/services/definitions/uptime-kuma.cjs.map +1 -1
- package/dist/services/definitions/uptime-kuma.mjs +8 -1
- package/dist/services/definitions/uptime-kuma.mjs.map +1 -1
- package/dist/services/registry.test.cjs +36 -36
- package/dist/services/registry.test.cjs.map +1 -1
- package/dist/services/registry.test.mjs +1 -1
- package/dist/{skills-BlzpHmpH.cjs → skills-BSF7iNa4.cjs} +142 -1
- package/dist/{skills-BlzpHmpH.cjs.map → skills-BSF7iNa4.cjs.map} +1 -1
- package/dist/{vi.2VT5v0um-C_jmO7m2.mjs → test.CTcmp4Su-ClCHJ3FA.mjs} +6793 -6403
- package/dist/test.CTcmp4Su-ClCHJ3FA.mjs.map +1 -0
- package/dist/{vi.2VT5v0um-iVBt6Fyq.cjs → test.CTcmp4Su-DlzTarwH.cjs} +6793 -6403
- package/dist/test.CTcmp4Su-DlzTarwH.cjs.map +1 -0
- package/dist/track-analytics.test.cjs +28 -28
- package/dist/track-analytics.test.cjs.map +1 -1
- package/dist/track-analytics.test.mjs +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +10 -2
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +10 -2
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/validator.cjs +1 -1
- package/dist/validator.test.cjs +15 -15
- package/dist/validator.test.cjs.map +1 -1
- package/dist/validator.test.mjs +2 -2
- package/dist/version-manager.test.cjs +37 -37
- package/dist/version-manager.test.cjs.map +1 -1
- package/dist/version-manager.test.mjs +1 -1
- package/package.json +4 -4
- package/src/__snapshots__/composer.snapshot.test.ts.snap +5 -0
- package/src/addon-stack.test.ts +648 -0
- package/src/addon-stack.ts +1046 -0
- package/src/composer.ts +4 -4
- package/src/generators/postgres-init.ts +2 -0
- package/src/generators/skills.ts +142 -0
- package/src/index.ts +20 -2
- package/src/schema.ts +190 -0
- package/src/services/definitions/browserless.ts +3 -0
- package/src/services/definitions/burnlink.ts +142 -0
- package/src/services/definitions/convex.ts +31 -0
- package/src/services/definitions/grafana.ts +9 -0
- package/src/services/definitions/hindsight.ts +131 -0
- package/src/services/definitions/index.ts +10 -0
- package/src/services/definitions/meilisearch.ts +9 -0
- package/src/services/definitions/minio.ts +2 -0
- package/src/services/definitions/n8n.ts +9 -0
- package/src/services/definitions/ollama.ts +2 -0
- package/src/services/definitions/opensandbox.ts +156 -0
- package/src/services/definitions/qdrant.ts +2 -0
- package/src/services/definitions/searxng.ts +3 -0
- package/src/services/definitions/uptime-kuma.ts +3 -0
- package/src/types.ts +18 -0
- package/dist/schema-eX44HhRp.d.mts.map +0 -1
- package/dist/schema-tn5RK8CM.d.cts.map +0 -1
- package/dist/vi.2VT5v0um-C_jmO7m2.mjs.map +0 -1
- package/dist/vi.2VT5v0um-iVBt6Fyq.cjs.map +0 -1
package/dist/resolver.test.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const require_test_CTcmp4Su = require("./test.CTcmp4Su-DlzTarwH.cjs");
|
|
2
2
|
const require_resolver = require("./resolver.cjs");
|
|
3
3
|
//#region src/resolver.test.ts
|
|
4
4
|
const MANDATORY_IDS = [
|
|
@@ -7,107 +7,107 @@ const MANDATORY_IDS = [
|
|
|
7
7
|
"tailscale"
|
|
8
8
|
];
|
|
9
9
|
const MANDATORY_MEMORY = 448;
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
require_test_CTcmp4Su.describe("resolve", () => {
|
|
11
|
+
require_test_CTcmp4Su.it("returns only mandatory services for empty input", () => {
|
|
12
12
|
const result = require_resolver.resolve({
|
|
13
13
|
services: [],
|
|
14
14
|
skillPacks: []
|
|
15
15
|
});
|
|
16
16
|
const ids = result.services.map((s) => s.definition.id);
|
|
17
|
-
for (const id of MANDATORY_IDS)
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
for (const id of MANDATORY_IDS) require_test_CTcmp4Su.globalExpect(ids).toContain(id);
|
|
18
|
+
require_test_CTcmp4Su.globalExpect(result.isValid).toBe(true);
|
|
19
|
+
require_test_CTcmp4Su.globalExpect(result.estimatedMemoryMB).toBe(512 + MANDATORY_MEMORY);
|
|
20
20
|
});
|
|
21
|
-
|
|
21
|
+
require_test_CTcmp4Su.it("resolves a single service alongside mandatory services", () => {
|
|
22
22
|
const result = require_resolver.resolve({
|
|
23
23
|
services: ["redis"],
|
|
24
24
|
skillPacks: []
|
|
25
25
|
});
|
|
26
26
|
const ids = result.services.map((s) => s.definition.id);
|
|
27
|
-
|
|
28
|
-
for (const id of MANDATORY_IDS)
|
|
29
|
-
|
|
27
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("redis");
|
|
28
|
+
for (const id of MANDATORY_IDS) require_test_CTcmp4Su.globalExpect(ids).toContain(id);
|
|
29
|
+
require_test_CTcmp4Su.globalExpect(result.isValid).toBe(true);
|
|
30
30
|
});
|
|
31
|
-
|
|
31
|
+
require_test_CTcmp4Su.it("auto-adds PostgreSQL when n8n is selected", () => {
|
|
32
32
|
const result = require_resolver.resolve({
|
|
33
33
|
services: ["n8n"],
|
|
34
34
|
skillPacks: []
|
|
35
35
|
});
|
|
36
36
|
const ids = result.services.map((s) => s.definition.id);
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("n8n");
|
|
38
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("postgresql");
|
|
39
|
+
require_test_CTcmp4Su.globalExpect(result.addedDependencies).toContainEqual(require_test_CTcmp4Su.globalExpect.objectContaining({ service: "postgresql" }));
|
|
40
|
+
require_test_CTcmp4Su.globalExpect(result.isValid).toBe(true);
|
|
41
41
|
});
|
|
42
|
-
|
|
42
|
+
require_test_CTcmp4Su.it("auto-adds Prometheus when Grafana is selected", () => {
|
|
43
43
|
const ids = require_resolver.resolve({
|
|
44
44
|
services: ["grafana"],
|
|
45
45
|
skillPacks: []
|
|
46
46
|
}).services.map((s) => s.definition.id);
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("grafana");
|
|
48
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("prometheus");
|
|
49
49
|
});
|
|
50
|
-
|
|
50
|
+
require_test_CTcmp4Su.it("detects Redis + Valkey conflict", () => {
|
|
51
51
|
const result = require_resolver.resolve({
|
|
52
52
|
services: ["redis", "valkey"],
|
|
53
53
|
skillPacks: []
|
|
54
54
|
});
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
require_test_CTcmp4Su.globalExpect(result.isValid).toBe(false);
|
|
56
|
+
require_test_CTcmp4Su.globalExpect(result.errors).toContainEqual(require_test_CTcmp4Su.globalExpect.objectContaining({ type: "conflict" }));
|
|
57
57
|
});
|
|
58
|
-
|
|
58
|
+
require_test_CTcmp4Su.it("detects Caddy + Traefik conflict", () => {
|
|
59
59
|
const result = require_resolver.resolve({
|
|
60
60
|
services: ["caddy", "traefik"],
|
|
61
61
|
skillPacks: []
|
|
62
62
|
});
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
require_test_CTcmp4Su.globalExpect(result.isValid).toBe(false);
|
|
64
|
+
require_test_CTcmp4Su.globalExpect(result.errors).toContainEqual(require_test_CTcmp4Su.globalExpect.objectContaining({ type: "conflict" }));
|
|
65
65
|
});
|
|
66
|
-
|
|
66
|
+
require_test_CTcmp4Su.it("expands research-agent skill pack", () => {
|
|
67
67
|
const result = require_resolver.resolve({
|
|
68
68
|
services: [],
|
|
69
69
|
skillPacks: ["research-agent"]
|
|
70
70
|
});
|
|
71
71
|
const ids = result.services.map((s) => s.definition.id);
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
72
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("qdrant");
|
|
73
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("searxng");
|
|
74
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("browserless");
|
|
75
|
+
require_test_CTcmp4Su.globalExpect(result.isValid).toBe(true);
|
|
76
76
|
});
|
|
77
|
-
|
|
77
|
+
require_test_CTcmp4Su.it("expands video-creator skill pack", () => {
|
|
78
78
|
const ids = require_resolver.resolve({
|
|
79
79
|
services: [],
|
|
80
80
|
skillPacks: ["video-creator"]
|
|
81
81
|
}).services.map((s) => s.definition.id);
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("ffmpeg");
|
|
83
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("remotion");
|
|
84
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("minio");
|
|
85
85
|
});
|
|
86
|
-
|
|
86
|
+
require_test_CTcmp4Su.it("expands dev-ops skill pack with transitive deps", () => {
|
|
87
87
|
const ids = require_resolver.resolve({
|
|
88
88
|
services: [],
|
|
89
89
|
skillPacks: ["dev-ops"]
|
|
90
90
|
}).services.map((s) => s.definition.id);
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
91
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("n8n");
|
|
92
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("redis");
|
|
93
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("uptime-kuma");
|
|
94
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("grafana");
|
|
95
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("prometheus");
|
|
96
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("postgresql");
|
|
97
97
|
});
|
|
98
|
-
|
|
99
|
-
|
|
98
|
+
require_test_CTcmp4Su.it("reports unknown service IDs", () => {
|
|
99
|
+
require_test_CTcmp4Su.globalExpect(require_resolver.resolve({
|
|
100
100
|
services: ["nonexistent"],
|
|
101
101
|
skillPacks: []
|
|
102
|
-
}).errors).toContainEqual(
|
|
102
|
+
}).errors).toContainEqual(require_test_CTcmp4Su.globalExpect.objectContaining({ type: "unknown_service" }));
|
|
103
103
|
});
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
require_test_CTcmp4Su.it("reports unknown skill pack IDs", () => {
|
|
105
|
+
require_test_CTcmp4Su.globalExpect(require_resolver.resolve({
|
|
106
106
|
services: [],
|
|
107
107
|
skillPacks: ["nonexistent-pack"]
|
|
108
|
-
}).errors).toContainEqual(
|
|
108
|
+
}).errors).toContainEqual(require_test_CTcmp4Su.globalExpect.objectContaining({ type: "unknown_skill_pack" }));
|
|
109
109
|
});
|
|
110
|
-
|
|
110
|
+
require_test_CTcmp4Su.it("does not duplicate services already selected by user", () => {
|
|
111
111
|
const qdrantCount = require_resolver.resolve({
|
|
112
112
|
services: [
|
|
113
113
|
"qdrant",
|
|
@@ -116,32 +116,32 @@ require_vi_2VT5v0um.describe("resolve", () => {
|
|
|
116
116
|
],
|
|
117
117
|
skillPacks: ["research-agent"]
|
|
118
118
|
}).services.map((s) => s.definition.id).filter((id) => id === "qdrant").length;
|
|
119
|
-
|
|
119
|
+
require_test_CTcmp4Su.globalExpect(qdrantCount).toBe(1);
|
|
120
120
|
});
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
require_test_CTcmp4Su.it("estimates memory correctly", () => {
|
|
122
|
+
require_test_CTcmp4Su.globalExpect(require_resolver.resolve({
|
|
123
123
|
services: ["redis"],
|
|
124
124
|
skillPacks: []
|
|
125
125
|
}).estimatedMemoryMB).toBe(640 + MANDATORY_MEMORY);
|
|
126
126
|
});
|
|
127
|
-
|
|
128
|
-
|
|
127
|
+
require_test_CTcmp4Su.it("adds proxy service when specified", () => {
|
|
128
|
+
require_test_CTcmp4Su.globalExpect(require_resolver.resolve({
|
|
129
129
|
services: ["redis"],
|
|
130
130
|
skillPacks: [],
|
|
131
131
|
proxy: "caddy"
|
|
132
132
|
}).services.map((s) => s.definition.id)).toContain("caddy");
|
|
133
133
|
});
|
|
134
|
-
|
|
134
|
+
require_test_CTcmp4Su.it("adds monitoring stack when flag is set", () => {
|
|
135
135
|
const ids = require_resolver.resolve({
|
|
136
136
|
services: [],
|
|
137
137
|
skillPacks: [],
|
|
138
138
|
monitoring: true
|
|
139
139
|
}).services.map((s) => s.definition.id);
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
140
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("uptime-kuma");
|
|
141
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("grafana");
|
|
142
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("prometheus");
|
|
143
143
|
});
|
|
144
|
-
|
|
144
|
+
require_test_CTcmp4Su.it("is deterministic - same input gives same output", () => {
|
|
145
145
|
const input = {
|
|
146
146
|
services: [
|
|
147
147
|
"redis",
|
|
@@ -154,56 +154,56 @@ require_vi_2VT5v0um.describe("resolve", () => {
|
|
|
154
154
|
const result2 = require_resolver.resolve(input);
|
|
155
155
|
const ids1 = result1.services.map((s) => s.definition.id);
|
|
156
156
|
const ids2 = result2.services.map((s) => s.definition.id);
|
|
157
|
-
|
|
157
|
+
require_test_CTcmp4Su.globalExpect(ids1).toEqual(ids2);
|
|
158
158
|
});
|
|
159
|
-
|
|
159
|
+
require_test_CTcmp4Su.it("topologically sorts dependencies before dependents", () => {
|
|
160
160
|
const ids = require_resolver.resolve({
|
|
161
161
|
services: ["n8n"],
|
|
162
162
|
skillPacks: []
|
|
163
163
|
}).services.map((s) => s.definition.id);
|
|
164
164
|
const pgIndex = ids.indexOf("postgresql");
|
|
165
165
|
const n8nIndex = ids.indexOf("n8n");
|
|
166
|
-
|
|
166
|
+
require_test_CTcmp4Su.globalExpect(pgIndex).toBeLessThan(n8nIndex);
|
|
167
167
|
});
|
|
168
|
-
|
|
169
|
-
|
|
168
|
+
require_test_CTcmp4Su.it("warns about GPU when AI services selected without gpu flag", () => {
|
|
169
|
+
require_test_CTcmp4Su.globalExpect(require_resolver.resolve({
|
|
170
170
|
services: ["redis"],
|
|
171
171
|
skillPacks: [],
|
|
172
172
|
gpu: false
|
|
173
173
|
}).warnings.filter((w) => w.type === "gpu")).toHaveLength(0);
|
|
174
174
|
});
|
|
175
|
-
|
|
175
|
+
require_test_CTcmp4Su.it("resolves tailscale (mandatory, always present)", () => {
|
|
176
176
|
const result = require_resolver.resolve({
|
|
177
177
|
services: [],
|
|
178
178
|
skillPacks: []
|
|
179
179
|
});
|
|
180
|
-
|
|
181
|
-
|
|
180
|
+
require_test_CTcmp4Su.globalExpect(result.services.map((s) => s.definition.id)).toContain("tailscale");
|
|
181
|
+
require_test_CTcmp4Su.globalExpect(result.isValid).toBe(true);
|
|
182
182
|
});
|
|
183
|
-
|
|
183
|
+
require_test_CTcmp4Su.it("resolves coolify and dokploy as single services", () => {
|
|
184
184
|
const result = require_resolver.resolve({
|
|
185
185
|
services: ["coolify", "dokploy"],
|
|
186
186
|
skillPacks: []
|
|
187
187
|
});
|
|
188
188
|
const ids = result.services.map((s) => s.definition.id);
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
189
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("coolify");
|
|
190
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("dokploy");
|
|
191
|
+
require_test_CTcmp4Su.globalExpect(result.isValid).toBe(true);
|
|
192
192
|
});
|
|
193
|
-
|
|
193
|
+
require_test_CTcmp4Su.it("auto-adds postgresql, redis, and livekit when lasuite-meet-backend is selected", () => {
|
|
194
194
|
const result = require_resolver.resolve({
|
|
195
195
|
services: ["lasuite-meet-backend"],
|
|
196
196
|
skillPacks: []
|
|
197
197
|
});
|
|
198
198
|
const ids = result.services.map((s) => s.definition.id);
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
199
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("lasuite-meet-backend");
|
|
200
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("postgresql");
|
|
201
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("redis");
|
|
202
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("livekit");
|
|
203
|
+
require_test_CTcmp4Su.globalExpect(result.addedDependencies.some((a) => a.service === "postgresql")).toBe(true);
|
|
204
|
+
require_test_CTcmp4Su.globalExpect(result.isValid).toBe(true);
|
|
205
205
|
});
|
|
206
|
-
|
|
206
|
+
require_test_CTcmp4Su.it("resolves La Suite Meet preset (postgresql, redis, livekit, backend, frontend, agents)", () => {
|
|
207
207
|
const lasuiteMeetServices = [
|
|
208
208
|
"postgresql",
|
|
209
209
|
"redis",
|
|
@@ -217,10 +217,10 @@ require_vi_2VT5v0um.describe("resolve", () => {
|
|
|
217
217
|
skillPacks: []
|
|
218
218
|
});
|
|
219
219
|
const ids = result.services.map((s) => s.definition.id);
|
|
220
|
-
for (const id of lasuiteMeetServices)
|
|
221
|
-
|
|
220
|
+
for (const id of lasuiteMeetServices) require_test_CTcmp4Su.globalExpect(ids).toContain(id);
|
|
221
|
+
require_test_CTcmp4Su.globalExpect(result.isValid).toBe(true);
|
|
222
222
|
});
|
|
223
|
-
|
|
223
|
+
require_test_CTcmp4Su.it("orders lasuite-meet-backend after postgresql, redis, and livekit", () => {
|
|
224
224
|
const ids = require_resolver.resolve({
|
|
225
225
|
services: ["lasuite-meet-backend", "lasuite-meet-frontend"],
|
|
226
226
|
skillPacks: []
|
|
@@ -230,39 +230,39 @@ require_vi_2VT5v0um.describe("resolve", () => {
|
|
|
230
230
|
const livekitIdx = ids.indexOf("livekit");
|
|
231
231
|
const backendIdx = ids.indexOf("lasuite-meet-backend");
|
|
232
232
|
const frontendIdx = ids.indexOf("lasuite-meet-frontend");
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
233
|
+
require_test_CTcmp4Su.globalExpect(pgIdx).toBeGreaterThanOrEqual(0);
|
|
234
|
+
require_test_CTcmp4Su.globalExpect(backendIdx).toBeGreaterThan(pgIdx);
|
|
235
|
+
require_test_CTcmp4Su.globalExpect(backendIdx).toBeGreaterThan(redisIdx);
|
|
236
|
+
require_test_CTcmp4Su.globalExpect(backendIdx).toBeGreaterThan(livekitIdx);
|
|
237
|
+
require_test_CTcmp4Su.globalExpect(frontendIdx).toBeGreaterThan(backendIdx);
|
|
238
238
|
});
|
|
239
|
-
|
|
239
|
+
require_test_CTcmp4Su.it("auto-includes mandatory services even when not selected", () => {
|
|
240
240
|
const result = require_resolver.resolve({
|
|
241
241
|
services: ["redis"],
|
|
242
242
|
skillPacks: []
|
|
243
243
|
});
|
|
244
244
|
const ids = result.services.map((s) => s.definition.id);
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
245
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("mission-control");
|
|
246
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("convex");
|
|
247
|
+
require_test_CTcmp4Su.globalExpect(ids).toContain("tailscale");
|
|
248
|
+
require_test_CTcmp4Su.globalExpect(result.services.find((s) => s.definition.id === "mission-control").addedBy).toBe("mandatory");
|
|
249
249
|
});
|
|
250
|
-
|
|
250
|
+
require_test_CTcmp4Su.it("marks user-selected mandatory services as 'user' not 'mandatory'", () => {
|
|
251
251
|
const result = require_resolver.resolve({
|
|
252
252
|
services: ["mission-control"],
|
|
253
253
|
skillPacks: []
|
|
254
254
|
});
|
|
255
|
-
|
|
256
|
-
|
|
255
|
+
require_test_CTcmp4Su.globalExpect(result.services.find((s) => s.definition.id === "mission-control").addedBy).toBe("user");
|
|
256
|
+
require_test_CTcmp4Su.globalExpect(result.services.find((s) => s.definition.id === "convex")).toBeDefined();
|
|
257
257
|
});
|
|
258
|
-
|
|
258
|
+
require_test_CTcmp4Su.it("orders convex before mission-control (dependency ordering)", () => {
|
|
259
259
|
const ids = require_resolver.resolve({
|
|
260
260
|
services: ["redis"],
|
|
261
261
|
skillPacks: []
|
|
262
262
|
}).services.map((s) => s.definition.id);
|
|
263
263
|
const convexIdx = ids.indexOf("convex");
|
|
264
264
|
const mcIdx = ids.indexOf("mission-control");
|
|
265
|
-
|
|
265
|
+
require_test_CTcmp4Su.globalExpect(convexIdx).toBeLessThan(mcIdx);
|
|
266
266
|
});
|
|
267
267
|
});
|
|
268
268
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolver.test.cjs","names":["describe","resolve","expect"],"sources":["../src/resolver.test.ts"],"sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport { resolve } from \"./resolver.js\";\n\n// Mandatory services (convex, mission-control, tailscale) are always auto-included.\n// These IDs and their combined memory are accounted for in all tests.\nconst MANDATORY_IDS = [\"convex\", \"mission-control\", \"tailscale\"];\nconst MANDATORY_MEMORY = 256 + 128 + 64; // convex + mission-control + tailscale\n\ndescribe(\"resolve\", () => {\n\tit(\"returns only mandatory services for empty input\", () => {\n\t\tconst result = resolve({ services: [], skillPacks: [] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\tfor (const id of MANDATORY_IDS) {\n\t\t\texpect(ids).toContain(id);\n\t\t}\n\t\texpect(result.isValid).toBe(true);\n\t\t// 512 (base) + mandatory services memory\n\t\texpect(result.estimatedMemoryMB).toBe(512 + MANDATORY_MEMORY);\n\t});\n\n\tit(\"resolves a single service alongside mandatory services\", () => {\n\t\tconst result = resolve({ services: [\"redis\"], skillPacks: [] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\texpect(ids).toContain(\"redis\");\n\t\tfor (const id of MANDATORY_IDS) {\n\t\t\texpect(ids).toContain(id);\n\t\t}\n\t\texpect(result.isValid).toBe(true);\n\t});\n\n\tit(\"auto-adds PostgreSQL when n8n is selected\", () => {\n\t\tconst result = resolve({ services: [\"n8n\"], skillPacks: [] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\texpect(ids).toContain(\"n8n\");\n\t\texpect(ids).toContain(\"postgresql\");\n\t\texpect(result.addedDependencies).toContainEqual(\n\t\t\texpect.objectContaining({ service: \"postgresql\" }),\n\t\t);\n\t\texpect(result.isValid).toBe(true);\n\t});\n\n\tit(\"auto-adds Prometheus when Grafana is selected\", () => {\n\t\tconst result = resolve({ services: [\"grafana\"], skillPacks: [] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\texpect(ids).toContain(\"grafana\");\n\t\texpect(ids).toContain(\"prometheus\");\n\t});\n\n\tit(\"detects Redis + Valkey conflict\", () => {\n\t\tconst result = resolve({ services: [\"redis\", \"valkey\"], skillPacks: [] });\n\t\texpect(result.isValid).toBe(false);\n\t\texpect(result.errors).toContainEqual(expect.objectContaining({ type: \"conflict\" }));\n\t});\n\n\tit(\"detects Caddy + Traefik conflict\", () => {\n\t\tconst result = resolve({ services: [\"caddy\", \"traefik\"], skillPacks: [] });\n\t\texpect(result.isValid).toBe(false);\n\t\texpect(result.errors).toContainEqual(expect.objectContaining({ type: \"conflict\" }));\n\t});\n\n\tit(\"expands research-agent skill pack\", () => {\n\t\tconst result = resolve({ services: [], skillPacks: [\"research-agent\"] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\texpect(ids).toContain(\"qdrant\");\n\t\texpect(ids).toContain(\"searxng\");\n\t\texpect(ids).toContain(\"browserless\");\n\t\texpect(result.isValid).toBe(true);\n\t});\n\n\tit(\"expands video-creator skill pack\", () => {\n\t\tconst result = resolve({ services: [], skillPacks: [\"video-creator\"] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\texpect(ids).toContain(\"ffmpeg\");\n\t\texpect(ids).toContain(\"remotion\");\n\t\texpect(ids).toContain(\"minio\");\n\t});\n\n\tit(\"expands dev-ops skill pack with transitive deps\", () => {\n\t\tconst result = resolve({ services: [], skillPacks: [\"dev-ops\"] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\texpect(ids).toContain(\"n8n\");\n\t\texpect(ids).toContain(\"redis\");\n\t\texpect(ids).toContain(\"uptime-kuma\");\n\t\texpect(ids).toContain(\"grafana\");\n\t\texpect(ids).toContain(\"prometheus\");\n\t\t// n8n requires postgresql (transitive)\n\t\texpect(ids).toContain(\"postgresql\");\n\t});\n\n\tit(\"reports unknown service IDs\", () => {\n\t\tconst result = resolve({ services: [\"nonexistent\"], skillPacks: [] });\n\t\texpect(result.errors).toContainEqual(expect.objectContaining({ type: \"unknown_service\" }));\n\t});\n\n\tit(\"reports unknown skill pack IDs\", () => {\n\t\tconst result = resolve({ services: [], skillPacks: [\"nonexistent-pack\"] });\n\t\texpect(result.errors).toContainEqual(expect.objectContaining({ type: \"unknown_skill_pack\" }));\n\t});\n\n\tit(\"does not duplicate services already selected by user\", () => {\n\t\tconst result = resolve({\n\t\t\tservices: [\"qdrant\", \"searxng\", \"browserless\"],\n\t\t\tskillPacks: [\"research-agent\"],\n\t\t});\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\tconst qdrantCount = ids.filter((id) => id === \"qdrant\").length;\n\t\texpect(qdrantCount).toBe(1);\n\t});\n\n\tit(\"estimates memory correctly\", () => {\n\t\tconst result = resolve({ services: [\"redis\"], skillPacks: [] });\n\t\t// 512 (base) + 128 (redis) + mandatory services\n\t\texpect(result.estimatedMemoryMB).toBe(512 + 128 + MANDATORY_MEMORY);\n\t});\n\n\tit(\"adds proxy service when specified\", () => {\n\t\tconst result = resolve({ services: [\"redis\"], skillPacks: [], proxy: \"caddy\" });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\texpect(ids).toContain(\"caddy\");\n\t});\n\n\tit(\"adds monitoring stack when flag is set\", () => {\n\t\tconst result = resolve({ services: [], skillPacks: [], monitoring: true });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\texpect(ids).toContain(\"uptime-kuma\");\n\t\texpect(ids).toContain(\"grafana\");\n\t\texpect(ids).toContain(\"prometheus\");\n\t});\n\n\tit(\"is deterministic - same input gives same output\", () => {\n\t\tconst input = { services: [\"redis\", \"qdrant\", \"n8n\"], skillPacks: [\"research-agent\"] };\n\t\tconst result1 = resolve(input);\n\t\tconst result2 = resolve(input);\n\t\tconst ids1 = result1.services.map((s) => s.definition.id);\n\t\tconst ids2 = result2.services.map((s) => s.definition.id);\n\t\texpect(ids1).toEqual(ids2);\n\t});\n\n\tit(\"topologically sorts dependencies before dependents\", () => {\n\t\tconst result = resolve({ services: [\"n8n\"], skillPacks: [] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\tconst pgIndex = ids.indexOf(\"postgresql\");\n\t\tconst n8nIndex = ids.indexOf(\"n8n\");\n\t\texpect(pgIndex).toBeLessThan(n8nIndex);\n\t});\n\n\tit(\"warns about GPU when AI services selected without gpu flag\", () => {\n\t\tconst result = resolve({ services: [\"redis\"], skillPacks: [], gpu: false });\n\t\tconst gpuWarnings = result.warnings.filter((w) => w.type === \"gpu\");\n\t\texpect(gpuWarnings).toHaveLength(0);\n\t});\n\n\tit(\"resolves tailscale (mandatory, always present)\", () => {\n\t\tconst result = resolve({ services: [], skillPacks: [] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\texpect(ids).toContain(\"tailscale\");\n\t\texpect(result.isValid).toBe(true);\n\t});\n\n\tit(\"resolves coolify and dokploy as single services\", () => {\n\t\tconst result = resolve({ services: [\"coolify\", \"dokploy\"], skillPacks: [] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\texpect(ids).toContain(\"coolify\");\n\t\texpect(ids).toContain(\"dokploy\");\n\t\texpect(result.isValid).toBe(true);\n\t});\n\n\tit(\"auto-adds postgresql, redis, and livekit when lasuite-meet-backend is selected\", () => {\n\t\tconst result = resolve({ services: [\"lasuite-meet-backend\"], skillPacks: [] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\texpect(ids).toContain(\"lasuite-meet-backend\");\n\t\texpect(ids).toContain(\"postgresql\");\n\t\texpect(ids).toContain(\"redis\");\n\t\texpect(ids).toContain(\"livekit\");\n\t\texpect(result.addedDependencies.some((a) => a.service === \"postgresql\")).toBe(true);\n\t\texpect(result.isValid).toBe(true);\n\t});\n\n\tit(\"resolves La Suite Meet preset (postgresql, redis, livekit, backend, frontend, agents)\", () => {\n\t\tconst lasuiteMeetServices = [\n\t\t\t\"postgresql\",\n\t\t\t\"redis\",\n\t\t\t\"livekit\",\n\t\t\t\"lasuite-meet-backend\",\n\t\t\t\"lasuite-meet-frontend\",\n\t\t\t\"lasuite-meet-agents\",\n\t\t];\n\t\tconst result = resolve({ services: lasuiteMeetServices, skillPacks: [] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\tfor (const id of lasuiteMeetServices) {\n\t\t\texpect(ids).toContain(id);\n\t\t}\n\t\texpect(result.isValid).toBe(true);\n\t});\n\n\tit(\"orders lasuite-meet-backend after postgresql, redis, and livekit\", () => {\n\t\tconst result = resolve({\n\t\t\tservices: [\"lasuite-meet-backend\", \"lasuite-meet-frontend\"],\n\t\t\tskillPacks: [],\n\t\t});\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\tconst pgIdx = ids.indexOf(\"postgresql\");\n\t\tconst redisIdx = ids.indexOf(\"redis\");\n\t\tconst livekitIdx = ids.indexOf(\"livekit\");\n\t\tconst backendIdx = ids.indexOf(\"lasuite-meet-backend\");\n\t\tconst frontendIdx = ids.indexOf(\"lasuite-meet-frontend\");\n\t\texpect(pgIdx).toBeGreaterThanOrEqual(0);\n\t\texpect(backendIdx).toBeGreaterThan(pgIdx);\n\t\texpect(backendIdx).toBeGreaterThan(redisIdx);\n\t\texpect(backendIdx).toBeGreaterThan(livekitIdx);\n\t\texpect(frontendIdx).toBeGreaterThan(backendIdx);\n\t});\n\n\t// ── Mandatory services enforcement ──────────────────────────────────────\n\n\tit(\"auto-includes mandatory services even when not selected\", () => {\n\t\tconst result = resolve({ services: [\"redis\"], skillPacks: [] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\texpect(ids).toContain(\"mission-control\");\n\t\texpect(ids).toContain(\"convex\");\n\t\texpect(ids).toContain(\"tailscale\");\n\t\tconst mc = result.services.find((s) => s.definition.id === \"mission-control\");\n\t\texpect(mc!.addedBy).toBe(\"mandatory\");\n\t});\n\n\tit(\"marks user-selected mandatory services as 'user' not 'mandatory'\", () => {\n\t\tconst result = resolve({ services: [\"mission-control\"], skillPacks: [] });\n\t\tconst mc = result.services.find((s) => s.definition.id === \"mission-control\");\n\t\texpect(mc!.addedBy).toBe(\"user\");\n\t\t// convex should still be auto-added as dependency of mission-control\n\t\tconst convex = result.services.find((s) => s.definition.id === \"convex\");\n\t\texpect(convex).toBeDefined();\n\t});\n\n\tit(\"orders convex before mission-control (dependency ordering)\", () => {\n\t\tconst result = resolve({ services: [\"redis\"], skillPacks: [] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\tconst convexIdx = ids.indexOf(\"convex\");\n\t\tconst mcIdx = ids.indexOf(\"mission-control\");\n\t\texpect(convexIdx).toBeLessThan(mcIdx);\n\t});\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"resolver.test.cjs","names":["describe","resolve","expect"],"sources":["../src/resolver.test.ts"],"sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport { resolve } from \"./resolver.js\";\n\n// Mandatory services (convex, mission-control, tailscale) are always auto-included.\n// These IDs and their combined memory are accounted for in all tests.\nconst MANDATORY_IDS = [\"convex\", \"mission-control\", \"tailscale\"];\nconst MANDATORY_MEMORY = 256 + 128 + 64; // convex + mission-control + tailscale\n\ndescribe(\"resolve\", () => {\n\tit(\"returns only mandatory services for empty input\", () => {\n\t\tconst result = resolve({ services: [], skillPacks: [] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\tfor (const id of MANDATORY_IDS) {\n\t\t\texpect(ids).toContain(id);\n\t\t}\n\t\texpect(result.isValid).toBe(true);\n\t\t// 512 (base) + mandatory services memory\n\t\texpect(result.estimatedMemoryMB).toBe(512 + MANDATORY_MEMORY);\n\t});\n\n\tit(\"resolves a single service alongside mandatory services\", () => {\n\t\tconst result = resolve({ services: [\"redis\"], skillPacks: [] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\texpect(ids).toContain(\"redis\");\n\t\tfor (const id of MANDATORY_IDS) {\n\t\t\texpect(ids).toContain(id);\n\t\t}\n\t\texpect(result.isValid).toBe(true);\n\t});\n\n\tit(\"auto-adds PostgreSQL when n8n is selected\", () => {\n\t\tconst result = resolve({ services: [\"n8n\"], skillPacks: [] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\texpect(ids).toContain(\"n8n\");\n\t\texpect(ids).toContain(\"postgresql\");\n\t\texpect(result.addedDependencies).toContainEqual(\n\t\t\texpect.objectContaining({ service: \"postgresql\" }),\n\t\t);\n\t\texpect(result.isValid).toBe(true);\n\t});\n\n\tit(\"auto-adds Prometheus when Grafana is selected\", () => {\n\t\tconst result = resolve({ services: [\"grafana\"], skillPacks: [] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\texpect(ids).toContain(\"grafana\");\n\t\texpect(ids).toContain(\"prometheus\");\n\t});\n\n\tit(\"detects Redis + Valkey conflict\", () => {\n\t\tconst result = resolve({ services: [\"redis\", \"valkey\"], skillPacks: [] });\n\t\texpect(result.isValid).toBe(false);\n\t\texpect(result.errors).toContainEqual(expect.objectContaining({ type: \"conflict\" }));\n\t});\n\n\tit(\"detects Caddy + Traefik conflict\", () => {\n\t\tconst result = resolve({ services: [\"caddy\", \"traefik\"], skillPacks: [] });\n\t\texpect(result.isValid).toBe(false);\n\t\texpect(result.errors).toContainEqual(expect.objectContaining({ type: \"conflict\" }));\n\t});\n\n\tit(\"expands research-agent skill pack\", () => {\n\t\tconst result = resolve({ services: [], skillPacks: [\"research-agent\"] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\texpect(ids).toContain(\"qdrant\");\n\t\texpect(ids).toContain(\"searxng\");\n\t\texpect(ids).toContain(\"browserless\");\n\t\texpect(result.isValid).toBe(true);\n\t});\n\n\tit(\"expands video-creator skill pack\", () => {\n\t\tconst result = resolve({ services: [], skillPacks: [\"video-creator\"] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\texpect(ids).toContain(\"ffmpeg\");\n\t\texpect(ids).toContain(\"remotion\");\n\t\texpect(ids).toContain(\"minio\");\n\t});\n\n\tit(\"expands dev-ops skill pack with transitive deps\", () => {\n\t\tconst result = resolve({ services: [], skillPacks: [\"dev-ops\"] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\texpect(ids).toContain(\"n8n\");\n\t\texpect(ids).toContain(\"redis\");\n\t\texpect(ids).toContain(\"uptime-kuma\");\n\t\texpect(ids).toContain(\"grafana\");\n\t\texpect(ids).toContain(\"prometheus\");\n\t\t// n8n requires postgresql (transitive)\n\t\texpect(ids).toContain(\"postgresql\");\n\t});\n\n\tit(\"reports unknown service IDs\", () => {\n\t\tconst result = resolve({ services: [\"nonexistent\"], skillPacks: [] });\n\t\texpect(result.errors).toContainEqual(expect.objectContaining({ type: \"unknown_service\" }));\n\t});\n\n\tit(\"reports unknown skill pack IDs\", () => {\n\t\tconst result = resolve({ services: [], skillPacks: [\"nonexistent-pack\"] });\n\t\texpect(result.errors).toContainEqual(expect.objectContaining({ type: \"unknown_skill_pack\" }));\n\t});\n\n\tit(\"does not duplicate services already selected by user\", () => {\n\t\tconst result = resolve({\n\t\t\tservices: [\"qdrant\", \"searxng\", \"browserless\"],\n\t\t\tskillPacks: [\"research-agent\"],\n\t\t});\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\tconst qdrantCount = ids.filter((id) => id === \"qdrant\").length;\n\t\texpect(qdrantCount).toBe(1);\n\t});\n\n\tit(\"estimates memory correctly\", () => {\n\t\tconst result = resolve({ services: [\"redis\"], skillPacks: [] });\n\t\t// 512 (base) + 128 (redis) + mandatory services\n\t\texpect(result.estimatedMemoryMB).toBe(512 + 128 + MANDATORY_MEMORY);\n\t});\n\n\tit(\"adds proxy service when specified\", () => {\n\t\tconst result = resolve({ services: [\"redis\"], skillPacks: [], proxy: \"caddy\" });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\texpect(ids).toContain(\"caddy\");\n\t});\n\n\tit(\"adds monitoring stack when flag is set\", () => {\n\t\tconst result = resolve({ services: [], skillPacks: [], monitoring: true });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\texpect(ids).toContain(\"uptime-kuma\");\n\t\texpect(ids).toContain(\"grafana\");\n\t\texpect(ids).toContain(\"prometheus\");\n\t});\n\n\tit(\"is deterministic - same input gives same output\", () => {\n\t\tconst input = { services: [\"redis\", \"qdrant\", \"n8n\"], skillPacks: [\"research-agent\"] };\n\t\tconst result1 = resolve(input);\n\t\tconst result2 = resolve(input);\n\t\tconst ids1 = result1.services.map((s) => s.definition.id);\n\t\tconst ids2 = result2.services.map((s) => s.definition.id);\n\t\texpect(ids1).toEqual(ids2);\n\t});\n\n\tit(\"topologically sorts dependencies before dependents\", () => {\n\t\tconst result = resolve({ services: [\"n8n\"], skillPacks: [] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\tconst pgIndex = ids.indexOf(\"postgresql\");\n\t\tconst n8nIndex = ids.indexOf(\"n8n\");\n\t\texpect(pgIndex).toBeLessThan(n8nIndex);\n\t});\n\n\tit(\"warns about GPU when AI services selected without gpu flag\", () => {\n\t\tconst result = resolve({ services: [\"redis\"], skillPacks: [], gpu: false });\n\t\tconst gpuWarnings = result.warnings.filter((w) => w.type === \"gpu\");\n\t\texpect(gpuWarnings).toHaveLength(0);\n\t});\n\n\tit(\"resolves tailscale (mandatory, always present)\", () => {\n\t\tconst result = resolve({ services: [], skillPacks: [] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\texpect(ids).toContain(\"tailscale\");\n\t\texpect(result.isValid).toBe(true);\n\t});\n\n\tit(\"resolves coolify and dokploy as single services\", () => {\n\t\tconst result = resolve({ services: [\"coolify\", \"dokploy\"], skillPacks: [] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\texpect(ids).toContain(\"coolify\");\n\t\texpect(ids).toContain(\"dokploy\");\n\t\texpect(result.isValid).toBe(true);\n\t});\n\n\tit(\"auto-adds postgresql, redis, and livekit when lasuite-meet-backend is selected\", () => {\n\t\tconst result = resolve({ services: [\"lasuite-meet-backend\"], skillPacks: [] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\texpect(ids).toContain(\"lasuite-meet-backend\");\n\t\texpect(ids).toContain(\"postgresql\");\n\t\texpect(ids).toContain(\"redis\");\n\t\texpect(ids).toContain(\"livekit\");\n\t\texpect(result.addedDependencies.some((a) => a.service === \"postgresql\")).toBe(true);\n\t\texpect(result.isValid).toBe(true);\n\t});\n\n\tit(\"resolves La Suite Meet preset (postgresql, redis, livekit, backend, frontend, agents)\", () => {\n\t\tconst lasuiteMeetServices = [\n\t\t\t\"postgresql\",\n\t\t\t\"redis\",\n\t\t\t\"livekit\",\n\t\t\t\"lasuite-meet-backend\",\n\t\t\t\"lasuite-meet-frontend\",\n\t\t\t\"lasuite-meet-agents\",\n\t\t];\n\t\tconst result = resolve({ services: lasuiteMeetServices, skillPacks: [] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\tfor (const id of lasuiteMeetServices) {\n\t\t\texpect(ids).toContain(id);\n\t\t}\n\t\texpect(result.isValid).toBe(true);\n\t});\n\n\tit(\"orders lasuite-meet-backend after postgresql, redis, and livekit\", () => {\n\t\tconst result = resolve({\n\t\t\tservices: [\"lasuite-meet-backend\", \"lasuite-meet-frontend\"],\n\t\t\tskillPacks: [],\n\t\t});\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\tconst pgIdx = ids.indexOf(\"postgresql\");\n\t\tconst redisIdx = ids.indexOf(\"redis\");\n\t\tconst livekitIdx = ids.indexOf(\"livekit\");\n\t\tconst backendIdx = ids.indexOf(\"lasuite-meet-backend\");\n\t\tconst frontendIdx = ids.indexOf(\"lasuite-meet-frontend\");\n\t\texpect(pgIdx).toBeGreaterThanOrEqual(0);\n\t\texpect(backendIdx).toBeGreaterThan(pgIdx);\n\t\texpect(backendIdx).toBeGreaterThan(redisIdx);\n\t\texpect(backendIdx).toBeGreaterThan(livekitIdx);\n\t\texpect(frontendIdx).toBeGreaterThan(backendIdx);\n\t});\n\n\t// ── Mandatory services enforcement ──────────────────────────────────────\n\n\tit(\"auto-includes mandatory services even when not selected\", () => {\n\t\tconst result = resolve({ services: [\"redis\"], skillPacks: [] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\texpect(ids).toContain(\"mission-control\");\n\t\texpect(ids).toContain(\"convex\");\n\t\texpect(ids).toContain(\"tailscale\");\n\t\tconst mc = result.services.find((s) => s.definition.id === \"mission-control\");\n\t\texpect(mc!.addedBy).toBe(\"mandatory\");\n\t});\n\n\tit(\"marks user-selected mandatory services as 'user' not 'mandatory'\", () => {\n\t\tconst result = resolve({ services: [\"mission-control\"], skillPacks: [] });\n\t\tconst mc = result.services.find((s) => s.definition.id === \"mission-control\");\n\t\texpect(mc!.addedBy).toBe(\"user\");\n\t\t// convex should still be auto-added as dependency of mission-control\n\t\tconst convex = result.services.find((s) => s.definition.id === \"convex\");\n\t\texpect(convex).toBeDefined();\n\t});\n\n\tit(\"orders convex before mission-control (dependency ordering)\", () => {\n\t\tconst result = resolve({ services: [\"redis\"], skillPacks: [] });\n\t\tconst ids = result.services.map((s) => s.definition.id);\n\t\tconst convexIdx = ids.indexOf(\"convex\");\n\t\tconst mcIdx = ids.indexOf(\"mission-control\");\n\t\texpect(convexIdx).toBeLessThan(mcIdx);\n\t});\n});\n"],"mappings":"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"}
|
package/dist/resolver.test.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as describe, r as it, t as globalExpect } from "./
|
|
1
|
+
import { n as describe, r as it, t as globalExpect } from "./test.CTcmp4Su-ClCHJ3FA.mjs";
|
|
2
2
|
import { resolve } from "./resolver.mjs";
|
|
3
3
|
//#region src/resolver.test.ts
|
|
4
4
|
const MANDATORY_IDS = [
|