codexmate 0.0.44 → 0.0.47

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.
Files changed (41) hide show
  1. package/README.md +20 -7
  2. package/README.zh.md +20 -7
  3. package/cli.js +473 -3
  4. package/package.json +2 -1
  5. package/web-ui/app.js +42 -5
  6. package/web-ui/index.html +2 -0
  7. package/web-ui/modules/app.computed.index.mjs +3 -1
  8. package/web-ui/modules/app.computed.main-tabs.mjs +3 -0
  9. package/web-ui/modules/app.computed.prompts.mjs +28 -0
  10. package/web-ui/modules/app.computed.session.mjs +23 -1
  11. package/web-ui/modules/app.constants.mjs +13 -0
  12. package/web-ui/modules/app.methods.agents.mjs +50 -4
  13. package/web-ui/modules/app.methods.index.mjs +6 -0
  14. package/web-ui/modules/app.methods.navigation.mjs +2 -1
  15. package/web-ui/modules/app.methods.opencode-config.mjs +228 -0
  16. package/web-ui/modules/app.methods.session-actions.mjs +10 -0
  17. package/web-ui/modules/app.methods.startup-claude.mjs +3 -1
  18. package/web-ui/modules/app.methods.tool-config-permissions.mjs +3 -2
  19. package/web-ui/modules/config-mode.computed.mjs +17 -1
  20. package/web-ui/modules/i18n/locales/en.mjs +66 -5
  21. package/web-ui/modules/i18n/locales/ja.mjs +66 -5
  22. package/web-ui/modules/i18n/locales/vi.mjs +74 -0
  23. package/web-ui/modules/i18n/locales/zh-tw.mjs +1269 -0
  24. package/web-ui/modules/i18n/locales/zh.mjs +66 -5
  25. package/web-ui/modules/i18n.dict.mjs +2 -0
  26. package/web-ui/modules/i18n.mjs +3 -2
  27. package/web-ui/partials/index/layout-footer.html +1 -1
  28. package/web-ui/partials/index/layout-header.html +70 -2
  29. package/web-ui/partials/index/modal-config-template-agents.html +12 -13
  30. package/web-ui/partials/index/panel-config-claude.html +6 -12
  31. package/web-ui/partials/index/panel-config-codex.html +6 -11
  32. package/web-ui/partials/index/panel-config-opencode.html +166 -0
  33. package/web-ui/partials/index/panel-prompts.html +100 -0
  34. package/web-ui/partials/index/panel-sessions.html +30 -10
  35. package/web-ui/partials/index/panel-usage.html +34 -18
  36. package/web-ui/res/web-ui-render.precompiled.js +932 -183
  37. package/web-ui/styles/controls-forms.css +62 -4
  38. package/web-ui/styles/modals-core.css +162 -0
  39. package/web-ui/styles/responsive.css +65 -5
  40. package/web-ui/styles/sessions-toolbar-trash.css +45 -10
  41. package/web-ui/styles/sessions-usage.css +31 -2
@@ -1,5 +1,5 @@
1
1
  window.__CODEXMATE_WEB_UI_RENDER__ = (() => {
2
- const { toDisplayString: _toDisplayString, openBlock: _openBlock, createElementBlock: _createElementBlock, createCommentVNode: _createCommentVNode, createTextVNode: _createTextVNode, createElementVNode: _createElementVNode, normalizeClass: _normalizeClass, Fragment: _Fragment, renderList: _renderList, vShow: _vShow, withDirectives: _withDirectives, vModelSelect: _vModelSelect, vModelText: _vModelText, withKeys: _withKeys, withModifiers: _withModifiers, isMemoSame: _isMemoSame, withMemo: _withMemo, normalizeStyle: _normalizeStyle, vModelDynamic: _vModelDynamic, vModelCheckbox: _vModelCheckbox } = Vue
2
+ const { toDisplayString: _toDisplayString, openBlock: _openBlock, createElementBlock: _createElementBlock, createCommentVNode: _createCommentVNode, createTextVNode: _createTextVNode, createElementVNode: _createElementVNode, normalizeClass: _normalizeClass, Fragment: _Fragment, renderList: _renderList, vShow: _vShow, withDirectives: _withDirectives, vModelSelect: _vModelSelect, vModelText: _vModelText, withKeys: _withKeys, withModifiers: _withModifiers, vModelDynamic: _vModelDynamic, vModelCheckbox: _vModelCheckbox, isMemoSame: _isMemoSame, withMemo: _withMemo, normalizeStyle: _normalizeStyle } = Vue
3
3
 
4
4
  return function render(_ctx, _cache) {
5
5
  return (_openBlock(), _createElementBlock(_Fragment, null, [
@@ -71,7 +71,7 @@ return function render(_ctx, _cache) {
71
71
  "data-config-mode": _ctx.configMode,
72
72
  tabindex: _ctx.mainTab === 'config' ? 0 : -1,
73
73
  "aria-selected": _ctx.mainTab === 'config',
74
- "aria-controls": _ctx.configMode === 'claude' ? 'panel-config-claude' : (_ctx.configMode === 'openclaw' ? 'panel-config-openclaw' : 'panel-config-provider'),
74
+ "aria-controls": _ctx.configMode === 'claude' ? 'panel-config-claude' : (_ctx.configMode === 'openclaw' ? 'panel-config-openclaw' : (_ctx.configMode === 'opencode' ? 'panel-config-opencode' : 'panel-config-provider')),
75
75
  onPointerdown: $event => (_ctx.onMainTabPointerDown('config', $event)),
76
76
  onClick: $event => (_ctx.onMainTabClick('config', $event))
77
77
  }, _toDisplayString(_ctx.t('tab.config')), 43 /* TEXT, CLASS, PROPS, NEED_HYDRATION */, ["data-config-mode", "tabindex", "aria-selected", "aria-controls", "onPointerdown", "onClick"]),
@@ -138,6 +138,18 @@ return function render(_ctx, _cache) {
138
138
  onPointerdown: $event => (_ctx.onMainTabPointerDown('plugins', $event)),
139
139
  onClick: $event => (_ctx.onMainTabClick('plugins', $event))
140
140
  }, _toDisplayString(_ctx.t('tab.plugins')), 43 /* TEXT, CLASS, PROPS, NEED_HYDRATION */, ["tabindex", "aria-selected", "onPointerdown", "onClick"]),
141
+ _createElementVNode("button", {
142
+ type: "button",
143
+ class: _normalizeClass(["top-tab", { active: _ctx.isMainTabNavActive('prompts') }]),
144
+ id: "tab-prompts",
145
+ role: "tab",
146
+ "data-main-tab": "prompts",
147
+ tabindex: _ctx.mainTab === 'prompts' ? 0 : -1,
148
+ "aria-selected": _ctx.mainTab === 'prompts',
149
+ "aria-controls": "panel-prompts",
150
+ onPointerdown: $event => (_ctx.onMainTabPointerDown('prompts', $event)),
151
+ onClick: $event => (_ctx.onMainTabClick('prompts', $event))
152
+ }, _toDisplayString(_ctx.t('tab.prompts')), 43 /* TEXT, CLASS, PROPS, NEED_HYDRATION */, ["tabindex", "aria-selected", "onPointerdown", "onClick"]),
141
153
  _createElementVNode("button", {
142
154
  type: "button",
143
155
  class: _normalizeClass(["top-tab", { active: _ctx.isMainTabNavActive('settings') }]),
@@ -181,15 +193,7 @@ return function render(_ctx, _cache) {
181
193
  alt: "Codex Mate logo"
182
194
  }),
183
195
  _createElementVNode("div", { class: "brand-copy" }, [
184
- _createElementVNode("div", { class: "brand-kicker" }, [
185
- _createTextVNode("Codex Mate"),
186
- (_ctx.appVersion)
187
- ? (_openBlock(), _createElementBlock("span", {
188
- key: 0,
189
- class: "brand-version"
190
- }, " v" + _toDisplayString(_ctx.appVersion), 1 /* TEXT */))
191
- : _createCommentVNode("v-if", true)
192
- ])
196
+ _createElementVNode("div", { class: "brand-kicker" }, "Codex Mate")
193
197
  ])
194
198
  ]),
195
199
  (_ctx.isAppVersionStatusVisible())
@@ -307,6 +311,58 @@ return function render(_ctx, _cache) {
307
311
  ? (_openBlock(), _createElementBlock("span", { key: 0 }, _toDisplayString(_ctx.t('common.current', { value: _ctx.currentOpenclawConfig })), 1 /* TEXT */))
308
312
  : _createCommentVNode("v-if", true)
309
313
  ])
314
+ ], 42 /* CLASS, PROPS, NEED_HYDRATION */, ["aria-current", "onPointerdown", "onClick"]),
315
+ _createElementVNode("button", {
316
+ id: "side-tab-config-opencode",
317
+ "data-main-tab": "config",
318
+ "data-config-mode": "opencode",
319
+ "aria-current": _ctx.mainTab === 'config' && _ctx.configMode === 'opencode' ? 'page' : null,
320
+ class: _normalizeClass(['side-item', { active: _ctx.isConfigModeNavActive('opencode') }]),
321
+ onPointerdown: $event => (_ctx.onConfigTabPointerDown('opencode', $event)),
322
+ onClick: $event => (_ctx.onConfigTabClick('opencode', $event))
323
+ }, [
324
+ _createElementVNode("div", { class: "side-item-title" }, _toDisplayString(_ctx.t('side.config.opencode')), 1 /* TEXT */),
325
+ _createElementVNode("div", { class: "side-item-meta" }, [
326
+ _createElementVNode("span", null, _toDisplayString(_ctx.t('side.config.opencode.meta')), 1 /* TEXT */),
327
+ (_ctx.opencodeModel)
328
+ ? (_openBlock(), _createElementBlock("span", { key: 0 }, _toDisplayString(_ctx.t('common.current', { value: _ctx.opencodeModel })), 1 /* TEXT */))
329
+ : _createCommentVNode("v-if", true)
330
+ ])
331
+ ], 42 /* CLASS, PROPS, NEED_HYDRATION */, ["aria-current", "onPointerdown", "onClick"])
332
+ ], 8 /* PROPS */, ["aria-label"]),
333
+ _createElementVNode("div", {
334
+ class: "side-section",
335
+ role: "navigation",
336
+ "aria-label": _ctx.t('side.prompts')
337
+ }, [
338
+ _createElementVNode("div", { class: "side-section-title" }, _toDisplayString(_ctx.t('side.prompts')), 1 /* TEXT */),
339
+ _createElementVNode("button", {
340
+ id: "side-tab-prompts-agents",
341
+ "data-main-tab": "prompts",
342
+ "data-prompts-sub-tab": "codex",
343
+ "aria-current": _ctx.mainTab === 'prompts' && _ctx.promptsSubTab === 'codex' ? 'page' : null,
344
+ class: _normalizeClass(['side-item', { active: _ctx.isMainTabNavActive('prompts') && _ctx.promptsSubTab === 'codex' }]),
345
+ onPointerdown: $event => (_ctx.onMainTabPointerDown('prompts', $event)),
346
+ onClick: $event => {_ctx.switchPromptsSubTab('codex'); _ctx.onMainTabClick('prompts')}
347
+ }, [
348
+ _createElementVNode("div", { class: "side-item-title" }, _toDisplayString(_ctx.t('side.prompts.agents')), 1 /* TEXT */),
349
+ _createElementVNode("div", { class: "side-item-meta" }, [
350
+ _createElementVNode("span", null, _toDisplayString(_ctx.t('side.prompts.agents.meta')), 1 /* TEXT */)
351
+ ])
352
+ ], 42 /* CLASS, PROPS, NEED_HYDRATION */, ["aria-current", "onPointerdown", "onClick"]),
353
+ _createElementVNode("button", {
354
+ id: "side-tab-prompts-claude",
355
+ "data-main-tab": "prompts",
356
+ "data-prompts-sub-tab": "claude-md",
357
+ "aria-current": _ctx.mainTab === 'prompts' && _ctx.promptsSubTab === 'claude-md' ? 'page' : null,
358
+ class: _normalizeClass(['side-item', { active: _ctx.isMainTabNavActive('prompts') && _ctx.promptsSubTab === 'claude-md' }]),
359
+ onPointerdown: $event => (_ctx.onMainTabPointerDown('prompts', $event)),
360
+ onClick: $event => {_ctx.switchPromptsSubTab('claude-md'); _ctx.onMainTabClick('prompts')}
361
+ }, [
362
+ _createElementVNode("div", { class: "side-item-title" }, _toDisplayString(_ctx.t('side.prompts.claude')), 1 /* TEXT */),
363
+ _createElementVNode("div", { class: "side-item-meta" }, [
364
+ _createElementVNode("span", null, _toDisplayString(_ctx.t('side.prompts.claude.meta')), 1 /* TEXT */)
365
+ ])
310
366
  ], 42 /* CLASS, PROPS, NEED_HYDRATION */, ["aria-current", "onPointerdown", "onClick"])
311
367
  ], 8 /* PROPS */, ["aria-label"]),
