@oscharko-dev/keiko-tools 0.2.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 (59) hide show
  1. package/dist/.tsbuildinfo +1 -0
  2. package/dist/browser/cdp-client.d.ts +36 -0
  3. package/dist/browser/cdp-client.d.ts.map +1 -0
  4. package/dist/browser/cdp-client.js +218 -0
  5. package/dist/browser/errors.d.ts +27 -0
  6. package/dist/browser/errors.d.ts.map +1 -0
  7. package/dist/browser/errors.js +61 -0
  8. package/dist/browser/session.d.ts +46 -0
  9. package/dist/browser/session.d.ts.map +1 -0
  10. package/dist/browser/session.js +759 -0
  11. package/dist/browser/types.d.ts +49 -0
  12. package/dist/browser/types.d.ts.map +1 -0
  13. package/dist/browser/types.js +2 -0
  14. package/dist/browser/validators.d.ts +6 -0
  15. package/dist/browser/validators.d.ts.map +1 -0
  16. package/dist/browser/validators.js +97 -0
  17. package/dist/errors.d.ts +3 -0
  18. package/dist/errors.d.ts.map +1 -0
  19. package/dist/errors.js +4 -0
  20. package/dist/exec.d.ts +45 -0
  21. package/dist/exec.d.ts.map +1 -0
  22. package/dist/exec.js +372 -0
  23. package/dist/index.d.ts +20 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +33 -0
  26. package/dist/patch-content.d.ts +11 -0
  27. package/dist/patch-content.d.ts.map +1 -0
  28. package/dist/patch-content.js +130 -0
  29. package/dist/patch-normalize.d.ts +2 -0
  30. package/dist/patch-normalize.d.ts.map +1 -0
  31. package/dist/patch-normalize.js +85 -0
  32. package/dist/patch-parse.d.ts +9 -0
  33. package/dist/patch-parse.d.ts.map +1 -0
  34. package/dist/patch-parse.js +201 -0
  35. package/dist/patch.d.ts +22 -0
  36. package/dist/patch.d.ts.map +1 -0
  37. package/dist/patch.js +469 -0
  38. package/dist/registry.d.ts +35 -0
  39. package/dist/registry.d.ts.map +1 -0
  40. package/dist/registry.js +240 -0
  41. package/dist/sandbox.d.ts +9 -0
  42. package/dist/sandbox.d.ts.map +1 -0
  43. package/dist/sandbox.js +131 -0
  44. package/dist/schemas.d.ts +3 -0
  45. package/dist/schemas.d.ts.map +1 -0
  46. package/dist/schemas.js +51 -0
  47. package/dist/terminal-policy.d.ts +10 -0
  48. package/dist/terminal-policy.d.ts.map +1 -0
  49. package/dist/terminal-policy.js +306 -0
  50. package/dist/types.d.ts +5 -0
  51. package/dist/types.d.ts.map +1 -0
  52. package/dist/types.js +18 -0
  53. package/dist/version.d.ts +2 -0
  54. package/dist/version.d.ts.map +1 -0
  55. package/dist/version.js +4 -0
  56. package/dist/writer.d.ts +8 -0
  57. package/dist/writer.d.ts.map +1 -0
  58. package/dist/writer.js +20 -0
  59. package/package.json +42 -0
