@unbrained/pm-cli 2026.8.25 → 2026.8.27

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 (206) hide show
  1. package/.agents/skills/HARNESS_COMPATIBILITY.md +32 -0
  2. package/.agents/skills/README.md +47 -0
  3. package/.agents/skills/pm-developer/SKILL.md +117 -0
  4. package/.agents/skills/pm-developer/references/COMMAND_PLAYBOOK.md +49 -0
  5. package/.agents/skills/pm-developer/references/GRAPH_AND_RELATIONSHIPS.md +91 -0
  6. package/.agents/skills/pm-developer/references/MULTI_AGENT_MERGE.md +72 -0
  7. package/.agents/skills/pm-developer/references/PROMPTS.md +17 -0
  8. package/.agents/skills/pm-developer/references/SCRIPTING_COMPOSITION.md +82 -0
  9. package/.agents/skills/pm-developer/references/TOKEN_BUDGETS.md +85 -0
  10. package/.agents/skills/pm-extensions/SKILL.md +106 -0
  11. package/.agents/skills/pm-extensions/references/AUTHORING.md +95 -0
  12. package/.agents/skills/pm-extensions/references/LIFECYCLE.md +40 -0
  13. package/.agents/skills/pm-extensions/references/TROUBLESHOOTING.md +25 -0
  14. package/.agents/skills/pm-sdk/SKILL.md +107 -0
  15. package/.agents/skills/pm-sdk/references/DOMAIN_MODELING.md +78 -0
  16. package/.agents/skills/pm-sdk/references/INTEGRATION_CHECKLIST.md +31 -0
  17. package/.agents/skills/pm-sdk/references/PROMPTS.md +13 -0
  18. package/.agents/skills/pm-sdk/references/SURFACE_MAP.md +82 -0
  19. package/.agents/skills/pm-user/SKILL.md +111 -0
  20. package/.agents/skills/pm-user/references/BACKLOG_SHAPING.md +105 -0
  21. package/.agents/skills/pm-user/references/PROMPTS.md +17 -0
  22. package/.agents/skills/pm-user/references/WORKFLOWS.md +35 -0
  23. package/.claude-plugin/marketplace.json +2 -2
  24. package/CHANGELOG.md +58 -3
  25. package/README.md +8 -5
  26. package/dist/cli/commander-usage.js +11 -7
  27. package/dist/cli/error-guidance.js +3 -3
  28. package/dist/cli/help-content.d.ts +2 -0
  29. package/dist/cli/help-content.js +53 -17
  30. package/dist/cli/help-json-payload.d.ts +8 -2
  31. package/dist/cli/help-json-payload.js +46 -12
  32. package/dist/cli/main.js +52 -74
  33. package/dist/cli/register-annotations.js +27 -21
  34. package/dist/cli/register-setup.js +98 -57
  35. package/dist/cli-bundle/bundle-manifest.json +156 -156
  36. package/dist/cli-bundle/chunks/chunk-3OO3W6FW.js +202 -0
  37. package/dist/cli-bundle/chunks/chunk-52EKTW6V.js +3 -0
  38. package/dist/cli-bundle/chunks/{chunk-QLUORNIB.js → chunk-CVBBGWW5.js} +62 -44
  39. package/dist/cli-bundle/chunks/chunk-MFNTKMTI.js +13 -0
  40. package/dist/cli-bundle/chunks/chunk-OS27HHBN.js +35 -0
  41. package/dist/cli-bundle/chunks/chunk-QTO7USTH.js +2 -0
  42. package/dist/cli-bundle/chunks/{chunk-5I5RWIJC.js → chunk-R4ETAOJC.js} +2 -2
  43. package/dist/cli-bundle/chunks/{chunk-OWHNAR2B.js → chunk-SH6P7FXI.js} +2 -2
  44. package/dist/cli-bundle/chunks/chunk-SHMDY36D.js +8 -0
  45. package/dist/cli-bundle/chunks/{chunk-244MI4GS.js → chunk-SKXLJIEK.js} +60 -60
  46. package/dist/cli-bundle/chunks/chunk-TNX6HC54.js +3 -0
  47. package/dist/cli-bundle/chunks/{register-list-query-XVN2ZLI7.js → register-list-query-EUWM6VII.js} +2 -2
  48. package/dist/cli-bundle/chunks/{register-mutation-QCKAEGIJ.js → register-mutation-FD4HSAVU.js} +4 -4
  49. package/dist/cli-bundle/chunks/{register-operations-SDEAXE7E.js → register-operations-HRMNFEC3.js} +2 -2
  50. package/dist/cli-bundle/chunks/register-setup-33GNICLX.js +2 -0
  51. package/dist/cli-bundle/focused-chunks/{chunk-IBZZZGK3.js → chunk-2AGZ5BRT.js} +2 -2
  52. package/dist/cli-bundle/focused-chunks/chunk-4BR5UU52.js +50 -0
  53. package/dist/cli-bundle/focused-chunks/{chunk-OHIHZ7HS.js → chunk-6GCRSLPG.js} +2 -2
  54. package/dist/cli-bundle/focused-chunks/{chunk-OVJL6NZE.js → chunk-AD6ULRAF.js} +4 -4
  55. package/dist/cli-bundle/focused-chunks/{chunk-7YCDTCBC.js → chunk-AQ5IYEZZ.js} +2 -2
  56. package/dist/cli-bundle/focused-chunks/{chunk-YO3ZF3FI.js → chunk-EKX37ZHA.js} +2 -2
  57. package/dist/cli-bundle/focused-chunks/{chunk-N7W67YIG.js → chunk-FC2AXLB5.js} +2 -2
  58. package/dist/cli-bundle/focused-chunks/{chunk-H5JZEIQV.js → chunk-HC7ODMH3.js} +2 -2
  59. package/dist/cli-bundle/focused-chunks/{chunk-NOOZGIXP.js → chunk-HVQ22RC4.js} +2 -2
  60. package/dist/cli-bundle/focused-chunks/{chunk-A644DUFQ.js → chunk-MEASX544.js} +2 -2
  61. package/dist/cli-bundle/focused-chunks/{chunk-RAFKLNZX.js → chunk-MXTYGECH.js} +2 -2
  62. package/dist/cli-bundle/focused-chunks/{chunk-2UIWOP3O.js → chunk-SUBSWYW3.js} +2 -2
  63. package/dist/cli-bundle/focused-chunks/{chunk-VXWATRFL.js → chunk-XDPYBQCF.js} +9 -9
  64. package/dist/cli-bundle/focused-chunks/{chunk-XUQPEKRN.js → chunk-Y3JJXRVK.js} +2 -2
  65. package/dist/cli-bundle/focused-chunks/{chunk-GQR3WH3F.js → chunk-Y5A7SJJ7.js} +2 -2
  66. package/dist/cli-bundle/focused-chunks/chunk-YHWHX6YY.js +2 -0
  67. package/dist/cli-bundle/focused-chunks/{chunk-ONYQCALA.js → chunk-YVVZ3LQ6.js} +6 -6
  68. package/dist/cli-bundle/focused-chunks/chunk-Z2USIBR2.js +5 -0
  69. package/dist/cli-bundle/main.js +15 -14
  70. package/dist/cli-bundle/sdk-authoring.js +1 -1
  71. package/dist/cli-bundle/sdk-contracts.js +2 -2
  72. package/dist/cli-bundle/sdk-core.js +31 -31
  73. package/dist/cli-bundle/sdk-governance.js +1 -1
  74. package/dist/cli-bundle/sdk-graph.js +1 -1
  75. package/dist/cli-bundle/sdk-merge.js +31 -31
  76. package/dist/cli-bundle/sdk-query.js +1 -1
  77. package/dist/cli-bundle/sdk-runtime.js +1 -1
  78. package/dist/cli-bundle/sdk-testing.js +1 -1
  79. package/dist/cli-bundle/sdk.js +32 -6
  80. package/dist/core/extensions/manifest-schema.d.ts +20 -0
  81. package/dist/core/extensions/manifest-schema.js +28 -10
  82. package/dist/core/governance/issue-codes.d.ts +11 -2
  83. package/dist/core/governance/issue-codes.js +29 -10
  84. package/dist/core/item/item-format.js +3 -3
  85. package/dist/core/store/item-store.js +12 -5
  86. package/dist/mcp/http-server.d.ts +60 -0
  87. package/dist/mcp/http-server.js +451 -0
  88. package/dist/mcp/legacy-adapter.d.ts +50 -0
  89. package/dist/mcp/legacy-adapter.js +64 -0
  90. package/dist/mcp/server.d.ts +42 -9
  91. package/dist/mcp/server.js +572 -59
  92. package/dist/mcp/tool-definitions.d.ts +2 -0
  93. package/dist/mcp/tool-definitions.js +2 -2
  94. package/dist/sdk/agent/closed-domain-contracts.d.ts +1 -1
  95. package/dist/sdk/agent/closed-domain-contracts.js +24 -2
  96. package/dist/sdk/agent/refusal-closure-census.d.ts +6 -2
  97. package/dist/sdk/agent/refusal-closure-census.js +16 -8
  98. package/dist/sdk/agent-capability-contracts.js +6 -2
  99. package/dist/sdk/cli-bootstrap.js +3 -2
  100. package/dist/sdk/cli-contracts/command-aliases.js +15 -2
  101. package/dist/sdk/cli-contracts/enum-contracts.d.ts +4 -1
  102. package/dist/sdk/cli-contracts/enum-contracts.js +7 -2
  103. package/dist/sdk/cli-contracts/flag-contracts.js +9 -5
  104. package/dist/sdk/cli-contracts/grammar-contracts.d.ts +3 -3
  105. package/dist/sdk/cli-contracts/grammar-contracts.js +24 -17
  106. package/dist/sdk/cli-contracts/runtime-contracts.js +13 -11
  107. package/dist/sdk/cli-contracts/tool-schema.js +18 -15
  108. package/dist/sdk/cli-contracts.d.ts +1 -1
  109. package/dist/sdk/cli-contracts.js +3 -3
  110. package/dist/sdk/cli-program.js +3 -2
  111. package/dist/sdk/completion.js +40 -13
  112. package/dist/sdk/compose.d.ts +4 -1
  113. package/dist/sdk/compose.js +23 -36
  114. package/dist/sdk/extension/author-manifest.d.ts +22 -0
  115. package/dist/sdk/extension/author-manifest.js +93 -0
  116. package/dist/sdk/extension.js +6 -3
  117. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +20 -5
  118. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +18 -3
  119. package/dist/sdk/governance/health.js +7 -2
  120. package/dist/sdk/governance/upgrade.d.ts +2 -0
  121. package/dist/sdk/governance/upgrade.js +30 -8
  122. package/dist/sdk/governance/validate.js +8 -6
  123. package/dist/sdk/guide-topics.js +6 -6
  124. package/dist/sdk/index.d.ts +10 -2
  125. package/dist/sdk/index.js +11 -3
  126. package/dist/sdk/mcp/apps.d.ts +70 -0
  127. package/dist/sdk/mcp/apps.js +154 -0
  128. package/dist/sdk/mcp/authorization.d.ts +134 -0
  129. package/dist/sdk/mcp/authorization.js +405 -0
  130. package/dist/sdk/mcp/interactions.d.ts +118 -0
  131. package/dist/sdk/mcp/interactions.js +337 -0
  132. package/dist/sdk/mcp/protocol.d.ts +142 -0
  133. package/dist/sdk/mcp/protocol.js +174 -0
  134. package/dist/sdk/mcp/skills.d.ts +127 -0
  135. package/dist/sdk/mcp/skills.js +390 -0
  136. package/dist/sdk/mcp/subscriptions.d.ts +65 -0
  137. package/dist/sdk/mcp/subscriptions.js +212 -0
  138. package/dist/sdk/mcp/tasks.d.ts +107 -0
  139. package/dist/sdk/mcp/tasks.js +431 -0
  140. package/dist/sdk/mcp/transport.d.ts +30 -0
  141. package/dist/sdk/mcp/transport.js +261 -0
  142. package/dist/sdk/merge/receipts.d.ts +16 -0
  143. package/dist/sdk/merge/receipts.js +9 -8
  144. package/dist/sdk/read-output-contracts.js +16 -3
  145. package/dist/sdk/runtime-action-aliases.js +7 -3
  146. package/dist/sdk/runtime-input.js +12 -4
  147. package/dist/sdk/runtime-primitives.d.ts +2 -2
  148. package/dist/sdk/runtime-primitives.js +4 -4
  149. package/dist/sdk/test/execution.d.ts +6 -0
  150. package/dist/sdk/test/execution.js +32 -3
  151. package/docs/AGENT_PROVENANCE_ADR.md +6 -4
  152. package/docs/AGENT_RUNTIME_PRIMITIVES.md +6 -5
  153. package/docs/CLAUDE_CODE_PLUGIN.md +12 -5
  154. package/docs/CLI_GRAMMAR.md +7 -1
  155. package/docs/COMMANDS.md +2 -2
  156. package/docs/DIAGNOSTIC_OUTPUT_CONTRACTS.md +8 -0
  157. package/docs/EXTENSIONS.md +36 -36
  158. package/docs/MCP_2026_07_28.md +160 -0
  159. package/docs/MCP_2026_07_28_CONFORMANCE.md +30 -0
  160. package/docs/MCP_REMOTE_TRANSPORT_SECURITY.md +180 -0
  161. package/docs/MCP_SKILLS_AND_APPS.md +107 -0
  162. package/docs/QUICKSTART.md +15 -15
  163. package/docs/README.md +5 -0
  164. package/docs/RELEASING.md +12 -3
  165. package/docs/SDK.md +22 -1
  166. package/docs/SDK_AGENT_SESSION_CONTEXT.md +18 -13
  167. package/docs/SDK_CONTEXT_INTEGRITY.md +6 -0
  168. package/docs/SDK_EVIDENCE_TRACEABILITY.md +9 -1
  169. package/docs/SDK_MCP_INTERACTIONS.md +227 -0
  170. package/docs/TESTING.md +4 -0
  171. package/docs/generated/AGENT_CAPABILITY_ROUTING.md +1 -1
  172. package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +13 -11
  173. package/marketplace.json +2 -2
  174. package/package.json +15 -11
  175. package/packages/pm-beads/README.md +12 -6
  176. package/packages/pm-beads/docs/MIGRATION.md +53 -0
  177. package/packages/pm-beads/extensions/beads/index.ts +8 -0
  178. package/packages/pm-beads/extensions/beads/runtime.ts +671 -112
  179. package/packages/pm-beads/package.json +1 -1
  180. package/packages/pm-calendar/package.json +1 -1
  181. package/packages/pm-command-kit/package.json +1 -1
  182. package/packages/pm-digital-twin/package.json +1 -1
  183. package/packages/pm-governance-audit/package.json +1 -1
  184. package/packages/pm-guide-shell/package.json +1 -1
  185. package/packages/pm-kanban/package.json +1 -1
  186. package/packages/pm-lifecycle-hooks/package.json +1 -1
  187. package/packages/pm-linked-test-adapters/package.json +1 -1
  188. package/packages/pm-search-advanced/package.json +1 -1
  189. package/packages/pm-templates/package.json +1 -1
  190. package/packages/pm-todos/package.json +1 -1
  191. package/packages/pm-vcs/package.json +1 -1
  192. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  193. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  194. package/scripts/finalize-build.mjs +1 -0
  195. package/sdk/public-surface.json +902 -54
  196. package/dist/cli-bundle/chunks/chunk-2F3LUFMW.js +0 -8
  197. package/dist/cli-bundle/chunks/chunk-65MHLHAA.js +0 -2
  198. package/dist/cli-bundle/chunks/chunk-6C7GIMIL.js +0 -13
  199. package/dist/cli-bundle/chunks/chunk-QKGMHGEI.js +0 -202
  200. package/dist/cli-bundle/chunks/chunk-T2ENPRXF.js +0 -3
  201. package/dist/cli-bundle/chunks/chunk-TPQIBSL2.js +0 -3
  202. package/dist/cli-bundle/chunks/chunk-YQMYF3YD.js +0 -35
  203. package/dist/cli-bundle/chunks/register-setup-LXVBRCJ3.js +0 -2
  204. package/dist/cli-bundle/focused-chunks/chunk-42S3GGZ7.js +0 -50
  205. package/dist/cli-bundle/focused-chunks/chunk-7I23XGWO.js +0 -2
  206. package/dist/cli-bundle/focused-chunks/chunk-LMKG3DFE.js +0 -5
