@litfamily/litclaude 1.0.25 → 1.0.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.26 - 2026-10-13
4
+
5
+ - The LIT card now shows where you are in the LIT workflow. A map row lights the current stage of the running family (interview, plan, work, review, loop, research), and a detail line under it says what that stage is doing: the interview round and ambiguity, whether the plan awaits approval, how many tasks are checked and which comes next, each review lane's verdict. On the right of that line the live step names the tool the main loop is running and for how long, or `thinking` between tool calls, and never shows its arguments.
6
+ - The map moves on its own. LitClaude's hooks advance it as lit-plan saves the plan, start-work's tasks are checked, review lanes report their verdicts and a lit-loop criterion goes from RED to GREEN to VERIFY, so the model does not have to report each step. For what the hooks cannot see, such as a loop step or a crucible verdict, the new `litclaude-ai workflow-stage` command records the stage.
7
+ - In the Claude desktop app the card is drawn as one picture. The app sets text in a proportional font, which pulled the terminal card apart there, so the desktop and editor surfaces now get the same rows as a single drawing, moving under the same `motion` setting. The terminal keeps the card it had.
8
+ - A new `notify` option raises a notification through your own notification channel when LIT work completes or a LIT turn longer than three minutes ends. It is `off` unless you turn it on with `/config` or `litclaude-ai config notify finish`.
9
+ - The start-work gate no longer blocks read-only searches. It used to read a grep or rg pattern, a quoted phrase passed to a node script, or `litclaude-ai start-work status` as an unverified path and deny it. Patterns and plain words now count as data, while the searched paths are still checked against the work's grants.
10
+ - `litclaude-ai doctor` reports the card options before the Claude validation step.
11
+ - The README card pictures are retaken to show the workflow map and the detail line.
12
+
3
13
  ## 1.0.25 - 2026-10-12
4
14
 
5
15
  - The LIT card now moves while LitClaude is at work, so a glance tells you it is busy. The LIT pill and the border slowly glow from pink to flame orange and back, a light passes over the current phase and the skill chips of this request, and a spark runs along the top edge and back along the bottom one. When the turn ends the card goes still again. With the `motion` setting at `subtle` only the glow stays, and `off` keeps the card still.
package/README.md CHANGED
@@ -1,14 +1,14 @@
1
- <p align="center"><picture><source media="(prefers-reduced-motion: reduce)" srcset="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.25/docs/assets/cover-motion-still.webp" /><img src="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.25/docs/assets/cover-motion.webp" width="100%" alt="LitFamily motion cover: five armored robots power on one by one, the LitClaude robot wakes with glowing eyes and a lit frame, then LITFAMILY and KEEP THE WORK LIT. light up." /></picture></p>
1
+ <p align="center"><picture><source media="(prefers-reduced-motion: reduce)" srcset="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.26/docs/assets/cover-motion-still.webp" /><img src="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.26/docs/assets/cover-motion.webp" width="100%" alt="LitFamily motion cover: five armored robots power on one by one, the LitClaude robot wakes with glowing eyes and a lit frame, then LITFAMILY and KEEP THE WORK LIT. light up." /></picture></p>
2
2
 
3
3
  <h1 align="center">LitClaude</h1>
4
4
  <p align="center"><strong>Keep the work lit.</strong></p>
5
5
  <p align="center">A Claude Code plugin that helps every session plan the work, build it, check it, and leave a note the next session can pick up.</p>
6
6
  <p align="center">
7
- <img src="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.25/docs/assets/readme/badge-version.svg" alt="1.0.25" />
8
- <a href="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.25/LICENSE"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.25/docs/assets/readme/badge-license.svg" alt="MIT license" /></a>
7
+ <img src="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.26/docs/assets/readme/badge-version.svg" alt="1.0.26" />
8
+ <a href="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.26/LICENSE"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.26/docs/assets/readme/badge-license.svg" alt="MIT license" /></a>
9
9
  </p>
10
10
  <p align="center">
11
- <a href="https://github.com/wjgoarxiv/litclaude#readme">Full guide and skills gallery on GitHub</a> · <a href="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.25/README_ko-KR.md">한국어</a>
11
+ <a href="https://github.com/wjgoarxiv/litclaude#readme">Full guide and skills gallery on GitHub</a> · <a href="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.26/README_ko-KR.md">한국어</a>
12
12
  </p>
13
13
 
14
14
  Add `lit` to a Claude Code prompt and Claude pins the goal, writes a failing test first,
@@ -73,7 +73,7 @@ the `/plugin` menu.
73
73
  ## More
74
74
 