312
368
  _createElementVNode("div", {
@@ -523,13 +579,28 @@ return function render(_ctx, _cache) {
523
579
  _createElementVNode("span", { class: "value" }, _toDisplayString(_ctx.openclawWorkspaceFileName || _ctx.t('common.notSelected')), 1 /* TEXT */)
524
580
  ])
525
581
  ], 64 /* STABLE_FRAGMENT */))
526
- : (_openBlock(), _createElementBlock("div", {
527
- key: 3,
528
- class: "status-chip"
529
- }, [
530
- _createElementVNode("span", { class: "label" }, _toDisplayString(_ctx.t('status.configMode')), 1 /* TEXT */),
531
- _createElementVNode("span", { class: "value" }, _toDisplayString(_ctx.t('common.notSelected')), 1 /* TEXT */)
532
- ]))
582
+ : (_ctx.configMode === 'opencode')
583
+ ? (_openBlock(), _createElementBlock(_Fragment, { key: 3 }, [
584
+ _createElementVNode("div", { class: "status-chip" }, [
585
+ _createElementVNode("span", { class: "label" }, _toDisplayString(_ctx.t('status.opencodeProvider')), 1 /* TEXT */),
586
+ _createElementVNode("span", { class: "value" }, _toDisplayString(_ctx.opencodeProvider || _ctx.t('common.notSelected')), 1 /* TEXT */)
587
+ ]),
588
+ _createElementVNode("div", { class: "status-chip" }, [
589
+ _createElementVNode("span", { class: "label" }, _toDisplayString(_ctx.t('status.opencodeModel')), 1 /* TEXT */),
590
+ _createElementVNode("span", { class: "value" }, _toDisplayString(_ctx.opencodeModel || _ctx.t('common.notSelected')), 1 /* TEXT */)
591
+ ]),
592
+ _createElementVNode("div", { class: "status-chip" }, [
593
+ _createElementVNode("span", { class: "label" }, _toDisplayString(_ctx.t('status.opencodeConfig')), 1 /* TEXT */),
594
+ _createElementVNode("span", { class: "value" }, _toDisplayString(_ctx.opencodeConfigPath || _ctx.t('common.notSelected')), 1 /* TEXT */)
595
+ ])
596
+ ], 64 /* STABLE_FRAGMENT */))
597
+ : (_openBlock(), _createElementBlock("div", {
598
+ key: 4,
599
+ class: "status-chip"
600
+ }, [
601
+ _createElementVNode("span", { class: "label" }, _toDisplayString(_ctx.t('status.configMode')), 1 /* TEXT */),
602
+ _createElementVNode("span", { class: "value" }, _toDisplayString(_ctx.t('common.notSelected')), 1 /* TEXT */)
603
+ ]))
533
604
  ]))
534
605
  : (!_ctx.sessionStandalone && _ctx.mainTab === 'sessions')
535
606
  ? (_openBlock(), _createElementBlock("div", {
@@ -1058,16 +1129,6 @@ return function render(_ctx, _cache) {
1058
1129
  ])
1059
1130
  ]))
1060
1131
  : _createCommentVNode("v-if", true),
1061
- _createElementVNode("div", { class: "selector-section" }, [
1062
- _createElementVNode("div", { class: "selector-header" }, [
1063
- _createElementVNode("span", { class: "selector-title" }, "AGENTS.md")
1064
- ]),
1065
- _createElementVNode("button", {
1066
- class: "btn-tool",
1067
- onClick: _ctx.openAgentsEditor,
1068
- disabled: _ctx.loading || !!_ctx.initError || _ctx.agentsLoading
1069
- }, _toDisplayString(_ctx.agentsLoading ? _ctx.t('config.modelLoading') : _ctx.t('config.agents.open')), 9 /* TEXT, PROPS */, ["onClick", "disabled"])
1070
- ]),
1071
1132
  _createElementVNode("div", { class: "selector-section" }, [
1072
1133
  _createElementVNode("div", { class: "selector-header" }, [
1073
1134
  _createElementVNode("span", { class: "selector-title" }, _toDisplayString(_ctx.t('config.models')), 1 /* TEXT */),
@@ -1532,25 +1593,25 @@ return function render(_ctx, _cache) {
1532
1593
  ], 42 /* CLASS, PROPS, NEED_HYDRATION */, ["onClick", "onKeydown", "tabindex", "aria-current"]))
1533
1594
  }), 128 /* KEYED_FRAGMENT */))
1534
1595
  ]))
1596
+ : _createCommentVNode("v-if", true),
1597
+ (!_ctx.isToolConfigWriteAllowed('codex'))
1598
+ ? (_openBlock(), _createElementBlock("div", {
1599
+ key: 4,
1600
+ class: "tool-config-write-overlay"
1601
+ }, [
1602
+ _createElementVNode("div", { class: "tool-config-write-overlay-card" }, [
1603
+ _createElementVNode("div", { class: "tool-config-write-overlay-title" }, _toDisplayString(_ctx.t('toolConfig.codex.lockedTitle')), 1 /* TEXT */),
1604
+ _createElementVNode("p", null, _toDisplayString(_ctx.t('toolConfig.codex.lockedDesc')), 1 /* TEXT */),
1605
+ _createElementVNode("button", {
1606
+ type: "button",
1607
+ class: "btn-tool",
1608
+ onClick: $event => (_ctx.setToolConfigPermission('codex', true)),
1609
+ disabled: _ctx.toolConfigPermissionSaving.codex
1610
+ }, _toDisplayString(_ctx.t('toolConfig.enableWrite')), 9 /* TEXT, PROPS */, ["onClick", "disabled"])
1611
+ ])
1612
+ ]))
1535
1613
  : _createCommentVNode("v-if", true)
1536
- ]),
1537
- (!_ctx.isToolConfigWriteAllowed('codex'))
1538
- ? (_openBlock(), _createElementBlock("div", {
1539
- key: 0,
1540
- class: "tool-config-write-overlay"
1541
- }, [
1542
- _createElementVNode("div", { class: "tool-config-write-overlay-card" }, [
1543
- _createElementVNode("div", { class: "tool-config-write-overlay-title" }, _toDisplayString(_ctx.t('toolConfig.codex.lockedTitle')), 1 /* TEXT */),
1544
- _createElementVNode("p", null, _toDisplayString(_ctx.t('toolConfig.codex.lockedDesc')), 1 /* TEXT */),
1545
- _createElementVNode("button", {
1546
- type: "button",
1547
- class: "btn-tool",
1548
- onClick: $event => (_ctx.setToolConfigPermission('codex', true)),
1549
- disabled: _ctx.toolConfigPermissionSaving.codex
1550
- }, _toDisplayString(_ctx.t('toolConfig.enableWrite')), 9 /* TEXT, PROPS */, ["onClick", "disabled"])
1551
- ])
1552
- ]))
1553
- : _createCommentVNode("v-if", true)
1614
+ ])
1554
1615
  ], 2 /* CLASS */)
1555
1616
  ], 64 /* STABLE_FRAGMENT */))
1556
1617
  ], 8 /* PROPS */, ["aria-labelledby"]), [
@@ -1821,17 +1882,6 @@ return function render(_ctx, _cache) {
1821
1882
  disabled: _ctx.loading || !!_ctx.initError
1822
1883
  }, _toDisplayString(_ctx.t('config.template.openEditor')), 9 /* TEXT, PROPS */, ["onClick", "disabled"])
1823
1884
  ]),
1824
- _createElementVNode("div", { class: "selector-section" }, [
1825
- _createElementVNode("div", { class: "selector-header" }, [
1826
- _createElementVNode("span", { class: "selector-title" }, "CLAUDE.md")
1827
- ]),
1828
- _createElementVNode("button", {
1829
- class: "btn-tool",
1830
- onClick: _ctx.openClaudeMdEditor,
1831
- disabled: _ctx.loading || !!_ctx.initError || _ctx.agentsLoading
1832
- }, _toDisplayString(_ctx.agentsLoading ? _ctx.t('config.modelLoading') : _ctx.t('claude.md.open')), 9 /* TEXT, PROPS */, ["onClick", "disabled"]),
1833
- _createElementVNode("div", { class: "config-template-hint" }, _toDisplayString(_ctx.t('claude.md.hint')), 1 /* TEXT */)
1834
- ]),
1835
1885
  _createElementVNode("div", { class: "selector-section" }, [
1836
1886
  _createElementVNode("div", { class: "selector-header" }, [
1837
1887
  _createElementVNode("span", { class: "selector-title" }, _toDisplayString(_ctx.t('config.health.title')), 1 /* TEXT */)
@@ -2071,25 +2121,25 @@ return function render(_ctx, _cache) {
2071
2121
  ])
2072
2122
  ], 42 /* CLASS, PROPS, NEED_HYDRATION */, ["onClick", "onKeydown", "aria-current"]))
2073
2123
  }), 128 /* KEYED_FRAGMENT */))
