keystone-cli 1.0.3 → 1.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 (153) hide show
  1. package/README.md +276 -32
  2. package/package.json +8 -4
  3. package/src/cli.ts +350 -416
  4. package/src/commands/doc.ts +31 -0
  5. package/src/commands/event.ts +29 -0
  6. package/src/commands/graph.ts +37 -0
  7. package/src/commands/index.ts +14 -0
  8. package/src/commands/init.ts +185 -0
  9. package/src/commands/run.ts +124 -0
  10. package/src/commands/schema.ts +40 -0
  11. package/src/commands/utils.ts +78 -0
  12. package/src/commands/validate.ts +111 -0
  13. package/src/db/workflow-db.test.ts +314 -0
  14. package/src/db/workflow-db.ts +810 -210
  15. package/src/expression/evaluator-audit.test.ts +4 -2
  16. package/src/expression/evaluator.test.ts +14 -1
  17. package/src/expression/evaluator.ts +166 -19
  18. package/src/parser/config-schema.ts +18 -0
  19. package/src/parser/schema.ts +153 -22
  20. package/src/parser/test-schema.ts +6 -6
  21. package/src/parser/workflow-parser.test.ts +24 -0
  22. package/src/parser/workflow-parser.ts +65 -3
  23. package/src/runner/auto-heal.test.ts +5 -6
  24. package/src/runner/blueprint-executor.test.ts +2 -2
  25. package/src/runner/debug-repl.test.ts +5 -8
  26. package/src/runner/debug-repl.ts +59 -16
  27. package/src/runner/durable-timers.test.ts +11 -2
  28. package/src/runner/engine-executor.test.ts +1 -1
  29. package/src/runner/events.ts +57 -0
  30. package/src/runner/executors/artifact-executor.ts +166 -0
  31. package/src/runner/{blueprint-executor.ts → executors/blueprint-executor.ts} +15 -7
  32. package/src/runner/{engine-executor.ts → executors/engine-executor.ts} +55 -7
  33. package/src/runner/executors/file-executor.test.ts +48 -0
  34. package/src/runner/executors/file-executor.ts +324 -0
  35. package/src/runner/{foreach-executor.ts → executors/foreach-executor.ts} +168 -80
  36. package/src/runner/executors/human-executor.ts +144 -0
  37. package/src/runner/executors/join-executor.ts +75 -0
  38. package/src/runner/executors/llm-executor.ts +1266 -0
  39. package/src/runner/executors/memory-executor.ts +71 -0
  40. package/src/runner/executors/plan-executor.ts +104 -0
  41. package/src/runner/executors/request-executor.ts +265 -0
  42. package/src/runner/executors/script-executor.ts +43 -0
  43. package/src/runner/executors/shell-executor.ts +403 -0
  44. package/src/runner/executors/subworkflow-executor.ts +114 -0
  45. package/src/runner/executors/types.ts +69 -0
  46. package/src/runner/executors/wait-executor.ts +59 -0
  47. package/src/runner/join-scheduling.test.ts +197 -0
  48. package/src/runner/llm-adapter-runtime.test.ts +209 -0
  49. package/src/runner/llm-adapter.test.ts +419 -24
  50. package/src/runner/llm-adapter.ts +130 -26
  51. package/src/runner/llm-clarification.test.ts +2 -1
  52. package/src/runner/llm-executor.test.ts +532 -17
  53. package/src/runner/mcp-client-audit.test.ts +1 -2
  54. package/src/runner/mcp-client.ts +136 -46
  55. package/src/runner/mcp-manager.test.ts +4 -0
  56. package/src/runner/mcp-server.test.ts +58 -0
  57. package/src/runner/mcp-server.ts +26 -0
  58. package/src/runner/memoization.test.ts +190 -0
  59. package/src/runner/optimization-runner.ts +4 -9
  60. package/src/runner/quality-gate.test.ts +69 -0
  61. package/src/runner/reflexion.test.ts +6 -17
  62. package/src/runner/resource-pool.ts +102 -14
  63. package/src/runner/services/context-builder.ts +144 -0
  64. package/src/runner/services/secret-manager.ts +105 -0
  65. package/src/runner/services/workflow-validator.ts +131 -0
  66. package/src/runner/shell-executor.test.ts +28 -4
  67. package/src/runner/standard-tools-ast.test.ts +196 -0
  68. package/src/runner/standard-tools-execution.test.ts +27 -0
  69. package/src/runner/standard-tools-integration.test.ts +6 -10
  70. package/src/runner/standard-tools.ts +339 -102
  71. package/src/runner/step-executor.test.ts +216 -4
  72. package/src/runner/step-executor.ts +69 -941
  73. package/src/runner/stream-utils.ts +7 -3
  74. package/src/runner/test-harness.ts +20 -1
  75. package/src/runner/timeout.test.ts +10 -0
  76. package/src/runner/timeout.ts +11 -2
  77. package/src/runner/tool-integration.test.ts +1 -1
  78. package/src/runner/wait-step.test.ts +102 -0
  79. package/src/runner/workflow-runner.test.ts +208 -15
  80. package/src/runner/workflow-runner.ts +890 -818
  81. package/src/runner/workflow-scheduler.ts +75 -0
  82. package/src/runner/workflow-state.ts +269 -0
  83. package/src/runner/workflow-subflows.test.ts +13 -12
  84. package/src/scripts/generate-schemas.ts +16 -0
  85. package/src/templates/agents/explore.md +1 -0
  86. package/src/templates/agents/general.md +1 -0
  87. package/src/templates/agents/handoff-router.md +14 -0
  88. package/src/templates/agents/handoff-specialist.md +15 -0
  89. package/src/templates/agents/keystone-architect.md +13 -44
  90. package/src/templates/agents/my-agent.md +1 -0
  91. package/src/templates/agents/software-engineer.md +1 -0
  92. package/src/templates/agents/summarizer.md +1 -0
  93. package/src/templates/agents/test-agent.md +1 -0
  94. package/src/templates/agents/tester.md +1 -0
  95. package/src/templates/{basic-inputs.yaml → basics/basic-inputs.yaml} +2 -0
  96. package/src/templates/{basic-shell.yaml → basics/basic-shell.yaml} +2 -1
  97. package/src/templates/{full-feature-demo.yaml → basics/full-feature-demo.yaml} +2 -0
  98. package/src/templates/{stop-watch.yaml → basics/stop-watch.yaml} +1 -0
  99. package/src/templates/{child-rollback.yaml → control-flow/child-rollback.yaml} +1 -0
  100. package/src/templates/{cleanup-finally.yaml → control-flow/cleanup-finally.yaml} +1 -0
  101. package/src/templates/{fan-out-fan-in.yaml → control-flow/fan-out-fan-in.yaml} +3 -0
  102. package/src/templates/control-flow/idempotency-example.yaml +30 -0
  103. package/src/templates/{loop-parallel.yaml → control-flow/loop-parallel.yaml} +3 -0
  104. package/src/templates/{parent-rollback.yaml → control-flow/parent-rollback.yaml} +1 -0
  105. package/src/templates/{retry-policy.yaml → control-flow/retry-policy.yaml} +3 -0
  106. package/src/templates/features/artifact-example.yaml +39 -0
  107. package/src/templates/{engine-example.yaml → features/engine-example.yaml} +1 -0
  108. package/src/templates/{human-interaction.yaml → features/human-interaction.yaml} +1 -0
  109. package/src/templates/{llm-agent.yaml → features/llm-agent.yaml} +1 -0
  110. package/src/templates/{memory-service.yaml → features/memory-service.yaml} +2 -0
  111. package/src/templates/{robust-automation.yaml → features/robust-automation.yaml} +3 -0
  112. package/src/templates/features/script-example.yaml +27 -0
  113. package/src/templates/patterns/agent-handoff.yaml +53 -0
  114. package/src/templates/{approval-process.yaml → patterns/approval-process.yaml} +1 -0
  115. package/src/templates/{batch-processor.yaml → patterns/batch-processor.yaml} +2 -0
  116. package/src/templates/{composition-child.yaml → patterns/composition-child.yaml} +1 -0
  117. package/src/templates/{composition-parent.yaml → patterns/composition-parent.yaml} +1 -0
  118. package/src/templates/{data-pipeline.yaml → patterns/data-pipeline.yaml} +2 -0
  119. package/src/templates/{decompose-implement.yaml → scaffolding/decompose-implement.yaml} +1 -0
  120. package/src/templates/{decompose-problem.yaml → scaffolding/decompose-problem.yaml} +1 -0
  121. package/src/templates/{decompose-research.yaml → scaffolding/decompose-research.yaml} +1 -0
  122. package/src/templates/{decompose-review.yaml → scaffolding/decompose-review.yaml} +1 -0
  123. package/src/templates/{dev.yaml → scaffolding/dev.yaml} +1 -0
  124. package/src/templates/scaffolding/review-loop.yaml +97 -0
  125. package/src/templates/{scaffold-feature.yaml → scaffolding/scaffold-feature.yaml} +2 -0
  126. package/src/templates/{scaffold-generate.yaml → scaffolding/scaffold-generate.yaml} +1 -0
  127. package/src/templates/{scaffold-plan.yaml → scaffolding/scaffold-plan.yaml} +1 -0
  128. package/src/templates/testing/invalid.yaml +6 -0
  129. package/src/ui/dashboard.tsx +191 -33
  130. package/src/utils/auth-manager.test.ts +337 -0
  131. package/src/utils/auth-manager.ts +157 -61
  132. package/src/utils/blueprint-utils.ts +4 -6
  133. package/src/utils/config-loader.test.ts +2 -0
  134. package/src/utils/config-loader.ts +12 -3
  135. package/src/utils/constants.ts +76 -0
  136. package/src/utils/container.ts +63 -0
  137. package/src/utils/context-injector.test.ts +200 -0
  138. package/src/utils/context-injector.ts +244 -0
  139. package/src/utils/doc-generator.ts +85 -0
  140. package/src/utils/env-filter.ts +45 -0
  141. package/src/utils/json-parser.test.ts +12 -0
  142. package/src/utils/json-parser.ts +30 -5
  143. package/src/utils/logger.ts +12 -1
  144. package/src/utils/mermaid.ts +4 -0
  145. package/src/utils/paths.ts +52 -1
  146. package/src/utils/process-sandbox-worker.test.ts +46 -0
  147. package/src/utils/process-sandbox.ts +227 -14
  148. package/src/utils/redactor.test.ts +11 -6
  149. package/src/utils/redactor.ts +25 -9
  150. package/src/utils/sandbox.ts +3 -0
  151. package/src/runner/llm-executor.ts +0 -638
  152. package/src/runner/shell-executor.ts +0 -366
  153. package/src/templates/invalid.yaml +0 -5
