Skip to content

Worktree jwt ux - #1912

Closed
destan wants to merge 21 commits into
CorentinTh:mainfrom
destan:worktree-jwt-ux
Closed

destan wants to merge 21 commits into
CorentinTh:mainfrom
destan:worktree-jwt-ux

Conversation

@destan

@destan destan commented Nov 6, 2026

Copy link
Copy Markdown

No description provided.

destan and others added 21 commits November 4, 2026 18:19
* build: use Node 22 and add Wrangler config for SPA routing

Wrangler 4.157.0 requires Node 22, and the Cloudflare build read
Node 18.18.2 from .nvmrc, so the deploy step failed.

- Pin Node 22 in .nvmrc and in the GitHub workflows.
- Add wrangler.jsonc to serve dist as static assets, with
  single-page-application fallback so deep links load index.html.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PEUYi3wRPPWqzZDKJpt17C

* build: add previews block to Wrangler config

Workers Builds runs `npx wrangler preview` for non-production branches.
Wrangler 4.157.0 refuses to run that command without a `previews` block
in the configuration, so the preview deploy for this branch failed:

  Your Wrangler configuration is missing a `previews` block to run
  this command.

An empty block is enough. Assets and compatibility settings stay at the
top level.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PEUYi3wRPPWqzZDKJpt17C

---------

Co-authored-by: Claude <noreply@anthropic.com>
* test(e2e): update Playwright to 1.64.1 for Ubuntu 24.04 runners

ubuntu-latest runs Ubuntu 24.04. Playwright 1.32.3 installs browser
dependencies by Ubuntu 20.04 and 22.04 package names, so
`playwright install --with-deps` failed before any test ran:

  E: Package 'libasound2' has no installation candidate

Playwright supports Ubuntu 24.04 from 1.45.0.

- Update @playwright/test from 1.32.3 to 1.64.1.
- Read the Playwright version for the browser cache key from
  devDependencies["@playwright/test"]. The step read
  dependencies.playwright, which is null, so every key was the same.
- Pin @vueuse/shared to 12.0.0 for @unhead/vue with a pnpm override.
  @unhead/vue 0.5.1 depends on "@vueuse/shared": "latest", so any
  lockfile change re-resolved it to 15.0.0, which requires Vue 3.5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PEUYi3wRPPWqzZDKJpt17C

* ci(e2e): raise the job timeout to 20 minutes

The E2E job installs Playwright browsers and their system packages on
every run, because the cache covers only ~/.cache/ms-playwright. On a
slow apt mirror, test (3/3) spent all 10 minutes in
`playwright install --with-deps` and was cancelled before any test
ran. The same shard finished in about 3 minutes on the previous run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PEUYi3wRPPWqzZDKJpt17C

---------

Co-authored-by: Claude <noreply@anthropic.com>
…#2)

pnpm audit reported critical and high advisories in direct
dependencies. Update each one to the latest release of its current
major version:

- crypto-js 4.2.0, dompurify 3.4.17, node-forge 1.4.3, lodash 4.18.1
- markdown-it 14.3.3, figlet 1.12.0, yaml 2.9.1, vue-i18n 9.14.5
- colord 2.10.0, vite 4.5.14

figlet 1.12 ships its own types, so ascii-text-drawer imports
FigletOptions and FontName instead of the @types/figlet namespace.

@unhead/vue 0.5.1 depends on "@vueuse/shared": "latest". Any lockfile
change re-resolved it to 15.0.0, which requires Vue 3.5. A pnpm
override keeps it at 12.0.0, the version the lockfile already had.


Claude-Session: https://claude.ai/code/session_01PEUYi3wRPPWqzZDKJpt17C

Co-authored-by: Claude <noreply@anthropic.com>
#5)

The demo routes called import(/* @vite-ignore */ path) with the raw
.vue source path. Vite did not bundle these calls, so production builds
requested files such as c-alert/c-alert.demo.vue, which do not exist.
The SPA fallback returned index.html and the module load failed.

The eager glob already loads every demo module, so the routes use those
modules directly.


Claude-Session: https://claude.ai/code/session_01PEUYi2r9cE1KsyVxsuTJ2E

Co-authored-by: Claude <noreply@anthropic.com>
Phase 0 of the dependency upgrade plan in #4.

