@withpica/mcp-sdk 1.46.0 → 1.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -11,6 +11,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ## [1.48.0] - 2026-06-25
15
+
16
+ ### Added
17
+
18
+ - **`resolveRelease(id, body)`** → `POST /admin/releases/:id/resolve`, plus the
19
+ `ResolveReleaseResult` type. Backs `pica_resolve_release` (release-grain
20
+ Spotify gap-fill enrichment through the authority gate).
21
+ - **`CatalogHealthResource`** — `catalogHealth()` (`GET /admin/catalog-health`,
22
+ whole-catalog completeness + cleanliness verdict), `catalogHealthPlan(body)`
23
+ (derives an actionable fix-plan + `planToken`), and `catalogHealthFix(body)`
24
+ (applies accepted `actionIds` / `all_safe_auto`, returning honest
25
+ `applied` / `skipped`). Plus the `CatalogHealth*` result types. Back
26
+ `pica_catalog_health` / `_plan` / `_fix` (ADR-272 / ADR-273).
27
+ - **`DocumentsResource`** — `listCatalog(params)`, `read(id, params)` (bounded
28
+ content read), and `link(id, entity_type, entity_id)` (provenance link to a
29
+ work / person / recording). Backs the ADR-274 document bridge
30
+ (`pica_documents_list` / `_read` / `_link`).
31
+
32
+ ## [1.47.0] - 2026-06-22
33
+
34
+ ### Added
35
+
36
+ - **`ReleasesResource.delete(id)`** — deletes a release via `DELETE /admin/releases/:id`. Returns the uniform `DeletionResult`; a refused delete (release still has tracks / active share links — releases have no soft-delete) surfaces as an `ApiError` carrying `to_fully_delete`.
37
+ - **`AudioFilesResource.delete(id)`** — deletes an audio file via `DELETE /admin/audio-files/:id`, returning the uniform `DeletionResult`. Backs the new `pica_audio_delete` tool, which also cleans up the underlying storage object.
38
+
14
39
  ## [1.46.0] - 2026-06-19
15
40
 
16
41
  ### Added
package/dist/index.d.ts CHANGED
@@ -92,6 +92,42 @@ export interface ResolveRecordingResult {
92
92
  skipped_lower_authority: SkippedAuthorityReceipt[];
93
93
  recovery_hints: string[];
94
94
  }
95
+ /**
96
+ * Release resolver result. Mirrors the server-side `ResolveReleaseResult`
97
+ * in the resolver service. Duplicated here — no type-sharing mechanism with
98
+ * the PICA monorepo; drift is caught by the holdout suite.
99
+ */
100
+ export interface ResolveReleaseResult {
101
+ entity_type: "release";
102
+ entity_id: string;
103
+ /** v1 is Spotify-only; field narrowed to reflect the single eligible source. */
104
+ sources_run: Array<"spotify">;
105
+ applied: Array<{
106
+ source: "spotify";
107
+ rule_id: string;
108
+ fields: string[];
109
+ target_entity_type: "release";
110
+ target_entity_id: string;
111
+ }>;
112
+ proposals: Array<{
113
+ proposal_id: string;
114
+ source: "spotify";
115
+ rule_id: string;
116
+ confidence: number | null;
117
+ field_count: number;
118
+ signals: Record<string, unknown> | null;
119
+ }>;
120
+ errors: Array<{
121
+ source: "spotify";
122
+ rule_id?: string;
123
+ error_code: string;
124
+ retry_after_ms?: number;
125
+ message?: string;
126
+ }>;
127
+ overwrote: OverwriteReceipt[];
128
+ skipped_lower_authority: SkippedAuthorityReceipt[];
129
+ recovery_hints: string[];
130
+ }
95
131
  /**
96
132
  * ADR-179 Phase 2 person resolver result. Mirrors the server-side
97
133
  * `ResolvePersonResult` in `lib/services/enrichment-cascade/resolver.ts`.
@@ -278,6 +314,7 @@ interface Recording {
278
314
  isrc?: string;
279
315
  duration_seconds?: number;
280
316
  work_id?: string;
317
+ notes?: string | null;
281
318
  created_at: string;
282
319
  updated_at: string;
283
320
  }
@@ -992,6 +1029,12 @@ declare class AudioFilesResource extends BaseResource {
992
1029
  identify(id: string, options?: {
993
1030
  force?: boolean;
994
1031
  }): Promise<IdentifyResult>;
1032
+ /**
1033
+ * Delete an audio file — removes the DB row AND its underlying storage
1034
+ * object (the service cleans up the bucket object best-effort). Mirrors
1035
+ * RecordingsResource.delete: returns the structured DeletionOutcome.
1036
+ */
1037
+ delete(id: string): Promise<DeletionResult>;
995
1038
  }
