@absolutejs/mcp 0.17.6 → 0.17.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,12 @@ This file is generated by `absolute-changelog` from the entries in
6
6
  `changelog/`. Edit an entry, not this file — and add new ones under
7
7
  `changelog/unreleased/`.
8
8
 
9
+ ## 0.17.7 — 2026-09-12
10
+
11
+ ### Added
12
+
13
+ - **Ship a synthetic external-checkout host canary with expiring links, explicit approval and purchase-status checks**
14
+
9
15
  ## 0.17.6 — 2026-09-11
10
16
 
11
17
  ### Added
@@ -0,0 +1,198 @@
1
+ /** Synthetic external-checkout fixture. No accounts, card inputs or gateway. */
2
+ import {
3
+ createCheckoutHandoffTool,
4
+ createMcpHandler,
5
+ createPurchaseStatusTool,
6
+ } from "@absolutejs/mcp";
7
+
8
+ export function createCheckoutCanary(origin: string, now = () => Date.now()) {
9
+ const publicUrl = new URL(origin);
10
+ if (publicUrl.protocol !== "https:" || publicUrl.origin !== origin)
11
+ throw Error("Provide an exact HTTPS checkout origin");
12
+ const purchases = new Map<
13
+ string,
14
+ { token: string; expires: number; approved: boolean }
15
+ >();
16
+ const started = now();
17
+ const checkout = createCheckoutHandoffTool({
18
+ origin,
19
+ issue: async (productId) => {
20
+ if (productId !== "synthetic-1000")
21
+ throw Error("Only synthetic-1000 is supported");
22
+ if (purchases.size >= 100)
23
+ throw Error("Restart the canary before creating more fixtures");
24
+ const purchaseId = crypto.randomUUID();
25
+ const token = crypto.randomUUID();
26
+ const expires = now() + 15 * 60_000;
27
+ purchases.set(purchaseId, { token, expires, approved: false });
28
+ return {
29
+ purchaseId,
30
+ url: `${origin}/checkout#${purchaseId}/${token}`,
31
+ expiresAt: new Date(expires).toISOString(),
32
+ };
33
+ },
34
+ });
35
+ const status = createPurchaseStatusTool({
36
+ read: async (purchaseId) => {
37
+ const purchase = purchases.get(purchaseId);
38
+ return purchase
39
+ ? {
40
+ purchaseId,
41
+ status: purchase.approved ? "approved" : "not_started",
42
+ creditsGranted: purchase.approved ? 1000 : 0,
43
+ }
44
+ : null;
45
+ },
46
+ });
47
+ const handler = createMcpHandler({
48
+ issuer: "http://127.0.0.1:4428",
49
+ path: "/mcp",
50
+ serverInfo: { name: "absolute-checkout-canary", version: "1" },
51
+ authorize: async () => ({
52
+ ok: true,
53
+ caller: "synthetic-fixture",
54
+ scopes: [],
55
+ }),
56
+ // This review authorizes only this synthetic developer fixture. Never reuse
57
+ // it for a real merchant or infer a commerce binding from clientInfo.
58
+ commerce: () => ({
59
+ profiles: ["direct-mcp"],
60
+ capabilities: { externalLinks: true },
61
+ reviews: [
62
+ {
63
+ id: "operator-synthetic-checkout-canary",
64
+ profile: "direct-mcp",
65
+ actions: ["external_checkout"],
66
+ categories: ["usage_credits"],
67
+ reviewedAt: new Date(started).toISOString(),
68
+ expiresAt: new Date(started + 60 * 60_000).toISOString(),
69
+ sourceUrls: ["https://code.visualstudio.com/license"],
70
+ },
71
+ ],
72
+ }),
73
+ tools: () => ({
74
+ prepare_test_checkout: {
75
+ ...checkout,
76
+ description: `SYNTHETIC TEST ONLY. Use productId synthetic-1000. ${checkout.description}`,
77
+ },
78
+ get_test_purchase_status: status,
79
+ }),
80
+ });
81
+ const headers = {
82
+ "content-type": "text/html; charset=utf-8",
83
+ "cache-control": "no-store",
84
+ "referrer-policy": "no-referrer",
85
+ "x-content-type-options": "nosniff",
86
+ "content-security-policy":
87
+ "default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; connect-src 'self'; base-uri 'none'; frame-ancestors 'none'; form-action 'none'",
88
+ };
89
+ const page = `<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width"><title>MCP checkout test</title><style>:root{color-scheme:light dark;font:18px system-ui}body{max-width:40rem;margin:10vh auto;padding:2rem}button{padding:1rem;font:inherit}strong{display:block;margin:1rem 0}</style><h1>MCP checkout test</h1><p>Synthetic developer fixture. No real payment, card information, account or subscription.</p><strong>1,000 simulated credits · $0 charged</strong><p id="status" role="status">Checking test link…</p><button id="approve" disabled>Simulate approval</button><script>
90
+ const capability=location.hash.slice(1);history.replaceState(null,'','/checkout');const status=document.getElementById('status'),button=document.getElementById('approve');
91
+ async function update(action){button.disabled=true;try{const r=await fetch('/state',{method:'POST',headers:{'content-type':'application/json'},body:JSON.stringify({capability,action})});if(!r.ok)throw Error('This test link is invalid or expired.');const value=await r.json();status.textContent=value.approved?'Approved — 1,000 simulated credits. Return to your assistant and check purchase status.':'Ready. Opening this page has not approved anything.';button.hidden=value.approved;button.disabled=value.approved;}catch(e){status.textContent=e.message;}}
92
+ button.addEventListener('click',()=>update('approve'));update('read');</script></html>`;
93
+ return {
94
+ mcp: handler,
95
+ checkout: async (request: Request): Promise<Response> => {
96
+ const url = new URL(request.url);
97
+ if (url.pathname === "/checkout" && request.method === "GET")
98
+ return new Response(page, { headers });
99
+ if (url.pathname !== "/state" || request.method !== "POST")
100
+ return new Response("Not found", { status: 404 });
101
+ if (
102
+ request.headers.get("origin") !== origin ||
103
+ !request.headers.get("content-type")?.startsWith("application/json")
104
+ )
105
+ return new Response("Forbidden", { status: 403 });
106
+ const raw = await request.text();
107
+ if (raw.length > 1024) return new Response("Too large", { status: 413 });
108
+ let input;
109
+ try {
110
+ input = JSON.parse(raw);
111
+ } catch {
112
+ return new Response("Invalid JSON", { status: 400 });
113
+ }
114
+ if (
115
+ !input ||
116
+ typeof input.capability !== "string" ||
117
+ !["read", "approve"].includes(input.action)
118
+ )
119
+ return new Response("Invalid request", { status: 400 });
120
+ const [id, token, extra] = input.capability.split("/");
121
+ const purchase = purchases.get(id);
122
+ if (
123
+ extra !== undefined ||
124
+ !purchase ||
125
+ purchase.token !== token ||
126
+ purchase.expires <= now()
127
+ )
128
+ return new Response("Invalid or expired test link", { status: 404 });
129
+ if (input.action === "approve") purchase.approved = true;
130
+ return Response.json(
131
+ { approved: purchase.approved },
132
+ { headers: { "cache-control": "no-store" } },
133
+ );
134
+ },
135
+ };
136
+ }
137
+
138
+ if (import.meta.main) {
139
+ const fixture = createCheckoutCanary(
140
+ process.env.CANARY_CHECKOUT_ORIGIN ?? "",
141
+ );
142
+ Bun.serve({
143
+ hostname: "127.0.0.1",
144
+ port: 4438,
145
+ fetch: async (request) => {
146
+ const response = await fixture.checkout(request);
147
+ const path = new URL(request.url).pathname;
148
+ console.log(
149
+ JSON.stringify({
150
+ surface: "checkout",
151
+ method: request.method,
152
+ route: path === "/checkout" || path === "/state" ? path : "unknown",
153
+ status: response.status,
154
+ }),
155
+ );
156
+ return response;
157
+ },
158
+ });
159
+ Bun.serve({
160
+ hostname: "127.0.0.1",
161
+ port: 4428,
162
+ fetch: async (request) => {
163
+ let rpc;
164
+ try {
165
+ if (request.method === "POST") rpc = await request.clone().json();
166
+ } catch {
167
+ /* handler validates */
168
+ }
169
+ const response =
170
+ (await fixture.mcp(request)) ??
171
+ new Response("Not found", { status: 404 });
172
+ // Never log checkout capabilities, arguments, transcripts or auth headers.
173
+ console.log(
174
+ JSON.stringify({
175
+ method: rpc?.method ?? request.method,
176
+ status: response.status,
177
+ ...(rpc?.method === "initialize"
178
+ ? {
179
+ client: rpc.params?.clientInfo?.name,
180
+ version: rpc.params?.clientInfo?.version,
181
+ }
182
+ : {}),
183
+ ...(rpc?.method === "tools/call" ? { tool: rpc.params?.name } : {}),
184
+ }),
185
+ );
186
+ return response;
187
+ },
188
+ });
189
+ console.log(
190
+ JSON.stringify({
191
+ ready: true,
192
+ mcp: "http://127.0.0.1:4428/mcp",
193
+ checkoutPort: 4438,
194
+ synthetic: true,
195
+ payments: false,
196
+ }),
197
+ );
198
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "host": "Visual Studio Code",
3
+ "version": "1.135.0",
4
+ "surface": "native Windows Copilot chat, directly configured loopback MCP",
5
+ "fixture": "canary/checkout.ts",
6
+ "date": "2026-09-12",
7
+ "synthetic": true,
8
+ "realPayments": false,
9
+ "results": {
10
+ "discoversBothTools": true,
11
+ "linkCreationApprovalVisible": true,
12
+ "toolResultReviewVisible": true,
13
+ "clickableMarkdownAnchor": true,
14
+ "nativeAnchorLaunch": "unverified: mouse and keyboard activation did not produce a measured checkout request",
15
+ "windowsHttpsHandlerOpensReturnedUrl": true,
16
+ "nativeChromeCheckoutPage": true,
17
+ "fragmentRemovedAfterLoad": true,
18
+ "beforeBrowserApproval": { "status": "not_started", "creditsGranted": 0 },
19
+ "afterBrowserApproval": { "status": "approved", "creditsGranted": 1000 },
20
+ "repeatedRead": { "status": "approved", "creditsGranted": 1000 }
21
+ },
22
+ "limits": [
23
+ "Native link launch remains a host-canary gate; no one-click end-to-end claim.",
24
+ "Browser state assertions used a second visible Chrome profile after explicit navigation to the returned URL.",
25
+ "No OAuth, real gateway, rich payment UI, real sales approval or marketplace distribution certified.",
26
+ "No checkout capability, purchase ID, card data or account credentials included."
27
+ ]
28
+ }
package/changelog.json CHANGED
@@ -1,161 +1,171 @@
1
1
  {
2
- "contract": 1,
3
- "name": "@absolutejs/mcp",
4
- "releases": [
5
- {
6
- "version": "0.17.6",
7
- "date": "2026-09-11",
8
- "changes": [
9
- {
10
- "kind": "fixed",
11
- "summary": "Use text and structured report results on affected VS Code builds while their upstream webview startup race remains unresolved"
12
- },
13
- {
14
- "kind": "added",
15
- "summary": "Allow verified patched hosts through the version fallback with optional Apps configuration",
16
- "symbols": [
17
- "clientSupportsMcpApps",
18
- "McpAppsConfig"
19
- ]
20
- }
21
- ]
22
- },
23
- {
24
- "version": "0.17.5",
25
- "date": "2026-09-11",
26
- "changes": [
27
- {
28
- "kind": "added",
29
- "summary": "Distribute a verified VS Code webview startup-race source patch and actual-method regression checker, with explicit upstream delivery requirements"
30
- }
31
- ]
32
- },
33
- {
34
- "version": "0.17.4",
35
- "date": "2026-09-11",
36
- "changes": [
37
- {
38
- "kind": "added",
39
- "summary": "Ship an authenticated two-account staging canary for read isolation, credential rejection and session reconnect with private credentials and aggregate-only results"
40
- }
41
- ]
42
- },
43
- {
44
- "version": "0.17.3",
45
- "date": "2026-09-11",
46
- "changes": [
47
- {
48
- "kind": "fixed",
49
- "summary": "Authorize session deletion, recover explicit client initialization after expiry, and preserve typed HTTP failures without replaying tools"
50
- },
51
- {
52
- "kind": "fixed",
53
- "summary": "Accept the standard protocol-header compatibility fallback used by VS Code Copilot and record native report rendering evidence"
54
- }
55
- ]
56
- },
57
- {
58
- "version": "0.17.2",
59
- "date": "2026-09-11",
60
- "changes": [
61
- {
62
- "kind": "added",
63
- "summary": "Record verified Claude web rendering, refresh, pagination and narrow-viewport host canary evidence"
64
- }
65
- ]
66
- },
67
- {
68
- "version": "0.17.1",
69
- "date": "2026-09-11",
70
- "changes": [
71
- {
72
- "kind": "added",
73
- "summary": "Ship a preflight-validated synthetic host canary and record Claude Code and Codex terminal interoperability evidence"
74
- }
75
- ]
76
- },
77
- {
78
- "version": "0.17.0",
79
- "date": "2026-09-11",
80
- "changes": [
81
- {
82
- "kind": "added",
83
- "summary": "Negotiate MCP Apps with persisted capabilities, guarded offline UI resources and reusable SDK-backed billing views"
84
- },
85
- {
86
- "kind": "added",
87
- "summary": "Preserve remote UI metadata in the client and expose immutable PostgreSQL migration entries"
88
- },
89
- {
90
- "kind": "changed",
91
- "summary": "Extend McpClientOptions, McpRemoteTool, createSessionRegistry, McpSessionStore, McpServerConfig, McpTool and McpToolResult with optional Apps capability and metadata fields; existing text-only callers remain supported",
92
- "symbols": [
93
- "McpClientOptions",
94
- "McpRemoteTool",
95
- "createSessionRegistry",
96
- "McpSessionStore",
97
- "McpServerConfig",
98
- "McpTool",
99
- "McpToolResult"
100
- ]
101
- }
102
- ]
103
- },
104
- {
105
- "version": "0.16.0",
106
- "date": "2026-09-11",
107
- "changes": [
108
- {
109
- "kind": "added",
110
- "summary": "Add account-bound billing status, paginated receipts, bounded usage and reviewed billing-management links"
111
- }
112
- ]
113
- },
114
- {
115
- "version": "0.15.1",
116
- "date": "2026-09-11",
117
- "changes": [
118
- {
119
- "kind": "fixed",
120
- "summary": "Build and test before publishing so checkout exports are present in the distributed artifact"
121
- }
122
- ]
123
- },
124
- {
125
- "version": "0.15.0",
126
- "date": "2026-09-11",
127
- "changes": [
128
- {
129
- "kind": "added",
130
- "summary": "Add commerce-classified account-bound checkout handoff and purchase status tools"
131
- }
132
- ]
133
- },
134
- {
135
- "changes": [
136
- {
137
- "kind": "added",
138
- "summary": "Add explicit credit-budget envelopes for durable prepaid MCP work"
139
- }
140
- ],
141
- "date": "2026-09-11",
142
- "version": "0.14.0"
143
- },
144
- {
145
- "changes": [
146
- {
147
- "kind": "added",
148
- "summary": "Add reviewed host commerce eligibility, execution guards, and reusable credit status tools",
149
- "symbols": [
150
- "McpServerConfig",
151
- "McpTool",
152
- "evaluateCommerce",
153
- "createCreditBalanceTool"
154
- ]
155
- }
156
- ],
157
- "date": "2026-09-11",
158
- "version": "0.13.0"
159
- }
160
- ]
2
+ "contract": 1,
3
+ "name": "@absolutejs/mcp",
4
+ "releases": [
5
+ {
6
+ "changes": [
7
+ {
8
+ "kind": "added",
9
+ "summary": "Ship a synthetic external-checkout host canary with expiring links, explicit approval and purchase-status checks"
10
+ }
11
+ ],
12
+ "date": "2026-09-12",
13
+ "version": "0.17.7"
14
+ },
15
+ {
16
+ "changes": [
17
+ {
18
+ "kind": "fixed",
19
+ "summary": "Use text and structured report results on affected VS Code builds while their upstream webview startup race remains unresolved"
20
+ },
21
+ {
22
+ "kind": "added",
23
+ "summary": "Allow verified patched hosts through the version fallback with optional Apps configuration",
24
+ "symbols": [
25
+ "clientSupportsMcpApps",
26
+ "McpAppsConfig"
27
+ ]
28
+ }
29
+ ],
30
+ "date": "2026-09-11",
31
+ "version": "0.17.6"
32
+ },
33
+ {
34
+ "changes": [
35
+ {
36
+ "kind": "added",
37
+ "summary": "Distribute a verified VS Code webview startup-race source patch and actual-method regression checker, with explicit upstream delivery requirements"
38
+ }
39
+ ],
40
+ "date": "2026-09-11",
41
+ "version": "0.17.5"
42
+ },
43
+ {
44
+ "changes": [
45
+ {
46
+ "kind": "added",
47
+ "summary": "Ship an authenticated two-account staging canary for read isolation, credential rejection and session reconnect with private credentials and aggregate-only results"
48
+ }
49
+ ],
50
+ "date": "2026-09-11",
51
+ "version": "0.17.4"
52
+ },
53
+ {
54
+ "changes": [
55
+ {
56
+ "kind": "fixed",
57
+ "summary": "Authorize session deletion, recover explicit client initialization after expiry, and preserve typed HTTP failures without replaying tools"
58
+ },
59
+ {
60
+ "kind": "fixed",
61
+ "summary": "Accept the standard protocol-header compatibility fallback used by VS Code Copilot and record native report rendering evidence"
62
+ }
63
+ ],
64
+ "date": "2026-09-11",
65
+ "version": "0.17.3"
66
+ },
67
+ {
68
+ "changes": [
69
+ {
70
+ "kind": "added",
71
+ "summary": "Record verified Claude web rendering, refresh, pagination and narrow-viewport host canary evidence"
72
+ }
73
+ ],
74
+ "date": "2026-09-11",
75
+ "version": "0.17.2"
76
+ },
77
+ {
78
+ "changes": [
79
+ {
80
+ "kind": "added",
81
+ "summary": "Ship a preflight-validated synthetic host canary and record Claude Code and Codex terminal interoperability evidence"
82
+ }
83
+ ],
84
+ "date": "2026-09-11",
85
+ "version": "0.17.1"
86
+ },
87
+ {
88
+ "changes": [
89
+ {
90
+ "kind": "added",
91
+ "summary": "Negotiate MCP Apps with persisted capabilities, guarded offline UI resources and reusable SDK-backed billing views"
92
+ },
93
+ {
94
+ "kind": "added",
95
+ "summary": "Preserve remote UI metadata in the client and expose immutable PostgreSQL migration entries"
96
+ },
97
+ {
98
+ "kind": "changed",
99
+ "summary": "Extend McpClientOptions, McpRemoteTool, createSessionRegistry, McpSessionStore, McpServerConfig, McpTool and McpToolResult with optional Apps capability and metadata fields; existing text-only callers remain supported",
100
+ "symbols": [
101
+ "McpClientOptions",
102
+ "McpRemoteTool",
103
+ "createSessionRegistry",
104
+ "McpSessionStore",
105
+ "McpServerConfig",
106
+ "McpTool",
107
+ "McpToolResult"
108
+ ]
109
+ }
110
+ ],
111
+ "date": "2026-09-11",
112
+ "version": "0.17.0"
113
+ },
114
+ {
115
+ "changes": [
116
+ {
117
+ "kind": "added",
118
+ "summary": "Add account-bound billing status, paginated receipts, bounded usage and reviewed billing-management links"
119
+ }
120
+ ],
121
+ "date": "2026-09-11",
122
+ "version": "0.16.0"
123
+ },
124
+ {
125
+ "changes": [
126
+ {
127
+ "kind": "fixed",
128
+ "summary": "Build and test before publishing so checkout exports are present in the distributed artifact"
129
+ }
130
+ ],
131
+ "date": "2026-09-11",
132
+ "version": "0.15.1"
133
+ },
134
+ {
135
+ "changes": [
136
+ {
137
+ "kind": "added",
138
+ "summary": "Add commerce-classified account-bound checkout handoff and purchase status tools"
139
+ }
140
+ ],
141
+ "date": "2026-09-11",
142
+ "version": "0.15.0"
143
+ },
144
+ {
145
+ "changes": [
146
+ {
147
+ "kind": "added",
148
+ "summary": "Add explicit credit-budget envelopes for durable prepaid MCP work"
149
+ }
150
+ ],
151
+ "date": "2026-09-11",
152
+ "version": "0.14.0"
153
+ },
154
+ {
155
+ "changes": [
156
+ {
157
+ "kind": "added",
158
+ "summary": "Add reviewed host commerce eligibility, execution guards, and reusable credit status tools",
159
+ "symbols": [
160
+ "McpServerConfig",
161
+ "McpTool",
162
+ "evaluateCommerce",
163
+ "createCreditBalanceTool"
164
+ ]
165
+ }
166
+ ],
167
+ "date": "2026-09-11",
168
+ "version": "0.13.0"
169
+ }
170
+ ]
161
171
  }