2074
- ])
2075
- ]),
2076
- (!_ctx.isToolConfigWriteAllowed('claude'))
2077
- ? (_openBlock(), _createElementBlock("div", {
2078
- key: 0,
2079
- class: "tool-config-write-overlay"
2080
- }, [
2081
- _createElementVNode("div", { class: "tool-config-write-overlay-card" }, [
2082
- _createElementVNode("div", { class: "tool-config-write-overlay-title" }, _toDisplayString(_ctx.t('toolConfig.claude.lockedTitle')), 1 /* TEXT */),
2083
- _createElementVNode("p", null, _toDisplayString(_ctx.t('toolConfig.claude.lockedDesc')), 1 /* TEXT */),
2084
- _createElementVNode("button", {
2085
- type: "button",
2086
- class: "btn-tool",
2087
- onClick: $event => (_ctx.setToolConfigPermission('claude', true)),
2088
- disabled: _ctx.toolConfigPermissionSaving.claude
2089
- }, _toDisplayString(_ctx.t('toolConfig.enableWrite')), 9 /* TEXT, PROPS */, ["onClick", "disabled"])
2090
- ])
2091
- ]))
2092
- : _createCommentVNode("v-if", true)
2124
+ ]),
2125
+ (!_ctx.isToolConfigWriteAllowed('claude'))
2126
+ ? (_openBlock(), _createElementBlock("div", {
2127
+ key: 1,
2128
+ class: "tool-config-write-overlay"
2129
+ }, [
2130
+ _createElementVNode("div", { class: "tool-config-write-overlay-card" }, [
2131
+ _createElementVNode("div", { class: "tool-config-write-overlay-title" }, _toDisplayString(_ctx.t('toolConfig.claude.lockedTitle')), 1 /* TEXT */),
2132
+ _createElementVNode("p", null, _toDisplayString(_ctx.t('toolConfig.claude.lockedDesc')), 1 /* TEXT */),
2133
+ _createElementVNode("button", {
2134
+ type: "button",
2135
+ class: "btn-tool",
2136
+ onClick: $event => (_ctx.setToolConfigPermission('claude', true)),
2137
+ disabled: _ctx.toolConfigPermissionSaving.claude
2138
+ }, _toDisplayString(_ctx.t('toolConfig.enableWrite')), 9 /* TEXT, PROPS */, ["onClick", "disabled"])
2139
+ ])
2140
+ ]))
2141
+ : _createCommentVNode("v-if", true)
2142
+ ])
2093
2143
  ], 2 /* CLASS */)
2094
2144
  ], 64 /* STABLE_FRAGMENT */))
2095
2145
  ], 8 /* PROPS */, ["aria-labelledby"]), [
@@ -2254,6 +2304,394 @@ return function render(_ctx, _cache) {
2254
2304
  ], 8 /* PROPS */, ["aria-labelledby"]), [
2255
2305
  [_vShow, _ctx.mainTab === 'config' && _ctx.configMode === 'openclaw']
2256
2306
  ]),
