// Model-facing tool descriptions per edit mode (adapted from oh-my-pi's crates/pi-edit/prompts). export const HASHLINE = `Patch existing files with hashline anchors (new files: \`write\`). Each file section starts with \`[PATH#TAG]\` — TAG is the required 4-hex snapshot from the latest \`read\`/\`grep\`/\`edit\` output for that file. Line numbers are the original \`LINE:TEXT\` numbers of that snapshot, never shifted by earlier hunks in the same call. \`PUT N.=M:\` replace inclusive lines N–M with the \`+\` body (\`N.=N\` for one line); \`PUT N*:\` replace the block opening on line N. \`PUT N:\` insert before/after line N (\`<1\` = file head, \`>$\` = tail). \`PUT >N*:\` insert after the block opening at N (sibling depth); to insert inside a block use \`PUT N @name\` paste at a gap (omit the name for the anonymous CUT of this call); \`PUT N.=M @name\` / \`PUT N* @name\` paste over a range/block (name REQUIRED). Register pastes have NO body; named registers persist across calls. \`REM\` delete the file; \`MV DEST\` rename it after the section's edits (quote paths with spaces). - Only \`:\` ops take a body: rows are \`+TEXT\` verbatim including indentation; a lone \`+\` is a blank line. Literal \`- item\`/\`+ item\` → \`+- item\`/\`++ item\`. NEVER \`-\` rows or bare context lines. Body length is independent of the range; delete with CUT, not an empty PUT. - Touch only lines you have seen; truncated/omitted lines are UNSEEN — read them first. Keep ranges tight: split non-adjacent changes into separate ops; never include unchanged keepers or start/end mid-expression. Pure additions use a gap PUT. - \`*\` needs a multi-line opener (function/class/heading/object line), NEVER a closer, blank line or inner statement; for one statement use a range. Anchor the first decorator/attribute/doc-comment to include it. - Markdown: a heading block runs through deeper headings until the next same/higher heading; after a section \`PUT >N*:\` end the body with a blank line. - NEVER restyle unrelated code. Tags and numbers change after every edit: use the \`[PATH#TAG]\` and preview in the edit response, or re-read. On a stale tag or surprise, STOP and re-read. [greet.py#A1B2] PUT 1*: +@cache +def greet(name): + print(name) [PLAN.md#3C4D] PUT >2: +- task Cross-file move: \`CUT 1* @fn\` in the source section, then \`PUT <1 @fn\` in the destination section.` export const REPLACE = `Edit an existing UTF-8 text file by string replacement, with fuzzy whitespace matching (indentation, trailing spaces, smart quotes). - Use the smallest \`old_string\` that uniquely identifies the change; if it is not unique, add surrounding context or set \`replace_all\`. - Several changes to the same file: pass \`edits\` (array of {old_string, new_string, replace_all?}); they apply atomically against the original text. - You MUST read the file in this conversation before editing it. Use \`write\` for new files.` export const SLOPPY = `Anchored edit patch: Find quotes existing text; Replace replaces it; Insert Before/Insert After add lines without replacing it. - \`*** Edit File: path\` opens a file; a bare \`*** Edit File:\` continues it. Repeat for more files; all edits apply atomically. Append \` all\` to the opener to change every match. - \`*** Find\` MUST match once unless \`all\`. Copy exact text/indentation from the latest read. Use the smallest unique anchor; if ambiguous, add parent context. - Follow each Find with exactly one of \`*** Replace\` (complete final text; empty deletes), \`*** Insert Before\`, \`*** Insert After\`. Inserts keep the match. - Headers stand alone; bodies are raw lines until the next header — no \`+\`/\`-\` prefixes, no \`@@\` hunks, no closing line. Edits address the original file. - In Find, \`…\` captures omitted text (mid-line gaps stay on the line; a gap at line end spans lines). Each \`…\` in Replace re-emits the next capture. - Failure applies nothing: fix and resend the whole payload. *** Edit File: src/util.ts *** Find const helper = () => 1; *** Replace const helper = () => 2; *** Find run(target); *** Insert Before log(target); ` export const APPLY_PATCH = `Edit files with a stripped-down, file-oriented diff (apply_patch format). Envelope: *** Begin Patch [ one or more file sections ] *** End Patch \`*** Add File: \` create a file; every following line starts with \`+\`. \`*** Delete File: \` remove a file; nothing follows. \`*** Update File: \` patch in place; optional \`*** Move to: \`; then one or more hunks. A hunk starts with \`@@\` (optionally \`@@ \` to scope it; repeat \`@@\` lines to narrow further) followed by lines prefixed with space (context), \`-\` (remove) or \`+\` (add). Use 3 lines of context before and after each change; don't repeat context between adjacent changes. \`*** End of File\` anchors a hunk at EOF. Example: *** Begin Patch *** Update File: src/app.py @@ def main(): args = parse() - run(args) + run(args, verbose=True) *** Add File: src/new.py +print("hi") *** End Patch` export const READ_HASHLINE_NOTE = ' Output is `[PATH#TAG]` followed by `LINE:TEXT` rows; copy that header and the line numbers into `edit`.' export const GREP_HASHLINE_NOTE = ' Matches are grouped under `[PATH#TAG]` headers with `LINE:TEXT` rows usable as `edit` anchors.'