@@ -0,0 +1,261 @@
1
+ /**
2
+ * @module sdk/mcp/transport
3
+ *
4
+ * Implements MCP 2026-07-28 Streamable HTTP header encoding, schema-derived
5
+ * custom header extraction, and body/header parity validation.
6
+ */
7
+
8
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="5ffe7128-0fbb-59af-89ef-74d5d799a00d")}catch(e){}}();
9
+ import { PM_MCP_ERROR_CODES, PM_MCP_PROTOCOL_VERSION, PmMcpProtocolError, isMcpRecord, resolveMcpRequestContext, } from "./protocol.js";
10
+ const BASE64_SENTINEL_PATTERN = /^=\?base64\?([A-Za-z0-9+/]*={0,2})\?=$/u;
11
+ const HEADER_NAME_TOKEN_PATTERN = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/u;
12
+ const PLAIN_HEADER_VALUE_PATTERN = /^[\t\x20-\x7E]*$/u;
13
+ const REQUIRED_NAME_METHODS = new Set([
14
+ "prompts/get",
15
+ "resources/read",
16
+ "tools/call",
17
+ ]);
18
+ function normalizedHeaders(headers) {
19
+ const normalized = new Map();
20
+ for (const [name, value] of Object.entries(headers)) {
21
+ if (value === undefined)
22
+ continue;
23
+ const entry = typeof value === "string" ? value : value.join(", ");
24
+ normalized.set(name.toLowerCase(), entry);
25
+ }
26
+ return normalized;
27
+ }
28
+ function failHeader(message, header) {
29
+ throw new PmMcpProtocolError(message, PM_MCP_ERROR_CODES.headerMismatch, {
30
+ header,
31
+ });
32
+ }
33
+ /** Encode a name or primitive parameter into the protocol's safe header form. */
34
+ export function encodeMcpHttpHeaderValue(value) {
35
+ const serialized = typeof value === "boolean" ? String(value).toLowerCase() : String(value);
36
+ if (serialized.length > 0 &&
37
+ serialized.trim() === serialized &&
38
+ PLAIN_HEADER_VALUE_PATTERN.test(serialized) &&
39
+ !BASE64_SENTINEL_PATTERN.test(serialized)) {
40
+ return serialized;
41
+ }
42
+ return `=?base64?${Buffer.from(serialized, "utf8").toString("base64")}?=`;
43
+ }
44
+ /** Decode and validate a mirrored MCP header value. */
45
+ export function decodeMcpHttpHeaderValue(value, header) {
46
+ const sentinel = BASE64_SENTINEL_PATTERN.exec(value);
47
+ if (sentinel) {
48
+ const encoded = sentinel[1];
49
+ const decoded = Buffer.from(encoded, "base64");
50
+ if (decoded.toString("base64") !== encoded || decoded.length === 0) {
51
+ return failHeader("Malformed MCP Base64 header value", header);
52
+ }
53
+ return decoded.toString("utf8");
54
+ }
55
+ if (value.length === 0 ||
56
+ value.trim() !== value ||
57
+ !PLAIN_HEADER_VALUE_PATTERN.test(value)) {
58
+ return failHeader("Malformed MCP header value", header);
59
+ }
60
+ return value;
61
+ }
62
+ function containsHeaderAnnotation(value) {
63
+ if (Array.isArray(value))
64
+ return value.some(containsHeaderAnnotation);
65
+ if (!isMcpRecord(value))
66
+ return false;
67
+ return (Object.prototype.hasOwnProperty.call(value, "x-mcp-header") ||
68
+ Object.values(value).some(containsHeaderAnnotation));
69
+ }
70
+ /** Validate and normalize one schema-derived custom-header annotation. */
71
+ function parseMcpHeaderAnnotation(propertySchema, propertyPath, names) {
72
+ const annotation = propertySchema["x-mcp-header"];
73
+ if (annotation === undefined)
74
+ return undefined;
75
+ const type = propertySchema.type;
76
+ if (typeof annotation !== "string" ||
77
+ !HEADER_NAME_TOKEN_PATTERN.test(annotation) ||
78
+ !["boolean", "integer", "string"].includes(String(type)) ||
79
+ names.has(annotation.toLowerCase())) {
80
+ throw new PmMcpProtocolError("Invalid MCP x-mcp-header annotation", PM_MCP_ERROR_CODES.invalidParams, { field: propertyPath.join("."), annotation });
81
+ }
82
+ names.add(annotation.toLowerCase());
83
+ return {
84
+ name: annotation,
85
+ path: propertyPath,
86
+ type: type,
87
+ };
88
+ }
89
+ /** Parse valid statically reachable custom-header annotations from a tool schema. */
90
+ export function collectMcpHeaderAnnotations(schema) {
91
+ if (!isMcpRecord(schema)) {
92
+ throw new PmMcpProtocolError("Invalid MCP tool schema", PM_MCP_ERROR_CODES.invalidParams, { field: "inputSchema", expected: "object" });
93
+ }
94
+ const annotations = [];
95
+ const names = new Set();
96
+ const visitProperties = (node, path) => {
97
+ const properties = node.properties;
98
+ if (properties === undefined)
99
+ return;
100
+ if (!isMcpRecord(properties)) {
101
+ throw new PmMcpProtocolError("Invalid MCP tool schema properties", PM_MCP_ERROR_CODES.invalidParams, { field: "inputSchema.properties" });
102
+ }
103
+ for (const [property, propertySchema] of Object.entries(properties)) {
104
+ if (!isMcpRecord(propertySchema))
105
+ continue;
106
+ const propertyPath = [...path, property];
107
+ const annotation = parseMcpHeaderAnnotation(propertySchema, propertyPath, names);
108
+ if (annotation)
109
+ annotations.push(annotation);
110
+ for (const [keyword, nested] of Object.entries(propertySchema)) {
111
+ if (keyword !== "properties" &&
112
+ keyword !== "x-mcp-header" &&
113
+ containsHeaderAnnotation(nested)) {
114
+ throw new PmMcpProtocolError("MCP x-mcp-header is not statically reachable", PM_MCP_ERROR_CODES.invalidParams, { field: propertyPath.join("."), keyword });
115
+ }
116
+ }
117
+ visitProperties(propertySchema, propertyPath);
118
+ }
119
+ };
120
+ for (const [keyword, nested] of Object.entries(schema)) {
121
+ if (keyword !== "properties" && containsHeaderAnnotation(nested)) {
122
+ throw new PmMcpProtocolError("MCP x-mcp-header is not statically reachable", PM_MCP_ERROR_CODES.invalidParams, { field: "inputSchema", keyword });
123
+ }
124
+ }
125
+ visitProperties(schema, []);
126
+ return annotations;
127
+ }
128
+ function valueAtPath(value, path) {
129
+ let current = value;
130
+ for (const part of path) {
131
+ if (!isMcpRecord(current))
132
+ return undefined;
133
+ current = current[part];
134
+ }
135
+ return current;
136
+ }
137
+ function mirroredName(method, params) {
138
+ const value = method === "resources/read" ? params.uri : params.name;
139
+ return typeof value === "string" ? value : undefined;
140
+ }
141
+ function buildMcpCustomRequestHeaders(params, toolSchema) {
142
+ const argumentsValue = isMcpRecord(params.arguments) ? params.arguments : {};
143
+ const headers = {};
144
+ for (const annotation of collectMcpHeaderAnnotations(toolSchema)) {
145
+ const value = valueAtPath(argumentsValue, annotation.path);
146
+ if (value === undefined || value === null)
147
+ continue;
148
+ const valid = (annotation.type === "integer" &&
149
+ typeof value === "number" &&
150
+ Number.isSafeInteger(value)) ||
151
+ (annotation.type === "boolean" && typeof value === "boolean") ||
152
+ (annotation.type === "string" && typeof value === "string");
153
+ if (!valid) {
154
+ throw new PmMcpProtocolError("Invalid MCP custom header argument", PM_MCP_ERROR_CODES.invalidParams, { field: annotation.path.join("."), expected: annotation.type });
155
+ }
156
+ headers[`Mcp-Param-${annotation.name}`] = encodeMcpHttpHeaderValue(value);
157
+ }
158
+ return headers;
159
+ }
160
+ /** Build required Streamable HTTP headers for one modern client request. */
161
+ export function buildMcpHttpRequestHeaders(input) {
162
+ const params = isMcpRecord(input.request.params)
163
+ ? input.request.params
164
+ : undefined;
165
+ const context = resolveMcpRequestContext(params);
166
+ const method = input.request.method;
167
+ if (typeof method !== "string" || method.length === 0) {
168
+ return failHeader("Missing MCP request method", "Mcp-Method");
169
+ }
170
+ const headers = {
171
+ Accept: "application/json, text/event-stream",
172
+ "Content-Type": "application/json",
173
+ "MCP-Protocol-Version": context.protocolVersion,
174
+ "Mcp-Method": method,
175
+ };
176
+ const name = mirroredName(method, params);
177
+ if (REQUIRED_NAME_METHODS.has(method)) {
178
+ if (name === undefined)
179
+ return failHeader("Missing MCP request name", "Mcp-Name");
180
+ headers["Mcp-Name"] = encodeMcpHttpHeaderValue(name);
181
+ }
182
+ if (method === "tools/call" && input.toolSchema !== undefined) {
183
+ Object.assign(headers, buildMcpCustomRequestHeaders(params, input.toolSchema));
184
+ }
185
+ return headers;
186
+ }
187
+ function validateMcpRequiredRequestHeaders(headers, request) {
188
+ const method = request.method;
189
+ if (typeof method !== "string" || method.length === 0) {
190
+ failHeader("Missing MCP request method", "Mcp-Method");
191
+ }
192
+ const params = isMcpRecord(request.params) ? request.params : undefined;
193
+ const expectedProtocol = resolveMcpRequestContext(params).protocolVersion;
194
+ if (headers.get("mcp-protocol-version") !== expectedProtocol) {
195
+ failHeader("MCP protocol header does not match request metadata", "MCP-Protocol-Version");
196
+ }
197
+ if (headers.get("mcp-method") !== method) {
198
+ failHeader("MCP method header does not match request body", "Mcp-Method");
199
+ }
200
+ if (REQUIRED_NAME_METHODS.has(method)) {
201
+ const headerName = headers.get("mcp-name");
202
+ const name = mirroredName(method, params);
203
+ if (headerName === undefined ||
204
+ name === undefined ||
205
+ decodeMcpHttpHeaderValue(headerName, "Mcp-Name") !== name) {
206
+ failHeader("MCP name header does not match request body", "Mcp-Name");
207
+ }
208
+ }
209
+ if (headers.has("last-event-id")) {
210
+ // The preceding match is an mcp-deprecation-negative-control: no resume/redelivery.
211
+ failHeader("MCP SSE resumability is not supported", "Last-Event-ID");
212
+ }
213
+ }
214
+ function customHeaderMatches(annotation, value, decoded) {
215
+ if (annotation.type === "integer") {
216
+ return (typeof value === "number" &&
217
+ Number.isSafeInteger(value) &&
218
+ Number(decoded) === value);
219
+ }
220
+ if (annotation.type === "boolean") {
221
+ return typeof value === "boolean" && decoded === String(value);
222
+ }
223
+ return typeof value === "string" && decoded === value;
224
+ }
225
+ function validateMcpCustomRequestHeaders(input) {
226
+ const argumentsValue = isMcpRecord(input.params.arguments)
227
+ ? input.params.arguments
228
+ : {};
229
+ for (const annotation of collectMcpHeaderAnnotations(input.toolSchema)) {
230
+ const value = valueAtPath(argumentsValue, annotation.path);
231
+ const header = `Mcp-Param-${annotation.name}`;
232
+ const mirrored = input.headers.get(header.toLowerCase());
233
+ if (value === undefined || value === null) {
234
+ if (mirrored !== undefined)
235
+ failHeader("Unexpected MCP parameter header", header);
236
+ continue;
237
+ }
238
+ if (mirrored === undefined)
239
+ failHeader("Missing MCP parameter header", header);
240
+ if (!customHeaderMatches(annotation, value, decodeMcpHttpHeaderValue(mirrored, header))) {
241
+ failHeader("MCP parameter header does not match request body", header);
242
+ }
243
+ }
244
+ }
245
+ /** Validate required Streamable HTTP headers against the JSON-RPC body. */
246
+ export function validateMcpHttpRequestHeaders(input) {
247
+ const headers = normalizedHeaders(input.headers);
248
+ const method = typeof input.request.method === "string" ? input.request.method : "";
249
+ validateMcpRequiredRequestHeaders(headers, input.request);
250
+ if (method !== "tools/call" || input.toolSchema === undefined)
251
+ return;
252
+ validateMcpCustomRequestHeaders({
253
+ headers,
254
+ params: input.request.params,
255
+ toolSchema: input.toolSchema,
256
+ });
257
+ }
258
+ /** Required protocol version exposed for clients constructing headers manually. */
259
+ export const PM_MCP_HTTP_PROTOCOL_VERSION = PM_MCP_PROTOCOL_VERSION;
260
+ //# sourceMappingURL=transport.js.map
261
+ //# debugId=5ffe7128-0fbb-59af-89ef-74d5d799a00d
@@ -77,6 +77,17 @@ export interface MergeReceiptEvidenceScan {
77
77
  /** Number of JSON receipt candidates that could not be validated safely. */
78
78
  invalid_evidence_count: number;
79
79
  }
