dsh-plugin-local-infer 0.1.3 → 0.1.4

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 (250) hide show
  1. package/README.md +22 -4
  2. package/cordis.patch.yml +7 -0
  3. package/docs/zh/README.md +14 -2
  4. package/dsh/client.js +4195 -4522
  5. package/package.json +28 -11
  6. package/packages/core/lib/adapter.d.ts +133 -9
  7. package/packages/core/lib/adapter.js +74 -1
  8. package/packages/core/lib/config.d.ts +1 -1
  9. package/packages/core/lib/config.js +1 -1
  10. package/packages/core/lib/debug.d.ts +1 -1
  11. package/packages/core/lib/debug.js +1 -1
  12. package/packages/core/lib/defaults.d.ts +1 -1
  13. package/packages/core/lib/defaults.js +1 -1
  14. package/packages/core/lib/deps.d.ts +44 -17
  15. package/packages/core/lib/deps.js +24 -8
  16. package/packages/core/lib/estimator.d.ts +1 -1
  17. package/packages/core/lib/estimator.js +1 -1
  18. package/packages/core/lib/guideline.d.ts +1 -1
  19. package/packages/core/lib/guideline.js +1 -1
  20. package/packages/core/lib/hardware.d.ts +1 -1
  21. package/packages/core/lib/hardware.js +1 -1
  22. package/packages/core/lib/hf-cache.d.ts +70 -0
  23. package/packages/core/lib/hf-cache.js +83 -0
  24. package/packages/core/lib/index.d.ts +16 -9
  25. package/packages/core/lib/index.js +10 -6
  26. package/packages/core/lib/infer-cache.d.ts +39 -0
  27. package/packages/core/lib/infer-cache.js +53 -0
  28. package/packages/core/lib/launch-command.d.ts +8 -4
  29. package/packages/core/lib/launch-command.js +13 -6
  30. package/packages/core/lib/launch-record.d.ts +1 -1
  31. package/packages/core/lib/launch-record.js +1 -1
  32. package/packages/core/lib/logs.d.ts +8 -1
  33. package/packages/core/lib/logs.js +12 -4
  34. package/packages/core/lib/models.d.ts +120 -14
  35. package/packages/core/lib/models.js +209 -17
  36. package/packages/core/lib/parameter.d.ts +31 -3
  37. package/packages/core/lib/parameter.js +1 -1
  38. package/packages/core/lib/progress.d.ts +54 -0
  39. package/packages/core/lib/progress.js +120 -0
  40. package/packages/core/lib/registrar.d.ts +20 -9
  41. package/packages/core/lib/registrar.js +27 -7
  42. package/packages/core/lib/reserve.d.ts +11 -3
  43. package/packages/core/lib/reserve.js +6 -4
  44. package/packages/core/lib/status.d.ts +12 -6
  45. package/packages/core/lib/status.js +21 -10
  46. package/packages/core/lib/sudo.d.ts +80 -0
  47. package/packages/core/lib/sudo.js +78 -0
  48. package/packages/core/package.json +1 -1
  49. package/packages/orchestrator/lib/config.d.ts +63 -0
  50. package/packages/orchestrator/lib/config.js +111 -0
  51. package/packages/orchestrator/lib/index.d.ts +51 -0
  52. package/packages/orchestrator/lib/index.js +73 -0
  53. package/packages/orchestrator/lib/route.d.ts +60 -0
  54. package/packages/orchestrator/lib/route.js +159 -0
  55. package/packages/orchestrator/locale/en.json +6 -0
  56. package/packages/orchestrator/package.json +39 -0
  57. package/packages/orchestrator/prompt.md +87 -0
  58. package/packages/providers/lib/acquire.d.ts +92 -14
  59. package/packages/providers/lib/acquire.js +215 -37
  60. package/packages/providers/lib/adapters.d.ts +136 -12
  61. package/packages/providers/lib/adapters.js +597 -70
  62. package/packages/providers/lib/debug.d.ts +1 -1
  63. package/packages/providers/lib/debug.js +1 -1
  64. package/packages/providers/lib/deps.d.ts +27 -230
  65. package/packages/providers/lib/deps.js +61 -214
  66. package/packages/providers/lib/engines/basalt/basalt.d.ts +130 -0
  67. package/packages/providers/lib/engines/basalt/basalt.js +304 -0
  68. package/packages/providers/lib/engines/basalt/basaltAdapter.d.ts +85 -0
  69. package/packages/providers/lib/engines/basalt/basaltAdapter.js +439 -0
  70. package/packages/providers/lib/engines/basalt/basaltLinux.d.ts +23 -0
  71. package/packages/providers/lib/engines/basalt/basaltLinux.js +47 -0
  72. package/packages/providers/lib/engines/basalt/basaltMacOS.d.ts +17 -0
  73. package/packages/providers/lib/engines/basalt/basaltMacOS.js +19 -0
  74. package/packages/providers/lib/engines/basalt/basaltWindows.d.ts +24 -0
  75. package/packages/providers/lib/engines/basalt/basaltWindows.js +49 -0
  76. package/packages/providers/lib/engines/engineOs.d.ts +24 -0
  77. package/packages/providers/lib/engines/engineOs.js +17 -0
  78. package/packages/providers/lib/engines/{hyperqwen.d.ts → hyperqwen/hyperqwen.d.ts} +2 -2
  79. package/packages/providers/lib/engines/{hyperqwen.js → hyperqwen/hyperqwen.js} +14 -2
  80. package/packages/providers/lib/engines/{hyperqwenAdapter.d.ts → hyperqwen/hyperqwenAdapter.d.ts} +6 -6
  81. package/packages/providers/lib/engines/{hyperqwenAdapter.js → hyperqwen/hyperqwenAdapter.js} +24 -14
  82. package/packages/providers/lib/engines/hyperqwen/hyperqwenArch.d.ts +9 -0
  83. package/packages/providers/lib/engines/hyperqwen/hyperqwenArch.js +9 -0
  84. package/packages/providers/lib/engines/hyperqwen/hyperqwenDebian.d.ts +9 -0
  85. package/packages/providers/lib/engines/hyperqwen/hyperqwenDebian.js +9 -0
  86. package/packages/providers/lib/engines/hyperqwen/hyperqwenFedora.d.ts +9 -0
  87. package/packages/providers/lib/engines/hyperqwen/hyperqwenFedora.js +9 -0
  88. package/packages/providers/lib/engines/hyperqwen/hyperqwenLinux.d.ts +10 -0
  89. package/packages/providers/lib/engines/hyperqwen/hyperqwenLinux.js +14 -0
  90. package/packages/providers/lib/engines/hyperqwen/hyperqwenMacOS.d.ts +9 -0
  91. package/packages/providers/lib/engines/hyperqwen/hyperqwenMacOS.js +9 -0
  92. package/packages/providers/lib/engines/hyperqwen/hyperqwenWindows.d.ts +9 -0
  93. package/packages/providers/lib/engines/hyperqwen/hyperqwenWindows.js +9 -0
  94. package/packages/providers/lib/engines/{infernix.d.ts → infernix/infernix.d.ts} +7 -4
  95. package/packages/providers/lib/engines/{infernix.js → infernix/infernix.js} +52 -7
  96. package/packages/providers/lib/engines/{infernixAdapter.d.ts → infernix/infernixAdapter.d.ts} +5 -6
  97. package/packages/providers/lib/engines/{infernixAdapter.js → infernix/infernixAdapter.js} +75 -42
  98. package/packages/providers/lib/engines/infernix/infernixArch.d.ts +9 -0
  99. package/packages/providers/lib/engines/infernix/infernixArch.js +9 -0
  100. package/packages/providers/lib/engines/infernix/infernixDebian.d.ts +9 -0
  101. package/packages/providers/lib/engines/infernix/infernixDebian.js +9 -0
  102. package/packages/providers/lib/engines/infernix/infernixFedora.d.ts +9 -0
  103. package/packages/providers/lib/engines/infernix/infernixFedora.js +9 -0
  104. package/packages/providers/lib/engines/infernix/infernixLinux.d.ts +17 -0
  105. package/packages/providers/lib/engines/infernix/infernixLinux.js +35 -0
  106. package/packages/providers/lib/engines/infernix/infernixMacOS.d.ts +16 -0
  107. package/packages/providers/lib/engines/infernix/infernixMacOS.js +18 -0
  108. package/packages/providers/lib/engines/infernix/infernixWindows.d.ts +16 -0
  109. package/packages/providers/lib/engines/infernix/infernixWindows.js +34 -0
  110. package/packages/providers/lib/engines/{llamacpp.d.ts → llamacpp/llamacpp.d.ts} +2 -2
  111. package/packages/providers/lib/engines/{llamacpp.js → llamacpp/llamacpp.js} +12 -2
  112. package/packages/providers/lib/engines/{llamacppAdapter.d.ts → llamacpp/llamacppAdapter.d.ts} +5 -6
  113. package/packages/providers/lib/engines/{llamacppAdapter.js → llamacpp/llamacppAdapter.js} +87 -45
  114. package/packages/providers/lib/engines/llamacpp/llamacppArch.d.ts +9 -0
  115. package/packages/providers/lib/engines/llamacpp/llamacppArch.js +9 -0
  116. package/packages/providers/lib/engines/llamacpp/llamacppDebian.d.ts +9 -0
  117. package/packages/providers/lib/engines/llamacpp/llamacppDebian.js +9 -0
  118. package/packages/providers/lib/engines/llamacpp/llamacppFedora.d.ts +9 -0
  119. package/packages/providers/lib/engines/llamacpp/llamacppFedora.js +9 -0
  120. package/packages/providers/lib/engines/llamacpp/llamacppLinux.d.ts +17 -0
  121. package/packages/providers/lib/engines/llamacpp/llamacppLinux.js +28 -0
  122. package/packages/providers/lib/engines/llamacpp/llamacppMacOS.d.ts +15 -0
  123. package/packages/providers/lib/engines/llamacpp/llamacppMacOS.js +17 -0
  124. package/packages/providers/lib/engines/llamacpp/llamacppWindows.d.ts +15 -0
  125. package/packages/providers/lib/engines/llamacpp/llamacppWindows.js +26 -0
  126. package/packages/providers/lib/engines/{ninfer.d.ts → ninfer/ninfer.d.ts} +2 -2
  127. package/packages/providers/lib/engines/{ninfer.js → ninfer/ninfer.js} +24 -2
  128. package/packages/providers/lib/engines/{ninferAdapter.d.ts → ninfer/ninferAdapter.d.ts} +5 -6
  129. package/packages/providers/lib/engines/{ninferAdapter.js → ninfer/ninferAdapter.js} +123 -55
  130. package/packages/providers/lib/engines/ninfer/ninferArch.d.ts +9 -0
  131. package/packages/providers/lib/engines/ninfer/ninferArch.js +9 -0
  132. package/packages/providers/lib/engines/ninfer/ninferDebian.d.ts +9 -0
  133. package/packages/providers/lib/engines/ninfer/ninferDebian.js +9 -0
  134. package/packages/providers/lib/engines/ninfer/ninferFedora.d.ts +9 -0
  135. package/packages/providers/lib/engines/ninfer/ninferFedora.js +9 -0
  136. package/packages/providers/lib/engines/ninfer/ninferLinux.d.ts +17 -0
  137. package/packages/providers/lib/engines/ninfer/ninferLinux.js +37 -0
  138. package/packages/providers/lib/engines/ninfer/ninferMacOS.d.ts +15 -0
  139. package/packages/providers/lib/engines/ninfer/ninferMacOS.js +17 -0
  140. package/packages/providers/lib/engines/ninfer/ninferWindows.d.ts +29 -0
  141. package/packages/providers/lib/engines/ninfer/ninferWindows.js +59 -0
  142. package/packages/providers/lib/engines/strata/strata.d.ts +1 -0
  143. package/packages/providers/lib/engines/{strata.js → strata/strata.js} +70 -3
  144. package/packages/providers/lib/engines/{strataAdapter.d.ts → strata/strataAdapter.d.ts} +5 -6
  145. package/packages/providers/lib/engines/{strataAdapter.js → strata/strataAdapter.js} +147 -111
  146. package/packages/providers/lib/engines/strata/strataArch.d.ts +9 -0
  147. package/packages/providers/lib/engines/strata/strataArch.js +9 -0
  148. package/packages/providers/lib/engines/strata/strataDebian.d.ts +9 -0
  149. package/packages/providers/lib/engines/strata/strataDebian.js +9 -0
  150. package/packages/providers/lib/engines/strata/strataFedora.d.ts +9 -0
  151. package/packages/providers/lib/engines/strata/strataFedora.js +9 -0
  152. package/packages/providers/lib/engines/strata/strataLinux.d.ts +21 -0
  153. package/packages/providers/lib/engines/strata/strataLinux.js +30 -0
  154. package/packages/providers/lib/engines/strata/strataMacOS.d.ts +16 -0
  155. package/packages/providers/lib/engines/strata/strataMacOS.js +17 -0
  156. package/packages/providers/lib/engines/strata/strataWindows.d.ts +27 -0
  157. package/packages/providers/lib/engines/strata/strataWindows.js +37 -0
  158. package/packages/providers/lib/engines.d.ts +7 -5
  159. package/packages/providers/lib/engines.js +21 -10
  160. package/packages/providers/lib/guidelines.d.ts +5 -4
  161. package/packages/providers/lib/guidelines.js +18 -5
  162. package/packages/providers/lib/index.d.ts +33 -29
  163. package/packages/providers/lib/index.js +45 -33
  164. package/packages/providers/lib/model-defaults.d.ts +5 -1
  165. package/packages/providers/lib/model-defaults.js +25 -1
  166. package/packages/providers/lib/platform.d.ts +8 -5
  167. package/packages/providers/lib/platform.js +23 -9
  168. package/packages/providers/lib/presets.d.ts +6 -4
  169. package/packages/providers/lib/presets.js +53 -5
  170. package/packages/providers/lib/systemDeps.d.ts +313 -0
  171. package/packages/providers/lib/systemDeps.js +284 -0
  172. package/packages/providers/lib/vram.d.ts +34 -8
  173. package/packages/providers/lib/vram.js +81 -8
  174. package/packages/providers/package.json +2 -2
  175. package/packages/service/lib/index.d.ts +176 -21
  176. package/packages/service/lib/index.js +589 -86
  177. package/packages/service/lib/launch-target.d.ts +19 -0
  178. package/packages/service/lib/launch-target.js +28 -0
  179. package/packages/service/lib/run-logs.d.ts +72 -0
  180. package/packages/service/lib/run-logs.js +125 -0
  181. package/packages/service/lib/types.d.ts +163 -6
  182. package/packages/service/lib/types.js +1 -1
  183. package/packages/service/package.json +2 -2
  184. package/packages/tool/lib/index.d.ts +1 -1
  185. package/packages/tool/lib/index.js +1 -1
  186. package/packages/tool/package.json +2 -2
  187. package/packages/ui/lib/config.d.ts +12 -2
  188. package/packages/ui/lib/config.js +18 -2
  189. package/packages/ui/lib/deps.d.ts +1 -1
  190. package/packages/ui/lib/deps.js +1 -1
  191. package/packages/ui/lib/form.d.ts +1 -1
  192. package/packages/ui/lib/form.js +1 -1
  193. package/packages/ui/lib/index.d.ts +7 -1
  194. package/packages/ui/lib/index.js +12 -2
  195. package/packages/ui/lib/meter.d.ts +1 -1
  196. package/packages/ui/lib/meter.js +1 -1
  197. package/packages/ui/lib/ops/engine.d.ts +142 -34
  198. package/packages/ui/lib/ops/engine.js +469 -265
  199. package/packages/ui/lib/ops/get-steps.d.ts +98 -0
  200. package/packages/ui/lib/ops/get-steps.js +359 -0
  201. package/packages/ui/lib/ops/hf.d.ts +26 -11
  202. package/packages/ui/lib/ops/hf.js +115 -25
  203. package/packages/ui/lib/ops/logs.d.ts +70 -15
  204. package/packages/ui/lib/ops/logs.js +96 -35
  205. package/packages/ui/lib/ops/model.d.ts +2 -10
  206. package/packages/ui/lib/ops/model.js +9 -16
  207. package/packages/ui/lib/request.d.ts +1 -1
  208. package/packages/ui/lib/request.js +1 -1
  209. package/packages/ui/lib/route.d.ts +22 -6
  210. package/packages/ui/lib/route.js +32 -9
  211. package/packages/ui/lib/routes/chat-template.d.ts +1 -14
  212. package/packages/ui/lib/routes/chat-template.js +1 -37
  213. package/packages/ui/lib/routes/deps.d.ts +1 -16
  214. package/packages/ui/lib/routes/deps.js +1 -27
  215. package/packages/ui/lib/routes/download.d.ts +1 -16
  216. package/packages/ui/lib/routes/download.js +1 -48
  217. package/packages/ui/lib/routes/get.d.ts +1 -18
  218. package/packages/ui/lib/routes/get.js +66 -17
  219. package/packages/ui/lib/routes/install.d.ts +1 -1
  220. package/packages/ui/lib/routes/install.js +1 -1
  221. package/packages/ui/lib/routes/launch.d.ts +13 -7
  222. package/packages/ui/lib/routes/launch.js +33 -9
  223. package/packages/ui/lib/routes/logs.d.ts +57 -0
  224. package/packages/ui/lib/routes/logs.js +117 -0
  225. package/packages/ui/lib/routes/provider-delete.d.ts +1 -1
  226. package/packages/ui/lib/routes/provider-delete.js +1 -1
  227. package/packages/ui/lib/routes/register.d.ts +1 -1
  228. package/packages/ui/lib/routes/register.js +1 -1
  229. package/packages/ui/lib/routes/save.d.ts +1 -1
  230. package/packages/ui/lib/routes/save.js +22 -2
  231. package/packages/ui/lib/routes/stop.d.ts +7 -4
  232. package/packages/ui/lib/routes/stop.js +7 -4
  233. package/packages/ui/lib/routes/stream.d.ts +40 -0
  234. package/packages/ui/lib/routes/stream.js +68 -0
  235. package/packages/ui/lib/routes/summary.d.ts +1 -1
  236. package/packages/ui/lib/routes/summary.js +1 -1
  237. package/packages/ui/lib/routes/unregister.d.ts +1 -1
  238. package/packages/ui/lib/routes/unregister.js +1 -1
  239. package/packages/ui/lib/viewmodels/deps.d.ts +1 -31
  240. package/packages/ui/lib/viewmodels/deps.js +1 -89
  241. package/packages/ui/lib/viewmodels/depsHelpers.d.ts +1 -28
  242. package/packages/ui/lib/viewmodels/depsHelpers.js +72 -11
  243. package/packages/ui/lib/viewmodels/summary.d.ts +7 -2
  244. package/packages/ui/lib/viewmodels/summary.js +55 -35
  245. package/packages/ui/lib/viewmodels/summaryHelpers.d.ts +1 -1
  246. package/packages/ui/lib/viewmodels/summaryHelpers.js +1 -1
  247. package/packages/ui/lib/warnings.d.ts +1 -1
  248. package/packages/ui/lib/warnings.js +1 -1
  249. package/packages/ui/package.json +4 -4
  250. package/packages/providers/lib/engines/strata.d.ts +0 -53
