Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
197 commits
Select commit Hold shift + click to select a range
5df5b8d
Bootstrap the OWS repository
Jun 26, 2026
ab27ff6
Update dependencies and implement ngrok integration for secure tunneling
Jun 26, 2026
a803f5a
Enhance ows-signer-utils with viem integration and update README
Jun 29, 2026
aaf43d4
Add @1shotapi/ows-types package for shared types and errors across OW…
Jun 29, 2026
df8be67
Add support for shared protocol types across OWS SDKs
Jun 29, 2026
d5accf0
Add .env.example for ngrok configuration and update package dependencies
Jun 30, 2026
dfdbd64
Successful demo with personal_sign!
Jun 30, 2026
ed170b8
Bring in type brands
Jul 1, 2026
dd8cc31
Enhance EIP-1193 provider with typed results and branded types
Jul 1, 2026
e6dc63b
Introduce EVMSignatureHex type and update EIP-1193 requests
Jul 1, 2026
8df7a5c
Refactor OWS architecture and introduce general wallet example
Jul 1, 2026
38578b6
Add branding core and registry modules for OWS
Jul 3, 2026
e19842a
Refactor Postmate integration and enhance general wallet example
Jul 3, 2026
c63eff5
Add restore backup functionality to general wallet example
Jul 4, 2026
eae834a
Add EVMChainId support and enhance general wallet with EIP-1193 methods
Jul 4, 2026
88ab147
Enhance wallet example with ERC-20 token balance check and new UI ele…
Jul 4, 2026
a781f13
Refactor approval dialog module to support EIP-712 typed data signing
Jul 6, 2026
ff1cc49
Fix arc chain IDs/rpcs
Jul 7, 2026
77a16b0
Add OWS Credentials Extension with issuer and verifier demos
Jul 7, 2026
75d59f0
Update TypeScript and Webpack configurations across examples
Jul 8, 2026
cbe155f
Refactor credential storage and UI handling
Jul 8, 2026
8eeecf2
Add SD-JWT VC support and enhance credential handling
Jul 8, 2026
e83e5ce
Refactor OWS credential handling and dissolve the @1shotapi/ows-crede…
Jul 8, 2026
0e1b1d1
Refactor SD-JWT VC utilities and decouple from wallet-utils
Jul 8, 2026
f2af795
Enhance general wallet setup and address management
Jul 9, 2026
2ef5e84
Remove deprecated code and add a rule for development.
Jul 9, 2026
86656a3
Allow dismissing dialogs by clicking backdrops.
Jul 9, 2026
de0a265
Create plan for trusted loader for the signer. We'll implement it later.
Jul 9, 2026
36974d1
Enhance HTTPS support and documentation for credential issuer and ver…
Jul 9, 2026
19bc082
Fix issues with type brand usage
Jul 9, 2026
225624d
Add Agent Skills section to documentation
Jul 10, 2026
9a87faf
Phase 1 and 2 of DEMODULARIZE.md's plan
Jul 13, 2026
55501c4
Add overlaySignerIframe helper to ows-signer-utils
Jul 13, 2026
bbd72d0
Refactor backup flow to improve cancel button handling
Jul 13, 2026
b9831dd
Add SignHelper for EIP-1193 personal_sign and typed-data handling
Jul 13, 2026
9ec269f
Refactor examples and update shared module structure
Jul 13, 2026
34fc0a4
Remove debug code
Jul 13, 2026
c40df34
Remove deprecated `ows-branding-core` and `ows-registry` packages, up…
Jul 13, 2026
7a64996
Refactor general wallet example to use Vite and React
Jul 13, 2026
0a220f4
Refactor examples to use Vite for improved development experience
Jul 13, 2026
7e9d808
Enhance general wallet and host examples with strict port configurati…
Jul 13, 2026
dc6753f
Merge pull request #1 from 1Shot-API/feature/IdentityProvisions
Jul 13, 2026
3c8b506
Implement OID4VCI proof-of-possession and enhance credential verifica…
Jul 13, 2026
89e40a9
Enhance credential management and signing layer integration
Jul 14, 2026
55f9a22
Implement AES-256-GCM encryption and decryption in the Signing Layer
Jul 14, 2026
c8c8ac9
Fix two issues from code review
Jul 14, 2026
a78bba8
Update credential issuer and verifier examples with OID4VCI integration
Jul 14, 2026
a7bc456
Merge pull request #2 from 1Shot-API/feature/Demodularize
Jul 14, 2026
9e5d594
Update the skill
Jul 14, 2026
0dfa659
Fix issue with deleted credentials vs. revoked
Jul 14, 2026
9e18f3e
Version Packages
Jul 15, 2026
a8656c1
Merge pull request #3 from 1Shot-API/feature/FinishCredentials
csibbach Jul 15, 2026
c50fcaa
Fix skill
Jul 15, 2026
58ef5d1
Add presentation mode for branding iframe in ows-provider
Jul 15, 2026
21c757e
Version and release the ows-provider package
Jul 15, 2026
afc99f3
Refactor public key handling to use COSE format
Jul 16, 2026
348265a
Bump versions and publish
Jul 16, 2026
da34865
Merge pull request #4 from 1Shot-API/feature/DisplayLogicUpdates
csibbach Jul 16, 2026
fd48ab0
Enhance branding iframe configuration and ensure credential readiness
Jul 16, 2026
5e1b42f
Enhance transaction handling and UI for USDC operations
Jul 17, 2026
7490ef6
Fix stream handling in dev server
Jul 17, 2026
7a36ac7
Merge pull request #5 from 1Shot-API/feature/SendTransaction
csibbach Jul 17, 2026
7f2c3ce
Fix issue with missing files and 404 handling.
Jul 17, 2026
8fa33e0
Enhance modal components with improved overflow handling
Jul 17, 2026
498d823
Add EChainTechnology and RelayerTransactionId; refactor transaction a…
Jul 21, 2026
0bc6063
Publish new versions
Jul 21, 2026
a15690e
Implement one-shot access token deletion in oid4vci-plugin and enhanc…
Jul 21, 2026
ca64262
Refactor signature handling for EVM compatibility and enhance tests
Jul 23, 2026
8629a36
Release new versions
Jul 23, 2026
6856913
Enhance signature handling in `signedAuthorizationFromSignature` for …
Jul 23, 2026
fefb84f
Version ows-signer-utils
Jul 23, 2026
ae79e0f
Enhance signing functionality with batch processing support
Jul 23, 2026
ce9ae69
Add react-doctor
Jul 23, 2026
9cd2def
Update general wallet configuration and enhance modal components
Jul 23, 2026
49f85de
Refactor text formatting and improve accessibility in wallet components
Jul 23, 2026
a39b7b2
Implement Signing Layer ceremony UI and enhance modal components
Jul 24, 2026
2f2a186
Enhance `toViemLocalAccount` function and update OWSSigner key handling
Jul 24, 2026
ab46c16
Version packages
Jul 24, 2026
91c4315
Merge pull request #6 from 1Shot-API/feature/BatchSigning
csibbach Jul 24, 2026
08133a8
Implement revealPrivateKey functionality to keep the ceremony panel o…
Jul 25, 2026
795685a
Publish new packages
Jul 25, 2026
09d93bb
Add `importPrivateKey` functionality to the Signing Layer
Jul 26, 2026
21e1a52
Release version bump
Jul 26, 2026
9d0836e
Enhance signing modals and approval handling
Jul 27, 2026
4e7a624
Version package
Jul 27, 2026
11da6b4
Enhance CreateBackupModal with error handling and rejection support
Jul 27, 2026
55769c0
Merge pull request #7 from 1Shot-API/feature/ExportPrivateKeyFixes
csibbach Jul 27, 2026
eafc2c5
Add clearSession method to OWSSigner for managing session state
Jul 27, 2026
ce5535c
Enhance credential creation process with updated ceremony UI
Jul 28, 2026
25d264c
Release new versions of signer and signer utils
Jul 28, 2026
74ed4f0
Refactor signing modals to improve cancellation handling
Jul 28, 2026
ce874c1
Fix react-doctor hook
Jul 28, 2026
c8fd466
Allow for deferred key derivation so that we avoid extra passkey cere…
Jul 28, 2026
e4b97e9
Refactor credential ID handling across signer utilities
Jul 28, 2026
49d46b2
Version packages
Jul 28, 2026
d4e23a5
Refactor react-doctor hook to streamline event name handling
Jul 28, 2026
c0bf1ce
Enhance react-doctor hook to improve tool name handling
Jul 28, 2026
2f6bb67
Implement flyout and drawer display modes for wallet panel
Jul 28, 2026
465d4b9
Version packages and release
Jul 28, 2026
46f6735
Update package lock
Jul 28, 2026
28dc576
Refine flyout and drawer display logic for wallet panel
Jul 28, 2026
1594e67
Version with bug fixes
Jul 28, 2026
fc337a5
Fix examples
Jul 28, 2026
92767d0
Merge pull request #9 from 1Shot-API/feature/StylingFixes
csibbach Jul 28, 2026
cef51ad
Merge pull request #8 from 1Shot-API/feature/InitialCreationStreamline
csibbach Jul 28, 2026
8158bf8
Add signer.css for styling and update README with CSP details
Jul 29, 2026
75b2be5
Enhance signer.css for improved UI styling
Jul 29, 2026
4a88894
Refine react-doctor hook's tool name scanning logic
Jul 29, 2026
ee8dcf7
Add EIP-7715 execution permissions and RpcHelper hooks
Jul 30, 2026
88d12ac
Version and publish packages. Remove double type wrap of EVMTransacti…
Jul 30, 2026
ca3e889
Update version to 0.3.1 and add new branded primitives
Jul 30, 2026
8853ae0
Add path resolution utility for environment variables in host-dev exa…
Jul 30, 2026
09afc87
Add analytics support for Branding→Host communication
Jul 30, 2026
895efe0
Add analytics events for account creation and personal signing
Jul 30, 2026
ec4a1c1
Version and publish packages
Jul 30, 2026
b6d539d
Merge pull request #10 from 1Shot-API/feature/Analytics
csibbach Jul 31, 2026
f0eff1f
Release focus from the wallet iframe before collapsing it and mark th…
Aug 4, 2026
892a1ab
Update version to 0.4.1 and release focus from the wallet iframe befo…
Aug 4, 2026
bff1e80
Merge pull request #11 from 1Shot-API/feature/FixAriaWarning
csibbach Aug 4, 2026
e3b3146
Lock some packages to avoid supply-chain attack
Aug 4, 2026
b7f6fb7
Merge branch 'develop' of https://github.com/1Shot-API/prf-wallet int…
Aug 4, 2026
a8af65f
Refactor WebAuthn assertion handling
Aug 7, 2026
df9c4b7
Create changeset, move validation of assertion to ows layer.
Aug 7, 2026
c3d5c34
Enhance WebAuthn assertion handling in OWSSigner
Aug 7, 2026
5ab28b0
Version packages and publish
Aug 7, 2026
afc52a8
Merge pull request #12 from 1Shot-API/feature/AssertionExpansion
csibbach Aug 7, 2026
36fa253
Implement EIP-1193 event handling in wallet provider
Aug 7, 2026
40a2065
Version packages and publish
Aug 7, 2026
8f4b8ee
Fix compile error
Aug 7, 2026
ebc03aa
Refactor CredentialsHelper to align with SignHelper branding ownershi…
Aug 8, 2026
6eb1116
Version packages and publish
Aug 8, 2026
2ae0037
Refactor encryption key handling in oid4vp-plugin and update clearWal…
Aug 8, 2026
c3a08b1
Merge pull request #13 from 1Shot-API/feature/CredentialsRefactor
csibbach Aug 8, 2026
b011db3
Enhance display session handling in host and child client
Aug 11, 2026
99a3850
Implement ceremony cancellation and error handling improvements
Aug 12, 2026
fc0cc7e
Changelog and version packages
Aug 12, 2026
ac55486
Enhance debugging capabilities in WebAuthn and UI components
Aug 13, 2026
3d52a82
Update README and constants for PRF labels clarification
Aug 19, 2026
629316f
Version and publish
Aug 19, 2026
7edbcbf
Refactor Modal component and enhance wallet session handling
Aug 19, 2026
e790358
Merge pull request #14 from 1Shot-API/feature/Ed25519ReoveryFix
csibbach Aug 19, 2026
3255b83
Add legal terms and update licence
Aug 28, 2026
498c055
Merge pull request #15 from 1Shot-API/feature/LegalStuff
csibbach Aug 28, 2026
4c9757f
Add addressToBytes32Hex utility function for EVM address conversion
Sep 4, 2026
89b446c
New ows-types version
Sep 4, 2026
b5b3ba3
Merge pull request #16 from 1Shot-API/feature/NewConversionUtils
csibbach Sep 4, 2026
728eb8d
Add Bitcoin Native SegWit support and refactor OWSProxy
Sep 5, 2026
3dd75f0
Released new packages.
Sep 5, 2026
f1129df
Merge pull request #17 from 1Shot-API/feature/Bitcoin
csibbach Sep 5, 2026
042beab
Update package versions and enhance Bitcoin chain ID handling
Sep 7, 2026
e432a66
Version packages
Sep 7, 2026
68ecbc2
Merge pull request #18 from 1Shot-API/feature/FixNobleImport
csibbach Sep 7, 2026
02b6de2
extend EIP7715 caveats
TtheBC01 Sep 22, 2026
d3ea587
npm run version-packages
TtheBC01 Sep 22, 2026
5abb2ab
Merge pull request #19 from 1Shot-API/feature/ScopedDelegations
csibbach Sep 22, 2026
3c96fc4
added node to devDependencies and tsconfigs
TtheBC01 Sep 22, 2026
06dc6ee
Merge pull request #20 from 1Shot-API/bug/compilertypes
csibbach Sep 22, 2026
61ea18f
Implement flyout retention fix and enhance session management
Sep 22, 2026
eefd18c
Version packages and publish
Sep 23, 2026
0ab711a
Merge pull request #21 from 1Shot-API/feature/BugFixesForSessionReten…
csibbach Sep 23, 2026
ccbff31
Update version to 0.6.4 and enhance eth_sendTransaction flow
Sep 23, 2026
8b37a22
Merge pull request #22 from 1Shot-API/feature/FixSignHelper
csibbach Sep 23, 2026
6cd2357
Add ChainUtils.asEVMChainId for EIP-155 chain ID normalization
Sep 24, 2026
855277f
Update versions and enhance EIP-155 chain ID normalization
Sep 24, 2026
737de5a
Merge pull request #23 from 1Shot-API/feature/ChainIdNormalization
csibbach Sep 24, 2026
b512d0c
Update version to 0.6.6 and fix address caching issues
Sep 26, 2026
a857039
Merge pull request #24 from 1Shot-API/feature/StaleState
csibbach Sep 26, 2026
346c5d8
Passkey ceremony uses a bottom sheet and transparent host strip.
TtheBC01 Oct 2, 2026
5387c6c
Size ceremony host strip to 50dvh and tune sheet spacing.
TtheBC01 Oct 2, 2026
b66fccf
Merge pull request #25 from 1Shot-API/feature/signerUIPanel
TtheBC01 Oct 2, 2026
e0a117b
Update agent skills documentation and installation instructions
Oct 6, 2026
823928d
Merge pull request #26 from 1Shot-API/feature/SkillCentralization
csibbach Oct 7, 2026
88a9f66
Removed tiemouts for RPC calls since users may take a long time.
Oct 20, 2026
d2cc549
Versioned and published packages
Oct 20, 2026
37b5e85
Merge pull request #27 from 1Shot-API/feature/RPCTimeouts
csibbach Oct 20, 2026
972fd3b
Implement Solana Phase 1 features including CAIP-2 `SolanaChainId`, b…
Oct 21, 2026
7068087
Release new packages
Oct 21, 2026
17fe471
Solana phase 2
Oct 21, 2026
1769bcf
Missed files from last commit
Oct 21, 2026
7fb0d6f
Add support for Solana chain to example host
Oct 21, 2026
7b131e8
Add SolanaATAAddress type and utils
Oct 22, 2026
1780b1a
Refactor Solana transaction types
Oct 22, 2026
eaf3e6e
Apply changeset and publish
Oct 22, 2026
77483b5
Merge pull request #29 from 1Shot-API/feature/Solana
csibbach Oct 22, 2026
32edcec
wallet-utils were not published
Oct 22, 2026
1aa1322
Merge pull request #30 from 1Shot-API/feature/PublishNewWalletUtils
csibbach Oct 22, 2026
ec08739
Performed a Cloudflare Security Audit on the Signer and it's interact…
Oct 23, 2026
f7ae673
Fix code review bugs and version packages for publishing
Oct 23, 2026
e47b380
More code review fixes
Oct 23, 2026
b0bcd1c
Merge pull request #31 from 1Shot-API/feature/SecurityAudit
csibbach Oct 23, 2026
b20bd83
Allow private-key reveal after the passkey sheet blurs the signer ifr…
TtheBC01 Nov 5, 2026
fd05aad
Version packages after testing fix
Nov 5, 2026
b2f5603
Merge pull request #32 from 1Shot-API/bugfix/Export
csibbach Nov 5, 2026
77dce56
Show private-key import as the ceremony sheet.
TtheBC01 Nov 5, 2026
99784eb
Add a patch changeset for the private-key import sheet.
TtheBC01 Nov 5, 2026
86bbf46
Version @1shotapi/ows-signer to 0.4.6.
TtheBC01 Nov 5, 2026
b11f8ec
Merge pull request #33 from 1Shot-API/bugfix/Import
csibbach Nov 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
56 changes: 56 additions & 0 deletions .agents/skills/react-doctor/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
name: react-doctor
description: Use when finishing a feature, fixing a bug, before committing React code, or when the user types `/doctor`, asks to scan, triage, or clean up React diagnostics. Covers lint, accessibility, bundle size, architecture. Includes a regression check and a full local-triage workflow that fetches the canonical playbook.
version: "1.2.0"
---

