@better-openclaw/core 1.0.14 → 1.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dist/{manifest-BjK4ALvr.mjs → manifest-B8UDsVlR.mjs} +39 -13
  2. package/dist/manifest-B8UDsVlR.mjs.map +1 -0
  3. package/dist/resolver.mjs.map +1 -1
  4. package/dist/services/definitions/authentik.d.mts +7 -0
  5. package/dist/services/definitions/authentik.d.mts.map +1 -0
  6. package/dist/services/definitions/authentik.mjs +105 -0
  7. package/dist/services/definitions/authentik.mjs.map +1 -0
  8. package/dist/services/definitions/crowdsec.d.mts +7 -0
  9. package/dist/services/definitions/crowdsec.d.mts.map +1 -0
  10. package/dist/services/definitions/crowdsec.mjs +62 -0
  11. package/dist/services/definitions/crowdsec.mjs.map +1 -0
  12. package/dist/services/definitions/ghost.d.mts +7 -0
  13. package/dist/services/definitions/ghost.d.mts.map +1 -0
  14. package/dist/services/definitions/ghost.mjs +58 -0
  15. package/dist/services/definitions/ghost.mjs.map +1 -0
  16. package/dist/services/definitions/headscale.d.mts +7 -0
  17. package/dist/services/definitions/headscale.d.mts.map +1 -0
  18. package/dist/services/definitions/headscale.mjs +71 -0
  19. package/dist/services/definitions/headscale.mjs.map +1 -0
  20. package/dist/services/definitions/homeassistant.d.mts +7 -0
  21. package/dist/services/definitions/homeassistant.d.mts.map +1 -0
  22. package/dist/services/definitions/homeassistant.mjs +61 -0
  23. package/dist/services/definitions/homeassistant.mjs.map +1 -0
  24. package/dist/services/definitions/immich.d.mts +7 -0
  25. package/dist/services/definitions/immich.d.mts.map +1 -0
  26. package/dist/services/definitions/immich.mjs +92 -0
  27. package/dist/services/definitions/immich.mjs.map +1 -0
  28. package/dist/services/definitions/index.d.mts +15 -1
  29. package/dist/services/definitions/index.d.mts.map +1 -1
  30. package/dist/services/definitions/index.mjs +30 -2
  31. package/dist/services/definitions/index.mjs.map +1 -1
  32. package/dist/services/definitions/jellyfin.d.mts +7 -0
  33. package/dist/services/definitions/jellyfin.d.mts.map +1 -0
  34. package/dist/services/definitions/jellyfin.mjs +62 -0
  35. package/dist/services/definitions/jellyfin.mjs.map +1 -0
  36. package/dist/services/definitions/jenkins.d.mts +7 -0
  37. package/dist/services/definitions/jenkins.d.mts.map +1 -0
  38. package/dist/services/definitions/jenkins.mjs +62 -0
  39. package/dist/services/definitions/jenkins.mjs.map +1 -0
  40. package/dist/services/definitions/loki.d.mts +7 -0
  41. package/dist/services/definitions/loki.d.mts.map +1 -0
  42. package/dist/services/definitions/loki.mjs +51 -0
  43. package/dist/services/definitions/loki.mjs.map +1 -0
  44. package/dist/services/definitions/milvus.d.mts +7 -0
  45. package/dist/services/definitions/milvus.d.mts.map +1 -0
  46. package/dist/services/definitions/milvus.mjs +75 -0
  47. package/dist/services/definitions/milvus.mjs.map +1 -0
  48. package/dist/services/definitions/nextcloud.d.mts +7 -0
  49. package/dist/services/definitions/nextcloud.d.mts.map +1 -0
  50. package/dist/services/definitions/nextcloud.mjs +80 -0
  51. package/dist/services/definitions/nextcloud.mjs.map +1 -0
  52. package/dist/services/definitions/signoz.d.mts +7 -0
  53. package/dist/services/definitions/signoz.d.mts.map +1 -0
  54. package/dist/services/definitions/signoz.mjs +54 -0
  55. package/dist/services/definitions/signoz.mjs.map +1 -0
  56. package/dist/services/definitions/supabase.d.mts +7 -0
  57. package/dist/services/definitions/supabase.d.mts.map +1 -0
  58. package/dist/services/definitions/supabase.mjs +69 -0
  59. package/dist/services/definitions/supabase.mjs.map +1 -0
  60. package/dist/services/definitions/vaultwarden.d.mts +7 -0
  61. package/dist/services/definitions/vaultwarden.d.mts.map +1 -0
  62. package/dist/services/definitions/vaultwarden.mjs +63 -0
  63. package/dist/services/definitions/vaultwarden.mjs.map +1 -0
  64. package/dist/skills/skill-manifest.mjs +1 -1
  65. package/package.json +1 -1
  66. package/src/resolver.ts +10 -10
  67. package/src/services/definitions/authentik.ts +106 -0
  68. package/src/services/definitions/crowdsec.ts +66 -0
  69. package/src/services/definitions/ghost.ts +60 -0
  70. package/src/services/definitions/headscale.ts +72 -0
  71. package/src/services/definitions/homeassistant.ts +65 -0
  72. package/src/services/definitions/immich.ts +93 -0
  73. package/src/services/definitions/index.ts +42 -0
  74. package/src/services/definitions/jellyfin.ts +66 -0
  75. package/src/services/definitions/jenkins.ts +67 -0
  76. package/src/services/definitions/loki.ts +53 -0
  77. package/src/services/definitions/milvus.ts +84 -0
  78. package/src/services/definitions/nextcloud.ts +81 -0
  79. package/src/services/definitions/signoz.ts +54 -0
  80. package/src/services/definitions/supabase.ts +73 -0
  81. package/src/services/definitions/vaultwarden.ts +68 -0
  82. package/src/skills/manifest.json +63 -12
  83. package/dist/manifest-BjK4ALvr.mjs.map +0 -1
@@ -92,7 +92,23 @@ var manifest_default = {
92
92
  "id": "better-openclaw",
93
93
  "path": "better-openclaw/SKILL.md",
94
94
  "emoji": "🦞",
95
- "services": []
95
+ "services": [
96
+ "caddy",
97
+ "chromadb",
98
+ "ffmpeg",
99
+ "grafana",
100
+ "minio",
101
+ "n8n",
102
+ "ollama",
103
+ "postgresql",
104
+ "prometheus",
105
+ "qdrant",
106
+ "redis",
107
+ "remotion",
108
+ "traefik",
109
+ "weaviate",
110
+ "whisper"
111
+ ]
96
112
  },
