You are invoking the cowork-insights report generator. Your job is to:
- Determine the right parameters from the user's request
- Run the generator
- Show the results
The engine scans Claude and Codex histories. Codex goal-control envelopes remain in raw history but are excluded from prompts and facet transcripts.
Step 1: Determine Parameters
Parse the user's request to determine these flags:
| Flag |
How to decide |
Default |
--from |
"this week" / "7d" / "last month" / "1m" / "2026-03-01" |
omit (all time) |
--to |
usually omit |
omit (now) |
--scope |
"this project" → default, "with subfolders" → with-subfolder, "everything" → all |
default |
--path |
specific folder if mentioned, else the user's repo |
always pass "$PWD" — never omit (the engine's own cwd is the plugin dir, so omitting scans the wrong project) |
--exclude-path |
folders to exclude (repeatable) |
omit |
--tz |
timezone if mentioned |
Asia/Seoul |
--format |
"full recap" → full, "quick" → standard, "minimal" / "standup" → minimal. Auto: 20+ sessions → full, 1-19 → standard |
auto |
--language |
auto-detect from the user's conversation language (the language THEY are writing to you in), unless they explicitly request another. Pass the BCP-47-ish short code: ko, en, ja, zh-Hans, etc. |
auto-detect (fallback en) |
--output |
output path base |
omit (auto) |
Language detection (do this, don't default blindly): look at the language the user is actually
writing in this conversation and pass it as --language. Korean prompts → ko, English → en,
Japanese → ja. Only override when the user explicitly asks for a specific output language
("write the report in English" → en). Use the SAME language for the facet step (Step 1.5) and the report so the
two layers match.
Step 1.5: Generate the qualitative layer (facets) — BEFORE rendering
The report has two layers: quantitative (commits, tokens, tools — always present) and
qualitative (outcomes, friction patterns, verbatim key prompts, memories). The qualitative layer
comes from per-session facets. generate-narrative.ts only loads cached facets — it never
creates them. If no facets exist, the report silently degrades to bare metrics (this is the
single biggest quality failure of this skill). So generate them first, automatically — do not ask.
List the sessions that still need a facet (deterministic — never compute the project hash
yourself):
bun run "${CLAUDE_PLUGIN_ROOT}/src/cli.ts" list-uncached \
--from <FROM> --to <TO> --scope <SCOPE> --path "$PWD" --tz <TZ>
Output: { facetsDir, analyzed, cached, subagentsSkipped, uncachedCount, uncached: [{sessionId, path}] }.
(Subagent sessions are pre-skipped; list-uncached already matches the report's analyzed set, so
you never over-generate.)
If uncachedCount === 0 → skip to Step 2 (facets already cached; re-runs are free).
If uncachedCount > 0 → dispatch the cowork-facet-extractor agent once per uncached
session, all in parallel (bundle the Agent calls in a SINGLE message so they run concurrently —
not one at a time). Do NOT inline a giant facet prompt; the agent already owns the schema, enum
constraints, and CC-derived analysis guidelines. Pass only the three variables:
Agent(subagent_type="cowork-facet-extractor"), one per session, with prompt:
SESSION_ID: <uncached[i].sessionId>
JSONL_PATH: <uncached[i].path>
LANGUAGE: <the --language you resolved in Step 1>
facetsDir: <facetsDir from list-uncached>
Extract this session's facet and write it to <facetsDir>/<SESSION_ID>.json per your spec.
Each agent reads its own transcript (off your context — it never bloats the main session) and
writes one JSON file. They reply only DONE <id> ….
Wait for all to finish, then proceed to Step 2. The generator will now load them and render
the full qualitative layer (target: analyzed === cached, all 7 sections succeed).
Scale note: for very large ranges (--scope all, months) uncachedCount can be dozens+. That is
expected and fine — they run in parallel and the cache is permanent (facets survive even after the
original session files are deleted). Don't cap or sample silently; if you must bound it, say so.
Step 2: Run the Generator
Run a single command. This handles everything: data collection, parallel LLM generation, assembly, and rendering.
bun run "${CLAUDE_PLUGIN_ROOT}/src/generate-narrative.ts" \
--from <FROM> --to <TO> \
--scope <SCOPE> --path "$PWD" \
--exclude-path <EXCLUDE> \
--tz <TZ> \
--format <FORMAT> \
--language <LANGUAGE> \
--output <OUTPUT>
Omit flags that aren't needed. The generator outputs progress to stderr and the final result (JSON with file paths) to stdout.
Do NOT run scan, summarize, or render-report separately. The generator handles the full pipeline internally:
- Runs
summarize to collect data (~20KB compact + full scan data)
- Spawns parallel
claude -p calls for section generation (~30-40s)
- Generates At a Glance referencing other sections (~15-20s)
- Assembles NarrativeData JSON
- Renders HTML + Markdown
Expected time: 50-130 seconds depending on data volume and format.
Step 3: Show Results
After the generator completes, show:
- One-line summary stats (sessions, messages, hours, commits, lines)
- Full At a Glance section (read from the generated narrative JSON)
- 2-3 best key prompts with verbatim quotes
- Links to both files (HTML + Markdown)
If 0 sessions returned, suggest different date ranges or scope.
Notes
- Facets are now generated up front (Step 1.5), not as an afterthought. The qualitative layer is
part of the deliverable, not optional — never render a facet-empty report and call it done. If
generate-narrative logs Facets: 0 while analyzed > 0, Step 1.5 was skipped — go back and run
it. (Verify with the generator's Step 1 done … Facets: N line: N should equal the analyzed
session count, minus any skipped subagents.)
- The facet schema + analysis rules live in the
cowork-facet-extractor agent, not here — one
source of truth. If the schema changes, edit the agent and src/facet-cache.ts together.
- Cost: facet extraction uses Sonnet by default (the agent's
model:), parallel and cached, so
the qualitative layer is cheap to add and free to re-render afterward.
1---2name: cowork-insights3description: Invoke for "/cowork-insights" or requests to summarize, review, or report on past Claude Code or Codex sessions. Shows key prompts, outcomes, friction, tools, and actionable insights. DO NOT invoke for active tasks or commit-time recaps (use cowork-commit).4---56You are invoking the cowork-insights report generator. Your job is to:71. Determine the right parameters from the user's request82. Run the generator93. Show the results1011The engine scans Claude and Codex histories. Codex goal-control envelopes remain in raw history but are excluded from prompts and facet transcripts.1213## Step 1: Determine Parameters1415Parse the user's request to determine these flags:1617| Flag | How to decide | Default |18|------|--------------|---------|19| `--from` | "this week" / "7d" / "last month" / "1m" / "2026-03-01" | omit (all time) |20| `--to` | usually omit | omit (now) |21| `--scope` | "this project" → `default`, "with subfolders" → `with-subfolder`, "everything" → `all` | `default` |22| `--path` | specific folder if mentioned, else the user's repo | **always pass `"$PWD"`** — never omit (the engine's own cwd is the plugin dir, so omitting scans the wrong project) |23| `--exclude-path` | folders to exclude (repeatable) | omit |24| `--tz` | timezone if mentioned | `Asia/Seoul` |25| `--format` | "full recap" → `full`, "quick" → `standard`, "minimal" / "standup" → `minimal`. Auto: 20+ sessions → `full`, 1-19 → `standard` | auto |26| `--language` | **auto-detect from the user's conversation language** (the language THEY are writing to you in), unless they explicitly request another. Pass the BCP-47-ish short code: `ko`, `en`, `ja`, `zh-Hans`, etc. | auto-detect (fallback `en`) |27| `--output` | output path base | omit (auto) |2829**Language detection (do this, don't default blindly):** look at the language the user is actually30writing in *this* conversation and pass it as `--language`. Korean prompts → `ko`, English → `en`,31Japanese → `ja`. Only override when the user explicitly asks for a specific output language32("write the report in English" → `en`). Use the SAME language for the facet step (Step 1.5) and the report so the33two layers match.3435## Step 1.5: Generate the qualitative layer (facets) — BEFORE rendering3637The report has two layers: **quantitative** (commits, tokens, tools — always present) and38**qualitative** (outcomes, friction patterns, verbatim key prompts, memories). The qualitative layer39comes from per-session **facets**. `generate-narrative.ts` only *loads* cached facets — it never40creates them. **If no facets exist, the report silently degrades to bare metrics** (this is the41single biggest quality failure of this skill). So generate them first, automatically — do not ask.42431. **List the sessions that still need a facet** (deterministic — never compute the project hash44 yourself):4546 ```bash47 bun run "${CLAUDE_PLUGIN_ROOT}/src/cli.ts" list-uncached \48 --from <FROM> --to <TO> --scope <SCOPE> --path "$PWD" --tz <TZ>49 ```5051 Output: `{ facetsDir, analyzed, cached, subagentsSkipped, uncachedCount, uncached: [{sessionId, path}] }`.52 (Subagent sessions are pre-skipped; `list-uncached` already matches the report's analyzed set, so53 you never over-generate.)54552. **If `uncachedCount === 0`** → skip to Step 2 (facets already cached; re-runs are free).56573. **If `uncachedCount > 0`** → dispatch the **`cowork-facet-extractor`** agent **once per uncached58 session, all in parallel** (bundle the Agent calls in a SINGLE message so they run concurrently —59 not one at a time). Do NOT inline a giant facet prompt; the agent already owns the schema, enum60 constraints, and CC-derived analysis guidelines. Pass only the three variables:6162 ```63 Agent(subagent_type="cowork-facet-extractor"), one per session, with prompt:6465 SESSION_ID: <uncached[i].sessionId>66 JSONL_PATH: <uncached[i].path>67 LANGUAGE: <the --language you resolved in Step 1>68 facetsDir: <facetsDir from list-uncached>6970 Extract this session's facet and write it to <facetsDir>/<SESSION_ID>.json per your spec.71 ```7273 Each agent reads its own transcript (off your context — it never bloats the main session) and74 writes one JSON file. They reply only `DONE <id> …`.75764. **Wait for all to finish**, then proceed to Step 2. The generator will now load them and render77 the full qualitative layer (target: `analyzed === cached`, all 7 sections succeed).7879> Scale note: for very large ranges (`--scope all`, months) `uncachedCount` can be dozens+. That is80> expected and fine — they run in parallel and the cache is permanent (facets survive even after the81> original session files are deleted). Don't cap or sample silently; if you must bound it, say so.8283## Step 2: Run the Generator8485Run a **single command**. This handles everything: data collection, parallel LLM generation, assembly, and rendering.8687```bash88bun run "${CLAUDE_PLUGIN_ROOT}/src/generate-narrative.ts" \89 --from <FROM> --to <TO> \90 --scope <SCOPE> --path "$PWD" \91 --exclude-path <EXCLUDE> \92 --tz <TZ> \93 --format <FORMAT> \94 --language <LANGUAGE> \95 --output <OUTPUT>96```9798Omit flags that aren't needed. The generator outputs progress to stderr and the final result (JSON with file paths) to stdout.99100**Do NOT run `scan`, `summarize`, or `render-report` separately.** The generator handles the full pipeline internally:1011. Runs `summarize` to collect data (~20KB compact + full scan data)1022. Spawns parallel `claude -p` calls for section generation (~30-40s)1033. Generates At a Glance referencing other sections (~15-20s)1044. Assembles NarrativeData JSON1055. Renders HTML + Markdown106107Expected time: **50-130 seconds** depending on data volume and format.108109## Step 3: Show Results110111After the generator completes, show:1121. One-line summary stats (sessions, messages, hours, commits, lines)1132. Full At a Glance section (read from the generated narrative JSON)1143. 2-3 best key prompts with verbatim quotes1154. Links to both files (HTML + Markdown)116117If 0 sessions returned, suggest different date ranges or scope.118119## Notes120121- **Facets are now generated up front (Step 1.5), not as an afterthought.** The qualitative layer is122 part of the deliverable, not optional — never render a facet-empty report and call it done. If123 `generate-narrative` logs `Facets: 0` while `analyzed > 0`, Step 1.5 was skipped — go back and run124 it. (Verify with the generator's `Step 1 done … Facets: N` line: `N` should equal the analyzed125 session count, minus any skipped subagents.)126- **The facet schema + analysis rules live in the `cowork-facet-extractor` agent**, not here — one127 source of truth. If the schema changes, edit the agent and `src/facet-cache.ts` together.128- **Cost**: facet extraction uses Sonnet by default (the agent's `model:`), parallel and cached, so129 the qualitative layer is cheap to add and free to re-render afterward.