Skip to content

feat(gamepad): implement SDK, tooling, and complete repository coverage - #242

Merged
dskvr merged 20 commits into
mainfrom
feat/nap-gamepad
Oct 14, 2026
Merged

dskvr merged 20 commits into
mainfrom
feat/nap-gamepad

Conversation

@dskvr

@dskvr dskvr commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Implement the proposed NAP-GAMEPAD across every organization repo and package, including boilerplate and the Kehto runtime dependency. Add core/API types, the cached NAP binding, SDK root/subpath exports and npm/JSR maps, selected shim injection, manifest inference, conformance envelopes/reference injection, and authoring/site/package guidance.

Controllers use exactly subscribe, unsubscribe, and state envelopes without correlation ids. Bindings preserve null slots, validate ranges and neutral views, clone caller/listener snapshots, and accept only parent state. The reference mock reports unavailable controllers; live host behavior is verified in Kehto.

Validation: pnpm build, pnpm type-check, recursive unit suite, docs build pass. The current slop gate is 98/100 with zero errors and the existing fflate dependency advisory. Built SDK import tests prove both root and subpath exports. Real Chromium verifies controller access denial and frame/host/tab focus isolation. Compiled macOS CLI renders the controller fixture and invokes the maintained Paja entry with no host Node/npm/pnpm/Deno on PATH, using explicitly assembled source-build private cache entries. This does not claim unreleased npm packages were downloaded.

Release metadata prepares core/NAP 0.34.0, SDK 0.30.0, shim 0.32.0, conformance 0.20.0, conformance CLI 0.3.4, plugin 0.16.1, while retaining CLI 0.9.0. Conformance CLI requires the already-published Paja line >=0.21.0 <0.22.0; the lockfile selects 0.21.0 and compatible core/NAP peers. Strict npm and pnpm consumer installs of the unchanged release tarballs pass, and installed previews receive GAMEPAD state with both published Paja 0.21.0 and 0.21.1. CLI runner pins are split into follow-up #243, which merges after this release publishes conformance CLI 0.3.4 with Kehto CLI 0.5.5 already published. Primary CLI retains its existing published runners so fresh-cache CI does not try to download its own unpublished package. No provisioning test was weakened.

Coverage and limits are recorded in .planning/phases/163-nap-gamepad-across-repositories/COVERAGE.md. Consumer PRs: napplet/boilerplate#7, napplet/nappagochi#1, napplet/migrate#1, napplet/cvm#1, napplet/.github#1. naps PR 108 is the authoritative proposal; no duplicate normative spec is added.

CVM controller tests pass, but its existing protected-authority/timing failures reproduce on untouched main. No production image promotion or deployment is performed.

Native API replacement remains deferred because GAMEPAD permits it while NIP-5D currently limits runtime injection to window.napplet. Runtime access denial and the required domain API are implemented. Canonical heads rechecked unchanged: GAMEPAD 0b28f77e3dfa0f07dd7c0f9d61a7090ee99f3a5e; NIP-5D 020cb8b33a9e4c6b8ca4b2f9d0ed0a67843b68f7.

dskvr and others added 8 commits October 12, 2026 09:09
Co-Authored-By: Codex <codex@openai.com>
Add the proposed GAMEPAD types, exact fire-and-forget envelopes, selected runtime injection, synchronous cached reads, and npm/JSR public entrypoints. Test mutation isolation, independent listeners, source trust and built SDK imports.

Co-Authored-By: Codex <codex@openai.com>
Co-Authored-By: Codex <codex@openai.com>
Co-Authored-By: Codex <codex@openai.com>
Co-Authored-By: Codex <codex@openai.com>
dskvr and others added 2 commits October 12, 2026 12:31
Co-Authored-By: Codex <codex@openai.com>
@dskvr
dskvr requested a review from hzrd149 October 12, 2026 19:48
hzrd149 and others added 7 commits October 12, 2026 15:09
A throwing listener stopped delivery to every later listener, including
neutral focus-loss snapshots. Each listener now runs in its own try/catch
and the error is rethrown from a microtask so it is still reported.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The runtime prelude embedded createGamepadStateTools.toString(), which
breaks inside the opaque iframe once a bundler or coverage transform adds
helper references (__name, cov_*). The prelude now uses a literal JS source
kept equivalent to @napplet/nap/gamepad by a vector test, and isolates
throwing onChange listeners the same way the nap binding does.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
NAP-GAMEPAD's Web Projection Guidance gives allow="gamepad 'none'" for
napplet frames. No NIP-5D or NAP text covers hid or usb, so the harness
no longer adds them to its loading model.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
installGamepadShim subscribed immediately, so every napplet using the
default domain set sent gamepad.subscribe and received controller state
for its lifetime, and the conformance prelude's own subscribe was credited
to the napplet under test. NAP-GAMEPAD lets the binding subscribe "before
or on first use"; both bindings now wait for the first read or onChange.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Replace the domain === 'gamepad' special case in the shared validator
with an optional forbiddenReason on EnvelopeSpec.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The snippet closed its onChange subscription in the same synchronous
block, so the handler could never run.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The release step hard-wrapped every existing CHANGELOG entry and left
runs of spaces in the new ones. Earlier entries now match main and only
the new version sections are added.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@hzrd149