75
75
  - [Full guide and skills gallery on GitHub](https://github.com/wjgoarxiv/litclaude#readme)
76
- - [Privacy and network behavior](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.25/docs/privacy.md)
77
- - [Migration and ownership conflicts](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.25/docs/migration.md)
78
- - [Release history](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.25/CHANGELOG.md)
79
- - [MIT license](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.25/LICENSE)
76
+ - [Privacy and network behavior](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.26/docs/privacy.md)
77
+ - [Migration and ownership conflicts](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.26/docs/migration.md)
78
+ - [Release history](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.26/CHANGELOG.md)
79
+ - [MIT license](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.26/LICENSE)
package/README_ko-KR.md CHANGED
@@ -1,14 +1,14 @@
1
- <p align="center"><picture><source media="(prefers-reduced-motion: reduce)" srcset="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.25/docs/assets/cover-motion-still.webp" /><img src="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.25/docs/assets/cover-motion.webp" width="100%" alt="LitFamily 모션 커버: 다섯 로봇 패널이 차례로 켜지고, LitClaude 로봇의 눈과 테두리가 빛난 뒤 LITFAMILY와 KEEP THE WORK LIT. 문구가 밝아지는 영상" /></picture></p>
1
+ <p align="center"><picture><source media="(prefers-reduced-motion: reduce)" srcset="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.26/docs/assets/cover-motion-still.webp" /><img src="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.26/docs/assets/cover-motion.webp" width="100%" alt="LitFamily 모션 커버: 다섯 로봇 패널이 차례로 켜지고, LitClaude 로봇의 눈과 테두리가 빛난 뒤 LITFAMILY와 KEEP THE WORK LIT. 문구가 밝아지는 영상" /></picture></p>
2
2
 
3
3
  <h1 align="center">LitClaude</h1>
4
4
  <p align="center"><strong>Keep the work lit.</strong></p>
5
5
  <p align="center">Claude Code에서 세션마다 계획하고, 만들고, 확인한 뒤 다음 세션이 이어받을 기록을 남기게 돕는 플러그인입니다.</p>
6
6
  <p align="center">
7
- <img src="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.25/docs/assets/readme/badge-version.svg" alt="1.0.25" />
8
- <a href="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.25/LICENSE"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.25/docs/assets/readme/badge-license.svg" alt="MIT license" /></a>
7
+ <img src="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.26/docs/assets/readme/badge-version.svg" alt="1.0.26" />
8
+ <a href="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.26/LICENSE"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.26/docs/assets/readme/badge-license.svg" alt="MIT license" /></a>
9
9
  </p>
10
10
  <p align="center">
11
- <a href="https://github.com/wjgoarxiv/litclaude/blob/main/README_ko-KR.md">전체 안내와 스킬 갤러리는 GitHub에서</a> · <a href="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.25/README.md">English</a>
11
+ <a href="https://github.com/wjgoarxiv/litclaude/blob/main/README_ko-KR.md">전체 안내와 스킬 갤러리는 GitHub에서</a> · <a href="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.26/README.md">English</a>
12
12
  </p>
13
13
 
14
14
  Claude Code 프롬프트에 `lit`을 붙이면 Claude가 목표를 고정하고, 실패하는 테스트를 먼저 쓰고,
@@ -71,7 +71,7 @@ LitClaude는 프로젝트 상태를 `.litclaude/`에 두고, 그 안의 `.gitign
71
71
  ## 더 보기
72
72
 
73
73
  - [전체 안내와 스킬 갤러리 (GitHub)](https://github.com/wjgoarxiv/litclaude/blob/main/README_ko-KR.md)
74
- - [개인정보와 네트워크 동작](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.25/docs/privacy.md)
75
- - [이전과 소유권 충돌](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.25/docs/migration.md)
76
- - [변경 이력](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.25/CHANGELOG.md)
77
- - [MIT 라이선스](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.25/LICENSE)
74
+ - [개인정보와 네트워크 동작](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.26/docs/privacy.md)
75
+ - [이전과 소유권 충돌](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.26/docs/migration.md)
76
+ - [변경 이력](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.26/CHANGELOG.md)
77
+ - [MIT 라이선스](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.26/LICENSE)
@@ -39,6 +39,7 @@ import { runStartWorkContinuationCli } from "../plugins/litclaude/lib/start-work
39
39
  import { runStartWorkCli } from "../plugins/litclaude/lib/start-work-cli.mjs";
40
40
  import { runLitgoalCli } from "../plugins/litclaude/lib/litgoal/cli.mjs";
41
41
  import { runWorkflowCheckCli } from "../plugins/litclaude/lib/workflow-check.mjs";
42
+ import { runWorkflowStageCli } from "../plugins/litclaude/lib/workflow-stage.mjs";
42
43
  import { runWikifyKnowledgeCli } from "../plugins/litclaude/lib/wikify-knowledge-cli.mjs";
43
44
  import { automaticUpdateRoot, runAutomaticUpdate } from "../plugins/litclaude/lib/automatic-update.mjs";
44
45
  import { jevStatusLine } from "../plugins/litclaude/lib/jev-skill-hint.mjs";
@@ -81,14 +82,14 @@ const prewarmMotionRuntime = () => {
81
82
  };
82
83
  const version = packageJson.version;
83
84
 
84
- const usage = `Usage: litclaude-ai [--dry-run] <install|doctor|config|path|run|update|uninstall|litgoal|wikify|workflow-check|start-work|start-work-next|public-read|motion-runtime> [...args]
85
+ const usage = `Usage: litclaude-ai [--dry-run] <install|doctor|config|path|run|update|uninstall|litgoal|wikify|workflow-check|workflow-stage|start-work|start-work-next|public-read|motion-runtime> [...args]
85
86
  litclaude-ai --version
86
87
 
87
88
  Commands:
88
89
  install Register the packaged LitClaude plugin in Claude Code.
89
90
  doctor Validate the installed LitClaude plugin path.
90
91
  config [<option> <value>]
91
- Show or change the LIT card options (motion, glyphs, band) in
92
+ Show or change the LIT card options (motion, glyphs, band, notify) in
92
93
  pluginConfigs, the same values /config edits. Works for the
93
94
  desktop app too, which shows no editor for them.
94
95
  path Print the installed Claude plugin path.
@@ -98,6 +99,9 @@ Commands:
98
99
  workflow-check Verify Dynamic workflow, /goal, and subagent delegation readiness.
99
100
  start-work Manage schema-3 bounded-authority lifecycle state.
100
101
  start-work-next Print the next active start-work continuation directive.
102
+ workflow-stage <family> <stage> [--n N --total M --unit U --verdict name=pass]
103
+ Record where a review, loop, iteration or crucible run stands, for
104
+ the LIT card's workflow map (.litclaude/workflow-stage.json).
101
105
  public-read Read a public http(s) source with FetchAttempt/FetchVerdict JSON.
102
106
  motion-runtime Pre-warm (install [--audio] [--word-timing]) or report (status) the
103
107
  lit-typographic-motion runtime cache. Run it outside a sandboxed session.
@@ -383,7 +387,7 @@ const familyBanner = ({ color = shouldColorInstall() } = {}) => [
383
387
  ].join("\n");
384
388
 
385
389
  const printCommandBanner = (parsed) => {
386
- if (["install", "update"].includes(parsed.command)) return;
390
+ if (["install", "update", "workflow-stage"].includes(parsed.command)) return;
387
391
  if (parsed.rest.some((arg) => arg === "--json" || arg.startsWith("--json="))) return;
388
392
  const color = shouldColorInstall();
389
393
  process.stdout.write(`${renderLitClaudeWordmark({ color }).join("\n")}\n`);
@@ -1837,6 +1841,9 @@ const main = async () => {
1837
1841
  case "workflow-check":
1838
1842
  exitAfterFlush(runWorkflowCheckCli(root, version, parsed.rest));
1839
1843
  break;
1844
+ case "workflow-stage":
1845
+ exitAfterFlush(runWorkflowStageCli(parsed.rest, process.cwd()));
1846
+ break;
1840
1847
  case "public-read":
1841
1848
  exitAfterFlush(await runPublicRead(parsed));
1842
1849
  break;
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="146" height="20" role="img" aria-label="release: 1.0.25"><title>release: 1.0.25</title><g shape-rendering="crispEdges"><rect width="49" height="20" fill="#080d14"/><rect x="49" width="97" height="20" fill="#ff6337"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text x="255" y="140" textLength="390" transform="scale(.1)">release</text><text x="965" y="140" textLength="870" transform="scale(.1)" fill="#080D14">1.0.25</text></g></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="146" height="20" role="img" aria-label="release: 1.0.26"><title>release: 1.0.26</title><g shape-rendering="crispEdges"><rect width="49" height="20" fill="#080d14"/><rect x="49" width="97" height="20" fill="#ff6337"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text x="255" y="140" textLength="390" transform="scale(.1)">release</text><text x="965" y="140" textLength="870" transform="scale(.1)" fill="#080D14">1.0.26</text></g></svg>
package/docs/hooks.md CHANGED
@@ -105,10 +105,10 @@ silent no-op for callers that still invoke it directly.
105
105
  | `SessionStart` | `plugins/litclaude/bin/litclaude-hook.js session-start` | Runs the bounded foreground automatic-update barrier on a fresh session (or starts the detached version-cache refresh when the cache is stale), discovers repo-local rule files, names the newest valid `plans/<slug>.md`, and on `source: compact` spends one of two durable re-injection reservations at reduced caps and, with automatic handoff on, reloads the fresh handoff once. |
106
106
  | `UserPromptSubmit` | `plugins/litclaude/bin/litclaude-hook.js user-prompt-submit` | Detects prompt routes and injects workflow context; independently delivers static rules not already recorded for this session; with `LITCLAUDE_JEV=1` and `TYPESAFE_API_KEY` set, adds at most one Jev skill hint line to an unrouted turn; answers the exact prompts `lit-handoff auto on <percent>`, `lit-handoff auto off` and `lit-handoff auto status` by changing or reporting the automatic handoff setting. |
107
107
  | `PreToolUse` | `plugins/litclaude/bin/litclaude-hook.js pre-tool-use` | Enforces semantic action/root grants before Write, Edit, MultiEdit, NotebookEdit, Bash, Agent, and bounded read tools execute; denies supported reader-facing text writes with a humanizer block-tier finding. |
108
- | `PostToolUse` | `plugins/litclaude/bin/litclaude-hook.js post-tool-use` | Names the post-edit checks the edit actually earned, injects any glob-scoped rule matching the edited paths, and checks successfully created DOCX/PPTX/PDF files for humanizer findings, including paths reported by Bash output. |
108
+ | `PostToolUse` | `plugins/litclaude/bin/litclaude-hook.js post-tool-use` | Moves the LIT card's stage record on from what the tool did (plan saved, task checked, lit-loop step, a reviewer's verdict from an `Agent` result). Names the post-edit checks the edit actually earned, injects any glob-scoped rule matching the edited paths, and checks successfully created DOCX/PPTX/PDF files for humanizer findings, including paths reported by Bash output. |
109
109
  | `Stop` | `plugins/litclaude/bin/litclaude-hook.js stop` | Holds a lit-plan turn with no persisted plan and a lit workflow turn that edited interface files without a clean interface-probe run (each at most twice per turn), emits bounded start-work continuation on new progress, otherwise applies the opt-in litgoal autoloop gate, and last of all, with automatic handoff on, blocks once per crossing of the chosen percent to have the handoff written. |
110
110
  | `SubagentStart` | `plugins/litclaude/bin/litclaude-hook.js subagent-start` | Registers child-lane and Claude-owned worktree identity. |
111
- | `SubagentStop` | `plugins/litclaude/bin/litclaude-hook.js subagent-stop` | Finalizes the lane without child continuation. |
111
+ | `SubagentStop` | `plugins/litclaude/bin/litclaude-hook.js subagent-stop` | Finalizes the lane without child continuation, and gives a background review-work reviewer's verdict to the LIT card's stage record. |
112
112
  | `SessionEnd` | `plugins/litclaude/bin/litclaude-hook.js session-end` | Records root-session end without blocking Claude. |
113
113
 
114
114
  ### Changed-text humanizer guard
@@ -347,38 +347,74 @@ itself. LitClaude's is `plugins/litclaude/hooks/lit-mod.mjs`, named under `modul
347
347
  setup. The status line stays as it is; the band adds a live layer above the prompt.
348
348
 
349
349
  From the first prompt to the end of the session a LIT card sits above the prompt. It keeps the
350
- same four rows whether LitClaude is working or idle, and takes the status line's accent
350
+ same five rows whether LitClaude is working or idle, and takes the status line's accent
351
351
  (`LITCLAUDE_HUD_ACCENT`, read from the installed status line command), so the card and the
352
352
  status line read as one family:
353
353
 
354
354
  ```
355
- ╭─ [🔥 LIT] · lit-loop ─────────────────────────── WORK ● ─╮
356
- │ ● PLAN ━━ [WORK] ━━ ○ REVIEW goal ██░░░ 2/5 │
357
- │ skills [⚡ lit-plan] [⚡ litresearch] [↯ lit-docx] │
358
- ╰─ ctx 42% ▰▰▱▱▱ · 5h 31% · 1w 12% · git main ─────────────╯
355
+ ╭─ [🔥 LIT] · start-work ───────────────────────────────── WORK ● ─╮
356
+ │ interview ✓ ━━ plan ✓ ━━ [work 3/7] ━━ review · ── done · 1 lane │
357
+ │ └ task 3/7 ███░░░░░ · next ▸ 4. README demo - Bash · 0:12 │
358
+ │ skills [⚡ start-work] [↯ lit-plan] │
359
+ ╰─ ctx 42% ▰▰▱▱▱ · 5h 31% · 1w 12% · git main ─────────────────────╯
359
360
  ```
360
361
 
361
362
  The brackets stand for the ends of filled pills: rounded caps from the icon font with `nerd`
362
- glyphs, one cell of the pill's colour with `basic`. The brand is a pink pill, the active phase
363
+ glyphs, one cell of the pill's colour with `basic`. The brand is a pink pill, the current stage
363
364
  and the skills of this request are pills on the accent with dark text, and skills from earlier
364
365
  requests are muted grey pills.
365
366
 
366
367
  - The top edge names the discipline the prompt hook ignited (the last one, dimmed, while the
367
- session is idle; `ready` before any) and, on the right, the current phase: `WORK ●`, `idle`,
368
- or `DONE ✓` during the finish. While a subagent is still running the card stays at work
369
- (`LIVE ●` when no phase is active) and never reads `DONE`, even after the main turn ended.
370
- - The phase row lights `PLAN ━━ WORK ━━ REVIEW` from the start-work plan, the litgoal goal and
371
- the discipline (the active phase as a pill, done phases `●`, the rest `○`), and on its right shows a pink-to-cyan progress bar with the checked tasks or
372
- passed criteria (`goal ✓ 5/5` once a goal is met), the number of live subagents (`● 2 lanes`), the autoloop
373
- count with the time left in its 30-minute budget, and `ctx 76% → 80%` when the context is
374
- within five points of the auto-handoff percent.
375
- - The chips row shows each LitFamily skill that fired as a pill: a Skill tool call naming a LitClaude
368
+ session is idle; `ready` before any) and, on the right, the current stage: `WORK ●`, `RED ●`,
369
+ `idle`, or `DONE ✓` during the finish. While a subagent is still running the card stays at
370
+ work (`LIVE ●` when no stage is current) and never reads `DONE`, even after the main turn ended.
371
+ - The second row is the workflow map: where the session stands in its LIT family
372
+ (`lib/mod/workflow.mjs`). The main chain is `interview › plan › work n/m › review › done`
373
+ (litgoal criteria and autoresearch iterations ride the work stage); litresearch is
374
+ `decompose › wave n › expand › verify › synthesis`; a lit-loop criterion cycles
375
+ `PIN › RED › GREEN › VERIFY › REVIEW › RECORD` (SURFACE shows on VERIFY, CLEAN on RECORD).
376
+ Done stages carry `✓` in a colour graded along the rail from flame orange through pink to the
377
+ accent, the current stage is a pill, the stages ahead are dim `name ·`. The rail into the
378
+ current stage is solid `━`; the rail leaving it fills with the stage's count and, while
379
+ LitClaude works, carries a bright head; the rails ahead are dim `─`. On its right the row keeps
380
+ the live subagents (`● 2 lanes`), the autoloop count and its time left, and `ctx 76% → 80%` when
381
+ the context nears the auto-handoff percent. A session no family places (a lit-docx request, a
382
+ fresh session) keeps the old `PLAN ━━ WORK ━━ REVIEW` track there.
383
+ - The stage comes from the newest of the ignited discipline, a LitClaude skill this request
384
+ fired, and the stage record; with none of those, from the state that says work is under way.
385
+ The detail comes from files LitClaude already writes: the deep-interview state
386
+ (`round 3/12 · ambiguity 42% → 20%`), the lit-plan draft's approval gate (`drafting`,
387
+ `awaiting approval`), the start-work plan's tasks and next task, the litgoal criteria and the
388
+ litresearch session folder (`wave-*.md`, `verify-*.md`, `SYNTHESIS.md`). What no file
389
+ records goes into `.litclaude/workflow-stage.json`, a small record LitClaude's hooks keep
390
+ moving without the model's help. The prompt and PreToolUse hooks start it when lit-plan,
391
+ review-work, lit-loop, autoresearch or lit-crucible starts, and clear it for any other skill. PostToolUse checks the plan stage when lit-plan saves
392
+ `plans/<slug>.md` (`plan ✓`, detail `plan saved`), counts the tasks each time the active
393
+ start-work plan is edited (`work 1/2`), and steps a lit-loop criterion to RED when a test
394
+ file is written, GREEN when the code changes after it, VERIFY when the tests run and RECORD
395
+ when `litgoal record-evidence` runs. For review-work, PreToolUse marks a lane running when a
396
+ prompt titled `Review lane: <lane>.` is spawned, and the lane's `verdict:` line, read by
397
+ PostToolUse for a foreground reviewer and by SubagentStop for a background one, marks it
398
+ passed or failed. The card names the lanes `goal`, `quality`, `security`, `qa` and `context`
399
+ (review-work's scope/diff, package/payload, security/provenance, tests/evidence and
400
+ real-surface/docs lanes); five passes finish the review. The hooks keep only the stage, the
401
+ lane and the counts, never a path, command or prompt. The model can still refine the record
402
+ with `litclaude-ai workflow-stage <family> <stage> [--n --total --unit --verdict
403
+ name=pass|fail|pending|running]` for what the hooks cannot see: a lane run without a child
404
+ agent, a loop step such as SURFACE, an autoresearch iteration, the crucible verdict. Another
405
+ session's record is ignored and a source older than six hours no longer counts.
406
+ - The third row is the detail line: `└` and the current stage's detail (a pink-to-cyan bar for a
407
+ count, the lane verdicts as `✓`, `✗`, `●` while a reviewer runs, or `·`, the next task), and on the right the live step,
408
+ the tool the main loop is running and for how long (`- Bash · 0:12`, `thinking` between tool
409
+ calls). The step shows the tool's name and its clock only, never its arguments, command,
410
+ prompt or paths.
411
+ - The fourth row shows each LitFamily skill that fired as a pill: a Skill tool call naming a LitClaude
376
412
  skill, a typed `/litclaude:<name>`, or bare `lit` routing seen through the ignition record.
