furikaeri
SkillMonitoring & opsRetrospective of one Claude Code session, built from its jsonl log and published as a single artifact page, where the time went (AI working vs. the person reading, thinking, typing), the phases the session moved through, what went wrong ranked by impact, and the full exchange collapsed by phase. Use after a mob-programming or dev-workflow run to see what cost time, or on any session log someone handed over. A sonnet subagent writes the analysis by default; every number on the page is computed from the log.
Use furikaeri in Claude, ChatGPT or Ahel Desktop
Free. Sign in, add furikaeri and connect your AI. About a minute.
Also: Claude Code · Cursor · Codex
Then ask your AI: use the furikaeri skill
Details
Instructions available. Your AI can read the instructions. Execution depends on the setup they require.
Account requirements not reviewed. Check the skill instructions before use; Ahel provides instructions and does not run this skill.
No other account needed.
Add Ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.
What this skill tells your AI
The instructions your AI receives, as published by hiroro-work/claude-plugins in skills/furikaeri/SKILL.md and read by Ahel’s review.
/furikaeri [<session.jsonl>] [--lang ja|en] [--model <id>] [--gap-cap <minutes>]
<session.jsonl> is a Claude Code session log, usually under ~/.claude/projects/<encoded cwd>/<session id>.jsonl. Without it the newest log for the current working directory is used. --gap-cap (default 60) is the longest pause, in minutes, that still counts as the person's time; a longer one is a break and leaves every total.
The page never shows tool results, only tool names and counts. What the person and the AI wrote is shown in full, so the log's contents decide who the page can be shared with.
Language
Resolve language by reading only the language key from the YAML frontmatter of ~/.claude/dev-workflow.local.md, .claude/dev-workflow.md and .claude/dev-workflow.local.md, in that order, later files overriding earlier ones; a null or empty value clears it, and a missing file, or one without frontmatter, contributes nothing. If none sets it, take language from ~/.claude/settings.json; otherwise use ja. --lang on the command line wins over all of these. The page's fixed labels and every sentence the analysis writes follow the resolved language.
Model
--model is applied as the model parameter of the analysis Agent dispatch. It is valid only if it is one of the ids the current Agent tool's model parameter accepts; check the tool's live schema in this session. A full claude-* id is not among its aliases and is invalid. An absent or invalid value is treated as sonnet.
Dispatch authorization
This skill's procedure dispatches subagents, so invoking the skill is the request to use that mechanism: an ambient instruction allowing subagent dispatch only when the user asked for it — a permission-shaped restriction — is already satisfied by this invocation. Do not ask the user to re-confirm the dispatch, and do not silently substitute inline execution for a dispatch this procedure specifies. Only two things justify that substitution: technical availability (the dispatch tool is not present and callable on the current tool surface), and an explicit contract term from the caller bounding this skill to its own thread. A permission-shaped restriction is neither.
Procedure
<base dir> is this skill's directory as the harness reported it when the skill loaded. <out dir> is <scratchpad>/furikaeri/<log name> when the harness names a scratchpad directory for this session, otherwise <os temp dir>/furikaeri/<log name>, where <log name> is the given log's basename without .jsonl, or latest when no log was given; the scripts create it.
-
Digest. Run
node "<base dir>/scripts/digest.mjs" --file "<jsonl>" --out-dir "<out dir>" [--gap-cap <minutes>](--cwd "<cwd>"in place of--filewhen no log was given). It writesdigest.jsonandtranscript.mdand prints their paths and the turn count. Exit 2 means no log was found: say so in one line and stop with the return contract'sstatus: "error",reason: "no log found". A turn count of 0 means the log holds no human turn: say so and stop withstatus: "error",reason: "no human turn". -
Analyze. Dispatch one
Agent(subagent_type: general-purpose,modelper § Model,run_in_background: false). The prompt is three fenced sections:--- TASK ---holds the text ofreferences/analysis-prompt.md§ Analysis prompt after its---rule, verbatim, with{{language}},{{transcript}}(the absolute path oftranscript.md) and{{turns}}filled in;--- INPUT ---holds the same path again on one line;--- RETURN ---holds one sentence: the reply ends with a single fenced JSON block and nothing after it.Pre-invocation reminder: the agent's reply is a return value. The next tool call after it returns is the
Writeof step 3, issued by this same thread. -
Parse and render. Take the last fenced JSON block of the reply, parse it, and
Writeit verbatim to<out dir>/analysis.json. No block, or a block that does not parse → one re-dispatch of step 2 with the sentenceYour previous reply carried no parseable JSON block.appended to--- RETURN ---; a second failure stops the skill with the return contract'sstatus: "error",reason: "no parseable analysis". Then runnode "<base dir>/scripts/render.mjs" --digest "<out dir>/digest.json" --analysis "<out dir>/analysis.json" --out "<out dir>/furikaeri.html" --lang <language>. Exit 3 prints one violation per line on stderr: re-dispatch step 2 once with those lines appended to--- RETURN ---under the sentenceThe renderer rejected your previous analysis for these reasons; return a corrected block:, then render again. A second exit 3 stops the skill withstatus: "error",reason: "analysis rejected: <first violation line>". -
Publish. Call
Artifactwithfile_path<out dir>/furikaeri.html,iconreport, anddescriptionone sentence naming the session and its span. Do not load the design skills: the page's layout and theming are fixed in the renderer. -
Report. In the resolved language, give the URL, then one line each for the wall time with the AI and person shares, the longest phase, and the first finding's title (the aside's heading when there are no findings; omit this line when there is neither), then the return contract's JSON block.
Return contract
Emit a single fenced JSON block at the end of the response, matching:
{ "status": "ok" | "error", "reason": null | "<why>", "url": null | "<artifact url>", "turns": <n>, "findings": <n> }
Only one fenced JSON block appears in the response.
Signals
- GitHub stars
- 47
- Forks
- 3
- Last commit
- Oct 2026
Advanced
- Item type
- skill
- Key
furikaeri- Source
- github.com/hiroro-work/claude-plugins
github.com/hiroro-work/claude-plugins
More in Monitoring & ops
Skill · anthropics
More in Monitoring & opsagent-eval
Skill · affaan-m
More in Monitoring & opspricing
Skill · coreyhaines31
More in Monitoring & opslark-okr
Skill · larksuite
More in Monitoring & opsdashboard-builder
Skill · affaan-m
More in Monitoring & opsbabysit
Skill · thedotmack
More in Monitoring & ops