@withpica/mcp-server 2.99.0 → 2.101.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 (114) hide show
  1. package/CHANGELOG.md +203 -0
  2. package/README.md +6 -6
  3. package/dist/lib/changelog.generated.d.ts +2 -2
  4. package/dist/lib/changelog.generated.d.ts.map +1 -1
  5. package/dist/lib/changelog.generated.js +2 -2
  6. package/dist/lib/changelog.generated.js.map +1 -1
  7. package/dist/prompts/creator-question-atlas.d.ts.map +1 -1
  8. package/dist/prompts/creator-question-atlas.js +11 -0
  9. package/dist/prompts/creator-question-atlas.js.map +1 -1
  10. package/dist/prompts/index.js +2 -2
  11. package/dist/resources/agent-guide.d.ts.map +1 -1
  12. package/dist/resources/agent-guide.js +38 -7
  13. package/dist/resources/agent-guide.js.map +1 -1
  14. package/dist/resources/index.d.ts +15 -2
  15. package/dist/resources/index.d.ts.map +1 -1
  16. package/dist/resources/index.js +37 -27
  17. package/dist/resources/index.js.map +1 -1
  18. package/dist/resources/required-schemas.generated.d.ts +16 -10
  19. package/dist/resources/required-schemas.generated.d.ts.map +1 -1
  20. package/dist/resources/required-schemas.generated.js +29 -15
  21. package/dist/resources/required-schemas.generated.js.map +1 -1
  22. package/dist/resources/required-schemas.source.d.ts.map +1 -1
  23. package/dist/resources/required-schemas.source.js +15 -11
  24. package/dist/resources/required-schemas.source.js.map +1 -1
  25. package/dist/server-instructions.d.ts +2 -2
  26. package/dist/server-instructions.d.ts.map +1 -1
  27. package/dist/server-instructions.js +2 -2
  28. package/dist/server-instructions.js.map +1 -1
  29. package/dist/server.d.ts.map +1 -1
  30. package/dist/server.js +9 -0
  31. package/dist/server.js.map +1 -1
  32. package/dist/skills/index.d.ts +5 -3
  33. package/dist/skills/index.d.ts.map +1 -1
  34. package/dist/skills/index.js +11 -9
  35. package/dist/skills/index.js.map +1 -1
  36. package/dist/skills/sep2640.d.ts +71 -0
  37. package/dist/skills/sep2640.d.ts.map +1 -0
  38. package/dist/skills/sep2640.js +198 -0
  39. package/dist/skills/sep2640.js.map +1 -0
  40. package/dist/skills/skills.generated.js +2 -2
  41. package/dist/skills/skills.generated.js.map +1 -1
  42. package/dist/tools/api-error-body.d.ts +16 -4
  43. package/dist/tools/api-error-body.d.ts.map +1 -1
  44. package/dist/tools/api-error-body.js +40 -1
  45. package/dist/tools/api-error-body.js.map +1 -1
  46. package/dist/tools/approvals.d.ts.map +1 -1
  47. package/dist/tools/approvals.js +12 -1
  48. package/dist/tools/approvals.js.map +1 -1
  49. package/dist/tools/assets.d.ts.map +1 -1
  50. package/dist/tools/assets.js +15 -3
  51. package/dist/tools/assets.js.map +1 -1
  52. package/dist/tools/credits.d.ts.map +1 -1
  53. package/dist/tools/credits.js +205 -45
  54. package/dist/tools/credits.js.map +1 -1
  55. package/dist/tools/dashboard.js +1 -1
  56. package/dist/tools/dashboard.js.map +1 -1
  57. package/dist/tools/directory.d.ts.map +1 -1
  58. package/dist/tools/directory.js +21 -10
  59. package/dist/tools/directory.js.map +1 -1
  60. package/dist/tools/discovery.d.ts.map +1 -1
  61. package/dist/tools/discovery.js +14 -3
  62. package/dist/tools/discovery.js.map +1 -1
  63. package/dist/tools/documents.d.ts.map +1 -1
  64. package/dist/tools/documents.js +6 -4
  65. package/dist/tools/documents.js.map +1 -1
  66. package/dist/tools/duplicates.d.ts +13 -0
  67. package/dist/tools/duplicates.d.ts.map +1 -1
  68. package/dist/tools/duplicates.js +178 -1
  69. package/dist/tools/duplicates.js.map +1 -1
  70. package/dist/tools/import-documents.d.ts +1 -0
  71. package/dist/tools/import-documents.d.ts.map +1 -1
  72. package/dist/tools/import-documents.js +67 -0
  73. package/dist/tools/import-documents.js.map +1 -1
  74. package/dist/tools/import.d.ts.map +1 -1
  75. package/dist/tools/import.js +14 -0
  76. package/dist/tools/import.js.map +1 -1
  77. package/dist/tools/index.d.ts +2 -1
  78. package/dist/tools/index.d.ts.map +1 -1
  79. package/dist/tools/index.js +39 -1
  80. package/dist/tools/index.js.map +1 -1
  81. package/dist/tools/memory.d.ts.map +1 -1
  82. package/dist/tools/memory.js +24 -6
  83. package/dist/tools/memory.js.map +1 -1
  84. package/dist/tools/metadata.d.ts.map +1 -1
  85. package/dist/tools/metadata.js +42 -0
  86. package/dist/tools/metadata.js.map +1 -1
  87. package/dist/tools/people.d.ts +54 -22
  88. package/dist/tools/people.d.ts.map +1 -1
  89. package/dist/tools/people.js +236 -27
  90. package/dist/tools/people.js.map +1 -1
  91. package/dist/tools/profile-claims.d.ts +31 -0
  92. package/dist/tools/profile-claims.d.ts.map +1 -0
  93. package/dist/tools/profile-claims.js +188 -0
  94. package/dist/tools/profile-claims.js.map +1 -0
  95. package/dist/tools/public-filter.js +1 -1
  96. package/dist/tools/public-filter.js.map +1 -1
  97. package/dist/tools/recovery-hints.d.ts.map +1 -1
  98. package/dist/tools/recovery-hints.js +140 -7
  99. package/dist/tools/recovery-hints.js.map +1 -1
  100. package/dist/tools/rights.d.ts.map +1 -1
  101. package/dist/tools/rights.js +11 -1
  102. package/dist/tools/rights.js.map +1 -1
  103. package/dist/tools/shows.d.ts.map +1 -1
  104. package/dist/tools/shows.js +25 -2
  105. package/dist/tools/shows.js.map +1 -1
  106. package/dist/tools/skills.d.ts +3 -4
  107. package/dist/tools/skills.d.ts.map +1 -1
  108. package/dist/tools/skills.js.map +1 -1
  109. package/dist/tools/split-sheets.d.ts +8 -0
  110. package/dist/tools/split-sheets.d.ts.map +1 -1
  111. package/dist/tools/split-sheets.js +191 -8
  112. package/dist/tools/split-sheets.js.map +1 -1
  113. package/package.json +6 -4
  114. package/server.json +2 -2
