codexmate 0.1.24 → 0.1.27

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 (50) hide show
  1. package/cli/session-usage.js +10 -4
  2. package/cli.js +737 -200
  3. package/lib/cli-sessions.js +1 -1
  4. package/package.json +3 -3
  5. package/plugins/prompt-templates/computed.mjs +1 -1
  6. package/plugins/prompt-templates/index.mjs +3 -3
  7. package/plugins/prompt-templates/manifest.mjs +5 -3
  8. package/plugins/prompt-templates/methods.mjs +9 -2
  9. package/plugins/registry.mjs +5 -2
  10. package/plugins/text-tools/computed.mjs +23 -0
  11. package/plugins/text-tools/index.mjs +14 -0
  12. package/plugins/text-tools/manifest.mjs +20 -0
  13. package/plugins/text-tools/methods.mjs +24 -0
  14. package/plugins/text-tools/overview.mjs +12 -0
  15. package/plugins/text-tools/ownership.mjs +7 -0
  16. package/tools/dev/launch.js +147 -0
  17. package/web-ui/app.js +15 -5
  18. package/web-ui/index.html +1 -2
  19. package/web-ui/logic.markdown-editor.mjs +5 -57
  20. package/web-ui/logic.prompts-token-count.mjs +49 -0
  21. package/web-ui/logic.sessions.mjs +30 -15
  22. package/web-ui/modules/app.computed.dashboard.mjs +1 -0
  23. package/web-ui/modules/app.computed.prompts.mjs +18 -0
  24. package/web-ui/modules/app.computed.session.mjs +3 -1
  25. package/web-ui/modules/app.methods.navigation.mjs +79 -3
  26. package/web-ui/modules/app.methods.prompts-editor.mjs +6 -64
  27. package/web-ui/modules/app.methods.session-actions.mjs +10 -4
  28. package/web-ui/modules/app.methods.session-browser.mjs +34 -45
  29. package/web-ui/modules/app.methods.session-timeline.mjs +1 -0
  30. package/web-ui/modules/app.methods.web-ui-preferences.mjs +7 -1
  31. package/web-ui/modules/i18n/locales/en.mjs +20 -1
  32. package/web-ui/modules/i18n/locales/ja.mjs +20 -1
  33. package/web-ui/modules/i18n/locales/vi.mjs +20 -1
  34. package/web-ui/modules/i18n/locales/zh-tw.mjs +20 -1
  35. package/web-ui/modules/i18n/locales/zh.mjs +20 -1
  36. package/web-ui/modules/plugins.computed.mjs +8 -2
  37. package/web-ui/modules/plugins.methods.mjs +8 -2
  38. package/web-ui/partials/index/layout-header.html +23 -6
  39. package/web-ui/partials/index/panel-plugins.html +45 -5
  40. package/web-ui/partials/index/panel-prompts.html +16 -17
  41. package/web-ui/partials/index/panel-sessions.html +19 -4
  42. package/web-ui/res/web-ui-render.precompiled.js +193 -93
  43. package/web-ui/session-helpers.mjs +1 -2
  44. package/web-ui/source-bundle.cjs +1 -0
  45. package/web-ui/styles/base-theme.css +24 -0
  46. package/web-ui/styles/modals-core.css +48 -0
  47. package/web-ui/styles/prompts-editor.css +3 -66
  48. package/web-ui/styles/sessions-list.css +1 -1
  49. package/web-ui/styles/sessions-preview.css +56 -7
  50. package/web-ui/styles/sessions-toolbar-trash.css +1 -7
@@ -97,9 +97,6 @@
97
97
  <button class="btn-tool btn-tool-compact" type="button" @click="switchMainTab('dashboard')" :title="t('dashboard.doctor.title')">
98
98
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="btn-icon-sm"><path d="M22 12h-4l-3 9L9 3l-3 9H2"/></svg>
99
99
  </button>
100
- <button class="btn-tool btn-tool-compact" type="button" @click="copySessionsFilterShareUrl" :disabled="sessionsLoading">
101
- {{ t('sessions.filters.copyLink') }}
102
- </button>
103
100
  <button class="btn-tool btn-tool-compact" type="button" @click="clearSessionFilters" :disabled="sessionsLoading">
104
101
  {{ t('common.resetFilters') }}
105
102
  </button>
@@ -409,7 +406,7 @@
409
406
  <span class="session-msg-time">{{ msg.timestamp || '' }}</span>
410
407
  </div>
411
408
  </div>
412
- <div class="session-msg-content" v-html="highlightQueryText(msg.text) || ''"></div>
409
+ <div class="session-msg-content" v-html="msg.text || ''"></div>
413
410
  <button
414
411
  v-if="msg.normalizedRole === 'user'"
415
412
  type="button"
@@ -432,6 +429,24 @@
432
429
  </div>
433
430
  </div>
434
431
  </div>
432
+ <div class="session-preview-jump">
433
+ <button
434
+ type="button"
435
+ class="session-match-nav-btn"
436
+ @click="scrollSessionPreviewToTop"
437
+ :title="t('sessions.preview.scrollTop')"
438
+ :aria-label="t('sessions.preview.scrollTop')">
439
+ <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 10 8 5 13 10"/></svg>
440
+ </button>
441
+ <button
442
+ type="button"
443
+ class="session-match-nav-btn"
444
+ @click="scrollSessionPreviewToBottom"
445
+ :title="t('sessions.preview.scrollBottom')"
446
+ :aria-label="t('sessions.preview.scrollBottom')">
447
+ <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 8 11 13 6"/></svg>
448
+ </button>
449
+ </div>
435
450
  <aside v-if="sessionPreviewRenderEnabled && sessionTimelineNodes.length" :class="['session-timeline', 'session-timeline-' + sessionTimelineStyle]" :aria-label="t('sessions.timeline.aria')">