2307
+ _createCommentVNode(" OpenCode 配置 "),
2308
+ _withDirectives(_createElementVNode("div", {
2309
+ class: "mode-content mode-cards",
2310
+ id: "panel-config-opencode",
2311
+ role: "tabpanel",
2312
+ "aria-labelledby": _ctx.forceCompactLayout ? 'tab-config' : 'side-tab-config-opencode'
2313
+ }, [
2314
+ (_ctx.forceCompactLayout && !_ctx.sessionStandalone)
2315
+ ? (_openBlock(), _createElementBlock("div", {
2316
+ key: 0,
2317
+ class: "segmented-control"
2318
+ }, [
2319
+ _createElementVNode("button", {
2320
+ type: "button",
2321
+ class: _normalizeClass(['segment', { active: _ctx.configMode === 'codex' }]),
2322
+ onClick: $event => (_ctx.switchConfigMode('codex'))
2323
+ }, _toDisplayString(_ctx.t('tab.config.codex')), 11 /* TEXT, CLASS, PROPS */, ["onClick"]),
2324
+ _createElementVNode("button", {
2325
+ type: "button",
2326
+ class: _normalizeClass(['segment', { active: _ctx.configMode === 'claude' }]),
2327
+ onClick: $event => (_ctx.switchConfigMode('claude'))
2328
+ }, _toDisplayString(_ctx.t('tab.config.claude')), 11 /* TEXT, CLASS, PROPS */, ["onClick"]),
2329
+ _createElementVNode("button", {
2330
+ type: "button",
2331
+ class: _normalizeClass(['segment', { active: _ctx.configMode === 'openclaw' }]),
2332
+ onClick: $event => (_ctx.switchConfigMode('openclaw'))
2333
+ }, _toDisplayString(_ctx.t('tab.config.openclaw')), 11 /* TEXT, CLASS, PROPS */, ["onClick"]),
2334
+ _createElementVNode("button", {
2335
+ type: "button",
2336
+ class: _normalizeClass(['segment', { active: _ctx.configMode === 'opencode' }]),
2337
+ onClick: $event => (_ctx.switchConfigMode('opencode'))
2338
+ }, _toDisplayString(_ctx.t('tab.config.opencode')), 11 /* TEXT, CLASS, PROPS */, ["onClick"])
2339
+ ]))
2340
+ : _createCommentVNode("v-if", true),
2341
+ _createElementVNode("section", {
2342
+ class: "tool-config-write-card",
2343
+ "aria-label": _ctx.t('opencode.writeAria')
2344
+ }, [
2345
+ _createElementVNode("div", { class: "tool-config-write-copy" }, [
2346
+ _createElementVNode("div", { class: "tool-config-write-title" }, _toDisplayString(_ctx.t('toolConfig.opencode.title')), 1 /* TEXT */),
2347
+ _createElementVNode("p", { class: "tool-config-write-desc" }, _toDisplayString(_ctx.t('toolConfig.opencode.desc')), 1 /* TEXT */)
2348
+ ]),
2349
+ _createElementVNode("label", { class: "settings-toggle-row tool-config-write-toggle" }, [
2350
+ _createElementVNode("input", {
2351
+ type: "checkbox",
2352
+ autocomplete: "off",
2353
+ checked: _ctx.isToolConfigWriteAllowed('opencode'),
2354
+ disabled: _ctx.toolConfigPermissionSaving.opencode,
2355
+ onChange: $event => (_ctx.setToolConfigPermission('opencode', $event.target.checked))
2356
+ }, null, 40 /* PROPS, NEED_HYDRATION */, ["checked", "disabled", "onChange"]),
2357
+ _createElementVNode("span", { class: "toggle-track" }, [
2358
+ _createElementVNode("span", { class: "toggle-thumb" })
2359
+ ]),
2360
+ _createElementVNode("span", null, _toDisplayString(_ctx.toolConfigPermissionStatusLabel('opencode')), 1 /* TEXT */)
2361
+ ])
2362
+ ], 8 /* PROPS */, ["aria-label"]),
2363
+ _createElementVNode("div", {
2364
+ class: _normalizeClass(["tool-config-write-scope", { locked: !_ctx.isToolConfigWriteAllowed('opencode') }])
2365
+ }, [
2366
+ _createElementVNode("div", { class: "tool-config-write-body" }, [
2367
+ _createElementVNode("section", { class: "selector-section" }, [
2368
+ _createElementVNode("div", { class: "selector-header" }, [
2369
+ _createElementVNode("span", { class: "selector-title" }, _toDisplayString(_ctx.t('opencode.providerModel.title')), 1 /* TEXT */),
2370
+ _createElementVNode("div", { class: "selector-actions opencode-provider-actions" }, [
2371
+ _createElementVNode("button", {
2372
+ type: "button",
2373
+ class: "btn-tool btn-tool-compact",
2374
+ onClick: $event => (_ctx.loadOpencodeConfig({ toast: true })),
2375
+ disabled: _ctx.opencodeLoading
2376
+ }, _toDisplayString(_ctx.opencodeLoading ? _ctx.t('common.refreshing') : _ctx.t('common.refresh')), 9 /* TEXT, PROPS */, ["onClick", "disabled"]),
2377
+ _createElementVNode("button", {
2378
+ type: "button",
2379
+ class: "btn-tool btn-tool-compact",
2380
+ onClick: _ctx.applyOpencodeSelection,
2381
+ disabled: _ctx.opencodeApplying || _ctx.opencodeLoading || !_ctx.isToolConfigWriteAllowed('opencode')
2382
+ }, _toDisplayString(_ctx.opencodeApplying ? _ctx.t('common.applying') : _ctx.t('opencode.applySelection')), 9 /* TEXT, PROPS */, ["onClick", "disabled"])
2383
+ ])
2384
+ ]),
2385
+ _createElementVNode("div", { class: "config-template-hint" }, _toDisplayString(_ctx.t('opencode.targetFile', { path: _ctx.opencodeConfigPath || '~/.config/opencode/opencode.jsonc', status: _ctx.opencodeConfigExists ? _ctx.t('common.exists') : _ctx.t('common.notExistsWillCreateOnSave') })), 1 /* TEXT */),
2386
+ _createElementVNode("div", { class: "config-template-hint" }, _toDisplayString(_ctx.t('opencode.providerStoreFile', { path: _ctx.opencodeProviderStorePath || '~/.codexmate/opencode/providers.json' })), 1 /* TEXT */),
2387
+ _createElementVNode("div", { class: "codex-config-grid" }, [
2388
+ _createElementVNode("div", { class: "form-group codex-config-field" }, [
2389
+ _createElementVNode("label", {
2390
+ class: "form-label",
2391
+ for: "opencode-provider"
2392
+ }, _toDisplayString(_ctx.t('field.provider')), 1 /* TEXT */),
2393
+ _withDirectives(_createElementVNode("input", {
2394
+ id: "opencode-provider",
2395
+ class: "form-input",
2396
+ "onUpdate:modelValue": $event => ((_ctx.opencodeProvider) = $event),
2397
+ list: "opencode-provider-options",
2398
+ autocomplete: "off",
2399
+ spellcheck: "false",
2400
+ onChange: $event => (_ctx.fillOpencodeProvider(_ctx.opencodeProvider)),
2401
+ onBlur: $event => (_ctx.fillOpencodeProvider(_ctx.opencodeProvider)),
2402
+ placeholder: "anthropic / openai / gemini"
2403
+ }, null, 40 /* PROPS, NEED_HYDRATION */, ["onUpdate:modelValue", "onChange", "onBlur"]), [
2404
+ [_vModelText, _ctx.opencodeProvider]
2405
+ ]),
2406
+ _createElementVNode("datalist", { id: "opencode-provider-options" }, [
2407
+ (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.opencodeProviderCatalog(), (provider) => {
2408
+ return (_openBlock(), _createElementBlock("option", {
2409
+ key: provider,
2410
+ value: provider
2411
+ }, null, 8 /* PROPS */, ["value"]))
2412
+ }), 128 /* KEYED_FRAGMENT */))
2413
+ ])
2414
+ ]),
2415
+ _createElementVNode("div", { class: "form-group codex-config-field" }, [
2416
+ _createElementVNode("label", {
2417
+ class: "form-label",
2418
+ for: "opencode-model"
2419
+ }, _toDisplayString(_ctx.t('field.model')), 1 /* TEXT */),
2420
+ _withDirectives(_createElementVNode("input", {
2421
+ id: "opencode-model",
2422
+ class: "form-input",
2423
+ "onUpdate:modelValue": $event => ((_ctx.opencodeModel) = $event),
2424
+ list: "opencode-model-options",
2425
+ autocomplete: "off",
2426
+ spellcheck: "false",
2427
+ placeholder: "claude-3.7-sonnet / gpt-4.1"
2428
+ }, null, 8 /* PROPS */, ["onUpdate:modelValue"]), [
2429
+ [_vModelText, _ctx.opencodeModel]
2430
+ ]),
2431
+ _createElementVNode("datalist", { id: "opencode-model-options" }, [
2432
+ (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.opencodeModelCatalogForProvider(_ctx.opencodeProvider), (model) => {
2433
+ return (_openBlock(), _createElementBlock("option", {
2434
+ key: model,
2435
+ value: model
2436
+ }, null, 8 /* PROPS */, ["value"]))
2437
+ }), 128 /* KEYED_FRAGMENT */))
2438
+ ])
2439
+ ]),
2440
+ _createElementVNode("div", { class: "form-group codex-config-field" }, [
2441
+ _createElementVNode("label", {
2442
+ class: "form-label",
2443
+ for: "opencode-agent"
2444
+ }, _toDisplayString(_ctx.t('opencode.field.agent')), 1 /* TEXT */),
2445
+ _withDirectives(_createElementVNode("input", {
2446
+ id: "opencode-agent",
2447
+ class: "form-input",
2448
+ "onUpdate:modelValue": $event => ((_ctx.opencodeAgent) = $event),
2449
+ list: "opencode-agent-options",
2450
+ autocomplete: "off",
2451
+ spellcheck: "false",
2452
+ placeholder: "build"
2453
+ }, null, 8 /* PROPS */, ["onUpdate:modelValue"]), [
2454
+ [_vModelText, _ctx.opencodeAgent]
2455
+ ]),
2456
+ _createElementVNode("datalist", { id: "opencode-agent-options" }, [
2457
+ _createElementVNode("option", { value: "build" }),
2458
+ _createElementVNode("option", { value: "plan" }),
2459
+ _createElementVNode("option", { value: "general" }),
2460
+ _createElementVNode("option", { value: "summary" }),
2461
+ _createElementVNode("option", { value: "compaction" }),
2462
+ _createElementVNode("option", { value: "title" }),
2463
+ (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.opencodeAgents, (agent) => {
2464
+ return (_openBlock(), _createElementBlock("option", {
2465
+ key: agent.name,
2466
+ value: agent.name
2467
+ }, null, 8 /* PROPS */, ["value"]))
2468
+ }), 128 /* KEYED_FRAGMENT */))
2469
+ ])
2470
+ ]),
2471
+ _createElementVNode("div", { class: "form-group codex-config-field" }, [
2472
+ _createElementVNode("label", {
2473
+ class: "form-label",
2474
+ for: "opencode-api-key"
2475
+ }, _toDisplayString(_ctx.t('opencode.field.apiKeyKeep')), 1 /* TEXT */),
2476
+ _createElementVNode("div", { class: "input-with-toggle" }, [
2477
+ _withDirectives(_createElementVNode("input", {
2478
+ id: "opencode-api-key",
2479
+ class: "form-input",
2480
+ "onUpdate:modelValue": $event => ((_ctx.opencodeApiKey) = $event),
2481
+ type: _ctx.opencodeShowKey ? 'text' : 'password',
2482
+ autocomplete: "off",
2483
+ spellcheck: "false",
2484
+ placeholder: "sk-..."
2485
+ }, null, 8 /* PROPS */, ["onUpdate:modelValue", "type"]), [
2486
+ [_vModelDynamic, _ctx.opencodeApiKey]
2487
+ ]),
2488
+ _createElementVNode("button", {
2489
+ type: "button",
2490
+ class: "input-toggle-btn",
2491
+ onClick: $event => (_ctx.opencodeShowKey = !_ctx.opencodeShowKey),
2492
+ title: _ctx.opencodeShowKey ? _ctx.t('common.hide') : _ctx.t('common.show')
2493
+ }, _toDisplayString(_ctx.opencodeShowKey ? _ctx.t('common.hide') : _ctx.t('common.show')), 9 /* TEXT, PROPS */, ["onClick", "title"])
2494
+ ])
2495
+ ]),
2496
+ _createElementVNode("div", { class: "form-group codex-config-field" }, [
2497
+ _createElementVNode("label", {
2498
+ class: "form-label",
2499
+ for: "opencode-max-tokens"
2500
+ }, _toDisplayString(_ctx.t('opencode.field.maxTokens')), 1 /* TEXT */),
2501
+ _withDirectives(_createElementVNode("input", {
2502
+ id: "opencode-max-tokens",
2503
+ class: "form-input",
2504
+ "onUpdate:modelValue": $event => ((_ctx.opencodeMaxTokens) = $event),
2505
+ inputmode: "numeric",
2506
+ autocomplete: "off",
2507
+ placeholder: "5000"
2508
+ }, null, 8 /* PROPS */, ["onUpdate:modelValue"]), [
2509
+ [_vModelText, _ctx.opencodeMaxTokens]
2510
+ ])
2511
+ ]),
2512
+ _createElementVNode("div", { class: "form-group codex-config-field" }, [
2513
+ _createElementVNode("label", {
2514
+ class: "form-label",
2515
+ for: "opencode-reasoning-effort"
2516
+ }, _toDisplayString(_ctx.t('opencode.field.reasoningEffort')), 1 /* TEXT */),
2517
+ _withDirectives(_createElementVNode("select", {
2518
+ id: "opencode-reasoning-effort",
2519
+ class: "model-select",
2520
+ "onUpdate:modelValue": $event => ((_ctx.opencodeReasoningEffort) = $event)
2521
+ }, [
2522
+ _createElementVNode("option", { value: "" }, _toDisplayString(_ctx.t('opencode.option.keepUnchanged')), 1 /* TEXT */),
2523
+ _createElementVNode("option", { value: "low" }, _toDisplayString(_ctx.t('opencode.option.reasoningLow')), 1 /* TEXT */),
2524
+ _createElementVNode("option", { value: "medium" }, _toDisplayString(_ctx.t('opencode.option.reasoningMedium')), 1 /* TEXT */),
2525
+ _createElementVNode("option", { value: "high" }, _toDisplayString(_ctx.t('opencode.option.reasoningHigh')), 1 /* TEXT */)
2526
+ ], 8 /* PROPS */, ["onUpdate:modelValue"]), [
2527
+ [_vModelSelect, _ctx.opencodeReasoningEffort]
2528
+ ])
2529
+ ])
2530
+ ]),
2531
+ _createElementVNode("label", {
2532
+ class: "settings-toggle-row",
2533
+ style: {"margin-top":"12px"}
2534
+ }, [
2535
+ _withDirectives(_createElementVNode("input", {
2536
+ type: "checkbox",
2537
+ "onUpdate:modelValue": $event => ((_ctx.opencodeApplyToCoreAgents) = $event)
2538
+ }, null, 8 /* PROPS */, ["onUpdate:modelValue"]), [
2539
+ [_vModelCheckbox, _ctx.opencodeApplyToCoreAgents]
2540
+ ]),
2541
+ _createElementVNode("span", { class: "toggle-track" }, [
2542
+ _createElementVNode("span", { class: "toggle-thumb" })
2543
+ ]),
2544
+ _createElementVNode("span", null, _toDisplayString(_ctx.t('opencode.applyToCoreAgents')), 1 /* TEXT */)
2545
+ ]),
2546
+ _createElementVNode("label", {
2547
+ class: "settings-toggle-row",
2548
+ style: {"margin-top":"8px"}
2549
+ }, [
2550
+ _withDirectives(_createElementVNode("input", {
2551
+ type: "checkbox",
2552
+ "onUpdate:modelValue": $event => ((_ctx.opencodeAutoCompact) = $event)
2553
+ }, null, 8 /* PROPS */, ["onUpdate:modelValue"]), [
2554
+ [_vModelCheckbox, _ctx.opencodeAutoCompact]
2555
+ ]),
2556
+ _createElementVNode("span", { class: "toggle-track" }, [
2557
+ _createElementVNode("span", { class: "toggle-thumb" })
2558
+ ]),
2559
+ _createElementVNode("span", null, _toDisplayString(_ctx.t('opencode.enableAutoCompaction')), 1 /* TEXT */)
2560
+ ]),
2561
+ _createElementVNode("label", {
2562
+ class: "settings-toggle-row",
2563
+ style: {"margin-top":"8px"}
2564
+ }, [
2565
+ _withDirectives(_createElementVNode("input", {
2566
+ type: "checkbox",
2567
+ "onUpdate:modelValue": $event => ((_ctx.opencodeProviderDisabled) = $event)
2568
+ }, null, 8 /* PROPS */, ["onUpdate:modelValue"]), [
2569
+ [_vModelCheckbox, _ctx.opencodeProviderDisabled]
2570
+ ]),
2571
+ _createElementVNode("span", { class: "toggle-track" }, [
2572
+ _createElementVNode("span", { class: "toggle-thumb" })
2573
+ ]),
2574
+ _createElementVNode("span", null, _toDisplayString(_ctx.t('opencode.disableProvider')), 1 /* TEXT */)
2575
+ ])
2576
+ ]),
2577
+ _createElementVNode("section", { class: "selector-section" }, [
2578
+ _createElementVNode("div", { class: "selector-header" }, [
2579
+ _createElementVNode("span", { class: "selector-title" }, _toDisplayString(_ctx.t('opencode.configFile.title')), 1 /* TEXT */),
2580
+ _createElementVNode("div", { class: "selector-actions" }, [
2581
+ _createElementVNode("button", {
2582
+ type: "button",
2583
+ class: "btn-tool btn-tool-compact",
2584
+ onClick: $event => (_ctx.$refs.opencodeImportInput && _ctx.$refs.opencodeImportInput.click())
2585
+ }, _toDisplayString(_ctx.t('opencode.importParse')), 9 /* TEXT, PROPS */, ["onClick"]),
2586
+ _createElementVNode("button", {
2587
+ type: "button",
2588
+ class: "btn-tool btn-tool-compact",
2589
+ onClick: _ctx.saveOpencodeConfig,
2590
+ disabled: _ctx.opencodeSaving || _ctx.opencodeLoading || !_ctx.isToolConfigWriteAllowed('opencode')
2591
+ }, _toDisplayString(_ctx.opencodeSaving ? _ctx.t('common.saving') : _ctx.t('opencode.saveConfig')), 9 /* TEXT, PROPS */, ["onClick", "disabled"])
2592
+ ])
2593
+ ]),
2594
+ _createElementVNode("input", {
2595
+ ref: "opencodeImportInput",
2596
+ class: "sr-only",
2597
+ type: "file",
2598
+ accept: ".json,.jsonc,.opencode",
2599
+ onChange: _ctx.handleOpencodeImportChange
2600
+ }, null, 40 /* PROPS, NEED_HYDRATION */, ["onChange"]),
2601
+ (_ctx.opencodeImportFileName)
2602
+ ? (_openBlock(), _createElementBlock("div", {
2603
+ key: 0,
2604
+ class: "config-template-hint"
2605
+ }, _toDisplayString(_ctx.t('opencode.parsedFile', { file: _ctx.opencodeImportFileName })), 1 /* TEXT */))
2606
+ : _createCommentVNode("v-if", true),
2607
+ (_ctx.opencodeError || _ctx.opencodeImportError)
2608
+ ? (_openBlock(), _createElementBlock("div", {
2609
+ key: 1,
2610
+ class: "config-template-hint error-text"
2611
+ }, _toDisplayString(_ctx.opencodeError || _ctx.opencodeImportError), 1 /* TEXT */))
2612
+ : _createCommentVNode("v-if", true),
2613
+ _withDirectives(_createElementVNode("textarea", {
2614
+ class: "template-textarea",
2615
+ "onUpdate:modelValue": $event => ((_ctx.opencodeContent) = $event),
2616
+ spellcheck: "false",
2617
+ readonly: _ctx.opencodeSaving || _ctx.opencodeLoading,
2618
+ placeholder: _ctx.t('opencode.textarea.placeholder')
2619
+ }, null, 8 /* PROPS */, ["onUpdate:modelValue", "readonly", "placeholder"]), [
2620
+ [_vModelText, _ctx.opencodeContent]
2621
+ ]),
2622
+ _createElementVNode("div", { class: "config-template-hint" }, _toDisplayString(_ctx.t('opencode.configFile.hint')), 1 /* TEXT */)
2623
+ ]),
2624
+ (_ctx.opencodeProviders.length || _ctx.opencodeAgents.length)
2625
+ ? (_openBlock(), _createElementBlock("section", {
2626
+ key: 0,
2627
+ class: "selector-section"
2628
+ }, [
2629
+ _createElementVNode("div", { class: "selector-header" }, [
2630
+ _createElementVNode("span", { class: "selector-title" }, _toDisplayString(_ctx.t('opencode.summary.title')), 1 /* TEXT */)
2631
+ ]),
2632
+ _createElementVNode("div", { class: "card-list" }, [
2633
+ (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.opencodeProviders, (provider) => {
2634
+ return (_openBlock(), _createElementBlock("div", {
2635
+ key: provider.name,
2636
+ class: "card"
2637
+ }, [
2638
+ _createElementVNode("div", { class: "card-leading" }, [
2639
+ _createElementVNode("div", { class: "card-icon" }, _toDisplayString(provider.name.charAt(0).toUpperCase()), 1 /* TEXT */),
2640
+ _createElementVNode("div", { class: "card-content" }, [
2641
+ _createElementVNode("div", { class: "card-title" }, _toDisplayString(provider.name), 1 /* TEXT */),
2642
+ _createElementVNode("div", { class: "card-subtitle" }, _toDisplayString(provider.hasKey ? provider.apiKey : _ctx.t('opencode.summary.noApiKey')), 1 /* TEXT */)
2643
+ ])
2644
+ ]),
2645
+ _createElementVNode("div", { class: "card-trailing" }, [
2646
+ _createElementVNode("span", {
2647
+ class: _normalizeClass(['pill', provider.disabled ? 'empty' : 'configured'])
2648
+ }, _toDisplayString(provider.disabled ? _ctx.t('common.disabled') : _ctx.t('common.enabled')), 3 /* TEXT, CLASS */),
2649
+ _createElementVNode("span", { class: "pill empty" }, _toDisplayString(provider.source === 'codexmate' ? _ctx.t('opencode.summary.sourceCodexMate') : _ctx.t('opencode.summary.sourceOpenCode')), 1 /* TEXT */)
2650
+ ])
2651
+ ]))
2652
+ }), 128 /* KEYED_FRAGMENT */)),
2653
+ (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.opencodeAgents, (agent) => {
2654
+ return (_openBlock(), _createElementBlock("div", {
2655
+ key: agent.name,
2656
+ class: "card"
2657
+ }, [
2658
+ _createElementVNode("div", { class: "card-leading" }, [
2659
+ _createElementVNode("div", { class: "card-icon" }, "A"),
2660
+ _createElementVNode("div", { class: "card-content" }, [
2661
+ _createElementVNode("div", { class: "card-title" }, _toDisplayString(agent.name), 1 /* TEXT */),
2662
+ _createElementVNode("div", { class: "card-subtitle" }, _toDisplayString(agent.model || _ctx.t('opencode.summary.noModel')), 1 /* TEXT */)
2663
+ ])
2664
+ ]),
2665
+ _createElementVNode("div", { class: "card-trailing" }, [
2666
+ _createElementVNode("span", { class: "pill configured" }, _toDisplayString(_ctx.t('opencode.summary.agentType')), 1 /* TEXT */)
2667
+ ])
2668
+ ]))
2669
+ }), 128 /* KEYED_FRAGMENT */))
2670
+ ])
2671
+ ]))
2672
+ : _createCommentVNode("v-if", true),
2673
+ (!_ctx.isToolConfigWriteAllowed('opencode'))
2674
+ ? (_openBlock(), _createElementBlock("div", {
2675
+ key: 1,
2676
+ class: "tool-config-write-overlay"
2677
+ }, [
2678
+ _createElementVNode("div", { class: "tool-config-write-overlay-card" }, [
2679
+ _createElementVNode("div", { class: "tool-config-write-overlay-title" }, _toDisplayString(_ctx.t('toolConfig.opencode.lockedTitle')), 1 /* TEXT */),
2680
+ _createElementVNode("p", null, _toDisplayString(_ctx.t('toolConfig.opencode.lockedDesc')), 1 /* TEXT */),
2681
+ _createElementVNode("button", {
2682
+ type: "button",
2683
+ class: "btn-tool",
2684
+ onClick: $event => (_ctx.setToolConfigPermission('opencode', true)),
2685
+ disabled: _ctx.toolConfigPermissionSaving.opencode
2686
+ }, _toDisplayString(_ctx.t('toolConfig.enableWrite')), 9 /* TEXT, PROPS */, ["onClick", "disabled"])
2687
+ ])
2688
+ ]))
2689
+ : _createCommentVNode("v-if", true)
2690
+ ])
2691
+ ], 2 /* CLASS */)
2692
+ ], 8 /* PROPS */, ["aria-labelledby"]), [
2693
+ [_vShow, _ctx.mainTab === 'config' && _ctx.configMode === 'opencode']
2694
+ ]),
2257
2695
  _createCommentVNode(" 会话浏览模式 "),