996
1039
  declare class MultimediaResource extends BaseResource {
997
1040
  search(params?: {
@@ -1003,10 +1046,7 @@ declare class MultimediaResource extends BaseResource {
1003
1046
  person_id?: string;
1004
1047
  limit?: number;
1005
1048
  offset?: number;
1006
- }): Promise<{
1007
- data: MultimediaItem[];
1008
- count: number;
1009
- }>;
1049
+ }): Promise<PaginatedResult<MultimediaItem>>;
1010
1050
  create(data: Partial<MultimediaItem>): Promise<MultimediaItem>;
1011
1051
  importFromUrl(params: {
1012
1052
  url: string;
@@ -1299,6 +1339,22 @@ declare class EnrichmentResource extends BaseResource {
1299
1339
  */
1300
1340
  force?: boolean;
1301
1341
  }): Promise<ResolveRecordingResult>;
1342
+ /**
1343
+ * Resolve a release against every eligible enrichment source.
1344
+ * v1 is Spotify-only — a release resolve always re-checks Spotify and
1345
+ * gap-fills empty fields via the authority gate (no idempotence stamps
1346
+ * exist for releases). `force` is accepted for API parity but has no
1347
+ * distinct effect here.
1348
+ *
1349
+ * @param releaseId UUID of the release to resolve.
1350
+ * @param options
1351
+ * sources: optional whitelist. v1 supports `spotify` only.
1352
+ * force: accepted for parity; no distinct effect for releases.
1353
+ */
1354
+ resolveRelease(releaseId: string, options?: {
1355
+ sources?: Array<"spotify">;
1356
+ force?: boolean;
1357
+ }): Promise<ResolveReleaseResult>;
1302
1358
  /**
1303
1359
  * ADR-164: manually re-evaluate a work against every cascade rule.
1304
1360
  * Idempotent — rules whose preconditions are already satisfied skip.
@@ -1437,10 +1493,107 @@ declare class RegistrationResource extends BaseResource {
1437
1493
  getCoverage(): Promise<any>;
1438
1494
  getWorkCascadeStatus(workId: string): Promise<any>;
1439
1495
  }
1496
+ export interface CatalogHealthItem {
1497
+ grain: "work" | "recording" | "release" | "person";
1498
+ issue: string;
1499
+ dimension: "completeness" | "cleanliness";
1500
+ severity: "high" | "medium" | "low";
1501
+ count: number;
1502
+ sampleIds: string[];
1503
+ truncated: boolean;
1504
+ needsScope: string | null;
1505
+ actionableByCaller: boolean;
1506
+ }
1507
+ export interface CatalogHealthVerdict {
1508
+ score: number | null;
1509
+ dimensionScores: {
1510
+ completeness: number | null;
1511
+ cleanliness: number | null;
1512
+ };
1513
+ assessed: string[];
1514
+ notAssessed: string[];
1515
+ items: CatalogHealthItem[];
1516
+ generatedAt: string;
1517
+ }
1518
+ export interface CatalogHealthPlanAction {
1519
+ actionId: string;
1520
+ issue: string;
1521
+ actionKind: string;
1522
+ disposition: "auto" | "propose";
1523
+ destructive: boolean;
1524
+ needsScope: string;
1525
+ actionableByCaller: boolean;
1526
+ entityRefs: {
1527
+ type: string;
1528
+ id: string;
1529
+ }[];
1530
+ preview: Record<string, unknown>;
1531
+ }
1532
+ export interface CatalogHealthResidualItem {
1533
+ issue: string;
1534
+ count: number;
1535
+ reason: string;
1536
+ next_tool?: string;
1537
+ }
1538
+ export interface CatalogHealthPlan {
1539
+ score: number | null;
1540
+ dimensionScores: {
1541
+ completeness: number | null;
1542
+ cleanliness: number | null;
1543
+ };
1544
+ targetScore: number;
1545
+ actions: CatalogHealthPlanAction[];
1546
+ residual: CatalogHealthResidualItem[];
1547
+ planToken: string;
1548
+ generatedAt: string;
1549
+ }
1550
+ export interface CatalogHealthAppliedResult {
1551
+ actionId: string;
1552
+ met: true;
1553
+ summary: string;
1554
+ }
1555
+ export interface CatalogHealthSkippedResult {
1556
+ actionId: string;
1557
+ met: false;
1558
+ reason: "scope_denied" | "guard_blocked" | "stale" | "not_accepted";
1559
+ }
1560
+ export interface CatalogHealthFixResult {
1561
+ applied: CatalogHealthAppliedResult[];
1562
+ skipped: CatalogHealthSkippedResult[];
1563
+ verdict: unknown;
1564
+ outcomesRecorded: number;
1565
+ }
1440
1566
  declare class HealthResource extends BaseResource {
1441
1567
  getWorksHealth(): Promise<any>;
1442
1568
  getLowScoreWorks(): Promise<any>;
1443
1569
  getWorkCompleteness(workId: string): Promise<any>;
1570
+ /**
1571
+ * ADR-272 — org-scoped catalog health verdict (completeness + cleanliness
1572
+ * with a ranked punch-list). The route returns `{ success, data: verdict }`;
1573
+ * BaseResource.request unwraps the `{ success, data }` envelope via
1574
+ * `data.data || data`, so this resolves to the verdict object directly
1575
+ * (NOT a second `.data` — the recurring double-unwrap trap). Typed against
1576
+ * the UNWRAPPED shape.
1577
+ */
1578
+ catalogHealth(): Promise<CatalogHealthVerdict>;
1579
+ /**
1580
+ * ADR-273 — scope-gated fix plan. POSTs to /admin/catalog-health/plan,
1581
+ * returns a CatalogHealthPlan with actionable fix-actions + planToken.
1582
+ * Mutates nothing.
1583
+ */
1584
+ catalogHealthPlan(body: {
1585
+ targetScore?: number;
1586
+ only?: string[];
1587
+ }): Promise<CatalogHealthPlan>;
1588
+ /**
1589
+ * ADR-273 — apply accepted fix actions from a prior plan. Requires planToken
1590
+ * from catalogHealthPlan; accept is a list of actionIds (or "all_safe_auto").
1591
+ * Returns honest per-action met/unmet plus a fresh verdict.
1592
+ */
1593
+ catalogHealthFix(body: {
1594
+ planToken: string;
1595
+ accept: string[];
1596
+ }): Promise<CatalogHealthFixResult>;
1444
1597
  }
