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.
94 lines • 5.04 kB
TypeScript
import { type GitRunner } from './project.js';
import { DATA_BRANCH } from './branch-names.js';
export { DATA_BRANCH };
/** The data branch's checkout under a project: `<repo>/.the-framework/branches/tf-data`. */
export declare function dataWorktreePath(cwd: string): string;
/** Injectable seams; production takes the defaults. */
export interface DataBranchDeps {
git?: GitRunner;
/** Write one file, creating parents (default `node:fs/promises`). */
write?: (path: string, content: string) => Promise<void>;
/** Whether anything (file, dir, or dangling link) sits at `path` (default `fs.lstat`). */
lexists?: (path: string) => Promise<boolean>;
/** Create a symlink at `path` to `target` (default `node:fs/promises`). */
symlink?: (target: string, path: string) => Promise<void>;
log?: (message: string) => void;
}
/**
* Make sure the data branch and its checkout exist, the queue file is seeded, and the root
* `tickets` symlink points into the checkout. Idempotent and cheap when everything is in place
* (one `git rev-parse` against the checkout); never throws — a project this cannot be set up in
* reports why and is left alone.
*/
export declare function ensureDataWorktree(cwd: string, deps?: DataBranchDeps): Promise<{
ok: boolean;
error?: string;
}>;
/**
* What one funneled write did. `changed: false` is the clean no-op (the op wrote nothing new).
* A failure says whether the change still landed as a local commit (`committed` — the push is
* what failed, and the next cycle carries it out) or nothing survived at all.
*/
export type DataWriteResult = {
ok: true;
changed: boolean;
pushed: boolean;
} | {
ok: false;
committed: boolean;
error: string;
};
/**
* Apply one change to the data branch: sync with origin, run `op` against the checkout, commit
* whatever it changed, push. The single funnel every local data write goes through (#1582).
*
* `op` must be re-runnable: when the push loses a race with another machine, the cycle re-syncs
* and runs it again against the fresher state rather than force-fitting a stale commit — the op
* *is* the intent, the commit is just its serialization. Two attempts; a push that still fails
* (the network, most likely) keeps the commit local and reports the error — the next cycle's sync
* rebases it onto whatever origin has by then, and the next push carries it.
*
* Never throws: callers run on background ticks with nothing to catch it.
*/
export declare function withDataBranch(cwd: string, message: string | (() => string), op: (dataDir: string) => Promise<void>, deps?: DataBranchDeps): Promise<DataWriteResult>;
/** How a sync went: converged with origin, or why it could not. */
export type DataSyncResult = {
ok: true;
} | {
ok: false;
error: string;
};
/**
* The eager pull (#1582): sync the checkout with origin so this machine reads what other machines
* and cloud sessions committed, without waiting for the next local write — and push anything a
* failed cycle left stranded locally, via the same owed-push rule as the writer. Ensures the
* checkout exists, so a fresh clone converges on its first tick. Never throws.
*
* Reports why it could not converge (#1599): a push origin rejects, or no origin to converge with
* at all. The writer treats a remote-less repo as fine — the commit is safe locally — but a sync's
* whole job is to meet the other machines, and a repo nothing can reach is an error state the user
* has to fix, not a mode the framework supports (#1595). The daemon records the answer as the
* project's error state, so it reaches the dashboard rather than only the daemon's stdout.
*/
export declare function pullDataBranch(cwd: string, deps?: DataBranchDeps): Promise<DataSyncResult>;
/**
* The project root `cwd` belongs to: the directory holding the repo's real `.git`. From the main
* checkout that is `cwd` itself; from an agent's worktree it is the repo the worktree was made
* from — where the data checkout lives, and the address every data write funnels to. `undefined`
* outside any repo.
*/
export declare function dataProjectRoot(cwd: string, git?: GitRunner): Promise<string | undefined>;
/**
* Read one file off the data branch, from anywhere in the repo: the checkout when this `cwd` has
* one, else `git show` against the local branch (worktrees share the repo's refs, so an agent's
* checkout reads the same data without holding any of it), else against `origin/…` (a fresh
* clone that fetched but never branched — the cloud case). `undefined` when the file exists in
* none of them. Never throws.
*
* `fresh: true` fetches first and prefers origin's copy — for a reader about to act on the queue
* from a long-lived agent process, where the local ref may trail what other writers pushed.
*/
export declare function readDataFile(cwd: string, rel: string, opts?: {
fresh?: boolean;
}, deps?: DataBranchDeps): Promise<string | undefined>;
//# sourceMappingURL=data-branch.d.ts.map