@kurrent/kcap 0.11.10 → 0.11.12

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/bin/kcap.js CHANGED
@@ -5,28 +5,11 @@
5
5
  const { execFileSync, spawnSync } = require("child_process");
6
6
  const path = require("path");
7
7
  const fs = require("fs");
8
-
9
- function isMusl() {
10
- if (process.platform !== "linux") return false;
11
- try {
12
- return fs.readFileSync("/usr/bin/ldd", "utf8").includes("musl");
13
- } catch {
14
- try {
15
- return fs.readdirSync("/lib").some((f) => f.startsWith("ld-musl-"));
16
- } catch {
17
- return false;
18
- }
19
- }
20
- }
21
-
22
- const PLATFORM_PACKAGES = {
23
- "darwin-arm64": "@kurrent/kcap-darwin-arm64",
24
- "linux-x64": "@kurrent/kcap-linux-x64",
25
- "linux-arm64": "@kurrent/kcap-linux-arm64",
26
- "linux-musl-x64": "@kurrent/kcap-linux-musl-x64",
27
- "linux-musl-arm64": "@kurrent/kcap-linux-musl-arm64",
28
- "win32-x64": "@kurrent/kcap-win-x64",
29
- };
8
+ // Platform detection + native-binary resolution live in resolve.js — a
9
+ // side-effect-free module shared with refresh.js (which must never require
10
+ // THIS file: during `kcap update`, runUpdate executes before the final
11
+ // module.exports below, so it would see partial exports).
12
+ const { PLATFORM_PACKAGES, platformKey } = require("./resolve");
30
13
 
31
14
  // Resolves the npm dist-tag to install for `kcap update`, based on the
32
15
  // resolved channel reported by `kcap update --check`'s `install_tag` field.
