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.
- package/README.md +276 -32
- package/package.json +8 -4
- package/src/cli.ts +350 -416
- package/src/commands/doc.ts +31 -0
- package/src/commands/event.ts +29 -0
- package/src/commands/graph.ts +37 -0
- package/src/commands/index.ts +14 -0
- package/src/commands/init.ts +185 -0
- package/src/commands/run.ts +124 -0
- package/src/commands/schema.ts +40 -0
- package/src/commands/utils.ts +78 -0
- package/src/commands/validate.ts +111 -0
- package/src/db/workflow-db.test.ts +314 -0
- package/src/db/workflow-db.ts +810 -210
- package/src/expression/evaluator-audit.test.ts +4 -2
- package/src/expression/evaluator.test.ts +14 -1
- package/src/expression/evaluator.ts +166 -19
- package/src/parser/config-schema.ts +18 -0
- package/src/parser/schema.ts +153 -22
- package/src/parser/test-schema.ts +6 -6
- package/src/parser/workflow-parser.test.ts +24 -0
- package/src/parser/workflow-parser.ts +65 -3
- package/src/runner/auto-heal.test.ts +5 -6
- package/src/runner/blueprint-executor.test.ts +2 -2
- package/src/runner/debug-repl.test.ts +5 -8
- package/src/runner/debug-repl.ts +59 -16
- package/src/runner/durable-timers.test.ts +11 -2
- package/src/runner/engine-executor.test.ts +1 -1
- package/src/runner/events.ts +57 -0
- package/src/runner/executors/artifact-executor.ts +166 -0
- package/src/runner/{blueprint-executor.ts → executors/blueprint-executor.ts} +15 -7
- package/src/runner/{engine-executor.ts → executors/engine-executor.ts} +55 -7
- package/src/runner/executors/file-executor.test.ts +48 -0
- package/src/runner/executors/file-executor.ts +324 -0
- package/src/runner/{foreach-executor.ts → executors/foreach-executor.ts} +168 -80
- package/src/runner/executors/human-executor.ts +144 -0
- package/src/runner/executors/join-executor.ts +75 -0
- package/src/runner/executors/llm-executor.ts +1266 -0
- package/src/runner/executors/memory-executor.ts +71 -0
- package/src/runner/executors/plan-executor.ts +104 -0
- package/src/runner/executors/request-executor.ts +265 -0
- package/src/runner/executors/script-executor.ts +43 -0
- package/src/runner/executors/shell-executor.ts +403 -0
- package/src/runner/executors/subworkflow-executor.ts +114 -0
- package/src/runner/executors/types.ts +69 -0
- package/src/runner/executors/wait-executor.ts +59 -0
- package/src/runner/join-scheduling.test.ts +197 -0
- package/src/runner/llm-adapter-runtime.test.ts +209 -0
- package/src/runner/llm-adapter.test.ts +419 -24
- package/src/runner/llm-adapter.ts +130 -26
- package/src/runner/llm-clarification.test.ts +2 -1
- package/src/runner/llm-executor.test.ts +532 -17
- package/src/runner/mcp-client-audit.test.ts +1 -2
- package/src/runner/mcp-client.ts +136 -46
- package/src/runner/mcp-manager.test.ts +4 -0
- package/src/runner/mcp-server.test.ts +58 -0
- package/src/runner/mcp-server.ts +26 -0
- package/src/runner/memoization.test.ts +190 -0
- package/src/runner/optimization-runner.ts +4 -9
- package/src/runner/quality-gate.test.ts +69 -0
- package/src/runner/reflexion.test.ts +6 -17
- package/src/runner/resource-pool.ts +102 -14
- package/src/runner/services/context-builder.ts +144 -0
- package/src/runner/services/secret-manager.ts +105 -0
- package/src/runner/services/workflow-validator.ts +131 -0
- package/src/runner/shell-executor.test.ts +28 -4
- package/src/runner/standard-tools-ast.test.ts +196 -0
- package/src/runner/standard-tools-execution.test.ts +27 -0
- package/src/runner/standard-tools-integration.test.ts +6 -10
- package/src/runner/standard-tools.ts +339 -102
- package/src/runner/step-executor.test.ts +216 -4
- package/src/runner/step-executor.ts +69 -941
- package/src/runner/stream-utils.ts +7 -3
- package/src/runner/test-harness.ts +20 -1
- package/src/runner/timeout.test.ts +10 -0
- package/src/runner/timeout.ts +11 -2
- package/src/runner/tool-integration.test.ts +1 -1
- package/src/runner/wait-step.test.ts +102 -0
- package/src/runner/workflow-runner.test.ts +208 -15
- package/src/runner/workflow-runner.ts +890 -818
- package/src/runner/workflow-scheduler.ts +75 -0
- package/src/runner/workflow-state.ts +269 -0
- package/src/runner/workflow-subflows.test.ts +13 -12
- package/src/scripts/generate-schemas.ts +16 -0
- package/src/templates/agents/explore.md +1 -0
- package/src/templates/agents/general.md +1 -0
- package/src/templates/agents/handoff-router.md +14 -0
- package/src/templates/agents/handoff-specialist.md +15 -0
- package/src/templates/agents/keystone-architect.md +13 -44
- package/src/templates/agents/my-agent.md +1 -0
- package/src/templates/agents/software-engineer.md +1 -0
- package/src/templates/agents/summarizer.md +1 -0
- package/src/templates/agents/test-agent.md +1 -0
- package/src/templates/agents/tester.md +1 -0
- package/src/templates/{basic-inputs.yaml → basics/basic-inputs.yaml} +2 -0
- package/src/templates/{basic-shell.yaml → basics/basic-shell.yaml} +2 -1
- package/src/templates/{full-feature-demo.yaml → basics/full-feature-demo.yaml} +2 -0
- package/src/templates/{stop-watch.yaml → basics/stop-watch.yaml} +1 -0
- package/src/templates/{child-rollback.yaml → control-flow/child-rollback.yaml} +1 -0
- package/src/templates/{cleanup-finally.yaml → control-flow/cleanup-finally.yaml} +1 -0
- package/src/templates/{fan-out-fan-in.yaml → control-flow/fan-out-fan-in.yaml} +3 -0
- package/src/templates/control-flow/idempotency-example.yaml +30 -0
- package/src/templates/{loop-parallel.yaml → control-flow/loop-parallel.yaml} +3 -0
- package/src/templates/{parent-rollback.yaml → control-flow/parent-rollback.yaml} +1 -0
- package/src/templates/{retry-policy.yaml → control-flow/retry-policy.yaml} +3 -0
- package/src/templates/features/artifact-example.yaml +39 -0
- package/src/templates/{engine-example.yaml → features/engine-example.yaml} +1 -0
- package/src/templates/{human-interaction.yaml → features/human-interaction.yaml} +1 -0
- package/src/templates/{llm-agent.yaml → features/llm-agent.yaml} +1 -0
- package/src/templates/{memory-service.yaml → features/memory-service.yaml} +2 -0
- package/src/templates/{robust-automation.yaml → features/robust-automation.yaml} +3 -0
- package/src/templates/features/script-example.yaml +27 -0
- package/src/templates/patterns/agent-handoff.yaml +53 -0
- package/src/templates/{approval-process.yaml → patterns/approval-process.yaml} +1 -0
- package/src/templates/{batch-processor.yaml → patterns/batch-processor.yaml} +2 -0
- package/src/templates/{composition-child.yaml → patterns/composition-child.yaml} +1 -0
- package/src/templates/{composition-parent.yaml → patterns/composition-parent.yaml} +1 -0
- package/src/templates/{data-pipeline.yaml → patterns/data-pipeline.yaml} +2 -0
- package/src/templates/{decompose-implement.yaml → scaffolding/decompose-implement.yaml} +1 -0
- package/src/templates/{decompose-problem.yaml → scaffolding/decompose-problem.yaml} +1 -0
- package/src/templates/{decompose-research.yaml → scaffolding/decompose-research.yaml} +1 -0
- package/src/templates/{decompose-review.yaml → scaffolding/decompose-review.yaml} +1 -0
- package/src/templates/{dev.yaml → scaffolding/dev.yaml} +1 -0
- package/src/templates/scaffolding/review-loop.yaml +97 -0
- package/src/templates/{scaffold-feature.yaml → scaffolding/scaffold-feature.yaml} +2 -0
- package/src/templates/{scaffold-generate.yaml → scaffolding/scaffold-generate.yaml} +1 -0
- package/src/templates/{scaffold-plan.yaml → scaffolding/scaffold-plan.yaml} +1 -0
- package/src/templates/testing/invalid.yaml +6 -0
- package/src/ui/dashboard.tsx +191 -33
- package/src/utils/auth-manager.test.ts +337 -0
- package/src/utils/auth-manager.ts +157 -61
- package/src/utils/blueprint-utils.ts +4 -6
- package/src/utils/config-loader.test.ts +2 -0
- package/src/utils/config-loader.ts +12 -3
- package/src/utils/constants.ts +76 -0
- package/src/utils/container.ts +63 -0
- package/src/utils/context-injector.test.ts +200 -0
- package/src/utils/context-injector.ts +244 -0
- package/src/utils/doc-generator.ts +85 -0
- package/src/utils/env-filter.ts +45 -0
- package/src/utils/json-parser.test.ts +12 -0
- package/src/utils/json-parser.ts +30 -5
- package/src/utils/logger.ts +12 -1
- package/src/utils/mermaid.ts +4 -0
- package/src/utils/paths.ts +52 -1
- package/src/utils/process-sandbox-worker.test.ts +46 -0
- package/src/utils/process-sandbox.ts +227 -14
- package/src/utils/redactor.test.ts +11 -6
- package/src/utils/redactor.ts +25 -9
- package/src/utils/sandbox.ts +3 -0
- package/src/runner/llm-executor.ts +0 -638
- package/src/runner/shell-executor.ts +0 -366
- 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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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":"
|
|
143
|
+
function: { name: 'run_command', arguments: '{"command":"echo $HOME"}' },
|
|
147
144
|
},
|
|
148
145
|
],
|
|
149
146
|
},
|
|
150
|
-
|
|
151
|
-
} as any;
|
|
147
|
+
};
|
|
152
148
|
}) as unknown as LLMAdapter['chat'];
|
|
153
149
|
const getAdapter = createMockGetAdapter(chatMock);
|
|
154
150
|
|