vibe-coding-master 0.0.12 → 0.0.14
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/README.md +33 -14
- package/dist/backend/api/claude-hook-routes.js +5 -0
- package/dist/backend/api/message-routes.js +4 -0
- package/dist/backend/api/round-routes.js +33 -0
- package/dist/backend/api/session-routes.js +2 -0
- package/dist/backend/api/task-routes.js +1 -0
- package/dist/backend/server.js +27 -3
- package/dist/backend/services/app-settings-service.js +2 -1
- package/dist/backend/services/claude-hook-service.js +70 -0
- package/dist/backend/services/harness-service.js +95 -0
- package/dist/backend/services/message-service.js +222 -49
- package/dist/backend/services/project-service.js +1 -1
- package/dist/backend/services/round-service.js +117 -0
- package/dist/backend/services/session-service.js +39 -0
- package/dist/backend/services/status-service.js +0 -76
- package/dist/backend/services/task-service.js +14 -6
- package/dist/backend/templates/harness/architect-agent.js +5 -0
- package/dist/backend/templates/harness/claude-root.js +6 -0
- package/dist/backend/templates/harness/coder-agent.js +5 -0
- package/dist/backend/templates/harness/gitignore.js +2 -1
- package/dist/backend/templates/harness/project-manager-agent.js +7 -0
- package/dist/backend/templates/harness/reviewer-agent.js +5 -0
- package/dist/backend/templates/message-envelope.js +3 -1
- package/dist/backend/ws/terminal-ws.js +15 -1
- package/dist/cli/vcmctl.js +30 -0
- package/dist/shared/types/claude-hook.js +1 -0
- package/dist/shared/types/round.js +1 -0
- package/dist-frontend/assets/index-DVhkEVnA.js +89 -0
- package/dist-frontend/assets/index-jEkUTnIY.css +32 -0
- package/dist-frontend/index.html +2 -2
- package/docs/cc-best-practices.md +15 -4
- package/docs/product-design.md +71 -38
- package/docs/v1-architecture-design.md +108 -49
- package/docs/v1-implementation-plan.md +107 -32
- package/package.json +1 -1
- package/dist-frontend/assets/index-Bi4X3GSR.css +0 -32
- package/dist-frontend/assets/index-DaHXq14j.js +0 -88
|
@@ -17,7 +17,7 @@ V1 is implemented as a local GUI app with:
|
|
|
17
17
|
- API-driven message bus.
|
|
18
18
|
- Translation panel based on Claude transcript JSONL tailing.
|
|
19
19
|
- npm packaging with built `dist` and `dist-frontend` output.
|
|
20
|
-
- Task creation creates one `feature/<task>` branch and one `.
|
|
20
|
+
- Task creation creates one `feature/<task>` branch and one `.claude/worktrees/<task>` git worktree by default; users may clear `Create worktree and branch` to create an inline task in the connected repository/current branch. Because handoffs are scoped as `.ai/vcm/handoffs/` under the task runtime repo, only one active inline task is allowed per connected repository.
|
|
21
21
|
|
|
22
22
|
## 2. Package And Build
|
|
23
23
|
|
|
@@ -193,6 +193,11 @@ Theme modes:
|
|
|
193
193
|
- `light`
|
|
194
194
|
- `dark`
|
|
195
195
|
|
|
196
|
+
Preferences:
|
|
197
|
+
|
|
198
|
+
- `themeMode`
|
|
199
|
+
- `roundCompletionAlerts`, default `true`
|
|
200
|
+
|
|
196
201
|
### `src/shared/types/task.ts`
|
|
197
202
|
|
|
198
203
|
Defines:
|
|
@@ -239,6 +244,17 @@ Defines:
|
|
|
239
244
|
|
|
240
245
|
The state type includes `paused` for backend/API compatibility. The current GUI only exposes manual/auto.
|
|
241
246
|
|
|
247
|
+
### `src/shared/types/round.ts`
|
|
248
|
+
|
|
249
|
+
Defines:
|
|
250
|
+
|
|
251
|
+
- `VcmRoleTurnStatus`
|
|
252
|
+
- `VcmTaskRoundStatus`
|
|
253
|
+
- `VcmRoleTurnState`
|
|
254
|
+
- `VcmTaskRoundState`
|
|
255
|
+
|
|
256
|
+
Round state is task-level. It reports the latest active/completed role, queued and pending message counts, and a stable `completionId` for frontend notification dedupe.
|
|
257
|
+
|
|
242
258
|
### `src/shared/types/translation.ts`
|
|
243
259
|
|
|
244
260
|
Defines:
|
|
@@ -288,10 +304,6 @@ Defines:
|
|
|
288
304
|
|
|
289
305
|
- `ApiErrorResponse`
|
|
290
306
|
- `TaskStatusReport`
|
|
291
|
-
- `TaskWorkflowStepId`
|
|
292
|
-
- `TaskWorkflowStepStatus`
|
|
293
|
-
- `TaskWorkflowStep`
|
|
294
|
-
- `TaskWorkflowReport`
|
|
295
307
|
- `DispatchRoleCommandResult`
|
|
296
308
|
- `BootstrapState`
|
|
297
309
|
|
|
@@ -413,7 +425,7 @@ Worktree methods:
|
|
|
413
425
|
Required safety:
|
|
414
426
|
|
|
415
427
|
- all Git commands keep command-scoped `safe.directory`
|
|
416
|
-
- `TaskService` verifies Close Task worktree paths are under `<baseRepoRoot>/.
|
|
428
|
+
- `TaskService` verifies Close Task worktree paths are under `<baseRepoRoot>/.claude/worktrees/`
|
|
417
429
|
- VCM-created task branches are derived from validated task slugs as `feature/<taskSlug>`
|
|
418
430
|
|
|
419
431
|
### `src/backend/adapters/claude-adapter.ts`
|
|
@@ -503,7 +515,7 @@ Responsibilities:
|
|
|
503
515
|
- record recent repo paths in app settings
|
|
504
516
|
- create `~/.vcm/projects/<project-id>/config.json`
|
|
505
517
|
- ensure base state directories
|
|
506
|
-
- ensure `.ai/vcm/`
|
|
518
|
+
- ensure `.ai/vcm/` and `.claude/worktrees/` are ignored by Git before task-worktree creation
|
|
507
519
|
- expose base repo as the project control root
|
|
508
520
|
|
|
509
521
|
Repository connect should keep connecting to the base repo. Task worktrees are managed under that base repo and should not be treated as separate projects in the normal task list.
|
|
@@ -539,8 +551,9 @@ createTask(baseRepoRoot, { taskSlug })
|
|
|
539
551
|
-> assertValidTaskSlug(taskSlug)
|
|
540
552
|
-> assert .ai/vcm/ is ignored
|
|
541
553
|
-> if createWorktree is not false:
|
|
554
|
+
-> assert .claude/worktrees/ is ignored
|
|
542
555
|
-> branch = feature/<taskSlug>
|
|
543
|
-
-> worktreePath = <baseRepoRoot>/.
|
|
556
|
+
-> worktreePath = <baseRepoRoot>/.claude/worktrees/<taskSlug>
|
|
544
557
|
-> assert base repo has no uncommitted changes
|
|
545
558
|
-> assert branch does not exist
|
|
546
559
|
-> assert worktree path does not exist
|
|
@@ -565,7 +578,7 @@ cleanupTask(baseRepoRoot, taskSlug, options)
|
|
|
565
578
|
-> route layer lists role sessions
|
|
566
579
|
-> route layer stops each VCM-managed role session with status running
|
|
567
580
|
-> route layer stops translation tailers and clears task translation cache
|
|
568
|
-
-> if worktreePath exists, verify it is under <baseRepoRoot>/.
|
|
581
|
+
-> if worktreePath exists, verify it is under <baseRepoRoot>/.claude/worktrees/
|
|
569
582
|
-> if worktreePath exists, git.removeWorktree(baseRepoRoot, worktreePath, force=true)
|
|
570
583
|
-> if worktreePath exists, git.deleteBranch(baseRepoRoot, task.branch, force=true) by default
|
|
571
584
|
-> delete <baseRepoRoot>/.ai/vcm/tasks/<task>.json
|
|
@@ -623,7 +636,7 @@ Responsibilities:
|
|
|
623
636
|
- assemble `TaskStatusReport`
|
|
624
637
|
- list sessions
|
|
625
638
|
- list artifact checks
|
|
626
|
-
-
|
|
639
|
+
- emit missing/incomplete artifact warnings
|
|
627
640
|
|
|
628
641
|
### `src/backend/services/session-service.ts`
|
|
629
642
|
|
|
@@ -673,12 +686,18 @@ Responsibilities:
|
|
|
673
686
|
|
|
674
687
|
- list messages
|
|
675
688
|
- send messages
|
|
689
|
+
- confirm submitted messages from Claude Code `UserPromptSubmit` hooks
|
|
690
|
+
- mark all open messages done for manual recovery
|
|
676
691
|
- stage/approve/reject messages
|
|
677
692
|
- get/update orchestration state
|
|
678
693
|
- enforce message policy
|
|
694
|
+
- enforce per-target-role in-flight delivery
|
|
695
|
+
- queue extra messages for a busy target role
|
|
696
|
+
- acknowledge a role's active message when that role sends `vcmctl reply` or `vcmctl result`
|
|
697
|
+
- deliver the next queued message for that role after acknowledgement
|
|
679
698
|
- persist message snapshots
|
|
680
699
|
- write message body markdown
|
|
681
|
-
- write staged or
|
|
700
|
+
- write staged or delivering messages to target terminal
|
|
682
701
|
|
|
683
702
|
In task-worktree mode:
|
|
684
703
|
|
|
@@ -686,6 +705,30 @@ In task-worktree mode:
|
|
|
686
705
|
- orchestration state lives under `task.worktreePath/.ai/vcm/orchestration`
|
|
687
706
|
- message body files live under `task.worktreePath/.ai/vcm/handoffs/messages`
|
|
688
707
|
- terminal delivery uses the runtime session for the role, whose cwd is the task worktree
|
|
708
|
+
- message mutations are serialized per task inside the VCM process to avoid concurrent API calls bypassing the in-flight check
|
|
709
|
+
|
|
710
|
+
Auto-delivery state:
|
|
711
|
+
|
|
712
|
+
- `send` writes the envelope and Enter, then stores `delivering`
|
|
713
|
+
- `UserPromptSubmit` hook with the same message id stores `submitted`
|
|
714
|
+
- `delivering`, `submitted`, `delivered`, and `staged` all count as active for per-role turn-taking
|
|
715
|
+
- target-role `vcmctl reply` / `vcmctl result` acknowledges the active message and releases the next queued message
|
|
716
|
+
- `markAllDone` appends `acknowledged` snapshots for open messages so the user can recover after manually copying or sending stuck queued work
|
|
717
|
+
|
|
718
|
+
### `src/backend/services/claude-hook-service.ts`
|
|
719
|
+
|
|
720
|
+
Exports:
|
|
721
|
+
|
|
722
|
+
- `ClaudeHookService`
|
|
723
|
+
- `createClaudeHookService(deps)`
|
|
724
|
+
|
|
725
|
+
Responsibilities:
|
|
726
|
+
|
|
727
|
+
- accept Claude Code hook events from `vcmctl hook-event`
|
|
728
|
+
- support only `UserPromptSubmit` and `Stop` in V1
|
|
729
|
+
- map hook events to the current VCM project, task, role, and persisted Claude session id
|
|
730
|
+
- update `RoleSessionRecord.activityStatus`: `UserPromptSubmit -> running`, `Stop -> idle`
|
|
731
|
+
- call `MessageService.confirmPromptSubmitted` when a `UserPromptSubmit` prompt contains a VCM message id
|
|
689
732
|
|
|
690
733
|
### `src/backend/services/command-dispatcher.ts`
|
|
691
734
|
|
|
@@ -812,6 +855,26 @@ Responsibilities:
|
|
|
812
855
|
|
|
813
856
|
Terminal submission is delegated to `src/backend/runtime/terminal-submit.ts`, which bracket-pastes text, waits briefly, then sends Enter separately.
|
|
814
857
|
|
|
858
|
+
### `src/backend/services/round-service.ts`
|
|
859
|
+
|
|
860
|
+
Exports:
|
|
861
|
+
|
|
862
|
+
- `RoundService`
|
|
863
|
+
- `TaskRoundInput`
|
|
864
|
+
- `RoundServiceDeps`
|
|
865
|
+
- `createRoundService(deps)`
|
|
866
|
+
- `evaluateTaskRoundState(input)`
|
|
867
|
+
|
|
868
|
+
Responsibilities:
|
|
869
|
+
|
|
870
|
+
- read hook-driven role activity from `RoleSessionRecord`
|
|
871
|
+
- map `activityStatus: "running"` to role state `answering`
|
|
872
|
+
- map `activityStatus: "idle"` plus `lastStopAt` to role state `idle`
|
|
873
|
+
- evaluate task-level round completion from messages plus role states
|
|
874
|
+
- wait for the latest active delivering/submitted/delivered/staged target role in PM -> role -> PM chains
|
|
875
|
+
- ignore completion while queued or pending messages exist
|
|
876
|
+
- keep `stopSession` and `stopTask` as no-op lifecycle compatibility hooks
|
|
877
|
+
|
|
815
878
|
## 9. Backend API
|
|
816
879
|
|
|
817
880
|
### `src/backend/server.ts`
|
|
@@ -836,7 +899,9 @@ Registers HTTP routes and the terminal WebSocket.
|
|
|
836
899
|
- `src/backend/api/task-routes.ts`: tasks, task status, and Close Task cleanup endpoint; Close Task stops running role sessions before translation/task cleanup
|
|
837
900
|
- `src/backend/api/session-routes.ts`: session lifecycle and dispatch compatibility endpoint
|
|
838
901
|
- `src/backend/api/artifact-routes.ts`: artifact, role command, and log reads/writes
|
|
839
|
-
- `src/backend/api/message-routes.ts`: messages and orchestration
|
|
902
|
+
- `src/backend/api/message-routes.ts`: messages, Mark All Done recovery, and orchestration
|
|
903
|
+
- `src/backend/api/claude-hook-routes.ts`: Claude Code `UserPromptSubmit` and `Stop` hook receiver
|
|
904
|
+
- `src/backend/api/round-routes.ts`: task round completion state
|
|
840
905
|
- `src/backend/api/translation-routes.ts`: settings, prompt previews, provider test, start/poll, input/send, clear/retry
|
|
841
906
|
|
|
842
907
|
Worktree task API:
|
|
@@ -855,6 +920,8 @@ Terminal WebSocket forwards PTY output/input/resize.
|
|
|
855
920
|
|
|
856
921
|
Translation does not use WebSocket. The backend writes cached translation events under `<taskRepoRoot>/.ai/vcm/translation/<task>/<role>/<session-id>.jsonl`; the frontend polls `GET /api/translation/sessions/:sessionId/events?after=<cursor>`. The cursor is the next expected seq, so `after=18` means seq `1..17` can be removed and seq `18+` should be returned.
|
|
857
922
|
|
|
923
|
+
Round completion is HTTP-polled too. `GET /api/tasks/:taskSlug/round` returns `VcmTaskRoundState` from hook-driven role activity and message state; it is not a WebSocket stream.
|
|
924
|
+
|
|
858
925
|
## 10. Backend Templates
|
|
859
926
|
|
|
860
927
|
### `src/backend/templates/handoff.ts`
|
|
@@ -910,6 +977,7 @@ It calls:
|
|
|
910
977
|
- artifact endpoints
|
|
911
978
|
- message endpoints
|
|
912
979
|
- orchestration endpoints
|
|
980
|
+
- round completion endpoint
|
|
913
981
|
- translation endpoints
|
|
914
982
|
|
|
915
983
|
Implemented task cleanup method:
|
|
@@ -943,10 +1011,12 @@ Responsibilities:
|
|
|
943
1011
|
|
|
944
1012
|
- own top-level app state
|
|
945
1013
|
- load current project and recent paths on startup
|
|
1014
|
+
- load app preferences, including `themeMode` and `roundCompletionAlerts`
|
|
946
1015
|
- load tasks and harness status after connect
|
|
947
1016
|
- pass sidebar props to `ProjectDashboard`
|
|
948
1017
|
- pass task props to `TaskWorkspace`
|
|
949
|
-
- keep active
|
|
1018
|
+
- keep active messages/orchestration/events synchronized by task
|
|
1019
|
+
- dedupe task round `completionId` values and show/play completion alerts when enabled
|
|
950
1020
|
|
|
951
1021
|
### `src/frontend/routes/project-dashboard.tsx`
|
|
952
1022
|
|
|
@@ -960,8 +1030,9 @@ Responsibilities:
|
|
|
960
1030
|
- collapsible sidebar
|
|
961
1031
|
- repository connect form
|
|
962
1032
|
- repository summary
|
|
963
|
-
- workflow panel
|
|
964
1033
|
- settings section
|
|
1034
|
+
- round completion alert toggle
|
|
1035
|
+
- try alert test button
|
|
965
1036
|
- messages modal
|
|
966
1037
|
- events modal
|
|
967
1038
|
- harness panel
|
|
@@ -981,6 +1052,7 @@ Responsibilities:
|
|
|
981
1052
|
- red `Close Task` action with destructive confirmation
|
|
982
1053
|
- show branch and immutable worktree path for the active task
|
|
983
1054
|
- status/message/orchestration refresh
|
|
1055
|
+
- round state refresh
|
|
984
1056
|
- periodic polling
|
|
985
1057
|
- session lifecycle actions
|
|
986
1058
|
- per-role permission state
|
|
@@ -1020,15 +1092,6 @@ Exports:
|
|
|
1020
1092
|
|
|
1021
1093
|
Shows harness status and install/update action.
|
|
1022
1094
|
|
|
1023
|
-
### `src/frontend/components/workflow-panel.tsx`
|
|
1024
|
-
|
|
1025
|
-
Exports:
|
|
1026
|
-
|
|
1027
|
-
- `WorkflowPanelProps`
|
|
1028
|
-
- `WorkflowPanel({ workflow })`
|
|
1029
|
-
|
|
1030
|
-
Renders the sidebar workflow steps.
|
|
1031
|
-
|
|
1032
1095
|
### `src/frontend/components/message-timeline.tsx`
|
|
1033
1096
|
|
|
1034
1097
|
Exports:
|
|
@@ -1037,7 +1100,7 @@ Exports:
|
|
|
1037
1100
|
- `getMessageCounts(messages)`
|
|
1038
1101
|
- `MessageTimeline(props)`
|
|
1039
1102
|
|
|
1040
|
-
Used inside the Messages modal. Current UI rows show sequence, timestamp, route, type, status, body preview, body path, and a `Copy` button. Stage/approve/reject backend APIs remain compatibility paths, but those buttons are not displayed in the current modal.
|
|
1103
|
+
Used inside the Messages modal. Current UI rows show sequence, timestamp, route, type, status, body preview, body path, and a `Copy` button. The modal header includes `Mark All Done` for manual recovery from stuck queued/in-flight messages. Stage/approve/reject backend APIs remain compatibility paths, but those buttons are not displayed in the current modal.
|
|
1041
1104
|
|
|
1042
1105
|
### `src/frontend/components/event-log.tsx`
|
|
1043
1106
|
|
|
@@ -1073,7 +1136,7 @@ Exports:
|
|
|
1073
1136
|
- `SessionConsoleProps`
|
|
1074
1137
|
- `SessionConsole(props)`
|
|
1075
1138
|
|
|
1076
|
-
Role console and translation split.
|
|
1139
|
+
Role console, `Auto orchestration` toggle, and translation split.
|
|
1077
1140
|
|
|
1078
1141
|
### `src/frontend/components/session-toolbar.tsx`
|
|
1079
1142
|
|
|
@@ -1147,15 +1210,25 @@ Sidebar:
|
|
|
1147
1210
|
|
|
1148
1211
|
- all groups default collapsed
|
|
1149
1212
|
- `Repository Path` default open only when no task is selected
|
|
1150
|
-
- `Settings` includes `Theme`, `
|
|
1213
|
+
- `Settings` includes `Theme`, `Round alert`, `Try alert`, `Messages`, and `Events`
|
|
1151
1214
|
- `Theme` cycles through `System`, `Light`, and `Dark`; `System` follows the browser/OS color-scheme preference
|
|
1215
|
+
- `Round alert` is on by default and controls the in-app completion prompt plus short sound
|
|
1216
|
+
- `Try alert` calls the same prompt/sound path without waiting for a real completed round
|
|
1152
1217
|
|
|
1153
1218
|
Task workspace:
|
|
1154
1219
|
|
|
1155
1220
|
- role tabs in the first header row
|
|
1156
|
-
- workflow is not in main workspace
|
|
1157
1221
|
- messages/events are not in main workspace
|
|
1158
1222
|
- active role console fills available space
|
|
1223
|
+
- `Auto orchestration` appears immediately to the left of `Translate` and uses the same compact toggle style
|
|
1224
|
+
|
|
1225
|
+
Round completion:
|
|
1226
|
+
|
|
1227
|
+
- task state follows the latest active delivering/submitted/delivered/staged message target role
|
|
1228
|
+
- role activity uses `UserPromptSubmit -> running` and `Stop -> idle`
|
|
1229
|
+
- PM -> role -> PM chains complete after PM's final hook `Stop`, not after the intermediate role's `Stop`
|
|
1230
|
+
- queued or pending messages keep the round active
|
|
1231
|
+
- frontend dedupes `completionId` before showing a prompt or playing sound
|
|
1159
1232
|
|
|
1160
1233
|
Translation:
|
|
1161
1234
|
|
|
@@ -1173,7 +1246,7 @@ App settings:
|
|
|
1173
1246
|
~/.vcm/settings.json
|
|
1174
1247
|
```
|
|
1175
1248
|
|
|
1176
|
-
Contains UI theme preference, translation settings/secrets, and recent repository paths.
|
|
1249
|
+
Contains UI theme preference, round-completion alert preference, translation settings/secrets, and recent repository paths.
|
|
1177
1250
|
|
|
1178
1251
|
Project config:
|
|
1179
1252
|
|
|
@@ -1216,7 +1289,7 @@ Translation cache:
|
|
|
1216
1289
|
Task worktrees:
|
|
1217
1290
|
|
|
1218
1291
|
```text
|
|
1219
|
-
.
|
|
1292
|
+
.claude/worktrees/<task>/
|
|
1220
1293
|
```
|
|
1221
1294
|
|
|
1222
1295
|
Handoff artifacts:
|
|
@@ -1245,9 +1318,9 @@ npm run verify:package
|
|
|
1245
1318
|
For frontend layout changes, also verify manually:
|
|
1246
1319
|
|
|
1247
1320
|
- connect repository
|
|
1248
|
-
- confirm `.ai/vcm/`
|
|
1321
|
+
- confirm `.ai/vcm/` and `.claude/worktrees/` are ignored before creating a task worktree
|
|
1249
1322
|
- create task and verify branch `feature/<task>` is created
|
|
1250
|
-
- verify worktree path is `<baseRepoRoot>/.
|
|
1323
|
+
- verify worktree path is `<baseRepoRoot>/.claude/worktrees/<task>`
|
|
1251
1324
|
- open task
|
|
1252
1325
|
- verify role sessions start with cwd set to the task worktree
|
|
1253
1326
|
- role tabs stay in header
|
|
@@ -1256,7 +1329,9 @@ For frontend layout changes, also verify manually:
|
|
|
1256
1329
|
- translation split is 50/50
|
|
1257
1330
|
- Messages modal opens from sidebar Settings
|
|
1258
1331
|
- Events modal opens from sidebar Settings
|
|
1259
|
-
- Auto orchestration toggles on/off
|
|
1332
|
+
- Auto orchestration toggles on/off from the role toolbar
|
|
1333
|
+
- Auto orchestration switches to the target role tab when a new message is confirmed by `UserPromptSubmit`
|
|
1334
|
+
- Round alert can be toggled from sidebar Settings and fires once after a chained round truly completes
|
|
1260
1335
|
- `Enter` in translation composer translates/sends
|
|
1261
1336
|
- `Shift+Enter` inserts newline
|
|
1262
1337
|
- close a worktree-backed task and verify it stops running role sessions, removes the worktree, deletes the task branch, and removes central task metadata
|
package/package.json
CHANGED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) 2014 The xterm.js authors. All rights reserved.
|
|
3
|
-
* Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
|
|
4
|
-
* https://github.com/chjj/term.js
|
|
5
|
-
* @license MIT
|
|
6
|
-
*
|
|
7
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
-
* of this software and associated documentation files (the "Software"), to deal
|
|
9
|
-
* in the Software without restriction, including without limitation the rights
|
|
10
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
-
* copies of the Software, and to permit persons to whom the Software is
|
|
12
|
-
* furnished to do so, subject to the following conditions:
|
|
13
|
-
*
|
|
14
|
-
* The above copyright notice and this permission notice shall be included in
|
|
15
|
-
* all copies or substantial portions of the Software.
|
|
16
|
-
*
|
|
17
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
23
|
-
* THE SOFTWARE.
|
|
24
|
-
*
|
|
25
|
-
* Originally forked from (with the author's permission):
|
|
26
|
-
* Fabrice Bellard's javascript vt100 for jslinux:
|
|
27
|
-
* http://bellard.org/jslinux/
|
|
28
|
-
* Copyright (c) 2011 Fabrice Bellard
|
|
29
|
-
* The original design remains. The terminal itself
|
|
30
|
-
* has been extended to include xterm CSI codes, among
|
|
31
|
-
* other features.
|
|
32
|
-
*/.xterm{cursor:text;position:relative;user-select:none;-ms-user-select:none;-webkit-user-select:none}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{position:absolute;top:0;z-index:5}.xterm .xterm-helper-textarea{padding:0;border:0;margin:0;position:absolute;opacity:0;left:-9999em;top:0;width:0;height:0;z-index:-5;white-space:nowrap;overflow:hidden;resize:none}.xterm .composition-view{background:#000;color:#fff;display:none;position:absolute;white-space:nowrap;z-index:1}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{background-color:#000;overflow-y:scroll;cursor:default;position:absolute;right:0;left:0;top:0;bottom:0}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;left:0;top:0}.xterm .xterm-scroll-area{visibility:hidden}.xterm-char-measure-element{display:inline-block;visibility:hidden;position:absolute;top:0;left:-9999em;line-height:normal}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer,.xterm .xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility:not(.debug),.xterm .xterm-message{position:absolute;left:0;top:0;bottom:0;right:0;z-index:10;color:transparent;pointer-events:none}.xterm .xterm-accessibility-tree:not(.debug) *::selection{color:transparent}.xterm .xterm-accessibility-tree{-webkit-user-select:text;user-select:text;white-space:pre}.xterm .live-region{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}.xterm-dim{opacity:1!important}.xterm-underline-1{text-decoration:underline}.xterm-underline-2{text-decoration:double underline}.xterm-underline-3{text-decoration:wavy underline}.xterm-underline-4{text-decoration:dotted underline}.xterm-underline-5{text-decoration:dashed underline}.xterm-overline{text-decoration:overline}.xterm-overline.xterm-underline-1{text-decoration:overline underline}.xterm-overline.xterm-underline-2{text-decoration:overline double underline}.xterm-overline.xterm-underline-3{text-decoration:overline wavy underline}.xterm-overline.xterm-underline-4{text-decoration:overline dotted underline}.xterm-overline.xterm-underline-5{text-decoration:overline dashed underline}.xterm-strikethrough{text-decoration:line-through}.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}.xterm-decoration-overview-ruler{z-index:8;position:absolute;top:0;right:0;pointer-events:none}.xterm-decoration-top{z-index:2;position:relative}:root{color-scheme:light;font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;background:#f5f2ea;color:#1c2024;line-height:1.5}html,body,#root{height:100%}*{box-sizing:border-box}body{margin:0;min-width:320px;min-height:100vh;background:#f5f2ea}button,input,select,textarea{font:inherit}button{border:1px solid #9ba6ad;background:#f8f7f2;color:#1d252b;border-radius:6px;min-height:34px;padding:6px 10px;cursor:pointer}button:hover:not(:disabled){background:#eef4f2;border-color:#607d74}button:disabled{cursor:not-allowed;opacity:.55}.danger-button{border-color:#b84a45;background:#fff1ee;color:#8d211d;font-weight:750}.danger-button:hover:not(:disabled){border-color:#8d211d;background:#ffe2dc}input,select,textarea:not(.xterm-helper-textarea){width:100%;border:1px solid #b9b0a1;border-radius:6px;background:#fffdf8;color:#202326;padding:8px 10px}textarea:not(.xterm-helper-textarea){min-height:240px;resize:vertical;font-family:Menlo,Monaco,Consolas,monospace;font-size:12px}h1,h2,p{margin-top:0}h1{margin-bottom:4px;font-size:26px;line-height:1.15}h2{margin-bottom:10px;font-size:14px;letter-spacing:0}.app-shell{display:grid;grid-template-columns:minmax(280px,320px) minmax(0,1fr);height:100vh;min-height:0;overflow:hidden}.app-shell.is-sidebar-collapsed{grid-template-columns:46px minmax(0,1fr)}.app-sidebar{position:relative;min-width:0;border-right:1px solid #d3c9b8;background:#fbfaf6;padding:14px;overflow:auto}.app-shell.is-sidebar-collapsed .app-sidebar{overflow:hidden;padding:8px}.sidebar-toggle{position:absolute;top:10px;right:10px;z-index:2;display:grid;place-items:center;width:28px;min-height:28px;padding:0;background:#fffdf8}.sidebar-toggle:before{width:8px;height:8px;border-color:currentColor;border-style:solid;border-width:0 2px 2px 0;content:"";transform:translate(2px) rotate(135deg)}.app-shell.is-sidebar-collapsed .sidebar-toggle{left:9px;right:auto}.app-shell.is-sidebar-collapsed .sidebar-toggle:before{transform:translate(-2px) rotate(-45deg)}.sidebar-content{min-width:0}.app-shell.is-sidebar-collapsed .sidebar-content{width:0;opacity:0;pointer-events:none}.app-main{min-width:0;height:100%;padding:14px 16px;overflow:auto}.brand-header{display:flex;gap:12px;align-items:baseline;margin-bottom:10px;padding-right:34px}.brand-header strong{font-size:18px}.brand-header span,.muted,.workspace-branch,.workspace-worktree{color:#667071;font-size:13px}.sidebar-section{margin-bottom:8px;border:1px solid #e0d6c7;border-radius:8px;background:#fffdfa;overflow:hidden}.sidebar-section-toggle{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:center;width:100%;min-height:34px;border:0;border-radius:0;background:transparent;color:#1c2024;font-size:13px;font-weight:750;text-align:left}.sidebar-section-toggle:hover{background:#f5f1e8}.sidebar-section-toggle[aria-expanded=true]{border-bottom:1px solid #ece5d9}.sidebar-section-chevron{width:8px;height:8px;border-color:currentColor;border-style:solid;border-width:0 2px 2px 0;transform:rotate(45deg)}.sidebar-section-toggle[aria-expanded=true] .sidebar-section-chevron{transform:rotate(-135deg)}.sidebar-section-content{padding:8px}.repo-connect,.project-summary,.harness-panel,.task-create{margin:0}.inline-form{display:grid;grid-template-columns:minmax(0,1fr);gap:8px}.inline-form.has-recent-paths{grid-template-columns:minmax(0,1fr) auto}.inline-form>input{grid-column:1 / -1}.inline-form>button{justify-self:end}.inline-form.has-recent-paths>button{justify-self:auto}.repo-recent-select{min-width:0;max-width:none}.project-summary dl{display:grid;gap:8px;margin:0}.project-summary div{min-width:0}.project-summary dt{color:#6c6255;font-size:12px}.project-summary dd{margin:0;overflow-wrap:anywhere;font-size:13px}.warnings,.error-banner{border:1px solid #c87b54;background:#fff4ed;color:#6f3218;border-radius:6px;padding:10px 12px}.warnings{margin:12px 0 0;padding-left:26px;font-size:13px}.harness-panel{display:grid;gap:8px}.harness-panel-header{display:flex;justify-content:space-between;gap:8px;align-items:center}.harness-panel-header h2,.harness-panel-header p,.harness-result p{margin-bottom:0}.harness-actions{display:flex;flex-wrap:wrap;gap:6px;justify-content:flex-end}.harness-file-list{display:grid;gap:6px;margin:0;padding:0;list-style:none}.harness-file-list li{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:center;border:1px solid #ece5d9;border-radius:6px;padding:6px 8px;background:#fffdfa}.harness-file-list span{overflow:hidden;font-size:12px;font-weight:650;text-overflow:ellipsis;white-space:nowrap}.harness-changes,.harness-result{border:1px solid #e0d6c7;border-radius:6px;padding:8px;background:#f8f7f2;font-size:12px}.harness-changes h3{margin:0 0 4px;font-size:12px}.harness-changes ul,.harness-result ul{margin:0;padding-left:18px}.task-create form{display:grid;gap:8px}.task-create-preview{display:grid;gap:2px;border:1px solid #e0d6c7;border-radius:6px;background:#f8f7f2;padding:6px 8px}.task-create-option{display:flex;align-items:center;gap:8px;color:#1f242b;font-size:13px;font-weight:700}.task-create-option input{width:16px;height:16px;margin:0}.task-create-preview span{color:#255f3d;font-size:12px;font-weight:700}.task-create-preview small{overflow:hidden;color:#687273;font-size:11px;text-overflow:ellipsis;white-space:nowrap}.task-nav{display:grid;gap:8px}.task-nav-item{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:center;text-align:left}.task-nav-item.is-active,.role-tab.is-active{border-color:#2f6f73;background:#e8f1ef}.sidebar-settings{display:grid;gap:8px}.sidebar-settings button{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:center;width:100%;text-align:left}.sidebar-settings .settings-toggle.is-active{border-color:#2f6f73;background:#e8f1ef}.sidebar-settings .theme-mode-toggle span:last-child{font-weight:750}.workspace-header{display:grid;grid-template-columns:minmax(180px,auto) minmax(420px,1fr) auto auto;gap:16px;align-items:center;margin-bottom:6px}.workspace-title-line{display:flex;flex-wrap:wrap;gap:10px;align-items:baseline;min-width:0}.workspace-title-line h1{margin-bottom:0;font-size:18px;line-height:1.15}.workspace-branch{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.workspace-worktree{max-width:260px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.eyebrow{color:#7a5c2f;font-size:12px;font-weight:700;text-transform:uppercase}.role-tabs{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px;margin-bottom:8px;min-width:0}.workspace-header .role-tabs{margin-bottom:0}.role-tab{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px;align-items:center;min-height:30px;padding:4px 8px;text-align:left}.workflow-panel{display:grid;gap:8px;margin:0}.workflow-summary p{margin-bottom:0}.workflow-summary p{color:#4f5558;font-size:13px}.workflow-steps{display:grid;grid-template-columns:minmax(0,1fr);gap:6px;margin:0;padding:0;list-style:none}.workflow-steps li{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px;align-items:center;min-height:28px;border:1px solid #ece5d9;border-radius:6px;padding:4px 6px;background:#fffdfa}.workflow-steps li.is-current{border-color:#2f6f73;background:#e8f1ef}.workflow-steps span{overflow:hidden;color:#394246;font-size:12px;font-weight:650;text-overflow:ellipsis;white-space:nowrap}.workspace-grid{display:grid;grid-template-columns:minmax(0,1fr);flex:1;gap:10px;align-items:stretch;min-height:0}.workspace-main{min-width:0;min-height:0;display:flex;flex-direction:column;gap:8px}.role-console-stack{min-width:0;min-height:0;flex:1;display:flex;flex-direction:column}.role-console-panel{min-width:0;min-height:0;flex:1;display:none}.role-console-panel.is-active{display:flex;flex-direction:column}.session-console,.message-panel,.event-log,.empty-workspace{border:1px solid #d6d0c6;border-radius:8px;background:#fffdf8;padding:10px}.task-workspace{display:flex;flex-direction:column;gap:8px;height:100%;min-height:0}.session-console{display:grid;grid-template-rows:auto minmax(0,1fr);gap:8px;flex:1;height:100%;min-height:0}.session-console-top{display:flex;gap:10px;align-items:center;justify-content:space-between}.session-controls{display:flex;flex-wrap:wrap;gap:8px;align-items:center;justify-content:space-between;margin:0 0 8px}.permission-mode-field{display:grid;grid-template-columns:auto minmax(180px,260px);gap:8px;align-items:center;width:fit-content;max-width:100%}.permission-mode-field span{color:#5f6a6c;font-size:13px;font-weight:650}.permission-mode-field small{display:block;color:#7b8587;font-size:11px;font-weight:500;line-height:1.2}.permission-mode-field select{width:100%;min-height:30px;border:1px solid #b9b0a1;border-radius:6px;background:#fffdf8;color:#202326;padding:4px 8px}.session-toolbar{display:flex;flex-wrap:wrap;gap:6px;justify-content:flex-end}.session-toolbar button{min-height:30px;padding:4px 9px}.translation-toggle{display:inline-flex;align-items:center;justify-content:center;min-height:28px;border:1px solid #b5bec4;border-radius:6px;background:#fffefa;color:#4f5558;font-size:12px;font-weight:650;padding:3px 10px;white-space:nowrap}.translation-toggle.is-active{border-color:#2f7e84;background:#e8f4f2;color:#145e64}.translation-settings-grid input[type=checkbox]{width:auto}.session-console-body{display:grid;grid-template-columns:minmax(0,1fr);min-width:0;min-height:0;height:100%}.session-console-body.has-translation{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:10px;align-items:stretch}.terminal-pane,.translation-pane{display:grid;min-width:0;min-height:0;height:100%}.terminal-frame,.terminal-empty{width:100%;height:100%;min-height:0;border-radius:6px;overflow:hidden;background:#111316}.terminal-empty{display:grid;place-items:center;align-content:center;gap:8px;color:#d6d0c6;border:1px solid #292d31}.translation-panel{display:grid;grid-template-rows:auto minmax(0,1fr) auto;gap:8px;height:100%;min-height:0;border:1px solid #292d31;border-radius:6px;background:#0d1117;color:#d6deeb;padding:8px;min-width:0;width:100%;overflow:hidden;font-family:Menlo,Monaco,Consolas,monospace}.translation-panel-header{display:grid;gap:3px}.translation-panel-titlebar,.translation-panel-actions,.translation-status-row{display:flex;flex-wrap:wrap;gap:6px;align-items:center;justify-content:space-between}.translation-panel-header h2,.translation-panel-header p{margin-bottom:0}.translation-panel-titlebar h2{font-size:16px}.translation-panel-header p,.translation-composer span{color:#8b949e;font-size:12px}.translation-panel-actions button{border-color:#3a4149;background:#161b22;color:#d6deeb;min-height:26px;padding:2px 8px;font-size:12px}.translation-panel-actions button:hover:not(:disabled),.translation-composer-actions button:hover:not(:disabled){border-color:#58a6ff;background:#1f2937}.translation-panel-actions .auto-send-toggle.is-active{border-color:#56d364;background:#12261a;color:#d6deeb}.translation-panel-actions{justify-content:flex-end}.translation-status-row{flex-wrap:nowrap}.translation-status-row p:last-child{flex:0 0 auto;text-align:right}.translation-entry-list{display:grid;align-content:start;gap:8px;min-height:0;min-width:0;overflow-x:hidden;overflow-y:auto;scrollbar-color:#4b5563 #0d1117}.translation-entry{border:0;border-radius:0;background:transparent;min-width:0;max-width:100%;padding:0}.translation-entry.is-user-input{border-top:4px solid #3a4149;margin-top:14px;padding-top:14px}.translation-entry.is-user-input:first-child{margin-top:0}.translation-entry pre{box-sizing:border-box;margin:0;max-height:none;max-width:100%;min-width:0;overflow:visible;white-space:pre-wrap;overflow-wrap:anywhere;font-family:Menlo,Monaco,Consolas,monospace;font-size:12px;line-height:1.45;color:#d6deeb}.translation-markdown{max-width:100%;min-width:0;color:#d6deeb;font-size:12px;line-height:1.55;overflow-wrap:anywhere}.translation-markdown>:first-child{margin-top:0}.translation-markdown>:last-child{margin-bottom:0}.translation-markdown p,.translation-markdown ul,.translation-markdown ol,.translation-markdown blockquote,.translation-markdown pre,.translation-markdown table{margin:0 0 8px}.translation-markdown h1,.translation-markdown h2,.translation-markdown h3,.translation-markdown h4,.translation-markdown h5,.translation-markdown h6{margin:10px 0 6px;color:#f0f6fc;font-weight:700;line-height:1.25}.translation-markdown h1{font-size:17px}.translation-markdown h2{font-size:15px}.translation-markdown h3,.translation-markdown h4,.translation-markdown h5,.translation-markdown h6{font-size:13px}.translation-markdown ul,.translation-markdown ol{padding-left:22px}.translation-markdown li{margin:2px 0}.translation-markdown .task-list-item{list-style:none}.translation-markdown input[type=checkbox]{width:13px;height:13px;margin:0 6px 0 0;accent-color:#56d364}.translation-markdown blockquote{border-left:3px solid #3a4149;color:#b7c0ca;padding-left:10px}.translation-markdown a{color:#79c0ff}.translation-markdown code{border-radius:4px;background:#161b22;color:#f0f6fc;padding:1px 4px;font-family:Menlo,Monaco,Consolas,monospace;font-size:.95em}.translation-markdown pre{overflow-x:auto;border:1px solid #292d31;border-radius:6px;background:#111316;padding:8px;white-space:pre}.translation-markdown pre code{background:transparent;padding:0}.translation-markdown table{display:block;max-width:100%;overflow-x:auto;border-collapse:collapse}.translation-markdown img{max-width:100%;border-radius:4px}.translation-markdown th,.translation-markdown td{border:1px solid #30363d;padding:4px 6px;text-align:left;vertical-align:top}.translation-markdown hr{border:0;border-top:1px solid #292d31;margin:10px 0}.translation-entry.is-tool-output pre{display:block;overflow:hidden;color:#7d8590;text-overflow:ellipsis;white-space:nowrap;width:100%}.translation-entry-note{margin:2px 0 0;color:#6e7681;font-size:10px;line-height:1.35}.translation-entry-note.is-error{color:#a3715f}.translation-composer{display:grid;gap:6px;border-top:1px solid #292d31;padding-top:8px}.translation-composer-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:stretch}.translation-composer textarea{width:100%;min-height:38px;max-height:88px;border-color:#3a4149;background:#0d1117;color:#d6deeb;font-family:inherit;font-size:12px;line-height:1.35;resize:vertical}.translation-composer textarea::placeholder{color:#7d8590}.translation-composer textarea::selection{background:#8b949e59;color:#fff}.translation-composer textarea:focus,.translation-composer textarea:focus-visible{border-color:#4b5563;outline:none;box-shadow:none}.translation-composer-actions{display:grid;align-content:start;gap:6px;min-width:104px}.translation-composer-actions button{border-color:#3a4149;background:#161b22;color:#d6deeb;width:100%;min-height:38px;padding:4px 9px;font-size:12px}.translation-panel .muted{color:#8b949e}.translation-panel .error-banner{border-color:#da7b72;background:#2d1518;color:#ffdcd7}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:20;display:grid;place-items:center;background:#181c1f61;padding:18px}.translation-settings-modal{display:grid;gap:12px;width:min(980px,100%);max-height:min(760px,92vh);overflow:auto;border:1px solid #d6d0c6;border-radius:8px;background:#fffdf8;padding:14px}.message-modal,.event-modal{display:grid;grid-template-rows:auto minmax(0,1fr);gap:12px;width:min(980px,100%);max-height:min(760px,92vh);overflow:hidden;border:1px solid #d6d0c6;border-radius:8px;background:#fffdf8;padding:14px}.translation-settings-modal header,.message-modal header,.event-modal header,.translation-settings-modal footer{display:flex;gap:8px;align-items:center;justify-content:space-between}.translation-prompt-settings{display:grid;gap:10px;border-top:1px solid #ece5d9;padding-top:12px}.translation-prompt-settings header{display:flex;gap:10px;align-items:end;justify-content:space-between}.translation-prompt-settings h3,.translation-prompt-settings p{margin-bottom:0}.translation-prompt-settings h3{font-size:13px}.translation-prompt-settings textarea{min-height:120px;max-height:260px;font-family:Menlo,Monaco,Consolas,monospace;font-size:12px}.translation-prompt-stack{display:grid;gap:10px}.translation-prompt-stack label{display:grid;gap:4px}.translation-prompt-stack span{color:#4f5558;font-size:12px;font-weight:650}.translation-settings-modal h2,.message-modal h2,.message-modal p,.event-modal h2,.event-modal p,.translation-settings-modal p{margin-bottom:0}.translation-settings-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.translation-settings-grid label{display:grid;gap:4px}.translation-settings-grid span{color:#4f5558;font-size:12px;font-weight:650}.translation-settings-grid select,.translation-prompt-settings select{min-height:34px;border:1px solid #b9b0a1;border-radius:6px;background:#fffdf8;color:#202326;padding:6px 10px}.translation-test-result{border-radius:6px;padding:8px;font-size:13px}.translation-test-result.is-ok{border:1px solid #6ea77e;background:#e6f3e9;color:#245334}.translation-test-result.is-error{border:1px solid #c46e5f;background:#fae9e6;color:#6f2b21}.message-panel{display:grid;gap:8px}.message-modal .message-panel,.event-modal .event-log{min-height:0;overflow:auto;border:0;background:transparent;padding:0}.message-panel-header{display:flex;justify-content:space-between;gap:12px;align-items:center}.message-panel-header h2,.message-panel-header p{margin-bottom:0}.message-controls,.message-mode-toggle,.message-actions{display:flex;flex-wrap:wrap;gap:8px;align-items:center}.message-mode-toggle{color:#4f5558;font-size:13px;font-weight:650}.message-mode-toggle input{width:auto}.message-list{display:grid;gap:8px;margin:0;padding:0;list-style:none}.message-item{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:10px;align-items:start;border:1px solid #ece5d9;border-radius:6px;padding:8px;background:#fffdfa}.message-meta{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:4px}.message-meta time,.message-meta span:not(.status-badge),.message-path{color:#667071;font-size:12px}.message-sequence{min-width:32px;color:#1f242b;font-weight:800}.message-actions button{min-height:30px;padding:4px 10px}.message-item p{display:-webkit-box;margin-bottom:4px;overflow:hidden;-webkit-box-orient:vertical;-webkit-line-clamp:2}.message-path{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.event-log ol{margin:0;padding-left:22px;font-size:13px}.event-log{max-height:92px;overflow:auto}.event-log h2{margin-bottom:4px;font-size:13px}.event-log p{margin-bottom:0}.event-log li{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.status-badge{display:inline-flex;align-items:center;justify-content:center;min-width:66px;min-height:20px;border-radius:999px;padding:2px 8px;border:1px solid #c7c1b8;background:#f2eee7;color:#4f5558;font-size:11px;white-space:nowrap}.status-running,.status-ok{border-color:#6ea77e;background:#e6f3e9;color:#245334}.status-blocked,.status-crashed,.status-missing,.status-empty{border-color:#c46e5f;background:#fae9e6;color:#6f2b21}.status-waiting,.status-starting,.status-incomplete{border-color:#c4a34e;background:#f7efcf;color:#604e16}.status-exited,.status-done,.status-resumable,.status-staged,.status-delivered,.status-acknowledged{border-color:#7b98b8;background:#e9f0f8;color:#2e4e70}.status-pending_approval,.status-queued,.status-translating,.status-ready,.status-create,.status-insert,.status-update{border-color:#c4a34e;background:#f7efcf;color:#604e16}.status-rejected,.status-failed,.status-cancelled,.status-blocked{border-color:#c46e5f;background:#fae9e6;color:#6f2b21}.status-pending{border-color:#c7c1b8;background:#f2eee7;color:#4f5558}.status-translated,.status-preserved{border-color:#7b98b8;background:#e9f0f8;color:#2e4e70}.empty-workspace{max-width:680px}@media(max-width:980px){.app-shell,.workspace-grid{grid-template-columns:1fr}.app-sidebar{border-right:0;border-bottom:1px solid #d3c9b8}.role-tabs{grid-template-columns:repeat(2,minmax(0,1fr))}.workflow-panel,.workflow-steps,.session-console-body.has-translation,.translation-settings-grid{grid-template-columns:1fr}}@media(max-width:560px){.app-main,.app-sidebar{padding:12px}.workspace-header,.inline-form,.inline-form.has-recent-paths{grid-template-columns:1fr;display:grid}.role-tabs{grid-template-columns:1fr}.terminal-frame,.terminal-empty{min-height:300px;height:54vh}.permission-mode-field{grid-template-columns:1fr;width:100%}}:root[data-theme=dark]{color-scheme:dark;background:#0d1117;color:#e6edf3}:root[data-theme=dark] body,:root[data-theme=dark] .app-main{background:#0d1117;color:#e6edf3}:root[data-theme=dark] button{border-color:#3d4652;background:#161b22;color:#e6edf3}:root[data-theme=dark] button:hover:not(:disabled){border-color:#58a6ff;background:#1f2937}:root[data-theme=dark] input,:root[data-theme=dark] select,:root[data-theme=dark] textarea:not(.xterm-helper-textarea){border-color:#3d4652;background:#0d1117;color:#e6edf3}:root[data-theme=dark] input::placeholder,:root[data-theme=dark] textarea::placeholder{color:#7d8590}:root[data-theme=dark] .danger-button{border-color:#da7b72;background:#2d1518;color:#ffdcd7}:root[data-theme=dark] .danger-button:hover:not(:disabled){border-color:#ffa198;background:#3d1f23}:root[data-theme=dark] .app-sidebar{border-color:#30363d;background:#0f141b}:root[data-theme=dark] .sidebar-toggle{background:#161b22}:root[data-theme=dark] .brand-header span,:root[data-theme=dark] .muted,:root[data-theme=dark] .workspace-branch,:root[data-theme=dark] .workspace-worktree,:root[data-theme=dark] .message-meta time,:root[data-theme=dark] .message-meta span:not(.status-badge),:root[data-theme=dark] .message-path{color:#8b949e}:root[data-theme=dark] .sidebar-section,:root[data-theme=dark] .session-console,:root[data-theme=dark] .message-panel,:root[data-theme=dark] .event-log,:root[data-theme=dark] .empty-workspace,:root[data-theme=dark] .translation-settings-modal,:root[data-theme=dark] .message-modal,:root[data-theme=dark] .event-modal{border-color:#30363d;background:#11161d}:root[data-theme=dark] .sidebar-section-toggle{color:#e6edf3}:root[data-theme=dark] .sidebar-section-toggle:hover{background:#161b22}:root[data-theme=dark] .sidebar-section-toggle[aria-expanded=true],:root[data-theme=dark] .translation-prompt-settings{border-color:#30363d}:root[data-theme=dark] .project-summary dt,:root[data-theme=dark] .permission-mode-field span,:root[data-theme=dark] .translation-settings-grid span,:root[data-theme=dark] .translation-prompt-stack span,:root[data-theme=dark] .message-mode-toggle,:root[data-theme=dark] .workflow-summary p{color:#b7c0ca}:root[data-theme=dark] .permission-mode-field small,:root[data-theme=dark] .task-create-preview small{color:#8b949e}:root[data-theme=dark] .warnings,:root[data-theme=dark] .error-banner{border-color:#da7b72;background:#2d1518;color:#ffdcd7}:root[data-theme=dark] .harness-file-list li,:root[data-theme=dark] .harness-changes,:root[data-theme=dark] .harness-result,:root[data-theme=dark] .task-create-preview,:root[data-theme=dark] .workflow-steps li,:root[data-theme=dark] .message-item{border-color:#30363d;background:#0d1117}:root[data-theme=dark] .task-create-option{color:#e6edf3}:root[data-theme=dark] .task-create-preview span{color:#7ee787}:root[data-theme=dark] .workflow-steps span{color:#d6deeb}:root[data-theme=dark] .message-sequence{color:#f0f6fc}:root[data-theme=dark] .eyebrow{color:#d29922}:root[data-theme=dark] .task-nav-item.is-active,:root[data-theme=dark] .role-tab.is-active,:root[data-theme=dark] .workflow-steps li.is-current,:root[data-theme=dark] .sidebar-settings .settings-toggle.is-active,:root[data-theme=dark] .translation-toggle.is-active{border-color:#56d4dd;background:#10262b;color:#d6fbff}:root[data-theme=dark] .translation-toggle{border-color:#3d4652;background:#161b22;color:#b7c0ca}:root[data-theme=dark] .permission-mode-field select,:root[data-theme=dark] .translation-settings-grid select,:root[data-theme=dark] .translation-prompt-settings select{border-color:#3d4652;background:#0d1117;color:#e6edf3}:root[data-theme=dark] .terminal-empty{border-color:#30363d}:root[data-theme=dark] .modal-backdrop{background:#010409b8}:root[data-theme=dark] .message-modal .message-panel,:root[data-theme=dark] .event-modal .event-log{background:transparent}:root[data-theme=dark] .status-badge{border-color:#3d4652;background:#161b22;color:#d6deeb}:root[data-theme=dark] .translation-test-result.is-ok,:root[data-theme=dark] .status-running,:root[data-theme=dark] .status-ok{border-color:#3fb950;background:#12261a;color:#aff5b4}:root[data-theme=dark] .translation-test-result.is-error,:root[data-theme=dark] .status-blocked,:root[data-theme=dark] .status-crashed,:root[data-theme=dark] .status-missing,:root[data-theme=dark] .status-empty,:root[data-theme=dark] .status-rejected,:root[data-theme=dark] .status-failed,:root[data-theme=dark] .status-cancelled{border-color:#f85149;background:#2d1518;color:#ffdcd7}:root[data-theme=dark] .status-waiting,:root[data-theme=dark] .status-starting,:root[data-theme=dark] .status-incomplete,:root[data-theme=dark] .status-pending_approval,:root[data-theme=dark] .status-queued,:root[data-theme=dark] .status-translating,:root[data-theme=dark] .status-ready,:root[data-theme=dark] .status-create,:root[data-theme=dark] .status-insert,:root[data-theme=dark] .status-update{border-color:#d29922;background:#2d2208;color:#f8e3a1}:root[data-theme=dark] .status-exited,:root[data-theme=dark] .status-done,:root[data-theme=dark] .status-resumable,:root[data-theme=dark] .status-staged,:root[data-theme=dark] .status-delivered,:root[data-theme=dark] .status-acknowledged,:root[data-theme=dark] .status-translated,:root[data-theme=dark] .status-preserved{border-color:#388bfd;background:#10223a;color:#c9e2ff}:root[data-theme=dark] .status-pending{border-color:#3d4652;background:#161b22;color:#d6deeb}
|