377
413
  A skill fired in the current request is bright, with a short light passing over its name as
378
414
  it arrives; when the turn completes it dims into the `recent` list, and a new firing brightens
379
415
  it again. Chips follow a dim `skills` label; those that do not fit collapse into a muted `+N`. Skills of other plugins never get a chip.
380
- With no chip yet, the row shows the next task while work runs, or how to start (`lit <task>`)
381
- while idle.
416
+ With no chip yet, the row shows the next task while work runs (when the detail line does not),
417
+ or how to start (`lit <task>`) while idle.
382
418
  - The bottom edge carries the live figures from the status line: context fill, the five-hour
383
419
  and weekly rate windows and the Git branch (read from `HEAD`, across a linked worktree).
384
420
  - A notice takes the chips row for a few seconds, with a toast, when a gate fires: lit-plan not
@@ -399,7 +435,9 @@ stops counting too, so a crashed or lost agent cannot hold the card at work.
399
435
 
400
436
  The card is the terminal's width up to 120 columns and every row is fitted to it, with Hangul and
401
437
  emoji counted as two cells. Nothing wraps: on a narrow terminal the Git branch goes first, then
402
- the weekly and five-hour windows, the lanes, the autoloop count and the long phase labels (`P ━ W ━ R`).
438
+ the weekly and five-hour windows, the lanes and the autoloop count. The map drops its rails, then
439
+ shortens the names (`int ✓ pla ✓ [wor 3/7] rev ·`), then shows only the current stage and its
440
+ neighbours; the review verdicts shorten to three letters and then to their marks.
403
441
 
