jishushell 0.4.17 → 0.4.24-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (241) hide show
  1. package/Dockerfile.hermes-slim +193 -0
  2. package/apps/hermes-container.yaml +35 -0
  3. package/apps/ollama-binary.yaml +164 -0
  4. package/apps/ollama-cpu-container.yaml +37 -0
  5. package/apps/ollama-with-hollama-binary.yaml +159 -0
  6. package/apps/openclaw-binary.yaml +69 -0
  7. package/apps/openclaw-container.yaml +37 -0
  8. package/apps/openclaw-with-ollama-container.yaml +42 -0
  9. package/apps/openclaw-with-searxng-container.yaml +136 -0
  10. package/apps/openwebui-container.yaml +53 -0
  11. package/apps/playwright-container.yaml +120 -0
  12. package/apps/searxng-container.yaml +115 -0
  13. package/dist/auth.d.ts +1 -0
  14. package/dist/auth.js +15 -14
  15. package/dist/auth.js.map +1 -1
  16. package/dist/cli/app.d.ts +1 -0
  17. package/dist/cli/app.js +770 -52
  18. package/dist/cli/app.js.map +1 -1
  19. package/dist/cli/backup.d.ts +3 -0
  20. package/dist/cli/backup.js +434 -0
  21. package/dist/cli/backup.js.map +1 -0
  22. package/dist/cli/doctor.d.ts +1 -0
  23. package/dist/cli/doctor.js +61 -35
  24. package/dist/cli/doctor.js.map +1 -1
  25. package/dist/cli/job.d.ts +1 -0
  26. package/dist/cli/job.js +37 -99
  27. package/dist/cli/job.js.map +1 -1
  28. package/dist/cli/llm.d.ts +1 -0
  29. package/dist/cli/llm.js +20 -14
  30. package/dist/cli/llm.js.map +1 -1
  31. package/dist/cli/managed-list.d.ts +30 -0
  32. package/dist/cli/managed-list.js +129 -0
  33. package/dist/cli/managed-list.js.map +1 -0
  34. package/dist/cli/panel.d.ts +4 -3
  35. package/dist/cli/panel.js +94 -24
  36. package/dist/cli/panel.js.map +1 -1
  37. package/dist/cli/version.d.ts +1 -0
  38. package/dist/cli/version.js +12 -0
  39. package/dist/cli/version.js.map +1 -0
  40. package/dist/cli.js +47 -516
  41. package/dist/cli.js.map +1 -1
  42. package/dist/config.d.ts +68 -0
  43. package/dist/config.js +266 -12
  44. package/dist/config.js.map +1 -1
  45. package/dist/control.d.ts +10 -6
  46. package/dist/control.js +87 -6
  47. package/dist/control.js.map +1 -1
  48. package/dist/install.d.ts +16 -0
  49. package/dist/install.js +75 -26
  50. package/dist/install.js.map +1 -1
  51. package/dist/routes/agent-apps.d.ts +15 -0
  52. package/dist/routes/agent-apps.js +78 -0
  53. package/dist/routes/agent-apps.js.map +1 -0
  54. package/dist/routes/apps.js +186 -7
  55. package/dist/routes/apps.js.map +1 -1
  56. package/dist/routes/backup.js +3 -3
  57. package/dist/routes/backup.js.map +1 -1
  58. package/dist/routes/instances.d.ts +6 -0
  59. package/dist/routes/instances.js +862 -879
  60. package/dist/routes/instances.js.map +1 -1
  61. package/dist/routes/llm.js +9 -8
  62. package/dist/routes/llm.js.map +1 -1
  63. package/dist/routes/runtime.d.ts +15 -0
  64. package/dist/routes/runtime.js +69 -0
  65. package/dist/routes/runtime.js.map +1 -0
  66. package/dist/routes/setup.js +103 -8
  67. package/dist/routes/setup.js.map +1 -1
  68. package/dist/routes/system.js +25 -3
  69. package/dist/routes/system.js.map +1 -1
  70. package/dist/server.js +71 -7
  71. package/dist/server.js.map +1 -1
  72. package/dist/services/agent-apps/catalog.d.ts +30 -0
  73. package/dist/services/agent-apps/catalog.js +60 -0
  74. package/dist/services/agent-apps/catalog.js.map +1 -0
  75. package/dist/services/agent-apps/index.d.ts +36 -0
  76. package/dist/services/agent-apps/index.js +171 -0
  77. package/dist/services/agent-apps/index.js.map +1 -0
  78. package/dist/services/agent-apps/installers/adapter-probes.d.ts +49 -0
  79. package/dist/services/agent-apps/installers/adapter-probes.js +223 -0
  80. package/dist/services/agent-apps/installers/adapter-probes.js.map +1 -0
  81. package/dist/services/agent-apps/installers/adapter.d.ts +30 -0
  82. package/dist/services/agent-apps/installers/adapter.js +171 -0
  83. package/dist/services/agent-apps/installers/adapter.js.map +1 -0
  84. package/dist/services/agent-apps/installers/registry-probe.d.ts +38 -0
  85. package/dist/services/agent-apps/installers/registry-probe.js +183 -0
  86. package/dist/services/agent-apps/installers/registry-probe.js.map +1 -0
  87. package/dist/services/agent-apps/installers/shell-script.d.ts +47 -0
  88. package/dist/services/agent-apps/installers/shell-script.js +471 -0
  89. package/dist/services/agent-apps/installers/shell-script.js.map +1 -0
  90. package/dist/services/agent-apps/types.d.ts +125 -0
  91. package/dist/services/agent-apps/types.js +17 -0
  92. package/dist/services/agent-apps/types.js.map +1 -0
  93. package/dist/services/{app-compiler.d.ts → app/app-compiler.d.ts} +3 -3
  94. package/dist/services/{app-compiler.js → app/app-compiler.js} +10 -7
  95. package/dist/services/app/app-compiler.js.map +1 -0
  96. package/dist/services/app/app-manager.d.ts +142 -0
  97. package/dist/services/app/app-manager.js +2148 -0
  98. package/dist/services/app/app-manager.js.map +1 -0
  99. package/dist/services/app/custom-manager.d.ts +27 -0
  100. package/dist/services/app/custom-manager.js +285 -0
  101. package/dist/services/app/custom-manager.js.map +1 -0
  102. package/dist/services/app/hermes-agent-manager.d.ts +20 -0
  103. package/dist/services/app/hermes-agent-manager.js +289 -0
  104. package/dist/services/app/hermes-agent-manager.js.map +1 -0
  105. package/dist/services/app/id-normalizer.d.ts +27 -0
  106. package/dist/services/app/id-normalizer.js +77 -0
  107. package/dist/services/app/id-normalizer.js.map +1 -0
  108. package/dist/services/app/ollama-manager.d.ts +18 -0
  109. package/dist/services/app/ollama-manager.js +207 -0
  110. package/dist/services/app/ollama-manager.js.map +1 -0
  111. package/dist/services/app/openclaw-manager.d.ts +63 -0
  112. package/dist/services/app/openclaw-manager.js +1178 -0
  113. package/dist/services/app/openclaw-manager.js.map +1 -0
  114. package/dist/services/app/paths.d.ts +47 -0
  115. package/dist/services/app/paths.js +68 -0
  116. package/dist/services/app/paths.js.map +1 -0
  117. package/dist/services/app/registry.d.ts +17 -0
  118. package/dist/services/app/registry.js +31 -0
  119. package/dist/services/app/registry.js.map +1 -0
  120. package/dist/services/app/remote-spec.d.ts +14 -0
  121. package/dist/services/app/remote-spec.js +58 -0
  122. package/dist/services/app/remote-spec.js.map +1 -0
  123. package/dist/services/app/terminal-session-manager.d.ts +27 -0
  124. package/dist/services/app/terminal-session-manager.js +157 -0
  125. package/dist/services/app/terminal-session-manager.js.map +1 -0
  126. package/dist/services/app/types.d.ts +72 -0
  127. package/dist/services/app/types.js +16 -0
  128. package/dist/services/app/types.js.map +1 -0
  129. package/dist/services/backup-manager.js +60 -22
  130. package/dist/services/backup-manager.js.map +1 -1
  131. package/dist/services/instance-manager.d.ts +82 -39
  132. package/dist/services/instance-manager.js +575 -1142
  133. package/dist/services/instance-manager.js.map +1 -1
  134. package/dist/services/llm-proxy/circuit-breaker.js +10 -2
  135. package/dist/services/llm-proxy/circuit-breaker.js.map +1 -1
  136. package/dist/services/llm-proxy/index.d.ts +14 -1
  137. package/dist/services/llm-proxy/index.js +51 -6
  138. package/dist/services/llm-proxy/index.js.map +1 -1
  139. package/dist/services/nomad-manager.d.ts +260 -3
  140. package/dist/services/nomad-manager.js +2866 -449
  141. package/dist/services/nomad-manager.js.map +1 -1
  142. package/dist/services/panel-manager.d.ts +10 -0
  143. package/dist/services/panel-manager.js +97 -0
  144. package/dist/services/panel-manager.js.map +1 -1
  145. package/dist/services/plugin-installer.js +28 -2
  146. package/dist/services/plugin-installer.js.map +1 -1
  147. package/dist/services/process-manager.js +22 -0
  148. package/dist/services/process-manager.js.map +1 -1
  149. package/dist/services/runtime/adapters/custom.d.ts +20 -0
  150. package/dist/services/runtime/adapters/custom.js +90 -0
  151. package/dist/services/runtime/adapters/custom.js.map +1 -0
  152. package/dist/services/runtime/adapters/hermes.d.ts +174 -0
  153. package/dist/services/runtime/adapters/hermes.js +1316 -0
  154. package/dist/services/runtime/adapters/hermes.js.map +1 -0
  155. package/dist/services/runtime/adapters/openclaw-routes.d.ts +17 -0
  156. package/dist/services/runtime/adapters/openclaw-routes.js +946 -0
  157. package/dist/services/runtime/adapters/openclaw-routes.js.map +1 -0
  158. package/dist/services/runtime/adapters/openclaw.d.ts +188 -0
  159. package/dist/services/runtime/adapters/openclaw.js +2195 -0
  160. package/dist/services/runtime/adapters/openclaw.js.map +1 -0
  161. package/dist/services/runtime/errors.d.ts +28 -0
  162. package/dist/services/runtime/errors.js +31 -0
  163. package/dist/services/runtime/errors.js.map +1 -0
  164. package/dist/services/runtime/index.d.ts +34 -0
  165. package/dist/services/runtime/index.js +51 -0
  166. package/dist/services/runtime/index.js.map +1 -0
  167. package/dist/services/runtime/instance.d.ts +24 -0
  168. package/dist/services/runtime/instance.js +143 -0
  169. package/dist/services/runtime/instance.js.map +1 -0
  170. package/dist/services/runtime/migrations.d.ts +15 -0
  171. package/dist/services/runtime/migrations.js +25 -0
  172. package/dist/services/runtime/migrations.js.map +1 -0
  173. package/dist/services/runtime/registry.d.ts +13 -0
  174. package/dist/services/runtime/registry.js +32 -0
  175. package/dist/services/runtime/registry.js.map +1 -0
  176. package/dist/services/runtime/types.d.ts +545 -0
  177. package/dist/services/runtime/types.js +14 -0
  178. package/dist/services/runtime/types.js.map +1 -0
  179. package/dist/services/setup-manager.d.ts +70 -29
  180. package/dist/services/setup-manager.js +278 -597
  181. package/dist/services/setup-manager.js.map +1 -1
  182. package/dist/services/task-registry.d.ts +44 -0
  183. package/dist/services/task-registry.js +74 -0
  184. package/dist/services/task-registry.js.map +1 -0
  185. package/dist/services/telemetry/heartbeat.d.ts +6 -6
  186. package/dist/services/telemetry/heartbeat.js +29 -30
  187. package/dist/services/telemetry/heartbeat.js.map +1 -1
  188. package/dist/types.d.ts +164 -2
  189. package/dist/utils/docker-host.d.ts +15 -0
  190. package/dist/utils/docker-host.js +64 -0
  191. package/dist/utils/docker-host.js.map +1 -0
  192. package/install/jishu-install.sh +25 -2
  193. package/package.json +14 -4
  194. package/public/assets/Dashboard-rh9qpYRR.js +1 -0
  195. package/public/assets/HermesChatPanel-D6JI6lLY.js +1 -0
  196. package/public/assets/HermesConfigForm-DcbSemaj.js +4 -0
  197. package/public/assets/InitPassword-CFTKsED4.js +1 -0
  198. package/public/assets/InstanceDetail-BhNIKA6Z.js +91 -0
  199. package/public/assets/{Login-D1Bt-Lyk.js → Login-KB9qrtM0.js} +1 -1
  200. package/public/assets/NewInstance-CxkO8Hlq.js +1 -0
  201. package/public/assets/Settings-BVWJvOkU.js +1 -0
  202. package/public/assets/Setup-X-lzuaUT.js +1 -0
  203. package/public/assets/WeixinLoginPanel-gca0QTic.js +9 -0
  204. package/public/assets/index-C8B0cFJM.js +19 -0
  205. package/public/assets/index-CPhVFEsx.css +1 -0
  206. package/public/assets/input-paste-CrNVAyOy.js +1 -0
  207. package/public/assets/registry-fVUSujib.js +2 -0
  208. package/public/assets/{usePolling-CK0DfI4h.js → usePolling-Do5Erqm_.js} +1 -1
  209. package/public/assets/vendor-i18n-ucpM0OR0.js +9 -0
  210. package/public/assets/{vendor-react-B1-3Yrt-.js → vendor-react-Bk1hRGiY.js} +1 -1
  211. package/public/favicon.png +0 -0
  212. package/public/index.html +9 -4
  213. package/public/logos/hermes.png +0 -0
  214. package/public/logos/ollama.png +0 -0
  215. package/public/logos/openclaw.svg +60 -0
  216. package/scripts/build-hermes-image.sh +21 -0
  217. package/scripts/build-local.sh +54 -0
  218. package/scripts/check-adapter-isolation.ts +293 -0
  219. package/scripts/fixtures/instances/hermes-sample/instance.json +37 -0
  220. package/scripts/fixtures/instances/legacy-openclaw-sample/instance.json +7 -0
  221. package/scripts/smoke/hermes-bootstrap.sh +195 -0
  222. package/templates/hermes-entrypoint.sh +154 -0
  223. package/dist/cli/openclaw.d.ts +0 -12
  224. package/dist/cli/openclaw.js +0 -156
  225. package/dist/cli/openclaw.js.map +0 -1
  226. package/dist/services/app-compiler.js.map +0 -1
  227. package/dist/services/app-manager.d.ts +0 -17
  228. package/dist/services/app-manager.js +0 -168
  229. package/dist/services/app-manager.js.map +0 -1
  230. package/dist/services/job-manager.d.ts +0 -22
  231. package/dist/services/job-manager.js +0 -102
  232. package/dist/services/job-manager.js.map +0 -1
  233. package/public/assets/Dashboard-CQsp1Mr9.js +0 -1
  234. package/public/assets/InitPassword-BEC8SE4A.js +0 -1
  235. package/public/assets/InstanceDetail-B5wTgNEg.js +0 -17
  236. package/public/assets/NewInstance-GQzm3K9D.js +0 -1
  237. package/public/assets/Settings-ByjGlqhP.js +0 -1
  238. package/public/assets/Setup-cMF21Y-8.js +0 -1
  239. package/public/assets/index-B6qQP4mH.css +0 -1
  240. package/public/assets/index-BuTQtuNy.js +0 -16
  241. package/public/assets/vendor-i18n-CfW0RvgE.js +0 -9