2258
2696
  _withDirectives(_createElementVNode("div", {
2259
2697
  class: "mode-content",
@@ -2650,31 +3088,163 @@ return function render(_ctx, _cache) {
2650
3088
  _createElementVNode("button", {
2651
3089
  class: "btn-session-refresh",
2652
3090
  onClick: _ctx.loadActiveSessionDetail,
2653
- disabled: _ctx.sessionDetailLoading || !_ctx.activeSession
2654
- }, _toDisplayString(_ctx.sessionDetailLoading ? _ctx.t('sessions.preview.loading') : _ctx.t('sessions.preview.refresh')), 9 /* TEXT, PROPS */, ["onClick", "disabled"]),
3091
+ disabled: _ctx.sessionDetailLoading || !_ctx.activeSession,
3092
+ title: _ctx.sessionDetailLoading ? _ctx.t('sessions.preview.loading') : _ctx.t('sessions.preview.refresh'),
3093
+ "aria-label": _ctx.sessionDetailLoading ? _ctx.t('sessions.preview.loading') : _ctx.t('sessions.preview.refresh')
3094
+ }, [
3095
+ (_openBlock(), _createElementBlock("svg", {
3096
+ viewBox: "0 0 16 16",
3097
+ fill: "none",
3098
+ stroke: "currentColor",
3099
+ "stroke-width": "1.8",
3100
+ "stroke-linecap": "round",
3101
+ "stroke-linejoin": "round"
3102
+ }, [
3103
+ _createElementVNode("path", { d: "M2.5 8a5.5 5.5 0 0 1 9.4-3.8" }),
3104
+ _createElementVNode("path", { d: "M13.5 8a5.5 5.5 0 0 1-9.4 3.8" }),
3105
+ _createElementVNode("polyline", { points: "2.5 2 2.5 5 5.5 5" }),
3106
+ _createElementVNode("polyline", { points: "13.5 14 13.5 11 10.5 11" })
3107
+ ]))
3108
+ ], 8 /* PROPS */, ["onClick", "disabled", "title", "aria-label"]),
2655
3109
  (_ctx.isDeleteAvailable(_ctx.activeSession))
2656
3110
  ? (_openBlock(), _createElementBlock("button", {
2657
3111
  key: 0,
2658
3112
  class: "btn-session-delete",
2659
3113
  onClick: $event => (_ctx.deleteSession(_ctx.activeSession)),
2660
- disabled: !_ctx.activeSession || _ctx.sessionsLoading || _ctx.sessionDeleting[_ctx.getSessionExportKey(_ctx.activeSession)]
2661
- }, _toDisplayString((_ctx.activeSession && _ctx.sessionDeleting[_ctx.getSessionExportKey(_ctx.activeSession)]) ? (_ctx.sessionTrashEnabled === false ? _ctx.t('sessions.preview.deleting') : _ctx.t('sessions.preview.moving')) : (_ctx.sessionTrashEnabled === false ? _ctx.t('sessions.preview.deleteHard') : _ctx.t('sessions.preview.moveToTrash'))), 9 /* TEXT, PROPS */, ["onClick", "disabled"]))
3114
+ disabled: !_ctx.activeSession || _ctx.sessionsLoading || _ctx.sessionDeleting[_ctx.getSessionExportKey(_ctx.activeSession)],
3115
+ title: (_ctx.activeSession && _ctx.sessionDeleting[_ctx.getSessionExportKey(_ctx.activeSession)]) ? (_ctx.sessionTrashEnabled === false ? _ctx.t('sessions.preview.deleting') : _ctx.t('sessions.preview.moving')) : (_ctx.sessionTrashEnabled === false ? _ctx.t('sessions.preview.deleteHard') : _ctx.t('sessions.preview.moveToTrash')),
3116
+ "aria-label": (_ctx.activeSession && _ctx.sessionDeleting[_ctx.getSessionExportKey(_ctx.activeSession)]) ? (_ctx.sessionTrashEnabled === false ? _ctx.t('sessions.preview.deleting') : _ctx.t('sessions.preview.moving')) : (_ctx.sessionTrashEnabled === false ? _ctx.t('sessions.preview.deleteHard') : _ctx.t('sessions.preview.moveToTrash'))
3117
+ }, [
3118
+ (_openBlock(), _createElementBlock("svg", {
3119
+ viewBox: "0 0 16 16",
3120
+ fill: "none",
3121
+ stroke: "currentColor",
3122
+ "stroke-width": "1.8",
3123
+ "stroke-linecap": "round",
3124
+ "stroke-linejoin": "round"
3125
+ }, [
3126
+ _createElementVNode("polyline", { points: "3 4 4 4 13 4" }),
3127
+ _createElementVNode("path", { d: "M5.5 4V2.5a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1V4" }),
3128
+ _createElementVNode("path", { d: "M12 4v9.5a1.5 1.5 0 0 1-1.5 1.5h-5A1.5 1.5 0 0 1 4 13.5V4" })
3129
+ ]))
3130
+ ], 8 /* PROPS */, ["onClick", "disabled", "title", "aria-label"]))
2662
3131
  : _createCommentVNode("v-if", true),
