@litfamily/litclaude 1.0.7 → 1.0.9
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 +15 -2
- package/README.md +186 -139
- package/README_ko-KR.md +182 -119
- package/docs/agents.md +30 -8
- package/docs/assets/cover-motion-still.webp +0 -0
- package/docs/assets/cover-motion.webp +0 -0
- package/docs/assets/litclaude-continuity-1600.webp +0 -0
- package/docs/assets/litclaude-ignition-1600.webp +0 -0
- package/docs/assets/litfamily-machines.png +0 -0
- package/docs/assets/readme/JetBrainsMono-OFL.txt +93 -0
- package/docs/assets/readme/Lucide-LICENSE.txt +43 -0
- package/docs/assets/readme/ascii-readme.svg +5 -0
- package/docs/assets/readme/badge-version.svg +1 -1
- package/docs/assets/readme/ignition-film.mp4 +0 -0
- package/docs/assets/readme/ignition-poster.png +0 -0
- package/docs/assets/readme/ignition-readme.gif +0 -0
- package/docs/assets/readme/lucide-book-open.svg +14 -0
- package/docs/assets/readme/lucide-play.svg +13 -0
- package/docs/assets/readme/lucide-shield-check.svg +14 -0
- package/docs/hooks.md +26 -10
- package/package.json +14 -1
- package/plugins/litclaude/.claude-plugin/plugin.json +1 -1
- package/plugins/litclaude/bin/litclaude-hook.js +55 -10
- package/plugins/litclaude/bin/litclaude-hud.js +5 -1
- package/plugins/litclaude/bin/litclaude-mcp.js +1 -1
- package/plugins/litclaude/commands/lit-handoff.md +3 -3
- package/plugins/litclaude/commands/lit-scientific-visualization.md +2 -2
- package/plugins/litclaude/lib/canonical-skill-catalog.mjs +1 -0
- package/plugins/litclaude/lib/canonical-skill-resources.mjs +26 -3
- package/plugins/litclaude/lib/hud-accent-palette.mjs +2 -2
- package/plugins/litclaude/lib/hud-ignition.mjs +74 -0
- package/plugins/litclaude/skills/frontend-ui-ux/SKILL.md +21 -12
- package/plugins/litclaude/skills/frontend-ui-ux/references/complete-contract.md +8 -9
- package/plugins/litclaude/skills/frontend-ui-ux/references/default-editorial-pixel.json +21 -0
- package/plugins/litclaude/skills/frontend-ui-ux/references/production-interview.md +17 -0
- package/plugins/litclaude/skills/lit-handoff/SKILL.md +2 -2
- package/plugins/litclaude/skills/lit-scientific-visualization/SKILL.md +3 -3
- package/plugins/litclaude/skills/litwork/SKILL.md +2 -2
- package/plugins/litclaude/skills/readme-studio/SKILL.md +86 -0
- package/plugins/litclaude/skills/readme-studio/references/decoration-and-navigation.md +55 -0
- package/plugins/litclaude/skills/readme-studio/references/facts-and-assembly.md +19 -0
- package/plugins/litclaude/skills/readme-studio/references/production-interview.md +11 -0
- package/plugins/litclaude/skills/readme-studio/references/render-and-deliver.md +44 -0
- package/plugins/litclaude/skills/readme-studio/references/type-and-background.md +23 -0
- package/plugins/litclaude/skills/readme-studio/scripts/validate-readme-facts.mjs +28 -0
- package/plugins/litclaude/skills/readme-studio/templates/cover-source.json +21 -0
- package/plugins/litclaude/skills/readme-studio/templates/hyperframes-cover/index.html +30 -0
- package/plugins/litclaude/skills/readme-studio/templates/hyperframes-cover/index.motion.json +1 -0
- package/plugins/litclaude/skills/readme-studio/templates/hyperframes-cover/package-lock.json +1969 -0
- package/plugins/litclaude/skills/readme-studio/templates/hyperframes-cover/package.json +8 -0
- package/plugins/litclaude/skills/readme-studio/templates/readme-cover-section.md +75 -0
- package/plugins/litclaude/skills/readme-studio/templates/readme-facts.json +4 -0
- package/plugins/litclaude/skills/readme-studio/templates/remotion-cover/package-lock.json +3783 -0
- package/plugins/litclaude/skills/readme-studio/templates/remotion-cover/package.json +7 -0
- package/plugins/litclaude/skills/readme-studio/templates/remotion-cover/src/index.tsx +36 -0
- package/plugins/litclaude/skills/readme-studio/templates/typography/package-lock.json +133 -0
- package/plugins/litclaude/skills/readme-studio/templates/typography/package.json +6 -0
- package/plugins/litclaude/skills/readme-studio/templates/typography/safe-files.mjs +57 -0
- package/plugins/litclaude/skills/readme-studio/templates/typography/shape-text-to-svg.mjs +47 -0
- package/scripts/qa-real-surface-lib.mjs +3 -2
- package/scripts/strip-ansi.mjs +1 -0
- package/tools/check-model-routing.mjs +6 -6
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Local motion production
|
|
2
|
+
|
|
3
|
+
Choose an engine before rendering. Inspect the pinned package's CLI help and license, Chrome and encoding prerequisites. Do not silently install globally or switch engines after a failure. Keep dependencies and outputs in the authorized project. If a sandbox cannot launch Chrome, preserve source and report the exact boundary; an authorized outer process may render that same source with the boundary recorded, without weakening the sandbox.
|
|
4
|
+
|
|
5
|
+
## Remotion
|
|
6
|
+
|
|
7
|
+
`templates/remotion-cover/` pins Remotion and its CLI to 4.0.526 with React/React DOM 19.3.0. Prefer it when compatible with the user's license situation. Its license has eligibility conditions; it is not the plugin's MIT license. Check https://www.remotion.dev/license for the actual use case before choosing it. If eligibility is unknown, keep this choice pending and select the Apache-2.0 alternative only as an explicit initial decision.
|
|
8
|
+
|
|
9
|
+
Copy the full template to a new project directory, then `npm ci`. Place inspected `background.png`, title and subtitle SVG ink variants and label variants under public/. Compose from editable cover-source.json records. Run the project-local commands, each with a fresh output:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm run compositions
|
|
13
|
+
npm run render -- src/index.tsx CoverWideLight out/wide-light-v01.mp4
|
|
14
|
+
npm run still -- src/index.tsx CoverWideLight out/wide-light-v01.png --frame 90
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Other IDs are CoverWideDark, CoverMobileLight and CoverMobileDark. All are 60fps, 300 frames / 5 seconds; mobile is 800x1000, wide 1600x800. Use frame-driven motion only. The template exposes blur, grain and expressive treatment props; adjust them without blurring text. Static grain and a deterministic eased cycle prevent random flicker. Read https://www.remotion.dev/docs/animating-properties for the frame-driven requirement.
|
|
18
|
+
|
|
19
|
+
## HyperFrames
|
|
20
|
+
|
|
21
|
+
`templates/hyperframes-cover/` pins the published `hyperframes@0.8.51` package, Apache-2.0, Node >=22. Copy it into a fresh workspace, `npm ci`, then inspect `./node_modules/.bin/hyperframes render --help`. Set HYPERFRAMES_NO_TELEMETRY=1 for task-local rendering. Keep the root composition timing and data-no-timeline marker: this template deliberately uses finite CSS animations, not a missing GSAP timeline. Retain index.motion.json and test that timeline before rendering.
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
./node_modules/.bin/hyperframes check . --samples 60 --no-contrast --json
|
|
25
|
+
./node_modules/.bin/hyperframes render . -c index.html --fps 60 --workers 1 --output wide-light-v01.mp4
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The positional argument is the project directory; `-c` names the composition. Use one worker for this recipe; inspect the bottom edge in decoded frames to catch clipping. Use a separate project directory per light/dark and wide/mobile variant, each with exactly one root index.html. Multiple root compositions fail the native lint check. Configure the theme ink paths and dimensions before rendering. Keep each composition's own dimensions, duration and matching sidecar. The HTML's data attributes are editable source, not proof that a movie was produced. Primary package/source: https://registry.npmjs.org/hyperframes/0.8.51 and https://github.com/heygen-com/hyperframes . Do not substitute an unpublished CLI name or unpinned latest.
|
|
29
|
+
|
|
30
|
+
## Delivery and inspection
|
|
31
|
+
|
|
32
|
+
Keep recognizable type on frame zero, a brief eased typographic movement, a readable hold and a return with matching endpoints. Inspect frames 0/150/299 as well as playback; check full-height output, dark/light ink pairing, original pixel motif, contrast, crops and seam. Use ffprobe to verify master dimensions, fps and duration. A missing movie or failed encoder remains MOTION_RENDER_BLOCKED even when the tool printed a success-like message.
|
|
33
|
+
|
|
34
|
+
Create posters and <=2.5 MiB inline GIFs. A useful starting encoder profile is 6fps, wide 560x280 or mobile 384x480, 64 colors, 30 frames for five seconds. Lower preview fps is distinct from the 60fps master. Example with local FFmpeg, keeping existing outputs safe:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
ffmpeg -n -i out/wide-light-v01.mp4 -filter_complex '[0:v]fps=6,scale=560:280:flags=lanczos,split[a][b];[a]palettegen=max_colors=64[p];[b][p]paletteuse=dither=bayer' out/wide-light-v01.gif
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
If over budget, optimize and inspect readability again. If still too large, record INLINE_PREVIEW_SIZE_BLOCKED and obtain an explicit delivery choice. Never quietly omit a required animation and claim the full set. A static fallback remains mandatory even when playback works.
|
|
41
|
+
|
|
42
|
+
Static posters are still frames from the layered composition: keep the sharp foreground plane, depth-staged background blur and directional rim-light band visible in each poster. The image is motionless while both depth and light effects remain present; do not remove them for reduced-motion output.
|
|
43
|
+
|
|
44
|
+
Record actual tool version/license choice, commands, exit statuses, dimensions, frame count, fps, byte sizes, source paths and inspection judgments. Test local picture selection at 320/390/1440px and both color schemes, including reduced motion. This is local evidence only; GitHub, npm/CDN and their actual accessibility settings remain POST_PUBLICATION_UNVERIFIED. No remote publication is part of this skill.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Image input, typography and safe local assets
|
|
2
|
+
|
|
3
|
+
Inspect native tool availability in Claude Code, not the capabilities of a different assistant running the task. Only a real supported generator invocation plus inspected output establishes generated imagery. Record its tool identity, prompt, returned asset, hash and copied project path. If unavailable, state IMAGE_GENERATION_UNAVAILABLE and retain that result before continuing with an explicitly supplied background. Facts and README text can proceed without the missing image; full cover delivery cannot. Do not author a procedural substitute, even with a provenance disclaimer. Await an explicit supplied image before background composition or rendering. Keep the original input and a manifest with created paths and stages so an interrupted composition never repeats generation blindly.
|
|
4
|
+
|
|
5
|
+
Backgrounds should contain no words, logos or baked-in captions. Examine the wide and mobile crop before composition. Treat blur, grain, glow and depth as deterministic composition layers, not evidence of generation. Keep foreground pixel art original and sharp. Untrusted SVG images may carry scripts, foreignObject, external references or event handlers; reject them or safely rasterize through a supported isolated tool. Do not embed arbitrary SVG markup into a document.
|
|
6
|
+
|
|
7
|
+
Resolve local Pretendard for Korean/display/prose and Meslo LGS NF for technical text. Inspect the actual family/style/version and applicable license notice; record hashes and upstream provenance. A similarly named file is insufficient. Font files must be regular, bounded, non-symlink inputs; missing glyphs, wrong family and uncertain license are blockers. Never install system fonts or add font bytes to the plugin package. Keep a redistribution license next to any authorized project-local font copy.
|
|
8
|
+
|
|
9
|
+
Copy `templates/typography/` from the exact selected skill directory into a fresh output workspace. Its lockfile pins fontkit 2.0.4; run `npm ci --ignore-scripts --no-audit --no-fund` there. The helper reads a bounded descriptor, shapes glyph runs with advances and offsets, and computes a padded union of actual transformed glyph bounds. Whitespace may have an empty outline but still carries an advance. Missing-glyph id zero is rejected. Output creation is exclusive within an explicit existing root, with non-symlink parent checks.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
node "$README_STUDIO_PROJECT_ROOT/.readme-studio/typography/shape-text-to-svg.mjs" \
|
|
13
|
+
--font "/explicit/task-font/Pretendard-Regular.otf" \
|
|
14
|
+
--family "Pretendard" --text "연구 노트 / Research notes" \
|
|
15
|
+
--output-root "$README_STUDIO_PROJECT_ROOT" --output "assets/title-dark.svg" \
|
|
16
|
+
--font-size 84 --fill '#18272b'
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Create each revision under a fresh filename. For dark fields repeat with light ink and a different output. Ink names describe the glyph fill: `title-dark.svg` belongs on a light field; `title-light.svg` on a dark field. Require at least 4.5:1 for the actual text/field pair, including the darkest/lightest moving backgrounds. Use a solid or near-opaque text field if art makes contrast uncertain.
|
|
20
|
+
|
|
21
|
+
Retain the helper's font/hash/geometry result and editable text in cover-source.json. Verify the SVG has path geometry and no text element or external font reference; compare the displayed wording character by character. An SVG title is semantic metadata, not outlined geometry. Keep the same exact title in Markdown for accessibility. Raster background plus SVG text is honestly a hybrid cover.
|
|
22
|
+
|
|
23
|
+
Primary API reference: https://github.com/foliojs/fontkit (layout glyphs/positions, path and bounding box). Font choice and license remain the user's explicit project inputs.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { relative, resolve } from "node:path";
|
|
3
|
+
import { argumentsMap, boundedRead, inside } from "../templates/typography/safe-files.mjs";
|
|
4
|
+
|
|
5
|
+
const report = { valid: false, validation_scope: "structure-only", factual_accuracy: "not-checked", source_contents_compared: false, badge_truth_checked: false, issues: [] };
|
|
6
|
+
try {
|
|
7
|
+
const args = argumentsMap(process.argv.slice(2), ["--project-root", "--facts"]);
|
|
8
|
+
if (!args.get("--project-root") || !args.get("--facts")) throw new Error("PROJECT_ROOT_AND_FACTS_REQUIRED");
|
|
9
|
+
const root = resolve(args.get("--project-root"));
|
|
10
|
+
const factsPath = inside(root, relative(root, resolve(args.get("--facts"))).replaceAll("\\", "/"));
|
|
11
|
+
const data = JSON.parse(boundedRead(factsPath, 1024 * 1024).toString("utf8"));
|
|
12
|
+
if (!data || !Array.isArray(data.claims) || !data.claims.length || !Array.isArray(data.badges)) throw new Error("CLAIMS_AND_BADGES_REQUIRED");
|
|
13
|
+
const ids = new Set();
|
|
14
|
+
for (const claim of data.claims) {
|
|
15
|
+
if (!claim || typeof claim.id !== "string" || !claim.id.trim() || ids.has(claim.id) || typeof claim.value !== "string" || !claim.value.trim()) throw new Error("INVALID_OR_DUPLICATE_CLAIM");
|
|
16
|
+
ids.add(claim.id);
|
|
17
|
+
boundedRead(inside(root, claim.source), 8 * 1024 * 1024);
|
|
18
|
+
}
|
|
19
|
+
for (const badge of data.badges) {
|
|
20
|
+
if (!badge || typeof badge.label !== "string" || !badge.label.trim() || typeof badge.url !== "string" || /[\s\x00-\x1f\x7f]/u.test(badge.url)) throw new Error("INVALID_BADGE");
|
|
21
|
+
const url = new URL(badge.url);
|
|
22
|
+
if (!/^https?:\/\//u.test(badge.url) || !["http:", "https:"].includes(url.protocol) || url.username || url.password) throw new Error("UNSAFE_BADGE_URL");
|
|
23
|
+
boundedRead(inside(root, badge.source), 8 * 1024 * 1024);
|
|
24
|
+
}
|
|
25
|
+
report.valid = true;
|
|
26
|
+
} catch (error) { report.issues.push(error.message); }
|
|
27
|
+
console.log(JSON.stringify(report));
|
|
28
|
+
process.exitCode = report.valid ? 0 : 1;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": "litclaude.readme-cover/v1",
|
|
3
|
+
"title": "",
|
|
4
|
+
"subtitle": "",
|
|
5
|
+
"label": "",
|
|
6
|
+
"background": {"path": "", "origin": "unresolved", "sha256": "", "inspected": false},
|
|
7
|
+
"fonts": [],
|
|
8
|
+
"renderer": {"engine": "unselected", "version": "", "license_checked": false},
|
|
9
|
+
"effects": {
|
|
10
|
+
"blur_px": 2,
|
|
11
|
+
"focal_depth": {"foreground": "sharp", "background": "staged-blur"},
|
|
12
|
+
"second_light": "directional-rim",
|
|
13
|
+
"grain_seed": 19,
|
|
14
|
+
"grain_opacity": 0.06,
|
|
15
|
+
"glow": 0.2,
|
|
16
|
+
"variant": "restrained"
|
|
17
|
+
},
|
|
18
|
+
"assets": [],
|
|
19
|
+
"stages": {"facts": "pending", "background": "pending", "type": "pending", "render": "pending", "inspection": "pending"},
|
|
20
|
+
"hosted_render": "POST_PUBLICATION_UNVERIFIED"
|
|
21
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en"><head><meta charset="utf-8"><title>README cover source</title>
|
|
3
|
+
<style>
|
|
4
|
+
*{box-sizing:border-box}html,body{margin:0;width:100%;height:100%;overflow:hidden}
|
|
5
|
+
#cover{--paper:#f5f3eb;--ink:#18272b;--blur:2px;--grain:.06;position:relative;width:1600px;height:800px;background:var(--paper);overflow:hidden}
|
|
6
|
+
#cover[data-theme=dark]{--paper:#18272b;--ink:#f5f3eb}
|
|
7
|
+
.background{position:absolute;width:100%;height:100%;object-fit:cover}
|
|
8
|
+
.depth-far{inset:0;filter:blur(calc(var(--blur) + 8px));transform:scale(1.08);animation:depth 5s ease-in-out both}
|
|
9
|
+
.depth-mid{inset:0;clip-path:inset(8% 8% 18% 26% round 40px);filter:blur(calc(var(--blur) + 1px));opacity:.56;transform:scale(1.04);animation:depth 5s ease-in-out both}
|
|
10
|
+
.light{position:absolute;inset:0;background:radial-gradient(ellipse at 85% 12%,transparent,var(--paper));opacity:.75}
|
|
11
|
+
.glow{position:absolute;right:-100px;top:-200px;width:800px;height:600px;border-radius:50%;background:#b7d8c733;filter:blur(80px);animation:float 5s ease-in-out both}
|
|
12
|
+
.grain{position:absolute;inset:0;width:100%;height:100%;opacity:var(--grain)}
|
|
13
|
+
.rim-light{position:absolute;z-index:4;left:1060px;top:48px;width:460px;height:200px;border-radius:50%;background:radial-gradient(ellipse at 54% 42%,rgba(255,242,190,.6) 0%,rgba(255,242,190,.28) 38%,rgba(255,242,190,0) 76%);filter:blur(14px);opacity:.9;transform:rotate(-12deg);pointer-events:none}
|
|
14
|
+
.type,.foreground-plane{z-index:5}
|
|
15
|
+
.type{position:absolute;left:80px;top:145px;width:940px;padding:42px;background:var(--paper);border:1px solid var(--ink);animation:entry 5s ease-in-out both}
|
|
16
|
+
.type img{display:block;width:100%}.type .label{width:58%;max-height:40px;object-fit:contain;object-position:left}.type .title{margin-top:36px}.type .subtitle{width:90%}.rule{width:64px;height:5px;background:#c64d2e;margin:28px 0}
|
|
17
|
+
.pixel{position:absolute;z-index:6;width:400px;right:100px;bottom:125px;animation:float 5s ease-in-out both}
|
|
18
|
+
.line{position:absolute;bottom:40px;left:80px;right:80px;border-top:1px solid var(--ink)}
|
|
19
|
+
#cover[data-layout=mobile]{width:800px;height:1000px}#cover[data-layout=mobile] .type{left:54px;top:100px;width:692px;padding:30px}#cover[data-layout=mobile] .pixel{width:300px;right:80px;bottom:65px}#cover[data-layout=mobile] .rim-light{left:110px;top:20px;width:580px;height:56px;filter:blur(10px);opacity:.9;transform:none}
|
|
20
|
+
@keyframes depth{0%,100%{transform:scale(1.04)}50%{transform:scale(1.055)}}
|
|
21
|
+
@keyframes entry{0%,100%{transform:translateY(16px)}8%,88%{transform:translateY(0)}}
|
|
22
|
+
@keyframes float{0%,100%{transform:translateY(0)}50%{transform:translateY(-14px)}}
|
|
23
|
+
@media(prefers-reduced-motion:reduce){.depth-far,.depth-mid,.glow,.type,.pixel{animation:none;transform:none}}
|
|
24
|
+
</style></head><body>
|
|
25
|
+
<main id="cover" data-composition-id="readme-cover" data-start="0" data-duration="5" data-width="1600" data-height="800" data-no-timeline data-theme="light" data-layout="wide">
|
|
26
|
+
<img class="background depth-far" src="assets/background.png" alt=""><img class="background depth-mid" src="assets/background.png" alt=""><div class="light"></div><div class="glow"></div>
|
|
27
|
+
<svg class="grain"><filter id="noise"><feTurbulence type="fractalNoise" baseFrequency=".65" numOctaves="3" seed="19" stitchTiles="stitch"/></filter><rect width="100%" height="100%" filter="url(#noise)"/></svg>
|
|
28
|
+
<div class="rim-light" data-light-zone="open-background" aria-hidden="true"></div><section class="type foreground-plane"><img class="label" src="assets/label-dark.svg" alt="Technical label"><img class="title" src="assets/title-dark.svg" alt="Project title"><div class="rule"></div><img class="subtitle" src="assets/subtitle-dark.svg" alt="Project purpose"></section>
|
|
29
|
+
<svg class="pixel" viewBox="0 0 20 20" shape-rendering="crispEdges" aria-label="Original pixel notebook motif"><path fill="var(--paper)" d="M3 1h12v2h2v15H3z"/><path fill="var(--ink)" d="M3 1h12v2H5v13h10V3h2v15H3zM7 5h6v1H7zM7 8h6v1H7zM7 11h4v1H7z"/><path fill="#c64d2e" d="M1 4h4v2H1zM1 9h4v2H1zM1 14h4v2H1zM13 13h5v2h-5z"/></svg><div class="line"></div>
|
|
30
|
+
</main></body></html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"duration":5,"assertions":[{"kind":"keepsMoving","withinSelector":"#cover","maxStaticSec":1.2}]}
|