# React Doctor

Scans React codebases for security, performance, correctness, and architecture issues. Outputs a 0–100 health score.

## After making React code changes:

Run `npx react-doctor@latest --verbose --scope changed` and check the score did not regress.

If the score dropped, fix the regressions before committing.

## For general cleanup or code improvement:

Run `npx react-doctor@latest --verbose` (the default `--scope full`) to scan the full codebase. Fix issues by severity — errors first, then warnings.

## For a focused UI design audit:

Run `npx react-doctor@latest design --verbose`. This selects only design-tagged UI composition, typography, interaction, accessibility, and motion rules, including focused rules that remain opt-in during a general health scan.

## /doctor — full local triage workflow

When the user types `/doctor`, says "run react doctor", or asks for a full triage / cleanup pass (not just a regression check), fetch the canonical local-triage playbook and follow every step in it:

```bash
curl --fail --silent --show-error \
--header 'Cache-Control: no-cache' \
https://www.react.doctor/prompts/react-doctor-agent.md
```

The playbook is the single source of truth — a scan → filter → triage → fix → validate loop that edits the working tree directly (never commits, never opens PRs). Updating the prompt at its source updates every agent on its next fetch — no skill reinstall needed.

Pair it with the matching per-rule prompts at `https://www.react.doctor/prompts/rules/<plugin>/<rule>.md` (fetched on demand inside the playbook) so each fix uses the canonical, reviewer-tested recipe.

