UNPKG

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.

145 lines 11 kB
/** * The system prompt (#326), verbatim, as a template. It supersedes the * anti-lazy-pill (#297/#301) it grew out of: the prompt is analyzed first — an * ambiguous one becomes a ranked `showChoices()` list, a * large scope becomes a PLAN file to approve, a very large one also spins off a TODO * backlog (consumed by the backlog loop, #323), the work moves onto its own * `tf-<session>` branch before the first change, and the alternatives flow * rates problem "variability" before code is written. * * Two layers make it executable: * - `${{ ... }}` fragments are JS evaluated against a {@link TfContext} (#350). * - The trailing `# User prompt` section is the user-prompt slot; use * {@link renderSystemPrompt} to render and split the two halves. * * The `<SHOW_*>` / `<AWAIT>` macros are interpreted by the agent itself (Rom's * call on #326); the await protocol (#337/#339) pins how the stop-signal is * emitted so the turn-boundary gates can detect it. * * The text lives in `prompts/system_prompt.md` (#551), not here. It is Rom's living * doc: change it on #326 first, then sync the markdown. */ export declare const SYSTEM_PROMPT_TEMPLATE = "# System prompt\n\nSHOW_MD: Show it via `showMarkdown()`\nSHOW_CHOICES: Show it via `showChoices()`\nAWAIT: Stop, await user answer before resuming\nSESSION_NAME: the name of the session\nTODO_FILE: `TODO_AGENTS.md`\n\n## Analyze the user prompt\n\nAnalyze the user prompt and follow the instructions below.\n\n### Ambiguous prompt\n\nIf it isn't clear what you should do (e.g. unclear scope, unclear user prompt), make a list of interpretations sorted by plausibility, <SHOW_CHOICES>, <AWAIT>\n\n### Scope\n\n- If the scope of what you'll work on is *large*, create a `PLAN_<SESSION_NAME>.agent.md` of what you'll work on, <SHOW_MD>, <AWAIT>\n- If the scope is potentially *very large* (e.g. spans over many hours/days of work), consider adding entries to <TODO_FILE> (backlog of follow-up tasks) and show new entries <SHOW_MD>\n\n\n## Before starting changes\n\nDo the following before applying your first change.\n\n### Workspace\n\nYour working directory is the whole of your workspace. Every file you read or write is under it.\n\n- Address files relative to it. An absolute path is how you leave it without noticing\n- It may sit *inside* another checkout of the same repo. That outer copy is the user's own working tree \u2014 not another view of your files, and never yours to edit\n- The same file can therefore exist twice. The one under your working directory is yours; editing the other one puts your work somewhere your branch and your commits cannot reach it\n- If something you need is genuinely outside, say so and stop \u2014 do not reach for it\n\n### Session name\n\n1. Create a <SESSION_NAME> as a string [a-z0-9-]+ that succinctly represents the intention of the user prompt\n2. Create a new branch `tf-<SESSION_NAME>` and `$ git checkout` it \u2014 do all the work in that branch\n3. Call setSessionName(<SESSION_NAME>)\n\n\n## Before applying changes\n\nDo the following before applying changes \u2014 do it again anytime you make new changes.\n\n### Alternatives\n\nMeasure \"variability\":\n- List all high-level problems that you're about to solve\n- Give a rating to each problem (from 0 to 10) following this criteria: is there an obviously optimal way to solve the problem (10), or is it highly unclear whether the problem can be solved in a better way (0)?\n- Explore and suggest alternatives for problems with a low rating\n- For each problem that has alternatives: list all alternatives sorted in a sensible order, <SHOW_CHOICES>, <AWAIT>\n\n\n## After applying changes\n\nAfter you're done, decide: is <SESSION_NAME> finished, with no work left to do?\n- Yes: call setReadyForMerge() \u2014 required, the work is never merged without it\n- No: don't call it; say what's left instead\n\n\n\n# User prompt\n\n${{tf.prompt}}"; /** * The `tf` context the templates' `${{...}}` fragments read (#326/#350). One shape across * the prompts; each reads the subset it needs. `session_name` is the on-before-mergeable * prompt's (#556), and is snake_case because the doc writes it that way. */ export interface TfContext { /** The user's prompt (the session's intent, or the typed prompt): fills `${{tf.prompt}}`. */ prompt: string; /** * The session name the agent set via setSessionName(), carried on session state. Only the * on-before-mergeable prompt reads it, never the system prompt: it is set before the agent makes * changes and read afterwards, so it is not chicken-and-egg. */ session_name?: string | undefined; } /** A project-context document: a repo-root path and the one-line gloss shown beside it (#559). */ export interface ContextDoc { path: string; comment: string; } /** * The business-knowledge docs (#537): what the repo has learned about itself, which the * agent both reads at the start of an agent and folds new knowledge back into at merge. The * on-before-mergeable prompt's `## Business knowledge` section names this exact set, so the * agent is never told to read one set of files and update another (pinned by a test). A * subset of {@link CONTEXT_DOCS}. */ export declare const BUSINESS_KNOWLEDGE_DOCS: readonly ContextDoc[]; /** * Everything the agent keeps in context when it starts (#683), which * {@link systemPromptBlock} renders as the `Context:` bullets. A superset of * {@link BUSINESS_KNOWLEDGE_DOCS}: it adds `GOAL.md`, `BUSINESS_LOGIC.md`, and the * roadmap/queue/history pointers the agent reads but does *not* fold knowledge back into — * `tickets/**.md` (the potential work, whose file shape is the `Ticketing format` spec, #684/#674) * and the `TODO_AGENTS.md` task queue (whose shape is the `TODO_AGENTS.md` spec, #880). Repo-root * paths, because that is the agent's cwd. README is left out: a repo's own `README.md` already * covers the overview. * * The two format-bearing bullets point at {@link CONTEXT_FORMATS}, which travels in the same * channel, rather than at a file the agent has to go and open (#1163). */ export declare const CONTEXT_DOCS: readonly ContextDoc[]; /** The two halves of the rendered {@link SYSTEM_PROMPT_TEMPLATE}. */ export interface RenderedSystemPrompt { /** The `# System prompt` half: frames the session's system channel. */ system: string; /** The `# User prompt` half: the rendered user-prompt slot (`${{tf.prompt}}` plus any framing Rom adds around it). */ user: string; } /** * Render the built-in system prompt against a {@link TfContext} and split it at * the `# User prompt` heading. The split happens on the *template*, before * rendering, so a user prompt that itself contains the heading can never move * the boundary. */ export declare function renderSystemPrompt(tf?: TfContext): RenderedSystemPrompt; /** Inputs to {@link systemPromptBlock}. */ export interface SystemPromptOptions { /** Remove the built-in #326 system prompt. Default `false` — it is included. */ vanilla?: boolean | undefined; /** The user's own system prompt (e.g. from `SYSTEM.md`), injected after the built-in one. */ user?: string | undefined; /** Context for the template's `${{...}}` fragments. Default: {@link DEFAULT_TF}. */ tf?: TfContext | undefined; /** * Directories the user picked as in-context (#439/#314). The agent can reach every * registered repo, so this narrows its focus: it prepends one `Context: <dirs>` line to * the block. Empty/absent adds nothing. */ context?: readonly string[] | undefined; /** * Transparent mode (#625): drop *everything* framework-authored from the system channel — * the built-in prompt, the knowledge docs, AND the emit protocols — so the agent receives an * empty system channel, byte-identical to raw `claude -p <prompt>`. This is stronger than * `--vanilla` (which keeps the AWAIT/SIGNAL emit contract so the agent can still drive the * dashboard's gates); transparent means there is no framework behavior left to signal to. * Short-circuits {@link composeAgentSystem}, so it overrides every other option here. */ transparent?: boolean | undefined; /** * This agent has a real browser attached (#824). Adds the section telling the agent so: the * tools are wired through MCP, which the agent discovers, but nothing otherwise says to prefer * them — so it reaches for `WebFetch`, and the browser (and its preview) sits unused. */ browser?: boolean | undefined; /** * This agent hands off to a remote session nothing local can steer (#1231), so the await gates * are not available in it (#1234). Appends {@link HANDS_OFF_PROTOCOL} right after the await * protocol it amends, so an ambiguous prompt takes its most plausible reading and says so, * instead of parking a cloud session forever on a question nobody attached can answer. */ handsOff?: boolean | undefined; } /** * Compose the system-prompt block injected into every prompt: the built-in #326 * prompt (unless removed) followed by the user's own prompt. Additive, so a repo * can keep the built-in *and* add its instructions, remove it and keep only its * own, or leave both off. Returns `''` when there is nothing to inject. Only the * template's system half lands here; the user-prompt half is the caller's to * deliver (see {@link renderSystemPrompt}). */ export declare function systemPromptBlock(opts?: SystemPromptOptions): string; /** Inputs to {@link composeAgentSystem}. */ export type AgentSystemOptions = SystemPromptOptions; /** * Assemble an agent's full system channel — the single place it is composed (#501), so the * build path and the direct-prompt path, before D2 collapsed them into one {@link runAgent} * cannot drift. That drift is exactly what dropped the session-action (#326) layer from `--vanilla` * builds (#500): the two sites each inlined the composition and one nested the protocols * inside the built-in-prompt branch. * * Order is fixed: the built-in system prompt (#326) block (context / built-in prompt / user SYSTEM.md) * first, then the emit protocols. Nothing else is appended — a build agent's system channel * is exactly this (#547), which is what lets the dashboard show the whole prompt before an agent * starts (#520). The protocols are otherwise unconditional — they are the *emit contract* (how * the agent signals an awaited choice and the setSessionName()/setReadyForMerge() lifecycle), * not prompt content — so the agent needs them even with the built-in prompt off (`--vanilla`). * * The one exception is transparent mode (#625): there is no framework behavior to signal to, so * the whole channel is empty and the agent runs as raw `claude -p`. */ export declare function composeAgentSystem(opts?: AgentSystemOptions): string; //# sourceMappingURL=system-prompt.d.ts.map