404
442
  The spinner gains ` · <discipline> · n/m` after its ellipsis. `/lit-evidence` opens a pane with
405
443
  three tabs (keys `1`, `2`, `3`): the goal's criteria with their last evidence, blockers and the
@@ -410,18 +448,31 @@ changes ease in and out (300 ms and 140 ms), notices slide in over 220 ms and le
410
448
  a chip's arrival light runs 400 ms (a plain fade under `subtle`, nothing under `off`), and the
411
449
  finish lasts at most 1.2 s. While LitClaude is at work the card keeps moving so you can tell it
412
450
  is active at a glance: the LIT pill breathes from pink to flame orange every 2.4 s, a light sweeps
413
- across the active phase and this request's skill chips every 1.8 s, and a comet runs along the top rule and back along the
414
- bottom one every 2.6 s. Under `subtle` only the breathing stays; under `off` nothing moves. An
451
+ across the current stage and this request's skill chips every 1.8 s, a bright head runs the rail
452
+ leaving the current stage every 1.4 s, the count bar's head shimmers, and a comet runs along the
453
+ top rule and back along the bottom one every 2.6 s. Under `subtle` only the breathing stays; under `off` nothing moves. An
415
454
  idle card holds still. The band's `Client` element animates on Claude Code's frame clock, every