@@ -8,43 +8,82 @@
8
8
  * local changes aborts, because a rebase would eat the user's work.
9
9
  * @module dsh-plugin-local-infer/providers/acquire
10
10
  */
11
+ import { commandLogLine } from '../../core/lib/index.js';
12
+ import { NINFER_LINUX } from "./engines/ninfer/ninferLinux.js";
13
+ import { NINFER_MACOS } from "./engines/ninfer/ninferMacOS.js";
14
+ import { NINFER_WINDOWS } from "./engines/ninfer/ninferWindows.js";
15
+ import { INFERNIX_LINUX } from "./engines/infernix/infernixLinux.js";
16
+ import { INFERNIX_MACOS } from "./engines/infernix/infernixMacOS.js";
17
+ import { INFERNIX_WINDOWS } from "./engines/infernix/infernixWindows.js";
18
+ import { LLAMACPP_LINUX } from "./engines/llamacpp/llamacppLinux.js";
19
+ import { LLAMACPP_MACOS } from "./engines/llamacpp/llamacppMacOS.js";
20
+ import { LLAMACPP_WINDOWS } from "./engines/llamacpp/llamacppWindows.js";
21
+ import { HYPERQWEN_LINUX } from "./engines/hyperqwen/hyperqwenLinux.js";
22
+ import { HYPERQWEN_MACOS } from "./engines/hyperqwen/hyperqwenMacOS.js";
23
+ import { HYPERQWEN_WINDOWS } from "./engines/hyperqwen/hyperqwenWindows.js";
24
+ import { STRATA_LINUX } from "./engines/strata/strataLinux.js";
25
+ import { STRATA_MACOS } from "./engines/strata/strataMacOS.js";
26
+ import { STRATA_WINDOWS } from "./engines/strata/strataWindows.js";
27
+ import { BASALT_LINUX } from "./engines/basalt/basaltLinux.js";
28
+ import { BASALT_MACOS } from "./engines/basalt/basaltMacOS.js";
29
+ import { BASALT_WINDOWS } from "./engines/basalt/basaltWindows.js";
11
30
  /**
12
31
  * The remote name a user-provided fork is added under, so the checkout's own
13
32
  * origin (the upstream it was cloned from) survives the fork override.
14
33
  */
