@miakapp/cli 4.0.0-alpha.0 → 4.0.0-alpha.3

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 (57) hide show
  1. package/package.json +4 -3
  2. package/dist/agent-pack.d.ts +0 -78
  3. package/dist/agent-pack.d.ts.map +0 -1
  4. package/dist/agent-pack.js +0 -193
  5. package/dist/agent-pack.js.map +0 -1
  6. package/dist/artifact.d.ts +0 -32
  7. package/dist/artifact.d.ts.map +0 -1
  8. package/dist/artifact.js +0 -328
  9. package/dist/artifact.js.map +0 -1
  10. package/dist/control-plane.d.ts +0 -37
  11. package/dist/control-plane.d.ts.map +0 -1
  12. package/dist/control-plane.js +0 -127
  13. package/dist/control-plane.js.map +0 -1
  14. package/dist/discovery.d.ts +0 -95
  15. package/dist/discovery.d.ts.map +0 -1
  16. package/dist/discovery.js +0 -389
  17. package/dist/discovery.js.map +0 -1
  18. package/dist/errors.d.ts +0 -37
  19. package/dist/errors.d.ts.map +0 -1
  20. package/dist/errors.js +0 -56
  21. package/dist/errors.js.map +0 -1
  22. package/dist/internal/http.d.ts +0 -35
  23. package/dist/internal/http.d.ts.map +0 -1
  24. package/dist/internal/http.js +0 -125
  25. package/dist/internal/http.js.map +0 -1
  26. package/dist/internal/json.d.ts +0 -15
  27. package/dist/internal/json.d.ts.map +0 -1
  28. package/dist/internal/json.js +0 -227
  29. package/dist/internal/json.js.map +0 -1
  30. package/dist/internal/names.d.ts +0 -45
  31. package/dist/internal/names.d.ts.map +0 -1
  32. package/dist/internal/names.js +0 -98
  33. package/dist/internal/names.js.map +0 -1
  34. package/dist/internal/requirements.d.ts +0 -10
  35. package/dist/internal/requirements.d.ts.map +0 -1
  36. package/dist/internal/requirements.js +0 -50
  37. package/dist/internal/requirements.js.map +0 -1
  38. package/dist/internal/yaml.d.ts +0 -26
  39. package/dist/internal/yaml.d.ts.map +0 -1
  40. package/dist/internal/yaml.js +0 -184
  41. package/dist/internal/yaml.js.map +0 -1
  42. package/dist/main.d.ts +0 -86
  43. package/dist/main.d.ts.map +0 -1
  44. package/dist/main.js +0 -666
  45. package/dist/main.js.map +0 -1
  46. package/dist/mcp.d.ts +0 -93
  47. package/dist/mcp.d.ts.map +0 -1
  48. package/dist/mcp.js +0 -524
  49. package/dist/mcp.js.map +0 -1
  50. package/dist/project.d.ts +0 -25
  51. package/dist/project.d.ts.map +0 -1
  52. package/dist/project.js +0 -90
  53. package/dist/project.js.map +0 -1
  54. package/dist/publication.d.ts +0 -95
  55. package/dist/publication.d.ts.map +0 -1
  56. package/dist/publication.js +0 -408
  57. package/dist/publication.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miakapp/cli",
3
- "version": "4.0.0-alpha.0",
3
+ "version": "4.0.0-alpha.3",
4
4
  "description": "Agent-first Miakapp command line: check, build, publish, activate and roll back home components",
5
5
  "type": "module",
6
6
  "engines": {
@@ -8,7 +8,7 @@
8
8
  "node": ">=22.9"
9
9
  },
10
10
  "bin": {
11
- "miakapp": "./bin/miakapp.js"
11
+ "miakapp": "bin/miakapp.js"
12
12
  },
13
13
  "files": [
14
14
  "assets",
@@ -30,7 +30,8 @@
30
30
  "directory": "packages/cli"
31
31
  },
32
32
  "publishConfig": {
33
- "access": "public"
33
+ "access": "public",
34
+ "tag": "latest"
34
35
  },
