From 1e9370e53aeb793450fcbe8382293f1f93189bd6 Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 17:01:37 -0400 Subject: [PATCH 01/27] refactor: remove unused compiler options from tsconfig files --- tsconfig.json | 5 +---- tsconfig.lint.json | 3 +-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index 8be0206..3e1a69d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,10 +5,7 @@ "moduleResolution": "bundler", "strict": true, "skipLibCheck": true, - "resolveJsonModule": true, - "esModuleInterop": true, - "isolatedModules": true, - "sourceMap": true, + "verbatimModuleSyntax": true, "noEmit": true }, "include": ["src"], diff --git a/tsconfig.lint.json b/tsconfig.lint.json index 7ce2f43..8f77925 100644 --- a/tsconfig.lint.json +++ b/tsconfig.lint.json @@ -1,8 +1,7 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "noEmit": true, - "moduleResolution": "node" + "noEmit": true }, "include": ["src", "scripts"] } From 8432a30d7d5488dd880cdd6305332cc13264dada Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 17:25:33 -0400 Subject: [PATCH 02/27] docs: update CLI specification with ADR reference and add pull request template --- .github/pull_request_template.md | 8 + docs/adrs/002.cli.start-stop.md | 151 ++++++++++++++ .../003.release-process.semantic-release.md | 130 ++++++++++++ docs/specs/cli.md | 2 +- docs/specs/release-process.md | 186 ++++++++++++++++++ 5 files changed, 476 insertions(+), 1 deletion(-) create mode 100644 .github/pull_request_template.md create mode 100644 docs/adrs/002.cli.start-stop.md create mode 100644 docs/adrs/003.release-process.semantic-release.md create mode 100644 docs/specs/release-process.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..6cd229d --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,8 @@ +## Description + + + +## ADRs + + +- diff --git a/docs/adrs/002.cli.start-stop.md b/docs/adrs/002.cli.start-stop.md new file mode 100644 index 0000000..dc0cffc --- /dev/null +++ b/docs/adrs/002.cli.start-stop.md @@ -0,0 +1,151 @@ +# ADR 002: CLI — `wtty start` / `wtty stop` + +**SPEC:** [cli](../specs/cli.md) +**Status:** Proposed +**Date:** 2026-03-21 + +--- + +## Context + +wtty currently has one entry point: `src/server.ts`, run directly via `bun run src/server.ts` or `tsx src/server.ts`. There is no CLI, no daemon mode, and no way to stop the server other than `Ctrl-C` in the terminal that started it. + +The goal for this slice is `npx wtty start` / `npx wtty stop` — the minimal lifecycle commands. `start` forks the server as a background daemon and exits. `stop` terminates that daemon. + +Two sub-questions drive this ADR: + +1. **How does `start` fork a background process?** Node.js `child_process.spawn` with `detached: true` + `stdio: 'ignore'` + `unref()` — the parent exits, the child keeps running. +2. **How does `stop` terminate the server?** `POST /api/server/stop` — the server handles its own shutdown. No PID file, no signals, works identically on Mac, Linux, and Windows. + +## Decision + +Add a CLI entry point (`src/cli.ts`) and a `POST /api/server/stop` endpoint to `src/server.ts`. No new runtime dependencies — Commander.js is deferred until there are enough subcommands to justify it. + +**`wtty start`**: +- Spawns `dist/server.js` with `detached: true`, `stdio: 'ignore'`, `unref()`. +- Waits briefly for the server to be ready (polls `GET /api/server/stop` or a short fixed delay). +- Prints `wtty started` and exits. + +**`wtty stop`**: +- Sends `POST http://localhost:PORT/api/server/stop`. +- If the request succeeds: prints `wtty stopped`. +- If the request fails (connection refused): prints `wtty is not running`. + +**`server.ts` change**: Add `POST /api/server/stop` — kills all PTY sessions, closes the WebSocket server, and calls `process.exit(0)`. The server owns its own shutdown on all platforms. + +## Considered Options + +### Option A: HTTP stop endpoint (chosen) + +`wtty stop` sends `POST /api/server/stop`. Server cleans up and exits itself. + +- **Pros**: Fully cross-platform — no signals, no PID file. Server owns its cleanup. Connection refused = not running, no separate state to track. Consistent with the existing HTTP surface of the server. +- **Cons**: Requires the server to be responsive. If the server is hung, HTTP stop won't work — acceptable as a degraded edge case; a hard `kill` fallback can be added later if needed. + +### Option B: PID file + SIGTERM + +Write the server PID to `~/.wtty/server.pid`. `stop` reads it and sends `SIGTERM`. + +- **Pros**: Works without an HTTP round-trip. PID file is human-readable. +- **Cons**: SIGTERM on Windows calls `TerminateProcess()` — hard kill, server cleanup handler never runs. Stale PID files if the server crashes. Requires PID file management in both the CLI and server. More state to track. + +### Option C: Commander.js from the start + +Add Commander.js now and model `start`/`stop` as commands. + +- **Pros**: Consistent with the CLI spec's stated direction. Auto-generates `--help`. +- **Cons**: Adds a dependency for two `if` branches. Commander.js is justified when there are multiple subcommands with options — for this slice it's overhead. Deferred to the session management slice. + +### Option D: Shell script wrapper + +A `wtty.sh` that does `node dist/server.js &`. + +- **Pros**: Trivial. +- **Cons**: Platform-specific (no Windows). Doesn't compose with `npx`. + +## Consequences + +**Good**: `npx wtty start` works from any directory. Daemon runs in background, terminal is free. `npx wtty stop` works identically on Mac, Linux, and Windows — no signals, no PID files, no platform-specific code. Server owns its cleanup. No new runtime dependencies. + +**Bad**: If the server is hung, `wtty stop` fails silently — acceptable for this slice; hard-kill fallback deferred. Port is hardcoded at 2346 — will become configurable when the config file slice lands. + +## Implementation Notes + +### `package.json` changes + +```json +{ + "bin": { + "wtty": "./dist/cli.js" + } +} +``` + +Add `src/cli.ts` as a second build entrypoint alongside `src/server.ts`. + +### File layout + +``` +src/ + cli.ts ← new: wtty start / wtty stop + server.ts ← add: POST /api/server/stop endpoint +``` + +### `src/cli.ts` sketch + +```ts +const command = process.argv[2]; +const BASE_URL = `http://localhost:${PORT}`; + +if (command === 'start') { + const child = spawn(process.execPath, [serverEntry], { + detached: true, + stdio: 'ignore', + }); + child.unref(); + console.log('wtty started'); +} else if (command === 'stop') { + try { + await fetch(`${BASE_URL}/api/server/stop`, { method: 'POST' }); + console.log('wtty stopped'); + } catch { + console.log('wtty is not running'); + } +} else { + console.error('Usage: wtty start | wtty stop'); + process.exit(1); +} +``` + +### `POST /api/server/stop` in `server.ts` + +```ts +if (req.method === 'POST' && pathname === '/api/server/stop') { + res.writeHead(200); + res.end('stopping'); + for (const [ws, session] of sessions.entries()) { + session.pty.kill(); + ws.close(); + } + wss.close(); + httpServer.close(() => process.exit(0)); + return; +} +``` + +### Daemon spawn + +```ts +const child = spawn(process.execPath, [serverEntry], { + detached: true, + stdio: 'ignore', +}); +child.unref(); +``` + +`process.execPath` is the Node.js or Bun binary that launched the CLI — ensures the server runs under the same runtime. + +## Related Decisions + +- [ADR 001 — Bootstrap](001.wtty.bootstrap.md): `src/server.ts` is the server entry point extended by this ADR +- [ADR 003 — Release Process](003.release-process.semantic-release.md): CLI entry point is part of the binary artifact built and released diff --git a/docs/adrs/003.release-process.semantic-release.md b/docs/adrs/003.release-process.semantic-release.md new file mode 100644 index 0000000..41dd3d6 --- /dev/null +++ b/docs/adrs/003.release-process.semantic-release.md @@ -0,0 +1,130 @@ +# ADR 003: Release Process — semantic-release on GitHub + +**SPEC:** [release-process](../specs/release-process.md) +**Status:** Proposed +**Date:** 2026-03-21 + +--- + +## Context + +wtty has a stub release workflow (`.github/workflows/release.yml`) that runs `bun run build` then `echo "TODO - publish step"`. No versioning, no published artifacts. + +wtty is distributed as a standalone binary — not published to npm (`"private": true`). A release means a GitHub Release with platform-specific binary artifacts attached. The version should be derived automatically from what changed, not set manually. + +The cfx repo solved the same versioning problem with semantic-release (ADR 004): conventional commit prefixes in PR/MR titles drive version bumps post-merge, git tags are the sole version record, no release commits. That pattern maps cleanly to wtty with one difference: instead of `@semantic-release/npm`, the publish step is `@semantic-release/github` with binary assets. + +## Decision + +Use **semantic-release** with `@semantic-release/github`, running post-merge on `main`. Developers write a conventional commit prefix in the PR title. GitHub squash merge uses the PR title as the commit message on `main`. semantic-release reads that message, determines the version bump, creates a GitHub Release with release notes, and attaches pre-built binaries. No manual versioning, no release commits, no extra files per PR. + +## Considered Options + +### Option A: semantic-release post-merge on main, tag-only (chosen) + +- **Pros**: Zero developer overhead beyond PR title. GitHub Release + binary upload fully automated. Battle-tested. No version conflicts between concurrent PRs. No release commits — clean one-commit-per-PR history on `main`. No branch push permissions needed (only tag push). `GITHUB_TOKEN` is provided automatically — no secrets to configure. +- **Cons**: `package.json` version doesn't reflect the released version (use `0.0.0-development` placeholder). No in-repo `CHANGELOG.md` (release notes live on GitHub Releases). Requires conventional commit discipline in PR titles (mitigate: squash merge uses PR title — one line to get right). + +### Option B: Manual GitHub Release + +Create GitHub Releases manually — edit the release notes, attach binaries by hand, tag manually. + +- **Pros**: Full control over release notes. No tooling to configure. +- **Cons**: Manual — error-prone, inconsistent, easy to forget. Version tracking relies on human discipline. Doesn't scale. + +### Option C: release-it + +release-it (used in cfx ADR 006) supports GitHub releases natively and has a simpler config surface than semantic-release. + +- **Pros**: Simpler per-package config, base version frozen on prerelease. +- **Cons**: wtty has no prerelease channel need (the main reason cfx switched to release-it). semantic-release's automatic version derivation from commit type is the better fit here — release-it requires either a manual bump type or more config to replicate the same behavior. + +### Option D: Changesets + +- **Pros**: Human-written changelogs, 1 dependency. +- **Cons**: Extra file per PR, developer must run `npx changeset`, changeset summary duplicates PR title. Same reasons rejected in cfx ADR 004. + +## Consequences + +**Good**: Zero developer overhead — write a conventional PR title, everything else is automated. GitHub Release auto-created with release notes. Binary artifacts attached. Clean `main` history — one commit per PR, no interleaved release commits. `GITHUB_TOKEN` is automatic — no manual secret setup. Follows semantic-release's own recommended approach (tag-only, no commit-back). + +**Bad**: `package.json` version stays at `0.0.0-development` — doesn't reflect the released version. No `CHANGELOG.md` in repo (release notes on GitHub Releases). Requires conventional commit discipline in PR titles. + +## Implementation Notes + +### Plugin Chain + +```json +{ + "branches": ["main"], + "tagFormat": "v${version}", + "plugins": [ + "@semantic-release/commit-analyzer", + "@semantic-release/release-notes-generator", + ["@semantic-release/github", { "assets": ["dist/wtty-*"] }] + ] +} +``` + +`@semantic-release/commit-analyzer`, `@semantic-release/release-notes-generator`, and `@semantic-release/github` are all bundled with `semantic-release` — no additional plugin packages needed. `@semantic-release/git` and `@semantic-release/changelog` are intentionally omitted (tag-only). + +### Release Workflow + +```yaml +# .github/workflows/release.yml +on: + push: + branches: [main] +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + persist-credentials: false + - uses: oven-sh/setup-bun@v2 + with: + bun-version: 1.3.10 + - run: bun install --frozen-lockfile + - run: bun run build + - name: Build platform binaries + run: bun run build:binaries + - name: Release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: bunx semantic-release +``` + +- `fetch-depth: 0` — full clone so semantic-release can walk commit history to find previous tags +- `persist-credentials: false` — semantic-release manages its own git auth via `GITHUB_TOKEN` +- Binary build precedes the release step so assets exist before `@semantic-release/github` uploads them + +### Why Tag-Only (No Release Commits) + +semantic-release's own FAQ recommends against committing during release. Omitting `@semantic-release/git` and `@semantic-release/changelog`: + +- **No branch push permissions needed** — `GITHUB_TOKEN` only needs to push tags and create releases +- **Clean history** — one commit per PR, no interleaved `chore(release):` commits +- **No `[skip ci]` dance** — no recursive pipeline triggering +- **Fewer dependencies** — 1 devDependency (`semantic-release`) instead of 3+ + +### GitHub Repository Settings + +| Setting | Value | Why | +|---------|-------|-----| +| Squash merging | Enabled | PR title becomes the commit semantic-release reads | +| Workflow permissions | Read and write | `GITHUB_TOKEN` needs to push tags and create releases | + +### `package.json` Version Placeholder + +```json +{ "version": "0.0.0-development" } +``` + +Signals that the in-repo version is not the released version. semantic-release writes the real version to `package.json` in CI only (during the npm plugin step) — but since there's no `@semantic-release/npm` here, it's purely cosmetic. Git tags are the source of truth. + +## Related Decisions + +- [ADR 001 — Bootstrap](001.wtty.bootstrap.md): Established the build pipeline (`bun run build`) that the release workflow extends +- [ADR 002 — CLI start/stop](002.cli.start-stop.md): CLI entry point is the binary artifact built and released diff --git a/docs/specs/cli.md b/docs/specs/cli.md index 0c44a22..0dd4d58 100644 --- a/docs/specs/cli.md +++ b/docs/specs/cli.md @@ -21,5 +21,5 @@ The CLI communicates with the server exclusively over HTTP to localhost — no U | Feature | Description | ADR | Done? | |---------|-------------|-----|-------| -| Server lifecycle | `wtty start`, `wtty stop`, `wtty restart`, `wtty status` — daemon control via PID file + HTTP | — | ⬜ | +| Server lifecycle | `wtty start`, `wtty stop`, `wtty restart`, `wtty status` — daemon control via PID file + HTTP | [ADR 002](../adrs/002.cli.start-stop.md) | ⬜ | | Session management | `wtty session create/list/kill` — thin wrappers over the session REST API | — | ⬜ | diff --git a/docs/specs/release-process.md b/docs/specs/release-process.md new file mode 100644 index 0000000..d8d1b32 --- /dev/null +++ b/docs/specs/release-process.md @@ -0,0 +1,186 @@ +# Release Process + +**Last Updated**: 2026-03-21 + +## Overview + +Automated release pipeline for wtty using semantic-release. Conventional commit prefixes in PR titles drive version bumps post-merge to `main`. semantic-release determines the version, creates a GitHub Release with release notes, and uploads platform-specific binary artifacts. No manual versioning, no release commits, no extra files. Git tags are the sole version record. + +## Principles + +| # | Principle | Meaning | +|---|-----------|---------| +| 1 | Developers don't version | Merge to `main` with a conventional PR title — CI handles the rest. | +| 2 | Commit message is the changelog | PR title (squash merge commit message) is the changelog entry. No separate changeset files. | +| 3 | Git tags are the version record | `package.json` version stays at `0.0.0-development`. Tags are the source of truth. | +| 4 | Tag-only releases | No release commits pushed back to the repo. No `@semantic-release/git`. Clean one-commit-per-PR history. | +| 5 | Binary artifacts on every release | GitHub Release includes pre-built binaries for all supported platforms. | + +## Flow + +``` +PR Post-Merge (main) ++----------------------------+ +------------------------------------------+ +| lint, build, test | → | semantic-release | +| (PR check workflow) | squash | analyze commits → determine version bump | ++----------------------------+ | create GitHub Release + release notes | + | build & upload platform binaries | + +------------------------------------------+ +``` + +### Developer Workflow + +1. Open a PR to `main` with a conventional commit prefix in the title +2. Get review and approval +3. Squash merge — PR title becomes the single commit message on `main` +4. CI runs semantic-release post-merge: + - `fix:` → patch bump (`0.1.0` → `0.1.1`) + - `feat:` → minor bump (`0.1.0` → `0.2.0`) + - `feat!:` / `BREAKING CHANGE:` → major bump (`0.1.0` → `1.0.0`) + - `chore:`, `docs:`, `ci:` → no release +5. GitHub Release created with tag `v0.2.0` and binary artifacts attached + +### Conventional Commit Prefixes + +| Prefix | Bump | Example | +|--------|------|---------| +| `fix:` | Patch (0.0.x) | `fix: handle PTY exit on Windows` | +| `feat:` | Minor (0.x.0) | `feat: add config file support` | +| `feat!:` / `BREAKING CHANGE:` | Major (x.0.0) | `feat!: redesign WebSocket protocol` | +| `chore:`, `docs:`, `ci:` | No release | `chore: update dev deps` | + +PRs that don't match a release prefix produce no release — no error, no tag. + +## Pipeline Structure + +### PR Check Workflow (`.github/workflows/ci.yml`) + +Runs on every push to an open PR. No versioning. + +```yaml +on: + pull_request: + branches: [main] +jobs: + lint, build, test +``` + +### Release Workflow (`.github/workflows/release.yml`) + +Runs post-merge on `main`. Triggered by push to `main`. + +```yaml +on: + push: + branches: [main] +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # full clone — semantic-release needs commit history + persist-credentials: false + - uses: oven-sh/setup-bun@v2 + with: + bun-version: 1.3.10 + - run: bun install --frozen-lockfile + - run: bun run build + - name: Build platform binaries + run: bun run build:binaries + - name: Release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: bunx semantic-release +``` + +Key details: +- `fetch-depth: 0` — semantic-release needs full git history to find previous tags +- `persist-credentials: false` + `GITHUB_TOKEN` — semantic-release pushes tags via its own auth +- Binary build step produces artifacts before the release step attaches them + +## Configuration + +### `.releaserc.json` (repo root) + +```json +{ + "branches": ["main"], + "tagFormat": "v${version}", + "plugins": [ + "@semantic-release/commit-analyzer", + "@semantic-release/release-notes-generator", + [ + "@semantic-release/github", + { + "assets": [ + { "path": "dist/wtty-linux-x64", "label": "wtty-linux-x64" }, + { "path": "dist/wtty-linux-arm64", "label": "wtty-linux-arm64" }, + { "path": "dist/wtty-darwin-x64", "label": "wtty-darwin-x64" }, + { "path": "dist/wtty-darwin-arm64", "label": "wtty-darwin-arm64" }, + { "path": "dist/wtty-win32-x64.exe", "label": "wtty-win32-x64.exe" } + ] + } + ] + ] +} +``` + +Plugin chain: +1. **commit-analyzer** — determines bump type from conventional commits +2. **release-notes-generator** — generates changelog from commits (used for GitHub Release body) +3. **github** — creates the GitHub Release, uploads binary assets, pushes the git tag + +`@semantic-release/git` and `@semantic-release/changelog` are intentionally omitted — tag-only approach keeps history clean and avoids CI push-to-branch permissions. + +### `package.json` version + +Keep at `0.0.0-development` to signal that the in-repo version is not the published version: + +```json +{ + "version": "0.0.0-development" +} +``` + +## Version Progression + +``` +main branch: + v0.1.0 (feat: bootstrap terminal server) + v0.1.1 (fix: handle PTY exit on Windows) + v0.2.0 (feat: add config file support) + v1.0.0 (feat!: redesign WebSocket protocol) +``` + +## Tag Format + +Git tags: `v` (e.g. `v0.2.0`). Created by `@semantic-release/github` on the merge commit on `main`. Do not delete tags — semantic-release uses them to determine the next version. + +## GitHub Settings (one-time) + +### Repository Settings + +| Setting | Value | Why | +|---------|-------|-----| +| Squash merging | Enabled | PR title becomes the commit message semantic-release reads | +| Allow merge commits | Disabled (recommended) | Enforce squash-only to keep one commit per PR on `main` | + +### Workflow Permissions + +Go to **Settings → Actions → General → Workflow permissions**: + +| Setting | Value | Why | +|---------|-------|-----| +| Workflow permissions | Read and write | `GITHUB_TOKEN` needs to push tags and create releases | +| Allow GitHub Actions to create and approve pull requests | Not needed | Release workflow doesn't open PRs | + +`GITHUB_TOKEN` is provided automatically by GitHub Actions — no manual secret setup needed. + +## Features + +| Feature | Status | Reference | +|---------|--------|-----------| +| Automated versioning via conventional commits | ⬜ | [ADR 003](../adrs/003.release-process.semantic-release.md) | +| GitHub Release with release notes | ⬜ | [ADR 003](../adrs/003.release-process.semantic-release.md) | +| Platform binary artifacts on release | ⬜ | [ADR 003](../adrs/003.release-process.semantic-release.md) | From 7ccf4c2df7bf8154d9fbbd921e3e916cf8827092 Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 17:51:15 -0400 Subject: [PATCH 03/27] feat: implement automated release process with semantic-release - Set up semantic-release for automated versioning and GitHub releases. - Update release workflow to push git tags and create releases with release notes. - Add CLI commands for starting and stopping the server. - Modify build script to include CLI entry point. - Introduce .releaserc.json for semantic-release configuration. - Update package.json to reflect development version and add CLI binary. - Enhance server to handle stop command via API. --- .github/workflows/release.yml | 11 +- .releaserc.json | 9 + bun.lock | 893 ++++++++++++++++++ .../003.release-process.semantic-release.md | 62 +- docs/specs/release-process.md | 81 +- package.json | 9 +- scripts/build.ts | 2 +- src/cli.ts | 32 + src/server.ts | 12 + 9 files changed, 998 insertions(+), 113 deletions(-) create mode 100644 .releaserc.json create mode 100644 src/cli.ts diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 501a3c8..6a7a61e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,12 +8,19 @@ on: jobs: release: runs-on: ubuntu-latest + permissions: + contents: write steps: - uses: actions/checkout@v4 + with: + fetch-depth: 0 + persist-credentials: false - uses: oven-sh/setup-bun@v2 with: bun-version: 1.3.10 - run: bun install --frozen-lockfile - run: bun run build - - name: Publish (dummy) - run: echo "TODO - publish step" + - name: Release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: bunx semantic-release diff --git a/.releaserc.json b/.releaserc.json new file mode 100644 index 0000000..fea7fae --- /dev/null +++ b/.releaserc.json @@ -0,0 +1,9 @@ +{ + "branches": ["main"], + "tagFormat": "v${version}", + "plugins": [ + "@semantic-release/commit-analyzer", + "@semantic-release/release-notes-generator", + "@semantic-release/github" + ] +} diff --git a/bun.lock b/bun.lock index ad98f81..b80b8ef 100644 --- a/bun.lock +++ b/bun.lock @@ -14,12 +14,25 @@ "@types/bun": "1.3.11", "@types/ws": "8.18.1", "rimraf": "6.1.3", + "semantic-release": "25.0.3", "tsx": "4.21.0", "typescript": "5.9.3", }, }, }, "packages": { + "@actions/core": ["@actions/core@3.0.0", "", { "dependencies": { "@actions/exec": "^3.0.0", "@actions/http-client": "^4.0.0" } }, "sha512-zYt6cz+ivnTmiT/ksRVriMBOiuoUpDCJJlZ5KPl2/FRdvwU3f7MPh9qftvbkXJThragzUZieit2nyHUyw53Seg=="], + + "@actions/exec": ["@actions/exec@3.0.0", "", { "dependencies": { "@actions/io": "^3.0.2" } }, "sha512-6xH/puSoNBXb72VPlZVm7vQ+svQpFyA96qdDBvhB8eNZOE8LtPf9L4oAsfzK/crCL8YZ+19fKYVnM63Sl+Xzlw=="], + + "@actions/http-client": ["@actions/http-client@4.0.0", "", { "dependencies": { "tunnel": "^0.0.6", "undici": "^6.23.0" } }, "sha512-QuwPsgVMsD6qaPD57GLZi9sqzAZCtiJT8kVBCDpLtxhL5MydQ4gS+DrejtZZPdIYyB1e95uCK9Luyds7ybHI3g=="], + + "@actions/io": ["@actions/io@3.0.2", "", {}, "sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw=="], + + "@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="], + + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], + "@biomejs/biome": ["@biomejs/biome@2.4.8", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.8", "@biomejs/cli-darwin-x64": "2.4.8", "@biomejs/cli-linux-arm64": "2.4.8", "@biomejs/cli-linux-arm64-musl": "2.4.8", "@biomejs/cli-linux-x64": "2.4.8", "@biomejs/cli-linux-x64-musl": "2.4.8", "@biomejs/cli-win32-arm64": "2.4.8", "@biomejs/cli-win32-x64": "2.4.8" }, "bin": { "biome": "bin/biome" } }, "sha512-ponn0oKOky1oRXBV+rlSaUlixUxf1aZvWC19Z41zBfUOUesthrQqL3OtiAlSB1EjFjyWpn98Q64DHelhA6jNlA=="], "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.8", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ARx0tECE8I7S2C2yjnWYLNbBdDoPdq3oyNLhMglmuctThwUsuzFWRKrHmIGwIRWKz0Mat9DuzLEDp52hGnrxGQ=="], @@ -38,6 +51,8 @@ "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.8", "", { "os": "win32", "cpu": "x64" }, "sha512-vAn7iXDoUbqFXqVocuq1sMYAd33p8+mmurqJkWl6CtIhobd/O6moe4rY5AJvzbunn/qZCdiDVcveqtkFh1e7Hg=="], + "@colors/colors": ["@colors/colors@1.5.0", "", {}, "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ=="], + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.4", "", { "os": "aix", "cpu": "ppc64" }, "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q=="], "@esbuild/android-arm": ["@esbuild/android-arm@0.27.4", "", { "os": "android", "cpu": "arm" }, "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ=="], @@ -104,48 +119,926 @@ "@lydell/node-pty-win32-x64": ["@lydell/node-pty-win32-x64@1.2.0-beta.3", "", { "os": "win32", "cpu": "x64" }, "sha512-TpdqSFYx7/Rj+68tuP6F/lkRYrHCYAIJgaS1bx3SctTkb5QAQCFwOKHd4xlsivmEOMT2LdhkJggPxwX9PAO5pQ=="], + "@octokit/auth-token": ["@octokit/auth-token@6.0.0", "", {}, "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w=="], + + "@octokit/core": ["@octokit/core@7.0.6", "", { "dependencies": { "@octokit/auth-token": "^6.0.0", "@octokit/graphql": "^9.0.3", "@octokit/request": "^10.0.6", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "before-after-hook": "^4.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q=="], + + "@octokit/endpoint": ["@octokit/endpoint@11.0.3", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag=="], + + "@octokit/graphql": ["@octokit/graphql@9.0.3", "", { "dependencies": { "@octokit/request": "^10.0.6", "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA=="], + + "@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="], + + "@octokit/plugin-paginate-rest": ["@octokit/plugin-paginate-rest@14.0.0", "", { "dependencies": { "@octokit/types": "^16.0.0" }, "peerDependencies": { "@octokit/core": ">=6" } }, "sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw=="], + + "@octokit/plugin-retry": ["@octokit/plugin-retry@8.1.0", "", { "dependencies": { "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "bottleneck": "^2.15.3" }, "peerDependencies": { "@octokit/core": ">=7" } }, "sha512-O1FZgXeiGb2sowEr/hYTr6YunGdSAFWnr2fyW39Ah85H8O33ELASQxcvOFF5LE6Tjekcyu2ms4qAzJVhSaJxTw=="], + + "@octokit/plugin-throttling": ["@octokit/plugin-throttling@11.0.3", "", { "dependencies": { "@octokit/types": "^16.0.0", "bottleneck": "^2.15.3" }, "peerDependencies": { "@octokit/core": "^7.0.0" } }, "sha512-34eE0RkFCKycLl2D2kq7W+LovheM/ex3AwZCYN8udpi6bxsyjZidb2McXs69hZhLmJlDqTSP8cH+jSRpiaijBg=="], + + "@octokit/request": ["@octokit/request@10.0.8", "", { "dependencies": { "@octokit/endpoint": "^11.0.3", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "fast-content-type-parse": "^3.0.0", "json-with-bigint": "^3.5.3", "universal-user-agent": "^7.0.2" } }, "sha512-SJZNwY9pur9Agf7l87ywFi14W+Hd9Jg6Ifivsd33+/bGUQIjNujdFiXII2/qSlN2ybqUHfp5xpekMEjIBTjlSw=="], + + "@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="], + + "@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="], + + "@pnpm/config.env-replace": ["@pnpm/config.env-replace@1.1.0", "", {}, "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w=="], + + "@pnpm/network.ca-file": ["@pnpm/network.ca-file@1.0.2", "", { "dependencies": { "graceful-fs": "4.2.10" } }, "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA=="], + + "@pnpm/npm-conf": ["@pnpm/npm-conf@3.0.2", "", { "dependencies": { "@pnpm/config.env-replace": "^1.1.0", "@pnpm/network.ca-file": "^1.0.1", "config-chain": "^1.1.11" } }, "sha512-h104Kh26rR8tm+a3Qkc5S4VLYint3FE48as7+/5oCEcKR2idC/pF1G6AhIXKI+eHPJa/3J9i5z0Al47IeGHPkA=="], + + "@sec-ant/readable-stream": ["@sec-ant/readable-stream@0.4.1", "", {}, "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg=="], + + "@semantic-release/commit-analyzer": ["@semantic-release/commit-analyzer@13.0.1", "", { "dependencies": { "conventional-changelog-angular": "^8.0.0", "conventional-changelog-writer": "^8.0.0", "conventional-commits-filter": "^5.0.0", "conventional-commits-parser": "^6.0.0", "debug": "^4.0.0", "import-from-esm": "^2.0.0", "lodash-es": "^4.17.21", "micromatch": "^4.0.2" }, "peerDependencies": { "semantic-release": ">=20.1.0" } }, "sha512-wdnBPHKkr9HhNhXOhZD5a2LNl91+hs8CC2vsAVYxtZH3y0dV3wKn+uZSN61rdJQZ8EGxzWB3inWocBHV9+u/CQ=="], + + "@semantic-release/error": ["@semantic-release/error@4.0.0", "", {}, "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ=="], + + "@semantic-release/github": ["@semantic-release/github@12.0.6", "", { "dependencies": { "@octokit/core": "^7.0.0", "@octokit/plugin-paginate-rest": "^14.0.0", "@octokit/plugin-retry": "^8.0.0", "@octokit/plugin-throttling": "^11.0.0", "@semantic-release/error": "^4.0.0", "aggregate-error": "^5.0.0", "debug": "^4.3.4", "dir-glob": "^3.0.1", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.0", "issue-parser": "^7.0.0", "lodash-es": "^4.17.21", "mime": "^4.0.0", "p-filter": "^4.0.0", "tinyglobby": "^0.2.14", "undici": "^7.0.0", "url-join": "^5.0.0" }, "peerDependencies": { "semantic-release": ">=24.1.0" } }, "sha512-aYYFkwHW3c6YtHwQF0t0+lAjlU+87NFOZuH2CvWFD0Ylivc7MwhZMiHOJ0FMpIgPpCVib/VUAcOwvrW0KnxQtA=="], + + "@semantic-release/npm": ["@semantic-release/npm@13.1.5", "", { "dependencies": { "@actions/core": "^3.0.0", "@semantic-release/error": "^4.0.0", "aggregate-error": "^5.0.0", "env-ci": "^11.2.0", "execa": "^9.0.0", "fs-extra": "^11.0.0", "lodash-es": "^4.17.21", "nerf-dart": "^1.0.0", "normalize-url": "^9.0.0", "npm": "^11.6.2", "rc": "^1.2.8", "read-pkg": "^10.0.0", "registry-auth-token": "^5.0.0", "semver": "^7.1.2", "tempy": "^3.0.0" }, "peerDependencies": { "semantic-release": ">=20.1.0" } }, "sha512-Hq5UxzoatN3LHiq2rTsWS54nCdqJHlsssGERCo8WlvdfFA9LoN0vO+OuKVSjtNapIc/S8C2LBj206wKLHg62mg=="], + + "@semantic-release/release-notes-generator": ["@semantic-release/release-notes-generator@14.1.0", "", { "dependencies": { "conventional-changelog-angular": "^8.0.0", "conventional-changelog-writer": "^8.0.0", "conventional-commits-filter": "^5.0.0", "conventional-commits-parser": "^6.0.0", "debug": "^4.0.0", "get-stream": "^7.0.0", "import-from-esm": "^2.0.0", "into-stream": "^7.0.0", "lodash-es": "^4.17.21", "read-package-up": "^11.0.0" }, "peerDependencies": { "semantic-release": ">=20.1.0" } }, "sha512-CcyDRk7xq+ON/20YNR+1I/jP7BYKICr1uKd1HHpROSnnTdGqOTburi4jcRiTYz0cpfhxSloQO3cGhnoot7IEkA=="], + + "@simple-libs/stream-utils": ["@simple-libs/stream-utils@1.2.0", "", {}, "sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA=="], + + "@sindresorhus/is": ["@sindresorhus/is@4.6.0", "", {}, "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw=="], + + "@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@4.0.0", "", {}, "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ=="], + "@types/bun": ["@types/bun@1.3.11", "", { "dependencies": { "bun-types": "1.3.11" } }, "sha512-5vPne5QvtpjGpsGYXiFyycfpDF2ECyPcTSsFBMa0fraoxiQyMJ3SmuQIGhzPg2WJuWxVBoxWJ2kClYTcw/4fAg=="], "@types/node": ["@types/node@25.5.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw=="], + "@types/normalize-package-data": ["@types/normalize-package-data@2.4.4", "", {}, "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA=="], + "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], + "agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + + "aggregate-error": ["aggregate-error@5.0.0", "", { "dependencies": { "clean-stack": "^5.2.0", "indent-string": "^5.0.0" } }, "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw=="], + + "ansi-escapes": ["ansi-escapes@7.3.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg=="], + + "ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], + + "ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="], + + "any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="], + + "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], + + "argv-formatter": ["argv-formatter@1.0.0", "", {}, "sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw=="], + + "array-ify": ["array-ify@1.0.0", "", {}, "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng=="], + "balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + "before-after-hook": ["before-after-hook@4.0.0", "", {}, "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="], + + "bottleneck": ["bottleneck@2.19.5", "", {}, "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="], + "brace-expansion": ["brace-expansion@5.0.4", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg=="], + "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], + "bun-types": ["bun-types@1.3.11", "", { "dependencies": { "@types/node": "*" } }, "sha512-1KGPpoxQWl9f6wcZh57LvrPIInQMn2TQ7jsgxqpRzg+l0QPOFvJVH7HmvHo/AiPgwXy+/Thf6Ov3EdVn1vOabg=="], + "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], + + "chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], + + "char-regex": ["char-regex@1.0.2", "", {}, "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw=="], + + "clean-stack": ["clean-stack@5.3.0", "", { "dependencies": { "escape-string-regexp": "5.0.0" } }, "sha512-9ngPTOhYGQqNVSfeJkYXHmF7AGWp4/nN5D/QqNQs3Dvxd1Kk/WpjHfNujKHYUQ/5CoGyOyFNoWSPk5afzP0QVg=="], + + "cli-highlight": ["cli-highlight@2.1.11", "", { "dependencies": { "chalk": "^4.0.0", "highlight.js": "^10.7.1", "mz": "^2.4.0", "parse5": "^5.1.1", "parse5-htmlparser2-tree-adapter": "^6.0.0", "yargs": "^16.0.0" }, "bin": { "highlight": "bin/highlight" } }, "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg=="], + + "cli-table3": ["cli-table3@0.6.5", "", { "dependencies": { "string-width": "^4.2.0" }, "optionalDependencies": { "@colors/colors": "1.5.0" } }, "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ=="], + + "cliui": ["cliui@9.0.1", "", { "dependencies": { "string-width": "^7.2.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" } }, "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w=="], + + "color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="], + + "color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="], + + "compare-func": ["compare-func@2.0.0", "", { "dependencies": { "array-ify": "^1.0.0", "dot-prop": "^5.1.0" } }, "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA=="], + + "config-chain": ["config-chain@1.1.13", "", { "dependencies": { "ini": "^1.3.4", "proto-list": "~1.2.1" } }, "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ=="], + + "conventional-changelog-angular": ["conventional-changelog-angular@8.3.0", "", { "dependencies": { "compare-func": "^2.0.0" } }, "sha512-DOuBwYSqWzfwuRByY9O4oOIvDlkUCTDzfbOgcSbkY+imXXj+4tmrEFao3K+FxemClYfYnZzsvudbwrhje9VHDA=="], + + "conventional-changelog-writer": ["conventional-changelog-writer@8.4.0", "", { "dependencies": { "@simple-libs/stream-utils": "^1.2.0", "conventional-commits-filter": "^5.0.0", "handlebars": "^4.7.7", "meow": "^13.0.0", "semver": "^7.5.2" }, "bin": { "conventional-changelog-writer": "dist/cli/index.js" } }, "sha512-HHBFkk1EECxxmCi4CTu091iuDpQv5/OavuCUAuZmrkWpmYfyD816nom1CvtfXJ/uYfAAjavgHvXHX291tSLK8g=="], + + "conventional-commits-filter": ["conventional-commits-filter@5.0.0", "", {}, "sha512-tQMagCOC59EVgNZcC5zl7XqO30Wki9i9J3acbUvkaosCT6JX3EeFwJD7Qqp4MCikRnzS18WXV3BLIQ66ytu6+Q=="], + + "conventional-commits-parser": ["conventional-commits-parser@6.3.0", "", { "dependencies": { "@simple-libs/stream-utils": "^1.2.0", "meow": "^13.0.0" }, "bin": { "conventional-commits-parser": "dist/cli/index.js" } }, "sha512-RfOq/Cqy9xV9bOA8N+ZH6DlrDR+5S3Mi0B5kACEjESpE+AviIpAptx9a9cFpWCCvgRtWT+0BbUw+e1BZfts9jg=="], + + "convert-hrtime": ["convert-hrtime@5.0.0", "", {}, "sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg=="], + + "core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="], + + "cosmiconfig": ["cosmiconfig@9.0.1", "", { "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0" }, "peerDependencies": { "typescript": ">=4.9.5" }, "optionalPeers": ["typescript"] }, "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ=="], + + "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], + + "crypto-random-string": ["crypto-random-string@4.0.0", "", { "dependencies": { "type-fest": "^1.0.1" } }, "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA=="], + + "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + + "deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="], + + "dir-glob": ["dir-glob@3.0.1", "", { "dependencies": { "path-type": "^4.0.0" } }, "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA=="], + + "dot-prop": ["dot-prop@5.3.0", "", { "dependencies": { "is-obj": "^2.0.0" } }, "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q=="], + + "duplexer2": ["duplexer2@0.1.4", "", { "dependencies": { "readable-stream": "^2.0.2" } }, "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA=="], + + "emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], + + "emojilib": ["emojilib@2.4.0", "", {}, "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw=="], + + "env-ci": ["env-ci@11.2.0", "", { "dependencies": { "execa": "^8.0.0", "java-properties": "^1.0.2" } }, "sha512-D5kWfzkmaOQDioPmiviWAVtKmpPT4/iJmMVQxWxMPJTFyTkdc5JQUfc5iXEeWxcOdsYTKSAiA/Age4NUOqKsRA=="], + + "env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], + + "environment": ["environment@1.1.0", "", {}, "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q=="], + + "error-ex": ["error-ex@1.3.4", "", { "dependencies": { "is-arrayish": "^0.2.1" } }, "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ=="], + "esbuild": ["esbuild@0.27.4", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.4", "@esbuild/android-arm": "0.27.4", "@esbuild/android-arm64": "0.27.4", "@esbuild/android-x64": "0.27.4", "@esbuild/darwin-arm64": "0.27.4", "@esbuild/darwin-x64": "0.27.4", "@esbuild/freebsd-arm64": "0.27.4", "@esbuild/freebsd-x64": "0.27.4", "@esbuild/linux-arm": "0.27.4", "@esbuild/linux-arm64": "0.27.4", "@esbuild/linux-ia32": "0.27.4", "@esbuild/linux-loong64": "0.27.4", "@esbuild/linux-mips64el": "0.27.4", "@esbuild/linux-ppc64": "0.27.4", "@esbuild/linux-riscv64": "0.27.4", "@esbuild/linux-s390x": "0.27.4", "@esbuild/linux-x64": "0.27.4", "@esbuild/netbsd-arm64": "0.27.4", "@esbuild/netbsd-x64": "0.27.4", "@esbuild/openbsd-arm64": "0.27.4", "@esbuild/openbsd-x64": "0.27.4", "@esbuild/openharmony-arm64": "0.27.4", "@esbuild/sunos-x64": "0.27.4", "@esbuild/win32-arm64": "0.27.4", "@esbuild/win32-ia32": "0.27.4", "@esbuild/win32-x64": "0.27.4" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ=="], + "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], + + "escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], + + "execa": ["execa@9.6.1", "", { "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", "cross-spawn": "^7.0.6", "figures": "^6.1.0", "get-stream": "^9.0.0", "human-signals": "^8.0.1", "is-plain-obj": "^4.1.0", "is-stream": "^4.0.1", "npm-run-path": "^6.0.0", "pretty-ms": "^9.2.0", "signal-exit": "^4.1.0", "strip-final-newline": "^4.0.0", "yoctocolors": "^2.1.1" } }, "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA=="], + + "fast-content-type-parse": ["fast-content-type-parse@3.0.0", "", {}, "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg=="], + + "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + + "figures": ["figures@6.1.0", "", { "dependencies": { "is-unicode-supported": "^2.0.0" } }, "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg=="], + + "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], + + "find-up": ["find-up@2.1.0", "", { "dependencies": { "locate-path": "^2.0.0" } }, "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ=="], + + "find-up-simple": ["find-up-simple@1.0.1", "", {}, "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ=="], + + "find-versions": ["find-versions@6.0.0", "", { "dependencies": { "semver-regex": "^4.0.5", "super-regex": "^1.0.0" } }, "sha512-2kCCtc+JvcZ86IGAz3Z2Y0A1baIz9fL31pH/0S1IqZr9Iwnjq8izfPtrCyQKO6TLMPELLsQMre7VDqeIKCsHkA=="], + + "from2": ["from2@2.3.0", "", { "dependencies": { "inherits": "^2.0.1", "readable-stream": "^2.0.0" } }, "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g=="], + + "fs-extra": ["fs-extra@11.3.4", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA=="], + "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], + "function-timeout": ["function-timeout@1.0.2", "", {}, "sha512-939eZS4gJ3htTHAldmyyuzlrD58P03fHG49v2JfFXbV6OhvZKRC9j2yAtdHw/zrp2zXHuv05zMIy40F0ge7spA=="], + + "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], + + "get-east-asian-width": ["get-east-asian-width@1.5.0", "", {}, "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA=="], + + "get-stream": ["get-stream@6.0.1", "", {}, "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="], + "get-tsconfig": ["get-tsconfig@4.13.6", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw=="], "ghostty-web": ["ghostty-web@0.4.0-next.14.g6a1a50d", "", {}, "sha512-01H59pAKq43Y8ZZiIhH98cu0ahZaoGoPQPtW4KnZPT0JFdQYen2djsXrOnt27JnMv64D4eLeAq8D6h72mo52xQ=="], + "git-log-parser": ["git-log-parser@1.2.1", "", { "dependencies": { "argv-formatter": "~1.0.0", "spawn-error-forwarder": "~1.0.0", "split2": "~1.0.0", "stream-combiner2": "~1.1.1", "through2": "~2.0.0", "traverse": "0.6.8" } }, "sha512-PI+sPDvHXNPl5WNOErAK05s3j0lgwUzMN6o8cyQrDaKfT3qd7TmNJKeXX+SknI5I0QhG5fVPAEwSY4tRGDtYoQ=="], + "glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], + "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], + + "handlebars": ["handlebars@4.7.8", "", { "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.2", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, "optionalDependencies": { "uglify-js": "^3.1.4" }, "bin": { "handlebars": "bin/handlebars" } }, "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ=="], + + "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], + + "highlight.js": ["highlight.js@10.7.3", "", {}, "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A=="], + + "hook-std": ["hook-std@4.0.0", "", {}, "sha512-IHI4bEVOt3vRUDJ+bFA9VUJlo7SzvFARPNLw75pqSmAOP2HmTWfFJtPvLBrDrlgjEYXY9zs7SFdHPQaJShkSCQ=="], + + "hosted-git-info": ["hosted-git-info@9.0.2", "", { "dependencies": { "lru-cache": "^11.1.0" } }, "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg=="], + + "http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="], + + "https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], + + "human-signals": ["human-signals@8.0.1", "", {}, "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ=="], + + "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], + + "import-from-esm": ["import-from-esm@2.0.0", "", { "dependencies": { "debug": "^4.3.4", "import-meta-resolve": "^4.0.0" } }, "sha512-YVt14UZCgsX1vZQ3gKjkWVdBdHQ6eu3MPU1TBgL1H5orXe2+jWD006WCPPtOuwlQm10NuzOW5WawiF1Q9veW8g=="], + + "import-meta-resolve": ["import-meta-resolve@4.2.0", "", {}, "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg=="], + + "indent-string": ["indent-string@5.0.0", "", {}, "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg=="], + + "index-to-position": ["index-to-position@1.2.0", "", {}, "sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw=="], + + "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], + + "ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="], + + "into-stream": ["into-stream@7.0.0", "", { "dependencies": { "from2": "^2.3.0", "p-is-promise": "^3.0.0" } }, "sha512-2dYz766i9HprMBasCMvHMuazJ7u4WzhJwo5kb3iPSiW/iRYV6uPari3zHoqZlnuaR7V1bEiNMxikhp37rdBXbw=="], + + "is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="], + + "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], + + "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], + + "is-obj": ["is-obj@2.0.0", "", {}, "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="], + + "is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="], + + "is-stream": ["is-stream@4.0.1", "", {}, "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A=="], + + "is-unicode-supported": ["is-unicode-supported@2.1.0", "", {}, "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ=="], + + "isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="], + + "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], + + "issue-parser": ["issue-parser@7.0.1", "", { "dependencies": { "lodash.capitalize": "^4.2.1", "lodash.escaperegexp": "^4.1.2", "lodash.isplainobject": "^4.0.6", "lodash.isstring": "^4.0.1", "lodash.uniqby": "^4.7.0" } }, "sha512-3YZcUUR2Wt1WsapF+S/WiA2WmlW0cWAoPccMqne7AxEBhCdFeTPjfv/Axb8V2gyCgY3nRw+ksZ3xSUX+R47iAg=="], + + "java-properties": ["java-properties@1.0.2", "", {}, "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ=="], + + "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], + + "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], + + "json-parse-better-errors": ["json-parse-better-errors@1.0.2", "", {}, "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="], + + "json-parse-even-better-errors": ["json-parse-even-better-errors@2.3.1", "", {}, "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="], + + "json-with-bigint": ["json-with-bigint@3.5.8", "", {}, "sha512-eq/4KP6K34kwa7TcFdtvnftvHCD9KvHOGGICWwMFc4dOOKF5t4iYqnfLK8otCRCRv06FXOzGGyqE8h8ElMvvdw=="], + + "jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="], + + "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], + + "load-json-file": ["load-json-file@4.0.0", "", { "dependencies": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", "pify": "^3.0.0", "strip-bom": "^3.0.0" } }, "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw=="], + + "locate-path": ["locate-path@2.0.0", "", { "dependencies": { "p-locate": "^2.0.0", "path-exists": "^3.0.0" } }, "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA=="], + + "lodash-es": ["lodash-es@4.17.23", "", {}, "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg=="], + + "lodash.capitalize": ["lodash.capitalize@4.2.1", "", {}, "sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw=="], + + "lodash.escaperegexp": ["lodash.escaperegexp@4.1.2", "", {}, "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw=="], + + "lodash.isplainobject": ["lodash.isplainobject@4.0.6", "", {}, "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="], + + "lodash.isstring": ["lodash.isstring@4.0.1", "", {}, "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="], + + "lodash.uniqby": ["lodash.uniqby@4.7.0", "", {}, "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww=="], + "lru-cache": ["lru-cache@11.2.7", "", {}, "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA=="], + "make-asynchronous": ["make-asynchronous@1.1.0", "", { "dependencies": { "p-event": "^6.0.0", "type-fest": "^4.6.0", "web-worker": "^1.5.0" } }, "sha512-ayF7iT+44LXdxJLTrTd3TLQpFDDvPCBxXxbv+pMUSuHA5Q8zyAfwkRP6aHHwNVFBUFWtxAHqwNJxF8vMZLAbVg=="], + + "marked": ["marked@15.0.12", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA=="], + + "marked-terminal": ["marked-terminal@7.3.0", "", { "dependencies": { "ansi-escapes": "^7.0.0", "ansi-regex": "^6.1.0", "chalk": "^5.4.1", "cli-highlight": "^2.1.11", "cli-table3": "^0.6.5", "node-emoji": "^2.2.0", "supports-hyperlinks": "^3.1.0" }, "peerDependencies": { "marked": ">=1 <16" } }, "sha512-t4rBvPsHc57uE/2nJOLmMbZCQ4tgAccAED3ngXQqW6g+TxA488JzJ+FK3lQkzBQOI1mRV/r/Kq+1ZlJ4D0owQw=="], + + "meow": ["meow@13.2.0", "", {}, "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA=="], + + "merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="], + + "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], + + "mime": ["mime@4.1.0", "", { "bin": { "mime": "bin/cli.js" } }, "sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw=="], + + "mimic-fn": ["mimic-fn@4.0.0", "", {}, "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw=="], + "minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="], + "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], + "minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="], + + "neo-async": ["neo-async@2.6.2", "", {}, "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="], + + "nerf-dart": ["nerf-dart@1.0.0", "", {}, "sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g=="], + + "node-emoji": ["node-emoji@2.2.0", "", { "dependencies": { "@sindresorhus/is": "^4.6.0", "char-regex": "^1.0.2", "emojilib": "^2.4.0", "skin-tone": "^2.0.0" } }, "sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw=="], + + "normalize-package-data": ["normalize-package-data@8.0.0", "", { "dependencies": { "hosted-git-info": "^9.0.0", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4" } }, "sha512-RWk+PI433eESQ7ounYxIp67CYuVsS1uYSonX3kA6ps/3LWfjVQa/ptEg6Y3T6uAMq1mWpX9PQ+qx+QaHpsc7gQ=="], + + "normalize-url": ["normalize-url@9.0.0", "", {}, "sha512-z9nC87iaZXXySbWWtTHfCFJyFvKaUAW6lODhikG7ILSbVgmwuFjUqkgnheHvAUcGedO29e2QGBRXMUD64aurqQ=="], + + "npm": ["npm@11.12.0", "", { "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", "@npmcli/arborist": "^9.4.2", "@npmcli/config": "^10.8.0", "@npmcli/fs": "^5.0.0", "@npmcli/map-workspaces": "^5.0.3", "@npmcli/metavuln-calculator": "^9.0.3", "@npmcli/package-json": "^7.0.5", "@npmcli/promise-spawn": "^9.0.1", "@npmcli/redact": "^4.0.0", "@npmcli/run-script": "^10.0.4", "@sigstore/tuf": "^4.0.2", "abbrev": "^4.0.0", "archy": "~1.0.0", "cacache": "^20.0.4", "chalk": "^5.6.2", "ci-info": "^4.4.0", "fastest-levenshtein": "^1.0.16", "fs-minipass": "^3.0.3", "glob": "^13.0.6", "graceful-fs": "^4.2.11", "hosted-git-info": "^9.0.2", "ini": "^6.0.0", "init-package-json": "^8.2.5", "is-cidr": "^6.0.3", "json-parse-even-better-errors": "^5.0.0", "libnpmaccess": "^10.0.3", "libnpmdiff": "^8.1.5", "libnpmexec": "^10.2.5", "libnpmfund": "^7.0.19", "libnpmorg": "^8.0.1", "libnpmpack": "^9.1.5", "libnpmpublish": "^11.1.3", "libnpmsearch": "^9.0.1", "libnpmteam": "^8.0.2", "libnpmversion": "^8.0.3", "make-fetch-happen": "^15.0.5", "minimatch": "^10.2.4", "minipass": "^7.1.3", "minipass-pipeline": "^1.2.4", "ms": "^2.1.2", "node-gyp": "^12.2.0", "nopt": "^9.0.0", "npm-audit-report": "^7.0.0", "npm-install-checks": "^8.0.0", "npm-package-arg": "^13.0.2", "npm-pick-manifest": "^11.0.3", "npm-profile": "^12.0.1", "npm-registry-fetch": "^19.1.1", "npm-user-validate": "^4.0.0", "p-map": "^7.0.4", "pacote": "^21.5.0", "parse-conflict-json": "^5.0.1", "proc-log": "^6.1.0", "qrcode-terminal": "^0.12.0", "read": "^5.0.1", "semver": "^7.7.4", "spdx-expression-parse": "^4.0.0", "ssri": "^13.0.1", "supports-color": "^10.2.2", "tar": "^7.5.11", "text-table": "~0.2.0", "tiny-relative-date": "^2.0.2", "treeverse": "^3.0.0", "validate-npm-package-name": "^7.0.2", "which": "^6.0.1" }, "bin": { "npm": "bin/npm-cli.js", "npx": "bin/npx-cli.js" } }, "sha512-xPhOap4ZbJWyd7DAOukP564WFwNSGu/2FeTRFHhiiKthcauxhH/NpkJAQm24xD+cAn8av5tQ00phi98DqtfLsg=="], + + "npm-run-path": ["npm-run-path@6.0.0", "", { "dependencies": { "path-key": "^4.0.0", "unicorn-magic": "^0.3.0" } }, "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA=="], + + "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], + + "onetime": ["onetime@6.0.0", "", { "dependencies": { "mimic-fn": "^4.0.0" } }, "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ=="], + + "p-each-series": ["p-each-series@3.0.0", "", {}, "sha512-lastgtAdoH9YaLyDa5i5z64q+kzOcQHsQ5SsZJD3q0VEyI8mq872S3geuNbRUQLVAE9siMfgKrpj7MloKFHruw=="], + + "p-event": ["p-event@6.0.1", "", { "dependencies": { "p-timeout": "^6.1.2" } }, "sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w=="], + + "p-filter": ["p-filter@4.1.0", "", { "dependencies": { "p-map": "^7.0.1" } }, "sha512-37/tPdZ3oJwHaS3gNJdenCDB3Tz26i9sjhnguBtvN0vYlRIiDNnvTWkuh+0hETV9rLPdJ3rlL3yVOYPIAnM8rw=="], + + "p-is-promise": ["p-is-promise@3.0.0", "", {}, "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ=="], + + "p-limit": ["p-limit@1.3.0", "", { "dependencies": { "p-try": "^1.0.0" } }, "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q=="], + + "p-locate": ["p-locate@2.0.0", "", { "dependencies": { "p-limit": "^1.1.0" } }, "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg=="], + + "p-map": ["p-map@7.0.4", "", {}, "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ=="], + + "p-reduce": ["p-reduce@3.0.0", "", {}, "sha512-xsrIUgI0Kn6iyDYm9StOpOeK29XM1aboGji26+QEortiFST1hGZaUQOLhtEbqHErPpGW/aSz6allwK2qcptp0Q=="], + + "p-timeout": ["p-timeout@6.1.4", "", {}, "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg=="], + + "p-try": ["p-try@1.0.0", "", {}, "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww=="], + "package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="], + "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], + + "parse-json": ["parse-json@5.2.0", "", { "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg=="], + + "parse-ms": ["parse-ms@4.0.0", "", {}, "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw=="], + + "parse5": ["parse5@5.1.1", "", {}, "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug=="], + + "parse5-htmlparser2-tree-adapter": ["parse5-htmlparser2-tree-adapter@6.0.1", "", { "dependencies": { "parse5": "^6.0.1" } }, "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA=="], + + "path-exists": ["path-exists@3.0.0", "", {}, "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ=="], + + "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], + "path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="], + "path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="], + + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], + + "picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + + "pify": ["pify@3.0.0", "", {}, "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg=="], + + "pkg-conf": ["pkg-conf@2.1.0", "", { "dependencies": { "find-up": "^2.0.0", "load-json-file": "^4.0.0" } }, "sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g=="], + + "pretty-ms": ["pretty-ms@9.3.0", "", { "dependencies": { "parse-ms": "^4.0.0" } }, "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ=="], + + "process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="], + + "proto-list": ["proto-list@1.2.4", "", {}, "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA=="], + + "rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": { "rc": "./cli.js" } }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="], + + "read-package-up": ["read-package-up@12.0.0", "", { "dependencies": { "find-up-simple": "^1.0.1", "read-pkg": "^10.0.0", "type-fest": "^5.2.0" } }, "sha512-Q5hMVBYur/eQNWDdbF4/Wqqr9Bjvtrw2kjGxxBbKLbx8bVCL8gcArjTy8zDUuLGQicftpMuU0riQNcAsbtOVsw=="], + + "read-pkg": ["read-pkg@10.1.0", "", { "dependencies": { "@types/normalize-package-data": "^2.4.4", "normalize-package-data": "^8.0.0", "parse-json": "^8.3.0", "type-fest": "^5.4.4", "unicorn-magic": "^0.4.0" } }, "sha512-I8g2lArQiP78ll51UeMZojewtYgIRCKCWqZEgOO8c/uefTI+XDXvCSXu3+YNUaTNvZzobrL5+SqHjBrByRRTdg=="], + + "readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], + + "registry-auth-token": ["registry-auth-token@5.1.1", "", { "dependencies": { "@pnpm/npm-conf": "^3.0.2" } }, "sha512-P7B4+jq8DeD2nMsAcdfaqHbssgHtZ7Z5+++a5ask90fvmJ8p5je4mOa+wzu+DB4vQ5tdJV/xywY+UnVFeQLV5Q=="], + + "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], + + "resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="], + "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="], "rimraf": ["rimraf@6.1.3", "", { "dependencies": { "glob": "^13.0.3", "package-json-from-dist": "^1.0.1" }, "bin": { "rimraf": "dist/esm/bin.mjs" } }, "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA=="], + "safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], + + "semantic-release": ["semantic-release@25.0.3", "", { "dependencies": { "@semantic-release/commit-analyzer": "^13.0.1", "@semantic-release/error": "^4.0.0", "@semantic-release/github": "^12.0.0", "@semantic-release/npm": "^13.1.1", "@semantic-release/release-notes-generator": "^14.1.0", "aggregate-error": "^5.0.0", "cosmiconfig": "^9.0.0", "debug": "^4.0.0", "env-ci": "^11.0.0", "execa": "^9.0.0", "figures": "^6.0.0", "find-versions": "^6.0.0", "get-stream": "^6.0.0", "git-log-parser": "^1.2.0", "hook-std": "^4.0.0", "hosted-git-info": "^9.0.0", "import-from-esm": "^2.0.0", "lodash-es": "^4.17.21", "marked": "^15.0.0", "marked-terminal": "^7.3.0", "micromatch": "^4.0.2", "p-each-series": "^3.0.0", "p-reduce": "^3.0.0", "read-package-up": "^12.0.0", "resolve-from": "^5.0.0", "semver": "^7.3.2", "signale": "^1.2.1", "yargs": "^18.0.0" }, "bin": { "semantic-release": "bin/semantic-release.js" } }, "sha512-WRgl5GcypwramYX4HV+eQGzUbD7UUbljVmS+5G1uMwX/wLgYuJAxGeerXJDMO2xshng4+FXqCgyB5QfClV6WjA=="], + + "semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], + + "semver-regex": ["semver-regex@4.0.5", "", {}, "sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw=="], + + "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], + + "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], + + "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + + "signale": ["signale@1.4.0", "", { "dependencies": { "chalk": "^2.3.2", "figures": "^2.0.0", "pkg-conf": "^2.1.0" } }, "sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w=="], + + "skin-tone": ["skin-tone@2.0.0", "", { "dependencies": { "unicode-emoji-modifier-base": "^1.0.0" } }, "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA=="], + + "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], + + "spawn-error-forwarder": ["spawn-error-forwarder@1.0.0", "", {}, "sha512-gRjMgK5uFjbCvdibeGJuy3I5OYz6VLoVdsOJdA6wV0WlfQVLFueoqMxwwYD9RODdgb6oUIvlRlsyFSiQkMKu0g=="], + + "spdx-correct": ["spdx-correct@3.2.0", "", { "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA=="], + + "spdx-exceptions": ["spdx-exceptions@2.5.0", "", {}, "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w=="], + + "spdx-expression-parse": ["spdx-expression-parse@3.0.1", "", { "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q=="], + + "spdx-license-ids": ["spdx-license-ids@3.0.23", "", {}, "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw=="], + + "split2": ["split2@1.0.0", "", { "dependencies": { "through2": "~2.0.0" } }, "sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg=="], + + "stream-combiner2": ["stream-combiner2@1.1.1", "", { "dependencies": { "duplexer2": "~0.1.0", "readable-stream": "^2.0.2" } }, "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw=="], + + "string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], + + "string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], + + "strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], + + "strip-bom": ["strip-bom@3.0.0", "", {}, "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA=="], + + "strip-final-newline": ["strip-final-newline@4.0.0", "", {}, "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw=="], + + "strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="], + + "super-regex": ["super-regex@1.1.0", "", { "dependencies": { "function-timeout": "^1.0.1", "make-asynchronous": "^1.0.1", "time-span": "^5.1.0" } }, "sha512-WHkws2ZflZe41zj6AolvvmaTrWds/VuyeYr9iPVv/oQeaIoVxMKaushfFWpOGDT+GuBrM/sVqF8KUCYQlSSTdQ=="], + + "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], + + "supports-hyperlinks": ["supports-hyperlinks@3.2.0", "", { "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" } }, "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig=="], + + "tagged-tag": ["tagged-tag@1.0.0", "", {}, "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng=="], + + "temp-dir": ["temp-dir@3.0.0", "", {}, "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw=="], + + "tempy": ["tempy@3.2.0", "", { "dependencies": { "is-stream": "^3.0.0", "temp-dir": "^3.0.0", "type-fest": "^2.12.2", "unique-string": "^3.0.0" } }, "sha512-d79HhZya5Djd7am0q+W4RTsSU+D/aJzM+4Y4AGJGuGlgM2L6sx5ZvOYTmZjqPhrDrV6xJTtRSm1JCLj6V6LHLQ=="], + + "thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="], + + "thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="], + + "through2": ["through2@2.0.5", "", { "dependencies": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" } }, "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ=="], + + "time-span": ["time-span@5.1.0", "", { "dependencies": { "convert-hrtime": "^5.0.0" } }, "sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA=="], + + "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], + + "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], + + "traverse": ["traverse@0.6.8", "", {}, "sha512-aXJDbk6SnumuaZSANd21XAo15ucCDE38H4fkqiGsc3MhCK+wOlZvLP9cB/TvpHT0mOyWgC4Z8EwRlzqYSUzdsA=="], + "tsx": ["tsx@4.21.0", "", { "dependencies": { "esbuild": "~0.27.0", "get-tsconfig": "^4.7.5" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw=="], + "tunnel": ["tunnel@0.0.6", "", {}, "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="], + + "type-fest": ["type-fest@5.5.0", "", { "dependencies": { "tagged-tag": "^1.0.0" } }, "sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g=="], + "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + "uglify-js": ["uglify-js@3.19.3", "", { "bin": { "uglifyjs": "bin/uglifyjs" } }, "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ=="], + + "undici": ["undici@7.24.5", "", {}, "sha512-3IWdCpjgxp15CbJnsi/Y9TCDE7HWVN19j1hmzVhoAkY/+CJx449tVxT5wZc1Gwg8J+P0LWvzlBzxYRnHJ+1i7Q=="], + "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="], + "unicode-emoji-modifier-base": ["unicode-emoji-modifier-base@1.0.0", "", {}, "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g=="], + + "unicorn-magic": ["unicorn-magic@0.4.0", "", {}, "sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw=="], + + "unique-string": ["unique-string@3.0.0", "", { "dependencies": { "crypto-random-string": "^4.0.0" } }, "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ=="], + + "universal-user-agent": ["universal-user-agent@7.0.3", "", {}, "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A=="], + + "universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="], + + "url-join": ["url-join@5.0.0", "", {}, "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA=="], + + "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], + + "validate-npm-package-license": ["validate-npm-package-license@3.0.4", "", { "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew=="], + + "web-worker": ["web-worker@1.5.0", "", {}, "sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw=="], + + "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], + + "wordwrap": ["wordwrap@1.0.0", "", {}, "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="], + + "wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="], + "ws": ["ws@8.20.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA=="], + + "xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="], + + "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], + + "yargs": ["yargs@18.0.0", "", { "dependencies": { "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "string-width": "^7.2.0", "y18n": "^5.0.5", "yargs-parser": "^22.0.0" } }, "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg=="], + + "yargs-parser": ["yargs-parser@22.0.0", "", {}, "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw=="], + + "yoctocolors": ["yoctocolors@2.1.2", "", {}, "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug=="], + + "@actions/http-client/undici": ["undici@6.24.1", "", {}, "sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA=="], + + "@pnpm/network.ca-file/graceful-fs": ["graceful-fs@4.2.10", "", {}, "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="], + + "@semantic-release/release-notes-generator/get-stream": ["get-stream@7.0.1", "", {}, "sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ=="], + + "@semantic-release/release-notes-generator/read-package-up": ["read-package-up@11.0.0", "", { "dependencies": { "find-up-simple": "^1.0.0", "read-pkg": "^9.0.0", "type-fest": "^4.6.0" } }, "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ=="], + + "cli-highlight/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + + "cli-highlight/yargs": ["yargs@16.2.0", "", { "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" } }, "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw=="], + + "cli-table3/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + + "crypto-random-string/type-fest": ["type-fest@1.4.0", "", {}, "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA=="], + + "env-ci/execa": ["execa@8.0.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", "human-signals": "^5.0.0", "is-stream": "^3.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^5.1.0", "onetime": "^6.0.0", "signal-exit": "^4.1.0", "strip-final-newline": "^3.0.0" } }, "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg=="], + + "execa/get-stream": ["get-stream@9.0.1", "", { "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" } }, "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA=="], + + "import-fresh/resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], + + "load-json-file/parse-json": ["parse-json@4.0.0", "", { "dependencies": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" } }, "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw=="], + + "make-asynchronous/type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="], + + "npm/@gar/promise-retry": ["@gar/promise-retry@1.0.3", "", {}, "sha512-GmzA9ckNokPypTg10pgpeHNQe7ph+iIKKmhKu3Ob9ANkswreCx7R3cKmY781K8QK3AqVL3xVh9A42JvIAbkkSA=="], + + "npm/@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="], + + "npm/@isaacs/string-locale-compare": ["@isaacs/string-locale-compare@1.1.0", "", { "bundled": true }, "sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ=="], + + "npm/@npmcli/agent": ["@npmcli/agent@4.0.0", "", { "dependencies": { "agent-base": "^7.1.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.1", "lru-cache": "^11.2.1", "socks-proxy-agent": "^8.0.3" } }, "sha512-kAQTcEN9E8ERLVg5AsGwLNoFb+oEG6engbqAU2P43gD4JEIkNGMHdVQ096FsOAAYpZPB0RSt0zgInKIAS1l5QA=="], + + "npm/@npmcli/arborist": ["@npmcli/arborist@9.4.2", "", { "dependencies": { "@gar/promise-retry": "^1.0.0", "@isaacs/string-locale-compare": "^1.1.0", "@npmcli/fs": "^5.0.0", "@npmcli/installed-package-contents": "^4.0.0", "@npmcli/map-workspaces": "^5.0.0", "@npmcli/metavuln-calculator": "^9.0.2", "@npmcli/name-from-folder": "^4.0.0", "@npmcli/node-gyp": "^5.0.0", "@npmcli/package-json": "^7.0.0", "@npmcli/query": "^5.0.0", "@npmcli/redact": "^4.0.0", "@npmcli/run-script": "^10.0.0", "bin-links": "^6.0.0", "cacache": "^20.0.1", "common-ancestor-path": "^2.0.0", "hosted-git-info": "^9.0.0", "json-stringify-nice": "^1.1.4", "lru-cache": "^11.2.1", "minimatch": "^10.0.3", "nopt": "^9.0.0", "npm-install-checks": "^8.0.0", "npm-package-arg": "^13.0.0", "npm-pick-manifest": "^11.0.1", "npm-registry-fetch": "^19.0.0", "pacote": "^21.0.2", "parse-conflict-json": "^5.0.1", "proc-log": "^6.0.0", "proggy": "^4.0.0", "promise-all-reject-late": "^1.0.0", "promise-call-limit": "^3.0.1", "semver": "^7.3.7", "ssri": "^13.0.0", "treeverse": "^3.0.0", "walk-up-path": "^4.0.0" }, "bundled": true, "bin": { "arborist": "bin/index.js" } }, "sha512-omJgPyzt11cEGrxzgrECoOyxAunmPMgBFTcAB/FbaB+9iOYhGmRdsQqySV8o0LWQ/l2kTeASUIMR4xJufVwmtw=="], + + "npm/@npmcli/config": ["@npmcli/config@10.8.0", "", { "dependencies": { "@npmcli/map-workspaces": "^5.0.0", "@npmcli/package-json": "^7.0.0", "ci-info": "^4.0.0", "ini": "^6.0.0", "nopt": "^9.0.0", "proc-log": "^6.0.0", "semver": "^7.3.5", "walk-up-path": "^4.0.0" }, "bundled": true }, "sha512-YkhoXZQU7zxyGi3V7J0zdK2pghzF9YXHiRdpRX8QNhsefk/zAJZJjRsbbw1hD67hlMp2gSygUGgW4y7FlrUThw=="], + + "npm/@npmcli/fs": ["@npmcli/fs@5.0.0", "", { "dependencies": { "semver": "^7.3.5" }, "bundled": true }, "sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og=="], + + "npm/@npmcli/git": ["@npmcli/git@7.0.2", "", { "dependencies": { "@gar/promise-retry": "^1.0.0", "@npmcli/promise-spawn": "^9.0.0", "ini": "^6.0.0", "lru-cache": "^11.2.1", "npm-pick-manifest": "^11.0.1", "proc-log": "^6.0.0", "semver": "^7.3.5", "which": "^6.0.0" } }, "sha512-oeolHDjExNAJAnlYP2qzNjMX/Xi9bmu78C9dIGr4xjobrSKbuMYCph8lTzn4vnW3NjIqVmw/f8BCfouqyJXlRg=="], + + "npm/@npmcli/installed-package-contents": ["@npmcli/installed-package-contents@4.0.0", "", { "dependencies": { "npm-bundled": "^5.0.0", "npm-normalize-package-bin": "^5.0.0" }, "bin": { "installed-package-contents": "bin/index.js" } }, "sha512-yNyAdkBxB72gtZ4GrwXCM0ZUedo9nIbOMKfGjt6Cu6DXf0p8y1PViZAKDC8q8kv/fufx0WTjRBdSlyrvnP7hmA=="], + + "npm/@npmcli/map-workspaces": ["@npmcli/map-workspaces@5.0.3", "", { "dependencies": { "@npmcli/name-from-folder": "^4.0.0", "@npmcli/package-json": "^7.0.0", "glob": "^13.0.0", "minimatch": "^10.0.3" }, "bundled": true }, "sha512-o2grssXo1e774E5OtEwwrgoszYRh0lqkJH+Pb9r78UcqdGJRDRfhpM8DvZPjzNLLNYeD/rNbjOKM3Ss5UABROw=="], + + "npm/@npmcli/metavuln-calculator": ["@npmcli/metavuln-calculator@9.0.3", "", { "dependencies": { "cacache": "^20.0.0", "json-parse-even-better-errors": "^5.0.0", "pacote": "^21.0.0", "proc-log": "^6.0.0", "semver": "^7.3.5" }, "bundled": true }, "sha512-94GLSYhLXF2t2LAC7pDwLaM4uCARzxShyAQKsirmlNcpidH89VA4/+K1LbJmRMgz5gy65E/QBBWQdUvGLe2Frg=="], + + "npm/@npmcli/name-from-folder": ["@npmcli/name-from-folder@4.0.0", "", {}, "sha512-qfrhVlOSqmKM8i6rkNdZzABj8MKEITGFAY+4teqBziksCQAOLutiAxM1wY2BKEd8KjUSpWmWCYxvXr0y4VTlPg=="], + + "npm/@npmcli/node-gyp": ["@npmcli/node-gyp@5.0.0", "", {}, "sha512-uuG5HZFXLfyFKqg8QypsmgLQW7smiRjVc45bqD/ofZZcR/uxEjgQU8qDPv0s9TEeMUiAAU/GC5bR6++UdTirIQ=="], + + "npm/@npmcli/package-json": ["@npmcli/package-json@7.0.5", "", { "dependencies": { "@npmcli/git": "^7.0.0", "glob": "^13.0.0", "hosted-git-info": "^9.0.0", "json-parse-even-better-errors": "^5.0.0", "proc-log": "^6.0.0", "semver": "^7.5.3", "spdx-expression-parse": "^4.0.0" }, "bundled": true }, "sha512-iVuTlG3ORq2iaVa1IWUxAO/jIp77tUKBhoMjuzYW2kL4MLN1bi/ofqkZ7D7OOwh8coAx1/S2ge0rMdGv8sLSOQ=="], + + "npm/@npmcli/promise-spawn": ["@npmcli/promise-spawn@9.0.1", "", { "dependencies": { "which": "^6.0.0" }, "bundled": true }, "sha512-OLUaoqBuyxeTqUvjA3FZFiXUfYC1alp3Sa99gW3EUDz3tZ3CbXDdcZ7qWKBzicrJleIgucoWamWH1saAmH/l2Q=="], + + "npm/@npmcli/query": ["@npmcli/query@5.0.0", "", { "dependencies": { "postcss-selector-parser": "^7.0.0" } }, "sha512-8TZWfTQOsODpLqo9SVhVjHovmKXNpevHU0gO9e+y4V4fRIOneiXy0u0sMP9LmS71XivrEWfZWg50ReH4WRT4aQ=="], + + "npm/@npmcli/redact": ["@npmcli/redact@4.0.0", "", { "bundled": true }, "sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q=="], + + "npm/@npmcli/run-script": ["@npmcli/run-script@10.0.4", "", { "dependencies": { "@npmcli/node-gyp": "^5.0.0", "@npmcli/package-json": "^7.0.0", "@npmcli/promise-spawn": "^9.0.0", "node-gyp": "^12.1.0", "proc-log": "^6.0.0" }, "bundled": true }, "sha512-mGUWr1uMnf0le2TwfOZY4SFxZGXGfm4Jtay/nwAa2FLNAKXUoUwaGwBMNH36UHPtinWfTSJ3nqFQr0091CxVGg=="], + + "npm/@sigstore/bundle": ["@sigstore/bundle@4.0.0", "", { "dependencies": { "@sigstore/protobuf-specs": "^0.5.0" } }, "sha512-NwCl5Y0V6Di0NexvkTqdoVfmjTaQwoLM236r89KEojGmq/jMls8S+zb7yOwAPdXvbwfKDlP+lmXgAL4vKSQT+A=="], + + "npm/@sigstore/core": ["@sigstore/core@3.2.0", "", {}, "sha512-kxHrDQ9YgfrWUSXU0cjsQGv8JykOFZQ9ErNKbFPWzk3Hgpwu8x2hHrQ9IdA8yl+j9RTLTC3sAF3Tdq1IQCP4oA=="], + + "npm/@sigstore/protobuf-specs": ["@sigstore/protobuf-specs@0.5.0", "", {}, "sha512-MM8XIwUjN2bwvCg1QvrMtbBmpcSHrkhFSCu1D11NyPvDQ25HEc4oG5/OcQfd/Tlf/OxmKWERDj0zGE23jQaMwA=="], + + "npm/@sigstore/sign": ["@sigstore/sign@4.1.1", "", { "dependencies": { "@gar/promise-retry": "^1.0.2", "@sigstore/bundle": "^4.0.0", "@sigstore/core": "^3.2.0", "@sigstore/protobuf-specs": "^0.5.0", "make-fetch-happen": "^15.0.4", "proc-log": "^6.1.0" } }, "sha512-Hf4xglukg0XXQ2RiD5vSoLjdPe8OBUPA8XeVjUObheuDcWdYWrnH/BNmxZCzkAy68MzmNCxXLeurJvs6hcP2OQ=="], + + "npm/@sigstore/tuf": ["@sigstore/tuf@4.0.2", "", { "dependencies": { "@sigstore/protobuf-specs": "^0.5.0", "tuf-js": "^4.1.0" }, "bundled": true }, "sha512-TCAzTy0xzdP79EnxSjq9KQ3eaR7+FmudLC6eRKknVKZbV7ZNlGLClAAQb/HMNJ5n2OBNk2GT1tEmU0xuPr+SLQ=="], + + "npm/@sigstore/verify": ["@sigstore/verify@3.1.0", "", { "dependencies": { "@sigstore/bundle": "^4.0.0", "@sigstore/core": "^3.1.0", "@sigstore/protobuf-specs": "^0.5.0" } }, "sha512-mNe0Iigql08YupSOGv197YdHpPPr+EzDZmfCgMc7RPNaZTw5aLN01nBl6CHJOh3BGtnMIj83EeN4butBchc8Ag=="], + + "npm/@tufjs/canonical-json": ["@tufjs/canonical-json@2.0.0", "", {}, "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA=="], + + "npm/@tufjs/models": ["@tufjs/models@4.1.0", "", { "dependencies": { "@tufjs/canonical-json": "2.0.0", "minimatch": "^10.1.1" } }, "sha512-Y8cK9aggNRsqJVaKUlEYs4s7CvQ1b1ta2DVPyAimb0I2qhzjNk+A+mxvll/klL0RlfuIUei8BF7YWiua4kQqww=="], + + "npm/abbrev": ["abbrev@4.0.0", "", { "bundled": true }, "sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA=="], + + "npm/agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + + "npm/aproba": ["aproba@2.1.0", "", {}, "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew=="], + + "npm/archy": ["archy@1.0.0", "", { "bundled": true }, "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw=="], + + "npm/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + + "npm/bin-links": ["bin-links@6.0.0", "", { "dependencies": { "cmd-shim": "^8.0.0", "npm-normalize-package-bin": "^5.0.0", "proc-log": "^6.0.0", "read-cmd-shim": "^6.0.0", "write-file-atomic": "^7.0.0" } }, "sha512-X4CiKlcV2GjnCMwnKAfbVWpHa++65th9TuzAEYtZoATiOE2DQKhSp4CJlyLoTqdhBKlXjpXjCTYPNNFS33Fi6w=="], + + "npm/binary-extensions": ["binary-extensions@3.1.0", "", {}, "sha512-Jvvd9hy1w+xUad8+ckQsWA/V1AoyubOvqn0aygjMOVM4BfIaRav1NFS3LsTSDaV4n4FtcCtQXvzep1E6MboqwQ=="], + + "npm/brace-expansion": ["brace-expansion@5.0.4", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg=="], + + "npm/cacache": ["cacache@20.0.4", "", { "dependencies": { "@npmcli/fs": "^5.0.0", "fs-minipass": "^3.0.0", "glob": "^13.0.0", "lru-cache": "^11.1.0", "minipass": "^7.0.3", "minipass-collect": "^2.0.1", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "p-map": "^7.0.2", "ssri": "^13.0.0" }, "bundled": true }, "sha512-M3Lab8NPYlZU2exsL3bMVvMrMqgwCnMWfdZbK28bn3pK6APT/Te/I8hjRPNu1uwORY9a1eEQoifXbKPQMfMTOA=="], + + "npm/chalk": ["chalk@5.6.2", "", { "bundled": true }, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], + + "npm/chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], + + "npm/ci-info": ["ci-info@4.4.0", "", { "bundled": true }, "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg=="], + + "npm/cidr-regex": ["cidr-regex@5.0.3", "", {}, "sha512-zfPT2uurEroxXqefaL2L7/fT5ED2XTutC6UwFbSZfqSOk1vk5VFY6xa6/R6pBxB4Uc8MNPbRW5ykqutFG5P5ww=="], + + "npm/cmd-shim": ["cmd-shim@8.0.0", "", {}, "sha512-Jk/BK6NCapZ58BKUxlSI+ouKRbjH1NLZCgJkYoab+vEHUY3f6OzpNBN9u7HFSv9J6TRDGs4PLOHezoKGaFRSCA=="], + + "npm/common-ancestor-path": ["common-ancestor-path@2.0.0", "", {}, "sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng=="], + + "npm/cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="], + + "npm/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + + "npm/diff": ["diff@8.0.3", "", {}, "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ=="], + + "npm/env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], + + "npm/exponential-backoff": ["exponential-backoff@3.1.3", "", {}, "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA=="], + + "npm/fastest-levenshtein": ["fastest-levenshtein@1.0.16", "", { "bundled": true }, "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg=="], + + "npm/fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + + "npm/fs-minipass": ["fs-minipass@3.0.3", "", { "dependencies": { "minipass": "^7.0.3" }, "bundled": true }, "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw=="], + + "npm/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" }, "bundled": true }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], + + "npm/graceful-fs": ["graceful-fs@4.2.11", "", { "bundled": true }, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], + + "npm/hosted-git-info": ["hosted-git-info@9.0.2", "", { "dependencies": { "lru-cache": "^11.1.0" }, "bundled": true }, "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg=="], + + "npm/http-cache-semantics": ["http-cache-semantics@4.2.0", "", {}, "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ=="], + + "npm/http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="], + + "npm/https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], + + "npm/iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="], + + "npm/ignore-walk": ["ignore-walk@8.0.0", "", { "dependencies": { "minimatch": "^10.0.3" } }, "sha512-FCeMZT4NiRQGh+YkeKMtWrOmBgWjHjMJ26WQWrRQyoyzqevdaGSakUaJW5xQYmjLlUVk2qUnCjYVBax9EKKg8A=="], + + "npm/ini": ["ini@6.0.0", "", { "bundled": true }, "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ=="], + + "npm/init-package-json": ["init-package-json@8.2.5", "", { "dependencies": { "@npmcli/package-json": "^7.0.0", "npm-package-arg": "^13.0.0", "promzard": "^3.0.1", "read": "^5.0.1", "semver": "^7.7.2", "validate-npm-package-name": "^7.0.0" }, "bundled": true }, "sha512-IknQ+upLuJU6t3p0uo9wS3GjFD/1GtxIwcIGYOWR8zL2HxQeJwvxYTgZr9brJ8pyZ4kvpkebM8ZKcyqOeLOHSg=="], + + "npm/ip-address": ["ip-address@10.1.0", "", {}, "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q=="], + + "npm/is-cidr": ["is-cidr@6.0.3", "", { "dependencies": { "cidr-regex": "^5.0.1" }, "bundled": true }, "sha512-tPdsizbDiISrc4PoII6ZfpmAokx0oDKeYqAUp5bXOfznauOFXfEeosKBRrl0o0SriE4xoRR05Czn4YPCFMjSHA=="], + + "npm/isexe": ["isexe@4.0.0", "", {}, "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw=="], + + "npm/json-parse-even-better-errors": ["json-parse-even-better-errors@5.0.0", "", { "bundled": true }, "sha512-ZF1nxZ28VhQouRWhUcVlUIN3qwSgPuswK05s/HIaoetAoE/9tngVmCHjSxmSQPav1nd+lPtTL0YZ/2AFdR/iYQ=="], + + "npm/json-stringify-nice": ["json-stringify-nice@1.1.4", "", {}, "sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw=="], + + "npm/jsonparse": ["jsonparse@1.3.1", "", {}, "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg=="], + + "npm/just-diff": ["just-diff@6.0.2", "", {}, "sha512-S59eriX5u3/QhMNq3v/gm8Kd0w8OS6Tz2FS1NG4blv+z0MuQcBRJyFWjdovM0Rad4/P4aUPFtnkNjMjyMlMSYA=="], + + "npm/just-diff-apply": ["just-diff-apply@5.5.0", "", {}, "sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw=="], + + "npm/libnpmaccess": ["libnpmaccess@10.0.3", "", { "dependencies": { "npm-package-arg": "^13.0.0", "npm-registry-fetch": "^19.0.0" }, "bundled": true }, "sha512-JPHTfWJxIK+NVPdNMNGnkz4XGX56iijPbe0qFWbdt68HL+kIvSzh+euBL8npLZvl2fpaxo+1eZSdoG15f5YdIQ=="], + + "npm/libnpmdiff": ["libnpmdiff@8.1.5", "", { "dependencies": { "@npmcli/arborist": "^9.4.2", "@npmcli/installed-package-contents": "^4.0.0", "binary-extensions": "^3.0.0", "diff": "^8.0.2", "minimatch": "^10.0.3", "npm-package-arg": "^13.0.0", "pacote": "^21.0.2", "tar": "^7.5.1" }, "bundled": true }, "sha512-3tknN/GosDOpIYjBplXpr7WVjpBDodAxXkZEtv410XlIsfMD+v/6mt9sYe/s/x+TRmmCRpzP/bxfhUorvV6Cqg=="], + + "npm/libnpmexec": ["libnpmexec@10.2.5", "", { "dependencies": { "@gar/promise-retry": "^1.0.0", "@npmcli/arborist": "^9.4.2", "@npmcli/package-json": "^7.0.0", "@npmcli/run-script": "^10.0.0", "ci-info": "^4.0.0", "npm-package-arg": "^13.0.0", "pacote": "^21.0.2", "proc-log": "^6.0.0", "read": "^5.0.1", "semver": "^7.3.7", "signal-exit": "^4.1.0", "walk-up-path": "^4.0.0" }, "bundled": true }, "sha512-ayouyoml/4NmcgH+nWzK6QB5w0gKrftsYB8TAHu5TB5v6Nj3fgz8ZBK9FsG2A1SNuHZVTjvrNMDyF2VzDih/bA=="], + + "npm/libnpmfund": ["libnpmfund@7.0.19", "", { "dependencies": { "@npmcli/arborist": "^9.4.2" }, "bundled": true }, "sha512-RNyp5gnjVXaqlx0asRLmAOrFkTwANntzqkRyTT6Iu2nUt1F2eiMZNMOpO2HNfA7/NceBVBk/xsrzas3miCz9oQ=="], + + "npm/libnpmorg": ["libnpmorg@8.0.1", "", { "dependencies": { "aproba": "^2.0.0", "npm-registry-fetch": "^19.0.0" }, "bundled": true }, "sha512-/QeyXXg4hqMw0ESM7pERjIT2wbR29qtFOWIOug/xO4fRjS3jJJhoAPQNsnHtdwnCqgBdFpGQ45aIdFFZx2YhTA=="], + + "npm/libnpmpack": ["libnpmpack@9.1.5", "", { "dependencies": { "@npmcli/arborist": "^9.4.2", "@npmcli/run-script": "^10.0.0", "npm-package-arg": "^13.0.0", "pacote": "^21.0.2" }, "bundled": true }, "sha512-H1IX364ZwpeRfrL6UYSuxFNgP16/TvlwtCm8ZallbB7/1FZ3h1FBZHamQtv7PqcZUTWE27mygdQ4wCCW2BmVlg=="], + + "npm/libnpmpublish": ["libnpmpublish@11.1.3", "", { "dependencies": { "@npmcli/package-json": "^7.0.0", "ci-info": "^4.0.0", "npm-package-arg": "^13.0.0", "npm-registry-fetch": "^19.0.0", "proc-log": "^6.0.0", "semver": "^7.3.7", "sigstore": "^4.0.0", "ssri": "^13.0.0" }, "bundled": true }, "sha512-NVPTth/71cfbdYHqypcO9Lt5WFGTzFEcx81lWd7GDJIgZ95ERdYHGUfCtFejHCyqodKsQkNEx2JCkMpreDty/A=="], + + "npm/libnpmsearch": ["libnpmsearch@9.0.1", "", { "dependencies": { "npm-registry-fetch": "^19.0.0" }, "bundled": true }, "sha512-oKw58X415ERY/BOGV3jQPVMcep8YeMRWMzuuqB0BAIM5VxicOU1tQt19ExCu4SV77SiTOEoziHxGEgJGw3FBYQ=="], + + "npm/libnpmteam": ["libnpmteam@8.0.2", "", { "dependencies": { "aproba": "^2.0.0", "npm-registry-fetch": "^19.0.0" }, "bundled": true }, "sha512-ypLrDUQoi8EhG+gzx5ENMcYq23YjPV17Mfvx4nOnQiHOi8vp47+4GvZBrMsEM4yeHPwxguF/HZoXH4rJfHdH/w=="], + + "npm/libnpmversion": ["libnpmversion@8.0.3", "", { "dependencies": { "@npmcli/git": "^7.0.0", "@npmcli/run-script": "^10.0.0", "json-parse-even-better-errors": "^5.0.0", "proc-log": "^6.0.0", "semver": "^7.3.7" }, "bundled": true }, "sha512-Avj1GG3DT6MGzWOOk3yA7rORcMDUPizkIGbI8glHCO7WoYn3NYNmskLDwxg2NMY1Tyf2vrHAqTuSG58uqd1lJg=="], + + "npm/lru-cache": ["lru-cache@11.2.7", "", {}, "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA=="], + + "npm/make-fetch-happen": ["make-fetch-happen@15.0.5", "", { "dependencies": { "@gar/promise-retry": "^1.0.0", "@npmcli/agent": "^4.0.0", "@npmcli/redact": "^4.0.0", "cacache": "^20.0.1", "http-cache-semantics": "^4.1.1", "minipass": "^7.0.2", "minipass-fetch": "^5.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^1.0.0", "proc-log": "^6.0.0", "ssri": "^13.0.0" }, "bundled": true }, "sha512-uCbIa8jWWmQZt4dSnEStkVC6gdakiinAm4PiGsywIkguF0eWMdcjDz0ECYhUolFU3pFLOev9VNPCEygydXnddg=="], + + "npm/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" }, "bundled": true }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="], + + "npm/minipass": ["minipass@7.1.3", "", { "bundled": true }, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], + + "npm/minipass-collect": ["minipass-collect@2.0.1", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw=="], + + "npm/minipass-fetch": ["minipass-fetch@5.0.2", "", { "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^2.0.0", "minizlib": "^3.0.1" }, "optionalDependencies": { "iconv-lite": "^0.7.2" } }, "sha512-2d0q2a8eCi2IRg/IGubCNRJoYbA1+YPXAzQVRFmB45gdGZafyivnZ5YSEfo3JikbjGxOdntGFvBQGqaSMXlAFQ=="], + + "npm/minipass-flush": ["minipass-flush@1.0.5", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw=="], + + "npm/minipass-pipeline": ["minipass-pipeline@1.2.4", "", { "dependencies": { "minipass": "^3.0.0" }, "bundled": true }, "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A=="], + + "npm/minipass-sized": ["minipass-sized@2.0.0", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-zSsHhto5BcUVM2m1LurnXY6M//cGhVaegT71OfOXoprxT6o780GZd792ea6FfrQkuU4usHZIUczAQMRUE2plzA=="], + + "npm/minizlib": ["minizlib@3.1.0", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw=="], + + "npm/ms": ["ms@2.1.3", "", { "bundled": true }, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "npm/mute-stream": ["mute-stream@3.0.0", "", {}, "sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw=="], + + "npm/negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], + + "npm/node-gyp": ["node-gyp@12.2.0", "", { "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", "graceful-fs": "^4.2.6", "make-fetch-happen": "^15.0.0", "nopt": "^9.0.0", "proc-log": "^6.0.0", "semver": "^7.3.5", "tar": "^7.5.4", "tinyglobby": "^0.2.12", "which": "^6.0.0" }, "bundled": true, "bin": { "node-gyp": "bin/node-gyp.js" } }, "sha512-q23WdzrQv48KozXlr0U1v9dwO/k59NHeSzn6loGcasyf0UnSrtzs8kRxM+mfwJSf0DkX0s43hcqgnSO4/VNthQ=="], + + "npm/nopt": ["nopt@9.0.0", "", { "dependencies": { "abbrev": "^4.0.0" }, "bundled": true, "bin": { "nopt": "bin/nopt.js" } }, "sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw=="], + + "npm/npm-audit-report": ["npm-audit-report@7.0.0", "", { "bundled": true }, "sha512-bluLL4xwGr/3PERYz50h2Upco0TJMDcLcymuFnfDWeGO99NqH724MNzhWi5sXXuXf2jbytFF0LyR8W+w1jTI6A=="], + + "npm/npm-bundled": ["npm-bundled@5.0.0", "", { "dependencies": { "npm-normalize-package-bin": "^5.0.0" } }, "sha512-JLSpbzh6UUXIEoqPsYBvVNVmyrjVZ1fzEFbqxKkTJQkWBO3xFzFT+KDnSKQWwOQNbuWRwt5LSD6HOTLGIWzfrw=="], + + "npm/npm-install-checks": ["npm-install-checks@8.0.0", "", { "dependencies": { "semver": "^7.1.1" }, "bundled": true }, "sha512-ScAUdMpyzkbpxoNekQ3tNRdFI8SJ86wgKZSQZdUxT+bj0wVFpsEMWnkXP0twVe1gJyNF5apBWDJhhIbgrIViRA=="], + + "npm/npm-normalize-package-bin": ["npm-normalize-package-bin@5.0.0", "", {}, "sha512-CJi3OS4JLsNMmr2u07OJlhcrPxCeOeP/4xq67aWNai6TNWWbTrlNDgl8NcFKVlcBKp18GPj+EzbNIgrBfZhsag=="], + + "npm/npm-package-arg": ["npm-package-arg@13.0.2", "", { "dependencies": { "hosted-git-info": "^9.0.0", "proc-log": "^6.0.0", "semver": "^7.3.5", "validate-npm-package-name": "^7.0.0" }, "bundled": true }, "sha512-IciCE3SY3uE84Ld8WZU23gAPPV9rIYod4F+rc+vJ7h7cwAJt9Vk6TVsK60ry7Uj3SRS3bqRRIGuTp9YVlk6WNA=="], + + "npm/npm-packlist": ["npm-packlist@10.0.4", "", { "dependencies": { "ignore-walk": "^8.0.0", "proc-log": "^6.0.0" } }, "sha512-uMW73iajD8hiH4ZBxEV3HC+eTnppIqwakjOYuvgddnalIw2lJguKviK1pcUJDlIWm1wSJkchpDZDSVVsZEYRng=="], + + "npm/npm-pick-manifest": ["npm-pick-manifest@11.0.3", "", { "dependencies": { "npm-install-checks": "^8.0.0", "npm-normalize-package-bin": "^5.0.0", "npm-package-arg": "^13.0.0", "semver": "^7.3.5" }, "bundled": true }, "sha512-buzyCfeoGY/PxKqmBqn1IUJrZnUi1VVJTdSSRPGI60tJdUhUoSQFhs0zycJokDdOznQentgrpf8LayEHyyYlqQ=="], + + "npm/npm-profile": ["npm-profile@12.0.1", "", { "dependencies": { "npm-registry-fetch": "^19.0.0", "proc-log": "^6.0.0" }, "bundled": true }, "sha512-Xs1mejJ1/9IKucCxdFMkiBJUre0xaxfCpbsO7DB7CadITuT4k68eI05HBlw4kj+Em1rsFMgeFNljFPYvPETbVQ=="], + + "npm/npm-registry-fetch": ["npm-registry-fetch@19.1.1", "", { "dependencies": { "@npmcli/redact": "^4.0.0", "jsonparse": "^1.3.1", "make-fetch-happen": "^15.0.0", "minipass": "^7.0.2", "minipass-fetch": "^5.0.0", "minizlib": "^3.0.1", "npm-package-arg": "^13.0.0", "proc-log": "^6.0.0" }, "bundled": true }, "sha512-TakBap6OM1w0H73VZVDf44iFXsOS3h+L4wVMXmbWOQroZgFhMch0juN6XSzBNlD965yIKvWg2dfu7NSiaYLxtw=="], + + "npm/npm-user-validate": ["npm-user-validate@4.0.0", "", { "bundled": true }, "sha512-TP+Ziq/qPi/JRdhaEhnaiMkqfMGjhDLoh/oRfW+t5aCuIfJxIUxvwk6Sg/6ZJ069N/Be6gs00r+aZeJTfS9uHQ=="], + + "npm/p-map": ["p-map@7.0.4", "", { "bundled": true }, "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ=="], + + "npm/pacote": ["pacote@21.5.0", "", { "dependencies": { "@gar/promise-retry": "^1.0.0", "@npmcli/git": "^7.0.0", "@npmcli/installed-package-contents": "^4.0.0", "@npmcli/package-json": "^7.0.0", "@npmcli/promise-spawn": "^9.0.0", "@npmcli/run-script": "^10.0.0", "cacache": "^20.0.0", "fs-minipass": "^3.0.0", "minipass": "^7.0.2", "npm-package-arg": "^13.0.0", "npm-packlist": "^10.0.1", "npm-pick-manifest": "^11.0.1", "npm-registry-fetch": "^19.0.0", "proc-log": "^6.0.0", "sigstore": "^4.0.0", "ssri": "^13.0.0", "tar": "^7.4.3" }, "bundled": true, "bin": { "pacote": "bin/index.js" } }, "sha512-VtZ0SB8mb5Tzw3dXDfVAIjhyVKUHZkS/ZH9/5mpKenwC9sFOXNI0JI7kEF7IMkwOnsWMFrvAZHzx1T5fmrp9FQ=="], + + "npm/parse-conflict-json": ["parse-conflict-json@5.0.1", "", { "dependencies": { "json-parse-even-better-errors": "^5.0.0", "just-diff": "^6.0.0", "just-diff-apply": "^5.2.0" }, "bundled": true }, "sha512-ZHEmNKMq1wyJXNwLxyHnluPfRAFSIliBvbK/UiOceROt4Xh9Pz0fq49NytIaeaCUf5VR86hwQ/34FCcNU5/LKQ=="], + + "npm/path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="], + + "npm/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], + + "npm/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="], + + "npm/proc-log": ["proc-log@6.1.0", "", { "bundled": true }, "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ=="], + + "npm/proggy": ["proggy@4.0.0", "", {}, "sha512-MbA4R+WQT76ZBm/5JUpV9yqcJt92175+Y0Bodg3HgiXzrmKu7Ggq+bpn6y6wHH+gN9NcyKn3yg1+d47VaKwNAQ=="], + + "npm/promise-all-reject-late": ["promise-all-reject-late@1.0.1", "", {}, "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw=="], + + "npm/promise-call-limit": ["promise-call-limit@3.0.2", "", {}, "sha512-mRPQO2T1QQVw11E7+UdCJu7S61eJVWknzml9sC1heAdj1jxl0fWMBypIt9ZOcLFf8FkG995ZD7RnVk7HH72fZw=="], + + "npm/promzard": ["promzard@3.0.1", "", { "dependencies": { "read": "^5.0.0" } }, "sha512-M5mHhWh+Adz0BIxgSrqcc6GTCSconR7zWQV9vnOSptNtr6cSFlApLc28GbQhuN6oOWBQeV2C0bNE47JCY/zu3Q=="], + + "npm/qrcode-terminal": ["qrcode-terminal@0.12.0", "", { "bundled": true, "bin": { "qrcode-terminal": "./bin/qrcode-terminal.js" } }, "sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ=="], + + "npm/read": ["read@5.0.1", "", { "dependencies": { "mute-stream": "^3.0.0" }, "bundled": true }, "sha512-+nsqpqYkkpet2UVPG8ZiuE8d113DK4vHYEoEhcrXBAlPiq6di7QRTuNiKQAbaRYegobuX2BpZ6QjanKOXnJdTA=="], + + "npm/read-cmd-shim": ["read-cmd-shim@6.0.0", "", {}, "sha512-1zM5HuOfagXCBWMN83fuFI/x+T/UhZ7k+KIzhrHXcQoeX5+7gmaDYjELQHmmzIodumBHeByBJT4QYS7ufAgs7A=="], + + "npm/safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], + + "npm/semver": ["semver@7.7.4", "", { "bundled": true, "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], + + "npm/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + + "npm/sigstore": ["sigstore@4.1.0", "", { "dependencies": { "@sigstore/bundle": "^4.0.0", "@sigstore/core": "^3.1.0", "@sigstore/protobuf-specs": "^0.5.0", "@sigstore/sign": "^4.1.0", "@sigstore/tuf": "^4.0.1", "@sigstore/verify": "^3.1.0" } }, "sha512-/fUgUhYghuLzVT/gaJoeVehLCgZiUxPCPMcyVNY0lIf/cTCz58K/WTI7PefDarXxp9nUKpEwg1yyz3eSBMTtgA=="], + + "npm/smart-buffer": ["smart-buffer@4.2.0", "", {}, "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="], + + "npm/socks": ["socks@2.8.7", "", { "dependencies": { "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" } }, "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A=="], + + "npm/socks-proxy-agent": ["socks-proxy-agent@8.0.5", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" } }, "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw=="], + + "npm/spdx-exceptions": ["spdx-exceptions@2.5.0", "", {}, "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w=="], + + "npm/spdx-expression-parse": ["spdx-expression-parse@4.0.0", "", { "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" }, "bundled": true }, "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ=="], + + "npm/spdx-license-ids": ["spdx-license-ids@3.0.23", "", {}, "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw=="], + + "npm/ssri": ["ssri@13.0.1", "", { "dependencies": { "minipass": "^7.0.3" }, "bundled": true }, "sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ=="], + + "npm/supports-color": ["supports-color@10.2.2", "", { "bundled": true }, "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g=="], + + "npm/tar": ["tar@7.5.12", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" }, "bundled": true }, "sha512-9TsuLcdhOn4XztcQqhNyq1KOwOOED/3k58JAvtULiYqbO8B/0IBAAIE1hj0Svmm58k27TmcigyDI0deMlgG3uw=="], + + "npm/text-table": ["text-table@0.2.0", "", { "bundled": true }, "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw=="], + + "npm/tiny-relative-date": ["tiny-relative-date@2.0.2", "", { "bundled": true }, "sha512-rGxAbeL9z3J4pI2GtBEoFaavHdO4RKAU54hEuOef5kfx5aPqiQtbhYktMOTL5OA33db8BjsDcLXuNp+/v19PHw=="], + + "npm/tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], + + "npm/treeverse": ["treeverse@3.0.0", "", { "bundled": true }, "sha512-gcANaAnd2QDZFmHFEOF4k7uc1J/6a6z3DJMd/QwEyxLoKGiptJRwid582r7QIsFlFMIZ3SnxfS52S4hm2DHkuQ=="], + + "npm/tuf-js": ["tuf-js@4.1.0", "", { "dependencies": { "@tufjs/models": "4.1.0", "debug": "^4.4.3", "make-fetch-happen": "^15.0.1" } }, "sha512-50QV99kCKH5P/Vs4E2Gzp7BopNV+KzTXqWeaxrfu5IQJBOULRsTIS9seSsOVT8ZnGXzCyx55nYWAi4qJzpZKEQ=="], + + "npm/util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], + + "npm/validate-npm-package-name": ["validate-npm-package-name@7.0.2", "", { "bundled": true }, "sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A=="], + + "npm/walk-up-path": ["walk-up-path@4.0.0", "", {}, "sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A=="], + + "npm/which": ["which@6.0.1", "", { "dependencies": { "isexe": "^4.0.0" }, "bundled": true, "bin": { "node-which": "bin/which.js" } }, "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg=="], + + "npm/write-file-atomic": ["write-file-atomic@7.0.1", "", { "dependencies": { "signal-exit": "^4.0.1" } }, "sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg=="], + + "npm/yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], + + "npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], + + "npm-run-path/unicorn-magic": ["unicorn-magic@0.3.0", "", {}, "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA=="], + + "parse5-htmlparser2-tree-adapter/parse5": ["parse5@6.0.1", "", {}, "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="], + + "read-pkg/parse-json": ["parse-json@8.3.0", "", { "dependencies": { "@babel/code-frame": "^7.26.2", "index-to-position": "^1.1.0", "type-fest": "^4.39.1" } }, "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ=="], + + "signale/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="], + + "signale/figures": ["figures@2.0.0", "", { "dependencies": { "escape-string-regexp": "^1.0.5" } }, "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA=="], + + "tempy/is-stream": ["is-stream@3.0.0", "", {}, "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA=="], + + "tempy/type-fest": ["type-fest@2.19.0", "", {}, "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA=="], + + "tinyglobby/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], + + "wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], + + "@semantic-release/release-notes-generator/read-package-up/read-pkg": ["read-pkg@9.0.1", "", { "dependencies": { "@types/normalize-package-data": "^2.4.3", "normalize-package-data": "^6.0.0", "parse-json": "^8.0.0", "type-fest": "^4.6.0", "unicorn-magic": "^0.1.0" } }, "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA=="], + + "@semantic-release/release-notes-generator/read-package-up/type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="], + + "cli-highlight/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + + "cli-highlight/yargs/cliui": ["cliui@7.0.4", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ=="], + + "cli-highlight/yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + + "cli-highlight/yargs/yargs-parser": ["yargs-parser@20.2.9", "", {}, "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w=="], + + "cli-table3/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + + "cli-table3/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "env-ci/execa/get-stream": ["get-stream@8.0.1", "", {}, "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA=="], + + "env-ci/execa/human-signals": ["human-signals@5.0.0", "", {}, "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ=="], + + "env-ci/execa/is-stream": ["is-stream@3.0.0", "", {}, "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA=="], + + "env-ci/execa/npm-run-path": ["npm-run-path@5.3.0", "", { "dependencies": { "path-key": "^4.0.0" } }, "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ=="], + + "env-ci/execa/strip-final-newline": ["strip-final-newline@3.0.0", "", {}, "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw=="], + + "npm/minipass-flush/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "npm/minipass-pipeline/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "read-pkg/parse-json/type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="], + + "signale/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], + + "signale/chalk/supports-color": ["supports-color@5.5.0", "", { "dependencies": { "has-flag": "^3.0.0" } }, "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="], + + "signale/figures/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], + + "@semantic-release/release-notes-generator/read-package-up/read-pkg/normalize-package-data": ["normalize-package-data@6.0.2", "", { "dependencies": { "hosted-git-info": "^7.0.0", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4" } }, "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g=="], + + "@semantic-release/release-notes-generator/read-package-up/read-pkg/parse-json": ["parse-json@8.3.0", "", { "dependencies": { "@babel/code-frame": "^7.26.2", "index-to-position": "^1.1.0", "type-fest": "^4.39.1" } }, "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ=="], + + "@semantic-release/release-notes-generator/read-package-up/read-pkg/unicorn-magic": ["unicorn-magic@0.1.0", "", {}, "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ=="], + + "cli-highlight/chalk/ansi-styles/color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], + + "cli-highlight/yargs/cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "cli-highlight/yargs/cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + + "cli-highlight/yargs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + + "cli-highlight/yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "cli-table3/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "env-ci/execa/npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], + + "npm/minipass-flush/minipass/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + + "npm/minipass-pipeline/minipass/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + + "signale/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="], + + "@semantic-release/release-notes-generator/read-package-up/read-pkg/normalize-package-data/hosted-git-info": ["hosted-git-info@7.0.2", "", { "dependencies": { "lru-cache": "^10.0.1" } }, "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w=="], + + "cli-highlight/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + + "cli-highlight/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "cli-highlight/yargs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + + "cli-highlight/yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "@semantic-release/release-notes-generator/read-package-up/read-pkg/normalize-package-data/hosted-git-info/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + + "cli-highlight/yargs/cliui/wrap-ansi/ansi-styles/color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], + + "cli-highlight/yargs/cliui/wrap-ansi/ansi-styles/color-convert/color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], } } diff --git a/docs/adrs/003.release-process.semantic-release.md b/docs/adrs/003.release-process.semantic-release.md index 41dd3d6..ad4d731 100644 --- a/docs/adrs/003.release-process.semantic-release.md +++ b/docs/adrs/003.release-process.semantic-release.md @@ -10,45 +10,41 @@ wtty has a stub release workflow (`.github/workflows/release.yml`) that runs `bun run build` then `echo "TODO - publish step"`. No versioning, no published artifacts. -wtty is distributed as a standalone binary — not published to npm (`"private": true`). A release means a GitHub Release with platform-specific binary artifacts attached. The version should be derived automatically from what changed, not set manually. +wtty targets developers who already have Node.js or Bun installed. Distribution via `npx wtty` is the natural fit — no binary downloads, no install step beyond what developers already have. A release means a GitHub Release with a git tag and release notes. The version should be derived automatically from what changed, not set manually. -The cfx repo solved the same versioning problem with semantic-release (ADR 004): conventional commit prefixes in PR/MR titles drive version bumps post-merge, git tags are the sole version record, no release commits. That pattern maps cleanly to wtty with one difference: instead of `@semantic-release/npm`, the publish step is `@semantic-release/github` with binary assets. +The cfx repo solved the same versioning problem with semantic-release (ADR 004): conventional commit prefixes in PR/MR titles drive version bumps post-merge, git tags are the sole version record, no release commits. That pattern maps directly to wtty. ## Decision -Use **semantic-release** with `@semantic-release/github`, running post-merge on `main`. Developers write a conventional commit prefix in the PR title. GitHub squash merge uses the PR title as the commit message on `main`. semantic-release reads that message, determines the version bump, creates a GitHub Release with release notes, and attaches pre-built binaries. No manual versioning, no release commits, no extra files per PR. +Use **semantic-release** with `@semantic-release/github`, running post-merge on `main`. Developers write a conventional commit prefix in the PR title. GitHub squash merge uses the PR title as the commit message on `main`. semantic-release reads that message, determines the version bump, creates a GitHub Release with release notes, and pushes a git tag. No manual versioning, no release commits, no extra files per PR. ## Considered Options ### Option A: semantic-release post-merge on main, tag-only (chosen) -- **Pros**: Zero developer overhead beyond PR title. GitHub Release + binary upload fully automated. Battle-tested. No version conflicts between concurrent PRs. No release commits — clean one-commit-per-PR history on `main`. No branch push permissions needed (only tag push). `GITHUB_TOKEN` is provided automatically — no secrets to configure. +- **Pros**: Zero developer overhead beyond PR title. GitHub Release + release notes fully automated. Battle-tested. No version conflicts between concurrent PRs. No release commits — clean one-commit-per-PR history on `main`. `GITHUB_TOKEN` is provided automatically — no secrets to configure. - **Cons**: `package.json` version doesn't reflect the released version (use `0.0.0-development` placeholder). No in-repo `CHANGELOG.md` (release notes live on GitHub Releases). Requires conventional commit discipline in PR titles (mitigate: squash merge uses PR title — one line to get right). ### Option B: Manual GitHub Release -Create GitHub Releases manually — edit the release notes, attach binaries by hand, tag manually. - -- **Pros**: Full control over release notes. No tooling to configure. -- **Cons**: Manual — error-prone, inconsistent, easy to forget. Version tracking relies on human discipline. Doesn't scale. +- **Pros**: Full control over release notes. No tooling. +- **Cons**: Manual — error-prone, inconsistent, easy to forget. ### Option C: release-it -release-it (used in cfx ADR 006) supports GitHub releases natively and has a simpler config surface than semantic-release. - -- **Pros**: Simpler per-package config, base version frozen on prerelease. -- **Cons**: wtty has no prerelease channel need (the main reason cfx switched to release-it). semantic-release's automatic version derivation from commit type is the better fit here — release-it requires either a manual bump type or more config to replicate the same behavior. +- **Pros**: Simpler config surface, base version frozen on prerelease. +- **Cons**: wtty has no prerelease channel need. semantic-release's automatic version derivation from commit type is the better fit — release-it requires a manual bump type or extra config to replicate this. ### Option D: Changesets - **Pros**: Human-written changelogs, 1 dependency. -- **Cons**: Extra file per PR, developer must run `npx changeset`, changeset summary duplicates PR title. Same reasons rejected in cfx ADR 004. +- **Cons**: Extra file per PR, developer must run `npx changeset`, duplicates PR title. Same reasons rejected in cfx ADR 004. ## Consequences -**Good**: Zero developer overhead — write a conventional PR title, everything else is automated. GitHub Release auto-created with release notes. Binary artifacts attached. Clean `main` history — one commit per PR, no interleaved release commits. `GITHUB_TOKEN` is automatic — no manual secret setup. Follows semantic-release's own recommended approach (tag-only, no commit-back). +**Good**: Zero developer overhead — write a conventional PR title, everything else is automated. GitHub Release auto-created with release notes. Clean `main` history. `GITHUB_TOKEN` is automatic. Follows semantic-release's own recommended approach (tag-only, no commit-back). -**Bad**: `package.json` version stays at `0.0.0-development` — doesn't reflect the released version. No `CHANGELOG.md` in repo (release notes on GitHub Releases). Requires conventional commit discipline in PR titles. +**Bad**: `package.json` version stays at `0.0.0-development`. No `CHANGELOG.md` in repo. Requires conventional commit discipline in PR titles. ## Implementation Notes @@ -61,23 +57,24 @@ release-it (used in cfx ADR 006) supports GitHub releases natively and has a sim "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", - ["@semantic-release/github", { "assets": ["dist/wtty-*"] }] + "@semantic-release/github" ] } ``` -`@semantic-release/commit-analyzer`, `@semantic-release/release-notes-generator`, and `@semantic-release/github` are all bundled with `semantic-release` — no additional plugin packages needed. `@semantic-release/git` and `@semantic-release/changelog` are intentionally omitted (tag-only). +All three plugins are bundled with `semantic-release` — no additional packages needed. `@semantic-release/git` and `@semantic-release/changelog` intentionally omitted (tag-only). ### Release Workflow ```yaml -# .github/workflows/release.yml on: push: branches: [main] jobs: release: runs-on: ubuntu-latest + permissions: + contents: write steps: - uses: actions/checkout@v4 with: @@ -88,33 +85,24 @@ jobs: bun-version: 1.3.10 - run: bun install --frozen-lockfile - run: bun run build - - name: Build platform binaries - run: bun run build:binaries - name: Release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: bunx semantic-release ``` -- `fetch-depth: 0` — full clone so semantic-release can walk commit history to find previous tags +- `fetch-depth: 0` — semantic-release needs full git history to find previous tags - `persist-credentials: false` — semantic-release manages its own git auth via `GITHUB_TOKEN` -- Binary build precedes the release step so assets exist before `@semantic-release/github` uploads them +- `permissions: contents: write` — `GITHUB_TOKEN` needs to push tags and create releases ### Why Tag-Only (No Release Commits) -semantic-release's own FAQ recommends against committing during release. Omitting `@semantic-release/git` and `@semantic-release/changelog`: - -- **No branch push permissions needed** — `GITHUB_TOKEN` only needs to push tags and create releases -- **Clean history** — one commit per PR, no interleaved `chore(release):` commits -- **No `[skip ci]` dance** — no recursive pipeline triggering -- **Fewer dependencies** — 1 devDependency (`semantic-release`) instead of 3+ - -### GitHub Repository Settings +Omitting `@semantic-release/git` and `@semantic-release/changelog`: -| Setting | Value | Why | -|---------|-------|-----| -| Squash merging | Enabled | PR title becomes the commit semantic-release reads | -| Workflow permissions | Read and write | `GITHUB_TOKEN` needs to push tags and create releases | +- No branch push permissions needed — `GITHUB_TOKEN` only needs to push tags +- Clean history — one commit per PR, no interleaved `chore(release):` commits +- No `[skip ci]` dance — no recursive pipeline triggering +- Fewer dependencies — 1 devDependency instead of 3+ ### `package.json` Version Placeholder @@ -122,9 +110,9 @@ semantic-release's own FAQ recommends against committing during release. Omittin { "version": "0.0.0-development" } ``` -Signals that the in-repo version is not the released version. semantic-release writes the real version to `package.json` in CI only (during the npm plugin step) — but since there's no `@semantic-release/npm` here, it's purely cosmetic. Git tags are the source of truth. +Git tags are the source of truth for the released version. ## Related Decisions -- [ADR 001 — Bootstrap](001.wtty.bootstrap.md): Established the build pipeline (`bun run build`) that the release workflow extends -- [ADR 002 — CLI start/stop](002.cli.start-stop.md): CLI entry point is the binary artifact built and released +- [ADR 001 — Bootstrap](001.wtty.bootstrap.md): Established the build pipeline that the release workflow extends +- [ADR 002 — CLI start/stop](002.cli.start-stop.md): CLI entry point distributed via `npx wtty` diff --git a/docs/specs/release-process.md b/docs/specs/release-process.md index d8d1b32..412769e 100644 --- a/docs/specs/release-process.md +++ b/docs/specs/release-process.md @@ -4,7 +4,9 @@ ## Overview -Automated release pipeline for wtty using semantic-release. Conventional commit prefixes in PR titles drive version bumps post-merge to `main`. semantic-release determines the version, creates a GitHub Release with release notes, and uploads platform-specific binary artifacts. No manual versioning, no release commits, no extra files. Git tags are the sole version record. +Automated release pipeline for wtty using semantic-release. Conventional commit prefixes in PR titles drive version bumps post-merge to `main`. semantic-release determines the version, creates a GitHub Release with release notes, and pushes a git tag. No manual versioning, no release commits, no extra files. Git tags are the sole version record. + +wtty targets developers who already have Node.js or Bun installed. Distribution is via `npx wtty` — no binary downloads needed. ## Principles @@ -13,8 +15,7 @@ Automated release pipeline for wtty using semantic-release. Conventional commit | 1 | Developers don't version | Merge to `main` with a conventional PR title — CI handles the rest. | | 2 | Commit message is the changelog | PR title (squash merge commit message) is the changelog entry. No separate changeset files. | | 3 | Git tags are the version record | `package.json` version stays at `0.0.0-development`. Tags are the source of truth. | -| 4 | Tag-only releases | No release commits pushed back to the repo. No `@semantic-release/git`. Clean one-commit-per-PR history. | -| 5 | Binary artifacts on every release | GitHub Release includes pre-built binaries for all supported platforms. | +| 4 | Tag-only releases | No release commits pushed back to the repo. Clean one-commit-per-PR history. | ## Flow @@ -24,7 +25,7 @@ PR Post-Merge (main) | lint, build, test | → | semantic-release | | (PR check workflow) | squash | analyze commits → determine version bump | +----------------------------+ | create GitHub Release + release notes | - | build & upload platform binaries | + | push git tag | +------------------------------------------+ ``` @@ -38,7 +39,6 @@ PR Post-Merge (main) - `feat:` → minor bump (`0.1.0` → `0.2.0`) - `feat!:` / `BREAKING CHANGE:` → major bump (`0.1.0` → `1.0.0`) - `chore:`, `docs:`, `ci:` → no release -5. GitHub Release created with tag `v0.2.0` and binary artifacts attached ### Conventional Commit Prefixes @@ -57,18 +57,8 @@ PRs that don't match a release prefix produce no release — no error, no tag. Runs on every push to an open PR. No versioning. -```yaml -on: - pull_request: - branches: [main] -jobs: - lint, build, test -``` - ### Release Workflow (`.github/workflows/release.yml`) -Runs post-merge on `main`. Triggered by push to `main`. - ```yaml on: push: @@ -76,32 +66,27 @@ on: jobs: release: runs-on: ubuntu-latest + permissions: + contents: write steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 # full clone — semantic-release needs commit history + fetch-depth: 0 persist-credentials: false - uses: oven-sh/setup-bun@v2 with: bun-version: 1.3.10 - run: bun install --frozen-lockfile - run: bun run build - - name: Build platform binaries - run: bun run build:binaries - name: Release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: bunx semantic-release ``` -Key details: -- `fetch-depth: 0` — semantic-release needs full git history to find previous tags -- `persist-credentials: false` + `GITHUB_TOKEN` — semantic-release pushes tags via its own auth -- Binary build step produces artifacts before the release step attaches them - ## Configuration -### `.releaserc.json` (repo root) +### `.releaserc.json` ```json { @@ -110,39 +95,11 @@ Key details: "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", - [ - "@semantic-release/github", - { - "assets": [ - { "path": "dist/wtty-linux-x64", "label": "wtty-linux-x64" }, - { "path": "dist/wtty-linux-arm64", "label": "wtty-linux-arm64" }, - { "path": "dist/wtty-darwin-x64", "label": "wtty-darwin-x64" }, - { "path": "dist/wtty-darwin-arm64", "label": "wtty-darwin-arm64" }, - { "path": "dist/wtty-win32-x64.exe", "label": "wtty-win32-x64.exe" } - ] - } - ] + "@semantic-release/github" ] } ``` -Plugin chain: -1. **commit-analyzer** — determines bump type from conventional commits -2. **release-notes-generator** — generates changelog from commits (used for GitHub Release body) -3. **github** — creates the GitHub Release, uploads binary assets, pushes the git tag - -`@semantic-release/git` and `@semantic-release/changelog` are intentionally omitted — tag-only approach keeps history clean and avoids CI push-to-branch permissions. - -### `package.json` version - -Keep at `0.0.0-development` to signal that the in-repo version is not the published version: - -```json -{ - "version": "0.0.0-development" -} -``` - ## Version Progression ``` @@ -153,29 +110,12 @@ main branch: v1.0.0 (feat!: redesign WebSocket protocol) ``` -## Tag Format - -Git tags: `v` (e.g. `v0.2.0`). Created by `@semantic-release/github` on the merge commit on `main`. Do not delete tags — semantic-release uses them to determine the next version. - ## GitHub Settings (one-time) -### Repository Settings - | Setting | Value | Why | |---------|-------|-----| | Squash merging | Enabled | PR title becomes the commit message semantic-release reads | -| Allow merge commits | Disabled (recommended) | Enforce squash-only to keep one commit per PR on `main` | - -### Workflow Permissions - -Go to **Settings → Actions → General → Workflow permissions**: - -| Setting | Value | Why | -|---------|-------|-----| | Workflow permissions | Read and write | `GITHUB_TOKEN` needs to push tags and create releases | -| Allow GitHub Actions to create and approve pull requests | Not needed | Release workflow doesn't open PRs | - -`GITHUB_TOKEN` is provided automatically by GitHub Actions — no manual secret setup needed. ## Features @@ -183,4 +123,3 @@ Go to **Settings → Actions → General → Workflow permissions**: |---------|--------|-----------| | Automated versioning via conventional commits | ⬜ | [ADR 003](../adrs/003.release-process.semantic-release.md) | | GitHub Release with release notes | ⬜ | [ADR 003](../adrs/003.release-process.semantic-release.md) | -| Platform binary artifacts on release | ⬜ | [ADR 003](../adrs/003.release-process.semantic-release.md) | diff --git a/package.json b/package.json index f4bb28a..6a34a23 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,22 @@ { "name": "wtty", - "version": "0.0.0", + "version": "0.0.0-development", "description": "Web TTY for running CLI/TUI applications in a browser tab, across platforms", + "bin": { + "wtty": "./dist/cli.js" + }, "private": true, "type": "module", "scripts": { "preinstall": "bun scripts/check-pkg-manager.ts", + "build": "bun run scripts/build.ts", "dev": "bun run src/server.ts", "dev:node": "tsx src/server.ts", + "cli": "bun run dist/cli.js", "preview": "bun run dist/server.js", "preview:node": "node dist/server.js", "lint": "tsc --noEmit -p tsconfig.lint.json && biome check .", "lint:fix": "tsc --noEmit -p tsconfig.lint.json && bunx biome check --write .", - "build": "bun run scripts/build.ts", "test": "bun test", "clean": "rimraf dist node_modules" }, @@ -26,6 +30,7 @@ "@types/bun": "1.3.11", "@types/ws": "8.18.1", "rimraf": "6.1.3", + "semantic-release": "25.0.3", "tsx": "4.21.0", "typescript": "5.9.3" } diff --git a/scripts/build.ts b/scripts/build.ts index 377fbbf..fd340e1 100644 --- a/scripts/build.ts +++ b/scripts/build.ts @@ -3,7 +3,7 @@ export {}; const result = await Bun.build({ - entrypoints: ['./src/server.ts'], + entrypoints: ['./src/server.ts', './src/cli.ts'], outdir: './dist', target: 'node', format: 'esm', diff --git a/src/cli.ts b/src/cli.ts new file mode 100644 index 0000000..49eafba --- /dev/null +++ b/src/cli.ts @@ -0,0 +1,32 @@ +import { spawn } from 'node:child_process'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const PORT = Number(process.env.PORT) || 2346; +const BASE_URL = `http://localhost:${PORT}`; + +const command = process.argv[2]; + +if (command === 'start') { + const serverEntry = path.resolve(__dirname, 'server.js'); + const child = spawn(process.execPath, [serverEntry], { + detached: true, + stdio: 'ignore', + env: { ...process.env, PORT: String(PORT) }, + }); + child.unref(); + console.log('wtty started'); +} else if (command === 'stop') { + try { + await fetch(`${BASE_URL}/api/server/stop`, { method: 'POST' }); + console.log('wtty stopped'); + } catch { + console.log('wtty is not running'); + } +} else { + console.error('Usage: wtty start | wtty stop'); + process.exit(1); +} diff --git a/src/server.ts b/src/server.ts index 26c45a5..1df23ea 100644 --- a/src/server.ts +++ b/src/server.ts @@ -144,6 +144,18 @@ const httpServer = http.createServer((req, res) => { const url = new URL(req.url ?? '/', `http://${req.headers.host}`); const pathname = url.pathname; + if (req.method === 'POST' && pathname === '/api/server/stop') { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end('stopping'); + for (const [ws, session] of sessions.entries()) { + session.pty.kill(); + ws.close(); + } + wss.close(); + httpServer.close(() => process.exit(0)); + return; + } + if (pathname === '/' || pathname === '/index.html') { res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(HTML_TEMPLATE); From 00dbb9fc0358d2fa6c3dc2d756f470f162ef04d5 Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 18:11:14 -0400 Subject: [PATCH 04/27] feat: enhance release process with npm publishing and clean-publish integration --- .github/workflows/release.yml | 5 +++ .npmignore | 16 +++++++ .releaserc.json | 1 + bun.lock | 13 ++++-- .../003.release-process.semantic-release.md | 42 +++++++++++++++---- docs/specs/release-process.md | 11 ++++- package.json | 25 +++++++---- 7 files changed, 94 insertions(+), 19 deletions(-) create mode 100644 .npmignore diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6a7a61e..1ed3f2c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,4 +23,9 @@ jobs: - name: Release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} run: bunx semantic-release + - name: Publish to npm + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + run: bunx clean-publish diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..6a457a9 --- /dev/null +++ b/.npmignore @@ -0,0 +1,16 @@ +# source +src/ +scripts/ + +# config +tsconfig*.json +biome.json +.releaserc.json +Makefile + +# docs +docs/ + +# misc +.github/ +.agents/ diff --git a/.releaserc.json b/.releaserc.json index fea7fae..85bff4c 100644 --- a/.releaserc.json +++ b/.releaserc.json @@ -4,6 +4,7 @@ "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", + ["@semantic-release/npm", { "npmPublish": false }], "@semantic-release/github" ] } diff --git a/bun.lock b/bun.lock index b80b8ef..6d7b227 100644 --- a/bun.lock +++ b/bun.lock @@ -13,6 +13,7 @@ "@biomejs/biome": "2.4.8", "@types/bun": "1.3.11", "@types/ws": "8.18.1", + "clean-publish": "^6.0.4", "rimraf": "6.1.3", "semantic-release": "25.0.3", "tsx": "4.21.0", @@ -209,6 +210,8 @@ "char-regex": ["char-regex@1.0.2", "", {}, "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw=="], + "clean-publish": ["clean-publish@6.0.4", "", { "dependencies": { "lilconfig": "^3.1.3", "picomatch": "^4.0.3", "tinyexec": "^1.0.4", "tinyglobby": "^0.2.15" }, "bin": { "clean-publish": "clean-publish.js", "clear-package-json": "clear-package-json.js" } }, "sha512-jY4mev6mOjDi76LKPET1/fOXbmBwl4C5Avt/TZDgEjyWNby7vkJ8waIa3lHi5cFRUsR0Yq19YNhjeimh8qsGLQ=="], + "clean-stack": ["clean-stack@5.3.0", "", { "dependencies": { "escape-string-regexp": "5.0.0" } }, "sha512-9ngPTOhYGQqNVSfeJkYXHmF7AGWp4/nN5D/QqNQs3Dvxd1Kk/WpjHfNujKHYUQ/5CoGyOyFNoWSPk5afzP0QVg=="], "cli-highlight": ["cli-highlight@2.1.11", "", { "dependencies": { "chalk": "^4.0.0", "highlight.js": "^10.7.1", "mz": "^2.4.0", "parse5": "^5.1.1", "parse5-htmlparser2-tree-adapter": "^6.0.0", "yargs": "^16.0.0" }, "bin": { "highlight": "bin/highlight" } }, "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg=="], @@ -377,6 +380,8 @@ "jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="], + "lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="], + "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], "load-json-file": ["load-json-file@4.0.0", "", { "dependencies": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", "pify": "^3.0.0", "strip-bom": "^3.0.0" } }, "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw=="], @@ -483,7 +488,7 @@ "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], - "picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], "pify": ["pify@3.0.0", "", {}, "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg=="], @@ -579,6 +584,8 @@ "time-span": ["time-span@5.1.0", "", { "dependencies": { "convert-hrtime": "^5.0.0" } }, "sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA=="], + "tinyexec": ["tinyexec@1.0.4", "", {}, "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw=="], + "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], @@ -661,6 +668,8 @@ "make-asynchronous/type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="], + "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + "npm/@gar/promise-retry": ["@gar/promise-retry@1.0.3", "", {}, "sha512-GmzA9ckNokPypTg10pgpeHNQe7ph+iIKKmhKu3Ob9ANkswreCx7R3cKmY781K8QK3AqVL3xVh9A42JvIAbkkSA=="], "npm/@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="], @@ -957,8 +966,6 @@ "tempy/type-fest": ["type-fest@2.19.0", "", {}, "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA=="], - "tinyglobby/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], - "wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], "@semantic-release/release-notes-generator/read-package-up/read-pkg": ["read-pkg@9.0.1", "", { "dependencies": { "@types/normalize-package-data": "^2.4.3", "normalize-package-data": "^6.0.0", "parse-json": "^8.0.0", "type-fest": "^4.6.0", "unicorn-magic": "^0.1.0" } }, "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA=="], diff --git a/docs/adrs/003.release-process.semantic-release.md b/docs/adrs/003.release-process.semantic-release.md index ad4d731..8f71c0f 100644 --- a/docs/adrs/003.release-process.semantic-release.md +++ b/docs/adrs/003.release-process.semantic-release.md @@ -10,19 +10,19 @@ wtty has a stub release workflow (`.github/workflows/release.yml`) that runs `bun run build` then `echo "TODO - publish step"`. No versioning, no published artifacts. -wtty targets developers who already have Node.js or Bun installed. Distribution via `npx wtty` is the natural fit — no binary downloads, no install step beyond what developers already have. A release means a GitHub Release with a git tag and release notes. The version should be derived automatically from what changed, not set manually. +wtty targets developers who already have Node.js or Bun installed. Distribution via `npx wtty` is the natural fit — no binary downloads needed. A release means publishing to npm and creating a GitHub Release with release notes. The version should be derived automatically from what changed, not set manually. -The cfx repo solved the same versioning problem with semantic-release (ADR 004): conventional commit prefixes in PR/MR titles drive version bumps post-merge, git tags are the sole version record, no release commits. That pattern maps directly to wtty. +The cfx repo solved the same versioning problem with semantic-release (ADR 004): conventional commit prefixes in PR/MR titles drive version bumps post-merge, git tags are the sole version record, no release commits. That pattern maps directly to wtty, with `@semantic-release/npm` added since wtty publishes to the public npm registry. ## Decision -Use **semantic-release** with `@semantic-release/github`, running post-merge on `main`. Developers write a conventional commit prefix in the PR title. GitHub squash merge uses the PR title as the commit message on `main`. semantic-release reads that message, determines the version bump, creates a GitHub Release with release notes, and pushes a git tag. No manual versioning, no release commits, no extra files per PR. +Use **semantic-release** with `@semantic-release/npm` and `@semantic-release/github`, running post-merge on `main`. Developers write a conventional commit prefix in the PR title. GitHub squash merge uses the PR title as the commit message on `main`. semantic-release reads that message, determines the version bump, publishes to npm, creates a GitHub Release with release notes, and pushes a git tag. No manual versioning, no release commits, no extra files per PR. ## Considered Options ### Option A: semantic-release post-merge on main, tag-only (chosen) -- **Pros**: Zero developer overhead beyond PR title. GitHub Release + release notes fully automated. Battle-tested. No version conflicts between concurrent PRs. No release commits — clean one-commit-per-PR history on `main`. `GITHUB_TOKEN` is provided automatically — no secrets to configure. +- **Pros**: Zero developer overhead beyond PR title. npm publish + GitHub Release + release notes fully automated. Battle-tested. No version conflicts between concurrent PRs. No release commits — clean one-commit-per-PR history on `main`. `GITHUB_TOKEN` is provided automatically. Only `NPM_TOKEN` needs manual setup. - **Cons**: `package.json` version doesn't reflect the released version (use `0.0.0-development` placeholder). No in-repo `CHANGELOG.md` (release notes live on GitHub Releases). Requires conventional commit discipline in PR titles (mitigate: squash merge uses PR title — one line to get right). ### Option B: Manual GitHub Release @@ -42,9 +42,9 @@ Use **semantic-release** with `@semantic-release/github`, running post-merge on ## Consequences -**Good**: Zero developer overhead — write a conventional PR title, everything else is automated. GitHub Release auto-created with release notes. Clean `main` history. `GITHUB_TOKEN` is automatic. Follows semantic-release's own recommended approach (tag-only, no commit-back). +**Good**: Zero developer overhead — write a conventional PR title, everything else is automated. Publishes to npm. GitHub Release auto-created with release notes. Clean `main` history. Follows semantic-release's own recommended approach (tag-only, no commit-back). -**Bad**: `package.json` version stays at `0.0.0-development`. No `CHANGELOG.md` in repo. Requires conventional commit discipline in PR titles. +**Bad**: `package.json` version stays at `0.0.0-development` in repo. No `CHANGELOG.md` in repo. Requires conventional commit discipline in PR titles. `NPM_TOKEN` must be set as a GitHub Actions secret. ## Implementation Notes @@ -57,12 +57,33 @@ Use **semantic-release** with `@semantic-release/github`, running post-merge on "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", + ["@semantic-release/npm", { "npmPublish": false }], "@semantic-release/github" ] } ``` -All three plugins are bundled with `semantic-release` — no additional packages needed. `@semantic-release/git` and `@semantic-release/changelog` intentionally omitted (tag-only). +`@semantic-release/npm` with `npmPublish: false` writes the bumped version to `package.json` in CI but does not publish. The actual publish is done by `clean-publish` in a separate workflow step, which strips `scripts` and `devDependencies` before calling `npm publish`. `@semantic-release/git` and `@semantic-release/changelog` intentionally omitted (tag-only). + +`clean-publish` is configured via the `clean-publish` field in `package.json`: + +```json +"clean-publish": { + "fields": ["scripts", "devDependencies"] +} +``` + +What consumers receive: + +```json +{ + "name": "wtty", + "bin": { "wtty": "./dist/cli.js" }, + "files": ["dist"], + "type": "module", + "dependencies": { ... } +} +``` ### Release Workflow @@ -88,12 +109,19 @@ jobs: - name: Release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} run: bunx semantic-release + - name: Publish to npm + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + run: bunx clean-publish ``` - `fetch-depth: 0` — semantic-release needs full git history to find previous tags - `persist-credentials: false` — semantic-release manages its own git auth via `GITHUB_TOKEN` - `permissions: contents: write` — `GITHUB_TOKEN` needs to push tags and create releases +- semantic-release writes the bumped version to `package.json`, then `clean-publish` strips `scripts` and `devDependencies` before publishing +- `NPM_TOKEN` — must be set as a GitHub Actions secret (Settings → Secrets → Actions). Generate from npmjs.com → Access Tokens → Automation token. ### Why Tag-Only (No Release Commits) diff --git a/docs/specs/release-process.md b/docs/specs/release-process.md index 412769e..dfcf75d 100644 --- a/docs/specs/release-process.md +++ b/docs/specs/release-process.md @@ -4,7 +4,7 @@ ## Overview -Automated release pipeline for wtty using semantic-release. Conventional commit prefixes in PR titles drive version bumps post-merge to `main`. semantic-release determines the version, creates a GitHub Release with release notes, and pushes a git tag. No manual versioning, no release commits, no extra files. Git tags are the sole version record. +Automated release pipeline for wtty using semantic-release. Conventional commit prefixes in PR titles drive version bumps post-merge to `main`. semantic-release determines the version, publishes to npm, creates a GitHub Release with release notes, and pushes a git tag. No manual versioning, no release commits, no extra files. Git tags are the sole version record. wtty targets developers who already have Node.js or Bun installed. Distribution is via `npx wtty` — no binary downloads needed. @@ -39,6 +39,7 @@ PR Post-Merge (main) - `feat:` → minor bump (`0.1.0` → `0.2.0`) - `feat!:` / `BREAKING CHANGE:` → major bump (`0.1.0` → `1.0.0`) - `chore:`, `docs:`, `ci:` → no release +5. npm package published, GitHub Release created with tag and release notes ### Conventional Commit Prefixes @@ -81,7 +82,12 @@ jobs: - name: Release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} run: bunx semantic-release + - name: Publish to npm + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + run: bunx clean-publish ``` ## Configuration @@ -95,6 +101,7 @@ jobs: "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", + "@semantic-release/npm", "@semantic-release/github" ] } @@ -116,10 +123,12 @@ main branch: |---------|-------|-----| | Squash merging | Enabled | PR title becomes the commit message semantic-release reads | | Workflow permissions | Read and write | `GITHUB_TOKEN` needs to push tags and create releases | +| `NPM_TOKEN` secret | npm Automation token | Settings → Secrets → Actions. Generate from npmjs.com → Access Tokens → Automation token. | ## Features | Feature | Status | Reference | |---------|--------|-----------| | Automated versioning via conventional commits | ⬜ | [ADR 003](../adrs/003.release-process.semantic-release.md) | +| npm publish on release | ⬜ | [ADR 003](../adrs/003.release-process.semantic-release.md) | | GitHub Release with release notes | ⬜ | [ADR 003](../adrs/003.release-process.semantic-release.md) | diff --git a/package.json b/package.json index 6a34a23..49116a7 100644 --- a/package.json +++ b/package.json @@ -5,20 +5,28 @@ "bin": { "wtty": "./dist/cli.js" }, - "private": true, + "files": [ + "dist" + ], "type": "module", "scripts": { + "clean": "rimraf dist node_modules", "preinstall": "bun scripts/check-pkg-manager.ts", - "build": "bun run scripts/build.ts", - "dev": "bun run src/server.ts", - "dev:node": "tsx src/server.ts", - "cli": "bun run dist/cli.js", - "preview": "bun run dist/server.js", - "preview:node": "node dist/server.js", "lint": "tsc --noEmit -p tsconfig.lint.json && biome check .", "lint:fix": "tsc --noEmit -p tsconfig.lint.json && bunx biome check --write .", "test": "bun test", - "clean": "rimraf dist node_modules" + "build": "bun run scripts/build.ts", + "dev": "bun run src/server.ts", + "prod": "bun run dist/server.js", + "dev:node": "tsx src/server.ts", + "prod:node": "node dist/server.js", + "wtty": "bun run dist/cli.js" + }, + "clean-publish": { + "fields": [ + "scripts", + "devDependencies" + ] }, "dependencies": { "@lydell/node-pty": "1.2.0-beta.3", @@ -29,6 +37,7 @@ "@biomejs/biome": "2.4.8", "@types/bun": "1.3.11", "@types/ws": "8.18.1", + "clean-publish": "6.0.4", "rimraf": "6.1.3", "semantic-release": "25.0.3", "tsx": "4.21.0", From 260a07135955c376c978d7010f75e38af20a130b Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 20:10:46 -0400 Subject: [PATCH 05/27] feat: update release process to use npm publish and remove clean-publish dependency --- .github/workflows/release.yml | 2 +- bun.lock | 15 +++++---------- docs/adrs/003.release-process.semantic-release.md | 14 ++++++-------- docs/specs/release-process.md | 2 +- package.json | 10 ++-------- scripts/clean-pkg-scripts.ts | 10 ++++++++++ 6 files changed, 25 insertions(+), 28 deletions(-) create mode 100644 scripts/clean-pkg-scripts.ts diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1ed3f2c..fcba984 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,4 +28,4 @@ jobs: - name: Publish to npm env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - run: bunx clean-publish + run: bun publish diff --git a/bun.lock b/bun.lock index 6d7b227..3e35fd9 100644 --- a/bun.lock +++ b/bun.lock @@ -13,7 +13,6 @@ "@biomejs/biome": "2.4.8", "@types/bun": "1.3.11", "@types/ws": "8.18.1", - "clean-publish": "^6.0.4", "rimraf": "6.1.3", "semantic-release": "25.0.3", "tsx": "4.21.0", @@ -210,8 +209,6 @@ "char-regex": ["char-regex@1.0.2", "", {}, "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw=="], - "clean-publish": ["clean-publish@6.0.4", "", { "dependencies": { "lilconfig": "^3.1.3", "picomatch": "^4.0.3", "tinyexec": "^1.0.4", "tinyglobby": "^0.2.15" }, "bin": { "clean-publish": "clean-publish.js", "clear-package-json": "clear-package-json.js" } }, "sha512-jY4mev6mOjDi76LKPET1/fOXbmBwl4C5Avt/TZDgEjyWNby7vkJ8waIa3lHi5cFRUsR0Yq19YNhjeimh8qsGLQ=="], - "clean-stack": ["clean-stack@5.3.0", "", { "dependencies": { "escape-string-regexp": "5.0.0" } }, "sha512-9ngPTOhYGQqNVSfeJkYXHmF7AGWp4/nN5D/QqNQs3Dvxd1Kk/WpjHfNujKHYUQ/5CoGyOyFNoWSPk5afzP0QVg=="], "cli-highlight": ["cli-highlight@2.1.11", "", { "dependencies": { "chalk": "^4.0.0", "highlight.js": "^10.7.1", "mz": "^2.4.0", "parse5": "^5.1.1", "parse5-htmlparser2-tree-adapter": "^6.0.0", "yargs": "^16.0.0" }, "bin": { "highlight": "bin/highlight" } }, "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg=="], @@ -380,8 +377,6 @@ "jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="], - "lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="], - "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], "load-json-file": ["load-json-file@4.0.0", "", { "dependencies": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", "pify": "^3.0.0", "strip-bom": "^3.0.0" } }, "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw=="], @@ -488,7 +483,7 @@ "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], - "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], + "picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], "pify": ["pify@3.0.0", "", {}, "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg=="], @@ -584,8 +579,6 @@ "time-span": ["time-span@5.1.0", "", { "dependencies": { "convert-hrtime": "^5.0.0" } }, "sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA=="], - "tinyexec": ["tinyexec@1.0.4", "", {}, "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw=="], - "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], @@ -662,14 +655,14 @@ "execa/get-stream": ["get-stream@9.0.1", "", { "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" } }, "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA=="], + "fdir/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], + "import-fresh/resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], "load-json-file/parse-json": ["parse-json@4.0.0", "", { "dependencies": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" } }, "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw=="], "make-asynchronous/type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="], - "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], - "npm/@gar/promise-retry": ["@gar/promise-retry@1.0.3", "", {}, "sha512-GmzA9ckNokPypTg10pgpeHNQe7ph+iIKKmhKu3Ob9ANkswreCx7R3cKmY781K8QK3AqVL3xVh9A42JvIAbkkSA=="], "npm/@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="], @@ -966,6 +959,8 @@ "tempy/type-fest": ["type-fest@2.19.0", "", {}, "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA=="], + "tinyglobby/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], + "wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], "@semantic-release/release-notes-generator/read-package-up/read-pkg": ["read-pkg@9.0.1", "", { "dependencies": { "@types/normalize-package-data": "^2.4.3", "normalize-package-data": "^6.0.0", "parse-json": "^8.0.0", "type-fest": "^4.6.0", "unicorn-magic": "^0.1.0" } }, "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA=="], diff --git a/docs/adrs/003.release-process.semantic-release.md b/docs/adrs/003.release-process.semantic-release.md index 8f71c0f..8c8bb11 100644 --- a/docs/adrs/003.release-process.semantic-release.md +++ b/docs/adrs/003.release-process.semantic-release.md @@ -63,14 +63,12 @@ Use **semantic-release** with `@semantic-release/npm` and `@semantic-release/git } ``` -`@semantic-release/npm` with `npmPublish: false` writes the bumped version to `package.json` in CI but does not publish. The actual publish is done by `clean-publish` in a separate workflow step, which strips `scripts` and `devDependencies` before calling `npm publish`. `@semantic-release/git` and `@semantic-release/changelog` intentionally omitted (tag-only). +`@semantic-release/npm` with `npmPublish: false` writes the bumped version to `package.json` in CI but does not publish. The actual publish is done by `npm publish` in a separate workflow step. A `prepublishOnly` script in `package.json` strips `scripts` and `devDependencies` in-place before npm reads the package. `@semantic-release/git` and `@semantic-release/changelog` intentionally omitted (tag-only). -`clean-publish` is configured via the `clean-publish` field in `package.json`: +`prepublishOnly` in `package.json` (runs automatically before `npm publish`): ```json -"clean-publish": { - "fields": ["scripts", "devDependencies"] -} +"prepublishOnly": "node -e \"const fs=require('fs'),p=JSON.parse(fs.readFileSync('package.json','utf8'));delete p.scripts;delete p.devDependencies;fs.writeFileSync('package.json',JSON.stringify(p,null,2)+'\\n');\"" ``` What consumers receive: @@ -114,14 +112,14 @@ jobs: - name: Publish to npm env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - run: bunx clean-publish + run: npm publish ``` - `fetch-depth: 0` — semantic-release needs full git history to find previous tags - `persist-credentials: false` — semantic-release manages its own git auth via `GITHUB_TOKEN` - `permissions: contents: write` — `GITHUB_TOKEN` needs to push tags and create releases -- semantic-release writes the bumped version to `package.json`, then `clean-publish` strips `scripts` and `devDependencies` before publishing -- `NPM_TOKEN` — must be set as a GitHub Actions secret (Settings → Secrets → Actions). Generate from npmjs.com → Access Tokens → Automation token. +- semantic-release writes the bumped version to `package.json`, then `npm publish` triggers `prepublishOnly` which strips dev fields before publishing +- `NPM_TOKEN` — must be set as a GitHub Actions secret. Generate from npmjs.com → Access Tokens → Automation token. ### Why Tag-Only (No Release Commits) diff --git a/docs/specs/release-process.md b/docs/specs/release-process.md index dfcf75d..06aef1c 100644 --- a/docs/specs/release-process.md +++ b/docs/specs/release-process.md @@ -87,7 +87,7 @@ jobs: - name: Publish to npm env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - run: bunx clean-publish + run: npm publish ``` ## Configuration diff --git a/package.json b/package.json index 49116a7..76267cd 100644 --- a/package.json +++ b/package.json @@ -20,13 +20,8 @@ "prod": "bun run dist/server.js", "dev:node": "tsx src/server.ts", "prod:node": "node dist/server.js", - "wtty": "bun run dist/cli.js" - }, - "clean-publish": { - "fields": [ - "scripts", - "devDependencies" - ] + "wtty": "bun run dist/cli.js", + "prepublishOnly": "bun scripts/clean-pkg-scripts.ts" }, "dependencies": { "@lydell/node-pty": "1.2.0-beta.3", @@ -37,7 +32,6 @@ "@biomejs/biome": "2.4.8", "@types/bun": "1.3.11", "@types/ws": "8.18.1", - "clean-publish": "6.0.4", "rimraf": "6.1.3", "semantic-release": "25.0.3", "tsx": "4.21.0", diff --git a/scripts/clean-pkg-scripts.ts b/scripts/clean-pkg-scripts.ts new file mode 100644 index 0000000..fd7f4ce --- /dev/null +++ b/scripts/clean-pkg-scripts.ts @@ -0,0 +1,10 @@ +#!/usr/bin/env bun + +import fs from 'node:fs'; + +const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8')); + +delete pkg.scripts; +delete pkg.devDependencies; + +fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n'); From 29954f59496420c399bd9352760a80fee23127a2 Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 20:17:33 -0400 Subject: [PATCH 06/27] fix: use template literal in clean-pkg-scripts Ultraworked with Sisyphus Co-authored-by: Sisyphus --- scripts/clean-pkg-scripts.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/clean-pkg-scripts.ts b/scripts/clean-pkg-scripts.ts index fd7f4ce..bbb56a1 100644 --- a/scripts/clean-pkg-scripts.ts +++ b/scripts/clean-pkg-scripts.ts @@ -7,4 +7,4 @@ const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8')); delete pkg.scripts; delete pkg.devDependencies; -fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n'); +fs.writeFileSync('package.json', `${JSON.stringify(pkg, null, 2)}\n`); From 2486adad53efc5de83871e0b969f4b4ea502f971 Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 20:17:34 -0400 Subject: [PATCH 07/27] test: add integration tests for server endpoints Ultraworked with Sisyphus Co-authored-by: Sisyphus --- src/server.test.ts | 63 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 src/server.test.ts diff --git a/src/server.test.ts b/src/server.test.ts new file mode 100644 index 0000000..cc12183 --- /dev/null +++ b/src/server.test.ts @@ -0,0 +1,63 @@ +import { afterAll, beforeAll, describe, expect, test } from 'bun:test'; +import { type ChildProcess, spawn } from 'node:child_process'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const SERVER_ENTRY = path.resolve(__dirname, 'server.ts'); + +const PORT = 2399; +const BASE_URL = `http://localhost:${PORT}`; + +async function waitForServer(timeout = 3000): Promise { + const deadline = Date.now() + timeout; + while (Date.now() < deadline) { + try { + await fetch(`${BASE_URL}/`); + return; + } catch { + await Bun.sleep(100); + } + } + throw new Error('Server did not start in time'); +} + +describe('server', () => { + let proc: ChildProcess; + + beforeAll(async () => { + proc = spawn(process.execPath, [SERVER_ENTRY], { + env: { ...process.env, PORT: String(PORT) }, + stdio: 'ignore', + }); + await waitForServer(); + }); + + afterAll(() => { + proc.kill(); + }); + + test('GET / returns HTML', async () => { + const res = await fetch(`${BASE_URL}/`); + expect(res.status).toBe(200); + expect(res.headers.get('content-type')).toContain('text/html'); + const body = await res.text(); + expect(body).toContain(''); + }); + + test('GET /unknown returns 404', async () => { + const res = await fetch(`${BASE_URL}/unknown`); + expect(res.status).toBe(404); + }); + + test('POST /api/server/stop returns 200 and stops server', async () => { + const res = await fetch(`${BASE_URL}/api/server/stop`, { method: 'POST' }); + expect(res.status).toBe(200); + const body = await res.text(); + expect(body).toBe('stopping'); + + await Bun.sleep(200); + + await expect(fetch(`${BASE_URL}/`)).rejects.toThrow(); + }); +}); From a4efdf4e9598ca775cbba2f772e09ecb9af4b1f9 Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 20:17:35 -0400 Subject: [PATCH 08/27] test: add integration tests for CLI start/stop Ultraworked with Sisyphus Co-authored-by: Sisyphus --- src/cli.test.ts | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/cli.test.ts diff --git a/src/cli.test.ts b/src/cli.test.ts new file mode 100644 index 0000000..8d76759 --- /dev/null +++ b/src/cli.test.ts @@ -0,0 +1,72 @@ +import { afterAll, describe, expect, test } from 'bun:test'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const CLI_ENTRY = path.resolve(__dirname, 'cli.ts'); + +const PORT = 2398; +const BASE_URL = `http://localhost:${PORT}`; + +async function runCli( + ...args: string[] +): Promise<{ stdout: string; stderr: string; exitCode: number }> { + const proc = Bun.spawn([process.execPath, CLI_ENTRY, ...args], { + env: { ...process.env, PORT: String(PORT) }, + stdout: 'pipe', + stderr: 'pipe', + }); + const [stdout, stderr] = await Promise.all([ + new Response(proc.stdout).text(), + new Response(proc.stderr).text(), + ]); + const exitCode = await proc.exited; + return { stdout: stdout.trim(), stderr: stderr.trim(), exitCode }; +} + +async function waitForServer(timeout = 3000): Promise { + const deadline = Date.now() + timeout; + while (Date.now() < deadline) { + try { + await fetch(`${BASE_URL}/`); + return true; + } catch { + await Bun.sleep(100); + } + } + return false; +} + +describe('cli', () => { + afterAll(async () => { + await fetch(`${BASE_URL}/api/server/stop`, { method: 'POST' }).catch(() => {}); + }); + + test('unknown command exits with error', async () => { + const { stderr, exitCode } = await runCli('unknown'); + expect(exitCode).toBe(1); + expect(stderr).toContain('Usage'); + }); + + test('start launches the server', async () => { + const { stdout, exitCode } = await runCli('start'); + expect(exitCode).toBe(0); + expect(stdout).toBe('wtty started'); + const running = await waitForServer(); + expect(running).toBe(true); + }); + + test('stop shuts down the server', async () => { + const { stdout, exitCode } = await runCli('stop'); + expect(exitCode).toBe(0); + expect(stdout).toBe('wtty stopped'); + await Bun.sleep(200); + await expect(fetch(`${BASE_URL}/`)).rejects.toThrow(); + }); + + test('stop when not running reports not running', async () => { + const { stdout, exitCode } = await runCli('stop'); + expect(exitCode).toBe(0); + expect(stdout).toBe('wtty is not running'); + }); +}); From 6d51de956e7e75f92cabccb5210370fb70d9712f Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 20:18:37 -0400 Subject: [PATCH 09/27] ci: add actions/checkout@v4 step before Copilot review Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- .github/workflows/copilot-review.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/copilot-review.yml b/.github/workflows/copilot-review.yml index 80ab057..258d682 100644 --- a/.github/workflows/copilot-review.yml +++ b/.github/workflows/copilot-review.yml @@ -11,6 +11,7 @@ jobs: permissions: pull-requests: write steps: + - uses: actions/checkout@v4 - name: Request Copilot review env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} From cfa0b278445965708665ca68069a216f82319037 Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 20:22:49 -0400 Subject: [PATCH 10/27] ci: remove copilot-review workflow --- .github/workflows/copilot-review.yml | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 .github/workflows/copilot-review.yml diff --git a/.github/workflows/copilot-review.yml b/.github/workflows/copilot-review.yml deleted file mode 100644 index 258d682..0000000 --- a/.github/workflows/copilot-review.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Copilot Review - -on: - pull_request: - branches: - - main - -jobs: - copilot-review: - runs-on: ubuntu-latest - permissions: - pull-requests: write - steps: - - uses: actions/checkout@v4 - - name: Request Copilot review - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh pr edit ${{ github.event.pull_request.number }} --add-reviewer "Copilot" From d3fa27674bbdc352c1b7e306c045d8ed053a6d65 Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 20:29:15 -0400 Subject: [PATCH 11/27] fix: add TypeScript ambient module declaration for @lydell/node-pty Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- src/env.d.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/env.d.ts diff --git a/src/env.d.ts b/src/env.d.ts new file mode 100644 index 0000000..aa43f4f --- /dev/null +++ b/src/env.d.ts @@ -0,0 +1,21 @@ +declare module '@lydell/node-pty' { + interface IPty { + onData(cb: (data: string) => void): void; + onExit(cb: (e: { exitCode: number; signal?: number }) => void): void; + write(data: string): void; + resize(cols: number, rows: number): void; + kill(signal?: string): void; + } + + interface ISpawnOptions { + name?: string; + cols?: number; + rows?: number; + cwd?: string; + env?: Record; + } + + function spawn(file: string, args: string[], options: ISpawnOptions): IPty; + + export default { spawn }; +} From 4afd418efb5ed0a4ede2b94c907e545d5b41c7b3 Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 20:34:39 -0400 Subject: [PATCH 12/27] refactor: move TypeScript declarations from src/env.d.ts to src/pty/node-pty.d.ts Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- src/{env.d.ts => pty/node-pty.d.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{env.d.ts => pty/node-pty.d.ts} (100%) diff --git a/src/env.d.ts b/src/pty/node-pty.d.ts similarity index 100% rename from src/env.d.ts rename to src/pty/node-pty.d.ts From 677c85b61c63acd647bd5eb4d1e1590dcb9244a8 Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 20:47:24 -0400 Subject: [PATCH 13/27] fix: resolve server entry and fetch error handling in CLI Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- src/cli.ts | 12 +++++++++--- src/server.ts | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/cli.ts b/src/cli.ts index 49eafba..4ba4070 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -11,7 +11,8 @@ const BASE_URL = `http://localhost:${PORT}`; const command = process.argv[2]; if (command === 'start') { - const serverEntry = path.resolve(__dirname, 'server.js'); + const isTs = __filename.endsWith('.ts'); + const serverEntry = path.resolve(__dirname, isTs ? 'server.ts' : 'server.js'); const child = spawn(process.execPath, [serverEntry], { detached: true, stdio: 'ignore', @@ -21,8 +22,13 @@ if (command === 'start') { console.log('wtty started'); } else if (command === 'stop') { try { - await fetch(`${BASE_URL}/api/server/stop`, { method: 'POST' }); - console.log('wtty stopped'); + const res = await fetch(`${BASE_URL}/api/server/stop`, { method: 'POST' }); + if (res.ok) { + console.log('wtty stopped'); + } else { + console.error(`wtty stop failed (status: ${res.status})`); + process.exit(1); + } } catch { console.log('wtty is not running'); } diff --git a/src/server.ts b/src/server.ts index 1df23ea..fddc619 100644 --- a/src/server.ts +++ b/src/server.ts @@ -278,6 +278,6 @@ process.on('SIGINT', () => { process.exit(0); }); -httpServer.listen(HTTP_PORT, () => { +httpServer.listen(HTTP_PORT, '127.0.0.1', () => { console.log(`listening on http://localhost:${HTTP_PORT}`); }); From b5e6856d1c04e0d4a5d65664da905edabdda1842 Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 20:47:30 -0400 Subject: [PATCH 14/27] test: use dynamic port allocation via getFreePort() Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- src/cli.test.ts | 38 ++++++++++++++++++++++++++------------ src/server.test.ts | 31 +++++++++++++++++++++---------- 2 files changed, 47 insertions(+), 22 deletions(-) diff --git a/src/cli.test.ts b/src/cli.test.ts index 8d76759..30b1bbf 100644 --- a/src/cli.test.ts +++ b/src/cli.test.ts @@ -1,18 +1,27 @@ import { afterAll, describe, expect, test } from 'bun:test'; +import net from 'node:net'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const CLI_ENTRY = path.resolve(__dirname, 'cli.ts'); -const PORT = 2398; -const BASE_URL = `http://localhost:${PORT}`; +function getFreePort(): Promise { + return new Promise((resolve, reject) => { + const srv = net.createServer(); + srv.listen(0, '127.0.0.1', () => { + const { port } = srv.address() as net.AddressInfo; + srv.close((err) => (err ? reject(err) : resolve(port))); + }); + }); +} async function runCli( + port: number, ...args: string[] ): Promise<{ stdout: string; stderr: string; exitCode: number }> { const proc = Bun.spawn([process.execPath, CLI_ENTRY, ...args], { - env: { ...process.env, PORT: String(PORT) }, + env: { ...process.env, PORT: String(port) }, stdout: 'pipe', stderr: 'pipe', }); @@ -24,11 +33,11 @@ async function runCli( return { stdout: stdout.trim(), stderr: stderr.trim(), exitCode }; } -async function waitForServer(timeout = 3000): Promise { +async function waitForServer(baseUrl: string, timeout = 3000): Promise { const deadline = Date.now() + timeout; while (Date.now() < deadline) { try { - await fetch(`${BASE_URL}/`); + await fetch(`${baseUrl}/`); return true; } catch { await Bun.sleep(100); @@ -38,34 +47,39 @@ async function waitForServer(timeout = 3000): Promise { } describe('cli', () => { + let port: number; + let baseUrl: string; + afterAll(async () => { - await fetch(`${BASE_URL}/api/server/stop`, { method: 'POST' }).catch(() => {}); + await fetch(`${baseUrl}/api/server/stop`, { method: 'POST' }).catch(() => {}); }); test('unknown command exits with error', async () => { - const { stderr, exitCode } = await runCli('unknown'); + port = await getFreePort(); + baseUrl = `http://localhost:${port}`; + const { stderr, exitCode } = await runCli(port, 'unknown'); expect(exitCode).toBe(1); expect(stderr).toContain('Usage'); }); test('start launches the server', async () => { - const { stdout, exitCode } = await runCli('start'); + const { stdout, exitCode } = await runCli(port, 'start'); expect(exitCode).toBe(0); expect(stdout).toBe('wtty started'); - const running = await waitForServer(); + const running = await waitForServer(baseUrl); expect(running).toBe(true); }); test('stop shuts down the server', async () => { - const { stdout, exitCode } = await runCli('stop'); + const { stdout, exitCode } = await runCli(port, 'stop'); expect(exitCode).toBe(0); expect(stdout).toBe('wtty stopped'); await Bun.sleep(200); - await expect(fetch(`${BASE_URL}/`)).rejects.toThrow(); + await expect(fetch(`${baseUrl}/`)).rejects.toThrow(); }); test('stop when not running reports not running', async () => { - const { stdout, exitCode } = await runCli('stop'); + const { stdout, exitCode } = await runCli(port, 'stop'); expect(exitCode).toBe(0); expect(stdout).toBe('wtty is not running'); }); diff --git a/src/server.test.ts b/src/server.test.ts index cc12183..d084787 100644 --- a/src/server.test.ts +++ b/src/server.test.ts @@ -1,19 +1,27 @@ import { afterAll, beforeAll, describe, expect, test } from 'bun:test'; import { type ChildProcess, spawn } from 'node:child_process'; +import net from 'node:net'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const SERVER_ENTRY = path.resolve(__dirname, 'server.ts'); -const PORT = 2399; -const BASE_URL = `http://localhost:${PORT}`; +function getFreePort(): Promise { + return new Promise((resolve, reject) => { + const srv = net.createServer(); + srv.listen(0, '127.0.0.1', () => { + const { port } = srv.address() as net.AddressInfo; + srv.close((err) => (err ? reject(err) : resolve(port))); + }); + }); +} -async function waitForServer(timeout = 3000): Promise { +async function waitForServer(baseUrl: string, timeout = 3000): Promise { const deadline = Date.now() + timeout; while (Date.now() < deadline) { try { - await fetch(`${BASE_URL}/`); + await fetch(`${baseUrl}/`); return; } catch { await Bun.sleep(100); @@ -24,13 +32,16 @@ async function waitForServer(timeout = 3000): Promise { describe('server', () => { let proc: ChildProcess; + let baseUrl: string; beforeAll(async () => { + const port = await getFreePort(); + baseUrl = `http://localhost:${port}`; proc = spawn(process.execPath, [SERVER_ENTRY], { - env: { ...process.env, PORT: String(PORT) }, + env: { ...process.env, PORT: String(port) }, stdio: 'ignore', }); - await waitForServer(); + await waitForServer(baseUrl); }); afterAll(() => { @@ -38,7 +49,7 @@ describe('server', () => { }); test('GET / returns HTML', async () => { - const res = await fetch(`${BASE_URL}/`); + const res = await fetch(`${baseUrl}/`); expect(res.status).toBe(200); expect(res.headers.get('content-type')).toContain('text/html'); const body = await res.text(); @@ -46,18 +57,18 @@ describe('server', () => { }); test('GET /unknown returns 404', async () => { - const res = await fetch(`${BASE_URL}/unknown`); + const res = await fetch(`${baseUrl}/unknown`); expect(res.status).toBe(404); }); test('POST /api/server/stop returns 200 and stops server', async () => { - const res = await fetch(`${BASE_URL}/api/server/stop`, { method: 'POST' }); + const res = await fetch(`${baseUrl}/api/server/stop`, { method: 'POST' }); expect(res.status).toBe(200); const body = await res.text(); expect(body).toBe('stopping'); await Bun.sleep(200); - await expect(fetch(`${BASE_URL}/`)).rejects.toThrow(); + await expect(fetch(`${baseUrl}/`)).rejects.toThrow(); }); }); From 3728aab76cfb29b1cc6d219c35f23d310eeed756 Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 20:47:36 -0400 Subject: [PATCH 15/27] fix: update release pipeline to use npm publish Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- .github/workflows/release.yml | 4 ---- .releaserc.json | 2 +- docs/adrs/003.release-process.semantic-release.md | 14 +++++--------- docs/specs/release-process.md | 4 ---- 4 files changed, 6 insertions(+), 18 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fcba984..2c6b93c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,7 +25,3 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} run: bunx semantic-release - - name: Publish to npm - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - run: bun publish diff --git a/.releaserc.json b/.releaserc.json index 85bff4c..b079ef9 100644 --- a/.releaserc.json +++ b/.releaserc.json @@ -4,7 +4,7 @@ "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", - ["@semantic-release/npm", { "npmPublish": false }], + "@semantic-release/npm", "@semantic-release/github" ] } diff --git a/docs/adrs/003.release-process.semantic-release.md b/docs/adrs/003.release-process.semantic-release.md index 8c8bb11..be0e00e 100644 --- a/docs/adrs/003.release-process.semantic-release.md +++ b/docs/adrs/003.release-process.semantic-release.md @@ -57,18 +57,18 @@ Use **semantic-release** with `@semantic-release/npm` and `@semantic-release/git "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", - ["@semantic-release/npm", { "npmPublish": false }], + "@semantic-release/npm", "@semantic-release/github" ] } ``` -`@semantic-release/npm` with `npmPublish: false` writes the bumped version to `package.json` in CI but does not publish. The actual publish is done by `npm publish` in a separate workflow step. A `prepublishOnly` script in `package.json` strips `scripts` and `devDependencies` in-place before npm reads the package. `@semantic-release/git` and `@semantic-release/changelog` intentionally omitted (tag-only). +`@semantic-release/npm` publishes to npm atomically within semantic-release's publish phase — before `@semantic-release/github` creates the tag and GitHub Release. This ensures a failed npm publish prevents the tag from being created (no partial releases). `prepublishOnly` in `package.json` strips `scripts` and `devDependencies` before the package is uploaded. `@semantic-release/git` and `@semantic-release/changelog` intentionally omitted (tag-only). -`prepublishOnly` in `package.json` (runs automatically before `npm publish`): +`prepublishOnly` in `package.json` (runs automatically before publish): ```json -"prepublishOnly": "node -e \"const fs=require('fs'),p=JSON.parse(fs.readFileSync('package.json','utf8'));delete p.scripts;delete p.devDependencies;fs.writeFileSync('package.json',JSON.stringify(p,null,2)+'\\n');\"" +"prepublishOnly": "bun scripts/clean-pkg-scripts.ts" ``` What consumers receive: @@ -109,16 +109,12 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} run: bunx semantic-release - - name: Publish to npm - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - run: npm publish ``` - `fetch-depth: 0` — semantic-release needs full git history to find previous tags - `persist-credentials: false` — semantic-release manages its own git auth via `GITHUB_TOKEN` - `permissions: contents: write` — `GITHUB_TOKEN` needs to push tags and create releases -- semantic-release writes the bumped version to `package.json`, then `npm publish` triggers `prepublishOnly` which strips dev fields before publishing +- `@semantic-release/npm` publishes first, then `@semantic-release/github` creates the tag — no partial release risk - `NPM_TOKEN` — must be set as a GitHub Actions secret. Generate from npmjs.com → Access Tokens → Automation token. ### Why Tag-Only (No Release Commits) diff --git a/docs/specs/release-process.md b/docs/specs/release-process.md index 06aef1c..fb712c0 100644 --- a/docs/specs/release-process.md +++ b/docs/specs/release-process.md @@ -84,10 +84,6 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} run: bunx semantic-release - - name: Publish to npm - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - run: npm publish ``` ## Configuration From ce4e07eeb782587620c7612d71e35fb447185eb6 Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 21:01:08 -0400 Subject: [PATCH 16/27] docs: update ADR status to Accepted and fix wording Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- docs/adrs/002.cli.start-stop.md | 7 +++---- docs/adrs/003.release-process.semantic-release.md | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/adrs/002.cli.start-stop.md b/docs/adrs/002.cli.start-stop.md index dc0cffc..fb12fcd 100644 --- a/docs/adrs/002.cli.start-stop.md +++ b/docs/adrs/002.cli.start-stop.md @@ -1,7 +1,7 @@ # ADR 002: CLI — `wtty start` / `wtty stop` **SPEC:** [cli](../specs/cli.md) -**Status:** Proposed +**Status:** Accepted **Date:** 2026-03-21 --- @@ -22,9 +22,8 @@ Two sub-questions drive this ADR: Add a CLI entry point (`src/cli.ts`) and a `POST /api/server/stop` endpoint to `src/server.ts`. No new runtime dependencies — Commander.js is deferred until there are enough subcommands to justify it. **`wtty start`**: -- Spawns `dist/server.js` with `detached: true`, `stdio: 'ignore'`, `unref()`. -- Waits briefly for the server to be ready (polls `GET /api/server/stop` or a short fixed delay). -- Prints `wtty started` and exits. +- Spawns the server with `detached: true`, `stdio: 'ignore'`, `unref()`. +- Immediately prints `wtty started` and exits. Does not wait for the server to be ready. **`wtty stop`**: - Sends `POST http://localhost:PORT/api/server/stop`. diff --git a/docs/adrs/003.release-process.semantic-release.md b/docs/adrs/003.release-process.semantic-release.md index be0e00e..95639db 100644 --- a/docs/adrs/003.release-process.semantic-release.md +++ b/docs/adrs/003.release-process.semantic-release.md @@ -1,7 +1,7 @@ # ADR 003: Release Process — semantic-release on GitHub **SPEC:** [release-process](../specs/release-process.md) -**Status:** Proposed +**Status:** Accepted **Date:** 2026-03-21 --- From bc9703686913752fc706f292ca25cc419d026389 Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 21:01:14 -0400 Subject: [PATCH 17/27] fix: restore package.json on exit via process handlers Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- scripts/clean-pkg-scripts.ts | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/scripts/clean-pkg-scripts.ts b/scripts/clean-pkg-scripts.ts index bbb56a1..d4f66b0 100644 --- a/scripts/clean-pkg-scripts.ts +++ b/scripts/clean-pkg-scripts.ts @@ -2,9 +2,28 @@ import fs from 'node:fs'; -const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8')); +const PKG_PATH = 'package.json'; +const original = fs.readFileSync(PKG_PATH, 'utf8'); + +const restore = () => { + try { + fs.writeFileSync(PKG_PATH, original); + } catch {} +}; + +process.on('exit', restore); +process.on('SIGINT', () => { + restore(); + process.exit(1); +}); +process.on('SIGTERM', () => { + restore(); + process.exit(1); +}); + +const pkg = JSON.parse(original); delete pkg.scripts; delete pkg.devDependencies; -fs.writeFileSync('package.json', `${JSON.stringify(pkg, null, 2)}\n`); +fs.writeFileSync(PKG_PATH, `${JSON.stringify(pkg, null, 2)}\n`); From bbbe019c129f0d6f40e896b3d6b3cfb92d27dc5b Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 21:09:51 -0400 Subject: [PATCH 18/27] fix: implement package.json strip/restore on publish Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- .gitignore | 1 + .npmignore | 3 +++ package.json | 3 ++- scripts/clean-pkg-scripts.ts | 37 ++++++++++++++++-------------------- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index 11699a5..2335af6 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ dist/ # npm publish artifacts *.tgz +package.json.publish-backup # Logs *.log diff --git a/.npmignore b/.npmignore index 6a457a9..62065f3 100644 --- a/.npmignore +++ b/.npmignore @@ -8,6 +8,9 @@ biome.json .releaserc.json Makefile +# publish backup +package.json.publish-backup + # docs docs/ diff --git a/package.json b/package.json index 76267cd..e5937d7 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,8 @@ "dev:node": "tsx src/server.ts", "prod:node": "node dist/server.js", "wtty": "bun run dist/cli.js", - "prepublishOnly": "bun scripts/clean-pkg-scripts.ts" + "prepublishOnly": "bun scripts/clean-pkg-scripts.ts strip", + "postpublish": "bun scripts/clean-pkg-scripts.ts restore" }, "dependencies": { "@lydell/node-pty": "1.2.0-beta.3", diff --git a/scripts/clean-pkg-scripts.ts b/scripts/clean-pkg-scripts.ts index d4f66b0..7e491cf 100644 --- a/scripts/clean-pkg-scripts.ts +++ b/scripts/clean-pkg-scripts.ts @@ -3,27 +3,22 @@ import fs from 'node:fs'; const PKG_PATH = 'package.json'; -const original = fs.readFileSync(PKG_PATH, 'utf8'); +const BACKUP_PATH = 'package.json.publish-backup'; +const command = process.argv[2]; -const restore = () => { - try { - fs.writeFileSync(PKG_PATH, original); - } catch {} -}; +if (command === 'strip') { + const original = fs.readFileSync(PKG_PATH, 'utf8'); + fs.writeFileSync(BACKUP_PATH, original); -process.on('exit', restore); -process.on('SIGINT', () => { - restore(); + const pkg = JSON.parse(original); + delete pkg.scripts; + delete pkg.devDependencies; + fs.writeFileSync(PKG_PATH, `${JSON.stringify(pkg, null, 2)}\n`); +} else if (command === 'restore') { + const original = fs.readFileSync(BACKUP_PATH, 'utf8'); + fs.writeFileSync(PKG_PATH, original); + fs.unlinkSync(BACKUP_PATH); +} else { + console.error('Usage: clean-pkg-scripts.ts strip | restore'); process.exit(1); -}); -process.on('SIGTERM', () => { - restore(); - process.exit(1); -}); - -const pkg = JSON.parse(original); - -delete pkg.scripts; -delete pkg.devDependencies; - -fs.writeFileSync(PKG_PATH, `${JSON.stringify(pkg, null, 2)}\n`); +} From b942474b7d7e88a3880dd1d4135136416cf590aa Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 21:11:15 -0400 Subject: [PATCH 19/27] chore: rename BACKUP_PATH from package.json.publish-backup to package.json.bak --- .gitignore | 2 +- .npmignore | 2 +- scripts/clean-pkg-scripts.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 2335af6..0c05a21 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,7 @@ dist/ # npm publish artifacts *.tgz -package.json.publish-backup +package.json.bak # Logs *.log diff --git a/.npmignore b/.npmignore index 62065f3..3f39391 100644 --- a/.npmignore +++ b/.npmignore @@ -9,7 +9,7 @@ biome.json Makefile # publish backup -package.json.publish-backup +package.json.bak # docs docs/ diff --git a/scripts/clean-pkg-scripts.ts b/scripts/clean-pkg-scripts.ts index 7e491cf..c270da6 100644 --- a/scripts/clean-pkg-scripts.ts +++ b/scripts/clean-pkg-scripts.ts @@ -3,7 +3,7 @@ import fs from 'node:fs'; const PKG_PATH = 'package.json'; -const BACKUP_PATH = 'package.json.publish-backup'; +const BACKUP_PATH = 'package.json.bak'; const command = process.argv[2]; if (command === 'strip') { From 8a8665fbf40ea476c248d5ba42575c4cfd09c756 Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 21:35:24 -0400 Subject: [PATCH 20/27] fix: wrap restore block in try/catch to handle missing backup gracefully --- scripts/clean-pkg-scripts.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/scripts/clean-pkg-scripts.ts b/scripts/clean-pkg-scripts.ts index c270da6..c7e56f8 100644 --- a/scripts/clean-pkg-scripts.ts +++ b/scripts/clean-pkg-scripts.ts @@ -15,9 +15,16 @@ if (command === 'strip') { delete pkg.devDependencies; fs.writeFileSync(PKG_PATH, `${JSON.stringify(pkg, null, 2)}\n`); } else if (command === 'restore') { - const original = fs.readFileSync(BACKUP_PATH, 'utf8'); - fs.writeFileSync(PKG_PATH, original); - fs.unlinkSync(BACKUP_PATH); + try { + const original = fs.readFileSync(BACKUP_PATH, 'utf8'); + fs.writeFileSync(PKG_PATH, original); + fs.unlinkSync(BACKUP_PATH); + } catch (err) { + console.error( + 'Warning: failed to restore package.json from backup — restore manually if needed.', + err, + ); + } } else { console.error('Usage: clean-pkg-scripts.ts strip | restore'); process.exit(1); From 5a1812a738df35e6517f5cba0403ab1d8634edab Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 21:43:58 -0400 Subject: [PATCH 21/27] fix: rename npm scripts and guard backup strip against stale .bak files Ultraworked with Sisyphus Co-authored-by: Sisyphus --- package.json | 4 ++-- scripts/clean-pkg-scripts.ts | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index e5937d7..e86af9a 100644 --- a/package.json +++ b/package.json @@ -21,8 +21,8 @@ "dev:node": "tsx src/server.ts", "prod:node": "node dist/server.js", "wtty": "bun run dist/cli.js", - "prepublishOnly": "bun scripts/clean-pkg-scripts.ts strip", - "postpublish": "bun scripts/clean-pkg-scripts.ts restore" + "prepack": "bun scripts/clean-pkg-scripts.ts strip", + "postpack": "bun scripts/clean-pkg-scripts.ts restore" }, "dependencies": { "@lydell/node-pty": "1.2.0-beta.3", diff --git a/scripts/clean-pkg-scripts.ts b/scripts/clean-pkg-scripts.ts index c7e56f8..0a9b7a4 100644 --- a/scripts/clean-pkg-scripts.ts +++ b/scripts/clean-pkg-scripts.ts @@ -7,6 +7,12 @@ const BACKUP_PATH = 'package.json.bak'; const command = process.argv[2]; if (command === 'strip') { + if (fs.existsSync(BACKUP_PATH)) { + console.error( + 'Error: package.json.bak already exists — a previous publish may have failed. Run restore first.', + ); + process.exit(1); + } const original = fs.readFileSync(PKG_PATH, 'utf8'); fs.writeFileSync(BACKUP_PATH, original); From 9b284d11549f4531487fafed43094de065490576 Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 21:58:16 -0400 Subject: [PATCH 22/27] fix: use 127.0.0.1 instead of localhost in CLI and build Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- scripts/build.ts | 1 + src/cli.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/build.ts b/scripts/build.ts index fd340e1..dead8d3 100644 --- a/scripts/build.ts +++ b/scripts/build.ts @@ -9,6 +9,7 @@ const result = await Bun.build({ format: 'esm', sourcemap: 'external', external: ['@lydell/node-pty', 'ws', 'ghostty-web'], + banner: '#!/usr/bin/env node', }); if (!result.success) { diff --git a/src/cli.ts b/src/cli.ts index 4ba4070..776e0d2 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -6,7 +6,7 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const PORT = Number(process.env.PORT) || 2346; -const BASE_URL = `http://localhost:${PORT}`; +const BASE_URL = `http://127.0.0.1:${PORT}`; const command = process.argv[2]; From 1bcc5585ac4ee683f5e996d5a954b77081eaeafd Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 21:58:16 -0400 Subject: [PATCH 23/27] test: replace Bun.sleep with waitForServerDown polling Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- src/cli.test.ts | 24 ++++++++++++++++++++---- src/server.test.ts | 17 +++++++++++++++-- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/cli.test.ts b/src/cli.test.ts index 30b1bbf..a4a6008 100644 --- a/src/cli.test.ts +++ b/src/cli.test.ts @@ -1,4 +1,4 @@ -import { afterAll, describe, expect, test } from 'bun:test'; +import { afterAll, beforeAll, describe, expect, test } from 'bun:test'; import net from 'node:net'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; @@ -46,17 +46,33 @@ async function waitForServer(baseUrl: string, timeout = 3000): Promise return false; } +async function waitForServerDown(baseUrl: string, timeout = 3000): Promise { + const deadline = Date.now() + timeout; + while (Date.now() < deadline) { + try { + await fetch(`${baseUrl}/`); + await Bun.sleep(100); + } catch { + return; + } + } + throw new Error('Server did not shut down in time'); +} + describe('cli', () => { let port: number; let baseUrl: string; + beforeAll(async () => { + port = await getFreePort(); + baseUrl = `http://127.0.0.1:${port}`; + }); + afterAll(async () => { await fetch(`${baseUrl}/api/server/stop`, { method: 'POST' }).catch(() => {}); }); test('unknown command exits with error', async () => { - port = await getFreePort(); - baseUrl = `http://localhost:${port}`; const { stderr, exitCode } = await runCli(port, 'unknown'); expect(exitCode).toBe(1); expect(stderr).toContain('Usage'); @@ -74,7 +90,7 @@ describe('cli', () => { const { stdout, exitCode } = await runCli(port, 'stop'); expect(exitCode).toBe(0); expect(stdout).toBe('wtty stopped'); - await Bun.sleep(200); + await waitForServerDown(baseUrl); await expect(fetch(`${baseUrl}/`)).rejects.toThrow(); }); diff --git a/src/server.test.ts b/src/server.test.ts index d084787..5b8c443 100644 --- a/src/server.test.ts +++ b/src/server.test.ts @@ -30,13 +30,26 @@ async function waitForServer(baseUrl: string, timeout = 3000): Promise { throw new Error('Server did not start in time'); } +async function waitForServerDown(baseUrl: string, timeout = 3000): Promise { + const deadline = Date.now() + timeout; + while (Date.now() < deadline) { + try { + await fetch(`${baseUrl}/`); + await Bun.sleep(100); + } catch { + return; + } + } + throw new Error('Server did not shut down in time'); +} + describe('server', () => { let proc: ChildProcess; let baseUrl: string; beforeAll(async () => { const port = await getFreePort(); - baseUrl = `http://localhost:${port}`; + baseUrl = `http://127.0.0.1:${port}`; proc = spawn(process.execPath, [SERVER_ENTRY], { env: { ...process.env, PORT: String(port) }, stdio: 'ignore', @@ -67,7 +80,7 @@ describe('server', () => { const body = await res.text(); expect(body).toBe('stopping'); - await Bun.sleep(200); + await waitForServerDown(baseUrl); await expect(fetch(`${baseUrl}/`)).rejects.toThrow(); }); From 0141cf53c143a8836bdb21347877090e840cb882 Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 21:58:17 -0400 Subject: [PATCH 24/27] chore: add Node.js engine requirement and update release process Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- docs/adrs/003.release-process.semantic-release.md | 7 ++++--- package.json | 3 +++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/adrs/003.release-process.semantic-release.md b/docs/adrs/003.release-process.semantic-release.md index 95639db..01a3fbb 100644 --- a/docs/adrs/003.release-process.semantic-release.md +++ b/docs/adrs/003.release-process.semantic-release.md @@ -63,12 +63,13 @@ Use **semantic-release** with `@semantic-release/npm` and `@semantic-release/git } ``` -`@semantic-release/npm` publishes to npm atomically within semantic-release's publish phase — before `@semantic-release/github` creates the tag and GitHub Release. This ensures a failed npm publish prevents the tag from being created (no partial releases). `prepublishOnly` in `package.json` strips `scripts` and `devDependencies` before the package is uploaded. `@semantic-release/git` and `@semantic-release/changelog` intentionally omitted (tag-only). +`@semantic-release/npm` publishes to npm atomically within semantic-release's publish phase — before `@semantic-release/github` creates the tag and GitHub Release. This ensures a failed npm publish prevents the tag from being created (no partial releases). `prepack`/`postpack` scripts in `package.json` temporarily strip `scripts` and `devDependencies` before the package is packed, then restore them after. `@semantic-release/git` and `@semantic-release/changelog` intentionally omitted (tag-only). -`prepublishOnly` in `package.json` (runs automatically before publish): +`prepack`/`postpack` in `package.json`: ```json -"prepublishOnly": "bun scripts/clean-pkg-scripts.ts" +"prepack": "bun scripts/clean-pkg-scripts.ts strip", +"postpack": "bun scripts/clean-pkg-scripts.ts restore" ``` What consumers receive: diff --git a/package.json b/package.json index e86af9a..f85fde2 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,9 @@ "dist" ], "type": "module", + "engines": { + "node": ">=18" + }, "scripts": { "clean": "rimraf dist node_modules", "preinstall": "bun scripts/check-pkg-manager.ts", From 3451bfee494c87670c21df482a69b36ad775bf1d Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 22:08:03 -0400 Subject: [PATCH 25/27] fix: update server log message to use 127.0.0.1 instead of localhost Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- src/server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server.ts b/src/server.ts index fddc619..3f584b3 100644 --- a/src/server.ts +++ b/src/server.ts @@ -279,5 +279,5 @@ process.on('SIGINT', () => { }); httpServer.listen(HTTP_PORT, '127.0.0.1', () => { - console.log(`listening on http://localhost:${HTTP_PORT}`); + console.log(`listening on http://127.0.0.1:${HTTP_PORT}`); }); From 966aed2a6211c89ccf6bcca10d9abcff53d3bfc4 Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 22:16:09 -0400 Subject: [PATCH 26/27] fix: add trailing newline to CLI banner string Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- scripts/build.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build.ts b/scripts/build.ts index dead8d3..ac98571 100644 --- a/scripts/build.ts +++ b/scripts/build.ts @@ -9,7 +9,7 @@ const result = await Bun.build({ format: 'esm', sourcemap: 'external', external: ['@lydell/node-pty', 'ws', 'ghostty-web'], - banner: '#!/usr/bin/env node', + banner: '#!/usr/bin/env node\n', }); if (!result.success) { From ad9043cfd1503206d5185992b9c7e81992c5cc62 Mon Sep 17 00:00:00 2001 From: jesse23 Date: Sat, 21 Mar 2026 22:25:08 -0400 Subject: [PATCH 27/27] fix: check serverEntry exists before spawning, exit 1 with error message if not found --- src/cli.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/cli.ts b/src/cli.ts index 776e0d2..ff5d4e4 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,4 +1,5 @@ import { spawn } from 'node:child_process'; +import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; @@ -13,6 +14,10 @@ const command = process.argv[2]; if (command === 'start') { const isTs = __filename.endsWith('.ts'); const serverEntry = path.resolve(__dirname, isTs ? 'server.ts' : 'server.js'); + if (!fs.existsSync(serverEntry)) { + console.error(`wtty: server entry not found at ${serverEntry}`); + process.exit(1); + } const child = spawn(process.execPath, [serverEntry], { detached: true, stdio: 'ignore',