Back to Skills
juliusbrussee/cavemanCheck passed

SKILL DETAIL

caveman-explore

juliusbrussee/caveman/caveman-explore

caveman-explore is a read-only repository explorer designed for cold-start exploration, cross-file localization, or when a direct search has failed. It works by issuing several tool calls in parallel (such as Glob, Grep, and Read) to quickly find relevant code, and returns only compact path:line citations without entering the main conversation. This tool is ideal for scenarios where you need to quickly find where code lives without deep understanding, such as when the issue does not specify the exact file or symbol. It emphasizes speed and efficiency, avoiding unnecessary exploration, and honestly reports when no relevant locations are found.

Installs · 1,009View source

Installation

npx skills add https://github.com/juliusbrussee/caveman --skill caveman-explore

Skill files

SKILL.md

Last synced · Aug 29, 2026

package.json
{
  "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 --test-force-exit tests/*.mjs"
  }
}
SKILL.md
---
name: caveman-explore
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.
tools: Read, Glob, Grep
model: haiku
---

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.
tests/skill-file.test.mjs
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}`);
  }
});