2663
3132
  _createElementVNode("button", {
2664
3133
  class: "btn-session-export",
2665
3134
  onClick: $event => (_ctx.exportSession(_ctx.activeSession)),
2666
- disabled: !_ctx.activeSession || _ctx.sessionExporting[_ctx.getSessionExportKey(_ctx.activeSession)]
2667
- }, _toDisplayString((_ctx.activeSession && _ctx.sessionExporting[_ctx.getSessionExportKey(_ctx.activeSession)]) ? _ctx.t('sessions.preview.exporting') : _ctx.t('sessions.preview.export')), 9 /* TEXT, PROPS */, ["onClick", "disabled"]),
2668
- _createElementVNode("button", {
2669
- class: "btn-session-open",
2670
- onClick: $event => (_ctx.copySessionLink(_ctx.activeSession)),
2671
- disabled: !_ctx.activeSession
2672
- }, _toDisplayString(_ctx.t('sessions.preview.copyLink')), 9 /* TEXT, PROPS */, ["onClick", "disabled"]),
3135
+ disabled: !_ctx.activeSession || _ctx.sessionExporting[_ctx.getSessionExportKey(_ctx.activeSession)],
3136
+ title: (_ctx.activeSession && _ctx.sessionExporting[_ctx.getSessionExportKey(_ctx.activeSession)]) ? _ctx.t('sessions.preview.exporting') : _ctx.t('sessions.preview.export'),
3137
+ "aria-label": (_ctx.activeSession && _ctx.sessionExporting[_ctx.getSessionExportKey(_ctx.activeSession)]) ? _ctx.t('sessions.preview.exporting') : _ctx.t('sessions.preview.export')
3138
+ }, [
3139
+ (_openBlock(), _createElementBlock("svg", {
3140
+ viewBox: "0 0 16 16",
3141
+ fill: "none",
3142
+ stroke: "currentColor",
3143
+ "stroke-width": "1.8",
3144
+ "stroke-linecap": "round",
3145
+ "stroke-linejoin": "round"
3146
+ }, [
3147
+ _createElementVNode("path", { d: "M8 2v8" }),
3148
+ _createElementVNode("polyline", { points: "4 7 8 10.5 12 7" }),
3149
+ _createElementVNode("path", { d: "M2.5 12v1.5a1 1 0 0 0 1 1h9a1 1 0 0 0 1-1V12" })
3150
+ ]))
3151
+ ], 8 /* PROPS */, ["onClick", "disabled", "title", "aria-label"]),
3152
+ _createElementVNode("div", { class: "session-link-group" }, [
3153
+ _createElementVNode("button", {
3154
+ class: "btn-session-open",
3155
+ onClick: $event => (_ctx.copySessionLink(_ctx.activeSession)),
3156
+ disabled: !_ctx.activeSession || !_ctx.canBuildStandaloneUrl(_ctx.activeSession),
3157
+ title: _ctx.t('sessions.preview.copyLink'),
3158
+ "aria-label": _ctx.t('sessions.preview.copyLink')
3159
+ }, [
3160
+ (_openBlock(), _createElementBlock("svg", {
3161
+ viewBox: "0 0 16 16",
3162
+ fill: "none",
3163
+ stroke: "currentColor",
3164
+ "stroke-width": "1.8",
3165
+ "stroke-linecap": "round",
3166
+ "stroke-linejoin": "round"
3167
+ }, [
3168
+ _createElementVNode("rect", {
3169
+ x: "6",
3170
+ y: "2.5",
3171
+ width: "4",
3172
+ height: "2",
3173
+ rx: "1"
3174
+ }),
3175
+ _createElementVNode("path", { d: "M4.5 4h7a.5.5 0 0 1 .5.5v9a.5.5 0 0 1-.5.5h-7a.5.5 0 0 1-.5-.5v-9a.5.5 0 0 1 .5-.5" }),
3176
+ _createElementVNode("line", {
3177
+ x1: "6",
3178
+ y1: "7.5",
3179
+ x2: "10",
3180
+ y2: "7.5"
3181
+ }),
3182
+ _createElementVNode("line", {
3183
+ x1: "6",
3184
+ y1: "10",
3185
+ x2: "10",
3186
+ y2: "10"
3187
+ })
3188
+ ]))
3189
+ ], 8 /* PROPS */, ["onClick", "disabled", "title", "aria-label"]),
3190
+ _createElementVNode("button", {
3191
+ class: "btn-session-open",
3192
+ onClick: $event => (_ctx.openSessionLink(_ctx.activeSession)),
3193
+ disabled: !_ctx.activeSession || !_ctx.canBuildStandaloneUrl(_ctx.activeSession),
3194
+ title: _ctx.t('sessions.preview.openLink'),
3195
+ "aria-label": _ctx.t('sessions.preview.openLink')
3196
+ }, [
3197
+ (_openBlock(), _createElementBlock("svg", {
3198
+ viewBox: "0 0 16 16",
3199
+ fill: "none",
3200
+ stroke: "currentColor",
3201
+ "stroke-width": "1.8",
3202
+ "stroke-linecap": "round",
3203
+ "stroke-linejoin": "round"
3204
+ }, [
3205
+ _createElementVNode("path", { d: "M12 2h-8.5A1.5 1.5 0 0 0 2 3.5v8A1.5 1.5 0 0 0 3.5 13h8a1.5 1.5 0 0 0 1.5-1.5v-3" }),
3206
+ _createElementVNode("path", { d: "M13 2v4h-4" }),
3207
+ _createElementVNode("path", { d: "M13 2L7 8" })
3208
+ ]))
3209
+ ], 8 /* PROPS */, ["onClick", "disabled", "title", "aria-label"])
3210
+ ]),
2673
3211
  _createElementVNode("button", {
2674
3212
  class: "btn-session-open",
2675
3213
  onClick: $event => (_ctx.copySessionPath(_ctx.activeSession)),
2676
- disabled: !_ctx.activeSession || !_ctx.getSessionFilePath(_ctx.activeSession)
2677
- }, _toDisplayString(_ctx.t('sessions.preview.copyPath')), 9 /* TEXT, PROPS */, ["onClick", "disabled"])
3214
+ disabled: !_ctx.activeSession || !_ctx.getSessionFilePath(_ctx.activeSession),
3215
+ title: _ctx.t('sessions.preview.copyPath'),
3216
+ "aria-label": _ctx.t('sessions.preview.copyPath')
3217
+ }, [
3218
+ (_openBlock(), _createElementBlock("svg", {
3219
+ viewBox: "0 0 16 16",
3220
+ fill: "none",
3221
+ stroke: "currentColor",
3222
+ "stroke-width": "1.8",
3223
+ "stroke-linecap": "round",
3224
+ "stroke-linejoin": "round"
3225
+ }, [
3226
+ _createElementVNode("rect", {
3227
+ x: "6",
3228
+ y: "2.5",
3229
+ width: "4",
3230
+ height: "2",
3231
+ rx: "1"
3232
+ }),
3233
+ _createElementVNode("path", { d: "M4.5 4h7a.5.5 0 0 1 .5.5v9a.5.5 0 0 1-.5.5h-7a.5.5 0 0 1-.5-.5v-9a.5.5 0 0 1 .5-.5" }),
3234
+ _createElementVNode("line", {
3235
+ x1: "6",
3236
+ y1: "7.5",
3237
+ x2: "10",
3238
+ y2: "7.5"
3239
+ }),
3240
+ _createElementVNode("line", {
3241
+ x1: "6",
3242
+ y1: "10",
3243
+ x2: "10",
3244
+ y2: "10"
3245
+ })
3246
+ ]))
3247
+ ], 8 /* PROPS */, ["onClick", "disabled", "title", "aria-label"])
2678
3248
  ])
2679
3249
  ], 512 /* NEED_PATCH */),
2680
3250
  (_ctx.sessionDetailLoading && !_ctx.sessionPreviewLoadingMore)