15
34
  export const FORK_REMOTE = 'dsh-fork';
35
+ /**
36
+ * The per-engine, per-OS build profiles, keyed by engine id then OS. The
37
+ * distro-specific Linux profiles (Arch, Debian, Fedora) reuse the shared Linux
38
+ * profile, so they are not separate keys here. A host OS with no dedicated
39
+ * profile (a Windows host for an engine that carries no Windows route) reads
40
+ * the shared Linux profile.
41
+ */
42
+ const ENGINE_OS_PROFILES = {
43
+ ninfer: { linux: NINFER_LINUX, macos: NINFER_MACOS, windows: NINFER_WINDOWS },
44
+ hyperqwen: { linux: HYPERQWEN_LINUX, macos: HYPERQWEN_MACOS, windows: HYPERQWEN_WINDOWS },
45
+ llamacpp: { linux: LLAMACPP_LINUX, macos: LLAMACPP_MACOS, windows: LLAMACPP_WINDOWS },
46
+ infernix: { linux: INFERNIX_LINUX, macos: INFERNIX_MACOS, windows: INFERNIX_WINDOWS },
47
+ strata: { linux: STRATA_LINUX, macos: STRATA_MACOS, windows: STRATA_WINDOWS },
48
+ basalt: { linux: BASALT_LINUX, macos: BASALT_MACOS, windows: BASALT_WINDOWS },
49
+ };
16
50
  /**
17
51
  * The per-engine git sources, keyed by engine id. NInfer and Infernix build
18
52
  * through cmake (Infernix through its own preset); llama.cpp builds through
19
53
  * the same cmake shape as NInfer; Hyper-Qwen is the compose-driven vLLM
20
54
  * engine, so it carries no local build steps (the compose up pulls the
21
55
  * image); Strata builds through its own setup.sh (the README's
22
- * Build-from-source route), which the source-build mode runs in the checkout.
56
+ * Build-from-source route), which the source-build mode runs in the checkout;
57
+ * Basalt builds through its own CMake route (the Ninja/MSVC variant on
58
+ * Windows). The build steps are read from the per-engine OS profiles, so a
59
+ * build command has one home (the OS-specific files under engines/).
23
60
  */