- Pin Node 26 in .nvmrc, the four workflows, and the Dockerfile.
  Node 22 entered maintenance on 2025-10-21. Node 26 is the active LTS.
- Change packageManager from pnpm@9.11.0 to pnpm@9.15.9.
- Replace `corepack enable` with pnpm/action-setup@v6.1.1, which reads
  the pnpm version from packageManager. The Node 26 distribution does
  not include corepack. The step runs before actions/setup-node, because
  `cache: 'pnpm'` needs pnpm on the path.
- Pin pnpm 9.15.9 in the Dockerfile. The unpinned
  `npm install -g pnpm` installed the npm `latest` dist-tag (12.16.1).
- Update the GitHub Actions to their latest tags:
  - actions/checkout: the v4-commented SHA to the v7.0.1 commit SHA
  - actions/setup-node: v3 to v7.1.0
  - actions/cache: v3 to v6.1.0
  - docker/login-action: v3 to v4.7.0
  - docker/setup-qemu-action: v3 to v4.4.0
  - docker/setup-buildx-action: v3 to v4.4.1
  - docker/build-push-action: v5 to v7.4.0
  - softprops/action-gh-release: v1 to v3.0.3

The workflows set every action input that they used before. Each input
still exists in the action.yml of the target tag.


Claude-Session: https://claude.ai/code/session_01PEUYi2Ve581PMqxiDbPpuS

Co-authored-by: Claude <noreply@anthropic.com>
- Point GitHub links to destan/toolbox and remove the X and "Buy me a coffee" links.
- Rename IT-Tools to Toolbox and credit IT-Tools and Corentin Thomasset as the origin of this fork.
- Point index.html to toolbox.destan.dev and replace the social preview banner.
- Remove FUNDING.yml, the Docker release workflows, netlify.toml, vercel.json, and the IT-Tools logos.
- Read VITE_APP_ENV and VITE_COMMIT_SHA instead of the Vercel variables, so Cloudflare builds no longer run as development.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PEUYi5ApKVayYRcdi8BqTs
The "Install Playwright Browsers" step took 33 to 58 seconds per shard,
even with a browser cache hit. Almost all of that time went to apt-get
installing the OS dependencies, which the cache cannot hold.

- Run the e2e job in mcr.microsoft.com/playwright:v1.64.1-noble, which
  ships the browsers and their OS dependencies. Remove the version step,
  the cache step, and the install step.
- Pin @playwright/test to 1.64.1, so no install resolves a newer version
  than the image.
- Add a Renovate package rule that puts @playwright/test and the image
  in one update PR.

On one run per side, the Playwright setup dropped from 60-80 s to
23-40 s per shard, and the run's wall-clock time from 252 s to 217 s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PEUYi2N5ePDQccPGBmDMcy
### Description

Replace every reference to `toolbox.destan.dev` with
`toolbox.destan.workers.dev`.

- `index.html`: the canonical link, `og:url`, `og:image`, and
`twitter:image`. The canonical link gains a trailing slash to match
`og:url`.
- `README.md`: the "Try it!" link.
- `.github/ISSUE_TEMPLATE/bug-report.yml`: the "Public app" option.
- `src/tools/qr-code-generator/qr-code-generator.vue`: the default QR
code text.
- `src/tools/url-parser/url-parser.vue`: the sample URL uses
`example.com`, so it does not depend on the site domain.

### Additional context

- `git grep destan.dev` returns no matches after this change.
- The live site returns `200 image/png` for `/banner.png?v=2` on the new
domain.
- Neither changed tool has tests, and no test references the old values.
Lint and build were not run, since every change edits a string literal.

---

### What is the purpose of this pull request?

- [ ] Bug fix
- [ ] New Feature
- [ ] Documentation update
- [x] Other

### Before submitting the PR, please make sure you do the following

- [ ] Submit the PR against the `dev` branch. (The repository has no
`dev` branch, so this PR targets `main`.)
- [x] Check that there isn't already a PR that solves the problem the
same way to avoid creating a duplicate.
- [x] Provide a description in this PR that addresses **what** the PR is
solving, or reference the issue that it solves (e.g. `fixes #123`).
- [ ] Ideally, include relevant tests that fail without this PR but pass
with it.

