litclaude-ai 0.3.32 → 0.3.34

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.
Files changed (55) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +27 -5
  3. package/README_ko-KR.md +27 -5
  4. package/RELEASE_CHECKLIST.md +57 -10
  5. package/bin/litclaude-ai.js +63 -24
  6. package/bin/update-notifier-refresh.mjs +7 -0
  7. package/bin/update-notifier.mjs +504 -0
  8. package/docs/native-goal-surface.md +41 -0
  9. package/package.json +2 -1
  10. package/plugins/litclaude/.claude-plugin/plugin.json +1 -1
  11. package/plugins/litclaude/agents/oracle-verifier.md +7 -1
  12. package/plugins/litclaude/agents/quality-reviewer.md +7 -1
  13. package/plugins/litclaude/bin/litclaude-mcp.js +1 -1
  14. package/plugins/litclaude/lib/canonical-skill-catalog.mjs +39 -0
  15. package/plugins/litclaude/lib/canonical-skill-resources.mjs +47 -0
  16. package/plugins/litclaude/lib/skill-resource-integrity.mjs +31 -0
  17. package/plugins/litclaude/lib/strict-json.mjs +143 -0
  18. package/plugins/litclaude/skills/frontend-ui-ux/LICENSE +21 -0
  19. package/plugins/litclaude/skills/frontend-ui-ux/PROVENANCE.json +38 -0
  20. package/plugins/litclaude/skills/frontend-ui-ux/SKILL.md +370 -76
  21. package/plugins/litclaude/skills/frontend-ui-ux/SOURCE-MANIFEST.json +1060 -0
  22. package/plugins/litclaude/skills/frontend-ui-ux/THIRD-PARTY-NOTICE.txt +14 -0
  23. package/plugins/litclaude/skills/frontend-ui-ux/data/design-intelligence.json +1 -0
  24. package/plugins/litclaude/skills/frontend-ui-ux/schemas/design-contract-v1alpha1.schema.json +362 -0
  25. package/plugins/litclaude/skills/frontend-ui-ux/scripts/design-contract-inventory-rules.mjs +120 -0
  26. package/plugins/litclaude/skills/frontend-ui-ux/scripts/design-contract-rules.mjs +188 -0
  27. package/plugins/litclaude/skills/frontend-ui-ux/scripts/design-contract-surface-rules.mjs +134 -0
  28. package/plugins/litclaude/skills/frontend-ui-ux/scripts/design-data.mjs +68 -0
  29. package/plugins/litclaude/skills/frontend-ui-ux/scripts/errors.mjs +12 -0
  30. package/plugins/litclaude/skills/frontend-ui-ux/scripts/import-design-intelligence.mjs +124 -0
  31. package/plugins/litclaude/skills/frontend-ui-ux/scripts/json-boundary.mjs +63 -0
  32. package/plugins/litclaude/skills/frontend-ui-ux/scripts/query-design-intelligence.mjs +106 -0
  33. package/plugins/litclaude/skills/frontend-ui-ux/scripts/search.mjs +43 -0
  34. package/plugins/litclaude/skills/frontend-ui-ux/scripts/source-replay.mjs +153 -0
  35. package/plugins/litclaude/skills/frontend-ui-ux/scripts/validate-design-contract.mjs +39 -0
  36. package/plugins/litclaude/skills/lit-loop/SKILL.md +3 -0
  37. package/plugins/litclaude/skills/review-work/SKILL.md +6 -0
  38. package/plugins/litclaude/skills/start-work/SKILL.md +10 -0
  39. package/plugins/litclaude/skills/visual-qa/SKILL.md +461 -356
  40. package/plugins/litclaude/skills/visual-qa/schemas/evidence-manifest-v1alpha1.schema.json +234 -0
  41. package/plugins/litclaude/skills/visual-qa/schemas/review-receipt-v1alpha1.schema.json +63 -0
  42. package/plugins/litclaude/skills/visual-qa/scripts/cli.mjs +95 -0
  43. package/plugins/litclaude/skills/visual-qa/scripts/errors.mjs +12 -0
  44. package/plugins/litclaude/skills/visual-qa/scripts/evidence-io.mjs +102 -0
  45. package/plugins/litclaude/skills/visual-qa/scripts/evidence-semantic.mjs +94 -0
  46. package/plugins/litclaude/skills/visual-qa/scripts/evidence-shape.mjs +141 -0
  47. package/plugins/litclaude/skills/visual-qa/scripts/evidence.mjs +245 -0
  48. package/plugins/litclaude/skills/visual-qa/scripts/image-diff.mjs +89 -0
  49. package/plugins/litclaude/skills/visual-qa/scripts/png-chunks.mjs +107 -0
  50. package/plugins/litclaude/skills/visual-qa/scripts/png-decode.mjs +143 -0
  51. package/plugins/litclaude/skills/visual-qa/scripts/review-rules.mjs +135 -0
  52. package/plugins/litclaude/skills/visual-qa/scripts/terminal-text.mjs +117 -0
  53. package/plugins/litclaude/skills/visual-qa/scripts/tui-check.mjs +74 -0
  54. package/scripts/doctor.mjs +25 -3
  55. package/scripts/qa-uiux-visual-qa-scenarios.mjs +185 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,39 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.34 - 2026-07-25 — evidence-first UI/UX and visual QA
