From 815223976ac0586219f39e82baff73f17f59db99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Jerci=C5=84ski?= Date: Tue, 9 Jun 2026 08:47:55 +0200 Subject: [PATCH 1/5] chore: align repository config with j4k-align templates --- .githooks/pre-commit | 74 +++++++++++++++++++----------- .github/workflows/checks.yml | 14 ++---- .github/workflows/dedupe-check.yml | 8 ---- .github/workflows/release-npm.yml | 14 ++---- .vscode/settings.json | 3 +- package.json | 2 +- 6 files changed, 55 insertions(+), 60 deletions(-) diff --git a/.githooks/pre-commit b/.githooks/pre-commit index 3ba6bcc..a983e4c 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -2,9 +2,19 @@ # Native Git hook - enable with: git config core.hooksPath .githooks set -euo pipefail -git diff --cached --check +ignored_staged_paths=( + ":(exclude).agents/**" + ":(exclude).claude/**" +) + +git diff --cached --check -- . "${ignored_staged_paths[@]}" has_staged_changes() { + if [[ "$#" -eq 0 ]]; then + git diff --cached --quiet -- . "${ignored_staged_paths[@]}" || return 0 + return 1 + fi + git diff --cached --quiet -- "$@" || return 0 return 1 } @@ -13,6 +23,10 @@ if [[ ! -f package.json ]]; then exit 0 fi +if ! has_staged_changes; then + exit 0 +fi + # `npm pkg fix` normalizes package.json (e.g., sorts keys, trims invalid # fields). Only run it when package.json is already staged, so the hook never # pulls unrelated working-tree edits into a commit. @@ -21,25 +35,44 @@ if has_staged_changes package.json && command -v npm >/dev/null 2>&1; then git add package.json 2>/dev/null || true fi -run_script() { +package_script_exists() { local script_name="$1" # Check if the script exists in package.json (node - reads from stdin, arg becomes argv[2]) - if node - "$script_name" <<'EOF' + node - "$script_name" <<'EOF' const fs = require("fs"); const pkg = JSON.parse(fs.readFileSync("package.json", "utf8")); const scripts = pkg.scripts || {}; process.exit(scripts[process.argv[2]] ? 0 : 1); EOF - then - if command -v pnpm >/dev/null 2>&1; then - pnpm -s run "$script_name" - elif command -v npm >/dev/null 2>&1; then - npm run --silent "$script_name" - else - echo "No package manager available to run script: $script_name" >&2 - exit 1 - fi +} + +run_package_script() { + local script_name="$1" + if command -v pnpm >/dev/null 2>&1; then + pnpm run "$script_name" + elif command -v npm >/dev/null 2>&1; then + npm run "$script_name" + else + echo "No package manager available to run script: $script_name" >&2 + exit 1 + fi +} + +script_log=$(mktemp) +trap 'rm -f "$script_log"' EXIT + +# Silent on success; on failure, dump captured output and exit non-zero. +run_script() { + local script_name="$1" + if ! package_script_exists "$script_name"; then + return 0 + fi + echo "==> $script_name" >&2 + if run_package_script "$script_name" > "$script_log" 2>&1; then + return 0 fi + cat "$script_log" >&2 + exit 1 } if [[ -f pnpm-lock.yaml ]] && command -v pnpm >/dev/null 2>&1; then @@ -51,22 +84,9 @@ if [[ -f pnpm-lock.yaml ]] && command -v pnpm >/dev/null 2>&1; then fi fi -if has_staged_changes; then - run_script "format:check" -fi - +run_script "format:check" run_script "knip" run_script "typecheck" run_script "lint" run_script "fta" - -# Run tests quietly - only show output on failure -test_log=$(mktemp) -trap 'rm -f "$test_log"' EXIT - -if run_script "test" > "$test_log" 2>&1; then - : # Success, stay silent -else - cat "$test_log" >&2 - exit 1 -fi +run_script "test" diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 906701f..6c81670 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -9,12 +9,8 @@ on: jobs: quality-checks: - # Private dev dependencies require NPM_TOKEN, which fork PRs cannot access. - if: ${{ github.event_name != 'pull_request' || !github.event.pull_request.head.repo.fork }} runs-on: ubuntu-latest timeout-minutes: 10 - env: - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} steps: - name: Checkout code uses: actions/checkout@v6 @@ -28,10 +24,6 @@ jobs: node-version-file: "package.json" cache: "pnpm" - - name: Configure npm.j4k.dev auth - if: ${{ env.NPM_TOKEN != '' }} - run: printf "registry=https://npm.j4k.dev/\n//npm.j4k.dev/:_authToken=%s\n" "${NPM_TOKEN}" > .npmrc - - name: Install dependencies run: pnpm install --frozen-lockfile @@ -50,8 +42,8 @@ jobs: - name: Run fta run: pnpm fta - - name: Run tests - run: pnpm run test - - name: Run build run: pnpm build + + - name: Run tests + run: pnpm run test diff --git a/.github/workflows/dedupe-check.yml b/.github/workflows/dedupe-check.yml index 1fe1d8b..a1bf0b9 100644 --- a/.github/workflows/dedupe-check.yml +++ b/.github/workflows/dedupe-check.yml @@ -13,12 +13,8 @@ on: jobs: dedupe-check: - # Private dev dependencies require NPM_TOKEN, which fork PRs cannot access. - if: ${{ github.event_name != 'pull_request' || !github.event.pull_request.head.repo.fork }} runs-on: ubuntu-latest timeout-minutes: 5 - env: - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} steps: - name: Checkout code uses: actions/checkout@v6 @@ -32,10 +28,6 @@ jobs: node-version-file: "package.json" cache: "pnpm" - - name: Configure npm.j4k.dev auth - if: ${{ env.NPM_TOKEN != '' }} - run: printf "registry=https://npm.j4k.dev/\n//npm.j4k.dev/:_authToken=%s\n" "${NPM_TOKEN}" > .npmrc - - name: Install dependencies run: pnpm install --frozen-lockfile diff --git a/.github/workflows/release-npm.yml b/.github/workflows/release-npm.yml index c80422b..ae22fee 100644 --- a/.github/workflows/release-npm.yml +++ b/.github/workflows/release-npm.yml @@ -42,22 +42,14 @@ jobs: uses: actions/setup-node@v6 with: node-version-file: "package.json" - registry-url: https://registry.npmjs.org cache: "pnpm" - - name: Configure npm.j4k.dev auth - env: - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - run: | - if [ -z "${NPM_TOKEN}" ]; then - echo "NPM_TOKEN is required to install private dependencies." >&2 - exit 1 - fi - printf "registry=https://npm.j4k.dev/\n//npm.j4k.dev/:_authToken=%s\n" "${NPM_TOKEN}" > .npmrc - - name: Install dependencies run: pnpm install --frozen-lockfile + - name: Configure public npm registry (publish) + run: echo "registry=https://registry.npmjs.org/" >> ~/.npmrc + - name: Release id: release env: diff --git a/.vscode/settings.json b/.vscode/settings.json index aba257d..eb3b23d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,3 @@ { - "js/ts.experimental.useTsgo": true, - "typescript.native-preview.tsdk": "./node_modules/@typescript/native-preview" + "js/ts.experimental.useTsgo": true } diff --git a/package.json b/package.json index 5007092..8772388 100644 --- a/package.json +++ b/package.json @@ -81,5 +81,5 @@ "engines": { "node": ">=24.0.0" }, - "packageManager": "pnpm@10.33.0" + "packageManager": "pnpm@11.5.1" } From 61bc48049d9134bad0a119029f369602248c5d28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Jerci=C5=84ski?= Date: Tue, 9 Jun 2026 12:46:24 +0200 Subject: [PATCH 2/5] chore: sync AGENTS.md via sync-rules --- AGENTS.md | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index f5ea230..2defed1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -117,42 +117,6 @@ email.bulkSend(generateExpiryEmails(getExpiredUsers(db.getUsers(), new Date()))) Test the functional core, not the shell. Core tests are fast, deterministic, and need no mocks; the shell becomes thin orchestration where bugs are easy to spot through review. If shell tests are explicitly requested, prefer integration tests over unit tests with mocks. -# Rule: Inline Obvious Code - -Keep simple, self-explanatory code inline rather than extracting it into functions. Every abstraction carries cognitive cost—readers must jump to another location, parse a signature, and track context. For obvious logic, this overhead exceeds any benefit. - -Extracting code into a function is not inherently virtuous. A function should exist because it encapsulates meaningful complexity, not because code appears twice. - -```ts -// GOOD: Inline obvious logic -if (removedFrom.length === 0) { - return { ok: true, message: "No credentials found" }; -} -return { ok: true, message: `Removed from ${removedFrom.join(" and ")}` }; - -// BAD: Extraction hides obvious logic behind indirection -return formatRemovalResult(removedFrom); -``` - -## When to extract - -Extract when duplication causes real maintenance risk, not merely because code appears twice: - -- A name clarifies complex intent -- Multiple call sites must stay in lockstep and silent divergence would be a bug -- The function encapsulates a coherent standalone concept -- Testing it in isolation provides value - -Don't extract for hypothetical reuse: - -- For a single caller -- Because "we might need this elsewhere" -- When the name describes implementation rather than purpose - -## The wrong abstraction - -Abstractions decay when requirements diverge: programmer A extracts duplication into a shared function, programmer B adds a parameter for different behavior, and this repeats until the "abstraction" is a mess of conditionals. When an abstraction proves wrong, re-introduce duplication and let the code show you what's actually shared. Duplication is far cheaper than the wrong abstraction. - # Rule: No Logic in Tests Write test assertions as concrete input/output examples, not computed values. Avoid operators, string concatenation, loops, and conditionals in test bodies—these obscure bugs and make tests harder to verify at a glance. From 41d6779a19b4a1dd62fd47357b71c8ebee8fa1b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Jerci=C5=84ski?= Date: Tue, 9 Jun 2026 13:34:35 +0200 Subject: [PATCH 3/5] fix: pass confirm-modules-purge to pre-commit dedupe check --- .githooks/pre-commit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.githooks/pre-commit b/.githooks/pre-commit index a983e4c..02b0d48 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -79,7 +79,7 @@ if [[ -f pnpm-lock.yaml ]] && command -v pnpm >/dev/null 2>&1; then if has_staged_changes package.json pnpm-lock.yaml pnpm-workspace.yaml; then # Order matters: dedupe is the cheaper read-only check, so fail fast on # lockfile bloat before the heavier lockfile-vs-package.json sync check. - pnpm dedupe --check + pnpm dedupe --check --config.confirm-modules-purge=false pnpm install --frozen-lockfile --ignore-scripts --config.confirm-modules-purge=false fi fi From d748a0ca28463049248fb9310c0e2dd3a8a8a261 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Jerci=C5=84ski?= Date: Tue, 9 Jun 2026 14:36:04 +0200 Subject: [PATCH 4/5] fix: install through npm.j4k.dev for private-registry dependency --- .github/workflows/checks.yml | 5 +++++ .github/workflows/dedupe-check.yml | 5 +++++ .github/workflows/release-npm.yml | 5 +++++ pnpm-workspace.yaml | 2 ++ 4 files changed, 17 insertions(+) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 6c81670..f900953 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -24,6 +24,11 @@ jobs: node-version-file: "package.json" cache: "pnpm" + - name: Configure registry auth + run: echo "//npm.j4k.dev/:_authToken=${NODE_AUTH_TOKEN}" > ~/.npmrc + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Install dependencies run: pnpm install --frozen-lockfile diff --git a/.github/workflows/dedupe-check.yml b/.github/workflows/dedupe-check.yml index a1bf0b9..08d0eba 100644 --- a/.github/workflows/dedupe-check.yml +++ b/.github/workflows/dedupe-check.yml @@ -28,6 +28,11 @@ jobs: node-version-file: "package.json" cache: "pnpm" + - name: Configure registry auth + run: echo "//npm.j4k.dev/:_authToken=${NODE_AUTH_TOKEN}" > ~/.npmrc + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Install dependencies run: pnpm install --frozen-lockfile diff --git a/.github/workflows/release-npm.yml b/.github/workflows/release-npm.yml index ae22fee..c7cd2dd 100644 --- a/.github/workflows/release-npm.yml +++ b/.github/workflows/release-npm.yml @@ -44,6 +44,11 @@ jobs: node-version-file: "package.json" cache: "pnpm" + - name: Configure registry auth (install) + run: echo "//npm.j4k.dev/:_authToken=${NODE_AUTH_TOKEN}" > ~/.npmrc + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Install dependencies run: pnpm install --frozen-lockfile diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index a95e5cf..c813e2e 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,5 @@ allowBuilds: esbuild: true enableGlobalVirtualStore: true +registries: + default: https://npm.j4k.dev/ From 65272f823868a23b36795f5f2b5946cc42965ca8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Jerci=C5=84ski?= Date: Tue, 9 Jun 2026 22:26:54 +0200 Subject: [PATCH 5/5] fix: surface missing-package-manager error in pre-commit hook run_package_script exited inside run_script's redirected invocation, so the error landed in a log that is only dumped on function return. Returning 127 lets run_script dump the log. Synced from j4k-align #27. --- .githooks/pre-commit | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.githooks/pre-commit b/.githooks/pre-commit index 02b0d48..dba8705 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -53,8 +53,11 @@ run_package_script() { elif command -v npm >/dev/null 2>&1; then npm run "$script_name" else + # return, not exit: callers redirect this function's output into a log + # they only dump on failure — exit here would abort before the dump, + # leaving the commit to die with no visible error. echo "No package manager available to run script: $script_name" >&2 - exit 1 + return 127 fi }