35
36
  "keywords": [
36
37
  "Miakapp",
@@ -1,78 +0,0 @@
1
- /** Directory the pack owns inside the owner's repository. */
2
- export declare const PACK_DIRECTORY = ".miakapp";
3
- /** The guide, copied out of the package so it is readable offline. */
4
- export declare const GUIDE_FILE = ".miakapp/agent-guide.md";
5
- /** Project-scope MCP configuration. Claude Code reads this file by name. */
6
- export declare const MCP_FILE = ".mcp.json";
7
- /** The name the server is registered under, and the tool-name prefix. */
8
- export declare const SERVER_NAME = "miakapp";
9
- /**
10
- * Instruction files, by the client that reads each one. Both are written:
11
- * a repository is handed to whichever agent the owner has, and an unused
12
- * pointer costs a paragraph.
13
- */
14
- export declare const INSTRUCTION_FILES: readonly {
15
- readonly path: string;
16
- readonly client: string;
17
- }[];
18
- export declare const BEGIN_MARKER = "<!-- miakapp:begin -->";
19
- export declare const END_MARKER = "<!-- miakapp:end -->";
20
- /** What happened to one file, reported per file rather than summed. */
21
- export type PackAction = 'created' | 'updated' | 'unchanged';
22
- export interface PackedFile {
23
- readonly path: string;
24
- readonly action: PackAction;
25
- }
26
- export interface FileStore {
27
- read(path: string): Promise<Uint8Array>;
28
- write(path: string, bytes: Uint8Array): Promise<void>;
29
- replace(path: string, bytes: Uint8Array): Promise<void>;
30
- exists(path: string): Promise<boolean>;
31
- makeDirectory(path: string): Promise<void>;
32
- }
33
- /**
34
- * The block written into each instruction file.
35
- *
36
- * It is short on purpose. Everything an agent needs to know is in the guide,
37
- * and a summary that drifts from the guide is worse than no summary: the agent
38
- * would believe the stale copy it read first.
39
- */
40
- export declare function instructionBlock(client: string): string;
41
- /**
42
- * Merges the block into an instruction file.
43
- *
44
- * Three cases, and the owner's prose survives all three: no file, a file with
45
- * no block, and a file with a block from an earlier run. The block is appended
46
- * rather than prepended because the top of an instruction file is where the
47
- * owner put what matters to them.
48
- */
49
- export declare function mergeInstructions(existing: string | undefined, block: string): string;
50
- /**
51
- * The server entry, as a client expects to find it.
52
- *
53
- * `command` is the bare binary name: the pack is written into a repository that
54
- * may be opened on another machine, where an absolute path from this one would
55
- * resolve to nothing.
56
- */
57
- export declare function serverEntry(): Record<string, unknown>;
58
- /**
59
- * Merges the server entry into an existing `.mcp.json`.
60
- *
61
- * Parsed and re-serialized rather than patched as text: every other server in
62
- * the file is carried across by name, and a file that does not parse is refused
63
- * instead of being overwritten with a valid one. An owner who hand-edited that
64
- * file into a syntax error still wants their edit back.
65
- */
66
- export declare function mergeMcpConfig(existing: string | undefined): string;
67
- export interface PackResult {
68
- readonly root: string;
69
- readonly files: readonly PackedFile[];
70
- }
71
- /**
72
- * Installs the pack under `root`.
73
- *
74
- * `guide` is passed in rather than read here so the caller decides where the
75
- * guide comes from: the packaged asset in production, a fixture in a test.
76
- */
77
- export declare function installPack(files: FileStore, root: string, guide: string): Promise<PackResult>;
78
- //# sourceMappingURL=agent-pack.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"agent-pack.d.ts","sourceRoot":"","sources":["../src/agent-pack.ts"],"names":[],"mappings":"AAqBA,6DAA6D;AAC7D,eAAO,MAAM,cAAc,aAAa,CAAC;AAEzC,sEAAsE;AACtE,eAAO,MAAM,UAAU,4BAAqC,CAAC;AAE7D,4EAA4E;AAC5E,eAAO,MAAM,QAAQ,cAAc,CAAC;AAEpC,yEAAyE;AACzE,eAAO,MAAM,WAAW,YAAY,CAAC;AAErC;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAG1F,CAAC;AAEF,eAAO,MAAM,YAAY,2BAA2B,CAAC;AACrD,eAAO,MAAM,UAAU,yBAAyB,CAAC;AAEjD,uEAAuE;AACvE,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC;AAE7D,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;CAC7B;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACxC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5C;AAoCD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CA8BvD;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAiBrF;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAMrD;AAMD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CA+BnE;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;CACvC;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,SAAS,EAChB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,UAAU,CAAC,CAiBrB"}
@@ -1,193 +0,0 @@
1
- /**
2
- * The installable pack.
3
- *
4
- * A coding agent handed someone's house does not arrive knowing how a Miakapp
5
- * home is built. It arrives in the owner's repository, with whatever files are
6
- * already there. This command puts three things in that repository:
7
- *
8
- * - the guide, as a file, so the knowledge survives without a network;
9
- * - a pointer to it in the instruction file each client actually reads —
10
- * `AGENTS.md` for Codex, `CLAUDE.md` for Claude Code;
11
- * - the MCP server entry, so the tools are wired rather than described.
12
- *
13
- * The repository belongs to the owner, and the CLI's rule that it never
14
- * rewrites what it did not generate holds here too. That rule is what shapes
15
- * every merge below: the guide is a file this command owns outright, the
16
- * instruction files are edited only between markers this command wrote, and
17
- * `.mcp.json` is edited as a structure — one key, by name — never as text.
18
- * Bytes outside those regions are copied through untouched.
19
- */
20
- import { projectError } from './errors.js';
21
- /** Directory the pack owns inside the owner's repository. */
22
- export const PACK_DIRECTORY = '.miakapp';
23
- /** The guide, copied out of the package so it is readable offline. */
24
- export const GUIDE_FILE = `${PACK_DIRECTORY}/agent-guide.md`;
25
- /** Project-scope MCP configuration. Claude Code reads this file by name. */
26
- export const MCP_FILE = '.mcp.json';
27
- /** The name the server is registered under, and the tool-name prefix. */
28
- export const SERVER_NAME = 'miakapp';
29
- /**
30
- * Instruction files, by the client that reads each one. Both are written:
31
- * a repository is handed to whichever agent the owner has, and an unused
32
- * pointer costs a paragraph.
33
- */
34
- export const INSTRUCTION_FILES = [
35
- { path: 'AGENTS.md', client: 'Codex' },
36
- { path: 'CLAUDE.md', client: 'Claude Code' },
37
- ];
38
- export const BEGIN_MARKER = '<!-- miakapp:begin -->';
39
- export const END_MARKER = '<!-- miakapp:end -->';
40
- const encoder = new TextEncoder();
41
- function decode(bytes, path) {
42
- try {
43
- return new TextDecoder('utf-8', { fatal: true }).decode(bytes);
44
- }
45
- catch {
46
- throw projectError(`${path} is not readable as UTF-8 text`, 'The pack edits text files in place; move this one aside and run the command again.');
47
- }
48
- }
49
- /**
50
- * Writes `bytes` at `path`, creating or replacing.
51
- *
52
- * Returns `unchanged` when the bytes already on disk are identical, so a second
53
- * run of the pack reports honestly instead of claiming work it did not do.
54
- */
55
- async function put(files, path, content) {
56
- const bytes = encoder.encode(content);
57
- if (!await files.exists(path)) {
58
- await files.write(path, bytes);
59
- return { path, action: 'created' };
60
- }
61
- if (decode(await files.read(path), path) === content)
62
- return { path, action: 'unchanged' };
63
- await files.replace(path, bytes);
64
- return { path, action: 'updated' };
65
- }
66
- /**
67
- * The block written into each instruction file.
68
- *
69
- * It is short on purpose. Everything an agent needs to know is in the guide,
70
- * and a summary that drifts from the guide is worse than no summary: the agent
71
- * would believe the stale copy it read first.
72
- */
73
- export function instructionBlock(client) {
74
- return `${BEGIN_MARKER}
75
- ## Miakapp
76
-
77
- This repository is a Miakapp home: a coordinator that runs on the owner's
78
- machine and owns state, events and authorization, and a component that runs
79
- sandboxed in the household's browser and owns nothing but the interface.
80
-
81
- **Read \`${GUIDE_FILE}\` before writing or publishing anything here.** It is the
82
- full guide, copied into this repository so it is readable offline, and it is the
83
- source of truth for the rules below.
84
-
85
- The \`${SERVER_NAME}\` MCP server in \`${MCP_FILE}\` exposes the toolchain to ${client}:
86
- inventory an existing installation, validate the project, publish, and roll back.
87
- The same commands exist as \`${SERVER_NAME}\` on the command line; they are one
88
- implementation, so neither surface can drift from the other.
89
-
90
- Three rules the guide explains and this file repeats because getting them wrong
91
- is expensive:
92
-
93
- - \`publish\`, \`activate\` and \`rollback\` change what every device in the home
94
- runs. Over MCP they refuse to act without \`confirm: true\`. Set it when the
95
- owner asked for that publication, never to get past an error.
96
- - Every failure carries a stable \`kind\`. Branch on it, not on the message.
97
- \`conflict\` means re-read the pointer; \`unknown_outcome\` means the effect is
98
- undetermined — reconcile with \`${SERVER_NAME} release\` or \`${SERVER_NAME} upload\`
99
- before acting again, and never retry it.
100
- - The Home Key lives in \`MIAKAPP_HOME_KEY\` in the environment. No command
101
- accepts it as an argument, and it belongs in no file in this repository.
102
- ${END_MARKER}`;
103
- }
104
- /**
105
- * Merges the block into an instruction file.
106
- *
107
- * Three cases, and the owner's prose survives all three: no file, a file with
108
- * no block, and a file with a block from an earlier run. The block is appended
109
- * rather than prepended because the top of an instruction file is where the
110
- * owner put what matters to them.
111
- */
112
- export function mergeInstructions(existing, block) {
113
- if (existing === undefined || existing.trim() === '')
114
- return `${block}\n`;
115
- const start = existing.indexOf(BEGIN_MARKER);
116
- if (start === -1) {
117
- const separator = existing.endsWith('\n') ? '\n' : '\n\n';
118
- return `${existing}${separator}${block}\n`;
119
- }
120
- const end = existing.indexOf(END_MARKER, start);
121
- if (end === -1) {
122
- throw projectError(`An unterminated ${BEGIN_MARKER} block is open in this file`, `Close it with ${END_MARKER}, or delete the block and run the pack again.`);
123
- }
124
- return existing.slice(0, start) + block + existing.slice(end + END_MARKER.length);
125
- }
126
- /**
127
- * The server entry, as a client expects to find it.
128
- *
129
- * `command` is the bare binary name: the pack is written into a repository that
130
- * may be opened on another machine, where an absolute path from this one would
131
- * resolve to nothing.
132
- */
133
- export function serverEntry() {
134
- return {
135
- type: 'stdio',
136
- command: SERVER_NAME,
137
- args: ['mcp'],
138
- };
139
- }
140
- function isPlainObject(value) {
141
- return typeof value === 'object' && value !== null && !Array.isArray(value);
142
- }
143
- /**
144
- * Merges the server entry into an existing `.mcp.json`.
145
- *
146
- * Parsed and re-serialized rather than patched as text: every other server in
147
- * the file is carried across by name, and a file that does not parse is refused
148
- * instead of being overwritten with a valid one. An owner who hand-edited that
149
- * file into a syntax error still wants their edit back.
150
- */
151
- export function mergeMcpConfig(existing) {
152
- let document = {};
153
- if (existing !== undefined && existing.trim() !== '') {
154
- let parsed;
155
- try {
156
- parsed = JSON.parse(existing);
157
- }
158
- catch (error) {
159
- throw projectError(`${MCP_FILE} is not valid JSON: ${error instanceof Error ? error.message : 'parse failed'}`, 'The pack merges one entry into this file and will not replace it. Fix the JSON first.');
160
- }
161
- if (!isPlainObject(parsed)) {
162
- throw projectError(`${MCP_FILE} must hold a JSON object`, 'The pack merges one entry into this file and will not replace it.');
163
- }
164
- document = parsed;
165
- }
166
- const servers = document['mcpServers'];
167
- if (servers !== undefined && !isPlainObject(servers)) {
168
- throw projectError(`${MCP_FILE} has an "mcpServers" key that is not an object`, 'The pack merges one entry into this file and will not replace it.');
169
- }
170
- const merged = { ...(servers ?? {}), [SERVER_NAME]: serverEntry() };
171
- return `${JSON.stringify({ ...document, mcpServers: merged }, null, 2)}\n`;
172
- }
173
- /**
174
- * Installs the pack under `root`.
175
- *
176
- * `guide` is passed in rather than read here so the caller decides where the
177
- * guide comes from: the packaged asset in production, a fixture in a test.
178
- */
179
- export async function installPack(files, root, guide) {
180
- const written = [];
181
- await files.makeDirectory(`${root}/${PACK_DIRECTORY}`);
182
- written.push(await put(files, `${root}/${GUIDE_FILE}`, guide));
183
- for (const { path, client } of INSTRUCTION_FILES) {
184
- const full = `${root}/${path}`;
185
- const existing = await files.exists(full) ? decode(await files.read(full), full) : undefined;
186
- written.push(await put(files, full, mergeInstructions(existing, instructionBlock(client))));
187
- }
188
- const mcpPath = `${root}/${MCP_FILE}`;
189
- const config = await files.exists(mcpPath) ? decode(await files.read(mcpPath), mcpPath) : undefined;
190
- written.push(await put(files, mcpPath, mergeMcpConfig(config)));
191
- return { root, files: written };
192
- }
193
- //# sourceMappingURL=agent-pack.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"agent-pack.js","sourceRoot":"","sources":["../src/agent-pack.ts"],"names":[],"mappings":"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"}
@@ -1,32 +0,0 @@
1
- export interface Artifact {
2
- /** Exact bytes that will be uploaded; nothing re-encodes them later. */
3
- readonly bytes: Uint8Array;
4
- /** SHA-256 of those bytes as unpadded base64url, per RFC 0002 §7.1. */
5
- readonly sha256: string;
6
- readonly size: number;
7
- readonly tokens: number;
8
- }
9
- export type ArtifactFindingKind = 'module_syntax' | 'dynamic_import' | 'source_map_directive' | 'token_ceiling' | 'unterminated';
10
- export interface ArtifactFinding {
11
- readonly kind: ArtifactFindingKind;
12
- readonly line: number;
13
- readonly detail: string;
14
- }
15
- /**
16
- * Publisher pre-check for the RFC 0002 §7.2 artifact rules.
17
- *
18
- * RFC 0002 makes the broker's pinned platform parser authoritative; this scan
19
- * exists so an agent learns about module syntax, a dynamic import, a source-map
20
- * directive or an oversized program before spending an upload capability. It
21
- * reports findings rather than throwing, so one run can show every problem.
22
- */
23
- export declare function scanArtifactSource(source: string): {
24
- tokens: number;
25
- findings: readonly ArtifactFinding[];
26
- };
27
- /**
28
- * Verifies the exact bytes an upload would deliver and derives the digest and
29
- * size that bind the upload capability.
30
- */
31
- export declare function prepareArtifact(bytes: Uint8Array): Artifact;
32
- //# sourceMappingURL=artifact.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"artifact.d.ts","sourceRoot":"","sources":["../src/artifact.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,QAAQ;IACvB,wEAAwE;IACxE,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,uEAAuE;IACvE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,mBAAmB,GAC3B,eAAe,GACf,gBAAgB,GAChB,sBAAsB,GACtB,eAAe,GACf,cAAc,CAAC;AAEnB,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAwBD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;CACtC,CAsIA;AAiHD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,QAAQ,CA8B3D"}
package/dist/artifact.js DELETED
@@ -1,328 +0,0 @@
1
- import { createHash } from 'node:crypto';
2
- import { artifactError } from './errors.js';
3
- import { MAXIMUM_ARTIFACT_BYTES, MAXIMUM_PROGRAM_TOKENS, } from './internal/names.js';
4
- const IDENTIFIER_START = /[$_\p{ID_Start}]/u;
5
- const IDENTIFIER_PART = /[$_\u200c\u200d\p{ID_Continue}]/u;
6
- /**
7
- * Tokens after which a `/` starts a regular expression rather than a division.
8
- * The list is deliberately conservative: a wrong guess only changes how the
9
- * scanner counts, never whether the broker's pinned parser accepts the program.
10
- */
11
- const REGEX_ALLOWED_AFTER = new Set([
12
- 'case', 'delete', 'do', 'else', 'in', 'instanceof', 'new', 'of', 'return',
13
- 'throw', 'typeof', 'void', 'yield',
14
- ]);
15
- function isRegexPosition(previous) {
16
- if (previous === undefined)
17
- return true;
18
- if (REGEX_ALLOWED_AFTER.has(previous))
19
- return true;
20
- if (/^[A-Za-z_$]/.test(previous))
21
- return false;
22
- if (/^[0-9]/.test(previous))
23
- return false;
24
- return previous !== ')' && previous !== ']' && previous !== '}' && previous !== '++'
25
- && previous !== '--' && previous[0] !== '"' && previous[0] !== "'" && previous[0] !== '`';
26
- }
27
- /**
28
- * Publisher pre-check for the RFC 0002 §7.2 artifact rules.
29
- *
30
- * RFC 0002 makes the broker's pinned platform parser authoritative; this scan
31
- * exists so an agent learns about module syntax, a dynamic import, a source-map
32
- * directive or an oversized program before spending an upload capability. It
33
- * reports findings rather than throwing, so one run can show every problem.
34
- */
35
- export function scanArtifactSource(source) {
36
- const findings = [];
37
- let index = 0;
38
- let line = 1;
39
- let tokens = 0;
40
- let previous;
41
- let lineStartOnlyWhitespace = true;
42
- const record = (kind, detail) => {
43
- if (findings.some((finding) => finding.kind === kind && finding.line === line))
44
- return;
45
- findings.push({ kind, line, detail });
46
- };
47
- const advanceLines = (text) => {
48
- for (const character of text)
49
- if (character === '\n')
50
- line += 1;
51
- };
52
- while (index < source.length) {
53
- const character = source[index];
54
- if (character === '\n') {
55
- line += 1;
56
- lineStartOnlyWhitespace = true;
57
- index += 1;
58
- continue;
59
- }
60
- if (character === ' ' || character === '\t' || character === '\r' || character === '\f'
61
- || character === '\v' || character === '\u00a0' || character === '\ufeff') {
62
- index += 1;
63
- continue;
64
- }
65
- if (character === '/' && source[index + 1] === '/') {
66
- const end = source.indexOf('\n', index);
67
- const comment = source.slice(index, end === -1 ? source.length : end);
68
- if (/^\/\/[#@]\s*sourceMappingURL=/.test(comment)) {
69
- record('source_map_directive', comment.trim());
70
- }
71
- index = end === -1 ? source.length : end;
72
- continue;
73
- }
74
- if (character === '/' && source[index + 1] === '*') {
75
- const end = source.indexOf('*/', index + 2);
76
- if (end === -1) {
77
- record('unterminated', 'Unterminated block comment');
78
- break;
79
- }
80
- const comment = source.slice(index, end + 2);
81
- if (/^\/\*[#@]\s*sourceMappingURL=/.test(comment)) {
82
- record('source_map_directive', comment.slice(0, 64));
83
- }
84
- advanceLines(comment);
85
- index = end + 2;
86
- continue;
87
- }
88
- if (character === '"' || character === "'") {
89
- const end = scanQuoted(source, index, character);
90
- if (end === -1) {
91
- record('unterminated', 'Unterminated string literal');
92
- break;
93
- }
94
- advanceLines(source.slice(index, end));
95
- previous = `${character}string`;
96
- tokens += 1;
97
- index = end;
98
- lineStartOnlyWhitespace = false;
99
- continue;
100
- }
101
- if (character === '`') {
102
- const end = scanTemplate(source, index);
103
- if (end === -1) {
104
- record('unterminated', 'Unterminated template literal');
105
- break;
106
- }
107
- advanceLines(source.slice(index, end));
108
- previous = '`template';
109
- tokens += 1;
110
- index = end;
111
- lineStartOnlyWhitespace = false;
112
- continue;
113
- }
114
- if (character === '/' && isRegexPosition(previous)) {
115
- const end = scanRegex(source, index);
116
- if (end === -1) {
117
- record('unterminated', 'Unterminated regular expression literal');
118
- break;
119
- }
120
- previous = '/regex';
121
- tokens += 1;
122
- index = end;
123
- lineStartOnlyWhitespace = false;
124
- continue;
125
- }
126
- if (IDENTIFIER_START.test(character)) {
127
- let end = index + 1;
128
- while (end < source.length && IDENTIFIER_PART.test(source[end]))
129
- end += 1;
130
- const word = source.slice(index, end);
131
- if (word === 'import') {
132
- const next = nextSignificant(source, end);
133
- if (next === '(')
134
- record('dynamic_import', 'import( expression');
135
- else if (next === '.')
136
- record('dynamic_import', 'import.meta reference');
137
- else
138
- record('module_syntax', 'import declaration');
139
- }
140
- else if (word === 'export' && lineStartOnlyWhitespace) {
141
- record('module_syntax', 'export declaration');
142
- }
143
- previous = word;
144
- tokens += 1;
145
- index = end;
146
- lineStartOnlyWhitespace = false;
147
- continue;
148
- }
149
- if (character >= '0' && character <= '9') {
150
- let end = index + 1;
151
- while (end < source.length && /[0-9a-fA-FxXoObBn._]/.test(source[end]))
152
- end += 1;
153
- previous = source.slice(index, end);
154
- tokens += 1;
155
- index = end;
156
- lineStartOnlyWhitespace = false;
157
- continue;
158
- }
159
- const punctuator = scanPunctuator(source, index);
160
- previous = punctuator;
161
- tokens += 1;
162
- index += punctuator.length;
163
- lineStartOnlyWhitespace = false;
164
- if (tokens > MAXIMUM_PROGRAM_TOKENS)
165
- break;
166
- }
167
- if (tokens > MAXIMUM_PROGRAM_TOKENS) {
168
- findings.push({
169
- kind: 'token_ceiling',
170
- line,
171
- detail: `Program exceeds the ABI 1 ceiling of ${MAXIMUM_PROGRAM_TOKENS} lexical tokens`,
172
- });
173
- }
174
- return { tokens, findings };
175
- }
176
- function scanQuoted(source, start, quote) {
177
- let index = start + 1;
178
- while (index < source.length) {
179
- const character = source[index];
180
- if (character === '\\') {
181
- index += 2;
182
- continue;
183
- }
184
- if (character === quote)
185
- return index + 1;
186
- if (character === '\n')
187
- return -1;
188
- index += 1;
189
- }
190
- return -1;
191
- }
192
- function scanTemplate(source, start) {
193
- let index = start + 1;
194
- while (index < source.length) {
195
- const character = source[index];
196
- if (character === '\\') {
197
- index += 2;
198
- continue;
199
- }
200
- if (character === '`')
201
- return index + 1;
202
- if (character === '$' && source[index + 1] === '{') {
203
- let depth = 1;
204
- index += 2;
205
- while (index < source.length && depth > 0) {
206
- const inner = source[index];
207
- if (inner === '{')
208
- depth += 1;
209
- else if (inner === '}')
210
- depth -= 1;
211
- else if (inner === '`') {
212
- const nested = scanTemplate(source, index);
213
- if (nested === -1)
214
- return -1;
215
- index = nested;
216
- continue;
217
- }
218
- else if (inner === '"' || inner === "'") {
219
- const nested = scanQuoted(source, index, inner);
220
- if (nested === -1)
221
- return -1;
222
- index = nested;
223
- continue;
224
- }
225
- index += 1;
226
- }
227
- continue;
228
- }
229
- index += 1;
230
- }
231
- return -1;
232
- }
233
- function scanRegex(source, start) {
234
- let index = start + 1;
235
- let inClass = false;
236
- while (index < source.length) {
237
- const character = source[index];
238
- if (character === '\\') {
239
- index += 2;
240
- continue;
241
- }
242
- if (character === '\n')
243
- return -1;
244
- if (character === '[')
245
- inClass = true;
246
- else if (character === ']')
247
- inClass = false;
248
- else if (character === '/' && !inClass) {
249
- index += 1;
250
- while (index < source.length && IDENTIFIER_PART.test(source[index]))
251
- index += 1;
252
- return index;
253
- }
254
- index += 1;
255
- }
256
- return -1;
257
- }
258
- const PUNCTUATORS = [
259
- '>>>=', '...', '===', '!==', '**=', '<<=', '>>=', '>>>', '&&=', '||=', '??=',
260
- '=>', '==', '!=', '<=', '>=', '&&', '||', '??', '?.', '++', '--', '+=', '-=',
261
- '*=', '/=', '%=', '&=', '|=', '^=', '<<', '>>', '**',
262
- ];
263
- function scanPunctuator(source, index) {
264
- for (const punctuator of PUNCTUATORS) {
265
- if (source.startsWith(punctuator, index))
266
- return punctuator;
267
- }
268
- return source[index];
269
- }
270
- function nextSignificant(source, from) {
271
- let index = from;
272
- while (index < source.length) {
273
- const character = source[index];
274
- if (/\s/.test(character)) {
275
- index += 1;
276
- continue;
277
- }
278
- if (character === '/' && source[index + 1] === '/') {
279
- const end = source.indexOf('\n', index);
280
- if (end === -1)
281
- return undefined;
282
- index = end + 1;
283
- continue;
284
- }
285
- if (character === '/' && source[index + 1] === '*') {
286
- const end = source.indexOf('*/', index + 2);
287
- if (end === -1)
288
- return undefined;
289
- index = end + 2;
290
- continue;
291
- }
292
- return character;
293
- }
294
- return undefined;
295
- }
296
- /**
297
- * Verifies the exact bytes an upload would deliver and derives the digest and
298
- * size that bind the upload capability.
299
- */
300
- export function prepareArtifact(bytes) {
301
- if (bytes.byteLength === 0)
302
- throw artifactError('Artifact is empty');
303
- if (bytes.byteLength > MAXIMUM_ARTIFACT_BYTES) {
304
- throw artifactError(`Artifact is ${bytes.byteLength} bytes, above the ABI 1 ceiling of ${MAXIMUM_ARTIFACT_BYTES}`);
305
- }
306
- let source;
307
- try {
308
- source = new TextDecoder('utf-8', { fatal: true }).decode(bytes);
309
- }
310
- catch {
311
- throw artifactError('Artifact is not valid UTF-8');
312
- }
313
- const { tokens, findings } = scanArtifactSource(source);
314
- if (findings.length > 0) {
315
- const detail = findings
316
- .map((finding) => ` line ${finding.line}: ${finding.kind} — ${finding.detail}`)
317
- .join('\n');
318
- throw artifactError(`Artifact violates the RFC 0002 §7.2 artifact rules:\n${detail}`, 'Bundle to one self-contained classic Worker program with no module syntax, '
319
- + 'no dynamic import and no source map.');
320
- }
321
- return Object.freeze({
322
- bytes,
323
- sha256: createHash('sha256').update(bytes).digest('base64url'),
324
- size: bytes.byteLength,
325
- tokens,
326
- });
327
- }
328
- //# sourceMappingURL=artifact.js.map