## Configuring or explaining rules

When the user wants to understand a rule, disagrees with one, or wants to disable / tune which rules run (not fix code), read [references/explain.md](references/explain.md) and follow it. Start with `npx react-doctor@latest rules explain <rule>`, then apply the narrowest control via `npx react-doctor@latest rules disable|set|category|ignore-tag …`, which edits your `doctor.config.*` (or `package.json#reactDoctor`).

## Command

```bash
npx react-doctor@latest --verbose --scope changed
```

| Flag | Purpose |
| ----------------- | ---------------------------------------------------------------- |
| `.` | Scan current directory |
| `--verbose` | Show affected files and line numbers per rule |
| `--scope changed` | Only report issues introduced vs the base branch (default: full) |
| `--scope lines` | Only report issues on the changed lines |
| `--score` | Output only the numeric score |
| `design` | Run only the focused UI design diagnostics |
73 changes: 73 additions & 0 deletions .agents/skills/react-doctor/references/explain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Explaining and configuring rules

Explain React Doctor rules and edit `doctor.config.*` safely. Use this when a user
wants to understand a rule or change which rules run — not for fixing diagnostics
(that is the main `react-doctor` skill / `/doctor`).

Triggers: "why did this rule fire", "I disagree with this rule", "turn this rule off",
"stop flagging X", "too noisy", "disable design rules".