4
+
5
+ - Add the packaged `frontend-ui-ux` design-intelligence workflow with a
6
+ 2,277-record offline dataset, pinned source manifest, provenance and license
7
+ records, a strict Design Contract schema, and bounded retrieval/import tools.
8
+ - Add strict visual evidence and independent-review schemas, bounded PNG and
9
+ TUI analyzers, honest capability blockers, zero smoke review receipts, and
10
+ exactly two independent receipts for full and reference-fidelity runs.
11
+ - Enroll both skills through the canonical catalog, CLI, doctor, installer,
12
+ package guards, and adversarial scenario tests; prevent blocking P1 findings
13
+ from retaining `PASS`, keep reviewers read-only, and bound TUI captures to
14
+ 1 MiB and 4,096 lines.
15
+
16
+ ## 0.3.33 - 2026-07-24 — update notice and installed catalog verification
17
+
18
+ - Add a nonblocking npm update notice for interactive `install`, `update`, and
19
+ `doctor`, backed by a strict product cache, atomic concurrent reservation,
20
+ and bounded official registry refresh. Attempt timestamps throttle successful,
21
+ offline, failed, and interrupted checks for 24 hours without discarding the
22
+ last trusted result; stale trusted results may still notify, while future or
23
+ noncanonical timestamps fail safe. Transition/recovery mutex ownership and
24
+ per-attempt generation fencing prevent stale takeover or late-worker cache
25
+ overwrite. CI/JSON/dry-run/non-TTY and environment opt-outs remain authoritative.
26
+ - Preserve the installed permission mode and HUD accent during an optionless
27
+ reinstall while retaining explicit overrides.
28
+ - Make source doctor, install verification, installed doctor, and Claude plugin
29
+ details share the exact canonical skill catalog. Missing installed skill
30
+ payloads now fail with `DOCTOR_FAIL`, and packed-install corruption coverage
31
+ proves the user-facing doctor cannot report success for an incomplete catalog.
32
+ - Add a narrow native `/goal` capability matrix for user/Remote Control,
33
+ SDK-owned, separate print, and already-open TUI session boundaries without a
34
+ plugin runtime bridge, including minimum client, workspace trust, policy/hook,
35
+ and SDK-advertised command prerequisites.
36
+
3
37
  ## 0.3.32 - 2026-07-23 — bounded-authority start-work lifecycle
4
38
 
5
39
  - Added a code-owned schema-3 start-work runtime with canonical authority roots,
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.32-2ea44f" />
12
+ <img src="https://img.shields.io/badge/version-0.3.34-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.32` for personal install
25
+ This checkout is prepared as `litclaude-ai@0.3.34` 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.32 release material adds the code-owned schema-3 start-work lifecycle with canonical bounded authority, explicit single-use resume grants, PreToolUse enforcement, root/subagent lane identity, progress-bound Stop continuation receipts, and fail-closed release boundaries. The v0.3.31 release material hardens litgoal creation, replacement, completion, and autoloop receipts while making visual QA browser ownership, bounded waits, blocked states, and cleanup evidence explicit. The v0.3.30 release material strengthens LitResearch with root-owned scientific evidence records, DOI/PDF lifecycle receipts, bounded route coverage, and a connection-pinned public-source reader with inert-content and secret-redaction guarantees. The v0.3.29 release material bundles exact-source `lit-handoff` and `lit-scientific-visualization` skills with Claude-native commands, exact-bare hook invocation, visible LITBURN banners, installed-payload integrity checks, and read-only scientific dependency diagnostics. 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
28
+ Future package releases still require explicit user approval. The v0.3.34 release material adds packaged evidence-first UI/UX design intelligence, strict Design/Evidence/Review contracts, bounded PNG and TUI inspection, tier-correct independent review, and adversarial zero-false-PASS coverage. The v0.3.33 release material adds a quiet nonblocking npm update notice with strict cache, concurrency, timestamp, opt-out, and official-registry boundaries; preserves the installed permission mode and HUD accent on optionless updates; and makes source, install, installed-doctor, and Claude-details checks share the exact canonical skill catalog so missing packaged skills fail with `DOCTOR_FAIL`. The v0.3.32 release material adds the code-owned schema-3 start-work lifecycle with canonical bounded authority, explicit single-use resume grants, PreToolUse enforcement, root/subagent lane identity, progress-bound Stop continuation receipts, and fail-closed release boundaries. The v0.3.31 release material hardens litgoal creation, replacement, completion, and autoloop receipts while making visual QA browser ownership, bounded waits, blocked states, and cleanup evidence explicit. The v0.3.30 release material strengthens LitResearch with root-owned scientific evidence records, DOI/PDF lifecycle receipts, bounded route coverage, and a connection-pinned public-source reader with inert-content and secret-redaction guarantees. The v0.3.29 release material bundles exact-source `lit-handoff` and `lit-scientific-visualization` skills with Claude-native commands, exact-bare hook invocation, visible LITBURN banners, installed-payload integrity checks, and read-only scientific dependency diagnostics. 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
@@ -131,7 +131,7 @@ directory, the normal install command works:
131
131
 
132
132
  ```bash
133
133
  cd /tmp
134
- npx --yes litclaude-ai@0.3.32 install
134
+ npx --yes litclaude-ai@0.3.34 install
135
135
  ```
136
136
 
137
137
  Validate the installed plugin:
@@ -140,11 +140,26 @@ Validate the installed plugin:
140
140
  npx --yes litclaude-ai doctor
