@goodandready/dsh-clinebot 0.3.8 → 0.3.10

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.
@@ -1,82 +0,0 @@
1
- # Design Contract: `@goodandready/dsh-clinebot`
2
-
3
- ## 1. Executive Summary
4
- `@goodandready/dsh-clinebot` is a companion plugin for DeepSeek Harness (DSH) enabling native integration of the **ClineBot / ClinePass** subscription provider. Because ClinePass is an OpenAI-compatible endpoint whose `GET /v1/models` returns `404 Not Found`, dynamic discovery is impossible. This plugin acts as the bridge: delivering a curated catalog of open-weights models, securely resolving credentials, exposing health and smoke tests, and mutating the DSH `llm-pi-ai` provider registry.
5
-
6
- ## 2. Architecture & Cordis Lifecycles
7
- The plugin consists of two runtime boundaries conforming to DSH authoring standards:
8
-
9
- ### 2.1 Host Runtime (`lib/index.js`, `lib/cline-client.js`, `lib/models.js`, `lib/http.js`)
10
- * **Cordis Service Registration**: Declares `inject = ['settings', 'webServer', 'credentials']` and registers the settings namespace dynamically via `ctx.inject(['settings'], (sctx) => { sctx.settings.register(NS, Config, { base: config }) })`. This guarantees that the configuration schema, default values, and reactive watchers are declared and available to the host and client settingsScope without timing issues.
11
- * **Safe Service Resolution**: Service lookups utilize defensive proxy resolution `(ctx?.get && ctx.get('credentials')) || ctx?.credentials` to prevent `undefined` properties on Cordis proxies.
12
- * **Credential Isolation**: The plugin NEVER stores plain API keys in its configuration. The setting `apiKeyEnv` holds the credential identifier (default: `CLINEBOT_API_KEY`), resolved via `ctx.get('credentials').resolve()` or `process.env`.
13
- * **State Synchronization & Auto-Registration**: Mutates the core `llm-pi-ai` settings space (`op: 'set', path: ['providers', 'clinebot']`) declaratively and automatically when enabled or key is saved.
14
- * **Auto-Discovery & `disabledModels`**: Features automatic background polling of subscription plan models (`GET /api/v1/users/me/plan`). User preferences are tracked via `disabledModels: []`, ensuring newly added plan models appear enabled by default in the DSH chat picker without manual re-synchronization.
15
-
16
- ### 2.2 Client Runtime (`lib/client.js`)
17
- * Self-registering module via `window.__ModuleLoader__.load({ id: '@goodandready/dsh-clinebot', factory })`.
18
- * Injects `['slots', 'locale', 'settingsScope']`.
19
- * Slots strictly and exclusively into `settings.plugin.item` (`key: NS`, `locale: NS`). Standalone top-level `settings.section` registration is omitted to maintain clean primary navigation in DSH and prevent side-list pollution.
20
- * Uses `refreshMirrorUntilVisible(ctx)` to invalidate and re-read the client settings mirror until the namespace is reported ready by the host.
21
- * Registers localized `en` and `ru` dictionaries with duplicate-safe guards (`ctx.locale.register()`).
22
- * Reactive binding via `((ctx?.get && ctx.get('lanSettings')) || ctx?.settingsScope).bind({ namespace: NS })` with `useSyncExternalStore` guarding against `unavailable` / `loading` snapshot states. Form mutations write directly to `scope.set()`.
23
- * Uses native design tokens (`--dsw-alias-...`) with full dark/light theme support.
24
- * Injects isolated style tag tagged with `data-dsh-plugin="dsh-clinebot"`.
25
-
26
- ```mermaid
27
- graph LR
28
- subgraph Client [DSH Web Interface]
29
- UI[Settings Card: ClineBot]
30
- SmokeBtn[Smoke Test Button]
31
- RegBtn[Register in DSH Models]
32
- end
33
-
34
- subgraph Host [DSH Node.js Runtime]
35
- API["HTTP API: /api/plugins/dsh-clinebot/*"]
36
- ClientHelper["lib/cline-client.js"]
37
- Catalog["lib/models.js (Static 11 Models)"]
38
- CredService[DSH Credentials Service]
39
- PiAiSettings["DSH Settings: llm-pi-ai"]
40
- end
41
-
42
- subgraph Remote [Cline Service]
43
- ClineAPI["api.cline.bot/api/v1"]
44
- end
45
-
46
- UI -->|GET /status| API
47
- SmokeBtn -->|POST /smoke| API
48
- RegBtn -->|POST /register| API
49
- API --> CredService
50
- API --> ClientHelper
51
- ClientHelper --> Catalog
52
- API -->|Mutate| PiAiSettings
53
- ClientHelper -->|POST /chat/completions| ClineAPI
54
- ```
55
-
56
- ## 3. UI/UX Contract
57
- * **Badges**:
58
- * Host connectivity: `Host online (<ms>)` (green) / `Host unreachable` (red).
59
- * Credential presence: `Key ✓ (credentials|env)` (green) / `Key missing` (amber).
60
- * Registration status: `DSH Registered` (green) / `Not Registered` (amber).
61
- * **Model Picker**: Interactive checklist of all 11 official models with multi-select and vision capability indicators.
62
- * **Non-destructive actions**: Unregister cleanly removes the provider entry from DSH without touching other providers or configurations.
63
-
64
- ## 4. Security & Isolation
65
- * CSRF / Cross-site protection: All mutating routes (`/register`, `/unregister`, `/smoke`, `/models`, `/accounts/active`, `/auth/begin`) validate `isTrustedSettingsRequest(req)` (`Sec-Fetch-Site !== 'cross-site'`).
66
- * Body size limits: Request payloads are strictly capped at 256 KB.
67
- * Sensitive credential data is never returned across the HTTP API (only `{ present: boolean, source: string, envName: string }`).
68
-
69
- ## 5. Multi-Account Pool & Resilient Execution (v0.3.3)
70
- * **Account Pool**: The plugin supports multiple accounts (`accounts: [{ label, apiKeyEnv }]`, `activeAccount`). `resolveActiveAccountKey()` automatically selects the configured active account or falls back to primary `apiKeyEnv`. Account switching (`POST /dsh-clinebot/accounts/active` and `/cline switch <label>`) triggers instant re-registration in `llm-pi-ai` without service restart.
71
- * **Resilient Retry Policy**: HTTP calls to ClinePass utilize `retryWithBackoff()` with exponential delays and jitter to automatically absorb transient 429 rate-limiting events and upstream 5xx errors.
72
- * **Reasoning Effort Support**: Models declaring `reasoningEfforts: ['low', 'medium', 'high', 'max']` expose native thinking controls within the DSH model picker, accompanied by UI badges (`🧠 Reasoning`).
73
- * **Offline Cold-Start Cache**: Discovered plan models are serialized locally to `modelsCachePath` (`~/.dsh/clinebot-models-cache.json`), ensuring models remain immediately available on cold boot even if the upstream network or Cline API is temporarily unavailable.
74
-
75
-
76
- ## 6. Performance, Resilience & Telemetry (v0.3.8)
77
- * **Stale-While-Revalidate (SWR) Network Probing**: `probeHealth()` utilizes an in-memory SWR cache (`probeCache`) with 25s TTL. Repeated `/status` queries return instantaneously (<1ms latency) with fresh host availability, asynchronously refreshing network latency in the background without blocking the client UI thread.
78
- * **HTTP Keep-Alive Connection Reuse**: Outbound fetch calls to `api.cline.bot` enforce persistent connection keepalive (`keepalive: true`), eliminating recurrent TLS handshake and TCP connection establishment latency.
79
- * **Auto-Failover Account Rotation**: When an active account encounters HTTP 429 (Rate Limit) or 100% quota depletion, `rotateToNextAccount()` automatically selects the next configured account in the pool, applies the update to DSH settings, and re-synchronizes credentials in `llm-pi-ai` in real time.
80
- * **Accurate Token Telemetry**: Real usage metadata (`prompt_tokens`, `completion_tokens`, `total_tokens`) is parsed directly from chat completion responses and tracked in session telemetry (`sessionStats`).
81
- * **Expanded Slash Commands**: Slash command `/cline` supports `/cline test [model]` (smoke test with latency, response and token metrics), `/cline ping` (real-time host connectivity test), and `/cline rotate` (round-robin active account rotation).
82
- * **Debounced Model Selection**: Model exclusion checkboxes in `lib/client.js` utilize immediate optimistic UI rendering paired with a 280ms debounced persistence layer, ensuring smooth interaction without request thrashing.