416
455
  33 ms while a transition plays and every 66 ms during work, and stops its timer once the card is
417
456
  idle and settled. In Claude
418
457
  Code 2.1.292 a terminal row whose only change is a non-ASCII glyph is not repainted, so every
419
458
  moving part changes ASCII text or colour: bar cells are coloured spaces, embers are ASCII sparks,
420
- a chip's light moves over its ASCII name, and a glyph swaps only together with its words.
459
+ a chip's light moves over its ASCII name, the map's `━` and `─` cells move by colour alone, the
460
+ step's spinner (`- \ | /`) and clock are ASCII, and a glyph swaps only together with its words.
461
+
462
+ The desktop app's Code tab, and the other surfaces that are not a terminal, draw a mod's `Text` in
463
+ a proportional font and cut each span to the cells it was laid out for, so the card above comes
464
+ apart there. On those surfaces the mod draws the same five rows as one `Svg` element instead
465
+ (`lib/mod/svg-card.mjs`): monospace text placed by counted cells, real pills and a rounded border.
466
+ It shows the settled state, with no entrances or crossfades. While LitClaude works it moves with
467
+ SMIL animation inside the drawing, which the surface runs in a script-less sandboxed frame: the
468
+ pill and the border breathe and the step's spinner turns, and on `full` a light crosses the
469
+ current stage and the current chips, a head runs the rail leaving it, the count bar's head
470
+ shimmers and a comet runs around the border. An idle card is a still image. The step's clock
471
+ moves with each new drawing, about every two seconds.
421
472
 
