@rockhopper-co/mcp-server 0.6.0 → 0.8.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +156 -1
  2. package/README.md +57 -10
  3. package/dist/api-client.d.ts +67 -5
  4. package/dist/api-client.d.ts.map +1 -1
  5. package/dist/api-client.js +143 -19
  6. package/dist/api-client.js.map +1 -1
  7. package/dist/auth/device-grant-client.d.ts +80 -0
  8. package/dist/auth/device-grant-client.d.ts.map +1 -0
  9. package/dist/auth/device-grant-client.js +140 -0
  10. package/dist/auth/device-grant-client.js.map +1 -0
  11. package/dist/auth/resolve-auth.d.ts +52 -0
  12. package/dist/auth/resolve-auth.d.ts.map +1 -0
  13. package/dist/auth/resolve-auth.js +100 -0
  14. package/dist/auth/resolve-auth.js.map +1 -0
  15. package/dist/auth/token-store.d.ts +51 -0
  16. package/dist/auth/token-store.d.ts.map +1 -0
  17. package/dist/auth/token-store.js +98 -0
  18. package/dist/auth/token-store.js.map +1 -0
  19. package/dist/cli.js +68 -10
  20. package/dist/cli.js.map +1 -1
  21. package/dist/correlation.d.ts +9 -0
  22. package/dist/correlation.d.ts.map +1 -0
  23. package/dist/correlation.js +26 -0
  24. package/dist/correlation.js.map +1 -0
  25. package/dist/logger.d.ts +42 -0
  26. package/dist/logger.d.ts.map +1 -0
  27. package/dist/logger.js +159 -0
  28. package/dist/logger.js.map +1 -0
  29. package/dist/prompts/index.d.ts.map +1 -1
  30. package/dist/prompts/index.js +20 -9
  31. package/dist/prompts/index.js.map +1 -1
  32. package/dist/resources/changes.d.ts.map +1 -1
  33. package/dist/resources/changes.js +8 -2
  34. package/dist/resources/changes.js.map +1 -1
  35. package/dist/resources/orchestration-guide.md +1 -1
  36. package/dist/server.d.ts.map +1 -1
  37. package/dist/server.js +38 -1
  38. package/dist/server.js.map +1 -1
  39. package/dist/tools/search.d.ts.map +1 -1
  40. package/dist/tools/search.js +113 -20
  41. package/dist/tools/search.js.map +1 -1
  42. package/dist/tools/write-files.js +4 -4
  43. package/dist/tools/write-files.js.map +1 -1
  44. package/dist/tools/write-reviews.d.ts.map +1 -1
  45. package/dist/tools/write-reviews.js +3 -1
  46. package/dist/tools/write-reviews.js.map +1 -1
  47. package/dist/types.d.ts +23 -1
  48. package/dist/types.d.ts.map +1 -1
  49. package/dist/zod-schemas.d.ts +63 -0
  50. package/dist/zod-schemas.d.ts.map +1 -0
  51. package/dist/zod-schemas.js +62 -0
  52. package/dist/zod-schemas.js.map +1 -0
  53. package/package.json +13 -6