@@ -1,7 +1,7 @@
1
1
  import { describe, expect, it } from 'bun:test';
2
2
  import type { ExpressionContext } from '../expression/evaluator';
3
3
  import type { ShellStep } from '../parser/schema';
4
- import { escapeShellArg, executeShell } from './shell-executor';
4
+ import { escapeShellArg, executeShell } from './executors/shell-executor.ts';
5
5
 
6
6
  describe('shell-executor', () => {
7
7
  describe('escapeShellArg', () => {
@@ -27,6 +27,7 @@ describe('shell-executor', () => {
27
27
  type: 'shell',
28
28
  needs: [],
29
29
  run: 'echo "hello world"',
30
+ allowInsecure: true,
30
31
  };
31
32
 
32
33
  const result = await executeShell(step, context);
@@ -40,6 +41,7 @@ describe('shell-executor', () => {
40
41
  type: 'shell',
41
42
  needs: [],
42
43
  run: 'echo "${{ inputs.name }}"',
44
+ allowInsecure: true,
43
45
  };
44
46
  const customContext: ExpressionContext = {
45
47
  ...context,
@@ -56,6 +58,7 @@ describe('shell-executor', () => {
56
58
  type: 'shell',
57
59
  needs: [],
58
60
  run: 'echo $TEST_VAR',
61
+ allowInsecure: true,
59
62
  env: {
60
63
  TEST_VAR: 'env-value',
61
64
  },
@@ -72,6 +75,7 @@ describe('shell-executor', () => {
72
75
  needs: [],
73
76
  run: 'pwd',
74
77
  dir: '/tmp',
78
+ allowOutsideCwd: true,
75
79
  };
76
80
 
77
81
  const result = await executeShell(step, context);
@@ -84,6 +88,7 @@ describe('shell-executor', () => {
84
88
  type: 'shell',
85
89
  needs: [],
86
90
  run: 'echo "error" >&2',
91
+ allowInsecure: true,
87
92
  };
88
93
 
89
94
  const result = await executeShell(step, context);
@@ -96,6 +101,7 @@ describe('shell-executor', () => {
96
101
  type: 'shell',
97
102
  needs: [],
98
103
  run: 'exit 1',
104
+ allowInsecure: true,
99
105
  };
100
106
 
101
107
  const result = await executeShell(step, context);
@@ -113,12 +119,13 @@ describe('shell-executor', () => {
113
119
  await expect(executeShell(step, context)).rejects.toThrow(/Security Error/);
114
120
  });
115
121
 
116
- it('should allow legitimate shell variable expansion like ${HOME}', async () => {
122
+ it('should allow shell variable expansion like ${HOME} when allowInsecure is true', async () => {
117
123
  const step: ShellStep = {
118
124
  id: 'test',
119
125
  type: 'shell',
120
126
  needs: [],
121
127
  run: 'echo ${HOME}',
128
+ allowInsecure: true,
122
129
  };
123
130
 
124
131
  // Should NOT throw - ${HOME} is legitimate
@@ -127,7 +134,7 @@ describe('shell-executor', () => {
127
134
  expect(result.stdout.trim()).toBe(Bun.env.HOME || '');
128
135
  });
129
136
 
130
- it('should still block dangerous parameter expansion like ${IFS}', async () => {
137
+ it('should block parameter expansion like ${IFS} by default', async () => {
131
138
  const step: ShellStep = {
132
139
  id: 'test',
133
140
  type: 'shell',
@@ -137,12 +144,29 @@ describe('shell-executor', () => {
137
144
 
138
145
  await expect(executeShell(step, context)).rejects.toThrow(/Security Error/);
139
146
  });
140
- it('should allow flow control with semicolons', async () => {
147
+
148
+ it('should allow braces and quotes for JSON usage with allowInsecure', async () => {
149
+ // {} and quotes now require allowInsecure due to strict whitelist
150
+ const step: ShellStep = {
151
+ id: 'test',
152
+ type: 'shell',
153
+ needs: [],
154
+ run: 'echo \'{"values": [1, 2, 3]}\'',
155
+ allowInsecure: true,
156
+ };
157
+
158
+ const result = await executeShell(step, context);
159
+ expect(result.exitCode).toBe(0);
160
+ expect(result.stdout.trim()).toBe('{"values": [1, 2, 3]}');
161
+ });
162
+
163
+ it('should allow flow control with semicolons when allowInsecure is true', async () => {
141
164
  const step: ShellStep = {
142
165
  id: 'test',
143
166
  type: 'shell',
144
167
  needs: [],
145
168
  run: 'if [ "1" = "1" ]; then echo "match"; fi',
169
+ allowInsecure: true,
146
170
  };
147
171
 
148
172
  const result = await executeShell(step, context);
@@ -0,0 +1,196 @@
1
+ import { afterAll, beforeAll, describe, expect, it } from 'bun:test';
2
+ import * as fs from 'node:fs';
3
+ import * as os from 'node:os';
4
+ import * as path from 'node:path';
5
+ import * as vm from 'node:vm';
6
+ import { STANDARD_TOOLS, validateStandardToolSecurity } from './standard-tools';
7
+
8
+ describe('AST-Grep Tools', () => {
9
+ let tempDir: string;
10
+ let testFile: string;
11
+
12
+ beforeAll(() => {
13
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ast-grep-test-'));
14
+ testFile = path.join(tempDir, 'test.js');
15
+ fs.writeFileSync(
16
+ testFile,
17
+ `function hello() {
18
+ console.log("world");
19
+ console.log("hello");
20
+ }
21
+ `
22
+ );
23
+ });
24
+
25
+ afterAll(() => {
26
+ fs.rmSync(tempDir, { recursive: true, force: true });
27
+ });
28
+
29
+ describe('Tool Definitions', () => {
30
+ it('should have ast_grep_search tool', () => {
31
+ const tool = STANDARD_TOOLS.find((t) => t.name === 'ast_grep_search');
32
+ expect(tool).toBeDefined();
33
+ expect(tool?.execution?.type).toBe('script');
34
+ expect(tool?.parameters?.required).toContain('pattern');
35
+ expect(tool?.parameters?.required).toContain('paths');
36
+ });
37
+
38
+ it('should have ast_grep_replace tool', () => {
39
+ const tool = STANDARD_TOOLS.find((t) => t.name === 'ast_grep_replace');
40
+ expect(tool).toBeDefined();
41
+ expect(tool?.execution?.type).toBe('script');
42
+ expect(tool?.parameters?.required).toContain('pattern');
43
+ expect(tool?.parameters?.required).toContain('rewrite');
44
+ expect(tool?.parameters?.required).toContain('paths');
45
+ });
46
+
47
+ it('should have append_file tool', () => {
48
+ const tool = STANDARD_TOOLS.find((t) => t.name === 'append_file');
49
+ expect(tool).toBeDefined();
50
+ expect(tool?.execution?.type).toBe('file');
51
+ expect(tool?.execution?.op).toBe('append');
52
+ });
53
+ });
54
+
55
+ describe('Security Validation', () => {
56
+ const cwd = process.cwd();
57
+
58
+ it('should allow AST tools for paths within CWD', () => {
59
+ expect(() => {
60
+ validateStandardToolSecurity(
61
+ 'ast_grep_search',
62
+ { pattern: 'console.log($A)', paths: ['src/test.ts'] },
63
+ { allowOutsideCwd: false }
64
+ );
65
+ }).not.toThrow();
66
+ });
67
+
68
+ it('should block AST tools for paths outside CWD', () => {
69
+ expect(() => {
70
+ validateStandardToolSecurity(
71
+ 'ast_grep_search',
72
+ { pattern: 'console.log($A)', paths: ['/etc/passwd'] },
73
+ { allowOutsideCwd: false }
74
+ );
75
+ }).toThrow(/Access denied/);
76
+ });
77
+
78
+ it('should allow AST tools for paths outside CWD when allowOutsideCwd is true', () => {
79
+ expect(() => {
80
+ validateStandardToolSecurity(
81
+ 'ast_grep_replace',
82
+ { pattern: 'foo', rewrite: 'bar', paths: ['/tmp/test.js'] },
83
+ { allowOutsideCwd: true }
84
+ );
85
+ }).not.toThrow();
86
+ });
87
+
88
+ it('should validate all paths in the array', () => {
89
+ expect(() => {
90
+ validateStandardToolSecurity(
91
+ 'ast_grep_search',
92
+ { pattern: 'test', paths: ['src/ok.ts', '../../outside.ts'] },
93
+ { allowOutsideCwd: false }
94
+ );
95
+ }).toThrow(/Access denied/);
96
+ });
97
+
98
+ it('should allow append_file within CWD', () => {
99
+ expect(() => {
100
+ validateStandardToolSecurity(
101
+ 'append_file',
102
+ { path: 'test.log', content: 'test' },
103
+ { allowOutsideCwd: false }
104
+ );
105
+ }).not.toThrow();
106
+ });
107
+ });
108
+
109
+ describe('AST-Grep Search Execution', () => {
110
+ it('should compile ast_grep_search script without errors', () => {
111
+ const tool = STANDARD_TOOLS.find((t) => t.name === 'ast_grep_search');
112
+ expect(tool).toBeDefined();
113
+
114
+ const script = tool?.execution?.run as string;
115
+ const sandbox = {
116
+ args: { pattern: 'console.log($A)', language: 'javascript', paths: [] },
117
+ require: (mod: string) => {
118
+ if (mod === 'node:fs' || mod === 'fs') {
119
+ return {
120
+ existsSync: () => false,
121
+ readFileSync: () => '',
122
+ };
123
+ }
124
+ if (mod === 'node:path' || mod === 'path') {
125
+ return { join: (...args: string[]) => args.join('/') };
126
+ }
127
+ if (mod === '@ast-grep/napi') {
128
+ return {
129
+ Lang: {
130
+ JavaScript: 'javascript',
131
+ TypeScript: 'typescript',
132
+ },
133
+ parse: () => ({
134
+ root: () => ({
135
+ findAll: () => [],
136
+ }),
137
+ }),
138
+ };
139
+ }
140
+ return {};
141
+ },
142
+ };
143
+
144
+ expect(() => {
145
+ vm.runInNewContext(script, sandbox);
146
+ }).not.toThrow();
147
+ });
148
+ });
149
+
150
+ describe('AST-Grep Replace Execution', () => {
151
+ it('should compile ast_grep_replace script without errors', () => {
152
+ const tool = STANDARD_TOOLS.find((t) => t.name === 'ast_grep_replace');
153
+ expect(tool).toBeDefined();
154
+
155
+ const script = tool?.execution?.run as string;
156
+ const sandbox = {
157
+ args: {
158
+ pattern: 'console.log($A)',
159
+ rewrite: 'logger.info($A)',
160
+ language: 'javascript',
161
+ paths: [],
162
+ },
163
+ require: (mod: string) => {
164
+ if (mod === 'node:fs' || mod === 'fs') {
165
+ return {
166
+ existsSync: () => false,
167
+ readFileSync: () => '',
168
+ writeFileSync: () => {},
169
+ };
170
+ }
171
+ if (mod === 'node:path' || mod === 'path') {
172
+ return { join: (...args: string[]) => args.join('/') };
173
+ }
174
+ if (mod === '@ast-grep/napi') {
175
+ return {
176
+ Lang: {
177
+ JavaScript: 'javascript',
178
+ TypeScript: 'typescript',
179
+ },
180
+ parse: () => ({
181
+ root: () => ({
182
+ replace: () => '',
183
+ }),
184
+ }),
185
+ };
186
+ }
187
+ return {};
188
+ },
189
+ };
190
+
191
+ expect(() => {
192
+ vm.runInNewContext(script, sandbox);
193
+ }).not.toThrow();
194
+ });
195
+ });
196
+ });
@@ -19,6 +19,7 @@ describe('Standard Tools Execution Verification', () => {
19
19
  readdirSync: () => [],
20
20
  statSync: () => ({ size: 0 }),
21
21
  readFileSync: () => '',
22
+ writeFileSync: () => {},
22
23
  };
23
24
  }
24
25
  if (mod === 'node:path' || mod === 'path') {
@@ -27,6 +28,32 @@ describe('Standard Tools Execution Verification', () => {
27
28
  if (mod === 'glob') {
28
29
  return { globSync: () => [] };
29
30
  }
31
+ if (mod === '@ast-grep/napi') {
32
+ return {
33
+ Lang: {
34
+ JavaScript: 'javascript',
35
+ TypeScript: 'typescript',
36
+ Tsx: 'tsx',
37
+ Python: 'python',
38
+ Rust: 'rust',
39
+ Go: 'go',
40
+ C: 'c',
41
+ Cpp: 'cpp',
42
+ Java: 'java',
43
+ Kotlin: 'kotlin',
44
+ Swift: 'swift',
45
+ Html: 'html',
46
+ Css: 'css',
47
+ Json: 'json',
48
+ },
49
+ parse: () => ({
50
+ root: () => ({
51
+ findAll: () => [],
52
+ replace: () => '',
53
+ }),
54
+ }),
55
+ };
56
+ }
30
57
  return {};
31
58
  },
32
59
  };
@@ -3,8 +3,8 @@ import { existsSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
3
3
  import { join } from 'node:path';
4
4
  import type { ExpressionContext } from '../expression/evaluator';
5
5
  import type { LlmStep, Step } from '../parser/schema';
6
+ import { executeLlmStep } from './executors/llm-executor.ts';
6
7
  import type { LLMAdapter } from './llm-adapter';
7
- import { executeLlmStep } from './llm-executor';
8
8
  import type { StepResult } from './step-executor';
9
9
 
10
10
  describe('Standard Tools Integration', () => {
@@ -42,8 +42,7 @@ System prompt`,
42
42
  });
43
43
 
44
44
  it('should inject standard tools when useStandardTools is true', async () => {
45
- // biome-ignore lint/suspicious/noExplicitAny: mock
46
- let capturedTools: any[] = [];
45
+ let capturedTools: unknown[] = [];
47
46
 
48
47
  const chatMock = mock(async (messages, options) => {
49
48
  capturedTools = options.tools || [];
@@ -63,8 +62,7 @@ System prompt`,
63
62
  ],
64
63
  },
65
64
  usage: { prompt_tokens: 10, completion_tokens: 10, total_tokens: 20 },
66
- // biome-ignore lint/suspicious/noExplicitAny: mock
67
- } as any;
65
+ };
68
66
  }) as unknown as LLMAdapter['chat'];
69
67
  const getAdapter = createMockGetAdapter(chatMock);
70
68
 
@@ -133,8 +131,7 @@ System prompt`,
133
131
  return {
134
132
  message: { role: 'assistant', content: 'stop' },
135
133
  usage: { prompt_tokens: 1, completion_tokens: 1, total_tokens: 2 },
136
- // biome-ignore lint/suspicious/noExplicitAny: mock
137
- } as any;
134
+ };
138
135
  }
139
136
  return {
140
137
  message: {
@@ -143,12 +140,11 @@ System prompt`,
143
140
  {
144
141
  id: 'c2',
145
142
  type: 'function',
146
- function: { name: 'run_command', arguments: '{"command":"rm -rf /"}' },
143
+ function: { name: 'run_command', arguments: '{"command":"echo $HOME"}' },
147
144
  },
148
145
  ],
149
146
  },
150
- // biome-ignore lint/suspicious/noExplicitAny: mock
151
- } as any;
147
+ };
152
148
  }) as unknown as LLMAdapter['chat'];
153
149
  const getAdapter = createMockGetAdapter(chatMock);
154
150