@withpica/mcp-sdk 3.24.0 → 3.26.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,51 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ## [3.26.0] - 2026-10-17
15
+
16
+ ### Added
17
+
18
+ - `credits.listRowsForWork(workId)` → `WorkCreditRows`: every credit row on a work, one entry per row
19
+ with its own `id`, its `role`, its `grain` (`composition` = songwriting, `master` = recording) and,
20
+ for a master credit, its `recording_id`; plus `count` (rows) and `people_count` (distinct people).
21
+ Reads `GET /admin/works/{id}/credits?view=rows`. `listForWork` still groups per person.
22
+
23
+ ## [3.25.0] - 2026-10-14
24
+
25
+ > **Publish order:** `asideFromReport` is imported as a value by
26
+ > `@withpica/mcp-utils`'s billing gate. Publish this package (3.25.0) BEFORE
27
+ > the mcp-utils release that uses it, and raise mcp-utils' range to `^3.25.0`
28
+ > in that release; an mcp-utils on an older SDK fails at load.
29
+
30
+ ### Added
31
+
32
+ - `asideFromReport(fn)`: run requests that still name the current client
33
+ catalogue, but leave them off the call's report (a check PICA makes for
34
+ itself, such as the billing gate reading whether the catalogue is paid for).
35
+ - `pica.handovers`: `create` and `send` for catalogues an organisation prepares for a client
36
+ (`POST /admin/handovers`, `POST /admin/handovers/{id}/send`), with `HandoverCreatedRecord` and
37
+ `HandoverRecord`.
38
+ - `runInCatalogue(id, fn)` → `{ value, report }` and `CatalogueCallReport` (ADR-333 D7): what the app
39
+ did with one call's requests in a client catalogue — how many it answered for that catalogue, and
40
+ each request it refused with `RELATIONSHIP_REFUSED` (path and `reason_code`, from the one
41
+ refusal shape: `error.code`, `error.details.reason_code`). The MCP server uses it so a tool that fails its parts soft
42
+ cannot answer "success" with every part refused. `withCatalogue` is unchanged for callers.
43
+ - `withCatalogue(id, fn)`, `currentCatalogue()`, `CATALOGUE_HEADER`, `CATALOGUE_RESOLVED_HEADER` and
44
+ `CatalogueNotHonouredError` (ADR-333 D7). Every request made inside `withCatalogue` sends
45
+ `x-pica-catalogue: <id>`. A successful answer without a matching `x-pica-catalogue-resolved`
46
+ echo throws `CatalogueNotHonouredError` instead of reporting success, so a route that ignores
47
+ the header can never pass for having acted for the client. The catalogue is held per call
48
+ (AsyncLocalStorage), so concurrent calls on one shared client never mix catalogues.
49
+ - `relationships` (ADR-333): `list`, `get`, `invite`, `answer`, `revoke`, `stepDown`, `events`,
50
+ `activity` and `acceptInvite` over `/admin/relationships/**`, with typed records
51
+ (`RelationshipRecord`, `RelationshipListPage`, `RelationshipEventRecord`,
52
+ `RelationshipStepRecord`, `ClaimableInviteRecord`). Every step sends `expected_version`.
53
+ - `portfolio` (ADR-333): `list` and `briefing` over `/admin/portfolio`, with
54
+ `PortfolioClientRecord` and `PortfolioSection` (a section is checked, out of scope, unavailable
55
+ or failed, never a bare 0).
56
+ - `duplicates.markDifferent(entityType, ids)` and `duplicates.unmarkDifferent(entityType, ids)`
57
+ for recordings and releases (`POST` / `DELETE /admin/catalog/duplicates/exclusions`).
58
+
14
59
  ## [3.24.0] - 2026-10-09
15
60
 
16
61
  ### Added
