vibe-coding-master 0.0.10 → 0.0.12

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 CHANGED
@@ -181,7 +181,7 @@ VCM will not offer a separate `Create task worktree` button after a task exists,
181
181
 
182
182
  Because worktrees live under `.ai/vcm/worktrees/`, the connected repository must ignore `.ai/vcm/`. Apply the VCM Harness before creating tasks so `.gitignore` contains the managed ignore block. The base repository must also be clean because the task branch/worktree is created from the connected repo's current `HEAD`.
183
183
 
184
- When a task is complete, VCM provides a red `Close Task` action. Closing a worktree-backed task shows a destructive confirmation, then deletes the task worktree, deletes the task branch by default, removes the base task index entry, and removes task runtime metadata. VCM does not check running sessions or uncommitted changes before closing. Tasks created without a worktree only remove VCM metadata because they do not own a separate branch/worktree.
184
+ When a task is complete, VCM provides a red `Close Task` action. Closing a task shows a destructive confirmation, stops VCM-managed running role sessions for that task, then deletes the task worktree, deletes the task branch by default, removes the base task index entry, and removes task runtime metadata. VCM does not preflight running sessions or uncommitted changes before closing. Tasks created without a worktree only remove VCM metadata because they do not own a separate branch/worktree.
185
185
 
186
186
  ## Sidebar UI
187
187
 
@@ -207,7 +207,7 @@ Translation settings are local and stored in:
207
207
  ~/.vcm/settings.json
208
208
  ```
209
209
 
210
- The same file stores recent repository paths. The translation API key is stored locally under `translation.secrets.apiKey`; it is not written to the connected repository, `.ai/handoffs`, raw terminal logs, or git diffs.
210
+ The same file stores recent repository paths. The translation API key is stored locally under `translation.secrets.apiKey`; it is not written to the connected repository, `.ai/vcm/handoffs`, raw terminal logs, or git diffs.
211
211
 
212
212
  The sidebar `Settings` section also stores the UI theme preference in this file. The default is `system`, which follows the OS/browser color-scheme preference; users can cycle between `System`, `Light`, and `Dark`.
213
213
 
@@ -283,18 +283,18 @@ Examples that roles can run inside their terminal:
283
283
  ```bash
284
284
  vcmctl send --to coder --type task --body-file /tmp/message.md
285
285
  vcmctl reply --type blocked --body "Need clarification."
286
- vcmctl result --body-file /tmp/result.md --artifact .ai/handoffs/task/implementation-log.md
286
+ vcmctl result --body-file /tmp/result.md --artifact .ai/vcm/handoffs/implementation-log.md
287
287
  vcmctl inbox
288
288
  ```
289
289
 
290
- Durable message and handoff files:
290
+ Runtime message and handoff files:
291
291
 
292
292
  ```text
293
293
  .ai/vcm/messages/<task>.jsonl # under the task runtime repo
294
294
  .ai/vcm/orchestration/<task>.json # under the task runtime repo
295
- .ai/handoffs/<task>/messages/<message-id>.md
296
- .ai/handoffs/<task>/role-commands/
297
- .ai/handoffs/<task>/logs/
295
+ .ai/vcm/handoffs/messages/<message-id>.md
296
+ .ai/vcm/handoffs/role-commands/
297
+ .ai/vcm/handoffs/logs/
298
298
  ```
299
299
 
300
300
  The backend also keeps a compatibility role-command dispatch endpoint, but the primary workflow is PM-mediated `vcmctl` messaging.
@@ -308,8 +308,9 @@ When it is off, VCM is in manual mode:
308
308
  - Roles may send messages through `vcmctl`.
309
309
  - Messages appear in the `Messages` modal.
310
310
  - The user can inspect them.
311
- - Clicking `Stage` writes a prompt into the target embedded terminal input line.
312
- - VCM does not press Enter for the user.
311
+ - The current GUI shows sequence, timestamp, status, body preview, path, and a `Copy` button for each message.
312
+ - The user decides what to do next by copying or manually acting on the message.
313
+ - VCM does not write to the target terminal or press Enter for the user.
313
314
 
314
315
  When it is on, VCM is in auto mode:
315
316
 
@@ -320,6 +321,8 @@ When it is on, VCM is in auto mode:
320
321
 
321
322
  The backend state model still contains a `paused` field for compatibility with existing API routes, but the current GUI exposes only a single on/off orchestration toggle.
322
323
 
324
+ The backend still exposes stage/approve/reject compatibility APIs for automation and future UI work. They are not primary controls in the current Messages modal.
325
+
323
326
  ## Resume Behavior
324
327
 
325
328
  Each role session stores its Claude session id and transcript path under:
@@ -347,17 +350,19 @@ For a connected repository, VCM uses:
347
350
  <taskRepoRoot>/.ai/vcm/messages/<task>.jsonl
348
351
  <taskRepoRoot>/.ai/vcm/orchestration/<task>.json
349
352
  <taskRepoRoot>/.ai/vcm/translation/<task>/
350
- <taskRepoRoot>/.ai/handoffs/<task>/architecture-plan.md
351
- <taskRepoRoot>/.ai/handoffs/<task>/implementation-log.md
352
- <taskRepoRoot>/.ai/handoffs/<task>/validation-log.md
353
- <taskRepoRoot>/.ai/handoffs/<task>/review-report.md
354
- <taskRepoRoot>/.ai/handoffs/<task>/docs-sync-report.md
355
- <taskRepoRoot>/.ai/handoffs/<task>/role-commands/{architect,coder,reviewer}.md
356
- <taskRepoRoot>/.ai/handoffs/<task>/logs/{project-manager,architect,coder,reviewer}.log
353
+ <taskRepoRoot>/.ai/vcm/handoffs/architecture-plan.md
354
+ <taskRepoRoot>/.ai/vcm/handoffs/implementation-log.md
355
+ <taskRepoRoot>/.ai/vcm/handoffs/validation-log.md
356
+ <taskRepoRoot>/.ai/vcm/handoffs/review-report.md
357
+ <taskRepoRoot>/.ai/vcm/handoffs/docs-sync-report.md
358
+ <taskRepoRoot>/.ai/vcm/handoffs/role-commands/{architect,coder,reviewer}.md
359
+ <taskRepoRoot>/.ai/vcm/handoffs/logs/{project-manager,architect,coder,reviewer}.log
357
360
  ```
358
361
 
359
362
  The project config is stored under `~/.vcm` so it is durable local app state and is not hidden inside a Git-ignored repository directory. For worktree-backed tasks, `taskRepoRoot` is `<baseRepoRoot>/.ai/vcm/worktrees/<task>`; for inline tasks, `taskRepoRoot` is the connected base repo.
360
363
 
364
+ Because handoffs are scoped to `taskRepoRoot` without an extra task-name directory, VCM allows only one active inline task per connected repository. Use the default worktree mode for parallel tasks.
365
+
361
366
  ## Packaging
362
367
 
363
368
  The npm package publishes built output, not raw TypeScript entry files. `package.json` includes:
@@ -20,10 +20,19 @@ export function registerTaskRoutes(app, deps) {
20
20
  app.post("/api/tasks/:taskSlug/cleanup", async (request) => {
21
21
  const project = await requireCurrentProject(deps.projectService);
22
22
  const task = await deps.taskService.loadTask(project.repoRoot, request.params.taskSlug);
23
+ await stopRunningRoleSessions(deps, project.repoRoot, request.params.taskSlug);
23
24
  await deps.translationService.stopTask(getTaskRuntimeRepoRoot(task), request.params.taskSlug, { clearCache: true });
24
25
  return deps.taskService.cleanupTask(project.repoRoot, request.params.taskSlug, request.body ?? {});
25
26
  });
26
27
  }
