@tt-a1i/hive 1.2.0 → 1.3.4
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 +119 -14
- package/README.en.md +63 -8
- package/README.md +37 -6
- package/assets/hive-team-view.png +0 -0
- package/dist/src/cli/hive-update.d.ts +15 -0
- package/dist/src/cli/hive-update.js +81 -0
- package/dist/src/cli/hive.js +21 -5
- package/dist/src/cli/team.d.ts +6 -0
- package/dist/src/cli/team.js +48 -0
- package/dist/src/server/agent-launch-cache.js +25 -6
- package/dist/src/server/agent-manager.d.ts +2 -2
- package/dist/src/server/agent-run-store.d.ts +1 -1
- package/dist/src/server/agent-runtime-contract.d.ts +3 -0
- package/dist/src/server/agent-runtime.js +3 -0
- package/dist/src/server/agent-startup-instructions.js +1 -1
- package/dist/src/server/agent-stdin-dispatcher.d.ts +4 -0
- package/dist/src/server/agent-stdin-dispatcher.js +12 -0
- package/dist/src/server/app.js +12 -1
- package/dist/src/server/dispatch-ledger-store.d.ts +22 -1
- package/dist/src/server/dispatch-ledger-store.js +34 -3
- package/dist/src/server/hive-team-guidance.js +3 -1
- package/dist/src/server/open-target-commands.js +0 -17
- package/dist/src/server/package-version.d.ts +15 -0
- package/dist/src/server/package-version.js +15 -0
- package/dist/src/server/route-types.d.ts +7 -0
- package/dist/src/server/routes-dispatches.js +4 -2
- package/dist/src/server/routes-runtime.js +1 -0
- package/dist/src/server/routes-team.js +22 -0
- package/dist/src/server/runtime-store-helpers.d.ts +2 -1
- package/dist/src/server/runtime-store-helpers.js +14 -4
- package/dist/src/server/runtime-store.d.ts +5 -8
- package/dist/src/server/runtime-store.js +1 -0
- package/dist/src/server/tasks-websocket-server.d.ts +2 -1
- package/dist/src/server/tasks-websocket-server.js +18 -2
- package/dist/src/server/team-authz.d.ts +1 -1
- package/dist/src/server/team-authz.js +1 -1
- package/dist/src/server/team-operations.d.ts +16 -1
- package/dist/src/server/team-operations.js +28 -1
- package/dist/src/server/terminal-input-profile.d.ts +10 -0
- package/dist/src/server/terminal-input-profile.js +15 -0
- package/dist/src/server/terminal-stream-hub.js +10 -2
- package/dist/src/server/terminal-ws-server.d.ts +2 -1
- package/dist/src/server/terminal-ws-server.js +2 -2
- package/dist/src/server/version-service.js +4 -1
- package/dist/src/server/workspace-shell-runtime.d.ts +2 -1
- package/dist/src/server/workspace-shell-runtime.js +37 -10
- package/dist/src/server/workspace-store-contract.d.ts +1 -0
- package/dist/src/server/workspace-store-mutations.d.ts +1 -0
- package/dist/src/server/workspace-store-mutations.js +1 -0
- package/dist/src/server/workspace-store.js +2 -1
- package/dist/src/shared/open-targets.d.ts +1 -1
- package/dist/src/shared/open-targets.js +9 -16
- package/package.json +2 -2
- package/web/dist/assets/AddWorkerDialog-D6-K1wJm.js +1 -0
- package/web/dist/assets/AddWorkspaceDialog-Du0lndJ0.js +1 -0
- package/web/dist/assets/FirstRunWizard-B8k7S5De.js +1 -0
- package/web/dist/assets/WorkerModal-B3XhIvAX.js +1 -0
- package/web/dist/assets/WorkspaceTaskDrawer-CjEoLJvS.js +1 -0
- package/web/dist/assets/chevron-right-BvbSCniy.js +1 -0
- package/web/dist/assets/finder-C4Jmsb0B.png +0 -0
- package/web/dist/assets/ghostty-D-Js4rdm.png +0 -0
- package/web/dist/assets/index-DB5fHAMI.js +81 -0
- package/web/dist/assets/index-Sbdu6Se0.css +1 -0
- package/web/dist/assets/zed-C5BQT8X3.png +0 -0
- package/web/dist/icons/apple-touch-icon-180.png +0 -0
- package/web/dist/icons/icon-192.png +0 -0
- package/web/dist/icons/icon-32.png +0 -0
- package/web/dist/icons/icon-512-maskable.png +0 -0
- package/web/dist/icons/icon-512.png +0 -0
- package/web/dist/index.html +11 -3
- package/web/dist/manifest.webmanifest +60 -0
- package/web/dist/screenshots/wide-overview.png +0 -0
- package/web/dist/sw.js +99 -0
- package/web/dist/assets/index-BgXxFsKj.css +0 -1
- package/web/dist/assets/index-VeKhgpe_.js +0 -66
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { Server } from 'node:http';
|
|
2
2
|
import type { RuntimeStore } from './runtime-store.js';
|
|
3
|
+
import type { TasksFileService } from './tasks-file.js';
|
|
3
4
|
export interface TasksWebSocketServer {
|
|
4
5
|
close: () => void;
|
|
5
6
|
publish: (workspaceId: string, content: string) => void;
|
|
6
7
|
}
|
|
7
|
-
export declare const createTasksWebSocketServer: (server: Server, store: RuntimeStore) => TasksWebSocketServer;
|
|
8
|
+
export declare const createTasksWebSocketServer: (server: Server, store: RuntimeStore, tasksFileService: Pick<TasksFileService, "readTasks">) => TasksWebSocketServer;
|
|
@@ -10,7 +10,7 @@ const rejectUpgrade = (socket, status) => {
|
|
|
10
10
|
socket.write(`HTTP/1.1 ${status}\r\n\r\n`);
|
|
11
11
|
socket.destroy();
|
|
12
12
|
};
|
|
13
|
-
export const createTasksWebSocketServer = (server, store) => {
|
|
13
|
+
export const createTasksWebSocketServer = (server, store, tasksFileService) => {
|
|
14
14
|
const wss = new WebSocketServer({ noServer: true });
|
|
15
15
|
const socketsByWorkspaceId = new Map();
|
|
16
16
|
const validateUpgradeSession = (request) => {
|
|
@@ -33,8 +33,9 @@ export const createTasksWebSocketServer = (server, store) => {
|
|
|
33
33
|
rejectUpgrade(socket, '401 Unauthorized');
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
36
|
+
let workspacePath = '';
|
|
36
37
|
try {
|
|
37
|
-
store.getWorkspaceSnapshot(workspaceId);
|
|
38
|
+
workspacePath = store.getWorkspaceSnapshot(workspaceId).summary.path;
|
|
38
39
|
}
|
|
39
40
|
catch {
|
|
40
41
|
rejectUpgrade(socket, '404 Not Found');
|
|
@@ -50,6 +51,21 @@ export const createTasksWebSocketServer = (server, store) => {
|
|
|
50
51
|
socketsByWorkspaceId.delete(workspaceId);
|
|
51
52
|
}
|
|
52
53
|
});
|
|
54
|
+
setImmediate(() => {
|
|
55
|
+
if (ws.readyState !== ws.OPEN)
|
|
56
|
+
return;
|
|
57
|
+
try {
|
|
58
|
+
ws.send(JSON.stringify({
|
|
59
|
+
type: 'tasks-snapshot',
|
|
60
|
+
content: tasksFileService.readTasks(workspacePath),
|
|
61
|
+
}));
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
if (ws.readyState === ws.OPEN) {
|
|
65
|
+
ws.send(JSON.stringify({ type: 'tasks-snapshot', content: '' }));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
});
|
|
53
69
|
});
|
|
54
70
|
});
|
|
55
71
|
return {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AgentSummary } from '../shared/types.js';
|
|
2
|
-
export type TeamCommand = 'send' | 'list' | 'report' | 'status' | 'help';
|
|
2
|
+
export type TeamCommand = 'send' | 'list' | 'report' | 'status' | 'cancel' | 'help';
|
|
3
3
|
export declare const commandAllowedForRole: (role: AgentSummary["role"], command: TeamCommand) => boolean;
|
|
4
4
|
interface AuthenticateInput {
|
|
5
5
|
fromAgentId: string | undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ForbiddenError, UnauthorizedError } from './http-errors.js';
|
|
2
|
-
const ORCHESTRATOR_COMMANDS = new Set(['send', 'list', 'help']);
|
|
2
|
+
const ORCHESTRATOR_COMMANDS = new Set(['send', 'list', 'cancel', 'help']);
|
|
3
3
|
const WORKER_COMMANDS = new Set(['report', 'status', 'help']);
|
|
4
4
|
const WORKER_ROLES = new Set(['coder', 'reviewer', 'tester', 'custom']);
|
|
5
5
|
export const commandAllowedForRole = (role, command) => {
|
|
@@ -13,7 +13,13 @@ export interface TeamOperationsInput {
|
|
|
13
13
|
deleteDispatch: (dispatchId: string) => void;
|
|
14
14
|
deleteMessage: (handle: MessageLogHandle) => void;
|
|
15
15
|
findOpenDispatch: (workspaceId: string, toAgentId: string, dispatchId?: string) => DispatchRecord | undefined;
|
|
16
|
+
findOpenDispatchById: (workspaceId: string, dispatchId: string) => DispatchRecord | undefined;
|
|
16
17
|
insertMessage: (record: MessageLogRecord) => MessageLogHandle;
|
|
18
|
+
markDispatchCancelled: (input: {
|
|
19
|
+
dispatchId: string;
|
|
20
|
+
reason: string;
|
|
21
|
+
workspaceId: string;
|
|
22
|
+
}) => DispatchRecord | undefined;
|
|
17
23
|
markDispatchReportedByWorker: (input: {
|
|
18
24
|
artifacts: string[];
|
|
19
25
|
dispatchId?: string;
|
|
@@ -40,12 +46,21 @@ export interface StatusTaskInput {
|
|
|
40
46
|
requireActiveRun?: boolean;
|
|
41
47
|
text?: string;
|
|
42
48
|
}
|
|
49
|
+
export interface CancelTaskInput {
|
|
50
|
+
fromAgentId: string;
|
|
51
|
+
reason: string;
|
|
52
|
+
}
|
|
43
53
|
export interface ReportTaskResult {
|
|
44
54
|
dispatch: DispatchRecord | null;
|
|
45
55
|
forwardError: string | null;
|
|
46
56
|
forwarded: boolean;
|
|
47
57
|
}
|
|
48
|
-
export declare const createTeamOperations: ({ agentRuntime, createDispatch, deleteDispatch, deleteMessage, findOpenDispatch, insertMessage, markDispatchReportedByWorker, markDispatchSubmitted, workspaceStore, }: TeamOperationsInput) => {
|
|
58
|
+
export declare const createTeamOperations: ({ agentRuntime, createDispatch, deleteDispatch, deleteMessage, findOpenDispatch, findOpenDispatchById, insertMessage, markDispatchCancelled, markDispatchReportedByWorker, markDispatchSubmitted, workspaceStore, }: TeamOperationsInput) => {
|
|
59
|
+
cancelTask(workspaceId: string, dispatchId: string, input: CancelTaskInput): {
|
|
60
|
+
dispatch: DispatchRecord;
|
|
61
|
+
forwardError: string | null;
|
|
62
|
+
forwarded: boolean;
|
|
63
|
+
};
|
|
49
64
|
dispatchTask: (workspaceId: string, workerId: string, text: string, input?: DispatchTaskInput) => Promise<DispatchRecord>;
|
|
50
65
|
dispatchTaskByWorkerName(workspaceId: string, workerName: string, text: string, input?: DispatchTaskInput): Promise<DispatchRecord>;
|
|
51
66
|
recordUserInput(workspaceId: string, orchestratorId: string, text: string): void;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ConflictError, PtyInactiveError } from './http-errors.js';
|
|
2
2
|
import { createReportMessage, createSendMessage, createStatusMessage, createUserInputMessage, } from './runtime-message-builders.js';
|
|
3
3
|
const reportForwardErrorMessage = (error) => error instanceof Error ? error.message : String(error);
|
|
4
|
-
export const createTeamOperations = ({ agentRuntime, createDispatch, deleteDispatch, deleteMessage, findOpenDispatch, insertMessage, markDispatchReportedByWorker, markDispatchSubmitted, workspaceStore, }) => {
|
|
4
|
+
export const createTeamOperations = ({ agentRuntime, createDispatch, deleteDispatch, deleteMessage, findOpenDispatch, findOpenDispatchById, insertMessage, markDispatchCancelled, markDispatchReportedByWorker, markDispatchSubmitted, workspaceStore, }) => {
|
|
5
5
|
const ensureWorkerRun = async (workspaceId, workerId, hivePort) => {
|
|
6
6
|
if (agentRuntime.getActiveRunByAgentId(workspaceId, workerId)) {
|
|
7
7
|
return;
|
|
@@ -54,6 +54,33 @@ export const createTeamOperations = ({ agentRuntime, createDispatch, deleteDispa
|
|
|
54
54
|
}
|
|
55
55
|
};
|
|
56
56
|
return {
|
|
57
|
+
cancelTask(workspaceId, dispatchId, input) {
|
|
58
|
+
workspaceStore.getAgent(workspaceId, input.fromAgentId);
|
|
59
|
+
const openDispatch = findOpenDispatchById(workspaceId, dispatchId);
|
|
60
|
+
if (!openDispatch) {
|
|
61
|
+
throw new ConflictError(`No open dispatch: ${dispatchId}`);
|
|
62
|
+
}
|
|
63
|
+
const dispatch = markDispatchCancelled({
|
|
64
|
+
dispatchId,
|
|
65
|
+
reason: input.reason,
|
|
66
|
+
workspaceId,
|
|
67
|
+
});
|
|
68
|
+
if (!dispatch) {
|
|
69
|
+
throw new ConflictError(`No open dispatch: ${dispatchId}`);
|
|
70
|
+
}
|
|
71
|
+
workspaceStore.markTaskCancelled(workspaceId, dispatch.toAgentId);
|
|
72
|
+
let forwardError = null;
|
|
73
|
+
let forwarded = false;
|
|
74
|
+
try {
|
|
75
|
+
agentRuntime.writeCancelPrompt(workspaceId, dispatch.toAgentId, dispatch.id, input.reason);
|
|
76
|
+
forwarded = true;
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
forwardError = reportForwardErrorMessage(error);
|
|
80
|
+
console.error('[hive] swallowed:teamCancel.forward', error);
|
|
81
|
+
}
|
|
82
|
+
return { dispatch, forwardError, forwarded };
|
|
83
|
+
},
|
|
57
84
|
dispatchTask,
|
|
58
85
|
dispatchTaskByWorkerName(workspaceId, workerName, text, input = {}) {
|
|
59
86
|
const worker = workspaceStore.getWorkerByName(workspaceId, workerName);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AgentLaunchConfigInput } from './agent-run-store.js';
|
|
2
|
+
export type TerminalInputProfile = 'default' | 'opencode';
|
|
3
|
+
export interface TerminalRunSummary {
|
|
4
|
+
agent_id: string;
|
|
5
|
+
agent_name: string;
|
|
6
|
+
run_id: string;
|
|
7
|
+
status: string;
|
|
8
|
+
terminal_input_profile: TerminalInputProfile;
|
|
9
|
+
}
|
|
10
|
+
export declare const resolveTerminalInputProfile: (config: AgentLaunchConfigInput | undefined) => TerminalInputProfile;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { basename } from 'node:path';
|
|
2
|
+
const normalizeExecutable = (value) => {
|
|
3
|
+
if (!value)
|
|
4
|
+
return null;
|
|
5
|
+
const normalized = basename(value).toLowerCase();
|
|
6
|
+
return normalized.replace(/\.(cmd|exe)$/u, '');
|
|
7
|
+
};
|
|
8
|
+
export const resolveTerminalInputProfile = (config) => {
|
|
9
|
+
if (!config)
|
|
10
|
+
return 'default';
|
|
11
|
+
if (config.commandPresetId === 'opencode')
|
|
12
|
+
return 'opencode';
|
|
13
|
+
const executable = normalizeExecutable(config.interactiveCommand) ?? normalizeExecutable(config.command);
|
|
14
|
+
return executable === 'opencode' ? 'opencode' : 'default';
|
|
15
|
+
};
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { createTerminalOutputFlow } from './terminal-flow-control.js';
|
|
2
2
|
import { parseTerminalControlMessage, serializeTerminalError, serializeTerminalExit, serializeTerminalRestore, } from './terminal-protocol.js';
|
|
3
3
|
import { TerminalStateMirror } from './terminal-state-mirror.js';
|
|
4
|
+
const normalizeTerminalInput = (raw, isBinary) => {
|
|
5
|
+
const bytes = Buffer.isBuffer(raw)
|
|
6
|
+
? raw
|
|
7
|
+
: Array.isArray(raw)
|
|
8
|
+
? Buffer.concat(raw)
|
|
9
|
+
: Buffer.from(raw);
|
|
10
|
+
return isBinary ? Buffer.from(bytes) : bytes.toString();
|
|
11
|
+
};
|
|
4
12
|
export const createTerminalStreamHub = (store) => {
|
|
5
13
|
const runStates = new Map();
|
|
6
14
|
const maybeResumeRun = (runId, state, clientId) => {
|
|
@@ -149,8 +157,8 @@ export const createTerminalStreamHub = (store) => {
|
|
|
149
157
|
maybeResumeRun(runId, state, clientId);
|
|
150
158
|
},
|
|
151
159
|
});
|
|
152
|
-
socket.on('message', (raw) => {
|
|
153
|
-
store.writeRunInput(runId, raw
|
|
160
|
+
socket.on('message', (raw, isBinary) => {
|
|
161
|
+
store.writeRunInput(runId, normalizeTerminalInput(raw, isBinary));
|
|
154
162
|
});
|
|
155
163
|
socket.on('close', () => {
|
|
156
164
|
if (viewer.ioSocket === socket)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Server } from 'node:http';
|
|
2
2
|
import type { RuntimeStore } from './runtime-store.js';
|
|
3
|
-
|
|
3
|
+
import type { TasksFileService } from './tasks-file.js';
|
|
4
|
+
export declare const createTerminalWebSocketServer: (server: Server, store: RuntimeStore, tasksFileService: Pick<TasksFileService, "readTasks">) => {
|
|
4
5
|
close: () => void;
|
|
5
6
|
};
|
|
@@ -28,10 +28,10 @@ const rejectUpgrade = (socket, status) => {
|
|
|
28
28
|
socket.write(`HTTP/1.1 ${status}\r\n\r\n`);
|
|
29
29
|
socket.destroy();
|
|
30
30
|
};
|
|
31
|
-
export const createTerminalWebSocketServer = (server, store) => {
|
|
31
|
+
export const createTerminalWebSocketServer = (server, store, tasksFileService) => {
|
|
32
32
|
const ioWss = new WebSocketServer({ noServer: true });
|
|
33
33
|
const controlWss = new WebSocketServer({ noServer: true });
|
|
34
|
-
const tasksWss = createTasksWebSocketServer(server, store);
|
|
34
|
+
const tasksWss = createTasksWebSocketServer(server, store, tasksFileService);
|
|
35
35
|
const hub = createTerminalStreamHub(store);
|
|
36
36
|
const disposeTasksListener = store.registerTasksListener((workspaceId, content) => {
|
|
37
37
|
tasksWss.publish(workspaceId, content);
|
|
@@ -27,7 +27,10 @@ export const compareVersions = (left, right) => {
|
|
|
27
27
|
};
|
|
28
28
|
const buildVersionInfo = (currentVersion, latestVersion) => ({
|
|
29
29
|
current_version: currentVersion,
|
|
30
|
-
|
|
30
|
+
// Show `hive update` as the primary upgrade path now that the subcommand
|
|
31
|
+
// exists; it prints the npm fallback if its own spawn fails, so users
|
|
32
|
+
// running on Windows / Linux without a working npm in PATH still recover.
|
|
33
|
+
install_hint: 'hive update',
|
|
31
34
|
latest_version: latestVersion,
|
|
32
35
|
package_name: PACKAGE_NAME,
|
|
33
36
|
release_url: `https://www.npmjs.com/package/${PACKAGE_NAME}/v/${latestVersion}`,
|
|
@@ -18,12 +18,13 @@ export declare const createWorkspaceShellRuntime: (agentManager: AgentManager |
|
|
|
18
18
|
agent_name: string;
|
|
19
19
|
run_id: string;
|
|
20
20
|
status: import("./agent-manager.js").RunStatus;
|
|
21
|
+
terminal_input_profile: "default";
|
|
21
22
|
}[];
|
|
22
23
|
pauseRun(runId: string): void;
|
|
23
24
|
resizeRun(runId: string, cols: number, rows: number): void;
|
|
24
25
|
resumeRun(runId: string): void;
|
|
25
26
|
start(workspace: WorkspaceSummary): Promise<LiveAgentRun>;
|
|
26
27
|
stopRun(runId: string): void;
|
|
27
|
-
writeInput(runId: string,
|
|
28
|
+
writeInput(runId: string, input: Buffer | string): void;
|
|
28
29
|
};
|
|
29
30
|
export type WorkspaceShellRuntime = ReturnType<typeof createWorkspaceShellRuntime>;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { basename } from 'node:path';
|
|
2
2
|
const WORKSPACE_SHELL_SUFFIX = ':shell';
|
|
3
|
+
const WORKSPACE_SHELL_LABEL = 'Shell';
|
|
4
|
+
const EXITED_SHELL_RETENTION_MS = 5000;
|
|
3
5
|
export const getWorkspaceShellAgentId = (workspaceId) => `${workspaceId}${WORKSPACE_SHELL_SUFFIX}`;
|
|
4
6
|
export const isWorkspaceShellAgentId = (agentId) => agentId.endsWith(WORKSPACE_SHELL_SUFFIX);
|
|
5
7
|
const shouldUseLoginShell = (command) => {
|
|
@@ -20,10 +22,10 @@ export const resolveWorkspaceShellLaunch = (env = process.env, platform = proces
|
|
|
20
22
|
};
|
|
21
23
|
export const createWorkspaceShellRuntime = (agentManager) => {
|
|
22
24
|
const labelsByRunId = new Map();
|
|
23
|
-
const nextShellNumberByWorkspaceId = new Map();
|
|
24
25
|
const workspaceIdsByRunId = new Map();
|
|
25
26
|
const runIdsByWorkspaceId = new Map();
|
|
26
27
|
const startedAtByRunId = new Map();
|
|
28
|
+
const exitCleanupTimersByRunId = new Map();
|
|
27
29
|
const requireManager = () => {
|
|
28
30
|
if (!agentManager)
|
|
29
31
|
throw new Error('Agent manager is required for workspace shell terminals');
|
|
@@ -43,6 +45,10 @@ export const createWorkspaceShellRuntime = (agentManager) => {
|
|
|
43
45
|
}
|
|
44
46
|
};
|
|
45
47
|
const detachRun = (runId) => {
|
|
48
|
+
const exitCleanupTimer = exitCleanupTimersByRunId.get(runId);
|
|
49
|
+
if (exitCleanupTimer)
|
|
50
|
+
clearTimeout(exitCleanupTimer);
|
|
51
|
+
exitCleanupTimersByRunId.delete(runId);
|
|
46
52
|
const workspaceId = workspaceIdsByRunId.get(runId);
|
|
47
53
|
if (workspaceId) {
|
|
48
54
|
const retained = (runIdsByWorkspaceId.get(workspaceId) ?? []).filter((id) => id !== runId);
|
|
@@ -61,11 +67,27 @@ export const createWorkspaceShellRuntime = (agentManager) => {
|
|
|
61
67
|
startedAtByRunId.set(runId, startedAt);
|
|
62
68
|
runIdsByWorkspaceId.set(workspaceId, [...(runIdsByWorkspaceId.get(workspaceId) ?? []), runId]);
|
|
63
69
|
};
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
70
|
+
const forgetShellRun = (runId) => {
|
|
71
|
+
detachRun(runId);
|
|
72
|
+
try {
|
|
73
|
+
requireManager().removeRun(runId);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// The PTY manager may have already dropped the run.
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
const handleShellExit = (runId) => {
|
|
80
|
+
if (!hasRun(runId) || exitCleanupTimersByRunId.has(runId))
|
|
81
|
+
return;
|
|
82
|
+
const timer = setTimeout(() => {
|
|
83
|
+
exitCleanupTimersByRunId.delete(runId);
|
|
84
|
+
if (hasRun(runId))
|
|
85
|
+
forgetShellRun(runId);
|
|
86
|
+
}, EXITED_SHELL_RETENTION_MS);
|
|
87
|
+
timer.unref?.();
|
|
88
|
+
exitCleanupTimersByRunId.set(runId, timer);
|
|
68
89
|
};
|
|
90
|
+
const isListedRun = (run) => run.status === 'starting' || run.status === 'running';
|
|
69
91
|
const stopPtyRun = (runId) => {
|
|
70
92
|
requireManager().stopRun(runId);
|
|
71
93
|
};
|
|
@@ -92,7 +114,9 @@ export const createWorkspaceShellRuntime = (agentManager) => {
|
|
|
92
114
|
workspaceIdsByRunId.clear();
|
|
93
115
|
startedAtByRunId.clear();
|
|
94
116
|
labelsByRunId.clear();
|
|
95
|
-
|
|
117
|
+
for (const timer of exitCleanupTimersByRunId.values())
|
|
118
|
+
clearTimeout(timer);
|
|
119
|
+
exitCleanupTimersByRunId.clear();
|
|
96
120
|
},
|
|
97
121
|
closeRun(workspaceId, runId) {
|
|
98
122
|
if (workspaceIdsByRunId.get(runId) !== workspaceId)
|
|
@@ -110,7 +134,6 @@ export const createWorkspaceShellRuntime = (agentManager) => {
|
|
|
110
134
|
}
|
|
111
135
|
}
|
|
112
136
|
runIdsByWorkspaceId.delete(workspaceId);
|
|
113
|
-
nextShellNumberByWorkspaceId.delete(workspaceId);
|
|
114
137
|
},
|
|
115
138
|
getLiveRun(runId) {
|
|
116
139
|
if (!hasRun(runId))
|
|
@@ -122,12 +145,15 @@ export const createWorkspaceShellRuntime = (agentManager) => {
|
|
|
122
145
|
return (runIdsByWorkspaceId.get(workspaceId) ?? []).flatMap((runId) => {
|
|
123
146
|
try {
|
|
124
147
|
const run = toLiveRun(runId);
|
|
148
|
+
if (!isListedRun(run))
|
|
149
|
+
return [];
|
|
125
150
|
return [
|
|
126
151
|
{
|
|
127
152
|
agent_id: getWorkspaceShellAgentId(workspaceId),
|
|
128
153
|
agent_name: labelsByRunId.get(runId) ?? 'Shell',
|
|
129
154
|
run_id: run.runId,
|
|
130
155
|
status: run.status,
|
|
156
|
+
terminal_input_profile: 'default',
|
|
131
157
|
},
|
|
132
158
|
];
|
|
133
159
|
}
|
|
@@ -163,17 +189,18 @@ export const createWorkspaceShellRuntime = (agentManager) => {
|
|
|
163
189
|
TERM: 'xterm-256color',
|
|
164
190
|
TERM_PROGRAM: 'hive-shell',
|
|
165
191
|
},
|
|
192
|
+
onExit: ({ runId }) => handleShellExit(runId),
|
|
166
193
|
});
|
|
167
|
-
attachRun(workspace.id, run.runId,
|
|
194
|
+
attachRun(workspace.id, run.runId, WORKSPACE_SHELL_LABEL, startedAt);
|
|
168
195
|
return { ...run, startedAt };
|
|
169
196
|
},
|
|
170
197
|
stopRun(runId) {
|
|
171
198
|
if (hasRun(runId))
|
|
172
199
|
stopPtyRun(runId);
|
|
173
200
|
},
|
|
174
|
-
writeInput(runId,
|
|
201
|
+
writeInput(runId, input) {
|
|
175
202
|
if (hasRun(runId))
|
|
176
|
-
requireManager().writeInput(runId,
|
|
203
|
+
requireManager().writeInput(runId, input);
|
|
177
204
|
},
|
|
178
205
|
};
|
|
179
206
|
};
|
|
@@ -24,5 +24,6 @@ export interface WorkspaceStore {
|
|
|
24
24
|
markAgentStarted: (workspaceId: string, agentId: string) => void;
|
|
25
25
|
markAgentStopped: (workspaceId: string, agentId: string) => void;
|
|
26
26
|
markTaskDispatched: (workspaceId: string, workerId: string) => void;
|
|
27
|
+
markTaskCancelled: (workspaceId: string, workerId: string) => void;
|
|
27
28
|
markTaskReported: (workspaceId: string, workerId: string) => void;
|
|
28
29
|
}
|
|
@@ -10,4 +10,5 @@ export declare const markAgentStarted: (workspaces: WorkspaceMap, workspaceId: s
|
|
|
10
10
|
export declare const markAgentStopped: (workspaces: WorkspaceMap, workspaceId: string, agentId: string) => void;
|
|
11
11
|
export declare const markTaskDispatched: (workspaces: WorkspaceMap, workspaceId: string, workerId: string) => void;
|
|
12
12
|
export declare const markTaskReported: (workspaces: WorkspaceMap, workspaceId: string, workerId: string) => void;
|
|
13
|
+
export declare const markTaskCancelled: (workspaces: WorkspaceMap, workspaceId: string, workerId: string) => void;
|
|
13
14
|
export {};
|
|
@@ -2,7 +2,7 @@ import { randomUUID } from 'node:crypto';
|
|
|
2
2
|
import { ConflictError } from './http-errors.js';
|
|
3
3
|
import { getDefaultRoleDescription } from './role-templates.js';
|
|
4
4
|
import { hydrateWorkspaceFromDb, seedWorkspacesFromDb } from './workspace-store-hydration.js';
|
|
5
|
-
import { getAgentRecord, getWorkerByNameRecord, getWorkerRecord, markAgentStarted, markAgentStopped, markTaskDispatched, markTaskReported, } from './workspace-store-mutations.js';
|
|
5
|
+
import { getAgentRecord, getWorkerByNameRecord, getWorkerRecord, markAgentStarted, markAgentStopped, markTaskCancelled, markTaskDispatched, markTaskReported, } from './workspace-store-mutations.js';
|
|
6
6
|
import { createOrchestrator, isWorkerAgent, } from './workspace-store-support.js';
|
|
7
7
|
const normalizeWorkerName = (name) => {
|
|
8
8
|
const trimmed = name.trim();
|
|
@@ -113,6 +113,7 @@ export const createWorkspaceStore = (db, messageKinds) => {
|
|
|
113
113
|
markAgentStarted: (workspaceId, agentId) => markAgentStarted(workspaces, workspaceId, agentId),
|
|
114
114
|
markAgentStopped: (workspaceId, agentId) => markAgentStopped(workspaces, workspaceId, agentId),
|
|
115
115
|
markTaskDispatched: (workspaceId, workerId) => markTaskDispatched(workspaces, workspaceId, workerId),
|
|
116
|
+
markTaskCancelled: (workspaceId, workerId) => markTaskCancelled(workspaces, workspaceId, workerId),
|
|
116
117
|
markTaskReported: (workspaceId, workerId) => markTaskReported(workspaces, workspaceId, workerId),
|
|
117
118
|
};
|
|
118
119
|
};
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* and the web client (button + preference store in `web/src/workspace/open-targets.ts`)
|
|
5
5
|
* pull the union and platform whitelist from here so they cannot drift.
|
|
6
6
|
*/
|
|
7
|
-
export type OpenTargetId = 'vscode' | 'vscode-insiders' | 'cursor' | '
|
|
7
|
+
export type OpenTargetId = 'vscode' | 'vscode-insiders' | 'cursor' | 'finder' | 'terminal' | 'ghostty' | 'zed';
|
|
8
8
|
export type OpenTargetPlatform = 'mac' | 'windows' | 'linux' | 'other';
|
|
9
9
|
export declare const OPEN_TARGET_IDS_BY_PLATFORM: Record<OpenTargetPlatform, readonly OpenTargetId[]>;
|
|
10
10
|
export declare const isOpenTargetId: (value: unknown) => value is OpenTargetId;
|
|
@@ -6,23 +6,16 @@
|
|
|
6
6
|
*/
|
|
7
7
|
// Note: there is no `cursor-insiders` here. Cursor stopped shipping a separate
|
|
8
8
|
// Nightly bundle / `cursor-nightly` binary in March 2024; the pre-release
|
|
9
|
-
// channel is now an in-app toggle on the regular Cursor.app
|
|
10
|
-
//
|
|
9
|
+
// channel is now an in-app toggle on the regular Cursor.app.
|
|
10
|
+
//
|
|
11
|
+
// IntelliJ IDEA, Windsurf, and iTerm2 were intentionally dropped after 1.3.0:
|
|
12
|
+
// IntelliJ users typically launch from JetBrains Toolbox rather than a folder
|
|
13
|
+
// picker; Windsurf overlaps with Cursor/VS Code; iTerm2 overlaps with the
|
|
14
|
+
// built-in macOS Terminal entry.
|
|
11
15
|
export const OPEN_TARGET_IDS_BY_PLATFORM = {
|
|
12
|
-
mac: [
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
'cursor',
|
|
16
|
-
'windsurf',
|
|
17
|
-
'finder',
|
|
18
|
-
'terminal',
|
|
19
|
-
'iterm2',
|
|
20
|
-
'ghostty',
|
|
21
|
-
'intellijidea',
|
|
22
|
-
'zed',
|
|
23
|
-
],
|
|
24
|
-
windows: ['vscode', 'vscode-insiders', 'cursor', 'windsurf', 'finder', 'zed'],
|
|
25
|
-
linux: ['vscode', 'vscode-insiders', 'cursor', 'windsurf', 'finder', 'zed'],
|
|
16
|
+
mac: ['vscode', 'vscode-insiders', 'cursor', 'finder', 'terminal', 'ghostty', 'zed'],
|
|
17
|
+
windows: ['vscode', 'vscode-insiders', 'cursor', 'finder', 'zed'],
|
|
18
|
+
linux: ['vscode', 'vscode-insiders', 'cursor', 'finder', 'zed'],
|
|
26
19
|
other: ['vscode', 'vscode-insiders', 'finder'],
|
|
27
20
|
};
|
|
28
21
|
const ALL_TARGET_IDS = new Set(OPEN_TARGET_IDS_BY_PLATFORM.mac);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tt-a1i/hive",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.4",
|
|
4
4
|
"description": "Browser-native hive-mind for CLI coding agents — Claude Code, Codex, Gemini, and OpenCode collaborate as real PTY processes via a team protocol.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "pnpm@10.30.3",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"postinstall": "node scripts/fix-runtime-artifacts.mjs",
|
|
61
61
|
"release:dry": "pnpm check && pnpm build && pnpm test && pnpm pack:check && pnpm pack:smoke",
|
|
62
62
|
"test": "vitest run",
|
|
63
|
-
"test:windows": "vitest run tests/unit/agent-command-resolver.test.ts tests/unit/session-capture-multi-cli.test.ts tests/unit/claude-session-support.test.ts tests/unit/worker-name-generator.test.ts tests/unit/open-target-commands.test.ts tests/server/fs-pick-folder.test.ts tests/server/fs-browse.test.ts tests/server/schema-version.test.ts tests/server/runtime-rehydration.test.ts tests/server/open-workspace-route.test.ts tests/web/workspace-picker.test.tsx tests/web/confirm-dialog.test.tsx tests/web/toast.test.tsx tests/web/open-workspace-button.test.tsx --no-file-parallelism --maxWorkers=1 --testTimeout=
|
|
63
|
+
"test:windows": "vitest run tests/unit/agent-command-resolver.test.ts tests/unit/session-capture-multi-cli.test.ts tests/unit/claude-session-support.test.ts tests/unit/worker-name-generator.test.ts tests/unit/open-target-commands.test.ts tests/unit/sw-template-substitution.test.ts tests/unit/build-sw-plugin.test.ts tests/server/fs-pick-folder.test.ts tests/server/fs-browse.test.ts tests/server/schema-version.test.ts tests/server/runtime-rehydration.test.ts tests/server/open-workspace-route.test.ts tests/server/static-pwa.test.ts tests/web/workspace-picker.test.tsx tests/web/confirm-dialog.test.tsx tests/web/toast.test.tsx tests/web/open-workspace-button.test.tsx tests/web/register-service-worker.test.ts tests/web/use-shortcut-action.test.ts tests/web/update-available-toast.test.tsx tests/web/runtime-offline-page.test.tsx tests/web/use-terminal-panel-height.test.ts tests/web/use-terminal-panel-tabs.test.ts tests/web/terminal-tabs.test.tsx tests/web/terminal-bottom-panel.test.tsx --no-file-parallelism --maxWorkers=1 --testTimeout=60000 --hookTimeout=60000",
|
|
64
64
|
"test:watch": "vitest"
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{c as S,j as e,A as H,u as k,r as x,C as z,e as L,h as K,x as Q,y as V,z as G,k as J,m as U,O as X,n as Y,o as Z,D as R,a as ee}from"./index-DB5fHAMI.js";const te=[["path",{d:"M12 7v6",key:"lw1j43"}],["path",{d:"M15 10H9",key:"o6yqo3"}],["path",{d:"M17 3a2 2 0 0 1 2 2v15a1 1 0 0 1-1.496.868l-4.512-2.578a2 2 0 0 0-1.984 0l-4.512 2.578A1 1 0 0 1 5 20V5a2 2 0 0 1 2-2z",key:"oz39mx"}]],ae=S("bookmark-plus",te);const re=[["rect",{width:"12",height:"12",x:"2",y:"10",rx:"2",ry:"2",key:"6agr2n"}],["path",{d:"m17.92 14 3.5-3.5a2.24 2.24 0 0 0 0-3l-5-4.92a2.24 2.24 0 0 0-3 0L10 6",key:"1o487t"}],["path",{d:"M6 18h.01",key:"uhywen"}],["path",{d:"M10 14h.01",key:"ssrbsk"}],["path",{d:"M15 6h.01",key:"cblpky"}],["path",{d:"M18 9h.01",key:"2061c0"}]],se=S("dices",re);const ne=[["path",{d:"m21 21-4.34-4.34",key:"14j7rj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}]],le=S("search",ne),oe={orchestrator:"Or",coder:"Co",reviewer:"Re",tester:"Te",custom:"Cu"},ie={orchestrator:"var(--accent)",coder:"var(--status-blue)",reviewer:"var(--status-purple)",tester:"var(--status-orange)",custom:"var(--text-secondary)"},de={working:"var(--status-green)",idle:"var(--text-tertiary)",stopped:"var(--status-red)"},ce=({role:t,size:a=32,statusRing:n="none"})=>e.jsx(H,{size:a,color:ie[t],fontRatio:.34,mono:!0,ringColor:n==="none"?null:de[n],ringSurface:"var(--bg-2)",testId:"role-avatar",data:{role:t,"status-ring":n},children:oe[t]}),ue=[{value:"coder"},{value:"reviewer"},{value:"tester"},{value:"custom",dashed:!0}],T=t=>`role.${t}`,C=({children:t})=>e.jsx("span",{className:"text-sm font-medium text-sec",children:t}),xe=({active:t,spec:a,onSelect:n})=>{const{t:l}=k();return e.jsxs("button",{type:"button",onClick:n,"aria-pressed":t,"data-testid":`role-card-${a.value}`,className:`selectable-card${a.dashed?" selectable-card--dashed":""} flex items-center gap-3 px-3 py-2`,children:[e.jsx(ce,{role:a.value,size:20}),e.jsx("span",{className:"flex-1 text-left text-base font-medium text-pri",children:l(T(a.value))}),t?e.jsx(L,{size:14,className:"shrink-0 text-accent","aria-hidden":!0}):null]})},me=({onRoleChange:t,workerRole:a})=>{const{t:n}=k();return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx(C,{children:n("addWorker.role")}),e.jsx("div",{className:"grid grid-cols-2 gap-2",children:ue.map(l=>e.jsx(xe,{active:a===l.value,spec:l,onSelect:()=>t(l.value)},l.value))})]})},pe=({customTemplates:t,disabledReason:a,onDeleteTemplate:n,onSelect:l,selectedTemplateId:o})=>{const{t:i}=k(),[p,u]=x.useState(!1),[m,d]=x.useState(""),[h,v]=x.useState(null),y=x.useRef(null),f=x.useMemo(()=>t.find(r=>r.id===o)??null,[t,o]),g=x.useMemo(()=>{const r=m.trim().toLowerCase();return r?t.filter(s=>s.name.toLowerCase().includes(r)||s.description.toLowerCase().includes(r)):t},[t,m]);return x.useEffect(()=>{if(!p)return;const r=b=>{b.key==="Escape"&&u(!1)},s=b=>{const W=y.current;W&&!W.contains(b.target)&&u(!1)};return document.addEventListener("keydown",r),document.addEventListener("pointerdown",s),()=>{document.removeEventListener("keydown",r),document.removeEventListener("pointerdown",s)}},[p]),e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx(C,{children:i("addWorker.template")}),e.jsxs("div",{ref:y,className:"relative",children:[e.jsxs("button",{type:"button","aria-haspopup":"listbox","aria-expanded":p,"data-testid":"role-template-picker-trigger",onClick:()=>u(r=>!r),className:"flex w-full items-center justify-between gap-2 rounded border px-3 py-2 text-left text-sm transition-colors hover:bg-3",style:{borderColor:"var(--border)",background:"var(--bg-1)"},children:[e.jsx("span",{className:"min-w-0 flex-1 truncate text-pri",children:f?f.name:i("addWorker.templatePickPlaceholder")}),e.jsx(z,{size:14,className:"shrink-0 text-ter","aria-hidden":!0})]}),p?e.jsxs("div",{role:"listbox","aria-label":i("addWorker.template"),"data-testid":"role-template-picker-menu",className:"elev-2 absolute left-0 right-0 top-full z-30 mt-1 flex max-h-72 flex-col overflow-hidden rounded border",style:{background:"var(--bg-elevated)",borderColor:"var(--border-bright)"},children:[e.jsxs("div",{className:"flex items-center gap-2 border-b px-2 py-1.5",style:{borderColor:"var(--border)"},children:[e.jsx(le,{size:14,className:"text-ter","aria-hidden":!0}),e.jsx("input",{value:m,onChange:r=>d(r.currentTarget.value),placeholder:i("addWorker.templateSearchPlaceholder"),"data-testid":"role-template-search-input",className:"w-full bg-transparent text-sm text-pri outline-none placeholder:text-ter",spellCheck:!1})]}),e.jsx("div",{className:"flex-1 overflow-y-auto py-1",children:t.length===0?e.jsx("div",{"data-testid":"role-template-empty-state",className:"px-3 py-3 text-center text-sm text-ter",children:i("addWorker.templateEmpty")}):g.length===0?e.jsx("div",{className:"px-3 py-3 text-center text-sm text-ter",children:i("addWorker.templateNoMatch")}):g.map(r=>{const s=r.id===o;return e.jsxs("div",{className:"relative",children:[e.jsxs("button",{type:"button",role:"option","aria-selected":s,"data-testid":`role-template-option-${r.id}`,onClick:()=>{l(r.id),u(!1),d("")},className:"flex w-full items-center gap-2 px-3 py-1.5 pr-9 text-left text-sm text-pri hover:bg-3",style:s?{background:"var(--bg-3)"}:void 0,children:[e.jsx("span",{className:"min-w-0 flex-1 truncate",children:r.name}),s?e.jsx(L,{size:14,className:"shrink-0 text-accent","aria-hidden":!0}):null]}),e.jsx("button",{type:"button","aria-label":i("addWorker.templateDeleteAria",{name:r.name}),"data-testid":`role-template-delete-${r.id}`,disabled:!!a,title:a??void 0,onClick:b=>{b.preventDefault(),b.stopPropagation(),!a&&v(r)},className:"absolute right-1 top-1/2 flex h-6 w-6 -translate-y-1/2 items-center justify-center rounded text-ter transition-colors hover:bg-3 hover:text-pri",children:e.jsx(K,{size:14,"aria-hidden":!0})})]},r.id)})}),o!==null?e.jsx("button",{type:"button","data-testid":"role-template-clear",onClick:()=>{l(null),u(!1),d("")},className:"border-t px-3 py-1.5 text-left text-sm text-ter transition-colors hover:bg-3 hover:text-pri",style:{borderColor:"var(--border)"},children:i("addWorker.templateClear")}):null]}):null]}),e.jsx(Q,{open:h!==null,onOpenChange:r=>{r||v(null)},title:i("addWorker.templateDeleteTitle"),description:h?i("addWorker.templateDeleteConfirm",{name:h.name}):"",confirmLabel:i("addWorker.templateDeleteConfirmLabel"),confirmKind:"danger",onConfirm:()=>{if(!h||a)return;const r=h.id;v(null),n(r)}})]})},he=({canSaveAsTemplate:t,modified:a,onChange:n,onReset:l,onSaveAsTemplate:o,roleDescription:i,templateBusy:p,workerRole:u,writeDisabledReason:m})=>{const{t:d}=k(),[h,v]=x.useState(!1),[y,f]=x.useState(!1),[g,r]=x.useState("");return x.useEffect(()=>{(u==="custom"||a)&&v(!0)},[a,u]),x.useEffect(()=>{t||(f(!1),r(""))},[t]),e.jsxs("details",{open:h,onToggle:s=>v(s.currentTarget.open),className:"group flex flex-col gap-2",children:[e.jsxs("summary",{className:"flex cursor-pointer select-none items-center justify-between gap-2 list-none",children:[e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx(z,{size:12,"aria-hidden":!0,className:"-rotate-90 text-ter transition-transform duration-150 group-open:rotate-0"}),e.jsx(C,{children:d("addWorker.roleInstructions")}),a?e.jsxs("span",{className:"text-sm text-ter",children:["· ",d("addWorker.modifiedFrom",{role:d(T(u))})]}):null]}),e.jsxs("div",{className:"flex items-center gap-1",children:[t&&!y?e.jsxs("button",{type:"button","data-testid":"role-template-save",disabled:!!m,title:m??void 0,onClick:s=>{s.preventDefault(),s.stopPropagation(),f(!0)},className:"flex items-center gap-1 rounded px-2 py-0.5 text-xs font-medium transition-colors hover:opacity-80 disabled:cursor-not-allowed disabled:opacity-50",style:{color:"var(--accent)",background:"color-mix(in oklab, var(--accent) 14%, transparent)"},children:[e.jsx(ae,{size:12,"aria-hidden":!0}),d("addWorker.saveAsTemplate")]}):null,a?e.jsxs("button",{type:"button",className:"flex items-center gap-1 rounded px-1.5 py-0.5 text-xs text-ter transition-colors hover:bg-3 hover:text-sec",onClick:s=>{s.preventDefault(),s.stopPropagation(),l()},children:[e.jsx(V,{size:12,"aria-hidden":!0}),d("addWorker.reset")]}):null]})]}),e.jsx("textarea",{"aria-label":"Role instructions",id:"add-worker-role-instructions",value:i,rows:5,onChange:s=>n(s.currentTarget.value),placeholder:u==="custom"?d("addWorker.customPlaceholder"):void 0,title:d("addWorker.roleInstructionsTitle"),className:"input mono resize-y text-sm",style:{minHeight:150},"data-testid":"role-instructions-textarea"}),t&&y?e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{autoFocus:!0,value:g,onChange:s=>r(s.currentTarget.value),placeholder:d("addWorker.templateNamePlaceholder"),"data-testid":"role-template-save-name",className:"input flex-1 text-sm"}),e.jsx("button",{type:"button",disabled:p||!g.trim()||!!m,title:m??void 0,"data-testid":"role-template-save-confirm",onClick:async()=>{if(m)return;const s=g.trim();if(s)try{await o(s),f(!1),r("")}catch{}},className:"icon-btn icon-btn--primary text-xs",children:d("addWorker.templateSaveConfirm")}),e.jsx("button",{type:"button","data-testid":"role-template-save-cancel",onClick:()=>{f(!1),r("")},className:"icon-btn text-xs",children:d("common.cancel")})]}):null]})},B=({active:t,command:a,displayName:n,notFound:l=!1,testId:o,onSelect:i})=>{const{t:p}=k();return e.jsxs("button",{type:"button",onClick:i,"aria-pressed":t,"data-testid":o,className:"selectable-card flex items-center justify-between gap-2 px-3 py-2",children:[e.jsxs("span",{className:"flex min-w-0 flex-col items-start gap-0.5",children:[e.jsx("span",{className:"truncate text-base font-medium text-pri",children:n}),e.jsxs("span",{className:"mono truncate text-xs text-ter",children:[a,l?` · ${p("addWorker.agentNotFound")}`:""]})]}),t?e.jsx(L,{size:14,className:"shrink-0 text-accent","aria-hidden":!0}):null]})},fe=({active:t,preset:a,onSelect:n})=>e.jsx(B,{active:t,command:a.command,displayName:a.displayName,notFound:a.available===!1,testId:`agent-radio-${a.id}`,onSelect:n}),ve=({commandPresetId:t,commandPresets:a,onPresetChange:n})=>e.jsx(ge,{commandPresetId:t,commandPresets:a,onPresetChange:n}),ge=({commandPresetId:t,commandPresets:a,onPresetChange:n})=>{const{t:l}=k();return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx(C,{children:l("addWorker.agentCli")}),a.length===0?e.jsx("div",{className:"text-sm text-ter",children:l("addWorker.loadingPresets")}):e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[a.map(o=>e.jsx(fe,{active:t===o.id,preset:o,onSelect:()=>n(o.id)},o.id)),e.jsx(B,{active:t==="",command:l("addWorker.genericCommand"),displayName:l("addWorker.genericAgent"),testId:"agent-radio-generic",onSelect:()=>n("")})]})]})},be=({onChange:t,value:a})=>{const{t:n}=k(),l=a.trim();return e.jsxs("details",{className:"group flex flex-col gap-2",children:[e.jsx("summary",{className:"flex cursor-pointer select-none items-center justify-between gap-2 list-none",children:e.jsxs("span",{className:"flex min-w-0 items-center gap-1.5",children:[e.jsx(z,{size:12,"aria-hidden":!0,className:"-rotate-90 shrink-0 text-ter transition-transform duration-150 group-open:rotate-0"}),e.jsx(C,{children:n("addWorker.startupCommand")}),l?e.jsxs("span",{className:"truncate text-sm text-ter",children:["· ",n("addWorker.startupOverrides")]}):null]})}),e.jsxs("div",{className:"flex flex-col gap-2 rounded border bg-2 p-3",style:{borderColor:"var(--border)"},children:[e.jsx("input",{"aria-label":"Startup command",value:a,onChange:o=>t(o.currentTarget.value),placeholder:"qwen --model qwen3-coder",className:"input mono text-sm",spellCheck:!1}),e.jsx("p",{className:"text-sm leading-5 text-ter",children:n("addWorker.startupHelp",{example:"claude --resume <session-id>"})})]})]})},ke=({commandPresets:t,commandPresetId:a,creating:n=!1,customTemplates:l,onClose:o,onDeleteTemplate:i,onNameChange:p,onPresetChange:u,onRandomName:m,onRoleDescriptionChange:d,onRoleDescriptionReset:h,onRoleChange:v,onSaveAsTemplate:y,onStartupCommandChange:f,onSubmit:g,onTemplateChange:r,roleDescription:s,roleDescriptionDefault:b,selectedTemplateId:W,startupCommand:P,templateBusy:$,workerName:A,workerRole:w,writeDisabledReason:N})=>{const{t:c}=k(),F=G(),_=j=>{j||o()},q=s!==b,E=t.find(j=>j.id===a),M=P.trim(),D=()=>N||(A.trim()?!a&&!M?c("addWorker.pickCliOrStartup"):E?.available===!1&&!M?c("addWorker.unavailable",{name:E.displayName}):s.trim()?null:c("addWorker.emptyInstructions"):c("addWorker.enterName")),I=j=>{const O=D();if(O){j.preventDefault(),F.show({kind:"warning",message:O});return}g(j)};return e.jsx(J,{open:!0,onOpenChange:_,children:e.jsxs(U,{children:[e.jsx(X,{"data-testid":"add-worker-overlay",className:"app-overlay fixed inset-0 z-40"}),e.jsx("div",{className:"pointer-events-none fixed inset-0 z-50 grid place-items-center p-4",children:e.jsx(Y,{"data-testid":"add-worker-content",className:"dialog-scale-pop elev-2 pointer-events-auto flex max-h-[calc(100vh-32px)] w-[560px] max-w-full flex-col rounded-lg border",style:{background:"var(--bg-elevated)",borderColor:"var(--border-bright)"},children:e.jsxs("form",{onSubmit:I,"aria-label":c("addWorker.title"),className:"flex flex-col",children:[e.jsxs("div",{className:"flex shrink-0 flex-col gap-0.5 border-b px-5 py-4",style:{borderColor:"var(--border)"},children:[e.jsx(Z,{className:"text-lg font-semibold text-pri",children:c("addWorker.title")}),e.jsx(R,{className:"text-sm text-ter",children:c("addWorker.description",{command:"team send"})})]}),e.jsxs("div",{className:"flex flex-col gap-4 overflow-y-auto px-5 py-4",children:[e.jsxs("label",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-baseline justify-between gap-2",children:[e.jsx(C,{children:c("addWorker.name")}),e.jsx(ee,{label:c("addWorker.randomTooltip"),children:e.jsxs("button",{type:"button","aria-label":c("addWorker.randomAria"),className:"flex cursor-pointer items-center gap-1 rounded px-1.5 py-0.5 text-xs text-ter transition-colors hover:bg-3 hover:text-sec",onClick:m,"data-testid":"random-worker-name",children:[e.jsx(se,{size:12,"aria-hidden":!0}),c("addWorker.random")]})})]}),e.jsx("input",{autoFocus:!0,value:A,onChange:j=>p(j.target.value),placeholder:c("addWorker.namePlaceholder"),className:"input"})]}),e.jsx(me,{workerRole:w,onRoleChange:v}),w==="custom"?e.jsx(pe,{customTemplates:l,disabledReason:N,onDeleteTemplate:i,onSelect:r,selectedTemplateId:W}):null,e.jsx(he,{canSaveAsTemplate:w==="custom"&&!W&&s.trim().length>0,modified:q,onChange:d,onReset:h,onSaveAsTemplate:y,roleDescription:s,templateBusy:$,workerRole:w,writeDisabledReason:N}),e.jsx(ve,{commandPresetId:a,commandPresets:t,onPresetChange:u}),e.jsx(be,{value:P,onChange:f})]}),e.jsxs("div",{className:"flex shrink-0 items-center justify-end gap-2 border-t px-5 py-3",style:{borderColor:"var(--border)",background:"var(--bg-2)"},children:[e.jsx("button",{type:"button",onClick:o,className:"icon-btn","data-testid":"add-worker-cancel",children:c("addWorker.cancel")}),e.jsx("button",{type:"submit",disabled:n||!!N,title:N??void 0,className:"icon-btn icon-btn--primary","data-testid":"add-worker-submit",children:c(n?"addWorker.creating":"addWorker.create")})]})]})})})]})})};export{ke as AddWorkerDialog};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{c as V,u as D,r as c,j as e,i as se,C as A,e as Z,k as T,m as I,O as q,n as U,o as W,D as K,q as ae,s as re,t as ne,X as ce,v as le,w as oe,T as ie}from"./index-DB5fHAMI.js";import{C as L}from"./chevron-right-BvbSCniy.js";const de=[["path",{d:"m5 12 7-7 7 7",key:"hav0vg"}],["path",{d:"M12 19V5",key:"x0mq9r"}]],pe=V("arrow-up",de);const xe=[["path",{d:"M10.7 20H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v4.1",key:"1bw5m7"}],["path",{d:"m21 21-1.9-1.9",key:"1g2n9r"}],["circle",{cx:"17",cy:"17",r:"3",key:"18b49y"}]],ue=V("folder-search",xe);const me=[["path",{d:"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z",key:"1kt360"}]],X=V("folder",me);const he=[["path",{d:"M15 6a9 9 0 0 0-9 9V3",key:"1cii5b"}],["circle",{cx:"18",cy:"6",r:"3",key:"1h7g24"}],["circle",{cx:"6",cy:"18",r:"3",key:"fqmcym"}]],Q=V("git-branch",he),ee=({error:t,onChange:o,presets:p,value:a})=>{const{t:i}=D(),[d,r]=c.useState(!1),s=c.useRef(null),u=p.find(l=>l.id===a),n=a==="",k=u?[u.command,...u.args].join(" ").trim():i(n?"workspace.preset.genericPreview":"workspace.preset.loading"),g=u?.displayName??(n?i("workspace.preset.generic"):"Claude Code (CC)"),j=p.length===0&&!n;return c.useEffect(()=>{if(!d)return;const l=f=>{s.current?.contains(f.target)||r(!1)},m=f=>{f.key==="Escape"&&r(!1)};return document.addEventListener("mousedown",l),document.addEventListener("keydown",m),()=>{document.removeEventListener("mousedown",l),document.removeEventListener("keydown",m)}},[d]),e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("span",{className:"text-xs font-medium uppercase tracking-wider text-ter",children:i("workspace.preset.label")}),e.jsxs("div",{ref:s,className:"cli-select group relative",children:[e.jsx(se,{size:14,"aria-hidden":!0,className:"cli-select__leading"}),e.jsx("button",{type:"button","aria-haspopup":"listbox","aria-expanded":d,"aria-disabled":j||void 0,className:"cli-select__field cli-select__field--button text-left","data-testid":"workspace-command-preset","data-value":a,disabled:j,onClick:()=>r(l=>!l),children:g}),e.jsx(A,{size:14,"aria-hidden":!0,className:"cli-select__trailing"}),d&&p.length>0?e.jsxs("div",{role:"listbox","aria-label":i("workspace.preset.optionsAria"),className:"cli-select__menu","data-testid":"workspace-command-preset-menu",children:[p.map(l=>{const m=l.id===a,f=l.available===!1;return e.jsxs("button",{type:"button",role:"option","aria-selected":m,"data-testid":`workspace-command-preset-option-${l.id}`,className:"cli-select__option",onClick:()=>{o(l.id),r(!1)},children:[e.jsx(Z,{size:12,"aria-hidden":!0,className:"cli-select__check",style:{opacity:m?1:0}}),e.jsxs("span",{children:[l.displayName,f?i("workspace.preset.notFoundSuffix"):""]})]},l.id)}),e.jsxs("button",{type:"button",role:"option","aria-selected":n,"data-testid":"workspace-command-preset-option-generic",className:"cli-select__option",onClick:()=>{o(""),r(!1)},children:[e.jsx(Z,{size:12,"aria-hidden":!0,className:"cli-select__check",style:{opacity:n?1:0}}),e.jsx("span",{children:i("workspace.preset.generic")})]})]}):null]}),e.jsxs("div",{className:"mono flex items-center gap-1.5 truncate text-xs text-ter",title:k,children:[e.jsx("span",{className:"text-sec",children:"$"}),e.jsx("span",{className:"truncate",children:k})]}),t?e.jsx("span",{className:"text-xs",style:{color:"var(--status-red)"},children:t}):null]})},G=t=>t.split(/[\\/]/).filter(Boolean).pop()??"",M=({children:t})=>e.jsx("span",{className:"text-xs font-medium uppercase tracking-wider text-ter",children:t}),fe=({probe:t,pasteFallbackDefault:o=!1,commandPresetError:p,commandPresetId:a,commandPresets:i,onCancel:d,onCommandPresetChange:r,onCreate:s,onOpenServerBrowse:u})=>{const{t:n}=D(),k=t?.path??"",g=t?.suggested_name??G(k),[j,l]=c.useState(g),[m,f]=c.useState(""),[C,P]=c.useState(o),[w,E]=c.useState(!1),[_,h]=c.useState("");c.useEffect(()=>{l(t?.suggested_name??G(t?.path??""))},[t?.path,t?.suggested_name]);const y=m.trim(),x=C&&y.length>0?y:t?.path??"",N=_.trim(),S=i.find(v=>v.id===a),R=i.length===0&&!p,B=!a&&N.length===0,F=S?.available===!1&&N.length===0,O=B?n("workspace.preset.genericRequiresStartup"):F?n("workspace.preset.notInstalled",{name:S.displayName}):null,$=j.trim().length>0&&x.length>0&&!R&&!B&&!F,H=()=>{$&&s({commandPresetId:a||null,name:j.trim(),path:x,...N?{startupCommand:N}:{}})};return e.jsx(T,{open:!0,onOpenChange:v=>!v&&d(),children:e.jsxs(I,{children:[e.jsx(q,{"data-testid":"confirm-workspace-overlay",className:"app-overlay fixed inset-0 z-40"}),e.jsx("div",{className:"pointer-events-none fixed inset-0 z-50 grid place-items-center p-4",children:e.jsxs(U,{"data-testid":"confirm-workspace-dialog",className:"dialog-scale-pop elev-2 pointer-events-auto flex w-[480px] max-w-full flex-col rounded-lg border",style:{background:"var(--bg-elevated)",borderColor:"var(--border-bright)"},children:[e.jsxs("div",{className:"flex items-center gap-3 border-b px-5 py-4",style:{borderColor:"var(--border)"},children:[e.jsx("div",{className:"flex h-9 w-9 shrink-0 items-center justify-center rounded",style:{background:"color-mix(in oklab, var(--accent) 12%, transparent)",color:"var(--accent)"},children:e.jsx(X,{size:18,"aria-hidden":!0})}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx(W,{className:"text-lg font-semibold text-pri",children:n("workspace.confirm.title")}),e.jsx(K,{className:"text-xs text-ter",children:n("workspace.confirm.description")})]})]}),e.jsxs("div",{className:"flex flex-col gap-4 px-5 py-4",children:[e.jsxs("label",{className:"flex flex-col gap-2",children:[e.jsx(M,{children:n("workspace.field.path")}),e.jsx("input",{readOnly:!0,value:t?.path??"",placeholder:n("workspace.field.pathEmptyPlaceholder"),className:"input input--readonly mono","data-testid":"confirm-workspace-path"})]}),t?.is_git_repository?e.jsxs("div",{className:"flex items-center gap-2 text-xs","data-testid":"confirm-workspace-git-badge",children:[e.jsxs("span",{className:"inline-flex items-center gap-1.5 rounded px-2 py-0.5 font-medium",style:{background:"color-mix(in oklab, var(--status-blue) 12%, transparent)",color:"var(--status-blue)",border:"1px solid color-mix(in oklab, var(--status-blue) 30%, transparent)"},children:[e.jsx(Q,{size:12,"aria-hidden":!0}),t.current_branch??n("workspace.git.detached")]}),e.jsx("span",{className:"text-ter",children:n("workspace.git.detected")})]}):t?.ok?e.jsx("span",{className:"text-xs text-ter",children:n("workspace.git.none")}):null,e.jsxs("label",{className:"flex flex-col gap-2",children:[e.jsx(M,{children:n("workspace.field.name")}),e.jsx("input",{value:j,onChange:v=>l(v.target.value),placeholder:G(t?.path??"")||n("workspace.field.nameDefaultPlaceholder"),className:"input","data-testid":"confirm-workspace-name"})]}),e.jsx(ee,{error:p??O,onChange:r,presets:i,value:a}),e.jsxs("button",{type:"button",onClick:()=>E(v=>!v),className:"flex items-center gap-1.5 self-start text-xs uppercase tracking-wider text-ter hover:text-sec","data-testid":"confirm-workspace-startup-toggle",children:[w?e.jsx(A,{size:12,"aria-hidden":!0}):e.jsx(L,{size:12,"aria-hidden":!0}),n("workspace.advanced.startup")]}),w?e.jsxs("label",{className:"flex flex-col gap-2",children:[e.jsx(M,{children:n("workspace.field.startup")}),e.jsx("input",{type:"text",value:_,onChange:v=>h(v.target.value),placeholder:n("workspace.field.startupPlaceholder"),className:"input mono","data-testid":"confirm-workspace-startup-command"}),e.jsx("span",{className:"text-xs text-ter",children:n("workspace.startup.hint")})]}):null,e.jsxs("button",{type:"button",onClick:()=>P(v=>!v),className:"flex items-center gap-1.5 self-start text-xs uppercase tracking-wider text-ter hover:text-sec","data-testid":"confirm-workspace-paste-toggle",children:[C?e.jsx(A,{size:12,"aria-hidden":!0}):e.jsx(L,{size:12,"aria-hidden":!0}),n("workspace.advanced.pastePath")]}),C?e.jsxs("label",{className:"flex flex-col gap-2",children:[e.jsx(M,{children:n("workspace.field.absolutePath")}),e.jsx("input",{type:"text",value:m,onChange:v=>f(v.target.value),placeholder:n("workspace.field.absolutePathPlaceholder"),className:"input mono","data-testid":"confirm-workspace-paste-path"})]}):null,e.jsxs("button",{type:"button",onClick:u,className:"flex items-center gap-1.5 self-start text-xs uppercase tracking-wider text-ter hover:text-sec","data-testid":"confirm-workspace-browse-toggle",children:[e.jsx(L,{size:12,"aria-hidden":!0}),n("workspace.advanced.browse")]})]}),e.jsxs("div",{className:"flex items-center justify-end gap-2 border-t px-5 py-3",style:{borderColor:"var(--border)"},children:[e.jsx("button",{type:"button",onClick:d,className:"icon-btn",children:n("common.cancel")}),e.jsx("button",{type:"button",onClick:H,disabled:!$,"data-testid":"confirm-workspace-create",className:"icon-btn icon-btn--primary",children:n("workspace.confirm.create")})]})]})})]})})},be=({entries:t,error:o,loading:p,onNavigate:a,onSelect:i,selected:d})=>{const{t:r}=D();return e.jsx("div",{className:"scroll-y min-h-[200px] flex-1 border-t border-b",style:{borderColor:"var(--border)"},"data-testid":"fs-entry-list",children:p?e.jsx("p",{className:"p-4 text-center text-xs text-ter",children:r("common.loading")}):o?e.jsx("p",{className:"p-4 text-center text-xs",style:{color:"var(--status-red)"},"data-testid":"fs-browse-error",children:o}):t.length===0?e.jsx("p",{className:"p-4 text-center text-xs text-ter",children:r("workspace.browse.empty")}):e.jsx("ul",{children:t.map(s=>{const u=d===s.path;return e.jsxs("li",{className:"flex items-center gap-0",children:[e.jsxs("button",{type:"button","data-testid":`fs-entry-${s.name}`,onClick:()=>i(s.path),onDoubleClick:()=>a(s.path),className:"flex flex-1 items-center gap-2 px-3 py-2 text-left text-xs hover:bg-3",style:u?{background:"var(--bg-3)",color:"var(--text-primary)"}:{color:"var(--text-primary)"},children:[e.jsx("span",{"aria-hidden":!0,className:"inline-flex items-center text-sec",children:s.is_git_repository?e.jsx(Q,{size:14}):e.jsx(X,{size:14})}),e.jsx("span",{className:"mono flex-1 truncate",children:s.name}),s.is_git_repository?e.jsx("span",{className:"text-xs uppercase tracking-wider",style:{color:"var(--accent)"},children:r("workspace.browse.gitBadge")}):null]}),e.jsx("button",{type:"button","data-testid":`fs-entry-open-${s.name}`,onClick:()=>a(s.path),"aria-label":r("workspace.browse.openAria",{name:s.name}),className:"px-3 py-2 text-xs text-ter hover:text-pri",children:"→"})]},s.path)})})})},ge=({probe:t,suggestedName:o,onSuggestedNameChange:p})=>{const{t:a}=D(),i=!!t&&t.ok&&t.is_dir;return e.jsxs("div",{className:"flex flex-col gap-2 rounded border p-3 text-xs",style:{background:"var(--bg-1)",borderColor:"var(--border)"},"data-testid":"fs-selection-preview",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-ter uppercase tracking-wider text-xs",children:a("workspace.browse.selected")}),t?.is_git_repository?e.jsx("span",{className:"role-badge role-badge--coder","data-testid":"fs-preview-git-badge",children:a("workspace.git.short",{branch:t.current_branch??a("workspace.git.detached")})}):i?e.jsx("span",{className:"text-ter text-xs",children:a("workspace.git.noneShort")}):null]}),e.jsx("span",{className:"mono truncate text-pri","data-testid":"fs-preview-path",children:t?.path??"—"}),e.jsxs("label",{className:"mt-1 flex flex-col gap-1 text-ter",children:[e.jsx("span",{className:"text-xs uppercase tracking-wider",children:a("workspace.field.name")}),e.jsx("input",{type:"text",value:o,onChange:d=>p(d.target.value),disabled:!i,className:"mono rounded border px-2 py-1 text-sm text-pri disabled:opacity-50",style:{background:"var(--bg-0)",borderColor:"var(--border)"},"data-testid":"fs-preview-name-input"})]})]})},ke=t=>{const p=t.replace(/[\\/]+$/,"").split(/[\\/]/).filter(Boolean),a=p[p.length-1];return a?`~ (${a})`:t},ve=(t,o)=>{if(!o||!t)return[];const p=[{label:ke(o),path:o}];if(t===o)return p;const a=o.replace(/[\\/]+$/,""),i=t.startsWith(a)?t.slice(a.length).replace(/^[\\/]+/,""):"";if(!i)return p;const d=i.split(/[\\/]/).filter(Boolean);let r=a;for(const s of d)r=`${r}/${s}`,p.push({label:s,path:r});return p},J={current_path:"",entries:[],error:null,ok:!1,parent_path:null,root_path:""},je=t=>{const[o,p]=c.useState(J),[a,i]=c.useState(!1),[d,r]=c.useState(null),[s,u]=c.useState(null),n=c.useRef(0),k=c.useRef(0),g=c.useCallback(async l=>{const m=++n.current;i(!0);try{const f=await ae(l);if(n.current!==m)return;p(f),f.ok&&r(f.current_path)}catch{}finally{n.current===m&&i(!1)}},[]);c.useEffect(()=>{if(!t){n.current++,k.current++,p(J),r(null),u(null);return}g("")},[t,g]),c.useEffect(()=>{if(!d){u(null);return}const l=++k.current;re(d).then(m=>{k.current===l&&u(m)}).catch(m=>{console.debug("[hive] discarded:fsBrowser.probe (likely stale token)",m)})},[d]);const j=c.useCallback(l=>{r(l)},[]);return{browse:o,loading:a,navigate:g,probe:s,selectEntry:j,selected:d}},we=({commandPresetError:t,commandPresetId:o,commandPresets:p,onClose:a,onCommandPresetChange:i,onCreate:d,open:r})=>{const{t:s}=D(),{browse:u,loading:n,navigate:k,probe:g,selectEntry:j,selected:l}=je(r),[m,f]=c.useState(""),[C,P]=c.useState(!1),[w,E]=c.useState(""),[_,h]=c.useState(!1),[y,x]=c.useState("");if(c.useEffect(()=>{r||(f(""),P(!1),E(""),h(!1),x(""))},[r]),c.useEffect(()=>{g?.suggested_name&&f(g.suggested_name)},[g?.suggested_name]),!r)return null;const N=ve(u.current_path,u.root_path),S=p.find(b=>b.id===o),R=y.trim(),B=p.length===0&&!t,F=!o&&R.length===0,O=S?.available===!1&&R.length===0,$=F?s("workspace.preset.genericRequiresStartup"):O?s("workspace.preset.notInstalled",{name:S.displayName}):null,H=m.trim().length>0&&(g?.is_dir===!0||C&&w.trim().length>0)&&!B&&!F&&!O,v=()=>{const b=C&&w.trim().length>0?w.trim():g?.path??"";b&&d({commandPresetId:o||null,name:m.trim(),path:b,...R?{startupCommand:R}:{}})};return e.jsx(T,{open:!0,onOpenChange:b=>!b&&a(),children:e.jsxs(I,{children:[e.jsx(q,{"data-testid":"server-browse-overlay",className:"app-overlay fixed inset-0 z-40"}),e.jsx("div",{className:"pointer-events-none fixed inset-0 z-50 grid place-items-center p-4",children:e.jsxs(U,{"data-testid":"add-workspace-dialog",className:"dialog-scale-pop elev-2 pointer-events-auto flex w-[760px] max-w-[calc(100vw-32px)] flex-col rounded-lg border",style:{height:"min(600px, calc(100vh - 64px))",background:"var(--bg-elevated)",borderColor:"var(--border-bright)"},children:[e.jsxs("div",{className:"flex shrink-0 items-center gap-3 border-b px-5 py-4",style:{borderColor:"var(--border)"},children:[e.jsx("div",{className:"flex h-9 w-9 shrink-0 items-center justify-center rounded",style:{background:"color-mix(in oklab, var(--accent) 12%, transparent)",color:"var(--accent)"},children:e.jsx(X,{size:18,"aria-hidden":!0})}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx(W,{className:"text-lg font-semibold text-pri",children:s("workspace.browse.title")}),e.jsx(K,{className:"mono truncate text-xs text-ter","data-testid":"fs-root-path",children:u.root_path?s("workspace.browse.root",{path:u.root_path}):s("workspace.browse.rootLoading")})]}),e.jsx(ne,{asChild:!0,children:e.jsx("button",{type:"button","aria-label":s("common.closeDialog"),className:"flex h-7 w-7 items-center justify-center rounded text-sec hover:bg-3 hover:text-pri",children:e.jsx(ce,{size:14,"aria-hidden":!0})})})]}),e.jsxs("nav",{className:"flex shrink-0 items-center gap-1 border-b px-4 py-2 text-xs",style:{borderColor:"var(--border)"},"aria-label":s("workspace.browse.breadcrumb"),"data-testid":"fs-breadcrumb",children:[e.jsxs("button",{type:"button",onClick:()=>u.parent_path?k(u.parent_path):null,disabled:!u.parent_path,"aria-label":s("workspace.browse.parentAria"),className:"flex items-center gap-1 rounded px-2 py-0.5 text-sec hover:bg-3 hover:text-pri disabled:opacity-40",children:[e.jsx(pe,{size:12,"aria-hidden":!0})," ",s("workspace.browse.up")]}),e.jsx("div",{className:"mx-2 h-4 w-px",style:{background:"var(--border)"}}),N.map((b,Y)=>{const te=Y===N.length-1;return e.jsxs("span",{className:"flex items-center gap-0.5",children:[Y>0?e.jsx("span",{className:"text-ter",children:"/"}):null,te?e.jsx("span",{className:"px-1 py-0.5 font-medium text-pri",children:b.label}):e.jsx("button",{type:"button",onClick:()=>k(b.path),className:"rounded px-1 py-0.5 text-sec hover:bg-3 hover:text-pri",children:b.label})]},b.path)})]}),e.jsxs("div",{className:"flex min-h-0 flex-1",children:[e.jsx("div",{className:"flex min-h-0 flex-1 flex-col",children:e.jsx(be,{entries:u.entries,error:u.ok?null:u.error,loading:n,onNavigate:k,onSelect:j,selected:l})}),e.jsxs("div",{className:"flex w-[280px] shrink-0 flex-col gap-3 border-l p-4",style:{borderColor:"var(--border)"},children:[e.jsx(ge,{onSuggestedNameChange:f,probe:g,suggestedName:m}),e.jsx(ee,{error:t??$,onChange:i,presets:p,value:o}),e.jsxs("button",{type:"button",onClick:()=>h(b=>!b),className:"flex items-center gap-1.5 text-left text-xs uppercase tracking-wider text-ter hover:text-sec",children:[_?e.jsx(A,{size:12,"aria-hidden":!0}):e.jsx(L,{size:12,"aria-hidden":!0}),s("workspace.advanced.startup")]}),_?e.jsxs("label",{className:"flex flex-col gap-2 text-xs uppercase tracking-wider text-ter",children:[s("workspace.field.startup"),e.jsx("input",{type:"text",value:y,onChange:b=>x(b.target.value),placeholder:s("workspace.field.startupPlaceholder"),className:"input mono","data-testid":"fs-startup-command"}),e.jsx("span",{className:"text-xs normal-case tracking-normal text-ter",children:s("workspace.startup.hintShort")})]}):null,e.jsxs("button",{type:"button",onClick:()=>P(b=>!b),className:"flex items-center gap-1.5 text-left text-xs uppercase tracking-wider text-ter hover:text-sec",children:[C?e.jsx(A,{size:12,"aria-hidden":!0}):e.jsx(L,{size:12,"aria-hidden":!0}),s("workspace.advanced.pastePath")]}),C?e.jsxs("label",{className:"flex flex-col gap-2 text-xs uppercase tracking-wider text-ter",children:[s("workspace.field.absolutePath"),e.jsx("input",{type:"text",value:w,onChange:b=>E(b.target.value),placeholder:s("workspace.field.absolutePathPlaceholder"),className:"input mono","data-testid":"fs-manual-path"})]}):null]})]}),e.jsxs("div",{className:"flex shrink-0 items-center justify-end gap-2 border-t px-5 py-3",style:{borderColor:"var(--border)"},children:[e.jsx("button",{type:"button",onClick:a,className:"icon-btn",children:s("common.cancel")}),e.jsx("button",{type:"button",onClick:v,disabled:!H,"data-testid":"add-workspace-create",className:"icon-btn icon-btn--primary",children:s("workspace.confirm.create")})]})]})})]})})},z="claude",ye=t=>t.some(o=>o.id===z&&o.available)?z:t.find(o=>o.available)?.id??t[0]?.id??z,_e=({trigger:t,onClose:o,onCreate:p})=>{const{t:a}=D(),i=c.useRef(a);c.useEffect(()=>{i.current=a},[a]);const[d,r]=c.useState({kind:"idle"}),[s,u]=c.useState([]),[n,k]=c.useState(z),[g,j]=c.useState(null),l=c.useRef({error:null,id:z,presets:[]}),m=c.useRef(o);c.useEffect(()=>{m.current=o},[o]),c.useEffect(()=>{if(t===0)return;let h=!1;j(null);const y=le().then(x=>{if(h)return;const N=x.some(S=>S.id===l.current.id&&S.available)?l.current.id:ye(x);l.current={error:null,id:N,presets:x},u(x),k(N)}).catch(()=>{if(h)return;const x=i.current("workspace.preset.loadFailed");l.current={error:x,id:z,presets:[]},u([]),k(z),j(x)});return r({kind:"picking"}),oe().then(async x=>{if(await y,!h){if(x.canceled){if(x.error){r({kind:"error",message:x.error});return}r({kind:"idle"}),m.current();return}if(!x.supported){r({kind:"confirm",probe:null,pasteDefault:!0});return}if(!x.probe?.ok||!x.probe.is_dir){r({kind:"error",message:x.error??i.current("workspace.error.outsideSandbox")});return}r({kind:"confirm",probe:x.probe,pasteDefault:!1})}}).catch(x=>{if(h)return;const N=x instanceof Error?x.message:i.current("workspace.error.pickerFailed");r({kind:"error",message:N})}),()=>{h=!0}},[t]);const f=()=>{r({kind:"idle"}),o()},C=h=>{Promise.resolve(p(h)).then(()=>r({kind:"idle"})).catch(y=>{const x=y instanceof Error?y.message:a("workspace.error.createFailed");r({kind:"error",title:a("workspace.error.createTitle"),message:x})})},P=h=>{l.current={...l.current,id:h},k(h)},w=s.length>0||g?s:l.current.presets,E=n===""?"":w.length>0&&!w.some(h=>h.id===n&&h.available)?l.current.id:n,_=g??l.current.error;if(d.kind==="idle")return null;if(d.kind==="picking"){const h=()=>r({kind:"idle"});return e.jsx(T,{open:!0,onOpenChange:y=>!y&&h(),children:e.jsxs(I,{children:[e.jsx(q,{className:"app-overlay fixed inset-0 z-40"}),e.jsxs(U,{"data-testid":"add-workspace-picking","aria-describedby":void 0,className:"fixed inset-0 z-50 flex items-center justify-center p-4",children:[e.jsx(W,{className:"sr-only",children:a("workspace.picking.title")}),e.jsxs("div",{"data-testid":"add-workspace-picking-panel",className:"dialog-scale-pop elev-2 flex items-center gap-3 rounded-lg border px-5 py-4",style:{background:"var(--bg-elevated)",borderColor:"var(--border-bright)"},children:[e.jsx(ue,{size:18,"aria-hidden":!0,className:"animate-pulse",style:{color:"var(--accent)"}}),e.jsx("span",{className:"text-sm text-pri",children:a("workspace.picking.message")})]})]})]})})}return d.kind==="error"?e.jsx(T,{open:!0,onOpenChange:h=>!h&&f(),children:e.jsxs(I,{children:[e.jsx(q,{className:"app-overlay fixed inset-0 z-40"}),e.jsx("div",{className:"pointer-events-none fixed inset-0 z-50 grid place-items-center p-4",children:e.jsxs(U,{"data-testid":"add-workspace-error",className:"dialog-scale-pop elev-2 pointer-events-auto w-[440px] max-w-[calc(100vw-32px)] rounded-lg border p-5",style:{background:"var(--bg-elevated)",borderColor:"var(--border-bright)"},children:[e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx("div",{className:"flex h-9 w-9 shrink-0 items-center justify-center rounded",style:{background:"color-mix(in oklab, var(--status-red) 14%, transparent)",color:"var(--status-red)"},children:e.jsx(ie,{size:18,"aria-hidden":!0})}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx(W,{className:"text-lg font-semibold text-pri",children:d.title??a("workspace.error.pickerFailed")}),e.jsx(K,{className:"mt-1.5 break-words text-sm text-ter",children:d.message})]})]}),e.jsxs("div",{className:"mt-5 flex justify-end gap-2",children:[e.jsx("button",{type:"button",onClick:f,className:"icon-btn",children:a("common.close")}),e.jsx("button",{type:"button",onClick:()=>r({kind:"confirm",probe:null,pasteDefault:!0}),className:"icon-btn icon-btn--primary",children:a("workspace.error.pastePathInstead")})]})]})})]})}):d.kind==="browse"?e.jsx(we,{commandPresetError:_,commandPresetId:E,commandPresets:w,onClose:f,onCommandPresetChange:P,onCreate:C,open:!0}):e.jsx(fe,{commandPresetError:_,commandPresetId:E,commandPresets:w,pasteFallbackDefault:d.pasteDefault,probe:d.probe,onCancel:f,onCommandPresetChange:P,onCreate:C,onOpenServerBrowse:()=>r({kind:"browse"})})};export{_e as AddWorkspaceDialog};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{c as f,u as h,r as j,j as e,k as b,m as N,O as v,n as y,D as g,o as c}from"./index-DB5fHAMI.js";const R=[["path",{d:"M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z",key:"yt0hxn"}]],k=f("hexagon",R),C=({open:o,onClose:r,onAddWorkspace:x,onTryDemo:d})=>{const{t:s}=h(),[n,l]=j.useState(0),u=t=>{t||(l(0),r())},i=(t=!0)=>{l(0),r(t)},a=n===2;return e.jsx(b,{open:o,onOpenChange:u,children:e.jsxs(N,{children:[e.jsx(v,{className:"app-overlay fixed inset-0 z-40"}),e.jsx("div",{className:"pointer-events-none fixed inset-0 z-50 grid place-items-center p-4",children:e.jsxs(y,{"aria-label":s("firstRun.title"),className:"dialog-scale-pop elev-2 pointer-events-auto w-[480px] max-w-[calc(100vw-32px)] rounded-lg border p-6",style:{background:"var(--bg-elevated)",borderColor:"var(--border-bright)"},children:[e.jsx(g,{className:"sr-only",children:s("firstRun.step",{current:n+1,total:3})}),e.jsxs("div",{className:"min-h-[200px]",children:[n===0&&e.jsxs("div",{className:"flex flex-col items-center gap-4 py-4 text-center",children:[e.jsx("div",{"aria-hidden":!0,className:"flex h-14 w-14 items-center justify-center rounded-lg",style:{background:"color-mix(in oklab, var(--accent) 15%, transparent)",color:"var(--accent)",border:"1px solid color-mix(in oklab, var(--accent) 30%, transparent)"},children:e.jsx(k,{size:32})}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(c,{className:"text-xl font-semibold text-pri",children:s("firstRun.title")}),e.jsx("p",{className:"text-sm text-sec",children:s("firstRun.desc")}),e.jsx("p",{className:"text-xs text-ter",children:s("firstRun.subtitle")})]})]}),n>0&&e.jsx(c,{className:"sr-only",children:s("firstRun.title")}),n===1&&e.jsxs("div",{className:"flex flex-col gap-4 py-2",children:[e.jsx("h2",{className:"text-lg font-semibold text-pri",children:s("firstRun.howItWorks")}),e.jsx("ol",{className:"flex flex-col gap-3",children:[{n:1,title:s("firstRun.slide1Title"),desc:s("firstRun.slide1Desc")},{n:2,title:s("firstRun.slide2Title"),desc:s("firstRun.slide2Desc")},{n:3,title:s("firstRun.slide3Title"),desc:s("firstRun.slide3Desc")}].map(({n:t,title:m,desc:p})=>e.jsxs("li",{className:"flex items-start gap-3",children:[e.jsx("span",{className:"flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-xs font-medium",style:{background:"var(--bg-elevated)",border:"1px solid var(--border-bright)",color:"var(--accent)"},children:t}),e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium text-pri",children:m}),e.jsx("div",{className:"text-xs text-sec",children:p})]})]},t))})]}),n===2&&e.jsxs("div",{className:"flex flex-col gap-3 py-2",children:[e.jsx("h2",{className:"text-lg font-semibold text-pri",children:s("firstRun.getStarted")}),e.jsx("p",{className:"text-sm text-sec",children:s("firstRun.optionDesc")}),e.jsxs("div",{className:"mt-2 flex flex-col gap-2",children:[e.jsx("button",{type:"button",onClick:()=>{x(),i(!1)},className:"icon-btn icon-btn--primary w-full justify-center",children:s("firstRun.addWorkspace")}),e.jsx("button",{type:"button",onClick:()=>{d(),i(!0)},className:"icon-btn w-full justify-center",children:s("firstRun.tryDemo")}),e.jsx("button",{type:"button",onClick:()=>i(),className:"text-xs text-sec underline hover:text-pri mt-1",children:s("firstRun.skipForNow")})]})]})]}),e.jsxs("div",{className:"mt-5 flex items-center justify-between",children:[e.jsx("span",{className:"text-xs text-ter",children:s("firstRun.step",{current:n+1,total:3})}),e.jsxs("div",{className:"flex items-center gap-2",children:[n>0&&!a&&e.jsx("button",{type:"button",onClick:()=>l(t=>t-1),className:"icon-btn",children:s("firstRun.back")}),!a&&e.jsx("button",{type:"button",onClick:()=>l(t=>t+1),className:"icon-btn icon-btn--primary",children:s("firstRun.next")}),e.jsx("button",{type:"button",onClick:()=>i(),className:"text-xs text-ter underline hover:text-sec",children:s("firstRun.skip")})]})]})]})})]})})};export{C as FirstRunWizard};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as d,u as z,j as e,k as j,m as k,O as R,n as C,o as N,D as E,T as S,a as M,t as D,X as L,B as T,F as O,G as A}from"./index-DB5fHAMI.js";const I=t=>{switch(t){case"coder":return{badgeClass:"role-badge--coder",label:"Coder"};case"tester":return{badgeClass:"role-badge--tester",label:"Tester"};case"reviewer":return{badgeClass:"role-badge--reviewer",label:"Reviewer"};case"custom":return{badgeClass:"role-badge--custom",label:"Custom"};default:return{badgeClass:"role-badge--custom",label:String(t)}}},w="hive.worker-modal.width",c=480,W=.5,x=t=>{const s=typeof window<"u"?window.innerWidth-24:1200;return Math.min(Math.max(t,c),Math.max(c,s))},v=()=>typeof window>"u"?c:x(Math.round(window.innerWidth*W)),P=()=>{try{const t=localStorage.getItem(w);if(!t)return v();const s=Number.parseInt(t,10);return Number.isFinite(s)?x(s):v()}catch{return v()}},_=()=>{const[t,s]=d.useState(()=>P()),[u,i]=d.useState(!1);d.useEffect(()=>{try{localStorage.setItem(w,String(Math.round(t)))}catch{}},[t]),d.useEffect(()=>{const a=()=>{s(r=>x(r))};return window.addEventListener("resize",a),()=>window.removeEventListener("resize",a)},[]);const m=d.useCallback(a=>r=>{r.preventDefault();const h=r.clientX,l=t;i(!0);const b=document.body.style.cursor,n=document.body.style.userSelect;document.body.style.cursor="col-resize",document.body.style.userSelect="none";const p=f=>{const g=f.clientX-h,y=a==="left"?l-2*g:l+2*g;s(x(y))},o=()=>{i(!1),document.body.style.cursor=b,document.body.style.userSelect=n,document.removeEventListener("pointermove",p),document.removeEventListener("pointerup",o),document.removeEventListener("pointercancel",o)};document.addEventListener("pointermove",p),document.addEventListener("pointerup",o),document.addEventListener("pointercancel",o)},[t]);return{width:t,resizing:u,beginResize:m}},X=({onClose:t,onStart:s,runId:u,startError:i,starting:m,worker:a})=>{const{t:r}=z(),h=I(a.role),l=!!u,b=A(l),n=_(),p=o=>{o||t()};return e.jsx(j,{open:!0,onOpenChange:p,children:e.jsxs(k,{children:[e.jsx(R,{"data-testid":"worker-modal-overlay",className:"app-overlay fixed inset-0 z-40"}),e.jsx("div",{className:"pointer-events-none fixed inset-0 z-50 grid place-items-center",children:e.jsxs(C,{"data-testid":"worker-modal","aria-label":r("worker.detail",{name:a.name}),className:"dialog-scale-pop pointer-events-auto relative flex h-screen max-h-screen max-w-full flex-col overflow-hidden",onEscapeKeyDown:o=>o.preventDefault(),style:{background:"var(--bg-1)",width:`${n.width}px`},children:[e.jsx("div",{role:"separator","aria-orientation":"vertical","aria-label":r("worker.widthResize"),"aria-valuemin":c,"aria-valuenow":Math.round(n.width),className:"modal-resize-handle modal-resize-handle--left",tabIndex:-1,"data-resizing":n.resizing||void 0,onPointerDown:n.beginResize("left")}),e.jsx("div",{role:"separator","aria-orientation":"vertical","aria-label":r("worker.widthResize"),"aria-valuemin":c,"aria-valuenow":Math.round(n.width),className:"modal-resize-handle modal-resize-handle--right",tabIndex:-1,"data-resizing":n.resizing||void 0,onPointerDown:n.beginResize("right")}),e.jsx(N,{className:"sr-only",children:a.name}),e.jsxs(E,{className:"sr-only",children:[h.label," agent — status ",b.label]}),i?e.jsxs("div",{role:"alert",className:"flex shrink-0 items-center gap-2 border-b px-4 py-2 text-xs",style:{background:"color-mix(in oklab, var(--status-red) 10%, transparent)",borderColor:"color-mix(in oklab, var(--status-red) 30%, var(--border))",color:"var(--status-red)"},children:[e.jsx(S,{size:12,"aria-hidden":!0}),e.jsx("span",{className:"break-words",children:i})]}):null,e.jsxs("div",{className:"relative flex min-h-0 flex-1 flex-col p-3","data-testid":"worker-modal-terminal-slot",children:[e.jsx(M,{label:r("common.close"),children:e.jsx(D,{asChild:!0,children:e.jsx("button",{type:"button","aria-label":"Close worker detail",className:"float-action absolute top-4 right-4 z-10",children:e.jsx(L,{size:14,"aria-hidden":!0})})})}),e.jsx("div",{className:"flex min-h-0 flex-1 rounded-lg border",style:{background:"var(--bg-crust)",borderColor:"var(--border)"},children:l?e.jsx("div",{id:`worker-pty-${u}`,className:"flex h-full w-full","data-pty-slot":"worker"}):e.jsxs("div",{className:"m-auto flex max-w-[400px] flex-col items-center gap-3 px-6 text-center",children:[e.jsx(T,{commandPresetId:a.commandPresetId,workerRole:a.role,size:48}),e.jsx("div",{className:"text-sm text-pri",children:a.name}),e.jsxs("div",{className:"text-xs text-ter",children:[a.status==="stopped"?r("worker.terminalStopped"):r("worker.terminalNotStarted"),a.pendingTaskCount>0?r("worker.pendingResume",{count:a.pendingTaskCount}):r("worker.startAgent")]}),e.jsxs("button",{type:"button",onClick:()=>s(a),disabled:m,className:"icon-btn icon-btn--primary","data-testid":"worker-start-empty",children:[e.jsx(O,{size:12,"aria-hidden":!0})," ",r(m?"common.starting":"common.start")]})]})})]})]})})]})})};export{X as WorkerModal};
|