@withpica/mcp-server 2.11.0 → 2.23.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 (96) hide show
  1. package/CHANGELOG.md +639 -1
  2. package/dist/config.d.ts.map +1 -1
  3. package/dist/config.js +3 -2
  4. package/dist/config.js.map +1 -1
  5. package/dist/prompts/index.d.ts +48 -16
  6. package/dist/prompts/index.d.ts.map +1 -1
  7. package/dist/prompts/index.js +320 -607
  8. package/dist/prompts/index.js.map +1 -1
  9. package/dist/tools/agreement-types.d.ts.map +1 -1
  10. package/dist/tools/agreement-types.js +14 -129
  11. package/dist/tools/agreement-types.js.map +1 -1
  12. package/dist/tools/agreements.d.ts.map +1 -1
  13. package/dist/tools/agreements.js +11 -109
  14. package/dist/tools/agreements.js.map +1 -1
  15. package/dist/tools/assets.d.ts.map +1 -1
  16. package/dist/tools/assets.js +17 -257
  17. package/dist/tools/assets.js.map +1 -1
  18. package/dist/tools/audit.d.ts +19 -0
  19. package/dist/tools/audit.d.ts.map +1 -0
  20. package/dist/tools/audit.js +57 -0
  21. package/dist/tools/audit.js.map +1 -0
  22. package/dist/tools/bulk.d.ts +7 -1
  23. package/dist/tools/bulk.d.ts.map +1 -1
  24. package/dist/tools/bulk.js +24 -2
  25. package/dist/tools/bulk.js.map +1 -1
  26. package/dist/tools/credits.d.ts.map +1 -1
  27. package/dist/tools/credits.js +27 -13
  28. package/dist/tools/credits.js.map +1 -1
  29. package/dist/tools/discovery.d.ts.map +1 -1
  30. package/dist/tools/discovery.js +25 -0
  31. package/dist/tools/discovery.js.map +1 -1
  32. package/dist/tools/enrichment.d.ts +47 -0
  33. package/dist/tools/enrichment.d.ts.map +1 -1
  34. package/dist/tools/enrichment.js +416 -19
  35. package/dist/tools/enrichment.js.map +1 -1
  36. package/dist/tools/index.d.ts.map +1 -1
  37. package/dist/tools/index.js +17 -0
  38. package/dist/tools/index.js.map +1 -1
  39. package/dist/tools/labels.d.ts +20 -0
  40. package/dist/tools/labels.d.ts.map +1 -0
  41. package/dist/tools/labels.js +47 -0
  42. package/dist/tools/labels.js.map +1 -0
  43. package/dist/tools/metadata.d.ts.map +1 -1
  44. package/dist/tools/metadata.js +93 -0
  45. package/dist/tools/metadata.js.map +1 -1
  46. package/dist/tools/multimedia.d.ts.map +1 -1
  47. package/dist/tools/multimedia.js +86 -11
  48. package/dist/tools/multimedia.js.map +1 -1
  49. package/dist/tools/notes.d.ts.map +1 -1
  50. package/dist/tools/notes.js +4 -1
  51. package/dist/tools/notes.js.map +1 -1
  52. package/dist/tools/people.d.ts +228 -4
  53. package/dist/tools/people.d.ts.map +1 -1
  54. package/dist/tools/people.js +238 -262
  55. package/dist/tools/people.js.map +1 -1
  56. package/dist/tools/projects.d.ts +1 -0
  57. package/dist/tools/projects.d.ts.map +1 -1
  58. package/dist/tools/projects.js +188 -17
  59. package/dist/tools/projects.js.map +1 -1
  60. package/dist/tools/publishers.d.ts +15 -1
  61. package/dist/tools/publishers.d.ts.map +1 -1
  62. package/dist/tools/publishers.js +43 -9
  63. package/dist/tools/publishers.js.map +1 -1
  64. package/dist/tools/recordings.d.ts +53 -2
  65. package/dist/tools/recordings.d.ts.map +1 -1
  66. package/dist/tools/recordings.js +185 -122
  67. package/dist/tools/recordings.js.map +1 -1
  68. package/dist/tools/recovery-hints.d.ts.map +1 -1
  69. package/dist/tools/recovery-hints.js +49 -0
  70. package/dist/tools/recovery-hints.js.map +1 -1
  71. package/dist/tools/releases.d.ts +19 -1
  72. package/dist/tools/releases.d.ts.map +1 -1
  73. package/dist/tools/releases.js +538 -32
  74. package/dist/tools/releases.js.map +1 -1
  75. package/dist/tools/sessions.d.ts.map +1 -1
  76. package/dist/tools/sessions.js +42 -8
  77. package/dist/tools/sessions.js.map +1 -1
  78. package/dist/tools/settings.d.ts +4 -0
  79. package/dist/tools/settings.d.ts.map +1 -1
  80. package/dist/tools/settings.js +155 -1
  81. package/dist/tools/settings.js.map +1 -1
  82. package/dist/tools/share-links.d.ts.map +1 -1
  83. package/dist/tools/share-links.js +19 -53
  84. package/dist/tools/share-links.js.map +1 -1
  85. package/dist/tools/split-sheets.d.ts.map +1 -1
  86. package/dist/tools/split-sheets.js +3 -42
  87. package/dist/tools/split-sheets.js.map +1 -1
  88. package/dist/tools/team.d.ts.map +1 -1
  89. package/dist/tools/team.js +9 -4
  90. package/dist/tools/team.js.map +1 -1
  91. package/dist/tools/works.d.ts +27 -1
  92. package/dist/tools/works.d.ts.map +1 -1
  93. package/dist/tools/works.js +119 -219
  94. package/dist/tools/works.js.map +1 -1
  95. package/package.json +3 -2
  96. package/server.json +2 -2
