| name | cf-ask |
| description | Quick Q&A about codebase — explores code to answer, saves to docs/memory. Use when the user asks a focused question about the project — e.g. "how does X work?", "where is Y defined?", "what's the flow for Z?", "explain this module", "how are these connected?", "what pattern does this use?", "why is this done this way?". Unlike /cf-research (deep multi-doc output), this gives a single focused answer.
|
| disable-model-invocation | true |
| created | "2026-02-20T00:00:00.000Z" |
| updated | "2026-07-04T00:00:00.000Z" |
| model | sonnet |
/cf-ask
CLI Requirement: OPTIONAL — Uses the memory MCP from coding-friend-cli for fast indexed search and storage. Without the CLI: falls back to grep over docs/memory/ and direct file writes. Full functionality preserved, slower memory recall. See CLI requirements.
Answer the question: $ARGUMENTS
Purpose
Quick, focused Q&A about the codebase. Proactively explores code to find the answer, then saves the Q&A to project memory so it can be referenced later.
- Unlike
/cf-research: single focused answer, no multi-doc output
- Unlike
/cf-remember: proactively explores the codebase to answer vs extracting knowledge already in conversation
Folder
Output goes to {docsDir}/memory/ (default: docs/memory/). Check .coding-friend/config.json for custom docsDir if it exists.
IMPORTANT — path resolution:
- Use
MAIN_REPO_ROOT from the SessionStart bootstrap context (injected via session-init.sh). If absent, fall back to running pwd for $CWD and use $CWD as MAIN_REPO_ROOT.
- Read config from
CF_CONFIG_FILE (= $MAIN_REPO_ROOT/.coding-friend/config.json) — do NOT search sub-folders
- Use
CF_DOCS_ROOT as the docs base dir (= $MAIN_REPO_ROOT/{docsDir} where docsDir comes from config, default docs)
- Always resolve
file_path as an absolute path: {CF_DOCS_ROOT}/memory/{category}/{name}.md
- Never use relative paths in write specs — they may resolve incorrectly when the working directory contains nested git repos
Workflow
Step 0: Custom Guide
Custom guide — auto-loaded below (if the raw command shows instead of its output, run it yourself):
bash "${CLAUDE_PLUGIN_ROOT}/lib/load-custom-guide.sh" cf-ask
If output is not empty, integrate returned sections: ## Before → before first step, ## Rules → apply throughout, ## After → after final step.
Step 1: Parse the Question
-
Read $ARGUMENTS as the question
-
If no question provided, ask the user what they want to know
-
Identify keywords and likely relevant areas (modules, features, patterns)
-
Classify the question type — check if the question is a flow question. A flow question asks about how something works end-to-end, how components interact, or what happens when a process runs. Trigger words: "how does X work", "flow of", "lifecycle", "sequence", "process", "when X happens", "walk me through", "how are X connected", "what triggers", "what happens when", "pipeline", "chain". Non-flow questions (lookup/definition/pattern/why) do NOT trigger this path.
Set IS_FLOW_QUESTION = true/false for use in Steps 3, 4, 5, and 6.
Step 2: Check Existing Memory (Memory Recall)
Before exploring the codebase, search existing memory docs. Extract 2-3 keywords from the question.
Primary method — Memory MCP tool (if memory_search tool is available):
Call the memory_search MCP tool with: { "query": "<keywords from question>", "limit": 5 }
If the tool call fails (MCP not configured), fall back to the grep method below.
Fallback — 3-tier grep (if memory MCP unavailable):
Check {docsDir} from .coding-friend/config.json (default: docs).
- Grep
^description: lines across {docsDir}/memory/**/*.md — match against question keywords
- If no match, grep
^tags: lines across {docsDir}/memory/**/*.md
- If no match, grep file content for the keywords (
output_mode: "files_with_matches")
After finding matches:
- Read the top 2-3 most relevant matched files
- If a direct match is found (same or very similar question already answered):
- Present the existing answer to the user (cite the memory file)
- Ask if they want a fresh exploration or if the existing answer is sufficient
- If sufficient → skip to Step 7 (no save needed)
- If related context is found (useful background, not a direct answer):
- Collect it as supplementary context to pass along to Step 3
- If no relevant memory is found → proceed to Step 3
Step 3: Explore the Codebase (via cf-explorer agent)
Launch the cf-explorer agent to gather codebase context for the question.
Use the Agent tool with subagent_type: "coding-friend:cf-explorer". Pass:
Explore the codebase to answer the following question: [question from Step 1]
Questions to answer:
- [rephrase the user's question as specific search targets]
- What files, functions, or patterns are relevant?
- What are the key code snippets that answer the question?
Scope: [keywords and likely relevant areas from Step 1]
If IS_FLOW_QUESTION = true, add the following to the agent prompt:
Flow mapping required — also identify and report:
- Entry points: where does the flow start? (user action, event, API call, CLI command…)
- Actors / components: what modules, classes, functions, or services are involved?
- States / stages: what are the distinct states or phases the system moves through?
- Transitions: what triggers movement from one state/stage to the next?
- Exit points / outcomes: what are the final states or outputs?
- Error / alternate paths: are there branches, retries, or failure modes?
Organize findings as a list of states and transitions — not just a list of files.
If related memory context was found in Step 2, include it:
Existing memory context (use as supplementary info, verify against current code):
[summary of related memory findings]
Wait for the cf-explorer to return its findings.
Step 4: Form the Answer
- Synthesize findings into a clear, structured answer
- Incorporate any related memory context from Step 2
- Reference specific files and line ranges where relevant
- Use code snippets only when they clarify the answer
- Keep it concise — this is a focused answer, not a research paper
If IS_FLOW_QUESTION = true, also generate an ASCII diagram as part of the answer:
- Pick the right layout based on the flow's shape:
- Discrete states with transitions → a state chart: boxed states joined by labeled arrows (e.g.
[Idle] --start--> [Running])
- Component-to-component interactions with messages → a sequence layout: vertical actor lanes with horizontal
---> message arrows top-to-bottom
- Process with decisions / branching → a top-down flowchart: boxes for steps, a decision node with
yes / no labeled branches
- Rubric: identify actors/states (nodes), then transitions/messages (edges), then add alternate/error paths as labeled arrows. Label every transition with what triggers it. Keep the diagram to the minimum nodes needed to convey the big picture — omit internal implementation details that don't add clarity.
- Style: plain text only, using box-drawing / arrow characters (
┌ ─ ┐ │ └ ┘ → ← ↑ ↓ + | -). No Mermaid or other rendered-diagram syntax. Render it inside a plain fenced code block so alignment is preserved.
- The diagram IS the concise answer for flow questions — keep surrounding prose tight.
Step 5: Present to User
- Show the answer directly in the conversation
- If
IS_FLOW_QUESTION = true, display the ASCII diagram inline (inside a plain fenced code block) before or after the prose — whichever gives the clearest reading order
- List the key files that were consulted
Step 6: Save to Memory (via cf-writer agent)
- Read
language config (local .coding-friend/config.json overrides global ~/.coding-friend/config.json, default: en)
- Search existing memory files in
{docsDir}/memory/ — if an existing file covers the same topic, use task: update (append). Otherwise, use task: create.
- Choose the appropriate category:
features/YYYY-MM-DD-<name>.md — for feature-specific logic, flows, APIs
conventions/YYYY-MM-DD-<name>.md — for project-wide patterns and rules
decisions/YYYY-MM-DD-<name>.md — for architecture/design decisions
- Use kebab-case for file names
Backward compat: When updating existing memory files without a date prefix, preserve the existing filename — do not add a date prefix to already-created files.
Construct a write spec and delegate to cf-writer agent via the Agent tool with subagent_type: "coding-friend:cf-writer".
When creating a new file (use absolute path for file_path):
WRITE SPEC
----------
task: create
file_path: {CF_DOCS_ROOT}/memory/{category}/YYYY-MM-DD-{name}.md
language: {language from config}
content: |
---
title: "<Title>"
description: "<One-line summary for grep-based recall, under 100 chars>"
tags: [tag1, tag2, tag3]
created: YYYY-MM-DD
updated: YYYY-MM-DD
---
# <Title>
## Overview
<1-2 sentences>
## Q&A: <short question summary> (YYYY-MM-DD)
**Q:** <question>
**A:** <concise answer>
<!-- Include this section only when IS_FLOW_QUESTION = true -->
## Flow Diagram
```
<diagram generated in Step 4>
Related files: path/to/file1, path/to/file2
readme_update: false
auto_commit: false
existing_file_action: skip
**When appending** to an existing file (use absolute path for `file_path`):
WRITE SPEC
task: update
file_path: {CF_DOCS_ROOT}/memory/{category}/YYYY-MM-DD-{name}.md
language: {language from config}
content: |
Q&A: (YYYY-MM-DD)
Q:
A:
Flow Diagram
<diagram generated in Step 4>
Related files: path/to/file1, path/to/file2
readme_update: false
auto_commit: false
existing_file_action: append
When appending, also instruct cf-writer to update the `updated` date in the existing frontmatter.
**Frontmatter rules:**
- `description`: factual, searchable summary under 100 chars. Good: `"JWT auth flow with refresh tokens and OAuth2 integration"`. Bad: `"About auth"`.
- `tags`: 3-5 keywords as array
### Step 7: Index in CF Memory (MANDATORY)
**This step is REQUIRED — do NOT skip it.**
After the cf-writer agent completes and the file is saved, you MUST call the `memory_store` MCP tool to index the memory in the database. This is a separate action from writing the file — the cf-writer agent does NOT do this.
**If creating a new memory** — call `memory_store` with:
- `title`: from the frontmatter title
- `description`: from the frontmatter description
- `type`: `fact`
- `tags`: from the frontmatter tags
- `content`: the full markdown content (including frontmatter)
- `importance`: 3 (default)
- `source`: "conversation"
- `index_only`: true
**If updating an existing memory** — call `memory_update` with:
- `id`: the memory ID (e.g., `features/auth-module` — derived from `{category}/{name}`)
- `content`: the updated full markdown content
- `tags`: updated tags array (if changed)
If the MCP tools are unavailable, log a warning to the user but do NOT fail silently — the user should know the memory was saved as a file but NOT indexed.
### Step 8: Confirm
Show the user a 2-line summary:
- **Markdown file:** `path/to/file.md` (created or appended)
- **Memory DB:** indexed ✓ — or: MCP unavailable, file only
## Rules
- Delegate exploration to the cf-explorer agent — keep the main context lean
- Stay lightweight — no multi-doc output
- Always save to `{docsDir}/memory/` — saving is mandatory, not optional
- Search existing memory files before creating new ones
- NEVER overwrite existing content — only append
- Respect `.coding-friend/ignore` patterns
- Use `language` config for answer language
- Create directories as needed