@@ -0,0 +1,306 @@
1
+ // ADR-0018 D3 — permitted-command policy for the UI terminal tool. A separate, narrower allowlist
2
+ // than the harness DEFAULT_COMMAND_RULES so the human-facing terminal cannot widen the agent surface.
3
+ // The CommandRule schema (allowedSubcommands / denyFlags / valueFlags) handles the structural
4
+ // shape; `isTerminalCommandAllowed` adds a thin Layer-2 pass for flag policies that `CommandRule`
5
+ // cannot express (node's positional-arg ban, git branch/remote mutation).
6
+ // Pure module: no IO, no spawn, no fs.
7
+ import { isCommandAllowed } from "./sandbox.js";
8
+ const FROZEN_NONE = Object.freeze([]);
9
+ // Read-only inspection commands. Each rule is conservative: omitted subcommands are denied by the
10
+ // allowlist mode; the only flag policy expressed here is what CommandRule already supports.
11
+ export const TERMINAL_COMMAND_RULES = Object.freeze([
12
+ { executable: "ls" },
13
+ { executable: "cat" },
14
+ { executable: "head" },
15
+ { executable: "tail" },
16
+ { executable: "wc", denyFlags: Object.freeze(["--files0-from"]) },
17
+ { executable: "grep" },
18
+ { executable: "pwd" },
19
+ { executable: "echo" },
20
+ {
21
+ executable: "find",
22
+ denyFlags: Object.freeze([
23
+ "-exec",
24
+ "-execdir",
25
+ "-ok",
26
+ "-okdir",
27
+ "-delete",
28
+ "-fprint",
29
+ "-fprint0",
30
+ "-fprintf",
31
+ "-fls",
32
+ "-files0-from",
33
+ ]),
34
+ },
35
+ {
36
+ executable: "tree",
37
+ denyFlags: Object.freeze(["-o", "--output"]),
38
+ },
39
+ // node: only --version/-v allowed. Enforced positionally in Layer 2 (a per-arg policy is not
40
+ // expressible in CommandRule).
41
+ { executable: "node" },
42
+ {
43
+ executable: "npm",
44
+ allowedSubcommands: Object.freeze(["ls", "list", "help"]),
45
+ denyFlags: Object.freeze(["-c", "--call", "--prefix", "--global", "-g", "--location"]),
46
+ },
47
+ {
48
+ executable: "git",
49
+ allowedSubcommands: Object.freeze([
50
+ "status",
51
+ "diff",
52
+ "log",
53
+ "show",
54
+ "rev-parse",
55
+ "ls-files",
56
+ "describe",
57
+ "blame",
58
+ "cat-file",
59
+ "branch",
60
+ "remote",
61
+ ]),
62
+ valueFlags: Object.freeze([
63
+ "-C",
64
+ "-c",
65
+ "--git-dir",
66
+ "--work-tree",
67
+ "--namespace",
68
+ "--exec-path",
69
+ ]),
70
+ denyFlags: Object.freeze([
71
+ "-C",
72
+ "-c",
73
+ "--git-dir",
74
+ "--work-tree",
75
+ "--namespace",
76
+ "--exec-path",
77
+ "--ext-diff",
78
+ "--textconv",
79
+ "--output",
80
+ "--no-index",
81
+ "--contents",
82
+ ]),
83
+ },
84
+ ]);
85
+ // Flags that delete, write, or execute via find. Any of these anywhere in args denies.
86
+ const FIND_DENY_FLAGS = new Set([
87
+ "-exec",
88
+ "-execdir",
89
+ "-ok",
90
+ "-okdir",
91
+ "-delete",
92
+ "-fprint",
93
+ "-fprint0",
94
+ "-fprintf",
95
+ "-fls",
96
+ "-files0-from",
97
+ ]);
98
+ const TREE_DENY_FLAGS = new Set(["-o", "--output"]);
99
+ // Only --version and -v are accepted for node. Every other positional or flag is denied.
100
+ const NODE_ALLOWED_ARGS = new Set(["--version", "-v"]);
101
+ // Branch mutation flags (A2). Scoped to `git branch` only — these deny branch creation, deletion,
102
+ // copy, rename, and force operations. `-c`/`-C` are included here because for `branch` they mean
103
+ // copy, not the git-global config flag (which is caught by A5 before we reach here).
104
+ const GIT_BRANCH_DENY_FLAGS = new Set([
105
+ "-D",
106
+ "-d",
107
+ "-m",
108
+ "-M",
109
+ "--delete",
110
+ "-c",
111
+ "-C",
112
+ "-f",
113
+ "--copy",
114
+ "--force",
115
+ "--set-upstream-to",
116
+ "--unset-upstream",
117
+ "--edit-description",
118
+ ]);
119
+ // Global git flags that modify git's own config, working-tree, cwd, or execution path (A5 /
120
+ // ADR-0018 S-H2). These are checked BEFORE subcommand resolution so they cannot be smuggled via a
121
+ // value-flag value that happens to look like a subcommand.
122
+ const GIT_GLOBAL_DENY_FLAGS = new Set([
123
+ "-C",
124
+ "-c",
125
+ "--git-dir",
126
+ "--work-tree",
127
+ "--namespace",
128
+ "--exec-path",
129
+ ]);
130
+ const GIT_UNSAFE_FLAGS = new Set([
131
+ "--ext-diff",
132
+ "--textconv",
133
+ "--output",
134
+ "--no-index",
135
+ "--contents",
136
+ ]);
137
+ function denied(reason) {
138
+ return { allowed: false, reason };
139
+ }
140
+ function checkFind(args) {
141
+ for (const arg of args) {
142
+ if (FIND_DENY_FLAGS.has(arg)) {
143
+ return denied(`find: denied flag ${arg}`);
144
+ }
145
+ }
146
+ return { allowed: true };
147
+ }
148
+ function checkTree(args) {
149
+ for (const arg of args) {
150
+ const flag = arg.includes("=") ? arg.slice(0, arg.indexOf("=")) : arg;
151
+ if (TREE_DENY_FLAGS.has(flag) || arg.startsWith("-o")) {
152
+ return denied(`tree: denied write flag ${flag}`);
153
+ }
154
+ }
155
+ return { allowed: true };
156
+ }
157
+ function checkNode(args) {
158
+ for (const arg of args) {
159
+ if (!NODE_ALLOWED_ARGS.has(arg)) {
160
+ return denied("node: only --version/-v is permitted");
161
+ }
162
+ }
163
+ return { allowed: true };
164
+ }
165
+ // Shared value-flags used by gitSubcommand and argsAfterSubcommand. Kept as a module-level
166
+ // constant (not re-created per call) so the hot-path doesn't allocate on every invocation.
167
+ const GIT_VALUE_FLAGS = new Set([
168
+ "-C",
169
+ "-c",
170
+ "--git-dir",
171
+ "--work-tree",
172
+ "--namespace",
173
+ "--exec-path",
174
+ ]);
175
+ // Resolves the git subcommand (first non-flag arg, skipping value-flag pairs). Returns undefined
176
+ // when the subcommand can't be determined — the caller treats that as not-a-mutation.
177
+ function gitSubcommand(args) {
178
+ let skipNext = false;
179
+ for (const arg of args) {
180
+ if (skipNext) {
181
+ skipNext = false;
182
+ continue;
183
+ }
184
+ if (!arg.startsWith("-")) {
185
+ return arg;
186
+ }
187
+ if (!arg.includes("=") && GIT_VALUE_FLAGS.has(arg)) {
188
+ skipNext = true;
189
+ }
190
+ }
191
+ return undefined;
192
+ }
193
+ // Returns the slice of args that appears AFTER the first token equal to `subcommand`, skipping
194
+ // value-flag pairs using the same walk as gitSubcommand. Returns undefined when not found.
195
+ function argsAfterSubcommand(args, subcommand) {
196
+ // Convert to a mutable array for indexed access so we can use a for...of without a C-style loop
197
+ // (avoids noUncheckedIndexedAccess while remaining tsc-clean under no-non-null-assertion).
198
+ const arr = Array.from(args);
199
+ let skipNext = false;
200
+ for (const [i, arg] of arr.entries()) {
201
+ if (skipNext) {
202
+ skipNext = false;
203
+ continue;
204
+ }
205
+ if (arg === subcommand) {
206
+ return args.slice(i + 1);
207
+ }
208
+ if (arg.startsWith("-") && !arg.includes("=") && GIT_VALUE_FLAGS.has(arg)) {
209
+ skipNext = true;
210
+ }
211
+ }
212
+ return undefined;
213
+ }
214
+ // A2 — After resolving the `branch` subcommand, walk the remaining args. Any non-flag positional
215
+ // (a branch name operand) denies creation/switching. Deny all known mutation flags.
216
+ function checkGitBranch(argsAfterBranch) {
217
+ for (const arg of argsAfterBranch) {
218
+ const flag = arg.includes("=") ? arg.slice(0, arg.indexOf("=")) : arg;
219
+ if (GIT_BRANCH_DENY_FLAGS.has(flag)) {
220
+ return denied(`git branch: denied mutation flag ${flag}`);
221
+ }
222
+ if (!arg.startsWith("-")) {
223
+ // A bare positional after `branch` is a branch name operand — implies creation or mutation.
224
+ return denied("git branch: positional operand denied (read-only listing only)");
225
+ }
226
+ }
227
+ return { allowed: true };
228
+ }
229
+ // A1 — After resolving the `remote` subcommand, walk the remaining args. No non-flag positional is
230
+ // allowed: `show`, `update`, and `prune` can contact remotes, while add/rm/rename/set-url mutate
231
+ // config. `git remote` and `git remote -v` remain local read-only inspection.
232
+ function checkGitRemote(argsAfterRemote) {
233
+ for (const arg of argsAfterRemote) {
234
+ if (arg.startsWith("-")) {
235
+ // Pure flag (e.g. -v / --verbose) — already covered by the CommandRule valueFlags/denyFlags
236
+ // at Layer 1, but we allow flags through here to avoid double-denying them.
237
+ continue;
238
+ }
239
+ return denied(`git remote: subcommand "${arg}" is denied (read-only: use flags only)`);
240
+ }
241
+ return { allowed: true };
242
+ }
243
+ function deniedGitFlag(arg) {
244
+ const flag = arg.includes("=") ? arg.slice(0, arg.indexOf("=")) : arg;
245
+ // A5 — Deny global config/env-injection and cwd-shifting flags before resolving the subcommand.
246
+ if (GIT_GLOBAL_DENY_FLAGS.has(flag) ||
247
+ arg.startsWith("-C") ||
248
+ (arg.startsWith("-c") && !arg.startsWith("--"))) {
249
+ return `git: denied global flag ${flag}`;
250
+ }
251
+ if (GIT_UNSAFE_FLAGS.has(flag)) {
252
+ return `git: denied unsafe flag ${flag}`;
253
+ }
254
+ return undefined;
255
+ }
256
+ function checkGitFlags(args) {
257
+ for (const arg of args) {
258
+ const reason = deniedGitFlag(arg);
259
+ if (reason !== undefined)
260
+ return denied(reason);
261
+ }
262
+ return { allowed: true };
263
+ }
264
+ function checkGitSubcommand(args) {
265
+ const sub = gitSubcommand(args);
266
+ if (sub === "branch") {
267
+ const rest = argsAfterSubcommand(args, "branch") ?? [];
268
+ return checkGitBranch(rest);
269
+ }
270
+ if (sub === "remote") {
271
+ const rest = argsAfterSubcommand(args, "remote") ?? [];
272
+ return checkGitRemote(rest);
273
+ }
274
+ return { allowed: true };
275
+ }
276
+ function checkGit(args) {
277
+ const flags = checkGitFlags(args);
278
+ if (!flags.allowed)
279
+ return flags;
280
+ return checkGitSubcommand(args);
281
+ }
282
+ // Pure deny-by-default decision for a terminal command. Layer 1 is the shared `isCommandAllowed`
283
+ // (validates the executable and applies CommandRule's subcommand allowlist/denyFlags/valueFlags).
284
+ // Layer 2 here adds the per-command flag policies that CommandRule cannot express (find / tree /
285
+ // node / git branch and remote mutation flags).
286
+ export function isTerminalCommandAllowed(command, args) {
287
+ const layer1 = isCommandAllowed(TERMINAL_COMMAND_RULES, command, args);
288
+ if (!layer1.allowed) {
289
+ return { allowed: false, reason: layer1.reason };
290
+ }
291
+ if (command === "find") {
292
+ return checkFind(args);
293
+ }
294
+ if (command === "tree") {
295
+ return checkTree(args);
296
+ }
297
+ if (command === "node") {
298
+ return checkNode(args);
299
+ }
300
+ if (command === "git") {
301
+ return checkGit(args);
302
+ }
303
+ return { allowed: true };
304
+ }
305
+ // Re-export so callers don't have to import from sandbox.ts directly.
306
+ export { FROZEN_NONE as TERMINAL_NO_FLAGS };
@@ -0,0 +1,5 @@
1
+ import { type ToolHostConfig, type ToolHostConfigInput } from "@oscharko-dev/keiko-contracts";
2
+ export type { NetworkPolicy, FilesystemPolicy, SandboxPolicy, SandboxBackend, SandboxAttestation, CommandRule, CommandRunInput, CommandResult, PatchChangeKind, PatchHunk, PatchFileChange, PatchRejectionCode, PatchRejection, PatchConflict, PatchValidation, PatchLimits, PatchApplyResult, ToolHostConfig, ToolHostConfigInput, } from "@oscharko-dev/keiko-contracts";
3
+ export { DEFAULT_ENV_ALLOWLIST, DEFAULT_SANDBOX_POLICY, DEFAULT_COMMAND_RULES, DEFAULT_PATCH_LIMITS, DEFAULT_TOOL_HOST_CONFIG, } from "@oscharko-dev/keiko-contracts";
4
+ export declare function resolveToolHostConfig(input: ToolHostConfigInput | undefined): ToolHostConfig;
5
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAKA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACzB,MAAM,+BAA+B,CAAC;AAEvC,YAAY,EACV,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,WAAW,EACX,eAAe,EACf,aAAa,EACb,eAAe,EACf,SAAS,EACT,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,mBAAmB,GACpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,+BAA+B,CAAC;AAIvC,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,mBAAmB,GAAG,SAAS,GAAG,cAAc,CAS5F"}
package/dist/types.js ADDED
@@ -0,0 +1,18 @@
1
+ // Re-export shim: tool contract types and frozen default tables live in
2
+ // @oscharko-dev/keiko-contracts (issue #158). The `resolveToolHostConfig` runtime helper STAYS
3
+ // here because contracts contains type/data only — no runtime functions. `verbatimModuleSyntax`
4
+ // is on, so type-only names use `export type` and value-emitting frozen constants use `export`.
5
+ import { DEFAULT_TOOL_HOST_CONFIG, } from "@oscharko-dev/keiko-contracts";
6
+ export { DEFAULT_ENV_ALLOWLIST, DEFAULT_SANDBOX_POLICY, DEFAULT_COMMAND_RULES, DEFAULT_PATCH_LIMITS, DEFAULT_TOOL_HOST_CONFIG, } from "@oscharko-dev/keiko-contracts";
7
+ // Deep-merges a caller override over the defaults: the nested sandbox/patchLimits objects merge
8
+ // field-by-field so a partial override never drops an unspecified default (S-M2).
9
+ export function resolveToolHostConfig(input) {
10
+ const base = DEFAULT_TOOL_HOST_CONFIG;
11
+ return {
12
+ sandbox: { ...base.sandbox, ...input?.sandbox },
13
+ commandRules: input?.commandRules ?? base.commandRules,
14
+ patchLimits: { ...base.patchLimits, ...input?.patchLimits },
15
+ applyEnabled: input?.applyEnabled ?? base.applyEnabled,
16
+ maxReadBytes: input?.maxReadBytes ?? base.maxReadBytes,
17
+ };
18
+ }
@@ -0,0 +1,2 @@
1
+ export declare const KEIKO_TOOLS_VERSION: "0.1.0";
2
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,mBAAmB,EAAG,OAAgB,CAAC"}
@@ -0,0 +1,4 @@
1
+ // Package version constant. Pinned to 0.1.0 because the tools surface is internal and
2
+ // versioned via the umbrella keiko package. Bump on any breaking-shape change to the public
3
+ // barrel (errors, ports, types) so consumers can detect divergence in tests.
4
+ export const KEIKO_TOOLS_VERSION = "0.1.0";
@@ -0,0 +1,8 @@
1
+ export interface WorkspaceWriter {
2
+ readonly writeFileUtf8: (absolutePath: string, content: string) => void;
3
+ readonly mkdirp: (absoluteDir: string) => void;
4
+ readonly remove: (absolutePath: string) => void;
5
+ readonly rename: (fromAbsolute: string, toAbsolute: string) => void;
6
+ }
7
+ export declare const nodeWorkspaceWriter: WorkspaceWriter;
8
+ //# sourceMappingURL=writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../src/writer.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,aAAa,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACxE,QAAQ,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,QAAQ,CAAC,MAAM,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,QAAQ,CAAC,MAAM,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;CACrE;AAED,eAAO,MAAM,mBAAmB,EAAE,eAajC,CAAC"}
package/dist/writer.js ADDED
@@ -0,0 +1,20 @@
1
+ // The single controlled filesystem-WRITE boundary (ADR-0006 D2). WorkspaceFs stays read-only
2
+ // (ADR-0005); all mutation goes through this port so the apply phase is auditable and testable
3
+ // with an in-memory fake. Callers (patch.ts) MUST pre-validate every absolute path via
4
+ // resolveWithinWorkspace + isDenied before handing it here; this adapter does no validation
5
+ // itself — it is the effectful edge, kept deliberately thin. Synchronous, mirroring nodeWorkspaceFs.
6
+ import { mkdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
7
+ export const nodeWorkspaceWriter = {
8
+ writeFileUtf8: (absolutePath, content) => {
9
+ writeFileSync(absolutePath, content, "utf8");
10
+ },
11
+ mkdirp: (absoluteDir) => {
12
+ mkdirSync(absoluteDir, { recursive: true });
13
+ },
14
+ remove: (absolutePath) => {
15
+ rmSync(absolutePath, { force: true });
16
+ },
17
+ rename: (fromAbsolute, toAbsolute) => {
18
+ renameSync(fromAbsolute, toAbsolute);
19
+ },
20
+ };
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@oscharko-dev/keiko-tools",
3
+ "version": "0.2.0",
4
+ "type": "module",
5
+ "license": "Apache-2.0",
6
+ "description": "Internal tools package: Keiko safe tool-execution layer — terminal-policy command allowlist, env-isolated no-shell spawn, atomic patch workflow, browser CDP adapter, and the WorkspaceWriter boundary (ADR-0006 / ADR-0017). Not published independently.",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ },
14
+ "./internal/exec": {
15
+ "types": "./dist/exec.d.ts",
16
+ "import": "./dist/exec.js"
17
+ },
18
+ "./internal/writer": {
19
+ "types": "./dist/writer.d.ts",
20
+ "import": "./dist/writer.js"
21
+ }
22
+ },
23
+ "scripts": {
24
+ "build": "tsc -b tsconfig.json",
25
+ "typecheck": "tsc -b tsconfig.json",
26
+ "test": "vitest run"
27
+ },
28
+ "files": [
29
+ "dist"
30
+ ],
31
+ "sideEffects": false,
32
+ "engines": {
33
+ "node": ">=22"
34
+ },
35
+ "dependencies": {
36
+ "@oscharko-dev/keiko-contracts": "0.2.0",
37
+ "@oscharko-dev/keiko-sandbox": "0.2.0",
38
+ "@oscharko-dev/keiko-security": "0.2.0",
39
+ "@oscharko-dev/keiko-workspace": "0.2.0",
40
+ "ws": "^8.21.0"
41
+ }
42
+ }