@felan-ai/agent-core 0.0.0-bootstrap.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 (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +29 -0
  3. package/dist/extensions.d.ts +10 -0
  4. package/dist/extensions.d.ts.map +1 -0
  5. package/dist/extensions.js +73 -0
  6. package/dist/extensions.js.map +1 -0
  7. package/dist/host-agent-runtime.d.ts +24 -0
  8. package/dist/host-agent-runtime.d.ts.map +1 -0
  9. package/dist/host-agent-runtime.js +202 -0
  10. package/dist/host-agent-runtime.js.map +1 -0
  11. package/dist/index.d.ts +13 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +7 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/resource-loader.d.ts +11 -0
  16. package/dist/resource-loader.d.ts.map +1 -0
  17. package/dist/resource-loader.js +58 -0
  18. package/dist/resource-loader.js.map +1 -0
  19. package/dist/runtime-conformance.d.ts +29 -0
  20. package/dist/runtime-conformance.d.ts.map +1 -0
  21. package/dist/runtime-conformance.js +172 -0
  22. package/dist/runtime-conformance.js.map +1 -0
  23. package/dist/runtime-test-kit.d.ts +5 -0
  24. package/dist/runtime-test-kit.d.ts.map +1 -0
  25. package/dist/runtime-test-kit.js +3 -0
  26. package/dist/runtime-test-kit.js.map +1 -0
  27. package/dist/runtime.d.ts +23 -0
  28. package/dist/runtime.d.ts.map +1 -0
  29. package/dist/runtime.js +2 -0
  30. package/dist/runtime.js.map +1 -0
  31. package/dist/session.d.ts +52 -0
  32. package/dist/session.d.ts.map +1 -0
  33. package/dist/session.js +81 -0
  34. package/dist/session.js.map +1 -0
  35. package/dist/test-agent-runtime.d.ts +41 -0
  36. package/dist/test-agent-runtime.d.ts.map +1 -0
  37. package/dist/test-agent-runtime.js +203 -0
  38. package/dist/test-agent-runtime.js.map +1 -0
  39. package/dist/tools.d.ts +4 -0
  40. package/dist/tools.d.ts.map +1 -0
  41. package/dist/tools.js +150 -0
  42. package/dist/tools.js.map +1 -0
  43. package/package.json +39 -0
@@ -0,0 +1,172 @@
1
+ import { dirname, resolve } from 'node:path';
2
+ const literalArguments = ['plain', 'two words', '"quoted"', "'single'", '$HOME', 'semi;colon', '', '--flag=value'];
3
+ export const testRuntimeConformanceFixtures = {
4
+ argv: {
5
+ command: 'fixture:argv',
6
+ args: literalArguments,
7
+ stdout: JSON.stringify(literalArguments),
8
+ },
9
+ failure: {
10
+ command: 'fixture:failure',
11
+ args: [],
12
+ stderr: 'expected failure',
13
+ code: 17,
14
+ },
15
+ longRunning: {
16
+ command: 'fixture:wait',
17
+ args: [],
18
+ },
19
+ cwd: {
20
+ command: 'fixture:cwd',
21
+ args: [],
22
+ },
23
+ binary: new Uint8Array([0, 255, 1, 128, 10, 13, 239, 191, 189]),
24
+ };
25
+ export function createNodeRuntimeConformanceFixtures(command = 'node') {
26
+ return {
27
+ argv: {
28
+ command,
29
+ args: ['-e', 'process.stdout.write(JSON.stringify(process.argv.slice(1)))', '--', ...literalArguments],
30
+ stdout: JSON.stringify(literalArguments),
31
+ },
32
+ failure: {
33
+ command,
34
+ args: ['-e', "process.stderr.write('expected failure'); process.exit(17)"],
35
+ stderr: 'expected failure',
36
+ code: 17,
37
+ },
38
+ longRunning: {
39
+ command,
40
+ args: ['-e', 'setInterval(() => {}, 1000)'],
41
+ },
42
+ cwd: {
43
+ command,
44
+ args: ['-e', 'process.stdout.write(process.cwd())'],
45
+ },
46
+ binary: testRuntimeConformanceFixtures.binary.slice(),
47
+ };
48
+ }
49
+ export function createRuntimeConformanceCases(fixtures) {
50
+ return [
51
+ {
52
+ name: 'keeps cwd immutable and contains file paths',
53
+ async run(runtime) {
54
+ const originalCwd = runtime.cwd;
55
+ Reflect.set(runtime, 'cwd', resolve(runtime.cwd, 'other'));
56
+ equal(runtime.cwd, originalCwd, 'cwd changed');
57
+ await runtime.mkdir('nested', { recursive: true });
58
+ await runtime.writeFile('nested/relative.bin', fixtures.binary);
59
+ bytesEqual(await runtime.readFile(resolve(runtime.cwd, 'nested/relative.bin')), fixtures.binary);
60
+ await rejects(() => runtime.readFile('../outside'));
61
+ await rejects(() => runtime.writeFile(`${runtime.cwd}\0bad`, fixtures.binary));
62
+ await rejects(() => runtime.remove(runtime.cwd, { recursive: true }));
63
+ },
64
+ },
65
+ {
66
+ name: 'rejects escaping exec cwd before execution',
67
+ async run(runtime) {
68
+ await rejects(() => runtime.exec(fixtures.cwd.command, fixtures.cwd.args, {
69
+ cwd: resolve(runtime.cwd, '..'),
70
+ }));
71
+ const childCwd = resolve(runtime.cwd, 'child');
72
+ await runtime.mkdir(childCwd, { recursive: true });
73
+ const result = await runtime.exec(fixtures.cwd.command, fixtures.cwd.args, { cwd: childCwd });
74
+ equal(result.stdout, childCwd, 'exec cwd was not contained or normalized');
75
+ },
76
+ },
77
+ {
78
+ name: 'rejects symlink-resolved escapes when supported',
79
+ async run(runtime, harness) {
80
+ if (!harness.createSymlinkEscape)
81
+ return;
82
+ const linkPath = resolve(runtime.cwd, 'escape-link');
83
+ await harness.createSymlinkEscape(runtime, linkPath);
84
+ await rejects(() => runtime.readFile(resolve(linkPath, 'secret')));
85
+ },
86
+ },
87
+ {
88
+ name: 'preserves literal argv boundaries',
89
+ async run(runtime) {
90
+ const result = await runtime.exec(fixtures.argv.command, fixtures.argv.args);
91
+ equal(result.stdout, fixtures.argv.stdout ?? '', 'argv output changed');
92
+ equal(result.code, 0, 'argv command failed');
93
+ equal(result.killed, false, 'argv command was killed');
94
+ },
95
+ },
96
+ {
97
+ name: 'returns nonzero execution results',
98
+ async run(runtime) {
99
+ const result = await runtime.exec(fixtures.failure.command, fixtures.failure.args);
100
+ equal(result.code, fixtures.failure.code ?? 1, 'nonzero code changed');
101
+ equal(result.stderr, fixtures.failure.stderr ?? '', 'stderr changed');
102
+ equal(result.killed, false, 'failure command was killed');
103
+ },
104
+ },
105
+ {
106
+ name: 'round-trips binary file content',
107
+ async run(runtime) {
108
+ await runtime.mkdir(dirname('binary/payload.bin'), { recursive: true });
109
+ await runtime.writeFile('binary/payload.bin', fixtures.binary);
110
+ bytesEqual(await runtime.readFile('binary/payload.bin'), fixtures.binary);
111
+ },
112
+ },
113
+ {
114
+ name: 'kills execution on timeout',
115
+ async run(runtime) {
116
+ const result = await runtime.exec(fixtures.longRunning.command, fixtures.longRunning.args, { timeout: 10 });
117
+ killed(result, 'timeout');
118
+ },
119
+ },
120
+ {
121
+ name: 'kills execution on AbortSignal cancellation',
122
+ async run(runtime) {
123
+ const controller = new AbortController();
124
+ const execution = runtime.exec(fixtures.longRunning.command, fixtures.longRunning.args, {
125
+ signal: controller.signal,
126
+ });
127
+ controller.abort();
128
+ killed(await execution, 'AbortSignal');
129
+ },
130
+ },
131
+ ];
132
+ }
133
+ export async function runRuntimeConformance(harness, fixtures) {
134
+ for (const testCase of createRuntimeConformanceCases(fixtures)) {
135
+ const runtime = await harness.createRuntime();
136
+ try {
137
+ await testCase.run(runtime, harness);
138
+ }
139
+ catch (error) {
140
+ throw new Error(`Runtime conformance failed: ${testCase.name}`, { cause: error });
141
+ }
142
+ finally {
143
+ await harness.disposeRuntime?.(runtime);
144
+ }
145
+ }
146
+ }
147
+ function equal(actual, expected, message) {
148
+ if (actual !== expected) {
149
+ throw new Error(`${message}: expected ${String(expected)}, received ${String(actual)}`);
150
+ }
151
+ }
152
+ function bytesEqual(actual, expected) {
153
+ if (actual.length !== expected.length || actual.some((value, index) => value !== expected[index])) {
154
+ throw new Error('Binary content changed');
155
+ }
156
+ }
157
+ async function rejects(operation) {
158
+ try {
159
+ await operation();
160
+ }
161
+ catch {
162
+ return;
163
+ }
164
+ throw new Error('Expected operation to reject');
165
+ }
166
+ function killed(result, source) {
167
+ equal(result.killed, true, `${source} did not kill execution`);
168
+ if (result.code === 0) {
169
+ throw new Error(`${source} returned a successful exit code`);
170
+ }
171
+ }
172
+ //# sourceMappingURL=runtime-conformance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-conformance.js","sourceRoot":"","sources":["../src/runtime-conformance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { createNodeRuntimeConformanceFixtures, createRuntimeConformanceCases, runRuntimeConformance, testRuntimeConformanceFixtures, } from './runtime-conformance.js';
2
+ export type { RuntimeCommandFixture, RuntimeConformanceCase, RuntimeConformanceFixtures, RuntimeConformanceHarness, } from './runtime-conformance.js';
3
+ export { TestAgentRuntime } from './test-agent-runtime.js';
4
+ export type { TestAgentRuntimeOptions, TestExecCall, TestShellCall, TestShellOptions, } from './test-agent-runtime.js';
5
+ //# sourceMappingURL=runtime-test-kit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-test-kit.d.ts","sourceRoot":"","sources":["../src/runtime-test-kit.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oCAAoC,EACpC,6BAA6B,EAC7B,qBAAqB,EACrB,8BAA8B,GAC/B,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,qBAAqB,EACrB,sBAAsB,EACtB,0BAA0B,EAC1B,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EACV,uBAAuB,EACvB,YAAY,EACZ,aAAa,EACb,gBAAgB,GACjB,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { createNodeRuntimeConformanceFixtures, createRuntimeConformanceCases, runRuntimeConformance, testRuntimeConformanceFixtures, } from './runtime-conformance.js';
2
+ export { TestAgentRuntime } from './test-agent-runtime.js';
3
+ //# sourceMappingURL=runtime-test-kit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-test-kit.js","sourceRoot":"","sources":["../src/runtime-test-kit.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oCAAoC,EACpC,6BAA6B,EAC7B,qBAAqB,EACrB,8BAA8B,GAC/B,MAAM,0BAA0B,CAAC;AAOlC,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { ExecOptions, ExecResult } from '@earendil-works/pi-coding-agent';
2
+ export type { ExecOptions, ExecResult } from '@earendil-works/pi-coding-agent';
3
+ export type AgentRuntimeKind = 'host' | 'docker' | 'daytona';
4
+ export interface AgentRuntime {
5
+ readonly kind: AgentRuntimeKind;
6
+ readonly cwd: string;
7
+ exec(command: string, args: readonly string[], options?: ExecOptions): Promise<ExecResult>;
8
+ shell(command: string, options?: ExecOptions & {
9
+ env?: Readonly<Record<string, string>>;
10
+ }): Promise<ExecResult>;
11
+ readFile(path: string): Promise<Uint8Array>;
12
+ writeFile(path: string, content: Uint8Array): Promise<void>;
13
+ listFiles(path: string, options?: {
14
+ recursive?: boolean;
15
+ }): Promise<string[]>;
16
+ mkdir(path: string, options?: {
17
+ recursive?: boolean;
18
+ }): Promise<void>;
19
+ remove(path: string, options?: {
20
+ recursive?: boolean;
21
+ }): Promise<void>;
22
+ }
23
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE/E,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE/E,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE7D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAErB,IAAI,CACF,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,UAAU,CAAC,CAAC;IAEvB,KAAK,CACH,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,WAAW,GAAG;QAAE,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;KAAE,GACjE,OAAO,CAAC,UAAU,CAAC,CAAC;IAEvB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC5C,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9E,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":""}
@@ -0,0 +1,52 @@
1
+ import { type AgentSession, type CreateAgentSessionOptions, type CreateAgentSessionResult, type CreateAgentSessionRuntimeFactory, type CreateAgentSessionRuntimeResult, type ModelRuntime, type SessionManager, type SessionStartEvent, type SettingsManager, type ToolDefinition } from '@earendil-works/pi-coding-agent';
2
+ import { type ExtensionPackageImporter } from './extensions.js';
3
+ import type { AgentRuntime } from './runtime.js';
4
+ export type StreamFunction = AgentSession['agent']['streamFunction'];
5
+ export interface AgentSessionHost {
6
+ wrapStreamFunction?(original: StreamFunction): StreamFunction;
7
+ createChildSession(request: AgentChildSessionRequest): Promise<AgentChildSessionResult>;
8
+ }
9
+ export interface AgentChildSessionRequest {
10
+ readonly rootSessionId: string;
11
+ readonly parentSessionId: string;
12
+ readonly personaId: string;
13
+ readonly prompt: string;
14
+ readonly block: boolean;
15
+ readonly model?: string;
16
+ readonly timeoutMinutes?: number;
17
+ readonly metadata?: Readonly<Record<string, unknown>>;
18
+ }
19
+ export interface AgentChildSessionResult {
20
+ readonly ok: boolean;
21
+ readonly sessionId: string;
22
+ readonly status: 'running' | 'queued' | 'completed' | 'failed';
23
+ readonly result?: string;
24
+ readonly error?: string;
25
+ readonly message?: string;
26
+ }
27
+ export interface CreateAgentCoreSessionOptions {
28
+ readonly applicationKind: 'cloud' | 'tui';
29
+ readonly runtime: AgentRuntime;
30
+ readonly host: AgentSessionHost;
31
+ readonly extensionPackages: readonly string[];
32
+ readonly importExtension: ExtensionPackageImporter;
33
+ readonly extensionFlagValues?: ReadonlyMap<string, boolean | string>;
34
+ readonly modelRuntime: ModelRuntime;
35
+ readonly settingsManager: SettingsManager;
36
+ readonly sessionManager: SessionManager;
37
+ readonly agentDir?: string;
38
+ readonly model?: CreateAgentSessionOptions['model'];
39
+ readonly thinkingLevel?: CreateAgentSessionOptions['thinkingLevel'];
40
+ readonly scopedModels?: CreateAgentSessionOptions['scopedModels'];
41
+ readonly sessionStartEvent?: SessionStartEvent;
42
+ readonly customTools?: readonly ToolDefinition[];
43
+ readonly systemPrompt?: string;
44
+ readonly appendSystemPrompt?: readonly string[];
45
+ }
46
+ export declare function createAgentCoreSession(options: CreateAgentCoreSessionOptions): Promise<CreateAgentSessionResult>;
47
+ export declare function createAgentCoreSessionRuntime(options: CreateAgentCoreSessionOptions): Promise<CreateAgentSessionRuntimeResult>;
48
+ export type AgentCoreSessionRuntimeFactoryRequest = Parameters<CreateAgentSessionRuntimeFactory>[0];
49
+ export type AgentCoreSessionRuntimeFactoryOptions = Omit<CreateAgentCoreSessionOptions, 'agentDir' | 'sessionManager' | 'sessionStartEvent'>;
50
+ export type AgentCoreSessionRuntimeOptionsFactory = (request: AgentCoreSessionRuntimeFactoryRequest) => AgentCoreSessionRuntimeFactoryOptions | Promise<AgentCoreSessionRuntimeFactoryOptions>;
51
+ export declare function createAgentCoreSessionRuntimeFactory(createOptions: AgentCoreSessionRuntimeOptionsFactory): CreateAgentSessionRuntimeFactory;
52
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ import { createAgentSession, } from '@earendil-works/pi-coding-agent';
2
+ import { loadFelanExtensions } from './extensions.js';
3
+ import { createAgentCoreResourceLoader } from './resource-loader.js';
4
+ import { createRuntimeCodingTools } from './tools.js';
5
+ export async function createAgentCoreSession(options) {
6
+ const composition = await composeAgentCoreSession(options);
7
+ return composition.result;
8
+ }
9
+ export async function createAgentCoreSessionRuntime(options) {
10
+ const composition = await composeAgentCoreSession(options);
11
+ return {
12
+ ...composition.result,
13
+ services: composition.services,
14
+ diagnostics: composition.services.diagnostics,
15
+ };
16
+ }
17
+ export function createAgentCoreSessionRuntimeFactory(createOptions) {
18
+ return async (request) => createAgentCoreSessionRuntime({
19
+ ...await createOptions(request),
20
+ agentDir: request.agentDir,
21
+ sessionManager: request.sessionManager,
22
+ ...(request.sessionStartEvent === undefined
23
+ ? {}
24
+ : { sessionStartEvent: request.sessionStartEvent }),
25
+ });
26
+ }
27
+ async function composeAgentCoreSession(options) {
28
+ const extensionFactories = await loadFelanExtensions(options.extensionPackages, options.importExtension, options.runtime);
29
+ const agentDir = options.agentDir ?? options.runtime.cwd;
30
+ const resourceLoader = await createAgentCoreResourceLoader({
31
+ cwd: options.runtime.cwd,
32
+ agentDir,
33
+ extensionFactories,
34
+ ...(options.extensionFlagValues === undefined
35
+ ? {}
36
+ : { extensionFlagValues: options.extensionFlagValues }),
37
+ ...(options.systemPrompt === undefined ? {} : { systemPrompt: options.systemPrompt }),
38
+ ...(options.appendSystemPrompt === undefined
39
+ ? {}
40
+ : { appendSystemPrompt: options.appendSystemPrompt }),
41
+ });
42
+ const customTools = [
43
+ ...createRuntimeCodingTools(options.runtime),
44
+ ...(options.customTools ?? []),
45
+ ];
46
+ const result = await createAgentSession({
47
+ cwd: options.runtime.cwd,
48
+ agentDir,
49
+ modelRuntime: options.modelRuntime,
50
+ noTools: 'builtin',
51
+ customTools,
52
+ resourceLoader,
53
+ sessionManager: options.sessionManager,
54
+ settingsManager: options.settingsManager,
55
+ ...(options.model === undefined ? {} : { model: options.model }),
56
+ ...(options.thinkingLevel === undefined ? {} : { thinkingLevel: options.thinkingLevel }),
57
+ ...(options.scopedModels === undefined ? {} : { scopedModels: options.scopedModels }),
58
+ ...(options.sessionStartEvent === undefined
59
+ ? {}
60
+ : { sessionStartEvent: options.sessionStartEvent }),
61
+ });
62
+ if (options.host.wrapStreamFunction) {
63
+ const wrapped = options.host.wrapStreamFunction(result.session.agent.streamFunction);
64
+ if (typeof wrapped !== 'function') {
65
+ throw new Error('AgentSessionHost.wrapStreamFunction must return a stream function');
66
+ }
67
+ result.session.agent.streamFunction = wrapped;
68
+ }
69
+ return {
70
+ result,
71
+ services: {
72
+ cwd: options.runtime.cwd,
73
+ agentDir,
74
+ modelRuntime: options.modelRuntime,
75
+ settingsManager: options.settingsManager,
76
+ resourceLoader,
77
+ diagnostics: [],
78
+ },
79
+ };
80
+ }
81
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import type { AgentRuntime, AgentRuntimeKind, ExecOptions, ExecResult } from './runtime.js';
2
+ export type TestShellOptions = ExecOptions & {
3
+ env?: Readonly<Record<string, string>>;
4
+ };
5
+ export interface TestExecCall {
6
+ readonly command: string;
7
+ readonly args: readonly string[];
8
+ readonly options?: ExecOptions;
9
+ }
10
+ export interface TestShellCall {
11
+ readonly command: string;
12
+ readonly options?: TestShellOptions;
13
+ }
14
+ export interface TestAgentRuntimeOptions {
15
+ readonly kind?: AgentRuntimeKind;
16
+ readonly exec?: (call: TestExecCall) => ExecResult | Promise<ExecResult>;
17
+ readonly shell?: (call: TestShellCall) => ExecResult | Promise<ExecResult>;
18
+ }
19
+ export declare class TestAgentRuntime implements AgentRuntime {
20
+ #private;
21
+ readonly execCalls: TestExecCall[];
22
+ readonly shellCalls: TestShellCall[];
23
+ constructor(cwd?: string, options?: TestAgentRuntimeOptions);
24
+ get cwd(): string;
25
+ get kind(): AgentRuntimeKind;
26
+ exec(command: string, args: readonly string[], options?: ExecOptions): Promise<ExecResult>;
27
+ shell(command: string, options?: TestShellOptions): Promise<ExecResult>;
28
+ readFile(path: string): Promise<Uint8Array>;
29
+ writeFile(path: string, content: Uint8Array): Promise<void>;
30
+ listFiles(path: string, options?: {
31
+ recursive?: boolean;
32
+ }): Promise<string[]>;
33
+ mkdir(path: string, options?: {
34
+ recursive?: boolean;
35
+ }): Promise<void>;
36
+ remove(path: string, options?: {
37
+ recursive?: boolean;
38
+ }): Promise<void>;
39
+ addSymlink(path: string, target: string): void;
40
+ }
41
+ //# sourceMappingURL=test-agent-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-agent-runtime.d.ts","sourceRoot":"","sources":["../src/test-agent-runtime.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE5F,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG;IAC3C,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACxC,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,gBAAgB,CAAC;CACrC;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACjC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACzE,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CAC5E;AASD,qBAAa,gBAAiB,YAAW,YAAY;;IASnD,QAAQ,CAAC,SAAS,EAAE,YAAY,EAAE,CAAM;IACxC,QAAQ,CAAC,UAAU,EAAE,aAAa,EAAE,CAAM;gBAE9B,GAAG,SAAe,EAAE,OAAO,GAAE,uBAA4B;IAQrE,IAAI,GAAG,IAAI,MAAM,CAEhB;IAED,IAAI,IAAI,IAAI,gBAAgB,CAE3B;IAEK,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAa1F,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC;IAWvE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAS3C,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ3D,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAc7E,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBrE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB5E,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;CA+F/C"}
@@ -0,0 +1,203 @@
1
+ import { dirname, isAbsolute, relative, resolve, sep } from 'node:path';
2
+ const successResult = () => ({
3
+ stdout: '',
4
+ stderr: '',
5
+ code: 0,
6
+ killed: false,
7
+ });
8
+ export class TestAgentRuntime {
9
+ #cwd;
10
+ #kind;
11
+ #execHandler;
12
+ #shellHandler;
13
+ #files = new Map();
14
+ #directories = new Set();
15
+ #symlinks = new Map();
16
+ execCalls = [];
17
+ shellCalls = [];
18
+ constructor(cwd = '/workspace', options = {}) {
19
+ this.#cwd = resolve(cwd);
20
+ this.#kind = options.kind ?? 'host';
21
+ this.#execHandler = options.exec ?? successResult;
22
+ this.#shellHandler = options.shell ?? successResult;
23
+ this.#directories.add(this.#cwd);
24
+ }
25
+ get cwd() {
26
+ return this.#cwd;
27
+ }
28
+ get kind() {
29
+ return this.#kind;
30
+ }
31
+ async exec(command, args, options) {
32
+ const normalizedOptions = this.#normalizeExecOptions(options);
33
+ if (normalizedOptions?.signal?.aborted) {
34
+ return this.#killedResult();
35
+ }
36
+ const call = normalizedOptions
37
+ ? { command, args: [...args], options: normalizedOptions }
38
+ : { command, args: [...args] };
39
+ this.execCalls.push(call);
40
+ return this.#run(() => this.#execHandler(call), normalizedOptions);
41
+ }
42
+ async shell(command, options) {
43
+ const normalizedOptions = this.#normalizeShellOptions(options);
44
+ if (normalizedOptions?.signal?.aborted) {
45
+ return this.#killedResult();
46
+ }
47
+ const call = normalizedOptions ? { command, options: normalizedOptions } : { command };
48
+ this.shellCalls.push(call);
49
+ return this.#run(() => this.#shellHandler(call), normalizedOptions);
50
+ }
51
+ async readFile(path) {
52
+ const resolvedPath = this.#resolvePath(path);
53
+ const content = this.#files.get(resolvedPath);
54
+ if (!content) {
55
+ throw new Error(`File does not exist: ${path}`);
56
+ }
57
+ return content.slice();
58
+ }
59
+ async writeFile(path, content) {
60
+ const resolvedPath = this.#resolvePath(path, false);
61
+ if (!this.#directories.has(dirname(resolvedPath))) {
62
+ throw new Error(`Parent directory does not exist: ${path}`);
63
+ }
64
+ this.#files.set(resolvedPath, content.slice());
65
+ }
66
+ async listFiles(path, options) {
67
+ const resolvedPath = this.#resolvePath(path);
68
+ if (!this.#directories.has(resolvedPath)) {
69
+ throw new Error(`Directory does not exist: ${path}`);
70
+ }
71
+ const prefix = `${resolvedPath}${sep}`;
72
+ return [...this.#files.keys()]
73
+ .filter((filePath) => filePath.startsWith(prefix))
74
+ .map((filePath) => relative(resolvedPath, filePath))
75
+ .filter((filePath) => options?.recursive || !filePath.includes(sep))
76
+ .sort();
77
+ }
78
+ async mkdir(path, options) {
79
+ const resolvedPath = this.#resolvePath(path);
80
+ if (options?.recursive) {
81
+ let current = resolvedPath;
82
+ const pending = [];
83
+ while (current !== this.#cwd && !this.#directories.has(current)) {
84
+ pending.push(current);
85
+ current = dirname(current);
86
+ }
87
+ for (const directory of pending.reverse()) {
88
+ this.#directories.add(directory);
89
+ }
90
+ return;
91
+ }
92
+ if (!this.#directories.has(dirname(resolvedPath))) {
93
+ throw new Error(`Parent directory does not exist: ${path}`);
94
+ }
95
+ this.#directories.add(resolvedPath);
96
+ }
97
+ async remove(path, options) {
98
+ const resolvedPath = this.#resolvePath(path, false);
99
+ const prefix = `${resolvedPath}${sep}`;
100
+ const descendants = [...this.#files.keys(), ...this.#directories, ...this.#symlinks.keys()]
101
+ .filter((entry) => entry.startsWith(prefix));
102
+ if (descendants.length > 0 && !options?.recursive) {
103
+ throw new Error(`Directory is not empty: ${path}`);
104
+ }
105
+ this.#files.delete(resolvedPath);
106
+ this.#directories.delete(resolvedPath);
107
+ this.#symlinks.delete(resolvedPath);
108
+ if (options?.recursive) {
109
+ for (const entry of descendants) {
110
+ this.#files.delete(entry);
111
+ this.#directories.delete(entry);
112
+ this.#symlinks.delete(entry);
113
+ }
114
+ }
115
+ }
116
+ addSymlink(path, target) {
117
+ const linkPath = this.#resolvePath(path, false, false);
118
+ const targetPath = isAbsolute(target) ? resolve(target) : resolve(dirname(linkPath), target);
119
+ this.#symlinks.set(linkPath, targetPath);
120
+ }
121
+ #normalizeExecOptions(options) {
122
+ if (!options) {
123
+ return undefined;
124
+ }
125
+ const normalized = {};
126
+ if (options.cwd !== undefined)
127
+ normalized.cwd = this.#resolvePath(options.cwd);
128
+ if (options.signal !== undefined)
129
+ normalized.signal = options.signal;
130
+ if (options.timeout !== undefined)
131
+ normalized.timeout = options.timeout;
132
+ return normalized;
133
+ }
134
+ #normalizeShellOptions(options) {
135
+ const normalized = this.#normalizeExecOptions(options);
136
+ if (!options?.env) {
137
+ return normalized;
138
+ }
139
+ return { ...normalized, env: { ...options.env } };
140
+ }
141
+ async #run(handler, options) {
142
+ if ((!options?.timeout || options.timeout <= 0) && !options?.signal) {
143
+ return handler();
144
+ }
145
+ let timeout;
146
+ let abortListener;
147
+ const cancellation = new Promise((resolveCancellation) => {
148
+ if (options?.timeout && options.timeout > 0) {
149
+ timeout = setTimeout(() => resolveCancellation(this.#killedResult()), options.timeout);
150
+ }
151
+ if (options?.signal) {
152
+ abortListener = () => resolveCancellation(this.#killedResult());
153
+ options.signal.addEventListener('abort', abortListener, { once: true });
154
+ }
155
+ });
156
+ try {
157
+ return await Promise.race([handler(), cancellation]);
158
+ }
159
+ finally {
160
+ if (timeout)
161
+ clearTimeout(timeout);
162
+ if (abortListener && options?.signal) {
163
+ options.signal.removeEventListener('abort', abortListener);
164
+ }
165
+ }
166
+ }
167
+ #killedResult() {
168
+ return { stdout: '', stderr: '', code: 143, killed: true };
169
+ }
170
+ #resolvePath(path, allowRoot = true, followSymlinks = true) {
171
+ if (path.includes('\0')) {
172
+ throw new Error('Paths cannot contain NUL bytes');
173
+ }
174
+ let resolvedPath = isAbsolute(path) ? resolve(path) : resolve(this.#cwd, path);
175
+ this.#assertContained(resolvedPath, allowRoot);
176
+ if (followSymlinks) {
177
+ const relativePath = relative(this.#cwd, resolvedPath);
178
+ const segments = relativePath === '' ? [] : relativePath.split(sep);
179
+ let current = this.#cwd;
180
+ for (let index = 0; index < segments.length; index += 1) {
181
+ current = resolve(current, segments[index]);
182
+ const target = this.#symlinks.get(current);
183
+ if (target) {
184
+ resolvedPath = resolve(target, ...segments.slice(index + 1));
185
+ this.#assertContained(resolvedPath, allowRoot);
186
+ break;
187
+ }
188
+ }
189
+ }
190
+ return resolvedPath;
191
+ }
192
+ #assertContained(path, allowRoot) {
193
+ const relativePath = relative(this.#cwd, path);
194
+ const contained = relativePath === '' || (!relativePath.startsWith(`..${sep}`) && relativePath !== '..' && !isAbsolute(relativePath));
195
+ if (!contained) {
196
+ throw new Error(`Path escapes runtime cwd: ${path}`);
197
+ }
198
+ if (!allowRoot && relativePath === '') {
199
+ throw new Error('The runtime cwd cannot be modified or removed');
200
+ }
201
+ }
202
+ }
203
+ //# sourceMappingURL=test-agent-runtime.js.map