80
+ declare function prepareReceiptSettlement(params: {
81
+ receiptPath: string;
82
+ receiptId: string;
83
+ evidenceSource: "clone_local" | "durable";
84
+ reconciledAt: string;
85
+ readReceipt?: (receiptPath: string) => Promise<string | null>;
86
+ }): Promise<{
87
+ path: string;
88
+ content: string;
89
+ fingerprint: string;
90
+ } | null>;
80
91
  /** Convert a raw receipt into privacy-safe history context. */
81
92
  export declare function summarizeMergeReceipt(receipt: MergeDecisionReceipt): MergeDecisionReceiptSummary;
82
93
  /** Persist one item-driver outcome in the clone-local Git directory. */
@@ -123,3 +134,8 @@ export declare function runMergeReceiptReport(options: {
123
134
  /** Repository directory to inspect; defaults to the process working directory. */
124
135
  cwd?: string;
125
136
  }): Promise<MergeReceiptReport>;
137
+ /** Test-only seams for deterministic receipt-boundary fault coverage. */
138
+ export declare const _testOnlyMergeReceipts: {
139
+ prepareReceiptSettlement: typeof prepareReceiptSettlement;
140
+ };
141
+ export {};
@@ -7,7 +7,7 @@
7
7
  * value for the coordinator that performed the merge.
