p-spore 0.1.3 → 0.1.42

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 (396) hide show
  1. package/README.md +110 -15
  2. package/dist/agents/agent-manager.d.ts +3 -3
  3. package/dist/agents/agent-manager.d.ts.map +1 -1
  4. package/dist/agents/agent-manager.js +3 -2
  5. package/dist/agents/agent-manager.js.map +1 -1
  6. package/dist/application/agent-application.d.ts +29 -5
  7. package/dist/application/agent-application.d.ts.map +1 -1
  8. package/dist/application/agent-application.js +444 -14
  9. package/dist/application/agent-application.js.map +1 -1
  10. package/dist/articles/diff.d.ts +70 -0
  11. package/dist/articles/diff.d.ts.map +1 -0
  12. package/dist/articles/diff.js +330 -0
  13. package/dist/articles/diff.js.map +1 -0
  14. package/dist/articles/docx.d.ts +10 -0
  15. package/dist/articles/docx.d.ts.map +1 -0
  16. package/dist/articles/docx.js +219 -0
  17. package/dist/articles/docx.js.map +1 -0
  18. package/dist/articles/draft.d.ts +18 -0
  19. package/dist/articles/draft.d.ts.map +1 -0
  20. package/dist/articles/draft.js +88 -0
  21. package/dist/articles/draft.js.map +1 -0
  22. package/dist/articles/edits.d.ts +24 -0
  23. package/dist/articles/edits.d.ts.map +1 -0
  24. package/dist/articles/edits.js +54 -0
  25. package/dist/articles/edits.js.map +1 -0
  26. package/dist/articles/html.d.ts +10 -0
  27. package/dist/articles/html.d.ts.map +1 -0
  28. package/dist/articles/html.js +122 -0
  29. package/dist/articles/html.js.map +1 -0
  30. package/dist/articles/plain.d.ts +8 -0
  31. package/dist/articles/plain.d.ts.map +1 -0
  32. package/dist/articles/plain.js +69 -0
  33. package/dist/articles/plain.js.map +1 -0
  34. package/dist/articles/preview.d.ts +43 -0
  35. package/dist/articles/preview.d.ts.map +1 -0
  36. package/dist/articles/preview.js +90 -0
  37. package/dist/articles/preview.js.map +1 -0
  38. package/dist/articles/publish.d.ts +10 -0
  39. package/dist/articles/publish.d.ts.map +1 -0
  40. package/dist/articles/publish.js +54 -0
  41. package/dist/articles/publish.js.map +1 -0
  42. package/dist/articles/receipt.d.ts +16 -0
  43. package/dist/articles/receipt.d.ts.map +1 -0
  44. package/dist/articles/receipt.js +27 -0
  45. package/dist/articles/receipt.js.map +1 -0
  46. package/dist/articles/store.d.ts +78 -0
  47. package/dist/articles/store.d.ts.map +1 -0
  48. package/dist/articles/store.js +308 -0
  49. package/dist/articles/store.js.map +1 -0
  50. package/dist/articles/tool.d.ts +14 -0
  51. package/dist/articles/tool.d.ts.map +1 -0
  52. package/dist/articles/tool.js +175 -0
  53. package/dist/articles/tool.js.map +1 -0
  54. package/dist/articles/writer-context.d.ts +5 -0
  55. package/dist/articles/writer-context.d.ts.map +1 -0
  56. package/dist/articles/writer-context.js +56 -0
  57. package/dist/articles/writer-context.js.map +1 -0
  58. package/dist/articles/writer.d.ts +18 -0
  59. package/dist/articles/writer.d.ts.map +1 -0
  60. package/dist/articles/writer.js +79 -0
  61. package/dist/articles/writer.js.map +1 -0
  62. package/dist/articles/zip-write.d.ts +11 -0
  63. package/dist/articles/zip-write.d.ts.map +1 -0
  64. package/dist/articles/zip-write.js +63 -0
  65. package/dist/articles/zip-write.js.map +1 -0
  66. package/dist/bundled-skills/README.md +17 -0
  67. package/dist/bundled-skills/aegis-search/SKILL.md +59 -0
  68. package/dist/bundled-skills/aegis-search/bin/.gitkeep +0 -0
  69. package/dist/bundled-skills/article-canvas/SKILL.md +28 -0
  70. package/dist/bundled-skills/binaries.json +23 -0
  71. package/dist/bundled-skills/doc-extract/SKILL.md +56 -0
  72. package/dist/cli/main.d.ts.map +1 -1
  73. package/dist/cli/main.js +407 -54
  74. package/dist/cli/main.js.map +1 -1
  75. package/dist/config/config.d.ts +43 -0
  76. package/dist/config/config.d.ts.map +1 -1
  77. package/dist/config/config.js +150 -6
  78. package/dist/config/config.js.map +1 -1
  79. package/dist/daemon/daemon.d.ts.map +1 -1
  80. package/dist/daemon/daemon.js +80 -11
  81. package/dist/daemon/daemon.js.map +1 -1
  82. package/dist/desktop/application.d.ts +4 -0
  83. package/dist/desktop/application.d.ts.map +1 -0
  84. package/dist/desktop/application.js +1688 -0
  85. package/dist/desktop/application.js.map +1 -0
  86. package/dist/desktop/article-export.d.ts +12 -0
  87. package/dist/desktop/article-export.d.ts.map +1 -0
  88. package/dist/desktop/article-export.js +87 -0
  89. package/dist/desktop/article-export.js.map +1 -0
  90. package/dist/desktop/assets/pspore.png +0 -0
  91. package/dist/desktop/assets/pspore.svg +24 -0
  92. package/dist/desktop/conversation-smoke.d.ts +5 -0
  93. package/dist/desktop/conversation-smoke.d.ts.map +1 -0
  94. package/dist/desktop/conversation-smoke.js +93 -0
  95. package/dist/desktop/conversation-smoke.js.map +1 -0
  96. package/dist/desktop/daemon-bridge.d.ts.map +1 -1
  97. package/dist/desktop/daemon-bridge.js +62 -17
  98. package/dist/desktop/daemon-bridge.js.map +1 -1
  99. package/dist/desktop/ipc-contract.d.ts +124 -0
  100. package/dist/desktop/ipc-contract.d.ts.map +1 -1
  101. package/dist/desktop/ipc-contract.js +191 -12
  102. package/dist/desktop/ipc-contract.js.map +1 -1
  103. package/dist/desktop/local-path.d.ts +15 -0
  104. package/dist/desktop/local-path.d.ts.map +1 -0
  105. package/dist/desktop/local-path.js +59 -0
  106. package/dist/desktop/local-path.js.map +1 -0
  107. package/dist/desktop/main.d.ts +10 -1
  108. package/dist/desktop/main.d.ts.map +1 -1
  109. package/dist/desktop/main.js +122 -530
  110. package/dist/desktop/main.js.map +1 -1
  111. package/dist/desktop/native-startup.d.ts +4 -0
  112. package/dist/desktop/native-startup.d.ts.map +1 -0
  113. package/dist/desktop/native-startup.js +57 -0
  114. package/dist/desktop/native-startup.js.map +1 -0
  115. package/dist/desktop/preload.cjs +28 -1
  116. package/dist/desktop/renderer/article-panel.d.ts +45 -0
  117. package/dist/desktop/renderer/article-panel.d.ts.map +1 -0
  118. package/dist/desktop/renderer/article-panel.js +1126 -0
  119. package/dist/desktop/renderer/article-panel.js.map +1 -0
  120. package/dist/desktop/renderer/article-split.d.ts +32 -0
  121. package/dist/desktop/renderer/article-split.d.ts.map +1 -0
  122. package/dist/desktop/renderer/article-split.js +48 -0
  123. package/dist/desktop/renderer/article-split.js.map +1 -0
  124. package/dist/desktop/renderer/composer-file-references.d.ts +23 -0
  125. package/dist/desktop/renderer/composer-file-references.d.ts.map +1 -0
  126. package/dist/desktop/renderer/composer-file-references.js +51 -0
  127. package/dist/desktop/renderer/composer-file-references.js.map +1 -0
  128. package/dist/desktop/renderer/conversation.d.ts +23 -0
  129. package/dist/desktop/renderer/conversation.d.ts.map +1 -0
  130. package/dist/desktop/renderer/conversation.js +66 -0
  131. package/dist/desktop/renderer/conversation.js.map +1 -0
  132. package/dist/desktop/renderer/dom-reconcile.d.ts +15 -0
  133. package/dist/desktop/renderer/dom-reconcile.d.ts.map +1 -0
  134. package/dist/desktop/renderer/dom-reconcile.js +33 -0
  135. package/dist/desktop/renderer/dom-reconcile.js.map +1 -0
  136. package/dist/desktop/renderer/index.html +211 -34
  137. package/dist/desktop/renderer/indexing-view.d.ts +22 -0
  138. package/dist/desktop/renderer/indexing-view.d.ts.map +1 -0
  139. package/dist/desktop/renderer/indexing-view.js +115 -0
  140. package/dist/desktop/renderer/indexing-view.js.map +1 -0
  141. package/dist/desktop/renderer/markdown-view.d.ts +23 -0
  142. package/dist/desktop/renderer/markdown-view.d.ts.map +1 -0
  143. package/dist/desktop/renderer/markdown-view.js +436 -0
  144. package/dist/desktop/renderer/markdown-view.js.map +1 -0
  145. package/dist/desktop/renderer/motion.d.ts +67 -0
  146. package/dist/desktop/renderer/motion.d.ts.map +1 -0
  147. package/dist/desktop/renderer/motion.js +296 -0
  148. package/dist/desktop/renderer/motion.js.map +1 -0
  149. package/dist/desktop/renderer/renderer.js +1793 -155
  150. package/dist/desktop/renderer/renderer.js.map +1 -1
  151. package/dist/desktop/renderer/session-find.d.ts +18 -0
  152. package/dist/desktop/renderer/session-find.d.ts.map +1 -0
  153. package/dist/desktop/renderer/session-find.js +29 -0
  154. package/dist/desktop/renderer/session-find.js.map +1 -0
  155. package/dist/desktop/renderer/session-search.d.ts +30 -0
  156. package/dist/desktop/renderer/session-search.d.ts.map +1 -0
  157. package/dist/desktop/renderer/session-search.js +296 -0
  158. package/dist/desktop/renderer/session-search.js.map +1 -0
  159. package/dist/desktop/renderer/store.d.ts +35 -8
  160. package/dist/desktop/renderer/store.d.ts.map +1 -1
  161. package/dist/desktop/renderer/store.js +95 -78
  162. package/dist/desktop/renderer/store.js.map +1 -1
  163. package/dist/desktop/renderer/styles.css +910 -268
  164. package/dist/desktop/renderer/vendor/gsap.min.js +11 -0
  165. package/dist/desktop/renderer-diagnostics.d.ts +5 -0
  166. package/dist/desktop/renderer-diagnostics.d.ts.map +1 -0
  167. package/dist/desktop/renderer-diagnostics.js +47 -0
  168. package/dist/desktop/renderer-diagnostics.js.map +1 -0
  169. package/dist/desktop/security.d.ts +26 -1
  170. package/dist/desktop/security.d.ts.map +1 -1
  171. package/dist/desktop/security.js +26 -6
  172. package/dist/desktop/security.js.map +1 -1
  173. package/dist/desktop/smoke-fixture.d.ts.map +1 -1
  174. package/dist/desktop/smoke-fixture.js +77 -3
  175. package/dist/desktop/smoke-fixture.js.map +1 -1
  176. package/dist/desktop/splash/index.html +25 -0
  177. package/dist/desktop/splash/splash.d.ts +2 -0
  178. package/dist/desktop/splash/splash.d.ts.map +1 -0
  179. package/dist/desktop/splash/splash.js +8 -0
  180. package/dist/desktop/splash/splash.js.map +1 -0
  181. package/dist/desktop/splash/styles.css +24 -0
  182. package/dist/desktop/system-open.d.ts +16 -0
  183. package/dist/desktop/system-open.d.ts.map +1 -0
  184. package/dist/desktop/system-open.js +90 -0
  185. package/dist/desktop/system-open.js.map +1 -0
  186. package/dist/desktop/validation.d.ts.map +1 -1
  187. package/dist/desktop/validation.js +99 -21
  188. package/dist/desktop/validation.js.map +1 -1
  189. package/dist/desktop/window-security.d.ts +4 -0
  190. package/dist/desktop/window-security.d.ts.map +1 -0
  191. package/dist/desktop/window-security.js +26 -0
  192. package/dist/desktop/window-security.js.map +1 -0
  193. package/dist/documents/errors.d.ts +12 -0
  194. package/dist/documents/errors.d.ts.map +1 -0
  195. package/dist/documents/errors.js +12 -0
  196. package/dist/documents/errors.js.map +1 -0
  197. package/dist/documents/extract.d.ts +37 -0
  198. package/dist/documents/extract.d.ts.map +1 -0
  199. package/dist/documents/extract.js +90 -0
  200. package/dist/documents/extract.js.map +1 -0
  201. package/dist/documents/legacy-office.d.ts +23 -0
  202. package/dist/documents/legacy-office.d.ts.map +1 -0
  203. package/dist/documents/legacy-office.js +439 -0
  204. package/dist/documents/legacy-office.js.map +1 -0
  205. package/dist/documents/ole.d.ts +20 -0
  206. package/dist/documents/ole.d.ts.map +1 -0
  207. package/dist/documents/ole.js +189 -0
  208. package/dist/documents/ole.js.map +1 -0
  209. package/dist/documents/ooxml.d.ts +23 -0
  210. package/dist/documents/ooxml.d.ts.map +1 -0
  211. package/dist/documents/ooxml.js +197 -0
  212. package/dist/documents/ooxml.js.map +1 -0
  213. package/dist/documents/pdf.d.ts +20 -0
  214. package/dist/documents/pdf.d.ts.map +1 -0
  215. package/dist/documents/pdf.js +95 -0
  216. package/dist/documents/pdf.js.map +1 -0
  217. package/dist/documents/plain-text.d.ts +22 -0
  218. package/dist/documents/plain-text.d.ts.map +1 -0
  219. package/dist/documents/plain-text.js +57 -0
  220. package/dist/documents/plain-text.js.map +1 -0
  221. package/dist/documents/zip.d.ts +15 -0
  222. package/dist/documents/zip.d.ts.map +1 -0
  223. package/dist/documents/zip.js +137 -0
  224. package/dist/documents/zip.js.map +1 -0
  225. package/dist/domain/indexing.d.ts +60 -0
  226. package/dist/domain/indexing.d.ts.map +1 -0
  227. package/dist/domain/indexing.js +13 -0
  228. package/dist/domain/indexing.js.map +1 -0
  229. package/dist/domain/runtime.d.ts +133 -5
  230. package/dist/domain/runtime.d.ts.map +1 -1
  231. package/dist/gateway/local-gateway.d.ts +8 -0
  232. package/dist/gateway/local-gateway.d.ts.map +1 -1
  233. package/dist/gateway/local-gateway.js +105 -21
  234. package/dist/gateway/local-gateway.js.map +1 -1
  235. package/dist/indexing/index-service.d.ts +56 -0
  236. package/dist/indexing/index-service.d.ts.map +1 -0
  237. package/dist/indexing/index-service.js +262 -0
  238. package/dist/indexing/index-service.js.map +1 -0
  239. package/dist/kernel/loop.d.ts +10 -0
  240. package/dist/kernel/loop.d.ts.map +1 -1
  241. package/dist/kernel/loop.js +6 -2
  242. package/dist/kernel/loop.js.map +1 -1
  243. package/dist/kernel/reducer.d.ts.map +1 -1
  244. package/dist/kernel/reducer.js +17 -1
  245. package/dist/kernel/reducer.js.map +1 -1
  246. package/dist/kernel/state.d.ts +17 -4
  247. package/dist/kernel/state.d.ts.map +1 -1
  248. package/dist/kernel/state.js +2 -0
  249. package/dist/kernel/state.js.map +1 -1
  250. package/dist/memory/memory-tools.d.ts.map +1 -1
  251. package/dist/memory/memory-tools.js +25 -5
  252. package/dist/memory/memory-tools.js.map +1 -1
  253. package/dist/pi/context-budget.d.ts +8 -0
  254. package/dist/pi/context-budget.d.ts.map +1 -0
  255. package/dist/pi/context-budget.js +62 -0
  256. package/dist/pi/context-budget.js.map +1 -0
  257. package/dist/pi/pi-runtime-adapter.d.ts +38 -3
  258. package/dist/pi/pi-runtime-adapter.d.ts.map +1 -1
  259. package/dist/pi/pi-runtime-adapter.js +551 -56
  260. package/dist/pi/pi-runtime-adapter.js.map +1 -1
  261. package/dist/plugins/bundled-skills.d.ts +56 -0
  262. package/dist/plugins/bundled-skills.d.ts.map +1 -0
  263. package/dist/plugins/bundled-skills.js +243 -0
  264. package/dist/plugins/bundled-skills.js.map +1 -0
  265. package/dist/plugins/extension-manager.d.ts +23 -1
  266. package/dist/plugins/extension-manager.d.ts.map +1 -1
  267. package/dist/plugins/extension-manager.js +117 -0
  268. package/dist/plugins/extension-manager.js.map +1 -1
  269. package/dist/plugins/types.d.ts +29 -0
  270. package/dist/plugins/types.d.ts.map +1 -1
  271. package/dist/plugins/workspace-skills.d.ts +36 -0
  272. package/dist/plugins/workspace-skills.d.ts.map +1 -0
  273. package/dist/plugins/workspace-skills.js +309 -0
  274. package/dist/plugins/workspace-skills.js.map +1 -0
  275. package/dist/policy/policy.d.ts.map +1 -1
  276. package/dist/policy/policy.js +26 -4
  277. package/dist/policy/policy.js.map +1 -1
  278. package/dist/protocol/client.d.ts +1 -0
  279. package/dist/protocol/client.d.ts.map +1 -1
  280. package/dist/protocol/client.js +49 -24
  281. package/dist/protocol/client.js.map +1 -1
  282. package/dist/protocol/limits.d.ts +69 -0
  283. package/dist/protocol/limits.d.ts.map +1 -0
  284. package/dist/protocol/limits.js +166 -0
  285. package/dist/protocol/limits.js.map +1 -0
  286. package/dist/protocol/schema.d.ts +6 -0
  287. package/dist/protocol/schema.d.ts.map +1 -1
  288. package/dist/protocol/schema.js.map +1 -1
  289. package/dist/protocol/server-frame-codec.d.ts +18 -0
  290. package/dist/protocol/server-frame-codec.d.ts.map +1 -0
  291. package/dist/protocol/server-frame-codec.js +211 -0
  292. package/dist/protocol/server-frame-codec.js.map +1 -0
  293. package/dist/service/legacy-daemon.d.ts +6 -0
  294. package/dist/service/legacy-daemon.d.ts.map +1 -0
  295. package/dist/service/legacy-daemon.js +42 -0
  296. package/dist/service/legacy-daemon.js.map +1 -0
  297. package/dist/service/service-launch.d.ts +10 -0
  298. package/dist/service/service-launch.d.ts.map +1 -0
  299. package/dist/service/service-launch.js +56 -0
  300. package/dist/service/service-launch.js.map +1 -0
  301. package/dist/service/system-service.d.ts +57 -0
  302. package/dist/service/system-service.d.ts.map +1 -0
  303. package/dist/service/system-service.js +263 -0
  304. package/dist/service/system-service.js.map +1 -0
  305. package/dist/sessions/session-catalog.d.ts +45 -0
  306. package/dist/sessions/session-catalog.d.ts.map +1 -0
  307. package/dist/sessions/session-catalog.js +270 -0
  308. package/dist/sessions/session-catalog.js.map +1 -0
  309. package/dist/sessions/session-file.d.ts +12 -0
  310. package/dist/sessions/session-file.d.ts.map +1 -0
  311. package/dist/sessions/session-file.js +47 -0
  312. package/dist/sessions/session-file.js.map +1 -0
  313. package/dist/settings/compaction-settings.d.ts +10 -0
  314. package/dist/settings/compaction-settings.d.ts.map +1 -0
  315. package/dist/settings/compaction-settings.js +8 -0
  316. package/dist/settings/compaction-settings.js.map +1 -0
  317. package/dist/settings/indexing-settings-service.d.ts +16 -0
  318. package/dist/settings/indexing-settings-service.d.ts.map +1 -0
  319. package/dist/settings/indexing-settings-service.js +57 -0
  320. package/dist/settings/indexing-settings-service.js.map +1 -0
  321. package/dist/settings/indexing-settings.d.ts +30 -0
  322. package/dist/settings/indexing-settings.d.ts.map +1 -0
  323. package/dist/settings/indexing-settings.js +58 -0
  324. package/dist/settings/indexing-settings.js.map +1 -0
  325. package/dist/settings/llm-settings-service.d.ts +6 -0
  326. package/dist/settings/llm-settings-service.d.ts.map +1 -1
  327. package/dist/settings/llm-settings-service.js +137 -12
  328. package/dist/settings/llm-settings-service.js.map +1 -1
  329. package/dist/settings/llm-settings.d.ts +68 -2
  330. package/dist/settings/llm-settings.d.ts.map +1 -1
  331. package/dist/settings/llm-settings.js +119 -17
  332. package/dist/settings/llm-settings.js.map +1 -1
  333. package/dist/settings/model-api.d.ts +10 -0
  334. package/dist/settings/model-api.d.ts.map +1 -0
  335. package/dist/settings/model-api.js +10 -0
  336. package/dist/settings/model-api.js.map +1 -0
  337. package/dist/storage/home.d.ts +1 -0
  338. package/dist/storage/home.d.ts.map +1 -1
  339. package/dist/storage/home.js +37 -2
  340. package/dist/storage/home.js.map +1 -1
  341. package/dist/tools/core-tools.d.ts +2 -0
  342. package/dist/tools/core-tools.d.ts.map +1 -1
  343. package/dist/tools/core-tools.js +91 -1
  344. package/dist/tools/core-tools.js.map +1 -1
  345. package/dist/ui/shared/activity.d.ts +27 -0
  346. package/dist/ui/shared/activity.d.ts.map +1 -0
  347. package/dist/ui/shared/activity.js +384 -0
  348. package/dist/ui/shared/activity.js.map +1 -0
  349. package/dist/ui/shared/full-message.d.ts +22 -0
  350. package/dist/ui/shared/full-message.d.ts.map +1 -0
  351. package/dist/ui/shared/full-message.js +40 -0
  352. package/dist/ui/shared/full-message.js.map +1 -0
  353. package/dist/ui/shared/local-links.d.ts +7 -0
  354. package/dist/ui/shared/local-links.d.ts.map +1 -0
  355. package/dist/ui/shared/local-links.js +24 -0
  356. package/dist/ui/shared/local-links.js.map +1 -0
  357. package/dist/ui/shared/markdown-stream.d.ts +25 -0
  358. package/dist/ui/shared/markdown-stream.d.ts.map +1 -0
  359. package/dist/ui/shared/markdown-stream.js +35 -0
  360. package/dist/ui/shared/markdown-stream.js.map +1 -0
  361. package/dist/ui/shared/markdown.d.ts +70 -0
  362. package/dist/ui/shared/markdown.d.ts.map +1 -0
  363. package/dist/ui/shared/markdown.js +434 -0
  364. package/dist/ui/shared/markdown.js.map +1 -0
  365. package/dist/ui/shared/presentation.d.ts +10 -2
  366. package/dist/ui/shared/presentation.d.ts.map +1 -1
  367. package/dist/ui/shared/presentation.js +83 -22
  368. package/dist/ui/shared/presentation.js.map +1 -1
  369. package/dist/ui/shared/protocol-state.d.ts +19 -0
  370. package/dist/ui/shared/protocol-state.d.ts.map +1 -1
  371. package/dist/ui/shared/protocol-state.js +188 -26
  372. package/dist/ui/shared/protocol-state.js.map +1 -1
  373. package/dist/ui/shared/virtual-list.d.ts +34 -0
  374. package/dist/ui/shared/virtual-list.d.ts.map +1 -0
  375. package/dist/ui/shared/virtual-list.js +143 -0
  376. package/dist/ui/shared/virtual-list.js.map +1 -0
  377. package/dist/ui/tui/commands.d.ts +1 -1
  378. package/dist/ui/tui/commands.d.ts.map +1 -1
  379. package/dist/ui/tui/commands.js +9 -3
  380. package/dist/ui/tui/commands.js.map +1 -1
  381. package/dist/ui/tui/store.d.ts +26 -0
  382. package/dist/ui/tui/store.d.ts.map +1 -1
  383. package/dist/ui/tui/store.js +67 -3
  384. package/dist/ui/tui/store.js.map +1 -1
  385. package/dist/ui/tui/tui-app.d.ts.map +1 -1
  386. package/dist/ui/tui/tui-app.js +316 -38
  387. package/dist/ui/tui/tui-app.js.map +1 -1
  388. package/dist/ui/tui/view.d.ts +10 -0
  389. package/dist/ui/tui/view.d.ts.map +1 -1
  390. package/dist/ui/tui/view.js +253 -49
  391. package/dist/ui/tui/view.js.map +1 -1
  392. package/dist/version.d.ts +1 -1
  393. package/dist/version.d.ts.map +1 -1
  394. package/dist/version.js +1 -1
  395. package/dist/version.js.map +1 -1
  396. package/package.json +13 -2
