@oharness/server 0.9.2 → 0.10.0

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.
Files changed (61) hide show
  1. package/dist/i18n.js +356 -62
  2. package/dist/i18n.js.map +1 -1
  3. package/dist/main.js +4 -0
  4. package/dist/main.js.map +1 -1
  5. package/dist/page/client/account.js +430 -23
  6. package/dist/page/client/account.js.map +1 -1
  7. package/dist/page/client/base.js +20 -1
  8. package/dist/page/client/base.js.map +1 -1
  9. package/dist/page/client/composer.js +709 -58
  10. package/dist/page/client/composer.js.map +1 -1
  11. package/dist/page/client/computer.d.ts +27 -0
  12. package/dist/page/client/computer.js +358 -0
  13. package/dist/page/client/computer.js.map +1 -0
  14. package/dist/page/client/dialogs.js +93 -6
  15. package/dist/page/client/dialogs.js.map +1 -1
  16. package/dist/page/client/events.js +94 -7
  17. package/dist/page/client/events.js.map +1 -1
  18. package/dist/page/client/files.js +86 -1
  19. package/dist/page/client/files.js.map +1 -1
  20. package/dist/page/client/index.js +4 -0
  21. package/dist/page/client/index.js.map +1 -1
  22. package/dist/page/client/panels.js +12 -6
  23. package/dist/page/client/panels.js.map +1 -1
  24. package/dist/page/client/routines.js +296 -41
  25. package/dist/page/client/routines.js.map +1 -1
  26. package/dist/page/client/shell.js +229 -51
  27. package/dist/page/client/shell.js.map +1 -1
  28. package/dist/page/client/state.js +273 -19
  29. package/dist/page/client/state.js.map +1 -1
  30. package/dist/page/client/tasks.d.ts +8 -0
  31. package/dist/page/client/tasks.js +293 -0
  32. package/dist/page/client/tasks.js.map +1 -0
  33. package/dist/page/client/transcript.js +174 -6
  34. package/dist/page/client/transcript.js.map +1 -1
  35. package/dist/page/client/usage.js +1 -11
  36. package/dist/page/client/usage.js.map +1 -1
  37. package/dist/page/style.js +706 -104
  38. package/dist/page/style.js.map +1 -1
  39. package/dist/page.js +161 -54
  40. package/dist/page.js.map +1 -1
  41. package/dist/prefs.d.ts +14 -0
  42. package/dist/prefs.js +8 -1
  43. package/dist/prefs.js.map +1 -1
  44. package/dist/remote-crypto.d.ts +78 -0
  45. package/dist/remote-crypto.js +216 -0
  46. package/dist/remote-crypto.js.map +1 -0
  47. package/dist/remote.d.ts +103 -0
  48. package/dist/remote.js +498 -0
  49. package/dist/remote.js.map +1 -0
  50. package/dist/server.d.ts +70 -0
  51. package/dist/server.js +1291 -49
  52. package/dist/server.js.map +1 -1
  53. package/dist/starters.d.ts +92 -0
  54. package/dist/starters.js +213 -0
  55. package/dist/starters.js.map +1 -0
  56. package/dist/theme.js +5 -0
  57. package/dist/theme.js.map +1 -1
  58. package/dist/turn-shots.d.ts +27 -0
  59. package/dist/turn-shots.js +71 -0
  60. package/dist/turn-shots.js.map +1 -0
  61. package/package.json +2 -2
