clauderipple 0.8.10 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +60 -0
- package/README.es.md +21 -15
- package/README.ja.md +13 -9
- package/README.ko.md +23 -9
- package/README.md +26 -11
- package/README.pt-BR.md +21 -15
- package/README.zh-CN.md +13 -9
- package/dist/app/package.json +1 -1
- package/dist/cli/src/codex.js +3 -1
- package/dist/cli/src/settings.js +5 -2
- package/dist/mod/.claude-plugin/plugin.json +9 -1
- package/dist/mod/hooks/cache.ts +60 -0
- package/dist/mod/hooks/compact.ts +40 -0
- package/dist/mod/hooks/handoff.ts +43 -0
- package/dist/mod/hooks/i18n.ts +2716 -0
- package/dist/mod/hooks/judge.ts +242 -0
- package/dist/mod/hooks/ladder.js +179 -0
- package/dist/mod/hooks/ladder.ts +174 -0
- package/dist/mod/hooks/modes.ts +93 -0
- package/dist/mod/hooks/register.tsx +1458 -256
- package/dist/mod/hooks/session.ts +62 -0
- package/dist/mod/hooks/settings.js +342 -0
- package/dist/mod/hooks/settings.ts +321 -0
- package/dist/mod/hooks/stats.ts +59 -0
- package/dist/mod/hooks/ui/agents.tsx +138 -0
- package/dist/mod/hooks/ui/alerts.tsx +373 -0
- package/dist/mod/hooks/ui/art.ts +628 -0
- package/dist/mod/hooks/ui/band.tsx +836 -0
- package/dist/mod/hooks/ui/kit.tsx +258 -0
- package/dist/mod/hooks/ui/log.tsx +109 -0
- package/dist/mod/hooks/ui/parts.tsx +217 -0
- package/dist/mod/hooks/ui/ripple.ts +614 -0
- package/dist/mod/hooks/ui/settings.tsx +376 -0
- package/dist/mod/hooks/ui/setup.tsx +148 -0
- package/dist/mod/hooks/ui/theme.ts +217 -0
- package/dist/mod/hooks/ui/view.ts +371 -0
- package/dist/mod/hooks/worker.ts +1 -1
- package/dist/mod/hooks/workers.ts +217 -0
- package/dist/mod/tests/register.test.tsx +1730 -0
- package/dist/mod/tests/ui.test.tsx +853 -0
- package/dist/mod/tsconfig.json +2 -1
- package/dist/mod/types/index.d.ts +320 -1
- package/dist/router/src/admin.js +170 -52
- package/dist/router/src/agents.js +24 -5
- package/dist/router/src/bootstrap.js +4 -2
- package/dist/router/src/config.js +3 -0
- package/dist/router/src/health.js +33 -0
- package/dist/router/src/index.js +1 -0
- package/dist/router/src/ingress/models.js +4 -1
- package/dist/router/src/mod-settings.js +120 -0
- package/dist/router/src/model-policy.js +6 -0
- package/dist/router/src/model-scores.js +159 -0
- package/dist/router/src/picker.js +7 -0
- package/dist/router/src/providers/chatgpt/index.js +23 -5
- package/dist/router/src/providers/chatgpt/translate.js +4 -1
- package/dist/router/src/providers/google/index.js +8 -3
- package/dist/router/src/providers/openai/index.js +6 -1
- package/dist/router/src/providers/openai/translate.js +6 -1
- package/dist/router/src/proxy.js +62 -24
- package/dist/router/src/requestlog.js +78 -20
- package/dist/router/src/version.js +1 -1
- package/dist/ui/app.js +908 -209
- package/dist/ui/favicon-32.png +0 -0
- package/dist/ui/favicon.svg +12 -0
- package/dist/ui/i18n.js +919 -233
- package/dist/ui/index.html +159 -87
- package/dist/ui/style.css +789 -410
- package/docs/ARCHITECTURE.md +141 -0
- package/package.json +7 -3
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -196,6 +196,15 @@ request went, and a `Pane` holds the request log.
|
|
|
196
196
|
browser) are the app's own; the mod API (CLI 2.1.286 types) has no place for
|
|
197
197
|
a plugin's button there. Its sites are the band, the status line, panes,
|
|
198
198
|
transcript rows and slash commands.
|
|
199
|
+
- **Pictures on the desktop are images, never frames.** The desktop app draws
|
|
200
|
+
each answer as a new DOM tree; an `Svg` becomes a new `<img>` of a data URL,
|
|
201
|
+
or with `isInteractive` a sandboxed `<iframe srcdoc>` that paints blank until
|
|
202
|
+
loaded. Only the frame blinks on a redraw: a plain `Svg` image does not, and
|
|
203
|
+
CSS `@keyframes` inside the SVG run in it (seen by the owner in the desktop
|
|
204
|
+
app on 2026-10-11 at commit 8d43b97, 리플이 moving in the band and the quick
|
|
205
|
+
settings with no flicker; Effortless animates its band the same way). A
|
|
206
|
+
redraw still starts the motion over, so the mod's loops all open on a rest
|
|
207
|
+
pose (`packages/mod/hooks/ui/ripple.ts`).
|
|
199
208
|
- **A pane's open state is the engine's.** A module reload drops its pane
|
|
200
209
|
without a `ui.close` the module hears, while `$.state` survives the reload: a
|
|
201
210
|
flag kept there stuck the Log button on "Close log" (2026-10-05). The mod asks
|
|
@@ -205,9 +214,128 @@ request went, and a `Pane` holds the request log.
|
|
|
205
214
|
path list other plugins may share, so only the entry whose manifest is named
|
|
206
215
|
`clauderipple-status` is added or removed (`clauderipple mod on|off`, the
|
|
207
216
|
Clients screen switch).
|
|
217
|
+
- **Developing it, sessions load a copy at the last commit.** With
|
|
218
|
+
`CLAUDE_CODE_PLUGIN_DIR_WATCH=1` a session reloads a plugin folder whenever
|
|
219
|
+
it changes, and each reload leaves "ripple reloaded (N hooks: …)" in every
|
|
220
|
+
open transcript: pointed at the checkout, one session editing the mod
|
|
221
|
+
flooded all the others (2026-10-13). On this machine the entry is
|
|
222
|
+
`~/.clauderipple/mod`, which `scripts/sync-mod.mts` keeps at main's
|
|
223
|
+
`packages/mod` from the post-commit, post-merge and post-rewrite hooks
|
|
224
|
+
(`--install` writes them), writing only files that differ. Uncommitted work
|
|
225
|
+
never reaches everyday sessions; `clauderipple mod on` would point the entry
|
|
226
|
+
back at the checkout.
|
|
227
|
+
|
|
228
|
+
### 3b. Shared mod settings and judge-only models (2026-10-10)
|
|
229
|
+
|
|
230
|
+
The router is the single source of the mod's settings, persisted in
|
|
231
|
+
`<homeDir()>/mod-settings.json`. `GET /api/mod-settings` returns
|
|
232
|
+
`{settings:<full normalized Settings>, revision, stored:boolean}`. Before the first
|
|
233
|
+
write it returns normalized defaults, revision 0 and `stored:false`, without creating
|
|
234
|
+
storage. `PUT` accepts `{settings, revision?}`, normalizes with the mod's own pure
|
|
235
|
+
`hooks/settings.ts:normalizeSettings` (type-only imports, no `claude-code` runtime),
|
|
236
|
+
increments the revision under the account stores' `withFileLock` and `writeJsonAtomic`
|
|
237
|
+
helpers (0600), and returns `{settings, revision, stored:true}`. A stale supplied
|
|
238
|
+
revision returns 409 with the same full current snapshot, including `stored`.
|
|
239
|
+
Existing stored settings are normalized on reads as well; unknown fields are dropped.
|
|
240
|
+
Before normalization, the router refuses nonobjects, settings over 64 KiB of UTF-8
|
|
241
|
+
JSON (413), and credential field names at any depth, including inside arrays (400).
|
|
242
|
+
The final word of a field name decides (`apiKey`, `access_token`, `clientSecret`,
|
|
243
|
+
`password`, etc.); `keepWarmMinTokens` is a count, not a credential, and is accepted.
|
|
244
|
+
Corrupt storage is an error, never an empty store to overwrite.
|
|
245
|
+
|
|
246
|
+
The mod reads this endpoint at `session.start` and every 3-second router poll, even
|
|
247
|
+
when its band is hidden. A changed revision replaces the settings atom and redraws
|
|
248
|
+
readers. Only when `stored:false` does it read legacy plugin-store `settings` and
|
|
249
|
+
`setupDone` and migrate them with a revision-checked PUT; a racing first writer wins
|
|
250
|
+
instead of being overwritten. Afterwards settings are never read from or saved to the
|
|
251
|
+
plugin store; unrelated keys such as picks, band visibility and handoff choices remain.
|
|
252
|
+
Panel/setup saves PUT the last seen revision. On 409 the mod takes the server copy,
|
|
253
|
+
reapplies only the user's changed paths (including sibling rule/provider fields), and
|
|
254
|
+
retries once. A panel keeps its opening baseline so a poll while it is open cannot
|
|
255
|
+
turn an unrelated remote edit into a local overwrite. Offline changes remain active
|
|
256
|
+
locally with the existing router-not-answering notice and retry on the next poll,
|
|
257
|
+
rebased over that poll's server copy. Revision, pending edits and migration state live
|
|
258
|
+
in session atoms and survive module hot reloads; settings HTTP work is serialized.
|
|
259
|
+
Language resolution and the separate Jev key file are unchanged. Verified with
|
|
260
|
+
`test/admin.test.ts`, `test/mod/settings.test.ts` and the mod's 2.1.293 engine tests.
|
|
261
|
+
|
|
262
|
+
`GET /api/mod-options` returns `agents` (owned manifest entries with existing agent
|
|
263
|
+
files), all configured `models` (`model`, `provider`, `name`, `judgeOnly`), `providers`
|
|
264
|
+
(`name`, `type`, `usable`), `zen:{configured,model}`, and `scores`. ChatGPT usability
|
|
265
|
+
shares `/api/status`'s quota refresh and account states, including purchased credits;
|
|
266
|
+
AA scores reuse `model-scores.ts` and retain its attribution. No provider key is exposed.
|
|
267
|
+
Since 2026-10-11 (the worker ladder, docs/specs/2026-10-11-worker-ladder.md) each agent also
|
|
268
|
+
carries `efforts` (its model's ladder from `effortLevels`, mod efforts only) and `billing`
|
|
269
|
+
(`free | payg | subscription`, `hooks/ladder.ts:billingOf`: ChatGPT, Claude login, Antigravity
|
|
270
|
+
and the OpenCode Go preset are subscriptions, Ollama/LM Studio, a hand-entered local URL and
|
|
271
|
+
`:free`/`-free` models are free, every other preset or API is pay-per-token); providers carry
|
|
272
|
+
`billing`; `claudeEfforts` is Anthropic's ladder; `presets` are the four ladder presets computed
|
|
273
|
+
by the mod's own `hooks/ladder.ts` from the usable workers plus Claude's models, so the dashboard
|
|
274
|
+
and the session's quick settings fill rungs alike.
|
|
275
|
+
|
|
276
|
+
The worker ladder replaced Pin as the default rule mode (`{mode:'ladder', rungs:{light, standard,
|
|
277
|
+
hard, plan}}`, each rung `{target, effort, backup?}`). The judge adds `kind: plan|do`; level picks
|
|
278
|
+
Light/Standard/Hard, a plan at standard or deep goes to Plan, and `sure < 0.5` moves Light→Standard
|
|
279
|
+
→Hard (Plan does not move). An unavailable rung tries its backup, then one rung up (its model, then
|
|
280
|
+
its backup), then the session model (`general-purpose` with no model; refused only when Anthropic is
|
|
281
|
+
switched off), never down. Stored pins normalize to ladders on every read (missing levels climb,
|
|
282
|
+
efforts start at the default ladder's for the same model or low/medium/high, calibrated as the pin
|
|
283
|
+
was; Plan is Hard's model one effort up); Auto stays Auto, shown as experimental. `fallback` and
|
|
284
|
+
`preference` are kept; only Auto still reads `preference`. Every pick writes one
|
|
285
|
+
`ClaudeRipple worker pick:` debug line. Tests: `test/mod/ladder.test.ts`, `test/admin.test.ts`.
|
|
286
|
+
|
|
287
|
+
`model-policy.ts:isJudgeOnlyModel` is the single judge-only rule: ids beginning with
|
|
288
|
+
`jev` are not chat models (the OpenCode Zen note in `presets.ts`: `/systemone` only).
|
|
289
|
+
Desktop/CLI picker injection (including aliases/routes targeting Jev), derived worker
|
|
290
|
+
aliases, generated agents, AA auto-worker score candidates, OpenAI model lists and
|
|
291
|
+
Codex catalogs exclude them; the next enabled agent sync removes previously
|
|
292
|
+
owned Jev files, never hand-written ones. Provider configuration and mod options keep
|
|
293
|
+
them available as judge candidates. Tests: `test/admin.test.ts`, `test/model-policy.test.ts`.
|
|
208
294
|
|
|
209
295
|
## 4. Provider adapters
|
|
210
296
|
|
|
297
|
+
### Artificial Analysis model scores (2026-10-10)
|
|
298
|
+
|
|
299
|
+
`scripts/aa-dataset.mjs` builds `aa-models.json` on the orphan GitHub `data` branch;
|
|
300
|
+
`.github/workflows/aa-data.yml` checks daily at 03:37 UTC, replacing its single commit
|
|
301
|
+
only for substantive changes or after a week. Source: [AA API v2](https://artificialanalysis.ai/api/v2/data/llms/models)
|
|
302
|
+
(`x-api-key`, free limit 1,000 requests/day; `AA_API_KEY` stays in the environment).
|
|
303
|
+
The API supplies slug/name/creator/release date, `evaluations.artificial_analysis_intelligence_index`
|
|
304
|
+
and input/output USD-per-million prices, **not** cost per task. The model page's Next.js
|
|
305
|
+
flight record supplies `intelligenceIndex`, `intelligenceIndexIsEstimated` and
|
|
306
|
+
`intelligenceIndexCostPerTask.cost.total` (USD, already including input/cache/output);
|
|
307
|
+
`intelligenceIndexCost.total` is a different, whole-benchmark total and is never used.
|
|
308
|
+
Measured [GPT-6.1 Sol High](https://artificialanalysis.ai/models/gpt-6-1-sol-high):
|
|
309
|
+
index **50.2378** (≈50.24), **$0.319144 per task** (≈$0.3191), not estimated.
|
|
310
|
+
|
|
311
|
+
Track families with at least one measured release in the last **365 days**, including
|
|
312
|
+
all their older/unmeasured variants. Group by creator and model name with reasoning
|
|
313
|
+
parentheses removed; retain unrelated Preview/Beta/date labels. Strip only recognized
|
|
314
|
+
reasoning endings from slugs. Effort uses the page suffix/name parentheses, then slug:
|
|
315
|
+
`max/xhigh/high/medium/low/minimal/non-reasoning`; Non-reasoning takes precedence over
|
|
316
|
+
an accompanying High/Low label. Generic Reasoning or the unsuffixed default maps to
|
|
317
|
+
max in a multi-variant family; a single-variant model has null effort. Successful
|
|
318
|
+
`checkedAt` values under **7 days** are reused; failed pages retain prior values/time
|
|
319
|
+
(or null cost/time), and embedded defaults are harvested opportunistically by exact
|
|
320
|
+
slug. Page requests are sequential, ≥1.5 seconds apart with one backed-off 429/5xx
|
|
321
|
+
retry. Fewer than half of attempted pages parsing their requested slug aborts publication.
|
|
322
|
+
The extraction marker `canonicalIntelligenceIndexTokenCount` is a private page-format
|
|
323
|
+
anchor, not an output metric: no token counts are stored. `--limit N` caps page fetches
|
|
324
|
+
for a local smoke run; use `--output <path>` and never publish capped output.
|
|
325
|
+
|
|
326
|
+
Auto routing and field rules were removed 2026-10-12 (along with `GET /api/model-scores`);
|
|
327
|
+
routing is the four workers (docs/specs/2026-10-12-worker-tiers.md). `model-scores.ts`
|
|
328
|
+
remains as the admin's internal catalog for the mod's options, with normalized
|
|
329
|
+
AA bases (decimal dots → hyphens, provider namespace/Claude snapshot date removed),
|
|
330
|
+
variant intelligence/cost, attribution and generation time. The picker's five effort
|
|
331
|
+
names are preserved; AA minimal/non-reasoning and single variants return null rather
|
|
332
|
+
than being mislabeled low. Unknown models remain present with `matched:false`.
|
|
333
|
+
Scores are metadata, never routing policy or the user's subscription bill. The public
|
|
334
|
+
raw JSON is fetched with a 5-second timeout, kept 24 hours in memory and
|
|
335
|
+
`<homeDir()>/aa-models.json` (mtime records retrieval), shared by concurrent lookups;
|
|
336
|
+
on failure the last cache is kept and retried after one hour. Displays/republication
|
|
337
|
+
must preserve **Data: Artificial Analysis (artificialanalysis.ai)** attribution.
|
|
338
|
+
|
|
211
339
|
- **The Claude model list is Anthropic's own (2026-10-08).** The native `anthropic`
|
|
212
340
|
provider's models came from a constant in admin.ts, so each release after it was cut
|
|
213
341
|
was missing from the provider form, the mapping table and the declared list until a
|
|
@@ -631,6 +759,19 @@ request went, and a `Pane` holds the request log.
|
|
|
631
759
|
|
|
632
760
|
### 4a. Claude Code request shapes a translator must handle (measured 2026-09-13, CLI 2.1.266)
|
|
633
761
|
|
|
762
|
+
**Request-log metadata (`requests.jsonl`, 2026-10-14).** These fields are optional;
|
|
763
|
+
old records and `RequestLog.summary()` remain compatible. No prompt, auth or reasoning
|
|
764
|
+
text is added. Source: `requestlog.ts`, `proxy.ts`, provider adapter outcomes.
|
|
765
|
+
|
|
766
|
+
- `usage.cacheWrite`: native/Anthropic numeric cache creation tokens, including explicit 0; absent/non-number is omitted, as is a translated adapter's synthetic 0.
|
|
767
|
+
- `upstreamRequestId`: the final forwarded native Anthropic response's `request-id` header (passthrough or account pool).
|
|
768
|
+
- `messageId`: the Anthropic message id delivered by a translated adapter or forwarded compatible response; not a generated id from a non-streaming error.
|
|
769
|
+
- `upstreamCalled`: `false` only for a known pre-model-API exit; omitted when a search backend was attempted or the call state is unknown.
|
|
770
|
+
- `refusal`: `thread-continue`, `drain`, `unroutable`, `no-account`, `unknown-provider` or `web-search-unsupported`, from the actual exit branch.
|
|
771
|
+
- `purpose`: `auto-mode-classifier` from the security-monitor request shape regardless of routing settings, or `web-search` for router-served searches.
|
|
772
|
+
- `requestedTier`: the service tier actually sent upstream, including ChatGPT's `speed: "fast"` → `priority`; omitted when no tier was sent.
|
|
773
|
+
- `servedTier`: the response-reported tier (Responses/Chat `service_tier` or Anthropic `usage.service_tier`); never inferred from the request.
|
|
774
|
+
|
|
634
775
|
- **Server-side threads ("tether").** The first request of a session carries
|
|
635
776
|
`thread: {type:"create"}` and the full history; later turns carry
|
|
636
777
|
`thread: {type:"continue", previous_message_id: <our last assistant msg id>}` and
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clauderipple",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Use GPT (any ChatGPT plan with Codex), DeepSeek and 400+ other models in the Claude Desktop Code tab and Claude Code while staying signed in to your Claude subscription — no third-party gateway mode. Several ChatGPT accounts that take over when one runs out, in Codex too.",
|
|
5
5
|
"license": "GPL-3.0-only",
|
|
6
6
|
"workspaces": [
|
|
@@ -10,11 +10,15 @@
|
|
|
10
10
|
"node": ">=24"
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
|
-
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
13
|
+
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p packages/remote/tsconfig.web.json --noEmit && tsc -p packages/remote/relay/tsconfig.json --noEmit",
|
|
14
14
|
"dist": "npm --workspace @clauderipple/app run dist",
|
|
15
15
|
"release": "npm --workspace @clauderipple/app run release",
|
|
16
16
|
"router": "node packages/router/src/index.ts",
|
|
17
|
-
"
|
|
17
|
+
"remote": "node --disable-warning=ExperimentalWarning packages/remote/src/main.ts",
|
|
18
|
+
"relay:build": "node --disable-warning=ExperimentalWarning packages/remote/relay/build-web.ts",
|
|
19
|
+
"relay:dev": "npm run relay:build && wrangler dev -c packages/remote/relay/wrangler.toml --ip 127.0.0.1 --port 8798",
|
|
20
|
+
"relay:deploy": "npm run relay:build && wrangler deploy -c packages/remote/relay/wrangler.toml",
|
|
21
|
+
"test": "node --test packages/router/test/*.test.ts packages/cli/test/*.test.ts test/mod/*.test.ts packages/remote/test/*.test.ts",
|
|
18
22
|
"cli": "node packages/cli/src/index.ts",
|
|
19
23
|
"prepack": "node scripts/build-npm.mjs",
|
|
20
24
|
"build": "node scripts/build-npm.mjs"
|