@@ -0,0 +1,545 @@
1
+ /**
2
+ * Runtime adapter types — §32.2 full decoupling contract.
3
+ *
4
+ * Goal: adding a new agent = 1 new file in `runtime/adapters/` + 1 import in
5
+ * `runtime/index.ts`. Core files (instance-manager / nomad-manager /
6
+ * setup-manager / routes / llm-proxy) never mention specific agent kinds.
7
+ *
8
+ * - Field names use camelCase; on-wire JSON matches the type exactly.
9
+ * - Legacy OpenClaw path remains wired through `instance-manager` helpers,
10
+ * but the control flow now enters through `OpenClawAdapter` methods so
11
+ * framework code dispatches via `getAdapter(agentType)` uniformly.
12
+ */
13
+ /**
14
+ * Discriminator for pluggable agent runtimes. Canonical identifier in code,
15
+ * on-disk `instance.json`, and HTTP APIs is `agentType`.
16
+ */
17
+ export type AgentType = "openclaw" | "hermes" | (string & {});
18
+ export interface RuntimePortSpec {
19
+ name: string;
20
+ containerPort: number;
21
+ hostPort?: number;
22
+ visibility?: "external" | "internal";
23
+ }
24
+ export interface RuntimeVolumeSpec {
25
+ hostPath: string;
26
+ containerPath: string;
27
+ mode: "rw" | "ro";
28
+ }
29
+ export interface RuntimeHealthSpec {
30
+ type: "http" | "tcp" | "process";
31
+ path?: string;
32
+ port?: number;
33
+ interval?: string;
34
+ timeout?: string;
35
+ retries?: number;
36
+ }
37
+ export interface RuntimeResources {
38
+ CPU: number;
39
+ MemoryMB: number;
40
+ MemoryMaxMB?: number;
41
+ }
42
+ /**
43
+ * Engine-neutral description of a runnable unit.
44
+ * Scheduler (Nomad / process manager) consumes this without knowing the runtime kind.
45
+ */
46
+ export interface RuntimeSpec {
47
+ image?: string | null;
48
+ command: string;
49
+ args: string[];
50
+ cwd: string;
51
+ user?: string;
52
+ env: Record<string, string>;
53
+ envFiles?: string[];
54
+ resources: RuntimeResources;
55
+ ports?: RuntimePortSpec[];
56
+ volumes?: RuntimeVolumeSpec[];
57
+ health?: RuntimeHealthSpec | null;
58
+ }
59
+ export interface CapabilityProfile {
60
+ gateway: {
61
+ http: boolean;
62
+ websocket: boolean;
63
+ /**
64
+ * Which Chat UI style the frontend should use for this runtime. Values
65
+ * describe **behavior**, not agent identity, so a new adapter can pick
66
+ * the right mode without touching framework code.
67
+ * - "iframe": iframe the runtime's own gateway web UI (OpenClaw today)
68
+ * - "inline": JishuShell-side chat panel via frontend registry's
69
+ * `chatComponent` (Hermes today); runtime exposes an
70
+ * OpenAI-compat endpoint reached through
71
+ * /api/instances/:id/agent/chat
72
+ * - "none": no Chat UI; users interact via CLI / messaging platforms
73
+ */
74
+ chatPanel: "iframe" | "inline" | "none";
75
+ };
76
+ pairing: {
77
+ list: boolean;
78
+ approve: boolean;
79
+ revoke: boolean;
80
+ clearPending: boolean;
81
+ };
82
+ configEditor: "json" | "yaml+env" | "custom";
83
+ configSchema: boolean;
84
+ customProvider: boolean;
85
+ pluginInstall: boolean;
86
+ skills: boolean;
87
+ mcp: boolean;
88
+ memory: boolean;
89
+ backupRestore: boolean;
90
+ usageStats: boolean;
91
+ restartlessReload: boolean;
92
+ messagingPlatforms: string[];
93
+ }
94
+ /**
95
+ * Runtime version info exposed to the UI / CLI per §32.7.
96
+ *
97
+ * - `agentType` — mirror of the adapter's own agentType for symmetry with the registry
98
+ * - `ref` — hermes: commit sha when in overlay mode; openclaw: package.json version
99
+ * - `digest` — image digest captured in panel.json when installHermes ran
100
+ * - `mode` — hermes-only distinction, OpenClaw always "baseline"
101
+ */
102
+ export interface RuntimeVersionInfo {
103
+ agentType: string;
104
+ ref?: string;
105
+ digest?: string;
106
+ mode: "baseline" | "overlay";
107
+ }
108
+ export interface InstancePaths {
109
+ instanceDir: string;
110
+ agentHome: string;
111
+ primaryConfig?: string;
112
+ secretEnv?: string;
113
+ }
114
+ /**
115
+ * Entry in panel.json:runtime_catalog.<agentType>. Catalog-level defaults captured at
116
+ * install time. `defaultImageDigest` is the digest captured by
117
+ * setup-manager.installHermes() per §32.1 so the HermesAdapter.buildRuntime()
118
+ * can pin the image by digest (preferred) instead of the mutable tag.
119
+ */
120
+ export interface RuntimeCatalogEntry {
121
+ defaultImage: string;
122
+ defaultImageDigest?: string;
123
+ shimPath?: string;
124
+ configFormat: "json" | "yaml+env" | "custom";
125
+ homeDirName: string;
126
+ resources: RuntimeResources;
127
+ allowDockerSock?: boolean;
128
+ }
129
+ export interface CreateInstanceContext {
130
+ instanceId: string;
131
+ name: string;
132
+ description?: string;
133
+ }
134
+ export type JsonConfigDocument = {
135
+ format: "json";
136
+ content: Record<string, any>;
137
+ };
138
+ export type YamlEnvConfigDocument = {
139
+ format: "yaml+env";
140
+ yaml: string;
141
+ env: string;
142
+ /**
143
+ * Optional JishuShell meta block persisted alongside yaml/env. Mirrors
144
+ * the `x-jishushell` key OpenClaw stores inside its JSON config — for
145
+ * Hermes and other yaml+env runtimes, this block lives on instance.json
146
+ * but rides through the same ConfigDocument shape so the frontend can
147
+ * edit per-instance upstream provider config (provider id, baseUrl,
148
+ * API key, models) without learning runtime-specific storage paths.
149
+ *
150
+ * When the adapter's `writeConfig` sees this field, it delegates to the
151
+ * shared llm-proxy `saveInstanceConfig` flow so API key encryption,
152
+ * provider.env persistence, and cache invalidation stay in one place.
153
+ */
154
+ "x-jishushell"?: Record<string, any>;
155
+ };
156
+ export type ConfigDocument = JsonConfigDocument | YamlEnvConfigDocument;
157
+ export interface InstanceConfigMeta {
158
+ agentType: AgentType;
159
+ format: ConfigDocument["format"];
160
+ schemaId: string;
161
+ capabilities: CapabilityProfile;
162
+ secretFields: string[];
163
+ runtimeVersion: RuntimeVersionInfo;
164
+ }
165
+ export interface PairingApproveInput {
166
+ channel: string;
167
+ code: string;
168
+ notify?: boolean;
169
+ }
170
+ /**
171
+ * Input shape handed to `RuntimeAdapter.createInstance()` from route / CLI layer.
172
+ * Framework-level fields only — agent-specific extras live inside `extras` so
173
+ * the core layer never special-cases by kind.
174
+ */
175
+ export interface CreateInstanceArgs {
176
+ instanceId: string;
177
+ name: string;
178
+ description: string;
179
+ cloneFrom?: string;
180
+ agentHome?: string;
181
+ cloneOptions?: {
182
+ include_sessions?: boolean;
183
+ include_memory?: boolean;
184
+ };
185
+ appSpec?: any;
186
+ extras?: Record<string, any>;
187
+ }
188
+ /**
189
+ * Declarative metadata that describes a runtime without requiring any runtime
190
+ * code from the framework. Exposed via `GET /api/runtime/catalog` to drive
191
+ * frontend cards / create-forms / install wizards (§32.2.2).
192
+ *
193
+ * All fields are OPTIONAL in MVP so existing adapters can land incrementally.
194
+ */
195
+ export interface AdapterManifest {
196
+ agentType: AgentType;
197
+ displayName: string;
198
+ description: string;
199
+ defaultCapabilities: CapabilityProfile;
200
+ defaultCatalogEntry?: Partial<RuntimeCatalogEntry>;
201
+ /** Declarative hint: does this runtime require Nomad + Docker driver? */
202
+ requiresNomadDocker?: boolean;
203
+ /** Approximate disk space (MB) required for install — surfaced in setup UI. */
204
+ diskSpaceMB?: number;
205
+ /** Provider presets the adapter wants to contribute to the UI picker. */
206
+ providerPresets?: Array<Record<string, any>>;
207
+ }
208
+ /**
209
+ * Cross-cutting lifecycle hooks. Framework calls these at well-defined
210
+ * points so adapters can extend behavior without forcing if/else branches
211
+ * into `instance-manager.ts` / `backup-manager.ts` / `routes/*`.
212
+ *
213
+ * All hooks are optional — adapters implement only what they need.
214
+ */
215
+ export interface AdapterHooks {
216
+ /** Run immediately after instance.json is persisted on a fresh create. */
217
+ onCreate?(args: {
218
+ instanceId: string;
219
+ meta: Record<string, any>;
220
+ }): Promise<void>;
221
+ /** Run just before the instance directory is removed from disk.
222
+ * Return `{ warnings }` to surface non-fatal advisories (e.g. legacy
223
+ * `openclaw_home` pointing outside the instance dir). Returning void
224
+ * means "no warnings". */
225
+ onDelete?(args: {
226
+ instanceId: string;
227
+ meta: Record<string, any>;
228
+ }): Promise<void | {
229
+ warnings?: string[];
230
+ }>;
231
+ /** Run after a successful `writeConfig` — lets adapters auto-install
232
+ * channel plugins, enforce terminal.backend, etc. */
233
+ onConfigSaved?(args: {
234
+ instanceId: string;
235
+ oldConfig: unknown;
236
+ newConfig: unknown;
237
+ }): Promise<void>;
238
+ /** Run just before Nomad receives a job submission. Adapters can patch
239
+ * on-disk files, seed symlinks, or precompute secrets here. */
240
+ onBeforeStart?(args: {
241
+ instanceId: string;
242
+ }): Promise<void>;
243
+ /** Run after service control reports the instance as started. */
244
+ onAfterStart?(args: {
245
+ instanceId: string;
246
+ }): Promise<void>;
247
+ /** Run just before service control issues a stop. */
248
+ onBeforeStop?(args: {
249
+ instanceId: string;
250
+ }): Promise<void>;
251
+ /** Run when panel default_provider changes — adapters rewrite whatever
252
+ * file their runtime reads upstream credentials from. */
253
+ onUpstreamProviderChange?(args: {
254
+ instanceId: string;
255
+ upstream: Record<string, any>;
256
+ }): Promise<void>;
257
+ }
258
+ /**
259
+ * Full RuntimeAdapter contract — §32.2 / §32.8.
260
+ *
261
+ * All new methods below the "MVP core" block are OPTIONAL so HermesAdapter
262
+ * (which predates §32.8) continues to work. OpenClawAdapter implements the
263
+ * full surface, enabling framework code to dispatch uniformly instead of
264
+ * branching on `agentType === "hermes"`.
265
+ */
266
+ export interface RuntimeAdapter {
267
+ readonly agentType: AgentType;
268
+ readonly displayName: string;
269
+ readonly defaultCapabilities: CapabilityProfile;
270
+ readonly manifest?: AdapterManifest;
271
+ readonly hooks?: AdapterHooks;
272
+ /**
273
+ * Default port the framework uses as a fallback when an instance's
274
+ * persisted runtime spec has no host port recorded. Adapters declare
275
+ * their canonical base port here (OpenClaw 18789, Hermes 8642).
276
+ */
277
+ readonly defaultGatewayPort?: number;
278
+ createInitialLayout(ctx: CreateInstanceContext): Promise<InstancePaths>;
279
+ buildRuntime(instanceId: string): Promise<RuntimeSpec>;
280
+ getRuntimeVersion(instanceId: string): Promise<RuntimeVersionInfo>;
281
+ getConfigMeta(instanceId: string): Promise<InstanceConfigMeta>;
282
+ readConfig(instanceId: string): Promise<ConfigDocument>;
283
+ writeConfig(instanceId: string, doc: ConfigDocument): Promise<ConfigDocument>;
284
+ buildPairingListCommand(instanceId: string): Promise<string[]>;
285
+ buildPairingApproveCommand(instanceId: string, input: PairingApproveInput): Promise<string[]>;
286
+ /**
287
+ * Create a new instance end-to-end: filesystem layout + port allocation +
288
+ * persist instance.json + seed proxy token. Returns the fully-populated
289
+ * meta that framework code passes back to the HTTP route layer.
290
+ *
291
+ * Optional for backward compat: adapters that do not implement this will
292
+ * fall back to the legacy `instance-manager.createInstance()` path.
293
+ */
294
+ createInstance?(args: CreateInstanceArgs): Promise<Record<string, any>>;
295
+ /**
296
+ * Read the runtime's raw native configuration object. For OpenClaw this
297
+ * is the parsed `openclaw.json` body; for Hermes it is a synthetic stub
298
+ * containing only the `x-jishushell` upstream metadata block.
299
+ *
300
+ * Used by LLM proxy, backup manager, and other framework code that needs
301
+ * to inspect the merged config without going through the typed
302
+ * `readConfig()` wrapper. Returns null if no config is available.
303
+ */
304
+ getNativeConfig?(instanceId: string): Record<string, any> | null;
305
+ /**
306
+ * Read the stored native configuration including backend-managed fields
307
+ * (plugin installs, channel credentials, weixin accounts) that would be
308
+ * filtered out of the typed `readConfig()` editor view. Used by flows
309
+ * that round-trip the full config to disk.
310
+ */
311
+ getStoredNativeConfig?(instanceId: string): Record<string, any> | null;
312
+ /**
313
+ * Persist a raw native configuration object. For OpenClaw this drives
314
+ * the full `saveConfig` pipeline (channel plugin auto-install, env file
315
+ * key rewrites, x-jishushell propagation). Returns true on success.
316
+ *
317
+ * Framework callers (`instance-manager.saveConfig`) always `await` the
318
+ * result, so async implementations get proper success/failure signalling.
319
+ * Synchronous implementations are transparently supported.
320
+ */
321
+ saveNativeConfig?(instanceId: string, config: Record<string, any>): boolean | Promise<boolean>;
322
+ /**
323
+ * Install a channel-specific plugin into the running instance. Returns
324
+ * once install is complete. Throws on fatal error. OpenClaw-specific;
325
+ * other adapters can leave unimplemented or throw "not supported".
326
+ */
327
+ installChannelPlugin?(instanceId: string, channelId: string): Promise<void>;
328
+ /** Report whether a channel plugin is already installed. */
329
+ isChannelPluginInstalled?(instanceId: string, channelId: string): boolean;
330
+ /** Channel-id → npm package map for auto-install decisions. */
331
+ readonly channelPluginMap?: Record<string, string>;
332
+ /**
333
+ * Save Feishu/Lark OAuth credentials into the instance's native config.
334
+ * OpenClaw-specific; other adapters can leave unimplemented.
335
+ */
336
+ saveFeishuCredentials?(instanceId: string, creds: {
337
+ appId: string;
338
+ appSecret: string;
339
+ domain: string;
340
+ channelKey?: string;
341
+ }): void;
342
+ /** Save WeChat bot login credentials + register the account. */
343
+ saveWeixinCredentials?(instanceId: string, creds: {
344
+ accountId: string;
345
+ token: string;
346
+ baseUrl: string;
347
+ userId: string;
348
+ }): void;
349
+ /** Read the list of connected WeChat accounts for an instance. */
350
+ getWeixinAccounts?(instanceId: string): Array<{
351
+ accountId: string;
352
+ userId?: string;
353
+ savedAt?: string;
354
+ }>;
355
+ /** Return the list of other instance IDs that share this one's agent-home. */
356
+ findInstancesSharingHome?(instanceId: string): string[];
357
+ /** Resolve the canonical agent binary path (OpenClaw only). */
358
+ resolveBin?(): string;
359
+ /** Resolve the instance's on-disk config file path. */
360
+ resolveConfigPath?(instanceId: string): string;
361
+ /** Resolve the legacy (pre-state-dir) config file path if applicable. */
362
+ resolveLegacyConfigPath?(instanceId: string): string;
363
+ /** Resolve the agent-home directory for an instance (not the instance dir). */
364
+ resolveAgentHome?(instanceId: string): string;
365
+ /**
366
+ * Build the env var set the adapter's native CLI expects when run as
367
+ * a subprocess (e.g. for backup/restore via `openclaw backup create`).
368
+ * Used by backup-manager so it doesn't hardcode `OPENCLAW_HOME`.
369
+ */
370
+ buildCliEnv?(instanceId: string): Record<string, string>;
371
+ /**
372
+ * Read the gateway port out of a raw runtime record — used as a
373
+ * back-compat fallback when `RuntimeSpec.ports[]` is empty (legacy
374
+ * OpenClaw instances still persist their port in `runtime.env`).
375
+ */
376
+ readLegacyGatewayPort?(runtime: Record<string, any>): number | null;
377
+ /**
378
+ * Rewrite a runtime spec in place to target a new host port. Called
379
+ * by `reallocateGatewayPort` when the previously-assigned port is
380
+ * busy at start time — each adapter knows how to express the change
381
+ * in its own runtime shape (args, env, ports[], etc.).
382
+ */
383
+ reallocateRuntimePort?(runtime: Record<string, any>, newPort: number): void;
384
+ /**
385
+ * Job name prefix for Nomad submissions. Framework reads this via
386
+ * `getAdapter(agentType).nomadJobPrefix` so nomad-manager doesn't hardcode
387
+ * per-runtime prefixes.
388
+ */
389
+ readonly nomadJobPrefix?: string;
390
+ /**
391
+ * Nomad task name inside the TaskGroup. Framework code (nomad-manager.ts)
392
+ * reads allocation state, stats, and log streams keyed by this name.
393
+ * Default "gateway" — an adapter can override if its buildNomadTask()
394
+ * returns a different `Name`.
395
+ */
396
+ readonly nomadTaskName?: string;
397
+ /**
398
+ * Whether this adapter's runtime install is **required** for overall
399
+ * panel readiness. When true, a failed install in `runFullSetup` aborts
400
+ * the whole setup (panel.json not written as complete). When false (the
401
+ * default), install failures are downgraded to warning-level step
402
+ * results — the panel still completes setup and the user can install
403
+ * this agent later from the wizard.
404
+ *
405
+ * Only `openclaw` is required today (it is the default/core runtime).
406
+ * Third-party agents should leave this unset so upgrade paths don't
407
+ * break when their image registry is unreachable.
408
+ */
409
+ readonly required?: boolean;
410
+ /**
411
+ * Suffix appended to `nomad/jobs/<jid>/` for the adapter's per-instance
412
+ * secret storage (e.g. "openclaw/gateway"). When undefined, nomad-manager
413
+ * skips all Variable writes for this adapter — adapters that do not use
414
+ * Nomad Variables (no Template interpolation) should leave it unset.
415
+ *
416
+ * The value must match the path referenced by the adapter's own
417
+ * `buildNomadTask()` Templates so the template interpolation resolves.
418
+ */
419
+ readonly nomadVariablePath?: string;
420
+ /**
421
+ * Build the Nomad task definition for this instance. Called by
422
+ * `nomad-manager.buildJob()` at start time. Lets adapters fully own how
423
+ * their RuntimeSpec maps onto a Nomad docker/raw_exec task (volumes,
424
+ * templates, cap_drop profile, etc.) without nomad-manager knowing the
425
+ * runtime kind. Name of the task becomes the Nomad task group's Name.
426
+ */
427
+ buildNomadTask?(instanceId: string): Promise<Record<string, any>>;
428
+ /**
429
+ * Framework → adapter delete hook. Lets the adapter decide whether to
430
+ * preserve a custom agent-home directory when the instance is removed.
431
+ * Returns a list of warnings surfaced to the caller.
432
+ */
433
+ onDelete?(args: {
434
+ instanceId: string;
435
+ meta: Record<string, any>;
436
+ }): Promise<string[]>;
437
+ /**
438
+ * Install the runtime binaries / docker images / shim templates required
439
+ * to launch this agent. Called by `setup-manager.install<Kind>()` via
440
+ * adapter dispatch. Returns an InstallResult-shaped object; the framework
441
+ * layer is agnostic to the exact shape so we stay typed as `any` to
442
+ * avoid a cross-module dependency back into setup-manager types.
443
+ */
444
+ installRuntime?(opts?: Record<string, any>): Promise<any>;
445
+ /**
446
+ * Non-blocking variant: returns immediately with a task id the caller
447
+ * can poll via `/api/setup/tasks/:id` SSE. Adapters implement this when
448
+ * their install takes long enough that the HTTP layer wants to avoid
449
+ * holding the connection open (Hermes image pull, OpenClaw docker build).
450
+ */
451
+ startInstallRuntime?(opts?: Record<string, any>): any;
452
+ /**
453
+ * Build the runtime's docker image (OpenClaw only — baked base image
454
+ * shared across all OpenClaw instances). Non-OpenClaw adapters may leave
455
+ * this unimplemented.
456
+ */
457
+ buildRuntimeImage?(opts?: Record<string, any>): Promise<any>;
458
+ /**
459
+ * Non-blocking variant of `buildRuntimeImage`.
460
+ */
461
+ startBuildRuntimeImage?(opts?: Record<string, any>): any;
462
+ /**
463
+ * One-shot, panel-level migration invoked at server startup. Adapters
464
+ * use this to rewrite stale panel.json catalog entries (mutable image
465
+ * tags → digest-pinned tags) or perform similar self-repair that has
466
+ * to happen before instances start. Must be idempotent and silent on
467
+ * no-op. The framework runs all registered adapters' migrations via
468
+ * `runStartupMigrations()` so `server.ts` never imports an adapter.
469
+ */
470
+ migrateStartup?(): void | Promise<void>;
471
+ /**
472
+ * Report whether this adapter's runtime is ready to spawn instances. The
473
+ * framework uses this to (a) gate the NewInstance UI, (b) render the
474
+ * per-agent row in the Setup wizard, and (c) decide whether `runFullSetup`
475
+ * should invoke `buildRuntimeImage`/`installRuntime` for this agent.
476
+ *
477
+ * Shape is intentionally minimal and adapter-agnostic:
478
+ * - installed: everything required to start an instance is present
479
+ * - imageReady: the docker image (if any) is local or pinned
480
+ * - version: free-form version string for the Setup UI label
481
+ * - digest: pinned image digest (when available)
482
+ *
483
+ * Implementations should be synchronous or fast-async (no network). They
484
+ * are called from the status endpoint that the Setup wizard polls.
485
+ */
486
+ getInstallStatus?(): {
487
+ installed: boolean;
488
+ imageReady: boolean;
489
+ version?: string;
490
+ digest?: string;
491
+ } | Promise<{
492
+ installed: boolean;
493
+ imageReady: boolean;
494
+ version?: string;
495
+ digest?: string;
496
+ }>;
497
+ /**
498
+ * Register adapter-owned HTTP endpoints. Called by `routes/instances.ts`
499
+ * at server startup with the shared Fastify instance. Implementations
500
+ * should use the framework helpers re-exported from `routes/instances.ts`
501
+ * (validateId, getSvc, HOP_BY_HOP, etc.) so cross-cutting plumbing stays
502
+ * in one place. New agents that need zero custom routes leave this
503
+ * unimplemented.
504
+ */
505
+ registerRoutes?(app: any): void | Promise<void>;
506
+ /**
507
+ * Declarative descriptor for the shared inline-chat forwarder route
508
+ * `POST /api/instances/:id/agent/chat`. Adapters that declare
509
+ * `capabilities.gateway.chatPanel === "inline"` set this so the
510
+ * framework-owned route can dispatch without hardcoding Hermes-specific
511
+ * env var names or endpoint paths.
512
+ *
513
+ * Omit this field (or leave chatPanel !== "inline") and the route
514
+ * returns HTTP 400 for this runtime.
515
+ */
516
+ readonly inlineChatDescriptor?: InlineChatDescriptor;
517
+ }
518
+ /**
519
+ * Per-adapter configuration for the shared inline-chat HTTP forwarder.
520
+ * Declarative so a new agent with an OpenAI-compat HTTP endpoint can
521
+ * plug in without touching `routes/instances.ts`.
522
+ */
523
+ export interface InlineChatDescriptor {
524
+ /**
525
+ * Name of the env var (inside the instance's secretEnv file) that holds
526
+ * the bearer/auth token for the agent's own chat endpoint. Hermes uses
527
+ * `API_SERVER_KEY`; third-party agents declare their own name.
528
+ */
529
+ apiKeyEnvVar: string;
530
+ /**
531
+ * URL path appended to `http://127.0.0.1:<gatewayHostPort>` for the chat
532
+ * endpoint. Default: `/v1/chat/completions`.
533
+ */
534
+ endpointPath?: string;
535
+ /** Auth header name. Default `Authorization`. */
536
+ authHeader?: string;
537
+ /** Prefix applied before the key in the header. Default `Bearer `. */
538
+ authScheme?: string;
539
+ /**
540
+ * Upstream response timeout in milliseconds. Default 120_000. Agents that
541
+ * run expensive tool loops can raise this; simple chat endpoints can
542
+ * tighten it.
543
+ */
544
+ timeoutMs?: number;
545
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Runtime adapter types — §32.2 full decoupling contract.
3
+ *
4
+ * Goal: adding a new agent = 1 new file in `runtime/adapters/` + 1 import in
5
+ * `runtime/index.ts`. Core files (instance-manager / nomad-manager /
6
+ * setup-manager / routes / llm-proxy) never mention specific agent kinds.
7
+ *
8
+ * - Field names use camelCase; on-wire JSON matches the type exactly.
9
+ * - Legacy OpenClaw path remains wired through `instance-manager` helpers,
10
+ * but the control flow now enters through `OpenClawAdapter` methods so
11
+ * framework code dispatches via `getAdapter(agentType)` uniformly.
12
+ */
13
+ export {};
14
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/services/runtime/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
@@ -1,30 +1,20 @@
1
+ import { type Task } from "./task-registry.js";
1
2
  export declare function setServerPort(port: number): void;
2
- export interface TaskEvent {
3
- type: "log" | "progress" | "done" | "error";
4
- message: string;
5
- progress?: number;
6
- }
7
- interface Task {
8
- id: string;
9
- name: string;
10
- status: "running" | "done" | "error";
11
- events: TaskEvent[];
12
- listeners: Set<(event: TaskEvent) => void>;
13
- }
14
- export declare function getTask(id: string): Task | undefined;
15
- export interface TaskSnapshot {
16
- id: string;
17
- name: string;
18
- status: "running" | "done" | "error";
19
- events: TaskEvent[];
20
- }
21
- export declare function getTaskSnapshot(id: string): TaskSnapshot | undefined;
22
- /** Find running tasks, optionally filtered by name prefix */
23
- export declare function getRunningTasks(namePrefix?: string): Array<{
24
- id: string;
25
- name: string;
3
+ export { createTask, emitTask, getTask, getTaskSnapshot, getRunningTasks, subscribeTask, } from "./task-registry.js";
4
+ export type { Task, TaskEvent, TaskSnapshot } from "./task-registry.js";
5
+ /** Run a shell command as a spawned process, streaming output to a task */
6
+ export declare function spawnWithTask(task: Task, cmd: string, args: string[], options?: {
7
+ timeout?: number;
8
+ env?: Record<string, string>;
9
+ cwd?: string;
10
+ progressParser?: (line: string) => number | null;
11
+ }): Promise<{
12
+ ok: boolean;
13
+ output: string;
26
14
  }>;
27
- export declare function subscribeTask(id: string, listener: (event: TaskEvent) => void): (() => void) | null;
15
+ export declare function npmProgressParser(line: string): number | null;
16
+ export declare function dockerBuildProgressParser(line: string): number | null;
17
+ export declare function getDirSizeMB(dir: string): number;
28
18
  export interface DependencyStatus {
29
19
  name: string;
30
20
  installed: boolean;
@@ -50,10 +40,30 @@ export interface SetupStatus {
50
40
  id: string;
51
41
  name: string;
52
42
  }>;
43
+ /**
44
+ * Per-runtime install status, keyed by agentType. Populated by iterating
45
+ * over `listRegisteredAdapters()` and calling each adapter's
46
+ * `getInstallStatus()`. OpenClaw is **also** reported at the top level
47
+ * (`openclaw` field + `dockerImageReady`) for backward compat with older
48
+ * frontends — new frontend code should read `runtimes[agentType]`.
49
+ */
50
+ runtimes?: Record<string, {
51
+ installed: boolean;
52
+ imageReady: boolean;
53
+ version?: string;
54
+ digest?: string;
55
+ /**
56
+ * Mirror of `adapter.required`. The Setup wizard must gate overall
57
+ * completion on `required === true` runtimes only; optional runtimes
58
+ * (the default for third-party agents) stay advertised in the UI
59
+ * but do not block progress when absent.
60
+ */
61
+ required: boolean;
62
+ }>;
53
63
  }
54
64
  /** Enable cgroup memory in boot cmdline if not already enabled. Returns true if a reboot is needed. */
55
65
  export declare function ensureCgroupMemory(): boolean;
56
- export declare function getSetupStatus(): SetupStatus;
66
+ export declare function getSetupStatus(): Promise<SetupStatus>;
57
67
  export interface InstallResult {
58
68
  ok: boolean;
59
69
  message: string;
@@ -71,10 +81,42 @@ export declare function startNomad(): Promise<InstallResult>;
71
81
  export declare function stopNomad(): Promise<InstallResult>;
72
82
  export declare function installNomadSystemd(): InstallResult;
73
83
  export declare function installJishushellSystemd(port?: number): InstallResult;
84
+ /**
85
+ * Install OpenClaw runtime — thin dispatch wrapper.
86
+ *
87
+ * The heavy lifting lives in `OpenClawAdapter.installRuntime()` (§32.2.4).
88
+ * This wrapper is kept only for back-compat with the existing
89
+ * `routes/setup.ts` endpoint and the CLI installer.
90
+ */
74
91
  export declare function installOpenclaw(version?: string): Promise<InstallResult>;
75
- export declare function buildOpenclawDockerImage(tag?: string): Promise<InstallResult>;
76
- export declare function startBuildOpenclawDockerImage(tag?: string): InstallResult;
92
+ /**
93
+ * Capture the immutable digest of a locally-present image so HermesAdapter
94
+ * can pin via digest rather than the mutable tag. Returns undefined if the
95
+ * image has no RepoDigests (e.g. locally-built image) — caller may still
96
+ * proceed using the tag alone.
97
+ */
98
+ export declare function captureImageDigest(imageRef: string): string | undefined;
99
+ /**
100
+ * Install Hermes runtime — thin dispatch wrapper.
101
+ *
102
+ * Heavy lifting lives in `HermesAdapter.installRuntime()` (§32.2.4).
103
+ */
104
+ export declare function installHermes(): Promise<InstallResult>;
105
+ /**
106
+ * Non-blocking variant — returns a task id immediately. Implementation
107
+ * dispatches via `HermesAdapter.startInstallRuntime()`.
108
+ */
109
+ export declare function startInstallHermes(): InstallResult;
110
+ /** Helper for setup status — true when runtime catalog has hermes entry. */
111
+ export declare function isHermesInstalled(): boolean;
112
+ export type DockerInvocation = {
113
+ cmd: string;
114
+ argsPrefix: string[];
115
+ };
116
+ export declare function resolveDockerInvocation(): DockerInvocation;
117
+ /** Blocking: pull or build the OpenClaw docker image. */
77
118
  export declare function buildSlimOpenclawImage(tag?: string): Promise<InstallResult>;
119
+ /** Non-blocking: returns immediately with a task id for SSE polling. */
78
120
  export declare function startBuildSlimOpenclawImage(tag?: string): InstallResult;
79
121
  /** @deprecated Use buildSlimOpenclawImage instead */
80
122
  export declare function buildCustomOpenclawImage(tag?: string): Promise<InstallResult>;
@@ -92,4 +134,3 @@ export declare function runFullSetup(options?: {
92
134
  ok: boolean;
93
135
  steps: SetupProgress[];
94
136
  }>;
95
- export {};