package/dist/i18n.js CHANGED
@@ -11,7 +11,9 @@ export const STRINGS = {
11
11
  en: {
12
12
  "app.name": "OHarness",
13
13
  "nav.new": "New session",
14
+ "nav.home": "Home",
14
15
  "nav.search": "Search",
16
+ "nav.searchSessions": "Search sessions",
15
17
  "nav.artifacts": "Artifacts",
16
18
  "nav.sessions": "Sessions",
17
19
  "nav.browser": "Browser",
@@ -59,6 +61,7 @@ export const STRINGS = {
59
61
  "browser.stopped": "Browser stopped. It will start again the next time Browser Use is needed.",
60
62
  "browser.takeoverHint": "Click and type straight into the page. Escape gives control back.",
61
63
  "nav.models": "Models",
64
+ "nav.usage": "Usage",
62
65
  "nav.routines": "Routines",
63
66
  "nav.settings": "Settings",
64
67
  "update.available": "Update to {version}",
@@ -109,9 +112,62 @@ export const STRINGS = {
109
112
  "cmd.rename": "Title this session",
110
113
  "cmd.schedule": "Run a routine now",
111
114
  "cmd.new": "Start a fresh session here",
115
+ "cmd.compact": "Summarize the conversation now to free up context",
116
+ "cmd.compacting": "Compacting the conversation…",
117
+ "cmd.nothingToCompact": "Nothing safe to compact yet.",
118
+ "cmd.goal": "Keep working until a goal is done",
119
+ "add.goal": "Goal mode",
120
+ "goal.chip": "Goal mode",
121
+ "goal.placeholder": "Describe what done looks like — the agent keeps going until it gets there",
122
+ "add.worktree": "New worktree",
123
+ "worktree.chip": "New worktree",
124
+ "worktree.placeholder": "Describe the task — it runs in a new worktree beside this project",
125
+ "worktree.started": "Working in {name}",
126
+ "worktree.startedBranch": "Working in {name} on {branch}",
127
+ "worktree.failed": "Could not make the worktree",
128
+ "worktree.finish": "Finish worktree…",
129
+ "worktree.tag": "worktree",
130
+ "worktree.clean": "No changes",
131
+ "worktree.changes": "{n} changed file(s)",
132
+ "worktree.commits": "{n} commit(s) on {branch}",
133
+ "worktree.action.remove": "Remove worktree",
134
+ "worktree.action.discard": "Discard worktree and its changes",
135
+ "worktree.action.commit": "Commit changes…",
136
+ "worktree.action.push": "Push branch and open pull request",
137
+ "worktree.action.merge": "Merge into the main checkout",
138
+ "worktree.action.apply": "Apply changes back to {name}",
139
+ "worktree.commitPrompt": "Commit message",
140
+ "worktree.discardConfirm": "Discard {name}? Its changes will be lost.",
141
+ "goal.tag": "Goal",
142
+ "goal.stop": "Stop working toward this goal",
143
+ "goal.needsText": "Describe the goal to work toward",
144
+ "add.computerUse": "Computer use",
145
+ "add.sectionAttach": "Attach",
146
+ "add.planMode": "Plan mode",
147
+ "plan.held": "Plan mode: this step would change something, so it waits until the plan is approved.",
148
+ "add.sectionMode": "Mode",
149
+ "add.sectionReach": "Extensions",
150
+ "computer.chip": "Computer use",
151
+ "computer.stop": "Stop the agent and give back every window it holds",
152
+ "computer.hide": "Fold away",
153
+ "computer.grow": "Larger / smaller",
154
+ "computer.showPane": "Show the window it is working in",
155
+ "computer.noStream": "Can't show this window live. OHarness needs Screen Recording, and some windows (minimised, or protected) can't be captured.",
156
+ "computer.windowGone": "The window closed or was minimised.",
157
+ "computer.off": "Turn off computer use",
158
+ "computer.permTitle": "{app} needs permission to use your Mac",
159
+ "computer.permBody": "macOS asks you to allow this once, in System Settings › Privacy & Security.",
160
+ "computer.permBodyDev": "This is a development build, so macOS asks about {app}, not OHarness: switch on {app} in System Settings › Privacy & Security.",
161
+ "computer.permScreen": "Screen Recording — to see app windows",
162
+ "computer.permAx": "Accessibility — to click and type in apps",
163
+ "computer.allow": "Allow",
164
+ "computer.granted": "Allowed",
165
+ "computer.recheck": "Check again",
166
+ "computer.relaunch": "Relaunch OHarness",
167
+ "computer.relaunchHint": "Just allowed Screen Recording? macOS applies it after a relaunch.",
168
+ "computer.unavailable": "Computer use could not start: {error}",
112
169
  "cmd.needsTitle": "A title is required: /rename my session",
113
170
  "mention.files": "Files",
114
- "add.upload": "Upload from computer",
115
171
  "add.up": "Back",
116
172
  "add.noDialog": "This machine has no file dialog. Type @ to name a file in the project.",
117
173
  "add.outsideFile": "{name} is outside the project and too large to send with the message — the agent will not be able to open it.",
@@ -143,6 +199,18 @@ export const STRINGS = {
143
199
  "add.more": "Keep typing to narrow this down",
144
200
  "add.remove": "Remove",
145
201
  "composer.send": "Send",
202
+ "composer.dictate": "Dictate",
203
+ "composer.dictateStop": "Stop dictating",
204
+ "dictate.opening": "Opening the microphone…",
205
+ "dictate.cancel": "Cancel (Esc)",
206
+ "dictate.done": "Done (Enter)",
207
+ "dictate.close": "Close",
208
+ "dictate.listening": "Listening…",
209
+ "dictate.transcribing": "Transcribing…",
210
+ "dictate.tidying": "Tidying…",
211
+ "dictate.denied": "Microphone access is off. Allow OHarness in System Settings › Privacy & Security › Microphone.",
212
+ "dictate.signIn": "Sign in to your OHarness account, or add an OpenAI key, to dictate.",
213
+ "dictate.failed": "Dictation didn't work: {error}",
146
214
  "composer.stop": "Stop",
147
215
  "composer.resize": "Drag to resize · double-click to reset",
148
216
  "queue.mark": "Queued",
@@ -154,37 +222,18 @@ export const STRINGS = {
154
222
  "empty.connected": "Connected to",
155
223
  // The invitation. Labels stay short enough to read as chips; the prompt is
156
224
  // the sentence the chip actually sends, so it can afford to be specific.
157
- "starter.explain": "Map the entry points and trace one request end to end",
158
- "starter.explain.prompt": "Map this project for me. List the entry points, the five to eight modules that actually matter and what each one owns, then trace one real request end to end, naming the files it passes through in order. Finish with the three things that would surprise a new contributor.",
159
- "starter.bugs": "Audit the input, error and concurrency paths for bugs",
160
- "starter.bugs.prompt": "Hunt for bugs in the code paths that handle input, errors and anything concurrent. Report each one as file:line, what triggers it, and what it costs when it fires. Fix the ones you are certain about, leave the rest as a list for me to judge, and run the test suite before and after.",
161
- "starter.tests": "Test the three riskiest functions nothing covers",
162
- "starter.tests.prompt": "Find the three riskiest untested functions here — the ones where a wrong answer is expensive — and write tests for them using whatever framework this project already uses. Cover the failure cases, not just the happy path, and show me the run output.",
163
- "starter.review": "Review my uncommitted diff before I commit it",
164
- "starter.review.prompt": "Review my uncommitted changes (git diff), file by file. Correctness first, then naming, dead code and anything I left half-done. Give it to me as file:line, what to change, why it matters — worst first — and end with a plain yes or no on whether this is safe to commit.",
165
- "starter.faster": "Profile the slowest path, then make it measurably faster",
166
- "starter.faster.prompt": "Measure before you touch anything: find the slowest path in this project, show me a timing you actually ran, then make it faster and show the same measurement after. Behaviour stays identical and the tests stay green — tell me if that turns out to be impossible.",
167
- "starter.plan": "Turn what I am building into an ordered plan",
168
- "starter.plan.prompt": "Ask me what I am trying to build, then turn my answer into a plan: five to eight ordered steps, each naming the files it touches and how I will know it is done. Put the decisions I have to make before step one at the top, and stop there until I answer them.",
169
- "starter.docs": "Write a README whose commands you have actually run",
170
- "starter.docs.prompt": "Write the README this project deserves: what it does in two sentences, install and run commands you have actually executed to confirm they work, one worked example with its real output, and the config options with their defaults. Cut whatever in the current one is no longer true.",
171
- "starter.digest": "Summarise this week's commits as a status update",
172
- "starter.digest.prompt": "Read the last seven days of commits and write me a status update: what shipped, what is still in flight, what broke, what is next. Group it by theme, write plain sentences rather than commit subjects, keep it under 200 words, and make it ready to paste into Slack.",
173
- "starter.automate": "Turn the most repetitive chore into one command",
174
- "starter.automate.prompt": "Find the manual chores in this project — steps spelled out in the README, command sequences repeated across scripts, anything done by hand before a release. Pick the one that costs the most time, turn it into a single documented command, and show me it running end to end.",
175
- "starter.backlog": "Rank every TODO by what ignoring it will cost",
176
- "starter.backlog.prompt": "Collect every TODO, FIXME and HACK in the codebase with its file:line, group them by theme, and rank them by what they will cost if nobody touches them. Tell me the three worth doing this week and why, then fix the cheapest one on the list and show me the diff.",
177
- "starter.landing": "Write landing page copy backed by what the code does",
178
- "starter.landing.prompt": "Read this project, then write the landing page copy: a headline under ten words, a one-sentence subhead, three benefits each backed by something the code genuinely does, one paragraph answering the obvious objection, and a single call to action. Save it as landing.md.",
179
- "starter.launch": "Draft the launch post, short version and blog version",
180
- "starter.launch.prompt": "Write the launch announcement for this project in two sizes: a post under 280 characters, and a 400-word blog version covering the problem, the before-and-after, and one concrete example. Plain voice — no superlatives, no exclamation marks, nothing the project cannot actually do.",
181
- "starter.pitch": "Pitch this to a non-technical buyer in five sentences",
182
- "starter.pitch.prompt": "Pitch this project to a non-technical buyer in exactly five sentences: the problem, what it costs them today, what changes, one proof point taken from the codebase, and the next step. Then compress the whole thing into one sentence I could say out loud.",
183
- "starter.position": "Write one page on who this is for and what it replaces",
184
- "starter.position.prompt": "Draft the positioning for this project on one page: who it is for, the job they would hire it to do, what it replaces, three differences from the obvious alternatives with evidence for each, and — plainly — who should not use it.",
185
- "starter.changelog": "Turn the commits since the last release into a changelog",
186
- "starter.changelog.prompt": "Turn the commits since the last release into a changelog customers can read. Group it as Added, Changed and Fixed, write each line as what someone can now do rather than what moved in the tree, and put anything breaking at the top with the upgrade step. Save it to CHANGELOG.md.",
225
+ "starter.trip": "Plan a 2-day Miami trip from NYC for $800",
226
+ "starter.trip.prompt": "Plan a two-day solo weekend in Miami from New York City with an $800 budget. Give me a simple itinerary, flight and hotel suggestions, and a budget breakdown.",
227
+ "starter.email": "Turn this week's unread work email into 5 tasks",
228
+ "starter.email.prompt": "Read my unread email from this week and list the five most important tasks with deadlines and owners. Draft any necessary replies, but do not send them.",
229
+ "starter.research": "Choose one $20/month AI coding assistant",
230
+ "starter.research.prompt": "Compare the US plans from ChatGPT, Claude and Gemini around $20 per month for daily coding. Give me a short table of strengths and limits, then recommend one.",
231
+ "starter.savings": "Scan last month's email bills and cut 50%",
232
+ "starter.savings.prompt": "Scan last month's email bills and uncover forgotten subscriptions, duplicate charges and cheaper alternatives. Give me a prioritized plan to cut the total by 50%, showing exactly how many dollars each change saves—without canceling anything for me.",
233
+ "starter.japanTrip": "Plan a 7-day Tokyo trip from LA for $2,500",
234
+ "starter.japanTrip.prompt": "Plan a 7-day solo trip from Los Angeles to Tokyo for $2,500, including flights and hotels. Avoid red-eye flights, include one day at DisneySea, and give me a simple daily itinerary and budget.",
187
235
  "palette.placeholder": "Search sessions, projects and actions…",
236
+ "palette.sessionsPlaceholder": "Search sessions…",
188
237
  "palette.actions": "Actions",
189
238
  "palette.sessions": "Sessions",
190
239
  "palette.projects": "Projects",
@@ -235,6 +284,10 @@ export const STRINGS = {
235
284
  "paywall.perYear": " / year",
236
285
  "paywall.popular": "Popular",
237
286
  "paywall.save": "Save {percent}%",
287
+ "paywall.upTo": "up to −{percent}%",
288
+ "paywall.included": "Included with every plan",
289
+ "paywall.chat": "Chat & code",
290
+ "paywall.media": "Images & video",
238
291
  "paywall.everyMonth": "{credits} credits every month",
239
292
  "paywall.everyYear": "{credits} credits every year",
240
293
  "paywall.orOnce": "Or buy credits once",
@@ -292,6 +345,30 @@ export const STRINGS = {
292
345
  "account.download": "Download the app",
293
346
  "account.enterprise": "For teams",
294
347
  "account.contact": "Contact us",
348
+ "feedback.menu": "Feedback",
349
+ "remote.pair.title": "Allow {name} to control this computer?",
350
+ "remote.pair.body": "It is signed in to your account. Allow it only if this code matches the one on the phone; it can then send messages and approve actions here.",
351
+ "remote.pair.allow": "Allow",
352
+ "remote.pair.deny": "Don't allow",
353
+ "feedback.title": "Feedback",
354
+ "feedback.kind.bug": "Bug",
355
+ "feedback.kind.idea": "Idea",
356
+ "feedback.kind.other": "Other",
357
+ "feedback.placeholder": "What happened, or what would help?",
358
+ "feedback.send": "Send",
359
+ "feedback.sending": "Sending…",
360
+ "feedback.sent": "Thanks — your feedback was sent.",
361
+ "feedback.empty": "Write something first.",
362
+ "feedback.attach": "Attach screenshot or video",
363
+ "feedback.add": "Add",
364
+ "feedback.mediaTitle": "Screenshots or videos",
365
+ "feedback.mediaHint": "Paste or drop here · up to 50 MB each, 5 max",
366
+ "feedback.mediaCount": "{n} of {max} added · up to 50 MB each",
367
+ "feedback.remove": "Remove",
368
+ "feedback.tooMany": "At most 5 files.",
369
+ "feedback.tooBig": "{name} is over 50 MB.",
370
+ "feedback.badType": "{name} is not an image or video we can take (PNG, JPEG, GIF, WebP, MP4, WebM, MOV).",
371
+ "feedback.uploading": "Uploading {n}/{total}…",
295
372
  "theme.label": "Theme",
296
373
  "theme.system": "System",
297
374
  "theme.light": "Light",
@@ -316,6 +393,7 @@ export const STRINGS = {
316
393
  "account.personal": "Personal",
317
394
  "account.createTeam": "Create a team",
318
395
  "account.manageTeams": "Manage workspaces",
396
+ "account.manage": "Manage",
319
397
  "paywall.teamUnit": "{team} credits",
320
398
  "paywall.teamMember": "{team} has no credits left. Ask the owner or someone with billing permission to top up, or bill to your own plan meanwhile.",
321
399
  "paywall.teamOwner": "{team} has no credits left. Top up or add seats on the team page.",
@@ -369,6 +447,7 @@ export const STRINGS = {
369
447
  "routines.remove": "Delete",
370
448
  "routines.removeConfirm": "Delete the routine \"{name}\"?",
371
449
  "routines.starter": "Create a routine: ",
450
+ "deepLink.replaceDraft": "A link wants to open a new session with its own prompt in the message box. Replace what you have typed there?",
372
451
  "routines.empty": "Choose New routine and say what should happen and when — \"every weekday at 9, summarise yesterday's commits\" — and the agent sets it up.",
373
452
  "routines.paused": "paused",
374
453
  "routines.pause": "Pause this routine",
@@ -380,6 +459,16 @@ export const STRINGS = {
380
459
  "routines.stillRunning": "the previous run was still going",
381
460
  "routines.catchUp": "caught up after a missed time",
382
461
  "routines.turns": "{n} turns",
462
+ "routines.status.running": "Running",
463
+ "routines.status.ok": "Done",
464
+ "routines.status.failed": "Failed",
465
+ "routines.status.skipped": "Skipped",
466
+ "routines.elapsed": "running for {d}",
467
+ "routines.showAll": "Show all {n}",
468
+ "routines.showFewer": "Show fewer",
469
+ "routines.openRun": "Open the conversation",
470
+ "routines.starting": "Starting…",
471
+ "routines.historyCount": "History · {n}",
383
472
  "routines.history": "History",
384
473
  "routines.loading": "Loading…",
385
474
  "routines.noRuns": "No runs yet.",
@@ -449,6 +538,30 @@ export const STRINGS = {
449
538
  "settings.keepAwakeOn": "On",
450
539
  "settings.keepAwakeOff": "Off",
451
540
  "settings.keepAwakeHint": "Stops the computer idling to sleep while OHarness is open, so routines run on time. Closing the lid still puts it to sleep.",
541
+ "settings.section.remote": "Remote control",
542
+ "settings.remote": "Let your iPhone control this Mac",
543
+ "settings.remote.off": "Off",
544
+ "settings.remote.connecting": "Connecting…",
545
+ "settings.remote.online": "Online",
546
+ "settings.remote.signedOut": "Signed out",
547
+ "settings.remoteHint": "The OHarness iPhone app, signed in to the same OHarness account, can open sessions, send prompts and approve permissions here. Each new phone needs your Allow on this screen, with a 6-digit code that matches the one on the phone. Traffic is end-to-end encrypted through the relay, and bypass mode can't be turned on from a phone.",
548
+ "settings.remoteAwake": "While it's on, this computer is kept from idling to sleep so your phone can reach it. Closing the lid still puts it to sleep.",
549
+ "settings.remoteStatus.off": "Off — no phone can reach this computer.",
550
+ "settings.remoteStatus.connecting": "Reaching the relay…",
551
+ "settings.remoteStatus.online": "Online — your iPhone can reach this computer.",
552
+ "settings.remoteStatus.signedOut": "Needs an OHarness account. Sign in to go online; until then no phone can reach this computer.",
553
+ "settings.remoteSignIn": "Sign in",
554
+ "settings.remotePhones": "Paired phones",
555
+ "settings.remoteNoPhones": "No phones paired yet.",
556
+ "settings.remotePairedOn": "paired {date}",
557
+ "settings.remoteForget": "Forget",
558
+ "settings.remoteForgotten": "{name} forgotten. It will need your Allow again.",
559
+ "settings.computerTakeover": "Computer use: take over the mouse",
560
+ "settings.computerTakeoverAsk": "Ask each time",
561
+ "settings.computerTakeoverNever": "Never",
562
+ "settings.computerTakeoverHint": "Computer use works in the background where apps allow it. Some actions (drag and drop, and most clicks on Windows) need the real mouse and keyboard: on, it asks you each time; off, it stays in the background and tells you what it could not do.",
563
+ "settings.computerBlocked": "Apps it must never look at or control (one per line: name, bundle id or exe name). Password managers and security settings are always blocked.",
564
+ "settings.computerBlockedPlaceholder": "e.g. com.tinyspeck.slackmacgap or slack.exe",
452
565
  "settings.browserMode": "Browser",
453
566
  "settings.browserMode.auto": "Auto",
454
567
  "settings.browserMode.builtin": "Built-in",
@@ -492,8 +605,20 @@ export const STRINGS = {
492
605
  "usage.back": "Back to settings",
493
606
  "usage.tokens": "{n} tokens",
494
607
  "usage.cached": "{pct}% cached",
608
+ "ctx.title": "Context window",
609
+ "ctx.total": "{used} / {total} ({pct}%)",
610
+ "ctx.system": "System prompt",
611
+ "ctx.tools": "Tool definitions",
612
+ "ctx.messages": "Messages",
613
+ "ctx.free": "Free space",
614
+ "ctx.autoAt": "Compacts automatically at {n}",
615
+ "ctx.autoOff": "Automatic compaction is off",
616
+ "ctx.measured": "Total as the provider counted the last request; the split is estimated",
617
+ "ctx.estimated": "Estimated until the next reply is measured",
618
+ "ctx.compactNow": "Compact now",
495
619
  "usage.cacheHint": "How much of what was sent came back out of the prompt cache instead of being charged again",
496
620
  "usage.context": "Context used",
621
+ "usage.contextOf": "Context {used} / {total} ({pct}%)",
497
622
  "usage.spend": "Spent",
498
623
  "usage.tokensLabel": "Tokens",
499
624
  "usage.cacheLabel": "From cache",
@@ -569,6 +694,8 @@ export const STRINGS = {
569
694
  "files.terminalTab": "Terminal",
570
695
  "files.refresh": "Refresh",
571
696
  "files.close": "Close",
697
+ "files.search": "Search files",
698
+ "files.noMatch": "No files match",
572
699
  "files.empty": "This folder is empty",
573
700
  "files.pick": "Pick a file to preview it",
574
701
  "files.binary": "This file isn't text, so there's nothing to preview.",
@@ -644,6 +771,26 @@ export const STRINGS = {
644
771
  "turn.copy": "Copy",
645
772
  "turn.copied": "Copied",
646
773
  "work.thinking": "Thinking",
774
+ "tasks.title": "Background tasks",
775
+ "tasks.cardTitle": "Background tasks ended",
776
+ "tasks.status.queued": "Queued",
777
+ "tasks.status.running": "Running",
778
+ "tasks.status.completed": "Done",
779
+ "tasks.status.failed": "Failed",
780
+ "tasks.status.cancelled": "Stopped",
781
+ "tasks.open": "View",
782
+ "tasks.stop": "Stop task",
783
+ "tasks.dismiss": "Dismiss",
784
+ "tasks.messageLabel": "Message this task",
785
+ "tasks.close": "Close",
786
+ "tasks.send": "Send",
787
+ "tasks.more": "{n} more background tasks",
788
+ "tasks.turns": "{n} turns",
789
+ "tasks.empty": "Nothing yet.",
790
+ "tasks.placeholder.running": "Tell it something; it reads this at its next step",
791
+ "tasks.placeholder.ended": "Send a follow-up; it carries on where it stopped",
792
+ "tasks.placeholder.stopped": "A stopped task can't be continued",
793
+ "ask.from": "From {from}",
647
794
  "work.thoughtFor": "Thought for {n}s",
648
795
  "work.thoughtAbout": "Thought about it",
649
796
  "review.changes": "Changes",
@@ -882,7 +1029,9 @@ export const STRINGS = {
882
1029
  },
883
1030
  zh: {
884
1031
  "nav.new": "新建会话",
1032
+ "nav.home": "首页",
885
1033
  "nav.search": "搜索",
1034
+ "nav.searchSessions": "搜索会话",
886
1035
  "nav.artifacts": "制品",
887
1036
  "nav.sessions": "会话",
888
1037
  "nav.browser": "浏览器",
@@ -930,6 +1079,7 @@ export const STRINGS = {
930
1079
  "browser.stopped": "浏览器已停止,下次需要 Browser Use 时会自动重新启动。",
931
1080
  "browser.takeoverHint": "可以直接在页面上点击和输入。按 Esc 交还控制。",
932
1081
  "nav.models": "模型",
1082
+ "nav.usage": "用量",
933
1083
  "nav.routines": "定时任务",
934
1084
  "nav.settings": "设置",
935
1085
  "update.available": "更新到 {version}",
@@ -980,9 +1130,62 @@ export const STRINGS = {
980
1130
  "cmd.rename": "给本会话命名",
981
1131
  "cmd.schedule": "立即运行一个例行任务",
982
1132
  "cmd.new": "在当前目录开一个新会话",
1133
+ "cmd.compact": "立即压缩对话,释放上下文",
1134
+ "cmd.compacting": "正在压缩对话…",
1135
+ "cmd.nothingToCompact": "暂时没有可以安全压缩的内容。",
1136
+ "cmd.goal": "持续工作直到目标完成",
1137
+ "add.goal": "目标模式",
1138
+ "goal.chip": "目标模式",
1139
+ "goal.placeholder": "描述完成的标准——Agent 会一直工作直到达成",
1140
+ "add.worktree": "新 worktree",
1141
+ "worktree.chip": "新 worktree",
1142
+ "worktree.placeholder": "描述任务——会在项目旁新建一个 worktree 来做",
1143
+ "worktree.started": "已在 {name} 中开始",
1144
+ "worktree.startedBranch": "已在 {name}(分支 {branch})中开始",
1145
+ "worktree.failed": "无法创建 worktree",
1146
+ "worktree.finish": "结束 worktree…",
1147
+ "worktree.tag": "worktree",
1148
+ "worktree.clean": "没有改动",
1149
+ "worktree.changes": "{n} 个文件有改动",
1150
+ "worktree.commits": "{branch} 上有 {n} 个提交",
1151
+ "worktree.action.remove": "删除 worktree",
1152
+ "worktree.action.discard": "丢弃 worktree 及其改动",
1153
+ "worktree.action.commit": "提交改动…",
1154
+ "worktree.action.push": "推送分支并开 PR",
1155
+ "worktree.action.merge": "合并到主 checkout",
1156
+ "worktree.action.apply": "把改动应用回 {name}",
1157
+ "worktree.commitPrompt": "提交说明",
1158
+ "worktree.discardConfirm": "丢弃 {name}?其中的改动会丢失。",
1159
+ "goal.tag": "目标",
1160
+ "goal.stop": "停止追踪这个目标",
1161
+ "goal.needsText": "请描述要达成的目标",
1162
+ "add.computerUse": "操作电脑",
1163
+ "add.sectionAttach": "添加",
1164
+ "add.planMode": "计划模式",
1165
+ "plan.held": "计划模式:这一步会做出改动,等方案确认后再执行。",
1166
+ "add.sectionMode": "模式",
1167
+ "add.sectionReach": "扩展",
1168
+ "computer.chip": "操作电脑",
1169
+ "computer.stop": "停止 Agent,并交还它占用的所有窗口",
1170
+ "computer.hide": "收起",
1171
+ "computer.grow": "放大 / 缩小",
1172
+ "computer.showPane": "查看它正在操作的窗口",
1173
+ "computer.noStream": "无法实时显示这个窗口。OHarness 需要屏幕录制权限;最小化或受保护的窗口也无法采集。",
1174
+ "computer.windowGone": "窗口已关闭或最小化。",
1175
+ "computer.off": "关闭操作电脑",
1176
+ "computer.permTitle": "{app} 需要权限才能操作你的 Mac",
1177
+ "computer.permBody": "macOS 需要你在「系统设置 › 隐私与安全性」里允许一次。",
1178
+ "computer.permBodyDev": "这是开发版,macOS 认的是 {app} 而不是 OHarness:请在「系统设置 › 隐私与安全性」里打开 {app}。",
1179
+ "computer.permScreen": "屏幕录制——用来看到应用窗口",
1180
+ "computer.permAx": "辅助功能——用来在应用里点击和输入",
1181
+ "computer.allow": "允许",
1182
+ "computer.granted": "已允许",
1183
+ "computer.recheck": "重新检查",
1184
+ "computer.relaunch": "重启 OHarness",
1185
+ "computer.relaunchHint": "刚允许了屏幕录制?macOS 要重启应用后才生效。",
1186
+ "computer.unavailable": "操作电脑无法启动:{error}",
983
1187
  "cmd.needsTitle": "需要一个标题:/rename 我的会话",
984
1188
  "mention.files": "文件",
985
- "add.upload": "从本机上传",
986
1189
  "add.up": "返回",
987
1190
  "add.noDialog": "此机器没有文件对话框。输入 @ 可引用项目内的文件。",
988
1191
  "add.outsideFile": "{name} 在项目之外,也太大而无法随消息发送——agent 打不开它。",
@@ -1014,6 +1217,18 @@ export const STRINGS = {
1014
1217
  "add.more": "继续输入以缩小范围",
1015
1218
  "add.remove": "移除",
1016
1219
  "composer.send": "发送",
1220
+ "composer.dictate": "语音输入",
1221
+ "composer.dictateStop": "停止语音输入",
1222
+ "dictate.opening": "正在打开麦克风…",
1223
+ "dictate.cancel": "取消(Esc)",
1224
+ "dictate.done": "完成(Enter)",
1225
+ "dictate.close": "关闭",
1226
+ "dictate.listening": "正在听…",
1227
+ "dictate.transcribing": "转写中…",
1228
+ "dictate.tidying": "整理中…",
1229
+ "dictate.denied": "麦克风权限未开启。请在 系统设置 › 隐私与安全性 › 麦克风 中允许 OHarness。",
1230
+ "dictate.signIn": "登录 OHarness 账户,或添加 OpenAI 密钥后即可使用语音输入。",
1231
+ "dictate.failed": "语音输入失败:{error}",
1017
1232
  "composer.stop": "停止",
1018
1233
  "composer.resize": "拖动改变高度 · 双击恢复",
1019
1234
  "queue.mark": "排队中",
@@ -1023,37 +1238,18 @@ export const STRINGS = {
1023
1238
  "queue.attachmentsOnly": "附件",
1024
1239
  "empty.title": "今天做点什么?",
1025
1240
  "empty.connected": "已连接到",
1026
- "starter.explain": "梳理入口,并跟着一条请求走完全程",
1027
- "starter.explain.prompt": "帮我把这个项目梳理一遍:入口在哪里,真正重要的五到八个模块分别管什么,然后挑一条真实请求从头走到尾,按顺序点出它经过的文件。最后告诉我三件新人最容易想不到的事。",
1028
- "starter.bugs": "排查输入、错误和并发路径上的 bug",
1029
- "starter.bugs.prompt": "重点排查处理输入、错误和并发的那些代码路径。每个问题给我 file:line、什么情况会触发、触发之后的代价。有把握的直接修掉,没把握的列出来交给我判断,改动前后都跑一遍测试。",
1030
- "starter.tests": "给最危险又没有测试的三个函数补上测试",
1031
- "starter.tests.prompt": "找出这里风险最高、又没有测试覆盖的三个函数——就是一旦算错代价很大的那种——用项目现有的测试框架给它们补上测试。要覆盖出错的分支,不要只测顺利路径,最后把测试运行结果贴给我。",
1032
- "starter.review": "提交之前 review 我还没提交的改动",
1033
- "starter.review.prompt": "逐个文件 review 我还没提交的改动(git diff):先看正确性,再看命名、死代码和我写了一半的地方。按 file:line、该改什么、为什么重要的格式给我,严重的排在前面,最后直说一句这版能不能提交。",
1034
- "starter.faster": "先测出最慢的路径,再把它优化掉",
1035
- "starter.faster.prompt": "先测量再动手:找出这个项目里最慢的一条路径,把你实际跑出来的耗时给我看,优化之后再用同样的方法测一次。行为必须完全不变、测试必须继续通过——如果做不到,直接告诉我。",
1036
- "starter.plan": "把我要做的事拆成一份有序的计划",
1037
- "starter.plan.prompt": "先问我想做什么,然后把我的回答变成一份计划:五到八个有先后顺序的步骤,每步写清楚要动哪些文件、怎样算做完。把动手前我必须先拍板的决定放在最前面,然后停下来等我回答。",
1038
- "starter.docs": "写一份命令都亲手验证过的 README",
1039
- "starter.docs.prompt": "把这个项目该有的 README 写出来:两句话说清它是做什么的,安装和运行命令要你自己真的跑过确认可用,一个带真实输出的完整示例,以及各项配置和默认值。当前文档里已经不成立的内容直接删掉。",
1040
- "starter.digest": "把这周的提交整理成一份进展汇报",
1041
- "starter.digest.prompt": "读最近七天的提交,给我写一份进展汇报:发布了什么、还在做什么、哪里出了问题、接下来做什么。按主题分组,用人话写而不是抄提交标题,控制在 300 字以内,写成可以直接贴进群里的样子。",
1042
- "starter.automate": "把最费时间的手工步骤做成一条命令",
1043
- "starter.automate.prompt": "找出这个项目里需要手动重复做的事——README 里一步步写的操作、多个脚本里重复出现的命令、每次发版前手工做的动作。挑最费时间的那一件,做成一条带说明的命令,并且完整跑一遍给我看。",
1044
- "starter.backlog": "把 TODO 按放着不管的代价排个序",
1045
- "starter.backlog.prompt": "把代码里所有 TODO、FIXME、HACK 连同 file:line 收集起来,按主题分组,再按“放着不管会付出什么代价”排序。告诉我这周最值得做的三条以及理由,然后把其中成本最低的那条改掉,把 diff 给我看。",
1046
- "starter.landing": "写一版有代码事实支撑的落地页文案",
1047
- "starter.landing.prompt": "读懂这个项目,然后写落地页文案:十个字以内的主标题、一句话副标题、三条价值点(每条都要对应代码里确实做到的事)、一段回应最明显疑虑的文字,以及一个行动号召。保存为 landing.md。",
1048
- "starter.launch": "写发布公告:一条社媒短文加一篇博客",
1049
- "starter.launch.prompt": "为这个项目写两个尺寸的发布公告:一条 280 字符以内的社媒短文,和一篇 400 词左右的博客版,讲清楚问题、前后对比和一个具体例子。语气朴素——不要形容词堆砌、不要感叹号、不要写项目做不到的事。",
1050
- "starter.pitch": "用五句话把它讲给不懂技术的客户听",
1051
- "starter.pitch.prompt": "用整整五句话把这个项目讲给不懂技术的采购方听:问题是什么、他们今天为此付出什么代价、之后会怎样、一个来自代码本身的佐证、下一步该做什么。然后再把这五句压缩成一句我能当面说出口的话。",
1052
- "starter.position": "写一页定位:给谁用、又替代掉了什么",
1053
- "starter.position.prompt": "用一页纸写出这个项目的定位:给谁用、他们雇它来干什么活、它替代掉什么、和几个显而易见的替代品有哪三点不同(每点都要有依据),以及——直说——什么人不该用它。",
1054
- "starter.changelog": "把上次发布之后的提交写成更新日志",
1055
- "starter.changelog.prompt": "把上次发布之后的提交整理成用户看得懂的更新日志。按新增、变更、修复分组,每条写“用户现在能做什么”而不是“哪些文件动了”,破坏性改动连同升级步骤放在最前面。保存到 CHANGELOG.md。",
1241
+ "starter.trip": "规划纽约出发的迈阿密两日游,预算 800 美元",
1242
+ "starter.trip.prompt": "帮我规划从纽约出发、一个人去迈阿密的周末两日游,预算 800 美元。给我简单的行程、机票和酒店建议,以及预算明细。",
1243
+ "starter.email": "把本周未读工作邮件整理成 5 项待办",
1244
+ "starter.email.prompt": "读取我本周的未读邮件,整理出最重要的 5 项待办,标明截止时间和负责人。需要回复的邮件可以起草,但不要发送。",
1245
+ "starter.research": "从三款产品中选一个每月 20 美元的 AI 编程助手",
1246
+ "starter.research.prompt": "对比 ChatGPT、Claude 和 Gemini 在美国每月约 20 美元的套餐用于日常编程的优势和限制,用一个简短表格展示,最后只推荐一个。",
1247
+ "starter.savings": "扫描上月邮件账单,把开销降低 50%",
1248
+ "starter.savings.prompt": "扫描我上个月邮件里的账单,找出遗忘的订阅、重复扣费和更便宜的替代方案。按优先级给我一套把总开销降低 50% 的计划,明确每项能省多少美元,但不要替我取消任何服务。",
1249
+ "starter.japanTrip": "规划洛杉矶出发的东京 7 日游,预算 2500 美元",
1250
+ "starter.japanTrip.prompt": "帮我规划从洛杉矶出发、一个人去东京的 7 日游,总预算 2500 美元,包含机票和酒店。不要红眼航班,安排一天迪士尼海洋,给我简单的每日行程和预算。",
1056
1251
  "palette.placeholder": "搜索会话、项目与操作…",
1252
+ "palette.sessionsPlaceholder": "搜索会话…",
1057
1253
  "palette.actions": "操作",
1058
1254
  "palette.sessions": "会话",
1059
1255
  "palette.projects": "项目",
@@ -1101,6 +1297,10 @@ export const STRINGS = {
1101
1297
  "paywall.perYear": " / 年",
1102
1298
  "paywall.popular": "热门",
1103
1299
  "paywall.save": "省 {percent}%",
1300
+ "paywall.upTo": "最高省 {percent}%",
1301
+ "paywall.included": "每个套餐都包含",
1302
+ "paywall.chat": "对话与编程",
1303
+ "paywall.media": "图片与视频",
1104
1304
  "paywall.everyMonth": "每月 {credits} 点",
1105
1305
  "paywall.everyYear": "每年 {credits} 点",
1106
1306
  "paywall.orOnce": "或者单次购买点数",
@@ -1151,6 +1351,30 @@ export const STRINGS = {
1151
1351
  "account.download": "下载客户端",
1152
1352
  "account.enterprise": "团队方案",
1153
1353
  "account.contact": "联系我们",
1354
+ "feedback.menu": "反馈",
1355
+ "remote.pair.title": "允许 {name} 控制这台电脑?",
1356
+ "remote.pair.body": "它登录的是你的账号。只有当下面的代码和手机上显示的一致时才允许;允许后它可以在这里发消息、批准操作。",
1357
+ "remote.pair.allow": "允许",
1358
+ "remote.pair.deny": "不允许",
1359
+ "feedback.title": "反馈",
1360
+ "feedback.kind.bug": "问题",
1361
+ "feedback.kind.idea": "建议",
1362
+ "feedback.kind.other": "其他",
1363
+ "feedback.placeholder": "遇到了什么问题,或者有什么建议?",
1364
+ "feedback.send": "发送",
1365
+ "feedback.sending": "发送中…",
1366
+ "feedback.sent": "谢谢,反馈已发送。",
1367
+ "feedback.empty": "请先写点内容。",
1368
+ "feedback.attach": "添加截图或视频",
1369
+ "feedback.add": "添加",
1370
+ "feedback.mediaTitle": "截图或视频",
1371
+ "feedback.mediaHint": "可直接粘贴或拖入 · 单个最大 50MB,最多 5 个",
1372
+ "feedback.mediaCount": "已添加 {n}/{max} · 单个最大 50MB",
1373
+ "feedback.remove": "移除",
1374
+ "feedback.tooMany": "最多 5 个附件。",
1375
+ "feedback.tooBig": "{name} 超过 50MB。",
1376
+ "feedback.badType": "{name} 不是支持的格式(PNG、JPEG、GIF、WebP、MP4、WebM、MOV)。",
1377
+ "feedback.uploading": "上传中 {n}/{total}…",
1154
1378
  "theme.label": "主题",
1155
1379
  "theme.system": "跟随系统",
1156
1380
  "theme.light": "浅色",
@@ -1172,6 +1396,7 @@ export const STRINGS = {
1172
1396
  "account.personal": "个人",
1173
1397
  "account.createTeam": "创建团队",
1174
1398
  "account.manageTeams": "管理工作区",
1399
+ "account.manage": "管理",
1175
1400
  "paywall.teamUnit": "{team} 的点数",
1176
1401
  "paywall.teamMember": "{team} 的点数用完了。请所有者或有账单权限的成员充值,或先切回自己的套餐。",
1177
1402
  "paywall.teamOwner": "{team} 的点数用完了。到团队页面充值或增加席位。",
@@ -1225,6 +1450,7 @@ export const STRINGS = {
1225
1450
  "routines.remove": "删除",
1226
1451
  "routines.removeConfirm": "删除定时任务「{name}」?",
1227
1452
  "routines.starter": "新建一个定时任务:",
1453
+ "deepLink.replaceDraft": "一个链接想用它自带的提示词新开一个会话,填进输入框。要替换你已经输入的内容吗?",
1228
1454
  "routines.empty": "点「新建定时任务」,说清楚做什么、什么时候做,比如「每个工作日早上 9 点总结昨天的提交」,agent 会帮你设好。",
1229
1455
  "routines.paused": "已暂停",
1230
1456
  "routines.pause": "暂停这个定时任务",
@@ -1236,6 +1462,16 @@ export const STRINGS = {
1236
1462
  "routines.stillRunning": "上一次还没跑完",
1237
1463
  "routines.catchUp": "错过后补跑",
1238
1464
  "routines.turns": "{n} 轮",
1465
+ "routines.status.running": "运行中",
1466
+ "routines.status.ok": "完成",
1467
+ "routines.status.failed": "失败",
1468
+ "routines.status.skipped": "已跳过",
1469
+ "routines.elapsed": "已运行 {d}",
1470
+ "routines.showAll": "显示全部 {n} 条",
1471
+ "routines.showFewer": "收起",
1472
+ "routines.openRun": "打开对话",
1473
+ "routines.starting": "正在启动…",
1474
+ "routines.historyCount": "历史 · {n}",
1239
1475
  "routines.history": "运行记录",
1240
1476
  "routines.loading": "加载中…",
1241
1477
  "routines.noRuns": "还没有运行过。",
@@ -1303,6 +1539,30 @@ export const STRINGS = {
1303
1539
  "settings.keepAwakeOn": "开",
1304
1540
  "settings.keepAwakeOff": "关",
1305
1541
  "settings.keepAwakeHint": "OHarness 开着时不让电脑因闲置进入睡眠,定时任务才能按时运行。合上笔记本盖子仍会睡眠。",
1542
+ "settings.section.remote": "远程控制",
1543
+ "settings.remote": "允许 iPhone 控制这台 Mac",
1544
+ "settings.remote.off": "关",
1545
+ "settings.remote.connecting": "连接中…",
1546
+ "settings.remote.online": "在线",
1547
+ "settings.remote.signedOut": "未登录",
1548
+ "settings.remoteHint": "登录同一个 OHarness 账号的 OHarness iPhone 应用可以在这里打开会话、发送消息、批准操作。每台新手机都需要你在这个界面点「允许」,并核对与手机上一致的 6 位代码。流量经中继端到端加密,手机无法开启跳过审批模式。",
1549
+ "settings.remoteAwake": "开启期间,这台电脑不会因闲置进入睡眠,手机才能连上。合上笔记本盖子仍会睡眠。",
1550
+ "settings.remoteStatus.off": "已关闭——没有手机能连到这台电脑。",
1551
+ "settings.remoteStatus.connecting": "正在连接中继…",
1552
+ "settings.remoteStatus.online": "在线——你的 iPhone 可以连到这台电脑。",
1553
+ "settings.remoteStatus.signedOut": "需要 OHarness 账号。登录后才会上线;在此之前没有手机能连到这台电脑。",
1554
+ "settings.remoteSignIn": "登录",
1555
+ "settings.remotePhones": "已配对的手机",
1556
+ "settings.remoteNoPhones": "还没有配对的手机。",
1557
+ "settings.remotePairedOn": "配对于 {date}",
1558
+ "settings.remoteForget": "移除",
1559
+ "settings.remoteForgotten": "已移除 {name}。它再次连接时需要你重新允许。",
1560
+ "settings.computerTakeover": "操作电脑:接管鼠标键盘",
1561
+ "settings.computerTakeoverAsk": "每次询问",
1562
+ "settings.computerTakeoverNever": "从不",
1563
+ "settings.computerTakeoverHint": "操作电脑会尽量在后台进行。有些操作(拖放,以及 Windows 上的大多数点击)需要真实的鼠标和键盘:打开时每次先问你;关闭时只在后台操作,做不到的会告诉你。",
1564
+ "settings.computerBlocked": "永远不能查看或操作的应用(每行一个:名称、bundle id 或 exe 名)。密码管理器和安全设置始终被禁止。",
1565
+ "settings.computerBlockedPlaceholder": "例如 com.tinyspeck.slackmacgap 或 slack.exe",
1306
1566
  "settings.browserMode": "浏览器",
1307
1567
  "settings.browserMode.auto": "自动",
1308
1568
  "settings.browserMode.builtin": "内置",
@@ -1345,8 +1605,20 @@ export const STRINGS = {
1345
1605
  "usage.back": "返回设置",
1346
1606
  "usage.tokens": "{n} tokens",
1347
1607
  "usage.cached": "{pct}% 命中缓存",
1608
+ "ctx.title": "上下文窗口",
1609
+ "ctx.total": "{used} / {total}({pct}%)",
1610
+ "ctx.system": "系统提示词",
1611
+ "ctx.tools": "工具定义",
1612
+ "ctx.messages": "对话消息",
1613
+ "ctx.free": "剩余空间",
1614
+ "ctx.autoAt": "达到 {n} 时自动压缩",
1615
+ "ctx.autoOff": "自动压缩已关闭",
1616
+ "ctx.measured": "总量来自服务商对上一次请求的统计,各部分占比为估算",
1617
+ "ctx.estimated": "下一次回复前为估算值",
1618
+ "ctx.compactNow": "立即压缩",
1348
1619
  "usage.cacheHint": "发送出去的内容中,有多大比例是从提示词缓存里取回的,而不是重新计费",
1349
1620
  "usage.context": "已用上下文",
1621
+ "usage.contextOf": "上下文 {used} / {total}({pct}%)",
1350
1622
  "usage.spend": "已花费",
1351
1623
  "usage.tokensLabel": "Token",
1352
1624
  "usage.cacheLabel": "缓存命中",
@@ -1422,6 +1694,8 @@ export const STRINGS = {
1422
1694
  "files.terminalTab": "终端",
1423
1695
  "files.refresh": "刷新",
1424
1696
  "files.close": "关闭",
1697
+ "files.search": "搜索文件",
1698
+ "files.noMatch": "没有匹配的文件",
1425
1699
  "files.empty": "这个文件夹是空的",
1426
1700
  "files.pick": "选择一个文件进行预览",
1427
1701
  "files.binary": "这不是文本文件,无法预览。",
@@ -1495,6 +1769,26 @@ export const STRINGS = {
1495
1769
  "turn.copy": "复制",
1496
1770
  "turn.copied": "已复制",
1497
1771
  "work.thinking": "思考中",
1772
+ "tasks.title": "后台任务",
1773
+ "tasks.cardTitle": "后台任务已结束",
1774
+ "tasks.status.queued": "排队中",
1775
+ "tasks.status.running": "运行中",
1776
+ "tasks.status.completed": "已完成",
1777
+ "tasks.status.failed": "失败",
1778
+ "tasks.status.cancelled": "已停止",
1779
+ "tasks.open": "查看",
1780
+ "tasks.stop": "停止任务",
1781
+ "tasks.dismiss": "关闭",
1782
+ "tasks.messageLabel": "给这个任务发消息",
1783
+ "tasks.close": "关闭",
1784
+ "tasks.send": "发送",
1785
+ "tasks.more": "还有 {n} 个后台任务",
1786
+ "tasks.turns": "{n} 轮",
1787
+ "tasks.empty": "还没有内容。",
1788
+ "tasks.placeholder.running": "告诉它点什么,它会在下一步读到",
1789
+ "tasks.placeholder.ended": "发一条消息,它会接着之前的进度做",
1790
+ "tasks.placeholder.stopped": "已停止的任务不能继续",
1791
+ "ask.from": "来自 {from}",
1498
1792
  "work.thoughtFor": "思考了 {n} 秒",
1499
1793
  "work.thoughtAbout": "思考完成",
1500
1794
  "review.changes": "改动",