Skip to content
Agentmart
Submit a tool

lineage

Answer "why does this line exist?" — trace a file, or a specific line, back to the change, prompt, agent, and session that produced it.

Skill by onlooker-community

IndexedMIT
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/onlooker-community-lineage

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Answer "why does this line exist?" — trace a file, or a specific line, back to the change, prompt, agent, and session that produced it. Reads lineage's per-project change ledger and joins it to the transcripts historian preserves. Modes — /lineage <file> (change history), /lineage <file>:<line> or --line N (single-line provenance), /lineage <file> --grep <text> (content search), /lineage --status (ledger stats). Use when the user asks who/what/why introduced code in a file, or invokes /lineage.

Use cases: writing, agent-building

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/lineage

What's inside

Skill name
lineage
Description
Answer "why does this line exist?" — trace a file, or a specific line, back to the change, prompt, agent, and session that produced it. Reads lineage's per-project change ledger and joins it to the transcripts historian preserves. Modes — /lineage <file> (change history), /lineage <file>:<line> or --line N (single-line provenance), /lineage <file> --grep <text> (content search), /lineage --status (ledger stats). Use when the user asks who/what/why introduced code in a file, or invokes /lineage.
License
MIT
Instructions
179 lines in SKILL.md · view on GitHub

Files (1)

  • SKILL.md

SKILL.md (first lines)

# Lineage Skill

`/lineage` reads the per-project change ledger that the PostToolUse hook records
and resolves each change's originating prompt by joining to historian's durable
session transcripts (falling back to the live transcript). It answers
"why does this line exist?" without an LLM call — pure read, join, and render.

## Setup

Run once. Sources the plugin helpers, loads config, and resolves project context.

```bash
set -uo pipefail
PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}"
export CLAUDE_PLUGIN_ROOT="$PLUGIN_ROOT"

source "$PLUGIN_ROOT/scripts/lib/portable-lock.sh"
source "$PLUGIN_ROOT/scripts/lib/lineage-config.sh"
source "$PLUGIN_ROOT/scripts/lib/lineage-events.sh"
source "$PLUGIN_ROOT/scripts/lib/onlooker-project-key.sh"
source "$PLUGIN_ROOT/scripts/lib/lineage-redact.sh"
source "$PLUGIN_ROOT/scripts/lib/lineage-record.sh"
source "$PLUGIN_ROOT/scripts/lib/lineage-query.sh"

REPO_ROOT=$(onlooker_project_repo_root "$(pwd)")
lineage_config_load "$REPO_ROOT"

PROJECT_KEY=$(onlooker_project_key "$(pwd)")
if [[ -z "$PROJECT_KEY" ]]; then
  echo "No project key — lineage needs a git repository (remote or root) to scope its ledger."
  exit 0
fi
PROMPT_SOURCE=$(lineage_config_prompt_source)
QSID="${CLAUDE_SESSION_ID:-lineage-query}"
```

## Invocation Modes

### `/lineage <file>` — change history (default)

Set `FILE` to the path the user named, then run. (Repo-relative paths are
resolved against the repo root.)

