boten-gemma 0.1.0

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 (334) hide show
  1. package/README.md +860 -0
  2. package/dist/automation/cron/index.d.ts +6 -0
  3. package/dist/automation/cron/index.d.ts.map +1 -0
  4. package/dist/automation/cron/index.js +4 -0
  5. package/dist/automation/cron/index.js.map +1 -0
  6. package/dist/automation/cron/parse-schedule.d.ts +11 -0
  7. package/dist/automation/cron/parse-schedule.d.ts.map +1 -0
  8. package/dist/automation/cron/parse-schedule.js +36 -0
  9. package/dist/automation/cron/parse-schedule.js.map +1 -0
  10. package/dist/automation/cron/schedule.d.ts +7 -0
  11. package/dist/automation/cron/schedule.d.ts.map +1 -0
  12. package/dist/automation/cron/schedule.js +28 -0
  13. package/dist/automation/cron/schedule.js.map +1 -0
  14. package/dist/automation/cron/service.d.ts +70 -0
  15. package/dist/automation/cron/service.d.ts.map +1 -0
  16. package/dist/automation/cron/service.js +207 -0
  17. package/dist/automation/cron/service.js.map +1 -0
  18. package/dist/automation/cron/store.d.ts +12 -0
  19. package/dist/automation/cron/store.d.ts.map +1 -0
  20. package/dist/automation/cron/store.js +27 -0
  21. package/dist/automation/cron/store.js.map +1 -0
  22. package/dist/automation/cron/types.d.ts +67 -0
  23. package/dist/automation/cron/types.d.ts.map +1 -0
  24. package/dist/automation/cron/types.js +5 -0
  25. package/dist/automation/cron/types.js.map +1 -0
  26. package/dist/automation/cron.d.ts +15 -0
  27. package/dist/automation/cron.d.ts.map +1 -0
  28. package/dist/automation/cron.js +10 -0
  29. package/dist/automation/cron.js.map +1 -0
  30. package/dist/automation/heartbeat.d.ts +14 -0
  31. package/dist/automation/heartbeat.d.ts.map +1 -0
  32. package/dist/automation/heartbeat.js +27 -0
  33. package/dist/automation/heartbeat.js.map +1 -0
  34. package/dist/channels/cli.d.ts +17 -0
  35. package/dist/channels/cli.d.ts.map +1 -0
  36. package/dist/channels/cli.js +125 -0
  37. package/dist/channels/cli.js.map +1 -0
  38. package/dist/channels/telegram.d.ts +27 -0
  39. package/dist/channels/telegram.d.ts.map +1 -0
  40. package/dist/channels/telegram.js +288 -0
  41. package/dist/channels/telegram.js.map +1 -0
  42. package/dist/channels/types.d.ts +50 -0
  43. package/dist/channels/types.d.ts.map +1 -0
  44. package/dist/channels/types.js +6 -0
  45. package/dist/channels/types.js.map +1 -0
  46. package/dist/channels/web.d.ts +149 -0
  47. package/dist/channels/web.d.ts.map +1 -0
  48. package/dist/channels/web.js +1113 -0
  49. package/dist/channels/web.js.map +1 -0
  50. package/dist/config/defaults.d.ts +11 -0
  51. package/dist/config/defaults.d.ts.map +1 -0
  52. package/dist/config/defaults.js +80 -0
  53. package/dist/config/defaults.js.map +1 -0
  54. package/dist/config/loader.d.ts +22 -0
  55. package/dist/config/loader.d.ts.map +1 -0
  56. package/dist/config/loader.js +158 -0
  57. package/dist/config/loader.js.map +1 -0
  58. package/dist/config/schema.d.ts +261 -0
  59. package/dist/config/schema.d.ts.map +1 -0
  60. package/dist/config/schema.js +119 -0
  61. package/dist/config/schema.js.map +1 -0
  62. package/dist/confirm/audit.d.ts +34 -0
  63. package/dist/confirm/audit.d.ts.map +1 -0
  64. package/dist/confirm/audit.js +49 -0
  65. package/dist/confirm/audit.js.map +1 -0
  66. package/dist/confirm/auto-approve.d.ts +20 -0
  67. package/dist/confirm/auto-approve.d.ts.map +1 -0
  68. package/dist/confirm/auto-approve.js +62 -0
  69. package/dist/confirm/auto-approve.js.map +1 -0
  70. package/dist/confirm/gate.d.ts +50 -0
  71. package/dist/confirm/gate.d.ts.map +1 -0
  72. package/dist/confirm/gate.js +138 -0
  73. package/dist/confirm/gate.js.map +1 -0
  74. package/dist/confirm/parser.d.ts +23 -0
  75. package/dist/confirm/parser.d.ts.map +1 -0
  76. package/dist/confirm/parser.js +76 -0
  77. package/dist/confirm/parser.js.map +1 -0
  78. package/dist/confirm/presenter.d.ts +23 -0
  79. package/dist/confirm/presenter.d.ts.map +1 -0
  80. package/dist/confirm/presenter.js +92 -0
  81. package/dist/confirm/presenter.js.map +1 -0
  82. package/dist/core/agent-loop.d.ts +44 -0
  83. package/dist/core/agent-loop.d.ts.map +1 -0
  84. package/dist/core/agent-loop.js +156 -0
  85. package/dist/core/agent-loop.js.map +1 -0
  86. package/dist/core/compaction.d.ts +17 -0
  87. package/dist/core/compaction.d.ts.map +1 -0
  88. package/dist/core/compaction.js +70 -0
  89. package/dist/core/compaction.js.map +1 -0
  90. package/dist/core/context-builder.d.ts +38 -0
  91. package/dist/core/context-builder.d.ts.map +1 -0
  92. package/dist/core/context-builder.js +137 -0
  93. package/dist/core/context-builder.js.map +1 -0
  94. package/dist/core/logger.d.ts +42 -0
  95. package/dist/core/logger.d.ts.map +1 -0
  96. package/dist/core/logger.js +95 -0
  97. package/dist/core/logger.js.map +1 -0
  98. package/dist/core/queue.d.ts +25 -0
  99. package/dist/core/queue.d.ts.map +1 -0
  100. package/dist/core/queue.js +33 -0
  101. package/dist/core/queue.js.map +1 -0
  102. package/dist/core/router.d.ts +21 -0
  103. package/dist/core/router.d.ts.map +1 -0
  104. package/dist/core/router.js +27 -0
  105. package/dist/core/router.js.map +1 -0
  106. package/dist/core/session-store.d.ts +53 -0
  107. package/dist/core/session-store.d.ts.map +1 -0
  108. package/dist/core/session-store.js +367 -0
  109. package/dist/core/session-store.js.map +1 -0
  110. package/dist/core/session.d.ts +89 -0
  111. package/dist/core/session.d.ts.map +1 -0
  112. package/dist/core/session.js +49 -0
  113. package/dist/core/session.js.map +1 -0
  114. package/dist/daemon/launchd.d.ts +8 -0
  115. package/dist/daemon/launchd.d.ts.map +1 -0
  116. package/dist/daemon/launchd.js +155 -0
  117. package/dist/daemon/launchd.js.map +1 -0
  118. package/dist/daemon/service.d.ts +12 -0
  119. package/dist/daemon/service.d.ts.map +1 -0
  120. package/dist/daemon/service.js +42 -0
  121. package/dist/daemon/service.js.map +1 -0
  122. package/dist/daemon/systemd.d.ts +11 -0
  123. package/dist/daemon/systemd.d.ts.map +1 -0
  124. package/dist/daemon/systemd.js +145 -0
  125. package/dist/daemon/systemd.js.map +1 -0
  126. package/dist/daemon/types.d.ts +14 -0
  127. package/dist/daemon/types.d.ts.map +1 -0
  128. package/dist/daemon/types.js +2 -0
  129. package/dist/daemon/types.js.map +1 -0
  130. package/dist/daemon/update.d.ts +41 -0
  131. package/dist/daemon/update.d.ts.map +1 -0
  132. package/dist/daemon/update.js +106 -0
  133. package/dist/daemon/update.js.map +1 -0
  134. package/dist/gateway.d.ts +103 -0
  135. package/dist/gateway.d.ts.map +1 -0
  136. package/dist/gateway.js +1063 -0
  137. package/dist/gateway.js.map +1 -0
  138. package/dist/index.d.ts +3 -0
  139. package/dist/index.d.ts.map +1 -0
  140. package/dist/index.js +572 -0
  141. package/dist/index.js.map +1 -0
  142. package/dist/llm/auth/oauth-callback.d.ts +20 -0
  143. package/dist/llm/auth/oauth-callback.d.ts.map +1 -0
  144. package/dist/llm/auth/oauth-callback.js +95 -0
  145. package/dist/llm/auth/oauth-callback.js.map +1 -0
  146. package/dist/llm/auth/oauth.d.ts +30 -0
  147. package/dist/llm/auth/oauth.d.ts.map +1 -0
  148. package/dist/llm/auth/oauth.js +331 -0
  149. package/dist/llm/auth/oauth.js.map +1 -0
  150. package/dist/llm/auth/resolver.d.ts +24 -0
  151. package/dist/llm/auth/resolver.d.ts.map +1 -0
  152. package/dist/llm/auth/resolver.js +97 -0
  153. package/dist/llm/auth/resolver.js.map +1 -0
  154. package/dist/llm/auth/token-store.d.ts +15 -0
  155. package/dist/llm/auth/token-store.d.ts.map +1 -0
  156. package/dist/llm/auth/token-store.js +94 -0
  157. package/dist/llm/auth/token-store.js.map +1 -0
  158. package/dist/llm/auth/types.d.ts +20 -0
  159. package/dist/llm/auth/types.d.ts.map +1 -0
  160. package/dist/llm/auth/types.js +3 -0
  161. package/dist/llm/auth/types.js.map +1 -0
  162. package/dist/llm/gemini.d.ts +28 -0
  163. package/dist/llm/gemini.d.ts.map +1 -0
  164. package/dist/llm/gemini.js +524 -0
  165. package/dist/llm/gemini.js.map +1 -0
  166. package/dist/llm/openai-compat.d.ts +14 -0
  167. package/dist/llm/openai-compat.d.ts.map +1 -0
  168. package/dist/llm/openai-compat.js +200 -0
  169. package/dist/llm/openai-compat.js.map +1 -0
  170. package/dist/llm/provider.d.ts +2 -0
  171. package/dist/llm/provider.d.ts.map +1 -0
  172. package/dist/llm/provider.js +4 -0
  173. package/dist/llm/provider.js.map +1 -0
  174. package/dist/llm/types.d.ts +75 -0
  175. package/dist/llm/types.d.ts.map +1 -0
  176. package/dist/llm/types.js +3 -0
  177. package/dist/llm/types.js.map +1 -0
  178. package/dist/mcp/adapter.d.ts +14 -0
  179. package/dist/mcp/adapter.d.ts.map +1 -0
  180. package/dist/mcp/adapter.js +58 -0
  181. package/dist/mcp/adapter.js.map +1 -0
  182. package/dist/mcp/index.d.ts +4 -0
  183. package/dist/mcp/index.d.ts.map +1 -0
  184. package/dist/mcp/index.js +3 -0
  185. package/dist/mcp/index.js.map +1 -0
  186. package/dist/mcp/manager.d.ts +48 -0
  187. package/dist/mcp/manager.d.ts.map +1 -0
  188. package/dist/mcp/manager.js +109 -0
  189. package/dist/mcp/manager.js.map +1 -0
  190. package/dist/memory/daily-log.d.ts +19 -0
  191. package/dist/memory/daily-log.d.ts.map +1 -0
  192. package/dist/memory/daily-log.js +47 -0
  193. package/dist/memory/daily-log.js.map +1 -0
  194. package/dist/memory/memory-manager.d.ts +41 -0
  195. package/dist/memory/memory-manager.d.ts.map +1 -0
  196. package/dist/memory/memory-manager.js +97 -0
  197. package/dist/memory/memory-manager.js.map +1 -0
  198. package/dist/memory/workspace.d.ts +21 -0
  199. package/dist/memory/workspace.d.ts.map +1 -0
  200. package/dist/memory/workspace.js +63 -0
  201. package/dist/memory/workspace.js.map +1 -0
  202. package/dist/panels/bridge.d.ts +19 -0
  203. package/dist/panels/bridge.d.ts.map +1 -0
  204. package/dist/panels/bridge.js +74 -0
  205. package/dist/panels/bridge.js.map +1 -0
  206. package/dist/panels/registry.d.ts +30 -0
  207. package/dist/panels/registry.d.ts.map +1 -0
  208. package/dist/panels/registry.js +102 -0
  209. package/dist/panels/registry.js.map +1 -0
  210. package/dist/panels/routes.d.ts +8 -0
  211. package/dist/panels/routes.d.ts.map +1 -0
  212. package/dist/panels/routes.js +252 -0
  213. package/dist/panels/routes.js.map +1 -0
  214. package/dist/panels/sdk/gemma-panel.js +331 -0
  215. package/dist/panels/service-context.d.ts +28 -0
  216. package/dist/panels/service-context.d.ts.map +1 -0
  217. package/dist/panels/service-context.js +84 -0
  218. package/dist/panels/service-context.js.map +1 -0
  219. package/dist/panels/service-loader.d.ts +19 -0
  220. package/dist/panels/service-loader.d.ts.map +1 -0
  221. package/dist/panels/service-loader.js +61 -0
  222. package/dist/panels/service-loader.js.map +1 -0
  223. package/dist/panels/service-manager.d.ts +40 -0
  224. package/dist/panels/service-manager.d.ts.map +1 -0
  225. package/dist/panels/service-manager.js +148 -0
  226. package/dist/panels/service-manager.js.map +1 -0
  227. package/dist/panels/storage.d.ts +14 -0
  228. package/dist/panels/storage.d.ts.map +1 -0
  229. package/dist/panels/storage.js +47 -0
  230. package/dist/panels/storage.js.map +1 -0
  231. package/dist/panels/types.d.ts +39 -0
  232. package/dist/panels/types.d.ts.map +1 -0
  233. package/dist/panels/types.js +8 -0
  234. package/dist/panels/types.js.map +1 -0
  235. package/dist/shared/ws-types.d.ts +332 -0
  236. package/dist/shared/ws-types.d.ts.map +1 -0
  237. package/dist/shared/ws-types.js +7 -0
  238. package/dist/shared/ws-types.js.map +1 -0
  239. package/dist/skills/gating.d.ts +15 -0
  240. package/dist/skills/gating.d.ts.map +1 -0
  241. package/dist/skills/gating.js +49 -0
  242. package/dist/skills/gating.js.map +1 -0
  243. package/dist/skills/loader.d.ts +32 -0
  244. package/dist/skills/loader.d.ts.map +1 -0
  245. package/dist/skills/loader.js +66 -0
  246. package/dist/skills/loader.js.map +1 -0
  247. package/dist/skills/parser.d.ts +22 -0
  248. package/dist/skills/parser.d.ts.map +1 -0
  249. package/dist/skills/parser.js +29 -0
  250. package/dist/skills/parser.js.map +1 -0
  251. package/dist/skills/prompt-injector.d.ts +10 -0
  252. package/dist/skills/prompt-injector.d.ts.map +1 -0
  253. package/dist/skills/prompt-injector.js +29 -0
  254. package/dist/skills/prompt-injector.js.map +1 -0
  255. package/dist/tools/builtin/cron.d.ts +3 -0
  256. package/dist/tools/builtin/cron.d.ts.map +1 -0
  257. package/dist/tools/builtin/cron.js +198 -0
  258. package/dist/tools/builtin/cron.js.map +1 -0
  259. package/dist/tools/builtin/edit.d.ts +3 -0
  260. package/dist/tools/builtin/edit.d.ts.map +1 -0
  261. package/dist/tools/builtin/edit.js +77 -0
  262. package/dist/tools/builtin/edit.js.map +1 -0
  263. package/dist/tools/builtin/exec.d.ts +3 -0
  264. package/dist/tools/builtin/exec.d.ts.map +1 -0
  265. package/dist/tools/builtin/exec.js +88 -0
  266. package/dist/tools/builtin/exec.js.map +1 -0
  267. package/dist/tools/builtin/panel.d.ts +14 -0
  268. package/dist/tools/builtin/panel.d.ts.map +1 -0
  269. package/dist/tools/builtin/panel.js +521 -0
  270. package/dist/tools/builtin/panel.js.map +1 -0
  271. package/dist/tools/builtin/read.d.ts +3 -0
  272. package/dist/tools/builtin/read.d.ts.map +1 -0
  273. package/dist/tools/builtin/read.js +61 -0
  274. package/dist/tools/builtin/read.js.map +1 -0
  275. package/dist/tools/builtin/web-fetch.d.ts +3 -0
  276. package/dist/tools/builtin/web-fetch.d.ts.map +1 -0
  277. package/dist/tools/builtin/web-fetch.js +68 -0
  278. package/dist/tools/builtin/web-fetch.js.map +1 -0
  279. package/dist/tools/builtin/web-search.d.ts +3 -0
  280. package/dist/tools/builtin/web-search.d.ts.map +1 -0
  281. package/dist/tools/builtin/web-search.js +67 -0
  282. package/dist/tools/builtin/web-search.js.map +1 -0
  283. package/dist/tools/builtin/write.d.ts +3 -0
  284. package/dist/tools/builtin/write.d.ts.map +1 -0
  285. package/dist/tools/builtin/write.js +40 -0
  286. package/dist/tools/builtin/write.js.map +1 -0
  287. package/dist/tools/executor.d.ts +16 -0
  288. package/dist/tools/executor.d.ts.map +1 -0
  289. package/dist/tools/executor.js +142 -0
  290. package/dist/tools/executor.js.map +1 -0
  291. package/dist/tools/registry.d.ts +23 -0
  292. package/dist/tools/registry.d.ts.map +1 -0
  293. package/dist/tools/registry.js +72 -0
  294. package/dist/tools/registry.js.map +1 -0
  295. package/dist/tools/types.d.ts +58 -0
  296. package/dist/tools/types.d.ts.map +1 -0
  297. package/dist/tools/types.js +8 -0
  298. package/dist/tools/types.js.map +1 -0
  299. package/dist/ui/assets/code-block-OCS4YCEC-D5mQabi7.js +2 -0
  300. package/dist/ui/assets/index-0RdIdnZu.js +456 -0
  301. package/dist/ui/assets/index-CjWH8YjU.css +1 -0
  302. package/dist/ui/index.html +16 -0
  303. package/package.json +89 -0
  304. package/skills/coding/SKILL.md +52 -0
  305. package/skills/file-ops/SKILL.md +50 -0
  306. package/skills/panel-dev/SKILL.md +742 -0
  307. package/skills/system-admin/SKILL.md +56 -0
  308. package/skills/web-research/SKILL.md +44 -0
  309. package/templates/BOOTSTRAP.md +19 -0
  310. package/templates/IDENTITY.md +9 -0
  311. package/templates/INSTRUCTIONS.md +19 -0
  312. package/templates/MEMORY.md +5 -0
  313. package/templates/SOUL.md +21 -0
  314. package/templates/TOOLS.md +13 -0
  315. package/templates/USER.md +12 -0
  316. package/templates/panel/gemma-panel-sdk.d.ts +27 -0
  317. package/templates/panel/gemma-panel.d.ts +46 -0
  318. package/templates/panel/index.html +59 -0
  319. package/templates/panel/package.json +15 -0
  320. package/templates/panel/panel.json +12 -0
  321. package/templates/panel/service.ts +69 -0
  322. package/templates/panel/tsconfig.json +17 -0
  323. package/templates/panel/vite.config.ts +13 -0
  324. package/templates/panel-react/index.html +12 -0
  325. package/templates/panel-react/package.json +22 -0
  326. package/templates/panel-react/panel.json +10 -0
  327. package/templates/panel-react/service.ts +69 -0
  328. package/templates/panel-react/src/App.tsx +108 -0
  329. package/templates/panel-react/src/gemma.d.ts +13 -0
  330. package/templates/panel-react/src/main.tsx +9 -0
  331. package/templates/panel-react/src/vite-env.d.ts +1 -0
  332. package/templates/panel-react/tsconfig.json +17 -0
  333. package/templates/panel-react/tsconfig.service.json +16 -0
  334. package/templates/panel-react/vite.config.ts +14 -0
