@oharness/server 0.1.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.
- package/dist/analytics.d.ts +47 -0
- package/dist/analytics.js +323 -0
- package/dist/analytics.js.map +1 -0
- package/dist/artifacts.d.ts +53 -0
- package/dist/artifacts.js +129 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/canvas.d.ts +28 -0
- package/dist/canvas.js +646 -0
- package/dist/canvas.js.map +1 -0
- package/dist/changes.d.ts +54 -0
- package/dist/changes.js +154 -0
- package/dist/changes.js.map +1 -0
- package/dist/files.d.ts +48 -0
- package/dist/files.js +168 -0
- package/dist/files.js.map +1 -0
- package/dist/i18n.d.ts +15 -0
- package/dist/i18n.js +625 -0
- package/dist/i18n.js.map +1 -0
- package/dist/icons.d.ts +9 -0
- package/dist/icons.js +197 -0
- package/dist/icons.js.map +1 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.js +148 -0
- package/dist/main.js.map +1 -0
- package/dist/markdown.d.ts +10 -0
- package/dist/markdown.js +253 -0
- package/dist/markdown.js.map +1 -0
- package/dist/page.d.ts +1 -0
- package/dist/page.js +8591 -0
- package/dist/page.js.map +1 -0
- package/dist/pick.d.ts +62 -0
- package/dist/pick.js +215 -0
- package/dist/pick.js.map +1 -0
- package/dist/prefs.d.ts +59 -0
- package/dist/prefs.js +66 -0
- package/dist/prefs.js.map +1 -0
- package/dist/projects.d.ts +34 -0
- package/dist/projects.js +129 -0
- package/dist/projects.js.map +1 -0
- package/dist/server.d.ts +50 -0
- package/dist/server.js +2789 -0
- package/dist/server.js.map +1 -0
- package/package.json +36 -0
package/dist/i18n.js
ADDED
|
@@ -0,0 +1,625 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UI copy, in one place per language.
|
|
3
|
+
*
|
|
4
|
+
* English is the source: a key with no translation falls back to it rather
|
|
5
|
+
* than showing the key, because a missing string should degrade to readable
|
|
6
|
+
* text, not to `nav.models`. The locale is chosen from the browser and can be
|
|
7
|
+
* overridden with `?lang=`, so a translation can be checked without changing
|
|
8
|
+
* system settings.
|
|
9
|
+
*/
|
|
10
|
+
export const STRINGS = {
|
|
11
|
+
en: {
|
|
12
|
+
"app.name": "OHarness",
|
|
13
|
+
"nav.new": "New session",
|
|
14
|
+
"nav.search": "Search",
|
|
15
|
+
"nav.artifacts": "Artifacts",
|
|
16
|
+
"nav.models": "Models",
|
|
17
|
+
"nav.routines": "Routines",
|
|
18
|
+
"nav.settings": "Settings",
|
|
19
|
+
"tabs.new": "New tab",
|
|
20
|
+
"tabs.close": "Close tab",
|
|
21
|
+
"composer.placeholder": "Describe a task…",
|
|
22
|
+
"composer.attach": "Add files, folders and connectors",
|
|
23
|
+
"composer.workspace": "Where this session runs",
|
|
24
|
+
"add.attachFiles": "Attach files or photos",
|
|
25
|
+
"add.attachFolders": "Attach folders",
|
|
26
|
+
"add.connectors": "Connectors",
|
|
27
|
+
"add.plugins": "Plugins",
|
|
28
|
+
"add.upload": "Upload from computer",
|
|
29
|
+
"add.up": "Back",
|
|
30
|
+
"add.noDialog": "This machine has no file dialog. Type @ to name a file in the project.",
|
|
31
|
+
"add.outsideFile": "{name} is outside the project and too large to send with the message — the agent will not be able to open it.",
|
|
32
|
+
"add.outsideFolder": "{name} is outside the project — the agent will not be able to open it.",
|
|
33
|
+
"add.tools": "{n} tools",
|
|
34
|
+
"add.offline": "not connected",
|
|
35
|
+
"add.needsAuth": "waiting for you to sign in",
|
|
36
|
+
"market.installed": "In this session",
|
|
37
|
+
"market.available": "Available",
|
|
38
|
+
"market.add": "Add",
|
|
39
|
+
"market.adding": "Adding…",
|
|
40
|
+
"market.needsEnv": "needs {names} in the environment",
|
|
41
|
+
"market.serverIdle": "1 server, not started",
|
|
42
|
+
"market.serversIdle": "{n} servers, not started",
|
|
43
|
+
"market.authorize": "Sign in",
|
|
44
|
+
"market.authorizing": "Waiting…",
|
|
45
|
+
"market.authOpened": "Finish signing in to {name} in the tab that just opened.",
|
|
46
|
+
"market.authorized": "Signed in to {name}.",
|
|
47
|
+
"market.attach": "Attach to this message",
|
|
48
|
+
"market.close": "Done",
|
|
49
|
+
"market.loading": "Loading…",
|
|
50
|
+
"market.empty": "Nothing here yet.",
|
|
51
|
+
"market.connectorsNote": "MCP servers. Adding one starts it now and keeps it for next time.",
|
|
52
|
+
"market.pluginsNote": "Loaded from ~/.oharness/plugins, .oharness/plugins, and whatever Claude Code has installed. Their skills and agents are used; their servers and hooks are not started on their own.",
|
|
53
|
+
"add.noConnectors": "No connectors configured",
|
|
54
|
+
"add.noPlugins": "No plugins installed",
|
|
55
|
+
"add.more": "Keep typing to narrow this down",
|
|
56
|
+
"add.remove": "Remove",
|
|
57
|
+
"composer.send": "Send",
|
|
58
|
+
"composer.stop": "Stop",
|
|
59
|
+
"empty.title": "What should I work on?",
|
|
60
|
+
"empty.connected": "Connected to",
|
|
61
|
+
// The invitation. Labels stay short enough to read as chips; the prompt is
|
|
62
|
+
// the sentence the chip actually sends, so it can afford to be specific.
|
|
63
|
+
"starter.explain": "Map the entry points and trace one request end to end",
|
|
64
|
+
"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.",
|
|
65
|
+
"starter.bugs": "Audit the input, error and concurrency paths for bugs",
|
|
66
|
+
"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.",
|
|
67
|
+
"starter.tests": "Test the three riskiest functions nothing covers",
|
|
68
|
+
"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.",
|
|
69
|
+
"starter.review": "Review my uncommitted diff before I commit it",
|
|
70
|
+
"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.",
|
|
71
|
+
"starter.faster": "Profile the slowest path, then make it measurably faster",
|
|
72
|
+
"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.",
|
|
73
|
+
"starter.plan": "Turn what I am building into an ordered plan",
|
|
74
|
+
"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.",
|
|
75
|
+
"starter.docs": "Write a README whose commands you have actually run",
|
|
76
|
+
"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.",
|
|
77
|
+
"starter.digest": "Summarise this week's commits as a status update",
|
|
78
|
+
"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.",
|
|
79
|
+
"starter.automate": "Turn the most repetitive chore into one command",
|
|
80
|
+
"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.",
|
|
81
|
+
"starter.backlog": "Rank every TODO by what ignoring it will cost",
|
|
82
|
+
"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.",
|
|
83
|
+
"starter.landing": "Write landing page copy backed by what the code does",
|
|
84
|
+
"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.",
|
|
85
|
+
"starter.launch": "Draft the launch post, short version and blog version",
|
|
86
|
+
"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.",
|
|
87
|
+
"starter.pitch": "Pitch this to a non-technical buyer in five sentences",
|
|
88
|
+
"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.",
|
|
89
|
+
"starter.position": "Write one page on who this is for and what it replaces",
|
|
90
|
+
"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.",
|
|
91
|
+
"starter.changelog": "Turn the commits since the last release into a changelog",
|
|
92
|
+
"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.",
|
|
93
|
+
"palette.placeholder": "Search sessions, projects and actions…",
|
|
94
|
+
"palette.actions": "Actions",
|
|
95
|
+
"palette.sessions": "Sessions",
|
|
96
|
+
"palette.projects": "Projects",
|
|
97
|
+
"palette.switchProject": "Switch project…",
|
|
98
|
+
"palette.moveHint": "move",
|
|
99
|
+
"palette.openHint": "open",
|
|
100
|
+
"palette.closeHint": "close",
|
|
101
|
+
"menu.search": "Search…",
|
|
102
|
+
"menu.none": "No match",
|
|
103
|
+
"menu.manage": "Manage models",
|
|
104
|
+
"menu.setUp": "Not connected — set up…",
|
|
105
|
+
"menu.discover": "No models yet — discover…",
|
|
106
|
+
"models.title": "Models",
|
|
107
|
+
"models.discoverAll": "Discover all",
|
|
108
|
+
"models.discover": "Discover",
|
|
109
|
+
"models.connect": "Connect",
|
|
110
|
+
"models.saving": "saving…",
|
|
111
|
+
"models.disconnect": "Disconnect",
|
|
112
|
+
"models.connected": "Connected",
|
|
113
|
+
"models.popular": "Popular",
|
|
114
|
+
"models.more": "More providers",
|
|
115
|
+
"models.searchProviders": "Search providers…",
|
|
116
|
+
"models.openIn": "Open in Models",
|
|
117
|
+
"models.noModels": "no models",
|
|
118
|
+
"models.nModels": "{n} models",
|
|
119
|
+
"models.asking": "Asking {id} for its model list…",
|
|
120
|
+
"models.notConnected": "Not connected. Open it in Models to add a key.",
|
|
121
|
+
"models.storedIn": "Stored in ~/.oharness/auth.json (0600). Or set {vars} instead.",
|
|
122
|
+
"models.getKey": "Get a key",
|
|
123
|
+
"models.recommended": "Recommended",
|
|
124
|
+
// The paywall. Every string here is read by someone who has just been
|
|
125
|
+
// stopped mid-task, so none of them says "error" and all of them say what
|
|
126
|
+
// to do next.
|
|
127
|
+
"paywall.title": "Out of credits",
|
|
128
|
+
"paywall.desc": "This turn could not be paid for.",
|
|
129
|
+
"paywall.checking": "Checking the balance…",
|
|
130
|
+
"paywall.unit": "credits",
|
|
131
|
+
"paywall.balance": "{credits} credits",
|
|
132
|
+
"paywall.subscribed": "The {plan} credits for this period are spent. Top up to keep going.",
|
|
133
|
+
"paywall.new": "This account has no credits yet.",
|
|
134
|
+
"paywall.topUp": "Top up",
|
|
135
|
+
"paywall.subscribe": "Subscribe",
|
|
136
|
+
"paywall.opened": "Opened the payment page in your browser. This closes itself once the credits land.",
|
|
137
|
+
"paywall.ready": "{credits} credits available. Send it again.",
|
|
138
|
+
"paywall.notForSale": "This deployment does not sell credits — add them on the OHarness site.",
|
|
139
|
+
"paywall.unreachable": "Could not reach the billing service. The OHarness site can still take a payment.",
|
|
140
|
+
"paywall.signIn": "Sign in to see what this account has left.",
|
|
141
|
+
"paywall.later": "Later",
|
|
142
|
+
"paywall.onSite": "Open my account page",
|
|
143
|
+
// The dialog's left column. Deliberately the same sentences the website's
|
|
144
|
+
// own sign-in uses: they are the same account, and two surfaces describing
|
|
145
|
+
// it differently is how a reader ends up wondering whether it is.
|
|
146
|
+
"auth.lede": "One account for the site, the CLI and this app. Signing in here is the same sign-in the website does.",
|
|
147
|
+
"auth.lede.web": "One account for the site, the CLI and this page. Signing in here is the same sign-in the website does.",
|
|
148
|
+
"auth.point.one": "One account for the site, the CLI and the desktop app.",
|
|
149
|
+
"auth.point.two": "The app signs in with one click — no key to copy across.",
|
|
150
|
+
"auth.point.two.web": "Signing in here is one click — no key to copy across.",
|
|
151
|
+
"auth.point.three": "No card is asked for until you choose a plan.",
|
|
152
|
+
// Shown when a turn came back 401. Says which vendor refused, because the
|
|
153
|
+
// model that was running is not always the one the picker last showed.
|
|
154
|
+
"auth.refused": "{provider} refused the credential this app is using. Connect it again to keep going.",
|
|
155
|
+
"models.signIn": "Sign in",
|
|
156
|
+
// Not "Sign in": the button above it in the dialog already says that, and
|
|
157
|
+
// that one opens the browser. This submits a code out of an email.
|
|
158
|
+
"models.verify": "Verify and sign in",
|
|
159
|
+
"models.sendCode": "Email a code",
|
|
160
|
+
"models.sending": "sending…",
|
|
161
|
+
"models.email": "you@example.com",
|
|
162
|
+
"models.code": "Sign-in code",
|
|
163
|
+
"models.orKey": "Or paste an API key",
|
|
164
|
+
"models.signInWithSite": "Sign in with the OHarness website",
|
|
165
|
+
"models.signInOpened": "Opened {site} in your browser. This updates as soon as you are signed in.",
|
|
166
|
+
"models.signedInAs": "Signed in as {email}",
|
|
167
|
+
"models.orCode": "No browser on this machine? Have a sign-in code emailed instead",
|
|
168
|
+
"models.orCode.web": "Can't open the website from here? Have a sign-in code emailed instead",
|
|
169
|
+
"models.cancel": "Cancel",
|
|
170
|
+
"models.close": "Close",
|
|
171
|
+
"account.signIn": "Sign in",
|
|
172
|
+
"account.localOnly": "Local only",
|
|
173
|
+
"account.signedIn": "Signed in",
|
|
174
|
+
"account.dashboard": "Account dashboard",
|
|
175
|
+
"account.signOut": "Sign out",
|
|
176
|
+
"models.keyStored": "Stored in ~/.oharness/auth.json (0600).",
|
|
177
|
+
"models.keyEnv": "Or set",
|
|
178
|
+
"models.discovered": "{id}: {n} models",
|
|
179
|
+
"models.discoveredNone": "{id} answered with no models. Reached {url}.",
|
|
180
|
+
"models.envConnected": "Connected by {name}. Unset it to disconnect, or save a key here to override it.",
|
|
181
|
+
"routines.title": "Routines",
|
|
182
|
+
"routines.none": "No schedules configured.",
|
|
183
|
+
"routines.hint": "Add them under \"schedules\" in oharness.config.json — a name, a five-field cron, and the prompt each firing runs.",
|
|
184
|
+
"routines.run": "Run now",
|
|
185
|
+
"routines.running": "running…",
|
|
186
|
+
"settings.title": "Settings",
|
|
187
|
+
"settings.cwd": "Working directory",
|
|
188
|
+
"settings.writes": "Writes",
|
|
189
|
+
"settings.audit": "Audit log",
|
|
190
|
+
"settings.auditOnValue": "on — kept with each session",
|
|
191
|
+
"settings.auditOffValue": "off",
|
|
192
|
+
"settings.auditOff": "Nothing is being recorded. Switch it on to keep a trail of what the agent was allowed to do.",
|
|
193
|
+
"settings.auditOn": "Every permission decision and the answer it got, stored beside the transcript. It stays on this machine — the trail is never synced.",
|
|
194
|
+
"settings.auditProject": "This project's config decides it, so it cannot be changed here.",
|
|
195
|
+
"settings.auditFile": "Also appended to {path}.",
|
|
196
|
+
"settings.auditExport": "Export this session",
|
|
197
|
+
"settings.auditExportAll": "Export everything",
|
|
198
|
+
"settings.auditEmpty": "Nothing recorded in this session yet.",
|
|
199
|
+
"settings.auditMore": "{n} older entries not shown.",
|
|
200
|
+
"settings.rules": "Permission rules",
|
|
201
|
+
"settings.rulesHint": "What the agent may do without asking, what stops for a question, and what is refused outright.",
|
|
202
|
+
"settings.files": "Settings files",
|
|
203
|
+
"settings.filesHint": "Where the settings on this page are read from.",
|
|
204
|
+
"settings.sessionApproved": "approved this session",
|
|
205
|
+
"settings.notPersisted": "Not persisted.",
|
|
206
|
+
"settings.change": "Change…",
|
|
207
|
+
"settings.cwdHint": "Every session, tool call and write is rooted here.",
|
|
208
|
+
"settings.analytics": "Usage analytics",
|
|
209
|
+
"settings.analyticsOn": "On",
|
|
210
|
+
"settings.analyticsOff": "Off",
|
|
211
|
+
"settings.analyticsEnable": "Turn on",
|
|
212
|
+
"settings.analyticsDisable": "Turn off",
|
|
213
|
+
"settings.analyticsHint": "Off unless you turn it on. Sends which features were used — a panel opened, a model switched — never prompts, paths, diffs or anything you typed.",
|
|
214
|
+
// The line under the composer, and the page it opens onto. "Tokens" is
|
|
215
|
+
// left untranslated everywhere below: it is the word the bills, the model
|
|
216
|
+
// pickers and the providers all use, in every language.
|
|
217
|
+
"usage.title": "Usage",
|
|
218
|
+
"usage.value": "Tokens, cache hits and spend, per model and per session",
|
|
219
|
+
"usage.hint": "Totalled from the transcripts on this machine. Nothing is sent anywhere to work it out.",
|
|
220
|
+
"usage.open": "Open",
|
|
221
|
+
"usage.back": "Back to settings",
|
|
222
|
+
"usage.tokens": "{n} tokens",
|
|
223
|
+
"usage.cached": "{pct}% cached",
|
|
224
|
+
"usage.cacheHint": "How much of what was sent came back out of the prompt cache instead of being charged again",
|
|
225
|
+
"usage.context": "Context used",
|
|
226
|
+
"usage.spend": "Spent",
|
|
227
|
+
"usage.tokensLabel": "Tokens",
|
|
228
|
+
"usage.cacheLabel": "From cache",
|
|
229
|
+
"usage.overSessions": "across {n} sessions",
|
|
230
|
+
"usage.overSession": "across one session",
|
|
231
|
+
"usage.inOut": "{in} in · {out} out",
|
|
232
|
+
"usage.cacheSplit": "{read} read · {written} written",
|
|
233
|
+
"usage.range.7d": "7 days",
|
|
234
|
+
"usage.range.30d": "30 days",
|
|
235
|
+
"usage.range.90d": "90 days",
|
|
236
|
+
"usage.range.all": "All",
|
|
237
|
+
"usage.nothing": "nothing spent",
|
|
238
|
+
"usage.perDay": "per day",
|
|
239
|
+
"usage.perWeek": "per week",
|
|
240
|
+
"usage.otherModels": "{n} others",
|
|
241
|
+
"usage.byModel": "By model",
|
|
242
|
+
"usage.bySession": "Recent sessions",
|
|
243
|
+
"usage.thisSession": "this session",
|
|
244
|
+
"usage.none": "Nothing has been spent yet.",
|
|
245
|
+
"usage.scope": "Every session stored on this machine, including ones started from the terminal.",
|
|
246
|
+
"usage.scopeCapped": "The {n} most recent sessions on this machine. Older ones are not counted.",
|
|
247
|
+
"projects.title": "Projects",
|
|
248
|
+
"projects.search": "Search projects",
|
|
249
|
+
"projects.add": "Add project",
|
|
250
|
+
"projects.browse": "Browse…",
|
|
251
|
+
"projects.pickFailed": "Could not open a folder chooser here — browse instead.",
|
|
252
|
+
"projects.up": "Up",
|
|
253
|
+
"projects.choose": "Open this folder",
|
|
254
|
+
"projects.other": "Another folder…",
|
|
255
|
+
"projects.missing": "missing",
|
|
256
|
+
"projects.open": "Open",
|
|
257
|
+
"projects.pin": "Pin",
|
|
258
|
+
"projects.unpin": "Unpin",
|
|
259
|
+
"projects.forget": "Remove from list",
|
|
260
|
+
"projects.delete": "Delete {n} session(s)",
|
|
261
|
+
"projects.deleteConfirm": "Delete permanently",
|
|
262
|
+
"projects.deleteNote": "Transcripts, artifacts and the permission trail — here and on any device you sync with. The files in the directory are untouched.",
|
|
263
|
+
"projects.deleted": "Deleted {n} session(s) recorded in {name}.",
|
|
264
|
+
"projects.forgot": "{name} is off the list. Its sessions are still here.",
|
|
265
|
+
"error.title": "Could not load",
|
|
266
|
+
"error.stale": "If the server was restarted, reopen the URL it printed — the token changes every run.",
|
|
267
|
+
"ask.allow": "Allow once",
|
|
268
|
+
// Each scope repeats the verb: the three sit side by side, and a bare
|
|
269
|
+
// "This session" next to "Deny" does not say which way it answers.
|
|
270
|
+
"ask.session": "Allow this session",
|
|
271
|
+
"ask.project": "Allow in this project",
|
|
272
|
+
"ask.no": "Deny",
|
|
273
|
+
"ask.scopeSession": "Stops asking for {key} until this session ends. Nothing is written to disk.",
|
|
274
|
+
"ask.scopeProject": "Writes an allow rule for {key} into this project's settings. Revoke it under Settings › Writes.",
|
|
275
|
+
"ask.expand": "Show all {n} lines",
|
|
276
|
+
"ask.collapse": "Show less",
|
|
277
|
+
"ask.raw": "Raw parameters",
|
|
278
|
+
"ask.rawHide": "Hide parameters",
|
|
279
|
+
"ask.nLines": "{n} lines",
|
|
280
|
+
"ask.oneLine": "1 line",
|
|
281
|
+
"ask.diffStat": "+{added} −{removed} lines",
|
|
282
|
+
"ask.tagWrite": "Write file",
|
|
283
|
+
"ask.tagEdit": "Replace text",
|
|
284
|
+
"ask.tagEditAll": "Replace every occurrence",
|
|
285
|
+
"ask.tagBash": "Run command",
|
|
286
|
+
"ask.tagFetch": "Fetch a URL",
|
|
287
|
+
"ask.tagCall": "Tool call",
|
|
288
|
+
"turn.fork": "Fork from here",
|
|
289
|
+
"turn.copy": "Copy",
|
|
290
|
+
"turn.copied": "Copied",
|
|
291
|
+
"work.thinking": "Thinking",
|
|
292
|
+
"work.thoughtFor": "Thought for {n}s",
|
|
293
|
+
"work.thoughtAbout": "Thought about it",
|
|
294
|
+
"review.changes": "Changes",
|
|
295
|
+
"review.nothing": "nothing changed yet",
|
|
296
|
+
"review.files": "{n} files",
|
|
297
|
+
"artifacts.search": "Search artifacts",
|
|
298
|
+
"artifacts.open": "Open",
|
|
299
|
+
"artifacts.none": "Nothing yet.",
|
|
300
|
+
"artifacts.what": "An artifact is something the model makes for you to look at — a chart, a canvas, a rendered page. Ask for one and it will appear here.",
|
|
301
|
+
"artifacts.noMatch": "Nothing matches \u201c{q}\u201d.",
|
|
302
|
+
"artifacts.showing": "{n} of {total}",
|
|
303
|
+
"artifacts.thisSession": "this session",
|
|
304
|
+
"artifacts.fromLogs": "Read from what each session wrote down, so this is everything on this machine — not only the sessions open in a tab. Opening one opens the session that made it.",
|
|
305
|
+
"artifacts.more": "{n} older sessions with artifacts are not listed.",
|
|
306
|
+
"shelf.title": "Artifacts",
|
|
307
|
+
"shelf.nothing": "nothing made yet",
|
|
308
|
+
"time.now": "just now",
|
|
309
|
+
"time.yesterday": "yesterday",
|
|
310
|
+
"session.showMore": "Show more",
|
|
311
|
+
"session.untitled": "Untitled",
|
|
312
|
+
"session.turn": "1 turn",
|
|
313
|
+
"session.turns": "{n} turns",
|
|
314
|
+
"session.more": "More",
|
|
315
|
+
"session.pin": "Pin",
|
|
316
|
+
"session.unpin": "Unpin",
|
|
317
|
+
"session.rename": "Rename",
|
|
318
|
+
"session.fork": "Fork",
|
|
319
|
+
"session.delete": "Delete session",
|
|
320
|
+
"session.deleteConfirm": "Delete permanently",
|
|
321
|
+
"session.deleteNote": "This cannot be undone.",
|
|
322
|
+
"session.deletedForks": "That session had {n} fork(s); they no longer have a parent.",
|
|
323
|
+
},
|
|
324
|
+
zh: {
|
|
325
|
+
"nav.new": "新建会话",
|
|
326
|
+
"nav.search": "搜索",
|
|
327
|
+
"nav.artifacts": "制品",
|
|
328
|
+
"nav.models": "模型",
|
|
329
|
+
"nav.routines": "定时任务",
|
|
330
|
+
"nav.settings": "设置",
|
|
331
|
+
"tabs.new": "新建标签页",
|
|
332
|
+
"tabs.close": "关闭标签页",
|
|
333
|
+
"composer.placeholder": "描述一个任务…",
|
|
334
|
+
"composer.attach": "添加文件、文件夹与连接器",
|
|
335
|
+
"composer.workspace": "此会话运行的工作区",
|
|
336
|
+
"add.attachFiles": "附加文件或图片",
|
|
337
|
+
"add.attachFolders": "附加文件夹",
|
|
338
|
+
"add.connectors": "连接器",
|
|
339
|
+
"add.plugins": "插件",
|
|
340
|
+
"add.upload": "从本机上传",
|
|
341
|
+
"add.up": "返回",
|
|
342
|
+
"add.noDialog": "此机器没有文件对话框。输入 @ 可引用项目内的文件。",
|
|
343
|
+
"add.outsideFile": "{name} 在项目之外,也太大而无法随消息发送——agent 打不开它。",
|
|
344
|
+
"add.outsideFolder": "{name} 在项目之外——agent 打不开它。",
|
|
345
|
+
"add.tools": "{n} 个工具",
|
|
346
|
+
"add.offline": "未连接",
|
|
347
|
+
"add.needsAuth": "等待你登录",
|
|
348
|
+
"market.installed": "本会话可用",
|
|
349
|
+
"market.available": "可添加",
|
|
350
|
+
"market.add": "添加",
|
|
351
|
+
"market.adding": "正在添加…",
|
|
352
|
+
"market.needsEnv": "需要环境变量 {names}",
|
|
353
|
+
"market.serverIdle": "1 个服务器,未启动",
|
|
354
|
+
"market.serversIdle": "{n} 个服务器,未启动",
|
|
355
|
+
"market.authorize": "登录",
|
|
356
|
+
"market.authorizing": "等待中…",
|
|
357
|
+
"market.authOpened": "请在刚打开的标签页里完成 {name} 的登录。",
|
|
358
|
+
"market.authorized": "已登录 {name}。",
|
|
359
|
+
"market.attach": "附加到本条消息",
|
|
360
|
+
"market.close": "完成",
|
|
361
|
+
"market.loading": "加载中…",
|
|
362
|
+
"market.empty": "这里还没有内容。",
|
|
363
|
+
"market.connectorsNote": "MCP 服务器。添加后立即启动,并在下次继续可用。",
|
|
364
|
+
"market.pluginsNote": "从 ~/.oharness/plugins、.oharness/plugins,以及 Claude Code 已安装的插件中加载。只采用其中的技能与子代理,不会自行启动其服务器和钩子。",
|
|
365
|
+
"add.noConnectors": "尚未配置连接器",
|
|
366
|
+
"add.noPlugins": "尚未安装插件",
|
|
367
|
+
"add.more": "继续输入以缩小范围",
|
|
368
|
+
"add.remove": "移除",
|
|
369
|
+
"composer.send": "发送",
|
|
370
|
+
"composer.stop": "停止",
|
|
371
|
+
"empty.title": "今天做点什么?",
|
|
372
|
+
"empty.connected": "已连接到",
|
|
373
|
+
"starter.explain": "梳理入口,并跟着一条请求走完全程",
|
|
374
|
+
"starter.explain.prompt": "帮我把这个项目梳理一遍:入口在哪里,真正重要的五到八个模块分别管什么,然后挑一条真实请求从头走到尾,按顺序点出它经过的文件。最后告诉我三件新人最容易想不到的事。",
|
|
375
|
+
"starter.bugs": "排查输入、错误和并发路径上的 bug",
|
|
376
|
+
"starter.bugs.prompt": "重点排查处理输入、错误和并发的那些代码路径。每个问题给我 file:line、什么情况会触发、触发之后的代价。有把握的直接修掉,没把握的列出来交给我判断,改动前后都跑一遍测试。",
|
|
377
|
+
"starter.tests": "给最危险又没有测试的三个函数补上测试",
|
|
378
|
+
"starter.tests.prompt": "找出这里风险最高、又没有测试覆盖的三个函数——就是一旦算错代价很大的那种——用项目现有的测试框架给它们补上测试。要覆盖出错的分支,不要只测顺利路径,最后把测试运行结果贴给我。",
|
|
379
|
+
"starter.review": "提交之前 review 我还没提交的改动",
|
|
380
|
+
"starter.review.prompt": "逐个文件 review 我还没提交的改动(git diff):先看正确性,再看命名、死代码和我写了一半的地方。按 file:line、该改什么、为什么重要的格式给我,严重的排在前面,最后直说一句这版能不能提交。",
|
|
381
|
+
"starter.faster": "先测出最慢的路径,再把它优化掉",
|
|
382
|
+
"starter.faster.prompt": "先测量再动手:找出这个项目里最慢的一条路径,把你实际跑出来的耗时给我看,优化之后再用同样的方法测一次。行为必须完全不变、测试必须继续通过——如果做不到,直接告诉我。",
|
|
383
|
+
"starter.plan": "把我要做的事拆成一份有序的计划",
|
|
384
|
+
"starter.plan.prompt": "先问我想做什么,然后把我的回答变成一份计划:五到八个有先后顺序的步骤,每步写清楚要动哪些文件、怎样算做完。把动手前我必须先拍板的决定放在最前面,然后停下来等我回答。",
|
|
385
|
+
"starter.docs": "写一份命令都亲手验证过的 README",
|
|
386
|
+
"starter.docs.prompt": "把这个项目该有的 README 写出来:两句话说清它是做什么的,安装和运行命令要你自己真的跑过确认可用,一个带真实输出的完整示例,以及各项配置和默认值。当前文档里已经不成立的内容直接删掉。",
|
|
387
|
+
"starter.digest": "把这周的提交整理成一份进展汇报",
|
|
388
|
+
"starter.digest.prompt": "读最近七天的提交,给我写一份进展汇报:发布了什么、还在做什么、哪里出了问题、接下来做什么。按主题分组,用人话写而不是抄提交标题,控制在 300 字以内,写成可以直接贴进群里的样子。",
|
|
389
|
+
"starter.automate": "把最费时间的手工步骤做成一条命令",
|
|
390
|
+
"starter.automate.prompt": "找出这个项目里需要手动重复做的事——README 里一步步写的操作、多个脚本里重复出现的命令、每次发版前手工做的动作。挑最费时间的那一件,做成一条带说明的命令,并且完整跑一遍给我看。",
|
|
391
|
+
"starter.backlog": "把 TODO 按放着不管的代价排个序",
|
|
392
|
+
"starter.backlog.prompt": "把代码里所有 TODO、FIXME、HACK 连同 file:line 收集起来,按主题分组,再按“放着不管会付出什么代价”排序。告诉我这周最值得做的三条以及理由,然后把其中成本最低的那条改掉,把 diff 给我看。",
|
|
393
|
+
"starter.landing": "写一版有代码事实支撑的落地页文案",
|
|
394
|
+
"starter.landing.prompt": "读懂这个项目,然后写落地页文案:十个字以内的主标题、一句话副标题、三条价值点(每条都要对应代码里确实做到的事)、一段回应最明显疑虑的文字,以及一个行动号召。保存为 landing.md。",
|
|
395
|
+
"starter.launch": "写发布公告:一条社媒短文加一篇博客",
|
|
396
|
+
"starter.launch.prompt": "为这个项目写两个尺寸的发布公告:一条 280 字符以内的社媒短文,和一篇 400 词左右的博客版,讲清楚问题、前后对比和一个具体例子。语气朴素——不要形容词堆砌、不要感叹号、不要写项目做不到的事。",
|
|
397
|
+
"starter.pitch": "用五句话把它讲给不懂技术的客户听",
|
|
398
|
+
"starter.pitch.prompt": "用整整五句话把这个项目讲给不懂技术的采购方听:问题是什么、他们今天为此付出什么代价、之后会怎样、一个来自代码本身的佐证、下一步该做什么。然后再把这五句压缩成一句我能当面说出口的话。",
|
|
399
|
+
"starter.position": "写一页定位:给谁用、又替代掉了什么",
|
|
400
|
+
"starter.position.prompt": "用一页纸写出这个项目的定位:给谁用、他们雇它来干什么活、它替代掉什么、和几个显而易见的替代品有哪三点不同(每点都要有依据),以及——直说——什么人不该用它。",
|
|
401
|
+
"starter.changelog": "把上次发布之后的提交写成更新日志",
|
|
402
|
+
"starter.changelog.prompt": "把上次发布之后的提交整理成用户看得懂的更新日志。按新增、变更、修复分组,每条写“用户现在能做什么”而不是“哪些文件动了”,破坏性改动连同升级步骤放在最前面。保存到 CHANGELOG.md。",
|
|
403
|
+
"palette.placeholder": "搜索会话、项目与操作…",
|
|
404
|
+
"palette.actions": "操作",
|
|
405
|
+
"palette.sessions": "会话",
|
|
406
|
+
"palette.projects": "项目",
|
|
407
|
+
"palette.switchProject": "切换项目…",
|
|
408
|
+
"palette.moveHint": "移动",
|
|
409
|
+
"palette.openHint": "打开",
|
|
410
|
+
"palette.closeHint": "关闭",
|
|
411
|
+
"menu.search": "搜索…",
|
|
412
|
+
"menu.none": "无匹配",
|
|
413
|
+
"menu.manage": "管理模型",
|
|
414
|
+
"menu.setUp": "未连接 — 去配置…",
|
|
415
|
+
"menu.discover": "暂无模型 — 去获取…",
|
|
416
|
+
"models.title": "模型",
|
|
417
|
+
"models.discoverAll": "全部发现",
|
|
418
|
+
"models.discover": "发现",
|
|
419
|
+
"models.connect": "连接",
|
|
420
|
+
"models.saving": "保存中…",
|
|
421
|
+
"models.disconnect": "断开",
|
|
422
|
+
"models.connected": "已连接",
|
|
423
|
+
"models.popular": "常用",
|
|
424
|
+
"models.more": "更多供应商",
|
|
425
|
+
"models.searchProviders": "搜索供应商…",
|
|
426
|
+
"models.openIn": "在模型页打开",
|
|
427
|
+
"models.noModels": "暂无模型",
|
|
428
|
+
"models.nModels": "{n} 个模型",
|
|
429
|
+
"models.asking": "正在向 {id} 获取模型列表…",
|
|
430
|
+
"models.notConnected": "未连接。到模型页填入 key。",
|
|
431
|
+
"models.storedIn": "存于 ~/.oharness/auth.json(0600)。也可以改设 {vars}。",
|
|
432
|
+
"models.getKey": "获取 key",
|
|
433
|
+
"models.recommended": "推荐",
|
|
434
|
+
"paywall.title": "额度已用完",
|
|
435
|
+
"paywall.desc": "这一轮无法计费。",
|
|
436
|
+
"paywall.checking": "正在查询余额…",
|
|
437
|
+
"paywall.unit": "点数",
|
|
438
|
+
"paywall.balance": "{credits} 点数",
|
|
439
|
+
"paywall.subscribed": "{plan} 本期额度已经用完,充值即可继续。",
|
|
440
|
+
"paywall.new": "这个账号还没有额度。",
|
|
441
|
+
"paywall.topUp": "充值",
|
|
442
|
+
"paywall.subscribe": "订阅",
|
|
443
|
+
"paywall.opened": "已在浏览器中打开付款页,到账后这个窗口会自动关闭。",
|
|
444
|
+
"paywall.ready": "余额 {credits} 点数,再发一次即可。",
|
|
445
|
+
"paywall.notForSale": "这个部署不出售点数 —— 请在 OHarness 站点上添加。",
|
|
446
|
+
"paywall.unreachable": "连不上计费服务。OHarness 站点仍然可以付款。",
|
|
447
|
+
"paywall.signIn": "登录后才能查看这个账号还剩多少。",
|
|
448
|
+
"paywall.later": "以后再说",
|
|
449
|
+
"paywall.onSite": "打开账号页",
|
|
450
|
+
"auth.lede": "网站、命令行和这个客户端是同一个账号,这里登录的就是网站那个登录。",
|
|
451
|
+
"auth.lede.web": "网站、命令行和这个页面是同一个账号,这里登录的就是网站那个登录。",
|
|
452
|
+
"auth.point.one": "网站、命令行和桌面客户端共用一个账号。",
|
|
453
|
+
"auth.point.two": "客户端一键登录,不用手动复制 key。",
|
|
454
|
+
"auth.point.two.web": "在这个页面一键登录,不用手动复制 key。",
|
|
455
|
+
"auth.point.three": "选套餐之前不会要付款方式。",
|
|
456
|
+
"auth.refused": "{provider} 拒绝了这个客户端使用的凭据,重新连接后才能继续。",
|
|
457
|
+
"models.signIn": "登录",
|
|
458
|
+
"models.verify": "验证并登录",
|
|
459
|
+
"models.sendCode": "发送验证码",
|
|
460
|
+
"models.sending": "发送中…",
|
|
461
|
+
"models.email": "you@example.com",
|
|
462
|
+
"models.code": "邮件里的验证码",
|
|
463
|
+
"models.orKey": "或直接填 API key",
|
|
464
|
+
"models.signInWithSite": "用 OHarness 官网登录",
|
|
465
|
+
"models.signInOpened": "已在浏览器中打开 {site},登录完成后这里会自动更新。",
|
|
466
|
+
"models.signedInAs": "已登录:{email}",
|
|
467
|
+
"models.orCode": "这台机器没有浏览器?改用邮箱验证码登录",
|
|
468
|
+
"models.orCode.web": "这里打不开网站?改用邮箱验证码登录",
|
|
469
|
+
"models.cancel": "取消",
|
|
470
|
+
"models.close": "关闭",
|
|
471
|
+
"account.signIn": "登录",
|
|
472
|
+
"account.localOnly": "仅本机",
|
|
473
|
+
"account.signedIn": "已登录",
|
|
474
|
+
"account.dashboard": "账号面板",
|
|
475
|
+
"account.signOut": "退出登录",
|
|
476
|
+
"models.keyStored": "存于 ~/.oharness/auth.json(0600)。",
|
|
477
|
+
"models.keyEnv": "也可以改设环境变量",
|
|
478
|
+
"models.discovered": "{id}:{n} 个模型",
|
|
479
|
+
"models.discoveredNone": "{id} 没有返回任何模型。请求的是 {url}。",
|
|
480
|
+
"models.envConnected": "由 {name} 连接。取消该环境变量即可断开,或在此填 key 覆盖。",
|
|
481
|
+
"routines.title": "定时任务",
|
|
482
|
+
"routines.none": "尚未配置任何计划。",
|
|
483
|
+
"routines.hint": "在 oharness.config.json 的 \"schedules\" 下添加:一个名字、五段式 cron,以及每次触发运行的 prompt。",
|
|
484
|
+
"routines.run": "立即运行",
|
|
485
|
+
"routines.running": "运行中…",
|
|
486
|
+
"settings.title": "设置",
|
|
487
|
+
"settings.cwd": "工作目录",
|
|
488
|
+
"settings.writes": "写入范围",
|
|
489
|
+
"settings.audit": "审计日志",
|
|
490
|
+
"settings.auditOnValue": "已开启 —— 随会话一起保存",
|
|
491
|
+
"settings.auditOffValue": "已关闭",
|
|
492
|
+
"settings.auditOff": "当前不记录。打开后会留下一份「它当时被允许做了什么」的记录。",
|
|
493
|
+
"settings.auditOn": "每一次权限判定连同它得到的答复,都存在对话记录旁边。只留在本机 —— 这份记录不会同步。",
|
|
494
|
+
"settings.auditProject": "由该项目的配置决定,无法在这里更改。",
|
|
495
|
+
"settings.auditFile": "同时追加到 {path}。",
|
|
496
|
+
"settings.auditExport": "导出本会话",
|
|
497
|
+
"settings.auditExportAll": "导出全部",
|
|
498
|
+
"settings.auditEmpty": "这个会话还没有记录。",
|
|
499
|
+
"settings.auditMore": "另有 {n} 条更早的记录未显示。",
|
|
500
|
+
"settings.rules": "权限规则",
|
|
501
|
+
"settings.rulesHint": "哪些操作可以直接执行、哪些会停下来询问、哪些直接拒绝。",
|
|
502
|
+
"settings.files": "设置文件",
|
|
503
|
+
"settings.filesHint": "这个页面上的设置是从这些文件读出来的。",
|
|
504
|
+
"settings.sessionApproved": "本次会话已批准",
|
|
505
|
+
"settings.notPersisted": "不会持久化。",
|
|
506
|
+
"settings.analytics": "使用分析",
|
|
507
|
+
"settings.analyticsOn": "已开启",
|
|
508
|
+
"settings.analyticsOff": "已关闭",
|
|
509
|
+
"settings.analyticsEnable": "开启",
|
|
510
|
+
"settings.analyticsDisable": "关闭",
|
|
511
|
+
"settings.analyticsHint": "默认关闭,由你决定是否开启。只发送用到了哪些功能——打开了哪个面板、切换了哪个模型——不发送提示词、路径、diff,也不发送任何你输入的内容。",
|
|
512
|
+
"settings.change": "更改…",
|
|
513
|
+
"settings.cwdHint": "所有会话、工具调用和写入都以此为根目录。",
|
|
514
|
+
"usage.title": "用量",
|
|
515
|
+
"usage.value": "按模型和会话统计的 token、缓存命中与花费",
|
|
516
|
+
"usage.hint": "统计自本机保存的对话记录。为了算出这些数字,不会向任何地方发送内容。",
|
|
517
|
+
"usage.open": "查看",
|
|
518
|
+
"usage.back": "返回设置",
|
|
519
|
+
"usage.tokens": "{n} tokens",
|
|
520
|
+
"usage.cached": "{pct}% 命中缓存",
|
|
521
|
+
"usage.cacheHint": "发送出去的内容中,有多大比例是从提示词缓存里取回的,而不是重新计费",
|
|
522
|
+
"usage.context": "已用上下文",
|
|
523
|
+
"usage.spend": "已花费",
|
|
524
|
+
"usage.tokensLabel": "Token",
|
|
525
|
+
"usage.cacheLabel": "缓存命中",
|
|
526
|
+
"usage.overSessions": "共 {n} 个会话",
|
|
527
|
+
"usage.overSession": "共 1 个会话",
|
|
528
|
+
"usage.inOut": "输入 {in} · 输出 {out}",
|
|
529
|
+
"usage.cacheSplit": "读取 {read} · 写入 {written}",
|
|
530
|
+
"usage.range.7d": "7 天",
|
|
531
|
+
"usage.range.30d": "30 天",
|
|
532
|
+
"usage.range.90d": "90 天",
|
|
533
|
+
"usage.range.all": "全部",
|
|
534
|
+
"usage.nothing": "没有花费",
|
|
535
|
+
"usage.perDay": "每天",
|
|
536
|
+
"usage.perWeek": "每周",
|
|
537
|
+
"usage.otherModels": "其他 {n} 个",
|
|
538
|
+
"usage.byModel": "按模型",
|
|
539
|
+
"usage.bySession": "最近的会话",
|
|
540
|
+
"usage.thisSession": "当前会话",
|
|
541
|
+
"usage.none": "还没有产生任何花费。",
|
|
542
|
+
"usage.scope": "包含本机保存的每一个会话,也包含从终端启动的那些。",
|
|
543
|
+
"usage.scopeCapped": "本机最近的 {n} 个会话。更早的没有计入。",
|
|
544
|
+
"projects.title": "项目",
|
|
545
|
+
"projects.search": "搜索项目",
|
|
546
|
+
"projects.add": "添加项目",
|
|
547
|
+
"projects.browse": "浏览…",
|
|
548
|
+
"projects.pickFailed": "此环境无法打开系统对话框 —— 请用浏览方式选择。",
|
|
549
|
+
"projects.up": "上一级",
|
|
550
|
+
"projects.choose": "打开此文件夹",
|
|
551
|
+
"projects.other": "其他文件夹…",
|
|
552
|
+
"projects.missing": "不存在",
|
|
553
|
+
"projects.open": "打开",
|
|
554
|
+
"projects.pin": "置顶",
|
|
555
|
+
"projects.unpin": "取消置顶",
|
|
556
|
+
"projects.forget": "从列表移除",
|
|
557
|
+
"projects.delete": "删除 {n} 个会话",
|
|
558
|
+
"projects.deleteConfirm": "永久删除",
|
|
559
|
+
"projects.deleteNote": "对话记录、artifact 和权限记录 —— 本机以及与你同步的其他设备上都会删除。目录里的文件不受影响。",
|
|
560
|
+
"projects.deleted": "已删除 {name} 下的 {n} 个会话。",
|
|
561
|
+
"projects.forgot": "{name} 已从列表移除,它的会话仍在。",
|
|
562
|
+
"error.title": "加载失败",
|
|
563
|
+
"error.stale": "如果服务器重启过,请重新打开它打印的 URL —— token 每次都不同。",
|
|
564
|
+
"ask.allow": "允许一次",
|
|
565
|
+
"ask.session": "本次会话都允许",
|
|
566
|
+
"ask.project": "此项目都允许",
|
|
567
|
+
"ask.no": "拒绝",
|
|
568
|
+
"ask.scopeSession": "本次会话结束前不再为 {key} 询问,不写入磁盘。",
|
|
569
|
+
"ask.scopeProject": "把 {key} 的放行规则写进此项目的设置,可在「设置 › 写入范围」撤销。",
|
|
570
|
+
"ask.expand": "展开全部 {n} 行",
|
|
571
|
+
"ask.collapse": "收起",
|
|
572
|
+
"ask.raw": "原始参数",
|
|
573
|
+
"ask.rawHide": "隐藏参数",
|
|
574
|
+
"ask.nLines": "{n} 行",
|
|
575
|
+
"ask.oneLine": "1 行",
|
|
576
|
+
"ask.diffStat": "+{added} −{removed} 行",
|
|
577
|
+
"ask.tagWrite": "写入文件",
|
|
578
|
+
"ask.tagEdit": "替换文本",
|
|
579
|
+
"ask.tagEditAll": "替换全部匹配",
|
|
580
|
+
"ask.tagBash": "执行命令",
|
|
581
|
+
"ask.tagFetch": "抓取网址",
|
|
582
|
+
"ask.tagCall": "工具调用",
|
|
583
|
+
"turn.fork": "从这里分叉",
|
|
584
|
+
"turn.copy": "复制",
|
|
585
|
+
"turn.copied": "已复制",
|
|
586
|
+
"work.thinking": "思考中",
|
|
587
|
+
"work.thoughtFor": "思考了 {n} 秒",
|
|
588
|
+
"work.thoughtAbout": "思考完成",
|
|
589
|
+
"review.changes": "改动",
|
|
590
|
+
"review.nothing": "尚无改动",
|
|
591
|
+
"review.files": "{n} 个文件",
|
|
592
|
+
"artifacts.search": "搜索制品",
|
|
593
|
+
"artifacts.open": "打开",
|
|
594
|
+
"artifacts.none": "还没有制品。",
|
|
595
|
+
"artifacts.what": "制品是模型做出来给你看的东西 —— 一张图、一块画布、一个渲染好的页面。让它做一个,就会出现在这里。",
|
|
596
|
+
"artifacts.noMatch": "没有匹配「{q}」的制品。",
|
|
597
|
+
"artifacts.showing": "{total} 个中的 {n} 个",
|
|
598
|
+
"artifacts.thisSession": "当前会话",
|
|
599
|
+
"artifacts.fromLogs": "读自每个会话自己记下的内容,所以这里是本机的全部制品 —— 不只是标签页里开着的那些会话。打开某个制品会同时打开做出它的会话。",
|
|
600
|
+
"artifacts.more": "还有 {n} 个更早的、有制品的会话未列出。",
|
|
601
|
+
"shelf.title": "制品",
|
|
602
|
+
"shelf.nothing": "尚无制品",
|
|
603
|
+
"time.now": "刚刚",
|
|
604
|
+
"time.yesterday": "昨天",
|
|
605
|
+
"session.showMore": "显示更多",
|
|
606
|
+
"session.untitled": "未命名",
|
|
607
|
+
"session.turn": "1 轮",
|
|
608
|
+
"session.turns": "{n} 轮",
|
|
609
|
+
"session.more": "更多",
|
|
610
|
+
"session.pin": "置顶",
|
|
611
|
+
"session.unpin": "取消置顶",
|
|
612
|
+
"session.rename": "重命名",
|
|
613
|
+
"session.fork": "分叉",
|
|
614
|
+
"session.delete": "删除会话",
|
|
615
|
+
"session.deleteConfirm": "永久删除",
|
|
616
|
+
"session.deleteNote": "此操作不可撤销。",
|
|
617
|
+
"session.deletedForks": "该会话有 {n} 个分支,它们的父会话已不存在。",
|
|
618
|
+
},
|
|
619
|
+
};
|
|
620
|
+
/** Locales offered in the UI, in menu order. */
|
|
621
|
+
export const LOCALES = [
|
|
622
|
+
{ id: "en", label: "English" },
|
|
623
|
+
{ id: "zh", label: "中文" },
|
|
624
|
+
];
|
|
625
|
+
//# sourceMappingURL=i18n.js.map
|