141
141
  ```
142
142
 
143
+ Interactive `install`, `update`, and `doctor` runs may show a quiet update notice
144
+ on stderr from LitClaude's own cache. A strictly validated last successful
145
+ version may still be shown after it becomes stale. At most one new attempt is
146
+ reserved per 24 hours across concurrent parents; that reservation remains after
147
+ offline, failed, or interrupted refreshes while preserving the last successful
148
+ version and check time. A transition/recovery mutex and per-attempt ownership
149
+ generation serialize stale takeover and completion, so an old worker cannot
150
+ remove a newer reservation or overwrite its result. The refresh is a detached, three-second request to the
151
+ official npm registry, so the management command does not wait. Noncanonical or
152
+ future cache timestamps are not trusted. The notice is disabled for CI, JSON,
153
+ dry-run, or non-TTY use and by either `NO_UPDATE_NOTIFIER` or
154
+ `LITCLAUDE_NO_UPDATE_CHECK`. It never reads npm credentials or installs an
155
+ update. Follow the version-pinned `npx --yes litclaude-ai@<version> install`
156
+ command shown in the notice, then restart Claude Code.
157
+
143
158
  The installer also sets Claude Code's `statusLine` command to the packaged
144
159
  LitClaude HUD. A typical no-color render starts like:
145
160
 
146
161
  ```text
147
- [🔥LITCLAUDE v0.3.32] | O4.8 │ ctx [▎░░] 9%/1000k │ 5h [▏░] 4% ↻2h15m │ 1w [▊░] 35% ↻3d6h │ git main +3 ✓
162
+ [🔥LITCLAUDE v0.3.34] | O4.8 │ ctx [▎░░] 9%/1000k │ 5h [▏░] 4% ↻2h15m │ 1w [▊░] 35% ↻3d6h │ git main +3 ✓
148
163
  ```
149
164
 
150
165
  The `↻` suffix is a compact rate-limit reset countdown. It is separated from
@@ -159,6 +174,10 @@ To override the accent without the picker, set `LITCLAUDE_HUD_ACCENT` to one
159
174
  of `cyan`, `blue`, `teal`, `green`, `lavender`, `rose`, `gold`, `orange`,
160
175
  `slate`, or `gray` before installing.
161
176
 
177
+ An optionless `litclaude update` preserves the installed permission mode and
178
+ HUD accent. An explicit `--permission-mode` / `--yolo` choice or
179
+ `LITCLAUDE_HUD_ACCENT` value still overrides the saved choice.
180
+
162
181
  Launch Claude Code normally:
163
182
 
164
183
  ```bash
@@ -294,6 +313,9 @@ litclaude litgoal native-worker --condition "<completion condition>" --mode bg -
294
313
  `native-worker` starts a separate print/background Claude Code worker whose first
295
314
  prompt begins with `/goal`; it does not arm the already-open TUI, does not use
296
315
  tmux keystroke injection, and does not mutate private transcript metadata.
316
+ See the clean-room [native `/goal` surface matrix](./docs/native-goal-surface.md)
317
+ for the separate User / Remote Control, SDK-owned, `claude -p`, and already-open
318
+ TUI capability boundaries plus a ready-to-paste ledger-backed condition.
297
319
  For large independent work, LitClaude applies the same principle to Claude
298
320
  Code's available orchestration surfaces: `lit workflow`, `lit dynamic workflow`,
299
321
  and `lit ultracode` prefer current `ultracode` or explicit “run a workflow” /
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.32-2ea44f" />
12
+ <img src="https://img.shields.io/badge/version-0.3.34-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.32` 배포 준비용으로 정리되어 있습니다. 목적은
29
+ 현재 checkout은 `litclaude-ai@0.3.34` 배포 준비용으로 정리되어 있습니다. 목적은
30
30
  다른 PC에서도 빠르게 설치하기 위한 개인용 package metadata를 갖추는 것입니다.
31
31
  npm package metadata를 준비했다고 해서 홍보, 공개 저장소 운영, Claude
32
32
  marketplace 등록을 의미하지는 않습니다. 새 버전 배포는 항상 별도의 명시적
33
- 승인 후에 진행합니다. v0.3.32 release material은 canonical bounded authority, single-use resume grant, PreToolUse enforcement, root/subagent lane identity, progress-bound Stop continuation receipt, fail-closed release boundary를 갖춘 code-owned schema-3 start-work lifecycle을 추가합니다. v0.3.31 release material은 litgoal 생성·교체·완료와 autoloop receipt를 강화하고 visual QA의 browser ownership, bounded wait, blocked state, cleanup evidence를 명확히 합니다. v0.3.30 release material은 root-owned scientific evidence record, DOI/PDF lifecycle receipt, bounded route coverage, connection-pinned public-source reader, inert-content 및 secret-redaction 보장을 포함하는 LitResearch 강화판입니다. v0.3.29 release material은 exact-source `lit-handoff`와 `lit-scientific-visualization` skill, Claude-native command, exact-bare hook invocation, visible LITBURN banner, installed-payload integrity check, read-only scientific dependency diagnostic을 함께 포함합니다. 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`,
33
+ 승인 후에 진행합니다. v0.3.34 release material은 packaged evidence-first UI/UX design intelligence, strict Design/Evidence/Review contract, bounded PNG/TUI inspection, tier-correct independent review, adversarial zero-false-PASS coverage를 추가합니다. v0.3.33 release material은 strict cache, concurrency, timestamp, opt-out, official-registry boundary를 갖춘 조용한 nonblocking npm update notice를 추가하고, optionless update에서 기존 permission mode와 HUD accent를 보존하며, source/install/installed doctor/Claude details가 정확한 canonical skill catalog를 공유해 packaged skill 누락 시 `DOCTOR_FAIL`로 실패하도록 합니다. v0.3.32 release material은 canonical bounded authority, single-use resume grant, PreToolUse enforcement, root/subagent lane identity, progress-bound Stop continuation receipt, fail-closed release boundary를 갖춘 code-owned schema-3 start-work lifecycle을 추가합니다. v0.3.31 release material은 litgoal 생성·교체·완료와 autoloop receipt를 강화하고 visual QA의 browser ownership, bounded wait, blocked state, cleanup evidence를 명확히 합니다. v0.3.30 release material은 root-owned scientific evidence record, DOI/PDF lifecycle receipt, bounded route coverage, connection-pinned public-source reader, inert-content 및 secret-redaction 보장을 포함하는 LitResearch 강화판입니다. v0.3.29 release material은 exact-source `lit-handoff`와 `lit-scientific-visualization` skill, Claude-native command, exact-bare hook invocation, visible LITBURN banner, installed-payload integrity check, read-only scientific dependency diagnostic을 함께 포함합니다. 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`
@@ -131,7 +131,7 @@ checkout을 먼저 해석해서 `sh: litclaude-ai: command not found`로 실패
131
131
 
