83 lines
5.4 KiB
JavaScript
83 lines
5.4 KiB
JavaScript
// 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.
|
||
|
||
<ops>
|
||
\`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:\` / \`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 <M:\` at its closer.
|
||
\`CUT N.=M\` / \`CUT N*\` delete and capture, optionally into \`@name\`.
|
||
\`PUT <N @name\` / \`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).
|
||
</ops>
|
||
|
||
<rules>
|
||
- 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.
|
||
</rules>
|
||
|
||
<example>
|
||
[greet.py#A1B2]
|
||
PUT 1*:
|
||
+@cache
|
||
+def greet(name):
|
||
+ print(name)
|
||
[PLAN.md#3C4D]
|
||
PUT >2:
|
||
+- task
|
||
</example>
|
||
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.
|
||
|
||
<ops>
|
||
- \`*** 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.
|
||
</ops>
|
||
|
||
<example>
|
||
*** Edit File: src/util.ts
|
||
*** Find
|
||
const helper = () => 1;
|
||
*** Replace
|
||
const helper = () => 2;
|
||
*** Find
|
||
run(target);
|
||
*** Insert Before
|
||
log(target);
|
||
</example>`
|
||
|
||
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: <path>\` create a file; every following line starts with \`+\`.
|
||
\`*** Delete File: <path>\` remove a file; nothing follows.
|
||
\`*** Update File: <path>\` patch in place; optional \`*** Move to: <new path>\`; then one or more hunks. A hunk starts with \`@@\` (optionally \`@@ <class/function line>\` 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.'
|