@better-openclaw/core 1.0.23 → 1.0.24
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/bare-metal-partition.test.cjs +3 -4
- package/dist/bare-metal-partition.test.cjs.map +1 -1
- package/dist/bare-metal-partition.test.mjs +3 -4
- package/dist/bare-metal-partition.test.mjs.map +1 -1
- package/dist/composer.cjs +13 -1
- package/dist/composer.cjs.map +1 -1
- package/dist/composer.d.cts.map +1 -1
- package/dist/composer.d.mts.map +1 -1
- package/dist/composer.mjs +13 -1
- package/dist/composer.mjs.map +1 -1
- package/dist/composer.snapshot.test.cjs +1 -1
- package/dist/composer.snapshot.test.mjs +1 -1
- package/dist/composer.test.cjs +3 -2
- package/dist/composer.test.cjs.map +1 -1
- package/dist/composer.test.mjs +3 -2
- package/dist/composer.test.mjs.map +1 -1
- package/dist/deployers/strip-host-ports.test.cjs +1 -1
- package/dist/deployers/strip-host-ports.test.mjs +1 -1
- package/dist/generate.cjs +6 -2
- package/dist/generate.cjs.map +1 -1
- package/dist/generate.d.cts.map +1 -1
- package/dist/generate.d.mts.map +1 -1
- package/dist/generate.mjs +6 -2
- package/dist/generate.mjs.map +1 -1
- package/dist/generate.test.cjs +2 -2
- package/dist/generate.test.cjs.map +1 -1
- package/dist/generate.test.mjs +2 -2
- package/dist/generate.test.mjs.map +1 -1
- package/dist/generators/bare-metal-install.test.cjs +1 -1
- package/dist/generators/bare-metal-install.test.mjs +1 -1
- package/dist/generators/caddy.test.cjs +1 -1
- package/dist/generators/caddy.test.mjs +1 -1
- package/dist/generators/clone-repos.cjs +140 -0
- package/dist/generators/clone-repos.cjs.map +1 -0
- package/dist/generators/clone-repos.d.cts +11 -0
- package/dist/generators/clone-repos.d.cts.map +1 -0
- package/dist/generators/clone-repos.d.mts +11 -0
- package/dist/generators/clone-repos.d.mts.map +1 -0
- package/dist/generators/clone-repos.mjs +139 -0
- package/dist/generators/clone-repos.mjs.map +1 -0
- package/dist/generators/clone-repos.test.cjs +140 -0
- package/dist/generators/clone-repos.test.cjs.map +1 -0
- package/dist/generators/clone-repos.test.d.cts +1 -0
- package/dist/generators/clone-repos.test.d.mts +1 -0
- package/dist/generators/clone-repos.test.mjs +141 -0
- package/dist/generators/clone-repos.test.mjs.map +1 -0
- package/dist/generators/env.test.cjs +1 -1
- package/dist/generators/env.test.mjs +1 -1
- package/dist/generators/health-check.test.cjs +1 -1
- package/dist/generators/health-check.test.mjs +1 -1
- package/dist/generators/postgres-init.cjs +20 -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 +20 -0
- package/dist/generators/postgres-init.mjs.map +1 -1
- package/dist/generators/scripts.cjs +332 -3
- package/dist/generators/scripts.cjs.map +1 -1
- package/dist/generators/scripts.d.cts +3 -1
- package/dist/generators/scripts.d.cts.map +1 -1
- package/dist/generators/scripts.d.mts +3 -1
- package/dist/generators/scripts.d.mts.map +1 -1
- package/dist/generators/scripts.mjs +332 -3
- package/dist/generators/scripts.mjs.map +1 -1
- package/dist/generators/scripts.test.cjs +39 -5
- package/dist/generators/scripts.test.cjs.map +1 -1
- package/dist/generators/scripts.test.mjs +39 -5
- package/dist/generators/scripts.test.mjs.map +1 -1
- package/dist/generators/stack-manifest.cjs +1 -0
- package/dist/generators/stack-manifest.cjs.map +1 -1
- package/dist/generators/stack-manifest.d.cts +3 -2
- package/dist/generators/stack-manifest.d.cts.map +1 -1
- package/dist/generators/stack-manifest.d.mts +3 -2
- package/dist/generators/stack-manifest.d.mts.map +1 -1
- package/dist/generators/stack-manifest.mjs +1 -0
- package/dist/generators/stack-manifest.mjs.map +1 -1
- package/dist/generators/traefik.test.cjs +1 -1
- package/dist/generators/traefik.test.mjs +1 -1
- package/dist/index.cjs +8 -1
- package/dist/index.d.cts +5 -3
- package/dist/index.d.mts +5 -3
- package/dist/index.mjs +5 -3
- package/dist/migrations.test.cjs +1 -1
- package/dist/migrations.test.mjs +1 -1
- package/dist/presets/registry.cjs.map +1 -1
- package/dist/presets/registry.d.cts.map +1 -1
- package/dist/presets/registry.d.mts.map +1 -1
- package/dist/presets/registry.mjs.map +1 -1
- package/dist/presets/registry.test.cjs +1 -1
- package/dist/presets/registry.test.mjs +1 -1
- package/dist/resolver.cjs +8 -0
- package/dist/resolver.cjs.map +1 -1
- package/dist/resolver.mjs +9 -1
- package/dist/resolver.mjs.map +1 -1
- package/dist/resolver.test.cjs +47 -12
- package/dist/resolver.test.cjs.map +1 -1
- package/dist/resolver.test.mjs +47 -12
- package/dist/resolver.test.mjs.map +1 -1
- package/dist/{schema-B4c64P8N.d.cts → schema-eX44HhRp.d.mts} +62 -8
- package/dist/schema-eX44HhRp.d.mts.map +1 -0
- package/dist/{schema-CXNhYci1.d.mts → schema-tn5RK8CM.d.cts} +62 -8
- package/dist/schema-tn5RK8CM.d.cts.map +1 -0
- package/dist/schema.cjs +22 -4
- 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 +21 -5
- package/dist/schema.mjs.map +1 -1
- package/dist/schema.test.cjs +1 -1
- package/dist/schema.test.mjs +1 -1
- package/dist/services/definitions/apptension-saas.cjs +87 -0
- package/dist/services/definitions/apptension-saas.cjs.map +1 -0
- package/dist/services/definitions/apptension-saas.d.cts +7 -0
- package/dist/services/definitions/apptension-saas.d.cts.map +1 -0
- package/dist/services/definitions/apptension-saas.d.mts +7 -0
- package/dist/services/definitions/apptension-saas.d.mts.map +1 -0
- package/dist/services/definitions/apptension-saas.mjs +86 -0
- package/dist/services/definitions/apptension-saas.mjs.map +1 -0
- package/dist/services/definitions/boxyhq-saas.cjs +88 -0
- package/dist/services/definitions/boxyhq-saas.cjs.map +1 -0
- package/dist/services/definitions/boxyhq-saas.d.cts +7 -0
- package/dist/services/definitions/boxyhq-saas.d.cts.map +1 -0
- package/dist/services/definitions/boxyhq-saas.d.mts +7 -0
- package/dist/services/definitions/boxyhq-saas.d.mts.map +1 -0
- package/dist/services/definitions/boxyhq-saas.mjs +87 -0
- package/dist/services/definitions/boxyhq-saas.mjs.map +1 -0
- package/dist/services/definitions/cmsaas-starter.cjs +86 -0
- package/dist/services/definitions/cmsaas-starter.cjs.map +1 -0
- package/dist/services/definitions/cmsaas-starter.d.cts +7 -0
- package/dist/services/definitions/cmsaas-starter.d.cts.map +1 -0
- package/dist/services/definitions/cmsaas-starter.d.mts +7 -0
- package/dist/services/definitions/cmsaas-starter.d.mts.map +1 -0
- package/dist/services/definitions/cmsaas-starter.mjs +85 -0
- package/dist/services/definitions/cmsaas-starter.mjs.map +1 -0
- package/dist/services/definitions/index.cjs +51 -36
- package/dist/services/definitions/index.cjs.map +1 -1
- package/dist/services/definitions/index.d.cts +30 -25
- package/dist/services/definitions/index.d.cts.map +1 -1
- package/dist/services/definitions/index.d.mts +30 -25
- package/dist/services/definitions/index.d.mts.map +1 -1
- package/dist/services/definitions/index.mjs +47 -37
- package/dist/services/definitions/index.mjs.map +1 -1
- package/dist/services/definitions/ixartz-saas.cjs +88 -0
- package/dist/services/definitions/ixartz-saas.cjs.map +1 -0
- package/dist/services/definitions/ixartz-saas.d.cts +7 -0
- package/dist/services/definitions/ixartz-saas.d.cts.map +1 -0
- package/dist/services/definitions/ixartz-saas.d.mts +7 -0
- package/dist/services/definitions/ixartz-saas.d.mts.map +1 -0
- package/dist/services/definitions/ixartz-saas.mjs +87 -0
- package/dist/services/definitions/ixartz-saas.mjs.map +1 -0
- package/dist/services/definitions/mission-control.cjs +16 -2
- package/dist/services/definitions/mission-control.cjs.map +1 -1
- package/dist/services/definitions/mission-control.mjs +16 -2
- package/dist/services/definitions/mission-control.mjs.map +1 -1
- package/dist/services/definitions/open-saas.cjs +81 -0
- package/dist/services/definitions/open-saas.cjs.map +1 -0
- package/dist/services/definitions/open-saas.d.cts +7 -0
- package/dist/services/definitions/open-saas.d.cts.map +1 -0
- package/dist/services/definitions/open-saas.d.mts +7 -0
- package/dist/services/definitions/open-saas.d.mts.map +1 -0
- package/dist/services/definitions/open-saas.mjs +80 -0
- package/dist/services/definitions/open-saas.mjs.map +1 -0
- package/dist/services/registry.cjs +3 -0
- package/dist/services/registry.cjs.map +1 -1
- package/dist/services/registry.d.cts.map +1 -1
- package/dist/services/registry.d.mts.map +1 -1
- package/dist/services/registry.mjs +3 -0
- package/dist/services/registry.mjs.map +1 -1
- package/dist/services/registry.test.cjs +8 -1
- package/dist/services/registry.test.cjs.map +1 -1
- package/dist/services/registry.test.mjs +8 -1
- package/dist/services/registry.test.mjs.map +1 -1
- package/dist/{skill-manifest-BVUXU0__.mjs → skill-manifest-6XhrhWsG.mjs} +49 -1
- package/dist/{skill-manifest--IgY9REK.cjs.map → skill-manifest-6XhrhWsG.mjs.map} +1 -1
- package/dist/{skill-manifest--IgY9REK.cjs → skill-manifest-B8znSsym.cjs} +49 -1
- package/dist/{skill-manifest-BVUXU0__.mjs.map → skill-manifest-B8znSsym.cjs.map} +1 -1
- package/dist/skills/registry.cjs +3 -3
- package/dist/skills/registry.cjs.map +1 -1
- package/dist/skills/registry.mjs +3 -3
- package/dist/skills/registry.mjs.map +1 -1
- package/dist/skills/skill-manifest.cjs +1 -1
- package/dist/skills/skill-manifest.mjs +1 -1
- package/dist/track-analytics.cjs +50 -0
- package/dist/track-analytics.cjs.map +1 -0
- package/dist/track-analytics.d.cts +34 -0
- package/dist/track-analytics.d.cts.map +1 -0
- package/dist/track-analytics.d.mts +34 -0
- package/dist/track-analytics.d.mts.map +1 -0
- package/dist/track-analytics.mjs +48 -0
- package/dist/track-analytics.mjs.map +1 -0
- package/dist/track-analytics.test.cjs +91 -0
- package/dist/track-analytics.test.cjs.map +1 -0
- package/dist/track-analytics.test.d.cts +1 -0
- package/dist/track-analytics.test.d.mts +1 -0
- package/dist/track-analytics.test.mjs +92 -0
- package/dist/track-analytics.test.mjs.map +1 -0
- package/dist/types.cjs +7 -0
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +4 -2
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +4 -2
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +7 -0
- package/dist/types.mjs.map +1 -1
- package/dist/validator.test.cjs +1 -1
- package/dist/validator.test.mjs +1 -1
- package/dist/version-manager.cjs +1 -1
- package/dist/version-manager.cjs.map +1 -1
- package/dist/version-manager.mjs +1 -1
- package/dist/version-manager.mjs.map +1 -1
- package/dist/version-manager.test.cjs +7 -5
- package/dist/version-manager.test.cjs.map +1 -1
- package/dist/version-manager.test.mjs +7 -5
- package/dist/version-manager.test.mjs.map +1 -1
- package/dist/{vi.2VT5v0um-DvC3SVNc.mjs → vi.2VT5v0um-C_jmO7m2.mjs} +5 -5
- package/dist/{vi.2VT5v0um-DvC3SVNc.mjs.map → vi.2VT5v0um-C_jmO7m2.mjs.map} +1 -1
- package/dist/{vi.2VT5v0um-CRqXre87.cjs → vi.2VT5v0um-iVBt6Fyq.cjs} +5 -5
- package/dist/{vi.2VT5v0um-CRqXre87.cjs.map → vi.2VT5v0um-iVBt6Fyq.cjs.map} +1 -1
- package/package.json +1 -1
- package/src/__snapshots__/composer.snapshot.test.ts.snap +155 -0
- package/src/bare-metal-partition.test.ts +4 -3
- package/src/composer.test.ts +4 -2
- package/src/composer.ts +20 -1
- package/src/generate.test.ts +2 -1
- package/src/generate.ts +10 -1
- package/src/generators/clone-repos.test.ts +154 -0
- package/src/generators/clone-repos.ts +159 -0
- package/src/generators/postgres-init.ts +17 -0
- package/src/generators/scripts.test.ts +52 -4
- package/src/generators/scripts.ts +351 -3
- package/src/generators/stack-manifest.ts +4 -2
- package/src/index.ts +8 -0
- package/src/presets/registry.ts +241 -329
- package/src/resolver.test.ts +53 -15
- package/src/resolver.ts +13 -1
- package/src/schema.ts +33 -4
- package/src/services/definitions/apptension-saas.ts +84 -0
- package/src/services/definitions/boxyhq-saas.ts +84 -0
- package/src/services/definitions/cmsaas-starter.ts +84 -0
- package/src/services/definitions/index.ts +90 -70
- package/src/services/definitions/ixartz-saas.ts +84 -0
- package/src/services/definitions/mission-control.ts +19 -2
- package/src/services/definitions/open-saas.ts +79 -0
- package/src/services/registry.test.ts +8 -0
- package/src/services/registry.ts +7 -0
- package/src/skills/manifest.json +64 -0
- package/src/skills/registry.ts +3 -3
- package/src/track-analytics.test.ts +82 -0
- package/src/track-analytics.ts +76 -0
- package/src/types.ts +11 -0
- package/src/version-manager.test.ts +10 -5
- package/src/version-manager.ts +1 -1
- package/dist/schema-B4c64P8N.d.cts.map +0 -1
- package/dist/schema-CXNhYci1.d.mts.map +0 -1
package/src/resolver.test.ts
CHANGED
|
@@ -1,18 +1,30 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
2
|
import { resolve } from "./resolver.js";
|
|
3
3
|
|
|
4
|
+
// Mandatory services (convex, mission-control, tailscale) are always auto-included.
|
|
5
|
+
// These IDs and their combined memory are accounted for in all tests.
|
|
6
|
+
const MANDATORY_IDS = ["convex", "mission-control", "tailscale"];
|
|
7
|
+
const MANDATORY_MEMORY = 256 + 128 + 64; // convex + mission-control + tailscale
|
|
8
|
+
|
|
4
9
|
describe("resolve", () => {
|
|
5
|
-
it("returns
|
|
10
|
+
it("returns only mandatory services for empty input", () => {
|
|
6
11
|
const result = resolve({ services: [], skillPacks: [] });
|
|
7
|
-
|
|
12
|
+
const ids = result.services.map((s) => s.definition.id);
|
|
13
|
+
for (const id of MANDATORY_IDS) {
|
|
14
|
+
expect(ids).toContain(id);
|
|
15
|
+
}
|
|
8
16
|
expect(result.isValid).toBe(true);
|
|
9
|
-
|
|
17
|
+
// 512 (base) + mandatory services memory
|
|
18
|
+
expect(result.estimatedMemoryMB).toBe(512 + MANDATORY_MEMORY);
|
|
10
19
|
});
|
|
11
20
|
|
|
12
|
-
it("resolves a single service
|
|
21
|
+
it("resolves a single service alongside mandatory services", () => {
|
|
13
22
|
const result = resolve({ services: ["redis"], skillPacks: [] });
|
|
14
|
-
|
|
15
|
-
expect(
|
|
23
|
+
const ids = result.services.map((s) => s.definition.id);
|
|
24
|
+
expect(ids).toContain("redis");
|
|
25
|
+
for (const id of MANDATORY_IDS) {
|
|
26
|
+
expect(ids).toContain(id);
|
|
27
|
+
}
|
|
16
28
|
expect(result.isValid).toBe(true);
|
|
17
29
|
});
|
|
18
30
|
|
|
@@ -97,8 +109,8 @@ describe("resolve", () => {
|
|
|
97
109
|
|
|
98
110
|
it("estimates memory correctly", () => {
|
|
99
111
|
const result = resolve({ services: ["redis"], skillPacks: [] });
|
|
100
|
-
// 512 (base) + 128 (redis)
|
|
101
|
-
expect(result.estimatedMemoryMB).toBe(
|
|
112
|
+
// 512 (base) + 128 (redis) + mandatory services
|
|
113
|
+
expect(result.estimatedMemoryMB).toBe(512 + 128 + MANDATORY_MEMORY);
|
|
102
114
|
});
|
|
103
115
|
|
|
104
116
|
it("adds proxy service when specified", () => {
|
|
@@ -133,18 +145,15 @@ describe("resolve", () => {
|
|
|
133
145
|
});
|
|
134
146
|
|
|
135
147
|
it("warns about GPU when AI services selected without gpu flag", () => {
|
|
136
|
-
// Ollama doesn't have gpuRequired=true (it's recommended not required)
|
|
137
|
-
// but we should still check GPU warning logic works
|
|
138
148
|
const result = resolve({ services: ["redis"], skillPacks: [], gpu: false });
|
|
139
|
-
// Redis doesn't need GPU, so no GPU warnings
|
|
140
149
|
const gpuWarnings = result.warnings.filter((w) => w.type === "gpu");
|
|
141
150
|
expect(gpuWarnings).toHaveLength(0);
|
|
142
151
|
});
|
|
143
152
|
|
|
144
|
-
it("resolves tailscale
|
|
145
|
-
const result = resolve({ services: [
|
|
146
|
-
|
|
147
|
-
expect(
|
|
153
|
+
it("resolves tailscale (mandatory, always present)", () => {
|
|
154
|
+
const result = resolve({ services: [], skillPacks: [] });
|
|
155
|
+
const ids = result.services.map((s) => s.definition.id);
|
|
156
|
+
expect(ids).toContain("tailscale");
|
|
148
157
|
expect(result.isValid).toBe(true);
|
|
149
158
|
});
|
|
150
159
|
|
|
@@ -201,4 +210,33 @@ describe("resolve", () => {
|
|
|
201
210
|
expect(backendIdx).toBeGreaterThan(livekitIdx);
|
|
202
211
|
expect(frontendIdx).toBeGreaterThan(backendIdx);
|
|
203
212
|
});
|
|
213
|
+
|
|
214
|
+
// ── Mandatory services enforcement ──────────────────────────────────────
|
|
215
|
+
|
|
216
|
+
it("auto-includes mandatory services even when not selected", () => {
|
|
217
|
+
const result = resolve({ services: ["redis"], skillPacks: [] });
|
|
218
|
+
const ids = result.services.map((s) => s.definition.id);
|
|
219
|
+
expect(ids).toContain("mission-control");
|
|
220
|
+
expect(ids).toContain("convex");
|
|
221
|
+
expect(ids).toContain("tailscale");
|
|
222
|
+
const mc = result.services.find((s) => s.definition.id === "mission-control");
|
|
223
|
+
expect(mc!.addedBy).toBe("mandatory");
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it("marks user-selected mandatory services as 'user' not 'mandatory'", () => {
|
|
227
|
+
const result = resolve({ services: ["mission-control"], skillPacks: [] });
|
|
228
|
+
const mc = result.services.find((s) => s.definition.id === "mission-control");
|
|
229
|
+
expect(mc!.addedBy).toBe("user");
|
|
230
|
+
// convex should still be auto-added as dependency of mission-control
|
|
231
|
+
const convex = result.services.find((s) => s.definition.id === "convex");
|
|
232
|
+
expect(convex).toBeDefined();
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
it("orders convex before mission-control (dependency ordering)", () => {
|
|
236
|
+
const result = resolve({ services: ["redis"], skillPacks: [] });
|
|
237
|
+
const ids = result.services.map((s) => s.definition.id);
|
|
238
|
+
const convexIdx = ids.indexOf("convex");
|
|
239
|
+
const mcIdx = ids.indexOf("mission-control");
|
|
240
|
+
expect(convexIdx).toBeLessThan(mcIdx);
|
|
241
|
+
});
|
|
204
242
|
});
|
package/src/resolver.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getServiceById } from "./services/registry.js";
|
|
1
|
+
import { getAllServices, getServiceById } from "./services/registry.js";
|
|
2
2
|
import { getSkillPackById } from "./skills/registry.js";
|
|
3
3
|
import type {
|
|
4
4
|
AddedDependency,
|
|
@@ -99,6 +99,18 @@ export function resolve(input: ResolverInput): ResolverOutput {
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
// Add mandatory platform services (mission-control, convex, tailscale, etc.)
|
|
103
|
+
for (const def of getAllServices()) {
|
|
104
|
+
if (def.mandatory && !serviceIds.has(def.id)) {
|
|
105
|
+
serviceIds.add(def.id);
|
|
106
|
+
serviceAddedBy.set(def.id, "mandatory");
|
|
107
|
+
addedDependencies.push({
|
|
108
|
+
service: def.id,
|
|
109
|
+
reason: "Mandatory OpenClaw platform service",
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
102
114
|
// Validate all service IDs exist
|
|
103
115
|
const unknownIds: string[] = [];
|
|
104
116
|
for (const id of serviceIds) {
|
package/src/schema.ts
CHANGED
|
@@ -38,6 +38,7 @@ export const ServiceCategorySchema = z.enum([
|
|
|
38
38
|
"business-intelligence",
|
|
39
39
|
"dns-networking",
|
|
40
40
|
"iot",
|
|
41
|
+
"saas-boilerplate",
|
|
41
42
|
]);
|
|
42
43
|
|
|
43
44
|
export const MaturitySchema = z.enum(["stable", "beta", "experimental"]);
|
|
@@ -153,6 +154,30 @@ export const NativeRecipeSchema = z.object({
|
|
|
153
154
|
systemdUnit: z.string().optional(),
|
|
154
155
|
});
|
|
155
156
|
|
|
157
|
+
// ─── Git Source / Build Context (for repo-based services) ───────────────────
|
|
158
|
+
|
|
159
|
+
export const GitSourceSchema = z.object({
|
|
160
|
+
/** Git clone URL, e.g. "https://github.com/wasp-lang/open-saas.git" */
|
|
161
|
+
repoUrl: z.string().url(),
|
|
162
|
+
/** Branch or tag to clone. Defaults to repo's default branch. */
|
|
163
|
+
branch: z.string().optional(),
|
|
164
|
+
/** Subdirectory within the cloned repo to use as build context root. */
|
|
165
|
+
subdirectory: z.string().optional(),
|
|
166
|
+
/** Commands to run after cloning (e.g. "cp .env.example .env"). */
|
|
167
|
+
postCloneCommands: z.array(z.string()).default([]),
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
export const BuildContextSchema = z.object({
|
|
171
|
+
/** Path to Dockerfile relative to the context root. Defaults to "Dockerfile". */
|
|
172
|
+
dockerfile: z.string().optional(),
|
|
173
|
+
/** Build context path relative to the subdirectory root. Defaults to ".". */
|
|
174
|
+
context: z.string().default("."),
|
|
175
|
+
/** Docker build args to pass at build time. */
|
|
176
|
+
args: z.record(z.string(), z.string()).optional(),
|
|
177
|
+
/** Target stage in a multi-stage Dockerfile. */
|
|
178
|
+
target: z.string().optional(),
|
|
179
|
+
});
|
|
180
|
+
|
|
156
181
|
// ─── Service Definition ─────────────────────────────────────────────────────
|
|
157
182
|
|
|
158
183
|
export const ServiceDefinitionSchema = z.object({
|
|
@@ -166,9 +191,13 @@ export const ServiceDefinitionSchema = z.object({
|
|
|
166
191
|
category: ServiceCategorySchema,
|
|
167
192
|
icon: z.string(),
|
|
168
193
|
|
|
169
|
-
// Docker
|
|
170
|
-
image: z.string().min(1),
|
|
171
|
-
imageTag: z.string().min(1),
|
|
194
|
+
// Docker (required for image-based services, omitted for git-based)
|
|
195
|
+
image: z.string().min(1).optional(),
|
|
196
|
+
imageTag: z.string().min(1).optional(),
|
|
197
|
+
|
|
198
|
+
// Git source (for services built from cloned repositories)
|
|
199
|
+
gitSource: GitSourceSchema.optional(),
|
|
200
|
+
buildContext: BuildContextSchema.optional(),
|
|
172
201
|
ports: z.array(PortMappingSchema).default([]),
|
|
173
202
|
volumes: z.array(VolumeMappingSchema).default([]),
|
|
174
203
|
environment: z.array(EnvVariableSchema).default([]),
|
|
@@ -278,7 +307,7 @@ export const GenerationInputSchema = z.object({
|
|
|
278
307
|
|
|
279
308
|
export const ResolvedServiceSchema = z.object({
|
|
280
309
|
definition: ServiceDefinitionSchema,
|
|
281
|
-
addedBy: z.enum(["user", "dependency", "skill-pack", "proxy", "monitoring"]).default("user"),
|
|
310
|
+
addedBy: z.enum(["user", "dependency", "skill-pack", "proxy", "monitoring", "mandatory"]).default("user"),
|
|
282
311
|
});
|
|
283
312
|
|
|
284
313
|
export const AddedDependencySchema = z.object({
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { ServiceDefinition } from "../../types.js";
|
|
2
|
+
|
|
3
|
+
export const apptensionSaasDefinition: ServiceDefinition = {
|
|
4
|
+
id: "apptension-saas",
|
|
5
|
+
name: "SaaS Boilerplate (Apptension)",
|
|
6
|
+
description:
|
|
7
|
+
"Production-ready SaaS boilerplate with React frontend, Django backend, GraphQL API, PostgreSQL, async workers, email, Stripe payments, and Docker Compose support.",
|
|
8
|
+
category: "saas-boilerplate",
|
|
9
|
+
icon: "🚀",
|
|
10
|
+
|
|
11
|
+
gitSource: {
|
|
12
|
+
repoUrl: "https://github.com/apptension/saas-boilerplate.git",
|
|
13
|
+
branch: "master",
|
|
14
|
+
postCloneCommands: [],
|
|
15
|
+
},
|
|
16
|
+
buildContext: {
|
|
17
|
+
dockerfile: "Dockerfile",
|
|
18
|
+
context: ".",
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
ports: [
|
|
22
|
+
{
|
|
23
|
+
host: 3101,
|
|
24
|
+
container: 80,
|
|
25
|
+
description: "Apptension SaaS web application",
|
|
26
|
+
exposed: true,
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
volumes: [],
|
|
30
|
+
environment: [
|
|
31
|
+
{
|
|
32
|
+
key: "APPTENSION_SAAS_DB_PASSWORD",
|
|
33
|
+
defaultValue: "",
|
|
34
|
+
secret: true,
|
|
35
|
+
description: "Database password for Apptension SaaS",
|
|
36
|
+
required: true,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
key: "DB_CONNECTION",
|
|
40
|
+
defaultValue: "postgresql://apptensionsaas:${APPTENSION_SAAS_DB_PASSWORD}@postgresql:5432/apptensionsaas",
|
|
41
|
+
secret: false,
|
|
42
|
+
description: "PostgreSQL connection string",
|
|
43
|
+
required: true,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
key: "DJANGO_SECRET_KEY",
|
|
47
|
+
defaultValue: "",
|
|
48
|
+
secret: true,
|
|
49
|
+
description: "Django secret key",
|
|
50
|
+
required: true,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
key: "REDIS_URL",
|
|
54
|
+
defaultValue: "redis://redis:6379/0",
|
|
55
|
+
secret: false,
|
|
56
|
+
description: "Redis connection URL for caching and async workers",
|
|
57
|
+
required: true,
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
healthcheck: {
|
|
61
|
+
test: "wget -q --spider http://localhost:80/ || exit 1",
|
|
62
|
+
interval: "30s",
|
|
63
|
+
timeout: "10s",
|
|
64
|
+
retries: 3,
|
|
65
|
+
startPeriod: "60s",
|
|
66
|
+
},
|
|
67
|
+
dependsOn: ["postgresql", "redis"],
|
|
68
|
+
restartPolicy: "unless-stopped",
|
|
69
|
+
networks: ["openclaw-network"],
|
|
70
|
+
|
|
71
|
+
skills: [],
|
|
72
|
+
openclawEnvVars: [],
|
|
73
|
+
|
|
74
|
+
docsUrl: "https://docs.demo.saas.apptension.com",
|
|
75
|
+
tags: ["saas", "boilerplate", "react", "django", "graphql", "stripe", "enterprise"],
|
|
76
|
+
maturity: "beta",
|
|
77
|
+
|
|
78
|
+
requires: ["postgresql", "redis"],
|
|
79
|
+
recommends: [],
|
|
80
|
+
conflictsWith: [],
|
|
81
|
+
|
|
82
|
+
minMemoryMB: 768,
|
|
83
|
+
gpuRequired: false,
|
|
84
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { ServiceDefinition } from "../../types.js";
|
|
2
|
+
|
|
3
|
+
export const boxyhqSaasDefinition: ServiceDefinition = {
|
|
4
|
+
id: "boxyhq-saas",
|
|
5
|
+
name: "BoxyHQ Enterprise SaaS Starter",
|
|
6
|
+
description:
|
|
7
|
+
"Enterprise-grade Next.js SaaS starter kit with SSO (SAML/OIDC), directory sync, audit logs, team management, Prisma ORM, Stripe billing, and PostgreSQL.",
|
|
8
|
+
category: "saas-boilerplate",
|
|
9
|
+
icon: "🚀",
|
|
10
|
+
|
|
11
|
+
gitSource: {
|
|
12
|
+
repoUrl: "https://github.com/boxyhq/saas-starter-kit.git",
|
|
13
|
+
branch: "main",
|
|
14
|
+
postCloneCommands: ["cp .env.example .env"],
|
|
15
|
+
},
|
|
16
|
+
buildContext: {
|
|
17
|
+
dockerfile: "Dockerfile",
|
|
18
|
+
context: ".",
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
ports: [
|
|
22
|
+
{
|
|
23
|
+
host: 3102,
|
|
24
|
+
container: 3000,
|
|
25
|
+
description: "BoxyHQ SaaS web application",
|
|
26
|
+
exposed: true,
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
volumes: [],
|
|
30
|
+
environment: [
|
|
31
|
+
{
|
|
32
|
+
key: "BOXYHQ_SAAS_DB_PASSWORD",
|
|
33
|
+
defaultValue: "",
|
|
34
|
+
secret: true,
|
|
35
|
+
description: "Database password for BoxyHQ SaaS",
|
|
36
|
+
required: true,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
key: "DATABASE_URL",
|
|
40
|
+
defaultValue: "postgresql://boxyhqsaas:${BOXYHQ_SAAS_DB_PASSWORD}@postgresql:5432/boxyhqsaas",
|
|
41
|
+
secret: false,
|
|
42
|
+
description: "PostgreSQL connection string",
|
|
43
|
+
required: true,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
key: "NEXTAUTH_SECRET",
|
|
47
|
+
defaultValue: "",
|
|
48
|
+
secret: true,
|
|
49
|
+
description: "NextAuth.js session encryption secret",
|
|
50
|
+
required: true,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
key: "NEXTAUTH_URL",
|
|
54
|
+
defaultValue: "http://localhost:3102",
|
|
55
|
+
secret: false,
|
|
56
|
+
description: "NextAuth.js callback URL",
|
|
57
|
+
required: true,
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
healthcheck: {
|
|
61
|
+
test: "wget -q --spider http://localhost:3000/ || exit 1",
|
|
62
|
+
interval: "30s",
|
|
63
|
+
timeout: "10s",
|
|
64
|
+
retries: 3,
|
|
65
|
+
startPeriod: "60s",
|
|
66
|
+
},
|
|
67
|
+
dependsOn: ["postgresql"],
|
|
68
|
+
restartPolicy: "unless-stopped",
|
|
69
|
+
networks: ["openclaw-network"],
|
|
70
|
+
|
|
71
|
+
skills: [],
|
|
72
|
+
openclawEnvVars: [],
|
|
73
|
+
|
|
74
|
+
docsUrl: "https://github.com/boxyhq/saas-starter-kit#readme",
|
|
75
|
+
tags: ["saas", "boilerplate", "nextjs", "enterprise", "sso", "saml", "stripe", "prisma"],
|
|
76
|
+
maturity: "beta",
|
|
77
|
+
|
|
78
|
+
requires: ["postgresql"],
|
|
79
|
+
recommends: [],
|
|
80
|
+
conflictsWith: [],
|
|
81
|
+
|
|
82
|
+
minMemoryMB: 512,
|
|
83
|
+
gpuRequired: false,
|
|
84
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { ServiceDefinition } from "../../types.js";
|
|
2
|
+
|
|
3
|
+
export const cmsaasStarterDefinition: ServiceDefinition = {
|
|
4
|
+
id: "cmsaas-starter",
|
|
5
|
+
name: "CMSaasStarter",
|
|
6
|
+
description:
|
|
7
|
+
"SvelteKit SaaS starter with Supabase backend, Stripe payments, user management, blog engine, SEO optimization, and edge deployment support.",
|
|
8
|
+
category: "saas-boilerplate",
|
|
9
|
+
icon: "🚀",
|
|
10
|
+
|
|
11
|
+
gitSource: {
|
|
12
|
+
repoUrl: "https://github.com/CriticalMoments/CMSaasStarter.git",
|
|
13
|
+
branch: "main",
|
|
14
|
+
postCloneCommands: [],
|
|
15
|
+
},
|
|
16
|
+
buildContext: {
|
|
17
|
+
dockerfile: "Dockerfile",
|
|
18
|
+
context: ".",
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
ports: [
|
|
22
|
+
{
|
|
23
|
+
host: 3104,
|
|
24
|
+
container: 3000,
|
|
25
|
+
description: "CMSaasStarter web application",
|
|
26
|
+
exposed: true,
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
volumes: [],
|
|
30
|
+
environment: [
|
|
31
|
+
{
|
|
32
|
+
key: "PUBLIC_SUPABASE_URL",
|
|
33
|
+
defaultValue: "",
|
|
34
|
+
secret: false,
|
|
35
|
+
description: "Supabase project URL",
|
|
36
|
+
required: true,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
key: "PUBLIC_SUPABASE_ANON_KEY",
|
|
40
|
+
defaultValue: "",
|
|
41
|
+
secret: false,
|
|
42
|
+
description: "Supabase anonymous/public key",
|
|
43
|
+
required: true,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
key: "PRIVATE_SUPABASE_SERVICE_ROLE",
|
|
47
|
+
defaultValue: "",
|
|
48
|
+
secret: true,
|
|
49
|
+
description: "Supabase service role key (server-side only)",
|
|
50
|
+
required: true,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
key: "PRIVATE_STRIPE_API_KEY",
|
|
54
|
+
defaultValue: "",
|
|
55
|
+
secret: true,
|
|
56
|
+
description: "Stripe secret API key",
|
|
57
|
+
required: true,
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
healthcheck: {
|
|
61
|
+
test: "wget -q --spider http://localhost:3000/ || exit 1",
|
|
62
|
+
interval: "30s",
|
|
63
|
+
timeout: "10s",
|
|
64
|
+
retries: 3,
|
|
65
|
+
startPeriod: "60s",
|
|
66
|
+
},
|
|
67
|
+
dependsOn: [],
|
|
68
|
+
restartPolicy: "unless-stopped",
|
|
69
|
+
networks: ["openclaw-network"],
|
|
70
|
+
|
|
71
|
+
skills: [],
|
|
72
|
+
openclawEnvVars: [],
|
|
73
|
+
|
|
74
|
+
docsUrl: "https://github.com/CriticalMoments/CMSaasStarter#readme",
|
|
75
|
+
tags: ["saas", "boilerplate", "sveltekit", "supabase", "stripe", "seo"],
|
|
76
|
+
maturity: "beta",
|
|
77
|
+
|
|
78
|
+
requires: [],
|
|
79
|
+
recommends: ["postgresql"],
|
|
80
|
+
conflictsWith: [],
|
|
81
|
+
|
|
82
|
+
minMemoryMB: 256,
|
|
83
|
+
gpuRequired: false,
|
|
84
|
+
};
|