## Workflow

1. Identify the rule key from the diagnostic (e.g. `react-doctor/no-array-index-as-key`).
2. Explain it before changing anything:

```bash
npx react-doctor@latest rules explain react-doctor/no-array-index-as-key
```

3. Pick the narrowest control that matches the user's intent (see decision guide).
4. Apply it with a `rules` subcommand (edits your `doctor.config.*` or `package.json#reactDoctor` in place, preserving other fields and formatting).
5. Validate the change did what they wanted:

```bash
npx react-doctor@latest --verbose --diff
```

## Commands

```bash
npx react-doctor@latest rules list # every rule + its effective severity
npx react-doctor@latest rules list --configured # only what your config changed
npx react-doctor@latest rules list --category Performance # filter by category
npx react-doctor@latest rules explain <rule> # why it matters + how to configure
npx react-doctor@latest rules disable <rule> # rule never runs
npx react-doctor@latest rules enable <rule> # turn back on at its recommended severity
npx react-doctor@latest rules set <rule> warn # off | warn | error
npx react-doctor@latest rules category "React Native" off # whole category
npx react-doctor@latest rules ignore-tag design # skip a rule family (design, test-noise, …)
npx react-doctor@latest rules unignore-tag design
```

Rule references accept the full key (`react-doctor/no-danger`), the bare id (`no-danger`), or a legacy key (`react/no-danger`).