132
132
  ```bash
133
133
  cd /tmp
134
- npx --yes litclaude-ai@0.3.32 install
134
+ npx --yes litclaude-ai@0.3.34 install
135
135
  ```
136
136
 
137
137
  설치 상태를 확인합니다.
@@ -140,11 +140,26 @@ npx --yes litclaude-ai@0.3.32 install
140
140
  npx --yes litclaude-ai doctor
141
141
  ```
142
142
 
143
+ interactive `install`, `update`, `doctor`에서는 LitClaude가 소유하는 cache의
144
+ 마지막으로 검증된 성공 버전이 오래되었더라도 조용한 update notice를 stderr에
145
+ 표시할 수 있습니다. 여러 parent가 동시에 실행되어도 atomic reservation으로
146
+ 24시간에 한 번만 새 조회를 예약합니다. offline, 실패, 중단된 조회도 attempted
147
+ time을 남겨 24시간 동안 재시도를 제한하되 마지막 성공 version/check time은
148
+ 보존합니다. transition/recovery mutex와 attempt별 ownership generation이 stale
149
+ takeover와 completion을 직렬화하므로 이전 worker가 새 reservation을 지우거나 새
150
+ 결과를 덮어쓸 수 없습니다. refresh는 official npm registry를 최대 3초 동안 조회하는 detached
151
+ process이므로 management command는 기다리지 않습니다. canonical하지 않거나
152
+ 미래인 cache timestamp는 신뢰하지 않습니다. CI, JSON, dry-run, non-TTY에서는
153
+ 동작하지 않으며 `NO_UPDATE_NOTIFIER` 또는 `LITCLAUDE_NO_UPDATE_CHECK`로 끌 수
154
+ 있습니다. npm credential을 읽거나 update를 자동 설치하지 않습니다. notice가 제시한
155
+ `npx --yes litclaude-ai@<version> install`을 실행한 뒤 Claude Code를 다시
156
+ 시작하세요.
157
+
143
158
  installer는 Claude Code의 `statusLine` command도 packaged LitClaude HUD로
144
159
  설정합니다. 색상을 제거한 예시는 다음처럼 시작합니다.
145
160
 
146
161
  ```text
147
- [🔥LITCLAUDE v0.3.32] | O4.8 │ ctx [▎░░] 9%/1000k │ 5h [▏░] 4% ↻2h15m │ 1w [▊░] 35% ↻3d6h │ git main +3 ✓
162
+ [🔥LITCLAUDE v0.3.34] | O4.8 │ ctx [▎░░] 9%/1000k │ 5h [▏░] 4% ↻2h15m │ 1w [▊░] 35% ↻3d6h │ git main +3 ✓
148
163
  ```
149
164
 
150
165
  `↻` 표시는 rate-limit reset까지 남은 시간을 짧게 보여주는 countdown입니다.
@@ -158,6 +173,10 @@ picker 없이 색상을 지정하려면 설치 전에 `LITCLAUDE_HUD_ACCENT`를
158
173
  `cyan`, `blue`, `teal`, `green`, `lavender`, `rose`, `gold`, `orange`,
159
174
  `slate`, `gray` 중 하나로 설정하세요.
160
175
 
176
+ option을 생략한 `litclaude update`는 기존 permission mode와 HUD accent를
177
+ 보존합니다. 명시적인 `--permission-mode` / `--yolo` 선택 또는
178
+ `LITCLAUDE_HUD_ACCENT` 값은 저장된 선택을 계속 override합니다.
179
+
161
180
  설치 후에는 일반적인 `claude` 명령으로 Claude Code를 실행합니다.
162
181
 
163
182
  ```bash
@@ -284,6 +303,9 @@ litclaude litgoal native-worker --condition "<completion condition>" --mode bg -
284
303
  `native-worker`는 첫 prompt가 `/goal`로 시작하는 별도 print/background Claude
285
304
  Code worker를 시작합니다. 이미 열린 TUI를 arm하지 않고, tmux keystroke
286
305
  injection이나 private transcript metadata 변경도 사용하지 않습니다.
306
+ User / Remote Control, SDK-owned session, 별도 `claude -p`, 이미 열린 TUI의
307
+ capability boundary와 ledger 기반 ready-to-paste condition은 clean-room
308
+ [native `/goal` surface matrix](./docs/native-goal-surface.md)에 정리되어 있습니다.
287
309
  `Workflow`가 노출되면 먼저 제안하고 사용자 opt-in 또는 이미 허용된 orchestration
288
310
  상태에서만 `Workflow` tool을 호출합니다. isolated edit lane이 model-facing
289
311
  worktree를 필요로 하면 `EnterWorktree`를 사용합니다. CLI surface만 가능한 새 격리
@@ -1,9 +1,17 @@
1
1
  # LitClaude Release Checklist
2
2
 