8
8
  */
9
9
 
10
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="5add49c0-25be-5159-abfc-6c7ae9272f6b")}catch(e){}}();
10
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="145a6d31-5e14-5b0b-95fb-6f837d11e2f4")}catch(e){}}();
11
11
  import { execFile } from "node:child_process";
12
12
  import { randomUUID } from "node:crypto";
13
13
  import { readdir } from "node:fs/promises";
@@ -222,7 +222,7 @@ async function readBoundedRegularReceiptFile(receiptPath) {
222
222
  async function prepareReceiptSettlement(params) {
223
223
  let raw;
224
224
  try {
225
- raw = await readBoundedRegularReceiptFile(params.receiptPath);
225
+ raw = await (params.readReceipt ?? readBoundedRegularReceiptFile)(params.receiptPath);
226
226
  }
227
227
  catch (error) {
228
228
  if (isFileAbsentError(error))
@@ -467,6 +467,10 @@ export async function markMergeReceiptReconciled(cwd, receipt, options = {}) {
467
467
  }
468
468
  return;
469
469
  }
470
+ const receiptEvidenceSource = receipt.evidence_source ?? "clone_local";
471
+ if (!isMergeDecisionReceipt(receipt, receiptEvidenceSource)) {
472
+ throw new Error("Merge receipt trusted settlement input failed schema validation.");
473
+ }
470
474
  const reconciledAt = nowIso();
471
475
  const localPath = path.join(directory, receiptFileName(receipt.id));
472
476
  const trackerRoot = await resolveTrackerRootFromItemPath(cwd, receipt.item_path);
@@ -498,11 +502,6 @@ export async function markMergeReceiptReconciled(cwd, receipt, options = {}) {
498
502
  }
499
503
  return;
500
504
  }
501
- const receiptEvidenceSource = receipt.evidence_source ?? "clone_local";
502
- const trustedReceiptId = receipt.id;
503
- if (!isMergeDecisionReceipt(receipt, receiptEvidenceSource)) {
504
- throw new Error(`Receipt ${trustedReceiptId} trusted settlement input failed schema validation.`);
505
- }
506
505
  const expectedFingerprint = receiptProvenanceFingerprint(receipt);
507
506
  if (new Set([expectedFingerprint, ...writes.map((write) => write.fingerprint)])
508
507
  .size !== 1) {
@@ -525,5 +524,7 @@ export async function runMergeReceiptReport(options) {
525
524
  generated_at: nowIso(),
526
525
  };
527
526
  }
527
+ /** Test-only seams for deterministic receipt-boundary fault coverage. */
528
+ export const _testOnlyMergeReceipts = { prepareReceiptSettlement };
528
529
  //# sourceMappingURL=receipts.js.map
529
- //# debugId=5add49c0-25be-5159-abfc-6c7ae9272f6b
530
+ //# debugId=145a6d31-5e14-5b0b-95fb-6f837d11e2f4
@@ -5,7 +5,7 @@
5
5
  * surface without coupling package authors to command-specific option names.
6
6
  */
7
7
 
8
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="d084da05-c967-58f1-afe4-069f09838e6f")}catch(e){}}();
8
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="2103a4dc-3037-5768-b2c7-5964de4ac86b")}catch(e){}}();
9
9
  import { EXIT_CODE } from "../core/shared/constants.js";