@@ -203,12 +186,11 @@ function printLockedBinaryHelp(globalRoot, onlyIfFound = false) {
203
186
  // runs the update flow), so it's guarded to only run when this file is
204
187
  // executed directly — not when `require()`d (e.g. by the test).
205
188
  if (require.main === module) {
206
- const musl = process.platform === "linux" && isMusl() ? "-musl" : "";
207
- const platformKey = `${process.platform}${musl}-${process.arch}`;
208
- const packageName = PLATFORM_PACKAGES[platformKey];
189
+ const key = platformKey();
190
+ const packageName = PLATFORM_PACKAGES[key];
209
191
 
210
192
  if (!packageName) {
211
- console.error(`Unsupported platform: ${platformKey}`);
193
+ console.error(`Unsupported platform: ${key}`);
212
194
  console.error(`Supported: ${Object.keys(PLATFORM_PACKAGES).join(", ")}`);
213
195
  process.exit(1);
214
196
  }
package/bin/refresh.js CHANGED
@@ -7,8 +7,14 @@
7
7
  // when the package manager allows install scripts to run.
8
8
  // - kcap.js `update` — runs after a user-initiated `kcap update`, which works
9
9
  // even when the package manager blocks postinstall scripts.
10
+ //
11
+ // This file must never require kcap.js: during `kcap update`, runUpdate executes
12
+ // before kcap.js's final module.exports assignment, so it would observe partial
13
+ // exports. Shared platform/binary resolution lives in resolve.js instead.
10
14
 
11
15
  const { spawnSync } = require("child_process");
16
+ const path = require("path");
17
+ const fs = require("fs");
12
18
 
13
19
  // One entry per agent. Order is independent — each refresh is gated by its own
14
20
  // marker via `--if-installed`, which no-ops unless the user has previously
@@ -28,6 +34,11 @@ const REFRESHES = [
28
34
  // from one never prevents the others and never throws to the caller — a failed
29
35
  // refresh must never break `npm install` or report `kcap update` as failed.
30
36
  function runRefreshes(launcherPath) {
37
+ // Point the shipped Claude plugin's MCP entries at the native binary. Runs
38
+ // here because runRefreshes fires at exactly the two moments the plugin dir
39
+ // has just been (re)written by npm: postinstall and `kcap update`.
40
+ patchPluginMcpConfig(launcherPath);
41
+
31
42
  for (const argv of REFRESHES) {
32
43
  try {
33
44
  spawnSync(process.execPath, [launcherPath, ...argv], {
@@ -44,4 +55,96 @@ function runRefreshes(launcherPath) {
44
55
  }
45
56
  }
46
57
 
47
- module.exports = { runRefreshes };
58
+ // ── Claude plugin .mcp.json patch ───────────────────────────────────────────
59
+ //
60
+ // The plugin ships `"command": "kcap"`, which resolves to the node wrapper —
61
+ // one resident Node runtime per MCP server per open Claude session (~25 MB
62
+ // idle each). Rewriting the command to the resolved native binary makes Claude
63
+ // spawn the binary directly. Best-effort: on any failure the shipped value
64
+ // stays in place, which still works via the wrapper.
65
+
66
+ // The servers shipped in the plugin's .mcp.json, keyed by canonical
67
+ // `["mcp", <suffix>]` args. Only these exact name/args pairs are patched —
68
+ // anything else in the file is preserved verbatim.
69
+ const PLUGIN_MCP_SERVERS = {
70
+ "kcap-review": "review",
71
+ "kcap-sessions": "sessions",
72
+ "kcap-flows": "flows",
73
+ "kcap-memory": "memory",
74
+ "kcap-workitems": "workitems",
75
+ "kcap-analytics": "analytics",
76
+ };
77
+
78
+ // A command this patcher may rewrite: the shipped literal "kcap", or an
79
+ // absolute path whose basename is the kcap binary (a previous patch that has
80
+ // gone stale after an npm re-layout). Handles both path flavors so a stale
81
+ // Windows path is still recognized. Anything else is a customization → keep.
82
+ function isPatchableKcapCommand(command) {
83
+ if (command === "kcap") return true;
84
+ if (typeof command !== "string") return false;
85
+ if (!path.posix.isAbsolute(command) && !path.win32.isAbsolute(command)) return false;
86
+ const base = command.split(/[\\/]/).pop().toLowerCase();
87
+ return base === "kcap" || base === "kcap.exe";
88
+ }
89
+
90
+ // Pure: rewrites in place the canonical plugin entries of `cfg` whose command
91
+ // is patchable, returning whether anything changed. Throws on a shape that
92
+ // isn't the plugin config (caller turns that into the single warning).
93
+ function patchPluginMcpServers(cfg, binaryPath) {
94
+ if (!cfg || typeof cfg !== "object" || Array.isArray(cfg)) {
95
+ throw new Error("config is not an object");
96
+ }
97
+ const servers = cfg.mcpServers;
98
+ if (!servers || typeof servers !== "object" || Array.isArray(servers)) {
99
+ throw new Error("mcpServers is not an object");
100
+ }
101
+
102
+ let changed = false;
103
+ for (const [name, suffix] of Object.entries(PLUGIN_MCP_SERVERS)) {
104
+ const entry = servers[name];
105
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) continue;
106
+ if (!Array.isArray(entry.args) || entry.args.length !== 2 ||
107
+ entry.args[0] !== "mcp" || entry.args[1] !== suffix) continue; // customized args → keep
108
+ if (!isPatchableKcapCommand(entry.command)) continue; // customized command → keep
109
+ if (entry.command === binaryPath) continue; // already current
110
+ entry.command = binaryPath;
111
+ changed = true;
112
+ }
113
+ return changed;
114
+ }
115
+
116
+ // Rewrites the plugin's shipped .mcp.json (a sibling `kcap/` dir of the
117
+ // launcher's `bin/`) so Claude spawns the native binary directly. Validates
118
+ // before writing, writes a sibling temp file, then renames atomically — the
119
+ // original survives any pre-rename failure. Never throws; on failure it emits
120
+ // ONE concise warning and leaves the shipped `"command": "kcap"` in place.
121
+ // `binaryPath` is a test seam; real callers let it resolve.
122
+ function patchPluginMcpConfig(launcherPath, binaryPath) {
123
+ let mcpJsonPath;
124
+ try {
125
+ binaryPath = binaryPath || require("./resolve").resolveNativeBinary();
126
+ if (!binaryPath) return; // unsupported platform / package missing — wrapper keeps working
127
+
128
+ mcpJsonPath = path.join(path.dirname(launcherPath), "..", "kcap", ".mcp.json");
129
+ if (!fs.existsSync(mcpJsonPath)) return; // dev checkout / plugin not shipped
130
+
131
+ const cfg = JSON.parse(fs.readFileSync(mcpJsonPath, "utf8"));
132
+ if (!patchPluginMcpServers(cfg, binaryPath)) return; // already patched / nothing canonical
133
+
134
+ const tmp = `${mcpJsonPath}.tmp-${process.pid}-${Date.now()}`;
135
+ try {
136
+ fs.writeFileSync(tmp, JSON.stringify(cfg, null, 2) + "\n");
137
+ fs.renameSync(tmp, mcpJsonPath);
138
+ } catch (e) {
139
+ try { fs.unlinkSync(tmp); } catch {}
140
+ throw e;
141
+ }
142
+ } catch (e) {
143
+ console.warn(
144
+ `kcap: could not point the Claude plugin MCP entries at the native binary` +
145
+ ` (${e && e.message ? e.message : e}); they will keep launching via the node wrapper.`,
146
+ );
147
+ }
148
+ }
149
+
150
+ module.exports = { runRefreshes, patchPluginMcpConfig, patchPluginMcpServers, isPatchableKcapCommand };
package/bin/resolve.js ADDED
@@ -0,0 +1,61 @@
1
+ // Side-effect-free platform/native-binary resolution, shared by kcap.js (the
2
+ // launcher) and refresh.js (postinstall / `kcap update` refresh).
3
+ //
4
+ // This lives in its OWN module — refresh.js must never require kcap.js: during
5
+ // `kcap update`, runUpdate executes BEFORE kcap.js's final module.exports
6
+ // assignment, so a refresh.js → kcap.js require would observe partial exports
7
+ // exactly on that path. Requiring this module has no side effects.
8
+
9
+ const path = require("path");
10
+ const fs = require("fs");
11
+
12
+ function isMusl() {
13
+ if (process.platform !== "linux") return false;
14
+ try {
15
+ return fs.readFileSync("/usr/bin/ldd", "utf8").includes("musl");
16
+ } catch {
17
+ try {
18
+ return fs.readdirSync("/lib").some((f) => f.startsWith("ld-musl-"));
19
+ } catch {
20
+ return false;
21
+ }
22
+ }
23
+ }
24
+
25
+ const PLATFORM_PACKAGES = {
26
+ "darwin-arm64": "@kurrent/kcap-darwin-arm64",
27
+ "linux-x64": "@kurrent/kcap-linux-x64",
28
+ "linux-arm64": "@kurrent/kcap-linux-arm64",
29
+ "linux-musl-x64": "@kurrent/kcap-linux-musl-x64",
30
+ "linux-musl-arm64": "@kurrent/kcap-linux-musl-arm64",
31
+ "win32-x64": "@kurrent/kcap-win-x64",
32
+ };
33
+
34
+ function platformKey() {
35
+ const musl = process.platform === "linux" && isMusl() ? "-musl" : "";
36
+ return `${process.platform}${musl}-${process.arch}`;
37
+ }
38
+
39
+ // Absolute path to the native kcap binary for the current platform, or null
40
+ // when the platform is unsupported, the platform package isn't installed, or
41
+ // the binary file is missing. `basedir` (optional) overrides where module
42
+ // resolution starts — tests point it at a fake package layout; callers inside
43
+ // the real install tree omit it (resolution then starts from this file).
44
+ function resolveNativeBinary(basedir) {
45
+ const packageName = PLATFORM_PACKAGES[platformKey()];
46
+ if (!packageName) return null;
47
+
48
+ let binaryDir;
49
+ try {
50
+ const opts = basedir ? { paths: [basedir] } : undefined;
51
+ binaryDir = path.dirname(require.resolve(`${packageName}/package.json`, opts));
52
+ } catch {
53
+ return null;
54
+ }
55
+
56
+ const ext = process.platform === "win32" ? ".exe" : "";
57
+ const binaryPath = path.join(binaryDir, "bin", `kcap${ext}`);
58
+ return fs.existsSync(binaryPath) ? binaryPath : null;
59
+ }
60
+
61
+ module.exports = { PLATFORM_PACKAGES, isMusl, platformKey, resolveNativeBinary };
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "kcap",
3
- "version": "0.11.10",
3
+ "version": "0.11.12",
4
4
  "description": "Records and visualizes Claude Code sessions via kcap CLI hooks"
5
5
  }
@@ -44,7 +44,10 @@ Once the user has explicitly opted into a flow (see above), pick the `definition
44
44
 
45
45
  For the reserved `spec-review` and `code-review` aliases, reviewer-vendor language is role-bound:
46
46
  pass the one vendor explicitly named as the reviewer, ignore driver-harness mentions, honor
47
- negation, omit the vendor when none is named, and ask when multiple candidates remain. Custom
47
+ negation, omit the vendor when none is named, and ask when multiple candidates remain. Omitting
48
+ `vendor` resolves to the definition's authored vendor when it declares one, then to your saved
49
+ `flows.reviewer_vendor` preference, then (with nothing saved) a `reviewer_vendor_required`
50
+ response — see `review-flows`' "Choosing the reviewer vendor" for the full chain. Custom
48
51
  catalog definitions keep their authored vendors unless an explicit single-participant override is
49
52
  requested; dynamic definitions always carry vendors per participant and reject a top-level override.
50
53
 
@@ -52,12 +55,15 @@ requested; dynamic definitions always carry vendors per participant and reject a
52
55
 
53
56
  Your harness is holding an MCP tool schema it cached before kcap was upgraded, and kcap cannot
54
57
  refresh a schema the harness has already cached. A parameter you cannot see is one you cannot send:
55
- **do not start the flow and then report that the named reviewer ran** — without `vendor` the server
56
- applies its own configured default, which may be a different vendor. Nothing server-side can catch
57
- this for you: an omitted `vendor` is indistinguishable from a caller who deliberately wanted the
58
- default, so the request carries no trace of the name the user asked for. Tell the user to restart
59
- the harness session (or reconnect the `kcap-flows` MCP server) and start a fresh task; start without
60
- `vendor` only if they then explicitly ask for the server default.
58
+ **do not start the flow and then report that the named reviewer ran** — without `vendor` you get
59
+ whatever the flow definition's authored vendor resolves to, or — for a vendor-less definition — an
60
+ automatic retry against your saved `flows.reviewer_vendor` preference, or a
61
+ `reviewer_vendor_required` response if none is saved; none of these is guaranteed to be the vendor
62
+ the user named. Nothing server-side can catch this for you: an omitted `vendor` is indistinguishable
63
+ from a caller who deliberately wants that resolved vendor, so the request carries no trace of the
64
+ name the user asked for. Tell the user to restart the harness session (or reconnect the
65
+ `kcap-flows` MCP server) and start a fresh task; start without `vendor` only if they then
66
+ explicitly ask you to proceed with whatever vendor the definition or saved preference resolves to.
61
67
 
62
68
  Canonical reviewer aliases for reserved review flows: Claude / Claude Code → `claude`; Codex /
63
69
  OpenAI Codex → `codex`; Cursor / cursor-agent → `cursor`; GitHub Copilot / Copilot CLI → `copilot`;
@@ -204,7 +210,7 @@ report completion to user
204
210
 
205
211
  | Tool | Required args | Optional args | When to call |
206
212
  |---|---|---|---|
207
- | `start_flow` | Exactly one of `definition_id` (catalog id, e.g. `spec-review`, `code-review`, or a custom catalog id) or `definition_yaml` (inline dynamic definition — see "Composing a dynamic flow"); plus `target_kind` (what is being worked on: `spec`, `code`, `pr`, `branch`, `file`, etc.), `target_ref` (a path, branch name, or PR URL/number that identifies the target), `target_title` (short human-readable title), `context` (background context: what to focus on, constraints, definition of done) | `vendor` (reserved aliases only — explicit reviewer vendor; omit for server default), `model` (reserved aliases only — explicit reviewer model override; REQUIRES `vendor`, rejected on dynamic/multi-participant starts), `instructions`, `mode` (`context-only` — optional; by default the participant's worktree is mirrored from THIS SESSION's project directory, not from the directory you are working in. Pass `context-only` to opt out and treat the submitted context as authoritative) | Once, at the start of a flow task. |
213
+ | `start_flow` | Exactly one of `definition_id` (catalog id, e.g. `spec-review`, `code-review`, or a custom catalog id) or `definition_yaml` (inline dynamic definition — see "Composing a dynamic flow"); plus `target_kind` (what is being worked on: `spec`, `code`, `pr`, `branch`, `file`, etc.), `target_ref` (a path, branch name, or PR URL/number that identifies the target), `target_title` (short human-readable title), `context` (background context: what to focus on, constraints, definition of done) | `vendor` (reserved aliases only — explicit reviewer vendor; omit to use the definition's authored vendor, or your saved `flows.reviewer_vendor` preference if it declares none), `model` (reserved aliases only — explicit reviewer model override; REQUIRES `vendor`, rejected on dynamic/multi-participant starts), `instructions`, `mode` (`context-only` — optional; by default the participant's worktree is mirrored from THIS SESSION's project directory, not from the directory you are working in. Pass `context-only` to opt out and treat the submitted context as authoritative) | Once, at the start of a flow task. |
208
214
  | `send_to_participant` | `flow_run_id`, `participant` (role name declared in the flow definition's `participants` map; single-participant definitions use `reviewer` — an unknown role is rejected, naming the valid ones), `message` | `instructions`, `async` (defaults to `true`) | After addressing a non-clean result for that role, or to launch a role for the first time. Pass the same `flow_run_id`, the role's name, and the updated message. |
209
215
  | `get_flow_status` | `flow_run_id` | — | Poll or check the current status of a flow run (running, waiting, completed, failed). |
210
216
  | `close_flow` | `flow_run_id` | — | Only after the definition's clean signal — or when abandoning the task early; the run otherwise stays open until closed. |
@@ -47,8 +47,12 @@ Treat the driver harness and reviewer as independent. A request such as "ask Cla
47
47
  selects `vendor: "claude"` even when the current driver is Codex; mentions of the driver do not
48
48
  select a reviewer. Anchor vendor language to the reviewer role ("Claude reviewer", "review with
49
49
  Cursor", "ask Codex for review"), including negation ("not Claude"). If exactly one reviewer
50
- vendor is named, pass it. If none is named, omit `vendor` and let the server's configured default
51
- apply. If multiple reviewer candidates remain after negation, ask the user to choose; never guess.
50
+ vendor is named, pass it. If none is named, omit `vendor`: the flow definition's authored vendor
51
+ applies when it declares one; otherwise your saved `flows.reviewer_vendor` preference is applied
52
+ automatically (the response says so), and with no preference the server returns
53
+ `reviewer_vendor_required` — ask the user which reviewer vendor to use, pass it explicitly, and
54
+ offer to save it with `kcap config set flows.reviewer_vendor <vendor>`. If multiple reviewer
55
+ candidates remain after negation, ask the user to choose; never guess.
52
56
 
53
57
  Canonical reviewer aliases: Claude / Claude Code → `claude`; Codex / OpenAI Codex → `codex`;
54
58
  Cursor / cursor-agent → `cursor`; GitHub Copilot / Copilot CLI → `copilot`; Gemini / Gemini CLI →
@@ -65,16 +69,19 @@ cannot send. kcap cannot refresh a schema the harness has already cached.
65
69
 
66
70
  When that happens and the user has named a reviewer:
67
71
 
68
- - **Do not start the flow and then report that the named reviewer ran.** Without `vendor` the
69
- server applies its own configured default, which may be an entirely different vendor. Claiming
70
- the named reviewer ran when you could not send the parameter is the single failure this
71
- contract exists to prevent.
72
+ - **Do not start the flow and then report that the named reviewer ran.** Without `vendor` you get
73
+ whatever the flow definition's authored vendor resolves to, or — for a vendor-less definition —
74
+ an automatic retry against your saved `flows.reviewer_vendor` preference, or a
75
+ `reviewer_vendor_required` response if none is saved; none of these is guaranteed to be the
76
+ vendor the user named. Claiming the named reviewer ran when you could not send the parameter is
77
+ the single failure this contract exists to prevent.
72
78
  - Tell the user their harness is holding a stale kcap MCP schema, and that the fix is to
73
79
  restart the harness session (or reconnect the `kcap-flows` MCP server) and start a fresh task.
74
- - Start without `vendor` only if the user, having been told, explicitly asks for the server default.
80
+ - Start without `vendor` only if the user, having been told, explicitly asks you to proceed with
81
+ whatever vendor the definition or saved preference resolves to.
75
82
 
76
83
  **Nothing server-side catches this for you.** An omitted `vendor` is indistinguishable from a caller
77
- who deliberately wanted the server default — the request carries no trace of the name the user
84
+ who deliberately wants that resolved vendor — the request carries no trace of the name the user
78
85
  asked for, so there is nothing for the server to reject. The `client_upgrade_required`,
79
86
  `flow_client_protocol_required`, and `flow_client_protocol_unsupported` errors below are separate
80
87
  protections, against *protocol* skew; they do **not** fire on a cached schema that simply omits the
@@ -131,8 +138,9 @@ After applying the role-surface safety gate, if `start_review_flow` / `submit_re
131
138
 
132
139
  - **`400` starting `no_daemon_available:`** — no connected daemon has the repo checked out. Relay the server's remediation verbatim, then act on the part you can: run `kcap daemon start -d` on a machine with the repo cloned (add `--name <new-name>` if the account already runs a daemon elsewhere), or get the repo cloned on a machine that already runs one. **You cannot redirect the flow at another daemon or checkout** — these tools expose no daemon or repo-path parameter. If the server's text suggests passing `daemon_name` / `repo_path`, ignore that part: do not invent those arguments, and do not retry unchanged.
133
140
  - **`400` starting `daemon_outdated:`** — the daemon's kcap is too old to host flow participants. Relay the server error's remediation verbatim — it names the outdated daemon; the fix: update kcap (`npm i -g @kurrent/kcap`), then `kcap daemon restart --name <its-name>` (works for detached and service-managed daemons alike — a raw `daemon stop` deliberately refuses a service-managed one; `kcap daemon status` lists names, and `--when-idle` defers the restart if the daemon is busy).
134
- - **`reviewer_vendor_required`** — no explicit vendor and no server default; ask the user to name a reviewer or have an admin configure `Flows:Review:DefaultVendor`.
141
+ - **`reviewer_vendor_required`** — ask the user to name a reviewer vendor, pass it explicitly, and offer to save it (`kcap config set flows.reviewer_vendor <vendor>`); this appears only when the definition declares no vendor and no preference is saved.
135
142
  - **`reviewer_vendor_unavailable`** — the selected vendor is not installed/certified unattended on an eligible daemon; do not silently fall back to another vendor.
143
+ - **`reviewer_vendor_unresolvable`** — returned from `submit_review_round` on a legacy in-flight run whose pinned definition lost its vendor and has no recorded assignment; close the flow and start a new one.
136
144
  - **`client_upgrade_required`, `flow_client_protocol_required`, or `flow_client_protocol_unsupported`** — update kcap; reserved review aliases fail closed on stale clients.
137
145
  - **`reserved_review_alias_shape`** — an admin changed a reserved alias to an invalid participant shape; restore exactly one participant named `reviewer`.
138
146
  - **`400` starting `participant_unavailable:`** — the reviewer agent died and automatic relaunch is not available yet. Close this flow and start a new one, carrying your context forward; re-submitting will keep failing.
@@ -161,7 +169,7 @@ if findings:
161
169
 
162
170
  | Tool | Required args | Optional args | When to call |
163
171
  |---|---|---|---|
164
- | `start_review_flow` | `kind` (`spec-review`\|`code-review`), `target_kind` (what is being reviewed: `spec`, `code`, `pr`, `branch`, `file`, etc.), `target_ref` (a path, branch name, or PR URL/number that identifies the target), `target_title` (short human-readable title, e.g. spec name or PR title), `context` (background context: what to focus on, constraints, definition of done) | `vendor` (explicit reviewer vendor; omit for server default), `model` (explicit reviewer model override — REQUIRES `vendor`; only pass it when the user named a model), `instructions`, `mode` (`context-only` — optional) | Once, at the start of a review task. |
172
+ | `start_review_flow` | `kind` (`spec-review`\|`code-review`), `target_kind` (what is being reviewed: `spec`, `code`, `pr`, `branch`, `file`, etc.), `target_ref` (a path, branch name, or PR URL/number that identifies the target), `target_title` (short human-readable title, e.g. spec name or PR title), `context` (background context: what to focus on, constraints, definition of done) | `vendor` (explicit reviewer vendor; omit to use the definition's authored vendor, or your saved `flows.reviewer_vendor` preference if it declares none), `model` (explicit reviewer model override — REQUIRES `vendor`; only pass it when the user named a model), `instructions`, `mode` (`context-only` — optional) | Once, at the start of a review task. |
165
173
  | `submit_review_round` | `flow_run_id`, `context` | `instructions` | After addressing findings. Pass the same `flow_run_id` and the updated context. |
166
174
  | `get_review_flow_status` | `flow_run_id` | — | Poll or check the current status of a flow (running, waiting, completed, failed). |
167
175
  | `close_review_flow` | `flow_run_id` | — | Only after the reviewer returns `clean`. |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kurrent/kcap",
3
- "version": "0.11.10",
3
+ "version": "0.11.12",
4
4
  "description": "CLI companion for Kurrent Capacitor — records and visualizes Claude Code sessions",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "repository": {
@@ -14,17 +14,17 @@
14
14
  "postinstall": "node bin/postinstall.js"
15
15
  },
16
16
  "optionalDependencies": {
17
- "@kurrent/kcap-darwin-arm64": "0.11.10",
18
- "@kurrent/kcap-linux-arm64": "0.11.10",
19
- "@kurrent/kcap-linux-musl-arm64": "0.11.10",
20
- "@kurrent/kcap-linux-musl-x64": "0.11.10",
21
- "@kurrent/kcap-linux-x64": "0.11.10",
22
- "@kurrent/kcap-win-x64": "0.11.10"
17
+ "@kurrent/kcap-darwin-arm64": "0.11.12",
18
+ "@kurrent/kcap-linux-arm64": "0.11.12",
19
+ "@kurrent/kcap-linux-musl-arm64": "0.11.12",
20
+ "@kurrent/kcap-linux-musl-x64": "0.11.12",
21
+ "@kurrent/kcap-linux-x64": "0.11.12",
22
+ "@kurrent/kcap-win-x64": "0.11.12"
23
23
  },
24
24
  "files": [
25
25
  "bin/",
26
26
  "kcap/"
27
27
  ],
28
- "kcapReleaseCommit": "bfb7bb27de7ce6fb19e60af548e60f672f1cba23",
29
- "kcapReleaseTag": "v0.11.10"
28
+ "kcapReleaseCommit": "b02e5f0a0e20700edd6787f61704419b78556f30",
29
+ "kcapReleaseTag": "v0.11.12"
30
30
  }