@once-agent/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +43 -0
  3. package/dist/apply.d.ts +9 -0
  4. package/dist/apply.d.ts.map +1 -0
  5. package/dist/apply.js +265 -0
  6. package/dist/apply.js.map +1 -0
  7. package/dist/cli.d.ts +3 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +191 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/index.d.ts +76 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +240 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/protect.d.ts +8 -0
  16. package/dist/protect.d.ts.map +1 -0
  17. package/dist/protect.js +563 -0
  18. package/dist/protect.js.map +1 -0
  19. package/dist/scan.d.ts +18 -0
  20. package/dist/scan.d.ts.map +1 -0
  21. package/dist/scan.js +632 -0
  22. package/dist/scan.js.map +1 -0
  23. package/dist/setup.d.ts +8 -0
  24. package/dist/setup.d.ts.map +1 -0
  25. package/dist/setup.js +558 -0
  26. package/dist/setup.js.map +1 -0
  27. package/dist/transformers/http-patch-plan-v1.d.ts +23 -0
  28. package/dist/transformers/http-patch-plan-v1.d.ts.map +1 -0
  29. package/dist/transformers/http-patch-plan-v1.js +149 -0
  30. package/dist/transformers/http-patch-plan-v1.js.map +1 -0
  31. package/dist/transformers/http-write-v1.d.ts +23 -0
  32. package/dist/transformers/http-write-v1.d.ts.map +1 -0
  33. package/dist/transformers/http-write-v1.js +134 -0
  34. package/dist/transformers/http-write-v1.js.map +1 -0
  35. package/dist/transformers/once-binding-v1.d.ts +17 -0
  36. package/dist/transformers/once-binding-v1.d.ts.map +1 -0
  37. package/dist/transformers/once-binding-v1.js +134 -0
  38. package/dist/transformers/once-binding-v1.js.map +1 -0
  39. package/package.json +56 -0