436
451
  <!-- 点状模式 -->
437
452
  <template v-if="sessionTimelineStyle === 'dots'">
@@ -412,7 +412,7 @@ return function render(_ctx, _cache) {
412
412
  _createElementVNode("div", { class: "side-item-title" }, _toDisplayString(_ctx.t('side.sessions.browser')), 1 /* TEXT */),
413
413
  _createElementVNode("div", { class: "side-item-meta" }, [
414
414
  _createElementVNode("span", null, _toDisplayString(_ctx.t('side.sessions.browser.meta')), 1 /* TEXT */),
415
- _createElementVNode("span", null, _toDisplayString(_ctx.t('sessions.sourceLabel', { value: (_ctx.sessionFilterSource === 'all' ? _ctx.t('sessions.source.all') : (_ctx.sessionFilterSource === 'claude' ? 'Claude Code' : (_ctx.sessionFilterSource === 'gemini' ? 'Gemini CLI' : (_ctx.sessionFilterSource === 'codebuddy' ? 'CodeBuddy Code' : 'Codex')))) })), 1 /* TEXT */)
415
+ _createElementVNode("span", null, _toDisplayString(_ctx.t('sessions.sourceLabel', { value: (_ctx.sessionFilterSource === 'all' ? _ctx.t('sessions.source.all') : (_ctx.sessionFilterSource === 'claude' ? 'Claude Code' : (_ctx.sessionFilterSource === 'gemini' ? 'Gemini CLI' : (_ctx.sessionFilterSource === 'codebuddy' ? 'CodeBuddy Code' : (_ctx.sessionFilterSource === 'workbuddy' ? 'WorkBuddy AI' : 'Codex'))))) })), 1 /* TEXT */)
416
416
  ])
417
417
  ], 42 /* CLASS, PROPS, NEED_HYDRATION */, ["aria-current", "onPointerdown", "onClick"]),
418
418
  _createElementVNode("button", {
@@ -485,10 +485,11 @@ return function render(_ctx, _cache) {
485
485
  _createElementVNode("button", {
486
486
  id: "side-tab-plugins",
487
487
  "data-main-tab": "plugins",
488
- "aria-current": _ctx.mainTab === 'plugins' ? 'page' : null,
489
- class: _normalizeClass(['side-item', { active: _ctx.isMainTabNavActive('plugins') }]),
490
- onPointerdown: $event => (_ctx.onMainTabPointerDown('plugins', $event)),
491
- onClick: $event => (_ctx.onMainTabClick('plugins', $event))
488
+ "data-plugins-id": "prompt-templates",
489
+ "aria-current": _ctx.mainTab === 'plugins' && _ctx.pluginsActiveId === 'prompt-templates' ? 'page' : null,
490
+ class: _normalizeClass(['side-item', { active: _ctx.isPluginsIdNavActive('prompt-templates') }]),
491
+ onPointerdown: $event => (_ctx.onPluginsTabPointerDown('prompt-templates', $event)),
492
+ onClick: $event => (_ctx.onPluginsTabClick('prompt-templates', $event))
492
493
  }, [
493
494
  _createElementVNode("span", {
494
495
  class: "side-item-icon",
@@ -499,6 +500,24 @@ return function render(_ctx, _cache) {
499
500
  _createElementVNode("span", null, _toDisplayString(_ctx.t('side.plugins.tools.meta')), 1 /* TEXT */),
500
501
  _createElementVNode("span", null, _toDisplayString(_ctx.t('side.plugins.templatesCount', { count: _ctx.promptTemplatesList.length })), 1 /* TEXT */)
501
502
  ])
503
+ ], 42 /* CLASS, PROPS, NEED_HYDRATION */, ["aria-current", "onPointerdown", "onClick"]),
504
+ _createElementVNode("button", {
505
+ id: "side-tab-plugins-text-tools",
506
+ "data-main-tab": "plugins",
507
+ "data-plugins-id": "text-tools",
508
+ "aria-current": _ctx.mainTab === 'plugins' && _ctx.pluginsActiveId === 'text-tools' ? 'page' : null,
509
+ class: _normalizeClass(['side-item', { active: _ctx.isPluginsIdNavActive('text-tools') }]),
510
+ onPointerdown: $event => (_ctx.onPluginsTabPointerDown('text-tools', $event)),
511
+ onClick: $event => (_ctx.onPluginsTabClick('text-tools', $event))
512
+ }, [
513
+ _createElementVNode("span", {
514
+ class: "side-item-icon",
515
+ "aria-hidden": "true"
516
+ }, "▤"),
517
+ _createElementVNode("div", { class: "side-item-title" }, _toDisplayString(_ctx.t('plugins.catalog.textTools.title')), 1 /* TEXT */),
518
+ _createElementVNode("div", { class: "side-item-meta" }, [
519
+ _createElementVNode("span", null, _toDisplayString(_ctx.t('plugins.textTools.tools.compress')), 1 /* TEXT */)
520
+ ])
502
521
  ], 42 /* CLASS, PROPS, NEED_HYDRATION */, ["aria-current", "onPointerdown", "onClick"])
503
522
  ], 8 /* PROPS */, ["aria-label"]),
504
523
  _createElementVNode("div", {
@@ -708,7 +727,9 @@ return function render(_ctx, _cache) {
708
727
  ? _ctx.t('sessions.source.gemini')
709
728
  : (_ctx.sessionFilterSource === 'codebuddy'
710
729
  ? _ctx.t('sessions.source.codebuddy')
711
- : _ctx.t('sessions.source.codex')))))), 1 /* TEXT */)
730
+ : (_ctx.sessionFilterSource === 'workbuddy'
731
+ ? _ctx.t('sessions.source.workbuddy')
732
+ : _ctx.t('sessions.source.codex'))))))), 1 /* TEXT */)
712
733
  ]),