```bash
FILE="REPLACE_WITH_FILE"
[[ "$FILE" != /* && -n "$REPO_ROOT" ]] && FILE="$REPO_ROOT/$FILE"
# Match the spelling the ledger stores. The lookup is an exact string compare,
# and the hook resolves every path it records, so a symlinked checkout would
# otherwise find nothing (ecosystem-htl).
FILE=$(lineage_resolve_path "$FILE")

echo "## Lineage — change history for \`$FILE\`"
count=0
while IFS= read -r rec; do
  [[ -z "$rec" ]] && continue
  count=$((count + 1))
  ts=$(jq -r '.ts' <<<"$rec"); sid=$(jq -r '.session_id' <<<"$rec")
  turn=$(jq -r '.turn // ""' <<<"$rec"); tool=$(jq -r '.tool' <<<"$rec")
  la=$(jq -r '.lines_added' <<<"$rec"); lr=$(jq -r '.lines_removed' <<<"$rec")
  tp=$(jq -r '.transcript_path // ""' <<<"$rec")
  # How much of the change this record's content actually covers. Carried in
  # the header because a list of changes is scanned, not read.
  scope=$(lineage_scope_kind "$(jq -r '.content_scope // ""' <<<"$rec")" "$tool")
  resolved=$(lineage_resolve_prompt "$PROJECT_KEY" "$sid" "$turn" "$tp" "$PROMPT_SOURCE")
  prompt=$(jq -r '.prompt' <<<"$resolved"); via=$(jq -r '.resolved_via' <<<"$resolved")
  echo ""
  echo "### ${ts} · ${tool} (+${la}/-${lr}) · scope ${scope} · session ${sid}${turn:+ · turn ${turn}}"
  if [[ -n "$prompt" ]]; then
    echo "Prompt context (${via}):"; echo ""
    printf '%s\n' "$prompt" | head -c 600 | sed 's/^/> /'
  else
    echo "_Prompt unavailable (${via})._"
  fi
done < <(lineage_changes_for_file "$PROJECT_KEY" "$FILE")
[[ "$count" -eq 0 ]] && { echo ""; echo "No recorded changes for this file (it may predate lineage)."; }

lineage_emit_event "lineage.query.answered" \
  "$(jq -nc --arg pk "$PROJECT_KEY" --arg f "$FILE" --argjson m "$count" \
     '{project_key:$pk, file_path:$f, matches:$m}')" "$QSID" || true
```

### `/lineage <file>:<line>` (or `--line N`) — single-line provenance

Set `FILE` and `LINE`, then run. Reads the current line's text and content-anchors
it to the change that introduced it.

```bash
FILE="REPLACE_WITH_FILE"; LINE="REPLACE_WITH_LINE_NUMBER"
[[ "$FILE" != /* && -n "$REPO_ROOT" ]] && FILE="$REPO_ROOT/$FILE"
# Match the spelling the ledger stores. The lookup is an exact string compare,
# and the hook resolves every path it records, so a symlinked checkout would
# otherwise find nothing (ecosystem-htl).
FILE=$(lineage_resolve_path "$FILE")

line_text=$(sed -n "${LINE}p" "$FILE" 2>/dev/null)
needle=$(printf '%s' "$line_text" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')

echo "## Lineage — why does \`$FILE\`:${LINE} exist?"
echo ""
echo "Line ${LINE}: \`${line_text}\`"

rec=$(lineage_match_line "$PROJECT_KEY" "$FILE" "$needle")
via="none"; matches=0
if [[ -z "$rec" ]]; then
  echo ""
  echo "No recorded change introduced this content (it may predate lineage, or the line moved since it was written)."
else
  matches=1
  ts=$(jq -r '.ts' <<<"$rec"); sid=$(jq -r '.session_id' <<<"$rec")
  turn=$(jq -r '.turn // ""' <<<"$rec"); tool=$(jq -r '.tool' <<<"$rec")
  tp=$(jq -r '.transcript_path // ""' <<<"$rec")
  scope_raw=$(jq -r '.content_scope // ""' <<<"$rec")
  resolved=$(lineage_resolve_prompt "$PROJECT_KEY" "$sid" "$turn" "$tp" "$PROMPT_SOURCE")
  prompt=$(jq -r '.prompt' <<<"$resolved"); via=$(jq -r '.resolved_via' <<<"$resolved")
  echo ""
  echo "Introduced ${ts} by $(lineage_tool_phrase "$tool") in session ${sid}${turn:+ (turn ${turn})}."
  # Always printed. A single-line answer is the one most likely to be quoted
  # back as fact, so it is the one that most needs to say what it is worth.
  echo ""

From onlooker-community/ecosystem, MIT.

Signals

Stars
0
Forks
0
Open issues
0
Last commit (this folder)
Oct 11, 2026 (18 days ago)
Last release
Oct 24, 2026 (5 days ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from onlooker-community

Cite this page

lineage skill. Agent Mart. https://agentmart.dev/skills/onlooker-community-lineage (last updated 2026-10-24)