@impetik/xeer-mcp 0.2.17 → 0.2.19
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/package.json +2 -2
- package/vendor/spec/actions.d.ts +5 -5
- package/vendor/spec/actions.js +11 -6
- package/vendor/spec/admin.d.ts +7 -5
- package/vendor/spec/admin.js +7 -21
- package/vendor/spec/diagnostics.js +77 -26
- package/vendor/spec/import-policy.d.ts +38 -11
- package/vendor/spec/import-policy.js +30 -8
- package/vendor/spec/index.d.ts +1 -0
- package/vendor/spec/index.js +1 -0
- package/vendor/spec/local-identity.d.ts +83 -8
- package/vendor/spec/local-identity.js +135 -11
- package/vendor/spec/page-cursor.d.ts +26 -0
- package/vendor/spec/page-cursor.js +45 -0
- package/vendor/spec/review.js +2 -0
- package/vendor/spec/route.d.ts +13 -0
- package/vendor/spec/route.js +33 -0
- package/vendor/spec/schema-lifecycle.d.ts +10 -4
- package/vendor/spec/schema-lifecycle.js +32 -4
- package/vendor/spec/schema-plan.d.ts +10 -1
- package/vendor/spec/schema-plan.js +22 -3
- package/vendor/spec/schema.d.ts +9 -0
- package/vendor/spec/schema.js +20 -0
- package/vendor/spec/state-export.d.ts +22 -0
- package/vendor/spec/state-export.js +42 -2
- package/vendor/spec/tunnel.d.ts +3 -0
- package/vendor/spec/tunnel.js +18 -0
- package/vendor/spec/type-check-profile.d.ts +67 -0
- package/vendor/spec/type-check-profile.js +78 -0
- package/vendor/spec/types.d.ts +75 -5
- package/vendor/spec/types.js +10 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@impetik/xeer-mcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.19",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Model Context Protocol server for Xeer: the scaffold, check, dev, build, and deploy loop as agent tools.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
49
49
|
"zod": "^4.0.10",
|
|
50
|
-
"@impetik/xeer": "0.2.
|
|
50
|
+
"@impetik/xeer": "0.2.19"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@types/node": "^24.1.0"
|
package/vendor/spec/actions.d.ts
CHANGED
|
@@ -481,7 +481,7 @@ declare const actions: readonly [{
|
|
|
481
481
|
readonly command: readonly ["inspect"];
|
|
482
482
|
readonly summary: "Read a running application manifest.";
|
|
483
483
|
readonly description: string;
|
|
484
|
-
readonly usage: readonly ["inspect <local-url|app> [--environment prod|preview] [--control-url <url>] [--json]"];
|
|
484
|
+
readonly usage: readonly ["inspect <local-url|app|directory> [--environment prod|preview] [--control-url <url>] [--json]"];
|
|
485
485
|
readonly helpOrder: 230;
|
|
486
486
|
readonly outputProtocol: "xeer.command.v0";
|
|
487
487
|
readonly effects: readonly ["network-read", "read-state"];
|
|
@@ -874,7 +874,7 @@ declare const actions: readonly [{
|
|
|
874
874
|
readonly id: "preview";
|
|
875
875
|
readonly command: readonly ["preview"];
|
|
876
876
|
readonly summary: "Run a verified artifact in a local preview server.";
|
|
877
|
-
readonly usage: readonly ["preview [directory] [--host <host>] [--port <port>] [--json]"];
|
|
877
|
+
readonly usage: readonly ["preview [directory] [--host <host>] [--port <port>] [--force] [--json]"];
|
|
878
878
|
readonly helpOrder: 240;
|
|
879
879
|
readonly outputProtocol: "xeer.dev.v0";
|
|
880
880
|
readonly effects: readonly ["read-source", "write-generated", "run-local", "write-state"];
|
|
@@ -892,7 +892,7 @@ declare const actions: readonly [{
|
|
|
892
892
|
readonly command: readonly ["state"];
|
|
893
893
|
readonly summary: "Read record counts from a running application.";
|
|
894
894
|
readonly description: string;
|
|
895
|
-
readonly usage: readonly ["state <local-url|app> [--environment prod|preview] [--control-url <url>] [--json]"];
|
|
895
|
+
readonly usage: readonly ["state <local-url|app|directory> [--environment prod|preview] [--control-url <url>] [--json]"];
|
|
896
896
|
readonly helpOrder: 260;
|
|
897
897
|
readonly outputProtocol: "xeer.command.v0";
|
|
898
898
|
readonly effects: readonly ["network-read", "read-state"];
|
|
@@ -927,7 +927,7 @@ declare const actions: readonly [{
|
|
|
927
927
|
readonly command: readonly ["logs"];
|
|
928
928
|
readonly summary: "Read the bounded log ring of a running application.";
|
|
929
929
|
readonly description: string;
|
|
930
|
-
readonly usage: readonly ["logs <local-url|app> [--environment prod|preview] [--after <cursor>] [--control-url <url>] [--json]"];
|
|
930
|
+
readonly usage: readonly ["logs <local-url|app|directory> [--environment prod|preview] [--after <cursor>] [--control-url <url>] [--json]"];
|
|
931
931
|
readonly helpOrder: 280;
|
|
932
932
|
readonly outputProtocol: "xeer.command.v0";
|
|
933
933
|
readonly effects: readonly ["network-read", "read-state"];
|
|
@@ -1014,7 +1014,7 @@ declare const actions: readonly [{
|
|
|
1014
1014
|
readonly id: "auth.as";
|
|
1015
1015
|
readonly command: readonly ["auth", "as"];
|
|
1016
1016
|
readonly summary: "Select a deterministic local development persona.";
|
|
1017
|
-
readonly usage: readonly ["auth as <alice|bob> [directory] [--workspace <id>]... [--json]"];
|
|
1017
|
+
readonly usage: readonly ["auth as <alice|bob|carol> [directory] [--workspace <id>]... [--role <name>]... [--permission <name>]... [--json]"];
|
|
1018
1018
|
readonly helpOrder: 200;
|
|
1019
1019
|
readonly outputProtocol: "xeer.command.v0";
|
|
1020
1020
|
readonly effects: readonly ["write-state"];
|
package/vendor/spec/actions.js
CHANGED
|
@@ -75,7 +75,9 @@ const MCP_PRESENTATION = {
|
|
|
75
75
|
'Each failed case carries a Diagnostic-shaped failure with matcher, expected, actual, and the',
|
|
76
76
|
'project-relative test location: XE1904 assertion, XE1905 threw or unexpectedly refused call,',
|
|
77
77
|
'XE1906 timeout. Compiler diagnostics abort the run before any test boots.',
|
|
78
|
-
'Tests call as(\'alice\'|\'bob\'|\'guest\'),
|
|
78
|
+
'Tests call as(\'alice\'|\'bob\'|\'carol\'|\'guest\'), optionally with { workspaceIds, roles, permissions },',
|
|
79
|
+
'so ownership and authorization are directly testable. A persona holding none of the three is',
|
|
80
|
+
'kind: "guest" and authenticated() refuses it.',
|
|
79
81
|
].join(' '),
|
|
80
82
|
},
|
|
81
83
|
new: {
|
|
@@ -340,7 +342,8 @@ const actions = [
|
|
|
340
342
|
description: 'Reads a local dev or preview URL directly. For a deployed application, Xeer uses the '
|
|
341
343
|
+ 'signed-in builder credential and defaults names and app IDs to production; pass an exact URL or '
|
|
342
344
|
+ '--environment preview to select preview.',
|
|
343
|
-
usage: ['inspect <local-url|app> [--environment prod|preview] [--control-url <url>] [--json]'],
|
|
345
|
+
usage: ['inspect <local-url|app|directory> [--environment prod|preview] [--control-url <url>] [--json]'],
|
|
346
|
+
helpOrder: 230,
|
|
344
347
|
outputProtocol: 'xeer.command.v0', effects: ['network-read', 'read-state'], idempotent: true,
|
|
345
348
|
reversible: true, destructive: false, humanPrerequisites: [], pathPolicy: 'app-or-url',
|
|
346
349
|
surfaces: {
|
|
@@ -531,7 +534,7 @@ const actions = [
|
|
|
531
534
|
},
|
|
532
535
|
{
|
|
533
536
|
id: 'preview', command: ['preview'], summary: 'Run a verified artifact in a local preview server.',
|
|
534
|
-
usage: ['preview [directory] [--host <host>] [--port <port>] [--json]'], helpOrder: 240,
|
|
537
|
+
usage: ['preview [directory] [--host <host>] [--port <port>] [--force] [--json]'], helpOrder: 240,
|
|
535
538
|
outputProtocol: 'xeer.dev.v0', effects: ['read-source', 'write-generated', 'run-local', 'write-state'],
|
|
536
539
|
idempotent: false, reversible: true, destructive: false, humanPrerequisites: [],
|
|
537
540
|
pathPolicy: 'project-relative', surfaces: { cli: true, mcpExclusion: NOT_EXPOSED_V0 },
|
|
@@ -541,7 +544,8 @@ const actions = [
|
|
|
541
544
|
description: 'Reads a local dev or preview URL directly. For a deployed application, Xeer uses the '
|
|
542
545
|
+ 'signed-in builder credential and defaults names and app IDs to production; pass an exact URL or '
|
|
543
546
|
+ '--environment preview to select preview.',
|
|
544
|
-
usage: ['state <local-url|app> [--environment prod|preview] [--control-url <url>] [--json]'],
|
|
547
|
+
usage: ['state <local-url|app|directory> [--environment prod|preview] [--control-url <url>] [--json]'],
|
|
548
|
+
helpOrder: 260,
|
|
545
549
|
outputProtocol: 'xeer.command.v0', effects: ['network-read', 'read-state'], idempotent: true,
|
|
546
550
|
reversible: true, destructive: false, humanPrerequisites: [], pathPolicy: 'app-or-url',
|
|
547
551
|
surfaces: { cli: true, mcpExclusion: NOT_EXPOSED_V0 },
|
|
@@ -559,7 +563,7 @@ const actions = [
|
|
|
559
563
|
description: 'Reads a local dev or preview URL directly. For a deployed application, Xeer uses the '
|
|
560
564
|
+ 'signed-in builder credential and defaults names and app IDs to production; pass an exact URL or '
|
|
561
565
|
+ '--environment preview to select preview.',
|
|
562
|
-
usage: ['logs <local-url|app> [--environment prod|preview] [--after <cursor>] [--control-url <url>] [--json]'],
|
|
566
|
+
usage: ['logs <local-url|app|directory> [--environment prod|preview] [--after <cursor>] [--control-url <url>] [--json]'],
|
|
563
567
|
helpOrder: 280, outputProtocol: 'xeer.command.v0', effects: ['network-read', 'read-state'],
|
|
564
568
|
idempotent: true, reversible: true, destructive: false, humanPrerequisites: [], pathPolicy: 'app-or-url',
|
|
565
569
|
surfaces: { cli: true, mcpExclusion: NOT_EXPOSED_V0 },
|
|
@@ -607,7 +611,8 @@ const actions = [
|
|
|
607
611
|
},
|
|
608
612
|
{
|
|
609
613
|
id: 'auth.as', command: ['auth', 'as'], summary: 'Select a deterministic local development persona.',
|
|
610
|
-
usage: ['auth as <alice|bob> [directory] [--workspace <id>]... [--json]'],
|
|
614
|
+
usage: ['auth as <alice|bob|carol> [directory] [--workspace <id>]... [--role <name>]... [--permission <name>]... [--json]'],
|
|
615
|
+
helpOrder: 200,
|
|
611
616
|
outputProtocol: 'xeer.command.v0', effects: ['write-state'], idempotent: true,
|
|
612
617
|
reversible: true, destructive: false, humanPrerequisites: [], pathPolicy: 'project-relative',
|
|
613
618
|
surfaces: { cli: true, mcpExclusion: NOT_EXPOSED_V0 },
|
package/vendor/spec/admin.d.ts
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
* `INSERT OR IGNORE`, so a retried request writes the same id and changes nothing, and the response
|
|
20
20
|
* says whether this call was the one that created it. No request ledger, no dedupe window.
|
|
21
21
|
*/
|
|
22
|
+
import { decodePageCursor, encodePageCursor } from './page-cursor.js';
|
|
22
23
|
import type { EncodedValue } from './value.js';
|
|
23
24
|
export declare const ADMIN_PROTOCOL: "xeer.admin.v0";
|
|
24
25
|
/** Columns the runtime owns on every table. Present in every row, never writable by a client. */
|
|
@@ -101,10 +102,11 @@ export interface AdminWriteResponseV0 {
|
|
|
101
102
|
* A page cursor. Opaque to clients by contract, and deliberately not signed: it names a position in
|
|
102
103
|
* the caller's own data on a surface they already had to authenticate to reach, so there is nothing
|
|
103
104
|
* for a forged one to disclose that the next page would not have shown anyway.
|
|
105
|
+
*
|
|
106
|
+
* The console and `ctx.db.table(…).page(…)` seek the same `(created_at, id)` keyset over the same
|
|
107
|
+
* tables, so they share one codec rather than keeping two that could drift into disagreeing about
|
|
108
|
+
* what a token means. The names stay because the admin protocol names them.
|
|
104
109
|
*/
|
|
105
|
-
export declare
|
|
110
|
+
export declare const encodeAdminCursor: typeof encodePageCursor;
|
|
106
111
|
/** The inverse, or `null` when the text is not a cursor this version wrote. */
|
|
107
|
-
export declare
|
|
108
|
-
createdAt: string;
|
|
109
|
-
id: string;
|
|
110
|
-
} | null;
|
|
112
|
+
export declare const decodeAdminCursor: typeof decodePageCursor;
|
package/vendor/spec/admin.js
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
* `INSERT OR IGNORE`, so a retried request writes the same id and changes nothing, and the response
|
|
20
20
|
* says whether this call was the one that created it. No request ledger, no dedupe window.
|
|
21
21
|
*/
|
|
22
|
+
import { decodePageCursor, encodePageCursor } from './page-cursor.js';
|
|
22
23
|
export const ADMIN_PROTOCOL = 'xeer.admin.v0';
|
|
23
24
|
/** Columns the runtime owns on every table. Present in every row, never writable by a client. */
|
|
24
25
|
export const ADMIN_RUNTIME_FIELDS = Object.freeze([
|
|
@@ -33,26 +34,11 @@ export const ADMIN_PAGE_MAX = 200;
|
|
|
33
34
|
* A page cursor. Opaque to clients by contract, and deliberately not signed: it names a position in
|
|
34
35
|
* the caller's own data on a surface they already had to authenticate to reach, so there is nothing
|
|
35
36
|
* for a forged one to disclose that the next page would not have shown anyway.
|
|
37
|
+
*
|
|
38
|
+
* The console and `ctx.db.table(…).page(…)` seek the same `(created_at, id)` keyset over the same
|
|
39
|
+
* tables, so they share one codec rather than keeping two that could drift into disagreeing about
|
|
40
|
+
* what a token means. The names stay because the admin protocol names them.
|
|
36
41
|
*/
|
|
37
|
-
export
|
|
38
|
-
const text = JSON.stringify([createdAt, id]);
|
|
39
|
-
return btoa(String.fromCharCode(...new TextEncoder().encode(text)))
|
|
40
|
-
.replaceAll('+', '-').replaceAll('/', '_').replaceAll('=', '');
|
|
41
|
-
}
|
|
42
|
+
export const encodeAdminCursor = encodePageCursor;
|
|
42
43
|
/** The inverse, or `null` when the text is not a cursor this version wrote. */
|
|
43
|
-
export
|
|
44
|
-
try {
|
|
45
|
-
const padded = cursor.replaceAll('-', '+').replaceAll('_', '/');
|
|
46
|
-
const bytes = Uint8Array.from(atob(padded + '='.repeat((4 - (padded.length % 4)) % 4)), (c) => c.charCodeAt(0));
|
|
47
|
-
const parsed = JSON.parse(new TextDecoder().decode(bytes));
|
|
48
|
-
if (!Array.isArray(parsed) || parsed.length !== 2)
|
|
49
|
-
return null;
|
|
50
|
-
const [createdAt, id] = parsed;
|
|
51
|
-
if (typeof createdAt !== 'string' || typeof id !== 'string')
|
|
52
|
-
return null;
|
|
53
|
-
return { createdAt, id };
|
|
54
|
-
}
|
|
55
|
-
catch {
|
|
56
|
-
return null;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
44
|
+
export const decodeAdminCursor = decodePageCursor;
|
|
@@ -143,39 +143,61 @@ export const DIAGNOSTIC_DEFINITIONS = [
|
|
|
143
143
|
define('XE1003', 'The manifest carries a property the application-source schema does not define.', 'Remove the property, or fix its spelling. The manifest is closed: unknown keys are never ignored.', CHECKED_BY_EVERY_COMPILE),
|
|
144
144
|
define('XE1101', 'An entrypoint path is absolute or escapes the project root.', 'Use a forward-slash path relative to xeer.app.json that stays inside the project.', CHECKED_BY_EVERY_COMPILE),
|
|
145
145
|
define('XE1201', 'A source import breaks the zone boundary: it is absolute, leaves the project root, '
|
|
146
|
-
+ 'reaches the opposite entrypoint, or
|
|
147
|
-
+ '
|
|
148
|
-
+ 'both
|
|
149
|
-
|
|
150
|
-
+ '
|
|
151
|
-
+ '
|
|
152
|
-
+ '
|
|
153
|
-
|
|
154
|
-
+ '
|
|
155
|
-
+
|
|
156
|
-
+ '
|
|
146
|
+
+ 'reaches the opposite entrypoint, or pulls a module out of the other zone\'s graph. A cross-zone '
|
|
147
|
+
+ 'import is reported at the import that admitted the module, not at the modules it dragged in — '
|
|
148
|
+
+ 'those are correct where they live. A module both graphs reach with no zone-exclusive import '
|
|
149
|
+
+ 'anywhere beneath it names no offending side, and is reported on the module itself.', 'Keep imports relative and inside the project; never import one entrypoint from the other. For a '
|
|
150
|
+
+ 'cross-zone import, delete the import the message points at: move code both zones need to '
|
|
151
|
+
+ 'src/shared/ and import it from there, or expose the data through a query, mutation, or endpoint '
|
|
152
|
+
+ 'and call it from the client. Do not remove the zone imports from the modules it reached.', CHECKED_BY_EVERY_COMPILE),
|
|
153
|
+
define('XE1202', 'A package import violates the zone\'s import policy structurally: a Node builtin '
|
|
154
|
+
+ 'or a native addon (.node) in any zone, a platform subpath the zone does not admit, a '
|
|
155
|
+
+ 'renderer-family entrypoint that is test-only, metadata, or unknown to the selected runtime '
|
|
156
|
+
+ 'source, or a package family the other zone owns — the renderer (preact, react, react-dom, '
|
|
157
|
+
+ 'scheduler) in the server zone. It is not reported for an ordinary npm package in either zone: '
|
|
158
|
+
+ 'both admit any declared and installed dependency.', `The client zone admits ${CLIENT_IMPORT_POLICY.platformModules.join(', ')} and the `
|
|
159
|
+
+ 'platform-managed renderer surface (preact and its supported entrypoints, plus '
|
|
160
|
+
+ 'React-ecosystem imports aliased onto preact/compat); the server zone admits '
|
|
161
|
+
+ `${SERVER_IMPORT_POLICY.platformModules.join(', ')}. Both zones additionally admit any npm `
|
|
162
|
+
+ 'package declared in package.json dependencies and installed. Node builtins and native addons '
|
|
163
|
+
+ 'are never importable anywhere: the client runs in a browser and the server runs in workerd, '
|
|
164
|
+
+ 'neither of which has them — that is a runtime fact, not an allowlist. Move the code to the '
|
|
165
|
+
+ 'zone that owns the import, or use a dependency that targets browsers and workers.', CHECKED_BY_EVERY_COMPILE),
|
|
157
166
|
define('XE1203', 'A dynamic import() specifier is not a string literal.', 'Use a literal specifier so the module graph stays statically knowable, or a static import.', CHECKED_BY_EVERY_COMPILE),
|
|
158
167
|
define('XE1204', 'A relative source import does not resolve to a file.', 'Write the specifier without an extension, or with the file\'s real one: the resolver appends '
|
|
159
168
|
+ 'candidate extensions rather than rewriting them, so ./shared/title.js does not find '
|
|
160
169
|
+ 'shared/title.ts. Directory imports resolve to index.*.', CHECKED_BY_EVERY_COMPILE),
|
|
161
170
|
define('XE1205', 'TypeScript reported an error in a file reachable from an entrypoint. The message '
|
|
162
171
|
+ 'starts with the TS#### code and span points at the exact position.', 'Fix the type error. Operation input and result types come from the generated contract, so a mismatch '
|
|
163
|
-
+ 'between a client call and its server handler surfaces here.'
|
|
172
|
+
+ 'between a client call and its server handler surfaces here. A handler whose result the platform '
|
|
173
|
+
+ 'cannot encode is reported on the handler: declare result shapes with a `type` alias rather than an '
|
|
174
|
+
+ '`interface`, which TypeScript never gives an implicit index signature.', CHECKED_BY_EVERY_COMPILE),
|
|
164
175
|
define('XE1206', 'A stylesheet is imported outside the client graph.', 'Import .css only from client modules; the server bundle has no styling stage.', CHECKED_BY_EVERY_COMPILE),
|
|
165
|
-
define('XE1207', '
|
|
176
|
+
define('XE1207', 'An import names an npm package that package.json does not declare in '
|
|
166
177
|
+ '"dependencies". It may still resolve through hoisting, which is exactly the accident the rule '
|
|
167
|
-
+ 'exists to prevent.
|
|
168
|
-
+ '
|
|
178
|
+
+ 'exists to prevent. Reported in both zones: the message names the zone the import was written '
|
|
179
|
+
+ 'in, but the rule is the same one.', 'Add the package to the application\'s package.json "dependencies" and install it. Either zone '
|
|
180
|
+
+ 'may import any declared and installed npm package; type-only imports may come from '
|
|
169
181
|
+ 'devDependencies instead.', CHECKED_BY_EVERY_COMPILE),
|
|
170
|
-
define('XE1208', '
|
|
171
|
-
+ 'in a reachable node_modules provides it.', 'Run your package manager\'s install (npm install / pnpm install) so the declared dependency is '
|
|
182
|
+
define('XE1208', 'An import names a declared dependency that is not installed: nothing '
|
|
183
|
+
+ 'in a reachable node_modules provides it. Reported in both zones.', 'Run your package manager\'s install (npm install / pnpm install) so the declared dependency is '
|
|
172
184
|
+ 'present on disk, then check again.', CHECKED_BY_EVERY_COMPILE),
|
|
185
|
+
define('XE1209', 'A subresource — an image, a font, or a wasm module — is imported outside the '
|
|
186
|
+
+ 'client graph. The declarations that give such an import a type are program-global, so it '
|
|
187
|
+
+ 'type-checks in every zone, but only the client bundler has a loader that turns one into a URL.', 'Import images, fonts, and wasm only from client modules; the server bundle has no asset stage. '
|
|
188
|
+
+ 'A server handler that needs the bytes should read them from public/ or receive the URL from '
|
|
189
|
+
+ 'the client.', CHECKED_BY_EVERY_COMPILE),
|
|
173
190
|
define('XE1300', 'The default server export is not a statically inspectable defineServer({...}) call, '
|
|
174
191
|
+ 'or an operation group is not a literal object.', 'Export `default defineServer({ queries: {...}, mutations: {...}, endpoints: {...} })` with literal '
|
|
175
192
|
+ 'object members: no spreads, shorthand, computed keys, or wrappers.', CHECKED_BY_EVERY_COMPILE),
|
|
176
193
|
define('XE1301', 'Two operations in the same group share a name.', 'Rename one of them, or delete the duplicate registration if it was a copy-paste.', CHECKED_BY_EVERY_COMPILE),
|
|
177
194
|
define('XE1302', 'An endpoint key is not `METHOD /api/path`.', 'Use an uppercase HTTP method, one space, and a literal /api path; dynamic segments are :name.', CHECKED_BY_EVERY_COMPILE),
|
|
178
|
-
define('XE1303', 'A query or mutation name
|
|
195
|
+
define('XE1303', 'A query or mutation name does not match the operation-name grammar: two or more '
|
|
196
|
+
+ 'dot-separated segments, each starting with a lowercase letter and continuing with lowercase '
|
|
197
|
+
+ 'letters, digits, `_`, or `-`.', 'Write the name as `namespace.name` with no uppercase letter anywhere — uppercase is the '
|
|
198
|
+
+ 'restriction authors do not expect, so `posts.bySlug` is refused even though it is namespaced. '
|
|
199
|
+
+ 'Separate words with `_` or `-` instead: notes.list, notes.list_pinned, notes.by-slug, and '
|
|
200
|
+
+ 'notes.pinned.v2 are all accepted. Formally `^[a-z][a-z0-9_-]*\\.[a-z][a-z0-9_.-]*$`.', CHECKED_BY_EVERY_COMPILE),
|
|
179
201
|
define('XE1304', 'Two endpoints reduce to the same route shape, so dispatch would be ambiguous.', 'Change the method or a static path segment. Parameter names do not distinguish routes: '
|
|
180
202
|
+ 'GET /api/notes/:id and GET /api/notes/:slug are the same route.', CHECKED_BY_EVERY_COMPILE),
|
|
181
203
|
define('XE1401', 'A compiled module (10 MiB) or an asset (25 MiB) exceeds the v0 limit.', 'Shrink the module or asset. There is no flag that raises a v0 limit.', BUILT_BY_EVERY_BUILD),
|
|
@@ -194,12 +216,14 @@ export const DIAGNOSTIC_DEFINITIONS = [
|
|
|
194
216
|
+ 'packages to reconsider before the error tier is reached.', BUILT_BY_EVERY_BUILD),
|
|
195
217
|
define('XE1501', 'Bundling failed after the module graph and types were accepted.', 'Read the bundler message in `message`. It usually names a syntax construct the target does not '
|
|
196
218
|
+ 'support, rather than a Xeer rule.', BUILT_BY_EVERY_BUILD),
|
|
197
|
-
define('XE1502', 'A bundled
|
|
198
|
-
+ '
|
|
199
|
-
+ 'the
|
|
200
|
-
+ '
|
|
201
|
-
+ '
|
|
202
|
-
+ '
|
|
219
|
+
define('XE1502', 'A bundled dependency imports a Node builtin, so the bundle cannot run where its '
|
|
220
|
+
+ 'zone runs — a browser for the client zone, workerd for the server zone. The message names the '
|
|
221
|
+
+ 'zone, the dependency and the builtin; the offending import sits inside the package, not in '
|
|
222
|
+
+ 'application code. The diagnostic is located at the application import that admitted the '
|
|
223
|
+
+ 'package into that zone\'s graph.', 'Use a package targeting browsers and workers, or the package\'s browser/worker entrypoint. '
|
|
224
|
+
+ 'Neither zone has Node builtins to offer, so the platform refuses the bundle rather than '
|
|
225
|
+
+ 'shipping one that throws at load time. This is a property of the dependency chain and so is '
|
|
226
|
+
+ 'found at build, not at check.', BUILT_BY_EVERY_BUILD),
|
|
203
227
|
define('XE1503', 'The client bundle would contain a second physical copy of the managed renderer. '
|
|
204
228
|
+ 'Bare renderer imports are pinned to the platform anchor, so a second copy means a path-based '
|
|
205
229
|
+ 'escape: a relative or absolute import reaching into some node_modules copy of the renderer.', 'Import the renderer by its bare specifier (preact, preact/hooks, react, …) so the platform pins '
|
|
@@ -276,8 +300,10 @@ export const DIAGNOSTIC_DEFINITIONS = [
|
|
|
276
300
|
+ "names: pass it with as({ name, workspaceIds }).", ['test']),
|
|
277
301
|
define('XE1906', 'A test exceeded its 20 second budget. The remaining tests still run.', 'Remove the wait: tests run against a local runtime, so a timeout means an unresolved promise or an '
|
|
278
302
|
+ 'operation that never returns, not a slow machine.', ['test']),
|
|
279
|
-
define('XE2001', 'An inspector command was invoked without a target
|
|
280
|
-
+ '
|
|
303
|
+
define('XE2001', 'An inspector command was invoked without a target, or with a project directory in '
|
|
304
|
+
+ 'which no `xeer dev` or `xeer preview` server is running — or in which both are, so the '
|
|
305
|
+
+ 'directory does not name one of them.', 'Pass a project directory (`.`) to read the local server running for it, the URL from the '
|
|
306
|
+
+ 'dev/preview `preview.ready` event, or a deployed application name, appId, or URL.', ['inspect', 'state']),
|
|
281
307
|
define('XE2002', 'The inspector request itself failed: a local dev/preview inspector that answered '
|
|
282
308
|
+ 'a non-2xx status or no JSON, or a control plane that refused the proxied read, in which case '
|
|
283
309
|
+ 'the read never reached the application. An application that refused the read is XE2004.', 'Confirm the preview is still running and the URL matches the current `preview.ready` event. For a '
|
|
@@ -353,6 +379,11 @@ export const DIAGNOSTIC_DEFINITIONS = [
|
|
|
353
379
|
define('XE5133', 'A closed-beta quota refused the environment-variable request: `xeer env set` claims '
|
|
354
380
|
+ 'the project on first use, so it is capped by the same apps-per-builder quota as `xeer deploy`.', 'Set the value on an app you already own — `xeer link` lists them — or ask the Xeer team to raise the '
|
|
355
381
|
+ 'quota. `message` states the quota, your usage, and any reset.', ['env']),
|
|
382
|
+
define('XE5134', 'A file exists at `.xeer/env.<environment>.local.json` but could not be used '
|
|
383
|
+
+ 'in full: it is not a `xeer.env-local.v0` document, it could not be read, or some of its '
|
|
384
|
+
+ 'entries have names or values a local run cannot load — so `ctx.env` is missing them.', 'Read `message`: it names the file and the exact problem — the shape to write is '
|
|
385
|
+
+ '{"format": "xeer.env-local.v0", "values": {"NAME": "value"}} with UPPER_SNAKE_CASE names '
|
|
386
|
+
+ 'and string values. `xeer env pull` writes the file correctly.', ['dev', 'preview', 'test']),
|
|
356
387
|
define('XE5139', 'xeer env failed without a more specific code.', 'Read `message`; it is the underlying error verbatim.', ['env']),
|
|
357
388
|
define('XE5140', 'An `xeer deployments` invocation is wrong: an unusable --limit, or a directory that '
|
|
358
389
|
+ 'declares no app identity.', 'Read `message`. --limit takes a positive integer up to 200. In a directory with no appId, run '
|
|
@@ -475,9 +506,18 @@ export function renderDiagnosticsReference() {
|
|
|
475
506
|
' file?: string; // project-relative POSIX path, never absolute',
|
|
476
507
|
' span?: { line: number; column: number; length?: number }; // 1-based',
|
|
477
508
|
' hint?: string; // suggested edit',
|
|
509
|
+
' primary?: true; // this broke the generated contract — repair it first',
|
|
510
|
+
' causedBy?: string; // a consequence of that code, not an independent error',
|
|
478
511
|
'}',
|
|
479
512
|
'```',
|
|
480
513
|
'',
|
|
514
|
+
'`primary` and `causedBy` are optional and may be absent from an entire envelope; absence means nothing',
|
|
515
|
+
'was attributed, not that a diagnostic is independent. When they are present, repair every `primary: true`',
|
|
516
|
+
'diagnostic first and leave every `causedBy` one alone until the primaries are clean: a `causedBy`',
|
|
517
|
+
'diagnostic sits in a file the broken contract poisoned, and editing that file makes the application',
|
|
518
|
+
'worse. Re-run afterwards — whatever still reports is real and carries its own location. A run that',
|
|
519
|
+
'found a contract failure emits its primaries first; sort on the field rather than relying on that.',
|
|
520
|
+
'',
|
|
481
521
|
'The "Seen in" column lists the commands whose JSON can carry the code. `check` diagnostics also appear',
|
|
482
522
|
'in `build` and `dev`, because both run the same manifest and analysis stages first.',
|
|
483
523
|
];
|
|
@@ -515,9 +555,20 @@ export function renderDiagnosticsDocsPage() {
|
|
|
515
555
|
' file?: string; // project-relative POSIX path, never absolute',
|
|
516
556
|
' span?: { line: number; column: number; length?: number }; // 1-based',
|
|
517
557
|
' hint?: string; // suggested edit',
|
|
558
|
+
' primary?: true; // this broke the generated contract — repair it first',
|
|
559
|
+
' causedBy?: string; // a consequence of that code, not an independent error',
|
|
518
560
|
'}',
|
|
519
561
|
'```',
|
|
520
562
|
'',
|
|
563
|
+
'The last two fields are optional and may be absent from an entire envelope; absence means nothing was',
|
|
564
|
+
'attributed, not that a diagnostic is independent. A failure that invalidates the generated contract —',
|
|
565
|
+
'a `defineServer` the compiler cannot read statically, a duplicate operation name, an operation result',
|
|
566
|
+
'the platform cannot encode — makes every type derived from those operations wrong, so the files that',
|
|
567
|
+
'consume the contract fill with `XE1205` type errors their authors never caused. Repair the',
|
|
568
|
+
'`primary: true` diagnostics first, ignore the `causedBy` ones until the primaries are clean, then',
|
|
569
|
+
're-run: whatever still reports is real. Such a run emits its primaries ahead of the rest, so the',
|
|
570
|
+
'diagnostic worth reading is also the first one printed.',
|
|
571
|
+
'',
|
|
521
572
|
'Every command prints these as JSON with `--json`; see [Building with AI agents](/guides/agents).',
|
|
522
573
|
'The "Seen in" column lists the commands whose output can carry the code. `check` diagnostics also',
|
|
523
574
|
'appear in `build` and `dev`, because both run the same manifest and analysis stages first.',
|
|
@@ -59,16 +59,24 @@ export interface ZoneImportPolicy {
|
|
|
59
59
|
* knowledge — the SDK module targets live beside its resolver, not in this declarative layer.
|
|
60
60
|
*/
|
|
61
61
|
readonly platformModules: readonly string[];
|
|
62
|
-
/** Singleton-sensitive families. The renderer on the client; empty on the server
|
|
62
|
+
/** Singleton-sensitive families. The renderer on the client; empty on the server. */
|
|
63
63
|
readonly managedFamilies: readonly ManagedPackageFamily[];
|
|
64
|
-
/**
|
|
64
|
+
/**
|
|
65
|
+
* Package families another zone owns, refused here whatever the open set says. The renderer on the
|
|
66
|
+
* server: `preact` is declared and installed in any application with a client, so once the server
|
|
67
|
+
* zone admits declared dependencies (#244) nothing else would stop a server module importing it,
|
|
68
|
+
* and the server has no DOM to render into. Zone-exclusive rather than structurally impossible —
|
|
69
|
+
* which is what makes it *evidence* for cross-zone attribution, where a Node builtin is not.
|
|
70
|
+
*/
|
|
71
|
+
readonly foreignFamilies: readonly ManagedPackageFamily[];
|
|
72
|
+
/** The open set. `closed` admits nothing beyond the two lists above. */
|
|
65
73
|
readonly applicationDependencies: {
|
|
66
74
|
readonly mode: 'closed' | 'open';
|
|
67
75
|
/** Bundler resolution conditions for this zone's application dependencies. */
|
|
68
76
|
readonly conditions: readonly string[];
|
|
69
77
|
/** Compile-time defines applied when bundling this zone. */
|
|
70
78
|
readonly defines: Readonly<Record<string, string>>;
|
|
71
|
-
/** Byte budgets over the zone's single-chunk bundle; `null`
|
|
79
|
+
/** Byte budgets over the zone's single-chunk bundle; `null` when the zone declares none. */
|
|
72
80
|
readonly bundleBudget: {
|
|
73
81
|
readonly errorBytes: number;
|
|
74
82
|
readonly advisoryBytes: number;
|
|
@@ -98,9 +106,22 @@ export declare const CLIENT_BUNDLE_ADVISORY_BUDGET_BYTES: number;
|
|
|
98
106
|
export declare const PREACT_RENDERER_FAMILY: ManagedPackageFamily;
|
|
99
107
|
export declare const CLIENT_IMPORT_POLICY: ZoneImportPolicy;
|
|
100
108
|
/**
|
|
101
|
-
* The server zone
|
|
102
|
-
*
|
|
103
|
-
*
|
|
109
|
+
* The server zone, open to application dependencies since ADR 0005 was accepted (#244).
|
|
110
|
+
*
|
|
111
|
+
* The two zones now state the same rule — declare it, install it, type it, use it — and differ only
|
|
112
|
+
* where the *runtime* differs. `workerd` conditions are declared because that is what the server
|
|
113
|
+
* executes in, so a package that publishes a worker build gets it. What stays refused on the server
|
|
114
|
+
* is refused for one of two reasons, and the distinction is load-bearing for both the diagnostic's
|
|
115
|
+
* wording and cross-zone attribution:
|
|
116
|
+
*
|
|
117
|
+
* - **Impossible**: Node builtins and native addons. workerd provides neither, and no policy change
|
|
118
|
+
* can conjure them. Refused in *every* zone, so it says nothing about which zone a module is in.
|
|
119
|
+
* - **Zone-exclusive**: the renderer family, and `@impetik/xeer/client*`. Perfectly loadable here;
|
|
120
|
+
* simply the other zone's surface. This is what attribution reads as evidence.
|
|
121
|
+
*
|
|
122
|
+
* No byte budget: unlike the client bundle, the server module is not shipped to a browser on every
|
|
123
|
+
* cold navigation, so the 10 MiB v0 module ceiling (XE1401) is the only bound the platform has a
|
|
124
|
+
* defensible number for. A per-zone budget is a product decision, not a gap this change may fill.
|
|
104
125
|
*/
|
|
105
126
|
export declare const SERVER_IMPORT_POLICY: ZoneImportPolicy;
|
|
106
127
|
export declare function zoneImportPolicy(zone: ImportZone): ZoneImportPolicy;
|
|
@@ -127,15 +148,21 @@ export type BareImportAdmission =
|
|
|
127
148
|
| {
|
|
128
149
|
kind: 'open';
|
|
129
150
|
}
|
|
130
|
-
/**
|
|
151
|
+
/**
|
|
152
|
+
* Rejected on a zone rule rather than on the declaration invariant: a subpath of the platform
|
|
153
|
+
* package this zone does not admit, a package family another zone owns, or a zone that admits no
|
|
154
|
+
* application dependencies at all. Every one of these is *zone-exclusive* — the same specifier is
|
|
155
|
+
* legal somewhere — which is why they are attribution evidence and Node builtins are not.
|
|
156
|
+
*/
|
|
131
157
|
| {
|
|
132
158
|
kind: 'rejected';
|
|
133
|
-
reason: 'platform-subpath' | 'closed';
|
|
159
|
+
reason: 'platform-subpath' | 'foreign-family' | 'closed';
|
|
134
160
|
};
|
|
135
161
|
/**
|
|
136
|
-
* Classifies one bare specifier under a zone's policy. Node builtins
|
|
137
|
-
* analyzer already owns
|
|
138
|
-
* open set — is answered here so no
|
|
162
|
+
* Classifies one bare specifier under a zone's policy. Node builtins and native addons are the
|
|
163
|
+
* caller's concern (the analyzer already owns those, and they are refused in every zone); everything
|
|
164
|
+
* else — platform subpaths, managed and foreign families, and the open set — is answered here so no
|
|
165
|
+
* consumer keeps a private copy of the rules.
|
|
139
166
|
*/
|
|
140
167
|
export declare function admitBareImport(policy: ZoneImportPolicy, specifier: string): BareImportAdmission;
|
|
141
168
|
/**
|
|
@@ -110,6 +110,7 @@ export const CLIENT_IMPORT_POLICY = Object.freeze({
|
|
|
110
110
|
zone: 'client',
|
|
111
111
|
platformModules: CLIENT_PLATFORM_MODULES,
|
|
112
112
|
managedFamilies: Object.freeze([PREACT_RENDERER_FAMILY]),
|
|
113
|
+
foreignFamilies: Object.freeze([]),
|
|
113
114
|
applicationDependencies: Object.freeze({
|
|
114
115
|
mode: 'open',
|
|
115
116
|
conditions: Object.freeze(['browser', 'import']),
|
|
@@ -121,17 +122,31 @@ export const CLIENT_IMPORT_POLICY = Object.freeze({
|
|
|
121
122
|
}),
|
|
122
123
|
});
|
|
123
124
|
/**
|
|
124
|
-
* The server zone
|
|
125
|
-
*
|
|
126
|
-
*
|
|
125
|
+
* The server zone, open to application dependencies since ADR 0005 was accepted (#244).
|
|
126
|
+
*
|
|
127
|
+
* The two zones now state the same rule — declare it, install it, type it, use it — and differ only
|
|
128
|
+
* where the *runtime* differs. `workerd` conditions are declared because that is what the server
|
|
129
|
+
* executes in, so a package that publishes a worker build gets it. What stays refused on the server
|
|
130
|
+
* is refused for one of two reasons, and the distinction is load-bearing for both the diagnostic's
|
|
131
|
+
* wording and cross-zone attribution:
|
|
132
|
+
*
|
|
133
|
+
* - **Impossible**: Node builtins and native addons. workerd provides neither, and no policy change
|
|
134
|
+
* can conjure them. Refused in *every* zone, so it says nothing about which zone a module is in.
|
|
135
|
+
* - **Zone-exclusive**: the renderer family, and `@impetik/xeer/client*`. Perfectly loadable here;
|
|
136
|
+
* simply the other zone's surface. This is what attribution reads as evidence.
|
|
137
|
+
*
|
|
138
|
+
* No byte budget: unlike the client bundle, the server module is not shipped to a browser on every
|
|
139
|
+
* cold navigation, so the 10 MiB v0 module ceiling (XE1401) is the only bound the platform has a
|
|
140
|
+
* defensible number for. A per-zone budget is a product decision, not a gap this change may fill.
|
|
127
141
|
*/
|
|
128
142
|
export const SERVER_IMPORT_POLICY = Object.freeze({
|
|
129
143
|
zone: 'server',
|
|
130
144
|
platformModules: SERVER_PLATFORM_MODULES,
|
|
131
145
|
managedFamilies: Object.freeze([]),
|
|
146
|
+
foreignFamilies: Object.freeze([PREACT_RENDERER_FAMILY]),
|
|
132
147
|
applicationDependencies: Object.freeze({
|
|
133
|
-
mode: '
|
|
134
|
-
conditions: Object.freeze([]),
|
|
148
|
+
mode: 'open',
|
|
149
|
+
conditions: Object.freeze(['worker', 'import']),
|
|
135
150
|
defines: Object.freeze({}),
|
|
136
151
|
bundleBudget: null,
|
|
137
152
|
}),
|
|
@@ -145,9 +160,10 @@ export function packageNameOfSpecifier(specifier) {
|
|
|
145
160
|
return specifier.startsWith('@') ? segments.slice(0, 2).join('/') : segments[0];
|
|
146
161
|
}
|
|
147
162
|
/**
|
|
148
|
-
* Classifies one bare specifier under a zone's policy. Node builtins
|
|
149
|
-
* analyzer already owns
|
|
150
|
-
* open set — is answered here so no
|
|
163
|
+
* Classifies one bare specifier under a zone's policy. Node builtins and native addons are the
|
|
164
|
+
* caller's concern (the analyzer already owns those, and they are refused in every zone); everything
|
|
165
|
+
* else — platform subpaths, managed and foreign families, and the open set — is answered here so no
|
|
166
|
+
* consumer keeps a private copy of the rules.
|
|
151
167
|
*/
|
|
152
168
|
export function admitBareImport(policy, specifier) {
|
|
153
169
|
if (policy.platformModules.includes(specifier))
|
|
@@ -169,6 +185,12 @@ export function admitBareImport(policy, specifier) {
|
|
|
169
185
|
return { kind: 'managed-rejected', reason: 'metadata' };
|
|
170
186
|
return { kind: 'managed', classification, target };
|
|
171
187
|
}
|
|
188
|
+
// Before the open set, or an installed renderer would be admitted by the declaration invariant it
|
|
189
|
+
// satisfies in every application that has a client.
|
|
190
|
+
for (const family of policy.foreignFamilies) {
|
|
191
|
+
if (family.packages.includes(packageName))
|
|
192
|
+
return { kind: 'rejected', reason: 'foreign-family' };
|
|
193
|
+
}
|
|
172
194
|
if (policy.applicationDependencies.mode === 'open')
|
|
173
195
|
return { kind: 'open' };
|
|
174
196
|
return { kind: 'rejected', reason: 'closed' };
|
package/vendor/spec/index.d.ts
CHANGED
package/vendor/spec/index.js
CHANGED