@@ -0,0 +1,42 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { ProtocolClient } from "../protocol/client.js";
3
+ import { psporePaths } from "../storage/home.js";
4
+ /**
5
+ * One-time migration helper: an old GUI-owned daemon cannot be adopted by
6
+ * systemd, so ask it to exit cleanly before the new service starts.
7
+ */
8
+ export async function stopLegacyDaemon(home) {
9
+ const paths = psporePaths(home);
10
+ let socket = paths.socket;
11
+ try {
12
+ const endpoint = JSON.parse(await readFile(paths.endpoint, "utf8"));
13
+ if (typeof endpoint.socket === "string" && endpoint.socket)
14
+ socket = endpoint.socket;
15
+ }
16
+ catch {
17
+ return;
18
+ }
19
+ const client = new ProtocolClient({ socketPath: socket, clientId: `service-migration-${process.pid}` });
20
+ try {
21
+ await client.connect();
22
+ await client.command("daemon.shutdown", {});
23
+ }
24
+ catch {
25
+ return;
26
+ }
27
+ finally {
28
+ await client.close().catch(() => undefined);
29
+ }
30
+ const deadline = Date.now() + 5_000;
31
+ while (Date.now() < deadline) {
32
+ try {
33
+ await readFile(paths.endpoint, "utf8");
34
+ }
35
+ catch {
36
+ return;
37
+ }
38
+ await new Promise((resolve) => setTimeout(resolve, 50));
39
+ }
40
+ throw new Error("The legacy daemon did not stop within 5 seconds; stop it manually and retry service installation");
41
+ }
42
+ //# sourceMappingURL=legacy-daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legacy-daemon.js","sourceRoot":"","sources":["../../src/service/legacy-daemon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAY;IACjD,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAC1B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAyB,CAAC;QAC5F,IAAI,OAAO,QAAQ,CAAC,MAAM,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM;YAAE,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;IACvF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,qBAAqB,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACxG,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;QACvB,MAAM,MAAM,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC9C,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;IACpC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;QACD,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IAC1D,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,kGAAkG,CAAC,CAAC;AACtH,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { SystemServiceLaunchSpec } from "./system-service.js";
2
+ export interface ServiceRuntimeIdentity {
3
+ execPath: string;
4
+ argvEntry?: string;
5
+ moduleUrl: string;
6
+ electron?: boolean;
7
+ }
8
+ /** Build a stable service command for npm, source builds, SEA, or Electron packages. */
9
+ export declare function serviceLaunchSpec(home: string, workspace: string, identity: ServiceRuntimeIdentity): Promise<SystemServiceLaunchSpec>;
10
+ //# sourceMappingURL=service-launch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-launch.d.ts","sourceRoot":"","sources":["../../src/service/service-launch.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAEnE,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wFAAwF;AACxF,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,sBAAsB,GAC/B,OAAO,CAAC,uBAAuB,CAAC,CA2BlC"}
@@ -0,0 +1,56 @@
1
+ import { access } from "node:fs/promises";
2
+ import { dirname, resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ /** Build a stable service command for npm, source builds, SEA, or Electron packages. */
5
+ export async function serviceLaunchSpec(home, workspace, identity) {
6
+ const executable = resolve(identity.execPath);
7
+ if (identity.electron) {
8
+ const cliEntry = fileURLToPath(new URL("../cli/main.js", identity.moduleUrl));
9
+ await requireReadableEntry(cliEntry);
10
+ return {
11
+ executable,
12
+ args: [cliEntry, "--home", resolve(home), "daemon"],
13
+ workingDirectory: resolve(workspace),
14
+ environment: { ELECTRON_RUN_AS_NODE: "1" },
15
+ };
16
+ }
17
+ if (isSingleExecutableRuntime(identity.argvEntry, executable, identity.moduleUrl)) {
18
+ return {
19
+ executable,
20
+ args: ["--home", resolve(home), "daemon"],
21
+ workingDirectory: resolve(workspace),
22
+ };
23
+ }
24
+ const cliEntry = await compiledCliEntry(identity.moduleUrl);
25
+ return {
26
+ executable,
27
+ args: [cliEntry, "--home", resolve(home), "daemon"],
28
+ workingDirectory: resolve(workspace),
29
+ };
30
+ }
31
+ async function compiledCliEntry(moduleUrl) {
32
+ const current = fileURLToPath(moduleUrl);
33
+ if (current.endsWith(".js")) {
34
+ await requireReadableEntry(current);
35
+ return current;
36
+ }
37
+ const built = resolve(dirname(current), "../../dist/cli/main.js");
38
+ await requireReadableEntry(built);
39
+ return built;
40
+ }
41
+ async function requireReadableEntry(path) {
42
+ try {
43
+ await access(path);
44
+ }
45
+ catch {
46
+ throw new Error(`The system service entry is not built at ${path}; run \`npm run build\` first`);
47
+ }
48
+ }
49
+ function isSingleExecutableRuntime(argvEntry, executable, moduleUrl) {
50
+ if (fileURLToPath(moduleUrl) === executable)
51
+ return true;
52
+ if (!argvEntry)
53
+ return false;
54
+ return resolve(argvEntry) === executable;
55
+ }
56
+ //# sourceMappingURL=service-launch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-launch.js","sourceRoot":"","sources":["../../src/service/service-launch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAWzC,wFAAwF;AACxF,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,IAAY,EACZ,SAAiB,EACjB,QAAgC;IAEhC,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC9C,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACtB,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,gBAAgB,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;QAC9E,MAAM,oBAAoB,CAAC,QAAQ,CAAC,CAAC;QACrC,OAAO;YACL,UAAU;YACV,IAAI,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC;YACnD,gBAAgB,EAAE,OAAO,CAAC,SAAS,CAAC;YACpC,WAAW,EAAE,EAAE,oBAAoB,EAAE,GAAG,EAAE;SAC3C,CAAC;IACJ,CAAC;IAED,IAAI,yBAAyB,CAAC,QAAQ,CAAC,SAAS,EAAE,UAAU,EAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAClF,OAAO;YACL,UAAU;YACV,IAAI,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC;YACzC,gBAAgB,EAAE,OAAO,CAAC,SAAS,CAAC;SACrC,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC5D,OAAO;QACL,UAAU;QACV,IAAI,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC;QACnD,gBAAgB,EAAE,OAAO,CAAC,SAAS,CAAC;KACrC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,SAAiB;IAC/C,MAAM,OAAO,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IACzC,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,oBAAoB,CAAC,OAAO,CAAC,CAAC;QACpC,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,wBAAwB,CAAC,CAAC;IAClE,MAAM,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAClC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,oBAAoB,CAAC,IAAY;IAC9C,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,4CAA4C,IAAI,+BAA+B,CAAC,CAAC;IACnG,CAAC;AACH,CAAC;AAED,SAAS,yBAAyB,CAAC,SAA6B,EAAE,UAAkB,EAAE,SAAiB;IACrG,IAAI,aAAa,CAAC,SAAS,CAAC,KAAK,UAAU;QAAE,OAAO,IAAI,CAAC;IACzD,IAAI,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC;IAC7B,OAAO,OAAO,CAAC,SAAS,CAAC,KAAK,UAAU,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,57 @@
1
+ export interface SystemServiceLaunchSpec {
2
+ executable: string;
3
+ args: readonly string[];
4
+ workingDirectory: string;
5
+ environment?: Readonly<Record<string, string>>;
6
+ }
7
+ export interface SystemServiceCommandResult {
8
+ code: number;
9
+ stdout: string;
10
+ stderr: string;
11
+ }
12
+ export type SystemServiceCommandRunner = (executable: string, args: readonly string[]) => Promise<SystemServiceCommandResult>;
13
+ export interface SystemServiceStatus {
14
+ unitName: string;
15
+ unitPath: string;
16
+ installed: boolean;
17
+ enabled: boolean;
18
+ active: boolean;
19
+ linger: boolean | undefined;
20
+ detail?: string;
21
+ }
22
+ export interface SystemServiceEnsureResult extends SystemServiceStatus {
23
+ unitChanged: boolean;
24
+ lingerWarning?: string;
25
+ /** Set when a previously failed unit had to be reset before it could start. */
26
+ recoveredFromFailure?: boolean;
27
+ }
28
+ export interface SystemServiceManagerOptions {
29
+ home: string;
30
+ userConfigDirectory?: string;
31
+ username?: string;
32
+ runner?: SystemServiceCommandRunner;
33
+ beforeStart?: () => Promise<void>;
34
+ }
35
+ /**
36
+ * Installs and controls the per-user systemd service used by production clients.
37
+ * GUI/TUI callers never own the daemon process; their only lifecycle action is
38
+ * asking systemd to keep the authoritative service enabled and running.
39
+ */
40
+ export declare class SystemServiceManager {
41
+ #private;
42
+ readonly unitName: string;
43
+ readonly unitPath: string;
44
+ constructor(options: SystemServiceManagerOptions);
45
+ ensureRunning(spec: SystemServiceLaunchSpec): Promise<SystemServiceEnsureResult>;
46
+ install(spec: SystemServiceLaunchSpec): Promise<boolean>;
47
+ restart(): Promise<void>;
48
+ start(): Promise<void>;
49
+ stop(): Promise<void>;
50
+ uninstall(): Promise<void>;
51
+ status(): Promise<SystemServiceStatus>;
52
+ logs(lines?: number): Promise<string>;
53
+ }
54
+ export declare function renderSystemdUserUnit(home: string, spec: SystemServiceLaunchSpec): string;
55
+ export declare function serviceUnitName(home: string, defaultHome?: string): string;
56
+ export declare function systemdQuote(value: string): string;
57
+ //# sourceMappingURL=system-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-service.d.ts","sourceRoot":"","sources":["../../src/service/system-service.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAChD;AAED,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,0BAA0B,GAAG,CACvC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,SAAS,MAAM,EAAE,KACpB,OAAO,CAAC,0BAA0B,CAAC,CAAC;AAEzC,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,yBAA0B,SAAQ,mBAAmB;IACpE,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+EAA+E;IAC/E,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,2BAA2B;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,0BAA0B,CAAC;IACpC,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC;AAED;;;;GAIG;AACH,qBAAa,oBAAoB;;IAK/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,OAAO,EAAE,2BAA2B;IAW1C,aAAa,CAAC,IAAI,EAAE,uBAAuB,GAAG,OAAO,CAAC,yBAAyB,CAAC;IAiChF,OAAO,CAAC,IAAI,EAAE,uBAAuB,GAAG,OAAO,CAAC,OAAO,CAAC;IAcxD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAKxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ1B,MAAM,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAoBtC,IAAI,CAAC,KAAK,SAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CA+CzC;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,uBAAuB,GAAG,MAAM,CAiCzF;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,SAA6B,GAAG,MAAM,CAK9F;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMlD"}
@@ -0,0 +1,263 @@
1
+ import { createHash } from "node:crypto";
2
+ import { execFile } from "node:child_process";
3
+ import { access, mkdir, readFile, unlink } from "node:fs/promises";
4
+ import { homedir, userInfo } from "node:os";
5
+ import { dirname, join, normalize, resolve } from "node:path";
6
+ import { promisify } from "node:util";
7
+ import { atomicWriteFile } from "../storage/atomic.js";
8
+ const execFileAsync = promisify(execFile);
9
+ /**
10
+ * Installs and controls the per-user systemd service used by production clients.
11
+ * GUI/TUI callers never own the daemon process; their only lifecycle action is
12
+ * asking systemd to keep the authoritative service enabled and running.
13
+ */
14
+ export class SystemServiceManager {
15
+ #home;
16
+ #runner;
17
+ #username;
18
+ #beforeStart;
19
+ unitName;
20
+ unitPath;
21
+ constructor(options) {
22
+ this.#home = resolve(options.home);
23
+ this.#runner = options.runner ?? runSystemCommand;
24
+ this.#username = options.username ?? userInfo().username;
25
+ this.#beforeStart = options.beforeStart;
26
+ this.unitName = serviceUnitName(this.#home);
27
+ const configDirectory = options.userConfigDirectory
28
+ ?? resolve(process.env["XDG_CONFIG_HOME"] || join(homedir(), ".config"));
29
+ this.unitPath = join(configDirectory, "systemd", "user", this.unitName);
30
+ }
31
+ async ensureRunning(spec) {
32
+ const unitChanged = await this.install(spec);
33
+ if (unitChanged)
34
+ await this.#systemctl("daemon-reload");
35
+ const wasActive = await this.#isSystemctlState("is-active");
36
+ const recoveredFromFailure = wasActive ? false : await this.#resetFailedUnit();
37
+ if (!wasActive)
38
+ await this.#beforeStart?.();
39
+ if (unitChanged && wasActive) {
40
+ await this.#systemctl("restart", this.unitName);
41
+ }
42
+ else {
43
+ await this.#systemctl("enable", "--now", this.unitName);
44
+ }
45
+ let lingerWarning;
46
+ let linger = await this.#lingerEnabled();
47
+ if (linger === false) {
48
+ const result = await this.#runner("loginctl", ["--no-ask-password", "enable-linger", this.#username]);
49
+ if (result.code === 0)
50
+ linger = await this.#lingerEnabled();
51
+ else
52
+ lingerWarning = commandFailure("Could not enable boot-time user lingering", result);
53
+ }
54
+ const status = await this.status();
55
+ if (!status.active) {
56
+ throw new Error(status.detail ?? `System service ${this.unitName} did not become active`);
57
+ }
58
+ return {
59
+ ...status,
60
+ unitChanged,
61
+ ...(recoveredFromFailure ? { recoveredFromFailure } : {}),
62
+ ...(lingerWarning === undefined ? {} : { lingerWarning }),
63
+ };
64
+ }
65
+ async install(spec) {
66
+ const content = renderSystemdUserUnit(this.#home, spec);
67
+ let current;
68
+ try {
69
+ current = await readFile(this.unitPath, "utf8");
70
+ }
71
+ catch (error) {
72
+ if (!isNodeError(error) || error.code !== "ENOENT")
73
+ throw error;
74
+ }
75
+ if (current === content)
76
+ return false;
77
+ await mkdir(dirname(this.unitPath), { recursive: true, mode: 0o700 });
78
+ await atomicWriteFile(this.unitPath, content, 0o644);
79
+ return true;
80
+ }
81
+ async restart() {
82
+ await this.#resetFailedUnit();
83
+ await this.#systemctl("restart", this.unitName);
84
+ }
85
+ async start() {
86
+ await this.#resetFailedUnit();
87
+ await this.#systemctl("enable", "--now", this.unitName);
88
+ }
89
+ async stop() {
90
+ await this.#systemctl("stop", this.unitName);
91
+ }
92
+ async uninstall() {
93
+ await this.#runner("systemctl", ["--user", "disable", "--now", this.unitName]);
94
+ await unlink(this.unitPath).catch((error) => {
95
+ if (!isNodeError(error) || error.code !== "ENOENT")
96
+ throw error;
97
+ });
98
+ await this.#systemctl("daemon-reload");
99
+ }
100
+ async status() {
101
+ const installed = await access(this.unitPath).then(() => true, () => false);
102
+ const enabledResult = await this.#runner("systemctl", ["--user", "is-enabled", this.unitName]);
103
+ const activeResult = await this.#runner("systemctl", ["--user", "is-active", this.unitName]);
104
+ const enabled = enabledResult.code === 0 && enabledResult.stdout.trim() === "enabled";
105
+ const active = activeResult.code === 0 && activeResult.stdout.trim() === "active";
106
+ const detail = active
107
+ ? undefined
108
+ : [activeResult.stderr.trim(), activeResult.stdout.trim()].filter(Boolean).join(": ") || undefined;
109
+ return {
110
+ unitName: this.unitName,
111
+ unitPath: this.unitPath,
112
+ installed,
113
+ enabled,
114
+ active,
115
+ linger: await this.#lingerEnabled(),
116
+ ...(detail === undefined ? {} : { detail }),
117
+ };
118
+ }
119
+ async logs(lines = 100) {
120
+ if (!Number.isSafeInteger(lines) || lines < 1 || lines > 2_000) {
121
+ throw new Error("Service log line count must be between 1 and 2000");
122
+ }
123
+ const result = await this.#runner("journalctl", [
124
+ "--user-unit",
125
+ this.unitName,
126
+ "--lines",
127
+ String(lines),
128
+ "--no-pager",
129
+ "--output",
130
+ "short-iso",
131
+ ]);
132
+ if (result.code !== 0)
133
+ throw new Error(commandFailure("Could not read service logs", result));
134
+ return result.stdout;
135
+ }
136
+ async #systemctl(...args) {
137
+ const result = await this.#runner("systemctl", ["--user", ...args]);
138
+ if (result.code !== 0)
139
+ throw new Error(commandFailure(`systemctl --user ${args.join(" ")} failed`, result));
140
+ }
141
+ /**
142
+ * A daemon that crashes repeatedly trips `StartLimitBurst`, and systemd then
143
+ * refuses every further start with "start request repeated too quickly". The
144
+ * unit stays failed across client restarts, so clients report a permanently
145
+ * lost connection until the failure is cleared. Clearing it is safe: it only
146
+ * resets systemd's bookkeeping, never a running service.
147
+ */
148
+ async #resetFailedUnit() {
149
+ const result = await this.#runner("systemctl", ["--user", "is-failed", this.unitName]);
150
+ if (result.stdout.trim() !== "failed")
151
+ return false;
152
+ await this.#runner("systemctl", ["--user", "reset-failed", this.unitName]);
153
+ return true;
154
+ }
155
+ async #isSystemctlState(command) {
156
+ const result = await this.#runner("systemctl", ["--user", command, this.unitName]);
157
+ return result.code === 0 && result.stdout.trim() === (command === "is-active" ? "active" : "enabled");
158
+ }
159
+ async #lingerEnabled() {
160
+ const result = await this.#runner("loginctl", ["show-user", this.#username, "--property", "Linger", "--value"]);
161
+ if (result.code !== 0)
162
+ return undefined;
163
+ const value = result.stdout.trim().toLowerCase();
164
+ return value === "yes" ? true : value === "no" ? false : undefined;
165
+ }
166
+ }
167
+ export function renderSystemdUserUnit(home, spec) {
168
+ const executable = resolveExecutable(spec.executable);
169
+ const workingDirectory = resolve(spec.workingDirectory);
170
+ const command = [executable, ...spec.args].map(systemdQuote).join(" ");
171
+ const environment = Object.entries(spec.environment ?? {})
172
+ .sort(([left], [right]) => left.localeCompare(right))
173
+ .map(([key, value]) => {
174
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key))
175
+ throw new Error(`Invalid service environment name: ${key}`);
176
+ return `Environment=${systemdQuote(`${key}=${value}`)}`;
177
+ });
178
+ return [
179
+ "[Unit]",
180
+ "Description=pSpore local agent service",
181
+ "Documentation=https://github.com/advnljs/pSpore",
182
+ "StartLimitIntervalSec=30",
183
+ "StartLimitBurst=5",
184
+ "",
185
+ "[Service]",
186
+ "Type=simple",
187
+ `ExecStart=${command}`,
188
+ `WorkingDirectory=${systemdPath(workingDirectory)}`,
189
+ `Environment=${systemdQuote(`PSPORE_HOME=${resolve(home)}`)}`,
190
+ ...environment,
191
+ "UMask=0077",
192
+ "Restart=always",
193
+ "RestartSec=2",
194
+ "TimeoutStopSec=20",
195
+ "KillMode=mixed",
196
+ "",
197
+ "[Install]",
198
+ "WantedBy=default.target",
199
+ "",
200
+ ].join("\n");
201
+ }
202
+ export function serviceUnitName(home, defaultHome = join(homedir(), ".pspore")) {
203
+ const normalizedHome = normalize(resolve(home));
204
+ if (normalizedHome === normalize(resolve(defaultHome)))
205
+ return "pspore.service";
206
+ const suffix = createHash("sha256").update(normalizedHome).digest("hex").slice(0, 12);
207
+ return `pspore-${suffix}.service`;
208
+ }
209
+ export function systemdQuote(value) {
210
+ if (/[\r\n\u0000]/u.test(value))
211
+ throw new Error("System service arguments cannot contain newlines or NUL");
212
+ if (/[\u0001-\u0008\u000b\u000c\u000e-\u001f\u007f]/u.test(value)) {
213
+ throw new Error("System service arguments cannot contain control characters");
214
+ }
215
+ return `"${value.replaceAll("%", "%%").replaceAll("\\", "\\\\").replaceAll('"', '\\"')}"`;
216
+ }
217
+ /**
218
+ * Path-valued directives do not use ExecStart's command-line quoting rules.
219
+ * In particular, systemd 245 treats surrounding quotes as literal path bytes,
220
+ * so an otherwise absolute WorkingDirectory becomes invalid. Spaces are valid
221
+ * unquoted in this directive; percent signs still need escaping as specifiers.
222
+ */
223
+ function systemdPath(value) {
224
+ if (/\s$/u.test(value))
225
+ throw new Error("System service paths cannot end with whitespace");
226
+ if (/[\r\n\u0000]/u.test(value))
227
+ throw new Error("System service paths cannot contain newlines or NUL");
228
+ if (/[\u0001-\u0008\u000b\u000c\u000e-\u001f\u007f]/u.test(value)) {
229
+ throw new Error("System service paths cannot contain control characters");
230
+ }
231
+ return value.replaceAll("%", "%%");
232
+ }
233
+ async function runSystemCommand(executable, args) {
234
+ try {
235
+ const result = await execFileAsync(executable, [...args], {
236
+ encoding: "utf8",
237
+ timeout: 20_000,
238
+ maxBuffer: 1_048_576,
239
+ });
240
+ return { code: 0, stdout: result.stdout, stderr: result.stderr };
241
+ }
242
+ catch (error) {
243
+ const candidate = error;
244
+ return {
245
+ code: typeof candidate.code === "number" ? candidate.code : 1,
246
+ stdout: typeof candidate.stdout === "string" ? candidate.stdout : "",
247
+ stderr: typeof candidate.stderr === "string" ? candidate.stderr : candidate.message,
248
+ };
249
+ }
250
+ }
251
+ function resolveExecutable(value) {
252
+ if (!value.trim())
253
+ throw new Error("System service executable is required");
254
+ return value.includes("/") ? resolve(value) : value;
255
+ }
256
+ function commandFailure(prefix, result) {
257
+ const detail = result.stderr.trim() || result.stdout.trim() || `exit ${result.code}`;
258
+ return `${prefix}: ${detail}`;
259
+ }
260
+ function isNodeError(error) {
261
+ return error instanceof Error && "code" in error;
262
+ }
263
+ //# sourceMappingURL=system-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-service.js","sourceRoot":"","sources":["../../src/service/system-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import type { RootSessionMetadata } from "../domain/runtime.js";
2
+ export interface RootSessionRecord extends RootSessionMetadata {
3
+ id: string;
4
+ sessionFile: string;
5
+ cwd: string;
6
+ titleSource: "default" | "user" | "prompt";
7
+ }
8
+ export interface SessionCatalogOptions {
9
+ path: string;
10
+ sessionsRoot: string;
11
+ workspaceId: string;
12
+ cwd: string;
13
+ clock?: () => Date;
14
+ }
15
+ export declare class SessionCatalog {
16
+ #private;
17
+ private constructor();
18
+ static open(options: SessionCatalogOptions): Promise<SessionCatalog>;
19
+ list(): RootSessionRecord[];
20
+ get(id: string): RootSessionRecord | undefined;
21
+ idle(): Promise<void>;
22
+ add(input: {
23
+ id: string;
24
+ sessionFile: string;
25
+ cwd: string;
26
+ title?: string;
27
+ }): Promise<RootSessionRecord>;
28
+ /**
29
+ * Forgets a root session and deletes the transcript it owns.
30
+ *
31
+ * The stored path is re-resolved against the sessions root before anything is
32
+ * unlinked, so a catalog entry that points outside the root loses its record
33
+ * without the filesystem being touched. Deleting is the point of the command,
34
+ * so a transcript that is already gone is not an error.
35
+ */
36
+ remove(id: string): Promise<{
37
+ record: RootSessionRecord;
38
+ transcriptRemoved: boolean;
39
+ } | undefined>;
40
+ touch(id: string, options?: {
41
+ prompt?: string;
42
+ sessionFile?: string;
43
+ }): Promise<RootSessionRecord | undefined>;
44
+ }
45
+ //# sourceMappingURL=session-catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-catalog.d.ts","sourceRoot":"","sources":["../../src/sessions/session-catalog.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAIhE,MAAM,WAAW,iBAAkB,SAAQ,mBAAmB;IAC5D,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;CAC5C;AAOD,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,qBAAa,cAAc;;IASzB,OAAO;WAQM,IAAI,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,cAAc,CAAC;IAM1E,IAAI,IAAI,iBAAiB,EAAE;IAM3B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAKxC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,GAAG,CAAC,KAAK,EAAE;QACf,EAAE,EAAE,MAAM,CAAC;QACX,WAAW,EAAE,MAAM,CAAC;QACpB,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAsB9B;;;;;;;OAOG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,iBAAiB,CAAC;QAAC,iBAAiB,EAAE,OAAO,CAAA;KAAE,GAAG,SAAS,CAAC;IAmBlG,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC;CAiGzH"}