@@ -0,0 +1,149 @@
1
+ import { createHash } from "node:crypto";
2
+ import { transformHttpWriteV1 } from "./http-write-v1.js";
3
+ import { bindOnceCallSiteV1 } from "./once-binding-v1.js";
4
+ export const HTTP_WRITE_PATCH_PLAN_ID = "ts_fetch_post_void_patch_v1";
5
+ function sha256(value) {
6
+ return createHash("sha256")
7
+ .update(value, "utf8")
8
+ .digest("hex");
9
+ }
10
+ function countExact(source, needle) {
11
+ if (!needle) {
12
+ return 0;
13
+ }
14
+ let count = 0;
15
+ let offset = 0;
16
+ while (true) {
17
+ const index = source.indexOf(needle, offset);
18
+ if (index < 0) {
19
+ break;
20
+ }
21
+ count++;
22
+ offset =
23
+ index +
24
+ needle.length;
25
+ }
26
+ return count;
27
+ }
28
+ function indentReplacement(source, index, replacement) {
29
+ const lineStart = source.lastIndexOf("\n", Math.max(0, index - 1)) + 1;
30
+ const prefix = source.slice(lineStart, index);
31
+ /*
32
+ * We only replace a standalone statement.
33
+ * Anything executable before it on the same
34
+ * line is outside the proven patch model.
35
+ */
36
+ if (!/^[ \t]*$/.test(prefix)) {
37
+ return null;
38
+ }
39
+ return replacement
40
+ .split("\n")
41
+ .map((line, lineIndex) => lineIndex === 0
42
+ ? line
43
+ : prefix + line)
44
+ .join("\n");
45
+ }
46
+ export function buildHttpWritePatchV1(input) {
47
+ const source = input.source.replace(/\r\n/g, "\n");
48
+ const statement = input.statement
49
+ .replace(/\r\n/g, "\n")
50
+ .trim();
51
+ if (!statement) {
52
+ return {
53
+ eligible: false,
54
+ reason: "The source statement is empty."
55
+ };
56
+ }
57
+ const transformer = transformHttpWriteV1({
58
+ statement,
59
+ functionSource: input.functionSource,
60
+ provider: input.provider
61
+ });
62
+ if (!transformer.eligible) {
63
+ return {
64
+ eligible: false,
65
+ reason: transformer.reason
66
+ };
67
+ }
68
+ /*
69
+ * Fail closed if the exact statement occurs
70
+ * more than once. An automatic patch must
71
+ * have one unambiguous target.
72
+ */
73
+ const originalOccurrences = countExact(source, statement);
74
+ if (originalOccurrences !== 1) {
75
+ return {
76
+ eligible: false,
77
+ reason: `Expected exactly one exact source statement; found ${originalOccurrences}.`
78
+ };
79
+ }
80
+ const binding = bindOnceCallSiteV1(source, transformer.replacement);
81
+ if (!binding.eligible) {
82
+ return {
83
+ eligible: false,
84
+ reason: binding.reason
85
+ };
86
+ }
87
+ const sourceWithImport = binding.sourceWithImport;
88
+ const occurrencesAfterImport = countExact(sourceWithImport, statement);
89
+ if (occurrencesAfterImport !== 1) {
90
+ return {
91
+ eligible: false,
92
+ reason: "Import insertion changed or duplicated the target statement."
93
+ };
94
+ }
95
+ const index = sourceWithImport.indexOf(statement);
96
+ if (index < 0) {
97
+ return {
98
+ eligible: false,
99
+ reason: "Exact source statement disappeared before replacement."
100
+ };
101
+ }
102
+ const replacement = indentReplacement(sourceWithImport, index, binding.boundReplacement);
103
+ if (!replacement) {
104
+ return {
105
+ eligible: false,
106
+ reason: "Target statement is not isolated on its source line."
107
+ };
108
+ }
109
+ const proposedSource = sourceWithImport.slice(0, index) +
110
+ replacement +
111
+ sourceWithImport.slice(index +
112
+ statement.length);
113
+ if (countExact(proposedSource, statement) !== 0) {
114
+ return {
115
+ eligible: false,
116
+ reason: "Original consequential statement remains after transformation."
117
+ };
118
+ }
119
+ const importCount = countExact(proposedSource, binding.importStatement);
120
+ if (importCount !== 1) {
121
+ return {
122
+ eligible: false,
123
+ reason: `Expected one Once SDK import; found ${importCount}.`
124
+ };
125
+ }
126
+ const executionCount = (proposedSource.match(/\bnew\s+__OnceAgentClient\(\)\.execute\s*\(/g) ?? []).length;
127
+ if (executionCount !== 1) {
128
+ return {
129
+ eligible: false,
130
+ reason: `Expected one bound Once execution; found ${executionCount}.`
131
+ };
132
+ }
133
+ if (/\bawait\s+once\.execute\s*\(/.test(proposedSource)) {
134
+ return {
135
+ eligible: false,
136
+ reason: "Unbound transformer call remains in proposed source."
137
+ };
138
+ }
139
+ return {
140
+ eligible: true,
141
+ patchPlan: HTTP_WRITE_PATCH_PLAN_ID,
142
+ transformerId: transformer.transformer,
143
+ bindingStrategy: "call-site-constructor",
144
+ proposedSource,
145
+ sourceSha256: sha256(source),
146
+ proposedSourceSha256: sha256(proposedSource)
147
+ };
148
+ }
149
+ //# sourceMappingURL=http-patch-plan-v1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-patch-plan-v1.js","sourceRoot":"","sources":["../../src/transformers/http-patch-plan-v1.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ export declare const HTTP_WRITE_TRANSFORMER_ID: "ts_fetch_post_void_v1";
2
+ export type HttpWriteTransformInput = {
3
+ statement: string;
4
+ functionSource: string;
5
+ provider: string;
6
+ };
7
+ export type HttpWriteTransformSuccess = {
8
+ eligible: true;
9
+ transformer: typeof HTTP_WRITE_TRANSFORMER_ID;
10
+ replacement: string;
11
+ actionType: "http_write_v1";
12
+ method: "POST";
13
+ url: string;
14
+ bodyExpression: string;
15
+ requiresOnceBinding: true;
16
+ };
17
+ export type HttpWriteTransformFailure = {
18
+ eligible: false;
19
+ reason: string;
20
+ };
21
+ export type HttpWriteTransformResult = HttpWriteTransformSuccess | HttpWriteTransformFailure;
22
+ export declare function transformHttpWriteV1(input: HttpWriteTransformInput): HttpWriteTransformResult;
23
+ //# sourceMappingURL=http-write-v1.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-write-v1.d.ts","sourceRoot":"","sources":["../../src/transformers/http-write-v1.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,yBAAyB,EACpC,uBAAgC,CAAC;AAEnC,MAAM,MAAM,uBAAuB,GAAG;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,QAAQ,EAAE,IAAI,CAAC;IACf,WAAW,EACT,OAAO,yBAAyB,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,eAAe,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB,EAAE,IAAI,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,QAAQ,EAAE,KAAK,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAChC,yBAAyB,GACzB,yBAAyB,CAAC;AA4C9B,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,uBAAuB,GAC7B,wBAAwB,CAqM1B"}
@@ -0,0 +1,134 @@
1
+ export const HTTP_WRITE_TRANSFORMER_ID = "ts_fetch_post_void_v1";
2
+ function hasOperationIdParameter(functionSource) {
3
+ const match = functionSource.match(/\(([^)]*)\)/);
4
+ if (!match) {
5
+ return false;
6
+ }
7
+ const parameters = match[1]
8
+ .split(",")
9
+ .map(parameter => parameter
10
+ .trim()
11
+ .replace(/^\.\.\./, "")
12
+ .split(/[:=]/)[0]
13
+ .trim());
14
+ return parameters.includes("operationId");
15
+ }
16
+ function quote(value) {
17
+ return JSON.stringify(value);
18
+ }
19
+ export function transformHttpWriteV1(input) {
20
+ const provider = input.provider.trim();
21
+ if (!provider) {
22
+ return {
23
+ eligible: false,
24
+ reason: "A configured provider is required."
25
+ };
26
+ }
27
+ if (!hasOperationIdParameter(input.functionSource)) {
28
+ return {
29
+ eligible: false,
30
+ reason: "The surrounding function must already receive a stable operationId parameter."
31
+ };
32
+ }
33
+ const statement = input.statement
34
+ .replace(/\r\n/g, "\n")
35
+ .trim();
36
+ /*
37
+ * Deliberately require an unused-response
38
+ * await fetch(...) expression statement.
39
+ *
40
+ * return await fetch(...)
41
+ * const x = await fetch(...)
42
+ *
43
+ * are not accepted because Once.execute()
44
+ * does not have the same return contract as
45
+ * the native Fetch Response object.
46
+ */
47
+ if (!/^await\s+fetch\s*\(/.test(statement)) {
48
+ return {
49
+ eligible: false,
50
+ reason: "Only an unused-response `await fetch(...)` statement is supported."
51
+ };
52
+ }
53
+ const callMatch = statement.match(/^await\s+fetch\s*\(\s*(["'])(https:\/\/[^"'\\]+)\1\s*,\s*\{([\s\S]*)\}\s*\)\s*;?$/);
54
+ if (!callMatch) {
55
+ return {
56
+ eligible: false,
57
+ reason: "Only a literal HTTPS URL and an inline fetch options object are supported."
58
+ };
59
+ }
60
+ const url = callMatch[2];
61
+ const options = callMatch[3];
62
+ /*
63
+ * v0.6 allows exactly two fetch options:
64
+ *
65
+ * method
66
+ * body
67
+ *
68
+ * Anything else requires a richer
69
+ * semantics-preserving transformer.
70
+ */
71
+ const keys = Array.from(options.matchAll(/(?:^|,|\n)\s*([A-Za-z_$][A-Za-z0-9_$]*)\s*:/g), match => match[1]);
72
+ const uniqueKeys = Array.from(new Set(keys)).sort();
73
+ if (uniqueKeys.length !== 2 ||
74
+ uniqueKeys[0] !== "body" ||
75
+ uniqueKeys[1] !== "method") {
76
+ return {
77
+ eligible: false,
78
+ reason: "v0.6 supports exactly the fetch options `method` and `body`."
79
+ };
80
+ }
81
+ const methodMatch = options.match(/\bmethod\s*:\s*(["'])POST\1/);
82
+ if (!methodMatch) {
83
+ return {
84
+ eligible: false,
85
+ reason: "v0.6 supports only literal POST requests."
86
+ };
87
+ }
88
+ const bodyMatch = options.match(/\bbody\s*:\s*JSON\.stringify\(\s*([A-Za-z_$][A-Za-z0-9_$]*(?:\.[A-Za-z_$][A-Za-z0-9_$]*)*)\s*\)/);
89
+ if (!bodyMatch) {
90
+ return {
91
+ eligible: false,
92
+ reason: "v0.6 requires body: JSON.stringify(<simple expression>)."
93
+ };
94
+ }
95
+ const bodyExpression = bodyMatch[1];
96
+ /*
97
+ * Ensure the recognized expressions account
98
+ * for the expected option values rather than
99
+ * accepting an object containing additional
100
+ * unsupported executable syntax.
101
+ */
102
+ const methodOccurrences = (options.match(/\bmethod\s*:/g) ?? []).length;
103
+ const bodyOccurrences = (options.match(/\bbody\s*:/g) ?? []).length;
104
+ if (methodOccurrences !== 1 ||
105
+ bodyOccurrences !== 1) {
106
+ return {
107
+ eligible: false,
108
+ reason: "Duplicate method/body options are not supported."
109
+ };
110
+ }
111
+ const replacement = [
112
+ "await once.execute({",
113
+ " operationId,",
114
+ ` provider: ${quote(provider)},`,
115
+ " action: {",
116
+ ' type: "http_write_v1",',
117
+ ' method: "POST",',
118
+ ` url: ${quote(url)},`,
119
+ ` body_json: JSON.stringify(${bodyExpression})`,
120
+ " }",
121
+ "});"
122
+ ].join("\n");
123
+ return {
124
+ eligible: true,
125
+ transformer: HTTP_WRITE_TRANSFORMER_ID,
126
+ replacement,
127
+ actionType: "http_write_v1",
128
+ method: "POST",
129
+ url,
130
+ bodyExpression,
131
+ requiresOnceBinding: true
132
+ };
133
+ }
134
+ //# sourceMappingURL=http-write-v1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-write-v1.js","sourceRoot":"","sources":["../../src/transformers/http-write-v1.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export declare const ONCE_CLIENT_ALIAS: "__OnceAgentClient";
2
+ export declare const ONCE_IMPORT: "import { Once as __OnceAgentClient } from \"@once-agent/sdk\";";
3
+ export type OnceBindingSuccess = {
4
+ eligible: true;
5
+ importStatement: typeof ONCE_IMPORT;
6
+ clientAlias: typeof ONCE_CLIENT_ALIAS;
7
+ sourceWithImport: string;
8
+ boundReplacement: string;
9
+ constructorTiming: "call-site";
10
+ };
11
+ export type OnceBindingFailure = {
12
+ eligible: false;
13
+ reason: string;
14
+ };
15
+ export type OnceBindingResult = OnceBindingSuccess | OnceBindingFailure;
16
+ export declare function bindOnceCallSiteV1(source: string, replacement: string): OnceBindingResult;
17
+ //# sourceMappingURL=once-binding-v1.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"once-binding-v1.d.ts","sourceRoot":"","sources":["../../src/transformers/once-binding-v1.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,EAC5B,mBAA4B,CAAC;AAE/B,eAAO,MAAM,WAAW,EACtB,gEAAuE,CAAC;AAE1E,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,IAAI,CAAC;IACf,eAAe,EACb,OAAO,WAAW,CAAC;IACrB,WAAW,EACT,OAAO,iBAAiB,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,WAAW,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,KAAK,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GACzB,kBAAkB,GAClB,kBAAkB,CAAC;AA+MvB,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,iBAAiB,CAiFnB"}
@@ -0,0 +1,134 @@
1
+ export const ONCE_CLIENT_ALIAS = "__OnceAgentClient";
2
+ export const ONCE_IMPORT = 'import { Once as __OnceAgentClient } from "@once-agent/sdk";';
3
+ function hasEsmSyntax(source) {
4
+ return (/(^|\n)\s*import\s+/m.test(source) ||
5
+ /(^|\n)\s*export\s+/m.test(source));
6
+ }
7
+ function aliasExists(source) {
8
+ return new RegExp(`\\b${ONCE_CLIENT_ALIAS}\\b`).test(source);
9
+ }
10
+ function findImportInsertionOffset(source) {
11
+ let cursor = source.charCodeAt(0) ===
12
+ 0xFEFF
13
+ ? 1
14
+ : 0;
15
+ /*
16
+ * Preserve a Node shebang.
17
+ */
18
+ if (source.startsWith("#!", cursor)) {
19
+ const newline = source.indexOf("\n", cursor);
20
+ cursor =
21
+ newline < 0
22
+ ? source.length
23
+ : newline + 1;
24
+ }
25
+ /*
26
+ * Preserve the directive prologue:
27
+ *
28
+ * "use client";
29
+ * "use strict";
30
+ *
31
+ * Comments and whitespace do not end a directive
32
+ * prologue, so skip them while searching.
33
+ */
34
+ let search = cursor;
35
+ let lastDirectiveEnd = cursor;
36
+ while (search <
37
+ source.length) {
38
+ const whitespace = source
39
+ .slice(search)
40
+ .match(/^[ \t\r\n]+/);
41
+ if (whitespace) {
42
+ search +=
43
+ whitespace[0].length;
44
+ }
45
+ if (source.startsWith("//", search)) {
46
+ const newline = source.indexOf("\n", search);
47
+ search =
48
+ newline < 0
49
+ ? source.length
50
+ : newline + 1;
51
+ continue;
52
+ }
53
+ if (source.startsWith("/*", search)) {
54
+ const close = source.indexOf("*/", search + 2);
55
+ if (close < 0) {
56
+ return cursor;
57
+ }
58
+ search =
59
+ close + 2;
60
+ continue;
61
+ }
62
+ const directive = source
63
+ .slice(search)
64
+ .match(/^(["'])(?:\\.|(?!\1)[^\\\r\n])*\1\s*;?/);
65
+ if (!directive) {
66
+ break;
67
+ }
68
+ search +=
69
+ directive[0].length;
70
+ /*
71
+ * Include the remainder of the directive line.
72
+ */
73
+ const newline = source.indexOf("\n", search);
74
+ lastDirectiveEnd =
75
+ newline < 0
76
+ ? source.length
77
+ : newline + 1;
78
+ search =
79
+ lastDirectiveEnd;
80
+ }
81
+ return lastDirectiveEnd;
82
+ }
83
+ function insertOnceImport(source) {
84
+ const offset = findImportInsertionOffset(source);
85
+ const before = source.slice(0, offset);
86
+ const after = source.slice(offset);
87
+ const separatorBefore = before.length > 0 &&
88
+ !before.endsWith("\n")
89
+ ? "\n"
90
+ : "";
91
+ return (before +
92
+ separatorBefore +
93
+ ONCE_IMPORT +
94
+ "\n" +
95
+ after);
96
+ }
97
+ export function bindOnceCallSiteV1(source, replacement) {
98
+ if (!hasEsmSyntax(source)) {
99
+ return {
100
+ eligible: false,
101
+ reason: "v0.8 automatic binding supports ESM TypeScript modules only."
102
+ };
103
+ }
104
+ if (aliasExists(source)) {
105
+ return {
106
+ eligible: false,
107
+ reason: `Reserved Once client alias ${ONCE_CLIENT_ALIAS} already exists in the source file.`
108
+ };
109
+ }
110
+ const calls = replacement.match(/\bawait\s+once\.execute\s*\(/g) ?? [];
111
+ if (calls.length !== 1) {
112
+ return {
113
+ eligible: false,
114
+ reason: "Expected exactly one transformer-generated await once.execute(...) call."
115
+ };
116
+ }
117
+ const boundReplacement = replacement.replace(/\bawait\s+once\.execute\s*\(/, `await new ${ONCE_CLIENT_ALIAS}().execute(`);
118
+ if (/\bconst\s+once\b/.test(boundReplacement) ||
119
+ /\blet\s+once\b/.test(boundReplacement)) {
120
+ return {
121
+ eligible: false,
122
+ reason: "Generated binding unexpectedly introduced a persistent once variable."
123
+ };
124
+ }
125
+ return {
126
+ eligible: true,
127
+ importStatement: ONCE_IMPORT,
128
+ clientAlias: ONCE_CLIENT_ALIAS,
129
+ sourceWithImport: insertOnceImport(source),
130
+ boundReplacement,
131
+ constructorTiming: "call-site"
132
+ };
133
+ }
134
+ //# sourceMappingURL=once-binding-v1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"once-binding-v1.js","sourceRoot":"","sources":["../../src/transformers/once-binding-v1.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@once-agent/sdk",
3
+ "version": "0.1.0",
4
+ "description": "Execution safety for side-effecting AI agent tools.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "README.md"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "typecheck": "tsc --noEmit",
21
+ "benchmark:scan": "npm run build && node ./scripts/scan-benchmark.mjs",
22
+ "test:contract": "npm run build && tsc --noEmit --target ES2022 --module NodeNext --moduleResolution NodeNext --strict --types node ./scripts/sdk-contract-types.ts && node ./scripts/sdk-contract-runtime.mjs",
23
+ "test:release": "npm run benchmark:scan && npm run test:scanner-declarations && npm run test:contract && npm run test:protect && npm run test:capabilities && npm run test:transformer && npm run test:binding && npm run test:patch-planner && npm run test:transformer-protect && npm run test:apply && npm run test:id-conformance && npm run test:consumer && npm run test:package",
24
+ "test:protect": "npm run build && node ./scripts/protect-regression.mjs",
25
+ "test:capabilities": "npm run build && node ./scripts/capability-regression.mjs",
26
+ "test:transformer": "npm run build && node ./scripts/http-transformer-regression.mjs",
27
+ "test:scanner-declarations": "npm run build && node ./scripts/scanner-declaration-regression.mjs",
28
+ "test:transformer-protect": "npm run build && node ./scripts/transformer-protect-regression.mjs",
29
+ "test:binding": "npm run build && node ./scripts/once-binding-regression.mjs",
30
+ "test:patch-planner": "npm run build && node ./scripts/http-patch-planner-regression.mjs",
31
+ "test:apply": "npm run build && node ./scripts/apply-engine-regression.mjs && node ./scripts/apply-regression.mjs",
32
+ "test:package": "npm run build && node ./scripts/package-isolation-regression.mjs",
33
+ "test:consumer": "npm run build && node ./scripts/consumer-package-regression.mjs",
34
+ "test:id-conformance": "npm run build && node ./scripts/id-conformance-regression.mjs"
35
+ },
36
+ "keywords": [
37
+ "ai",
38
+ "agents",
39
+ "idempotency",
40
+ "reliability",
41
+ "execution-safety"
42
+ ],
43
+ "license": "MIT",
44
+ "engines": {
45
+ "node": ">=18"
46
+ },
47
+ "devDependencies": {
48
+ "@types/node": "^26.6.1"
49
+ },
50
+ "bin": {
51
+ "once": "./dist/cli.js"
52
+ },
53
+ "dependencies": {
54
+ "typescript": "^5.9.0"
55
+ }
56
+ }