@moikapy/origen-zero 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,169 @@
1
+ # @moikapy/origen-zero
2
+
3
+ Bridge package connecting [Origen](https://www.npmjs.com/package/@moikapy/origen) agents to the [ZeroLang](https://zerolang.ai) compiler and runtime.
4
+
5
+ ## Why?
6
+
7
+ Origen agents write tool logic in TypeScript. ZeroLang is a **systems language designed for agents** — structured compiler output, explicit effects, repair metadata, and JSON diagnostics are first-class. This package bridges the two:
8
+
9
+ - **Define tools in Zero** — Write `.0` files, compile them, get structured diagnostics before registration
10
+ - **Register as OrigenTools** — Zero functions become first-class Origen tools
11
+ - **Interactive compiler tools** — `zero_check`, `zero_graph`, `zero_size`, `zero_fix` as Origen tools
12
+ - **Self-modify** — Write, check, fix, and register tools during a single conversation session
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ npm install @moikapy/origen-zero
18
+ ```
19
+
20
+ **Prerequisites:**
21
+ - `@moikapy/origen` ^0.6.0 (peer dependency)
22
+ - Zero CLI installed and available on `$PATH` — [install guide](https://zerolang.ai)
23
+
24
+ ## Usage
25
+
26
+ ### Register a Compiled Zero Binary as OrigenTool
27
+
28
+ ```typescript
29
+ import { createZeroTool } from "@moikapy/origen-zero/tools";
30
+ import { streamOrigen } from "@moikapy/origen";
31
+
32
+ const lookupTool = createZeroTool({
33
+ functionName: "lookup",
34
+ description: "Look up a record by ID",
35
+ executablePath: "./bin/lookup",
36
+ });
37
+
38
+ const config = {
39
+ appName: "MyAgent",
40
+ tools: [lookupTool],
41
+ getD1: async () => myD1,
42
+ };
43
+ ```
44
+
45
+ ### Interactive Compiler Tools (LLM Calls Zero CLI)
46
+
47
+ ```typescript
48
+ import { createZeroCompilerTools } from "@moikapy/origen-zero/tools";
49
+
50
+ const compilerTools = createZeroCompilerTools();
51
+ // Returns: [zero_check, zero_graph, zero_size, zero_fix]
52
+ ```
53
+
54
+ ### Write, Check, Fix, Register — Full Loop
55
+
56
+ ```typescript
57
+ import { compileAndRegister } from "@moikapy/origen-zero/tools";
58
+
59
+ const result = await compileAndRegister({
60
+ path: "math.0",
61
+ content: sourceCode,
62
+ });
63
+
64
+ if ("tools" in result) {
65
+ // ✅ Compiled — result.tools are ready
66
+ } else {
67
+ // ❌ Errors — return to LLM for self-repair
68
+ console.log(result.errors);
69
+ }
70
+ ```
71
+
72
+ ### Direct Compiler Access
73
+
74
+ ```typescript
75
+ import { ZeroCompiler } from "@moikapy/origen-zero/compiler";
76
+
77
+ const compiler = new ZeroCompiler({ binaryPath: "zero", timeout: 10000 });
78
+
79
+ // Check for errors
80
+ const result = await compiler.check("fun main() {}" /* ... */);
81
+ if (result.ok) { /* clean */ }
82
+
83
+ // Get dependency graph
84
+ const graph = await compiler.graph("./src/math.0");
85
+
86
+ // Get size estimates
87
+ const sizes = await compiler.size("./src/math.0");
88
+
89
+ // Build WASM for Workers
90
+ const build = await compiler.build("./src/math.0", { emit: "wasm", target: "wasm32-web", out: "./dist/math" });
91
+ ```
92
+
93
+ ## API
94
+
95
+ ### `ZeroCompiler`
96
+
97
+ | Method | Description | Zero CLI |
98
+ |---|---|---|
99
+ | `check(source)` | Check for errors, return diagnostics | `zero check --json` |
100
+ | `graph(source)` | Get dependency graph | `zero graph --json` |
101
+ | `size(source)` | Get function size estimates | `zero size --json` |
102
+ | `fix(source)` | Get repair suggestions | `zero fix --plan --json` |
103
+ | `build(source, opts?)` | Compile to native executable | `zero build` |
104
+ | `explain(code)` | Human-readable diagnostic explanation | `zero explain` |
105
+
106
+ ### Tool Registration
107
+
108
+ | Function | Description |
109
+ |---|---|
110
+ | `createZeroTool(config)` | Register a compiled Zero function as an OrigenTool |
111
+ | `createZeroToolsFromProgram(path, opts?)` | Discover and register all public functions |
112
+ | `compileAndRegister(source, opts?)` | Write → compile → verify → register in one call |
113
+
114
+ ### Interactive Compiler Tools
115
+
116
+ | Tool Name | Description |
117
+ |---|---|
118
+ | `zero_check` | Check Zero source for errors |
119
+ | `zero_graph` | Show dependency graph |
120
+ | `zero_size` | Show function size estimates |
121
+ | `zero_fix` | Suggest repairs for errors |
122
+
123
+ ## Error Types
124
+
125
+ | Error | When |
126
+ |---|---|
127
+ | `ZeroCompilerNotFoundError` | `zero` binary not on PATH |
128
+ | `ZeroCheckFailedError` | Source has diagnostics |
129
+ | `ZeroBuildFailedError` | Build produces no output |
130
+ | `ZeroTimeoutError` | CLI invocation exceeds timeout |
131
+ | `ZeroExecutionError` | Compiled binary exits non-zero |
132
+
133
+ ### WASM Execution (Workers-ready)
134
+
135
+ ```typescript
136
+ import { createZeroWASMTool } from "@moikapy/origen-zero/wasm-tool";
137
+ import { readFileSync } from "node:fs";
138
+
139
+ // Load pre-compiled WASM module
140
+ const wasmBytes = readFileSync("./dist/my-tool.wasm");
141
+
142
+ // In Workers — WASM runs in-process, no subprocess or HTTP needed
143
+ const tool = createZeroWASMTool({
144
+ functionName: "main",
145
+ description: "My Zero tool",
146
+ wasmBytes,
147
+ });
148
+
149
+ // Execute: Zero program writes to stdout, tool captures the output
150
+ const result = await tool.execute({ input: "hello" });
151
+ ```
152
+
153
+ Build the WASM module from Zero source:
154
+
155
+ ```bash
156
+ zero build --emit wasm --target wasm32-web src/my-tool.0 --out dist/my-tool
157
+ ```
158
+
159
+ ## Execution Modes
160
+
161
+ | Mode | Transport | Works In | When |
162
+ |---|---|---|---|
163
+ | `subprocess` | execFile() | Node.js, Bun | Native binaries |
164
+ | `http` | fetch() | Workers, Node, browser | Remote Zero service |
165
+ | `wasm` | WebAssembly.instantiate() | Workers, Node, browser | Pre-compiled .wasm |
166
+
167
+ ## License
168
+
169
+ MIT
@@ -0,0 +1,232 @@
1
+ // src/errors.ts
2
+ var ZeroError = class extends Error {
3
+ constructor(message, code, diagnostics) {
4
+ super(message);
5
+ this.code = code;
6
+ this.diagnostics = diagnostics;
7
+ this.name = "ZeroError";
8
+ }
9
+ code;
10
+ diagnostics;
11
+ };
12
+ var ZeroCompilerNotFoundError = class extends ZeroError {
13
+ constructor(binaryPath) {
14
+ super(
15
+ `Zero CLI not found at "${binaryPath}". Install Zero CLI or configure binaryPath.`,
16
+ "ZERO_NOT_FOUND"
17
+ );
18
+ this.name = "ZeroCompilerNotFoundError";
19
+ }
20
+ };
21
+ var ZeroCheckFailedError = class extends ZeroError {
22
+ constructor(diagnostics) {
23
+ super(
24
+ `Zero check failed with ${diagnostics.length} diagnostic(s):
25
+ ${diagnostics.map((d) => ` [${d.code}] ${d.severity}: ${d.message} (line ${d.line})`).join("\n")}`,
26
+ "ZERO_CHECK_FAILED",
27
+ diagnostics
28
+ );
29
+ this.name = "ZeroCheckFailedError";
30
+ }
31
+ };
32
+ var ZeroBuildFailedError = class extends ZeroError {
33
+ constructor(diagnostics) {
34
+ super(
35
+ `Zero build failed with ${diagnostics.length} diagnostic(s)`,
36
+ "ZERO_BUILD_FAILED",
37
+ diagnostics
38
+ );
39
+ this.name = "ZeroBuildFailedError";
40
+ }
41
+ };
42
+ var ZeroTimeoutError = class extends ZeroError {
43
+ constructor(command, timeout) {
44
+ super(
45
+ `Zero CLI command "${command}" timed out after ${timeout}ms`,
46
+ "ZERO_TIMEOUT"
47
+ );
48
+ this.name = "ZeroTimeoutError";
49
+ }
50
+ };
51
+ var ZeroHTTPError = class extends ZeroError {
52
+ constructor(status, url, body) {
53
+ super(
54
+ `Zero compiler service returned ${status} from ${url}: ${body}`,
55
+ "ZERO_HTTP_ERROR"
56
+ );
57
+ this.status = status;
58
+ this.url = url;
59
+ this.name = "ZeroHTTPError";
60
+ }
61
+ status;
62
+ url;
63
+ };
64
+ var ZeroExecutionError = class extends ZeroError {
65
+ constructor(exitCode, stderr) {
66
+ super(
67
+ `Zero binary exited with code ${exitCode}: ${stderr}`,
68
+ "ZERO_EXECUTION_ERROR"
69
+ );
70
+ this.exitCode = exitCode;
71
+ this.stderr = stderr;
72
+ this.name = "ZeroExecutionError";
73
+ }
74
+ exitCode;
75
+ stderr;
76
+ };
77
+
78
+ // src/parser.ts
79
+ import { z } from "zod";
80
+ var DIAGNOSTIC_CODE_PATTERN = /^[A-Z]{3}\d{3}$/;
81
+ var ZeroDiagnosticSchema = z.object({
82
+ code: z.string().regex(DIAGNOSTIC_CODE_PATTERN, {
83
+ message: "Diagnostic code must match XXX### pattern (e.g., NAM003)"
84
+ }),
85
+ severity: z.enum(["error", "warning", "info"]),
86
+ message: z.string(),
87
+ line: z.number().int().positive(),
88
+ column: z.number().int().positive().optional(),
89
+ repair: z.object({
90
+ id: z.string(),
91
+ suggestion: z.string().optional()
92
+ }).optional()
93
+ });
94
+ var ZeroCheckResultSchema = z.object({
95
+ ok: z.boolean(),
96
+ diagnostics: z.array(ZeroDiagnosticSchema),
97
+ raw: z.record(z.string(), z.unknown())
98
+ });
99
+ var ZeroGraphResultSchema = z.object({
100
+ ok: z.boolean(),
101
+ graph: z.record(z.string(), z.array(z.string())),
102
+ raw: z.record(z.string(), z.unknown())
103
+ });
104
+ var ZeroSizeResultSchema = z.object({
105
+ ok: z.boolean(),
106
+ sizes: z.record(z.string(), z.number()),
107
+ raw: z.record(z.string(), z.unknown())
108
+ });
109
+ var ZeroFixSuggestionSchema = z.object({
110
+ id: z.string(),
111
+ diagnosticCode: z.string(),
112
+ safety: z.string(),
113
+ summary: z.string(),
114
+ appliesEdits: z.boolean()
115
+ });
116
+ var ZeroFixResultSchema = z.object({
117
+ ok: z.boolean(),
118
+ fixes: z.array(ZeroFixSuggestionSchema),
119
+ raw: z.record(z.string(), z.unknown())
120
+ });
121
+ function parseDiagnostic(d) {
122
+ return {
123
+ code: String(d.code ?? "UNK000"),
124
+ severity: ["error", "warning", "info"].includes(d.severity) ? d.severity : "error",
125
+ message: String(d.message ?? ""),
126
+ line: Number(d.line ?? 0) || 0,
127
+ column: d.column ? Number(d.column) : void 0,
128
+ repair: d.repair ? {
129
+ id: String(d.repair.id ?? ""),
130
+ suggestion: d.repair.suggestion ? String(d.repair.suggestion) : void 0
131
+ } : void 0
132
+ };
133
+ }
134
+ function parseCheckOutput(raw) {
135
+ const json = JSON.parse(raw);
136
+ return {
137
+ ok: json.ok ?? false,
138
+ diagnostics: (json.diagnostics ?? []).map(parseDiagnostic),
139
+ raw: json
140
+ };
141
+ }
142
+ function parseGraphOutput(raw) {
143
+ const json = JSON.parse(raw);
144
+ const diagnostics = json.diagnostics ?? [];
145
+ const hasErrors = diagnostics.some((d) => d.severity === "error");
146
+ return {
147
+ ok: !hasErrors,
148
+ symbols: (json.symbols ?? []).map((s) => ({
149
+ name: String(s.name ?? ""),
150
+ module: String(s.module ?? ""),
151
+ kind: String(s.kind ?? ""),
152
+ public: Boolean(s.public),
153
+ effects: Array.isArray(s.effects) ? s.effects.map(String) : []
154
+ })),
155
+ functions: (json.functions ?? []).map((f) => ({
156
+ name: String(f.name ?? ""),
157
+ kind: String(f.kind ?? ""),
158
+ public: Boolean(f.public),
159
+ params: Number(f.params ?? 0),
160
+ returnType: String(f.returnType ?? ""),
161
+ raises: Boolean(f.raises),
162
+ effects: Array.isArray(f.effects) ? f.effects.map(String) : [],
163
+ allocationBehavior: String(f.allocationBehavior ?? ""),
164
+ targetSupport: (() => {
165
+ const ts = f.targetSupport;
166
+ return ts ? { status: String(ts.status ?? ""), missingCapabilities: Array.isArray(ts.missingCapabilities) ? ts.missingCapabilities.map(String) : [] } : { status: "unknown", missingCapabilities: [] };
167
+ })()
168
+ })),
169
+ raw: json
170
+ };
171
+ }
172
+ function parseSizeOutput(raw) {
173
+ const json = JSON.parse(raw);
174
+ const diagnostics = json.diagnostics ?? [];
175
+ const hasErrors = diagnostics.some((d) => d.severity === "error");
176
+ const pr = json.portableRuntime;
177
+ return {
178
+ ok: !hasErrors,
179
+ portableRuntime: pr ? {
180
+ target: String(pr.target ?? ""),
181
+ runtimeKind: String(pr.runtimeKind ?? ""),
182
+ portable: Boolean(pr.portable),
183
+ imports: {
184
+ functionCount: Number(pr.imports?.functionCount ?? 0),
185
+ functions: Array.isArray(pr.imports?.functions) ? pr.imports.functions.map(String) : [],
186
+ module: pr.imports?.module ?? null
187
+ },
188
+ memoryFloor: pr.memoryFloor ? { floorBytes: Number(pr.memoryFloor.floorBytes ?? 0), minimumPages: Number(pr.memoryFloor.minimumPages ?? 0) } : void 0,
189
+ capabilityRestrictions: pr.capabilityRestrictions ?? void 0
190
+ } : void 0,
191
+ raw: json
192
+ };
193
+ }
194
+ function parseFixOutput(raw) {
195
+ const json = JSON.parse(raw);
196
+ const fixes = (json.fixes ?? []).map(
197
+ (f) => ({
198
+ id: String(f.id ?? ""),
199
+ diagnosticCode: String(f.diagnosticCode ?? f.code ?? ""),
200
+ safety: String(f.safety ?? "requires-human-review"),
201
+ summary: String(f.summary ?? f.message ?? ""),
202
+ appliesEdits: Boolean(f.appliesEdits ?? false)
203
+ })
204
+ );
205
+ return {
206
+ ok: json.ok ?? false,
207
+ fixes,
208
+ raw: json
209
+ };
210
+ }
211
+
212
+ export {
213
+ ZeroError,
214
+ ZeroCompilerNotFoundError,
215
+ ZeroCheckFailedError,
216
+ ZeroBuildFailedError,
217
+ ZeroTimeoutError,
218
+ ZeroHTTPError,
219
+ ZeroExecutionError,
220
+ ZeroDiagnosticSchema,
221
+ ZeroCheckResultSchema,
222
+ ZeroGraphResultSchema,
223
+ ZeroSizeResultSchema,
224
+ ZeroFixSuggestionSchema,
225
+ ZeroFixResultSchema,
226
+ parseDiagnostic,
227
+ parseCheckOutput,
228
+ parseGraphOutput,
229
+ parseSizeOutput,
230
+ parseFixOutput
231
+ };
232
+ //# sourceMappingURL=chunk-6RAZN3WM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts","../src/parser.ts"],"sourcesContent":["/**\n * @moikapy/origen-zero — Error hierarchy\n *\n * All errors extend ZeroError for consistent catch patterns.\n */\n\n/** Base error for all origen-zero errors. */\nexport class ZeroError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly diagnostics?: ZeroDiagnostic[],\n ) {\n super(message);\n this.name = \"ZeroError\";\n }\n}\n\n/** Thrown when the `zero` binary cannot be found on PATH or configured path. */\nexport class ZeroCompilerNotFoundError extends ZeroError {\n constructor(binaryPath: string) {\n super(\n `Zero CLI not found at \"${binaryPath}\". Install Zero CLI or configure binaryPath.`,\n \"ZERO_NOT_FOUND\",\n );\n this.name = \"ZeroCompilerNotFoundError\";\n }\n}\n\n/** Thrown when a Zero source file has diagnostic errors/warnings. */\nexport class ZeroCheckFailedError extends ZeroError {\n constructor(diagnostics: ZeroDiagnostic[]) {\n super(\n `Zero check failed with ${diagnostics.length} diagnostic(s):\\n${diagnostics.map((d) => ` [${d.code}] ${d.severity}: ${d.message} (line ${d.line})`).join(\"\\n\")}`,\n \"ZERO_CHECK_FAILED\",\n diagnostics,\n );\n this.name = \"ZeroCheckFailedError\";\n }\n}\n\n/** Thrown when `zero build` fails (produces no output binary). */\nexport class ZeroBuildFailedError extends ZeroError {\n constructor(diagnostics: ZeroDiagnostic[]) {\n super(\n `Zero build failed with ${diagnostics.length} diagnostic(s)`,\n \"ZERO_BUILD_FAILED\",\n diagnostics,\n );\n this.name = \"ZeroBuildFailedError\";\n }\n}\n\n/** Thrown when a Zero CLI invocation exceeds the configured timeout. */\nexport class ZeroTimeoutError extends ZeroError {\n constructor(command: string, timeout: number) {\n super(\n `Zero CLI command \"${command}\" timed out after ${timeout}ms`,\n \"ZERO_TIMEOUT\",\n );\n this.name = \"ZeroTimeoutError\";\n }\n}\n\n/** Thrown when a Zero HTTP compiler request fails. */\nexport class ZeroHTTPError extends ZeroError {\n constructor(\n public readonly status: number,\n public readonly url: string,\n body: string,\n ) {\n super(\n `Zero compiler service returned ${status} from ${url}: ${body}`,\n \"ZERO_HTTP_ERROR\",\n );\n this.name = \"ZeroHTTPError\";\n }\n}\n\n/** Thrown when a compiled Zero binary returns a non-zero exit code. */\nexport class ZeroExecutionError extends ZeroError {\n constructor(\n public readonly exitCode: number,\n public readonly stderr: string,\n ) {\n super(\n `Zero binary exited with code ${exitCode}: ${stderr}`,\n \"ZERO_EXECUTION_ERROR\",\n );\n this.name = \"ZeroExecutionError\";\n }\n}\n\n// Re-export ZeroDiagnostic from types so consumers don't need to import both\nimport type { ZeroDiagnostic } from \"./types.js\";\nexport type { ZeroDiagnostic } from \"./types.js\";","/**\n * @moikapy/origen-zero — Zero CLI output parser\n *\n * Parses JSON output from `zero check --json`, `zero graph --json`,\n * `zero size --json`, and `zero fix --plan --json` into typed structures.\n */\n\nimport { z } from \"zod\";\nimport type {\n ZeroDiagnostic,\n ZeroCheckResult,\n ZeroGraphResult,\n ZeroSizeResult,\n ZeroFixResult,\n ZeroFixSuggestion,\n} from \"./types.js\";\n\n// ── Zod Schemas ─────────────────────────────────────────────────────────\n\n/** Diagnostic code pattern: three uppercase letters + three digits. */\nconst DIAGNOSTIC_CODE_PATTERN = /^[A-Z]{3}\\d{3}$/;\n\nexport const ZeroDiagnosticSchema = z.object({\n code: z.string().regex(DIAGNOSTIC_CODE_PATTERN, {\n message: \"Diagnostic code must match XXX### pattern (e.g., NAM003)\",\n }),\n severity: z.enum([\"error\", \"warning\", \"info\"]),\n message: z.string(),\n line: z.number().int().positive(),\n column: z.number().int().positive().optional(),\n repair: z\n .object({\n id: z.string(),\n suggestion: z.string().optional(),\n })\n .optional(),\n});\n\nexport const ZeroCheckResultSchema = z.object({\n ok: z.boolean(),\n diagnostics: z.array(ZeroDiagnosticSchema),\n raw: z.record(z.string(), z.unknown()),\n});\n\nexport const ZeroGraphResultSchema = z.object({\n ok: z.boolean(),\n graph: z.record(z.string(), z.array(z.string())),\n raw: z.record(z.string(), z.unknown()),\n});\n\nexport const ZeroSizeResultSchema = z.object({\n ok: z.boolean(),\n sizes: z.record(z.string(), z.number()),\n raw: z.record(z.string(), z.unknown()),\n});\n\nexport const ZeroFixSuggestionSchema = z.object({\n id: z.string(),\n diagnosticCode: z.string(),\n safety: z.string(),\n summary: z.string(),\n appliesEdits: z.boolean(),\n});\n\nexport const ZeroFixResultSchema = z.object({\n ok: z.boolean(),\n fixes: z.array(ZeroFixSuggestionSchema),\n raw: z.record(z.string(), z.unknown()),\n});\n\n// ── Parsers ──────────────────────────────────────────────────────────────\n\n/** Parse a single diagnostic from raw JSON. */\nexport function parseDiagnostic(d: Record<string, unknown>): ZeroDiagnostic {\n return {\n code: String(d.code ?? \"UNK000\"),\n severity: ([\"error\", \"warning\", \"info\"].includes(d.severity as string)\n ? d.severity\n : \"error\") as ZeroDiagnostic[\"severity\"],\n message: String(d.message ?? \"\"),\n line: Number(d.line ?? 0) || 0,\n column: d.column ? Number(d.column) : undefined,\n repair: d.repair\n ? {\n id: String((d.repair as Record<string, unknown>).id ?? \"\"),\n suggestion: (d.repair as Record<string, unknown>).suggestion\n ? String((d.repair as Record<string, unknown>).suggestion)\n : undefined,\n }\n : undefined,\n };\n}\n\n/** Parse `zero check --json` output into a typed ZeroCheckResult. */\nexport function parseCheckOutput(raw: string): ZeroCheckResult {\n const json = JSON.parse(raw);\n return {\n ok: json.ok ?? false,\n diagnostics: (json.diagnostics ?? []).map(parseDiagnostic),\n raw: json,\n };\n}\n\n/** Parse `zero graph --json` output into a typed ZeroGraphResult. */\nexport function parseGraphOutput(raw: string): ZeroGraphResult {\n const json = JSON.parse(raw);\n const diagnostics = json.diagnostics ?? [];\n const hasErrors = diagnostics.some((d: any) => d.severity === \"error\");\n return {\n ok: !hasErrors,\n symbols: (json.symbols ?? []).map((s: Record<string, unknown>) => ({\n name: String(s.name ?? \"\"),\n module: String(s.module ?? \"\"),\n kind: String(s.kind ?? \"\"),\n public: Boolean(s.public),\n effects: Array.isArray(s.effects) ? s.effects.map(String) : [],\n })),\n functions: (json.functions ?? []).map((f: Record<string, unknown>) => ({\n name: String(f.name ?? \"\"),\n kind: String(f.kind ?? \"\"),\n public: Boolean(f.public),\n params: Number(f.params ?? 0),\n returnType: String(f.returnType ?? \"\"),\n raises: Boolean(f.raises),\n effects: Array.isArray(f.effects) ? f.effects.map(String) : [],\n allocationBehavior: String(f.allocationBehavior ?? \"\"),\n targetSupport: (() => {\n const ts = f.targetSupport as Record<string, unknown> | undefined;\n return ts\n ? { status: String(ts.status ?? \"\"), missingCapabilities: Array.isArray(ts.missingCapabilities) ? ts.missingCapabilities.map(String) : [] }\n : { status: \"unknown\", missingCapabilities: [] };\n })(),\n })),\n raw: json,\n };\n}\n\n/** Parse `zero size --json` output into a typed ZeroSizeResult. */\nexport function parseSizeOutput(raw: string): ZeroSizeResult {\n const json = JSON.parse(raw);\n const diagnostics = json.diagnostics ?? [];\n const hasErrors = diagnostics.some((d: any) => d.severity === \"error\");\n const pr = json.portableRuntime;\n return {\n ok: !hasErrors,\n portableRuntime: pr\n ? {\n target: String(pr.target ?? \"\"),\n runtimeKind: String(pr.runtimeKind ?? \"\"),\n portable: Boolean(pr.portable),\n imports: {\n functionCount: Number(pr.imports?.functionCount ?? 0),\n functions: Array.isArray(pr.imports?.functions) ? pr.imports.functions.map(String) : [],\n module: pr.imports?.module ?? null,\n },\n memoryFloor: pr.memoryFloor\n ? { floorBytes: Number(pr.memoryFloor.floorBytes ?? 0), minimumPages: Number(pr.memoryFloor.minimumPages ?? 0) }\n : undefined,\n capabilityRestrictions: pr.capabilityRestrictions ?? undefined,\n }\n : undefined,\n raw: json,\n };\n}\n\n/** Parse `zero fix --plan --json` output into a typed ZeroFixResult. */\nexport function parseFixOutput(raw: string): ZeroFixResult {\n const json = JSON.parse(raw);\n const fixes: ZeroFixSuggestion[] = (json.fixes ?? []).map(\n (f: Record<string, unknown>) => ({\n id: String(f.id ?? \"\"),\n diagnosticCode: String(f.diagnosticCode ?? f.code ?? \"\"),\n safety: String(f.safety ?? \"requires-human-review\"),\n summary: String(f.summary ?? f.message ?? \"\"),\n appliesEdits: Boolean(f.appliesEdits ?? false),\n }),\n );\n return {\n ok: json.ok ?? false,\n fixes,\n raw: json,\n };\n}"],"mappings":"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","names":[]}
@@ -0,0 +1,194 @@
1
+ import {
2
+ ZeroBuildFailedError,
3
+ ZeroCompilerNotFoundError,
4
+ ZeroTimeoutError,
5
+ parseCheckOutput,
6
+ parseFixOutput,
7
+ parseGraphOutput,
8
+ parseSizeOutput
9
+ } from "./chunk-6RAZN3WM.js";
10
+
11
+ // src/compiler.ts
12
+ import { execFile } from "child_process";
13
+ import { mkdir, writeFile, rm } from "fs/promises";
14
+ import { join } from "path";
15
+ var DEFAULT_BINARY = "zero";
16
+ var DEFAULT_TIMEOUT = 3e4;
17
+ var TEMP_DIR = ".zero-origen/tmp";
18
+ var ZERO_EXIT_ERRORS = 1;
19
+ var ZERO_EXIT_INTERNAL = 2;
20
+ var ZeroCompiler = class {
21
+ binaryPath;
22
+ workingDir;
23
+ timeout;
24
+ constructor(config) {
25
+ this.binaryPath = config?.binaryPath ?? DEFAULT_BINARY;
26
+ this.workingDir = config?.workingDir ?? process.cwd();
27
+ this.timeout = config?.timeout ?? DEFAULT_TIMEOUT;
28
+ }
29
+ // ── Public API ──────────────────────────────────────────────────────
30
+ /** Check a Zero file or package for errors. Returns structured diagnostics. */
31
+ async check(source) {
32
+ const filePath = await this.writeSource(source);
33
+ try {
34
+ const stdout = await this.exec(["check", "--json", filePath]);
35
+ return parseCheckOutput(stdout);
36
+ } finally {
37
+ await this.cleanup(filePath);
38
+ }
39
+ }
40
+ /** Get the dependency graph for a Zero package. */
41
+ async graph(source) {
42
+ const filePath = await this.writeSource(source);
43
+ try {
44
+ const stdout = await this.exec(["graph", "--json", filePath]);
45
+ return parseGraphOutput(stdout);
46
+ } finally {
47
+ await this.cleanup(filePath);
48
+ }
49
+ }
50
+ /** Get size estimates for functions in a Zero file. */
51
+ async size(source) {
52
+ const filePath = await this.writeSource(source);
53
+ try {
54
+ const stdout = await this.exec(["size", "--json", filePath]);
55
+ return parseSizeOutput(stdout);
56
+ } finally {
57
+ await this.cleanup(filePath);
58
+ }
59
+ }
60
+ /** Get repair suggestions for a Zero program. */
61
+ async fix(source) {
62
+ const filePath = await this.writeSource(source);
63
+ try {
64
+ const stdout = await this.exec(["fix", "--plan", "--json", filePath]);
65
+ return parseFixOutput(stdout);
66
+ } finally {
67
+ await this.cleanup(filePath);
68
+ }
69
+ }
70
+ /** Build a Zero file to a native executable. */
71
+ async build(source, options) {
72
+ const filePath = await this.writeSource(source);
73
+ const args = ["build", "--json", "--emit", options?.emit ?? "exe"];
74
+ if (options?.target) {
75
+ args.push("--target", options.target);
76
+ }
77
+ if (options?.out) {
78
+ args.push("--out", options.out);
79
+ }
80
+ args.push(filePath);
81
+ try {
82
+ const stdout = await this.exec(args);
83
+ const json = JSON.parse(stdout);
84
+ return {
85
+ ok: true,
86
+ outputPath: json.artifactPath ?? options?.out,
87
+ diagnostics: []
88
+ };
89
+ } catch (err) {
90
+ if (err instanceof ZeroCompilerNotFoundError) throw err;
91
+ return {
92
+ ok: false,
93
+ diagnostics: []
94
+ };
95
+ } finally {
96
+ await this.cleanup(filePath);
97
+ }
98
+ }
99
+ /** Get a human-readable explanation for a diagnostic code. */
100
+ async explain(diagnosticCode) {
101
+ const stdout = await this.exec(["explain", diagnosticCode]);
102
+ return stdout.trim();
103
+ }
104
+ // ── Internal ────────────────────────────────────────────────────────
105
+ /** Resolve source to a file path. If inline content, write to temp dir. */
106
+ async writeSource(source) {
107
+ if (typeof source !== "string") {
108
+ if (source.content !== void 0) {
109
+ const tmpPath2 = join(this.workingDir, TEMP_DIR, source.path);
110
+ await mkdir(join(this.workingDir, TEMP_DIR), { recursive: true });
111
+ await writeFile(tmpPath2, source.content, "utf-8");
112
+ return tmpPath2;
113
+ }
114
+ return source.path;
115
+ }
116
+ try {
117
+ const stat = await import("fs/promises").then((fs) => fs.stat(source));
118
+ if (stat.isFile()) return source;
119
+ } catch {
120
+ }
121
+ const tmpPath = join(this.workingDir, TEMP_DIR, `check-${Date.now()}.0`);
122
+ await mkdir(join(this.workingDir, TEMP_DIR), { recursive: true });
123
+ await writeFile(tmpPath, source, "utf-8");
124
+ return tmpPath;
125
+ }
126
+ /** Clean up temp files (best effort — ignore errors). */
127
+ async cleanup(filePath) {
128
+ if (filePath.includes(TEMP_DIR)) {
129
+ await rm(filePath, { force: true }).catch(() => {
130
+ });
131
+ }
132
+ }
133
+ /**
134
+ * Execute the Zero CLI binary with the given arguments.
135
+ * Returns stdout on success (exit code 0).
136
+ * Throws ZeroCompilerNotFoundError if the binary isn't found.
137
+ * Throws ZeroTimeoutError if the invocation exceeds the timeout.
138
+ */
139
+ exec(args) {
140
+ return new Promise((resolve, reject) => {
141
+ const timeout = setTimeout(() => {
142
+ killed = true;
143
+ reject(new ZeroTimeoutError(`${this.binaryPath} ${args.join(" ")}`, this.timeout));
144
+ }, this.timeout);
145
+ let killed = false;
146
+ execFile(
147
+ this.binaryPath,
148
+ args,
149
+ {
150
+ cwd: this.workingDir,
151
+ maxBuffer: 1024 * 1024
152
+ // 1MB
153
+ },
154
+ (error, stdout, stderr) => {
155
+ clearTimeout(timeout);
156
+ if (killed) return;
157
+ if (error) {
158
+ if (error.code === "ENOENT") {
159
+ reject(new ZeroCompilerNotFoundError(this.binaryPath));
160
+ return;
161
+ }
162
+ const exitCode = error.code ?? error.status;
163
+ if (exitCode === ZERO_EXIT_ERRORS && stdout) {
164
+ resolve(stdout);
165
+ return;
166
+ }
167
+ if (exitCode === ZERO_EXIT_INTERNAL) {
168
+ reject(
169
+ new ZeroBuildFailedError([
170
+ {
171
+ code: "ZERO_INTERNAL",
172
+ severity: "error",
173
+ message: stderr || error.message,
174
+ line: 0
175
+ }
176
+ ])
177
+ );
178
+ return;
179
+ }
180
+ reject(error);
181
+ return;
182
+ }
183
+ resolve(stdout);
184
+ }
185
+ );
186
+ });
187
+ }
188
+ };
189
+
190
+ export {
191
+ TEMP_DIR,
192
+ ZeroCompiler
193
+ };
194
+ //# sourceMappingURL=chunk-DE5JDJKT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/compiler.ts"],"sourcesContent":["/**\n * @moikapy/origen-zero — ZeroCompiler class\n *\n * Wraps the Zero CLI binary, invoking it as a subprocess with --json flags\n * and parsing the structured output into typed results.\n */\n\nimport { execFile } from \"node:child_process\";\nimport { mkdir, writeFile, rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type {\n ZeroCompilerLike,\n ZeroCompilerConfig,\n ZeroSourceFile,\n ZeroCheckResult,\n ZeroGraphResult,\n ZeroSizeResult,\n ZeroFixResult,\n ZeroBuildResult,\n ZeroBuildOptions,\n} from \"./types.js\";\nimport {\n parseCheckOutput,\n parseGraphOutput,\n parseSizeOutput,\n parseFixOutput,\n} from \"./parser.js\";\nimport {\n ZeroCompilerNotFoundError,\n ZeroTimeoutError,\n ZeroBuildFailedError,\n} from \"./errors.js\";\n\n// ── Defaults ────────────────────────────────────────────────────────────\n\nconst DEFAULT_BINARY = \"zero\";\nconst DEFAULT_TIMEOUT = 30_000;\n\n/** Temp directory for Zero compilation artifacts. Shared across modules. */\nexport const TEMP_DIR = \".zero-origen/tmp\";\nconst ZERO_EXIT_OK = 0;\nconst ZERO_EXIT_ERRORS = 1;\nconst ZERO_EXIT_INTERNAL = 2;\n\n// ── ZeroCompiler ────────────────────────────────────────────────────────\n\nexport class ZeroCompiler implements ZeroCompilerLike {\n private readonly binaryPath: string;\n private readonly workingDir: string;\n private readonly timeout: number;\n\n constructor(config?: ZeroCompilerConfig) {\n this.binaryPath = config?.binaryPath ?? DEFAULT_BINARY;\n this.workingDir = config?.workingDir ?? process.cwd();\n this.timeout = config?.timeout ?? DEFAULT_TIMEOUT;\n }\n\n // ── Public API ──────────────────────────────────────────────────────\n\n /** Check a Zero file or package for errors. Returns structured diagnostics. */\n async check(source: string | ZeroSourceFile): Promise<ZeroCheckResult> {\n const filePath = await this.writeSource(source);\n try {\n const stdout = await this.exec([\"check\", \"--json\", filePath]);\n return parseCheckOutput(stdout);\n } finally {\n await this.cleanup(filePath);\n }\n }\n\n /** Get the dependency graph for a Zero package. */\n async graph(source: string | ZeroSourceFile): Promise<ZeroGraphResult> {\n const filePath = await this.writeSource(source);\n try {\n const stdout = await this.exec([\"graph\", \"--json\", filePath]);\n return parseGraphOutput(stdout);\n } finally {\n await this.cleanup(filePath);\n }\n }\n\n /** Get size estimates for functions in a Zero file. */\n async size(source: string | ZeroSourceFile): Promise<ZeroSizeResult> {\n const filePath = await this.writeSource(source);\n try {\n const stdout = await this.exec([\"size\", \"--json\", filePath]);\n return parseSizeOutput(stdout);\n } finally {\n await this.cleanup(filePath);\n }\n }\n\n /** Get repair suggestions for a Zero program. */\n async fix(source: string | ZeroSourceFile): Promise<ZeroFixResult> {\n const filePath = await this.writeSource(source);\n try {\n const stdout = await this.exec([\"fix\", \"--plan\", \"--json\", filePath]);\n return parseFixOutput(stdout);\n } finally {\n await this.cleanup(filePath);\n }\n }\n\n /** Build a Zero file to a native executable. */\n async build(\n source: string | ZeroSourceFile,\n options?: ZeroBuildOptions,\n ): Promise<ZeroBuildResult> {\n const filePath = await this.writeSource(source);\n const args = [\"build\", \"--json\", \"--emit\", options?.emit ?? \"exe\"];\n\n if (options?.target) {\n args.push(\"--target\", options.target);\n }\n\n if (options?.out) {\n args.push(\"--out\", options.out);\n }\n\n args.push(filePath);\n\n try {\n const stdout = await this.exec(args);\n // Build produces structured JSON output\n const json = JSON.parse(stdout);\n return {\n ok: true,\n outputPath: json.artifactPath ?? options?.out,\n diagnostics: [],\n };\n } catch (err) {\n if (err instanceof ZeroCompilerNotFoundError) throw err;\n // Build errors may include diagnostics in stderr or structured output\n return {\n ok: false,\n diagnostics: [],\n };\n } finally {\n await this.cleanup(filePath);\n }\n }\n\n /** Get a human-readable explanation for a diagnostic code. */\n async explain(diagnosticCode: string): Promise<string> {\n const stdout = await this.exec([\"explain\", diagnosticCode]);\n return stdout.trim();\n }\n\n // ── Internal ────────────────────────────────────────────────────────\n\n /** Resolve source to a file path. If inline content, write to temp dir. */\n private async writeSource(source: string | ZeroSourceFile): Promise<string> {\n // If it's a ZeroSourceFile with explicit content, write to temp\n if (typeof source !== \"string\") {\n if (source.content !== undefined) {\n const tmpPath = join(this.workingDir, TEMP_DIR, source.path);\n await mkdir(join(this.workingDir, TEMP_DIR), { recursive: true });\n await writeFile(tmpPath, source.content, \"utf-8\");\n return tmpPath;\n }\n // Content is undefined — read from disk at source.path\n return source.path;\n }\n\n // String: check if it's a file path that exists on disk\n try {\n const stat = await import(\"node:fs/promises\").then((fs) => fs.stat(source));\n if (stat.isFile()) return source; // It's a real file path\n } catch {\n // Not a file — treat as inline source\n }\n\n // Inline source — write to temp file\n const tmpPath = join(this.workingDir, TEMP_DIR, `check-${Date.now()}.0`);\n await mkdir(join(this.workingDir, TEMP_DIR), { recursive: true });\n await writeFile(tmpPath, source, \"utf-8\");\n return tmpPath;\n }\n\n /** Clean up temp files (best effort — ignore errors). */\n private async cleanup(filePath: string): Promise<void> {\n if (filePath.includes(TEMP_DIR)) {\n await rm(filePath, { force: true }).catch(() => {});\n }\n }\n\n /**\n * Execute the Zero CLI binary with the given arguments.\n * Returns stdout on success (exit code 0).\n * Throws ZeroCompilerNotFoundError if the binary isn't found.\n * Throws ZeroTimeoutError if the invocation exceeds the timeout.\n */\n private exec(args: string[]): Promise<string> {\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n killed = true;\n reject(new ZeroTimeoutError(`${this.binaryPath} ${args.join(\" \")}`, this.timeout));\n }, this.timeout);\n\n let killed = false;\n\n execFile(\n this.binaryPath,\n args,\n {\n cwd: this.workingDir,\n maxBuffer: 1024 * 1024, // 1MB\n },\n (error, stdout, stderr) => {\n clearTimeout(timeout);\n if (killed) return;\n\n if (error) {\n // ENOENT means binary not found\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n reject(new ZeroCompilerNotFoundError(this.binaryPath));\n return;\n }\n // Exit code 1 means errors in the source – check both code (Node 25+) and status (older)\n const exitCode = (error as NodeJS.ErrnoException & { code?: number; status?: number }).code\n ?? (error as NodeJS.ErrnoException & { status?: number }).status;\n if (exitCode === ZERO_EXIT_ERRORS && stdout) {\n resolve(stdout);\n return;\n }\n // Exit code 2 means internal error\n if (exitCode === ZERO_EXIT_INTERNAL) {\n reject(\n new ZeroBuildFailedError([\n {\n code: \"ZERO_INTERNAL\",\n severity: \"error\",\n message: stderr || error.message,\n line: 0,\n },\n ]),\n );\n return;\n }\n reject(error);\n return;\n }\n\n resolve(stdout);\n },\n );\n });\n }\n}"],"mappings":"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","names":["tmpPath"]}