ptbk 0.119.0-16 → 0.119.0-21

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 (330) hide show
  1. package/README.md +27 -9
  2. package/dist/book/commitments.d.ts +38 -10
  3. package/dist/book/commitments.js +61 -17
  4. package/dist/book/commitments.js.map +1 -1
  5. package/dist/book/convert.d.ts +36 -0
  6. package/dist/book/convert.js +156 -0
  7. package/dist/book/convert.js.map +1 -0
  8. package/dist/book/parse.d.ts +50 -13
  9. package/dist/book/parse.js +132 -45
  10. package/dist/book/parse.js.map +1 -1
  11. package/dist/book/references.d.ts +12 -4
  12. package/dist/book/references.js +34 -9
  13. package/dist/book/references.js.map +1 -1
  14. package/dist/book/write.d.ts +42 -0
  15. package/dist/book/write.js +74 -0
  16. package/dist/book/write.js.map +1 -0
  17. package/dist/browser/browser.d.ts +122 -12
  18. package/dist/browser/browser.js +372 -21
  19. package/dist/browser/browser.js.map +1 -1
  20. package/dist/browser/recording.d.ts +3 -3
  21. package/dist/browser/recording.js +5 -5
  22. package/dist/browser/recording.js.map +1 -1
  23. package/dist/chats/chat-book.d.ts +105 -0
  24. package/dist/chats/chat-book.js +180 -0
  25. package/dist/chats/chat-book.js.map +1 -0
  26. package/dist/chats/conversation.d.ts +54 -0
  27. package/dist/chats/conversation.js +188 -0
  28. package/dist/chats/conversation.js.map +1 -0
  29. package/dist/chats/local.d.ts +46 -0
  30. package/dist/chats/local.js +184 -0
  31. package/dist/chats/local.js.map +1 -0
  32. package/dist/chats/migration.d.ts +12 -0
  33. package/dist/chats/migration.js +62 -0
  34. package/dist/chats/migration.js.map +1 -0
  35. package/dist/chats/service.d.ts +81 -0
  36. package/dist/chats/service.js +122 -0
  37. package/dist/chats/service.js.map +1 -0
  38. package/dist/chats/store.d.ts +132 -0
  39. package/dist/chats/store.js +181 -0
  40. package/dist/chats/store.js.map +1 -0
  41. package/dist/chats/task-chats.d.ts +52 -0
  42. package/dist/chats/task-chats.js +96 -0
  43. package/dist/chats/task-chats.js.map +1 -0
  44. package/dist/cli/chats.d.ts +45 -0
  45. package/dist/cli/chats.js +108 -0
  46. package/dist/cli/chats.js.map +1 -0
  47. package/dist/cli/commands/add.js +32 -22
  48. package/dist/cli/commands/add.js.map +1 -1
  49. package/dist/cli/commands/answer.d.ts +2 -1
  50. package/dist/cli/commands/answer.js +35 -41
  51. package/dist/cli/commands/answer.js.map +1 -1
  52. package/dist/cli/commands/ask.d.ts +7 -0
  53. package/dist/cli/commands/ask.js +37 -0
  54. package/dist/cli/commands/ask.js.map +1 -0
  55. package/dist/cli/commands/boilerplates.js +14 -3
  56. package/dist/cli/commands/boilerplates.js.map +1 -1
  57. package/dist/cli/commands/chat.d.ts +9 -0
  58. package/dist/cli/commands/chat.js +89 -0
  59. package/dist/cli/commands/chat.js.map +1 -0
  60. package/dist/cli/commands/dashboard.d.ts +3 -1
  61. package/dist/cli/commands/dashboard.js +41 -3
  62. package/dist/cli/commands/dashboard.js.map +1 -1
  63. package/dist/cli/commands/find.js +6 -8
  64. package/dist/cli/commands/find.js.map +1 -1
  65. package/dist/cli/commands/fix.js +4 -6
  66. package/dist/cli/commands/fix.js.map +1 -1
  67. package/dist/cli/commands/init.d.ts +0 -1
  68. package/dist/cli/commands/init.js +38 -38
  69. package/dist/cli/commands/init.js.map +1 -1
  70. package/dist/cli/commands/lint.js +16 -2
  71. package/dist/cli/commands/lint.js.map +1 -1
  72. package/dist/cli/commands/list.js +21 -13
  73. package/dist/cli/commands/list.js.map +1 -1
  74. package/dist/cli/commands/migrate.d.ts +2 -1
  75. package/dist/cli/commands/migrate.js +70 -24
  76. package/dist/cli/commands/migrate.js.map +1 -1
  77. package/dist/cli/commands/pause.d.ts +8 -0
  78. package/dist/cli/commands/pause.js +40 -0
  79. package/dist/cli/commands/pause.js.map +1 -0
  80. package/dist/cli/commands/plan.js +6 -9
  81. package/dist/cli/commands/plan.js.map +1 -1
  82. package/dist/cli/commands/recover.js +7 -3
  83. package/dist/cli/commands/recover.js.map +1 -1
  84. package/dist/cli/commands/restart.d.ts +3 -1
  85. package/dist/cli/commands/restart.js +74 -18
  86. package/dist/cli/commands/restart.js.map +1 -1
  87. package/dist/cli/commands/resume.d.ts +8 -0
  88. package/dist/cli/commands/resume.js +15 -0
  89. package/dist/cli/commands/resume.js.map +1 -0
  90. package/dist/cli/commands/run.js +6 -9
  91. package/dist/cli/commands/run.js.map +1 -1
  92. package/dist/cli/commands/start.js +40 -36
  93. package/dist/cli/commands/start.js.map +1 -1
  94. package/dist/cli/commands/status.d.ts +2 -1
  95. package/dist/cli/commands/status.js +5 -1
  96. package/dist/cli/commands/status.js.map +1 -1
  97. package/dist/cli/commands/stop.d.ts +3 -1
  98. package/dist/cli/commands/stop.js +18 -8
  99. package/dist/cli/commands/stop.js.map +1 -1
  100. package/dist/cli/commands/verify.js +7 -7
  101. package/dist/cli/commands/verify.js.map +1 -1
  102. package/dist/cli/common.d.ts +13 -0
  103. package/dist/cli/common.js +22 -0
  104. package/dist/cli/common.js.map +1 -1
  105. package/dist/cli/engine-delegation.d.ts +14 -0
  106. package/dist/cli/engine-delegation.js +46 -0
  107. package/dist/cli/engine-delegation.js.map +1 -0
  108. package/dist/cli/lifecycle.d.ts +40 -0
  109. package/dist/cli/lifecycle.js +71 -0
  110. package/dist/cli/lifecycle.js.map +1 -0
  111. package/dist/cli/registry.js +113 -31
  112. package/dist/cli/registry.js.map +1 -1
  113. package/dist/cli/service-view.d.ts +14 -2
  114. package/dist/cli/service-view.js +46 -5
  115. package/dist/cli/service-view.js.map +1 -1
  116. package/dist/cli/sources.js +5 -8
  117. package/dist/cli/sources.js.map +1 -1
  118. package/dist/cli/spec.js +1 -1
  119. package/dist/cli/spec.js.map +1 -1
  120. package/dist/common/app-data.d.ts +9 -0
  121. package/dist/common/app-data.js +20 -0
  122. package/dist/common/app-data.js.map +1 -0
  123. package/dist/common/errors.d.ts +2 -0
  124. package/dist/common/errors.js.map +1 -1
  125. package/dist/common/time.d.ts +6 -0
  126. package/dist/common/time.js +9 -0
  127. package/dist/common/time.js.map +1 -1
  128. package/dist/engine/agenda.d.ts +213 -43
  129. package/dist/engine/agenda.js +846 -260
  130. package/dist/engine/agenda.js.map +1 -1
  131. package/dist/engine/executor.d.ts +23 -7
  132. package/dist/engine/executor.js +131 -84
  133. package/dist/engine/executor.js.map +1 -1
  134. package/dist/engine/generated.d.ts +21 -1
  135. package/dist/engine/generated.js +36 -21
  136. package/dist/engine/generated.js.map +1 -1
  137. package/dist/engine/preview.js +10 -10
  138. package/dist/engine/preview.js.map +1 -1
  139. package/dist/engine/prompt.d.ts +16 -4
  140. package/dist/engine/prompt.js +22 -4
  141. package/dist/engine/prompt.js.map +1 -1
  142. package/dist/engine/routing.js +28 -4
  143. package/dist/engine/routing.js.map +1 -1
  144. package/dist/engine/snapshot.d.ts +178 -29
  145. package/dist/engine/state.d.ts +40 -13
  146. package/dist/engine/state.js +20 -5
  147. package/dist/engine/state.js.map +1 -1
  148. package/dist/engine/task-trace.d.ts +35 -7
  149. package/dist/engine/task-trace.js +74 -15
  150. package/dist/engine/task-trace.js.map +1 -1
  151. package/dist/engine/team.d.ts +20 -7
  152. package/dist/engine/team.js +30 -24
  153. package/dist/engine/team.js.map +1 -1
  154. package/dist/engine/traces.d.ts +1 -1
  155. package/dist/engine/traces.js +1 -1
  156. package/dist/expert/_main.md +67 -52
  157. package/dist/expert/agents/_index.md +11 -13
  158. package/dist/expert/agents/chatter.md +31 -0
  159. package/dist/expert/agents/consistency.md +6 -11
  160. package/dist/expert/agents/core-agents.md +9 -7
  161. package/dist/expert/agents/expert.md +2 -2
  162. package/dist/expert/agents/fixer.md +24 -0
  163. package/dist/expert/agents/learning.md +1 -1
  164. package/dist/expert/agents/non-agents.md +6 -4
  165. package/dist/expert/agents/teacher.md +1 -1
  166. package/dist/expert/agents/visual-identity.md +4 -4
  167. package/dist/expert/book-language/_index.md +9 -8
  168. package/dist/expert/book-language/commitments/_index.md +23 -3
  169. package/dist/expert/book-language/commitments/agent.md +11 -0
  170. package/dist/expert/book-language/commitments/chat-member.md +7 -0
  171. package/dist/expert/book-language/commitments/chat-message.md +11 -0
  172. package/dist/expert/book-language/commitments/chat-status.md +7 -0
  173. package/dist/expert/book-language/commitments/chat.md +11 -0
  174. package/dist/expert/book-language/commitments/entity.md +9 -0
  175. package/dist/expert/book-language/commitments/from.md +1 -1
  176. package/dist/expert/book-language/commitments/goal.md +6 -2
  177. package/dist/expert/book-language/commitments/link.md +9 -0
  178. package/dist/expert/book-language/commitments/task-depends-on.md +1 -1
  179. package/dist/expert/book-language/commitments/task-parent.md +1 -1
  180. package/dist/expert/book-language/commitments/task.md +7 -3
  181. package/dist/expert/book-language/commitments/team.md +1 -1
  182. package/dist/expert/book-language/inheritance.md +2 -2
  183. package/dist/expert/book-language/references.md +20 -24
  184. package/dist/expert/book-language/syntax.md +54 -11
  185. package/dist/expert/cli/acceptance.md +59 -24
  186. package/dist/expert/cli/api.md +23 -9
  187. package/dist/expert/cli/authoring.md +6 -4
  188. package/dist/expert/cli/autonomous-operation.md +3 -3
  189. package/dist/expert/cli/browser.md +29 -18
  190. package/dist/expert/cli/channels.md +5 -7
  191. package/dist/expert/cli/chat-ui.md +32 -0
  192. package/dist/expert/cli/chats.md +59 -0
  193. package/dist/expert/cli/cli.md +44 -26
  194. package/dist/expert/cli/configuration.md +3 -3
  195. package/dist/expert/cli/controls.md +13 -7
  196. package/dist/expert/cli/dashboard-details.md +23 -0
  197. package/dist/expert/cli/dashboard-layout.md +19 -12
  198. package/dist/expert/cli/dashboard.md +12 -8
  199. package/dist/expert/cli/execution.md +8 -6
  200. package/dist/expert/cli/first-task.md +4 -4
  201. package/dist/expert/cli/generated-names.md +44 -0
  202. package/dist/expert/cli/git-persistence.md +19 -17
  203. package/dist/expert/cli/global-dashboard.md +33 -0
  204. package/dist/expert/cli/goal-discovery.md +1 -1
  205. package/dist/expert/cli/help.md +1 -1
  206. package/dist/expert/cli/initialization-ui.md +2 -0
  207. package/dist/expert/cli/initialization.md +9 -7
  208. package/dist/expert/cli/interactive-ui.md +9 -5
  209. package/dist/expert/cli/locking.md +21 -0
  210. package/dist/expert/cli/migration.md +22 -6
  211. package/dist/expert/cli/process-modes.md +21 -13
  212. package/dist/expert/cli/recovery.md +8 -6
  213. package/dist/expert/cli/recurrence.md +1 -1
  214. package/dist/expert/cli/rich-input.md +2 -2
  215. package/dist/expert/cli/service-lifecycle.md +57 -0
  216. package/dist/expert/cli/start.md +2 -2
  217. package/dist/expert/cli/status-view.md +16 -12
  218. package/dist/expert/cli/task-books.md +11 -15
  219. package/dist/expert/cli/task-identity.md +8 -10
  220. package/dist/expert/cli/task-markdown.md +6 -10
  221. package/dist/expert/cli/task-origins.md +3 -1
  222. package/dist/expert/cli/task-relationships.md +5 -9
  223. package/dist/expert/cli/team.md +17 -7
  224. package/dist/expert/cli/terminal.md +20 -12
  225. package/dist/expert/cli/trace-configuration.md +1 -1
  226. package/dist/expert/cli/traces.md +19 -23
  227. package/dist/expert/cli/user-interactions.md +14 -26
  228. package/dist/expert/cli/workspace.md +15 -9
  229. package/dist/expert/concepts/engine-and-project.md +11 -0
  230. package/dist/expert/concepts/project-model.md +39 -0
  231. package/dist/expert/dictionary.md +21 -15
  232. package/dist/harness/plugins/claude-code/index.js +1 -0
  233. package/dist/harness/plugins/claude-code/index.js.map +1 -1
  234. package/dist/harness/plugins/cline/index.js +1 -0
  235. package/dist/harness/plugins/cline/index.js.map +1 -1
  236. package/dist/harness/plugins/openai-codex/index.js +1 -0
  237. package/dist/harness/plugins/openai-codex/index.js.map +1 -1
  238. package/dist/harness/plugins/opencode/index.js +1 -0
  239. package/dist/harness/plugins/opencode/index.js.map +1 -1
  240. package/dist/harness/types.d.ts +3 -1
  241. package/dist/project/agents.d.ts +29 -81
  242. package/dist/project/agents.js +48 -267
  243. package/dist/project/agents.js.map +1 -1
  244. package/dist/project/books.d.ts +150 -0
  245. package/dist/project/books.js +253 -0
  246. package/dist/project/books.js.map +1 -0
  247. package/dist/project/config.js +2 -2
  248. package/dist/project/config.js.map +1 -1
  249. package/dist/project/defaults.d.ts +35 -6
  250. package/dist/project/defaults.js +73 -40
  251. package/dist/project/defaults.js.map +1 -1
  252. package/dist/project/expert.js +18 -10
  253. package/dist/project/expert.js.map +1 -1
  254. package/dist/project/git.d.ts +4 -3
  255. package/dist/project/git.js +16 -5
  256. package/dist/project/git.js.map +1 -1
  257. package/dist/project/setup.d.ts +4 -1
  258. package/dist/project/setup.js +26 -6
  259. package/dist/project/setup.js.map +1 -1
  260. package/dist/service/actions.d.ts +34 -10
  261. package/dist/service/actions.js +51 -19
  262. package/dist/service/actions.js.map +1 -1
  263. package/dist/service/control.d.ts +53 -1
  264. package/dist/service/control.js +64 -4
  265. package/dist/service/control.js.map +1 -1
  266. package/dist/service/discovery.d.ts +133 -0
  267. package/dist/service/discovery.js +138 -0
  268. package/dist/service/discovery.js.map +1 -0
  269. package/dist/service/host.d.ts +8 -1
  270. package/dist/service/host.js +65 -18
  271. package/dist/service/host.js.map +1 -1
  272. package/dist/service/http.d.ts +3 -0
  273. package/dist/service/http.js +26 -6
  274. package/dist/service/http.js.map +1 -1
  275. package/dist/service/launcher.d.ts +66 -13
  276. package/dist/service/launcher.js +78 -18
  277. package/dist/service/launcher.js.map +1 -1
  278. package/dist/service/records.d.ts +12 -2
  279. package/dist/service/records.js +19 -5
  280. package/dist/service/records.js.map +1 -1
  281. package/dist/service/spa/app.css +83 -2
  282. package/dist/service/spa/app.js +393 -72
  283. package/dist/service/supervisor.js +7 -1
  284. package/dist/service/supervisor.js.map +1 -1
  285. package/dist/service/worker.js +14 -5
  286. package/dist/service/worker.js.map +1 -1
  287. package/dist/tasks/authoring.d.ts +3 -5
  288. package/dist/tasks/authoring.js +6 -7
  289. package/dist/tasks/authoring.js.map +1 -1
  290. package/dist/tasks/book-task.d.ts +18 -10
  291. package/dist/tasks/book-task.js +27 -23
  292. package/dist/tasks/book-task.js.map +1 -1
  293. package/dist/tasks/eligibility.d.ts +15 -7
  294. package/dist/tasks/eligibility.js +41 -14
  295. package/dist/tasks/eligibility.js.map +1 -1
  296. package/dist/tasks/identity.d.ts +41 -15
  297. package/dist/tasks/identity.js +100 -31
  298. package/dist/tasks/identity.js.map +1 -1
  299. package/dist/tasks/markdown.d.ts +7 -14
  300. package/dist/tasks/markdown.js +15 -29
  301. package/dist/tasks/markdown.js.map +1 -1
  302. package/dist/tasks/model.d.ts +20 -4
  303. package/dist/tasks/model.js +17 -0
  304. package/dist/tasks/model.js.map +1 -1
  305. package/dist/tasks/sources.d.ts +7 -2
  306. package/dist/tasks/sources.js +46 -35
  307. package/dist/tasks/sources.js.map +1 -1
  308. package/dist/ui/chat-client.d.ts +70 -0
  309. package/dist/ui/chat-client.js +209 -0
  310. package/dist/ui/chat-client.js.map +1 -0
  311. package/dist/ui/dashboard.d.ts +8 -5
  312. package/dist/ui/dashboard.js +227 -86
  313. package/dist/ui/dashboard.js.map +1 -1
  314. package/dist/ui/details.d.ts +64 -0
  315. package/dist/ui/details.js +175 -0
  316. package/dist/ui/details.js.map +1 -0
  317. package/dist/ui/global-dashboard.d.ts +59 -0
  318. package/dist/ui/global-dashboard.js +307 -0
  319. package/dist/ui/global-dashboard.js.map +1 -0
  320. package/dist/ui/status-view.d.ts +7 -0
  321. package/dist/ui/status-view.js +94 -36
  322. package/dist/ui/status-view.js.map +1 -1
  323. package/package.json +1 -1
  324. package/dist/engine/requests.d.ts +0 -111
  325. package/dist/engine/requests.js +0 -173
  326. package/dist/engine/requests.js.map +0 -1
  327. package/dist/expert/book-language/commitments/task-id.md +0 -9
  328. package/dist/tasks/prepare.d.ts +0 -33
  329. package/dist/tasks/prepare.js +0 -90
  330. package/dist/tasks/prepare.js.map +0 -1
