litclaude-ai 0.3.26 → 0.3.28
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 +19 -0
- package/README.md +16 -9
- package/README_ko-KR.md +14 -11
- package/RELEASE_CHECKLIST.md +10 -8
- package/bin/litclaude-ai.js +151 -25
- package/docs/hooks.md +3 -1
- package/package.json +1 -1
- package/plugins/litclaude/.claude-plugin/plugin.json +1 -1
- package/plugins/litclaude/bin/litclaude-hook.js +5 -1
- package/plugins/litclaude/bin/litclaude-mcp.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.28 - 2026-07-14 — explicit start-work activation
|
|
4
|
+
|
|
5
|
+
- Require the `$start-work` shorthand and natural `lit start work` activation
|
|
6
|
+
to be leading command phrases without changing other dollar routes.
|
|
7
|
+
- Keep diagnostic prose, copied blockquotes, and explanatory mentions of
|
|
8
|
+
`$start-work` or `lit start work` inert while preserving explicit dollar,
|
|
9
|
+
bare, natural, and native slash start-work routes.
|
|
10
|
+
|
|
11
|
+
## 0.3.27 - 2026-07-12 — structured interactive installer
|
|
12
|
+
|
|
13
|
+
- Present interactive installs as five persistent, numbered Claude-native
|
|
14
|
+
stages with purpose and target details plus a live spinner during filesystem
|
|
15
|
+
work.
|
|
16
|
+
- Add explicit `PREPARING INSTALL`, successful `INSTALL RECEIPT`, and failed
|
|
17
|
+
`INSTALL STOPPED` summaries without changing dry-run or deterministic
|
|
18
|
+
non-TTY `INSTALL_STEP` behavior.
|
|
19
|
+
- Respect `NO_COLOR`, retain CI-safe output, and verify the installed payload,
|
|
20
|
+
Claude plugin registry, and compatibility pointer before reporting success.
|
|
21
|
+
|
|
3
22
|
## 0.3.26 - 2026-07-11 — planning quality and orchestration safety
|
|
4
23
|
|
|
5
24
|
- Make `lit-plan` checklist depth adaptive: one bounded objective, explicit
|
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.28-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.28` 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.26 release material adds adaptive objective-achievable planning, draft-plan review, and orchestration readiness hardening. The v0.3.25 release material aligns portable details, public-read, litgoal status JSON, and evidence wording. The v0.3.24 release material aligns auxiliary skill inventories and advisory probes. The v0.3.23
|
|
28
|
+
Future package releases still require explicit user approval. The v0.3.28 release material requires explicit leading start-work invocations so diagnostic or copied mentions remain inert. The v0.3.27 release material adds a structured, animated five-stage installer with a success or failure receipt while preserving deterministic automation output. The v0.3.26 release material adds adaptive objective-achievable planning, draft-plan review, and orchestration readiness hardening. The v0.3.25 release material aligns portable details, public-read, litgoal status JSON, and evidence wording. The v0.3.24 release material aligns auxiliary skill inventories and advisory probes. The v0.3.23
|
|
29
29
|
release materials inject the bundled skill bodies for bare `hyperplan`,
|
|
30
30
|
`litresearch`, `lit research`, `init-deep`, and explicit `$start-work` prompt-hook routes while
|
|
31
31
|
preserving the v0.3.19 adversarial planning skill, the v0.3.18 read-only `lit-recap` session recap surface, the v0.3.17 separate-worker native `/goal` launcher, the v0.3.16
|
|
@@ -107,9 +107,14 @@ npx --yes litclaude-ai install
|
|
|
107
107
|
|
|
108
108
|
During an interactive `npx` install, LitClaude shows every HUD brand color as
|
|
109
109
|
a vivid live terminal preview and writes the selected accent into the managed
|
|
110
|
-
Claude `statusLine` command.
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
Claude `statusLine` command. The installer then presents `PREPARING INSTALL`,
|
|
111
|
+
five persistent numbered stages with each stage's purpose and target, an
|
|
112
|
+
animated spinner while filesystem work is active, and an `INSTALL RECEIPT`
|
|
113
|
+
that identifies the installed plugin, HUD, permission preference, and launch
|
|
114
|
+
command. A failed stage prints `INSTALL STOPPED` and never reports success.
|
|
115
|
+
`NO_COLOR` retains the structure without ANSI color. CI and non-TTY installs
|
|
116
|
+
keep deterministic plain `INSTALL_STEP` lines, and `--dry-run` remains a
|
|
117
|
+
side-effect-free preview.
|
|
113
118
|
|
|
114
119
|
If you are currently inside this repository checkout, which has the same
|
|
115
120
|
package name as the registry package, older published builds such as
|
|
@@ -120,7 +125,7 @@ directory, the normal install command works:
|
|
|
120
125
|
|
|
121
126
|
```bash
|
|
122
127
|
cd /tmp
|
|
123
|
-
npx --yes litclaude-ai@0.3.
|
|
128
|
+
npx --yes litclaude-ai@0.3.28 install
|
|
124
129
|
```
|
|
125
130
|
|
|
126
131
|
Validate the installed plugin:
|
|
@@ -133,7 +138,7 @@ The installer also sets Claude Code's `statusLine` command to the packaged
|
|
|
133
138
|
LitClaude HUD. A typical no-color render starts like:
|
|
134
139
|
|
|
135
140
|
```text
|
|
136
|
-
[🔥LITCLAUDE v0.3.
|
|
141
|
+
[🔥LITCLAUDE v0.3.28] | O4.8 │ ctx [▎░░] 9%/1000k │ 5h [▏░] 4% ↻2h15m │ 1w [▊░] 35% ↻3d6h │ git main +3 ✓
|
|
137
142
|
```
|
|
138
143
|
|
|
139
144
|
The `↻` suffix is a compact rate-limit reset countdown. It is separated from
|
|
@@ -250,7 +255,9 @@ a visible hook message. Slash commands such as `/lit-plan` are handled by Claude
|
|
|
250
255
|
Code's native command surface and should not double-activate the hook. Natural
|
|
251
256
|
`lit start work` is a safe handoff: it emits `BLOCKED:` and tells the user to
|
|
252
257
|
run `/start-work` or `/litclaude:start-work` with the approved plan because a
|
|
253
|
-
prompt hook cannot switch Claude Code agents.
|
|
258
|
+
prompt hook cannot switch Claude Code agents. The `$start-work` shorthand and
|
|
259
|
+
natural start-work phrases activate only at the beginning of the prompt, so diagnostic
|
|
260
|
+
prose and copied or blockquoted mentions stay inert. Plain `lit` still maps to
|
|
254
261
|
`/litclaude:lit-loop` / `Skill(lit-loop)` semantics before ordinary task
|
|
255
262
|
execution, then the matching skill and agent instructions steer Claude toward
|
|
256
263
|
test-first work, native goal handling, manual QA evidence, cleanup receipts, and
|
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.28-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.28` 배포 준비용으로 정리되어 있습니다. 목적은
|
|
30
30
|
다른 PC에서도 빠르게 설치하기 위한 개인용 package metadata를 갖추는 것입니다.
|
|
31
31
|
npm package metadata를 준비했다고 해서 홍보, 공개 저장소 운영, Claude
|
|
32
32
|
marketplace 등록을 의미하지는 않습니다. 새 버전 배포는 항상 별도의 명시적
|
|
33
|
-
승인 후에 진행합니다. v0.3.26 release material은 adaptive objective-achievable planning, draft-plan review, orchestration readiness hardening을 추가합니다. v0.3.25 release material은 portable details, public-read, litgoal status JSON, evidence wording을 정렬합니다. v0.3.24 release material은 auxiliary skill inventory와 advisory probe를 정렬합니다. v0.3.23 release material은 bare `hyperplan`,
|
|
33
|
+
승인 후에 진행합니다. v0.3.28 release material은 start-work 호출을 prompt 선두의 명시적 invocation으로 제한해 진단문이나 복사된 언급을 비활성 상태로 유지합니다. v0.3.27 release material은 success/failure receipt와 deterministic automation output을 갖춘 5-stage animated installer를 추가합니다. v0.3.26 release material은 adaptive objective-achievable planning, draft-plan review, orchestration readiness hardening을 추가합니다. v0.3.25 release material은 portable details, public-read, litgoal status JSON, evidence wording을 정렬합니다. v0.3.24 release material은 auxiliary skill inventory와 advisory probe를 정렬합니다. v0.3.23 release material은 bare `hyperplan`,
|
|
34
34
|
`litresearch`, `lit research`, `init-deep`, explicit `$start-work` prompt-hook route에
|
|
35
35
|
bundled skill body를 주입하면서, v0.3.19 adversarial planning
|
|
36
36
|
skill, v0.3.18 read-only `lit-recap` session recap surface, v0.3.17 별도 worker 기반 native `/goal`
|
|
@@ -110,10 +110,12 @@ npx --yes litclaude-ai install
|
|
|
110
110
|
|
|
111
111
|
interactive `npx` 설치에서는 LitClaude가 HUD brand color 후보를 더 선명한
|
|
112
112
|
실제 터미널 색상으로 바로 보여주고, 선택한 accent를 Claude의 managed
|
|
113
|
-
`statusLine` command에 저장합니다.
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
`
|
|
113
|
+
`statusLine` command에 저장합니다. 이후 `PREPARING INSTALL`, 목적과 target을
|
|
114
|
+
표시하는 5개의 numbered stage, 파일시스템 작업 중 animated spinner, 그리고
|
|
115
|
+
plugin·HUD·permission·launch command를 정리한 `INSTALL RECEIPT`를 보여줍니다.
|
|
116
|
+
중간 단계가 실패하면 `INSTALL STOPPED`를 출력하고 성공을 보고하지 않습니다.
|
|
117
|
+
`NO_COLOR`는 ANSI 색상만 제거하고 구조를 유지합니다. CI/non-TTY 설치는 deterministic한
|
|
118
|
+
plain `INSTALL_STEP` line을 유지하며 `--dry-run`은 계속 side-effect-free preview입니다.
|
|
117
119
|
|
|
118
120
|
현재 위치가 이 저장소 checkout이면, registry package와 같은 package name을
|
|
119
121
|
가진 same-name source checkout 안에 있는 상태입니다. 이 경우
|
|
@@ -124,7 +126,7 @@ checkout을 먼저 해석해서 `sh: litclaude-ai: command not found`로 실패
|
|
|
124
126
|
|
|
125
127
|
```bash
|
|
126
128
|
cd /tmp
|
|
127
|
-
npx --yes litclaude-ai@0.3.
|
|
129
|
+
npx --yes litclaude-ai@0.3.28 install
|
|
128
130
|
```
|
|
129
131
|
|
|
130
132
|
설치 상태를 확인합니다.
|
|
@@ -137,7 +139,7 @@ installer는 Claude Code의 `statusLine` command도 packaged LitClaude HUD로
|
|
|
137
139
|
설정합니다. 색상을 제거한 예시는 다음처럼 시작합니다.
|
|
138
140
|
|
|
139
141
|
```text
|
|
140
|
-
[🔥LITCLAUDE v0.3.
|
|
142
|
+
[🔥LITCLAUDE v0.3.28] | O4.8 │ ctx [▎░░] 9%/1000k │ 5h [▏░] 4% ↻2h15m │ 1w [▊░] 35% ↻3d6h │ git main +3 ✓
|
|
141
143
|
```
|
|
142
144
|
|
|
143
145
|
`↻` 표시는 rate-limit reset까지 남은 시간을 짧게 보여주는 countdown입니다.
|
|
@@ -246,8 +248,9 @@ visible hook message를 보여주는 것입니다. `/lit-plan` 같은 slash comm
|
|
|
246
248
|
Claude Code native command surface에서 처리되며 hook을 중복 활성화하지
|
|
247
249
|
않습니다. 자연어 `lit start work`는 안전한 handoff로 `BLOCKED:`를 내고,
|
|
248
250
|
prompt hook이 Claude Code agent를 전환할 수 없으므로 승인된 plan과 함께
|
|
249
|
-
`/start-work` 또는 `/litclaude:start-work`를 실행하라고 안내합니다.
|
|
250
|
-
|
|
251
|
+
`/start-work` 또는 `/litclaude:start-work`를 실행하라고 안내합니다.
|
|
252
|
+
`$start-work`와 자연어 start-work phrase는 prompt 선두에서만 활성화되므로 진단문,
|
|
253
|
+
복사문, blockquote 안의 단순 언급은 활성화되지 않습니다. plain `lit`는 일반 작업 실행 전 `/litclaude:lit-loop` / `Skill(lit-loop)` semantics로
|
|
251
254
|
처리됩니다. 그 뒤 skill 및 agent 지시문이 Claude를 test-first 작업, native
|
|
252
255
|
goal 처리, 실제 수동 QA 증거, cleanup receipt, 향후 release step의 명시적 승인
|
|
253
256
|
쪽으로 유도합니다.
|
package/RELEASE_CHECKLIST.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# LitClaude Release Checklist
|
|
2
2
|
|
|
3
|
-
Status: `litclaude-ai@0.3.
|
|
3
|
+
Status: `litclaude-ai@0.3.28` is the current release candidate — explicit
|
|
4
|
+
leading start-work activation guards plus a structured five-stage interactive
|
|
5
|
+
installer with success/failure receipts and adaptive
|
|
4
6
|
planning, draft-plan review, and orchestration-safety release on top of the portable
|
|
5
7
|
details, public-read, litgoal-status, and evidence-wording release and the auxiliary
|
|
6
8
|
skill inventory and advisory-probe release and the full bare
|
|
@@ -15,9 +17,9 @@ side-effect-free, the launcher starts only a separate Claude Code
|
|
|
15
17
|
print/background worker, and the release preserves the Korean polishing
|
|
16
18
|
command, strict multi-agent review pipeline, fidelity guardrails, package
|
|
17
19
|
hygiene checks, native route gates, and safe start-work handoff behavior.
|
|
18
|
-
`package.json` is aligned to `0.3.
|
|
19
|
-
`plugins/litclaude/.claude-plugin/plugin.json` is aligned to `0.3.
|
|
20
|
-
plugin-local MCP server reports `0.3.
|
|
20
|
+
`package.json` is aligned to `0.3.28`,
|
|
21
|
+
`plugins/litclaude/.claude-plugin/plugin.json` is aligned to `0.3.28`, and the
|
|
22
|
+
plugin-local MCP server reports `0.3.28`.
|
|
21
23
|
|
|
22
24
|
This release carries the v0.2.2 Dynamic workflow hardening surfaces:
|
|
23
25
|
`/dynamic-workflow`, `workflow-check --json`, native `/goal` fallback guidance,
|
|
@@ -66,10 +68,10 @@ No npm publication is required for this track.
|
|
|
66
68
|
Before requesting publication approval, confirm these artifacts from the current
|
|
67
69
|
checkout:
|
|
68
70
|
|
|
69
|
-
- `package.json` version is `0.3.
|
|
70
|
-
- `plugins/litclaude/.claude-plugin/plugin.json` version is `0.3.
|
|
71
|
-
- `plugins/litclaude/bin/litclaude-mcp.js` reports server version `0.3.
|
|
72
|
-
- Prompt-hook tests cover bundled `SKILL.md` body injection for bare `hyperplan`, `litresearch`, `lit research`, `init-deep`, and explicit `$start-work
|
|
71
|
+
- `package.json` version is `0.3.28`.
|
|
72
|
+
- `plugins/litclaude/.claude-plugin/plugin.json` version is `0.3.28`.
|
|
73
|
+
- `plugins/litclaude/bin/litclaude-mcp.js` reports server version `0.3.28`.
|
|
74
|
+
- Prompt-hook tests cover bundled `SKILL.md` body injection for bare `hyperplan`, `litresearch`, `lit research`, `init-deep`, and explicit leading `$start-work`; diagnostic/copy mentions stay inert while leading natural-language `lit start work` stays BLOCKED.
|
|
73
75
|
- `lit search` and `lit query` route to `/litclaude:litresearch` without activating on slash mentions, code spans, or non-lit prompts.
|
|
74
76
|
- Litresearch web lanes require public API/feed preference, validator-first checks, route traces, prompt-injection quarantine, and honest auth/paywall/private-data stop reasons.
|
|
75
77
|
- `node bin/litclaude-ai.js public-read <public-url> --json` exposes the guarded JS runtime reader.
|
package/bin/litclaude-ai.js
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
symlinkSync,
|
|
11
11
|
writeFileSync,
|
|
12
12
|
} from "node:fs";
|
|
13
|
+
import { cp, mkdir, rm } from "node:fs/promises";
|
|
13
14
|
import { homedir } from "node:os";
|
|
14
15
|
import { dirname, join, resolve } from "node:path";
|
|
15
16
|
import { createInterface } from "node:readline/promises";
|
|
@@ -169,6 +170,8 @@ const shouldAnimateInstall = () => {
|
|
|
169
170
|
return Boolean(process.stdout.isTTY && !process.env.CI);
|
|
170
171
|
};
|
|
171
172
|
|
|
173
|
+
const shouldColorInstall = () => !Object.hasOwn(process.env, "NO_COLOR");
|
|
174
|
+
|
|
172
175
|
const installStepTheme = (label) => {
|
|
173
176
|
if (/registry|HUD/iu.test(label)) return { code: 215, tag: "registry" };
|
|
174
177
|
if (/plugin/iu.test(label)) return { code: 141, tag: "plugin" };
|
|
@@ -177,32 +180,87 @@ const installStepTheme = (label) => {
|
|
|
177
180
|
return { code: 81, tag: "setup" };
|
|
178
181
|
};
|
|
179
182
|
|
|
180
|
-
const color256 = (code, text) => `\x1b[38;5;${code}m${text}\x1b[0m
|
|
183
|
+
const color256 = (code, text) => shouldColorInstall() ? `\x1b[38;5;${code}m${text}\x1b[0m` : text;
|
|
184
|
+
const bold = (text) => shouldColorInstall() ? `\x1b[1m${text}\x1b[0m` : text;
|
|
181
185
|
|
|
182
186
|
const formatInstallStep = (label) => {
|
|
183
187
|
const theme = installStepTheme(label);
|
|
184
|
-
return `${color256(theme.code, theme.tag)}
|
|
188
|
+
return `${color256(theme.code, theme.tag)} ${bold(label)}`;
|
|
185
189
|
};
|
|
186
190
|
|
|
187
191
|
const createInstallProgress = () => {
|
|
188
192
|
const animated = shouldAnimateInstall();
|
|
189
193
|
let frameIndex = 0;
|
|
194
|
+
const live = animated && Boolean(process.stdout.isTTY);
|
|
195
|
+
|
|
196
|
+
const clearLiveLine = () => {
|
|
197
|
+
if (live) process.stdout.write("\r\x1b[2K");
|
|
198
|
+
};
|
|
199
|
+
|
|
190
200
|
return {
|
|
191
|
-
|
|
201
|
+
prepare({ claudeTarget, litTarget }) {
|
|
192
202
|
if (!animated) {
|
|
193
|
-
process.stdout.write(`INSTALL_STEP: ${
|
|
203
|
+
process.stdout.write(`INSTALL_STEP: Installing LitClaude ${version}\n`);
|
|
194
204
|
return;
|
|
195
205
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
206
|
+
process.stdout.write(
|
|
207
|
+
`\n╭─ PREPARING INSTALL\n` +
|
|
208
|
+
`│ Package LitClaude ${version}\n` +
|
|
209
|
+
`│ Action Installing LitClaude ${version}\n` +
|
|
210
|
+
`│ Claude state ${claudeTarget}\n` +
|
|
211
|
+
`│ Local state ${litTarget}\n` +
|
|
212
|
+
`│ Progress 5 persistent stages with a final verification\n` +
|
|
213
|
+
`╰─ Existing unrelated Claude settings are preserved\n\n`,
|
|
214
|
+
);
|
|
199
215
|
},
|
|
200
|
-
|
|
216
|
+
async run({ number, title, label, purpose, target }, work) {
|
|
201
217
|
if (!animated) {
|
|
202
218
|
process.stdout.write(`INSTALL_STEP: ${label}\n`);
|
|
203
|
-
return;
|
|
219
|
+
return work();
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
process.stdout.write(
|
|
223
|
+
`${String(number).padStart(2, "0")} / 05 ${title}\n` +
|
|
224
|
+
` ${purpose}\n` +
|
|
225
|
+
` target ${target}\n`,
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
const renderSpinner = () => {
|
|
229
|
+
const frame = spinnerFrames[frameIndex % spinnerFrames.length];
|
|
230
|
+
frameIndex += 1;
|
|
231
|
+
const line = ` ${color256(81, frame)} ${formatInstallStep(label)}`;
|
|
232
|
+
process.stdout.write(live ? `\r\x1b[2K${line}` : `${line}\n`);
|
|
233
|
+
};
|
|
234
|
+
renderSpinner();
|
|
235
|
+
const timer = live ? setInterval(renderSpinner, 80) : undefined;
|
|
236
|
+
|
|
237
|
+
try {
|
|
238
|
+
const result = await work();
|
|
239
|
+
if (timer) clearInterval(timer);
|
|
240
|
+
clearLiveLine();
|
|
241
|
+
process.stdout.write(` ${color256(119, "✓")} ${bold(label)}\n\n`);
|
|
242
|
+
return result;
|
|
243
|
+
} catch (error) {
|
|
244
|
+
if (timer) clearInterval(timer);
|
|
245
|
+
clearLiveLine();
|
|
246
|
+
process.stdout.write(
|
|
247
|
+
` ${color256(203, "✗")} ${bold(`${label} failed`)}\n\n` +
|
|
248
|
+
`╭─ INSTALL STOPPED\n` +
|
|
249
|
+
`│ Stage ${String(number).padStart(2, "0")} / 05 · ${title}\n` +
|
|
250
|
+
`│ Reason ${error instanceof Error ? error.message : String(error)}\n` +
|
|
251
|
+
`│ Next Resolve the reason above, then rerun litclaude install\n` +
|
|
252
|
+
`╰─ Exit without reporting success\n`,
|
|
253
|
+
);
|
|
254
|
+
throw error;
|
|
204
255
|
}
|
|
205
|
-
|
|
256
|
+
},
|
|
257
|
+
receipt(rows) {
|
|
258
|
+
if (!animated) return;
|
|
259
|
+
process.stdout.write("\n╭─ INSTALL RECEIPT\n");
|
|
260
|
+
for (const [key, value] of rows) {
|
|
261
|
+
process.stdout.write(`│ ${key.padEnd(13)} ${value}\n`);
|
|
262
|
+
}
|
|
263
|
+
process.stdout.write("╰─ Installation complete\n\n");
|
|
206
264
|
},
|
|
207
265
|
};
|
|
208
266
|
};
|
|
@@ -560,6 +618,20 @@ const resetCurrentPointer = (home, target) => {
|
|
|
560
618
|
}
|
|
561
619
|
};
|
|
562
620
|
|
|
621
|
+
const verifyInstalledPayload = ({ home, litClaudeHome, targetPlugin }) => {
|
|
622
|
+
for (const relativePath of [".claude-plugin/plugin.json", "hooks/hooks.json", "bin/litclaude-hook.js"]) {
|
|
623
|
+
if (!existsSync(join(targetPlugin, relativePath))) {
|
|
624
|
+
throw new Error(`installed plugin is missing ${relativePath}`);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
if (!readInstalledPlugins(home).plugins[pluginKey]?.length) {
|
|
628
|
+
throw new Error(`Claude registry is missing ${pluginKey}`);
|
|
629
|
+
}
|
|
630
|
+
if (!existsSync(currentRoot(litClaudeHome))) {
|
|
631
|
+
throw new Error("LitClaude compatibility pointer was not created");
|
|
632
|
+
}
|
|
633
|
+
};
|
|
634
|
+
|
|
563
635
|
const install = async ({ dryRun, rest }) => {
|
|
564
636
|
const { permissionMode, permissionExplicit } = parseInstallOptions(rest);
|
|
565
637
|
const home = claudeHome();
|
|
@@ -586,24 +658,78 @@ const install = async ({ dryRun, rest }) => {
|
|
|
586
658
|
}
|
|
587
659
|
|
|
588
660
|
const hudAccent = await chooseHudAccent();
|
|
589
|
-
progress.
|
|
590
|
-
progress.
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
661
|
+
progress.prepare({ claudeTarget: home, litTarget: litClaudeHome });
|
|
662
|
+
await progress.run(
|
|
663
|
+
{
|
|
664
|
+
number: 1,
|
|
665
|
+
title: "PLUGIN PAYLOAD",
|
|
666
|
+
label: "Plugin payload copied",
|
|
667
|
+
purpose: "Copy the packaged hooks, skills, agents, MCP, and LSP surfaces",
|
|
668
|
+
target: targetPlugin,
|
|
669
|
+
},
|
|
670
|
+
async () => {
|
|
671
|
+
await rm(targetPlugin, { recursive: true, force: true });
|
|
672
|
+
await mkdir(dirname(targetPlugin), { recursive: true });
|
|
673
|
+
await cp(sourcePlugin, targetPlugin, { recursive: true });
|
|
674
|
+
},
|
|
675
|
+
);
|
|
676
|
+
const localMarketplace = await progress.run(
|
|
677
|
+
{
|
|
678
|
+
number: 2,
|
|
679
|
+
title: "LOCAL MARKETPLACE",
|
|
680
|
+
label: "Marketplace metadata written",
|
|
681
|
+
purpose: "Create a local Claude marketplace without a GitHub login",
|
|
682
|
+
target: targetMarketplace,
|
|
683
|
+
},
|
|
684
|
+
() => writeLocalMarketplace(litClaudeHome),
|
|
685
|
+
);
|
|
686
|
+
await progress.run(
|
|
687
|
+
{
|
|
688
|
+
number: 3,
|
|
689
|
+
title: "CLAUDE REGISTRY",
|
|
690
|
+
label: "Claude plugin and HUD enabled",
|
|
691
|
+
purpose: "Enable the plugin, statusLine HUD, and permission preference",
|
|
692
|
+
target: claudeSettingsPath(home),
|
|
693
|
+
},
|
|
694
|
+
() => registerClaudePlugin(targetPlugin, localMarketplace, home, hudAccent, permissionMode),
|
|
695
|
+
);
|
|
598
696
|
|
|
599
|
-
progress.step("Compatibility cache: refreshing local current pointer");
|
|
600
697
|
const litRoot = versionRoot(litClaudeHome);
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
698
|
+
await progress.run(
|
|
699
|
+
{
|
|
700
|
+
number: 4,
|
|
701
|
+
title: "COMPATIBILITY CACHE",
|
|
702
|
+
label: "Compatibility pointer refreshed",
|
|
703
|
+
purpose: "Refresh the versioned fallback used by LitClaude helper commands",
|
|
704
|
+
target: currentRoot(litClaudeHome),
|
|
705
|
+
},
|
|
706
|
+
async () => {
|
|
707
|
+
await rm(litRoot, { recursive: true, force: true });
|
|
708
|
+
await mkdir(dirname(pluginPathForRoot(litRoot)), { recursive: true });
|
|
709
|
+
await cp(sourcePlugin, pluginPathForRoot(litRoot), { recursive: true });
|
|
710
|
+
resetCurrentPointer(litClaudeHome, litRoot);
|
|
711
|
+
},
|
|
712
|
+
);
|
|
713
|
+
await progress.run(
|
|
714
|
+
{
|
|
715
|
+
number: 5,
|
|
716
|
+
title: "INSTALL VERIFICATION",
|
|
717
|
+
label: "Installed surfaces verified",
|
|
718
|
+
purpose: "Confirm the payload, Claude registry, and compatibility pointer",
|
|
719
|
+
target: targetPlugin,
|
|
720
|
+
},
|
|
721
|
+
() => verifyInstalledPayload({ home, litClaudeHome, targetPlugin }),
|
|
722
|
+
);
|
|
605
723
|
|
|
606
|
-
progress.
|
|
724
|
+
progress.receipt([
|
|
725
|
+
["Status", "Ready for Claude Code"],
|
|
726
|
+
["Version", version],
|
|
727
|
+
["Plugin", pluginKey],
|
|
728
|
+
["Plugin path", intendedPluginPath(home)],
|
|
729
|
+
["HUD", `${hudAccent} accent`],
|
|
730
|
+
["Permissions", permissionMode],
|
|
731
|
+
["Launch", "claude"],
|
|
732
|
+
]);
|
|
607
733
|
process.stdout.write(`INSTALL_PASS: LitClaude ${version} installed\n`);
|
|
608
734
|
process.stdout.write(`Claude plugin: ${pluginKey}\n`);
|
|
609
735
|
process.stdout.write(`Marketplace: ${localMarketplace}\n`);
|
package/docs/hooks.md
CHANGED
|
@@ -121,7 +121,9 @@ surfaces and do not activate this prompt hook; code spans, code fences,
|
|
|
121
121
|
substrings, and compound tokens are also ignored. Natural `lit start work`
|
|
122
122
|
returns a `BLOCKED:` handoff that tells the user to run `/start-work` or
|
|
123
123
|
`/litclaude:start-work` with the approved plan, because a prompt hook cannot
|
|
124
|
-
switch Claude Code agents.
|
|
124
|
+
switch Claude Code agents. The `$start-work` shorthand and natural start-work
|
|
125
|
+
phrases activate only when they lead the prompt; diagnostic prose and copied or
|
|
126
|
+
blockquoted mentions remain inert.
|
|
125
127
|
|
|
126
128
|
LitClaude follows the LitClaude goal pattern as an honest native-binding attempt,
|
|
127
129
|
not as slash-command injection. If Claude Code exposes native goal tools, the
|
package/package.json
CHANGED
|
@@ -159,6 +159,7 @@ const containsSlashCommandMention = (text) => slashCommandMentionPattern.test(te
|
|
|
159
159
|
const findDollarCommandTrigger = (raw) => {
|
|
160
160
|
const match = /(?:^|\s)\$(deep-interview|dynamic-workflow|init-deep|lit-plan|lit-recap|lit-loop|start-work|review-work|litgoal|litresearch)(?=$|[^\w-])/u.exec(raw);
|
|
161
161
|
if (!match) return undefined;
|
|
162
|
+
if (match[1] === "start-work" && !/^\s*\$start-work(?=$|[^\w-])/u.test(raw)) return undefined;
|
|
162
163
|
return { ...triggerByToken[match[1]], source: "dollar-command" };
|
|
163
164
|
};
|
|
164
165
|
|
|
@@ -169,6 +170,7 @@ const findLeadingBareCommandTrigger = (raw) => {
|
|
|
169
170
|
};
|
|
170
171
|
|
|
171
172
|
const hasLitTrigger = (raw) => containsCompoundBoundedWord(raw, "lit") || containsCompoundBoundedWord(raw, "litwork");
|
|
173
|
+
const hasTrailingLitInvocation = (raw) => /(?:^|\s)lit(?:work)?\s*$/u.test(raw);
|
|
172
174
|
|
|
173
175
|
const hangulSyllable = /^[가-힣]$/u;
|
|
174
176
|
|
|
@@ -205,12 +207,13 @@ const findNaturalLitTrigger = (prompt) => {
|
|
|
205
207
|
if (hasExplicitTeamRoute(normalized)) return { ...triggerByToken["agent-team"], source: "natural-language" };
|
|
206
208
|
if (hasExplicitWorkflowRoute(normalized)) return { ...triggerByToken["dynamic-workflow"], source: "natural-language" };
|
|
207
209
|
if (containsPlainWord(normalized, "review")) return { ...triggerByToken["review-work"], source: "natural-language" };
|
|
208
|
-
if (
|
|
210
|
+
if (/^\s*lit(?:work)?\s+start\s+work(?=$|[^\w-])/u.test(normalized)) {
|
|
209
211
|
return { ...triggerByToken["start-work"], source: "natural-language", safetyBlock: true };
|
|
210
212
|
}
|
|
211
213
|
if (hasExplicitResearchRoute(normalized)) return { ...triggerByToken.litresearch, source: "natural-language" };
|
|
212
214
|
if (containsPlainWord(normalized, "goal")) return { ...triggerByToken.litgoal, source: "natural-language" };
|
|
213
215
|
if (containsPlainWord(normalized, "plan")) return { ...triggerByToken["lit-plan"], source: "natural-language" };
|
|
216
|
+
if (containsPlainWord(normalized, "start") && containsPlainWord(normalized, "work") && !hasTrailingLitInvocation(normalized)) return undefined;
|
|
214
217
|
return { ...triggerByToken["lit-loop"], source: "natural-language", softConfirm: true };
|
|
215
218
|
};
|
|
216
219
|
|
|
@@ -218,6 +221,7 @@ const findWorkflowTrigger = (prompt) => {
|
|
|
218
221
|
const raw = rawTriggerText(prompt);
|
|
219
222
|
const dollarTrigger = findDollarCommandTrigger(raw);
|
|
220
223
|
if (dollarTrigger) return dollarTrigger;
|
|
224
|
+
if (/(?:^|\s)\$start-work(?=$|[^\w-])/u.test(raw) && !hasTrailingLitInvocation(raw)) return undefined;
|
|
221
225
|
if (containsSlashCommandMention(raw)) return undefined;
|
|
222
226
|
const bareCommandTrigger = findLeadingBareCommandTrigger(raw);
|
|
223
227
|
if (bareCommandTrigger) return bareCommandTrigger;
|