tide-commander 1.169.0 → 1.170.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/assets/{BossLogsModal-lFeLoDYQ.js → BossLogsModal-BPAHzrbZ.js} +1 -1
- package/dist/assets/{BossSpawnModal-Hd6BE1_1.js → BossSpawnModal-CaMQAL4B.js} +1 -1
- package/dist/assets/{ControlsModal-BogPdPgP.js → ControlsModal-CCCOEUic.js} +1 -1
- package/dist/assets/{DockerLogsModal-CO0bptY3.js → DockerLogsModal-eipz4JMG.js} +1 -1
- package/dist/assets/{EmbeddedEditor-VhhJKJWu.js → EmbeddedEditor-Dxi_G2S1.js} +18 -18
- package/dist/assets/{GmailOAuthSetup-D4XqI8K4.js → GmailOAuthSetup-DtK4z83H.js} +1 -1
- package/dist/assets/{GoogleOAuthSetup-D4Q7Zkf1.js → GoogleOAuthSetup-CsxxXsHU.js} +1 -1
- package/dist/assets/{IframeModal-u9KddMkk.js → IframeModal-MlgHd01n.js} +1 -1
- package/dist/assets/{IntegrationsPanel-Bjj_cALx.js → IntegrationsPanel-Ci-4UMQg.js} +2 -2
- package/dist/assets/{LogViewerModal-CYpewZ36.js → LogViewerModal-1A5doXcl.js} +1 -1
- package/dist/assets/{MonitoringModal-DsRCjUvY.js → MonitoringModal-CgsxxYKS.js} +1 -1
- package/dist/assets/{PM2LogsModal-CoD0U27e.js → PM2LogsModal-g7HH5Va8.js} +1 -1
- package/dist/assets/{RestoreArchivedAreaModal-DyYrh0Dn.js → RestoreArchivedAreaModal-J4ANUsTT.js} +1 -1
- package/dist/assets/{Scene2DCanvas-LSpu3CMy.js → Scene2DCanvas-CS2Ec3fo.js} +1 -1
- package/dist/assets/{SceneManager-CoSgXbt6.js → SceneManager-B3KisMqb.js} +1 -1
- package/dist/assets/{SkillsPanel-DCOYtvqY.js → SkillsPanel-CcSLi_lV.js} +1 -1
- package/dist/assets/{SlackMultiInstanceSetup-DzwD7mdT.js → SlackMultiInstanceSetup-CkDgMh7O.js} +1 -1
- package/dist/assets/{SpawnModal-CYKMGe4A.js → SpawnModal-DDkDa4lH.js} +1 -1
- package/dist/assets/{StatisticsModal-Rsk3RBJ-.js → StatisticsModal-DefIHAFP.js} +1 -1
- package/dist/assets/{SubordinateAssignmentModal-D_fpOQfa.js → SubordinateAssignmentModal-HXgM72IC.js} +1 -1
- package/dist/assets/{TriggerManagerPanel-dO5Q66AM.js → TriggerManagerPanel-CuE7hxxv.js} +1 -1
- package/dist/assets/{WorkflowEditorPanel-ChFVP91n.js → WorkflowEditorPanel-CtNhGXaK.js} +1 -1
- package/dist/assets/{abnfDiagram-VRR7QNED-Bd736gc1.js → abnfDiagram-VRR7QNED-BUlnnP_1.js} +1 -1
- package/dist/assets/{arc-CicRk3Wa.js → arc-BBtryQAN.js} +1 -1
- package/dist/assets/{architectureDiagram-ZJ3FMSHR-uk1YbOOV.js → architectureDiagram-ZJ3FMSHR-C0kI5Z7d.js} +1 -1
- package/dist/assets/{area-logos-CtetiK8U.js → area-logos-BjCgZv0Z.js} +1 -1
- package/dist/assets/{blockDiagram-677ZJIJ3-CPr5yp_O.js → blockDiagram-677ZJIJ3-C3Qr8pSs.js} +1 -1
- package/dist/assets/{c4Diagram-LMCZKHZV-Cwhulsrr.js → c4Diagram-LMCZKHZV-BGNVz2Pl.js} +1 -1
- package/dist/assets/channel-DfrQjJNO.js +1 -0
- package/dist/assets/{chunk-2Q5K7J3B-DntPK0R4.js → chunk-2Q5K7J3B-BfRYa0Ce.js} +1 -1
- package/dist/assets/{chunk-32BRIVSS-DPGnMNRt.js → chunk-32BRIVSS-QaQwn5eJ.js} +1 -1
- package/dist/assets/{chunk-5VM5RSS4-HqD1WKnr.js → chunk-5VM5RSS4-CBz119og.js} +1 -1
- package/dist/assets/{chunk-EX3LRPZG-CnQzt-nk.js → chunk-EX3LRPZG-CjKB5rDB.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-96_obCN5.js → chunk-JWPE2WC7-BY_eTYH-.js} +1 -1
- package/dist/assets/{chunk-MOJQB5TN-CNhoYGDI.js → chunk-MOJQB5TN-D-jZu9aq.js} +1 -1
- package/dist/assets/{chunk-RYQCIY6F-B66k9-Zp.js → chunk-RYQCIY6F-9tDKSaCa.js} +1 -1
- package/dist/assets/{chunk-V7JOEXUC-CDq9VX4u.js → chunk-V7JOEXUC-DAcdz5JR.js} +1 -1
- package/dist/assets/{chunk-VR4S4FIN-BoUv9bdH.js → chunk-VR4S4FIN-D0Gs0s1C.js} +1 -1
- package/dist/assets/{chunk-XXDRQBXY-Bilx42me.js → chunk-XXDRQBXY-BbFQhnEi.js} +1 -1
- package/dist/assets/classDiagram-OUVF2IWQ-Cojz9UCF.js +1 -0
- package/dist/assets/classDiagram-v2-EOCWNBFH-Cojz9UCF.js +1 -0
- package/dist/assets/{cose-bilkent-JH36ORCC-BLO85xX-.js → cose-bilkent-JH36ORCC-C_Zzgy_G.js} +1 -1
- package/dist/assets/{cynefin-VYW2F7L2-WYLw8wuA.js → cynefin-VYW2F7L2-C8Z0Gw9s.js} +1 -1
- package/dist/assets/{cynefinDiagram-TSTJHNR4-LAbqztaC.js → cynefinDiagram-TSTJHNR4-C6iZsj7V.js} +1 -1
- package/dist/assets/{dagre-VKFMJZFB-CpnUxGz2.js → dagre-VKFMJZFB-BIMPhAGq.js} +1 -1
- package/dist/assets/{diagram-FQU43EPY-D4XAWe06.js → diagram-FQU43EPY-BT3deX2Y.js} +1 -1
- package/dist/assets/{diagram-G47NLZAW-CLgptSnw.js → diagram-G47NLZAW-RdBVaRH-.js} +1 -1
- package/dist/assets/{diagram-NH7WQ7WH-ClRPCJJG.js → diagram-NH7WQ7WH-DSr98n7w.js} +1 -1
- package/dist/assets/{diagram-OA4YK3LP-DAwXS8R3.js → diagram-OA4YK3LP-DVZbdjtc.js} +1 -1
- package/dist/assets/{diagram-WEI45ONY-B-um2qgR.js → diagram-WEI45ONY-BIrvSxLv.js} +1 -1
- package/dist/assets/{ebnfDiagram-CCIWWBDH-BuluWV6z.js → ebnfDiagram-CCIWWBDH-B3IYx45j.js} +1 -1
- package/dist/assets/{erDiagram-Q63AITRT-iViEXIuX.js → erDiagram-Q63AITRT-CV_YuDOI.js} +1 -1
- package/dist/assets/{flowDiagram-23GEKE2U-BB1xkRK-.js → flowDiagram-23GEKE2U-DYyiTzbJ.js} +1 -1
- package/dist/assets/{ganttDiagram-NO4QXBWP-Y056vaku.js → ganttDiagram-NO4QXBWP-CvnfbOAj.js} +1 -1
- package/dist/assets/{gitGraphDiagram-IHSO6WYX-RVnA3-Oq.js → gitGraphDiagram-IHSO6WYX-J_g1ozi2.js} +1 -1
- package/dist/assets/{index-GNffDlPO.js → index-9o_y4lu7.js} +3 -3
- package/dist/assets/{index-Dy4xURwo.js → index-BgKnXI_I.js} +1 -1
- package/dist/assets/{index-BsZHZI4z.js → index-BhAy_8sx.js} +1 -1
- package/dist/assets/{index-DIxINv38.js → index-CqZv3WSe.js} +1 -1
- package/dist/assets/{index-B6QXj8_t.js → index-CzsLF0a9.js} +1 -1
- package/dist/assets/{index-BMDcamyw.js → index-D9L5KXBG.js} +1 -1
- package/dist/assets/{index-BGc24jpF.js → index-DGGpeHyi.js} +2 -2
- package/dist/assets/{index-B_8jWBCl.js → index-DkcDKqa-.js} +1 -1
- package/dist/assets/{index-BukJVnzE.js → index-YquOzpmw.js} +1 -1
- package/dist/assets/{infoDiagram-FWYZ7A6U-B5GbrTtK.js → infoDiagram-FWYZ7A6U-D5Mm8I_o.js} +1 -1
- package/dist/assets/{ishikawaDiagram-FXEZZL3T-BAiw7b0j.js → ishikawaDiagram-FXEZZL3T-Ce9yNDRK.js} +1 -1
- package/dist/assets/{journeyDiagram-5HDEW3XC-CKR52gw7.js → journeyDiagram-5HDEW3XC-hK5WUkcb.js} +1 -1
- package/dist/assets/{kanban-definition-HUTT4EX6-CWrhHM6G.js → kanban-definition-HUTT4EX6-BIIQCAOg.js} +1 -1
- package/dist/assets/{linear-CAZvZbxC.js → linear-BBTmd6GJ.js} +1 -1
- package/dist/assets/main-Bt0ZVYXE.css +1 -0
- package/dist/assets/main-D0DYgXWa.js +299 -0
- package/dist/assets/{mermaid.core-8841kka_.js → mermaid.core-DxOQypXd.js} +4 -4
- package/dist/assets/{mindmap-definition-LN4V7U3C-CFOf-bER.js → mindmap-definition-LN4V7U3C-DopTVGAH.js} +1 -1
- package/dist/assets/{pegDiagram-2B236MQR-tiGmjXoe.js → pegDiagram-2B236MQR-BDFZz7xQ.js} +1 -1
- package/dist/assets/{pieDiagram-ENE6RG2P-ByoCrcjG.js → pieDiagram-ENE6RG2P-DUxtuyZ8.js} +1 -1
- package/dist/assets/{quadrantDiagram-ABIIQ3AL-D3njdqNJ.js → quadrantDiagram-ABIIQ3AL-CYQ6z89q.js} +1 -1
- package/dist/assets/{railroadDiagram-RFXS5EU6-Co1Qyv4I.js → railroadDiagram-RFXS5EU6-CPZeXSzB.js} +1 -1
- package/dist/assets/{requirementDiagram-TGXJPOKE-Bcc-ZmtM.js → requirementDiagram-TGXJPOKE-DS-bSy_p.js} +1 -1
- package/dist/assets/{sankeyDiagram-HTMAVEWB-NGc5ZbW2.js → sankeyDiagram-HTMAVEWB-BSf-G1Jv.js} +1 -1
- package/dist/assets/{sequenceDiagram-DBY2YBRQ-DMK9vu1q.js → sequenceDiagram-DBY2YBRQ-Bsbp5-fW.js} +1 -1
- package/dist/assets/{sizeCapture-X5ZJPWSS-fw74589N.js → sizeCapture-X5ZJPWSS-0oauMclt.js} +1 -1
- package/dist/assets/{stateDiagram-2N3HPSRC-Ct1CF4lH.js → stateDiagram-2N3HPSRC-DxjtPYnw.js} +1 -1
- package/dist/assets/stateDiagram-v2-6OUMAXLB-DgB5IYLl.js +1 -0
- package/dist/assets/{swimlanes-5IMT3BWC-BTA4j6h_.js → swimlanes-5IMT3BWC-ClT0R_qt.js} +2 -2
- package/dist/assets/swimlanesDiagram-G3AALYLV-D0FT2zjl.js +8 -0
- package/dist/assets/{timeline-definition-FHXFAJF6-Cdsu0GVG.js → timeline-definition-FHXFAJF6-B_adEXyf.js} +1 -1
- package/dist/assets/{vennDiagram-L72KCM5P-DpcwNBEA.js → vennDiagram-L72KCM5P-DHLTq5FV.js} +1 -1
- package/dist/assets/{wardleyDiagram-EHGQE667-B24yQ2jy.js → wardleyDiagram-EHGQE667-B1HJZmfL.js} +1 -1
- package/dist/assets/{web-Da6xoNEp.js → web-Bm712dX7.js} +1 -1
- package/dist/assets/{web-wlEp31pO.js → web-DmrF7XGy.js} +1 -1
- package/dist/assets/{web-DObpRERU.js → web-SQqqv-F3.js} +1 -1
- package/dist/assets/{xychartDiagram-FW5EYKEG-um8cUnVI.js → xychartDiagram-FW5EYKEG-D2QD2opl.js} +1 -1
- package/dist/build-info.json +1 -1
- package/dist/index.html +2 -2
- package/dist/locales/de/config.json +3 -1
- package/dist/locales/de/terminal.json +1 -0
- package/dist/locales/de/tools.json +10 -1
- package/dist/locales/en/config.json +2 -0
- package/dist/locales/en/terminal.json +1 -0
- package/dist/locales/en/tools.json +10 -1
- package/dist/locales/es/config.json +2 -0
- package/dist/locales/es/terminal.json +1 -0
- package/dist/locales/es/tools.json +10 -1
- package/dist/locales/fr/config.json +3 -1
- package/dist/locales/fr/terminal.json +1 -0
- package/dist/locales/fr/tools.json +10 -1
- package/dist/locales/hi/config.json +3 -1
- package/dist/locales/hi/terminal.json +1 -0
- package/dist/locales/hi/tools.json +10 -1
- package/dist/locales/it/config.json +3 -1
- package/dist/locales/it/terminal.json +1 -0
- package/dist/locales/it/tools.json +10 -1
- package/dist/locales/ja/config.json +3 -1
- package/dist/locales/ja/terminal.json +1 -0
- package/dist/locales/ja/tools.json +10 -1
- package/dist/locales/pt/config.json +3 -1
- package/dist/locales/pt/terminal.json +1 -0
- package/dist/locales/pt/tools.json +10 -1
- package/dist/locales/ru/config.json +3 -1
- package/dist/locales/ru/terminal.json +1 -0
- package/dist/locales/ru/tools.json +10 -1
- package/dist/locales/zh-CN/config.json +3 -1
- package/dist/locales/zh-CN/terminal.json +1 -0
- package/dist/locales/zh-CN/tools.json +10 -1
- package/dist/src/packages/server/opencode/server/opencode-server-event-adapter.js +21 -0
- package/dist/src/packages/server/opencode/server/opencode-server-process.js +52 -8
- package/dist/src/packages/server/opencode/server/opencode-server-runner.js +28 -0
- package/dist/src/packages/server/routes/files.js +25 -3
- package/package.json +1 -1
- package/dist/assets/channel-5_glBCpe.js +0 -1
- package/dist/assets/classDiagram-OUVF2IWQ-BvvPWiAV.js +0 -1
- package/dist/assets/classDiagram-v2-EOCWNBFH-BvvPWiAV.js +0 -1
- package/dist/assets/main-BgmmrYDn.js +0 -298
- package/dist/assets/main-Dhz40TGa.css +0 -1
- package/dist/assets/stateDiagram-v2-6OUMAXLB-CUuNeVFf.js +0 -1
- package/dist/assets/swimlanesDiagram-G3AALYLV-FjJqxVNN.js +0 -8
|
@@ -44,7 +44,8 @@
|
|
|
44
44
|
"attemptCompletion": "AttemptCompletion",
|
|
45
45
|
"listFiles": "ListFiles",
|
|
46
46
|
"searchFiles": "SearchFiles",
|
|
47
|
-
"executeCommand": "ExecuteCommand"
|
|
47
|
+
"executeCommand": "ExecuteCommand",
|
|
48
|
+
"viewImage": "Vedi immagine"
|
|
48
49
|
},
|
|
49
50
|
"showOutputsInline": "Mostra tutti gli output bash in linea",
|
|
50
51
|
"hideOutputsInline": "Nascondi gli output bash in linea"
|
|
@@ -273,5 +274,13 @@
|
|
|
273
274
|
"response": {
|
|
274
275
|
"noContent": "Nessun contenuto di risposta disponibile.",
|
|
275
276
|
"rawMarkdown": "Markdown grezzo"
|
|
277
|
+
},
|
|
278
|
+
"preview": {
|
|
279
|
+
"loading": "Caricamento anteprima…",
|
|
280
|
+
"emptyFile": "(file vuoto)",
|
|
281
|
+
"noDiff": "(nessun diff disponibile)",
|
|
282
|
+
"diffTruncated": "diff troncato…",
|
|
283
|
+
"moreLines": "+{{count}} righe in più",
|
|
284
|
+
"skippedLines": "… {{count}} righe omesse …"
|
|
276
285
|
}
|
|
277
286
|
}
|
|
@@ -38,7 +38,9 @@
|
|
|
38
38
|
"notifications": "通知",
|
|
39
39
|
"soundEffects": "効果音",
|
|
40
40
|
"streamTextLive": "単語ごとのストリーミング",
|
|
41
|
-
"streamTextLiveTitle": "Claude と Grok のテキスト/思考をストリーミング表示します。オフにすると完成した返答のみ表示します。"
|
|
41
|
+
"streamTextLiveTitle": "Claude と Grok のテキスト/思考をストリーミング表示します。オフにすると完成した返答のみ表示します。",
|
|
42
|
+
"toolHoverPreview": "Ctrl+ホバーのプレビュー",
|
|
43
|
+
"toolHoverPreviewTitle": "Ctrl を押しながらターミナルのツール行やファイルパスにカーソルを合わせると、ファイル・差分・画像・コマンド出力をプレビューできます。パネルはスクロールできます。"
|
|
42
44
|
},
|
|
43
45
|
"agentNames": {
|
|
44
46
|
"customConfigured": "{{count}}個のカスタム名が設定済み",
|
|
@@ -44,7 +44,8 @@
|
|
|
44
44
|
"attemptCompletion": "AttemptCompletion",
|
|
45
45
|
"listFiles": "ListFiles",
|
|
46
46
|
"searchFiles": "SearchFiles",
|
|
47
|
-
"executeCommand": "ExecuteCommand"
|
|
47
|
+
"executeCommand": "ExecuteCommand",
|
|
48
|
+
"viewImage": "画像を表示"
|
|
48
49
|
},
|
|
49
50
|
"showOutputsInline": "すべてのBash出力をインライン表示",
|
|
50
51
|
"hideOutputsInline": "インラインBash出力を非表示"
|
|
@@ -273,5 +274,13 @@
|
|
|
273
274
|
"response": {
|
|
274
275
|
"noContent": "レスポンス内容がありません。",
|
|
275
276
|
"rawMarkdown": "生Markdown"
|
|
277
|
+
},
|
|
278
|
+
"preview": {
|
|
279
|
+
"loading": "プレビューを読み込み中…",
|
|
280
|
+
"emptyFile": "(空のファイル)",
|
|
281
|
+
"noDiff": "(差分なし)",
|
|
282
|
+
"diffTruncated": "差分を省略…",
|
|
283
|
+
"moreLines": "他 {{count}} 行",
|
|
284
|
+
"skippedLines": "… {{count}} 行を省略 …"
|
|
276
285
|
}
|
|
277
286
|
}
|
|
@@ -38,7 +38,9 @@
|
|
|
38
38
|
"notifications": "Notificacoes",
|
|
39
39
|
"soundEffects": "Efeitos Sonoros",
|
|
40
40
|
"streamTextLive": "Streaming palavra a palavra",
|
|
41
|
-
"streamTextLiveTitle": "Mostrar texto/pensamento do Claude e Grok à medida que são gerados. Desative para ver apenas respostas completas."
|
|
41
|
+
"streamTextLiveTitle": "Mostrar texto/pensamento do Claude e Grok à medida que são gerados. Desative para ver apenas respostas completas.",
|
|
42
|
+
"toolHoverPreview": "Pré-visualização com Ctrl",
|
|
43
|
+
"toolHoverPreviewTitle": "Segure Ctrl ao passar o cursor sobre uma linha de ferramenta ou caminho de arquivo no terminal para ver o arquivo, o diff, a imagem ou a saída do comando. O painel pode ser rolado."
|
|
42
44
|
},
|
|
43
45
|
"agentNames": {
|
|
44
46
|
"customConfigured": "{{count}} nomes personalizados configurados",
|
|
@@ -44,7 +44,8 @@
|
|
|
44
44
|
"attemptCompletion": "AttemptCompletion",
|
|
45
45
|
"listFiles": "ListFiles",
|
|
46
46
|
"searchFiles": "SearchFiles",
|
|
47
|
-
"executeCommand": "ExecuteCommand"
|
|
47
|
+
"executeCommand": "ExecuteCommand",
|
|
48
|
+
"viewImage": "Ver imagem"
|
|
48
49
|
},
|
|
49
50
|
"showOutputsInline": "Mostrar todas as saídas do bash em linha",
|
|
50
51
|
"hideOutputsInline": "Ocultar as saídas do bash em linha"
|
|
@@ -273,5 +274,13 @@
|
|
|
273
274
|
"response": {
|
|
274
275
|
"noContent": "Nenhum conteudo de resposta disponivel.",
|
|
275
276
|
"rawMarkdown": "Markdown Bruto"
|
|
277
|
+
},
|
|
278
|
+
"preview": {
|
|
279
|
+
"loading": "Carregando pré-visualização…",
|
|
280
|
+
"emptyFile": "(arquivo vazio)",
|
|
281
|
+
"noDiff": "(nenhum diff disponível)",
|
|
282
|
+
"diffTruncated": "diff truncado…",
|
|
283
|
+
"moreLines": "+{{count}} linhas a mais",
|
|
284
|
+
"skippedLines": "… {{count}} linhas omitidas …"
|
|
276
285
|
}
|
|
277
286
|
}
|
|
@@ -38,7 +38,9 @@
|
|
|
38
38
|
"notifications": "Уведомления",
|
|
39
39
|
"soundEffects": "Звуковые эффекты",
|
|
40
40
|
"streamTextLive": "Потоковая передача по словам",
|
|
41
|
-
"streamTextLiveTitle": "Показывать текст/мысли Claude и Grok по мере генерации. Отключите, чтобы видеть только готовые ответы."
|
|
41
|
+
"streamTextLiveTitle": "Показывать текст/мысли Claude и Grok по мере генерации. Отключите, чтобы видеть только готовые ответы.",
|
|
42
|
+
"toolHoverPreview": "Предпросмотр по Ctrl",
|
|
43
|
+
"toolHoverPreviewTitle": "Удерживайте Ctrl при наведении на строку инструмента или путь к файлу в терминале, чтобы увидеть файл, diff, изображение или вывод команды. Панель можно прокручивать."
|
|
42
44
|
},
|
|
43
45
|
"agentNames": {
|
|
44
46
|
"customConfigured": "{{count}} пользовательских имён настроено",
|
|
@@ -44,7 +44,8 @@
|
|
|
44
44
|
"attemptCompletion": "AttemptCompletion",
|
|
45
45
|
"listFiles": "ListFiles",
|
|
46
46
|
"searchFiles": "SearchFiles",
|
|
47
|
-
"executeCommand": "ExecuteCommand"
|
|
47
|
+
"executeCommand": "ExecuteCommand",
|
|
48
|
+
"viewImage": "Просмотр изображения"
|
|
48
49
|
},
|
|
49
50
|
"showOutputsInline": "Показывать все выводы bash в строке",
|
|
50
51
|
"hideOutputsInline": "Скрыть встроенные выводы bash"
|
|
@@ -273,5 +274,13 @@
|
|
|
273
274
|
"response": {
|
|
274
275
|
"noContent": "Содержимое ответа недоступно.",
|
|
275
276
|
"rawMarkdown": "Исходный Markdown"
|
|
277
|
+
},
|
|
278
|
+
"preview": {
|
|
279
|
+
"loading": "Загрузка предпросмотра…",
|
|
280
|
+
"emptyFile": "(пустой файл)",
|
|
281
|
+
"noDiff": "(нет доступных изменений)",
|
|
282
|
+
"diffTruncated": "diff усечён…",
|
|
283
|
+
"moreLines": "+{{count}} строк ещё",
|
|
284
|
+
"skippedLines": "… пропущено строк: {{count}} …"
|
|
276
285
|
}
|
|
277
286
|
}
|
|
@@ -38,7 +38,9 @@
|
|
|
38
38
|
"notifications": "通知",
|
|
39
39
|
"soundEffects": "音效",
|
|
40
40
|
"streamTextLive": "逐字流式输出",
|
|
41
|
-
"streamTextLiveTitle": "实时显示 Claude 和 Grok 的文本/思考。关闭后仅显示完整回复。"
|
|
41
|
+
"streamTextLiveTitle": "实时显示 Claude 和 Grok 的文本/思考。关闭后仅显示完整回复。",
|
|
42
|
+
"toolHoverPreview": "Ctrl 悬停预览",
|
|
43
|
+
"toolHoverPreviewTitle": "在终端中按住 Ctrl 并将鼠标悬停在工具行或文件路径上,即可预览文件、差异、图片或命令输出。面板可滚动。"
|
|
42
44
|
},
|
|
43
45
|
"agentNames": {
|
|
44
46
|
"customConfigured": "已配置 {{count}} 个自定义名称",
|
|
@@ -44,7 +44,8 @@
|
|
|
44
44
|
"attemptCompletion": "尝试完成",
|
|
45
45
|
"listFiles": "列出文件",
|
|
46
46
|
"searchFiles": "搜索文件",
|
|
47
|
-
"executeCommand": "执行命令"
|
|
47
|
+
"executeCommand": "执行命令",
|
|
48
|
+
"viewImage": "查看图片"
|
|
48
49
|
},
|
|
49
50
|
"showOutputsInline": "内联显示所有 Bash 输出",
|
|
50
51
|
"hideOutputsInline": "隐藏内联 Bash 输出"
|
|
@@ -273,5 +274,13 @@
|
|
|
273
274
|
"response": {
|
|
274
275
|
"noContent": "没有可用的响应内容。",
|
|
275
276
|
"rawMarkdown": "原始 Markdown"
|
|
277
|
+
},
|
|
278
|
+
"preview": {
|
|
279
|
+
"loading": "正在加载预览…",
|
|
280
|
+
"emptyFile": "(空文件)",
|
|
281
|
+
"noDiff": "(无可用差异)",
|
|
282
|
+
"diffTruncated": "差异已截断…",
|
|
283
|
+
"moreLines": "还有 {{count}} 行",
|
|
284
|
+
"skippedLines": "… 已跳过 {{count}} 行 …"
|
|
276
285
|
}
|
|
277
286
|
}
|
|
@@ -37,11 +37,23 @@ export class OpencodeServerEventAdapter {
|
|
|
37
37
|
partType = new Map();
|
|
38
38
|
lastTokens;
|
|
39
39
|
lastCost;
|
|
40
|
+
/** True once actual CONTENT flowed (message.part.* events) since the last
|
|
41
|
+
* finalized turn. A `session.idle` with no content behind it is a stale
|
|
42
|
+
* duplicate: aborting a turn double-fires idle, and the second one lands
|
|
43
|
+
* AFTER the next turn already started, which used to finalize that new turn
|
|
44
|
+
* prematurely (agent flipped idle while the model was still generating).
|
|
45
|
+
* Only part events arm this — the abort fallout replays a `message.updated`
|
|
46
|
+
* (metadata of the aborted message) BETWEEN the two idles, so metadata must
|
|
47
|
+
* not count as activity (captured live: error → idle#1 → message.updated →
|
|
48
|
+
* idle#2). */
|
|
49
|
+
sawActivity = false;
|
|
40
50
|
handle(event) {
|
|
41
51
|
const type = event.type;
|
|
42
52
|
if (!type)
|
|
43
53
|
return [];
|
|
44
54
|
const props = event.properties || {};
|
|
55
|
+
if (type === 'message.part.delta' || type === 'message.part.updated')
|
|
56
|
+
this.sawActivity = true;
|
|
45
57
|
switch (type) {
|
|
46
58
|
case 'message.part.delta': {
|
|
47
59
|
// OpenCode streams a part for the USER message too (the prompt itself);
|
|
@@ -91,6 +103,8 @@ export class OpencodeServerEventAdapter {
|
|
|
91
103
|
return [];
|
|
92
104
|
}
|
|
93
105
|
case 'session.idle':
|
|
106
|
+
if (!this.sawActivity)
|
|
107
|
+
return [];
|
|
94
108
|
return this.finalizeTurn();
|
|
95
109
|
case 'session.error': {
|
|
96
110
|
const err = props.error;
|
|
@@ -127,6 +141,12 @@ export class OpencodeServerEventAdapter {
|
|
|
127
141
|
}
|
|
128
142
|
return events;
|
|
129
143
|
}
|
|
144
|
+
/** Finalize unconditionally — for the runner's POST-resolution fallback,
|
|
145
|
+
* which fires when a turn ended server-side but its session.idle never
|
|
146
|
+
* arrived (so the activity gate must not apply). */
|
|
147
|
+
forceFinalize() {
|
|
148
|
+
return this.finalizeTurn();
|
|
149
|
+
}
|
|
130
150
|
finalizeTurn() {
|
|
131
151
|
// Feed a synthetic step_finish so the parser finalizes any open streaming
|
|
132
152
|
// rows and emits usage_snapshot + step_complete (with resultText from the
|
|
@@ -152,6 +172,7 @@ export class OpencodeServerEventAdapter {
|
|
|
152
172
|
this.toolDone.clear();
|
|
153
173
|
this.lastTokens = undefined;
|
|
154
174
|
this.lastCost = undefined;
|
|
175
|
+
this.sawActivity = false;
|
|
155
176
|
return events;
|
|
156
177
|
}
|
|
157
178
|
}
|
|
@@ -2,12 +2,18 @@
|
|
|
2
2
|
* OpencodeServerProcess
|
|
3
3
|
*
|
|
4
4
|
* Manages a DETACHED, restart-surviving `opencode serve` HTTP server and speaks
|
|
5
|
-
* its API: one SSE stream (`GET /event`) carries every session's events
|
|
5
|
+
* its API: one SSE stream (`GET /global/event`) carries every session's events
|
|
6
6
|
* (word-by-word `message.part.delta`), and prompts/sessions/aborts go over plain
|
|
7
7
|
* HTTP. One server multiplexes every OpenCode agent — each agent owns a
|
|
8
8
|
* `sessionID`, and every event carries `properties.sessionID` so the runner can
|
|
9
9
|
* fan them back out.
|
|
10
10
|
*
|
|
11
|
+
* The stream MUST be `/global/event`: the plain `/event` endpoint is
|
|
12
|
+
* PROJECT-SCOPED (resolved from the request's directory, defaulting to the
|
|
13
|
+
* daemon's cwd), so a subscription there silently drops every event from
|
|
14
|
+
* sessions living in any other working directory — those agents then get no
|
|
15
|
+
* deltas and no `session.idle`, wedging them in 'working' forever.
|
|
16
|
+
*
|
|
11
17
|
* Why detached + HTTP/SSE (vs `opencode run` per turn): `opencode run --format
|
|
12
18
|
* json` emits one full assistant message (no token deltas), and a child process
|
|
13
19
|
* dies with the commander. A detached server bound to a localhost port survives
|
|
@@ -31,6 +37,9 @@ export class OpencodeServerProcess {
|
|
|
31
37
|
stopped = false;
|
|
32
38
|
connected = false;
|
|
33
39
|
reconnectedToExisting = false;
|
|
40
|
+
/** Set once `/global/event` came back non-200 (older opencode) — stick to the
|
|
41
|
+
* legacy project-scoped `/event` stream from then on. */
|
|
42
|
+
legacyEventStream = false;
|
|
34
43
|
constructor(opts) {
|
|
35
44
|
this.opts = opts;
|
|
36
45
|
}
|
|
@@ -97,11 +106,22 @@ export class OpencodeServerProcess {
|
|
|
97
106
|
}
|
|
98
107
|
throw new Error('opencode server /api/health never became healthy');
|
|
99
108
|
}
|
|
100
|
-
/** Open the single
|
|
109
|
+
/** Open the single all-projects SSE stream (`/global/event`) and parse
|
|
110
|
+
* `data:` frames. Falls back to the legacy project-scoped `/event` on
|
|
111
|
+
* daemons too old to serve the global stream. */
|
|
101
112
|
openSse() {
|
|
102
113
|
if (this.stopped)
|
|
103
114
|
return;
|
|
104
|
-
const
|
|
115
|
+
const path = this.legacyEventStream ? '/event' : '/global/event';
|
|
116
|
+
const req = http.get(`${this.baseUrl}${path}`, { headers: { Accept: 'text/event-stream' } }, (res) => {
|
|
117
|
+
if (res.statusCode !== 200 && !this.legacyEventStream) {
|
|
118
|
+
log.warn(`GET /global/event → HTTP ${res.statusCode}; falling back to legacy project-scoped /event`);
|
|
119
|
+
this.legacyEventStream = true;
|
|
120
|
+
this.sseReq = null; // guard: the destroyed request's error/end must not trigger a reconnect
|
|
121
|
+
req.destroy();
|
|
122
|
+
this.openSse();
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
105
125
|
res.setEncoding('utf8');
|
|
106
126
|
let buffer = '';
|
|
107
127
|
res.on('data', (chunk) => {
|
|
@@ -114,10 +134,15 @@ export class OpencodeServerProcess {
|
|
|
114
134
|
this.handleFrame(frame);
|
|
115
135
|
}
|
|
116
136
|
});
|
|
117
|
-
res.on('end', () =>
|
|
137
|
+
res.on('end', () => {
|
|
138
|
+
if (this.sseReq === req)
|
|
139
|
+
this.handleSseClosed();
|
|
140
|
+
});
|
|
118
141
|
});
|
|
119
142
|
this.sseReq = req;
|
|
120
143
|
req.on('error', (err) => {
|
|
144
|
+
if (this.sseReq !== req)
|
|
145
|
+
return;
|
|
121
146
|
log.warn(`SSE connection error: ${err.message}`);
|
|
122
147
|
this.handleSseClosed();
|
|
123
148
|
});
|
|
@@ -140,7 +165,7 @@ export class OpencodeServerProcess {
|
|
|
140
165
|
catch {
|
|
141
166
|
return;
|
|
142
167
|
}
|
|
143
|
-
this.opts.onEvent(evt);
|
|
168
|
+
this.opts.onEvent(unwrapGlobalSseEvent(evt));
|
|
144
169
|
}
|
|
145
170
|
handleSseClosed() {
|
|
146
171
|
this.sseReq = null;
|
|
@@ -273,10 +298,10 @@ export class OpencodeServerProcess {
|
|
|
273
298
|
async activeSessionIds() {
|
|
274
299
|
try {
|
|
275
300
|
const resp = await this.httpJson('GET', '/api/session/active');
|
|
276
|
-
const
|
|
301
|
+
const raw = resp?.data ?? resp;
|
|
277
302
|
const ids = new Set();
|
|
278
|
-
if (Array.isArray(
|
|
279
|
-
for (const item of
|
|
303
|
+
if (Array.isArray(raw)) {
|
|
304
|
+
for (const item of raw) {
|
|
280
305
|
if (typeof item === 'string')
|
|
281
306
|
ids.add(item);
|
|
282
307
|
else if (item?.id)
|
|
@@ -285,6 +310,13 @@ export class OpencodeServerProcess {
|
|
|
285
310
|
ids.add(item.sessionID);
|
|
286
311
|
}
|
|
287
312
|
}
|
|
313
|
+
else if (raw && typeof raw === 'object') {
|
|
314
|
+
// 1.18.x returns a map keyed by sessionID: {"ses_…": {…}}
|
|
315
|
+
for (const key of Object.keys(raw)) {
|
|
316
|
+
if (key.startsWith('ses'))
|
|
317
|
+
ids.add(key);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
288
320
|
return ids;
|
|
289
321
|
}
|
|
290
322
|
catch {
|
|
@@ -316,6 +348,18 @@ export class OpencodeServerProcess {
|
|
|
316
348
|
clearDaemonInfo();
|
|
317
349
|
}
|
|
318
350
|
}
|
|
351
|
+
/**
|
|
352
|
+
* `/global/event` wraps every bus event as `{directory, project, payload: {id,
|
|
353
|
+
* type, properties}}`, while the legacy `/event` stream delivers the inner
|
|
354
|
+
* shape directly. Unwrap the envelope so downstream routing sees ONE shape.
|
|
355
|
+
*/
|
|
356
|
+
export function unwrapGlobalSseEvent(evt) {
|
|
357
|
+
const payload = evt.payload;
|
|
358
|
+
if (payload && typeof payload === 'object' && typeof payload.type === 'string') {
|
|
359
|
+
return payload;
|
|
360
|
+
}
|
|
361
|
+
return evt;
|
|
362
|
+
}
|
|
319
363
|
function isPidAlive(pid) {
|
|
320
364
|
if (!pid || pid < 1)
|
|
321
365
|
return false;
|
|
@@ -26,6 +26,9 @@ import { createLogger } from '../../utils/logger.js';
|
|
|
26
26
|
import { withAgentContext } from '../../utils/log-context.js';
|
|
27
27
|
const log = createLogger('OpencodeServerRunner');
|
|
28
28
|
const RECOVER_DELAY_MS = 1500;
|
|
29
|
+
/** How long after the turn's message POST resolves (= turn ended server-side)
|
|
30
|
+
* to wait for the real `session.idle` before force-finalizing the turn. */
|
|
31
|
+
const POST_IDLE_GRACE_MS = 3000;
|
|
29
32
|
export class OpencodeServerRunner {
|
|
30
33
|
callbacks;
|
|
31
34
|
backend = new OpencodeBackend();
|
|
@@ -98,6 +101,7 @@ export class OpencodeServerRunner {
|
|
|
98
101
|
lastActivityTime: Date.now(),
|
|
99
102
|
lastRequest: p.lastRequest,
|
|
100
103
|
queue: [],
|
|
104
|
+
turnSeq: 0,
|
|
101
105
|
};
|
|
102
106
|
this.agents.set(p.agentId, state);
|
|
103
107
|
this.sessionToAgent.set(p.sessionId, p.agentId);
|
|
@@ -169,6 +173,12 @@ export class OpencodeServerRunner {
|
|
|
169
173
|
}
|
|
170
174
|
}
|
|
171
175
|
}
|
|
176
|
+
// A step_complete for a turn that's already finalized (the POST-resolution
|
|
177
|
+
// fallback raced the real session.idle, or the server double-fired idle)
|
|
178
|
+
// must be dropped whole — re-emitting would render a spurious
|
|
179
|
+
// "(Empty response)" row and double-fire onComplete/drainQueue.
|
|
180
|
+
if (event.type === 'step_complete' && state.turnState !== 'processing')
|
|
181
|
+
return;
|
|
172
182
|
this.pipeline.emitStandardEvent(agentId, event);
|
|
173
183
|
if (event.type === 'step_complete') {
|
|
174
184
|
state.turnState = 'waiting_for_input';
|
|
@@ -228,6 +238,7 @@ export class OpencodeServerRunner {
|
|
|
228
238
|
lastActivityTime: Date.now(),
|
|
229
239
|
lastRequest: request,
|
|
230
240
|
queue: [],
|
|
241
|
+
turnSeq: 0,
|
|
231
242
|
};
|
|
232
243
|
this.agents.set(agentId, state);
|
|
233
244
|
this.sessionToAgent.set(sessionId, agentId);
|
|
@@ -266,8 +277,25 @@ export class OpencodeServerRunner {
|
|
|
266
277
|
const promptText = buildOpencodePrompt(config);
|
|
267
278
|
state.turnState = 'processing';
|
|
268
279
|
state.lastActivityTime = Date.now();
|
|
280
|
+
state.turnSeq += 1;
|
|
281
|
+
const seq = state.turnSeq;
|
|
269
282
|
try {
|
|
270
283
|
await proc.sendPrompt(state.sessionId, promptText, this.modelRef(state.lastRequest.model));
|
|
284
|
+
// opencode holds the message POST open for the ENTIRE turn, so resolving
|
|
285
|
+
// means the turn already ended server-side. `session.idle` over SSE is
|
|
286
|
+
// the normal finalizer — but if it doesn't land shortly after (missed
|
|
287
|
+
// frame, broken/mis-scoped stream), force-finalize so one lost event can
|
|
288
|
+
// never wedge the agent in 'working' with its queue backing up forever.
|
|
289
|
+
setTimeout(() => {
|
|
290
|
+
if (this.agents.get(agentId) !== state)
|
|
291
|
+
return;
|
|
292
|
+
if (state.turnSeq !== seq || state.turnState !== 'processing')
|
|
293
|
+
return;
|
|
294
|
+
log.warn(`Turn POST resolved but no session.idle after ${POST_IDLE_GRACE_MS}ms for ${agentId.slice(0, 8)}; force-finalizing turn`);
|
|
295
|
+
for (const event of state.adapter.forceFinalize()) {
|
|
296
|
+
this.applyEvent(agentId, state, event);
|
|
297
|
+
}
|
|
298
|
+
}, POST_IDLE_GRACE_MS);
|
|
271
299
|
}
|
|
272
300
|
catch (err) {
|
|
273
301
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -549,17 +549,39 @@ router.get('/read', async (req, res) => {
|
|
|
549
549
|
const content = fs.readFileSync(filePath, 'utf-8');
|
|
550
550
|
const extension = path.extname(filePath).toLowerCase();
|
|
551
551
|
const filename = path.basename(filePath);
|
|
552
|
-
|
|
552
|
+
const base = {
|
|
553
553
|
path: filePath,
|
|
554
554
|
filename,
|
|
555
555
|
extension,
|
|
556
|
-
content,
|
|
557
556
|
size: stats.size,
|
|
558
557
|
modified: stats.mtime,
|
|
559
558
|
strategy: resolution.strategy,
|
|
560
559
|
areaId: resolution.areaId,
|
|
561
560
|
areaName: resolution.areaName,
|
|
562
|
-
}
|
|
561
|
+
};
|
|
562
|
+
// Preview mode (Ctrl+hover tooltip in the terminal): return only the
|
|
563
|
+
// requested line window. Reading the file is cheap; shipping a 1MB body
|
|
564
|
+
// over the wire on every hover is not.
|
|
565
|
+
const previewLines = Number(req.query.previewLines);
|
|
566
|
+
if (Number.isFinite(previewLines) && previewLines > 0) {
|
|
567
|
+
const allLines = content.split('\n');
|
|
568
|
+
const rawOffset = Number(req.query.previewOffset);
|
|
569
|
+
const startLine = Number.isFinite(rawOffset) && rawOffset >= 1
|
|
570
|
+
? Math.min(Math.floor(rawOffset), Math.max(allLines.length, 1))
|
|
571
|
+
: 1;
|
|
572
|
+
const slice = allLines.slice(startLine - 1, startLine - 1 + Math.floor(previewLines));
|
|
573
|
+
res.json({
|
|
574
|
+
...base,
|
|
575
|
+
content: slice.join('\n'),
|
|
576
|
+
preview: {
|
|
577
|
+
startLine,
|
|
578
|
+
totalLines: allLines.length,
|
|
579
|
+
truncated: startLine - 1 + slice.length < allLines.length,
|
|
580
|
+
},
|
|
581
|
+
});
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
584
|
+
res.json({ ...base, content });
|
|
563
585
|
}
|
|
564
586
|
catch (err) {
|
|
565
587
|
log.error(' Failed to read file:', err);
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{U as a,C as n}from"./mermaid.core-8841kka_.js";const t=(r,o)=>a.lang.round(n.parse(r)[o]);export{t as c};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,c as s,a as e,C as t}from"./chunk-V7JOEXUC-CDq9VX4u.js";import{_ as i}from"./mermaid.core-8841kka_.js";import"./chunk-5VM5RSS4-HqD1WKnr.js";import"./chunk-XXDRQBXY-Bilx42me.js";import"./chunk-VR4S4FIN-BoUv9bdH.js";import"./chunk-32BRIVSS-DPGnMNRt.js";import"./main-BgmmrYDn.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-3OKhI9bz.js";var b={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{b as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,c as s,a as e,C as t}from"./chunk-V7JOEXUC-CDq9VX4u.js";import{_ as i}from"./mermaid.core-8841kka_.js";import"./chunk-5VM5RSS4-HqD1WKnr.js";import"./chunk-XXDRQBXY-Bilx42me.js";import"./chunk-VR4S4FIN-BoUv9bdH.js";import"./chunk-32BRIVSS-DPGnMNRt.js";import"./main-BgmmrYDn.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-3OKhI9bz.js";var b={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{b as diagram};
|