713
734
  _createElementVNode("div", { class: "status-chip" }, [
714
735
  _createElementVNode("span", { class: "label" }, _toDisplayString(_ctx.t('status.sessionCount')), 1 /* TEXT */),
@@ -3998,12 +4019,6 @@ return function render(_ctx, _cache) {
3998
4019
  _createElementVNode("path", { d: "M22 12h-4l-3 9L9 3l-3 9H2" })
3999
4020
  ]))
4000
4021
  ], 8 /* PROPS */, ["onClick", "title"]),
4001
- _createElementVNode("button", {
4002
- class: "btn-tool btn-tool-compact",
4003
- type: "button",
4004
- onClick: _ctx.copySessionsFilterShareUrl,
4005
- disabled: _ctx.sessionsLoading
4006
- }, _toDisplayString(_ctx.t('sessions.filters.copyLink')), 9 /* TEXT, PROPS */, ["onClick", "disabled"]),
4007
4022
  _createElementVNode("button", {
4008
4023
  class: "btn-tool btn-tool-compact",
4009
4024
  type: "button",
@@ -4628,7 +4643,7 @@ return function render(_ctx, _cache) {
4628
4643
  ]),
4629
4644
  _createElementVNode("div", {
4630
4645
  class: "session-msg-content",
4631
- innerHTML: _ctx.highlightQueryText(msg.text) || ''
4646
+ innerHTML: msg.text || ''
4632
4647
  }, null, 8 /* PROPS */, ["innerHTML"]),
4633
4648
  (msg.normalizedRole === 'user')
4634
4649
  ? (_openBlock(), _createElementBlock("button", {
@@ -4677,6 +4692,44 @@ return function render(_ctx, _cache) {
4677
4692
  ])
4678
4693
  ]))
4679
4694
  ], 40 /* PROPS, NEED_HYDRATION */, ["onScroll"]),
4695
+ _createElementVNode("div", { class: "session-preview-jump" }, [
4696
+ _createElementVNode("button", {
4697
+ type: "button",
4698
+ class: "session-match-nav-btn",
4699
+ onClick: _ctx.scrollSessionPreviewToTop,
4700
+ title: _ctx.t('sessions.preview.scrollTop'),
4701
+ "aria-label": _ctx.t('sessions.preview.scrollTop')
4702
+ }, [
4703
+ (_openBlock(), _createElementBlock("svg", {
4704
+ viewBox: "0 0 16 16",
4705
+ fill: "none",
4706
+ stroke: "currentColor",
4707
+ "stroke-width": "1.8",
4708
+ "stroke-linecap": "round",
4709
+ "stroke-linejoin": "round"
4710
+ }, [
4711
+ _createElementVNode("polyline", { points: "3 10 8 5 13 10" })
4712
+ ]))
4713
+ ], 8 /* PROPS */, ["onClick", "title", "aria-label"]),
4714
+ _createElementVNode("button", {
4715
+ type: "button",
4716
+ class: "session-match-nav-btn",
4717
+ onClick: _ctx.scrollSessionPreviewToBottom,
4718
+ title: _ctx.t('sessions.preview.scrollBottom'),
4719
+ "aria-label": _ctx.t('sessions.preview.scrollBottom')
4720
+ }, [
4721
+ (_openBlock(), _createElementBlock("svg", {
4722
+ viewBox: "0 0 16 16",
4723
+ fill: "none",
4724
+ stroke: "currentColor",
4725
+ "stroke-width": "1.8",
4726
+ "stroke-linecap": "round",
4727
+ "stroke-linejoin": "round"
4728
+ }, [
4729
+ _createElementVNode("polyline", { points: "3 6 8 11 13 6" })
4730
+ ]))
4731
+ ], 8 /* PROPS */, ["onClick", "title", "aria-label"])
4732
+ ]),
4680
4733
  (_ctx.sessionPreviewRenderEnabled && _ctx.sessionTimelineNodes.length)
