framework
Version:
The (AI) Framework: turnkey, zero-config AI orchestration that wraps a coding-agent CLI (Claude Code) as a black box and takes you from an idea to a running app. Vite for AI.
73 lines • 2.69 kB
JavaScript
import { makeEmit } from './session-support.js';
function asTurn(value) {
return typeof value === 'string' ? { text: value } : value;
}
/**
* An in-memory {@link Driver} for tests and `FRAMEWORK_FAKE` runs: it never spawns a
* process, replays scripted turns deterministically, and emits the same
* {@link DriverEvent} shape a real driver does. Mirrors `AiFake` /
* `FakeRunner`, so the whole flow runs offline with no CLI and no model.
*/
export class FakeDriver {
opts;
id = 'fake';
constructor(opts = {}) {
this.opts = opts;
}
// Narrowed to the concrete session so callers can read `prompts` for assertions.
start(opts) {
return Promise.resolve(new FakeDriverSession(this.opts, opts));
}
}
/** A single {@link FakeDriver} session. Records every prompt for assertions. */
export class FakeDriverSession {
config;
startOpts;
id;
cwd;
/** Every prompt this session received, in order. */
prompts = [];
index = 0;
constructor(config, startOpts) {
this.config = config;
this.startOpts = startOpts;
this.id = config.sessionId ?? 'fake-session';
this.cwd = startOpts.cwd;
}
prompt(text, opts = {}) {
if (this.startOpts.signal?.aborted || opts.signal?.aborted) {
return Promise.reject(new Error('[framework] fake prompt aborted'));
}
const i = this.index++;
this.prompts.push(text);
const turn = this.resolveTurn(text, i);
this.emit({ type: 'start', prompt: text });
for (const label of turn.actions ?? [])
this.emit({ type: 'action', label });
if (turn.text)
this.emit({ type: 'text', text: turn.text });
this.emit({ type: 'result', text: turn.text, sessionId: this.id, ...(turn.usage ? { usage: turn.usage } : {}) });
return Promise.resolve({ text: turn.text, sessionId: this.id, ...(turn.usage ? { usage: turn.usage } : {}) });
}
readCode(path) {
const contents = this.config.files?.[path];
if (contents === undefined)
return Promise.reject(new Error(`[framework] fake driver has no file ${path}`));
return Promise.resolve(contents);
}
dispose() {
return Promise.resolve();
}
resolveTurn(text, i) {
if (this.config.respond)
return asTurn(this.config.respond(text, i));
const turns = this.config.turns ?? [];
if (turns.length === 0)
return { text: '' };
return turns[Math.min(i, turns.length - 1)];
}
emit(event) {
makeEmit(this.startOpts.onEvent, 'fake driver')(event);
}
}
//# sourceMappingURL=fake.js.map