422
473
  Options, in `/config` under LitClaude (stored in `pluginConfigs` in `~/.claude/settings.json`,
423
474
  which the terminal and the desktop app's Code tab both read). The installer writes each default
424
- you have not set, so the desktop app, which has no editor for them, starts with all three;
475
+ you have not set, so the desktop app, which has no editor for them, starts with all four;
425
476
  `litclaude-ai config` prints them and `litclaude-ai config <option> <value>` changes one.
426
477
  Uninstall removes only the defaults it wrote that are still unchanged.
427
478
 
@@ -430,6 +481,7 @@ Uninstall removes only the defaults it wrote that are still unchanged.
430
481
  | `motion` | `full`, `subtle` (no overshoot, shimmer, embers, sweep or comet, shorter; the LIT pill still breathes during work), `off` (final frames only) | `full` |
431
482
  | `glyphs` | `auto` (Nerd glyphs when the icon font is installed), `nerd`, or `basic` | `auto` |
432
483
  | `band` | `always` (the whole session, idle included), `auto` (only while work is active or a skill of this request is lit), `off` | `always` |
484
+ | `notify` | `off`, `finish` (a notification through your own notification channel, `$.ui.notify`, when LIT work completes or a LIT turn longer than three minutes ends), `finish+sound` (the same; a sound is added once LitClaude ships one, and none ships yet) | `off` |
433
485
 
434
486
  Unknown values fall back to the default. The fields are plain strings with no `options` list on
435
487
  purpose: Claude Code 2.1.270 and older refuse to load a plugin whose `userConfig` has one, and
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@litfamily/litclaude",
3
- "version": "1.0.25",
3
+ "version": "1.0.26",
4
4
  "description": "Claude Code plugin: add lit to a prompt and Claude plans, tests, checks and reviews the work, then leaves a handoff for the next session.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "litclaude",
3
3
  "description": "Claude Code-native workflow plugin with a bounded-authority start-work lifecycle.",
4
- "version": "1.0.25",
4
+ "version": "1.0.26",
5
5
  "author": {
6
6
  "name": "LitClaude contributors"
7
7
  },
@@ -32,6 +32,12 @@
32
32
  "title": "LIT band",
33
33
  "description": "When the LIT card shows above the prompt: always (the whole session, idle included), auto (only while LitClaude work is active or a skill of this request is lit) or off.",
34
34
  "default": "always"
35
+ },
36
+ "notify": {
37
+ "type": "string",
38
+ "title": "LIT finish notification",
39
+ "description": "off, or finish: a notification through your own notification channel when LIT work completes or a LIT turn longer than three minutes ends. finish+sound also plays a sound once LitClaude ships one; until then it notifies like finish.",
40
+ "default": "off"
35
41
  }
