@tt-a1i/hive 1.6.0 → 2.0.1
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.
- package/CHANGELOG.md +65 -0
- package/README.en.md +74 -11
- package/README.md +42 -8
- package/dist/src/cli/hive-remote.d.ts +46 -0
- package/dist/src/cli/hive-remote.js +257 -0
- package/dist/src/cli/hive-update.js +7 -2
- package/dist/src/cli/hive.d.ts +6 -0
- package/dist/src/cli/hive.js +64 -0
- package/dist/src/cli/team.d.ts +22 -0
- package/dist/src/cli/team.js +255 -5
- package/dist/src/server/agent-command-resolver.js +10 -3
- package/dist/src/server/agent-exit-classification.d.ts +6 -0
- package/dist/src/server/agent-exit-classification.js +6 -0
- package/dist/src/server/agent-manager-support.d.ts +2 -1
- package/dist/src/server/agent-manager-support.js +59 -15
- package/dist/src/server/agent-manager.d.ts +3 -0
- package/dist/src/server/agent-manager.js +22 -7
- package/dist/src/server/agent-run-bootstrap.d.ts +20 -1
- package/dist/src/server/agent-run-bootstrap.js +16 -6
- package/dist/src/server/agent-run-exit-handler.js +14 -8
- package/dist/src/server/agent-run-starter.d.ts +3 -1
- package/dist/src/server/agent-run-starter.js +37 -6
- package/dist/src/server/agent-run-sync.js +13 -5
- package/dist/src/server/agent-runtime-types.d.ts +1 -0
- package/dist/src/server/agent-runtime.d.ts +2 -1
- package/dist/src/server/agent-runtime.js +9 -2
- package/dist/src/server/agent-startup-instructions.d.ts +2 -1
- package/dist/src/server/agent-startup-instructions.js +8 -4
- package/dist/src/server/agent-stdin-dispatcher.d.ts +4 -2
- package/dist/src/server/agent-stdin-dispatcher.js +35 -3
- package/dist/src/server/command-preset-defaults.d.ts +6 -1
- package/dist/src/server/command-preset-defaults.js +68 -0
- package/dist/src/server/fs-browse.d.ts +2 -0
- package/dist/src/server/fs-browse.js +165 -31
- package/dist/src/server/fs-pick-folder.js +6 -69
- package/dist/src/server/fs-sandbox.d.ts +5 -3
- package/dist/src/server/fs-sandbox.js +5 -3
- package/dist/src/server/hive-team-guidance.js +18 -6
- package/dist/src/server/machine-name.d.ts +2 -0
- package/dist/src/server/machine-name.js +13 -0
- package/dist/src/server/open-target-commands.d.ts +1 -0
- package/dist/src/server/open-target-commands.js +4 -1
- package/dist/src/server/orchestrator-autostart.js +1 -1
- package/dist/src/server/platform-path.d.ts +1 -0
- package/dist/src/server/platform-path.js +14 -1
- package/dist/src/server/post-start-input-writer.js +50 -13
- package/dist/src/server/preset-launch-support.js +3 -1
- package/dist/src/server/recovery-summary.d.ts +2 -1
- package/dist/src/server/recovery-summary.js +2 -1
- package/dist/src/server/remote-audit-store.d.ts +51 -0
- package/dist/src/server/remote-audit-store.js +108 -0
- package/dist/src/server/remote-config-keys.d.ts +17 -0
- package/dist/src/server/remote-config-keys.js +27 -0
- package/dist/src/server/remote-control-constants.d.ts +30 -0
- package/dist/src/server/remote-control-constants.js +29 -0
- package/dist/src/server/remote-device-session.d.ts +40 -0
- package/dist/src/server/remote-device-session.js +22 -0
- package/dist/src/server/remote-device-store.d.ts +36 -0
- package/dist/src/server/remote-device-store.js +67 -0
- package/dist/src/server/remote-frame-bridge.d.ts +102 -0
- package/dist/src/server/remote-frame-bridge.js +791 -0
- package/dist/src/server/remote-gateway-client.d.ts +14 -0
- package/dist/src/server/remote-gateway-client.js +36 -0
- package/dist/src/server/remote-loopback-auth.d.ts +6 -0
- package/dist/src/server/remote-loopback-auth.js +112 -0
- package/dist/src/server/remote-pairing-tunnel.d.ts +59 -0
- package/dist/src/server/remote-pairing-tunnel.js +146 -0
- package/dist/src/server/remote-pairing.d.ts +58 -0
- package/dist/src/server/remote-pairing.js +237 -0
- package/dist/src/server/remote-tunnel.d.ts +113 -0
- package/dist/src/server/remote-tunnel.js +514 -0
- package/dist/src/server/restart-policy-support.d.ts +4 -1
- package/dist/src/server/restart-policy-support.js +3 -1
- package/dist/src/server/restart-policy.d.ts +1 -1
- package/dist/src/server/restart-policy.js +19 -3
- package/dist/src/server/route-types.d.ts +1 -1
- package/dist/src/server/routes-dispatches.js +1 -1
- package/dist/src/server/routes-fs.js +3 -3
- package/dist/src/server/routes-marketplace.js +2 -2
- package/dist/src/server/routes-open-workspace.js +1 -1
- package/dist/src/server/routes-remote.d.ts +2 -0
- package/dist/src/server/routes-remote.js +166 -0
- package/dist/src/server/routes-runtime.js +6 -6
- package/dist/src/server/routes-settings.js +16 -16
- package/dist/src/server/routes-tasks.js +2 -2
- package/dist/src/server/routes-team-memory.d.ts +2 -0
- package/dist/src/server/routes-team-memory.js +154 -0
- package/dist/src/server/routes-team-recall.d.ts +2 -0
- package/dist/src/server/routes-team-recall.js +119 -0
- package/dist/src/server/routes-team.js +31 -9
- package/dist/src/server/routes-ui.js +11 -1
- package/dist/src/server/routes-workflow-schedules.js +3 -3
- package/dist/src/server/routes-workflows.js +5 -5
- package/dist/src/server/routes-workspace-memory-dreams.d.ts +2 -0
- package/dist/src/server/routes-workspace-memory-dreams.js +105 -0
- package/dist/src/server/routes-workspace-memory.d.ts +2 -0
- package/dist/src/server/routes-workspace-memory.js +215 -0
- package/dist/src/server/routes-workspaces.js +9 -9
- package/dist/src/server/routes.js +10 -0
- package/dist/src/server/runtime-database.d.ts +1 -0
- package/dist/src/server/runtime-database.js +27 -2
- package/dist/src/server/runtime-restart-policy.d.ts +3 -1
- package/dist/src/server/runtime-restart-policy.js +2 -1
- package/dist/src/server/runtime-store-contract.d.ts +37 -0
- package/dist/src/server/runtime-store-dream.d.ts +23 -0
- package/dist/src/server/runtime-store-dream.js +16 -0
- package/dist/src/server/runtime-store-helpers.d.ts +20 -0
- package/dist/src/server/runtime-store-helpers.js +81 -7
- package/dist/src/server/runtime-store-memory.d.ts +33 -0
- package/dist/src/server/runtime-store-memory.js +37 -0
- package/dist/src/server/runtime-store-remote.d.ts +5 -0
- package/dist/src/server/runtime-store-remote.js +45 -0
- package/dist/src/server/runtime-store-workflows.js +2 -0
- package/dist/src/server/runtime-store.js +14 -3
- package/dist/src/server/session-capture-claude.d.ts +1 -1
- package/dist/src/server/session-capture-claude.js +7 -4
- package/dist/src/server/session-capture-codex.js +4 -5
- package/dist/src/server/session-capture-gemini.js +4 -5
- package/dist/src/server/session-capture-opencode.d.ts +4 -4
- package/dist/src/server/session-capture-opencode.js +20 -12
- package/dist/src/server/session-capture-qwen.d.ts +5 -0
- package/dist/src/server/session-capture-qwen.js +104 -0
- package/dist/src/server/session-capture.d.ts +23 -0
- package/dist/src/server/session-capture.js +48 -0
- package/dist/src/server/sqlite-schema-v22.d.ts +2 -0
- package/dist/src/server/sqlite-schema-v22.js +27 -0
- package/dist/src/server/sqlite-schema-v23.d.ts +2 -0
- package/dist/src/server/sqlite-schema-v23.js +43 -0
- package/dist/src/server/sqlite-schema-v24.d.ts +2 -0
- package/dist/src/server/sqlite-schema-v24.js +34 -0
- package/dist/src/server/sqlite-schema-v25.d.ts +2 -0
- package/dist/src/server/sqlite-schema-v25.js +127 -0
- package/dist/src/server/sqlite-schema-v26.d.ts +2 -0
- package/dist/src/server/sqlite-schema-v26.js +56 -0
- package/dist/src/server/sqlite-schema-v27.d.ts +6 -0
- package/dist/src/server/sqlite-schema-v27.js +92 -0
- package/dist/src/server/sqlite-schema-v28.d.ts +2 -0
- package/dist/src/server/sqlite-schema-v28.js +19 -0
- package/dist/src/server/sqlite-schema-v29.d.ts +2 -0
- package/dist/src/server/sqlite-schema-v29.js +27 -0
- package/dist/src/server/sqlite-schema-v30.d.ts +2 -0
- package/dist/src/server/sqlite-schema-v30.js +27 -0
- package/dist/src/server/sqlite-schema-v31.d.ts +2 -0
- package/dist/src/server/sqlite-schema-v31.js +30 -0
- package/dist/src/server/sqlite-schema.d.ts +1 -1
- package/dist/src/server/sqlite-schema.js +54 -1
- package/dist/src/server/startup-command-parser.js +5 -1
- package/dist/src/server/tasks-file-watcher.d.ts +2 -0
- package/dist/src/server/tasks-file-watcher.js +15 -6
- package/dist/src/server/tasks-file.js +30 -5
- package/dist/src/server/tasks-websocket-server.js +4 -0
- package/dist/src/server/team-authz.d.ts +1 -1
- package/dist/src/server/team-authz.js +13 -1
- package/dist/src/server/team-list-enrichment.js +3 -1
- package/dist/src/server/team-memory-digest.d.ts +52 -0
- package/dist/src/server/team-memory-digest.js +200 -0
- package/dist/src/server/team-memory-dream-applier.d.ts +5 -0
- package/dist/src/server/team-memory-dream-applier.js +234 -0
- package/dist/src/server/team-memory-dream-http-serializers.d.ts +13 -0
- package/dist/src/server/team-memory-dream-http-serializers.js +12 -0
- package/dist/src/server/team-memory-dream-ops.d.ts +40 -0
- package/dist/src/server/team-memory-dream-ops.js +153 -0
- package/dist/src/server/team-memory-dream-reverter.d.ts +22 -0
- package/dist/src/server/team-memory-dream-reverter.js +221 -0
- package/dist/src/server/team-memory-dream-run-store.d.ts +23 -0
- package/dist/src/server/team-memory-dream-run-store.js +211 -0
- package/dist/src/server/team-memory-dream-runner.d.ts +37 -0
- package/dist/src/server/team-memory-dream-runner.js +178 -0
- package/dist/src/server/team-memory-dream-scheduler.d.ts +32 -0
- package/dist/src/server/team-memory-dream-scheduler.js +115 -0
- package/dist/src/server/team-memory-dream-store.d.ts +19 -0
- package/dist/src/server/team-memory-dream-store.js +16 -0
- package/dist/src/server/team-memory-dream-types.d.ts +104 -0
- package/dist/src/server/team-memory-dream-types.js +23 -0
- package/dist/src/server/team-memory-export.d.ts +22 -0
- package/dist/src/server/team-memory-export.js +220 -0
- package/dist/src/server/team-memory-feature.d.ts +12 -0
- package/dist/src/server/team-memory-feature.js +12 -0
- package/dist/src/server/team-memory-http-serializers.d.ts +102 -0
- package/dist/src/server/team-memory-http-serializers.js +46 -0
- package/dist/src/server/team-memory-injection.d.ts +31 -0
- package/dist/src/server/team-memory-injection.js +49 -0
- package/dist/src/server/team-memory-store.d.ts +116 -0
- package/dist/src/server/team-memory-store.js +513 -0
- package/dist/src/server/team-operations.d.ts +5 -1
- package/dist/src/server/team-operations.js +46 -16
- package/dist/src/server/team-recall-store.d.ts +38 -0
- package/dist/src/server/team-recall-store.js +205 -0
- package/dist/src/server/terminal-input-profile.d.ts +1 -1
- package/dist/src/server/terminal-input-profile.js +8 -0
- package/dist/src/server/terminal-ws-server.js +6 -0
- package/dist/src/server/ui-auth-helpers.d.ts +1 -1
- package/dist/src/server/ui-auth-helpers.js +7 -1
- package/dist/src/server/ui-auth.d.ts +3 -0
- package/dist/src/server/ui-auth.js +21 -1
- package/dist/src/server/workflow-cli-policy.d.ts +2 -3
- package/dist/src/server/workflow-cli-policy.js +3 -3
- package/dist/src/server/workflow-runner.d.ts +1 -0
- package/dist/src/server/workflow-runner.js +9 -4
- package/dist/src/server/workspace-path-validation.js +6 -2
- package/dist/src/server/workspace-store.d.ts +1 -1
- package/dist/src/server/workspace-store.js +35 -9
- package/dist/src/shared/fs-browse.d.ts +1 -0
- package/dist/src/shared/fs-browse.js +1 -0
- package/dist/src/shared/path-input.d.ts +12 -0
- package/dist/src/shared/path-input.js +22 -0
- package/dist/src/shared/remote-bridge-routing.d.ts +19 -0
- package/dist/src/shared/remote-bridge-routing.js +141 -0
- package/dist/src/shared/remote-crypto.d.ts +138 -0
- package/dist/src/shared/remote-crypto.js +427 -0
- package/dist/src/shared/remote-pairing-code.d.ts +7 -0
- package/dist/src/shared/remote-pairing-code.js +47 -0
- package/dist/src/shared/remote-protocol.d.ts +160 -0
- package/dist/src/shared/remote-protocol.js +526 -0
- package/dist/src/shared/team-memory.d.ts +11 -0
- package/dist/src/shared/team-memory.js +10 -0
- package/dist/src/shared/team-recall.d.ts +1 -0
- package/dist/src/shared/team-recall.js +1 -0
- package/dist/src/shared/types.d.ts +5 -6
- package/package.json +12 -5
- package/scripts/postinstall-native-artifacts.mjs +113 -0
- package/web/dist/assets/AddWorkerDialog-C86CwNgQ.js +2 -0
- package/web/dist/assets/AddWorkspaceFlow-Bm2Jz34D.js +1 -0
- package/web/dist/assets/FirstRunWizard-XzBoEpA5.js +1 -0
- package/web/dist/assets/MarketplaceDrawer-BFfGT8hH.js +67 -0
- package/web/dist/assets/TaskGraphDrawer-_uVH_0C1.js +1 -0
- package/web/dist/assets/{WhatsNewDialog-CSGzk-2U.js → WhatsNewDialog-DkJHmkMs.js} +1 -1
- package/web/dist/assets/WorkerModal-BtMJEOG9.js +1 -0
- package/web/dist/assets/WorkflowsDrawer-CiIdHS6_.js +1 -0
- package/web/dist/assets/WorkspaceMemoryDrawer-C6sNocl_.js +1 -0
- package/web/dist/assets/WorkspaceTaskDrawer-CyhhEB1Z.js +1 -0
- package/web/dist/assets/index-BAiLYajK.css +1 -0
- package/web/dist/assets/index-K-GG8UwR.js +73 -0
- package/web/dist/assets/search-BtRkkEmS.js +1 -0
- package/web/dist/assets/square-terminal-lEeQUWb3.js +1 -0
- package/web/dist/cli-icons/agy.png +0 -0
- package/web/dist/cli-icons/cursor.ico +0 -0
- package/web/dist/cli-icons/grok.ico +0 -0
- package/web/dist/cli-icons/hermes.png +0 -0
- package/web/dist/cli-icons/qwen.png +0 -0
- package/web/dist/index.html +8 -3
- package/web/dist/sw.js +1 -1
- package/scripts/fix-runtime-artifacts.mjs +0 -33
- package/web/dist/assets/AddWorkerDialog-CGbaxu0T.js +0 -2
- package/web/dist/assets/AddWorkspaceDialog-CNgExu6b.js +0 -1
- package/web/dist/assets/FirstRunWizard-DxGApUNc.js +0 -1
- package/web/dist/assets/MarketplaceDrawer-Bk6cpukn.js +0 -76
- package/web/dist/assets/WorkerModal-i2F3n3nZ.js +0 -1
- package/web/dist/assets/WorkspaceTaskDrawer-C_Ta_K13.js +0 -1
- package/web/dist/assets/WorkspaceTerminalPanels-DDGTF8rc.css +0 -1
- package/web/dist/assets/WorkspaceTerminalPanels-VdDxtrQF.js +0 -1
- package/web/dist/assets/index-5zh61jMg.css +0 -1
- package/web/dist/assets/index-CAgGM6nb.js +0 -75
- package/web/dist/assets/path-join-7MR1s7b1.js +0 -1
|
@@ -173,7 +173,12 @@ export const resolveHiveUpdateInstallArgs = (moduleUrl = import.meta.url) => {
|
|
|
173
173
|
return [...INSTALL_COMMAND_ARGS];
|
|
174
174
|
return [...INSTALL_COMMAND_ARGS, '--prefix', prefix];
|
|
175
175
|
};
|
|
176
|
-
const
|
|
176
|
+
const windowsQuote = (value) => {
|
|
177
|
+
if (/^[-A-Za-z0-9_/:=.,@+\\]+$/.test(value))
|
|
178
|
+
return value;
|
|
179
|
+
return `"${value.replace(/"/g, '""')}"`;
|
|
180
|
+
};
|
|
181
|
+
const formatInstallCommand = (args, platform = process.platform) => `npm ${args.map(platform === 'win32' ? windowsQuote : shellQuote).join(' ')}`;
|
|
177
182
|
export const runHiveUpdateCommand = async (argv, options = {}) => {
|
|
178
183
|
if (argv.includes('--help') || argv.includes('-h')) {
|
|
179
184
|
console.log(HIVE_UPDATE_USAGE);
|
|
@@ -190,7 +195,7 @@ export const runHiveUpdateCommand = async (argv, options = {}) => {
|
|
|
190
195
|
const run = options.runUpdate ?? defaultRunUpdate;
|
|
191
196
|
const command = getNpmCommand(options.platform);
|
|
192
197
|
const args = resolveHiveUpdateInstallArgs(options.moduleUrl);
|
|
193
|
-
const displayCommand = formatInstallCommand(args);
|
|
198
|
+
const displayCommand = formatInstallCommand(args, options.platform);
|
|
194
199
|
console.log(`Running: ${displayCommand}`);
|
|
195
200
|
const result = await run(command, args);
|
|
196
201
|
if (result.spawnError) {
|
package/dist/src/cli/hive.d.ts
CHANGED
|
@@ -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 };
|
package/dist/src/cli/hive.js
CHANGED
|
@@ -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
|
}
|
package/dist/src/cli/team.d.ts
CHANGED
|
@@ -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>;
|
package/dist/src/cli/team.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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(
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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 {};
|