@@ -1,27 +1,51 @@
1
1
  import type { Agenda } from '../engine/agenda.js';
2
- import type { UserRequest } from '../engine/requests.js';
3
2
  /**
4
- * Runtime actions shared by every channel (terminal, browser, API, CLI).
3
+ * Runtime actions shared by every channel (CLI, terminal, browser, API): the engine's lifecycle operations, wait
4
+ * skipping and coordinated project-browser recovery. `stop-now`/`cancel-stop` remain as compatibility aliases.
5
5
  *
6
6
  * @private shared runtime controls
7
7
  */
8
- export type ControlAction = 'pause' | 'resume' | 'skip-wait' | 'stop' | 'stop-now' | 'cancel-stop';
8
+ export type ControlAction = 'pause' | 'resume' | 'skip-wait' | 'stop' | 'force-stop' | 'restart' | 'stop-now' | 'cancel-stop' | 'browser-recheck' | 'browser-retry' | 'browser-restart';
9
9
  /**
10
- * Applies one runtime control action and reports its actual outcome.
10
+ * Every control action name (for request validation).
11
11
  *
12
12
  * @private shared runtime controls
13
13
  */
14
- export declare function applyControlAction(agenda: Agenda, action: string): {
15
- action: string;
16
- outcome: string;
17
- applied: boolean;
14
+ export declare const CONTROL_ACTIONS: ReadonlySet<string>;
15
+ /**
16
+ * Outcome of a control action as every client reports it.
17
+ *
18
+ * @private shared runtime controls
19
+ */
20
+ export type ControlOutcome = {
21
+ readonly action: string;
22
+ readonly outcome: string;
23
+ readonly applied: boolean;
24
+ readonly completed?: boolean;
25
+ readonly state?: string;
18
26
  };
19
27
  /**
20
- * Validates and applies an answer from any channel.
28
+ * Engine-owned browser recovery operations (the service owns the project browser).
29
+ *
30
+ * @private shared runtime controls
31
+ */
32
+ export type BrowserControls = {
33
+ readonly recheck: () => Promise<ControlOutcome>;
34
+ readonly retry: () => Promise<ControlOutcome>;
35
+ readonly restart: () => Promise<ControlOutcome>;
36
+ };
37
+ /**
38
+ * Applies one runtime control action and reports its actual outcome (accepted/pending versus completed).
39
+ *
40
+ * @private shared runtime controls
41
+ */
42
+ export declare function applyControlAction(agenda: Agenda, action: string, params?: Readonly<Record<string, unknown>>, browser?: BrowserControls): Promise<ControlOutcome>;
43
+ /**
44
+ * Chat operations shared by every channel (terminal, browser, API, CLI); writes go through the agenda's chat store.
21
45
  *
22
46
  * @private shared runtime controls
23
47
  */
24
- export declare function applyAnswer(agenda: Agenda, params: Readonly<Record<string, unknown>>, via: UserRequest['resolvedVia']): Promise<UserRequest>;
48
+ export declare function applyChatAction(agenda: Agenda, method: string, params: Readonly<Record<string, unknown>>, via: string): Promise<unknown>;
25
49
  /**
26
50
  * Validates raw setting changes from a channel and applies them (temporary unless saved).
27
51
  *
@@ -1,46 +1,78 @@
1
1
  import { PtbkError } from '../common/errors.js';
2
2
  import { parseSettingValue, SETTING_SPEC_BY_KEY } from '../project/config.js';
3
+ import { defaultChatAgent } from '../chats/service.js';
3
4
  /**
4
- * Applies one runtime control action and reports its actual outcome.
5
+ * Every control action name (for request validation).
5
6
  *
6
7
  * @private shared runtime controls
7
8
  */
8
- export function applyControlAction(agenda, action) {
9
+ export const CONTROL_ACTIONS = new Set(['pause', 'resume', 'skip-wait', 'stop', 'force-stop', 'restart', 'stop-now', 'cancel-stop', 'browser-recheck', 'browser-retry', 'browser-restart']);
10
+ /**
11
+ * Applies one runtime control action and reports its actual outcome (accepted/pending versus completed).
12
+ *
13
+ * @private shared runtime controls
14
+ */
15
+ export async function applyControlAction(agenda, action, params = {}, browser) {
9
16
  switch (action) {
10
17
  case 'pause':
11
- return { action, outcome: agenda.pause().state === 'pausing' ? 'Pause pending: the current task finishes first.' : 'Paused.', applied: true };
18
+ return agenda.pause({ replaceStop: params.replaceStop === true, revision: typeof params.revision === 'number' ? params.revision : undefined });
12
19
  case 'resume':
13
- agenda.resume();
14
- return { action, outcome: 'Resumed.', applied: true };
20
+ return agenda.resume();
15
21
  case 'skip-wait': {
16
22
  const result = agenda.skipWait();
17
23
  return { action, outcome: result.applied ? 'Wait skipped.' : (result.reason ?? 'Nothing to skip.'), applied: result.applied };
18
24
  }
19
25
  case 'stop':
20
- agenda.requestStop({ cancelCurrent: false });
21
- return { action, outcome: 'Stopping after the current task.', applied: true };
26
+ return agenda.requestStop({});
27
+ case 'force-stop':
22
28
  case 'stop-now':
23
- agenda.requestStop({ cancelCurrent: true });
24
- return { action, outcome: 'Stopping now; owned work is cancelled and recoverable.', applied: true };
29
+ return agenda.requestStop({ force: true });
30
+ case 'restart':
31
+ return agenda.requestStop({ restart: true });
25
32
  case 'cancel-stop':
26
- agenda.cancelStop();
27
- return { action, outcome: 'Stop cancelled (if it had not taken effect).', applied: true };
33
+ return agenda.cancelStop();
34
+ case 'browser-recheck':
35
+ case 'browser-retry':
36
+ case 'browser-restart': {
37
+ if (!browser)
38
+ return { action, outcome: 'This process does not own a project browser.', applied: false };
39
+ return action === 'browser-recheck' ? await browser.recheck() : action === 'browser-retry' ? await browser.retry() : await browser.restart();
40
+ }
28
41
  default:
29
42
  throw new PtbkError(`Unknown control action "${action}".`, { kind: 'usage' });
30
43
  }
31
44
  }
32
45
  /**
33
- * Validates and applies an answer from any channel.
46
+ * Chat operations shared by every channel (terminal, browser, API, CLI); writes go through the agenda's chat store.
34
47
  *
35
48
  * @private shared runtime controls
36
49
  */
37
- export async function applyAnswer(agenda, params, via) {
38
- const id = String(params.id ?? '');
39
- const status = params.status ?? 'answered';
40
- if (!['answered', 'cancelled', 'rejected', 'unable'].includes(status))
41
- throw new PtbkError(`Invalid answer status ${status}.`, { kind: 'usage' });
42
- const answer = typeof params.answer === 'string' ? params.answer : '';
43
- return await agenda.answer(id, answer, via, status);
50
+ export async function applyChatAction(agenda, method, params, via) {
51
+ const text = (key) => (typeof params[key] === 'string' ? params[key] : '');
52
+ switch (method) {
53
+ case 'chat-list':
54
+ return await agenda.chatList();
55
+ case 'chat-agents':
56
+ return agenda.chatAgents();
57
+ case 'chat-get':
58
+ return await agenda.chatGet(text('name'));
59
+ case 'chat-read':
60
+ await agenda.chatRead(text('name'));
61
+ return { read: true };
62
+ case 'chat-create': {
63
+ // A new human chat without an explicit target goes to Chatter (diagnosed, never silently replaced).
64
+ const agent = text('agent') || defaultChatAgent(agenda.chatAgents()).reference;
65
+ const written = await agenda.chatCreate(agent, text('text'), { name: text('title') || undefined, requestKey: text('requestKey') || undefined });
66
+ return { name: written.chat.name, path: written.relativePath, commit: written.commit, messages: written.chat.messages.length };
67
+ }
68
+ case 'chat-send': {
69
+ const expected = typeof params.expected === 'number' ? params.expected : undefined;
70
+ const written = await agenda.chatSend(text('name'), text('text'), { expected, via });
71
+ return { name: written.chat.name, path: written.relativePath, commit: written.commit, messages: written.chat.messages.length, status: written.chat.status };
72
+ }
73
+ default:
74
+ throw new PtbkError(`Unknown chat action "${method}".`, { kind: 'usage' });
75
+ }
44
76
  }
45
77
  /**
46
78
  * Validates raw setting changes from a channel and applies them (temporary unless saved).
@@ -1 +1 @@
1
- {"version":3,"file":"actions.js","sourceRoot":"","sources":["../../src/service/actions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"actions.js","sourceRoot":"","sources":["../../src/service/actions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE9E,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAUvD;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAwB,IAAI,GAAG,CAAgB,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,iBAAiB,EAAE,eAAe,EAAE,iBAAiB,CAAC,CAAC,CAAC;AAoBhO;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAc,EAAE,MAAc,EAAE,SAA4C,EAAE,EAAE,OAAyB;IAC9I,QAAQ,MAAM,EAAE,CAAC;QACb,KAAK,OAAO;YACR,OAAO,MAAM,CAAC,KAAK,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,KAAK,IAAI,EAAE,QAAQ,EAAE,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;QACnJ,KAAK,QAAQ;YACT,OAAO,MAAM,CAAC,MAAM,EAAE,CAAC;QAC3B,KAAK,WAAW,CAAC,CAAC,CAAC;YACf,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;YACjC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,kBAAkB,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;QAClI,CAAC;QACD,KAAK,MAAM;YACP,OAAO,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAClC,KAAK,YAAY,CAAC;QAClB,KAAK,UAAU;YACX,OAAO,MAAM,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,KAAK,SAAS;YACV,OAAO,MAAM,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QACjD,KAAK,aAAa;YACd,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC;QAC/B,KAAK,iBAAiB,CAAC;QACvB,KAAK,eAAe,CAAC;QACrB,KAAK,iBAAiB,CAAC,CAAC,CAAC;YACrB,IAAI,CAAC,OAAO;gBAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,8CAA8C,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;YACzG,OAAO,MAAM,KAAK,iBAAiB,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,eAAe,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QACjJ,CAAC;QACD;YACI,MAAM,IAAI,SAAS,CAAC,2BAA2B,MAAM,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IACtF,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAAc,EAAE,MAAc,EAAE,MAAyC,EAAE,GAAW;IACxH,MAAM,IAAI,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,CAAC,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAE,MAAM,CAAC,GAAG,CAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACvG,QAAQ,MAAM,EAAE,CAAC;QACb,KAAK,WAAW;YACZ,OAAO,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;QACnC,KAAK,aAAa;YACd,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC;QAC/B,KAAK,UAAU;YACX,OAAO,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9C,KAAK,WAAW;YACZ,MAAM,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YACpC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QAC1B,KAAK,aAAa,CAAC,CAAC,CAAC;YACjB,oGAAoG;YACpG,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,gBAAgB,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,SAAS,CAAC;YAC/E,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,SAAS,EAAE,CAAC,CAAC;YAChJ,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QACnI,CAAC;QACD,KAAK,WAAW,CAAC,CAAC,CAAC;YACf,MAAM,QAAQ,GAAG,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;YACnF,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;YACrF,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAChK,CAAC;QACD;YACI,MAAM,IAAI,SAAS,CAAC,wBAAwB,MAAM,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IACnF,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAAc,EAAE,MAAyC;IACzF,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAA4B,CAAC;IAC9D,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,qCAAqC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IACzI,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,GAAG,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC1C,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,SAAS,CAAC,mBAAmB,GAAG,GAAG,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAC7E,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC9C,IAAI,CAAC,MAAM,CAAC,EAAE;YAAE,MAAM,IAAI,SAAS,CAAC,qBAAqB,GAAG,KAAK,MAAM,CAAC,OAAO,GAAG,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QACvG,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC;IAC/B,CAAC;IACD,OAAO,MAAM,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AACrE,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { PtbkError } from '../common/errors.js';
1
2
  import { type IpcServer } from '../common/ipc.js';
2
3
  import type { Project } from '../project/workspace.js';
3
4
  import { type ProcessRecord } from './records.js';
@@ -7,6 +8,52 @@ import { type ProcessRecord } from './records.js';
7
8
  * @private service control
8
9
  */
9
10
  export declare const READ_ONLY_METHODS: Set<string>;
11
+ /**
12
+ * Version of the control contract: the shapes of snapshots and control replies that clients render.
13
+ *
14
+ * Engines and clients of different ptbk versions interoperate only when their contracts match. Bump it with every
15
+ * change that a client of the previous contract could misread (a removed, renamed or retyped field or method); a new
16
+ * snapshot field keeps the contract only when it is optional, so clients must handle its absence.
17
+ *
18
+ * @private service control
19
+ */
20
+ export declare const CONTROL_CONTRACT = 2;
21
+ /**
22
+ * Identity of the engine behind a control endpoint, as reported by its `identify` method.
23
+ *
24
+ * @private service control
25
+ */
26
+ export type EngineIdentity = {
27
+ /** Engine version actually loaded by the service (not this client's version). */
28
+ readonly version: string;
29
+ /** Control contract of the engine (absent for engines that predate it). */
30
+ readonly contract?: number;
31
+ /** Whether this client can read the engine's snapshots. */
32
+ readonly compatible: boolean;
33
+ };
34
+ /**
35
+ * Whether this client can read snapshots of an engine: the same version, or a matching control contract.
36
+ *
37
+ * @private service control
38
+ */
39
+ export declare function engineIdentityOf(reported: {
40
+ readonly version?: unknown;
41
+ readonly contract?: unknown;
42
+ }, record: ProcessRecord): EngineIdentity;
43
+ /**
44
+ * CLI entry point of the installation that runs a service (it may since have been removed or upgraded).
45
+ *
46
+ * @private service control
47
+ */
48
+ export declare function engineBin(record: ProcessRecord): string;
49
+ /**
50
+ * Actionable error of a client that cannot read the snapshots of an engine of another version.
51
+ *
52
+ * @private service control
53
+ */
54
+ export declare function incompatibleEngineError(project: Project, record: ProcessRecord, engine: EngineIdentity, options?: {
55
+ readonly installationGone?: boolean;
56
+ }): PtbkError;
10
57
  /**
11
58
  * Handler of control methods.
12
59
  *
@@ -27,6 +74,7 @@ export declare function startControlServer(address: string, token: string, handl
27
74
  export type ServiceLookup = {
28
75
  readonly state: 'running';
29
76
  readonly record: ProcessRecord;
77
+ readonly engine: EngineIdentity;
30
78
  readonly client: ControlClient;
31
79
  } | {
32
80
  readonly state: 'stopped';
@@ -44,7 +92,11 @@ export type ServiceLookup = {
44
92
  export declare class ControlClient {
45
93
  private readonly project;
46
94
  readonly record: ProcessRecord;
47
- constructor(project: Project, record: ProcessRecord);
95
+ /** Verified identity of the engine; snapshots of an incompatible engine are refused instead of misrendered. */
96
+ readonly engine?: EngineIdentity | undefined;
97
+ constructor(project: Project, record: ProcessRecord,
98
+ /** Verified identity of the engine; snapshots of an incompatible engine are refused instead of misrendered. */
99
+ engine?: EngineIdentity | undefined);
48
100
  /**
49
101
  * Sends a control request. Read-only requests retry briefly (re-authenticating the current record); a lost
50
102
  * reply to a mutating request is reported as unconfirmed and never replayed.
@@ -1,13 +1,66 @@
1
+ import { join } from 'node:path';
1
2
  import { PtbkError } from '../common/errors.js';
2
3
  import { IpcError, ipcRequest, startIpcServer } from '../common/ipc.js';
3
4
  import { isProcessAlive } from '../common/process.js';
5
+ import { ENGINE_VERSION } from '../common/version.js';
4
6
  import { readProcessRecord } from './records.js';
5
7
  /**
6
8
  * Control methods that only read state (safe to retry).
7
9
  *
8
10
  * @private service control
9
11
  */
10
- export const READ_ONLY_METHODS = new Set(['identify', 'snapshot', 'watch', 'requests', 'devices']);
12
+ export const READ_ONLY_METHODS = new Set(['identify', 'snapshot', 'summary', 'watch', 'requests', 'devices', 'chat-list', 'chat-agents', 'chat-get']);
13
+ /**
14
+ * Version of the control contract: the shapes of snapshots and control replies that clients render.
15
+ *
16
+ * Engines and clients of different ptbk versions interoperate only when their contracts match. Bump it with every
17
+ * change that a client of the previous contract could misread (a removed, renamed or retyped field or method); a new
18
+ * snapshot field keeps the contract only when it is optional, so clients must handle its absence.
19
+ *
20
+ * @private service control
21
+ */
22
+ export const CONTROL_CONTRACT = 2;
23
+ /**
24
+ * Control methods whose replies are rendered as a service snapshot; reading them from an engine of another
25
+ * contract would misrender (or crash) the client.
26
+ */
27
+ const SNAPSHOT_METHODS = new Set(['snapshot', 'watch']);
28
+ /**
29
+ * Whether this client can read snapshots of an engine: the same version, or a matching control contract.
30
+ *
31
+ * @private service control
32
+ */
33
+ export function engineIdentityOf(reported, record) {
34
+ const version = typeof reported.version === 'string' ? reported.version : record.engineVersion;
35
+ const contract = typeof reported.contract === 'number' ? reported.contract : undefined;
36
+ return { version, contract, compatible: version === ENGINE_VERSION || contract === CONTROL_CONTRACT };
37
+ }
38
+ /**
39
+ * CLI entry point of the installation that runs a service (it may since have been removed or upgraded).
40
+ *
41
+ * @private service control
42
+ */
43
+ export function engineBin(record) {
44
+ return join(record.installation, 'bin', 'ptbk.js');
45
+ }
46
+ /**
47
+ * Actionable error of a client that cannot read the snapshots of an engine of another version.
48
+ *
49
+ * @private service control
50
+ */
51
+ export function incompatibleEngineError(project, record, engine, options = {}) {
52
+ return new PtbkError(`The running service uses ptbk ${engine.version}; this ptbk ${ENGINE_VERSION} cannot read its status.`, {
53
+ kind: 'unsupported',
54
+ project: project.root,
55
+ reason: `The control contract differs (service ${engine.contract ?? 'unknown'}, this client ${CONTROL_CONTRACT})${options.installationGone ? `, and the service's installation at ${record.installation} no longer holds ptbk ${engine.version}` : ''}.`,
56
+ effect: 'Nothing was changed; the service keeps running.',
57
+ next: [
58
+ ...(options.installationGone ? [] : [`Use the service's own installation: \`node "${engineBin(record)}" dashboard\`.`]),
59
+ `Switch the service to ptbk ${ENGINE_VERSION}: \`ptbk stop\`, then \`ptbk start\` (unfinished work keeps its recovery record).`,
60
+ `Or view it with its own version: \`npx ptbk@${engine.version} dashboard\`.`,
61
+ ],
62
+ });
63
+ }
11
64
  /**
12
65
  * Starts the control server of a running process.
13
66
  *
@@ -31,15 +84,21 @@ export async function startControlServer(address, token, handler) {
31
84
  export class ControlClient {
32
85
  project;
33
86
  record;
34
- constructor(project, record) {
87
+ engine;
88
+ constructor(project, record,
89
+ /** Verified identity of the engine; snapshots of an incompatible engine are refused instead of misrendered. */
90
+ engine) {
35
91
  this.project = project;
36
92
  this.record = record;
93
+ this.engine = engine;
37
94
  }
38
95
  /**
39
96
  * Sends a control request. Read-only requests retry briefly (re-authenticating the current record); a lost
40
97
  * reply to a mutating request is reported as unconfirmed and never replayed.
41
98
  */
42
99
  async request(method, params = {}, timeoutMs = 30_000) {
100
+ if (this.engine && !this.engine.compatible && SNAPSHOT_METHODS.has(method))
101
+ throw incompatibleEngineError(this.project, this.record, this.engine);
43
102
  const readOnly = READ_ONLY_METHODS.has(method);
44
103
  let record = this.record;
45
104
  for (let attempt = 1;; attempt++) {
@@ -51,7 +110,7 @@ export class ControlClient {
51
110
  throw error;
52
111
  if (error.stage === 'remote') {
53
112
  const details = error.details;
54
- throw new PtbkError(error.message, { kind: details?.kind ?? 'technical', reason: details?.reason, next: details?.next });
113
+ throw new PtbkError(error.message, { kind: details?.kind ?? 'technical', reason: details?.reason, effect: details?.effect, next: details?.next, data: details?.data });
55
114
  }
56
115
  if (!readOnly) {
57
116
  throw new PtbkError(error.stage === 'connect' ? 'The service did not accept the request.' : `The outcome of "${method}" is unconfirmed.`, {
@@ -92,7 +151,8 @@ export async function lookupService(project) {
92
151
  const identity = await ipcRequest(record.controlAddress, { token: record.token, method: 'identify', params: {} }, 5000);
93
152
  if (identity.instanceId !== record.instanceId)
94
153
  return { state: 'unreachable', record, reason: 'The control endpoint belongs to a different instance.' };
95
- return { state: 'running', record, client: new ControlClient(project, record) };
154
+ const engine = engineIdentityOf(identity, record);
155
+ return { state: 'running', record, engine, client: new ControlClient(project, record, engine) };
96
156
  }
97
157
  catch (error) {
98
158
  return { state: 'unreachable', record, reason: error instanceof Error ? error.message : String(error) };
@@ -1 +1 @@
1
- {"version":3,"file":"control.js","sourceRoot":"","sources":["../../src/service/control.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"control.js","sourceRoot":"","sources":["../../src/service/control.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,133 @@
1
+ import { ControlClient } from './control.js';
2
+ /**
3
+ * Version of the host-wide discovery contract (kept interoperable across engine versions).
4
+ *
5
+ * @private service discovery
6
+ */
7
+ export declare const DISCOVERY_VERSION = 1;
8
+ /**
9
+ * One running engine as registered in the host-wide discovery registry (`<app data>/services/<instance>.json`).
10
+ *
11
+ * It points back to the verified owner of one concrete project. It is not a project lock, a credential (no control
12
+ * token) or a task store: connecting still requires the project's own owner-readable process record.
13
+ *
14
+ * @private service discovery
15
+ */
16
+ export type DiscoveryEntry = {
17
+ readonly version: typeof DISCOVERY_VERSION;
18
+ /** Unique instance of the engine process. */
19
+ readonly instanceId: string;
20
+ /** PID of the process hosting the engine. */
21
+ readonly pid: number;
22
+ /** PID of the daemon supervisor, when any. */
23
+ readonly supervisorPid?: number;
24
+ /** Placement of the engine. */
25
+ readonly mode: 'daemon' | 'foreground' | 'run';
26
+ /** Canonical project directory the engine owns. */
27
+ readonly projectRoot: string;
28
+ /** Display name of the project. */
29
+ readonly projectName: string;
30
+ /** Engine version actually loaded by the process. */
31
+ readonly engineVersion: string;
32
+ /** Installation running the engine. */
33
+ readonly installation: string;
34
+ /** Local control endpoint (useless without the project's token). */
35
+ readonly controlAddress: string;
36
+ /** Engine start (ISO). */
37
+ readonly startedAt: string;
38
+ };
39
+ /**
40
+ * Directory of the registry for the current OS user (other users' engines are outside it by design).
41
+ *
42
+ * @private service discovery
43
+ */
44
+ export declare function discoveryDirectory(env?: NodeJS.ProcessEnv): string;
45
+ /**
46
+ * Registers a running engine; returns the owner's own unregistration (it never touches other entries).
47
+ *
48
+ * @private service discovery
49
+ */
50
+ export declare function registerEngine(entry: DiscoveryEntry, env?: NodeJS.ProcessEnv): Promise<() => Promise<void>>;
51
+ /**
52
+ * Reads every registration of this OS user. A missing registry is an empty (successful) result; an unreadable one is
53
+ * reported as a problem instead of being presented as zero services.
54
+ *
55
+ * @private service discovery
56
+ */
57
+ export declare function readRegistry(env?: NodeJS.ProcessEnv): Promise<{
58
+ readonly entries: DiscoveryEntry[];
59
+ readonly problem?: string;
60
+ }>;
61
+ /**
62
+ * Compact live summary of one engine for the global table (the `summary` control method, or a full snapshot from
63
+ * engines that predate it).
64
+ *
65
+ * @private service discovery
66
+ */
67
+ export type EngineSummary = {
68
+ readonly state: string;
69
+ readonly phase: string;
70
+ readonly intent?: string;
71
+ readonly work?: string;
72
+ readonly waitingChats: number;
73
+ readonly observedAt: string;
74
+ };
75
+ /**
76
+ * Observed status of one registration.
77
+ *
78
+ * @private service discovery
79
+ */
80
+ export type DiscoveredEngine = {
81
+ readonly status: 'live';
82
+ readonly entry: DiscoveryEntry;
83
+ readonly client: ControlClient;
84
+ readonly summary: EngineSummary;
85
+ } | {
86
+ readonly status: 'unreachable';
87
+ readonly entry: DiscoveryEntry;
88
+ readonly reason: string;
89
+ } | {
90
+ readonly status: 'ended';
91
+ readonly entry: DiscoveryEntry;
92
+ readonly reason: string;
93
+ };
94
+ /**
95
+ * Verifies a registration against the project's own process record and the engine's control identity before it is
96
+ * shown as live. A proven-dead entry (process gone, or the project verifiably owned by another instance) is removed
97
+ * from the registry; nothing is killed and no project lock or project file is touched.
98
+ *
99
+ * @private service discovery
100
+ */
101
+ export declare function verifyEngine(entry: DiscoveryEntry, env?: NodeJS.ProcessEnv): Promise<DiscoveredEngine>;
102
+ /**
103
+ * Minimal shape of a full snapshot (engines without the `summary` method).
104
+ */
105
+ type SnapshotLike = {
106
+ readonly observedAt: string;
107
+ readonly phase: string;
108
+ readonly service: {
109
+ readonly state: string;
110
+ readonly lifecycle?: {
111
+ readonly intent?: string;
112
+ };
113
+ };
114
+ readonly current?: {
115
+ readonly agent: {
116
+ readonly name: string;
117
+ };
118
+ readonly taskTitle: string;
119
+ };
120
+ readonly wait?: {
121
+ readonly reason: string;
122
+ };
123
+ readonly chats?: {
124
+ readonly waiting: readonly unknown[];
125
+ };
126
+ };
127
+ /**
128
+ * Compact summary of a snapshot.
129
+ *
130
+ * @private service discovery
131
+ */
132
+ export declare function summaryOfSnapshot(snapshot: SnapshotLike): EngineSummary;
133
+ export {};