@tt-a1i/hive 1.7.0 → 2.0.2

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 (251) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/README.en.md +73 -11
  3. package/README.md +41 -8
  4. package/dist/src/cli/hive-remote.d.ts +46 -0
  5. package/dist/src/cli/hive-remote.js +257 -0
  6. package/dist/src/cli/hive-update.js +7 -2
  7. package/dist/src/cli/hive.d.ts +6 -0
  8. package/dist/src/cli/hive.js +64 -0
  9. package/dist/src/cli/team.d.ts +22 -0
  10. package/dist/src/cli/team.js +255 -5
  11. package/dist/src/server/agent-command-resolver.js +10 -3
  12. package/dist/src/server/agent-exit-classification.d.ts +6 -0
  13. package/dist/src/server/agent-exit-classification.js +6 -0
  14. package/dist/src/server/agent-manager-support.d.ts +2 -1
  15. package/dist/src/server/agent-manager-support.js +59 -15
  16. package/dist/src/server/agent-manager.d.ts +3 -0
  17. package/dist/src/server/agent-manager.js +22 -7
  18. package/dist/src/server/agent-run-bootstrap.d.ts +14 -0
  19. package/dist/src/server/agent-run-bootstrap.js +11 -4
  20. package/dist/src/server/agent-run-exit-handler.js +14 -8
  21. package/dist/src/server/agent-run-starter.d.ts +3 -1
  22. package/dist/src/server/agent-run-starter.js +22 -5
  23. package/dist/src/server/agent-run-sync.js +13 -5
  24. package/dist/src/server/agent-runtime-types.d.ts +1 -0
  25. package/dist/src/server/agent-runtime.d.ts +2 -1
  26. package/dist/src/server/agent-runtime.js +9 -2
  27. package/dist/src/server/agent-startup-instructions.d.ts +2 -1
  28. package/dist/src/server/agent-startup-instructions.js +8 -4
  29. package/dist/src/server/agent-stdin-dispatcher.d.ts +4 -2
  30. package/dist/src/server/agent-stdin-dispatcher.js +35 -3
  31. package/dist/src/server/command-preset-defaults.d.ts +6 -1
  32. package/dist/src/server/command-preset-defaults.js +56 -0
  33. package/dist/src/server/fs-browse.d.ts +2 -0
  34. package/dist/src/server/fs-browse.js +165 -31
  35. package/dist/src/server/fs-pick-folder.js +6 -69
  36. package/dist/src/server/fs-sandbox.d.ts +5 -3
  37. package/dist/src/server/fs-sandbox.js +5 -3
  38. package/dist/src/server/hive-team-guidance.js +18 -6
  39. package/dist/src/server/machine-name.d.ts +2 -0
  40. package/dist/src/server/machine-name.js +13 -0
  41. package/dist/src/server/open-target-commands.d.ts +1 -0
  42. package/dist/src/server/open-target-commands.js +4 -1
  43. package/dist/src/server/orchestrator-autostart.js +1 -1
  44. package/dist/src/server/platform-path.d.ts +1 -0
  45. package/dist/src/server/platform-path.js +14 -1
  46. package/dist/src/server/post-start-input-writer.js +50 -13
  47. package/dist/src/server/preset-launch-support.js +1 -0
  48. package/dist/src/server/recovery-summary.d.ts +2 -1
  49. package/dist/src/server/recovery-summary.js +2 -1
  50. package/dist/src/server/remote-audit-store.d.ts +51 -0
  51. package/dist/src/server/remote-audit-store.js +108 -0
  52. package/dist/src/server/remote-config-keys.d.ts +17 -0
  53. package/dist/src/server/remote-config-keys.js +27 -0
  54. package/dist/src/server/remote-control-constants.d.ts +30 -0
  55. package/dist/src/server/remote-control-constants.js +29 -0
  56. package/dist/src/server/remote-device-session.d.ts +40 -0
  57. package/dist/src/server/remote-device-session.js +22 -0
  58. package/dist/src/server/remote-device-store.d.ts +36 -0
  59. package/dist/src/server/remote-device-store.js +67 -0
  60. package/dist/src/server/remote-frame-bridge.d.ts +102 -0
  61. package/dist/src/server/remote-frame-bridge.js +791 -0
  62. package/dist/src/server/remote-gateway-client.d.ts +14 -0
  63. package/dist/src/server/remote-gateway-client.js +36 -0
  64. package/dist/src/server/remote-loopback-auth.d.ts +6 -0
  65. package/dist/src/server/remote-loopback-auth.js +112 -0
  66. package/dist/src/server/remote-pairing-tunnel.d.ts +59 -0
  67. package/dist/src/server/remote-pairing-tunnel.js +146 -0
  68. package/dist/src/server/remote-pairing.d.ts +58 -0
  69. package/dist/src/server/remote-pairing.js +237 -0
  70. package/dist/src/server/remote-tunnel.d.ts +113 -0
  71. package/dist/src/server/remote-tunnel.js +514 -0
  72. package/dist/src/server/restart-policy-support.d.ts +4 -1
  73. package/dist/src/server/restart-policy-support.js +3 -1
  74. package/dist/src/server/restart-policy.d.ts +1 -1
  75. package/dist/src/server/restart-policy.js +19 -3
  76. package/dist/src/server/route-types.d.ts +1 -1
  77. package/dist/src/server/routes-dispatches.js +1 -1
  78. package/dist/src/server/routes-fs.js +3 -3
  79. package/dist/src/server/routes-marketplace.js +2 -2
  80. package/dist/src/server/routes-open-workspace.js +1 -1
  81. package/dist/src/server/routes-remote.d.ts +2 -0
  82. package/dist/src/server/routes-remote.js +166 -0
  83. package/dist/src/server/routes-runtime.js +6 -6
  84. package/dist/src/server/routes-settings.js +16 -16
  85. package/dist/src/server/routes-tasks.js +2 -2
  86. package/dist/src/server/routes-team-memory.d.ts +2 -0
  87. package/dist/src/server/routes-team-memory.js +154 -0
  88. package/dist/src/server/routes-team-recall.d.ts +2 -0
  89. package/dist/src/server/routes-team-recall.js +119 -0
  90. package/dist/src/server/routes-team.js +31 -9
  91. package/dist/src/server/routes-ui.js +11 -1
  92. package/dist/src/server/routes-workflow-schedules.js +3 -3
  93. package/dist/src/server/routes-workflows.js +5 -5
  94. package/dist/src/server/routes-workspace-memory-dreams.d.ts +2 -0
  95. package/dist/src/server/routes-workspace-memory-dreams.js +105 -0
  96. package/dist/src/server/routes-workspace-memory.d.ts +2 -0
  97. package/dist/src/server/routes-workspace-memory.js +215 -0
  98. package/dist/src/server/routes-workspaces.js +9 -9
  99. package/dist/src/server/routes.js +10 -0
  100. package/dist/src/server/runtime-database.d.ts +1 -0
  101. package/dist/src/server/runtime-database.js +27 -2
  102. package/dist/src/server/runtime-restart-policy.d.ts +3 -1
  103. package/dist/src/server/runtime-restart-policy.js +2 -1
  104. package/dist/src/server/runtime-store-contract.d.ts +37 -0
  105. package/dist/src/server/runtime-store-dream.d.ts +23 -0
  106. package/dist/src/server/runtime-store-dream.js +16 -0
  107. package/dist/src/server/runtime-store-helpers.d.ts +20 -0
  108. package/dist/src/server/runtime-store-helpers.js +81 -7
  109. package/dist/src/server/runtime-store-memory.d.ts +33 -0
  110. package/dist/src/server/runtime-store-memory.js +37 -0
  111. package/dist/src/server/runtime-store-remote.d.ts +5 -0
  112. package/dist/src/server/runtime-store-remote.js +45 -0
  113. package/dist/src/server/runtime-store-workflows.js +2 -0
  114. package/dist/src/server/runtime-store.js +14 -3
  115. package/dist/src/server/session-capture-claude.d.ts +1 -1
  116. package/dist/src/server/session-capture-claude.js +7 -4
  117. package/dist/src/server/session-capture-codex.js +4 -5
  118. package/dist/src/server/session-capture-gemini.js +4 -5
  119. package/dist/src/server/session-capture-opencode.d.ts +4 -4
  120. package/dist/src/server/session-capture-opencode.js +20 -12
  121. package/dist/src/server/session-capture-qwen.d.ts +5 -0
  122. package/dist/src/server/session-capture-qwen.js +104 -0
  123. package/dist/src/server/session-capture.d.ts +17 -0
  124. package/dist/src/server/session-capture.js +16 -0
  125. package/dist/src/server/sqlite-schema-v23.d.ts +2 -0
  126. package/dist/src/server/sqlite-schema-v23.js +43 -0
  127. package/dist/src/server/sqlite-schema-v24.d.ts +2 -0
  128. package/dist/src/server/sqlite-schema-v24.js +34 -0
  129. package/dist/src/server/sqlite-schema-v25.d.ts +2 -0
  130. package/dist/src/server/sqlite-schema-v25.js +127 -0
  131. package/dist/src/server/sqlite-schema-v26.d.ts +2 -0
  132. package/dist/src/server/sqlite-schema-v26.js +56 -0
  133. package/dist/src/server/sqlite-schema-v27.d.ts +6 -0
  134. package/dist/src/server/sqlite-schema-v27.js +92 -0
  135. package/dist/src/server/sqlite-schema-v28.d.ts +2 -0
  136. package/dist/src/server/sqlite-schema-v28.js +19 -0
  137. package/dist/src/server/sqlite-schema-v29.d.ts +2 -0
  138. package/dist/src/server/sqlite-schema-v29.js +27 -0
  139. package/dist/src/server/sqlite-schema-v30.d.ts +2 -0
  140. package/dist/src/server/sqlite-schema-v30.js +27 -0
  141. package/dist/src/server/sqlite-schema-v31.d.ts +2 -0
  142. package/dist/src/server/sqlite-schema-v31.js +30 -0
  143. package/dist/src/server/sqlite-schema.d.ts +1 -1
  144. package/dist/src/server/sqlite-schema.js +49 -1
  145. package/dist/src/server/startup-command-parser.js +5 -1
  146. package/dist/src/server/tasks-file-watcher.d.ts +2 -0
  147. package/dist/src/server/tasks-file-watcher.js +15 -6
  148. package/dist/src/server/tasks-file.js +30 -5
  149. package/dist/src/server/tasks-websocket-server.js +4 -0
  150. package/dist/src/server/team-authz.d.ts +1 -1
  151. package/dist/src/server/team-authz.js +13 -1
  152. package/dist/src/server/team-list-enrichment.js +3 -1
  153. package/dist/src/server/team-memory-digest.d.ts +52 -0
  154. package/dist/src/server/team-memory-digest.js +200 -0
  155. package/dist/src/server/team-memory-dream-applier.d.ts +5 -0
  156. package/dist/src/server/team-memory-dream-applier.js +234 -0
  157. package/dist/src/server/team-memory-dream-http-serializers.d.ts +13 -0
  158. package/dist/src/server/team-memory-dream-http-serializers.js +12 -0
  159. package/dist/src/server/team-memory-dream-ops.d.ts +40 -0
  160. package/dist/src/server/team-memory-dream-ops.js +153 -0
  161. package/dist/src/server/team-memory-dream-reverter.d.ts +22 -0
  162. package/dist/src/server/team-memory-dream-reverter.js +221 -0
  163. package/dist/src/server/team-memory-dream-run-store.d.ts +23 -0
  164. package/dist/src/server/team-memory-dream-run-store.js +211 -0
  165. package/dist/src/server/team-memory-dream-runner.d.ts +37 -0
  166. package/dist/src/server/team-memory-dream-runner.js +178 -0
  167. package/dist/src/server/team-memory-dream-scheduler.d.ts +32 -0
  168. package/dist/src/server/team-memory-dream-scheduler.js +115 -0
  169. package/dist/src/server/team-memory-dream-store.d.ts +19 -0
  170. package/dist/src/server/team-memory-dream-store.js +16 -0
  171. package/dist/src/server/team-memory-dream-types.d.ts +104 -0
  172. package/dist/src/server/team-memory-dream-types.js +23 -0
  173. package/dist/src/server/team-memory-export.d.ts +22 -0
  174. package/dist/src/server/team-memory-export.js +220 -0
  175. package/dist/src/server/team-memory-feature.d.ts +12 -0
  176. package/dist/src/server/team-memory-feature.js +12 -0
  177. package/dist/src/server/team-memory-http-serializers.d.ts +102 -0
  178. package/dist/src/server/team-memory-http-serializers.js +46 -0
  179. package/dist/src/server/team-memory-injection.d.ts +31 -0
  180. package/dist/src/server/team-memory-injection.js +49 -0
  181. package/dist/src/server/team-memory-store.d.ts +116 -0
  182. package/dist/src/server/team-memory-store.js +513 -0
  183. package/dist/src/server/team-operations.d.ts +5 -1
  184. package/dist/src/server/team-operations.js +46 -16
  185. package/dist/src/server/team-recall-store.d.ts +38 -0
  186. package/dist/src/server/team-recall-store.js +205 -0
  187. package/dist/src/server/terminal-input-profile.d.ts +1 -1
  188. package/dist/src/server/terminal-input-profile.js +18 -0
  189. package/dist/src/server/terminal-ws-server.js +6 -0
  190. package/dist/src/server/ui-auth-helpers.d.ts +1 -1
  191. package/dist/src/server/ui-auth-helpers.js +7 -1
  192. package/dist/src/server/ui-auth.d.ts +3 -0
  193. package/dist/src/server/ui-auth.js +21 -1
  194. package/dist/src/server/workflow-cli-policy.d.ts +2 -3
  195. package/dist/src/server/workflow-cli-policy.js +3 -3
  196. package/dist/src/server/workflow-runner.d.ts +1 -0
  197. package/dist/src/server/workflow-runner.js +9 -4
  198. package/dist/src/server/workspace-path-validation.js +6 -2
  199. package/dist/src/server/workspace-store.d.ts +1 -1
  200. package/dist/src/server/workspace-store.js +35 -9
  201. package/dist/src/shared/fs-browse.d.ts +1 -0
  202. package/dist/src/shared/fs-browse.js +1 -0
  203. package/dist/src/shared/path-input.d.ts +12 -0
  204. package/dist/src/shared/path-input.js +22 -0
  205. package/dist/src/shared/remote-bridge-routing.d.ts +19 -0
  206. package/dist/src/shared/remote-bridge-routing.js +141 -0
  207. package/dist/src/shared/remote-crypto.d.ts +138 -0
  208. package/dist/src/shared/remote-crypto.js +427 -0
  209. package/dist/src/shared/remote-pairing-code.d.ts +7 -0
  210. package/dist/src/shared/remote-pairing-code.js +47 -0
  211. package/dist/src/shared/remote-protocol.d.ts +160 -0
  212. package/dist/src/shared/remote-protocol.js +526 -0
  213. package/dist/src/shared/team-memory.d.ts +11 -0
  214. package/dist/src/shared/team-memory.js +10 -0
  215. package/dist/src/shared/team-recall.d.ts +1 -0
  216. package/dist/src/shared/team-recall.js +1 -0
  217. package/dist/src/shared/types.d.ts +4 -5
  218. package/package.json +12 -5
  219. package/scripts/postinstall-native-artifacts.mjs +113 -0
  220. package/web/dist/assets/AddWorkerDialog-CbV75qUX.js +2 -0
  221. package/web/dist/assets/AddWorkspaceFlow-CwV-7wPx.js +1 -0
  222. package/web/dist/assets/FirstRunWizard-a6PWIK3x.js +1 -0
  223. package/web/dist/assets/MarketplaceDrawer-Dd8WIA8T.js +67 -0
  224. package/web/dist/assets/TaskGraphDrawer-Bk5WFIk_.js +1 -0
  225. package/web/dist/assets/{WhatsNewDialog-CHkZeINH.js → WhatsNewDialog-C2VZaip0.js} +1 -1
  226. package/web/dist/assets/WorkerModal-DucW-9YT.js +1 -0
  227. package/web/dist/assets/WorkflowsDrawer-Bjf4olbR.js +1 -0
  228. package/web/dist/assets/WorkspaceMemoryDrawer-DglCy_5f.js +1 -0
  229. package/web/dist/assets/WorkspaceTaskDrawer-BIWwISvA.js +1 -0
  230. package/web/dist/assets/index-BAiLYajK.css +1 -0
  231. package/web/dist/assets/index-BV2k9Dts.js +73 -0
  232. package/web/dist/assets/search-Bk2HQvO7.js +1 -0
  233. package/web/dist/assets/square-terminal-D93m9hfY.js +1 -0
  234. package/web/dist/cli-icons/agy.png +0 -0
  235. package/web/dist/cli-icons/cursor.ico +0 -0
  236. package/web/dist/cli-icons/grok.ico +0 -0
  237. package/web/dist/cli-icons/qwen.png +0 -0
  238. package/web/dist/index.html +8 -3
  239. package/web/dist/sw.js +1 -1
  240. package/scripts/fix-runtime-artifacts.mjs +0 -33
  241. package/web/dist/assets/AddWorkerDialog-BRUxpa3f.js +0 -2
  242. package/web/dist/assets/AddWorkspaceDialog-D56x5JCb.js +0 -1
  243. package/web/dist/assets/FirstRunWizard-BFVaMIsE.js +0 -1
  244. package/web/dist/assets/MarketplaceDrawer-DeEZ35dN.js +0 -76
  245. package/web/dist/assets/WorkerModal-BBCuMLIa.js +0 -1
  246. package/web/dist/assets/WorkspaceTaskDrawer-CpZHAcj1.js +0 -1
  247. package/web/dist/assets/WorkspaceTerminalPanels-7If2mDyp.js +0 -1
  248. package/web/dist/assets/WorkspaceTerminalPanels-DDGTF8rc.css +0 -1
  249. package/web/dist/assets/index-5zh61jMg.css +0 -1
  250. package/web/dist/assets/index-CxNL0O-C.js +0 -73
  251. package/web/dist/assets/path-join-7MR1s7b1.js +0 -1