10
10
  import { PmCliError } from "../core/shared/errors.js";
11
11
  import { compactReadOutputToBudget, estimateReadOutputTokens, resolveReadOutputRecoveryBudget, updateReadOutputReceiptEstimate, } from "./read-output-budget.js";
@@ -388,7 +388,20 @@ export function applyReadOutputIncludeModes(command, includeValue, commandOption
388
388
  modes.push(token);
389
389
  canonicalModes.add(token);
390
390
  }
391
- if (modes.length > 0) {
391
+ const forwardedGetFieldSelectors = resolveReadOutputSurface(command) === "get"
392
+ ? selectors.filter((selector) => selector !== "item")
393
+ : [];
394
+ const forwardedGetFields = forwardedGetFieldSelectors.length > 0;
395
+ if (forwardedGetFields) {
396
+ commandOptions.fields = [
397
+ ...new Set([
398
+ ...(stringList(commandOptions.fields) ?? []),
399
+ ...forwardedGetFieldSelectors,
400
+ ]),
401
+ ].join(",");
402
+ canonicalModes.add("fields");
403
+ }
404
+ if (modes.length > 0 || forwardedGetFields) {
392
405
  optionsWithProvenance[READ_OUTPUT_INVOCATION_PROVENANCE] = {
393
406
  canonical_include_modes: [...canonicalModes],
394
407
  explicit_legacy_aliases: [...explicitLegacyAliases],
@@ -1210,4 +1223,4 @@ export function resolveReadOutputEncoding(command, options) {
1210
1223
  : undefined;
1211
1224
  }
1212
1225
  //# sourceMappingURL=read-output-contracts.js.map
1213
- //# debugId=d084da05-c967-58f1-afe4-069f09838e6f
1226
+ //# debugId=2103a4dc-3037-5768-b2c7-5964de4ac86b
@@ -4,8 +4,8 @@
4
4
  * Declares canonical native-action routes for public SDK aliases.
5
5
  */
6
6
 
7
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="6f62939a-7b99-5687-93ae-834e0032f1d5")}catch(e){}}();
8
- import { PM_EXTENSION_PACKAGE_ACTION_SUBCOMMANDS } from "./cli-contracts/enum-contracts.js";
7
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="1ff4005f-be23-5dcf-9834-dbd7d083b76d")}catch(e){}}();
8
+ import { PM_EXTENSION_PACKAGE_ACTION_SUBCOMMANDS, PM_PACKAGE_ONLY_ACTION_SUBCOMMANDS, } from "./cli-contracts/enum-contracts.js";
9
9
  const LIST_ACTION_ALIASES = {
10
10
  "list-all": { action: "list", options: { excludeTerminal: false } },
11
11
  "list-draft": {
@@ -51,6 +51,10 @@ export const SDK_ACTION_ALIASES = {
51
51
  ...LIST_ACTION_ALIASES,
52
52
  ...buildExtensionPackageActionAliases("extension"),
53
53
  ...buildExtensionPackageActionAliases("package"),
54
+ ...Object.fromEntries(PM_PACKAGE_ONLY_ACTION_SUBCOMMANDS.map((subcommand) => [
55
+ `package-${subcommand}`,
56
+ { action: subcommand },
57
+ ])),
54
58
  };
55
59
  //# sourceMappingURL=runtime-action-aliases.js.map
56
- //# debugId=6f62939a-7b99-5687-93ae-834e0032f1d5
60
+ //# debugId=1ff4005f-be23-5dcf-9834-dbd7d083b76d
@@ -5,7 +5,7 @@
5
5
  * primitives are shared by native action dispatchers and MCP-specific adapters.
6
6
  */
7
7
 
8
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="2a1e986f-304d-50f6-a405-6afc221bdad5")}catch(e){}}();
8
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="7949205a-ab1b-5457-961c-593498aff88b")}catch(e){}}();
9
9
  import { EXIT_CODE } from "../core/shared/constants.js";
