@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/src/composer.ts
CHANGED
|
@@ -23,7 +23,7 @@ function getOpenclawImage(variant: OpenclawImageVariant, version: string): strin
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
/** Creates a YAML scalar that is always quoted — avoids YAML 1.1 bare `no` → false. */
|
|
26
|
-
function quotedStr(value: string): Scalar {
|
|
26
|
+
export function quotedStr(value: string): Scalar {
|
|
27
27
|
const s = new Scalar(value);
|
|
28
28
|
s.type = Scalar.QUOTE_DOUBLE;
|
|
29
29
|
return s;
|
|
@@ -53,7 +53,7 @@ const CATEGORY_PROFILE_MAP: Partial<Record<ServiceCategory, { file: string; prof
|
|
|
53
53
|
"saas-boilerplate": { file: "docker-compose.saas.yml", profile: "saas" },
|
|
54
54
|
};
|
|
55
55
|
|
|
56
|
-
const YAML_OPTIONS = { lineWidth: 120, nullStr: "" };
|
|
56
|
+
export const YAML_OPTIONS = { lineWidth: 120, nullStr: "" };
|
|
57
57
|
|
|
58
58
|
// ── Shared Gateway Builder ──────────────────────────────────────────────────
|
|
59
59
|
|
|
@@ -222,7 +222,7 @@ function buildGatewayServices(
|
|
|
222
222
|
|
|
223
223
|
// ── Shared Companion Service Builder ────────────────────────────────────────
|
|
224
224
|
|
|
225
|
-
function buildCompanionService(
|
|
225
|
+
export function buildCompanionService(
|
|
226
226
|
def: ResolverOutput["services"][number]["definition"],
|
|
227
227
|
resolved: ResolverOutput,
|
|
228
228
|
options: ComposeOptions,
|
|
@@ -445,7 +445,7 @@ function buildCompanionService(
|
|
|
445
445
|
*
|
|
446
446
|
* Returns null when no setup is needed (no PostgreSQL or no DB requirements).
|
|
447
447
|
*/
|
|
448
|
-
function buildPostgresSetup(resolved: ResolverOutput): Record<string, unknown> | null {
|
|
448
|
+
export function buildPostgresSetup(resolved: ResolverOutput): Record<string, unknown> | null {
|
|
449
449
|
const hasPostgres = resolved.services.some((s) => s.definition.id === "postgresql");
|
|
450
450
|
if (!hasPostgres) return null;
|
|
451
451
|
|
|
@@ -52,6 +52,8 @@ const DB_REQUIREMENTS: Record<string, Omit<DbRequirement, "serviceId" | "service
|
|
|
52
52
|
openpanel: { dbName: "openpanel", dbUser: "openpanel", passwordEnvVar: "OPENPANEL_DB_PASSWORD" },
|
|
53
53
|
usesend: { dbName: "usesend", dbUser: "usesend", passwordEnvVar: "USESEND_DB_PASSWORD" },
|
|
54
54
|
nextcloud: { dbName: "nextcloud", dbUser: "nextcloud", passwordEnvVar: "NEXTCLOUD_DB_PASSWORD" },
|
|
55
|
+
// ── Agent Memory ────────────────────────────────────────────────────────
|
|
56
|
+
hindsight: { dbName: "hindsight", dbUser: "hindsight", passwordEnvVar: "HINDSIGHT_DB_PASSWORD" },
|
|
55
57
|
// ── SaaS Boilerplates ────────────────────────────────────────────────────
|
|
56
58
|
"open-saas": { dbName: "opensaas", dbUser: "opensaas", passwordEnvVar: "OPENSAAS_DB_PASSWORD" },
|
|
57
59
|
"apptension-saas": {
|
package/src/generators/skills.ts
CHANGED
|
@@ -535,6 +535,148 @@ curl -X POST http://{{STEEL_HOST}}:{{STEEL_PORT}}/v1/scrape \\
|
|
|
535
535
|
- Proxy support and IP rotation
|
|
536
536
|
- Auto CAPTCHA solving
|
|
537
537
|
- Puppeteer/Playwright/Selenium compatible
|
|
538
|
+
`,
|
|
539
|
+
|
|
540
|
+
"code-sandbox": `---
|
|
541
|
+
name: code-sandbox
|
|
542
|
+
description: "Execute code safely in an isolated OpenSandbox container"
|
|
543
|
+
metadata:
|
|
544
|
+
openclaw:
|
|
545
|
+
emoji: "📦"
|
|
546
|
+
---
|
|
547
|
+
|
|
548
|
+
# Code Sandbox
|
|
549
|
+
|
|
550
|
+
Execute code safely in an isolated OpenSandbox container.
|
|
551
|
+
|
|
552
|
+
## Description
|
|
553
|
+
|
|
554
|
+
This skill provides secure, containerized code execution for AI agents. Code runs in ephemeral Docker containers with resource limits, network isolation, and automatic cleanup.
|
|
555
|
+
|
|
556
|
+
## Connection Details
|
|
557
|
+
|
|
558
|
+
- **Host:** \`{{OPENSANDBOX_HOST}}\`
|
|
559
|
+
- **Port:** \`{{OPENSANDBOX_PORT}}\`
|
|
560
|
+
- **Auth:** API key (auto-configured)
|
|
561
|
+
|
|
562
|
+
## Supported Languages
|
|
563
|
+
|
|
564
|
+
- Python 3.12
|
|
565
|
+
- JavaScript / TypeScript (Node.js 22)
|
|
566
|
+
- Java 21
|
|
567
|
+
- Go 1.24
|
|
568
|
+
- Bash
|
|
569
|
+
|
|
570
|
+
## Available Actions
|
|
571
|
+
|
|
572
|
+
### execute_code
|
|
573
|
+
|
|
574
|
+
Run a code snippet in a fresh sandbox.
|
|
575
|
+
|
|
576
|
+
**Parameters:**
|
|
577
|
+
- \`language\` (required): Programming language ("python", "javascript", "typescript", "java", "go", "bash")
|
|
578
|
+
- \`code\` (required): The code to execute
|
|
579
|
+
- \`timeout_seconds\` (optional): Max execution time (default: 60, max: 300)
|
|
580
|
+
|
|
581
|
+
**Returns:** stdout, stderr, exit_code, execution_time_ms
|
|
582
|
+
|
|
583
|
+
### execute_shell
|
|
584
|
+
|
|
585
|
+
Run a shell command in an existing or new sandbox.
|
|
586
|
+
|
|
587
|
+
**Parameters:**
|
|
588
|
+
- \`command\` (required): Shell command to execute
|
|
589
|
+
- \`sandbox_id\` (optional): Reuse an existing sandbox (for multi-step workflows)
|
|
590
|
+
- \`background\` (optional): Run in background (default: false)
|
|
591
|
+
|
|
592
|
+
**Returns:** stdout, stderr, exit_code
|
|
593
|
+
|
|
594
|
+
### upload_file
|
|
595
|
+
|
|
596
|
+
Upload a file to a sandbox for processing.
|
|
597
|
+
|
|
598
|
+
**Parameters:**
|
|
599
|
+
- \`sandbox_id\` (required): Target sandbox
|
|
600
|
+
- \`path\` (required): Destination path inside sandbox
|
|
601
|
+
- \`content\` (required): File content (text or base64 for binary)
|
|
602
|
+
|
|
603
|
+
### download_file
|
|
604
|
+
|
|
605
|
+
Download a file from a sandbox.
|
|
606
|
+
|
|
607
|
+
**Parameters:**
|
|
608
|
+
- \`sandbox_id\` (required): Source sandbox
|
|
609
|
+
- \`path\` (required): File path inside sandbox
|
|
610
|
+
|
|
611
|
+
**Returns:** File content
|
|
612
|
+
|
|
613
|
+
### list_sandboxes
|
|
614
|
+
|
|
615
|
+
List active sandboxes on this instance.
|
|
616
|
+
|
|
617
|
+
**Returns:** Array of { id, status, image, created_at, expires_at }
|
|
618
|
+
|
|
619
|
+
### terminate_sandbox
|
|
620
|
+
|
|
621
|
+
Terminate a running sandbox immediately.
|
|
622
|
+
|
|
623
|
+
**Parameters:**
|
|
624
|
+
- \`sandbox_id\` (required): Sandbox to terminate
|
|
625
|
+
|
|
626
|
+
### create_desktop
|
|
627
|
+
|
|
628
|
+
Create a GUI desktop sandbox with VNC access (for Homespace live preview).
|
|
629
|
+
|
|
630
|
+
**Parameters:**
|
|
631
|
+
- \`image\` (optional): Desktop image (default: "opensandbox/desktop:latest", also: "opensandbox/chrome:latest", "opensandbox/vscode:latest")
|
|
632
|
+
- \`resolution\` (optional): Screen resolution (default: "1280x800x24")
|
|
633
|
+
|
|
634
|
+
**Returns:** sandbox_id, vnc_endpoint (port 5900), novnc_url (port 6080 WebSocket), devtools_url (port 9222, chrome only)
|
|
635
|
+
|
|
636
|
+
### get_preview_url
|
|
637
|
+
|
|
638
|
+
Get the browser-accessible noVNC URL for an existing desktop sandbox.
|
|
639
|
+
|
|
640
|
+
**Parameters:**
|
|
641
|
+
- \`sandbox_id\` (required): Desktop sandbox ID
|
|
642
|
+
|
|
643
|
+
**Returns:** novnc_url (embeddable in iframe), vnc_endpoint, status
|
|
644
|
+
|
|
645
|
+
## Examples
|
|
646
|
+
|
|
647
|
+
### Run Python code
|
|
648
|
+
|
|
649
|
+
\`\`\`bash
|
|
650
|
+
curl -X POST http://{{OPENSANDBOX_HOST}}:{{OPENSANDBOX_PORT}}/v1/sandboxes \\
|
|
651
|
+
-H "Authorization: Bearer $OPENSANDBOX_API_KEY" \\
|
|
652
|
+
-H "Content-Type: application/json" \\
|
|
653
|
+
-d '{"image": "opensandbox/code-interpreter:python"}'
|
|
654
|
+
\`\`\`
|
|
655
|
+
|
|
656
|
+
### Execute code in a sandbox
|
|
657
|
+
|
|
658
|
+
\`\`\`bash
|
|
659
|
+
curl -X POST http://{{OPENSANDBOX_HOST}}:{{OPENSANDBOX_PORT}}/v1/sandboxes/{id}/code \\
|
|
660
|
+
-H "Authorization: Bearer $OPENSANDBOX_API_KEY" \\
|
|
661
|
+
-H "Content-Type: application/json" \\
|
|
662
|
+
-d '{"language": "python", "code": "print(42 * 42)"}'
|
|
663
|
+
\`\`\`
|
|
664
|
+
|
|
665
|
+
## Configuration
|
|
666
|
+
|
|
667
|
+
- **Default timeout:** 60 seconds
|
|
668
|
+
- **Max concurrent sandboxes:** Determined by VPS RAM
|
|
669
|
+
- **Idle cleanup:** Sandboxes with no activity for 30 minutes are auto-terminated
|
|
670
|
+
- **Network:** Bridge mode (isolated from host services)
|
|
671
|
+
- **Security:** gVisor runtime, capability dropping, PID limits
|
|
672
|
+
|
|
673
|
+
## Limitations
|
|
674
|
+
|
|
675
|
+
- No persistent storage between sandbox sessions (ephemeral by design)
|
|
676
|
+
- No GPU access (CPU-only execution)
|
|
677
|
+
- No outbound network access by default (egress blocked)
|
|
678
|
+
- Max 512 PIDs per sandbox (fork bomb protection)
|
|
679
|
+
- Memory capped per sandbox (default 512MB)
|
|
538
680
|
`,
|
|
539
681
|
};
|
|
540
682
|
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
// ───
|
|
1
|
+
// ─── Addon Stack (Clawexa) ──────────────────────────────────────────────────
|
|
2
|
+
export { generateAddonStack, updateAddonStack } from "./addon-stack.js";
|
|
2
3
|
|
|
3
4
|
// ─── Core Engines ───────────────────────────────────────────────────────────
|
|
4
5
|
export {
|
|
@@ -7,7 +8,7 @@ export {
|
|
|
7
8
|
resolvedWithOnlyServices,
|
|
8
9
|
} from "./bare-metal-partition.js";
|
|
9
10
|
export type { ComposeResult } from "./composer.js";
|
|
10
|
-
export { compose, composeMultiFile } from "./composer.js";
|
|
11
|
+
export { buildCompanionService, buildPostgresSetup, compose, composeMultiFile, quotedStr, YAML_OPTIONS } from "./composer.js";
|
|
11
12
|
// ─── PaaS Deployers ─────────────────────────────────────────────────────────
|
|
12
13
|
export type {
|
|
13
14
|
DeployInput as PaasDeployInput,
|
|
@@ -71,6 +72,10 @@ export {
|
|
|
71
72
|
} from "./presets/registry.js";
|
|
72
73
|
export { resolve } from "./resolver.js";
|
|
73
74
|
export {
|
|
75
|
+
AddonStackInputSchema,
|
|
76
|
+
AddonStackResultSchema,
|
|
77
|
+
AddonStackUpdateInputSchema,
|
|
78
|
+
AddonStackUpdateResultSchema,
|
|
74
79
|
AddedDependencySchema,
|
|
75
80
|
ApiErrorSchema,
|
|
76
81
|
BuildContextSchema,
|
|
@@ -79,6 +84,8 @@ export {
|
|
|
79
84
|
DeploymentTypeSchema,
|
|
80
85
|
DeploySchema,
|
|
81
86
|
DeployTargetSchema,
|
|
87
|
+
EnvQuirkFixSchema,
|
|
88
|
+
EnvQuirkSchema,
|
|
82
89
|
EnvVariableSchema,
|
|
83
90
|
ErrorSchema,
|
|
84
91
|
GenerationInputSchema,
|
|
@@ -93,6 +100,7 @@ export {
|
|
|
93
100
|
PlatformSchema,
|
|
94
101
|
PortMappingSchema,
|
|
95
102
|
PresetSchema,
|
|
103
|
+
ProxyRouteSchema,
|
|
96
104
|
ProxyTypeSchema,
|
|
97
105
|
ResolvedServiceSchema,
|
|
98
106
|
ResolverOutputSchema,
|
|
@@ -102,6 +110,8 @@ export {
|
|
|
102
110
|
ServiceDefinitionSchema,
|
|
103
111
|
SkillBindingSchema,
|
|
104
112
|
SkillPackSchema,
|
|
113
|
+
SkippedServiceReasonSchema,
|
|
114
|
+
SkippedServiceSchema,
|
|
105
115
|
ValidateRequestSchema,
|
|
106
116
|
ValidateResponseSchema,
|
|
107
117
|
VolumeMappingSchema,
|
|
@@ -130,6 +140,10 @@ export {
|
|
|
130
140
|
} from "./skills/skill-manifest.js";
|
|
131
141
|
// ─── Types ──────────────────────────────────────────────────────────────────
|
|
132
142
|
export type {
|
|
143
|
+
AddonStackInput,
|
|
144
|
+
AddonStackResult,
|
|
145
|
+
AddonStackUpdateInput,
|
|
146
|
+
AddonStackUpdateResult,
|
|
133
147
|
AddedDependency,
|
|
134
148
|
AiProvider,
|
|
135
149
|
ApiError,
|
|
@@ -140,6 +154,8 @@ export type {
|
|
|
140
154
|
DeploymentTarget,
|
|
141
155
|
DeploymentType,
|
|
142
156
|
DeployTarget,
|
|
157
|
+
EnvQuirk,
|
|
158
|
+
EnvQuirkFix,
|
|
143
159
|
EnvVariable,
|
|
144
160
|
GeneratedFiles,
|
|
145
161
|
GenerationInput,
|
|
@@ -157,6 +173,7 @@ export type {
|
|
|
157
173
|
Platform,
|
|
158
174
|
PortMapping,
|
|
159
175
|
Preset,
|
|
176
|
+
ProxyRoute,
|
|
160
177
|
ProxyType,
|
|
161
178
|
ResolvedService,
|
|
162
179
|
ResolverError,
|
|
@@ -168,6 +185,7 @@ export type {
|
|
|
168
185
|
ServiceDefinition,
|
|
169
186
|
SkillBinding,
|
|
170
187
|
SkillPack,
|
|
188
|
+
SkippedService,
|
|
171
189
|
ValidateRequest,
|
|
172
190
|
ValidateResponse,
|
|
173
191
|
VolumeMapping,
|
package/src/schema.ts
CHANGED
|
@@ -178,6 +178,24 @@ export const BuildContextSchema = z.object({
|
|
|
178
178
|
target: z.string().optional(),
|
|
179
179
|
});
|
|
180
180
|
|
|
181
|
+
// ─── Env Quirks (for addon stack generation) ────────────────────────────────
|
|
182
|
+
|
|
183
|
+
export const EnvQuirkFixSchema = z.object({
|
|
184
|
+
type: z.enum(["set_value", "generate_hex", "generate_base64url", "sync_with"]),
|
|
185
|
+
/** Fixed value to set (for set_value type). */
|
|
186
|
+
value: z.string().optional(),
|
|
187
|
+
/** Minimum bytes for generated secrets (for generate_hex/generate_base64url). */
|
|
188
|
+
minBytes: z.number().int().min(1).optional(),
|
|
189
|
+
/** Key to synchronize with (for sync_with type). */
|
|
190
|
+
syncKey: z.string().optional(),
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
export const EnvQuirkSchema = z.object({
|
|
194
|
+
key: z.string(),
|
|
195
|
+
issue: z.enum(["empty_string_crashes", "min_length", "must_sync"]),
|
|
196
|
+
fix: EnvQuirkFixSchema,
|
|
197
|
+
});
|
|
198
|
+
|
|
181
199
|
// ─── Service Definition ─────────────────────────────────────────────────────
|
|
182
200
|
|
|
183
201
|
export const ServiceDefinitionSchema = z.object({
|
|
@@ -236,6 +254,18 @@ export const ServiceDefinitionSchema = z.object({
|
|
|
236
254
|
// Bare-metal native (install/run on host when no Docker)
|
|
237
255
|
nativeSupported: z.boolean().optional(),
|
|
238
256
|
nativeRecipes: z.array(NativeRecipeSchema).optional(),
|
|
257
|
+
|
|
258
|
+
// Clawexa addon metadata
|
|
259
|
+
/** Whether the service works with cap_drop: ALL (default: undefined = not audited). */
|
|
260
|
+
capDropCompatible: z.boolean().optional(),
|
|
261
|
+
/** Pre-built Docker image for cloud-init deployment (replaces build: directives). */
|
|
262
|
+
prebuiltImage: z.string().optional(),
|
|
263
|
+
/** Default reverse proxy path (e.g. "/n8n", "/grafana"). */
|
|
264
|
+
proxyPath: z.string().optional(),
|
|
265
|
+
/** Linux capabilities needed at first boot (e.g. ["CHOWN", "SETGID"]). */
|
|
266
|
+
firstBootCapabilities: z.array(z.string()).optional(),
|
|
267
|
+
/** Known environment variable quirks that need special handling. */
|
|
268
|
+
envQuirks: z.array(EnvQuirkSchema).optional(),
|
|
239
269
|
});
|
|
240
270
|
|
|
241
271
|
// ─── Skill Pack ─────────────────────────────────────────────────────────────
|
|
@@ -364,6 +394,166 @@ export const ComposeOptionsSchema = z.object({
|
|
|
364
394
|
openclawInstallMethod: OpenclawInstallMethodSchema.default("docker"),
|
|
365
395
|
});
|
|
366
396
|
|
|
397
|
+
// ─── Addon Stack (Clawexa) ───────────────────────────────────────────────────
|
|
398
|
+
|
|
399
|
+
export const SkippedServiceReasonSchema = z.enum([
|
|
400
|
+
"missing_credentials",
|
|
401
|
+
"no_image",
|
|
402
|
+
"platform_unsupported",
|
|
403
|
+
"conflict",
|
|
404
|
+
"gpu_required",
|
|
405
|
+
"unknown_service",
|
|
406
|
+
"resolution_error",
|
|
407
|
+
]);
|
|
408
|
+
|
|
409
|
+
export const SkippedServiceSchema = z.object({
|
|
410
|
+
serviceId: z.string(),
|
|
411
|
+
reason: SkippedServiceReasonSchema,
|
|
412
|
+
details: z.string(),
|
|
413
|
+
requiredCredentials: z.array(z.string()).optional(),
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
export const ProxyRouteSchema = z.object({
|
|
417
|
+
serviceId: z.string(),
|
|
418
|
+
path: z.string(),
|
|
419
|
+
port: z.number().int(),
|
|
420
|
+
protocol: z.enum(["http", "https", "ws"]).default("http"),
|
|
421
|
+
stripPrefix: z.boolean().default(true),
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
export const AddonStackInputSchema = z.object({
|
|
425
|
+
/** Instance identifier (used for project name sanitization). */
|
|
426
|
+
instanceId: z.string().min(1),
|
|
427
|
+
/** Addon service IDs to deploy. */
|
|
428
|
+
services: z.array(z.string()),
|
|
429
|
+
/** Optional skill packs. */
|
|
430
|
+
skillPacks: z.array(z.string()).default([]),
|
|
431
|
+
/** Platform architecture. */
|
|
432
|
+
platform: PlatformSchema.default("linux/amd64"),
|
|
433
|
+
/** OpenClaw version running on the instance. */
|
|
434
|
+
openclawVersion: z.string().default("latest"),
|
|
435
|
+
/** Services already running on the instance (to detect conflicts). */
|
|
436
|
+
existingServices: z.array(z.string()).default([]),
|
|
437
|
+
/** Ports already in use on the host. */
|
|
438
|
+
reservedPorts: z.array(z.number().int()).default([]),
|
|
439
|
+
/** Whether to generate secrets (default: true). */
|
|
440
|
+
generateSecrets: z.boolean().default(true),
|
|
441
|
+
/** User-provided credentials for services that need them. */
|
|
442
|
+
credentials: z.record(z.string(), z.record(z.string(), z.string())).default({}),
|
|
443
|
+
/** Port overrides for specific services. */
|
|
444
|
+
portOverrides: z.record(z.string(), z.record(z.string(), z.number().int().min(1).max(65535))).optional(),
|
|
445
|
+
/** Whether the host has GPU support. */
|
|
446
|
+
gpu: z.boolean().default(false),
|
|
447
|
+
/** AI providers configured on this instance. */
|
|
448
|
+
aiProviders: z.array(AiProviderSchema).default([]),
|
|
449
|
+
/** Pre-built image overrides (serviceId → image:tag). */
|
|
450
|
+
prebuiltImages: z.record(z.string(), z.string()).default({}),
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
export const AddonStackResultSchema = z.object({
|
|
454
|
+
/** Single docker-compose.override.yml content. */
|
|
455
|
+
composeOverride: z.string(),
|
|
456
|
+
/** Complete .env file with all secrets generated. */
|
|
457
|
+
envFile: z.string(),
|
|
458
|
+
/** Structured env vars for UI display / credential management. */
|
|
459
|
+
envVars: z.array(z.object({
|
|
460
|
+
serviceName: z.string(),
|
|
461
|
+
vars: z.array(z.object({
|
|
462
|
+
key: z.string(),
|
|
463
|
+
description: z.string(),
|
|
464
|
+
value: z.string(),
|
|
465
|
+
secret: z.boolean(),
|
|
466
|
+
})),
|
|
467
|
+
})),
|
|
468
|
+
/** SKILL.md files keyed by slug. */
|
|
469
|
+
skillFiles: z.record(z.string(), z.string()),
|
|
470
|
+
/** OpenClaw config additions (skills.entries to merge). */
|
|
471
|
+
openclawConfigPatch: z.object({
|
|
472
|
+
skills: z.object({
|
|
473
|
+
entries: z.record(z.string(), z.object({ enabled: z.boolean() })),
|
|
474
|
+
}),
|
|
475
|
+
}),
|
|
476
|
+
/** Port mapping for reverse proxy configuration. */
|
|
477
|
+
proxyRoutes: z.array(ProxyRouteSchema),
|
|
478
|
+
/** Additional files to write alongside compose (e.g. sandbox.toml). Keyed by filename. */
|
|
479
|
+
additionalFiles: z.record(z.string(), z.string()).default({}),
|
|
480
|
+
/** Metadata. */
|
|
481
|
+
metadata: z.object({
|
|
482
|
+
serviceCount: z.number(),
|
|
483
|
+
skillCount: z.number(),
|
|
484
|
+
estimatedMemoryMB: z.number(),
|
|
485
|
+
resolvedServices: z.array(z.string()),
|
|
486
|
+
skippedServices: z.array(SkippedServiceSchema),
|
|
487
|
+
generatedSecretKeys: z.array(z.string()),
|
|
488
|
+
portAssignments: z.record(z.string(), z.number()),
|
|
489
|
+
/** Docker images to pre-pull during cloud-init, grouped by priority. */
|
|
490
|
+
prePullImages: z.array(z.object({
|
|
491
|
+
image: z.string(),
|
|
492
|
+
priority: z.union([z.literal(1), z.literal(2), z.literal(3)]),
|
|
493
|
+
})).default([]),
|
|
494
|
+
}),
|
|
495
|
+
/** Warnings (non-fatal issues). */
|
|
496
|
+
warnings: z.array(z.string()),
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
export const AddonStackUpdateInputSchema = z.object({
|
|
500
|
+
instanceId: z.string().min(1),
|
|
501
|
+
/** Current compose override YAML (from the running instance). */
|
|
502
|
+
currentCompose: z.string(),
|
|
503
|
+
/** Current .env content. */
|
|
504
|
+
currentEnv: z.string(),
|
|
505
|
+
/** Services to add. */
|
|
506
|
+
addServices: z.array(z.string()).default([]),
|
|
507
|
+
/** Services to remove. */
|
|
508
|
+
removeServices: z.array(z.string()).default([]),
|
|
509
|
+
/** Whether to generate secrets for newly added services (default: true). */
|
|
510
|
+
generateSecrets: z.boolean().default(true),
|
|
511
|
+
/** User-provided credentials for new services. */
|
|
512
|
+
credentials: z.record(z.string(), z.record(z.string(), z.string())).default({}),
|
|
513
|
+
/** Port overrides for specific services. */
|
|
514
|
+
portOverrides: z.record(z.string(), z.record(z.string(), z.number().int().min(1).max(65535))).optional(),
|
|
515
|
+
/** Reserved ports. */
|
|
516
|
+
reservedPorts: z.array(z.number().int()).default([]),
|
|
517
|
+
platform: PlatformSchema.default("linux/amd64"),
|
|
518
|
+
openclawVersion: z.string().default("latest"),
|
|
519
|
+
aiProviders: z.array(AiProviderSchema).default([]),
|
|
520
|
+
prebuiltImages: z.record(z.string(), z.string()).default({}),
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
export const AddonStackUpdateResultSchema = z.object({
|
|
524
|
+
/** Updated compose override (merged with existing). */
|
|
525
|
+
composeOverride: z.string(),
|
|
526
|
+
/** Updated .env (existing values preserved, new ones added). */
|
|
527
|
+
envFile: z.string(),
|
|
528
|
+
/** Only NEW skill files to deploy. */
|
|
529
|
+
newSkillFiles: z.record(z.string(), z.string()),
|
|
530
|
+
/** Skill slugs to remove from openclaw.json. */
|
|
531
|
+
removedSkillSlugs: z.array(z.string()),
|
|
532
|
+
/** Config patch to apply. */
|
|
533
|
+
openclawConfigPatch: z.object({
|
|
534
|
+
skills: z.object({
|
|
535
|
+
add: z.record(z.string(), z.object({ enabled: z.boolean() })),
|
|
536
|
+
remove: z.array(z.string()),
|
|
537
|
+
}),
|
|
538
|
+
}),
|
|
539
|
+
/** New proxy routes to add. */
|
|
540
|
+
addProxyRoutes: z.array(ProxyRouteSchema),
|
|
541
|
+
/** Proxy routes to remove (service IDs). */
|
|
542
|
+
removeProxyRoutes: z.array(z.string()),
|
|
543
|
+
/** Services that need their images pulled. */
|
|
544
|
+
imagesToPull: z.array(z.string()),
|
|
545
|
+
/** Services to restart (due to dependency changes). */
|
|
546
|
+
restartRequired: z.array(z.string()),
|
|
547
|
+
/** Metadata. */
|
|
548
|
+
metadata: z.object({
|
|
549
|
+
added: z.array(z.string()),
|
|
550
|
+
removed: z.array(z.string()),
|
|
551
|
+
unchanged: z.array(z.string()),
|
|
552
|
+
estimatedMemoryDelta: z.number(),
|
|
553
|
+
}),
|
|
554
|
+
warnings: z.array(z.string()),
|
|
555
|
+
});
|
|
556
|
+
|
|
367
557
|
// ─── API Request/Response ───────────────────────────────────────────────────
|
|
368
558
|
|
|
369
559
|
export const ValidateRequestSchema = z.object({
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import type { ServiceDefinition } from "../../types.js";
|
|
2
|
+
|
|
3
|
+
export const burnlinkDefinition: ServiceDefinition = {
|
|
4
|
+
id: "burnlink",
|
|
5
|
+
name: "BurnLink",
|
|
6
|
+
description:
|
|
7
|
+
"Privacy-first, zero-knowledge file sharing with end-to-end browser-side AES-256-GCM encryption, one-time downloads, view-once mode, and brute-force protection.",
|
|
8
|
+
category: "storage",
|
|
9
|
+
icon: "🔥",
|
|
10
|
+
|
|
11
|
+
image: "diopisemou/burnlink",
|
|
12
|
+
imageTag: "latest",
|
|
13
|
+
ports: [
|
|
14
|
+
{
|
|
15
|
+
host: 3250,
|
|
16
|
+
container: 3000,
|
|
17
|
+
description: "BurnLink web interface",
|
|
18
|
+
exposed: true,
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
volumes: [],
|
|
22
|
+
environment: [
|
|
23
|
+
{
|
|
24
|
+
key: "PORT",
|
|
25
|
+
defaultValue: "3000",
|
|
26
|
+
secret: false,
|
|
27
|
+
description: "Server listen port",
|
|
28
|
+
required: false,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
key: "SUPABASE_URL",
|
|
32
|
+
defaultValue: "",
|
|
33
|
+
secret: false,
|
|
34
|
+
description: "Supabase project URL for metadata storage",
|
|
35
|
+
required: true,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
key: "SUPABASE_SERVICE_ROLE_KEY",
|
|
39
|
+
defaultValue: "",
|
|
40
|
+
secret: true,
|
|
41
|
+
description: "Supabase service role key",
|
|
42
|
+
required: true,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
key: "R2_ACCOUNT_ID",
|
|
46
|
+
defaultValue: "",
|
|
47
|
+
secret: false,
|
|
48
|
+
description: "Cloudflare R2 account ID (or MinIO endpoint for self-hosted)",
|
|
49
|
+
required: true,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
key: "R2_ACCESS_KEY_ID",
|
|
53
|
+
defaultValue: "",
|
|
54
|
+
secret: true,
|
|
55
|
+
description: "S3-compatible storage access key",
|
|
56
|
+
required: true,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
key: "R2_SECRET_ACCESS_KEY",
|
|
60
|
+
defaultValue: "",
|
|
61
|
+
secret: true,
|
|
62
|
+
description: "S3-compatible storage secret key",
|
|
63
|
+
required: true,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
key: "R2_BUCKET_NAME",
|
|
67
|
+
defaultValue: "burnlink",
|
|
68
|
+
secret: false,
|
|
69
|
+
description: "Storage bucket name for encrypted files",
|
|
70
|
+
required: true,
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
key: "CANONICAL_BASE_URL",
|
|
74
|
+
defaultValue: "",
|
|
75
|
+
secret: false,
|
|
76
|
+
description: "Public URL for share links (e.g., https://burn.example.com)",
|
|
77
|
+
required: false,
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
key: "MAX_UPLOAD_BYTES",
|
|
81
|
+
defaultValue: "1073741824",
|
|
82
|
+
secret: false,
|
|
83
|
+
description: "Max file upload size in bytes (default 1 GB)",
|
|
84
|
+
required: false,
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
key: "NODE_ENV",
|
|
88
|
+
defaultValue: "production",
|
|
89
|
+
secret: false,
|
|
90
|
+
description: "Node environment (production enables rate limiting)",
|
|
91
|
+
required: false,
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
healthcheck: {
|
|
95
|
+
test: "wget -q --spider http://localhost:3000/ || exit 1",
|
|
96
|
+
interval: "30s",
|
|
97
|
+
timeout: "10s",
|
|
98
|
+
retries: 3,
|
|
99
|
+
startPeriod: "15s",
|
|
100
|
+
},
|
|
101
|
+
dependsOn: [],
|
|
102
|
+
restartPolicy: "unless-stopped",
|
|
103
|
+
networks: ["openclaw-network"],
|
|
104
|
+
|
|
105
|
+
skills: [],
|
|
106
|
+
openclawEnvVars: [
|
|
107
|
+
{
|
|
108
|
+
key: "BURNLINK_HOST",
|
|
109
|
+
defaultValue: "burnlink",
|
|
110
|
+
secret: false,
|
|
111
|
+
description: "BurnLink hostname",
|
|
112
|
+
required: false,
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
key: "BURNLINK_PORT",
|
|
116
|
+
defaultValue: "3000",
|
|
117
|
+
secret: false,
|
|
118
|
+
description: "BurnLink internal port",
|
|
119
|
+
required: false,
|
|
120
|
+
},
|
|
121
|
+
],
|
|
122
|
+
|
|
123
|
+
docsUrl: "https://github.com/diopisemou/BurnLink",
|
|
124
|
+
tags: ["file-sharing", "encryption", "privacy", "zero-knowledge", "self-destruct"],
|
|
125
|
+
maturity: "beta",
|
|
126
|
+
|
|
127
|
+
requires: [],
|
|
128
|
+
recommends: ["supabase", "minio"],
|
|
129
|
+
conflictsWith: [],
|
|
130
|
+
|
|
131
|
+
minMemoryMB: 128,
|
|
132
|
+
gpuRequired: false,
|
|
133
|
+
capDropCompatible: true,
|
|
134
|
+
proxyPath: "/burnlink",
|
|
135
|
+
envQuirks: [
|
|
136
|
+
{
|
|
137
|
+
key: "R2_SECRET_ACCESS_KEY",
|
|
138
|
+
issue: "min_length" as const,
|
|
139
|
+
fix: { type: "generate_base64url" as const, minBytes: 24 },
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
};
|
|
@@ -89,6 +89,14 @@ export const convexDefinition: ServiceDefinition = {
|
|
|
89
89
|
"Admin key for CLI access. Generate with: docker compose exec convex ./generate_admin_key.sh",
|
|
90
90
|
required: false,
|
|
91
91
|
},
|
|
92
|
+
{
|
|
93
|
+
key: "CONVEX_INSTANCE_SECRET",
|
|
94
|
+
defaultValue: "${INSTANCE_SECRET}",
|
|
95
|
+
secret: true,
|
|
96
|
+
description:
|
|
97
|
+
"Convex instance secret used by Mission Control (synced with INSTANCE_SECRET)",
|
|
98
|
+
required: false,
|
|
99
|
+
},
|
|
92
100
|
],
|
|
93
101
|
healthcheck: {
|
|
94
102
|
test: "curl -f http://localhost:3210/version",
|
|
@@ -118,4 +126,27 @@ export const convexDefinition: ServiceDefinition = {
|
|
|
118
126
|
|
|
119
127
|
minMemoryMB: 256,
|
|
120
128
|
gpuRequired: false,
|
|
129
|
+
capDropCompatible: false,
|
|
130
|
+
envQuirks: [
|
|
131
|
+
{
|
|
132
|
+
key: "DISABLE_BEACON",
|
|
133
|
+
issue: "empty_string_crashes" as const,
|
|
134
|
+
fix: { type: "set_value" as const, value: "true" },
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
key: "INSTANCE_SECRET",
|
|
138
|
+
issue: "min_length" as const,
|
|
139
|
+
fix: { type: "generate_hex" as const, minBytes: 32 },
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
key: "CONVEX_SELF_HOSTED_ADMIN_KEY",
|
|
143
|
+
issue: "min_length" as const,
|
|
144
|
+
fix: { type: "generate_hex" as const, minBytes: 32 },
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
key: "INSTANCE_SECRET",
|
|
148
|
+
issue: "must_sync" as const,
|
|
149
|
+
fix: { type: "sync_with" as const, syncKey: "CONVEX_INSTANCE_SECRET" },
|
|
150
|
+
},
|
|
151
|
+
],
|
|
121
152
|
};
|
|
@@ -80,4 +80,13 @@ export const grafanaDefinition: ServiceDefinition = {
|
|
|
80
80
|
|
|
81
81
|
minMemoryMB: 256,
|
|
82
82
|
gpuRequired: false,
|
|
83
|
+
capDropCompatible: true,
|
|
84
|
+
proxyPath: "/grafana",
|
|
85
|
+
envQuirks: [
|
|
86
|
+
{
|
|
87
|
+
key: "GF_SECURITY_ADMIN_PASSWORD",
|
|
88
|
+
issue: "min_length" as const,
|
|
89
|
+
fix: { type: "generate_base64url" as const, minBytes: 16 },
|
|
90
|
+
},
|
|
91
|
+
],
|
|
83
92
|
};
|