4681
4734
  ? (_openBlock(), _createElementBlock("aside", {
4682
4735
  key: 0,
@@ -6330,14 +6383,6 @@ return function render(_ctx, _cache) {
6330
6383
  _createElementVNode("div", null, [
6331
6384
  _createElementVNode("span", { class: "selector-title" }, _toDisplayString(_ctx.t('plugins.sidebar.title')), 1 /* TEXT */),
6332
6385
  _createElementVNode("div", { class: "plugins-panel-note" }, _toDisplayString(_ctx.t('plugins.sidebar.note')), 1 /* TEXT */)
6333
- ]),
6334
- _createElementVNode("div", { class: "settings-tab-actions" }, [
6335
- _createElementVNode("button", {
6336
- type: "button",
6337
- class: "btn-tool btn-tool-compact",
6338
- onClick: $event => (_ctx.loadPluginsOverview({ forceRefresh: true, silent: false })),
6339
- disabled: _ctx.loading || !!_ctx.initError || _ctx.pluginsLoading
6340
- }, _toDisplayString(_ctx.pluginsLoading ? _ctx.t('plugins.refreshing') : _ctx.t('plugins.refresh')), 9 /* TEXT, PROPS */, ["onClick", "disabled"])
6341
6386
  ])
6342
6387
  ]),
6343
6388
  _createElementVNode("div", {
@@ -6845,10 +6890,83 @@ return function render(_ctx, _cache) {
6845
6890
  ])
6846
6891
  ]))
6847
6892
  ]))
6848
- : (_openBlock(), _createElementBlock("div", {
6849
- key: 3,
6850
- class: "skills-empty-state"
6851
- }, _toDisplayString(_ctx.t('plugins.promptTemplates.noPluginSelected')), 1 /* TEXT */))
6893
+ : (_ctx.pluginsActiveId === 'text-tools')
6894
+ ? (_openBlock(), _createElementBlock("div", {
6895
+ key: 3,
6896
+ class: "plugins-panel"
6897
+ }, [
6898
+ _createElementVNode("div", { class: "plugins-panel-head" }, [
6899
+ _createElementVNode("div", null, [
6900
+ _createElementVNode("div", { class: "plugins-panel-title" }, _toDisplayString(_ctx.t('plugins.textTools.title')), 1 /* TEXT */),
6901
+ (_ctx.pluginsActiveAttribution)
6902
+ ? (_openBlock(), _createElementBlock("div", {
6903
+ key: 0,
6904
+ class: "plugins-panel-note"
6905
+ }, _toDisplayString(_ctx.pluginsActiveAttribution), 1 /* TEXT */))
6906
+ : _createCommentVNode("v-if", true)
6907
+ ])
6908
+ ]),
6909
+ _createElementVNode("div", {
6910
+ class: "prompt-templates-modebar",
6911
+ role: "tablist",
6912
+ "aria-label": _ctx.t('plugins.textTools.tools.aria')
6913
+ }, [
6914
+ (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.textToolsList, (tool) => {
6915
+ return (_openBlock(), _createElementBlock("button", {
6916
+ key: 'text-tool-' + tool.id,
6917
+ type: "button",
6918
+ role: "tab",
6919
+ "aria-selected": _ctx.textToolsActiveToolId === tool.id,
6920
+ class: _normalizeClass(['mode-pill', { active: _ctx.textToolsActiveToolId === tool.id }]),
6921
+ onClick: $event => (_ctx.textToolsActiveToolId = tool.id)
6922
+ }, _toDisplayString(tool.label), 11 /* TEXT, CLASS, PROPS */, ["aria-selected", "onClick"]))
6923
+ }), 128 /* KEYED_FRAGMENT */))
6924
+ ], 8 /* PROPS */, ["aria-label"]),
6925
+ _createElementVNode("div", { class: "prompt-compose" }, [
6926
+ _createElementVNode("div", { class: "prompt-compose-workspace" }, [
6927
+ _createElementVNode("div", { class: "prompt-compose-main" }, [
6928
+ _createElementVNode("div", { class: "prompt-compose-form" }, [
6929
+ _createElementVNode("label", { class: "form-label" }, _toDisplayString(_ctx.t('plugins.textTools.compress.inputLabel')), 1 /* TEXT */),
6930
+ _withDirectives(_createElementVNode("textarea", {
6931
+ class: "form-input prompt-editor-textarea",
6932
+ "onUpdate:modelValue": $event => ((_ctx.textToolsInput) = $event),
6933
+ rows: "10",
6934
+ spellcheck: "false",
6935
+ placeholder: _ctx.t('plugins.textTools.compress.inputPlaceholder'),
6936
+ "aria-label": _ctx.t('plugins.textTools.compress.inputAria')
6937
+ }, null, 8 /* PROPS */, ["onUpdate:modelValue", "placeholder", "aria-label"]), [
6938
+ [_vModelText, _ctx.textToolsInput]
6939
+ ])
6940
+ ])
6941
+ ]),
6942
+ _createElementVNode("div", { class: "prompt-preview-block prompt-compose-preview" }, [
6943
+ _createElementVNode("div", { class: "prompt-vars-head" }, [
6944
+ _createElementVNode("div", null, [
6945
+ _createElementVNode("div", { class: "prompt-vars-title" }, _toDisplayString(_ctx.t('plugins.textTools.compress.outputTitle')), 1 /* TEXT */)
6946
+ ]),
6947
+ _createElementVNode("button", {
6948
+ type: "button",
6949
+ class: "btn-mini",
6950
+ onClick: _ctx.copyTextToolsOutput,
6951
+ disabled: !_ctx.textToolsOutput
6952
+ }, _toDisplayString(_ctx.t('plugins.textTools.compress.copy')), 9 /* TEXT, PROPS */, ["onClick", "disabled"])
6953
+ ]),
6954
+ _createElementVNode("textarea", {
6955
+ class: "form-input prompt-preview-textarea",
6956
+ value: _ctx.textToolsOutput,
6957
+ rows: "10",
6958
+ readonly: "",
6959
+ spellcheck: "false",
6960
+ "aria-label": _ctx.t('plugins.textTools.compress.outputAria')
6961
+ }, null, 8 /* PROPS */, ["value", "aria-label"])
6962
+ ])
6963
+ ])
6964
+ ])
6965
+ ]))
6966
+ : (_openBlock(), _createElementBlock("div", {
6967
+ key: 4,
6968
+ class: "skills-empty-state"
6969
+ }, _toDisplayString(_ctx.t('plugins.promptTemplates.noPluginSelected')), 1 /* TEXT */))
6852
6970
  ], 8 /* PROPS */, ["aria-label"])
