@yugabytedb/meko-mcp 2.0.0 → 2.2.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 +183 -33
- package/assets/hooks-handlers/codex-session-end.sh +13 -0
- package/assets/hooks-handlers/cursor-session-start.sh +19 -1
- package/assets/hooks-handlers/lib/capture-notices.js +321 -0
- package/assets/hooks-handlers/lib/capture-state.js +2079 -0
- package/assets/hooks-handlers/lib/capture-status-cli.js +82 -0
- package/assets/hooks-handlers/lib/capture.js +1653 -225
- package/assets/hooks-handlers/lib/checkpoint-timer.js +455 -50
- package/assets/hooks-handlers/lib/kiro-handler.js +738 -0
- package/assets/hooks-handlers/lib/terminal-handoff.js +418 -0
- package/assets/hooks-handlers/session-end.sh +3 -24
- package/assets/hooks-handlers/session-start.sh +8 -1
- package/assets/hooks-handlers/test_checkpoint_timer.sh +162 -0
- package/assets/scripts/meko-statusline.sh +41 -1
- package/assets/scripts/package-desktop-skill.sh +32 -1
- package/assets/skills/meko-mcp-tools/SKILL.md +90 -137
- package/assets/skills/meko-mcp-tools/references/_sections.md +3 -5
- package/assets/skills/meko-mcp-tools/references/tools-agent-id-conventions.md +31 -28
- package/assets/skills/meko-mcp-tools/references/tools-conversation-dedup.md +5 -7
- package/assets/skills/meko-mcp-tools/references/tools-conversation-reasoning.md +50 -0
- package/assets/skills/meko-mcp-tools/references/tools-cookbook.md +69 -49
- package/assets/skills/meko-mcp-tools/references/tools-datapack-workflow.md +6 -6
- package/assets/skills/meko-mcp-tools/references/tools-known-limitations.md +29 -5
- package/assets/skills/meko-mcp-tools/references/tools-memory-vs-conversation.md +29 -92
- package/assets/skills/meko-mcp-tools/references/tools-overview.md +42 -40
- package/assets/skills/meko-mcp-tools/references/tools-rag-workflow.md +1 -2
- package/assets/skills/meko-mcp-tools/references/tools-troubleshooting.md +18 -11
- package/assets/skills/meko-mcp-tools/references/tools-user-id-conventions.md +10 -9
- package/assets/skills/meko-mcp-tools-desktop/SKILL.md +51 -44
- package/assets/skills/meko-mcp-tools-desktop/desktop/README.md +6 -6
- package/assets/skills/meko-mcp-tools-desktop/references/_sections.md +2 -2
- package/assets/skills/meko-mcp-tools-desktop/references/tools-agent-id-conventions.md +34 -25
- package/assets/skills/meko-mcp-tools-desktop/references/tools-conversation-reasoning.md +50 -0
- package/assets/skills/meko-mcp-tools-desktop/references/tools-cookbook.md +63 -37
- package/assets/skills/meko-mcp-tools-desktop/references/tools-known-limitations.md +4 -4
- package/assets/skills/meko-mcp-tools-desktop/references/tools-memory-vs-conversation.md +19 -22
- package/assets/skills/meko-mcp-tools-desktop/references/tools-overview.md +42 -40
- package/assets/skills/meko-mcp-tools-desktop/references/tools-rag-workflow.md +1 -2
- package/assets/skills/meko-mcp-tools-desktop/references/tools-troubleshooting.md +3 -17
- package/assets/skills/meko-select-datapack-desktop/SKILL.md +31 -21
- package/assets/skills/meko-select-datapack-desktop/references/cookbook.md +8 -8
- package/assets/skills/meko-select-datapack-desktop/references/role-display-future.md +41 -0
- package/assets/skills/meko-select-datapack-desktop/references/troubleshooting.md +1 -1
- package/bin/create-meko-setup.mjs +93 -16
- package/lib/capture-status.mjs +67 -0
- package/lib/clients/aliases.mjs +5 -0
- package/lib/clients/claude-code.mjs +8 -4
- package/lib/clients/claude-desktop.mjs +133 -4
- package/lib/clients/codex.mjs +29 -11
- package/lib/clients/common.mjs +2 -0
- package/lib/clients/cursor.mjs +7 -2
- package/lib/clients/index.mjs +2 -0
- package/lib/clients/kiro.mjs +705 -0
- package/lib/config.mjs +90 -0
- package/lib/detect.mjs +7 -2
- package/lib/installer.mjs +1 -0
- package/lib/migrate/adapters/codex.mjs +490 -0
- package/lib/migrate/id.mjs +28 -3
- package/lib/migrate/orchestrator.mjs +34 -7
- package/lib/migrate.mjs +4 -2
- package/lib/prompt.mjs +17 -2
- package/lib/url-selection.mjs +55 -0
- package/package.json +4 -4
- package/assets/skills/meko-mcp-tools/references/tools-scope-permissions.md +0 -71
- package/assets/skills/meko-mcp-tools-desktop/references/tools-scope-permissions.md +0 -71
package/README.md
CHANGED
|
@@ -1,12 +1,34 @@
|
|
|
1
1
|
# Meko Setup Installer
|
|
2
2
|
|
|
3
|
-
A zero-dependency Node.js CLI that configures [Meko MCP Server](https://mekodata.netlify.app/) for Claude Code, Claude Desktop, Cursor,
|
|
3
|
+
A zero-dependency Node.js CLI that configures [Meko MCP Server](https://mekodata.netlify.app/) for Claude Code, Claude Desktop, Cursor, OpenAI Codex (CLI + Desktop App), and Kiro (IDE + CLI) in one command. It registers MCP server settings, configures hook/runtime environment where supported, installs skills support, and validates the setup.
|
|
4
4
|
|
|
5
5
|
Reduces manual setup to a single command.
|
|
6
6
|
|
|
7
|
+
## What this installer authenticates with
|
|
8
|
+
|
|
9
|
+
The installer configures **API-key authentication only**. Every supported
|
|
10
|
+
client sends `Authorization: Bearer <your-api-key>` on the wire, plus the
|
|
11
|
+
`User-Agent` the Cloud WAF requires. Most adapters store the header value in
|
|
12
|
+
client config. Codex stores `bearer_token_env_var = "MEKO_API_KEY"` and resolves
|
|
13
|
+
the key from its runtime environment; Claude Desktop passes the same variable
|
|
14
|
+
through `mcp-remote` header interpolation.
|
|
15
|
+
|
|
16
|
+
Cloud Meko also accepts a browser **OAuth** flow, but that path is out of scope
|
|
17
|
+
here: you turn it on inside a client's own UI, and it uses no API key. Don't
|
|
18
|
+
configure both against the same client — see [Two authentication
|
|
19
|
+
modes](../README.md#two-authentication-modes--pick-one-dont-mix-them) for the
|
|
20
|
+
comparison and the failure modes, including why OAuth isn't currently usable from
|
|
21
|
+
clients that register a loopback callback.
|
|
22
|
+
|
|
23
|
+
**Note:** The server accepts the key only as `Authorization: Bearer …` on the
|
|
24
|
+
wire. An `API_KEY` or `MEKO_API_KEY` environment variable does nothing unless
|
|
25
|
+
the client config references it. The installer creates that reference for
|
|
26
|
+
Codex and Claude Desktop; installer-managed capture hooks also read
|
|
27
|
+
`MEKO_API_KEY` when they send data directly.
|
|
28
|
+
|
|
7
29
|
## Prerequisites
|
|
8
30
|
|
|
9
|
-
- **Node.js 18 or newer** on your PATH. Get it from [nodejs.org](https://nodejs.org/) or via a version manager (`nvm`, `fnm`, `asdf`). `npx`, which comes bundled with Node, is how you invoke the installer.
|
|
31
|
+
- **Node.js 20.18.1 or newer** on your PATH. Get it from [nodejs.org](https://nodejs.org/) or via a version manager (`nvm`, `fnm`, `asdf`). `npx`, which comes bundled with Node, is how you invoke the installer. (The Claude Desktop `mcp-remote` bridge depends on `undici@^7`, whose every release declares `engines.node >= 20.18.1`; the installer enforces that exact floor so the bridge can start.)
|
|
10
32
|
|
|
11
33
|
## Quick Start
|
|
12
34
|
|
|
@@ -62,7 +84,7 @@ You can also combine both: install via `.mcpb` for the MCP wiring, then run Opti
|
|
|
62
84
|
4. Quit and relaunch Claude Desktop.
|
|
63
85
|
5. Verify in chat: *"Is Claude configured with an MCP Server for Meko?"*
|
|
64
86
|
|
|
65
|
-
Prerequisite: Node 18+ on `PATH` (the bundle launches `npx mcp-remote` under the hood). See [`mcpb/README.md`](../mcpb/README.md) for what's in the bundle.
|
|
87
|
+
Prerequisite: Node 20.18.1+ on `PATH` (the bundle launches `npx mcp-remote` under the hood). See [`mcpb/README.md`](../mcpb/README.md) for what's in the bundle.
|
|
66
88
|
|
|
67
89
|
**Option B — `create-meko-setup` installer:**
|
|
68
90
|
|
|
@@ -98,7 +120,7 @@ Re-run the installer to refresh the bundles when skill content updates; you'll n
|
|
|
98
120
|
# Target two clients in one run:
|
|
99
121
|
npx @yugabytedb/meko-mcp --client claude-code,claude-desktop --local --yes
|
|
100
122
|
|
|
101
|
-
# Target every supported client (claude-code, claude-desktop, cursor):
|
|
123
|
+
# Target every supported client (claude-code, claude-desktop, cursor, codex, kiro):
|
|
102
124
|
npx @yugabytedb/meko-mcp --client all --local --yes
|
|
103
125
|
```
|
|
104
126
|
|
|
@@ -108,7 +130,7 @@ Each client is installed sequentially. A failure on one does not abort the other
|
|
|
108
130
|
|
|
109
131
|
```bash
|
|
110
132
|
npx @yugabytedb/meko-mcp \
|
|
111
|
-
--url https://
|
|
133
|
+
--url https://mcp.mekodata.ai/mcp \
|
|
112
134
|
--api-key "$MEKO_API_KEY" \
|
|
113
135
|
--yes
|
|
114
136
|
```
|
|
@@ -121,7 +143,7 @@ The installer performs up to 5 steps (some are skippable via flags):
|
|
|
121
143
|
|------|--------|------------------------|
|
|
122
144
|
| 1 | Register MCP server | `claude mcp add meko <url> --transport http --scope user` (with `-H "Authorization: Bearer <key>"` for cloud) |
|
|
123
145
|
| 2 | Set hook environment vars | Writes `MEKO_MCP_URL` and `MEKO_API_KEY` into `~/.claude/settings.json` under the `env` key. Also prunes any stale Meko hook entries in `settings.json.hooks` that point at a prior install path (e.g. a previous `npx` cache or homebrew-global copy) so only the current install's hooks fire. |
|
|
124
|
-
| 3 | Register plugin marketplace | `claude plugin marketplace add yugabyte/meko-
|
|
146
|
+
| 3 | Register public plugin marketplace | `claude plugin marketplace add https://github.com/yugabyte/meko-skills.git --scope user` |
|
|
125
147
|
| 4 | Install skills plugin | `claude plugin install meko-agent-skills --scope user` |
|
|
126
148
|
| 5 | Validate setup | Config check via `claude mcp list`, MCP `initialize` handshake, `tools/list` verification, and a canary `datapack_list` call |
|
|
127
149
|
|
|
@@ -159,9 +181,16 @@ The canary used to do a `memory_add` → `memory_get_by_id` → `memory_delete_b
|
|
|
159
181
|
```
|
|
160
182
|
This is **scoped to the Meko server block only** — it affects requests Codex makes to the Meko MCP server and nothing else (other MCP servers, other Codex traffic are untouched). The installer **merges** rather than clobbers: it reads whatever headers you already have — in either the inline `http_headers = { … }` form or the table form `[mcp_servers.meko.http_headers]` — keeps every one of them, and only *adds* a `User-Agent` if you don't already have one (a custom User-Agent is left exactly as you set it). If you had the table form, it's folded into the single inline line so there's never a conflicting duplicate definition. This holds **across a reinstall** too: re-registration deletes and rewrites the whole server block, so the installer snapshots your headers beforehand and merges them back. It **backs up `config.toml` to `config.toml.bak`** before writing. Local installs skip this (no WAF in front of `localhost`). Related: the capture-hook side of the same WAF issue is [#174](https://github.com/yugabyte/meko-mcp-server/issues/174).
|
|
161
183
|
- **No project scope**: Codex has no per-project config. `--scope project --client codex` warns and degrades to user scope.
|
|
162
|
-
- **Auto-capture hooks**:
|
|
184
|
+
- **Auto-capture hooks**: the installer copies the Meko hook scripts to `~/.codex/meko-hooks/hooks-handlers/`, writes Meko lifecycle hooks to `~/.codex/hooks.json` pointing at that copy, and prunes stale Meko hook entries from deleted install paths. The scripts live under `$CODEX_HOME` (not the shipped package) on purpose: under `npx @yugabytedb/meko-mcp` the package unpacks into an ephemeral `~/.npm/_npx/<hash>/` cache dir that npx later garbage-collects, so a `hooks.json` pinned there would become a dangling `bash '<missing>'` and Codex would report `SessionStart hook (failed) — hook exited with code 127`. Copying under `$CODEX_HOME` gives the hook a home-dir-stable target; re-running the installer refreshes the copy and auto-heals any stale npx-pinned entry. `memory_search` still handles recall; capture is driven by the hooks (and, where hooks are unavailable, by AGENTS.md-prompted per-turn `conversation_add_message` posting that the server extracts memories from). Explicit `memory_add` is reserved for the narrow cases — the user says "remember this", a fact lives only in the assistant's output or a tool result, or a negated/corrected fact needs overwriting.
|
|
163
185
|
- **API key storage** (security note): Codex's hooks.json schema rejects a top-level `env` block and provides no per-command env field. The installer writes `MEKO_MCP_URL` and (when supplied) `MEKO_API_KEY` to `~/.codex/meko-env.sh` at mode 0600 (user read/write only); each hook's `command` field sources that file before invoking bash, e.g. `. '/Users/you/.codex/meko-env.sh' && bash '/Users/you/.codex/meko-hooks/hooks-handlers/session-start.sh'`. The key never appears in process arguments, so `ps -ef` from another user can't lift it while a hook is running. Trust boundary is the same as `~/.aws/credentials` or `~/.netrc` — file-system permissions on the user's home directory. If your threat model precludes even that, install for the local Meko URL (no API key prompt), or skip hook installation by deleting the Meko entries from `~/.codex/hooks.json` and removing `~/.codex/meko-env.sh` and `~/.codex/meko-hooks/` after install.
|
|
164
186
|
- **Restart Codex.app** after install so it picks up the new MCP server registration.
|
|
187
|
+
- **Kiro (IDE + `kiro-cli`)** — one install configures both surfaces (they share the same config tree). `$KIRO_HOME` overrides the global root, matching how Kiro resolves every global surface.
|
|
188
|
+
- MCP config: `~/.kiro/settings/mcp.json` or `.kiro/settings/mcp.json`. Registered as a native remote server (`url` + `headers`), never via the `mcp-remote` stdio bridge. Because the file contains the bearer token, the adapter writes and reasserts mode 0600 — see [Kiro notes](#kiro-notes).
|
|
189
|
+
- Skills path: `~/.kiro/skills` or `.kiro/skills`. Kiro implements the same [Agent Skills](https://agentskills.io) standard our skills ship in, so they install by copy with no conversion. Packaged installs copy rather than symlink back into the ephemeral npm cache.
|
|
190
|
+
- Standalone hooks: `~/.kiro/hooks/meko-{session-start,user-prompt-submit,stop}.json` or the project equivalents, covering CLI 3.x and trusted IDE workspaces.
|
|
191
|
+
- Managed CLI 2.x agent: `~/.kiro/agents/meko-default.json` or `.kiro/agents/meko-default.json`, with inline `agentSpawn`, `userPromptSubmit`, and `stop` hooks. The installer preserves the previous `chat.defaultAgent` before selecting it.
|
|
192
|
+
- Stable capture runtime: `~/.kiro/hooks/meko-hooks/hooks-handlers/` or the project equivalent. `kiro-hook-env.json` stores the endpoint and optional API key at mode 0600.
|
|
193
|
+
- Steering file: `~/.kiro/steering/meko.md` or `.kiro/steering/meko.md`. It follows hook capture when the session-start marker is present and falls back to agent-driven persistence only when hooks are disabled, untrusted, or a different CLI 2.x agent is selected. See [Kiro notes](#kiro-notes).
|
|
165
194
|
|
|
166
195
|
## CLI Reference
|
|
167
196
|
|
|
@@ -172,8 +201,8 @@ Usage:
|
|
|
172
201
|
|
|
173
202
|
| Flag | Description | Default |
|
|
174
203
|
|------|-------------|---------|
|
|
175
|
-
| `--client <list>` | Target client(s): one or more of `claude-code`, `claude-desktop`, `cursor`, `codex`. Comma-separated, or `all`. `codex` covers both the OpenAI Codex CLI and the Codex Desktop App (they share `~/.codex/config.toml`). | `claude-code` |
|
|
176
|
-
| `--url <url>` | MCP server URL (from
|
|
204
|
+
| `--client <list>` | Target client(s): one or more of `claude-code`, `claude-desktop`, `cursor`, `codex`, `kiro`. Comma-separated, or `all`. `codex` covers both the OpenAI Codex CLI and the Codex Desktop App (they share `~/.codex/config.toml`); `kiro` covers both the Kiro IDE and `kiro-cli` (they share `~/.kiro/settings/mcp.json`). Aliases: `claude` → `claude-code`, `kiro-cli` / `kiro-ide` → `kiro`. | `claude-code` |
|
|
205
|
+
| `--url <url>` | MCP server URL (from cloud.mekodata.ai > Datapacks > Connect) | Shared existing endpoint, otherwise production; conflicts prompt or require `--url` under `--yes` |
|
|
177
206
|
| `--api-key <key>` | API key for Cloud Meko authentication. If a Cloud `--url` is supplied without this flag, the installer falls back to `$MEKO_API_KEY`, then to an interactive prompt on a TTY. Only fails hard when running under `--yes` or with no TTY attached. | _(interactive prompt or `$MEKO_API_KEY` env)_ |
|
|
178
207
|
| `--local` | Use local Meko at `http://localhost:8000/mcp` (no API key needed) | `false` |
|
|
179
208
|
| `--scope <scope>` | Config scope: `user` or `project` (`claude-desktop` uses user scope config) | `user` |
|
|
@@ -189,6 +218,13 @@ Usage:
|
|
|
189
218
|
| `-h`, `--help` | Show help message | |
|
|
190
219
|
| `-v`, `--version` | Show version | |
|
|
191
220
|
|
|
221
|
+
Capture health flags (durable outbox / recovery — Capture V2):
|
|
222
|
+
|
|
223
|
+
| Flag | Description | Default |
|
|
224
|
+
|------|-------------|---------|
|
|
225
|
+
| `--capture-status` | Report aggregate conversation-capture health from `~/.claude/meko-capture` (or `MEKO_WATERMARK_DIR`). Exit `0` = healthy\|catching_up, `2` = degraded_retrying, `3` = blocked_action_required. | `false` |
|
|
226
|
+
| `--json` | With `--capture-status`, print machine-readable JSON matching the capture-health cache shape. | `false` |
|
|
227
|
+
|
|
192
228
|
Migrate subcommand flags (see [Migrate Existing Data](#migrate-existing-data) below for details):
|
|
193
229
|
|
|
194
230
|
| Flag | Description | Default |
|
|
@@ -338,28 +374,66 @@ memory errs: 0 (failed memory_add calls; re-run with --force to
|
|
|
338
374
|
|
|
339
375
|
## Client Compatibility Matrix
|
|
340
376
|
|
|
341
|
-
| Capability | Claude Code | Claude Desktop | Cursor | Codex (CLI + App) |
|
|
342
|
-
|
|
343
|
-
| One-command install | Yes | Yes | Yes | Yes |
|
|
344
|
-
| MCP server registration | via `claude mcp add` | via `claude_desktop_config.json` merge using `mcp-remote` stdio bridge | via `.cursor/mcp.json` merge | via `codex mcp add` (CLI) or direct TOML write (App-only) |
|
|
345
|
-
| Backup before config write | `.bak` on `~/.claude/settings.json` | `.bak` on `claude_desktop_config.json` | `.bak`
|
|
346
|
-
| Automatic conversation capture | Yes (hooks) | **No** — see [issue #8](https://github.com/amiramm/meko-mcp-server/issues/8) | Yes (native hooks; first SessionStart may pause briefly while creating the Meko conversation) |
|
|
347
|
-
| Automatic memory persistence | Yes (hooks + skill) | Skill only (proactive `memory_add`) | Yes (hooks + skill) |
|
|
348
|
-
| Skill install | Plugin marketplace (automatic) | `.skill` bundle auto-built, user drags into app | Copy into `.cursor/skills` | Copy into `~/.agents/skills/meko-mcp-tools/` |
|
|
349
|
-
| Uninstall | Full automatic | MCP entry removed; skill must be removed manually from app | MCP + hooks + skills cleaned up | MCP entry, skill dir, and AGENTS.md block all cleaned up |
|
|
377
|
+
| Capability | Claude Code | Claude Desktop | Cursor | Codex (CLI + App) | Kiro (IDE + `kiro-cli`) |
|
|
378
|
+
|---|---|---|---|---|---|
|
|
379
|
+
| One-command install | Yes | Yes | Yes | Yes | Yes |
|
|
380
|
+
| MCP server registration | via `claude mcp add` | via `claude_desktop_config.json` merge using `mcp-remote` stdio bridge | via `.cursor/mcp.json` merge | via `codex mcp add` (CLI) or direct TOML write (App-only) | via `~/.kiro/settings/mcp.json` merge (native remote MCP) |
|
|
381
|
+
| Backup before config write | `.bak` on `~/.claude/settings.json` | `.bak` on `claude_desktop_config.json` | No `.bak` — additive JSON writes preserve unrelated MCP servers, hooks, and settings | `.bak` on `~/.codex/config.toml` and `~/.codex/AGENTS.md` | No `.bak` — the write is an additive merge that preserves other `mcpServers` entries |
|
|
382
|
+
| Automatic conversation capture | Yes (hooks) | **No** — see [issue #8](https://github.com/amiramm/meko-mcp-server/issues/8) | Yes (native hooks; first SessionStart may pause briefly while creating the Meko conversation) | Yes (hooks) — `SessionStart` / `PreCompact` / `SessionEnd` written to `~/.codex/hooks.json`; the AGENTS.md block provides fallback instructions when hooks are unavailable | Yes — inline CLI 2.x plus standalone CLI 3.x/IDE hooks share Capture v2 |
|
|
383
|
+
| Automatic memory persistence | Yes (hooks + skill) | Skill only (proactive `memory_add`) | Yes (hooks + skill) | Hooks + skill; AGENTS.md fallback when hooks are unavailable | Hooks + skill; conditional steering fallback when the hook marker is absent |
|
|
384
|
+
| Skill install | Plugin marketplace (automatic) | `.skill` bundle auto-built, user drags into app | Copy into `.cursor/skills` | Copy into `~/.agents/skills/meko-mcp-tools/` | Copy into `~/.kiro/skills/` (native Agent Skills format) |
|
|
385
|
+
| Uninstall | Full automatic | MCP entry removed; skill must be removed manually from app | MCP + hooks + skills cleaned up | MCP entry, skill dir, and AGENTS.md block all cleaned up | MCP entry plus installer-owned hooks, managed agent, private env, skills, and steering; pending outbox data is preserved |
|
|
386
|
+
| `agent_id` used by skill | `claude_code:<repo>` per project (via SessionStart hook); cross-project facts go to `meko_agent` | `claude_desktop` | `cursor:<repo>` per project (via Cursor hook); cross-project facts go to `meko_agent` | `codex:<repo>` per project (via SessionStart hook); cross-project facts go to `meko_agent` | `kiro:<repo>` per project via hook capture; cross-project facts go to `meko_agent` |
|
|
387
|
+
| Transport | HTTP only | HTTP (or stdio via hand-edited config) | HTTP only | HTTP (Codex's `bearer_token_env_var` model) | HTTP only |
|
|
388
|
+
| Auth model | inline `Authorization: Bearer ...` header | inline header via `mcp-remote` | inline header | MCP server: env-var name reference (`MEKO_API_KEY` exported in shell or via `launchctl setenv`). Hooks: key written to `~/.codex/meko-env.sh` at mode 0600; each hook command sources the file before bash (no env block in Codex's hooks schema; see [Security](#security)). | inline `Authorization: Bearer ...` header (never `mcp-remote` — see note below) |
|
|
389
|
+
| Project scope | Yes (`--scope project`) | No | Yes (`--scope project`) | No (warns and degrades to user scope) | Yes (`--scope project`) |
|
|
390
|
+
| Deferred to a follow-up | — | `.mcpb` Desktop Extension packaging — see [issue #7](https://github.com/amiramm/meko-mcp-server/issues/7) | — | — | Tool-call/hidden-reasoning capture (not exposed by Kiro hook events) |
|
|
350
391
|
|
|
351
392
|
Cursor previously had a hybrid hook mode that also wrote Claude-compatible hooks into `~/.claude/settings.json`. If you used that mode and now see duplicate `claude_code:*` Meko instructions in Cursor, remove the old Meko hook entries from `~/.claude/settings.json` unless you still use them for Claude Code.
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
393
|
+
|
|
394
|
+
### Kiro notes
|
|
395
|
+
|
|
396
|
+
**One adapter, both surfaces.** The Kiro IDE and `kiro-cli` read the same `mcpServers` config and the same skills directories, so `--client kiro` configures both. `kiro-cli` and `kiro-ide` are accepted as aliases. `$KIRO_HOME` is honored for the global config tree, matching how Kiro resolves every global surface.
|
|
397
|
+
|
|
398
|
+
**Never use the `mcp-remote` bridge with Kiro.** Kiro speaks remote MCP natively, so the installer registers `{ url, headers }` directly.
|
|
399
|
+
|
|
400
|
+
What is measured, against `https://mcp.mekodata.ai`:
|
|
401
|
+
|
|
402
|
+
- `mcp-remote@0.1.38` reads no auth env var (its only `process.env` reference is `MCP_REMOTE_CONFIG_DIR`), so `MEKO_API_KEY` is never sent; headers come only from `--header`. It therefore connects unauthenticated and begins OAuth.
|
|
403
|
+
- Run directly, it fails at `registerClient` — the DCR POST — with `HTTP 403: Invalid OAuth error response … Raw body: <html>403 Forbidden</html>`. Its source builds `redirect_uri` as `http://${host}:${callbackPort}${callbackPath}`, defaulting to `localhost` and `/oauth/callback`.
|
|
404
|
+
- Sending mcp-remote's exact registration body to `POST /register` reproduces it, and changing **only** the redirect host fixes it: loopback → `403 text/html` from `server: awselb/2.0`; `https://example.com/...` → `201 application/json` from `server: uvicorn`. So the block is at the AWS load balancer, before the app, and keys on the redirect host — not the scheme (`http://example.com` passes) and not the `client_id` (an unregistered one returns a helpful `400 JSON`).
|
|
405
|
+
- Refused redirect hosts: `localhost`, `127.0.0.1`, `0.0.0.0`, RFC1918, `169.254.169.254`. Accepted: public hosts and private-use schemes. (`[::1]` and `127.1` also pass — the rule is not exhaustive.)
|
|
406
|
+
- **This hits the Kiro IDE too, not just `kiro-cli`.** Both start a `http://localhost:<port>/oauth/callback` server, so OAuth fails identically on both surfaces. Verified against the installed IDE: with the installer's headers its MCP log shows `[meko] Connected`; remove the headers and change nothing else and it logs `HTTP 403 ... Raw body: <html>403 Forbidden</html>`, then closes the connection. Don't assume a GUI client is safe — what matters is the callback it registers, not whether it has a window.
|
|
407
|
+
|
|
408
|
+
Confirmed on `kiro-cli` 2.18.1 itself. Its DCR registration is:
|
|
409
|
+
|
|
410
|
+
```json
|
|
411
|
+
{"client_name":"kiro","redirect_uris":["http://127.0.0.1:56459"],"application_type":"native", ...}
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
so against Cloud Meko it fails with `Dynamic registration failed: Registration failed: HTTP 403 Forbidden`. Its first `POST /mcp` also goes out with **no `User-Agent`**, which trips a second HTML-403 rule independently. With Mode 1 headers and a valid `mko_tkn_…` key it connects and lists all 23 tools — no OAuth, no 403.
|
|
415
|
+
|
|
416
|
+
Both surfaces are verified against Cloud Meko with a real key. On the **Kiro IDE** (1.0.337), the installer's config produces `[meko] Connected` in its `Kiro - MCP Logs` output. On **`kiro-cli`** (2.18.1) the agent enumerates all 23 tools. The steering file is confirmed to reach the model, not just disk: asked with tools disabled what its Meko steering requires, the agent answered that it must call `memory_add` when the user states a durable fact and that this "explicitly overrides the meko-mcp-tools skill", which assumes capture hooks are running.
|
|
417
|
+
|
|
418
|
+
One naming correction worth knowing, since it has caused confusion: **`Q DEV CLI` is not an OAuth client id.** It is the MCP `initialize` handshake's `clientInfo.name` (`"clientInfo":{"name":"Q DEV CLI","version":"1.0.0"}`); the string appears nowhere in the `kiro-cli` binary's OAuth path, and its actual DCR `client_name` is `kiro`. There is nothing named `Q DEV CLI` to allowlist. See [#277](https://github.com/yugabyte/meko-mcp-server/issues/277).
|
|
419
|
+
|
|
420
|
+
Header auth avoids the OAuth path entirely. `installer/test/clients-kiro.test.mjs` guards this.
|
|
421
|
+
|
|
422
|
+
**Two hook generations coexist.** Kiro 2.18.1 CLI 2.x reads lowercase inline hooks from the selected custom agent, while CLI 3.x and IDE 1.x read [standalone PascalCase hooks](https://kiro.dev/docs/hooks/) from `hooks/`. The installer writes both formats and routes them to one handler. It creates a default-like `meko-default` agent for CLI 2.x, records and selects it, and restores the previous `chat.defaultAgent` on uninstall only when `meko-default` is still selected. Existing files at installer-owned names are treated as user-owned collisions and left untouched.
|
|
423
|
+
|
|
424
|
+
The handler captures the exact user prompt exposed by `UserPromptSubmit`/`userPromptSubmit` and the exact final assistant response exposed by `Stop`/`stop`. Kiro does not expose tool calls or hidden reasoning through these events, so those are outside the capture boundary. Inline and standalone hooks may both deliver the same event; prompt hashes and stable turn IDs deduplicate them, including the initial prompt repeated after `agentSpawn`. If another prompt arrives before Stop, the prior turn receives the standard interrupted-response marker.
|
|
425
|
+
|
|
426
|
+
Events are fsynced to a mode-0600 local JSONL journal before delivery. The handler initializes the shared Capture v2 session on spawn/start, launches a non-blocking drain on each Stop, and starts the normal recovery timer. Create/add failures remain queued; acknowledgements advance only through the existing validated Capture v2 protocol. Kiro's `session_id` is preferred; absent that, host PID plus working directory provides correlation. Project ownership is stable as `kiro:<repo>`, and these sessions appear in the normal `--capture-status` health view.
|
|
427
|
+
|
|
428
|
+
IDE workspace hooks run only in trusted workspaces. The installer does not alter Kiro's trust decision. The steering file is therefore conditional: `MEKO_CAPTURE_SESSION_STARTED` means hooks are active and normal capture rules apply; without it, hooks may be disabled or untrusted, or CLI 2.x may be using another agent, so steering asks the agent to persist turns proactively. The file carries a `Managed by meko installer` marker and is removed only when owned by the installer.
|
|
429
|
+
|
|
430
|
+
Uninstall removes only files carrying installer ownership markers: the three standalone hook files, managed agent, private hook environment/runtime, skills, and steering. It preserves user config and filename collisions, and deliberately leaves the Capture v2 event journal and pending outbox state so recovery can finish after a reinstall.
|
|
357
431
|
|
|
358
432
|
## Cloud vs Local
|
|
359
433
|
|
|
360
434
|
| | Cloud Meko | Local Meko |
|
|
361
435
|
|---|-----------|-----------|
|
|
362
|
-
| **URL** |
|
|
436
|
+
| **URL** | `https://mcp.mekodata.ai/mcp` (or the endpoint shown by cloud.mekodata.ai) | `http://localhost:8000/mcp` |
|
|
363
437
|
| **Authentication** | Requires `--api-key` or `$MEKO_API_KEY` env var | None |
|
|
364
438
|
| **MCP registration** | Includes `-H "Authorization: Bearer <key>"` header | No auth header |
|
|
365
439
|
| **Hook env vars** | Both `MEKO_MCP_URL` and `MEKO_API_KEY` written to settings | Only `MEKO_MCP_URL` written |
|
|
@@ -384,6 +458,9 @@ The installer auto-detects cloud vs local based on the URL: any URL containing `
|
|
|
384
458
|
- **OpenAI Codex (CLI + Desktop App)**
|
|
385
459
|
- MCP-server bearer reference — `~/.codex/config.toml` stores `bearer_token_env_var = "MEKO_API_KEY"`, **not** the key itself. The runtime env (shell rc or `launchctl setenv`) supplies the value.
|
|
386
460
|
- Hook commands — Codex's `~/.codex/hooks.json` schema rejects a top-level `env` block and provides no per-command env field, so the installer writes `MEKO_API_KEY` to `~/.codex/meko-env.sh` at **mode 0600** (user read/write only). Each Meko hook's `command` field sources that file before invoking bash, so the key never appears in process arguments — `ps -ef` from another user can't lift it while the hook runs. Same trust boundary as `~/.aws/credentials` or `~/.netrc` (file-system permissions on the user's home directory). To opt out: install for the local Meko URL (no key prompt), or skip Codex hook installation by deleting the Meko entries from `~/.codex/hooks.json` and removing `~/.codex/meko-env.sh` and `~/.codex/meko-hooks/` after install. The hook scripts themselves are copied to `~/.codex/meko-hooks/hooks-handlers/` (a home-dir-stable location) rather than referenced from the shipped package, so `npx`'s cache garbage-collection can't leave the hook pointing at a deleted script (which would fail with `code 127`).
|
|
461
|
+
- **Kiro (IDE + `kiro-cli`)**
|
|
462
|
+
- API key header — stored in `~/.kiro/settings/mcp.json` (or `.kiro/settings/mcp.json` for project scope) under `mcpServers.<name>.headers.Authorization`. The adapter forces the file to **mode 0600** on registration and removal rewrites.
|
|
463
|
+
- Hook runtime — the endpoint and optional API key are also stored in `kiro-hook-env.json` at **mode 0600** so inline and standalone hooks can authenticate without putting the key in their command strings.
|
|
387
464
|
|
|
388
465
|
**How credentials are protected:**
|
|
389
466
|
|
|
@@ -396,7 +473,7 @@ The installer auto-detects cloud vs local based on the URL: any URL containing `
|
|
|
396
473
|
|
|
397
474
|
**Backups:**
|
|
398
475
|
|
|
399
|
-
|
|
476
|
+
Adapters that use backup-aware merge helpers create a `.bak` copy alongside the original (for example `~/.claude/settings.json.bak`, `~/.codex/config.toml.bak`, or `~/.codex/AGENTS.md.bak`). The support matrix above lists backup behavior per client. Cursor and Kiro use additive JSON writes but do not create `.bak` files; they preserve unrelated settings and user-owned collisions instead.
|
|
400
477
|
|
|
401
478
|
## Upgrading
|
|
402
479
|
|
|
@@ -481,13 +558,13 @@ create-meko-setup --version
|
|
|
481
558
|
|
|
482
559
|
### Rollback
|
|
483
560
|
|
|
484
|
-
|
|
561
|
+
For Claude Code, Claude Desktop, or Codex, restore the relevant `.bak` file written before the change. For example, to restore Claude Code settings:
|
|
485
562
|
|
|
486
563
|
```bash
|
|
487
564
|
cp ~/.claude/settings.json.bak ~/.claude/settings.json
|
|
488
565
|
```
|
|
489
566
|
|
|
490
|
-
See the Security section above for the
|
|
567
|
+
See the Security section above for the exact backup locations. Cursor and Kiro do not write `.bak` files; rerun or uninstall the relevant adapter to remove installer-owned entries while preserving unrelated settings and user-owned files.
|
|
491
568
|
|
|
492
569
|
## Troubleshooting
|
|
493
570
|
|
|
@@ -505,6 +582,31 @@ which claude
|
|
|
505
582
|
claude --version
|
|
506
583
|
```
|
|
507
584
|
|
|
585
|
+
### MCP server `meko` already exists in the user config
|
|
586
|
+
|
|
587
|
+
```
|
|
588
|
+
[1/4] Failed to register MCP server.
|
|
589
|
+
MCP server meko already exists in the user config
|
|
590
|
+
Install for claude-code failed: MCP server registration failed.
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
Claude Code's `claude mcp add` refuses to overwrite an existing registration, so a re-run — or a previous install that failed partway through — aborts at step 1. Remove the stale entry, then re-run the installer:
|
|
594
|
+
|
|
595
|
+
```bash
|
|
596
|
+
claude mcp list # confirm the "meko" entry and which scope it is on
|
|
597
|
+
claude mcp remove meko --scope user # or --scope local / --scope project, matching what `list` showed
|
|
598
|
+
claude mcp list # confirm it is gone
|
|
599
|
+
npx @yugabytedb/meko-mcp@latest # re-run the installer
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
If `claude mcp remove` errors or you want to edit the file directly, the user-scope config lives at `~/.claude.json` — open it, find the `"mcpServers"` block, and delete the `"meko": { ... }` entry. Claude Desktop and Claude Code keep **separate** configs, so a clean Desktop install does not imply a clean Code install.
|
|
603
|
+
|
|
604
|
+
Logs worth collecting before filing a bug:
|
|
605
|
+
|
|
606
|
+
- **Installer log** — `ls -lt ~/.meko*/logs 2>/dev/null; ls -lt /tmp/meko-installer* 2>/dev/null` — share the newest file.
|
|
607
|
+
- **Claude Code MCP log** (macOS) — `ls -lt ~/Library/Caches/claude-cli-nodejs/*/mcp-logs-meko/ 2>/dev/null` — most recent `*.txt` shows the registration attempt and any stderr from the spawned process.
|
|
608
|
+
- **Current config snippet** — `grep -A 20 '"meko"' ~/.claude.json` — confirms what state Claude Code was in when the install was attempted.
|
|
609
|
+
|
|
508
610
|
### Connection refused
|
|
509
611
|
|
|
510
612
|
```
|
|
@@ -533,11 +635,48 @@ The MCP server is enforcing strict Streamable HTTP compliance: clients must adve
|
|
|
533
635
|
|
|
534
636
|
### Authentication failure (401 / 403)
|
|
535
637
|
|
|
536
|
-
|
|
638
|
+
Check the response shape first — it tells you which layer rejected you, and the
|
|
639
|
+
two causes have nothing to do with each other.
|
|
640
|
+
|
|
641
|
+
**A JSON 401 means the server saw your request and refused the credential.**
|
|
642
|
+
|
|
643
|
+
```output
|
|
537
644
|
Server returned 401. Verify your API key is correct and has not expired.
|
|
538
645
|
```
|
|
539
646
|
|
|
540
|
-
|
|
647
|
+
Work through the API-key checks below.
|
|
648
|
+
|
|
649
|
+
**An HTML 403 means a load balancer rejected the request before it reached the
|
|
650
|
+
server.** You'll see an unparseable error, often wrapped in a JSON parse failure
|
|
651
|
+
because the client expected JSON:
|
|
652
|
+
|
|
653
|
+
```output
|
|
654
|
+
HTTP 403: Invalid OAuth error response: SyntaxError: Unexpected token '<',
|
|
655
|
+
"<html>..." is not valid JSON. Raw body: <html>403 Forbidden</html>
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
Three known causes:
|
|
659
|
+
|
|
660
|
+
- **No `User-Agent` header.** The WAF refuses any request without one. Add
|
|
661
|
+
`User-Agent: meko-mcp-installer/1.0`. The installer always does; hand-written
|
|
662
|
+
configs and some native MCP clients don't.
|
|
663
|
+
- **An OAuth callback on a loopback address.** The WAF refuses any `redirect_uri`
|
|
664
|
+
pointing at an internal host, so dynamic client registration fails for any
|
|
665
|
+
client that registers such a callback, including IDEs. Use API-key auth
|
|
666
|
+
instead. Tracked in
|
|
667
|
+
[#277](https://github.com/yugabyte/meko-mcp-server/issues/277).
|
|
668
|
+
- **Message text that looks like a path.** Capture writes containing `../` or
|
|
669
|
+
absolute paths can trip a traversal rule. Tracked in
|
|
670
|
+
[#245](https://github.com/yugabyte/meko-mcp-server/issues/245).
|
|
671
|
+
|
|
672
|
+
**A stale key can surface as the HTML 403, not the JSON 401.** If your key is
|
|
673
|
+
expired, the server returns 401, the client quietly falls back to OAuth, and the
|
|
674
|
+
registration attempt returns the HTML 403. So verify your key before concluding
|
|
675
|
+
that OAuth is broken.
|
|
676
|
+
|
|
677
|
+
API-key checks:
|
|
678
|
+
|
|
679
|
+
- Confirm the API key at cloud.mekodata.ai > Datapacks > Connect.
|
|
541
680
|
- If using `$MEKO_API_KEY` env var, ensure it is exported in the current shell.
|
|
542
681
|
- Confirm the key environment matches the URL: PATs minted on `app.mekodev.com` only validate against `mcp.mekodev.com`; PATs minted on `cloud.mekodata.ai` only validate against `mcp.mekodata.ai`.
|
|
543
682
|
- The installer normalizes API keys (trims surrounding whitespace and a single matching pair of quotes) so a paste with a trailing newline or a literal `"…"` from a `.env` file is fine — but your raw shell variable might still be contaminated. Echo it (`echo "[$MEKO_API_KEY]"`) and check the brackets bracket the key tightly with no extra characters.
|
|
@@ -596,7 +735,7 @@ After the installer writes `claude_desktop_config.json`, **quit and relaunch** C
|
|
|
596
735
|
```json
|
|
597
736
|
"meko": {
|
|
598
737
|
"command": "npx",
|
|
599
|
-
"args": ["-y", "mcp-remote", "<url>", "--transport", "http-only", "--header", "User-Agent:meko-mcp-installer/1.0"]
|
|
738
|
+
"args": ["-y", "mcp-remote@0.1.38", "<url>", "--transport", "http-only", "--header", "User-Agent:meko-mcp-installer/1.0"]
|
|
600
739
|
}
|
|
601
740
|
```
|
|
602
741
|
If you see a `"url"` field at the top level instead, re-run the installer to rewrite it.
|
|
@@ -633,6 +772,17 @@ This reverses installer-managed changes for the selected client:
|
|
|
633
772
|
|
|
634
773
|
Each step is safe if the component was already removed -- the uninstaller logs a warning and continues.
|
|
635
774
|
|
|
775
|
+
### Claude Desktop: which artifact, and why the UI can't remove it
|
|
776
|
+
|
|
777
|
+
Claude Desktop can be connected to Meko in two different ways, and they are removed differently:
|
|
778
|
+
|
|
779
|
+
- **Config-file server** — the `mcpServers.<name>` entry this installer writes into `claude_desktop_config.json`. Claude Desktop shows it with a **"Local dev"** badge; that badge is just Desktop's label for *any* config-file server, **not** a Meko setting. It is **not** removable from the Desktop UI — remove it with the uninstall flow:
|
|
780
|
+
```bash
|
|
781
|
+
npx @yugabytedb/meko-mcp --client claude-desktop --uninstall
|
|
782
|
+
```
|
|
783
|
+
This removes the `mcpServers.<name>` entry (via `removeKeys(..., ['mcpServers.<name>'])`). If you installed under a non-default server name, pass `--name <name>`. Note: running bare `npx @yugabytedb/meko-mcp` re-runs the **install** flow and re-adds the entry — always include `--uninstall`. The uninstall strips only the MCP server entry; the imported Desktop **skill** must still be removed manually via **Settings > Extensions**.
|
|
784
|
+
- **OAuth Connector** — added by URL under **Settings > Connectors**. This is UI-managed and **is** removable directly from the Desktop UI; no CLI needed.
|
|
785
|
+
|
|
636
786
|
Use `--verbose` for detailed output during uninstall:
|
|
637
787
|
|
|
638
788
|
```bash
|
|
@@ -661,7 +811,7 @@ node installer/bin/create-meko-setup.mjs --uninstall --verbose
|
|
|
661
811
|
|
|
662
812
|
### Prerequisites
|
|
663
813
|
|
|
664
|
-
- Node.js >= 18.
|
|
814
|
+
- Node.js >= 20.18.1 (the Claude Desktop `mcp-remote` bridge's `undici@^7` dependency requires it; `util.parseArgs` and `node:test` are also used)
|
|
665
815
|
- No `npm install` needed -- zero external dependencies
|
|
666
816
|
|
|
667
817
|
### Project Structure
|
|
@@ -714,7 +864,7 @@ npm run test:integration
|
|
|
714
864
|
|
|
715
865
|
# Cloud round-trip tests (opt-in; regression coverage for MEKO-20).
|
|
716
866
|
# Requires credentials in the shell:
|
|
717
|
-
export MEKO_TEST_CLOUD_URL=https
|
|
867
|
+
export MEKO_TEST_CLOUD_URL=https://mcp.mekodata.ai/mcp
|
|
718
868
|
export MEKO_TEST_API_KEY=<your-cloud-api-key>
|
|
719
869
|
npm run test:integration:cloud
|
|
720
870
|
|
|
@@ -740,7 +890,7 @@ branch.
|
|
|
740
890
|
### Design Principles
|
|
741
891
|
|
|
742
892
|
- **Zero external dependencies** -- Node.js built-ins only (`fs`, `path`, `readline`, `child_process`, `url`, `http`, `https`, `os`, `node:test`, `node:assert`), matching the pattern of `capture.js`.
|
|
743
|
-
- **Non-destructive** --
|
|
893
|
+
- **Non-destructive** -- Preserves unrelated settings and user-owned files, and creates `.bak` backups where the client adapter supports them (see the support matrix).
|
|
744
894
|
- **Additive merges** -- New env vars are added without overwriting existing unrelated keys.
|
|
745
895
|
- **Graceful failures** -- Non-critical errors (plugin already exists) warn and continue; only missing prerequisites cause hard failures.
|
|
746
896
|
- **API key safety** -- Never logged, always redacted in output.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# Codex SessionEnd hook.
|
|
4
|
+
#
|
|
5
|
+
# Codex caps SessionEnd hooks at three seconds. The foreground invocation
|
|
6
|
+
# therefore enqueues via the shared terminal-handoff worker and exits
|
|
7
|
+
# immediately with `{}`. The worker drains lifecycle=closing and may retry
|
|
8
|
+
# until MEKO_WORKER_MAX_AGE_SECONDS, leaving the outbox pending afterward.
|
|
9
|
+
|
|
10
|
+
set -u
|
|
11
|
+
|
|
12
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
13
|
+
exec node "$SCRIPT_DIR/lib/terminal-handoff.js" enqueue
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
# Cursor native SessionStart hook. Cursor only documents context injection from
|
|
4
4
|
# SessionStart, so this wrapper returns the Meko context synchronously.
|
|
5
|
+
# Also spawns the checkpoint/recovery daemon (same as Claude/Codex) so Cursor
|
|
6
|
+
# sessions get live checkpoints and participate in self-draining recovery.
|
|
5
7
|
|
|
6
8
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
7
9
|
|
|
@@ -39,4 +41,20 @@ load_cursor_hook_env() {
|
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
load_cursor_hook_env
|
|
42
|
-
|
|
44
|
+
|
|
45
|
+
HOOK_INPUT="$(cat)"
|
|
46
|
+
TRANSCRIPT_PATH="$(printf '%s' "$HOOK_INPUT" | node -e '
|
|
47
|
+
const d = JSON.parse(require("fs").readFileSync(0,"utf-8"));
|
|
48
|
+
const p = d.transcript_path || (d.hookSpecificInput||{}).transcript_path || "";
|
|
49
|
+
process.stdout.write(p);
|
|
50
|
+
' 2>/dev/null)"
|
|
51
|
+
|
|
52
|
+
if [ -n "$TRANSCRIPT_PATH" ]; then
|
|
53
|
+
MEKO_LOG_DIR="${MEKO_WATERMARK_DIR:-$HOME/.claude/meko-capture}"
|
|
54
|
+
mkdir -p "$MEKO_LOG_DIR"
|
|
55
|
+
nohup node "$SCRIPT_DIR/lib/checkpoint-timer.js" "$TRANSCRIPT_PATH" \
|
|
56
|
+
</dev/null >/dev/null 2>>"$MEKO_LOG_DIR/timer.log" &
|
|
57
|
+
disown 2>/dev/null || true
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
printf '%s' "$HOOK_INPUT" | MEKO_HOOK_CLIENT=cursor node "$SCRIPT_DIR/lib/capture.js" session-start
|