From 24045c531b2bdd5f0a2c14a9b40c13a45a45faac Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Wed, 13 May 2026 10:46:05 -0700 Subject: [PATCH 1/7] chore: bumping @npmcli/template-oss from 4.29.0 to 5.1.0 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index c400295..16bc7d9 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^6.0.0", - "@npmcli/template-oss": "4.29.0", + "@npmcli/template-oss": "5.1.0", "@types/mute-stream": "^0.0.4", "@types/tap": "^15.0.11", "@typescript-eslint/parser": "^8.0.1", @@ -62,7 +62,7 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.29.0", + "version": "5.1.0", "publish": true, "typescript": true, "updateNpm": false From 9e2cf21cb8ad661a0fbd2409574111e732ecf040 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Wed, 13 May 2026 10:46:07 -0700 Subject: [PATCH 2/7] feat!: template-oss-apply --- .github/CODEOWNERS | 2 +- .github/workflows/audit.yml | 8 ++++---- .github/workflows/ci-release.yml | 18 ++++++++++++------ .github/workflows/ci.yml | 18 ++++++++++++------ .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/post-dependabot.yml | 8 ++++---- .github/workflows/pull-request.yml | 8 ++++---- .github/workflows/release-integration.yml | 8 ++++---- .github/workflows/release.yml | 16 ++++++++-------- 9 files changed, 50 insertions(+), 38 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 2c54b0d..b6ec921 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,3 +1,3 @@ # This file is automatically added by @npmcli/template-oss. Do not edit. -* @npm/cli-team +* @npm/cli-team @npm/cli-triage diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml index 628ed3b..c9a733f 100644 --- a/.github/workflows/audit.yml +++ b/.github/workflows/audit.yml @@ -21,17 +21,17 @@ jobs: shell: bash steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 id: node with: - node-version: 22.x - check-latest: contains('22.x', '.x') + node-version: 26.x + check-latest: contains('26.x', '.x') - name: Install Dependencies run: npm i --ignore-scripts --no-audit --no-fund --package-lock - name: Run Production Audit diff --git a/.github/workflows/ci-release.yml b/.github/workflows/ci-release.yml index 1284dd6..d92cca1 100644 --- a/.github/workflows/ci-release.yml +++ b/.github/workflows/ci-release.yml @@ -32,7 +32,7 @@ jobs: shell: bash steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: ref: ${{ inputs.ref }} - name: Setup Git User @@ -48,11 +48,11 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} sha: ${{ inputs.check-sha }} - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 id: node with: - node-version: 22.x - check-latest: contains('22.x', '.x') + node-version: 26.x + check-latest: contains('26.x', '.x') - name: Install Dependencies run: npm i --ignore-scripts --no-audit --no-fund - name: Lint @@ -91,6 +91,8 @@ jobs: - 20.x - 22.9.0 - 22.x + - 24.x + - 26.x exclude: - platform: { name: macOS, os: macos-15-intel, shell: bash } node-version: 20.17.0 @@ -100,13 +102,17 @@ jobs: node-version: 22.9.0 - platform: { name: macOS, os: macos-15-intel, shell: bash } node-version: 22.x + - platform: { name: macOS, os: macos-15-intel, shell: bash } + node-version: 24.x + - platform: { name: macOS, os: macos-15-intel, shell: bash } + node-version: 26.x runs-on: ${{ matrix.platform.os }} defaults: run: shell: ${{ matrix.platform.shell }} steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: ref: ${{ inputs.ref }} - name: Setup Git User @@ -122,7 +128,7 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} sha: ${{ inputs.check-sha }} - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 id: node with: node-version: ${{ matrix.node-version }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bd4e34d..2c406e6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,17 +25,17 @@ jobs: shell: bash steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 id: node with: - node-version: 22.x - check-latest: contains('22.x', '.x') + node-version: 26.x + check-latest: contains('26.x', '.x') - name: Install Dependencies run: npm i --ignore-scripts --no-audit --no-fund - name: Lint @@ -67,6 +67,8 @@ jobs: - 20.x - 22.9.0 - 22.x + - 24.x + - 26.x exclude: - platform: { name: macOS, os: macos-15-intel, shell: bash } node-version: 20.17.0 @@ -76,19 +78,23 @@ jobs: node-version: 22.9.0 - platform: { name: macOS, os: macos-15-intel, shell: bash } node-version: 22.x + - platform: { name: macOS, os: macos-15-intel, shell: bash } + node-version: 24.x + - platform: { name: macOS, os: macos-15-intel, shell: bash } + node-version: 26.x runs-on: ${{ matrix.platform.os }} defaults: run: shell: ${{ matrix.platform.shell }} steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 id: node with: node-version: ${{ matrix.node-version }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index af848e1..8c43556 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -26,7 +26,7 @@ jobs: security-events: write steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" diff --git a/.github/workflows/post-dependabot.yml b/.github/workflows/post-dependabot.yml index 8439f84..1118cd5 100644 --- a/.github/workflows/post-dependabot.yml +++ b/.github/workflows/post-dependabot.yml @@ -17,7 +17,7 @@ jobs: shell: bash steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: ref: ${{ github.event.pull_request.head.ref }} - name: Setup Git User @@ -25,11 +25,11 @@ jobs: git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 id: node with: - node-version: 22.x - check-latest: contains('22.x', '.x') + node-version: 26.x + check-latest: contains('26.x', '.x') - name: Install Dependencies run: npm i --ignore-scripts --no-audit --no-fund - name: Fetch Dependabot Metadata diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index bb7672c..29f868d 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -23,7 +23,7 @@ jobs: shell: bash steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: fetch-depth: 0 - name: Setup Git User @@ -31,11 +31,11 @@ jobs: git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 id: node with: - node-version: 22.x - check-latest: contains('22.x', '.x') + node-version: 26.x + check-latest: contains('26.x', '.x') - name: Install Dependencies run: npm i --ignore-scripts --no-audit --no-fund - name: Run Commitlint on Commits diff --git a/.github/workflows/release-integration.yml b/.github/workflows/release-integration.yml index 6d7fc3e..6614399 100644 --- a/.github/workflows/release-integration.yml +++ b/.github/workflows/release-integration.yml @@ -34,7 +34,7 @@ jobs: id-token: write steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: ref: ${{ fromJSON(inputs.releases)[0].tagName }} - name: Setup Git User @@ -42,11 +42,11 @@ jobs: git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 id: node with: - node-version: 22.x - check-latest: contains('22.x', '.x') + node-version: 26.x + check-latest: contains('26.x', '.x') - name: Install Dependencies run: npm i --ignore-scripts --no-audit --no-fund - name: Set npm authToken diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 15a528d..243d347 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -30,17 +30,17 @@ jobs: shell: bash steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 id: node with: - node-version: 22.x - check-latest: contains('22.x', '.x') + node-version: 26.x + check-latest: contains('26.x', '.x') - name: Install Dependencies run: npm i --ignore-scripts --no-audit --no-fund - name: Release Please @@ -103,7 +103,7 @@ jobs: shell: bash steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ needs.release.outputs.pr-branch }} @@ -112,11 +112,11 @@ jobs: git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 id: node with: - node-version: 22.x - check-latest: contains('22.x', '.x') + node-version: 26.x + check-latest: contains('26.x', '.x') - name: Install Dependencies run: npm i --ignore-scripts --no-audit --no-fund - name: Create Release Manager Checklist Text From f47003b3e9cb490e860988305416963384417365 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Wed, 13 May 2026 10:46:22 -0700 Subject: [PATCH 3/7] feat!: bump to new node engine range BREAKING CHANGE: `read` now supports node `^22.22.2 || ^24.15.0 || >=26.0.0` --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 16bc7d9..9979f21 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "typescript": "^6.0.3" }, "engines": { - "node": "^20.17.0 || >=22.9.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" }, "author": "GitHub Inc.", "description": "read(1) for node programs", From e956ab7065400a6be161c896ecdc602e0ecd28a7 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Wed, 13 May 2026 10:46:25 -0700 Subject: [PATCH 4/7] chore: template-oss-apply --- .github/workflows/ci-release.yml | 16 ++++++++-------- .github/workflows/ci.yml | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci-release.yml b/.github/workflows/ci-release.yml index d92cca1..8b06b96 100644 --- a/.github/workflows/ci-release.yml +++ b/.github/workflows/ci-release.yml @@ -87,23 +87,23 @@ jobs: os: windows-latest shell: cmd node-version: - - 20.17.0 - - 20.x - - 22.9.0 + - 22.22.2 - 22.x + - 24.15.0 - 24.x + - 26.0.0 - 26.x exclude: - platform: { name: macOS, os: macos-15-intel, shell: bash } - node-version: 20.17.0 - - platform: { name: macOS, os: macos-15-intel, shell: bash } - node-version: 20.x - - platform: { name: macOS, os: macos-15-intel, shell: bash } - node-version: 22.9.0 + node-version: 22.22.2 - platform: { name: macOS, os: macos-15-intel, shell: bash } node-version: 22.x + - platform: { name: macOS, os: macos-15-intel, shell: bash } + node-version: 24.15.0 - platform: { name: macOS, os: macos-15-intel, shell: bash } node-version: 24.x + - platform: { name: macOS, os: macos-15-intel, shell: bash } + node-version: 26.0.0 - platform: { name: macOS, os: macos-15-intel, shell: bash } node-version: 26.x runs-on: ${{ matrix.platform.os }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2c406e6..3ab03af 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -63,23 +63,23 @@ jobs: os: windows-latest shell: cmd node-version: - - 20.17.0 - - 20.x - - 22.9.0 + - 22.22.2 - 22.x + - 24.15.0 - 24.x + - 26.0.0 - 26.x exclude: - platform: { name: macOS, os: macos-15-intel, shell: bash } - node-version: 20.17.0 - - platform: { name: macOS, os: macos-15-intel, shell: bash } - node-version: 20.x - - platform: { name: macOS, os: macos-15-intel, shell: bash } - node-version: 22.9.0 + node-version: 22.22.2 - platform: { name: macOS, os: macos-15-intel, shell: bash } node-version: 22.x + - platform: { name: macOS, os: macos-15-intel, shell: bash } + node-version: 24.15.0 - platform: { name: macOS, os: macos-15-intel, shell: bash } node-version: 24.x + - platform: { name: macOS, os: macos-15-intel, shell: bash } + node-version: 26.0.0 - platform: { name: macOS, os: macos-15-intel, shell: bash } node-version: 26.x runs-on: ${{ matrix.platform.os }} From 12c4958bc76fd8720ed508cadd6244ffc64fceea Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Wed, 13 May 2026 10:46:40 -0700 Subject: [PATCH 5/7] deps: mute-stream@4.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9979f21..0c2141c 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ } }, "dependencies": { - "mute-stream": "^3.0.0" + "mute-stream": "^4.0.0" }, "devDependencies": { "@npmcli/eslint-config": "^6.0.0", From 159e355e171e763902e9cf59bcec096eb0fc8fc0 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Fri, 15 May 2026 10:31:27 -0700 Subject: [PATCH 6/7] chore: remove multiple dev deps --- package.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/package.json b/package.json index 0c2141c..5e62948 100644 --- a/package.json +++ b/package.json @@ -28,12 +28,8 @@ "@npmcli/eslint-config": "^6.0.0", "@npmcli/template-oss": "5.1.0", "@types/mute-stream": "^0.0.4", - "@types/tap": "^15.0.11", "@typescript-eslint/parser": "^8.0.1", - "c8": "^11.0.0", "eslint-import-resolver-typescript": "^4.3.2", - "tap": "^16.3.9", - "ts-node": "^10.9.1", "tshy": "^4.1.1", "typescript": "^6.0.3" }, From d6ec880612bb77e3f961c7d05e1120644556ac0c Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Fri, 15 May 2026 10:32:16 -0700 Subject: [PATCH 7/7] fix: swap testing and resolve loading issues --- .github/matchers/tap.json | 32 --------------------------- .github/workflows/ci-release.yml | 8 ++++--- .github/workflows/ci.yml | 8 ++++--- package.json | 24 +++++--------------- scripts/template-oss/index.js | 7 ++++++ scripts/template-oss/package-json.hbs | 9 ++++++++ src/read.ts | 3 ++- test/basic.ts | 23 ++++++++++--------- test/fixtures/setup.ts | 3 ++- test/many.ts | 13 ++++++----- 10 files changed, 55 insertions(+), 75 deletions(-) delete mode 100644 .github/matchers/tap.json create mode 100644 scripts/template-oss/index.js create mode 100644 scripts/template-oss/package-json.hbs diff --git a/.github/matchers/tap.json b/.github/matchers/tap.json deleted file mode 100644 index 2c81ea9..0000000 --- a/.github/matchers/tap.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "//@npmcli/template-oss": "This file is automatically added by @npmcli/template-oss. Do not edit.", - "problemMatcher": [ - { - "owner": "tap", - "pattern": [ - { - "regexp": "^\\s*not ok \\d+ - (.*)", - "message": 1 - }, - { - "regexp": "^\\s*---" - }, - { - "regexp": "^\\s*at:" - }, - { - "regexp": "^\\s*line:\\s*(\\d+)", - "line": 1 - }, - { - "regexp": "^\\s*column:\\s*(\\d+)", - "column": 1 - }, - { - "regexp": "^\\s*file:\\s*(.*)", - "file": 1 - } - ] - } - ] -} diff --git a/.github/workflows/ci-release.yml b/.github/workflows/ci-release.yml index 8b06b96..cc46466 100644 --- a/.github/workflows/ci-release.yml +++ b/.github/workflows/ci-release.yml @@ -135,9 +135,11 @@ jobs: check-latest: contains(matrix.node-version, '.x') - name: Install Dependencies run: npm i --ignore-scripts --no-audit --no-fund - - name: Add Problem Matcher - run: echo "::add-matcher::.github/matchers/tap.json" - - name: Test + - name: Test (with coverage on Node >= 24) + if: ${{ startsWith(matrix.node-version, '24') }} + run: npm run test:cover --ignore-scripts + - name: Test (without coverage on Node < 24) + if: ${{ !startsWith(matrix.node-version, '24') }} run: npm test --ignore-scripts - name: Conclude Check uses: LouisBrunner/checks-action@v1.6.0 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3ab03af..c78cb8a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -101,7 +101,9 @@ jobs: check-latest: contains(matrix.node-version, '.x') - name: Install Dependencies run: npm i --ignore-scripts --no-audit --no-fund - - name: Add Problem Matcher - run: echo "::add-matcher::.github/matchers/tap.json" - - name: Test + - name: Test (with coverage on Node >= 24) + if: ${{ startsWith(matrix.node-version, '24') }} + run: npm run test:cover --ignore-scripts + - name: Test (without coverage on Node < 24) + if: ${{ !startsWith(matrix.node-version, '24') }} run: npm test --ignore-scripts diff --git a/package.json b/package.json index 5e62948..3ac42fd 100644 --- a/package.json +++ b/package.json @@ -45,14 +45,13 @@ "license": "ISC", "scripts": { "prepare": "tshy", - "pretest": "npm run prepare", - "presnap": "npm run prepare", - "test": "c8 tap", + "test": "node --experimental-strip-types --no-warnings --test './test/*.ts'", + "snap": "node --experimental-strip-types --no-warnings --test --test-update-snapshots './test/*.ts'", + "test:cover": "node --experimental-strip-types --no-warnings --test --experimental-test-coverage './test/*.ts'", "lint": "npm run eslint", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", "lintfix": "npm run eslint -- --fix", - "snap": "c8 tap", "posttest": "npm run lint", "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, @@ -61,23 +60,12 @@ "version": "5.1.0", "publish": true, "typescript": true, - "updateNpm": false + "updateNpm": false, + "testRunner": "node:test", + "content": "./scripts/template-oss" }, "main": "./dist/commonjs/read.js", "types": "./dist/commonjs/read.d.ts", - "tap": { - "coverage": false, - "node-arg": [ - "--no-warnings", - "--loader", - "ts-node/esm" - ], - "ts": false, - "nyc-arg": [ - "--exclude", - "tap-snapshots/**" - ] - }, "files": [ "dist/" ], diff --git a/scripts/template-oss/index.js b/scripts/template-oss/index.js new file mode 100644 index 0000000..784a416 --- /dev/null +++ b/scripts/template-oss/index.js @@ -0,0 +1,7 @@ +export default { + rootModule: { + add: { + 'package.json': { file: 'package-json.hbs', overwrite: false }, + }, + }, +} diff --git a/scripts/template-oss/package-json.hbs b/scripts/template-oss/package-json.hbs new file mode 100644 index 0000000..802a8cc --- /dev/null +++ b/scripts/template-oss/package-json.hbs @@ -0,0 +1,9 @@ +{ + "scripts": { + "test": "node --experimental-strip-types --no-warnings --test './test/*.ts'", + "snap": "node --experimental-strip-types --no-warnings --test --test-update-snapshots './test/*.ts'", + "test:cover": "node --experimental-strip-types --no-warnings --test --experimental-test-coverage './test/*.ts'", + "pretest": {{{ del }}}, + "presnap": {{{ del }}} + } +} diff --git a/src/read.ts b/src/read.ts index 2bd446e..e820854 100644 --- a/src/read.ts +++ b/src/read.ts @@ -1,5 +1,6 @@ import Mute from 'mute-stream' -import { Completer, AsyncCompleter, createInterface, ReadLineOptions } from 'readline' +import { createInterface } from 'readline' +import type { Completer, AsyncCompleter, ReadLineOptions } from 'readline' export interface Options { default?: T diff --git a/test/basic.ts b/test/basic.ts index 3d932e7..7997be4 100644 --- a/test/basic.ts +++ b/test/basic.ts @@ -1,6 +1,7 @@ -import t from 'tap' -import { read } from '../src/read.js' -import spawnRead from './fixtures/setup.js' +import { test } from 'node:test' +import { strict as assert } from 'node:assert' +import { read } from '../src/read.ts' +import spawnRead from './fixtures/setup.ts' async function child () { const user = await read({ prompt: 'Username: ', default: 'test-user' }) @@ -30,47 +31,47 @@ async function child () { } const main = () => { - t.test('basic', async t => { + test('basic', async () => { const { stdout, stderr } = await spawnRead(import.meta.url, { 'Username: (test-user)': 'a user', 'Password: (