hzrd149 commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator

Review follow-up: two findings were not fixed on the branch.

1. Release-order conflict with @kehto/paja (needs a decision). packages/conformance-cli/package.json now uses workspace:* for @napplet/core / @napplet/nap, which publishes as 0.34.0. The newest published Paja is 0.20.1 (0.21.0 isn't on npm yet), and it peer-requires core/nap >=0.32.0 <0.33.0. If conformance-cli 0.3.4 ships before Paja 0.21.0 with widened peers, npm 7+ fails with ERESOLVE and pnpm only warns, then runs Paja against mismatched core/nap. Options: hold the conformance-cli release until Paja 0.21.0 is published, or keep the old 0.32.0 pins in this release and move to workspace:* in the CLI follow-up.

4. forbiddenFields: ['id'] on gamepad.subscribe/unsubscribe: no change needed. NAP-GAMEPAD (napplet/naps#108) says "All three messages are fire-and-forget. None carries id." and "The shell silently ignores malformed or excessive subscription messages." So both the conformance error and the reference shell dropping such messages follow the spec.

🤖 Generated with Claude Code

@dskvr

dskvr commented Oct 14, 2026

Copy link
Copy Markdown
Contributor Author

@hzrd149 Paja 0.21.0 has been published.

dskvr and others added 2 commits October 14, 2026 00:38
Raise the Paja minimum to 0.21.0 and update the lockfile to its compatible core/NAP peer graph. Verify the packed 0.3.4 release with strict npm and pnpm installs while retaining GAMEPAD correlation-id validation.

Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
@dskvr

dskvr commented Oct 14, 2026

Copy link
Copy Markdown
Contributor Author

Following up on this review: addressed the release-order finding in 3c3f1a66.

1. Keep the core/NAP 0.34.0 release and require compatible published Paja. Paja 0.21.0 is now published with core/NAP peers >=0.32.0 <0.35.0. Raised the conformance CLI dependency to >=0.21.0 <0.22.0, updated the lockfile from 0.20.1 to 0.21.0 and its compatible Kehto dependency graph, and synchronized the package/site documentation and 0.3.4 changelog.

Reproduced the old 0.20.1/core 0.34.0 pairing failing with npm ERESOLVE. Fresh npm and pnpm installs of the candidate pass with strict peer checking. Because the napplet versions are not published yet, a temporary registry served their unchanged pnpm pack tarballs; Kehto and other dependencies came from npm. No dependency overrides or peer-check bypasses were used. Verified both Paja 0.21.0 and the subsequently published 0.21.1, including installed CLI screenshot captures that wait for actual GAMEPAD state delivery.

4. Retained the existing behavior. forbiddenFields: ['id'] remains on both subscription messages. Checked that valid envelopes pass, envelopes carrying an id fail validation, and the reference shell silently drops them. This follows the current NAP-GAMEPAD Wire Protocol and Error Handling.

Local build, types, recursive unit tests, five browser conformance tests, release/workflow contract tests, and the slop gate pass. Slop is 98/100 with zero errors and the existing fflate advisory. All nine remote checks pass on final head 5e11d4ca, including CI, conformance, link checks, the slop gate, and all five standalone platforms. This resolves the review findings; #243 still follows publication of conformance CLI 0.3.4.

Co-Authored-By: Codex <noreply@openai.com>

# Conflicts:
#	.planning/STATE.md
#	skills/napplet-design/SKILL.md
@dskvr
dskvr merged commit 8390005 into main Oct 14, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants