@tt-a1i/hive 1.4.4 → 1.6.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 (180) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/README.en.md +21 -0
  3. package/README.md +16 -0
  4. package/assets/qq-group.jpg +0 -0
  5. package/dist/bin/team.cmd +1 -0
  6. package/dist/src/cli/hive-update.d.ts +45 -17
  7. package/dist/src/cli/hive-update.js +63 -25
  8. package/dist/src/cli/hive.d.ts +25 -0
  9. package/dist/src/cli/hive.js +41 -3
  10. package/dist/src/cli/team.d.ts +1 -0
  11. package/dist/src/cli/team.js +216 -3
  12. package/dist/src/server/agent-command-resolver.js +3 -19
  13. package/dist/src/server/agent-manager-support.d.ts +2 -2
  14. package/dist/src/server/agent-manager-support.js +98 -24
  15. package/dist/src/server/agent-run-starter.d.ts +6 -1
  16. package/dist/src/server/agent-run-starter.js +9 -2
  17. package/dist/src/server/agent-run-store.d.ts +1 -1
  18. package/dist/src/server/agent-runtime-close.d.ts +1 -0
  19. package/dist/src/server/agent-runtime-close.js +25 -1
  20. package/dist/src/server/agent-runtime-contract.d.ts +12 -1
  21. package/dist/src/server/agent-runtime-stop-run.d.ts +1 -1
  22. package/dist/src/server/agent-runtime-stop-run.js +4 -1
  23. package/dist/src/server/agent-runtime.d.ts +2 -1
  24. package/dist/src/server/agent-runtime.js +14 -3
  25. package/dist/src/server/agent-startup-instructions.d.ts +7 -1
  26. package/dist/src/server/agent-startup-instructions.js +17 -9
  27. package/dist/src/server/agent-stdin-dispatcher.d.ts +25 -5
  28. package/dist/src/server/agent-stdin-dispatcher.js +141 -40
  29. package/dist/src/server/cron-util.d.ts +7 -0
  30. package/dist/src/server/cron-util.js +19 -0
  31. package/dist/src/server/dispatch-ledger-store.d.ts +22 -0
  32. package/dist/src/server/dispatch-ledger-store.js +51 -3
  33. package/dist/src/server/env-sync-message.js +9 -9
  34. package/dist/src/server/feature-flags.d.ts +42 -0
  35. package/dist/src/server/feature-flags.js +24 -0
  36. package/dist/src/server/fs-pick-folder.js +4 -0
  37. package/dist/src/server/fs-sandbox.js +36 -7
  38. package/dist/src/server/hive-team-guidance.d.ts +12 -6
  39. package/dist/src/server/hive-team-guidance.js +253 -71
  40. package/dist/src/server/live-run-registry.d.ts +1 -0
  41. package/dist/src/server/live-run-registry.js +1 -1
  42. package/dist/src/server/open-target-commands.js +5 -6
  43. package/dist/src/server/orchestrator-autostart.d.ts +12 -0
  44. package/dist/src/server/orchestrator-autostart.js +15 -13
  45. package/dist/src/server/path-canonicalization.d.ts +3 -0
  46. package/dist/src/server/path-canonicalization.js +29 -0
  47. package/dist/src/server/platform-path.d.ts +3 -0
  48. package/dist/src/server/platform-path.js +13 -0
  49. package/dist/src/server/post-start-input-writer.d.ts +1 -1
  50. package/dist/src/server/post-start-input-writer.js +110 -13
  51. package/dist/src/server/preset-launch-support.d.ts +1 -1
  52. package/dist/src/server/preset-launch-support.js +33 -2
  53. package/dist/src/server/recovery-summary.d.ts +5 -1
  54. package/dist/src/server/recovery-summary.js +18 -17
  55. package/dist/src/server/report-outbox-store.d.ts +36 -0
  56. package/dist/src/server/report-outbox-store.js +33 -0
  57. package/dist/src/server/restart-policy-support.d.ts +5 -1
  58. package/dist/src/server/restart-policy-support.js +9 -1
  59. package/dist/src/server/restart-policy.d.ts +6 -2
  60. package/dist/src/server/restart-policy.js +51 -31
  61. package/dist/src/server/role-template-store.d.ts +1 -0
  62. package/dist/src/server/role-template-store.js +11 -1
  63. package/dist/src/server/route-types.d.ts +43 -0
  64. package/dist/src/server/routes-runtime.js +2 -1
  65. package/dist/src/server/routes-settings.js +76 -0
  66. package/dist/src/server/routes-tasks.js +23 -0
  67. package/dist/src/server/routes-team.js +211 -1
  68. package/dist/src/server/routes-workflow-schedules.d.ts +2 -0
  69. package/dist/src/server/routes-workflow-schedules.js +58 -0
  70. package/dist/src/server/routes-workflows.d.ts +2 -0
  71. package/dist/src/server/routes-workflows.js +83 -0
  72. package/dist/src/server/routes-workspaces.js +5 -0
  73. package/dist/src/server/routes.js +4 -0
  74. package/dist/src/server/runtime-restart-policy.d.ts +3 -1
  75. package/dist/src/server/runtime-restart-policy.js +2 -1
  76. package/dist/src/server/runtime-store-contract.d.ts +125 -0
  77. package/dist/src/server/runtime-store-contract.js +1 -0
  78. package/dist/src/server/runtime-store-helpers.d.ts +11 -0
  79. package/dist/src/server/runtime-store-helpers.js +106 -2
  80. package/dist/src/server/runtime-store-workflows.d.ts +6 -0
  81. package/dist/src/server/runtime-store-workflows.js +108 -0
  82. package/dist/src/server/runtime-store.d.ts +3 -72
  83. package/dist/src/server/runtime-store.js +71 -4
  84. package/dist/src/server/session-capture-codex.d.ts +3 -3
  85. package/dist/src/server/session-capture-codex.js +9 -7
  86. package/dist/src/server/session-capture-gemini.d.ts +1 -1
  87. package/dist/src/server/session-capture-gemini.js +6 -3
  88. package/dist/src/server/settings-store.d.ts +3 -0
  89. package/dist/src/server/settings-store.js +1 -0
  90. package/dist/src/server/sqlite-schema-v19.d.ts +2 -0
  91. package/dist/src/server/sqlite-schema-v19.js +17 -0
  92. package/dist/src/server/sqlite-schema-v20.d.ts +2 -0
  93. package/dist/src/server/sqlite-schema-v20.js +20 -0
  94. package/dist/src/server/sqlite-schema-v21.d.ts +2 -0
  95. package/dist/src/server/sqlite-schema-v21.js +20 -0
  96. package/dist/src/server/sqlite-schema.d.ts +1 -1
  97. package/dist/src/server/sqlite-schema.js +110 -1
  98. package/dist/src/server/system-message.d.ts +7 -0
  99. package/dist/src/server/system-message.js +8 -1
  100. package/dist/src/server/task-deps.d.ts +32 -0
  101. package/dist/src/server/task-deps.js +40 -0
  102. package/dist/src/server/tasks-file-watcher.d.ts +12 -1
  103. package/dist/src/server/tasks-file-watcher.js +128 -23
  104. package/dist/src/server/tasks-file.d.ts +3 -1
  105. package/dist/src/server/tasks-file.js +33 -9
  106. package/dist/src/server/tasks-websocket-server.js +13 -14
  107. package/dist/src/server/team-authz.d.ts +1 -1
  108. package/dist/src/server/team-authz.js +10 -1
  109. package/dist/src/server/team-autostaff.d.ts +16 -0
  110. package/dist/src/server/team-autostaff.js +16 -0
  111. package/dist/src/server/team-list-serializer.d.ts +1 -1
  112. package/dist/src/server/team-list-serializer.js +3 -1
  113. package/dist/src/server/team-operations.d.ts +21 -1
  114. package/dist/src/server/team-operations.js +183 -16
  115. package/dist/src/server/terminal-protocol.js +9 -3
  116. package/dist/src/server/terminal-stream-hub.js +16 -10
  117. package/dist/src/server/terminal-ws-server.js +10 -8
  118. package/dist/src/server/webhook-notifier.d.ts +34 -0
  119. package/dist/src/server/webhook-notifier.js +47 -0
  120. package/dist/src/server/websocket-upgrade-safety.d.ts +10 -0
  121. package/dist/src/server/websocket-upgrade-safety.js +35 -0
  122. package/dist/src/server/windows-command-line.d.ts +3 -0
  123. package/dist/src/server/windows-command-line.js +9 -0
  124. package/dist/src/server/windows-filename.d.ts +2 -0
  125. package/dist/src/server/windows-filename.js +33 -0
  126. package/dist/src/server/workflow-cli-policy.d.ts +60 -0
  127. package/dist/src/server/workflow-cli-policy.js +110 -0
  128. package/dist/src/server/workflow-dispatch-awaiter.d.ts +12 -0
  129. package/dist/src/server/workflow-dispatch-awaiter.js +80 -0
  130. package/dist/src/server/workflow-feature.d.ts +15 -0
  131. package/dist/src/server/workflow-feature.js +15 -0
  132. package/dist/src/server/workflow-http-serializers.d.ts +64 -0
  133. package/dist/src/server/workflow-http-serializers.js +58 -0
  134. package/dist/src/server/workflow-output-schema.d.ts +18 -0
  135. package/dist/src/server/workflow-output-schema.js +41 -0
  136. package/dist/src/server/workflow-run-log-store.d.ts +19 -0
  137. package/dist/src/server/workflow-run-log-store.js +45 -0
  138. package/dist/src/server/workflow-run-store.d.ts +50 -0
  139. package/dist/src/server/workflow-run-store.js +103 -0
  140. package/dist/src/server/workflow-runner.d.ts +147 -0
  141. package/dist/src/server/workflow-runner.js +411 -0
  142. package/dist/src/server/workflow-schedule-create.d.ts +14 -0
  143. package/dist/src/server/workflow-schedule-create.js +41 -0
  144. package/dist/src/server/workflow-schedule-store.d.ts +43 -0
  145. package/dist/src/server/workflow-schedule-store.js +112 -0
  146. package/dist/src/server/workflow-scheduler.d.ts +36 -0
  147. package/dist/src/server/workflow-scheduler.js +97 -0
  148. package/dist/src/server/workflow-script-loader.d.ts +34 -0
  149. package/dist/src/server/workflow-script-loader.js +106 -0
  150. package/dist/src/server/workspace-path-validation.js +16 -4
  151. package/dist/src/server/workspace-shell-runtime.d.ts +5 -0
  152. package/dist/src/server/workspace-shell-runtime.js +24 -2
  153. package/dist/src/server/workspace-store-contract.d.ts +4 -1
  154. package/dist/src/server/workspace-store-hydration.js +23 -7
  155. package/dist/src/server/workspace-store-mutations.js +2 -5
  156. package/dist/src/server/workspace-store-support.d.ts +4 -0
  157. package/dist/src/server/workspace-store-support.js +13 -1
  158. package/dist/src/server/workspace-store.js +38 -4
  159. package/dist/src/shared/types.d.ts +16 -1
  160. package/package.json +4 -2
  161. package/web/dist/assets/{AddWorkerDialog-DeZhTQLi.js → AddWorkerDialog-CGbaxu0T.js} +2 -2
  162. package/web/dist/assets/AddWorkspaceDialog-CNgExu6b.js +1 -0
  163. package/web/dist/assets/{FirstRunWizard-B5wLcat5.js → FirstRunWizard-DxGApUNc.js} +1 -1
  164. package/web/dist/assets/{MarketplaceDrawer-BC0eBOEW.js → MarketplaceDrawer-Bk6cpukn.js} +1 -1
  165. package/web/dist/assets/WhatsNewDialog-CSGzk-2U.js +1 -0
  166. package/web/dist/assets/WorkerModal-i2F3n3nZ.js +1 -0
  167. package/web/dist/assets/WorkspaceTaskDrawer-C_Ta_K13.js +1 -0
  168. package/web/dist/assets/WorkspaceTerminalPanels-VdDxtrQF.js +1 -0
  169. package/web/dist/assets/index-5zh61jMg.css +1 -0
  170. package/web/dist/assets/index-CAgGM6nb.js +75 -0
  171. package/web/dist/assets/path-join-7MR1s7b1.js +1 -0
  172. package/web/dist/index.html +2 -2
  173. package/web/dist/sw.js +1 -1
  174. package/web/dist/assets/AddWorkspaceDialog-DDpXNEKf.js +0 -1
  175. package/web/dist/assets/WorkerModal-BwMHq-Bi.js +0 -1
  176. package/web/dist/assets/WorkspaceTaskDrawer-CxvT4nqs.js +0 -1
  177. package/web/dist/assets/WorkspaceTerminalPanels-CvibsPSd.js +0 -1
  178. package/web/dist/assets/index-BEsTmfrO.css +0 -1
  179. package/web/dist/assets/index-Ddb7bDN5.js +0 -75
  180. package/web/dist/assets/path-join-S7qkXQtP.js +0 -1
@@ -0,0 +1,125 @@
1
+ import type { AgentSummary, TeamListItem, WorkspaceSummary } from '../shared/types.js';
2
+ import type { AgentManager } from './agent-manager.js';
3
+ import type { AgentLaunchConfigInput, PersistedAgentRun } from './agent-run-store.js';
4
+ import type { LiveAgentRun } from './agent-runtime-types.js';
5
+ import type { DispatchRecord, ListDispatchesOptions } from './dispatch-ledger-store.js';
6
+ import type { RecoveryMessage } from './message-log-store.js';
7
+ import type { PtyOutputBus } from './pty-output-bus.js';
8
+ import type { SettingsStore } from './settings-store.js';
9
+ import type { CancelTaskInput, DispatchTaskInput, ReportTaskInput, ReportTaskResult, StatusTaskInput } from './team-operations.js';
10
+ import type { TerminalRunSummary } from './terminal-input-profile.js';
11
+ import type { WorkflowDispatchAwaiter } from './workflow-dispatch-awaiter.js';
12
+ import type { WorkflowRunRecord } from './workflow-run-store.js';
13
+ import type { RunInlineWorkflowInput, RunWorkflowInput, WorkflowRunner } from './workflow-runner.js';
14
+ import type { WorkflowScheduleRecord } from './workflow-schedule-store.js';
15
+ import type { WorkerInput, WorkspaceRecord } from './workspace-store.js';
16
+ export interface RuntimeStore {
17
+ close: () => Promise<void>;
18
+ createWorkspace: (path: string, name: string) => WorkspaceSummary;
19
+ deleteWorkspace: (workspaceId: string) => Promise<void>;
20
+ listWorkspaces: () => WorkspaceSummary[];
21
+ addWorker: (workspaceId: string, input: WorkerInput) => AgentSummary;
22
+ addWorkerWithLaunch: (workspaceId: string, input: WorkerInput, launchConfig: AgentLaunchConfigInput) => AgentSummary;
23
+ deleteWorker: (workspaceId: string, workerId: string) => void;
24
+ renameWorker: (workspaceId: string, workerId: string, name: string) => AgentSummary;
25
+ recordUserInput: (workspaceId: string, orchestratorId: string, text: string) => void;
26
+ dispatchTask: (workspaceId: string, workerId: string, text: string, input?: DispatchTaskInput) => Promise<DispatchRecord>;
27
+ dispatchTaskByWorkerName: (workspaceId: string, workerName: string, text: string, input?: DispatchTaskInput) => Promise<DispatchRecord & {
28
+ restartedWorker: boolean;
29
+ }>;
30
+ reportTask: (workspaceId: string, workerId: string, input?: ReportTaskInput) => ReportTaskResult;
31
+ /** Flush any reports stranded by a prior orchestrator outage. Safe no-op
32
+ * when the orchestrator is down or the outbox is empty. */
33
+ drainReportOutbox: (workspaceId: string) => void;
34
+ statusTask: (workspaceId: string, workerId: string, input?: StatusTaskInput) => ReportTaskResult;
35
+ cancelTask: (workspaceId: string, dispatchId: string, input: CancelTaskInput) => ReportTaskResult;
36
+ listDispatches: (workspaceId: string, options?: ListDispatchesOptions) => DispatchRecord[];
37
+ listWorkers: (workspaceId: string) => TeamListItem[];
38
+ getLastPtyLineForAgent: (workspaceId: string, agentId: string) => string | null;
39
+ getWorkspaceSnapshot: (workspaceId: string) => WorkspaceRecord;
40
+ getWorker: (workspaceId: string, workerId: string) => AgentSummary;
41
+ getAgent: (workspaceId: string, agentId: string) => AgentSummary;
42
+ getPtyOutputBus: () => PtyOutputBus;
43
+ listTerminalRuns: (workspaceId: string) => TerminalRunSummary[];
44
+ closeWorkspaceShell: (workspaceId: string, runId: string) => boolean;
45
+ startWorkspaceShell: (workspaceId: string) => Promise<LiveAgentRun>;
46
+ configureAgentLaunch: (workspaceId: string, agentId: string, input: AgentLaunchConfigInput) => void;
47
+ peekAgentLaunchConfig: (workspaceId: string, agentId: string) => AgentLaunchConfigInput | undefined;
48
+ startAgent: (workspaceId: string, agentId: string, input: StartAgentOptions) => Promise<LiveAgentRun>;
49
+ autostartConfiguredAgents: (input: StartAgentOptions) => Promise<Array<{
50
+ agent_id: string;
51
+ error: string | null;
52
+ ok: boolean;
53
+ run_id: string | null;
54
+ workspace_id: string;
55
+ }>>;
56
+ startWorkspaceWatch: (workspaceId: string) => Promise<void>;
57
+ getLiveRun: (runId: string) => LiveAgentRun;
58
+ getActiveRunByAgentId: (workspaceId: string, agentId: string) => LiveAgentRun | undefined;
59
+ registerTasksListener: (listener: (workspaceId: string, content: string) => void) => () => void;
60
+ listAgentRuns: (agentId: string) => PersistedAgentRun[];
61
+ listMessagesForRecovery: (workspaceId: string, sinceMs: number) => RecoveryMessage[];
62
+ peekAgentToken: (agentId: string) => string | undefined;
63
+ pauseTerminalRun: (runId: string) => void;
64
+ resizeAgentRun: (runId: string, cols: number, rows: number) => void;
65
+ resumeTerminalRun: (runId: string) => void;
66
+ settings: SettingsStore;
67
+ writeRunInput: (runId: string, input: Buffer | string) => void;
68
+ getUiToken: () => string;
69
+ stopAgentRun: (runId: string) => void;
70
+ validateAgentToken: (agentId: string, token: string | undefined) => boolean;
71
+ validateUiToken: (token: string | undefined) => boolean;
72
+ getWorkflowDispatchAwaiter: () => WorkflowDispatchAwaiter;
73
+ runWorkflow: (input: RunWorkflowInput) => Promise<WorkflowRunRecord>;
74
+ startWorkflow: (input: RunWorkflowInput) => Promise<WorkflowRunRecord>;
75
+ startWorkflowInline: (input: RunInlineWorkflowInput) => Promise<WorkflowRunRecord>;
76
+ stopWorkflowRun: (runId: string) => boolean;
77
+ getWorkflowRun: (runId: string) => WorkflowRunRecord | undefined;
78
+ listWorkspaceWorkflowRuns: (workspaceId: string) => WorkflowRunRecord[];
79
+ listWorkflowRunDispatches: (runId: string) => DispatchRecord[];
80
+ listWorkflowRunLogs: (runId: string) => Array<{
81
+ id: number;
82
+ ts: number;
83
+ message: string;
84
+ }>;
85
+ createWorkflowSchedule: (input: {
86
+ workspaceId: string;
87
+ scriptPath: string;
88
+ cron: string;
89
+ nextRunAt: number;
90
+ args?: unknown;
91
+ enabled?: boolean;
92
+ }) => WorkflowScheduleRecord;
93
+ scheduleWorkflowInline: (input: {
94
+ workspaceId: string;
95
+ source: string;
96
+ name: string;
97
+ cron: string;
98
+ nextRunAt: number;
99
+ args?: unknown;
100
+ }) => Promise<WorkflowScheduleRecord>;
101
+ updateWorkflowSchedule: (id: string, input: {
102
+ cron?: string;
103
+ args?: unknown;
104
+ enabled?: boolean;
105
+ lastRunAt?: number;
106
+ nextRunAt?: number;
107
+ }) => void;
108
+ getWorkflowSchedule: (id: string) => WorkflowScheduleRecord | undefined;
109
+ listWorkspaceWorkflowSchedules: (workspaceId: string) => WorkflowScheduleRecord[];
110
+ deleteWorkflowSchedule: (id: string) => void;
111
+ }
112
+ export interface RuntimeStoreOptions {
113
+ dataDir?: string;
114
+ agentManager?: AgentManager;
115
+ }
116
+ export interface StartAgentOptions {
117
+ hivePort: string;
118
+ }
119
+ export type RuntimeWorkflowRuntime = {
120
+ runner: WorkflowRunner;
121
+ scheduler: {
122
+ close: () => void;
123
+ start: () => void;
124
+ };
125
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -11,7 +11,12 @@ import { createTasksFileService } from './tasks-file.js';
11
11
  import { createTasksFileWatcher } from './tasks-file-watcher.js';
12
12
  import { createTeamOperations } from './team-operations.js';
13
13
  import { createUiAuth } from './ui-auth.js';
14
+ import { createWebhookNotifier } from './webhook-notifier.js';
14
15
  import { type WorkerOutputTracker } from './worker-output-tracker.js';
16
+ import { type WorkflowDispatchAwaiter } from './workflow-dispatch-awaiter.js';
17
+ import { createWorkflowRunLogStore } from './workflow-run-log-store.js';
18
+ import { createWorkflowRunStore } from './workflow-run-store.js';
19
+ import { createWorkflowScheduleStore } from './workflow-schedule-store.js';
15
20
  import { createWorkspaceShellRuntime } from './workspace-shell-runtime.js';
16
21
  import { createWorkspaceStore } from './workspace-store.js';
17
22
  export interface RuntimeStoreServices {
@@ -27,7 +32,12 @@ export interface RuntimeStoreServices {
27
32
  tasksFileService: ReturnType<typeof createTasksFileService>;
28
33
  teamOps: ReturnType<typeof createTeamOperations>;
29
34
  uiAuth: ReturnType<typeof createUiAuth>;
35
+ webhookNotifier: ReturnType<typeof createWebhookNotifier>;
30
36
  workerOutputTracker: WorkerOutputTracker | null;
37
+ workflowDispatchAwaiter: WorkflowDispatchAwaiter;
38
+ workflowRunLogStore: ReturnType<typeof createWorkflowRunLogStore>;
39
+ workflowRunStore: ReturnType<typeof createWorkflowRunStore>;
40
+ workflowScheduleStore: ReturnType<typeof createWorkflowScheduleStore>;
31
41
  workspaceStore: ReturnType<typeof createWorkspaceStore>;
32
42
  }
33
43
  interface CreateRuntimeStoreServicesOptions {
@@ -38,6 +48,7 @@ interface CreateRuntimeStoreLifecycleOptions {
38
48
  agentManager?: AgentManager;
39
49
  services: RuntimeStoreServices;
40
50
  }
51
+ export declare const logTasksFileWatchStartError: (workspaceId: string, error: unknown) => void;
41
52
  export declare const createRuntimeStoreServices: (options?: CreateRuntimeStoreServicesOptions) => RuntimeStoreServices;
42
53
  export declare const createRuntimeStoreLifecycle: ({ agentManager, services, }: CreateRuntimeStoreLifecycleOptions) => {
43
54
  close: () => Promise<void>;
@@ -2,8 +2,10 @@ import { createAgentRunStore } from './agent-run-store.js';
2
2
  import { createAgentRuntime } from './agent-runtime.js';
3
3
  import { createAgentSessionStore } from './agent-session-store.js';
4
4
  import { createDispatchLedgerStore } from './dispatch-ledger-store.js';
5
+ import { readFeatureFlags } from './feature-flags.js';
5
6
  import { createMessageLogStore } from './message-log-store.js';
6
7
  import { seedOrchestratorLaunchConfig } from './orchestrator-launch.js';
8
+ import { createReportOutboxStore } from './report-outbox-store.js';
7
9
  import { openRuntimeDatabase } from './runtime-database.js';
8
10
  import { buildRuntimeRestartPolicy } from './runtime-restart-policy.js';
9
11
  import { createSettingsStore } from './settings-store.js';
@@ -12,35 +14,59 @@ import { createTasksFileWatcher } from './tasks-file-watcher.js';
12
14
  import { createTeamOperations } from './team-operations.js';
13
15
  import { resolveTerminalInputProfile } from './terminal-input-profile.js';
14
16
  import { createUiAuth } from './ui-auth.js';
17
+ import { createWebhookNotifier, WEBHOOK_URL_KEY } from './webhook-notifier.js';
15
18
  import { createWorkerOutputTracker } from './worker-output-tracker.js';
19
+ import { readWorkflowCliPolicy, WORKFLOW_CLI_POLICY_KEY } from './workflow-cli-policy.js';
20
+ import { createWorkflowDispatchAwaiter, } from './workflow-dispatch-awaiter.js';
21
+ import { createWorkflowRunLogStore } from './workflow-run-log-store.js';
22
+ import { createWorkflowRunStore } from './workflow-run-store.js';
23
+ import { createWorkflowScheduleStore } from './workflow-schedule-store.js';
16
24
  import { createWorkspaceShellRuntime } from './workspace-shell-runtime.js';
17
25
  import { createWorkspaceStore } from './workspace-store.js';
26
+ import { getOrchestratorId } from './workspace-store-support.js';
18
27
  const notifyTasksUpdated = (callbacks, workspaceId, content) => {
19
28
  for (const callback of callbacks) {
20
29
  callback(workspaceId, content);
21
30
  }
22
31
  };
32
+ export const logTasksFileWatchStartError = (workspaceId, error) => {
33
+ console.error(`[hive] failed to start tasks watcher for workspace ${workspaceId}`, error);
34
+ };
23
35
  export const createRuntimeStoreServices = (options = {}) => {
24
36
  const db = openRuntimeDatabase(options.dataDir);
25
37
  const messageLogStore = createMessageLogStore(db);
26
38
  const dispatchLedgerStore = createDispatchLedgerStore(db);
39
+ const reportOutbox = createReportOutboxStore(db);
40
+ const workflowDispatchAwaiter = createWorkflowDispatchAwaiter();
41
+ const workflowRunStore = createWorkflowRunStore(db);
42
+ const workflowRunLogStore = createWorkflowRunLogStore(db);
43
+ const workflowScheduleStore = createWorkflowScheduleStore(db);
27
44
  const agentRunStore = createAgentRunStore(db);
28
45
  const agentSessionStore = createAgentSessionStore(db);
29
46
  const settings = createSettingsStore(db);
47
+ const getFlags = () => readFeatureFlags(settings);
48
+ const webhookNotifier = createWebhookNotifier({
49
+ getUrl: () => settings.getAppState(WEBHOOK_URL_KEY)?.value ?? null,
50
+ });
30
51
  const tasksFileService = createTasksFileService();
31
52
  const tasksFileWatchCallbacks = new Set();
32
53
  const tasksFileWatcher = createTasksFileWatcher({
33
54
  onTasksUpdated: (workspaceId, content) => {
34
55
  notifyTasksUpdated(tasksFileWatchCallbacks, workspaceId, content);
35
56
  },
57
+ getWorkflowCliPolicy: () => readWorkflowCliPolicy(settings.getAppState(WORKFLOW_CLI_POLICY_KEY)?.value ?? null),
58
+ getFlags,
36
59
  });
37
60
  const uiAuth = createUiAuth();
38
61
  const shellRuntime = createWorkspaceShellRuntime(options.agentManager);
39
62
  agentRunStore.markUnfinishedRunsStale();
63
+ workflowRunStore.markUnfinishedRunsInterrupted();
40
64
  const workspaceStore = createWorkspaceStore(db, dispatchLedgerStore.listOpenDispatchKinds());
41
65
  const startExistingWorkspaceWatches = () => {
42
66
  for (const workspace of workspaceStore.listWorkspaces()) {
43
- void tasksFileWatcher.start(workspace.id, workspace.path);
67
+ void tasksFileWatcher
68
+ .start(workspace.id, workspace.path)
69
+ .catch((error) => logTasksFileWatchStartError(workspace.id, error));
44
70
  }
45
71
  };
46
72
  const restartPolicy = buildRuntimeRestartPolicy({
@@ -48,6 +74,7 @@ export const createRuntimeStoreServices = (options = {}) => {
48
74
  messageLogStore,
49
75
  tasksFileService,
50
76
  workspaceStore,
77
+ getFlags,
51
78
  });
52
79
  const workerOutputTracker = options.agentManager
53
80
  ? createWorkerOutputTracker(options.agentManager.getOutputBus())
@@ -57,7 +84,70 @@ export const createRuntimeStoreServices = (options = {}) => {
57
84
  if (!workspaceStore.hasAgent(workspaceId, agentId))
58
85
  return;
59
86
  workspaceStore.markAgentStopped(workspaceId, agentId);
60
- }, restartPolicy, (workspaceId, agentId) => workspaceStore.getAgent(workspaceId, agentId));
87
+ // TIER 1 #1 if the exiting worker had any open workflow dispatches,
88
+ // tell the workflow awaiter so the runner's `awaitReport` rejects
89
+ // immediately instead of hanging until DEFAULT_TIMEOUT_MS (10 min).
90
+ // This is the only signal the runtime has that an ephemeral
91
+ // workflow worker died without calling `team report`.
92
+ const openWorkflowDispatches = dispatchLedgerStore.listOpenWorkflowDispatchesForWorker(workspaceId, agentId);
93
+ for (const { dispatchId } of openWorkflowDispatches) {
94
+ try {
95
+ const cancelled = dispatchLedgerStore.markCancelled({
96
+ dispatchId,
97
+ reason: 'worker PTY exited before report',
98
+ workspaceId,
99
+ });
100
+ if (!cancelled)
101
+ continue;
102
+ try {
103
+ workspaceStore.markTaskCancelled(workspaceId, agentId);
104
+ }
105
+ catch (error) {
106
+ console.error('[hive] onAgentExit.markTaskCancelled failed', dispatchId, error);
107
+ }
108
+ workflowDispatchAwaiter.notifyCancel(dispatchId, 'worker PTY exited before report');
109
+ }
110
+ catch (error) {
111
+ console.error('[hive] onAgentExit.markCancelled failed', dispatchId, error);
112
+ }
113
+ }
114
+ // Cascade: when the orchestrator's PTY exits, dismiss the ephemeral
115
+ // workers it spawned via `team spawn` (spec §6.3). Workflow-spawned
116
+ // workers are owned by the runner, not the orchestrator.
117
+ if (agentId === getOrchestratorId(workspaceId)) {
118
+ const children = workspaceStore
119
+ .getWorkspaceSnapshot(workspaceId)
120
+ .agents.filter((agent) => agent.ephemeral === true && agent.spawnedBy === 'orchestrator');
121
+ for (const child of children)
122
+ removeWorkerCompletely(workspaceId, child.id);
123
+ }
124
+ }, restartPolicy, (workspaceId, agentId) => workspaceStore.getAgent(workspaceId, agentId), getFlags);
125
+ // Mirrors runtime-store.deleteWorker (stop run → drop launch config → drop
126
+ // dispatches → drop worker row, transactionally). Hoisted `function` so the
127
+ // onAgentExit closure above can reference it; only invoked at runtime, after
128
+ // agentRuntime is assigned.
129
+ function removeWorkerCompletely(workspaceId, workerId) {
130
+ const activeRun = agentRuntime.getActiveRunByAgentId(workspaceId, workerId);
131
+ if (activeRun)
132
+ agentRuntime.stopAgentRun(activeRun.runId);
133
+ agentRuntime.deleteAgentLaunchConfig(workspaceId, workerId);
134
+ db.transaction(() => {
135
+ dispatchLedgerStore.deleteWorkerDispatches(workspaceId, workerId);
136
+ workspaceStore.deleteWorker(workspaceId, workerId);
137
+ })();
138
+ }
139
+ // Boot cleanup: after a runtime restart every ephemeral worker is an orphan
140
+ // (its spawner — a workflow run or an orchestrator PTY — is gone). Remove
141
+ // them so they don't accumulate (spec §6.3).
142
+ const cleanupOrphanEphemeralWorkers = () => {
143
+ for (const workspace of workspaceStore.listWorkspaces()) {
144
+ const ephemeral = workspaceStore
145
+ .getWorkspaceSnapshot(workspace.id)
146
+ .agents.filter((agent) => agent.ephemeral === true);
147
+ for (const agent of ephemeral)
148
+ removeWorkerCompletely(workspace.id, agent.id);
149
+ }
150
+ };
61
151
  const teamOps = createTeamOperations({
62
152
  agentRuntime,
63
153
  createDispatch: dispatchLedgerStore.createDispatch,
@@ -69,8 +159,13 @@ export const createRuntimeStoreServices = (options = {}) => {
69
159
  markDispatchCancelled: dispatchLedgerStore.markCancelled,
70
160
  markDispatchReportedByWorker: dispatchLedgerStore.markReportedByWorker,
71
161
  markDispatchSubmitted: dispatchLedgerStore.markSubmitted,
162
+ reportOutbox,
163
+ notifyWebhook: webhookNotifier.notify,
164
+ workflowDispatchAwaiter,
72
165
  workspaceStore,
166
+ dismissEphemeralWorker: (workspaceId, workerId) => removeWorkerCompletely(workspaceId, workerId),
73
167
  });
168
+ cleanupOrphanEphemeralWorkers();
74
169
  startExistingWorkspaceWatches();
75
170
  return {
76
171
  agentRunStore,
@@ -85,7 +180,12 @@ export const createRuntimeStoreServices = (options = {}) => {
85
180
  tasksFileService,
86
181
  teamOps,
87
182
  uiAuth,
183
+ webhookNotifier,
88
184
  workerOutputTracker,
185
+ workflowDispatchAwaiter,
186
+ workflowRunLogStore,
187
+ workflowRunStore,
188
+ workflowScheduleStore,
89
189
  workspaceStore,
90
190
  };
91
191
  };
@@ -143,6 +243,10 @@ export const createRuntimeStoreLifecycle = ({ agentManager, services, }) => {
143
243
  };
144
244
  return {
145
245
  close: async () => {
246
+ // Fail in-flight workflow awaiters BEFORE their workers vanish, so the
247
+ // runner's `await agent(...)` rejects with a clear shutdown error
248
+ // instead of hanging on a Promise that can never resolve.
249
+ services.workflowDispatchAwaiter.cancelAll('runtime closing');
146
250
  services.shellRuntime.close();
147
251
  await services.agentRuntime.close();
148
252
  await services.tasksFileWatcher.close();
@@ -0,0 +1,6 @@
1
+ import type { RuntimeStore } from './runtime-store-contract.js';
2
+ import type { RuntimeStoreServices } from './runtime-store-helpers.js';
3
+ export declare const createRuntimeStoreWorkflowRuntime: (services: RuntimeStoreServices, store: RuntimeStore) => {
4
+ runner: import("./workflow-runner.js").WorkflowRunner;
5
+ scheduler: import("./workflow-scheduler.js").WorkflowScheduler;
6
+ };
@@ -0,0 +1,108 @@
1
+ import { readWorkflowCliPolicy, WORKFLOW_CLI_POLICY_KEY } from './workflow-cli-policy.js';
2
+ import { readWorkflowEnabled, WORKFLOW_ENABLED_KEY } from './workflow-feature.js';
3
+ import { createWorkflowRunner } from './workflow-runner.js';
4
+ import { createWorkflowScheduler } from './workflow-scheduler.js';
5
+ export const createRuntimeStoreWorkflowRuntime = (services, store) => {
6
+ const runner = createWorkflowRunner({
7
+ awaiter: services.workflowDispatchAwaiter,
8
+ workflowRunStore: services.workflowRunStore,
9
+ dispatchPort: {
10
+ listOpenDispatchIdsForRun: (runId) => services.dispatchLedgerStore.listOpenDispatchIdsForRun(runId),
11
+ },
12
+ resolveWorkspacePath: (workspaceId) => services.workspaceStore.getWorkspaceSnapshot(workspaceId).summary.path,
13
+ logStore: {
14
+ append: (runId, message, ts) => services.workflowRunLogStore.append(runId, message, ts),
15
+ },
16
+ getWorkflowCliPolicy: () => readWorkflowCliPolicy(services.settings.getAppState(WORKFLOW_CLI_POLICY_KEY)?.value ?? null),
17
+ roleTemplateResolver: {
18
+ findByName: (name) => {
19
+ const t = services.settings.findRoleTemplateByName(name);
20
+ if (!t)
21
+ return undefined;
22
+ return {
23
+ name: t.name,
24
+ roleType: t.roleType,
25
+ defaultCommand: t.defaultCommand,
26
+ defaultArgs: t.defaultArgs,
27
+ };
28
+ },
29
+ },
30
+ onRunFinished: ({ runId, triggeredByAgentId, finalRecord }) => {
31
+ const workspaceId = finalRecord.workspaceId;
32
+ const dispatches = services.dispatchLedgerStore.listWorkflowRunDispatches(runId);
33
+ const errorLine = finalRecord.error ? `\nerror: ${finalRecord.error}` : '';
34
+ const dispatchSummary = dispatches.length === 0
35
+ ? '\n(no agent() calls in this run)'
36
+ : '\n' +
37
+ dispatches
38
+ .map((d) => {
39
+ const reply = d.reportText
40
+ ? d.reportText.length > 200
41
+ ? `${d.reportText.slice(0, 197).trim()}...`
42
+ : d.reportText.trim()
43
+ : `(no report; status=${d.status})`;
44
+ return ` #${d.stepIndex ?? '?'} -> ${reply}`;
45
+ })
46
+ .join('\n');
47
+ const resultBlock = (() => {
48
+ if (finalRecord.result === null || finalRecord.result === undefined)
49
+ return '';
50
+ const serialized = typeof finalRecord.result === 'string'
51
+ ? finalRecord.result
52
+ : JSON.stringify(finalRecord.result, null, 2);
53
+ const truncated = serialized.length > 4000
54
+ ? `${serialized.slice(0, 4000)}\n...(truncated; ${serialized.length - 4000} more chars)`
55
+ : serialized;
56
+ return `\nResult (workflow return value):\n${truncated}`;
57
+ })();
58
+ const logTail = services.workflowRunLogStore.tailForRun(runId, 8);
59
+ const logBlock = logTail.length === 0
60
+ ? ''
61
+ : `\nNarrator (last ${logTail.length} log line${logTail.length === 1 ? '' : 's'}):\n` +
62
+ logTail.map((line) => ` - ${line}`).join('\n');
63
+ const payload = '<hive-system-reminder>\n' +
64
+ `Hive workflow \`${finalRecord.name}\` finished: status=${finalRecord.status}` +
65
+ ` (run_id=${runId}, ${dispatches.length} agent call${dispatches.length === 1 ? '' : 's'}).` +
66
+ errorLine +
67
+ resultBlock +
68
+ logBlock +
69
+ dispatchSummary +
70
+ '\nThis result is what you should synthesize back to the user. ' +
71
+ 'Per-agent transcripts are available via `team workflow show ' +
72
+ runId +
73
+ '` if needed.\n' +
74
+ '</hive-system-reminder>\n';
75
+ try {
76
+ services.agentRuntime.writeSystemMessageToAgent(workspaceId, triggeredByAgentId, payload);
77
+ }
78
+ catch (error) {
79
+ console.error('[hive] workflow.notifyTrigger failed', error);
80
+ }
81
+ // Outbound completion webhook (best-effort) so the user is pinged when a
82
+ // long fan-out finishes without watching the drawer.
83
+ services.webhookNotifier.notify({
84
+ type: 'workflow_finished',
85
+ workspaceId,
86
+ summary: `${finalRecord.name}: ${finalRecord.status}${finalRecord.error ? ` — ${finalRecord.error}` : ''}`,
87
+ at: Date.now(),
88
+ });
89
+ },
90
+ store: {
91
+ addWorkerWithLaunch: (ws, input, launch) => store.addWorkerWithLaunch(ws, input, launch),
92
+ deleteWorker: (ws, workerId) => store.deleteWorker(ws, workerId),
93
+ dispatchTaskByWorkerName: async (ws, name, text, input) => {
94
+ const dispatch = await store.dispatchTaskByWorkerName(ws, name, text, input);
95
+ return { id: dispatch.id };
96
+ },
97
+ startAgent: (ws, agentId, input) => store.startAgent(ws, agentId, input),
98
+ },
99
+ });
100
+ const scheduler = createWorkflowScheduler({
101
+ schedules: services.workflowScheduleStore,
102
+ startWorkflow: (input) => store.startWorkflow(input),
103
+ workspaceExists: (workspaceId) => services.workspaceStore.hasWorkspace(workspaceId),
104
+ isWorkflowEnabled: () => readWorkflowEnabled(services.settings.getAppState(WORKFLOW_ENABLED_KEY)?.value ?? null),
105
+ });
106
+ scheduler.start();
107
+ return { runner, scheduler };
108
+ };
@@ -1,73 +1,4 @@
1
- import type { AgentSummary, TeamListItem, WorkspaceSummary } from '../shared/types.js';
2
- import type { AgentManager } from './agent-manager.js';
3
- import type { AgentLaunchConfigInput, PersistedAgentRun } from './agent-run-store.js';
4
- import type { LiveAgentRun } from './agent-runtime-types.js';
5
- import type { DispatchRecord, ListDispatchesOptions } from './dispatch-ledger-store.js';
6
- import type { RecoveryMessage } from './message-log-store.js';
7
- import type { PtyOutputBus } from './pty-output-bus.js';
8
- import type { SettingsStore } from './settings-store.js';
9
- import type { CancelTaskInput, DispatchTaskInput, ReportTaskInput, ReportTaskResult, StatusTaskInput } from './team-operations.js';
10
- import type { TerminalRunSummary } from './terminal-input-profile.js';
11
- import type { WorkerInput, WorkspaceRecord } from './workspace-store.js';
12
- interface RuntimeStore {
13
- close: () => Promise<void>;
14
- createWorkspace: (path: string, name: string) => WorkspaceSummary;
15
- deleteWorkspace: (workspaceId: string) => Promise<void>;
16
- listWorkspaces: () => WorkspaceSummary[];
17
- addWorker: (workspaceId: string, input: WorkerInput) => AgentSummary;
18
- deleteWorker: (workspaceId: string, workerId: string) => void;
19
- renameWorker: (workspaceId: string, workerId: string, name: string) => AgentSummary;
20
- recordUserInput: (workspaceId: string, orchestratorId: string, text: string) => void;
21
- dispatchTask: (workspaceId: string, workerId: string, text: string, input?: DispatchTaskInput) => Promise<DispatchRecord>;
22
- dispatchTaskByWorkerName: (workspaceId: string, workerName: string, text: string, input?: DispatchTaskInput) => Promise<DispatchRecord & {
23
- restartedWorker: boolean;
24
- }>;
25
- reportTask: (workspaceId: string, workerId: string, input?: ReportTaskInput) => ReportTaskResult;
26
- statusTask: (workspaceId: string, workerId: string, input?: StatusTaskInput) => ReportTaskResult;
27
- cancelTask: (workspaceId: string, dispatchId: string, input: CancelTaskInput) => ReportTaskResult;
28
- listDispatches: (workspaceId: string, options?: ListDispatchesOptions) => DispatchRecord[];
29
- listWorkers: (workspaceId: string) => TeamListItem[];
30
- getLastPtyLineForAgent: (workspaceId: string, agentId: string) => string | null;
31
- getWorkspaceSnapshot: (workspaceId: string) => WorkspaceRecord;
32
- getWorker: (workspaceId: string, workerId: string) => AgentSummary;
33
- getAgent: (workspaceId: string, agentId: string) => AgentSummary;
34
- getPtyOutputBus: () => PtyOutputBus;
35
- listTerminalRuns: (workspaceId: string) => TerminalRunSummary[];
36
- closeWorkspaceShell: (workspaceId: string, runId: string) => boolean;
37
- startWorkspaceShell: (workspaceId: string) => Promise<LiveAgentRun>;
38
- configureAgentLaunch: (workspaceId: string, agentId: string, input: AgentLaunchConfigInput) => void;
39
- peekAgentLaunchConfig: (workspaceId: string, agentId: string) => AgentLaunchConfigInput | undefined;
40
- startAgent: (workspaceId: string, agentId: string, input: StartAgentOptions) => Promise<LiveAgentRun>;
41
- autostartConfiguredAgents: (input: StartAgentOptions) => Promise<Array<{
42
- agent_id: string;
43
- error: string | null;
44
- ok: boolean;
45
- run_id: string | null;
46
- workspace_id: string;
47
- }>>;
48
- startWorkspaceWatch: (workspaceId: string) => Promise<void>;
49
- getLiveRun: (runId: string) => LiveAgentRun;
50
- getActiveRunByAgentId: (workspaceId: string, agentId: string) => LiveAgentRun | undefined;
51
- registerTasksListener: (listener: (workspaceId: string, content: string) => void) => () => void;
52
- listAgentRuns: (agentId: string) => PersistedAgentRun[];
53
- listMessagesForRecovery: (workspaceId: string, sinceMs: number) => RecoveryMessage[];
54
- peekAgentToken: (agentId: string) => string | undefined;
55
- pauseTerminalRun: (runId: string) => void;
56
- resizeAgentRun: (runId: string, cols: number, rows: number) => void;
57
- resumeTerminalRun: (runId: string) => void;
58
- settings: SettingsStore;
59
- writeRunInput: (runId: string, input: Buffer | string) => void;
60
- getUiToken: () => string;
61
- stopAgentRun: (runId: string) => void;
62
- validateAgentToken: (agentId: string, token: string | undefined) => boolean;
63
- validateUiToken: (token: string | undefined) => boolean;
64
- }
65
- interface RuntimeStoreOptions {
66
- dataDir?: string;
67
- agentManager?: AgentManager;
68
- }
69
- interface StartAgentOptions {
70
- hivePort: string;
71
- }
72
- export type { RuntimeStore };
1
+ import type { RuntimeStore, RuntimeStoreOptions } from './runtime-store-contract.js';
2
+ import type { WorkflowRunRecord } from './workflow-run-store.js';
3
+ export type { RuntimeStore, WorkflowRunRecord };
73
4
  export declare const createRuntimeStore: (options?: RuntimeStoreOptions) => RuntimeStore;
@@ -1,4 +1,6 @@
1
- import { createRuntimeStoreLifecycle, createRuntimeStoreServices } from './runtime-store-helpers.js';
1
+ import { createRuntimeStoreLifecycle, createRuntimeStoreServices, logTasksFileWatchStartError, } from './runtime-store-helpers.js';
2
+ import { createRuntimeStoreWorkflowRuntime } from './runtime-store-workflows.js';
3
+ import { persistWorkflowSchedule } from './workflow-schedule-create.js';
2
4
  export const createRuntimeStore = (options = {}) => {
3
5
  const services = createRuntimeStoreServices(options);
4
6
  const lifecycle = createRuntimeStoreLifecycle(options.agentManager ? { agentManager: options.agentManager, services } : { services });
@@ -9,11 +11,22 @@ export const createRuntimeStore = (options = {}) => {
9
11
  }
10
12
  services.db.transaction(mutation)();
11
13
  };
12
- return {
13
- close: lifecycle.close,
14
+ let workflowRuntime;
15
+ const getWorkflowRuntime = () => {
16
+ if (!workflowRuntime)
17
+ throw new Error('Workflow runtime not initialized');
18
+ return workflowRuntime;
19
+ };
20
+ const store = {
21
+ close: async () => {
22
+ workflowRuntime?.scheduler.close();
23
+ await lifecycle.close();
24
+ },
14
25
  createWorkspace: (path, name) => {
15
26
  const workspace = services.workspaceStore.createWorkspace(path, name);
16
- void lifecycle.startWorkspaceWatch(workspace.id);
27
+ void lifecycle
28
+ .startWorkspaceWatch(workspace.id)
29
+ .catch((error) => logTasksFileWatchStartError(workspace.id, error));
17
30
  return workspace;
18
31
  },
19
32
  listWorkspaces: () => services.workspaceStore.listWorkspaces(),
@@ -36,6 +49,34 @@ export const createRuntimeStore = (options = {}) => {
36
49
  }
37
50
  },
38
51
  addWorker: (workspaceId, input) => services.workspaceStore.addWorker(workspaceId, input),
52
+ addWorkerWithLaunch: (workspaceId, input, launchConfig) => {
53
+ // Atomic spawn: create the worker AND its launch config together so a
54
+ // failure can never persist a worker with no way to start it. The DB
55
+ // transaction rolls back the row; the catch prunes the in-memory worker
56
+ // that addWorker already pushed into the workspace record.
57
+ let worker;
58
+ try {
59
+ runDataMutation(() => {
60
+ worker = store.addWorker(workspaceId, input);
61
+ store.configureAgentLaunch(workspaceId, worker.id, launchConfig);
62
+ });
63
+ }
64
+ catch (error) {
65
+ if (worker) {
66
+ try {
67
+ store.deleteWorker(workspaceId, worker.id);
68
+ }
69
+ catch {
70
+ // The transaction already removed the DB row; this only prunes the
71
+ // stale in-memory entry, which may already be gone.
72
+ }
73
+ }
74
+ throw error;
75
+ }
76
+ if (!worker)
77
+ throw new Error('addWorkerWithLaunch produced no worker');
78
+ return worker;
79
+ },
39
80
  renameWorker: (workspaceId, workerId, name) => services.workspaceStore.renameWorker(workspaceId, workerId, name),
40
81
  deleteWorker: (workspaceId, workerId) => {
41
82
  const activeRun = services.agentRuntime.getActiveRunByAgentId(workspaceId, workerId);
@@ -52,6 +93,7 @@ export const createRuntimeStore = (options = {}) => {
52
93
  dispatchTask: services.teamOps.dispatchTask,
53
94
  dispatchTaskByWorkerName: services.teamOps.dispatchTaskByWorkerName,
54
95
  reportTask: services.teamOps.reportTask,
96
+ drainReportOutbox: services.teamOps.drainReportOutbox,
55
97
  statusTask: services.teamOps.statusTask,
56
98
  listDispatches: services.dispatchLedgerStore.listWorkspaceDispatches,
57
99
  listWorkers: (workspaceId) => services.workspaceStore.listWorkers(workspaceId),
@@ -83,5 +125,30 @@ export const createRuntimeStore = (options = {}) => {
83
125
  stopAgentRun: lifecycle.stopTerminalRun,
84
126
  validateAgentToken: (agentId, token) => services.agentRuntime.validateAgentToken(agentId, token),
85
127
  validateUiToken: (token) => services.uiAuth.validate(token),
128
+ getWorkflowDispatchAwaiter: () => services.workflowDispatchAwaiter,
129
+ runWorkflow: (input) => getWorkflowRuntime().runner.runWorkflow(input),
130
+ startWorkflow: (input) => getWorkflowRuntime().runner.startWorkflow(input),
131
+ startWorkflowInline: (input) => getWorkflowRuntime().runner.startWorkflowInline(input),
132
+ stopWorkflowRun: (runId) => getWorkflowRuntime().runner.stopRun(runId),
133
+ getWorkflowRun: (runId) => services.workflowRunStore.getRun(runId),
134
+ listWorkspaceWorkflowRuns: (workspaceId) => services.workflowRunStore.listWorkspaceRuns(workspaceId),
135
+ listWorkflowRunDispatches: (runId) => services.dispatchLedgerStore.listWorkflowRunDispatches(runId),
136
+ listWorkflowRunLogs: (runId) => services.workflowRunLogStore.listForRun(runId).map((row) => ({
137
+ id: row.id,
138
+ ts: row.ts,
139
+ message: row.message,
140
+ })),
141
+ createWorkflowSchedule: (input) => services.workflowScheduleStore.create(input),
142
+ scheduleWorkflowInline: (input) => persistWorkflowSchedule({
143
+ workspacePath: services.workspaceStore.getWorkspaceSnapshot(input.workspaceId).summary.path,
144
+ scheduleStore: services.workflowScheduleStore,
145
+ ...input,
146
+ }),
147
+ updateWorkflowSchedule: (id, input) => services.workflowScheduleStore.update(id, input),
148
+ getWorkflowSchedule: (id) => services.workflowScheduleStore.get(id),
149
+ listWorkspaceWorkflowSchedules: (workspaceId) => services.workflowScheduleStore.listForWorkspace(workspaceId),
150
+ deleteWorkflowSchedule: (id) => services.workflowScheduleStore.deleteSchedule(id),
86
151
  };
152
+ workflowRuntime = createRuntimeStoreWorkflowRuntime(services, store);
153
+ return store;
87
154
  };