From 2ff1d435d8cc87e4e683a539441de37399b9af49 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sun, 6 Sep 2026 01:43:55 +0200 Subject: [PATCH] Add the Claude SDK sidecar: framing, the closed schema converter, the query MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `sidecar/claude-sdk` is the repo's second TypeScript package, wired to the root only through `npm --prefix`. It reads length-prefixed MessagePack frames on stdin, runs one SDK query, forwards every tool call to Rust, and returns Rust's answer to the model verbatim. It computes no tool result, reads no credential, logs no prompt, argument, or result, and writes nothing outside its own stdout. The query is opened with a custom system prompt, `settingSources: []`, `tools: []`, `strictMcpConfig`, `persistSession: false`, and `alwaysLoad` on every tool, so no CLAUDE.md, settings file, output style, built-in tool, or persisted transcript reaches a caller-derived prompt. `schema.ts` converts exactly the grammar `tool_schema.rs` emits and throws on anything else, so an emitter that outgrows it fails a test rather than registering a looser tool. Two Rust tests publish the fixtures the sidecar tests read — the frame bytes and every real `parameters_json` — so the halves cannot drift apart silently. Dependencies are exact-pinned: @anthropic-ai/claude-agent-sdk 0.3.261, @msgpack/msgpack 3.1.3, zod 4.5.4, and dev typescript 5.9.3 with @types/node 24.13.3. `engines.node` is the installed major. Co-Authored-By: Claude Opus 5 --- .gitignore | 1 + .../src/world/sdk_inference.rs | 46 + package.json | 2 + sidecar/claude-sdk/package-lock.json | 1558 +++++++++++++++++ sidecar/claude-sdk/package.json | 18 + sidecar/claude-sdk/src/frames.ts | 158 ++ sidecar/claude-sdk/src/main.ts | 491 ++++++ sidecar/claude-sdk/src/schema.ts | 134 ++ sidecar/claude-sdk/test/frames.test.ts | 99 ++ sidecar/claude-sdk/test/lowering.test.ts | 113 ++ sidecar/claude-sdk/test/schema.test.ts | 95 + sidecar/claude-sdk/test/schemas.json | 178 ++ sidecar/claude-sdk/tsconfig.json | 18 + 13 files changed, 2911 insertions(+) create mode 100644 sidecar/claude-sdk/package-lock.json create mode 100644 sidecar/claude-sdk/package.json create mode 100644 sidecar/claude-sdk/src/frames.ts create mode 100644 sidecar/claude-sdk/src/main.ts create mode 100644 sidecar/claude-sdk/src/schema.ts create mode 100644 sidecar/claude-sdk/test/frames.test.ts create mode 100644 sidecar/claude-sdk/test/lowering.test.ts create mode 100644 sidecar/claude-sdk/test/schema.test.ts create mode 100644 sidecar/claude-sdk/test/schemas.json create mode 100644 sidecar/claude-sdk/tsconfig.json diff --git a/.gitignore b/.gitignore index a77b285..42aa0e8 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ __pycache__/ .venv/ node_modules/ web/dist/ +sidecar/claude-sdk/dist/ state/scratch-compaction-*.md experiments/images/ target/ diff --git a/crates/ghostlight-dungeon/src/world/sdk_inference.rs b/crates/ghostlight-dungeon/src/world/sdk_inference.rs index 4ba19da..c14ef7c 100644 --- a/crates/ghostlight-dungeon/src/world/sdk_inference.rs +++ b/crates/ghostlight-dungeon/src/world/sdk_inference.rs @@ -1377,6 +1377,52 @@ mod tests { ); } + /// The Rust half of the sidecar's schema-grammar pair (spec test 17): + /// publishes every `parameters_json` the two catalogs actually emit, so the + /// sidecar's closed converter is tested against real strings rather than + /// hand-written ones. + #[test] + fn schema_fixtures_match_the_checked_in_sidecar_grammar() { + let granted = vec![AffordanceSnapshot { + id: AffordanceId::issue(), + entry: kernel_speak_entry(), + }]; + let mut emitted: Vec<(String, String)> = patch_tools() + .into_iter() + .chain(catalog_tools("", &granted)) + .chain(catalog_tools("c3__", &granted)) + .map(|tool| (tool.name, tool.parameters_json)) + .collect(); + emitted.sort(); + emitted.dedup(); + let rendered = serde_json::to_string_pretty( + &emitted + .into_iter() + .map( + |(name, schema)| serde_json::json!({ "name": name, "parameters_json": schema }), + ) + .collect::>(), + ) + .unwrap(); + let path = std::path::Path::new(env!("CARGO_MANIFEST_DIR")) + .join("../../sidecar/claude-sdk/test/schemas.json"); + if std::env::var_os("GHOSTLIGHT_WRITE_SIDECAR_FIXTURES").is_some() { + std::fs::create_dir_all(path.parent().unwrap()).unwrap(); + std::fs::write(&path, format!("{rendered}\n")).unwrap(); + } + let on_disk = std::fs::read_to_string(&path).unwrap_or_else(|error| { + panic!( + "the sidecar schema fixture {} is missing ({error}); regenerate with GHOSTLIGHT_WRITE_SIDECAR_FIXTURES=1", + path.display() + ) + }); + assert_eq!( + on_disk.replace("\r\n", "\n"), + format!("{rendered}\n"), + "the emitted tool schemas drifted from the sidecar's converter fixture" + ); + } + /// The Rust half of the sidecar's frame round-trip pair (spec test 18): /// pins the exact `rmp_serde::to_vec_named` bytes the TypeScript decoder is /// tested against, so the two halves cannot drift apart silently. diff --git a/package.json b/package.json index 876fbad..29d2640 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,8 @@ "dungeon:build": "cargo build --workspace && npm --prefix web run build", "dungeon:test": "cargo test --workspace && npm --prefix web run build", "dungeon:run": "cargo run -p ghostlight-dungeon", + "sdk:build": "npm --prefix sidecar/claude-sdk run build", + "sdk:test": "npm --prefix sidecar/claude-sdk test", "state:status": "\"C:\\Users\\Meta\\.cache\\codex-runtimes\\codex-primary-runtime\\dependencies\\python\\python.exe\" .\\tools\\ghostlight_state.py status", "state:prepare-compaction": "\"C:\\Users\\Meta\\.cache\\codex-runtimes\\codex-primary-runtime\\dependencies\\python\\python.exe\" .\\tools\\ghostlight_prepare_compaction.py", "agent-state:validate": "\"C:\\Users\\Meta\\.cache\\codex-runtimes\\codex-primary-runtime\\dependencies\\python\\python.exe\" .\\tools\\validate_agent_state.py", diff --git a/sidecar/claude-sdk/package-lock.json b/sidecar/claude-sdk/package-lock.json new file mode 100644 index 0000000..fd71505 --- /dev/null +++ b/sidecar/claude-sdk/package-lock.json @@ -0,0 +1,1558 @@ +{ + "name": "ghostlight-claude-sdk-sidecar", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "ghostlight-claude-sdk-sidecar", + "version": "0.1.0", + "dependencies": { + "@anthropic-ai/claude-agent-sdk": "0.3.261", + "@msgpack/msgpack": "3.1.3", + "zod": "4.5.4" + }, + "devDependencies": { + "@types/node": "24.13.3", + "typescript": "5.9.3" + }, + "engines": { + "node": ">=24 <25" + } + }, + "node_modules/@anthropic-ai/claude-agent-sdk": { + "version": "0.3.261", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.3.261.tgz", + "integrity": "sha512-CDG9z14JVKYRHjpp/g6zJ2k8xM5uSoRgjGdpTiK9woLDZxXtXcxV93ipCh55jQ3REj7M7H3GieMsETGZXB/ydw==", + "license": "SEE LICENSE IN README.md", + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "@anthropic-ai/claude-agent-sdk-darwin-arm64": "0.3.261", + "@anthropic-ai/claude-agent-sdk-darwin-x64": "0.3.261", + "@anthropic-ai/claude-agent-sdk-linux-arm64": "0.3.261", + "@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "0.3.261", + "@anthropic-ai/claude-agent-sdk-linux-x64": "0.3.261", + "@anthropic-ai/claude-agent-sdk-linux-x64-musl": "0.3.261", + "@anthropic-ai/claude-agent-sdk-win32-arm64": "0.3.261", + "@anthropic-ai/claude-agent-sdk-win32-x64": "0.3.261" + }, + "peerDependencies": { + "@anthropic-ai/sdk": ">=0.93.0", + "@modelcontextprotocol/sdk": "^1.29.0", + "zod": "^4.0.0" + } + }, + "node_modules/@anthropic-ai/claude-agent-sdk-darwin-arm64": { + "version": "0.3.261", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-arm64/-/claude-agent-sdk-darwin-arm64-0.3.261.tgz", + "integrity": "sha512-oI8SPd6g+xUF6EnEqIInxz5CjSSJXoDlaqefjbSJvTFCawGGBhxlQs0g9jzsYou6Rdu+i2tJBToJZLsKSnN/0Q==", + "cpu": [ + "arm64" + ], + "license": "SEE LICENSE IN LICENSE.md", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@anthropic-ai/claude-agent-sdk-darwin-x64": { + "version": "0.3.261", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-x64/-/claude-agent-sdk-darwin-x64-0.3.261.tgz", + "integrity": "sha512-PODd45XbrKxwngebFmc60Xd68QDb7xCo+0toYTJKfFumU24b/JT2WpO5sTSfc5+fahd/P11q0uF5v9YeSjWmjg==", + "cpu": [ + "x64" + ], + "license": "SEE LICENSE IN LICENSE.md", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@anthropic-ai/claude-agent-sdk-linux-arm64": { + "version": "0.3.261", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64/-/claude-agent-sdk-linux-arm64-0.3.261.tgz", + "integrity": "sha512-C+y3N3MD2ExrwrbCYcbLdM39VkbJkQKUv23oubvoZr0CtHiH2LESyUUC3JsUbHJ1TRKO8fbzLqvPkjZ9UsBIcw==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "SEE LICENSE IN LICENSE.md", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@anthropic-ai/claude-agent-sdk-linux-arm64-musl": { + "version": "0.3.261", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64-musl/-/claude-agent-sdk-linux-arm64-musl-0.3.261.tgz", + "integrity": "sha512-BAUG2EremVyy8bA14jKF35VRJjGE2TqREpFerA0CRBWg9/sUJZVWdmIRXUiXCKh0MvenPRUJbEgwcHFllQETOw==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "SEE LICENSE IN LICENSE.md", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@anthropic-ai/claude-agent-sdk-linux-x64": { + "version": "0.3.261", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64/-/claude-agent-sdk-linux-x64-0.3.261.tgz", + "integrity": "sha512-MdojjfN0HJHT0JMiZJ6rTj3/ODNi5OdY0py1JZmVVEVTYOdvgH6OG3oy9/BmmJTx0mp/BBCHbOGNpibtnqE+1g==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "SEE LICENSE IN LICENSE.md", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@anthropic-ai/claude-agent-sdk-linux-x64-musl": { + "version": "0.3.261", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64-musl/-/claude-agent-sdk-linux-x64-musl-0.3.261.tgz", + "integrity": "sha512-H7sCtM7X9OyQ+ZCEhh6TY/Z1i+5WIn8YyHRVJ2LrZRFOaszPeDbl1SzSxxuOd5ibwJZA9gx+2uQ78dx+bDkQUA==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "SEE LICENSE IN LICENSE.md", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@anthropic-ai/claude-agent-sdk-win32-arm64": { + "version": "0.3.261", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-arm64/-/claude-agent-sdk-win32-arm64-0.3.261.tgz", + "integrity": "sha512-zvZfec4+wDooqF/ZOI3lthgq9WfZLIrSserS6tULpBqCLKNRbTIpARDcljY7SrRuMGb3Ex+LFn/yXazgajpwzg==", + "cpu": [ + "arm64" + ], + "license": "SEE LICENSE IN LICENSE.md", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@anthropic-ai/claude-agent-sdk-win32-x64": { + "version": "0.3.261", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-x64/-/claude-agent-sdk-win32-x64-0.3.261.tgz", + "integrity": "sha512-tepSwNpNsl4tyDdJ1+YcRXeY7VZNirPqpCtKDuh2YVwDkMfzQevCqojURtACAdLwI8BUXeOGaecwRbh3zoSUtA==", + "cpu": [ + "x64" + ], + "license": "SEE LICENSE IN LICENSE.md", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@anthropic-ai/sdk": { + "version": "0.124.0", + "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.124.0.tgz", + "integrity": "sha512-cN5O8i9UVxHeOQAzj/XjshWXG8KiibJDw9OGpH2Z/eR3n/RBxdoLxDJOcfqAJWvjaMDFfHTBADU04hWRJVkDyA==", + "license": "MIT", + "peer": true, + "dependencies": { + "json-schema-to-ts": "^3.1.1", + "standardwebhooks": "^1.0.0" + }, + "bin": { + "anthropic-ai-sdk": "bin/cli" + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "zod": { + "optional": true + } + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@hono/node-server": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-2.1.1.tgz", + "integrity": "sha512-ELuehkj5VCBdgEw9zs+ivkKwyzzUCSQuE96YmiPvn1ECBoZCczbFXJLeEGMTYjphP6gydh4pHMqEYPVMYUVgQg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "hono": "^4" + } + }, + "node_modules/@modelcontextprotocol/sdk": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.30.0.tgz", + "integrity": "sha512-xKd8OIzlqNzcqcNumGAa6g+PW2kjD5vrpcKOnfldAUPP3j7lnqMPwlTXQm8gF+UwH72z0lqaRbjr9hqGz0eITA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@hono/node-server": "^1.19.9 || ^2.0.5", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", + "content-type": "^1.0.5", + "cors": "^2.8.5", + "cross-spawn": "^7.0.5", + "eventsource": "^3.0.2", + "eventsource-parser": "^3.0.0", + "express": "^5.2.1", + "express-rate-limit": "^8.2.1", + "hono": "^4.11.4", + "jose": "^6.1.3", + "json-schema-typed": "^8.0.2", + "pkce-challenge": "^5.0.0", + "raw-body": "^3.0.0", + "zod": "^3.25 || ^4.0", + "zod-to-json-schema": "^3.25.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@cfworker/json-schema": "^4.1.1", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "@cfworker/json-schema": { + "optional": true + }, + "zod": { + "optional": false + } + } + }, + "node_modules/@msgpack/msgpack": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@msgpack/msgpack/-/msgpack-3.1.3.tgz", + "integrity": "sha512-47XIizs9XZXvuJgoaJUIE2lFoID8ugvc0jzSHP+Ptfk8nTbnR8g788wv48N03Kx0UkAv559HWRQ3yzOgzlRNUA==", + "license": "ISC", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@stablelib/base64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/base64/-/base64-1.0.1.tgz", + "integrity": "sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==", + "license": "MIT", + "peer": true + }, + "node_modules/@types/node": { + "version": "24.13.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.3.tgz", + "integrity": "sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.18.0" + } + }, + "node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", + "peer": true, + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/body-parser": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz", + "integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==", + "license": "MIT", + "peer": true, + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^2.0.0", + "debug": "^4.4.3", + "http-errors": "^2.0.1", + "iconv-lite": "^0.7.2", + "on-finished": "^2.4.1", + "qs": "^6.15.2", + "raw-body": "^3.0.2", + "type-is": "^2.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/body-parser/node_modules/content-type": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz", + "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/content-disposition": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", + "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/cors": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "license": "MIT", + "peer": true, + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "peer": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "peer": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT", + "peer": true + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "license": "MIT", + "peer": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT", + "peer": true + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventsource": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", + "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", + "license": "MIT", + "peer": true, + "dependencies": { + "eventsource-parser": "^3.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/eventsource-parser": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.1.1.tgz", + "integrity": "sha512-EKN1vKAMcZ8MlYMpaNuxN6R9yakzH6uajHcHVTqWJzvu5pWw9DyhbP35HH8MVBQ+dZjAfDxk+A8NiR9KWaXiyQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/express": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "license": "MIT", + "peer": true, + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express-rate-limit": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.7.0.tgz", + "integrity": "sha512-hOwV7WOxXfjRpAM1DSJWZDXx3GhplwD8IfwuwvogD8i1Qnkgosw/H45s4ZnFAUHDAhPjlY9hLBvJhKmGMyY26g==", + "license": "MIT", + "peer": true, + "dependencies": { + "debug": "^4.4.3", + "ip-address": "^10.2.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT", + "peer": true + }, + "node_modules/fast-sha256": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-sha256/-/fast-sha256-1.3.0.tgz", + "integrity": "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==", + "license": "Unlicense", + "peer": true + }, + "node_modules/fast-uri": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.7.tgz", + "integrity": "sha512-dOvZVzjdZdz7phd9v6jCbwxrBW3fK6n8Rc0CtdmM4bumzMnxywBYhuph6J819RRw/ku+rLbelwfMunktuzVVHg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "license": "MIT", + "peer": true, + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "peer": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "license": "MIT", + "peer": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hono": { + "version": "4.13.7", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.13.7.tgz", + "integrity": "sha512-c8/gF9ac8Y78/agExVocyLevgR+JlpNB444Py0FSX8pJoPdYUfUzRcXtYEYGwt6l19qIlVZPN5Mfsw9jFShmQQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=16.9.0" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", + "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC", + "peer": true + }, + "node_modules/ip-address": { + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.7.0.tgz", + "integrity": "sha512-BGFsyJd5mpXp3rK6jIdADLNgpJUK1jnjzvYF8lK+VyDab9JAmqN0YOKDdP17HlgKb2+ehPgDc8EtnRLbGCAMhA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT", + "peer": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC", + "peer": true + }, + "node_modules/jose": { + "version": "6.2.12", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.12.tgz", + "integrity": "sha512-9NiFmJEex0sy2Dk58j2UGBSHgUs2ypF9eZSu4L6vjOX3Dp96Sw1F3uL+H+D1sx02jZZdzUT0HgvCy59CuvXcWw==", + "license": "MIT", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/json-schema-to-ts": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-3.1.1.tgz", + "integrity": "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==", + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.18.3", + "ts-algebra": "^2.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT", + "peer": true + }, + "node_modules/json-schema-typed": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "license": "BSD-2-Clause", + "peer": true + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.1.tgz", + "integrity": "sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "peer": true, + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT", + "peer": true + }, + "node_modules/negotiator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.1.0.tgz", + "integrity": "sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg==", + "license": "MIT", + "peer": true, + "dependencies": { + "content-type": "^2.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/negotiator/node_modules/content-type": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz", + "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "peer": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "peer": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-to-regexp": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", + "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", + "license": "MIT", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/pkce-challenge": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", + "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "peer": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.16.0.tgz", + "integrity": "sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.3.0.tgz", + "integrity": "sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "license": "MIT", + "peer": true, + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT", + "peer": true + }, + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/serve-static": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", + "license": "MIT", + "peer": true, + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC", + "peer": true + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "peer": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "license": "MIT", + "peer": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/standardwebhooks": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/standardwebhooks/-/standardwebhooks-1.1.1.tgz", + "integrity": "sha512-bCbX9ZEyFkWPsRz7Bl3NuQUJohmwGSev/yhr7vhaGPlc4AfIrspIRa6cPTBuI1ItmrTDJ4d/S2hCsfe4+vQGnQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@stablelib/base64": "^1.0.0", + "fast-sha256": "^1.3.0" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ts-algebra": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ts-algebra/-/ts-algebra-2.0.0.tgz", + "integrity": "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==", + "license": "MIT", + "peer": true + }, + "node_modules/type-is": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz", + "integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==", + "license": "MIT", + "peer": true, + "dependencies": { + "content-type": "^2.0.0", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/type-is/node_modules/content-type": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz", + "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "peer": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC", + "peer": true + }, + "node_modules/zod": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.5.4.tgz", + "integrity": "sha512-sC95tT5iHHH9gtpj6A81kh+NEaRAUFN+qlUPDUbRfOMvNf5QCBqsb3WgvnpVtK5Y+4UfA6KqufotuTvMGiTlsA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.25.2", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz", + "integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==", + "license": "ISC", + "peer": true, + "peerDependencies": { + "zod": "^3.25.28 || ^4" + } + } + } +} diff --git a/sidecar/claude-sdk/package.json b/sidecar/claude-sdk/package.json new file mode 100644 index 0000000..4c104bb --- /dev/null +++ b/sidecar/claude-sdk/package.json @@ -0,0 +1,18 @@ +{ + "name": "ghostlight-claude-sdk-sidecar", + "version": "0.1.0", + "private": true, + "type": "module", + "description": "Ghostlight's Claude Agent SDK sidecar. Reads length-prefixed MessagePack frames on stdin, runs one SDK query, and answers every tool call by asking Rust. It computes nothing and holds no credential.", + "engines": { "node": ">=24 <25" }, + "scripts": { + "build": "tsc -p .", + "test": "node --experimental-strip-types --test \"test/**/*.test.ts\"" + }, + "dependencies": { + "@anthropic-ai/claude-agent-sdk": "0.3.261", + "@msgpack/msgpack": "3.1.3", + "zod": "4.5.4" + }, + "devDependencies": { "@types/node": "24.13.3", "typescript": "5.9.3" } +} diff --git a/sidecar/claude-sdk/src/frames.ts b/sidecar/claude-sdk/src/frames.ts new file mode 100644 index 0000000..dbe5fa7 --- /dev/null +++ b/sidecar/claude-sdk/src/frames.ts @@ -0,0 +1,158 @@ +// The wire between Rust and this sidecar: a 4-byte big-endian length prefix +// followed by MessagePack with string keys, matching `rmp_serde::to_vec_named`. +// Rust owns the shapes; this file only encodes and decodes them. + +import { decode, encode } from "@msgpack/msgpack"; + +/** The connector's own frame cap. Rust refuses anything larger on its side too. */ +export const MAX_FRAME_BYTES = 1_052_672; + +export interface SidecarTool { + name: string; + description: string; + parameters_json: string; +} + +export type SidecarEvent = + | { kind: "text"; text: string } + | { + kind: "tool_call"; + call_id: string; + name: string; + arguments: string; + dispatched: boolean; + }; + +export interface SdkModelUsage { + model: string; + input_tokens: number; + output_tokens: number; + cache_read_input_tokens: number; + cache_creation_input_tokens: number; +} + +export interface SdkResultMaterial { + session_id: string; + result_uuid: string; + subtype: string; + stop_reason: string | null; + num_turns: number; + assistant_message_uuids: string[]; + assistant_request_ids: string[]; + usage: SdkModelUsage[]; + total_cost_usd_estimate: string; +} + +/** + * The closed set of failures this sidecar may name. It reports a reason; Rust + * assigns the disposition, so nothing here can quarantine the world. + */ +export type SidecarFaultReason = + | "rate_limited" + | "overloaded" + | "server_error" + | "api_timeout" + | "authentication_failed" + | "org_not_allowed" + | "billing_error" + | "invalid_request" + | "model_not_found" + | "max_output_tokens" + | "max_budget_usd" + | "execution_error" + | "unknown" + | "protocol_violation" + | "tool_registration_failed" + | "turn_cap_refused"; + +export type SidecarFrame = + | { + kind: "query"; + query_id: number; + model: string; + instructions: string; + prompt: string; + transcript: string[]; + tools: SidecarTool[]; + effort: string | null; + max_output_tokens: number | null; + turn_cap: number; + } + | { + kind: "tool_call"; + query_id: number; + call_id: string; + name: string; + arguments: string; + } + | { + kind: "tool_result"; + query_id: number; + call_id: string; + output: string; + } + | { + kind: "output"; + query_id: number; + events: SidecarEvent[]; + receipt: SdkResultMaterial; + } + | { + kind: "fault"; + query_id: number; + reason: SidecarFaultReason; + detail: string; + }; + +export function encodeFrame(frame: SidecarFrame): Uint8Array { + const body = encode(frame, { useBigInt64: false }); + if (body.length > MAX_FRAME_BYTES) { + throw new Error(`frame of ${body.length} bytes exceeds ${MAX_FRAME_BYTES}`); + } + const framed = new Uint8Array(4 + body.length); + new DataView(framed.buffer).setUint32(0, body.length, false); + framed.set(body, 4); + return framed; +} + +export function decodeFrameBody(body: Uint8Array): SidecarFrame { + const value = decode(body); + if (typeof value !== "object" || value === null || !("kind" in value)) { + throw new Error("a sidecar frame decoded to something without a kind"); + } + return value as SidecarFrame; +} + +/** Reassembles frames from an arbitrarily chunked byte stream. */ +export class FrameReader { + #buffer = new Uint8Array(0); + + push(chunk: Uint8Array): void { + const grown = new Uint8Array(this.#buffer.length + chunk.length); + grown.set(this.#buffer, 0); + grown.set(chunk, this.#buffer.length); + this.#buffer = grown; + } + + /** The next whole frame, or null while one is still arriving. */ + next(): SidecarFrame | null { + if (this.#buffer.length < 4) { + return null; + } + const length = new DataView( + this.#buffer.buffer, + this.#buffer.byteOffset, + 4, + ).getUint32(0, false); + if (length === 0 || length > MAX_FRAME_BYTES) { + throw new Error(`frame length ${length} is outside 1..=${MAX_FRAME_BYTES}`); + } + if (this.#buffer.length < 4 + length) { + return null; + } + const body = this.#buffer.subarray(4, 4 + length); + const frame = decodeFrameBody(body); + this.#buffer = this.#buffer.slice(4 + length); + return frame; + } +} diff --git a/sidecar/claude-sdk/src/main.ts b/sidecar/claude-sdk/src/main.ts new file mode 100644 index 0000000..0582881 --- /dev/null +++ b/sidecar/claude-sdk/src/main.ts @@ -0,0 +1,491 @@ +// Ghostlight's Claude Agent SDK sidecar. +// +// One query at a time, one child process for many queries. Every tool call is +// forwarded to Rust and answered by Rust: this process computes no tool result, +// reads no credential, logs no prompt, argument, or result, and writes nothing +// outside its own stdout. +// +// Operator prerequisites, none of which Ghostlight performs: install the Claude +// Code CLI, sign in with `/login` or mint a token with `claude setup-token`, +// verify with one plain `claude -p` query, then `npm --prefix sidecar/claude-sdk +// install` and `npm run sdk:build`. The SDK finds that login on its own through +// the ambient environment. Nothing in this repository reads, copies, forwards, +// or logs the credential. +// +// Runtime binding: `GHOSTLIGHT_SDK_SIDECAR` is this file's built path +// (`sidecar/claude-sdk/dist/main.js`) and `GHOSTLIGHT_SDK_MODEL_PREFIX` +// (default `claude`) is the model-name prefix that routes a lane here. + +import { + createSdkMcpServer, + query, + tool, + type Options, +} from "@anthropic-ai/claude-agent-sdk"; +import { + FrameReader, + encodeFrame, + type SdkModelUsage, + type SdkResultMaterial, + type SidecarEvent, + type SidecarFaultReason, + type SidecarFrame, + type SidecarTool, +} from "./frames.ts"; +import { toolRawShape } from "./schema.ts"; +import { resolve } from "node:path"; +import { pathToFileURL } from "node:url"; + +const SERVER_NAME = "ghostlight"; +const QUALIFIED_PREFIX = `mcp__${SERVER_NAME}__`; +/** The header a prior round's rendered transcript is folded under. */ +const TRANSCRIPT_HEADER = + "Earlier turns in this same request, as they happened:"; +/** No deadline tighter than the Rust side's own response timeout. */ +const RENDEZVOUS_TIMEOUT_MS = 900_000; +/** The largest round budget any Ghostlight lane carries. */ +const MAX_TURN_CAP = 24; + +export class SidecarFault extends Error { + readonly reason: SidecarFaultReason; + + constructor(reason: SidecarFaultReason, detail: string) { + super(detail); + this.reason = reason; + } +} + +interface Dispatch { + call_id: string; + name: string; + arguments: string; +} + +/** One in-flight query's rendezvous with Rust. */ +export class QuerySession { + readonly dispatches: Dispatch[] = []; + readonly queryId: number; + readonly #pending = new Map void>(); + readonly #write: (frame: SidecarFrame) => void; + #nextCall = 0; + + constructor(queryId: number, write: (frame: SidecarFrame) => void) { + this.queryId = queryId; + this.#write = write; + } + + /** Sends one call to Rust and resolves when Rust answers it. */ + async ask(name: string, args: unknown): Promise { + const call_id = `c${this.#nextCall++}`; + const argumentsJson = JSON.stringify(args ?? {}); + this.dispatches.push({ call_id, name, arguments: argumentsJson }); + const answer = new Promise((resolve) => { + this.#pending.set(call_id, resolve); + }); + this.#write({ + kind: "tool_call", + query_id: this.queryId, + call_id, + name, + arguments: argumentsJson, + }); + return answer; + } + + answer(call_id: string, output: string): void { + const resolve = this.#pending.get(call_id); + if (!resolve) { + throw new SidecarFault( + "protocol_violation", + `a tool result arrived for the unissued call ${call_id}`, + ); + } + this.#pending.delete(call_id); + resolve(output); + } +} + +function apiRetryReason(category: unknown): SidecarFaultReason { + switch (category) { + case "rate_limit": + return "rate_limited"; + case "overloaded": + return "overloaded"; + case "server_error": + return "server_error"; + case "authentication_failed": + return "authentication_failed"; + case "oauth_org_not_allowed": + return "org_not_allowed"; + case "billing_error": + return "billing_error"; + case "invalid_request": + return "invalid_request"; + case "model_not_found": + return "model_not_found"; + case "max_output_tokens": + return "max_output_tokens"; + default: + return "unknown"; + } +} + +function resultReason(subtype: string, apiErrorStatus: unknown): SidecarFaultReason { + if (typeof apiErrorStatus === "number") { + if (apiErrorStatus === 429) { + return "rate_limited"; + } + if (apiErrorStatus >= 500) { + return "server_error"; + } + } + switch (subtype) { + case "error_max_budget_usd": + return "max_budget_usd"; + case "error_during_execution": + case "error_max_structured_output_retries": + return "execution_error"; + default: + return "unknown"; + } +} + +function usageRows(modelUsage: unknown): SdkModelUsage[] { + if (typeof modelUsage !== "object" || modelUsage === null) { + return []; + } + return Object.entries(modelUsage as Record>).map( + ([model, row]) => ({ + model, + input_tokens: Number(row?.inputTokens ?? row?.input_tokens ?? 0), + output_tokens: Number(row?.outputTokens ?? row?.output_tokens ?? 0), + cache_read_input_tokens: Number( + row?.cacheReadInputTokens ?? row?.cache_read_input_tokens ?? 0, + ), + cache_creation_input_tokens: Number( + row?.cacheCreationInputTokens ?? row?.cache_creation_input_tokens ?? 0, + ), + }), + ); +} + +/** + * The `query()` options one frame lowers to. Exported so a test can assert the + * hygiene — no CLAUDE.md, no settings, no built-in tools, no persisted session + * — against a stub instead of a live query. + */ +export function lowerQuery( + frame: Extract, + session: QuerySession, +): { prompt: string; options: Options } { + if (frame.turn_cap < 1 || frame.turn_cap > MAX_TURN_CAP) { + throw new SidecarFault( + "turn_cap_refused", + `turn cap ${frame.turn_cap} is outside 1..=${MAX_TURN_CAP}`, + ); + } + const tools = frame.tools.map((entry: SidecarTool) => { + let shape; + try { + shape = toolRawShape(entry.parameters_json, entry.name); + } catch (error) { + throw new SidecarFault("tool_registration_failed", String(error)); + } + return tool( + entry.name, + entry.description, + shape, + async (args: unknown) => ({ + content: [ + { type: "text" as const, text: await session.ask(entry.name, args) }, + ], + }), + { alwaysLoad: true }, + ); + }); + const prompt = frame.transcript.length + ? `${frame.prompt}\n\n${TRANSCRIPT_HEADER}\n${frame.transcript.join("\n")}` + : frame.prompt; + const options: Record = { + systemPrompt: { type: "custom", prompt: frame.instructions }, + // No CLAUDE.md, no settings.json, no output styles, no built-in tools. + settingSources: [], + tools: [], + strictMcpConfig: true, + model: frame.model, + maxTurns: frame.turn_cap, + includePartialMessages: false, + persistSession: false, + }; + if (frame.effort) { + options.effort = frame.effort; + } + if (tools.length) { + options.mcpServers = { + [SERVER_NAME]: createSdkMcpServer({ + name: SERVER_NAME, + tools, + alwaysLoad: true, + timeout: RENDEZVOUS_TIMEOUT_MS, + }), + }; + options.allowedTools = [`${QUALIFIED_PREFIX}*`]; + } + return { prompt, options: options as unknown as Options }; +} + +function strip(name: string): string { + return name.startsWith(QUALIFIED_PREFIX) + ? name.slice(QUALIFIED_PREFIX.length) + : name; +} + +/** + * Walks the assistant messages in order and pairs each registered tool_use + * block with the dispatch it caused, so the ids Rust answered and the ids + * reported here are the same ids. + */ +export function assembleEvents( + messages: { content: unknown }[], + registered: Set, + dispatches: Dispatch[], +): SidecarEvent[] { + const events: SidecarEvent[] = []; + let taken = 0; + let undispatched = 0; + for (const message of messages) { + const blocks = Array.isArray(message.content) ? message.content : []; + for (const block of blocks as Record[]) { + if (block.type === "text" && typeof block.text === "string") { + events.push({ kind: "text", text: block.text }); + continue; + } + if (block.type !== "tool_use") { + continue; + } + const name = strip(String(block.name ?? "")); + if (registered.has(name)) { + const dispatch = dispatches[taken++]; + if (!dispatch || dispatch.name !== name) { + throw new SidecarFault( + "protocol_violation", + `a registered tool_use block for ${name} has no matching dispatch`, + ); + } + events.push({ kind: "tool_call", ...dispatch, dispatched: true }); + continue; + } + events.push({ + kind: "tool_call", + call_id: `u${undispatched++}`, + name, + arguments: JSON.stringify(block.input ?? {}), + dispatched: false, + }); + } + } + if (taken !== dispatches.length) { + throw new SidecarFault( + "protocol_violation", + "more tool calls were dispatched than the assistant messages report", + ); + } + return events; +} + +async function runQuery( + frame: Extract, + write: (frame: SidecarFrame) => void, + session: QuerySession, +): Promise { + const registered = new Set(frame.tools.map((entry) => entry.name)); + const { prompt, options } = lowerQuery(frame, session); + const assistant: { content: unknown }[] = []; + const material: SdkResultMaterial = { + session_id: "", + result_uuid: "", + subtype: "", + stop_reason: null, + num_turns: 0, + assistant_message_uuids: [], + assistant_request_ids: [], + usage: [], + total_cost_usd_estimate: "0", + }; + let sawResult = false; + const stream = query({ prompt, options }); + try { + for await (const message of stream as AsyncIterable>) { + if (message.type === "assistant") { + const inner = message.message as Record | undefined; + assistant.push({ content: inner?.content }); + if (typeof message.uuid === "string") { + material.assistant_message_uuids.push(message.uuid); + } + if (typeof message.request_id === "string") { + material.assistant_request_ids.push(message.request_id); + } + continue; + } + if (message.type === "system" && message.subtype === "api_retry") { + // The harness owns its own retries; only an exhausted one reaches a + // result, so this is recorded and not raised. + continue; + } + if (message.type !== "result") { + continue; + } + sawResult = true; + const subtype = String(message.subtype ?? ""); + material.session_id = String(message.session_id ?? ""); + material.result_uuid = String(message.uuid ?? ""); + material.subtype = subtype; + material.stop_reason = + typeof message.stop_reason === "string" ? message.stop_reason : null; + material.num_turns = Number(message.num_turns ?? 0); + material.usage = usageRows(message.modelUsage); + material.total_cost_usd_estimate = String(message.total_cost_usd ?? 0); + // `error_max_turns` is not a fault: the cap is the lane's own remaining + // round budget, so reaching it means the model spent turns the evaluator + // would also have allowed. The lane sees one ordinary round. + if (subtype !== "success" && subtype !== "error_max_turns") { + const errors = Array.isArray(message.errors) + ? (message.errors as unknown[]).map(String).join("; ") + : ""; + const category = Array.isArray(message.errors) + ? undefined + : (message as Record).error; + const reason = + category === undefined + ? resultReason(subtype, message.api_error_status) + : apiRetryReason(category); + throw new SidecarFault(reason, `${subtype}: ${errors}`); + } + } + } catch (error) { + // The TS SDK throws after yielding an error result. A result already + // collected for `error_max_turns` is the normal path, so only an + // unaccounted throw becomes a fault. + if (error instanceof SidecarFault) { + throw error; + } + if (!sawResult) { + throw new SidecarFault("execution_error", String(error)); + } + } + if (!sawResult) { + throw new SidecarFault("execution_error", "the SDK query produced no result"); + } + write({ + kind: "output", + query_id: frame.query_id, + events: assembleEvents(assistant, registered, session.dispatches), + receipt: material, + }); +} + +async function main(): Promise { + const reader = new FrameReader(); + const write = (frame: SidecarFrame) => { + process.stdout.write(encodeFrame(frame)); + }; + let live: QuerySession | null = null; + let running: Promise = Promise.resolve(); + + for await (const chunk of process.stdin) { + reader.push(chunk as Uint8Array); + for (;;) { + let frame: SidecarFrame | null; + try { + frame = reader.next(); + } catch (error) { + write({ + kind: "fault", + query_id: live?.queryId ?? 0, + reason: "protocol_violation", + detail: String(error), + }); + return; + } + if (!frame) { + break; + } + if (frame.kind === "query") { + if (live) { + write({ + kind: "fault", + query_id: frame.query_id, + reason: "protocol_violation", + detail: "a second query arrived while one was in flight", + }); + continue; + } + const opening = frame; + const session = new QuerySession(opening.query_id, write); + live = session; + running = (async () => { + try { + await runQuery(opening, write, session); + } catch (error) { + const fault = + error instanceof SidecarFault + ? error + : new SidecarFault("execution_error", String(error)); + write({ + kind: "fault", + query_id: opening.query_id, + reason: fault.reason, + detail: fault.message, + }); + } finally { + live = null; + } + })(); + void running; + continue; + } + if (frame.kind === "tool_result") { + if (!live || live.queryId !== frame.query_id) { + write({ + kind: "fault", + query_id: frame.query_id, + reason: "protocol_violation", + detail: "a tool result arrived outside its query", + }); + continue; + } + try { + live.answer(frame.call_id, frame.output); + } catch (error) { + const fault = + error instanceof SidecarFault + ? error + : new SidecarFault("protocol_violation", String(error)); + write({ + kind: "fault", + query_id: frame.query_id, + reason: fault.reason, + detail: fault.message, + }); + } + continue; + } + write({ + kind: "fault", + query_id: 0, + reason: "protocol_violation", + detail: `frame kind ${frame.kind} is not one this sidecar accepts`, + }); + } + } + await running; +} + +// Only run the loop when this file is the entry point, so the tests can import +// its pure halves without starting a stdin reader. +if ( + process.argv[1] && + import.meta.url === pathToFileURL(resolve(process.argv[1])).href +) { + await main(); +} diff --git a/sidecar/claude-sdk/src/schema.ts b/sidecar/claude-sdk/src/schema.ts new file mode 100644 index 0000000..cf885c7 --- /dev/null +++ b/sidecar/claude-sdk/src/schema.ts @@ -0,0 +1,134 @@ +// The JSON Schema grammar Ghostlight's one emitter produces, converted to the +// Zod raw shape the SDK's `tool()` takes. It is closed on purpose: anything +// outside the grammar throws, so an emitter that grows a construct fails a test +// here rather than silently registering a looser tool. + +import { z } from "zod"; + +type Json = Record; + +const FORBIDDEN = ["oneOf", "allOf", "not", "$ref"] as const; + +function isObject(value: unknown): value is Json { + return typeof value === "object" && value !== null && !Array.isArray(value); +} + +function convert(node: unknown, at: string): z.ZodTypeAny { + if (!isObject(node)) { + throw new Error(`${at}: schema node is not an object`); + } + for (const forbidden of FORBIDDEN) { + if (forbidden in node) { + throw new Error(`${at}: \`${forbidden}\` is outside the emitted grammar`); + } + } + if ("anyOf" in node) { + const branches = node.anyOf; + if (!Array.isArray(branches) || branches.length === 0) { + throw new Error(`${at}: anyOf must be a nonempty array`); + } + // The nullable shape the emitter uses for an optional argument. + if ( + branches.length === 2 && + isObject(branches[1]) && + branches[1].type === "null" + ) { + return convert(branches[0], `${at}/anyOf/0`).nullable(); + } + const converted = branches.map((branch, index) => + convert(branch, `${at}/anyOf/${index}`), + ); + if (converted.length === 1) { + return converted[0]!; + } + return z.union(converted as [z.ZodTypeAny, z.ZodTypeAny, ...z.ZodTypeAny[]]); + } + const kind = node.type; + if (typeof kind !== "string") { + throw new Error(`${at}: schema node names no type`); + } + switch (kind) { + case "object": + return z.object(rawShape(node, at)).strict(); + case "string": { + if ("const" in node) { + if (typeof node.const !== "string") { + throw new Error(`${at}: a string const must be a string`); + } + return z.literal(node.const); + } + if ("enum" in node) { + const values = node.enum; + if ( + !Array.isArray(values) || + values.length === 0 || + values.some((value) => typeof value !== "string") + ) { + throw new Error(`${at}: enum must be a nonempty array of strings`); + } + return z.enum(values as [string, ...string[]]); + } + return z.string(); + } + case "integer": { + let schema = z.number().int(); + if (typeof node.minimum === "number") { + schema = schema.min(node.minimum); + } + if (typeof node.maximum === "number") { + schema = schema.max(node.maximum); + } + return schema; + } + case "boolean": + return z.boolean(); + case "null": + return z.null(); + case "array": + return z.array(convert(node.items, `${at}/items`)); + default: + throw new Error(`${at}: type \`${kind}\` is outside the emitted grammar`); + } +} + +function rawShape(node: Json, at: string): Record { + if (node.additionalProperties !== false) { + throw new Error(`${at}: every emitted object is closed`); + } + const properties = node.properties; + if (!isObject(properties)) { + throw new Error(`${at}: object without properties`); + } + const names = Object.keys(properties).sort(); + const required = Array.isArray(node.required) + ? [...(node.required as unknown[])].map(String).sort() + : []; + if (names.length !== required.length || names.some((name, index) => name !== required[index])) { + throw new Error(`${at}: every emitted property is required`); + } + const shape: Record = {}; + for (const name of names) { + shape[name] = convert(properties[name], `${at}/${name}`); + } + return shape; +} + +/** + * One tool's `parameters_json` as the raw shape `tool()` takes. Throws on any + * node outside the grammar the emitter produces. + */ +export function toolRawShape( + parametersJson: string, + at: string, +): Record { + let parsed: unknown; + try { + parsed = JSON.parse(parametersJson); + } catch (error) { + throw new Error(`${at}: parameters_json is not JSON (${String(error)})`); + } + if (!isObject(parsed) || parsed.type !== "object") { + throw new Error(`${at}: a tool's parameters must be an object schema`); + } + return rawShape(parsed, at); +} diff --git a/sidecar/claude-sdk/test/frames.test.ts b/sidecar/claude-sdk/test/frames.test.ts new file mode 100644 index 0000000..884a19f --- /dev/null +++ b/sidecar/claude-sdk/test/frames.test.ts @@ -0,0 +1,99 @@ +// Spec test 18: the frame bytes Rust writes decode here, and the bytes this +// side encodes are byte-identical to Rust's. The `.bin` fixtures are written by +// the Rust test `frame_fixtures_match_the_checked_in_sidecar_bytes`. + +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import { fileURLToPath } from "node:url"; +import test from "node:test"; +import { + FrameReader, + MAX_FRAME_BYTES, + decodeFrameBody, + encodeFrame, + type SidecarFrame, +} from "../src/frames.ts"; + +function fixture(name: string): Uint8Array { + return new Uint8Array( + readFileSync(fileURLToPath(new URL(`./frames/${name}.bin`, import.meta.url))), + ); +} + +const NAMES = ["query", "tool_call", "tool_result", "output", "fault"]; + +test("every Rust frame fixture decodes and re-encodes to the same bytes", () => { + for (const name of NAMES) { + const bytes = fixture(name); + const frame = decodeFrameBody(bytes.subarray(4)); + assert.equal(frame.kind, name, `${name} decoded to the wrong kind`); + assert.deepEqual( + Array.from(encodeFrame(frame)), + Array.from(bytes), + `${name} did not re-encode to Rust's bytes`, + ); + } +}); + +test("the query fixture carries the fields the lowering reads", () => { + const frame = decodeFrameBody(fixture("query").subarray(4)) as Extract< + SidecarFrame, + { kind: "query" } + >; + assert.equal(frame.query_id, 7); + assert.equal(frame.model, "claude-opus-5"); + assert.equal(frame.turn_cap, 24); + assert.equal(frame.effort, "medium"); + assert.equal(frame.max_output_tokens, 4000); + assert.deepEqual(frame.transcript, ["assistant: thinking", "tool result: ok"]); + assert.equal(frame.tools.length, 1); + assert.equal(frame.tools[0]!.name, "submit"); +}); + +test("the output fixture reports dispatch honestly", () => { + const frame = decodeFrameBody(fixture("output").subarray(4)) as Extract< + SidecarFrame, + { kind: "output" } + >; + assert.deepEqual(frame.events[0], { kind: "text", text: "Done." }); + assert.deepEqual(frame.events[1], { + kind: "tool_call", + call_id: "call-0", + name: "submit", + arguments: "{}", + dispatched: true, + }); + assert.equal(frame.receipt.session_id, "session-one"); + assert.equal(frame.receipt.usage[0]!.output_tokens, 34); +}); + +test("a chunked stream reassembles into whole frames", () => { + const reader = new FrameReader(); + const stream = new Uint8Array([ + ...fixture("tool_call"), + ...fixture("tool_result"), + ]); + const seen: SidecarFrame[] = []; + for (let at = 0; at < stream.length; at += 3) { + reader.push(stream.subarray(at, Math.min(at + 3, stream.length))); + for (;;) { + const frame = reader.next(); + if (!frame) { + break; + } + seen.push(frame); + } + } + assert.deepEqual( + seen.map((frame) => frame.kind), + ["tool_call", "tool_result"], + ); +}); + +test("a length prefix outside the cap is refused", () => { + const reader = new FrameReader(); + const prefix = new Uint8Array(4); + new DataView(prefix.buffer).setUint32(0, MAX_FRAME_BYTES + 1, false); + reader.push(prefix); + assert.throws(() => reader.next()); +}); diff --git a/sidecar/claude-sdk/test/lowering.test.ts b/sidecar/claude-sdk/test/lowering.test.ts new file mode 100644 index 0000000..41b3d8d --- /dev/null +++ b/sidecar/claude-sdk/test/lowering.test.ts @@ -0,0 +1,113 @@ +// Spec test 16: the hygiene the query options must carry, asserted against the +// same function `main.ts` uses. No credential, no network, no query. + +import assert from "node:assert/strict"; +import test from "node:test"; +import { QuerySession, lowerQuery, SidecarFault } from "../src/main.ts"; +import type { SidecarFrame } from "../src/frames.ts"; + +const EMPTY_SCHEMA = JSON.stringify({ + type: "object", + additionalProperties: false, + required: [], + properties: {}, +}); + +function queryFrame( + overrides: Partial> = {}, +): Extract { + return { + kind: "query", + query_id: 1, + model: "claude-opus-5", + instructions: "Author the shortfall.", + prompt: "Answer the deficit.", + transcript: [], + tools: [ + { name: "submit", description: "Submit the draft.", parameters_json: EMPTY_SCHEMA }, + { name: "record_gap", description: "Record a gap.", parameters_json: EMPTY_SCHEMA }, + ], + effort: "medium", + max_output_tokens: 4000, + turn_cap: 24, + ...overrides, + }; +} + +function session(frame: Extract): QuerySession { + return new QuerySession(frame.query_id, () => {}); +} + +test("lowers a query to SDK options that load nothing ambient", () => { + const frame = queryFrame(); + const { prompt, options } = lowerQuery(frame, session(frame)); + const raw = options as unknown as Record; + + assert.equal(prompt, frame.prompt, "a first round carried a transcript header"); + assert.deepEqual(raw.systemPrompt, { + type: "custom", + prompt: frame.instructions, + }); + assert.deepEqual(raw.settingSources, [], "settings sources were not emptied"); + assert.deepEqual(raw.tools, [], "built-in tools were not stripped"); + assert.equal(raw.strictMcpConfig, true); + assert.equal(raw.persistSession, false, "the caller's conversation would persist"); + assert.equal(raw.includePartialMessages, false); + assert.equal(raw.maxTurns, frame.turn_cap); + assert.equal(raw.model, frame.model); + assert.equal(raw.effort, frame.effort); + assert.deepEqual(raw.allowedTools, ["mcp__ghostlight__*"]); + + const servers = raw.mcpServers as Record>; + assert.ok(servers.ghostlight, "the ghostlight MCP server was not registered"); + const registered = servers.ghostlight.instance ?? servers.ghostlight; + assert.ok(registered, "the in-process server carries no instance"); +}); + +test("a request with no tools registers no MCP server", () => { + const frame = queryFrame({ tools: [], turn_cap: 1 }); + const { options } = lowerQuery(frame, session(frame)); + const raw = options as unknown as Record; + assert.equal(raw.mcpServers, undefined); + assert.equal(raw.allowedTools, undefined); + assert.equal(raw.maxTurns, 1); +}); + +test("a prior round's transcript is folded under one fixed header", () => { + const frame = queryFrame({ + transcript: ["assistant: thinking", "tool result: ok"], + }); + const { prompt } = lowerQuery(frame, session(frame)); + assert.equal( + prompt, + "Answer the deficit.\n\nEarlier turns in this same request, as they happened:\nassistant: thinking\ntool result: ok", + ); +}); + +test("a turn cap outside the lane budgets is refused", () => { + for (const turn_cap of [0, 25]) { + const frame = queryFrame({ turn_cap }); + assert.throws( + () => lowerQuery(frame, session(frame)), + (error: unknown) => + error instanceof SidecarFault && error.reason === "turn_cap_refused", + ); + } +}); + +test("a tool schema outside the emitted grammar refuses registration", () => { + const frame = queryFrame({ + tools: [ + { + name: "submit", + description: "Submit the draft.", + parameters_json: JSON.stringify({ oneOf: [{ type: "string" }] }), + }, + ], + }); + assert.throws( + () => lowerQuery(frame, session(frame)), + (error: unknown) => + error instanceof SidecarFault && error.reason === "tool_registration_failed", + ); +}); diff --git a/sidecar/claude-sdk/test/schema.test.ts b/sidecar/claude-sdk/test/schema.test.ts new file mode 100644 index 0000000..8d151f4 --- /dev/null +++ b/sidecar/claude-sdk/test/schema.test.ts @@ -0,0 +1,95 @@ +// Spec test 17: every schema Ghostlight's one emitter actually produces +// converts, and everything outside that grammar throws. `schemas.json` is +// written by the Rust test `schema_fixtures_match_the_checked_in_sidecar_grammar`, +// so the two halves cannot drift apart. + +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import { fileURLToPath } from "node:url"; +import test from "node:test"; +import { toolRawShape } from "../src/schema.ts"; + +const emitted: { name: string; parameters_json: string }[] = JSON.parse( + readFileSync(fileURLToPath(new URL("./schemas.json", import.meta.url)), "utf8"), +); + +test("every emitted tool schema converts", () => { + assert.ok(emitted.length > 0, "the schema fixture is empty"); + for (const entry of emitted) { + const shape = toolRawShape(entry.parameters_json, entry.name); + const declared = Object.keys( + JSON.parse(entry.parameters_json).properties as Record, + ).sort(); + assert.deepEqual(Object.keys(shape).sort(), declared, entry.name); + } +}); + +test("a converted shape accepts a value its schema admits", () => { + const shape = toolRawShape( + JSON.stringify({ + type: "object", + additionalProperties: false, + required: ["detail", "count", "flag", "choice", "maybe", "many"], + properties: { + detail: { type: "string" }, + count: { type: "integer", minimum: 1, maximum: 4 }, + flag: { type: "boolean" }, + choice: { type: "string", enum: ["a", "b"] }, + maybe: { anyOf: [{ type: "string" }, { type: "null" }] }, + many: { type: "array", items: { type: "string" } }, + }, + }), + "sample", + ); + assert.equal(shape.detail!.safeParse("ok").success, true); + assert.equal(shape.count!.safeParse(2).success, true); + assert.equal(shape.count!.safeParse(9).success, false); + assert.equal(shape.choice!.safeParse("c").success, false); + assert.equal(shape.maybe!.safeParse(null).success, true); + assert.equal(shape.many!.safeParse(["a"]).success, true); +}); + +test("anything outside the grammar throws", () => { + const refused = [ + { oneOf: [{ type: "string" }] }, + { allOf: [{ type: "string" }] }, + { $ref: "#/definitions/thing" }, + { description: "no type at all" }, + { type: "number" }, + ]; + for (const node of refused) { + assert.throws( + () => + toolRawShape( + JSON.stringify({ + type: "object", + additionalProperties: false, + required: ["field"], + properties: { field: node }, + }), + "refused", + ), + `${JSON.stringify(node)} was accepted`, + ); + } +}); + +test("an open object or a partly optional one throws", () => { + assert.throws(() => + toolRawShape( + JSON.stringify({ type: "object", required: [], properties: {} }), + "open", + ), + ); + assert.throws(() => + toolRawShape( + JSON.stringify({ + type: "object", + additionalProperties: false, + required: ["a"], + properties: { a: { type: "string" }, b: { type: "string" } }, + }), + "partial", + ), + ); +}); diff --git a/sidecar/claude-sdk/test/schemas.json b/sidecar/claude-sdk/test/schemas.json new file mode 100644 index 0000000..597afe8 --- /dev/null +++ b/sidecar/claude-sdk/test/schemas.json @@ -0,0 +1,178 @@ +[ + { + "name": "acquire_knowledge", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"confidence\":{\"enum\":[\"doubted\",\"believed\",\"certain\"],\"type\":\"string\"},\"fact\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing fact\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"source\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"source\":{\"const\":\"witnessed\",\"type\":\"string\"}},\"required\":[\"source\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"source\":{\"const\":\"evidenced\",\"type\":\"string\"}},\"required\":[\"source\"],\"type\":\"object\"}]},\"subject\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"subject\",\"fact\",\"source\",\"confidence\"],\"type\":\"object\"}" + }, + { + "name": "admit", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"evidence\":{\"description\":\"an exact evidence receipt retrieved for this answer\",\"type\":\"string\"},\"holder\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"qty\":{\"maximum\":18446744073709551615,\"minimum\":1,\"type\":\"integer\"},\"resource\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing resource\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"holder\",\"resource\",\"qty\",\"evidence\"],\"type\":\"object\"}" + }, + { + "name": "advance_pressure", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"by\":{\"maximum\":4294967295,\"minimum\":1,\"type\":\"integer\"},\"source\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"from\":{\"const\":\"commitment\",\"type\":\"string\"},\"of\":{\"additionalProperties\":false,\"properties\":{\"key\":{\"additionalProperties\":false,\"properties\":{\"command\":{\"description\":\"the command id that created the commitment\",\"type\":\"string\"},\"index\":{\"maximum\":4294967295,\"minimum\":0,\"type\":\"integer\"}},\"required\":[\"command\",\"index\"],\"type\":\"object\"},\"subject\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"subject\",\"key\"],\"type\":\"object\"}},\"required\":[\"from\",\"of\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"from\":{\"const\":\"dependency\",\"type\":\"string\"},\"of\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"ref\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing resource\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"target\":{\"const\":\"resource\",\"type\":\"string\"}},\"required\":[\"target\",\"ref\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"ref\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing route\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"target\":{\"const\":\"route\",\"type\":\"string\"}},\"required\":[\"target\",\"ref\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"ref\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"target\":{\"const\":\"subject\",\"type\":\"string\"}},\"required\":[\"target\",\"ref\"],\"type\":\"object\"}]}},\"required\":[\"from\",\"of\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"from\":{\"const\":\"subject\",\"type\":\"string\"},\"of\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"from\",\"of\"],\"type\":\"object\"}]},\"target\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"source\",\"target\",\"by\"],\"type\":\"object\"}" + }, + { + "name": "alter_cost", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"cost\":{\"maximum\":525600,\"minimum\":1,\"type\":\"integer\"},\"route\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing route\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"route\",\"cost\"],\"type\":\"object\"}" + }, + { + "name": "bind", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"subject\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"target\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"ref\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing resource\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"target\":{\"const\":\"resource\",\"type\":\"string\"}},\"required\":[\"target\",\"ref\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"ref\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing route\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"target\":{\"const\":\"route\",\"type\":\"string\"}},\"required\":[\"target\",\"ref\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"ref\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"target\":{\"const\":\"subject\",\"type\":\"string\"}},\"required\":[\"target\",\"ref\"],\"type\":\"object\"}]}},\"required\":[\"subject\",\"target\"],\"type\":\"object\"}" + }, + { + "name": "c3__finish_without_proposal", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{},\"type\":\"object\"}" + }, + { + "name": "c3__record_need", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"detail\":{\"description\":\"what the agent would need and does not have\",\"type\":\"string\"}},\"required\":[\"detail\"],\"type\":\"object\"}" + }, + { + "name": "c3__speak", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"text\":{\"description\":\"the utterance this invocation carries\",\"type\":\"string\"}},\"required\":[\"text\"],\"type\":\"object\"}" + }, + { + "name": "close_forum", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"grievance\":{\"description\":\"the grievance kind\",\"type\":\"string\"}},\"required\":[\"grievance\"],\"type\":\"object\"}" + }, + { + "name": "close_office", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"institution\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"office\":{\"description\":\"the office's name\",\"type\":\"string\"}},\"required\":[\"institution\",\"office\"],\"type\":\"object\"}" + }, + { + "name": "close_route", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"route\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing route\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"route\"],\"type\":\"object\"}" + }, + { + "name": "communicate", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"fact\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing fact\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"speaker\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"to\":{\"anyOf\":[{\"const\":\"colocated\",\"type\":\"string\"},{\"additionalProperties\":false,\"properties\":{\"channel\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing channel\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"channel\"],\"type\":\"object\"}]}},\"required\":[\"speaker\",\"fact\",\"to\"],\"type\":\"object\"}" + }, + { + "name": "consume", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"holder\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"qty\":{\"maximum\":18446744073709551615,\"minimum\":1,\"type\":\"integer\"},\"resource\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing resource\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"holder\",\"resource\",\"qty\"],\"type\":\"object\"}" + }, + { + "name": "create_commitment", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"checks\":{\"items\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"at\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing place\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"precondition\":{\"const\":\"present\",\"type\":\"string\"}},\"required\":[\"precondition\",\"at\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"precondition\":{\"const\":\"reachable\",\"type\":\"string\"},\"to\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing place\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"within\":{\"maximum\":525600,\"minimum\":1,\"type\":\"integer\"}},\"required\":[\"precondition\",\"to\",\"within\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"at_least\":{\"maximum\":18446744073709551615,\"minimum\":1,\"type\":\"integer\"},\"precondition\":{\"const\":\"holds\",\"type\":\"string\"},\"resource\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing resource\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"precondition\",\"resource\",\"at_least\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"kind\":{\"description\":\"the authority kind\",\"type\":\"string\"},\"over\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"over\":{\"const\":\"subject\",\"type\":\"string\"},\"ref\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"over\",\"ref\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"over\":{\"const\":\"place_subtree\",\"type\":\"string\"},\"ref\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing place\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"over\",\"ref\"],\"type\":\"object\"}]},\"precondition\":{\"const\":\"authorized\",\"type\":\"string\"}},\"required\":[\"precondition\",\"over\",\"kind\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"grievance\":{\"description\":\"the grievance kind\",\"type\":\"string\"},\"precondition\":{\"const\":\"has_standing\",\"type\":\"string\"}},\"required\":[\"precondition\",\"grievance\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"at_least\":{\"enum\":[\"doubted\",\"believed\",\"certain\"],\"type\":\"string\"},\"fact\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing fact\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"precondition\":{\"const\":\"knows\",\"type\":\"string\"}},\"required\":[\"precondition\",\"fact\",\"at_least\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"precondition\":{\"const\":\"can_broadcast\",\"type\":\"string\"},\"via\":{\"anyOf\":[{\"const\":\"colocated\",\"type\":\"string\"},{\"additionalProperties\":false,\"properties\":{\"channel\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing channel\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"channel\"],\"type\":\"object\"}]}},\"required\":[\"precondition\",\"via\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"precondition\":{\"const\":\"can_reach\",\"type\":\"string\"},\"subject\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"via\":{\"anyOf\":[{\"const\":\"colocated\",\"type\":\"string\"},{\"additionalProperties\":false,\"properties\":{\"channel\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing channel\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"channel\"],\"type\":\"object\"}]}},\"required\":[\"precondition\",\"subject\",\"via\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"kind\":{\"enum\":[\"routine\",\"obligation\",\"goal\"],\"type\":\"string\"},\"precondition\":{\"const\":\"committed\",\"type\":\"string\"},\"to\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"precondition\",\"to\",\"kind\"],\"type\":\"object\"}]},\"type\":\"array\"},\"counterparty\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},{\"type\":\"null\"}]},\"due\":{\"maximum\":18446744073709551615,\"minimum\":0,\"type\":\"integer\"},\"kind\":{\"enum\":[\"routine\",\"obligation\",\"goal\"],\"type\":\"string\"},\"period\":{\"anyOf\":[{\"maximum\":525600,\"minimum\":1,\"type\":\"integer\"},{\"type\":\"null\"}]},\"subject\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"subject\",\"counterparty\",\"kind\",\"due\",\"period\",\"checks\"],\"type\":\"object\"}" + }, + { + "name": "declare_affordance", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"carries_speech\":{\"type\":\"boolean\"},\"effect_slots\":{\"items\":{\"additionalProperties\":false,\"properties\":{\"bounds\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"bound\":{\"const\":\"none\",\"type\":\"string\"}},\"required\":[\"bound\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"bound\":{\"const\":\"quantity\",\"type\":\"string\"},\"max\":{\"maximum\":18446744073709551615,\"minimum\":1,\"type\":\"integer\"}},\"required\":[\"bound\",\"max\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"bound\":{\"const\":\"cost\",\"type\":\"string\"},\"max\":{\"maximum\":525600,\"minimum\":1,\"type\":\"integer\"}},\"required\":[\"bound\",\"max\"],\"type\":\"object\"}]},\"op_kind\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"op\":{\"const\":\"relocate\",\"type\":\"string\"}},\"required\":[\"op\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"op\":{\"const\":\"open_route\",\"type\":\"string\"}},\"required\":[\"op\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"op\":{\"const\":\"close_route\",\"type\":\"string\"}},\"required\":[\"op\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"op\":{\"const\":\"alter_cost\",\"type\":\"string\"}},\"required\":[\"op\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"op\":{\"const\":\"transfer\",\"type\":\"string\"}},\"required\":[\"op\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"op\":{\"const\":\"transform\",\"type\":\"string\"}},\"required\":[\"op\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"op\":{\"const\":\"consume\",\"type\":\"string\"}},\"required\":[\"op\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"op\":{\"const\":\"bind\",\"type\":\"string\"}},\"required\":[\"op\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"op\":{\"const\":\"release\",\"type\":\"string\"}},\"required\":[\"op\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"kind\":{\"description\":\"the authority kind\",\"type\":\"string\"},\"op\":{\"const\":\"grant_authority\",\"type\":\"string\"}},\"required\":[\"op\",\"kind\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"kind\":{\"description\":\"the authority kind\",\"type\":\"string\"},\"op\":{\"const\":\"revoke_authority\",\"type\":\"string\"}},\"required\":[\"op\",\"kind\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"office\":{\"description\":\"the office's name\",\"type\":\"string\"},\"op\":{\"const\":\"install_incumbent\",\"type\":\"string\"}},\"required\":[\"op\",\"office\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"office\":{\"description\":\"the office's name\",\"type\":\"string\"},\"op\":{\"const\":\"vacate_office\",\"type\":\"string\"}},\"required\":[\"op\",\"office\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"confidence\":{\"enum\":[\"doubted\",\"believed\",\"certain\"],\"type\":\"string\"},\"op\":{\"const\":\"acquire_knowledge\",\"type\":\"string\"}},\"required\":[\"op\",\"confidence\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"op\":{\"const\":\"forget\",\"type\":\"string\"}},\"required\":[\"op\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"horizon\":{\"maximum\":525600,\"minimum\":1,\"type\":\"integer\"},\"kind\":{\"enum\":[\"routine\",\"obligation\",\"goal\"],\"type\":\"string\"},\"op\":{\"const\":\"create_commitment\",\"type\":\"string\"},\"period\":{\"anyOf\":[{\"maximum\":525600,\"minimum\":1,\"type\":\"integer\"},{\"type\":\"null\"}]}},\"required\":[\"op\",\"kind\",\"horizon\",\"period\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"by\":{\"maximum\":4294967295,\"minimum\":1,\"type\":\"integer\"},\"op\":{\"const\":\"advance_pressure\",\"type\":\"string\"}},\"required\":[\"op\",\"by\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"by\":{\"maximum\":4294967295,\"minimum\":1,\"type\":\"integer\"},\"op\":{\"const\":\"reduce_pressure\",\"type\":\"string\"}},\"required\":[\"op\",\"by\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"op\":{\"const\":\"resolve_pressure\",\"type\":\"string\"}},\"required\":[\"op\"],\"type\":\"object\"}]},\"roles\":{\"items\":{\"description\":\"a declared role name\",\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"op_kind\",\"roles\",\"bounds\"],\"type\":\"object\"},\"type\":\"array\"},\"handle\":{\"description\":\"a new draft handle, unique within this patch\",\"type\":\"string\"},\"kind\":{\"description\":\"the affordance's tool name\",\"type\":\"string\"},\"outcome_bands\":{\"items\":{\"additionalProperties\":false,\"properties\":{\"effects\":{\"items\":{\"maximum\":4294967295,\"minimum\":0,\"type\":\"integer\"},\"type\":\"array\"},\"weight\":{\"maximum\":4294967295,\"minimum\":1,\"type\":\"integer\"}},\"required\":[\"weight\",\"effects\"],\"type\":\"object\"},\"type\":\"array\"},\"preconditions\":{\"items\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"at\":{\"description\":\"a declared role name\",\"type\":\"string\"},\"precondition\":{\"const\":\"present\",\"type\":\"string\"}},\"required\":[\"precondition\",\"at\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"precondition\":{\"const\":\"reachable\",\"type\":\"string\"},\"to\":{\"description\":\"a declared role name\",\"type\":\"string\"},\"within\":{\"maximum\":525600,\"minimum\":1,\"type\":\"integer\"}},\"required\":[\"precondition\",\"to\",\"within\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"at_least\":{\"maximum\":18446744073709551615,\"minimum\":1,\"type\":\"integer\"},\"precondition\":{\"const\":\"holds\",\"type\":\"string\"},\"resource\":{\"description\":\"a declared role name\",\"type\":\"string\"}},\"required\":[\"precondition\",\"resource\",\"at_least\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"kind\":{\"description\":\"the authority kind\",\"type\":\"string\"},\"over\":{\"description\":\"a declared role name\",\"type\":\"string\"},\"precondition\":{\"const\":\"authorized\",\"type\":\"string\"}},\"required\":[\"precondition\",\"over\",\"kind\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"grievance\":{\"description\":\"the grievance kind\",\"type\":\"string\"},\"precondition\":{\"const\":\"has_standing\",\"type\":\"string\"}},\"required\":[\"precondition\",\"grievance\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"at_least\":{\"enum\":[\"doubted\",\"believed\",\"certain\"],\"type\":\"string\"},\"fact\":{\"description\":\"a declared role name\",\"type\":\"string\"},\"precondition\":{\"const\":\"knows\",\"type\":\"string\"}},\"required\":[\"precondition\",\"fact\",\"at_least\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"precondition\":{\"const\":\"can_broadcast\",\"type\":\"string\"},\"via\":{\"anyOf\":[{\"const\":\"colocated\",\"type\":\"string\"},{\"additionalProperties\":false,\"properties\":{\"channel\":{\"description\":\"a declared role name\",\"type\":\"string\"}},\"required\":[\"channel\"],\"type\":\"object\"}]}},\"required\":[\"precondition\",\"via\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"precondition\":{\"const\":\"can_reach\",\"type\":\"string\"},\"subject\":{\"description\":\"a declared role name\",\"type\":\"string\"},\"via\":{\"anyOf\":[{\"const\":\"colocated\",\"type\":\"string\"},{\"additionalProperties\":false,\"properties\":{\"channel\":{\"description\":\"a declared role name\",\"type\":\"string\"}},\"required\":[\"channel\"],\"type\":\"object\"}]}},\"required\":[\"precondition\",\"subject\",\"via\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"kind\":{\"enum\":[\"routine\",\"obligation\",\"goal\"],\"type\":\"string\"},\"precondition\":{\"const\":\"committed\",\"type\":\"string\"},\"to\":{\"description\":\"a declared role name\",\"type\":\"string\"}},\"required\":[\"precondition\",\"to\",\"kind\"],\"type\":\"object\"}]},\"type\":\"array\"},\"roles\":{\"items\":{\"additionalProperties\":false,\"properties\":{\"kind\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"kind\":{\"anyOf\":[{\"enum\":[\"person\",\"institution\",\"population\"],\"type\":\"string\"},{\"type\":\"null\"}]},\"namespace\":{\"const\":\"subject\",\"type\":\"string\"}},\"required\":[\"namespace\",\"kind\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"kind\":{\"enum\":[\"place\",\"resource\",\"fact\",\"channel\"],\"type\":\"string\"},\"namespace\":{\"const\":\"entity\",\"type\":\"string\"}},\"required\":[\"namespace\",\"kind\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"kind\":{\"enum\":[\"route\"],\"type\":\"string\"},\"namespace\":{\"const\":\"edge\",\"type\":\"string\"}},\"required\":[\"namespace\",\"kind\"],\"type\":\"object\"}]},\"role\":{\"description\":\"the slot's parameter name\",\"type\":\"string\"}},\"required\":[\"role\",\"kind\"],\"type\":\"object\"},\"type\":\"array\"}},\"required\":[\"handle\",\"kind\",\"roles\",\"preconditions\",\"effect_slots\",\"outcome_bands\",\"carries_speech\"],\"type\":\"object\"}" + }, + { + "name": "declare_channel", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"controller\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},{\"type\":\"null\"}]},\"handle\":{\"description\":\"a new draft handle, unique within this patch\",\"type\":\"string\"},\"label\":{\"description\":\"a display label\",\"type\":\"string\"},\"reach\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"of\":{\"items\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"type\":\"array\"},\"reach\":{\"const\":\"subjects\",\"type\":\"string\"}},\"required\":[\"reach\",\"of\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"of\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing place\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"reach\":{\"const\":\"place\",\"type\":\"string\"}},\"required\":[\"reach\",\"of\"],\"type\":\"object\"}]}},\"required\":[\"handle\",\"label\",\"reach\",\"controller\"],\"type\":\"object\"}" + }, + { + "name": "declare_fact", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"handle\":{\"description\":\"a new draft handle, unique within this patch\",\"type\":\"string\"},\"label\":{\"description\":\"a display label\",\"type\":\"string\"},\"standing\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"evidence\":{\"description\":\"an exact evidence receipt\",\"type\":\"string\"},\"standing\":{\"const\":\"canonical\",\"type\":\"string\"}},\"required\":[\"standing\",\"evidence\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"by\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"standing\":{\"const\":\"claimed\",\"type\":\"string\"}},\"required\":[\"standing\",\"by\"],\"type\":\"object\"}]},\"statement\":{\"description\":\"the committed world text this fact carries\",\"type\":\"string\"}},\"required\":[\"handle\",\"label\",\"statement\",\"standing\"],\"type\":\"object\"}" + }, + { + "name": "declare_place", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"container\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing place\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},{\"type\":\"null\"}]},\"handle\":{\"description\":\"a new draft handle, unique within this patch\",\"type\":\"string\"},\"label\":{\"description\":\"a display label\",\"type\":\"string\"}},\"required\":[\"handle\",\"label\",\"container\"],\"type\":\"object\"}" + }, + { + "name": "declare_resource", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"handle\":{\"description\":\"a new draft handle, unique within this patch\",\"type\":\"string\"},\"label\":{\"description\":\"a display label\",\"type\":\"string\"}},\"required\":[\"handle\",\"label\"],\"type\":\"object\"}" + }, + { + "name": "declare_route", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"access\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"access\":{\"const\":\"public\",\"type\":\"string\"}},\"required\":[\"access\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"access\":{\"const\":\"restricted\",\"type\":\"string\"},\"requires\":{\"description\":\"the authority kind that opens this route\",\"type\":\"string\"}},\"required\":[\"access\",\"requires\"],\"type\":\"object\"}]},\"cost\":{\"maximum\":525600,\"minimum\":1,\"type\":\"integer\"},\"from\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing place\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"handle\":{\"description\":\"a new draft handle, unique within this patch\",\"type\":\"string\"},\"label\":{\"description\":\"a display label\",\"type\":\"string\"},\"to\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing place\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"handle\",\"label\",\"from\",\"to\",\"access\",\"cost\"],\"type\":\"object\"}" + }, + { + "name": "declare_subject", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"affordances\":{\"items\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing affordance\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"type\":\"array\"},\"controller\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"type\":{\"const\":\"narrative_persona\",\"type\":\"string\"}},\"required\":[\"type\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"type\":{\"const\":\"operational_agent\",\"type\":\"string\"}},\"required\":[\"type\"],\"type\":\"object\"}]},\"handle\":{\"description\":\"a new draft handle, unique within this patch\",\"type\":\"string\"},\"kind\":{\"enum\":[\"person\",\"institution\",\"population\"],\"type\":\"string\"},\"label\":{\"description\":\"a display label\",\"type\":\"string\"},\"position\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing place\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},{\"type\":\"null\"}]}},\"required\":[\"handle\",\"label\",\"kind\",\"controller\",\"affordances\",\"position\"],\"type\":\"object\"}" + }, + { + "name": "discharge_commitment", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"key\":{\"additionalProperties\":false,\"properties\":{\"command\":{\"description\":\"the command id that created the commitment\",\"type\":\"string\"},\"index\":{\"maximum\":4294967295,\"minimum\":0,\"type\":\"integer\"}},\"required\":[\"command\",\"index\"],\"type\":\"object\"},\"subject\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"subject\",\"key\"],\"type\":\"object\"}" + }, + { + "name": "finish_without_proposal", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{},\"type\":\"object\"}" + }, + { + "name": "forget", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"fact\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing fact\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"subject\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"subject\",\"fact\"],\"type\":\"object\"}" + }, + { + "name": "grant_authority", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"grant\":{\"additionalProperties\":false,\"properties\":{\"kind\":{\"description\":\"the authority kind\",\"type\":\"string\"},\"over\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"over\":{\"const\":\"subject\",\"type\":\"string\"},\"ref\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"over\",\"ref\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"over\":{\"const\":\"place_subtree\",\"type\":\"string\"},\"ref\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing place\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"over\",\"ref\"],\"type\":\"object\"}]}},\"required\":[\"kind\",\"over\"],\"type\":\"object\"},\"holder\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"holder\",\"grant\"],\"type\":\"object\"}" + }, + { + "name": "install_incumbent", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"incumbent\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"institution\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"office\":{\"description\":\"the office's name\",\"type\":\"string\"}},\"required\":[\"institution\",\"office\",\"incumbent\"],\"type\":\"object\"}" + }, + { + "name": "open_forum", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"forum\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"grievance\":{\"description\":\"the grievance kind\",\"type\":\"string\"},\"standing\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"over\":{\"const\":\"subject\",\"type\":\"string\"},\"ref\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"over\",\"ref\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"over\":{\"const\":\"place_subtree\",\"type\":\"string\"},\"ref\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing place\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"over\",\"ref\"],\"type\":\"object\"}]}},\"required\":[\"grievance\",\"forum\",\"standing\"],\"type\":\"object\"}" + }, + { + "name": "open_office", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"delegated\":{\"items\":{\"description\":\"an authority kind the office lends\",\"type\":\"string\"},\"type\":\"array\"},\"institution\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"office\":{\"description\":\"the office's name\",\"type\":\"string\"}},\"required\":[\"institution\",\"office\",\"delegated\"],\"type\":\"object\"}" + }, + { + "name": "open_route", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"route\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing route\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"route\"],\"type\":\"object\"}" + }, + { + "name": "record_gap", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"detail\":{\"description\":\"what the world needs and this vocabulary cannot express\",\"type\":\"string\"}},\"required\":[\"detail\"],\"type\":\"object\"}" + }, + { + "name": "record_need", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"detail\":{\"description\":\"what the agent would need and does not have\",\"type\":\"string\"}},\"required\":[\"detail\"],\"type\":\"object\"}" + }, + { + "name": "reduce_pressure", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"by\":{\"maximum\":4294967295,\"minimum\":1,\"type\":\"integer\"},\"source\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"from\":{\"const\":\"commitment\",\"type\":\"string\"},\"of\":{\"additionalProperties\":false,\"properties\":{\"key\":{\"additionalProperties\":false,\"properties\":{\"command\":{\"description\":\"the command id that created the commitment\",\"type\":\"string\"},\"index\":{\"maximum\":4294967295,\"minimum\":0,\"type\":\"integer\"}},\"required\":[\"command\",\"index\"],\"type\":\"object\"},\"subject\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"subject\",\"key\"],\"type\":\"object\"}},\"required\":[\"from\",\"of\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"from\":{\"const\":\"dependency\",\"type\":\"string\"},\"of\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"ref\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing resource\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"target\":{\"const\":\"resource\",\"type\":\"string\"}},\"required\":[\"target\",\"ref\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"ref\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing route\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"target\":{\"const\":\"route\",\"type\":\"string\"}},\"required\":[\"target\",\"ref\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"ref\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"target\":{\"const\":\"subject\",\"type\":\"string\"}},\"required\":[\"target\",\"ref\"],\"type\":\"object\"}]}},\"required\":[\"from\",\"of\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"from\":{\"const\":\"subject\",\"type\":\"string\"},\"of\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"from\",\"of\"],\"type\":\"object\"}]},\"target\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"source\",\"target\",\"by\"],\"type\":\"object\"}" + }, + { + "name": "release", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"subject\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"target\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"ref\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing resource\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"target\":{\"const\":\"resource\",\"type\":\"string\"}},\"required\":[\"target\",\"ref\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"ref\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing route\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"target\":{\"const\":\"route\",\"type\":\"string\"}},\"required\":[\"target\",\"ref\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"ref\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"target\":{\"const\":\"subject\",\"type\":\"string\"}},\"required\":[\"target\",\"ref\"],\"type\":\"object\"}]}},\"required\":[\"subject\",\"target\"],\"type\":\"object\"}" + }, + { + "name": "relocate", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"subject\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"via\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing route\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"subject\",\"via\"],\"type\":\"object\"}" + }, + { + "name": "resolve_pressure", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"source\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"from\":{\"const\":\"commitment\",\"type\":\"string\"},\"of\":{\"additionalProperties\":false,\"properties\":{\"key\":{\"additionalProperties\":false,\"properties\":{\"command\":{\"description\":\"the command id that created the commitment\",\"type\":\"string\"},\"index\":{\"maximum\":4294967295,\"minimum\":0,\"type\":\"integer\"}},\"required\":[\"command\",\"index\"],\"type\":\"object\"},\"subject\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"subject\",\"key\"],\"type\":\"object\"}},\"required\":[\"from\",\"of\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"from\":{\"const\":\"dependency\",\"type\":\"string\"},\"of\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"ref\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing resource\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"target\":{\"const\":\"resource\",\"type\":\"string\"}},\"required\":[\"target\",\"ref\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"ref\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing route\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"target\":{\"const\":\"route\",\"type\":\"string\"}},\"required\":[\"target\",\"ref\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"ref\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"target\":{\"const\":\"subject\",\"type\":\"string\"}},\"required\":[\"target\",\"ref\"],\"type\":\"object\"}]}},\"required\":[\"from\",\"of\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"from\":{\"const\":\"subject\",\"type\":\"string\"},\"of\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"from\",\"of\"],\"type\":\"object\"}]},\"target\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"source\",\"target\"],\"type\":\"object\"}" + }, + { + "name": "revoke_authority", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"grant\":{\"additionalProperties\":false,\"properties\":{\"kind\":{\"description\":\"the authority kind\",\"type\":\"string\"},\"over\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"over\":{\"const\":\"subject\",\"type\":\"string\"},\"ref\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"over\",\"ref\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"over\":{\"const\":\"place_subtree\",\"type\":\"string\"},\"ref\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing place\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"over\",\"ref\"],\"type\":\"object\"}]}},\"required\":[\"kind\",\"over\"],\"type\":\"object\"},\"holder\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"holder\",\"grant\"],\"type\":\"object\"}" + }, + { + "name": "set_controller", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"channel\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing channel\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"controller\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},{\"type\":\"null\"}]}},\"required\":[\"channel\",\"controller\"],\"type\":\"object\"}" + }, + { + "name": "set_reach", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"channel\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing channel\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"reach\":{\"anyOf\":[{\"additionalProperties\":false,\"properties\":{\"of\":{\"items\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"type\":\"array\"},\"reach\":{\"const\":\"subjects\",\"type\":\"string\"}},\"required\":[\"reach\",\"of\"],\"type\":\"object\"},{\"additionalProperties\":false,\"properties\":{\"of\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing place\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"reach\":{\"const\":\"place\",\"type\":\"string\"}},\"required\":[\"reach\",\"of\"],\"type\":\"object\"}]}},\"required\":[\"channel\",\"reach\"],\"type\":\"object\"}" + }, + { + "name": "speak", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"text\":{\"description\":\"the utterance this invocation carries\",\"type\":\"string\"}},\"required\":[\"text\"],\"type\":\"object\"}" + }, + { + "name": "submit", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{},\"required\":[],\"type\":\"object\"}" + }, + { + "name": "transfer", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"from\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"qty\":{\"maximum\":18446744073709551615,\"minimum\":1,\"type\":\"integer\"},\"resource\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing resource\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"to\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"from\",\"to\",\"resource\",\"qty\"],\"type\":\"object\"}" + }, + { + "name": "transform", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"from_resource\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing resource\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"holder\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"into_resource\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing resource\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"qty\":{\"maximum\":18446744073709551615,\"minimum\":1,\"type\":\"integer\"}},\"required\":[\"holder\",\"from_resource\",\"into_resource\",\"qty\"],\"type\":\"object\"}" + }, + { + "name": "vacate_office", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"institution\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing subject\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"office\":{\"description\":\"the office's name\",\"type\":\"string\"}},\"required\":[\"institution\",\"office\"],\"type\":\"object\"}" + }, + { + "name": "witness", + "parameters_json": "{\"additionalProperties\":false,\"properties\":{\"confidence\":{\"enum\":[\"doubted\",\"believed\",\"certain\"],\"type\":\"string\"},\"fact\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing fact\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"},\"place\":{\"additionalProperties\":false,\"properties\":{\"ref\":{\"enum\":[\"draft\",\"existing\"],\"type\":\"string\"},\"value\":{\"description\":\"a draft handle declared in this same patch, or the canonical id of an existing place\",\"type\":\"string\"}},\"required\":[\"ref\",\"value\"],\"type\":\"object\"}},\"required\":[\"fact\",\"place\",\"confidence\"],\"type\":\"object\"}" + } +] diff --git a/sidecar/claude-sdk/tsconfig.json b/sidecar/claude-sdk/tsconfig.json new file mode 100644 index 0000000..4d199af --- /dev/null +++ b/sidecar/claude-sdk/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "outDir": "dist", + "rootDir": "src", + "declaration": false, + "sourceMap": false, + "skipLibCheck": true, + "allowImportingTsExtensions": true, + "rewriteRelativeImportExtensions": true + }, + "include": ["src/**/*.ts"] +}