36
42
  }
37
43
  }
@@ -6,6 +6,8 @@ import { fileURLToPath } from "node:url";
6
6
  import { standard, micro, colorMode, supportsBlocks } from "../lib/lit-mark.mjs";
7
7
  import { NEON_END, NEON_START, rainbowText } from "../lib/hud-accent-palette.mjs";
8
8
  import { ignitionMark, writeIgnitionState } from "../lib/hud-ignition.mjs";
9
+ import { DISCIPLINE_ENTRY } from "../lib/mod/workflow.mjs";
10
+ import { observeWorkflowPostTool, observeWorkflowPreTool, observeWorkflowSubagentStop, startWorkflowStage } from "../lib/workflow-stage.mjs";
9
11
  import { renameAliases, renameNote } from "../lib/rename-aliases.mjs";
10
12
  import { hasInterfaceModeWord, interfaceMode } from "../lib/interface-mode.mjs";
11
13
  import { transcriptHasContextPressure } from "../lib/context-pressure.mjs";
@@ -1322,6 +1324,13 @@ switch (eventName) {
1322
1324
  else clearLitPlanTurn(stateRoot);
1323
1325
  recordInterfaceProbeTurn(stateRoot, { sessionId: input.session_id, discipline: trigger?.safetyBlock ? null : trigger?.discipline });
1324
1326
  recordMotionTurn(stateRoot, { sessionId: input.session_id, discipline: trigger?.discipline });
1327
+ // The LIT card's stage record follows the discipline this prompt ignited: it starts over for a
1328
+ // skill only it can follow and is cleared for any other.
1329
+ // A typed `/litclaude:<skill>` is expanded by the host and never routes here, so its skill
1330
+ // is read off the prompt's first word.
1331
+ const typed = /^\/(?:litclaude:)?([a-z][a-z-]{0,40})(?=\s|$)/u.exec(prompt.trim())?.[1];
1332
+ const started = trigger?.discipline && !trigger.safetyBlock ? trigger.discipline : typed && Object.hasOwn(DISCIPLINE_ENTRY, typed) ? typed : null;
1333
+ if (started) startWorkflowStage(cwd, { sessionId: input.session_id, skill: started });
1325
1334
  } catch {
1326
1335
  // Persistence-gate state is advisory to routing; an unwritable record never alters the prompt hook.
1327
1336
  }