3
- Status: `litclaude-ai@0.3.32` is the current release candidate — a code-owned
4
- schema-3 start-work lifecycle with canonical bounded authority, single-use
5
- resume grants, PreToolUse enforcement, root/subagent lane identity, bounded Stop
6
- continuation receipts, and fail-closed release boundaries, plus guarded litgoal
3
+ Status: `litclaude-ai@0.3.34` is the current release candidate — packaged
4
+ evidence-first UI/UX design intelligence, strict Design/Evidence/Review
5
+ contracts, bounded PNG and TUI inspection, tier-correct independent review, and
6
+ adversarial zero-false-PASS coverage. It also carries the quiet nonblocking npm
7
+ update notice with strict cache, concurrency, timestamp, opt-out, and
8
+ official-registry boundaries; optionless update preservation for the installed
9
+ permission mode and HUD accent; and a shared canonical skill catalog enforced
10
+ by source, install, installed-doctor, and Claude-details checks, with
11
+ `DOCTOR_FAIL` on missing installed skills, plus the
12
+ code-owned schema-3 start-work lifecycle with canonical bounded authority,
13
+ single-use resume grants, PreToolUse enforcement, root/subagent lane identity,
14
+ bounded Stop continuation receipts, and fail-closed release boundaries, plus guarded litgoal
7
15
  creation and replacement, durable idempotent autoloop completion, and explicit
8
16
  visual QA backend ownership, bounded waits, blocked states, and cleanup receipts,
9
17
  plus root-owned scientific evidence records, DOI/PDF lifecycle receipts, bounded route coverage,
@@ -28,9 +36,9 @@ side-effect-free, the launcher starts only a separate Claude Code
28
36
  print/background worker, and the release preserves the Korean polishing
29
37
  command, strict multi-agent review pipeline, fidelity guardrails, package
30
38
  hygiene checks, native route gates, and safe start-work handoff behavior.
31
- `package.json` is aligned to `0.3.32`,
32
- `plugins/litclaude/.claude-plugin/plugin.json` is aligned to `0.3.32`, and the
33
- plugin-local MCP server reports `0.3.32`.
39
+ `package.json` is aligned to `0.3.34`,
40
+ `plugins/litclaude/.claude-plugin/plugin.json` is aligned to `0.3.34`, and the
41
+ plugin-local MCP server reports `0.3.34`.
34
42
 
35
43
  This release carries the v0.2.2 Dynamic workflow hardening surfaces:
36
44
  `/dynamic-workflow`, `workflow-check --json`, native `/goal` fallback guidance,
@@ -57,6 +65,10 @@ behavior.
57
65
 
58
66
  - `npm test`
59
67
  - `npm run validate:plugin`
68
+ - `npm run doctor`
69
+ - `npm run check:version`
70
+ - `npm run scan:legacy-tokens`
71
+ - `npm run pack:payload-guard`
60
72
  - `npm run qa:tmux`
61
73
  - `npm run qa:portable`
62
74
  - `npm run pack:dry-run`
@@ -74,6 +86,41 @@ Use this track when testing from the current checkout:
74
86
 
75
87
  No npm publication is required for this track.
76
88
 
89
+ ## v0.3.34 Evidence-First UI/UX and Visual QA Gates
90
+
91
+ Before requesting publication approval, confirm `frontend-ui-ux` ships the
92
+ 2,277-record offline dataset, pinned source manifest, provenance, license
93
+ records, strict Design Contract schema, and bounded retrieval/import tools.
94
+ Confirm `visual-qa` ships strict Evidence Manifest and Review Receipt schemas,
95
+ bounded PNG and TUI analyzers, and stable capability blocker codes.
96
+
97
+ Smoke evidence must contain zero independent review receipts. Full and
98
+ reference-fidelity evidence must contain exactly two independent receipts from
99
+ the declared reviewer capabilities. A blocking P1 finding must invalidate
100
+ `PASS`, and the reviewer agents must expose only `Read`, `Grep`, and `Glob`.
101
+ TUI captures must reject inputs above 1 MiB or 4,096 lines before emitting
102
+ unbounded result arrays.
103
+
104
+ Confirm the source-checkout-only adversarial replay is labeled honestly while
105
+ the installed package can run its packaged visual CLI against caller-owned
106
+ captures. Source doctor, isolated install, installed doctor, canonical resource
107
+ integrity, scenario replay, and package-payload guards must all pass.
108
+
109
+ ## v0.3.33 Update Notice and Canonical Catalog Gates
110
+
111
+ Before requesting publication approval, confirm interactive `install`, `update`,
112
+ and `doctor` can show only the quiet stderr update notice while CI, JSON,
113
+ dry-run, non-TTY, `NO_UPDATE_NOTIFIER`, and `LITCLAUDE_NO_UPDATE_CHECK` remain
114
+ authoritative opt-outs. Confirm the cache accepts only stable official-package
115
+ metadata, preserves the last trusted result across failed refreshes, throttles
116
+ attempts for 24 hours, and fences stale owners from newer reservations.
117
+
118
+ Confirm source doctor, installation verification, installed doctor, and
119
+ `claude plugin details` consume the same exact canonical skill catalog. A
120
+ packed isolated install must emit `SKILL_CATALOG_PASS` and `DOCTOR_PASS`; after
121
+ one canonical `SKILL.md` is moved aside, doctor must exit nonzero with
122
+ `DOCTOR_FAIL` and must not print `DOCTOR_PASS`.
123
+
77
124
  ## v0.3.32 Bounded-Authority Start-Work Gates
78
125
 
79
126
  Before requesting publication approval, confirm schema-3 state remains
@@ -138,9 +185,9 @@ checkout and from an isolated install of the packed tarball:
138
185
  Before requesting publication approval, confirm these artifacts from the current
139
186
  checkout:
140
187
 