package/dist/index.d.ts CHANGED
@@ -1,7 +1,3 @@
1
- /**
2
- * Lightweight PICA SDK client for MCP server
3
- * Uses the PICA API directly without external dependencies
4
- */
5
1
  /**
6
2
  * ADR-179 resolver result shape. Mirrors the server-side
7
3
  * `ResolveWorkResult` in `lib/services/enrichment-cascade/resolver.ts`.
@@ -406,6 +402,30 @@ interface WorkCredit {
406
402
  split_status?: string;
407
403
  is_owner?: boolean;
408
404
  }
405
+ /** One credit row on a work, from GET /admin/works/:id/credits?view=rows. */
406
+ export interface WorkCreditRow {
407
+ /** The row's own id: work_collaborators.id or recording_credits.id. */
408
+ id: string;
409
+ /** "composition" = songwriting (work_collaborators), "master" = recording (recording_credits). */
410
+ grain: "composition" | "master";
411
+ person_id: string;
412
+ person_name: string;
413
+ ipi: string | null;
414
+ role: string;
415
+ split_percentage: number | null;
416
+ /** Set for a master credit: the recording it is on. */
417
+ recording_id: string | null;
418
+ is_primary: boolean | null;
419
+ notes: string | null;
420
+ attestation_status: string | null;
421
+ }
422
+ export interface WorkCreditRows {
423
+ credits: WorkCreditRow[];
424
+ /** Number of credit rows. */
425
+ count: number;
426
+ /** Number of distinct people among them. */
427
+ people_count: number;
428
+ }
409
429
  interface WorkCreditsInput {
410
430
  credits: Array<{
411
431
  person_id: string;
@@ -870,6 +890,69 @@ export declare class ApiError extends Error {
870
890
  retryAfterMs?: number | undefined;
871
891
  constructor(message: string, status: number, retryable: boolean, retryAfterMs?: number | undefined);
872
892
  }
893
+ /**
894
+ * ADR-333 D7 — acting for a client catalogue, one call at a time.
895
+ *
896
+ * An organisation's assistant names the client catalogue on each tool call
897
+ * (the optional `catalogue` argument). The MCP server runs that call inside
898
+ * `withCatalogue(id, …)`, and every request the call makes carries
899
+ * `x-pica-catalogue: <id>`. The app resolves it through the relationship on
900
+ * every request (PR 1.3) and answers with `x-pica-catalogue-resolved: <id>`.
901
+ *
902
+ * A per-call context, not a field on the client: the stdio server shares one
903
+ * client across concurrent tool calls, so a field would leak one call's
904
+ * catalogue into another's requests.
905
+ *
906
+ * Fails closed: a 2xx answer without a matching echo means the route did not
907
+ * act for that catalogue (it may have used the caller's own), so the call
908
+ * throws `CatalogueNotHonouredError` instead of reporting success. This is the
909
+ * client's check only; stopping such a route from writing at all is the app's
910
+ * job (PR 1.3 refuses a catalogue header it did not resolve).
911
+ */
912
+ export declare const CATALOGUE_HEADER = "x-pica-catalogue";
913
+ export declare const CATALOGUE_RESOLVED_HEADER = "x-pica-catalogue-resolved";
914
+ /**
915
+ * What the app did with one call's requests in a client catalogue: how many it
916
+ * answered for that catalogue, and which it refused because the route does
917
+ * not open through a relationship, or because the relationship does not
918
+ * allow it (code RELATIONSHIP_REFUSED: proxy.ts, the request-context
919
+ * builders, requireCatalogueContext).
920
+ * The MCP server reads it after the tool returns: a tool that fails its parts
921
+ * soft would otherwise answer "success" with every part refused.
922
+ */
923
+ export interface CatalogueCallReport {
924
+ catalogueId: string;
925
+ answered: number;
926
+ refused: Array<{
927
+ path: string;
928
+ reason: string | null;
929
+ }>;
930
+ }
931
+ /** Run `fn` with every SDK request in it acting for `catalogueId`. */
932
+ export declare function withCatalogue<T>(catalogueId: string | undefined, fn: () => Promise<T>): Promise<T>;
933
+ /**
934
+ * `withCatalogue`, also returning the call's report. The report is the one
935
+ * the call's requests wrote to; it is complete once `fn` settles.
936
+ */
937
+ export declare function runInCatalogue<T>(catalogueId: string, fn: () => Promise<T>): Promise<{
938
+ value: T;
939
+ report: CatalogueCallReport;
940
+ }>;
941
+ /** The catalogue the current call acts for, if any. */
942
+ export declare function currentCatalogue(): string | undefined;
943
+ /**
944
+ * Run `fn` in the current client catalogue (its requests still name it), but
945
+ * leave its requests off the current call's report: for a check PICA makes
946
+ * for itself, which must not read as the tool's own work having been
947
+ * answered (the MCP server judges a call "every part refused" by that
948
+ * report). No caller since the MCP billing gate was retired (ADR-335); kept
949
+ * because it is part of the published SDK.
950
+ */
951
+ export declare function asideFromReport<T>(fn: () => Promise<T>): Promise<T>;
952
+ export declare class CatalogueNotHonouredError extends ApiError {
953
+ catalogueId: string;
954
+ constructor(catalogueId: string, path: string);
955
+ }
873
956
  /**
874
957
  * Uniform delete outcome (mirrors the server's deletion contract). `deleted` =
875
958
  * gone; `archived` = hidden but kept (registry data / dependents preserved);
@@ -1520,6 +1603,11 @@ export interface AtomicCreditResult {
1520
1603
  }
1521
1604
  declare class CreditsResource extends BaseResource {
1522
1605
  listForWork(workId: string): Promise<WorkCredit[]>;
1606
+ /**
1607
+ * Every credit row on a work, composition and master, one entry per row
1608
+ * with its own id (listForWork groups per person and keeps one id).
1609
+ */
1610
+ listRowsForWork(workId: string): Promise<WorkCreditRows>;
1523
1611
  updateForWork(workId: string, credits: WorkCreditsInput): Promise<WorkCredit[]>;
1524
1612
  listCollaborators(workId: string): Promise<WorkCredit[]>;
1525
1613
  updateCollaborators(workId: string, collaborators: WorkCreditsInput): Promise<WorkCredit[]>;
@@ -3654,6 +3742,14 @@ declare class DuplicatesResource extends BaseResource {
3654
3742
  */
3655
3743
  findDuplicates(entityType: "works" | "people" | "releases" | "recordings" | "audio_files"): Promise<any>;
3656
3744
  merge(entityType: "work" | "person" | "recording" | "release", winnerId: string, loserIds: string[]): Promise<any>;
3745
+ /**
3746
+ * "They're different": mark every pair among `ids` (2–25 recordings or
3747
+ * releases of this catalogue) as not duplicates, so findDuplicates stops
3748
+ * offering them. Idempotent. Resolves {entity_type, ids, pairs, changed}.
3749
+ */
3750
+ markDifferent(entityType: "recordings" | "releases", ids: string[]): Promise<any>;
3751
+ /** Take back markDifferent for every pair among `ids`. */
3752
+ unmarkDifferent(entityType: "recordings" | "releases", ids: string[]): Promise<any>;
3657
3753
  }
3658
3754
  declare class EntityContextResource extends BaseResource {
3659
3755
  getWorkFull(workId: string): Promise<Record<string, unknown>>;
@@ -5207,6 +5303,318 @@ declare class RightsResource extends BaseResource {
5207
5303
  /** GET /admin/rights-statements/measures — the four measures (ADR-321 §7a). */
5208
5304
  measures(): Promise<any>;
5209
5305
  }
5306
+ /** A relationship's scope, as the routes return it (camelCase). */
5307
+ export interface RelationshipScopeRecord {
5308
+ half: "both" | "composition" | "master";
5309
+ territories: string[];
5310
+ termStartsOn: string | null;
5311
+ termEndsOn: string | null;
5312
+ money: boolean;
5313
+ directory: boolean;
5314
+ catalogue: "whole" | "chosen";
5315
+ workIds: string[];
5316
+ recordingIds: string[];
5317
+ }
5318
+ /**
5319
+ * One relationship (`org_grants` row) as GET /admin/relationships returns it.
5320
+ * `version` is passed back as `expected_version` on every step, so a step
5321
+ * never lands on terms that changed since they were read.
5322
+ */
5323
+ export interface RelationshipRecord {
5324
+ id: string;
5325
+ grantorOrgId: string;
5326
+ grantorOrgName: string;
5327
+ granteeOrgId: string;
5328
+ granteeOrgName: string;
5329
+ type: "co_owner" | "administrator" | "representative" | "viewer";
5330
+ status: "proposed" | "active" | "declined" | "revoked" | "stepped_down" | "expired" | "suspended";
5331
+ proposedBySide: "grantor" | "grantee";
5332
+ scope: RelationshipScopeRecord;
5333
+ proposedAt: string;
5334
+ respondedAt: string | null;
5335
+ endedAt: string | null;
5336
+ endReason: string | null;
5337
+ proposalExpiresAt: string | null;
5338
+ suspendedAt: string | null;
5339
+ version: number;
5340
+ [key: string]: unknown;
5341
+ }
5342
+ /** An invitation waiting for the person (no address in it). */
5343
+ export interface ClaimableInviteRecord {
5344
+ invite_id: string;
5345
+ direction: "grantee_invites_owner" | "owner_invites_grantee";
5346
+ inviting_org_id: string;
5347
+ inviting_org_name: string;
5348
+ type: RelationshipRecord["type"];
5349
+ scope: RelationshipScopeRecord;
5350
+ expires_at: string;
5351
+ eligible_organisations: Array<{
5352
+ id: string;
5353
+ name: string;
5354
+ }>;
5355
+ }
5356
+ export interface RelationshipListPage {
5357
+ rows: RelationshipRecord[];
5358
+ nextCursor: string | null;
5359
+ waiting_for_you: ClaimableInviteRecord[];
5360
+ /** Set when the waiting invitations could not be read: never "none waiting". */
5361
+ waiting_for_you_unavailable?: "email_not_verified" | "check_failed";
5362
+ }
5363
+ /** One audit row (`org_grant_events`). */
5364
+ export interface RelationshipEventRecord {
5365
+ id: string;
5366
+ relationshipId: string;
5367
+ kind: string;
5368
+ at: string;
5369
+ actorSide: "grantor" | "grantee" | "system" | "platform";
5370
+ actorDisplayName: string | null;
5371
+ grantorOrgId: string;
5372
+ grantorOrgName: string;
5373
+ granteeOrgId: string;
5374
+ granteeOrgName: string;
5375
+ type: RelationshipRecord["type"];
5376
+ typeBefore: RelationshipRecord["type"] | null;
5377
+ statusBefore: RelationshipRecord["status"] | null;
5378
+ statusAfter: RelationshipRecord["status"];
5379
+ version: number;
5380
+ /** The scope before this event (null for `proposed`). */
5381
+ scopeBefore: RelationshipScopeRecord | null;
5382
+ /** The scope after this event (for an ending: the scope that ended). */
5383
+ scope: RelationshipScopeRecord;
5384
+ reason: string | null;
5385
+ action: string | null;
5386
+ entityType: string | null;
5387
+ entityId: string | null;
5388
+ detail: Record<string, unknown>;
5389
+ [key: string]: unknown;
5390
+ }
5391
+ export interface RelationshipPageOf<T> {
5392
+ rows: T[];
5393
+ nextCursor: string | null;
5394
+ }
5395
+ /** The result of accepting, declining, editing, revoking or stepping down. */
5396
+ export interface RelationshipStepRecord {
5397
+ relationship: RelationshipRecord;
5398
+ event: RelationshipEventRecord | null;
5399
+ }
5400
+ /** The result of accepting an invitation: the claim and the accept, both recorded. */
5401
+ export interface RelationshipInviteAcceptRecord {
5402
+ relationship: RelationshipRecord;
5403
+ events: RelationshipEventRecord[];
5404
+ }
5405
+ /** A hand-over just created (ADR-333 D5): nothing is sent yet. */
5406
+ export interface HandoverCreatedRecord {
5407
+ handover_id: string;
5408
+ catalogue_org_id: string;
5409
+ }
5410
+ /** A hand-over as its builder sees it (POST /admin/handovers/{id}/send). */
5411
+ export interface HandoverRecord {
5412
+ handover_id: string;
5413
+ catalogue_org_id: string;
5414
+ catalogue_name: string | null;
5415
+ builder_org_id: string;
5416
+ builder_name: string | null;
5417
+ client_name: string;
5418
+ client_email?: string;
5419
+ status: string;
5420
+ relationship_type: string;
5421
+ sent_at: string | null;
5422
+ expires_at: string | null;
5423
+ version: number;
5424
+ }
5425
+ /**
5426
+ * Catalogues an organisation builds for a client, who accepts to own them
5427
+ * (ADR-333 D5). Builder side only: the client answers on screen, signed in.
5428
+ */
5429
+ declare class HandoversResource extends BaseResource {
5430
+ /**
5431
+ * POST /admin/handovers — create a catalogue for a client
5432
+ * (catalogue_name), or a new hand-over on one this organisation built whose
5433
+ * last one closed (catalogue_org_id). Nothing is sent.
5434
+ */
5435
+ create(body: {
5436
+ catalogue_name?: string;
5437
+ catalogue_org_id?: string;
5438
+ client_name: string;
5439
+ client_email: string;
5440
+ relationship_type: string;
5441
+ }): Promise<HandoverCreatedRecord>;
5442
+ /** POST /admin/handovers/{id}/send { expected_version? } — email the client. */
5443
+ send(id: string, body: {
5444
+ expected_version?: number;
5445
+ }): Promise<HandoverRecord>;
5446
+ }
5447
+ /**
5448
+ * /admin/relationships/** — both sides of a relationship. Refusals arrive as
5449
+ * `{ success: false, error: { code, message, details? } }` (read them with
5450
+ * the MCP package's parseApiErrorBody); a step whose terms changed since they
5451
+ * were read is a 409 `status_changed` carrying `details.relationship`.
5452
+ */
5453
+ declare class RelationshipsResource extends BaseResource {
5454
+ /** GET /admin/relationships?side=owner|organisation&status=&cursor=&limit= */
5455
+ list(params: {
5456
+ side: "owner" | "organisation";
5457
+ statuses?: string[];
5458
+ cursor?: string;
5459
+ limit?: number;
5460
+ }): Promise<RelationshipListPage>;
5461
+ /** GET /admin/relationships/{id} */
5462
+ get(id: string): Promise<RelationshipRecord>;
5463
+ /**
5464
+ * POST /admin/relationships { as, email, type, scope? } — invite someone by
5465
+ * email. as="owner" asks someone at an organisation to look after this
5466
+ * catalogue; as="organisation" asks a client to let this organisation look
5467
+ * after theirs. The reply is the same whether or not the address is on PICA.
5468
+ */
5469
+ invite(body: {
5470
+ as: "owner" | "organisation";
5471
+ email: string;
5472
+ type: string;
5473
+ scope?: Record<string, unknown>;
5474
+ }): Promise<Record<string, unknown>>;
5475
+ /** PATCH /admin/relationships/{id} { action: accept | decline | edit, expected_version, … } */
5476
+ answer(id: string, body: {
5477
+ action: "accept" | "decline" | "edit";
5478
+ expected_version: number;
5479
+ type?: string;
5480
+ scope?: Record<string, unknown>;
5481
+ reason?: string;
5482
+ }): Promise<RelationshipStepRecord>;
5483
+ /** DELETE /admin/relationships/{id} { expected_version, reason? } — the owner ends it. */
5484
+ revoke(id: string, body: {
5485
+ expected_version: number;
5486
+ reason?: string;
5487
+ }): Promise<RelationshipStepRecord>;
5488
+ /** POST /admin/relationships/{id}/step-down { expected_version, reason? } — the organisation ends its side. */
5489
+ stepDown(id: string, body: {
5490
+ expected_version: number;
5491
+ reason?: string;
5492
+ }): Promise<RelationshipStepRecord>;
5493
+ /** GET /admin/relationships/{id}/activity — one relationship's history, either party. */
5494
+ events(id: string, params?: {
5495
+ cursor?: string;
5496
+ limit?: number;
5497
+ }): Promise<RelationshipPageOf<RelationshipEventRecord>>;
5498
+ /**
5499
+ * GET /admin/relationships/activity?side=&org= — side=owner: what
5500
+ * organisations did in this catalogue (org = one organisation);
5501
+ * side=organisation: this organisation's own actions (org = one catalogue).
5502
+ */
5503
+ activity(params: {
5504
+ side: "owner" | "organisation";
5505
+ org?: string;
5506
+ cursor?: string;
5507
+ limit?: number;
5508
+ }): Promise<RelationshipPageOf<RelationshipEventRecord>>;
5509
+ /**
5510
+ * PATCH /admin/relationships/invites/{id} { action: "accept", organisation_id, type?, scope? }
5511
+ * — answer yes to an invitation for one of the person's organisations.
5512
+ */
5513
+ acceptInvite(inviteId: string, body: {
5514
+ organisation_id: string;
5515
+ type?: string;
5516
+ scope?: Record<string, unknown>;
5517
+ }): Promise<RelationshipInviteAcceptRecord>;
5518
+ }
5519
+ /** A portfolio section: checked, out of scope, unavailable, or failed (never 0). */
5520
+ export type PortfolioSection<T> = {
5521
+ state: "ok";
5522
+ data: T;
5523
+ } | {
5524
+ state: "not_in_scope" | "unavailable" | "failed";
5525
+ reason: string;
5526
+ };
5527
+ /** One client catalogue an organisation looks after (portfolio PR 1.4). */
5528
+ export interface PortfolioClientRecord {
5529
+ relationshipId: string;
5530
+ catalogue: {
5531
+ orgId: string;
5532
+ name: string;
5533
+ };
5534
+ relationship: {
5535
+ type: RelationshipRecord["type"];
5536
+ typeLabel: string;
5537
+ status: "active" | "suspended";
5538
+ access: "open" | "paused" | "not_started";
5539
+ acceptedAt: string | null;
5540
+ termEndsOn: string | null;
5541
+ endingSoon: boolean;
5542
+ version: number;
5543
+ /** What a change by this caller does in that catalogue. */
5544
+ changes: "direct" | "proposal" | "none";
5545
+ scope: {
5546
+ half: RelationshipScopeRecord["half"];
5547
+ territories: string[];
5548
+ termStartsOn: string | null;
5549
+ termEndsOn: string | null;
5550
+ money: boolean;
5551
+ directory: boolean;
5552
+ catalogue: "whole" | "chosen";
5553
+ songsChosen: number;
5554
+ recordingsChosen: number;
5555
+ };
5556
+ };
5557
+ /** null = the scope doesn't cover that half ("not covered", never 0). */
5558
+ missing: PortfolioSection<{
5559
+ songs: number | null;
5560
+ songsWithGaps: number | null;
5561
+ recordings: number | null;
5562
+ recordingsWithGaps: number | null;
5563
+ }>;
5564
+ moneyBlockers: PortfolioSection<{
5565
+ songs: number;
5566
+ blocked: number;
5567
+ clear: number;
5568
+ unknown: number;
5569
+ byCode: Array<{
5570
+ code: string;
5571
+ label: string;
5572
+ songs: number;
5573
+ }>;
5574
+ }>;
5575
+ enquiries: PortfolioSection<{
5576
+ waiting: number;
5577
+ oldestAt: string | null;
5578
+ }>;
5579
+ deadlines: PortfolioSection<{
5580
+ total: number;
5581
+ items: Array<{
5582
+ kind: string;
5583
+ on: string;
5584
+ label: string;
5585
+ }>;
5586
+ }>;
5587
+ /** Briefing only: at most five, in scope only. */
5588
+ highlights?: Array<{
5589
+ kind: string;
5590
+ label: string;
5591
+ workId?: string;
5592
+ recordingId?: string;
5593
+ }>;
5594
+ [key: string]: unknown;
5595
+ }
5596
+ export interface PortfolioPage {
5597
+ rows: PortfolioClientRecord[];
5598
+ nextCursor: string | null;
5599
+ asOf: string;
5600
+ }
5601
+ /**
5602
+ * /admin/portfolio — the client catalogues an organisation looks after. A
5603
+ * page may hold fewer rows than `limit` and still not be the last: follow
5604
+ * `nextCursor` until it is null.
5605
+ */
5606
+ declare class PortfolioResource extends BaseResource {
5607
+ /** GET /admin/portfolio?cursor=&limit= (limit ≤ 25) */
5608
+ list(params?: {
5609
+ cursor?: string;
5610
+ limit?: number;
5611
+ }): Promise<PortfolioPage>;
5612
+ /** GET /admin/portfolio/briefing?cursor=&limit= — the list plus what needs attention. */
5613
+ briefing(params?: {
5614
+ cursor?: string;
5615
+ limit?: number;
5616
+ }): Promise<PortfolioPage>;
5617
+ }
5210
5618
  declare class RoyaltiesResource extends BaseResource {
5211
5619
  payments(params?: {
5212
5620
  source?: string;
@@ -5748,6 +6156,11 @@ export declare class PicaClient {
5748
6156
  producerAgreements: ProducerAgreementsResource;
5749
6157
  workForHire: WorkForHireResource;
5750
6158
  royalties: RoyaltiesResource;
6159
+ /** ADR-333 — who looks after whose catalogue, from either side. */
6160
+ relationships: RelationshipsResource;
6161
+ handovers: HandoversResource;
6162
+ /** ADR-333 — the client catalogues an organisation looks after. */
6163
+ portfolio: PortfolioResource;
5751
6164
  /** ADR-321 Phase 2 — programmable rights (propose / status / inspect). */
5752
6165
  rights: RightsResource;
5753
6166
  statements: StatementsResource;