cli-jaw 1.5.0 → 1.6.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/README.ko.md +26 -19
- package/README.md +50 -22
- package/README.zh-CN.md +26 -19
- package/dist/bin/cli-jaw.js +5 -1
- package/dist/bin/cli-jaw.js.map +1 -1
- package/dist/bin/commands/dispatch.js +57 -0
- package/dist/bin/commands/dispatch.js.map +1 -0
- package/dist/lib/mcp-sync.js +1 -1
- package/dist/lib/mcp-sync.js.map +1 -1
- package/dist/lib/upload.js +14 -1
- package/dist/lib/upload.js.map +1 -1
- package/dist/server.js +57 -42
- package/dist/server.js.map +1 -1
- package/dist/src/agent/events.js +72 -13
- package/dist/src/agent/events.js.map +1 -1
- package/dist/src/agent/spawn.js +71 -29
- package/dist/src/agent/spawn.js.map +1 -1
- package/dist/src/cli/acp-client.js +4 -2
- package/dist/src/cli/acp-client.js.map +1 -1
- package/dist/src/cli/commands.js +6 -6
- package/dist/src/cli/commands.js.map +1 -1
- package/dist/src/cli/handlers.js +11 -9
- package/dist/src/cli/handlers.js.map +1 -1
- package/dist/src/cli/registry.js +7 -1
- package/dist/src/cli/registry.js.map +1 -1
- package/dist/src/core/config.js +15 -8
- package/dist/src/core/config.js.map +1 -1
- package/dist/src/core/db.js +18 -3
- package/dist/src/core/db.js.map +1 -1
- package/dist/src/core/employees.js +34 -0
- package/dist/src/core/employees.js.map +1 -0
- package/dist/src/discord/bot.js +72 -9
- package/dist/src/discord/bot.js.map +1 -1
- package/dist/src/discord/commands.js +12 -8
- package/dist/src/discord/commands.js.map +1 -1
- package/dist/src/orchestrator/distribute.js +57 -35
- package/dist/src/orchestrator/distribute.js.map +1 -1
- package/dist/src/orchestrator/gateway.js +3 -1
- package/dist/src/orchestrator/gateway.js.map +1 -1
- package/dist/src/orchestrator/pipeline.js +120 -27
- package/dist/src/orchestrator/pipeline.js.map +1 -1
- package/dist/src/orchestrator/research.js +5 -5
- package/dist/src/orchestrator/research.js.map +1 -1
- package/dist/src/orchestrator/scope.js +55 -0
- package/dist/src/orchestrator/scope.js.map +1 -0
- package/dist/src/orchestrator/state-machine.js +23 -21
- package/dist/src/orchestrator/state-machine.js.map +1 -1
- package/dist/src/orchestrator/worker-registry.js +9 -2
- package/dist/src/orchestrator/worker-registry.js.map +1 -1
- package/dist/src/prompt/builder.js +76 -37
- package/dist/src/prompt/builder.js.map +1 -1
- package/dist/src/prompt/templates/a1-system.md +40 -0
- package/dist/src/prompt/templates/employee.md +12 -4
- package/dist/src/prompt/templates/orchestration.md +17 -1
- package/dist/src/telegram/bot.js +7 -1
- package/dist/src/telegram/bot.js.map +1 -1
- package/package.json +4 -2
- package/public/assets/fonts/GeistVF.woff2 +0 -0
- package/public/assets/fonts/JetBrainsMono-Variable.woff2 +0 -0
- package/public/assets/providers/claude-color.svg +1 -0
- package/public/assets/providers/claude.svg +1 -0
- package/public/assets/providers/copilot-color.svg +1 -0
- package/public/assets/providers/copilot.svg +1 -0
- package/public/assets/providers/discord.svg +1 -0
- package/public/assets/providers/gemini-color.svg +1 -0
- package/public/assets/providers/gemini.svg +1 -0
- package/public/assets/providers/openai.svg +1 -0
- package/public/assets/providers/opencode.svg +1 -0
- package/public/assets/providers/telegram.svg +1 -0
- package/public/css/chat.css +79 -51
- package/public/css/diagram.css +348 -0
- package/public/css/layout.css +38 -11
- package/public/css/markdown.css +64 -18
- package/public/css/modals.css +3 -3
- package/public/css/orc-state.css +9 -9
- package/public/css/sidebar.css +37 -3
- package/public/css/tool-ui.css +46 -11
- package/public/css/variables.css +63 -63
- package/public/dist/assets/api-Bbmmo0o1.js +1 -0
- package/public/dist/assets/architecture-YZFGNWBL-BxiHqtOH.js +1 -0
- package/public/dist/assets/architectureDiagram-Q4EWVU46-CJTGDw5p.js +1 -0
- package/public/dist/assets/blockDiagram-DXYQGD6D-Btl5Y-Er.js +1 -0
- package/public/dist/assets/c4Diagram-AHTNJAMY-sDfjW4ZF.js +1 -0
- package/public/dist/assets/classDiagram-6PBFFD2Q-ByCgggL2.js +1 -0
- package/public/dist/assets/classDiagram-v2-HSJHXN6E-t1amaXkU.js +1 -0
- package/public/dist/assets/constants-C8_0OtK2.js +1 -0
- package/public/dist/assets/cose-bilkent-S5V4N54A-eOSFGdaE.js +1 -0
- package/public/dist/assets/dagre-KV5264BT-OCB5j8Q6.js +1 -0
- package/public/dist/assets/diagram-5BDNPKRD-C-4fgK5P.js +1 -0
- package/public/dist/assets/diagram-G4DWMVQ6-C6vmHKDV.js +1 -0
- package/public/dist/assets/diagram-MMDJMWI5-BMCo_wmt.js +1 -0
- package/public/dist/assets/diagram-TYMM5635-DaCLdttJ.js +1 -0
- package/public/dist/assets/employees-D5n7mX5v.js +39 -0
- package/public/dist/assets/erDiagram-SMLLAGMA-BiTRdm5s.js +1 -0
- package/public/dist/assets/flowDiagram-DWJPFMVM-sv6jVi0d.js +1 -0
- package/public/dist/assets/ganttDiagram-T4ZO3ILL-jCP3OW23.js +1 -0
- package/public/dist/assets/gitGraph-7Q5UKJZL-BIeKLxpm.js +1 -0
- package/public/dist/assets/gitGraphDiagram-UUTBAWPF-CokylnbW.js +1 -0
- package/public/dist/assets/index-CLd0BsAu.js +49 -0
- package/public/dist/assets/index-D6ci1wCN.css +1 -0
- package/public/dist/assets/info-OMHHGYJF-CIEl5dWF.js +1 -0
- package/public/dist/assets/infoDiagram-42DDH7IO-BBnK1Bh2.js +1 -0
- package/public/dist/assets/ishikawaDiagram-UXIWVN3A-qXIz0VhS.js +1 -0
- package/public/dist/assets/journeyDiagram-VCZTEJTY-BdrOLof3.js +1 -0
- package/public/dist/assets/kanban-definition-6JOO6SKY-CcX7CE04.js +1 -0
- package/public/dist/assets/mermaid.core-BoxIvw7E.js +1 -0
- package/public/dist/assets/mindmap-definition-QFDTVHPH-CdXARskX.js +1 -0
- package/public/dist/assets/packet-4T2RLAQJ-Bz4ZwYZ3.js +1 -0
- package/public/dist/assets/pie-ZZUOXDRM-AtGL3wZ2.js +1 -0
- package/public/dist/assets/pieDiagram-DEJITSTG-B5SOq9Yr.js +1 -0
- package/public/dist/assets/quadrantDiagram-34T5L4WZ-D0uNWgpI.js +1 -0
- package/public/dist/assets/radar-PYXPWWZC-AbJSfeqB.js +1 -0
- package/public/dist/assets/render-C8N0rp4L.js +25 -0
- package/public/dist/assets/requirementDiagram-MS252O5E-62td6IQ-.js +1 -0
- package/public/dist/assets/sankeyDiagram-XADWPNL6-Crg_02iC.js +1 -0
- package/public/dist/assets/sequenceDiagram-FGHM5R23-fbCocZHj.js +1 -0
- package/public/dist/assets/settings-BJR-IGM5.js +41 -0
- package/public/dist/assets/settings-Dm6OnPmY.js +1 -0
- package/public/dist/assets/skills-D6jv9AIs.js +1 -0
- package/public/dist/assets/skills-uywskdFh.js +12 -0
- package/public/dist/assets/slash-commands-CCDonT40.js +1 -0
- package/public/dist/assets/{slash-commands-DMsE88bu.js → slash-commands-DWvL-VDU.js} +1 -1
- package/public/dist/assets/stateDiagram-FHFEXIEX-Gy3DhXxQ.js +1 -0
- package/public/dist/assets/stateDiagram-v2-QKLJ7IA2-DJc-FW9O.js +1 -0
- package/public/dist/assets/timeline-definition-GMOUNBTQ-B3cA9DgY.js +1 -0
- package/public/dist/assets/treeView-SZITEDCU-Cn58DIbB.js +1 -0
- package/public/dist/assets/treemap-W4RFUUIX-DPcYjDzH.js +1 -0
- package/public/dist/assets/ui-C1daR00l.js +1 -0
- package/public/dist/assets/ui-D-oFkXed.js +131 -0
- package/public/dist/assets/vendor-icons-1Ec7ZWcT.js +1 -0
- package/public/dist/assets/{vendor-mermaid-COidH9HB.js → vendor-mermaid-lvHqQdfg.js} +4 -4
- package/public/dist/assets/vennDiagram-DHZGUBPP-DkBfxilo.js +1 -0
- package/public/dist/assets/wardley-RL74JXVD-6Dg0PJ4H.js +1 -0
- package/public/dist/assets/wardleyDiagram-NUSXRM2D-Dsntl_vy.js +1 -0
- package/public/dist/assets/ws-Dnn8HG8B.js +2 -0
- package/public/dist/assets/xychartDiagram-5P7HB3ND-B_McB5GE.js +1 -0
- package/public/dist/index.html +63 -55
- package/public/index.html +62 -53
- package/public/js/constants.ts +8 -2
- package/public/js/diagram/iframe-renderer.ts +559 -0
- package/public/js/diagram/types.ts +129 -0
- package/public/js/diagram/widget-validator.ts +82 -0
- package/public/js/features/chat.ts +24 -12
- package/public/js/features/employees.ts +3 -2
- package/public/js/features/heartbeat.ts +4 -3
- package/public/js/features/memory.ts +4 -3
- package/public/js/features/process-block.ts +12 -11
- package/public/js/features/settings-cli-status.ts +10 -7
- package/public/js/features/settings-core.ts +13 -3
- package/public/js/features/settings-discord.ts +9 -0
- package/public/js/features/settings-mcp.ts +8 -7
- package/public/js/features/settings-stt.ts +4 -4
- package/public/js/features/settings-templates.ts +10 -8
- package/public/js/features/settings-types.ts +1 -1
- package/public/js/features/settings.ts +1 -1
- package/public/js/features/sidebar.ts +37 -7
- package/public/js/features/skills.ts +4 -3
- package/public/js/features/theme.ts +4 -0
- package/public/js/features/tool-ui.ts +6 -5
- package/public/js/features/voice-recorder.ts +2 -1
- package/public/js/icons.ts +257 -0
- package/public/js/main.ts +9 -3
- package/public/js/provider-icons.ts +88 -0
- package/public/js/render.ts +493 -30
- package/public/js/streaming-render.ts +3 -3
- package/public/js/ui.ts +38 -18
- package/public/js/ws.ts +17 -10
- package/public/locales/en.json +89 -88
- package/public/locales/ko.json +89 -88
- package/scripts/release-1.6.0.sh +69 -0
- package/scripts/release-preview.sh +1 -1
- package/dist/lib/token-keepalive.js +0 -34
- package/dist/lib/token-keepalive.js.map +0 -1
- package/public/dist/assets/api-BlPw3bUI.js +0 -1
- package/public/dist/assets/architecture-YZFGNWBL-BkS7SZQi.js +0 -1
- package/public/dist/assets/architectureDiagram-Q4EWVU46-Dl3iBKeR.js +0 -1
- package/public/dist/assets/blockDiagram-DXYQGD6D-DPr4D17p.js +0 -1
- package/public/dist/assets/c4Diagram-AHTNJAMY-CfoxJtDk.js +0 -1
- package/public/dist/assets/classDiagram-6PBFFD2Q-BOAdHnnB.js +0 -1
- package/public/dist/assets/classDiagram-v2-HSJHXN6E-B2QCJXWC.js +0 -1
- package/public/dist/assets/constants-DshMUJbo.js +0 -1
- package/public/dist/assets/cose-bilkent-S5V4N54A-CA14jk7w.js +0 -1
- package/public/dist/assets/dagre-KV5264BT-BVwNaSwC.js +0 -1
- package/public/dist/assets/diagram-5BDNPKRD-CHqIAvdc.js +0 -1
- package/public/dist/assets/diagram-G4DWMVQ6-DxvsCvTP.js +0 -1
- package/public/dist/assets/diagram-MMDJMWI5-DqOPO7dl.js +0 -1
- package/public/dist/assets/diagram-TYMM5635-C9xMWPQn.js +0 -1
- package/public/dist/assets/employees-CFRlsbHm.js +0 -39
- package/public/dist/assets/erDiagram-SMLLAGMA-BTmpfRkm.js +0 -1
- package/public/dist/assets/flowDiagram-DWJPFMVM-DZBSQAKA.js +0 -1
- package/public/dist/assets/ganttDiagram-T4ZO3ILL-TAEMCRbT.js +0 -1
- package/public/dist/assets/gitGraph-7Q5UKJZL-bbxndRNA.js +0 -1
- package/public/dist/assets/gitGraphDiagram-UUTBAWPF-CBxtx0MB.js +0 -1
- package/public/dist/assets/index-1Gg-6jeC.css +0 -1
- package/public/dist/assets/index-CQHqXjrK.js +0 -49
- package/public/dist/assets/info-OMHHGYJF-DRXq_Ywr.js +0 -1
- package/public/dist/assets/infoDiagram-42DDH7IO-C7FFwX4m.js +0 -1
- package/public/dist/assets/ishikawaDiagram-UXIWVN3A-DEZJE79j.js +0 -1
- package/public/dist/assets/journeyDiagram-VCZTEJTY-ZHLiY6GV.js +0 -1
- package/public/dist/assets/kanban-definition-6JOO6SKY-NP7pY7ML.js +0 -1
- package/public/dist/assets/mermaid.core-CHuluSlD.js +0 -1
- package/public/dist/assets/mindmap-definition-QFDTVHPH-Bd1OgfN_.js +0 -1
- package/public/dist/assets/packet-4T2RLAQJ-CGu8ST97.js +0 -1
- package/public/dist/assets/pie-ZZUOXDRM-CDG65mhS.js +0 -1
- package/public/dist/assets/pieDiagram-DEJITSTG-BbMBHLDM.js +0 -1
- package/public/dist/assets/quadrantDiagram-34T5L4WZ-CDCDgI1e.js +0 -1
- package/public/dist/assets/radar-PYXPWWZC-1gS-6ylu.js +0 -1
- package/public/dist/assets/render-YHvL5VM_.js +0 -6
- package/public/dist/assets/requirementDiagram-MS252O5E-DkmvOtYz.js +0 -1
- package/public/dist/assets/sankeyDiagram-XADWPNL6-GNcXIYsL.js +0 -1
- package/public/dist/assets/sequenceDiagram-FGHM5R23-BFrw2n6x.js +0 -1
- package/public/dist/assets/settings-BQF_u5px.js +0 -37
- package/public/dist/assets/settings-C5Q9IPjJ.js +0 -1
- package/public/dist/assets/skills-9Pd2rOw-.js +0 -1
- package/public/dist/assets/skills-BI7sQAdk.js +0 -12
- package/public/dist/assets/slash-commands-FMpJzlDB.js +0 -1
- package/public/dist/assets/stateDiagram-FHFEXIEX-BLgKnllT.js +0 -1
- package/public/dist/assets/stateDiagram-v2-QKLJ7IA2-CbzuWsSa.js +0 -1
- package/public/dist/assets/timeline-definition-GMOUNBTQ-CcZTJ3gL.js +0 -1
- package/public/dist/assets/treeView-SZITEDCU-BDqBsaH1.js +0 -1
- package/public/dist/assets/treemap-W4RFUUIX-BaWHA3Di.js +0 -1
- package/public/dist/assets/ui-BukgLHuh.js +0 -29
- package/public/dist/assets/ui-Bvz1JfTE.js +0 -1
- package/public/dist/assets/vennDiagram-DHZGUBPP-BWV_j1bh.js +0 -1
- package/public/dist/assets/wardley-RL74JXVD-C7gKA3d7.js +0 -1
- package/public/dist/assets/wardleyDiagram-NUSXRM2D-BUoq_wug.js +0 -1
- package/public/dist/assets/ws-S_AZgx7L.js +0 -2
- package/public/dist/assets/xychartDiagram-5P7HB3ND-PvT5Ec82.js +0 -1
- /package/public/dist/assets/{api-B8XKQ4OT.js → api-Ci-lgwRp.js} +0 -0
- /package/public/dist/assets/{locale-BjoAcbis.js → locale-DIXc-_34.js} +0 -0
package/public/js/ui.ts
CHANGED
|
@@ -7,7 +7,10 @@ import { api } from './api.js';
|
|
|
7
7
|
import { cacheMessages, getCachedMessages, appendCachedMessage } from './features/idb-cache.js';
|
|
8
8
|
import { getVirtualScroll, VS_THRESHOLD } from './virtual-scroll.js';
|
|
9
9
|
import { createStreamRenderer, appendChunk, finalizeStream, type StreamState } from './streaming-render.js';
|
|
10
|
+
import { activateWidgets } from './diagram/iframe-renderer.js';
|
|
10
11
|
import { renderLiveToolActivity, cleanupToolElements, bindToolItemInteractions, type ToolLogEntry } from './features/tool-ui.js';
|
|
12
|
+
import { ICONS, emojiToIcon, emojiToStatus, isCompletionEmoji } from './icons.js';
|
|
13
|
+
import { providerIcon } from './provider-icons.js';
|
|
11
14
|
import {
|
|
12
15
|
createProcessBlock,
|
|
13
16
|
addStep,
|
|
@@ -18,7 +21,7 @@ import {
|
|
|
18
21
|
bindProcessBlockInteractions,
|
|
19
22
|
type ProcessStep,
|
|
20
23
|
} from './features/process-block.js';
|
|
21
|
-
interface MessageItem { role: string; content: string; tool_log?: string | null; }
|
|
24
|
+
interface MessageItem { role: string; content: string; tool_log?: string | null; cli?: string | null; }
|
|
22
25
|
|
|
23
26
|
function parseToolLog(toolLog?: string | null): ToolLogEntry[] {
|
|
24
27
|
if (!toolLog) return [];
|
|
@@ -30,13 +33,19 @@ function parseToolLog(toolLog?: string | null): ToolLogEntry[] {
|
|
|
30
33
|
}
|
|
31
34
|
}
|
|
32
35
|
|
|
36
|
+
function getAgentIcon(_cli?: string | null): string {
|
|
37
|
+
// Chat mascot is always the shark — provider icons are for header/sidebar only
|
|
38
|
+
return ICONS.shark;
|
|
39
|
+
}
|
|
40
|
+
|
|
33
41
|
function toProcessSteps(tools: ToolLogEntry[]): ProcessStep[] {
|
|
34
42
|
return tools.map((tool: any) => ({
|
|
35
43
|
id: crypto.randomUUID(),
|
|
36
|
-
icon: tool.icon
|
|
44
|
+
icon: tool.icon ? emojiToIcon(tool.icon) : ICONS.tool,
|
|
37
45
|
label: tool.label || tool.name || 'tool',
|
|
38
46
|
type: tool.toolType || 'tool',
|
|
39
47
|
detail: tool.detail || '',
|
|
48
|
+
stepRef: tool.stepRef || '',
|
|
40
49
|
status: tool.status || 'done',
|
|
41
50
|
startTime: Date.now(),
|
|
42
51
|
}));
|
|
@@ -49,11 +58,11 @@ export function setStatus(s: string): void {
|
|
|
49
58
|
document.getElementById('typingIndicator')?.classList.toggle('active', state.agentBusy);
|
|
50
59
|
if (s === 'running') {
|
|
51
60
|
if (badge) { badge.className = 'status-badge status-running'; badge.textContent = 'running'; }
|
|
52
|
-
if (btn) { btn.
|
|
61
|
+
if (btn) { btn.innerHTML = ICONS.stop; btn.title = t('btn.stop'); btn.classList.add('stop-mode'); }
|
|
53
62
|
showSkeleton();
|
|
54
63
|
} else {
|
|
55
64
|
if (badge) { badge.className = 'status-badge status-idle'; badge.textContent = 'idle'; }
|
|
56
|
-
if (btn) { btn.
|
|
65
|
+
if (btn) { btn.innerHTML = ICONS.send; btn.title = 'Send'; btn.classList.remove('stop-mode'); }
|
|
57
66
|
removeSkeleton();
|
|
58
67
|
updateQueueBadge(0);
|
|
59
68
|
}
|
|
@@ -110,7 +119,7 @@ export function addSystemMsg(text: string, extraClass?: string, type?: string):
|
|
|
110
119
|
const div = document.createElement('div');
|
|
111
120
|
const typeClass = type ? ` msg-type-${type}` : '';
|
|
112
121
|
div.className = 'msg msg-system' + typeClass + (extraClass ? ' ' + extraClass : '');
|
|
113
|
-
div.
|
|
122
|
+
div.innerHTML = text;
|
|
114
123
|
container.appendChild(div);
|
|
115
124
|
container.scrollTop = container.scrollHeight;
|
|
116
125
|
}
|
|
@@ -143,9 +152,11 @@ export function showProcessStep(step: ProcessStep): void {
|
|
|
143
152
|
}
|
|
144
153
|
}
|
|
145
154
|
if (state.currentProcessBlock) {
|
|
146
|
-
// Completion
|
|
147
|
-
|
|
148
|
-
|
|
155
|
+
// Completion detection: prefer semantic status field, fall back to emoji check
|
|
156
|
+
const resolvedStatus = (step.status && step.status !== 'running')
|
|
157
|
+
? step.status
|
|
158
|
+
: emojiToStatus(step.icon);
|
|
159
|
+
if (resolvedStatus === 'done' || resolvedStatus === 'error') {
|
|
149
160
|
// Prefer matching by stepRef (stable correlation), fall back to label
|
|
150
161
|
const ref = step.stepRef;
|
|
151
162
|
const match = ref
|
|
@@ -154,7 +165,7 @@ export function showProcessStep(step: ProcessStep): void {
|
|
|
154
165
|
: [...state.currentProcessBlock.steps].reverse()
|
|
155
166
|
.find(s => s.status === 'running' && s.label === step.label);
|
|
156
167
|
if (match) {
|
|
157
|
-
updateStepStatus(state.currentProcessBlock, match.id,
|
|
168
|
+
updateStepStatus(state.currentProcessBlock, match.id, resolvedStatus);
|
|
158
169
|
scrollToBottom();
|
|
159
170
|
return;
|
|
160
171
|
}
|
|
@@ -162,7 +173,7 @@ export function showProcessStep(step: ProcessStep): void {
|
|
|
162
173
|
const anyRunning = [...state.currentProcessBlock.steps].reverse()
|
|
163
174
|
.find(s => s.status === 'running');
|
|
164
175
|
if (anyRunning) {
|
|
165
|
-
updateStepStatus(state.currentProcessBlock, anyRunning.id,
|
|
176
|
+
updateStepStatus(state.currentProcessBlock, anyRunning.id, resolvedStatus);
|
|
166
177
|
scrollToBottom();
|
|
167
178
|
return;
|
|
168
179
|
}
|
|
@@ -180,6 +191,8 @@ export function showProcessStep(step: ProcessStep): void {
|
|
|
180
191
|
return;
|
|
181
192
|
}
|
|
182
193
|
}
|
|
194
|
+
// Convert emoji icon to SVG before adding step
|
|
195
|
+
step.icon = emojiToIcon(step.icon);
|
|
183
196
|
addStep(state.currentProcessBlock, step);
|
|
184
197
|
}
|
|
185
198
|
scrollToBottom();
|
|
@@ -222,13 +235,15 @@ export function finalizeAgent(text: string, toolLog?: ToolLogEntry[]): void {
|
|
|
222
235
|
state.currentAgentDiv = addMessage('agent', '');
|
|
223
236
|
}
|
|
224
237
|
const content = (state.currentAgentDiv as HTMLElement)?.querySelector('.msg-content');
|
|
225
|
-
//
|
|
226
|
-
const
|
|
238
|
+
// Live stream is preview-only; agent_done text stays authoritative.
|
|
239
|
+
const streamedText = currentStream ? finalizeStream(currentStream) : '';
|
|
240
|
+
const finalText = text || streamedText;
|
|
227
241
|
currentStream = null;
|
|
228
242
|
// Skip static tool HTML when process block already shows tool summary
|
|
229
243
|
const toolHtml = hasTools && !hadProcessBlock ? buildProcessBlockHtml(toProcessSteps(toolLog!), true) : '';
|
|
230
244
|
if (content) content.innerHTML = toolHtml + renderMarkdown(finalText);
|
|
231
245
|
if (content) content.setAttribute('data-raw', stripOrchestration(finalText));
|
|
246
|
+
if (content) activateWidgets(content as HTMLElement);
|
|
232
247
|
}
|
|
233
248
|
currentStream = null;
|
|
234
249
|
state.currentAgentDiv = null;
|
|
@@ -239,7 +254,7 @@ export function finalizeAgent(text: string, toolLog?: ToolLogEntry[]): void {
|
|
|
239
254
|
if (text) appendCachedMessage('assistant', text).catch(() => {});
|
|
240
255
|
}
|
|
241
256
|
|
|
242
|
-
export function addMessage(role: string, text: string): HTMLDivElement {
|
|
257
|
+
export function addMessage(role: string, text: string, cli?: string | null): HTMLDivElement {
|
|
243
258
|
const container = document.getElementById('chatMessages');
|
|
244
259
|
const vs = getVirtualScroll();
|
|
245
260
|
if (vs.active) vs.flushToDOM();
|
|
@@ -252,7 +267,7 @@ export function addMessage(role: string, text: string): HTMLDivElement {
|
|
|
252
267
|
const div = document.createElement('div');
|
|
253
268
|
if (role === 'agent') {
|
|
254
269
|
div.className = 'msg msg-agent';
|
|
255
|
-
div.innerHTML = `<div class="agent-icon" aria-hidden="true"
|
|
270
|
+
div.innerHTML = `<div class="agent-icon" aria-hidden="true">${getAgentIcon(cli)}</div><div class="agent-body"><div class="msg-content">${rendered}</div><button class="msg-copy" title="Copy" aria-label="Copy message"></button></div>`;
|
|
256
271
|
} else {
|
|
257
272
|
div.className = `msg msg-${role}`;
|
|
258
273
|
div.innerHTML = `<div class="msg-label">${label}</div><div class="msg-content">${rendered}</div><button class="msg-copy" title="Copy" aria-label="Copy message"></button>`;
|
|
@@ -260,6 +275,7 @@ export function addMessage(role: string, text: string): HTMLDivElement {
|
|
|
260
275
|
const contentEl = div.querySelector('.msg-content');
|
|
261
276
|
if (contentEl) contentEl.setAttribute('data-raw', stripOrchestration(text));
|
|
262
277
|
container?.appendChild(div);
|
|
278
|
+
activateWidgets(div);
|
|
263
279
|
scrollToBottom();
|
|
264
280
|
return div;
|
|
265
281
|
}
|
|
@@ -328,14 +344,18 @@ export async function loadMessages(): Promise<void> {
|
|
|
328
344
|
const tools = m.role === 'assistant' ? parseToolLog(m.tool_log) : [];
|
|
329
345
|
const toolHtml = tools.length > 0 ? buildProcessBlockHtml(toProcessSteps(tools), true) : '';
|
|
330
346
|
const html = role === 'agent'
|
|
331
|
-
? `<div class="msg msg-agent"><div class="agent-icon" aria-hidden="true"
|
|
347
|
+
? `<div class="msg msg-agent"><div class="agent-icon" aria-hidden="true">${getAgentIcon(m.cli)}</div><div class="agent-body">${toolHtml}<div class="msg-content" data-raw="${escapeHtml(stripOrchestration(m.content))}">${rendered}</div><button class="msg-copy" title="Copy" aria-label="Copy message"></button></div></div>`
|
|
332
348
|
: `<div class="msg msg-${role}"><div class="msg-label">${label}</div><div class="msg-content" data-raw="${escapeHtml(stripOrchestration(m.content))}">${rendered}</div><button class="msg-copy" title="Copy" aria-label="Copy message"></button></div>`;
|
|
333
349
|
vs.addItem(crypto.randomUUID(), html);
|
|
334
350
|
}
|
|
335
351
|
vs.scrollToBottom();
|
|
352
|
+
requestAnimationFrame(() => {
|
|
353
|
+
const chatElRef = document.getElementById('chatMessages');
|
|
354
|
+
if (chatElRef) activateWidgets(chatElRef);
|
|
355
|
+
});
|
|
336
356
|
} else {
|
|
337
357
|
msgs.forEach(m => {
|
|
338
|
-
const div = addMessage(m.role === 'assistant' ? 'agent' : m.role, m.content);
|
|
358
|
+
const div = addMessage(m.role === 'assistant' ? 'agent' : m.role, m.content, m.cli);
|
|
339
359
|
if (m.role === 'assistant') {
|
|
340
360
|
const tools = parseToolLog(m.tool_log);
|
|
341
361
|
if (tools.length > 0) {
|
|
@@ -366,7 +386,7 @@ export async function loadMessages(): Promise<void> {
|
|
|
366
386
|
const cached = await getCachedMessages();
|
|
367
387
|
if (cached.length > 0) {
|
|
368
388
|
cached.forEach(m => addMessage(m.role === 'assistant' ? 'agent' : m.role, m.content));
|
|
369
|
-
|
|
389
|
+
addSystemMsg(`${ICONS.warning} 오프라인 모드 — 캐시된 메시지 표시 중`);
|
|
370
390
|
}
|
|
371
391
|
showEmptyState();
|
|
372
392
|
}
|
|
@@ -406,7 +426,7 @@ export function initMsgCopy(): void {
|
|
|
406
426
|
const text = content.getAttribute('data-raw') || content.innerText || content.textContent || '';
|
|
407
427
|
navigator.clipboard.writeText(text).then(() => {
|
|
408
428
|
btn.classList.add('copied');
|
|
409
|
-
btn.
|
|
429
|
+
btn.innerHTML = ICONS.checkSimple;
|
|
410
430
|
setTimeout(() => {
|
|
411
431
|
btn.classList.remove('copied');
|
|
412
432
|
btn.textContent = '';
|
package/public/js/ws.ts
CHANGED
|
@@ -3,6 +3,8 @@ import { state } from './state.js';
|
|
|
3
3
|
import { setStatus, updateQueueBadge, addSystemMsg, appendAgentText, finalizeAgent, addMessage, showProcessStep, cleanupToolActivity } from './ui.js';
|
|
4
4
|
import { t, getLang } from './features/i18n.js';
|
|
5
5
|
import { getVirtualScroll } from './virtual-scroll.js';
|
|
6
|
+
import { ICONS, emojiToIcon } from './icons.js';
|
|
7
|
+
import { escapeHtml } from './render.js';
|
|
6
8
|
import type { OrcStateName } from './state.js';
|
|
7
9
|
|
|
8
10
|
const ROADMAP_PHASES = ['P', 'A', 'B', 'C'] as const;
|
|
@@ -36,6 +38,7 @@ function positionShark(roadmap: HTMLElement, shark: HTMLElement, phase: string):
|
|
|
36
38
|
|
|
37
39
|
interface WsMessage {
|
|
38
40
|
type: string;
|
|
41
|
+
scope?: string;
|
|
39
42
|
running?: boolean;
|
|
40
43
|
status?: string;
|
|
41
44
|
agentId?: string;
|
|
@@ -68,6 +71,8 @@ interface WsMessage {
|
|
|
68
71
|
// Agent phase state (populated by agent_status events from orchestrator)
|
|
69
72
|
const agentPhaseState: Record<string, { phase: string; phaseLabel: string }> = {};
|
|
70
73
|
|
|
74
|
+
let currentOrcScope = '';
|
|
75
|
+
|
|
71
76
|
/** Hydrate agent phase cache from snapshot (used after reconnect) */
|
|
72
77
|
export function hydrateAgentPhases(workers: Array<{
|
|
73
78
|
agentId: string;
|
|
@@ -214,10 +219,10 @@ export function connect(): void {
|
|
|
214
219
|
} else if (msg.type === 'queue_update') {
|
|
215
220
|
updateQueueBadge(msg.pending || 0);
|
|
216
221
|
} else if (msg.type === 'worklog_created') {
|
|
217
|
-
addSystemMsg(
|
|
222
|
+
addSystemMsg(`${ICONS.clipboard} Worklog: ${escapeHtml(msg.path || '')}`);
|
|
218
223
|
} else if (msg.type === 'round_start') {
|
|
219
224
|
const agents = (msg.agentPhases || msg.subtasks || []);
|
|
220
|
-
const names = agents.map(a => a.agent || a.name || '').join(', ');
|
|
225
|
+
const names = agents.map(a => escapeHtml(a.agent || a.name || '')).join(', ');
|
|
221
226
|
addSystemMsg(t('ws.roundStart', { round: msg.round || 0, count: agents.length, names }));
|
|
222
227
|
} else if (msg.type === 'round_done') {
|
|
223
228
|
if (msg.action === 'complete') {
|
|
@@ -233,21 +238,21 @@ export function connect(): void {
|
|
|
233
238
|
showProcessStep({
|
|
234
239
|
id: `step-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
235
240
|
type: stepType,
|
|
236
|
-
icon: msg.icon ||
|
|
241
|
+
icon: msg.icon || ICONS.tool,
|
|
237
242
|
label: msg.label || '',
|
|
238
243
|
detail: msg.detail || '',
|
|
239
244
|
stepRef: msg.stepRef || '',
|
|
240
|
-
status: 'running',
|
|
245
|
+
status: (msg.status as 'running' | 'done' | 'error') || 'running',
|
|
241
246
|
startTime: Date.now(),
|
|
242
247
|
});
|
|
243
248
|
} else if (msg.type === 'agent_output') {
|
|
244
249
|
appendAgentText(msg.text || '');
|
|
245
250
|
} else if (msg.type === 'agent_retry') {
|
|
246
|
-
addSystemMsg(t('ws.retry', { cli: msg.cli || '', delay: msg.delay || 10 }), 'tool-activity');
|
|
251
|
+
addSystemMsg(t('ws.retry', { cli: escapeHtml(msg.cli || ''), delay: msg.delay || 10 }), 'tool-activity');
|
|
247
252
|
} else if (msg.type === 'agent_fallback') {
|
|
248
|
-
addSystemMsg(t('ws.fallback', { from: msg.from || '', to: msg.to || '' }), 'tool-activity');
|
|
253
|
+
addSystemMsg(t('ws.fallback', { from: escapeHtml(msg.from || ''), to: escapeHtml(msg.to || '') }), 'tool-activity');
|
|
249
254
|
} else if (msg.type === 'agent_smoke') {
|
|
250
|
-
addSystemMsg(
|
|
255
|
+
addSystemMsg(`${ICONS.warning} ${escapeHtml(msg.cli || 'agent')}: smoke response detected — auto-continuing`, 'tool-activity');
|
|
251
256
|
} else if (msg.type === 'agent_done') {
|
|
252
257
|
finalizeAgent(msg.text || '', msg.toolLog);
|
|
253
258
|
} else if (msg.type === 'orchestrate_done') {
|
|
@@ -258,13 +263,14 @@ export function connect(): void {
|
|
|
258
263
|
const el = document.getElementById('chatMessages');
|
|
259
264
|
if (el) el.innerHTML = '';
|
|
260
265
|
} else if (msg.type === 'session_reset') {
|
|
261
|
-
addSystemMsg(
|
|
266
|
+
addSystemMsg(`${ICONS.refresh} Session reset — history preserved`, 'tool-activity');
|
|
262
267
|
} else if (msg.type === 'agent_added' || msg.type === 'agent_updated' || msg.type === 'agent_deleted') {
|
|
263
268
|
import('./features/employees.js').then(m => m.loadEmployees());
|
|
264
269
|
} else if (msg.type === 'orc_state') {
|
|
270
|
+
if (msg.scope && currentOrcScope && msg.scope !== currentOrcScope) return;
|
|
265
271
|
applyOrcState(typeof msg.state === 'string' ? msg.state : 'IDLE', msg.title);
|
|
266
272
|
} else if (msg.type === 'new_message' && (msg.source === 'telegram' || msg.source === 'discord')) {
|
|
267
|
-
addMessage(msg.role === 'assistant' ? 'agent' : (msg.role || 'user'), msg.content || '');
|
|
273
|
+
addMessage(msg.role === 'assistant' ? 'agent' : (msg.role || 'user'), msg.content || '', msg.cli);
|
|
268
274
|
}
|
|
269
275
|
};
|
|
270
276
|
state.ws.onopen = () => {
|
|
@@ -281,6 +287,7 @@ export function connect(): void {
|
|
|
281
287
|
fetch('/api/orchestrate/snapshot')
|
|
282
288
|
.then(r => r.json())
|
|
283
289
|
.then((snap: any) => {
|
|
290
|
+
currentOrcScope = String(snap.orc.scope || '');
|
|
284
291
|
applyOrcState(snap.orc.state);
|
|
285
292
|
hydrateAgentPhases(snap.workers);
|
|
286
293
|
updateQueueBadge(snap.runtime.queuePending);
|
|
@@ -295,7 +302,7 @@ export function connect(): void {
|
|
|
295
302
|
console.log('[ws] disconnected, reconnecting in 2s...');
|
|
296
303
|
import('./ui.js').then(m => m.cleanupToolActivity());
|
|
297
304
|
setStatus('idle');
|
|
298
|
-
addSystemMsg(
|
|
305
|
+
addSystemMsg(`${ICONS.exec} 연결 끊김 — 재연결 중...`, 'tool-activity');
|
|
299
306
|
setTimeout(connect, 2000);
|
|
300
307
|
};
|
|
301
308
|
}
|
package/public/locales/en.json
CHANGED
|
@@ -34,42 +34,42 @@
|
|
|
34
34
|
"cmd.steer.tg_desc": "Redirect agent to new task",
|
|
35
35
|
"cmd.steer.noPrompt": "Usage: /steer <new prompt>",
|
|
36
36
|
"cmd.steer.noAgent": "No agent is currently running.",
|
|
37
|
-
"cmd.steer.started": "
|
|
37
|
+
"cmd.steer.started": "Redirecting...",
|
|
38
38
|
"cmd.unknown": "Unknown command: /{name}\nUse /help to see available commands.",
|
|
39
|
-
"cmd.unsupported": "
|
|
40
|
-
"cmd.error": "
|
|
39
|
+
"cmd.unsupported": "/{name} is not available on {iface}.",
|
|
40
|
+
"cmd.error": "/{name} execution error: {msg}",
|
|
41
41
|
"cmd.helpTitle": "Available commands",
|
|
42
42
|
"cmd.helpDetail": "Detailed help: /help <command>",
|
|
43
|
-
"cmd.settingsLoadFail": "
|
|
43
|
+
"cmd.settingsLoadFail": "Failed to load settings.",
|
|
44
44
|
"cmd.model.current": "Current model ({cli}): {model}",
|
|
45
|
-
"cmd.model.invalid": "
|
|
46
|
-
"cmd.model.changed": "
|
|
45
|
+
"cmd.model.invalid": "Invalid model name.",
|
|
46
|
+
"cmd.model.changed": "Model changed: {model}\nApplied from next message.",
|
|
47
47
|
"cmd.cli.current": "Current CLI: {cli}\nAvailable: {available}",
|
|
48
|
-
"cmd.cli.unknown": "
|
|
48
|
+
"cmd.cli.unknown": "Unknown CLI: {cli}\nAvailable: {available}",
|
|
49
49
|
"cmd.cli.already": "{cli} is already active.",
|
|
50
|
-
"cmd.cli.changed": "
|
|
51
|
-
"cmd.skill.loadFail": "
|
|
52
|
-
"cmd.skill.resetUnavailable": "
|
|
53
|
-
"cmd.skill.resetDone": "
|
|
54
|
-
"cmd.employee.resetUnavailable": "
|
|
55
|
-
"cmd.employee.resetDone": "
|
|
56
|
-
"cmd.clear.telegram": "
|
|
57
|
-
"cmd.clear.discord": "
|
|
58
|
-
"cmd.clear.done": "
|
|
59
|
-
"cmd.reset.confirm": "
|
|
60
|
-
"cmd.reset.unavailable": "
|
|
61
|
-
"cmd.reset.done": "
|
|
50
|
+
"cmd.cli.changed": "CLI changed: {from} → {to}",
|
|
51
|
+
"cmd.skill.loadFail": "Failed to load skill info.",
|
|
52
|
+
"cmd.skill.resetUnavailable": "/skill reset is not available in this environment.",
|
|
53
|
+
"cmd.skill.resetDone": "Skill reset completed.",
|
|
54
|
+
"cmd.employee.resetUnavailable": "/employee reset is not available in this environment.",
|
|
55
|
+
"cmd.employee.resetDone": "Employees reset to defaults ({count} agents)",
|
|
56
|
+
"cmd.clear.telegram": "/clear only shows a notice on Telegram (no screen clearing).",
|
|
57
|
+
"cmd.clear.discord": "/clear only shows a notice on Discord (no screen clearing).",
|
|
58
|
+
"cmd.clear.done": "Screen cleared. (Chat history preserved)",
|
|
59
|
+
"cmd.reset.confirm": "Full reset: MCP, skills, employees, and session will be reset to defaults.\nType /reset confirm to proceed.",
|
|
60
|
+
"cmd.reset.unavailable": "Reset is not supported in this environment.",
|
|
61
|
+
"cmd.reset.done": "Reset complete: {items}",
|
|
62
62
|
"cmd.reset.skills": "Skills",
|
|
63
63
|
"cmd.reset.employees": "Employees",
|
|
64
64
|
"cmd.reset.sessions": "Session",
|
|
65
|
-
"cmd.mcp.syncDone": "
|
|
66
|
-
"cmd.mcp.installDone": "
|
|
67
|
-
"cmd.memory.empty": "
|
|
68
|
-
"cmd.browser.noTabs": "
|
|
69
|
-
"cmd.fallback.inactive": "
|
|
70
|
-
"cmd.fallback.off": "
|
|
71
|
-
"cmd.fallback.invalidCli": "
|
|
72
|
-
"cmd.fallback.set": "
|
|
65
|
+
"cmd.mcp.syncDone": "MCP sync complete ({count} targets)",
|
|
66
|
+
"cmd.mcp.installDone": "MCP install complete ({count} servers)",
|
|
67
|
+
"cmd.memory.empty": "No memory files.",
|
|
68
|
+
"cmd.browser.noTabs": "No open tabs.",
|
|
69
|
+
"cmd.fallback.inactive": "Fallback: disabled\nAvailable: {available}",
|
|
70
|
+
"cmd.fallback.off": "Fallback disabled",
|
|
71
|
+
"cmd.fallback.invalidCli": "No valid CLI specified\nAvailable: {available}",
|
|
72
|
+
"cmd.fallback.set": "Fallback set: {order}",
|
|
73
73
|
"cmd.arg.skillList": "Skill list",
|
|
74
74
|
"cmd.arg.skillReset": "Reset skills",
|
|
75
75
|
"cmd.arg.employeeReset": "Reset to 4 defaults",
|
|
@@ -77,93 +77,93 @@
|
|
|
77
77
|
"cmd.arg.browserTabs": "Open tabs",
|
|
78
78
|
"cmd.arg.fallbackOff": "Disable",
|
|
79
79
|
"cmd.arg.flushOff": "Disable (use active CLI)",
|
|
80
|
-
"cmd.flush.current": "
|
|
81
|
-
"cmd.flush.changed": "
|
|
82
|
-
"cmd.flush.reset": "
|
|
83
|
-
"cmd.flush.cliUnavailable": "
|
|
80
|
+
"cmd.flush.current": "Flush model ({cli}): {model}",
|
|
81
|
+
"cmd.flush.changed": "Flush model changed: {cli} / {model}",
|
|
82
|
+
"cmd.flush.reset": "Flush model reset (using active CLI/model)",
|
|
83
|
+
"cmd.flush.cliUnavailable": "{cli} CLI not found (model: {model}). Please install and retry.",
|
|
84
84
|
"cmd.arg.argSelect": "Select argument",
|
|
85
85
|
"api.notCommand": "Not a slash command.",
|
|
86
86
|
"api.serverError": "Server error: {msg}",
|
|
87
|
-
"ws.agentBusy": "
|
|
88
|
-
"ws.roundStart": "
|
|
89
|
-
"ws.roundDone": "
|
|
90
|
-
"ws.roundNext": "
|
|
91
|
-
"ws.roundRetry": "
|
|
92
|
-
"ws.fallback": "
|
|
93
|
-
"ws.retry": "
|
|
94
|
-
"tg.settingsUnsupported": "
|
|
95
|
-
"dc.settingsUnsupported": "
|
|
87
|
+
"ws.agentBusy": "Agent is currently running. Please try again after it completes.",
|
|
88
|
+
"ws.roundStart": "Round {round} — {count} tasks [{names}]",
|
|
89
|
+
"ws.roundDone": "Round {round} complete",
|
|
90
|
+
"ws.roundNext": "Round {round} → next round",
|
|
91
|
+
"ws.roundRetry": "Round {round} → retry",
|
|
92
|
+
"ws.fallback": "{from} failed → retrying with {to}",
|
|
93
|
+
"ws.retry": "{cli} 429 → retrying in {delay}s",
|
|
94
|
+
"tg.settingsUnsupported": "Settings changes are not supported on Telegram.",
|
|
95
|
+
"dc.settingsUnsupported": "Settings changes are not supported on Discord.",
|
|
96
96
|
"tg.promptUnsupported": "(Not supported on Telegram)",
|
|
97
|
-
"tg.queued": "
|
|
97
|
+
"tg.queued": "Added to queue (#{count})",
|
|
98
98
|
"tg.imageCaption": "[📷 Image] {caption}",
|
|
99
|
-
"tg.imageFail": "
|
|
100
|
-
"tg.fileFail": "
|
|
101
|
-
"tg.voiceFail": "
|
|
102
|
-
"tg.voiceEmpty": "
|
|
99
|
+
"tg.imageFail": "Image processing failed: {msg}",
|
|
100
|
+
"tg.fileFail": "File processing failed: {msg}",
|
|
101
|
+
"tg.voiceFail": "Voice transcription failed: {msg}",
|
|
102
|
+
"tg.voiceEmpty": "Couldn't understand the voice message. Please try again.",
|
|
103
103
|
"voice.start": "Record voice",
|
|
104
104
|
"voice.stop": "Stop recording",
|
|
105
|
-
"voice.micDenied": "
|
|
106
|
-
"voice.micNotFound": "
|
|
107
|
-
"voice.micBusy": "
|
|
108
|
-
"voice.httpsRequired": "
|
|
109
|
-
"voice.unsupported": "
|
|
110
|
-
"voice.interrupted": "
|
|
111
|
-
"voice.tooLarge": "
|
|
112
|
-
"voice.tooShort": "
|
|
113
|
-
"voice.sttFail": "
|
|
114
|
-
"copilot.keychain": "
|
|
105
|
+
"voice.micDenied": "Microphone access denied. Please allow microphone in browser settings.",
|
|
106
|
+
"voice.micNotFound": "No microphone found. Please connect a microphone.",
|
|
107
|
+
"voice.micBusy": "Microphone is in use by another app.",
|
|
108
|
+
"voice.httpsRequired": "Voice recording requires HTTPS or localhost.",
|
|
109
|
+
"voice.unsupported": "Voice recording is not supported in this browser.",
|
|
110
|
+
"voice.interrupted": "Recording was interrupted.",
|
|
111
|
+
"voice.tooLarge": "Recording too large (max 20MB).",
|
|
112
|
+
"voice.tooShort": "Recording too short.",
|
|
113
|
+
"voice.sttFail": "Voice recognition failed: {msg}",
|
|
114
|
+
"copilot.keychain": "Keychain",
|
|
115
115
|
"copilot.keychainHint": "Re-read Copilot token from macOS Keychain",
|
|
116
|
-
"stt.title": "
|
|
116
|
+
"stt.title": "Voice Recognition (STT)",
|
|
117
117
|
"stt.engine": "Engine",
|
|
118
118
|
"stt.geminiKey": "Gemini API Key",
|
|
119
119
|
"stt.geminiKeyHint": "Used for cloud STT via Gemini",
|
|
120
120
|
"stt.geminiModel": "Gemini Model",
|
|
121
121
|
"stt.whisperModel": "Whisper Model",
|
|
122
|
-
"stt.save": "
|
|
123
|
-
"stt.saved": "
|
|
124
|
-
"stt.shortcutHint": "
|
|
122
|
+
"stt.save": "Save STT Settings",
|
|
123
|
+
"stt.saved": "Saved",
|
|
124
|
+
"stt.shortcutHint": "Ctrl+Shift+Space (⌘+Shift+Space on Mac)",
|
|
125
125
|
"stt.openaiBaseUrl": "Base URL",
|
|
126
126
|
"stt.openaiKey": "API Key",
|
|
127
127
|
"stt.openaiModel": "Model",
|
|
128
128
|
"stt.vertexConfig": "Vertex AI Config (JSON)",
|
|
129
|
-
"tg.timeout": "
|
|
129
|
+
"tg.timeout": "Timeout (20 min no response)",
|
|
130
130
|
"tg.noResponse": "No response",
|
|
131
|
-
"tg.connected": "
|
|
132
|
-
"tg.resetDone": "
|
|
131
|
+
"tg.connected": "Jaw Agent connected! Send a message and the AI agent will respond.",
|
|
132
|
+
"tg.resetDone": "Reset complete.",
|
|
133
133
|
"cli.fileNotFound": "File not found: {path}",
|
|
134
134
|
"cli.fileSentPrompt": "[User sent a file: {path}]\nPlease read and analyze this file.",
|
|
135
135
|
"cli.fileSentWithMsg": "\n\nUser message: {text}",
|
|
136
136
|
"cli.fallbackRetry": "{from} failed → retrying with {to}",
|
|
137
137
|
"cli.noReadyCli": "No authenticated CLI available — install and authenticate at least one CLI above to get started.",
|
|
138
|
-
"chat.cmd.fail": "
|
|
138
|
+
"chat.cmd.fail": "Command execution failed: {msg}",
|
|
139
139
|
"chat.file.sent": "[User sent a file: {path}]\nPlease read and analyze this file.",
|
|
140
140
|
"chat.file.sentWithMsg": "\n\nUser message: {text}",
|
|
141
|
-
"chat.file.uploadFail": "
|
|
141
|
+
"chat.file.uploadFail": "File upload failed: {msg}",
|
|
142
142
|
"chat.requestFail": "Request failed ({status})",
|
|
143
|
-
"chat.continue": "
|
|
143
|
+
"chat.continue": "Continuing from previous worklog.",
|
|
144
144
|
"skill.loadFail": "Failed to load skills",
|
|
145
145
|
"skill.count": "{active} active / {total} total",
|
|
146
146
|
"skill.filter.all": "All",
|
|
147
|
-
"skill.filter.installed": "
|
|
148
|
-
"skill.filter.productivity": "
|
|
149
|
-
"skill.filter.communication": "
|
|
150
|
-
"skill.filter.devtools": "
|
|
151
|
-
"skill.filter.utility": "
|
|
152
|
-
"skill.filter.smarthome": "
|
|
153
|
-
"skill.filter.other": "
|
|
154
|
-
"skill.filter.ai": "
|
|
147
|
+
"skill.filter.installed": "Installed",
|
|
148
|
+
"skill.filter.productivity": "Productivity",
|
|
149
|
+
"skill.filter.communication": "Comms",
|
|
150
|
+
"skill.filter.devtools": "Dev",
|
|
151
|
+
"skill.filter.utility": "Utility",
|
|
152
|
+
"skill.filter.smarthome": "Home",
|
|
153
|
+
"skill.filter.other": "Other",
|
|
154
|
+
"skill.filter.ai": "AI",
|
|
155
155
|
"lang.ko": "한국어",
|
|
156
156
|
"lang.en": "English",
|
|
157
157
|
"emp.addPrompt": "Add an agent",
|
|
158
158
|
"emp.delete": "Delete",
|
|
159
159
|
"emp.customRole": "Custom role...",
|
|
160
|
-
"emp.customModel": "
|
|
161
|
-
"role.label.frontend": "
|
|
162
|
-
"role.label.backend": "
|
|
163
|
-
"role.label.research": "
|
|
164
|
-
"role.label.data": "
|
|
165
|
-
"role.label.docs": "
|
|
166
|
-
"role.label.custom": "
|
|
160
|
+
"emp.customModel": "Enter manually...",
|
|
161
|
+
"role.label.frontend": "Frontend",
|
|
162
|
+
"role.label.backend": "Backend",
|
|
163
|
+
"role.label.research": "Research",
|
|
164
|
+
"role.label.data": "Data",
|
|
165
|
+
"role.label.docs": "Docs",
|
|
166
|
+
"role.label.custom": "Custom...",
|
|
167
167
|
"hb.empty": "No heartbeats",
|
|
168
168
|
"hb.name": "Name",
|
|
169
169
|
"hb.prompt": "Prompt...",
|
|
@@ -184,15 +184,15 @@
|
|
|
184
184
|
"mem.noFiles": "No memory files yet",
|
|
185
185
|
"mem.empty": "No memory yet",
|
|
186
186
|
"model.promptInput": "Enter model ID:",
|
|
187
|
-
"model.customOption": "
|
|
187
|
+
"model.customOption": "Enter manually...",
|
|
188
188
|
"model.placeholder": "Enter model ID",
|
|
189
189
|
"mcp.syncing": "Syncing...",
|
|
190
|
-
"mcp.installing": "
|
|
190
|
+
"mcp.installing": "Installing via npm... (up to 2 min)",
|
|
191
191
|
"settings.none": "(none)",
|
|
192
192
|
"cli.gemini.auth": "Browser auth on first run",
|
|
193
|
-
"cli.authRequired": "
|
|
194
|
-
"cli.notAuthenticated": "
|
|
195
|
-
"drag.drop": "
|
|
193
|
+
"cli.authRequired": "Install / auth required",
|
|
194
|
+
"cli.notAuthenticated": "Auth required — run command below",
|
|
195
|
+
"drag.drop": "Drop files here",
|
|
196
196
|
"status.responding": "Responding",
|
|
197
197
|
"aria.cmdList": "Command list",
|
|
198
198
|
"btn.attach": "Attach file",
|
|
@@ -244,8 +244,8 @@
|
|
|
244
244
|
"label.flushEvery": "Flush Every",
|
|
245
245
|
"emp.empty": "No employees yet",
|
|
246
246
|
"modal.promptTitle": "System Prompt (A-2)",
|
|
247
|
-
"modal.heartbeatTitle": "
|
|
248
|
-
"modal.memoryTitle": "
|
|
247
|
+
"modal.heartbeatTitle": "Heartbeat Jobs",
|
|
248
|
+
"modal.memoryTitle": "Memory",
|
|
249
249
|
"code.copy": "Copy",
|
|
250
250
|
"code.copied": "Copied ✓",
|
|
251
251
|
"mcp.noServers": "(no servers configured)",
|
|
@@ -254,5 +254,6 @@
|
|
|
254
254
|
"cmd.ide.desc": "IDE diff view",
|
|
255
255
|
"cmd.ide.toggled": "IDE diff mode toggled",
|
|
256
256
|
"cmd.ide.popToggled": "IDE popup toggled",
|
|
257
|
-
"cmd.ide.usage": "Usage: /ide [pop|on|off]"
|
|
257
|
+
"cmd.ide.usage": "Usage: /ide [pop|on|off]",
|
|
258
|
+
"label.mentionOnly": "Mention Only"
|
|
258
259
|
}
|