## Decision guide

Match the control to the intent — prefer the narrowest one:

- **User disagrees with one rule / it's a false positive for them** → `rules disable <rule>` (sets `rules.<key> = "off"`; the rule stops running everywhere). This is the default for "I don't want this rule".
- **Rule is fine but wrong severity** → `rules set <rule> warn` or `rules set <rule> error`.
- **A disabled-by-default rule they want on** → `rules enable <rule>`.
- **A whole area is unwanted** (e.g. all React Native rules) → `rules category "<Category>" off`.
- **A behavioral family is noisy** (`design`, `test-noise`, `migration-hint`) → `rules ignore-tag <tag>`.
- **Keep it locally but hide from PR comment / score / CI gate only** → do NOT disable. Edit `surfaces` in your config (`surfaces.prComment.excludeRules`, `surfaces.score.excludeTags`, `surfaces.ciFailure.excludeCategories`). The rule still shows in local `cli` output.
- **Restore test or story findings to production health** → set `surfaces.score.includeFileContexts` or `surfaces.ciFailure.includeFileContexts` to `["test"]`, `["story"]`, or both. Other surface exclusions still apply.

How the layers combine: `ignore.tags` disables every rule carrying that tag **before** linting, so a tagged rule stays off even if `rules`/`categories` set it to `warn`/`error` (a rule-level override cannot re-enable a tag-ignored rule). For rules that aren't tag-disabled, `rules` overrides `categories` overrides the rule's default. `surfaces` is visibility-only and never changes whether a rule runs.