10
10
  import { PmCliError } from "../core/shared/errors.js";
11
11
  import { asRecordClone } from "../core/shared/primitives.js";
@@ -202,6 +202,15 @@ const HOISTED_ACTION_OPTION_KEYS = {
202
202
  update: ["parent", "allowMissingParent", "completedAt"],
203
203
  copy: ["allowDuplicate"],
204
204
  close: ["duplicateOf", "completedAt"],
205
+ upgrade: [
206
+ "scope",
207
+ "dryRun",
208
+ "cliOnly",
209
+ "packagesOnly",
210
+ "repair",
211
+ "tag",
212
+ "packageName",
213
+ ],
205
214
  // pm-7u9j: the narrow pm_append tool declares `body` top-level; runAppend
206
215
  // reads it from options, while schema/config consume their top-level values
207
216
  // directly in runAction and therefore need no hoisting.
@@ -232,8 +241,7 @@ export function normalizeMcpOptionsArrays(options, action = "") {
232
241
  result[key] = value;
233
242
  continue;
234
243
  }
235
- if (typeof value === "string" &&
236
- scalarToArrayFields.has(key)) {
244
+ if (typeof value === "string" && scalarToArrayFields.has(key)) {
237
245
  result[key] = [value];
238
246
  continue;
239
247
  }
@@ -578,4 +586,4 @@ export function updateManyOptionsFromFlat(options) {
578
586
  };
579
587
  }
580
588
  //# sourceMappingURL=runtime-input.js.map
581
- //# debugId=2a1e986f-304d-50f6-a405-6afc221bdad5
589
+ //# debugId=7949205a-ab1b-5457-961c-593498aff88b
@@ -13,7 +13,7 @@ export { type ActiveExtensionHookContext, type ExtensionCommandRegistry, type Ex
13
13
  export { applyRegisteredItemFieldDefaultsAndValidation, collectRegisteredItemFieldNames, parseRegisteredItemFieldAssignments, } from "../core/extensions/item-fields.js";
14
14
  export { resolveExtensionRoots } from "../core/extensions/loader.js";
15
15
  export { resolveRegisteredSearchProvider, resolveRegisteredVectorStoreAdapter, } from "../core/extensions/runtime-registrations.js";
16
- export { pathExists, readFileIfExists, removeFileIfExists, writeFileAtomic, } from "../core/fs/fs-utils.js";
16
+ export { isFileMissingError, pathExists, readFileIfExists, removeFileIfExists, writeFileAtomic, } from "../core/fs/fs-utils.js";
17
17
  export { normalizeBulkIdsValue, parseBulkIdsText, resolveCliBulkIdsInput, type BulkIdsFileReader, type BulkIdsInputReaders, type BulkIdsStdinReader, type BulkIdsValue, } from "../core/io/bulk-ids-input.js";
18
18
  export { type HistoryDiffValueEntry, computeHistoryDiff, patchPathToChangedField, } from "../core/history/history-diff.js";
19
19
  export { enforceHistoryStreamPolicyForItem, enforceHistoryStreamPolicyForItems, } from "../core/history/history-stream-policy.js";
@@ -75,7 +75,7 @@ export { migrateItemFilesToFormat } from "../core/store/item-format-migration.js
75
75
  export { type CachedDocumentCandidate, listAllDocumentCandidatesCached, } from "../core/store/item-metadata-cache.js";
76
76
  export { buildItemNotFoundError, createMutationGuardSdk, deleteItem, listAllItemMetadata, listAllItemMetadataLight, locateItem, mutateItem, mutateItemWithHistoryContext, readLocatedItem, } from "../core/store/item-store.js";
77
77
  export { isTerminalPlanMode, shouldCompletePlanOnClose, } from "../core/item/plan-lifecycle.js";
78
- export { getHistoryPath, getItemPath, getSettingsPath, resolveImplicitPmRoot, resolvePmRoot, } from "../core/store/paths.js";
78
+ export { getHistoryPath, getItemPath, getSettingsPath, resolveImplicitPmRoot, resolvePmRoot, resolveWorkspaceRoot, } from "../core/store/paths.js";
79
79
  export { persistSelectedItemFormat, readSettings, readSettingsWithMetadata, writeSettings, } from "../core/store/settings.js";
80
80
  export { maybeRunFirstUseTelemetryPrompt } from "../core/telemetry/consent.js";
81
81
  export { type TelemetryCommandResolution, type TelemetryResolutionStage, deriveTelemetryCommandResolution, } from "../core/telemetry/observability.js";
@@ -7,7 +7,7 @@
7
7
  * prefer the typed operations exported by the main SDK barrel.
8
8
  */
9
9
 
10
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="be6f7869-f197-5d38-b8d9-faf8f390cd56")}catch(e){}}();
10
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="d45775e5-6826-521b-80b3-429ed22947d9")}catch(e){}}();
11
11
  export { createCheckpointId, loadMutationCheckpoint, restoreCheckpointItems, writeMutationCheckpoint, } from "../core/checkpoint/mutation-checkpoint.js";
