diff --git a/.changeset/organize-repository-scripts.md b/.changeset/organize-repository-scripts.md new file mode 100644 index 000000000..a845151cc --- /dev/null +++ b/.changeset/organize-repository-scripts.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.dependency-cruiser.cjs b/.dependency-cruiser.cjs index 0a2032db7..b1e294a8b 100644 --- a/.dependency-cruiser.cjs +++ b/.dependency-cruiser.cjs @@ -59,7 +59,7 @@ module.exports = { { name: "extension-api-is-import-free", comment: - "packages/hunk/src/extension-api is the published contract; declaration emission publishes whatever it reaches (scripts/check-pack.ts gates the pack, this gates the graph).", + "packages/hunk/src/extension-api is the published contract; declaration emission publishes whatever it reaches (scripts/packaging/check-pack.ts gates the pack, this gates the graph).", severity: "error", from: { path: "^packages/hunk/src/extension-api/" }, to: { path: "^packages/", pathNot: "^packages/hunk/src/extension-api/" }, diff --git a/.github/workflows/install-sh-e2e.yml b/.github/workflows/install-sh-e2e.yml index 52074ef5f..dd5eeb6a3 100644 --- a/.github/workflows/install-sh-e2e.yml +++ b/.github/workflows/install-sh-e2e.yml @@ -1,6 +1,6 @@ # Runs the hunk.dev install script end to end against the newest published release. # -# The unit suite (scripts/install-sh.test.ts) checks the script as text and exercises its +# The unit suite (scripts/packaging/install-sh.test.ts) checks the script as text and exercises its # functions in isolation; this workflow is the only place the real download, checksum, extract, # and PATH flow runs against real release assets. It triggers on changes to the script itself, # on a weekly schedule to catch release-asset drift the script did not cause, and on demand. diff --git a/.github/workflows/pr-ci.yml b/.github/workflows/pr-ci.yml index 429c17a18..304f11167 100644 --- a/.github/workflows/pr-ci.yml +++ b/.github/workflows/pr-ci.yml @@ -47,7 +47,7 @@ jobs: env: BASE_SHA: ${{ github.event.pull_request.base.sha }} HEAD_SHA: ${{ github.sha }} - run: bun run ./scripts/verify-pr-release-notes.ts "$BASE_SHA" "$HEAD_SHA" + run: bun run ./scripts/release/verify-pr-release-notes.ts "$BASE_SHA" "$HEAD_SHA" windows-compat: name: Windows compatibility diff --git a/.github/workflows/release-prebuilt-npm.yml b/.github/workflows/release-prebuilt-npm.yml index 67681d104..3537b0787 100644 --- a/.github/workflows/release-prebuilt-npm.yml +++ b/.github/workflows/release-prebuilt-npm.yml @@ -59,7 +59,7 @@ jobs: if [ "$GITHUB_EVENT_NAME" = "push" ]; then current_latest="$(npm view hunkdiff dist-tags.latest)" fi - resolution="$(bun ./scripts/resolve-release-channel.ts \ + resolution="$(bun ./scripts/release/resolve-release-channel.ts \ --event "$GITHUB_EVENT_NAME" \ --ref "$GITHUB_REF_NAME" \ --requested-tag "$REQUESTED_NPM_TAG" \ @@ -94,7 +94,7 @@ jobs: - name: Verify tag matches package version if: github.event_name == 'push' - run: bun run ./scripts/check-release-version.ts "${{ github.ref_name }}" + run: bun run ./scripts/release/check-release-version.ts "${{ github.ref_name }}" - name: Compare release benchmark snapshot id: benchmark-gate @@ -163,7 +163,7 @@ jobs: - name: Build host artifact run: | bun run build:bin - bun run ./scripts/build-prebuilt-artifact.ts --expect-package "${{ matrix.package_name }}" + bun run ./scripts/packaging/build-prebuilt-artifact.ts --expect-package "${{ matrix.package_name }}" # Bun's default x64 runtime is compiled for Haswell and raises SIGILL on older CPUs. # Run the real artifact under an emulated pre-AVX CPU so a dropped baseline target @@ -207,7 +207,7 @@ jobs: - name: Verify tag matches package version if: github.event_name == 'push' - run: bun run ./scripts/check-release-version.ts "${{ github.ref_name }}" + run: bun run ./scripts/release/check-release-version.ts "${{ github.ref_name }}" - name: Download platform artifacts uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml index 680e88f13..7e00075ae 100644 --- a/.github/workflows/website.yml +++ b/.github/workflows/website.yml @@ -33,7 +33,7 @@ jobs: run: bun install --cwd website --frozen-lockfile - name: Test website tooling - run: bun test scripts/generate-docs.test.ts scripts/check-website-links.test.ts scripts/check-extension-catalog.test.ts + run: bun test scripts/generate/generate-docs.test.ts scripts/website/check-website-links.test.ts scripts/website/check-extension-catalog.test.ts - name: Check generated reference docs run: bun run check:docs diff --git a/AGENTS.md b/AGENTS.md index ccaff87f2..9c6dda1e5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -62,7 +62,7 @@ ReviewIntent + caller facts -> planReviewIntent -> ReviewAction[] -> reducer -> - **Conformance:** `test/review-conformance/` has hand-authored semantic fixtures covering every registered core, terminal, producer, broker, protocol, and extension projection. Every new semantic consumer registers its real projection and runs the whole corpus. - `scripts/source-boundaries.test.ts` keeps the seam + `scripts/quality/source-boundaries.test.ts` keeps the seam renderer/platform-free; its Node-debt list is shrink-only and tombstone lists append-only. A repaid seam finding deletes copies, adds a file or banned-symbol tombstone and adversarial fixture, registers consumers, and updates `docs/browser-review-seam-audit.md`. @@ -120,7 +120,7 @@ ReviewIntent + caller facts -> planReviewIntent -> ReviewAction[] -> reducer -> - When adding or renaming a built-in theme, update validation, public exports, docs/examples, the appropriate Changeset, and tests. Keep source palette tokens separate from semantic mappings and cover non-trivial derived colors. -- `BUNDLED_SHIKI_THEME_DIFF_COLORS` in `packages/hunk/src/core/theme/catalog.ts` is generated. Edit the sourcing policy in `scripts/generate-theme-diff-colors.ts`, then run `bun run generate:theme-colors`. +- `BUNDLED_SHIKI_THEME_DIFF_COLORS` in `packages/hunk/src/core/theme/catalog.ts` is generated. Edit the sourcing policy in `scripts/generate/generate-theme-diff-colors.ts`, then run `bun run generate:theme-colors`. ## testing diff --git a/docs/browser-review-rebuild.md b/docs/browser-review-rebuild.md index 86b4b44ca..e5cebe3fc 100644 --- a/docs/browser-review-rebuild.md +++ b/docs/browser-review-rebuild.md @@ -10,7 +10,7 @@ stack of small, independently reviewable PRs. Its Hunk-owned capability, resourc protocol remains separate from the generic per-application daemon contract in [`session-broker-sdk.md`](session-broker-sdk.md). Each phase has a hard gate and stands on the previous one. The seam contract — shared primitives stay renderer-free and platform-neutral — -is enforced by `scripts/source-boundaries.test.ts`, whose debt lists may only shrink. +is enforced by `scripts/quality/source-boundaries.test.ts`, whose debt lists may only shrink. Each phase lists the audit findings it repays (`browser-review-seam-audit.md`, ids A1–G5). A finding whose duplicate sites span phases is checked off when its **last** site converts; until @@ -222,7 +222,7 @@ allowlist design exists. Import gates prove code _may_ use a primitive, not that it _does_ — a consumer can silently re-derive. Every phase therefore passes the same five-rung ladder, and each rung is mechanical: -1. **Boundary gates** (every phase, exists today): `scripts/source-boundaries.test.ts` — +1. **Boundary gates** (every phase, exists today): `scripts/quality/source-boundaries.test.ts` — import containment, shrink-only debt lists, and the extracted-duplicate tombstone list. Repaying an audit finding means deleting the duplicate copies **and appending their paths to the tombstone list in the same PR**; a resurrected path fails CI forever after. diff --git a/docs/browser-review-seam-audit.md b/docs/browser-review-seam-audit.md index 1f0529373..a909b1cbd 100644 --- a/docs/browser-review-seam-audit.md +++ b/docs/browser-review-seam-audit.md @@ -286,7 +286,7 @@ duplication); hunk header text (browser delegates to Pierre separators); platfor the members that need them — and `toReviewIntent` strips them again, so an action is validated and narrowed rather than restated. The action-type-to-parser table is keyed by the vocabulary, so a wire-reachable intent without a parser does not compile. - `scripts/review-vocabulary.test.ts` is the ladder's rung 5: it asserts the equality, that + `scripts/quality/review-vocabulary.test.ts` is the ladder's rung 5: it asserts the equality, that every exclusion names a real intent once, and that every type in the vocabulary really reaches a parser. Round-trip fixtures for every action live in `test/review-conformance/wireFixtures.ts`, registered as the `review wire protocol` consumer. @@ -385,7 +385,7 @@ path suffixes, expansion retention, git-status badges). clamped to the ceiling a reader is allowed to hold rather than emitting frames the reader will refuse. `browserReviewServer.ts` imports all of it and declares none of it; the browser client imports the same module unchanged in Phase 5, which - `scripts/source-boundaries.test.ts` keeps possible by gating the module's transitive + `scripts/quality/source-boundaries.test.ts` keeps possible by gating the module's transitive closure platform-free. Two decisions differ from the prototype deliberately: a chunked payload is framed and verified as the byte stream it is, so reading it is the shared `ReviewChunkAssembler` rather than a fourth reassembly loop (C2's rule applied here); and @@ -488,7 +488,7 @@ path suffixes, expansion retention, git-status badges). registration's file limit, and every digest check is `isReviewSha256Digest`. The one coupling the protocol cannot express as an import is the transport frame size — importing the broker package would cost the module its browser safety — so - `scripts/review-vocabulary.test.ts` asserts it instead, alongside a check that no session + `scripts/quality/review-vocabulary.test.ts` asserts it instead, alongside a check that no session module re-declares a name the review model exports and that no module writes its own 64-character digest pattern. Naming `isActiveStoredReviewNote` beside `isRenderableStoredReviewNote` and commenting `parseReviewState` are browser-tier work and @@ -653,11 +653,11 @@ implementation does. The per-phase verification ladder lives in `browser-review-rebuild.md` § "Per-phase seam verification". A finding here counts as repaid only when all four hold: duplicate copies deleted, their paths (for whole files) or banned-symbol entries (for function-level -deletions) appended to the tombstone lists in `scripts/source-boundaries.test.ts`, +deletions) appended to the tombstone lists in `scripts/quality/source-boundaries.test.ts`, the finding's adversarial fixture landed in the conformance harness, and the consumer registered against that harness. -- The seam boundary tests (`scripts/source-boundaries.test.ts`) keep deleted copies deleted. +- The seam boundary tests (`scripts/quality/source-boundaries.test.ts`) keep deleted copies deleted. - Renderer parity tests (Phase 5 gate) drive shared fixtures through the terminal planner and browser projection and assert identical note placement, gap addressing, reveal targets, and default note targets — the drift class import gates cannot catch. diff --git a/docs/changelog-on-hunk-dev.md b/docs/changelog-on-hunk-dev.md index 4b186eeb4..29cfcd3c5 100644 --- a/docs/changelog-on-hunk-dev.md +++ b/docs/changelog-on-hunk-dev.md @@ -1,7 +1,7 @@ # Release notes on hunk.dev -`CHANGELOG.md` is the source of truth for what shipped. `scripts/generate-changelog.ts` projects it -into the pages published at `hunk.dev/changelog`, the same way `scripts/generate-docs.ts` projects +`CHANGELOG.md` is the source of truth for what shipped. `scripts/generate/generate-changelog.ts` projects it +into the pages published at `hunk.dev/changelog`, the same way `scripts/generate/generate-docs.ts` projects runtime metadata into the CLI and config references. Nothing under the generated paths is hand-edited; `bun run check:changelog` fails the build when they drift. @@ -103,7 +103,7 @@ Presentation lives in the site: - The landing page imports `website/releases/latest.json` for its release ribbon, so the current version is a static import rather than a build-time parse of generated Markdown. -`vercel.json` must keep `CHANGELOG.md` and `scripts/generate-changelog.ts` in its `ignoreCommand` +`vercel.json` must keep `CHANGELOG.md` and `scripts/generate/generate-changelog.ts` in its `ignoreCommand` path list, or release commits will not trigger a deploy. ## Social cards diff --git a/docs/extension-architecture.md b/docs/extension-architecture.md index 78ade69d3..ae0b72c0b 100644 --- a/docs/extension-architecture.md +++ b/docs/extension-architecture.md @@ -372,7 +372,7 @@ ordering before core or UI consumes it. The authoring surface is the `hunkdiff/extension` export — a façade over internal types, declared in `packages/hunk/src/extension-api/types.ts`. That module must stay import-free: declaration emission ships every module the entry reaches, -so an import there publishes Hunk internals (`scripts/check-pack.ts` fails +so an import there publishes Hunk internals (`scripts/packaging/check-pack.ts` fails the pack when it does, and typechecks every `docs/extensions.md` example as a consumer). Shapes shared with internal code are declared there and re-exported inward. diff --git a/docs/module-boundaries.md b/docs/module-boundaries.md index 7497173e1..3f5cfbf3f 100644 --- a/docs/module-boundaries.md +++ b/docs/module-boundaries.md @@ -10,7 +10,7 @@ graph (`packages/hunk/src/` plus `packages/`, tests excluded): and nothing is ever added. New code must respect the boundaries from day one. - Rules live in `.dependency-cruiser.cjs`; each rule's comment states the boundary it protects. -`scripts/source-boundaries.test.ts` remains the deeper, hand-authored gate for the review seam +`scripts/quality/source-boundaries.test.ts` remains the deeper, hand-authored gate for the review seam (browser-safe closure, Node-debt tombstones). The dependency-cruiser rules are the coarse tier-level complement, with real module resolution instead of regex import scanning. @@ -169,7 +169,7 @@ module that owns their behaviour, one home each: Deleting the re-exports made one hidden dependency visible: `core/review/annotations.ts` names `AgentAnnotation`, which is declared in `packages/hunk/src/extension-api/types.ts` because it is simultaneously an internal model type and part of the published contract. Routing that through -`core/types.ts` had disguised it as a core-local import, and `scripts/source-boundaries.test.ts` +`core/types.ts` had disguised it as a core-local import, and `scripts/quality/source-boundaries.test.ts` ("keeps the review model contained in core") caught it the moment the disguise came off. The allowance is now explicit and narrow — that one file, not the tree — and it cannot widen the seam, since `extension-api-is-import-free` forbids `extension-api/types.ts` any import at all. diff --git a/docs/source-architecture.md b/docs/source-architecture.md index f51545c22..36adfe92c 100644 --- a/docs/source-architecture.md +++ b/docs/source-architecture.md @@ -20,7 +20,7 @@ for executable rules and migration history. Of the checked-in workspaces, only `hunkdiff` is published. Release automation also generates the public `hunkdiff-{platform}-{arch}` binary packages from the matrix in -`scripts/prebuilt-package-helpers.ts`. Provider, VCS helper, broker, and term-video workspaces remain +`scripts/packaging/prebuilt-package-helpers.ts`. Provider, VCS helper, broker, and term-video workspaces remain private. ## Hunk source ownership @@ -102,8 +102,8 @@ path. The browser client and UI remain planned. public/provider contracts. `bun run deps:check` applies `.dependency-cruiser.cjs` to every package and to Hunk's internal tiers. -`scripts/source-boundaries.test.ts` adds browser-safe review and provider checks. The executable -rules take precedence over this summary. +`scripts/quality/source-boundaries.test.ts` adds browser-safe review and provider checks. The +executable rules take precedence over this summary. ## Bootstrap and lifecycle diff --git a/docs/watch-benchmark-final.md b/docs/watch-benchmark-final.md index 23ff86b12..d69a1388b 100644 --- a/docs/watch-benchmark-final.md +++ b/docs/watch-benchmark-final.md @@ -274,7 +274,7 @@ Complete harness file inventory: - **Protocol/fixture/schema/runner/report:** `benchmarks/watch/README.md`, `fixture.ts`, `campaign.ts`, `schema.ts`, `run.ts`, `report.ts`, and their `fixture.test.ts`, `campaign.test.ts`, `schema.test.ts`, and `run.test.ts`. - **Terminal, ConPTY, sampling, and Git instrumentation:** `terminal.ts`, `sampler.ts`, `git-log.ts`, `observer-probe.ts`, `artifacts.ts`, with `terminal.test.ts`, `sampler.test.ts`, `git-log.test.ts`, and `observer-probe.test.ts`. - **Freeze, provenance, transfer, build, and preflight:** `freeze.ts`, `stage.ts`, `build-host.ts`, `host-identity.ts`, `host-preflight.ts`, `prepare-preflight.ts`, with `stage.test.ts`, `build-host.test.ts`, `host-identity.test.ts`, `host-preflight.test.ts`, and shared `test-helpers.ts`. -- **Package/build integration:** seven `bench:watch*` scripts in `package.json`; dev-only `@xterm/headless@5.5.0` and `ghostty-opentui@1.4.10` plus `bun.lock`; `scripts/build-bin.ts` reuses `process.execPath` to prevent ambient-Bun builds. +- **Package/build integration:** seven `bench:watch*` scripts in `package.json`; dev-only `@xterm/headless@5.5.0` and `ghostty-opentui@1.4.10` plus `bun.lock`; `scripts/build/build-bin.ts` reuses `process.execPath` to prevent ambient-Bun builds. - **Benchmark-only production seams:** `packages/hunk/src/core/watch/observer.ts` and `.test.ts` accept an injected `auto|native|chokidar` backend for forced probes; production remains `auto`. - **Workflow:** `.github/workflows/benchmarks.yml` contains the Windows adapter. - **Maintenance changesets:** `.changeset/watch-benchmark-harness.md` and `.changeset/witty-schools-sit.md` are empty/non-release changesets. @@ -306,4 +306,4 @@ The ARM64 VM uses native ARM64 Bun 1.3.14 and builds/checksums a native PE. Beca Campaign-owned worktrees, binaries, fixture reconstructions, terminal logs, and temporary libraries are cleanup-owned by the campaign operator. Linux recovery inventoried and removed only campaign-created extraction files; unrelated paths were not touched. Remote copies may be deleted after archive/checksum acceptance, but the canonical frozen bundle, raw JSON, terminal evidence, failure records, manifests, provenance, summaries, and checksum index should be retained together. -The reusable fixture/freeze/schema/report pieces have value for a future benchmark, but maintaining the full harness means owning ConPTY adapters, two terminal parsers, OS samplers, workflow behavior, and cross-platform tests. **Recommended disposition:** retain the canonical campaign archive and this report; keep PR #531 free of harness-only code; preserve or extract the reusable core in a focused benchmark follow-up only if another campaign is planned; otherwise delete the temporary harness branch, manual workflow additions, dev-only terminal dependencies, empty changesets, forced-backend seam, and recovery script after the archive is secured. The exact-Bun `scripts/build-bin.ts` fix is independently useful but should be proposed separately if retained. +The reusable fixture/freeze/schema/report pieces have value for a future benchmark, but maintaining the full harness means owning ConPTY adapters, two terminal parsers, OS samplers, workflow behavior, and cross-platform tests. **Recommended disposition:** retain the canonical campaign archive and this report; keep PR #531 free of harness-only code; preserve or extract the reusable core in a focused benchmark follow-up only if another campaign is planned; otherwise delete the temporary harness branch, manual workflow additions, dev-only terminal dependencies, empty changesets, forced-backend seam, and recovery script after the archive is secured. The exact-Bun `scripts/build/build-bin.ts` fix is independently useful but should be proposed separately if retained. diff --git a/install.sh b/install.sh index c6725cdd9..631ff3962 100755 --- a/install.sh +++ b/install.sh @@ -22,7 +22,7 @@ # macOS and Linux only. On Windows, install with `npm install -g hunkdiff`. # # This file's canonical home is the repository root; the website build stages it into the -# deploy output so hunk.dev serves it (scripts/stage-install-script.ts). +# deploy output so hunk.dev serves it (scripts/packaging/stage-install-script.ts). # # Everything below only defines functions; the last line runs main. A partially delivered # script therefore dies on a syntax error instead of executing a truncated prefix. diff --git a/knip.json b/knip.json index 9e958541c..6b7975990 100644 --- a/knip.json +++ b/knip.json @@ -11,8 +11,8 @@ "test/session-broker-node/*.ts", "test/session-broker-runtime/*.ts", "scripts/launch-video/*.{ts,mjs}", - "scripts/probe-terminal-theme.ts", - "scripts/test-large-untracked-render.tsx", + "scripts/dev/probe-terminal-theme.ts", + "scripts/dev/test-large-untracked-render.tsx", "examples/extensions/**/index.{ts,tsx}", "examples/extensions/**/run.ts", "examples/**/*.test.ts" diff --git a/package.json b/package.json index d56dd53b5..5a03417f3 100644 --- a/package.json +++ b/package.json @@ -8,23 +8,23 @@ "scripts": { "start": "bun run packages/hunk/src/main.tsx", "dev": "bun --watch packages/hunk/src/main.tsx", - "build:npm": "bun run ./scripts/build-npm.ts", - "build:bin": "bun run ./scripts/build-bin.ts", - "build:prebuilt:npm": "bun run build:npm && bun run build:bin && bun run ./scripts/stage-prebuilt-npm.ts", - "build:prebuilt:artifact": "bun run build:bin && bun run ./scripts/build-prebuilt-artifact.ts", - "stage:prebuilt:release": "bun run build:npm && bun run ./scripts/stage-prebuilt-npm.ts --artifact-root ./dist/release/artifacts", - "install:bin": "bun run ./scripts/install-bin.ts", - "generate:skill": "bun run ./scripts/generate-skill.ts", - "generate:theme-colors": "bun run ./scripts/generate-theme-diff-colors.ts", - "generate:docs": "bun run ./scripts/generate-docs.ts", - "generate:changelog": "bun run ./scripts/generate-changelog.ts", + "build:npm": "bun run ./scripts/build/build-npm.ts", + "build:bin": "bun run ./scripts/build/build-bin.ts", + "build:prebuilt:npm": "bun run build:npm && bun run build:bin && bun run ./scripts/packaging/stage-prebuilt-npm.ts", + "build:prebuilt:artifact": "bun run build:bin && bun run ./scripts/packaging/build-prebuilt-artifact.ts", + "stage:prebuilt:release": "bun run build:npm && bun run ./scripts/packaging/stage-prebuilt-npm.ts --artifact-root ./dist/release/artifacts", + "install:bin": "bun run ./scripts/build/install-bin.ts", + "generate:skill": "bun run ./scripts/generate/generate-skill.ts", + "generate:theme-colors": "bun run ./scripts/generate/generate-theme-diff-colors.ts", + "generate:docs": "bun run ./scripts/generate/generate-docs.ts", + "generate:changelog": "bun run ./scripts/generate/generate-changelog.ts", "generate:og": "bun run ./website/scripts/generate-og.ts", - "check:docs": "bun run ./scripts/generate-docs.ts --check", - "check:changelog": "bun run ./scripts/generate-changelog.ts --check", + "check:docs": "bun run ./scripts/generate/generate-docs.ts --check", + "check:changelog": "bun run ./scripts/generate/generate-changelog.ts --check", "website:dev": "bun run --cwd website dev", - "website:build": "bun run check:docs && bun run check:changelog && bun run --cwd website build && bun run ./scripts/stage-install-script.ts", + "website:build": "bun run check:docs && bun run check:changelog && bun run --cwd website build && bun run ./scripts/packaging/stage-install-script.ts", "website:check": "bun run check:docs && bun run check:changelog && bun run --cwd website check", - "website:links": "bun run ./scripts/check-website-links.ts", + "website:links": "bun run ./scripts/website/check-website-links.ts", "website:test:browser": "bun run --cwd website test:browser", "typecheck": "tsc --noEmit", "format": "oxfmt --write .", @@ -36,22 +36,22 @@ "deps:baseline": "depcruise packages --config .dependency-cruiser.cjs --output-type baseline --output-to .dependency-cruiser-known-violations.json", "changeset": "bunx @changesets/cli@2.31.0", "changeset:status": "bunx @changesets/cli@2.31.0 status", - "release:version": "bun run ./scripts/changeset-version.ts", + "release:version": "bun run ./scripts/release/changeset-version.ts", "prepare": "simple-git-hooks", - "test": "bun run ./scripts/run-test-suite.ts", + "test": "bun run ./scripts/test/run-test-suite.ts", "test:theme-contrast": "bun test packages/hunk/src/ui/themes.test.ts --test-name-pattern contrast", "test:integration": "\"${npm_execpath:-bun}\" test ./test/pty", - "test:session-broker-node": "bun run ./scripts/test-session-broker-node.ts", + "test:session-broker-node": "bun run ./scripts/test/test-session-broker-node.ts", "test:tty-smoke": "HUNK_RUN_TTY_SMOKE=1 \"${npm_execpath:-bun}\" test ./test/smoke", "test:install-vm": "bun run ./test/cli/install-vm/runner.ts", "test:install-vm:clean": "bun run ./test/cli/install-vm/runner.ts --clean", - "check:pack": "bun run ./scripts/check-pack.ts", - "check:prebuilt-pack": "bun run ./scripts/check-prebuilt-pack.ts", - "smoke:prebuilt-install": "bun run ./scripts/smoke-prebuilt-install.ts", - "publish:prebuilt:npm": "bun run ./scripts/publish-prebuilt-npm.ts", + "check:pack": "bun run ./scripts/packaging/check-pack.ts", + "check:prebuilt-pack": "bun run ./scripts/packaging/check-prebuilt-pack.ts", + "smoke:prebuilt-install": "bun run ./scripts/packaging/smoke-prebuilt-install.ts", + "publish:prebuilt:npm": "bun run ./scripts/packaging/publish-prebuilt-npm.ts", "bench": "bun run benchmarks/run.ts", - "bench:release": "bun run ./scripts/run-release-benchmark.ts", - "bench:release:compare": "bun run ./scripts/compare-release-benchmarks.ts", + "bench:release": "bun run ./scripts/benchmarks/run-release-benchmark.ts", + "bench:release:compare": "bun run ./scripts/benchmarks/compare-release-benchmarks.ts", "bench:bootstrap-load": "bun run benchmarks/bootstrap-load.ts", "bench:working-tree-load": "bun run benchmarks/working-tree-load.ts", "bench:changeset-parse": "bun run benchmarks/changeset-parse.ts", @@ -71,7 +71,7 @@ "bench:geometry-memory": "bun run benchmarks/geometry-memory.ts", "bench:navigation-memory": "bun run benchmarks/navigation-memory.ts", "bench:resize-memory": "bun run benchmarks/resize-memory.ts", - "bench:daemon-memory": "bun run scripts/daemon-memory-check.ts", + "bench:daemon-memory": "bun run scripts/benchmarks/daemon-memory-check.ts", "bench:competitors": "bun run benchmarks/competitors.ts", "nix:update-lock": "nix run .#update-bun-lock" }, diff --git a/packages/hunk/package.json b/packages/hunk/package.json index 7260fe707..1e443e1ec 100644 --- a/packages/hunk/package.json +++ b/packages/hunk/package.json @@ -47,7 +47,7 @@ "access": "public" }, "scripts": { - "prepack": "bun run ../../scripts/build-npm.ts" + "prepack": "bun run ../../scripts/build/build-npm.ts" }, "dependencies": { "bun": "^1.4.2", diff --git a/packages/hunk/skills/hunk-extensions/SKILL.md b/packages/hunk/skills/hunk-extensions/SKILL.md index fd0f84784..2dcc21106 100644 --- a/packages/hunk/skills/hunk-extensions/SKILL.md +++ b/packages/hunk/skills/hunk-extensions/SKILL.md @@ -320,7 +320,7 @@ Only when the work is in the `hunk` repo rather than in a user extension: that is a real gap, not a reason for a private path. `default/vcs/` loads from VCS adapter resolution and must stay renderer-free. - `packages/hunk/src/extension-api/types.ts` must stay **import-free**; declaration emission - publishes whatever it reaches, and `scripts/check-pack.ts` fails the pack + publishes whatever it reaches, and `scripts/packaging/check-pack.ts` fails the pack otherwise. Shapes shared with internal code are declared there and re-exported inward. - New API surface means updating `docs/extensions.md` (its examples are diff --git a/packages/hunk/src/core/install/installSource.test.ts b/packages/hunk/src/core/install/installSource.test.ts index 7ec220aeb..7cc0d7fa5 100644 --- a/packages/hunk/src/core/install/installSource.test.ts +++ b/packages/hunk/src/core/install/installSource.test.ts @@ -156,7 +156,7 @@ describe("install source detection", () => { }); test("detects local source builds installed into the default install directory", () => { - // Built from this platform's own default so the check tracks `scripts/install-bin.ts`. + // Built from this platform's own default so the check tracks `scripts/build/install-bin.ts`. const installDir = resolveDevInstallDir({}, HOME_DIR); expect(installDir).toBeDefined(); expect( diff --git a/packages/hunk/src/core/install/installSource.ts b/packages/hunk/src/core/install/installSource.ts index 72a5a5dc9..5cac017a8 100644 --- a/packages/hunk/src/core/install/installSource.ts +++ b/packages/hunk/src/core/install/installSource.ts @@ -122,7 +122,7 @@ function isHomebrewExecutablePath(executablePath: string) { /** * Resolve the directory `bun run install:bin` copies local builds into. * - * Mirrors `scripts/install-bin.ts`: an explicit `HUNK_INSTALL_DIR` wins, Windows installs land in + * Mirrors `scripts/build/install-bin.ts`: an explicit `HUNK_INSTALL_DIR` wins, Windows installs land in * the per-user Programs directory, and everything else uses `~/.local/bin`. */ export function resolveDevInstallDir(env: NodeJS.ProcessEnv, homeDir: string | undefined) { diff --git a/packages/hunk/src/session/reviewEventProtocol.ts b/packages/hunk/src/session/reviewEventProtocol.ts index ad6de51ce..00a94b541 100644 --- a/packages/hunk/src/session/reviewEventProtocol.ts +++ b/packages/hunk/src/session/reviewEventProtocol.ts @@ -12,7 +12,7 @@ * refuse (`docs/browser-review-seam-audit.md`, C4). Here the server imports these * definitions, and the browser client will import the same ones unchanged — which is what * makes the module browser-safe by construction, gated as such by - * `scripts/source-boundaries.test.ts`. + * `scripts/quality/source-boundaries.test.ts`. * * Three properties worth stating up front: * diff --git a/packages/hunk/src/session/reviewProtocol.ts b/packages/hunk/src/session/reviewProtocol.ts index b6af8bc2d..31fe0ed1d 100644 --- a/packages/hunk/src/session/reviewProtocol.ts +++ b/packages/hunk/src/session/reviewProtocol.ts @@ -22,9 +22,9 @@ * * The module is browser-safe by construction and gated as such: it imports from * `packages/hunk/src/core/review/` and nothing else — no Node builtins, no broker package, no - * transport. `scripts/source-boundaries.test.ts` enforces that, and the transport-side + * transport. `scripts/quality/source-boundaries.test.ts` enforces that, and the transport-side * couplings it deliberately does not import (frame sizes) are asserted against this - * module's own bounds in `scripts/review-vocabulary.test.ts`. + * module's own bounds in `scripts/quality/review-vocabulary.test.ts`. */ import type { ReviewExpandedLineClaim } from "../core/review/expansion"; import { @@ -68,7 +68,7 @@ export const HUNK_REVIEW_PROTOCOL_VERSION = 1 as const; * * The protocol's own bound rather than a repetition of a frame size: a transport that * cannot carry this much is the transport's problem to declare, and - * `scripts/review-vocabulary.test.ts` asserts the session transport's frame limit still + * `scripts/quality/review-vocabulary.test.ts` asserts the session transport's frame limit still * accommodates it. Keeping the import out is what lets this module stay browser-safe. */ export const MAX_HUNK_REVIEW_ENVELOPE_BYTES = 4 * 1024 * 1024; diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 000000000..537e500f8 --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,17 @@ +# Repository scripts + +Scripts are grouped by the workflow they support. Prefer the stable `bun run` aliases in the root +`package.json` when one exists. + +- `benchmarks/` — release and daemon benchmark tooling +- `build/` — source builds and local binary installation +- `dev/` — manual development probes and fixtures +- `generate/` — checked-in documentation, skill, changelog, and theme generation +- `launch-video/` — launch-video capture and composition +- `packaging/` — package assembly, validation, publication, and install checks +- `quality/` — repository architecture, package-contract, and example conformance tests +- `release/` — Changesets and release-channel validation +- `test/` — default test-suite and compatibility runners +- `website/` — website catalogs, helpers, and link checks + +Keep tests next to the script or policy they cover. diff --git a/scripts/compare-release-benchmarks.test.ts b/scripts/benchmarks/compare-release-benchmarks.test.ts similarity index 98% rename from scripts/compare-release-benchmarks.test.ts rename to scripts/benchmarks/compare-release-benchmarks.test.ts index ca52d9ce0..46cfb7c71 100644 --- a/scripts/compare-release-benchmarks.test.ts +++ b/scripts/benchmarks/compare-release-benchmarks.test.ts @@ -2,7 +2,10 @@ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs"; import os from "node:os"; import path from "node:path"; import { afterEach, describe, expect, test } from "bun:test"; -import type { BenchmarkMetricResult, BenchmarkRunResult } from "../benchmarks/lib/benchmark-result"; +import type { + BenchmarkMetricResult, + BenchmarkRunResult, +} from "../../benchmarks/lib/benchmark-result"; import { compareBenchmarkRuns, findPreviousReleaseBenchmark, diff --git a/scripts/compare-release-benchmarks.ts b/scripts/benchmarks/compare-release-benchmarks.ts similarity index 99% rename from scripts/compare-release-benchmarks.ts rename to scripts/benchmarks/compare-release-benchmarks.ts index e4664ad7e..b427143bc 100644 --- a/scripts/compare-release-benchmarks.ts +++ b/scripts/benchmarks/compare-release-benchmarks.ts @@ -9,7 +9,7 @@ import type { BenchmarkMetricResult, BenchmarkRunResult, BenchmarkThreshold, -} from "../benchmarks/lib/benchmark-result"; +} from "../../benchmarks/lib/benchmark-result"; interface ParsedVersion { raw: string; @@ -29,7 +29,7 @@ interface CompareOptions { } const BENCHMARK_FILE_PATTERN = /^bench-(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)\.json$/; -const repoRoot = path.resolve(import.meta.dir, ".."); +const repoRoot = path.resolve(import.meta.dir, "../.."); /** Resolve the directory that stores committed release benchmark snapshots. */ export function releaseBenchmarkDir(root = repoRoot) { diff --git a/scripts/daemon-memory-check.ts b/scripts/benchmarks/daemon-memory-check.ts similarity index 93% rename from scripts/daemon-memory-check.ts rename to scripts/benchmarks/daemon-memory-check.ts index 27081853c..8395a6f97 100644 --- a/scripts/daemon-memory-check.ts +++ b/scripts/benchmarks/daemon-memory-check.ts @@ -5,7 +5,7 @@ import { tmpdir } from "node:os"; import { join } from "node:path"; import { createServer } from "node:net"; import { SESSION_BROKER_REGISTRATION_VERSION } from "@hunk/session-broker-core"; -import { HUNK_SESSION_API_PATH } from "../packages/hunk/src/session/protocol"; +import { HUNK_SESSION_API_PATH } from "../../packages/hunk/src/session/protocol"; type MemorySample = { label: string; @@ -74,7 +74,7 @@ function parseArgs(argv: string[]): CliOptions { const arg = argv[index]!; if (arg === "--help" || arg === "-h") { console.log( - `Usage: bun run scripts/daemon-memory-check.ts [options]\n\nOptions:\n --cycles Register/use/unregister cycles (default ${defaultOptions.cycles})\n --warmup-cycles Cycles ignored for trend analysis (default ${defaultOptions.warmupCycles})\n --sessions-per-cycle Fake websocket sessions per cycle (default ${defaultOptions.sessionsPerCycle})\n --files-per-session Review files stored per fake session (default ${defaultOptions.filesPerSession})\n --hunks-per-file Hunks per review file (default ${defaultOptions.hunksPerFile})\n --lines-per-hunk Diff lines per hunk side (default ${defaultOptions.linesPerHunk})\n --api-requests-per-cycle list/context/review requests while sessions are live (default ${defaultOptions.apiRequestsPerCycle})\n --snapshot-updates-per-cycle Snapshot update messages per session per cycle (default ${defaultOptions.snapshotUpdatesPerCycle})\n --settle-ms Delay before post-cleanup sampling (default ${defaultOptions.settleMs})\n --max-rss-growth-mb Fail if post-warmup RSS grows beyond this (default ${defaultOptions.maxRssGrowthMb})\n --max-rss-slope-kb Fail if post-warmup RSS slope exceeds this per cycle (default ${defaultOptions.maxRssSlopeKb})\n --json-out Write full sample summary JSON\n`, + `Usage: bun run scripts/benchmarks/daemon-memory-check.ts [options]\n\nOptions:\n --cycles Register/use/unregister cycles (default ${defaultOptions.cycles})\n --warmup-cycles Cycles ignored for trend analysis (default ${defaultOptions.warmupCycles})\n --sessions-per-cycle Fake websocket sessions per cycle (default ${defaultOptions.sessionsPerCycle})\n --files-per-session Review files stored per fake session (default ${defaultOptions.filesPerSession})\n --hunks-per-file Hunks per review file (default ${defaultOptions.hunksPerFile})\n --lines-per-hunk Diff lines per hunk side (default ${defaultOptions.linesPerHunk})\n --api-requests-per-cycle list/context/review requests while sessions are live (default ${defaultOptions.apiRequestsPerCycle})\n --snapshot-updates-per-cycle Snapshot update messages per session per cycle (default ${defaultOptions.snapshotUpdatesPerCycle})\n --settle-ms Delay before post-cleanup sampling (default ${defaultOptions.settleMs})\n --max-rss-growth-mb Fail if post-warmup RSS grows beyond this (default ${defaultOptions.maxRssGrowthMb})\n --max-rss-slope-kb Fail if post-warmup RSS slope exceeds this per cycle (default ${defaultOptions.maxRssSlopeKb})\n --json-out Write full sample summary JSON\n`, ); process.exit(0); } diff --git a/scripts/run-release-benchmark.ts b/scripts/benchmarks/run-release-benchmark.ts similarity index 97% rename from scripts/run-release-benchmark.ts rename to scripts/benchmarks/run-release-benchmark.ts index c956aa0cc..6e620bca7 100644 --- a/scripts/run-release-benchmark.ts +++ b/scripts/benchmarks/run-release-benchmark.ts @@ -14,7 +14,7 @@ export interface RunReleaseBenchmarkOptions { out: string; } -const repoRoot = path.resolve(import.meta.dir, ".."); +const repoRoot = path.resolve(import.meta.dir, "../.."); function readArgValue(args: string[], index: number) { const value = args[index + 1]; diff --git a/scripts/build-bin.test.ts b/scripts/build/build-bin.test.ts similarity index 100% rename from scripts/build-bin.test.ts rename to scripts/build/build-bin.test.ts diff --git a/scripts/build-bin.ts b/scripts/build/build-bin.ts similarity index 100% rename from scripts/build-bin.ts rename to scripts/build/build-bin.ts diff --git a/scripts/build-npm.ts b/scripts/build/build-npm.ts similarity index 100% rename from scripts/build-npm.ts rename to scripts/build/build-npm.ts diff --git a/scripts/install-bin.ts b/scripts/build/install-bin.ts similarity index 91% rename from scripts/install-bin.ts rename to scripts/build/install-bin.ts index 419ccd731..5f2ce6f12 100644 --- a/scripts/install-bin.ts +++ b/scripts/build/install-bin.ts @@ -4,7 +4,7 @@ import { chmodSync, copyFileSync, cpSync, mkdirSync, rmSync } from "node:fs"; import os from "node:os"; import path from "node:path"; -const repoRoot = path.resolve(import.meta.dir, ".."); +const repoRoot = path.resolve(import.meta.dir, "../.."); const isWindows = process.platform === "win32"; const binaryName = isWindows ? "hunk.exe" : "hunk"; const legacyBinaryName = isWindows ? "otdiff.exe" : "otdiff"; @@ -24,7 +24,7 @@ const installDir = process.env.HUNK_INSTALL_DIR ?? defaultInstallDir(); const installPath = path.join(installDir, binaryName); const legacyInstallPath = path.join(installDir, legacyBinaryName); -const buildScript = path.join(repoRoot, "scripts", "build-bin.ts"); +const buildScript = path.join(import.meta.dir, "build-bin.ts"); const build = Bun.spawnSync(["bun", "run", buildScript], { cwd: repoRoot, stdin: "inherit", @@ -34,7 +34,7 @@ const build = Bun.spawnSync(["bun", "run", buildScript], { }); if (build.exitCode !== 0) { - throw new Error(`scripts/build-bin.ts failed with exit ${build.exitCode}`); + throw new Error(`scripts/build/build-bin.ts failed with exit ${build.exitCode}`); } mkdirSync(installDir, { recursive: true }); diff --git a/scripts/package-paths.ts b/scripts/build/package-paths.ts similarity index 83% rename from scripts/package-paths.ts rename to scripts/build/package-paths.ts index 39cce836b..1f3cfedfe 100644 --- a/scripts/package-paths.ts +++ b/scripts/build/package-paths.ts @@ -1,7 +1,7 @@ import path from "node:path"; /** Repository and application paths shared by build, pack, and release tooling. */ -export const REPO_ROOT = path.resolve(import.meta.dir, ".."); +export const REPO_ROOT = path.resolve(import.meta.dir, "../.."); export const HUNK_PACKAGE_ROOT = path.join(REPO_ROOT, "packages", "hunk"); export const HUNK_SOURCE_ROOT = path.join(HUNK_PACKAGE_ROOT, "src"); export const HUNK_NPM_DIST = path.join(HUNK_PACKAGE_ROOT, "dist", "npm"); diff --git a/scripts/probe-terminal-theme.ts b/scripts/dev/probe-terminal-theme.ts similarity index 95% rename from scripts/probe-terminal-theme.ts rename to scripts/dev/probe-terminal-theme.ts index e1f5689a0..3fd5cb599 100644 --- a/scripts/probe-terminal-theme.ts +++ b/scripts/dev/probe-terminal-theme.ts @@ -6,7 +6,7 @@ import { detectTerminalThemeModeFromBackground, parseOsc11BackgroundColor, themeModeForBackgroundColor, -} from "../packages/hunk/src/core/theme/detection"; +} from "../../packages/hunk/src/core/theme/detection"; const inputFd = fs.openSync("/dev/tty", "r"); const input = new tty.ReadStream(inputFd); diff --git a/scripts/test-large-untracked-render.tsx b/scripts/dev/test-large-untracked-render.tsx similarity index 86% rename from scripts/test-large-untracked-render.tsx rename to scripts/dev/test-large-untracked-render.tsx index 90d013ee7..a0e6c0cd1 100644 --- a/scripts/test-large-untracked-render.tsx +++ b/scripts/dev/test-large-untracked-render.tsx @@ -3,11 +3,11 @@ import { mkdtempSync, rmSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { act } from "react"; -import { getBundledVcsCatalog } from "../packages/hunk/src/app/vcsCatalog"; -import { loadAppBootstrap } from "../packages/hunk/src/core/changeset/loaders"; -import { createExtensionSession } from "../packages/hunk/src/extensions/session"; -import { createEmptyExtensionLoadResult } from "../packages/hunk/src/extensions/types"; -import { AppHost } from "../packages/hunk/src/ui/AppHost"; +import { getBundledVcsCatalog } from "../../packages/hunk/src/app/vcsCatalog"; +import { loadAppBootstrap } from "../../packages/hunk/src/core/changeset/loaders"; +import { createExtensionSession } from "../../packages/hunk/src/extensions/session"; +import { createEmptyExtensionLoadResult } from "../../packages/hunk/src/extensions/types"; +import { AppHost } from "../../packages/hunk/src/ui/AppHost"; function runGit(cwd: string, ...args: string[]) { const proc = Bun.spawnSync(["git", ...args], { @@ -40,7 +40,9 @@ function createLargeFileBody(lineCount: number) { const lineCount = Number.parseInt(process.argv[2] ?? "100000", 10); const fixtureKind = process.argv[3] === "tracked" ? "tracked" : "untracked"; if (!Number.isFinite(lineCount) || lineCount <= 0) { - throw new Error("Usage: bun run scripts/test-large-untracked-render.tsx [line-count] [tracked]"); + throw new Error( + "Usage: bun run scripts/dev/test-large-untracked-render.tsx [line-count] [tracked]", + ); } const repo = mkdtempSync(join(tmpdir(), "hunk-large-untracked-render-")); diff --git a/scripts/generate-changelog.test.ts b/scripts/generate/generate-changelog.test.ts similarity index 100% rename from scripts/generate-changelog.test.ts rename to scripts/generate/generate-changelog.test.ts diff --git a/scripts/generate-changelog.ts b/scripts/generate/generate-changelog.ts similarity index 99% rename from scripts/generate-changelog.ts rename to scripts/generate/generate-changelog.ts index 8fcd19c00..7116cd134 100644 --- a/scripts/generate-changelog.ts +++ b/scripts/generate/generate-changelog.ts @@ -16,7 +16,7 @@ import { resolve } from "node:path"; * that has neither is rendered as unreleased. */ -const REPO_ROOT = resolve(import.meta.dir, ".."); +const REPO_ROOT = resolve(import.meta.dir, "../.."); const REPO_URL = "https://github.com/modem-dev/hunk"; const SITE_ORIGIN = "https://hunk.dev"; const GENERATED_NOTICE = diff --git a/scripts/generate-docs.test.ts b/scripts/generate/generate-docs.test.ts similarity index 90% rename from scripts/generate-docs.test.ts rename to scripts/generate/generate-docs.test.ts index a1a07ab80..7ccf053d2 100644 --- a/scripts/generate-docs.test.ts +++ b/scripts/generate/generate-docs.test.ts @@ -2,17 +2,17 @@ import { afterEach, describe, expect, test } from "bun:test"; import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs"; import { join } from "node:path"; import { tmpdir } from "node:os"; -import { CONFIG_REFERENCE_OPTIONS } from "../packages/hunk/src/core/run/config"; -import { renderHunkReviewSkill } from "../packages/hunk/src/hunk-review/skillDocument"; -import { SESSION_AGENT_COMMAND_LIST } from "../packages/hunk/src/session/agent/surface"; +import { CONFIG_REFERENCE_OPTIONS } from "../../packages/hunk/src/core/run/config"; +import { renderHunkReviewSkill } from "../../packages/hunk/src/hunk-review/skillDocument"; +import { SESSION_AGENT_COMMAND_LIST } from "../../packages/hunk/src/session/agent/surface"; import { DEFAULT_SESSION_BROKER_HOST, DEFAULT_SESSION_BROKER_PORT, SESSION_BROKER_HOST_ENV, SESSION_BROKER_PORT_ENV, UNSAFE_ALLOW_REMOTE_SESSION_BROKER_ENV, -} from "../packages/hunk/src/session/broker/brokerConfig"; -import { LEGACY_THEME_ID_ALIASES } from "../packages/hunk/src/core/theme/catalog"; +} from "../../packages/hunk/src/session/broker/brokerConfig"; +import { LEGACY_THEME_ID_ALIASES } from "../../packages/hunk/src/core/theme/catalog"; import { generateDocsArtifacts, GENERATED_DOC_PATHS, diff --git a/scripts/generate-docs.ts b/scripts/generate/generate-docs.ts similarity index 97% rename from scripts/generate-docs.ts rename to scripts/generate/generate-docs.ts index d5c6ce71f..a8f2b1b8b 100644 --- a/scripts/generate-docs.ts +++ b/scripts/generate/generate-docs.ts @@ -6,30 +6,30 @@ import { type CliReferenceCommand, type CliReferenceOption, WATCH_OPTION, -} from "../packages/hunk/src/app/cli"; +} from "../../packages/hunk/src/app/cli"; import { BUILT_IN_THEME_IDS, CONFIG_COMMAND_SECTIONS, CONFIG_REFERENCE_CUSTOM_THEME, CONFIG_REFERENCE_EXTENSIONS, CONFIG_REFERENCE_OPTIONS, -} from "../packages/hunk/src/core/run/config"; -import { renderHunkReviewSkill } from "../packages/hunk/src/hunk-review/skillDocument"; +} from "../../packages/hunk/src/core/run/config"; +import { renderHunkReviewSkill } from "../../packages/hunk/src/hunk-review/skillDocument"; import { type AgentCommandOption, SESSION_AGENT_COMMAND_LIST, -} from "../packages/hunk/src/session/agent/surface"; +} from "../../packages/hunk/src/session/agent/surface"; import { DEFAULT_SESSION_BROKER_HOST, DEFAULT_SESSION_BROKER_PORT, SESSION_BROKER_HOST_ENV, SESSION_BROKER_PORT_ENV, UNSAFE_ALLOW_REMOTE_SESSION_BROKER_ENV, -} from "../packages/hunk/src/session/broker/brokerConfig"; +} from "../../packages/hunk/src/session/broker/brokerConfig"; -const REPO_ROOT = resolve(import.meta.dir, ".."); +const REPO_ROOT = resolve(import.meta.dir, "../.."); const GENERATED_NOTICE = - ""; + ""; export const GENERATED_DOC_PATHS = { cli: resolve(REPO_ROOT, "website", "src", "content", "docs", "docs", "reference", "cli.md"), diff --git a/scripts/generate-skill.ts b/scripts/generate/generate-skill.ts similarity index 84% rename from scripts/generate-skill.ts rename to scripts/generate/generate-skill.ts index 2c3d0743c..5115c7ee3 100644 --- a/scripts/generate-skill.ts +++ b/scripts/generate/generate-skill.ts @@ -1,5 +1,5 @@ import { join } from "node:path"; -import { renderHunkReviewSkill } from "../packages/hunk/src/hunk-review/skillDocument"; +import { renderHunkReviewSkill } from "../../packages/hunk/src/hunk-review/skillDocument"; /** * Regenerate `packages/hunk/skills/hunk-review/SKILL.md` from the typed agent surface. The checked-in @@ -8,7 +8,7 @@ import { renderHunkReviewSkill } from "../packages/hunk/src/hunk-review/skillDoc */ const skillPath = join( import.meta.dir, - "..", + "../..", "packages", "hunk", "skills", diff --git a/scripts/generate-theme-diff-colors.test.ts b/scripts/generate/generate-theme-diff-colors.test.ts similarity index 98% rename from scripts/generate-theme-diff-colors.test.ts rename to scripts/generate/generate-theme-diff-colors.test.ts index 4198c43cd..9ac8af029 100644 --- a/scripts/generate-theme-diff-colors.test.ts +++ b/scripts/generate/generate-theme-diff-colors.test.ts @@ -1,6 +1,6 @@ import { describe, expect, test } from "bun:test"; import { dirname, join, resolve } from "node:path"; -import { BUNDLED_SHIKI_THEME_DIFF_COLORS } from "../packages/hunk/src/core/theme/catalog"; +import { BUNDLED_SHIKI_THEME_DIFF_COLORS } from "../../packages/hunk/src/core/theme/catalog"; import { harvestBundledThemeDiffColors, harvestThemeDiffColors, @@ -113,7 +113,7 @@ describe("checked-in catalog table", () => { test("resolves the catalog inside packages/hunk", async () => { const expected = resolve( import.meta.dir, - "..", + "../..", "packages", "hunk", "src", diff --git a/scripts/generate-theme-diff-colors.ts b/scripts/generate/generate-theme-diff-colors.ts similarity index 98% rename from scripts/generate-theme-diff-colors.ts rename to scripts/generate/generate-theme-diff-colors.ts index f06787e6e..271013469 100644 --- a/scripts/generate-theme-diff-colors.ts +++ b/scripts/generate/generate-theme-diff-colors.ts @@ -4,7 +4,7 @@ import { BUNDLED_SHIKI_THEME_BACKGROUNDS, type BundledShikiThemeDiffColors, type BundledShikiThemeId, -} from "../packages/hunk/src/core/theme/catalog"; +} from "../../packages/hunk/src/core/theme/catalog"; /** * Regenerates `BUNDLED_SHIKI_THEME_DIFF_COLORS` in @@ -231,7 +231,7 @@ function renderDiffColorTable( /** Resolves the Hunk package's checked-in theme catalog from this generator's directory. */ export function resolveThemeCatalogPath(scriptDirectory = import.meta.dir) { - return join(scriptDirectory, "..", "packages", "hunk", "src", "core", "theme", "catalog.ts"); + return join(scriptDirectory, "../..", "packages", "hunk", "src", "core", "theme", "catalog.ts"); } /** Rewrites the generated table region of catalog.ts in place. */ diff --git a/scripts/build-prebuilt-artifact.test.ts b/scripts/packaging/build-prebuilt-artifact.test.ts similarity index 97% rename from scripts/build-prebuilt-artifact.test.ts rename to scripts/packaging/build-prebuilt-artifact.test.ts index ca337c98f..3bbe0be44 100644 --- a/scripts/build-prebuilt-artifact.test.ts +++ b/scripts/packaging/build-prebuilt-artifact.test.ts @@ -2,7 +2,7 @@ import { existsSync, mkdtempSync, mkdirSync, rmSync, statSync, writeFileSync } f import os from "node:os"; import path from "node:path"; import { afterEach, describe, expect, test } from "bun:test"; -import { BUNDLED_SKILL_NAMES } from "../packages/hunk/src/core/run/paths"; +import { BUNDLED_SKILL_NAMES } from "../../packages/hunk/src/core/run/paths"; import { stagePrebuiltArtifact } from "./build-prebuilt-artifact"; import { binaryFilenameForSpec, getHostPlatformPackageSpec } from "./prebuilt-package-helpers"; diff --git a/scripts/build-prebuilt-artifact.ts b/scripts/packaging/build-prebuilt-artifact.ts similarity index 97% rename from scripts/build-prebuilt-artifact.ts rename to scripts/packaging/build-prebuilt-artifact.ts index be75543b4..2ee991207 100644 --- a/scripts/build-prebuilt-artifact.ts +++ b/scripts/packaging/build-prebuilt-artifact.ts @@ -2,7 +2,7 @@ import { chmodSync, cpSync, existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs"; import path from "node:path"; -import { BUNDLED_SKILL_NAMES } from "../packages/hunk/src/core/run/paths"; +import { BUNDLED_SKILL_NAMES } from "../../packages/hunk/src/core/run/paths"; import { binaryFilenameForSpec, getHostPlatformPackageSpec, @@ -41,7 +41,7 @@ export interface StagePrebuiltArtifactOptions { /** Stage one standalone prebuilt release artifact for the current host. */ export function stagePrebuiltArtifact(options: StagePrebuiltArtifactOptions = {}) { - const repoRoot = path.resolve(options.repoRoot ?? path.resolve(import.meta.dir, "..")); + const repoRoot = path.resolve(options.repoRoot ?? path.resolve(import.meta.dir, "../..")); const spec = getHostPlatformPackageSpec(); const binaryName = binaryFilenameForSpec(spec); const compiledBinaryCandidates = [ diff --git a/scripts/check-pack.ts b/scripts/packaging/check-pack.ts similarity index 99% rename from scripts/check-pack.ts rename to scripts/packaging/check-pack.ts index d219ae687..86104e74d 100644 --- a/scripts/check-pack.ts +++ b/scripts/packaging/check-pack.ts @@ -7,7 +7,7 @@ import { buildDocExamples } from "./extension-doc-examples"; import { checkPackedPublicConsumers } from "./packed-public-consumer-check"; import { npmCommand } from "./script-helpers"; -const repoRoot = path.resolve(import.meta.dir, ".."); +const repoRoot = path.resolve(import.meta.dir, "../.."); /** * A representative extension, written the way an author would write one. diff --git a/scripts/check-prebuilt-pack.ts b/scripts/packaging/check-prebuilt-pack.ts similarity index 98% rename from scripts/check-prebuilt-pack.ts rename to scripts/packaging/check-prebuilt-pack.ts index 8d28f09b1..d6819f63a 100644 --- a/scripts/check-prebuilt-pack.ts +++ b/scripts/packaging/check-prebuilt-pack.ts @@ -67,7 +67,7 @@ function assertPaths(pack: PackResult, requiredPaths: string[]) { } } -const repoRoot = path.resolve(import.meta.dir, ".."); +const repoRoot = path.resolve(import.meta.dir, "../.."); const releaseRoot = releaseNpmDir(repoRoot); const metaDir = path.join(releaseRoot, "hunkdiff"); diff --git a/scripts/extension-consumer-check.ts b/scripts/packaging/extension-consumer-check.ts similarity index 100% rename from scripts/extension-consumer-check.ts rename to scripts/packaging/extension-consumer-check.ts diff --git a/scripts/extension-doc-examples.test.ts b/scripts/packaging/extension-doc-examples.test.ts similarity index 100% rename from scripts/extension-doc-examples.test.ts rename to scripts/packaging/extension-doc-examples.test.ts diff --git a/scripts/extension-doc-examples.ts b/scripts/packaging/extension-doc-examples.ts similarity index 100% rename from scripts/extension-doc-examples.ts rename to scripts/packaging/extension-doc-examples.ts diff --git a/scripts/install-sh.test.ts b/scripts/packaging/install-sh.test.ts similarity index 99% rename from scripts/install-sh.test.ts rename to scripts/packaging/install-sh.test.ts index 3c870b9bd..d1d172c40 100644 --- a/scripts/install-sh.test.ts +++ b/scripts/packaging/install-sh.test.ts @@ -14,7 +14,7 @@ import { PLATFORM_PACKAGE_MATRIX } from "./prebuilt-package-helpers"; /** * Covers `install.sh` at the repository root, the script published at https://hunk.dev/install.sh - * (staged into the website build by `scripts/stage-install-script.ts`). + * (staged into the website build by `scripts/packaging/stage-install-script.ts`). * * The script is the one piece of Hunk that runs before Hunk exists, so it is checked as text and * as a shell program: it must parse under a POSIX shell, name the same release archives the @@ -23,7 +23,7 @@ import { PLATFORM_PACKAGE_MATRIX } from "./prebuilt-package-helpers"; * shell, so they stay Unix-only. */ -const REPO_ROOT = resolve(import.meta.dir, ".."); +const REPO_ROOT = resolve(import.meta.dir, "../.."); const INSTALL_SCRIPT_PATH = join(REPO_ROOT, "install.sh"); const INSTALL_SCRIPT = readFileSync(INSTALL_SCRIPT_PATH, "utf8"); diff --git a/scripts/packed-public-consumer-check.ts b/scripts/packaging/packed-public-consumer-check.ts similarity index 100% rename from scripts/packed-public-consumer-check.ts rename to scripts/packaging/packed-public-consumer-check.ts diff --git a/scripts/prebuilt-package-helpers.test.ts b/scripts/packaging/prebuilt-package-helpers.test.ts similarity index 100% rename from scripts/prebuilt-package-helpers.test.ts rename to scripts/packaging/prebuilt-package-helpers.test.ts diff --git a/scripts/prebuilt-package-helpers.ts b/scripts/packaging/prebuilt-package-helpers.ts similarity index 100% rename from scripts/prebuilt-package-helpers.ts rename to scripts/packaging/prebuilt-package-helpers.ts diff --git a/scripts/publish-prebuilt-npm.ts b/scripts/packaging/publish-prebuilt-npm.ts similarity index 98% rename from scripts/publish-prebuilt-npm.ts rename to scripts/packaging/publish-prebuilt-npm.ts index d830c05eb..561c06bda 100644 --- a/scripts/publish-prebuilt-npm.ts +++ b/scripts/packaging/publish-prebuilt-npm.ts @@ -84,7 +84,7 @@ function publishDirectory(directory: string, dryRun: boolean, npmTag: string) { } } -const repoRoot = path.resolve(import.meta.dir, ".."); +const repoRoot = path.resolve(import.meta.dir, "../.."); const releaseRoot = releaseNpmDir(repoRoot); const options = parseArgs(process.argv.slice(2)); diff --git a/scripts/script-helpers.ts b/scripts/packaging/script-helpers.ts similarity index 100% rename from scripts/script-helpers.ts rename to scripts/packaging/script-helpers.ts diff --git a/scripts/smoke-prebuilt-install.ts b/scripts/packaging/smoke-prebuilt-install.ts similarity index 99% rename from scripts/smoke-prebuilt-install.ts rename to scripts/packaging/smoke-prebuilt-install.ts index f67eaa7c0..05cf23200 100644 --- a/scripts/smoke-prebuilt-install.ts +++ b/scripts/packaging/smoke-prebuilt-install.ts @@ -86,7 +86,7 @@ function commandDirectory(command: string) { return path.dirname(commandPath(command)); } -const repoRoot = path.resolve(import.meta.dir, ".."); +const repoRoot = path.resolve(import.meta.dir, "../.."); const packageVersion = JSON.parse( await Bun.file(path.join(repoRoot, "packages", "hunk", "package.json")).text(), ).version as string; diff --git a/scripts/stage-install-script.ts b/scripts/packaging/stage-install-script.ts similarity index 95% rename from scripts/stage-install-script.ts rename to scripts/packaging/stage-install-script.ts index 091b42351..ec3a63877 100644 --- a/scripts/stage-install-script.ts +++ b/scripts/packaging/stage-install-script.ts @@ -10,7 +10,7 @@ import { join, resolve } from "node:path"; * dist directory means the build order is wrong and the copy must fail rather than invent one. */ -const REPO_ROOT = resolve(import.meta.dir, ".."); +const REPO_ROOT = resolve(import.meta.dir, "../.."); const SOURCE = join(REPO_ROOT, "install.sh"); const DIST_DIR = join(REPO_ROOT, "website", "dist"); diff --git a/scripts/stage-prebuilt-npm.ts b/scripts/packaging/stage-prebuilt-npm.ts similarity index 99% rename from scripts/stage-prebuilt-npm.ts rename to scripts/packaging/stage-prebuilt-npm.ts index 9aaf142bd..556b33e24 100644 --- a/scripts/stage-prebuilt-npm.ts +++ b/scripts/packaging/stage-prebuilt-npm.ts @@ -169,7 +169,7 @@ function collectArtifactSpecs(artifactRoot: string) { }); } -const repoRoot = path.resolve(import.meta.dir, ".."); +const repoRoot = path.resolve(import.meta.dir, "../.."); const options = parseArgs(process.argv.slice(2)); const rootPackage = loadRootPackage(repoRoot); const releaseRoot = releaseNpmDir(repoRoot); diff --git a/scripts/hunk-git-package.test.ts b/scripts/quality/hunk-git-package.test.ts similarity index 97% rename from scripts/hunk-git-package.test.ts rename to scripts/quality/hunk-git-package.test.ts index 77ab0799b..03f71b0b4 100644 --- a/scripts/hunk-git-package.test.ts +++ b/scripts/quality/hunk-git-package.test.ts @@ -3,7 +3,7 @@ import gitExtension, { GitVcsAdapter } from "@hunk/git"; import { readFileSync } from "node:fs"; import { join, resolve } from "node:path"; -const REPO_ROOT = resolve(import.meta.dir, ".."); +const REPO_ROOT = resolve(import.meta.dir, "../.."); const PACKAGE_ROOT = join(REPO_ROOT, "packages", "hunk-git"); describe("@hunk/git package boundary", () => { diff --git a/scripts/hunk-jj-package.test.ts b/scripts/quality/hunk-jj-package.test.ts similarity index 97% rename from scripts/hunk-jj-package.test.ts rename to scripts/quality/hunk-jj-package.test.ts index 3f4d6bfc9..f1dbbd49c 100644 --- a/scripts/hunk-jj-package.test.ts +++ b/scripts/quality/hunk-jj-package.test.ts @@ -3,7 +3,7 @@ import jjExtension, { JjVcsAdapter } from "@hunk/jj"; import { readFileSync } from "node:fs"; import { join, resolve } from "node:path"; -const REPO_ROOT = resolve(import.meta.dir, ".."); +const REPO_ROOT = resolve(import.meta.dir, "../.."); const PACKAGE_ROOT = join(REPO_ROOT, "packages", "hunk-jj"); describe("@hunk/jj package boundary", () => { diff --git a/scripts/hunk-sapling-package.test.ts b/scripts/quality/hunk-sapling-package.test.ts similarity index 97% rename from scripts/hunk-sapling-package.test.ts rename to scripts/quality/hunk-sapling-package.test.ts index 0844f9417..0e5f1b4e9 100644 --- a/scripts/hunk-sapling-package.test.ts +++ b/scripts/quality/hunk-sapling-package.test.ts @@ -3,7 +3,7 @@ import slExtension, { SaplingVcsAdapter } from "@hunk/sapling"; import { readFileSync } from "node:fs"; import { join, resolve } from "node:path"; -const REPO_ROOT = resolve(import.meta.dir, ".."); +const REPO_ROOT = resolve(import.meta.dir, "../.."); const PACKAGE_ROOT = join(REPO_ROOT, "packages", "hunk-sapling"); describe("@hunk/sapling package boundary", () => { diff --git a/scripts/hunk-vcs-package.test.ts b/scripts/quality/hunk-vcs-package.test.ts similarity index 98% rename from scripts/hunk-vcs-package.test.ts rename to scripts/quality/hunk-vcs-package.test.ts index a15ebb63e..5e776f99b 100644 --- a/scripts/hunk-vcs-package.test.ts +++ b/scripts/quality/hunk-vcs-package.test.ts @@ -3,7 +3,7 @@ import { cpSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:f import { tmpdir } from "node:os"; import { join, resolve } from "node:path"; -const REPO_ROOT = resolve(import.meta.dir, ".."); +const REPO_ROOT = resolve(import.meta.dir, "../.."); const PACKAGE_ROOT = join(REPO_ROOT, "packages", "hunk-vcs"); const EXPECTED_EXPORTS = ["./async-process", "./diff-target", "./large-file", "./path", "./source"]; const tempDirs: string[] = []; diff --git a/scripts/inline-edit-extension.test.ts b/scripts/quality/inline-edit-extension.test.ts similarity index 98% rename from scripts/inline-edit-extension.test.ts rename to scripts/quality/inline-edit-extension.test.ts index 14db47c41..9b5c25620 100644 --- a/scripts/inline-edit-extension.test.ts +++ b/scripts/quality/inline-edit-extension.test.ts @@ -9,11 +9,11 @@ import type { ExtensionKeyEvent, ExtensionWorkspaceWriteResult, HunkExtensionAPI, -} from "../packages/hunk/src/extension-api/types"; -import { validateFileViewLayout } from "../packages/hunk/src/ui/fileViews/layout"; -import { buildFileViewRenderPlan } from "../packages/hunk/src/ui/fileViews/renderPlan"; -import { createVisibleAgentNote } from "../packages/hunk/src/ui/lib/agentAnnotations"; -import inlineEditExtension from "../examples/extensions/inline-edit"; +} from "../../packages/hunk/src/extension-api/types"; +import { validateFileViewLayout } from "../../packages/hunk/src/ui/fileViews/layout"; +import { buildFileViewRenderPlan } from "../../packages/hunk/src/ui/fileViews/renderPlan"; +import { createVisibleAgentNote } from "../../packages/hunk/src/ui/lib/agentAnnotations"; +import inlineEditExtension from "../../examples/extensions/inline-edit"; const TEST_FILE = { id: "alpha", diff --git a/scripts/jsx-file-view-gallery.test.ts b/scripts/quality/jsx-file-view-gallery.test.ts similarity index 95% rename from scripts/jsx-file-view-gallery.test.ts rename to scripts/quality/jsx-file-view-gallery.test.ts index 92555e396..c0f6c43fa 100644 --- a/scripts/jsx-file-view-gallery.test.ts +++ b/scripts/quality/jsx-file-view-gallery.test.ts @@ -6,19 +6,19 @@ import type { ExtensionCommandHandler, ExtensionFileView, HunkExtensionAPI, -} from "../packages/hunk/src/extension-api/types"; -import { createTestDiffFile, createTestSourceFetcher } from "../test/helpers/diff-helpers"; +} from "../../packages/hunk/src/extension-api/types"; +import { createTestDiffFile, createTestSourceFetcher } from "../../test/helpers/diff-helpers"; import galleryExtension, { createChangeAtlasLayout, createCssPaletteLayout, createDependencyLayout, impactMeter, versionChangeHighlights, -} from "../examples/extensions/jsx-file-view-gallery"; -import { createFileViewInput, fileViewHunkCount } from "../packages/hunk/src/ui/fileViews/host"; -import { validateFileViewLayout } from "../packages/hunk/src/ui/fileViews/layout"; +} from "../../examples/extensions/jsx-file-view-gallery"; +import { createFileViewInput, fileViewHunkCount } from "../../packages/hunk/src/ui/fileViews/host"; +import { validateFileViewLayout } from "../../packages/hunk/src/ui/fileViews/layout"; -const galleryRoot = join(import.meta.dir, "../examples/extensions/jsx-file-view-gallery"); +const galleryRoot = join(import.meta.dir, "../../examples/extensions/jsx-file-view-gallery"); /** Build a real parsed diff input backed by one checked-in gallery fixture pair. */ function fixtureInput(fixture: string, beforePath: string, afterPath: string, displayPath: string) { diff --git a/scripts/nix-package.test.ts b/scripts/quality/nix-package.test.ts similarity index 95% rename from scripts/nix-package.test.ts rename to scripts/quality/nix-package.test.ts index 796690617..207632173 100644 --- a/scripts/nix-package.test.ts +++ b/scripts/quality/nix-package.test.ts @@ -2,7 +2,7 @@ import { describe, expect, test } from "bun:test"; import { readFileSync } from "node:fs"; import path from "node:path"; -const definition = readFileSync(path.resolve(import.meta.dir, "../nix/package.nix"), "utf8"); +const definition = readFileSync(path.resolve(import.meta.dir, "../../nix/package.nix"), "utf8"); describe("Nix package-first paths", () => { test("reads the publishable manifest and compiles the moved application entry", () => { diff --git a/scripts/rendered-markdown-extension.test.ts b/scripts/quality/rendered-markdown-extension.test.ts similarity index 97% rename from scripts/rendered-markdown-extension.test.ts rename to scripts/quality/rendered-markdown-extension.test.ts index a84be988f..7923c73d4 100644 --- a/scripts/rendered-markdown-extension.test.ts +++ b/scripts/quality/rendered-markdown-extension.test.ts @@ -4,8 +4,8 @@ import type { ExtensionCommandHandler, ExtensionFileView, HunkExtensionAPI, -} from "../packages/hunk/src/extension-api/types"; -import renderedMarkdownExtension from "../examples/extensions/rendered-markdown"; +} from "../../packages/hunk/src/extension-api/types"; +import renderedMarkdownExtension from "../../examples/extensions/rendered-markdown"; function registerMarkdownTestView() { let view: ExtensionFileView | undefined; diff --git a/scripts/review-vocabulary.test.ts b/scripts/quality/review-vocabulary.test.ts similarity index 94% rename from scripts/review-vocabulary.test.ts rename to scripts/quality/review-vocabulary.test.ts index 32380c87f..cab15712d 100644 --- a/scripts/review-vocabulary.test.ts +++ b/scripts/quality/review-vocabulary.test.ts @@ -25,20 +25,20 @@ import { describe, expect, test } from "bun:test"; import { readdirSync, readFileSync } from "node:fs"; import { join, resolve, sep } from "node:path"; import { MAX_WS_MESSAGE_BYTES } from "@hunk/session-broker-core"; -import { REVIEW_INTENT_TYPES } from "../packages/hunk/src/core/review/intents"; -import { REVIEW_RESOURCE_CHUNK_BYTES } from "../packages/hunk/src/core/review/resources"; +import { REVIEW_INTENT_TYPES } from "../../packages/hunk/src/core/review/intents"; +import { REVIEW_RESOURCE_CHUNK_BYTES } from "../../packages/hunk/src/core/review/resources"; import { MAX_REVIEW_EVENT_CHUNKS, MAX_REVIEW_EVENT_PAYLOAD_BYTES, REVIEW_EVENT_CHUNK_BYTES, -} from "../packages/hunk/src/session/reviewEventProtocol"; +} from "../../packages/hunk/src/session/reviewEventProtocol"; import { HUNK_REVIEW_ACTION_TYPES, MAX_HUNK_REVIEW_ENVELOPE_BYTES, parseHunkReviewAction, -} from "../packages/hunk/src/session/reviewProtocol"; +} from "../../packages/hunk/src/session/reviewProtocol"; -const REPO_ROOT = resolve(import.meta.dir, ".."); +const REPO_ROOT = resolve(import.meta.dir, "../.."); const HUNK_SOURCE_ROOT = join(REPO_ROOT, "packages", "hunk", "src"); const REVIEW_MODEL_ROOT = join(HUNK_SOURCE_ROOT, "core", "review"); const SESSION_ROOT = join(HUNK_SOURCE_ROOT, "session"); diff --git a/scripts/source-boundaries.test.ts b/scripts/quality/source-boundaries.test.ts similarity index 99% rename from scripts/source-boundaries.test.ts rename to scripts/quality/source-boundaries.test.ts index 5c7d672e5..ad335fe69 100644 --- a/scripts/source-boundaries.test.ts +++ b/scripts/quality/source-boundaries.test.ts @@ -2,7 +2,7 @@ import { describe, expect, test } from "bun:test"; import { existsSync, readdirSync, readFileSync } from "node:fs"; import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path"; -const REPO_ROOT = resolve(import.meta.dir, ".."); +const REPO_ROOT = resolve(import.meta.dir, "../.."); const SRC_ROOT = join(REPO_ROOT, "packages", "hunk", "src"); const CORE_ROOT = join(SRC_ROOT, "core"); const EXTENSIONS_ROOT = join(SRC_ROOT, "extensions"); diff --git a/scripts/vim-navigation-extension.test.ts b/scripts/quality/vim-navigation-extension.test.ts similarity index 98% rename from scripts/vim-navigation-extension.test.ts rename to scripts/quality/vim-navigation-extension.test.ts index ae85f0e33..0926b7880 100644 --- a/scripts/vim-navigation-extension.test.ts +++ b/scripts/quality/vim-navigation-extension.test.ts @@ -2,7 +2,7 @@ import { describe, expect, test } from "bun:test"; import { createVimNavigationState, executeVimCommand, -} from "../examples/extensions/vim-navigation/state"; +} from "../../examples/extensions/vim-navigation/state"; /** Record semantic executions made by the example grammar. */ function recordingState() { diff --git a/scripts/changeset-version.test.ts b/scripts/release/changeset-version.test.ts similarity index 100% rename from scripts/changeset-version.test.ts rename to scripts/release/changeset-version.test.ts diff --git a/scripts/changeset-version.ts b/scripts/release/changeset-version.ts similarity index 96% rename from scripts/changeset-version.ts rename to scripts/release/changeset-version.ts index 874a253c8..35e9a375d 100644 --- a/scripts/changeset-version.ts +++ b/scripts/release/changeset-version.ts @@ -10,7 +10,7 @@ import { copyFileSync, existsSync, rmSync } from "node:fs"; import path from "node:path"; -import { HUNK_PACKAGE_ROOT, REPO_ROOT } from "./package-paths"; +import { HUNK_PACKAGE_ROOT, REPO_ROOT } from "../build/package-paths"; export interface ChangesetVersionPaths { repoRoot: string; diff --git a/scripts/check-release-version.ts b/scripts/release/check-release-version.ts similarity index 80% rename from scripts/check-release-version.ts rename to scripts/release/check-release-version.ts index 4d75aac55..f13390090 100644 --- a/scripts/check-release-version.ts +++ b/scripts/release/check-release-version.ts @@ -2,7 +2,7 @@ import path from "node:path"; -const repoRoot = path.resolve(import.meta.dir, ".."); +const repoRoot = path.resolve(import.meta.dir, "../.."); const packageJson = JSON.parse( await Bun.file(path.join(repoRoot, "packages", "hunk", "package.json")).text(), ) as { @@ -11,7 +11,7 @@ const packageJson = JSON.parse( const refName = process.argv[2]; if (!refName) { - throw new Error("Usage: bun run ./scripts/check-release-version.ts "); + throw new Error("Usage: bun run ./scripts/release/check-release-version.ts "); } const expectedTag = `v${packageJson.version}`; diff --git a/scripts/resolve-release-channel.test.ts b/scripts/release/resolve-release-channel.test.ts similarity index 100% rename from scripts/resolve-release-channel.test.ts rename to scripts/release/resolve-release-channel.test.ts diff --git a/scripts/resolve-release-channel.ts b/scripts/release/resolve-release-channel.ts similarity index 100% rename from scripts/resolve-release-channel.ts rename to scripts/release/resolve-release-channel.ts diff --git a/scripts/verify-pr-release-notes.test.ts b/scripts/release/verify-pr-release-notes.test.ts similarity index 99% rename from scripts/verify-pr-release-notes.test.ts rename to scripts/release/verify-pr-release-notes.test.ts index c2fa53644..6f3a0e0eb 100644 --- a/scripts/verify-pr-release-notes.test.ts +++ b/scripts/release/verify-pr-release-notes.test.ts @@ -2,7 +2,7 @@ import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync import os from "node:os"; import path from "node:path"; import { afterEach, describe, expect, test } from "bun:test"; -import { removeTestDirectory } from "../test/helpers/filesystem"; +import { removeTestDirectory } from "../../test/helpers/filesystem"; import { isGeneratedPrereleasePreparation, isGeneratedReleasePath, diff --git a/scripts/verify-pr-release-notes.ts b/scripts/release/verify-pr-release-notes.ts similarity index 99% rename from scripts/verify-pr-release-notes.ts rename to scripts/release/verify-pr-release-notes.ts index dfbf4552f..898776515 100644 --- a/scripts/verify-pr-release-notes.ts +++ b/scripts/release/verify-pr-release-notes.ts @@ -22,7 +22,7 @@ interface GeneratedPrereleaseInput { changesetIdsOnDisk: ReadonlySet; } -const repoRoot = path.resolve(import.meta.dir, ".."); +const repoRoot = path.resolve(import.meta.dir, "../.."); const RELEASE_BENCHMARK_PATTERN = /^benchmarks\/release\/bench-[^/]+\.json$/; const CHANGESET_PATTERN = /^\.changeset\/[^/]+\.md$/; diff --git a/scripts/run-test-suite.test.ts b/scripts/test/run-test-suite.test.ts similarity index 100% rename from scripts/run-test-suite.test.ts rename to scripts/test/run-test-suite.test.ts diff --git a/scripts/run-test-suite.ts b/scripts/test/run-test-suite.ts similarity index 100% rename from scripts/run-test-suite.ts rename to scripts/test/run-test-suite.ts diff --git a/scripts/test-session-broker-node.ts b/scripts/test/test-session-broker-node.ts similarity index 100% rename from scripts/test-session-broker-node.ts rename to scripts/test/test-session-broker-node.ts diff --git a/scripts/check-comparison-catalog.test.ts b/scripts/website/check-comparison-catalog.test.ts similarity index 96% rename from scripts/check-comparison-catalog.test.ts rename to scripts/website/check-comparison-catalog.test.ts index 0a6e6ace0..a77ae5988 100644 --- a/scripts/check-comparison-catalog.test.ts +++ b/scripts/website/check-comparison-catalog.test.ts @@ -1,6 +1,6 @@ import { describe, expect, test } from "bun:test"; -import { BUNDLED_SHIKI_THEME_IDS } from "../packages/hunk/src/core/theme/catalog"; -import { COMPARISONS, COMPARISONS_REVIEWED_ON } from "../website/src/data/comparisons"; +import { BUNDLED_SHIKI_THEME_IDS } from "../../packages/hunk/src/core/theme/catalog"; +import { COMPARISONS, COMPARISONS_REVIEWED_ON } from "../../website/src/data/comparisons"; /** * The hunk.dev comparison catalog, held to the standard the pages claim. diff --git a/scripts/check-extension-catalog.test.ts b/scripts/website/check-extension-catalog.test.ts similarity index 95% rename from scripts/check-extension-catalog.test.ts rename to scripts/website/check-extension-catalog.test.ts index 3b88d47b2..9e5404646 100644 --- a/scripts/check-extension-catalog.test.ts +++ b/scripts/website/check-extension-catalog.test.ts @@ -1,6 +1,6 @@ import { describe, expect, test } from "bun:test"; -import { HUNK_EXTENSION_API_VERSION } from "../packages/hunk/src/extension-api/types"; -import { parseExtensionInstallSource } from "../packages/hunk/src/extensions/manage/source"; +import { HUNK_EXTENSION_API_VERSION } from "../../packages/hunk/src/extension-api/types"; +import { parseExtensionInstallSource } from "../../packages/hunk/src/extensions/manage/source"; import { EXTENSION_CATALOG, avatarUrl, @@ -10,7 +10,7 @@ import { installCommand, ownerOf, repositoryUrl, -} from "../website/src/data/extensions"; +} from "../../website/src/data/extensions"; /** * The hunk.dev extension directory is hand-curated, so nothing but a test keeps diff --git a/scripts/check-website-helpers.test.ts b/scripts/website/check-website-helpers.test.ts similarity index 94% rename from scripts/check-website-helpers.test.ts rename to scripts/website/check-website-helpers.test.ts index 12941ec1e..9b40064d1 100644 --- a/scripts/check-website-helpers.test.ts +++ b/scripts/website/check-website-helpers.test.ts @@ -1,8 +1,8 @@ import { describe, expect, test } from "bun:test"; -import { COMPARISONS, type Comparison } from "../website/src/data/comparisons"; -import { renderComparisonMarkdown } from "../website/src/lib/comparisonMarkdown"; -import { withInlineCode, withoutInlineCode } from "../website/src/lib/inlineCode"; -import { toJsonLdScriptBody } from "../website/src/lib/jsonLd"; +import { COMPARISONS, type Comparison } from "../../website/src/data/comparisons"; +import { renderComparisonMarkdown } from "../../website/src/lib/comparisonMarkdown"; +import { withInlineCode, withoutInlineCode } from "../../website/src/lib/inlineCode"; +import { toJsonLdScriptBody } from "../../website/src/lib/jsonLd"; /** * The hunk.dev helpers that turn stored text into markup. diff --git a/scripts/check-website-links.test.ts b/scripts/website/check-website-links.test.ts similarity index 100% rename from scripts/check-website-links.test.ts rename to scripts/website/check-website-links.test.ts diff --git a/scripts/check-website-links.ts b/scripts/website/check-website-links.ts similarity index 99% rename from scripts/check-website-links.ts rename to scripts/website/check-website-links.ts index e365714de..e04f26bd6 100644 --- a/scripts/check-website-links.ts +++ b/scripts/website/check-website-links.ts @@ -1,7 +1,7 @@ import { existsSync, readFileSync, readdirSync } from "node:fs"; import { join, relative, resolve, sep } from "node:path"; -const REPO_ROOT = resolve(import.meta.dir, ".."); +const REPO_ROOT = resolve(import.meta.dir, "../.."); const DEFAULT_DIST_DIR = join(REPO_ROOT, "website", "dist"); const CANONICAL_ORIGIN = "https://hunk.dev"; const EDIT_PREFIX = "https://github.com/modem-dev/hunk/edit/main/"; diff --git a/test/README.md b/test/README.md index 910a701d5..9e55daeb7 100644 --- a/test/README.md +++ b/test/README.md @@ -33,13 +33,13 @@ test/ ## Commands and coverage -| Command | Coverage | -| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------- | -| `bun run test` | `packages/`, `scripts/`, `examples/`, `test/cli/`, and `test/session/`, as defined by `scripts/run-test-suite.ts` | -| `bun test ./test/review-conformance` | Shared review fixtures and registered consumer projections | -| `bun run test:session-broker-node` | Real Node listener/adapter conformance using the checked-in cross-runtime fixtures | -| `bun run test:integration` | PTY-backed tests under `test/pty/` | -| `bun run test:tty-smoke` | Opt-in real-TTY smoke tests under `test/smoke/` | +| Command | Coverage | +| ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- | +| `bun run test` | `packages/`, `scripts/`, `examples/`, `test/cli/`, and `test/session/`, as defined by `scripts/test/run-test-suite.ts` | +| `bun test ./test/review-conformance` | Shared review fixtures and registered consumer projections | +| `bun run test:session-broker-node` | Real Node listener/adapter conformance using the checked-in cross-runtime fixtures | +| `bun run test:integration` | PTY-backed tests under `test/pty/` | +| `bun run test:tty-smoke` | Opt-in real-TTY smoke tests under `test/smoke/` | The dedicated trees are not selected directly by `bun run test`, though package tests import some shared runtime fixtures. Run the commands that match the changed behavior; omission from the default diff --git a/test/cli/install-vm/prepare-daemon-upgrade-fixtures.ts b/test/cli/install-vm/prepare-daemon-upgrade-fixtures.ts index 7e4cea702..3379cd8d0 100644 --- a/test/cli/install-vm/prepare-daemon-upgrade-fixtures.ts +++ b/test/cli/install-vm/prepare-daemon-upgrade-fixtures.ts @@ -309,7 +309,7 @@ async function buildVariant( rewriteDaemonUpgradeVariantSources(destination, packageVersion, daemonRevision); const compiler = createDaemonUpgradeCompilerEnvironment(destination); try { - const proc = Bun.spawn([process.execPath, "run", "./scripts/build-bin.ts"], { + const proc = Bun.spawn([process.execPath, "run", "./scripts/build/build-bin.ts"], { cwd: destination, env: compiler.env, stdin: "ignore", diff --git a/test/cli/install-vm/prepare-fixtures.ts b/test/cli/install-vm/prepare-fixtures.ts index 6eac6e200..25799c53e 100644 --- a/test/cli/install-vm/prepare-fixtures.ts +++ b/test/cli/install-vm/prepare-fixtures.ts @@ -22,9 +22,9 @@ import { buildPlatformPackageManifest, getPlatformPackageSpecForHost, releaseNpmDir, -} from "../../../scripts/prebuilt-package-helpers"; -import { stagePrebuiltArtifact } from "../../../scripts/build-prebuilt-artifact"; -import { npmCommand } from "../../../scripts/script-helpers"; +} from "../../../scripts/packaging/prebuilt-package-helpers"; +import { stagePrebuiltArtifact } from "../../../scripts/packaging/build-prebuilt-artifact"; +import { npmCommand } from "../../../scripts/packaging/script-helpers"; import { DAEMON_UPGRADE_VERSION_A, DAEMON_UPGRADE_VERSION_B, diff --git a/vercel.json b/vercel.json index b1a47230c..2ce98fcae 100644 --- a/vercel.json +++ b/vercel.json @@ -1,7 +1,7 @@ { "$schema": "https://openapi.vercel.sh/vercel.json", "framework": "astro", - "ignoreCommand": "git diff --quiet HEAD^ HEAD -- ./website ./vercel.json ./install.sh ./scripts/stage-install-script.ts ./scripts/generate-docs.ts ./scripts/generate-changelog.ts ./CHANGELOG.md", + "ignoreCommand": "git diff --quiet HEAD^ HEAD -- ./website ./vercel.json ./install.sh ./scripts/packaging/stage-install-script.ts ./scripts/generate/generate-docs.ts ./scripts/generate/generate-changelog.ts ./CHANGELOG.md", "installCommand": "SKIP_INSTALL_SIMPLE_GIT_HOOKS=1 bun install --frozen-lockfile && bun install --cwd website --frozen-lockfile", "buildCommand": "bun run website:build", "outputDirectory": "website/dist", diff --git a/website/scripts/generate-og.ts b/website/scripts/generate-og.ts index fd8eabd4c..400276dae 100644 --- a/website/scripts/generate-og.ts +++ b/website/scripts/generate-og.ts @@ -38,7 +38,7 @@ const fontFile = join( "jetbrains-mono-latin-wght-normal.woff2", ); -/** Mirrors `SocialCard` in `scripts/generate-changelog.ts`. */ +/** Mirrors `SocialCard` in `scripts/generate/generate-changelog.ts`. */ type SocialCard = { slug: string; title: string; diff --git a/website/src/content/docs/docs/reference/cli.md b/website/src/content/docs/docs/reference/cli.md index 84a0f6d07..19e84dfa8 100644 --- a/website/src/content/docs/docs/reference/cli.md +++ b/website/src/content/docs/docs/reference/cli.md @@ -3,7 +3,7 @@ title: CLI reference description: Exhaustive generated reference for Hunk commands, options, and live-session controls. --- - + This reference is generated from the command metadata used by Hunk itself. Run `hunk --help` or `hunk --help` to inspect the installed version. diff --git a/website/src/content/docs/docs/reference/config.md b/website/src/content/docs/docs/reference/config.md index c7a6978d7..c851864f0 100644 --- a/website/src/content/docs/docs/reference/config.md +++ b/website/src/content/docs/docs/reference/config.md @@ -3,7 +3,7 @@ title: Config reference description: Exhaustive generated reference for Hunk TOML keys, defaults, aliases, and layering. --- - + Hunk reads TOML preferences from the user config and an optional repository config. This reference is generated from the same catalog that `packages/hunk/src/core/run/config.ts` uses to parse preference keys.