## Config shape

Config lives in `doctor.config.ts` (or `.js`/`.mjs`/`.cjs`/`.json`/`.jsonc`), or the `reactDoctor` key in `package.json`. The `rules` commands edit whichever exists — TS/JS edits preserve formatting (via magicast) — and create `doctor.config.json` when none does, stamping `$schema`:

```ts
// doctor.config.ts
export default {
rules: { "react-doctor/no-array-index-as-key": "off" },
categories: { "React Native": "warn" },
ignore: { tags: ["design"] },
};
```

## Educating the user

When explaining a rule, lead with the "Why it matters" guidance from `rules explain` and, when they want depth, the per-rule recipe at `https://www.react.doctor/prompts/rules/<plugin>/<rule>.md`. Only after they understand it should you offer to disable it — many "bad" rules are catching real issues.
5 changes: 5 additions & 0 deletions .changeset/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Changesets

OWS publishable packages (`@1shotapi/ows-*`) are versioned independently via [Changesets](https://github.com/changesets/changesets).

Example apps are excluded. Maintainers: `npm run changeset` → `npm run version-packages` → `npm run release`.
17 changes: 17 additions & 0 deletions .changeset/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": [
"@1shotapi/ows-onchain",
"@1shotapi/ows-example-general-wallet",
"@1shotapi/ows-example-host",
"@1shotapi/ows-example-credential-issuer",
"@1shotapi/ows-example-credential-verifier"
]
}
12 changes: 12 additions & 0 deletions .cursor/hooks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": 1,
"hooks": {
"postToolUse": [
{
"command": "node .cursor/hooks/react-doctor.mjs",
"matcher": "Write|Edit|MultiEdit|ApplyPatch",
"timeout": 120
}
]
}
}
153 changes: 153 additions & 0 deletions .cursor/hooks/react-doctor.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import { existsSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { spawnSync } from 'node:child_process';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

// --verbose scans on large diffs can exceed spawnSync's 1 MiB default.
const SPAWN_MAX_BUFFER_BYTES = 16 * 1024 * 1024;

const EDIT_TOOL_NAMES = new Set(['Edit', 'Write', 'MultiEdit', 'NotebookEdit', 'ApplyPatch']);

const readFileOrEmpty = (filePath) => {
try {
return readFileSync(filePath, 'utf8');
} catch {
return '';
}
};

/**
* Consume hook JSON from stdin without `readFileSync(0)`, which blocks until
* EOF and can hang the hook when stdin is not a ready pipe.
*/
const readStdin = async () => {
if (process.stdin.isTTY) {
return '';
}
const chunks = [];
for await (const chunk of process.stdin) {
chunks.push(chunk);
}
return Buffer.concat(chunks).toString('utf8');
};

const hookEventName = (input) =>
input.hook_event_name || input.eventName || input.event_name;

const shouldScan = (input) => {
const eventName = hookEventName(input);
if (eventName === 'PostToolBatch') {
const toolCalls = Array.isArray(input.tool_calls) ? input.tool_calls : [];
return toolCalls.some((toolCall) => EDIT_TOOL_NAMES.has(toolCall.tool_name));
}
const toolName = input.tool_name || input.toolName || input.tool;
// hooks.json matcher already limits invocation. If the payload omits toolName,
// scan conservatively rather than silently skipping. If toolName is present
// but not an edit tool, skip.
if (toolName == null || toolName === '') {
return true;
}
return EDIT_TOOL_NAMES.has(toolName);
};

const runReactDoctor = (outputPath) => {
// Each candidate is a single shell command string (not an args array):
// `shell: true` is required to run the Windows `.cmd` shims, and an args
// array with `shell: true` trips Node's DEP0190. A missing command exits
// 127 via a POSIX shell (no ENOENT error) and 9009 via cmd.exe, so fall
// through on those. The local bin is probed with existsSync (its `./`
// prefix form is not runnable by cmd.exe at all). Returns `null` when no
// runner is available (distinct from exit 0 = clean scan).
const localBin = process.platform === 'win32'
? 'node_modules\\.bin\\react-doctor.cmd'
: './node_modules/.bin/react-doctor';
const commands = [
...(existsSync(localBin)
? [localBin + ' --verbose --scope changed --blocking warning --no-score']
: []),
'react-doctor --verbose --scope changed --blocking warning --no-score',
'pnpm dlx react-doctor@latest --verbose --scope changed --blocking warning --no-score',
'npx --yes react-doctor@latest --verbose --scope changed --blocking warning --no-score',
];

for (const command of commands) {
const result = spawnSync(command, { encoding: 'utf8', shell: true, maxBuffer: SPAWN_MAX_BUFFER_BYTES });
if (result.error?.code === 'ENOENT' || result.status === 127 || result.status === 9009) continue;
try {
writeFileSync(outputPath, (result.stdout || '') + (result.stderr || ''));
} catch {}
return result.status ?? 1;
}

return null;
};

const cleanup = (...paths) => {
for (const path of paths) {
try { unlinkSync(path); } catch {}
}
};

const fail = (error) => {
const message = error instanceof Error ? (error.stack ?? error.message) : String(error);
// stderr only — stdout is reserved for hook JSON the agent parses.
console.error(`[react-doctor hook] ${message}`);
process.exit(1);
};

const main = async () => {
let input;
try {
input = JSON.parse((await readStdin()) || '{}');
} catch (error) {
fail(error instanceof Error ? error : new Error(`invalid hook stdin JSON: ${String(error)}`));
}

if (!shouldScan(input)) {
process.exit(0);
}

const projectRoot = process.env.CLAUDE_PROJECT_DIR || join(__dirname, '../..');
const outputPath = join(tmpdir(), `react-doctor-agent-hook-output-${process.pid}.txt`);

try {
process.chdir(projectRoot);
} catch (error) {
fail(error);
}

const scanResult = runReactDoctor(outputPath);
if (scanResult === null) {
// Soft skip: do not block the agent, but do not pretend a clean scan ran.
cleanup(outputPath);
console.error('[react-doctor hook] react-doctor not found; skipping scan');
process.exit(0);
}
if (scanResult === 0) {
cleanup(outputPath);
process.exit(0);
}

// Scan findings are reported via stdout JSON below. Missing scan output
// (e.g. unwritable tmpdir) is a soft skip — not a hook runtime failure.
const scanOutput = readFileOrEmpty(outputPath).trim();
cleanup(outputPath);

if (!scanOutput) {
process.exit(0);
}

const message = `React Doctor found issues in the changed files. Review this output and fix the regressions before finishing. For confirmed issues that cannot be fixed now, create GitHub issues with the rule, file/line, confidence, impact, and proposed fix.\n\n${scanOutput}`;

if (hookEventName(input) === 'PostToolBatch') {
console.log(JSON.stringify({ hookSpecificOutput: { hookEventName: 'PostToolBatch', additionalContext: message } }));
} else {
console.log(JSON.stringify({ additional_context: message }));
}
};

main().catch(fail);
15 changes: 15 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 2
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false

[*.sol]
indent_size = 4
26 changes: 26 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Repo root — copy to .env (gitignored)

# ngrok authtoken for `npm run dev:general-wallet`
# https://dashboard.ngrok.com/get-started/your-authtoken
NGROK_AUTHTOKEN=

# Optional: reserved ngrok domain (stable URL instead of random subdomain)
# Find yours at https://dashboard.ngrok.com/domains — e.g. immune-sheep-light.ngrok-free.app
NGROK_DOMAIN=

# Optional: full Branding Layer iframe URL for host / credential-issuer / credential-verifier.
# Overrides NGROK_DOMAIN and the localhost default — useful when testing another wallet repo.
# Example: WALLET_IFRAME_URL=https://immune-sheep-light.ngrok-free.app/wallet/
# WALLET_IFRAME_URL=

# Optional: HTTPS for Host Layer examples (host, credential-issuer, credential-verifier).
# Required when embedding HTTPS wallet iframes for passkeys (secure-context ancestor chain).
# If examples/host/certs/dev-*.pem exist, HTTPS is enabled for all three automatically.
# HOST_HTTPS=1
# HOST_SSL_CERT=examples/host/certs/dev-cert.pem
# HOST_SSL_KEY=examples/host/certs/dev-key.pem
# Generate: mkcert -install && mkcert -cert-file examples/host/certs/dev-cert.pem -key-file examples/host/certs/dev-key.pem ows-host.com ows-issuer.com ows-verifier.com localhost 127.0.0.1

# Optional: public origins for credential demos (defaults shown)
# ISSUER_ORIGIN=https://ows-issuer.com:5175
# VERIFIER_ORIGIN=https://ows-verifier.com:5176
27 changes: 27 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: npm

- name: Install
run: npm ci

- name: Build
run: npm run build

- name: Test
run: npm test
Loading
Loading