1445
1598
  declare class DashboardResource extends BaseResource {
1446
1599
  discoveries(params?: {
@@ -2142,6 +2295,13 @@ declare class ExportResource extends BaseResource {
2142
2295
  }): Promise<any>;
2143
2296
  industryReady(params?: {
2144
2297
  work_ids?: string[];
2298
+ /**
2299
+ * "zip" (default) returns a signed-URL JSON envelope to the generated ZIP
2300
+ * on S3. "json" returns the structured export data inline — reachable by
2301
+ * sandboxed agents whose allowlist excludes the S3 host (ops_issue
2302
+ * 8662c489).
2303
+ */
2304
+ format?: "zip" | "json";
2145
2305
  }): Promise<any>;
2146
2306
  catalogAssetReport(params: {
2147
2307
  sections: {
@@ -2497,6 +2657,20 @@ declare class ImportResource extends BaseResource {
2497
2657
  }
2498
2658
  declare class DocumentsResource extends BaseResource {
2499
2659
  analyse(id: string): Promise<Record<string, unknown>>;
2660
+ listCatalog(params?: {
2661
+ parsed_status?: string;
2662
+ limit?: number;
2663
+ offset?: number;
2664
+ }): Promise<{
2665
+ documents: unknown[];
2666
+ total: number;
2667
+ has_more: boolean;
2668
+ }>;
2669
+ read(id: string, params?: {
2670
+ offset?: number;
2671
+ max_chars?: number;
2672
+ }): Promise<Record<string, unknown>>;
2673
+ link(id: string, entity_type: string, entity_id: string): Promise<unknown>;
2500
2674
  }
2501
2675
  interface CollaboratorInvite {
2502
2676
  id: string;
@@ -3176,7 +3350,7 @@ declare class ReleasesResource extends BaseResource {
3176
3350
  }>;
3177
3351
  create(data: Record<string, any>): Promise<any>;
3178
3352
  update(id: string, data: Record<string, any>): Promise<any>;
3179
- delete(id: string): Promise<any>;
3353
+ delete(id: string): Promise<DeletionResult>;
3180
3354
  /**
3181
3355
  * ADR-173: attach a recording and/or work to a release at a
3182
3356
  * specific (disc, track) position. Idempotent on position.
@@ -3445,6 +3619,9 @@ declare class RegisterResource extends BaseResource {
3445
3619
  recording_id: string;
3446
3620
  completeness_score?: number;
3447
3621
  master_ownership: "created" | "failed";
3622
+ template_application?: "skipped" | "applied" | "partial";
3623
+ definition_of_done_met?: boolean;
3624
+ unmet_reasons?: string[];
3448
3625
  }>;
3449
3626
  }
3450
3627
  declare class RecordingSamplesResource extends BaseResource {