@moikapy/origen-zero 0.1.0 → 0.1.1
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/dist/index.d.ts +51 -4
- package/dist/index.js +48 -0
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { e as ZeroDiagnostic, b as ZeroCheckResult, f as ZeroFixResult, h as ZeroGraphResult, j as ZeroSizeResult, d as ZeroCompilerLike, c as ZeroCompilerConfig } from './types-Dc-cDRjG.js';
|
|
2
|
-
export { Z as ZeroBuildOptions, a as ZeroBuildResult, g as ZeroFixSuggestion, i as ZeroHTTPCompilerConfig,
|
|
1
|
+
import { e as ZeroDiagnostic, b as ZeroCheckResult, f as ZeroFixResult, h as ZeroGraphResult, j as ZeroSizeResult, d as ZeroCompilerLike, c as ZeroCompilerConfig, k as ZeroSourceFile } from './types-Dc-cDRjG.js';
|
|
2
|
+
export { Z as ZeroBuildOptions, a as ZeroBuildResult, g as ZeroFixSuggestion, i as ZeroHTTPCompilerConfig, l as ZeroToolConfig, m as ZeroToolExecution, n as ZeroToolRegistrationFailure, o as ZeroToolRegistrationSuccess } from './types-Dc-cDRjG.js';
|
|
3
3
|
export { ZeroCompiler } from './compiler.js';
|
|
4
4
|
export { ZeroHTTPCompiler } from './http-compiler.js';
|
|
5
|
+
import { ZeroWASMToolConfig } from './wasm-tool.js';
|
|
5
6
|
export { createZeroWASMTool, createZeroWASMTools } from './wasm-tool.js';
|
|
6
7
|
export { ZeroWASIRuntime, ZeroWASIRuntimeConfig, createZeroWASIRuntime } from './wasi-runtime.js';
|
|
7
8
|
import { z } from 'zod';
|
|
8
9
|
export { compileAndRegister, createZeroTool, createZeroToolsFromProgram } from './tools.js';
|
|
9
|
-
import { OrigenTool } from '@moikapy/origen';
|
|
10
|
+
import { OrigenTool, ArtifactStore } from '@moikapy/origen';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* @moikapy/origen-zero — Error hierarchy
|
|
@@ -148,4 +149,50 @@ declare function parseFixOutput(raw: string): ZeroFixResult;
|
|
|
148
149
|
*/
|
|
149
150
|
declare function createZeroCompilerTools(compiler?: ZeroCompilerLike | ZeroCompilerConfig): OrigenTool[];
|
|
150
151
|
|
|
151
|
-
|
|
152
|
+
/**
|
|
153
|
+
* @moikapy/origen-zero — Artifact-aware tool creation
|
|
154
|
+
*
|
|
155
|
+
* The getOrCreateTool helper checks the artifact store for a cached WASM
|
|
156
|
+
* module before using provided bytes. If the artifact exists and the source
|
|
157
|
+
* hash matches, it reuses the cached bytes. If not, it stores the provided
|
|
158
|
+
* bytes for future sessions.
|
|
159
|
+
*
|
|
160
|
+
* This is the "compile once, use forever" pattern that makes Zero tools
|
|
161
|
+
* practical in production — no recompilation across sessions.
|
|
162
|
+
*
|
|
163
|
+
* The caller is responsible for obtaining WASM bytes (via ZeroCompiler,
|
|
164
|
+
* ZeroHTTPCompiler, or any other method). getOrCreateTool handles caching.
|
|
165
|
+
*/
|
|
166
|
+
|
|
167
|
+
interface GetOrCreateToolOptions {
|
|
168
|
+
/** Name for the tool (used as artifact key prefix and function name). */
|
|
169
|
+
name: string;
|
|
170
|
+
/** The compiled WASM bytes. If the artifact store has a cache hit, this is skipped. */
|
|
171
|
+
wasmBytes: ArrayBuffer;
|
|
172
|
+
/** Artifact store for caching compiled WASM. */
|
|
173
|
+
artifactStore: ArtifactStore;
|
|
174
|
+
/** Zero source code (used to derive the content hash for cache key). */
|
|
175
|
+
source: string | ZeroSourceFile;
|
|
176
|
+
/** Custom WASM tool config overrides (description, parameters, runtimeConfig). */
|
|
177
|
+
toolConfig?: Partial<Pick<ZeroWASMToolConfig, "description" | "parameters" | "runtimeConfig">>;
|
|
178
|
+
/** Content type for the artifact. Default: "application/wasm". */
|
|
179
|
+
contentType?: string;
|
|
180
|
+
/** Whether to force re-storage even if cached. Default: false. */
|
|
181
|
+
forceRecompile?: boolean;
|
|
182
|
+
/** Compiler version tag for cache invalidation. Default: "wasm32-web". */
|
|
183
|
+
compilerVersion?: string;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Get or create a Zero WASM tool, using the artifact store as a cache.
|
|
187
|
+
*
|
|
188
|
+
* 1. Compute source hash → derive artifact key
|
|
189
|
+
* 2. Check artifact store for cached WASM bytes
|
|
190
|
+
* 3. If cached and hash matches → instantiate from cached bytes
|
|
191
|
+
* 4. If cache miss → store provided bytes → instantiate
|
|
192
|
+
*
|
|
193
|
+
* The caller is responsible for compilation. This function handles caching
|
|
194
|
+
* and instantiation, so it works in any environment (Workers, Node, Bun).
|
|
195
|
+
*/
|
|
196
|
+
declare function getOrCreateTool(options: GetOrCreateToolOptions): Promise<OrigenTool>;
|
|
197
|
+
|
|
198
|
+
export { type GetOrCreateToolOptions, ZeroBuildFailedError, ZeroCheckFailedError, ZeroCheckResult, ZeroCheckResultSchema, ZeroCompilerConfig, ZeroCompilerLike, ZeroCompilerNotFoundError, ZeroDiagnostic, ZeroDiagnosticSchema, ZeroError, ZeroExecutionError, ZeroFixResult, ZeroFixResultSchema, ZeroFixSuggestionSchema, ZeroGraphResult, ZeroGraphResultSchema, ZeroHTTPError, ZeroSizeResult, ZeroSizeResultSchema, ZeroSourceFile, ZeroTimeoutError, createZeroCompilerTools, getOrCreateTool, parseCheckOutput, parseDiagnostic, parseFixOutput, parseGraphOutput, parseSizeOutput };
|
package/dist/index.js
CHANGED
|
@@ -158,6 +158,53 @@ ${lines.join("\n")}`;
|
|
|
158
158
|
};
|
|
159
159
|
return [checkTool, graphTool, sizeTool, fixTool];
|
|
160
160
|
}
|
|
161
|
+
|
|
162
|
+
// src/artifact-tool.ts
|
|
163
|
+
async function getOrCreateTool(options) {
|
|
164
|
+
const {
|
|
165
|
+
name,
|
|
166
|
+
wasmBytes,
|
|
167
|
+
artifactStore,
|
|
168
|
+
source,
|
|
169
|
+
toolConfig,
|
|
170
|
+
contentType = "application/wasm",
|
|
171
|
+
forceRecompile = false,
|
|
172
|
+
compilerVersion = "wasm32-web"
|
|
173
|
+
} = options;
|
|
174
|
+
const sourceString = typeof source === "string" ? source : source.content ?? "";
|
|
175
|
+
const sourceHash = await hashSource(sourceString);
|
|
176
|
+
const key = `zero/${name}-${sourceHash.slice(0, 12)}`;
|
|
177
|
+
if (!forceRecompile) {
|
|
178
|
+
const cached = await artifactStore.get(key);
|
|
179
|
+
if (cached) {
|
|
180
|
+
return createZeroWASMTool({
|
|
181
|
+
functionName: name,
|
|
182
|
+
description: toolConfig?.description ?? `Zero tool: ${name}`,
|
|
183
|
+
wasmBytes: cached,
|
|
184
|
+
parameters: toolConfig?.parameters,
|
|
185
|
+
runtimeConfig: toolConfig?.runtimeConfig
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
await artifactStore.put(key, wasmBytes, {
|
|
190
|
+
contentType,
|
|
191
|
+
sourceHash,
|
|
192
|
+
compilerVersion
|
|
193
|
+
});
|
|
194
|
+
return createZeroWASMTool({
|
|
195
|
+
functionName: name,
|
|
196
|
+
description: toolConfig?.description ?? `Zero tool: ${name}`,
|
|
197
|
+
wasmBytes,
|
|
198
|
+
parameters: toolConfig?.parameters,
|
|
199
|
+
runtimeConfig: toolConfig?.runtimeConfig
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
async function hashSource(source) {
|
|
203
|
+
const encoded = new TextEncoder().encode(source);
|
|
204
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", encoded);
|
|
205
|
+
const hashArray = new Uint8Array(hashBuffer);
|
|
206
|
+
return Array.from(hashArray).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
207
|
+
}
|
|
161
208
|
export {
|
|
162
209
|
ZeroBuildFailedError,
|
|
163
210
|
ZeroCheckFailedError,
|
|
@@ -181,6 +228,7 @@ export {
|
|
|
181
228
|
createZeroWASIRuntime,
|
|
182
229
|
createZeroWASMTool,
|
|
183
230
|
createZeroWASMTools,
|
|
231
|
+
getOrCreateTool,
|
|
184
232
|
parseCheckOutput,
|
|
185
233
|
parseDiagnostic,
|
|
186
234
|
parseFixOutput,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/compiler-tools.ts"],"sourcesContent":["/**\n * @moikapy/origen-zero — Interactive compiler tools\n *\n * Creates four OrigenTools that let the LLM write, check, and fix\n * Zero programs during a conversation:\n * - zero_check: Check a Zero program for errors\n * - zero_graph: Get the dependency graph\n * - zero_size: Get size estimates for functions\n * - zero_fix: Plan repairs for a Zero program\n */\n\nimport type { OrigenTool } from \"@moikapy/origen\";\nimport { ZeroCompiler, TEMP_DIR } from \"./compiler.js\";\nimport type { ZeroCompilerLike, ZeroCompilerConfig } from \"./types.js\";\n\n/**\n * Create the set of interactive Zero compiler tools that let the LLM\n * write, check, and fix Zero programs during a conversation.\n *\n * Accepts either a ZeroCompilerLike instance (ZeroCompiler or ZeroHTTPCompiler)\n * or a ZeroCompilerConfig for the local CLI compiler.\n */\nexport function createZeroCompilerTools(\n compiler?: ZeroCompilerLike | ZeroCompilerConfig,\n): OrigenTool[] {\n const zero: ZeroCompilerLike = !compiler\n ? new ZeroCompiler()\n : \"check\" in compiler && typeof compiler.check === \"function\"\n ? (compiler as ZeroCompilerLike)\n : new ZeroCompiler(compiler as ZeroCompilerConfig);\n\n const checkTool: OrigenTool = {\n name: \"zero_check\",\n description: `Check a Zero program for errors. Returns structured diagnostics with repair suggestions. Write your Zero source code in the \"source\" parameter.`,\n parameters: {\n type: \"object\",\n properties: {\n source: {\n type: \"string\",\n description: \"Zero source code to check\",\n },\n path: {\n type: \"string\",\n description: \"File path hint for error reporting (optional)\",\n },\n },\n required: [\"source\"],\n },\n async execute(args: Record<string, unknown>): Promise<string> {\n const source = String(args.source ?? \"\");\n const path = args.path ? String(args.path) : undefined;\n const result = await zero.check(path ? { path, content: source } : source);\n\n if (result.ok) {\n return \"✅ Zero program checks passed with no errors.\";\n }\n\n const lines = result.diagnostics.map((d) => {\n let line = `[${d.code}] ${d.severity}: ${d.message}`;\n if (d.line) line += ` (line ${d.line})`;\n if (d.column) line += `:${d.column}`;\n if (d.repair) line += ` → Fix: ${d.repair.suggestion ?? d.repair.id}`;\n return line;\n });\n\n return `❌ Zero program has ${result.diagnostics.length} diagnostic(s):\\n${lines.join(\"\\n\")}`;\n },\n };\n\n const graphTool: OrigenTool = {\n name: \"zero_graph\",\n description: `Get the dependency graph of a Zero program. Shows which functions depend on which other functions.`,\n parameters: {\n type: \"object\",\n properties: {\n source: {\n type: \"string\",\n description: \"Zero source code to analyze\",\n },\n path: {\n type: \"string\",\n description: \"File path hint (optional)\",\n },\n },\n required: [\"source\"],\n },\n async execute(args: Record<string, unknown>): Promise<string> {\n const source = String(args.source ?? \"\");\n const path = args.path ? String(args.path) : undefined;\n const result = await zero.graph(path ? { path, content: source } : source);\n return JSON.stringify({ symbols: result.symbols, functions: result.functions }, null, 2);\n },\n };\n\n const sizeTool: OrigenTool = {\n name: \"zero_size\",\n description: `Get size estimates for functions in a Zero program. Returns estimated binary size per function.`,\n parameters: {\n type: \"object\",\n properties: {\n source: {\n type: \"string\",\n description: \"Zero source code to size-report\",\n },\n path: {\n type: \"string\",\n description: \"File path hint (optional)\",\n },\n },\n required: [\"source\"],\n },\n async execute(args: Record<string, unknown>): Promise<string> {\n const source = String(args.source ?? \"\");\n const path = args.path ? String(args.path) : undefined;\n const result = await zero.size(path ? { path, content: source } : source);\n return JSON.stringify(result.portableRuntime ?? result.raw, null, 2);\n },\n };\n\n const fixTool: OrigenTool = {\n name: \"zero_fix\",\n description: `Plan repairs for a Zero program. Returns suggested fixes with line numbers and descriptions. Use this after zero_check reports errors.`,\n parameters: {\n type: \"object\",\n properties: {\n source: {\n type: \"string\",\n description: \"Zero source code to repair\",\n },\n path: {\n type: \"string\",\n description: \"File path hint (optional)\",\n },\n },\n required: [\"source\"],\n },\n async execute(args: Record<string, unknown>): Promise<string> {\n const source = String(args.source ?? \"\");\n const path = args.path ? String(args.path) : undefined;\n const result = await zero.fix(path ? { path, content: source } : source);\n\n if (result.ok && result.fixes.length === 0) {\n return \"✅ No fixes needed — program is clean.\";\n }\n\n const lines = result.fixes.map((f) => {\n let line = `[${f.diagnosticCode}] ${f.summary} (${f.safety})`;\n if (f.appliesEdits) line += ` [auto-fixable]`;\n return line;\n });\n\n return `📝 ${result.fixes.length} fix suggestion(s):\\n${lines.join(\"\\n\")}`;\n },\n };\n\n return [checkTool, graphTool, sizeTool, fixTool];\n}"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/compiler-tools.ts","../src/artifact-tool.ts"],"sourcesContent":["/**\n * @moikapy/origen-zero — Interactive compiler tools\n *\n * Creates four OrigenTools that let the LLM write, check, and fix\n * Zero programs during a conversation:\n * - zero_check: Check a Zero program for errors\n * - zero_graph: Get the dependency graph\n * - zero_size: Get size estimates for functions\n * - zero_fix: Plan repairs for a Zero program\n */\n\nimport type { OrigenTool } from \"@moikapy/origen\";\nimport { ZeroCompiler, TEMP_DIR } from \"./compiler.js\";\nimport type { ZeroCompilerLike, ZeroCompilerConfig } from \"./types.js\";\n\n/**\n * Create the set of interactive Zero compiler tools that let the LLM\n * write, check, and fix Zero programs during a conversation.\n *\n * Accepts either a ZeroCompilerLike instance (ZeroCompiler or ZeroHTTPCompiler)\n * or a ZeroCompilerConfig for the local CLI compiler.\n */\nexport function createZeroCompilerTools(\n compiler?: ZeroCompilerLike | ZeroCompilerConfig,\n): OrigenTool[] {\n const zero: ZeroCompilerLike = !compiler\n ? new ZeroCompiler()\n : \"check\" in compiler && typeof compiler.check === \"function\"\n ? (compiler as ZeroCompilerLike)\n : new ZeroCompiler(compiler as ZeroCompilerConfig);\n\n const checkTool: OrigenTool = {\n name: \"zero_check\",\n description: `Check a Zero program for errors. Returns structured diagnostics with repair suggestions. Write your Zero source code in the \"source\" parameter.`,\n parameters: {\n type: \"object\",\n properties: {\n source: {\n type: \"string\",\n description: \"Zero source code to check\",\n },\n path: {\n type: \"string\",\n description: \"File path hint for error reporting (optional)\",\n },\n },\n required: [\"source\"],\n },\n async execute(args: Record<string, unknown>): Promise<string> {\n const source = String(args.source ?? \"\");\n const path = args.path ? String(args.path) : undefined;\n const result = await zero.check(path ? { path, content: source } : source);\n\n if (result.ok) {\n return \"✅ Zero program checks passed with no errors.\";\n }\n\n const lines = result.diagnostics.map((d) => {\n let line = `[${d.code}] ${d.severity}: ${d.message}`;\n if (d.line) line += ` (line ${d.line})`;\n if (d.column) line += `:${d.column}`;\n if (d.repair) line += ` → Fix: ${d.repair.suggestion ?? d.repair.id}`;\n return line;\n });\n\n return `❌ Zero program has ${result.diagnostics.length} diagnostic(s):\\n${lines.join(\"\\n\")}`;\n },\n };\n\n const graphTool: OrigenTool = {\n name: \"zero_graph\",\n description: `Get the dependency graph of a Zero program. Shows which functions depend on which other functions.`,\n parameters: {\n type: \"object\",\n properties: {\n source: {\n type: \"string\",\n description: \"Zero source code to analyze\",\n },\n path: {\n type: \"string\",\n description: \"File path hint (optional)\",\n },\n },\n required: [\"source\"],\n },\n async execute(args: Record<string, unknown>): Promise<string> {\n const source = String(args.source ?? \"\");\n const path = args.path ? String(args.path) : undefined;\n const result = await zero.graph(path ? { path, content: source } : source);\n return JSON.stringify({ symbols: result.symbols, functions: result.functions }, null, 2);\n },\n };\n\n const sizeTool: OrigenTool = {\n name: \"zero_size\",\n description: `Get size estimates for functions in a Zero program. Returns estimated binary size per function.`,\n parameters: {\n type: \"object\",\n properties: {\n source: {\n type: \"string\",\n description: \"Zero source code to size-report\",\n },\n path: {\n type: \"string\",\n description: \"File path hint (optional)\",\n },\n },\n required: [\"source\"],\n },\n async execute(args: Record<string, unknown>): Promise<string> {\n const source = String(args.source ?? \"\");\n const path = args.path ? String(args.path) : undefined;\n const result = await zero.size(path ? { path, content: source } : source);\n return JSON.stringify(result.portableRuntime ?? result.raw, null, 2);\n },\n };\n\n const fixTool: OrigenTool = {\n name: \"zero_fix\",\n description: `Plan repairs for a Zero program. Returns suggested fixes with line numbers and descriptions. Use this after zero_check reports errors.`,\n parameters: {\n type: \"object\",\n properties: {\n source: {\n type: \"string\",\n description: \"Zero source code to repair\",\n },\n path: {\n type: \"string\",\n description: \"File path hint (optional)\",\n },\n },\n required: [\"source\"],\n },\n async execute(args: Record<string, unknown>): Promise<string> {\n const source = String(args.source ?? \"\");\n const path = args.path ? String(args.path) : undefined;\n const result = await zero.fix(path ? { path, content: source } : source);\n\n if (result.ok && result.fixes.length === 0) {\n return \"✅ No fixes needed — program is clean.\";\n }\n\n const lines = result.fixes.map((f) => {\n let line = `[${f.diagnosticCode}] ${f.summary} (${f.safety})`;\n if (f.appliesEdits) line += ` [auto-fixable]`;\n return line;\n });\n\n return `📝 ${result.fixes.length} fix suggestion(s):\\n${lines.join(\"\\n\")}`;\n },\n };\n\n return [checkTool, graphTool, sizeTool, fixTool];\n}","/**\n * @moikapy/origen-zero — Artifact-aware tool creation\n *\n * The getOrCreateTool helper checks the artifact store for a cached WASM\n * module before using provided bytes. If the artifact exists and the source\n * hash matches, it reuses the cached bytes. If not, it stores the provided\n * bytes for future sessions.\n *\n * This is the \"compile once, use forever\" pattern that makes Zero tools\n * practical in production — no recompilation across sessions.\n *\n * The caller is responsible for obtaining WASM bytes (via ZeroCompiler,\n * ZeroHTTPCompiler, or any other method). getOrCreateTool handles caching.\n */\n\nimport type { ArtifactStore } from \"@moikapy/origen\";\nimport type { ZeroSourceFile } from \"./types.js\";\nimport { createZeroWASMTool, type ZeroWASMToolConfig } from \"./wasm-tool.js\";\nimport type { OrigenTool } from \"@moikapy/origen\";\n\n// ── Options ─────────────────────────────────────────────────────────────\n\nexport interface GetOrCreateToolOptions {\n /** Name for the tool (used as artifact key prefix and function name). */\n name: string;\n /** The compiled WASM bytes. If the artifact store has a cache hit, this is skipped. */\n wasmBytes: ArrayBuffer;\n /** Artifact store for caching compiled WASM. */\n artifactStore: ArtifactStore;\n /** Zero source code (used to derive the content hash for cache key). */\n source: string | ZeroSourceFile;\n /** Custom WASM tool config overrides (description, parameters, runtimeConfig). */\n toolConfig?: Partial<Pick<ZeroWASMToolConfig, \"description\" | \"parameters\" | \"runtimeConfig\">>;\n /** Content type for the artifact. Default: \"application/wasm\". */\n contentType?: string;\n /** Whether to force re-storage even if cached. Default: false. */\n forceRecompile?: boolean;\n /** Compiler version tag for cache invalidation. Default: \"wasm32-web\". */\n compilerVersion?: string;\n}\n\n// ── getOrCreateTool ─────────────────────────────────────────────────────\n\n/**\n * Get or create a Zero WASM tool, using the artifact store as a cache.\n *\n * 1. Compute source hash → derive artifact key\n * 2. Check artifact store for cached WASM bytes\n * 3. If cached and hash matches → instantiate from cached bytes\n * 4. If cache miss → store provided bytes → instantiate\n *\n * The caller is responsible for compilation. This function handles caching\n * and instantiation, so it works in any environment (Workers, Node, Bun).\n */\nexport async function getOrCreateTool(\n options: GetOrCreateToolOptions,\n): Promise<OrigenTool> {\n const {\n name,\n wasmBytes,\n artifactStore,\n source,\n toolConfig,\n contentType = \"application/wasm\",\n forceRecompile = false,\n compilerVersion = \"wasm32-web\",\n } = options;\n\n // Derive a content-addressable key from the source\n const sourceString = typeof source === \"string\" ? source : source.content ?? \"\";\n const sourceHash = await hashSource(sourceString);\n const key = `zero/${name}-${sourceHash.slice(0, 12)}`;\n\n // Step 1: Check cache (skip if forceRecompile)\n if (!forceRecompile) {\n const cached = await artifactStore.get(key);\n if (cached) {\n return createZeroWASMTool({\n functionName: name,\n description: toolConfig?.description ?? `Zero tool: ${name}`,\n wasmBytes: cached,\n parameters: toolConfig?.parameters,\n runtimeConfig: toolConfig?.runtimeConfig,\n });\n }\n }\n\n // Step 2: Store the WASM bytes in the artifact cache\n await artifactStore.put(key, wasmBytes, {\n contentType,\n sourceHash,\n compilerVersion,\n });\n\n // Step 3: Create and return the tool\n return createZeroWASMTool({\n functionName: name,\n description: toolConfig?.description ?? `Zero tool: ${name}`,\n wasmBytes,\n parameters: toolConfig?.parameters,\n runtimeConfig: toolConfig?.runtimeConfig,\n });\n}\n\n// ── Helpers ─────────────────────────────────────────────────────────────\n\n/** Compute SHA-256 hash of source string (content-addressable key). */\nasync function hashSource(source: string): Promise<string> {\n const encoded = new TextEncoder().encode(source);\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encoded);\n const hashArray = new Uint8Array(hashBuffer);\n return Array.from(hashArray)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moikapy/origen-zero",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Bridge package connecting Origen agents to ZeroLang compiler and runtime",
|
|
6
6
|
"license": "MIT",
|
|
@@ -49,15 +49,15 @@
|
|
|
49
49
|
"prepublishOnly": "bun run build:release"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
|
-
"@moikapy/origen": "^0.
|
|
52
|
+
"@moikapy/origen": "^0.7.0"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"zod": "^4.4.2"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@moikapy/origen": "^0.
|
|
58
|
+
"@moikapy/origen": "^0.7.2",
|
|
59
59
|
"tsup": "^8.5.1",
|
|
60
60
|
"typescript": "^5",
|
|
61
61
|
"vitest": "^3"
|
|
62
62
|
}
|
|
63
|
-
}
|
|
63
|
+
}
|