@@ -0,0 +1,71 @@
1
+ import { z } from "zod";
2
+ import type { Skill } from "./skills.generated.js";
3
+ import type { SkillsRegistry, SkillOrigin } from "./index.js";
4
+ export declare const SKILLS_EXTENSION_ID = "io.modelcontextprotocol/skills";
5
+ /** Spread into `capabilities.extensions`. No `directoryRead`: every skill is one file. */
6
+ export declare const SKILLS_EXTENSION_CAPABILITY: {
7
+ "io.modelcontextprotocol/skills": {};
8
+ };
9
+ export interface SkillFrontmatter {
10
+ name: string;
11
+ description: string;
12
+ compatibility: string;
13
+ metadata: Record<string, string>;
14
+ }
15
+ export interface SkillResourceRef {
16
+ uri: string;
17
+ digest: string;
18
+ size: number;
19
+ }
20
+ export interface SkillEntry {
21
+ uri: string;
22
+ frontmatter: SkillFrontmatter;
23
+ resources: SkillResourceRef[];
24
+ }
25
+ export declare class SkillEntryNotFoundError extends Error {
26
+ readonly uri: string;
27
+ constructor(uri: string);
28
+ }
29
+ export declare function skillUri(name: string): string;
30
+ /** Skill name from a `skill://withpica/<name>/SKILL.md` URI, or null. */
31
+ export declare function skillNameFromUri(uri: string): string | null;
32
+ export declare function skillFrontmatter(skill: Skill, origin: SkillOrigin): SkillFrontmatter;
33
+ /** The exact text served by `resources/read` for this skill's SKILL.md. */
34
+ export declare function renderSkillMd(skill: Skill, origin: SkillOrigin): string;
35
+ /**
36
+ * Entries for `skills/list`. A skill whose name or description breaks the
37
+ * Agent Skills rules (custom-skill names allow `--` and a trailing hyphen —
38
+ * lib/services/custom-skills.ts NAME_RE) is left out of the
39
+ * listing — SEP-2640 permits a partial listing — but stays gettable by URI.
40
+ */
41
+ export declare function listSkillEntries(registry: SkillsRegistry): SkillEntry[];
42
+ /** Entry for `skills/get`. Throws SkillEntryNotFoundError (→ -32602). */
43
+ export declare function getSkillEntry(registry: SkillsRegistry, uri: string): SkillEntry;
44
+ export declare const SkillsListRequestSchema: z.ZodObject<{
45
+ method: z.ZodLiteral<"skills/list">;
46
+ params: z.ZodOptional<z.ZodObject<{
47
+ cursor: z.ZodOptional<z.ZodString>;
48
+ }, z.core.$loose>>;
49
+ }, z.core.$strip>;
50
+ export declare const SkillsGetRequestSchema: z.ZodObject<{
51
+ method: z.ZodLiteral<"skills/get">;
52
+ params: z.ZodOptional<z.ZodObject<{
53
+ uri: z.ZodUnknown;
54
+ }, z.core.$loose>>;
55
+ }, z.core.$strip>;
56
+ /** `skills/list` result. One page: PICA's catalog is small and fixed per caller. */
57
+ export declare function skillsListResult(entries: SkillEntry[]): {
58
+ resultType: "complete";
59
+ skills: SkillEntry[];
60
+ };
61
+ /**
62
+ * `skills/get` result. A missing, unknown or malformed URI is -32602 (Invalid
63
+ * params), the code SEP-2640 requires; pinned by sep2640-protocol.test.ts.
64
+ * (PICA's resources/read still answers -32603 for an unknown URI: ResourceError
65
+ * carries a string code, which the SDK maps to InternalError.)
66
+ */
67
+ export declare function skillsGetResult(uri: unknown, get: (uri: string) => SkillEntry): {
68
+ resultType: "complete";
69
+ skill: SkillEntry;
70
+ };
71
+ //# sourceMappingURL=sep2640.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sep2640.d.ts","sourceRoot":"","sources":["../../src/skills/sep2640.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9D,eAAO,MAAM,mBAAmB,mCAAmC,CAAC;AAEpE,0FAA0F;AAC1F,eAAO,MAAM,2BAA2B;;CAAgC,CAAC;AAWzE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,gBAAgB,CAAC;IAC9B,SAAS,EAAE,gBAAgB,EAAE,CAAC;CAC/B;AAED,qBAAa,uBAAwB,SAAQ,KAAK;aACpB,GAAG,EAAE,MAAM;gBAAX,GAAG,EAAE,MAAM;CAIxC;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE3D;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,WAAW,GAClB,gBAAgB,CAoBlB;AA+DD,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,GAAG,MAAM,CAEvE;AA0BD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,cAAc,GAAG,UAAU,EAAE,CAMvE;AAED,yEAAyE;AACzE,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,cAAc,EACxB,GAAG,EAAE,MAAM,GACV,UAAU,CAKZ;AAED,eAAO,MAAM,uBAAuB;;;;;iBAGlC,CAAC;AAIH,eAAO,MAAM,sBAAsB;;;;;iBAGjC,CAAC;AAEH,oFAAoF;AACpF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,UAAU,EAAE;;;EAErD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,UAAU;;;EAajC"}
@@ -0,0 +1,198 @@
1
+ // Copyright (c) 2025-2026 Withpica Ltd. All rights reserved.
2
+ /**
3
+ * SEP-2640 skills extension — ADR-328.
4
+ *
5
+ * The one place that decides what a served `skill://withpica/<name>/SKILL.md`
6
+ * says, and the `skills/list` / `skills/get` entry that describes it. Both
7
+ * transports (stdio `resources/index.ts`, HTTP `app/api/mcp/route.ts`) read
8
+ * skill text through `renderSkillMd`, and build entries through `skillEntry`,
9
+ * so the digest and the bytes it covers come from the same function.
10
+ *
11
+ * The entry's `frontmatter` and the served YAML are serialised from one
12
+ * object; `__tests__/skills/sep2640.test.ts` parses the served text back and
13
+ * hashes it to check the two agree.
14
+ *
15
+ * Served frontmatter follows the Agent Skills spec (agentskills.io): only
16
+ * name / description / compatibility at the top level; PICA's own fields go
17
+ * under `metadata` as strings. The source SKILL.md files and the
18
+ * `org_custom_skills` table keep their own shape — this is the served form.
19
+ */
20
+ import { createHash } from "node:crypto";
21
+ import { z } from "zod";
22
+ import { ErrorCode, McpError } from "@modelcontextprotocol/sdk/types.js";
23
+ export const SKILLS_EXTENSION_ID = "io.modelcontextprotocol/skills";
24
+ /** Spread into `capabilities.extensions`. No `directoryRead`: every skill is one file. */
25
+ export const SKILLS_EXTENSION_CAPABILITY = { [SKILLS_EXTENSION_ID]: {} };
26
+ const URI_PREFIX = "skill://withpica/";
27
+ const URI_RE = /^skill:\/\/withpica\/([a-z0-9-]+)\/SKILL\.md$/;
28
+ /** Agent Skills naming rule: 1–64 chars, a-z0-9 and single inner hyphens. */
29
+ const AGENT_SKILLS_NAME_RE = /^(?=.{1,64}$)[a-z0-9]+(-[a-z0-9]+)*$/;
30
+ const MAX_DESCRIPTION = 1024;
31
+ const COMPATIBILITY = "Requires the withPICA MCP server (pica_* tools).";
32
+ export class SkillEntryNotFoundError extends Error {
33
+ uri;
34
+ constructor(uri) {
35
+ super(`Not a served skill: ${uri}`);
36
+ this.uri = uri;
37
+ this.name = "SkillEntryNotFoundError";
38
+ }
39
+ }
40
+ export function skillUri(name) {
41
+ return `${URI_PREFIX}${name}/SKILL.md`;
42
+ }
43
+ /** Skill name from a `skill://withpica/<name>/SKILL.md` URI, or null. */
44
+ export function skillNameFromUri(uri) {
45
+ return uri.match(URI_RE)?.[1] ?? null;
46
+ }
47
+ export function skillFrontmatter(skill, origin) {
48
+ const metadata = {
49
+ "pica-audience": skill.audience,
50
+ "pica-output": skill.output,
51
+ "pica-triggers": skill.triggers.join("\n"),
52
+ "pica-tools-required": skill.tools_required.join("\n"),
53
+ };
54
+ if (skill.definition_of_done) {
55
+ metadata["pica-definition-of-done"] = skill.definition_of_done;
56
+ }
57
+ if (skill.when_not_to_use) {
58
+ metadata["pica-when-not-to-use"] = skill.when_not_to_use;
59
+ }
60
+ metadata["pica-origin"] = origin;
61
+ return {
62
+ name: skill.name,
63
+ description: skill.description,
64
+ compatibility: COMPATIBILITY,
65
+ metadata,
66
+ };
67
+ }
68
+ /**
69
+ * Characters JSON.stringify leaves raw that YAML forbids or reads differently:
70
+ * DEL and the C1 controls (NEL U+0085 is a line break in YAML 1.1), the line /
71
+ * paragraph separators, BOM and the non-characters U+FFFE / U+FFFF.
72
+ */
73
+ const YAML_UNSAFE = /[\u007F-\u009F\u2028\u2029\uFEFF\uFFFE\uFFFF]/g;
74
+ /** A JSON string literal with YAML-unsafe characters as \uXXXX escapes. */
75
+ function quote(value) {
76
+ return JSON.stringify(value).replace(YAML_UNSAFE, (c) => "\\u" + c.charCodeAt(0).toString(16).padStart(4, "0"));
77
+ }
78
+ /**
79
+ * A skill name that YAML reads back as the same string when written plain:
80
+ * starts with a letter (so never a number or date) and is not one of the
81
+ * YAML 1.1 / 1.2 boolean or null words.
82
+ */
83
+ const PLAIN_SAFE_NAME = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
84
+ const YAML_RESERVED_WORDS = new Set([
85
+ "y",
86
+ "n",
87
+ "yes",
88
+ "no",
89
+ "on",
90
+ "off",
91
+ "true",
92
+ "false",
93
+ "null",
94
+ ]);
95
+ /**
96
+ * `name` is written plain when PLAIN_SAFE_NAME allows it, as the Agent Skills
97
+ * examples do. Clients that read `name:` out of the text with a pattern, not a
98
+ * YAML parser, then still find it. Every other scalar goes through `quote`: a
99
+ * JSON string with the YAML-unsafe characters escaped, which is a valid YAML
100
+ * double-quoted scalar. sep2640.test.ts parses the served text with a YAML
101
+ * parser and compares it to the entry, including those characters and the
102
+ * reserved-word names.
103
+ */
104
+ function yamlName(name) {
105
+ return PLAIN_SAFE_NAME.test(name) && !YAML_RESERVED_WORDS.has(name)
106
+ ? name
107
+ : quote(name);
108
+ }
109
+ function toYaml(fm) {
110
+ const lines = [
111
+ `name: ${yamlName(fm.name)}`,
112
+ `description: ${quote(fm.description)}`,
113
+ `compatibility: ${quote(fm.compatibility)}`,
114
+ "metadata:",
115
+ ...Object.entries(fm.metadata).map(([k, v]) => ` ${quote(k)}: ${quote(v)}`),
116
+ ];
117
+ return lines.join("\n") + "\n";
118
+ }
119
+ /** The exact text served by `resources/read` for this skill's SKILL.md. */
120
+ export function renderSkillMd(skill, origin) {
121
+ return `---\n${toYaml(skillFrontmatter(skill, origin))}---\n\n${skill.body}`;
122
+ }
123
+ function skillEntry(skill, origin) {
124
+ const bytes = Buffer.from(renderSkillMd(skill, origin), "utf8");
125
+ const uri = skillUri(skill.name);
126
+ return {
127
+ uri,
128
+ frontmatter: skillFrontmatter(skill, origin),
129
+ resources: [
130
+ {
131
+ uri,
132
+ digest: `sha256:${createHash("sha256").update(bytes).digest("hex")}`,
133
+ size: bytes.length,
134
+ },
135
+ ],
136
+ };
137
+ }
138
+ function isListable(skill) {
139
+ return (AGENT_SKILLS_NAME_RE.test(skill.name) &&
140
+ skill.description.length > 0 &&
141
+ skill.description.length <= MAX_DESCRIPTION);
142
+ }
143
+ /**
144
+ * Entries for `skills/list`. A skill whose name or description breaks the
145
+ * Agent Skills rules (custom-skill names allow `--` and a trailing hyphen —
146
+ * lib/services/custom-skills.ts NAME_RE) is left out of the
147
+ * listing — SEP-2640 permits a partial listing — but stays gettable by URI.
148
+ */
149
+ export function listSkillEntries(registry) {
150
+ return registry
151
+ .listNames()
152
+ .map((name) => registry.getSkill(name))
153
+ .filter(isListable)
154
+ .map((skill) => skillEntry(skill, registry.originOf(skill.name)));
155
+ }
156
+ /** Entry for `skills/get`. Throws SkillEntryNotFoundError (→ -32602). */
157
+ export function getSkillEntry(registry, uri) {
158
+ const name = skillNameFromUri(uri);
159
+ const origin = name ? registry.originOf(name) : null;
160
+ if (!name || !origin)
161
+ throw new SkillEntryNotFoundError(uri);
162
+ return skillEntry(registry.getSkill(name), origin);
163
+ }
164
+ export const SkillsListRequestSchema = z.object({
165
+ method: z.literal("skills/list"),
166
+ params: z.object({ cursor: z.string().optional() }).passthrough().optional(),
167
+ });
168
+ // `uri` is checked in skillsGetResult, not here: a schema failure surfaces as
169
+ // -32603 from the SDK, and SEP-2640 wants -32602 for a bad request.
170
+ export const SkillsGetRequestSchema = z.object({
171
+ method: z.literal("skills/get"),
172
+ params: z.object({ uri: z.unknown() }).passthrough().optional(),
173
+ });
174
+ /** `skills/list` result. One page: PICA's catalog is small and fixed per caller. */
175
+ export function skillsListResult(entries) {
176
+ return { resultType: "complete", skills: entries };
177
+ }
178
+ /**
179
+ * `skills/get` result. A missing, unknown or malformed URI is -32602 (Invalid
180
+ * params), the code SEP-2640 requires; pinned by sep2640-protocol.test.ts.
181
+ * (PICA's resources/read still answers -32603 for an unknown URI: ResourceError
182
+ * carries a string code, which the SDK maps to InternalError.)
183
+ */
184
+ export function skillsGetResult(uri, get) {
185
+ if (typeof uri !== "string") {
186
+ throw new McpError(ErrorCode.InvalidParams, "skills/get requires a uri");
187
+ }
188
+ try {
189
+ return { resultType: "complete", skill: get(uri) };
190
+ }
191
+ catch (error) {
192
+ if (error instanceof SkillEntryNotFoundError) {
193
+ throw new McpError(ErrorCode.InvalidParams, error.message);
194
+ }
195
+ throw error;
196
+ }
197
+ }
198
+ //# sourceMappingURL=sep2640.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sep2640.js","sourceRoot":"","sources":["../../src/skills/sep2640.ts"],"names":[],"mappings":"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"}
@@ -100,7 +100,7 @@ export const SKILLS = {
100
100
  audience: "artist / session musician / MD / engineer / tour crew",
101
101
  tools_required: ["pica_log_show", "pica_shows_query", "pica_setlist_match", "pica_people_query", "pica_collaborators_invite"],
102
102
  output: "A show (or tour credit) with its setlist matched to works where they exist, plus optional contributors awaiting attestation.",
103
- body: "# log-a-show\n\nHelp the user log a live show. Capture it as a sentence, never as a form.\n\n## Establish one thing first: were they the act?\n\n\"I played the Lexington\" is different from \"I played drums with X at the Albert Hall.\" Set\n`logged_as: \"contributor\"` for the second — it changes everything downstream. A session\nplayer's setlist is describing the gig, not claiming anything, and their own catalogue is not\nexpected to contain those songs. A wrong guess here gets the rest of the conversation wrong, so\nask if it isn't already obvious from how the user described the night.\n\n## Capture it conversationally\n\nGet the shape of the night in a sentence or two — venue, city, date, and what was played. Don't\nwalk the user through a field-by-field form. `pica_log_show` resolves the venue against what\npica already holds: an exact match attaches quietly, anything else comes back as candidates for\nthe user to confirm. A venue is never created without a human confirming it.\n\n## Never do these\n\n- **Never prompt for contributors or crew.** Only record them if the user raises them —\n `pica_collaborators_invite` is there for when they do, not a checklist to work through.\n- **Never imply money is owed.** A song the user did not write earns them nothing from a\n performance. Say that plainly if it comes up; do not soften it into a maybe.\n- **Never say pica filed anything with a performing-rights society.** pica produces a record and\n a dossier, nothing more. No society accepts a setlist by API — PRS Setlists, ASCAP OnStage and\n BMI Live are all web forms the user still has to submit themselves.\n- **Never present an unconfirmed match as a fact.** \"I think Wide Open is your work of the same\n name — is that right?\", never \"you played Wide Open.\" `pica_setlist_match` returns a\n confidence, not a certainty, until the user confirms it.\n\n## Tour credits\n\n\"I programmed the tracks for X, who's on tour right now\" has no date and no venue. It still\nneeds **act, year, and role** — without them the credit is unverifiable and attaches to nothing.\nIf pica already holds that tour, the credit resolves against it and can be corroborated. If not,\nit is recorded as the user's own unverified claim, and should be described that way — never as a\nconfirmed credit.\n\nThe credit itself is a person plus a role on that tour, and pica resolves a person only by\n`email` or `person_id` — a name alone would risk creating a second copy of someone who already\nexists. With neither, `pica_log_show` records the tour and says plainly that it did **not**\nrecord the credit. Relay that and ask for an email; do not let the user leave believing a credit\nexists when only a tour does.\n\n## Attestation\n\nIf the user names someone who was there and offers an email, that person can be invited to\nattest via `pica_collaborators_invite`. Ask before inviting — an invitation is a request, not a\nnotification, and a person who says they were not there is recording something meaningful too.\n\n## What not to do\n\n- Don't turn the setlist into an interrogation — capture titles as given and let matching happen\n quietly with `pica_setlist_match` in the background.\n- Don't infer a role or a split from \"we all played on it\" in passing — that is a separate,\n deliberate step with its own confirmation flow.\n- Don't reconcile this show against past shows (\"didn't you play this venue in March?\") unless\n the user asks — use `pica_shows_query` only when they want the history, not to second-guess\n what they just told you.\n",
103
+ body: "# log-a-show\n\nHelp the user log a live show. Capture it as a sentence, never as a form.\n\n## Establish one thing first: were they the act?\n\n\"I played the Lexington\" is different from \"I played drums with X at the Albert Hall.\" Set\n`logged_as: \"contributor\"` for the second — it changes everything downstream. A session\nplayer's setlist is describing the gig, not claiming anything, and their own catalogue is not\nexpected to contain those songs. A wrong guess here gets the rest of the conversation wrong, so\nask if it isn't already obvious from how the user described the night.\n\n## Capture it conversationally\n\nGet the shape of the night in a sentence or two — venue, city, date, and what was played. Don't\nwalk the user through a field-by-field form. `pica_log_show` resolves the venue against what\npica already holds: an exact match attaches quietly, anything else comes back as candidates for\nthe user to confirm. A venue is never created without a human confirming it.\n\n## From a document: draft first, one yes\n\nGig details often arrive as something the user was sent rather than something they type: a\nbooking email, a daysheet PDF, a screenshot of a group chat, a calendar invite. Read it yourself\nand pull out what is there: venue, city, date, the billed act, the user's role, and the songs, if\na set is listed. Never fill a field the document does not state. A date, a venue or a song you\nguessed would end up in the user's record as if they had said it.\n\nThen call `pica_log_show` with `dry_run: true`. It saves nothing and returns the draft: whether\nthe venue matched, which songs matched their works, and any show already logged for the same\nnight. Show the user the draft in a line or two, for example: \"Jazz Café, London, Thu 9 Oct,\nplaying keys, 12 songs (9 matched to your works). Log it?\" Call it again without `dry_run` only\nafter they say yes.\n\nIf the draft lists a show already logged for that night, ask whether it is the same show before\nlogging another. That list only covers this user's own catalogue: a bandmate logging the same gig\nin theirs never appears in it.\n\n## Never do these\n\n- **Never prompt for contributors or crew.** Only record them if the user raises them —\n `pica_collaborators_invite` is there for when they do, not a checklist to work through.\n- **Never imply money is owed.** A song the user did not write earns them nothing from a\n performance. Say that plainly if it comes up; do not soften it into a maybe.\n- **Never say pica filed anything with a performing-rights society.** pica produces a record and\n a dossier, nothing more. No society accepts a setlist by API — PRS Setlists, ASCAP OnStage and\n BMI Live are all web forms the user still has to submit themselves.\n- **Never present an unconfirmed match as a fact.** \"I think Wide Open is your work of the same\n name — is that right?\", never \"you played Wide Open.\" `pica_setlist_match` returns a\n confidence, not a certainty, until the user confirms it.\n\n## Tour credits\n\n\"I programmed the tracks for X, who's on tour right now\" has no date and no venue. It still\nneeds **act, year, and role** — without them the credit is unverifiable and attaches to nothing.\nIf pica already holds that tour, the credit resolves against it and can be corroborated. If not,\nit is recorded as the user's own unverified claim, and should be described that way — never as a\nconfirmed credit.\n\nThe credit itself is a person plus a role on that tour, and pica resolves a person only by\n`email` or `person_id` — a name alone would risk creating a second copy of someone who already\nexists. With neither, `pica_log_show` records the tour and says plainly that it did **not**\nrecord the credit. Relay that and ask for an email; do not let the user leave believing a credit\nexists when only a tour does.\n\n## Attestation\n\nIf the user names someone who was there and offers an email, that person can be invited to\nattest via `pica_collaborators_invite`. Ask before inviting — an invitation is a request, not a\nnotification, and a person who says they were not there is recording something meaningful too.\n\n## What not to do\n\n- Don't turn the setlist into an interrogation — capture titles as given and let matching happen\n quietly with `pica_setlist_match` in the background.\n- Don't infer a role or a split from \"we all played on it\" in passing — that is a separate,\n deliberate step with its own confirmation flow.\n- Beyond the same-night check the draft does for you, don't reconcile this show against past\n shows (\"didn't you play this venue in March?\") unless\n the user asks — use `pica_shows_query` only when they want the history, not to second-guess\n what they just told you.\n",
104
104
  },
