Don't scroll to bottm when sending message on mobile

This commit is contained in:
天クマ 2026-08-18 06:49:34 -03:00
commit 9b51159e42
116 changed files with 6201 additions and 1 deletions

View 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.

View 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"
}
}

View 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}`);
}
});