refactor: extract tmux-launch-agent from implement-issue/setup-skills, overhaul PKM skills

- New common/misc/tmux-launch-agent skill with detect-agent script
  and agents-seed.md (moved from engineering/setup-skills)
- implement-issue simplified: delegates agent dispatch to
  tmux-launch-agent instead of inlining it
- setup-skills stripped of Section E (agent CLI config)
- New in-progress/agent-handoff skill using tmux-launch-agent
- PKM skills simplified: conversation-summary and pkm-curation
  rewritten with leaner process, crit streamlined
- knowledge-gardener removed (moved to common/in-progress/)
- All READMEs updated to match
This commit is contained in:
2026-07-06 11:29:16 -04:00
parent 1614a0d469
commit c92ee69440
13 changed files with 547 additions and 608 deletions
+1 -1
View File
@@ -12,7 +12,7 @@ A collection of agent skills (slash commands and behaviors) loaded into Steve Be
- [implement-issue](common/engineering/implement-issue/SKILL.md) — Dispatch a child agent in an isolated git worktree to implement a ready-for-agent issue end-to-end.
- [improve-codebase-architecture](common/engineering/improve-codebase-architecture/SKILL.md) — Scan a codebase for deepening opportunities, present them as a visual HTML report, then grill through whichever one you pick.
- [knowledge-gardener](common/pkm/knowledge-gardener/SKILL.md) — Run vault-aware semantic search, synthesis, note creation, linking, and Zettelkasten workflows for this Obsidian vault.
- [pkm-curation](common/pkm/pkm-curation/SKILL.md) — Curate an Obsidian-style personal knowledge vault by classifying notes, normalizing frontmatter, improving structure, extracting atomic notes, and adding meaningful wikilinks.
- [pkm-curation](common/pkm/pkm-curation/SKILL.md) — Curate an Obsidian vault — classify notes, normalize frontmatter, add wikilinks, extract atomic notes. Use when curating, batch-processing, reviewing, or doing a serendipity pick.
- [project-context-pack](common/engineering/project-context-pack/SKILL.md) — Build and refresh a bounded repo context memory file so agents use disciplined search instead of repeated browsing.
- [research-vault](common/pkm/research-vault/SKILL.md) — Research a topic through a one-question-at-a-time learning conversation, answer directly, share resources when useful, and save a linked Obsidian research packet.
- [setup-skills](common/engineering/setup-skills/SKILL.md) — Configure this repo for the engineering skills, set up its issue tracker, triage label vocabulary, and domain doc layout.
+1 -1
View File
@@ -11,7 +11,7 @@ Skills that work in all CLI agents.
- [handoff](productivity/handoff/SKILL.md) — Compact the current conversation into a handoff document for another agent to pick up.
- [improve-codebase-architecture](engineering/improve-codebase-architecture/SKILL.md) — Scan a codebase for deepening opportunities, present them as a visual HTML report, then grill through whichever one you pick.
- [knowledge-gardener](pkm/knowledge-gardener/SKILL.md) — Run vault-aware semantic search, synthesis, note creation, linking, and Zettelkasten workflows for this Obsidian vault.
- [pkm-curation](pkm/pkm-curation/SKILL.md) — Curate an Obsidian-style personal knowledge vault by classifying notes, normalizing frontmatter, improving structure, extracting atomic notes, and adding meaningful wikilinks.
- [pkm-curation](pkm/pkm-curation/SKILL.md) — Curate an Obsidian vault — classify notes, normalize frontmatter, add wikilinks, extract atomic notes. Use when curating, batch-processing, reviewing, or doing a serendipity pick.
- [project-context-pack](engineering/project-context-pack/SKILL.md) — Build and refresh a bounded repo context memory file so agents use disciplined search instead of repeated browsing.
- [research-vault](pkm/research-vault/SKILL.md) — Research a topic through a one-question-at-a-time learning conversation, answer directly, share resources when useful, and save a linked Obsidian research packet.
- [setup-skills](engineering/setup-skills/SKILL.md) — Configure this repo for the engineering skills, set up its issue tracker, triage label vocabulary, and domain doc layout.
+26 -178
View File
@@ -1,227 +1,75 @@
---
name: implement-issue
description: Dispatch a child agent in an isolated git worktree to implement a `ready-for-agent` issue end-to-end.
description: "Dispatch a child agent in an isolated git worktree to implement a piece of work based on a PRD or set of issues."
disable-model-invocation: true
---
# Implement Issue
Dispatch a child agent in an isolated git worktree to implement a `ready-for-agent` issue end-to-end — explore, implement with TDD, run the full quality gate, push a branch, create a PR, comment on the issue, and update labels.
The issue tracker conventions live in [`docs/agents/issue-tracker.md`](../../../docs/agents/issue-tracker.md) and the triage label vocabulary in [`docs/agents/triage-labels.md`](../../../docs/agents/triage-labels.md). Both should have been provided to you already.
## Invocation
```
/skill:implement-issue <N> [--base <branch>] [--force]
```
- `<N>` — required, the issue number
- `--base <branch>` — optional, target base branch (default: repo default branch).
- `--force` — optional, allow overwriting an existing worktree.
## Agent CLI Configuration
The CLI agent for child agents is configured in `docs/agents/agent-cli.md`. This file is written by `/setup-skills` Section E and contains:
```yaml
selected: <agent-name>
binary: <binary-name>
args: "<arguments including @{prompt}>"
```
Supported agents and their configurations are defined in `agents-seed.md` in the setup-skills skill directory.
- `--base <branch>` — optional, target base branch (default: repo default branch)
- `--force` — optional, allow overwriting an existing worktree
## Process
### 1. Pre-flight checks
### 1. Setup
Stop on any failure and report clearly what needs fixing. Do not proceed.
#### a. Label the issue `in-progress`
#### 1b. Issue exists and is open
Change the issue triage labels to `in-progress`.
If the issue is not found or state is not `open`, report and stop.
Completion criterion: The issue label is confirmed as `in-progress`.
#### 1c. Issue is labeled `ready-for-agent`
Check that the issue's labels include `ready-for-agent`. If not, report the current state and point the user to `/triage`. Stop.
#### 1d. No open blockers
Read the issue body for "Blocked by #M" references. For each referenced issue, check whether it is open:
If any blocker is open, report the blocking issues and stop.
#### 1e. Remote exists and base branch is reachable
Default base is the repo's default branch — infer from `git ls-remote --heads origin` (look for `main` or `master`). Allow an explicit `--base <branch>` override.
```bash
git ls-remote --heads origin <base>
```
If the remote is unreachable or the base branch doesn't exist, report and stop.
#### 1f. Branch name is free
Derive the branch name from the issue title:
- Format: `issue-<N>-<slug>`
- Slug: lowercase the title, strip to `[a-z0-9-]`, truncate to ~4–5 short words (max ~50 chars), collapse double hyphens
- If the title yields no usable slug, fall back to `issue-<N>`
Check that the branch doesn't already exist on the remote:
```bash
git ls-remote --heads origin <branch-name>
```
If it exists, report and stop. (No auto-suffix, no force-push.)
#### 1g. Worktree path is free
The worktree path is a sibling to the main repo: `../<repo-name>-issue-<N>`. Check that it doesn't already exist:
```bash
ls -d ../<repo-name>-issue-<N>
```
If it exists, report and stop. Let the user override with `--force`.
#### 1h. Running inside a tmux session
Confirm `$TMUX` is set. If not, report "This skill requires a tmux session. Start tmux and rerun." and stop.
#### 1i. Read agent CLI config
Read `docs/agents/agent-cli.md` and parse the `selected`, `binary`, and `args` fields. If the file is missing or malformed, report:
> Agent CLI not configured. Run `/setup-skills` Section E to configure the CLI agent for child agents.
Stop.
#### 1j. Validate binary on PATH
Confirm the configured `binary` is on PATH:
```bash
command -v <binary>
```
If the binary is not found, fail with:
> Agent '<binary>' not found on PATH — rerun /setup-skills to reconfigure.
Stop.
### 2. Setup
#### 2a. Label the issue `in-progress`
Change the issue triage labels to `in-progress`
#### 2b. Create the worktree
#### b. Create the worktree
```bash
git worktree add -b <branch-name> ../<repo-name>-issue-<N> <base>
```
### 3. Compose and write the child prompt
Completion criterion: The worktree exists at `../<repo-name>-issue-<N>` and the new branch is checked out.
### 2. Compose the child prompt
Assemble a single prompt that the child agent will receive. Include:
- **Issue body** — the full markdown body of the issue.
- **Comments** — all comments, if any
- **Standing instruction**: "Implement using TDD: write a failing test first, make it pass, refactor. Explore the codebase before writing code. Respect ADRs and the project domain glossary. Set up the project (install dependencies, build) before starting. The issue body may contain Implementation Decisions and Testing Decisions sections — treat these as constraints."
- **Context**: "Base branch: `<base>`. Target your PR at `<base>`. Branch name: `<branch-name>`."
- **Checklist** — a numbered checklist the child should work through:
1. Explore the codebase and read the issue body + comments thoroughly
2. Install dependencies and build the project
3. Implement the change using TDD (red-green-refactor)
4. Run the full project quality gate (infer from package.json, Makefile, Cargo.toml, etc.), fix until green
5. Commit with conventional commits (`feat:` for enhancement, `fix:` for bug) referencing `(#<N>)`
6. Push the branch: `git push origin <branch-name>`
7. Create a PR with: link to the issue, one-sentence summary, short key-changes list
8. Comment on the issue with the PR link: `"PR opened: <url>"`
9. Change the issue triage label to `needs-review`
10. remove the prompt file from `/tmp` (the child may have already read it)
11. Print `DONE — issue #<N>`
- **Standing instruction**: "Implement using /tdd where possible, at the pre-agreed seam. Run typechecking regularly, run single test files regularly, and run the full test suite once at the end. Once done, use /code-review to review the work. Commit your work and push the new branch and create a PR with a link to the issue, one-sentence summary, and short key-changes list. Comment on the issue with the PR link: `PR opened: <url>`. Change the issue triage label to needs-review when done."
- **Failure instruction**: "If any step fails, report where you stopped and what remains for manual recovery. Print the exact commands needed."
Write the full prompt to a temp file:
(The prompt is passed as arguments to tmux-launch-agent in step 3, which handles writing it to a temp file if needed.)
```bash
cat > /tmp/issue-<N>-prompt.md <<'PROMPT_EOF'
<full-composed-prompt>
PROMPT_EOF
```
Completion criterion: The prompt is composed with all required sections (issue body, comments, standing instruction, failure instruction).
### 4. Launch the child
### 3. Launch the child via tmux-launch-agent
#### 4a. Detect runtime environment
Use the [`tmux-launch-agent`](../../../../.agents/skills/tmux-launch-agent/SKILL.md) skill to fork the child agent into a new tmux window. Tmux-launch-agent handles agent detection, config lookup, command building (prompt-file or stdin-pipe), mise/SHELL wrapping, and `tmux new-window` creation.
Check if `mise` is available:
Pass these parameters:
```bash
command -v mise
```
| Parameter | Value |
|-----------|-------|
| `--name` | `"issue-<N>-<repo-slug>"` — tmux window title |
| Remaining args | The full prompt text composed in step 2 |
If available, use `mise x --allow-env='*' --` as the runner prefix. Otherwise, fall back to `$SHELL -c`.
Ensure the child agent starts in the worktree. If the current pane's working directory is already inside `<absolute-worktree-path>` (from step 1b), tmux-launch-agent's new window inherits it. Otherwise, add `-c <absolute-worktree-path>` to the `tmux new-window` command in tmux-launch-agent's step 6.
#### 4b. Compose the agent command
Substitute `{prompt}` in the configured `args` with the absolute path to the temp prompt file. The prompt file path is `/tmp/issue-<N>-prompt.md`:
```bash
prompt_file="/tmp/issue-<N>-prompt.md"
substituted_args="${args//\{prompt\}/$prompt_file}"
```
- If `args` was non-empty: the agent command is `<binary> $substituted_args`
- If `args` was empty (stdin-piping agents): the agent command is `cat $prompt_file | <binary>`
#### 4c. Compose the full tmux command
Use `$substituted_args` from step 4b:
```bash
tmux new-window -n "issue-<N>-<repo-slug>" -c <absolute-worktree-path> "<runner-prefix> <binary> $substituted_args"
```
**With mise:**
```bash
tmux new-window -n "issue-<N>-<repo>" -c /path/to/worktree "mise x --allow-env='*' -- $binary $substituted_args"
```
**Without mise (fallback):**
```bash
tmux new-window -n "issue-<N>-<repo>" -c /path/to/worktree "$SHELL -c '$binary $substituted_args'"
```
For stdin-piping agents (empty args), use the pipe form:
**With mise:**
```bash
tmux new-window -n "issue-<N>-<repo>" -c /path/to/worktree "mise x --allow-env='*' -- sh -c 'cat $prompt_file | $binary'"
```
**Without mise:**
```bash
tmux new-window -n "issue-<N>-<repo>" -c /path/to/worktree "$SHELL -c 'cat $prompt_file | $binary'"
```
Do **not** pre-write the prompt to a separate file — tmux-launch-agent writes its own temp file if the target agent uses prompt-file mode.
The window stays open after the child completes so the user can review the output.
Do not remove the prompt file immediately — the child agent may not have read it yet. The file will be read from `/tmp` and cleaned up by the OS or the child after use.
Completion criterion: `tmux new-window` exits 0 and a new tmux window appears with the child agent session active.
### 5. Print summary
### 4. Print summary
After launching, print:
- Issue number and title
- Worktree path
- Branch name
- Base branch
- Agent used (from `docs/agents/agent-cli.md`)
- Agent used (detected by tmux-launch-agent)
- Tmux window name (so the user can find it)
- Cleanup command: `git worktree remove <worktree-path> && git worktree prune`
-40
View File
@@ -12,7 +12,6 @@ Scaffold the per-repo configuration that the engineering skills assume:
- Triage labels: the strings used for the canonical triage roles, labels are defined in `triage-labels.md`
- Domain docs: where `CONTEXT.md` and ADRs live, and the consumer rules for reading them
- **ADR wiki** — where ADRs are stored (forge wiki, cloned into `docs/adr/`), and the clone/push workflow
- **Agent CLI** — which CLI agent to use for child agents in `/implement-issue`
This is a prompt-driven skill, not a deterministic script. Explore, present what you found, confirm with the user, then write.
@@ -90,37 +89,6 @@ After the forge is confirmed, present the workflow and confirm:
Record the answers in `docs/agents/adr-wiki.md`.
**Section E — Agent CLI.**
> Explainer: The `implement-issue` skill dispatches a child agent in an isolated git worktree. It needs to know which CLI agent to spawn (pi, opencode, goose, codex, or claude) and how to invoke it. This configuration lives in `docs/agents/agent-cli.md` and is set up once per repo so every developer uses the same agent by default.
Read `agents-seed.md` from this skill directory to get the list of known agents. Present them as a numbered menu:
```
Available agents:
1. pi — My primary agent harness. Accepts prompt file via -p flag.
2. opencode — OpenCode agent. Accepts prompt file via -f flag.
3. goose — Goose agent. Accepts prompt file via -i flag.
4. codex — OpenAI Codex. Pipes stdin via cat.
5. claude — Anthropic Claude CLI. Pipes stdin via cat.
```
Ask the user to type the agent name (or number):
> Which CLI agent should `/implement-issue` use for child agents? (default: pi)
Validate the selected agent's binary is on PATH:
```bash
command -v <selected-binary>
```
If the binary is not found, tell the user:
> Binary '<binary>' not found on PATH. Please install it or choose a different agent.
Loop until a valid binary is found or the user quits.
### 3. Confirm and edit
Show the user a draft of:
@@ -183,14 +151,6 @@ Then write the docs files:
- [adr-wiki.md](./adr-wiki.md) — ADR wiki clone and push workflow
- `docs/agents/agent-cli.md` — agent CLI config with `selected`, `binary`, and `args` fields
For Section E, write `docs/agents/agent-cli.md` with the selected agent:
```yaml
selected: <agent-name>
binary: <binary-name>
args: "<args-from-seed>"
```
For "other" issue trackers, write `docs/agents/issue-tracker.md` from scratch using the user's description.
### 5. Done
+53
View File
@@ -0,0 +1,53 @@
---
name: agent-handoff
description: Hand the current conversation off to a fresh background agent that picks up the work immediately.
argument-hint: "What will the next session be used for?"
disable-model-invocation: true
---
## Invocation
```
/skill:agent-handoff [focus description]
```
Arguments are optional. If provided, they describe what the next session should focus on and the summary is tailored accordingly.
## Process
### 1. Assess the conversation
Review what has been done, what remains, and any user-provided focus. Identify existing artifacts that capture the work so far (PRDs, plans, ADRs, issues, commits, diffs) so they can be referenced rather than duplicated.
If the user passed arguments, treat them as the priority or scope for the next session.
Completion criterion: The conversation is assessed — what's done, what's left, and the user's focus (if any) are identified.
### 2. Compose the handoff summary
Write a summary of the current state so a fresh agent can continue the work without reading the full conversation. Organise it with these sections:
- **Current state** — what was accomplished, branch/commit, what's working
- **Next steps** — what needs to be done next, in priority order
- **Open questions** — decisions still needed, unknowns, trade-offs
- **Suggested skills** — a bullet list of skills the next agent should invoke (e.g. `/tdd`, `/code-review`)
- **References** — paths or URLs to existing artifacts (PRDs, plans, ADRs, issues, commits, diffs). Do **not** duplicate their content — reference them.
The summary is a **compass**, not a copy: it points the next agent where to go, it does not replay where you've been. Any content already captured in the referenced artifacts does not belong here.
Redact any sensitive information: API keys, passwords, personally identifiable information.
Completion criterion: The summary covers all required sections, references existing artifacts without duplicating them, and contains no sensitive information.
### 3. Launch the background agent
Use the [`tmux-launch-agent`](../misc/tmux-launch-agent/SKILL.md) skill to fork a fresh agent seeded with the summary:
```
/skill:tmux-launch-agent --name "<descriptive-title>" <handoff-summary>
```
- `--name` is **required** — use a short descriptive title (e.g. `"Fix login bug"`, `"Implement user roles"`). This sets the display name in the job list, session picker, and terminal title.
- The handoff summary from step 2 becomes the new agent's initial prompt.
Completion criterion: `tmux new-window` exits 0 and a new tmux window appears with the handoff summary as the agent's prompt.
+57
View File
@@ -0,0 +1,57 @@
---
name: tmux-launch-agent
description: Fork a new agent CLI session into a new tmux window, detected from the current agent.
disable-model-invocation: true
---
## Agent CLI Seed Data
The agent config (binary, `args` convention per agent) and field meanings are in [`agents-seed.md`](agents-seed.md). Step 2 reads it to find the calling agent's entry.
## Process
1. **Detect the calling agent** — Run `./detect-agent` (sibling to this skill). If it exits 1 (agent unknown), report the failure and stop — the agent name is required.
Completion criterion: The agent name is known and non-empty.
2. **Look up the agent config** — Find the agent's entry in [`agents-seed.md`](agents-seed.md) by `name`. Extract its `binary` and `args` fields.
Completion criterion: The agent's entry is found and its `binary` and `args` are known.
3. **Parse flags** — Scan the user's arguments for optional flags (which must come before the prompt text):
- `--name <title>` or `-n <title>` — the tmux window title. Extract the title and remove the flag and its value from the arguments list.
- `-c <path>` — the working directory for the new window. Extract the path and remove the flag and its value from the arguments list.
The remaining text after stripping both flags is the prompt for the child agent.
If `--name`/`-n` is absent, tmux auto-names the window.
If `-c` is absent, the new window inherits the current pane's working directory.
Completion criterion: The arguments are split into an optional window name, an optional directory path, and the remaining prompt text.
4. **Build the inner command** — Combine the agent config with the remaining user-supplied prompt arguments. The `args` template determines how the prompt is delivered:
- **Prompt-file agents** (`args` contains `{prompt}`) — Write the prompt text to a temporary file under `/tmp/` and substitute the file path for `{prompt}` in the args template. For example, an agent with `args: "@{prompt}"` becomes `<binary> @/tmp/tmux-launch-XXXX.md`.
- **Stdin-pipe agents** (`args` is empty) — Pipe the prompt text via `echo` into the binary.
- **No prompt** — If the user passed no arguments (after removing flags), launch the binary bare (interactive start) with no prompt file or pipe.
Completion criterion: The inner command is correctly built per the target agent's `args` convention (prompt-file, stdin-pipe, or bare).
5. **Wrap with the environment runner** — Detect whether `mise` is available via `command -v mise`:
- **mise available** — Wrap the inner command as `mise x --allow-env='*' -- <inner-command>`.
- **mise absent** — Wrap the inner command as `$SHELL -c '<inner-command>'`.
Completion criterion: A valid shell command string is ready.
6. **Fork into a new tmux window** — Build and run:
```
tmux new-window <name-flag> <dir-flag> "<shell-command>"
```
- `<shell-command>` — the wrapped command from step 5.
- `<name-flag>` — `-n "<title>"` if a window name was parsed in step 3, omitted otherwise.
- `<dir-flag>` — `-c <path>` if a directory was parsed in step 3, omitted otherwise.
Completion criterion: `tmux new-window` exits 0 and a new tmux window appears with the agent CLI session active.
@@ -1,6 +1,4 @@
# Agent CLI Seed Data
This file is the source of truth for all supported CLI agents. It is read by `setup-skills` Section E to present the menu and by `implement-issue` for agent dispatch.
# TMUX Launch Agent — Agent CLI Seed Data
## Agents
+353
View File
@@ -0,0 +1,353 @@
#!/usr/bin/env bash
#
# detect-agent — Detect which AI agent CLI launched this script.
#
# Checks environment variables and walks the parent process tree to
# identify the originating coding agent. Designed for agent-agnostic
# tools (skills, scripts, hooks) that need to adjust behaviour based
# on which agent invoked them.
#
# Usage:
# detect-agent # print name (e.g. "pi", "opencode")
# detect-agent --name # same as default
# detect-agent --json # JSON: {"agent":"pi","detected":true}
# detect-agent --verbose # human-readable with debug info
# detect-agent --list-agents # list all known agent names
#
# Exit codes:
# 0 agent detected
# 1 unknown / not detected
#
# Supported agents (add your own at the top of each definition map):
# pi, opencode, aider, claude, codex, cursor, windsurf, continue,
# github-copilot, goose
#
# Detection order:
# 1. Environment variable signatures (most reliable)
# 2. Walk parent process tree skipping shells
# 3. Check /proc/$PPID/{comm,cmdline} as fallback
#
set -euo pipefail
########################################################################
# Agent definitions
########################################################################
# Each entry: "<env-var>:<match-value>:<agent-name>"
# If match-value is "*", any non-empty value matches.
# If match-value is a literal, the env var must equal it.
AGENT_ENV_SIGS=(
"PI_CODING_AGENT:true:pi"
"OPENCODE_CONFIG:*:opencode"
"OPENCODE_CONFIG_DIR:*:opencode"
"OPENCODE_API_KEY:*:opencode"
"CLAUDE_CODE_AGENT_RULE_DISABLED:*:claude"
"CLAUDE_CODE_SSE_PORT:*:claude"
"AIDER_DARK_MODE:*:aider"
"CODEX_API_KEY:*:codex"
"CURSOR_AGENT_RULE_DISABLED:*:cursor"
"WINDSURF_AGENT_RULE_DISABLED:*:windsurf"
"CONTINUE_ON_ERROR:*:continue"
)
# Key = /proc/PID/comm (truncated to 15 chars on Linux).
# Value = canonical agent name.
declare -A AGENT_COMM
AGENT_COMM=(
[pi]="pi"
[opencode]="opencode"
[aider]="aider"
[claude]="claude"
[codex]="codex"
[cursor]="cursor"
[windsurf]="windsurf"
[continue]="continue"
[github-copilot]="github-copilot"
[copilot]="github-copilot"
[goose]="goose"
)
# For agents running under an interpreter (node, python, etc.).
# Key = substring to search in cmdline, Value = agent name.
declare -A AGENT_CMDLINE
AGENT_CMDLINE=(
["opencode"]="opencode"
["/pi "]="pi"
["/aider"]="aider"
["/claude"]="claude"
["/codex"]="codex"
["cursor"]="cursor"
["windsurf"]="windsurf"
["continue.dev"]="continue"
["github-copilot"]="github-copilot"
["goose"]="goose"
)
# Shells to skip when walking ancestors.
SHELL_COMMS=(
bash zsh fish sh dash ksh mksh posh ash tcsh csh
tmux:server tmux screen
sudo doas
)
SHELL_CMDLINE_SUBSTRINGS=(
"/bash" "/zsh" "/fish" "/sh" "/dash" "/ksh"
)
########################################################################
# Helpers
########################################################################
comm_of() {
local pid="$1"
cat "/proc/${pid}/comm" 2>/dev/null || true
}
cmdline_of() {
local pid="$1"
tr '\0' ' ' <"/proc/${pid}/cmdline" 2>/dev/null || true
}
is_shell() {
local pid="$1"
local c; c="$(comm_of "$pid")" || true
[[ -z "$c" ]] && return 1
for s in "${SHELL_COMMS[@]}"; do
[[ "$c" == "$s" ]] && return 0
done
local cl; cl="$(cmdline_of "$pid")" || true
for s in "${SHELL_CMDLINE_SUBSTRINGS[@]}"; do
[[ "$cl" == *"$s"* ]] && return 0
done
return 1
}
walk_to_agent_comm() {
local pid="$1"
local c
while [[ "$pid" -gt 1 ]]; do
c="$(comm_of "$pid")" || true
[[ -z "$c" ]] && break
if ! is_shell "$pid"; then
echo "$c"
return 0
fi
pid="$(awk '/^PPid:/{print $2}' "/proc/${pid}/status" 2>/dev/null || true)"
[[ -z "$pid" ]] && break
done
return 1
}
walk_to_agent_cmdline() {
local pid="$1"
local cl
while [[ "$pid" -gt 1 ]]; do
if ! is_shell "$pid"; then
cl="$(cmdline_of "$pid")" || true
if [[ -n "$cl" ]]; then
echo "$cl"
return 0
fi
fi
pid="$(awk '/^PPid:/{print $2}' "/proc/${pid}/status" 2>/dev/null || true)"
[[ -z "$pid" ]] && break
done
return 1
}
check_env_sigs() {
local var val agent
for sig in "${AGENT_ENV_SIGS[@]}"; do
IFS=':' read -r var val agent <<< "$sig"
if [[ "$val" == "*" ]]; then
if [[ -n "${!var:-}" ]]; then
echo "$agent"
return 0
fi
else
if [[ "${!var:-}" == "$val" ]]; then
echo "$agent"
return 0
fi
fi
done
return 1
}
match_cmdline() {
local cl="$1"
local needle agent
for needle in "${!AGENT_CMDLINE[@]}"; do
agent="${AGENT_CMDLINE[$needle]}"
if [[ "$cl" == *"$needle"* ]]; then
echo "$agent"
return 0
fi
done
return 1
}
match_comm() {
local c="$1"
local comm_name
for comm_name in "${!AGENT_COMM[@]}"; do
if [[ "$c" == "$comm_name" ]]; then
echo "${AGENT_COMM[$comm_name]}"
return 0
fi
done
return 1
}
########################################################################
# Main detection logic
########################################################################
detect() {
local agent=""
# Phase 1 — environment variables (most reliable)
agent="$(check_env_sigs)" || true
[[ -n "$agent" ]] && echo "$agent" && return 0
# Phase 2 — walk ancestors, check comm
local ancestor_comm
ancestor_comm="$(walk_to_agent_comm "$PPID")" || true
if [[ -n "$ancestor_comm" ]]; then
agent="$(match_comm "$ancestor_comm")" || true
[[ -n "$agent" ]] && echo "$agent" && return 0
# comm matched but not in our map; try its cmdline
local ancestor_pid="$PPID"
while [[ "$ancestor_pid" -gt 1 ]]; do
local ac; ac="$(comm_of "$ancestor_pid")" || true
if [[ "$ac" == "$ancestor_comm" ]]; then
local ancestor_cl
ancestor_cl="$(cmdline_of "$ancestor_pid")" || true
if [[ -n "$ancestor_cl" ]]; then
agent="$(match_cmdline "$ancestor_cl")" || true
[[ -n "$agent" ]] && echo "$agent" && return 0
fi
break
fi
ancestor_pid="$(awk '/^PPid:/{print $2}' "/proc/${ancestor_pid}/status" 2>/dev/null || true)"
done
fi
# Phase 3 — walk ancestors, check cmdline (catches node-based agents)
local ancestor_cl
ancestor_cl="$(walk_to_agent_cmdline "$PPID")" || true
if [[ -n "$ancestor_cl" ]]; then
agent="$(match_cmdline "$ancestor_cl")" || true
[[ -n "$agent" ]] && echo "$agent" && return 0
fi
# Phase 4 — fallback: check immediate PPID directly
local ppid_comm; ppid_comm="$(comm_of "$PPID")" || true
agent="$(match_comm "$ppid_comm")" || true
[[ -n "$agent" ]] && echo "$agent" && return 0
local ppid_cl; ppid_cl="$(cmdline_of "$PPID")" || true
agent="$(match_cmdline "$ppid_cl")" || true
[[ -n "$agent" ]] && echo "$agent" && return 0
return 1
}
########################################################################
# Output
########################################################################
mode="${1:---name}"
case "$mode" in
--list-agents)
echo "Known agents (by env-var / process-name):"
echo ""
echo "Environment variable signatures:"
for sig in "${AGENT_ENV_SIGS[@]}"; do
IFS=':' read -r var val agent <<< "$sig"
printf " %-12s %-8s %s=%s\n" "$agent" "(env)" "$var" "$val"
done
echo ""
echo "Process comm signatures:"
for comm_name in "${!AGENT_COMM[@]}"; do
printf " %-12s %-8s %s\n" "${AGENT_COMM[$comm_name]}" "(comm)" "$comm_name"
done
echo ""
echo "Cmdline substring signatures:"
for needle in "${!AGENT_CMDLINE[@]}"; do
printf " %-12s %-8s *%s*\n" "${AGENT_CMDLINE[$needle]}" "(cmdline)" "$needle"
done
;;
--json)
agent="$(detect)" || agent="null"
if [[ "$agent" != "null" ]]; then
printf '{"agent":"%s","detected":true}\n' "$agent"
else
printf '{"agent":null,"detected":false}\n'
exit 1
fi
;;
--verbose)
echo "=== Agent Detection ==="
agent="$(detect)" || true
if [[ -n "$agent" ]]; then
echo "Detected agent: $agent"
else
echo "Detected agent: (unknown)"
fi
echo ""
echo "Relevant environment variables:"
for sig in "${AGENT_ENV_SIGS[@]}"; do
IFS=':' read -r var val _ <<< "$sig"
# Skip entries that aren't real variable names (e.g. patterns with *).
[[ "$var" == *\** ]] && continue
if [[ -n "${!var:-}" ]]; then
echo " $var=${!var}"
fi
done
[[ -z "${PI_CODING_AGENT:-}" ]] && echo " PI_CODING_AGENT=<unset>"
echo ""
echo "Process tree (up from PPID=$PPID):"
_dbg_pid="$PPID"
_dbg_depth=0
while [[ "$_dbg_pid" -gt 1 && "$_dbg_depth" -lt 15 ]]; do
_dbg_c="$(comm_of "$_dbg_pid")" || true
_dbg_cl="$(cmdline_of "$_dbg_pid")" || true
if [[ -n "$_dbg_c" ]]; then
printf " [%d] %s" "$_dbg_depth" "$_dbg_c"
if [[ -n "$_dbg_cl" ]]; then
printf " <- %s" "${_dbg_cl:0:100}"
fi
if [[ -n "$agent" ]]; then
_dbg_mc="$(match_comm "$_dbg_c")" || true
if [[ "$_dbg_mc" == "$agent" ]]; then
printf " <-- DETECTED"
fi
fi
echo ""
fi
_dbg_pid="$(awk '/^PPid:/{print $2}' "/proc/${_dbg_pid}/status" 2>/dev/null || true)"
_dbg_depth=$((_dbg_depth + 1))
done
;;
--name|*)
agent="$(detect)" || agent=""
if [[ -n "$agent" ]]; then
echo "$agent"
else
echo "unknown"
exit 1
fi
;;
esac
+2 -2
View File
@@ -2,10 +2,10 @@
## User-invoked
- [conversation-summary](conversation-summary/SKILL.md) — Summarize the current AI conversation into a new Obsidian markdown note and matching transcript file.
- [conversation-summary](conversation-summary/SKILL.md) — Save the current conversation as a comprehensive report note in your Obsidian vault.
- [crit](crit/SKILL.md) — Brainstorm with AI using the CRIT framework to generate and evaluate ideas.
- [knowledge-gardener](knowledge-gardener/SKILL.md) — Run vault-aware semantic search, synthesis, note creation, linking, and Zettelkasten workflows for this Obsidian vault.
- [pkm-curation](pkm-curation/SKILL.md) — Curate an Obsidian-style personal knowledge vault by classifying notes, normalizing frontmatter, improving structure, extracting atomic notes, and adding meaningful wikilinks.
- [pkm-curation](pkm-curation/SKILL.md) — Curate an Obsidian vault — classify notes, normalize frontmatter, add wikilinks, extract atomic notes. Use when curating, batch-processing, reviewing, or doing a serendipity pick.
- [research-vault](research-vault/SKILL.md) — Research a topic through a one-question-at-a-time learning conversation and save a linked Obsidian research packet.
## Model-invoked
+23 -204
View File
@@ -1,224 +1,43 @@
---
name: conversation-summary
description: Summarize the current AI conversation into a new Obsidian markdown note and matching transcript file. Use when the user asks to save, export, log, archive, or summarize the current chat into an Obsidian vault, research note, markdown note, meeting note, decision log, or second-brain workflow.
description: Save the current conversation as a comprehensive report note in your Obsidian vault.
disable-model-invocation: true
---
Create exactly one new Obsidian summary note for the current conversation. Also create exactly one transcript note for the same conversation.
Save this conversation as two linked files in your Obsidian vault: a report (the narrative) and a transcript (the raw conversation).
## Default location
## Report
- Write notes to `obsidian vault` unless the user requests another path.
- Ask if you don't know the location of the obsidian vault.
- Create the directory if it does not exist.
- Never overwrite an existing note.
- Never append to an existing note unless the user explicitly asks.
Write a thorough, standalone report as a Markdown note. A rich narrative in prose, organized under natural headings that follow the conversation's own shape. Capture everything of substance:
## Required behavior
- What prompted the conversation and what context was shared
- What was explored, investigated, or discussed in detail — including code, files, paths, URLs, tools, or skills that came up
- What was found, decided, agreed, or concluded
- Explanations given and concepts clarified
- Open questions or unresolved items
1. Read the current conversation context only.
2. Generate a filesystem-safe title.
3. Write one summary note.
4. Write one transcript note.
5. Verify both files exist.
6. Return the exact paths, generated title, and count of action items captured.
The report must be self-contained — someone reading it later should understand the full discussion, including the reasoning and all relevant details, without having been there. Err on the side of including too much detail rather than too little.
## Title rules
Include a link to the companion transcript where it fits naturally — an Obsidian wikilink like `[[{{title}}_transcript]]` in the section where it makes the most sense (often near the end).
Use this format:
## Transcript
`YYYY-MM-DD_HH-mm_<descriptor>_<ID>`
Save the raw conversation as a separate Markdown note alongside the report. Keep it chronological with no editorializing. Redact likely credentials, secrets, tokens, and private keys.
Rules:
- `<descriptor>`: 3-6 word slug based on the main topic.
- Allowed characters in the full title: letters, digits, `.`, `_`, `-`.
- Replace spaces with `-`.
- Remove other punctuation.
- Collapse repeated separators.
- `<ID>`: 4-character uppercase alphanumeric suffix.
- If a filename collision occurs, regenerate only `<ID>` until unique.
- If too long for the filesystem, shorten only `<descriptor>`.
## Location
## Obsidian-specific rules
Save both files to `AI Conversation Summaries/` under your vault root. Create the directory if needed. Never overwrite existing notes — if a filename collides, append a numeric suffix.
- Use valid YAML frontmatter.
- Keep frontmatter simple and machine-safe.
- Use wikilink-friendly filenames.
- Include both standard markdown links and Obsidian wikilinks where useful.
- Keep headings shallow and scannable.
- Use UTF-8 markdown.
- Prefer stable tags in frontmatter plus inline hashtag tags at the end.
- If the conversation mentions files, URLs, papers, repos, tools, docs, or paths, capture them in a dedicated `References` section.
- If the conversation includes explicit choices, approvals, rejections, or resolved tradeoffs, capture them in `Decisions Made`.
## Filenames
## Summary quality rules
- Report: `YYYY-MM-DD_HH-mm_<topic-slug>.md`
- Transcript: `YYYY-MM-DD_HH-mm_<topic-slug>_transcript.md`
- Use only facts available in the current conversation.
- Do not invent references, decisions, action items, or conclusions.
- Do not write a play-by-play transcript in the summary note.
- Synthesize the conversation into a compact research/work summary.
- If information is missing, say so explicitly.
- If the conversation is short, still use the full template with fallback lines.
- If the transcript available to you is incomplete, mark it as partial.
## Safety
## Automatic tags
- Use only facts from the conversation. Do not invent references, decisions, or conclusions.
- Redact likely credentials, secrets, tokens, and private keys from any inline content.
Generate 4-8 tags total.
## Done
Always include:
- `ai-summary`
- one domain/topic tag based on the conversation
- one workflow tag based on the type of work, if clear
Add tags from these categories when supported by the conversation:
- domain: `research`, `coding`, `obsidian`, `automation`, `writing`, `planning`, `debugging`
- artifact: `skill`, `note`, `transcript`, `review`, `decision-log`
- status: `draft`, `completed`, `follow-up`
- technology/tool names in lowercase slug form when clearly central
Tag rules:
- Use lowercase kebab-case only.
- Prefer specific tags over generic ones.
- Do not add unsupported tags.
## References capture
In the `References` section, capture conversation-specific source material that was explicitly mentioned or used, such as:
- local file paths
- URLs
- repository paths
- document names
- tool names
- named skills, scripts, or commands
Format each reference as one bullet with a short label and what it was used for.
If none were mentioned, write:
- `- No explicit references or source artifacts captured.`
## Decisions capture
Capture only explicit decisions. Include items such as:
- accepted approach
- rejected alternative
- agreed file location
- approved implementation direction
- confirmed formatting preference
If none were made, write:
- `- No explicit decisions captured.`
## Transcript rules
- Save transcript in a separate file named `{{title}}_transcript.md`.
- Keep chronological order.
- Redact likely secrets or credentials.
- Add `[Transcript may be partial]` at the top if the available transcript is incomplete.
- Do not inline the full transcript inside the summary note.
## Summary note template
```md
---
id: {{title}}
aliases:
- {{descriptor}}
- {{short human title}}
tags:
- ai-summary
- {{tag1}}
- {{tag2}}
- {{tag3}}
created: {{ISO-8601 timestamp}}
source: current-ai-conversation
conversation_type: {{research|coding|planning|review|general}}
status: {{draft|completed|follow-up}}
---
# {{short human title}}
> [!abstract]
> **Created:** {{ISO-8601 timestamp}}
> **Source:** Current AI conversation
> **Main Topic:** {{one sentence, 8-20 words}}
## Research Question / Objective
{{One concise sentence. If none: `Not explicitly provided.`}}
## Summary
{{3-5 sentences synthesizing the main discussion, findings, constraints, and outcome. If none: `No meaningful summary could be derived beyond the limited conversation context.`}}
## Key Points
- {{3-7 concrete bullets}}
## Decisions Made
- {{explicit decision}}
## Action Items
- [ ] {{explicit next step}}
## Limitations / Unresolved Assumptions
- {{limitation or assumption}}
## Open Questions
- {{unresolved question}}
## References
- {{reference label}} — {{why it mattered}}
## Related Notes
- Transcript: [[{{title}}_transcript]]
- Markdown link: [{{title}}_transcript.md]({{title}}_transcript.md)
## Tags
#ai-summary {{inline_tags}}
```
## Transcript template
```md
[Transcript may be partial]
# {{short human title}} — Transcript
**Summary Note:** [[{{title}}]]
**Created:** {{ISO-8601 timestamp}}
{{verbatim conversation transcript with likely secrets redacted}}
```
If the transcript is complete, omit the `[Transcript may be partial]` line.
## Fallback lines
Use these exact fallbacks when needed:
- Decisions Made: `- No explicit decisions captured.`
- Action Items: `- [ ] No explicit action items identified.`
- Limitations / Unresolved Assumptions: `- No limitations or unresolved assumptions captured.`
- Open Questions: `- No open questions identified.`
- References: `- No explicit references or source artifacts captured.`
## File paths
- Summary: `AI Conversation Summaries/{{title}}.md`
- Transcript: `AI Conversation Summaries/{{title}}_transcript.md`
## Safety rules
- Never overwrite existing notes.
- Never fabricate transcript lines.
- Never fabricate references or decisions.
- Redact likely credentials, secrets, tokens, and private keys.
- If writing fails, return the full markdown for both files plus intended paths.
- If required context is unavailable, state that clearly in the note instead of guessing.
## Final response format
Confirm success with:
- summary file path
- transcript file path
- generated title
- number of action items captured
- tags generated
- number of references captured
- number of explicit decisions captured
Confirm both file paths and a one-sentence description of what the report covers.
+5 -34
View File
@@ -6,7 +6,7 @@ disable-model-invocation: true
## Purpose
This skill implements the CRIT (Context-Request-Input-Tone) framework for structured brainstorming and idea evaluation. It transforms abstract discussions into concrete, actionable outcomes through systematic analysis and iterative refinement.
This skill implements the CRIT (Context-Request-Ideation-Tone) framework for structured brainstorming and idea evaluation.
## Core Workflow
@@ -23,7 +23,7 @@ Before generating ideas, establish the foundation:
- What has been tried before (if applicable)?
- What resources are available?
**Completion Criterion**: Clear understanding of domain, constraints, and current state documented.
**Completion Criterion**: Domain, constraints, and current state captured in a compact summary (3-5 sentences).
### Step 2: Request Clarification
Structure the brainstorming request:
@@ -38,9 +38,9 @@ Structure the brainstorming request:
- What assumptions should be validated?
- What data or resources are required?
**Completion Criterion**: Specific goal and input requirements clearly defined.
**Completion Criterion**: Goal and input requirements captured as 1-3 concrete statements, each with a checkable success criterion.
### Step 3: Idea Generation
### Step 3: Ideation
Generate diverse, high-quality ideas:
1. **Divergent Thinking Phase**
@@ -86,34 +86,5 @@ Adapt communication to the audience:
- Include examples or analogies for clarity
- Suggest next steps and follow-up questions
**Completion Criterion**: Response delivered in appropriate tone with clear structure.
## Quality Guardrails
- Never generate ideas without clear context and goals
- Always evaluate ideas against defined success criteria
- Maintain transparency about assumptions and limitations
- Encourage iteration and collaboration throughout the process
- Ensure all recommendations are practical and actionable
## Trigger Hints
Load this skill when the user asks to:
- Generate ideas for a specific problem or opportunity
- Brainstorm solutions with structured evaluation
- Get expert guidance through systematic analysis
- Develop actionable plans from abstract concepts
- Evaluate multiple approaches to a challenge
## Output Format
Return results in this structure:
1. **Context Analysis**: Documented understanding of domain and constraints
2. **Request Clarification**: Defined goals and input requirements
3. **Idea Generation**: List of ideas with evaluation scores
4. **Refined Solutions**: Detailed action plans for top candidates
5. **Next Steps**: Suggested follow-up actions and questions
Each section should be clearly labeled and include completion criteria verification.
**Completion Criterion**: Response delivered in chosen role with sections clearly labeled (Context, Request, Ideation, Refinement, Next Steps).
-106
View File
@@ -1,106 +0,0 @@
---
name: knowledge-gardener
description: Run vault-aware semantic search, synthesis, note creation, linking, and Zettelkasten workflows for this Obsidian vault.
metadata:
vault_style: para-plus-zettelkasten
default_write_folder: Inbox
daily_folder: Dailies
templates_folder: Templates
disable-model-invocation: true
---
## Purpose
This skill turns your agent into a vault-aware Obsidian knowledge gardener.
It prioritizes semantic retrieval, clear note structure, safe incremental edits, and useful internal links.
## Vault Conventions
- Preserve folder casing and names used in this vault: `Inbox/`, `Dailies/`, `projects/`, `resources/`, `archive/`, `Templates/`.
- Use Obsidian wikilinks: `[[Note Title]]`.
- Keep existing frontmatter schema compatible with existing notes:
```yaml
---
id: <slug-or-date-id>
aliases: []
tags: []
area: ""
project: ""
---
```
- Default location for new AI-generated notes is `Inbox/` unless explicitly asked otherwise.
## Core Workflows
1. Semantic Search
- Use `python tools/obsidian_semantic_query.py --vault-root . --query "..." --k 12`.
- Return ranked notes with short relevance rationale.
2. Summarization
- Retrieve nearest notes first, then synthesize.
- Include conflicts, unknowns, and suggested next notes.
3. New Note Creation
- Create with canonical frontmatter.
- Include `## Summary` and optional scaffold sections.
- If a summary is provided, include it verbatim under `## Summary`.
4. Automatic Linking
- Suggest links from semantically related notes.
- Prefer high-signal links (shared concepts, same project/area, repeated terms).
5. Refactor to Atomic Notes
- Split long mixed-topic notes into smaller notes.
- Keep parent note as a structure note and link to children.
6. Metadata Maintenance
- Keep `id`, `aliases`, `tags`, `area`, `project` valid.
- Suggest tags from note content; avoid noisy tag spam.
7. Research Capture
- Store source summary in vault.
- Extract key claims, evidence, confidence, and follow-up questions.
- Distinguish raw source claims, agent synthesis, user opinions, and open questions.
- Convert durable insights into permanent notes.
8. Compiled Wiki Maintenance
- For bounded research topics, maintain a Karpathy-style compiled wiki layer: immutable raw sources → maintained concept/claim/synthesis notes → retrievable answers.
- On ingest, update existing pages before creating duplicates; the graph should get denser, not just larger.
- File durable query answers back into notes, then add or update links from indexes/MOCs.
- Keep a lightweight log of ingests, filed answers, lint passes, promotions, and major corrections when the folder has a `Log.md` or equivalent.
9. Retrieval Lint
- Check for unsupported claims, stale or contradictory claims, orphan notes, missing backlinks, missing glossary terms, and unanswered questions.
- Verify a future agent can answer the main question from the maintained notes without rereading raw sources.
10. Packet Promotion
- Treat research packets as incubators and the main vault as the indexed library.
- Promote notes only when they are reusable beyond the packet, stand alone, have evidence/provenance, and connect to existing vault concepts.
- Leave a link behind in the packet and update relevant indexes/MOCs.
11. Zettelkasten Conversion
- Convert source note into atomic permanent notes.
- Add explicit links and one short structure note (MOC-lite) when useful.
## Quality Guardrails
- Never delete user content unless explicitly requested.
- Prefer additive edits and clear section boundaries.
- Keep writing concise and skimmable.
- Keep tags focused and reusable.
- Keep citations close to claims; do not let synthesized notes obscure source provenance.
- Before finalizing research edits, run a retrieval check: likely future questions should have obvious entry points through indexes, links, claims, or glossary terms.
- Rebuild semantic index after major note creation/refactor sessions.
## Operational Commands
- Build index: `python tools/obsidian_semantic_index.py --vault-root .`
- Query index: `python tools/obsidian_semantic_query.py --vault-root . --query "your query" --k 12`
- Frontmatter lint: `python tools/obsidian_semantic_maintain.py lint --vault-root .`
- Related notes: `python tools/obsidian_semantic_maintain.py related --vault-root . --note "Inbox/your-note.md" --k 8`
## Trigger Hints
Load this skill when the user asks to search, summarize, connect, refactor, or organize Obsidian notes.
+24 -38
View File
@@ -1,6 +1,6 @@
---
name: pkm-curation
description: Curate an Obsidian-style personal knowledge vault by classifying notes, normalizing frontmatter, improving structure, extracting atomic notes, and adding meaningful wikilinks.
description: Curate an Obsidian vault — classify notes, normalize frontmatter, add wikilinks, extract atomic notes. Use when curating, batch-processing, reviewing, or doing a serendipity pick.
---
# PKM Curation
@@ -9,11 +9,10 @@ Use this skill when working inside a Markdown-first vault that values curation o
## Goals
- Turn raw notes into clear, reusable notes.
- Turn raw notes into reusable atomic notes.
- Keep new notes consistent with vault conventions.
- Strengthen the link graph with meaningful `[[wikilinks]]` syntax `[[Note Title]]`.
- Strengthen the link graph with meaningful `[[wikilinks]]`.
- Extract atomic notes from long or mixed-topic notes.
- Avoid unnecessary reorganization and weak links.
## Read This First
@@ -23,9 +22,7 @@ Use this skill when working inside a Markdown-first vault that values curation o
- Keep changes small and reviewable.
- Keep file operations local to the vault unless the user explicitly asks otherwise.
## Workflows
## Search for notes
## Search
```bash
# Search by filename
@@ -33,33 +30,15 @@ fd --type f ".md" "path/to/obsidian-vault" | rg -i "keyword"
# Search by content
rg -l "keyword" "path/to/obsidian-vault" --include "*.md"
```
## Curate existing note
1. Inspect the target note or note set.
2. Identify the note type: inbox, source, atomic, project, daily, or reference.
3. Normalize frontmatter and basic structure.
4. Clarify the title if the current one is vague or timestamp-like.
5. Summarize or distill the note if it mixes too many ideas.
6. Add or suggest meaningful `[[wikilinks]]` to related notes.
7. If a note contains multiple durable ideas, extract 1-3 atomic notes.
8. Suggest moving the note only if the destination is clearly better.
## Find related notes
Search for `[[Note Title]]` across the vault to find backlinks:
```bash
# Find backlinks to a note
rg -l "\\[\\[Note Title\\]\\]" "path/to/obsidian-vault" --include "*.md"
```
### Find index notes
```bash
# Find index notes
fd --type f "Index" "path/to/obsidian-vault"
```
## Operating Rules
## Rules
- Prefer curation over reorganization.
- Do not move, rename, or delete many notes at once unless the user asks.
@@ -149,16 +128,17 @@ Keep extracted notes short. One note, one idea.
### Curate one note
- inspect the note
- identify note type
- normalize frontmatter
- tighten headings and summary
- add a few strong links
- suggest extracted atomic notes if warranted
- locate the target file in the vault
- inspect nearby related notes before adding links
- patch the note in place
- return a short summary of edits and suggested follow-up notes
1. Inspect the target note and locate its file in the vault.
2. Identify the note type: inbox, source, atomic, project, daily, or reference.
3. Normalize frontmatter and basic structure.
4. Clarify the title if vague or timestamp-like.
5. Tighten headings and summary; distill if it mixes too many ideas.
6. Inspect nearby related notes, then add a few strong `[[wikilinks]]`.
7. If the note contains multiple durable ideas, extract 1-3 atomic notes.
8. Suggest moving only if the destination is clearly better.
9. Patch the note in place and return a short summary of edits.
**Completion Criterion**: Note inspected, classified, normalized, linked, and patched, with a summary returned to the user.
### Curate an inbox batch
@@ -171,6 +151,8 @@ Keep extracted notes short. One note, one idea.
- process them one at a time
- stop and summarize after each batch
**Completion Criterion**: Each note in the batch classified and normalized, with a summary returned after the batch.
### Review recent notes
- inspect recently edited notes
@@ -180,6 +162,8 @@ Keep extracted notes short. One note, one idea.
- search by recent filenames or recent folders when file metadata is available
- keep edits conservative and return a review summary
**Completion Criterion**: Recently edited notes inspected, missing links and mixed concerns flagged, with a review summary returned.
### Serendipity review
- choose a note from the vault
@@ -189,6 +173,8 @@ Keep extracted notes short. One note, one idea.
- pick one note from a user-specified folder or from curated folders only
- avoid randomizing across obviously raw capture unless the user asks for that
**Completion Criterion**: One curated note chosen, briefly summarized, compared to active topic, with only high-confidence connections suggested.
## Output Style
When responding to the user: