@iodes/releasekit
v0.3.0
Published
Git-based visual release notes and portable agent skills
Readme
ReleaseKit pairs a deterministic CLI with portable agent skills. Your agent writes the notes and selects or creates images; the CLI collects Git evidence, prepares image requests, validates content, and exports JSON with local assets.
| Dark | Light |
| :---: | :---: |
|
|
|
One scene brief, two theme variants. Fictional feature illustrations. Browse the composition gallery →
Why ReleaseKit?
- Grounded in Git. Draft from tags or commits, pin the evidence, and keep each release's changes together.
- Works with your agent. Use portable skills for Codex, Claude Code, and Cursor, plus the image tools already available to you.
- Visuals for your feature. Generate flat explanations in dark and light, or reuse an approved screenshot, photo, or content image across both viewer themes.
- Content you own. Keep Markdown, translations, and images in your repository. Export JSON and local assets for your product to display.
Quick start
Requires Git and Node.js 22.12+.
1. Install
npm install -g @iodes/releasekit2. Set up your product
Run inside your product's Git repository:
releasekit initSetup asks for agent tools first, then image themes. In the tool list, use ↑/↓ to move, Space to select or clear a tool, and Enter to continue. No tools are selected initially; A toggles all and I inverts the selection. Select at least one tool to continue. Pressing Enter with no selection displays an error and keeps the tool picker open. For image themes, use ↑/↓ to choose Both dark and light (the default), Dark only, or Light only, then press Enter. The picker explains each highlighted choice: both themes prepares matching versions for dark and light backgrounds; a single theme prepares one version for the chosen background. This default applies to generated release-note illustrations in new drafts and can be changed later. Ctrl+C cancels before configuration is written. Product name defaults to the repository folder name, and the original language defaults to English with no translations. Language selection remains part of the first draft workflow.
The original command still initializes immediately with no questions:
releasekit init --tools codex,claude,cursor --themes bothUse --tools codex to install only selected tools, or --tools none to install no skills. Explicit --tools and --themes options skip their corresponding questions. With --json, --no-interactive, or non-terminal input/output, setup skips all questions and uses all supported tools and both themes unless explicitly overridden. Optional --product, --source-locale, and --locales overrides remain available without adding questions; --locales must include the original language with no duplicates.
Settings are saved to releasekit/config.yaml, and setup prints invocation hints for the installed tools. You can also initialize another existing Git repository with releasekit init ./your-product (relative to --cwd, if supplied). Re-running releasekit init opens only the tool picker, with the saved selection pre-selected. It saves your new selection and installs or refreshes those skills while preserving other settings, configuration comments, line endings, and existing releases. Use releasekit init --tools codex,claude to change tools without prompts, or releasekit init --tools none to select no tools. Without interactive input or an explicit --tools option, re-running init keeps the saved selection. Deselected tools are excluded from future updates; their existing files are not deleted. Product, theme, and language options apply only to first-time initialization; on existing projects, those options produce an error pointing to the configuration file. Edit releasekit/config.yaml later to change defaults for new drafts. Existing releases retain their saved settings.
3. Ask your agent
Start with the installed releasekit-draft skill. Example first-use conversation with a Korean-speaking user, shown here in English, and an image tool available:
You: Use releasekit-draft to draft 1.4.0.
AI: I'll use English for the original notes. Add Korean, your current
language, as a translation (recommended), or use English only?
You can also enter additional languages together.
You: Korean and Japanese translations, and a single release history.
AI: Saved these language defaults and channels: false in releasekit/config.yaml.
Found v1.4.0 and its preceding release tag v1.3.0 on this line.
Created releasekit/releases/1.4.0/
✓ Pinned v1.3.0 → v1.4.0 and collected change evidence
✓ Wrote English originals with Korean and Japanese translations
Next: use releasekit-image to prepare images for all drafted notes.
Choose: Prepare images (recommended), Request copy changes,
or Finish drafting — save the draft and ask for revisions later.
You: Finish drafting.
AI: Drafting 1.4.0 is complete. Opened a local multilingual preview.
Ask me here to rewrite a feature description, leave a feature out,
or add a feature that was missed. I'll update the draft and its
affected translations; saved changes appear in the same preview.
Images and finalization remain pending.
You: Rewrite the queue feature description to explain when to use it.
AI: Updated that feature description and its Korean and Japanese translations.
You: Prepare images.
AI: ✓ Generated dark/light explanations from shared scene briefs
✓ Reviewed and imported both variants for each generated graphic
The product-detail image is pending; I need an approved capture
or photo. Next: provide that image, or review the completed copy
while it is pending.
You: Use ./approved-capture.png for the product-detail note.
AI: ✓ Reviewed and imported it once for both viewer themes
Images for all current notes are ready to review.
Ask me to revise any feature image or replace it with another image.
If no image changes are needed, use releasekit-finalize to confirm 1.4.0.
You: Use releasekit-finalize for 1.4.0, then export up to three releases
in English to ./release-output.
AI: ✓ Validated notes, translations, and images
✓ Marked release 1.4.0 ready
Exported release-output/
├── release-notes.en-US.json ← English notes grouped by release
└── assets/ ← Theme variants and shared supplied imagesThe agent resolves the version and Git range from your request, saved releases, repository tags, and release metadata. It reports a clear scope and proceeds without a tag-selection or confirmation step. If inspection leaves materially different scopes, it asks which work to cover in ordinary language. You can still supply explicit refs to select a particular interval.
Language selection is a first-use decision. When it is still unresolved, the draft skill defaults the original to English, suggests the user's current language for optional translation, and accepts additional language names or locale codes as well as an English-only choice. Explicit choices and intentional project settings are reused. The first selection is saved in releasekit/config.yaml before preparing the draft, without a separate confirmation. Each new draft uses the current config's original language and complete translation set without asking again, even when previous releases used different languages. Existing drafts keep their saved selection. The draft includes the source and all selected translations; use the same skill to request a language change or refresh translations. Changing project defaults affects future drafts while earlier releases remain unchanged.
Invoke the skill with $releasekit-draft in Codex, /releasekit-draft in Claude Code, or the skill picker in Cursor. The agent runs the CLI, generates flat explanations, and requests approved source images when the actual product or content must be shown.
CLI progress and next steps
releasekit list # All releases, including channels
releasekit list --channel stable # One channel
releasekit status # Validate all releases and show next steps
releasekit status 1.4.0 # One unchanneled release
releasekit status 1.4.0 --channel stable
releasekit status --json # Structured progress for scripts
releasekit update # Refresh installed skills; preserve user editslist shows release identities, saved draft/ready state, note counts, and dates. status checks content with the same validation used by validate, displays errors and warnings, and suggests the next step. A ready label alone does not guarantee that files still pass validation. Status is read-only and exits successfully even when drafts have pending work; use validate for a failing exit code when content is invalid. Before initialization, status points to init.
Running releasekit update refreshes skills only for the tools saved in the project configuration during setup. It installs missing skills for those tools, preserves current project configuration and locally modified files, and never prompts for tool selection. An empty tools list installs no skills. Run releasekit init again or edit the tools list in the configuration to change the selection; update does not remove previously installed skills for deselected tools. Update validates only the product label and tool selection from configuration; it does not migrate settings, rewrite config.yaml, or create configuration backups. Older or invalid release settings do not block skill refreshes, but content commands still validate them. Remove obsolete history.limit settings when using content commands; use export --limit for an explicit export limit, or omit it to export all releases. The result leads with a distinct status for completed updates, already-current skills, preserved-file conflicts, or skipped updates with no tools selected. Aligned file counts and project details follow. Successful updates show invocation hints; conflicts list files to merge, and execution failures show the error and retry guidance. Terminal colors highlight success in green, conflicts in yellow, and failures in red; symbols and labels keep the output readable without color. Color follows terminal support and the standard Node.js color environment variables, including NO_COLOR. LF/CRLF-only differences are treated as already current without rewriting skill files. Updates preserve existing skill line endings and recognize hashes from older installations. Actual content edits remain protected. Conflicts and execution failures produce exit code 1. --json returns only the structured result, including written, unchanged, and conflicts arrays. This command refreshes bundled project skills; it does not upgrade the CLI package itself.
Setup, update, prepare, list, status, and validate print readable summaries. --json preserves structured output for automation; command and option errors are JSON objects on stderr with a nonzero exit code. Help and version output remain plain text. Other content operations retain their detailed JSON results. Run releasekit <command> --help for options and releasekit --help for the workflow overview.
Read a draft in your browser
After drafting, the agent opens a local multilingual preview automatically. Choose a saved language to read its full titles and Markdown bodies, switch between light and dark, and see imported images alongside the copy. Ask for all copy, translation, and image revisions in your existing agent conversation; saved changes appear in the same preview automatically. The preview has no direct editing or save controls.
You can also start it yourself:
releasekit preview 1.4.0 --open
releasekit preview 1.4.0 --channel stable --locale ko --open
releasekit preview 1.4.0 --port 4317 --jsonpreview serves only the selected release at http://127.0.0.1:<port>/. Omit --port (or use 0) for an available port; keep the command running and press Ctrl+C to stop. --open launches the default browser; otherwise, open the printed URL in a browser or your agent's web panel. --json prints one startup object containing url, project, version, and optional channel, then keeps the server running. The agent reuses its recorded process and URL for the same project and release rather than opening a server after every revision. There is no installed background service or cross-conversation process discovery.
--locale prefers an exact saved locale or a unique match for a language-only code, such as ko for ko-KR. Missing, unfinished, or stale translations initially fall back to the source language with an explanation. All saved languages remain selectable with their status visible, and switching languages never generates translations or fills missing text from another language. Without a preference, the source language opens first. Interface labels are Korean when the requested locale (or, when omitted, browser language) is Korean, and English otherwise; release content can use any configured locale.
Unfinished drafts can be previewed before validation succeeds. Missing images have a small notice; imported dark/light variants, single-theme images, and unchanged shared supplied images appear when available. Text-only notes have no image notice. The preview polls every second, preserves reading preferences and position, and shows connection or file-reading problems while retaining the last loaded content. A saved ready label is not a substitute for final validation. It reads source files without changing them, serves registered local raster images only, and does not expose a write API or publish content. If the agent environment cannot provide a reachable local preview, it explains the limitation and shows the saved draft in the conversation.
Adopting ReleaseKit later
You can start after your product has already shipped. Ask the draft skill to set a starting point; it finds a relevant release tag or commit from the repository and asks how to handle the earlier period when that choice is unresolved. Regular notes begin after the selected baseline commit.
| Earlier history | Result | | --- | --- | | Product introduction (recommended for an established product) | A concise overview of capabilities at the baseline, grounded in that snapshot without reconstructing every old commit. | | Analyze history | Notes based on the repository's beginning through the baseline. | | Skip | No earlier entry; start recording subsequent changes. |
An introduction does not assume that adopting ReleaseKit was the product's launch. Version, date, and product claims should reflect the actual product. The agent reuses choices already made in the conversation or saved setup.
For example, introduce the product at v1.3.0, then record changes from there:
releasekit start --at v1.3.0 --past summary --baseline-version 1.3.0
releasekit prepare 1.3.0
# Ask the agent to write, review, and finalize the baseline introduction.
releasekit prepare 1.4.0 --previous 1.3.0 --to v1.4.0Use --past history to analyze earlier commits instead. With --past skip, omit --baseline-version; the first regular prepare uses the saved boundary. You can save HEAD as the start now and prepare the first draft when later commits exist. Setup pins the SHA, so moving a tag or adding commits cannot shift the boundary.
start saves the choice and creates no notes. Summary/history baselines become ordinary draft releases when prepared and follow the same draft (including translations), image, and finalization workflow. They count as one release in exported history; skipping creates no extra group. Existing releases keep their current workflow. See the first-use guide.
Workflow
Git range → Draft source + translations → Images → Finalize → Optional export| Skill | Purpose |
| --- | --- |
| releasekit-draft | Choose a first-use baseline, write and revise source notes and selected translations, or refresh translations alone. |
| releasekit-image | Plan, generate or request, review, and import required images. |
| releasekit-finalize | Review copy, evidence, translations, and images; validate and mark the release ready; export when requested. |
All three skills use the agent's native question picker when clarification is needed and the tool is available, with free-text input for another answer; otherwise they ask in chat. This covers language choices, image references, translation scope or terminology, and unresolved finalization/export choices. Existing decisions are reused, and routine technical parameters are resolved through repository inspection. Required CLI flags do not become a questionnaire. Once a question is asked, dependent work waits for your submitted answer; a default selection, elapsed time, or a closed picker does not count as a choice. Only one question request may remain unanswered in the conversation: newly discovered questions and next-step choices wait in a queue, even across skills or releases. A partial answer keeps the remaining questions pending. The agent keeps an asynchronous picker open while waiting, or asks in chat if the environment cannot support that wait. Image uploads are requested through the conversation's attachment flow.
After each stage, the agent reports what is complete and recommends the next useful task based on the release's current state. Choose a suggested action or describe another direction to continue in the same conversation. After drafting is complete, Finish drafting saves the draft for you to read and request changes from the agent. The agent shows the saved draft titles and full bodies directly in the conversation, using an available complete translation in your language or falling back to the release's source language. The preview does not change saved language settings. The handoff also includes links and examples of revision requests; the agent edits the same draft and refreshes affected translations when you ask. At other stages, you can stop for now. If you already requested the remaining work, the agent continues without asking again. When source and translations are complete, the next step is images; when required images are complete, it is finalization. Text-only releases go directly to finalization. Completed steps are skipped, and missing images or translations stay visible until resolved.
The agent handles editorial work, media selection, and image generation where appropriate. The CLI handles files, evidence, validation, and export. Finalization includes review and marks local content ready with a content fingerprint. Export is optional; committing, publishing, and displaying it remain separate steps.
Replace the sample version, Git refs, and note ID with your own. Save first-use language choices in releasekit/config.yaml before preparation. If release 1.3.0 already exists in ReleaseKit, add --previous 1.3.0 to link its history.
releasekit prepare 1.4.0 --from v1.3.0 --to v1.4.0
# prepare copied sourceLocale and locales from the current config.yaml.
# This example has sourceLocale: en-US and locales: [en-US, ko-KR].
releasekit note add 1.4.0 queue-action
# Write the source and selected translations, then attach evidence.
# Review each translation before marking it current.
releasekit translation mark 1.4.0 queue-action --locale ko-KR
# Complete the visual brief for image work.
# Choose an archetype and set scene.source to generated for this example.
releasekit image plan 1.4.0
# Generate and review the dark image with your agent or an external tool.
releasekit image import 1.4.0 queue-action --theme dark --file ./selected-dark.png
# Plan again to use the accepted dark image as a composition reference.
releasekit image plan 1.4.0
# Generate and review the matching light image, then import it.
releasekit image import 1.4.0 queue-action --theme light --file ./selected-light.png
# Review facts, copy, translations, and selected images, then finalize.
releasekit validate 1.4.0
releasekit finalize 1.4.0
# Export when requested.
releasekit export --out ./release-output- Preparing creates only
release.yamlwith pinned Git boundaries. ItssourceLocaleandlocalesalways come from current project configuration. The agent reads commit history and relevant file diffs from Git as needed. - Use
--from-rootfor an explicitly requested full-history first release. --todefaults to the pinned SHA when preparing a saved baseline, and toHEADotherwise;--previouscan supply the comparison start.- Edit existing drafts in place.
preparenever overwrites them. - Notes include images by default. Use
note add --no-imageonly for an explicit text-only choice. Adding a note clears any previousemptyReason. - Use
releasekit note remove <version> <id>to exclude a draft note. It removes the note folder, translations, visual brief, prompts, and unused managed images, including older imports. Images referenced by remaining visuals and source originals are preserved. The result lists removed paths and retained shared assets. Removing the last note leaves the draft pending until you add notes or supply a factualemptyReason. - Add
--jsonfor structured results or--cwdto select a project directory. - Only
--outis required for export. Omit--currentto select the release with no successor in the savedpreviouslinks; multiple release lines require an explicit--current. The selected release must be ready. Omit--limitto export the entire linked history; pass--limit Nto select at most N releases. - Omit
--localeto export every locale saved in the current release asrelease-notes.<locale>.json, such asrelease-notes.en-US.jsonandrelease-notes.ko-KR.json. Add--locale en-USfor only the English file. All files share the sameassets/directory. Each selected version must contain the requested locales; missing or stale translations stop the export before output is created. - Export to a new directory; an existing destination is never overwritten. The command result lists generated JSON paths in
files, the number of version groups inreleases, and the number of shared image files inassets.
See the agent workflow for ancestry rules and continuing existing releases.
After installing a newer package version, run releasekit update in your product repository. It refreshes managed files, preserves user edits, and reports conflicts.
Codex and Cursor share .agents/skills to avoid duplicate discovery. Claude Code uses .claude/skills.
Release channels
Channel use is a first-draft choice, alongside unresolved language choices. The draft skill saves channels: false for a single history, or a user-selected channel map before preparing content. Initialization leaves the choice unset. Existing projects with releases and no channel setting continue their single history.
The skill asks whether to keep one history or organize releases by audience or purpose. Examples include stable/preview releases, public/internal audiences, or deployment environments when relevant. Names and which releases each view displays are user choices; there is no fixed channel preset.
For example, if you choose stable and preview channels and want preview to display both:
channels:
stable:
include: [stable]
preview:
include: [preview, stable]For later new drafts, an explicit request such as “Draft 2.1 for preview” selects that channel. With several configured channels and no clear target, the skill asks which channel to write for. It reuses an existing draft's channel and never guesses from the previous release or branch name. A project with one configured channel needs no target question. The CLI itself does not prompt.
Channel releases live in releasekit/releases/<channel>/<version>/. The same version can exist in several channels. All channel releases share one newest-to-oldest previous chain using { channel, version } references; an export follows that chain and skips drafts and excluded channels without sorting dates. Channel-free releases keep their separate existing history.
releasekit prepare 2.1 --channel preview --from <git-ref> --to <git-ref>
releasekit finalize 2.1 --channel preview
releasekit export --channel preview --out ./output/preview
releasekit export --channel stable --limit 3 --out ./output/stableThere is no default export count limit. --limit N caps the combined, filtered result at N releases. With the configuration above, preview shows preview and stable releases; stable shows only stable releases. For independent views, set preview to include: [preview]. Includes name channels directly and do not grant or restrict access. The exported entries identify their channels, and the exported previous links connect only entries included in that output. Git analysis boundaries remain independent of display links.
Ask the draft skill to move one or several whole releases, for example “Move preview 2.0 and 2.1 to stable.” It previews and runs the deterministic move command, preserving ready status, content, images, Git boundaries, and release timestamps. Channel-to-channel moves retain their global position; moves to or from a channel-free history splice the selected releases between histories. Conflicts stop the whole move.
releasekit release move 2.0 2.1 --from-channel preview --to-channel stable --dry-run
releasekit release move 2.0 2.1 --from-channel preview --to-channel stablereleasedAt accepts a date or a timestamp with Z or an explicit UTC offset. New drafts default to the current UTC timestamp, including milliseconds. Use --date 2026-09-14T18:30:00+09:00 to supply one; existing date-only strings are preserved. Neither finalization nor channel moves replace the saved time.
See channels and moves for first-use decisions, identity, history, and insertion options.
Image themes
Image work covers every drafted note by default, including grouped minor fixes and improvements. A group uses one visual brief and the configured image variants; individual bullets do not require separate images. Only an explicit text-only choice omits a note's image. Calling releasekit-image again fills missing images, including those for notes added later, and reuses existing valid images. Existing images that need corrections stay pending until the affected revision or replacement is requested.
Minor Fixes and Minor Improvements reuse common originals across releases. The image skill first checks releasekit/common-images/minor-fixes/ or releasekit/common-images/minor-improvements/, importing reviewed compatible images and creating only missing originals or themes. Each release keeps its own copies, so changes to the common design do not rewrite earlier releases. Bullet edits and translations do not require new pictures. The directories are created when reviewed originals become available; see common images.
After generation, review the images and ask the agent to revise anything you dislike or replace it with another approved image. When no image changes are needed and the content is complete, ask for releasekit-finalize to confirm the release.
Generated graphics default to dark and light. Paired variants share one scene brief, preserving geometry, feature meaning, and semantic colors while presentation surfaces adapt. Images are shared across locales.
Choose scene.source in each note's visual brief before planning:
| Source | Use for | Theme handling |
| --- | --- | --- |
| generated | Flat glyphs, interface explanations, diagrams, and data graphics supported by the feature. | Separate images for the configured dark/light themes. |
| provided | Approved screenshots, photographs, or content artwork. Required for object-detail and editorial-scene. | One unchanged shared asset, or distinct genuine theme captures. |
Choose a single theme during setup with --themes dark or --themes light, or edit this field in the generated configuration while keeping the other visual settings:
# releasekit/config.yaml
visuals:
themes: both # both | dark | lightreleasekit image plan <version> reports pending and reusable assets, with separate generationRequests and providedRequests counts. It reuses current imports and never calls a model API. Single-theme exports contain one real asset and an explicit fallback.
To replace or regenerate an image, import the reviewed result with the same release version and note ID and the intended --theme. Import automatically switches shared/themed usage and removes the note's unused managed images after saving, including older imports. Files still referenced by visuals and source originals outside the note's managed assets are preserved. Keep existing variant entries until the replacement is imported. Use --source provided when replacing generated illustrations with a supplied image, or --source generated for the reverse change when the subject permits it; source and selection are saved together. See image transitions.
Requests with action: generate include a prompt for the agent or an external tool. Requests with action: provide have promptFile: null and identify the needed source. Missing supplied media stays pending and blocks finalization; the agent can continue independent writing and translation work.
Complete the note's visual brief with scene.source: provided. This example uses the note ID product-detail:
releasekit image plan 1.4.0
# Once an approved capture or photo is available, inspect it and import.
releasekit image import 1.4.0 product-detail --theme shared --file ./approved-capture.pngThe CLI keeps the original bytes, dimensions, and colors. One shared asset serves both viewer themes without generating or duplicating another file.
If genuine dark/light captures exist, import them with --theme dark and --theme light instead. The CLI replaces the previous shared/themed selection during import; keep its metadata in place until the new file is successfully registered. A missing configured capture remains a supplied-image request.
Follow the current image plan even if older prompt files remain. See the supplied-media example and media source guide for pending inputs and older briefs.
Releases capture the project's visual settings when prepared. To apply updated defaults:
releasekit image plan 1.4.0 --sync-configThis preserves selected files and schedules only newly required or stale variants. Reopen ready content first by setting status: draft and contentHash: null in its release.yaml.
Content and export
Everything lives alongside your product:
releasekit/
├── config.yaml
└── releases/
└── 1.4.0/
├── release.yaml # Metadata, note order, previous release
├── notes/ # Markdown for each locale
├── visuals/ # Scene briefs, media sources, and variants
├── prompts/ # Prompts for pending generated variants
└── assets/ # Selected raster imagesMajor capabilities and changes that warrant individual attention get standalone notes. Small user-visible corrections and conveniences are collected into separate Minor Fixes and Minor Improvements notes, each with a short bullet list, normally after the main notes in that release. Every bullet retains its supporting evidence and selected translations. See note grouping.
Releases store the comparison start and end SHAs in release.yaml, with relevant paths or commits attached to individual notes. They do not save a full patch or a separate changed-file index. Draft validation reads the pinned Git range, or the baseline snapshot for a product introduction; finalized releases can be validated and exported without Git history.
Export follows explicit previous links, keeping each version's notes in a separate group. There is no default count limit; --limit N selects the first N releases after filtering. Similar notes in different versions remain separate.
The bundle contains display data and relative assets. Git evidence, prompts, and private source paths stay out of the export. Consumers safely render bodyMarkdown and select image.variants[theme], falling back to image.variants[image.fallbackTheme] when needed. Text-only notes have image: null.
fallbackTheme can be dark, light, or shared. A shared-image export contains one image.variants.shared entry with fallbackTheme: shared; the same consumer lookup displays it in either viewer theme. Preserve the supplied image's original appearance when displaying it.
Translations track source fingerprints, and finalized releases record content fingerprints to detect later edits. See the file contract and JSON schemas for the full structure.
Documentation
| Guide | What it covers | | --- | --- | | First use in an existing product | Starting points, product introductions, historical analysis, and skipped history. | | Agent workflow | Git boundaries, drafts and translations, images, finalization, and export. | | Writing and translation | Product copy, evidence, and locale freshness. | | Visual language | Composition, hierarchy, materials, and acceptance checks. | | Choosing generated or supplied media | Source selection, pending captures, and shared assets. | | Composition recipes | Eight presentation categories matched to the feature and its source. | | Theme pairs and cost | Shared geometry, single-theme policies, and reuse. | | Common images | Reusing minor-group originals across releases, missing themes, and preserved release copies. | | File contract · JSON schemas | Authoring files and the public export format. | | Worked examples | Paired illustrations, supplied-image workflow, independent briefs, and three-release bundles. |
Visual guidance uses independent, brand-neutral descriptions. Each illustration should communicate the actual feature through its own scene. Worked examples demonstrate the process; standalone notes get their own composition, while minor groups reuse their common scene.
The built-in guidance covers source selection, a scene contract, semantic palette roles, theme-pair invariants, text rules, cost-aware reuse, and visual acceptance checks. Generated icons use compact flat filled glyphs. Neutral supporting elements keep the hierarchy quiet; use the project accent for a primary action, selected/enabled state, active path, or focal information when it guides attention. Color need not be indispensable in grayscale. Generic information icons can remain neutral; review both decorative overuse and suppressed functional accents. The themes use independent neutral hierarchies: compact mid-light neutral glyphs and distinct charcoal layers for dark, medium-gray neutral glyphs and softer supporting values for light. Assign roles by visual hierarchy and compare each theme at equal display widths. A light-only palette correction preserves accepted dark images; shared geometry corrections apply to both affected variants. Existing project palettes and release snapshots remain authoritative. Physical details and content previews use supplied images rather than invented 3D objects or decorative scenes.
Development
Use Node.js 24 for development. From a local checkout:
npm ci
npm run check
npm test
npm run build
npm pack --dry-runCI runs on Windows and Linux with Node.js 22 and 24. Tests cover first-use setup, snapshot summaries, Git ranges, release history, image integrity, theme policies, supplied media and shared assets, translation freshness, finalization, installation conflicts, and CLI behavior.
npm pack
npm install -g ./iodes-releasekit-0.1.0.tgzUse the tarball filename printed by npm pack if the package version differs. Packing builds the package automatically.
The Publish workflow runs manually on a release/x.y.z branch. The branch selects the major/minor release line and starting patch; all three components must be numeric with no leading zeros.
Once the workflow exists on the default and release branches, open Actions → Publish → Run workflow and select the release branch. It pins the selected commit and calculates the next available patch from both Git tags and npm versions. For release/0.1.0, publishing starts at 0.1.0 if unused, then advances past the highest existing patch to 0.1.1, 0.1.2, and so on. A newer major/minor line blocks older lines, and registry errors stop the workflow.
The runner restores dependencies and updates the package and lockfile with npm version --no-git-tag-version; no version-bump commit is needed. The CLI reads that package version for --version. After checks, tests, build, and package preview pass, the workflow creates a new tag and publishes through the npm trusted publisher configured for publish.yml.
Existing tags are never moved. Every run calculates a fresh version, even for the same commit. If an earlier attempt already created a tag or published a package, rerunning advances to the next patch. Tag pushes do not start publishing.
License
MIT © 2026 SO, HYEONSEOP.
