@toddzheng024/dscode-bundle 0.7.1 → 0.7.2
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/package.json +1 -1
- package/plugins/auto-review/index.mjs +21 -3
- package/plugins/auto-review/policy.mjs +25 -0
- package/plugins/i18n/messages.mjs +6 -6
- package/plugins/session-metrics/balance.mjs +52 -0
- package/plugins/session-metrics/index.mjs +18 -0
- package/plugins/session-metrics/pricing.mjs +16 -2
- package/plugins/session-metrics/view.mjs +34 -15
- package/vendor/persistent/index.js +19 -2
- package/vendor/tui/index.mjs +167 -239
- package/vendor/tui/.dscode-viewport-probe-78546.mjs +0 -39239
- package/vendor/tui/dscode-email.mjs +0 -69
package/vendor/tui/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// dscode-language-v2
|
|
2
2
|
// dscode-language-v1
|
|
3
3
|
const DSCODE_LANGUAGES = [{"code":"en","name":"English"},{"code":"zh-CN","name":"简体中文"},{"code":"zh-TW","name":"繁體中文"},{"code":"ja","name":"日本語"},{"code":"ko","name":"한국어"},{"code":"es","name":"Español"}];
|
|
4
|
-
const DSCODE_MESSAGES = {"en":{"activity.replying":"Replying","activity.thinking":"Thinking","activity.running":"Running","activity.turn":"this turn","activity.interrupt":"Esc to interrupt","agents.running":"running","agents.idle":"idle","agents.done":"done","agents.total":"total","welcome.model":"model","welcome.effort":"effort","welcome.project":"project","verbose.on":"verbose on: thinking and tool calls are shown in the chat","verbose.off":"verbose off","mouse.on":"mouse on: the wheel scrolls the chat · hold Shift while dragging to select text (Option in iTerm2, Fn in Terminal)","mouse.off":"mouse off: select and copy freely · PageUp/PageDown scroll the chat · /mouse turns wheel scrolling on","language.current":"Language: {name} · /language en | zh-CN | zh-TW | ja | ko | es","language.set":"language → {name}","language.title":"/language — interface language","language.currentMark":"current","language.unknown":"Unknown language \"{value}\". Choose en, zh-CN, zh-TW, ja, ko or es.","language.saveFailed":"language save failed: {error}","doctor.logs.new":"Only warnings/errors since this TUI version started are recorded.","footer.current":"current","footer.average":"average","footer.context":"context","footer.cache":"cache","composer.placeholder":"type a message","doctor.nearTimeout":"Assessment: {count} Bash calls ended at about 300 seconds, which matches the tool timeout; traces alone cannot prove the root cause. Next, check those calls' shell completion markers and terminal errors.","doctor.logs.none":"No log file yet; earlier console logs were not persisted and cannot be recovered.","doctor.evidence":"Diagnostic evidence: {traces} recent sessions, {logs} warnings/errors.","doctor.noFindings":"No clear timeouts, unfinished tool calls or error events in recent traces.","doctor.noRoute":"No model route is available, so the model analysis could not run.","doctor.scope":"Evidence scope: {traces} recent sessions, {logs} warnings/errors; conversation text, tool arguments and tool output were not read.","doctor.failed":"Model analysis did not finish: {error}."},"zh-CN":{"activity.replying":"正在回复","activity.thinking":"正在思考","activity.running":"正在执行","activity.turn":"本轮","activity.interrupt":"Esc 中断","agents.running":"运行中","agents.idle":"空闲","agents.done":"已完成","agents.total":"总计","welcome.model":"模型","welcome.effort":"推理","welcome.project":"项目","verbose.on":"详细模式已开启:对话中显示思考与工具调用","verbose.off":"详细模式已关闭","mouse.on":"鼠标捕获已开启:滚轮滚动对话 · 拖选文本时按住 Shift(iTerm2 按住 Option、Terminal 按住 Fn)","mouse.off":"鼠标捕获已关闭:可自由选择复制 · PageUp/PageDown 滚动对话 · /mouse 重新开启","language.current":"语言:{name} · /language en | zh-CN | zh-TW | ja | ko | es","language.set":"语言 → {name}","language.title":"/language — 界面语言","language.currentMark":"当前","language.unknown":"未知语言 \"{value}\"。可选 en、zh-CN、zh-TW、ja、ko、es。","language.saveFailed":"语言设置保存失败:{error}","doctor.logs.new":"仅记录新版 TUI 启动后的 warning/error。","footer.current":"当前","footer.average":"平均","footer.context":"上下文","footer.cache":"缓存","composer.placeholder":"输入消息","doctor.nearTimeout":"判断:{count} 次 Bash 调用在约 300 秒结束,符合工具超时特征;trace 不能单独证明触发超时的根因。下一步检查这些调用的 shell 完成标记和终端错误。","doctor.logs.none":"日志文件尚未建立;旧版控制台日志未持久化,无法回溯。","doctor.evidence":"诊断证据:{traces} 个近期会话、{logs} 条 warning/error。","doctor.noFindings":"近期 trace 中未发现明确的超时、未完成工具调用或错误事件。","doctor.noRoute":"没有可用的模型路由,无法运行模型分析。","doctor.scope":"证据范围:{traces} 个近期会话、{logs} 条 warning/error;未读取对话正文、工具参数或工具输出。","doctor.failed":"模型分析未完成:{error}。"},"zh-TW":{"activity.replying":"正在回覆","activity.thinking":"正在思考","activity.running":"正在執行","activity.turn":"本輪","activity.interrupt":"Esc 中斷","agents.running":"執行中","agents.idle":"閒置","agents.done":"已完成","agents.total":"總計","welcome.model":"模型","welcome.effort":"推理","welcome.project":"專案","verbose.on":"詳細模式已開啟:對話中顯示思考與工具呼叫","verbose.off":"詳細模式已關閉","mouse.on":"滑鼠擷取已開啟:滾輪捲動對話 · 拖選文字時按住 Shift(iTerm2 按住 Option、Terminal 按住 Fn)","mouse.off":"滑鼠擷取已關閉:可自由選取複製 · PageUp/PageDown 捲動對話 · /mouse 重新開啟","language.current":"語言:{name} · /language en | zh-CN | zh-TW | ja | ko | es","language.set":"語言 → {name}","language.title":"/language — 介面語言","language.currentMark":"目前","language.unknown":"未知語言 \"{value}\"。可選 en、zh-CN、zh-TW、ja、ko、es。","language.saveFailed":"語言設定儲存失敗:{error}","doctor.logs.new":"僅記錄新版 TUI 啟動後的 warning/error。","footer.current":"目前","footer.average":"平均","footer.context":"上下文","footer.cache":"快取","composer.placeholder":"輸入訊息","doctor.nearTimeout":"判斷:{count} 次 Bash 呼叫在約 300 秒結束,符合工具逾時特徵;trace 無法單獨證明觸發逾時的根因。下一步檢查這些呼叫的 shell 完成標記和終端錯誤。","doctor.logs.none":"日誌檔尚未建立;舊版主控台日誌未持久化,無法回溯。","doctor.evidence":"診斷證據:{traces} 個近期工作階段、{logs} 筆 warning/error。","doctor.noFindings":"近期 trace 中未發現明確的逾時、未完成工具呼叫或錯誤事件。","doctor.noRoute":"沒有可用的模型路由,無法執行模型分析。","doctor.scope":"證據範圍:{traces} 個近期工作階段、{logs} 筆 warning/error;未讀取對話內容、工具參數或工具輸出。","doctor.failed":"模型分析未完成:{error}。"},"ja":{"activity.replying":"応答中","activity.thinking":"思考中","activity.running":"実行中","activity.turn":"今回のターン","activity.interrupt":"Esc で中断","agents.running":"実行中","agents.idle":"待機中","agents.done":"完了","agents.total":"合計","welcome.model":"モデル","welcome.effort":"推論","welcome.project":"プロジェクト","verbose.on":"詳細モード オン:思考とツール呼び出しをチャットに表示します","verbose.off":"詳細モード オフ","mouse.on":"マウス キャプチャ オン:ホイールでチャットをスクロール · Shift(iTerm2 は Option、Terminal は Fn)を押しながらドラッグでテキスト選択","mouse.off":"マウス キャプチャ オフ:自由に選択・コピーできます · PageUp/PageDown でスクロール · /mouse で再びオン","language.current":"言語:{name} · /language en | zh-CN | zh-TW | ja | ko | es","language.set":"言語 → {name}","language.title":"/language — 表示言語","language.currentMark":"現在","language.unknown":"不明な言語 \"{value}\"。en、zh-CN、zh-TW、ja、ko、es から選んでください。","language.saveFailed":"言語設定の保存に失敗しました:{error}","doctor.logs.new":"この TUI バージョンの起動以降の warning/error のみ記録されています。","footer.current":"現在","footer.average":"平均","footer.context":"コンテキスト","footer.cache":"キャッシュ","composer.placeholder":"メッセージを入力","doctor.nearTimeout":"判断:Bash 呼び出し {count} 件が約 300 秒で終了しており、ツールのタイムアウトの特徴に一致します。トレースだけでは根本原因を証明できません。次はこれらの呼び出しのシェル完了マーカーと端末エラーを確認してください。","doctor.logs.none":"ログファイルはまだありません。以前のコンソールログは保存されておらず、遡れません。","doctor.evidence":"診断の根拠:直近のセッション {traces} 件、warning/error {logs} 件。","doctor.noFindings":"直近のトレースに明確なタイムアウト、未完了ツール、停滞は見つかりませんでした。","doctor.noRoute":"利用できるモデルルートがないため、モデル分析を実行できません。","doctor.scope":"根拠の範囲:直近のセッション {traces} 件、warning/error {logs} 件。会話本文、ツール引数、ツール出力は読んでいません。","doctor.failed":"モデル分析が完了しませんでした:{error}。"},"ko":{"activity.replying":"응답 중","activity.thinking":"생각 중","activity.running":"실행 중","activity.turn":"이번 턴","activity.interrupt":"Esc 중단","agents.running":"실행 중","agents.idle":"대기","agents.done":"완료","agents.total":"전체","welcome.model":"모델","welcome.effort":"추론","welcome.project":"프로젝트","verbose.on":"상세 모드 켜짐: 생각과 도구 호출을 채팅에 표시합니다","verbose.off":"상세 모드 꺼짐","mouse.on":"마우스 캡처 켜짐: 휠로 채팅 스크롤 · Shift(iTerm2는 Option, Terminal은 Fn)를 누른 채 드래그하여 텍스트 선택","mouse.off":"마우스 캡처 꺼짐: 자유롭게 선택·복사 · PageUp/PageDown으로 채팅 스크롤 · /mouse로 다시 켜기","language.current":"언어: {name} · /language en | zh-CN | zh-TW | ja | ko | es","language.set":"언어 → {name}","language.title":"/language — 인터페이스 언어","language.currentMark":"현재","language.unknown":"알 수 없는 언어 \"{value}\". en, zh-CN, zh-TW, ja, ko, es 중에서 선택하세요.","language.saveFailed":"언어 설정 저장 실패: {error}","doctor.logs.new":"이 TUI 버전 시작 이후의 warning/error만 기록됩니다.","footer.current":"현재","footer.average":"평균","footer.context":"컨텍스트","footer.cache":"캐시","composer.placeholder":"메시지를 입력하세요","doctor.nearTimeout":"판단: Bash 호출 {count}건이 약 300초에 종료되어 도구 시간 초과 특징과 일치합니다. 트레이스만으로는 근본 원인을 증명할 수 없습니다. 다음으로 해당 호출의 셸 완료 표시와 터미널 오류를 확인하세요.","doctor.logs.none":"아직 로그 파일이 없습니다. 이전 콘솔 로그는 저장되지 않아 복구할 수 없습니다.","doctor.evidence":"진단 근거: 최근 세션 {traces}개, warning/error {logs}건.","doctor.noFindings":"최근 트레이스에서 명확한 시간 초과, 미완료 도구, 정지는 발견되지 않았습니다.","doctor.noRoute":"사용 가능한 모델 경로가 없어 모델 분석을 실행할 수 없습니다.","doctor.scope":"근거 범위: 최근 세션 {traces}개, warning/error {logs}건. 대화 본문, 도구 인수, 도구 출력은 읽지 않았습니다.","doctor.failed":"모델 분석이 완료되지 않았습니다: {error}."},"es":{"activity.replying":"Respondiendo","activity.thinking":"Pensando","activity.running":"Ejecutando","activity.turn":"este turno","activity.interrupt":"Esc para interrumpir","agents.running":"en ejecución","agents.idle":"inactivo","agents.done":"terminado","agents.total":"en total","welcome.model":"modelo","welcome.effort":"esfuerzo","welcome.project":"proyecto","verbose.on":"modo detallado activado: el razonamiento y las llamadas a herramientas se muestran en el chat","verbose.off":"modo detallado desactivado","mouse.on":"ratón activado: la rueda desplaza el chat · mantén Shift al arrastrar para seleccionar texto (Option en iTerm2, Fn en Terminal)","mouse.off":"ratón desactivado: selecciona y copia libremente · PageUp/PageDown desplazan el chat · /mouse vuelve a activar la captura","language.current":"Idioma: {name} · /language en | zh-CN | zh-TW | ja | ko | es","language.set":"idioma → {name}","language.title":"/language — idioma de la interfaz","language.currentMark":"actual","language.unknown":"Idioma desconocido \"{value}\". Elige en, zh-CN, zh-TW, ja, ko o es.","language.saveFailed":"no se pudo guardar el idioma: {error}","doctor.logs.new":"Solo se registran los warnings/errores desde que arrancó esta versión del TUI.","footer.current":"actual","footer.average":"promedio","footer.context":"contexto","footer.cache":"caché","composer.placeholder":"escribe un mensaje","doctor.nearTimeout":"Valoración: {count} llamadas a Bash terminaron a unos 300 segundos, lo que coincide con el tiempo de espera de la herramienta; las trazas por sí solas no prueban la causa raíz. A continuación, revisa los marcadores de finalización del shell y los errores de terminal de esas llamadas.","doctor.logs.none":"Aún no hay archivo de registro; los registros de consola anteriores no se conservaron y no se pueden recuperar.","doctor.evidence":"Evidencia del diagnóstico: {traces} sesiones recientes, {logs} warnings/errores.","doctor.noFindings":"No hay tiempos de espera, herramientas sin terminar ni bloqueos claros en las trazas recientes.","doctor.noRoute":"No hay una ruta de modelo disponible, así que el análisis con modelo no se pudo ejecutar.","doctor.scope":"Alcance de la evidencia: {traces} sesiones recientes, {logs} warnings/errores; no se leyó el texto de la conversación, los argumentos ni la salida de las herramientas.","doctor.failed":"El análisis con modelo no terminó: {error}."}};
|
|
4
|
+
const DSCODE_MESSAGES = {"en":{"activity.replying":"Replying","activity.thinking":"Thinking","activity.running":"Running","activity.turn":"this turn","activity.interrupt":"Esc to interrupt","agents.running":"running","agents.idle":"idle","agents.done":"done","agents.total":"total","welcome.model":"model","welcome.effort":"effort","welcome.project":"project","verbose.on":"verbose on: thinking and tool calls are shown in the chat","verbose.off":"verbose off","mouse.on":"mouse on: the wheel scrolls the chat · hold Shift while dragging to select text (Option in iTerm2, Fn in Terminal)","mouse.off":"mouse off: select and copy freely · PageUp/PageDown scroll the chat · /mouse turns wheel scrolling on","language.current":"Language: {name} · /language en | zh-CN | zh-TW | ja | ko | es","language.set":"language → {name}","language.title":"/language — interface language","language.currentMark":"current","language.unknown":"Unknown language \"{value}\". Choose en, zh-CN, zh-TW, ja, ko or es.","language.saveFailed":"language save failed: {error}","doctor.logs.new":"Only warnings/errors since this TUI version started are recorded.","footer.current":"current","footer.average":"average","footer.context":"context","footer.cache":"cache hit","composer.placeholder":"type a message","doctor.nearTimeout":"Assessment: {count} Bash calls ended at about 300 seconds, which matches the tool timeout; traces alone cannot prove the root cause. Next, check those calls' shell completion markers and terminal errors.","doctor.logs.none":"No log file yet; earlier console logs were not persisted and cannot be recovered.","doctor.evidence":"Diagnostic evidence: {traces} recent sessions, {logs} warnings/errors.","doctor.noFindings":"No clear timeouts, unfinished tool calls or error events in recent traces.","doctor.noRoute":"No model route is available, so the model analysis could not run.","doctor.scope":"Evidence scope: {traces} recent sessions, {logs} warnings/errors; conversation text, tool arguments and tool output were not read.","doctor.failed":"Model analysis did not finish: {error}."},"zh-CN":{"activity.replying":"正在回复","activity.thinking":"正在思考","activity.running":"正在执行","activity.turn":"本轮","activity.interrupt":"Esc 中断","agents.running":"运行中","agents.idle":"空闲","agents.done":"已完成","agents.total":"总计","welcome.model":"模型","welcome.effort":"推理","welcome.project":"项目","verbose.on":"详细模式已开启:对话中显示思考与工具调用","verbose.off":"详细模式已关闭","mouse.on":"鼠标捕获已开启:滚轮滚动对话 · 拖选文本时按住 Shift(iTerm2 按住 Option、Terminal 按住 Fn)","mouse.off":"鼠标捕获已关闭:可自由选择复制 · PageUp/PageDown 滚动对话 · /mouse 重新开启","language.current":"语言:{name} · /language en | zh-CN | zh-TW | ja | ko | es","language.set":"语言 → {name}","language.title":"/language — 界面语言","language.currentMark":"当前","language.unknown":"未知语言 \"{value}\"。可选 en、zh-CN、zh-TW、ja、ko、es。","language.saveFailed":"语言设置保存失败:{error}","doctor.logs.new":"仅记录新版 TUI 启动后的 warning/error。","footer.current":"当前","footer.average":"平均","footer.context":"上下文","footer.cache":"缓存命中","composer.placeholder":"输入消息","doctor.nearTimeout":"判断:{count} 次 Bash 调用在约 300 秒结束,符合工具超时特征;trace 不能单独证明触发超时的根因。下一步检查这些调用的 shell 完成标记和终端错误。","doctor.logs.none":"日志文件尚未建立;旧版控制台日志未持久化,无法回溯。","doctor.evidence":"诊断证据:{traces} 个近期会话、{logs} 条 warning/error。","doctor.noFindings":"近期 trace 中未发现明确的超时、未完成工具调用或错误事件。","doctor.noRoute":"没有可用的模型路由,无法运行模型分析。","doctor.scope":"证据范围:{traces} 个近期会话、{logs} 条 warning/error;未读取对话正文、工具参数或工具输出。","doctor.failed":"模型分析未完成:{error}。"},"zh-TW":{"activity.replying":"正在回覆","activity.thinking":"正在思考","activity.running":"正在執行","activity.turn":"本輪","activity.interrupt":"Esc 中斷","agents.running":"執行中","agents.idle":"閒置","agents.done":"已完成","agents.total":"總計","welcome.model":"模型","welcome.effort":"推理","welcome.project":"專案","verbose.on":"詳細模式已開啟:對話中顯示思考與工具呼叫","verbose.off":"詳細模式已關閉","mouse.on":"滑鼠擷取已開啟:滾輪捲動對話 · 拖選文字時按住 Shift(iTerm2 按住 Option、Terminal 按住 Fn)","mouse.off":"滑鼠擷取已關閉:可自由選取複製 · PageUp/PageDown 捲動對話 · /mouse 重新開啟","language.current":"語言:{name} · /language en | zh-CN | zh-TW | ja | ko | es","language.set":"語言 → {name}","language.title":"/language — 介面語言","language.currentMark":"目前","language.unknown":"未知語言 \"{value}\"。可選 en、zh-CN、zh-TW、ja、ko、es。","language.saveFailed":"語言設定儲存失敗:{error}","doctor.logs.new":"僅記錄新版 TUI 啟動後的 warning/error。","footer.current":"目前","footer.average":"平均","footer.context":"上下文","footer.cache":"快取命中","composer.placeholder":"輸入訊息","doctor.nearTimeout":"判斷:{count} 次 Bash 呼叫在約 300 秒結束,符合工具逾時特徵;trace 無法單獨證明觸發逾時的根因。下一步檢查這些呼叫的 shell 完成標記和終端錯誤。","doctor.logs.none":"日誌檔尚未建立;舊版主控台日誌未持久化,無法回溯。","doctor.evidence":"診斷證據:{traces} 個近期工作階段、{logs} 筆 warning/error。","doctor.noFindings":"近期 trace 中未發現明確的逾時、未完成工具呼叫或錯誤事件。","doctor.noRoute":"沒有可用的模型路由,無法執行模型分析。","doctor.scope":"證據範圍:{traces} 個近期工作階段、{logs} 筆 warning/error;未讀取對話內容、工具參數或工具輸出。","doctor.failed":"模型分析未完成:{error}。"},"ja":{"activity.replying":"応答中","activity.thinking":"思考中","activity.running":"実行中","activity.turn":"今回のターン","activity.interrupt":"Esc で中断","agents.running":"実行中","agents.idle":"待機中","agents.done":"完了","agents.total":"合計","welcome.model":"モデル","welcome.effort":"推論","welcome.project":"プロジェクト","verbose.on":"詳細モード オン:思考とツール呼び出しをチャットに表示します","verbose.off":"詳細モード オフ","mouse.on":"マウス キャプチャ オン:ホイールでチャットをスクロール · Shift(iTerm2 は Option、Terminal は Fn)を押しながらドラッグでテキスト選択","mouse.off":"マウス キャプチャ オフ:自由に選択・コピーできます · PageUp/PageDown でスクロール · /mouse で再びオン","language.current":"言語:{name} · /language en | zh-CN | zh-TW | ja | ko | es","language.set":"言語 → {name}","language.title":"/language — 表示言語","language.currentMark":"現在","language.unknown":"不明な言語 \"{value}\"。en、zh-CN、zh-TW、ja、ko、es から選んでください。","language.saveFailed":"言語設定の保存に失敗しました:{error}","doctor.logs.new":"この TUI バージョンの起動以降の warning/error のみ記録されています。","footer.current":"現在","footer.average":"平均","footer.context":"コンテキスト","footer.cache":"キャッシュヒット","composer.placeholder":"メッセージを入力","doctor.nearTimeout":"判断:Bash 呼び出し {count} 件が約 300 秒で終了しており、ツールのタイムアウトの特徴に一致します。トレースだけでは根本原因を証明できません。次はこれらの呼び出しのシェル完了マーカーと端末エラーを確認してください。","doctor.logs.none":"ログファイルはまだありません。以前のコンソールログは保存されておらず、遡れません。","doctor.evidence":"診断の根拠:直近のセッション {traces} 件、warning/error {logs} 件。","doctor.noFindings":"直近のトレースに明確なタイムアウト、未完了ツール、停滞は見つかりませんでした。","doctor.noRoute":"利用できるモデルルートがないため、モデル分析を実行できません。","doctor.scope":"根拠の範囲:直近のセッション {traces} 件、warning/error {logs} 件。会話本文、ツール引数、ツール出力は読んでいません。","doctor.failed":"モデル分析が完了しませんでした:{error}。"},"ko":{"activity.replying":"응답 중","activity.thinking":"생각 중","activity.running":"실행 중","activity.turn":"이번 턴","activity.interrupt":"Esc 중단","agents.running":"실행 중","agents.idle":"대기","agents.done":"완료","agents.total":"전체","welcome.model":"모델","welcome.effort":"추론","welcome.project":"프로젝트","verbose.on":"상세 모드 켜짐: 생각과 도구 호출을 채팅에 표시합니다","verbose.off":"상세 모드 꺼짐","mouse.on":"마우스 캡처 켜짐: 휠로 채팅 스크롤 · Shift(iTerm2는 Option, Terminal은 Fn)를 누른 채 드래그하여 텍스트 선택","mouse.off":"마우스 캡처 꺼짐: 자유롭게 선택·복사 · PageUp/PageDown으로 채팅 스크롤 · /mouse로 다시 켜기","language.current":"언어: {name} · /language en | zh-CN | zh-TW | ja | ko | es","language.set":"언어 → {name}","language.title":"/language — 인터페이스 언어","language.currentMark":"현재","language.unknown":"알 수 없는 언어 \"{value}\". en, zh-CN, zh-TW, ja, ko, es 중에서 선택하세요.","language.saveFailed":"언어 설정 저장 실패: {error}","doctor.logs.new":"이 TUI 버전 시작 이후의 warning/error만 기록됩니다.","footer.current":"현재","footer.average":"평균","footer.context":"컨텍스트","footer.cache":"캐시 적중","composer.placeholder":"메시지를 입력하세요","doctor.nearTimeout":"판단: Bash 호출 {count}건이 약 300초에 종료되어 도구 시간 초과 특징과 일치합니다. 트레이스만으로는 근본 원인을 증명할 수 없습니다. 다음으로 해당 호출의 셸 완료 표시와 터미널 오류를 확인하세요.","doctor.logs.none":"아직 로그 파일이 없습니다. 이전 콘솔 로그는 저장되지 않아 복구할 수 없습니다.","doctor.evidence":"진단 근거: 최근 세션 {traces}개, warning/error {logs}건.","doctor.noFindings":"최근 트레이스에서 명확한 시간 초과, 미완료 도구, 정지는 발견되지 않았습니다.","doctor.noRoute":"사용 가능한 모델 경로가 없어 모델 분석을 실행할 수 없습니다.","doctor.scope":"근거 범위: 최근 세션 {traces}개, warning/error {logs}건. 대화 본문, 도구 인수, 도구 출력은 읽지 않았습니다.","doctor.failed":"모델 분석이 완료되지 않았습니다: {error}."},"es":{"activity.replying":"Respondiendo","activity.thinking":"Pensando","activity.running":"Ejecutando","activity.turn":"este turno","activity.interrupt":"Esc para interrumpir","agents.running":"en ejecución","agents.idle":"inactivo","agents.done":"terminado","agents.total":"en total","welcome.model":"modelo","welcome.effort":"esfuerzo","welcome.project":"proyecto","verbose.on":"modo detallado activado: el razonamiento y las llamadas a herramientas se muestran en el chat","verbose.off":"modo detallado desactivado","mouse.on":"ratón activado: la rueda desplaza el chat · mantén Shift al arrastrar para seleccionar texto (Option en iTerm2, Fn en Terminal)","mouse.off":"ratón desactivado: selecciona y copia libremente · PageUp/PageDown desplazan el chat · /mouse vuelve a activar la captura","language.current":"Idioma: {name} · /language en | zh-CN | zh-TW | ja | ko | es","language.set":"idioma → {name}","language.title":"/language — idioma de la interfaz","language.currentMark":"actual","language.unknown":"Idioma desconocido \"{value}\". Elige en, zh-CN, zh-TW, ja, ko o es.","language.saveFailed":"no se pudo guardar el idioma: {error}","doctor.logs.new":"Solo se registran los warnings/errores desde que arrancó esta versión del TUI.","footer.current":"actual","footer.average":"promedio","footer.context":"contexto","footer.cache":"éxitos de caché","composer.placeholder":"escribe un mensaje","doctor.nearTimeout":"Valoración: {count} llamadas a Bash terminaron a unos 300 segundos, lo que coincide con el tiempo de espera de la herramienta; las trazas por sí solas no prueban la causa raíz. A continuación, revisa los marcadores de finalización del shell y los errores de terminal de esas llamadas.","doctor.logs.none":"Aún no hay archivo de registro; los registros de consola anteriores no se conservaron y no se pueden recuperar.","doctor.evidence":"Evidencia del diagnóstico: {traces} sesiones recientes, {logs} warnings/errores.","doctor.noFindings":"No hay tiempos de espera, herramientas sin terminar ni bloqueos claros en las trazas recientes.","doctor.noRoute":"No hay una ruta de modelo disponible, así que el análisis con modelo no se pudo ejecutar.","doctor.scope":"Alcance de la evidencia: {traces} sesiones recientes, {logs} warnings/errores; no se leyó el texto de la conversación, los argumentos ni la salida de las herramientas.","doctor.failed":"El análisis con modelo no terminó: {error}."}};
|
|
5
5
|
const DSCODE_LANGUAGE_ALIASES = {"en":["en","english","eng","英文","英语","英語"],"zh-CN":["zh-cn","zh","zh-hans","zhhans","cn","chinese","simplified","中文","简体","简体中文","简中","中文简体"],"zh-TW":["zh-tw","zh-hant","zhhant","tw","hk","zh-hk","traditional","繁体","繁體","繁體中文","繁体中文","繁中"],"ja":["ja","jp","japanese","日本語","日语","日語"],"ko":["ko","kr","korean","한국어","韩语","韓語","韓文"],"es":["es","spanish","español","espanol","西班牙语","西班牙語"]};
|
|
6
6
|
function dscodeNormalizeLanguage(value) {
|
|
7
7
|
const aliasesByCode = DSCODE_LANGUAGE_ALIASES;
|
|
@@ -39,32 +39,6 @@ function dscodeLoadFlag(name, fallback = false) {
|
|
|
39
39
|
function dscodeSaveFlag(name, value) {
|
|
40
40
|
try { fs.mkdirSync(join(homedir(), ".dsh", "dsh-code"), { recursive: true }); fs.writeFileSync(dscodeFlagFile(name), JSON.stringify({ [name]: value }, null, 2) + "\n"); } catch {}
|
|
41
41
|
}
|
|
42
|
-
// dscode-scroll-v3
|
|
43
|
-
// dscode-interaction-v2
|
|
44
|
-
// dscode-welcome-scroll-v2
|
|
45
|
-
// dscode-welcome-v2
|
|
46
|
-
const WELCOME_ART = ["...........1.1..........","............1...........","............1...........",".........1..1..1........",".......1..22222..1......","...1...1....2....1...1..","..11...2....2....2...11.","....11.2...222...2.11...","......22.22.3.22.22.....",".....22.22.333.22.22....","....1...2.33332.2...1...","........2.33322.2.......","....1...2.33222.2...1...",".....22.22.222.22.22....","......22.22.3.22.22.....","....11.2...222...2.11...","..11...2....2....2...11.","...1...1....2....1...1..",".......1..22222..1......",".........1..1..1........","............1...........","............1...........","...........1.1..........","........................"];
|
|
47
|
-
const WELCOME_ART_SMALL = ["..........1.1.........","...........1..........","........1..1..1.......",".........1.2.1........","...1..1...222...1..1..","...1..1....2....1..1..","..1.1.2...222...2.1.1.",".....22.22.3.22.22....","....12.22.333.22.21...","...1...2.33332.2...1..",".......2.33322.2......","...1...2.33222.2...1..","....12.22.222.22.21...",".....22.22.3.22.22....","..1.1.2...222...2.1.1.","...1..1....2....1..1..","...1..1...222...1..1..",".........1.2.1........","........1..1..1.......","...........1..........","..........1.1.........","......................"];
|
|
48
|
-
function welcomeArtRows(grid, tones) {
|
|
49
|
-
const rows = [];
|
|
50
|
-
for (let y = 0; y < grid.length; y += 2) {
|
|
51
|
-
const top = grid[y] || '';
|
|
52
|
-
const bottom = grid[y + 1] || '';
|
|
53
|
-
const segments = [];
|
|
54
|
-
for (let x = 0; x < Math.max(top.length, bottom.length); x++) {
|
|
55
|
-
const upper = tones[top[x]] || '';
|
|
56
|
-
const lower = tones[bottom[x]] || '';
|
|
57
|
-
const glyph = upper && lower ? upper === lower ? '\u2588' : '\u2580' : upper ? '\u2580' : lower ? '\u2584' : ' ';
|
|
58
|
-
const color = upper || lower;
|
|
59
|
-
const background = upper && lower && upper !== lower ? lower : '';
|
|
60
|
-
const last = segments[segments.length - 1];
|
|
61
|
-
if (last && last.glyph === glyph && last.color === color && last.background === background) last.text += glyph;
|
|
62
|
-
else segments.push({ glyph, text: glyph, color, background });
|
|
63
|
-
}
|
|
64
|
-
rows.push(segments);
|
|
65
|
-
}
|
|
66
|
-
return rows;
|
|
67
|
-
}
|
|
68
42
|
import { readClipboardImage as dscodeReadClipboardImage } from "./dscode-clipboard-image/index.mjs";
|
|
69
43
|
// dscode-clipboard-image-v1
|
|
70
44
|
// dscode-large-paste-v1
|
|
@@ -147,52 +121,11 @@ function userBackgroundRows(rows, columns, measure) {
|
|
|
147
121
|
};
|
|
148
122
|
});
|
|
149
123
|
}
|
|
150
|
-
// dscode-turn-divider-
|
|
151
|
-
function turnDividedLines(entry, columns, rendered
|
|
152
|
-
if (entry?.turnEnded !== true
|
|
124
|
+
// dscode-turn-divider-v2
|
|
125
|
+
function turnDividedLines(entry, columns, rendered) {
|
|
126
|
+
if (entry?.turnEnded !== true) return rendered;
|
|
153
127
|
// Full terminal width: the row renders with truncate-end, so it can never wrap.
|
|
154
|
-
return [...rendered, { segments: [{ text: '─'.repeat(Math.max(1, columns)), style: 'dim' }] }];
|
|
155
|
-
}
|
|
156
|
-
// dscode-scroll-v1
|
|
157
|
-
function transcriptWindow(lines, rows, offset) {
|
|
158
|
-
if (rows <= 0) return [];
|
|
159
|
-
const end = Math.max(0, lines.length - Math.max(0, offset));
|
|
160
|
-
return lines.slice(Math.max(0, end - rows), end);
|
|
161
|
-
}
|
|
162
|
-
function mouseWheelDirection(unit) {
|
|
163
|
-
const match = /^\x1b\[<(\d+);\d+;\d+([Mm])$/.exec(unit);
|
|
164
|
-
if (!match) return null;
|
|
165
|
-
if (match[2] !== 'M') return 0;
|
|
166
|
-
const button = Number(match[1]) & ~(4 | 8 | 16);
|
|
167
|
-
return button === 64 ? 1 : button === 65 ? -1 : 0;
|
|
168
|
-
}
|
|
169
|
-
const DSCODE_MOUSE_ENABLE = "\x1b[?1000h\x1b[?1006h";
|
|
170
|
-
const DSCODE_MOUSE_DISABLE = "\x1b[?1006l\x1b[?1000l";
|
|
171
|
-
const DSCODE_WHEEL_FRAME_MS = 16;
|
|
172
|
-
const dscodeWheelListeners = new Set();
|
|
173
|
-
let dscodeWheelPending = 0;
|
|
174
|
-
let dscodeWheelTimer = void 0;
|
|
175
|
-
function dscodeQueueWheel(direction) {
|
|
176
|
-
dscodeWheelPending += direction;
|
|
177
|
-
if (dscodeWheelTimer !== void 0) return;
|
|
178
|
-
dscodeWheelTimer = setTimeout(() => {
|
|
179
|
-
dscodeWheelTimer = void 0;
|
|
180
|
-
const delta = dscodeWheelPending;
|
|
181
|
-
dscodeWheelPending = 0;
|
|
182
|
-
if (delta !== 0) for (const listener of dscodeWheelListeners) listener(delta);
|
|
183
|
-
}, DSCODE_WHEEL_FRAME_MS);
|
|
184
|
-
}
|
|
185
|
-
let dscodeMouseEnabled = dscodeLoadFlag("mouse", true);
|
|
186
|
-
function dscodeSetMouse(enabled) {
|
|
187
|
-
dscodeMouseEnabled = enabled;
|
|
188
|
-
if (process.stdout.isTTY === true) process.stdout.write(enabled ? DSCODE_MOUSE_ENABLE : DSCODE_MOUSE_DISABLE);
|
|
189
|
-
return enabled;
|
|
190
|
-
}
|
|
191
|
-
function dscodeHandleMouseUnit(unit) {
|
|
192
|
-
const direction = mouseWheelDirection(unit);
|
|
193
|
-
if (direction === null) return false;
|
|
194
|
-
if (direction !== 0) dscodeQueueWheel(direction);
|
|
195
|
-
return true;
|
|
128
|
+
return [...rendered, { segments: [] }, { segments: [{ text: '─'.repeat(Math.max(1, columns)), style: 'dim' }] }, { segments: [] }];
|
|
196
129
|
}
|
|
197
130
|
// dscode-interrupt-v1
|
|
198
131
|
function ctrlCAction(armed, { interrupt, busy, preparingImages, active, hasDraft }) {
|
|
@@ -202,11 +135,6 @@ function ctrlCAction(armed, { interrupt, busy, preparingImages, active, hasDraft
|
|
|
202
135
|
if (!active) return 'wait';
|
|
203
136
|
return hasDraft ? 'clear-draft' : 'quit';
|
|
204
137
|
}
|
|
205
|
-
// dscode-welcome-scroll-v1
|
|
206
|
-
function welcomeVisibleRows(capacity, maximum, demand, canScroll = true) {
|
|
207
|
-
if (!canScroll || capacity < maximum) return maximum;
|
|
208
|
-
return Math.max(0, Math.min(maximum, capacity - demand));
|
|
209
|
-
}
|
|
210
138
|
// dscode-email-v4
|
|
211
139
|
import { createImapConnector as dscodeCreateImapConnector } from "./dscode-email/imap.mjs";
|
|
212
140
|
import { createGmailConnector as dscodeCreateGmailConnector } from "./dscode-email/gmail.mjs";
|
|
@@ -339,6 +267,7 @@ function DscodeEmailPanel({ columns, rows, pick, close, gmail, imap }) {
|
|
|
339
267
|
}
|
|
340
268
|
// dscode-effort-bar-v6
|
|
341
269
|
// dscode-welcome-v1
|
|
270
|
+
// dscode-welcome-v2
|
|
342
271
|
function welcomePath(path, width) {
|
|
343
272
|
const full = singleLineText(path || '');
|
|
344
273
|
if (visibleColumns(full) <= width) return full;
|
|
@@ -351,23 +280,46 @@ function welcomePath(path, width) {
|
|
|
351
280
|
}
|
|
352
281
|
return suffix ? '…' + suffix : '…' + truncateColumns(segments.at(-1) || full, Math.max(1, width - 1));
|
|
353
282
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
const
|
|
358
|
-
let
|
|
359
|
-
|
|
360
|
-
const
|
|
361
|
-
const
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
283
|
+
const WELCOME_ART = ["...........1.1..........","............1...........","............1...........",".........1..1..1........",".......1..22222..1......","...1...1....2....1...1..","..11...2....2....2...11.","....11.2...222...2.11...","......22.22.3.22.22.....",".....22.22.333.22.22....","....1...2.33332.2...1...","........2.33322.2.......","....1...2.33222.2...1...",".....22.22.222.22.22....","......22.22.3.22.22.....","....11.2...222...2.11...","..11...2....2....2...11.","...1...1....2....1...1..",".......1..22222..1......",".........1..1..1........","............1...........","............1...........","...........1.1..........","........................"];
|
|
284
|
+
const WELCOME_ART_SMALL = ["..........1.1.........","...........1..........","........1..1..1.......",".........1.2.1........","...1..1...222...1..1..","...1..1....2....1..1..","..1.1.2...222...2.1.1.",".....22.22.3.22.22....","....12.22.333.22.21...","...1...2.33332.2...1..",".......2.33322.2......","...1...2.33222.2...1..","....12.22.222.22.21...",".....22.22.3.22.22....","..1.1.2...222...2.1.1.","...1..1....2....1..1..","...1..1...222...1..1..",".........1.2.1........","........1..1..1.......","...........1..........","..........1.1.........","......................"];
|
|
285
|
+
function welcomeArtRows(grid, tones) {
|
|
286
|
+
const rows = [];
|
|
287
|
+
for (let y = 0; y < grid.length; y += 2) {
|
|
288
|
+
const top = grid[y] || '';
|
|
289
|
+
const bottom = grid[y + 1] || '';
|
|
290
|
+
const segments = [];
|
|
291
|
+
for (let x = 0; x < Math.max(top.length, bottom.length); x++) {
|
|
292
|
+
const upper = tones[top[x]] || '';
|
|
293
|
+
const lower = tones[bottom[x]] || '';
|
|
294
|
+
const glyph = upper && lower ? upper === lower ? '\u2588' : '\u2580' : upper ? '\u2580' : lower ? '\u2584' : ' ';
|
|
295
|
+
const color = upper || lower;
|
|
296
|
+
const background = upper && lower && upper !== lower ? lower : '';
|
|
297
|
+
const last = segments[segments.length - 1];
|
|
298
|
+
if (last && last.glyph === glyph && last.color === color && last.background === background) last.text += glyph;
|
|
299
|
+
else segments.push({ glyph, text: glyph, color, background });
|
|
365
300
|
}
|
|
301
|
+
rows.push(segments);
|
|
366
302
|
}
|
|
367
|
-
return
|
|
303
|
+
return rows;
|
|
368
304
|
}
|
|
369
305
|
// dscode-style-v1
|
|
370
306
|
|
|
307
|
+
function dscodeFooterHeader(facts, stats) {
|
|
308
|
+
const raw = typeof facts?.model === "string" ? facts.model : "";
|
|
309
|
+
if (raw === "") return "";
|
|
310
|
+
const cut = raw.indexOf("/");
|
|
311
|
+
const provider = cut > 0 ? raw.slice(0, cut) : "";
|
|
312
|
+
const model = cut > 0 ? raw.slice(cut + 1) : raw;
|
|
313
|
+
const effort = typeof facts?.effort === "string" && facts.effort !== "" ? facts.effort : (typeof stats?.reasoningEffort === "string" ? stats.reasoningEffort : "");
|
|
314
|
+
return (provider === "" ? model : provider + ": " + model) + (effort === "" ? "" : " @ " + effort);
|
|
315
|
+
}
|
|
316
|
+
function dscodeStatusLead(facts, model, effort) {
|
|
317
|
+
const source = facts?.title !== void 0 && facts.title !== "" ? facts.title : facts?.sessionId;
|
|
318
|
+
const title = source === void 0 || source === "" ? "" : truncateColumns(safe(source), TITLE_BUDGET);
|
|
319
|
+
if (title !== "") return title;
|
|
320
|
+
return effort === "" ? model : model + " | " + effort;
|
|
321
|
+
}
|
|
322
|
+
|
|
371
323
|
|
|
372
324
|
// dscode-tps-colors-v1
|
|
373
325
|
function dscodeTpsTone(rate) {
|
|
@@ -377,8 +329,18 @@ function dscodeTpsTone(rate) {
|
|
|
377
329
|
if (rate <= 250) return "blue";
|
|
378
330
|
return "purple";
|
|
379
331
|
}
|
|
332
|
+
// Cache hit rate: red under 90, yellow to 95, green to 98, blue above.
|
|
333
|
+
const dscodeCacheLabels = ["cache hit", "缓存命中", "快取命中", "キャッシュヒット", "캐시 적중", "éxitos de caché"];
|
|
334
|
+
function dscodeCacheTone(rate) {
|
|
335
|
+
if (!Number.isFinite(rate) || rate < 0) return null;
|
|
336
|
+
if (rate < 90) return "red";
|
|
337
|
+
if (rate < 95) return "yellow";
|
|
338
|
+
if (rate < 98) return "green";
|
|
339
|
+
return "blue";
|
|
340
|
+
}
|
|
380
341
|
function dscodeTpsInkColor(tone) {
|
|
381
342
|
const palette = getPalette();
|
|
343
|
+
if (tone === "red") return inkColor(getTheme() === "light" ? [185, 28, 28] : [248, 113, 113]);
|
|
382
344
|
if (tone === "yellow") return inkColor(palette.warn);
|
|
383
345
|
if (tone === "green") return inkColor(palette.success);
|
|
384
346
|
if (tone === "blue") return inkColor(palette.brandBright);
|
|
@@ -387,13 +349,25 @@ function dscodeTpsInkColor(tone) {
|
|
|
387
349
|
}
|
|
388
350
|
function dscodeTelemetryParts(value) {
|
|
389
351
|
const result = [];
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
352
|
+
const parts = String(value).split(" | ");
|
|
353
|
+
for (const [index, part] of parts.entries()) {
|
|
354
|
+
if (index > 0) result.push({ text: " | ", tone: null });
|
|
355
|
+
const match = /^(.+?: )(~?(?:\d+(?:\.\d+)?|--)) tps$/.exec(part);
|
|
356
|
+
if (match) {
|
|
357
|
+
const display = match[2];
|
|
358
|
+
const rate = Number(display.startsWith("~") ? display.slice(1) : display);
|
|
359
|
+
result.push({ text: match[1], tone: null }, { text: display + " tps", tone: display && dscodeTpsTone(rate) });
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
362
|
+
// The cache hit rate is the last segment of the telemetry line.
|
|
363
|
+
// The cache hit rate closes the telemetry line; only a recognised cache label is tinted.
|
|
364
|
+
const labelled = index === parts.length - 1 ? /^(.*?)(\d+(?:\.\d+)?)%$/.exec(part) : null;
|
|
365
|
+
const cache = labelled && dscodeCacheLabels.includes(labelled[1].replace(/:\s*$/, "").trim().toLowerCase()) ? labelled : null;
|
|
366
|
+
if (cache) {
|
|
367
|
+
result.push({ text: cache[1], tone: null }, { text: cache[2] + "%", tone: dscodeCacheTone(Number(cache[2])) });
|
|
368
|
+
continue;
|
|
369
|
+
}
|
|
370
|
+
result.push({ text: part, tone: null });
|
|
397
371
|
}
|
|
398
372
|
return result;
|
|
399
373
|
}
|
|
@@ -402,6 +376,7 @@ function dscodeTelemetryNodes(value, key) {
|
|
|
402
376
|
{ key: key + "p" + index, color: dscodeTpsInkColor(part.tone) }, part.text));
|
|
403
377
|
}
|
|
404
378
|
|
|
379
|
+
|
|
405
380
|
function dscodeActivity(entries, streaming) {
|
|
406
381
|
const running = entries.filter(entry => entry.kind === "tool" && entry.state === "running");
|
|
407
382
|
const tool = running.at(-1);
|
|
@@ -454,7 +429,6 @@ function DscodeActivityLine({ entries, streaming, since, animated = true }) {
|
|
|
454
429
|
(0, import_react.createElement)(Text, { color: inkColor(getPalette().dim) }, suffix)));
|
|
455
430
|
}
|
|
456
431
|
|
|
457
|
-
|
|
458
432
|
// dscode-footer-v1
|
|
459
433
|
import { footerFor as dscodeFooterFor } from "../../plugins/session-metrics/view.mjs";
|
|
460
434
|
// dscode-ime-v1
|
|
@@ -500,6 +474,7 @@ function imeWriter(stream, anchors) {
|
|
|
500
474
|
function dscodeVisibleRelay(message) {
|
|
501
475
|
return message.source.kind === "plugin" && message.source.plugin === "dscode-session-bridge" && message.source.form === "relay";
|
|
502
476
|
}
|
|
477
|
+
// dscode-interaction-v2
|
|
503
478
|
// dscode-interaction-v1
|
|
504
479
|
function dscodeChatLines(entry, columns, verbose = false) {
|
|
505
480
|
const width = Math.max(1, Math.floor(columns));
|
|
@@ -517,7 +492,7 @@ function dscodeChatLines(entry, columns, verbose = false) {
|
|
|
517
492
|
return [...thinking, ...transcriptEntryLines({ ...entry, reasoning: "" }, columns, false, false, false)];
|
|
518
493
|
}
|
|
519
494
|
const rows = transcriptEntryLines(entry, columns, false, false, false);
|
|
520
|
-
return entry.kind === "user" && !entry.notice ? userBackgroundRows(rows, columns, visibleColumns) : rows;
|
|
495
|
+
return entry.kind === "user" && !entry.notice ? [...userBackgroundRows(rows, columns, visibleColumns), { segments: [] }] : rows;
|
|
521
496
|
}
|
|
522
497
|
function dscodeThinkingLines(reasoning, width) {
|
|
523
498
|
const lines = hangingTextLines("Thinking: " + reasoning.replace(/\s+/g, " ").trim(), width, "· ", "dimItalic", " ");
|
|
@@ -26181,18 +26156,9 @@ function replayProjectEvent(acc, event) {
|
|
|
26181
26156
|
acc.busy = false;
|
|
26182
26157
|
acc.busySince = 0;
|
|
26183
26158
|
for (const entry of appended) appendReplayEntry(acc, entry);
|
|
26184
|
-
|
|
26185
|
-
|
|
26186
|
-
|
|
26187
|
-
if (entry.turnEnded !== true) {
|
|
26188
|
-
acc.entries[index] = { ...entry, turnEnded: true };
|
|
26189
|
-
acc.ops += 1;
|
|
26190
|
-
}
|
|
26191
|
-
break;
|
|
26192
|
-
}
|
|
26193
|
-
return true;
|
|
26194
|
-
}
|
|
26195
|
-
case "llm/retry": {
|
|
26159
|
+
return true;
|
|
26160
|
+
}
|
|
26161
|
+
case "llm/retry": {
|
|
26196
26162
|
const data = event.data;
|
|
26197
26163
|
acc.streaming = "";
|
|
26198
26164
|
acc.streamingReasoning = "";
|
|
@@ -28912,10 +28878,11 @@ function buildCandidates(facts, stats, busy, enabled, contextWidth) {
|
|
|
28912
28878
|
identity.push(span);
|
|
28913
28879
|
};
|
|
28914
28880
|
const model = safe(facts.model).split("/").at(-1);
|
|
28915
|
-
|
|
28881
|
+
// dscode-footer-rows-v1: the title leads row 1, the model rides the footer header.
|
|
28882
|
+
if ((model !== "" && enabled.has("model")) || enabled.has("title")) {
|
|
28916
28883
|
const effort = safe(facts.effort ?? stats.reasoningEffort);
|
|
28917
28884
|
push({
|
|
28918
|
-
text:
|
|
28885
|
+
text: dscodeStatusLead(facts, model, effort),
|
|
28919
28886
|
tone: "model"
|
|
28920
28887
|
});
|
|
28921
28888
|
}
|
|
@@ -29045,15 +29012,7 @@ function buildCandidates(facts, stats, busy, enabled, contextWidth) {
|
|
|
29045
29012
|
id: "tokens"
|
|
29046
29013
|
});
|
|
29047
29014
|
}
|
|
29048
|
-
|
|
29049
|
-
if (label !== "" && enabled.has("title")) row2.push({
|
|
29050
|
-
group: { spans: [{
|
|
29051
|
-
text: label,
|
|
29052
|
-
tone: "meta"
|
|
29053
|
-
}] },
|
|
29054
|
-
rank: RANK_TITLE,
|
|
29055
|
-
id: "title"
|
|
29056
|
-
});
|
|
29015
|
+
// dscode-footer-rows-v1: the title moved to the identity lead on row 1.
|
|
29057
29016
|
if (facts.goal !== void 0 && enabled.has("goal")) row2.push({
|
|
29058
29017
|
group: { spans: [{
|
|
29059
29018
|
text: facts.goal.phase === "active" ? "◎ round " + facts.goal.rounds + "/" + facts.goal.max : "◎ " + safe(facts.goal.phase),
|
|
@@ -29074,15 +29033,16 @@ function buildCandidates(facts, stats, busy, enabled, contextWidth) {
|
|
|
29074
29033
|
const permission = safe(facts.permission);
|
|
29075
29034
|
let badge = -1;
|
|
29076
29035
|
if (permission !== "" && enabled.has("permission")) {
|
|
29077
|
-
|
|
29078
|
-
|
|
29036
|
+
// dscode-footer-rows-v1: the permission rides row 1 next to the title.
|
|
29037
|
+
left.push({
|
|
29038
|
+
group: { spans: [{
|
|
29079
29039
|
text: permission,
|
|
29080
29040
|
tone: permissionTone(permission)
|
|
29081
|
-
},
|
|
29041
|
+
}] },
|
|
29082
29042
|
rank: RANK_BADGE,
|
|
29083
29043
|
id: "permission"
|
|
29084
29044
|
});
|
|
29085
|
-
badge =
|
|
29045
|
+
badge = left.length - 1;
|
|
29086
29046
|
}
|
|
29087
29047
|
return {
|
|
29088
29048
|
left,
|
|
@@ -29446,7 +29406,7 @@ function transcriptEntryLines(entry, columns, showReasoning = true, reasoningTog
|
|
|
29446
29406
|
}
|
|
29447
29407
|
/** Settled-history variant carrying the Ctrl+R reasoning fold. */
|
|
29448
29408
|
function settledEntryLines(entry, columns, showReasoning) {
|
|
29449
|
-
return dscodeChatLines(entry, columns, showReasoning);
|
|
29409
|
+
return turnDividedLines(entry, columns, dscodeChatLines(entry, columns, showReasoning));
|
|
29450
29410
|
}
|
|
29451
29411
|
/**
|
|
29452
29412
|
* Clamp the live-region allocation so the flexible dynamic rows never exceed
|
|
@@ -30893,6 +30853,37 @@ function DscodeUltraRipple({ columns }) {
|
|
|
30893
30853
|
bold: settled || Math.abs(Math.abs(index - center) - Math.max(0, tick - 1) * 3) < 3
|
|
30894
30854
|
}, letter))), rippleLine(2));
|
|
30895
30855
|
}
|
|
30856
|
+
function DscodeUltraFocus({ width, animations }) {
|
|
30857
|
+
const palette = getPalette();
|
|
30858
|
+
const [frame, setFrame] = (0, import_react.useState)(0);
|
|
30859
|
+
const lastFrame = Math.ceil(width / 6) + 2;
|
|
30860
|
+
(0, import_react.useEffect)(() => {
|
|
30861
|
+
if (!animations) return;
|
|
30862
|
+
let step = 0;
|
|
30863
|
+
const timer = setInterval(() => {
|
|
30864
|
+
step++;
|
|
30865
|
+
setFrame(step);
|
|
30866
|
+
if (step >= lastFrame) clearInterval(timer);
|
|
30867
|
+
}, 55);
|
|
30868
|
+
return () => clearInterval(timer);
|
|
30869
|
+
}, [animations, lastFrame]);
|
|
30870
|
+
const label = dscodeEffortCenter(truncateColumns('✦ ULTRA ✦', width), width);
|
|
30871
|
+
const center = (width - 1) / 2;
|
|
30872
|
+
const settled = !animations || frame >= lastFrame;
|
|
30873
|
+
const first = label.length - label.trimStart().length;
|
|
30874
|
+
const last = label.trimEnd().length - 1;
|
|
30875
|
+
return (0, import_react.createElement)(Text, { wrap: 'truncate-end' },
|
|
30876
|
+
...Array.from(label, (letter, index) => {
|
|
30877
|
+
const outer = index < first || index > last;
|
|
30878
|
+
const burst = animations && !settled && outer &&
|
|
30879
|
+
(index === Math.floor(center - frame * 3) || index === Math.ceil(center + frame * 3));
|
|
30880
|
+
return (0, import_react.createElement)(Text, {
|
|
30881
|
+
key: index,
|
|
30882
|
+
color: inkColor(settled ? outer ? palette.brandDeep : palette.brandBright : dscodeRippleTone(index, center, frame, palette)),
|
|
30883
|
+
bold: burst || letter !== ' ' && (settled || Math.abs(Math.abs(index - center) - frame * 3) < 3)
|
|
30884
|
+
}, burst ? '✦' : outer ? '─' : letter);
|
|
30885
|
+
}));
|
|
30886
|
+
}
|
|
30896
30887
|
function DscodeEffortBar({ row, current, select, back, onExit, animations = true }) {
|
|
30897
30888
|
const ids = ['low', 'high', 'max', 'ultra'];
|
|
30898
30889
|
const advertised = row.reasoning.efforts;
|
|
@@ -30957,37 +30948,6 @@ function DscodeEffortBar({ row, current, select, back, onExit, animations = true
|
|
|
30957
30948
|
(0, import_react.createElement)(Text, { color: inkColor(palette.dim), wrap: 'truncate-end' },
|
|
30958
30949
|
truncateColumns(footer, contentWidth)));
|
|
30959
30950
|
}
|
|
30960
|
-
function DscodeUltraFocus({ width, animations }) {
|
|
30961
|
-
const palette = getPalette();
|
|
30962
|
-
const [frame, setFrame] = (0, import_react.useState)(0);
|
|
30963
|
-
const lastFrame = Math.ceil(width / 6) + 2;
|
|
30964
|
-
(0, import_react.useEffect)(() => {
|
|
30965
|
-
if (!animations) return;
|
|
30966
|
-
let step = 0;
|
|
30967
|
-
const timer = setInterval(() => {
|
|
30968
|
-
step++;
|
|
30969
|
-
setFrame(step);
|
|
30970
|
-
if (step >= lastFrame) clearInterval(timer);
|
|
30971
|
-
}, 55);
|
|
30972
|
-
return () => clearInterval(timer);
|
|
30973
|
-
}, [animations, lastFrame]);
|
|
30974
|
-
const label = dscodeEffortCenter(truncateColumns('✦ ULTRA ✦', width), width);
|
|
30975
|
-
const center = (width - 1) / 2;
|
|
30976
|
-
const settled = !animations || frame >= lastFrame;
|
|
30977
|
-
const first = label.length - label.trimStart().length;
|
|
30978
|
-
const last = label.trimEnd().length - 1;
|
|
30979
|
-
return (0, import_react.createElement)(Text, { wrap: 'truncate-end' },
|
|
30980
|
-
...Array.from(label, (letter, index) => {
|
|
30981
|
-
const outer = index < first || index > last;
|
|
30982
|
-
const burst = animations && !settled && outer &&
|
|
30983
|
-
(index === Math.floor(center - frame * 3) || index === Math.ceil(center + frame * 3));
|
|
30984
|
-
return (0, import_react.createElement)(Text, {
|
|
30985
|
-
key: index,
|
|
30986
|
-
color: inkColor(settled ? outer ? palette.brandDeep : palette.brandBright : dscodeRippleTone(index, center, frame, palette)),
|
|
30987
|
-
bold: burst || letter !== ' ' && (settled || Math.abs(Math.abs(index - center) - frame * 3) < 3)
|
|
30988
|
-
}, burst ? '✦' : outer ? '─' : letter);
|
|
30989
|
-
}));
|
|
30990
|
-
}
|
|
30991
30951
|
function EffortPanel(props) {
|
|
30992
30952
|
const reasoning = props.row.reasoning;
|
|
30993
30953
|
const ids = reasoning?.efforts.map(effort => effort.id) ?? [];
|
|
@@ -32044,10 +32004,6 @@ const LOCAL_COMMANDS = [
|
|
|
32044
32004
|
label: "/verbose",
|
|
32045
32005
|
description: "toggle thinking and tool call details in the chat"
|
|
32046
32006
|
},
|
|
32047
|
-
{
|
|
32048
|
-
label: "/mouse",
|
|
32049
|
-
description: "toggle mouse capture: off to select and copy text, on for wheel scrolling"
|
|
32050
|
-
},
|
|
32051
32007
|
{
|
|
32052
32008
|
label: "/language",
|
|
32053
32009
|
description: "show or set the interface language: en, zh-CN, zh-TW, ja, ko, es"
|
|
@@ -32415,7 +32371,7 @@ function Header({ cwd = "", model = "", effort = "", animated = false }) {
|
|
|
32415
32371
|
if (!full) return (0, import_react.createElement)(Box, { flexDirection: "column", paddingX: 2, marginBottom: 1 },
|
|
32416
32372
|
(0, import_react.createElement)(Text, { wrap: "truncate-end" },
|
|
32417
32373
|
(0, import_react.createElement)(Text, { color: inkColor(getPalette().brandBright), bold: true }, "❄ DSCODE"),
|
|
32418
|
-
(0, import_react.createElement)(Text, { color: inkColor(getPalette().dim) }, " v0.7.
|
|
32374
|
+
(0, import_react.createElement)(Text, { color: inkColor(getPalette().dim) }, " v0.7.2")),
|
|
32419
32375
|
(0, import_react.createElement)(Text, { wrap: "truncate-end" }, truncateColumns(modelName + " · " + effortName, width)),
|
|
32420
32376
|
(0, import_react.createElement)(Text, { color: inkColor(getPalette().dim), wrap: "truncate-end" }, welcomePath(cwd, width)));
|
|
32421
32377
|
return (0, import_react.createElement)(Box, { flexDirection: "column", width, borderStyle: "round", borderColor: inkColor(getPalette().brand), paddingX: 1 },
|
|
@@ -32426,7 +32382,7 @@ function Header({ cwd = "", model = "", effort = "", animated = false }) {
|
|
|
32426
32382
|
(0, import_react.createElement)(Box, { flexDirection: "column", width: detailsWidth, marginTop: 2 },
|
|
32427
32383
|
(0, import_react.createElement)(Text, { color: inkColor(getPalette().text), bold: true }, "DSCODE"),
|
|
32428
32384
|
(0, import_react.createElement)(Text, { color: inkColor(getPalette().brandDeep) }, "────────────"),
|
|
32429
|
-
(0, import_react.createElement)(Text, { color: inkColor(getPalette().dim) }, "v0.7.
|
|
32385
|
+
(0, import_react.createElement)(Text, { color: inkColor(getPalette().dim) }, "v0.7.2"),
|
|
32430
32386
|
(0, import_react.createElement)(Text, { wrap: "truncate-end" }, truncateColumns(dscodePadEnd(dscodeT("welcome.model"), 9) + modelName, detailsWidth)),
|
|
32431
32387
|
(0, import_react.createElement)(Text, { wrap: "truncate-end" }, truncateColumns(dscodePadEnd(dscodeT("welcome.effort"), 9) + effortName, detailsWidth)),
|
|
32432
32388
|
(0, import_react.createElement)(Text, null, " "),
|
|
@@ -32637,7 +32593,7 @@ function deepseekWaveHues(tier) {
|
|
|
32637
32593
|
function StatusLine({ facts, stats, busy, columns, items }) {
|
|
32638
32594
|
const [, refreshMetrics] = (0, import_react.useState)(0);
|
|
32639
32595
|
(0, import_react.useEffect)(() => { const timer = setInterval(() => refreshMetrics(n => n + 1), 1000); return () => clearInterval(timer); }, []);
|
|
32640
|
-
facts = { ...facts, telemetry: columns >= 48 ? dscodeFooterFor(facts.fullSessionId, stats, Math.max(1, Math.min(columns - 8, Math.max(40, Math.floor(columns * 0.8) - 4))), dscodeLocale) : "" };
|
|
32596
|
+
facts = { ...facts, telemetry: columns >= 48 ? dscodeFooterFor(facts.fullSessionId, stats, Math.max(1, Math.min(columns - 8, Math.max(40, Math.floor(columns * 0.8) - 4))), dscodeFooterHeader(facts, stats), dscodeLocale) : "" };
|
|
32641
32597
|
const layout = (0, import_react.useMemo)(() => layoutStatusBar(facts, stats, Math.max(8, columns - 2), {
|
|
32642
32598
|
busy,
|
|
32643
32599
|
items,
|
|
@@ -32697,7 +32653,7 @@ function StatusLine({ facts, stats, busy, columns, items }) {
|
|
|
32697
32653
|
return (0, import_react.createElement)(Box, {
|
|
32698
32654
|
paddingLeft: 2 + indent,
|
|
32699
32655
|
width: columns, // dscode-footer-width
|
|
32700
|
-
justifyContent: rightParts.length > 0 ?
|
|
32656
|
+
justifyContent: rightParts.length > 0 ? "space-between" : void 0
|
|
32701
32657
|
}, (0, import_react.createElement)(Text, { wrap: "truncate-end" }, ...leftParts), rightParts.length > 0 ? (0, import_react.createElement)(Text, { wrap: "truncate-end" }, ...rightParts) : void 0);
|
|
32702
32658
|
};
|
|
32703
32659
|
const row2Present = layout.row2.left.length > 0 || layout.row2.right.length > 0;
|
|
@@ -34672,7 +34628,7 @@ function CompletionMenu({ active, mention, index, rows, error }) {
|
|
|
34672
34628
|
* While a modal (approval / question / model panel) owns the keys, the
|
|
34673
34629
|
* box passes every key through untouched.
|
|
34674
34630
|
*/
|
|
34675
|
-
function Input({ effortSurface, ultraPulse, active, frozen, busy, descriptors, skills, dispatch, steer, interrupt, quit, openEmail, emailFill, emailConsumed, openLogin, openModel, openEffort, openHelp, openMode, openPermission, openResume, openPlugin, openJobs, openStatusline, openTheme, openLanguage, openHistory, openAgents, openSubagent, openTodos, openDelete, openDiff, reviewChanges, deleteConfirm, confirmDelete, cancelDelete, createSession, forkSession, cancelSessionSwitch, notify, applyEditorKeys, hasNotice, dismissNotice, toggleReasoning, openVerbose, clearView, refresh, loadMentions, inspectImages, prepareImages, inspectFiles, prepareFiles, readClipboardImage, cyclePermission, exportTranscript, renameTitle, copyLastResponse, recallSpace, recordLocal, recordHistory, queued, cancelQueued, historyFill, historyConsumed, animations, applyAnimations, waveTier, waveStyle, maxRows, onEditorRows, onMenuRows,
|
|
34631
|
+
function Input({ effortSurface, ultraPulse, active, frozen, busy, descriptors, skills, dispatch, steer, interrupt, quit, openEmail, emailFill, emailConsumed, openLogin, openModel, openEffort, openHelp, openMode, openPermission, openResume, openPlugin, openJobs, openStatusline, openTheme, openLanguage, openHistory, openAgents, openSubagent, openTodos, openDelete, openDiff, reviewChanges, deleteConfirm, confirmDelete, cancelDelete, createSession, forkSession, cancelSessionSwitch, notify, applyEditorKeys, hasNotice, dismissNotice, toggleReasoning, openVerbose, clearView, refresh, loadMentions, inspectImages, prepareImages, inspectFiles, prepareFiles, readClipboardImage, cyclePermission, exportTranscript, renameTitle, copyLastResponse, recallSpace, recordLocal, recordHistory, queued, cancelQueued, historyFill, historyConsumed, animations, applyAnimations, waveTier, waveStyle, maxRows, onEditorRows, onMenuRows, sessionKey }) {
|
|
34676
34632
|
const columns = useStdout().stdout?.columns ?? 80;
|
|
34677
34633
|
const inputTerminalRows = useStdout().stdout?.rows ?? 30;
|
|
34678
34634
|
const dscodeImeStdout = useStdout().stdout;
|
|
@@ -35146,7 +35102,6 @@ function Input({ effortSurface, ultraPulse, active, frozen, busy, descriptors, s
|
|
|
35146
35102
|
return;
|
|
35147
35103
|
}
|
|
35148
35104
|
ctrlCArmedRef.current = false;
|
|
35149
|
-
if (key.pageUp || key.pageDown) { onTranscriptScroll?.(key.pageUp ? 1 : -1, true); return; }
|
|
35150
35105
|
if (preparingImages) {
|
|
35151
35106
|
if (key.escape || key.ctrl && input === "c") cancelImageSubmission();
|
|
35152
35107
|
return;
|
|
@@ -35408,12 +35363,6 @@ function Input({ effortSurface, ultraPulse, active, frozen, busy, descriptors, s
|
|
|
35408
35363
|
toggleReasoning();
|
|
35409
35364
|
return;
|
|
35410
35365
|
}
|
|
35411
|
-
if (text === "/mouse") {
|
|
35412
|
-
const enabled = dscodeSetMouse(!dscodeMouseEnabled);
|
|
35413
|
-
dscodeSaveFlag("mouse", enabled);
|
|
35414
|
-
notify(dscodeT(enabled ? "mouse.on" : "mouse.off"));
|
|
35415
|
-
return;
|
|
35416
|
-
}
|
|
35417
35366
|
if (text === "/language" || text.startsWith("/language ")) {
|
|
35418
35367
|
const wanted = text.slice(9).trim();
|
|
35419
35368
|
if (!wanted) { openLanguage(); return; }
|
|
@@ -36119,6 +36068,19 @@ function App(props) {
|
|
|
36119
36068
|
rows: appStdout?.rows ?? 30
|
|
36120
36069
|
}));
|
|
36121
36070
|
const terminalSizeRef = (0, import_react.useRef)(terminalSize);
|
|
36071
|
+
const settledRowsCache = (0, import_react.useRef)(void 0);
|
|
36072
|
+
const settledRows = (0, import_react.useMemo)(() => {
|
|
36073
|
+
const result = computeSettledRows(settledRowsCache.current, view.entries, settled, showReasoning, props.resumed, refreshEpoch, terminalSize.columns, SETTLED_ROW_CAP, { cwd: props.workspaceRoot ?? props.cwd, model: modelLabel, effort: effortLabel, animated: animations });
|
|
36074
|
+
settledRowsCache.current = result.cache;
|
|
36075
|
+
return result.cache.flat;
|
|
36076
|
+
}, [
|
|
36077
|
+
view.entries,
|
|
36078
|
+
settled,
|
|
36079
|
+
showReasoning,
|
|
36080
|
+
props.resumed,
|
|
36081
|
+
refreshEpoch,
|
|
36082
|
+
terminalSize.columns
|
|
36083
|
+
]);
|
|
36122
36084
|
const synchronizedReplayPending = (0, import_react.useRef)(false);
|
|
36123
36085
|
(0, import_react.useEffect)(() => {
|
|
36124
36086
|
if (appStdout === void 0) return;
|
|
@@ -36156,60 +36118,21 @@ function App(props) {
|
|
|
36156
36118
|
setMenuRows((current) => current === rows ? current : rows);
|
|
36157
36119
|
}, []);
|
|
36158
36120
|
const composerEditorCap = composerMaxRows(terminalRows);
|
|
36159
|
-
const
|
|
36160
|
-
const
|
|
36161
|
-
|
|
36162
|
-
|
|
36163
|
-
|
|
36164
|
-
|
|
36165
|
-
|
|
36166
|
-
|
|
36167
|
-
|
|
36168
|
-
|
|
36169
|
-
|
|
36170
|
-
showReasoning
|
|
36171
|
-
]);
|
|
36172
|
-
const allSettledLines = (0, import_react.useMemo)(() => visibleSettledLines(view.entries, settled, Infinity, terminalColumns, showReasoning, settledEntryLines), [settled, view.entries[settled - 1], terminalColumns, showReasoning]);
|
|
36173
|
-
const settledTail = allSettledLines.slice(-transcriptCapacity);
|
|
36174
|
-
const streamingDemand = streamingActive ? textLines(view.streaming.slice(-Math.max(1, terminalColumns * transcriptCapacity)), Math.max(10, terminalColumns - 2)).length : 0;
|
|
36175
|
-
const demand = settledTail.length + allLiveLines.length + streamingDemand + (busy ? 1 : 0) + (agentRows.length > 0 ? 1 : 0);
|
|
36176
|
-
const welcomeRows = welcomeVisibleRows(transcriptCapacity, welcomeMaxRows, demand, transcriptVisible);
|
|
36177
|
-
const settledBudget = transcriptVisible ? Math.max(0, transcriptCapacity - welcomeRows) : 0;
|
|
36178
|
-
const liveDemand = allLiveLines.length + streamingDemand;
|
|
36179
|
-
const liveCap = busy || streamingActive ? Math.max(1, Math.floor(settledBudget * 2 / 3)) : 0;
|
|
36180
|
-
const liveRows = Math.min(liveDemand, liveCap);
|
|
36181
|
-
const settledViewportRows = Math.max(0, settledBudget - liveRows);
|
|
36182
|
-
const [scrollOffset, setScrollOffset] = (0, import_react.useState)(0);
|
|
36183
|
-
const previousHistory = (0, import_react.useRef)({ sessionKey: props.sessionKey, count: allSettledLines.length });
|
|
36184
|
-
const sameHistory = previousHistory.current.sessionKey === props.sessionKey;
|
|
36185
|
-
const growth = sameHistory ? Math.max(0, allSettledLines.length - previousHistory.current.count) : 0;
|
|
36186
|
-
const maxScrollOffset = Math.max(0, allSettledLines.length - settledViewportRows);
|
|
36187
|
-
const effectiveScrollOffset = sameHistory ? Math.min(maxScrollOffset, scrollOffset === 0 ? 0 : scrollOffset + growth) : 0;
|
|
36188
|
-
(0, import_react.useEffect)(() => {
|
|
36189
|
-
previousHistory.current = { sessionKey: props.sessionKey, count: allSettledLines.length };
|
|
36190
|
-
if (scrollOffset !== effectiveScrollOffset) setScrollOffset(effectiveScrollOffset);
|
|
36191
|
-
}, [props.sessionKey, allSettledLines.length, effectiveScrollOffset]);
|
|
36192
|
-
const scrollTranscript = (direction, page = false) => {
|
|
36193
|
-
if (!transcriptVisible || settledViewportRows <= 0) return;
|
|
36194
|
-
const step = page ? Math.max(1, settledViewportRows - 1) : 1;
|
|
36195
|
-
const amount = direction * step;
|
|
36196
|
-
if (amount === 0) return;
|
|
36197
|
-
setScrollOffset(current => Math.max(0, Math.min(maxScrollOffset, (current === scrollOffset ? effectiveScrollOffset : current) + amount)));
|
|
36198
|
-
};
|
|
36199
|
-
const scrollRef = (0, import_react.useRef)(scrollTranscript);
|
|
36200
|
-
scrollRef.current = scrollTranscript;
|
|
36201
|
-
(0, import_react.useEffect)(() => {
|
|
36202
|
-
const listener = delta => scrollRef.current(delta);
|
|
36203
|
-
dscodeWheelListeners.add(listener);
|
|
36204
|
-
return () => dscodeWheelListeners.delete(listener);
|
|
36205
|
-
}, []);
|
|
36206
|
-
const renderedSettled = transcriptWindow(allSettledLines, settledViewportRows, effectiveScrollOffset);
|
|
36207
|
-
const dynamicRows = Math.max(0, settledBudget - settledViewportRows);
|
|
36208
|
-
const liveBudget = dynamicRows === 0 ? 0 : streamingActive ? Math.max(0, dynamicRows - Math.min(streamingDemand, dynamicRows)) : dynamicRows;
|
|
36121
|
+
const MENU_RESERVE_ROWS = 5;
|
|
36122
|
+
const dynamicRows = Math.max(1, terminalRows - 8 - MENU_RESERVE_ROWS - composerGutterRows - (composerRows - 1) - Math.max(0, menuRows - MENU_RESERVE_ROWS));
|
|
36123
|
+
const streamingActive = view.streaming !== "" || showReasoning && view.streamingReasoning !== "";
|
|
36124
|
+
const deepDivingVisible = busy;
|
|
36125
|
+
const allLiveLines = (0, import_react.useMemo)(() => view.entries.slice(settled).flatMap((entry) => dscodeChatLines(entry, Math.max(1, terminalColumns - 2), showReasoning)), [
|
|
36126
|
+
view.entries,
|
|
36127
|
+
settled,
|
|
36128
|
+
terminalColumns,
|
|
36129
|
+
showReasoning
|
|
36130
|
+
]);
|
|
36131
|
+
const liveBudget = busy || streamingActive ? Math.max(1, Math.floor(dynamicRows / 3)) : Math.max(0, dynamicRows - (deepDivingVisible ? 1 : 0));
|
|
36209
36132
|
const visibleLiveLines = liveBudget === 0 ? [] : allLiveLines.slice(-liveBudget);
|
|
36210
36133
|
const streamRows = Math.max(1, dynamicRows - visibleLiveLines.length);
|
|
36211
|
-
const reasoningRows = 0;
|
|
36212
|
-
const answerRows = view.streaming === ""
|
|
36134
|
+
const reasoningRows = !showReasoning || view.streamingReasoning === "" || view.streaming !== "" ? 0 : streamRows;
|
|
36135
|
+
const answerRows = view.streaming === "" ? 0 : Math.max(1, streamRows - reasoningRows);
|
|
36213
36136
|
const liveAudit = clampLiveAllocation({
|
|
36214
36137
|
live: visibleLiveLines.length,
|
|
36215
36138
|
reasoning: reasoningRows,
|
|
@@ -36222,7 +36145,7 @@ function App(props) {
|
|
|
36222
36145
|
const auditedLiveLines = liveAudit.allocation.live === visibleLiveLines.length ? visibleLiveLines : visibleLiveLines.slice(-liveAudit.allocation.live);
|
|
36223
36146
|
const auditedReasoningRows = liveAudit.allocation.reasoning;
|
|
36224
36147
|
const auditedAnswerRows = liveAudit.allocation.answer;
|
|
36225
|
-
|
|
36148
|
+
const transcriptVisible = !emailOpen && !modelOpen && !helpOpen && !modeOpen && !permissionOpen && !resumeOpen && !pluginOpen && !jobsOpen && !statuslineOpen && !themeOpen && !languageOpen && !historyOpen && !agentsOpen && !subagentOpen && !todosOpen && !verboseOpen && diffView === void 0 && !approvalPending && !questionPending;
|
|
36226
36149
|
const modalVisible = emailOpen || modelOpen || helpOpen || modeOpen || permissionOpen || resumeOpen || pluginOpen || jobsOpen || statuslineOpen || themeOpen || languageOpen || historyOpen || agentsOpen || subagentOpen || todosOpen || verboseOpen && !approvalPending && !questionPending || diffView !== void 0 || approvalPending || questionPending;
|
|
36227
36150
|
const closeInspector = (0, import_react.useCallback)(() => {
|
|
36228
36151
|
setVerboseOpen(false);
|
|
@@ -36239,6 +36162,15 @@ function App(props) {
|
|
|
36239
36162
|
synchronizedReplayPending.current = false;
|
|
36240
36163
|
appStdout.write(SYNCHRONIZED_UPDATE_END);
|
|
36241
36164
|
}, [appStdout, refreshEpoch]);
|
|
36165
|
+
const settledNeedsTrim = settledRowsCache.current?.needsTrim === true;
|
|
36166
|
+
(0, import_react.useEffect)(() => {
|
|
36167
|
+
if (!settledNeedsTrim || busy || streamingActive) return;
|
|
36168
|
+
refreshScreen();
|
|
36169
|
+
}, [
|
|
36170
|
+
settledNeedsTrim,
|
|
36171
|
+
busy,
|
|
36172
|
+
streamingActive
|
|
36173
|
+
]);
|
|
36242
36174
|
const sessionHasImages = (0, import_react.useMemo)(() => view.entries.some((entry) => (entry.kind === "user" || entry.kind === "pending") && (entry.images?.length ?? 0) > 0), [view.entries]);
|
|
36243
36175
|
/** Apply one /model pick: record the selection, close the panel, report via notice. */
|
|
36244
36176
|
const applyModel = (row, effortId) => {
|
|
@@ -36471,15 +36403,14 @@ function App(props) {
|
|
|
36471
36403
|
onClose: closeModelSurface
|
|
36472
36404
|
});
|
|
36473
36405
|
}
|
|
36474
|
-
return (0, import_react.createElement)(Box, { flexDirection: "column",
|
|
36475
|
-
|
|
36476
|
-
|
|
36477
|
-
|
|
36406
|
+
return (0, import_react.createElement)(Box, { flexDirection: "column" }, (0, import_react.createElement)(MemoStaticTranscript, {
|
|
36407
|
+
key: refreshEpoch,
|
|
36408
|
+
items: settledRows
|
|
36409
|
+
}), emailOpen && !approvalPending && !questionPending ? (0, import_react.createElement)(DscodeEmailPanel, {
|
|
36478
36410
|
gmail, imap, columns: terminalColumns, rows: Math.max(3, terminalRows - 8 - composerGutterRows - composerRows),
|
|
36479
36411
|
close: () => setEmailOpen(false),
|
|
36480
36412
|
pick: mail => { props.steer(dscodeEmailPrompt(mail), [], props.sessionKey); setEmailOpen(false); }
|
|
36481
36413
|
}) : void 0,
|
|
36482
|
-
transcriptVisible && settledViewportRows > 0 ? (0, import_react.createElement)(StyledRows, { lines: renderedSettled }) : void 0,
|
|
36483
36414
|
transcriptVisible ? (0, import_react.createElement)(Box, { flexDirection: "column" }, auditedLiveLines.length === 0 ? void 0 : (0, import_react.createElement)(StyledRows, { lines: auditedLiveLines }), view.streamingReasoning !== "" && auditedReasoningRows > 0 ? showReasoning ? (0, import_react.createElement)(StreamTail, {
|
|
36484
36415
|
text: view.streamingReasoning,
|
|
36485
36416
|
prefix: "✻ ",
|
|
@@ -36634,7 +36565,7 @@ function App(props) {
|
|
|
36634
36565
|
setSubagentOpen(false);
|
|
36635
36566
|
},
|
|
36636
36567
|
close: () => setSubagentOpen(false)
|
|
36637
|
-
}) : void 0,
|
|
36568
|
+
}) : void 0, notice === void 0 ? void 0 : (0, import_react.createElement)(NoticeLine, {
|
|
36638
36569
|
text: notice.text,
|
|
36639
36570
|
tone: notice.tone,
|
|
36640
36571
|
columns: terminalColumns
|
|
@@ -36780,8 +36711,7 @@ function App(props) {
|
|
|
36780
36711
|
waveStyle,
|
|
36781
36712
|
maxRows: composerEditorCap,
|
|
36782
36713
|
onEditorRows: handleEditorRows,
|
|
36783
|
-
onMenuRows: handleMenuRows
|
|
36784
|
-
onTranscriptScroll: scrollTranscript
|
|
36714
|
+
onMenuRows: handleMenuRows
|
|
36785
36715
|
}), (0, import_react.createElement)(StatusLine, {
|
|
36786
36716
|
facts: {
|
|
36787
36717
|
fullSessionId: props.sessionKey,
|
|
@@ -37014,7 +36944,7 @@ function createSplitStdin(source) {
|
|
|
37014
36944
|
stalePasteTimer.unref?.();
|
|
37015
36945
|
};
|
|
37016
36946
|
const onChunk = (chunk) => {
|
|
37017
|
-
for (const unit of splitter.push(String(chunk)))
|
|
36947
|
+
for (const unit of splitter.push(String(chunk))) stream.write(unit);
|
|
37018
36948
|
if (splitter.openPaste()) armStalePasteTimer();
|
|
37019
36949
|
else disarmStalePasteTimer();
|
|
37020
36950
|
};
|
|
@@ -37058,8 +36988,7 @@ const internals = {
|
|
|
37058
36988
|
const focusReporting = isVsCodeTerminalEnv();
|
|
37059
36989
|
if (process.stdin.isTTY === true) process.stdin.setRawMode?.(true);
|
|
37060
36990
|
try {
|
|
37061
|
-
|
|
37062
|
-
process.stdout.write((keyboardEnhanced ? KEYBOARD_ENHANCE_ENABLE : "") + BRACKETED_PASTE_ENABLE + (focusReporting ? TERMINAL_FOCUS_REPORT_ENABLE : "") + (process.stdout.isTTY === true && dscodeMouseEnabled ? DSCODE_MOUSE_ENABLE : ""));
|
|
36991
|
+
process.stdout.write((keyboardEnhanced ? KEYBOARD_ENHANCE_ENABLE : "") + BRACKETED_PASTE_ENABLE + (focusReporting ? TERMINAL_FOCUS_REPORT_ENABLE : ""));
|
|
37063
36992
|
const tuiStdin = createSplitStdin(process.stdin);
|
|
37064
36993
|
const instance = render(element, {
|
|
37065
36994
|
exitOnCtrlC: false,
|
|
@@ -37072,7 +37001,7 @@ const internals = {
|
|
|
37072
37001
|
},
|
|
37073
37002
|
unmount() {
|
|
37074
37003
|
try {
|
|
37075
|
-
process.stdout.write((keyboardEnhanced ? KEYBOARD_ENHANCE_DISABLE : "") + BRACKETED_PASTE_DISABLE + (focusReporting ? TERMINAL_FOCUS_REPORT_DISABLE : "")
|
|
37004
|
+
process.stdout.write((keyboardEnhanced ? KEYBOARD_ENHANCE_DISABLE : "") + BRACKETED_PASTE_DISABLE + (focusReporting ? TERMINAL_FOCUS_REPORT_DISABLE : ""));
|
|
37076
37005
|
} finally {
|
|
37077
37006
|
try {
|
|
37078
37007
|
instance.unmount();
|
|
@@ -37084,7 +37013,6 @@ const internals = {
|
|
|
37084
37013
|
}
|
|
37085
37014
|
};
|
|
37086
37015
|
} catch (error) {
|
|
37087
|
-
if (process.stdout.isTTY === true) process.stdout.write(DSCODE_MOUSE_DISABLE);
|
|
37088
37016
|
if (process.stdin.isTTY === true) process.stdin.setRawMode?.(false);
|
|
37089
37017
|
throw error;
|
|
37090
37018
|
}
|