12
12
  export { flattenFlagListValue, resolveFlagValueKind, } from "../core/extensions/flag-value-types.js";
13
13
  export { createUnknownSubcommandError, } from "./agent/subcommand-recovery.js";
@@ -15,7 +15,7 @@ export { activateExtensions, clearActiveExtensionHooks, consumeAfterCommandAffec
15
15
  export { applyRegisteredItemFieldDefaultsAndValidation, collectRegisteredItemFieldNames, parseRegisteredItemFieldAssignments, } from "../core/extensions/item-fields.js";
16
16
  export { resolveExtensionRoots } from "../core/extensions/loader.js";
17
17
  export { resolveRegisteredSearchProvider, resolveRegisteredVectorStoreAdapter, } from "../core/extensions/runtime-registrations.js";
18
- export { pathExists, readFileIfExists, removeFileIfExists, writeFileAtomic, } from "../core/fs/fs-utils.js";
18
+ export { isFileMissingError, pathExists, readFileIfExists, removeFileIfExists, writeFileAtomic, } from "../core/fs/fs-utils.js";
19
19
  export { normalizeBulkIdsValue, parseBulkIdsText, resolveCliBulkIdsInput, } from "../core/io/bulk-ids-input.js";
20
20
  export { computeHistoryDiff, patchPathToChangedField, } from "../core/history/history-diff.js";
21
21
  export { enforceHistoryStreamPolicyForItem, enforceHistoryStreamPolicyForItems, } from "../core/history/history-stream-policy.js";
@@ -76,10 +76,10 @@ export { migrateItemFilesToFormat } from "../core/store/item-format-migration.js
76
76
  export { listAllDocumentCandidatesCached, } from "../core/store/item-metadata-cache.js";
77
77
  export { buildItemNotFoundError, createMutationGuardSdk, deleteItem, listAllItemMetadata, listAllItemMetadataLight, locateItem, mutateItem, mutateItemWithHistoryContext, readLocatedItem, } from "../core/store/item-store.js";
78
78
  export { isTerminalPlanMode, shouldCompletePlanOnClose, } from "../core/item/plan-lifecycle.js";
79
- export { getHistoryPath, getItemPath, getSettingsPath, resolveImplicitPmRoot, resolvePmRoot, } from "../core/store/paths.js";
79
+ export { getHistoryPath, getItemPath, getSettingsPath, resolveImplicitPmRoot, resolvePmRoot, resolveWorkspaceRoot, } from "../core/store/paths.js";
80
80
  export { persistSelectedItemFormat, readSettings, readSettingsWithMetadata, writeSettings, } from "../core/store/settings.js";
81
81
  export { maybeRunFirstUseTelemetryPrompt } from "../core/telemetry/consent.js";
82
82
  export { deriveTelemetryCommandResolution, } from "../core/telemetry/observability.js";
83
83
  export { emitTelemetryErrorEvent, finishTelemetryCommand, startTelemetryCommand, } from "../core/telemetry/runtime.js";
84
84
  //# sourceMappingURL=runtime-primitives.js.map
85
- //# debugId=be6f7869-f197-5d38-b8d9-faf8f390cd56
85
+ //# debugId=d45775e5-6826-521b-80b3-429ed22947d9
@@ -220,6 +220,11 @@ declare function copyIntoSandboxIfPresent(sourcePath: string, targetPath: string
220
220
  }) => Promise<unknown>): Promise<void>;
221
221
  declare function seedLinkedTestSandbox(sandboxPmPath: string, sandboxGlobalPath: string, sourceRoots: LinkedTestSandboxSourceRoots): Promise<void>;
222
222
  declare function seedLinkedTestTrackerData(sourceRoot: string, sandboxRoot: string): Promise<void>;
223
+ /**
224
+ * Create an audited settings snapshot only for source trackers that predate
225
+ * workspace history, while preserving any existing source history verbatim.
226
+ */
227
+ declare function seedMissingLinkedTestSettingsHistory(sourceRoot: string, sandboxRoot: string): Promise<void>;
223
228
  declare function countLinkedTestItemFiles(pmRoot: string): Promise<number>;
224
229
  /** Implements resolve linked test failure exit code for the public runtime surface of this module. */
225
230
  export declare function resolveLinkedTestFailureExitCode(execution: Pick<LinkedTestExecutionResult, "exitCode" | "timedOut" | "maxBufferExceeded">): number;
@@ -321,6 +326,7 @@ export declare const _testOnlyTestCommand: {
321
326
  resolveTestRunOptions: typeof resolveTestRunOptions;
322
327
  resolveTrackedRunId: typeof resolveTrackedRunId;
323
328
  runLinkedTestCommand: typeof runLinkedTestCommand;
329
+ seedMissingLinkedTestSettingsHistory: typeof seedMissingLinkedTestSettingsHistory;
324
330
  seedLinkedTestSandbox: typeof seedLinkedTestSandbox;
325
331
  seedLinkedTestTrackerData: typeof seedLinkedTestTrackerData;
326
332
  segmentInvokesRecursiveTestAll: typeof segmentInvokesRecursiveTestAll;
@@ -4,14 +4,15 @@
4
4
  * Implements the pm test command surface and its agent-facing runtime behavior.
5
5
  */
6
6
 
7
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="7659721c-21f5-55da-8cce-31b290de5bfb")}catch(e){}}();
7
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="99ce92bb-ed45-5327-b148-b5bb26a0bf05")}catch(e){}}();
8
8
  import { assertInitializedTracker } from "../environment/tracker-preflight.js";