@@ -0,0 +1,155 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { writeFile, unlink, mkdir } from 'node:fs/promises';
3
+ import { existsSync } from 'node:fs';
4
+ import { join, dirname } from 'node:path';
5
+ import { homedir } from 'node:os';
6
+ const LABEL = 'ai.gemma.gateway';
7
+ const PLIST_PATH = join(homedir(), 'Library/LaunchAgents/ai.gemma.gateway.plist');
8
+ function exec(cmd, args) {
9
+ return new Promise((resolve, reject) => {
10
+ execFile(cmd, args, (error, stdout, stderr) => {
11
+ if (error) {
12
+ reject(Object.assign(error, { stdout, stderr }));
13
+ }
14
+ else {
15
+ resolve({ stdout, stderr });
16
+ }
17
+ });
18
+ });
19
+ }
20
+ function getUid() {
21
+ try {
22
+ return process.getuid();
23
+ }
24
+ catch {
25
+ return 501; // fallback for environments without getuid
26
+ }
27
+ }
28
+ export function buildLaunchdPlist(config) {
29
+ const envEntries = config.env
30
+ ? Object.entries(config.env)
31
+ .map(([k, v]) => ` <key>${escapeXml(k)}</key>\n <string>${escapeXml(v)}</string>`)
32
+ .join('\n')
33
+ : '';
34
+ const envSection = config.env
35
+ ? ` <key>EnvironmentVariables</key>
36
+ <dict>
37
+ <key>GEMMA_HOME</key>
38
+ <string>${escapeXml(config.gemmaHome)}</string>
39
+ <key>NODE_ENV</key>
40
+ <string>production</string>
41
+ ${envEntries}
42
+ </dict>`
43
+ : ` <key>EnvironmentVariables</key>
44
+ <dict>
45
+ <key>GEMMA_HOME</key>
46
+ <string>${escapeXml(config.gemmaHome)}</string>
47
+ <key>NODE_ENV</key>
48
+ <string>production</string>
49
+ </dict>`;
50
+ const logsDir = join(config.gemmaHome, 'logs');
51
+ return `<?xml version="1.0" encoding="UTF-8"?>
52
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
53
+ <plist version="1.0">
54
+ <dict>
55
+ <key>Label</key>
56
+ <string>${LABEL}</string>
57
+
58
+ <key>ProgramArguments</key>
59
+ <array>
60
+ <string>${escapeXml(config.nodePath)}</string>
61
+ <string>${escapeXml(config.entryPath)}</string>
62
+ <string>start</string>
63
+ </array>
64
+
65
+ <key>WorkingDirectory</key>
66
+ <string>${escapeXml(config.gemmaHome)}</string>
67
+
68
+ ${envSection}
69
+
70
+ <key>KeepAlive</key>
71
+ <true/>
72
+
73
+ <key>RunAtLoad</key>
74
+ <true/>
75
+
76
+ <key>StandardOutPath</key>
77
+ <string>${escapeXml(join(logsDir, 'gateway.stdout.log'))}</string>
78
+
79
+ <key>StandardErrorPath</key>
80
+ <string>${escapeXml(join(logsDir, 'gateway.stderr.log'))}</string>
81
+ </dict>
82
+ </plist>
83
+ `;
84
+ }
85
+ export async function installLaunchdService(config) {
86
+ // Ensure logs directory exists
87
+ await mkdir(join(config.gemmaHome, 'logs'), { recursive: true });
88
+ // Ensure LaunchAgents directory exists
89
+ await mkdir(dirname(PLIST_PATH), { recursive: true });
90
+ // Write plist file
91
+ const plist = buildLaunchdPlist(config);
92
+ await writeFile(PLIST_PATH, plist, 'utf-8');
93
+ const uid = getUid();
94
+ const domain = `gui/${uid}`;
95
+ // Bootstrap the service (register it with launchd)
96
+ await exec('launchctl', ['bootstrap', domain, PLIST_PATH]);
97
+ // Kick-start it immediately
98
+ await exec('launchctl', ['kickstart', '-k', `${domain}/${LABEL}`]);
99
+ }
100
+ export async function uninstallLaunchdService() {
101
+ const uid = getUid();
102
+ const domain = `gui/${uid}`;
103
+ // Bootout the service (deregister it)
104
+ try {
105
+ await exec('launchctl', ['bootout', `${domain}/${LABEL}`]);
106
+ }
107
+ catch {
108
+ // May already be unloaded
109
+ }
110
+ // Remove the plist file
111
+ if (existsSync(PLIST_PATH)) {
112
+ await unlink(PLIST_PATH);
113
+ }
114
+ }
115
+ export async function startLaunchdService() {
116
+ const uid = getUid();
117
+ await exec('launchctl', ['kickstart', '-k', `gui/${uid}/${LABEL}`]);
118
+ }
119
+ export async function stopLaunchdService() {
120
+ const uid = getUid();
121
+ await exec('launchctl', ['kill', 'SIGTERM', `gui/${uid}/${LABEL}`]);
122
+ }
123
+ export async function getLaunchdServiceStatus() {
124
+ const uid = getUid();
125
+ const status = {
126
+ installed: existsSync(PLIST_PATH),
127
+ running: false,
128
+ platform: 'darwin',
129
+ };
130
+ if (!status.installed)
131
+ return status;
132
+ try {
133
+ const { stdout } = await exec('launchctl', ['print', `gui/${uid}/${LABEL}`]);
134
+ // Parse pid from output like "pid = 12345"
135
+ const pidMatch = stdout.match(/pid\s*=\s*(\d+)/);
136
+ if (pidMatch) {
137
+ status.running = true;
138
+ status.pid = parseInt(pidMatch[1], 10);
139
+ }
140
+ // If no pid match but the command succeeded, the service is registered but not running
141
+ }
142
+ catch {
143
+ // Service is not loaded
144
+ }
145
+ return status;
146
+ }
147
+ function escapeXml(str) {
148
+ return str
149
+ .replace(/&/g, '&amp;')
150
+ .replace(/</g, '&lt;')
151
+ .replace(/>/g, '&gt;')
152
+ .replace(/"/g, '&quot;')
153
+ .replace(/'/g, '&apos;');
154
+ }
155
+ //# sourceMappingURL=launchd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launchd.js","sourceRoot":"","sources":["../../src/daemon/launchd.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { ServiceConfig, ServiceStatus } from './types.js';
2
+ export interface GemmaService {
3
+ install(config: ServiceConfig): Promise<void>;
4
+ uninstall(): Promise<void>;
5
+ start(): Promise<void>;
6
+ stop(): Promise<void>;
7
+ restart(): Promise<void>;
8
+ status(): Promise<ServiceStatus>;
9
+ }
10
+ export declare function resolveServiceConfig(gemmaHome: string, port?: number): ServiceConfig;
11
+ export declare function resolveService(): Promise<GemmaService>;
12
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/daemon/service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE/D,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,MAAM,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;CAClC;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,aAAa,CASpF;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,YAAY,CAAC,CAiD5D"}
@@ -0,0 +1,42 @@
1
+ import { resolve } from 'node:path';
2
+ import { fileURLToPath } from 'node:url';
3
+ export function resolveServiceConfig(gemmaHome, port) {
4
+ const entryPath = resolve(fileURLToPath(new URL('../../index.js', import.meta.url)));
5
+ return {
6
+ nodePath: process.execPath,
7
+ entryPath,
8
+ gemmaHome,
9
+ port: port ?? 18789,
10
+ };
11
+ }
12
+ export async function resolveService() {
13
+ const platform = process.platform;
14
+ if (platform === 'darwin') {
15
+ const { installLaunchdService, uninstallLaunchdService, startLaunchdService, stopLaunchdService, getLaunchdServiceStatus, } = await import('./launchd.js');
16
+ return {
17
+ install: installLaunchdService,
18
+ uninstall: uninstallLaunchdService,
19
+ start: startLaunchdService,
20
+ stop: stopLaunchdService,
21
+ restart: async () => {
22
+ await stopLaunchdService();
23
+ await startLaunchdService();
24
+ },
25
+ status: getLaunchdServiceStatus,
26
+ };
27
+ }
28
+ if (platform === 'linux') {
29
+ const { installSystemdService, uninstallSystemdService, startSystemdService, stopSystemdService, restartSystemdService, getSystemdServiceStatus, } = await import('./systemd.js');
30
+ return {
31
+ install: installSystemdService,
32
+ uninstall: uninstallSystemdService,
33
+ start: startSystemdService,
34
+ stop: stopSystemdService,
35
+ restart: restartSystemdService,
36
+ status: getSystemdServiceStatus,
37
+ };
38
+ }
39
+ throw new Error(`Daemon service management is not supported on ${platform}. ` +
40
+ `Supported platforms: macOS (launchd), Linux (systemd).`);
41
+ }
42
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/daemon/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAYzC,MAAM,UAAU,oBAAoB,CAAC,SAAiB,EAAE,IAAa;IACnE,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAErF,OAAO;QACL,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,SAAS;QACT,SAAS;QACT,IAAI,EAAE,IAAI,IAAI,KAAK;KACpB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAElC,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,MAAM,EACJ,qBAAqB,EACrB,uBAAuB,EACvB,mBAAmB,EACnB,kBAAkB,EAClB,uBAAuB,GACxB,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QAEjC,OAAO;YACL,OAAO,EAAE,qBAAqB;YAC9B,SAAS,EAAE,uBAAuB;YAClC,KAAK,EAAE,mBAAmB;YAC1B,IAAI,EAAE,kBAAkB;YACxB,OAAO,EAAE,KAAK,IAAI,EAAE;gBAClB,MAAM,kBAAkB,EAAE,CAAC;gBAC3B,MAAM,mBAAmB,EAAE,CAAC;YAC9B,CAAC;YACD,MAAM,EAAE,uBAAuB;SAChC,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,MAAM,EACJ,qBAAqB,EACrB,uBAAuB,EACvB,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EACrB,uBAAuB,GACxB,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QAEjC,OAAO;YACL,OAAO,EAAE,qBAAqB;YAC9B,SAAS,EAAE,uBAAuB;YAClC,KAAK,EAAE,mBAAmB;YAC1B,IAAI,EAAE,kBAAkB;YACxB,OAAO,EAAE,qBAAqB;YAC9B,MAAM,EAAE,uBAAuB;SAChC,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,KAAK,CACb,iDAAiD,QAAQ,IAAI;QAC3D,wDAAwD,CAC3D,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { ServiceConfig, ServiceStatus } from './types.js';
2
+ export declare function buildSystemdUnit(config: ServiceConfig): string;
3
+ export declare function installSystemdService(config: ServiceConfig): Promise<void>;
4
+ export declare function uninstallSystemdService(): Promise<void>;
5
+ export declare function startSystemdService(): Promise<void>;
6
+ export declare function stopSystemdService(): Promise<void>;
7
+ export declare function restartSystemdService(): Promise<void>;
8
+ export declare function getSystemdServiceStatus(): Promise<ServiceStatus>;
9
+ export declare function isSystemdAvailable(): Promise<boolean>;
10
+ export declare function enableLinger(): Promise<void>;
11
+ //# sourceMappingURL=systemd.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"systemd.d.ts","sourceRoot":"","sources":["../../src/daemon/systemd.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAoB/D,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAyB9D;AAED,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBhF;AAED,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC,CAqB7D;AAED,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAEzD;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAExD;AAED,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAE3D;AAED,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,aAAa,CAAC,CAwCtE;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CAU3D;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAElD"}
@@ -0,0 +1,145 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { writeFile, unlink, mkdir } from 'node:fs/promises';
3
+ import { existsSync } from 'node:fs';
4
+ import { join, dirname } from 'node:path';
5
+ import { homedir } from 'node:os';
6
+ const UNIT_NAME = 'gemma-gateway';
7
+ function getUnitPath() {
8
+ return join(homedir(), '.config/systemd/user/gemma-gateway.service');
9
+ }
10
+ function exec(cmd, args) {
11
+ return new Promise((resolve, reject) => {
12
+ execFile(cmd, args, (error, stdout, stderr) => {
13
+ if (error) {
14
+ reject(Object.assign(error, { stdout, stderr }));
15
+ }
16
+ else {
17
+ resolve({ stdout, stderr });
18
+ }
19
+ });
20
+ });
21
+ }
22
+ export function buildSystemdUnit(config) {
23
+ const envLines = config.env
24
+ ? Object.entries(config.env)
25
+ .map(([k, v]) => `Environment=${k}=${v}`)
26
+ .join('\n')
27
+ : '';
28
+ return `[Unit]
29
+ Description=Gemma AI Gateway
30
+ After=network-online.target
31
+ Wants=network-online.target
32
+
33
+ [Service]
34
+ ExecStart=${config.nodePath} ${config.entryPath} start
35
+ WorkingDirectory=${config.gemmaHome}
36
+ Restart=always
37
+ RestartSec=5
38
+ KillMode=process
39
+ Environment=GEMMA_HOME=${config.gemmaHome}
40
+ Environment=NODE_ENV=production
41
+ ${envLines}
42
+
43
+ [Install]
44
+ WantedBy=default.target
45
+ `;
46
+ }
47
+ export async function installSystemdService(config) {
48
+ const unitPath = getUnitPath();
49
+ // Ensure the systemd user directory exists
50
+ await mkdir(dirname(unitPath), { recursive: true });
51
+ // Ensure logs directory exists
52
+ await mkdir(join(config.gemmaHome, 'logs'), { recursive: true });
53
+ // Write the unit file
54
+ const unit = buildSystemdUnit(config);
55
+ await writeFile(unitPath, unit, 'utf-8');
56
+ // Reload systemd and enable + start the service
57
+ await exec('systemctl', ['--user', 'daemon-reload']);
58
+ await exec('systemctl', ['--user', 'enable', '--now', `${UNIT_NAME}.service`]);
59
+ }
60
+ export async function uninstallSystemdService() {
61
+ const unitPath = getUnitPath();
62
+ // Disable and stop the service
63
+ try {
64
+ await exec('systemctl', ['--user', 'disable', '--now', `${UNIT_NAME}.service`]);
65
+ }
66
+ catch {
67
+ // May already be disabled/stopped
68
+ }
69
+ // Remove the unit file
70
+ if (existsSync(unitPath)) {
71
+ await unlink(unitPath);
72
+ }
73
+ // Reload daemon so systemd forgets the unit
74
+ try {
75
+ await exec('systemctl', ['--user', 'daemon-reload']);
76
+ }
77
+ catch {
78
+ // Best effort
79
+ }
80
+ }
81
+ export async function startSystemdService() {
82
+ await exec('systemctl', ['--user', 'start', `${UNIT_NAME}.service`]);
83
+ }
84
+ export async function stopSystemdService() {
85
+ await exec('systemctl', ['--user', 'stop', `${UNIT_NAME}.service`]);
86
+ }
87
+ export async function restartSystemdService() {
88
+ await exec('systemctl', ['--user', 'restart', `${UNIT_NAME}.service`]);
89
+ }
90
+ export async function getSystemdServiceStatus() {
91
+ const unitPath = getUnitPath();
92
+ const status = {
93
+ installed: existsSync(unitPath),
94
+ running: false,
95
+ platform: 'linux',
96
+ };
97
+ if (!status.installed)
98
+ return status;
99
+ try {
100
+ const { stdout } = await exec('systemctl', [
101
+ '--user',
102
+ 'is-active',
103
+ `${UNIT_NAME}.service`,
104
+ ]);
105
+ status.running = stdout.trim() === 'active';
106
+ }
107
+ catch {
108
+ // is-active returns exit code 3 when inactive
109
+ status.running = false;
110
+ }
111
+ if (status.running) {
112
+ try {
113
+ const { stdout } = await exec('systemctl', [
114
+ '--user',
115
+ 'show',
116
+ '--property=MainPID',
117
+ `${UNIT_NAME}.service`,
118
+ ]);
119
+ const match = stdout.match(/MainPID=(\d+)/);
120
+ if (match && match[1] !== '0') {
121
+ status.pid = parseInt(match[1], 10);
122
+ }
123
+ }
124
+ catch {
125
+ // PID lookup is best-effort
126
+ }
127
+ }
128
+ return status;
129
+ }
130
+ export async function isSystemdAvailable() {
131
+ try {
132
+ await exec('systemctl', ['--user', '--no-pager', 'status']);
133
+ return true;
134
+ }
135
+ catch (err) {
136
+ // Exit code 1 means systemd is available but no unit was specified
137
+ // Exit code 127 means systemctl is not found
138
+ const code = err.code;
139
+ return code !== 127;
140
+ }
141
+ }
142
+ export async function enableLinger() {
143
+ await exec('loginctl', ['enable-linger']);
144
+ }
145
+ //# sourceMappingURL=systemd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"systemd.js","sourceRoot":"","sources":["../../src/daemon/systemd.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export interface ServiceConfig {
2
+ nodePath: string;
3
+ entryPath: string;
4
+ gemmaHome: string;
5
+ port: number;
6
+ env?: Record<string, string>;
7
+ }
8
+ export interface ServiceStatus {
9
+ installed: boolean;
10
+ running: boolean;
11
+ pid?: number;
12
+ platform: 'darwin' | 'linux' | 'win32';
13
+ }
14
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/daemon/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;CACxC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/daemon/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,41 @@
1
+ /** Read the installed package name and version (async). */
2
+ export declare function getPackageInfo(): Promise<{
3
+ name: string;
4
+ version: string;
5
+ }>;
6
+ /** Return the installed version synchronously (for `--version` flag). */
7
+ export declare function getPackageVersion(): string;
8
+ export interface UpdateCheckResult {
9
+ current: string;
10
+ latest: string;
11
+ updateAvailable: boolean;
12
+ }
13
+ /**
14
+ * Query the npm registry for the latest published version of this package
15
+ * and compare it with the locally installed version.
16
+ */
17
+ export declare function checkForUpdate(): Promise<UpdateCheckResult>;
18
+ export interface UpdateResult {
19
+ success: boolean;
20
+ previousVersion: string;
21
+ newVersion: string;
22
+ error?: string;
23
+ }
24
+ /**
25
+ * Run `npm install -g <package>@<channel>` to update the globally installed
26
+ * copy of Gemma.
27
+ *
28
+ * @param channel - npm dist-tag to install (default: `"latest"`).
29
+ */
30
+ export declare function performUpdate(channel?: string): Promise<UpdateResult>;
31
+ /**
32
+ * Restart the running Gemma gateway.
33
+ *
34
+ * Strategy:
35
+ * 1. If a platform service manager is installed and the service is running,
36
+ * delegate to the service manager's restart command.
37
+ * 2. Otherwise send `SIGUSR1` to the current process so the gateway can
38
+ * perform a graceful self-restart.
39
+ */
40
+ export declare function restartGateway(): Promise<void>;
41
+ //# sourceMappingURL=update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/daemon/update.ts"],"names":[],"mappings":"AAoCA,2DAA2D;AAC3D,wBAAsB,cAAc,IAAI,OAAO,CAAC;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC,CAID;AAED,yEAAyE;AACzE,wBAAgB,iBAAiB,IAAI,MAAM,CAI1C;AAMD,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAQjE;AAMD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,CAAC,CAiBvB;AAMD;;;;;;;;GAQG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAepD"}
@@ -0,0 +1,106 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { readFileSync } from 'node:fs';
3
+ import { readFile } from 'node:fs/promises';
4
+ import { join } from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+ // ---------------------------------------------------------------------------
7
+ // Helpers
8
+ // ---------------------------------------------------------------------------
9
+ const __dirname = fileURLToPath(new URL('.', import.meta.url));
10
+ /** Promisified `child_process.execFile`. */
11
+ function exec(cmd, args) {
12
+ return new Promise((resolve, reject) => {
13
+ execFile(cmd, args, { encoding: 'utf-8' }, (err, stdout, stderr) => {
14
+ if (err)
15
+ reject(err);
16
+ else
17
+ resolve({ stdout: stdout.trim(), stderr: stderr.trim() });
18
+ });
19
+ });
20
+ }
21
+ /** Resolve the path to this package's `package.json`. */
22
+ function getPackageJsonPath() {
23
+ // From dist/daemon/update.js → ../../package.json
24
+ return join(__dirname, '..', '..', 'package.json');
25
+ }
26
+ // ---------------------------------------------------------------------------
27
+ // Package info
28
+ // ---------------------------------------------------------------------------
29
+ /** Read the installed package name and version (async). */
30
+ export async function getPackageInfo() {
31
+ const raw = await readFile(getPackageJsonPath(), 'utf-8');
32
+ const pkg = JSON.parse(raw);
33
+ return { name: pkg.name, version: pkg.version };
34
+ }
35
+ /** Return the installed version synchronously (for `--version` flag). */
36
+ export function getPackageVersion() {
37
+ const raw = readFileSync(getPackageJsonPath(), 'utf-8');
38
+ const pkg = JSON.parse(raw);
39
+ return pkg.version;
40
+ }
41
+ /**
42
+ * Query the npm registry for the latest published version of this package
43
+ * and compare it with the locally installed version.
44
+ */
45
+ export async function checkForUpdate() {
46
+ const { name, version: current } = await getPackageInfo();
47
+ const { stdout: latest } = await exec('npm', ['view', name, 'version']);
48
+ return {
49
+ current,
50
+ latest,
51
+ updateAvailable: latest !== current,
52
+ };
53
+ }
54
+ /**
55
+ * Run `npm install -g <package>@<channel>` to update the globally installed
56
+ * copy of Gemma.
57
+ *
58
+ * @param channel - npm dist-tag to install (default: `"latest"`).
59
+ */
60
+ export async function performUpdate(channel) {
61
+ const { name, version: previousVersion } = await getPackageInfo();
62
+ const target = channel ? `${name}@${channel}` : `${name}@latest`;
63
+ try {
64
+ await exec('npm', ['install', '-g', target]);
65
+ // Re-read version from the newly installed package.json
66
+ const { version: newVersion } = await getPackageInfo();
67
+ return { success: true, previousVersion, newVersion };
68
+ }
69
+ catch (err) {
70
+ return {
71
+ success: false,
72
+ previousVersion,
73
+ newVersion: previousVersion,
74
+ error: err instanceof Error ? err.message : String(err),
75
+ };
76
+ }
77
+ }
78
+ // ---------------------------------------------------------------------------
79
+ // Restart
80
+ // ---------------------------------------------------------------------------
81
+ /**
82
+ * Restart the running Gemma gateway.
83
+ *
84
+ * Strategy:
85
+ * 1. If a platform service manager is installed and the service is running,
86
+ * delegate to the service manager's restart command.
87
+ * 2. Otherwise send `SIGUSR1` to the current process so the gateway can
88
+ * perform a graceful self-restart.
89
+ */
90
+ export async function restartGateway() {
91
+ try {
92
+ const { resolveService } = await import('./service.js');
93
+ const service = await resolveService();
94
+ const status = await service.status();
95
+ if (status.installed && status.running) {
96
+ await service.restart();
97
+ return;
98
+ }
99
+ }
100
+ catch {
101
+ // Service module not available or not configured — fall through.
102
+ }
103
+ // Fallback: signal the current process for a graceful restart.
104
+ process.kill(process.pid, 'SIGUSR1');
105
+ }
106
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/daemon/update.ts"],"names":[],"mappings":"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"}