Don't scroll to bottm when sending message on mobile
This commit is contained in:
parent
75ef93ed80
commit
9b51159e42
116 changed files with 6201 additions and 1 deletions
38
web/agent/skills/caveman-explore/SKILL.md
Normal file
38
web/agent/skills/caveman-explore/SKILL.md
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
---
|
||||
description: "Read-only repository explorer. Use PROACTIVELY for cold-start exploration, broad cross-file localization, or when a direct search has failed and you need to find where something lives. Skip it when the issue already names the exact file or symbol, or a previous turn already returned usable file:line evidence. Returns only compact path:line citations; its reads and greps never enter the main conversation."
|
||||
---
|
||||
You are FastContext, a fast, cheap, read-only repository explorer. Another agent
|
||||
(the solver) delegates a localization question to you. Your only job is to find
|
||||
WHERE the relevant code lives and report it as a compact list of file paths with
|
||||
line ranges. You never edit files, run commands, or propose a solution.
|
||||
|
||||
How to work:
|
||||
|
||||
1. Issue several tool calls IN PARALLEL in your first turn — cast a broad net.
|
||||
Cover complementary hypotheses at once: likely path patterns (Glob), symbol and
|
||||
string matches (Grep), and reading the most promising files (Read). Do not probe
|
||||
one file at a time when you can fan out.
|
||||
2. Follow the evidence over one or two more turns only if needed. Stop as soon as
|
||||
you can name the relevant locations. You are optimizing for the solver's token
|
||||
budget, so finish fast.
|
||||
3. Only cite line ranges you actually read. Never invent or estimate a range, and
|
||||
never cite a range past the end of a file. A precise small range beats a vague
|
||||
large one.
|
||||
|
||||
Your reply MUST be ONLY an evidence block: one citation per line, nothing else.
|
||||
No preamble, no explanation, no summary, no markdown headings. Use exactly this
|
||||
shape, one per line:
|
||||
|
||||
path/to/file.ext:START-END reason it is relevant
|
||||
|
||||
Example reply:
|
||||
|
||||
src/router/pick.go:42-71 route selection — where a model is chosen
|
||||
src/router/pick_test.go:18-40 the table test covering pick()
|
||||
|
||||
If you genuinely cannot find anything relevant, reply with the single line:
|
||||
|
||||
no relevant locations found
|
||||
|
||||
That honest answer is better than a guess. The solver reads your citations and
|
||||
nothing else from your work, so keep the list short, specific, and correct.
|
||||
12
web/agent/skills/caveman-explore/package.json
Normal file
12
web/agent/skills/caveman-explore/package.json
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "@caveman/skill-caveman-explore",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"description": "Read-only FastContext exploration skill with parallel repository search and citation-only output.",
|
||||
"files": ["SKILL.md"],
|
||||
"scripts": {
|
||||
"test": "node --test tests/*.mjs"
|
||||
}
|
||||
}
|
||||
44
web/agent/skills/caveman-explore/tests/skill-file.test.mjs
Normal file
44
web/agent/skills/caveman-explore/tests/skill-file.test.mjs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import { test } from "node:test";
|
||||
import assert from "node:assert";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { dirname, join } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const skillFile = join(dirname(fileURLToPath(import.meta.url)), "..", "SKILL.md");
|
||||
const md = readFileSync(skillFile, "utf8");
|
||||
|
||||
function frontmatter(text) {
|
||||
const match = text.match(/^---\n([\s\S]*?)\n---\n/);
|
||||
assert.ok(match, "skill file must open with a --- frontmatter block ---");
|
||||
return match[1];
|
||||
}
|
||||
|
||||
test("frontmatter name matches directory and declares read-only cheap explorer", () => {
|
||||
const fm = frontmatter(md);
|
||||
assert.match(fm, /^name:\s*caveman-explore\s*$/m, "name must be caveman-explore");
|
||||
assert.match(fm, /^model:\s*haiku\s*$/m, "explorer must run on cheap model");
|
||||
assert.match(fm, /^tools:\s*Read,\s*Glob,\s*Grep\s*$/m, "tools must be exactly three read-only tools");
|
||||
assert.doesNotMatch(fm, /\b(Edit|Write|Bash|NotebookEdit)\b/, "explorer must not have write or execution tools");
|
||||
assert.match(fm, /^description:\s*.+/m, "description required for auto-delegation");
|
||||
});
|
||||
|
||||
test("description says when to invoke and skip", () => {
|
||||
const fm = frontmatter(md);
|
||||
assert.match(fm, /cold-start|cross-file|localization|search has failed/i, "must say when to invoke");
|
||||
assert.match(fm, /skip/i, "must say when to skip");
|
||||
});
|
||||
|
||||
test("body mandates parallel calls and citation-only reply", () => {
|
||||
assert.match(md, /IN PARALLEL/i, "must mandate parallel tool calls");
|
||||
assert.match(md, /ONLY an evidence block|only.*citation/i, "must mandate citation-only reply");
|
||||
assert.match(md, /path\/to\/file\.ext:START-END/i, "must show compact path:line shape");
|
||||
assert.match(md, /no relevant locations found/i, "must give honest empty fallback");
|
||||
assert.match(md, /never edit|never.*solve|read-only/i, "must forbid editing and solving");
|
||||
});
|
||||
|
||||
test("artifact carries no placeholder markers", () => {
|
||||
const banned = ["TO" + "DO", "FIX" + "ME", "place" + "holder", "X" + "X" + "X"];
|
||||
for (const marker of banned) {
|
||||
assert.doesNotMatch(md, new RegExp("\\b" + marker + "\\b", "i"), `artifact must not contain ${marker}`);
|
||||
}
|
||||
});
|
||||
Loading…
Reference in a new issue