Files
AgentHub/client/src/i18n/locales/en/run.json
T
nntrivi2001 f77049c238 feat(run,ui): make the lane console usable — terminal focus, live-exit recovery, auto permission mode, model aliases
Terminal (issue #33):
- `convertEol` is gone from xterm. It rewrote every bare LF as CR+LF, so a
  tmux pane that scrolled (tmux emits a bare LF and keeps drawing at the
  column it was on) had the rest of that draw land at column 0, stamping a
  line's first characters into the left margin of the rows below — the torn
  left edge that only showed up once content scrolled.
- The attach carries the client's real size (`?cols=&rows=`, `sizeFromQuery`
  in `server/websocket.js`, bounded because it reaches a TIOCSWINSZ ioctl).
  `attach()` spawned `tmux attach-session` at a hardcoded 80x24 on every
  attach, and tmux sizes the window to the newest client, so `claude` redrew
  its whole UI at 80 columns until the first `resize` message landed.
- The terminal takes the keyboard on mount, so typing reaches tmux without
  clicking the pane first.
- A pane that ends (double Ctrl+C, `exit`, a crash) reports itself through a
  new `onExit` prop and `LaneConsolePane` runs `newRun()`, so the console
  returns to the setup form instead of leaving a dead pane behind a
  "New run" button.

Pane environment:
- `server/lib/desktop-env.js` forwards the graphical session's DISPLAY /
  WAYLAND_DISPLAY / XAUTHORITY / XDG_RUNTIME_DIR (from
  `systemctl --user show-environment`, this process's own values winning)
  into the pane. The server normally runs as a systemd user service with none
  of them, so `claude` there could not read the clipboard and answered "no
  image found in clipboard" on every image paste.

Run setup:
- `auto` is a permission mode and is now the default everywhere — allowlists,
  the `--permission-mode` fallback, the select, and the pane's initial state.
- The model picker sends the CLI's aliases (`fable`/`opus`/`sonnet`/`haiku`)
  instead of pinned ids. `claude --model` resolves an alias to the latest
  model itself, so a release like Fable 5.1 needs no edit here; pricing is
  unaffected because it keys off the resolved id the transcript reports.
- **Create/update readme file** moved from the Add-lane modal into the lane's
  Tools menu: creating a lane and writing its docs are separate decisions,
  and the second is worth re-running long after the first.
- The Workspace's no-lane state is a real banner; the lane strip (add tile
  included) renders only once a lane exists.

Refs #32, #33.

Tests: npm run test:server (1828 pass), client vitest (558 pass).
2026-09-21 17:03:27 +07:00

167 lines
6.0 KiB
JSON

