@parallel-cli/parallel 0.4.0 → 0.4.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/dist/i18n.js CHANGED
@@ -55,6 +55,10 @@ const en = {
55
55
  'wiz.provider.name.ph': 'e.g. openrouter, mistral, ollama…',
56
56
  'wiz.provider.url.title': 'Base URL (OpenAI-compatible endpoint)',
57
57
  'wiz.provider.url.ph': 'e.g. https://openrouter.ai/api/v1',
58
+ 'wiz.provider.endpoint.title': 'Review endpoint for {name}',
59
+ 'wiz.provider.endpoint.model': 'Model: {model}',
60
+ 'wiz.provider.endpoint.use': 'Use this endpoint',
61
+ 'wiz.provider.endpoint.edit': 'Edit endpoint',
58
62
  'wiz.provider.model.title': "Model name — exactly as written in the provider's documentation",
59
63
  'wiz.provider.model.ph': 'e.g. deepseek-chat, gpt-4o-mini, qwen2.5-coder…',
60
64
  'wiz.provider.key.title': 'API key for {name}',
@@ -117,7 +121,7 @@ const en = {
117
121
  'help.l2d': ' for everyone).',
118
122
  '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
123
  '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',
124
+ 'help.keys': 'Esc: back to agents view · Tab: completion · ↑/↓: suggestions, history, or view scroll · Ctrl+V: paste image',
121
125
  // commands (descriptions)
122
126
  'cmd.ask': 'Ask-only agent: answers and advises without editing',
123
127
  'cmd.task': 'Task agent: executes, edits, validates, summarizes',
@@ -155,6 +159,8 @@ const en = {
155
159
  'cmd.doctor': 'Check provider/model/API key configuration and repair hints',
156
160
  'cmd.settings': 'Global settings — providers, API keys, language, defaults (persisted)',
157
161
  'cmd.ssettings': 'Session settings — model, approvals, sound (this session only)',
162
+ 'cmd.project': 'Change project folder or reopen folder picker',
163
+ 'cmd.wizard': 'Relaunch the setup wizard',
158
164
  'cmd.approvals': 'Shell approvals: ask, auto-safe, or yolo (this session)',
159
165
  'cmd.sound': 'Sound cues (this session)',
160
166
  'cmd.save': 'Save the session now (optionally with a name)',
@@ -252,7 +258,7 @@ const en = {
252
258
  'm.usageSession': 'Usage: /sessions to list, then /session <n> or /session latest',
253
259
  'm.sessionLoaded': '📂 Session from {date} loaded.',
254
260
  'm.missingProvider': 'No provider configured. Open /settings → Add a provider, or restart with a first-run config.',
255
- 'm.missingKey': 'Provider {name} has no API key. Use /key <API key> or /settings → API key.',
261
+ 'm.missingKey': 'Provider {name} has no API key. Use /settings Providers → API key.',
256
262
  'm.missingModel': 'Provider {name} has no default model. Use /settings → Provider models.',
257
263
  'm.doctorOk': '✓ Configuration ready: {pm}. Changes: /settings · temporary model: /model [provider:]model',
258
264
  'm.spawnFail': 'Cannot launch the agent: no usable provider/model. Configure one via /settings.',
@@ -276,6 +282,8 @@ const en = {
276
282
  'sset.model': 'Session model: {pm}',
277
283
  'sset.approvals': 'Shell approvals (session): {mode}',
278
284
  'sset.sound': 'Sound (session): {state}',
285
+ 'sset.providers.title': 'Change provider & model',
286
+ 'sset.providers.back': 'Back',
279
287
  'set.esc': 'Esc: close',
280
288
  // agent questions (auto-run)
281
289
  'q.title': '❓ AGENT QUESTION',
@@ -327,6 +335,45 @@ const en = {
327
335
  'set.priceBad': 'Invalid format — expected: input, output (e.g. 0.27, 1.10)',
328
336
  'set.newSkillName': 'Skill name (a .md template will be created in ~/.parallel/skills)',
329
337
  'set.newSpecialistName': 'Specialist name (a .md template will be created in ~/.parallel/specialists)',
338
+ // provider-pick section headers
339
+ 'wiz.provider.section.configured': 'Configured Providers',
340
+ 'wiz.provider.section.western': 'Western',
341
+ 'wiz.provider.section.chinese': 'Chinese',
342
+ 'wiz.provider.section.gateways': 'Gateways',
343
+ 'wiz.provider.section.inference': 'Inference',
344
+ 'wiz.provider.section.local': 'Local Models',
345
+ 'wiz.provider.customDetail': 'Configure manually',
346
+ 'wiz.provider.ollamaDetail': 'Local — no API key needed',
347
+ 'wiz.provider.ollama.checking': 'Checking Ollama at localhost:11434...',
348
+ 'wiz.provider.ollama.found': 'Found {n} models',
349
+ 'wiz.provider.ollama.notFound': 'Could not reach Ollama at localhost:11434. Is it running?',
350
+ 'wiz.provider.ollama.continueDefaults': 'Continue with defaults',
351
+ 'wiz.provider.ollama.goBack': 'Go back',
352
+ // provider settings (future use)
353
+ 'set.providers': 'Providers',
354
+ 'set.providers.title': 'Providers',
355
+ 'set.providers.add': 'Add Provider...',
356
+ 'set.providers.back': 'Back',
357
+ 'set.providerDetail.title': '{name}',
358
+ 'set.providerDetail.key': 'Set API Key',
359
+ 'set.providerDetail.clearKey': 'Clear API Key',
360
+ 'set.providerDetail.endpoint': 'Endpoint',
361
+ 'set.providerDetail.models': 'Manage Models',
362
+ 'set.providerDetail.pricing': 'Pricing',
363
+ 'set.providerDetail.setDefault': 'Set as Default',
364
+ 'set.providerDetail.remove': 'Remove Provider',
365
+ 'set.providerDetail.back': 'Back',
366
+ 'set.defaultProvider': 'Default Provider',
367
+ 'set.defaultProvider.title': 'Default Provider',
368
+ 'set.removeProvider.title': 'Remove {name}?',
369
+ 'set.removeProvider.confirm': 'This cannot be undone.',
370
+ 'set.removeProvider.yes': 'Yes, remove',
371
+ 'set.removeProvider.no': 'Cancel',
372
+ 'set.status.configured': 'configured',
373
+ 'set.status.noKey': 'no key',
374
+ 'set.status.local': 'local',
375
+ 'set.status.default': 'default',
376
+ 'set.key.masked': '{masked}',
330
377
  };
331
378
  const fr = {
332
379
  tagline: 'Des agents de code en parallèle, en temps réel — sans verrous, sans attente.',
@@ -360,6 +407,10 @@ const fr = {
360
407
  'wiz.provider.name.ph': 'ex : openrouter, mistral, ollama…',
361
408
  'wiz.provider.url.title': 'URL de base (endpoint OpenAI-compatible)',
362
409
  'wiz.provider.url.ph': 'ex : https://openrouter.ai/api/v1',
410
+ 'wiz.provider.endpoint.title': 'Vérifier l’endpoint de {name}',
411
+ 'wiz.provider.endpoint.model': 'Modèle : {model}',
412
+ 'wiz.provider.endpoint.use': 'Utiliser cet endpoint',
413
+ 'wiz.provider.endpoint.edit': 'Modifier l’endpoint',
363
414
  'wiz.provider.model.title': 'Nom du modèle — exactement comme dans la documentation du provider',
364
415
  'wiz.provider.model.ph': 'ex : deepseek-chat, gpt-4o-mini, qwen2.5-coder…',
365
416
  'wiz.provider.key.title': 'Clef API pour {name}',
@@ -418,7 +469,7 @@ const fr = {
418
469
  'help.l2d': ' pour tous).',
419
470
  '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.',
420
471
  '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).",
421
- 'help.keys': 'Esc : revenir à la vue agents · Tab : complétion · ↑/↓ : historique · Ctrl+V : coller une image',
472
+ 'help.keys': 'Esc : revenir à la vue agents · Tab : complétion · ↑/↓ : suggestions, historique ou scroll selon la vue · Ctrl+V : coller une image',
422
473
  'cmd.ask': 'Agent ask : répond et conseille sans modifier',
423
474
  'cmd.task': 'Agent task : exécute, modifie, valide, résume',
424
475
  'cmd.agents': 'Vue panneaux agents (temps réel)',
@@ -455,6 +506,8 @@ const fr = {
455
506
  'cmd.doctor': 'Vérifier provider/modèle/clef API et afficher les corrections',
456
507
  'cmd.settings': 'Réglages globaux — providers, clefs API, langue, défauts (persistés)',
457
508
  'cmd.ssettings': 'Réglages de session — modèle, approbations, son (cette session)',
509
+ 'cmd.project': 'Changer de dossier projet ou rouvrir le choix de dossier',
510
+ 'cmd.wizard': 'Relancer le wizard de configuration',
458
511
  'cmd.approvals': 'Approbations shell : ask, auto-safe ou yolo (cette session)',
459
512
  'cmd.sound': 'Repères sonores (cette session)',
460
513
  'cmd.save': 'Sauvegarder la session maintenant (avec un nom optionnel)',
@@ -551,7 +604,7 @@ const fr = {
551
604
  'm.usageSession': 'Usage : /sessions pour lister, puis /session <n> ou /session latest',
552
605
  'm.sessionLoaded': '📂 Session du {date} chargée.',
553
606
  'm.missingProvider': 'Aucun provider configuré. Ouvre /settings → Ajouter un provider, ou relance une première config.',
554
- 'm.missingKey': 'Le provider {name} n’a pas de clef API. Utilise /key <clef API> ou /settings → Clef API.',
607
+ 'm.missingKey': 'Le provider {name} n’a pas de clef API. Utilise /settings Providers → Clef API.',
555
608
  'm.missingModel': 'Le provider {name} n’a pas de modèle par défaut. Utilise /settings → Modèles du provider.',
556
609
  'm.doctorOk': '✓ Configuration prête : {pm}. Changements : /settings · modèle temporaire : /model [provider:]modèle',
557
610
  'm.spawnFail': "Impossible de lancer l'agent : aucun provider/modèle utilisable. Configure-en un via /settings.",
@@ -574,6 +627,8 @@ const fr = {
574
627
  'sset.model': 'Modèle de session : {pm}',
575
628
  'sset.approvals': 'Approbations shell (session) : {mode}',
576
629
  'sset.sound': 'Son (session) : {state}',
630
+ 'sset.providers.title': 'Changer de fournisseur et de modèle',
631
+ 'sset.providers.back': 'Retour',
577
632
  'set.esc': 'Esc : fermer',
578
633
  'q.title': '❓ QUESTION D’UN AGENT',
579
634
  'q.pending': ' ({n} en attente)',
@@ -619,6 +674,45 @@ const fr = {
619
674
  'set.priceBad': 'Format invalide — attendu : input, output (ex : 0.27, 1.10)',
620
675
  'set.newSkillName': 'Nom du skill (un modèle .md sera créé dans ~/.parallel/skills)',
621
676
  'set.newSpecialistName': 'Nom du spécialiste (un modèle .md sera créé dans ~/.parallel/specialists)',
677
+ // provider-pick section headers
678
+ 'wiz.provider.section.configured': 'Providers configurés',
679
+ 'wiz.provider.section.western': 'Occidental',
680
+ 'wiz.provider.section.chinese': 'Chinois',
681
+ 'wiz.provider.section.gateways': 'Passerelles',
682
+ 'wiz.provider.section.inference': 'Inférence',
683
+ 'wiz.provider.section.local': 'Modèles locaux',
684
+ 'wiz.provider.customDetail': 'Configurer manuellement',
685
+ 'wiz.provider.ollamaDetail': 'Local — pas de clef API requise',
686
+ 'wiz.provider.ollama.checking': 'Vérification de Ollama sur localhost:11434…',
687
+ 'wiz.provider.ollama.found': '{n} modèles trouvés',
688
+ 'wiz.provider.ollama.notFound': 'Ollama est injoignable sur localhost:11434. Est-il lancé ?',
689
+ 'wiz.provider.ollama.continueDefaults': 'Continuer avec les valeurs par défaut',
690
+ 'wiz.provider.ollama.goBack': 'Retour',
691
+ // provider settings (future use)
692
+ 'set.providers': 'Fournisseurs',
693
+ 'set.providers.title': 'Fournisseurs',
694
+ 'set.providers.add': 'Ajouter un fournisseur…',
695
+ 'set.providers.back': 'Retour',
696
+ 'set.providerDetail.title': '{name}',
697
+ 'set.providerDetail.key': 'Définir la clef API',
698
+ 'set.providerDetail.clearKey': 'Effacer la clef API',
699
+ 'set.providerDetail.endpoint': 'Endpoint',
700
+ 'set.providerDetail.models': 'Gérer les modèles',
701
+ 'set.providerDetail.pricing': 'Tarifs',
702
+ 'set.providerDetail.setDefault': 'Définir par défaut',
703
+ 'set.providerDetail.remove': 'Supprimer le fournisseur',
704
+ 'set.providerDetail.back': 'Retour',
705
+ 'set.defaultProvider': 'Fournisseur par défaut',
706
+ 'set.defaultProvider.title': 'Fournisseur par défaut',
707
+ 'set.removeProvider.title': 'Supprimer {name} ?',
708
+ 'set.removeProvider.confirm': 'Cette action est irréversible.',
709
+ 'set.removeProvider.yes': 'Oui, supprimer',
710
+ 'set.removeProvider.no': 'Annuler',
711
+ 'set.status.configured': 'configuré',
712
+ 'set.status.noKey': 'pas de clef',
713
+ 'set.status.local': 'local',
714
+ 'set.status.default': 'défaut',
715
+ 'set.key.masked': '{masked}',
622
716
  };
623
717
  const es = {
624
718
  tagline: 'Agentes de código en paralelo, en tiempo real — sin bloqueos, sin esperas.',
@@ -652,6 +746,10 @@ const es = {
652
746
  'wiz.provider.name.ph': 'ej.: openrouter, mistral, ollama…',
653
747
  'wiz.provider.url.title': 'URL base (endpoint compatible con OpenAI)',
654
748
  'wiz.provider.url.ph': 'ej.: https://openrouter.ai/api/v1',
749
+ 'wiz.provider.endpoint.title': 'Revisar endpoint de {name}',
750
+ 'wiz.provider.endpoint.model': 'Modelo: {model}',
751
+ 'wiz.provider.endpoint.use': 'Usar este endpoint',
752
+ 'wiz.provider.endpoint.edit': 'Editar endpoint',
655
753
  'wiz.provider.model.title': 'Nombre del modelo — exactamente como en la documentación del proveedor',
656
754
  'wiz.provider.model.ph': 'ej.: deepseek-chat, gpt-4o-mini, qwen2.5-coder…',
657
755
  'wiz.provider.key.title': 'Clave API para {name}',
@@ -710,7 +808,7 @@ const es = {
710
808
  'help.l2d': ' para todos).',
711
809
  '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.',
712
810
  '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).',
713
- 'help.keys': 'Esc: volver a la vista de agentes · Tab: autocompletar · ↑/↓: historial · Ctrl+V: pegar imagen',
811
+ 'help.keys': 'Esc: volver a la vista de agentes · Tab: autocompletar · ↑/↓: sugerencias, historial o scroll de vista · Ctrl+V: pegar imagen',
714
812
  'cmd.ask': 'Agente ask: responde y aconseja sin editar',
715
813
  'cmd.task': 'Agente task: ejecuta, edita, valida y resume',
716
814
  'cmd.agents': 'Vista de paneles de agentes (tiempo real)',
@@ -747,6 +845,8 @@ const es = {
747
845
  'cmd.doctor': 'Comprobar proveedor/modelo/clave API y mostrar correcciones',
748
846
  'cmd.settings': 'Ajustes globales — proveedores, claves API, idioma, valores por defecto (persistentes)',
749
847
  'cmd.ssettings': 'Ajustes de sesión — modelo, aprobaciones, sonido (solo esta sesión)',
848
+ 'cmd.project': 'Cambiar carpeta del proyecto o reabrir selector de carpeta',
849
+ 'cmd.wizard': 'Relanzar el asistente de configuración',
750
850
  'cmd.approvals': 'Aprobaciones shell: ask, auto-safe o yolo (esta sesión)',
751
851
  'cmd.sound': 'Señales sonoras (esta sesión)',
752
852
  'cmd.save': 'Guardar la sesión ahora (con un nombre opcional)',
@@ -843,7 +943,7 @@ const es = {
843
943
  'm.usageSession': 'Uso: /sessions para listar, luego /session <n> o /session latest',
844
944
  'm.sessionLoaded': '📂 Sesión del {date} cargada.',
845
945
  'm.missingProvider': 'No hay proveedor configurado. Abre /settings → Añadir proveedor, o reinicia con configuración inicial.',
846
- 'm.missingKey': 'El proveedor {name} no tiene clave API. Usa /key <clave API> o /settings → Clave API.',
946
+ 'm.missingKey': 'El proveedor {name} no tiene clave API. Usa /settings Providers → Clave API.',
847
947
  'm.missingModel': 'El proveedor {name} no tiene modelo por defecto. Usa /settings → Modelos del proveedor.',
848
948
  'm.doctorOk': '✓ Configuración lista: {pm}. Cambios: /settings · modelo temporal: /model [proveedor:]modelo',
849
949
  'm.spawnFail': 'No se puede lanzar el agente: ningún provider/modelo utilizable. Configura uno con /settings.',
@@ -866,6 +966,8 @@ const es = {
866
966
  'sset.model': 'Modelo de sesión: {pm}',
867
967
  'sset.approvals': 'Aprobaciones shell (sesión): {mode}',
868
968
  'sset.sound': 'Sonido (sesión): {state}',
969
+ 'sset.providers.title': 'Cambiar proveedor y modelo',
970
+ 'sset.providers.back': 'Volver',
869
971
  'set.esc': 'Esc: cerrar',
870
972
  'q.title': '❓ PREGUNTA DE UN AGENTE',
871
973
  'q.pending': ' ({n} pendientes)',
@@ -911,6 +1013,45 @@ const es = {
911
1013
  'set.priceBad': 'Formato inválido — esperado: input, output (ej.: 0.27, 1.10)',
912
1014
  'set.newSkillName': 'Nombre del skill (se creará una plantilla .md en ~/.parallel/skills)',
913
1015
  'set.newSpecialistName': 'Nombre del especialista (se creará una plantilla .md en ~/.parallel/specialists)',
1016
+ // provider-pick section headers
1017
+ 'wiz.provider.section.configured': 'Proveedores configurados',
1018
+ 'wiz.provider.section.western': 'Occidental',
1019
+ 'wiz.provider.section.chinese': 'Chino',
1020
+ 'wiz.provider.section.gateways': 'Pasarelas',
1021
+ 'wiz.provider.section.inference': 'Inferencia',
1022
+ 'wiz.provider.section.local': 'Modelos locales',
1023
+ 'wiz.provider.customDetail': 'Configurar manualmente',
1024
+ 'wiz.provider.ollamaDetail': 'Local — no requiere clave API',
1025
+ 'wiz.provider.ollama.checking': 'Comprobando Ollama en localhost:11434…',
1026
+ 'wiz.provider.ollama.found': '{n} modelos encontrados',
1027
+ 'wiz.provider.ollama.notFound': 'No se pudo contactar con Ollama en localhost:11434. ¿Está en ejecución?',
1028
+ 'wiz.provider.ollama.continueDefaults': 'Continuar con valores predeterminados',
1029
+ 'wiz.provider.ollama.goBack': 'Volver',
1030
+ // provider settings (future use)
1031
+ 'set.providers': 'Proveedores',
1032
+ 'set.providers.title': 'Proveedores',
1033
+ 'set.providers.add': 'Añadir proveedor…',
1034
+ 'set.providers.back': 'Volver',
1035
+ 'set.providerDetail.title': '{name}',
1036
+ 'set.providerDetail.key': 'Establecer clave API',
1037
+ 'set.providerDetail.clearKey': 'Borrar clave API',
1038
+ 'set.providerDetail.endpoint': 'Endpoint',
1039
+ 'set.providerDetail.models': 'Gestionar modelos',
1040
+ 'set.providerDetail.pricing': 'Precios',
1041
+ 'set.providerDetail.setDefault': 'Establecer como predeterminado',
1042
+ 'set.providerDetail.remove': 'Eliminar proveedor',
1043
+ 'set.providerDetail.back': 'Volver',
1044
+ 'set.defaultProvider': 'Proveedor predeterminado',
1045
+ 'set.defaultProvider.title': 'Proveedor predeterminado',
1046
+ 'set.removeProvider.title': '¿Eliminar {name}?',
1047
+ 'set.removeProvider.confirm': 'Esta acción no se puede deshacer.',
1048
+ 'set.removeProvider.yes': 'Sí, eliminar',
1049
+ 'set.removeProvider.no': 'Cancelar',
1050
+ 'set.status.configured': 'configurado',
1051
+ 'set.status.noKey': 'sin clave',
1052
+ 'set.status.local': 'local',
1053
+ 'set.status.default': 'predeterminado',
1054
+ 'set.key.masked': '{masked}',
914
1055
  };
915
1056
  const zh = {
916
1057
  tagline: '并行实时代码智能体 — 无锁定,无等待。',
@@ -944,6 +1085,10 @@ const zh = {
944
1085
  'wiz.provider.name.ph': '例如 openrouter、mistral、ollama…',
945
1086
  'wiz.provider.url.title': '基础 URL(OpenAI 兼容端点)',
946
1087
  'wiz.provider.url.ph': '例如 https://openrouter.ai/api/v1',
1088
+ 'wiz.provider.endpoint.title': '检查 {name} 端点',
1089
+ 'wiz.provider.endpoint.model': '模型:{model}',
1090
+ 'wiz.provider.endpoint.use': '使用此端点',
1091
+ 'wiz.provider.endpoint.edit': '编辑端点',
947
1092
  'wiz.provider.model.title': '模型名称 — 与提供商文档中的写法完全一致',
948
1093
  'wiz.provider.model.ph': '例如 deepseek-chat、gpt-4o-mini、qwen2.5-coder…',
949
1094
  'wiz.provider.key.title': '{name} 的 API 密钥',
@@ -1002,7 +1147,7 @@ const zh = {
1002
1147
  'help.l2d': ' 发给所有)。',
1003
1148
  'help.l3': '每次行动前,智能体都能看到彼此的状态和差异:它们共同编辑同一批文件,互不阻塞,也不破坏彼此的工作。',
1004
1149
  'help.states': '状态:🔨 工作中 · 👂 倾听其他智能体(双边框)· 🧠 思考中 · ✋ 等待你的批准 · ⏹ 停止。声音:1 声 = 智能体启动/完成,2 声 = 需要批准(/sound off 静音)。',
1005
- 'help.keys': 'Esc:返回智能体视图 · Tab:补全 · ↑/↓:历史 · Ctrl+V:粘贴图片',
1150
+ 'help.keys': 'Esc:返回智能体视图 · Tab:补全 · ↑/↓:建议、历史或视图滚动 · Ctrl+V:粘贴图片',
1006
1151
  'cmd.ask': 'Ask 智能体:只回答和建议,不编辑',
1007
1152
  'cmd.task': 'Task 智能体:执行、编辑、验证并总结',
1008
1153
  'cmd.agents': '智能体面板视图(实时)',
@@ -1039,6 +1184,8 @@ const zh = {
1039
1184
  'cmd.doctor': '检查提供商/模型/API 密钥配置并显示修复提示',
1040
1185
  'cmd.settings': '全局设置 — 提供商、API 密钥、语言、默认值(持久化)',
1041
1186
  'cmd.ssettings': '会话设置 — 模型、批准、声音(仅本会话)',
1187
+ 'cmd.project': '更改项目文件夹或重新打开文件夹选择器',
1188
+ 'cmd.wizard': '重新启动设置向导',
1042
1189
  'cmd.approvals': 'Shell 批准:ask、auto-safe 或 yolo(本会话)',
1043
1190
  'cmd.sound': '声音提示(本会话)',
1044
1191
  'cmd.save': '立即保存会话(可附加名称)',
@@ -1135,7 +1282,7 @@ const zh = {
1135
1282
  'm.usageSession': '用法:先用 /sessions 列出,然后 /session <n> 或 /session latest',
1136
1283
  'm.sessionLoaded': '📂 已加载 {date} 的会话。',
1137
1284
  'm.missingProvider': '未配置提供商。打开 /settings → 添加提供商,或重新进行首次配置。',
1138
- 'm.missingKey': '提供商 {name} 没有 API 密钥。使用 /key <API 密钥> 或 /settings → API 密钥。',
1285
+ 'm.missingKey': '提供商 {name} 没有 API 密钥。使用 /settings Providers → API 密钥。',
1139
1286
  'm.missingModel': '提供商 {name} 没有默认模型。使用 /settings → 提供商模型。',
1140
1287
  'm.doctorOk': '✓ 配置就绪:{pm}。修改:/settings · 临时模型:/model [提供商:]模型',
1141
1288
  'm.spawnFail': '无法启动智能体:没有可用的 provider/模型。请通过 /settings 配置。',
@@ -1158,6 +1305,8 @@ const zh = {
1158
1305
  'sset.model': '会话模型:{pm}',
1159
1306
  'sset.approvals': 'Shell 批准(会话):{mode}',
1160
1307
  'sset.sound': '声音(会话):{state}',
1308
+ 'sset.providers.title': '更改提供商和模型',
1309
+ 'sset.providers.back': '返回',
1161
1310
  'set.esc': 'Esc:关闭',
1162
1311
  'q.title': '❓ 智能体提问',
1163
1312
  'q.pending': '({n} 个待处理)',
@@ -1203,5 +1352,44 @@ const zh = {
1203
1352
  'set.priceBad': '格式无效 — 应为:input, output(例:0.27, 1.10)',
1204
1353
  'set.newSkillName': '技能名称(将在 ~/.parallel/skills 创建 .md 模板)',
1205
1354
  'set.newSpecialistName': '专家名称(将在 ~/.parallel/specialists 创建 .md 模板)',
1355
+ // provider-pick section headers
1356
+ 'wiz.provider.section.configured': '已配置的提供商',
1357
+ 'wiz.provider.section.western': '西方',
1358
+ 'wiz.provider.section.chinese': '中文',
1359
+ 'wiz.provider.section.gateways': '网关',
1360
+ 'wiz.provider.section.inference': '推理',
1361
+ 'wiz.provider.section.local': '本地模型',
1362
+ 'wiz.provider.customDetail': '手动配置',
1363
+ 'wiz.provider.ollamaDetail': '本地 — 无需 API 密钥',
1364
+ 'wiz.provider.ollama.checking': '正在检查 Ollama(localhost:11434)…',
1365
+ 'wiz.provider.ollama.found': '找到 {n} 个模型',
1366
+ 'wiz.provider.ollama.notFound': '无法连接到 localhost:11434 的 Ollama。它在运行吗?',
1367
+ 'wiz.provider.ollama.continueDefaults': '继续使用默认值',
1368
+ 'wiz.provider.ollama.goBack': '返回',
1369
+ // provider settings (future use)
1370
+ 'set.providers': '提供商',
1371
+ 'set.providers.title': '提供商',
1372
+ 'set.providers.add': '添加提供商…',
1373
+ 'set.providers.back': '返回',
1374
+ 'set.providerDetail.title': '{name}',
1375
+ 'set.providerDetail.key': '设置 API 密钥',
1376
+ 'set.providerDetail.clearKey': '清除 API 密钥',
1377
+ 'set.providerDetail.endpoint': '端点',
1378
+ 'set.providerDetail.models': '管理模型',
1379
+ 'set.providerDetail.pricing': '定价',
1380
+ 'set.providerDetail.setDefault': '设为默认',
1381
+ 'set.providerDetail.remove': '移除提供商',
1382
+ 'set.providerDetail.back': '返回',
1383
+ 'set.defaultProvider': '默认提供商',
1384
+ 'set.defaultProvider.title': '默认提供商',
1385
+ 'set.removeProvider.title': '移除 {name}?',
1386
+ 'set.removeProvider.confirm': '此操作无法撤销。',
1387
+ 'set.removeProvider.yes': '是,移除',
1388
+ 'set.removeProvider.no': '取消',
1389
+ 'set.status.configured': '已配置',
1390
+ 'set.status.noKey': '无密钥',
1391
+ 'set.status.local': '本地',
1392
+ 'set.status.default': '默认',
1393
+ 'set.key.masked': '{masked}',
1206
1394
  };
1207
1395
  const STRINGS = { en, fr, es, zh };
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import path from 'node:path';
6
6
  import { render } from 'ink';
7
7
  import { App } from './ui/App.js';
8
8
  import { Controller } from './controller.js';
9
- import { loadConfig, setConfigHome } from './config.js';
9
+ import { loadConfig, providerReady, setConfigHome } from './config.js';
10
10
  import { setLang } from './i18n.js';
11
11
  const argv = process.argv.slice(2);
12
12
  function takeFlagValue(flag) {
@@ -47,10 +47,13 @@ Environment variables:
47
47
  PARALLEL_API_KEY / DEEPSEEK_API_KEY API key
48
48
  PARALLEL_MODEL Default model (e.g. deepseek-chat)
49
49
  PARALLEL_BASE_URL OpenAI-compatible endpoint
50
+ PARALLEL_NO_ALT_SCREEN=1 Disable the alternate terminal screen.
50
51
 
51
52
  Inside the TUI:
52
53
  <task> + Enter Launch agent N+1 — even while the others are working
53
54
  @a1 <message> Real-time instruction to an agent (@all for everyone)
55
+ /project [folder] Change project folder or reopen the folder picker
56
+ /wizard Relaunch the setup wizard
54
57
  /help All commands
55
58
  `);
56
59
  process.exit(0);
@@ -104,7 +107,7 @@ if (headless) {
104
107
  // No human in the loop: commands are auto-approved.
105
108
  ctl.setSessionApprovalMode('yolo');
106
109
  const provider = ctl.sessionProvider();
107
- if (!provider || !provider.apiKey) {
110
+ if (!provider || !providerReady(provider)) {
108
111
  console.error('Headless mode needs a configured provider + API key. Run `parallel` interactively once, or set PARALLEL_API_KEY.');
109
112
  process.exit(1);
110
113
  }
package/dist/pricing.js CHANGED
@@ -5,33 +5,162 @@
5
5
  * Prices drift over time; overrides always win.
6
6
  */
7
7
  const BUILTIN = {
8
- // DeepSeek
9
- 'deepseek-v4-flash': { input: 0.27, output: 1.1 },
10
- 'deepseek-v4-pro': { input: 0.55, output: 2.19 },
11
- 'deepseek-chat': { input: 0.27, output: 1.1 },
12
- 'deepseek-reasoner': { input: 0.55, output: 2.19 },
8
+ // === Western ===
13
9
  // OpenAI
14
- 'gpt-4o': { input: 2.5, output: 10 },
15
- 'gpt-4o-mini': { input: 0.15, output: 0.6 },
16
- 'gpt-4.1': { input: 2, output: 8 },
17
- 'gpt-4.1-mini': { input: 0.4, output: 1.6 },
18
- 'gpt-4.1-nano': { input: 0.1, output: 0.4 },
19
- 'o3-mini': { input: 1.1, output: 4.4 },
20
- 'o4-mini': { input: 1.1, output: 4.4 },
10
+ 'gpt-5.5': { input: 5.00, output: 30.00, cacheHit: 0.50 },
11
+ 'gpt-5.5-pro': { input: 30.00, output: 180.00, cacheHit: 3.00 },
12
+ 'gpt-5.4': { input: 1.25, output: 10.00, cacheHit: 0.125 }, // approx
13
+ 'gpt-5.3-codex': { input: 1.25, output: 10.00, cacheHit: 0.125 }, // approx
14
+ 'gpt-4o': { input: 2.50, output: 10.00 },
15
+ 'gpt-4o-mini': { input: 0.15, output: 0.60 },
16
+ 'o4-mini': { input: 1.10, output: 4.40 },
17
+ 'o3': { input: 5.00, output: 20.00 },
18
+ 'o3-mini': { input: 0.55, output: 2.20 },
19
+ 'o1': { input: 15.00, output: 60.00 },
20
+ 'o1-mini': { input: 1.10, output: 4.40 },
21
21
  // Anthropic
22
- 'claude-opus-4': { input: 15, output: 75 },
23
- 'claude-sonnet-4': { input: 3, output: 15 },
24
- 'claude-haiku-4': { input: 1, output: 5 },
25
- 'claude-3-5-haiku': { input: 0.8, output: 4 },
22
+ 'claude-opus-4-8': { input: 5.00, output: 25.00, cacheHit: 0.50 },
23
+ 'claude-opus-4-7': { input: 5.00, output: 25.00, cacheHit: 0.50 },
24
+ 'claude-sonnet-4-6': { input: 3.00, output: 15.00, cacheHit: 0.30 },
25
+ 'claude-haiku-4-5': { input: 1.00, output: 5.00, cacheHit: 0.10 },
26
+ // Google Gemini
27
+ 'gemini-3.1-pro': { input: 2.00, output: 12.00, cacheHit: 0.20 }, // tiered: >200K = 2×/1.5×
28
+ 'gemini-3.5-flash': { input: 1.50, output: 9.00, cacheHit: 0.15 },
29
+ 'gemini-3-flash': { input: 0.60, output: 3.00, cacheHit: 0.06 }, // approx
30
+ 'gemini-3.1-flash-lite': { input: 0.10, output: 0.40, cacheHit: 0.01 },
31
+ // xAI Grok
32
+ 'grok-4': { input: 3.00, output: 15.00 }, // approx
33
+ 'grok-4-fast-reasoning': { input: 0.20, output: 0.50 }, // approx
34
+ 'grok-3': { input: 3.00, output: 15.00 },
35
+ 'grok-code-fast-1': { input: 0.20, output: 1.50 }, // approx
26
36
  // Mistral
27
- 'mistral-large': { input: 2, output: 6 },
28
- 'codestral': { input: 0.3, output: 0.9 },
29
- 'devstral': { input: 0.1, output: 0.3 },
30
- // Alibaba
31
- 'qwen2.5-coder': { input: 0.09, output: 0.09 },
32
- 'qwen-max': { input: 1.6, output: 6.4 },
33
- // Local endpoints are free
34
- 'ollama': { input: 0, output: 0 },
37
+ 'mistral-large-2': { input: 2.00, output: 6.00 },
38
+ 'magistral-medium': { input: 2.00, output: 5.00 },
39
+ 'codestral-latest': { input: 0.30, output: 0.90 },
40
+ 'mistral-small-latest': { input: 0.20, output: 0.60 },
41
+ // Cohere
42
+ 'command-a': { input: 2.50, output: 10.00 },
43
+ 'command-r-plus': { input: 2.50, output: 10.00 },
44
+ // Perplexity
45
+ 'sonar-pro': { input: 3.00, output: 15.00 },
46
+ 'sonar-deep-research': { input: 2.00, output: 8.00 },
47
+ // === Chinese ===
48
+ // DeepSeek
49
+ 'deepseek-v4-pro': { input: 0.435, output: 0.87, cacheHit: 0.0036 },
50
+ 'deepseek-v4-flash': { input: 0.14, output: 0.28, cacheHit: 0.003 },
51
+ 'deepseek-chat': { input: 0.27, output: 1.10, cacheHit: 0.027 },
52
+ 'deepseek-reasoner': { input: 0.55, output: 2.19, cacheHit: 0.14 },
53
+ // MiniMax — list pricing
54
+ 'MiniMax-M3': { input: 0.60, output: 2.40, cacheHit: 0.12 },
55
+ 'MiniMax-M2.7': { input: 0.30, output: 1.20, cacheHit: 0.06 },
56
+ 'MiniMax-M2.7-highspeed': { input: 0.60, output: 2.40, cacheHit: 0.06 },
57
+ // Z.ai / GLM
58
+ 'glm-5.2': { input: 1.00, output: 3.20 },
59
+ 'glm-5.1': { input: 1.00, output: 3.20 },
60
+ 'glm-4.7': { input: 0.60, output: 2.20 },
61
+ 'glm-4.7-flash': { input: 0.00, output: 0.00 }, // free
62
+ 'glm-5v-turbo': { input: 0.30, output: 0.90 },
63
+ // Alibaba / Qwen
64
+ 'qwen3.7-max': { input: 1.25, output: 3.75 }, // promo price, cache: yes
65
+ 'qwen3.6-max-preview': { input: 1.04, output: 6.24 }, // tiered, lower bound
66
+ 'qwen3.6-plus': { input: 0.40, output: 1.20 },
67
+ 'qwen3.5-coder': { input: 0.20, output: 0.60 },
68
+ // Moonshot / Kimi
69
+ 'kimi-k2.6': { input: 0.95, output: 4.00, cacheHit: 0.16 },
70
+ 'kimi-k2.7-code': { input: 0.95, output: 4.00, cacheHit: 0.19 },
71
+ 'kimi-k2.5': { input: 0.60, output: 3.00, cacheHit: 0.10 },
72
+ 'moonshot-v1-128k': { input: 0.85, output: 1.70 },
73
+ // Xiaomi / MiMo
74
+ 'mimo-v2-pro': { input: 0.30, output: 1.00 }, // approx
75
+ 'mimo-v2-omni': { input: 0.40, output: 1.50 }, // approx
76
+ // StepFun
77
+ 'step-2-16k': { input: 0.50, output: 1.50 }, // approx
78
+ // === Gateways ===
79
+ // OpenRouter
80
+ 'openai/gpt-5.5': { input: 5.00, output: 30.00 },
81
+ 'anthropic/claude-sonnet-4-6': { input: 3.00, output: 15.00 },
82
+ 'google/gemini-3.5-flash': { input: 1.50, output: 9.00 },
83
+ 'deepseek/deepseek-v4-pro': { input: 0.435, output: 0.87 },
84
+ 'meta-llama/llama-4-maverick': { input: 0.50, output: 1.60 },
85
+ 'mistralai/mistral-large-2': { input: 2.00, output: 6.00 },
86
+ // SiliconFlow
87
+ 'deepseek-ai/DeepSeek-V4-Pro': { input: 0.435, output: 0.87 },
88
+ 'deepseek-ai/DeepSeek-R1': { input: 0.55, output: 2.19 },
89
+ 'Qwen/Qwen3-Coder-480B': { input: 0.20, output: 0.60 },
90
+ 'glm-4/GLM-5.2': { input: 1.00, output: 3.20 },
91
+ 'moonshotai/Kimi-K2.6': { input: 0.95, output: 4.00 },
92
+ // Atlas Cloud
93
+ 'deepseek-v4-pro @atlas': { input: 0.435, output: 0.87 },
94
+ 'deepseek-r1 @atlas': { input: 0.55, output: 2.19 },
95
+ 'qwen3.7-max @atlas': { input: 1.25, output: 3.75 },
96
+ 'glm-5.2 @atlas': { input: 1.00, output: 3.20 },
97
+ 'kimi-k2.6 @atlas': { input: 0.95, output: 4.00 },
98
+ 'llama-4-maverick @atlas': { input: 0.50, output: 1.60 },
99
+ // Requesty — 0% markup, same as direct
100
+ 'gpt-5.5 @requesty': { input: 5.00, output: 30.00 },
101
+ 'claude-sonnet-4-6 @requesty': { input: 3.00, output: 15.00 },
102
+ 'gemini-3.5-flash @requesty': { input: 1.50, output: 9.00 },
103
+ 'deepseek-v4-pro @requesty': { input: 0.435, output: 0.87 },
104
+ 'llama-4-maverick @requesty': { input: 0.50, output: 1.60 },
105
+ 'mistral-large-2 @requesty': { input: 2.00, output: 6.00 },
106
+ // Vercel AI Gateway — list price, no markup
107
+ 'gpt-5.5 @vercel': { input: 5.00, output: 30.00 },
108
+ 'claude-sonnet-4-6 @vercel': { input: 3.00, output: 15.00 },
109
+ 'gemini-3.5-flash @vercel': { input: 1.50, output: 9.00 },
110
+ 'deepseek-v4-pro @vercel': { input: 0.435, output: 0.87 },
111
+ 'llama-4-maverick @vercel': { input: 0.50, output: 1.60 },
112
+ // === Inference hosts ===
113
+ // Groq
114
+ 'qwen-2.5-coder-32b': { input: 0.30, output: 0.50 },
115
+ 'deepseek-r1-distill-llama-70b': { input: 0.30, output: 2.00 },
116
+ 'kimi-k2.6 @groq': { input: 1.00, output: 3.00 },
117
+ 'llama-3.3-70b-versatile': { input: 0.15, output: 0.30 },
118
+ // Cerebras
119
+ 'llama-4-maverick-17b-128e-instruct': { input: 0.65, output: 0.85 },
120
+ 'qwen3-coder-480b @cerebras': { input: 2.00, output: 2.00 },
121
+ 'kimi-k2.6 @cerebras': { input: 1.65, output: 6.50 },
122
+ 'llama-3.3-70b @cerebras': { input: 0.10, output: 0.20 },
123
+ // Together AI
124
+ 'meta-llama/Llama-4-Maverick-17B-128E-Instruct': { input: 0.27, output: 0.85 },
125
+ 'deepseek-ai/DeepSeek-V3 @together': { input: 0.30, output: 0.30 },
126
+ 'Qwen/Qwen3-Coder-480B @together': { input: 0.40, output: 1.20 },
127
+ 'moonshotai/Kimi-K2.6 @together': { input: 0.60, output: 2.50 },
128
+ // Fireworks
129
+ 'accounts/fireworks/models/llama4-maverick-17b': { input: 0.22, output: 0.88 },
130
+ 'accounts/fireworks/models/deepseek-v3': { input: 0.90, output: 0.90 },
131
+ 'accounts/fireworks/models/qwen3-coder-480b': { input: 0.45, output: 1.80 },
132
+ 'accounts/fireworks/models/kimi-k2.6': { input: 0.60, output: 2.50 },
133
+ // DeepInfra
134
+ 'meta-llama/Llama-4-Maverick-17B-128E': { input: 0.20, output: 0.60 },
135
+ 'deepseek-ai/DeepSeek-V3 @deepinfra': { input: 0.26, output: 0.38 },
136
+ 'Qwen/Qwen3-Coder-480B @deepinfra': { input: 0.30, output: 1.00 },
137
+ 'moonshotai/Kimi-K2.6 @deepinfra': { input: 0.75, output: 3.50, cacheHit: 0.15 },
138
+ // Novita
139
+ 'meta-llama/llama-4-maverick-17b-128e': { input: 0.20, output: 0.60 },
140
+ 'deepseek/deepseek-v3': { input: 0.10, output: 0.28 },
141
+ 'qwen/qwen3-coder-480b': { input: 0.30, output: 1.20 },
142
+ 'moonshotai/kimi-k2.6': { input: 0.57, output: 2.30 },
143
+ // Hyperbolic
144
+ 'meta-llama/Llama-4-Maverick-17B-128E @hyperbolic': { input: 0.20, output: 0.60 },
145
+ 'deepseek-ai/DeepSeek-V3 @hyperbolic': { input: 0.25, output: 0.85 },
146
+ 'Qwen/Qwen3-Coder-480B @hyperbolic': { input: 0.30, output: 1.20 },
147
+ 'moonshotai/Kimi-K2.6 @hyperbolic': { input: 0.80, output: 3.00 },
148
+ // SambaNova
149
+ 'Meta-Llama-4-Maverick-17B-128E-Instruct': { input: 0.20, output: 0.30 },
150
+ 'DeepSeek-V3 @sambanova': { input: 1.00, output: 1.50 },
151
+ 'Llama-3.3-70B-Instruct': { input: 0.10, output: 0.20 },
152
+ // === Local (free) ===
153
+ // Ollama
154
+ 'qwen3-coder:480b': { input: 0.00, output: 0.00 },
155
+ 'glm-4.7 @ollama': { input: 0.00, output: 0.00 },
156
+ 'deepseek-v3 @ollama': { input: 0.00, output: 0.00 },
157
+ 'kimi-k2 @ollama': { input: 0.00, output: 0.00 },
158
+ 'llama3.2': { input: 0.00, output: 0.00 },
159
+ 'mistral @ollama': { input: 0.00, output: 0.00 },
160
+ 'codellama': { input: 0.00, output: 0.00 },
161
+ 'gemma3': { input: 0.00, output: 0.00 },
162
+ // vLLM / SGLang
163
+ 'your-model-here': { input: 0.00, output: 0.00 },
35
164
  };
36
165
  /**
37
166
  * Resolve the price of a model: provider override first, then built-in table
@@ -39,22 +168,28 @@ const BUILTIN = {
39
168
  * "claude-sonnet-4-20250514" or "openai/gpt-4o-mini"). null = unknown.
40
169
  */
41
170
  export function priceFor(provider, model) {
42
- const override = provider?.prices?.[model];
171
+ const overrideKey = provider?.prices
172
+ ? Object.keys(provider.prices).find((key) => key.toLowerCase() === model.toLowerCase())
173
+ : undefined;
174
+ const override = overrideKey ? provider?.prices?.[overrideKey] : undefined;
43
175
  if (override)
44
176
  return override;
45
177
  const m = model.toLowerCase();
46
178
  // strip an optional "vendor/" prefix (OpenRouter-style ids)
47
179
  const bare = m.includes('/') ? m.slice(m.lastIndexOf('/') + 1) : m;
48
- if (BUILTIN[bare])
49
- return BUILTIN[bare];
180
+ const builtins = Object.entries(BUILTIN).map(([key, price]) => [key.toLowerCase(), price]);
181
+ const exact = builtins.find(([key]) => key === bare);
182
+ if (exact)
183
+ return exact[1];
50
184
  // longest prefix wins so "deepseek-chat" beats nothing else
51
185
  let best = null;
52
- for (const key of Object.keys(BUILTIN)) {
53
- if ((bare.startsWith(key) || bare.includes(key)) && (!best || key.length > best.length))
54
- best = key;
186
+ for (const entry of builtins) {
187
+ const [key] = entry;
188
+ if ((bare.startsWith(key) || bare.includes(key)) && (!best || key.length > best[0].length))
189
+ best = entry;
55
190
  }
56
191
  if (best)
57
- return BUILTIN[best];
192
+ return best[1];
58
193
  // local endpoints (ollama, llama.cpp, vLLM on localhost) → free
59
194
  if (provider && /localhost|127\.0\.0\.1|0\.0\.0\.0/.test(provider.baseUrl))
60
195
  return { input: 0, output: 0 };