@rynfar/meridian 1.71.1 → 1.72.0
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/README.md +115 -162
- package/assets/desktop-dashboard.jpg +0 -0
- package/assets/trayTemplate.png +0 -0
- package/assets/trayTemplate@2x.png +0 -0
- package/assets/trayTemplate@3x.png +0 -0
- package/dist/{cli-ryt69ryf.js → cli-ab7zkp1a.js} +164 -49
- package/dist/cli.js +2 -2
- package/dist/{pluginPage-n3gdtbmj.js → pluginPage-f5gdmbxc.js} +1 -1
- package/dist/{profilePage-vfj2dbhn.js → profilePage-mamej7kp.js} +1 -1
- package/dist/proxy/errors.d.ts.map +1 -1
- package/dist/proxy/server.d.ts.map +1 -1
- package/dist/proxy/session/processIncarnation.d.ts +7 -0
- package/dist/proxy/session/processIncarnation.d.ts.map +1 -1
- package/dist/proxy/sessionLifecycle.d.ts +8 -1
- package/dist/proxy/sessionLifecycle.d.ts.map +1 -1
- package/dist/proxy/sessionStore.d.ts.map +1 -1
- package/dist/server.js +2 -2
- package/dist/telemetry/profileBar.d.ts +8 -0
- package/dist/telemetry/profileBar.d.ts.map +1 -1
- package/package.json +2 -1
- /package/dist/{cli-8yp89fan.js → cli-hj61zpt7.js} +0 -0
package/README.md
CHANGED
|
@@ -1,197 +1,150 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="assets/banner.svg" alt="Meridian" width="800"/>
|
|
2
|
+
<img src="assets/banner.svg" alt="Meridian — Harness Claude, your way." width="800" />
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
6
|
-
<
|
|
7
|
-
<a href="https://www.npmjs.com/package/@rynfar/meridian"><img src="https://img.shields.io/npm/v/@rynfar/meridian?style=flat-square&color=bc8cff&label=npm" alt="npm"></a>
|
|
8
|
-
<a href="#"><img src="https://img.shields.io/badge/platform-macOS%20%7C%20Linux%20%7C%20Windows-58a6ff?style=flat-square" alt="Platform"></a>
|
|
9
|
-
<a href="#"><img src="https://img.shields.io/badge/license-MIT-bc8cff?style=flat-square" alt="License"></a>
|
|
10
|
-
<a href="https://discord.gg/jP2a2Z92NZ"><img src="https://img.shields.io/badge/discord-join-5865F2?style=flat-square&logo=discord&logoColor=white" alt="Discord"></a>
|
|
6
|
+
<strong>Your tools. Your sessions. One place to see what’s happening.</strong>
|
|
11
7
|
</p>
|
|
12
8
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
>
|
|
18
|
-
>
|
|
19
|
-
>
|
|
20
|
-
> Meridian is built entirely on the [Claude Agent SDK](https://code.claude.com/docs/en/agent-sdk). Every request flows through `query()` — the same documented function Anthropic provides for programmatic access. No OAuth tokens are extracted, no binaries are patched, nothing is reverse-engineered.
|
|
21
|
-
>
|
|
22
|
-
> Because we use the SDK, Anthropic remains in full control of prompt caching, context window management, compaction, rate limiting, and authentication. Meridian doesn't bypass these mechanisms — it depends on them. Max subscription tokens flow through the correct channel, governed by the same guardrails Anthropic built into Claude Code.
|
|
23
|
-
>
|
|
24
|
-
> What Meridian adds is a **presentation and interoperability layer**. We translate Claude Code's output into the standard Anthropic API format so developers can connect the editors, terminals, and workflows they prefer. The SDK does the work; Meridian formats the result.
|
|
25
|
-
>
|
|
26
|
-
> **Our philosophy is simple: work within the SDK's constraints, not around them.** The generous limits on Claude Max exist because Anthropic can optimize and manage usage through Claude Code. Meridian respects that by building only on the tools Anthropic provides — no shortcuts, no workarounds that create friction. We believe this is how developers keep the freedom to choose their own frontends while keeping the platform sustainable for everyone.
|
|
27
|
-
|
|
28
|
-
## Quick Start
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
# 1. Install
|
|
32
|
-
npm install -g @rynfar/meridian
|
|
33
|
-
|
|
34
|
-
# 2. Authenticate (one time)
|
|
35
|
-
claude login
|
|
36
|
-
|
|
37
|
-
# 3. Configure OpenCode plugin (one time — OpenCode users only)
|
|
38
|
-
meridian setup # OpenCode V1
|
|
39
|
-
# meridian setup --v2 --opencode-bin ~/.local/bin/opencode2 # pinned V2 beta
|
|
40
|
-
|
|
41
|
-
# 4. Start
|
|
42
|
-
meridian
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
Meridian runs on `http://127.0.0.1:3456`. Point any Anthropic-compatible tool at it:
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
ANTHROPIC_API_KEY=x ANTHROPIC_BASE_URL=http://127.0.0.1:3456 opencode
|
|
49
|
-
```
|
|
9
|
+
<p align="center">
|
|
10
|
+
<a href="https://github.com/rynfar/meridian/releases">Releases</a> ·
|
|
11
|
+
<a href="#get-started">Get started</a> ·
|
|
12
|
+
<a href="docs/agents.md">Connect your agent</a> ·
|
|
13
|
+
<a href="https://discord.gg/jP2a2Z92NZ">Discord</a>
|
|
14
|
+
</p>
|
|
50
15
|
|
|
51
|
-
|
|
16
|
+
<p align="center">
|
|
17
|
+
<a href="https://www.npmjs.com/package/@rynfar/meridian"><img src="https://img.shields.io/npm/v/@rynfar/meridian?style=flat-square&color=58a6ff" alt="npm version" /></a>
|
|
18
|
+
<img src="https://img.shields.io/badge/desktop-macOS_preview-bc8cff?style=flat-square" alt="Desktop: macOS preview" />
|
|
19
|
+
<img src="https://img.shields.io/badge/headless-macOS_·_Linux_·_Windows-58a6ff?style=flat-square" alt="Headless: macOS, Linux and Windows" />
|
|
20
|
+
<a href="https://opensource.org/license/mit"><img src="https://img.shields.io/badge/license-MIT-bc8cff?style=flat-square" alt="MIT license" /></a>
|
|
21
|
+
</p>
|
|
52
22
|
|
|
53
|
-
|
|
23
|
+
Meridian connects Anthropic- and OpenAI-compatible clients to Claude through the
|
|
24
|
+
Claude Agent SDK. Keep the editor or terminal you like, with streaming, persistent
|
|
25
|
+
sessions, account routing and visibility into usage and prompt caching.
|
|
54
26
|
|
|
55
|
-
|
|
27
|
+
**Now with an optional Mac app.** Manage Meridian versions, install plugins, find
|
|
28
|
+
failed requests and see your usage limits without keeping a terminal open.
|
|
29
|
+
Headless Meridian remains fully supported—npm, Docker, Nix and your existing
|
|
30
|
+
service manager all remain valid ways to run it.
|
|
56
31
|
|
|
57
|
-
|
|
32
|
+
## Meet Meridian Desktop
|
|
58
33
|
|
|
59
34
|
<p align="center">
|
|
60
|
-
<img src="assets/
|
|
35
|
+
<img src="assets/desktop-dashboard.jpg" alt="Meridian Desktop overview showing usage limits, cache activity and recent requests. Sample data." width="1000" />
|
|
61
36
|
</p>
|
|
62
37
|
|
|
63
|
-
|
|
38
|
+
<p align="center"><sub>macOS dashboard preview · Sample data</sub></p>
|
|
64
39
|
|
|
65
|
-
|
|
|
66
|
-
|
|
67
|
-
|
|
|
68
|
-
|
|
|
69
|
-
|
|
|
70
|
-
| [Deployment](docs/deployment.md) | NixOS / Nix flake, Home Manager service, Docker |
|
|
71
|
-
| [Plugins](docs/plugins.md) | Plugin system and the official scrub plugins |
|
|
72
|
-
| [Development](docs/development.md) | Architecture overview, testing, programmatic API |
|
|
73
|
-
| [`MONITORING.md`](MONITORING.md) | Telemetry, token usage, and prompt cache health |
|
|
74
|
-
| [`ARCHITECTURE.md`](ARCHITECTURE.md) | Module map and dependency rules |
|
|
75
|
-
|
|
76
|
-
## Features
|
|
77
|
-
|
|
78
|
-
- **Standard Anthropic API** — drop-in compatible with any tool that supports a custom `base_url`
|
|
79
|
-
- **OpenAI-compatible API** — `/v1/chat/completions` and `/v1/models` for tools that only speak the OpenAI protocol (Open WebUI, Continue, etc.) — no LiteLLM needed, including `image_url` support for data URLs
|
|
80
|
-
- **Session management** — conversations persist across requests, survive compaction and undo, resume after proxy restarts
|
|
81
|
-
- **Streaming** — full SSE streaming with MCP tool filtering
|
|
82
|
-
- **Concurrent sessions** — run parent and subagent requests in parallel
|
|
83
|
-
- **Subagent model selection** — primary agents get 1M context; subagents get 200k, preserving rate-limit budget
|
|
84
|
-
- **Auto token refresh** — expired OAuth tokens are refreshed automatically; requests continue without interruption
|
|
85
|
-
- **Passthrough mode** — forward tool calls to the client instead of executing internally
|
|
86
|
-
- **Multimodal** — images, documents, file attachments, and multimodal tool results pass through to Claude
|
|
87
|
-
- **Multi-profile** — switch between Claude accounts instantly, no restart needed; opt-in [sticky session routing](docs/profiles.md#sticky-session-routing) distributes sessions across accounts while keeping per-account prompt caches warm
|
|
88
|
-
- **Adapter instances** — run several configurations of the same adapter side by side (per-instance thinking, system prompt, passthrough) selected by header or match rules — see [Adapter instances](docs/agents.md#adapter-instances)
|
|
89
|
-
- **Telemetry dashboard** — real-time performance metrics at `/telemetry`, including token usage and prompt cache efficiency ([`MONITORING.md`](MONITORING.md))
|
|
90
|
-
- **Cost estimation** — estimated API-equivalent value of your traffic, per model and per profile, using current list prices with configurable overrides (`~/.config/meridian/model-pricing.json`, editable at `/settings`)
|
|
91
|
-
- **Envelope integrity auditing** — Meridian validates its own wire output on every response (no dangling blocks, no undelivered or empty tool calls) and surfaces violations on the dashboard
|
|
92
|
-
- **Telemetry persistence** — opt-in SQLite storage for telemetry data that survives proxy restarts, with configurable retention
|
|
93
|
-
- **Prometheus metrics** — `GET /metrics` endpoint for scraping request counters and duration histograms
|
|
94
|
-
- **SDK feature toggles** *(experimental)* — unlock Claude Code features (memory, dreaming, CLAUDE.md) for any connected agent
|
|
95
|
-
|
|
96
|
-
## Tested Agents
|
|
97
|
-
|
|
98
|
-
| Agent | Status | Notes |
|
|
99
|
-
|-------|--------|-------|
|
|
100
|
-
| [OpenCode](https://github.com/anomalyco/opencode) | ✅ Verified | V1 and pinned V2 beta support; requires the matching `meridian setup` mode ([setup](docs/agents.md#opencode)) — tools, durable resume, restart, undo, compaction, parallel subagents |
|
|
101
|
-
| [ForgeCode](https://forgecode.dev) | ✅ Verified | Provider config (see [Agent Setup](docs/agents.md)) — passthrough tool execution, session resume, streaming |
|
|
102
|
-
| [Droid (Factory AI)](https://factory.ai/product/ide) | ✅ Verified | BYOK config (see [Agent Setup](docs/agents.md)) — full tool support, session resume, streaming |
|
|
103
|
-
| [Crush](https://github.com/charmbracelet/crush) | ✅ Verified | Provider config (see [Agent Setup](docs/agents.md)) — full tool support, session resume, headless `crush run` |
|
|
104
|
-
| [Cline](https://github.com/cline/cline) | ✅ Verified | Config (see [Agent Setup](docs/agents.md)) — full tool support, file read/write/edit, bash, session resume |
|
|
105
|
-
| [Aider](https://github.com/paul-gauthier/aider) | ✅ Verified | Env vars — file editing, streaming; `--no-stream` broken (litellm bug) |
|
|
106
|
-
| [Open WebUI](https://github.com/open-webui/open-webui) | ✅ Verified | OpenAI-compatible endpoints — set base URL to `http://127.0.0.1:3456` |
|
|
107
|
-
| [Pi](https://github.com/mariozechner/pi-coding-agent) | ✅ Verified | models.json config (see [Agent Setup](docs/agents.md)) — full tool support via passthrough; detected via `x-meridian-agent: pi` header |
|
|
108
|
-
| [Prime Agent](https://www.npmjs.com/package/prime-agent) | ⚠️ Single-agent verified | Extension config (see [Agent Setup](docs/agents.md)) — reliable with one active agent. Concurrent RLM subagents receive distinct session keys, but are not yet production-safe; see [Prime Agent subagents](#prime-agent-subagents). The extension's `metadata.user_id` stamp is **required**, not optional. |
|
|
109
|
-
| [Claude Code](https://docs.anthropic.com/en/docs/claude-code) | ✅ Verified | `ANTHROPIC_BASE_URL` — remote clients share a Max subscription over the network; client CWD preserved in system prompt |
|
|
110
|
-
| [Cherry Studio](https://github.com/CherryHQ/cherry-studio) | ✅ Verified | `cherry` adapter (see [Agent Setup](docs/agents.md)) — chat client with Claude's built-in web search via internal mode |
|
|
111
|
-
| [Polytoken](https://polytoken.dev/) | ✅ Verified | Provider config (see [Agent Setup](docs/agents.md#Polytoken)) — `X-Polytoken-Session` identity, mandatory client-owned tools (passthrough cannot be disabled), signed-thinking passthrough |
|
|
112
|
-
| Jcode | ✅ Verified | `/v1/chat/completions` + `x-jcode-session` header — dedicated `jcode` adapter keeps append-only history intact, so retained sessions resume on one SDK session (90.9% cache hit on turn 2 of a two-turn Opus session) |
|
|
113
|
-
| [Codex CLI](https://github.com/openai/codex) | ✅ Verified | `/v1/responses` (see [Agent Setup](docs/agents.md)) — Responses-API provider, passthrough tool execution; verified on 0.144 (plain + tool-driving turns) |
|
|
114
|
-
| [Continue](https://github.com/continuedev/continue) | 🔲 Untested | OpenAI-compatible endpoints should work — set `apiBase` to `http://127.0.0.1:3456` |
|
|
115
|
-
|
|
116
|
-
### Prime Agent subagents
|
|
117
|
-
|
|
118
|
-
Prime Agent is reliable through Meridian with one active agent. RLM children have
|
|
119
|
-
separate session identities and can execute successfully, but concurrent subagent
|
|
120
|
-
orchestration is not yet production-safe. Observed failure modes include overload
|
|
121
|
-
amplification, expensive cache churn after fresh-session replay, loss of child-task
|
|
122
|
-
context during recovery, and undelivered tool envelopes. Use a single active Prime
|
|
123
|
-
Agent for unattended or usage-sensitive work until coordinated fixes land in Prime
|
|
124
|
-
Agent and Meridian.
|
|
125
|
-
|
|
126
|
-
Parent-to-child cancellation is handled on the Meridian side: when the extension
|
|
127
|
-
stamps `parent_session_id` alongside the child's session id, aborting a parent's
|
|
128
|
-
in-flight request aborts every live request in the subtree below it and evicts
|
|
129
|
-
each one's session mapping. See
|
|
130
|
-
[Subagent cancellation](docs/agents.md#prime-agent).
|
|
131
|
-
|
|
132
|
-
Prime Agent can keep Opus on the root session while selecting Sol for an individual
|
|
133
|
-
child. A child inherits its parent's model unless the `rlm` call supplies an exact
|
|
134
|
-
`provider/model` selector returned by `rlm.find_models()`:
|
|
135
|
-
|
|
136
|
-
```python
|
|
137
|
-
sol_models = await rlm.find_models("sol")
|
|
138
|
-
print(sol_models) # choose an available exact selector for your authenticated providers
|
|
139
|
-
|
|
140
|
-
child = await rlm(
|
|
141
|
-
"Review this change and report your findings to the parent.",
|
|
142
|
-
name="sol-reviewer",
|
|
143
|
-
model="openai-codex/gpt-5.6-sol",
|
|
144
|
-
)
|
|
145
|
-
```
|
|
40
|
+
| See what matters | Keep it under control |
|
|
41
|
+
| --- | --- |
|
|
42
|
+
| **Usage & limits** — account quota windows, reset times and token activity. | **Versions** — install published Meridian releases, switch versions and roll back. |
|
|
43
|
+
| **Requests & cache** — timing, failures, cache history and request details. | **Service** — start, stop, restart and recover an app-managed installation. |
|
|
44
|
+
| **Logs & alerts** — searchable diagnostics and opt-in failure, cache and quota notifications. | **Plugins** — install and update the Pi, OpenCode, Hermes and OpenClaw scrub plugins. |
|
|
146
45
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
46
|
+
Native macOS chrome, menu bar controls and Liquid Glass on supported Macs through
|
|
47
|
+
[electron-liquid-glass](https://github.com/Meridius-Labs/electron-liquid-glass).
|
|
48
|
+
The desktop preview targets **macOS on Apple Silicon**. Linux and Windows desktop
|
|
49
|
+
apps are planned; their runtime support is not ready yet.
|
|
151
50
|
|
|
152
|
-
|
|
51
|
+
## Get started
|
|
153
52
|
|
|
154
|
-
|
|
53
|
+
### With the Mac app
|
|
155
54
|
|
|
156
|
-
|
|
157
|
-
|
|
55
|
+
The first downloadable desktop release is being prepared. Until it is published,
|
|
56
|
+
use the [desktop preview instructions](apps/desktop/README.md#run-locally).
|
|
57
|
+
Signed, notarized `.dmg` and `.zip` downloads will appear under
|
|
58
|
+
[GitHub Releases](https://github.com/rynfar/meridian/releases).
|
|
158
59
|
|
|
159
|
-
|
|
160
|
-
|
|
60
|
+
1. Connect to an existing local Meridian service, or install Meridian from **Versions**.
|
|
61
|
+
2. For a new installation, choose app management in **Service** and start it.
|
|
62
|
+
3. Sign in to a Claude account, then follow your [agent’s setup guide](docs/agents.md).
|
|
161
63
|
|
|
162
|
-
|
|
163
|
-
|
|
64
|
+
The app can monitor Docker or Nix installations through a published local HTTP
|
|
65
|
+
port. Their package manager retains control of updates and lifecycle. Supported
|
|
66
|
+
macOS LaunchAgents can be handed to the app and returned to headless operation.
|
|
67
|
+
[How service ownership works →](apps/desktop/README.md#connect-to-an-existing-installation)
|
|
164
68
|
|
|
165
|
-
|
|
69
|
+
### Headless, as always
|
|
166
70
|
|
|
167
|
-
|
|
168
|
-
# CLI — works whether the proxy is running or not
|
|
169
|
-
meridian refresh-token
|
|
71
|
+
Requires Node.js 22 or newer and a Claude account configured for the SDK.
|
|
170
72
|
|
|
171
|
-
|
|
172
|
-
|
|
73
|
+
```sh
|
|
74
|
+
npm install -g @rynfar/meridian
|
|
75
|
+
claude login
|
|
76
|
+
meridian
|
|
173
77
|
```
|
|
174
78
|
|
|
175
|
-
|
|
176
|
-
|
|
79
|
+
Meridian listens at `http://127.0.0.1:3456`. For OpenCode V1, run
|
|
80
|
+
`meridian setup` once and restart OpenCode. Other clients—including OpenCode V2—have
|
|
81
|
+
[specific setup instructions](docs/agents.md).
|
|
177
82
|
|
|
178
|
-
|
|
179
|
-
|
|
83
|
+
```sh
|
|
84
|
+
# Example for a POSIX shell, with Meridian API-key protection disabled:
|
|
85
|
+
ANTHROPIC_API_KEY=x ANTHROPIC_BASE_URL=http://127.0.0.1:3456 opencode
|
|
86
|
+
```
|
|
180
87
|
|
|
181
|
-
|
|
88
|
+
`x` is a client-required placeholder. If you configure Meridian’s API-key
|
|
89
|
+
protection, use that key instead. Claude authentication comes from the configured
|
|
90
|
+
Claude account. See [configuration](docs/configuration.md) for authentication,
|
|
91
|
+
ports and Windows setup, or [deployment](docs/deployment.md) for Docker and Nix.
|
|
92
|
+
|
|
93
|
+
**No desktop dependency.** Installing the headless package does not install
|
|
94
|
+
Electron. You can run Meridian entirely without the app, including its browser
|
|
95
|
+
[telemetry dashboard](MONITORING.md).
|
|
96
|
+
|
|
97
|
+
## Built for ongoing work
|
|
98
|
+
|
|
99
|
+
- **Keep conversations going.** Sessions resume across requests and proxy restarts,
|
|
100
|
+
with handling for client compaction, undo and branching.
|
|
101
|
+
- **Use the protocol your client speaks.** Anthropic Messages, OpenAI Chat
|
|
102
|
+
Completions and Responses endpoints, including streaming and tool forwarding.
|
|
103
|
+
- **Keep accounts organized.** Multiple Claude profiles, explicit account selection
|
|
104
|
+
and opt-in sticky session routing.
|
|
105
|
+
- **Understand cache behavior.** Request history, prompt-cache metrics, diagnostic
|
|
106
|
+
events and optional persistent telemetry. API-equivalent cost estimates are
|
|
107
|
+
estimates, not your subscription bill.
|
|
108
|
+
- **Keep your deployment.** CLI, containers, declarative Nix services or the
|
|
109
|
+
optional desktop manager share the same Meridian server.
|
|
182
110
|
|
|
183
|
-
|
|
184
|
-
|
|
111
|
+
<p align="center">
|
|
112
|
+
<img src="assets/how-it-works.svg" alt="Your client connects to Meridian, which sends requests through the Claude Agent SDK." width="920" />
|
|
113
|
+
</p>
|
|
185
114
|
|
|
186
|
-
|
|
115
|
+
Meridian uses the SDK’s authentication and request execution. Account access,
|
|
116
|
+
model availability and usage limits still depend on your provider account.
|
|
187
117
|
|
|
188
|
-
|
|
189
|
-
You haven't run `meridian setup`. Without the plugin, OpenCode requests won't have session tracking or subagent model selection. Run `meridian setup` and restart OpenCode.
|
|
118
|
+
## Bring your agent
|
|
190
119
|
|
|
191
|
-
|
|
120
|
+
Setup guides cover **OpenCode, Pi, Claude Code, Codex CLI, Cline, Aider, Crush,
|
|
121
|
+
ForgeCode, Droid, Open WebUI, Cherry Studio, Polytoken, Jcode and Prime Agent**.
|
|
122
|
+
Compatibility varies by client and version; see the
|
|
123
|
+
[tested-agent matrix](docs/agents.md#compatibility-at-a-glance) for evidence and
|
|
124
|
+
limitations. Prime Agent concurrent subagents remain unsuitable for unattended
|
|
125
|
+
or usage-sensitive work. Continue is unverified.
|
|
192
126
|
|
|
193
|
-
|
|
127
|
+
The desktop **Plugins** page installs the four official scrub plugins. Client
|
|
128
|
+
connection setup is still separate; installing a scrub plugin does not configure
|
|
129
|
+
its corresponding client. [Plugin guide →](docs/plugins.md)
|
|
194
130
|
|
|
195
|
-
##
|
|
131
|
+
## Documentation
|
|
196
132
|
|
|
197
|
-
|
|
133
|
+
| Start here | What you’ll find |
|
|
134
|
+
| --- | --- |
|
|
135
|
+
| [Desktop guide](apps/desktop/README.md) | Setup, service ownership, updates, plugins and platform status |
|
|
136
|
+
| [Agent setup](docs/agents.md) | Client configuration and compatibility notes |
|
|
137
|
+
| [Configuration](docs/configuration.md) | CLI, environment variables, endpoints and API-key protection |
|
|
138
|
+
| [Accounts & profiles](docs/profiles.md) | Sign-in, multiple accounts and session routing |
|
|
139
|
+
| [Deployment](docs/deployment.md) | Docker, Nix and headless services |
|
|
140
|
+
| [Plugins](docs/plugins.md) | Official packages and plugin configuration |
|
|
141
|
+
| [Monitoring](MONITORING.md) | Usage, request diagnostics and prompt caching |
|
|
142
|
+
| [Development](docs/development.md) | Build, test and programmatic API |
|
|
143
|
+
| [Desktop releases](docs/desktop-releases.md) | Signing, notarization and download publication |
|
|
144
|
+
|
|
145
|
+
## Contribute
|
|
146
|
+
|
|
147
|
+
[Report a bug or suggest a feature](https://github.com/rynfar/meridian/issues),
|
|
148
|
+
open a PR, or join [Discord](https://discord.gg/jP2a2Z92NZ).
|
|
149
|
+
Read [AGENTS.md](AGENTS.md), [ARCHITECTURE.md](ARCHITECTURE.md) and
|
|
150
|
+
[E2E.md](E2E.md) before changing behavior. Meridian is [MIT licensed](https://opensource.org/license/mit).
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
profileBarHtml,
|
|
29
29
|
profileBarJs,
|
|
30
30
|
themeCss
|
|
31
|
-
} from "./cli-
|
|
31
|
+
} from "./cli-hj61zpt7.js";
|
|
32
32
|
import {
|
|
33
33
|
CANONICAL_SONNET_MODEL,
|
|
34
34
|
OAUTH_CLIENT_ID,
|
|
@@ -22112,6 +22112,9 @@ var WINDOWS_START_PATTERN = /^[1-9][0-9]{0,31}$/;
|
|
|
22112
22112
|
var DARWIN_START_PATTERN = /^(Sun|Mon|Tue|Wed|Thu|Fri|Sat) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) [ 0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-6][0-9] [0-9]{4}$/;
|
|
22113
22113
|
var PROBE_TIMEOUT_MS = 2000;
|
|
22114
22114
|
var WINDOWS_PROBE_TIMEOUT_MS = 1e4;
|
|
22115
|
+
function processIncarnationProbeBudgetMs() {
|
|
22116
|
+
return process.platform === "win32" ? WINDOWS_PROBE_TIMEOUT_MS : PROBE_TIMEOUT_MS;
|
|
22117
|
+
}
|
|
22115
22118
|
var cachedLocalBootIdentity;
|
|
22116
22119
|
var cachedCurrentProcessIncarnation;
|
|
22117
22120
|
function hashIdentity(value) {
|
|
@@ -23786,6 +23789,14 @@ function classifyError(errMsg, model) {
|
|
|
23786
23789
|
message: `Claude Code process exited unexpectedly (code ${code}). Check proxy logs for details. If this persists, try 'claude login' to refresh authentication.`
|
|
23787
23790
|
};
|
|
23788
23791
|
}
|
|
23792
|
+
if (lower.includes("timed out waiting for") && lower.includes(".lock") || lower.includes("ownership backlog is full") || lower.includes("ownership capacity is full")) {
|
|
23793
|
+
const reason = lower.includes("ownership backlog is full") ? "the retirement backlog is full" : lower.includes("ownership capacity is full") ? "the ownership capacity is full" : "a bookkeeping lock is busy";
|
|
23794
|
+
return {
|
|
23795
|
+
status: 503,
|
|
23796
|
+
type: "overloaded_error",
|
|
23797
|
+
message: `Meridian's session bookkeeping is saturated: ${reason}. This is proxy load, not the request; retry shortly.`
|
|
23798
|
+
};
|
|
23799
|
+
}
|
|
23789
23800
|
if (lower.includes("timeout") || lower.includes("timed out")) {
|
|
23790
23801
|
return {
|
|
23791
23802
|
status: 504,
|
|
@@ -32686,6 +32697,7 @@ import {
|
|
|
32686
32697
|
closeSync as closeSync2,
|
|
32687
32698
|
existsSync as existsSync6,
|
|
32688
32699
|
fchmodSync,
|
|
32700
|
+
fstatSync,
|
|
32689
32701
|
fsyncSync as fsyncSync2,
|
|
32690
32702
|
linkSync,
|
|
32691
32703
|
lstatSync as lstatSync3,
|
|
@@ -33439,6 +33451,38 @@ function validateStoreMeta(value) {
|
|
|
33439
33451
|
priorityRollbackMappings
|
|
33440
33452
|
};
|
|
33441
33453
|
}
|
|
33454
|
+
var storeDocumentCache;
|
|
33455
|
+
function readStoreDocumentCached(path3) {
|
|
33456
|
+
let fd;
|
|
33457
|
+
try {
|
|
33458
|
+
const info = statSync(path3);
|
|
33459
|
+
const cached2 = storeDocumentCache;
|
|
33460
|
+
if (cached2?.path === path3 && cached2.ino === info.ino && cached2.mtimeMs === info.mtimeMs && cached2.size === info.size) {
|
|
33461
|
+
return cached2.document;
|
|
33462
|
+
}
|
|
33463
|
+
fd = openSync2(path3, "r");
|
|
33464
|
+
const identity = fstatSync(fd);
|
|
33465
|
+
const document = parseStoreDocument(readFileSync6(fd, "utf8"));
|
|
33466
|
+
storeDocumentCache = { path: path3, ino: identity.ino, mtimeMs: identity.mtimeMs, size: identity.size, document };
|
|
33467
|
+
return document;
|
|
33468
|
+
} catch (error51) {
|
|
33469
|
+
if (error51.code !== "ENOENT")
|
|
33470
|
+
throw error51;
|
|
33471
|
+
storeDocumentCache = undefined;
|
|
33472
|
+
return emptyStoreDocument();
|
|
33473
|
+
} finally {
|
|
33474
|
+
if (fd !== undefined)
|
|
33475
|
+
closeSync2(fd);
|
|
33476
|
+
}
|
|
33477
|
+
}
|
|
33478
|
+
function publishStoreCache(path3, document) {
|
|
33479
|
+
try {
|
|
33480
|
+
const info = statSync(path3);
|
|
33481
|
+
storeDocumentCache = { path: path3, ino: info.ino, mtimeMs: info.mtimeMs, size: info.size, document };
|
|
33482
|
+
} catch {
|
|
33483
|
+
storeDocumentCache = undefined;
|
|
33484
|
+
}
|
|
33485
|
+
}
|
|
33442
33486
|
function readStoreDocumentStrict(path3) {
|
|
33443
33487
|
let data;
|
|
33444
33488
|
try {
|
|
@@ -33448,6 +33492,9 @@ function readStoreDocumentStrict(path3) {
|
|
|
33448
33492
|
return emptyStoreDocument();
|
|
33449
33493
|
throw error51;
|
|
33450
33494
|
}
|
|
33495
|
+
return parseStoreDocument(data);
|
|
33496
|
+
}
|
|
33497
|
+
function parseStoreDocument(data) {
|
|
33451
33498
|
const parsed = JSON.parse(data);
|
|
33452
33499
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
33453
33500
|
throw new Error("session store must contain a JSON object");
|
|
@@ -33480,13 +33527,13 @@ function readStoreDocumentStrict(path3) {
|
|
|
33480
33527
|
return { sessions, meta: meta3 };
|
|
33481
33528
|
}
|
|
33482
33529
|
function readStoreStrict(path3) {
|
|
33483
|
-
return
|
|
33530
|
+
return readStoreDocumentCached(path3).sessions;
|
|
33484
33531
|
}
|
|
33485
33532
|
function readSessionStoreSnapshot() {
|
|
33486
33533
|
return readStoreStrict(getStorePath());
|
|
33487
33534
|
}
|
|
33488
33535
|
function readSessionStoreGenerationSnapshot(adapterSessionId, profileIds = []) {
|
|
33489
|
-
const document =
|
|
33536
|
+
const document = readStoreDocumentCached(getStorePath());
|
|
33490
33537
|
const keys = new Set(Object.keys(document.sessions).filter((key) => key === adapterSessionId || key.endsWith(`:${adapterSessionId}`)));
|
|
33491
33538
|
keys.add(adapterSessionId);
|
|
33492
33539
|
for (const profileId of profileIds) {
|
|
@@ -33518,7 +33565,7 @@ function writeStore(path3, document) {
|
|
|
33518
33565
|
fd = openSync2(tmp, "wx", 384);
|
|
33519
33566
|
fchmodSync(fd, 384);
|
|
33520
33567
|
const serialized = { [STORE_META_KEY]: document.meta, ...document.sessions };
|
|
33521
|
-
writeFileSync2(fd, JSON.stringify(serialized
|
|
33568
|
+
writeFileSync2(fd, JSON.stringify(serialized), "utf8");
|
|
33522
33569
|
fsyncSync2(fd);
|
|
33523
33570
|
closeSync2(fd);
|
|
33524
33571
|
fd = undefined;
|
|
@@ -33547,8 +33594,10 @@ function mutateStore(mutator) {
|
|
|
33547
33594
|
const lock = acquireLock(`${path3}.lock`);
|
|
33548
33595
|
try {
|
|
33549
33596
|
const document = readStoreDocumentStrict(path3);
|
|
33550
|
-
if (mutator(document))
|
|
33597
|
+
if (mutator(document)) {
|
|
33551
33598
|
writeStore(path3, document);
|
|
33599
|
+
publishStoreCache(path3, document);
|
|
33600
|
+
}
|
|
33552
33601
|
} finally {
|
|
33553
33602
|
releaseLock(lock);
|
|
33554
33603
|
}
|
|
@@ -33559,7 +33608,7 @@ function hasLegacyUserDenialBoundary(session) {
|
|
|
33559
33608
|
}
|
|
33560
33609
|
function lookupSharedSessionResult(key) {
|
|
33561
33610
|
try {
|
|
33562
|
-
const document =
|
|
33611
|
+
const document = readStoreDocumentCached(getStorePath());
|
|
33563
33612
|
const session = document.sessions[key];
|
|
33564
33613
|
const generation = keyGeneration(key, session, document.meta);
|
|
33565
33614
|
if (!session)
|
|
@@ -33579,7 +33628,7 @@ function lookupSharedSession(key) {
|
|
|
33579
33628
|
}
|
|
33580
33629
|
function lookupPriorityAssignmentResult(routeKey) {
|
|
33581
33630
|
try {
|
|
33582
|
-
const document =
|
|
33631
|
+
const document = readStoreDocumentCached(getStorePath());
|
|
33583
33632
|
const assignment = document.meta.version === PRIORITY_STORE_META_VERSION ? document.meta.priorityAssignments[routeKey] : undefined;
|
|
33584
33633
|
const generation = priorityAssignmentGeneration(routeKey, assignment, document.meta);
|
|
33585
33634
|
const attempt = document.meta.version === PRIORITY_STORE_META_VERSION ? document.meta.priorityAttempts[routeKey] : undefined;
|
|
@@ -33592,7 +33641,7 @@ function lookupPriorityAssignmentResult(routeKey) {
|
|
|
33592
33641
|
}
|
|
33593
33642
|
function lookupSharedSessionByClaudeIdResult(claudeSessionId) {
|
|
33594
33643
|
try {
|
|
33595
|
-
const document =
|
|
33644
|
+
const document = readStoreDocumentCached(getStorePath());
|
|
33596
33645
|
let newest;
|
|
33597
33646
|
let newestKey;
|
|
33598
33647
|
for (const [key, session] of Object.entries(document.sessions)) {
|
|
@@ -33673,8 +33722,8 @@ function storeSharedSession(key, claudeSessionId, messageCount, lineageHash, mes
|
|
|
33673
33722
|
passthroughToolCallAssistantUuid: passthroughToolCallAssistantUuid === undefined ? existing?.passthroughToolCallAssistantUuid : passthroughToolCallAssistantUuid ?? undefined,
|
|
33674
33723
|
passthroughToolCallIds: passthroughToolCallIds === undefined ? existing?.passthroughToolCallIds : passthroughToolCallIds ?? undefined,
|
|
33675
33724
|
contextUsage: contextUsage ?? existing?.contextUsage,
|
|
33676
|
-
...resolvedCurrentTranscript ? { currentTranscript: resolvedCurrentTranscript } : {},
|
|
33677
|
-
...previousTranscript ? { previousTranscript } : {},
|
|
33725
|
+
...resolvedCurrentTranscript ? { currentTranscript: { ...resolvedCurrentTranscript } } : {},
|
|
33726
|
+
...previousTranscript ? { previousTranscript: { ...previousTranscript } } : {},
|
|
33678
33727
|
...previousClaudeSessionId ? { previousClaudeSessionId } : {}
|
|
33679
33728
|
};
|
|
33680
33729
|
const maxEntries = getMaxStoredSessionsLimit();
|
|
@@ -34100,7 +34149,7 @@ function attachSharedTranscriptLocator(key, expectedClaudeSessionId, locator, ex
|
|
|
34100
34149
|
if (expectedGeneration !== undefined && getStoredSessionGeneration(existing, key) !== expectedGeneration)
|
|
34101
34150
|
return false;
|
|
34102
34151
|
if (!sameTranscriptLocator(existing.currentTranscript, locator)) {
|
|
34103
|
-
existing.currentTranscript = locator;
|
|
34152
|
+
existing.currentTranscript = { ...locator };
|
|
34104
34153
|
existing.revision = (existing.revision ?? 0) + 1;
|
|
34105
34154
|
existing.generationId = randomUUID2();
|
|
34106
34155
|
advanceKeySlot(key, meta3);
|
|
@@ -35093,7 +35142,7 @@ class CrossProcessTurnCoordinator {
|
|
|
35093
35142
|
|
|
35094
35143
|
// src/proxy/sessionLifecycle.ts
|
|
35095
35144
|
import { createHash as createHash9, randomUUID as randomUUID4 } from "node:crypto";
|
|
35096
|
-
import { spawn } from "node:child_process";
|
|
35145
|
+
import { spawn, spawnSync as spawnSync2 } from "node:child_process";
|
|
35097
35146
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
35098
35147
|
import {
|
|
35099
35148
|
chmod as chmod2,
|
|
@@ -35120,9 +35169,11 @@ var DEFAULT_LOCK_RETRY_MS = 25;
|
|
|
35120
35169
|
var DEFAULT_LOCK_STALE_MS = 60000;
|
|
35121
35170
|
var DEFAULT_PREPARED_GRACE_MS = 5 * 60000;
|
|
35122
35171
|
var DEFAULT_RETIRED_GRACE_MS = 11 * 60000;
|
|
35172
|
+
var DEFAULT_UNARMED_LEASE_TTL_MS = 11 * 60000;
|
|
35123
35173
|
var DEFAULT_RETRY_BASE_MS = 5000;
|
|
35124
35174
|
var DEFAULT_RETRY_MAX_MS = 60 * 60000;
|
|
35125
35175
|
var DEFAULT_DELETE_TIMEOUT_MS = 30000;
|
|
35176
|
+
var SESSION_GC_NOT_FOUND_EXIT_CODE = 69;
|
|
35126
35177
|
|
|
35127
35178
|
class SessionLifecycleError extends Error {
|
|
35128
35179
|
}
|
|
@@ -35161,13 +35212,14 @@ async function acquireActiveTranscriptLease(locators, options = {}) {
|
|
|
35161
35212
|
const token = randomUUID4();
|
|
35162
35213
|
await withSidecarLock(options, async (paths) => {
|
|
35163
35214
|
const sidecar = await readSidecar(paths.sidecar);
|
|
35215
|
+
const unarmedLeaseTtlMs = nonNegativeOption(options.unarmedLeaseTtlMs, DEFAULT_UNARMED_LEASE_TTL_MS, "unarmedLeaseTtlMs");
|
|
35164
35216
|
for (const [key, locator] of normalized) {
|
|
35165
35217
|
const resource = sidecar.resources[key];
|
|
35166
35218
|
if (!resource)
|
|
35167
35219
|
throw new SessionLifecycleError(`cannot lease unjournaled transcript ${key}`);
|
|
35168
35220
|
assertSameLocator(resource.locator, locator);
|
|
35169
35221
|
assertExactLifecycleGeneration(resource, locator);
|
|
35170
|
-
pruneDeadActiveLeases(resource);
|
|
35222
|
+
pruneDeadActiveLeases(resource, nowMs(options), unarmedLeaseTtlMs);
|
|
35171
35223
|
if (Object.values(resource.activeLeases ?? {}).some((lease) => lease.purpose !== "publication")) {
|
|
35172
35224
|
throw new SessionLifecycleError(`transcript ${key} already has an active SDK writer`);
|
|
35173
35225
|
}
|
|
@@ -35484,8 +35536,9 @@ async function reconcile(pins, options = {}) {
|
|
|
35484
35536
|
const now = nowMs(options);
|
|
35485
35537
|
const preparedCutoff = now - nonNegativeOption(options.preparedGraceMs, DEFAULT_PREPARED_GRACE_MS, "preparedGraceMs");
|
|
35486
35538
|
let changed = false;
|
|
35539
|
+
const unarmedLeaseTtlMs = nonNegativeOption(options.unarmedLeaseTtlMs, DEFAULT_UNARMED_LEASE_TTL_MS, "unarmedLeaseTtlMs");
|
|
35487
35540
|
for (const resource of Object.values(sidecar.resources)) {
|
|
35488
|
-
if (pruneDeadActiveLeases(resource))
|
|
35541
|
+
if (pruneDeadActiveLeases(resource, now, unarmedLeaseTtlMs))
|
|
35489
35542
|
changed = true;
|
|
35490
35543
|
}
|
|
35491
35544
|
let pending = pendingResourceCount(sidecar);
|
|
@@ -35494,7 +35547,7 @@ async function reconcile(pins, options = {}) {
|
|
|
35494
35547
|
for (const resource of Object.values(sidecar.resources)) {
|
|
35495
35548
|
if (resource.state !== "deleting")
|
|
35496
35549
|
continue;
|
|
35497
|
-
const executorDead = resource.deletionExecutor && resource.deletionProcessGroupId !== undefined ? processIncarnationIsDead(resource.deletionExecutor) && processGroupIsEmpty(resource.deletionProcessGroupId) : false;
|
|
35550
|
+
const executorDead = resource.deletionExecutor && resource.deletionProcessGroupId !== undefined ? processIncarnationIsDead(resource.deletionExecutor) && (process.platform === "win32" || processGroupIsEmpty(resource.deletionProcessGroupId)) : false;
|
|
35498
35551
|
const ownerDiedBeforeHandshake = !resource.deletionExecutor && resource.deletionOwner !== undefined && processIncarnationIsDead(resource.deletionOwner);
|
|
35499
35552
|
if (!executorDead && !ownerDiedBeforeHandshake)
|
|
35500
35553
|
continue;
|
|
@@ -35550,14 +35603,6 @@ async function reconcile(pins, options = {}) {
|
|
|
35550
35603
|
async function runGc(pins, options = {}) {
|
|
35551
35604
|
await reconcile(pins, options);
|
|
35552
35605
|
let currentPins = pins.map(canonicalizeTranscriptLocator);
|
|
35553
|
-
if (!options.deleter && process.platform === "win32") {
|
|
35554
|
-
return {
|
|
35555
|
-
deleted: 0,
|
|
35556
|
-
notFound: 0,
|
|
35557
|
-
failed: 0,
|
|
35558
|
-
deferred: await countDeferred(currentPins, options)
|
|
35559
|
-
};
|
|
35560
|
-
}
|
|
35561
35606
|
const limit = option(options.maxDeletesPerRun, DEFAULT_MAX_DELETES, "maxDeletesPerRun");
|
|
35562
35607
|
const result = { deleted: 0, notFound: 0, failed: 0, deferred: 0 };
|
|
35563
35608
|
const runTimeoutMs = option(options.runTimeoutMs, DEFAULT_DELETE_TIMEOUT_MS, "runTimeoutMs");
|
|
@@ -35611,9 +35656,10 @@ async function claimDeletion(pins, options) {
|
|
|
35611
35656
|
const sidecar = await readSidecar(paths.sidecar);
|
|
35612
35657
|
const finalPins = (options.pinProvider?.() ?? pins).map(canonicalizeTranscriptLocator);
|
|
35613
35658
|
const now = nowMs(options);
|
|
35659
|
+
const unarmedLeaseTtlMs = nonNegativeOption(options.unarmedLeaseTtlMs, DEFAULT_UNARMED_LEASE_TTL_MS, "unarmedLeaseTtlMs");
|
|
35614
35660
|
let leasesChanged = false;
|
|
35615
35661
|
for (const resource of Object.values(sidecar.resources)) {
|
|
35616
|
-
if (pruneDeadActiveLeases(resource))
|
|
35662
|
+
if (pruneDeadActiveLeases(resource, now, unarmedLeaseTtlMs))
|
|
35617
35663
|
leasesChanged = true;
|
|
35618
35664
|
}
|
|
35619
35665
|
const candidate = Object.values(sidecar.resources).filter((resource) => resource.state === "retired" && !resourceIsPinned(resource, finalPins) && !hasActiveTranscriptLease(resource) && (resource.nextAttemptAt ?? 0) <= now).sort((left, right) => left.updatedAt - right.updatedAt || left.key.localeCompare(right.key))[0];
|
|
@@ -35687,6 +35733,9 @@ async function countDeferred(pins, options) {
|
|
|
35687
35733
|
|
|
35688
35734
|
class DeletionStillRunningError extends Error {
|
|
35689
35735
|
}
|
|
35736
|
+
|
|
35737
|
+
class TranscriptAlreadyAbsentError extends Error {
|
|
35738
|
+
}
|
|
35690
35739
|
async function awaitCustomDeleter(deletion, timeoutMs) {
|
|
35691
35740
|
let timer;
|
|
35692
35741
|
const timeout = new Promise((_resolve, reject) => {
|
|
@@ -35708,8 +35757,9 @@ async function awaitCustomDeleter(deletion, timeoutMs) {
|
|
|
35708
35757
|
}
|
|
35709
35758
|
}
|
|
35710
35759
|
function processGroupIsEmpty(processGroupId) {
|
|
35711
|
-
if (process.platform === "win32")
|
|
35712
|
-
|
|
35760
|
+
if (process.platform === "win32") {
|
|
35761
|
+
throw new SessionLifecycleError("process-group probes are POSIX-only");
|
|
35762
|
+
}
|
|
35713
35763
|
try {
|
|
35714
35764
|
process.kill(-processGroupId, 0);
|
|
35715
35765
|
return false;
|
|
@@ -35718,8 +35768,13 @@ function processGroupIsEmpty(processGroupId) {
|
|
|
35718
35768
|
}
|
|
35719
35769
|
}
|
|
35720
35770
|
function signalProcessGroup(processGroupId, signal) {
|
|
35721
|
-
if (process.platform === "win32")
|
|
35771
|
+
if (process.platform === "win32") {
|
|
35772
|
+
spawnSync2("taskkill", ["/PID", String(processGroupId), "/T", "/F"], {
|
|
35773
|
+
stdio: "ignore",
|
|
35774
|
+
windowsHide: true
|
|
35775
|
+
});
|
|
35722
35776
|
return;
|
|
35777
|
+
}
|
|
35723
35778
|
try {
|
|
35724
35779
|
process.kill(-processGroupId, signal);
|
|
35725
35780
|
} catch (error51) {
|
|
@@ -35753,7 +35808,7 @@ async function waitForDeletionExit(exited, timeoutMs) {
|
|
|
35753
35808
|
}
|
|
35754
35809
|
}
|
|
35755
35810
|
async function deleteWithSdkChild(locator, deletionToken, timeoutMs, attachExecutor, options) {
|
|
35756
|
-
const sdkUrl = import.meta.resolve("@anthropic-ai/claude-agent-sdk");
|
|
35811
|
+
const sdkUrl = options.sdkModuleUrl ?? import.meta.resolve("@anthropic-ai/claude-agent-sdk");
|
|
35757
35812
|
const gateDirectory = join10(getStoreDir(options), "deletion-gates");
|
|
35758
35813
|
await mkdir5(gateDirectory, { recursive: true, mode: 448 });
|
|
35759
35814
|
const gatePath = join10(gateDirectory, `${deletionToken}.go`);
|
|
@@ -35770,15 +35825,31 @@ while (!existsSync(process.env.MERIDIAN_GC_GATE_PATH)) {
|
|
|
35770
35825
|
await wait(10);
|
|
35771
35826
|
}
|
|
35772
35827
|
const sdk = await import(process.env.MERIDIAN_GC_SDK_URL);
|
|
35828
|
+
const sessionId = process.env.MERIDIAN_GC_SESSION_ID;
|
|
35773
35829
|
const options = process.env.MERIDIAN_GC_PROJECT_DIR
|
|
35774
35830
|
? { dir: process.env.MERIDIAN_GC_PROJECT_DIR }
|
|
35775
35831
|
: undefined;
|
|
35832
|
+
// Only the SDK's session-specific verdict means "already absent". A generic
|
|
35833
|
+
// "not found" can be the SDK or the child itself failing to load, and must stay
|
|
35834
|
+
// a retryable failure rather than tombstone a transcript still on disk.
|
|
35835
|
+
const absent = (message) => message.includes(process.env.MERIDIAN_GC_ABSENT_PHRASE);
|
|
35776
35836
|
try {
|
|
35777
|
-
await sdk.deleteSession(
|
|
35837
|
+
await sdk.deleteSession(sessionId, options);
|
|
35778
35838
|
} catch (error) {
|
|
35779
35839
|
const message = error instanceof Error ? error.message : String(error);
|
|
35780
|
-
if (!
|
|
35781
|
-
|
|
35840
|
+
if (!message.includes("not found")) throw error;
|
|
35841
|
+
if (options) {
|
|
35842
|
+
try {
|
|
35843
|
+
await sdk.deleteSession(sessionId);
|
|
35844
|
+
process.exit(0); // The dir-less retry deleted it: a deletion, not an absence.
|
|
35845
|
+
} catch (fallbackError) {
|
|
35846
|
+
const fallbackMessage = fallbackError instanceof Error ? fallbackError.message : String(fallbackError);
|
|
35847
|
+
if (!absent(fallbackMessage)) throw fallbackError;
|
|
35848
|
+
process.exit(${SESSION_GC_NOT_FOUND_EXIT_CODE});
|
|
35849
|
+
}
|
|
35850
|
+
}
|
|
35851
|
+
if (!absent(message)) throw error;
|
|
35852
|
+
process.exit(${SESSION_GC_NOT_FOUND_EXIT_CODE});
|
|
35782
35853
|
}
|
|
35783
35854
|
`;
|
|
35784
35855
|
const child = spawn(getSessionGcNodeExecutable(), ["--input-type=module", "--eval", script], {
|
|
@@ -35787,9 +35858,10 @@ try {
|
|
|
35787
35858
|
CLAUDE_CONFIG_DIR: locator.configDir,
|
|
35788
35859
|
MERIDIAN_GC_SDK_URL: sdkUrl,
|
|
35789
35860
|
MERIDIAN_GC_SESSION_ID: locator.sessionId,
|
|
35861
|
+
MERIDIAN_GC_ABSENT_PHRASE: sessionAbsentPhrase(locator.sessionId),
|
|
35790
35862
|
MERIDIAN_GC_PROJECT_DIR: locator.projectDir ?? "",
|
|
35791
35863
|
MERIDIAN_GC_GATE_PATH: gatePath,
|
|
35792
|
-
MERIDIAN_GC_GATE_TIMEOUT_MS: String(timeoutMs)
|
|
35864
|
+
MERIDIAN_GC_GATE_TIMEOUT_MS: String(timeoutMs + processIncarnationProbeBudgetMs())
|
|
35793
35865
|
},
|
|
35794
35866
|
stdio: ["ignore", "pipe", "pipe"],
|
|
35795
35867
|
windowsHide: true,
|
|
@@ -35811,15 +35883,21 @@ try {
|
|
|
35811
35883
|
let timer;
|
|
35812
35884
|
const joinTimeoutMs = Math.max(100, Math.min(2000, timeoutMs));
|
|
35813
35885
|
const processGroupId = child.pid;
|
|
35886
|
+
let deletionTreeKilled = false;
|
|
35887
|
+
const killDeletionTree = () => {
|
|
35888
|
+
if (!processGroupId || deletionTreeKilled)
|
|
35889
|
+
return;
|
|
35890
|
+
if (process.platform === "win32" && (child.exitCode !== null || child.signalCode !== null))
|
|
35891
|
+
return;
|
|
35892
|
+
signalProcessGroup(processGroupId, "SIGKILL");
|
|
35893
|
+
deletionTreeKilled = true;
|
|
35894
|
+
};
|
|
35814
35895
|
try {
|
|
35815
35896
|
if (!processGroupId)
|
|
35816
35897
|
throw new Error("session deletion child has no PID");
|
|
35817
35898
|
const executor = captureProcessIncarnation(processGroupId);
|
|
35818
35899
|
if (!executor)
|
|
35819
35900
|
throw new Error("cannot capture session deletion executor incarnation");
|
|
35820
|
-
if (process.platform === "win32") {
|
|
35821
|
-
throw new SessionLifecycleError("fenced session deletion is unavailable on win32");
|
|
35822
|
-
}
|
|
35823
35901
|
await attachExecutor(executor, processGroupId);
|
|
35824
35902
|
const gateHandle = await open3(gatePath, "wx", 384);
|
|
35825
35903
|
try {
|
|
@@ -35831,27 +35909,30 @@ try {
|
|
|
35831
35909
|
}
|
|
35832
35910
|
const timeout = new Promise((_resolve, reject) => {
|
|
35833
35911
|
timer = setTimeout(() => {
|
|
35834
|
-
|
|
35912
|
+
killDeletionTree();
|
|
35835
35913
|
reject(new Error("session deletion process group timed out and was killed"));
|
|
35836
35914
|
}, timeoutMs);
|
|
35837
35915
|
timer.unref?.();
|
|
35838
35916
|
});
|
|
35839
35917
|
const status = await Promise.race([exited, timeout]);
|
|
35840
|
-
joined = await waitForProcessGroupEmpty(processGroupId, joinTimeoutMs);
|
|
35918
|
+
joined = process.platform === "win32" ? true : await waitForProcessGroupEmpty(processGroupId, joinTimeoutMs);
|
|
35841
35919
|
if (!joined) {
|
|
35842
35920
|
throw new DeletionStillRunningError("session deletion process group remains active");
|
|
35843
35921
|
}
|
|
35922
|
+
if (status.code === SESSION_GC_NOT_FOUND_EXIT_CODE) {
|
|
35923
|
+
throw new TranscriptAlreadyAbsentError(`session deletion child reported transcript ${locator.sessionId} already absent`);
|
|
35924
|
+
}
|
|
35844
35925
|
if (status.code !== 0) {
|
|
35845
|
-
throw new Error(`session deletion child exited ${status.code ?? status.signal}: ${output
|
|
35926
|
+
throw new Error(`session deletion child exited ${status.code ?? status.signal}: ${clipChildOutput(output)}`);
|
|
35846
35927
|
}
|
|
35847
35928
|
} finally {
|
|
35848
35929
|
if (timer)
|
|
35849
35930
|
clearTimeout(timer);
|
|
35850
35931
|
if (!joined && processGroupId) {
|
|
35851
|
-
|
|
35932
|
+
killDeletionTree();
|
|
35852
35933
|
const [leaderExited, groupEmpty] = await Promise.all([
|
|
35853
35934
|
waitForDeletionExit(exited, joinTimeoutMs),
|
|
35854
|
-
waitForProcessGroupEmpty(processGroupId, joinTimeoutMs)
|
|
35935
|
+
process.platform === "win32" ? Promise.resolve(true) : waitForProcessGroupEmpty(processGroupId, joinTimeoutMs)
|
|
35855
35936
|
]);
|
|
35856
35937
|
joined = leaderExited && groupEmpty;
|
|
35857
35938
|
unjoined = !joined;
|
|
@@ -35866,6 +35947,15 @@ try {
|
|
|
35866
35947
|
}
|
|
35867
35948
|
}
|
|
35868
35949
|
}
|
|
35950
|
+
function clipChildOutput(output) {
|
|
35951
|
+
const halfBudget = 2000;
|
|
35952
|
+
if (output.length <= halfBudget * 2)
|
|
35953
|
+
return output;
|
|
35954
|
+
const elided = output.length - halfBudget * 2;
|
|
35955
|
+
return `${output.slice(0, halfBudget)}
|
|
35956
|
+
…[${elided} chars elided]…
|
|
35957
|
+
${output.slice(-halfBudget)}`;
|
|
35958
|
+
}
|
|
35869
35959
|
function getStoreDir(options) {
|
|
35870
35960
|
if (options.storeDir)
|
|
35871
35961
|
return options.storeDir;
|
|
@@ -36175,7 +36265,7 @@ async function writeSidecar(path3, sidecar) {
|
|
|
36175
36265
|
let handle;
|
|
36176
36266
|
try {
|
|
36177
36267
|
handle = await open3(temp, "wx", 384);
|
|
36178
|
-
await handle.writeFile(`${JSON.stringify(sidecar
|
|
36268
|
+
await handle.writeFile(`${JSON.stringify(sidecar)}
|
|
36179
36269
|
`, "utf8");
|
|
36180
36270
|
await handle.sync();
|
|
36181
36271
|
await handle.close();
|
|
@@ -36318,14 +36408,15 @@ function releasePublicationLease(resource) {
|
|
|
36318
36408
|
delete resource.activeLeases;
|
|
36319
36409
|
return changed;
|
|
36320
36410
|
}
|
|
36321
|
-
function pruneDeadActiveLeases(resource) {
|
|
36411
|
+
function pruneDeadActiveLeases(resource, now, unarmedLeaseTtlMs) {
|
|
36322
36412
|
if (!resource.activeLeases)
|
|
36323
36413
|
return false;
|
|
36324
36414
|
let changed = false;
|
|
36325
36415
|
for (const [token, lease] of Object.entries(resource.activeLeases)) {
|
|
36326
36416
|
const executorDead = lease.executor && lease.executorRecoverable !== false ? processIncarnationIsDead(lease.executor) : false;
|
|
36327
36417
|
const unarmedOwnerDead = !lease.executor && processIncarnationIsDead(lease.owner);
|
|
36328
|
-
|
|
36418
|
+
const unarmedLeaseExpired = !lease.executor && now - lease.createdAt > unarmedLeaseTtlMs;
|
|
36419
|
+
if (!executorDead && !unarmedOwnerDead && !unarmedLeaseExpired)
|
|
36329
36420
|
continue;
|
|
36330
36421
|
delete resource.activeLeases[token];
|
|
36331
36422
|
changed = true;
|
|
@@ -36395,11 +36486,32 @@ function assertSameLocator(left, right) {
|
|
|
36395
36486
|
function isState(value) {
|
|
36396
36487
|
return value === "prepared" || value === "live" || value === "retired" || value === "deleting" || value === "deleted";
|
|
36397
36488
|
}
|
|
36489
|
+
function sessionAbsentPhrase(sessionId) {
|
|
36490
|
+
return `Session ${sessionId} not found`;
|
|
36491
|
+
}
|
|
36398
36492
|
function isNotFoundError(error51, sessionId) {
|
|
36399
|
-
|
|
36493
|
+
if (error51 instanceof TranscriptAlreadyAbsentError)
|
|
36494
|
+
return true;
|
|
36495
|
+
return errorMessage(error51).includes(sessionAbsentPhrase(sessionId));
|
|
36400
36496
|
}
|
|
36497
|
+
var sessionGcNodeExecutable;
|
|
36401
36498
|
function getSessionGcNodeExecutable() {
|
|
36402
|
-
|
|
36499
|
+
if (typeof process.versions.bun !== "string")
|
|
36500
|
+
return process.execPath;
|
|
36501
|
+
if (sessionGcNodeExecutable)
|
|
36502
|
+
return sessionGcNodeExecutable;
|
|
36503
|
+
const probe = spawnSync2("node", ["-p", "process.execPath"], {
|
|
36504
|
+
encoding: "utf8",
|
|
36505
|
+
timeout: 5000,
|
|
36506
|
+
maxBuffer: 16 * 1024,
|
|
36507
|
+
windowsHide: true
|
|
36508
|
+
});
|
|
36509
|
+
const executable = probe.stdout?.trim();
|
|
36510
|
+
if (probe.error || probe.status !== 0 || !executable || !isAbsolute5(executable)) {
|
|
36511
|
+
throw new SessionLifecycleError("cannot resolve Node executable for session deletion");
|
|
36512
|
+
}
|
|
36513
|
+
sessionGcNodeExecutable = realpathSync2(executable);
|
|
36514
|
+
return sessionGcNodeExecutable;
|
|
36403
36515
|
}
|
|
36404
36516
|
function errorMessage(error51) {
|
|
36405
36517
|
return error51 instanceof Error ? error51.message : String(error51);
|
|
@@ -36917,6 +37029,8 @@ function createProxyServer(config2 = {}) {
|
|
|
36917
37029
|
maxDeletesPerRun: Math.max(1, envInt("SESSION_GC_MAX_DELETES", 16)),
|
|
36918
37030
|
preparedGraceMs: Math.max(SESSION_TURN_MAX_HOLD_MS + 60000, envInt("SESSION_GC_PREPARED_GRACE_MS", SESSION_TURN_MAX_HOLD_MS + 60000)),
|
|
36919
37031
|
retiredGraceMs: Math.max(0, envInt("SESSION_GC_GRACE_MS", SESSION_TURN_MAX_HOLD_MS + 60000)),
|
|
37032
|
+
lockWaitMs: Math.max(100, envInt("SESSION_GC_LOCK_WAIT_MS", 2000)),
|
|
37033
|
+
unarmedLeaseTtlMs: SESSION_TURN_MAX_HOLD_MS + 60000,
|
|
36920
37034
|
deletionTimeoutMs: Math.max(1000, envInt("SESSION_GC_DELETE_TIMEOUT_MS", 30000)),
|
|
36921
37035
|
runTimeoutMs: Math.max(1000, envInt("SESSION_GC_RUN_TIMEOUT_MS", 30000))
|
|
36922
37036
|
};
|
|
@@ -38131,7 +38245,7 @@ data: ${JSON.stringify(lastError)}
|
|
|
38131
38245
|
if (managedForkTarget)
|
|
38132
38246
|
return;
|
|
38133
38247
|
managedFreshTarget = false;
|
|
38134
|
-
managedForkSource = cachedSession?.currentTranscript?.sessionId === sourceSessionId ? cachedSession.currentTranscript : transcriptLocator(sourceSessionId);
|
|
38248
|
+
managedForkSource = cachedSession?.currentTranscript?.sessionId === sourceSessionId ? { ...cachedSession.currentTranscript } : transcriptLocator(sourceSessionId);
|
|
38135
38249
|
managedForkTarget = transcriptLocator(randomUUID6());
|
|
38136
38250
|
releaseManagedForkPins = pinActiveSessionGcLocators(managedForkSource, managedForkTarget);
|
|
38137
38251
|
const attachedGeneration = lifecycleMappingKey ? await attachPinnedTranscript(managedForkSource, () => {
|
|
@@ -40116,7 +40230,8 @@ data: ${JSON.stringify({
|
|
|
40116
40230
|
if (!recoverySourceId || !lifecycleMappingKey) {
|
|
40117
40231
|
throw new Error("Silent recovery has no durable source mapping");
|
|
40118
40232
|
}
|
|
40119
|
-
|
|
40233
|
+
const storedRecoverySource = lookupSharedSession(lifecycleMappingKey)?.currentTranscript;
|
|
40234
|
+
recoveryForkSource = storedRecoverySource ? { ...storedRecoverySource } : transcriptLocator(recoverySourceId);
|
|
40120
40235
|
const recoveryAttachedGeneration = recoveryForkSource.sessionId === recoverySourceId ? await attachPinnedTranscript(recoveryForkSource, () => {
|
|
40121
40236
|
assertDurableWritesAllowed();
|
|
40122
40237
|
return attachSharedTranscriptLocator(lifecycleMappingKey, recoverySourceId, recoveryForkSource, mappingExpectedGeneration ?? undefined);
|
|
@@ -41470,7 +41585,7 @@ data: ${JSON.stringify({
|
|
|
41470
41585
|
});
|
|
41471
41586
|
});
|
|
41472
41587
|
app.get("/profiles", async (c) => {
|
|
41473
|
-
const { profilePageHtml } = await import("./profilePage-
|
|
41588
|
+
const { profilePageHtml } = await import("./profilePage-mamej7kp.js");
|
|
41474
41589
|
return c.html(profilePageHtml);
|
|
41475
41590
|
});
|
|
41476
41591
|
app.post("/profiles/active", async (c) => {
|
|
@@ -41538,7 +41653,7 @@ data: ${JSON.stringify({
|
|
|
41538
41653
|
}
|
|
41539
41654
|
});
|
|
41540
41655
|
app.get("/plugins", async (c) => {
|
|
41541
|
-
const { pluginPageHtml } = await import("./pluginPage-
|
|
41656
|
+
const { pluginPageHtml } = await import("./pluginPage-f5gdmbxc.js");
|
|
41542
41657
|
return c.html(pluginPageHtml);
|
|
41543
41658
|
});
|
|
41544
41659
|
app.post("/auth/refresh", async (c) => {
|
package/dist/cli.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
startProxyServer
|
|
4
|
-
} from "./cli-
|
|
4
|
+
} from "./cli-ab7zkp1a.js";
|
|
5
5
|
import"./cli-5jxyma6z.js";
|
|
6
6
|
import"./cli-sry5aqdj.js";
|
|
7
|
-
import"./cli-
|
|
7
|
+
import"./cli-hj61zpt7.js";
|
|
8
8
|
import {
|
|
9
9
|
resolveClaudeExecutableAsync
|
|
10
10
|
} from "./cli-9e5cxp89.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/proxy/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAExD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAc1D;AAoKD,2EAA2E;AAC3E,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAEpF;AAqFD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,eAAe,
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/proxy/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAExD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAc1D;AAoKD,2EAA2E;AAC3E,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAEpF;AAqFD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,eAAe,CA+M7E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAM3D;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,aAAa,GAAG,iBAAiB,CAAA;AAEtE;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAahG;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAI3E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGxD;AAuBD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,SAAS,IAAI,MAAM,CAEhG;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAE5E;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGjE;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,GAAG,cAAc,GAAG,SAAS,GAAG,eAAe,GAAG,kBAAkB,GAAG,SAAS,CAAA;IACnG,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;wCAEoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAuBD;;;;;;GAMG;AACH;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE;IAChD,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAA;IAChC,WAAW,EAAE,OAAO,CAAA;IACpB,gBAAgB,EAAE,MAAM,CAAA;IACxB,WAAW,EAAE,OAAO,CAAA;CACrB,GAAG,OAAO,CAYV;AAED;;;;;;GAMG;AACH,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAA;IACZ,+EAA+E;IAC/E,kBAAkB,EAAE,OAAO,CAAA;IAC3B,cAAc,EAAE,OAAO,CAAA;IACvB,WAAW,EAAE,OAAO,CAAA;CACrB;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAaT;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE;IAClD,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAA;IAChC,WAAW,EAAE,OAAO,CAAA;IACpB,gBAAgB,EAAE,MAAM,CAAA;IACxB,gBAAgB,EAAE,MAAM,CAAA;IACxB,iBAAiB,EAAE,MAAM,CAAA;IACzB,mBAAmB,EAAE,OAAO,CAAA;IAC5B,kBAAkB,EAAE,OAAO,CAAA;IAC3B,cAAc,EAAE,OAAO,CAAA;IACvB,yBAAyB,EAAE,OAAO,CAAA;IAClC,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAA;CACtC,GAAG,OAAO,CAeV;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAiEpE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,CAAC,EAAE,cAAc,EACjB,GAAG,EAAE;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,kBAAkB,CAAA;CAC3B,GACA,MAAM,CAkBR"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/proxy/server.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACtE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,CAAA;AAGvD,YAAY,EACV,SAAS,EACT,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,WAAW,GACZ,MAAM,aAAa,CAAA;AAKpB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AA4EnG,OAAO,EACL,kBAAkB,EAElB,WAAW,EACX,oBAAoB,EAMpB,KAAK,aAAa,EAGnB,MAAM,mBAAmB,CAAA;AAI1B,OAAO,EAKL,iBAAiB,EACjB,mBAAmB,EAKpB,MAAM,iBAAiB,CAAA;AA0CxB,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,oBAAoB,EAAE,CAAA;AAChE,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,CAAA;AACjD,YAAY,EAAE,aAAa,EAAE,CAAA;AA+Y7B,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,WAAW,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/proxy/server.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACtE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,CAAA;AAGvD,YAAY,EACV,SAAS,EACT,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,WAAW,GACZ,MAAM,aAAa,CAAA;AAKpB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AA4EnG,OAAO,EACL,kBAAkB,EAElB,WAAW,EACX,oBAAoB,EAMpB,KAAK,aAAa,EAGnB,MAAM,mBAAmB,CAAA;AAI1B,OAAO,EAKL,iBAAiB,EACjB,mBAAmB,EAKpB,MAAM,iBAAiB,CAAA;AA0CxB,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,oBAAoB,EAAE,CAAA;AAChE,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,CAAA;AACjD,YAAY,EAAE,aAAa,EAAE,CAAA;AA+Y7B,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,WAAW,CAmoPhF;AAWD,wBAAgB,gCAAgC,IAAI,IAAI,CAavD;AAED,wBAAsB,gBAAgB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA8NhG"}
|
|
@@ -29,6 +29,13 @@ export type ProcessStartObservation = {
|
|
|
29
29
|
} | {
|
|
30
30
|
status: "indeterminate";
|
|
31
31
|
};
|
|
32
|
+
/**
|
|
33
|
+
* How long a single capture may block before it gives up. Callers that gate a
|
|
34
|
+
* child on work they do *after* capturing its incarnation must add this to the
|
|
35
|
+
* child's own deadline: on win32 the capture shells out to PowerShell and can
|
|
36
|
+
* spend the whole budget before the caller reaches its next step.
|
|
37
|
+
*/
|
|
38
|
+
export declare function processIncarnationProbeBudgetMs(): number;
|
|
32
39
|
export declare function parseProcessIncarnation(value: unknown): ProcessIncarnation | undefined;
|
|
33
40
|
export declare function parseProcessIncarnationJson(raw: string): ProcessIncarnation | undefined;
|
|
34
41
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"processIncarnation.d.ts","sourceRoot":"","sources":["../../../src/proxy/session/processIncarnation.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,2BAA2B,IAAI,CAAA;AAE5C,MAAM,MAAM,kBAAkB,GAC1B,wBAAwB,GACxB,kBAAkB,GAClB,qBAAqB,CAAA;AAEzB;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,2BAA2B,CAAA;IAC3C,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,kBAAkB,CAAA;CAChC;AAED,MAAM,MAAM,uBAAuB,GAAG,OAAO,GAAG,MAAM,GAAG,eAAe,CAAA;AAExE,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,MAAM,uBAAuB,GAC/B;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,kBAAkB,CAAA;CAAE,GACrE;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,eAAe,CAAA;CAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"processIncarnation.d.ts","sourceRoot":"","sources":["../../../src/proxy/session/processIncarnation.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,2BAA2B,IAAI,CAAA;AAE5C,MAAM,MAAM,kBAAkB,GAC1B,wBAAwB,GACxB,kBAAkB,GAClB,qBAAqB,CAAA;AAEzB;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,2BAA2B,CAAA;IAC3C,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,kBAAkB,CAAA;CAChC;AAED,MAAM,MAAM,uBAAuB,GAAG,OAAO,GAAG,MAAM,GAAG,eAAe,CAAA;AAExE,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,MAAM,uBAAuB,GAC/B;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,kBAAkB,CAAA;CAAE,GACrE;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,eAAe,CAAA;CAAE,CAAA;AAa/B;;;;;GAKG;AACH,wBAAgB,+BAA+B,IAAI,MAAM,CAExD;AAuBD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,GAAG,SAAS,CAqBtF;AAED,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAMvF;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,kBAAkB,EACzB,SAAS,EAAE,iBAAiB,GAAG,SAAS,EACxC,aAAa,EAAE,uBAAuB,GAAG,SAAS,GACjD,uBAAuB,CAsBzB;AAkGD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAG3E;AA2BD;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,OAAO,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAazD;AAED,wBAAgB,yBAAyB,IAAI,kBAAkB,CAI9D;AAYD,+EAA+E;AAC/E,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQ9F;AAsDD,mFAAmF;AACnF,wBAAgB,yBAAyB,CAAC,GAAG,SAAc,GAAG,kBAAkB,GAAG,SAAS,CAkB3F;AAED,wEAAwE;AACxE,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,kBAAkB,GAAG,uBAAuB,CAS1F;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAE3E"}
|
|
@@ -28,6 +28,8 @@ export interface SessionLifecycleOptions {
|
|
|
28
28
|
deletingLeaseMs?: number;
|
|
29
29
|
/** Quarantine after retirement so old readers and rolling upgrades can drain. */
|
|
30
30
|
retiredGraceMs?: number;
|
|
31
|
+
/** Lifetime of an unarmed lease; sized by the caller's turn watchdog. */
|
|
32
|
+
unarmedLeaseTtlMs?: number;
|
|
31
33
|
retryBaseMs?: number;
|
|
32
34
|
retryMaxMs?: number;
|
|
33
35
|
deletionTimeoutMs?: number;
|
|
@@ -35,6 +37,9 @@ export interface SessionLifecycleOptions {
|
|
|
35
37
|
pinProvider?: () => readonly TranscriptLocator[];
|
|
36
38
|
/** Bound one complete sweep, including all child deletions. */
|
|
37
39
|
runTimeoutMs?: number;
|
|
40
|
+
/** Test seam. Overrides the resolved @anthropic-ai/claude-agent-sdk module the
|
|
41
|
+
* deletion child imports, so the fenced-delete path can run against a stub. */
|
|
42
|
+
sdkModuleUrl?: string;
|
|
38
43
|
}
|
|
39
44
|
export interface ActiveTranscriptLease {
|
|
40
45
|
token: string;
|
|
@@ -105,7 +110,9 @@ export declare function abandonFork(locator: TranscriptLocator, options?: Sessio
|
|
|
105
110
|
export declare function reconcile(pins: readonly TranscriptLocator[], options?: SessionLifecycleOptions): Promise<ReconcileResult>;
|
|
106
111
|
/** Delete a bounded batch of unpinned retired transcripts through the supported SDK API. */
|
|
107
112
|
export declare function runGc(pins: readonly TranscriptLocator[], options?: SessionLifecycleOptions): Promise<GcResult>;
|
|
113
|
+
/** Keep both ends of child output within the storage budget: the verdict sits
|
|
114
|
+
* at the head, while a Node crash report floods the tail with vendor source. */
|
|
115
|
+
export declare function clipChildOutput(output: string): string;
|
|
108
116
|
export declare function canonicalizeTranscriptLocator(locator: TranscriptLocator): TranscriptLocator;
|
|
109
|
-
/** Resolve a real Node runtime even when Meridian itself is bundled under Bun. */
|
|
110
117
|
export declare function getSessionGcNodeExecutable(): string;
|
|
111
118
|
//# sourceMappingURL=sessionLifecycle.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessionLifecycle.d.ts","sourceRoot":"","sources":["../../src/proxy/sessionLifecycle.ts"],"names":[],"mappings":"AA+BA,OAAO,
|
|
1
|
+
{"version":3,"file":"sessionLifecycle.d.ts","sourceRoot":"","sources":["../../src/proxy/sessionLifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessionStore.d.ts","sourceRoot":"","sources":["../../src/proxy/sessionStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;
|
|
1
|
+
{"version":3,"file":"sessionStore.d.ts","sourceRoot":"","sources":["../../src/proxy/sessionStore.ts"],"names":[],"mappings":"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"}
|
package/dist/server.js
CHANGED
|
@@ -11,10 +11,10 @@ import {
|
|
|
11
11
|
runObserveHook,
|
|
12
12
|
runTransformHook,
|
|
13
13
|
startProxyServer
|
|
14
|
-
} from "./cli-
|
|
14
|
+
} from "./cli-ab7zkp1a.js";
|
|
15
15
|
import"./cli-5jxyma6z.js";
|
|
16
16
|
import"./cli-sry5aqdj.js";
|
|
17
|
-
import"./cli-
|
|
17
|
+
import"./cli-hj61zpt7.js";
|
|
18
18
|
import"./cli-9e5cxp89.js";
|
|
19
19
|
import"./cli-khhjyk04.js";
|
|
20
20
|
import"./cli-vj9cv18n.js";
|
|
@@ -30,4 +30,12 @@ export declare const meridianLogoSvg = "<svg class=\"mh-logo\" width=\"24\" heig
|
|
|
30
30
|
export declare const profileBarCss = "\n .meridian-header {\n position: sticky; top: 0; z-index: 100;\n display: flex; align-items: center; gap: 20px;\n padding: 10px 24px;\n background: rgba(13, 17, 23, 0.92);\n backdrop-filter: blur(12px);\n border-bottom: 1px solid var(--border, #30363d);\n }\n .meridian-header .mh-brand {\n display: flex; align-items: center; gap: 10px;\n text-decoration: none; color: var(--text, #e6edf3);\n }\n .meridian-header .mh-logo { display: block; }\n .meridian-header .mh-name {\n font-size: 15px; font-weight: 700; letter-spacing: 2px;\n text-transform: uppercase;\n }\n .meridian-header .mh-nav { display: flex; align-items: center; gap: 2px; }\n .meridian-header .mh-nav a {\n color: var(--muted, #8b949e); text-decoration: none; font-size: 12px;\n font-weight: 500; padding: 5px 10px; border-radius: 6px;\n transition: color 0.15s, background 0.15s;\n }\n .meridian-header .mh-nav a:hover { color: var(--text, #e6edf3); background: var(--surface, #161b22); }\n .meridian-header .mh-nav a.active { color: var(--accent, #58a6ff); background: var(--surface, #161b22); }\n .meridian-header .mh-right {\n margin-left: auto; display: flex; align-items: center; gap: 10px;\n }\n .meridian-header .mh-profile {\n display: none; align-items: center; gap: 6px;\n font-size: 11px; font-weight: 500; color: var(--text, #e6edf3);\n padding: 3px 10px; border-radius: 20px;\n background: var(--surface, #161b22); border: 1px solid var(--border, #30363d);\n text-decoration: none; transition: border-color 0.15s;\n }\n .meridian-header .mh-profile:hover { border-color: var(--accent, #58a6ff); }\n .meridian-header .mh-profile.visible { display: inline-flex; }\n .meridian-header .mh-profile .mh-profile-type {\n color: var(--muted, #8b949e); font-size: 10px;\n }\n /* Build chip \u2014 two mutually exclusive states, and the colour is not a\n style choice: \"update available\" is a link to the releases page, so it\n is blue (interactive); \"local/dev build\" is a meta annotation with no\n href, so it is violet. Swapping them would break the DESIGN.md rule. */\n .meridian-header .mh-build {\n display: none; align-items: center; gap: 6px;\n font-size: 11px; font-weight: 500; white-space: nowrap;\n padding: 3px 10px; border-radius: 20px; text-decoration: none;\n transition: background 0.15s;\n }\n .meridian-header .mh-build.visible { display: inline-flex; }\n .meridian-header .mh-build.update {\n color: var(--accent, #58a6ff);\n background: rgba(88,166,255,0.12);\n border: 1px solid rgba(88,166,255,0.35);\n }\n .meridian-header .mh-build.update:hover { background: rgba(88,166,255,0.18); }\n .meridian-header .mh-build.provenance {\n color: var(--accent2, #bc8cff);\n background: rgba(188,140,255,0.12);\n border: 1px solid rgba(188,140,255,0.35);\n cursor: default;\n }\n .meridian-header .mh-status {\n display: inline-flex; align-items: center; gap: 6px;\n font-size: 11px; color: var(--muted, #8b949e); white-space: nowrap;\n }\n .meridian-header .mh-dot {\n width: 8px; height: 8px; border-radius: 50%;\n background: var(--muted, #8b949e); flex-shrink: 0;\n }\n .meridian-header .mh-dot.healthy { background: var(--green, #3fb950); box-shadow: 0 0 6px rgba(63,185,80,0.5); }\n .meridian-header .mh-dot.degraded { background: var(--yellow, #d29922); }\n .meridian-header .mh-dot.unhealthy { background: var(--red, #f85149); }\n @media (max-width: 720px) {\n .meridian-header { gap: 10px; padding: 10px 16px; flex-wrap: wrap; }\n .meridian-header .mh-name { display: none; }\n .meridian-header .mh-status .mh-status-text { display: none; }\n }\n";
|
|
31
31
|
export declare const profileBarHtml = "\n<header class=\"meridian-header\" id=\"meridianHeader\">\n <a class=\"mh-brand\" href=\"/\">\n <svg class=\"mh-logo\" width=\"24\" height=\"24\" viewBox=\"0 0 64 64\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <defs>\n <linearGradient id=\"mhGrad\" x1=\"32\" y1=\"4\" x2=\"32\" y2=\"60\" gradientUnits=\"userSpaceOnUse\">\n <stop stop-color=\"#58a6ff\"/>\n <stop offset=\"1\" stop-color=\"#bc8cff\"/>\n </linearGradient>\n </defs>\n <circle cx=\"32\" cy=\"32\" r=\"25\" stroke=\"url(#mhGrad)\" stroke-width=\"3.5\"/>\n <ellipse cx=\"32\" cy=\"32\" rx=\"10.5\" ry=\"25\" stroke=\"url(#mhGrad)\" stroke-width=\"2.5\" opacity=\"0.8\"/>\n <path d=\"M7 32h50\" stroke=\"url(#mhGrad)\" stroke-width=\"2\" opacity=\"0.4\"/>\n <circle cx=\"32\" cy=\"7\" r=\"4.5\" fill=\"#58a6ff\"/>\n <circle cx=\"32\" cy=\"57\" r=\"4.5\" fill=\"#bc8cff\"/>\n</svg>\n <span class=\"mh-name\">Meridian</span>\n </a>\n <nav class=\"mh-nav\">\n <a href=\"/\" id=\"nav-home\">Home</a>\n <a href=\"/telemetry\" id=\"nav-telemetry\">Telemetry</a>\n <a href=\"/profiles\" id=\"nav-profiles\">Profiles</a>\n <a href=\"/settings\" id=\"nav-settings\">Settings</a>\n <a href=\"/plugins\" id=\"nav-plugins\">Plugins</a>\n </nav>\n <div class=\"mh-right\">\n <a class=\"mh-build\" id=\"mhBuild\" target=\"_blank\" rel=\"noopener\"></a>\n <a class=\"mh-profile\" id=\"mhProfile\" href=\"/\" title=\"Active profile \u2014 switch from the home page\"></a>\n <span class=\"mh-status\" id=\"mhStatus\"><span class=\"mh-dot\" id=\"mhDot\"></span><span class=\"mh-status-text\" id=\"mhStatusText\"></span></span>\n </div>\n</header>\n";
|
|
32
32
|
export declare const profileBarJs = "\n(function() {\n var profileChip = document.getElementById('mhProfile');\n var buildChip = document.getElementById('mhBuild');\n var statusDot = document.getElementById('mhDot');\n var statusText = document.getElementById('mhStatusText');\n\n // Highlight active nav link\n var path = location.pathname;\n var navLinks = document.querySelectorAll('.mh-nav a');\n navLinks.forEach(function(a) {\n if (a.getAttribute('href') === path || (path === '/telemetry' && a.id === 'nav-telemetry') || (path === '/' && a.id === 'nav-home')) {\n a.classList.add('active');\n }\n });\n\n function esc(s) { var d = document.createElement('div'); d.textContent = s; return d.innerHTML; }\n\n // Build provenance chip. Hidden entirely for a current npm install, which\n // is the case that needs no comment.\n function renderBuild(build) {\n if (!buildChip) return;\n if (!build) { buildChip.className = 'mh-build'; return; }\n if (build.source !== 'npm') {\n buildChip.textContent = (build.source === 'dev' ? 'dev build' : 'local build') + (build.dirty ? ' *' : '');\n buildChip.removeAttribute('href');\n buildChip.title = 'Not an npm release \u2014 the reported version ' + build.version +\n ' is the tree\\'s last release, not proof of what is running' +\n (build.branch ? '\\nbranch: ' + build.branch : '') +\n (build.sha ? '\\ncommit: ' + build.sha.slice(0, 8) : '') +\n (build.dirty ? '\\nuncommitted changes present' : '');\n buildChip.className = 'mh-build provenance visible';\n return;\n }\n if (build.updateAvailable) {\n buildChip.textContent = build.latest + ' available';\n buildChip.href = 'https://github.com/rynfar/meridian/releases';\n buildChip.title = 'Running ' + build.version + ' \u2014 update with:\\nnpm install -g @rynfar/meridian@latest';\n buildChip.className = 'mh-build update visible';\n return;\n }\n buildChip.className = 'mh-build';\n }\n\n function loadHeader() {\n fetch('/health').then(function(r) { return r.json(); }).then(function(h) {\n var st = h.status === 'healthy' ? 'healthy' : h.status === 'degraded' ? 'degraded' : 'unhealthy';\n statusDot.className = 'mh-dot ' + st;\n statusText.textContent = st === 'healthy' ? 'Operational' : st === 'degraded' ? 'Degraded' : 'Offline';\n renderBuild(h.build);\n }).catch(function() {\n statusDot.className = 'mh-dot unhealthy';\n statusText.textContent = 'Offline';\n });\n\n fetch('/profiles/list').then(function(r) { return r.json(); }).then(function(data) {\n var current = (data.profiles || []).find(function(p) { return p.isActive; });\n if (!current) { profileChip.classList.remove('visible'); return; }\n profileChip.innerHTML = esc(current.id) + ' <span class=\"mh-profile-type\">' + esc(current.type || '') + '</span>';\n profileChip.classList.add('visible');\n }).catch(function() {});\n }\n\n loadHeader();\n setInterval(loadHeader, 10000);\n // Pages call this after mutating state (e.g. switching the active profile)\n // so the header chip updates immediately instead of on the next poll.\n window.meridianHeaderRefresh = loadHeader;\n})();\n";
|
|
33
|
+
/** Native desktop chrome: system appearance with the canonical Meridian hues.
|
|
34
|
+
* Web pages continue using themeCss and the shared profile header above. */
|
|
35
|
+
export declare const desktopThemeCss = "\n :root {\n color-scheme: light dark;\n --bg: #f4f5f7; --surface: #ffffff; --surface2: #edeff2;\n --border: #dde0e5; --text: #23272e; --muted: #69717e;\n --accent: #176bce; --accent2: #8250b5;\n --green: #237c40; --yellow: #976400; --red: #ca3b36;\n --sidebar: #e9edf1; --control: #ffffff; --control-border: #d0d5dc;\n }\n @media (prefers-color-scheme: dark) {\n :root {\n --bg: #0d1117; --surface: #161b22; --surface2: #1c2128;\n --border: #30363d; --text: #e6edf3; --muted: #8b949e;\n --accent: #58a6ff; --accent2: #bc8cff;\n --green: #3fb950; --yellow: #d29922; --red: #f85149;\n --sidebar: #161b22; --control: #242b35; --control-border: #39424e;\n }\n }\n body { background: var(--bg); }\n html.native-glass body { background: transparent; }\n";
|
|
36
|
+
export declare const desktopWindowColors: {
|
|
37
|
+
readonly transparent: "#00000000";
|
|
38
|
+
readonly dark: "#0d1117";
|
|
39
|
+
readonly light: "#f4f5f7";
|
|
40
|
+
};
|
|
33
41
|
//# sourceMappingURL=profileBar.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profileBar.d.ts","sourceRoot":"","sources":["../../src/telemetry/profileBar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,QAAQ,6gDAwCpB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,syBAYrB,CAAA;AAEP,eAAO,MAAM,aAAa,ioHAgFzB,CAAA;AAED,eAAO,MAAM,cAAc,ypDAmB1B,CAAA;AAED,eAAO,MAAM,YAAY,4pGAqExB,CAAA"}
|
|
1
|
+
{"version":3,"file":"profileBar.d.ts","sourceRoot":"","sources":["../../src/telemetry/profileBar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,QAAQ,6gDAwCpB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,syBAYrB,CAAA;AAEP,eAAO,MAAM,aAAa,ioHAgFzB,CAAA;AAED,eAAO,MAAM,cAAc,ypDAmB1B,CAAA;AAED,eAAO,MAAM,YAAY,4pGAqExB,CAAA;AAED;4EAC4E;AAC5E,eAAO,MAAM,eAAe,wyBAoB3B,CAAA;AAED,eAAO,MAAM,mBAAmB;;;;CAA2E,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rynfar/meridian",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.72.0",
|
|
4
4
|
"description": "Local Anthropic API powered by your Claude Max subscription. One subscription, every agent.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/server.js",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"postbuild": "node scripts/fix-bun-exports.mjs && node --check dist/cli.js && node --check dist/server.js && node --check dist/meridian-v2.js && node --check dist/meridian/index.js && node --check dist/meridian-v2/index.js && node -e \"if(!require('fs').existsSync('dist/proxy/server.d.ts'))process.exit(1)\"",
|
|
26
26
|
"postinstall": "node -e \"try{require('child_process').spawnSync(process.execPath,[require.resolve('@anthropic-ai/claude-code/install.cjs')],{stdio:'inherit'})}catch(e){console.error('[meridian] claude-code postinstall skipped:',e.message)}\"",
|
|
27
27
|
"prepublishOnly": "bun run build",
|
|
28
|
+
"pretest": "tsc --noEmit",
|
|
28
29
|
"test": "bun test --timeout 30000 --path-ignore-patterns '**/*session-store*' --path-ignore-patterns '**/*session-fingerprint-context*' --path-ignore-patterns '**/*priority-routing-integration*' --path-ignore-patterns '**/*proxy-async-ops*' --path-ignore-patterns '**/*models-auth-status*' --path-ignore-patterns '**/*proxy-context-usage-store*' --path-ignore-patterns '**/*proxy-passthrough-thinking*' --path-ignore-patterns '**/*proxy-thinking-setting*' --path-ignore-patterns '**/*session-recovery*' --path-ignore-patterns '**/*models.test*' --path-ignore-patterns '**/*proxy-health-build*' && bun test --timeout 30000 src/__tests__/proxy-async-ops.test.ts && bun test --timeout 30000 src/__tests__/proxy-session-store.test.ts && bun test --timeout 30000 src/__tests__/session-store-pruning.test.ts && bun test --timeout 30000 src/__tests__/proxy-session-store-locking.test.ts && bun test --timeout 30000 src/__tests__/session-fingerprint-context.test.ts && bun test --timeout 30000 src/__tests__/proxy-context-usage-store.test.ts && bun test --timeout 30000 src/__tests__/models-auth-status.test.ts && bun test --timeout 30000 src/__tests__/proxy-passthrough-thinking.test.ts && bun test --timeout 30000 src/__tests__/proxy-session-recovery.test.ts && bun test --timeout 30000 src/__tests__/proxy-thinking-setting.test.ts && bun test --timeout 30000 src/__tests__/models.test.ts && bun test --timeout 30000 src/__tests__/proxy-health-build.test.ts && bun test --timeout 30000 src/__tests__/priority-routing-integration.test.ts",
|
|
29
30
|
"nix:lock": "bun2nix -o bun.nix",
|
|
30
31
|
"typecheck": "tsc --noEmit",
|
|
File without changes
|