24
61
  export const ENGINE_SOURCES = {
25
62
  ninfer: {
26
63
  repo: 'https://github.com/Neroued/ninfer',
27
64
  branch: 'master',
28
- buildSteps: [
29
- 'cmake -S {dir} -B {dir}/build -G Ninja -DCMAKE_BUILD_TYPE=Release && cmake --build {dir}/build -j',
30
- ],
65
+ buildSteps: NINFER_LINUX.buildSteps,
66
+ // The Windows route is the ninfer-all fork's vcpkg build: the manifest
67
+ // pulls the dev libraries, then the engine's own build-native.bat
68
+ // configures and builds. The step cds into the checkout first (the {dir}
69
+ // placeholder), because vcpkg install and the relative script path both
70
+ // resolve against the checkout root.
71
+ windowsBuildSteps: NINFER_WINDOWS.buildSteps,
31
72
  },
32
73
  hyperqwen: {
33
74
  repo: 'https://github.com/vllm-project/vllm',
34
75
  branch: 'main',
35
- buildSteps: [],
76
+ buildSteps: HYPERQWEN_LINUX.buildSteps,
36
77
  },
37
78
  llamacpp: {
38
79
  repo: 'https://github.com/ggml-org/llama.cpp',
39
80
  branch: 'master',
40
- buildSteps: [
41
- 'cmake -S {dir} -B {dir}/build -G Ninja -DCMAKE_BUILD_TYPE=Release && cmake --build {dir}/build -j',
42
- ],
81
+ buildSteps: LLAMACPP_LINUX.buildSteps,
43
82
  },
44
83
  infernix: {
45
84
  repo: 'https://github.com/Wallawalla47/Infernix',
46
85
  branch: 'main',
47
- buildSteps: ['cd {dir} && cmake --preset release && cmake --build build -j'],
86
+ buildSteps: INFERNIX_LINUX.buildSteps,
48
87
  },
49
88
  strata: {
50
89
  // The README's Build-from-source route: git clone the repo, then run the
@@ -53,9 +92,50 @@ export const ENGINE_SOURCES = {
53
92
  // without starting the server, which the adapter's launch step then does.
54
93
  repo: 'https://github.com/Niko1221/Strata',
55
94
  branch: 'main',
56
- buildSteps: ['cd {dir} && ./setup.sh --yes --no-start'],
95
+ buildSteps: STRATA_LINUX.buildSteps,
96
+ },
97
+ basalt: {
98
+ // The engine's own CMake route: configure a Release build into the
99
+ // `build` directory, then compile it. The Windows variant adds the Ninja
100
+ // generator and runs in the MSVC developer shell (vcvars64.bat).
101
+ repo: 'https://github.com/jesdga95/basalt',
102
+ branch: 'main',
103
+ buildSteps: BASALT_LINUX.buildSteps,
104
+ windowsBuildSteps: BASALT_WINDOWS.buildSteps,
57
105
  },
58
106
  };
107
+ /**
108
+ * engineOsProfile reads the registered build profile for an engine id on an OS,
109
+ * or undefined when none is registered. A host OS with no dedicated profile
110
+ * (a Windows host for an engine that carries no Windows route) reads the
111
+ * shared Linux profile.
112
+ */
113
+ export function engineOsProfile(engineId, os = 'linux') {
114
+ const profiles = ENGINE_OS_PROFILES[engineId];
115
+ if (profiles === undefined)
116
+ return undefined;
117
+ return profiles[os] ?? profiles.linux;
118
+ }
119
+ /**
120
+ * engineBuildDir reads the directory, relative to the checkout, where an
121
+ * engine's build leaves its binary on an OS, so the binary symlink step reads
122
+ * the right tree. A Windows host reads the engine's Windows build tree (the
123
+ * vcpkg route for NInfer writes into build-windows\apps\Release); every other
124
+ * host reads the shared Linux build directory. An engine that installs its
125
+ * binary to the path (Strata) carries no build directory, so it reads as
126
+ * `build`, the shared default.
127
+ */
128
+ export function engineBuildDir(engineId, os = 'linux') {
129
+ return engineOsProfile(engineId, os)?.buildDir ?? 'build';
130
+ }
131
+ /**
132
+ * engineBinary reads the engine binary name on an OS (the .exe on Windows), so
133
+ * the adapters and the symlink step share one source. An engine with no local
134
+ * binary (the compose engines) reads as undefined.
135
+ */
136
+ export function engineBinary(engineId, os = 'linux') {
137
+ return engineOsProfile(engineId, os)?.binary;
138
+ }
59
139
  /**
60
140
  * engineSource reads the registered acquisition data for an engine id, or
61
141
  * undefined when none is registered.
@@ -64,17 +144,23 @@ export function engineSource(engineId) {
64
144
  return ENGINE_SOURCES[engineId];
65
145
  }
66
146
  /**
67
- * engineBuildSteps reads the build steps an engine runs in its checkout, so
68
- * the adapter's deploy step and the Get build step share one list.
147
+ * engineBuildSteps reads the build steps an engine runs in its checkout for an
148
+ * OS, so the adapter's deploy step and the Get build step share one list. The
149
+ * steps come from the engine's OS profile: a Windows host reads the engine's
150
+ * Windows profile (the vcpkg route for NInfer), and a host OS with no
151
+ * dedicated profile reads the shared Linux profile.
69
152
  */
70
- export function engineBuildSteps(engineId) {
71
- return ENGINE_SOURCES[engineId]?.buildSteps ?? [];
153
+ export function engineBuildSteps(engineId, os = 'linux') {
154
+ return engineOsProfile(engineId, os)?.buildSteps ?? [];
72
155
  }
73
156
  /**
74
157
  * runLogged runs one shell command through the host's streaming surface when
75
158
  * it has one (echoing the command and streaming its output through log), and
76
159
  * through plain run otherwise. The streamed copy is also collected, so a
77
- * caller can price the command's stdout (the dirty-check, for one).
160
+ * caller can price the command's stdout (the dirty-check, for one). A
161
+ * `shell` option (the engine OS profile's shell) runs the command in that
162
+ * shell instead of the host's default. A `needsSudo` option declares the
163
+ * command runs sudo, so the host applies the sudo-prompt rule to it.
78
164
  */
79
165
  async function runLogged(host, command, log, options) {
80
166
  let output = '';
@@ -83,13 +169,20 @@ async function runLogged(host, command, log, options) {
83
169
  log(chunk);
84
170
  };
85
171
  if (options?.echo !== false) {
86
- log(`$ ${command}\n`);
172
+ log(commandLogLine(command));
87
173
  }
174
+ // exactOptionalPropertyTypes: carry only the options the caller set, so an
175
+ // absent shell or sudo declaration never passes `{ shell: undefined }`
176
+ // through.
177
+ const runOptions = {
178
+ ...(options?.shell === undefined ? {} : { shell: options.shell }),
179
+ ...(options?.needsSudo === undefined ? {} : { needsSudo: options.needsSudo }),
180
+ };
88
181
  if (host.runStream !== undefined) {
89
- const outcome = await host.runStream(command, collect);
182
+ const outcome = await host.runStream(command, collect, runOptions);
90
183
  return { ...outcome, output };
91
184
  }
92
- const outcome = await host.run(command);
185
+ const outcome = await host.run(command, runOptions);
93
186
  return { ...outcome, output };
94
187
  }
95
188
  /**
@@ -98,7 +191,11 @@ async function runLogged(host, command, log, options) {
98
191
  * no fork is provided). An existing checkout with local changes aborts, so
99
192
  * the user's work is never rebased away; a clean checkout fetches the listed
100
193
  * fork (added as the named fork remote when provided, origin when not) and
101
- * rebases onto its branch. Every command echoes into log as it runs.
194
+ * rebases onto its branch. Every command echoes into log as it runs. The
195
+ * result's `cloned` flag names the path taken: set on a fresh clone (the
196
+ * checkout was absent), absent on the present-checkout path, so a caller
197
+ * prices a failure's fatality from the flag instead of re-probing the
198
+ * checkout.
102
199
  */
103
200
  export async function syncEngineRepo(host, request, log) {
104
201
  const source = engineSource(request.engineId);
@@ -110,7 +207,12 @@ export async function syncEngineRepo(host, request, log) {
110
207
  }
111
208
  const directory = request.directory;
112
209
  const fork = request.fork !== undefined && request.fork.trim() !== '' ? request.fork : undefined;
113
- const present = await host.run(`[ -d ${directory}/.git ]`);
210
+ // The presence probe is a git query, not a POSIX [ -d ] test: the shell the
211
+ // host runs is cmd on Windows, where [ is not a command and the test reads
212
+ // as a missing checkout every time. rev-parse exits 0 only inside a work
213
+ // tree, so a real checkout reads as present and an absent or non-git
214
+ // directory reads as missing, on every platform.
215
+ const present = await host.run(`git -C ${directory} rev-parse --is-inside-work-tree`);
114
216
  if (present.ok) {
115
217
  const status = await runLogged(host, `git -C ${directory} status --short`, log);
116
218
  if (!status.ok) {
@@ -149,9 +251,9 @@ export async function syncEngineRepo(host, request, log) {
149
251
  }
150
252
  const clone = await runLogged(host, `git clone ${fork ?? source.repo} ${directory}`, log);
151
253
  if (!clone.ok) {
152
- return { ok: false, detail: `git clone failed: ${clone.detail ?? 'unknown'}` };
254
+ return { ok: false, cloned: true, detail: `git clone failed: ${clone.detail ?? 'unknown'}` };
153
255
  }
154
- return { ok: true };
256
+ return { ok: true, cloned: true };
155
257
  }
156
258
  /**
157
259
  * syncAndRebuildEngine brings the engine checkout to the listed source and
@@ -185,7 +287,12 @@ export async function syncAndRebuildEngine(host, request, log) {
185
287
  chunks.push(chunk);
186
288
  log(chunk);
187
289
  };
188
- const present = await host.run(`[ -d ${directory}/.git ]`);
290
+ // The presence probe is a git query, not a POSIX [ -d ] test: the shell the
291
+ // host runs is cmd on Windows, where [ is not a command and the test reads
292
+ // as a missing checkout every time. rev-parse exits 0 only inside a work
293
+ // tree, so a real checkout reads as present and an absent or non-git
294
+ // directory reads as missing, on every platform.
295
+ const present = await host.run(`git -C ${directory} rev-parse --is-inside-work-tree`);
189
296
  let rebuilt = false;
190
297
  if (!present.ok) {
191
298
  // A missing checkout is a fresh clone of the fork (or the upstream repo),
@@ -205,10 +312,13 @@ export async function syncAndRebuildEngine(host, request, log) {
205
312
  else {
206
313
  if (fork !== undefined) {
207
314
  // Add the fork under its own remote name; a re-launch updates the URL in
208
- // place so an edited fork field takes effect on the next run.
209
- const add = await runLogged(host, `git -C ${directory} remote add ${FORK_REMOTE} ${fork}`, emit, { echo: false });
315
+ // place so an edited fork field takes effect on the next run. Both
316
+ // remote commands mutate the checkout's git config, so their `$ command`
317
+ // lines lead their output (the TASK-007 exec-audit rule): a re-launch
318
+ // reads the expected add failure and the set-url that follows.
319
+ const add = await runLogged(host, `git -C ${directory} remote add ${FORK_REMOTE} ${fork}`, emit);
210
320
  if (!add.ok) {
211
- await runLogged(host, `git -C ${directory} remote set-url ${FORK_REMOTE} ${fork}`, emit, { echo: false });
321
+ await runLogged(host, `git -C ${directory} remote set-url ${FORK_REMOTE} ${fork}`, emit);
212
322
  }
213
323
  }
214
324
  const status = await runLogged(host, `git -C ${directory} status --short`, emit, { echo: false });
@@ -225,7 +335,10 @@ export async function syncAndRebuildEngine(host, request, log) {
225
335
  return { ok: true, rebuilt: false, logs: chunks.join('') };
226
336
  }
227
337
  // The fetch is best-effort: an offline host prices the checkout it has.
228
- await runLogged(host, `git -C ${directory} fetch ${remote} || true`, emit, { echo: false });
338
+ // It mutates the checkout's objects and refs, so the `$ command` line
339
+ // leads its output (the TASK-007 exec-audit rule); the `|| true` keeps a
340
+ // failed fetch silent so the behind-check prices what is already present.
341
+ await runLogged(host, `git -C ${directory} fetch ${remote} || true`, emit);
229
342
  // Price whether the current branch is behind the remote branch. A fetch
230
343
  // that failed (offline) or a missing remote branch reads as not-behind, so
231
344
  // the checkout builds as-is.
@@ -277,13 +390,17 @@ export async function syncAndRebuildEngine(host, request, log) {
277
390
  : undefined;
278
391
  const steps = buildCommands !== undefined
279
392
  ? [`cd ${directory} && ${buildCommands}`]
280
- : source.buildSteps;
393
+ : engineBuildSteps(request.engineId, request.os ?? 'linux');
394
+ // The engine OS profile's shell (the Windows vcpkg route's pwsh.exe)
395
+ // runs the build steps; absent keeps the host's default shell.
396
+ const shell = engineOsProfile(request.engineId, request.os ?? 'linux')?.shell;
397
+ const stepOptions = shell !== undefined ? { shell } : undefined;
281
398
  // Report the build phase before the first step runs, so the card's button
282
399
  // reads "Building..." while the build is in flight, not after it completes.
283
400
  request.onBuildStart?.();
284
401
  for (const step of steps) {
285
402
  const command = step.replaceAll('{dir}', directory);
286
- const outcome = await runLogged(host, command, emit);
403
+ const outcome = await runLogged(host, command, emit, stepOptions);
287
404
  if (!outcome.ok) {
288
405
  return {
289
406
  ok: false,
@@ -295,13 +412,24 @@ export async function syncAndRebuildEngine(host, request, log) {
295
412
  }
296
413
  // A rebuild that did not install the binary (no make install) leaves it
297
414
  // out of the path. Check, and add a symlink when the trust gate allows.
298
- const binary = request.binary;
415
+ // The symlink name is the profile's bare binary (the .exe on Windows), not
416
+ // the launch path: a Windows launch path carries its build tree
417
+ // (build-windows\apps\Release\ninfer-serve.exe), so linking it under
418
+ // buildDir would double the tree.
419
+ const binary = engineBinary(request.engineId, request.os ?? 'linux');
299
420
  if (binary !== undefined) {
300
421
  const which = await host.run(`command -v ${binary}`);
301
422
  if (!which.ok) {
302
- const link = `sudo ln -sf ${directory}/build/${binary} /usr/local/bin/${binary}`;
423
+ // The build directory is OS-specific: a Windows host reads the
424
+ // engine's Windows build tree (the vcpkg route for NInfer writes into
425
+ // build-windows\apps\Release), every other host the shared Linux build
426
+ // directory.
427
+ const buildDir = engineBuildDir(request.engineId, request.os ?? 'linux');
428
+ const link = `sudo ln -sf ${directory}/${buildDir}/${binary} /usr/local/bin/${binary}`;
303
429
  if (request.allowRunDeps === true) {
304
- const result = await runLogged(host, link, emit);
430
+ // The hand-written sudo line declares its need at this call site;
431
+ // the host never parses the command text to find out.
432
+ const result = await runLogged(host, link, emit, { needsSudo: true });
305
433
  if (!result.ok) {
306
434
  emit(`!! ${link} failed: ${result.detail ?? 'unknown'}\n`);
307
435
  }
@@ -314,33 +442,83 @@ export async function syncAndRebuildEngine(host, request, log) {
314
442
  }
315
443
  return { ok: true, rebuilt, logs: chunks.join('') };
316
444
  }
445
+ /**
446
+ * syncEngineForDeploy runs the deploy step's git sync (the shared
447
+ * syncAndRebuildEngine) with the option shape every adapter's deploy step
448
+ * assembles: the platform entry's fork and build-command override, the
449
+ * Play/Run trust gate, the plan's host OS (the Windows vcpkg route when the
450
+ * user carries no build-command override), and the progress sink the card's
451
+ * button reads (the git sync reports "Downloading...", the build step
452
+ * reports "Building..." the moment it starts). The captured build output is
453
+ * returned as buildLogs, so a caller threads it to the card's Logs section
454
+ * without re-running the steps.
455
+ */
456
+ export async function syncEngineForDeploy(host, request) {
457
+ // The git sync is the checkout download: the card's button reads
458
+ // "Downloading..." for it, not "Building...".
459
+ request.onProgress?.('download');
460
+ const sync = await syncAndRebuildEngine(host, {
461
+ engineId: request.engineId,
462
+ directory: request.directory,
463
+ ...(request.platform?.engineFork !== undefined
464
+ ? { fork: request.platform.engineFork }
465
+ : {}),
466
+ ...(request.options?.allowRunDeps !== undefined
467
+ ? { allowRunDeps: request.options.allowRunDeps }
468
+ : {}),
469
+ ...(request.platform?.buildCommands !== undefined
470
+ ? { buildCommands: request.platform.buildCommands }
471
+ : {}),
472
+ ...(request.os !== undefined ? { os: request.os } : {}),
473
+ // Report the build phase the moment the build steps start, so the
474
+ // card's button reads "Building..." while the build is in flight.
475
+ onBuildStart: () => request.onProgress?.('build'),
476
+ }, () => { });
477
+ // The build output reads as a fresh Logs section: a "Building..."
478
+ // separator leads the rebuild decision and output, the same line the card
479
+ // writes when the build step event lands.
480
+ let buildLogs = sync.logs;
481
+ if (sync.rebuilt && buildLogs !== '') {
482
+ buildLogs = `--- Building...\n${buildLogs}`;
483
+ }
484
+ return {
485
+ ok: sync.ok,
486
+ ...(sync.detail !== undefined ? { detail: sync.detail } : {}),
487
+ buildLogs,
488
+ };
489
+ }
317
490
  /**
318
491
  * buildEngineRepo runs the engine's build steps in the checkout, streaming
319
492
  * each step's output through log. An engine with no build steps (the compose
320
493
  * engines) passes through with a note; a failing step stops the build with
321
494
  * the step's detail.
322
495
  */
323
- export async function buildEngineRepo(host, engineId, directory, log, buildCommands) {
496
+ export async function buildEngineRepo(host, engineId, directory, log, buildCommands, os = 'linux') {
324
497
  const source = engineSource(engineId);
325
498
  if (source === undefined) {
326
499
  return { ok: false, detail: `no engine source is registered for "${engineId}"` };
327
500
  }
328
501
  // The user's local build command (the card's Build commands field) overrides
329
502
  // the engine's default build steps: it runs in the checkout, so it is wrapped
330
- // with a cd into the directory. Absent falls back to the engine's steps.
503
+ // with a cd into the directory. Absent falls back to the engine's steps for
504
+ // the host OS (the Windows vcpkg route on a Windows host).
331
505
  const commands = buildCommands !== undefined && buildCommands.trim() !== '' ? buildCommands : undefined;
332
- const steps = commands !== undefined ? [`cd ${directory} && ${commands}`] : source.buildSteps;
506
+ const steps = commands !== undefined ? [`cd ${directory} && ${commands}`] : engineBuildSteps(engineId, os);
333
507
  if (steps.length === 0) {
334
508
  log(`no local build steps for ${engineId}\n`);
335
509
  return { ok: true };
336
510
  }
511
+ // The engine OS profile's shell (the Windows vcpkg route's pwsh.exe)
512
+ // runs the build steps; absent keeps the host's default shell.
513
+ const shell = engineOsProfile(engineId, os)?.shell;
514
+ const stepOptions = shell !== undefined ? { shell } : undefined;
337
515
  for (const step of steps) {
338
516
  const command = step.replaceAll('{dir}', directory);
339
- const outcome = await runLogged(host, command, log);
517
+ const outcome = await runLogged(host, command, log, stepOptions);
340
518
  if (!outcome.ok) {
341
519
  return { ok: false, detail: `build failed: ${outcome.detail ?? 'unknown'}` };
342
520
  }
343
521
  }
344
522
  return { ok: true };
345
523
  }
346
- //# sourceMappingURL=acquire.js.map
524
+ //# sourceMappingURL=acquire.js.map
@@ -1,18 +1,31 @@
1
1
  /**
2
2
  * The shared engine-adapter helpers: the spec-to-argv and spec-to-env
3
- * translators the concrete adapters (the `engines/*Adapter.ts` files) compose
3
+ * translators the concrete adapters (the `engines/<engine>/<engine>Adapter.ts`
4
+ * files) compose
4
5
  * into a `LaunchPlan`, the card's Custom Arguments translators, the
5
6
  * `LifecycleHost` the deploy, health-check, and stop steps drive, and the
6
7
  * health poll. The node implementation (`nodeLifecycleHost`) is what the
7
8
  * service wires in on a live host.
8
9
  * @module dsh-plugin-local-infer/providers/adapters
9
10
  */
10
- import type { Config, DebugLogger, HealthCheckOptions, HealthResult, LaunchPlan, LifecycleHost, ParameterSpec, ProcessHandle } from '../../core/lib/index.js';
11
+ import type { CommandLogger, CommandOutcome, Config, DebugLogger, HealthCheckOptions, HealthResult, LaunchPlan, LifecycleHost, ParameterDeploy, ParameterSpec, ProcessHandle, RunOptions } from '../../core/lib/index.js';
12
+ /**
13
+ * deployTargets normalizes a spec's `deploy` declaration into a target list: a
14
+ * single target wraps in a one-element list, a list passes through, and an
15
+ * absent `deploy` reads as an empty list (the un-migrated fallback). The
16
+ * spec-to-spelling helpers key off this list, so a multi-target spec
17
+ * (cli + env, the Strata shared specs) contributes to every matching helper.
18
+ */
19
+ export declare function deployTargets(spec: ParameterSpec): readonly ParameterDeploy[];
11
20
  /**
12
21
  * flagsFromSpecs turns a spec surface and a config into the CLI flag list: each
13
22
  * spec's `toArgv` runs over the config value (falling back to the spec
14
23
  * default), and empty results are skipped. A spec with no `toArgv` contributes
15
- * nothing.
24
+ * nothing. A declared `deploy` target gates the spelling: a `cli` target in the
25
+ * spec's target list (or no target, the un-migrated fallback that reads the
26
+ * `toArgv` presence) spells CLI flags, so a spec that deploys only to the env
27
+ * or a config file contributes no flag even when it carries a `toArgv`
28
+ * spelling.
16
29
  */
17
30
  export declare function flagsFromSpecs(specs: readonly ParameterSpec[], config: Config): string[];
18
31
  /**
@@ -35,20 +48,72 @@ export declare function customArgFlags(config: Config): string[];
35
48
  export declare function customArgEnv(config: Config): Record<string, string>;
36
49
  /**
37
50
  * envFromSpecs turns a spec surface and a config into the environment map: each
38
- * spec's `toEnv` runs over the config value (falling back to the spec
39
- * default). A spec with no `toEnv` contributes nothing.
51
+ * spec's `toEnv` runs over the config value (falling back to the spec default).
52
+ * A spec with no `toEnv` contributes nothing. A declared `deploy` target gates
53
+ * the spelling: an `env` target in the spec's target list (or no target, the
54
+ * un-migrated fallback that reads the `toEnv` presence) spells env vars, so a
55
+ * spec that deploys only to the CLI or a config file contributes no var even
56
+ * when it carries a `toEnv` spelling.
40
57
  */
41
58
  export declare function envFromSpecs(specs: readonly ParameterSpec[], config: Config): Record<string, string>;
59
+ /**
60
+ * ConfigFileFormat is the on-disk format a `config` deploy target renders to:
61
+ * JSON (the built-in stringify), a flat `.env` file, or YAML.
62
+ */
63
+ export type ConfigFileFormat = 'json' | 'yaml' | 'env';
64
+ /**
65
+ * configFileFromSpecs turns a spec surface and a config into the content of the
66
+ * config file the deploy step writes: every spec whose target list carries a
67
+ * `config` target resolves its value (`toConfig(value) ?? value`, falling back
68
+ * to the spec default) and nests it under that target's `block` / `key` (the
69
+ * key defaults to the spec key), then the result renders in the requested
70
+ * format. A spec with no `deploy`, or no `config` target, contributes nothing.
71
+ *
72
+ * A `block` ending in `[]` (e.g. `models[]`) follows the array-entry
73
+ * convention: the key lands inside the single object of a one-element array
74
+ * named by the prefix, and every spec sharing that block merges into that one
75
+ * entry. A plain block name nests as before, into one top-level object.
76
+ *
77
+ * A spec that carries both a `config` and a `cli` target contributes nothing
78
+ * here: the launch spells the CLI flag and leaves the on-disk config file (and
79
+ * any hand edits in it) untouched. Only a spec whose sole deploy path is the
80
+ * config file writes it.
81
+ *
82
+ * The YAML format loads the `yaml` package lazily (a root devDependency, so the
83
+ * JSON and env paths never touch it at runtime); a missing package throws only
84
+ * when the YAML format is requested.
85
+ */
86
+ export declare function configFileFromSpecs(specs: readonly ParameterSpec[], config: Config, format: ConfigFileFormat): string;
87
+ /**
88
+ * SudoHook is the optional sudo wiring createNodeLifecycleHost takes: `notify`
89
+ * announces a guarded command the probe found waiting for a password on the
90
+ * launching CLI (the service's sudo observer turns it into the Logs note), and
91
+ * `timeoutMs` overrides the 60 s password deadline. A host built without the
92
+ * hook never probes, announces, or caps a run.
93
+ */
94
+ export interface SudoHook {
95
+ notify: (command: string) => void;
96
+ timeoutMs?: number;
97
+ }
42
98
  /**
43
99
  * createNodeLifecycleHost builds the node `LifecycleHost`: `run` through the
44
100
  * system shell (a 10-minute cap, so a hung CUDA build cannot hang the panel),
45
- * `spawn` a detached child the stop step can signal, and `fetch` the health
46
- * URL. A fetch that throws (no route, connection refused) reads as status 0,
101
+ * `spawn` a detached child the stop step can signal, `writeFile` the config
102
+ * file the deploy step renders (creating the parent directory), and `fetch`
103
+ * the health URL. A fetch that throws (no route, connection refused) reads as status 0,
47
104
  * which the poll treats as not-ready. When `debug` is provided, the host logs
48
105
  * every command it issues (each `run` line and each `spawn` argv) through it,
49
- * so a DSH debug-mode host captures the full build-to-launch sequence.
106
+ * so a DSH debug-mode host captures the full build-to-launch sequence. A
107
+ * `RunOptions.shell` (the engine OS profile's shell, e.g. pwsh.exe for
108
+ * the Windows vcpkg route) runs the command line in that shell instead of the
109
+ * system default. A `RunOptions.graceMs` overrides the 5 s SIGTERM escalation
110
+ * window of the abort path for that run. The optional `sudo` hook wires the
111
+ * sudo-prompt rule: a run whose `RunOptions.needsSudo` declares sudo probes
112
+ * cached credentials first, announces a waiting prompt through the hook once,
113
+ * and dies at the password deadline with the `sudoFailureDetail` outcome. A
114
+ * host built without the hook never probes, announces, or caps a run.
50
115
  */
51
- export declare function createNodeLifecycleHost(debug?: DebugLogger): LifecycleHost;
116
+ export declare function createNodeLifecycleHost(debug?: DebugLogger, sudo?: SudoHook): LifecycleHost;
52
117
  /**
53
118
  * nodeLifecycleHost is the default live host the service wires in: the node
54
119
  * implementation with no debug logger, so a normal (non-debug) run logs no
@@ -64,16 +129,75 @@ export declare const nodeLifecycleHost: LifecycleHost;
64
129
  * watch (onExit absent) stays tracked until stop removes it.
65
130
  */
66
131
  export declare function trackChild(children: Map<string, ProcessHandle>, key: string, handle: ProcessHandle): void;
132
+ /**
133
+ * resolveLaunchArgv resolves a plan's launch argv against the engine
134
+ * directory the spawn runs in: a relative path that carries a separator (a
135
+ * build-tree binary, the NInfer Windows tree) is joined into an absolute
136
+ * path, and a bare name (a binary on the path after the rebuild's symlink
137
+ * step) is left as-is, so the spawn resolves the right command on every
138
+ * platform.
139
+ */
140
+ export declare function resolveLaunchArgv(engineDir: string | undefined, argv: readonly string[] | undefined): string[];
141
+ /**
142
+ * auditRun runs one mutating host command through the run's log sink: the
143
+ * `$ <command>` line reaches the sink before the child spawns, and the
144
+ * outcome's success output tail reaches it after the child settles, so the
145
+ * launch or stop run reads the command ahead of its result (the URL-query
146
+ * rule applied to execs: line first, settled outcome after). No sink (a
147
+ * headless call) and the command runs as before. A failed outcome lands no
148
+ * output here: the caller's own failure line carries the detail's output
149
+ * tail. The deploy and stop steps share this one audit rule for their direct
150
+ * `host.run` calls; the git and build steps run through the acquire step's
151
+ * own command-first echo.
152
+ */
153
+ export declare function auditRun(host: LifecycleHost, command: string, log?: CommandLogger, options?: RunOptions): Promise<CommandOutcome>;
154
+ /**
155
+ * stopProcessPlan signals the engine process a stop targets when the adapter
156
+ * tracks no child handle for it: an engine a DSH restart re-adopted from a
157
+ * stored launch record carries no in-memory handle, so the stop signals the
158
+ * pid the record stamped on the plan (kill on Linux and macOS, taskkill on a
159
+ * Windows plan). The optional `log` is the stop run's log sink: the signal
160
+ * command's `$ <command>` line reaches it before the child runs. A plan that
161
+ * names no pid is a no-op (nothing to signal), and a kill the host reports as
162
+ * failed throws with the host's detail, so the stop route names the broken
163
+ * step in the card's Logs section.
164
+ */
165
+ export declare function stopProcessPlan(host: LifecycleHost, plan: LaunchPlan, log?: CommandLogger): Promise<void>;
166
+ /**
167
+ * The health poll's defaults: the interval between attempts in ms and the
168
+ * attempt cap. The service passes the config's healthPollMs and
169
+ * healthMaxAttempts through, and an adapter that polls without options (or
170
+ * with a partial one) reads these, so the defaults have one home.
171
+ */
172
+ export declare const HEALTH_POLL_DEFAULT_MS = 1000;
173
+ export declare const HEALTH_POLL_MAX_ATTEMPTS = 120;
174
+ /**
175
+ * logHealthPoll brackets a health poll with the URL-query logging rule (the
176
+ * exec rule's URL twin): the one `> GET <url>` line reaches the run's log
177
+ * sink before the first request, the retries stay silent, and the settled
178
+ * verdict line (`> GET <url> ready`, Strata's still-downloading line, or the
179
+ * `!!` failure with the last detail) lands after the poll returns. The
180
+ * shared poll and the Strata poll both wrap their loop in this, so the rule
181
+ * has one home. `log` absent (a headless poll) runs the poll unlogged.
182
+ */
183
+ export declare function logHealthPoll(log: CommandLogger | undefined, url: string, poll: () => Promise<HealthResult>): Promise<HealthResult>;
67
184
  /**
68
185
  * pollHealth polls a plan's health URL until a 200 or the attempt cap, the
69
186
  * same loop the qwen-ninfer launcher runs. A poll interval of 0 skips the
70
- * delay, which the tests use to run the loop without a real sleep.
187
+ * delay, which the tests use to run the loop without a real sleep. `handle`
188
+ * is the tracked child the deploy step spawned: when it reports it has
189
+ * exited (hasExited true), the poll ends immediately with a failed result
190
+ * instead of running the full attempt cap, so a crash reports at once. A
191
+ * handle that cannot report its exit state (a stub) keeps the full poll.
192
+ * The poll's URL logging (the one `> GET` line ahead of the settled verdict)
193
+ * rides the shared logHealthPoll wrap when options.onLog carries the run's
194
+ * log sink.
71
195
  */
72
- export declare function pollHealth(host: LifecycleHost, plan: LaunchPlan, options?: HealthCheckOptions): Promise<HealthResult>;
196
+ export declare function pollHealth(host: LifecycleHost, plan: LaunchPlan, options?: HealthCheckOptions, handle?: ProcessHandle): Promise<HealthResult>;
73
197
  /**
74
198
  * delay waits `ms` milliseconds. The health polls use it between attempts; a
75
199
  * poll interval of 0 skips the wait, which the tests use to run the loop
76
200
  * without a real sleep.
77
201
  */
78
202
  export declare function delay(ms: number): Promise<void>;
79
- //# sourceMappingURL=adapters.d.ts.map
203
+ //# sourceMappingURL=adapters.d.ts.map