@@ -1407,6 +1416,13 @@ switch (eventName) {
1407
1416
  },
1408
1417
  }));
1409
1418
  } else {
1419
+ // The LIT card's stage record: a workflow skill starts it, a review lane's reviewer marks
1420
+ // its lane running.
1421
+ try {
1422
+ observeWorkflowPreTool(cwd, guardInput);
1423
+ } catch {
1424
+ // The stage record only feeds the card; a failed write never changes the tool decision.
1425
+ }
1410
1426
  let humanizerContext = "";
1411
1427
  try {
1412
1428
  const result = evaluateDeliverableHedgeGuard({ input: guardInput, pluginRoot });
@@ -1455,6 +1471,16 @@ switch (eventName) {
1455
1471
  case "post-tool-use": {
1456
1472
  const toolName = typeof input.tool_name === "string" ? input.tool_name : "unknown";
1457
1473
  const filePaths = extractMutatedFilePaths(input);
1474
+ // The LIT card's stage record moves on from what this tool did: the plan saved, a task checked
1475
+ // in the active plan, a lit-loop step, a reviewer's verdict.
1476
+ try {
1477
+ const cwd = typeof input.cwd === "string" ? input.cwd : process.cwd();
1478
+ observeWorkflowPostTool(cwd, input, { filePaths, lifecycleRoot: lifecycleRootFor(cwd) });
1479
+ } catch {
1480
+ // The stage record only feeds the card; a failed write never changes the tool's result.
1481
+ }
1482
+ // A reviewer's report only moves the card; the post-edit checks below are for writes.
1483
+ if (toolName === "Agent") break;
1458
1484
  try {
1459
1485
  const cwd = typeof input.cwd === "string" ? input.cwd : process.cwd();
1460
1486
  observeInterfaceProbeTool(resolveProjectStateRoot(cwd), { input, filePaths });
@@ -1545,6 +1571,11 @@ switch (eventName) {
1545
1571
  } catch {
1546
1572
  // SubagentStop remains continuation-inert; completion will fail closed on an active lane.
1547
1573
  }
1574
+ try {
1575
+ observeWorkflowSubagentStop(typeof input.cwd === "string" ? input.cwd : process.cwd(), input);
1576
+ } catch {
1577
+ // A background reviewer's verdict only feeds the card.
1578
+ }
1548
1579
  break;
1549
1580
  }
1550
1581
  case "session-end": {
@@ -9,7 +9,7 @@ import {
9
9
  } from "../lib/wikify-knowledge.mjs";
10
10
 
11
11
  const protocolVersion = "2024-11-05";
12
- const serverVersion = "1.0.25";
12
+ const serverVersion = "1.0.26";
13
13
 
14
14
  const publicSourceReadTool = {
15
15
  name: "public_source_read",
@@ -40,7 +40,7 @@
40
40
  ],
41
41
  "PostToolUse": [
42
42
  {
43
- "matcher": "^(Write|Edit|MultiEdit|NotebookEdit|Bash)$",
43
+ "matcher": "^(Write|Edit|MultiEdit|NotebookEdit|Bash|Agent)$",
44
44
  "hooks": [
45
45
  {
46
46
  "type": "command",