105
105
  "prepare-for-sync": {
106
106
  name: "prepare-for-sync",
@@ -138,7 +138,7 @@ export const SKILLS = {
138
138
  audience: "producer / artist / label / manager",
139
139
  tools_required: ["pica_recording_splits_list", "pica_recording_splits_create", "pica_recording_splits_verify", "pica_recordings_query", "pica_people_query", "pica_collaborators_invite", "pica_split_sheet_generate", "pica_split_sheet_send"],
140
140
  output: "Confirmed + verified recording_splits rows totalling 100%, with the option to generate and send a split sheet PDF for signatures.",
141
- body: "# set-recording-splits\n\nHelp the user set master ownership splits on a recording. These are master-side royalty shares — distinct from publishing splits, which are credits on a work. Splits flow into payments, so the skill prioritises accuracy over speed: propose → dry-run → confirm → commit → verify.\n\n## Pre-flight\n\nRead `pica://schemas/recording-splits-required` before any write. The canonical shape is `recording_id`, `person_id`, `percentage`, `split_type`, `role`. **Active shares for one `split_type` + territory may not pass 100%, and a person holds at most one share there** — the database refuses anything else (`RECORDING_SPLIT_TOTAL_EXCEEDED` / `RECORDING_SPLIT_EXISTS`).\n\n## Step 1 — Pick the recording\n\nIf the user names a recording or gives an ID, use it. Otherwise, call `pica_recordings_query` and let the user pick from recent recordings.\n\n## Step 2 — Show current state\n\nCall `pica_recording_splits_list` for the recording. Three states:\n\n- **Empty** — no splits set yet. Proceed to step 3.\n- **Partial** — some splits exist but don't total 100%. Ask the user whether they want to add the missing shares.\n- **Complete** — splits total 100%. Ask whether the user wants to verify (mark agreed-upon) what's there.\n\n`pica_recording_splits_create` only adds. It cannot replace or change a share already recorded — it refuses a second share for the same person with `RECORDING_SPLIT_EXISTS`, and there is no MCP tool that edits one. If the user wants a recorded share changed or ended, say so plainly: they can do it on the recording's page in /inspect.\n\nAlways summarise the current state plainly: \"right now this recording has [N] splits totalling [X]%, with [A] holding [P]%...\"\n\n## Step 3 — Capture proposed splits\n\nFor each split row, capture:\n\n- **Who owns this share?** — `person_id` from `pica_people_query`. If the person isn't on PICA yet, offer `pica_collaborators_invite` to bring them in before writing the split.\n- **What percentage?** — together with the shares already recorded, at most 100% for that `split_type` + territory.\n- **What kind?** — `split_type` is one of `master`, `mechanical`, `performance`, `sync` (master ownership is `master`); `role` is one of `owner`, `performer`, `producer`, `engineer`, `mixer`, `masterer`, `label`, `other`.\n\nSum the percentages out loud as you go. If they're not totalling 100% when the user finishes describing them, stop and ask them to adjust before proceeding.\n\n## Step 4 — Dry-run preview\n\nCall `pica_recording_splits_create` with `dry_run: true` for each proposed row. It writes nothing and returns the row that would land, the shares already recorded (`existing_shares`, `active_total`) and `likely_refusal`. Surface that to the user.\n\n- **If `likely_refusal` is set, stop** and tell the user what it says — the write would be refused.\n- **If `existing_shares_checked` is false**, the preview could not read the recorded shares and predicts nothing — say so; do not present it as a clean preview.\n- Each dry run checks one row against what is already recorded, not against the other rows you are proposing — sum the proposed rows yourself. **If they would pass 100% with what is recorded, stop.** Do not proceed to commit.\n\n## Step 5 — Explicit confirmation\n\nSay something like:\n\n> \"I'm about to set [N] splits on this recording totalling 100%:\n> - [A] — [P]% ([type])\n> - [B] — [Q]% ([type])\n> Reply 'yes' to commit, or tell me what to change.\"\n\nWait for the user's explicit \"yes\" (or equivalent). Don't write on ambiguous signals.\n\n## Step 6 — Commit\n\nFor each split, call `pica_recording_splits_create` (this time without `dry_run`). Report each row back as it lands. If any write fails, stop the loop — don't partially commit.\n\n## Step 7 — Verify\n\nVerification marks a split as agreed-upon — a separate state from \"exists in the database.\" It records WHICH PERSON agreed, so it is the split holder's own act: `pica_recording_splits_verify` refuses an agent (`VERIFICATION_REQUIRES_HUMAN_SESSION`) and you cannot do it for them. Tell each holder where to do it: signed in, \"confirm my share\" under ownership splits on the recording's page, `/inspect/recordings/<recording_id>#ownership-splits`. If a holder is someone other than the user, `pica_notify_person` with the `recording_id` sends them a link to that page.\n\n## Step 8 — Offer next moves\n\n- \"Want me to generate a split sheet PDF for signatures?\" → `pica_split_sheet_generate`\n- \"Want me to send the split sheet to the parties?\" → `pica_split_sheet_send`\n- \"Want me to set splits on another recording?\"\n\n## What not to do\n\n- Don't write splits without an explicit \"yes\" from the user\n- Don't proceed if the totals don't equal 100% — re-prompt instead\n- Don't skip telling holders how to verify, and don't retry `pica_recording_splits_verify` after it refuses. Verification is a deliberate moment for the holder, not for you.\n- Don't speculate about typical splits by genre or scene — if the user doesn't know what % someone deserves, that's a business conversation outside this skill\n- Don't conflate with writer splits — those are credits on a work, set via `pica_credits_update`. Different table, different semantics.\n\n## Follow-on skills\n\n- `close-the-loop` — recording splits are usually one gap among several on a work; close-the-loop fits the others\n- `register-my-works` — registered works pair with recordings that have clear ownership chains\n- `audit-credits` — splits health-check across the whole catalog\n",
141
+ body: "# set-recording-splits\n\nHelp the user set master ownership splits on a recording. These are master-side royalty shares — distinct from publishing splits, which are credits on a work. Splits flow into payments, so the skill prioritises accuracy over speed: propose → dry-run → confirm → commit → verify.\n\n## Pre-flight\n\nRead `pica://schemas/recording-splits-required` before any write. The canonical shape is `recording_id`, `person_id`, `percentage`, `split_type`, `role`. **Active shares for one `split_type` + territory may not pass 100%, and a person holds at most one ACTIVE share there (an ended share is history: it neither counts nor blocks a new one)** — the database refuses anything else (`RECORDING_SPLIT_TOTAL_EXCEEDED` / `RECORDING_SPLIT_EXISTS`).\n\n## Step 1 — Pick the recording\n\nIf the user names a recording or gives an ID, use it. Otherwise, call `pica_recordings_query` and let the user pick from recent recordings.\n\n## Step 2 — Show current state\n\nCall `pica_recording_splits_list` for the recording. Three states:\n\n- **Empty** — no splits set yet. Proceed to step 3.\n- **Partial** — some splits exist but don't total 100%. Ask the user whether they want to add the missing shares.\n- **Complete** — splits total 100%. Ask whether the user wants to verify (mark agreed-upon) what's there.\n\n`pica_recording_splits_create` only adds. It refuses a second ACTIVE share for the same person with `RECORDING_SPLIT_EXISTS` (a person whose share has ended can be given a new one), and a share that would take the active total past 100% with `RECORDING_SPLIT_TOTAL_EXCEEDED`. When a recorded share is wrong — a holder-less \"unknown\" row, the wrong percentage or role — fix that row instead of adding around it: `pica_recording_splits_update` (recording_id + split_id + what changes; `person_id` relinks an unknown holder) or, if it should stop counting, `pica_recording_splits_end` (keeps the row as history). Confirm the change with the user first, as in step 5. If the result says `verification_cleared: true`, tell the user the holder's confirmation was cleared and they need to confirm again.\n\nAlways summarise the current state plainly: \"right now this recording has [N] splits totalling [X]%, with [A] holding [P]%...\"\n\n## Step 3 — Capture proposed splits\n\nFor each split row, capture:\n\n- **Who owns this share?** — `person_id` from `pica_people_query`. If the person isn't on PICA yet, offer `pica_collaborators_invite` to bring them in before writing the split.\n- **What percentage?** — together with the shares already recorded, at most 100% for that `split_type` + territory.\n- **What kind?** — `split_type` is one of `master`, `mechanical`, `performance`, `sync` (master ownership is `master`); `role` is one of `owner`, `performer`, `producer`, `engineer`, `mixer`, `masterer`, `label`, `other`.\n\nSum the percentages out loud as you go. If they're not totalling 100% when the user finishes describing them, stop and ask them to adjust before proceeding.\n\n## Step 4 — Dry-run preview\n\nCall `pica_recording_splits_create` with `dry_run: true` for each proposed row. It writes nothing and returns the row that would land, the shares already recorded (`existing_shares`, `active_total`) and `likely_refusal`. Surface that to the user.\n\n- **If `likely_refusal` is set, stop** and tell the user what it says — the write would be refused.\n- **If `existing_shares_checked` is false**, the preview could not read the recorded shares and predicts nothing — say so; do not present it as a clean preview.\n- Each dry run checks one row against what is already recorded, not against the other rows you are proposing — sum the proposed rows yourself. **If they would pass 100% with what is recorded, stop.** Do not proceed to commit.\n\n## Step 5 — Explicit confirmation\n\nSay something like:\n\n> \"I'm about to set [N] splits on this recording totalling 100%:\n> - [A] — [P]% ([type])\n> - [B] — [Q]% ([type])\n> Reply 'yes' to commit, or tell me what to change.\"\n\nWait for the user's explicit \"yes\" (or equivalent). Don't write on ambiguous signals.\n\n## Step 6 — Commit\n\nFor each split, call `pica_recording_splits_create` (this time without `dry_run`). Report each row back as it lands. If any write fails, stop the loop — don't partially commit.\n\n## Step 7 — Verify\n\nVerification marks a split as agreed-upon — a separate state from \"exists in the database.\" It records WHICH PERSON agreed, so it is the split holder's own act: `pica_recording_splits_verify` refuses an agent (`VERIFICATION_REQUIRES_HUMAN_SESSION`) and you cannot do it for them. Tell each holder where to do it: signed in, \"confirm my share\" under ownership splits on the recording's page, `/inspect/recordings/<recording_id>#ownership-splits`. If a holder is someone other than the user, `pica_notify_person` with the `recording_id` sends them a link to that page.\n\n## Step 8 — Offer next moves\n\n- \"Want me to generate a split sheet PDF for signatures?\" → `pica_split_sheet_generate`\n- \"Want me to send the split sheet to the parties?\" → `pica_split_sheet_send`\n- \"Want me to set splits on another recording?\"\n\n## What not to do\n\n- Don't write splits without an explicit \"yes\" from the user\n- Don't proceed if the totals don't equal 100% — re-prompt instead\n- Don't skip telling holders how to verify, and don't retry `pica_recording_splits_verify` after it refuses. Verification is a deliberate moment for the holder, not for you.\n- Don't speculate about typical splits by genre or scene — if the user doesn't know what % someone deserves, that's a business conversation outside this skill\n- Don't conflate with writer splits — those are credits on a work, set via `pica_credits_update`. Different table, different semantics.\n\n## Follow-on skills\n\n- `close-the-loop` — recording splits are usually one gap among several on a work; close-the-loop fits the others\n- `register-my-works` — registered works pair with recordings that have clear ownership chains\n- `audit-credits` — splits health-check across the whole catalog\n",
142
142
  },
143
143
  "set-up-workspace": {
144
144
  name: "set-up-workspace",
@@ -1 +1 @@
1
- {"version":3,"file":"skills.generated.js","sourceRoot":"","sources":["../../src/skills/skills.generated.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"skills.generated.js","sourceRoot":"","sources":["../../src/skills/skills.generated.ts"],"names":[],"mappings":"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"}
@@ -8,7 +8,7 @@
8
8
  * `extractApiErrorBody` (:1639), and inline `replace`/`match` in
9
9
  * `duplicates.ts` and `integrity.ts`. Each still misses the `API 404 not
10
10
  * found:` prefix and the nested body shape described below. Migrating them is
11
- * outstanding; only `credits.ts` reads this one (2026-09-10).
11
+ * outstanding; `credits.ts` and `import.ts` read this one.
12
12
  *
13
13
  * The SDK's `ApiError` does not carry a structured body — it concatenates the
14
14
  * response text onto the message. Those extractors disagreed on both halves of
@@ -20,7 +20,10 @@
20
20
  * the third; that is the shape the recording-credit 404 arrives in.
21
21
  * - **The body.** Routes emit BOTH a flat shape
22
22
  * (`{success, error: "…", code: "VALIDATION_ERROR", details: […]}`) and a
23
- * nested one (`{success, error: {code, message, details}}`). A parser that
23
+ * nested one (`{success, error: {code, message, details}}`), and typed
24
+ * errors (`typedErrorResponse`, lib/api/typed-error-response.ts, used by
25
+ * both `handleRouteError` and `withDualAuth`) add a third
26
+ * (`{error: "CODE", message}`, no `code` key). A parser that
24
27
  * reads `parsed.code` sees `undefined` for every nested body, which is
25
28
  * what pushed callers back onto regexing the English prose — and prose is
26
29
  * ambiguous between siblings ("recording not found" vs "person not
@@ -33,12 +36,21 @@
33
36
  export interface ApiErrorBody {
34
37
  /** HTTP status, when the message prefix carried one. */
35
38
  status?: number;
36
- /** The route's machine code, from either body shape. */
39
+ /** The route's machine code, from any of the three body shapes. */
37
40
  code?: string;
38
- /** The route's human message, from either body shape. */
41
+ /** The route's human message, from any of the three body shapes. */
39
42
  message?: string;
40
43
  /** Whatever the route put in `details` — shape varies by route. */
41
44
  details?: unknown;
45
+ /**
46
+ * Top-level keys the route set BESIDE the error — `remedy` / `reason`
47
+ * (withDualAuth's INSUFFICIENT_SCOPE), `person_ids`
48
+ * (PERSON_ORG_MISMATCH), `next_tool` / `recording_count`
49
+ * (RECORDING_TARGET_REQUIRED). Everything except `success`, `error`,
50
+ * `code`, `message` and `details`; absent when there are none. Present
51
+ * only when the body parsed whole — a salvaged code carries no siblings.
52
+ */
53
+ extra?: Record<string, unknown>;
42
54
  }
43
55
  /**
44
56
  * Recover `{status, code, message, details}` from an SDK error (or a raw
@@ -1 +1 @@
1
- {"version":3,"file":"api-error-body.d.ts","sourceRoot":"","sources":["../../src/tools/api-error-body.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,MAAM,WAAW,YAAY;IAC3B,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAmBD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,YAAY,CAsE5D"}
1
+ {"version":3,"file":"api-error-body.d.ts","sourceRoot":"","sources":["../../src/tools/api-error-body.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,MAAM,WAAW,YAAY;IAC3B,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAqCD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,YAAY,CAkG5D"}
@@ -1,4 +1,19 @@
1
1
  // Copyright (c) 2025-2026 Withpica Ltd. All rights reserved.
2
+ const NON_EXTRA_KEYS = new Set([
3
+ "success",
4
+ "error",
5
+ "code",
6
+ "message",
7
+ "details",
8
+ ]);
9
+ function siblingFields(body) {
10
+ const extra = {};
11
+ for (const [key, value] of Object.entries(body)) {
12
+ if (!NON_EXTRA_KEYS.has(key))
13
+ extra[key] = value;
14
+ }
15
+ return Object.keys(extra).length > 0 ? { extra } : {};
16
+ }
2
17
  /** Prefixes the SDK uses before the response body. Each captures the status. */
3
18
  const PREFIXES = [
4
19
  /^API request failed:\s*(\d{3})\s*/i,
@@ -56,7 +71,9 @@ export function parseApiErrorBody(err) {
56
71
  // to its generic branch, reverting the fix this module exists for. The
57
72
  // code is the one field worth recovering from a mangled body, and it is
58
73
  // always well-formed even when the object is not.
59
- const salvaged = jsonText.match(/"code"\s*:\s*"([A-Z][A-Z0-9_]*)"/);
74
+ // A typed-error body carries its code as `"error"` rather than `"code"`.
75
+ const salvaged = jsonText.match(/"code"\s*:\s*"([A-Z][A-Z0-9_]*)"/) ??
76
+ jsonText.match(/"error"\s*:\s*"([A-Z][A-Z0-9_]*)"/);
60
77
  return {
61
78
  ...(status !== undefined ? { status } : {}),
62
79
  ...(salvaged ? { code: salvaged[1] } : {}),
@@ -75,6 +92,27 @@ export function parseApiErrorBody(err) {
75
92
  ? { message: asString(nested.message) }
76
93
  : {}),
77
94
  ...(nested.details !== undefined ? { details: nested.details } : {}),
95
+ ...siblingFields(body),
96
+ };
97
+ }
98
+ // Typed-error shape: `typedErrorResponse` (lib/api/typed-error-response.ts,
99
+ // called by both `handleRouteError` and `withDualAuth`) answers every
100
+ // MCPRecoverableError as `{error: <CODE>, message: <prose>}` — the
101
+ // code IS `error` and there is no `code` key. Read by the flat branch below,
102
+ // the code came back as the message and `code` as undefined, so no caller
103
+ // could branch on it.
104
+ const flatError = asString(body.error);
105
+ const flatMessage = asString(body.message);
106
+ if (body.code === undefined &&
107
+ flatError !== undefined &&
108
+ /^[A-Z][A-Z0-9_]*$/.test(flatError) &&
109
+ flatMessage !== undefined) {
110
+ return {
111
+ ...(status !== undefined ? { status } : {}),
112
+ code: flatError,
113
+ message: flatMessage,
114
+ ...(body.details !== undefined ? { details: body.details } : {}),
115
+ ...siblingFields(body),
78
116
  };
79
117
  }
80
118
  // Flat shape: `code` sits beside a string `error`.
@@ -83,6 +121,7 @@ export function parseApiErrorBody(err) {
83
121
  ...(asString(body.code) ? { code: asString(body.code) } : {}),
84
122
  ...(asString(body.error) ? { message: asString(body.error) } : {}),
85
123
  ...(body.details !== undefined ? { details: body.details } : {}),
124
+ ...siblingFields(body),
86
125
  };
87
126
  }
88
127
  //# sourceMappingURL=api-error-body.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"api-error-body.js","sourceRoot":"","sources":["../../src/tools/api-error-body.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api-error-body.js","sourceRoot":"","sources":["../../src/tools/api-error-body.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"approvals.d.ts","sourceRoot":"","sources":["../../src/tools/approvals.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,UAAU,EAAuB,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAc,MAAM,YAAY,CAAC;AAItE,qBAAa,cAAc;IACzB,OAAO,CAAC,IAAI,CAAa;gBAEb,IAAI,EAAE,UAAU;IAI5B,QAAQ,IAAI,KAAK,CAAC;QAAE,UAAU,EAAE,cAAc,CAAC;QAAC,QAAQ,EAAE,YAAY,CAAA;KAAE,CAAC;IA6DzE;;;;;OAKG;YACW,iBAAiB;CAuDhC"}
1
+ {"version":3,"file":"approvals.d.ts","sourceRoot":"","sources":["../../src/tools/approvals.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,UAAU,EAAuB,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAc,MAAM,YAAY,CAAC;AAItE,qBAAa,cAAc;IACzB,OAAO,CAAC,IAAI,CAAa;gBAEb,IAAI,EAAE,UAAU;IAI5B,QAAQ,IAAI,KAAK,CAAC;QAAE,UAAU,EAAE,cAAc,CAAC;QAAC,QAAQ,EAAE,YAAY,CAAA;KAAE,CAAC;IA0EzE;;;;;OAKG;YACW,iBAAiB;CAuDhC"}
@@ -32,7 +32,10 @@ export class ApprovalsTools {
32
32
  "decided. Use this only when an earlier write returned a " +
33
33
  "human_approval_required envelope; pass the approval_reference from " +
34
34
  "that envelope as approval_id. While status is pending, nothing has " +
35
- "executed yet; poll again shortly.",
35
+ "executed yet; poll again shortly. For a batched pica_merge_duplicates " +
36
+ "approval that has run, the result also carries summary + items: one " +
37
+ "outcome per pair (merged / skipped / failed, with the reason) — status " +
38
+ "is failed when any pair failed, even though the others ran.",
36
39
  workflows: "infrastructure",
37
40
  vernacular_kind: "specialist",
38
41
  vernacular_reason: "Polled by an agent after a write was deferred for out-of-band human approval; not a creator-vernacular entry point.",
@@ -65,6 +68,14 @@ export class ApprovalsTools {
65
68
  type: "string",
66
69
  description: "ISO timestamp the pending request expires.",
67
70
  },
71
+ summary: {
72
+ type: "object",
73
+ description: "Batched merge approvals only, once run: counts of merged / skipped / failed pairs.",
74
+ },
75
+ items: {
76
+ type: "array",
77
+ description: "Batched merge approvals only, once run: each pair's outcome (merged | skipped | failed) with the reason for a skip or failure.",
78
+ },
68
79
  },
69
80
  },
70
81
  },
@@ -1 +1 @@
1
- {"version":3,"file":"approvals.js","sourceRoot":"","sources":["../../src/tools/approvals.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"approvals.js","sourceRoot":"","sources":["../../src/tools/approvals.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../src/tools/assets.ts"],"names":[],"mappings":"AAEA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAiC,MAAM,mBAAmB,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,YAAY,EAAc,MAAM,YAAY,CAAC;AAatE,qBAAa,WAAW;IACtB,OAAO,CAAC,IAAI,CAAa;gBAEb,IAAI,EAAE,UAAU;IAI5B,QAAQ,IAAI,KAAK,CAAC;QAAE,UAAU,EAAE,cAAc,CAAC;QAAC,QAAQ,EAAE,YAAY,CAAA;KAAE,CAAC;YA0Z3D,UAAU;YAWV,YAAY;YAgIZ,WAAW;YAsCX,WAAW;YAQX,WAAW;YAOX,UAAU;YAOV,WAAW;YASX,eAAe;YAef,oBAAoB;YAepB,eAAe;YAYf,oBAAoB;CAWnC"}
1
+ {"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../src/tools/assets.ts"],"names":[],"mappings":"AAEA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAiC,MAAM,mBAAmB,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,YAAY,EAAc,MAAM,YAAY,CAAC;AAatE,qBAAa,WAAW;IACtB,OAAO,CAAC,IAAI,CAAa;gBAEb,IAAI,EAAE,UAAU;IAI5B,QAAQ,IAAI,KAAK,CAAC;QAAE,UAAU,EAAE,cAAc,CAAC;QAAC,QAAQ,EAAE,YAAY,CAAA;KAAE,CAAC;YAia3D,UAAU;YAWV,YAAY;YAqIZ,WAAW;YAsCX,WAAW;YAQX,WAAW;YAOX,UAAU;YAOV,WAAW;YASX,eAAe;YAef,oBAAoB;YAepB,eAAe;YAYf,oBAAoB;CAWnC"}
@@ -43,10 +43,17 @@ export class AssetsTools {
43
43
  scope: "read:files",
44
44
  audiences: ["stdio", "http", "public"],
45
45
  tier: "read",
46
- description: "Get details for a specific physical asset. Omit sections for everything. " +
46
+ description: "Get details for a specific physical asset. Omit sections for basic, " +
47
+ "valuations and links. " +
47
48
  "Sections: basic, valuations, market, links (work + recording link rows " +
48
49
  "written by pica_physical_assets_link_work / _link_recording with their " +
49
50
  "relationship + evidence + confidence fields). " +
51
+ "`market` is an AI-generated price estimate from the asset's make and " +
52
+ "model, not a recorded valuation: it runs only when listed by name, " +
53
+ "and needs a make or model on the asset. It is a POST to the " +
54
+ "assets area, so a key or grant needs write:catalog (or admin) " +
55
+ "for it; with read access only, `market` comes back as a section " +
56
+ "error and the other sections still answer. " +
50
57
  "→ then: pica_physical_assets_update (modify), pica_physical_assets_export (for insurance)",
51
58
  workflows: "infrastructure",
52
59
  vernacular_kind: "specialist",
@@ -64,7 +71,7 @@ export class AssetsTools {
64
71
  type: "string",
65
72
  enum: ["basic", "valuations", "market", "links"],
66
73
  },
67
- description: "Which data sections to include. Omit for all sections.",
74
+ description: "Which data sections to include. Omit for basic, valuations and links; `market` must be named.",
68
75
  },
69
76
  },
70
77
  required: ["id"],
@@ -428,7 +435,12 @@ export class AssetsTools {
428
435
  }
429
436
  })());
430
437
  }
431
- if (allSections || sections?.includes("market")) {
438
+ // `market` is not part of "everything". The route behind it
439
+ // (POST /api/admin/assets/[id]/market-check) asks an AI model for a price
440
+ // estimate on every call, so it runs only when the caller names it.
441
+ // Regression: "should not run the market check when sections omitted"
442
+ // in mcp-server/src/__tests__/tools/assets.test.ts.
443
+ if (sections?.includes("market")) {
432
444
  promises.push((async () => {
433
445
  try {
434
446
  results.market = await this.pica.assets.marketCheck(id);