@litfamily/litclaude 1.0.27 → 1.0.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 +6 -0
- package/README.md +8 -8
- package/README_ko-KR.md +8 -8
- package/docs/assets/readme/badge-version.svg +1 -1
- package/package.json +1 -1
- package/plugins/litclaude/.claude-plugin/plugin.json +1 -1
- package/plugins/litclaude/bin/litclaude-ai +48 -0
- package/plugins/litclaude/bin/litclaude-mcp.js +1 -1
- package/plugins/litclaude/lib/mod/state.mjs +4 -0
- package/plugins/litclaude/lib/mod/workflow.mjs +6 -2
- package/plugins/litclaude/lib/start-work-lifecycle.mjs +8 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.0.28 - 2026-10-14
|
|
4
|
+
|
|
5
|
+
- A new lit-loop no longer shows every stage of the card's workflow map as done when an older goal in the project had already finished. The finished goal now ends the map only when it finished after the current stage was recorded, so the map follows the work you are doing now; a goal that really finishes still shows done.
|
|
6
|
+
- `litclaude-ai` is now on the Bash PATH after a plugin install, so the documented `litclaude-ai litgoal`, `start-work`, `workflow-stage` and similar commands run without the npm package. Other subcommands point you at the npm package.
|
|
7
|
+
- The start-work gate lets its own `start-work pause` through when it names an outside target root. The pause records a pending boundary and grants nothing; forbidden actions are still refused.
|
|
8
|
+
|
|
3
9
|
## 1.0.27 - 2026-10-13
|
|
4
10
|
|
|
5
11
|
- The lit-loop map now moves when the work happens in the shell. Writing a test with a shell command (`cat > test/…`, `>>`, `tee` or `sed -i`) turns the map to RED, changing a source file the same way turns it to GREEN, and the next test run turns it to VERIFY. A failing test run while the criterion is still pinned also counts as RED, including a bare `npm test` that exits with an error. The card keeps only the stage, never the command or the file names.
|
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.
|
|
1
|
+
<p align="center"><picture><source media="(prefers-reduced-motion: reduce)" srcset="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.28/docs/assets/cover-motion-still.webp" /><img src="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.28/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.
|
|
8
|
-
<a href="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.
|
|
7
|
+
<img src="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.28/docs/assets/readme/badge-version.svg" alt="1.0.28" />
|
|
8
|
+
<a href="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.28/LICENSE"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.28/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.
|
|
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.28/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.
|
|
77
|
-
- [Migration and ownership conflicts](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.
|
|
78
|
-
- [Release history](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.
|
|
79
|
-
- [MIT license](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.
|
|
76
|
+
- [Privacy and network behavior](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.28/docs/privacy.md)
|
|
77
|
+
- [Migration and ownership conflicts](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.28/docs/migration.md)
|
|
78
|
+
- [Release history](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.28/CHANGELOG.md)
|
|
79
|
+
- [MIT license](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.28/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.
|
|
1
|
+
<p align="center"><picture><source media="(prefers-reduced-motion: reduce)" srcset="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.28/docs/assets/cover-motion-still.webp" /><img src="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.28/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.
|
|
8
|
-
<a href="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.
|
|
7
|
+
<img src="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.28/docs/assets/readme/badge-version.svg" alt="1.0.28" />
|
|
8
|
+
<a href="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.28/LICENSE"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.28/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.
|
|
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.28/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.
|
|
75
|
-
- [이전과 소유권 충돌](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.
|
|
76
|
-
- [변경 이력](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.
|
|
77
|
-
- [MIT 라이선스](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.
|
|
74
|
+
- [개인정보와 네트워크 동작](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.28/docs/privacy.md)
|
|
75
|
+
- [이전과 소유권 충돌](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.28/docs/migration.md)
|
|
76
|
+
- [변경 이력](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.28/CHANGELOG.md)
|
|
77
|
+
- [MIT 라이선스](https://cdn.jsdelivr.net/npm/@litfamily/litclaude@1.0.28/LICENSE)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="146" height="20" role="img" aria-label="release: 1.0.
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="146" height="20" role="img" aria-label="release: 1.0.28"><title>release: 1.0.28</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.28</text></g></svg>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@litfamily/litclaude",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.28",
|
|
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": {
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// The `litclaude-ai` the skills and commands name, as the installed plugin serves it. Claude Code
|
|
3
|
+
// puts this bin/ directory on the Bash tool's PATH; the npm CLI (bin/litclaude-ai.js in the
|
|
4
|
+
// package) is usually not there. This entry runs the in-session subcommands from the plugin's own
|
|
5
|
+
// lib/ and sends everything else (install, doctor, update…) to the user's terminal.
|
|
6
|
+
//
|
|
7
|
+
// No file extension, so the bare name resolves on PATH; the code avoids `import`, `require`,
|
|
8
|
+
// `import.meta` and `module` so it runs whether Node loads it as CommonJS or as an ES module.
|
|
9
|
+
|
|
10
|
+
const SUBCOMMANDS = {
|
|
11
|
+
litgoal: async (load, rest) => (await load("../lib/litgoal/cli.mjs")).runLitgoalCli(rest),
|
|
12
|
+
"start-work": async (load, rest) => (await load("../lib/start-work-cli.mjs")).runStartWorkCli(rest, undefined, process.cwd()),
|
|
13
|
+
"start-work-next": async (load, rest) => {
|
|
14
|
+
const { resolveProjectStateRoot } = await load("../lib/project-state-root.mjs");
|
|
15
|
+
return (await load("../lib/start-work-continuation.mjs")).runStartWorkContinuationCli(resolveProjectStateRoot(process.cwd()), rest);
|
|
16
|
+
},
|
|
17
|
+
"workflow-stage": async (load, rest) => (await load("../lib/workflow-stage.mjs")).runWorkflowStageCli(rest, process.cwd()),
|
|
18
|
+
wikify: async (load, rest) => (await load("../lib/wikify-knowledge-cli.mjs")).runWikifyKnowledgeCli(rest, undefined, process.cwd()),
|
|
19
|
+
"motion-runtime": async (load, rest) => (await load("../skills/lit-typographic-motion/scripts/motion-runtime.mjs")).main(rest),
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const main = async () => {
|
|
23
|
+
const [command, ...rest] = process.argv.slice(2);
|
|
24
|
+
const run = Object.hasOwn(SUBCOMMANDS, command ?? "") ? SUBCOMMANDS[command] : null;
|
|
25
|
+
if (!run) {
|
|
26
|
+
process.stderr.write(
|
|
27
|
+
`litclaude-ai (plugin): ${command ? `"${command}" is not served from the plugin` : "no command given"}. `
|
|
28
|
+
+ `In-session commands: ${Object.keys(SUBCOMMANDS).join(", ")}. `
|
|
29
|
+
+ `For install, update, doctor and the rest, ask the user to run in their own terminal: npx @litfamily/litclaude ${command ?? "--help"}\n`,
|
|
30
|
+
);
|
|
31
|
+
return 64;
|
|
32
|
+
}
|
|
33
|
+
const { realpathSync } = await import("node:fs");
|
|
34
|
+
const { dirname, join } = await import("node:path");
|
|
35
|
+
const { pathToFileURL } = await import("node:url");
|
|
36
|
+
const here = dirname(realpathSync(process.argv[1]));
|
|
37
|
+
return run((relative) => import(pathToFileURL(join(here, relative)).href), rest);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
main().then(
|
|
41
|
+
(code) => {
|
|
42
|
+
process.exitCode = Number.isInteger(code) ? code : 0;
|
|
43
|
+
},
|
|
44
|
+
(error) => {
|
|
45
|
+
process.stderr.write(`litclaude-ai (plugin): ${error?.message ?? error}\n`);
|
|
46
|
+
process.exitCode = 1;
|
|
47
|
+
},
|
|
48
|
+
);
|
|
@@ -233,6 +233,10 @@ export const parseGoals = (state, sessionId) => {
|
|
|
233
233
|
.filter(Boolean),
|
|
234
234
|
lastCheckpoint: str(Array.isArray(state.checkpoints) ? state.checkpoints.at(-1)?.status : null, 40),
|
|
235
235
|
createdAt: time(state.createdAt),
|
|
236
|
+
// When the goal was finished: its last `complete` checkpoint, else its last update.
|
|
237
|
+
completedAt: state.status === "complete"
|
|
238
|
+
? time((Array.isArray(state.checkpoints) ? state.checkpoints : []).findLast((entry) => entry?.status === "complete")?.createdAt) ?? time(state.updatedAt)
|
|
239
|
+
: null,
|
|
236
240
|
};
|
|
237
241
|
};
|
|
238
242
|
|
|
@@ -111,6 +111,10 @@ const entryOf = ({ snapshot, skills, now }) => {
|
|
|
111
111
|
return candidates.sort((a, b) => b.at - a.at || (a.from === "record" ? -1 : 1))[0] ?? null;
|
|
112
112
|
};
|
|
113
113
|
|
|
114
|
+
// A finished goal ends the map unless a stage record, skill or ignition came after it: that is a
|
|
115
|
+
// new request, and the old finish says nothing about it.
|
|
116
|
+
const goalFinished = (goal, entry) => goal?.status === "complete" && !(Number.isFinite(goal.completedAt) && Number.isFinite(entry?.at) && entry.at > goal.completedAt);
|
|
117
|
+
|
|
114
118
|
const goalIsOpen = (goal) => Boolean(goal && ["active", "blocked", "review_blocked", "needs_user_decision"].includes(goal.status));
|
|
115
119
|
|
|
116
120
|
// Without a discipline or a record, the durable state that says work is under way.
|
|
@@ -173,7 +177,7 @@ export const buildWorkflow = ({ snapshot, skills = [], completion = null, now })
|
|
|
173
177
|
const planSaved = stage === "plan" && record?.stage === "plan" && record.done;
|
|
174
178
|
if (planSaved) stage = "work";
|
|
175
179
|
const lanes = record?.stage === "review" ? laneVerdicts(record.verdicts) : null;
|
|
176
|
-
if (completion || goal
|
|
180
|
+
if (completion || goalFinished(goal, entry) || stage === "done") stage = "done";
|
|
177
181
|
else if (stage === "work" && !work && !goalIsOpen(goal) && snapshot.completedWorkIds.length > 0) stage = "review";
|
|
178
182
|
else if (stage === "review" && lanes?.every(({ state }) => state === "pass")) stage = "done";
|
|
179
183
|
if (planSaved && stage === "work" && !work) items.push("plan saved");
|
|
@@ -226,7 +230,7 @@ export const buildWorkflow = ({ snapshot, skills = [], completion = null, now })
|
|
|
226
230
|
}
|
|
227
231
|
|
|
228
232
|
const order = WORKFLOW_FAMILIES[family];
|
|
229
|
-
const finished = family === "main" ? stage === "done" : completion !== null || (family === "loop" && snapshot.goal
|
|
233
|
+
const finished = family === "main" ? stage === "done" : completion !== null || (family === "loop" && goalFinished(snapshot.goal, entry));
|
|
230
234
|
const current = finished ? -1 : order.indexOf(stage);
|
|
231
235
|
const wave = sources.research?.wave ?? 0;
|
|
232
236
|
const stages = order.map((id, index) => {
|
|
@@ -990,6 +990,14 @@ const classifyBashWords = (words, cwd) => {
|
|
|
990
990
|
if (rest[0] === "start-work" && START_WORK_SELF_MOVES.has(rest[1]) && !rest.includes("--root") && rest.every((word) => !word.includes("/"))) {
|
|
991
991
|
return canonicalBashTargets(cwd, [cwd, ...cli], "write");
|
|
992
992
|
}
|
|
993
|
+
// `pause` is how the work asks the user for a new boundary: it records the pending boundary
|
|
994
|
+
// and grants nothing, so the root it names may lie outside the grants, and the lifecycle
|
|
995
|
+
// refuses a forbidden action itself. Only that `--target-root` value may hold a `/`, and only
|
|
996
|
+
// the bare CLI name passes: a `node <path>/litclaude-ai.js` file is checked by name, not content.
|
|
997
|
+
if (cli.length === 0 && rest[0] === "start-work" && rest[1] === "pause" && !rest.includes("--root")
|
|
998
|
+
&& rest.every((word, index) => !word.includes("/") || rest[index - 1] === "--target-root")) {
|
|
999
|
+
return canonicalBashTargets(cwd, [cwd, ...cli], "write");
|
|
1000
|
+
}
|
|
993
1001
|
}
|
|
994
1002
|
if (head.text === "node") return classifyNodeScriptWords(args, cwd);
|
|
995
1003
|
return null;
|