package/CHANGELOG.md CHANGED
@@ -11,6 +11,645 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ## [2.23.0] - 2026-04-19
15
+
16
+ ### Added
17
+
18
+ - **ADR-181 Phase 1: `pica_audit_list` ported from `@withpica/mcp-server-settings`
19
+ (ADR-154 F6).** Closes the one trailing-gap tool from the source-merge audit —
20
+ every other tool the three sub-servers exposed was already registered by
21
+ `mcp-server`'s superset. Registered in `lib/services/mcp-scopes.ts`
22
+ `ADMIN_ONLY_TOOLS` alongside the team / org-profile admin operations; the
23
+ `mcp_audit_log` read is org-scoped and matches the existing admin posture
24
+ for `pica_organisation_profile` / `pica_team_list`. Landed in `54ae935d9`
25
+ via PR #50.
26
+ - **ADR-181 Phase 1: bundle-size CI gate per Decision 2.** New
27
+ `scripts/check-mcp-bundle.ts` walks `mcp-server/dist/`, sums byte size
28
+ (excluding source maps), and fails if total > 210 MB (70% × Vercel's
29
+ 300 MB serverless-function cap). Runs on every push / PR that touches
30
+ `mcp-server/**`, `mcp-server-shared/**`, the script, or the workflow
31
+ itself (`.github/workflows/mcp-bundle-size.yml`). `package.json`
32
+ `prepublishOnly` invokes it locally so a bloated bundle can't ship out
33
+ of a developer machine. Current measurement on this branch:
34
+ 0.79 MB / 210 MB limit (0.38% of cap). Landed in `558315069` via PR #50.
35
+
36
+ ## [2.22.0] - 2026-04-18
37
+
38
+ ### Added
39
+
40
+ - **ADR-174 Phase 2 item 7 follow-up: `pica_projects_attach_works` (stdio).**
41
+ Closes the `work_ids` FIELD_NOT_WIRED gap on `pica_projects_create` /
42
+ `_update`. Pre-slice the MCP tools advertised `work_ids` but the admin
43
+ route silently dropped it — the route redirect message already pointed
44
+ agents at `POST /api/admin/projects/[id]/works`, but no MCP tool
45
+ exposed that path. The new tool accepts
46
+ `{ project_id, works: [{ work_id, project_day?, notes? }...] }` and
47
+ attaches each item via `ProjectsResource.attachWork` with per-item
48
+ result reporting (`attached[]`, `skipped[]` for already-linked,
49
+ `failed[]` for other errors). Registered in `lib/services/mcp-scopes.ts`
50
+ under `write:catalog`.
51
+
52
+ ### Changed
53
+
54
+ - **ADR-174 Phase 2 item 22: `pica_publishers_create` reshaped.** Pre-slice
55
+ the schema exposed only `{ name, ipi }` (2 fields) and the SDK's
56
+ `PublishersResource.create` hit a 404 — the admin route did not exist.
57
+ The companion slice 1 commit added `POST /api/admin/publishers`;
58
+ this slice reshapes the tool to match. All 8 audit-row-22
59
+ Add-candidates surfaced (`legal_name`, `country`, `isni`,
60
+ `publisher_type`, `wikidata_id`, `parent_publisher_id`,
61
+ `founded_date`, `headquarters`) plus the explicit `ipi → ipi_number`
62
+ rename. `parent_publisher_id` description steers agents at
63
+ `pica_publishers_query` to resolve the parent UUID. Required fields:
64
+ `name`, `ipi_number`. The route is idempotent on `ipi_number` — a
65
+ duplicate IPI returns the existing row with `already_existed: true`
66
+ instead of failing.
67
+
68
+ - **ADR-174 Phase 2 items 14+15: `pica_agreements_create` / `_update`
69
+ reshaped to consume `AGREEMENTS_WRITE_PROPERTIES` from
70
+ `@withpica/mcp-utils`.** Tool schemas now advertise all 13
71
+ Add-candidate columns from audit rows 14+15. Tool descriptions steer
72
+ agents toward `counterparty_org_id` (ADR-176 first-class-party) over
73
+ free-text `other_party_name` — use `pica_search_all` to resolve an
74
+ org name to an ID. `_update` description calls out that
75
+ counterparty_org_id changes require the linked-org check at the
76
+ route layer (orgLinkingService.areLinked). No tool signature change
77
+ otherwise; existing fields preserved.
78
+
79
+ ### Route-side companion (non-package, same slice)
80
+
81
+ - `app/api/admin/agreements/route.ts` POST and
82
+ `app/api/admin/agreements/[id]/route.ts` PATCH — phantom/unknown key
83
+ rejection via `AGREEMENT_POST_ALLOWED_FIELDS` /
84
+ `AGREEMENT_PATCH_ALLOWED_FIELDS` /
85
+ `AGREEMENT_WRITE_PHANTOM_REDIRECTS` in
86
+ `lib/services/agreements-write-constants.ts`. Pre-slice both routes
87
+ spread `body` straight into the Supabase insert/update — effectively
88
+ a wide-open write surface. Also surfaces and fixes pre-existing dark
89
+ code in the PATCH test file (3 tests were sending `name` and `type`
90
+ — phantom field names that silently dropped against `title` and
91
+ `agreement_type`).
92
+
93
+ - `app/api/admin/publishers/route.ts` POST (NEW) — publishers had no
94
+ admin route at all pre-slice, so `pica_publishers_create` and the
95
+ SDK's `PublishersResource.create` 404'd at runtime. Slice 1
96
+ (0ba4d400d) adds the route with phantom/unknown-field rejection via
97
+ `PUBLISHERS_POST_ALLOWED_FIELDS` / `PUBLISHERS_WRITE_PHANTOM_REDIRECTS`
98
+ in `lib/services/publishers-write-constants.ts`, idempotent
99
+ deduplication by `ipi_number`, FK pre-validation on
100
+ `parent_publisher_id`, and server-stamped provenance.
101
+
102
+ - **ADR-174 Phase 2 item 21: `pica_multimedia_create` reshaped.** Added
103
+ 15 real-column fields that were invisible to agents pre-ADR-174:
104
+ `credits`, `duration_seconds`, `collection_id`, `display_order`,
105
+ `is_featured`, `is_published`, `venue`, `event_name`,
106
+ `performance_date`, `setlist_position`, `sync_side`, and the external
107
+ identifier set (`spotify_url`, `spotify_track_uri`, `spotify_track_id`,
108
+ `youtube_url`, `youtube_video_id`, `soundcloud_url`, `thumbnail_url`).
109
+ Description now points agents at `POST /api/admin/multimedia/upload`
110
+ for file uploads and `pica_multimedia_link_youtube` for the YouTube
111
+ enrichment flow — the generic create surface is for external-URL
112
+ linking and performance-context metadata.
113
+
114
+ ### Route-side companion (non-package, same slice)
115
+
116
+ - `app/api/admin/multimedia/route.ts` POST — phantom/unknown key guard
117
+ via `MULTIMEDIA_POST_ALLOWED_FIELDS` /
118
+ `MULTIMEDIA_POST_PHANTOM_REDIRECTS` in
119
+ `lib/services/multimedia-write-constants.ts`. Redirects upload-flow
120
+ columns (s3*key, file_name, …) to `/api/admin/multimedia/upload`,
121
+ enrichment columns (youtube_view_count, spotify_popularity) to their
122
+ respective cascades, and scanner columns (virus_scan*\*) to the
123
+ scanner flow. Also closes a latent privilege-escalation path: pre-slice
124
+ the route overwrote `body.user_id` with the authenticated session's
125
+ id, but a caller could still _attempt_ to pass `user_id` (silently
126
+ overwritten). The guard now 400s on `user_id` / `organisation_id`
127
+ injection attempts with a clear PHANTOM_FIELD message.
128
+
129
+ - **ADR-174 Phase 2 item 13: `pica_sessions_create` reshaped.** Dropped
130
+ `additionalProperties: true` per Decision 2. Added 6 previously-missing
131
+ real columns from audit row 13 as explicit Zod properties:
132
+ `description`, `timezone`, `is_all_day`, `location_url`, `recording_id`,
133
+ `status` (enum: scheduled / in_progress / completed / cancelled), plus
134
+ the `metadata` jsonb bag and the `participants` relational array
135
+ (already handled by the service but undocumented in the tool surface).
136
+ `recurrence_rule` deferred — the service's `CreateSessionParams` type
137
+ needs to accept it first (tracked in the route-guard PHANTOM_REDIRECT
138
+ entry).
139
+
140
+ ### Route-side companion (non-package, same slice)
141
+
142
+ - `app/api/admin/sessions/route.ts` POST now reads `body.status` and
143
+ `body.metadata` (pre-slice silently dropped) and 400s on phantom /
144
+ unknown keys via `SESSION_POST_ALLOWED_FIELDS` /
145
+ `SESSION_POST_PHANTOM_REDIRECTS` in
146
+ `lib/services/sessions-write-constants.ts`.
147
+
148
+ - **ADR-174 Phase 2 item 20: `pica_share_links_create` reshaped to
149
+ consume `SHARE_LINKS_WRITE_PROPERTIES` from `@withpica/mcp-utils`.**
150
+ Tool schema now advertises all 13 add-candidate columns from audit
151
+ row 20 that were previously invisible to agents (access_type,
152
+ allowed_person_ids, allow_comments, allow_view_collaborators,
153
+ allow_view_financials, notify_on_access, watermark_audio,
154
+ sent_to_emails, playlist_name, allow_streaming, include_all_files,
155
+ included_file_ids, description). Executor widened to pass every
156
+ caller-provided property through to the SDK / admin route — the
157
+ route-layer allow-list (slice 1) rejects anything outside the
158
+ contract. `password` remains the canonical plain-text input; the
159
+ route hashes to `password_hash`.
160
+
161
+ - **ADR-174 Phase 2 items 16+17: `pica_agreement_types_create` / `_update`
162
+ reshaped to consume `AGREEMENT_TYPES_WRITE_PROPERTIES` from
163
+ `@withpica/mcp-utils`.** Dropped the inlined property map in favour of
164
+ the shared module that documents per-branch applicability. Phantom
165
+ fields `title`, `description`, `points_percentage`, `recoupment_terms`,
166
+ `rights_assigned` removed from the schema (agents sending them now fail
167
+ fast at the admin route guard with a `PHANTOM_FIELD` redirect pointing
168
+ at the canonical column or resolution path). Tool descriptions updated
169
+ to truthfully list the required fields per branch (template needs
170
+ `name` + `category` + `templateText`; producer needs `producer_id` +
171
+ `royalty_points` + `deliverables` + `work_id`|`recording_id`;
172
+ work_for_hire needs `contractor_id` + `contractor_role` + `fee_amount`
173
+ - `services_description` + `work_id`|`recording_id`). Tool description
174
+ for `_update` now calls out that PATCH on producer_agreements and
175
+ work_for_hire_agreements is action-only — the generic update path has
176
+ no live field-update surface on those two branches until a follow-up
177
+ slice promotes the action-based PATCH handlers to accept field
178
+ updates.
179
+
180
+ ### Added
181
+
182
+ - **ADR-179 Phase 1: `pica_resolve_work` (stdio).** Outcome-shaped
183
+ resolver that fans a work out across every eligible enrichment source
184
+ in one call. Replaces the five `pica_enrich_work_*` tools' role at
185
+ the agent layer. Returns `applied[]` / `proposals[]` / `errors[]` /
186
+ `recovery_hints[]`. `isError` is set only when every source that ran
187
+ errored — partial failure is a non-error receipt. Credit + billing
188
+ gates wire through the `external_resolver_call` action key.
189
+ - **ADR-179 Phase 2: `pica_resolve_person` (stdio).** Person-side
190
+ resolver mirroring `pica_resolve_work`. Sources are narrower —
191
+ `isni` | `musicbrainz` — covering the identity-graph cascade rules
192
+ (ISNI→Wikidata and MBID→Wikidata crosswalks plus their downstream
193
+ awards / biography enrichment). Same output shape, same isError
194
+ semantics, same credit-gate action key as the work resolver.
195
+ Registered in `lib/services/mcp-scopes.ts` under `write:people` and
196
+ listed in the layered-discovery `enrichment` category so
197
+ `pica_discover` surfaces it above the deprecated
198
+ `pica_people_enrich_*` pair.
199
+
200
+ ### Deprecated
201
+
202
+ - **`pica_enrich_work_mlc`, `pica_enrich_work_musicbrainz`,
203
+ `pica_enrich_work_discogs`, `pica_enrich_work_spotify`,
204
+ `pica_enrich_work_youtube`.** All five now return
205
+ `TOOL_DEPRECATED` (jsonrpc code -32070) with a suggested-call
206
+ payload pointing at `pica_resolve_work` with the correct `sources`
207
+ narrowing. Tool definitions stay registered so `tools/list` and
208
+ `pica_tool_details` can still surface them with a migration hint for
209
+ one minor version — removal scheduled for the next minor after
210
+ ADR-179 Phase 4's publish.
211
+ - **`pica_people_enrich_isni`, `pica_people_enrich_musicbrainz`.**
212
+ Both now return `TOOL_DEPRECATED` (jsonrpc code -32070) with a
213
+ suggested-call payload pointing at
214
+ `pica_resolve_person(sources: ['isni' | 'musicbrainz'])`. Tool
215
+ definitions stay registered until the next minor; same one-minor-
216
+ version deprecation window as the work-side five.
217
+
218
+ ### Changed
219
+
220
+ - `pica_tool_details` responses for the five deprecated work tools
221
+ now carry a `TOOL_DEPRECATED` entry in `recovery_hints` as the first
222
+ item. Existing `NO_MATCH` / `MISSING_INPUT` hints are kept behind
223
+ it — they are dead code today but stay in the registry until tool
224
+ removal so downstream consumers don't see a mid-version
225
+ disappearance.
226
+ - Same treatment applied to the two deprecated person tools:
227
+ `pica_people_enrich_isni` and `pica_people_enrich_musicbrainz` each
228
+ get a `TOOL_DEPRECATED` recovery hint prepended to their existing
229
+ `NO_MATCH` entry.
230
+
231
+ ## [2.22.0] — 2026-04-16
232
+
233
+ ### Changed
234
+
235
+ - **ADR-174 Phase 2 item 10 (recording_splits): reshape
236
+ `pica_recording_splits_create`.** Adopts the shared
237
+ `RECORDING_SPLITS_WRITE_PROPERTIES` from `@withpica/mcp-utils@1.4.0`,
238
+ dropping `additionalProperties: true` per Decision 2. All 9 audit-
239
+ Keep fields now enumerated as explicit Zod properties — no phantom
240
+ additions, no renames. Description-level hint on `role` replaced
241
+ with a proper `enum` array matching the route's validRoles allow-
242
+ list. Schema is now byte-identical to `@withpica/mcp-server-business`
243
+ (both consume the shared module) — pre-slice they were independent
244
+ byte-divergent-risk copies.
245
+
246
+ ### Route-side companion (non-package, same slice)
247
+
248
+ - `app/api/admin/recordings/[id]/splits/route.ts` POST — UNKNOWN_FIELD
249
+ guard runs before the required-field check so misspelled keys fail
250
+ fast with the field name. See the slice commit.
251
+
252
+ ## [2.21.0] — 2026-04-16
253
+
254
+ ### Fixed
255
+
256
+ - **ADR-174 Phase 2 item 24 (team): `pica_team_update_role` now actually
257
+ updates role.** Pre-ADR-174 the tool was named `_update_role` but its
258
+ Zod schema only accepted `permissions` — the `role` field was missing
259
+ entirely. The admin PATCH route at `/api/admin/team/[id]` hard-
260
+ destructured `{ permissions }` and silently dropped every other
261
+ field, so even if an agent hand-crafted a call with `role` the DB
262
+ write would not happen. Audit row 24 flagged this as "Add `role`, or
263
+ rename the tool." Fixed by adding `role: string` to the MCP Zod
264
+ schema, widening the route to build the update object from whichever
265
+ of `role` / `permissions` are provided, and making the old
266
+ "permissions required" check accept "at least one of role or
267
+ permissions." `id` stays required; `role` and `permissions` are now
268
+ both optional but at least one must be set.
269
+
270
+ ### Route-side companion (non-package, same slice)
271
+
272
+ - `app/api/admin/team/[id]/route.ts` PATCH — phantom/unknown key
273
+ rejection via `TEAM_MEMBERSHIP_PATCH_ALLOWED_FIELDS` (allow-list of
274
+ `permissions` + `role`), error message updated from "permissions
275
+ required" to "at least one of permissions or role is required", and
276
+ "failed to update permissions" to "failed to update team membership"
277
+ (now-generic — it updates role too).
278
+
279
+ ## [2.20.0] — 2026-04-16
280
+
281
+ ### Changed
282
+
283
+ - **ADR-174 Phase 2 item 7 (projects): reshape `pica_projects_create` /
284
+ `pica_projects_update` Zod schemas.** Exposed 9 Add-candidate fields
285
+ from audit row 18 that were already plumbed end-to-end through the
286
+ route and service but invisible to agents via tool discovery:
287
+ `start_date`, `end_date`, `location_name`, `location_address`,
288
+ `location_url`, `virtual_url`, `is_open`, `max_participants`, `status`
289
+ (enum: draft / scheduled / active / completed / cancelled). Also
290
+ surfaced the route-level `generate_invite_code` flag and the
291
+ freeform `metadata` jsonb object. Dropped `work_ids` from both
292
+ schemas — the pre-ADR-174 tool advertised `work_ids` but the admin
293
+ POST / PATCH routes never routed it to the `project_works` junction
294
+ (see commit `edf890a24` for the route-side FIELD_NOT_WIRED rejection
295
+ and redirect message pointing at
296
+ `POST /api/admin/projects/[id]/works`). The `project_type`
297
+ description replaces the pre-ADR-174 "album, ep, compilation, single,
298
+ mixtape" hint (none of which are valid backend values) with the
299
+ actual convention: writing_camp, recording_session, production,
300
+ mixing, mastering, retreat, other.
301
+
302
+ ### Route-side companion (non-package, same slice)
303
+
304
+ - `app/api/admin/projects/route.ts` POST and
305
+ `app/api/admin/projects/[id]/route.ts` PATCH — phantom/unknown key
306
+ rejection with `FIELD_NOT_WIRED` redirect for `work_ids`. See commit
307
+ `edf890a24`.
308
+
309
+ ## [2.19.0] — 2026-04-16
310
+
311
+ ### Added
312
+
313
+ - **ADR-178: `pica_enrichment_propose` stdio tool.** New agentic write
314
+ tool that files enrichment proposals sourced from open-web research
315
+ (Audiomack, Songdata, MusicBrainz page, label portals, artist bios,
316
+ etc.) rather than from PICA's structured cascade. Every proposed
317
+ field must cite at least one source URL — `sources[].fields` arrays
318
+ form the trust moat, and the server rejects uncited claims with
319
+ `code: MISSING_SOURCE`. Source type routes the proposal as
320
+ `source = 'agent_research'`, `rule_id = 'agent_research'` on the
321
+ existing `enrichment_proposals` table (no new queue, no new review
322
+ tools — reuses `pica_enrichment_proposals_list` / `_apply` /
323
+ `_reject` from `2.10.0`).
324
+
325
+ Tool description carries ADR-178 Decision 3 language verbatim: when
326
+ the user is in-session, the agent asks for approval directly and
327
+ calls `pica_enrichment_proposal_apply` after confirmation — the
328
+ dashboard card is the receipt, not the workflow. This shapes agent
329
+ behaviour in-context without needing a new code path for "in-
330
+ session approval".
331
+
332
+ Wrapped in `withBillingGate` and (via
333
+ `@withpica/mcp-utils@1.3.0`) `withCreditGate` under the new
334
+ `enrichment_propose` action key. Credit gating is telemetric only
335
+ while ADR-162 keeps the subscription gate on; the wrap is already
336
+ in place so re-enabling billing doesn't need a tool-surface change.
337
+
338
+ ### Fixed
339
+
340
+ - **ADR-178 slice 1b regression caught in smoke test:** agent-research
341
+ proposals whose `proposed_fields` cite columns that don't exist on
342
+ the target table (tempo_bpm, musical_key, producers — the Heinzmann
343
+ transcript's fields, not columns on `works`) used to 500 with a
344
+ Postgres "column does not exist" error because the service built a
345
+ column-scoped `SELECT` from the proposed keys. Fix snapshots the
346
+ full live row and builds `current_fields` from the intersection of
347
+ proposed keys and actual columns. Unknown keys now land as pending
348
+ proposals with an empty baseline instead of crashing the request.
349
+ Apply path for unknown-column fields is a separate open question on
350
+ the ADR (see Open Question 5).
351
+
352
+ ## [2.18.0] — 2026-04-16
353
+
354
+ ### Changed
355
+
356
+ - **ADR-174 Phase 2 item 6: reshape `pica_credits_update` Zod schema.**
357
+ Dropped phantom `publisher_name` and `publisher_ipi` properties —
358
+ `work_credits` has no columns for either. Agents now resolve a
359
+ publisher name or IPI to a UUID via `pica_publishers_query` (or
360
+ create one via `pica_publishers_create`) and pass the result as
361
+ `publisher_id`. Added three audit "Add candidate" columns to the
362
+ per-credit-object shape: `is_primary` (boolean), `notes` (string),
363
+ `attestation_status` (enum: pending / attested / disputed /
364
+ declined). `attested_at` / `attested_by` remain service-managed.
365
+ Description refresh calls out `credit_type` as the canonical column
366
+ name stored behind the `role` alias and `writer_split_percentage`
367
+ behind `splits`. No required-field change — `person_id`, `role`,
368
+ `splits` stay required.
369
+
370
+ ### Route-side companion (non-package, same slice)
371
+
372
+ - `app/api/admin/works/[id]/credits/route.ts` POST — phantom/unknown
373
+ key rejection on each `credits[i]` element with field name + index
374
+ in the error payload, plus a mirror-fill step that normalises
375
+ `role` ↔ `credit_type` and `splits` ↔ `writer_split_percentage` so
376
+ callers sending either spelling flow through. See commit
377
+ `dbfb098ae` for the server-side guard.
378
+
379
+ ### Not covered by this slice
380
+
381
+ - `work_collaborators` (publishing-side POST at
382
+ `app/api/admin/works/[id]/collaborators/route.ts`) was not in the
383
+ ADR-174 audit — the MCP tool's `updateCollaborators` SDK hop hits
384
+ that route for writer/composer/lyricist/arranger roles today and
385
+ inherits a separate column set. Tracked as a follow-up slice.
386
+
387
+ ## [2.17.0] — 2026-04-16
388
+
389
+ ### Changed
390
+
391
+ - **ADR-174 Phase 2 item 5: reshape `pica_physical_assets_create` and
392
+ `pica_physical_assets_update` Zod schemas.** Adopted the shared
393
+ `PHYSICAL_ASSETS_WRITE_PROPERTIES` from `@withpica/mcp-utils@1.2.0`,
394
+ dropped `additionalProperties: true` on both tools, and moved 11
395
+ phantom top-level fields (`current_valuation`, `valuation_currency`,
396
+ `valuation_source`, `valuation_date`, `valuation_notes`,
397
+ `reverb_listing_url`, `ebay_item_url`, `insured`,
398
+ `insurance_provider`, `insurance_policy_number`, `insurance_coverage`)
399
+ off the top-level surface. Agents set these via
400
+ `external_references: { current_valuation: 1500, insurer: "ACME", ... }`
401
+ per the ADR-174 Open Decision 1 (2026-04-14) resolution. Two fields
402
+ were renamed at the jsonb layer: `insurance_provider → insurer`,
403
+ `insurance_coverage → insured_value`. `asset_type`, `condition`,
404
+ `acquisition_method`, `license_type`, and `status` gained proper
405
+ `enum` arrays matching the underlying `physical_assets_*_check` CHECK
406
+ constraints — pre-reshape they were loose strings with the enum
407
+ hinted in the description (so callers could pass `studio_equipment`
408
+ at the MCP layer and get a 500 from the CHECK constraint at the DB
409
+ layer).
410
+ - **No description lie.** Both tool descriptions now explicitly name
411
+ `external_references` as the home for valuation/insurance/DSP URL
412
+ details rather than the pre-ADR-174 "tracks … valuation, photos,
413
+ insurance, and status" claim that the schema couldn't honour.
414
+
415
+ ### Route-side companion (non-package, same slice)
416
+
417
+ - `app/api/admin/assets/route.ts` POST and
418
+ `app/api/admin/assets/[id]/route.ts` PATCH — phantom/unknown key
419
+ rejection with redirect messages (400 + `PHANTOM_FIELD` /
420
+ `UNKNOWN_FIELD` error codes). See commit `ced46b889` for the
421
+ server-side guard.
422
+
423
+ ## [2.16.0] — 2026-04-15
424
+
425
+ ### Added
426
+
427
+ - **ADR-173: five release-track tools.** Closes the gap flagged by two
428
+ independent external MCP reviewers on 2026-04-14 ("release layer looks
429
+ shallow"). New tools on the stdio transport:
430
+ - `pica_releases_attach_track` — attach a recording and/or work at a
431
+ specific `(disc_number, track_number)`. Idempotent on position.
432
+ At least one of `recording_id` / `work_id` is required.
433
+ - `pica_releases_list_tracks` — list tracks in `(disc, track)` order
434
+ with inlined title/artist/ISRC/duration from the linked recording
435
+ and work.
436
+ - `pica_releases_detach_track` — soft-confirmation detach by position
437
+ (preview without `confirm:true`, delete with).
438
+ - `pica_releases_reorder_tracks` — transactional positional reorder
439
+ via the `reorder_release_tracks_atomic` Postgres RPC. Rejects
440
+ duplicate positions in the payload before any DB write.
441
+ - `pica_releases_attach_recording_with_work` — compound workflow that
442
+ auto-pulls the recording's linked work onto the new track row.
443
+
444
+ ### Changed
445
+
446
+ - **`pica_works_inspect` and `pica_recordings_inspect` gain a `releases`
447
+ section.** Lazy (only fetched when requested). Returns every release
448
+ the entity appears on with its track position. Answers "which albums
449
+ is this master on?" in one call — previously unanswerable via MCP.
450
+
451
+ ### Fixed
452
+
453
+ - **`pica_releases_list_tracks` 500 on every call.** Pre-merge E2E
454
+ caught two latent bugs in the `listTracks` service query: a missing
455
+ FK `release_tracks.recording_id → recordings(id)` (PostgREST could
456
+ not resolve the `recording:recordings(...)` embed) and a
457
+ `duration_seconds` column reference where the live column is
458
+ `duration_ms`. Fixed in migration
459
+ `20260415_01_adr173_fix_release_tracks_recording_fk.sql` +
460
+ a rename in `lib/services/releases.ts`. The migration also NULLs 85
461
+ orphan `recording_id` values on production left behind by the
462
+ 2026-04-04 soundslikefez duplicate-works cleanup.
463
+
464
+ ### Note on version number
465
+
466
+ This release would have been `2.15.0` per the original ADR-173
467
+ implementation record, but `2.15.0` was taken on `develop` by the
468
+ ADR-174 Phase 2 item 4 slice while the ADR-173 fix commits were in
469
+ flight. Bumped to `2.16.0` to keep the published package timeline
470
+ linear.
471
+
472
+ ## [2.15.0] — 2026-04-15
473
+
474
+ ### Changed
475
+
476
+ - **ADR-174 Phase 2 item 4: `pica_people_create` / `pica_people_update`
477
+ schema reconciliation.** Introduced `PEOPLE_WRITE_PROPERTIES` as the
478
+ canonical source of truth for the people write surface — every
479
+ property maps to a real column on either `public.people` or
480
+ `public.person_enrichment`. `additionalProperties: true` is off;
481
+ unknown keys 400 at the HTTP layer (see develop commit
482
+ `fbea9e2a3`).
483
+ - **Satellite-routing made explicit.** Eleven fields remain in the
484
+ schema but their descriptions now name `person_enrichment` as the
485
+ write target: external identifiers (`isni`, `musicbrainz_id`,
486
+ `wikidata_id`, `discogs_artist_id`, `deezer_artist_id`) and
487
+ biographical data (`date_of_birth`, `gender`, `nationality`,
488
+ `birth_place`, `instruments`, `career_start_year`). The service
489
+ fans these out through `syncPersonEnrichmentSatellite`. Correction
490
+ to the original audit (row 7) landed in ADR-174's Corrections
491
+ block: six of these fields were classified as "Remove — no column
492
+ on people", which missed the satellite hop. They are not phantom
493
+ writes, and subsequent slices must audit satellite write paths
494
+ before classifying any field as phantom.
495
+ - **Twelve add-candidates surfaced** (audit row 7 "Missing writable
496
+ columns"): `middle_name`, `person_type`, `company`, `position`,
497
+ `territory`, `social_media`, `emails`, `pro_name`,
498
+ `pro_member_number`, `mcps_member_number`, `relationship_strength`,
499
+ `email_preferences`. All verified against `public.people` columns
500
+ 2026-04-15 (project `fwgcmjhlwevdnxgqmkmh`).
501
+ - **Deprecated duplicates rejected.** `type` (deprecated dup of
502
+ `person_type`) and `role` (deprecated singular of `roles`) are
503
+ now 400 PHANTOM_FIELD with a redirect message naming the canonical
504
+ column. Both DB columns still exist as unused dead space —
505
+ removing them is out of scope and scheduled for ADR-165-style
506
+ cleanup.
507
+ - **Description lies removed.** The audit (row 8) flagged
508
+ `pica_people_update` description as "Additional fields are also
509
+ accepted" with no enumeration. That sentence is gone from both
510
+ `create` and `update` descriptions.
511
+
512
+ ### Breaking
513
+
514
+ - Callers that were passing the deprecated `type` / `role`
515
+ duplicates now get a 400 with a redirect hint — previously the
516
+ keys were silently dropped by the ORM. Same failure-mode calculus
517
+ as the works / recordings slices — the writes were already
518
+ failing, now they fail visibly.
519
+ - Callers that were passing arbitrary unlisted keys now get a 400 —
520
+ previously `additionalProperties: true` let them through and the
521
+ ORM dropped them silently. Zero rows observed in `people.metadata`
522
+ jsonb for any of the pre-existing phantom keys (verified during
523
+ ADR-174 Phase 1 2026-04-14).
524
+
525
+ ## [2.14.0] — 2026-04-14
526
+
527
+ ### Changed
528
+
529
+ - **ADR-174 Phase 2: `pica_recordings_create` / `pica_recordings_update`
530
+ schema reconciliation.** Introduced `RECORDING_WRITE_PROPERTIES` as
531
+ the canonical source of truth for the recordings write surface —
532
+ every property maps to a real column on `public.recordings`. Added
533
+ thirteen fields the DB exposes that the tool was hiding:
534
+ `duration_ms`, `preview_url`, `album_art_url`, `spotify_url`,
535
+ `spotify_track_uri`, `spotify_track_id`, `youtube_video_id`,
536
+ `youtube_url`, `apple_music_url`, `deezer_track_id`,
537
+ `mlc_recording_id`, `mlc_song_code`, `isrc_prefix`. The
538
+ `version_type` field is now enum-restricted to the ADR-166 values
539
+ (`master`, `alternate_master`, `music_video`, `lyric_video`,
540
+ `live_performance`, `acoustic`, `remix`, `cover`, `alternate`),
541
+ matching the `recordings_version_type_check` DB constraint.
542
+ - **`pica_recordings_create` default `version_type` changed from
543
+ `"original"` to `"master"`.** Pre-fix the executor defaulted to
544
+ `"original"`, which is not a valid version_type — every call without
545
+ an explicit type tripped the recording-type CHECK constraint and
546
+ surfaced as a 500 from the service. `"master"` is the DB-level
547
+ default and the canonical ADR-166 value.
548
+ - **Title rename made explicit.** `recording_title` is the canonical
549
+ column on `public.recordings`. The tool keeps `title` as an input
550
+ alias for ergonomics; the schema now declares both fields with the
551
+ rename called out in their descriptions, instead of relying on
552
+ `additionalProperties: true` to hide the translation.
553
+ - Tool descriptions now steer album metadata (`album_name`,
554
+ `album_release_date`, `upc`, `track_number`) to
555
+ `pica_releases_create/update`, ISWCs to `pica_works_create/update`,
556
+ and label metadata to `pica_releases_*.label_organization_id` via
557
+ `pica_labels_query`. `duration_seconds` is explicitly named as the
558
+ works convention; `recordings` carries `duration_ms`.
559
+
560
+ ### Removed
561
+
562
+ - **ADR-174 Phase 2: seven phantom fields rejected on
563
+ `pica_recordings_create` / `pica_recordings_update`.** The Zod schema
564
+ no longer accepts them and `additionalProperties: true` is gone:
565
+ `album_name`, `album_release_date`, `upc`, `track_number`, `label`,
566
+ `duration_seconds`, `iswc` — none of these corresponded to columns on
567
+ `recordings`. The HTTP route at `POST/PATCH /api/admin/recordings[/id]`
568
+ now 400s on any of these keys with a redirect message naming the
569
+ correct tool (commit `cffa6f947`).
570
+
571
+ ## [2.13.1] — 2026-04-14
572
+
573
+ ### Changed
574
+
575
+ - **ADR-174 Phase 2: `pica_works_bulk_update.updates` schema gated on
576
+ `WORK_WRITE_PROPERTIES`.** The bulk tool was the last write-path
577
+ surface that still accepted any key — `updates: { type: "object" }`
578
+ with no property list (audit row 25). Now validates against the same
579
+ canonical schema as `pica_works_update`: phantom keys (label, upc,
580
+ album_name, …) and arbitrary unlisted keys fail fast with a
581
+ descriptive `VALIDATION_ERROR` before the SDK is called. One bad key
582
+ invalidates the whole batch — no partial writes.
583
+
584
+ ## [2.13.0] — 2026-04-14
585
+
586
+ ### Changed
587
+
588
+ - **ADR-174 Phase 2: `pica_works_create` / `pica_works_update` schema
589
+ reconciliation.** Introduced `WORK_WRITE_PROPERTIES` as the canonical
590
+ source of truth for the works write surface — every property maps to
591
+ a real column on `public.works`. Added five fields the DB exposes
592
+ that the tool was hiding: `tempo`, `key`, `display_artist`,
593
+ `published`, `tunecode`. Tool descriptions now steer album/release
594
+ metadata (`album_name`, `album_art_url`, `track_number`, `upc`,
595
+ `spotify_url`) to `pica_releases_create/update` and label metadata to
596
+ `pica_releases_*.label_organization_id` via `pica_labels_query`.
597
+
598
+ ### Removed
599
+
600
+ - **ADR-174 Phase 2: seven phantom fields removed from
601
+ `pica_works_create` / `pica_works_update`.** `label`, `spotify_url`,
602
+ `album_name`, `album_release_date`, `album_art_url`, `track_number`,
603
+ `upc` — none of these corresponded to columns on `works`. The HTTP
604
+ route at `POST/PATCH /api/admin/works[/id]` now 400s on any of these
605
+ keys with a redirect message naming the correct tool (commit
606
+ `9d68b16b1`). Previously they routed silently into the
607
+ `work_album_metadata` / `work_spotify_data` satellites that ADR-165
608
+ marked as dead — a write succeeded but no reader could find the
609
+ value.
610
+ - **ADR-174 Phase 2: `additionalProperties: true` removed from both
611
+ works write schemas.** The tool no longer silently accepts arbitrary
612
+ keys; unknown keys surface as validation errors. Description lies
613
+ about `available_for_licensing`, `vocal_type`, `energy`,
614
+ `danceability` also removed — those fields live on satellite tables
615
+ and are not exposed through MCP.
616
+
617
+ ## [2.12.0] — 2026-04-14
618
+
619
+ ### Added
620
+
621
+ - **ADR-174 Phase 2: `pica_labels_query` tool** — read-only resolution of
622
+ label names to `organisations.id`. Returns label organisations
623
+ (`org_type='label'`) whose name or display_name matches the substring
624
+ query, for use as `releases.label_organization_id` via
625
+ `pica_releases_create` / `pica_releases_update`. `query` and `limit`
626
+ both optional; limit defaults to 50, max 100. Category: catalog.
627
+ Annotations: `readOnlyHint: true`.
628
+
629
+ ### Changed
630
+
631
+ - **ADR-174 Phase 2: `pica_releases_create` / `pica_releases_update`
632
+ schema reconciliation.** Input schemas now expose the nine ADR-174
633
+ Decision 3 fields that `releases` actually stores:
634
+ `label_organization_id`, `distributor_organization_id`,
635
+ `pre_release_date`, `artwork_url`, `spotify_album_uri`, `spotify_url`,
636
+ `apple_music_url`, `other_urls`, `notes`. Tool descriptions now
637
+ direct agents to call `pica_labels_query` (new) or `pica_search_all`
638
+ to resolve a label/distributor name to an organisation ID before
639
+ writing.
640
+
641
+ ### Removed
642
+
643
+ - **ADR-174 Phase 2: freetext `label` removed from
644
+ `pica_releases_create` / `pica_releases_update`.** The field never
645
+ corresponded to a real column on `releases` — the DB models labels
646
+ via `label_organization_id` FK. Agents must now resolve a label name
647
+ to an organisation ID (via `pica_labels_query`) instead of passing a
648
+ string. Pre-fix behaviour: tool schema accepted `label`, service
649
+ propagated it to the DB, the DB rejected it as `42703 column does not
650
+ exist`, every call 500'd. No working integrations could have relied
651
+ on this — the change is strictly a fix, not a break.
652
+
14
653
  ## [2.11.0] — 2026-04-13
15
654
 
16
655
  ### Changed
@@ -31,7 +670,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
31
670
  `audit-credits`, `new-catalog-setup`, `register-my-works`,
32
671
  `prepare-for-sync`. Functionality folded into new skills —
33
672
  see design spec for mapping.
34
-
35
673
  - `workspace-autopilot` now routes through the full journey sequence
36
674
  (identity → catalog → audio → gaps → collaborators → ownership →
37
675
  notifications → exports) instead of the old 5-condition router.
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,UAAU,IAAI,YAAY,CA8CzC;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAWzD"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,UAAU,IAAI,YAAY,CA+CzC;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAWzD"}
package/dist/config.js CHANGED
@@ -35,8 +35,9 @@ export function loadConfig() {
35
35
  // in the MCP `initialize` handshake response under `serverInfo.version`,
36
36
  // which is what clients display in their connector UIs. Drift from
37
37
  // package.json was caught 2026-04-08 — banner read 2.5.0 long after
38
- // npm was on 2.6.1.
39
- version: "2.6.2",
38
+ // npm was on 2.6.1. Caught again 2026-04-19 during ADR-181 Phase 2 —
39
+ // banner read 2.6.2 long after npm was on 2.22.0; fixed here.
40
+ version: "2.23.0",
40
41
  debug,
41
42
  lobbyMode,
42
43
  credentialsPath,