141
- - `package.json` version is `0.3.32`.
142
- - `plugins/litclaude/.claude-plugin/plugin.json` version is `0.3.32`.
143
- - `plugins/litclaude/bin/litclaude-mcp.js` reports server version `0.3.32`.
188
+ - `package.json` version is `0.3.34`.
189
+ - `plugins/litclaude/.claude-plugin/plugin.json` version is `0.3.34`.
190
+ - `plugins/litclaude/bin/litclaude-mcp.js` reports server version `0.3.34`.
144
191
  - 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.
145
192
  - `lit search` and `lit query` route to `/litclaude:litresearch` without activating on slash mentions, code spans, or non-lit prompts.
146
193
  - Litresearch web lanes require public API/feed preference, validator-first checks, route traces, prompt-injection quarantine, and honest auth/paywall/private-data stop reasons.
@@ -15,13 +15,20 @@ import { homedir } from "node:os";
15
15
  import { dirname, join, resolve } from "node:path";
16
16
  import { createInterface } from "node:readline/promises";
17
17
  import { fileURLToPath } from "node:url";
18
+ import {
19
+ canonicalSkillFiles,
20
+ canonicalSkillIds,
21
+ canonicalSkillResourceFiles,
22
+ } from "../plugins/litclaude/lib/canonical-skill-catalog.mjs";
18
23
  import { HUD_ACCENT_THEMES, normalizeHudAccent, themeForAccent } from "../plugins/litclaude/lib/hud-accent-palette.mjs";
19
24
  import { readPublicSource } from "../plugins/litclaude/lib/public-source-reader/reader.mjs";
20
25
  import { verifyBundledSkillsIntegrity } from "../plugins/litclaude/lib/bundled-skills-integrity.mjs";
26
+ import { verifyCanonicalSkillResources } from "../plugins/litclaude/lib/skill-resource-integrity.mjs";
21
27
  import { runStartWorkContinuationCli } from "../plugins/litclaude/lib/start-work-continuation.mjs";
22
28
  import { runStartWorkCli } from "../plugins/litclaude/lib/start-work-cli.mjs";
23
29
  import { runLitgoalCli } from "../plugins/litclaude/lib/litgoal/cli.mjs";
24
30
  import { runWorkflowCheckCli } from "../plugins/litclaude/lib/workflow-check.mjs";
31
+ import { runUpdateNotifier } from "./update-notifier.mjs";
25
32
 
26
33
  const root = resolve(dirname(fileURLToPath(import.meta.url)), "..");
27
34
  const packageJson = JSON.parse(readFileSync(join(root, "package.json"), "utf8"));
