@withpica/mcp-server 2.103.0 → 2.104.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 +46 -0
- package/README.md +8 -4
- package/dist/lib/changelog.generated.d.ts +2 -2
- package/dist/lib/changelog.generated.d.ts.map +1 -1
- package/dist/lib/changelog.generated.js +2 -2
- package/dist/lib/changelog.generated.js.map +1 -1
- package/dist/resources/index.d.ts.map +1 -1
- package/dist/resources/index.js +23 -1
- package/dist/resources/index.js.map +1 -1
- package/dist/resources/required-schemas.generated.d.ts +77 -0
- package/dist/resources/required-schemas.generated.d.ts.map +1 -1
- package/dist/resources/required-schemas.generated.js +114 -0
- package/dist/resources/required-schemas.generated.js.map +1 -1
- package/dist/resources/required-schemas.source.d.ts.map +1 -1
- package/dist/resources/required-schemas.source.js +85 -0
- package/dist/resources/required-schemas.source.js.map +1 -1
- package/dist/server-instructions.d.ts +2 -2
- package/dist/server-instructions.d.ts.map +1 -1
- package/dist/server-instructions.js +2 -0
- package/dist/server-instructions.js.map +1 -1
- package/dist/skills/skills.generated.d.ts.map +1 -1
- package/dist/skills/skills.generated.js +25 -3
- package/dist/skills/skills.generated.js.map +1 -1
- package/dist/tools/catalogue-argument.d.ts +76 -0
- package/dist/tools/catalogue-argument.d.ts.map +1 -0
- package/dist/tools/catalogue-argument.js +114 -0
- package/dist/tools/catalogue-argument.js.map +1 -0
- package/dist/tools/custody.d.ts +2 -2
- package/dist/tools/custody.d.ts.map +1 -1
- package/dist/tools/custody.js +22 -20
- package/dist/tools/custody.js.map +1 -1
- package/dist/tools/dashboard.d.ts.map +1 -1
- package/dist/tools/dashboard.js +7 -4
- package/dist/tools/dashboard.js.map +1 -1
- package/dist/tools/discovery.d.ts.map +1 -1
- package/dist/tools/discovery.js +25 -2
- package/dist/tools/discovery.js.map +1 -1
- package/dist/tools/duplicates.d.ts +15 -2
- package/dist/tools/duplicates.d.ts.map +1 -1
- package/dist/tools/duplicates.js +109 -10
- package/dist/tools/duplicates.js.map +1 -1
- package/dist/tools/enrichment.d.ts.map +1 -1
- package/dist/tools/enrichment.js +6 -1
- package/dist/tools/enrichment.js.map +1 -1
- package/dist/tools/handovers.d.ts +42 -0
- package/dist/tools/handovers.d.ts.map +1 -0
- package/dist/tools/handovers.js +302 -0
- package/dist/tools/handovers.js.map +1 -0
- package/dist/tools/index.d.ts +6 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +78 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/metadata.d.ts.map +1 -1
- package/dist/tools/metadata.js +80 -0
- package/dist/tools/metadata.js.map +1 -1
- package/dist/tools/recordings.d.ts.map +1 -1
- package/dist/tools/recordings.js +10 -2
- package/dist/tools/recordings.js.map +1 -1
- package/dist/tools/recovery-hints.d.ts.map +1 -1
- package/dist/tools/recovery-hints.js +116 -0
- package/dist/tools/recovery-hints.js.map +1 -1
- package/dist/tools/relationship-change.d.ts +16 -0
- package/dist/tools/relationship-change.d.ts.map +1 -0
- package/dist/tools/relationship-change.js +60 -0
- package/dist/tools/relationship-change.js.map +1 -0
- package/dist/tools/relationship-copy.d.ts +99 -0
- package/dist/tools/relationship-copy.d.ts.map +1 -0
- package/dist/tools/relationship-copy.js +213 -0
- package/dist/tools/relationship-copy.js.map +1 -0
- package/dist/tools/relationship-scope.d.ts +104 -0
- package/dist/tools/relationship-scope.d.ts.map +1 -0
- package/dist/tools/relationship-scope.js +106 -0
- package/dist/tools/relationship-scope.js.map +1 -0
- package/dist/tools/relationships.d.ts +64 -0
- package/dist/tools/relationships.d.ts.map +1 -0
- package/dist/tools/relationships.js +1062 -0
- package/dist/tools/relationships.js.map +1 -0
- package/dist/tools/settings.d.ts.map +1 -1
- package/dist/tools/settings.js +4 -1
- package/dist/tools/settings.js.map +1 -1
- package/dist/tools/works.d.ts +11 -0
- package/dist/tools/works.d.ts.map +1 -1
- package/dist/tools/works.js +63 -3
- package/dist/tools/works.js.map +1 -1
- package/package.json +3 -3
- package/scripts/build-required-schemas.ts +6 -4
- package/server.json +2 -2
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
// Copyright (c) 2025-2026 Withpica Ltd. All rights reserved.
|
|
2
|
+
/**
|
|
3
|
+
* ADR-333 — plain words for a relationship (who looks after whose
|
|
4
|
+
* catalogue), as the assistant tools say them.
|
|
5
|
+
*
|
|
6
|
+
* The MCP package cannot import the app, so this keeps its own copy of what
|
|
7
|
+
* the screens say: the type labels and statuses (from
|
|
8
|
+
* lib/services/portfolio-relationship-model.ts), the screen addresses (from
|
|
9
|
+
* lib/config/relationship-paths.ts), and the status and history sentences
|
|
10
|
+
* (from app/inspect/lib/relationship-copy.ts). The tools and the screens
|
|
11
|
+
* cannot say different things without
|
|
12
|
+
* lib/services/__tests__/relationship-scope-mcp-parity.test.ts failing: it
|
|
13
|
+
* compares every constant here with the app's and runs both sentence
|
|
14
|
+
* builders over every status and event kind.
|
|
15
|
+
*
|
|
16
|
+
* Pure: no imports.
|
|
17
|
+
*/
|
|
18
|
+
export const GRANTABLE_RELATIONSHIP_TYPES = [
|
|
19
|
+
"co_owner",
|
|
20
|
+
"administrator",
|
|
21
|
+
"representative",
|
|
22
|
+
"viewer",
|
|
23
|
+
];
|
|
24
|
+
export const RELATIONSHIP_TYPE_LABELS = {
|
|
25
|
+
co_owner: "co-owner with a share",
|
|
26
|
+
administrator: "administrator",
|
|
27
|
+
representative: "representative",
|
|
28
|
+
viewer: "viewer",
|
|
29
|
+
};
|
|
30
|
+
export const RELATIONSHIP_STATUSES = [
|
|
31
|
+
"proposed",
|
|
32
|
+
"active",
|
|
33
|
+
"declined",
|
|
34
|
+
"revoked",
|
|
35
|
+
"stepped_down",
|
|
36
|
+
"expired",
|
|
37
|
+
"suspended",
|
|
38
|
+
];
|
|
39
|
+
/** What a type may do, said to the catalogue's owner. */
|
|
40
|
+
export const TYPE_DOES = {
|
|
41
|
+
administrator: "can edit and register your songs and send exports for you. changes to splits or custody come to you to approve.",
|
|
42
|
+
representative: "can see and export what's in scope, and suggest changes. every change to your record comes to you to approve first.",
|
|
43
|
+
viewer: "can see and export what's in scope, and nothing else.",
|
|
44
|
+
co_owner: "can see the songs and recordings it has a share in. it can't change your facts.",
|
|
45
|
+
};
|
|
46
|
+
/** The same allowances, said to the organisation that holds them. */
|
|
47
|
+
export const TYPE_DOES_FOR_ORG = {
|
|
48
|
+
administrator: "can edit and register their songs and send exports for them. changes to splits or custody go to them to approve.",
|
|
49
|
+
representative: "can see and export what's in scope, and suggest changes. every change to their record goes to them to approve first.",
|
|
50
|
+
viewer: "can see and export what's in scope, and nothing else.",
|
|
51
|
+
co_owner: "can see the songs and recordings it has a share in. it can't change their facts.",
|
|
52
|
+
};
|
|
53
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
54
|
+
// Screen addresses (paths; the tools prefix the web origin)
|
|
55
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
56
|
+
export const RELATIONSHIPS_PATH = "/inspect/relationships";
|
|
57
|
+
export function relationshipPath(relationshipId) {
|
|
58
|
+
return `${RELATIONSHIPS_PATH}/${encodeURIComponent(relationshipId)}`;
|
|
59
|
+
}
|
|
60
|
+
export const INVITATIONS_FOR_YOU_PATH = `${RELATIONSHIPS_PATH}#invitations-for-you`;
|
|
61
|
+
export function relationshipActivityPath(granteeOrgId) {
|
|
62
|
+
return granteeOrgId
|
|
63
|
+
? `${RELATIONSHIPS_PATH}/activity?org=${encodeURIComponent(granteeOrgId)}`
|
|
64
|
+
: `${RELATIONSHIPS_PATH}/activity`;
|
|
65
|
+
}
|
|
66
|
+
/** Hand-overs (ADR-333 D5); the app's are lib/config/handover-paths.ts. */
|
|
67
|
+
export const HANDOVERS_PATH = "/inspect/handovers";
|
|
68
|
+
export function handoverPath(handoverId) {
|
|
69
|
+
return `${HANDOVERS_PATH}/${encodeURIComponent(handoverId)}`;
|
|
70
|
+
}
|
|
71
|
+
export const NEW_HANDOVER_PATH = `${HANDOVERS_PATH}/new`;
|
|
72
|
+
/** Where a relationship stands, for the side reading it. */
|
|
73
|
+
export function statusLine(r, reader) {
|
|
74
|
+
const other = reader === "grantor" ? r.granteeOrgName : r.grantorOrgName;
|
|
75
|
+
const day = (iso) => (iso ? iso.slice(0, 10) : "");
|
|
76
|
+
switch (r.status) {
|
|
77
|
+
case "proposed": {
|
|
78
|
+
const lapses = r.proposalExpiresAt
|
|
79
|
+
? ` · expires ${day(r.proposalExpiresAt)}`
|
|
80
|
+
: "";
|
|
81
|
+
return r.proposedBySide === reader
|
|
82
|
+
? { text: `waiting for ${other} to answer${lapses}`, needsYou: false }
|
|
83
|
+
: {
|
|
84
|
+
text: `${other} is asking · needs your answer${lapses}`,
|
|
85
|
+
needsYou: true,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
case "suspended":
|
|
89
|
+
return {
|
|
90
|
+
text: `paused by pica ${day(r.suspendedAt)} · it grants nothing while paused. ask pica if you have questions.`,
|
|
91
|
+
needsYou: false,
|
|
92
|
+
};
|
|
93
|
+
case "active":
|
|
94
|
+
return {
|
|
95
|
+
text: `active since ${day(r.respondedAt) || day(r.proposedAt)}${r.scope.termEndsOn ? ` · ends ${r.scope.termEndsOn}` : ""}`,
|
|
96
|
+
needsYou: false,
|
|
97
|
+
};
|
|
98
|
+
case "declined":
|
|
99
|
+
return { text: `declined ${day(r.respondedAt)}`, needsYou: false };
|
|
100
|
+
case "revoked":
|
|
101
|
+
return { text: `ended by the owner ${day(r.endedAt)}`, needsYou: false };
|
|
102
|
+
case "stepped_down":
|
|
103
|
+
return {
|
|
104
|
+
text: `${r.granteeOrgName} stepped down ${day(r.endedAt)}`,
|
|
105
|
+
needsYou: false,
|
|
106
|
+
};
|
|
107
|
+
case "expired":
|
|
108
|
+
return {
|
|
109
|
+
text: r.endReason === "proposal_unanswered"
|
|
110
|
+
? `lapsed unanswered ${day(r.endedAt)}`
|
|
111
|
+
: `term ended ${day(r.endedAt)}`,
|
|
112
|
+
needsYou: false,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/** One audit row as a sentence: who did what, through which relationship. */
|
|
117
|
+
export function eventLine(e) {
|
|
118
|
+
const org = e.actorSide === "grantor"
|
|
119
|
+
? e.grantorOrgName
|
|
120
|
+
: e.actorSide === "grantee"
|
|
121
|
+
? e.granteeOrgName
|
|
122
|
+
: null;
|
|
123
|
+
// The PICA team acts as PICA: its people are not named to customers.
|
|
124
|
+
const who = e.actorSide === "platform"
|
|
125
|
+
? "pica"
|
|
126
|
+
: e.actorDisplayName
|
|
127
|
+
? org
|
|
128
|
+
? `${e.actorDisplayName} (${org})`
|
|
129
|
+
: e.actorDisplayName
|
|
130
|
+
: (org ?? "pica");
|
|
131
|
+
const type = RELATIONSHIP_TYPE_LABELS[e.type] ?? humanise(e.type);
|
|
132
|
+
switch (e.kind) {
|
|
133
|
+
case "proposed":
|
|
134
|
+
return `${who} proposed ${e.granteeOrgName} as ${type}`;
|
|
135
|
+
case "accepted":
|
|
136
|
+
return `${who} accepted ${e.granteeOrgName} as ${type}`;
|
|
137
|
+
case "declined":
|
|
138
|
+
return `${who} declined`;
|
|
139
|
+
case "scope_changed":
|
|
140
|
+
return `${who} changed what's covered`;
|
|
141
|
+
case "revoked":
|
|
142
|
+
return `${who} ended the relationship`;
|
|
143
|
+
case "stepped_down":
|
|
144
|
+
return `${who} stepped down`;
|
|
145
|
+
case "expired":
|
|
146
|
+
return e.reason === "proposal_unanswered"
|
|
147
|
+
? "the request lapsed unanswered"
|
|
148
|
+
: "the term ended";
|
|
149
|
+
case "term_ending_soon": {
|
|
150
|
+
const on = detailDate(e, "term_ends_on") ?? e.scope.termEndsOn;
|
|
151
|
+
return `the term ends on ${on ?? "its end date"}`;
|
|
152
|
+
}
|
|
153
|
+
case "proposal_expiring_soon": {
|
|
154
|
+
const on = detailDate(e, "proposal_expires_at");
|
|
155
|
+
return `the request lapses${on ? ` on ${on}` : " soon"} if nobody answers`;
|
|
156
|
+
}
|
|
157
|
+
case "suspended":
|
|
158
|
+
return "pica paused it: it grants nothing while paused";
|
|
159
|
+
case "reinstated":
|
|
160
|
+
return "pica resumed it";
|
|
161
|
+
case "acted":
|
|
162
|
+
return `${who} ${humanise(e.action) || "acted"}${e.entityType ? ` · ${humanise(e.entityType)}` : ""}`;
|
|
163
|
+
default:
|
|
164
|
+
// A kind added after this copy: said by its name, never dropped.
|
|
165
|
+
return `${who} · ${humanise(e.kind)}`;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function detailDate(e, key) {
|
|
169
|
+
const v = e.detail?.[key];
|
|
170
|
+
return typeof v === "string" && v.length >= 10 ? v.slice(0, 10) : null;
|
|
171
|
+
}
|
|
172
|
+
function humanise(s) {
|
|
173
|
+
return (s ?? "").replace(/_/g, " ").trim();
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* The scope in one line for the side reading it: what, which side, where,
|
|
177
|
+
* when, money and (administrators) the directory. Territories are ISO codes
|
|
178
|
+
* here ("GB, IE"); the screens spell the country names.
|
|
179
|
+
*/
|
|
180
|
+
export function scopeSummary(scope, type, reader) {
|
|
181
|
+
const whose = reader.side === "grantor" ? "your" : `${reader.grantorName}'s`;
|
|
182
|
+
const songs = scope.workIds?.length ?? scope.songsChosen ?? 0;
|
|
183
|
+
const recordings = scope.recordingIds?.length ?? scope.recordingsChosen ?? 0;
|
|
184
|
+
const count = (n, one) => `${n} ${one}${n === 1 ? "" : "s"}`;
|
|
185
|
+
const what = scope.catalogue === "whole"
|
|
186
|
+
? `${whose} whole catalogue`
|
|
187
|
+
: [
|
|
188
|
+
songs > 0 ? count(songs, "song") : null,
|
|
189
|
+
recordings > 0 ? count(recordings, "recording") : null,
|
|
190
|
+
]
|
|
191
|
+
.filter(Boolean)
|
|
192
|
+
.join(" and ") + ` from ${whose} catalogue`;
|
|
193
|
+
const half = scope.half === "both"
|
|
194
|
+
? "songs and recordings"
|
|
195
|
+
: scope.half === "composition"
|
|
196
|
+
? "the song side only"
|
|
197
|
+
: "the recording side only";
|
|
198
|
+
const where = scope.territories.includes("WW")
|
|
199
|
+
? "worldwide"
|
|
200
|
+
: scope.territories.join(", ");
|
|
201
|
+
const when = (scope.termStartsOn ? `from ${scope.termStartsOn}` : "from acceptance") +
|
|
202
|
+
(scope.termEndsOn ? ` until ${scope.termEndsOn}` : ", no end date");
|
|
203
|
+
const money = scope.money
|
|
204
|
+
? "can see statements"
|
|
205
|
+
: "can't see statements or earnings";
|
|
206
|
+
const directory = type === "administrator"
|
|
207
|
+
? scope.directory
|
|
208
|
+
? "; can list songs in the public directory"
|
|
209
|
+
: "; can't list songs in the public directory"
|
|
210
|
+
: "";
|
|
211
|
+
return `${what}, ${half}, ${where}, ${when}; ${money}${directory}`;
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=relationship-copy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relationship-copy.js","sourceRoot":"","sources":["../../src/tools/relationship-copy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The scope of a portfolio relationship, as the assistant tools accept it
|
|
3
|
+
* (ADR-333 D3). The main MCP server cannot import the app, so this mirrors
|
|
4
|
+
* `relationshipScopeSchema` in lib/services/portfolio-relationship-model.ts
|
|
5
|
+
* with snake_case names. lib/services/__tests__/relationship-scope-mcp-
|
|
6
|
+
* parity.test.ts fails if a field, an allowed value or a limit drifts.
|
|
7
|
+
*
|
|
8
|
+
* Every field is optional: the app fills the defaults (whole catalogue, both
|
|
9
|
+
* halves, worldwide, no end date, money on only for an administrator,
|
|
10
|
+
* directory off). The rules that join two fields (for example "worldwide
|
|
11
|
+
* cannot be combined with other territories") are enforced by the app, which
|
|
12
|
+
* refuses with a plain reason; the descriptions below state them.
|
|
13
|
+
*
|
|
14
|
+
* Deliberately has no imports, so the parity test can load it directly.
|
|
15
|
+
*/
|
|
16
|
+
export declare const SCOPE_HALVES: readonly ["both", "composition", "master"];
|
|
17
|
+
export declare const SCOPE_CATALOGUES: readonly ["whole", "chosen"];
|
|
18
|
+
export declare const SCOPE_MAX_TERRITORIES = 300;
|
|
19
|
+
export declare const SCOPE_MAX_ITEMS = 5000;
|
|
20
|
+
export declare const SCOPE_TERRITORY_PATTERN = "^[A-Z]{2}$";
|
|
21
|
+
export declare const SCOPE_DATE_PATTERN = "^\\d{4}-\\d{2}-\\d{2}$";
|
|
22
|
+
/** The tool argument name for each field of the app's scope. */
|
|
23
|
+
export declare const SCOPE_FIELD_NAMES: {
|
|
24
|
+
readonly half: "half";
|
|
25
|
+
readonly territories: "territories";
|
|
26
|
+
readonly term_starts_on: "termStartsOn";
|
|
27
|
+
readonly term_ends_on: "termEndsOn";
|
|
28
|
+
readonly money: "money";
|
|
29
|
+
readonly directory: "directory";
|
|
30
|
+
readonly catalogue: "catalogue";
|
|
31
|
+
readonly work_ids: "workIds";
|
|
32
|
+
readonly recording_ids: "recordingIds";
|
|
33
|
+
};
|
|
34
|
+
export type ScopeArgName = keyof typeof SCOPE_FIELD_NAMES;
|
|
35
|
+
/** JSON Schema for the optional `scope` argument of grant, invite and answer. */
|
|
36
|
+
export declare const RELATIONSHIP_SCOPE_INPUT_SCHEMA: {
|
|
37
|
+
readonly type: "object";
|
|
38
|
+
readonly description: string;
|
|
39
|
+
readonly additionalProperties: false;
|
|
40
|
+
readonly properties: {
|
|
41
|
+
readonly half: {
|
|
42
|
+
readonly type: "string";
|
|
43
|
+
readonly enum: readonly ["both", "composition", "master"];
|
|
44
|
+
readonly description: "Which half of the songs: both, composition (the song and its publishing) or master (the recordings).";
|
|
45
|
+
};
|
|
46
|
+
readonly territories: {
|
|
47
|
+
readonly type: "array";
|
|
48
|
+
readonly items: {
|
|
49
|
+
readonly type: "string";
|
|
50
|
+
readonly pattern: "^[A-Z]{2}$";
|
|
51
|
+
};
|
|
52
|
+
readonly minItems: 1;
|
|
53
|
+
readonly maxItems: 300;
|
|
54
|
+
readonly description: "Countries covered. Only [\"WW\"] (worldwide) is accepted today: limiting a relationship to some countries is not available yet, and any other value is refused.";
|
|
55
|
+
};
|
|
56
|
+
readonly term_starts_on: {
|
|
57
|
+
readonly type: readonly ["string", "null"];
|
|
58
|
+
readonly pattern: "^\\d{4}-\\d{2}-\\d{2}$";
|
|
59
|
+
readonly description: "First day covered, YYYY-MM-DD (UTC). Leave out or null to start when it is accepted.";
|
|
60
|
+
};
|
|
61
|
+
readonly term_ends_on: {
|
|
62
|
+
readonly type: readonly ["string", "null"];
|
|
63
|
+
readonly pattern: "^\\d{4}-\\d{2}-\\d{2}$";
|
|
64
|
+
readonly description: "Last day covered, YYYY-MM-DD (UTC), inclusive. Leave out or null for until revoked. On that date access ends by itself.";
|
|
65
|
+
};
|
|
66
|
+
readonly money: {
|
|
67
|
+
readonly type: "boolean";
|
|
68
|
+
readonly description: "true lets the organisation see statements and earnings in scope.";
|
|
69
|
+
};
|
|
70
|
+
readonly directory: {
|
|
71
|
+
readonly type: "boolean";
|
|
72
|
+
readonly description: "true lets an administrator list or hide songs in the public directory and answer enquiries. Administrators only.";
|
|
73
|
+
};
|
|
74
|
+
readonly catalogue: {
|
|
75
|
+
readonly type: "string";
|
|
76
|
+
readonly enum: readonly ["whole", "chosen"];
|
|
77
|
+
readonly description: "whole for the whole catalogue, or chosen for only the songs and recordings named in work_ids and recording_ids.";
|
|
78
|
+
};
|
|
79
|
+
readonly work_ids: {
|
|
80
|
+
readonly type: "array";
|
|
81
|
+
readonly items: {
|
|
82
|
+
readonly type: "string";
|
|
83
|
+
readonly format: "uuid";
|
|
84
|
+
};
|
|
85
|
+
readonly maxItems: 5000;
|
|
86
|
+
readonly description: "Songs covered when catalogue is chosen (ids from pica_works_query). Not allowed for a master-only scope.";
|
|
87
|
+
};
|
|
88
|
+
readonly recording_ids: {
|
|
89
|
+
readonly type: "array";
|
|
90
|
+
readonly items: {
|
|
91
|
+
readonly type: "string";
|
|
92
|
+
readonly format: "uuid";
|
|
93
|
+
};
|
|
94
|
+
readonly maxItems: 5000;
|
|
95
|
+
readonly description: "Recordings covered when catalogue is chosen (ids from pica_recordings_query). Not allowed for a composition-only scope.";
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Convert the tool's `scope` argument to the app's field names. Unknown keys
|
|
101
|
+
* are dropped here; the schema above already refuses them at the MCP layer.
|
|
102
|
+
*/
|
|
103
|
+
export declare function scopeArgToApi(scope: Record<string, unknown> | undefined): Record<string, unknown> | undefined;
|
|
104
|
+
//# sourceMappingURL=relationship-scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relationship-scope.d.ts","sourceRoot":"","sources":["../../src/tools/relationship-scope.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AAEH,eAAO,MAAM,YAAY,4CAA6C,CAAC;AACvE,eAAO,MAAM,gBAAgB,8BAA+B,CAAC;AAC7D,eAAO,MAAM,qBAAqB,MAAM,CAAC;AACzC,eAAO,MAAM,eAAe,OAAO,CAAC;AACpC,eAAO,MAAM,uBAAuB,eAAe,CAAC;AACpD,eAAO,MAAM,kBAAkB,2BAA2B,CAAC;AAE3D,gEAAgE;AAChE,eAAO,MAAM,iBAAiB;;;;;;;;;;CAUpB,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,MAAM,OAAO,iBAAiB,CAAC;AAE1D,iFAAiF;AACjF,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiElC,CAAC;AAEX;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GACzC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAOrC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// Copyright (c) 2025-2026 Withpica Ltd. All rights reserved.
|
|
2
|
+
/**
|
|
3
|
+
* The scope of a portfolio relationship, as the assistant tools accept it
|
|
4
|
+
* (ADR-333 D3). The main MCP server cannot import the app, so this mirrors
|
|
5
|
+
* `relationshipScopeSchema` in lib/services/portfolio-relationship-model.ts
|
|
6
|
+
* with snake_case names. lib/services/__tests__/relationship-scope-mcp-
|
|
7
|
+
* parity.test.ts fails if a field, an allowed value or a limit drifts.
|
|
8
|
+
*
|
|
9
|
+
* Every field is optional: the app fills the defaults (whole catalogue, both
|
|
10
|
+
* halves, worldwide, no end date, money on only for an administrator,
|
|
11
|
+
* directory off). The rules that join two fields (for example "worldwide
|
|
12
|
+
* cannot be combined with other territories") are enforced by the app, which
|
|
13
|
+
* refuses with a plain reason; the descriptions below state them.
|
|
14
|
+
*
|
|
15
|
+
* Deliberately has no imports, so the parity test can load it directly.
|
|
16
|
+
*/
|
|
17
|
+
export const SCOPE_HALVES = ["both", "composition", "master"];
|
|
18
|
+
export const SCOPE_CATALOGUES = ["whole", "chosen"];
|
|
19
|
+
export const SCOPE_MAX_TERRITORIES = 300;
|
|
20
|
+
export const SCOPE_MAX_ITEMS = 5000;
|
|
21
|
+
export const SCOPE_TERRITORY_PATTERN = "^[A-Z]{2}$";
|
|
22
|
+
export const SCOPE_DATE_PATTERN = "^\\d{4}-\\d{2}-\\d{2}$";
|
|
23
|
+
/** The tool argument name for each field of the app's scope. */
|
|
24
|
+
export const SCOPE_FIELD_NAMES = {
|
|
25
|
+
half: "half",
|
|
26
|
+
territories: "territories",
|
|
27
|
+
term_starts_on: "termStartsOn",
|
|
28
|
+
term_ends_on: "termEndsOn",
|
|
29
|
+
money: "money",
|
|
30
|
+
directory: "directory",
|
|
31
|
+
catalogue: "catalogue",
|
|
32
|
+
work_ids: "workIds",
|
|
33
|
+
recording_ids: "recordingIds",
|
|
34
|
+
};
|
|
35
|
+
/** JSON Schema for the optional `scope` argument of grant, invite and answer. */
|
|
36
|
+
export const RELATIONSHIP_SCOPE_INPUT_SCHEMA = {
|
|
37
|
+
type: "object",
|
|
38
|
+
description: "What the relationship covers. Leave out any field to use the default: the whole catalogue, " +
|
|
39
|
+
"both halves, worldwide, until revoked, statements hidden (shown by default only to an " +
|
|
40
|
+
"administrator), directory off.",
|
|
41
|
+
additionalProperties: false,
|
|
42
|
+
properties: {
|
|
43
|
+
half: {
|
|
44
|
+
type: "string",
|
|
45
|
+
enum: [...SCOPE_HALVES],
|
|
46
|
+
description: "Which half of the songs: both, composition (the song and its publishing) or master (the recordings).",
|
|
47
|
+
},
|
|
48
|
+
territories: {
|
|
49
|
+
type: "array",
|
|
50
|
+
items: { type: "string", pattern: SCOPE_TERRITORY_PATTERN },
|
|
51
|
+
minItems: 1,
|
|
52
|
+
maxItems: SCOPE_MAX_TERRITORIES,
|
|
53
|
+
description: 'Countries covered. Only ["WW"] (worldwide) is accepted today: limiting a relationship to some countries is not available yet, and any other value is refused.',
|
|
54
|
+
},
|
|
55
|
+
term_starts_on: {
|
|
56
|
+
type: ["string", "null"],
|
|
57
|
+
pattern: SCOPE_DATE_PATTERN,
|
|
58
|
+
description: "First day covered, YYYY-MM-DD (UTC). Leave out or null to start when it is accepted.",
|
|
59
|
+
},
|
|
60
|
+
term_ends_on: {
|
|
61
|
+
type: ["string", "null"],
|
|
62
|
+
pattern: SCOPE_DATE_PATTERN,
|
|
63
|
+
description: "Last day covered, YYYY-MM-DD (UTC), inclusive. Leave out or null for until revoked. On that date access ends by itself.",
|
|
64
|
+
},
|
|
65
|
+
money: {
|
|
66
|
+
type: "boolean",
|
|
67
|
+
description: "true lets the organisation see statements and earnings in scope.",
|
|
68
|
+
},
|
|
69
|
+
directory: {
|
|
70
|
+
type: "boolean",
|
|
71
|
+
description: "true lets an administrator list or hide songs in the public directory and answer enquiries. Administrators only.",
|
|
72
|
+
},
|
|
73
|
+
catalogue: {
|
|
74
|
+
type: "string",
|
|
75
|
+
enum: [...SCOPE_CATALOGUES],
|
|
76
|
+
description: "whole for the whole catalogue, or chosen for only the songs and recordings named in work_ids and recording_ids.",
|
|
77
|
+
},
|
|
78
|
+
work_ids: {
|
|
79
|
+
type: "array",
|
|
80
|
+
items: { type: "string", format: "uuid" },
|
|
81
|
+
maxItems: SCOPE_MAX_ITEMS,
|
|
82
|
+
description: "Songs covered when catalogue is chosen (ids from pica_works_query). Not allowed for a master-only scope.",
|
|
83
|
+
},
|
|
84
|
+
recording_ids: {
|
|
85
|
+
type: "array",
|
|
86
|
+
items: { type: "string", format: "uuid" },
|
|
87
|
+
maxItems: SCOPE_MAX_ITEMS,
|
|
88
|
+
description: "Recordings covered when catalogue is chosen (ids from pica_recordings_query). Not allowed for a composition-only scope.",
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Convert the tool's `scope` argument to the app's field names. Unknown keys
|
|
94
|
+
* are dropped here; the schema above already refuses them at the MCP layer.
|
|
95
|
+
*/
|
|
96
|
+
export function scopeArgToApi(scope) {
|
|
97
|
+
if (!scope)
|
|
98
|
+
return undefined;
|
|
99
|
+
const out = {};
|
|
100
|
+
for (const [arg, api] of Object.entries(SCOPE_FIELD_NAMES)) {
|
|
101
|
+
if (scope[arg] !== undefined)
|
|
102
|
+
out[api] = scope[arg];
|
|
103
|
+
}
|
|
104
|
+
return out;
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=relationship-scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relationship-scope.js","sourceRoot":"","sources":["../../src/tools/relationship-scope.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ADR-333 — who looks after whose catalogue, for assistants.
|
|
3
|
+
*
|
|
4
|
+
* Owner side: pica_relationships_list, _answer, _grant, _revoke, _activity.
|
|
5
|
+
* Organisation side: pica_portfolio_list, _briefing, _invite and
|
|
6
|
+
* pica_relationships_step_down (list, answer and activity serve both sides).
|
|
7
|
+
*
|
|
8
|
+
* Each tool calls one of pica-b5's /api/admin/relationships/** or
|
|
9
|
+
* /api/admin/portfolio routes, which hold no rules of their own: the 1.1
|
|
10
|
+
* service decides every step and refuses with a code and a plain sentence,
|
|
11
|
+
* which these tools pass on as they are.
|
|
12
|
+
*
|
|
13
|
+
* Accepting, changing, revoking and an owner's invitation give or take away
|
|
14
|
+
* access, so they are the person's own decision (ADR-333 D1):
|
|
15
|
+
* - from a connected app or agent grant, pica_relationships_answer, _grant
|
|
16
|
+
* and _revoke are `approvalMode: "human"`: the MCP route stages an
|
|
17
|
+
* approval for the person, and on approval
|
|
18
|
+
* lib/services/relationship-approvals.ts runs the step through the
|
|
19
|
+
* service, never this file;
|
|
20
|
+
* - from the in-app assistant (not staged), the route refuses those steps
|
|
21
|
+
* as HUMAN_CONFIRMATION_REQUIRED and the tool gives the screen to do it on.
|
|
22
|
+
* Declining, stepping down and an organisation's invitation take nothing
|
|
23
|
+
* from anyone, so an agent may do them.
|
|
24
|
+
*
|
|
25
|
+
* Every step sends the version of the relationship the caller read
|
|
26
|
+
* (expected_version). If the terms changed since, nothing happens and the
|
|
27
|
+
* tool returns the current terms to read again.
|
|
28
|
+
*/
|
|
29
|
+
import { type PicaClient } from "@withpica/mcp-sdk";
|
|
30
|
+
import type { PortfolioClientRecord } from "@withpica/mcp-sdk";
|
|
31
|
+
import type { ToolDefinition, ToolExecutor } from "./index.js";
|
|
32
|
+
/** 1.1's MAX_PAGE_LIMIT: a relationship page reads limit + 1 rows. */
|
|
33
|
+
export declare const RELATIONSHIP_PAGE_MAX = 999;
|
|
34
|
+
/** pica-2f's 1.4 page cap. */
|
|
35
|
+
export declare const PORTFOLIO_PAGE_MAX = 25;
|
|
36
|
+
/** The scope fields a client can be asked for: what they cover comes from the client. */
|
|
37
|
+
export declare const INVITE_SCOPE_FIELDS: readonly ["half", "territories", "term_starts_on", "term_ends_on"];
|
|
38
|
+
/** `https://withpica.com/api` → `https://withpica.com`. */
|
|
39
|
+
export declare function webOrigin(apiUrl: string | undefined): string;
|
|
40
|
+
/** One client as a line: who, as what, and what needs attention. */
|
|
41
|
+
export declare function portfolioLine(c: PortfolioClientRecord): string;
|
|
42
|
+
export declare class RelationshipTools {
|
|
43
|
+
private readonly pica;
|
|
44
|
+
private readonly origin;
|
|
45
|
+
constructor(pica: PicaClient, apiUrl?: string);
|
|
46
|
+
getTools(): Array<{
|
|
47
|
+
definition: ToolDefinition;
|
|
48
|
+
executor: ToolExecutor;
|
|
49
|
+
}>;
|
|
50
|
+
private list;
|
|
51
|
+
private activity;
|
|
52
|
+
private portfolioList;
|
|
53
|
+
private portfolioBriefing;
|
|
54
|
+
private portfolio;
|
|
55
|
+
private answer;
|
|
56
|
+
private stepResult;
|
|
57
|
+
private grant;
|
|
58
|
+
private invite;
|
|
59
|
+
private sendInvite;
|
|
60
|
+
private revoke;
|
|
61
|
+
private stepDown;
|
|
62
|
+
private end;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=relationships.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relationships.d.ts","sourceRoot":"","sources":["../../src/tools/relationships.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAY,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAGV,qBAAqB,EAKtB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAc,MAAM,YAAY,CAAC;AA0B3E,sEAAsE;AACtE,eAAO,MAAM,qBAAqB,MAAM,CAAC;AACzC,8BAA8B;AAC9B,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAGrC,yFAAyF;AACzF,eAAO,MAAM,mBAAmB,oEAKtB,CAAC;AAIX,2DAA2D;AAC3D,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAG5D;AAiSD,oEAAoE;AACpE,wBAAgB,aAAa,CAAC,CAAC,EAAE,qBAAqB,GAAG,MAAM,CAsC9D;AAED,qBAAa,iBAAiB;IAI1B,OAAO,CAAC,QAAQ,CAAC,IAAI;IAHvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAGb,IAAI,EAAE,UAAU,EACjC,MAAM,CAAC,EAAE,MAAM;IAKjB,QAAQ,IAAI,KAAK,CAAC;QAAE,UAAU,EAAE,cAAc,CAAC;QAAC,QAAQ,EAAE,YAAY,CAAA;KAAE,CAAC;YA4V3D,IAAI;YAmFJ,QAAQ;YAyER,aAAa;YAIb,iBAAiB;YAIjB,SAAS;YAiET,MAAM;IA4HpB,OAAO,CAAC,UAAU;YAoBJ,KAAK;YAIL,MAAM;YAIN,UAAU;YA+CV,MAAM;YAIN,QAAQ;YAIR,GAAG;CAqDlB"}
|