@parallel-cli/parallel 0.3.3
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/LICENSE +21 -0
- package/README.md +316 -0
- package/dist/agents/agent.js +518 -0
- package/dist/agents/tools.js +570 -0
- package/dist/commands.js +480 -0
- package/dist/config.js +163 -0
- package/dist/controller.js +703 -0
- package/dist/coordination/blackboard.js +225 -0
- package/dist/i18n.js +1087 -0
- package/dist/index.js +196 -0
- package/dist/llm/client.js +46 -0
- package/dist/pricing.js +76 -0
- package/dist/server.js +149 -0
- package/dist/skills.js +132 -0
- package/dist/types.js +1 -0
- package/dist/ui/AgentPanel.js +25 -0
- package/dist/ui/App.js +400 -0
- package/dist/ui/ApprovalPrompt.js +18 -0
- package/dist/ui/AttachApp.js +126 -0
- package/dist/ui/CommandInput.js +154 -0
- package/dist/ui/Md.js +40 -0
- package/dist/ui/QuestionPrompt.js +58 -0
- package/dist/ui/SettingsPanel.js +217 -0
- package/dist/ui/Spinner.js +12 -0
- package/dist/ui/Wizard.js +66 -0
- package/dist/ui/clipboard.js +36 -0
- package/dist/ui/theme.js +27 -0
- package/dist/ui/views.js +94 -0
- package/package.json +59 -0
package/dist/i18n.js
ADDED
|
@@ -0,0 +1,1087 @@
|
|
|
1
|
+
export const LANGS = [
|
|
2
|
+
{ code: 'en', label: 'English' },
|
|
3
|
+
{ code: 'zh', label: '中文(普通话)' },
|
|
4
|
+
{ code: 'es', label: 'Español' },
|
|
5
|
+
{ code: 'fr', label: 'Français' },
|
|
6
|
+
];
|
|
7
|
+
export const LANG_NAME_EN = {
|
|
8
|
+
en: 'English',
|
|
9
|
+
zh: 'Chinese (Mandarin)',
|
|
10
|
+
es: 'Spanish',
|
|
11
|
+
fr: 'French',
|
|
12
|
+
};
|
|
13
|
+
let current = 'en';
|
|
14
|
+
export function setLang(l) {
|
|
15
|
+
current = l;
|
|
16
|
+
}
|
|
17
|
+
export function getLang() {
|
|
18
|
+
return current;
|
|
19
|
+
}
|
|
20
|
+
export function t(key, vars) {
|
|
21
|
+
const s = STRINGS[current]?.[key] ?? STRINGS.en[key] ?? key;
|
|
22
|
+
return vars ? s.replace(/\{(\w+)\}/g, (_, k) => String(vars[k] ?? '')) : s;
|
|
23
|
+
}
|
|
24
|
+
const en = {
|
|
25
|
+
tagline: 'Code agents in parallel, in real time — no locks, no waiting.',
|
|
26
|
+
// agent states
|
|
27
|
+
'st.idle': 'IDLE',
|
|
28
|
+
'st.thinking': 'THINKING',
|
|
29
|
+
'st.listening': 'LISTENING TO AGENTS',
|
|
30
|
+
'st.working': 'WORKING',
|
|
31
|
+
'st.waiting': 'NEEDS YOUR OK',
|
|
32
|
+
'st.paused': 'PAUSED',
|
|
33
|
+
'st.done': 'DONE',
|
|
34
|
+
'st.error': 'ERROR',
|
|
35
|
+
'st.stopped': 'STOPPED',
|
|
36
|
+
// wizard
|
|
37
|
+
'wiz.lang.title': 'Language / 语言 / Idioma / Langue',
|
|
38
|
+
'wiz.folder.title': 'Choose your working folder (your codebase)',
|
|
39
|
+
'wiz.folder.current': '(current folder)',
|
|
40
|
+
'wiz.folder.recent': '(recent)',
|
|
41
|
+
'wiz.folder.input': 'or type a path (e.g. ~/my-project)…',
|
|
42
|
+
'wiz.folder.footer': '↑/↓ select · Enter confirm · or type a path',
|
|
43
|
+
'wiz.folder.notFound': 'Folder not found: {path}',
|
|
44
|
+
'wiz.session.title': 'Resume a previous session?',
|
|
45
|
+
'wiz.session.new': 'New session',
|
|
46
|
+
'wiz.session.newHint': '(start fresh)',
|
|
47
|
+
'wiz.session.item': 'Session from {date}',
|
|
48
|
+
'wiz.provider.title': 'Set up your model provider (OpenAI-compatible)',
|
|
49
|
+
'wiz.provider.deepseekHint': '(preset — just add your API key)',
|
|
50
|
+
'wiz.provider.needsKey': 'API key required',
|
|
51
|
+
'wiz.provider.presetHint': '({url} · default model: {model})',
|
|
52
|
+
'wiz.provider.custom': 'Custom provider…',
|
|
53
|
+
'wiz.provider.customHint': '(any OpenAI-compatible endpoint)',
|
|
54
|
+
'wiz.provider.name.title': 'Provider name',
|
|
55
|
+
'wiz.provider.name.ph': 'e.g. openrouter, mistral, ollama…',
|
|
56
|
+
'wiz.provider.url.title': 'Base URL (OpenAI-compatible endpoint)',
|
|
57
|
+
'wiz.provider.url.ph': 'e.g. https://openrouter.ai/api/v1',
|
|
58
|
+
'wiz.provider.model.title': "Model name — exactly as written in the provider's documentation",
|
|
59
|
+
'wiz.provider.model.ph': 'e.g. deepseek-chat, gpt-4o-mini, qwen2.5-coder…',
|
|
60
|
+
'wiz.provider.key.title': 'API key for {name}',
|
|
61
|
+
'wiz.provider.key.footer': 'Type your key then Enter — stored in ~/.parallel/config.json',
|
|
62
|
+
'wiz.model.title': 'Default model for Parallel',
|
|
63
|
+
'wiz.model.provider': 'Provider: {name} ({url})',
|
|
64
|
+
'wiz.model.default': '(default)',
|
|
65
|
+
'wiz.model.custom': 'Other model…',
|
|
66
|
+
'wiz.model.customHint': '(type its name)',
|
|
67
|
+
'wiz.model.customTitle': 'Default model name (see provider documentation)',
|
|
68
|
+
'wiz.model.addProvider': 'Add / switch provider…',
|
|
69
|
+
'wiz.footer.select': '↑/↓ select · Enter confirm',
|
|
70
|
+
'wiz.footer.type': 'Type then Enter',
|
|
71
|
+
// main screen
|
|
72
|
+
'main.ready1': '⚡ Ready — folder: {folder}',
|
|
73
|
+
'main.ready2': 'Type a task + Enter to launch your first agent. /help for help.',
|
|
74
|
+
'main.empty': 'No agents yet. Type a task + Enter to launch your first agent — then launch more at any time, even while they work.',
|
|
75
|
+
'main.status': 'Enter = new agent N+1 (even while others work) · @Name = real-time instruction · /help · views: /agents /board /diff /notes',
|
|
76
|
+
'main.placeholder': 'Type a task (= new agent N+1) · @Agent message · /command',
|
|
77
|
+
'agent.summary': 'Summary',
|
|
78
|
+
// input
|
|
79
|
+
'input.atHint': ' — send a real-time instruction',
|
|
80
|
+
'input.atAll': ' to all agents',
|
|
81
|
+
'input.pasted': '[pasted #{n}: {lines} lines]',
|
|
82
|
+
'input.image': '[image #{n}]',
|
|
83
|
+
'input.attPaste': '📋 pasted #{n} · {lines} lines',
|
|
84
|
+
'input.attImage': '🖼 image #{n} · {file}',
|
|
85
|
+
'input.imageNone': 'No image in clipboard (requires xclip or wl-clipboard).',
|
|
86
|
+
'input.imageAdded': '🖼 Image attached from clipboard (Ctrl+V).',
|
|
87
|
+
'input.imageHint': 'Ctrl+V: paste an image (multimodal models)',
|
|
88
|
+
// approval
|
|
89
|
+
'appr.title': '⚠ APPROVAL REQUIRED',
|
|
90
|
+
'appr.pending': ' ({n} pending)',
|
|
91
|
+
'appr.wants': 'Agent {name} wants to run:',
|
|
92
|
+
'appr.keys': '[y] allow · [n] deny · [a] always allow this command (session)',
|
|
93
|
+
// views
|
|
94
|
+
'board.title': '▣ REAL-TIME COORDINATION',
|
|
95
|
+
'board.agents': 'Agents:',
|
|
96
|
+
'board.none': '(no agents)',
|
|
97
|
+
'board.activity': 'Who works where (file activity, no locks):',
|
|
98
|
+
'board.noActivity': '(no edits yet)',
|
|
99
|
+
'board.notes': 'Latest notes:',
|
|
100
|
+
'notes.title': '✉ INTER-AGENT NOTES (last 30)',
|
|
101
|
+
'notes.empty': 'No notes exchanged yet.',
|
|
102
|
+
'sessions.title': '📂 SAVED SESSIONS',
|
|
103
|
+
'sessions.empty': 'No saved sessions for this project yet.',
|
|
104
|
+
'sessions.item': '{date} · {agents} agent(s)',
|
|
105
|
+
'sessions.hint': 'Restore one with /session <n> or /session latest. New launches start fresh by default.',
|
|
106
|
+
'diff.title': '± LIVE DIFFS — {total} change(s) total (last 4 shown)',
|
|
107
|
+
'diff.empty': 'No file changes yet.',
|
|
108
|
+
'diff.by': '— by {agent} at {time}',
|
|
109
|
+
'diff.trunc': '… (diff truncated)',
|
|
110
|
+
'help.title': '⚡ PARALLEL — help',
|
|
111
|
+
'help.l1a': 'Type a task + Enter',
|
|
112
|
+
'help.l1b': ' → launches agent N+1 ',
|
|
113
|
+
'help.l1c': 'even while the others are working',
|
|
114
|
+
'help.l2a': '@Agent message',
|
|
115
|
+
'help.l2b': ' → real-time instruction to a running agent (',
|
|
116
|
+
'help.l2c': '@all',
|
|
117
|
+
'help.l2d': ' for everyone).',
|
|
118
|
+
'help.l3': "Agents see each other's statuses and diffs before every action: they co-edit the same files without blocking and without breaking each other's work.",
|
|
119
|
+
'help.states': 'States: 🔨 working · 👂 listening to other agents (double border) · 🧠 thinking · ✋ waiting for your approval · ⏹ stop. Sounds: 1 beep = agent launched/finished, 2 beeps = approval required (/sound off to mute).',
|
|
120
|
+
'help.keys': 'Esc: back to agents view · Tab: completion · ↑/↓: history · Ctrl+V: paste image',
|
|
121
|
+
// commands (descriptions)
|
|
122
|
+
'cmd.spawn': 'Launch agent N+1 (same as: type the task + Enter)',
|
|
123
|
+
'cmd.agents': 'Agents panel view (real time)',
|
|
124
|
+
'cmd.board': 'Coordination view: who works where, notes',
|
|
125
|
+
'cmd.notes': 'Inter-agent notes history',
|
|
126
|
+
'cmd.diff': 'Live file diffs',
|
|
127
|
+
'cmd.send': 'Instruction to an agent (same as: @Agent message)',
|
|
128
|
+
'cmd.pause': 'Pause',
|
|
129
|
+
'cmd.resume': 'Resume',
|
|
130
|
+
'cmd.stop': 'Stop',
|
|
131
|
+
'cmd.model': 'Show/change the session model ([provider:]model)',
|
|
132
|
+
'cmd.sessions': 'List saved sessions for this project',
|
|
133
|
+
'cmd.session': 'Restore a saved session by number, or latest',
|
|
134
|
+
'cmd.doctor': 'Check provider/model/API key configuration and repair hints',
|
|
135
|
+
'cmd.settings': 'Global settings — providers, API keys, language, defaults (persisted)',
|
|
136
|
+
'cmd.ssettings': 'Session settings — model, approvals, sound (this session only)',
|
|
137
|
+
'cmd.approvals': 'Shell command confirmation (this session)',
|
|
138
|
+
'cmd.sound': 'Sound cues (this session)',
|
|
139
|
+
'cmd.save': 'Save the session now (optionally with a name)',
|
|
140
|
+
'cmd.focus': 'Focus one agent: plain text goes to it, full-width panel',
|
|
141
|
+
'cmd.restore': 'Relaunch an agent from the restored session with its full conversation',
|
|
142
|
+
'cmd.key': 'Set the API key of the current provider',
|
|
143
|
+
'cmd.clear': 'Remove finished agents from the display',
|
|
144
|
+
'cmd.help': 'Show help',
|
|
145
|
+
'cmd.quit': 'Quit (saves session, stops agents)',
|
|
146
|
+
// command messages
|
|
147
|
+
'm.spawned': '⚡ Agent {name} launched in parallel{model}.',
|
|
148
|
+
'm.usageSpawn': 'Usage: /spawn [Name:] <task> [--model=m]',
|
|
149
|
+
'm.usageAt': 'Usage: @Agent <message> (or @all <message>)',
|
|
150
|
+
'm.broadcast': '✉ Instruction broadcast to all agents.',
|
|
151
|
+
'm.sent': '✉ Instruction sent to {target}.',
|
|
152
|
+
'm.notFound': 'Agent not found: {target} (agents: {list})',
|
|
153
|
+
'm.none': 'none',
|
|
154
|
+
'm.usageSend': 'Usage: /send <agent|all> <message>',
|
|
155
|
+
'm.usagePause': 'Usage: /pause <agent|all>',
|
|
156
|
+
'm.allPaused': '⏸ All agents paused.',
|
|
157
|
+
'm.paused': '⏸ {name} paused.',
|
|
158
|
+
'm.usageResume': 'Usage: /resume <agent|all>',
|
|
159
|
+
'm.allResumed': '▶ All agents resumed.',
|
|
160
|
+
'm.resumed': '▶ {name} resumed.',
|
|
161
|
+
'm.usageStop': 'Usage: /stop <agent|all>',
|
|
162
|
+
'm.allStopped': '⏹ All agents stopped.',
|
|
163
|
+
'm.stopped': '⏹ {name} stopped.',
|
|
164
|
+
'm.model': 'Session model: {pm} (change: /model [provider:]model · global defaults: /settings)',
|
|
165
|
+
'm.modelSet': 'Session model: {pm} (agents already running keep theirs)',
|
|
166
|
+
'm.noProvider': 'Unknown provider: {name} (configured: {list})',
|
|
167
|
+
'm.usageApprovals': 'Usage: /approvals <ask|auto>',
|
|
168
|
+
'm.approvals': 'Approval mode (session): {mode}',
|
|
169
|
+
'm.approvalsWarn': ' ⚠ shell commands now run without confirmation',
|
|
170
|
+
'm.sound': 'Sound cues (session): {state}',
|
|
171
|
+
'm.usageSound': 'Sound: {state} — usage: /sound <on|off>',
|
|
172
|
+
'm.saved': '💾 Session saved.',
|
|
173
|
+
'm.savedAs': '💾 Session saved as "{name}".',
|
|
174
|
+
'm.usageFocus': 'Usage: /focus <agent|off>',
|
|
175
|
+
'm.focusOn': '🎯 Focus on {name} — plain text goes to it. Esc or /focus off to exit.',
|
|
176
|
+
'm.focusOff': '🎯 Focus off.',
|
|
177
|
+
'm.focusHint': '🎯 focus {name} · type to talk to it · PgUp/PgDn scroll · Esc to exit',
|
|
178
|
+
'm.usageRestore': 'Usage: /restore <agent> (after loading a session via /session)',
|
|
179
|
+
'm.restored': '⏪ {name} relaunched with its previous conversation.',
|
|
180
|
+
'm.noConversation': 'No saved conversation for "{name}" in the restored session.',
|
|
181
|
+
'm.conflict': '⚠ {path}: repeated collisions between agents — consider arbitrating (@agent or /focus).',
|
|
182
|
+
'status.bar': '⚡ {agents} agent(s) · {active} active · {cost}',
|
|
183
|
+
'cmd.plan': 'plan-first agent: presents its plan, edits only after your approval',
|
|
184
|
+
'cmd.issue': 'spawn an agent on a GitHub issue (needs the gh CLI)',
|
|
185
|
+
'cmd.undo': "revert the agent's last file change",
|
|
186
|
+
'cmd.commit': 'git-commit the files touched by an agent (or all)',
|
|
187
|
+
'cmd.autocommit': 'auto-commit each agent’s files when it finishes',
|
|
188
|
+
'm.usagePlan': 'Usage: /plan [Name:] <task> — the agent presents its plan and waits for your approval before editing.',
|
|
189
|
+
'm.usageIssue': 'Usage: /issue <number> — spawns an agent on this GitHub issue (gh CLI required).',
|
|
190
|
+
'm.ghMissing': '✗ gh CLI not found. Install it (https://cli.github.com) then `gh auth login`.',
|
|
191
|
+
'm.issueFail': '✗ gh failed: {msg}',
|
|
192
|
+
'm.issueSpawned': '⚡ {name} spawned on issue #{n}: {title}',
|
|
193
|
+
'm.usageUndo': 'Usage: /undo <agent> — reverts that agent’s last file change.',
|
|
194
|
+
'm.undoNone': 'No change to revert for {name}.',
|
|
195
|
+
'm.undone': '↩ {name}: {path} restored to its previous content.',
|
|
196
|
+
'm.undoConflict': '⚠ A later change by another agent on the same file was wiped too — check it.',
|
|
197
|
+
'm.usageCommit': 'Usage: /commit <agent|all> [message]',
|
|
198
|
+
'm.committed': '✔ git commit: {files} file(s) from {name}.',
|
|
199
|
+
'm.commitNone': 'Nothing to commit for {name}.',
|
|
200
|
+
'm.commitFail': '✗ git commit failed: {msg}',
|
|
201
|
+
'm.usageAutocommit': 'Usage: /autocommit <on|off> (currently {state})',
|
|
202
|
+
'm.autocommit': '✔ autocommit {state} — each agent commits its files at task_complete.',
|
|
203
|
+
'cmd.attach': 'open a dedicated terminal for an agent (or toggle auto-open)',
|
|
204
|
+
'm.usageAttach': 'Usage: /attach <agent> opens its terminal · /attach <on|off> toggles auto-open (currently {state})',
|
|
205
|
+
'm.attachOpened': '⧉ Dedicated terminal opened for {name}.',
|
|
206
|
+
'm.attachManual': '⧉ Could not open a terminal here — run in another terminal: {cmd}',
|
|
207
|
+
'm.attachAuto': '⧉ Terminal auto-open {state}.',
|
|
208
|
+
'attach.banner': 'AGENT TERMINAL',
|
|
209
|
+
'attach.placeholder': 'Message to {agent} (Enter to send, /quit to detach)…',
|
|
210
|
+
'attach.waiting': 'Waiting for agent {agent}… (is the main Parallel session running?)',
|
|
211
|
+
'attach.gone': 'Session ended — this terminal is detached.',
|
|
212
|
+
'attach.hint': '⇄ /spawn <task> = NEW agent (own terminal) · plain text steers this agent · /quit detaches',
|
|
213
|
+
'grid.above': '▲ {n} agent(s) above — PgUp',
|
|
214
|
+
'grid.below': '▼ {n} agent(s) below — PgDn',
|
|
215
|
+
'm.nothing': 'Nothing to save yet.',
|
|
216
|
+
'm.usageKey': 'Usage: /key <API key>',
|
|
217
|
+
'm.keySaved': 'API key saved for provider {name} (~/.parallel/config.json)',
|
|
218
|
+
'm.cleared': 'Finished agents removed from display.',
|
|
219
|
+
'm.unknown': 'Unknown command: {cmd} — type /help',
|
|
220
|
+
'm.imagesIgnored': 'Note: attached images are only supported when launching a new agent.',
|
|
221
|
+
'm.sessionRestored': '📂 Session from {date} restored.',
|
|
222
|
+
'm.usageSession': 'Usage: /sessions to list, then /session <n> or /session latest',
|
|
223
|
+
'm.sessionLoaded': '📂 Session from {date} loaded.',
|
|
224
|
+
'm.missingProvider': 'No provider configured. Open /settings → Add a provider, or restart with a first-run config.',
|
|
225
|
+
'm.missingKey': 'Provider {name} has no API key. Use /key <API key> or /settings → API key.',
|
|
226
|
+
'm.missingModel': 'Provider {name} has no default model. Use /settings → Provider models.',
|
|
227
|
+
'm.doctorOk': '✓ Configuration ready: {pm}. Changes: /settings · temporary model: /model [provider:]model',
|
|
228
|
+
'm.spawnFail': 'Cannot launch the agent: no usable provider/model. Configure one via /settings.',
|
|
229
|
+
// settings panels
|
|
230
|
+
'set.title': '⚙ SETTINGS — global (persisted in ~/.parallel/config.json)',
|
|
231
|
+
'sset.title': '⚙ SESSION SETTINGS — this session only (globals: /settings)',
|
|
232
|
+
'set.language': 'Language: {lang}',
|
|
233
|
+
'set.defaultPM': 'Default provider & model: {pm}',
|
|
234
|
+
'set.key': 'API key · {name}: {masked}',
|
|
235
|
+
'set.addProvider': 'Add a provider…',
|
|
236
|
+
'set.models': 'Provider models (add names / choose default)…',
|
|
237
|
+
'set.modelsFor': 'Models for {name} — select one to make it the global default, or type a new model name',
|
|
238
|
+
'set.makeDefault': 'make default',
|
|
239
|
+
'set.addModelName': 'model name exactly as written in the provider docs',
|
|
240
|
+
'set.approvals': 'Default approval mode: {mode}',
|
|
241
|
+
'set.sound': 'Default sound: {state}',
|
|
242
|
+
'set.back': '← Back',
|
|
243
|
+
'set.saved': '✓ Saved to ~/.parallel/config.json',
|
|
244
|
+
'set.chooseProvider': 'Choose a provider',
|
|
245
|
+
'set.chooseModel': 'Model ({name}) — pick or type a name from the provider docs',
|
|
246
|
+
'sset.model': 'Session model: {pm}',
|
|
247
|
+
'sset.approvals': 'Approvals (session): {mode}',
|
|
248
|
+
'sset.sound': 'Sound (session): {state}',
|
|
249
|
+
'set.esc': 'Esc: close',
|
|
250
|
+
// agent questions (auto-run)
|
|
251
|
+
'q.title': '❓ AGENT QUESTION',
|
|
252
|
+
'q.pending': ' ({n} pending)',
|
|
253
|
+
'q.from': 'Agent {name} asks:',
|
|
254
|
+
'q.autorun': '⏱ auto-run in {s}s',
|
|
255
|
+
'q.paused': '⏸ countdown paused (you are typing)',
|
|
256
|
+
'q.recommended': '★ recommended',
|
|
257
|
+
'q.keys': '↑/↓ + Enter or 1-4 to answer · no answer in 30s → the recommended option is chosen',
|
|
258
|
+
// cost view
|
|
259
|
+
'cost.title': '💰 SESSION COST — real time, per agent',
|
|
260
|
+
'cost.empty': 'No agents yet — costs will appear here in real time.',
|
|
261
|
+
'cost.unknown': '(unknown price — set it in /settings → Model prices)',
|
|
262
|
+
'cost.total': 'Session total:',
|
|
263
|
+
'cost.partial': '(partial — some models have no known price)',
|
|
264
|
+
'cost.hint': 'Prices in USD. Override per model: /settings → Model prices. Restored sessions keep their cost history.',
|
|
265
|
+
// skills / specialists views
|
|
266
|
+
'skills.title': '🧩 SKILLS — reusable instructions agents can load',
|
|
267
|
+
'skills.empty': 'No skills yet. Create one: /skill new <name> [global], then edit the .md file.',
|
|
268
|
+
'skills.hint1': 'Files: ~/.parallel/skills/*.md (global) · <project>/.parallel/skills/*.md (project).',
|
|
269
|
+
'skills.hint2': 'Force a skill on a task: "fix the tests #review" or let agents auto-load relevant ones.',
|
|
270
|
+
'spec.title': '🎓 SPECIALISTS — personas with a role and optional pinned model',
|
|
271
|
+
'spec.empty': 'No specialists yet. Create one: /specialist new <name> [global], then edit the .md file.',
|
|
272
|
+
'spec.hint1': 'Files: ~/.parallel/specialists/*.md (global) · <project>/.parallel/specialists/*.md (project).',
|
|
273
|
+
'spec.hint2': 'Launch: /specialist <name> <task> — the role is added to the agent system prompt.',
|
|
274
|
+
// new commands
|
|
275
|
+
'cmd.specialist': 'Launch an agent as a specialist, or create one (new <name>)',
|
|
276
|
+
'cmd.specialists': 'List the configured specialists',
|
|
277
|
+
'cmd.skill': 'Create a skill template (.md to edit)',
|
|
278
|
+
'cmd.skills': 'List the available skills',
|
|
279
|
+
'cmd.cost': 'Financial view: real-time cost per agent + session total',
|
|
280
|
+
// new messages
|
|
281
|
+
'm.qAnswered': '❓ You answered {name}: "{answer}"',
|
|
282
|
+
'm.qAuto': '⏱ Auto-run: "{answer}" chosen for {name} (no answer within 30s)',
|
|
283
|
+
'm.costHistory': '💰 Cost history of the restored session — total {total}:',
|
|
284
|
+
'm.noSpecialist': 'Unknown specialist: {name}',
|
|
285
|
+
'm.usageSkill': 'Usage: /skill new <name> [global] — then edit the created .md file',
|
|
286
|
+
'm.skillCreated': '🧩 Skill created: {file} — edit this file to define it.',
|
|
287
|
+
'm.specCreated': '🎓 Specialist created: {file} — edit this file to define the role.',
|
|
288
|
+
'm.alreadyExists': 'Already exists: {msg}',
|
|
289
|
+
'm.usageSpecialist': 'Usage: /specialist <name> <task> · /specialist new <name> [global]',
|
|
290
|
+
// settings additions
|
|
291
|
+
'set.prices': 'Model prices (USD per 1M tokens, overrides)…',
|
|
292
|
+
'set.newSkill': 'Create a skill (global)…',
|
|
293
|
+
'set.newSpecialist': 'Create a specialist (global)…',
|
|
294
|
+
'set.priceModel': 'Pick the model to price ({name}) — or type a name',
|
|
295
|
+
'set.priceUnknown': 'no known price',
|
|
296
|
+
'set.priceValue': 'Price of {model} in USD per 1M tokens: "input, output" (e.g. 0.27, 1.10)',
|
|
297
|
+
'set.priceBad': 'Invalid format — expected: input, output (e.g. 0.27, 1.10)',
|
|
298
|
+
'set.newSkillName': 'Skill name (a .md template will be created in ~/.parallel/skills)',
|
|
299
|
+
'set.newSpecialistName': 'Specialist name (a .md template will be created in ~/.parallel/specialists)',
|
|
300
|
+
};
|
|
301
|
+
const fr = {
|
|
302
|
+
tagline: 'Des agents de code en parallèle, en temps réel — sans verrous, sans attente.',
|
|
303
|
+
'st.idle': 'INACTIF',
|
|
304
|
+
'st.thinking': 'RÉFLÉCHIT',
|
|
305
|
+
'st.listening': 'ÉCOUTE LES AGENTS',
|
|
306
|
+
'st.working': 'TRAVAILLE',
|
|
307
|
+
'st.waiting': 'ATTEND TON OK',
|
|
308
|
+
'st.paused': 'PAUSE',
|
|
309
|
+
'st.done': 'TERMINÉ',
|
|
310
|
+
'st.error': 'ERREUR',
|
|
311
|
+
'st.stopped': 'STOP',
|
|
312
|
+
'wiz.lang.title': 'Language / 语言 / Idioma / Langue',
|
|
313
|
+
'wiz.folder.title': 'Choisis le dossier de travail (ton codebase)',
|
|
314
|
+
'wiz.folder.current': '(dossier courant)',
|
|
315
|
+
'wiz.folder.recent': '(récent)',
|
|
316
|
+
'wiz.folder.input': 'ou tape un chemin (ex : ~/mon-projet)…',
|
|
317
|
+
'wiz.folder.footer': '↑/↓ choisir · Entrée valider · ou tape un chemin',
|
|
318
|
+
'wiz.folder.notFound': 'Dossier introuvable : {path}',
|
|
319
|
+
'wiz.session.title': 'Reprendre une session précédente ?',
|
|
320
|
+
'wiz.session.new': 'Nouvelle session',
|
|
321
|
+
'wiz.session.newHint': '(repartir de zéro)',
|
|
322
|
+
'wiz.session.item': 'Session du {date}',
|
|
323
|
+
'wiz.provider.title': 'Configure ton provider de modèles (OpenAI-compatible)',
|
|
324
|
+
'wiz.provider.deepseekHint': '(préréglé — ajoute juste ta clef API)',
|
|
325
|
+
'wiz.provider.needsKey': 'clef API requise',
|
|
326
|
+
'wiz.provider.presetHint': '({url} · modèle par défaut : {model})',
|
|
327
|
+
'wiz.provider.custom': 'Provider personnalisé…',
|
|
328
|
+
'wiz.provider.customHint': '(tout endpoint OpenAI-compatible)',
|
|
329
|
+
'wiz.provider.name.title': 'Nom du provider',
|
|
330
|
+
'wiz.provider.name.ph': 'ex : openrouter, mistral, ollama…',
|
|
331
|
+
'wiz.provider.url.title': 'URL de base (endpoint OpenAI-compatible)',
|
|
332
|
+
'wiz.provider.url.ph': 'ex : https://openrouter.ai/api/v1',
|
|
333
|
+
'wiz.provider.model.title': 'Nom du modèle — exactement comme dans la documentation du provider',
|
|
334
|
+
'wiz.provider.model.ph': 'ex : deepseek-chat, gpt-4o-mini, qwen2.5-coder…',
|
|
335
|
+
'wiz.provider.key.title': 'Clef API pour {name}',
|
|
336
|
+
'wiz.provider.key.footer': 'Tape ta clef puis Entrée — stockée dans ~/.parallel/config.json',
|
|
337
|
+
'wiz.model.title': 'Modèle par défaut de Parallel',
|
|
338
|
+
'wiz.model.provider': 'Provider : {name} ({url})',
|
|
339
|
+
'wiz.model.default': '(par défaut)',
|
|
340
|
+
'wiz.model.custom': 'Autre modèle…',
|
|
341
|
+
'wiz.model.customHint': '(tape son nom)',
|
|
342
|
+
'wiz.model.customTitle': 'Nom du modèle par défaut (voir la documentation du provider)',
|
|
343
|
+
'wiz.model.addProvider': 'Ajouter / changer de provider…',
|
|
344
|
+
'wiz.footer.select': '↑/↓ choisir · Entrée valider',
|
|
345
|
+
'wiz.footer.type': 'Tape puis Entrée',
|
|
346
|
+
'main.ready1': '⚡ Prêt — dossier : {folder}',
|
|
347
|
+
'main.ready2': "Tape une tâche + Entrée pour lancer ton premier agent. /help pour l'aide.",
|
|
348
|
+
'main.empty': "Aucun agent pour le moment. Tape une tâche + Entrée pour lancer ton premier agent — puis relances-en d'autres à tout moment, même pendant qu'ils travaillent.",
|
|
349
|
+
'main.status': 'Entrée = nouvel agent N+1 (même pendant que les autres travaillent) · @Nom = instruction temps réel · /help · vues : /agents /board /diff /notes',
|
|
350
|
+
'main.placeholder': 'Tape une tâche (= nouvel agent N+1) · @Agent message · /commande',
|
|
351
|
+
'agent.summary': 'Récapitulatif',
|
|
352
|
+
'input.atHint': ' — envoyer une instruction temps réel',
|
|
353
|
+
'input.atAll': ' à tous les agents',
|
|
354
|
+
'input.pasted': '[collé #{n} : {lines} lignes]',
|
|
355
|
+
'input.image': '[image #{n}]',
|
|
356
|
+
'input.attPaste': '📋 collé #{n} · {lines} lignes',
|
|
357
|
+
'input.attImage': '🖼 image #{n} · {file}',
|
|
358
|
+
'input.imageNone': "Aucune image dans le presse-papiers (nécessite xclip ou wl-clipboard).",
|
|
359
|
+
'input.imageAdded': '🖼 Image attachée depuis le presse-papiers (Ctrl+V).',
|
|
360
|
+
'input.imageHint': 'Ctrl+V : coller une image (modèles multimodaux)',
|
|
361
|
+
'appr.title': '⚠ APPROBATION REQUISE',
|
|
362
|
+
'appr.pending': ' ({n} en attente)',
|
|
363
|
+
'appr.wants': "L'agent {name} veut exécuter :",
|
|
364
|
+
'appr.keys': '[y] autoriser · [n] refuser · [a] toujours autoriser cette commande (session)',
|
|
365
|
+
'board.title': '▣ COORDINATION TEMPS RÉEL',
|
|
366
|
+
'board.agents': 'Agents :',
|
|
367
|
+
'board.none': '(aucun agent)',
|
|
368
|
+
'board.activity': 'Qui travaille où (activité fichiers, sans verrou) :',
|
|
369
|
+
'board.noActivity': '(aucune modification pour le moment)',
|
|
370
|
+
'board.notes': 'Dernières notes :',
|
|
371
|
+
'notes.title': '✉ NOTES INTER-AGENTS (30 dernières)',
|
|
372
|
+
'notes.empty': 'Aucune note échangée pour le moment.',
|
|
373
|
+
'sessions.title': '📂 SESSIONS SAUVEGARDÉES',
|
|
374
|
+
'sessions.empty': 'Aucune session sauvegardée pour ce projet.',
|
|
375
|
+
'sessions.item': '{date} · {agents} agent(s)',
|
|
376
|
+
'sessions.hint': 'Restaure avec /session <n> ou /session latest. Les nouveaux lancements démarrent vierges par défaut.',
|
|
377
|
+
'diff.title': '± DIFFS EN DIRECT — {total} modification(s) au total (4 dernières affichées)',
|
|
378
|
+
'diff.empty': 'Aucune modification de fichier pour le moment.',
|
|
379
|
+
'diff.by': '— par {agent} à {time}',
|
|
380
|
+
'diff.trunc': '… (diff tronqué)',
|
|
381
|
+
'help.title': '⚡ PARALLEL — aide',
|
|
382
|
+
'help.l1a': 'Tape une tâche + Entrée',
|
|
383
|
+
'help.l1b': " → lance l'agent N+1 ",
|
|
384
|
+
'help.l1c': 'même pendant que les autres travaillent',
|
|
385
|
+
'help.l2a': '@Agent message',
|
|
386
|
+
'help.l2b': ' → instruction temps réel à un agent en cours (',
|
|
387
|
+
'help.l2c': '@all',
|
|
388
|
+
'help.l2d': ' pour tous).',
|
|
389
|
+
'help.l3': 'Les agents voient mutuellement leurs statuts et leurs diffs avant chaque action : ils co-éditent les mêmes fichiers sans se bloquer et sans casser le travail des autres.',
|
|
390
|
+
'help.states': "États : 🔨 travaille · 👂 écoute les autres agents (double bordure) · 🧠 réfléchit · ✋ attend ton approbation · ⏹ stop. Sons : 1 bip = agent lancé/terminé, 2 bips = approbation requise (/sound off pour couper).",
|
|
391
|
+
'help.keys': 'Esc : revenir à la vue agents · Tab : complétion · ↑/↓ : historique · Ctrl+V : coller une image',
|
|
392
|
+
'cmd.spawn': "Lancer l'agent N+1 (équivalent : taper la tâche + Entrée)",
|
|
393
|
+
'cmd.agents': 'Vue panneaux agents (temps réel)',
|
|
394
|
+
'cmd.board': 'Vue coordination : qui travaille où, notes',
|
|
395
|
+
'cmd.notes': 'Historique des notes inter-agents',
|
|
396
|
+
'cmd.diff': 'Modifications de fichiers (diffs en direct)',
|
|
397
|
+
'cmd.send': 'Instruction à un agent (équivalent : @Agent message)',
|
|
398
|
+
'cmd.pause': 'Mettre en pause',
|
|
399
|
+
'cmd.resume': 'Reprendre',
|
|
400
|
+
'cmd.stop': 'Arrêter',
|
|
401
|
+
'cmd.model': 'Afficher/changer le modèle de la session ([provider:]modèle)',
|
|
402
|
+
'cmd.sessions': 'Lister les sessions sauvegardées de ce projet',
|
|
403
|
+
'cmd.session': 'Restaurer une session sauvegardée par numéro, ou latest',
|
|
404
|
+
'cmd.doctor': 'Vérifier provider/modèle/clef API et afficher les corrections',
|
|
405
|
+
'cmd.settings': 'Réglages globaux — providers, clefs API, langue, défauts (persistés)',
|
|
406
|
+
'cmd.ssettings': 'Réglages de session — modèle, approbations, son (cette session)',
|
|
407
|
+
'cmd.approvals': 'Confirmation des commandes shell (cette session)',
|
|
408
|
+
'cmd.sound': 'Repères sonores (cette session)',
|
|
409
|
+
'cmd.save': 'Sauvegarder la session maintenant (avec un nom optionnel)',
|
|
410
|
+
'cmd.focus': 'Met le focus sur un agent : le texte simple lui est envoyé, panneau pleine largeur',
|
|
411
|
+
'cmd.restore': 'Relance un agent de la session restaurée avec toute sa conversation',
|
|
412
|
+
'cmd.key': 'Définir la clef API du provider courant',
|
|
413
|
+
'cmd.clear': "Retirer les agents terminés de l'affichage",
|
|
414
|
+
'cmd.help': "Afficher l'aide",
|
|
415
|
+
'cmd.quit': 'Quitter (sauvegarde la session, arrête les agents)',
|
|
416
|
+
'm.spawned': '⚡ Agent {name} lancé en parallèle{model}.',
|
|
417
|
+
'm.usageSpawn': 'Usage : /spawn [Nom:] <tâche> [--model=m]',
|
|
418
|
+
'm.usageAt': 'Usage : @Agent <message> (ou @all <message>)',
|
|
419
|
+
'm.broadcast': '✉ Instruction diffusée à tous les agents.',
|
|
420
|
+
'm.sent': '✉ Instruction envoyée à {target}.',
|
|
421
|
+
'm.notFound': 'Agent introuvable : {target} (agents : {list})',
|
|
422
|
+
'm.none': 'aucun',
|
|
423
|
+
'm.usageSend': 'Usage : /send <agent|all> <message>',
|
|
424
|
+
'm.usagePause': 'Usage : /pause <agent|all>',
|
|
425
|
+
'm.allPaused': '⏸ Tous les agents en pause.',
|
|
426
|
+
'm.paused': '⏸ {name} en pause.',
|
|
427
|
+
'm.usageResume': 'Usage : /resume <agent|all>',
|
|
428
|
+
'm.allResumed': '▶ Tous les agents repris.',
|
|
429
|
+
'm.resumed': '▶ {name} repris.',
|
|
430
|
+
'm.usageStop': 'Usage : /stop <agent|all>',
|
|
431
|
+
'm.allStopped': '⏹ Tous les agents arrêtés.',
|
|
432
|
+
'm.stopped': '⏹ {name} arrêté.',
|
|
433
|
+
'm.model': 'Modèle de session : {pm} (changer : /model [provider:]modèle · défauts globaux : /settings)',
|
|
434
|
+
'm.modelSet': 'Modèle de session : {pm} (les agents déjà lancés gardent le leur)',
|
|
435
|
+
'm.noProvider': 'Provider inconnu : {name} (configurés : {list})',
|
|
436
|
+
'm.usageApprovals': 'Usage : /approvals <ask|auto>',
|
|
437
|
+
'm.approvals': 'Mode approbation (session) : {mode}',
|
|
438
|
+
'm.approvalsWarn': ' ⚠ les commandes shell s’exécutent désormais sans confirmation',
|
|
439
|
+
'm.sound': 'Repères sonores (session) : {state}',
|
|
440
|
+
'm.usageSound': 'Son : {state} — usage : /sound <on|off>',
|
|
441
|
+
'm.saved': '💾 Session sauvegardée.',
|
|
442
|
+
'm.savedAs': '💾 Session sauvegardée sous "{name}".',
|
|
443
|
+
'm.usageFocus': 'Usage : /focus <agent|off>',
|
|
444
|
+
'm.focusOn': '🎯 Focus sur {name} — le texte simple lui est envoyé. Échap ou /focus off pour sortir.',
|
|
445
|
+
'm.focusOff': '🎯 Focus désactivé.',
|
|
446
|
+
'm.focusHint': '🎯 focus {name} · tapez pour lui parler · PgUp/PgDn défilement · Échap pour sortir',
|
|
447
|
+
'm.usageRestore': 'Usage : /restore <agent> (après avoir chargé une session via /session)',
|
|
448
|
+
'm.restored': '⏪ {name} relancé avec sa conversation précédente.',
|
|
449
|
+
'm.noConversation': 'Aucune conversation sauvegardée pour « {name} » dans la session restaurée.',
|
|
450
|
+
'm.conflict': '⚠ {path} : collisions répétées entre agents — pensez à arbitrer (@agent ou /focus).',
|
|
451
|
+
'status.bar': '⚡ {agents} agent(s) · {active} actif(s) · {cost}',
|
|
452
|
+
'cmd.plan': "agent plan-d'abord : présente son plan, ne modifie qu'après votre accord",
|
|
453
|
+
'cmd.issue': 'lance un agent sur une issue GitHub (CLI gh requise)',
|
|
454
|
+
'cmd.undo': "annule la dernière modification de fichier de l'agent",
|
|
455
|
+
'cmd.commit': 'git-commit des fichiers touchés par un agent (ou tous)',
|
|
456
|
+
'cmd.autocommit': 'commit auto des fichiers de chaque agent quand il termine',
|
|
457
|
+
'm.usagePlan': "Usage : /plan [Nom:] <tâche> — l'agent présente son plan et attend votre accord avant de modifier.",
|
|
458
|
+
'm.usageIssue': 'Usage : /issue <numéro> — lance un agent sur cette issue GitHub (CLI gh requise).',
|
|
459
|
+
'm.ghMissing': '✗ CLI gh introuvable. Installez-la (https://cli.github.com) puis `gh auth login`.',
|
|
460
|
+
'm.issueFail': '✗ gh a échoué : {msg}',
|
|
461
|
+
'm.issueSpawned': '⚡ {name} lancé sur l’issue #{n} : {title}',
|
|
462
|
+
'm.usageUndo': "Usage : /undo <agent> — annule la dernière modification de fichier de cet agent.",
|
|
463
|
+
'm.undoNone': 'Aucune modification à annuler pour {name}.',
|
|
464
|
+
'm.undone': '↩ {name} : {path} restauré à son contenu précédent.',
|
|
465
|
+
'm.undoConflict': '⚠ Une modification plus récente d’un autre agent sur ce fichier a aussi été effacée — vérifiez.',
|
|
466
|
+
'm.usageCommit': 'Usage : /commit <agent|all> [message]',
|
|
467
|
+
'm.committed': '✔ git commit : {files} fichier(s) de {name}.',
|
|
468
|
+
'm.commitNone': 'Rien à committer pour {name}.',
|
|
469
|
+
'm.commitFail': '✗ git commit a échoué : {msg}',
|
|
470
|
+
'm.usageAutocommit': 'Usage : /autocommit <on|off> (actuellement {state})',
|
|
471
|
+
'm.autocommit': '✔ autocommit {state} — chaque agent committe ses fichiers à task_complete.',
|
|
472
|
+
'cmd.attach': 'ouvrir un terminal dédié pour un agent (ou activer/désactiver l’auto-ouverture)',
|
|
473
|
+
'm.usageAttach': 'Usage : /attach <agent> ouvre son terminal · /attach <on|off> règle l’auto-ouverture (actuellement {state})',
|
|
474
|
+
'm.attachOpened': '⧉ Terminal dédié ouvert pour {name}.',
|
|
475
|
+
'm.attachManual': '⧉ Impossible d’ouvrir un terminal ici — lancez dans un autre terminal : {cmd}',
|
|
476
|
+
'm.attachAuto': '⧉ Auto-ouverture des terminaux : {state}.',
|
|
477
|
+
'attach.banner': 'TERMINAL AGENT',
|
|
478
|
+
'attach.placeholder': 'Message à {agent} (Entrée pour envoyer, /quit pour détacher)…',
|
|
479
|
+
'attach.waiting': 'En attente de l’agent {agent}… (la session Parallel principale tourne-t-elle ?)',
|
|
480
|
+
'attach.gone': 'Session terminée — ce terminal est détaché.',
|
|
481
|
+
'attach.hint': '⇄ /spawn <tâche> = NOUVEL agent (son propre terminal) · texte libre pilote cet agent · /quit détache',
|
|
482
|
+
'grid.above': '▲ {n} agent(s) au-dessus — PgUp',
|
|
483
|
+
'grid.below': '▼ {n} agent(s) en dessous — PgDn',
|
|
484
|
+
'm.nothing': 'Rien à sauvegarder pour le moment.',
|
|
485
|
+
'm.usageKey': 'Usage : /key <clef API>',
|
|
486
|
+
'm.keySaved': 'Clef API enregistrée pour le provider {name} (~/.parallel/config.json)',
|
|
487
|
+
'm.cleared': "Agents terminés retirés de l'affichage.",
|
|
488
|
+
'm.unknown': 'Commande inconnue : {cmd} — tape /help',
|
|
489
|
+
'm.imagesIgnored': "Note : les images jointes ne sont prises en compte qu'au lancement d'un nouvel agent.",
|
|
490
|
+
'm.sessionRestored': '📂 Session du {date} restaurée.',
|
|
491
|
+
'm.usageSession': 'Usage : /sessions pour lister, puis /session <n> ou /session latest',
|
|
492
|
+
'm.sessionLoaded': '📂 Session du {date} chargée.',
|
|
493
|
+
'm.missingProvider': 'Aucun provider configuré. Ouvre /settings → Ajouter un provider, ou relance une première config.',
|
|
494
|
+
'm.missingKey': 'Le provider {name} n’a pas de clef API. Utilise /key <clef API> ou /settings → Clef API.',
|
|
495
|
+
'm.missingModel': 'Le provider {name} n’a pas de modèle par défaut. Utilise /settings → Modèles du provider.',
|
|
496
|
+
'm.doctorOk': '✓ Configuration prête : {pm}. Changements : /settings · modèle temporaire : /model [provider:]modèle',
|
|
497
|
+
'm.spawnFail': "Impossible de lancer l'agent : aucun provider/modèle utilisable. Configure-en un via /settings.",
|
|
498
|
+
'set.title': '⚙ RÉGLAGES — globaux (persistés dans ~/.parallel/config.json)',
|
|
499
|
+
'sset.title': '⚙ RÉGLAGES DE SESSION — cette session uniquement (globaux : /settings)',
|
|
500
|
+
'set.language': 'Langue : {lang}',
|
|
501
|
+
'set.defaultPM': 'Provider & modèle par défaut : {pm}',
|
|
502
|
+
'set.key': 'Clef API · {name} : {masked}',
|
|
503
|
+
'set.addProvider': 'Ajouter un provider…',
|
|
504
|
+
'set.models': 'Modèles du provider (ajouter / choisir le défaut)…',
|
|
505
|
+
'set.modelsFor': 'Modèles de {name} — sélectionne pour mettre en défaut global, ou tape un nouveau nom',
|
|
506
|
+
'set.makeDefault': 'mettre par défaut',
|
|
507
|
+
'set.addModelName': 'nom du modèle exactement comme dans la doc du provider',
|
|
508
|
+
'set.approvals': 'Mode approbation par défaut : {mode}',
|
|
509
|
+
'set.sound': 'Son par défaut : {state}',
|
|
510
|
+
'set.back': '← Retour',
|
|
511
|
+
'set.saved': '✓ Enregistré dans ~/.parallel/config.json',
|
|
512
|
+
'set.chooseProvider': 'Choisis un provider',
|
|
513
|
+
'set.chooseModel': 'Modèle ({name}) — choisis ou tape un nom selon la doc du provider',
|
|
514
|
+
'sset.model': 'Modèle de session : {pm}',
|
|
515
|
+
'sset.approvals': 'Approbations (session) : {mode}',
|
|
516
|
+
'sset.sound': 'Son (session) : {state}',
|
|
517
|
+
'set.esc': 'Esc : fermer',
|
|
518
|
+
'q.title': '❓ QUESTION D’UN AGENT',
|
|
519
|
+
'q.pending': ' ({n} en attente)',
|
|
520
|
+
'q.from': "L'agent {name} demande :",
|
|
521
|
+
'q.autorun': '⏱ auto-run dans {s}s',
|
|
522
|
+
'q.paused': '⏸ compte à rebours en pause (tu tapes)',
|
|
523
|
+
'q.recommended': '★ recommandé',
|
|
524
|
+
'q.keys': '↑/↓ + Entrée ou 1-4 pour répondre · sans réponse en 30s → l’option recommandée est choisie',
|
|
525
|
+
'cost.title': '💰 COÛT DE LA SESSION — temps réel, par agent',
|
|
526
|
+
'cost.empty': 'Aucun agent pour le moment — les coûts apparaîtront ici en temps réel.',
|
|
527
|
+
'cost.unknown': '(prix inconnu — règle-le dans /settings → Prix des modèles)',
|
|
528
|
+
'cost.total': 'Total session :',
|
|
529
|
+
'cost.partial': '(partiel — certains modèles n’ont pas de prix connu)',
|
|
530
|
+
'cost.hint': 'Prix en USD. Override par modèle : /settings → Prix des modèles. Les sessions restaurées gardent leur historique de coût.',
|
|
531
|
+
'skills.title': '🧩 SKILLS — instructions réutilisables que les agents peuvent charger',
|
|
532
|
+
'skills.empty': 'Aucun skill. Crée-en un : /skill new <nom> [global], puis édite le fichier .md.',
|
|
533
|
+
'skills.hint1': 'Fichiers : ~/.parallel/skills/*.md (global) · <projet>/.parallel/skills/*.md (projet).',
|
|
534
|
+
'skills.hint2': 'Forcer un skill sur une tâche : "corrige les tests #review" — ou laisse les agents charger les pertinents.',
|
|
535
|
+
'spec.title': '🎓 SPÉCIALISTES — personas avec un rôle et un modèle épinglé optionnel',
|
|
536
|
+
'spec.empty': 'Aucun spécialiste. Crée-en un : /specialist new <nom> [global], puis édite le fichier .md.',
|
|
537
|
+
'spec.hint1': 'Fichiers : ~/.parallel/specialists/*.md (global) · <projet>/.parallel/specialists/*.md (projet).',
|
|
538
|
+
'spec.hint2': 'Lancer : /specialist <nom> <tâche> — le rôle est ajouté au prompt système de l’agent.',
|
|
539
|
+
'cmd.specialist': 'Lancer un agent en tant que spécialiste, ou en créer un (new <nom>)',
|
|
540
|
+
'cmd.specialists': 'Lister les spécialistes configurés',
|
|
541
|
+
'cmd.skill': 'Créer un modèle de skill (.md à éditer)',
|
|
542
|
+
'cmd.skills': 'Lister les skills disponibles',
|
|
543
|
+
'cmd.cost': 'Vue financière : coût temps réel par agent + total de session',
|
|
544
|
+
'm.qAnswered': '❓ Tu as répondu à {name} : « {answer} »',
|
|
545
|
+
'm.qAuto': '⏱ Auto-run : « {answer} » choisi pour {name} (pas de réponse en 30s)',
|
|
546
|
+
'm.costHistory': '💰 Historique des coûts de la session restaurée — total {total} :',
|
|
547
|
+
'm.noSpecialist': 'Spécialiste inconnu : {name}',
|
|
548
|
+
'm.usageSkill': 'Usage : /skill new <nom> [global] — puis édite le fichier .md créé',
|
|
549
|
+
'm.skillCreated': '🧩 Skill créé : {file} — édite ce fichier pour le définir.',
|
|
550
|
+
'm.specCreated': '🎓 Spécialiste créé : {file} — édite ce fichier pour définir le rôle.',
|
|
551
|
+
'm.alreadyExists': 'Existe déjà : {msg}',
|
|
552
|
+
'm.usageSpecialist': 'Usage : /specialist <nom> <tâche> · /specialist new <nom> [global]',
|
|
553
|
+
'set.prices': 'Prix des modèles (USD par 1M tokens, overrides)…',
|
|
554
|
+
'set.newSkill': 'Créer un skill (global)…',
|
|
555
|
+
'set.newSpecialist': 'Créer un spécialiste (global)…',
|
|
556
|
+
'set.priceModel': 'Choisis le modèle à tarifer ({name}) — ou tape un nom',
|
|
557
|
+
'set.priceUnknown': 'pas de prix connu',
|
|
558
|
+
'set.priceValue': 'Prix de {model} en USD par 1M tokens : « input, output » (ex : 0.27, 1.10)',
|
|
559
|
+
'set.priceBad': 'Format invalide — attendu : input, output (ex : 0.27, 1.10)',
|
|
560
|
+
'set.newSkillName': 'Nom du skill (un modèle .md sera créé dans ~/.parallel/skills)',
|
|
561
|
+
'set.newSpecialistName': 'Nom du spécialiste (un modèle .md sera créé dans ~/.parallel/specialists)',
|
|
562
|
+
};
|
|
563
|
+
const es = {
|
|
564
|
+
tagline: 'Agentes de código en paralelo, en tiempo real — sin bloqueos, sin esperas.',
|
|
565
|
+
'st.idle': 'INACTIVO',
|
|
566
|
+
'st.thinking': 'PENSANDO',
|
|
567
|
+
'st.listening': 'ESCUCHA A LOS AGENTES',
|
|
568
|
+
'st.working': 'TRABAJANDO',
|
|
569
|
+
'st.waiting': 'ESPERA TU OK',
|
|
570
|
+
'st.paused': 'PAUSA',
|
|
571
|
+
'st.done': 'TERMINADO',
|
|
572
|
+
'st.error': 'ERROR',
|
|
573
|
+
'st.stopped': 'DETENIDO',
|
|
574
|
+
'wiz.lang.title': 'Language / 语言 / Idioma / Langue',
|
|
575
|
+
'wiz.folder.title': 'Elige tu carpeta de trabajo (tu código)',
|
|
576
|
+
'wiz.folder.current': '(carpeta actual)',
|
|
577
|
+
'wiz.folder.recent': '(reciente)',
|
|
578
|
+
'wiz.folder.input': 'o escribe una ruta (ej.: ~/mi-proyecto)…',
|
|
579
|
+
'wiz.folder.footer': '↑/↓ elegir · Enter confirmar · o escribe una ruta',
|
|
580
|
+
'wiz.folder.notFound': 'Carpeta no encontrada: {path}',
|
|
581
|
+
'wiz.session.title': '¿Reanudar una sesión anterior?',
|
|
582
|
+
'wiz.session.new': 'Nueva sesión',
|
|
583
|
+
'wiz.session.newHint': '(empezar de cero)',
|
|
584
|
+
'wiz.session.item': 'Sesión del {date}',
|
|
585
|
+
'wiz.provider.title': 'Configura tu proveedor de modelos (compatible con OpenAI)',
|
|
586
|
+
'wiz.provider.deepseekHint': '(preconfigurado — solo añade tu clave API)',
|
|
587
|
+
'wiz.provider.needsKey': 'requiere clave API',
|
|
588
|
+
'wiz.provider.presetHint': '({url} · modelo por defecto: {model})',
|
|
589
|
+
'wiz.provider.custom': 'Proveedor personalizado…',
|
|
590
|
+
'wiz.provider.customHint': '(cualquier endpoint compatible con OpenAI)',
|
|
591
|
+
'wiz.provider.name.title': 'Nombre del proveedor',
|
|
592
|
+
'wiz.provider.name.ph': 'ej.: openrouter, mistral, ollama…',
|
|
593
|
+
'wiz.provider.url.title': 'URL base (endpoint compatible con OpenAI)',
|
|
594
|
+
'wiz.provider.url.ph': 'ej.: https://openrouter.ai/api/v1',
|
|
595
|
+
'wiz.provider.model.title': 'Nombre del modelo — exactamente como en la documentación del proveedor',
|
|
596
|
+
'wiz.provider.model.ph': 'ej.: deepseek-chat, gpt-4o-mini, qwen2.5-coder…',
|
|
597
|
+
'wiz.provider.key.title': 'Clave API para {name}',
|
|
598
|
+
'wiz.provider.key.footer': 'Escribe tu clave y Enter — se guarda en ~/.parallel/config.json',
|
|
599
|
+
'wiz.model.title': 'Modelo por defecto de Parallel',
|
|
600
|
+
'wiz.model.provider': 'Proveedor: {name} ({url})',
|
|
601
|
+
'wiz.model.default': '(por defecto)',
|
|
602
|
+
'wiz.model.custom': 'Otro modelo…',
|
|
603
|
+
'wiz.model.customHint': '(escribe su nombre)',
|
|
604
|
+
'wiz.model.customTitle': 'Nombre del modelo por defecto (ver documentación del proveedor)',
|
|
605
|
+
'wiz.model.addProvider': 'Añadir / cambiar proveedor…',
|
|
606
|
+
'wiz.footer.select': '↑/↓ elegir · Enter confirmar',
|
|
607
|
+
'wiz.footer.type': 'Escribe y Enter',
|
|
608
|
+
'main.ready1': '⚡ Listo — carpeta: {folder}',
|
|
609
|
+
'main.ready2': 'Escribe una tarea + Enter para lanzar tu primer agente. /help para ayuda.',
|
|
610
|
+
'main.empty': 'Aún no hay agentes. Escribe una tarea + Enter para lanzar tu primer agente — luego lanza más en cualquier momento, incluso mientras trabajan.',
|
|
611
|
+
'main.status': 'Enter = nuevo agente N+1 (incluso mientras otros trabajan) · @Nombre = instrucción en tiempo real · /help · vistas: /agents /board /diff /notes',
|
|
612
|
+
'main.placeholder': 'Escribe una tarea (= nuevo agente N+1) · @Agente mensaje · /comando',
|
|
613
|
+
'agent.summary': 'Resumen',
|
|
614
|
+
'input.atHint': ' — enviar una instrucción en tiempo real',
|
|
615
|
+
'input.atAll': ' a todos los agentes',
|
|
616
|
+
'input.pasted': '[pegado #{n}: {lines} líneas]',
|
|
617
|
+
'input.image': '[imagen #{n}]',
|
|
618
|
+
'input.attPaste': '📋 pegado #{n} · {lines} líneas',
|
|
619
|
+
'input.attImage': '🖼 imagen #{n} · {file}',
|
|
620
|
+
'input.imageNone': 'No hay imagen en el portapapeles (requiere xclip o wl-clipboard).',
|
|
621
|
+
'input.imageAdded': '🖼 Imagen adjuntada desde el portapapeles (Ctrl+V).',
|
|
622
|
+
'input.imageHint': 'Ctrl+V: pegar una imagen (modelos multimodales)',
|
|
623
|
+
'appr.title': '⚠ APROBACIÓN REQUERIDA',
|
|
624
|
+
'appr.pending': ' ({n} pendientes)',
|
|
625
|
+
'appr.wants': 'El agente {name} quiere ejecutar:',
|
|
626
|
+
'appr.keys': '[y] permitir · [n] denegar · [a] permitir siempre este comando (sesión)',
|
|
627
|
+
'board.title': '▣ COORDINACIÓN EN TIEMPO REAL',
|
|
628
|
+
'board.agents': 'Agentes:',
|
|
629
|
+
'board.none': '(sin agentes)',
|
|
630
|
+
'board.activity': 'Quién trabaja dónde (actividad de archivos, sin bloqueos):',
|
|
631
|
+
'board.noActivity': '(sin modificaciones por ahora)',
|
|
632
|
+
'board.notes': 'Últimas notas:',
|
|
633
|
+
'notes.title': '✉ NOTAS ENTRE AGENTES (últimas 30)',
|
|
634
|
+
'notes.empty': 'Aún no se han intercambiado notas.',
|
|
635
|
+
'sessions.title': '📂 SESIONES GUARDADAS',
|
|
636
|
+
'sessions.empty': 'Aún no hay sesiones guardadas para este proyecto.',
|
|
637
|
+
'sessions.item': '{date} · {agents} agente(s)',
|
|
638
|
+
'sessions.hint': 'Restaura una con /session <n> o /session latest. Los nuevos lanzamientos empiezan vacíos por defecto.',
|
|
639
|
+
'diff.title': '± DIFFS EN VIVO — {total} cambio(s) en total (últimos 4 mostrados)',
|
|
640
|
+
'diff.empty': 'Sin cambios de archivos por ahora.',
|
|
641
|
+
'diff.by': '— por {agent} a las {time}',
|
|
642
|
+
'diff.trunc': '… (diff truncado)',
|
|
643
|
+
'help.title': '⚡ PARALLEL — ayuda',
|
|
644
|
+
'help.l1a': 'Escribe una tarea + Enter',
|
|
645
|
+
'help.l1b': ' → lanza el agente N+1 ',
|
|
646
|
+
'help.l1c': 'incluso mientras los demás trabajan',
|
|
647
|
+
'help.l2a': '@Agente mensaje',
|
|
648
|
+
'help.l2b': ' → instrucción en tiempo real a un agente activo (',
|
|
649
|
+
'help.l2c': '@all',
|
|
650
|
+
'help.l2d': ' para todos).',
|
|
651
|
+
'help.l3': 'Los agentes ven los estados y diffs de los demás antes de cada acción: co-editan los mismos archivos sin bloquearse y sin romper el trabajo ajeno.',
|
|
652
|
+
'help.states': 'Estados: 🔨 trabajando · 👂 escuchando a otros agentes (borde doble) · 🧠 pensando · ✋ esperando tu aprobación · ⏹ stop. Sonidos: 1 bip = agente lanzado/terminado, 2 bips = aprobación requerida (/sound off para silenciar).',
|
|
653
|
+
'help.keys': 'Esc: volver a la vista de agentes · Tab: autocompletar · ↑/↓: historial · Ctrl+V: pegar imagen',
|
|
654
|
+
'cmd.spawn': 'Lanzar el agente N+1 (igual que: escribir la tarea + Enter)',
|
|
655
|
+
'cmd.agents': 'Vista de paneles de agentes (tiempo real)',
|
|
656
|
+
'cmd.board': 'Vista de coordinación: quién trabaja dónde, notas',
|
|
657
|
+
'cmd.notes': 'Historial de notas entre agentes',
|
|
658
|
+
'cmd.diff': 'Diffs de archivos en vivo',
|
|
659
|
+
'cmd.send': 'Instrucción a un agente (igual que: @Agente mensaje)',
|
|
660
|
+
'cmd.pause': 'Pausar',
|
|
661
|
+
'cmd.resume': 'Reanudar',
|
|
662
|
+
'cmd.stop': 'Detener',
|
|
663
|
+
'cmd.model': 'Mostrar/cambiar el modelo de la sesión ([proveedor:]modelo)',
|
|
664
|
+
'cmd.sessions': 'Listar las sesiones guardadas de este proyecto',
|
|
665
|
+
'cmd.session': 'Restaurar una sesión guardada por número, o latest',
|
|
666
|
+
'cmd.doctor': 'Comprobar proveedor/modelo/clave API y mostrar correcciones',
|
|
667
|
+
'cmd.settings': 'Ajustes globales — proveedores, claves API, idioma, valores por defecto (persistentes)',
|
|
668
|
+
'cmd.ssettings': 'Ajustes de sesión — modelo, aprobaciones, sonido (solo esta sesión)',
|
|
669
|
+
'cmd.approvals': 'Confirmación de comandos shell (esta sesión)',
|
|
670
|
+
'cmd.sound': 'Señales sonoras (esta sesión)',
|
|
671
|
+
'cmd.save': 'Guardar la sesión ahora (con un nombre opcional)',
|
|
672
|
+
'cmd.focus': 'Enfoca un agente: el texto simple se le envía, panel a ancho completo',
|
|
673
|
+
'cmd.restore': 'Relanza un agente de la sesión restaurada con toda su conversación',
|
|
674
|
+
'cmd.key': 'Definir la clave API del proveedor actual',
|
|
675
|
+
'cmd.clear': 'Quitar de la pantalla los agentes terminados',
|
|
676
|
+
'cmd.help': 'Mostrar la ayuda',
|
|
677
|
+
'cmd.quit': 'Salir (guarda la sesión, detiene los agentes)',
|
|
678
|
+
'm.spawned': '⚡ Agente {name} lanzado en paralelo{model}.',
|
|
679
|
+
'm.usageSpawn': 'Uso: /spawn [Nombre:] <tarea> [--model=m]',
|
|
680
|
+
'm.usageAt': 'Uso: @Agente <mensaje> (o @all <mensaje>)',
|
|
681
|
+
'm.broadcast': '✉ Instrucción difundida a todos los agentes.',
|
|
682
|
+
'm.sent': '✉ Instrucción enviada a {target}.',
|
|
683
|
+
'm.notFound': 'Agente no encontrado: {target} (agentes: {list})',
|
|
684
|
+
'm.none': 'ninguno',
|
|
685
|
+
'm.usageSend': 'Uso: /send <agente|all> <mensaje>',
|
|
686
|
+
'm.usagePause': 'Uso: /pause <agente|all>',
|
|
687
|
+
'm.allPaused': '⏸ Todos los agentes en pausa.',
|
|
688
|
+
'm.paused': '⏸ {name} en pausa.',
|
|
689
|
+
'm.usageResume': 'Uso: /resume <agente|all>',
|
|
690
|
+
'm.allResumed': '▶ Todos los agentes reanudados.',
|
|
691
|
+
'm.resumed': '▶ {name} reanudado.',
|
|
692
|
+
'm.usageStop': 'Uso: /stop <agente|all>',
|
|
693
|
+
'm.allStopped': '⏹ Todos los agentes detenidos.',
|
|
694
|
+
'm.stopped': '⏹ {name} detenido.',
|
|
695
|
+
'm.model': 'Modelo de sesión: {pm} (cambiar: /model [proveedor:]modelo · valores globales: /settings)',
|
|
696
|
+
'm.modelSet': 'Modelo de sesión: {pm} (los agentes ya lanzados conservan el suyo)',
|
|
697
|
+
'm.noProvider': 'Proveedor desconocido: {name} (configurados: {list})',
|
|
698
|
+
'm.usageApprovals': 'Uso: /approvals <ask|auto>',
|
|
699
|
+
'm.approvals': 'Modo de aprobación (sesión): {mode}',
|
|
700
|
+
'm.approvalsWarn': ' ⚠ los comandos shell se ejecutan ahora sin confirmación',
|
|
701
|
+
'm.sound': 'Señales sonoras (sesión): {state}',
|
|
702
|
+
'm.usageSound': 'Sonido: {state} — uso: /sound <on|off>',
|
|
703
|
+
'm.saved': '💾 Sesión guardada.',
|
|
704
|
+
'm.savedAs': '💾 Sesión guardada como "{name}".',
|
|
705
|
+
'm.usageFocus': 'Uso: /focus <agente|off>',
|
|
706
|
+
'm.focusOn': '🎯 Foco en {name} — el texto simple se le envía. Esc o /focus off para salir.',
|
|
707
|
+
'm.focusOff': '🎯 Foco desactivado.',
|
|
708
|
+
'm.focusHint': '🎯 foco {name} · escribe para hablarle · PgUp/PgDn desplazamiento · Esc para salir',
|
|
709
|
+
'm.usageRestore': 'Uso: /restore <agente> (tras cargar una sesión con /session)',
|
|
710
|
+
'm.restored': '⏪ {name} relanzado con su conversación anterior.',
|
|
711
|
+
'm.noConversation': 'No hay conversación guardada para "{name}" en la sesión restaurada.',
|
|
712
|
+
'm.conflict': '⚠ {path}: colisiones repetidas entre agentes — considera arbitrar (@agente o /focus).',
|
|
713
|
+
'status.bar': '⚡ {agents} agente(s) · {active} activo(s) · {cost}',
|
|
714
|
+
'cmd.plan': 'agente plan-primero: presenta su plan, solo edita tras tu aprobación',
|
|
715
|
+
'cmd.issue': 'lanza un agente sobre una issue de GitHub (requiere la CLI gh)',
|
|
716
|
+
'cmd.undo': 'revierte el último cambio de archivo del agente',
|
|
717
|
+
'cmd.commit': 'git-commit de los archivos tocados por un agente (o todos)',
|
|
718
|
+
'cmd.autocommit': 'commit automático de los archivos de cada agente al terminar',
|
|
719
|
+
'm.usagePlan': 'Uso: /plan [Nombre:] <tarea> — el agente presenta su plan y espera tu aprobación antes de editar.',
|
|
720
|
+
'm.usageIssue': 'Uso: /issue <número> — lanza un agente sobre esa issue de GitHub (requiere la CLI gh).',
|
|
721
|
+
'm.ghMissing': '✗ CLI gh no encontrada. Instálala (https://cli.github.com) y ejecuta `gh auth login`.',
|
|
722
|
+
'm.issueFail': '✗ gh falló: {msg}',
|
|
723
|
+
'm.issueSpawned': '⚡ {name} lanzado sobre la issue #{n}: {title}',
|
|
724
|
+
'm.usageUndo': 'Uso: /undo <agente> — revierte el último cambio de archivo de ese agente.',
|
|
725
|
+
'm.undoNone': 'Nada que revertir para {name}.',
|
|
726
|
+
'm.undone': '↩ {name}: {path} restaurado a su contenido anterior.',
|
|
727
|
+
'm.undoConflict': '⚠ También se borró un cambio posterior de otro agente en ese archivo — revísalo.',
|
|
728
|
+
'm.usageCommit': 'Uso: /commit <agente|all> [mensaje]',
|
|
729
|
+
'm.committed': '✔ git commit: {files} archivo(s) de {name}.',
|
|
730
|
+
'm.commitNone': 'Nada que commitear para {name}.',
|
|
731
|
+
'm.commitFail': '✗ git commit falló: {msg}',
|
|
732
|
+
'm.usageAutocommit': 'Uso: /autocommit <on|off> (actualmente {state})',
|
|
733
|
+
'm.autocommit': '✔ autocommit {state} — cada agente commitea sus archivos al terminar.',
|
|
734
|
+
'cmd.attach': 'abrir una terminal dedicada para un agente (o alternar la auto-apertura)',
|
|
735
|
+
'm.usageAttach': 'Uso: /attach <agente> abre su terminal · /attach <on|off> alterna la auto-apertura (actualmente {state})',
|
|
736
|
+
'm.attachOpened': '⧉ Terminal dedicada abierta para {name}.',
|
|
737
|
+
'm.attachManual': '⧉ No se pudo abrir una terminal aquí — ejecuta en otra terminal: {cmd}',
|
|
738
|
+
'm.attachAuto': '⧉ Auto-apertura de terminales: {state}.',
|
|
739
|
+
'attach.banner': 'TERMINAL DEL AGENTE',
|
|
740
|
+
'attach.placeholder': 'Mensaje a {agent} (Enter para enviar, /quit para desconectar)…',
|
|
741
|
+
'attach.waiting': 'Esperando al agente {agent}… (¿está corriendo la sesión principal de Parallel?)',
|
|
742
|
+
'attach.gone': 'Sesión terminada — esta terminal está desconectada.',
|
|
743
|
+
'attach.hint': '⇄ /spawn <tarea> = agente NUEVO (su propia terminal) · texto libre dirige a este agente · /quit desconecta',
|
|
744
|
+
'grid.above': '▲ {n} agente(s) arriba — PgUp',
|
|
745
|
+
'grid.below': '▼ {n} agente(s) abajo — PgDn',
|
|
746
|
+
'm.nothing': 'Nada que guardar por ahora.',
|
|
747
|
+
'm.usageKey': 'Uso: /key <clave API>',
|
|
748
|
+
'm.keySaved': 'Clave API guardada para el proveedor {name} (~/.parallel/config.json)',
|
|
749
|
+
'm.cleared': 'Agentes terminados quitados de la pantalla.',
|
|
750
|
+
'm.unknown': 'Comando desconocido: {cmd} — escribe /help',
|
|
751
|
+
'm.imagesIgnored': 'Nota: las imágenes adjuntas solo se tienen en cuenta al lanzar un agente nuevo.',
|
|
752
|
+
'm.sessionRestored': '📂 Sesión del {date} restaurada.',
|
|
753
|
+
'm.usageSession': 'Uso: /sessions para listar, luego /session <n> o /session latest',
|
|
754
|
+
'm.sessionLoaded': '📂 Sesión del {date} cargada.',
|
|
755
|
+
'm.missingProvider': 'No hay proveedor configurado. Abre /settings → Añadir proveedor, o reinicia con configuración inicial.',
|
|
756
|
+
'm.missingKey': 'El proveedor {name} no tiene clave API. Usa /key <clave API> o /settings → Clave API.',
|
|
757
|
+
'm.missingModel': 'El proveedor {name} no tiene modelo por defecto. Usa /settings → Modelos del proveedor.',
|
|
758
|
+
'm.doctorOk': '✓ Configuración lista: {pm}. Cambios: /settings · modelo temporal: /model [proveedor:]modelo',
|
|
759
|
+
'm.spawnFail': 'No se puede lanzar el agente: ningún provider/modelo utilizable. Configura uno con /settings.',
|
|
760
|
+
'set.title': '⚙ AJUSTES — globales (persistentes en ~/.parallel/config.json)',
|
|
761
|
+
'sset.title': '⚙ AJUSTES DE SESIÓN — solo esta sesión (globales: /settings)',
|
|
762
|
+
'set.language': 'Idioma: {lang}',
|
|
763
|
+
'set.defaultPM': 'Proveedor y modelo por defecto: {pm}',
|
|
764
|
+
'set.key': 'Clave API · {name}: {masked}',
|
|
765
|
+
'set.addProvider': 'Añadir un proveedor…',
|
|
766
|
+
'set.models': 'Modelos del proveedor (añadir / elegir defecto)…',
|
|
767
|
+
'set.modelsFor': 'Modelos de {name} — selecciona uno como defecto global, o escribe un nombre nuevo',
|
|
768
|
+
'set.makeDefault': 'hacer predeterminado',
|
|
769
|
+
'set.addModelName': 'nombre del modelo exactamente como en la doc del proveedor',
|
|
770
|
+
'set.approvals': 'Modo de aprobación por defecto: {mode}',
|
|
771
|
+
'set.sound': 'Sonido por defecto: {state}',
|
|
772
|
+
'set.back': '← Volver',
|
|
773
|
+
'set.saved': '✓ Guardado en ~/.parallel/config.json',
|
|
774
|
+
'set.chooseProvider': 'Elige un proveedor',
|
|
775
|
+
'set.chooseModel': 'Modelo ({name}) — elige o escribe un nombre según la doc del proveedor',
|
|
776
|
+
'sset.model': 'Modelo de sesión: {pm}',
|
|
777
|
+
'sset.approvals': 'Aprobaciones (sesión): {mode}',
|
|
778
|
+
'sset.sound': 'Sonido (sesión): {state}',
|
|
779
|
+
'set.esc': 'Esc: cerrar',
|
|
780
|
+
'q.title': '❓ PREGUNTA DE UN AGENTE',
|
|
781
|
+
'q.pending': ' ({n} pendientes)',
|
|
782
|
+
'q.from': 'El agente {name} pregunta:',
|
|
783
|
+
'q.autorun': '⏱ auto-run en {s}s',
|
|
784
|
+
'q.paused': '⏸ cuenta atrás en pausa (estás escribiendo)',
|
|
785
|
+
'q.recommended': '★ recomendado',
|
|
786
|
+
'q.keys': '↑/↓ + Enter o 1-4 para responder · sin respuesta en 30s → se elige la opción recomendada',
|
|
787
|
+
'cost.title': '💰 COSTE DE LA SESIÓN — tiempo real, por agente',
|
|
788
|
+
'cost.empty': 'Aún no hay agentes — los costes aparecerán aquí en tiempo real.',
|
|
789
|
+
'cost.unknown': '(precio desconocido — defínelo en /settings → Precios de modelos)',
|
|
790
|
+
'cost.total': 'Total de la sesión:',
|
|
791
|
+
'cost.partial': '(parcial — algunos modelos no tienen precio conocido)',
|
|
792
|
+
'cost.hint': 'Precios en USD. Override por modelo: /settings → Precios de modelos. Las sesiones restauradas conservan su historial de costes.',
|
|
793
|
+
'skills.title': '🧩 SKILLS — instrucciones reutilizables que los agentes pueden cargar',
|
|
794
|
+
'skills.empty': 'Sin skills. Crea uno: /skill new <nombre> [global], luego edita el archivo .md.',
|
|
795
|
+
'skills.hint1': 'Archivos: ~/.parallel/skills/*.md (global) · <proyecto>/.parallel/skills/*.md (proyecto).',
|
|
796
|
+
'skills.hint2': 'Forzar un skill en una tarea: "arregla los tests #review" — o deja que los agentes carguen los relevantes.',
|
|
797
|
+
'spec.title': '🎓 ESPECIALISTAS — personas con un rol y un modelo fijado opcional',
|
|
798
|
+
'spec.empty': 'Sin especialistas. Crea uno: /specialist new <nombre> [global], luego edita el archivo .md.',
|
|
799
|
+
'spec.hint1': 'Archivos: ~/.parallel/specialists/*.md (global) · <proyecto>/.parallel/specialists/*.md (proyecto).',
|
|
800
|
+
'spec.hint2': 'Lanzar: /specialist <nombre> <tarea> — el rol se añade al prompt de sistema del agente.',
|
|
801
|
+
'cmd.specialist': 'Lanzar un agente como especialista, o crear uno (new <nombre>)',
|
|
802
|
+
'cmd.specialists': 'Listar los especialistas configurados',
|
|
803
|
+
'cmd.skill': 'Crear una plantilla de skill (.md a editar)',
|
|
804
|
+
'cmd.skills': 'Listar los skills disponibles',
|
|
805
|
+
'cmd.cost': 'Vista financiera: coste en tiempo real por agente + total de sesión',
|
|
806
|
+
'm.qAnswered': '❓ Respondiste a {name}: «{answer}»',
|
|
807
|
+
'm.qAuto': '⏱ Auto-run: «{answer}» elegido para {name} (sin respuesta en 30s)',
|
|
808
|
+
'm.costHistory': '💰 Historial de costes de la sesión restaurada — total {total}:',
|
|
809
|
+
'm.noSpecialist': 'Especialista desconocido: {name}',
|
|
810
|
+
'm.usageSkill': 'Uso: /skill new <nombre> [global] — luego edita el archivo .md creado',
|
|
811
|
+
'm.skillCreated': '🧩 Skill creado: {file} — edita este archivo para definirlo.',
|
|
812
|
+
'm.specCreated': '🎓 Especialista creado: {file} — edita este archivo para definir el rol.',
|
|
813
|
+
'm.alreadyExists': 'Ya existe: {msg}',
|
|
814
|
+
'm.usageSpecialist': 'Uso: /specialist <nombre> <tarea> · /specialist new <nombre> [global]',
|
|
815
|
+
'set.prices': 'Precios de modelos (USD por 1M tokens, overrides)…',
|
|
816
|
+
'set.newSkill': 'Crear un skill (global)…',
|
|
817
|
+
'set.newSpecialist': 'Crear un especialista (global)…',
|
|
818
|
+
'set.priceModel': 'Elige el modelo a tarifar ({name}) — o escribe un nombre',
|
|
819
|
+
'set.priceUnknown': 'sin precio conocido',
|
|
820
|
+
'set.priceValue': 'Precio de {model} en USD por 1M tokens: «input, output» (ej.: 0.27, 1.10)',
|
|
821
|
+
'set.priceBad': 'Formato inválido — esperado: input, output (ej.: 0.27, 1.10)',
|
|
822
|
+
'set.newSkillName': 'Nombre del skill (se creará una plantilla .md en ~/.parallel/skills)',
|
|
823
|
+
'set.newSpecialistName': 'Nombre del especialista (se creará una plantilla .md en ~/.parallel/specialists)',
|
|
824
|
+
};
|
|
825
|
+
const zh = {
|
|
826
|
+
tagline: '并行实时代码智能体 — 无锁定,无等待。',
|
|
827
|
+
'st.idle': '空闲',
|
|
828
|
+
'st.thinking': '思考中',
|
|
829
|
+
'st.listening': '正在倾听其他智能体',
|
|
830
|
+
'st.working': '工作中',
|
|
831
|
+
'st.waiting': '等待你的确认',
|
|
832
|
+
'st.paused': '已暂停',
|
|
833
|
+
'st.done': '已完成',
|
|
834
|
+
'st.error': '错误',
|
|
835
|
+
'st.stopped': '已停止',
|
|
836
|
+
'wiz.lang.title': 'Language / 语言 / Idioma / Langue',
|
|
837
|
+
'wiz.folder.title': '选择工作文件夹(你的代码库)',
|
|
838
|
+
'wiz.folder.current': '(当前文件夹)',
|
|
839
|
+
'wiz.folder.recent': '(最近)',
|
|
840
|
+
'wiz.folder.input': '或输入路径(例如 ~/my-project)…',
|
|
841
|
+
'wiz.folder.footer': '↑/↓ 选择 · 回车确认 · 或输入路径',
|
|
842
|
+
'wiz.folder.notFound': '找不到文件夹:{path}',
|
|
843
|
+
'wiz.session.title': '恢复上一个会话?',
|
|
844
|
+
'wiz.session.new': '新建会话',
|
|
845
|
+
'wiz.session.newHint': '(从零开始)',
|
|
846
|
+
'wiz.session.item': '{date} 的会话',
|
|
847
|
+
'wiz.provider.title': '配置你的模型提供商(OpenAI 兼容)',
|
|
848
|
+
'wiz.provider.deepseekHint': '(预设 — 只需填入你的 API 密钥)',
|
|
849
|
+
'wiz.provider.needsKey': '需要 API 密钥',
|
|
850
|
+
'wiz.provider.presetHint': '({url} · 默认模型:{model})',
|
|
851
|
+
'wiz.provider.custom': '自定义提供商…',
|
|
852
|
+
'wiz.provider.customHint': '(任何 OpenAI 兼容端点)',
|
|
853
|
+
'wiz.provider.name.title': '提供商名称',
|
|
854
|
+
'wiz.provider.name.ph': '例如 openrouter、mistral、ollama…',
|
|
855
|
+
'wiz.provider.url.title': '基础 URL(OpenAI 兼容端点)',
|
|
856
|
+
'wiz.provider.url.ph': '例如 https://openrouter.ai/api/v1',
|
|
857
|
+
'wiz.provider.model.title': '模型名称 — 与提供商文档中的写法完全一致',
|
|
858
|
+
'wiz.provider.model.ph': '例如 deepseek-chat、gpt-4o-mini、qwen2.5-coder…',
|
|
859
|
+
'wiz.provider.key.title': '{name} 的 API 密钥',
|
|
860
|
+
'wiz.provider.key.footer': '输入密钥后回车 — 保存在 ~/.parallel/config.json',
|
|
861
|
+
'wiz.model.title': 'Parallel 默认模型',
|
|
862
|
+
'wiz.model.provider': '提供商:{name}({url})',
|
|
863
|
+
'wiz.model.default': '(默认)',
|
|
864
|
+
'wiz.model.custom': '其他模型…',
|
|
865
|
+
'wiz.model.customHint': '(输入其名称)',
|
|
866
|
+
'wiz.model.customTitle': '默认模型名称(参见提供商文档)',
|
|
867
|
+
'wiz.model.addProvider': '添加 / 切换提供商…',
|
|
868
|
+
'wiz.footer.select': '↑/↓ 选择 · 回车确认',
|
|
869
|
+
'wiz.footer.type': '输入后回车',
|
|
870
|
+
'main.ready1': '⚡ 就绪 — 文件夹:{folder}',
|
|
871
|
+
'main.ready2': '输入任务 + 回车即可启动第一个智能体。/help 查看帮助。',
|
|
872
|
+
'main.empty': '尚无智能体。输入任务 + 回车启动第一个 — 之后可随时启动更多,即使它们正在工作。',
|
|
873
|
+
'main.status': '回车 = 新智能体 N+1(即使其他智能体正在工作)· @名称 = 实时指令 · /help · 视图:/agents /board /diff /notes',
|
|
874
|
+
'main.placeholder': '输入任务(= 新智能体 N+1)· @智能体 消息 · /命令',
|
|
875
|
+
'agent.summary': '摘要',
|
|
876
|
+
'input.atHint': ' — 发送实时指令',
|
|
877
|
+
'input.atAll': ' 给所有智能体',
|
|
878
|
+
'input.pasted': '[粘贴 #{n}:{lines} 行]',
|
|
879
|
+
'input.image': '[图片 #{n}]',
|
|
880
|
+
'input.attPaste': '📋 粘贴 #{n} · {lines} 行',
|
|
881
|
+
'input.attImage': '🖼 图片 #{n} · {file}',
|
|
882
|
+
'input.imageNone': '剪贴板中没有图片(需要 xclip 或 wl-clipboard)。',
|
|
883
|
+
'input.imageAdded': '🖼 已从剪贴板附加图片(Ctrl+V)。',
|
|
884
|
+
'input.imageHint': 'Ctrl+V:粘贴图片(多模态模型)',
|
|
885
|
+
'appr.title': '⚠ 需要批准',
|
|
886
|
+
'appr.pending': '({n} 个待处理)',
|
|
887
|
+
'appr.wants': '智能体 {name} 想要执行:',
|
|
888
|
+
'appr.keys': '[y] 允许 · [n] 拒绝 · [a] 本会话始终允许此命令',
|
|
889
|
+
'board.title': '▣ 实时协调',
|
|
890
|
+
'board.agents': '智能体:',
|
|
891
|
+
'board.none': '(无智能体)',
|
|
892
|
+
'board.activity': '谁在哪里工作(文件活动,无锁定):',
|
|
893
|
+
'board.noActivity': '(暂无修改)',
|
|
894
|
+
'board.notes': '最新便签:',
|
|
895
|
+
'notes.title': '✉ 智能体间便签(最近 30 条)',
|
|
896
|
+
'notes.empty': '尚未交换任何便签。',
|
|
897
|
+
'sessions.title': '📂 已保存会话',
|
|
898
|
+
'sessions.empty': '此项目暂无已保存会话。',
|
|
899
|
+
'sessions.item': '{date} · {agents} 个智能体',
|
|
900
|
+
'sessions.hint': '用 /session <n> 或 /session latest 恢复。新的启动默认从空会话开始。',
|
|
901
|
+
'diff.title': '± 实时差异 — 共 {total} 处修改(显示最近 4 处)',
|
|
902
|
+
'diff.empty': '暂无文件修改。',
|
|
903
|
+
'diff.by': '— 由 {agent} 于 {time}',
|
|
904
|
+
'diff.trunc': '…(差异已截断)',
|
|
905
|
+
'help.title': '⚡ PARALLEL — 帮助',
|
|
906
|
+
'help.l1a': '输入任务 + 回车',
|
|
907
|
+
'help.l1b': ' → 启动智能体 N+1,',
|
|
908
|
+
'help.l1c': '即使其他智能体正在工作',
|
|
909
|
+
'help.l2a': '@智能体 消息',
|
|
910
|
+
'help.l2b': ' → 向运行中的智能体发送实时指令(',
|
|
911
|
+
'help.l2c': '@all',
|
|
912
|
+
'help.l2d': ' 发给所有)。',
|
|
913
|
+
'help.l3': '每次行动前,智能体都能看到彼此的状态和差异:它们共同编辑同一批文件,互不阻塞,也不破坏彼此的工作。',
|
|
914
|
+
'help.states': '状态:🔨 工作中 · 👂 倾听其他智能体(双边框)· 🧠 思考中 · ✋ 等待你的批准 · ⏹ 停止。声音:1 声 = 智能体启动/完成,2 声 = 需要批准(/sound off 静音)。',
|
|
915
|
+
'help.keys': 'Esc:返回智能体视图 · Tab:补全 · ↑/↓:历史 · Ctrl+V:粘贴图片',
|
|
916
|
+
'cmd.spawn': '启动智能体 N+1(等同于:输入任务 + 回车)',
|
|
917
|
+
'cmd.agents': '智能体面板视图(实时)',
|
|
918
|
+
'cmd.board': '协调视图:谁在哪里工作、便签',
|
|
919
|
+
'cmd.notes': '智能体间便签历史',
|
|
920
|
+
'cmd.diff': '实时文件差异',
|
|
921
|
+
'cmd.send': '向某个智能体发指令(等同于:@智能体 消息)',
|
|
922
|
+
'cmd.pause': '暂停',
|
|
923
|
+
'cmd.resume': '恢复',
|
|
924
|
+
'cmd.stop': '停止',
|
|
925
|
+
'cmd.model': '显示/更改会话模型([提供商:]模型)',
|
|
926
|
+
'cmd.sessions': '列出此项目的已保存会话',
|
|
927
|
+
'cmd.session': '按编号或 latest 恢复已保存会话',
|
|
928
|
+
'cmd.doctor': '检查提供商/模型/API 密钥配置并显示修复提示',
|
|
929
|
+
'cmd.settings': '全局设置 — 提供商、API 密钥、语言、默认值(持久化)',
|
|
930
|
+
'cmd.ssettings': '会话设置 — 模型、批准、声音(仅本会话)',
|
|
931
|
+
'cmd.approvals': 'Shell 命令确认(本会话)',
|
|
932
|
+
'cmd.sound': '声音提示(本会话)',
|
|
933
|
+
'cmd.save': '立即保存会话(可附加名称)',
|
|
934
|
+
'cmd.focus': '聚焦某个代理:普通文本直接发给它,面板全宽显示',
|
|
935
|
+
'cmd.restore': '从恢复的会话中重启代理,并保留其完整对话',
|
|
936
|
+
'cmd.key': '设置当前提供商的 API 密钥',
|
|
937
|
+
'cmd.clear': '从显示中移除已完成的智能体',
|
|
938
|
+
'cmd.help': '显示帮助',
|
|
939
|
+
'cmd.quit': '退出(保存会话,停止智能体)',
|
|
940
|
+
'm.spawned': '⚡ 智能体 {name} 已并行启动{model}。',
|
|
941
|
+
'm.usageSpawn': '用法:/spawn [名称:] <任务> [--model=m]',
|
|
942
|
+
'm.usageAt': '用法:@智能体 <消息>(或 @all <消息>)',
|
|
943
|
+
'm.broadcast': '✉ 指令已广播给所有智能体。',
|
|
944
|
+
'm.sent': '✉ 指令已发送给 {target}。',
|
|
945
|
+
'm.notFound': '找不到智能体:{target}(现有:{list})',
|
|
946
|
+
'm.none': '无',
|
|
947
|
+
'm.usageSend': '用法:/send <智能体|all> <消息>',
|
|
948
|
+
'm.usagePause': '用法:/pause <智能体|all>',
|
|
949
|
+
'm.allPaused': '⏸ 所有智能体已暂停。',
|
|
950
|
+
'm.paused': '⏸ {name} 已暂停。',
|
|
951
|
+
'm.usageResume': '用法:/resume <智能体|all>',
|
|
952
|
+
'm.allResumed': '▶ 所有智能体已恢复。',
|
|
953
|
+
'm.resumed': '▶ {name} 已恢复。',
|
|
954
|
+
'm.usageStop': '用法:/stop <智能体|all>',
|
|
955
|
+
'm.allStopped': '⏹ 所有智能体已停止。',
|
|
956
|
+
'm.stopped': '⏹ {name} 已停止。',
|
|
957
|
+
'm.model': '会话模型:{pm}(更改:/model [提供商:]模型 · 全局默认:/settings)',
|
|
958
|
+
'm.modelSet': '会话模型:{pm}(已启动的智能体保持原模型)',
|
|
959
|
+
'm.noProvider': '未知提供商:{name}(已配置:{list})',
|
|
960
|
+
'm.usageApprovals': '用法:/approvals <ask|auto>',
|
|
961
|
+
'm.approvals': '批准模式(会话):{mode}',
|
|
962
|
+
'm.approvalsWarn': ' ⚠ Shell 命令现在无需确认即可执行',
|
|
963
|
+
'm.sound': '声音提示(会话):{state}',
|
|
964
|
+
'm.usageSound': '声音:{state} — 用法:/sound <on|off>',
|
|
965
|
+
'm.saved': '💾 会话已保存。',
|
|
966
|
+
'm.savedAs': '💾 会话已保存为「{name}」。',
|
|
967
|
+
'm.usageFocus': '用法:/focus <代理|off>',
|
|
968
|
+
'm.focusOn': '🎯 已聚焦 {name} — 普通文本将发给它。按 Esc 或 /focus off 退出。',
|
|
969
|
+
'm.focusOff': '🎯 已取消聚焦。',
|
|
970
|
+
'm.focusHint': '🎯 聚焦 {name} · 直接输入与它对话 · PgUp/PgDn 滚动 · Esc 退出',
|
|
971
|
+
'm.usageRestore': '用法:/restore <代理>(先用 /session 加载会话)',
|
|
972
|
+
'm.restored': '⏪ {name} 已带着之前的对话重新启动。',
|
|
973
|
+
'm.noConversation': '恢复的会话中没有「{name}」的已保存对话。',
|
|
974
|
+
'm.conflict': '⚠ {path}:代理之间反复冲突 — 建议你介入仲裁(@代理 或 /focus)。',
|
|
975
|
+
'status.bar': '⚡ {agents} 个代理 · {active} 个活跃 · {cost}',
|
|
976
|
+
'cmd.plan': '先计划模式:代理先给出计划,你批准后才开始修改',
|
|
977
|
+
'cmd.issue': '基于 GitHub issue 启动代理(需要 gh CLI)',
|
|
978
|
+
'cmd.undo': '撤销该代理最近一次文件修改',
|
|
979
|
+
'cmd.commit': '把某个代理(或全部)改动的文件做 git 提交',
|
|
980
|
+
'cmd.autocommit': '每个代理完成任务时自动提交其文件',
|
|
981
|
+
'm.usagePlan': '用法:/plan [名称:] <任务> — 代理先呈现计划,获得你的批准后才开始修改。',
|
|
982
|
+
'm.usageIssue': '用法:/issue <编号> — 基于该 GitHub issue 启动代理(需要 gh CLI)。',
|
|
983
|
+
'm.ghMissing': '✗ 未找到 gh CLI。请安装(https://cli.github.com)并执行 `gh auth login`。',
|
|
984
|
+
'm.issueFail': '✗ gh 执行失败:{msg}',
|
|
985
|
+
'm.issueSpawned': '⚡ {name} 已基于 issue #{n} 启动:{title}',
|
|
986
|
+
'm.usageUndo': '用法:/undo <代理> — 撤销该代理最近一次文件修改。',
|
|
987
|
+
'm.undoNone': '{name} 没有可撤销的修改。',
|
|
988
|
+
'm.undone': '↩ {name}:{path} 已恢复到先前内容。',
|
|
989
|
+
'm.undoConflict': '⚠ 该文件上另一代理更晚的修改也被覆盖了 — 请检查。',
|
|
990
|
+
'm.usageCommit': '用法:/commit <代理|all> [信息]',
|
|
991
|
+
'm.committed': '✔ git 提交:{name} 的 {files} 个文件。',
|
|
992
|
+
'm.commitNone': '{name} 没有可提交的内容。',
|
|
993
|
+
'm.commitFail': '✗ git 提交失败:{msg}',
|
|
994
|
+
'm.usageAutocommit': '用法:/autocommit <on|off>(当前 {state})',
|
|
995
|
+
'm.autocommit': '✔ 自动提交已{state} — 每个代理在 task_complete 时提交其文件。',
|
|
996
|
+
'cmd.attach': '为代理打开专属终端(或切换自动打开)',
|
|
997
|
+
'm.usageAttach': '用法:/attach <代理> 打开其终端 · /attach <on|off> 切换自动打开(当前 {state})',
|
|
998
|
+
'm.attachOpened': '⧉ 已为 {name} 打开专属终端。',
|
|
999
|
+
'm.attachManual': '⧉ 无法在此打开终端 — 请在另一个终端运行:{cmd}',
|
|
1000
|
+
'm.attachAuto': '⧉ 终端自动打开:{state}。',
|
|
1001
|
+
'attach.banner': '代理终端',
|
|
1002
|
+
'attach.placeholder': '发给 {agent} 的消息(回车发送,/quit 断开)…',
|
|
1003
|
+
'attach.waiting': '等待代理 {agent}…(Parallel 主会话在运行吗?)',
|
|
1004
|
+
'attach.gone': '会话已结束 — 此终端已断开。',
|
|
1005
|
+
'attach.hint': '⇄ /spawn <任务> = 新代理(独立终端) · 直接输入文字可指挥此代理 · /quit 断开',
|
|
1006
|
+
'grid.above': '▲ 上方还有 {n} 个代理 — PgUp',
|
|
1007
|
+
'grid.below': '▼ 下方还有 {n} 个代理 — PgDn',
|
|
1008
|
+
'm.nothing': '暂无可保存的内容。',
|
|
1009
|
+
'm.usageKey': '用法:/key <API 密钥>',
|
|
1010
|
+
'm.keySaved': '已为提供商 {name} 保存 API 密钥(~/.parallel/config.json)',
|
|
1011
|
+
'm.cleared': '已从显示中移除完成的智能体。',
|
|
1012
|
+
'm.unknown': '未知命令:{cmd} — 输入 /help',
|
|
1013
|
+
'm.imagesIgnored': '注意:附加的图片仅在启动新智能体时生效。',
|
|
1014
|
+
'm.sessionRestored': '📂 已恢复 {date} 的会话。',
|
|
1015
|
+
'm.usageSession': '用法:先用 /sessions 列出,然后 /session <n> 或 /session latest',
|
|
1016
|
+
'm.sessionLoaded': '📂 已加载 {date} 的会话。',
|
|
1017
|
+
'm.missingProvider': '未配置提供商。打开 /settings → 添加提供商,或重新进行首次配置。',
|
|
1018
|
+
'm.missingKey': '提供商 {name} 没有 API 密钥。使用 /key <API 密钥> 或 /settings → API 密钥。',
|
|
1019
|
+
'm.missingModel': '提供商 {name} 没有默认模型。使用 /settings → 提供商模型。',
|
|
1020
|
+
'm.doctorOk': '✓ 配置就绪:{pm}。修改:/settings · 临时模型:/model [提供商:]模型',
|
|
1021
|
+
'm.spawnFail': '无法启动智能体:没有可用的 provider/模型。请通过 /settings 配置。',
|
|
1022
|
+
'set.title': '⚙ 设置 — 全局(持久化于 ~/.parallel/config.json)',
|
|
1023
|
+
'sset.title': '⚙ 会话设置 — 仅本会话(全局设置:/settings)',
|
|
1024
|
+
'set.language': '语言:{lang}',
|
|
1025
|
+
'set.defaultPM': '默认提供商和模型:{pm}',
|
|
1026
|
+
'set.key': 'API 密钥 · {name}:{masked}',
|
|
1027
|
+
'set.addProvider': '添加提供商…',
|
|
1028
|
+
'set.models': '提供商模型(添加名称 / 选择默认)…',
|
|
1029
|
+
'set.modelsFor': '{name} 的模型 — 选择一个作为全局默认,或输入新模型名称',
|
|
1030
|
+
'set.makeDefault': '设为默认',
|
|
1031
|
+
'set.addModelName': '模型名称,需与提供商文档完全一致',
|
|
1032
|
+
'set.approvals': '默认批准模式:{mode}',
|
|
1033
|
+
'set.sound': '默认声音:{state}',
|
|
1034
|
+
'set.back': '← 返回',
|
|
1035
|
+
'set.saved': '✓ 已保存到 ~/.parallel/config.json',
|
|
1036
|
+
'set.chooseProvider': '选择提供商',
|
|
1037
|
+
'set.chooseModel': '模型({name})— 选择或按提供商文档输入名称',
|
|
1038
|
+
'sset.model': '会话模型:{pm}',
|
|
1039
|
+
'sset.approvals': '批准(会话):{mode}',
|
|
1040
|
+
'sset.sound': '声音(会话):{state}',
|
|
1041
|
+
'set.esc': 'Esc:关闭',
|
|
1042
|
+
'q.title': '❓ 智能体提问',
|
|
1043
|
+
'q.pending': '({n} 个待处理)',
|
|
1044
|
+
'q.from': '智能体 {name} 询问:',
|
|
1045
|
+
'q.autorun': '⏱ {s} 秒后自动执行',
|
|
1046
|
+
'q.paused': '⏸ 倒计时已暂停(你正在输入)',
|
|
1047
|
+
'q.recommended': '★ 推荐',
|
|
1048
|
+
'q.keys': '↑/↓ + 回车 或 1-4 回答 · 30 秒内未回答 → 自动选择推荐选项',
|
|
1049
|
+
'cost.title': '💰 会话成本 — 实时,按智能体',
|
|
1050
|
+
'cost.empty': '尚无智能体 — 成本将在此实时显示。',
|
|
1051
|
+
'cost.unknown': '(价格未知 — 在 /settings → 模型价格 中设置)',
|
|
1052
|
+
'cost.total': '会话总计:',
|
|
1053
|
+
'cost.partial': '(部分 — 某些模型没有已知价格)',
|
|
1054
|
+
'cost.hint': '价格为美元。按模型覆盖:/settings → 模型价格。恢复的会话保留其成本历史。',
|
|
1055
|
+
'skills.title': '🧩 技能 — 智能体可加载的可复用指令',
|
|
1056
|
+
'skills.empty': '暂无技能。创建:/skill new <名称> [global],然后编辑 .md 文件。',
|
|
1057
|
+
'skills.hint1': '文件:~/.parallel/skills/*.md(全局)· <项目>/.parallel/skills/*.md(项目)。',
|
|
1058
|
+
'skills.hint2': '在任务中强制使用技能:"修复测试 #review" — 或让智能体自动加载相关技能。',
|
|
1059
|
+
'spec.title': '🎓 专家 — 带角色和可选固定模型的角色设定',
|
|
1060
|
+
'spec.empty': '暂无专家。创建:/specialist new <名称> [global],然后编辑 .md 文件。',
|
|
1061
|
+
'spec.hint1': '文件:~/.parallel/specialists/*.md(全局)· <项目>/.parallel/specialists/*.md(项目)。',
|
|
1062
|
+
'spec.hint2': '启动:/specialist <名称> <任务> — 角色会加入智能体的系统提示。',
|
|
1063
|
+
'cmd.specialist': '以专家身份启动智能体,或创建专家(new <名称>)',
|
|
1064
|
+
'cmd.specialists': '列出已配置的专家',
|
|
1065
|
+
'cmd.skill': '创建技能模板(待编辑的 .md)',
|
|
1066
|
+
'cmd.skills': '列出可用技能',
|
|
1067
|
+
'cmd.cost': '财务视图:每个智能体的实时成本 + 会话总计',
|
|
1068
|
+
'm.qAnswered': '❓ 你回答了 {name}:「{answer}」',
|
|
1069
|
+
'm.qAuto': '⏱ 自动执行:已为 {name} 选择「{answer}」(30 秒内未回答)',
|
|
1070
|
+
'm.costHistory': '💰 已恢复会话的成本历史 — 总计 {total}:',
|
|
1071
|
+
'm.noSpecialist': '未知专家:{name}',
|
|
1072
|
+
'm.usageSkill': '用法:/skill new <名称> [global] — 然后编辑创建的 .md 文件',
|
|
1073
|
+
'm.skillCreated': '🧩 技能已创建:{file} — 编辑此文件以定义它。',
|
|
1074
|
+
'm.specCreated': '🎓 专家已创建:{file} — 编辑此文件以定义角色。',
|
|
1075
|
+
'm.alreadyExists': '已存在:{msg}',
|
|
1076
|
+
'm.usageSpecialist': '用法:/specialist <名称> <任务> · /specialist new <名称> [global]',
|
|
1077
|
+
'set.prices': '模型价格(美元/100万 tokens,覆盖)…',
|
|
1078
|
+
'set.newSkill': '创建技能(全局)…',
|
|
1079
|
+
'set.newSpecialist': '创建专家(全局)…',
|
|
1080
|
+
'set.priceModel': '选择要定价的模型({name})— 或输入名称',
|
|
1081
|
+
'set.priceUnknown': '无已知价格',
|
|
1082
|
+
'set.priceValue': '{model} 的价格(美元/100万 tokens):「input, output」(例:0.27, 1.10)',
|
|
1083
|
+
'set.priceBad': '格式无效 — 应为:input, output(例:0.27, 1.10)',
|
|
1084
|
+
'set.newSkillName': '技能名称(将在 ~/.parallel/skills 创建 .md 模板)',
|
|
1085
|
+
'set.newSpecialistName': '专家名称(将在 ~/.parallel/specialists 创建 .md 模板)',
|
|
1086
|
+
};
|
|
1087
|
+
const STRINGS = { en, fr, es, zh };
|