9
9
  import { spawn } from "node:child_process";
10
10
  import { cp, mkdir, mkdtemp, open, readdir, rm, symlink, } from "node:fs/promises";
11
11
  import { tmpdir } from "node:os";
12
12
  import path from "node:path";
13
13
  import { getActiveExtensionRegistrations } from "../../core/extensions/index.js";
14
- import { isFileMissingError, pathExists } from "../../core/fs/fs-utils.js";
14
+ import { isFileMissingError, pathExists, readFileIfExists, } from "../../core/fs/fs-utils.js";
15
+ import { getWorkspaceHistoryPath, writeWorkspaceJsonWithHistory, } from "../../core/history/workspace-history.js";
15
16
  import { resolveItemTypeRegistry } from "../../core/item/type-registry.js";
16
17
  import { createStdinTokenResolver, parseCsvKv, parseOptionalNumber, } from "../../core/item/parse.js";
17
18
  import { EXIT_CODE } from "../../core/shared/constants.js";
@@ -1043,6 +1044,31 @@ async function seedLinkedTestTrackerData(sourceRoot, sandboxRoot) {
1043
1044
  }
1044
1045
  }
1045
1046
  }
1047
+ /**
1048
+ * Create an audited settings snapshot only for source trackers that predate
1049
+ * workspace history, while preserving any existing source history verbatim.
1050
+ */
1051
+ async function seedMissingLinkedTestSettingsHistory(sourceRoot, sandboxRoot) {
1052
+ const sourceSettingsRaw = await readFileIfExists(getSettingsPath(sourceRoot));
1053
+ if (sourceSettingsRaw === null ||
1054
+ (await pathExists(getWorkspaceHistoryPath(sourceRoot)))) {
1055
+ return;
1056
+ }
1057
+ const sandboxSettings = await readSettings(sandboxRoot);
1058
+ await rm(getWorkspaceHistoryPath(sandboxRoot), { force: true });
1059
+ await rm(getSettingsPath(sandboxRoot), { force: true });
1060
+ await writeWorkspaceJsonWithHistory({
1061
+ pmRoot: sandboxRoot,
1062
+ filePath: getSettingsPath(sandboxRoot),
1063
+ raw: sourceSettingsRaw,
1064
+ op: "settings:write",
1065
+ author: resolveAuthor(undefined, sandboxSettings.author_default),
1066
+ lockTtlSeconds: sandboxSettings.locks.ttl_seconds,
1067
+ lockWaitMs: sandboxSettings.locks.wait_ms,
1068
+ recordCreation: true,
1069
+ message: "Seed linked-test tracker settings history",
1070
+ });
1071
+ }
1046
1072
  async function countLinkedTestItemFiles(pmRoot) {
1047
1073
  if (!(await pathExists(pmRoot))) {
1048
1074
  return 0;
@@ -1339,6 +1365,8 @@ async function seedLinkedTestSandboxesFromSource(layout, sourceRoots, includeTra
1339
1365
  await seedLinkedTestSandbox(layout.trackerProjectPmPath, layout.trackerGlobalPmPath, sourceRoots);
1340
1366
  await seedLinkedTestTrackerData(sourceRoots.projectPmRoot, layout.trackerProjectPmPath);
1341
1367
  await seedLinkedTestTrackerData(sourceRoots.globalPmRoot, layout.trackerGlobalPmPath);
1368
+ await seedMissingLinkedTestSettingsHistory(sourceRoots.projectPmRoot, layout.trackerProjectPmPath);
1369
+ await seedMissingLinkedTestSettingsHistory(sourceRoots.globalPmRoot, layout.trackerGlobalPmPath);
1342
1370
  }
1343
1371
  function linkedTestsRequireTrackerData(tests, runLevelPmContextMode, options) {
1344
1372
  return tests.some((linkedTest) => {
@@ -2124,6 +2152,7 @@ export const _testOnlyTestCommand = {
2124
2152
  resolveTestRunOptions,
2125
2153
  resolveTrackedRunId,
2126
2154
  runLinkedTestCommand,
2155
+ seedMissingLinkedTestSettingsHistory,
2127
2156
  seedLinkedTestSandbox,
2128
2157
  seedLinkedTestTrackerData,
2129
2158
  segmentInvokesRecursiveTestAll,
@@ -2131,4 +2160,4 @@ export const _testOnlyTestCommand = {
2131
2160
  summarizeRunResultStatuses,
2132
2161
  };
2133
2162
  //# sourceMappingURL=execution.js.map
2134
- //# debugId=7659721c-21f5-55da-8cce-31b290de5bfb
2163
+ //# debugId=99ce92bb-ed45-5327-b148-b5bb26a0bf05
@@ -80,11 +80,13 @@ All new history fields are optional. Readers must accept:
80
80
  - explicit `model: null`, `effort: null`, or `role: null` observations meaning
81
81
  the dimension was declared but unavailable for a detected harness.
82
82
 
83
- MCP clients may supply a bounded `clientInfo.provenance` map during initialize.
83
+ Modern MCP clients may supply a bounded
84
+ `io.modelcontextprotocol/clientInfo.provenance` map in each request's `_meta`.
84
85
  The server retains only valid dimension names and trimmed values, then resolves
85
- that map inside the invocation-scoped identity context for every mutation. A
86
- missing MCP signal is recorded as explicit `null`; it is never confused with a
87
- legacy entry that predates the dimension.
86
+ that map inside the invocation-scoped identity context for that request. The
87
+ bounded `2025-06-18` adapter accepts the same map during legacy `initialize`.
88
+ A missing MCP signal is recorded as explicit `null`; it is never confused with
89
+ a legacy entry that predates the dimension.
88
90
 
89
91
  Unknown provenance dimensions are preserved as data and do not change author
90
92
  resolution. Removing a dimension from a descriptor never rewrites existing
@@ -156,11 +156,12 @@ author literals at read time; every row reports `harness_source` and
156
156
  `vocabulary_version`, and unresolved literals remain visible in the bounded
157
157
  summary. No history entry is rewritten.
158
158
 
159
- MCP captures `clientInfo.name` and `clientInfo.version` during initialize and
160
- scopes all later tool calls to that client signal. Optional host-provided
161
- `model`, `session`, `provenance`, and `episode` fields are supported, but
162
- version is not
163
- misclassified as a model or session. Provenance keys must use the bounded
159
+ MCP 2026-07-28 reads `io.modelcontextprotocol/clientInfo` independently from
160
+ every request's `_meta` and scopes only that request to the client signal. The
161
+ bounded legacy adapter still reads `clientInfo` during `2025-06-18`
162
+ `initialize`. Optional host-provided `model`, `session`, `provenance`, and
163
+ `episode` fields are supported, but version is not misclassified as a model or
164
+ session. Provenance keys must use the bounded
164
165
  lowercase dimension vocabulary; blank, malformed, and oversized data is
165
166
  discarded before mutation context is created. See
166
167
  [Agent Provenance ADR Amendment](AGENT_PROVENANCE_ADR.md) for precedence,