@@ -1,13 +1,18 @@
1
1
  #!/usr/bin/env node
2
+ import { type RemoteTunnel, type RemoteTunnelDeps } from '../server/remote-tunnel.js';
2
3
  import { type RuntimeStore } from '../server/runtime-store.js';
3
4
  import { type VersionService } from '../server/version-service.js';
4
5
  interface RunHiveCommandResult {
5
6
  port: number;
6
7
  close: () => Promise<void>;
7
8
  store: RuntimeStore;
9
+ /** The remote-access tunnel. Gated by remote_enabled (default OFF); off => no outbound socket. */
10
+ tunnel: RemoteTunnel;
8
11
  }
9
12
  type RunHiveCommandOptions = {
10
13
  versionService?: VersionService;
14
+ /** Seam: override the tunnel factory in tests. Defaults to the real createRemoteTunnel. */
15
+ createRemoteTunnel?: (deps: RemoteTunnelDeps) => RemoteTunnel;
11
16
  };
12
17
  /**
13
18
  * Signals that should drive a graceful shutdown. The interesting ones:
@@ -68,5 +73,6 @@ export declare const resolveDataDir: (platform?: NodeJS.Platform, env?: NodeJS.P
68
73
  * Exported for unit testing.
69
74
  */
70
75
  export declare const formatPortInUseMessage: (port: number, platform?: NodeJS.Platform) => string;
