@withpica/mcp-sdk 3.24.0 → 3.25.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 +36 -0
- package/dist/index.d.ts +387 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +253 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -11,6 +11,42 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
11
11
|
|
|
12
12
|
## [Unreleased]
|
|
13
13
|
|
|
14
|
+
## [3.25.0] - 2026-10-14
|
|
15
|
+
|
|
16
|
+
> **Publish order:** `asideFromReport` is imported as a value by
|
|
17
|
+
> `@withpica/mcp-utils`'s billing gate. Publish this package (3.25.0) BEFORE
|
|
18
|
+
> the mcp-utils release that uses it, and raise mcp-utils' range to `^3.25.0`
|
|
19
|
+
> in that release; an mcp-utils on an older SDK fails at load.
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- `asideFromReport(fn)`: run requests that still name the current client
|
|
24
|
+
catalogue, but leave them off the call's report (a check PICA makes for
|
|
25
|
+
itself, such as the billing gate reading whether the catalogue is paid for).
|
|
26
|
+
- `pica.handovers`: `create` and `send` for catalogues an organisation prepares for a client
|
|
27
|
+
(`POST /admin/handovers`, `POST /admin/handovers/{id}/send`), with `HandoverCreatedRecord` and
|
|
28
|
+
`HandoverRecord`.
|
|
29
|
+
- `runInCatalogue(id, fn)` → `{ value, report }` and `CatalogueCallReport` (ADR-333 D7): what the app
|
|
30
|
+
did with one call's requests in a client catalogue — how many it answered for that catalogue, and
|
|
31
|
+
each request it refused with `RELATIONSHIP_REFUSED` (path and `reason_code`, from the one
|
|
32
|
+
refusal shape: `error.code`, `error.details.reason_code`). The MCP server uses it so a tool that fails its parts soft
|
|
33
|
+
cannot answer "success" with every part refused. `withCatalogue` is unchanged for callers.
|
|
34
|
+
- `withCatalogue(id, fn)`, `currentCatalogue()`, `CATALOGUE_HEADER`, `CATALOGUE_RESOLVED_HEADER` and
|
|
35
|
+
`CatalogueNotHonouredError` (ADR-333 D7). Every request made inside `withCatalogue` sends
|
|
36
|
+
`x-pica-catalogue: <id>`. A successful answer without a matching `x-pica-catalogue-resolved`
|
|
37
|
+
echo throws `CatalogueNotHonouredError` instead of reporting success, so a route that ignores
|
|
38
|
+
the header can never pass for having acted for the client. The catalogue is held per call
|
|
39
|
+
(AsyncLocalStorage), so concurrent calls on one shared client never mix catalogues.
|
|
40
|
+
- `relationships` (ADR-333): `list`, `get`, `invite`, `answer`, `revoke`, `stepDown`, `events`,
|
|
41
|
+
`activity` and `acceptInvite` over `/admin/relationships/**`, with typed records
|
|
42
|
+
(`RelationshipRecord`, `RelationshipListPage`, `RelationshipEventRecord`,
|
|
43
|
+
`RelationshipStepRecord`, `ClaimableInviteRecord`). Every step sends `expected_version`.
|
|
44
|
+
- `portfolio` (ADR-333): `list` and `briefing` over `/admin/portfolio`, with
|
|
45
|
+
`PortfolioClientRecord` and `PortfolioSection` (a section is checked, out of scope, unavailable
|
|
46
|
+
or failed, never a bare 0).
|
|
47
|
+
- `duplicates.markDifferent(entityType, ids)` and `duplicates.unmarkDifferent(entityType, ids)`
|
|
48
|
+
for recordings and releases (`POST` / `DELETE /admin/catalog/duplicates/exclusions`).
|
|
49
|
+
|
|
14
50
|
## [3.24.0] - 2026-10-09
|
|
15
51
|
|
|
16
52
|
### 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`.
|
|
@@ -870,6 +866,68 @@ export declare class ApiError extends Error {
|
|
|
870
866
|
retryAfterMs?: number | undefined;
|
|
871
867
|
constructor(message: string, status: number, retryable: boolean, retryAfterMs?: number | undefined);
|
|
872
868
|
}
|
|
869
|
+
/**
|
|
870
|
+
* ADR-333 D7 — acting for a client catalogue, one call at a time.
|
|
871
|
+
*
|
|
872
|
+
* An organisation's assistant names the client catalogue on each tool call
|
|
873
|
+
* (the optional `catalogue` argument). The MCP server runs that call inside
|
|
874
|
+
* `withCatalogue(id, …)`, and every request the call makes carries
|
|
875
|
+
* `x-pica-catalogue: <id>`. The app resolves it through the relationship on
|
|
876
|
+
* every request (PR 1.3) and answers with `x-pica-catalogue-resolved: <id>`.
|
|
877
|
+
*
|
|
878
|
+
* A per-call context, not a field on the client: the stdio server shares one
|
|
879
|
+
* client across concurrent tool calls, so a field would leak one call's
|
|
880
|
+
* catalogue into another's requests.
|
|
881
|
+
*
|
|
882
|
+
* Fails closed: a 2xx answer without a matching echo means the route did not
|
|
883
|
+
* act for that catalogue (it may have used the caller's own), so the call
|
|
884
|
+
* throws `CatalogueNotHonouredError` instead of reporting success. This is the
|
|
885
|
+
* client's check only; stopping such a route from writing at all is the app's
|
|
886
|
+
* job (PR 1.3 refuses a catalogue header it did not resolve).
|
|
887
|
+
*/
|
|
888
|
+
export declare const CATALOGUE_HEADER = "x-pica-catalogue";
|
|
889
|
+
export declare const CATALOGUE_RESOLVED_HEADER = "x-pica-catalogue-resolved";
|
|
890
|
+
/**
|
|
891
|
+
* What the app did with one call's requests in a client catalogue: how many it
|
|
892
|
+
* answered for that catalogue, and which it refused because the route does
|
|
893
|
+
* not open through a relationship, or because the relationship does not
|
|
894
|
+
* allow it (code RELATIONSHIP_REFUSED: proxy.ts, the request-context
|
|
895
|
+
* builders, requireCatalogueContext).
|
|
896
|
+
* The MCP server reads it after the tool returns: a tool that fails its parts
|
|
897
|
+
* soft would otherwise answer "success" with every part refused.
|
|
898
|
+
*/
|
|
899
|
+
export interface CatalogueCallReport {
|
|
900
|
+
catalogueId: string;
|
|
901
|
+
answered: number;
|
|
902
|
+
refused: Array<{
|
|
903
|
+
path: string;
|
|
904
|
+
reason: string | null;
|
|
905
|
+
}>;
|
|
906
|
+
}
|
|
907
|
+
/** Run `fn` with every SDK request in it acting for `catalogueId`. */
|
|
908
|
+
export declare function withCatalogue<T>(catalogueId: string | undefined, fn: () => Promise<T>): Promise<T>;
|
|
909
|
+
/**
|
|
910
|
+
* `withCatalogue`, also returning the call's report. The report is the one
|
|
911
|
+
* the call's requests wrote to; it is complete once `fn` settles.
|
|
912
|
+
*/
|
|
913
|
+
export declare function runInCatalogue<T>(catalogueId: string, fn: () => Promise<T>): Promise<{
|
|
914
|
+
value: T;
|
|
915
|
+
report: CatalogueCallReport;
|
|
916
|
+
}>;
|
|
917
|
+
/** The catalogue the current call acts for, if any. */
|
|
918
|
+
export declare function currentCatalogue(): string | undefined;
|
|
919
|
+
/**
|
|
920
|
+
* Run `fn` in the current client catalogue (its requests still name it), but
|
|
921
|
+
* leave its requests off the current call's report: for a check PICA makes
|
|
922
|
+
* for itself (the billing gate reading the client's plan), which must not
|
|
923
|
+
* read as the tool's own work having been answered (the MCP server judges a
|
|
924
|
+
* call "every part refused" by that report).
|
|
925
|
+
*/
|
|
926
|
+
export declare function asideFromReport<T>(fn: () => Promise<T>): Promise<T>;
|
|
927
|
+
export declare class CatalogueNotHonouredError extends ApiError {
|
|
928
|
+
catalogueId: string;
|
|
929
|
+
constructor(catalogueId: string, path: string);
|
|
930
|
+
}
|
|
873
931
|
/**
|
|
874
932
|
* Uniform delete outcome (mirrors the server's deletion contract). `deleted` =
|
|
875
933
|
* gone; `archived` = hidden but kept (registry data / dependents preserved);
|
|
@@ -3654,6 +3712,14 @@ declare class DuplicatesResource extends BaseResource {
|
|
|
3654
3712
|
*/
|
|
3655
3713
|
findDuplicates(entityType: "works" | "people" | "releases" | "recordings" | "audio_files"): Promise<any>;
|
|
3656
3714
|
merge(entityType: "work" | "person" | "recording" | "release", winnerId: string, loserIds: string[]): Promise<any>;
|
|
3715
|
+
/**
|
|
3716
|
+
* "They're different": mark every pair among `ids` (2–25 recordings or
|
|
3717
|
+
* releases of this catalogue) as not duplicates, so findDuplicates stops
|
|
3718
|
+
* offering them. Idempotent. Resolves {entity_type, ids, pairs, changed}.
|
|
3719
|
+
*/
|
|
3720
|
+
markDifferent(entityType: "recordings" | "releases", ids: string[]): Promise<any>;
|
|
3721
|
+
/** Take back markDifferent for every pair among `ids`. */
|
|
3722
|
+
unmarkDifferent(entityType: "recordings" | "releases", ids: string[]): Promise<any>;
|
|
3657
3723
|
}
|
|
3658
3724
|
declare class EntityContextResource extends BaseResource {
|
|
3659
3725
|
getWorkFull(workId: string): Promise<Record<string, unknown>>;
|
|
@@ -5207,6 +5273,318 @@ declare class RightsResource extends BaseResource {
|
|
|
5207
5273
|
/** GET /admin/rights-statements/measures — the four measures (ADR-321 §7a). */
|
|
5208
5274
|
measures(): Promise<any>;
|
|
5209
5275
|
}
|
|
5276
|
+
/** A relationship's scope, as the routes return it (camelCase). */
|
|
5277
|
+
export interface RelationshipScopeRecord {
|
|
5278
|
+
half: "both" | "composition" | "master";
|
|
5279
|
+
territories: string[];
|
|
5280
|
+
termStartsOn: string | null;
|
|
5281
|
+
termEndsOn: string | null;
|
|
5282
|
+
money: boolean;
|
|
5283
|
+
directory: boolean;
|
|
5284
|
+
catalogue: "whole" | "chosen";
|
|
5285
|
+
workIds: string[];
|
|
5286
|
+
recordingIds: string[];
|
|
5287
|
+
}
|
|
5288
|
+
/**
|
|
5289
|
+
* One relationship (`org_grants` row) as GET /admin/relationships returns it.
|
|
5290
|
+
* `version` is passed back as `expected_version` on every step, so a step
|
|
5291
|
+
* never lands on terms that changed since they were read.
|
|
5292
|
+
*/
|
|
5293
|
+
export interface RelationshipRecord {
|
|
5294
|
+
id: string;
|
|
5295
|
+
grantorOrgId: string;
|
|
5296
|
+
grantorOrgName: string;
|
|
5297
|
+
granteeOrgId: string;
|
|
5298
|
+
granteeOrgName: string;
|
|
5299
|
+
type: "co_owner" | "administrator" | "representative" | "viewer";
|
|
5300
|
+
status: "proposed" | "active" | "declined" | "revoked" | "stepped_down" | "expired" | "suspended";
|
|
5301
|
+
proposedBySide: "grantor" | "grantee";
|
|
5302
|
+
scope: RelationshipScopeRecord;
|
|
5303
|
+
proposedAt: string;
|
|
5304
|
+
respondedAt: string | null;
|
|
5305
|
+
endedAt: string | null;
|
|
5306
|
+
endReason: string | null;
|
|
5307
|
+
proposalExpiresAt: string | null;
|
|
5308
|
+
suspendedAt: string | null;
|
|
5309
|
+
version: number;
|
|
5310
|
+
[key: string]: unknown;
|
|
5311
|
+
}
|
|
5312
|
+
/** An invitation waiting for the person (no address in it). */
|
|
5313
|
+
export interface ClaimableInviteRecord {
|
|
5314
|
+
invite_id: string;
|
|
5315
|
+
direction: "grantee_invites_owner" | "owner_invites_grantee";
|
|
5316
|
+
inviting_org_id: string;
|
|
5317
|
+
inviting_org_name: string;
|
|
5318
|
+
type: RelationshipRecord["type"];
|
|
5319
|
+
scope: RelationshipScopeRecord;
|
|
5320
|
+
expires_at: string;
|
|
5321
|
+
eligible_organisations: Array<{
|
|
5322
|
+
id: string;
|
|
5323
|
+
name: string;
|
|
5324
|
+
}>;
|
|
5325
|
+
}
|
|
5326
|
+
export interface RelationshipListPage {
|
|
5327
|
+
rows: RelationshipRecord[];
|
|
5328
|
+
nextCursor: string | null;
|
|
5329
|
+
waiting_for_you: ClaimableInviteRecord[];
|
|
5330
|
+
/** Set when the waiting invitations could not be read: never "none waiting". */
|
|
5331
|
+
waiting_for_you_unavailable?: "email_not_verified" | "check_failed";
|
|
5332
|
+
}
|
|
5333
|
+
/** One audit row (`org_grant_events`). */
|
|
5334
|
+
export interface RelationshipEventRecord {
|
|
5335
|
+
id: string;
|
|
5336
|
+
relationshipId: string;
|
|
5337
|
+
kind: string;
|
|
5338
|
+
at: string;
|
|
5339
|
+
actorSide: "grantor" | "grantee" | "system" | "platform";
|
|
5340
|
+
actorDisplayName: string | null;
|
|
5341
|
+
grantorOrgId: string;
|
|
5342
|
+
grantorOrgName: string;
|
|
5343
|
+
granteeOrgId: string;
|
|
5344
|
+
granteeOrgName: string;
|
|
5345
|
+
type: RelationshipRecord["type"];
|
|
5346
|
+
typeBefore: RelationshipRecord["type"] | null;
|
|
5347
|
+
statusBefore: RelationshipRecord["status"] | null;
|
|
5348
|
+
statusAfter: RelationshipRecord["status"];
|
|
5349
|
+
version: number;
|
|
5350
|
+
/** The scope before this event (null for `proposed`). */
|
|
5351
|
+
scopeBefore: RelationshipScopeRecord | null;
|
|
5352
|
+
/** The scope after this event (for an ending: the scope that ended). */
|
|
5353
|
+
scope: RelationshipScopeRecord;
|
|
5354
|
+
reason: string | null;
|
|
5355
|
+
action: string | null;
|
|
5356
|
+
entityType: string | null;
|
|
5357
|
+
entityId: string | null;
|
|
5358
|
+
detail: Record<string, unknown>;
|
|
5359
|
+
[key: string]: unknown;
|
|
5360
|
+
}
|
|
5361
|
+
export interface RelationshipPageOf<T> {
|
|
5362
|
+
rows: T[];
|
|
5363
|
+
nextCursor: string | null;
|
|
5364
|
+
}
|
|
5365
|
+
/** The result of accepting, declining, editing, revoking or stepping down. */
|
|
5366
|
+
export interface RelationshipStepRecord {
|
|
5367
|
+
relationship: RelationshipRecord;
|
|
5368
|
+
event: RelationshipEventRecord | null;
|
|
5369
|
+
}
|
|
5370
|
+
/** The result of accepting an invitation: the claim and the accept, both recorded. */
|
|
5371
|
+
export interface RelationshipInviteAcceptRecord {
|
|
5372
|
+
relationship: RelationshipRecord;
|
|
5373
|
+
events: RelationshipEventRecord[];
|
|
5374
|
+
}
|
|
5375
|
+
/** A hand-over just created (ADR-333 D5): nothing is sent yet. */
|
|
5376
|
+
export interface HandoverCreatedRecord {
|
|
5377
|
+
handover_id: string;
|
|
5378
|
+
catalogue_org_id: string;
|
|
5379
|
+
}
|
|
5380
|
+
/** A hand-over as its builder sees it (POST /admin/handovers/{id}/send). */
|
|
5381
|
+
export interface HandoverRecord {
|
|
5382
|
+
handover_id: string;
|
|
5383
|
+
catalogue_org_id: string;
|
|
5384
|
+
catalogue_name: string | null;
|
|
5385
|
+
builder_org_id: string;
|
|
5386
|
+
builder_name: string | null;
|
|
5387
|
+
client_name: string;
|
|
5388
|
+
client_email?: string;
|
|
5389
|
+
status: string;
|
|
5390
|
+
relationship_type: string;
|
|
5391
|
+
sent_at: string | null;
|
|
5392
|
+
expires_at: string | null;
|
|
5393
|
+
version: number;
|
|
5394
|
+
}
|
|
5395
|
+
/**
|
|
5396
|
+
* Catalogues an organisation builds for a client, who accepts to own them
|
|
5397
|
+
* (ADR-333 D5). Builder side only: the client answers on screen, signed in.
|
|
5398
|
+
*/
|
|
5399
|
+
declare class HandoversResource extends BaseResource {
|
|
5400
|
+
/**
|
|
5401
|
+
* POST /admin/handovers — create a catalogue for a client
|
|
5402
|
+
* (catalogue_name), or a new hand-over on one this organisation built whose
|
|
5403
|
+
* last one closed (catalogue_org_id). Nothing is sent.
|
|
5404
|
+
*/
|
|
5405
|
+
create(body: {
|
|
5406
|
+
catalogue_name?: string;
|
|
5407
|
+
catalogue_org_id?: string;
|
|
5408
|
+
client_name: string;
|
|
5409
|
+
client_email: string;
|
|
5410
|
+
relationship_type: string;
|
|
5411
|
+
}): Promise<HandoverCreatedRecord>;
|
|
5412
|
+
/** POST /admin/handovers/{id}/send { expected_version? } — email the client. */
|
|
5413
|
+
send(id: string, body: {
|
|
5414
|
+
expected_version?: number;
|
|
5415
|
+
}): Promise<HandoverRecord>;
|
|
5416
|
+
}
|
|
5417
|
+
/**
|
|
5418
|
+
* /admin/relationships/** — both sides of a relationship. Refusals arrive as
|
|
5419
|
+
* `{ success: false, error: { code, message, details? } }` (read them with
|
|
5420
|
+
* the MCP package's parseApiErrorBody); a step whose terms changed since they
|
|
5421
|
+
* were read is a 409 `status_changed` carrying `details.relationship`.
|
|
5422
|
+
*/
|
|
5423
|
+
declare class RelationshipsResource extends BaseResource {
|
|
5424
|
+
/** GET /admin/relationships?side=owner|organisation&status=&cursor=&limit= */
|
|
5425
|
+
list(params: {
|
|
5426
|
+
side: "owner" | "organisation";
|
|
5427
|
+
statuses?: string[];
|
|
5428
|
+
cursor?: string;
|
|
5429
|
+
limit?: number;
|
|
5430
|
+
}): Promise<RelationshipListPage>;
|
|
5431
|
+
/** GET /admin/relationships/{id} */
|
|
5432
|
+
get(id: string): Promise<RelationshipRecord>;
|
|
5433
|
+
/**
|
|
5434
|
+
* POST /admin/relationships { as, email, type, scope? } — invite someone by
|
|
5435
|
+
* email. as="owner" asks someone at an organisation to look after this
|
|
5436
|
+
* catalogue; as="organisation" asks a client to let this organisation look
|
|
5437
|
+
* after theirs. The reply is the same whether or not the address is on PICA.
|
|
5438
|
+
*/
|
|
5439
|
+
invite(body: {
|
|
5440
|
+
as: "owner" | "organisation";
|
|
5441
|
+
email: string;
|
|
5442
|
+
type: string;
|
|
5443
|
+
scope?: Record<string, unknown>;
|
|
5444
|
+
}): Promise<Record<string, unknown>>;
|
|
5445
|
+
/** PATCH /admin/relationships/{id} { action: accept | decline | edit, expected_version, … } */
|
|
5446
|
+
answer(id: string, body: {
|
|
5447
|
+
action: "accept" | "decline" | "edit";
|
|
5448
|
+
expected_version: number;
|
|
5449
|
+
type?: string;
|
|
5450
|
+
scope?: Record<string, unknown>;
|
|
5451
|
+
reason?: string;
|
|
5452
|
+
}): Promise<RelationshipStepRecord>;
|
|
5453
|
+
/** DELETE /admin/relationships/{id} { expected_version, reason? } — the owner ends it. */
|
|
5454
|
+
revoke(id: string, body: {
|
|
5455
|
+
expected_version: number;
|
|
5456
|
+
reason?: string;
|
|
5457
|
+
}): Promise<RelationshipStepRecord>;
|
|
5458
|
+
/** POST /admin/relationships/{id}/step-down { expected_version, reason? } — the organisation ends its side. */
|
|
5459
|
+
stepDown(id: string, body: {
|
|
5460
|
+
expected_version: number;
|
|
5461
|
+
reason?: string;
|
|
5462
|
+
}): Promise<RelationshipStepRecord>;
|
|
5463
|
+
/** GET /admin/relationships/{id}/activity — one relationship's history, either party. */
|
|
5464
|
+
events(id: string, params?: {
|
|
5465
|
+
cursor?: string;
|
|
5466
|
+
limit?: number;
|
|
5467
|
+
}): Promise<RelationshipPageOf<RelationshipEventRecord>>;
|
|
5468
|
+
/**
|
|
5469
|
+
* GET /admin/relationships/activity?side=&org= — side=owner: what
|
|
5470
|
+
* organisations did in this catalogue (org = one organisation);
|
|
5471
|
+
* side=organisation: this organisation's own actions (org = one catalogue).
|
|
5472
|
+
*/
|
|
5473
|
+
activity(params: {
|
|
5474
|
+
side: "owner" | "organisation";
|
|
5475
|
+
org?: string;
|
|
5476
|
+
cursor?: string;
|
|
5477
|
+
limit?: number;
|
|
5478
|
+
}): Promise<RelationshipPageOf<RelationshipEventRecord>>;
|
|
5479
|
+
/**
|
|
5480
|
+
* PATCH /admin/relationships/invites/{id} { action: "accept", organisation_id, type?, scope? }
|
|
5481
|
+
* — answer yes to an invitation for one of the person's organisations.
|
|
5482
|
+
*/
|
|
5483
|
+
acceptInvite(inviteId: string, body: {
|
|
5484
|
+
organisation_id: string;
|
|
5485
|
+
type?: string;
|
|
5486
|
+
scope?: Record<string, unknown>;
|
|
5487
|
+
}): Promise<RelationshipInviteAcceptRecord>;
|
|
5488
|
+
}
|
|
5489
|
+
/** A portfolio section: checked, out of scope, unavailable, or failed (never 0). */
|
|
5490
|
+
export type PortfolioSection<T> = {
|
|
5491
|
+
state: "ok";
|
|
5492
|
+
data: T;
|
|
5493
|
+
} | {
|
|
5494
|
+
state: "not_in_scope" | "unavailable" | "failed";
|
|
5495
|
+
reason: string;
|
|
5496
|
+
};
|
|
5497
|
+
/** One client catalogue an organisation looks after (portfolio PR 1.4). */
|
|
5498
|
+
export interface PortfolioClientRecord {
|
|
5499
|
+
relationshipId: string;
|
|
5500
|
+
catalogue: {
|
|
5501
|
+
orgId: string;
|
|
5502
|
+
name: string;
|
|
5503
|
+
};
|
|
5504
|
+
relationship: {
|
|
5505
|
+
type: RelationshipRecord["type"];
|
|
5506
|
+
typeLabel: string;
|
|
5507
|
+
status: "active" | "suspended";
|
|
5508
|
+
access: "open" | "paused" | "not_started";
|
|
5509
|
+
acceptedAt: string | null;
|
|
5510
|
+
termEndsOn: string | null;
|
|
5511
|
+
endingSoon: boolean;
|
|
5512
|
+
version: number;
|
|
5513
|
+
/** What a change by this caller does in that catalogue. */
|
|
5514
|
+
changes: "direct" | "proposal" | "none";
|
|
5515
|
+
scope: {
|
|
5516
|
+
half: RelationshipScopeRecord["half"];
|
|
5517
|
+
territories: string[];
|
|
5518
|
+
termStartsOn: string | null;
|
|
5519
|
+
termEndsOn: string | null;
|
|
5520
|
+
money: boolean;
|
|
5521
|
+
directory: boolean;
|
|
5522
|
+
catalogue: "whole" | "chosen";
|
|
5523
|
+
songsChosen: number;
|
|
5524
|
+
recordingsChosen: number;
|
|
5525
|
+
};
|
|
5526
|
+
};
|
|
5527
|
+
/** null = the scope doesn't cover that half ("not covered", never 0). */
|
|
5528
|
+
missing: PortfolioSection<{
|
|
5529
|
+
songs: number | null;
|
|
5530
|
+
songsWithGaps: number | null;
|
|
5531
|
+
recordings: number | null;
|
|
5532
|
+
recordingsWithGaps: number | null;
|
|
5533
|
+
}>;
|
|
5534
|
+
moneyBlockers: PortfolioSection<{
|
|
5535
|
+
songs: number;
|
|
5536
|
+
blocked: number;
|
|
5537
|
+
clear: number;
|
|
5538
|
+
unknown: number;
|
|
5539
|
+
byCode: Array<{
|
|
5540
|
+
code: string;
|
|
5541
|
+
label: string;
|
|
5542
|
+
songs: number;
|
|
5543
|
+
}>;
|
|
5544
|
+
}>;
|
|
5545
|
+
enquiries: PortfolioSection<{
|
|
5546
|
+
waiting: number;
|
|
5547
|
+
oldestAt: string | null;
|
|
5548
|
+
}>;
|
|
5549
|
+
deadlines: PortfolioSection<{
|
|
5550
|
+
total: number;
|
|
5551
|
+
items: Array<{
|
|
5552
|
+
kind: string;
|
|
5553
|
+
on: string;
|
|
5554
|
+
label: string;
|
|
5555
|
+
}>;
|
|
5556
|
+
}>;
|
|
5557
|
+
/** Briefing only: at most five, in scope only. */
|
|
5558
|
+
highlights?: Array<{
|
|
5559
|
+
kind: string;
|
|
5560
|
+
label: string;
|
|
5561
|
+
workId?: string;
|
|
5562
|
+
recordingId?: string;
|
|
5563
|
+
}>;
|
|
5564
|
+
[key: string]: unknown;
|
|
5565
|
+
}
|
|
5566
|
+
export interface PortfolioPage {
|
|
5567
|
+
rows: PortfolioClientRecord[];
|
|
5568
|
+
nextCursor: string | null;
|
|
5569
|
+
asOf: string;
|
|
5570
|
+
}
|
|
5571
|
+
/**
|
|
5572
|
+
* /admin/portfolio — the client catalogues an organisation looks after. A
|
|
5573
|
+
* page may hold fewer rows than `limit` and still not be the last: follow
|
|
5574
|
+
* `nextCursor` until it is null.
|
|
5575
|
+
*/
|
|
5576
|
+
declare class PortfolioResource extends BaseResource {
|
|
5577
|
+
/** GET /admin/portfolio?cursor=&limit= (limit ≤ 25) */
|
|
5578
|
+
list(params?: {
|
|
5579
|
+
cursor?: string;
|
|
5580
|
+
limit?: number;
|
|
5581
|
+
}): Promise<PortfolioPage>;
|
|
5582
|
+
/** GET /admin/portfolio/briefing?cursor=&limit= — the list plus what needs attention. */
|
|
5583
|
+
briefing(params?: {
|
|
5584
|
+
cursor?: string;
|
|
5585
|
+
limit?: number;
|
|
5586
|
+
}): Promise<PortfolioPage>;
|
|
5587
|
+
}
|
|
5210
5588
|
declare class RoyaltiesResource extends BaseResource {
|
|
5211
5589
|
payments(params?: {
|
|
5212
5590
|
source?: string;
|
|
@@ -5748,6 +6126,11 @@ export declare class PicaClient {
|
|
|
5748
6126
|
producerAgreements: ProducerAgreementsResource;
|
|
5749
6127
|
workForHire: WorkForHireResource;
|
|
5750
6128
|
royalties: RoyaltiesResource;
|
|
6129
|
+
/** ADR-333 — who looks after whose catalogue, from either side. */
|
|
6130
|
+
relationships: RelationshipsResource;
|
|
6131
|
+
handovers: HandoversResource;
|
|
6132
|
+
/** ADR-333 — the client catalogues an organisation looks after. */
|
|
6133
|
+
portfolio: PortfolioResource;
|
|
5751
6134
|
/** ADR-321 Phase 2 — programmable rights (propose / status / inspect). */
|
|
5752
6135
|
rights: RightsResource;
|
|
5753
6136
|
statements: StatementsResource;
|