6853
6971
  ], 2 /* CLASS */)
6854
6972
  ], 512 /* NEED_PATCH */), [
@@ -6950,6 +7068,12 @@ return function render(_ctx, _cache) {
6950
7068
  _createTextVNode(_toDisplayString(_ctx.agentsPath || _ctx.t('common.notLoaded')) + " ", 1 /* TEXT */),
6951
7069
  (_ctx.agentsPath)
6952
7070
  ? (_openBlock(), _createElementBlock("span", { key: 0 }, " (" + _toDisplayString(_ctx.agentsExists ? _ctx.t('common.exists') : _ctx.t('common.notExistsWillCreateOnSave')) + ") ", 1 /* TEXT */))
7071
+ : _createCommentVNode("v-if", true),
7072
+ (_ctx.agentsPath)
7073
+ ? (_openBlock(), _createElementBlock("span", {
7074
+ key: 1,
7075
+ class: "prompts-token-hint"
7076
+ }, "· " + _toDisplayString(_ctx.t('prompts.tokenCount.hint', { count: _ctx.agentsTokenCount })), 1 /* TEXT */))
6953
7077
  : _createCommentVNode("v-if", true)
6954
7078
  ]),
6955
7079
  _createElementVNode("div", { class: "prompts-editor-actions" }, [
@@ -7055,7 +7179,7 @@ return function render(_ctx, _cache) {
7055
7179
  _createElementVNode("div", { class: "prompts-editor-group prompts-editor-group--workflow" }, [
7056
7180
  _createElementVNode("button", {
7057
7181
  class: "btn-mini",
7058
- onClick: _ctx.loadPromptsContent,
7182
+ onClick: $event => (_ctx.agentsDiffVisible ? _ctx.resetAgentsDiffState() : _ctx.loadPromptsContent()),
7059
7183
  disabled: _ctx.agentsSaving || _ctx.agentsDiffLoading,
7060
7184
  title: _ctx.t('common.cancel')
7061
7185
  }, [
@@ -7069,25 +7193,6 @@ return function render(_ctx, _cache) {
7069
7193
  _createElementVNode("path", { d: "M18 6L6 18M6 6l12 12" })
7070
7194
  ]))
7071
7195
  ], 8 /* PROPS */, ["onClick", "disabled", "title"]),
7072
- (_ctx.agentsDiffVisible)
7073
- ? (_openBlock(), _createElementBlock("button", {
7074
- key: 0,
7075
- class: "btn-mini",
7076
- onClick: _ctx.resetAgentsDiffState,
7077
- disabled: _ctx.agentsSaving || _ctx.agentsDiffLoading,
7078
- title: _ctx.t('common.backToEdit')
7079
- }, [
7080
- (_openBlock(), _createElementBlock("svg", {
7081
- class: "btn-icon-sm",
7082
- viewBox: "0 0 24 24",
7083
- fill: "none",
7084
- stroke: "currentColor",
7085
- "stroke-width": "2"
7086
- }, [
7087
- _createElementVNode("path", { d: "M19 12H5M12 19l-7-7 7-7" })
7088
- ]))
7089
- ], 8 /* PROPS */, ["onClick", "disabled", "title"]))
7090
- : _createCommentVNode("v-if", true),
7091
7196
  _createElementVNode("button", {
7092
7197
  class: "btn-mini btn-confirm-mini",
7093
7198
  onClick: _ctx.applyAgentsContent,
@@ -7287,9 +7392,20 @@ return function render(_ctx, _cache) {
7287
7392
  _createElementVNode("div", { class: "form-group" }, [
7288
7393
  (_ctx.agentsDiffVisible)
7289
7394
  ? (_openBlock(), _createElementBlock("div", { key: 0 }, [
7290
- (!_ctx.agentsDiffLoading && !_ctx.agentsDiffError && !_ctx.agentsDiffTruncated && (_ctx.agentsDiffStats.added || _ctx.agentsDiffStats.removed))
7395
+ (!_ctx.agentsDiffLoading && !_ctx.agentsDiffError)
7291
7396
  ? (_openBlock(), _createElementBlock("div", {
7292
7397
  key: 0,
7398
+ class: "agents-diff-token-summary"
7399
+ }, [
7400
+ _createElementVNode("span", { class: "agents-diff-token-label" }, _toDisplayString(_ctx.t('prompts.tokenCount.diff', { before: _ctx.agentsDiffTokenStats.before, current: _ctx.agentsDiffTokenStats.current })), 1 /* TEXT */),
7401
+ _createElementVNode("span", {
7402
+ class: _normalizeClass(['agents-diff-token-delta', 'agents-diff-token-delta--' + _ctx.agentsDiffTokenStats.deltaKind])
7403
+ }, _toDisplayString(_ctx.agentsDiffTokenStats.deltaLabel), 3 /* TEXT, CLASS */)
7404
+ ]))
7405
+ : _createCommentVNode("v-if", true),
7406
+ (!_ctx.agentsDiffLoading && !_ctx.agentsDiffError && !_ctx.agentsDiffTruncated && (_ctx.agentsDiffStats.added || _ctx.agentsDiffStats.removed))
7407
+ ? (_openBlock(), _createElementBlock("div", {
7408
+ key: 1,
7293
7409
  class: "agents-diff-summary"
7294
7410
  }, [
7295
7411
  _createElementVNode("span", { class: "agents-diff-stat add" }, "+" + _toDisplayString(_ctx.agentsDiffStats.added), 1 /* TEXT */),
@@ -7298,26 +7414,26 @@ return function render(_ctx, _cache) {
7298
7414
  : _createCommentVNode("v-if", true),
7299
7415
  (_ctx.agentsDiffLoading)
7300
7416
  ? (_openBlock(), _createElementBlock("div", {
7301
- key: 1,
7417
+ key: 2,
7302
7418
  class: "state-message"
7303
7419
  }, _toDisplayString(_ctx.t('diff.generating')), 1 /* TEXT */))
7304
7420
  : (_ctx.agentsDiffError)
7305
7421
  ? (_openBlock(), _createElementBlock("div", {
7306
- key: 2,
7422
+ key: 3,
7307
7423
  class: "state-message error"
7308
7424
  }, _toDisplayString(_ctx.agentsDiffError), 1 /* TEXT */))
7309
7425
  : (_ctx.agentsDiffTruncated)
7310
7426
  ? (_openBlock(), _createElementBlock("div", {
7311
- key: 3,
7427
+ key: 4,
7312
7428
  class: "agents-diff-empty"
7313
7429
  }, _toDisplayString(_ctx.t('diff.tooLargeSkip')), 1 /* TEXT */))
7314
7430
  : (!_ctx.agentsDiffHasChanges)
7315
7431
  ? (_openBlock(), _createElementBlock("div", {
7316
- key: 4,
7432
+ key: 5,
7317
7433
  class: "agents-diff-empty"
7318
7434
  }, _toDisplayString(_ctx.t('diff.noChanges')), 1 /* TEXT */))
7319
7435
  : (_openBlock(), _createElementBlock("div", {
7320
- key: 5,
7436
+ key: 6,
7321
7437
  class: "prompts-diff-frame"
7322
7438
  }, [
7323
7439
  (_ctx.agentsChangeAxis.ticks.length)
@@ -7425,12 +7541,6 @@ return function render(_ctx, _cache) {
7425
7541
  : _createCommentVNode("v-if", true),
7426
7542
  _createElementVNode("div", { class: "prompts-editor-columns" }, [
7427
7543
  _createElementVNode("div", { class: "prompts-edit-pane" }, [
7428
- _createElementVNode("pre", {
7429
- ref: "promptsAgentsHighlight",
7430
- class: "prompts-highlight-backdrop",
7431
- "aria-hidden": "true",
7432
- innerHTML: _ctx.agentsHighlightHtml
7433
- }, null, 8 /* PROPS */, ["innerHTML"]),
7434
7544
  _withDirectives(_createElementVNode("textarea", {
7435
7545
  ref: "promptsAgentsTextarea",
7436
7546
  "onUpdate:modelValue": $event => ((_ctx.agentsContent) = $event),
@@ -7438,9 +7548,8 @@ return function render(_ctx, _cache) {
7438
7548
  spellcheck: "false",
7439
7549
  readonly: _ctx.agentsLoading || _ctx.agentsSaving || _ctx.agentsDiffVisible,
7440
7550
  onInput: _ctx.onAgentsContentInput,
7441
- onScroll: $event => (_ctx.syncPromptsOverlayScroll('agents')),
7442
7551
  placeholder: _ctx.t(_ctx.promptsSubTab === 'claude-project' ? 'modal.agents.placeholder.claudeProject' : 'modal.agents.placeholder')
7443
- }, null, 40 /* PROPS, NEED_HYDRATION */, ["onUpdate:modelValue", "readonly", "onInput", "onScroll", "placeholder"]), [
7552
+ }, null, 40 /* PROPS, NEED_HYDRATION */, ["onUpdate:modelValue", "readonly", "onInput", "placeholder"]), [
7444
7553
  [_vModelText, _ctx.agentsContent]
7445
7554
  ])
7446
7555
  ]),
@@ -7511,6 +7620,12 @@ return function render(_ctx, _cache) {
7511
7620
  _createTextVNode(_toDisplayString(_ctx.sysPromptPath || _ctx.t('common.notLoaded')) + " ", 1 /* TEXT */),
7512
7621
  (_ctx.sysPromptPath)
7513
7622
  ? (_openBlock(), _createElementBlock("span", { key: 0 }, " (" + _toDisplayString(_ctx.sysPromptExists ? _ctx.t('common.exists') : _ctx.t('common.notExistsWillCreateOnSave')) + ") ", 1 /* TEXT */))
7623
+ : _createCommentVNode("v-if", true),
7624
+ (_ctx.sysPromptPath)
7625
+ ? (_openBlock(), _createElementBlock("span", {
7626
+ key: 1,
7627
+ class: "prompts-token-hint"
7628
+ }, "· " + _toDisplayString(_ctx.t('prompts.tokenCount.hint', { count: _ctx.sysPromptTokenCount })), 1 /* TEXT */))
7514
7629
  : _createCommentVNode("v-if", true)
7515
7630
  ]),
7516
7631
  _createElementVNode("div", { class: "prompts-editor-actions" }, [
@@ -7616,7 +7731,7 @@ return function render(_ctx, _cache) {
7616
7731
  _createElementVNode("div", { class: "prompts-editor-group prompts-editor-group--workflow" }, [
7617
7732
  _createElementVNode("button", {
7618
7733
  class: "btn-mini",
7619
- onClick: _ctx.cancelSysPromptEdit,
7734
+ onClick: $event => (_ctx.sysPromptDiffVisible ? _ctx.resetSysPromptDiffState() : _ctx.cancelSysPromptEdit()),
7620
7735
  disabled: _ctx.sysPromptSaving || _ctx.sysPromptDiffLoading,
7621
7736
  title: _ctx.t('common.cancel')
7622
7737
  }, [
@@ -7630,25 +7745,6 @@ return function render(_ctx, _cache) {
7630
7745
  _createElementVNode("path", { d: "M18 6L6 18M6 6l12 12" })
7631
7746
  ]))
7632
7747
  ], 8 /* PROPS */, ["onClick", "disabled", "title"]),
7633
- (_ctx.sysPromptDiffVisible)
7634
- ? (_openBlock(), _createElementBlock("button", {
7635
- key: 0,
7636
- class: "btn-mini",
7637
- onClick: _ctx.resetSysPromptDiffState,
7638
- disabled: _ctx.sysPromptSaving || _ctx.sysPromptDiffLoading,
7639
- title: _ctx.t('common.backToEdit')
7640
- }, [
7641
- (_openBlock(), _createElementBlock("svg", {
7642
- class: "btn-icon-sm",
7643
- viewBox: "0 0 24 24",
7644
- fill: "none",
7645
- stroke: "currentColor",
7646
- "stroke-width": "2"
7647
- }, [
7648
- _createElementVNode("path", { d: "M19 12H5M12 19l-7-7 7-7" })
7649
- ]))
7650
- ], 8 /* PROPS */, ["onClick", "disabled", "title"]))
7651
- : _createCommentVNode("v-if", true),
7652
7748
  _createElementVNode("button", {
7653
7749
  class: "btn-mini btn-confirm-mini",
7654
7750
  onClick: _ctx.applySystemPrompt,
@@ -7754,9 +7850,20 @@ return function render(_ctx, _cache) {
7754
7850
  _createElementVNode("div", { class: "form-group" }, [
7755
7851
  (_ctx.sysPromptDiffVisible)
7756
7852
  ? (_openBlock(), _createElementBlock("div", { key: 0 }, [
7757
- (!_ctx.sysPromptDiffLoading && !_ctx.sysPromptDiffError && !_ctx.sysPromptDiffTruncated && (_ctx.sysPromptDiffStats.added || _ctx.sysPromptDiffStats.removed))
7853
+ (!_ctx.sysPromptDiffLoading && !_ctx.sysPromptDiffError)
7758
7854
  ? (_openBlock(), _createElementBlock("div", {
7759
7855
  key: 0,
7856
+ class: "agents-diff-token-summary"
7857
+ }, [
7858
+ _createElementVNode("span", { class: "agents-diff-token-label" }, _toDisplayString(_ctx.t('prompts.tokenCount.diff', { before: _ctx.sysPromptDiffTokenStats.before, current: _ctx.sysPromptDiffTokenStats.current })), 1 /* TEXT */),
7859
+ _createElementVNode("span", {
7860
+ class: _normalizeClass(['agents-diff-token-delta', 'agents-diff-token-delta--' + _ctx.sysPromptDiffTokenStats.deltaKind])
7861
+ }, _toDisplayString(_ctx.sysPromptDiffTokenStats.deltaLabel), 3 /* TEXT, CLASS */)
7862
+ ]))
7863
+ : _createCommentVNode("v-if", true),
7864
+ (!_ctx.sysPromptDiffLoading && !_ctx.sysPromptDiffError && !_ctx.sysPromptDiffTruncated && (_ctx.sysPromptDiffStats.added || _ctx.sysPromptDiffStats.removed))
7865
+ ? (_openBlock(), _createElementBlock("div", {
7866
+ key: 1,
7760
7867
  class: "agents-diff-summary"
7761
7868
  }, [
7762
7869
  _createElementVNode("span", { class: "agents-diff-stat add" }, "+" + _toDisplayString(_ctx.sysPromptDiffStats.added), 1 /* TEXT */),
@@ -7765,26 +7872,26 @@ return function render(_ctx, _cache) {
7765
7872
  : _createCommentVNode("v-if", true),
7766
7873
  (_ctx.sysPromptDiffLoading)
7767
7874
  ? (_openBlock(), _createElementBlock("div", {
7768
- key: 1,
7875
+ key: 2,
7769
7876
  class: "state-message"
7770
7877
  }, _toDisplayString(_ctx.t('diff.generating')), 1 /* TEXT */))
7771
7878
  : (_ctx.sysPromptDiffError)
7772
7879
  ? (_openBlock(), _createElementBlock("div", {
7773
- key: 2,
7880
+ key: 3,
7774
7881
  class: "state-message error"
7775
7882
  }, _toDisplayString(_ctx.sysPromptDiffError), 1 /* TEXT */))
7776
7883
  : (_ctx.sysPromptDiffTruncated)
7777
7884
  ? (_openBlock(), _createElementBlock("div", {
7778
- key: 3,
7885
+ key: 4,
7779
7886
  class: "agents-diff-empty"
7780
7887
  }, _toDisplayString(_ctx.t('diff.tooLargeSkip')), 1 /* TEXT */))
7781
7888
  : (!_ctx.sysPromptDiffHasChangesValue)
7782
7889
  ? (_openBlock(), _createElementBlock("div", {
7783
- key: 4,
7890
+ key: 5,
7784
7891
  class: "agents-diff-empty"
7785
7892
  }, _toDisplayString(_ctx.t('diff.noChanges')), 1 /* TEXT */))
7786
7893
  : (_openBlock(), _createElementBlock("div", {
7787
- key: 5,
7894
+ key: 6,
7788
7895
  class: "prompts-diff-frame"
7789
7896
  }, [
7790
7897
  (_ctx.sysChangeAxis.ticks.length)
@@ -7892,21 +7999,14 @@ return function render(_ctx, _cache) {
7892
7999
  : _createCommentVNode("v-if", true),
7893
8000
  _createElementVNode("div", { class: "prompts-editor-columns" }, [
7894
8001
  _createElementVNode("div", { class: "prompts-edit-pane" }, [
7895
- _createElementVNode("pre", {
7896
- ref: "promptsSysHighlight",
7897
- class: "prompts-highlight-backdrop",
7898
- "aria-hidden": "true",
7899
- innerHTML: _ctx.sysPromptHighlightHtml
7900
- }, null, 8 /* PROPS */, ["innerHTML"]),
7901
8002
  _withDirectives(_createElementVNode("textarea", {
7902
8003
  ref: "promptsSysTextarea",
7903
8004
  "onUpdate:modelValue": $event => ((_ctx.sysPromptContent) = $event),
7904
8005
  class: "form-input template-editor",
7905
8006
  spellcheck: "false",
7906
8007
  readonly: _ctx.sysPromptLoading || _ctx.sysPromptSaving || _ctx.sysPromptDiffVisible,
7907
- onScroll: $event => (_ctx.syncPromptsOverlayScroll('sys')),
7908
8008
  placeholder: _ctx.t('sysPrompt.placeholder')
7909
- }, null, 40 /* PROPS, NEED_HYDRATION */, ["onUpdate:modelValue", "readonly", "onScroll", "placeholder"]), [
8009
+ }, null, 8 /* PROPS */, ["onUpdate:modelValue", "readonly", "placeholder"]), [
7910
8010
  [_vModelText, _ctx.sysPromptContent]
7911
8011
  ])
7912
8012
  ]),
@@ -186,7 +186,6 @@ export function switchMainTab(tab) {
186
186
  void Promise.resolve(marketOverviewLoad).catch(() => {});
187
187
  }
188
188
  if (enteringPluginsTab && typeof this.loadPluginsOverview === 'function') {
189
- this.pluginsActiveId = 'prompt-templates';
190
189
  this.promptComposerPickerVisible = false;
191
190
  let pluginsLoad = null;
192
191
  try {
@@ -384,7 +383,7 @@ export async function loadActiveSessionDetail(api, options = {}) {
384
383
  sessionId: this.activeSession.sessionId,
385
384
  filePath: this.activeSession.filePath,
386
385
  messageLimit,
387
- preview
386
+ preview,
388
387
  });
389
388
 
390
389
  if (requestSeq !== this.sessionDetailRequestSeq) {
@@ -248,6 +248,7 @@ function transformJavaScriptModuleSource(source, options = {}) {
248
248
  });
249
249
  transformed = transformed.replace(/^[ \t]*export\s+\*\s+from\s+['"]\.[^'"]+['"]\s*;?\s*$/gm, '');
250
250
  if (!preserveExports) {
251
+ transformed = transformed.replace(/^[ \t]*export\s*\{[^{}\n]*\}\s*;?\s*$/gm, '');
251
252
  transformed = transformed.replace(/(^|\n)([ \t]*)export\s+(?=(?:async\s+function|const|let|class|function)\b)/g, '$1$2');
252
253
  }
253
254
  return transformed.trimEnd();
@@ -289,3 +289,27 @@ body::before {
289
289
  radial-gradient(circle at 86% 18%, rgba(255, 232, 206, 0.36), rgba(255, 232, 206, 0) 30%);
290
290
  z-index: 0;
291
291
  }
292
+
293
+ /* Site-wide custom scrollbars (class-scoped scrollbar-width:none rules keep priority via specificity) */
294
+ * {
295
+ scrollbar-width: thin;
296
+ scrollbar-color: rgba(137, 111, 94, 0.35) transparent;
297
+ }
298
+
299
+ ::-webkit-scrollbar {
300
+ width: 8px;
301
+ height: 8px;
302
+ }
303
+
304
+ ::-webkit-scrollbar-track {
305
+ background: transparent;
306
+ }
307
+
308
+ ::-webkit-scrollbar-thumb {
309
+ background: rgba(137, 111, 94, 0.35);
310
+ border-radius: 999px;
311
+ }
312
+
313
+ ::-webkit-scrollbar-thumb:hover {
314
+ background: rgba(137, 111, 94, 0.55);
315
+ }