28
+ async function stopRunningRoleSessions(deps, repoRoot, taskSlug) {
29
+ const sessions = await deps.sessionService.listRoleSessions(repoRoot, taskSlug);
30
+ for (const session of sessions) {
31
+ if (session.status === "running") {
32
+ await deps.sessionService.stopRoleSession(repoRoot, taskSlug, session.role);
33
+ }
34
+ }
35
+ }
27
36
  async function requireCurrentProject(projectService) {
28
37
  const project = await projectService.getCurrentProject();
29
38
  if (!project) {
@@ -54,6 +54,7 @@ export async function createServer(deps, options = {}) {
54
54
  registerTaskRoutes(app, {
55
55
  projectService: deps.projectService,
56
56
  taskService: deps.taskService,
57
+ sessionService: deps.sessionService,
57
58
  statusService: deps.statusService,
58
59
  translationService: deps.translationService
59
60
  });
@@ -1,7 +1,7 @@
1
1
  import path from "node:path";
2
2
  import { ROLE_NAMES } from "../../shared/constants.js";
3
3
  import { VcmError } from "../errors.js";
4
- const DEFAULT_HANDOFF_ROOT = ".ai/handoffs";
4
+ const DEFAULT_HANDOFF_ROOT = ".ai/vcm/handoffs";
5
5
  const DEFAULT_STATE_ROOT = ".ai/vcm";
6
6
  export function createProjectService(deps) {
7
7
  let currentProject = null;
@@ -116,7 +116,7 @@ function normalizeProjectConfig(input, repoRoot) {
116
116
  version: 1,
117
117
  repoRoot,
118
118
  defaultRoles: input.defaultRoles?.length ? input.defaultRoles : fallback.defaultRoles,
119
- handoffRoot: input.handoffRoot || fallback.handoffRoot,
119
+ handoffRoot: DEFAULT_HANDOFF_ROOT,
120
120
  stateRoot: DEFAULT_STATE_ROOT,
121
121
  terminalBackend: "node-pty",
122
122
  claudeCommand: input.claudeCommand || fallback.claudeCommand
@@ -30,6 +30,17 @@ export function createTaskService(deps) {
30
30
  hint: "Apply VCM Harness first so .gitignore contains the VCM managed block."
31
31
  });
32
32
  }
33
+ if (!shouldCreateWorktree) {
34
+ const activeInlineTask = await findActiveInlineTask(deps.fs, repoRoot, config.stateRoot);
35
+ if (activeInlineTask) {
36
+ throw new VcmError({
37
+ code: "INLINE_TASK_EXISTS",
38
+ message: `An inline task already exists: ${activeInlineTask.taskSlug}`,
39
+ statusCode: 409,
40
+ hint: "Close the existing inline task first, or enable Create worktree and branch for this task."
41
+ });
42
+ }
43
+ }
33
44
  if (shouldCreateWorktree && worktreePath) {
34
45
  if (await deps.git.branchExists(repoRoot, taskBranch)) {
35
46
  throw new VcmError({
@@ -75,7 +86,7 @@ export function createTaskService(deps) {
75
86
  repoRoot,
76
87
  worktreePath,
77
88
  branch: taskBranch,
78
- handoffDir: path.posix.join(config.handoffRoot, input.taskSlug),
89
+ handoffDir: config.handoffRoot,
79
90
  status: "created",
80
91
  specPath: input.specPath,
81
92
  cleanupStatus: "active"
@@ -146,7 +157,7 @@ export function createTaskService(deps) {
146
157
  const config = await deps.projectService.loadConfig(repoRoot);
147
158
  const task = await this.loadTask(repoRoot, taskSlug);
148
159
  const taskRepoRoot = getTaskRuntimeRepoRoot(task);
149
- const statePaths = getTaskStatePaths(repoRoot, taskRepoRoot, config.stateRoot, taskSlug);
160
+ const statePaths = getTaskStatePaths(repoRoot, taskRepoRoot, config.stateRoot, config.handoffRoot, taskSlug);
150
161
  const removedStatePaths = [];
151
162
  const cleanedAt = now();
152
163
  if (task.worktreePath) {
@@ -187,13 +198,28 @@ async function ensureTaskRuntimeStateDirs(fs, taskRepoRoot, stateRoot) {
187
198
  await fs.ensureDir(path.join(taskRepoRoot, stateRoot, "orchestration"));
188
199
  await fs.ensureDir(path.join(taskRepoRoot, stateRoot, "translation"));
189
200
  }
190
- function getTaskStatePaths(baseRepoRoot, taskRepoRoot, stateRoot, taskSlug) {
201
+ async function findActiveInlineTask(fs, repoRoot, stateRoot) {
202
+ const tasksDir = path.join(repoRoot, stateRoot, "tasks");
203
+ if (!(await fs.pathExists(tasksDir))) {
204
+ return undefined;
205
+ }
206
+ const entries = await fs.readDir(tasksDir);
207
+ for (const entry of entries.filter((candidate) => candidate.endsWith(".json"))) {
208
+ const task = await fs.readJson(path.join(tasksDir, entry));
209
+ if (!task.worktreePath && task.cleanupStatus !== "cleaned") {
210
+ return task;
211
+ }
212
+ }
213
+ return undefined;
214
+ }
215
+ function getTaskStatePaths(baseRepoRoot, taskRepoRoot, stateRoot, handoffRoot, taskSlug) {
191
216
  return [
192
217
  path.join(baseRepoRoot, stateRoot, "tasks", `${taskSlug}.json`),
193
218
  path.join(taskRepoRoot, stateRoot, "sessions", `${taskSlug}.json`),
194
219
  path.join(taskRepoRoot, stateRoot, "messages", `${taskSlug}.jsonl`),
195
220
  path.join(taskRepoRoot, stateRoot, "orchestration", `${taskSlug}.json`),
196
- path.join(taskRepoRoot, stateRoot, "translation", taskSlug)
221
+ path.join(taskRepoRoot, stateRoot, "translation", taskSlug),
222
+ path.join(taskRepoRoot, handoffRoot)
197
223
  ];
198
224
  }
199
225
  function assertTaskWorktreePath(repoRoot, stateRoot, worktreePath) {
@@ -3,9 +3,9 @@ export function renderRootClaudeHarnessRules() {
3
3
 
4
4
  - This repository uses VibeCodingMaster for multi-session Claude Code work.
5
5
  - User-facing work starts with the project-manager role.
6
- - Canonical task handoffs live under .ai/handoffs/<task-slug>/.
6
+ - Canonical task handoffs live under .ai/vcm/handoffs/ inside the current task runtime repo.
7
7
  - Use only the current task's handoff directory for task-specific artifacts.
8
- - Do not create or write .ai/handoffs/<other-task>/ for the current task.
8
+ - Do not create or write task handoffs outside .ai/vcm/handoffs/ for the current task.
9
9
  - Use vcmctl for role-to-role messaging instead of asking the user to copy prompts.
10
10
  - Non-PM roles only reply to project-manager; they do not message other roles directly.
11
11
  - High-risk decisions involving schema, auth, permissions, payment, billing, security, data deletion, or unclear user intent must stop for project-manager/user approval.
@@ -131,7 +131,7 @@ function printHelp() {
131
131
  Usage:
132
132
  vcmctl send --to coder --type task --body-file /tmp/message.md
133
133
  vcmctl reply --type blocked --body "Need clarification."
134
- vcmctl result --body-file /tmp/result.md --artifact .ai/handoffs/task/implementation-log.md
134
+ vcmctl result --body-file /tmp/result.md --artifact .ai/vcm/handoffs/implementation-log.md
135
135
  vcmctl inbox
136
136
  `);
137
137
  }
@@ -29,4 +29,4 @@
29
29
  * The original design remains. The terminal itself
30
30
  * has been extended to include xterm CSI codes, among
31
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 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}
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}
@@ -83,6 +83,6 @@ WARNING: This link could potentially be dangerous`)){const p=window.open();if(p)
83
83
  `))+1))}const _="#".repeat(S),a=l.enter("headingAtx"),u=l.enter("phrasing");b.move(_+" ");let h=l.containerPhrasing(i,{before:"# ",after:`
84
84
  `,...b.current()});return/^[\t ]/.test(h)&&(h=Os(h.charCodeAt(0))+h.slice(1)),h=h?_+" "+h:_,l.options.closeAtx&&(h+=" "+_),u(),a(),h}bm.peek=ZC;function bm(i){return i.value||""}function ZC(){return"<"}Cm.peek=JC;function Cm(i,s,l,o){const S=Tc(l),b=S==='"'?"Quote":"Apostrophe",_=l.enter("image");let a=l.enter("label");const u=l.createTracker(o);let h=u.move("![");return h+=u.move(l.safe(i.alt,{before:h,after:"]",...u.current()})),h+=u.move("]("),a(),!i.url&&i.title||/[\0- \u007F]/.test(i.url)?(a=l.enter("destinationLiteral"),h+=u.move("<"),h+=u.move(l.safe(i.url,{before:h,after:">",...u.current()})),h+=u.move(">")):(a=l.enter("destinationRaw"),h+=u.move(l.safe(i.url,{before:h,after:i.title?" ":")",...u.current()}))),a(),i.title&&(a=l.enter(`title${b}`),h+=u.move(" "+S),h+=u.move(l.safe(i.title,{before:h,after:S,...u.current()})),h+=u.move(S),a()),h+=u.move(")"),_(),h}function JC(){return"!"}wm.peek=ew;function wm(i,s,l,o){const S=i.referenceType,b=l.enter("imageReference");let _=l.enter("label");const a=l.createTracker(o);let u=a.move("![");const h=l.safe(i.alt,{before:u,after:"]",...a.current()});u+=a.move(h+"]["),_();const g=l.stack;l.stack=[],_=l.enter("reference");const c=l.safe(l.associationId(i),{before:u,after:"]",...a.current()});return _(),l.stack=g,b(),S==="full"||!h||h!==c?u+=a.move(c+"]"):S==="shortcut"?u=u.slice(0,-1):u+=a.move("]"),u}function ew(){return"!"}xm.peek=tw;function xm(i,s,l){let o=i.value||"",S="`",b=-1;for(;new RegExp("(^|[^`])"+S+"([^`]|$)").test(o);)S+="`";for(/[^ \r\n]/.test(o)&&(/^[ \r\n]/.test(o)&&/[ \r\n]$/.test(o)||/^`|`$/.test(o))&&(o=" "+o+" ");++b<l.unsafe.length;){const _=l.unsafe[b],a=l.compilePattern(_);let u;if(_.atBreak)for(;u=a.exec(o);){let h=u.index;o.charCodeAt(h)===10&&o.charCodeAt(h-1)===13&&h--,o=o.slice(0,h)+" "+o.slice(u.index+1)}}return S+o+S}function tw(){return"`"}function Em(i,s){const l=Sc(i);return!!(!s.options.resourceLink&&i.url&&!i.title&&i.children&&i.children.length===1&&i.children[0].type==="text"&&(l===i.url||"mailto:"+l===i.url)&&/^[a-z][a-z+.-]+:/i.test(i.url)&&!/[\0- <>\u007F]/.test(i.url))}km.peek=iw;function km(i,s,l,o){const S=Tc(l),b=S==='"'?"Quote":"Apostrophe",_=l.createTracker(o);let a,u;if(Em(i,l)){const g=l.stack;l.stack=[],a=l.enter("autolink");let c=_.move("<");return c+=_.move(l.containerPhrasing(i,{before:c,after:">",..._.current()})),c+=_.move(">"),a(),l.stack=g,c}a=l.enter("link"),u=l.enter("label");let h=_.move("[");return h+=_.move(l.containerPhrasing(i,{before:h,after:"](",..._.current()})),h+=_.move("]("),u(),!i.url&&i.title||/[\0- \u007F]/.test(i.url)?(u=l.enter("destinationLiteral"),h+=_.move("<"),h+=_.move(l.safe(i.url,{before:h,after:">",..._.current()})),h+=_.move(">")):(u=l.enter("destinationRaw"),h+=_.move(l.safe(i.url,{before:h,after:i.title?" ":")",..._.current()}))),u(),i.title&&(u=l.enter(`title${b}`),h+=_.move(" "+S),h+=_.move(l.safe(i.title,{before:h,after:S,..._.current()})),h+=_.move(S),u()),h+=_.move(")"),a(),h}function iw(i,s,l){return Em(i,l)?"<":"["}Am.peek=nw;function Am(i,s,l,o){const S=i.referenceType,b=l.enter("linkReference");let _=l.enter("label");const a=l.createTracker(o);let u=a.move("[");const h=l.containerPhrasing(i,{before:u,after:"]",...a.current()});u+=a.move(h+"]["),_();const g=l.stack;l.stack=[],_=l.enter("reference");const c=l.safe(l.associationId(i),{before:u,after:"]",...a.current()});return _(),l.stack=g,b(),S==="full"||!h||h!==c?u+=a.move(c+"]"):S==="shortcut"?u=u.slice(0,-1):u+=a.move("]"),u}function nw(){return"["}function Dc(i){const s=i.options.bullet||"*";if(s!=="*"&&s!=="+"&&s!=="-")throw new Error("Cannot serialize items with `"+s+"` for `options.bullet`, expected `*`, `+`, or `-`");return s}function rw(i){const s=Dc(i),l=i.options.bulletOther;if(!l)return s==="*"?"-":"*";if(l!=="*"&&l!=="+"&&l!=="-")throw new Error("Cannot serialize items with `"+l+"` for `options.bulletOther`, expected `*`, `+`, or `-`");if(l===s)throw new Error("Expected `bullet` (`"+s+"`) and `bulletOther` (`"+l+"`) to be different");return l}function sw(i){const s=i.options.bulletOrdered||".";if(s!=="."&&s!==")")throw new Error("Cannot serialize items with `"+s+"` for `options.bulletOrdered`, expected `.` or `)`");return s}function Tm(i){const s=i.options.rule||"*";if(s!=="*"&&s!=="-"&&s!=="_")throw new Error("Cannot serialize rules with `"+s+"` for `options.rule`, expected `*`, `-`, or `_`");return s}function lw(i,s,l,o){const S=l.enter("list"),b=l.bulletCurrent;let _=i.ordered?sw(l):Dc(l);const a=i.ordered?_==="."?")":".":rw(l);let u=s&&l.bulletLastUsed?_===l.bulletLastUsed:!1;if(!i.ordered){const g=i.children?i.children[0]:void 0;if((_==="*"||_==="-")&&g&&(!g.children||!g.children[0])&&l.stack[l.stack.length-1]==="list"&&l.stack[l.stack.length-2]==="listItem"&&l.stack[l.stack.length-3]==="list"&&l.stack[l.stack.length-4]==="listItem"&&l.indexStack[l.indexStack.length-1]===0&&l.indexStack[l.indexStack.length-2]===0&&l.indexStack[l.indexStack.length-3]===0&&(u=!0),Tm(l)===_&&g){let c=-1;for(;++c<i.children.length;){const C=i.children[c];if(C&&C.type==="listItem"&&C.children&&C.children[0]&&C.children[0].type==="thematicBreak"){u=!0;break}}}}u&&(_=a),l.bulletCurrent=_;const h=l.containerFlow(i,o);return l.bulletLastUsed=_,l.bulletCurrent=b,S(),h}function aw(i){const s=i.options.listItemIndent||"one";if(s!=="tab"&&s!=="one"&&s!=="mixed")throw new Error("Cannot serialize items with `"+s+"` for `options.listItemIndent`, expected `tab`, `one`, or `mixed`");return s}function ow(i,s,l,o){const S=aw(l);let b=l.bulletCurrent||Dc(l);s&&s.type==="list"&&s.ordered&&(b=(typeof s.start=="number"&&s.start>-1?s.start:1)+(l.options.incrementListMarker===!1?0:s.children.indexOf(i))+b);let _=b.length+1;(S==="tab"||S==="mixed"&&(s&&s.type==="list"&&s.spread||i.spread))&&(_=Math.ceil(_/4)*4);const a=l.createTracker(o);a.move(b+" ".repeat(_-b.length)),a.shift(_);const u=l.enter("listItem"),h=l.indentLines(l.containerFlow(i,a.current()),g);return u(),h;function g(c,C,w){return C?(w?"":" ".repeat(_))+c:(w?b:b+" ".repeat(_-b.length))+c}}function uw(i,s,l,o){const S=l.enter("paragraph"),b=l.enter("phrasing"),_=l.containerPhrasing(i,o);return b(),S(),_}const cw=da(["break","delete","emphasis","footnote","footnoteReference","image","imageReference","inlineCode","inlineMath","link","linkReference","mdxJsxTextElement","mdxTextExpression","strong","text","textDirective"]);function hw(i,s,l,o){return(i.children.some(function(_){return cw(_)})?l.containerPhrasing:l.containerFlow).call(l,i,o)}function fw(i){const s=i.options.strong||"*";if(s!=="*"&&s!=="_")throw new Error("Cannot serialize strong with `"+s+"` for `options.strong`, expected `*`, or `_`");return s}Dm.peek=dw;function Dm(i,s,l,o){const S=fw(l),b=l.enter("strong"),_=l.createTracker(o),a=_.move(S+S);let u=_.move(l.containerPhrasing(i,{after:S,before:a,..._.current()}));const h=u.charCodeAt(0),g=oa(o.before.charCodeAt(o.before.length-1),h,S);g.inside&&(u=Os(h)+u.slice(1));const c=u.charCodeAt(u.length-1),C=oa(o.after.charCodeAt(0),c,S);C.inside&&(u=u.slice(0,-1)+Os(c));const w=_.move(S+S);return b(),l.attentionEncodeSurroundingInfo={after:C.outside,before:g.outside},a+u+w}function dw(i,s,l){return l.options.strong||"*"}function pw(i,s,l,o){return l.safe(i.value,o)}function _w(i){const s=i.options.ruleRepetition||3;if(s<3)throw new Error("Cannot serialize rules with repetition `"+s+"` for `options.ruleRepetition`, expected `3` or more");return s}function mw(i,s,l){const o=(Tm(l)+(l.options.ruleSpaces?" ":"")).repeat(_w(l));return l.options.ruleSpaces?o.slice(0,-1):o}const Rm={blockquote:UC,break:T_,code:YC,definition:KC,emphasis:ym,hardBreak:T_,heading:QC,html:bm,image:Cm,imageReference:wm,inlineCode:xm,link:km,linkReference:Am,list:lw,listItem:ow,paragraph:uw,root:hw,strong:Dm,text:pw,thematicBreak:mw};function gw(){return{enter:{table:vw,tableData:D_,tableHeader:D_,tableRow:yw},exit:{codeText:bw,table:Sw,tableData:Ju,tableHeader:Ju,tableRow:Ju}}}function vw(i){const s=i._align;this.enter({type:"table",align:s.map(function(l){return l==="none"?null:l}),children:[]},i),this.data.inTable=!0}function Sw(i){this.exit(i),this.data.inTable=void 0}function yw(i){this.enter({type:"tableRow",children:[]},i)}function Ju(i){this.exit(i)}function D_(i){this.enter({type:"tableCell",children:[]},i)}function bw(i){let s=this.resume();this.data.inTable&&(s=s.replace(/\\([\\|])/g,Cw));const l=this.stack[this.stack.length-1];l.type,l.value=s,this.exit(i)}function Cw(i,s){return s==="|"?s:i}function ww(i){const s=i||{},l=s.tableCellPadding,o=s.tablePipeAlign,S=s.stringLength,b=l?" ":"|";return{unsafe:[{character:"\r",inConstruct:"tableCell"},{character:`
85
85
  `,inConstruct:"tableCell"},{atBreak:!0,character:"|",after:"[ :-]"},{character:"|",inConstruct:"tableCell"},{atBreak:!0,character:":",after:"-"},{atBreak:!0,character:"-",after:"[:|-]"}],handlers:{inlineCode:C,table:_,tableCell:u,tableRow:a}};function _(w,T,x,v){return h(g(w,x,v),w.align)}function a(w,T,x,v){const p=c(w,x,v),d=h([p]);return d.slice(0,d.indexOf(`
86
- `))}function u(w,T,x,v){const p=x.enter("tableCell"),d=x.enter("phrasing"),m=x.containerPhrasing(w,{...v,before:b,after:b});return d(),p(),m}function h(w,T){return NC(w,{align:T,alignDelimiters:o,padding:l,stringLength:S})}function g(w,T,x){const v=w.children;let p=-1;const d=[],m=T.enter("table");for(;++p<v.length;)d[p]=c(v[p],T,x);return m(),d}function c(w,T,x){const v=w.children;let p=-1;const d=[],m=T.enter("tableRow");for(;++p<v.length;)d[p]=u(v[p],w,T,x);return m(),d}function C(w,T,x){let v=Rm.inlineCode(w,T,x);return x.stack.includes("tableCell")&&(v=v.replace(/\|/g,"\\$&")),v}}function xw(){return{exit:{taskListCheckValueChecked:R_,taskListCheckValueUnchecked:R_,paragraph:kw}}}function Ew(){return{unsafe:[{atBreak:!0,character:"-",after:"[:|-]"}],handlers:{listItem:Aw}}}function R_(i){const s=this.stack[this.stack.length-2];s.type,s.checked=i.type==="taskListCheckValueChecked"}function kw(i){const s=this.stack[this.stack.length-2];if(s&&s.type==="listItem"&&typeof s.checked=="boolean"){const l=this.stack[this.stack.length-1];l.type;const o=l.children[0];if(o&&o.type==="text"){const S=s.children;let b=-1,_;for(;++b<S.length;){const a=S[b];if(a.type==="paragraph"){_=a;break}}_===l&&(o.value=o.value.slice(1),o.value.length===0?l.children.shift():l.position&&o.position&&typeof o.position.start.offset=="number"&&(o.position.start.column++,o.position.start.offset++,l.position.start=Object.assign({},o.position.start)))}}this.exit(i)}function Aw(i,s,l,o){const S=i.children[0],b=typeof i.checked=="boolean"&&S&&S.type==="paragraph",_="["+(i.checked?"x":" ")+"] ",a=l.createTracker(o);b&&a.move(_);let u=Rm.listItem(i,s,l,{...o,...a.current()});return b&&(u=u.replace(/^(?:[*+-]|\d+\.)([\r\n]| {1,3})/,h)),u;function h(g){return g+_}}function Tw(){return[lC(),AC(),LC(),gw(),xw()]}function Dw(i){return{extensions:[aC(),TC(i),MC(),ww(i),Ew()]}}const Rw={tokenize:Hw,partial:!0},Lm={tokenize:Nw,partial:!0},Mm={tokenize:jw,partial:!0},Om={tokenize:Uw,partial:!0},Lw={tokenize:Iw,partial:!0},Bm={name:"wwwAutolink",tokenize:Bw,previous:Hm},zm={name:"protocolAutolink",tokenize:zw,previous:Nm},qi={name:"emailAutolink",tokenize:Ow,previous:jm},wi={};function Mw(){return{text:wi}}let jn=48;for(;jn<123;)wi[jn]=qi,jn++,jn===58?jn=65:jn===91&&(jn=97);wi[43]=qi;wi[45]=qi;wi[46]=qi;wi[95]=qi;wi[72]=[qi,zm];wi[104]=[qi,zm];wi[87]=[qi,Bm];wi[119]=[qi,Bm];function Ow(i,s,l){const o=this;let S,b;return _;function _(c){return!cc(c)||!jm.call(o,o.previous)||Rc(o.events)?l(c):(i.enter("literalAutolink"),i.enter("literalAutolinkEmail"),a(c))}function a(c){return cc(c)?(i.consume(c),a):c===64?(i.consume(c),u):l(c)}function u(c){return c===46?i.check(Lw,g,h)(c):c===45||c===95||Dt(c)?(b=!0,i.consume(c),u):g(c)}function h(c){return i.consume(c),S=!0,u}function g(c){return b&&S&&Mt(o.previous)?(i.exit("literalAutolinkEmail"),i.exit("literalAutolink"),s(c)):l(c)}}function Bw(i,s,l){const o=this;return S;function S(_){return _!==87&&_!==119||!Hm.call(o,o.previous)||Rc(o.events)?l(_):(i.enter("literalAutolink"),i.enter("literalAutolinkWww"),i.check(Rw,i.attempt(Lm,i.attempt(Mm,b),l),l)(_))}function b(_){return i.exit("literalAutolinkWww"),i.exit("literalAutolink"),s(_)}}function zw(i,s,l){const o=this;let S="",b=!1;return _;function _(c){return(c===72||c===104)&&Nm.call(o,o.previous)&&!Rc(o.events)?(i.enter("literalAutolink"),i.enter("literalAutolinkHttp"),S+=String.fromCodePoint(c),i.consume(c),a):l(c)}function a(c){if(Mt(c)&&S.length<5)return S+=String.fromCodePoint(c),i.consume(c),a;if(c===58){const C=S.toLowerCase();if(C==="http"||C==="https")return i.consume(c),u}return l(c)}function u(c){return c===47?(i.consume(c),b?h:(b=!0,u)):l(c)}function h(c){return c===null||sa(c)||et(c)||Un(c)||ca(c)?l(c):i.attempt(Lm,i.attempt(Mm,g),l)(c)}function g(c){return i.exit("literalAutolinkHttp"),i.exit("literalAutolink"),s(c)}}function Hw(i,s,l){let o=0;return S;function S(_){return(_===87||_===119)&&o<3?(o++,i.consume(_),S):_===46&&o===3?(i.consume(_),b):l(_)}function b(_){return _===null?l(_):s(_)}}function Nw(i,s,l){let o,S,b;return _;function _(h){return h===46||h===95?i.check(Om,u,a)(h):h===null||et(h)||Un(h)||h!==45&&ca(h)?u(h):(b=!0,i.consume(h),_)}function a(h){return h===95?o=!0:(S=o,o=void 0),i.consume(h),_}function u(h){return S||o||!b?l(h):s(h)}}function jw(i,s){let l=0,o=0;return S;function S(_){return _===40?(l++,i.consume(_),S):_===41&&o<l?b(_):_===33||_===34||_===38||_===39||_===41||_===42||_===44||_===46||_===58||_===59||_===60||_===63||_===93||_===95||_===126?i.check(Om,s,b)(_):_===null||et(_)||Un(_)?s(_):(i.consume(_),S)}function b(_){return _===41&&o++,i.consume(_),S}}function Uw(i,s,l){return o;function o(a){return a===33||a===34||a===39||a===41||a===42||a===44||a===46||a===58||a===59||a===63||a===95||a===126?(i.consume(a),o):a===38?(i.consume(a),b):a===93?(i.consume(a),S):a===60||a===null||et(a)||Un(a)?s(a):l(a)}function S(a){return a===null||a===40||a===91||et(a)||Un(a)?s(a):o(a)}function b(a){return Mt(a)?_(a):l(a)}function _(a){return a===59?(i.consume(a),o):Mt(a)?(i.consume(a),_):l(a)}}function Iw(i,s,l){return o;function o(b){return i.consume(b),S}function S(b){return Dt(b)?l(b):s(b)}}function Hm(i){return i===null||i===40||i===42||i===95||i===91||i===93||i===126||et(i)}function Nm(i){return!Mt(i)}function jm(i){return!(i===47||cc(i))}function cc(i){return i===43||i===45||i===46||i===95||Dt(i)}function Rc(i){let s=i.length,l=!1;for(;s--;){const o=i[s][1];if((o.type==="labelLink"||o.type==="labelImage")&&!o._balanced){l=!0;break}if(o._gfmAutolinkLiteralWalkedInto){l=!1;break}}return i.length>0&&!l&&(i[i.length-1][1]._gfmAutolinkLiteralWalkedInto=!0),l}const Pw={tokenize:Ww,partial:!0};function Fw(){return{document:{91:{name:"gfmFootnoteDefinition",tokenize:Gw,continuation:{tokenize:Kw},exit:Xw}},text:{91:{name:"gfmFootnoteCall",tokenize:Yw},93:{name:"gfmPotentialFootnoteCall",add:"after",tokenize:qw,resolveTo:Vw}}}}function qw(i,s,l){const o=this;let S=o.events.length;const b=o.parser.gfmFootnotes||(o.parser.gfmFootnotes=[]);let _;for(;S--;){const u=o.events[S][1];if(u.type==="labelImage"){_=u;break}if(u.type==="gfmFootnoteCall"||u.type==="labelLink"||u.type==="label"||u.type==="image"||u.type==="link")break}return a;function a(u){if(!_||!_._balanced)return l(u);const h=pi(o.sliceSerialize({start:_.end,end:o.now()}));return h.codePointAt(0)!==94||!b.includes(h.slice(1))?l(u):(i.enter("gfmFootnoteCallLabelMarker"),i.consume(u),i.exit("gfmFootnoteCallLabelMarker"),s(u))}}function Vw(i,s){let l=i.length;for(;l--;)if(i[l][1].type==="labelImage"&&i[l][0]==="enter"){i[l][1];break}i[l+1][1].type="data",i[l+3][1].type="gfmFootnoteCallLabelMarker";const o={type:"gfmFootnoteCall",start:Object.assign({},i[l+3][1].start),end:Object.assign({},i[i.length-1][1].end)},S={type:"gfmFootnoteCallMarker",start:Object.assign({},i[l+3][1].end),end:Object.assign({},i[l+3][1].end)};S.end.column++,S.end.offset++,S.end._bufferIndex++;const b={type:"gfmFootnoteCallString",start:Object.assign({},S.end),end:Object.assign({},i[i.length-1][1].start)},_={type:"chunkString",contentType:"string",start:Object.assign({},b.start),end:Object.assign({},b.end)},a=[i[l+1],i[l+2],["enter",o,s],i[l+3],i[l+4],["enter",S,s],["exit",S,s],["enter",b,s],["enter",_,s],["exit",_,s],["exit",b,s],i[i.length-2],i[i.length-1],["exit",o,s]];return i.splice(l,i.length-l+1,...a),i}function Yw(i,s,l){const o=this,S=o.parser.gfmFootnotes||(o.parser.gfmFootnotes=[]);let b=0,_;return a;function a(c){return i.enter("gfmFootnoteCall"),i.enter("gfmFootnoteCallLabelMarker"),i.consume(c),i.exit("gfmFootnoteCallLabelMarker"),u}function u(c){return c!==94?l(c):(i.enter("gfmFootnoteCallMarker"),i.consume(c),i.exit("gfmFootnoteCallMarker"),i.enter("gfmFootnoteCallString"),i.enter("chunkString").contentType="string",h)}function h(c){if(b>999||c===93&&!_||c===null||c===91||et(c))return l(c);if(c===93){i.exit("chunkString");const C=i.exit("gfmFootnoteCallString");return S.includes(pi(o.sliceSerialize(C)))?(i.enter("gfmFootnoteCallLabelMarker"),i.consume(c),i.exit("gfmFootnoteCallLabelMarker"),i.exit("gfmFootnoteCall"),s):l(c)}return et(c)||(_=!0),b++,i.consume(c),c===92?g:h}function g(c){return c===91||c===92||c===93?(i.consume(c),b++,h):h(c)}}function Gw(i,s,l){const o=this,S=o.parser.gfmFootnotes||(o.parser.gfmFootnotes=[]);let b,_=0,a;return u;function u(T){return i.enter("gfmFootnoteDefinition")._container=!0,i.enter("gfmFootnoteDefinitionLabel"),i.enter("gfmFootnoteDefinitionLabelMarker"),i.consume(T),i.exit("gfmFootnoteDefinitionLabelMarker"),h}function h(T){return T===94?(i.enter("gfmFootnoteDefinitionMarker"),i.consume(T),i.exit("gfmFootnoteDefinitionMarker"),i.enter("gfmFootnoteDefinitionLabelString"),i.enter("chunkString").contentType="string",g):l(T)}function g(T){if(_>999||T===93&&!a||T===null||T===91||et(T))return l(T);if(T===93){i.exit("chunkString");const x=i.exit("gfmFootnoteDefinitionLabelString");return b=pi(o.sliceSerialize(x)),i.enter("gfmFootnoteDefinitionLabelMarker"),i.consume(T),i.exit("gfmFootnoteDefinitionLabelMarker"),i.exit("gfmFootnoteDefinitionLabel"),C}return et(T)||(a=!0),_++,i.consume(T),T===92?c:g}function c(T){return T===91||T===92||T===93?(i.consume(T),_++,g):g(T)}function C(T){return T===58?(i.enter("definitionMarker"),i.consume(T),i.exit("definitionMarker"),S.includes(b)||S.push(b),Ie(i,w,"gfmFootnoteDefinitionWhitespace")):l(T)}function w(T){return s(T)}}function Kw(i,s,l){return i.check(Hs,s,i.attempt(Pw,s,l))}function Xw(i){i.exit("gfmFootnoteDefinition")}function Ww(i,s,l){const o=this;return Ie(i,S,"gfmFootnoteDefinitionIndent",5);function S(b){const _=o.events[o.events.length-1];return _&&_[1].type==="gfmFootnoteDefinitionIndent"&&_[2].sliceSerialize(_[1],!0).length===4?s(b):l(b)}}function $w(i){let l=(i||{}).singleTilde;const o={name:"strikethrough",tokenize:b,resolveAll:S};return l==null&&(l=!0),{text:{126:o},insideSpan:{null:[o]},attentionMarkers:{null:[126]}};function S(_,a){let u=-1;for(;++u<_.length;)if(_[u][0]==="enter"&&_[u][1].type==="strikethroughSequenceTemporary"&&_[u][1]._close){let h=u;for(;h--;)if(_[h][0]==="exit"&&_[h][1].type==="strikethroughSequenceTemporary"&&_[h][1]._open&&_[u][1].end.offset-_[u][1].start.offset===_[h][1].end.offset-_[h][1].start.offset){_[u][1].type="strikethroughSequence",_[h][1].type="strikethroughSequence";const g={type:"strikethrough",start:Object.assign({},_[h][1].start),end:Object.assign({},_[u][1].end)},c={type:"strikethroughText",start:Object.assign({},_[h][1].end),end:Object.assign({},_[u][1].start)},C=[["enter",g,a],["enter",_[h][1],a],["exit",_[h][1],a],["enter",c,a]],w=a.parser.constructs.insideSpan.null;w&&Zt(C,C.length,0,ha(w,_.slice(h+1,u),a)),Zt(C,C.length,0,[["exit",c,a],["enter",_[u][1],a],["exit",_[u][1],a],["exit",g,a]]),Zt(_,h-1,u-h+3,C),u=h+C.length-2;break}}for(u=-1;++u<_.length;)_[u][1].type==="strikethroughSequenceTemporary"&&(_[u][1].type="data");return _}function b(_,a,u){const h=this.previous,g=this.events;let c=0;return C;function C(T){return h===126&&g[g.length-1][1].type!=="characterEscape"?u(T):(_.enter("strikethroughSequenceTemporary"),w(T))}function w(T){const x=Dr(h);if(T===126)return c>1?u(T):(_.consume(T),c++,w);if(c<2&&!l)return u(T);const v=_.exit("strikethroughSequenceTemporary"),p=Dr(T);return v._open=!p||p===2&&!!x,v._close=!x||x===2&&!!p,a(T)}}}class Qw{constructor(){this.map=[]}add(s,l,o){Zw(this,s,l,o)}consume(s){if(this.map.sort(function(b,_){return b[0]-_[0]}),this.map.length===0)return;let l=this.map.length;const o=[];for(;l>0;)l-=1,o.push(s.slice(this.map[l][0]+this.map[l][1]),this.map[l][2]),s.length=this.map[l][0];o.push(s.slice()),s.length=0;let S=o.pop();for(;S;){for(const b of S)s.push(b);S=o.pop()}this.map.length=0}}function Zw(i,s,l,o){let S=0;if(!(l===0&&o.length===0)){for(;S<i.map.length;){if(i.map[S][0]===s){i.map[S][1]+=l,i.map[S][2].push(...o);return}S+=1}i.map.push([s,l,o])}}function Jw(i,s){let l=!1;const o=[];for(;s<i.length;){const S=i[s];if(l){if(S[0]==="enter")S[1].type==="tableContent"&&o.push(i[s+1][1].type==="tableDelimiterMarker"?"left":"none");else if(S[1].type==="tableContent"){if(i[s-1][1].type==="tableDelimiterMarker"){const b=o.length-1;o[b]=o[b]==="left"?"center":"right"}}else if(S[1].type==="tableDelimiterRow")break}else S[0]==="enter"&&S[1].type==="tableDelimiterRow"&&(l=!0);s+=1}return o}function ex(){return{flow:{null:{name:"table",tokenize:tx,resolveAll:ix}}}}function tx(i,s,l){const o=this;let S=0,b=0,_;return a;function a(j){let P=o.events.length-1;for(;P>-1;){const Y=o.events[P][1].type;if(Y==="lineEnding"||Y==="linePrefix")P--;else break}const V=P>-1?o.events[P][1].type:null,q=V==="tableHead"||V==="tableRow"?A:u;return q===A&&o.parser.lazy[o.now().line]?l(j):q(j)}function u(j){return i.enter("tableHead"),i.enter("tableRow"),h(j)}function h(j){return j===124||(_=!0,b+=1),g(j)}function g(j){return j===null?l(j):Ce(j)?b>1?(b=0,o.interrupt=!0,i.exit("tableRow"),i.enter("lineEnding"),i.consume(j),i.exit("lineEnding"),w):l(j):ze(j)?Ie(i,g,"whitespace")(j):(b+=1,_&&(_=!1,S+=1),j===124?(i.enter("tableCellDivider"),i.consume(j),i.exit("tableCellDivider"),_=!0,g):(i.enter("data"),c(j)))}function c(j){return j===null||j===124||et(j)?(i.exit("data"),g(j)):(i.consume(j),j===92?C:c)}function C(j){return j===92||j===124?(i.consume(j),c):c(j)}function w(j){return o.interrupt=!1,o.parser.lazy[o.now().line]?l(j):(i.enter("tableDelimiterRow"),_=!1,ze(j)?Ie(i,T,"linePrefix",o.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(j):T(j))}function T(j){return j===45||j===58?v(j):j===124?(_=!0,i.enter("tableCellDivider"),i.consume(j),i.exit("tableCellDivider"),x):R(j)}function x(j){return ze(j)?Ie(i,v,"whitespace")(j):v(j)}function v(j){return j===58?(b+=1,_=!0,i.enter("tableDelimiterMarker"),i.consume(j),i.exit("tableDelimiterMarker"),p):j===45?(b+=1,p(j)):j===null||Ce(j)?E(j):R(j)}function p(j){return j===45?(i.enter("tableDelimiterFiller"),d(j)):R(j)}function d(j){return j===45?(i.consume(j),d):j===58?(_=!0,i.exit("tableDelimiterFiller"),i.enter("tableDelimiterMarker"),i.consume(j),i.exit("tableDelimiterMarker"),m):(i.exit("tableDelimiterFiller"),m(j))}function m(j){return ze(j)?Ie(i,E,"whitespace")(j):E(j)}function E(j){return j===124?T(j):j===null||Ce(j)?!_||S!==b?R(j):(i.exit("tableDelimiterRow"),i.exit("tableHead"),s(j)):R(j)}function R(j){return l(j)}function A(j){return i.enter("tableRow"),L(j)}function L(j){return j===124?(i.enter("tableCellDivider"),i.consume(j),i.exit("tableCellDivider"),L):j===null||Ce(j)?(i.exit("tableRow"),s(j)):ze(j)?Ie(i,L,"whitespace")(j):(i.enter("data"),k(j))}function k(j){return j===null||j===124||et(j)?(i.exit("data"),L(j)):(i.consume(j),j===92?O:k)}function O(j){return j===92||j===124?(i.consume(j),k):k(j)}}function ix(i,s){let l=-1,o=!0,S=0,b=[0,0,0,0],_=[0,0,0,0],a=!1,u=0,h,g,c;const C=new Qw;for(;++l<i.length;){const w=i[l],T=w[1];w[0]==="enter"?T.type==="tableHead"?(a=!1,u!==0&&(L_(C,s,u,h,g),g=void 0,u=0),h={type:"table",start:Object.assign({},T.start),end:Object.assign({},T.end)},C.add(l,0,[["enter",h,s]])):T.type==="tableRow"||T.type==="tableDelimiterRow"?(o=!0,c=void 0,b=[0,0,0,0],_=[0,l+1,0,0],a&&(a=!1,g={type:"tableBody",start:Object.assign({},T.start),end:Object.assign({},T.end)},C.add(l,0,[["enter",g,s]])),S=T.type==="tableDelimiterRow"?2:g?3:1):S&&(T.type==="data"||T.type==="tableDelimiterMarker"||T.type==="tableDelimiterFiller")?(o=!1,_[2]===0&&(b[1]!==0&&(_[0]=_[1],c=na(C,s,b,S,void 0,c),b=[0,0,0,0]),_[2]=l)):T.type==="tableCellDivider"&&(o?o=!1:(b[1]!==0&&(_[0]=_[1],c=na(C,s,b,S,void 0,c)),b=_,_=[b[1],l,0,0])):T.type==="tableHead"?(a=!0,u=l):T.type==="tableRow"||T.type==="tableDelimiterRow"?(u=l,b[1]!==0?(_[0]=_[1],c=na(C,s,b,S,l,c)):_[1]!==0&&(c=na(C,s,_,S,l,c)),S=0):S&&(T.type==="data"||T.type==="tableDelimiterMarker"||T.type==="tableDelimiterFiller")&&(_[3]=l)}for(u!==0&&L_(C,s,u,h,g),C.consume(s.events),l=-1;++l<s.events.length;){const w=s.events[l];w[0]==="enter"&&w[1].type==="table"&&(w[1]._align=Jw(s.events,l))}return i}function na(i,s,l,o,S,b){const _=o===1?"tableHeader":o===2?"tableDelimiter":"tableData",a="tableContent";l[0]!==0&&(b.end=Object.assign({},Ar(s.events,l[0])),i.add(l[0],0,[["exit",b,s]]));const u=Ar(s.events,l[1]);if(b={type:_,start:Object.assign({},u),end:Object.assign({},u)},i.add(l[1],0,[["enter",b,s]]),l[2]!==0){const h=Ar(s.events,l[2]),g=Ar(s.events,l[3]),c={type:a,start:Object.assign({},h),end:Object.assign({},g)};if(i.add(l[2],0,[["enter",c,s]]),o!==2){const C=s.events[l[2]],w=s.events[l[3]];if(C[1].end=Object.assign({},w[1].end),C[1].type="chunkText",C[1].contentType="text",l[3]>l[2]+1){const T=l[2]+1,x=l[3]-l[2]-1;i.add(T,x,[])}}i.add(l[3]+1,0,[["exit",c,s]])}return S!==void 0&&(b.end=Object.assign({},Ar(s.events,S)),i.add(S,0,[["exit",b,s]]),b=void 0),b}function L_(i,s,l,o,S){const b=[],_=Ar(s.events,l);S&&(S.end=Object.assign({},_),b.push(["exit",S,s])),o.end=Object.assign({},_),b.push(["exit",o,s]),i.add(l+1,0,b)}function Ar(i,s){const l=i[s],o=l[0]==="enter"?"start":"end";return l[1][o]}const nx={name:"tasklistCheck",tokenize:sx};function rx(){return{text:{91:nx}}}function sx(i,s,l){const o=this;return S;function S(u){return o.previous!==null||!o._gfmTasklistFirstContentOfListItem?l(u):(i.enter("taskListCheck"),i.enter("taskListCheckMarker"),i.consume(u),i.exit("taskListCheckMarker"),b)}function b(u){return et(u)?(i.enter("taskListCheckValueUnchecked"),i.consume(u),i.exit("taskListCheckValueUnchecked"),_):u===88||u===120?(i.enter("taskListCheckValueChecked"),i.consume(u),i.exit("taskListCheckValueChecked"),_):l(u)}function _(u){return u===93?(i.enter("taskListCheckMarker"),i.consume(u),i.exit("taskListCheckMarker"),i.exit("taskListCheck"),a):l(u)}function a(u){return Ce(u)?s(u):ze(u)?i.check({tokenize:lx},s,l)(u):l(u)}}function lx(i,s,l){return Ie(i,o,"whitespace");function o(S){return S===null?l(S):s(S)}}function ax(i){return W_([Mw(),Fw(),$w(i),ex(),rx()])}const ox={};function ux(i){const s=this,l=i||ox,o=s.data(),S=o.micromarkExtensions||(o.micromarkExtensions=[]),b=o.fromMarkdownExtensions||(o.fromMarkdownExtensions=[]),_=o.toMarkdownExtensions||(o.toMarkdownExtensions=[]);S.push(ax(l)),b.push(Tw()),_.push(Dw(l))}function cx({settings:i,busy:s=!1,promptPreviews:l,testResult:o,onSave:S,onTest:b,onClose:_}){const[a,u]=ge.useState(i),[h,g]=ge.useState(i.apiKey??"");return ge.useEffect(()=>{u(i),g(i.apiKey??"")},[i]),F.jsx("div",{className:"modal-backdrop",children:F.jsxs("section",{className:"translation-settings-modal",role:"dialog","aria-modal":"true","aria-label":"Translation Settings",children:[F.jsxs("header",{children:[F.jsxs("div",{children:[F.jsx("h2",{children:"Translation Settings"}),F.jsx("p",{children:"Use an OpenAI-compatible endpoint for the embedded translation panel."})]}),F.jsx("button",{type:"button",onClick:_,children:"Close"})]}),F.jsxs("div",{className:"translation-settings-grid",children:[F.jsxs("label",{children:[F.jsx("span",{children:"Base URL"}),F.jsx("input",{value:a.baseUrl,onChange:c=>u({...a,baseUrl:c.target.value}),placeholder:"https://api.openai.com/v1"})]}),F.jsxs("label",{children:[F.jsx("span",{children:"API key"}),F.jsx("input",{value:h,onChange:c=>g(c.target.value),placeholder:"API key",autoCapitalize:"off",autoComplete:"off",autoCorrect:"off",spellCheck:!1,type:"text"})]}),F.jsxs("label",{children:[F.jsx("span",{children:"Model"}),F.jsx("input",{value:a.model,onChange:c=>u({...a,model:c.target.value})})]}),F.jsxs("label",{children:[F.jsx("span",{children:"Target language"}),F.jsx("input",{value:a.targetLanguage,onChange:c=>u({...a,targetLanguage:c.target.value})})]}),F.jsxs("label",{children:[F.jsx("span",{children:"Use context"}),F.jsx("input",{checked:a.contextEnabled,type:"checkbox",onChange:c=>u({...a,contextEnabled:c.target.checked})})]}),F.jsxs("label",{children:[F.jsx("span",{children:"Timeout ms"}),F.jsx("input",{min:3e3,type:"number",value:a.requestTimeoutMs,onChange:c=>u({...a,requestTimeoutMs:Number(c.target.value)})})]}),F.jsxs("label",{children:[F.jsx("span",{children:"Temperature"}),F.jsx("input",{min:0,max:1,step:.1,type:"number",value:a.temperature,onChange:c=>u({...a,temperature:Number(c.target.value)})})]})]}),F.jsxs("section",{className:"translation-prompt-settings",children:[F.jsxs("header",{children:[F.jsxs("div",{children:[F.jsx("h3",{children:"Translation Prompts"}),F.jsx("p",{children:"Edit the three cc-pm style prompt slots directly."})]}),F.jsx("button",{type:"button",disabled:s,onClick:()=>u({...a,prompts:void 0}),children:"Reset prompts"})]}),F.jsx("div",{className:"translation-prompt-stack",children:l.map(c=>F.jsxs("label",{children:[F.jsx("span",{children:c.label}),F.jsx("textarea",{value:fx(a,c),onChange:C=>u({...a,prompts:hx(a.prompts,c.key,C.target.value,c.defaultPrompt)})})]},c.key))})]}),o?F.jsx("div",{className:o.ok?"translation-test-result is-ok":"translation-test-result is-error",children:o.ok?`Connection ok: ${o.model} in ${o.elapsedMs}ms`:o.error}):null,F.jsxs("footer",{children:[F.jsx("button",{type:"button",disabled:s,onClick:b,children:"Test Connection"}),F.jsx("button",{type:"button",disabled:s,onClick:()=>void S({...a,enabled:!0,translateOutput:!0,translateUserInput:!0,inputMode:"review-before-send"},h.trim()),children:"Save"})]})]})})}function hx(i,s,l,o){const S={...i??{}};return l.trim()&&l!==o?S[s]=l:delete S[s],Object.keys(S).length>0?S:void 0}function fx(i,s){var l;return((l=i.prompts)==null?void 0:l[s.key])??s.defaultPrompt}function dx({active:i=!0,taskSlug:s,role:l,sessionId:o}){const[S,b]=ge.useState(null),[_,a]=ge.useState([]),[u,h]=ge.useState(""),[g,c]=ge.useState(!1),[C,w]=ge.useState(!1),[T,x]=ge.useState(!1),[v,p]=ge.useState("ready"),[d,m]=ge.useState(""),[E,R]=ge.useState(Date.now()),[A,L]=ge.useState(!1),[k,O]=ge.useState(""),[j,P]=ge.useState(!1),[V,q]=ge.useState([]),[Y,$]=ge.useState(),[G,J]=ge.useState(0),ne=ge.useRef(i),z=ge.useRef(1),M=ge.useRef(null);ge.useEffect(()=>{ne.current=i},[i]),ge.useEffect(()=>{Promise.all([je.getTranslationSettings(),je.getTranslationPrompts()]).then(([Q,de])=>{b(Q),q(de)}).catch(Q=>O(Q.message))},[]),ge.useEffect(()=>{a([]),O(""),p("ready"),m(""),z.current=1;let Q=!1,de;const pe=()=>{Q||(de=window.setTimeout(ke,ne.current?200:1e3))},ke=async()=>{if(!Q)try{const xe=await je.pollTranslationSession(o,z.current);if(Q)return;H(xe.events),z.current=xe.nextCursor,p(xe.status),ne.current&&m(bx(new Date().toISOString()))}catch(xe){Q||O(xe instanceof Error?xe.message:"Translation poll failed.")}finally{pe()}};return je.startTranslationSession(s,l).then(xe=>{Q||(p(xe.status),z.current=xe.nextCursor,ke())}).catch(xe=>{Q||O(xe instanceof Error?xe.message:"Translation start failed.")}),()=>{Q=!0,de!==void 0&&window.clearTimeout(de)}},[o,s,l,G]),ge.useEffect(()=>{var Q;i&&((Q=M.current)==null||Q.scrollIntoView({block:"nearest"}))},[i,_.length]);const B=_x(_);ge.useEffect(()=>{if(!B)return;R(Date.now());const Q=window.setInterval(()=>R(Date.now()),250);return()=>window.clearInterval(Q)},[B]);async function I(Q=!1){if(S){L(!0),O(""),c(!1);try{const de=await je.translateUserInput(s,l,{text:u,mode:Q?"auto-send":"review-before-send",useContext:S.contextEnabled,send:Q});x(de.contextUsed),de.sent?(h(""),c(!1)):(h(de.englishPreview),c(!0))}catch(de){O(de instanceof Error?de.message:"Translation failed.")}finally{L(!1)}}}function H(Q){if(Q.length===0)return;for(const pe of Q)pe.type==="status"?p(pe.status):pe.type==="error"&&O(pe.message);const de=Q.filter(pe=>pe.type==="entry");de.length>0&&a(pe=>de.reduce((ke,xe)=>Sx(ke,xe.entry),pe))}async function ie(){if(u.trim()){L(!0),O("");try{await je.sendTranslatedInput(s,l,{englishText:u}),h(""),c(!1),x(!1)}catch(Q){O(Q instanceof Error?Q.message:"Failed to send English input.")}finally{L(!1)}}}function he(Q){Q.key!=="Enter"||Q.shiftKey||Q.nativeEvent.isComposing||(Q.preventDefault(),!A&&u.trim()&&(g?ie():I(C)))}async function fe(Q,de){L(!0),O("");try{const pe=await je.updateTranslationSettings({...Q,...de!==void 0?{apiKey:de}:{}}),ke=await je.getTranslationPrompts();b(pe),q(ke),P(!1),J(xe=>xe+1)}catch(pe){O(pe instanceof Error?pe.message:"Failed to save translation settings.")}finally{L(!1)}}async function X(){L(!0),O("");try{$(await je.testTranslationProvider())}catch(Q){O(Q instanceof Error?Q.message:"Provider test failed.")}finally{L(!1)}}async function N(){a([]),z.current=1,await je.clearTranslationSession(o).catch(Q=>O(Q.message))}if(!S)return F.jsx("aside",{className:"translation-panel",children:F.jsx("p",{className:"muted",children:"Loading translation settings..."})});const re=mx(_,v,E);return F.jsxs("aside",{className:"translation-panel",children:[F.jsxs("header",{className:"translation-panel-header",children:[F.jsxs("div",{className:"translation-panel-titlebar",children:[F.jsx("h2",{children:"Translation"}),F.jsxs("div",{className:"translation-panel-actions",children:[F.jsx("button",{"aria-pressed":C,className:`auto-send-toggle${C?" is-active":""}`,type:"button",onClick:()=>w(Q=>!Q),children:C?"✅ Auto-send":"× Auto-send"}),F.jsx("button",{type:"button",onClick:()=>P(!0),children:"Settings"}),F.jsx("button",{type:"button",onClick:()=>void N(),children:"Clear"})]})]}),F.jsxs("div",{className:"translation-status-row",children:[F.jsxs("p",{children:[S.model," · ",re,T?" · context used":""]}),F.jsx("p",{children:d?`poll ${d}`:"poll -"})]})]}),k?F.jsx("div",{className:"error-banner",children:k}):null,F.jsxs("div",{className:"translation-entry-list",children:[_.length===0?F.jsx("p",{className:"muted",children:"Translated Claude Code output will appear here."}):null,_.map(Q=>F.jsx(px,{entry:Q},Q.id)),F.jsx("div",{ref:M})]}),F.jsx("div",{className:"translation-composer",children:F.jsxs("div",{className:"translation-composer-row",children:[F.jsx("textarea",{value:u,onChange:Q=>{h(Q.target.value),Q.target.value.trim()||c(!1)},onKeyDown:he,placeholder:"输入中文,先翻译成英文工程指令..."}),F.jsx("div",{className:"translation-composer-actions",children:F.jsx("button",{type:"button",disabled:A||!g||!u.trim(),onClick:()=>void ie(),children:"Send English"})})]})}),j?F.jsx(cx,{settings:S,busy:A,promptPreviews:V,testResult:Y,onSave:fe,onTest:X,onClose:()=>P(!1)}):null]})}function px({entry:i}){const s=vx(i),l=i.sourceKind==="tool-output";return F.jsxs("article",{className:`translation-entry is-${i.sourceKind}`,children:[l?F.jsx("pre",{children:s}):F.jsx("div",{className:"translation-markdown",children:F.jsx($b,{remarkPlugins:[ux],children:s})}),i.warning?F.jsx("p",{className:"translation-entry-note",children:i.warning}):null,i.error?F.jsx("p",{className:"translation-entry-note is-error",children:i.error}):null]})}function _x(i){const s=i.find(Um);return(s==null?void 0:s.translationStartedAt)??(s==null?void 0:s.createdAt)}function mx(i,s,l){const o=i.find(Um);if(o)return`translating ${yx(Math.max(0,l-gx(o)))}`;const S=i.at(-1);return(S==null?void 0:S.status)==="failed"||s==="failed"?"error":s}function Um(i){return i.status==="queued"||i.status==="translating"}function gx(i){const s=Date.parse(i.translationStartedAt??i.createdAt);return Number.isFinite(s)?s:Date.now()}function vx(i){return i.status==="queued"||i.status==="translating"?i.sourceText:i.status==="translated"?i.translatedText:i.translatedText||i.sourceText}function Sx(i,s){return i.findIndex(o=>o.id===s.id)===-1?[...i,s]:i.map(o=>o.id===s.id?s:o)}function yx(i){if(i<1e3)return`${Math.max(.1,i/1e3).toFixed(1)}s`;const s=i/1e3;if(s<60)return`${s.toFixed(1)}s`;const l=Math.floor(s/60),o=Math.floor(s%60).toString().padStart(2,"0");return`${l}:${o}`}function bx(i){const s=new Date(i);return Number.isNaN(s.getTime())?i:s.toLocaleTimeString()}function Cx({role:i,session:s,permissionMode:l,active:o=!0,busy:S,onPermissionModeChange:b,onStart:_,onResume:a,onStop:u,onRestart:h,onTerminalEvent:g}){const[c,C]=ge.useState(!1);return F.jsxs("section",{className:"session-console",children:[F.jsxs("div",{className:"session-console-top",children:[F.jsx(NS,{role:i,session:s,permissionMode:l,busy:S,onPermissionModeChange:b,onStart:_,onResume:a,onStop:u,onRestart:h}),F.jsx("button",{"aria-pressed":c,className:`translation-toggle${c?" is-active":""}`,type:"button",onClick:()=>C(w=>!w),children:c?"✅ Translate":"× Translate"})]}),(s==null?void 0:s.status)==="running"?F.jsx(wx,{active:o,onTerminalEvent:g,role:i,session:s,taskSlug:s.taskSlug,translationEnabled:c}):F.jsxs("div",{className:"terminal-empty",children:[F.jsx("strong",{children:i}),F.jsx("span",{children:s!=null&&s.claudeSessionId?"Resume this role to reconnect its Claude Code conversation.":"Start this role to open an embedded Claude Code terminal."})]})]})}function wx({active:i,onTerminalEvent:s,role:l,session:o,taskSlug:S,translationEnabled:b}){return F.jsxs("div",{className:b?"session-console-body has-translation":"session-console-body",children:[F.jsx("div",{className:"terminal-pane",children:F.jsx(zS,{sessionId:o.id,active:i,onEvent:s},o.id)}),b?F.jsx("div",{className:"translation-pane",children:F.jsx(dx,{active:i,taskSlug:S,role:l,sessionId:o.id},o.id)}):null]})}function xx({task:i,activeRole:s,onTaskChanged:l,onActiveRoleChange:o,onWorkflowChanged:S,onMessagesChanged:b,onOrchestrationChanged:_,onEventsChanged:a}){const[u,h]=ge.useState(null),[g,c]=ge.useState({"project-manager":"default",architect:"default",coder:"default",reviewer:"default"}),[C,w]=ge.useState(!1),[T,x]=ge.useState(""),[v,p]=ge.useState([]),d=ge.useCallback(async()=>{const[L,k,O]=await Promise.all([je.getTaskStatus(i.taskSlug),je.listMessages(i.taskSlug),je.getOrchestrationState(i.taskSlug)]);h(L),S==null||S(L.workflow),b==null||b(k),_==null||_(O)},[b,_,S,i.taskSlug]);ge.useEffect(()=>{d().catch(L=>x(L.message))},[d]),ge.useEffect(()=>{p([]),a==null||a([])},[a,i.taskSlug]),ge.useEffect(()=>{c(L=>{let k=!1;const O={...L};for(const j of(u==null?void 0:u.sessions)??[])O[j.role]!==j.permissionMode&&(O[j.role]=j.permissionMode,k=!0);return k?O:L})},[u==null?void 0:u.sessions]),ge.useEffect(()=>{const L=window.setInterval(()=>{Promise.all([je.getTaskStatus(i.taskSlug),je.listMessages(i.taskSlug),je.getOrchestrationState(i.taskSlug)]).then(([k,O,j])=>{h(k),S==null||S(k.workflow),b==null||b(O),_==null||_(j)}).catch(k=>x(k.message))},3e3);return()=>window.clearInterval(L)},[b,_,S,i.taskSlug]);async function m(L){w(!0),x("");try{await L(),await d(),await l()}catch(k){x(k instanceof Error?k.message:"Action failed.")}finally{w(!1)}}async function E(){const L=i.worktreePath?[`Close task "${i.taskSlug}"?`,"","This is destructive:",`- deletes the task worktree: ${i.worktreePath}`,`- deletes the Git branch: ${i.branch}`,"- deletes VCM task/session/message/orchestration state","","VCM will not check running sessions or uncommitted changes before closing."].join(`
87
- `):[`Close task "${i.taskSlug}"?`,"","This task was created without a separate worktree/branch.","VCM will delete task/session/message/orchestration state only.","","VCM will not check running sessions or uncommitted changes before closing."].join(`
86
+ `))}function u(w,T,x,v){const p=x.enter("tableCell"),d=x.enter("phrasing"),m=x.containerPhrasing(w,{...v,before:b,after:b});return d(),p(),m}function h(w,T){return NC(w,{align:T,alignDelimiters:o,padding:l,stringLength:S})}function g(w,T,x){const v=w.children;let p=-1;const d=[],m=T.enter("table");for(;++p<v.length;)d[p]=c(v[p],T,x);return m(),d}function c(w,T,x){const v=w.children;let p=-1;const d=[],m=T.enter("tableRow");for(;++p<v.length;)d[p]=u(v[p],w,T,x);return m(),d}function C(w,T,x){let v=Rm.inlineCode(w,T,x);return x.stack.includes("tableCell")&&(v=v.replace(/\|/g,"\\$&")),v}}function xw(){return{exit:{taskListCheckValueChecked:R_,taskListCheckValueUnchecked:R_,paragraph:kw}}}function Ew(){return{unsafe:[{atBreak:!0,character:"-",after:"[:|-]"}],handlers:{listItem:Aw}}}function R_(i){const s=this.stack[this.stack.length-2];s.type,s.checked=i.type==="taskListCheckValueChecked"}function kw(i){const s=this.stack[this.stack.length-2];if(s&&s.type==="listItem"&&typeof s.checked=="boolean"){const l=this.stack[this.stack.length-1];l.type;const o=l.children[0];if(o&&o.type==="text"){const S=s.children;let b=-1,_;for(;++b<S.length;){const a=S[b];if(a.type==="paragraph"){_=a;break}}_===l&&(o.value=o.value.slice(1),o.value.length===0?l.children.shift():l.position&&o.position&&typeof o.position.start.offset=="number"&&(o.position.start.column++,o.position.start.offset++,l.position.start=Object.assign({},o.position.start)))}}this.exit(i)}function Aw(i,s,l,o){const S=i.children[0],b=typeof i.checked=="boolean"&&S&&S.type==="paragraph",_="["+(i.checked?"x":" ")+"] ",a=l.createTracker(o);b&&a.move(_);let u=Rm.listItem(i,s,l,{...o,...a.current()});return b&&(u=u.replace(/^(?:[*+-]|\d+\.)([\r\n]| {1,3})/,h)),u;function h(g){return g+_}}function Tw(){return[lC(),AC(),LC(),gw(),xw()]}function Dw(i){return{extensions:[aC(),TC(i),MC(),ww(i),Ew()]}}const Rw={tokenize:Hw,partial:!0},Lm={tokenize:Nw,partial:!0},Mm={tokenize:jw,partial:!0},Om={tokenize:Uw,partial:!0},Lw={tokenize:Iw,partial:!0},Bm={name:"wwwAutolink",tokenize:Bw,previous:Hm},zm={name:"protocolAutolink",tokenize:zw,previous:Nm},qi={name:"emailAutolink",tokenize:Ow,previous:jm},wi={};function Mw(){return{text:wi}}let jn=48;for(;jn<123;)wi[jn]=qi,jn++,jn===58?jn=65:jn===91&&(jn=97);wi[43]=qi;wi[45]=qi;wi[46]=qi;wi[95]=qi;wi[72]=[qi,zm];wi[104]=[qi,zm];wi[87]=[qi,Bm];wi[119]=[qi,Bm];function Ow(i,s,l){const o=this;let S,b;return _;function _(c){return!cc(c)||!jm.call(o,o.previous)||Rc(o.events)?l(c):(i.enter("literalAutolink"),i.enter("literalAutolinkEmail"),a(c))}function a(c){return cc(c)?(i.consume(c),a):c===64?(i.consume(c),u):l(c)}function u(c){return c===46?i.check(Lw,g,h)(c):c===45||c===95||Dt(c)?(b=!0,i.consume(c),u):g(c)}function h(c){return i.consume(c),S=!0,u}function g(c){return b&&S&&Mt(o.previous)?(i.exit("literalAutolinkEmail"),i.exit("literalAutolink"),s(c)):l(c)}}function Bw(i,s,l){const o=this;return S;function S(_){return _!==87&&_!==119||!Hm.call(o,o.previous)||Rc(o.events)?l(_):(i.enter("literalAutolink"),i.enter("literalAutolinkWww"),i.check(Rw,i.attempt(Lm,i.attempt(Mm,b),l),l)(_))}function b(_){return i.exit("literalAutolinkWww"),i.exit("literalAutolink"),s(_)}}function zw(i,s,l){const o=this;let S="",b=!1;return _;function _(c){return(c===72||c===104)&&Nm.call(o,o.previous)&&!Rc(o.events)?(i.enter("literalAutolink"),i.enter("literalAutolinkHttp"),S+=String.fromCodePoint(c),i.consume(c),a):l(c)}function a(c){if(Mt(c)&&S.length<5)return S+=String.fromCodePoint(c),i.consume(c),a;if(c===58){const C=S.toLowerCase();if(C==="http"||C==="https")return i.consume(c),u}return l(c)}function u(c){return c===47?(i.consume(c),b?h:(b=!0,u)):l(c)}function h(c){return c===null||sa(c)||et(c)||Un(c)||ca(c)?l(c):i.attempt(Lm,i.attempt(Mm,g),l)(c)}function g(c){return i.exit("literalAutolinkHttp"),i.exit("literalAutolink"),s(c)}}function Hw(i,s,l){let o=0;return S;function S(_){return(_===87||_===119)&&o<3?(o++,i.consume(_),S):_===46&&o===3?(i.consume(_),b):l(_)}function b(_){return _===null?l(_):s(_)}}function Nw(i,s,l){let o,S,b;return _;function _(h){return h===46||h===95?i.check(Om,u,a)(h):h===null||et(h)||Un(h)||h!==45&&ca(h)?u(h):(b=!0,i.consume(h),_)}function a(h){return h===95?o=!0:(S=o,o=void 0),i.consume(h),_}function u(h){return S||o||!b?l(h):s(h)}}function jw(i,s){let l=0,o=0;return S;function S(_){return _===40?(l++,i.consume(_),S):_===41&&o<l?b(_):_===33||_===34||_===38||_===39||_===41||_===42||_===44||_===46||_===58||_===59||_===60||_===63||_===93||_===95||_===126?i.check(Om,s,b)(_):_===null||et(_)||Un(_)?s(_):(i.consume(_),S)}function b(_){return _===41&&o++,i.consume(_),S}}function Uw(i,s,l){return o;function o(a){return a===33||a===34||a===39||a===41||a===42||a===44||a===46||a===58||a===59||a===63||a===95||a===126?(i.consume(a),o):a===38?(i.consume(a),b):a===93?(i.consume(a),S):a===60||a===null||et(a)||Un(a)?s(a):l(a)}function S(a){return a===null||a===40||a===91||et(a)||Un(a)?s(a):o(a)}function b(a){return Mt(a)?_(a):l(a)}function _(a){return a===59?(i.consume(a),o):Mt(a)?(i.consume(a),_):l(a)}}function Iw(i,s,l){return o;function o(b){return i.consume(b),S}function S(b){return Dt(b)?l(b):s(b)}}function Hm(i){return i===null||i===40||i===42||i===95||i===91||i===93||i===126||et(i)}function Nm(i){return!Mt(i)}function jm(i){return!(i===47||cc(i))}function cc(i){return i===43||i===45||i===46||i===95||Dt(i)}function Rc(i){let s=i.length,l=!1;for(;s--;){const o=i[s][1];if((o.type==="labelLink"||o.type==="labelImage")&&!o._balanced){l=!0;break}if(o._gfmAutolinkLiteralWalkedInto){l=!1;break}}return i.length>0&&!l&&(i[i.length-1][1]._gfmAutolinkLiteralWalkedInto=!0),l}const Pw={tokenize:Ww,partial:!0};function Fw(){return{document:{91:{name:"gfmFootnoteDefinition",tokenize:Gw,continuation:{tokenize:Kw},exit:Xw}},text:{91:{name:"gfmFootnoteCall",tokenize:Yw},93:{name:"gfmPotentialFootnoteCall",add:"after",tokenize:qw,resolveTo:Vw}}}}function qw(i,s,l){const o=this;let S=o.events.length;const b=o.parser.gfmFootnotes||(o.parser.gfmFootnotes=[]);let _;for(;S--;){const u=o.events[S][1];if(u.type==="labelImage"){_=u;break}if(u.type==="gfmFootnoteCall"||u.type==="labelLink"||u.type==="label"||u.type==="image"||u.type==="link")break}return a;function a(u){if(!_||!_._balanced)return l(u);const h=pi(o.sliceSerialize({start:_.end,end:o.now()}));return h.codePointAt(0)!==94||!b.includes(h.slice(1))?l(u):(i.enter("gfmFootnoteCallLabelMarker"),i.consume(u),i.exit("gfmFootnoteCallLabelMarker"),s(u))}}function Vw(i,s){let l=i.length;for(;l--;)if(i[l][1].type==="labelImage"&&i[l][0]==="enter"){i[l][1];break}i[l+1][1].type="data",i[l+3][1].type="gfmFootnoteCallLabelMarker";const o={type:"gfmFootnoteCall",start:Object.assign({},i[l+3][1].start),end:Object.assign({},i[i.length-1][1].end)},S={type:"gfmFootnoteCallMarker",start:Object.assign({},i[l+3][1].end),end:Object.assign({},i[l+3][1].end)};S.end.column++,S.end.offset++,S.end._bufferIndex++;const b={type:"gfmFootnoteCallString",start:Object.assign({},S.end),end:Object.assign({},i[i.length-1][1].start)},_={type:"chunkString",contentType:"string",start:Object.assign({},b.start),end:Object.assign({},b.end)},a=[i[l+1],i[l+2],["enter",o,s],i[l+3],i[l+4],["enter",S,s],["exit",S,s],["enter",b,s],["enter",_,s],["exit",_,s],["exit",b,s],i[i.length-2],i[i.length-1],["exit",o,s]];return i.splice(l,i.length-l+1,...a),i}function Yw(i,s,l){const o=this,S=o.parser.gfmFootnotes||(o.parser.gfmFootnotes=[]);let b=0,_;return a;function a(c){return i.enter("gfmFootnoteCall"),i.enter("gfmFootnoteCallLabelMarker"),i.consume(c),i.exit("gfmFootnoteCallLabelMarker"),u}function u(c){return c!==94?l(c):(i.enter("gfmFootnoteCallMarker"),i.consume(c),i.exit("gfmFootnoteCallMarker"),i.enter("gfmFootnoteCallString"),i.enter("chunkString").contentType="string",h)}function h(c){if(b>999||c===93&&!_||c===null||c===91||et(c))return l(c);if(c===93){i.exit("chunkString");const C=i.exit("gfmFootnoteCallString");return S.includes(pi(o.sliceSerialize(C)))?(i.enter("gfmFootnoteCallLabelMarker"),i.consume(c),i.exit("gfmFootnoteCallLabelMarker"),i.exit("gfmFootnoteCall"),s):l(c)}return et(c)||(_=!0),b++,i.consume(c),c===92?g:h}function g(c){return c===91||c===92||c===93?(i.consume(c),b++,h):h(c)}}function Gw(i,s,l){const o=this,S=o.parser.gfmFootnotes||(o.parser.gfmFootnotes=[]);let b,_=0,a;return u;function u(T){return i.enter("gfmFootnoteDefinition")._container=!0,i.enter("gfmFootnoteDefinitionLabel"),i.enter("gfmFootnoteDefinitionLabelMarker"),i.consume(T),i.exit("gfmFootnoteDefinitionLabelMarker"),h}function h(T){return T===94?(i.enter("gfmFootnoteDefinitionMarker"),i.consume(T),i.exit("gfmFootnoteDefinitionMarker"),i.enter("gfmFootnoteDefinitionLabelString"),i.enter("chunkString").contentType="string",g):l(T)}function g(T){if(_>999||T===93&&!a||T===null||T===91||et(T))return l(T);if(T===93){i.exit("chunkString");const x=i.exit("gfmFootnoteDefinitionLabelString");return b=pi(o.sliceSerialize(x)),i.enter("gfmFootnoteDefinitionLabelMarker"),i.consume(T),i.exit("gfmFootnoteDefinitionLabelMarker"),i.exit("gfmFootnoteDefinitionLabel"),C}return et(T)||(a=!0),_++,i.consume(T),T===92?c:g}function c(T){return T===91||T===92||T===93?(i.consume(T),_++,g):g(T)}function C(T){return T===58?(i.enter("definitionMarker"),i.consume(T),i.exit("definitionMarker"),S.includes(b)||S.push(b),Ie(i,w,"gfmFootnoteDefinitionWhitespace")):l(T)}function w(T){return s(T)}}function Kw(i,s,l){return i.check(Hs,s,i.attempt(Pw,s,l))}function Xw(i){i.exit("gfmFootnoteDefinition")}function Ww(i,s,l){const o=this;return Ie(i,S,"gfmFootnoteDefinitionIndent",5);function S(b){const _=o.events[o.events.length-1];return _&&_[1].type==="gfmFootnoteDefinitionIndent"&&_[2].sliceSerialize(_[1],!0).length===4?s(b):l(b)}}function $w(i){let l=(i||{}).singleTilde;const o={name:"strikethrough",tokenize:b,resolveAll:S};return l==null&&(l=!0),{text:{126:o},insideSpan:{null:[o]},attentionMarkers:{null:[126]}};function S(_,a){let u=-1;for(;++u<_.length;)if(_[u][0]==="enter"&&_[u][1].type==="strikethroughSequenceTemporary"&&_[u][1]._close){let h=u;for(;h--;)if(_[h][0]==="exit"&&_[h][1].type==="strikethroughSequenceTemporary"&&_[h][1]._open&&_[u][1].end.offset-_[u][1].start.offset===_[h][1].end.offset-_[h][1].start.offset){_[u][1].type="strikethroughSequence",_[h][1].type="strikethroughSequence";const g={type:"strikethrough",start:Object.assign({},_[h][1].start),end:Object.assign({},_[u][1].end)},c={type:"strikethroughText",start:Object.assign({},_[h][1].end),end:Object.assign({},_[u][1].start)},C=[["enter",g,a],["enter",_[h][1],a],["exit",_[h][1],a],["enter",c,a]],w=a.parser.constructs.insideSpan.null;w&&Zt(C,C.length,0,ha(w,_.slice(h+1,u),a)),Zt(C,C.length,0,[["exit",c,a],["enter",_[u][1],a],["exit",_[u][1],a],["exit",g,a]]),Zt(_,h-1,u-h+3,C),u=h+C.length-2;break}}for(u=-1;++u<_.length;)_[u][1].type==="strikethroughSequenceTemporary"&&(_[u][1].type="data");return _}function b(_,a,u){const h=this.previous,g=this.events;let c=0;return C;function C(T){return h===126&&g[g.length-1][1].type!=="characterEscape"?u(T):(_.enter("strikethroughSequenceTemporary"),w(T))}function w(T){const x=Dr(h);if(T===126)return c>1?u(T):(_.consume(T),c++,w);if(c<2&&!l)return u(T);const v=_.exit("strikethroughSequenceTemporary"),p=Dr(T);return v._open=!p||p===2&&!!x,v._close=!x||x===2&&!!p,a(T)}}}class Qw{constructor(){this.map=[]}add(s,l,o){Zw(this,s,l,o)}consume(s){if(this.map.sort(function(b,_){return b[0]-_[0]}),this.map.length===0)return;let l=this.map.length;const o=[];for(;l>0;)l-=1,o.push(s.slice(this.map[l][0]+this.map[l][1]),this.map[l][2]),s.length=this.map[l][0];o.push(s.slice()),s.length=0;let S=o.pop();for(;S;){for(const b of S)s.push(b);S=o.pop()}this.map.length=0}}function Zw(i,s,l,o){let S=0;if(!(l===0&&o.length===0)){for(;S<i.map.length;){if(i.map[S][0]===s){i.map[S][1]+=l,i.map[S][2].push(...o);return}S+=1}i.map.push([s,l,o])}}function Jw(i,s){let l=!1;const o=[];for(;s<i.length;){const S=i[s];if(l){if(S[0]==="enter")S[1].type==="tableContent"&&o.push(i[s+1][1].type==="tableDelimiterMarker"?"left":"none");else if(S[1].type==="tableContent"){if(i[s-1][1].type==="tableDelimiterMarker"){const b=o.length-1;o[b]=o[b]==="left"?"center":"right"}}else if(S[1].type==="tableDelimiterRow")break}else S[0]==="enter"&&S[1].type==="tableDelimiterRow"&&(l=!0);s+=1}return o}function ex(){return{flow:{null:{name:"table",tokenize:tx,resolveAll:ix}}}}function tx(i,s,l){const o=this;let S=0,b=0,_;return a;function a(j){let P=o.events.length-1;for(;P>-1;){const Y=o.events[P][1].type;if(Y==="lineEnding"||Y==="linePrefix")P--;else break}const V=P>-1?o.events[P][1].type:null,q=V==="tableHead"||V==="tableRow"?A:u;return q===A&&o.parser.lazy[o.now().line]?l(j):q(j)}function u(j){return i.enter("tableHead"),i.enter("tableRow"),h(j)}function h(j){return j===124||(_=!0,b+=1),g(j)}function g(j){return j===null?l(j):Ce(j)?b>1?(b=0,o.interrupt=!0,i.exit("tableRow"),i.enter("lineEnding"),i.consume(j),i.exit("lineEnding"),w):l(j):ze(j)?Ie(i,g,"whitespace")(j):(b+=1,_&&(_=!1,S+=1),j===124?(i.enter("tableCellDivider"),i.consume(j),i.exit("tableCellDivider"),_=!0,g):(i.enter("data"),c(j)))}function c(j){return j===null||j===124||et(j)?(i.exit("data"),g(j)):(i.consume(j),j===92?C:c)}function C(j){return j===92||j===124?(i.consume(j),c):c(j)}function w(j){return o.interrupt=!1,o.parser.lazy[o.now().line]?l(j):(i.enter("tableDelimiterRow"),_=!1,ze(j)?Ie(i,T,"linePrefix",o.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(j):T(j))}function T(j){return j===45||j===58?v(j):j===124?(_=!0,i.enter("tableCellDivider"),i.consume(j),i.exit("tableCellDivider"),x):R(j)}function x(j){return ze(j)?Ie(i,v,"whitespace")(j):v(j)}function v(j){return j===58?(b+=1,_=!0,i.enter("tableDelimiterMarker"),i.consume(j),i.exit("tableDelimiterMarker"),p):j===45?(b+=1,p(j)):j===null||Ce(j)?E(j):R(j)}function p(j){return j===45?(i.enter("tableDelimiterFiller"),d(j)):R(j)}function d(j){return j===45?(i.consume(j),d):j===58?(_=!0,i.exit("tableDelimiterFiller"),i.enter("tableDelimiterMarker"),i.consume(j),i.exit("tableDelimiterMarker"),m):(i.exit("tableDelimiterFiller"),m(j))}function m(j){return ze(j)?Ie(i,E,"whitespace")(j):E(j)}function E(j){return j===124?T(j):j===null||Ce(j)?!_||S!==b?R(j):(i.exit("tableDelimiterRow"),i.exit("tableHead"),s(j)):R(j)}function R(j){return l(j)}function A(j){return i.enter("tableRow"),L(j)}function L(j){return j===124?(i.enter("tableCellDivider"),i.consume(j),i.exit("tableCellDivider"),L):j===null||Ce(j)?(i.exit("tableRow"),s(j)):ze(j)?Ie(i,L,"whitespace")(j):(i.enter("data"),k(j))}function k(j){return j===null||j===124||et(j)?(i.exit("data"),L(j)):(i.consume(j),j===92?O:k)}function O(j){return j===92||j===124?(i.consume(j),k):k(j)}}function ix(i,s){let l=-1,o=!0,S=0,b=[0,0,0,0],_=[0,0,0,0],a=!1,u=0,h,g,c;const C=new Qw;for(;++l<i.length;){const w=i[l],T=w[1];w[0]==="enter"?T.type==="tableHead"?(a=!1,u!==0&&(L_(C,s,u,h,g),g=void 0,u=0),h={type:"table",start:Object.assign({},T.start),end:Object.assign({},T.end)},C.add(l,0,[["enter",h,s]])):T.type==="tableRow"||T.type==="tableDelimiterRow"?(o=!0,c=void 0,b=[0,0,0,0],_=[0,l+1,0,0],a&&(a=!1,g={type:"tableBody",start:Object.assign({},T.start),end:Object.assign({},T.end)},C.add(l,0,[["enter",g,s]])),S=T.type==="tableDelimiterRow"?2:g?3:1):S&&(T.type==="data"||T.type==="tableDelimiterMarker"||T.type==="tableDelimiterFiller")?(o=!1,_[2]===0&&(b[1]!==0&&(_[0]=_[1],c=na(C,s,b,S,void 0,c),b=[0,0,0,0]),_[2]=l)):T.type==="tableCellDivider"&&(o?o=!1:(b[1]!==0&&(_[0]=_[1],c=na(C,s,b,S,void 0,c)),b=_,_=[b[1],l,0,0])):T.type==="tableHead"?(a=!0,u=l):T.type==="tableRow"||T.type==="tableDelimiterRow"?(u=l,b[1]!==0?(_[0]=_[1],c=na(C,s,b,S,l,c)):_[1]!==0&&(c=na(C,s,_,S,l,c)),S=0):S&&(T.type==="data"||T.type==="tableDelimiterMarker"||T.type==="tableDelimiterFiller")&&(_[3]=l)}for(u!==0&&L_(C,s,u,h,g),C.consume(s.events),l=-1;++l<s.events.length;){const w=s.events[l];w[0]==="enter"&&w[1].type==="table"&&(w[1]._align=Jw(s.events,l))}return i}function na(i,s,l,o,S,b){const _=o===1?"tableHeader":o===2?"tableDelimiter":"tableData",a="tableContent";l[0]!==0&&(b.end=Object.assign({},Ar(s.events,l[0])),i.add(l[0],0,[["exit",b,s]]));const u=Ar(s.events,l[1]);if(b={type:_,start:Object.assign({},u),end:Object.assign({},u)},i.add(l[1],0,[["enter",b,s]]),l[2]!==0){const h=Ar(s.events,l[2]),g=Ar(s.events,l[3]),c={type:a,start:Object.assign({},h),end:Object.assign({},g)};if(i.add(l[2],0,[["enter",c,s]]),o!==2){const C=s.events[l[2]],w=s.events[l[3]];if(C[1].end=Object.assign({},w[1].end),C[1].type="chunkText",C[1].contentType="text",l[3]>l[2]+1){const T=l[2]+1,x=l[3]-l[2]-1;i.add(T,x,[])}}i.add(l[3]+1,0,[["exit",c,s]])}return S!==void 0&&(b.end=Object.assign({},Ar(s.events,S)),i.add(S,0,[["exit",b,s]]),b=void 0),b}function L_(i,s,l,o,S){const b=[],_=Ar(s.events,l);S&&(S.end=Object.assign({},_),b.push(["exit",S,s])),o.end=Object.assign({},_),b.push(["exit",o,s]),i.add(l+1,0,b)}function Ar(i,s){const l=i[s],o=l[0]==="enter"?"start":"end";return l[1][o]}const nx={name:"tasklistCheck",tokenize:sx};function rx(){return{text:{91:nx}}}function sx(i,s,l){const o=this;return S;function S(u){return o.previous!==null||!o._gfmTasklistFirstContentOfListItem?l(u):(i.enter("taskListCheck"),i.enter("taskListCheckMarker"),i.consume(u),i.exit("taskListCheckMarker"),b)}function b(u){return et(u)?(i.enter("taskListCheckValueUnchecked"),i.consume(u),i.exit("taskListCheckValueUnchecked"),_):u===88||u===120?(i.enter("taskListCheckValueChecked"),i.consume(u),i.exit("taskListCheckValueChecked"),_):l(u)}function _(u){return u===93?(i.enter("taskListCheckMarker"),i.consume(u),i.exit("taskListCheckMarker"),i.exit("taskListCheck"),a):l(u)}function a(u){return Ce(u)?s(u):ze(u)?i.check({tokenize:lx},s,l)(u):l(u)}}function lx(i,s,l){return Ie(i,o,"whitespace");function o(S){return S===null?l(S):s(S)}}function ax(i){return W_([Mw(),Fw(),$w(i),ex(),rx()])}const ox={};function ux(i){const s=this,l=i||ox,o=s.data(),S=o.micromarkExtensions||(o.micromarkExtensions=[]),b=o.fromMarkdownExtensions||(o.fromMarkdownExtensions=[]),_=o.toMarkdownExtensions||(o.toMarkdownExtensions=[]);S.push(ax(l)),b.push(Tw()),_.push(Dw(l))}function cx({settings:i,busy:s=!1,promptPreviews:l,testResult:o,onSave:S,onTest:b,onClose:_}){const[a,u]=ge.useState(i),[h,g]=ge.useState(i.apiKey??"");return ge.useEffect(()=>{u(i),g(i.apiKey??"")},[i]),F.jsx("div",{className:"modal-backdrop",children:F.jsxs("section",{className:"translation-settings-modal",role:"dialog","aria-modal":"true","aria-label":"Translation Settings",children:[F.jsxs("header",{children:[F.jsxs("div",{children:[F.jsx("h2",{children:"Translation Settings"}),F.jsx("p",{children:"Use an OpenAI-compatible endpoint for the embedded translation panel."})]}),F.jsx("button",{type:"button",onClick:_,children:"Close"})]}),F.jsxs("div",{className:"translation-settings-grid",children:[F.jsxs("label",{children:[F.jsx("span",{children:"Base URL"}),F.jsx("input",{value:a.baseUrl,onChange:c=>u({...a,baseUrl:c.target.value}),placeholder:"https://api.openai.com/v1"})]}),F.jsxs("label",{children:[F.jsx("span",{children:"API key"}),F.jsx("input",{value:h,onChange:c=>g(c.target.value),placeholder:"API key",autoCapitalize:"off",autoComplete:"off",autoCorrect:"off",spellCheck:!1,type:"text"})]}),F.jsxs("label",{children:[F.jsx("span",{children:"Model"}),F.jsx("input",{value:a.model,onChange:c=>u({...a,model:c.target.value})})]}),F.jsxs("label",{children:[F.jsx("span",{children:"Target language"}),F.jsx("input",{value:a.targetLanguage,onChange:c=>u({...a,targetLanguage:c.target.value})})]}),F.jsxs("label",{children:[F.jsx("span",{children:"Use context"}),F.jsx("input",{checked:a.contextEnabled,type:"checkbox",onChange:c=>u({...a,contextEnabled:c.target.checked})})]}),F.jsxs("label",{children:[F.jsx("span",{children:"Timeout ms"}),F.jsx("input",{min:3e3,type:"number",value:a.requestTimeoutMs,onChange:c=>u({...a,requestTimeoutMs:Number(c.target.value)})})]}),F.jsxs("label",{children:[F.jsx("span",{children:"Temperature"}),F.jsx("input",{min:0,max:1,step:.1,type:"number",value:a.temperature,onChange:c=>u({...a,temperature:Number(c.target.value)})})]})]}),F.jsxs("section",{className:"translation-prompt-settings",children:[F.jsxs("header",{children:[F.jsxs("div",{children:[F.jsx("h3",{children:"Translation Prompts"}),F.jsx("p",{children:"Edit the three cc-pm style prompt slots directly."})]}),F.jsx("button",{type:"button",disabled:s,onClick:()=>u({...a,prompts:void 0}),children:"Reset prompts"})]}),F.jsx("div",{className:"translation-prompt-stack",children:l.map(c=>F.jsxs("label",{children:[F.jsx("span",{children:c.label}),F.jsx("textarea",{value:fx(a,c),onChange:C=>u({...a,prompts:hx(a.prompts,c.key,C.target.value,c.defaultPrompt)})})]},c.key))})]}),o?F.jsx("div",{className:o.ok?"translation-test-result is-ok":"translation-test-result is-error",children:o.ok?`Connection ok: ${o.model} in ${o.elapsedMs}ms`:o.error}):null,F.jsxs("footer",{children:[F.jsx("button",{type:"button",disabled:s,onClick:b,children:"Test Connection"}),F.jsx("button",{type:"button",disabled:s,onClick:()=>void S({...a,enabled:!0,translateOutput:!0,translateUserInput:!0,inputMode:"review-before-send"},h.trim()),children:"Save"})]})]})})}function hx(i,s,l,o){const S={...i??{}};return l.trim()&&l!==o?S[s]=l:delete S[s],Object.keys(S).length>0?S:void 0}function fx(i,s){var l;return((l=i.prompts)==null?void 0:l[s.key])??s.defaultPrompt}function dx({active:i=!0,taskSlug:s,role:l,sessionId:o}){const[S,b]=ge.useState(null),[_,a]=ge.useState([]),[u,h]=ge.useState(""),[g,c]=ge.useState(!1),[C,w]=ge.useState(!1),[T,x]=ge.useState(!1),[v,p]=ge.useState("ready"),[d,m]=ge.useState(""),[E,R]=ge.useState(Date.now()),[A,L]=ge.useState(!1),[k,O]=ge.useState(""),[j,P]=ge.useState(!1),[V,q]=ge.useState([]),[Y,$]=ge.useState(),[G,J]=ge.useState(0),ne=ge.useRef(i),z=ge.useRef(1),M=ge.useRef(null);ge.useEffect(()=>{ne.current=i},[i]),ge.useEffect(()=>{Promise.all([je.getTranslationSettings(),je.getTranslationPrompts()]).then(([Q,de])=>{b(Q),q(de)}).catch(Q=>O(Q.message))},[]),ge.useEffect(()=>{a([]),O(""),p("ready"),m(""),z.current=1;let Q=!1,de;const pe=()=>{Q||(de=window.setTimeout(ke,ne.current?200:1e3))},ke=async()=>{if(!Q)try{const xe=await je.pollTranslationSession(o,z.current);if(Q)return;H(xe.events),z.current=xe.nextCursor,p(xe.status),ne.current&&m(bx(new Date().toISOString()))}catch(xe){Q||O(xe instanceof Error?xe.message:"Translation poll failed.")}finally{pe()}};return je.startTranslationSession(s,l).then(xe=>{Q||(p(xe.status),z.current=xe.nextCursor,ke())}).catch(xe=>{Q||O(xe instanceof Error?xe.message:"Translation start failed.")}),()=>{Q=!0,de!==void 0&&window.clearTimeout(de)}},[o,s,l,G]),ge.useEffect(()=>{var Q;i&&((Q=M.current)==null||Q.scrollIntoView({block:"nearest"}))},[i,_.length]);const B=_x(_);ge.useEffect(()=>{if(!B)return;R(Date.now());const Q=window.setInterval(()=>R(Date.now()),250);return()=>window.clearInterval(Q)},[B]);async function I(Q=!1){if(S){L(!0),O(""),c(!1);try{const de=await je.translateUserInput(s,l,{text:u,mode:Q?"auto-send":"review-before-send",useContext:S.contextEnabled,send:Q});x(de.contextUsed),de.sent?(h(""),c(!1)):(h(de.englishPreview),c(!0))}catch(de){O(de instanceof Error?de.message:"Translation failed.")}finally{L(!1)}}}function H(Q){if(Q.length===0)return;for(const pe of Q)pe.type==="status"?p(pe.status):pe.type==="error"&&O(pe.message);const de=Q.filter(pe=>pe.type==="entry");de.length>0&&a(pe=>de.reduce((ke,xe)=>Sx(ke,xe.entry),pe))}async function ie(){if(u.trim()){L(!0),O("");try{await je.sendTranslatedInput(s,l,{englishText:u}),h(""),c(!1),x(!1)}catch(Q){O(Q instanceof Error?Q.message:"Failed to send English input.")}finally{L(!1)}}}function he(Q){Q.key!=="Enter"||Q.shiftKey||Q.nativeEvent.isComposing||(Q.preventDefault(),!A&&u.trim()&&(g?ie():I(C)))}async function fe(Q,de){L(!0),O("");try{const pe=await je.updateTranslationSettings({...Q,...de!==void 0?{apiKey:de}:{}}),ke=await je.getTranslationPrompts();b(pe),q(ke),P(!1),J(xe=>xe+1)}catch(pe){O(pe instanceof Error?pe.message:"Failed to save translation settings.")}finally{L(!1)}}async function X(){L(!0),O("");try{$(await je.testTranslationProvider())}catch(Q){O(Q instanceof Error?Q.message:"Provider test failed.")}finally{L(!1)}}async function N(){a([]),z.current=1,await je.clearTranslationSession(o).catch(Q=>O(Q.message))}if(!S)return F.jsx("aside",{className:"translation-panel",children:F.jsx("p",{className:"muted",children:"Loading translation settings..."})});const re=mx(_,v,E);return F.jsxs("aside",{className:"translation-panel",children:[F.jsxs("header",{className:"translation-panel-header",children:[F.jsxs("div",{className:"translation-panel-titlebar",children:[F.jsx("h2",{children:"Translation"}),F.jsxs("div",{className:"translation-panel-actions",children:[F.jsx("button",{"aria-pressed":C,className:`auto-send-toggle${C?" is-active":""}`,type:"button",onClick:()=>w(Q=>!Q),children:C?"✅ Auto-send":"× Auto-send"}),F.jsx("button",{type:"button",onClick:()=>P(!0),children:"Settings"}),F.jsx("button",{type:"button",onClick:()=>void N(),children:"Clear"})]})]}),F.jsxs("div",{className:"translation-status-row",children:[F.jsxs("p",{children:[S.model," · ",re,T?" · context used":""]}),F.jsx("p",{children:d?`poll ${d}`:"poll -"})]})]}),k?F.jsx("div",{className:"error-banner",children:k}):null,F.jsxs("div",{className:"translation-entry-list",children:[_.length===0?F.jsx("p",{className:"muted",children:"Translated Claude Code output will appear here."}):null,_.map(Q=>F.jsx(px,{entry:Q},Q.id)),F.jsx("div",{ref:M})]}),F.jsx("div",{className:"translation-composer",children:F.jsxs("div",{className:"translation-composer-row",children:[F.jsx("textarea",{value:u,onChange:Q=>{h(Q.target.value),Q.target.value.trim()||c(!1)},onKeyDown:he,placeholder:"输入中文,先翻译成英文工程指令..."}),F.jsx("div",{className:"translation-composer-actions",children:F.jsx("button",{type:"button",disabled:A||!g||!u.trim(),onClick:()=>void ie(),children:"Send English"})})]})}),j?F.jsx(cx,{settings:S,busy:A,promptPreviews:V,testResult:Y,onSave:fe,onTest:X,onClose:()=>P(!1)}):null]})}function px({entry:i}){const s=vx(i),l=i.sourceKind==="tool-output",o=i.direction==="user-input-to-english",S=["translation-entry",`is-${i.sourceKind}`,o?"is-user-input":""].filter(Boolean).join(" ");return F.jsxs("article",{className:S,children:[l?F.jsx("pre",{children:s}):F.jsx("div",{className:"translation-markdown",children:F.jsx($b,{remarkPlugins:[ux],children:s})}),i.warning?F.jsx("p",{className:"translation-entry-note",children:i.warning}):null,i.error?F.jsx("p",{className:"translation-entry-note is-error",children:i.error}):null]})}function _x(i){const s=i.find(Um);return(s==null?void 0:s.translationStartedAt)??(s==null?void 0:s.createdAt)}function mx(i,s,l){const o=i.find(Um);if(o)return`translating ${yx(Math.max(0,l-gx(o)))}`;const S=i.at(-1);return(S==null?void 0:S.status)==="failed"||s==="failed"?"error":s}function Um(i){return i.status==="queued"||i.status==="translating"}function gx(i){const s=Date.parse(i.translationStartedAt??i.createdAt);return Number.isFinite(s)?s:Date.now()}function vx(i){return i.status==="queued"||i.status==="translating"?i.sourceText:i.status==="translated"?i.translatedText:i.translatedText||i.sourceText}function Sx(i,s){return i.findIndex(o=>o.id===s.id)===-1?[...i,s]:i.map(o=>o.id===s.id?s:o)}function yx(i){if(i<1e3)return`${Math.max(.1,i/1e3).toFixed(1)}s`;const s=i/1e3;if(s<60)return`${s.toFixed(1)}s`;const l=Math.floor(s/60),o=Math.floor(s%60).toString().padStart(2,"0");return`${l}:${o}`}function bx(i){const s=new Date(i);return Number.isNaN(s.getTime())?i:s.toLocaleTimeString()}function Cx({role:i,session:s,permissionMode:l,active:o=!0,busy:S,onPermissionModeChange:b,onStart:_,onResume:a,onStop:u,onRestart:h,onTerminalEvent:g}){const[c,C]=ge.useState(!1);return F.jsxs("section",{className:"session-console",children:[F.jsxs("div",{className:"session-console-top",children:[F.jsx(NS,{role:i,session:s,permissionMode:l,busy:S,onPermissionModeChange:b,onStart:_,onResume:a,onStop:u,onRestart:h}),F.jsx("button",{"aria-pressed":c,className:`translation-toggle${c?" is-active":""}`,type:"button",onClick:()=>C(w=>!w),children:c?"✅ Translate":"× Translate"})]}),(s==null?void 0:s.status)==="running"?F.jsx(wx,{active:o,onTerminalEvent:g,role:i,session:s,taskSlug:s.taskSlug,translationEnabled:c}):F.jsxs("div",{className:"terminal-empty",children:[F.jsx("strong",{children:i}),F.jsx("span",{children:s!=null&&s.claudeSessionId?"Resume this role to reconnect its Claude Code conversation.":"Start this role to open an embedded Claude Code terminal."})]})]})}function wx({active:i,onTerminalEvent:s,role:l,session:o,taskSlug:S,translationEnabled:b}){return F.jsxs("div",{className:b?"session-console-body has-translation":"session-console-body",children:[F.jsx("div",{className:"terminal-pane",children:F.jsx(zS,{sessionId:o.id,active:i,onEvent:s},o.id)}),b?F.jsx("div",{className:"translation-pane",children:F.jsx(dx,{active:i,taskSlug:S,role:l,sessionId:o.id},o.id)}):null]})}function xx({task:i,activeRole:s,onTaskChanged:l,onActiveRoleChange:o,onWorkflowChanged:S,onMessagesChanged:b,onOrchestrationChanged:_,onEventsChanged:a}){const[u,h]=ge.useState(null),[g,c]=ge.useState({"project-manager":"default",architect:"default",coder:"default",reviewer:"default"}),[C,w]=ge.useState(!1),[T,x]=ge.useState(""),[v,p]=ge.useState([]),d=ge.useCallback(async()=>{const[L,k,O]=await Promise.all([je.getTaskStatus(i.taskSlug),je.listMessages(i.taskSlug),je.getOrchestrationState(i.taskSlug)]);h(L),S==null||S(L.workflow),b==null||b(k),_==null||_(O)},[b,_,S,i.taskSlug]);ge.useEffect(()=>{d().catch(L=>x(L.message))},[d]),ge.useEffect(()=>{p([]),a==null||a([])},[a,i.taskSlug]),ge.useEffect(()=>{c(L=>{let k=!1;const O={...L};for(const j of(u==null?void 0:u.sessions)??[])O[j.role]!==j.permissionMode&&(O[j.role]=j.permissionMode,k=!0);return k?O:L})},[u==null?void 0:u.sessions]),ge.useEffect(()=>{const L=window.setInterval(()=>{Promise.all([je.getTaskStatus(i.taskSlug),je.listMessages(i.taskSlug),je.getOrchestrationState(i.taskSlug)]).then(([k,O,j])=>{h(k),S==null||S(k.workflow),b==null||b(O),_==null||_(j)}).catch(k=>x(k.message))},3e3);return()=>window.clearInterval(L)},[b,_,S,i.taskSlug]);async function m(L){w(!0),x("");try{await L(),await d(),await l()}catch(k){x(k instanceof Error?k.message:"Action failed.")}finally{w(!1)}}async function E(){const L=i.worktreePath?[`Close task "${i.taskSlug}"?`,"","This is destructive:","- stops VCM-managed running role sessions for this task",`- deletes the task worktree: ${i.worktreePath}`,`- deletes the Git branch: ${i.branch}`,"- deletes VCM task/session/message/orchestration state","","VCM will not check running sessions or uncommitted changes before closing."].join(`
87
+ `):[`Close task "${i.taskSlug}"?`,"","This task was created without a separate worktree/branch.","VCM will stop VCM-managed running role sessions for this task.","VCM will delete task/session/message/orchestration state only.","","VCM will not check running sessions or uncommitted changes before closing."].join(`
88
88
  `);if(window.confirm(L)){w(!0),x("");try{await je.cleanupTask(i.taskSlug,{force:!0,deleteBranch:!!i.worktreePath,forceDeleteBranch:!0}),R(`closed ${i.taskSlug}`),await l()}catch(O){x(O instanceof Error?O.message:"Close task failed.")}finally{w(!1)}}}function R(L){p(k=>{const O=[...k,`${new Date().toLocaleTimeString()} ${L}`];return a==null||a(O),O})}function A(L,k){c(O=>({...O,[L]:k}))}return F.jsxs("div",{className:"task-workspace",children:[F.jsxs("header",{className:"workspace-header",children:[F.jsxs("div",{className:"workspace-title-line",children:[F.jsx("span",{className:"eyebrow",children:"Task Workspace"}),F.jsx("h1",{children:i.title||i.taskSlug}),F.jsx("span",{className:"workspace-branch",children:i.branch}),i.worktreePath?F.jsx("span",{className:"workspace-worktree",children:i.worktreePath}):null]}),F.jsx(AS,{activeRole:s,sessions:(u==null?void 0:u.sessions)??[],onSelect:o}),F.jsx("button",{type:"button",onClick:()=>void d(),children:"Refresh"}),F.jsx("button",{className:"danger-button",type:"button",disabled:C,onClick:()=>void E(),children:"Close Task"})]}),T?F.jsx("div",{className:"error-banner",children:T}):null,F.jsx("div",{className:"workspace-grid",children:F.jsx("div",{className:"workspace-main",children:F.jsx("div",{className:"role-console-stack",children:ua.map(L=>{const k=L.name,O=k===s,j=O_((u==null?void 0:u.sessions)??[],k);return F.jsx("div",{className:O?"role-console-panel is-active":"role-console-panel","aria-hidden":!O,children:F.jsx(Cx,{role:k,session:j,permissionMode:g[k],active:O,busy:C,onPermissionModeChange:P=>A(k,P),onStart:()=>void m(async()=>{await je.startRoleSession(i.taskSlug,k,{cols:100,rows:28,permissionMode:g[k]}),R(`started ${k} with ${g[k]}`)}),onResume:()=>void m(async()=>{await je.resumeRoleSession(i.taskSlug,k,{cols:100,rows:28,permissionMode:g[k]}),R(`resumed ${k} with ${g[k]}`)}),onStop:()=>void m(async()=>{await je.stopRoleSession(i.taskSlug,k),R(`stopped ${k}`)}),onRestart:()=>void m(async()=>{await je.restartRoleSession(i.taskSlug,k,{cols:100,rows:28,permissionMode:g[k]}),R(`restarted ${k} with ${g[k]}`)}),onTerminalEvent:P=>R(`${L.label}: ${P}`)})},k)})})})})]})}function Ex(){const[i,s]=ge.useState(null),[l,o]=ge.useState([]),[S,b]=ge.useState(null),[_,a]=ge.useState(null),[u,h]=ge.useState([]),[g,c]=ge.useState(null),[C,w]=ge.useState(null),[T,x]=ge.useState(null),[v,p]=ge.useState(null),[d,m]=ge.useState(null),[E,R]=ge.useState("project-manager"),[A,L]=ge.useState("system"),[k,O]=ge.useState(!1),[j,P]=ge.useState(!1),[V,q]=ge.useState(""),Y=ge.useMemo(()=>pS(u,g),[u,g]),$=ge.useCallback(N=>{Y!=null&&Y.taskSlug&&w({taskSlug:Y.taskSlug,workflow:N})},[Y==null?void 0:Y.taskSlug]),G=ge.useCallback(N=>{Y!=null&&Y.taskSlug&&x({taskSlug:Y.taskSlug,messages:N})},[Y==null?void 0:Y.taskSlug]),J=ge.useCallback(N=>{Y!=null&&Y.taskSlug&&p({taskSlug:Y.taskSlug,orchestration:N})},[Y==null?void 0:Y.taskSlug]),ne=ge.useCallback(N=>{Y!=null&&Y.taskSlug&&m({taskSlug:Y.taskSlug,events:N})},[Y==null?void 0:Y.taskSlug]);async function z(){const N=await je.listTasks();return h(N),c(re=>{var Q;return re&&N.some(de=>de.taskSlug===re)?re:((Q=N[0])==null?void 0:Q.taskSlug)??null}),N}async function M(){const N=await je.getHarnessStatus();return b(N),N}async function B(){const N=await je.getRecentRepositoryPaths();return o(N),N}async function I(N){const[re,Q]=await Promise.all([je.listMessages(N),je.getOrchestrationState(N)]);x({taskSlug:N,messages:re}),p({taskSlug:N,orchestration:Q})}ge.useEffect(()=>{Promise.all([je.getCurrentProject(),je.getRecentRepositoryPaths(),je.getAppPreferences()]).then(async([N,re,Q])=>{s(N),o(re),L(Q.themeMode),N&&await Promise.all([z(),M()])}).catch(N=>q(N.message))},[]),ge.useEffect(()=>{const N=window.matchMedia("(prefers-color-scheme: dark)"),re=()=>O(N.matches);return re(),N.addEventListener("change",re),()=>N.removeEventListener("change",re)},[]),ge.useEffect(()=>{const N=A==="system"?k?"dark":"light":A;document.documentElement.dataset.theme=N,document.documentElement.dataset.themeMode=A},[k,A]);async function H(N){P(!0),q("");try{await N()}catch(re){q(re instanceof Error?re.message:"Action failed.")}finally{P(!1)}}const ie=C&&C.taskSlug===(Y==null?void 0:Y.taskSlug)?C.workflow:null,he=T&&T.taskSlug===(Y==null?void 0:Y.taskSlug)?T.messages:[],fe=v&&v.taskSlug===(Y==null?void 0:Y.taskSlug)?v.orchestration:null,X=d&&d.taskSlug===(Y==null?void 0:Y.taskSlug)?d.events:[];return F.jsxs(dS,{sidebar:F.jsx(wS,{project:i,recentRepositoryPaths:l,tasks:u,activeTaskSlug:(Y==null?void 0:Y.taskSlug)??null,workflow:ie,messages:he,orchestration:fe,events:X,harnessStatus:S,harnessApplyResult:_,busy:j,onConnect:N=>H(async()=>{const re=await je.connectProject({repoPath:N});s(re),a(null),await Promise.all([z(),M(),B()])}),onRefreshHarness:()=>H(async()=>{a(null),await M()}),onApplyHarness:()=>H(async()=>{const N=await je.applyHarness();a(N),await M()}),onCreateTask:N=>H(async()=>{const re=await je.createTask(N);await z(),c(re.taskSlug)}),onSelectTask:c,onOrchestrationModeChange:N=>{Y&&H(async()=>{const re=await je.updateOrchestrationState(Y.taskSlug,{mode:N});p({taskSlug:Y.taskSlug,orchestration:re})})},themeMode:A,onThemeModeChange:N=>{L(N),H(async()=>{const re=await je.updateAppPreferences({themeMode:N});L(re.themeMode)})},onStageMessage:N=>{H(async()=>{const re=await je.stageMessage(N.taskSlug,N.id);R(re.toRole),await I(N.taskSlug)})},onRejectMessage:N=>{H(async()=>{await je.rejectMessage(N.taskSlug,N.id),await I(N.taskSlug)})},onOpenMessageRole:R}),children:[V?F.jsx("div",{className:"error-banner",children:V}):null,i&&Y?F.jsx(xx,{task:Y,activeRole:E,onTaskChanged:async()=>{await z()},onActiveRoleChange:R,onWorkflowChanged:$,onMessagesChanged:G,onOrchestrationChanged:J,onEventsChanged:ne}):F.jsxs("section",{className:"empty-workspace",children:[F.jsx("h1",{children:i?"Create a task to open the workspace":"Connect a repository to begin"}),F.jsx("p",{children:i?"Tasks create local role commands, logs, and handoff artifacts for the selected repository.":"VibeCodingMaster will create a local task workspace, role sessions, logs, and handoff artifacts."})]})]})}const Im=document.getElementById("root");if(!Im)throw new Error("Missing #root element.");fS.createRoot(Im).render(F.jsx(ge.StrictMode,{children:F.jsx(Ex,{})}));
@@ -4,8 +4,8 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>VibeCodingMaster</title>
7
- <script type="module" crossorigin src="/assets/index-B1vIIwLq.js"></script>
8
- <link rel="stylesheet" crossorigin href="/assets/index-DPyKuEOz.css">
7
+ <script type="module" crossorigin src="/assets/index-DaHXq14j.js"></script>
8
+ <link rel="stylesheet" crossorigin href="/assets/index-Bi4X3GSR.css">
9
9
  </head>
10
10
  <body>
11
11
  <div id="root"></div>
@@ -97,13 +97,12 @@ repo/
97
97
 
98
98
  .ai/
99
99
  vcm/ # ignored local VCM control state
100
- task-specs/
101
- handoffs/
102
- <task-slug>/
100
+ handoffs/
103
101
  architecture-plan.md
104
102
  implementation-log.md
105
103
  validation-log.md
106
104
  review-report.md
105
+ task-specs/
107
106
  state/
108
107
  progress.md
109
108
  decisions.md
@@ -213,7 +212,7 @@ Role-specific behavior lives in `.claude/agents/`.
213
212
  - Default core roles are `project-manager`, `architect`, `coder`, and `reviewer`.
214
213
  - The `project-manager` role owns user communication, task routing, role commands, handoff verification, final status reporting, and PR preparation after required gates pass.
215
214
  - Do not let one coding session own architecture/plan decisions, implementation, final testing responsibility, and review.
216
- - Role outputs are exchanged through `.ai/handoffs/<task-slug>/`, not through chat history.
215
+ - Role outputs are exchanged through `.ai/vcm/handoffs/`, not through chat history.
217
216
  - When the required role route includes `architect`, coding must not start until the architecture and plan artifact exists.
218
217
  - If the current session was not started with the required role, stop and ask the user to restart with `claude --agent <role>`; do not pretend to be that role inside the wrong session.
219
218
  - Critical global rules may be repeated in role agent files for defense in depth, but repeated rules must use stable rule IDs and be checked by `tools/check-agent-rules`. Do not maintain untracked manual copies.
@@ -628,7 +627,7 @@ Role command examples:
628
627
  ```text
629
628
  architect command:
630
629
  read the task spec, architecture docs, module map, and relevant module-local CLAUDE.md
631
- produce .ai/handoffs/<task-slug>/architecture-plan.md
630
+ produce .ai/vcm/handoffs/architecture-plan.md
632
631
  define file responsibilities, public contracts, test contracts, phases, validation, and Replan triggers
633
632
  do not edit production code
634
633
 
@@ -726,8 +725,8 @@ architect
726
725
  owns architecture and plan
727
726
  defines module boundaries, file responsibilities, public contracts, dependency direction, risk, and phases
728
727
  owns post-review docs sync and architecture drift checks before PM final acceptance
729
- outputs .ai/handoffs/<task-slug>/architecture-plan.md
730
- outputs .ai/handoffs/<task-slug>/docs-sync-report.md when a post-review docs sync gate is required
728
+ outputs .ai/vcm/handoffs/architecture-plan.md
729
+ outputs .ai/vcm/handoffs/docs-sync-report.md when a post-review docs sync gate is required
731
730
  must not implement production code
732
731
 
733
732
  coder
@@ -743,7 +742,7 @@ reviewer
743
742
  checks, designs, and adds missing tests when needed
744
743
  may directly apply small, local, low-risk review fixes
745
744
  owns complex tests, E2E coverage, regression matrix, and release-level validation recommendations
746
- outputs .ai/handoffs/<task-slug>/review-report.md
745
+ outputs .ai/vcm/handoffs/review-report.md
747
746
  must escalate larger implementation issues to coder
748
747
  must escalate architecture, public contract, design, or documentation drift issues to architect
749
748
  ```
@@ -781,7 +780,7 @@ Role sessions communicate through files, not memory from previous chats.
781
780
  Required handoff directory:
782
781
 
783
782
  ```text
784
- .ai/handoffs/<task-slug>/
783
+ .ai/vcm/handoffs/
785
784
  role-commands/
786
785
  architect.md
787
786
  coder.md
@@ -875,7 +874,7 @@ escalate to architect:
875
874
  the implementation reveals that the architecture plan is invalid
876
875
  ```
877
876
 
878
- For a task with a handoff directory, `.ai/handoffs/<task-slug>/validation-log.md` is the authoritative validation record for that task. `.ai/state/validation-log.md` is only a rolling index of recent validation results across tasks.
877
+ For a task with a handoff directory, `.ai/vcm/handoffs/validation-log.md` is the authoritative validation record for that task. `.ai/state/validation-log.md` is only a rolling index of recent validation results across tasks.
879
878
 
880
879
  For complex or high-risk work, the next role must not start until the required previous artifact exists and is coherent.
881
880
 
@@ -1038,7 +1037,7 @@ You are the architecture and planning role for this project.
1038
1037
 
1039
1038
  # Outputs
1040
1039
 
1041
- - `.ai/handoffs/<task-slug>/architecture-plan.md`
1040
+ - `.ai/vcm/handoffs/architecture-plan.md`
1042
1041
 
1043
1042
  # Do Not
1044
1043
 
@@ -1489,8 +1488,8 @@ Branch rules:
1489
1488
  Close Task rules:
1490
1489
 
1491
1490
  - after task completion, use VCM `Close Task` only when the user is ready to delete task-local state
1492
- - for worktree-backed tasks, `Close Task` deletes the task worktree, deletes the task branch by default, and removes VCM task/session/message/orchestration metadata
1493
- - `Close Task` does not check running role sessions or uncommitted changes; finish, commit, or preserve anything important before using it
1491
+ - for worktree-backed tasks, `Close Task` deletes the task worktree, deletes the task branch by default, and removes VCM task/session/message/orchestration/handoff metadata
1492
+ - `Close Task` stops VCM-managed running role sessions, but it does not check uncommitted changes; finish, commit, or preserve anything important before using it
1494
1493
 
1495
1494
  Small commits:
1496
1495
 
@@ -1613,7 +1612,7 @@ State files:
1613
1612
 
1614
1613
  Validation log authority:
1615
1614
 
1616
- - `.ai/handoffs/<task-slug>/validation-log.md` is authoritative for one task.
1615
+ - `.ai/vcm/handoffs/validation-log.md` is authoritative for one task.
1617
1616
  - `.ai/state/validation-log.md` is a rolling index across tasks and should point to the task-level log when one exists.
1618
1617
  - Final reports and review reports should cite the task-level validation log, not scattered chat output.
1619
1618
 
@@ -1868,7 +1867,7 @@ behavior is correct
1868
1867
  - [ ] For T2+ work, architect performed post-review docs sync / architecture drift check before final PM acceptance.
1869
1868
  - [ ] Docs updates or a docs-sync-report explain why affected architecture/module/testing/security/dependency docs are current.
1870
1869
  - [ ] The project manager prepared final acceptance, commit, and PR only after reviewer and docs-sync gates passed or an exception was approved.
1871
- - [ ] Task-level validation evidence is recorded in `.ai/handoffs/<task-slug>/validation-log.md` when a handoff directory exists.
1870
+ - [ ] Task-level validation evidence is recorded in `.ai/vcm/handoffs/validation-log.md` when a handoff directory exists.
1872
1871
 
1873
1872
  ## Architecture
1874
1873
 
@@ -111,13 +111,14 @@ Task creation flow:
111
111
  New Task submit
112
112
  -> validate task name
113
113
  -> verify .ai/vcm/ is ignored
114
- -> if Create worktree and branch is selected:
115
- -> derive branch feature/<task-name>
116
- -> derive worktree path .ai/vcm/worktrees/<task-name>
117
- -> verify the base repo is clean
118
- -> git worktree add -b feature/<task-name> .ai/vcm/worktrees/<task-name> <base-ref>
119
- -> otherwise:
120
- -> use the connected repo path and current branch
114
+ -> if Create worktree and branch is selected:
115
+ -> derive branch feature/<task-name>
116
+ -> derive worktree path .ai/vcm/worktrees/<task-name>
117
+ -> verify the base repo is clean
118
+ -> git worktree add -b feature/<task-name> .ai/vcm/worktrees/<task-name> <base-ref>
119
+ -> otherwise:
120
+ -> use the connected repo path and current branch
121
+ -> reject if another inline task is already active
121
122
  -> create task metadata
122
123
  -> create handoff structure inside the task runtime repo
123
124
  -> open the task workspace with role session cwd = task runtime repo
@@ -128,6 +129,7 @@ Task close flow:
128
129
  ```text
129
130
  user clicks red Close Task
130
131
  -> show destructive confirmation
132
+ -> stop VCM-managed running role sessions for the task
131
133
  -> explain that VCM deletes the task worktree and task branch
132
134
  -> explain that VCM does not check running sessions or uncommitted changes
133
135
  -> remove git worktree when the task owns one
@@ -136,7 +138,7 @@ user clicks red Close Task
136
138
  -> remove task runtime metadata from the task runtime repo
137
139
  ```
138
140
 
139
- Tasks created without a worktree do not own a separate branch/worktree, so Close Task removes only VCM metadata for those tasks.
141
+ Tasks created without a worktree do not own a separate branch/worktree, so Close Task stops VCM-managed running role sessions and removes only VCM metadata for those tasks.
140
142
 
141
143
  ## 5. Roles
142
144
 
@@ -168,8 +170,8 @@ The architect owns:
168
170
 
169
171
  Outputs:
170
172
 
171
- - `.ai/handoffs/<task>/architecture-plan.md`
172
- - `.ai/handoffs/<task>/docs-sync-report.md`
173
+ - `.ai/vcm/handoffs/architecture-plan.md`
174
+ - `.ai/vcm/handoffs/docs-sync-report.md`
173
175
 
174
176
  ### Coder
175
177
 
@@ -182,8 +184,8 @@ The coder owns:
182
184
 
183
185
  Outputs:
184
186
 
185
- - `.ai/handoffs/<task>/implementation-log.md`
186
- - `.ai/handoffs/<task>/validation-log.md`
187
+ - `.ai/vcm/handoffs/implementation-log.md`
188
+ - `.ai/vcm/handoffs/validation-log.md`
187
189
 
188
190
  ### Reviewer
189
191
 
@@ -197,7 +199,7 @@ The reviewer owns:
197
199
 
198
200
  Output:
199
201
 
200
- - `.ai/handoffs/<task>/review-report.md`
202
+ - `.ai/vcm/handoffs/review-report.md`
201
203
 
202
204
  ## 6. Information Architecture
203
205
 
@@ -392,7 +394,7 @@ Role sessions get VCM behavior from `CLAUDE.md` and `.claude/agents/*.md`, not f
392
394
  Each task creates:
393
395
 
394
396
  ```text
395
- .ai/handoffs/<task>/
397
+ .ai/vcm/handoffs/
396
398
  role-commands/
397
399
  architect.md
398
400
  coder.md
@@ -411,7 +413,7 @@ Each task creates:
411
413
  <message-id>.md
412
414
  ```
413
415
 
414
- The product treats handoff files as durable facts. The terminal is useful for live interaction, but handoff files and message history are what survive task handoffs cleanly.
416
+ The product treats handoff files as task-local coordination facts. The terminal is useful for live interaction, but handoff files and message history are the source of truth during a task. They live under `.ai/vcm/`, are ignored by Git, and are removed by `Close Task`; final decisions that should survive must be copied into normal project docs, source, commit messages, or PR text.
415
417
 
416
418
  The main UI no longer has a dedicated artifact panel. Artifact APIs still exist for status checks, role command compatibility, and future UI work.
417
419
 
@@ -438,9 +440,9 @@ Manual mode:
438
440
 
439
441
  - message status becomes `pending_approval` when the target role is running
440
442
  - user opens `Messages`
441
- - user clicks `Stage`
442
- - VCM writes a short prompt into the target terminal
443
- - VCM does not submit Enter
443
+ - message rows show sequence, timestamp, status, body preview, path, and `Copy`
444
+ - user decides whether to copy or manually act on the message
445
+ - VCM does not write to the target terminal or submit Enter
444
446
 
445
447
  Auto mode:
446
448
 
@@ -448,7 +450,7 @@ Auto mode:
448
450
  - PM remains the routing hub
449
451
  - non-PM roles reply to PM
450
452
 
451
- The backend still has a `paused` state field and pause/resume API routes for compatibility. The current GUI exposes only manual/auto.
453
+ The backend still has `stage`, `approve`, `reject`, `paused`, and pause/resume API compatibility paths. The current GUI exposes only message copy plus manual/auto orchestration.
452
454
 
453
455
  ## 12. Translation
454
456
 
@@ -537,6 +539,8 @@ Keyboard behavior:
537
539
 
538
540
  After translation succeeds, the English draft replaces the original Chinese text in the same textarea.
539
541
 
542
+ The translated user input is also shown in the translation panel as a conversation boundary. User-input entries have a thick divider and larger top spacing so the next Claude output reads as the answer to that prompt.
543
+
540
544
  `Send English` pastes the current English text into the active role terminal, then sends Enter as a separate terminal input event.
541
545
 
542
546
  Translation panel `Auto-send` is separate from task `Auto orchestration`:
@@ -581,10 +585,10 @@ Task worktree local files:
581
585
  .ai/vcm/worktrees/<task>/.ai/vcm/messages/<task>.jsonl
582
586
  .ai/vcm/worktrees/<task>/.ai/vcm/orchestration/<task>.json
583
587
  .ai/vcm/worktrees/<task>/.ai/vcm/translation/<task>/
584
- .ai/vcm/worktrees/<task>/.ai/handoffs/<task>/
588
+ .ai/vcm/worktrees/<task>/.ai/vcm/handoffs/
585
589
  ```
586
590
 
587
- For tasks created without a worktree, the task runtime repo is the connected base repo, so the runtime state resolves under the base repo's `.ai/vcm/`.
591
+ For tasks created without a worktree, the task runtime repo is the connected base repo, so the runtime state resolves under the base repo's `.ai/vcm/`. Because `.ai/vcm/handoffs/` has no task-name segment, VCM allows only one active inline task in a connected repo.
588
592
 
589
593
  External Claude transcripts:
590
594
 
@@ -28,7 +28,7 @@ browser
28
28
  -> claude --agent <role>
29
29
  ```
30
30
 
31
- The app is local-first. It writes project control state under `.ai/vcm/`, handoff artifacts under `.ai/handoffs/` inside the active task worktree, app settings under `~/.vcm/settings.json`, and reads Claude transcript files under `~/.claude/projects/`.
31
+ The app is local-first. It writes project control state under `.ai/vcm/`, handoff artifacts under `.ai/vcm/handoffs/` inside the active task worktree, app settings under `~/.vcm/settings.json`, and reads Claude transcript files under `~/.claude/projects/`.
32
32
 
33
33
  ## 2. Processes And Ports
34
34
 
@@ -112,7 +112,7 @@ Responsibilities:
112
112
 
113
113
  - Fetch task status, messages, and orchestration state.
114
114
  - Poll those every three seconds.
115
- - Render compact header with task title, branch, immutable worktree path, role tabs, and Refresh.
115
+ - Render compact header with task title, branch, immutable worktree path, role tabs, Refresh, and red `Close Task`.
116
116
  - Hold per-role permission mode selection.
117
117
  - Render one `SessionConsole` per role but only show the active role.
118
118
  - Emit workflow/messages/orchestration/events back to `App` so sidebar stays synchronized.
@@ -179,6 +179,7 @@ Entry:
179
179
 
180
180
  Fastify registers:
181
181
 
182
+ - app settings routes
182
183
  - project routes
183
184
  - harness routes
184
185
  - task routes
@@ -294,11 +295,13 @@ Task runtime state, source changes, and handoff artifacts live in the task runti
294
295
  <baseRepoRoot>/.ai/vcm/worktrees/<task>/.ai/vcm/messages/<task>.jsonl
295
296
  <baseRepoRoot>/.ai/vcm/worktrees/<task>/.ai/vcm/orchestration/<task>.json
296
297
  <baseRepoRoot>/.ai/vcm/worktrees/<task>/.ai/vcm/translation/<task>/
297
- <baseRepoRoot>/.ai/vcm/worktrees/<task>/.ai/handoffs/<task>/
298
+ <baseRepoRoot>/.ai/vcm/worktrees/<task>/.ai/vcm/handoffs/
298
299
  ```
299
300
 
300
301
  For inline tasks, `taskRepoRoot` is the connected base repo, so these same runtime paths resolve under the connected repo's `.ai/vcm/`.
301
302
 
303
+ Because the handoff directory is `<taskRepoRoot>/.ai/vcm/handoffs/` without a task slug segment, VCM rejects creating a second active inline task in the same connected repository. Parallel tasks should use the default worktree mode.
304
+
302
305
  This split lets VCM list tasks from the base repo after worktrees are created, while each task's runtime state follows the same root as the role sessions.
303
306
 
304
307
  ### 6.2 Git Ignore Requirement
@@ -326,9 +329,10 @@ POST /api/tasks
326
329
  -> assert worktreePath does not already exist
327
330
  -> assert base repo has no uncommitted changes
328
331
  -> git worktree add -b feature/<taskSlug> <worktreePath> <baseRef>
329
- -> otherwise:
330
- -> read current base repo branch
331
- -> leave worktreePath undefined
332
+ -> otherwise:
333
+ -> read current base repo branch
334
+ -> leave worktreePath undefined
335
+ -> reject when another inline task is already active
332
336
  -> create handoff structure in taskRepoRoot
333
337
  -> write central task metadata under baseRepoRoot/.ai/vcm/tasks/<task>.json
334
338
  ```
@@ -340,14 +344,18 @@ The default `baseRef` is the connected repo's current `HEAD`.
340
344
  ```text
341
345
  POST /api/tasks/:taskSlug/cleanup
342
346
  -> load task metadata
347
+ -> list role sessions for the task
348
+ -> stop each VCM-managed role session whose runtime status is running
349
+ -> stop translation tailers and clear task translation cache
343
350
  -> when worktreePath exists, verify it belongs under <baseRepoRoot>/.ai/vcm/worktrees/
344
351
  -> when worktreePath exists, git worktree remove --force <worktreePath>
345
352
  -> when worktreePath exists, delete the task branch by default
346
353
  -> delete base task metadata
347
354
  -> delete task runtime session/message/orchestration/translation metadata
355
+ -> delete task runtime handoff directory
348
356
  ```
349
357
 
350
- Close Task is intentionally destructive after user confirmation. It does not preflight running role sessions or uncommitted worktree changes. Tasks created without a worktree remove VCM metadata only because there is no VCM-owned branch/worktree to delete.
358
+ Close Task is intentionally destructive after user confirmation. It actively stops VCM-managed running role sessions, but it does not preflight running sessions or uncommitted worktree changes. Tasks created without a worktree remove VCM metadata only because there is no VCM-owned branch/worktree to delete.
351
359
 
352
360
  ## 7. Task And Artifact Model
353
361
 
@@ -369,9 +377,8 @@ Each task stores:
369
377
  - `taskSlug`
370
378
  - optional `title`
371
379
  - timestamps
372
- - `baseRepoRoot`
373
- - `worktreePath`
374
- - `repoRoot` / `taskRepoRoot`
380
+ - `repoRoot`, which is the connected base repository
381
+ - optional `worktreePath`, which is the task runtime repo when present
375
382
  - branch, always `feature/<taskSlug>` for VCM-created tasks
376
383
  - handoff directory
377
384
  - status
@@ -388,10 +395,12 @@ POST /api/tasks
388
395
  -> write base .ai/vcm/tasks/<task>.json
389
396
  ```
390
397
 
398
+ Task cleanup is orchestrated by `src/backend/api/task-routes.ts` because it coordinates session stopping, translation tailer stopping, and `TaskService.cleanupTask`.
399
+
391
400
  Handoff directory:
392
401
 
393
402
  ```text
394
- <taskRepoRoot>/.ai/handoffs/<task>/
403
+ <taskRepoRoot>/.ai/vcm/handoffs/
395
404
  role-commands/
396
405
  architect.md
397
406
  coder.md
@@ -523,7 +532,7 @@ The runtime:
523
532
  - spawns `node-pty`
524
533
  - sets `TERM=xterm-256color`
525
534
  - sets color-friendly env vars
526
- - appends raw PTY output to `<taskRepoRoot>/.ai/handoffs/<task>/logs/<role>.log`
535
+ - appends raw PTY output to `<taskRepoRoot>/.ai/vcm/handoffs/logs/<role>.log`
527
536
  - emits terminal output/input/exit events to WebSocket subscribers
528
537
  - replays the log on terminal WebSocket subscribe
529
538
 
@@ -557,7 +566,7 @@ State:
557
566
  ```text
558
567
  <taskRepoRoot>/.ai/vcm/messages/<task>.jsonl
559
568
  <taskRepoRoot>/.ai/vcm/orchestration/<task>.json
560
- <taskRepoRoot>/.ai/handoffs/<task>/messages/<message-id>.md
569
+ <taskRepoRoot>/.ai/vcm/handoffs/messages/<message-id>.md
561
570
  ```
562
571
 
563
572
  Policy:
@@ -569,16 +578,10 @@ Policy:
569
578
  Manual mode:
570
579
 
571
580
  ```text
572
- send -> pending_approval -> Stage -> staged
581
+ send -> pending_approval or queued -> Messages modal -> Copy/manual action
573
582
  ```
574
583
 
575
- `Stage` writes:
576
-
577
- ```text
578
- Read and handle VCM message <id> at <bodyPath>
579
- ```
580
-
581
- It does not append Enter.
584
+ The current GUI shows sequence, timestamp, status, body preview, path, and a `Copy` button. It does not expose Open Role, Stage, or Reject buttons. The backend still exposes stage/approve/reject routes; `Stage` writes `Read and handle VCM message <id> at <bodyPath>` without appending Enter.
582
585
 
583
586
  Auto mode:
584
587
 
@@ -590,7 +593,6 @@ The backend pastes a `[VCM MESSAGE]` envelope into the target terminal, then sen
590
593
 
591
594
  The backend still exposes pause/resume orchestration API routes and stores `paused` for compatibility. The current GUI only toggles `mode` between `manual` and `auto`.
592
595
 
593
- Messages and orchestration snapshots are task runtime state under `taskRepoRoot/.ai/vcm`. Message body markdown also lives in the task worktree handoff directory.
594
596
  Messages and orchestration snapshots are task runtime state under `taskRepoRoot/.ai/vcm`. Message body markdown also lives in the task worktree handoff directory.
595
597
 
596
598
  ## 12. Role Command Compatibility
@@ -930,7 +932,7 @@ Current boundaries:
930
932
  - Translation API key is local in `~/.vcm/settings.json`.
931
933
  - Translation output is UI/runtime state only unless a user or role copies it into a file.
932
934
  - `.ai/vcm` is local project control state and must be ignored by Git.
933
- - Task handoff artifacts live in the task worktree and users should decide whether those artifacts belong in task commits.
935
+ - Task handoff artifacts live under `.ai/vcm/handoffs/` as task-local runtime state and are removed by Close Task. Durable conclusions belong in normal project docs, code comments, commit messages, or PR text.
934
936
  - Task worktrees are created only during task creation; VCM does not expose branch/worktree switching APIs.
935
937
  - Sandbox isolation should come from a devContainer, Docker container, VM, or other user-controlled environment.
936
938
 
@@ -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 `.ai/vcm/worktrees/<task>` git worktree by default; users may clear `Create worktree and branch` to create an inline task in the connected repository/current branch.
20
+ - Task creation creates one `feature/<task>` branch and one `.ai/vcm/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
 
@@ -28,7 +28,7 @@ File:
28
28
  Current package facts:
29
29
 
30
30
  - package name: `vibe-coding-master`
31
- - current version: `0.0.7`
31
+ - current version: `0.0.10`
32
32
  - type: ESM
33
33
  - `bin.vcm`: `dist/main.js`
34
34
  - `bin.vcmctl`: `dist/cli/vcmctl.js`
@@ -179,6 +179,20 @@ Important fields:
179
179
  - `claudeCommand`
180
180
  - `isDirty`
181
181
 
182
+ ### `src/shared/types/app-settings.ts`
183
+
184
+ Defines:
185
+
186
+ - `ThemeMode`
187
+ - `AppPreferences`
188
+ - `UpdateAppPreferencesRequest`
189
+
190
+ Theme modes:
191
+
192
+ - `system`
193
+ - `light`
194
+ - `dark`
195
+
182
196
  ### `src/shared/types/task.ts`
183
197
 
184
198
  Defines:
@@ -196,7 +210,7 @@ Worktree fields:
196
210
  - `cleanupStatus?: "active" | "cleaned"`
197
211
  - `cleanedAt?: string`
198
212
 
199
- `CreateTaskRequest` supports `createWorktree?: boolean`. It creates a worktree and branch by default, and skips both when `createWorktree === false`.
213
+ `CreateTaskRequest` supports `createWorktree?: boolean`. It creates a worktree and branch by default, and skips both when `createWorktree === false`. Inline creation rejects a second active inline task in the same connected repository.
200
214
 
201
215
  ### `src/shared/types/session.ts`
202
216
 
@@ -399,8 +413,8 @@ Worktree methods:
399
413
  Required safety:
400
414
 
401
415
  - all Git commands keep command-scoped `safe.directory`
402
- - refuse worktree paths outside `<baseRepoRoot>/.ai/vcm/worktrees/`
403
- - refuse branch names that do not match `feature/<taskSlug>` for VCM-created tasks
416
+ - `TaskService` verifies Close Task worktree paths are under `<baseRepoRoot>/.ai/vcm/worktrees/`
417
+ - VCM-created task branches are derived from validated task slugs as `feature/<taskSlug>`
404
418
 
405
419
  ### `src/backend/adapters/claude-adapter.ts`
406
420
 
@@ -532,10 +546,11 @@ createTask(baseRepoRoot, { taskSlug })
532
546
  -> assert worktree path does not exist
533
547
  -> git.createWorktree({ baseRepoRoot, branch, worktreePath, baseRef: HEAD })
534
548
  -> taskRepoRoot = worktreePath
535
- -> otherwise:
536
- -> branch = current base repo branch
537
- -> worktreePath = undefined
538
- -> taskRepoRoot = baseRepoRoot
549
+ -> otherwise:
550
+ -> branch = current base repo branch
551
+ -> worktreePath = undefined
552
+ -> taskRepoRoot = baseRepoRoot
553
+ -> reject if another inline task is already active
539
554
  -> artifactService.ensureHandoffStructure({ repoRoot: taskRepoRoot, handoffDir })
540
555
  -> artifactService.createArtifactTemplates({ repoRoot: taskRepoRoot, handoffDir })
541
556
  -> ensure task runtime state dirs under <taskRepoRoot>/.ai/vcm/
@@ -547,17 +562,21 @@ Close Task flow:
547
562
  ```text
548
563
  cleanupTask(baseRepoRoot, taskSlug, options)
549
564
  -> load central task record
565
+ -> route layer lists role sessions
566
+ -> route layer stops each VCM-managed role session with status running
567
+ -> route layer stops translation tailers and clears task translation cache
550
568
  -> if worktreePath exists, verify it is under <baseRepoRoot>/.ai/vcm/worktrees/
551
569
  -> if worktreePath exists, git.removeWorktree(baseRepoRoot, worktreePath, force=true)
552
570
  -> if worktreePath exists, git.deleteBranch(baseRepoRoot, task.branch, force=true) by default
553
- -> delete <baseRepoRoot>/.ai/vcm/tasks/<task>.json
571
+ -> delete <baseRepoRoot>/.ai/vcm/tasks/<task>.json
572
+ -> delete <taskRepoRoot>/.ai/vcm/handoffs/
554
573
  -> delete <taskRepoRoot>/.ai/vcm/sessions/<task>.json
555
574
  -> delete <taskRepoRoot>/.ai/vcm/messages/<task>.jsonl
556
575
  -> delete <taskRepoRoot>/.ai/vcm/orchestration/<task>.json
557
576
  -> delete <taskRepoRoot>/.ai/vcm/translation/<task>/
558
577
  ```
559
578
 
560
- The UI labels this operation `Close Task`, styles it as a red destructive action, and shows a browser confirmation that names the worktree, branch, and metadata that will be deleted. VCM does not check running sessions or uncommitted changes before closing. Tasks created without a worktree remove VCM metadata only.
579
+ The UI labels this operation `Close Task`, styles it as a red destructive action, and shows a browser confirmation that names running role-session shutdown, the worktree, branch, and metadata that will be deleted. VCM actively stops VCM-managed running role sessions, but it does not preflight running sessions or uncommitted changes before closing. Tasks created without a worktree remove VCM metadata only.
561
580
 
562
581
  ### `src/backend/services/artifact-service.ts`
563
582
 
@@ -582,13 +601,13 @@ In task-worktree mode, artifact paths are still repo-relative, but `repoRoot` mu
582
601
  Primary role command path:
583
602
 
584
603
  ```text
585
- .ai/handoffs/<task>/role-commands/<role>.md
604
+ .ai/vcm/handoffs/role-commands/<role>.md
586
605
  ```
587
606
 
588
607
  Legacy fallback:
589
608
 
590
609
  ```text
591
- .ai/handoffs/<task>/role-commands/<role>-command.md
610
+ .ai/vcm/handoffs/role-commands/<role>-command.md
592
611
  ```
593
612
 
594
613
  ### `src/backend/services/status-service.ts`
@@ -665,7 +684,7 @@ In task-worktree mode:
665
684
 
666
685
  - message snapshots live under `task.worktreePath/.ai/vcm/messages`
667
686
  - orchestration state lives under `task.worktreePath/.ai/vcm/orchestration`
668
- - message body files live under `task.worktreePath/.ai/handoffs/<task>/messages`
687
+ - message body files live under `task.worktreePath/.ai/vcm/handoffs/messages`
669
688
  - terminal delivery uses the runtime session for the role, whose cwd is the task worktree
670
689
 
671
690
  ### `src/backend/services/command-dispatcher.ts`
@@ -775,7 +794,6 @@ Exports:
775
794
  - `TranslationEventListener`
776
795
  - `TranslationServiceDeps`
777
796
  - `createTranslationService(deps)`
778
- - `formatTerminalSubmit(text)`
779
797
 
780
798
  Responsibilities:
781
799
 
@@ -792,6 +810,8 @@ Responsibilities:
792
810
  - subscribe to Claude transcript service
793
811
  - translate prose output and preserve tool output
794
812
 
813
+ Terminal submission is delegated to `src/backend/runtime/terminal-submit.ts`, which bracket-pastes text, waits briefly, then sends Enter separately.
814
+
795
815
  ## 9. Backend API
796
816
 
797
817
  ### `src/backend/server.ts`
@@ -810,9 +830,10 @@ Registers HTTP routes and the terminal WebSocket.
810
830
 
811
831
  ### Route files
812
832
 
833
+ - `src/backend/api/app-settings-routes.ts`: UI preferences
813
834
  - `src/backend/api/project-routes.ts`: health, recent paths, connect/current project
814
835
  - `src/backend/api/harness-routes.ts`: harness status/apply
815
- - `src/backend/api/task-routes.ts`: tasks, task status, and Close Task cleanup endpoint
836
+ - `src/backend/api/task-routes.ts`: tasks, task status, and Close Task cleanup endpoint; Close Task stops running role sessions before translation/task cleanup
816
837
  - `src/backend/api/session-routes.ts`: session lifecycle and dispatch compatibility endpoint
817
838
  - `src/backend/api/artifact-routes.ts`: artifact, role command, and log reads/writes
818
839
  - `src/backend/api/message-routes.ts`: messages and orchestration
@@ -891,12 +912,12 @@ It calls:
891
912
  - orchestration endpoints
892
913
  - translation endpoints
893
914
 
894
- Target additions:
915
+ Implemented task cleanup method:
895
916
 
896
- - `listGitWorktrees()`
897
- - `listGitBranches()`
898
917
  - `cleanupTask(taskSlug, options)`
899
918
 
919
+ There are no branch/worktree switching APIs in the current frontend client.
920
+
900
921
  ### `src/frontend/state/app-store.ts`
901
922
 
902
923
  Exports:
@@ -946,7 +967,6 @@ Responsibilities:
946
967
  - harness panel
947
968
  - task creation with one task-name field, `Create worktree and branch` checkbox selected by default, branch preview, and worktree path preview
948
969
  - task navigation
949
- - red `Close Task` action with destructive confirmation
950
970
 
951
971
  ### `src/frontend/routes/task-workspace.tsx`
952
972
 
@@ -958,6 +978,7 @@ Exports:
958
978
  Responsibilities:
959
979
 
960
980
  - task header with role tabs and refresh
981
+ - red `Close Task` action with destructive confirmation
961
982
  - show branch and immutable worktree path for the active task
962
983
  - status/message/orchestration refresh
963
984
  - periodic polling
@@ -1016,7 +1037,7 @@ Exports:
1016
1037
  - `getMessageCounts(messages)`
1017
1038
  - `MessageTimeline(props)`
1018
1039
 
1019
- Used inside the Messages modal. Can show stage/reject/open-role actions.
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.
1020
1041
 
1021
1042
  ### `src/frontend/components/event-log.tsx`
1022
1043
 
@@ -1082,6 +1103,7 @@ Important current behavior:
1082
1103
  - tool output is preserved, dim, one-line
1083
1104
  - prose source is replaced by translated text after completion
1084
1105
  - prose renders Markdown with GFM support
1106
+ - user-input translation entries add a thick divider and larger top spacing to mark question/answer boundaries
1085
1107
  - no separate translated-English textarea
1086
1108
 
1087
1109
  ### `src/frontend/components/translation-settings-modal.tsx`
@@ -1176,7 +1198,7 @@ Messages:
1176
1198
 
1177
1199
  ```text
1178
1200
  <taskRepoRoot>/.ai/vcm/messages/<task>.jsonl
1179
- <taskRepoRoot>/.ai/handoffs/<task>/messages/<message-id>.md
1201
+ <taskRepoRoot>/.ai/vcm/handoffs/messages/<message-id>.md
1180
1202
  ```
1181
1203
 
1182
1204
  Orchestration:
@@ -1200,7 +1222,7 @@ Task worktrees:
1200
1222
  Handoff artifacts:
1201
1223
 
1202
1224
  ```text
1203
- .ai/handoffs/<task>/
1225
+ .ai/vcm/handoffs/
1204
1226
  ```
1205
1227
 
1206
1228
  Claude transcripts:
@@ -1237,7 +1259,7 @@ For frontend layout changes, also verify manually:
1237
1259
  - Auto orchestration toggles on/off
1238
1260
  - `Enter` in translation composer translates/sends
1239
1261
  - `Shift+Enter` inserts newline
1240
- - close a worktree-backed task and verify it removes the worktree, deletes the task branch, and removes central task metadata
1262
+ - close a worktree-backed task and verify it stops running role sessions, removes the worktree, deletes the task branch, and removes central task metadata
1241
1263
 
1242
1264
  ## 17. V1 Boundaries To Preserve
1243
1265
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibe-coding-master",
3
- "version": "0.0.10",
3
+ "version": "0.0.12",
4
4
  "description": "Local GUI session cockpit for Claude Code role sessions.",
5
5
  "type": "module",
6
6
  "files": [