@@ -67,6 +74,7 @@ const parseArgs = (argv) => {
67
74
 
68
75
  const litHome = () => resolve(process.env.LITCLAUDE_HOME ?? join(homedir(), ".litclaude"));
69
76
  const claudeHome = () => resolve(process.env.CLAUDE_CONFIG_DIR ?? process.env.CLAUDE_HOME ?? join(homedir(), ".claude"));
77
+ const updateNotifierCachePath = (home = litHome()) => join(home, "update-notifier", "latest.json");
70
78
  const versionRoot = (home = litHome()) => join(home, "litclaude-ai", version);
71
79
  const currentRoot = (home = litHome()) => join(home, "current");
72
80
  const pluginPathForRoot = (installRoot) => join(installRoot, "plugins", "litclaude");
@@ -96,8 +104,9 @@ const parsePermissionMode = (value) => {
96
104
  return value;
97
105
  };
98
106
 
99
- const parseInstallOptions = (rest) => {
100
- let permissionMode = parsePermissionMode(process.env.LITCLAUDE_PERMISSION_MODE || "safe");
107
+ const parseInstallOptions = (rest, existingPermissionMode = "safe") => {
108
+ const preservedMode = permissionModes.has(existingPermissionMode) ? existingPermissionMode : "safe";
109
+ let permissionMode = parsePermissionMode(process.env.LITCLAUDE_PERMISSION_MODE || preservedMode);
101
110
  let permissionExplicit = Boolean(process.env.LITCLAUDE_PERMISSION_MODE);
102
111
 
103
112
  for (let index = 0; index < rest.length; index += 1) {
@@ -308,12 +317,13 @@ const shouldPromptHudAccent = () => {
308
317
  return Boolean(process.stdin.isTTY && process.stdout.isTTY && !process.env.CI);
309
318
  };
310
319
 
311
- const chooseHudAccent = async () => {
320
+ const chooseHudAccent = async (existingAccent = "cyan") => {
321
+ const preservedAccent = normalizeHudAccent(existingAccent);
312
322
  const envAccent = process.env.LITCLAUDE_HUD_ACCENT;
313
323
  if (envAccent && process.env.LITCLAUDE_HUD_ACCENT_PROMPT !== "1") {
314
324
  return normalizeHudAccent(envAccent);
315
325
  }
316
- if (!shouldPromptHudAccent()) return normalizeHudAccent(envAccent);
326
+ if (!shouldPromptHudAccent()) return envAccent ? normalizeHudAccent(envAccent) : preservedAccent;
317
327
 
318
328
  process.stdout.write("Choose LitClaude HUD brand color:\n");
319
329
  for (const [index, theme] of hudAccentThemes.entries()) {
@@ -322,10 +332,10 @@ const chooseHudAccent = async () => {
322
332
 
323
333
  const rl = createInterface({ input: process.stdin, output: process.stdout });
324
334
  try {
325
- const answer = await rl.question("Color 1-10 or name [cyan]: ");
335
+ const answer = await rl.question(`Color 1-10 or name [${preservedAccent}]: `);
326
336
  const trimmed = answer.trim().toLowerCase();
327
337
  const byIndex = hudAccentThemes[Number.parseInt(trimmed, 10) - 1]?.name;
328
- const selected = byIndex ?? normalizeHudAccent(trimmed);
338
+ const selected = byIndex ?? (trimmed ? normalizeHudAccent(trimmed) : preservedAccent);
329
339
  if (trimmed && selected === "cyan" && trimmed !== "cyan" && byIndex === undefined) {
330
340
  process.stdout.write("HUD_COLOR_WARNING: unknown color; using cyan\n");
331
341
  }
@@ -563,6 +573,8 @@ const commandExists = (command) => {
563
573
  };
564
574
 
565
575
  const escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
576
+ const exactInventoryToken = (value) =>
577
+ new RegExp(`(?<![A-Za-z0-9_-])${escapeRegex(value)}(?![A-Za-z0-9_-])`, "u");
566
578
 
567
579
  const assertCurrentPluginDetails = (detailsOutput) => {
568
580
  const missing = [];
@@ -586,11 +598,11 @@ const assertCurrentPluginDetails = (detailsOutput) => {
586
598
  missing.push("expected nonzero Agents inventory with prometheus-planner");
587
599
  }
588
600
 
589
- if (!/\blit-loop\b/u.test(skillsInventory) || !/\blit-plan\b/u.test(skillsInventory)) {
590
- missing.push("expected lit-loop and lit-plan skills");
591
- }
592
- if (!/\blit-handoff\b/u.test(skillsInventory) || !/\blit-scientific-visualization\b/u.test(skillsInventory)) {
593
- missing.push("expected lit-handoff and lit-scientific-visualization skills");
601
+ const missingSkills = canonicalSkillIds.filter(
602
+ (skillId) => !exactInventoryToken(skillId).test(skillsInventory),
603
+ );
604
+ if (missingSkills.length > 0) {
605
+ missing.push(`expected canonical skills: ${missingSkills.join(", ")}`);
594
606
  }
595
607
 
596
608
  if (missing.length > 0) {
@@ -642,13 +654,11 @@ const verifyInstalledPayload = ({ home, litClaudeHome, targetPlugin }) => {
642
654
  "bin/litclaude-hook.js",
643
655
  "lib/start-work-lifecycle.mjs",
644
656
  "lib/start-work-cli.mjs",
645
- "skills/start-work/SKILL.md",
657
+ ...canonicalSkillResourceFiles,
646
658
  "commands/start-work.md",
647
659
  "bin/litclaude-scientific-visualization-doctor.js",
648
- "skills/lit-handoff/SKILL.md",
649
660
  "commands/lit-handoff.md",
650
661
  "vendor/022_handoff/SKILL.md",
651
- "skills/lit-scientific-visualization/SKILL.md",
652
662
  "commands/lit-scientific-visualization.md",
653
663
  "vendor/045_scientific-visualization/SKILL.md",
654
664
  "vendor/045_scientific-visualization/scripts/style_presets.py",
@@ -661,6 +671,10 @@ const verifyInstalledPayload = ({ home, litClaudeHome, targetPlugin }) => {
661
671
  if (integrity.status !== "PASS") {
662
672
  throw new Error(`installed bundled-skill integrity verification failed: ${JSON.stringify(integrity)}`);
663
673
  }
674
+ const resourceIntegrity = verifyCanonicalSkillResources(targetPlugin);
675
+ if (resourceIntegrity.status !== "PASS") {
676
+ throw new Error(`SKILL_RESOURCE_INTEGRITY_FAIL ${JSON.stringify(resourceIntegrity.failures)}`);
677
+ }
664
678
  if (!readInstalledPlugins(home).plugins[pluginKey]?.length) {
665
679
  throw new Error(`Claude registry is missing ${pluginKey}`);
666
680
  }
@@ -670,9 +684,14 @@ const verifyInstalledPayload = ({ home, litClaudeHome, targetPlugin }) => {
670
684
  };
671
685
 
672
686
  const install = async ({ dryRun, rest }) => {
673
- const { permissionMode, permissionExplicit } = parseInstallOptions(rest);
674
687
  const home = claudeHome();
675
688
  const litClaudeHome = litHome();
689
+ const existingLitClaude = readClaudeSettings(home)[litClaudeSettingsKey] ?? {};
690
+ const { permissionMode, permissionExplicit } = parseInstallOptions(rest, existingLitClaude.permissionMode);
691
+ const existingHudAccent = normalizeHudAccent(existingLitClaude.hudAccent);
692
+ const requestedHudAccent = process.env.LITCLAUDE_HUD_ACCENT
693
+ ? normalizeHudAccent(process.env.LITCLAUDE_HUD_ACCENT)
694
+ : existingHudAccent;
676
695
  const targetPlugin = claudePluginRoot(home);
677
696
  const sourcePlugin = sourcePluginPath();
678
697
  const targetMarketplace = marketplaceRoot(litClaudeHome);
@@ -683,8 +702,11 @@ const install = async ({ dryRun, rest }) => {
683
702
  process.stdout.write(`Would copy: ${sourcePlugin} -> ${targetPlugin}\n`);
684
703
  process.stdout.write(`Would create local marketplace: ${targetMarketplace}\n`);
685
704
  process.stdout.write(`Would register Claude plugin: ${pluginKey}\n`);
686
- process.stdout.write(`Would set Claude statusLine HUD: ${hudCommandForPlugin(targetPlugin)}\n`);
687
- process.stdout.write(`Would record permission preference: ${permissionMode}${permissionExplicit ? " (explicit)" : " (default)"}\n`);
705
+ process.stdout.write(`Would set Claude statusLine HUD: ${hudCommandForPlugin(targetPlugin, requestedHudAccent)}\n`);
706
+ const permissionSource = permissionExplicit
707
+ ? "explicit"
708
+ : permissionModes.has(existingLitClaude.permissionMode) ? "preserved" : "default";
709
+ process.stdout.write(`Would record permission preference: ${permissionMode} (${permissionSource})\n`);
688
710
  process.stdout.write(`Permission profile: ${permissionProfile(permissionMode).description}\n`);
689
711
  process.stdout.write("Launch with: claude\n");
690
712
  return;
@@ -694,7 +716,7 @@ const install = async ({ dryRun, rest }) => {
694
716
  fail(`Packaged LitClaude plugin payload is missing: ${sourcePlugin}`);
695
717
  }
696
718
 
697
- const hudAccent = await chooseHudAccent();
719
+ const hudAccent = await chooseHudAccent(existingHudAccent);
698
720
  progress.prepare({ claudeTarget: home, litTarget: litClaudeHome });
699
721
  await progress.run(
700
722
  {
@@ -801,17 +823,12 @@ const doctor = ({ dryRun }) => {
801
823
  "bin/litclaude-mcp.js",
802
824
  "lib/start-work-lifecycle.mjs",
803
825
  "lib/start-work-cli.mjs",
804
- "skills/start-work/SKILL.md",
805
826
  "commands/start-work.md",
806
- "skills/lit-loop/SKILL.md",
807
- "skills/lit-plan/SKILL.md",
808
- "skills/lit-handoff/SKILL.md",
809
827
  "commands/lit-handoff.md",
810
828
  "vendor/022_handoff/SKILL.md",
811
829
  "vendor/022_handoff/evals/evals.json",
812
830
  "vendor/022_handoff/examples/HANDOFF-example-generic-auth-refactor.md",
813
831
  "vendor/022_handoff/templates/HANDOFF.md",
814
- "skills/lit-scientific-visualization/SKILL.md",
815
832
  "commands/lit-scientific-visualization.md",
816
833
  "bin/litclaude-scientific-visualization-doctor.js",
817
834
  "vendor/045_scientific-visualization/SKILL.md",
@@ -828,6 +845,18 @@ const doctor = ({ dryRun }) => {
828
845
  const path = join(pluginPath, file);
829
846
  if (!existsSync(path)) fail(`LitClaude install is missing ${file}. Run \`litclaude install\` again.`);
830
847
  }
848
+ for (const file of canonicalSkillFiles) {
849
+ const path = join(pluginPath, file);
850
+ if (!existsSync(path)) {
851
+ fail(`DOCTOR_FAIL: LitClaude install is missing ${file}. Run \`litclaude install\` again.`);
852
+ }
853
+ }
854
+ process.stdout.write("SKILL_CATALOG_PASS\n");
855
+ const resourceIntegrity = verifyCanonicalSkillResources(pluginPath);
856
+ if (resourceIntegrity.status !== "PASS") {
857
+ fail(`SKILL_RESOURCE_INTEGRITY_FAIL ${JSON.stringify(resourceIntegrity.failures)}`);
858
+ }
859
+ process.stdout.write(`SKILL_RESOURCE_INTEGRITY_PASS: ${resourceIntegrity.checked} resources\n`);
831
860
 
832
861
  printLspDiagnostics(pluginPath, registry);
833
862
 
@@ -931,13 +960,15 @@ const runClaude = ({ dryRun, rest }) => {
931
960
  const uninstall = ({ dryRun }) => {
932
961
  const home = litHome();
933
962
  const pluginCacheRoot = join(claudeHome(), "plugins", "cache", "litclaude-ai");
963
+ const updateNotifierRoot = dirname(updateNotifierCachePath(home));
934
964
  if (dryRun) {
935
- process.stdout.write(`DRY_RUN: remove ${join(home, "litclaude-ai")}, ${currentRoot(home)}, ${marketplaceRoot(home)}, ${pluginCacheRoot}, ${pluginKey}, and its marketplace/settings entries\n`);
965
+ process.stdout.write(`DRY_RUN: remove ${join(home, "litclaude-ai")}, ${currentRoot(home)}, ${marketplaceRoot(home)}, ${updateNotifierRoot}, ${pluginCacheRoot}, ${pluginKey}, and its marketplace/settings entries\n`);
936
966
  return;
937
967
  }
938
968
  rmSync(currentRoot(home), { recursive: true, force: true });
939
969
  rmSync(join(home, "litclaude-ai"), { recursive: true, force: true });
940
970
  rmSync(marketplaceRoot(home), { recursive: true, force: true });
971
+ rmSync(updateNotifierRoot, { recursive: true, force: true });
941
972
  unregisterClaudePlugin();
942
973
  unregisterMarketplace();
943
974
  uninstallHudStatusLine();
@@ -993,6 +1024,14 @@ const main = async () => {
993
1024
  printUsage();
994
1025
  fail(`Unknown command: ${command}`, 64);
995
1026
  }
1027
+
1028
+ if (command === "install" || command === "update" || command === "doctor") {
1029
+ runUpdateNotifier({
1030
+ ...parsed,
1031
+ currentVersion: version,
1032
+ cachePath: updateNotifierCachePath(),
1033
+ });
1034
+ }
996
1035
  };
997
1036
 
998
1037
  main().catch((error) => fail(error.message));
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { refreshUpdateCache } from "./update-notifier.mjs";
4
+
5
+ const cachePath = process.argv[2];
6
+ const generation = process.argv[3];
7
+ if (cachePath && generation) await refreshUpdateCache(cachePath, { generation }).catch(() => {});