76
+ export declare const formatPortAccessDeniedMessage: (port: number, platform?: NodeJS.Platform) => string;
71
77
  export declare const runHiveCommand: (argv: string[], options?: RunHiveCommandOptions) => Promise<RunHiveCommandResult>;
72
78
  export type { RunHiveCommandResult };
@@ -8,8 +8,11 @@ import { createAgentManager } from '../server/agent-manager.js';
8
8
  import { createApp } from '../server/app.js';
9
9
  import { readPackageVersion } from '../server/package-version.js';
10
10
  import { sameFilesystemPath } from '../server/path-canonicalization.js';
11
+ import { createRemoteConfigSource } from '../server/remote-config-keys.js';
12
+ import { createRemoteTunnel, } from '../server/remote-tunnel.js';
11
13
  import { createRuntimeStore } from '../server/runtime-store.js';
12
14
  import { createVersionService } from '../server/version-service.js';
15
+ import { runHiveRemoteCommand } from './hive-remote.js';
13
16
  import { runHiveUpdateCommand } from './hive-update.js';
14
17
  /**
15
18
  * Signals that should drive a graceful shutdown. The interesting ones:
@@ -45,6 +48,7 @@ export const HIVE_USAGE = [
45
48
  '',
46
49
  'Commands:',
47
50
  ' update Upgrade Hive in place via `npm install -g`.',
51
+ ' remote Manage remote access (login / status / logout / devices / revoke).',
48
52
  ].join('\n');
49
53
  export const handleHiveInfoCommand = (argv) => {
50
54
  if (argv.includes('--help') || argv.includes('-h')) {
@@ -159,10 +163,31 @@ export const formatPortInUseMessage = (port, platform = process.platform) => {
159
163
  ` hive --port ${port + 1}`,
160
164
  ].join('\n');
161
165
  };
166
+ export const formatPortAccessDeniedMessage = (port, platform = process.platform) => {
167
+ if (platform !== 'win32') {
168
+ return `Hive could not start on port ${port}: permission denied.`;
169
+ }
170
+ return [
171
+ `Hive could not start on port ${port}: Windows denied access to that port.`,
172
+ '',
173
+ 'This can happen when Hyper-V, Docker Desktop, WSL2, or Windows itself reserves a TCP port range.',
174
+ '',
175
+ 'Check reserved ranges:',
176
+ ' netsh int ipv4 show excludedportrange protocol=tcp',
177
+ '',
178
+ 'Options:',
179
+ ' - Start Hive on a high unreserved port:',
180
+ ' hive --port 49152',
181
+ ' - Or choose another port outside the listed excluded ranges.',
182
+ ].join('\n');
183
+ };
162
184
  const formatListenError = (error, requestedPort) => {
163
185
  if (isListenError(error) && error.code === 'EADDRINUSE') {
164
186
  return new Error(formatPortInUseMessage(error.port ?? requestedPort));
165
187
  }
188
+ if (isListenError(error) && error.code === 'EACCES') {
189
+ return new Error(formatPortAccessDeniedMessage(error.port ?? requestedPort));
190
+ }
166
191
  return error;
167
192
  };
168
193
  export const runHiveCommand = async (argv, options = {}) => {
@@ -193,6 +218,32 @@ export const runHiveCommand = async (argv, options = {}) => {
193
218
  if (!address || typeof address === 'string') {
194
219
  throw new Error('Server did not bind to an inet port');
195
220
  }
221
+ // Remote tunnel — the outbound WebSocket to the gateway. GATED by app_state[remote_enabled]
222
+ // (default OFF). When off, refresh() settles 'disabled' synchronously: no socket is opened, no
223
+ // timer is armed, no listener is added, and the per-boot secret accept path stays inert (a request
224
+ // with no secret header hits the unchanged cookie path). This is invariant 4 — off == zero
225
+ // behavior change. Loopback requests authenticate via the per-boot internal secret (invariant 2),
226
+ // so the bridge never juggles browser cookies.
227
+ const tunnelFactory = options.createRemoteTunnel ?? createRemoteTunnel;
228
+ const tunnel = tunnelFactory({
229
+ loopbackPort: address.port,
230
+ config: createRemoteConfigSource({
231
+ get: (key) => app.store.settings.getAppState(key),
232
+ }),
233
+ deviceSessions: app.store.getRemoteDeviceSessions(),
234
+ loopbackSecret: app.store.getRemoteTunnelSecret(),
235
+ audit: app.store.getRemoteAuditStore(),
236
+ // The pairing engine — the tunnel carries pairing TEXT frames alongside the binary data plane and
237
+ // drives the daemon handshake half + the desktop-confirm sequence (gateway register + confirmed).
238
+ pairing: app.store.getRemotePairing(),
239
+ // Capture status so GET /api/remote/status.connected reflects the live tunnel (M4).
240
+ onStatus: (e) => app.store.setRemoteTunnelStatus(e.status),
241
+ });
242
+ // Bind the tunnel onto the store BEFORE refresh() so a revoke route fired during boot can close a
243
+ // device's live streams (the §6 closed loop). The provider-drop half is independent of binding.
244
+ app.store.bindRemoteTunnel(tunnel);
245
+ // refresh() reconciles desired (config) vs actual (socket). Disabled => settles immediately.
246
+ tunnel.refresh();
196
247
  let closePromise = null;
197
248
  const close = async () => {
198
249
  if (closePromise) {
@@ -202,6 +253,10 @@ export const runHiveCommand = async (argv, options = {}) => {
202
253
  for (const signal of SHUTDOWN_SIGNALS) {
203
254
  process.off(signal, gracefulShutdown);
204
255
  }
256
+ // Close the outbound tunnel FIRST so it stops reconnecting and tears down its in-flight
257
+ // loopback streams before we rip the inbound WS layer out from under them. Graceful: no status
258
+ // churn, hard-terminate after a short grace.
259
+ await tunnel.close();
205
260
  // Tear down the WebSocket layer FIRST. `app.server.close()` waits
206
261
  // on every existing socket, including upgraded WebSocket clients
207
262
  // that never go idle on their own; `server.closeAllConnections()`
@@ -245,6 +300,7 @@ export const runHiveCommand = async (argv, options = {}) => {
245
300
  port: address.port,
246
301
  close,
247
302
  store: app.store,
303
+ tunnel,
248
304
  };
249
305
  };
250
306
  const isMainModule = process.argv[1]
@@ -260,6 +316,14 @@ if (isMainModule) {
260
316
  process.exit(1);
261
317
  });
262
318
  }
319
+ else if (argv[0] === 'remote') {
320
+ runHiveRemoteCommand(argv.slice(1))
321
+ .then((code) => process.exit(code))
322
+ .catch((error) => {
323
+ console.error(error instanceof Error ? error.message : error);
324
+ process.exit(1);
325
+ });
326
+ }
263
327
  else if (handleHiveInfoCommand(argv)) {
264
328
  process.exit(0);
265
329
  }
@@ -1,3 +1,4 @@
1
+ import { type MemoryKind } from '../shared/team-memory.js';
1
2
  interface ParsedCancelArgs {
2
3
  dispatchId: string;
3
4
  reason: string;
@@ -10,6 +11,27 @@ export interface ParsedReportArgs {
10
11
  }
11
12
  export declare const parseReportArgs: (args: string[], command?: string) => ParsedReportArgs;
12
13
  export declare const parseCancelArgs: (args: string[]) => ParsedCancelArgs;
14
+ export declare const parseRecallArgs: (args: string[]) => {
15
+ window?: number;
16
+ limit?: number;
17
+ query: string;
18
+ };
19
+ export interface ParsedMemoryAddArgs {
20
+ body: string;
21
+ kind: MemoryKind;
22
+ tags: string[];
23
+ }
24
+ export declare const parseMemoryAddArgs: (args: string[]) => ParsedMemoryAddArgs;
25
+ export declare const parseMemoryShowArgs: (args: string[]) => {
26
+ memoryId: string;
27
+ };
28
+ export declare const parseMemorySearchArgs: (args: string[]) => {
29
+ limit?: number;
30
+ query: string;
31
+ };
32
+ export declare const parseMemoryForgetArgs: (args: string[]) => {
33
+ memoryId: string;
34
+ };
13
35
  export declare const decodeStdinBuffer: (buffer: Buffer) => string;
14
36
  export declare const readStdinToString: (command?: string) => Promise<string>;
15
37
  export declare const runTeamCommand: (argv: string[]) => Promise<void>;
@@ -1,5 +1,8 @@
1
1
  import { fileURLToPath } from 'node:url';
2
+ import { BUILTIN_COMMAND_PRESET_CLI_LIST } from '../server/command-preset-defaults.js';
2
3
  import { sameFilesystemPath } from '../server/path-canonicalization.js';
4
+ import { isMemoryKind, MEMORY_BODY_MAX_CHARS, MEMORY_KINDS, MEMORY_QUERY_MAX_CHARS, MEMORY_SEARCH_MAX_LIMIT, MEMORY_TAG_MAX_CHARS, MEMORY_TAG_MAX_COUNT, } from '../shared/team-memory.js';
5
+ import { RECALL_QUERY_MAX_CHARS } from '../shared/team-recall.js';
3
6
  const REQUIRED_ENV_KEYS = [
4
7
  'HIVE_PORT',
5
8
  'HIVE_PROJECT_ID',
@@ -10,8 +13,13 @@ const TEAM_USAGE = [
10
13
  'Usage:',
11
14
  ' team list',
12
15
  ' team next (tasks in .hive/tasks.md that are unblocked now — those whose [needs: #n] deps are all done)',
16
+ ' team recall "<query>" [--limit <n>] [--window <n>]',
17
+ ' team memory add "<body>" [--kind fact|preference|decision|pitfall|procedure_ref] [--tag <tag>]',
18
+ ' team memory show <memory-id>',
19
+ ' team memory search "<query>" [--limit <n>]',
20
+ ' team memory forget <memory-id>',
13
21
  ' team send <worker-name> "<task>"',
14
- ' team spawn <role> [--name <name>] [--cli <claude|codex|opencode|gemini|hermes>] [--ephemeral]',
22
+ ` team spawn <role> [--name <name>] [--cli <${BUILTIN_COMMAND_PRESET_CLI_LIST}>] [--ephemeral]`,
15
23
  ' team dismiss <worker-name>',
16
24
  " team workflow run --stdin [--args '<JSON>'] (script from stdin — for multi-line scripts)",
17
25
  ' team workflow run --inline "<source>" [--args \'<JSON>\']',
@@ -30,7 +38,7 @@ const TEAM_USAGE = [
30
38
  ' ... long report ...',
31
39
  ' EOF',
32
40
  ' Windows cmd: type body.txt | team report --stdin --dispatch <id>',
33
- ' PowerShell: Get-Content body.txt | team report --stdin --dispatch <id>',
41
+ ' PowerShell: Get-Content -Raw -Encoding utf8 body.txt | team report --stdin --dispatch <id>',
34
42
  ' Portable: team report --stdin --dispatch <id> < body.txt',
35
43
  '',
36
44
  'For role rules, workflow, and recovery instructions, see .hive/PROTOCOL.md',
@@ -52,7 +60,6 @@ const readFlag = (args, flag) => {
52
60
  const value = args[index + 1];
53
61
  return value && !value.startsWith('--') ? value : undefined;
54
62
  };
55
- const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
56
63
  const describeFetchError = (baseUrl, error) => {
57
64
  const cause = error instanceof Error && error.cause instanceof Error ? ` (${error.cause.message})` : '';
58
65
  const message = error instanceof Error ? error.message : String(error);
@@ -102,6 +109,11 @@ const postJson = async (baseUrl, path, body) => {
102
109
  const REPORT_USAGE = 'Usage: team report (<result> | --stdin) [--dispatch <dispatch-id>] [--artifact <path>]';
103
110
  const STATUS_USAGE = 'Usage: team status (<current status> | --stdin) [--artifact <path>]';
104
111
  const CANCEL_USAGE = 'Usage: team cancel --dispatch <dispatch-id> <reason>';
112
+ const RECALL_USAGE = 'Usage: team recall "<query>" [--limit <n>] [--window <n>]';
113
+ const MEMORY_ADD_USAGE = 'Usage: team memory add "<body>" [--kind fact|preference|decision|pitfall|procedure_ref] [--tag <tag>]';
114
+ const MEMORY_SHOW_USAGE = 'Usage: team memory show <memory-id>';
115
+ const MEMORY_SEARCH_USAGE = 'Usage: team memory search "<query>" [--limit <n>]';
116
+ const MEMORY_FORGET_USAGE = 'Usage: team memory forget <memory-id>';
105
117
  const usageFor = (command) => (command === 'status' ? STATUS_USAGE : REPORT_USAGE);
106
118
  const withUsage = (message, command) => `${message}\n\n${usageFor(command)}`;
107
119
  export const parseReportArgs = (args, command = 'report') => {
@@ -194,6 +206,165 @@ export const parseCancelArgs = (args) => {
194
206
  }
195
207
  return { dispatchId, reason };
196
208
  };
209
+ const parseNonNegativeIntFlag = (value, flag) => {
210
+ if (value === undefined)
211
+ return undefined;
212
+ const parsed = Number(value);
213
+ if (!Number.isInteger(parsed) || parsed < 0) {
214
+ throw new Error(`${flag} must be a non-negative integer\n\n${RECALL_USAGE}`);
215
+ }
216
+ return parsed;
217
+ };
218
+ export const parseRecallArgs = (args) => {
219
+ const positionals = [];
220
+ let limit;
221
+ let window;
222
+ for (let index = 0; index < args.length; index += 1) {
223
+ const arg = args[index];
224
+ if (arg === undefined)
225
+ continue;
226
+ if (arg === '--limit' || arg === '--window') {
227
+ const next = args[index + 1];
228
+ if (next === undefined || next.startsWith('--')) {
229
+ throw new Error(`${arg} requires a value\n\n${RECALL_USAGE}`);
230
+ }
231
+ if (arg === '--limit')
232
+ limit = parseNonNegativeIntFlag(next, '--limit');
233
+ else
234
+ window = parseNonNegativeIntFlag(next, '--window');
235
+ index += 1;
236
+ continue;
237
+ }
238
+ if (arg.startsWith('--')) {
239
+ throw new Error(`Unknown argument: ${arg}\n\n${RECALL_USAGE}`);
240
+ }
241
+ positionals.push(arg);
242
+ }
243
+ if (positionals.length === 0) {
244
+ throw new Error(`Missing <query>\n\n${RECALL_USAGE}`);
245
+ }
246
+ const query = positionals.join(' ').trim();
247
+ if ([...query].length > RECALL_QUERY_MAX_CHARS) {
248
+ throw new Error(`query must be ${RECALL_QUERY_MAX_CHARS} characters or fewer\n\n${RECALL_USAGE}`);
249
+ }
250
+ return {
251
+ query,
252
+ ...(limit !== undefined ? { limit } : {}),
253
+ ...(window !== undefined ? { window } : {}),
254
+ };
255
+ };
256
+ export const parseMemoryAddArgs = (args) => {
257
+ const positionals = [];
258
+ const tags = [];
259
+ let kind = 'fact';
260
+ for (let index = 0; index < args.length; index += 1) {
261
+ const arg = args[index];
262
+ if (arg === undefined)
263
+ continue;
264
+ if (arg === '--kind') {
265
+ const next = args[index + 1];
266
+ if (next === undefined || next.startsWith('--')) {
267
+ throw new Error(`--kind requires a value\n\n${MEMORY_ADD_USAGE}`);
268
+ }
269
+ if (!isMemoryKind(next)) {
270
+ throw new Error(`--kind must be one of: ${MEMORY_KINDS.join(', ')}\n\n${MEMORY_ADD_USAGE}`);
271
+ }
272
+ kind = next;
273
+ index += 1;
274
+ continue;
275
+ }
276
+ if (arg === '--tag') {
277
+ const next = args[index + 1];
278
+ if (next === undefined || next.startsWith('--')) {
279
+ throw new Error(`--tag requires a value\n\n${MEMORY_ADD_USAGE}`);
280
+ }
281
+ const tag = next.trim();
282
+ if (!tag) {
283
+ throw new Error(`--tag requires a non-empty value\n\n${MEMORY_ADD_USAGE}`);
284
+ }
285
+ if ([...tag].length > MEMORY_TAG_MAX_CHARS) {
286
+ throw new Error(`--tag must be ${MEMORY_TAG_MAX_CHARS} characters or fewer\n\n${MEMORY_ADD_USAGE}`);
287
+ }
288
+ if (!tags.includes(tag))
289
+ tags.push(tag);
290
+ index += 1;
291
+ continue;
292
+ }
293
+ if (arg.startsWith('--')) {
294
+ throw new Error(`Unknown argument: ${arg}\n\n${MEMORY_ADD_USAGE}`);
295
+ }
296
+ positionals.push(arg);
297
+ }
298
+ if (tags.length > MEMORY_TAG_MAX_COUNT) {
299
+ throw new Error(`--tag may be repeated ${MEMORY_TAG_MAX_COUNT} times or fewer\n\n${MEMORY_ADD_USAGE}`);
300
+ }
301
+ if (positionals.length === 0) {
302
+ throw new Error(`Missing <body>\n\n${MEMORY_ADD_USAGE}`);
303
+ }
304
+ const body = positionals.join(' ').trim();
305
+ if (!body) {
306
+ throw new Error(`Missing <body>\n\n${MEMORY_ADD_USAGE}`);
307
+ }
308
+ if ([...body].length > MEMORY_BODY_MAX_CHARS) {
309
+ throw new Error(`body must be ${MEMORY_BODY_MAX_CHARS} characters or fewer\n\n${MEMORY_ADD_USAGE}`);
310
+ }
311
+ return { body, kind, tags };
312
+ };
313
+ export const parseMemoryShowArgs = (args) => {
314
+ if (args.length !== 1 || !args[0] || args[0].startsWith('--')) {
315
+ throw new Error(`Missing <memory-id>\n\n${MEMORY_SHOW_USAGE}`);
316
+ }
317
+ return { memoryId: args[0] };
318
+ };
319
+ export const parseMemorySearchArgs = (args) => {
320
+ const positionals = [];
321
+ let limit;
322
+ for (let index = 0; index < args.length; index += 1) {
323
+ const arg = args[index];
324
+ if (arg === undefined)
325
+ continue;
326
+ if (arg === '--limit') {
327
+ const next = args[index + 1];
328
+ if (next === undefined || next.startsWith('--')) {
329
+ throw new Error(`--limit requires a value\n\n${MEMORY_SEARCH_USAGE}`);
330
+ }
331
+ const parsed = Number(next);
332
+ if (!Number.isInteger(parsed) || parsed < 0) {
333
+ throw new Error(`--limit must be a non-negative integer\n\n${MEMORY_SEARCH_USAGE}`);
334
+ }
335
+ limit = Math.min(parsed, MEMORY_SEARCH_MAX_LIMIT);
336
+ index += 1;
337
+ continue;
338
+ }
339
+ if (arg.startsWith('--')) {
340
+ throw new Error(`Unknown argument: ${arg}\n\n${MEMORY_SEARCH_USAGE}`);
341
+ }
342
+ positionals.push(arg);
343
+ }
344
+ if (positionals.length === 0) {
345
+ throw new Error(`Missing <query>\n\n${MEMORY_SEARCH_USAGE}`);
346
+ }
347
+ const query = positionals.join(' ').trim();
348
+ if (!query) {
349
+ throw new Error(`Missing <query>\n\n${MEMORY_SEARCH_USAGE}`);
350
+ }
351
+ if ([...query].length > MEMORY_QUERY_MAX_CHARS) {
352
+ throw new Error(`query must be ${MEMORY_QUERY_MAX_CHARS} characters or fewer\n\n${MEMORY_SEARCH_USAGE}`);
353
+ }
354
+ return {
355
+ query,
356
+ ...(limit !== undefined ? { limit } : {}),
357
+ };
358
+ };
359
+ export const parseMemoryForgetArgs = (args) => {
360
+ if (args.length === 0 || !args[0] || args[0].startsWith('--')) {
361
+ throw new Error(`Missing <memory-id>\n\n${MEMORY_FORGET_USAGE}`);
362
+ }
363
+ if (args.length !== 1) {
364
+ throw new Error(`Expected exactly one <memory-id>\n\n${MEMORY_FORGET_USAGE}`);
365
+ }
366
+ return { memoryId: args[0] };
367
+ };
197
368
  export const decodeStdinBuffer = (buffer) => {
198
369
  if (buffer.length >= 3 && buffer[0] === 0xef && buffer[1] === 0xbb && buffer[2] === 0xbf) {
199
370
  return buffer.subarray(3).toString('utf8');
@@ -260,10 +431,85 @@ export const runTeamCommand = async (argv) => {
260
431
  console.log(JSON.stringify(await response.json()));
261
432
  return;
262
433
  }
434
+ if (command === 'recall') {
435
+ const recall = parseRecallArgs(args);
436
+ const env = getHiveEnv();
437
+ const response = await postJson(getBaseUrl(env), '/api/team/recall', {
438
+ project_id: env.HIVE_PROJECT_ID,
439
+ from_agent_id: env.HIVE_AGENT_ID,
440
+ token: env.HIVE_AGENT_TOKEN,
441
+ query: recall.query,
442
+ ...(recall.limit !== undefined ? { limit: recall.limit } : {}),
443
+ ...(recall.window !== undefined ? { window: recall.window } : {}),
444
+ });
445
+ console.log(JSON.stringify(await response.json()));
446
+ return;
447
+ }
448
+ if (command === 'memory') {
449
+ const [subcommand, ...memoryArgs] = args;
450
+ if (subcommand === 'add') {
451
+ const memory = parseMemoryAddArgs(memoryArgs);
452
+ const env = getHiveEnv();
453
+ const response = await postJson(getBaseUrl(env), '/api/team/memory/add', {
454
+ project_id: env.HIVE_PROJECT_ID,
455
+ from_agent_id: env.HIVE_AGENT_ID,
456
+ token: env.HIVE_AGENT_TOKEN,
457
+ body: memory.body,
458
+ kind: memory.kind,
459
+ tags: memory.tags,
460
+ });
461
+ console.log(JSON.stringify(await response.json()));
462
+ return;
463
+ }
464
+ if (subcommand === 'show') {
465
+ const memory = parseMemoryShowArgs(memoryArgs);
466
+ const env = getHiveEnv();
467
+ const response = await postJson(getBaseUrl(env), '/api/team/memory/show', {
468
+ project_id: env.HIVE_PROJECT_ID,
469
+ from_agent_id: env.HIVE_AGENT_ID,
470
+ token: env.HIVE_AGENT_TOKEN,
471
+ memory_id: memory.memoryId,
472
+ });
473
+ console.log(JSON.stringify(await response.json()));
474
+ return;
475
+ }
476
+ if (subcommand === 'search') {
477
+ const memory = parseMemorySearchArgs(memoryArgs);
478
+ const env = getHiveEnv();
479
+ const response = await postJson(getBaseUrl(env), '/api/team/memory/search', {
480
+ project_id: env.HIVE_PROJECT_ID,
481
+ from_agent_id: env.HIVE_AGENT_ID,
482
+ token: env.HIVE_AGENT_TOKEN,
483
+ query: memory.query,
484
+ ...(memory.limit !== undefined ? { limit: memory.limit } : {}),
485
+ });
486
+ console.log(JSON.stringify(await response.json()));
487
+ return;
488
+ }
489
+ if (subcommand === 'forget') {
490
+ const memory = parseMemoryForgetArgs(memoryArgs);
491
+ const env = getHiveEnv();
492
+ const response = await postJson(getBaseUrl(env), '/api/team/memory/forget', {
493
+ project_id: env.HIVE_PROJECT_ID,
494
+ from_agent_id: env.HIVE_AGENT_ID,
495
+ token: env.HIVE_AGENT_TOKEN,
496
+ memory_id: memory.memoryId,
497
+ });
498
+ console.log(JSON.stringify(await response.json()));
499
+ return;
500
+ }
501
+ throw new Error([
502
+ 'Usage:',
503
+ ` ${MEMORY_ADD_USAGE}`,
504
+ ` ${MEMORY_SHOW_USAGE}`,
505
+ ` ${MEMORY_SEARCH_USAGE}`,
506
+ ` ${MEMORY_FORGET_USAGE}`,
507
+ ].join('\n'));
508
+ }
263
509
  if (command === 'send') {
264
510
  const [workerName, ...taskParts] = args;
265
511
  const task = taskParts.join(' ').trim();
266
- if (!workerName || !task || uuidPattern.test(workerName)) {
512
+ if (!workerName || !task) {
267
513
  throw new Error('Usage: team send <worker-name> <task>');
268
514
  }
269
515
  const env = getHiveEnv();
@@ -291,7 +537,7 @@ export const runTeamCommand = async (argv) => {
291
537
  if (command === 'spawn') {
292
538
  const role = args[0];
293
539
  if (!role || role.startsWith('--')) {
294
- throw new Error('Usage: team spawn <role> [--name <name>] [--cli <claude|codex|opencode|gemini|hermes>] [--ephemeral]\n' +
540
+ throw new Error(`Usage: team spawn <role> [--name <name>] [--cli <${BUILTIN_COMMAND_PRESET_CLI_LIST}>] [--ephemeral]\n` +
295
541
  ' Default: persistent member (lives until you `team dismiss` it).\n' +
296
542
  ' --ephemeral: auto-dismiss after the next dispatch report (one-shot worker).');
297
543
  }
@@ -483,6 +729,8 @@ export const runTeamCommand = async (argv) => {
483
729
  if (payload.forwarded === false && payload.forward_error) {
484
730
  console.error(`Hive recorded the status update, but could not deliver it to Orchestrator in real time: ${payload.forward_error}`);
485
731
  }
732
+ if (payload.pending_warning)
733
+ console.error(payload.pending_warning);
486
734
  return;
487
735
  }
488
736
  if (command === 'report') {
@@ -502,6 +750,8 @@ export const runTeamCommand = async (argv) => {
502
750
  if (payload.forwarded === false && payload.forward_error) {
503
751
  console.error(`Hive recorded the report, but could not deliver it to Orchestrator in real time: ${payload.forward_error}`);
504
752
  }
753
+ if (payload.pending_warning)
754
+ console.error(payload.pending_warning);
505
755
  return;
506
756
  }
507
757
  throw new Error('Unsupported team command');
@@ -18,7 +18,11 @@ const createCommandNotFoundError = (command) => Object.assign(new Error(`${comma
18
18
  const getEnvValue = (env, key, platform = process.platform) => {
19
19
  if (platform !== 'win32')
20
20
  return env[key];
21
- const matchedKey = Object.keys(env).find((item) => item.toLowerCase() === key.toLowerCase());
21
+ if (Object.hasOwn(env, key))
22
+ return env[key];
23
+ const matchedKey = Object.keys(env)
24
+ .filter((item) => item.toLowerCase() === key.toLowerCase())
25
+ .at(-1);
22
26
  return matchedKey ? env[matchedKey] : undefined;
23
27
  };
24
28
  const getWindowsExecutableNames = (command, env, platform = process.platform) => {
@@ -28,7 +32,7 @@ const getWindowsExecutableNames = (command, env, platform = process.platform) =>
28
32
  .split(';')
29
33
  .map((item) => item.trim())
30
34
  .filter(Boolean);
31
- return [...extensions.map((extension) => `${command}${extension}`), command];
35
+ return extensions.map((extension) => `${command}${extension}`);
32
36
  };
33
37
  const getExecutableNames = (command, env, platform = process.platform) => platform === 'win32' ? getWindowsExecutableNames(command, env, platform) : [command];
34
38
  export const resolveCommandPath = (command, cwd, env, platform = process.platform) => {
@@ -59,7 +63,10 @@ const buildWindowsBatchCommandLine = (command, args) => {
59
63
  // `call` is cmd's built-in batch invocation; it handles quoted .cmd / .bat
60
64
  // paths reliably (this is the same pattern Node.js's child_process uses
61
65
  // internally on Windows since the CVE-2024-27980 fix).
62
- return `/d /s /c ${buildCmdCallCommand(command, args)}`;
66
+ // Most Windows agent CLIs are npm .cmd shims. Set the console code page to
67
+ // UTF-8 before launching them so Hive's injected CJK startup guidance is not
68
+ // interpreted through the machine's OEM code page.
69
+ return `/d /s /c chcp 65001 >nul && ${buildCmdCallCommand(command, args)}`;
63
70
  };
64
71
  /**
65
72
  * Recognize the exact shape that `createStartupCommandLaunch` produces on
@@ -0,0 +1,6 @@
1
+ import type { PersistedAgentRun } from './agent-run-store.js';
2
+ export declare const WINDOWS_CONTROL_C_EXIT_CODE = 3221225786;
3
+ export declare const isUserInterruptExitCode: (exitCode: number | null) => boolean;
4
+ export declare const isCleanRunExitCode: (exitCode: number | null) => boolean;
5
+ export declare const classifyCompletedRunStatus: (exitCode: number | null) => PersistedAgentRun["status"];
6
+ export declare const shouldClearResumedSessionOnExit: (exitCode: number | null) => boolean;
@@ -0,0 +1,6 @@
1
+ export const WINDOWS_CONTROL_C_EXIT_CODE = 0xc000013a;
2
+ const USER_INTERRUPT_EXIT_CODES = new Set([130, 143, WINDOWS_CONTROL_C_EXIT_CODE]);
3
+ export const isUserInterruptExitCode = (exitCode) => exitCode !== null && USER_INTERRUPT_EXIT_CODES.has(exitCode);
4
+ export const isCleanRunExitCode = (exitCode) => exitCode === 0 || isUserInterruptExitCode(exitCode);
5
+ export const classifyCompletedRunStatus = (exitCode) => isCleanRunExitCode(exitCode) ? 'exited' : 'error';
6
+ export const shouldClearResumedSessionOnExit = (exitCode) => !isCleanRunExitCode(exitCode);
@@ -3,6 +3,7 @@ import type { AgentRunRecord, AgentRunSnapshot } from './agent-manager.js';
3
3
  import type { PtyOutputBus } from './pty-output-bus.js';
4
4
  export declare const MAX_RUN_OUTPUT_LENGTH = 1000000;
5
5
  type ExecRunner = (cmd: string, args: readonly string[], done: (success: boolean) => void) => void;
6
+ export declare const withSilencedConptyConsoleListAgent: <T>(platform: NodeJS.Platform, action: () => T) => T;
6
7
  /**
7
8
  * Windows analogue of POSIX `process.kill(-pgid, SIGKILL)`. node-pty on
8
9
  * Windows hands `pty.kill()` to TerminateProcess against the PTY's main
@@ -31,5 +32,5 @@ type ExecRunner = (cmd: string, args: readonly string[], done: (success: boolean
31
32
  export declare const taskkillProcessTree: (pid: number, platform?: NodeJS.Platform, runner?: ExecRunner, onFailure?: () => void) => boolean;
32
33
  export declare const toAgentRunSnapshot: (run: AgentRunRecord) => AgentRunSnapshot;
33
34
  export declare const finishAgentRun: (run: AgentRunRecord, exitCode: number | null, ptyOutputBus: PtyOutputBus) => void;
34
- export declare const attachAgentPty: (run: AgentRunRecord, pty: IPty, ptyOutputBus: PtyOutputBus) => void;
35
+ export declare const attachAgentPty: (run: AgentRunRecord, pty: IPty, ptyOutputBus: PtyOutputBus, platform?: NodeJS.Platform, execRunner?: ExecRunner) => void;
35
36
  export {};