{
"actions": {
"newRun": "New run",
"send": "Send",
"sending": "Sending…",
"start": "Run",
"starting": "Starting…",
"stop": "Stop",
"stopping": "Stopping…",
"viewSession": "View session"
},
"autocomplete": {
"fileHint": "Type @ to reference a file",
"groupBuiltin": "Built-in (CLI only - won't run from here)",
"groupFiles": "Files in cwd",
"groupProject": "Project commands",
"groupUser": "User commands",
"noMatches": "No matches",
"slashHint": "Type / for slash commands"
},
"binary": {
"found": "Using {{path}}",
"missing": "The `{{cli}}` CLI isn't on your PATH. Install {{tool}} or set PATH so the dashboard can spawn it."
},
"concurrency": {
"active_one": "{{count}} run already in flight",
"active_other": "{{count}} runs already in flight",
"atCap": "Concurrency cap reached ({{max}}). Stop one of the running runs to start a new one.",
"viewActive": "View active runs"
},
"empty": {
"body": "Type a prompt and click Run. Output streams here as the model thinks, calls tools, and answers.",
"title": "Nothing yet"
},
"errors": {
"attachFailed": "Couldn't attach to run: {{message}}",
"cwdRequired": "Working directory required to start a run",
"killFailed": "Couldn't stop: {{message}}",
"laneCreateFailed": "Failed to create lane: {{message}}",
"noLaneSelected": "No lane selected or could not create one",
"noRunIdReturned": "No run_id returned from lane start",
"runStartedButNotAttached": "Run is live but couldn't attach to console: {{message}}",
"sendFailed": "Couldn't send: {{message}}",
"startFailed": "Couldn't start run: {{message}}"
},
"events": {
"claude": "Claude",
"collapse": "Collapse",
"expand": "Expand",
"system": "System",
"thinking": "Thinking",
"tool": "Tool",
"toolResult": "Tool result",
"you": "You"
},
"fields": {
"approval": "Approval",
"approvalNever": "Never",
"approvalOnRequest": "On request",
"cwd": "Working directory",
"cwdGroups": {
"dashboard": "Dashboard server",
"home": "Home",
"recent": "Recent - used by Claude Code"
},
"cwdHint": "Absolute path. Defaults to the dashboard's own cwd.",
"cwdNoMatches": "No matches. Type an absolute path to use it directly.",
"cwdPlaceholder": "Type to search or paste an absolute path…",
"effort": "Thinking effort",
"model": "Model",
"modelCustom": "Custom…",
"modelCustomPlaceholder": "model id (e.g. claude-opus-5)",
"modelInheritLabel": "Inherit from settings",
"permissionAcceptEdits": "acceptEdits (file edits without asking)",
"permissionAuto": "auto (recommended - asks only for risky actions)",
"permissionBypass": "bypassPermissions (DANGER - allows everything without asking)",
"permissionDefault": "default (interactive prompts - sessions may hang headlessly)",
"permissionMode": "Permission mode",
"permissionPlan": "plan (read-only planning)",
"prompt": "Prompt",
"promptPlaceholder": "Ask Claude anything…",
"promptPlaceholderTerminal": "Ask Claude anything…",
"sandbox": "Sandbox",
"sandboxFullAccess": "Full access (dangerous)",
"sandboxReadOnly": "Read only",
"sandboxWorkspaceWrite": "Workspace write"
},
"footer": {
"cost": "Cost",
"duration": "Duration",
"exitCode": "Exit code",
"sessionId": "Session ID",
"turns": "Turns"
},
"hint": {
"headlessExplain": "Headless mode is best for scripted tasks where you know exactly what you want. The session can't ask follow-up questions and will hang on permission prompts unless you stay in acceptEdits.",
"permissionWarning": "bypassPermissions allows ALL tool invocations without confirming. Only use for trusted prompts.",
"sandboxWarning": "Codex will run commands with no sandbox.",
"shortcut": "Cmd+Enter / Ctrl+Enter to send"
},
"limitations": {
"dismiss": "Got it"
},
"mode": {
"conversation": "Conversation",
"conversationHint": "Multi-turn - keep typing follow-ups while the agent works.",
"headless": "One-shot",
"headlessHint": "Single prompt, single response. Stdin closes after spawn.",
"label": "Mode"
},
"resume": {
"clear": "Clear selection",
"freshHint": "Start a fresh Claude Code session.",
"freshOption": "New session",
"label": "Source session",
"lastOption": "Resume last session",
"noSessions": "No sessions found.",
"originalCwd": "Original cwd",
"pickSession": "Pick a session…",
"preview": "Last activity",
"resumeHint": "Pick a session from your history and continue the conversation. Cwd is locked to the original.",
"resumeOption": "Resume existing session",
"search": "Search by ID, cwd, or status…",
"selectedBadge": "Resuming"
},
"runs": {
"allSessionsLink": "See all Claude Code sessions →",
"attached": "Attached to existing run",
"externalBadge": "external",
"externalHint": "Started outside the dashboard, so there is no terminal to attach to. Resume opens a new tmux-backed `claude --resume` of this session in its folder.",
"scopeNote": "Runs started from this dashboard, plus Claude Code sessions running outside it.",
"started": "Started {{when}}",
"switcher": "Active runs",
"switcherEmpty": "No active runs",
"viewActive": "View active run",
"viewActive_other": "{{count}} active runs",
"viewLabel": "View"
},
"status": {
"abandoned": "Abandoned",
"completed": "Completed",
"error": "Error",
"idle": "Idle",
"killed": "Killed",
"running": "Running",
"spawning": "Spawning…"
},
"statusHeader": {
"cwd": "Cwd",
"duration": "Elapsed",
"effort": "Effort",
"envelopes": "Events",
"model": "Model",
"permissionMode": "Mode",
"session": "Session"
},
"subtitle": "Streamed output, multi-turn, same hooks and analytics as your terminal.",
"title": "Run {{tool}}",
"tokens": {
"cacheRead": "Cache hit",
"cost": "Cost",
"input": "Input",
"label": "Context",
"output": "Output"
}
}