@@ -264,3 +264,16 @@ The first slice exports `evaluateCommerce` through `@absolutejs/mcp/commerce`, a
264
264
  The bundled rules cover the explicit restrictions established above; the broad host inventory currently maps to reviewed direct/self-hosted or unknown profiles rather than claiming every host has been verified. Missing policy, malformed categories, ambiguous restrictions, expired reviews and unavailable capabilities block the action. Deployment reviews cannot override bundled restrictions.
265
265
 
266
266
  This slice is not a general content filter: prompts, resources, untagged tools and arbitrary returned links require the shared evaluator at their own presentation boundaries. Shared renderers, native capability plumbing, checkout sessions, prepaid accounting changes and live cross-host conformance remain to implement. Existing Agency enforcement remains independent.
267
+
268
+ ## September 12 follow-up: native VS Code developer checkout test
269
+
270
+ The directly configured VS Code/Copilot channel now has a package-owned
271
+ [synthetic checkout canary](host-canaries.md#synthetic-external-checkout-canary).
272
+ This is an application development test within VS Code license §1, with no real
273
+ merchant, card input, funds or credits. It does not change the `direct-mcp`
274
+ production default, approve Marketplace distribution, or establish permission
275
+ for live sales under every Copilot agreement. Check the actual account's terms:
276
+ individual Copilot uses GitHub ToS §J; volume licensing has separate current
277
+ Generative AI Services Terms. The old Copilot product-specific terms are archived.
278
+ The linked canary record preserves the exact native host result independently
279
+ of commercial eligibility. Existing Claude and ChatGPT restrictions still apply.
@@ -103,3 +103,62 @@ MCP 0.17.5 includes `canary/vscode/README.md`, a VS Code source patch and an exe
103
103
  The issue is tracked in [microsoft/vscode#335908](https://github.com/microsoft/vscode/issues/335908). Known affected versions now receive text and structured reports on new sessions, keeping tools usable without invoking the faulty webview path. Other hosts retain their negotiated presentation. See [UPSTREAM_ISSUES.md](../UPSTREAM_ISSUES.md) for scope and removal conditions. This workaround does not certify rich rendering on affected editors.
104
104
 
105
105
  Native Windows VS Code 1.135.0 verification: after removing the in-memory editor patch, reconnecting alone left cached UI metadata and produced resource errors. Running **MCP: Reset Cached Tools**, reloading the window and opening a new chat cleared it. The final run returned all three reports as visible text, with three successful tool calls, no resource reads and no App frames. This is a verified text fallback, not rich rendering evidence.
106
+
107
+ ## Synthetic external-checkout canary
108
+
109
+ `bun run canary:checkout` (installed: `bun node_modules/@absolutejs/mcp/canary/checkout.ts`)
110
+ uses the package's real checkout handoff and purchase-status tools with in-memory
111
+ synthetic purchases. Set `CANARY_CHECKOUT_ORIGIN` to the exact HTTPS origin of a
112
+ temporary reverse proxy to loopback port 4438. Connect the desktop test host only
113
+ to `http://127.0.0.1:4428/mcp`. Expose only port 4438 through the proxy; it serves
114
+ only the fixture page/state routes, never MCP. Stop both processes after testing.
115
+ No account database, payment provider, card input or real credit ledger is used.
116
+ Do not mount either handler in a customer application.
117
+
118
+ This is an operator-authorized development test, not a live commerce approval.
119
+ The fixture's one-hour, server-owned review applies only to synthetic links;
120
+ never copy it into a production commerce binding. VS Code's [license §1](https://code.visualstudio.com/license)
121
+ permits application development/testing. GitHub's [additional product terms](https://docs.github.com/en/site-policy/github-terms/github-terms-for-additional-products-and-features#github-copilot)
122
+ point individual Copilot users to ToS §J and business users to their applicable
123
+ agreement. The older Copilot product terms are archived; current volume purchases
124
+ may instead use the [March 2026 Generative AI Services Terms](https://github.com/customer-terms/github-generative-ai-services-terms).
125
+ Do not treat an old agreement, another product's marketplace rules, or this
126
+ technical test as approval for every Copilot account or live digital sales.
127
+
128
+ 1. Request `prepare_test_checkout` with `productId: "synthetic-1000"` and approve
129
+ the host's tool prompt if shown. Ask for a clickable link and a
130
+ `get_test_purchase_status` read using the returned `purchaseId`.
131
+ 2. Confirm status is `not_started`, with zero granted credits. Click the link
132
+ using the host's ordinary external-link UI. The HTTPS page must clearly say
133
+ synthetic test, show no card fields, and require **Simulate approval**.
134
+ 3. Before clicking that button, read status again: still zero. Click once, then
135
+ return to chat and request status again: approved, 1,000 simulated credits.
136
+ 4. Repeat the read: still 1,000. Never let the agent approve the browser step on
137
+ behalf of a paying customer. This operator test contains no real payment.
138
+
139
+ Links expire after 15 minutes. Capabilities travel in a URL fragment, are removed
140
+ from the address bar on load, and are submitted only to the same checkout origin.
141
+ Refreshing after removal intentionally requires reopening the original link.
142
+ The fixture is bounded to 100 purchases per run. Its aggregate log excludes
143
+ capabilities and tool arguments; keep full host transcripts private. Record the
144
+ actual link UI, approval UI, browser navigation, before/after tool results and
145
+ host version. This does not certify real merchant approval, OAuth continuity,
146
+ 3DS, or rich embedded payment support.
147
+
148
+ ### September 12 VS Code checkout observation
149
+
150
+ Native Windows VS Code 1.135.0/Copilot discovered both tools, displayed link-creation
151
+ and result-review prompts, and rendered the returned HTTPS URL as a Markdown
152
+ anchor. Native Chrome showed the fixture page with its fragment removed. Copilot
153
+ reported `not_started`/0 after the browser opened, then `approved`/1000 after the
154
+ operator's simulated approval, including a second unchanged status read.
155
+
156
+ **Qualified result:** mouse/keyboard activation of the Copilot anchor did not
157
+ produce a measured checkout request in the final navigation probe. Opening the
158
+ returned URL through the Windows HTTPS handler worked in the default Chrome
159
+ profile. Browser state assertions used explicit navigation in a separate visible
160
+ Chrome profile. These are separate observations: native one-click chat-to-browser
161
+ launch is still unverified. No upstream cause has been established. Use the
162
+ returned URL manually during development; do not advertise the seamless host
163
+ handoff as passed. See `canary/results/vscode-checkout-2026-09-12.json` for aggregate
164
+ evidence. No host/source patch or browser-default change was applied.
package/package.json CHANGED
@@ -85,8 +85,9 @@
85
85
  "prepublishOnly": "bun run check:package",
86
86
  "build:apps": "bun scripts/build-apps.ts",
87
87
  "canary": "bun canary/server.ts",
88
- "check:canary": "tsc --noEmit --strict --skipLibCheck --moduleResolution bundler --module esnext --target esnext --types bun canary/server.ts canary/authenticated.ts canary/vscode/check-mount.ts"
88
+ "check:canary": "tsc --noEmit --strict --skipLibCheck --moduleResolution bundler --module esnext --target esnext --types bun canary/server.ts canary/authenticated.ts canary/vscode/check-mount.ts canary/checkout.ts",
89
+ "canary:checkout": "bun canary/checkout.ts"
89
90
  },
90
91
  "types": "./dist/src/index.d.ts",
91
- "version": "0.17.6"
92
+ "version": "0.17.7"
92
93
  }