---
_Generated by [Claude
Code](https://claude.ai/code/session_01PEUYi2oMSEz9uSiT8DXC1a)_

Co-authored-by: Claude <noreply@anthropic.com>
Paste an image from the clipboard with Ctrl+V or Cmd+V, or with a
"Paste from clipboard" button for touch devices, then download it.

- Converts to PNG (default), JPEG, or WebP, with a quality slider for
  JPEG and WebP. The format and quality persist across visits.
- Keeps every image pasted in the session, with remove and clear all.
- Shows dimensions, original and output type and size.
- Edits the file name, copies the image as PNG, or copies a base64
  data URL.
- Converts images one at a time in the browser only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PEUYi3h8enZM5rmJAZ1UAF
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PEUYi2ZahVbFDot56M3F8d
Add a tool that cleans terminal and Claude Code output. The cleaner strips line numbers, ANSI escape sequences, box drawing, bullet markers, diff markers, trailing whitespace, and the common indent. Smart unwrap and Markdown / Reddit mode are optional. Options persist in localStorage. The pasted input is not saved.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PEUYi2gRxcytxRFXjPjH3U
### Description

This PR adds `docs/dependency-upgrade-plan.md`. The plan covers the
dependency upgrades that need a major version change. It also covers the
runtime, the package manager, the CI actions, and the remaining updates
within a major version.
[#2](#2) updated
only the vulnerable dependencies within their major versions.

On 2026-11-04, every target version matched the `latest` dist-tag in the
npm registry. Every "From" version matched `pnpm-lock.yaml` on `main`.

The plan splits the work into eight phases. Each phase is one PR. The
order follows the peer ranges and Node requirements that the plan lists:

| Phase | Scope |
|---|---|
| 0 | Node 22 to 26, pnpm 9.11.0 to 9.15.9, `pnpm/action-setup` in place
of `corepack enable`, a pinned pnpm in the `Dockerfile`, and the GitHub
Actions updates |
| 1 | Vue 3.3.4 to 3.5.44 within major version 3, `naive-ui`,
`@vue/test-utils`, the remaining updates within major versions, the 0.x
minor updates, deprecated type packages, and the `@vueuse/shared`
override |
| 2 | Vite 4 to 8, Vitest 0.34 to 5, `jsdom` 30, `workbox-window`,
`@types/jsdom`, `@types/node` 26, and all Vite plugins in one PR. This
phase removes all 6 critical advisories. |
| 3 | ESLint 8 to 10, with the move to the flat config format |
| 4 | `vue-tsc` 3, TypeScript 7 (or 6), and `@tsconfig/node26` |
| 5 | Pinia 4, `vue-router` 5, `vue-i18n` 11, VueUse 15, and
`@unhead/vue` 3.4.3 in place of `@vueuse/head` |
| 6 | Tiptap 3, `uuid`, `zx`, and `mathjs` |
| 7 | 17 major versions with no advisory, with their `@types` changes |

The starting point is the `pnpm audit` run on `main` at `5b069d5`: 6
critical, 90 high, 63 moderate, and 17 low advisories.

### Additional context

The plan labels each claim it could not verify as `Unverified`. It ends
with four open questions for the maintainer:

- Should the project remove `hygen` and its `script:create:ui` script,
or replace it?
- Should the project keep `composerize-ts`, given that no release fixes
its advisories?
- Which TypeScript major version should phase 4 target?
- Which pnpm major version should the project move to after phase 7?

This PR changes only documentation.

---

### What is the purpose of this pull request?

- [ ] Bug fix
- [ ] New Feature
- [x] Documentation update
- [ ] Other

---
_Generated by [Claude
Code](https://claude.ai/code/session_01PEUYi2tbhZhVoAquCHjbvf)_

---------

Co-authored-by: Claude <noreply@anthropic.com>
### Description

This PR implements phase 1 of the dependency upgrade plan in
[#4](#4): updates
within major versions, including Vue core.

Changes from the plan:

- Update `vue` from 3.3.4 to 3.5.44. Align `@vue/compiler-sfc` (3.2.47)
and `@vue/runtime-dom` (3.3.4) with it.
- Update `naive-ui` from 2.35.0 to 2.45.3 and `@vue/test-utils` from
2.3.2 to 2.5.1.
- Update the 21 packages in the plan's phase 1 table to their latest
version within the major version.
- Update the 0.x packages `@vicons/material` and `@vicons/tabler` to
0.13.0, `country-code-lookup` to 0.2.2, `randexp` to 0.6.1, and
`unicode-emoji-json` to 0.9.0.
- Remove `@types/dompurify` and `@types/figlet`. npm marks both
deprecated because `dompurify` and `figlet` ship their own types.

Changes beyond the plan.
[#4](#4) records
them in commit `01a509d`.

- **Keep the `@unhead/vue>@vueuse/shared` override.** `@vueuse/head`
1.0.0 depends on `@unhead/vue` 0.5.1, which imports `resolveUnref` from
`@vueuse/shared`. Without the override, pnpm resolved `@vueuse/shared`
15.0.0, and the build failed: `"resolveUnref" is not exported by
@vueuse/shared`. Phase 5 replaces `@vueuse/head` and removes the
override.
- **Update `typescript` from 5.2.2 to 5.4.5, and `vue-tsc` from 1.8.1 to
1.8.27.** The Vue 3.5 type definitions use `NoInfer`, which TypeScript
5.2 does not provide, so `vue-tsc` failed. `vue-tsc` 1.8.27 crashed on
TypeScript 5.5.4, 5.6.3, 5.7.3, 5.8.3, and 5.9.3. TypeScript 5.4.5 is
the newest release that works with it. Phase 4 moves to `vue-tsc` 3 and
TypeScript 6 or 7.
- **Guard the command palette Enter handler.** Pressing Enter with no
matching option passed `undefined` to `activateOption`, which threw a
`TypeError` on `const { closeOnSelect } = option`. The Vue 3.5 types
exposed this bug.
- **Read the string obfuscator inputs with `toValue` from `vue`.** The
`get` function of `@vueuse/core` 10 does not accept the Vue 3.5
`MaybeRef` type. `toValue` reads refs and plain values the same way.

### Verification

I ran these steps on Node 26.13.0 with pnpm 9.15.9, on top of `main` at
`ee2e5ba`:

| Step | Result |
|---|---|
| `pnpm install` | Passed. No peer dependency warnings. `main` reports
3, all caused by Vue 3.3.4. |
| `pnpm lint` | Passed with the same 3 UnoCSS ordering warnings as
`main`. |
| `pnpm test` | 138 of 138 tests passed. |
| `pnpm typecheck` | Passed. |
| `pnpm build` | Passed. |
| `pnpm audit` | 6 critical, 81 high, 59 moderate, 17 low. `main`
reports 6, 90, 63, 17. |

Unverified:

- The E2E tests on Chromium, Firefox, and WebKit. The E2E workflow on
this PR confirms them.
- The tools whose library changed, in the Cloudflare preview deployment.
The main ones are the phone parser (`country-code-lookup`,
`libphonenumber-js`), the regex tester (`randexp`), the emoji picker
(`unicode-emoji-json`), the string obfuscator, the IBAN validator
(`ibantools`), the QR code generators (`qrcode`), the XML formatter
(`xml-formatter`), and the command palette.

### Additional context

`pnpm build` regenerated `components.d.ts` with icons that the committed
file was missing. This drift exists on `main`, so this PR does not
include it. Phase 2 regenerates the file.

---

### What is the purpose of this pull request?

- [ ] Bug fix
- [ ] New Feature
- [ ] Documentation update
- [x] Other

---
_Generated by [Claude
Code](https://claude.ai/code/session_01PEUYi2Ve581PMqxiDbPpuS)_

Co-authored-by: Claude <noreply@anthropic.com>
serializeValue escaped double quotes with a backslash, quoted a field
only when it contained a comma, and turned line breaks into the literal
text \n and \r. Spreadsheet apps misread such output.

- Enclose a field in double quotes when it contains a comma, a double
  quote, or a line break, and double any inner double quote.
- Keep line breaks as real line breaks inside quoted fields.
- Escape header names with the same rule as values.
- Separate rows with CRLF.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PEUYi4JiJNM3VV8iTWmYxn
### Description

This PR implements phases 2 to 7 of `docs/dependency-upgrade-plan.md` in
one PR, so CI and the Cloudflare preview build run once. Each phase is a
separate commit.

| Commit | Phase | Scope |
|---|---|---|
| `433e5a2` | 2 | Vite 8, Vitest 5, jsdom 30, `vite-plugin-pwa` 2, all
Vite plugins, `@types/node` 26 |
| `9918138` | 4 | `vue-tsc` 3, TypeScript 6.0.3, `@vue/tsconfig` 0.9,
`@tsconfig/node26`, and the template type errors this exposed |
| `fc248f3` | 3 | ESLint 10, `@antfu/eslint-config` 10, flat config |
| `52cd05e` | 3 | ESLint autofix and the manual lint fixes |
| `af46c60` | 5 | Pinia 4, `vue-router` 5, `vue-i18n` 11, VueUse 15,
`@unhead/vue` 3 in place of `@vueuse/head` |
| `744ceda` | 6 | Tiptap 3, `uuid` 14, `zx` 8, `mathjs` 15 |
| `f5af38f` | 7 | 16 remaining major versions |
| `94c2bbe` | — | pnpm override for the `dompurify` copy of
`monaco-editor` |
| `676e8b4` | — | `docs/typescript-7-readiness.md` |

The phase 2 commit does not pass type checking on its own. The phase 4
commit fixes that. Each commit message lists its changes and reasons.

### Deviations from the plan

- **Phase 4 runs before phase 3.** `@types/node` 22, 24, and 26 require
TypeScript 5.6 or later. Phase 1 pinned TypeScript 5.4.5, the newest
release that `vue-tsc` 1 runs on.
- **TypeScript 6.0.3 instead of 7.0.2.** TypeScript 7 has no JavaScript
API, so `vue-tsc` fails. `@volar/typescript` and `typescript-eslint`
exclude it in their peer ranges. `docs/typescript-7-readiness.md`
records the evidence and the upgrade check.
- **`figue` stays at 1.2.0.** `figue` 3 replaces its `format` strings
with Standard Schema validators. The upgrade would add a validation
library and rewrite `src/config.ts`, and no advisory requires it.
- **Added `workbox-build` 7.4.1.** It is a required peer of
`vite-plugin-pwa` 2.
- **Added a pnpm override `monaco-editor>dompurify: ^3.4.17`.**
`monaco-editor` 0.57.0, the latest stable release, pins `dompurify`
3.4.15, which has a critical advisory. Remove the override once a
`monaco-editor` release depends on a fixed version.
- **Kept two code conventions of the old ESLint config:** no delimiters
after multiline type members, and no forced line breaks between list
items. The new defaults would have rewritten 723 lines.

### Bugs that the stricter types exposed

- **Meta tag generator:** the "Page type" select used naive-ui option
groups, which `c-select` does not support. The 8 Music and Video page
types could not be selected. The options are flat now, for example
"Music: Song".
- **Type checking during the build:** `vue-tsc --noEmit` ran against the
root `tsconfig.json`, which lists no files. It never type-checked the
app. The build runs `vue-tsc --build` now.
- **Template type checking:** the generated `components.d.ts` augmented
`@vue/runtime-core`, which pnpm cannot resolve from the project.
Templates were not type-checked against the props of the app components.
The regenerated file augments `vue`. The commit for phase 4 fixes the 33
errors this exposed, for example the `error` type of `c-alert`.
- **Token generator test:** the symbol pattern contained the range
`[-|`, which also accepted lowercase letters.

### Behavior changes

- **Case converter:** `change-case` 5 recognizes accented lowercase
letters at case changes. `éCRIVAIN` splits into `é` and `CRIVAIN`, like
`eCRIVAIN` already did. On 77 sample conversions, all other outputs
matched `change-case` 4.
- **SQL prettify:** `sql-formatter` 15 removed the `tabulateAlias`
option, so aliases are no longer aligned in a column.

### Verification

I ran these steps on Node 26.13.0 with pnpm 9.15.9, on top of `main` at
`b33c0b5`:

| Step | Result |
|---|---|
| `pnpm install` | Passed. No peer dependency warnings. |
| `pnpm lint` | Passed with no problems. |
| `pnpm test` | 208 of 208 tests passed. |
| `pnpm typecheck` | Passed. |
| `pnpm build` | Passed, including `vue-tsc --build`. |
| `playwright test`, Chromium only | 82 of 82 tests passed. |
| `pnpm audit` | 0 critical, 14 high, 14 moderate, 2 low. `main` reports
6 critical, 81 high, 59 moderate, 17 low. |

Unverified:

- The E2E tests in Firefox and WebKit. The E2E workflow on this PR runs
them.
- The tools whose library changed, in the Cloudflare preview deployment.
The main ones are the case converter, SQL prettify, Markdown rendering,
JWT parser, UUID generator, HTML WYSIWYG editor, diff editor (Monaco),
and the meta tag generator.

### Additional context

Open questions for the maintainer:

- `hygen` and `composerize-ts` pull in most of the remaining high
advisories, and no release fixes them. Should the project remove or
replace them?
- Should `figue` move to version 3 with a validation library?
- `docs/dependency-upgrade-plan.md` still describes the original order
and targets. Should a follow-up PR update it to match this PR?

---

### What is the purpose of this pull request?

- [ ] Bug fix
- [ ] New Feature
- [ ] Documentation update
- [x] Other

---
_Generated by [Claude
Code](https://claude.ai/code/session_01PEUYi2Ve581PMqxiDbPpuS)_

---------

Co-authored-by: Claude <noreply@anthropic.com>
… record the upgrade outcome (#16)

### Description

This PR resolves the three open questions from
[#15](#15).

- **Remove `hygen`.** It removes the package, the `script:create:ui`
script, and the `_templates` folder. `hygen` 6.2.11 is the latest
release and pulled in high advisories through `ejs`, `minimatch`, and
`cross-spawn`. The `script:create:tool` script stays.
- **Replace `composerize-ts` 0.6.2 with `composerize` 1.7.6** in the
Docker run to Docker Compose converter. In an isolated install, `npm
audit` reported 1 moderate and 3 high advisories for `composerize-ts`
and none for `composerize`.
- **Upgrade `figue` 1.2 to 3.3 with `valibot` 1.5 schemas.** The config
keeps the same keys, defaults, and environment variables. The temporary
`paths` mapping for `figue` 1 is removed.
- **Update `docs/dependency-upgrade-plan.md`.** An outcome section lists
the pull requests, the deviations from the plan, and the final audit
counts. The phase 4, 6, and 7 sections match what was done. Only the
pnpm question stays open.

### Behavior changes

- **Docker run converter:** `composerize` lists the options it cannot
translate as comments at the top of the YAML, for example `#
--unknown-flag=foo`. The three message panels of `composerize-ts` give
way to a single error alert for a command that fails to convert. The
output also starts with `name: <your project name>`.
- **Configuration:** none. These checks gave the same results as `figue`
1:
  - With no environment variables, the defaults apply.
  - `" TRUE "` enables a flag.
  - `"yes"` does not enable a flag.
  - `VITE_APP_ENV=staging` throws a validation error.

### Verification

I ran these steps on Node 26.13.0 with pnpm 9.15.9, on top of `main` at
`f9e1fea`:

| Step | Result |
|---|---|
| `pnpm install` | Passed. No peer dependency warnings. |
| `pnpm lint` | Passed with no problems. |
| `pnpm test` | 208 of 208 tests passed. |
| `pnpm typecheck` | Passed. |
| `pnpm build` | Passed. The converter chunk is 281 kB, or 87 kB
gzipped. |
| Converter in Chromium (`vite preview`) | The default command and an
unknown flag converted, with no page errors. |
| `pnpm audit` | 0 critical, 10 high, 8 moderate, 2 low. `main` reports
0 critical, 14 high, 14 moderate, 2 low. |

Unverified:

- The E2E tests in Firefox and WebKit. The E2E workflow on this PR runs
them.

### Additional context

The remaining high advisories come from build and lint tooling, such as
`unplugin-vue-markdown`, `vite-plugin-pwa`, and `@antfu/eslint-config`.
They also come from `@it-tools/bip39`. No release of these packages
fixes them yet.

---

### What is the purpose of this pull request?

- [ ] Bug fix
- [ ] New Feature
- [ ] Documentation update
- [x] Other

---
_Generated by [Claude
Code](https://claude.ai/code/session_01PEUYi2Ve581PMqxiDbPpuS)_

---------

Co-authored-by: Claude <noreply@anthropic.com>
### Description

The UUID generator generates v6 and v7 UUIDs.

- **v6 and v7:** The version picker has `v6` and `v7` buttons. The
`uuid` package (14.0.3, already a dependency) generates both without
options, which keeps the UUIDs of one batch in ascending order.
- **Namespace check:** The v3/v5 namespace field accepts any RFC 9562
UUID. The previous regex accepted only versions 1 to 5 and the NIL UUID,
so a v6, v7, or MAX UUID showed "Invalid UUID". The check uses
`validate()` from `uuid`.
- **Refactor:** The generation logic moved from `uuid-generator.vue`
into `uuid-generator.service.ts`, so unit tests can call it directly.
v1, v3, v4, v5, and NIL output is unchanged. v4 stays the default.
- **Search:** The tool keywords include `v6`, `v7`, `time-ordered`, and
`sortable`.

### Additional context

**Tests**

- `uuid-generator.service.test.ts` (21 unit tests) checks:
- the UUID count, validity, uniqueness, and version digit for each
version;
  - the RFC 9562 v3 and v5 test vectors;
  - the ascending order of v6 and v7 batches;
  - the v7 timestamp prefix against `Date.now()`;
  - the namespace check for valid and invalid input.
- With the old namespace regex restored, the MAX, v6, and v7 namespace
tests failed.
- `uuid-generator.e2e.spec.ts` checks v6/v7 ordering in the page and a
v7 namespace for v5. It uses test IDs added to the namespace, name, and
output fields.

**Verification**

- `vitest`: 229 of 229 tests passed. `eslint` and `vue-tsc` reported no
errors.
- The e2e spec passed in Chromium only. Firefox and WebKit run in CI.

**Reviewer note:** `c-button` renders `test-id` as a plain `test-id`
attribute, not `data-test-id`. For that reason, the e2e spec selects the
version buttons by role.

---

### What is the purpose of this pull request?

- [ ] Bug fix
- [x] New Feature
- [ ] Documentation update
- [ ] Other

### Before submitting the PR, please make sure you do the following

- [ ] Submit the PR against the `dev` branch. (This repository has no
`dev` branch. Earlier PRs target `main`.)
- [x] Check that there isn't already a PR that solves the problem the
same way to avoid creating a duplicate.
- [x] Provide a description in this PR that addresses **what** the PR is
solving, or reference the issue that it solves (e.g. `fixes #123`).
- [x] Ideally, include relevant tests that fail without this PR but pass
with it.

---
_Generated by [Claude
Code](https://claude.ai/code/session_01PEUYi4Euqw35pAKJKohbhB)_

Co-authored-by: Claude <noreply@anthropic.com>
### Description

This PR adds [OWASP
Dependency-Check](https://devguide.owasp.org/en/05-implementation/02-dependencies/01-dependency-check/)
to CI. It also fixes the findings that would otherwise fail the check.

**`.github/workflows/dependency-check.yml`**

- Runs on pull requests, on pushes to `main`, every Monday at 04:17 UTC,
and on manual dispatch.
- Uses `dependency-check/Dependency-Check_Action`. The action image
ships the vulnerability database and runs with `--noupdate`, so the
workflow needs no NVD API key.
- Scans `pnpm-lock.yaml` without `pnpm install`. The scan includes
devDependencies.
- Fails on findings with a CVSS score of 7 or higher (`--failOnCVSS 7`).
- Uploads all report formats as the `dependency-check-reports` artifact.
- Uploads the SARIF report to code scanning. Pull requests from forks
skip this step because their token is read-only.
- Pins every action to a commit SHA, like the other workflows.

**`pnpm-lock.yaml`**

After the merge of #15 and #16, the scan reported 3 findings at CVSS 7
or higher. All 3 are indirect dependencies whose parent ranges already
accept the fixed release:

| Package | From | To | Advisory | Via |
|---|---|---|---|---|
| `lodash-es` | 4.17.21 | 4.18.1 | GHSA-r5fr-rjxr-66jc | `naive-ui` |
| `defu` | 6.1.4 | 6.1.7 | GHSA-737v-mqg7-c878 | `unconfig` |
| `browserslist` | 4.24.3 | 4.29.5 | GHSA-c83g-rgw3-j3cx |
`@babel/helper-compilation-targets` |

`package.json` does not change.

### Additional context

Verification on Node 26.13.0, following the procedure in
`docs/dependency-upgrade-plan.md`:

1. `pnpm install --frozen-lockfile`: passed. The peer dependency
warnings match the warnings before the change.
2. `pnpm lint`: passed.
3. `pnpm test`: 36 files and 208 tests passed.
4. `pnpm typecheck`: passed.
5. `pnpm build`: passed.
6. A local Dependency-Check run with the action image: exit code 0, 7
findings, none at CVSS 7 or higher.
7. `pnpm audit`:

| Severity | Before | After |
|---|---|---|
| Critical | 0 | 0 |
| High | 10 | 6 |
| Moderate | 8 | 7 |
| Low | 2 | 2 |

The 6 remaining high advisories come from `js-yaml` (via
`unplugin-vue-markdown`) and `nanoid` 3.3.6 (via `@it-tools/bip39`).
Dependency-Check scores them below 7, so they do not fail the check.

The first CI run on this PR confirmed two points:

- The scan ran and passed. The action's entrypoint appends a stray
`ci.yml` argument, and the CLI ignores it.
- The SARIF upload to code scanning succeeded.

---

### What is the purpose of this pull request?

- [ ] Bug fix
- [ ] New Feature
- [ ] Documentation update
- [x] Other

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01PEUYi2tUG18ZAD3PgqPU64

---------

Co-authored-by: Claude <noreply@anthropic.com>
…#19)

### Description

This PR replaces the hero gradient SVG with an orange version. It also
switches the brand palette from green to orange, with `#E95420` as the
base color.

| Role | Color | Source |
|---|---|---|
| color | `#E95420` | base color |
| hover | `#EC6E41` | base mixed with 15% white |
| pressed | `#C34113` | middle stop of the hero gradient |
| faded | `#E954202f` | base at the previous transparency |
| focus background | `#E954201a` | base at the previous transparency |

Changed places:
- The theme files `src/ui/theme/themes.ts` and `src/themes.ts`.
- The Naive UI primary colors in light mode. Light mode used the
library's default green before.
- The colored card gradient, which uses the hero gradient stops.
- The focus backgrounds of `c-input-text` and `c-select`.
- The UnoCSS `primary` color.
- The PWA theme color, the Safari mask icon, and the color converter's
starting color.
- The hero in `src/layouts/base.layout.vue` has no divider under the
title. The divider styles were the only user of `useThemeVars` in that
file, so the import is gone too.

### Additional context

- The `success` color stays green on purpose.
- The hero SVG keeps the gradient id `small-hero-gradient-1`. A short id
like `a` could clash with other inline SVGs on the page.
- The favicons and app icon PNGs in `public/` keep the old colors.
- Verification: `pnpm typecheck` passes, and ESLint passes on the
changed `src` files. Screenshots of the home page in light and dark mode
showed the orange hero and badges. I did not run the production build or
the unit tests.

---

### What is the purpose of this pull request?

- [ ] Bug fix
- [ ] New Feature
- [ ] Documentation update
- [x] Other

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01PEUYi1VdYVqUgdM21rF6Xe

---------

Co-authored-by: Claude <noreply@anthropic.com>
Rework the page to match the UX of https://jwt.lannysport.net/.

- Add an Encoded panel with colored token segments, and a Decoded panel
  with an editable header and payload.
- Sign and verify tokens for the HS, RS, ES, and PS algorithms with jose.
- Accept SPKI, PKCS #1, PKCS #8, X.509, and JWK keys.
- Add a share link that carries the token in the URL fragment.
- Remove the claims table and its descriptions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sonarqubecloud

sonarqubecloud Bot commented Nov 6, 2026

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
C Security Rating on New Code (required ≥ A)
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

Comment thread .github/workflows/ci.yml
- run: corepack enable
- uses: actions/setup-node@v3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: pnpm/action-setup@v6.1.1
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- run: corepack enable
- uses: pnpm/action-setup@v6.1.1
Comment thread Dockerfile
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN npm install -g pnpm && pnpm i --frozen-lockfile
RUN npm install -g pnpm@9.15.9 && pnpm i --frozen-lockfile
Comment thread Dockerfile
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN npm install -g pnpm && pnpm i --frozen-lockfile
RUN npm install -g pnpm@9.15.9 && pnpm i --frozen-lockfile
@destan destan closed this Nov 6, 2026
@destan
destan deleted the worktree-jwt-ux branch November 6, 2026 23:44
@destan
destan restored the worktree-jwt-ux branch November 6, 2026 23:52
@destan
destan deleted the worktree-jwt-ux branch November 6, 2026 23:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants