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:
+1
-1
@@ -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.
|
||||
|
||||
@@ -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`
|
||||
|
||||
|
||||
@@ -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,16 +151,8 @@ 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
|
||||
|
||||
Tell the user the setup is complete, which engineering skills will now read from these files, and that ADR changes are pushed to the forge wiki at end of session. Mention they can edit `docs/agents/*.md` directly later — re-running this skill is only necessary if they want to switch issue trackers, restart from scratch, or reconfigure the ADR wiki or agent CLI.
|
||||
Tell the user the setup is complete, which engineering skills will now read from these files, and that ADR changes are pushed to the forge wiki at end of session. Mention they can edit `docs/agents/*.md` directly later — re-running this skill is only necessary if they want to switch issue trackers, restart from scratch, or reconfigure the ADR wiki or agent CLI.
|
||||
|
||||
@@ -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.
|
||||
@@ -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
-3
@@ -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
|
||||
|
||||
Executable
+353
@@ -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,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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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).
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user