agent-tempo 1.2.0 → 1.4.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 (281) hide show
  1. package/CLAUDE.md +253 -219
  2. package/LICENSE +21 -21
  3. package/README.md +293 -289
  4. package/assets/icon-dark.svg +9 -9
  5. package/assets/icon.svg +9 -9
  6. package/assets/logo-dark.svg +11 -11
  7. package/assets/logo-light.svg +11 -11
  8. package/dashboard/README.md +91 -91
  9. package/dashboard/dist/assets/{index-D6Xyje_n.js → index-jmYe6rmS.js} +2 -2
  10. package/dashboard/dist/assets/index-jmYe6rmS.js.map +1 -0
  11. package/dashboard/dist/index.html +20 -20
  12. package/dashboard/package.json +47 -47
  13. package/dist/activities/outbox.d.ts +30 -1
  14. package/dist/activities/outbox.js +96 -3
  15. package/dist/adapters/base.js +5 -0
  16. package/dist/adapters/copilot/adapter.js +12 -1
  17. package/dist/adapters/index.d.ts +1 -1
  18. package/dist/adapters/index.js +7 -0
  19. package/dist/adapters/pi/adapter.d.ts +2 -0
  20. package/dist/adapters/pi/adapter.js +43 -0
  21. package/dist/adapters/pi/index.d.ts +16 -0
  22. package/dist/adapters/pi/index.js +10 -0
  23. package/dist/cli/global-wrapper.d.ts +19 -0
  24. package/dist/cli/global-wrapper.js +169 -0
  25. package/dist/cli/help-text.js +97 -97
  26. package/dist/cli/startup.js +11 -0
  27. package/dist/cli/upgrade-command.js +81 -81
  28. package/dist/cli.js +12 -0
  29. package/dist/client/core.js +9 -2
  30. package/dist/client/interface.d.ts +6 -0
  31. package/dist/config.d.ts +79 -0
  32. package/dist/config.js +74 -0
  33. package/dist/daemon.js +37 -1
  34. package/dist/http/aggregate.d.ts +22 -1
  35. package/dist/http/aggregate.js +41 -0
  36. package/dist/http/auth.d.ts +94 -8
  37. package/dist/http/auth.js +93 -9
  38. package/dist/http/body.d.ts +4 -1
  39. package/dist/http/body.js +6 -3
  40. package/dist/http/event-bus.js +1 -0
  41. package/dist/http/event-types.d.ts +34 -2
  42. package/dist/http/event-types.js +1 -0
  43. package/dist/http/gate-audit.d.ts +12 -0
  44. package/dist/http/gate-audit.js +95 -0
  45. package/dist/http/gate-registry.d.ts +167 -0
  46. package/dist/http/gate-registry.js +163 -0
  47. package/dist/http/gate-routes.d.ts +48 -0
  48. package/dist/http/gate-routes.js +102 -0
  49. package/dist/http/ingest-registry.d.ts +30 -0
  50. package/dist/http/ingest-registry.js +108 -0
  51. package/dist/http/inner-loop-routes.d.ts +66 -0
  52. package/dist/http/inner-loop-routes.js +182 -0
  53. package/dist/http/inner-loop.d.ts +92 -0
  54. package/dist/http/inner-loop.js +155 -0
  55. package/dist/http/server.d.ts +38 -3
  56. package/dist/http/server.js +211 -6
  57. package/dist/http/snapshot.d.ts +6 -0
  58. package/dist/http/snapshot.js +6 -0
  59. package/dist/pi/cue-pump.d.ts +61 -0
  60. package/dist/pi/cue-pump.js +95 -0
  61. package/dist/pi/extension.d.ts +45 -0
  62. package/dist/pi/extension.js +407 -0
  63. package/dist/pi/gate-client.d.ts +54 -0
  64. package/dist/pi/gate-client.js +136 -0
  65. package/dist/pi/headless.d.ts +85 -0
  66. package/dist/pi/headless.js +224 -0
  67. package/dist/pi/index.d.ts +28 -0
  68. package/dist/pi/index.js +43 -0
  69. package/dist/pi/inner-loop-client.d.ts +67 -0
  70. package/dist/pi/inner-loop-client.js +164 -0
  71. package/dist/pi/inner-loop-publisher.d.ts +187 -0
  72. package/dist/pi/inner-loop-publisher.js +236 -0
  73. package/dist/pi/lazy-proxy.d.ts +37 -0
  74. package/dist/pi/lazy-proxy.js +55 -0
  75. package/dist/pi/mission-control/actions.d.ts +48 -0
  76. package/dist/pi/mission-control/actions.js +98 -0
  77. package/dist/pi/mission-control/board.d.ts +53 -0
  78. package/dist/pi/mission-control/board.js +104 -0
  79. package/dist/pi/mission-control/extension.d.ts +44 -0
  80. package/dist/pi/mission-control/extension.js +251 -0
  81. package/dist/pi/mission-control/index.d.ts +15 -0
  82. package/dist/pi/mission-control/index.js +32 -0
  83. package/dist/pi/mission-control/inner-tail.d.ts +48 -0
  84. package/dist/pi/mission-control/inner-tail.js +76 -0
  85. package/dist/pi/mission-control/pi-ui.d.ts +43 -0
  86. package/dist/pi/mission-control/pi-ui.js +10 -0
  87. package/dist/pi/mission-control/render.d.ts +6 -0
  88. package/dist/pi/mission-control/render.js +95 -0
  89. package/dist/pi/phase-driver.d.ts +74 -0
  90. package/dist/pi/phase-driver.js +122 -0
  91. package/dist/pi/pi-types.d.ts +208 -0
  92. package/dist/pi/pi-types.js +21 -0
  93. package/dist/pi/probe.d.ts +80 -0
  94. package/dist/pi/probe.js +154 -0
  95. package/dist/pi/render-tools.d.ts +17 -0
  96. package/dist/pi/render-tools.js +51 -0
  97. package/dist/pi/reset-pump.d.ts +47 -0
  98. package/dist/pi/reset-pump.js +85 -0
  99. package/dist/pi/tool-capability.d.ts +60 -0
  100. package/dist/pi/tool-capability.js +156 -0
  101. package/dist/pi/workflow-client.d.ts +158 -0
  102. package/dist/pi/workflow-client.js +289 -0
  103. package/dist/pi/zod-to-typebox.d.ts +74 -0
  104. package/dist/pi/zod-to-typebox.js +191 -0
  105. package/dist/scripts/verify-daemon-isolation-guard.js +24 -24
  106. package/dist/server-tools.d.ts +2 -0
  107. package/dist/server-tools.js +50 -46
  108. package/dist/server.js +4 -0
  109. package/dist/spawn.d.ts +55 -0
  110. package/dist/spawn.js +84 -12
  111. package/dist/tools/agent-types.d.ts +2 -2
  112. package/dist/tools/agent-types.js +22 -17
  113. package/dist/tools/attachment-info.d.ts +2 -2
  114. package/dist/tools/attachment-info.js +38 -33
  115. package/dist/tools/broadcast.d.ts +2 -2
  116. package/dist/tools/broadcast.js +69 -64
  117. package/dist/tools/cancel-stage.d.ts +2 -2
  118. package/dist/tools/cancel-stage.js +20 -15
  119. package/dist/tools/clear-state.d.ts +2 -2
  120. package/dist/tools/clear-state.js +25 -20
  121. package/dist/tools/coat-check-evict.d.ts +2 -2
  122. package/dist/tools/coat-check-evict.js +30 -25
  123. package/dist/tools/coat-check-get.d.ts +2 -2
  124. package/dist/tools/coat-check-get.js +39 -34
  125. package/dist/tools/coat-check-list.d.ts +2 -2
  126. package/dist/tools/coat-check-list.js +48 -43
  127. package/dist/tools/coat-check-put.d.ts +2 -2
  128. package/dist/tools/coat-check-put.js +41 -36
  129. package/dist/tools/cue.d.ts +2 -2
  130. package/dist/tools/cue.js +57 -52
  131. package/dist/tools/descriptor.d.ts +72 -0
  132. package/dist/tools/descriptor.js +39 -0
  133. package/dist/tools/destroy.d.ts +2 -2
  134. package/dist/tools/destroy.js +153 -148
  135. package/dist/tools/ensemble.d.ts +2 -2
  136. package/dist/tools/ensemble.js +71 -66
  137. package/dist/tools/evaluate-gate.d.ts +2 -2
  138. package/dist/tools/evaluate-gate.js +33 -27
  139. package/dist/tools/fetch-state.d.ts +2 -2
  140. package/dist/tools/fetch-state.js +43 -38
  141. package/dist/tools/gates.d.ts +2 -2
  142. package/dist/tools/gates.js +39 -34
  143. package/dist/tools/hosts.d.ts +2 -2
  144. package/dist/tools/hosts.js +25 -20
  145. package/dist/tools/listen.d.ts +2 -2
  146. package/dist/tools/listen.js +23 -18
  147. package/dist/tools/load-lineup.d.ts +2 -2
  148. package/dist/tools/load-lineup.js +324 -319
  149. package/dist/tools/migrate.d.ts +2 -2
  150. package/dist/tools/migrate.js +45 -40
  151. package/dist/tools/pause.d.ts +2 -2
  152. package/dist/tools/pause.js +34 -29
  153. package/dist/tools/play.d.ts +2 -2
  154. package/dist/tools/play.js +53 -48
  155. package/dist/tools/quality-gate.d.ts +2 -2
  156. package/dist/tools/quality-gate.js +26 -21
  157. package/dist/tools/recall.d.ts +2 -2
  158. package/dist/tools/recall.js +32 -27
  159. package/dist/tools/recruit.d.ts +2 -2
  160. package/dist/tools/recruit.js +325 -256
  161. package/dist/tools/release.d.ts +2 -2
  162. package/dist/tools/release.js +85 -80
  163. package/dist/tools/report.d.ts +2 -2
  164. package/dist/tools/report.js +28 -23
  165. package/dist/tools/reset.d.ts +3 -0
  166. package/dist/tools/reset.js +51 -0
  167. package/dist/tools/restart.d.ts +2 -2
  168. package/dist/tools/restart.js +51 -46
  169. package/dist/tools/restore.d.ts +2 -2
  170. package/dist/tools/restore.js +76 -71
  171. package/dist/tools/save-lineup.d.ts +2 -2
  172. package/dist/tools/save-lineup.js +32 -27
  173. package/dist/tools/save-state.d.ts +2 -2
  174. package/dist/tools/save-state.js +43 -38
  175. package/dist/tools/schedule.d.ts +2 -2
  176. package/dist/tools/schedule.js +133 -128
  177. package/dist/tools/schedules.d.ts +2 -2
  178. package/dist/tools/schedules.js +41 -36
  179. package/dist/tools/set-ensemble-description.d.ts +2 -2
  180. package/dist/tools/set-ensemble-description.js +26 -21
  181. package/dist/tools/set-name.d.ts +2 -2
  182. package/dist/tools/set-name.js +38 -33
  183. package/dist/tools/set-part.d.ts +2 -2
  184. package/dist/tools/set-part.js +20 -15
  185. package/dist/tools/shutdown.d.ts +2 -2
  186. package/dist/tools/shutdown.js +39 -34
  187. package/dist/tools/stage.d.ts +2 -2
  188. package/dist/tools/stage.js +28 -23
  189. package/dist/tools/stages.d.ts +2 -2
  190. package/dist/tools/stages.js +36 -31
  191. package/dist/tools/unschedule.d.ts +2 -2
  192. package/dist/tools/unschedule.js +30 -25
  193. package/dist/tools/who-am-i.d.ts +2 -2
  194. package/dist/tools/who-am-i.js +36 -31
  195. package/dist/tools/worktree.d.ts +2 -2
  196. package/dist/tools/worktree.js +134 -129
  197. package/dist/tui/index.js +6 -6
  198. package/dist/types.d.ts +47 -2
  199. package/dist/types.js +1 -1
  200. package/dist/utils/default-part.js +1 -0
  201. package/dist/utils/grpc-shutdown-guard.d.ts +52 -0
  202. package/dist/utils/grpc-shutdown-guard.js +88 -0
  203. package/dist/utils/sdk-probe.d.ts +23 -0
  204. package/dist/utils/sdk-probe.js +46 -7
  205. package/dist/worker.d.ts +3 -1
  206. package/dist/worker.js +6 -2
  207. package/dist/workflows/session.js +70 -2
  208. package/dist/workflows/signals.d.ts +32 -2
  209. package/dist/workflows/signals.js +25 -2
  210. package/examples/agents/tempo-composer.md +56 -56
  211. package/examples/agents/tempo-conductor.md +117 -117
  212. package/examples/agents/tempo-critic.md +73 -73
  213. package/examples/agents/tempo-improv.md +74 -74
  214. package/examples/agents/tempo-liner.md +75 -75
  215. package/examples/agents/tempo-roadie.md +61 -61
  216. package/examples/agents/tempo-soloist.md +71 -71
  217. package/examples/agents/tempo-tuner.md +94 -94
  218. package/examples/ensembles/tempo-big-band.yaml +146 -146
  219. package/examples/ensembles/tempo-dev-team.yaml +58 -58
  220. package/examples/ensembles/tempo-headless-jam.yaml +77 -77
  221. package/examples/ensembles/tempo-jam-session.yaml +41 -41
  222. package/examples/ensembles/tempo-mock-jam.yaml +79 -79
  223. package/examples/ensembles/tempo-review-squad.yaml +32 -32
  224. package/package.json +176 -173
  225. package/packaging/launchd/com.agent.tempo.plist +46 -46
  226. package/packaging/systemd/agent-tempo.service +32 -32
  227. package/packaging/windows/install-task.ps1 +71 -71
  228. package/scenarios/conductor-recruit-mock.yaml +33 -33
  229. package/scenarios/echo-roundtrip.yaml +15 -15
  230. package/scenarios/multi-player-handoff.yaml +38 -38
  231. package/scenarios/recruit-cascade.yaml +38 -38
  232. package/scenarios/two-player-conversation.yaml +33 -33
  233. package/workflow-bundle.js +97 -6
  234. package/dashboard/dist/assets/index-D6Xyje_n.js.map +0 -1
  235. package/dist/activities/claude-stop.d.ts +0 -21
  236. package/dist/activities/claude-stop.js +0 -94
  237. package/dist/channel.d.ts +0 -3
  238. package/dist/channel.js +0 -48
  239. package/dist/copilot-bridge.d.ts +0 -22
  240. package/dist/copilot-bridge.js +0 -565
  241. package/dist/scripts/258-spotcheck.js +0 -303
  242. package/dist/tools/detach.d.ts +0 -4
  243. package/dist/tools/detach.js +0 -45
  244. package/dist/tools/encore.d.ts +0 -4
  245. package/dist/tools/encore.js +0 -31
  246. package/dist/tools/helpers.d.ts +0 -21
  247. package/dist/tools/helpers.js +0 -25
  248. package/dist/tools/pause-ensemble.d.ts +0 -4
  249. package/dist/tools/pause-ensemble.js +0 -58
  250. package/dist/tools/resume-ensemble.d.ts +0 -4
  251. package/dist/tools/resume-ensemble.js +0 -79
  252. package/dist/tools/stop.d.ts +0 -4
  253. package/dist/tools/stop.js +0 -29
  254. package/dist/tui/client.d.ts +0 -6
  255. package/dist/tui/client.js +0 -9
  256. package/dist/tui/components/ActivityLog.d.ts +0 -16
  257. package/dist/tui/components/ActivityLog.js +0 -36
  258. package/dist/tui/components/CommandOverlay.d.ts +0 -15
  259. package/dist/tui/components/CommandOverlay.js +0 -34
  260. package/dist/tui/components/ConductorChat.d.ts +0 -16
  261. package/dist/tui/components/ConductorChat.js +0 -32
  262. package/dist/tui/components/EnsembleListView.d.ts +0 -14
  263. package/dist/tui/components/EnsembleListView.js +0 -32
  264. package/dist/tui/components/EnsemblePanel.d.ts +0 -12
  265. package/dist/tui/components/EnsemblePanel.js +0 -40
  266. package/dist/tui/components/InputBar.d.ts +0 -13
  267. package/dist/tui/components/InputBar.js +0 -58
  268. package/dist/tui/components/ScheduleOverlay.d.ts +0 -13
  269. package/dist/tui/components/ScheduleOverlay.js +0 -113
  270. package/dist/tui/components/TopBar.d.ts +0 -12
  271. package/dist/tui/components/TopBar.js +0 -15
  272. package/dist/tui/core-api.d.ts +0 -26
  273. package/dist/tui/core-api.js +0 -67
  274. package/dist/tui/hooks/useEnsembleDiscovery.d.ts +0 -3
  275. package/dist/tui/hooks/useEnsembleDiscovery.js +0 -30
  276. package/dist/tui/hooks/useMaestroPoller.d.ts +0 -3
  277. package/dist/tui/hooks/useMaestroPoller.js +0 -36
  278. package/dist/tui/hooks/useSendCommand.d.ts +0 -7
  279. package/dist/tui/hooks/useSendCommand.js +0 -29
  280. package/dist/utils/bg-preflight.d.ts +0 -25
  281. package/dist/utils/bg-preflight.js +0 -154
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.registerFetchStateTool = registerFetchStateTool;
3
+ exports.buildFetchStateTool = buildFetchStateTool;
4
4
  /**
5
5
  * `fetch_state` — read a saved state slot for self or any peer in the
6
6
  * ensemble (#334 PR-1, ADR 0011).
@@ -26,7 +26,7 @@ exports.registerFetchStateTool = registerFetchStateTool;
26
26
  const zod_1 = require("zod");
27
27
  const resolve_1 = require("./resolve");
28
28
  const signals_1 = require("../workflows/signals");
29
- const helpers_1 = require("./helpers");
29
+ const descriptor_1 = require("./descriptor");
30
30
  const validation_1 = require("../utils/validation");
31
31
  /**
32
32
  * Return type is monomorphic by design: `{ content, savedAt, savedBy } | null`.
@@ -37,42 +37,47 @@ const validation_1 = require("../utils/validation");
37
37
  * playerStateKeys`; v2 can graduate a dedicated `list_state` MCP tool if
38
38
  * telemetry shows real demand.
39
39
  */