@@ -2980,80 +3550,106 @@ return function render(_ctx, _cache) {
2980
3550
  }, [
2981
3551
  _createElementVNode("div", { class: "usage-card-title" }, _toDisplayString(_ctx.t('usage.daily.title')), 1 /* TEXT */),
2982
3552
  _createElementVNode("div", { class: "usage-wave-container" }, [
2983
- (_openBlock(), _createElementBlock("svg", {
2984
- class: "usage-wave-chart",
2985
- viewBox: "0 0 800 140",
2986
- preserveAspectRatio: "none"
2987
- }, [
2988
- _createElementVNode("defs", null, [
2989
- _createElementVNode("linearGradient", {
2990
- id: 'wave-gradient-' + _ctx.sessionsUsageTimeRange,
2991
- x1: "0",
2992
- y1: "0",
2993
- x2: "0",
2994
- y2: "1"
2995
- }, [
2996
- _createElementVNode("stop", {
2997
- offset: "0%",
2998
- "stop-color": 'var(--color-brand)',
2999
- "stop-opacity": "0.35"
3000
- }),
3001
- _createElementVNode("stop", {
3002
- offset: "100%",
3003
- "stop-color": 'var(--color-brand)',
3004
- "stop-opacity": "0"
3005
- })
3006
- ], 8 /* PROPS */, ["id"])
3007
- ]),
3008
- _createElementVNode("path", {
3009
- d: _ctx.sessionUsageWave.areaPath,
3010
- fill: 'url(#wave-gradient-' + _ctx.sessionsUsageTimeRange + ')',
3011
- class: "usage-wave-area"
3012
- }, null, 8 /* PROPS */, ["d", "fill"]),
3013
- _createElementVNode("path", {
3014
- d: _ctx.sessionUsageWave.linePath,
3015
- fill: "none",
3016
- stroke: 'var(--color-brand)',
3017
- "stroke-width": "2.5",
3018
- "stroke-linecap": "round",
3019
- "stroke-linejoin": "round",
3020
- class: "usage-wave-line"
3021
- }, null, 8 /* PROPS */, ["d"]),
3022
- (_ctx.sessionsUsageSelectedDay)
3023
- ? (_openBlock(), _createElementBlock("line", {
3024
- key: 0,
3553
+ _createElementVNode("div", { class: "usage-wave-yaxis" }, [
3554
+ (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.sessionUsageWave.yTicks, (tick) => {
3555
+ return (_openBlock(), _createElementBlock("span", {
3556
+ key: tick.value,
3557
+ class: "usage-wave-ytick",
3558
+ style: _normalizeStyle({ bottom: tick.percent + '%' })
3559
+ }, _toDisplayString(tick.label), 5 /* TEXT, STYLE */))
3560
+ }), 128 /* KEYED_FRAGMENT */))
3561
+ ]),
3562
+ _createElementVNode("div", { class: "usage-wave-chart-area" }, [
3563
+ (_openBlock(), _createElementBlock("svg", {
3564
+ class: "usage-wave-chart",
3565
+ viewBox: "0 0 800 140",
3566
+ preserveAspectRatio: "none"
3567
+ }, [
3568
+ _createElementVNode("defs", null, [
3569
+ _createElementVNode("linearGradient", {
3570
+ id: 'wave-gradient-' + _ctx.sessionsUsageTimeRange,
3571
+ x1: "0",
3572
+ y1: "0",
3573
+ x2: "0",
3574
+ y2: "1"
3575
+ }, [
3576
+ _createElementVNode("stop", {
3577
+ offset: "0%",
3578
+ "stop-color": 'var(--color-brand)',
3579
+ "stop-opacity": "0.35"
3580
+ }),
3581
+ _createElementVNode("stop", {
3582
+ offset: "100%",
3583
+ "stop-color": 'var(--color-brand)',
3584
+ "stop-opacity": "0"
3585
+ })
3586
+ ], 8 /* PROPS */, ["id"])
3587
+ ]),
3588
+ (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.sessionUsageWave.yTicks, (tick) => {
3589
+ return (_openBlock(), _createElementBlock("line", {
3590
+ key: 'g-' + tick.value,
3025
3591
  x1: "0",
3026
3592
  x2: _ctx.sessionUsageWave.width,
3027
- y1: _ctx.sessionUsageWave.hoverY,
3028
- y2: _ctx.sessionUsageWave.hoverY,
3593
+ y1: tick.y,
3594
+ y2: tick.y,
3029
3595
  stroke: "currentColor",
3030
- "stroke-width": "1",
3031
- "stroke-dasharray": "4 4",
3032
- opacity: "0.5",
3033
- class: "usage-wave-hover-line"
3596
+ "stroke-width": "0.5",
3597
+ opacity: "0.12",
3598
+ class: "usage-wave-gridline"
3034
3599
  }, null, 8 /* PROPS */, ["x2", "y1", "y2"]))
3035
- : _createCommentVNode("v-if", true),
3036
- (_ctx.sessionsUsageSelectedDay)
3037
- ? (_openBlock(), _createElementBlock("circle", {
3038
- key: 1,
3039
- cx: _ctx.sessionUsageWave.hoverX,
3040
- cy: _ctx.sessionUsageWave.hoverY,
3041
- r: "5",
3042
- fill: 'var(--color-surface)',
3043
- stroke: 'var(--color-brand)',
3044
- "stroke-width": "2.5",
3045
- class: "usage-wave-hover-point"
3046
- }, null, 8 /* PROPS */, ["cx", "cy"]))
3047
- : _createCommentVNode("v-if", true)
3048
- ])),
3049
- _createElementVNode("div", { class: "usage-wave-labels" }, [
3050
- (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.sessionUsageWave.labels, (label) => {
3051
- return (_openBlock(), _createElementBlock("span", {
3052
- key: label.key,
3053
- class: _normalizeClass(["usage-wave-label", { active: _ctx.sessionsUsageSelectedDay === label.key }]),
3054
- onClick: $event => (_ctx.selectSessionsUsageDay(label.key))
3055
- }, _toDisplayString(label.text), 11 /* TEXT, CLASS, PROPS */, ["onClick"]))
3056
- }), 128 /* KEYED_FRAGMENT */))
3600
+ }), 128 /* KEYED_FRAGMENT */)),
3601
+ _createElementVNode("path", {
3602
+ d: _ctx.sessionUsageWave.areaPath,
3603
+ fill: 'url(#wave-gradient-' + _ctx.sessionsUsageTimeRange + ')',
3604
+ class: "usage-wave-area"
3605
+ }, null, 8 /* PROPS */, ["d", "fill"]),
3606
+ _createElementVNode("path", {
3607
+ d: _ctx.sessionUsageWave.linePath,
3608
+ fill: "none",
3609
+ stroke: 'var(--color-brand)',
3610
+ "stroke-width": "2.5",
3611
+ "stroke-linecap": "round",
3612
+ "stroke-linejoin": "round",
3613
+ class: "usage-wave-line"
3614
+ }, null, 8 /* PROPS */, ["d"]),
3615
+ (_ctx.sessionsUsageSelectedDay)
3616
+ ? (_openBlock(), _createElementBlock("line", {
3617
+ key: 0,
3618
+ x1: "0",
3619
+ x2: _ctx.sessionUsageWave.width,
3620
+ y1: _ctx.sessionUsageWave.hoverY,
3621
+ y2: _ctx.sessionUsageWave.hoverY,
3622
+ stroke: "currentColor",
3623
+ "stroke-width": "1",
3624
+ "stroke-dasharray": "4 4",
3625
+ opacity: "0.5",
3626
+ class: "usage-wave-hover-line"
3627
+ }, null, 8 /* PROPS */, ["x2", "y1", "y2"]))
3628
+ : _createCommentVNode("v-if", true),
3629
+ (_ctx.sessionsUsageSelectedDay)
3630
+ ? (_openBlock(), _createElementBlock("circle", {
3631
+ key: 1,
3632
+ cx: _ctx.sessionUsageWave.hoverX,
3633
+ cy: _ctx.sessionUsageWave.hoverY,
3634
+ r: "5",
3635
+ fill: 'var(--color-surface)',
3636
+ stroke: 'var(--color-brand)',
3637
+ "stroke-width": "2.5",
3638
+ class: "usage-wave-hover-point"
3639
+ }, null, 8 /* PROPS */, ["cx", "cy"]))
3640
+ : _createCommentVNode("v-if", true)
3641
+ ])),
3642
+ _createElementVNode("div", { class: "usage-wave-labels" }, [
3643
+ (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.sessionUsageWave.labels, (label) => {
3644
+ return (_openBlock(), _createElementBlock("button", {
3645
+ key: label.key,
3646
+ type: "button",
3647
+ class: _normalizeClass(["usage-wave-label", { active: _ctx.sessionsUsageSelectedDay === label.key }]),
3648
+ "aria-pressed": _ctx.sessionsUsageSelectedDay === label.key,
3649
+ onClick: $event => (_ctx.selectSessionsUsageDay(label.key))
3650
+ }, _toDisplayString(label.text), 11 /* TEXT, CLASS, PROPS */, ["aria-pressed", "onClick"]))
3651
+ }), 128 /* KEYED_FRAGMENT */))
3652
+ ])
3057
3653
  ])
3058
3654
  ]),
3059
3655
  (_ctx.sessionsUsageSelectedDaySummary)
@@ -5364,15 +5960,169 @@ return function render(_ctx, _cache) {
5364
5960
  style: {"display":"none"},
5365
5961
  onChange: _ctx.handlePromptTemplatesImportChange
5366
5962
  }, null, 40 /* PROPS, NEED_HYDRATION */, ["onChange"]),