97
113
  {
98
114
  "id": "postgresql-query",
@@ -392,25 +408,25 @@ var manifest_default = {
392
408
  "id": "claude-code-assist",
393
409
  "path": "claude-code-assist/SKILL.md",
394
410
  "emoji": "🤖",
395
- "services": []
411
+ "services": ["claude-code"]
396
412
  },
397
413
  {
398
414
  "id": "codex-generate",
399
415
  "path": "codex-generate/SKILL.md",
400
416
  "emoji": "⌨️",
401
- "services": []
417
+ "services": ["codex"]
402
418
  },
403
419
  {
404
420
  "id": "gemini-cli-query",
405
421
  "path": "gemini-cli-query/SKILL.md",
406
422
  "emoji": "♊",
407
- "services": []
423
+ "services": ["gemini-cli"]
408
424
  },
409
425
  {
410
426
  "id": "opencode-develop",
411
427
  "path": "opencode-develop/SKILL.md",
412
428
  "emoji": "🔓",
413
- "services": []
429
+ "services": ["opencode", "ollama"]
414
430
  },
415
431
  {
416
432
  "id": "mission-control-manage",
@@ -596,7 +612,7 @@ var manifest_default = {
596
612
  "id": "calendar-manage",
597
613
  "path": "calendar-manage/SKILL.md",
598
614
  "emoji": "📆",
599
- "services": []
615
+ "services": ["nextcloud"]
600
616
  },
601
617
  {
602
618
  "id": "system-info",
@@ -698,7 +714,7 @@ var manifest_default = {
698
714
  "id": "haystack-rag",
699
715
  "path": "haystack-rag/SKILL.md",
700
716
  "emoji": "🔍",
701
- "services": []
717
+ "services": ["qdrant", "weaviate"]
702
718
  },
703
719
  {
704
720
  "id": "llamaindex-query",
@@ -722,7 +738,7 @@ var manifest_default = {
722
738
  "id": "ansible-configure",
723
739
  "path": "ansible-configure/SKILL.md",
724
740
  "emoji": "📋",
725
- "services": []
741
+ "services": ["jenkins"]
726
742
  },
727
743
  {
728
744
  "id": "woodpecker-ci",
@@ -1034,13 +1050,13 @@ var manifest_default = {
1034
1050
  "id": "ui-design-system",
1035
1051
  "path": "ui-design-system/SKILL.md",
1036
1052
  "emoji": "🎨",
1037
- "services": []
1053
+ "services": ["claude-code"]
1038
1054
  },
1039
1055
  {
1040
1056
  "id": "tailwind-design-system-v4",
1041
1057
  "path": "tailwind-design-system-v4/SKILL.md",
1042
1058
  "emoji": "💨",
1043
- "services": []
1059
+ "services": ["ghost"]
1044
1060
  },
1045
1061
  {
1046
1062
  "id": "interaction-design",
@@ -1112,7 +1128,7 @@ var manifest_default = {
1112
1128
  "id": "browser-learn",
1113
1129
  "path": "browser-learn/SKILL.md",
1114
1130
  "emoji": "🧠",
1115
- "services": []
1131
+ "services": ["browserless", "lightpanda"]
1116
1132
  },
1117
1133
  {
1118
1134
  "id": "scrapling-scrape",
@@ -1124,7 +1140,11 @@ var manifest_default = {
1124
1140
  "id": "youtube-growth",
1125
1141
  "path": "youtube-growth/SKILL.md",
1126
1142
  "emoji": "📈",
1127
- "services": []
1143
+ "services": [
1144
+ "comfyui",
1145
+ "ollama",
1146
+ "searxng"
1147
+ ]
1128
1148
  },
1129
1149
  {
1130
1150
  "id": "hexstrike-mcp",
@@ -1149,10 +1169,16 @@ var manifest_default = {
1149
1169
  "path": "pentestagent-runner/SKILL.md",
1150
1170
  "emoji": "🔍",
1151
1171
  "services": ["pentestagent"]
1172
+ },
1173
+ {
1174
+ "id": "headscale-network",
1175
+ "path": "headscale-network/SKILL.md",
1176
+ "emoji": "🌐",
1177
+ "services": ["headscale"]
1152
1178
  }
1153
1179
  ]
1154
1180
  };
1155
1181
 
1156
1182
  //#endregion
1157
1183
  export { manifest_default as t };
1158
- //# sourceMappingURL=manifest-BjK4ALvr.mjs.map
1184
+ //# sourceMappingURL=manifest-B8UDsVlR.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest-B8UDsVlR.mjs","names":[],"sources":["../src/skills/manifest.json"],"sourcesContent":[""],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"resolver.mjs","names":[],"sources":["../src/resolver.ts"],"sourcesContent":["import { getServiceById } from \"./services/registry.js\";\nimport { getSkillPackById } from \"./skills/registry.js\";\nimport type {\n\tAddedDependency,\n\tResolvedService,\n\tResolverError,\n\tResolverInput,\n\tResolverOutput,\n\tServiceDefinition,\n\tWarning,\n} from \"./types.js\";\n\nexport interface MemoryThresholds {\n\tinfo: number;\n\twarning: number;\n\tcritical: number;\n}\n\nconst DEFAULT_MEMORY_THRESHOLDS: MemoryThresholds = {\n\tinfo: 2048,\n\twarning: 4096,\n\tcritical: 8192,\n};\n\n/**\n * Resolves user selections into a complete, valid service list.\n *\n * Algorithm:\n * 1. Expand skill pack requirements into service list\n * 2. Resolve transitive `requires` dependencies (iterate until stable)\n * 3. Detect `conflictsWith` violations\n * 4. Check platform compatibility and GPU requirements\n * 5. Estimate total memory (sum minMemoryMB)\n * 6. Deduplicate\n * 7. Topological sort by dependency graph, alphabetical for ties\n *\n * Deterministic: same input -> same output, always.\n */\nexport function resolve(input: ResolverInput): ResolverOutput {\n\tconst addedDependencies: AddedDependency[] = [];\n\tconst warnings: Warning[] = [];\n\tconst errors: ResolverError[] = [];\n\n\t// Track all service IDs needed\n\tconst serviceIds = new Set<string>(input.services);\n\tconst serviceAddedBy = new Map<string, ResolvedService[\"addedBy\"]>();\n\n\t// Mark user-selected services\n\tfor (const id of input.services) {\n\t\tserviceAddedBy.set(id, \"user\");\n\t}\n\n\t// 1. Expand skill pack requirements\n\tfor (const packId of input.skillPacks) {\n\t\tconst pack = getSkillPackById(packId);\n\t\tif (!pack) {\n\t\t\terrors.push({\n\t\t\t\ttype: \"unknown_skill_pack\",\n\t\t\t\tmessage: `Unknown skill pack: \"${packId}\"`,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tfor (const requiredService of pack.requiredServices) {\n\t\t\tif (!serviceIds.has(requiredService)) {\n\t\t\t\tserviceIds.add(requiredService);\n\t\t\t\tserviceAddedBy.set(requiredService, \"skill-pack\");\n\t\t\t\taddedDependencies.push({\n\t\t\t\t\tservice: requiredService,\n\t\t\t\t\treason: `Required by skill pack: ${pack.name}`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t// Add proxy if specified\n\tif (input.proxy && input.proxy !== \"none\") {\n\t\tif (!serviceIds.has(input.proxy)) {\n\t\t\tserviceIds.add(input.proxy);\n\t\t\tserviceAddedBy.set(input.proxy, \"proxy\");\n\t\t\taddedDependencies.push({\n\t\t\t\tservice: input.proxy,\n\t\t\t\treason: `Selected as reverse proxy`,\n\t\t\t});\n\t\t}\n\t}\n\n\t// Add monitoring stack if requested\n\tif (input.monitoring) {\n\t\tconst monitoringServices = [\"uptime-kuma\", \"grafana\", \"prometheus\"];\n\t\tfor (const svc of monitoringServices) {\n\t\t\tif (!serviceIds.has(svc)) {\n\t\t\t\tserviceIds.add(svc);\n\t\t\t\tserviceAddedBy.set(svc, \"monitoring\");\n\t\t\t\taddedDependencies.push({\n\t\t\t\t\tservice: svc,\n\t\t\t\t\treason: \"Included with monitoring stack\",\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t// Validate all service IDs exist\n\tconst unknownIds: string[] = [];\n\tfor (const id of serviceIds) {\n\t\tif (!getServiceById(id)) {\n\t\t\tunknownIds.push(id);\n\t\t}\n\t}\n\tif (unknownIds.length > 0) {\n\t\tfor (const id of unknownIds) {\n\t\t\terrors.push({\n\t\t\t\ttype: \"unknown_service\",\n\t\t\t\tmessage: `Unknown service: \"${id}\"`,\n\t\t\t});\n\t\t\tserviceIds.delete(id);\n\t\t}\n\t}\n\n\t// 2. Resolve transitive dependencies (iterate until stable)\n\tlet changed = true;\n\tconst maxIterations = 50; // safety bound\n\tlet iteration = 0;\n\twhile (changed && iteration < maxIterations) {\n\t\tchanged = false;\n\t\titeration++;\n\t\tfor (const id of [...serviceIds]) {\n\t\t\tconst def = getServiceById(id);\n\t\t\tif (!def) continue;\n\t\t\tfor (const reqId of def.requires) {\n\t\t\t\tif (!serviceIds.has(reqId)) {\n\t\t\t\t\tserviceIds.add(reqId);\n\t\t\t\t\tserviceAddedBy.set(reqId, \"dependency\");\n\t\t\t\t\taddedDependencies.push({\n\t\t\t\t\t\tservice: reqId,\n\t\t\t\t\t\treason: `Required by ${def.name}`,\n\t\t\t\t\t});\n\t\t\t\t\tchanged = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (iteration >= maxIterations) {\n\t\twarnings.push({\n\t\t\ttype: \"resolution\",\n\t\t\tmessage: `Dependency resolution reached maximum iterations (${maxIterations}). Some transitive dependencies may not be fully resolved.`,\n\t\t});\n\t}\n\n\t// Check recommended services\n\tfor (const id of serviceIds) {\n\t\tconst def = getServiceById(id);\n\t\tif (!def) continue;\n\t\tfor (const recId of def.recommends) {\n\t\t\tif (!serviceIds.has(recId) && getServiceById(recId)) {\n\t\t\t\twarnings.push({\n\t\t\t\t\ttype: \"recommendation\",\n\t\t\t\t\tmessage: `${def.name} recommends \"${recId}\" for enhanced functionality`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t// 3. Detect conflicts\n\tconst resolvedDefs: ServiceDefinition[] = [];\n\tfor (const id of serviceIds) {\n\t\tconst def = getServiceById(id);\n\t\tif (def) resolvedDefs.push(def);\n\t}\n\n\tfor (let i = 0; i < resolvedDefs.length; i++) {\n\t\tfor (let j = i + 1; j < resolvedDefs.length; j++) {\n\t\t\tconst a = resolvedDefs[i]!;\n\t\t\tconst b = resolvedDefs[j]!;\n\t\t\tif (a.conflictsWith.includes(b.id) || b.conflictsWith.includes(a.id)) {\n\t\t\t\terrors.push({\n\t\t\t\t\ttype: \"conflict\",\n\t\t\t\t\tmessage: `${a.name} and ${b.name} cannot be used together`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t// 4. Check platform compatibility\n\tif (input.platform) {\n\t\tfor (const def of resolvedDefs) {\n\t\t\tif (def.platforms && def.platforms.length > 0 && !def.platforms.includes(input.platform)) {\n\t\t\t\twarnings.push({\n\t\t\t\t\ttype: \"platform\",\n\t\t\t\t\tmessage: `${def.name} may not be compatible with ${input.platform}. Supported: ${def.platforms.join(\", \")}`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check GPU requirements\n\tconst gpuServices = resolvedDefs.filter((d) => d.gpuRequired);\n\tif (gpuServices.length > 0 && !input.gpu) {\n\t\tfor (const svc of gpuServices) {\n\t\t\twarnings.push({\n\t\t\t\ttype: \"gpu\",\n\t\t\t\tmessage: `${svc.name} requires GPU passthrough. Enable --gpu flag for optimal performance.`,\n\t\t\t});\n\t\t}\n\t}\n\n\t// 5. Estimate total memory\n\tlet estimatedMemoryMB = 512; // Base for OpenClaw itself\n\tfor (const def of resolvedDefs) {\n\t\testimatedMemoryMB += def.minMemoryMB ?? 128;\n\t}\n\n\t// Memory warnings\n\tconst thresholds = input.memoryThresholds ?? DEFAULT_MEMORY_THRESHOLDS;\n\tif (estimatedMemoryMB > thresholds.critical) {\n\t\twarnings.push({\n\t\t\ttype: \"memory\",\n\t\t\tmessage: `Estimated ${(estimatedMemoryMB / 1024).toFixed(1)}GB RAM required. Ensure your server has sufficient resources.`,\n\t\t});\n\t} else if (estimatedMemoryMB > thresholds.warning) {\n\t\twarnings.push({\n\t\t\ttype: \"memory\",\n\t\t\tmessage: `Estimated ${(estimatedMemoryMB / 1024).toFixed(1)}GB RAM required. A server with at least 8GB RAM is recommended.`,\n\t\t});\n\t} else if (estimatedMemoryMB > thresholds.info) {\n\t\twarnings.push({\n\t\t\ttype: \"memory\",\n\t\t\tmessage: `Estimated ${(estimatedMemoryMB / 1024).toFixed(1)}GB RAM required.`,\n\t\t});\n\t}\n\n\t// 7. Topological sort by dependency graph\n\tconst sorted = topologicalSort(resolvedDefs);\n\n\t// Build final resolved services list\n\tconst services: ResolvedService[] = sorted.map((def) => ({\n\t\tdefinition: def,\n\t\taddedBy: serviceAddedBy.get(def.id) ?? \"user\",\n\t}));\n\n\tconst isValid = errors.length === 0;\n\n\treturn {\n\tservices,\n\taddedDependencies,\n\tremovedConflicts: [],\n\twarnings,\n\terrors,\n\tisValid,\n\testimatedMemoryMB,\n\taiProviders: input.aiProviders ?? [],\n\tgsdRuntimes: []\n};\n}\n\n/**\n * Topological sort using Kahn's algorithm.\n * Ties broken alphabetically by service ID for determinism.\n */\nfunction topologicalSort(definitions: ServiceDefinition[]): ServiceDefinition[] {\n\tconst idSet = new Set(definitions.map((d) => d.id));\n\tconst graph = new Map<string, string[]>(); // id -> list of IDs that depend on it\n\tconst inDegree = new Map<string, number>();\n\n\t// Initialize\n\tfor (const def of definitions) {\n\t\tgraph.set(def.id, []);\n\t\tinDegree.set(def.id, 0);\n\t}\n\n\t// Build edges: if A requires B, then B -> A (B must come before A)\n\tfor (const def of definitions) {\n\t\tfor (const reqId of [...def.requires, ...def.dependsOn]) {\n\t\t\tif (idSet.has(reqId)) {\n\t\t\t\tgraph.get(reqId)?.push(def.id);\n\t\t\t\tinDegree.set(def.id, (inDegree.get(def.id) ?? 0) + 1);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Kahn's algorithm with alphabetical tie-breaking\n\tconst queue: string[] = [];\n\tfor (const [id, deg] of inDegree) {\n\t\tif (deg === 0) queue.push(id);\n\t}\n\tqueue.sort(); // alphabetical for determinism\n\n\tconst sorted: ServiceDefinition[] = [];\n\tconst defMap = new Map(definitions.map((d) => [d.id, d]));\n\n\twhile (queue.length > 0) {\n\t\tconst id = queue.shift()!;\n\t\tconst def = defMap.get(id);\n\t\tif (def) sorted.push(def);\n\n\t\tconst neighbors = graph.get(id) ?? [];\n\t\tconst newReady: string[] = [];\n\t\tfor (const neighbor of neighbors) {\n\t\t\tconst deg = (inDegree.get(neighbor) ?? 0) - 1;\n\t\t\tinDegree.set(neighbor, deg);\n\t\t\tif (deg === 0) newReady.push(neighbor);\n\t\t}\n\t\t// Sort newly ready nodes alphabetically and add to queue in order\n\t\tnewReady.sort();\n\t\tqueue.push(...newReady);\n\t}\n\n\t// If not all nodes are in sorted, there's a cycle\n\tif (sorted.length < definitions.length) {\n\t\t// Return what we have plus remaining (cycle detected but we still produce output)\n\t\tconst sortedIds = new Set(sorted.map((d) => d.id));\n\t\tconst remaining = definitions.filter((d) => !sortedIds.has(d.id));\n\t\tremaining.sort((a, b) => a.id.localeCompare(b.id));\n\t\tsorted.push(...remaining);\n\t}\n\n\treturn sorted;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"resolver.mjs","names":[],"sources":["../src/resolver.ts"],"sourcesContent":["import { getServiceById } from \"./services/registry.js\";\nimport { getSkillPackById } from \"./skills/registry.js\";\nimport type {\n\tAddedDependency,\n\tResolvedService,\n\tResolverError,\n\tResolverInput,\n\tResolverOutput,\n\tServiceDefinition,\n\tWarning,\n} from \"./types.js\";\n\nexport interface MemoryThresholds {\n\tinfo: number;\n\twarning: number;\n\tcritical: number;\n}\n\nconst DEFAULT_MEMORY_THRESHOLDS: MemoryThresholds = {\n\tinfo: 2048,\n\twarning: 4096,\n\tcritical: 8192,\n};\n\n/**\n * Resolves user selections into a complete, valid service list.\n *\n * Algorithm:\n * 1. Expand skill pack requirements into service list\n * 2. Resolve transitive `requires` dependencies (iterate until stable)\n * 3. Detect `conflictsWith` violations\n * 4. Check platform compatibility and GPU requirements\n * 5. Estimate total memory (sum minMemoryMB)\n * 6. Deduplicate\n * 7. Topological sort by dependency graph, alphabetical for ties\n *\n * Deterministic: same input -> same output, always.\n */\nexport function resolve(input: ResolverInput): ResolverOutput {\n\tconst addedDependencies: AddedDependency[] = [];\n\tconst warnings: Warning[] = [];\n\tconst errors: ResolverError[] = [];\n\n\t// Track all service IDs needed\n\tconst serviceIds = new Set<string>(input.services);\n\tconst serviceAddedBy = new Map<string, ResolvedService[\"addedBy\"]>();\n\n\t// Mark user-selected services\n\tfor (const id of input.services) {\n\t\tserviceAddedBy.set(id, \"user\");\n\t}\n\n\t// 1. Expand skill pack requirements\n\tfor (const packId of input.skillPacks) {\n\t\tconst pack = getSkillPackById(packId);\n\t\tif (!pack) {\n\t\t\terrors.push({\n\t\t\t\ttype: \"unknown_skill_pack\",\n\t\t\t\tmessage: `Unknown skill pack: \"${packId}\"`,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tfor (const requiredService of pack.requiredServices) {\n\t\t\tif (!serviceIds.has(requiredService)) {\n\t\t\t\tserviceIds.add(requiredService);\n\t\t\t\tserviceAddedBy.set(requiredService, \"skill-pack\");\n\t\t\t\taddedDependencies.push({\n\t\t\t\t\tservice: requiredService,\n\t\t\t\t\treason: `Required by skill pack: ${pack.name}`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t// Add proxy if specified\n\tif (input.proxy && input.proxy !== \"none\") {\n\t\tif (!serviceIds.has(input.proxy)) {\n\t\t\tserviceIds.add(input.proxy);\n\t\t\tserviceAddedBy.set(input.proxy, \"proxy\");\n\t\t\taddedDependencies.push({\n\t\t\t\tservice: input.proxy,\n\t\t\t\treason: `Selected as reverse proxy`,\n\t\t\t});\n\t\t}\n\t}\n\n\t// Add monitoring stack if requested\n\tif (input.monitoring) {\n\t\tconst monitoringServices = [\"uptime-kuma\", \"grafana\", \"prometheus\"];\n\t\tfor (const svc of monitoringServices) {\n\t\t\tif (!serviceIds.has(svc)) {\n\t\t\t\tserviceIds.add(svc);\n\t\t\t\tserviceAddedBy.set(svc, \"monitoring\");\n\t\t\t\taddedDependencies.push({\n\t\t\t\t\tservice: svc,\n\t\t\t\t\treason: \"Included with monitoring stack\",\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t// Validate all service IDs exist\n\tconst unknownIds: string[] = [];\n\tfor (const id of serviceIds) {\n\t\tif (!getServiceById(id)) {\n\t\t\tunknownIds.push(id);\n\t\t}\n\t}\n\tif (unknownIds.length > 0) {\n\t\tfor (const id of unknownIds) {\n\t\t\terrors.push({\n\t\t\t\ttype: \"unknown_service\",\n\t\t\t\tmessage: `Unknown service: \"${id}\"`,\n\t\t\t});\n\t\t\tserviceIds.delete(id);\n\t\t}\n\t}\n\n\t// 2. Resolve transitive dependencies (iterate until stable)\n\tlet changed = true;\n\tconst maxIterations = 50; // safety bound\n\tlet iteration = 0;\n\twhile (changed && iteration < maxIterations) {\n\t\tchanged = false;\n\t\titeration++;\n\t\tfor (const id of [...serviceIds]) {\n\t\t\tconst def = getServiceById(id);\n\t\t\tif (!def) continue;\n\t\t\tfor (const reqId of def.requires) {\n\t\t\t\tif (!serviceIds.has(reqId)) {\n\t\t\t\t\tserviceIds.add(reqId);\n\t\t\t\t\tserviceAddedBy.set(reqId, \"dependency\");\n\t\t\t\t\taddedDependencies.push({\n\t\t\t\t\t\tservice: reqId,\n\t\t\t\t\t\treason: `Required by ${def.name}`,\n\t\t\t\t\t});\n\t\t\t\t\tchanged = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (iteration >= maxIterations) {\n\t\twarnings.push({\n\t\t\ttype: \"resolution\",\n\t\t\tmessage: `Dependency resolution reached maximum iterations (${maxIterations}). Some transitive dependencies may not be fully resolved.`,\n\t\t});\n\t}\n\n\t// Check recommended services\n\tfor (const id of serviceIds) {\n\t\tconst def = getServiceById(id);\n\t\tif (!def) continue;\n\t\tfor (const recId of def.recommends) {\n\t\t\tif (!serviceIds.has(recId) && getServiceById(recId)) {\n\t\t\t\twarnings.push({\n\t\t\t\t\ttype: \"recommendation\",\n\t\t\t\t\tmessage: `${def.name} recommends \"${recId}\" for enhanced functionality`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t// 3. Detect conflicts\n\tconst resolvedDefs: ServiceDefinition[] = [];\n\tfor (const id of serviceIds) {\n\t\tconst def = getServiceById(id);\n\t\tif (def) resolvedDefs.push(def);\n\t}\n\n\tfor (let i = 0; i < resolvedDefs.length; i++) {\n\t\tfor (let j = i + 1; j < resolvedDefs.length; j++) {\n\t\t\tconst a = resolvedDefs[i]!;\n\t\t\tconst b = resolvedDefs[j]!;\n\t\t\tif (a.conflictsWith.includes(b.id) || b.conflictsWith.includes(a.id)) {\n\t\t\t\terrors.push({\n\t\t\t\t\ttype: \"conflict\",\n\t\t\t\t\tmessage: `${a.name} and ${b.name} cannot be used together`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t// 4. Check platform compatibility\n\tif (input.platform) {\n\t\tfor (const def of resolvedDefs) {\n\t\t\tif (def.platforms && def.platforms.length > 0 && !def.platforms.includes(input.platform)) {\n\t\t\t\twarnings.push({\n\t\t\t\t\ttype: \"platform\",\n\t\t\t\t\tmessage: `${def.name} may not be compatible with ${input.platform}. Supported: ${def.platforms.join(\", \")}`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check GPU requirements\n\tconst gpuServices = resolvedDefs.filter((d) => d.gpuRequired);\n\tif (gpuServices.length > 0 && !input.gpu) {\n\t\tfor (const svc of gpuServices) {\n\t\t\twarnings.push({\n\t\t\t\ttype: \"gpu\",\n\t\t\t\tmessage: `${svc.name} requires GPU passthrough. Enable --gpu flag for optimal performance.`,\n\t\t\t});\n\t\t}\n\t}\n\n\t// 5. Estimate total memory\n\tlet estimatedMemoryMB = 512; // Base for OpenClaw itself\n\tfor (const def of resolvedDefs) {\n\t\testimatedMemoryMB += def.minMemoryMB ?? 128;\n\t}\n\n\t// Memory warnings\n\tconst thresholds = input.memoryThresholds ?? DEFAULT_MEMORY_THRESHOLDS;\n\tif (estimatedMemoryMB > thresholds.critical) {\n\t\twarnings.push({\n\t\t\ttype: \"memory\",\n\t\t\tmessage: `Estimated ${(estimatedMemoryMB / 1024).toFixed(1)}GB RAM required. Ensure your server has sufficient resources.`,\n\t\t});\n\t} else if (estimatedMemoryMB > thresholds.warning) {\n\t\twarnings.push({\n\t\t\ttype: \"memory\",\n\t\t\tmessage: `Estimated ${(estimatedMemoryMB / 1024).toFixed(1)}GB RAM required. A server with at least 8GB RAM is recommended.`,\n\t\t});\n\t} else if (estimatedMemoryMB > thresholds.info) {\n\t\twarnings.push({\n\t\t\ttype: \"memory\",\n\t\t\tmessage: `Estimated ${(estimatedMemoryMB / 1024).toFixed(1)}GB RAM required.`,\n\t\t});\n\t}\n\n\t// 7. Topological sort by dependency graph\n\tconst sorted = topologicalSort(resolvedDefs);\n\n\t// Build final resolved services list\n\tconst services: ResolvedService[] = sorted.map((def) => ({\n\t\tdefinition: def,\n\t\taddedBy: serviceAddedBy.get(def.id) ?? \"user\",\n\t}));\n\n\tconst isValid = errors.length === 0;\n\n\treturn {\n\t\tservices,\n\t\taddedDependencies,\n\t\tremovedConflicts: [],\n\t\twarnings,\n\t\terrors,\n\t\tisValid,\n\t\testimatedMemoryMB,\n\t\taiProviders: input.aiProviders ?? [],\n\t\tgsdRuntimes: [],\n\t};\n}\n\n/**\n * Topological sort using Kahn's algorithm.\n * Ties broken alphabetically by service ID for determinism.\n */\nfunction topologicalSort(definitions: ServiceDefinition[]): ServiceDefinition[] {\n\tconst idSet = new Set(definitions.map((d) => d.id));\n\tconst graph = new Map<string, string[]>(); // id -> list of IDs that depend on it\n\tconst inDegree = new Map<string, number>();\n\n\t// Initialize\n\tfor (const def of definitions) {\n\t\tgraph.set(def.id, []);\n\t\tinDegree.set(def.id, 0);\n\t}\n\n\t// Build edges: if A requires B, then B -> A (B must come before A)\n\tfor (const def of definitions) {\n\t\tfor (const reqId of [...def.requires, ...def.dependsOn]) {\n\t\t\tif (idSet.has(reqId)) {\n\t\t\t\tgraph.get(reqId)?.push(def.id);\n\t\t\t\tinDegree.set(def.id, (inDegree.get(def.id) ?? 0) + 1);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Kahn's algorithm with alphabetical tie-breaking\n\tconst queue: string[] = [];\n\tfor (const [id, deg] of inDegree) {\n\t\tif (deg === 0) queue.push(id);\n\t}\n\tqueue.sort(); // alphabetical for determinism\n\n\tconst sorted: ServiceDefinition[] = [];\n\tconst defMap = new Map(definitions.map((d) => [d.id, d]));\n\n\twhile (queue.length > 0) {\n\t\tconst id = queue.shift()!;\n\t\tconst def = defMap.get(id);\n\t\tif (def) sorted.push(def);\n\n\t\tconst neighbors = graph.get(id) ?? [];\n\t\tconst newReady: string[] = [];\n\t\tfor (const neighbor of neighbors) {\n\t\t\tconst deg = (inDegree.get(neighbor) ?? 0) - 1;\n\t\t\tinDegree.set(neighbor, deg);\n\t\t\tif (deg === 0) newReady.push(neighbor);\n\t\t}\n\t\t// Sort newly ready nodes alphabetically and add to queue in order\n\t\tnewReady.sort();\n\t\tqueue.push(...newReady);\n\t}\n\n\t// If not all nodes are in sorted, there's a cycle\n\tif (sorted.length < definitions.length) {\n\t\t// Return what we have plus remaining (cycle detected but we still produce output)\n\t\tconst sortedIds = new Set(sorted.map((d) => d.id));\n\t\tconst remaining = definitions.filter((d) => !sortedIds.has(d.id));\n\t\tremaining.sort((a, b) => a.id.localeCompare(b.id));\n\t\tsorted.push(...remaining);\n\t}\n\n\treturn sorted;\n}\n"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { ServiceDefinition } from "../../types.mjs";
2
+
3
+ //#region src/services/definitions/authentik.d.ts
4
+ declare const authentikDefinition: ServiceDefinition;
5
+ //#endregion
6
+ export { authentikDefinition };
7
+ //# sourceMappingURL=authentik.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authentik.d.mts","names":[],"sources":["../../../src/services/definitions/authentik.ts"],"mappings":";;;cAEa,mBAAA,EAAqB,iBAAA"}
@@ -0,0 +1,105 @@
1
+ //#region src/services/definitions/authentik.ts
2
+ const authentikDefinition = {
3
+ id: "authentik",
4
+ name: "Authentik",
5
+ description: "The open-source Identity Provider that unifies your identity infrastructure.",
6
+ category: "security",
7
+ icon: "🛡️",
8
+ image: "ghcr.io/goauthentik/server",
9
+ imageTag: "latest",
10
+ ports: [{
11
+ host: 9e3,
12
+ container: 9e3,
13
+ description: "Authentik HTTP Interface",
14
+ exposed: true
15
+ }, {
16
+ host: 9443,
17
+ container: 9443,
18
+ description: "Authentik HTTPS Interface",
19
+ exposed: false
20
+ }],
21
+ volumes: [{
22
+ name: "authentik_media",
23
+ containerPath: "/media",
24
+ description: "Authentik media storage"
25
+ }, {
26
+ name: "authentik_custom_templates",
27
+ containerPath: "/templates",
28
+ description: "Authentik custom templates"
29
+ }],
30
+ environment: [
31
+ {
32
+ key: "AUTHENTIK_REDIS__HOST",
33
+ defaultValue: "redis",
34
+ secret: false,
35
+ description: "Redis server hostname",
36
+ required: true
37
+ },
38
+ {
39
+ key: "AUTHENTIK_POSTGRESQL__HOST",
40
+ defaultValue: "postgres",
41
+ secret: false,
42
+ description: "Postgres database hostname",
43
+ required: true
44
+ },
45
+ {
46
+ key: "AUTHENTIK_POSTGRESQL__USER",
47
+ defaultValue: "postgres",
48
+ secret: false,
49
+ description: "Postgres database user",
50
+ required: true
51
+ },
52
+ {
53
+ key: "AUTHENTIK_POSTGRESQL__NAME",
54
+ defaultValue: "authentik",
55
+ secret: false,
56
+ description: "Postgres database name",
57
+ required: true
58
+ },
59
+ {
60
+ key: "AUTHENTIK_POSTGRESQL__PASSWORD",
61
+ defaultValue: "postgres",
62
+ secret: true,
63
+ description: "Postgres database password",
64
+ required: true
65
+ },
66
+ {
67
+ key: "AUTHENTIK_SECRET_KEY",
68
+ defaultValue: "authentik_secret_replace_me_in_production",
69
+ secret: true,
70
+ description: "Secret key used for cookie signing",
71
+ required: true
72
+ }
73
+ ],
74
+ healthcheck: {
75
+ test: "curl --fail http://localhost:9000/-/health/live/ || exit 1",
76
+ interval: "30s",
77
+ timeout: "5s",
78
+ retries: 3,
79
+ startPeriod: "30s"
80
+ },
81
+ dependsOn: ["postgresql", "redis"],
82
+ restartPolicy: "unless-stopped",
83
+ networks: ["openclaw-network"],
84
+ skills: [],
85
+ openclawEnvVars: [],
86
+ docsUrl: "https://docs.goauthentik.io/",
87
+ tags: [
88
+ "identity",
89
+ "sso",
90
+ "saml",
91
+ "oidc",
92
+ "oauth2",
93
+ "security"
94
+ ],
95
+ maturity: "stable",
96
+ requires: ["postgresql", "redis"],
97
+ recommends: [],
98
+ conflictsWith: [],
99
+ minMemoryMB: 2048,
100
+ gpuRequired: false
101
+ };
102
+
103
+ //#endregion
104
+ export { authentikDefinition };
105
+ //# sourceMappingURL=authentik.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authentik.mjs","names":[],"sources":["../../../src/services/definitions/authentik.ts"],"sourcesContent":["import type { ServiceDefinition } from \"../../types.js\";\n\nexport const authentikDefinition: ServiceDefinition = {\n\tid: \"authentik\",\n\tname: \"Authentik\",\n\tdescription: \"The open-source Identity Provider that unifies your identity infrastructure.\",\n\tcategory: \"security\",\n\ticon: \"🛡️\",\n\n\timage: \"ghcr.io/goauthentik/server\",\n\timageTag: \"latest\",\n\tports: [\n\t\t{\n\t\t\thost: 9000,\n\t\t\tcontainer: 9000,\n\t\t\tdescription: \"Authentik HTTP Interface\",\n\t\t\texposed: true,\n\t\t},\n\t\t{\n\t\t\thost: 9443,\n\t\t\tcontainer: 9443,\n\t\t\tdescription: \"Authentik HTTPS Interface\",\n\t\t\texposed: false,\n\t\t},\n\t],\n\tvolumes: [\n\t\t{\n\t\t\tname: \"authentik_media\",\n\t\t\tcontainerPath: \"/media\",\n\t\t\tdescription: \"Authentik media storage\",\n\t\t},\n\t\t{\n\t\t\tname: \"authentik_custom_templates\",\n\t\t\tcontainerPath: \"/templates\",\n\t\t\tdescription: \"Authentik custom templates\",\n\t\t},\n\t],\n\tenvironment: [\n\t\t{\n\t\t\tkey: \"AUTHENTIK_REDIS__HOST\",\n\t\t\tdefaultValue: \"redis\",\n\t\t\tsecret: false,\n\t\t\tdescription: \"Redis server hostname\",\n\t\t\trequired: true,\n\t\t},\n\t\t{\n\t\t\tkey: \"AUTHENTIK_POSTGRESQL__HOST\",\n\t\t\tdefaultValue: \"postgres\",\n\t\t\tsecret: false,\n\t\t\tdescription: \"Postgres database hostname\",\n\t\t\trequired: true,\n\t\t},\n\t\t{\n\t\t\tkey: \"AUTHENTIK_POSTGRESQL__USER\",\n\t\t\tdefaultValue: \"postgres\",\n\t\t\tsecret: false,\n\t\t\tdescription: \"Postgres database user\",\n\t\t\trequired: true,\n\t\t},\n\t\t{\n\t\t\tkey: \"AUTHENTIK_POSTGRESQL__NAME\",\n\t\t\tdefaultValue: \"authentik\",\n\t\t\tsecret: false,\n\t\t\tdescription: \"Postgres database name\",\n\t\t\trequired: true,\n\t\t},\n\t\t{\n\t\t\tkey: \"AUTHENTIK_POSTGRESQL__PASSWORD\",\n\t\t\tdefaultValue: \"postgres\",\n\t\t\tsecret: true,\n\t\t\tdescription: \"Postgres database password\",\n\t\t\trequired: true,\n\t\t},\n\t\t{\n\t\t\tkey: \"AUTHENTIK_SECRET_KEY\",\n\t\t\tdefaultValue: \"authentik_secret_replace_me_in_production\",\n\t\t\tsecret: true,\n\t\t\tdescription: \"Secret key used for cookie signing\",\n\t\t\trequired: true,\n\t\t},\n\t],\n\thealthcheck: {\n\t\ttest: \"curl --fail http://localhost:9000/-/health/live/ || exit 1\",\n\t\tinterval: \"30s\",\n\t\ttimeout: \"5s\",\n\t\tretries: 3,\n\t\tstartPeriod: \"30s\",\n\t},\n\tdependsOn: [\"postgresql\", \"redis\"],\n\trestartPolicy: \"unless-stopped\",\n\tnetworks: [\"openclaw-network\"],\n\n\tskills: [],\n\topenclawEnvVars: [],\n\n\tdocsUrl: \"https://docs.goauthentik.io/\",\n\ttags: [\"identity\", \"sso\", \"saml\", \"oidc\", \"oauth2\", \"security\"],\n\tmaturity: \"stable\",\n\n\trequires: [\"postgresql\", \"redis\"],\n\trecommends: [],\n\tconflictsWith: [],\n\n\tminMemoryMB: 2048,\n\tgpuRequired: false,\n};\n"],"mappings":";AAEA,MAAa,sBAAyC;CACrD,IAAI;CACJ,MAAM;CACN,aAAa;CACb,UAAU;CACV,MAAM;CAEN,OAAO;CACP,UAAU;CACV,OAAO,CACN;EACC,MAAM;EACN,WAAW;EACX,aAAa;EACb,SAAS;EACT,EACD;EACC,MAAM;EACN,WAAW;EACX,aAAa;EACb,SAAS;EACT,CACD;CACD,SAAS,CACR;EACC,MAAM;EACN,eAAe;EACf,aAAa;EACb,EACD;EACC,MAAM;EACN,eAAe;EACf,aAAa;EACb,CACD;CACD,aAAa;EACZ;GACC,KAAK;GACL,cAAc;GACd,QAAQ;GACR,aAAa;GACb,UAAU;GACV;EACD;GACC,KAAK;GACL,cAAc;GACd,QAAQ;GACR,aAAa;GACb,UAAU;GACV;EACD;GACC,KAAK;GACL,cAAc;GACd,QAAQ;GACR,aAAa;GACb,UAAU;GACV;EACD;GACC,KAAK;GACL,cAAc;GACd,QAAQ;GACR,aAAa;GACb,UAAU;GACV;EACD;GACC,KAAK;GACL,cAAc;GACd,QAAQ;GACR,aAAa;GACb,UAAU;GACV;EACD;GACC,KAAK;GACL,cAAc;GACd,QAAQ;GACR,aAAa;GACb,UAAU;GACV;EACD;CACD,aAAa;EACZ,MAAM;EACN,UAAU;EACV,SAAS;EACT,SAAS;EACT,aAAa;EACb;CACD,WAAW,CAAC,cAAc,QAAQ;CAClC,eAAe;CACf,UAAU,CAAC,mBAAmB;CAE9B,QAAQ,EAAE;CACV,iBAAiB,EAAE;CAEnB,SAAS;CACT,MAAM;EAAC;EAAY;EAAO;EAAQ;EAAQ;EAAU;EAAW;CAC/D,UAAU;CAEV,UAAU,CAAC,cAAc,QAAQ;CACjC,YAAY,EAAE;CACd,eAAe,EAAE;CAEjB,aAAa;CACb,aAAa;CACb"}
@@ -0,0 +1,7 @@
1
+ import { ServiceDefinition } from "../../types.mjs";
2
+
3
+ //#region src/services/definitions/crowdsec.d.ts
4
+ declare const crowdsecDefinition: ServiceDefinition;
5
+ //#endregion
6
+ export { crowdsecDefinition };
7
+ //# sourceMappingURL=crowdsec.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crowdsec.d.mts","names":[],"sources":["../../../src/services/definitions/crowdsec.ts"],"mappings":";;;cAEa,kBAAA,EAAoB,iBAAA"}
@@ -0,0 +1,62 @@
1
+ //#region src/services/definitions/crowdsec.ts
2
+ const crowdsecDefinition = {
3
+ id: "crowdsec",
4
+ name: "CrowdSec",
5
+ description: "Free, open-source and collaborative IPS designed to protect servers, services, and containers.",
6
+ category: "security",
7
+ icon: "⚔️",
8
+ image: "crowdsecurity/crowdsec",
9
+ imageTag: "latest",
10
+ ports: [{
11
+ host: 8080,
12
+ container: 8080,
13
+ description: "CrowdSec Local API Interface",
14
+ exposed: true
15
+ }],
16
+ volumes: [{
17
+ name: "crowdsec_data",
18
+ containerPath: "/v/lib/crowdsec/data",
19
+ description: "CrowdSec persistent SQLite data"
20
+ }, {
21
+ name: "crowdsec_config",
22
+ containerPath: "/etc/crowdsec",
23
+ description: "CrowdSec configurations"
24
+ }],
25
+ environment: [{
26
+ key: "COLLECTIONS",
27
+ defaultValue: "crowdsecurity/linux crowdsecurity/sshd",
28
+ secret: false,
29
+ description: "Default collections to install",
30
+ required: false
31
+ }],
32
+ healthcheck: {
33
+ test: "cscli metrics || exit 1",
34
+ interval: "30s",
35
+ timeout: "10s",
36
+ retries: 3,
37
+ startPeriod: "15s"
38
+ },
39
+ dependsOn: [],
40
+ restartPolicy: "unless-stopped",
41
+ networks: ["openclaw-network"],
42
+ skills: [],
43
+ openclawEnvVars: [],
44
+ docsUrl: "https://docs.crowdsec.net/",
45
+ tags: [
46
+ "ips",
47
+ "ids",
48
+ "firewall",
49
+ "security",
50
+ "threat-intelligence"
51
+ ],
52
+ maturity: "stable",
53
+ requires: [],
54
+ recommends: [],
55
+ conflictsWith: [],
56
+ minMemoryMB: 256,
57
+ gpuRequired: false
58
+ };
59
+
60
+ //#endregion
61
+ export { crowdsecDefinition };
62
+ //# sourceMappingURL=crowdsec.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crowdsec.mjs","names":[],"sources":["../../../src/services/definitions/crowdsec.ts"],"sourcesContent":["import type { ServiceDefinition } from \"../../types.js\";\n\nexport const crowdsecDefinition: ServiceDefinition = {\n\tid: \"crowdsec\",\n\tname: \"CrowdSec\",\n\tdescription:\n\t\t\"Free, open-source and collaborative IPS designed to protect servers, services, and containers.\",\n\tcategory: \"security\",\n\ticon: \"⚔️\",\n\n\timage: \"crowdsecurity/crowdsec\",\n\timageTag: \"latest\",\n\tports: [\n\t\t{\n\t\t\thost: 8080,\n\t\t\tcontainer: 8080,\n\t\t\tdescription: \"CrowdSec Local API Interface\",\n\t\t\texposed: true,\n\t\t},\n\t],\n\tvolumes: [\n\t\t{\n\t\t\tname: \"crowdsec_data\",\n\t\t\tcontainerPath: \"/v/lib/crowdsec/data\",\n\t\t\tdescription: \"CrowdSec persistent SQLite data\",\n\t\t},\n\t\t{\n\t\t\tname: \"crowdsec_config\",\n\t\t\tcontainerPath: \"/etc/crowdsec\",\n\t\t\tdescription: \"CrowdSec configurations\",\n\t\t},\n\t],\n\tenvironment: [\n\t\t{\n\t\t\tkey: \"COLLECTIONS\",\n\t\t\tdefaultValue: \"crowdsecurity/linux crowdsecurity/sshd\",\n\t\t\tsecret: false,\n\t\t\tdescription: \"Default collections to install\",\n\t\t\trequired: false,\n\t\t},\n\t],\n\thealthcheck: {\n\t\ttest: \"cscli metrics || exit 1\",\n\t\tinterval: \"30s\",\n\t\ttimeout: \"10s\",\n\t\tretries: 3,\n\t\tstartPeriod: \"15s\",\n\t},\n\tdependsOn: [],\n\trestartPolicy: \"unless-stopped\",\n\tnetworks: [\"openclaw-network\"],\n\n\tskills: [],\n\topenclawEnvVars: [],\n\n\tdocsUrl: \"https://docs.crowdsec.net/\",\n\ttags: [\"ips\", \"ids\", \"firewall\", \"security\", \"threat-intelligence\"],\n\tmaturity: \"stable\",\n\n\trequires: [],\n\trecommends: [],\n\tconflictsWith: [],\n\n\tminMemoryMB: 256,\n\tgpuRequired: false,\n};\n"],"mappings":";AAEA,MAAa,qBAAwC;CACpD,IAAI;CACJ,MAAM;CACN,aACC;CACD,UAAU;CACV,MAAM;CAEN,OAAO;CACP,UAAU;CACV,OAAO,CACN;EACC,MAAM;EACN,WAAW;EACX,aAAa;EACb,SAAS;EACT,CACD;CACD,SAAS,CACR;EACC,MAAM;EACN,eAAe;EACf,aAAa;EACb,EACD;EACC,MAAM;EACN,eAAe;EACf,aAAa;EACb,CACD;CACD,aAAa,CACZ;EACC,KAAK;EACL,cAAc;EACd,QAAQ;EACR,aAAa;EACb,UAAU;EACV,CACD;CACD,aAAa;EACZ,MAAM;EACN,UAAU;EACV,SAAS;EACT,SAAS;EACT,aAAa;EACb;CACD,WAAW,EAAE;CACb,eAAe;CACf,UAAU,CAAC,mBAAmB;CAE9B,QAAQ,EAAE;CACV,iBAAiB,EAAE;CAEnB,SAAS;CACT,MAAM;EAAC;EAAO;EAAO;EAAY;EAAY;EAAsB;CACnE,UAAU;CAEV,UAAU,EAAE;CACZ,YAAY,EAAE;CACd,eAAe,EAAE;CAEjB,aAAa;CACb,aAAa;CACb"}
@@ -0,0 +1,7 @@
1
+ import { ServiceDefinition } from "../../types.mjs";
2
+
3
+ //#region src/services/definitions/ghost.d.ts
4
+ declare const ghostDefinition: ServiceDefinition;
5
+ //#endregion
6
+ export { ghostDefinition };
7
+ //# sourceMappingURL=ghost.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ghost.d.mts","names":[],"sources":["../../../src/services/definitions/ghost.ts"],"mappings":";;;cAEa,eAAA,EAAiB,iBAAA"}
@@ -0,0 +1,58 @@
1
+ //#region src/services/definitions/ghost.ts
2
+ const ghostDefinition = {
3
+ id: "ghost",
4
+ name: "Ghost",
5
+ description: "The world's most popular modern open-source publishing platform.",
6
+ category: "social-media",
7
+ icon: "👻",
8
+ image: "ghost",
9
+ imageTag: "latest",
10
+ ports: [{
11
+ host: 2368,
12
+ container: 2368,
13
+ description: "Ghost Public Interface",
14
+ exposed: true
15
+ }],
16
+ volumes: [{
17
+ name: "ghost_content",
18
+ containerPath: "/var/lib/ghost/content",
19
+ description: "Ghost images, themes, and content storage"
20
+ }],
21
+ environment: [{
22
+ key: "url",
23
+ defaultValue: "http://localhost:2368",
24
+ secret: false,
25
+ description: "The URL of the Ghost install",
26
+ required: true
27
+ }],
28
+ healthcheck: {
29
+ test: "curl --fail http://localhost:2368/ghost/ || exit 1",
30
+ interval: "30s",
31
+ timeout: "10s",
32
+ retries: 3,
33
+ startPeriod: "30s"
34
+ },
35
+ dependsOn: [],
36
+ restartPolicy: "unless-stopped",
37
+ networks: ["openclaw-network"],
38
+ skills: [],
39
+ openclawEnvVars: [],
40
+ docsUrl: "https://ghost.org/docs/",
41
+ tags: [
42
+ "blog",
43
+ "publishing",
44
+ "writing",
45
+ "cms",
46
+ "content"
47
+ ],
48
+ maturity: "stable",
49
+ requires: [],
50
+ recommends: [],
51
+ conflictsWith: [],
52
+ minMemoryMB: 512,
53
+ gpuRequired: false
54
+ };
55
+
56
+ //#endregion
57
+ export { ghostDefinition };
58
+ //# sourceMappingURL=ghost.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ghost.mjs","names":[],"sources":["../../../src/services/definitions/ghost.ts"],"sourcesContent":["import type { ServiceDefinition } from \"../../types.js\";\n\nexport const ghostDefinition: ServiceDefinition = {\n\tid: \"ghost\",\n\tname: \"Ghost\",\n\tdescription: \"The world's most popular modern open-source publishing platform.\",\n\tcategory: \"social-media\",\n\ticon: \"👻\",\n\n\timage: \"ghost\",\n\timageTag: \"latest\",\n\tports: [\n\t\t{\n\t\t\thost: 2368,\n\t\t\tcontainer: 2368,\n\t\t\tdescription: \"Ghost Public Interface\",\n\t\t\texposed: true,\n\t\t},\n\t],\n\tvolumes: [\n\t\t{\n\t\t\tname: \"ghost_content\",\n\t\t\tcontainerPath: \"/var/lib/ghost/content\",\n\t\t\tdescription: \"Ghost images, themes, and content storage\",\n\t\t},\n\t],\n\tenvironment: [\n\t\t{\n\t\t\tkey: \"url\",\n\t\t\tdefaultValue: \"http://localhost:2368\",\n\t\t\tsecret: false,\n\t\t\tdescription: \"The URL of the Ghost install\",\n\t\t\trequired: true,\n\t\t},\n\t],\n\thealthcheck: {\n\t\ttest: \"curl --fail http://localhost:2368/ghost/ || exit 1\",\n\t\tinterval: \"30s\",\n\t\ttimeout: \"10s\",\n\t\tretries: 3,\n\t\tstartPeriod: \"30s\",\n\t},\n\tdependsOn: [],\n\trestartPolicy: \"unless-stopped\",\n\tnetworks: [\"openclaw-network\"],\n\n\tskills: [],\n\topenclawEnvVars: [],\n\n\tdocsUrl: \"https://ghost.org/docs/\",\n\ttags: [\"blog\", \"publishing\", \"writing\", \"cms\", \"content\"],\n\tmaturity: \"stable\",\n\n\trequires: [],\n\trecommends: [],\n\tconflictsWith: [],\n\n\tminMemoryMB: 512,\n\tgpuRequired: false,\n};\n"],"mappings":";AAEA,MAAa,kBAAqC;CACjD,IAAI;CACJ,MAAM;CACN,aAAa;CACb,UAAU;CACV,MAAM;CAEN,OAAO;CACP,UAAU;CACV,OAAO,CACN;EACC,MAAM;EACN,WAAW;EACX,aAAa;EACb,SAAS;EACT,CACD;CACD,SAAS,CACR;EACC,MAAM;EACN,eAAe;EACf,aAAa;EACb,CACD;CACD,aAAa,CACZ;EACC,KAAK;EACL,cAAc;EACd,QAAQ;EACR,aAAa;EACb,UAAU;EACV,CACD;CACD,aAAa;EACZ,MAAM;EACN,UAAU;EACV,SAAS;EACT,SAAS;EACT,aAAa;EACb;CACD,WAAW,EAAE;CACb,eAAe;CACf,UAAU,CAAC,mBAAmB;CAE9B,QAAQ,EAAE;CACV,iBAAiB,EAAE;CAEnB,SAAS;CACT,MAAM;EAAC;EAAQ;EAAc;EAAW;EAAO;EAAU;CACzD,UAAU;CAEV,UAAU,EAAE;CACZ,YAAY,EAAE;CACd,eAAe,EAAE;CAEjB,aAAa;CACb,aAAa;CACb"}
@@ -0,0 +1,7 @@
1
+ import { ServiceDefinition } from "../../types.mjs";
2
+
3
+ //#region src/services/definitions/headscale.d.ts
4
+ declare const headscaleDefinition: ServiceDefinition;
5
+ //#endregion
6
+ export { headscaleDefinition };
7
+ //# sourceMappingURL=headscale.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headscale.d.mts","names":[],"sources":["../../../src/services/definitions/headscale.ts"],"mappings":";;;cAEa,mBAAA,EAAqB,iBAAA"}
@@ -0,0 +1,71 @@
1
+ //#region src/services/definitions/headscale.ts
2
+ const headscaleDefinition = {
3
+ id: "headscale",
4
+ name: "Headscale",
5
+ description: "An open source, self-hosted implementation of the Tailscale control server.",
6
+ category: "dev-tools",
7
+ icon: "🌐",
8
+ image: "headscale/headscale",
9
+ imageTag: "latest",
10
+ command: "headscale serve",
11
+ ports: [{
12
+ host: 8080,
13
+ container: 8080,
14
+ description: "Headscale API and Web UI",
15
+ exposed: true
16
+ }, {
17
+ host: 9090,
18
+ container: 9090,
19
+ description: "Headscale metrics",
20
+ exposed: false
21
+ }],
22
+ volumes: [{
23
+ name: "headscale-data",
24
+ containerPath: "/var/lib/headscale",
25
+ description: "Headscale database and configurations"
26
+ }, {
27
+ name: "headscale-config",
28
+ containerPath: "/etc/headscale",
29
+ description: "Headscale configuration files"
30
+ }],
31
+ environment: [{
32
+ key: "HEADSCALE_SERVER_URL",
33
+ defaultValue: "http://localhost:8080",
34
+ secret: false,
35
+ description: "The URL where the headscale server will be accessible",
36
+ required: true
37
+ }, {
38
+ key: "HEADSCALE_METRICS_LISTEN_ADDR",
39
+ defaultValue: "0.0.0.0:9090",
40
+ secret: false,
41
+ description: "Metrics listen address",
42
+ required: false
43
+ }],
44
+ healthcheck: {
45
+ test: "curl -f http://localhost:8080/health",
46
+ interval: "30s",
47
+ timeout: "5s",
48
+ retries: 3
49
+ },
50
+ docsUrl: "https://github.com/juanfont/headscale",
51
+ tags: [
52
+ "vpn",
53
+ "networking",
54
+ "tailscale",
55
+ "mesh-network"
56
+ ],
57
+ dependsOn: [],
58
+ restartPolicy: "unless-stopped",
59
+ networks: [],
60
+ skills: [],
61
+ openclawEnvVars: [],
62
+ maturity: "stable",
63
+ requires: [],
64
+ recommends: [],
65
+ conflictsWith: [],
66
+ gpuRequired: false
67
+ };
68
+
69
+ //#endregion
70
+ export { headscaleDefinition };
71
+ //# sourceMappingURL=headscale.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headscale.mjs","names":[],"sources":["../../../src/services/definitions/headscale.ts"],"sourcesContent":["import type { ServiceDefinition } from \"../../types.js\";\n\nexport const headscaleDefinition: ServiceDefinition = {\n id: \"headscale\",\n name: \"Headscale\",\n description: \"An open source, self-hosted implementation of the Tailscale control server.\",\n category: \"dev-tools\",\n icon: \"🌐\",\n image: \"headscale/headscale\",\n imageTag: \"latest\",\n command: \"headscale serve\",\n ports: [\n {\n host: 8080,\n container: 8080,\n description: \"Headscale API and Web UI\",\n exposed: true,\n },\n {\n host: 9090,\n container: 9090,\n description: \"Headscale metrics\",\n exposed: false,\n },\n ],\n volumes: [\n {\n name: \"headscale-data\",\n containerPath: \"/var/lib/headscale\",\n description: \"Headscale database and configurations\",\n },\n {\n name: \"headscale-config\",\n containerPath: \"/etc/headscale\",\n description: \"Headscale configuration files\",\n },\n ],\n environment: [\n {\n key: \"HEADSCALE_SERVER_URL\",\n defaultValue: \"http://localhost:8080\",\n secret: false,\n description: \"The URL where the headscale server will be accessible\",\n required: true,\n },\n {\n key: \"HEADSCALE_METRICS_LISTEN_ADDR\",\n defaultValue: \"0.0.0.0:9090\",\n secret: false,\n description: \"Metrics listen address\",\n required: false,\n },\n ],\n healthcheck: {\n test: \"curl -f http://localhost:8080/health\",\n interval: \"30s\",\n timeout: \"5s\",\n retries: 3,\n },\n docsUrl: \"https://github.com/juanfont/headscale\",\n tags: [\"vpn\", \"networking\", \"tailscale\", \"mesh-network\"],\n dependsOn: [],\n restartPolicy: \"unless-stopped\",\n networks: [],\n skills: [],\n openclawEnvVars: [],\n maturity: \"stable\",\n requires: [],\n recommends: [],\n conflictsWith: [],\n gpuRequired: false\n};\n"],"mappings":";AAEA,MAAa,sBAAyC;CAClD,IAAI;CACJ,MAAM;CACN,aAAa;CACb,UAAU;CACV,MAAM;CACN,OAAO;CACP,UAAU;CACV,SAAS;CACT,OAAO,CACH;EACI,MAAM;EACN,WAAW;EACX,aAAa;EACb,SAAS;EACZ,EACD;EACI,MAAM;EACN,WAAW;EACX,aAAa;EACb,SAAS;EACZ,CACJ;CACD,SAAS,CACL;EACI,MAAM;EACN,eAAe;EACf,aAAa;EAChB,EACD;EACI,MAAM;EACN,eAAe;EACf,aAAa;EAChB,CACJ;CACD,aAAa,CACT;EACI,KAAK;EACL,cAAc;EACd,QAAQ;EACR,aAAa;EACb,UAAU;EACb,EACD;EACI,KAAK;EACL,cAAc;EACd,QAAQ;EACR,aAAa;EACb,UAAU;EACb,CACJ;CACD,aAAa;EACT,MAAM;EACN,UAAU;EACV,SAAS;EACT,SAAS;EACZ;CACD,SAAS;CACT,MAAM;EAAC;EAAO;EAAc;EAAa;EAAe;CACxD,WAAW,EAAE;CACb,eAAe;CACf,UAAU,EAAE;CACZ,QAAQ,EAAE;CACV,iBAAiB,EAAE;CACnB,UAAU;CACV,UAAU,EAAE;CACZ,YAAY,EAAE;CACd,eAAe,EAAE;CACjB,aAAa;CAChB"}
@@ -0,0 +1,7 @@
1
+ import { ServiceDefinition } from "../../types.mjs";
2
+
3
+ //#region src/services/definitions/homeassistant.d.ts
4
+ declare const homeassistantDefinition: ServiceDefinition;
5
+ //#endregion
6
+ export { homeassistantDefinition };
7
+ //# sourceMappingURL=homeassistant.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"homeassistant.d.mts","names":[],"sources":["../../../src/services/definitions/homeassistant.ts"],"mappings":";;;cAEa,uBAAA,EAAyB,iBAAA"}