@sponsio/sdk 0.1.0-alpha.3 → 0.2.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/sponsio.cjs +11 -0
- package/contracts/benchmark/agentdojo.yaml +551 -0
- package/contracts/benchmark/odcv_bench.yaml +393 -0
- package/contracts/benchmark/redcode_exec.yaml +488 -0
- package/contracts/benchmark/swebench.yaml +176 -0
- package/contracts/benchmark/tau2_bench.yaml +984 -0
- package/contracts/capability/credentials.yaml +8 -8
- package/contracts/capability/database.yaml +6 -6
- package/contracts/capability/filesystem-strict.yaml +4 -4
- package/contracts/capability/filesystem.yaml +9 -9
- package/contracts/capability/host-config-integrity.yaml +285 -0
- package/contracts/capability/self-modify.yaml +214 -9
- package/contracts/capability/shell.yaml +25 -32
- package/contracts/capability/subagent.yaml +5 -5
- package/contracts/core/llm_safety.yaml +21 -13
- package/contracts/incident/claude-code-secret-bypass.yaml +11 -12
- package/contracts/incident/cursor-railway-wipe.yaml +3 -3
- package/contracts/incident/mcp-composition.yaml +12 -12
- package/contracts/incident/openclaw.yaml +54 -45
- package/contracts/incident/subagent-escape.yaml +4 -4
- package/contracts/premium/.gitkeep +5 -6
- package/dist/cli/check.d.ts +2 -0
- package/dist/cli/check.d.ts.map +1 -0
- package/dist/cli/check.js +283 -0
- package/dist/cli/check.js.map +1 -0
- package/dist/cli/cli.d.ts +25 -0
- package/dist/cli/cli.d.ts.map +1 -0
- package/dist/cli/cli.js +459 -0
- package/dist/cli/cli.js.map +1 -0
- package/dist/cli/config.d.ts +88 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +243 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/demo.d.ts +12 -0
- package/dist/cli/demo.d.ts.map +1 -0
- package/dist/cli/demo.js +350 -0
- package/dist/cli/demo.js.map +1 -0
- package/dist/cli/doctor.d.ts +11 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +201 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/eval.d.ts +2 -0
- package/dist/cli/eval.d.ts.map +1 -0
- package/dist/cli/eval.js +361 -0
- package/dist/cli/eval.js.map +1 -0
- package/dist/cli/explain.d.ts +2 -0
- package/dist/cli/explain.d.ts.map +1 -0
- package/dist/cli/explain.js +266 -0
- package/dist/cli/explain.js.map +1 -0
- package/dist/cli/export-sessions.d.ts +2 -0
- package/dist/cli/export-sessions.d.ts.map +1 -0
- package/dist/cli/export-sessions.js +182 -0
- package/dist/cli/export-sessions.js.map +1 -0
- package/dist/cli/export.d.ts +2 -0
- package/dist/cli/export.d.ts.map +1 -0
- package/dist/cli/export.js +222 -0
- package/dist/cli/export.js.map +1 -0
- package/dist/cli/extractors/common.d.ts +27 -0
- package/dist/cli/extractors/common.d.ts.map +1 -0
- package/dist/cli/extractors/common.js +107 -0
- package/dist/cli/extractors/common.js.map +1 -0
- package/dist/cli/extractors/generic.d.ts +37 -0
- package/dist/cli/extractors/generic.d.ts.map +1 -0
- package/dist/cli/extractors/generic.js +185 -0
- package/dist/cli/extractors/generic.js.map +1 -0
- package/dist/cli/extractors/langchain.d.ts +18 -0
- package/dist/cli/extractors/langchain.d.ts.map +1 -0
- package/dist/cli/extractors/langchain.js +86 -0
- package/dist/cli/extractors/langchain.js.map +1 -0
- package/dist/cli/extractors/vercel.d.ts +17 -0
- package/dist/cli/extractors/vercel.d.ts.map +1 -0
- package/dist/cli/extractors/vercel.js +46 -0
- package/dist/cli/extractors/vercel.js.map +1 -0
- package/dist/cli/index.d.ts +38 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +146 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +2 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +177 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/mode.d.ts +2 -0
- package/dist/cli/mode.d.ts.map +1 -0
- package/dist/cli/mode.js +71 -0
- package/dist/cli/mode.js.map +1 -0
- package/dist/cli/onboard.d.ts +88 -0
- package/dist/cli/onboard.d.ts.map +1 -0
- package/dist/cli/onboard.js +758 -0
- package/dist/cli/onboard.js.map +1 -0
- package/dist/cli/otlp.d.ts +27 -0
- package/dist/cli/otlp.d.ts.map +1 -0
- package/dist/cli/otlp.js +79 -0
- package/dist/cli/otlp.js.map +1 -0
- package/dist/cli/package.json +1 -0
- package/dist/cli/packs.d.ts +16 -0
- package/dist/cli/packs.d.ts.map +1 -0
- package/dist/cli/packs.js +184 -0
- package/dist/cli/packs.js.map +1 -0
- package/dist/cli/patterns.d.ts +16 -0
- package/dist/cli/patterns.d.ts.map +1 -0
- package/dist/cli/patterns.js +136 -0
- package/dist/cli/patterns.js.map +1 -0
- package/dist/cli/prompt.d.ts +2 -0
- package/dist/cli/prompt.d.ts.map +1 -0
- package/dist/cli/prompt.js +54 -0
- package/dist/cli/prompt.js.map +1 -0
- package/dist/cli/replay.d.ts +2 -0
- package/dist/cli/replay.d.ts.map +1 -0
- package/dist/cli/replay.js +196 -0
- package/dist/cli/replay.js.map +1 -0
- package/dist/cli/report.d.ts +57 -0
- package/dist/cli/report.d.ts.map +1 -0
- package/dist/cli/report.js +298 -0
- package/dist/cli/report.js.map +1 -0
- package/dist/cli/scan.d.ts +2 -0
- package/dist/cli/scan.d.ts.map +1 -0
- package/dist/cli/scan.js +172 -0
- package/dist/cli/scan.js.map +1 -0
- package/dist/cli/skill.d.ts +15 -0
- package/dist/cli/skill.d.ts.map +1 -0
- package/dist/cli/skill.js +131 -0
- package/dist/cli/skill.js.map +1 -0
- package/dist/cli/tokens.d.ts +31 -0
- package/dist/cli/tokens.d.ts.map +1 -0
- package/dist/cli/tokens.js +73 -0
- package/dist/cli/tokens.js.map +1 -0
- package/dist/cli/types.d.ts +46 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js +3 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/cli/validate.d.ts +19 -0
- package/dist/cli/validate.d.ts.map +1 -0
- package/dist/cli/validate.js +205 -0
- package/dist/cli/validate.js.map +1 -0
- package/dist/cli/zod.d.ts +36 -0
- package/dist/cli/zod.d.ts.map +1 -0
- package/dist/cli/zod.js +226 -0
- package/dist/cli/zod.js.map +1 -0
- package/dist/contract.d.ts +13 -13
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +21 -21
- package/dist/contract.js.map +1 -1
- package/dist/core/config-loader.d.ts +1 -1
- package/dist/core/config-loader.d.ts.map +1 -1
- package/dist/core/config-loader.js +100 -26
- package/dist/core/config-loader.js.map +1 -1
- package/dist/core/evaluator.d.ts +9 -1
- package/dist/core/evaluator.d.ts.map +1 -1
- package/dist/core/evaluator.js +189 -13
- package/dist/core/evaluator.js.map +1 -1
- package/dist/core/formula.d.ts +76 -17
- package/dist/core/formula.d.ts.map +1 -1
- package/dist/core/formula.js +83 -1
- package/dist/core/formula.js.map +1 -1
- package/dist/core/grounding.d.ts +50 -3
- package/dist/core/grounding.d.ts.map +1 -1
- package/dist/core/grounding.js +317 -141
- package/dist/core/grounding.js.map +1 -1
- package/dist/core/nl-parser.d.ts +1 -1
- package/dist/core/nl-parser.d.ts.map +1 -1
- package/dist/core/nl-parser.js +76 -4
- package/dist/core/nl-parser.js.map +1 -1
- package/dist/core/pack-loader.d.ts.map +1 -1
- package/dist/core/pack-loader.js +14 -2
- package/dist/core/pack-loader.js.map +1 -1
- package/dist/core/parser.d.ts.map +1 -1
- package/dist/core/parser.js +30 -1
- package/dist/core/parser.js.map +1 -1
- package/dist/core/pattern-factory.d.ts +4 -4
- package/dist/core/pattern-factory.d.ts.map +1 -1
- package/dist/core/pattern-factory.js +53 -4
- package/dist/core/pattern-factory.js.map +1 -1
- package/dist/core/patterns.d.ts +127 -5
- package/dist/core/patterns.d.ts.map +1 -1
- package/dist/core/patterns.js +267 -3
- package/dist/core/patterns.js.map +1 -1
- package/dist/core/session-log.d.ts.map +1 -1
- package/dist/core/session-log.js +20 -1
- package/dist/core/session-log.js.map +1 -1
- package/dist/core/spans.d.ts +1 -1
- package/dist/core/spans.d.ts.map +1 -1
- package/dist/core/spans.js.map +1 -1
- package/dist/core/sto.d.ts +30 -66
- package/dist/core/sto.d.ts.map +1 -1
- package/dist/core/sto.js +39 -100
- package/dist/core/sto.js.map +1 -1
- package/dist/index.d.ts +83 -33
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +194 -142
- package/dist/index.js.map +1 -1
- package/dist/integrations/openai-agents.d.ts.map +1 -1
- package/dist/integrations/openai-agents.js +6 -4
- package/dist/integrations/openai-agents.js.map +1 -1
- package/dist/integrations/vercel-ai.d.ts.map +1 -1
- package/dist/integrations/vercel-ai.js +21 -3
- package/dist/integrations/vercel-ai.js.map +1 -1
- package/dist/render/tokens.d.ts.map +1 -1
- package/dist/render/tokens.js +1 -0
- package/dist/render/tokens.js.map +1 -1
- package/package.json +35 -7
- package/prompts/onboard.md +246 -0
- package/prompts/scan.md +123 -0
- package/skills/SKILL.md +432 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ``sponsio validate`` — CI-friendly config check.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors the first half of Python's ``sponsio validate`` command:
|
|
6
|
+
* parse sponsio.yaml, surface structural errors, and report what
|
|
7
|
+
* the TS runtime can / cannot handle. Exits non-zero when the file
|
|
8
|
+
* doesn't load or when --strict is set and the loader had to skip
|
|
9
|
+
* any unsupported yaml items.
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
*
|
|
13
|
+
* sponsio validate # validates ./sponsio.yaml
|
|
14
|
+
* sponsio validate ./config.yaml
|
|
15
|
+
* sponsio validate --agent support_bot
|
|
16
|
+
* sponsio validate --strict # non-zero on any skip
|
|
17
|
+
* sponsio validate --format json # machine-readable
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.runValidateCli = runValidateCli;
|
|
21
|
+
const node_fs_1 = require("node:fs");
|
|
22
|
+
const node_path_1 = require("node:path");
|
|
23
|
+
const HELP = [
|
|
24
|
+
"sponsio validate — parse sponsio.yaml and report what the TS runtime will use",
|
|
25
|
+
"",
|
|
26
|
+
"USAGE:",
|
|
27
|
+
" sponsio validate [path] [options]",
|
|
28
|
+
"",
|
|
29
|
+
"ARGUMENTS:",
|
|
30
|
+
" [path] Path to sponsio.yaml (default: ./sponsio.yaml)",
|
|
31
|
+
"",
|
|
32
|
+
"OPTIONS:",
|
|
33
|
+
" --agent <id> Which agent block to project (default: first one found)",
|
|
34
|
+
" --strict Exit non-zero if the loader had to skip anything",
|
|
35
|
+
" --format <f> 'text' (default) or 'json'",
|
|
36
|
+
" -h, --help Show this help",
|
|
37
|
+
"",
|
|
38
|
+
"EXIT CODES:",
|
|
39
|
+
" 0 config loads and the TS runtime can honour every declared contract",
|
|
40
|
+
" 1 yaml / schema error — config does not load at all",
|
|
41
|
+
" 2 loaded with warnings (unsupported yaml items skipped); only with --strict",
|
|
42
|
+
].join("\n") + "\n";
|
|
43
|
+
function parseArgs(argv) {
|
|
44
|
+
const a = {
|
|
45
|
+
path: "sponsio.yaml",
|
|
46
|
+
strict: false,
|
|
47
|
+
format: "text",
|
|
48
|
+
help: false,
|
|
49
|
+
};
|
|
50
|
+
const positional = [];
|
|
51
|
+
for (let i = 0; i < argv.length; i++) {
|
|
52
|
+
const flag = argv[i];
|
|
53
|
+
if (flag === "-h" || flag === "--help")
|
|
54
|
+
a.help = true;
|
|
55
|
+
else if (flag === "--agent")
|
|
56
|
+
a.agent = argv[++i];
|
|
57
|
+
else if (flag === "--strict")
|
|
58
|
+
a.strict = true;
|
|
59
|
+
else if (flag === "--format") {
|
|
60
|
+
const v = argv[++i];
|
|
61
|
+
if (v !== "text" && v !== "json") {
|
|
62
|
+
throw new Error(`--format must be 'text' or 'json', got ${v}`);
|
|
63
|
+
}
|
|
64
|
+
a.format = v;
|
|
65
|
+
}
|
|
66
|
+
else if (flag.startsWith("-")) {
|
|
67
|
+
throw new Error(`unknown flag: ${flag}`);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
positional.push(flag);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (positional.length > 1) {
|
|
74
|
+
throw new Error(`validate accepts at most one positional path, got ${positional.length}`);
|
|
75
|
+
}
|
|
76
|
+
if (positional[0])
|
|
77
|
+
a.path = positional[0];
|
|
78
|
+
return a;
|
|
79
|
+
}
|
|
80
|
+
async function runValidateCli(argv) {
|
|
81
|
+
let args;
|
|
82
|
+
try {
|
|
83
|
+
args = parseArgs(argv);
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
process.stderr.write(`${err instanceof Error ? err.message : String(err)}\n`);
|
|
87
|
+
process.exit(2);
|
|
88
|
+
}
|
|
89
|
+
if (args.help) {
|
|
90
|
+
process.stdout.write(HELP);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const resolved = (0, node_path_1.resolve)(process.cwd(), args.path);
|
|
94
|
+
if (!(0, node_fs_1.existsSync)(resolved)) {
|
|
95
|
+
process.stderr.write(`[sponsio] config not found: ${resolved}\n`);
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
// Lazy-load: avoids paying for the ts-sdk import on `--help`.
|
|
99
|
+
let result;
|
|
100
|
+
try {
|
|
101
|
+
// Import through the dist of ``@sponsio/sdk`` when the scanner
|
|
102
|
+
// ships on npm, and through a relative path when we're running
|
|
103
|
+
// in-repo. ``require.resolve`` lets us tolerate either.
|
|
104
|
+
const sdk = await loadSdk();
|
|
105
|
+
const loaded = sdk.loadSponsoConfig(resolved, args.agent ?? "agent");
|
|
106
|
+
// ``loaded.contracts`` is ``(string | DetFormula)[]``:
|
|
107
|
+
// - strings are NL that still needs ``parseNl`` (some rule
|
|
108
|
+
// factories might reject, count those separately);
|
|
109
|
+
// - objects are already-compiled DetFormula entries (structured
|
|
110
|
+
// patterns, raw LTL, A/G composition) — those are det-valid by
|
|
111
|
+
// construction.
|
|
112
|
+
const unparseable = [];
|
|
113
|
+
let preCompiled = 0;
|
|
114
|
+
for (const c of loaded.contracts) {
|
|
115
|
+
if (typeof c === "string") {
|
|
116
|
+
try {
|
|
117
|
+
if (!sdk.parseNl(c))
|
|
118
|
+
unparseable.push(c);
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
unparseable.push(c);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
preCompiled++;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
result = {
|
|
129
|
+
path: resolved,
|
|
130
|
+
agent: args.agent ?? "agent",
|
|
131
|
+
mode: loaded.mode,
|
|
132
|
+
detContracts: preCompiled +
|
|
133
|
+
(loaded.contracts.filter((c) => typeof c === "string").length -
|
|
134
|
+
unparseable.length),
|
|
135
|
+
stoContracts: loaded.stoSpecs?.length ?? 0,
|
|
136
|
+
judgeConfigured: !!loaded.judge,
|
|
137
|
+
skipped: loaded.skipped ?? [],
|
|
138
|
+
unparseableNl: unparseable,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
143
|
+
const error = { path: resolved, error: msg };
|
|
144
|
+
if (args.format === "json") {
|
|
145
|
+
process.stdout.write(JSON.stringify(error, null, 2) + "\n");
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
process.stderr.write(`[sponsio] validate failed: ${msg}\n`);
|
|
149
|
+
}
|
|
150
|
+
process.exit(1);
|
|
151
|
+
}
|
|
152
|
+
if (args.format === "json") {
|
|
153
|
+
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
process.stdout.write(renderText(result));
|
|
157
|
+
}
|
|
158
|
+
const hasWarnings = result.skipped.length > 0 ||
|
|
159
|
+
result.unparseableNl.length > 0 ||
|
|
160
|
+
// Sto contracts are not supported in this build (the engine is
|
|
161
|
+
// deterministic-only). They are rejected at load time. Surface as
|
|
162
|
+
// a strict-mode warning so CI catches it.
|
|
163
|
+
result.stoContracts > 0;
|
|
164
|
+
if (args.strict && hasWarnings)
|
|
165
|
+
process.exit(2);
|
|
166
|
+
}
|
|
167
|
+
function renderText(r) {
|
|
168
|
+
const lines = [];
|
|
169
|
+
lines.push(`✓ loaded ${r.path}`);
|
|
170
|
+
lines.push(` agent: ${r.agent}`);
|
|
171
|
+
lines.push(` runtime.mode: ${r.mode ?? "(unset — falls to observe)"}`);
|
|
172
|
+
lines.push(` det contracts: ${r.detContracts}`);
|
|
173
|
+
lines.push(` sto contracts: ${r.stoContracts}${r.stoContracts > 0 ? " (not supported in this build)" : ""}`);
|
|
174
|
+
lines.push(` judge configured: ${r.judgeConfigured ? "yes (not supported in this build)" : "no"}`);
|
|
175
|
+
if (r.unparseableNl.length) {
|
|
176
|
+
lines.push("");
|
|
177
|
+
lines.push(`! ${r.unparseableNl.length} contract(s) failed NL parsing:`);
|
|
178
|
+
for (const c of r.unparseableNl)
|
|
179
|
+
lines.push(` - ${c}`);
|
|
180
|
+
}
|
|
181
|
+
if (r.skipped.length) {
|
|
182
|
+
lines.push("");
|
|
183
|
+
lines.push(`! ${r.skipped.length} yaml item(s) skipped (Python-only):`);
|
|
184
|
+
for (const s of r.skipped)
|
|
185
|
+
lines.push(` - [${s.kind}] ${s.detail}`);
|
|
186
|
+
}
|
|
187
|
+
lines.push("");
|
|
188
|
+
return lines.join("\n");
|
|
189
|
+
}
|
|
190
|
+
async function loadSdk() {
|
|
191
|
+
// Resolve order: installed ``@sponsio/sdk`` > sibling repo path
|
|
192
|
+
// (useful during local dev when ``scan-ts`` runs via npm link but
|
|
193
|
+
// the SDK isn't hoisted). The bare specifier goes through a
|
|
194
|
+
// function-wrapped require so TS doesn't complain when the SDK
|
|
195
|
+
// isn't a declared dep of this package.
|
|
196
|
+
const dynamicImport = new Function("s", "return import(s)");
|
|
197
|
+
try {
|
|
198
|
+
return await dynamicImport("@sponsio/sdk");
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
const devPath = (0, node_path_1.resolve)(__dirname, "..", "..", "ts-sdk", "dist", "index.js");
|
|
202
|
+
return await dynamicImport(devPath);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/cli/validate.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;GAgBG;;AAiFH,wCAsFC;AArKD,qCAAqC;AACrC,yCAAoC;AAUpC,MAAM,IAAI,GACR;IACE,+EAA+E;IAC/E,EAAE;IACF,QAAQ;IACR,qCAAqC;IACrC,EAAE;IACF,YAAY;IACZ,oEAAoE;IACpE,EAAE;IACF,UAAU;IACV,6EAA6E;IAC7E,sEAAsE;IACtE,gDAAgD;IAChD,oCAAoC;IACpC,EAAE;IACF,aAAa;IACb,yEAAyE;IACzE,wDAAwD;IACxD,gFAAgF;CACjF,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAEtB,SAAS,SAAS,CAAC,IAAc;IAC/B,MAAM,CAAC,GAAiB;QACtB,IAAI,EAAE,cAAc;QACpB,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,KAAK;KACZ,CAAC;IACF,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,QAAQ;YAAE,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC;aACjD,IAAI,IAAI,KAAK,SAAS;YAAE,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;aAC5C,IAAI,IAAI,KAAK,UAAU;YAAE,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC;aACzC,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YAC7B,MAAM,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YACpB,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,MAAM,EAAE,CAAC;gBACjC,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,EAAE,CAAC,CAAC;YACjE,CAAC;YACD,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;QACf,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;QAC3C,CAAC;aAAM,CAAC;YACN,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IACD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CACb,qDAAqD,UAAU,CAAC,MAAM,EAAE,CACzE,CAAC;IACJ,CAAC;IACD,IAAI,UAAU,CAAC,CAAC,CAAC;QAAE,CAAC,CAAC,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;IAC1C,OAAO,CAAC,CAAC;AACX,CAAC;AAcM,KAAK,UAAU,cAAc,CAAC,IAAc;IACjD,IAAI,IAAkB,CAAC;IACvB,IAAI,CAAC;QACH,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CACxD,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO;IACT,CAAC;IAED,MAAM,QAAQ,GAAG,IAAA,mBAAO,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACnD,IAAI,CAAC,IAAA,oBAAU,EAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,+BAA+B,QAAQ,IAAI,CAAC,CAAC;QAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,8DAA8D;IAC9D,IAAI,MAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,+DAA+D;QAC/D,+DAA+D;QAC/D,wDAAwD;QACxD,MAAM,GAAG,GAAG,MAAM,OAAO,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,GAAG,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,IAAI,OAAO,CAAC,CAAC;QACrE,uDAAuD;QACvD,4DAA4D;QAC5D,sDAAsD;QACtD,iEAAiE;QACjE,kEAAkE;QAClE,mBAAmB;QACnB,MAAM,WAAW,GAAa,EAAE,CAAC;QACjC,IAAI,WAAW,GAAG,CAAC,CAAC;QACpB,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YACjC,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;gBAC1B,IAAI,CAAC;oBACH,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;wBAAE,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAC3C,CAAC;gBAAC,MAAM,CAAC;oBACP,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACtB,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,WAAW,EAAE,CAAC;YAChB,CAAC;QACH,CAAC;QACD,MAAM,GAAG;YACP,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,OAAO;YAC5B,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,YAAY,EACV,WAAW;gBACX,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,MAAM;oBAC3D,WAAW,CAAC,MAAM,CAAC;YACvB,YAAY,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC;YAC1C,eAAe,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK;YAC/B,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE;YAC7B,aAAa,EAAE,WAAW;SAC3B,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,MAAM,KAAK,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;QAC7C,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAC9D,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,GAAG,IAAI,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC/D,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,WAAW,GACf,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;QACzB,MAAM,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC;QAC/B,+DAA+D;QAC/D,kEAAkE;QAClE,0CAA0C;QAC1C,MAAM,CAAC,YAAY,GAAG,CAAC,CAAC;IAC1B,IAAI,IAAI,CAAC,MAAM,IAAI,WAAW;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,UAAU,CAAC,CAAiB;IACnC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACjC,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;IAC7C,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,IAAI,IAAI,4BAA4B,EAAE,CAAC,CAAC;IAC5E,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC;IACpD,KAAK,CAAC,IAAI,CACR,uBAAuB,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAC,EAAE,EAAE,CACrG,CAAC;IACF,KAAK,CAAC,IAAI,CACR,uBAAuB,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC,CAAC,IAAI,EAAE,CACxF,CAAC;IACF,IAAI,CAAC,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC,MAAM,iCAAiC,CAAC,CAAC;QACzE,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,aAAa;YAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAC5D,CAAC;IACD,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,MAAM,sCAAsC,CAAC,CAAC;QACxE,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO;YAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IACzE,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAiBD,KAAK,UAAU,OAAO;IACpB,gEAAgE;IAChE,kEAAkE;IAClE,4DAA4D;IAC5D,+DAA+D;IAC/D,wCAAwC;IACxC,MAAM,aAAa,GAAG,IAAI,QAAQ,CAChC,GAAG,EACH,kBAAkB,CACe,CAAC;IACpC,IAAI,CAAC;QACH,OAAO,MAAM,aAAa,CAAC,cAAc,CAAC,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,OAAO,GAAG,IAAA,mBAAO,EAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QAC7E,OAAO,MAAM,aAAa,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static Zod-expression → JSON-Schema converter.
|
|
3
|
+
*
|
|
4
|
+
* We never execute the user's code — we read the TypeScript AST and
|
|
5
|
+
* translate common Zod call patterns:
|
|
6
|
+
*
|
|
7
|
+
* z.object({ user_id: z.string(), count: z.number().int() })
|
|
8
|
+
*
|
|
9
|
+
* becomes:
|
|
10
|
+
*
|
|
11
|
+
* { type: "object",
|
|
12
|
+
* properties: {
|
|
13
|
+
* user_id: { type: "string" },
|
|
14
|
+
* count: { type: "integer" }
|
|
15
|
+
* },
|
|
16
|
+
* required: ["user_id", "count"] }
|
|
17
|
+
*
|
|
18
|
+
* Unknown Zod calls degrade to ``{ type: "string" }`` so the tool
|
|
19
|
+
* still shows up in the inventory — downstream heuristics care more
|
|
20
|
+
* about *which* param names exist than their exact types.
|
|
21
|
+
*/
|
|
22
|
+
import { Expression, ObjectLiteralExpression } from "ts-morph";
|
|
23
|
+
import type { JSONSchema, JSONSchemaProperty } from "./types";
|
|
24
|
+
/**
|
|
25
|
+
* Convert a Zod expression (``z.object({ ... })``, ``z.string()``, etc.)
|
|
26
|
+
* into a JSON Schema property. Returns ``{ type: "string" }`` for
|
|
27
|
+
* anything we can't statically decode — the param *name* carries most
|
|
28
|
+
* of the signal for the downstream Sponsio heuristics.
|
|
29
|
+
*/
|
|
30
|
+
export declare function zodExprToJsonSchema(expr: Expression): JSONSchemaProperty;
|
|
31
|
+
/**
|
|
32
|
+
* Translate a ``z.object({...})`` inner literal into a top-level
|
|
33
|
+
* JSON Schema.
|
|
34
|
+
*/
|
|
35
|
+
export declare function objectLiteralToJsonSchema(literal: ObjectLiteralExpression): JSONSchema;
|
|
36
|
+
//# sourceMappingURL=zod.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zod.d.ts","sourceRoot":"","sources":["../../src/cli/zod.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAEL,UAAU,EAEV,uBAAuB,EAGxB,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAkB,MAAM,SAAS,CAAC;AAe9E;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,UAAU,GAAG,kBAAkB,CAoExE;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,uBAAuB,GAC/B,UAAU,CAmBZ"}
|
package/dist/cli/zod.js
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Static Zod-expression → JSON-Schema converter.
|
|
4
|
+
*
|
|
5
|
+
* We never execute the user's code — we read the TypeScript AST and
|
|
6
|
+
* translate common Zod call patterns:
|
|
7
|
+
*
|
|
8
|
+
* z.object({ user_id: z.string(), count: z.number().int() })
|
|
9
|
+
*
|
|
10
|
+
* becomes:
|
|
11
|
+
*
|
|
12
|
+
* { type: "object",
|
|
13
|
+
* properties: {
|
|
14
|
+
* user_id: { type: "string" },
|
|
15
|
+
* count: { type: "integer" }
|
|
16
|
+
* },
|
|
17
|
+
* required: ["user_id", "count"] }
|
|
18
|
+
*
|
|
19
|
+
* Unknown Zod calls degrade to ``{ type: "string" }`` so the tool
|
|
20
|
+
* still shows up in the inventory — downstream heuristics care more
|
|
21
|
+
* about *which* param names exist than their exact types.
|
|
22
|
+
*/
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.zodExprToJsonSchema = zodExprToJsonSchema;
|
|
25
|
+
exports.objectLiteralToJsonSchema = objectLiteralToJsonSchema;
|
|
26
|
+
const ts_morph_1 = require("ts-morph");
|
|
27
|
+
const PRIMITIVE_MAP = {
|
|
28
|
+
string: "string",
|
|
29
|
+
number: "number",
|
|
30
|
+
bigint: "integer",
|
|
31
|
+
boolean: "boolean",
|
|
32
|
+
date: "string",
|
|
33
|
+
null: "null",
|
|
34
|
+
any: "string",
|
|
35
|
+
unknown: "string",
|
|
36
|
+
never: "string",
|
|
37
|
+
void: "null",
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Convert a Zod expression (``z.object({ ... })``, ``z.string()``, etc.)
|
|
41
|
+
* into a JSON Schema property. Returns ``{ type: "string" }`` for
|
|
42
|
+
* anything we can't statically decode — the param *name* carries most
|
|
43
|
+
* of the signal for the downstream Sponsio heuristics.
|
|
44
|
+
*/
|
|
45
|
+
function zodExprToJsonSchema(expr) {
|
|
46
|
+
const call = unwrapChain(expr);
|
|
47
|
+
if (!call)
|
|
48
|
+
return { type: "string" };
|
|
49
|
+
const head = getHeadMethod(call);
|
|
50
|
+
if (!head)
|
|
51
|
+
return { type: "string" };
|
|
52
|
+
// ── z.object({...}) — the only compound shape we emit as ``object``.
|
|
53
|
+
if (head === "object") {
|
|
54
|
+
const firstArg = call.getArguments()[0];
|
|
55
|
+
if (firstArg && ts_morph_1.Node.isObjectLiteralExpression(firstArg)) {
|
|
56
|
+
const nested = objectLiteralToJsonSchema(firstArg);
|
|
57
|
+
return {
|
|
58
|
+
type: "object",
|
|
59
|
+
properties: nested.properties,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
return { type: "object", properties: {} };
|
|
63
|
+
}
|
|
64
|
+
// ── z.array(<inner>) → { type: "array", items: ... }
|
|
65
|
+
if (head === "array") {
|
|
66
|
+
const inner = call.getArguments()[0];
|
|
67
|
+
if (inner && ts_morph_1.Node.isExpression(inner)) {
|
|
68
|
+
return { type: "array", items: zodExprToJsonSchema(inner) };
|
|
69
|
+
}
|
|
70
|
+
return { type: "array", items: { type: "string" } };
|
|
71
|
+
}
|
|
72
|
+
// ── z.enum([...]) → { type: "string", enum: [...] }
|
|
73
|
+
if (head === "enum") {
|
|
74
|
+
const arr = call.getArguments()[0];
|
|
75
|
+
if (arr && ts_morph_1.Node.isArrayLiteralExpression(arr)) {
|
|
76
|
+
const values = arr
|
|
77
|
+
.getElements()
|
|
78
|
+
.map((e) => literalValue(e))
|
|
79
|
+
.filter((v) => v !== undefined);
|
|
80
|
+
return { type: "string", enum: values };
|
|
81
|
+
}
|
|
82
|
+
return { type: "string" };
|
|
83
|
+
}
|
|
84
|
+
// ── z.literal(x) → narrow type + enum
|
|
85
|
+
if (head === "literal") {
|
|
86
|
+
const arg = call.getArguments()[0];
|
|
87
|
+
if (arg && ts_morph_1.Node.isExpression(arg)) {
|
|
88
|
+
const lit = literalValue(arg);
|
|
89
|
+
if (typeof lit === "string")
|
|
90
|
+
return { type: "string", enum: [lit] };
|
|
91
|
+
if (typeof lit === "number")
|
|
92
|
+
return { type: "number", enum: [lit] };
|
|
93
|
+
if (typeof lit === "boolean")
|
|
94
|
+
return { type: "boolean", enum: [lit] };
|
|
95
|
+
}
|
|
96
|
+
return { type: "string" };
|
|
97
|
+
}
|
|
98
|
+
// ── Primitive: z.string(), z.number(), z.boolean(), ...
|
|
99
|
+
const prim = PRIMITIVE_MAP[head];
|
|
100
|
+
if (prim) {
|
|
101
|
+
const base = { type: prim };
|
|
102
|
+
// Walk the method chain beyond the primitive to catch ``.int()``
|
|
103
|
+
// and similar refinements.
|
|
104
|
+
if (head === "number" && chainContains(expr, "int")) {
|
|
105
|
+
base.type = "integer";
|
|
106
|
+
}
|
|
107
|
+
return base;
|
|
108
|
+
}
|
|
109
|
+
// Unknown method — degrade gracefully.
|
|
110
|
+
return { type: "string" };
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Translate a ``z.object({...})`` inner literal into a top-level
|
|
114
|
+
* JSON Schema.
|
|
115
|
+
*/
|
|
116
|
+
function objectLiteralToJsonSchema(literal) {
|
|
117
|
+
const properties = {};
|
|
118
|
+
const required = [];
|
|
119
|
+
for (const prop of literal.getProperties()) {
|
|
120
|
+
if (!ts_morph_1.Node.isPropertyAssignment(prop))
|
|
121
|
+
continue;
|
|
122
|
+
const key = prop.getName().replace(/^['"`]|['"`]$/g, "");
|
|
123
|
+
const init = prop.getInitializer();
|
|
124
|
+
if (!init)
|
|
125
|
+
continue;
|
|
126
|
+
const schema = zodExprToJsonSchema(init);
|
|
127
|
+
properties[key] = schema;
|
|
128
|
+
if (!chainContains(init, "optional") && !chainContains(init, "nullish")) {
|
|
129
|
+
required.push(key);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const out = { type: "object", properties };
|
|
133
|
+
if (required.length)
|
|
134
|
+
out.required = required;
|
|
135
|
+
return out;
|
|
136
|
+
}
|
|
137
|
+
// ---------------------------------------------------------------------------
|
|
138
|
+
// AST walk helpers
|
|
139
|
+
// ---------------------------------------------------------------------------
|
|
140
|
+
/** Return the *deepest* CallExpression in a ``a.b().c().d()`` chain. */
|
|
141
|
+
function unwrapChain(expr) {
|
|
142
|
+
let cur = expr;
|
|
143
|
+
while (cur) {
|
|
144
|
+
if (ts_morph_1.Node.isCallExpression(cur))
|
|
145
|
+
return cur;
|
|
146
|
+
if (ts_morph_1.Node.isPropertyAccessExpression(cur)) {
|
|
147
|
+
cur = cur.getExpression();
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
return undefined;
|
|
151
|
+
}
|
|
152
|
+
return undefined;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Return the *head* method name of a Zod chain —
|
|
156
|
+
* ``z.string().min(3).optional()`` → ``"string"``. This is the
|
|
157
|
+
* identifier immediately following the root ``z.`` / variable.
|
|
158
|
+
*/
|
|
159
|
+
function getHeadMethod(call) {
|
|
160
|
+
let cur = call;
|
|
161
|
+
let last;
|
|
162
|
+
while (cur) {
|
|
163
|
+
if (ts_morph_1.Node.isCallExpression(cur)) {
|
|
164
|
+
const callee = cur.getExpression();
|
|
165
|
+
if (ts_morph_1.Node.isPropertyAccessExpression(callee)) {
|
|
166
|
+
last = callee.getName();
|
|
167
|
+
cur = callee.getExpression();
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if (ts_morph_1.Node.isIdentifier(callee)) {
|
|
171
|
+
return callee.getText();
|
|
172
|
+
}
|
|
173
|
+
return last;
|
|
174
|
+
}
|
|
175
|
+
if (ts_morph_1.Node.isPropertyAccessExpression(cur)) {
|
|
176
|
+
last = cur.getName();
|
|
177
|
+
cur = cur.getExpression();
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
return last;
|
|
181
|
+
}
|
|
182
|
+
return last;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Does any node in the method chain (at any depth) call a method
|
|
186
|
+
* whose name matches ``target``? Used to detect ``.optional()`` and
|
|
187
|
+
* ``.int()`` refiners.
|
|
188
|
+
*/
|
|
189
|
+
function chainContains(expr, target) {
|
|
190
|
+
let found = false;
|
|
191
|
+
expr.forEachDescendant((node, traversal) => {
|
|
192
|
+
if (ts_morph_1.Node.isCallExpression(node) &&
|
|
193
|
+
ts_morph_1.Node.isPropertyAccessExpression(node.getExpression()) &&
|
|
194
|
+
node.getExpression().getName() === target) {
|
|
195
|
+
found = true;
|
|
196
|
+
traversal.stop();
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
if (found)
|
|
200
|
+
return true;
|
|
201
|
+
// Also check the immediate expression itself
|
|
202
|
+
if (ts_morph_1.Node.isCallExpression(expr)) {
|
|
203
|
+
const callee = expr.getExpression();
|
|
204
|
+
if (ts_morph_1.Node.isPropertyAccessExpression(callee) &&
|
|
205
|
+
callee.getName() === target) {
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
/** Extract a literal JS value from an AST node, or ``undefined``. */
|
|
212
|
+
function literalValue(node) {
|
|
213
|
+
if (ts_morph_1.Node.isStringLiteral(node) || ts_morph_1.Node.isNoSubstitutionTemplateLiteral(node)) {
|
|
214
|
+
return node.getLiteralText();
|
|
215
|
+
}
|
|
216
|
+
if (ts_morph_1.Node.isNumericLiteral(node)) {
|
|
217
|
+
return Number(node.getLiteralText());
|
|
218
|
+
}
|
|
219
|
+
const k = node.getKind();
|
|
220
|
+
if (k === ts_morph_1.SyntaxKind.TrueKeyword)
|
|
221
|
+
return true;
|
|
222
|
+
if (k === ts_morph_1.SyntaxKind.FalseKeyword)
|
|
223
|
+
return false;
|
|
224
|
+
return undefined;
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=zod.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zod.js","sourceRoot":"","sources":["../../src/cli/zod.ts"],"names":[],"mappings":"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"}
|
package/dist/contract.d.ts
CHANGED
|
@@ -11,16 +11,16 @@
|
|
|
11
11
|
* contracts: [
|
|
12
12
|
* contract("refund policy gate")
|
|
13
13
|
* .assume("called `issue_refund`")
|
|
14
|
-
* .
|
|
14
|
+
* .guarantees("must call `check_policy` before `issue_refund`"),
|
|
15
15
|
* contract("rate cap")
|
|
16
|
-
* .
|
|
16
|
+
* .guarantees("tool `issue_refund` at most 3 times"),
|
|
17
17
|
* ],
|
|
18
18
|
* });
|
|
19
19
|
*
|
|
20
|
-
* Repeated ``.assume`` / ``.
|
|
20
|
+
* Repeated ``.assume`` / ``.guarantees`` calls AND-combine (matching
|
|
21
21
|
* the Python builder). If ``.assume`` is omitted the contract is
|
|
22
|
-
* unconditional and the
|
|
23
|
-
* ``.assume`` is present the formula is ``A ->
|
|
22
|
+
* unconditional and the guarantee formula is used as-is. If
|
|
23
|
+
* ``.assume`` is present the formula is ``A -> G``.
|
|
24
24
|
*
|
|
25
25
|
* The builder satisfies ``DetFormula`` structurally, so it can be
|
|
26
26
|
* passed directly to ``Sponsio({ contracts: [...] })`` — no ``build()``
|
|
@@ -33,23 +33,23 @@ export declare class ContractBuilder implements DetFormula {
|
|
|
33
33
|
readonly patternName: string;
|
|
34
34
|
readonly liveness: boolean;
|
|
35
35
|
private _assumption;
|
|
36
|
-
private
|
|
36
|
+
private _guarantee;
|
|
37
37
|
constructor(desc?: string);
|
|
38
38
|
/** Add an assumption clause (A side). Repeated calls AND-combine. */
|
|
39
39
|
assume(clause: string | DetFormula): ContractBuilder;
|
|
40
|
-
/** Add
|
|
41
|
-
|
|
40
|
+
/** Add a guarantee clause (G side). Repeated calls AND-combine. */
|
|
41
|
+
guarantees(clause: string | DetFormula): ContractBuilder;
|
|
42
42
|
/**
|
|
43
43
|
* The compiled LTL formula. Accessed at `Sponsio` construction time.
|
|
44
44
|
*
|
|
45
|
-
* - If both A and
|
|
46
|
-
* the evaluator runs from ``pos=0``; a bare ``Implies(A,
|
|
45
|
+
* - If both A and G are set: ``G(A -> G_)``. We wrap in ``G`` because
|
|
46
|
+
* the evaluator runs from ``pos=0``; a bare ``Implies(A, G_)`` would
|
|
47
47
|
* short-circuit whenever ``A`` was false at step 0 regardless of
|
|
48
48
|
* later events. ``G`` lifts the implication to every step so the
|
|
49
|
-
*
|
|
50
|
-
* - If only
|
|
49
|
+
* guarantee fires whenever the assumption holds.
|
|
50
|
+
* - If only G: ``G_`` (unconditional; the pattern factories already
|
|
51
51
|
* emit safety properties wrapped in ``G`` where needed).
|
|
52
|
-
* - If neither: throws — every contract needs
|
|
52
|
+
* - If neither: throws — every contract needs a guarantee.
|
|
53
53
|
*/
|
|
54
54
|
get formula(): Formula;
|
|
55
55
|
private _clone;
|
package/dist/contract.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAGH,OAAO,EAAmB,KAAK,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,qBAAa,eAAgB,YAAW,UAAU;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAc;IAC1C,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAS;IAEnC,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAGH,OAAO,EAAmB,KAAK,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,qBAAa,eAAgB,YAAW,UAAU;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAc;IAC1C,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAS;IAEnC,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,UAAU,CAAiB;gBAEvB,IAAI,CAAC,EAAE,MAAM;IAMzB,qEAAqE;IACrE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,eAAe;IAOpD,mEAAmE;IACnE,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,eAAe;IAOxD;;;;;;;;;;;OAWG;IACH,IAAI,OAAO,IAAI,OAAO,CASrB;IAED,OAAO,CAAC,MAAM;CAMf;AAeD,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,eAAe,CAEvD"}
|
package/dist/contract.js
CHANGED
|
@@ -11,16 +11,16 @@
|
|
|
11
11
|
* contracts: [
|
|
12
12
|
* contract("refund policy gate")
|
|
13
13
|
* .assume("called `issue_refund`")
|
|
14
|
-
* .
|
|
14
|
+
* .guarantees("must call `check_policy` before `issue_refund`"),
|
|
15
15
|
* contract("rate cap")
|
|
16
|
-
* .
|
|
16
|
+
* .guarantees("tool `issue_refund` at most 3 times"),
|
|
17
17
|
* ],
|
|
18
18
|
* });
|
|
19
19
|
*
|
|
20
|
-
* Repeated ``.assume`` / ``.
|
|
20
|
+
* Repeated ``.assume`` / ``.guarantees`` calls AND-combine (matching
|
|
21
21
|
* the Python builder). If ``.assume`` is omitted the contract is
|
|
22
|
-
* unconditional and the
|
|
23
|
-
* ``.assume`` is present the formula is ``A ->
|
|
22
|
+
* unconditional and the guarantee formula is used as-is. If
|
|
23
|
+
* ``.assume`` is present the formula is ``A -> G``.
|
|
24
24
|
*
|
|
25
25
|
* The builder satisfies ``DetFormula`` structurally, so it can be
|
|
26
26
|
* passed directly to ``Sponsio({ contracts: [...] })`` — no ``build()``
|
|
@@ -33,11 +33,11 @@ export class ContractBuilder {
|
|
|
33
33
|
patternName = "contract";
|
|
34
34
|
liveness = false;
|
|
35
35
|
_assumption;
|
|
36
|
-
|
|
36
|
+
_guarantee;
|
|
37
37
|
constructor(desc) {
|
|
38
38
|
this.desc = desc ?? "contract";
|
|
39
39
|
this._assumption = null;
|
|
40
|
-
this.
|
|
40
|
+
this._guarantee = null;
|
|
41
41
|
}
|
|
42
42
|
/** Add an assumption clause (A side). Repeated calls AND-combine. */
|
|
43
43
|
assume(clause) {
|
|
@@ -46,37 +46,37 @@ export class ContractBuilder {
|
|
|
46
46
|
next._assumption = next._assumption ? new And(next._assumption, f) : f;
|
|
47
47
|
return next;
|
|
48
48
|
}
|
|
49
|
-
/** Add
|
|
50
|
-
|
|
49
|
+
/** Add a guarantee clause (G side). Repeated calls AND-combine. */
|
|
50
|
+
guarantees(clause) {
|
|
51
51
|
const next = this._clone();
|
|
52
|
-
const f = toFormula(clause, "
|
|
53
|
-
next.
|
|
52
|
+
const f = toFormula(clause, "guarantees");
|
|
53
|
+
next._guarantee = next._guarantee ? new And(next._guarantee, f) : f;
|
|
54
54
|
return next;
|
|
55
55
|
}
|
|
56
56
|
/**
|
|
57
57
|
* The compiled LTL formula. Accessed at `Sponsio` construction time.
|
|
58
58
|
*
|
|
59
|
-
* - If both A and
|
|
60
|
-
* the evaluator runs from ``pos=0``; a bare ``Implies(A,
|
|
59
|
+
* - If both A and G are set: ``G(A -> G_)``. We wrap in ``G`` because
|
|
60
|
+
* the evaluator runs from ``pos=0``; a bare ``Implies(A, G_)`` would
|
|
61
61
|
* short-circuit whenever ``A`` was false at step 0 regardless of
|
|
62
62
|
* later events. ``G`` lifts the implication to every step so the
|
|
63
|
-
*
|
|
64
|
-
* - If only
|
|
63
|
+
* guarantee fires whenever the assumption holds.
|
|
64
|
+
* - If only G: ``G_`` (unconditional; the pattern factories already
|
|
65
65
|
* emit safety properties wrapped in ``G`` where needed).
|
|
66
|
-
* - If neither: throws — every contract needs
|
|
66
|
+
* - If neither: throws — every contract needs a guarantee.
|
|
67
67
|
*/
|
|
68
68
|
get formula() {
|
|
69
|
-
if (!this.
|
|
70
|
-
throw new Error(`contract(${JSON.stringify(this.desc)}): .
|
|
69
|
+
if (!this._guarantee) {
|
|
70
|
+
throw new Error(`contract(${JSON.stringify(this.desc)}): .guarantees(...) is required`);
|
|
71
71
|
}
|
|
72
72
|
return this._assumption
|
|
73
|
-
? new G(new Implies(this._assumption, this.
|
|
74
|
-
: this.
|
|
73
|
+
? new G(new Implies(this._assumption, this._guarantee))
|
|
74
|
+
: this._guarantee;
|
|
75
75
|
}
|
|
76
76
|
_clone() {
|
|
77
77
|
const next = new ContractBuilder(this.desc);
|
|
78
78
|
next._assumption = this._assumption;
|
|
79
|
-
next.
|
|
79
|
+
next._guarantee = this._guarantee;
|
|
80
80
|
return next;
|
|
81
81
|
}
|
|
82
82
|
}
|
package/dist/contract.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,OAAO,EAAgB,MAAM,mBAAmB,CAAC;AAGlE,MAAM,OAAO,eAAe;IACjB,IAAI,CAAS;IACb,WAAW,GAAW,UAAU,CAAC;IACjC,QAAQ,GAAY,KAAK,CAAC;IAE3B,WAAW,CAAiB;IAC5B,
|
|
1
|
+
{"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,OAAO,EAAgB,MAAM,mBAAmB,CAAC;AAGlE,MAAM,OAAO,eAAe;IACjB,IAAI,CAAS;IACb,WAAW,GAAW,UAAU,CAAC;IACjC,QAAQ,GAAY,KAAK,CAAC;IAE3B,WAAW,CAAiB;IAC5B,UAAU,CAAiB;IAEnC,YAAY,IAAa;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,UAAU,CAAC;QAC/B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;IACzB,CAAC;IAED,qEAAqE;IACrE,MAAM,CAAC,MAA2B;QAChC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACtC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACvE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,mEAAmE;IACnE,UAAU,CAAC,MAA2B;QACpC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QAC1C,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACpE,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;;OAWG;IACH,IAAI,OAAO;QACT,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CACb,YAAY,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,iCAAiC,CACvE,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC,WAAW;YACrB,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;YACvD,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC;IACtB,CAAC;IAEO,MAAM;QACZ,MAAM,IAAI,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QACpC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED,SAAS,SAAS,CAAC,MAA2B,EAAE,KAAa;IAC3D,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CACb,cAAc,KAAK,KAAK,MAAM,+BAA+B,CAC9D,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,CAAC,OAAO,CAAC;IACxB,CAAC;IACD,OAAO,MAAM,CAAC,OAAO,CAAC;AACxB,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,QAAQ,CAAC,IAAa;IACpC,OAAO,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC;AACnC,CAAC"}
|