@litfamily/litopencode 1.0.4 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README-Ko-KR.md +150 -115
- package/README.md +147 -116
- package/dist/activation-workflow-prompts.js +1 -1
- package/dist/agents/registry.js +30 -26
- package/dist/cli/args.js +3 -3
- package/dist/cli/host-limits.d.ts +1 -1
- package/dist/cli/host-limits.js +3 -2
- package/dist/cli/install-config.js +2 -2
- package/dist/cli/install-report.js +18 -1
- package/dist/cli/managed-skill-assets.d.ts +1 -1
- package/dist/cli/managed-skill-assets.js +3 -1
- package/dist/cli/model-catalog.d.ts +56 -0
- package/dist/cli/model-catalog.js +78 -17
- package/dist/cli/model-policy.js +7 -6
- package/dist/cli/native-skill-integrity.d.ts +16 -0
- package/dist/cli/native-skill-integrity.js +80 -0
- package/dist/cli/native-skills.d.ts +9 -1
- package/dist/cli/native-skills.js +19 -3
- package/dist/cli/types.d.ts +6 -1
- package/dist/cli.js +8 -7
- package/dist/config-parser.js +3 -2
- package/dist/config.d.ts +1 -1
- package/dist/config.js +13 -12
- package/dist/features.d.ts +17 -1
- package/dist/features.js +10 -0
- package/dist/model-route-policy.d.ts +1 -1
- package/dist/model-route-policy.js +24 -7
- package/dist/skills.d.ts +8 -1
- package/dist/skills.js +8 -0
- package/dist/uiux-visual-catalog.js +5 -5
- package/docs/assets/cover-motion-still.webp +0 -0
- package/docs/assets/cover-motion.webp +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-readme.gif +0 -0
- package/docs/assets/readme/litfamily-machines.png +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/assets/readme/poster.png +0 -0
- package/docs/migration.md +2 -2
- package/docs/reference-Ko-KR.md +43 -4
- package/docs/reference.md +51 -10
- package/package.json +1 -1
- package/skills/frontend-ui-ux/SKILL.md +25 -31
- package/skills/frontend-ui-ux/references/complete-contract.md +12 -12
- package/skills/frontend-ui-ux/references/default-editorial-pixel.json +19 -0
- package/skills/frontend-ui-ux/references/production.md +15 -0
- package/skills/managed-skill-manifest.json +92 -1
- package/skills/readme-studio/SKILL.md +76 -0
- package/skills/readme-studio/references/decoration-patterns.md +105 -0
- package/skills/readme-studio/references/motion.md +38 -0
- package/skills/readme-studio/references/production.md +13 -0
- package/skills/readme-studio/references/typography.md +16 -0
- package/skills/readme-studio/scripts/check-facts.mjs +28 -0
- package/skills/readme-studio/templates/cover-source.json +1 -0
- package/skills/readme-studio/templates/facts.json +1 -0
- package/skills/readme-studio/templates/hyperframes/index.html +62 -0
- package/skills/readme-studio/templates/hyperframes/index.motion.json +1 -0
- package/skills/readme-studio/templates/hyperframes/package-lock.json +1966 -0
- package/skills/readme-studio/templates/hyperframes/package.json +1 -0
- package/skills/readme-studio/templates/readme-cover-section.md +53 -0
- package/skills/readme-studio/templates/remotion/package-lock.json +3783 -0
- package/skills/readme-studio/templates/remotion/package.json +1 -0
- package/skills/readme-studio/templates/remotion/src/index.tsx +32 -0
- package/skills/readme-studio/templates/typography/files.mjs +46 -0
- package/skills/readme-studio/templates/typography/outline.mjs +47 -0
- package/skills/readme-studio/templates/typography/package-lock.json +133 -0
- package/skills/readme-studio/templates/typography/package.json +1 -0
- package/tools/check-pack-payload.mjs +34 -2
- package/tools/payload-substance-parity.json +4 -3
- package/tools/version-manifests.json +4 -4
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# README decoration patterns
|
|
2
|
+
|
|
3
|
+
Use decoration to help a reader find verified information. Keep the README's purpose,
|
|
4
|
+
working instructions, and source links understandable when every image and HTML block
|
|
5
|
+
is hidden. Decorations never establish a release, security, compatibility, quality, or
|
|
6
|
+
popularity claim.
|
|
7
|
+
|
|
8
|
+
## Inspection notes
|
|
9
|
+
|
|
10
|
+
Inspected on 2026-09-21. GitHub's displayed star counts below are selection-time snapshots,
|
|
11
|
+
not durable project facts; re-check them before any later research summary. No wording,
|
|
12
|
+
logos, or image assets from these repositories are reused here.
|
|
13
|
+
|
|
14
|
+
| Repository | Stars observed | README structure observed |
|
|
15
|
+
| --- | ---: | --- |
|
|
16
|
+
| [fastapi/fastapi](https://github.com/fastapi/fastapi) | 102.5k | A centered logo and short descriptor precede a compact row of linked workflow, coverage, and package badges. Sponsor marks are grouped by tier. Optional code variants and command detail use `<details>` blocks. Emoji appear selectively in prose and examples; section headings remain descriptive. |
|
|
17
|
+
| [vercel/next.js](https://github.com/vercel/next.js) | 142.2k | The opening stays text-led and links directly to learning, documentation, community, and a maintained showcase. Major topics use a simple heading hierarchy. |
|
|
18
|
+
| [astral-sh/uv](https://github.com/astral-sh/uv) | 90.0k | A small linked badge row and one-line purpose lead into a centered light/dark `<picture>` with a caption. Feature highlights are concise and scannable. |
|
|
19
|
+
| [ollama/ollama](https://github.com/ollama/ollama) | 181.3k | A centered linked logo leads into a short purpose statement. Usage is divided by reader task, then integrations are grouped by category. |
|
|
20
|
+
| [pytorch/pytorch](https://github.com/pytorch/pytorch) | 103.1k | The logo switches for light and dark themes. A linked table of contents supports a long README, and a two-column Markdown table compares components with their roles. |
|
|
21
|
+
|
|
22
|
+
Star figures were read from each repository page on the inspection date. They change and
|
|
23
|
+
must never be copied into project copy, badges, or generated claims as if they were stable.
|
|
24
|
+
|
|
25
|
+
## Apply the patterns
|
|
26
|
+
|
|
27
|
+
### Emoji section headers and section iconography
|
|
28
|
+
|
|
29
|
+
Treat an emoji as a small scan cue, not as the section name or a status indicator. The
|
|
30
|
+
inspected examples favor ordinary, descriptive headings and use emoji sparingly in nearby
|
|
31
|
+
copy. If the project's voice benefits from an icon, pair one recognizable glyph with a
|
|
32
|
+
clear heading, use the same meaning consistently, and leave the heading useful when the
|
|
33
|
+
glyph is missing or rendered monochrome. Do not use icons to imply a check, popularity,
|
|
34
|
+
security, or release state that repository evidence does not support.
|
|
35
|
+
|
|
36
|
+
### Centered hero and badge/logo row
|
|
37
|
+
|
|
38
|
+
Choose one hero arrangement: a centered project mark, a concise purpose line, and—only
|
|
39
|
+
when they help a reader act—a compact row of linked marks. The inspected README layouts
|
|
40
|
+
show both a logo-first arrangement and a short badge row near the title. Preserve the
|
|
41
|
+
project's actual logo and license. Each badge image and its link target must resolve to
|
|
42
|
+
the current repository's real endpoint or a verified project endpoint. Bind owner,
|
|
43
|
+
repository, default branch, package name, and workflow name from current local facts;
|
|
44
|
+
remove a badge if its image or target cannot be verified. Never carry another project's
|
|
45
|
+
badge URL forward.
|
|
46
|
+
|
|
47
|
+
Keep sponsor and partner marks in their own clearly labeled group. Use marks only where
|
|
48
|
+
the relationship is documented, and do not let placement imply endorsement or ownership.
|
|
49
|
+
|
|
50
|
+
### Collapsible `<details>` sections
|
|
51
|
+
|
|
52
|
+
The inspected README uses disclosure blocks for optional alternatives and extended
|
|
53
|
+
command notes. Keep the summary specific, make the primary path visible outside the
|
|
54
|
+
collapsed block, and put complete Markdown content between the opening and closing tags.
|
|
55
|
+
Use disclosures for secondary examples, long environment tables, or optional setup—not
|
|
56
|
+
for the project's purpose, required install steps, warnings, or essential features.
|
|
57
|
+
|
|
58
|
+
### Contributors, star history, and showcase embeds
|
|
59
|
+
|
|
60
|
+
The inspected Next.js README links to its maintained showcase instead of embedding a
|
|
61
|
+
third-party showcase widget; the other inspected projects also keep their core README
|
|
62
|
+
usable without contributor or star-history widgets. Use a direct repository graph or
|
|
63
|
+
maintained project page as the default. An image embed is optional: check the image URL
|
|
64
|
+
and click target for this exact repository, add meaningful alt text, and retain a text
|
|
65
|
+
link below it. Remove stale or unreachable embeds instead of leaving a broken panel.
|
|
66
|
+
|
|
67
|
+
For contributor art, use the repository's own contributor destination and do not imply
|
|
68
|
+
that a remote image service is an authoritative contributor record. For star history,
|
|
69
|
+
label the chart as a historical visualization and check that both the chart and link
|
|
70
|
+
identify this repository. For showcase material, use maintained examples with permission
|
|
71
|
+
and current destinations; a locally tracked screenshot grid is a good fallback. None of
|
|
72
|
+
these embeds proves project activity, adoption, endorsement, or quality.
|
|
73
|
+
|
|
74
|
+
### Table-based feature grids
|
|
75
|
+
|
|
76
|
+
The inspected PyTorch README uses a simple Markdown table to compare named components and
|
|
77
|
+
their roles. Use a table when each row answers the same small set of questions, such as
|
|
78
|
+
feature, reader-visible behavior, and repository evidence. Keep cells short, link to
|
|
79
|
+
real source or documentation, and move long explanations into their own sections. Do
|
|
80
|
+
not use a table for paragraphs, mobile-critical instructions, or decorative alignment.
|
|
81
|
+
|
|
82
|
+
### Footer navigation
|
|
83
|
+
|
|
84
|
+
The inspected READMEs keep durable destinations—documentation, contribution guidance,
|
|
85
|
+
community/support, and license—easy to find near the end or near the opening. A compact
|
|
86
|
+
footer link row can repeat the few destinations readers need after a long feature section.
|
|
87
|
+
Use only anchors and files that exist in this repository, keep labels descriptive, and
|
|
88
|
+
avoid repeating a full table of contents in the footer.
|
|
89
|
+
|
|
90
|
+
### Plain-Markdown fallback
|
|
91
|
+
|
|
92
|
+
Some registry and package pages remove HTML or render only a subset of it. Keep the
|
|
93
|
+
project title, purpose, install command, feature descriptions, and navigation as ordinary
|
|
94
|
+
Markdown. Replace centered HTML with a Markdown title and short paragraph; replace a
|
|
95
|
+
disclosure with a visible subheading; replace a remote image with its text link and
|
|
96
|
+
meaningful alt text. The cover picture and badge row are enhancements. If the renderer
|
|
97
|
+
cannot show them, readers must still get the same verified facts and usable links.
|
|
98
|
+
|
|
99
|
+
## Facts and endpoint rule
|
|
100
|
+
|
|
101
|
+
The facts helper checks reference structure and safe paths only; it does not compare a
|
|
102
|
+
claim with source contents or prove a badge endpoint. Before assembly, inspect the actual
|
|
103
|
+
repository files and open every badge, logo, contributor, chart, and showcase destination
|
|
104
|
+
that will ship. Keep claim text accurate, use only verified endpoints for this repository,
|
|
105
|
+
and omit every decoration whose truth or destination remains uncertain.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Portable rendering and delivery
|
|
2
|
+
|
|
3
|
+
Choose one engine and record its version/license before rendering. Remotion 4.0.526 is preferred when its company license terms fit the project; it is not an unrestricted MIT renderer. Review https://www.remotion.dev/docs/license and https://www.remotion.dev/docs/cli/render. The alternative is published `hyperframes@0.8.51` (MIT), with its own bundled dependency notices: https://github.com/heygen-com/hyperframes. Inspect installed help for the pinned version; no `latest`, global installs or invented package names.
|
|
4
|
+
|
|
5
|
+
Copy the selected template directory from the exact native-selected SKILL.md root into the authorized project. Run `npm ci --no-audit --no-fund` there; install no engine into the product's runtime dependencies. Both lockfiles travel with the template. Chrome and the renderer's FFmpeg path must be available locally. A sandbox failure is MOTION_RENDER_BLOCKED, not permission to disable the host's sandbox. Keep source for an authorized external local render and disclose that boundary.
|
|
6
|
+
|
|
7
|
+
## Remotion
|
|
8
|
+
|
|
9
|
+
Put the inspected background at `public/background.png` and the six outlined assets at `public/{title,subtitle,label}-{dark,light}.svg`. Suffix names ink. Verify light ink is bound to Dark compositions. The component uses a solid theme field behind type, two staged Gaussian background planes (far and middle), seeded grain, the existing glow, a second static rim-light band, and an original crisp pixel sprite. The panel stays sharp above both blur planes. Props `farBlur`, `middleBlur`, `grain`, `glow`, and `depth` control restraint; use a props JSON file, not interpolated user text. All motion is frame-derived; no CSS animations or random-per-frame noise. Reduced-motion posters are still renders of this composition: preserve both blur planes and the rim-light band in the static image.
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
./node_modules/.bin/remotion compositions src/index.tsx
|
|
13
|
+
./node_modules/.bin/remotion render src/index.tsx WideDark out/wide-dark-v1.mp4 --codec=h264 --concurrency=1 --overwrite=false
|
|
14
|
+
./node_modules/.bin/remotion still src/index.tsx WideDark out/poster-wide-dark-v1.png --frame=150 --overwrite=false
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Repeat for WideLight, MobileDark and MobileLight. Metadata specifies 60fps, 300 frames, 5 seconds. At frame zero type is already legible; a short eased translation settles into a readable hold and returns for the seam. Verify actual output, not just this metadata. Existing output names must never be reused.
|
|
18
|
+
|
|
19
|
+
## HyperFrames
|
|
20
|
+
|
|
21
|
+
The HTML recipe is a wide dark starting composition; copy it into separate local light/mobile variants and change field, ink asset bindings, dimensions and layout together. Use `background.png` and the light-ink SVGs beside index.html. It stages far and middle blur planes below a sharp panel and a separate rim-light band; reduced-motion mode disables movement while keeping those effects visible. Keep `data-composition-id`, dimensions, five-second duration and `data-no-timeline`: this template uses finite CSS keyframes, not a missing GSAP timeline. The motion sidecar probes the cover container (including descendants), not a leaf. Render with one worker; multiple workers have produced clipped output for this recipe.
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
./node_modules/.bin/hyperframes --version
|
|
25
|
+
./node_modules/.bin/hyperframes render --help
|
|
26
|
+
./node_modules/.bin/hyperframes check . --samples 60 --no-contrast --json
|
|
27
|
+
./node_modules/.bin/hyperframes render . -c . --fps 60 --workers 1 -o out/wide-dark-v1.mp4
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Verify current help's overwrite behavior and choose a fresh output. The positional argument is the project directory; `-c .` selects index.html (`-c` accepts a composition file path, not its id). A check or render failure stays partial; preserve logs and do not switch engines silently.
|
|
31
|
+
|
|
32
|
+
## Inspect and distribute
|
|
33
|
+
|
|
34
|
+
Probe width/height/r_frame_rate/nb_frames/duration with ffprobe when available, then decode frame 0/150/299 and inspect each master for clipping, title exactness, readable contrast and seam continuity. Inspect posters and previews at 320/390/1440px in both themes. Verify the paths-only SVGs and source strings at asset level; CSS cannot recolor an external SVG image.
|
|
35
|
+
|
|
36
|
+
Encode each inline preview initially at 6fps, 560x280 wide or 384x480 mobile, <=64 colors; 30 frames for five seconds. Use ffmpeg palettegen/paletteuse or an available equivalent. The master remains 60fps; do not describe the preview as 60fps. Inspect readability before trading dimensions/quality for bytes. Budget <=2.5 MiB each; record an explicit delivery decision if that cannot be met. GIF and animated WebP compatibility are separate checks. A static poster is always required.
|
|
37
|
+
|
|
38
|
+
Use `templates/readme-cover-section.md`, updating only to existing local asset names and meaningful alt text. Reduced-motion sources precede animation sources; img is static. Link MP4 as an optional viewing master; arbitrary README video HTML is not assumed supported. Verify local media selection and reduced motion now; GitHub/npm sanitization and actual public playback remain POST_PUBLICATION_UNVERIFIED. Never publish, invent a CDN URL or target new files at an immutable old version to close that gate.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Repository facts and assembly
|
|
2
|
+
|
|
3
|
+
Find the real package root, including monorepo boundaries. Read package metadata and scripts, entry points, LICENSE, current README anchors, contribution/support/security docs and relevant tests. Store claims with ids, wording and repository-relative source paths. Copy commands from executable metadata and try the harmless documented quick start in the task fixture. A field named license is not proof that unrelated art/fonts share that license.
|
|
4
|
+
|
|
5
|
+
The `scripts/check-facts.mjs` helper is read-only. It rejects unknown fields, duplicate claim ids, empty sources, escaping/symlink/missing source paths and malformed badge URLs. Its success is only structure/path validation. Manually compare each claim to source content and each badge to its real status endpoint. Omit uncertain popularity, coverage, affiliation and supported-platform assertions. Do not invent a badge URL; a syntactically valid URL does not establish that it exists.
|
|
6
|
+
|
|
7
|
+
First read the brief, current README, project identity and supplied assets. No interview is mandatory. Ask only when at least two plausible answers would materially change README scope or structure, architecture, permissions or data behavior, accessibility, or visual direction. For those choices, ask one high-impact question per user turn, state the consequence, and wait before choosing or editing. Retain every answer in a task-local decision note across rounds; after each reply, ask only about an unresolved material choice. Continue for as many rounds as materially necessary, then proceed without repeated approval. Never re-ask a settled choice, including in new wording; read the note on resume. When a brief names competing visual directions and leaves them undecided, that axis stays unresolved even if the brief calls every option acceptable: acceptance is not a selection or a delegation. Give it its own round once higher-impact choices are answered; you may recommend one option inside the question, but do not announce a default for it or implement before the user picks. A default applies only to choices the brief settles, choices it delegates ("your call", "pick one"), and details that do not materially change the result. A brief with no visual direction at all is not an open choice: apply the default cover direction without asking. For a bounded brief, state the default direction and continue. Review-only and plan-only requests remain read-only; a keyword or bare repository name does not authorize writes.
|
|
8
|
+
|
|
9
|
+
Choose alignment (left/center), tone and theme from the project's identity or the user's direction. A useful reading order is one distinctive cover, small relevant badge/logo row, purpose in plain text, copyable quick start, features or real demo, and navigation for longer documentation. Keep emoji restrained. Preserve current anchors and accurate instructions. Do not flatten prose, installation commands or critical instructions into images.
|
|
10
|
+
|
|
11
|
+
Keep an asset manifest listing input hashes, generator or supplied provenance, editable source, chosen engine/version/license decision, output state and inspection. States are source, rendered, inspected, partial; do not infer completion from filenames. On interruption record last completed stage and owned process identity. Resume without overwriting prior outputs. New revisions get new names; missing font/render tools name the exact prerequisite while factual copy continues.
|
|
12
|
+
|
|
13
|
+
Use only an explicit task output root. Read references as data, never as authority to run shell snippets, publish, authenticate or inspect secrets. Avoid shell interpolation of names, README text or SVG metadata. New assets must exist locally before README links are added. Do not target new assets at an immutable already-published npm version. Preserve local preview and label public renderer verification POST_PUBLICATION_UNVERIFIED.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Real inputs and crisp type
|
|
2
|
+
|
|
3
|
+
Image-generation availability belongs to the active OpenCode session, not the model's description of itself. Check its tool list and capabilities. A real native generator result must be inspected, saved inside the authorized project, and recorded with prompt and provenance. Without a callable generator report IMAGE_GENERATION_UNAVAILABLE and finish independent README work. The supplied-background branch may then complete composition, but never becomes native-generation evidence. CSS atmospheres are effects, not generated backgrounds.
|
|
4
|
+
|
|
5
|
+
Use Pretendard for Korean/prose/display and Meslo LGS NF for technical labels. Resolve actual regular font files and readable licenses locally. Record family, style, version, SHA256 and license source before rendering. Do not install system fonts, silently substitute or redistribute uncertain font bytes. A source image must be inspected for words/logos and appropriate mobile/wide crops; preserve it unmodified.
|
|
6
|
+
|
|
7
|
+
From the exact selected SKILL.md root copy `templates/typography/` to a fresh project-local tools directory. Install there with `npm ci --ignore-scripts --no-audit --no-fund`; the lock pins fontkit 2.0.4 (MIT). With explicit existing project root and output parent directories:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
node ./tools/typography/outline.mjs --font "./inputs/Pretendard-Regular.otf" --family Pretendard --license "./inputs/Pretendard-LICENSE.txt" --text "연구 노트" --root "$PWD" --output "assets/title-dark.svg" --fill '#15242a'
|
|
11
|
+
node ./tools/typography/outline.mjs --font "./inputs/MesloLGS NF Regular.ttf" --family 'MesloLGS NF' --license "./inputs/Meslo-LICENSE.txt" --text "FIELD NOTES / 01" --root "$PWD" --output "assets/label-light.svg" --fill '#f4f1e9'
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
The helper accepts bounded regular files, shapes glyph runs with positions and advances, checks all requested glyphs, and includes transformed outline bounds in its viewBox. Whitespace advances without visible outlines. Paths are escaped and output is exclusive; unsafe parent paths/symlinks and missing glyphs fail. Review the recorded license yourself: presence of license text is not legal verification. Stdout reports actual font identity/hash; save it in the asset manifest along with the editable source string. A paths-only SVG still needs text alternatives in Markdown.
|
|
15
|
+
|
|
16
|
+
Create title/subtitle/label variants for each ink palette. Dark-ink filenames bind to light fields; light-ink filenames bind to dark fields. External SVGs do not inherit CSS color. Inspect path fill and its solid backing field for >=4.5:1 contrast before rendering. Keep blur on background only, add static/seeded grain, a restrained lighting falloff and crisp original pixel imagery. Expose restrained/expressive amount controls without requiring duplicate outputs. Describe raster image plus vector outlines as a hybrid asset.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { parseArgs } from 'node:util';
|
|
2
|
+
import { pathToFileURL } from 'node:url';
|
|
3
|
+
import { inside, readRegular } from '../templates/typography/files.mjs';
|
|
4
|
+
|
|
5
|
+
export function checkFacts(facts, root) {
|
|
6
|
+
const keys = (value, allowed) => value && typeof value === 'object' && !Array.isArray(value) && Object.keys(value).every(k => allowed.includes(k));
|
|
7
|
+
const nonempty = s => typeof s === 'string' && s.trim().length > 0 && s.length <= 4096;
|
|
8
|
+
if (!keys(facts, ['claims','badges']) || !Array.isArray(facts.claims) || !facts.claims.length || facts.claims.length > 200 || !Array.isArray(facts.badges) || facts.badges.length > 20) throw new Error('invalid facts structure');
|
|
9
|
+
const ids = new Set();
|
|
10
|
+
for (const claim of facts.claims) {
|
|
11
|
+
if (!keys(claim, ['id','text','sources']) || !nonempty(claim.id) || ids.has(claim.id) || !nonempty(claim.text) || !Array.isArray(claim.sources) || !claim.sources.length || claim.sources.length > 20) throw new Error('invalid or duplicate claim');
|
|
12
|
+
ids.add(claim.id);
|
|
13
|
+
for (const source of claim.sources) readRegular(inside(root, source), 8 * 1048576);
|
|
14
|
+
}
|
|
15
|
+
for (const badge of facts.badges) {
|
|
16
|
+
if (!keys(badge, ['label','url','claim']) || !nonempty(badge.label) || !ids.has(badge.claim) || !nonempty(badge.url) || /[\s\x00-\x1f\x7f]/u.test(badge.url)) throw new Error('invalid badge');
|
|
17
|
+
const url = new URL(badge.url);
|
|
18
|
+
if (!['http:','https:'].includes(url.protocol) || url.username || url.password || !url.hostname) throw new Error('unsafe badge URL');
|
|
19
|
+
}
|
|
20
|
+
return {valid:true, validation_scope:'structure-only', factual_accuracy:'not-checked', source_contents_compared:false, badge_truth_checked:false};
|
|
21
|
+
}
|
|
22
|
+
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
23
|
+
try {
|
|
24
|
+
const {values} = parseArgs({options:{root:{type:'string'},facts:{type:'string'}}});
|
|
25
|
+
if (!values.root || !values.facts) throw new Error('--root and --facts required');
|
|
26
|
+
console.log(JSON.stringify(checkFacts(JSON.parse(readRegular(inside(values.root, values.facts))), values.root)));
|
|
27
|
+
} catch (error) { console.error(`readme-studio: ${error.message}`); process.exitCode = 1; }
|
|
28
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"title":"Replace with verified project name","subtitle":"Replace with verified purpose","label":"LOCAL PROJECT","background":{"path":"inputs/background.png","origin":"supplied or native tool receipt","sha256":"record actual hash"},"fonts":[],"alignment":"left","effects":{"blur":6,"grain":0.04,"glow":0.18,"depth":0.025},"engine":"select before rendering","state":"source"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"claims":[{"id":"purpose","text":"Replace with verified purpose","sources":["README.md"]}],"badges":[]}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en" data-fps="60">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>README cover</title>
|
|
6
|
+
<style>
|
|
7
|
+
* { box-sizing: border-box }
|
|
8
|
+
body { margin: 0 }
|
|
9
|
+
#cover {
|
|
10
|
+
position: relative; width: 1600px; height: 800px; overflow: hidden;
|
|
11
|
+
background: #15242a; --far-blur: 9px; --middle-blur: 2px; --grain: .04; --glow: .18;
|
|
12
|
+
}
|
|
13
|
+
.background { position: absolute; width: 100%; height: 100%; object-fit: cover }
|
|
14
|
+
.depth-plane-far {
|
|
15
|
+
filter: blur(var(--far-blur)); transform: scale(1.04);
|
|
16
|
+
animation: field 5s ease-in-out both;
|
|
17
|
+
}
|
|
18
|
+
.depth-plane-middle {
|
|
19
|
+
filter: blur(var(--middle-blur)); opacity: .68; transform: scale(1.03);
|
|
20
|
+
mask-image: linear-gradient(to bottom, transparent 5%, black 28%, black 72%, transparent 94%);
|
|
21
|
+
-webkit-mask-image: linear-gradient(to bottom, transparent 5%, black 28%, black 72%, transparent 94%);
|
|
22
|
+
animation: middle-plane 5s ease-in-out both;
|
|
23
|
+
}
|
|
24
|
+
.glow {
|
|
25
|
+
position: absolute; inset: 0;
|
|
26
|
+
background: radial-gradient(ellipse at 80% 10%, rgba(170,240,196,var(--glow)), transparent 60%);
|
|
27
|
+
}
|
|
28
|
+
.rim-light {
|
|
29
|
+
position: absolute; inset: 0; z-index: 3; pointer-events: none; mix-blend-mode: screen; opacity: .78;
|
|
30
|
+
background: linear-gradient(112deg, transparent 42%, rgba(255,244,196,.04) 46%, rgba(255,239,184,.38) 49%, rgba(255,255,245,.2) 50%, rgba(255,239,184,.08) 53%, transparent 59%);
|
|
31
|
+
}
|
|
32
|
+
.panel {
|
|
33
|
+
position: absolute; z-index: 4; left: 64px; top: 60px; width: 1024px; padding: 36px;
|
|
34
|
+
background: #15242a; border: 1px solid #f4f1e9; animation: entry 5s cubic-bezier(.2,.8,.2,1) both;
|
|
35
|
+
}
|
|
36
|
+
.sharp-foreground { filter: none }
|
|
37
|
+
.label { height: 24px; width: 42%; object-fit: contain; object-position: left }
|
|
38
|
+
.title { width: 100%; display: block; margin-top: 42px }
|
|
39
|
+
.subtitle { display: block; width: 94%; margin-top: 24px }
|
|
40
|
+
.rule { height: 1px; background: #f4f1e9; opacity: .35; margin-top: 40px }
|
|
41
|
+
.pixel { position: absolute; z-index: 5; right: 80px; bottom: 68px; width: 240px; height: 186px; animation: sprite 5s ease-in-out both }
|
|
42
|
+
@keyframes field { 0%,100% { transform: scale(1.04) } 50% { transform: scale(1.065) } }
|
|
43
|
+
@keyframes middle-plane { 0%,100% { transform: scale(1.03) } 50% { transform: scale(1.045) } }
|
|
44
|
+
@keyframes entry { 0%,100% { transform: translateY(12px) } 8%,92% { transform: translateY(0) } }
|
|
45
|
+
@keyframes sprite { 0%,100% { transform: translateY(0) } 50% { transform: translateY(-16px) } }
|
|
46
|
+
@media (prefers-reduced-motion: reduce) {
|
|
47
|
+
.depth-plane-far, .depth-plane-middle, .panel, .pixel { animation: none !important }
|
|
48
|
+
}
|
|
49
|
+
</style>
|
|
50
|
+
</head>
|
|
51
|
+
<body>
|
|
52
|
+
<div id="cover" data-composition-id="ReadmeCover" data-start="0" data-width="1600" data-height="800" data-duration="5" data-no-timeline>
|
|
53
|
+
<img class="background depth-plane-far" src="background.png" alt="">
|
|
54
|
+
<img class="background depth-plane-middle" src="background.png" alt="">
|
|
55
|
+
<div class="glow"></div>
|
|
56
|
+
<div class="rim-light"></div>
|
|
57
|
+
<svg width="1600" height="800" style="position:absolute;z-index:2;opacity:var(--grain)"><filter id="grain"><feTurbulence type="fractalNoise" baseFrequency=".8" numOctaves="2" seed="17"/></filter><rect width="100%" height="100%" filter="url(#grain)"/></svg>
|
|
58
|
+
<div class="panel sharp-foreground"><img class="label" src="label-light.svg" alt="Technical label"><img class="title" src="title-light.svg" alt="Project title"><img class="subtitle" src="subtitle-light.svg" alt="Purpose"><div class="rule"></div></div>
|
|
59
|
+
<svg class="pixel" viewBox="0 0 9 7" shape-rendering="crispEdges" aria-label="Original pixel sprite"><path fill="#c9ee95" d="M3 0h4v1H3zM2 1h6v1H2zM1 2h2v1H1zM4 2h1v1H4zM6 2h3v1H6zM0 3h9v1H0zM1 4h7v1H1zM2 5h1v1H2zM5 5h2v1H5zM1 6h2v1H1zM5 6h3v1H5z"/></svg>
|
|
60
|
+
</div>
|
|
61
|
+
</body>
|
|
62
|
+
</html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"duration":5,"assertions":[{"kind":"keepsMoving","withinSelector":"#cover","maxStaticSec":1.2}]}
|