5367
- _createCommentVNode(" 加载状态 "),
5368
- (_ctx.loading)
5963
+ _createCommentVNode(" Prompts editor "),
5964
+ (_ctx.mainTab === 'prompts')
5369
5965
  ? (_openBlock(), _createElementBlock("div", {
5370
5966
  key: 1,
5967
+ class: "mode-content mode-cards",
5968
+ id: "panel-prompts",
5969
+ role: "tabpanel",
5970
+ "aria-labelledby": "tab-prompts"
5971
+ }, [
5972
+ _createElementVNode("div", { class: "segmented-control" }, [
5973
+ _createElementVNode("button", {
5974
+ type: "button",
5975
+ class: _normalizeClass(['segment', { active: _ctx.promptsSubTab === 'codex' }]),
5976
+ onClick: $event => (_ctx.switchPromptsSubTab('codex'))
5977
+ }, _toDisplayString(_ctx.t('prompts.subTab.codex')), 11 /* TEXT, CLASS, PROPS */, ["onClick"]),
5978
+ _createElementVNode("button", {
5979
+ type: "button",
5980
+ class: _normalizeClass(['segment', { active: _ctx.promptsSubTab === 'claude-md' }]),
5981
+ onClick: $event => (_ctx.switchPromptsSubTab('claude-md'))
5982
+ }, _toDisplayString(_ctx.t('prompts.subTab.claude')), 11 /* TEXT, CLASS, PROPS */, ["onClick"])
5983
+ ]),
5984
+ _createElementVNode("div", { class: "prompts-editor" }, [
5985
+ _createElementVNode("div", { class: "prompts-editor-toolbar" }, [
5986
+ _createElementVNode("div", { class: "form-hint" }, [
5987
+ _createTextVNode(_toDisplayString(_ctx.agentsPath || _ctx.t('common.notLoaded')) + " ", 1 /* TEXT */),
5988
+ (_ctx.agentsPath)
5989
+ ? (_openBlock(), _createElementBlock("span", { key: 0 }, " (" + _toDisplayString(_ctx.agentsExists ? _ctx.t('common.exists') : _ctx.t('common.notExistsWillCreateOnSave')) + ") ", 1 /* TEXT */))
5990
+ : _createCommentVNode("v-if", true)
5991
+ ]),
5992
+ _createElementVNode("div", { class: "prompts-editor-actions" }, [
5993
+ _createElementVNode("div", { class: "prompts-editor-group prompts-editor-group--secondary" }, [
5994
+ _createElementVNode("button", {
5995
+ class: "btn-mini",
5996
+ onClick: _ctx.exportAgentsContent,
5997
+ disabled: _ctx.agentsLoading
5998
+ }, _toDisplayString(_ctx.t('modal.agents.export')), 9 /* TEXT, PROPS */, ["onClick", "disabled"]),
5999
+ _createElementVNode("button", {
6000
+ class: "btn-mini",
6001
+ onClick: _ctx.copyAgentsContent,
6002
+ disabled: _ctx.agentsLoading
6003
+ }, _toDisplayString(_ctx.t('modal.agents.copy')), 9 /* TEXT, PROPS */, ["onClick", "disabled"]),
6004
+ _createElementVNode("button", {
6005
+ class: "btn-mini",
6006
+ onClick: _ctx.pasteAgentsContent,
6007
+ disabled: _ctx.agentsLoading || _ctx.agentsSaving || _ctx.agentsDiffVisible
6008
+ }, _toDisplayString(_ctx.t('common.paste')), 9 /* TEXT, PROPS */, ["onClick", "disabled"])
6009
+ ]),
6010
+ _createElementVNode("div", { class: "prompts-editor-group prompts-editor-group--workflow" }, [
6011
+ _createElementVNode("button", {
6012
+ class: "btn-mini",
6013
+ onClick: _ctx.loadPromptsContent,
6014
+ disabled: _ctx.agentsSaving || _ctx.agentsDiffLoading
6015
+ }, _toDisplayString(_ctx.t('common.cancel')), 9 /* TEXT, PROPS */, ["onClick", "disabled"]),
6016
+ (_ctx.agentsDiffVisible)
6017
+ ? (_openBlock(), _createElementBlock("button", {
6018
+ key: 0,
6019
+ class: "btn-mini",
6020
+ onClick: _ctx.resetAgentsDiffState,
6021
+ disabled: _ctx.agentsSaving || _ctx.agentsDiffLoading
6022
+ }, _toDisplayString(_ctx.t('common.backToEdit')), 9 /* TEXT, PROPS */, ["onClick", "disabled"]))
6023
+ : _createCommentVNode("v-if", true),
6024
+ _createElementVNode("button", {
6025
+ class: "btn-mini btn-confirm-mini",
6026
+ onClick: _ctx.applyAgentsContent,
6027
+ disabled: _ctx.agentsSaving || _ctx.agentsLoading || _ctx.agentsDiffLoading || (!_ctx.agentsDiffVisible && !_ctx.hasAgentsContentChanged()) || (_ctx.agentsDiffVisible && !_ctx.agentsDiffHasChanges)
6028
+ }, _toDisplayString(_ctx.agentsSaving ? (_ctx.agentsDiffVisible ? _ctx.t('common.saving') : _ctx.t('common.previewing')) : (_ctx.agentsDiffVisible ? _ctx.t('common.save') : _ctx.t('common.preview'))), 9 /* TEXT, PROPS */, ["onClick", "disabled"])
6029
+ ])
6030
+ ])
6031
+ ]),
6032
+ _createElementVNode("div", { class: "form-group" }, [
6033
+ (_ctx.agentsDiffVisible)
6034
+ ? (_openBlock(), _createElementBlock("div", { key: 0 }, [
6035
+ (!_ctx.agentsDiffLoading && !_ctx.agentsDiffError && !_ctx.agentsDiffTruncated && (_ctx.agentsDiffStats.added || _ctx.agentsDiffStats.removed))
6036
+ ? (_openBlock(), _createElementBlock("div", {
6037
+ key: 0,
6038
+ class: "agents-diff-summary"
6039
+ }, [
6040
+ _createElementVNode("span", { class: "agents-diff-stat add" }, "+" + _toDisplayString(_ctx.agentsDiffStats.added), 1 /* TEXT */),
6041
+ _createElementVNode("span", { class: "agents-diff-stat del" }, "-" + _toDisplayString(_ctx.agentsDiffStats.removed), 1 /* TEXT */)
6042
+ ]))
6043
+ : _createCommentVNode("v-if", true),
6044
+ (_ctx.agentsDiffLoading)
6045
+ ? (_openBlock(), _createElementBlock("div", {
6046
+ key: 1,
6047
+ class: "state-message"
6048
+ }, _toDisplayString(_ctx.t('diff.generating')), 1 /* TEXT */))
6049
+ : (_ctx.agentsDiffError)
6050
+ ? (_openBlock(), _createElementBlock("div", {
6051
+ key: 2,
6052
+ class: "state-message error"
6053
+ }, _toDisplayString(_ctx.agentsDiffError), 1 /* TEXT */))
6054
+ : (_ctx.agentsDiffTruncated)
6055
+ ? (_openBlock(), _createElementBlock("div", {
6056
+ key: 3,
6057
+ class: "agents-diff-empty"
6058
+ }, _toDisplayString(_ctx.t('diff.tooLargeSkip')), 1 /* TEXT */))
6059
+ : (!_ctx.agentsDiffHasChanges)
6060
+ ? (_openBlock(), _createElementBlock("div", {
6061
+ key: 4,
6062
+ class: "agents-diff-empty"
6063
+ }, _toDisplayString(_ctx.t('diff.noChanges')), 1 /* TEXT */))
6064
+ : (_openBlock(), _createElementBlock("div", {
6065
+ key: 5,
6066
+ class: "agents-diff-view agents-diff-editor"
6067
+ }, [
6068
+ (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.agentsDiffLines, (line, index) => {
6069
+ return (_openBlock(), _createElementBlock("div", {
6070
+ key: line.key || (line.type + '-' + index),
6071
+ class: _normalizeClass(['agents-diff-line', line.type])
6072
+ }, [
6073
+ _createElementVNode("span", { class: "agents-diff-line-sign" }, _toDisplayString(line.type === 'add' ? '+' : (line.type === 'del' ? '-' : ' ')), 1 /* TEXT */),
6074
+ _createElementVNode("span", { class: "agents-diff-line-text" }, _toDisplayString(line.value), 1 /* TEXT */)
6075
+ ], 2 /* CLASS */))
6076
+ }), 128 /* KEYED_FRAGMENT */))
6077
+ ]))
6078
+ ]))
6079
+ : _createCommentVNode("v-if", true),
6080
+ _createElementVNode("div", {
6081
+ class: _normalizeClass(['editor-frame', { 'editor-frame--loading': _ctx.agentsLoading }])
6082
+ }, [
6083
+ (_ctx.agentsLoading)
6084
+ ? (_openBlock(), _createElementBlock("div", {
6085
+ key: 0,
6086
+ class: "editor-skeleton"
6087
+ }, [
6088
+ (_openBlock(), _createElementBlock(_Fragment, null, _renderList(6, (i) => {
6089
+ return _createElementVNode("div", {
6090
+ class: "skeleton-line",
6091
+ key: i
6092
+ })
6093
+ }), 64 /* STABLE_FRAGMENT */))
6094
+ ]))
6095
+ : _createCommentVNode("v-if", true),
6096
+ _withDirectives(_createElementVNode("textarea", {
6097
+ "onUpdate:modelValue": $event => ((_ctx.agentsContent) = $event),
6098
+ class: "form-input template-editor",
6099
+ spellcheck: "false",
6100
+ readonly: _ctx.agentsLoading || _ctx.agentsSaving || _ctx.agentsDiffVisible,
6101
+ onInput: _ctx.onAgentsContentInput,
6102
+ placeholder: _ctx.t(_ctx.promptsSubTab === 'claude-md' ? 'modal.agents.placeholder.claudeMd' : 'modal.agents.placeholder')
6103
+ }, null, 40 /* PROPS, NEED_HYDRATION */, ["onUpdate:modelValue", "readonly", "onInput", "placeholder"]), [
6104
+ [_vModelText, _ctx.agentsContent]
6105
+ ])
6106
+ ], 2 /* CLASS */),
6107
+ (_ctx.promptsContextHint)
6108
+ ? (_openBlock(), _createElementBlock("div", {
6109
+ key: 1,
6110
+ class: _normalizeClass(['prompts-context-hint', { 'prompts-context-hint--warn': _ctx.promptsContextHint.warn }])
6111
+ }, _toDisplayString(_ctx.promptsContextHint.text), 3 /* TEXT, CLASS */))
6112
+ : _createCommentVNode("v-if", true)
6113
+ ])
6114
+ ])
6115
+ ]))
6116
+ : _createCommentVNode("v-if", true),
6117
+ _createCommentVNode(" 加载状态 "),
6118
+ (_ctx.loading && _ctx.mainTab !== 'usage')
6119
+ ? (_openBlock(), _createElementBlock("div", {
6120
+ key: 2,
5371
6121
  class: "state-message"
5372
6122
  }, _toDisplayString(_ctx.t('app.loadingConfig')), 1 /* TEXT */))
5373
6123
  : (_ctx.initError)
5374
6124
  ? (_openBlock(), _createElementBlock("div", {
5375
- key: 2,
6125
+ key: 3,
5376
6126
  class: "state-message error"
5377
6127
  }, [
5378
6128
  _createCommentVNode(" 错误状态 "),
@@ -7187,7 +7937,26 @@ return function render(_ctx, _cache) {
7187
7937
  class: "btn-mini btn-modal-copy",
7188
7938
  onClick: _ctx.pasteAgentsContent,
7189
7939
  disabled: _ctx.agentsLoading || _ctx.agentsSaving || _ctx.agentsDiffVisible
7190
- }, _toDisplayString(_ctx.t('common.paste')), 9 /* TEXT, PROPS */, ["onClick", "disabled"])
7940
+ }, _toDisplayString(_ctx.t('common.paste')), 9 /* TEXT, PROPS */, ["onClick", "disabled"]),
7941
+ _createElementVNode("span", { class: "prompts-editor-actions-sep" }),
7942
+ _createElementVNode("button", {
7943
+ class: "btn-mini",
7944
+ onClick: _ctx.closeAgentsModal,
7945
+ disabled: _ctx.agentsSaving || _ctx.agentsDiffLoading
7946
+ }, _toDisplayString(_ctx.t('common.cancel')), 9 /* TEXT, PROPS */, ["onClick", "disabled"]),
7947
+ (_ctx.agentsDiffVisible)
7948
+ ? (_openBlock(), _createElementBlock("button", {
7949
+ key: 0,
7950
+ class: "btn-mini",
7951
+ onClick: _ctx.resetAgentsDiffState,
7952
+ disabled: _ctx.agentsSaving || _ctx.agentsDiffLoading
7953
+ }, _toDisplayString(_ctx.t('common.backToEdit')), 9 /* TEXT, PROPS */, ["onClick", "disabled"]))
7954
+ : _createCommentVNode("v-if", true),
7955
+ _createElementVNode("button", {
7956
+ class: "btn-mini btn-confirm-mini",
7957
+ onClick: _ctx.applyAgentsContent,
7958
+ disabled: _ctx.agentsSaving || _ctx.agentsLoading || _ctx.agentsDiffLoading || (_ctx.agentsDiffVisible && !_ctx.agentsDiffHasChanges)
7959
+ }, _toDisplayString(_ctx.agentsSaving ? (_ctx.agentsDiffVisible ? _ctx.t('common.saving') : _ctx.t('common.previewing')) : (_ctx.agentsDiffVisible ? _ctx.t('common.save') : _ctx.t('common.preview'))), 9 /* TEXT, PROPS */, ["onClick", "disabled"])
7191
7960
  ])
7192
7961
  ]),
7193
7962
  _createElementVNode("div", { class: "modal-editor-body" }, [
@@ -7299,26 +8068,6 @@ return function render(_ctx, _cache) {
7299
8068
  }, _toDisplayString(_ctx.t('diff.viewHint.preview')), 1 /* TEXT */))
7300
8069
  ])
7301
8070
  ])
7302
- ]),
7303
- _createElementVNode("div", { class: "btn-group modal-editor-footer" }, [
7304
- _createElementVNode("button", {
7305
- class: "btn btn-cancel",
7306
- onClick: _ctx.closeAgentsModal,
7307
- disabled: _ctx.agentsSaving || _ctx.agentsDiffLoading
7308
- }, _toDisplayString(_ctx.t('common.cancel')), 9 /* TEXT, PROPS */, ["onClick", "disabled"]),
7309
- (_ctx.agentsDiffVisible)
7310
- ? (_openBlock(), _createElementBlock("button", {
7311
- key: 0,
7312
- class: "btn",
7313
- onClick: _ctx.resetAgentsDiffState,
7314
- disabled: _ctx.agentsSaving || _ctx.agentsDiffLoading
7315
- }, _toDisplayString(_ctx.t('common.backToEdit')), 9 /* TEXT, PROPS */, ["onClick", "disabled"]))
7316
- : _createCommentVNode("v-if", true),
7317
- _createElementVNode("button", {
7318
- class: "btn btn-confirm",
7319
- onClick: _ctx.applyAgentsContent,
7320
- disabled: _ctx.agentsSaving || _ctx.agentsLoading || _ctx.agentsDiffLoading || (_ctx.agentsDiffVisible && !_ctx.agentsDiffHasChanges)
7321
- }, _toDisplayString(_ctx.agentsSaving ? (_ctx.agentsDiffVisible ? _ctx.t('common.applying') : _ctx.t('common.confirming')) : (_ctx.agentsDiffVisible ? _ctx.t('common.apply') : _ctx.t('common.confirm'))), 9 /* TEXT, PROPS */, ["onClick", "disabled"])
7322
8071
  ])
7323
8072
  ])
7324
8073
  ], 8 /* PROPS */, ["onClick"]))