40
- function registerFetchStateTool(server, client, config, handle, getPlayerId) {
41
- (0, helpers_1.defineTool)(server, 'fetch_state', `Read a saved-state slot for yourself or a peer. Defaults to your own "${validation_1.PLAYER_STATE_DEFAULT_KEY}" slot.
42
-
43
- Pass \`playerId\` to read a peer's slot (any player in the ensemble can read any other player's state — audit identity is recorded on each slot via \`savedBy\`). Returns a "(no state saved …)" message when the slot is empty.`, {
44
- key: zod_1.z.string().regex(validation_1.PLAYER_STATE_KEY_REGEX).max(validation_1.PLAYER_STATE_KEY_MAX).optional().describe(`Slot name (default "${validation_1.PLAYER_STATE_DEFAULT_KEY}").`),
45
- playerId: zod_1.z.string().max(validation_1.PLAYER_NAME_MAX).optional().describe('Target player name (default: self).'),
46
- }, async (args) => {
47
- const { key, playerId } = args;
48
- const targetId = playerId ?? getPlayerId();
49
- // Validate any explicit playerId — `getPlayerId()` is trusted (set by
50
- // the MCP server) and skips this check.
51
- if (playerId !== undefined) {
52
- const nameError = (0, validation_1.validatePlayerName)(playerId);
53
- if (nameError)
54
- return (0, helpers_1.fail)(nameError);
55
- }
56
- try {
57
- // Self-targeted reads use the cached own-session handle directly;
58
- // peer reads go through `resolveSession` (the codebase convention,
59
- // not a raw `client.workflow.getHandle`) so workflow-id format
60
- // changes only need to be tracked in one place.
61
- const targetHandle = targetId === getPlayerId()
62
- ? handle
63
- : await (0, resolve_1.resolveSession)(client, config.ensemble, targetId);
64
- if (!targetHandle) {
65
- return (0, helpers_1.fail)(`No session found with name "${targetId}".`);
40
+ function buildFetchStateTool(client, config, handle, getPlayerId) {
41
+ return {
42
+ name: 'fetch_state',
43
+ description: `Read a saved-state slot for yourself or a peer. Defaults to your own "${validation_1.PLAYER_STATE_DEFAULT_KEY}" slot.
44
+
45
+ Pass \`playerId\` to read a peer's slot (any player in the ensemble can read any other player's state — audit identity is recorded on each slot via \`savedBy\`). Returns a "(no state saved …)" message when the slot is empty.`,
46
+ params: {
47
+ key: zod_1.z.string().regex(validation_1.PLAYER_STATE_KEY_REGEX).max(validation_1.PLAYER_STATE_KEY_MAX).optional().describe(`Slot name (default "${validation_1.PLAYER_STATE_DEFAULT_KEY}").`),
48
+ playerId: zod_1.z.string().max(validation_1.PLAYER_NAME_MAX).optional().describe('Target player name (default: self).'),
49
+ },
50
+ handler: async (args) => {
51
+ const { key, playerId } = args;
52
+ const targetId = playerId ?? getPlayerId();
53
+ // Validate any explicit playerId — `getPlayerId()` is trusted (set by
54
+ // the MCP server) and skips this check.
55
+ if (playerId !== undefined) {
56
+ const nameError = (0, validation_1.validatePlayerName)(playerId);
57
+ if (nameError)
58
+ return (0, descriptor_1.fail)(nameError);
66
59
  }
67
- const slotKey = key ?? validation_1.PLAYER_STATE_DEFAULT_KEY;
68
- const result = await targetHandle.query(signals_1.playerStateQuery, { key: slotKey });
69
- if (!result) {
70
- return (0, helpers_1.ok)(`(no state saved at slot "${slotKey}" for ${targetId})`);
60
+ try {
61
+ // Self-targeted reads use the cached own-session handle directly;
62
+ // peer reads go through `resolveSession` (the codebase convention,
63
+ // not a raw `client.workflow.getHandle`) so workflow-id format
64
+ // changes only need to be tracked in one place.
65
+ const targetHandle = targetId === getPlayerId()
66
+ ? handle
67
+ : await (0, resolve_1.resolveSession)(client, config.ensemble, targetId);
68
+ if (!targetHandle) {
69
+ return (0, descriptor_1.fail)(`No session found with name "${targetId}".`);
70
+ }
71
+ const slotKey = key ?? validation_1.PLAYER_STATE_DEFAULT_KEY;
72
+ const result = await targetHandle.query(signals_1.playerStateQuery, { key: slotKey });
73
+ if (!result) {
74
+ return (0, descriptor_1.ok)(`(no state saved at slot "${slotKey}" for ${targetId})`);
75
+ }
76
+ return (0, descriptor_1.ok)(`Slot **"${slotKey}"** — saved by **${result.savedBy}** at ${result.savedAt}\n\n${result.content}`);
71
77
  }
72
- return (0, helpers_1.ok)(`Slot **"${slotKey}"** — saved by **${result.savedBy}** at ${result.savedAt}\n\n${result.content}`);
73
- }
74
- catch (err) {
75
- return (0, helpers_1.fail)(`Failed to fetch state: ${(0, helpers_1.formatError)(err)}`);
76
- }
77
- });
78
+ catch (err) {
79
+ return (0, descriptor_1.fail)(`Failed to fetch state: ${(0, descriptor_1.formatError)(err)}`);
80
+ }
81
+ },
82
+ };
78
83
  }
@@ -1,3 +1,3 @@
1
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
1
  import { WorkflowHandle } from '@temporalio/client';
3
- export declare function registerGatesTool(server: McpServer, handle: WorkflowHandle): void;
2
+ import { type TempoToolDescriptor } from './descriptor';
3
+ export declare function buildGatesTool(handle: WorkflowHandle): TempoToolDescriptor;
@@ -1,41 +1,46 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.registerGatesTool = registerGatesTool;
3
+ exports.buildGatesTool = buildGatesTool;
4
4
  const zod_1 = require("zod");
5
- const helpers_1 = require("./helpers");
5
+ const descriptor_1 = require("./descriptor");
6
6
  const validation_1 = require("../utils/validation");
7
- function registerGatesTool(server, handle) {
8
- (0, helpers_1.defineTool)(server, 'gates', 'List quality gates and their status. Optionally filter by task name or status. Conductor only.', {
9
- task: zod_1.z.string().max(validation_1.GATE_TASK_MAX).optional().describe('Filter by specific task name'),
10
- status: zod_1.z.enum(['open', 'passed', 'failed']).optional().describe('Filter by gate status'),
11
- }, async (args) => {
12
- const { task, status } = args;
13
- try {
14
- const gates = await handle.query('qualityGates');
15
- let filtered = gates;
16
- if (task) {
17
- filtered = filtered.filter((g) => g.task === task);
18
- }
19
- if (status) {
20
- filtered = filtered.filter((g) => g.status === status);
7
+ function buildGatesTool(handle) {
8
+ return {
9
+ name: 'gates',
10
+ description: 'List quality gates and their status. Optionally filter by task name or status. Conductor only.',
11
+ params: {
12
+ task: zod_1.z.string().max(validation_1.GATE_TASK_MAX).optional().describe('Filter by specific task name'),
13
+ status: zod_1.z.enum(['open', 'passed', 'failed']).optional().describe('Filter by gate status'),
14
+ },
15
+ handler: async (args) => {
16
+ const { task, status } = args;
17
+ try {
18
+ const gates = await handle.query('qualityGates');
19
+ let filtered = gates;
20
+ if (task) {
21
+ filtered = filtered.filter((g) => g.task === task);
22
+ }
23
+ if (status) {
24
+ filtered = filtered.filter((g) => g.status === status);
25
+ }
26
+ if (filtered.length === 0) {
27
+ return (0, descriptor_1.ok)('No quality gates found matching the filter.');
28
+ }
29
+ const lines = filtered.map((g) => {
30
+ const icon = g.status === 'passed' ? '\u2705' : g.status === 'failed' ? '\u274c' : '\u23f3';
31
+ const criteriaLines = g.criteria.map((c, i) => {
32
+ const cIcon = c.status === 'passed' ? '\u2705' : c.status === 'failed' ? '\u274c' : '\u2b1c';
33
+ const evaluator = c.evaluatedBy ? ` (by ${c.evaluatedBy})` : '';
34
+ const notes = c.notes ? ` — ${c.notes}` : '';
35
+ return ` ${i}. ${cIcon} ${c.text}${evaluator}${notes}`;
36
+ });
37
+ return `${icon} **${g.task}** [${g.status}] (by ${g.createdBy}, ${g.createdAt})\n${criteriaLines.join('\n')}`;
38
+ });
39
+ return (0, descriptor_1.ok)(`${filtered.length} quality gate${filtered.length === 1 ? '' : 's'}:\n\n${lines.join('\n\n')}`);
21
40
  }
22
- if (filtered.length === 0) {
23
- return (0, helpers_1.ok)('No quality gates found matching the filter.');
41
+ catch (err) {
42
+ return (0, descriptor_1.fail)(`Failed to query gates: ${(0, descriptor_1.formatError)(err)}`);
24
43
  }
25
- const lines = filtered.map((g) => {
26
- const icon = g.status === 'passed' ? '\u2705' : g.status === 'failed' ? '\u274c' : '\u23f3';
27
- const criteriaLines = g.criteria.map((c, i) => {
28
- const cIcon = c.status === 'passed' ? '\u2705' : c.status === 'failed' ? '\u274c' : '\u2b1c';
29
- const evaluator = c.evaluatedBy ? ` (by ${c.evaluatedBy})` : '';
30
- const notes = c.notes ? ` — ${c.notes}` : '';
31
- return ` ${i}. ${cIcon} ${c.text}${evaluator}${notes}`;
32
- });
33
- return `${icon} **${g.task}** [${g.status}] (by ${g.createdBy}, ${g.createdAt})\n${criteriaLines.join('\n')}`;
34
- });
35
- return (0, helpers_1.ok)(`${filtered.length} quality gate${filtered.length === 1 ? '' : 's'}:\n\n${lines.join('\n\n')}`);
36
- }
37
- catch (err) {
38
- return (0, helpers_1.fail)(`Failed to query gates: ${(0, helpers_1.formatError)(err)}`);
39
- }
40
- });
44
+ },
45
+ };
41
46
  }
@@ -1,4 +1,4 @@
1
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
1
  import { Client } from '@temporalio/client';
3
2
  import { Config } from '../config';
4
- export declare function registerHostsTool(server: McpServer, client: Client, config: Config): void;
3
+ import { type TempoToolDescriptor } from './descriptor';
4
+ export declare function buildHostsTool(client: Client, config: Config): TempoToolDescriptor;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.registerHostsTool = registerHostsTool;
3
+ exports.buildHostsTool = buildHostsTool;
4
4
  /**
5
5
  * `hosts` — MCP tool for surfacing daemons polling the Temporal namespace (#274).
6
6
  *
@@ -16,25 +16,30 @@ exports.registerHostsTool = registerHostsTool;
16
16
  * Thin wrapper — all the logic is in `listHosts`.
17
17
  */
18
18
  const zod_1 = require("zod");
19
- const helpers_1 = require("./helpers");
19
+ const descriptor_1 = require("./descriptor");
20
20
  const hosts_1 = require("../utils/hosts");
21
21
  const format_hosts_1 = require("../utils/format-hosts");
22
- function registerHostsTool(server, client, config) {
23
- (0, helpers_1.defineTool)(server, 'hosts', 'Show all daemons polling this Temporal namespace, with their advertised capabilities. Returns liveness (live/stale), recruit-readiness, and each daemon\'s profile (default agent, available player types, platform) when it signaled one at boot. Read-only diagnostic.', {
24
- includeStale: zod_1.z.boolean().optional().describe('Include hosts not seen in the last minute (default: false).'),
25
- force: zod_1.z.boolean().optional().describe('Bypass the 3-second result cache (default: false).'),
26
- }, async (args) => {
27
- const { includeStale, force } = args;
28
- try {
29
- const hosts = await (0, hosts_1.listHosts)(client, {
30
- force: Boolean(force),
31
- namespace: config.temporalNamespace,
32
- taskQueue: config.taskQueue,
33
- });
34
- return (0, helpers_1.ok)((0, format_hosts_1.formatHostList)(hosts, { includeStale: Boolean(includeStale) }));
35
- }
36
- catch (err) {
37
- return (0, helpers_1.fail)(`Failed to list hosts: ${(0, helpers_1.formatError)(err)}`);
38
- }
39
- });
22
+ function buildHostsTool(client, config) {
23
+ return {
24
+ name: 'hosts',
25
+ description: 'Show all daemons polling this Temporal namespace, with their advertised capabilities. Returns liveness (live/stale), recruit-readiness, and each daemon\'s profile (default agent, available player types, platform) when it signaled one at boot. Read-only diagnostic.',
26
+ params: {
27
+ includeStale: zod_1.z.boolean().optional().describe('Include hosts not seen in the last minute (default: false).'),
28
+ force: zod_1.z.boolean().optional().describe('Bypass the 3-second result cache (default: false).'),
29
+ },
30
+ handler: async (args) => {
31
+ const { includeStale, force } = args;
32
+ try {
33
+ const hosts = await (0, hosts_1.listHosts)(client, {
34
+ force: Boolean(force),
35
+ namespace: config.temporalNamespace,
36
+ taskQueue: config.taskQueue,
37
+ });
38
+ return (0, descriptor_1.ok)((0, format_hosts_1.formatHostList)(hosts, { includeStale: Boolean(includeStale) }));
39
+ }
40
+ catch (err) {
41
+ return (0, descriptor_1.fail)(`Failed to list hosts: ${(0, descriptor_1.formatError)(err)}`);
42
+ }
43
+ },
44
+ };
40
45
  }
@@ -1,3 +1,3 @@
1
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
1
  import { WorkflowHandle } from '@temporalio/client';
3
- export declare function registerListenTool(server: McpServer, handle: WorkflowHandle): void;
2
+ import { type TempoToolDescriptor } from './descriptor';
3
+ export declare function buildListenTool(handle: WorkflowHandle): TempoToolDescriptor;
@@ -1,22 +1,27 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.registerListenTool = registerListenTool;
4
- const helpers_1 = require("./helpers");
5
- function registerListenTool(server, handle) {
6
- (0, helpers_1.defineTool)(server, 'listen', 'Check for pending messages from other sessions. Use this if you want to manually check for new messages.', {}, async () => {
7
- try {
8
- const messages = await handle.query('pendingMessages');
9
- if (messages.length === 0) {
10
- return (0, helpers_1.ok)('No pending messages.');
3
+ exports.buildListenTool = buildListenTool;
4
+ const descriptor_1 = require("./descriptor");
5
+ function buildListenTool(handle) {
6
+ return {
7
+ name: 'listen',
8
+ description: 'Check for pending messages from other sessions. Use this if you want to manually check for new messages.',
9
+ params: {},
10
+ handler: async () => {
11
+ try {
12
+ const messages = await handle.query('pendingMessages');
13
+ if (messages.length === 0) {
14
+ return (0, descriptor_1.ok)('No pending messages.');
15
+ }
16
+ // Mark messages as delivered
17
+ const ids = messages.map((m) => m.id);
18
+ await handle.signal('markDelivered', ids);
19
+ const lines = messages.map((m) => `**${m.from}** (${m.timestamp}):\n${m.text}`);
20
+ return (0, descriptor_1.ok)(lines.join('\n\n'));
11
21
  }
12
- // Mark messages as delivered
13
- const ids = messages.map((m) => m.id);
14
- await handle.signal('markDelivered', ids);
15
- const lines = messages.map((m) => `**${m.from}** (${m.timestamp}):\n${m.text}`);
16
- return (0, helpers_1.ok)(lines.join('\n\n'));
17
- }
18
- catch (err) {
19
- return (0, helpers_1.fail)(`Failed to check messages: ${(0, helpers_1.formatError)(err)}`);
20
- }
21
- });
22
+ catch (err) {
23
+ return (0, descriptor_1.fail)(`Failed to check messages: ${(0, descriptor_1.formatError)(err)}`);
24
+ }
25
+ },
26
+ };
22
27
  }
@@ -1,5 +1,5 @@
1
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
1
  import { Client, WorkflowHandle } from '@temporalio/client';
3
2
  import { Config } from '../config';
4
3
  import { AgentType } from '../types';
5
- export declare function registerLoadLineupTool(server: McpServer, client: Client, config: Config, getPlayerId: () => string, ownAgentType?: AgentType, handle?: WorkflowHandle, setPlayerId?: (id: string) => void, isConductor?: boolean): void;
4
+ import { type TempoToolDescriptor } from './descriptor';
5
+ export declare function buildLoadLineupTool(client: Client, config: Config, getPlayerId: () => string, ownAgentType?: AgentType, handle?: WorkflowHandle, setPlayerId?: (id: string) => void, isConductor?: boolean): TempoToolDescriptor;