# dsh-pulse bundle patch: inserts the usage observatory over the profile
# root. A patch replaces a targeted row's whole config, so this row restates
# every key it owns. Pricing defaults come from the official page
# (https://api-docs.deepseek.com/zh-cn/quick_start/pricing/, checked
# 2026-10-19) and are built into the plugin; list rules here only to override.
# Official rates are peak/off-peak over the official Beijing-time windows
# (09:00–12:00, 14:00–18:00, Monday–Friday only; `weekdaysOnly: false` bills a
# rule's peak hours every day instead): use a `peak` block for peak-hour rates
# (omit it for a flat rate) and `peakHours` (0–23, Beijing time) to override
# the windows per model. Rules price in CNY (default) or USD; USD converts into
# the unified CNY total through `usdToCny`.
# `costEnabled: false` hides the cost chip and the /pulse command cost line.
# All of this is also editable live from the settings page (Settings →
# 用量观测台 → 定价与费用): 0.2.0 hosts write those edits straight into this
# patch's entry config and the plugin re-applies with the fresh values (the
# settings service's describe() no longer carries per-namespace rows, so the
# entry config is the single live source). This patch stays the composition
# `base` layer under the user's edits.
#
# `defaultDays` names the window served when the client sends no range; the
# client normally requests an explicit `from`/`to`. The host half also
# requires the harness's session-projection seam (registry + persisted
# cache), which the web profile's base/web-app bundles already compose.
#
# Two faces, one package — mutually exclusive by composition shape (the
# dsh-tui pattern: entry-level `disabled` guards read `ctx.loader.entries()`,
# which sees every mounted row regardless of activation state):
# - `pulse` (web half, injects webServer) self-disables inside a dsh-tui
#   profile — no web app bundle there, and a pending webServer would
#   deadlock the TUI boot.
# - `pulse-tui` (terminal face, zero top-level external imports) self-
#   disables everywhere else — it would find no tuiScenes to register with.
- insert:
    - id: pulse
      name: 'dsh-pulse'
      disabled: !!js >-
        (() => {
          try {
            return [...ctx.loader.entries()].some((entry) => typeof entry.options?.name === 'string' && entry.options.name.startsWith('@deepseek-harness-tui/dsh-tui') && !entry.disabled)
          } catch {
            return false
          }
        })()
      config:
        defaultDays: 30
        topProjects: 8
        usdToCny: 6.8
        pricing: []

    - id: pulse-tui
      name: 'dsh-pulse/tui'
      # cordis 4.0.4 (dsh 0.2.0) hides every non-injected service from this
      # row's ctx.get — the four tui seams carry the mini card / shortcuts /
      # scenes / the mediated plugin host, and the remaining seams feed the
      # observatory: `sessionQuery` is collect()'s only hard dependency
      # (without it the scenes render 读取失败), `sessions` supplies the
      # live session's event-log length as the fold-cache version stamp
      # (without it the 30s poll never refolds the active session), and
      # `commands` is where /pulse and the five sub-commands land when the
      # dsh-tui mediated registration is unavailable (no admitted Component
      # identity for a plain dsh bundle → the C-070 direct fallback). All
      # are core services a booting dsh always mounts.
      inject:
        - tuiScenes
        - tuiPluginHost
        - tuiStatus
        - tuiShortcuts
        - sessionQuery
        - sessions
        - commands
      config:
        defaultDays: 30
        topProjects: 8
        usdToCny: 6.8
        pricing: []
        costEnabled: true
        monthlyProviders: []
        modelColors: {}
      disabled: !!js >-
        (() => {
          try {
            return ![...ctx.loader.entries()].some((entry) => typeof entry.options?.name === 'string' && entry.options.name.startsWith('@deepseek-harness-tui/dsh-tui') && !entry.disabled)
          } catch {
            return true
          }
        })()
