litclaude-ai 0.3.1 → 0.3.6
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 +75 -0
- package/README.md +5 -5
- package/README_ko-KR.md +5 -5
- package/RELEASE_CHECKLIST.md +8 -6
- package/cover.png +0 -0
- package/generate_cover.py +1 -1
- package/package.json +1 -1
- package/plugins/litclaude/.claude-plugin/plugin.json +1 -1
- package/plugins/litclaude/bin/litclaude-hook.js +34 -4
- package/plugins/litclaude/commands/dynamic-workflow.md +6 -6
- package/plugins/litclaude/commands/review-work.md +5 -5
- package/plugins/litclaude/hooks/hooks.json +12 -0
- package/plugins/litclaude/lib/litgoal/autoloop.mjs +78 -0
- package/plugins/litclaude/lib/litgoal/cli.mjs +8 -0
- package/plugins/litclaude/skills/git-master/SKILL.md +130 -0
- package/plugins/litclaude/skills/init-deep/SKILL.md +196 -0
- package/plugins/litclaude/skills/lit-loop/SKILL.md +12 -10
- package/plugins/litclaude/skills/lit-plan/SKILL.md +9 -10
- package/plugins/litclaude/skills/litgoal/SKILL.md +41 -5
- package/plugins/litclaude/skills/lsp-setup/SKILL.md +151 -0
- package/plugins/litclaude/skills/lsp-setup/references/bash/README.md +63 -0
- package/plugins/litclaude/skills/lsp-setup/references/c-cpp/README.md +72 -0
- package/plugins/litclaude/skills/lsp-setup/references/csharp/README.md +81 -0
- package/plugins/litclaude/skills/lsp-setup/references/dart/README.md +53 -0
- package/plugins/litclaude/skills/lsp-setup/references/elixir/README.md +57 -0
- package/plugins/litclaude/skills/lsp-setup/references/go/README.md +59 -0
- package/plugins/litclaude/skills/lsp-setup/references/haskell/README.md +64 -0
- package/plugins/litclaude/skills/lsp-setup/references/java/README.md +66 -0
- package/plugins/litclaude/skills/lsp-setup/references/julia/README.md +62 -0
- package/plugins/litclaude/skills/lsp-setup/references/kotlin/README.md +68 -0
- package/plugins/litclaude/skills/lsp-setup/references/lua/README.md +64 -0
- package/plugins/litclaude/skills/lsp-setup/references/php/README.md +56 -0
- package/plugins/litclaude/skills/lsp-setup/references/python/README.md +68 -0
- package/plugins/litclaude/skills/lsp-setup/references/ruby/README.md +62 -0
- package/plugins/litclaude/skills/lsp-setup/references/rust/README.md +61 -0
- package/plugins/litclaude/skills/lsp-setup/references/swift/README.md +60 -0
- package/plugins/litclaude/skills/lsp-setup/references/terraform/README.md +61 -0
- package/plugins/litclaude/skills/lsp-setup/references/typescript/README.md +77 -0
- package/plugins/litclaude/skills/lsp-setup/references/yaml/README.md +60 -0
- package/plugins/litclaude/skills/lsp-setup/references/zig/README.md +55 -0
- package/plugins/litclaude/skills/lsp-setup/scripts/detect-lsp.ts +220 -0
- package/plugins/litclaude/skills/lsp-setup/scripts/lsp-server-table.ts +146 -0
- package/plugins/litclaude/skills/lsp-setup/scripts/tsconfig.json +18 -0
- package/plugins/litclaude/skills/lsp-setup/scripts/verify-lsp.ts +242 -0
- package/plugins/litclaude/skills/start-work/SKILL.md +12 -13
- package/plugins/litclaude/skills/visual-qa/SKILL.md +259 -0
- package/plugins/litclaude/skills/visual-qa/scripts/ansi.ts +17 -0
- package/plugins/litclaude/skills/visual-qa/scripts/cli.ts +96 -0
- package/plugins/litclaude/skills/visual-qa/scripts/east-asian-width.ts +72 -0
- package/plugins/litclaude/skills/visual-qa/scripts/image-diff.ts +109 -0
- package/plugins/litclaude/skills/visual-qa/scripts/png-crc.ts +27 -0
- package/plugins/litclaude/skills/visual-qa/scripts/png-decode.ts +206 -0
- package/plugins/litclaude/skills/visual-qa/scripts/png-synth.ts +57 -0
- package/plugins/litclaude/skills/visual-qa/scripts/tui-grid.ts +88 -0
- package/plugins/litclaude/skills/visual-qa/scripts/types.ts +54 -0
- package/scripts/qa-portable-install.sh +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,80 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.6 - 2026-06-14 — litgoal autoloop: a plugin-owned `/goal`-equivalent
|
|
4
|
+
|
|
5
|
+
- Add **litgoal autoloop** — a plugin-owned `Stop` hook
|
|
6
|
+
(`plugins/litclaude/hooks/hooks.json` + `bin/litclaude-hook.js` `case "stop"`) that reproduces
|
|
7
|
+
Claude Code `/goal`'s autonomous keep-running behavior **under plugin control**, driven entirely
|
|
8
|
+
by the durable litgoal ledger. The model arms it with
|
|
9
|
+
`litclaude-ai litgoal create-goals --brief "…" --autoloop`; on every Stop event the hook reads
|
|
10
|
+
`.litclaude/litgoal/goals.json` and returns `decision: block` with a snapshot of the remaining
|
|
11
|
+
criteria until **all criteria deterministically pass**, then allows the session to stop. This
|
|
12
|
+
enables a `/goal`-equivalent execution loop via LitClaude skills + hooks **without the user typing
|
|
13
|
+
`/goal`** (which is architecturally impossible for a plugin to invoke — see 0.3.5).
|
|
14
|
+
- Completion is a **pure function of recorded evidence** (stricter than the native small-model
|
|
15
|
+
evaluator — it cannot be faked). New `lib/litgoal/autoloop.mjs` exposes a side-effect-free
|
|
16
|
+
`evaluateAutoloop()` decision function plus a durable iteration counter (`autoloop.json`).
|
|
17
|
+
- **Four independent safety brakes** so the loop can never trap a session: opt-in `--autoloop`
|
|
18
|
+
(default off — ordinary goals never block); `LITCLAUDE_GOAL_OFF=1` env kill switch; a durable hard
|
|
19
|
+
cap (8 blocks / 30 min → `continue:false`); and fail-safe behavior (any unreadable ledger or
|
|
20
|
+
un-writable counter ALLOWS stopping). Escape via `checkpoint --status blocked`/`--status complete`.
|
|
21
|
+
- Design + adversarial review captured in `docs/design/litclaude-goal-autoloop-design.md` (internal).
|
|
22
|
+
Adds 13 tests (`test/litgoal-autoloop.test.mjs`) covering the decision function and the spawned hook.
|
|
23
|
+
|
|
24
|
+
## 0.3.5 - 2026-06-14 — correct the native `/goal` integration guidance
|
|
25
|
+
|
|
26
|
+
- Fix the native-goal guidance to match Claude Code reality. Claude Code's `/goal` (v2.1.139+) is a
|
|
27
|
+
**user-typed slash command** that sets an autonomous completion condition — it is **not a
|
|
28
|
+
model-facing tool**, and a hook or skill **cannot invoke it**. The previous guidance led with a
|
|
29
|
+
`get_goal`/`create_goal`/`update_goal` "native goal tool" path that does not exist in any current
|
|
30
|
+
Claude Code (a residue of the upstream Codex lineage), which buried the only real mechanism.
|
|
31
|
+
- Now, when a goal is worth binding (hook injection on `lit`/`litwork`/`/litgoal`, and the `lit-loop`,
|
|
32
|
+
`lit-plan`, `start-work`, `litgoal` skills), LitClaude **proposes a concrete, ready-to-paste
|
|
33
|
+
`/goal <completion condition>`** for the user and keeps the durable record in the local litgoal
|
|
34
|
+
ledger. The `get_goal`/`create_goal`/`update_goal` path is retained only as an explicit
|
|
35
|
+
forward-compat note ("if a future Claude Code build exposes model-facing goal tools, prefer them —
|
|
36
|
+
none are exposed today"). LitClaude still never auto-types or sends `/goal`.
|
|
37
|
+
|
|
38
|
+
## 0.3.4 - 2026-06-14 — port visual-qa + lsp-setup; fix subagent namespace; recompress cover
|
|
39
|
+
|
|
40
|
+
- Add the `visual-qa` skill (`plugins/litclaude/skills/visual-qa/`), a Claude-adapted port of the
|
|
41
|
+
reference dual-oracle visual QA: a bundled, dependency-free diff toolchain (PNG CRC/decoder,
|
|
42
|
+
image-diff, ANSI + East-Asian-width, tui-grid, cli) plus two parallel read-only oracle passes
|
|
43
|
+
(design-system + functional integrity; visual fidelity + CJK precision) synthesized into one
|
|
44
|
+
verdict. Scripts run under Node 22.6+ (`--experimental-strip-types`) or bun, no install.
|
|
45
|
+
- Add the `lsp-setup` skill (`plugins/litclaude/skills/lsp-setup/`), a Claude-adapted multi-language
|
|
46
|
+
LSP configurator: routes by file extension to `references/<lang>/README.md` for 20 languages
|
|
47
|
+
(server choice, per-OS install, `.lsp.json` snippet, troubleshooting) and ships `detect-lsp.ts` +
|
|
48
|
+
`verify-lsp.ts` (a real JSON-RPC diagnostics roundtrip) wired to LitClaude's `plugins/litclaude/
|
|
49
|
+
.lsp.json`. Complements the existing quick-path `lsp` skill.
|
|
50
|
+
- **Fix subagent-delegation guidance** to use the `litclaude:` namespace. The injected hook text and
|
|
51
|
+
the `dynamic-workflow` / `review-work` command docs now reference `litclaude:boulder-executor`,
|
|
52
|
+
`litclaude:prometheus-planner`, etc. (the actual exposed `subagent_type`) instead of bare names that
|
|
53
|
+
raised "Agent type 'boulder-executor' not found" when spawned literally.
|
|
54
|
+
- Losslessly recompress `cover.png` (2560×1280 preserved; ~3.74 MB → ~3.56 MB) and add
|
|
55
|
+
`optimize=True, compress_level=9` to `generate_cover.py` so the generator emits the optimized form.
|
|
56
|
+
|
|
57
|
+
## 0.3.3 - 2026-06-14 — port the init-deep skill
|
|
58
|
+
|
|
59
|
+
- Add the `init-deep` skill (`plugins/litclaude/skills/init-deep/`), a Claude-adapted port of the
|
|
60
|
+
reference hierarchical AGENTS.md generator: discovery → score → generate → review, with dynamic
|
|
61
|
+
explore-subagent scaling, a weighted scoring matrix, AGENTS.md templates, and quality gates. All
|
|
62
|
+
reference orchestration/LSP calls are re-authored to Claude Code surfaces (`Agent`/`Task` background
|
|
63
|
+
subagents, the `LSP` tool, `Workflow` for parallel generation, `TodoWrite`) — no literal calls to
|
|
64
|
+
missing tools, no Codex/opencode tokens.
|
|
65
|
+
- Add `plans/litclaude-reference-parity-sdd.md`: a decision-complete SDD plan capturing the full
|
|
66
|
+
OmO-reference parity audit (all 11 shared skills + both auxiliary packs are byte-identical) and the
|
|
67
|
+
remaining portable ports (`init-deep` done; `visual-qa` and `lsp-setup` planned), plus a verified
|
|
68
|
+
deliberate-omission (N/A) registry. Allowlisted as a non-shipped doc-class file.
|
|
69
|
+
|
|
70
|
+
## 0.3.2 - 2026-06-14 — port the git-master skill
|
|
71
|
+
|
|
72
|
+
- Add the `git-master` skill (`plugins/litclaude/skills/git-master/`), a Claude-adapted port of the
|
|
73
|
+
reference git-history specialist: mode-gated COMMIT / REBASE / HISTORY / STATUS workflows, atomic
|
|
74
|
+
commit grouping with local message-style detection, `--force-with-lease` rebase safety, and
|
|
75
|
+
`git log -S/-G` / `blame` / `bisect` / `reflog` history investigation. Aligned with LitClaude's
|
|
76
|
+
publish boundary — no commit/push/history rewrite without explicit user authorization.
|
|
77
|
+
|
|
3
78
|
## 0.3.1 - 2026-06-14 — neon-HUD truecolor detection on Windows Terminal / WSL2
|
|
4
79
|
|
|
5
80
|
- Fix the `[🔥LITCLAUDE]` HUD falling back to flat 256-color magenta in Windows Terminal under WSL2.
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
</p>
|
|
10
10
|
<p align="center">
|
|
11
11
|
<img src="https://img.shields.io/badge/npm-litclaude--ai-cb3837" />
|
|
12
|
-
<img src="https://img.shields.io/badge/version-0.3.
|
|
12
|
+
<img src="https://img.shields.io/badge/version-0.3.6-2ea44f" />
|
|
13
13
|
<img src="https://img.shields.io/badge/Claude%20Code-plugin-blueviolet" />
|
|
14
14
|
<img src="https://img.shields.io/badge/license-MIT-blue" />
|
|
15
15
|
</p>
|
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
> `litclaude@litclaude-ai`, so normal `claude` launches can load the
|
|
23
23
|
> LitClaude skills and hooks without a long `--plugin-dir` command.
|
|
24
24
|
|
|
25
|
-
This checkout is prepared as `litclaude-ai@0.3.
|
|
25
|
+
This checkout is prepared as `litclaude-ai@0.3.6` for personal install
|
|
26
26
|
convenience. The repo can remain quiet; preparing npm package metadata here does
|
|
27
27
|
not imply public repo promotion, marketplace publication, or advertisement.
|
|
28
|
-
Future package releases still require explicit user approval. The v0.3.
|
|
28
|
+
Future package releases still require explicit user approval. The v0.3.6
|
|
29
29
|
release materials preserve the v0.2.2 Dynamic workflow hardening work, add the
|
|
30
30
|
lit-family vocab rename and neon HUD on top of v0.2.2, describe LitClaude in
|
|
31
31
|
its own terms, and do not claim that npm publication has completed.
|
|
@@ -93,7 +93,7 @@ directory, the normal install command works:
|
|
|
93
93
|
|
|
94
94
|
```bash
|
|
95
95
|
cd /tmp
|
|
96
|
-
npx --yes litclaude-ai@0.3.
|
|
96
|
+
npx --yes litclaude-ai@0.3.6 install
|
|
97
97
|
```
|
|
98
98
|
|
|
99
99
|
Validate the installed plugin:
|
|
@@ -106,7 +106,7 @@ The installer also sets Claude Code's `statusLine` command to the packaged
|
|
|
106
106
|
LitClaude HUD. A typical no-color render starts like:
|
|
107
107
|
|
|
108
108
|
```text
|
|
109
|
-
[🔥LITCLAUDE v0.3.
|
|
109
|
+
[🔥LITCLAUDE v0.3.6] | O4.8 │ ctx [▎░░] 9%/1000k │ 5h [▏░] 4% ↻2h15m │ 1w [▊░] 35% ↻3d6h │ git main +3 ✓
|
|
110
110
|
```
|
|
111
111
|
|
|
112
112
|
The `↻` suffix is a compact rate-limit reset countdown. It is separated from
|
package/README_ko-KR.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
</p>
|
|
10
10
|
<p align="center">
|
|
11
11
|
<img src="https://img.shields.io/badge/npm-litclaude--ai-cb3837" />
|
|
12
|
-
<img src="https://img.shields.io/badge/version-0.3.
|
|
12
|
+
<img src="https://img.shields.io/badge/version-0.3.6-2ea44f" />
|
|
13
13
|
<img src="https://img.shields.io/badge/Claude%20Code-plugin-blueviolet" />
|
|
14
14
|
<img src="https://img.shields.io/badge/license-MIT-blue" />
|
|
15
15
|
</p>
|
|
@@ -26,11 +26,11 @@
|
|
|
26
26
|
> 설치되므로, 매번 긴 `--plugin-dir` 없이 일반 `claude` 실행에서
|
|
27
27
|
> LitClaude skill과 hook을 불러올 수 있습니다.
|
|
28
28
|
|
|
29
|
-
현재 checkout은 `litclaude-ai@0.3.
|
|
29
|
+
현재 checkout은 `litclaude-ai@0.3.6` 배포 준비용으로 정리되어 있습니다. 목적은
|
|
30
30
|
다른 PC에서도 빠르게 설치하기 위한 개인용 package metadata를 갖추는 것입니다.
|
|
31
31
|
npm package metadata를 준비했다고 해서 홍보, 공개 저장소 운영, Claude
|
|
32
32
|
marketplace 등록을 의미하지는 않습니다. 새 버전 배포는 항상 별도의 명시적
|
|
33
|
-
승인 후에 진행합니다. v0.3.
|
|
33
|
+
승인 후에 진행합니다. v0.3.6 release material은 v0.2.2 Dynamic workflow
|
|
34
34
|
hardening을 보존하고, lit-family vocab rename과 neon HUD를 추가하며,
|
|
35
35
|
LitClaude 자체의 표현으로 정리되어 있습니다. npm publish가 완료됐다고
|
|
36
36
|
주장하지 않습니다.
|
|
@@ -98,7 +98,7 @@ checkout을 먼저 해석해서 `sh: litclaude-ai: command not found`로 실패
|
|
|
98
98
|
|
|
99
99
|
```bash
|
|
100
100
|
cd /tmp
|
|
101
|
-
npx --yes litclaude-ai@0.3.
|
|
101
|
+
npx --yes litclaude-ai@0.3.6 install
|
|
102
102
|
```
|
|
103
103
|
|
|
104
104
|
설치 상태를 확인합니다.
|
|
@@ -111,7 +111,7 @@ installer는 Claude Code의 `statusLine` command도 packaged LitClaude HUD로
|
|
|
111
111
|
설정합니다. 색상을 제거한 예시는 다음처럼 시작합니다.
|
|
112
112
|
|
|
113
113
|
```text
|
|
114
|
-
[🔥LITCLAUDE v0.3.
|
|
114
|
+
[🔥LITCLAUDE v0.3.6] | O4.8 │ ctx [▎░░] 9%/1000k │ 5h [▏░] 4% ↻2h15m │ 1w [▊░] 35% ↻3d6h │ git main +3 ✓
|
|
115
115
|
```
|
|
116
116
|
|
|
117
117
|
`↻` 표시는 rate-limit reset까지 남은 시간을 짧게 보여주는 countdown입니다.
|
package/RELEASE_CHECKLIST.md
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
# LitClaude Release Checklist
|
|
2
2
|
|
|
3
|
-
Status: `litclaude-ai@0.3.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
Status: `litclaude-ai@0.3.6` is the current release candidate — adds **litgoal autoloop**: a
|
|
4
|
+
plugin-owned `Stop` hook bound to the litgoal ledger that reproduces `/goal`'s autonomous
|
|
5
|
+
keep-running behavior under plugin control (opt-in `--autoloop`, default off, deterministic
|
|
6
|
+
completion, 4 safety brakes). Enables `/goal`-equivalent execution via LitClaude skills + hooks.
|
|
7
|
+
`package.json` is aligned to `0.3.6`, and
|
|
8
|
+
`plugins/litclaude/.claude-plugin/plugin.json` is aligned to `0.3.6`.
|
|
7
9
|
|
|
8
10
|
This release carries the v0.2.2 Dynamic workflow hardening surfaces:
|
|
9
11
|
`/dynamic-workflow`, `workflow-check --json`, native `/goal` fallback guidance,
|
|
@@ -52,8 +54,8 @@ No npm publication is required for this track.
|
|
|
52
54
|
Before requesting publication approval, confirm these artifacts from the current
|
|
53
55
|
checkout:
|
|
54
56
|
|
|
55
|
-
- `package.json` version is `0.3.
|
|
56
|
-
- `plugins/litclaude/.claude-plugin/plugin.json` version is `0.3.
|
|
57
|
+
- `package.json` version is `0.3.6`.
|
|
58
|
+
- `plugins/litclaude/.claude-plugin/plugin.json` version is `0.3.6`.
|
|
57
59
|
- `plugins/litclaude/commands/dynamic-workflow.md` documents subagent delegation.
|
|
58
60
|
- `node bin/litclaude-ai.js workflow-check --json` reports `status: pass`.
|
|
59
61
|
- `node bin/litclaude-ai.js workflow-check --json` reports
|
package/cover.png
CHANGED
|
Binary file
|
package/generate_cover.py
CHANGED
|
@@ -113,7 +113,7 @@ def main() -> None:
|
|
|
113
113
|
ImageDraw.Draw(mask).rounded_rectangle([(0, 0), (WIDTH - 1, HEIGHT - 1)], radius=CORNER_RADIUS, fill=255)
|
|
114
114
|
canvas.putalpha(mask)
|
|
115
115
|
canvas = canvas.filter(ImageFilter.GaussianBlur(radius=1))
|
|
116
|
-
canvas.save(OUT_PATH, "PNG", dpi=(400, 400))
|
|
116
|
+
canvas.save(OUT_PATH, "PNG", dpi=(400, 400), optimize=True, compress_level=9)
|
|
117
117
|
print(f"Saved: {OUT_PATH}")
|
|
118
118
|
print(f"Size: {canvas.size}")
|
|
119
119
|
print(f"Mode: {canvas.mode}")
|
package/package.json
CHANGED
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
4
|
import { transcriptHasContextPressure } from "../lib/context-pressure.mjs";
|
|
5
5
|
import { extractMutatedFilePaths } from "../lib/mutated-file-paths.mjs";
|
|
6
|
+
import { litgoalGoalsPath } from "../lib/litgoal/paths.mjs";
|
|
7
|
+
import { readLitgoalState } from "../lib/litgoal/state.mjs";
|
|
8
|
+
import { evaluateAutoloop, readAutoloopState, writeAutoloopState } from "../lib/litgoal/autoloop.mjs";
|
|
6
9
|
|
|
7
10
|
const eventName = process.argv[2] ?? "";
|
|
8
11
|
|
|
@@ -21,6 +24,7 @@ const hookEventNames = {
|
|
|
21
24
|
"user-prompt-submit": "UserPromptSubmit",
|
|
22
25
|
"post-tool-use": "PostToolUse",
|
|
23
26
|
"post-compact": "PostCompact",
|
|
27
|
+
"stop": "Stop",
|
|
24
28
|
};
|
|
25
29
|
|
|
26
30
|
const writeContext = (additionalContext, systemMessage) => {
|
|
@@ -61,12 +65,12 @@ const litworkContext = ({ command, skill, discipline, softConfirm }) => [
|
|
|
61
65
|
discipline === "deep-interview" ? "DEEP INTERVIEW MODE ENABLED." : "LITWORK MODE ENABLED.",
|
|
62
66
|
`Treat this prompt as an explicit request to use LitClaude ${discipline} discipline now; load or follow ${command} / ${skill} semantics before ordinary task execution.`,
|
|
63
67
|
"Use evidence-bound planning, tests, manual QA, and cleanup receipts.",
|
|
64
|
-
"Native goal
|
|
65
|
-
"
|
|
66
|
-
"Do not auto-type or inject the user's slash commands; treat /goal as Claude Code's native
|
|
68
|
+
"Native goal binding (read this first): Claude Code's /goal (v2.1.139+) is a USER-TYPED slash command that sets an autonomous completion condition — a hook or skill CANNOT invoke it, and Claude Code currently exposes NO model-facing goal tools. So the real path is: when a goal is worth binding, propose a concrete, ready-to-paste /goal <completion condition> for the user, and keep driving the LitClaude evidence ledger meanwhile.",
|
|
69
|
+
"Forward-compat goal tools: if a future Claude Code build does expose model-facing goal tools, prefer them — first inspect get_goal, call create_goal with an objective-only payload when no matching goal is active, and reserve update_goal for verified completion or a genuine blocker. These are unavailable / not exposed today, so the /goal proposal above is the actual mechanism.",
|
|
70
|
+
"Do not auto-type or inject the user's slash commands; LitClaude does not auto-type /goal — treat /goal as Claude Code's native user surface, not as prompt text for this hook to send.",
|
|
67
71
|
"Dynamic workflow integration: when Claude Code exposes the Workflow tool and the task is broad, risky, parallel, or long-running, call the Workflow tool before serial execution and bind each lane to explicit criteria, artifacts, and cleanup receipts.",
|
|
68
72
|
"Dynamic worktree integration: when Claude Code exposes EnterWorktree and isolated edits are needed, use EnterWorktree for the selected lane; otherwise use or recommend claude --worktree <short-name> --tmux. Never mutate unrelated user state.",
|
|
69
|
-
"Subagent delegation: route planning to prometheus-planner, implementation to boulder-executor, verification to oracle-verifier, hands-on QA to qa-runner, code/security review to quality-reviewer, and local-first research to librarian-researcher when Claude Code subagents or Dynamic workflow lanes are available.",
|
|
73
|
+
"Subagent delegation: route planning to litclaude:prometheus-planner, implementation to litclaude:boulder-executor, verification to litclaude:oracle-verifier, hands-on QA to litclaude:qa-runner, code/security review to litclaude:quality-reviewer, and local-first research to litclaude:librarian-researcher when Claude Code subagents or Dynamic workflow lanes are available. LitClaude subagents are exposed under the litclaude: namespace, so pass the exact namespaced id (e.g. litclaude:boulder-executor) as the Agent/Task tool subagent_type, not the bare name.",
|
|
70
74
|
"Subagent reliability: each child assignment starts with TASK: and includes DELIVERABLE, SCOPE, and VERIFY; use short wait cycles, treat timeouts as no-update signals, and fallback only after a missing deliverable, acknowledgement-only reply, or BLOCKED: report.",
|
|
71
75
|
...(softConfirm ? ["Soft-confirm: the bare keyword 'lit' activated this hook. Before committing to the full lit-loop, briefly confirm with the user that they intended to start a litwork execution loop (a stray English 'lit' is recoverable)."] : []),
|
|
72
76
|
].join(" ");
|
|
@@ -103,6 +107,32 @@ switch (eventName) {
|
|
|
103
107
|
writeContext("LitClaude rule cache reset after compaction.");
|
|
104
108
|
break;
|
|
105
109
|
}
|
|
110
|
+
case "stop": {
|
|
111
|
+
// LitClaude litgoal autoloop — a /goal-EQUIVALENT autonomous completion loop
|
|
112
|
+
// driven entirely by the durable litgoal ledger (no native /goal typing needed).
|
|
113
|
+
// Default-OFF: only engages when the active goal was created with `--autoloop`.
|
|
114
|
+
// Fail-SAFE everywhere: any unreadable ledger, missing/over-cap counter, or write
|
|
115
|
+
// failure ALLOWS stopping (empty output) rather than risk trapping the session.
|
|
116
|
+
let decision;
|
|
117
|
+
try {
|
|
118
|
+
const cwd = typeof input.cwd === "string" ? input.cwd : process.cwd();
|
|
119
|
+
const state = readLitgoalState(litgoalGoalsPath(cwd), null);
|
|
120
|
+
const autoloopState = readAutoloopState(cwd);
|
|
121
|
+
decision = evaluateAutoloop({ env: process.env, state, autoloopState });
|
|
122
|
+
if (decision.action === "block") {
|
|
123
|
+
// Durably bound the loop BEFORE blocking; if we cannot persist the counter,
|
|
124
|
+
// fail safe and allow the stop instead of risking an unbounded loop.
|
|
125
|
+
writeAutoloopState(cwd, { blockCount: decision.nextCount, firstBlockAt: decision.firstBlockAt });
|
|
126
|
+
console.log(JSON.stringify({ decision: "block", reason: decision.reason }));
|
|
127
|
+
} else if (decision.action === "cap") {
|
|
128
|
+
console.log(JSON.stringify({ continue: false, stopReason: decision.stopReason }));
|
|
129
|
+
}
|
|
130
|
+
// action === "allow" (or counter write failed below): emit nothing -> stop is allowed.
|
|
131
|
+
} catch {
|
|
132
|
+
// Any error -> allow stop (no output).
|
|
133
|
+
}
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
106
136
|
default: {
|
|
107
137
|
console.error(`unknown hook event: ${eventName || "(missing)"}`);
|
|
108
138
|
process.exit(64);
|
|
@@ -18,12 +18,12 @@ Dynamic-workflow bootstrap first.
|
|
|
18
18
|
when Claude Code exposes it. Bind each lane to success criteria, evidence
|
|
19
19
|
artifacts, and cleanup receipts.
|
|
20
20
|
4. Use subagent delegation where available:
|
|
21
|
-
- `prometheus-planner` for read-only planning and dependency ordering.
|
|
22
|
-
- `boulder-executor` for implementation against a checked plan.
|
|
23
|
-
- `oracle-verifier` for evidence and acceptance verification.
|
|
24
|
-
- `qa-runner` for tmux/manual-QA scenarios and cleanup receipts.
|
|
25
|
-
- `quality-reviewer` for code-quality and security findings.
|
|
26
|
-
- `librarian-researcher` for local-first context mining.
|
|
21
|
+
- `litclaude:prometheus-planner` for read-only planning and dependency ordering.
|
|
22
|
+
- `litclaude:boulder-executor` for implementation against a checked plan.
|
|
23
|
+
- `litclaude:oracle-verifier` for evidence and acceptance verification.
|
|
24
|
+
- `litclaude:qa-runner` for tmux/manual-QA scenarios and cleanup receipts.
|
|
25
|
+
- `litclaude:quality-reviewer` for code-quality and security findings.
|
|
26
|
+
- `litclaude:librarian-researcher` for local-first context mining.
|
|
27
27
|
Each child assignment starts with `TASK:` and includes `DELIVERABLE`,
|
|
28
28
|
`SCOPE`, and `VERIFY`. Use short wait cycles; treat timeouts as no-update
|
|
29
29
|
signals, and fallback only after a missing deliverable, acknowledgement-only
|
|
@@ -17,14 +17,14 @@ other remote mutation still need explicit user approval.
|
|
|
17
17
|
|
|
18
18
|
Lane routing:
|
|
19
19
|
|
|
20
|
-
- goal and constraint verification: use `oracle-verifier` with `review-work`
|
|
20
|
+
- goal and constraint verification: use `litclaude:oracle-verifier` with `review-work`
|
|
21
21
|
and `rules`.
|
|
22
|
-
- hands-on QA execution: use `qa-runner` with `start-work` and `review-work`.
|
|
23
|
-
- code quality review: use `quality-reviewer` with `review-work` and
|
|
22
|
+
- hands-on QA execution: use `litclaude:qa-runner` with `start-work` and `review-work`.
|
|
23
|
+
- code quality review: use `litclaude:quality-reviewer` with `review-work` and
|
|
24
24
|
`programming`.
|
|
25
|
-
- security review: use `quality-reviewer` with `review-work` and
|
|
25
|
+
- security review: use `litclaude:quality-reviewer` with `review-work` and
|
|
26
26
|
`programming`.
|
|
27
|
-
- local-first context mining: use `librarian-researcher` with `rules`.
|
|
27
|
+
- local-first context mining: use `litclaude:librarian-researcher` with `rules`.
|
|
28
28
|
|
|
29
29
|
Before launching broad review work, check whether native goal tools are
|
|
30
30
|
available and bind the review to the active goal. If goal tools are unavailable,
|
|
@@ -49,6 +49,18 @@
|
|
|
49
49
|
}
|
|
50
50
|
]
|
|
51
51
|
}
|
|
52
|
+
],
|
|
53
|
+
"Stop": [
|
|
54
|
+
{
|
|
55
|
+
"hooks": [
|
|
56
|
+
{
|
|
57
|
+
"type": "command",
|
|
58
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/bin/litclaude-hook.js\" stop",
|
|
59
|
+
"timeout": 10,
|
|
60
|
+
"statusMessage": "checking LitClaude litgoal completion"
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
}
|
|
52
64
|
]
|
|
53
65
|
}
|
|
54
66
|
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// Durable iteration counter for the litgoal Stop-hook autoloop (the /goal-equivalent
|
|
2
|
+
// completion loop). The counter is the PRIMARY safety brake: the Stop hook blocks
|
|
3
|
+
// stopping only while it can durably increment this counter under the cap. If the
|
|
4
|
+
// counter cannot be read or written, the hook fails SAFE (allows stopping) rather
|
|
5
|
+
// than risk a runaway loop. State lives at `.litclaude/litgoal/autoloop.json`.
|
|
6
|
+
import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
import { litgoalStateDir } from "./paths.mjs";
|
|
9
|
+
|
|
10
|
+
export const litgoalAutoloopPath = (cwd = process.cwd()) => join(litgoalStateDir(cwd), "autoloop.json");
|
|
11
|
+
|
|
12
|
+
// Default safety caps for the autoloop. Exposed for tests and the hook.
|
|
13
|
+
export const AUTOLOOP_MAX_BLOCKS = 8;
|
|
14
|
+
export const AUTOLOOP_MAX_MS = 30 * 60 * 1000;
|
|
15
|
+
|
|
16
|
+
export const readAutoloopState = (cwd = process.cwd()) => {
|
|
17
|
+
try {
|
|
18
|
+
const parsed = JSON.parse(readFileSync(litgoalAutoloopPath(cwd), "utf8"));
|
|
19
|
+
return parsed && typeof parsed === "object" ? parsed : null;
|
|
20
|
+
} catch {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const writeAutoloopState = (cwd, state) => {
|
|
26
|
+
const dir = litgoalStateDir(cwd);
|
|
27
|
+
mkdirSync(dir, { recursive: true });
|
|
28
|
+
const target = litgoalAutoloopPath(cwd);
|
|
29
|
+
const tmp = `${target}.tmp`;
|
|
30
|
+
writeFileSync(tmp, JSON.stringify(state));
|
|
31
|
+
renameSync(tmp, target);
|
|
32
|
+
return state;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// Reset the counter when a fresh autoloop goal is bound.
|
|
36
|
+
export const resetAutoloopState = (cwd, now = Date.now()) =>
|
|
37
|
+
writeAutoloopState(cwd, { blockCount: 0, firstBlockAt: now });
|
|
38
|
+
|
|
39
|
+
// Pure decision function for the Stop hook — kept side-effect-free so it is unit
|
|
40
|
+
// testable without touching the filesystem or the process. Returns one of:
|
|
41
|
+
// { action: "allow" } -> let the session stop
|
|
42
|
+
// { action: "cap", stopReason } -> hard stop (continue:false)
|
|
43
|
+
// { action: "block", reason, nextCount } -> block stopping; caller persists nextCount
|
|
44
|
+
export const evaluateAutoloop = ({ env = {}, state, autoloopState, now = Date.now() } = {}) => {
|
|
45
|
+
if (env.LITCLAUDE_GOAL_OFF === "1") return { action: "allow", why: "kill-switch" };
|
|
46
|
+
if (!state || state.status !== "active" || state.autoloop !== true) {
|
|
47
|
+
return { action: "allow", why: "no-active-autoloop-goal" };
|
|
48
|
+
}
|
|
49
|
+
const criteria = Array.isArray(state.criteria) ? state.criteria : [];
|
|
50
|
+
const remaining = criteria.filter((c) => c && c.status !== "pass");
|
|
51
|
+
if (remaining.length === 0) return { action: "allow", why: "all-criteria-pass" };
|
|
52
|
+
|
|
53
|
+
const auto = autoloopState && typeof autoloopState === "object"
|
|
54
|
+
? autoloopState
|
|
55
|
+
: { blockCount: 0, firstBlockAt: now };
|
|
56
|
+
const blockCount = Number.isFinite(auto.blockCount) ? auto.blockCount : 0;
|
|
57
|
+
const firstBlockAt = Number.isFinite(auto.firstBlockAt) ? auto.firstBlockAt : now;
|
|
58
|
+
const elapsedMs = now - firstBlockAt;
|
|
59
|
+
if (blockCount >= AUTOLOOP_MAX_BLOCKS || elapsedMs > AUTOLOOP_MAX_MS) {
|
|
60
|
+
return {
|
|
61
|
+
action: "cap",
|
|
62
|
+
stopReason:
|
|
63
|
+
`LitClaude autoloop safety cap reached (${blockCount} blocks / ${Math.round(elapsedMs / 1000)}s); ` +
|
|
64
|
+
`goal left active. Escape: set LITCLAUDE_GOAL_OFF=1, or run ` +
|
|
65
|
+
`'litclaude-ai litgoal checkpoint --status blocked'.`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const nextCount = blockCount + 1;
|
|
70
|
+
const list = remaining
|
|
71
|
+
.map((c) => ` - ${c.id} [${c.status}]: ${c.description ?? c.scenario ?? ""}`)
|
|
72
|
+
.join("\n");
|
|
73
|
+
const reason =
|
|
74
|
+
`LitClaude litgoal still active: "${state.objective}". ${remaining.length} criterion(s) not yet pass:\n${list}\n` +
|
|
75
|
+
`Advance each: litclaude-ai litgoal record-evidence --criterion <id> --status pass --json '{"artifact":"..."}'. ` +
|
|
76
|
+
`Autoloop block ${nextCount}/${AUTOLOOP_MAX_BLOCKS}. Escape: litclaude-ai litgoal checkpoint --status blocked, or LITCLAUDE_GOAL_OFF=1.`;
|
|
77
|
+
return { action: "block", reason, nextCount, firstBlockAt };
|
|
78
|
+
};
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
litgoalLockDir,
|
|
9
9
|
} from "./paths.mjs";
|
|
10
10
|
import { readLitgoalState, LitgoalStateError, withLitgoalLock, writeLitgoalState } from "./state.mjs";
|
|
11
|
+
import { resetAutoloopState } from "./autoloop.mjs";
|
|
11
12
|
|
|
12
13
|
const subcommands = [
|
|
13
14
|
["create-goals", "Create durable goal records from a brief."],
|
|
@@ -93,12 +94,16 @@ const defaultCriterion = (brief) => ({
|
|
|
93
94
|
const createGoals = (cwd, args) => {
|
|
94
95
|
const brief = requireOption(args, "--brief", "brief").trim();
|
|
95
96
|
if (!brief) throw new LitgoalCliError("missing brief");
|
|
97
|
+
// Opt-in: `--autoloop` arms the LitClaude Stop hook to keep the session running
|
|
98
|
+
// (a /goal-equivalent loop) until every criterion passes. Default off.
|
|
99
|
+
const autoloop = hasFlag(args, "--autoloop");
|
|
96
100
|
return withLitgoalLock(litgoalLockDir(cwd), () => {
|
|
97
101
|
const timestamp = nowIso();
|
|
98
102
|
const state = {
|
|
99
103
|
version: 1,
|
|
100
104
|
objective: brief,
|
|
101
105
|
status: "active",
|
|
106
|
+
autoloop,
|
|
102
107
|
criteria: [defaultCriterion(brief)],
|
|
103
108
|
blockers: [],
|
|
104
109
|
steering: [],
|
|
@@ -110,10 +115,13 @@ const createGoals = (cwd, args) => {
|
|
|
110
115
|
mkdirSync(dirname(litgoalBriefPath(cwd)), { recursive: true });
|
|
111
116
|
writeFileSync(litgoalBriefPath(cwd), `${brief}\n`);
|
|
112
117
|
writeLitgoalState(litgoalGoalsPath(cwd), state);
|
|
118
|
+
// Fresh autoloop run -> reset the durable iteration counter so prior caps don't carry over.
|
|
119
|
+
if (autoloop) resetAutoloopState(cwd, Date.parse(timestamp) || Date.now());
|
|
113
120
|
appendLedger(cwd, {
|
|
114
121
|
event: "goal.created",
|
|
115
122
|
objective: brief,
|
|
116
123
|
status: state.status,
|
|
124
|
+
autoloop,
|
|
117
125
|
criteria: state.criteria.map(({ id, status }) => ({ id, status })),
|
|
118
126
|
});
|
|
119
127
|
return state;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: git-master
|
|
3
|
+
description: "MUST USE whenever a task needs a commit or git-history investigation. Covers atomic commits, staging, commit-message style, rebase, squash, fixup/autosquash, blame, bisect, reflog, git log -S/-G, and questions like who wrote this or when was this added. Do not use for ordinary code edits unless the user asks for git work."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Git Master
|
|
7
|
+
|
|
8
|
+
The LitClaude git-history specialist for Claude Code. Use this skill when the user
|
|
9
|
+
asks you to operate on Git history or answer a Git-history question. Be exact,
|
|
10
|
+
conservative, and evidence-led. Read the repository state before you infer anything.
|
|
11
|
+
|
|
12
|
+
## LitClaude publish boundary
|
|
13
|
+
|
|
14
|
+
Commit, push, force-push, and history rewrites are outward-facing or hard-to-reverse
|
|
15
|
+
operations. Per LitClaude discipline, do **not** commit, push, force-push, reset,
|
|
16
|
+
stash-pop, or rewrite history unless the user explicitly authorized that exact
|
|
17
|
+
operation. Investigative requests report findings and stop.
|
|
18
|
+
|
|
19
|
+
## Mode Gate
|
|
20
|
+
|
|
21
|
+
Classify the request first:
|
|
22
|
+
|
|
23
|
+
- `COMMIT`: stage and commit local changes.
|
|
24
|
+
- `REBASE`: rebase, squash, fixup, autosquash, reorder, split, or otherwise rewrite branch history.
|
|
25
|
+
- `HISTORY`: answer when, where, who, why, or which commit changed something.
|
|
26
|
+
- `STATUS`: inspect branch, diff, or working-tree state without changing it.
|
|
27
|
+
|
|
28
|
+
If the request is only investigative, report findings and stop.
|
|
29
|
+
|
|
30
|
+
## Ground Truth
|
|
31
|
+
|
|
32
|
+
Gather independent facts first (these are read-only and safe to run in parallel):
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
git status --short
|
|
36
|
+
git diff --stat
|
|
37
|
+
git diff --staged --stat
|
|
38
|
+
git branch --show-current
|
|
39
|
+
git log -30 --oneline
|
|
40
|
+
git rev-parse --abbrev-ref @{upstream}
|
|
41
|
+
git merge-base HEAD origin/main
|
|
42
|
+
git merge-base HEAD origin/master
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Missing upstream or missing `main`/`master` is normal. Fall back to the best
|
|
46
|
+
available branch or report the missing fact. Never treat a failed lookup as proof.
|
|
47
|
+
|
|
48
|
+
## Commit Mode
|
|
49
|
+
|
|
50
|
+
Commit only the user's requested changes. Preserve unrelated dirty work.
|
|
51
|
+
|
|
52
|
+
1. Detect message style from recent history (`git log -30 --pretty=format:%s`). Use the
|
|
53
|
+
dominant local pattern, language, and casing. Do not default to Conventional
|
|
54
|
+
Commits unless the repo already uses them.
|
|
55
|
+
2. Inspect the full diff, not only filenames. Separate unrelated user edits from the
|
|
56
|
+
requested commit.
|
|
57
|
+
3. Build atomic groups by behavior, module, and revertability. Keep implementation and
|
|
58
|
+
its direct tests together.
|
|
59
|
+
4. Prefer multiple commits for unrelated concerns. A single commit is acceptable only
|
|
60
|
+
when the changed files form one indivisible behavior or the user explicitly asks for one.
|
|
61
|
+
5. Stage by path or hunk so each commit contains only its atomic group.
|
|
62
|
+
6. Before each commit, verify `git diff --staged --stat` and enough staged diff to prove
|
|
63
|
+
the group is right.
|
|
64
|
+
7. Commit with the detected style. After each commit, verify `git log -1 --oneline`.
|
|
65
|
+
|
|
66
|
+
Grouping rules:
|
|
67
|
+
|
|
68
|
+
- Split different features, modules, generated artifacts, config, docs, and test-only
|
|
69
|
+
changes unless they are inseparable.
|
|
70
|
+
- Keep generated files with the source change that produced them when omitting them
|
|
71
|
+
would leave the repo inconsistent.
|
|
72
|
+
- Never hide failing or unrelated changes inside a broad commit.
|
|
73
|
+
- Follow the user's git conventions (e.g. no AI/co-author attribution when the repo or
|
|
74
|
+
the user's rules forbid it).
|
|
75
|
+
|
|
76
|
+
Final report: list commit hashes, messages, and any remaining uncommitted files.
|
|
77
|
+
|
|
78
|
+
## Rebase Mode
|
|
79
|
+
|
|
80
|
+
History rewriting is a shared-impact operation.
|
|
81
|
+
|
|
82
|
+
- Never rebase or rewrite `main`, `master`, `dev`, release branches, or a protected
|
|
83
|
+
branch unless the user explicitly named that exact operation.
|
|
84
|
+
- If commits may already be pushed, ask before force-pushing. Use `--force-with-lease`,
|
|
85
|
+
never plain `--force`.
|
|
86
|
+
- If the worktree is dirty, preserve it intentionally before rebasing. Do not stash-pop
|
|
87
|
+
over conflicts without checking what changed.
|
|
88
|
+
- For fixups, prefer `git commit --fixup=<hash>` then
|
|
89
|
+
`GIT_SEQUENCE_EDITOR=: git rebase -i --autosquash <base>`.
|
|
90
|
+
- For conflicts, read the conflicting files and resolve by intent. Do not choose
|
|
91
|
+
ours/theirs blindly.
|
|
92
|
+
- If a rebase goes wrong, run `git rebase --abort` first. Use reflog only after
|
|
93
|
+
explaining the recovery path.
|
|
94
|
+
|
|
95
|
+
After rewriting, run the relevant tests or at least the project's cheapest smoke check,
|
|
96
|
+
then show the new branch log from base to HEAD.
|
|
97
|
+
|
|
98
|
+
## History Mode
|
|
99
|
+
|
|
100
|
+
Choose the Git tool by the question:
|
|
101
|
+
|
|
102
|
+
- `git log -S "text"`: when the count of an exact string changed.
|
|
103
|
+
- `git log -G "regex"`: when diffs touched lines matching a pattern.
|
|
104
|
+
- `git blame -L start,end -- file`: who last changed specific lines.
|
|
105
|
+
- `git log --follow -- file`: history across renames for one file.
|
|
106
|
+
- `git show <hash>`: inspect the commit that appears relevant.
|
|
107
|
+
- `git bisect`: find the first bad commit when there is a deterministic pass/fail
|
|
108
|
+
command and known good/bad bounds.
|
|
109
|
+
- `git reflog`: recover or explain recent local history movement.
|
|
110
|
+
|
|
111
|
+
Always cite the exact command evidence in the answer: commit hash, subject, file path,
|
|
112
|
+
and line or diff context when relevant. If the evidence is ambiguous, say what remains
|
|
113
|
+
unproven.
|
|
114
|
+
|
|
115
|
+
## Safety Checks
|
|
116
|
+
|
|
117
|
+
Before any write to Git history:
|
|
118
|
+
|
|
119
|
+
- Current branch is known.
|
|
120
|
+
- Dirty work is accounted for.
|
|
121
|
+
- Upstream/pushed status is known or explicitly unknown.
|
|
122
|
+
- The operation matches an explicit user request and authorization.
|
|
123
|
+
- Recovery path is known (`rebase --abort`, reflog hash, or untouched worktree).
|
|
124
|
+
|
|
125
|
+
Before finishing:
|
|
126
|
+
|
|
127
|
+
- Run the most relevant verification available for the changed behavior or history
|
|
128
|
+
operation (Manual QA evidence where a behavior changed).
|
|
129
|
+
- Report commands that passed and any command you could not run.
|
|
130
|
+
- Leave the worktree state explicit.
|