SOURCE / PINNED RELEASE
Made of little things.
Drone Zone — deep field
- Release
- 578f277a8be1…
- Author-recorded commit
- a96742b428de…
- License
- LICENSE
- Author’s source reference
- nostr://npub1n8ga89w8h6tvwamxusfyzexw8gjy84yxu9rxgnmk955cxtml4ujswzxydd/wss%3A%2F%2Fgit.napplet.soy%2F/n-9753e6cf3ec
Archive hash verified: f7f3bf8ff3482551…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
# napplet soyLI integration
This project includes the maintained napplet/boilerplate and unchanged upstream
napplet-* skills. Start with napplet-make. Protocol guidance stays upstream;
this note maps its local tooling commands to the installed napplet soyLI.
## Commands
- The project is already scaffolded. Do not run another creator CLI or re-scaffold it.
- Skills are already installed locally in .agents/skills and .claude/skills.
The upstream npx skills command is an alternative for other environments.
- soyli setup prepares the pinned Node/pnpm toolchain and dependencies.
Nothing is installed globally; ordinary pnpm commands also work if you have it.
- soyli run verify runs the upstream guidance/type/build checks.
- soyli run test:conformance runs the upstream reference-shell checks.
Its pinned test browser is downloaded and cached on first use.
- soyli dev watches the Vite build inside the napplet.soy sandbox.
Use its URL for preview. The upstream pnpm dev URL serves source without a host.
Switch from Play to Listing to inspect the title, description, tags, creator,
screenshot, optional video clip, license and publishing destinations. Use Capture screenshot after
the final build; inspect the saved image in Listing before publishing. Captures
select a new PNG in napplet.json and preserve previous images.
The Settings button opens the same live configuration form as the website.
- soyli build makes dist/index.html. Edit index.html, src/main.ts and
src/styles.css; keep the upstream Vite configuration and dependency lockfile.
- soyli config shows effective publishing targets without a signer or build.
config init writes them into napplet.json for older projects.
- soyli check checks the existing built artifact in our host.
- soyli screenshot saves preview.png and selects it in napplet.json.
Inspect the image: it should show a representative app state, not a blank canvas
or loading screen. Use screenshot preview-2.png for another capture, or supply
your own PNG with preview.image. Capture after the final build.
- soyli record saves preview.webm and selects it with the current artifact hash.
Listing also offers Record clip with start-delay and length controls. It records
a fresh run, not the interactive session currently on screen. Play and inspect
it in Listing; keep the static PNG as well. Existing clips are never overwritten.
For an interaction recipe set preview.recording.actions: timed click (x/y in a
960 × 600 viewport), keyDown or keyUp with atMs relative to recording start.
preview.recording.durationMs is 2000–8000; startMs is 0–10000 after normal startup.
A changed build needs a fresh clip, or remove preview.video to publish only a PNG.
- soyli publish --dry-run inspects source and destinations;
soyli publish publishes the existing build. Build after editing and
before publishing. Publication and checks never execute project scripts.
- For older single-file projects whose napplet.json entry is index.html, edit
that file directly and use dev/check/publish; no build toolchain is required.
## Metadata and host support
napplet.json owns this client's creator reference, name, identifier, topic labels,
relay/resource hints and publication destinations. It replaces the upstream
CLI's deployment configuration in this workflow; never put creator secrets in
the project. Read it before publishing and tell the creator the effective targets.
New projects expose publish.networks.public and publish.networks.local explicitly:
relay is the primary manifest/descriptor relay, blossom receives the HTML, source
archive, preview image and selected WebM, grasp is the NIP-34 Git service, and site displays the
result. The defaults use wss://relay.napplet.soy, https://blossom.napplet.soy,
https://git.napplet.soy and https://napplet.soy. Edit those fields to choose services.
CLI --relay/--blossom/--grasp/--site overrides apply only to that publication.
The optional mirrors array receives extra descriptor/manifest copies only after
our primary relay acknowledges publication; failures do not undo the primary
publication. Use mirrors: [] to disable extra copies. Never substitute a foreign
primary relay silently. relays and servers at the top level are runtime read and
resource hints, not publishing destinations. Git must provide NIP-34/GRASP support.
A new release may change Blossom, site and mirrors. Existing relay/Git history
requires explicit migration when moving those services; --resume always uses the
saved release destinations. Keep the publication journal to preserve that history.
Publishing automatically captures a 1200 × 750 PNG from the sandbox when no
preview.image is selected, using preview.delayMs (1500 by default, 250–10000).
It uploads the PNG to the selected Blossom server and publishes a linked signed
app descriptor so other clients can discover it. This fallback prevents accidental
imageless releases; an inspected screenshot is still the preferred finishing step.
For an interactive scene needing a start click, take a representative PNG during
manual/browser testing and select it with preview.image. Only PNG up to 5 MiB and
4096 × 4096 is currently accepted. Remove preview.image to resume automatic capture.
Optional clips use silent VP8 WebM up to 5 MiB, 1200 × 750 and 12 seconds.
soyli record produces 960 × 600 video; the recorder may add a brief final frame.
Publishing freezes its bytes and NIP-92 imeta on the linked app descriptor, retaining
ordinary PNG metadata for clients that do not display video. Never fabricate a clip
or change preview.video.artifactHash to bypass the stale-build check.
The local preview setting is authoring configuration, not a new Nostr manifest tag.
Readable routes are a one-time website claim, not an automatic publish step.
After publishing, open the napplet page, connect the same creator account and
choose Named link to claim /@your-handle/your-slug. The name follows later releases.
Existing published napplets can claim a name without republishing.
## Local Git checkpoints and public releases
new initializes Git but does not create an initial commit. Treat local commits as
the creator's development checkpoints: make a first commit after reviewing the
scaffold, then commit coherent changes after the relevant checks. Before pausing,
save a checkpoint even if the whole napplet is unfinished; describe outstanding
issues accurately in its message. Do not wait for publication to preserve work.
Follow the creator's Git preferences and inspect git status and git diff first.
Review the files being staged, including new files; do not sweep unrelated work or
secrets into a commit, rewrite history, or push without the creator's authorization.
Local commits and publication serve different purposes. soyli publish freezes the
selected CURRENT FILE CONTENTS into a separate release repository inside the ignored
.napplet-space journal, then sends that release history to the configured GRASP.
It does not commit, push or back up the working repository's branches/history.
Built projects include tracked and unignored untracked files by default, plus the
built HTML and selected previews; publish.files can narrow source selection.
An uncommitted file can therefore be published. Inspect soyli publish --dry-run
before publishing. Keep private notes ignored and signing keys outside the project.
GRASP holds published source releases, not unpublished work or all local checkpoints.
Preserve a separate private backup of the project if those checkpoints matter.
## Pause and resume an existing creation
Keep the same folder, .git history, napplet.json creator/identifier and ignored
.napplet-space journal. For an AI handoff, save a private .napplet-space/RESUME.md
with the current goal, changed files, checks and results, known host limitations,
and next steps. Never include credentials. Do not put a private handoff in public
source files. A new AI session should read it and inspect Git before changing code.
After a soyLI release, stop the old dev process, update the executable using the
installer without new/remix arguments, and run soyli skills update in this folder.
Review reported conflicts; edited guidance is preserved. Start soyli dev again to
use the updated bundled host. Skills update does not replace source or dependencies;
follow explicit migration instructions if a release needs changes to those.
Keep using the existing creator identity. Do not scaffold a replacement project.
soyli publish --resume resumes a saved PUBLICATION, not authoring: it uploads the
old frozen bytes even if current files changed. Ordinary editing needs no resume flag.
## Creator backup
Creating a local identity also saves its private key as an nsec file outside this
Git project. The CLI prints the path before installing dependencies. By default
it is `~/.config/napplet-space/accounts/public/<public-key>.nsec` (local-network
identities use accounts/local). The file has owner-only permissions. Preserve a
private copy: it is unencrypted and can recover the creator identity.
soyli account backup saves or locates that file for an existing local
creator. To restore it, use soyli account import --stdin < /path/to/key.nsec.
Signing continues to use the OS credential store; the project contains only the
public creator reference. Remote-signer identities are backed up in their signer.
Never copy the key into source, skills, browser code, or published assets.
## Runtime capabilities
Keep hard domain requirements in vite.config.ts; the publisher reads the build's
napplet-requires metadata and checks it against this host. Optional domains must
degrade gracefully, following upstream guidance. Use the injected namespace and
SDK; do not add a bootstrap or a private protocol extension to app code.
This host provides configuration, identity, storage, theme, resource, relay/outbox reads,
common reads, user-confirmed links and session files. Social writes, signer
operations, ContextVM and cross-napplet operations are not currently granted.
A domain's presence does not promise that every operation will be permitted.
Our host check complements upstream conformance; report each result separately.
Check host capability discovery before implementing a capability-dependent feature:
an SDK export or passing upstream reference-shell test does not mean soyLI or the
deployed website implements that domain. Local and deployed versions may differ.
soyLI 0.8.0 adds NAP-MEDIA shell-owned audio/stream playback. The website needs the
matching deployment; upgrading one does not upgrade the other. Use the upstream SDK
media.createSession with owner: 'shell', source.url (public HTTPS), optional audio
metadata, live: true for radio, and autoplay: false when showing your own play button.
Wait for the result's canonical sessionId, subscribe with onState/onCapabilities,
then sendCommand for play/pause/stop/volume. Destroy sessions when leaving the view.
MP3, Ogg audio and WAV are supported subject to browser codecs. The host handles
streaming, source checks and gesture prompts. Only use advertised controls; no seek,
playlists/HLS/DASH, video, napplet-owned sessions or hash/Nostr-only source resolution
is implemented. Nostr hints and session context are metadata, not network authority.
Artwork is not loaded by this audio host. Four sessions per frame are allowed; one
plays at a time. Streams stop at 128 MiB or two hours and close with the napplet.
Small embedded data/blob audio and Web Audio are separate browser features, subject
to user activation and codec support. Do not work around missing media support by
adding direct remote URLs, fetch, an unbounded resource download or a looser CSP.
For clients without media, keep a clear unavailable state or user-confirmed link
fallback; if playback is the core purpose, declare media required and report the
host gap. Test the actual play/pause/volume flow, not only build/startup or relay lookup.
## User-facing settings
config.schema.json declares the napplet's NAP-CONFIG settings. The upstream Vite
plugin embeds it as napplet-config-schema metadata inside the signed HTML build.
This is separate from napplet.json, which configures publication and infrastructure.
The starter's src/napplet-settings.ts uses the upstream SDK config.subscribe to
apply text size, control height and text selection live. Replace these example
properties with settings relevant to the creation. Keep sensible in-app fallbacks
when config is optional; declare requires: ['config'] in the existing Vite plugin
only if the core experience cannot work without it.
Use the NAP-CONFIG Core Subset: typed properties, literal defaults, enum choices,
numeric/string/list bounds and nested objects (at most four levels). No refs,
regex patterns, expressions or conditional schemas. x-napplet-section and
x-napplet-order organize the form. config.openSettings can open it from an app
control. For a static schema, do not also call config.registerSchema at startup.
The host validates edits and pushes values; a napplet cannot write configuration.
Space scopes values by verified creator/address/build and viewer. A new build
starts fresh. Non-secret settings persist on this browser; x-napplet-secret
string fields are masked, have no default, and last only for the running session.
Never use settings to request the creator's signing key. Check Settings in the
local preview, including defaults, live changes and a reload, before publishing.
## Upstream maintenance
Pinned boilerplate: https://github.com/napplet/boilerplate/tree/cbbebe9bd56271277b054535c0a8d720a588f61d
Pinned skills: https://github.com/napplet/napplet/tree/976ad0549c38f93d4ed418d3ea59a615a7e5fd7f
Upstream source, configuration, documentation and scripts are retained. Local
changes: package name, this integration note, agent entry pointers, private-state
gitignore entries, a static settings example and its single main.ts import, and
excluding installed skill folders from the boilerplate's repository-guidance scan.
The guidance check for a schema-free starter now checks our static settings example.
Skill bodies and licenses are unchanged. Run
soyli skills update to install the CLI's bundled skill revision; modified
files are reported as conflicts and preserved. Template/source changes are never
applied by that command.