package/CHANGELOG.md CHANGED
@@ -4,7 +4,162 @@ All notable changes to this project are documented here. Follows
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
5
5
  [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
- ## [0.5.0] — 2026-05-12
7
+ ## [Unreleased]
8
+
9
+ ### Added
10
+ - **Local rotating diagnostic logfile (KI-225).** The server now writes a
11
+ local diagnostic log to `~/.rockhopper/mcp-server/` (rotated via
12
+ `pino-roll`, ~5 MB × 5 files). It captures request latency plus the
13
+ client-side failures the backend never sees — network-unreachable
14
+ (`api_unreachable`), local auth rejection (`auth_failed`), response schema
15
+ drift (`schema_validation_failed`), per-tool-call timing (`tool_call` /
16
+ `tool_call_failed`), and uncaught crashes (`uncaught_exception` /
17
+ `unhandled_rejection`). Every line auto-carries the Phase 1.1
18
+ `correlationId`.
19
+ - **File only — never stdout** (stdout is the MCP stdio transport). On any
20
+ failure to open the file, logging degrades to a no-op; the server never
21
+ crashes and never writes to stdout.
22
+ - **No remote transmission.** The file stays on the customer's machine and
23
+ can be handed to support.
24
+ - **Redacted.** Tokens, `Authorization` headers, request/response bodies,
25
+ tool arguments, and cell data are never logged — only event, method, URL
26
+ pathname (no query), status, durationMs, tool name, correlationId,
27
+ version, and error type/message.
28
+ - Configurable via `ROCKHOPPER_MCP_LOG_DIR` / `ROCKHOPPER_MCP_LOG_LEVEL`;
29
+ disable with `ROCKHOPPER_MCP_LOG_DISABLE`.
30
+
31
+ ### Fixed
32
+ - **`get_cell_history`, `resolve_comment`, and `rename_file` no longer
33
+ render `undefined` for every field (KI-096).** Diagnosis revealed the
34
+ formatters were correct — the backend was returning the wrong shape
35
+ on all three endpoints. Backend PR
36
+ [#478](https://github.com/Rockhopper-Co/backend/pull/478) fixed the
37
+ shapes; this PR adopts them:
38
+ - `getCellHistory` passes `?format=mcp` to opt into the backend's
39
+ normalized projection (`{versionId, value, changedBy, changedAt}`).
40
+ Default `format` preserves the raw-CTE shape the frontend cell-
41
+ history popover consumes — we never call that path.
42
+ - `resolveComment` + `updateEnrolledFile` continue to call the same
43
+ URLs but now receive the updated `FileChat` / `EnrolledFile` entity
44
+ (was TypeORM `UpdateResult`).
45
+ - `CellHistoryEntry.versionId` retyped `number` → `string` (was a
46
+ contributing root cause of the `Version undefined` symptom — the
47
+ backend's semver string never coerced to the declared numeric type).
48
+ - **`api-client.ts`: zod-parse opt-in for response validation
49
+ (KI-096).** `request<T>(path, init?, responseSchema?)` now accepts an
50
+ optional zod schema; when supplied, the response is parsed with
51
+ `safeParse` and any drift throws a useful diagnostic
52
+ (`Rockhopper API response failed schema check at <path>: <field> —
53
+ <message>`) instead of silently rendering `undefined` in formatters.
54
+ Three call sites opt in: `getCellHistory`, `resolveComment`,
55
+ `updateEnrolledFile`. Other methods stay unchanged; a sweep ticket
56
+ can migrate them later. New `src/zod-schemas.ts` module holds the
57
+ per-entity schemas.
58
+
59
+ ### Added
60
+ - **`search_files` `matchIn` parameter.** Optional enum (`name` |
61
+ `comments` | `versions` | `all`); defaults to `name` for back-compat.
62
+ Broadens search past file-name substring into comment text
63
+ (`FileChat.message`) and version descriptions (`FileVersion.description`).
64
+ Backed by [backend PR #472](https://github.com/Rockhopper-Co/backend/pull/472)
65
+ / ENG-1383; behavior available once that merges. Closes KI-080.
66
+ - **OAuth device-grant flow (RFC 8628) as default auth.** First launch
67
+ with no `ROCKHOPPER_TOKEN` env var now prints a verification code +
68
+ URL to stderr, polls the backend's `/auth/device/{code,token}`
69
+ endpoints, and persists the resulting bearer token in the OS keychain
70
+ (Keychain on macOS, Credential Manager on Windows, libsecret on
71
+ Linux). Subsequent launches reuse the stored token silently. Tokens
72
+ default to a 60-minute lifetime; on expiry the next launch silently
73
+ re-runs the flow. `ROCKHOPPER_TOKEN` still takes precedence when set
74
+ — PAT path preserved for headless / CI scenarios. Backed by
75
+ [backend PR #473](https://github.com/Rockhopper-Co/backend/pull/473)
76
+ / ENG-1384. Closes KI-081 / ENG-1444.
77
+ - **`get_unattributed_changes` cursor pagination + cap/summary (KI-097).**
78
+ File-wide mode now uses the dedicated paginated backend route
79
+ (`GET /unattributed-changes/paginated/:fileMsId`, added by
80
+ [backend PR #475](https://github.com/Rockhopper-Co/backend/pull/475) /
81
+ KI-102) instead of the legacy unpaginated route. The MCP tool gains an
82
+ optional `cursor` input for round-tripping the backend's cursor.
83
+ Responses are now capped at 200 displayed rows with a summary line
84
+ ("Showing X of Y change(s) on this page (Z total across the file)" +
85
+ top-sheets breakdown) and a pagination hint when more pages or hidden
86
+ rows are available. Audit measured one file at 12.5 MB / 28k rows on
87
+ the old route — context-blowing for AI clients; now bounded under
88
+ the 25k-token MCP limit. Sheet-filter mode (`sheetName` set) is
89
+ unchanged — it stays unpaginated since sheet size inherently bounds
90
+ it. Closes KI-097.
91
+
92
+ ### Changed
93
+ - `ROCKHOPPER_TOKEN` is now **optional** (was required). Unset → OAuth.
94
+ Set → PAT auth path.
95
+ - **`ApiClient.getUnattributedChanges` refactored into two methods**
96
+ (KI-097): `getUnattributedChangesBySheet(fileMsId, sheetName)` for
97
+ the sheet-filtered legacy route, and
98
+ `getUnattributedChangesPaginated(fileMsId, cursor?)` for the new
99
+ cursor-paginated route. The old combined method is removed. External
100
+ consumers of `ApiClient` (e.g. `mcp-gateway`) only use `createServer`
101
+ + `ApiClient` as types, not these methods directly, so the rename has
102
+ zero blast radius outside this repo.
103
+
104
+ ### Dependencies
105
+ - **`keytar`** (new runtime dep) — OS-native keychain wrapper. Linux
106
+ requires `libsecret` installed; otherwise the OAuth path errors with
107
+ a clear remediation message and you must fall back to PAT.
108
+
109
+ ### Changed (breaking)
110
+ - **`update_file_description` renamed to `rename_file`.** The tool always
111
+ performed a rename (its `name` input wires to backend
112
+ `PATCH /enrolled-files/:fileMsId`); the old name described non-existent
113
+ "description" semantics. Customers using the npm-installed local server
114
+ should update any tool-name allowlists or prompts referencing
115
+ `update_file_description`. Closes KI-100 / ENG-1439.
116
+
117
+ ### Fixed
118
+ - **`cancel_review` now actually cancels PENDING reviews.** The
119
+ pre-flight status check at `tools/write-reviews.ts` compared against
120
+ the lowercase string `'pending'`, but the backend's
121
+ `ReviewRequestStatus` enum is uppercase (`PENDING`/`APPROVED`/
122
+ `CANCELLED`). The check always failed → `api.cancelReview()` was never
123
+ invoked → every cancel returned "cannot be cancelled — status is
124
+ 'PENDING'". Now uses a defensive `.toUpperCase()` comparison so the
125
+ fix survives future backend casing flips. Closes KI-099 / ENG-1438.
126
+
127
+ ### Internal
128
+ - Test fixtures in `src/__tests__/unit/test-helpers.ts` and
129
+ `src/__tests__/e2e/fixtures/rockhopper-api-fixtures.ts` updated to use
130
+ the real backend's uppercase `ReviewRequestStatus` enum values. Prior
131
+ fixtures used lowercase, which masked KI-099 by being bug-symmetric
132
+ with the broken code.
133
+
134
+ ### Fixed (bundled — same casing-bug class as KI-099)
135
+ - **`file-overview` prompt no longer mis-classifies APPROVED + CANCELLED
136
+ reviews as pending.** `prompts/index.ts:180` filtered with lowercase
137
+ `r.status !== 'approved' && r.status !== 'rejected'`, but
138
+ `ReviewRequestStatus` is uppercase and contains no `'rejected'` value
139
+ (`PENDING`/`APPROVED`/`CANCELLED` only). Result: all non-pending
140
+ reviews were silently counted as pending in the prompt output. Now
141
+ filters with positive intent — `r.status?.toUpperCase() === 'PENDING'`.
142
+ Sibling fix to KI-099; same casing-bug class but in a different
143
+ surface (prompt vs. tool).
144
+
145
+ ### Tooling
146
+ - **`npm run lint` now works.** The `lint` script referenced
147
+ `eslint src/` but `eslint` was missing from `devDependencies`, so any
148
+ fresh install silently produced `sh: eslint: command not found`. Added
149
+ `@eslint/js`, `eslint`, `globals`, and `typescript-eslint` as devDeps
150
+ and shipped a flat-config `eslint.config.js` that mirrors the
151
+ `mcp-gateway` repo's setup. Test files relax
152
+ `@typescript-eslint/no-explicit-any` (mock-stub casts) while production
153
+ code keeps the rule on. Lint is clean across `src/`.
154
+
155
+ ## [0.6.0] — 2026-05-13
156
+
157
+ > Released to npm as `0.6.0`. The release branch was prepared with
158
+ > `package.json` at `0.5.0` (set in [PR #37](https://github.com/Rockhopper-Co/mcp-server/pull/37)),
159
+ > but the `release:minor` script ran on top of that and produced `0.6.0`
160
+ > via `npm version minor`. No code differs between the `0.5.0` manifest
161
+ > and the `0.6.0` published artifact — the bump is purely a version-string
162
+ > change. Content below is what shipped.
8
163
 
9
164
  ### Changed
10
165
  - **`resources/list` no longer enumerates per-file instances.** The 4
package/README.md CHANGED
@@ -6,17 +6,41 @@ MCP (Model Context Protocol) server for Rockhopper. Lets AI tools like Claude, C
6
6
 
7
7
  - Node.js 18+
8
8
  - A Rockhopper account with at least one enrolled file
9
- - A Personal Access Token (PAT) from Rockhopper
9
+ - (Optional) A Personal Access Token only required for headless / CI / scripted setups
10
10
 
11
- ## Setup
11
+ ## Authentication
12
12
 
13
- ### 1. Create a Personal Access Token
13
+ The server supports two auth modes. **OAuth (recommended)** is the default — no token to copy and paste. **PAT** stays available for headless scenarios.
14
14
 
15
- In the Rockhopper web app, go to **Settings > Personal Access Tokens** and create a new token. Choose `read-only` scope for read access or `read-write` if you also want to add comments/reviews.
15
+ ### OAuth (recommended)
16
16
 
17
- Copy the tokenit's shown only once.
17
+ On first launch, the server prints a short verification code to stderr and a URL to visit. Sign in once in your browser the resulting bearer token is stored in your OS keychain (Keychain on macOS, Credential Manager on Windows, libsecret on Linux). Subsequent launches pick the token up silently.
18
18
 
19
- ### 2. Install
19
+ Nothing to configure — just launch the server with no `ROCKHOPPER_TOKEN` set:
20
+
21
+ ```bash
22
+ npx @rockhopper-co/mcp-server
23
+ ```
24
+
25
+ You'll see (on stderr):
26
+
27
+ ```
28
+ Rockhopper — sign in to authorize this MCP client.
29
+ Open: https://app.rockhopper.co/device?user_code=ABCD2345
30
+ (or visit https://app.rockhopper.co/device and enter code: ABCD2345)
31
+ ```
32
+
33
+ Tokens default to a 60-minute lifetime. When yours expires, the next launch silently re-runs the device flow.
34
+
35
+ > **Linux**: requires `libsecret` to be installed (`apt-get install libsecret-1-dev` on Debian/Ubuntu, `dnf install libsecret` on Fedora). If unavailable, fall back to the PAT path below.
36
+
37
+ ### Personal Access Token (headless / CI)
38
+
39
+ For non-interactive setups, generate a PAT in the Rockhopper web app under **Settings > Personal Access Tokens** (`read-only` or `read-write` scope) and set it as `ROCKHOPPER_TOKEN`. PATs take precedence over OAuth — if `ROCKHOPPER_TOKEN` is set, the device-grant flow is skipped.
40
+
41
+ ## Setup
42
+
43
+ ### 1. Install
20
44
 
21
45
  ```bash
22
46
  npm install -g @rockhopper-co/mcp-server
@@ -28,7 +52,7 @@ Or run directly with npx:
28
52
  npx @rockhopper-co/mcp-server
29
53
  ```
30
54
 
31
- ### 3. Configure your AI tool
55
+ ### 2. Configure your AI tool
32
56
 
33
57
  #### Claude Desktop / Claude Code
34
58
 
@@ -41,7 +65,6 @@ Add to your MCP config (`~/.claude/mcp.json` or Claude Desktop settings):
41
65
  "command": "npx",
42
66
  "args": ["-y", "@rockhopper-co/mcp-server"],
43
67
  "env": {
44
- "ROCKHOPPER_TOKEN": "rh_pat_your_token_here",
45
68
  "ROCKHOPPER_API_URL": "https://api.rockhopper.co"
46
69
  }
47
70
  }
@@ -49,6 +72,8 @@ Add to your MCP config (`~/.claude/mcp.json` or Claude Desktop settings):
49
72
  }
50
73
  ```
51
74
 
75
+ Leave `ROCKHOPPER_TOKEN` out to use OAuth (recommended). Set it if you want PAT auth instead.
76
+
52
77
  #### Cursor
53
78
 
54
79
  Add to `.cursor/mcp.json` in your project:
@@ -60,7 +85,6 @@ Add to `.cursor/mcp.json` in your project:
60
85
  "command": "npx",
61
86
  "args": ["-y", "@rockhopper-co/mcp-server"],
62
87
  "env": {
63
- "ROCKHOPPER_TOKEN": "rh_pat_your_token_here",
64
88
  "ROCKHOPPER_API_URL": "https://api.rockhopper.co"
65
89
  }
66
90
  }
@@ -72,8 +96,31 @@ Add to `.cursor/mcp.json` in your project:
72
96
 
73
97
  | Variable | Required | Default | Description |
74
98
  |----------|----------|---------|-------------|
75
- | `ROCKHOPPER_TOKEN` | Yes | — | Personal Access Token (starts with `rh_pat_`) |
99
+ | `ROCKHOPPER_TOKEN` | No | — | Personal Access Token (starts with `rh_pat_`). When unset, OAuth device-grant flow runs on first launch. |
76
100
  | `ROCKHOPPER_API_URL` | No | `https://api.rockhopper.co` | Rockhopper API base URL |
101
+ | `ROCKHOPPER_MCP_LOG_DIR` | No | `~/.rockhopper/mcp-server/` | Directory for the local diagnostic logfile (see below). |
102
+ | `ROCKHOPPER_MCP_LOG_DISABLE` | No | — | Set truthy (`1` / `true`) to disable local diagnostic logging entirely. |
103
+ | `ROCKHOPPER_MCP_LOG_LEVEL` | No | `info` | Diagnostic log level (`fatal` / `error` / `warn` / `info` / `debug` / `trace` / `silent`). |
104
+
105
+ ## Diagnostic Logging
106
+
107
+ The server writes a **local diagnostic logfile** to `~/.rockhopper/mcp-server/`
108
+ (rotated, size-capped at ~5 MB × 5 files, named `mcp-server.<n>.log`). It
109
+ records request latency and the client-side failures the API never sees —
110
+ network-unreachable errors, local auth rejections, response schema drift, and
111
+ uncaught crashes — so you can hand the file to Rockhopper support when
112
+ something misbehaves.
113
+
114
+ - **Local only.** Nothing is transmitted anywhere — the file stays on your
115
+ machine. There is no remote telemetry.
116
+ - **Redacted.** Tokens, the `Authorization` header, request/response bodies,
117
+ tool arguments, and cell data are **never** written. Lines carry only
118
+ event name, HTTP method, URL pathname (no query string), status code,
119
+ duration, tool name, a correlation id, and error type/message.
120
+ - **Configurable.** Point it elsewhere with `ROCKHOPPER_MCP_LOG_DIR`, change
121
+ verbosity with `ROCKHOPPER_MCP_LOG_LEVEL`, or turn it off with
122
+ `ROCKHOPPER_MCP_LOG_DISABLE=1`. If the file can't be opened, logging
123
+ silently disables — it never interferes with the server.
77
124
 
78
125
  ## Postman
79
126
 
@@ -1,21 +1,49 @@
1
- import type { CellHistoryEntry, EnrolledFile, FileChat, FileVersion, ReviewActivity, ReviewRequest, Team, UnattributedChange, UserSummary } from './types.js';
1
+ import type { CellHistoryEntry, EnrolledFile, FileChat, FileVersion, PaginatedUnattributedResponse, ReviewActivity, ReviewRequest, Team, UnattributedChange, UserSummary } from './types.js';
2
2
  export interface ApiClientConfig {
3
3
  baseUrl: string;
4
4
  token: string;
5
+ /**
6
+ * Phase 1.1 / KI-226 — optional fixed correlation id stamped on every
7
+ * outbound request's `X-Correlation-Id` header. The mcp-gateway sets this
8
+ * to forward its own per-request id onto tool-call traffic (it constructs a
9
+ * fresh `ApiClient` per request). Precedence for the header value:
10
+ * an explicit per-call `init.headers['X-Correlation-Id']` >
11
+ * this config value > the per-tool-call ALS id (`getCorrelationId()`) >
12
+ * a freshly minted UUID v4.
13
+ */
14
+ correlationId?: string;
5
15
  }
6
16
  export declare class ApiClient {
7
17
  private readonly baseUrl;
8
18
  private readonly token;
19
+ private readonly correlationId?;
9
20
  constructor(config: ApiClientConfig);
21
+ /**
22
+ * KI-096: optional `responseSchema` validates the response shape with
23
+ * zod. When supplied, drift between backend's actual response and the
24
+ * mcp-server's declared type fails LOUDLY with a `ZodError` (wrapped
25
+ * here in an Error with the path that drifted) instead of silently
26
+ * rendering `undefined` in tool formatters. Opt-in per call site so
27
+ * existing methods stay untouched until a sweep migrates them.
28
+ */
10
29
  private request;
11
30
  getMe(): Promise<UserSummary>;
12
31
  getTeam(teamId: number): Promise<Team>;
13
32
  listEnrolledFiles(params?: {
14
33
  search?: string;
34
+ matchIn?: 'name' | 'comments' | 'versions' | 'all';
15
35
  }): Promise<EnrolledFile[]>;
16
36
  getEnrolledFile(fileMsId: string): Promise<EnrolledFile>;
17
37
  getFileVersions(fileMsId: string): Promise<FileVersion[]>;
18
38
  getFileVersion(versionInternalId: number): Promise<FileVersion>;
39
+ /**
40
+ * KI-096: passes `?format=mcp` to opt into the backend's normalized
41
+ * projection `{versionId, value, changedBy, changedAt}` (added by
42
+ * backend PR #478). Default `format` (omitted) returns the raw CTE
43
+ * row shape the frontend cell-history popover consumes — we never
44
+ * call that path. Zod-parses the response so future drift between
45
+ * backend and mcp-server contracts fails loudly.
46
+ */
19
47
  getCellHistory(fileMsId: string, sheetName: string, cellAddress: string): Promise<CellHistoryEntry[]>;
20
48
  getFileComments(fileMsId: string): Promise<FileChat[]>;
21
49
  getComment(chatId: number): Promise<FileChat>;
@@ -29,6 +57,14 @@ export declare class ApiClient {
29
57
  message: string;
30
58
  versionInternalId: number;
31
59
  }): Promise<FileChat>;
60
+ /**
61
+ * KI-096: zod-parses the response. Backend PR #478 fixed
62
+ * `PATCH /file-chat/:chatId` to return the updated entity (was
63
+ * UpdateResult) AND to persist `resolved` (was silently dropped).
64
+ * The schema check pins both fixes — if either regresses, the parse
65
+ * fails with a clear message instead of the formatter rendering
66
+ * `Comment undefined marked as resolved.`
67
+ */
32
68
  resolveComment(chatId: number): Promise<FileChat>;
33
69
  getReviewsForVersion(versionId: number): Promise<ReviewRequest[]>;
34
70
  getReviewsForLatestVersion(fileMsId: string): Promise<ReviewRequest[]>;
@@ -43,10 +79,28 @@ export declare class ApiClient {
43
79
  approveReview(reviewId: number, body: {
44
80
  notes?: string;
45
81
  }): Promise<ReviewRequest>;
46
- getUnattributedChanges(fileMsId: string, params?: {
47
- sheetName?: string;
48
- status?: string;
49
- }): Promise<UnattributedChange[]>;
82
+ /**
83
+ * Sheet-filtered unattributed changes. Returns ALL rows for the given
84
+ * sheet on the file (no pagination — sheet filter inherently bounds
85
+ * result size). Use this when the caller already knows which sheet to
86
+ * inspect; use {@link getUnattributedChangesPaginated} for the file-wide
87
+ * view.
88
+ */
89
+ getUnattributedChangesBySheet(fileMsId: string, sheetName: string): Promise<UnattributedChange[]>;
90
+ /**
91
+ * Cursor-paginated file-wide unattributed changes (KI-097).
92
+ *
93
+ * Hits the non-shadowable `GET /unattributed-changes/paginated/:fileMsId`
94
+ * route added by backend PR #475 (KI-102). The legacy `:fileMsId/v2`
95
+ * route is shadowed by `:fileMsId/:sheetName` route ordering and returns
96
+ * an empty array; do not call it from here.
97
+ *
98
+ * Pass `cursor` returned by a previous call to fetch the next page.
99
+ * Snapshot TTL is 30 minutes — older cursors cause the backend to return
100
+ * HTTP 410 GONE with `{ resyncRequired: { code: 'SNAPSHOT_EXPIRED' } }`,
101
+ * which surfaces here as a thrown RockhopperApiError.
102
+ */
103
+ getUnattributedChangesPaginated(fileMsId: string, cursor?: string): Promise<PaginatedUnattributedResponse>;
50
104
  createVersion(body: {
51
105
  enrolledFileMsId: string;
52
106
  version: {
@@ -60,6 +114,14 @@ export declare class ApiClient {
60
114
  description: string;
61
115
  }): Promise<FileVersion>;
62
116
  cancelReview(reviewId: number): Promise<ReviewRequest>;
117
+ /**
118
+ * KI-096: zod-parses the response. Backend PR #478 fixed
119
+ * `PATCH /enrolled-files/:fileMsId` to return the updated entity
120
+ * (was UpdateResult typed as Promise<any>). The schema check pins
121
+ * the entity contract — if it regresses, the parse fails with a
122
+ * clear message instead of `rename_file` rendering
123
+ * `File renamed to 'undefined' (id: undefined).`
124
+ */
63
125
  updateEnrolledFile(fileMsId: string, body: {
64
126
  name?: string;
65
127
  }): Promise<EnrolledFile>;
@@ -1 +1 @@
1
- {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
@@ -1,25 +1,97 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { getCorrelationId } from './correlation.js';
3
+ import { log } from './logger.js';
4
+ import { CellHistoryEntryArraySchema, EnrolledFileSchema, FileChatSchema, } from './zod-schemas.js';
1
5
  export class ApiClient {
2
6
  baseUrl;
3
7
  token;
8
+ correlationId;
4
9
  constructor(config) {
5
10
  this.baseUrl = config.baseUrl.replace(/\/+$/, '');
6
11
  this.token = config.token;
12
+ this.correlationId = config.correlationId;
7
13
  }
8
- async request(path, init) {
14
+ /**
15
+ * KI-096: optional `responseSchema` validates the response shape with
16
+ * zod. When supplied, drift between backend's actual response and the
17
+ * mcp-server's declared type fails LOUDLY with a `ZodError` (wrapped
18
+ * here in an Error with the path that drifted) instead of silently
19
+ * rendering `undefined` in tool formatters. Opt-in per call site so
20
+ * existing methods stay untouched until a sweep migrates them.
21
+ */
22
+ async request(path, init, responseSchema) {
9
23
  const url = `${this.baseUrl}${path}`;
10
- const response = await fetch(url, {
11
- ...init,
12
- headers: {
13
- Authorization: `Bearer ${this.token}`,
14
- 'Content-Type': 'application/json',
15
- ...init?.headers,
16
- },
17
- });
24
+ // KI-225: log only the URL pathname (drop the query string) — query may
25
+ // carry search terms / cell refs; it never carries the token (header
26
+ // only), but it's not a safe field to persist.
27
+ const pathname = path.split('?')[0];
28
+ const method = (init?.method ?? 'GET').toUpperCase();
29
+ const start = Date.now();
30
+ let response;
31
+ try {
32
+ response = await fetch(url, {
33
+ ...init,
34
+ headers: {
35
+ Authorization: `Bearer ${this.token}`,
36
+ 'Content-Type': 'application/json',
37
+ // KI-226: trace this request in backend logs. Placed BEFORE the
38
+ // `...init?.headers` spread so a per-call header still wins but the
39
+ // id can't be dropped. Precedence: per-call > config > ALS > mint.
40
+ // Non-sensitive UUID — never co-logged with the bearer token above.
41
+ 'X-Correlation-Id': this.correlationId ?? getCorrelationId() ?? randomUUID(),
42
+ ...init?.headers,
43
+ },
44
+ });
45
+ }
46
+ catch (err) {
47
+ // KI-225: the can't-reach-the-API case — a thrown fetch is a network
48
+ // failure, the class of error that NEVER reaches the backend log.
49
+ log.error({ event: 'api_unreachable', method, path: pathname, durationMs: Date.now() - start, err }, 'api_unreachable');
50
+ throw err;
51
+ }
52
+ const durationMs = Date.now() - start;
18
53
  if (!response.ok) {
54
+ // KI-225: classify auth rejections (401/403) so they're greppable
55
+ // separately from generic HTTP errors.
56
+ const classification = response.status === 401 || response.status === 403
57
+ ? 'auth_failed'
58
+ : 'http_error';
59
+ log.warn({
60
+ event: 'api_request_failed',
61
+ method,
62
+ path: pathname,
63
+ status: response.status,
64
+ durationMs,
65
+ classification,
66
+ }, 'api_request_failed');
19
67
  const body = await response.text().catch(() => '');
20
68
  throw new Error(`Rockhopper API ${response.status}: ${response.statusText} — ${body}`);
21
69
  }
22
- return response.json();
70
+ log.info({ event: 'api_request', method, path: pathname, status: response.status, durationMs }, 'api_request');
71
+ const json = await response.json();
72
+ if (responseSchema) {
73
+ const parsed = responseSchema.safeParse(json);
74
+ if (!parsed.success) {
75
+ // Surface a useful diagnostic — the formatter would otherwise show
76
+ // `undefined`, hiding the contract break. Include the path of the
77
+ // first issue so the cause is obvious from the error message.
78
+ const first = parsed.error.issues[0];
79
+ // KI-225: schema drift is a client-side detection the backend can't
80
+ // see. Log the issue path + message ONLY — never the raw payload
81
+ // (`json`), which may contain file/cell data.
82
+ log.warn({
83
+ event: 'schema_validation_failed',
84
+ endpoint: pathname,
85
+ issue: first?.path.join('.') || '<root>',
86
+ err: first?.message,
87
+ }, 'schema_validation_failed');
88
+ throw new Error(`Rockhopper API response failed schema check at ${path}: ` +
89
+ `${first?.path.join('.') || '<root>'} — ${first?.message} ` +
90
+ `(${parsed.error.issues.length} issue(s) total)`);
91
+ }
92
+ return parsed.data;
93
+ }
94
+ return json;
23
95
  }
24
96
  // --- Users ---
25
97
  async getMe() {
@@ -34,6 +106,8 @@ export class ApiClient {
34
106
  const query = new URLSearchParams();
35
107
  if (params?.search)
36
108
  query.set('search', params.search);
109
+ if (params?.matchIn)
110
+ query.set('matchIn', params.matchIn);
37
111
  const qs = query.toString();
38
112
  return this.request(`/enrolled-files${qs ? `?${qs}` : ''}`);
39
113
  }
@@ -47,9 +121,21 @@ export class ApiClient {
47
121
  async getFileVersion(versionInternalId) {
48
122
  return this.request(`/file-versions/file/version/${versionInternalId}`);
49
123
  }
124
+ /**
125
+ * KI-096: passes `?format=mcp` to opt into the backend's normalized
126
+ * projection `{versionId, value, changedBy, changedAt}` (added by
127
+ * backend PR #478). Default `format` (omitted) returns the raw CTE
128
+ * row shape the frontend cell-history popover consumes — we never
129
+ * call that path. Zod-parses the response so future drift between
130
+ * backend and mcp-server contracts fails loudly.
131
+ */
50
132
  async getCellHistory(fileMsId, sheetName, cellAddress) {
51
- const query = new URLSearchParams({ cell: cellAddress, sheetName });
52
- return this.request(`/file-versions/file/${fileMsId}/cell-history?${query}`);
133
+ const query = new URLSearchParams({
134
+ cell: cellAddress,
135
+ sheetName,
136
+ format: 'mcp',
137
+ });
138
+ return this.request(`/file-versions/file/${fileMsId}/cell-history?${query}`, undefined, CellHistoryEntryArraySchema);
53
139
  }
54
140
  // --- File Chat (Comments) ---
55
141
  async getFileComments(fileMsId) {
@@ -70,11 +156,19 @@ export class ApiClient {
70
156
  body: JSON.stringify(body),
71
157
  });
72
158
  }
159
+ /**
160
+ * KI-096: zod-parses the response. Backend PR #478 fixed
161
+ * `PATCH /file-chat/:chatId` to return the updated entity (was
162
+ * UpdateResult) AND to persist `resolved` (was silently dropped).
163
+ * The schema check pins both fixes — if either regresses, the parse
164
+ * fails with a clear message instead of the formatter rendering
165
+ * `Comment undefined marked as resolved.`
166
+ */
73
167
  async resolveComment(chatId) {
74
168
  return this.request(`/file-chat/${chatId}`, {
75
169
  method: 'PATCH',
76
170
  body: JSON.stringify({ resolved: true }),
77
- });
171
+ }, FileChatSchema);
78
172
  }
79
173
  // --- Reviews ---
80
174
  async getReviewsForVersion(versionId) {
@@ -102,11 +196,33 @@ export class ApiClient {
102
196
  });
103
197
  }
104
198
  // --- Unattributed Changes ---
105
- async getUnattributedChanges(fileMsId, params) {
106
- let path = `/unattributed-changes/${fileMsId}`;
107
- if (params?.sheetName) {
108
- path += `/${params.sheetName}`;
109
- }
199
+ /**
200
+ * Sheet-filtered unattributed changes. Returns ALL rows for the given
201
+ * sheet on the file (no pagination — sheet filter inherently bounds
202
+ * result size). Use this when the caller already knows which sheet to
203
+ * inspect; use {@link getUnattributedChangesPaginated} for the file-wide
204
+ * view.
205
+ */
206
+ async getUnattributedChangesBySheet(fileMsId, sheetName) {
207
+ const path = `/unattributed-changes/${fileMsId}/${encodeURIComponent(sheetName)}`;
208
+ return this.request(path);
209
+ }
210
+ /**
211
+ * Cursor-paginated file-wide unattributed changes (KI-097).
212
+ *
213
+ * Hits the non-shadowable `GET /unattributed-changes/paginated/:fileMsId`
214
+ * route added by backend PR #475 (KI-102). The legacy `:fileMsId/v2`
215
+ * route is shadowed by `:fileMsId/:sheetName` route ordering and returns
216
+ * an empty array; do not call it from here.
217
+ *
218
+ * Pass `cursor` returned by a previous call to fetch the next page.
219
+ * Snapshot TTL is 30 minutes — older cursors cause the backend to return
220
+ * HTTP 410 GONE with `{ resyncRequired: { code: 'SNAPSHOT_EXPIRED' } }`,
221
+ * which surfaces here as a thrown RockhopperApiError.
222
+ */
223
+ async getUnattributedChangesPaginated(fileMsId, cursor) {
224
+ const qs = cursor ? `?cursor=${encodeURIComponent(cursor)}` : '';
225
+ const path = `/unattributed-changes/paginated/${fileMsId}${qs}`;
110
226
  return this.request(path);
111
227
  }
112
228
  // --- Version lifecycle ---
@@ -130,11 +246,19 @@ export class ApiClient {
130
246
  });
131
247
  }
132
248
  // --- File metadata update ---
249
+ /**
250
+ * KI-096: zod-parses the response. Backend PR #478 fixed
251
+ * `PATCH /enrolled-files/:fileMsId` to return the updated entity
252
+ * (was UpdateResult typed as Promise<any>). The schema check pins
253
+ * the entity contract — if it regresses, the parse fails with a
254
+ * clear message instead of `rename_file` rendering
255
+ * `File renamed to 'undefined' (id: undefined).`
256
+ */
133
257
  async updateEnrolledFile(fileMsId, body) {
134
258
  return this.request(`/enrolled-files/${fileMsId}`, {
135
259
  method: 'PATCH',
136
260
  body: JSON.stringify(body),
137
- });
261
+ }, EnrolledFileSchema);
138
262
  }
139
263
  }
140
264
  //# sourceMappingURL=api-client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}