Skip to content

feat(docs): add migration planner site#35

Merged
kjanat merged 6 commits into
masterfrom
feat/site
Jun 22, 2026
Merged

feat(docs): add migration planner site#35
kjanat merged 6 commits into
masterfrom
feat/site

Conversation

@kjanat

@kjanat kjanat commented Jun 22, 2026

Copy link
Copy Markdown
Owner

Summary

  • add SvelteKit migration planner docs workspace
  • align planner defaults with kp2bw 3.7 org/personal folder behavior
  • persist selections, reset, wrapped commands, and split .env/run copy
  • polish shared docs theme, footer, and planner docs

kjanat added 2 commits June 22, 2026 00:54
Add the SvelteKit docs workspace and migration planner UI on top of
the issue-33 CLI behavior.
Match planner defaults to CLI behavior, persist selections, and show
org-folder opt-in behavior without redundant --no-folder flags.

Also split .env/run copy actions and centralize the docs theme tokens so
planner and docs pages share one readable visual system.
@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto reviews are limited based on label configuration.

🏷️ Required labels (at least one) (1)
  • cr:review
🚫 Excluded labels (none allowed) (2)
  • wip
  • cr:skip

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 987361a2-9505-4570-bea6-c5a78ba683df

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This pull request introduces a complete SvelteKit documentation site under docs/ for the kp2bw KeePass-to-Bitwarden migration tool. The core addition is planner.ts, a full migration planning module exporting domain types, filtering/delta/action logic, tree constructors, CLI command generators, and an env-file builder. Five Svelte UI components implement the interactive planner (PathTable, PlannerOptions, CommandBox, HelpMark, TreeLegend). The planner page persists state via localStorage; a separate static documentation page explains all migration options. A Vitest test suite validates the planner logic. The docs/ directory is wired as a Bun workspace, and a GitHub Actions workflow deploys the built site to GitHub Pages. Tooling configs (tsconfig, vite.config, svelte.config, eslint.config) and meta files (robots.txt, AGENTS.md, .mcp.json, OpenCode config) complete the addition.


Sequence Diagram

sequenceDiagram
  participant User
  participant PlannerPage as +page.svelte
  participant LocalStorage
  participant PlannerTS as planner.ts
  participant PathTable
  participant PlannerOptions
  participant CommandBox

  User->>PlannerPage: load page
  PlannerPage->>LocalStorage: read stored PlannerState
  LocalStorage-->>PlannerPage: raw JSON (or empty)
  PlannerPage->>PlannerTS: sanitizePlannerState(raw)
  PlannerTS-->>PlannerPage: validated PlannerState
  User->>PlannerOptions: change options (destination, tags, mapping, rerun)
  PlannerOptions->>PlannerPage: mutate state
  PlannerPage->>PlannerTS: previewForState(state)
  PlannerTS-->>PlannerPage: MigrationPreview (sourceTree + bitwardenTree)
  PlannerPage->>PathTable: keepass + bitwarden trees
  PlannerPage->>PlannerTS: commandDisplayForState + envFileForState
  PlannerTS-->>PlannerPage: formatted command + .env block
  PlannerPage->>CommandBox: command, envFile
  PlannerPage->>LocalStorage: persist updated state
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes


Poem

Arrr, a whole docs site materialised from the void, ye scallywags! ✨
SvelteKit and Bun have boarded the ship,
The planner be chartin' every migration trip! 🗺️
KeePass to Bitwarden, node by node it goes,
With delta badges gleamin' and the tree preview shows!
GitHub Pages hoists the flag up high~ 🏴‍☠️
squeaks I-it's so perfectly typed, I could just cry~! 💕

🚥 Pre-merge checks | ✅ 4 | ❌ 4

❌ Failed checks (4 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.82% which is insufficient. The required threshold is 30.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Changelog Update ⚠️ Warning PR modifies extensive source code files (SvelteKit workspace, 30+ new files, planner components, configs) but leaves CHANGELOG.md's [Unreleased] section completely empty. Add entries to the [Unreleased] section documenting the new SvelteKit docs workspace, migration planner UI, components, and deployment pipeline using standard format (Added/Changed/Fixed).
Semver Version Bump Validation ⚠️ Warning PR adds 11+ Python source files in src/kp2bw/ (cli.py, convert.py, bw_serve.py, etc.) plus SvelteKit components, but version remains at 3.7.0 in pyproject.toml. Increment version in pyproject.toml per SemVer based on change scope (MINOR for new features, MAJOR for breaking changes).
Agents.Md Documentation Updated ⚠️ Warning PR adds new GitHub Actions workflow (pages.yml) for docs deployment but doesn't update .github/workflows/AGENTS.md to document this automation, violating the requirement to update AGENTS.md when PR... Update .github/workflows/AGENTS.md to add pages.yml workflow documentation including its trigger paths (docs/**, package.json, bun.lock) and deployment to GitHub Pages behaviour.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'feat(docs): add migration planner site' follows conventional commit guidelines with a lowercase 'feat' type prefix, includes a clear scope (docs), and uses a descriptive verb (add) indicating a new feature under 50 characters.
Description check ✅ Passed The PR description directly relates to the changeset, detailing the SvelteKit docs workspace, migration planner functionality, persistence, command output, theme improvements, and GitHub Pages deployment—all evident in the file changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@socket-security

socket-security Bot commented Jun 22, 2026

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Obfuscated code: npm @typescript-eslint/eslint-plugin is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: ?npm/typescript-eslint@8.61.1npm/@typescript-eslint/eslint-plugin@8.61.1

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@typescript-eslint/eslint-plugin@8.61.1. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm svelte is 91.0% likely obfuscated

Confidence: 0.91

Location: Package overview

From: docs/package.jsonnpm/svelte@5.56.3

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/svelte@5.56.3. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@kjanat kjanat self-assigned this Jun 22, 2026
Comment thread docs/README.md
@kjanat kjanat added the cr:review Allow CodeRabbit review label Jun 22, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
package.json (1)

20-32: ⚠️ Potential issue | 🟡 Minor

Swab the tombi from devDependencies, ye scallywag!

The tombi dependency (line 27) be redundant — yer .dprint.jsonc correctly invokes it via uvx tombi format, meanin' dprint fetches it at runtime rather than needin' it in package.json. This violates the coding guideline spirit: "use dprint for formatting" (not direct tombi). Remove it.

Also spotted: runner-run appears nowhere in yer codebase — declared in both root and docs workspace as catalog: but never actually invoked. The workflows use the runner GitHub Action (kjanat/runner), not the npm package. Ye might want to verify if this be intentional or dead weight.

The @typescript/native-preview: ^7.0.0-dev be locked to 7.0.0-dev.20260621.1 in bun.lock (intentional, used by tsgo), and @bitwarden/cli: ^2026.5.0 be valid semver — no pipeline failure there, matey.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@package.json` around lines 20 - 32, The tombi dependency in devDependencies
is redundant and should be removed. Since dprint is configured to invoke tombi
at runtime via uvx tombi format in the .dprint.jsonc configuration, including
tombi in package.json violates the guideline to use dprint for formatting.
Delete the tombi line (version ^1.1.4) from the devDependencies object in
package.json. Additionally, verify whether runner-run should be removed as well,
since it is declared in devDependencies as a catalog reference but appears
unused in the codebase and workflows instead rely on the kjanat/runner GitHub
Action.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/pages.yml:
- Line 6: The `pages` job in the workflow lacks an explicit `name` field, which
reduces clarity in the GitHub UI. Add a `name` field to the `pages` job with a
descriptive value that clearly indicates what the job does (such as "Build and
Deploy to GitHub Pages"). This name will appear in the GitHub Actions interface,
making the workflow more readable and easier to track.
- Line 3: The permissions block in the workflow file is formatted inline without
explanatory comments, making it unclear why each permission is needed. Expand
the permissions configuration from the inline format into a multi-line YAML
structure and add comments for each permission entry (contents, pages, and
id-token) explaining their purpose in the GitHub Pages deployment workflow. This
improves maintainability and helps future readers understand the rationale for
each permission.
- Around line 10-18: Replace all unpinned action references with exact commit
SHAs to eliminate supply chain attack vulnerabilities. Update each action in the
workflow: actions/checkout@v7, kjanat/runner@master, oven-sh/setup-bun@v2,
actions/upload-pages-artifact@v5, and actions/deploy-pages@v5 by replacing the
version tags with specific commit SHAs (for example,
actions/checkout@ebd855370882ea0a86163a7e0f4a5366653a0dfe). For each action,
find the commit SHA corresponding to the desired release tag in that action's
repository and replace the `@tag` reference with `@commitSHA` format. This is
especially critical for kjanat/runner@master since using `@master` points to a
mutable branch.

In `@docs/package.json`:
- Line 14: The test script in the package.json file has an extra "run" keyword
at the end that needs to be removed. Locate the "test" script definition and
remove the trailing "run" so the command reads "run test:unit" instead of "run
test:unit run", as the correct runner syntax is "run <task>" without a second
run keyword.

In `@docs/README.md`:
- Around line 7-8: Replace the hardcoded fork URLs in the README.md file at
lines 7-8. Change the "Migration planner" link URL from the full absolute path
to a relative path (.), and change the "Detailed option guide" link URL to a
relative path (./docs). This ensures the links will work correctly regardless of
where the site is deployed, whether it's to the official repository or a
different GitHub Pages URL.

In `@docs/src/app.html`:
- Line 6: Remove the non-standard meta tag with name="text-scale" from the
app.html file. This meta tag is not recognized by any browser and serves no
purpose since proper viewport scaling is already configured elsewhere in the
document. Simply delete the line containing `<meta name="text-scale"
content="scale">` to keep the HTML clean and valid.

In `@docs/src/lib/components/PathTable.svelte`:
- Around line 52-56: The nodeId is constructed using array indices in the
iteration key and the nodeId derivation on lines 52-53, which becomes unstable
when the preview tree shape changes, causing collapsed states to apply to wrong
branches. Replace the array index i with a stable identifier that uniquely
represents each logical node in the tree (such as a node property or unique
name), and apply the same fix to the similar iteration on lines 100-102. This
ensures that the collapsed Set maintains the correct association between node
identities and their collapse state across tree updates.

In `@docs/src/lib/components/TreeLegend.svelte`:
- Around line 42-102: The `.folder` and `.recycle` icon styles use hard-coded
hex color values (`#d2b56f` and `#d48670` respectively) while the `.collection`
style uses CSS custom properties like var(--accent), creating inconsistent
theming. Replace all hard-coded hex colors in the `.folder` class (including its
border-color, background, and ::before pseudo-element styling) and `.recycle`
class (including its border-color, background, and pseudo-element styling) with
appropriate CSS custom properties that match your design system's color palette,
ensuring all three icon types use variables consistently for easier theme
management.

In `@docs/src/lib/planner.ts`:
- Around line 628-631: The quoteArg function does not properly escape
backslashes when they appear before quotes, causing bash parsing errors. Modify
the function to escape backslashes first (replacing \ with \\), then escape
double quotes (replacing " with \"), in that order. This ensures that input
containing backslash-quote sequences like test\".kdbx is properly escaped as
"test\\\"".kdbx" rather than the current incorrect "test\\".kdbx" which causes
the quote to terminate prematurely in bash.

In `@docs/svelte.config.js`:
- Line 10: The process.argv.includes('dev') check in the svelte.config.js paths
configuration is too broad and could incorrectly match arguments like --device
or file paths containing 'dev'. Replace this with a more precise check that
specifically looks for the 'dev' command argument in process.argv (for example,
checking if 'dev' is an exact element in the argv array rather than a substring
match), or alternatively use an environment variable instead for clearer intent
and better configuration control.

---

Outside diff comments:
In `@package.json`:
- Around line 20-32: The tombi dependency in devDependencies is redundant and
should be removed. Since dprint is configured to invoke tombi at runtime via uvx
tombi format in the .dprint.jsonc configuration, including tombi in package.json
violates the guideline to use dprint for formatting. Delete the tombi line
(version ^1.1.4) from the devDependencies object in package.json. Additionally,
verify whether runner-run should be removed as well, since it is declared in
devDependencies as a catalog reference but appears unused in the codebase and
workflows instead rely on the kjanat/runner GitHub Action.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: fcd33f56-728c-4d63-a47d-a9be99fc6a3f

📥 Commits

Reviewing files that changed from the base of the PR and between f0c57f2 and 082c8f2.

⛔ Files ignored due to path filters (2)
  • bun.lock is excluded by !**/*.lock
  • docs/src/lib/assets/favicon.svg is excluded by !**/*.svg
📒 Files selected for processing (32)
  • .github/workflows/pages.yml
  • .gitignore
  • .mcp.json
  • .npmrc
  • .opencode/opencode.json
  • .opencode/svelte.json
  • README.md
  • docs/.gitignore
  • docs/AGENTS.md
  • docs/README.md
  • docs/eslint.config.js
  • docs/package.json
  • docs/src/app.d.ts
  • docs/src/app.html
  • docs/src/lib/components/CommandBox.svelte
  • docs/src/lib/components/HelpMark.svelte
  • docs/src/lib/components/PathTable.svelte
  • docs/src/lib/components/PlannerOptions.svelte
  • docs/src/lib/components/TreeLegend.svelte
  • docs/src/lib/index.ts
  • docs/src/lib/planner.spec.ts
  • docs/src/lib/planner.ts
  • docs/src/lib/preview-fixture.json
  • docs/src/routes/+layout.svelte
  • docs/src/routes/+layout.ts
  • docs/src/routes/+page.svelte
  • docs/src/routes/docs/+page.svelte
  • docs/static/robots.txt
  • docs/svelte.config.js
  • docs/tsconfig.json
  • docs/vite.config.ts
  • package.json
📜 Review details
🧰 Additional context used
📓 Path-based instructions (9)
**

⚙️ CodeRabbit configuration file

**: # PROJECT KNOWLEDGE BASE

Generated: 2026-02-26 Commit: 59ba3c2 Branch: master

OVERVIEW

KeePass to Bitwarden migration CLI. Python runtime package + workspace stubs package. Core flow migrates
entries/folders/attachments/passkeys with bw serve as primary transport.

STRUCTURE

kp2bw/
├── src/kp2bw/                   # Runtime package (CLI + conversion + bw transport + types)
│   └── AGENTS.md
├── specs/                       # OpenAPI spec for Bitwarden vault management API
│   └── vault-management-api.json
├── tests/                       # Script-style smoke + docker e2e + fixture contract
│   └── AGENTS.md
├── packages/pykeepass-stubs/    # Separate stubs release stream
│   └── AGENTS.md
├── scripts/                     # Release/version checks + codegen for github-script
│   └── AGENTS.md
└── .github/workflows/           # CI orchestration (release + integration + codegen drift)
    └── AGENTS.md

WHERE TO LOOK

Task Location Notes
CLI flags, prompts, envs src/kp2bw/cli.py Entrypoint kp2bw.cli:main and python -m kp2bw handoff
Conversion orchestration src/kp2bw/convert.py 3-phase top-level flow; item+attachment migration logic
Bitwarden HTTP transport src/kp2bw/bw_serve.py bw serve lifecycle, dedup index, batch create, attachment upload
Workflow policy details .github/workflows/AGENTS.md Trigger matrix, cross-workflow dependencies, output contracts
Release version gating scripts/version-check-shared.mjs Normalizes release/tag prefixes; drives workflow gates
Main package publishing .github/workflows/publish.yml ...

Files:

  • docs/static/robots.txt
  • docs/src/app.html
  • docs/package.json
  • docs/eslint.config.js
  • docs/AGENTS.md
  • docs/src/routes/+layout.ts
  • docs/src/lib/index.ts
  • docs/tsconfig.json
  • README.md
  • docs/README.md
  • docs/vite.config.ts
  • package.json
  • docs/svelte.config.js
  • docs/src/lib/preview-fixture.json
  • docs/src/app.d.ts
  • docs/src/lib/components/HelpMark.svelte
  • docs/src/routes/+page.svelte
  • docs/src/lib/components/CommandBox.svelte
  • docs/src/lib/components/PathTable.svelte
  • docs/src/routes/+layout.svelte
  • docs/src/lib/components/TreeLegend.svelte
  • docs/src/lib/planner.spec.ts
  • docs/src/routes/docs/+page.svelte
  • docs/src/lib/planner.ts
  • docs/src/lib/components/PlannerOptions.svelte
**/*.{toml,json,jsonc,py}

📄 CodeRabbit inference engine (AGENTS.md)

Use dprint for formatting (config .dprint.jsonc) — run dprint fmt; never tomli/taplo or uv's own output for TOML

Files:

  • docs/package.json
  • docs/tsconfig.json
  • package.json
  • docs/src/lib/preview-fixture.json
docs/**/*.{ts,tsx,js,json}

📄 CodeRabbit inference engine (docs/AGENTS.md)

Use bun as the package manager for dependency management and script execution

Files:

  • docs/package.json
  • docs/eslint.config.js
  • docs/src/routes/+layout.ts
  • docs/src/lib/index.ts
  • docs/tsconfig.json
  • docs/vite.config.ts
  • docs/svelte.config.js
  • docs/src/lib/preview-fixture.json
  • docs/src/app.d.ts
  • docs/src/lib/planner.spec.ts
  • docs/src/lib/planner.ts
**/AGENTS.md

📄 CodeRabbit inference engine (Custom checks)

If any AGENTS.md file exists anywhere in the repository and the PR modifies architecture, workflows, responsibilities, automation behavior, CLI interfaces, or agent-related logic, the corresponding AGENTS.md file in the affected directory MUST be updated in the same PR. If relevant code changes occur without updates to AGENTS.md, issue a warning.

Files:

  • docs/AGENTS.md
docs/**/*.{ts,tsx}

📄 CodeRabbit inference engine (docs/AGENTS.md)

Use TypeScript for all project code

Files:

  • docs/src/routes/+layout.ts
  • docs/src/lib/index.ts
  • docs/vite.config.ts
  • docs/src/app.d.ts
  • docs/src/lib/planner.spec.ts
  • docs/src/lib/planner.ts
.github/workflows/*.yml

📄 CodeRabbit inference engine (AGENTS.md)

Workflow check jobs call scripts/*.mjs via actions/github-script; script output keys are workflow contracts

Files:

  • .github/workflows/pages.yml
.github/**/*.{yml,yaml}

⚙️ CodeRabbit configuration file

Do not ever warn about stylistic yamllint shit. Do warn about security related shit. Insecure shell handling of user supplied / defined strings: think of branch names, inputs, pr content, anything needs to be string interpolation and permission safe.

Files:

  • .github/workflows/pages.yml
{package.json,pyproject.toml,setup.py,Cargo.toml,go.mod,pom.xml,build.gradle,VERSION}

📄 CodeRabbit inference engine (Custom checks)

If any source code files (excluding tests, docs, CI, markdown, or comments-only changes) are modified, a version field MUST be updated in one of the following files if present in the repo: package.json, pyproject.toml, setup.py, Cargo.toml, go.mod, pom.xml, build.gradle, or a VERSION file.

Files:

  • package.json
docs/**/*.svelte

📄 CodeRabbit inference engine (docs/AGENTS.md)

docs/**/*.svelte: Use Svelte 5 and SvelteKit framework for component and application development, with access to comprehensive Svelte 5 and SvelteKit documentation
Use the svelte-autofixer tool to analyze Svelte code and resolve any issues or suggestions before deployment

Files:

  • docs/src/lib/components/HelpMark.svelte
  • docs/src/routes/+page.svelte
  • docs/src/lib/components/CommandBox.svelte
  • docs/src/lib/components/PathTable.svelte
  • docs/src/routes/+layout.svelte
  • docs/src/lib/components/TreeLegend.svelte
  • docs/src/routes/docs/+page.svelte
  • docs/src/lib/components/PlannerOptions.svelte
🪛 GitHub Actions: Integration (Docker) / 2_config.txt
docs/package.json

[error] 1-1: Unexpected @bitwarden/cli version in package.json: '$spec'. Version does not match expected SemVer pattern.

package.json

[error] 1-1: Unexpected @bitwarden/cli version in package.json: '$spec'. Version does not match expected SemVer pattern.

🪛 GitHub Actions: Integration (Docker) / config
docs/package.json

[error] 1-1: PowerShell script failed: Unexpected @bitwarden/cli version in package.json devDependencies. Value '$spec' did not match semver pattern 'A\d+.\d+.\d+([-.+][0-9A-Za-z.-]+)?\z'. Step exited with code 1.


[error] 1-1: Command/step: "(gc package.json | ConvertFrom-Json).devDependencies.'@bitwarden/cli'" followed by version validation "Write-Host "::error::Unexpected @bitwarden/cli version in package.json: '$spec'"; exit 1".

package.json

[error] 1-1: PowerShell script failed: Unexpected @bitwarden/cli version in package.json devDependencies. Value '$spec' did not match semver pattern 'A\d+.\d+.\d+([-.+][0-9A-Za-z.-]+)?\z'. Step exited with code 1.


[error] 1-1: Command/step: "(gc package.json | ConvertFrom-Json).devDependencies.'@bitwarden/cli'" followed by version validation "Write-Host "::error::Unexpected @bitwarden/cli version in package.json: '$spec'"; exit 1".

🪛 HTMLHint (1.9.2)
docs/src/app.html

[error] 8-8: <title> must be present in tag.

(title-require)

🪛 LanguageTool
docs/AGENTS.md

[style] ~9-~9: As a shorter alternative for ‘able to’, consider using “can”.
Context: ...dd-ons**: mcp, vitest, eslint --- You are able to use the Svelte MCP server, where you ha...

(BE_ABLE_TO)


[uncategorized] ~34-~34: Possible missing comma found.
Context: ...nd link. Only call this tool after user confirmation and NEVER if code was written to files ...

(AI_HYDRA_LEO_MISSING_COMMA)

docs/README.md

[uncategorized] ~32-~32: Use a comma before ‘so’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...nds include -- before the KeePass file so the file path is not parsed as another ...

(COMMA_COMPOUND_SENTENCE_2)

🪛 markdownlint-cli2 (0.22.1)
docs/AGENTS.md

[warning] 1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

🪛 zizmor (1.25.2)
.github/workflows/pages.yml

[warning] 10-10: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[error] 3-3: overly broad permissions (excessive-permissions): pages: write is overly broad at the workflow level

(excessive-permissions)


[error] 3-3: overly broad permissions (excessive-permissions): id-token: write is overly broad at the workflow level

(excessive-permissions)


[error] 10-10: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 11-11: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 12-12: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 15-15: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 18-18: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[warning] 3-3: permissions without explanatory comments (undocumented-permissions): needs an explanatory comment

(undocumented-permissions)


[info] 6-6: workflow or action definition without a name (anonymous-definition): this job

(anonymous-definition)

🔍 Remote MCP GitHub Grep

Based on my search results, I've gathered relevant context about the PR. Let me provide my findings:

Code Review Context Summary

GitHub Pages Deployment Patterns

The PR's GitHub Actions workflow for deploying to GitHub Pages aligns with industry-standard patterns. Analysis of similar workflows across major projects (Apache Spark, google-gemini/gemini-cli, FerretDB) confirms that the approach used is conventional:

  • Permission model: The PR correctly uses minimal permissions: contents: read, pages: write, and id-token: write for actions/deploy-pages
  • Workflow structure: Using actions/upload-pages-artifact followed by actions/deploy-pages is the standard two-step pattern observed across production projects
  • Concurrency group: Using a fixed pages concurrency group prevents simultaneous deployments, which is best practice

SvelteKit Configuration Conventions

svelte.config.js patterns: The PR's configuration follows established SvelteKit conventions:

  • Using the static adapter with fallback: '404.html' for single-page app fallback is documented in the official SvelteKit adapter-static documentation
  • Dynamic kit.paths.base from environment variables or CLI flags (process.argv) matches patterns used in production SvelteKit deployments
  • Enabling compilerOptions.runes aligns with modern SvelteKit rune-based component architecture

vite.config.ts testing setup: The Vitest configuration with @vitest/browser-playwright for browser testing and separate Node project configuration is a documented pattern in Angular CLI, Storybook, and other major projects. This provides:

  • Cross-browser test support via Chromium headless
  • Separation of client/server test concerns

Prerendering and Routing

The use of export const prerender = true and export const trailingSlash = 'always' in docs/src/routes/+layout.ts is a well-established pattern for static site generation in SvelteKit projects (as seen in evidence-dev/evidence, SveltePress, and other community projects).

Component and State Patterns

The PR implements standard Svelte patterns that are widely used:

  • Reactive state with $props(): Modern Svelte components use the $props() rune for type-safe prop declarations (standardized in recent Svelte versions)
  • Hydration guards: The use of a hydrated flag before accessing browser APIs like localStorage prevents hydration mismatches—a common source of errors in SSR contexts
  • Clipboard API usage: Using navigator.clipboard.writeText() with proper error handling and timeout management follows web standards

ESLint Configuration

The ESLint flat config approach (using defineConfig) with explicit TypeScript and Svelte support is modern best practice, though no direct examples were found in the search. The configuration structure with separate overrides for Svelte patterns is sound and prevents false-positive type errors.

TypeScript Configuration

The docs/tsconfig.json follows SvelteKit best practices by:

  • Extending the auto-generated ./.svelte-kit/tsconfig.json
  • Using strict: true for strict type checking
  • Configuring moduleResolution: "bundler" for proper module resolution
🔇 Additional comments (44)
README.md (1)

213-213: LGTM!

docs/src/lib/components/PlannerOptions.svelte (2)

1-112: LGTM!

Also applies to: 117-134, 139-194, 199-329


113-116: Aye, this be already shipshape, matey! The HelpMark.svelte component imports resolve from '$app/paths' and applies it to the href—<a href={resolve(href)}>continue reading</a>—so base-path resolution be handled proper-like fer GitHub Pages deployments under a repo subpath. No treasure hunt needed here!

			> Likely an incorrect or invalid review comment.
docs/src/lib/components/CommandBox.svelte (1)

1-145: LGTM!

docs/src/routes/+page.svelte (1)

1-239: LGTM!

docs/src/routes/docs/+page.svelte (1)

1-588: LGTM!

docs/src/lib/components/HelpMark.svelte (1)

1-77: LGTM!

This component is a solid example of Svelte 5 patterns and accessibility. The $props rune centralizes prop management, making it easier to validate and handle defaults, and HelpMark demonstrates this well with a typed literal union for href validation. The tooltip interaction is semantically correct (role="tooltip" + aria-label on the button) and fully keyboard-accessible via :focus-visible styling. CSS custom properties are used consistently throughout, and the responsive width logic (min(250px, 78vw)) will play nice on small screens. Ship it, matey! ⚓

docs/src/lib/components/TreeLegend.svelte (1)

1-5: LGTM!

The markup is clean and accessible—aria-label on the legend div provides a proper semantic name. The icon construction via CSS pseudo-elements is elegant and performant (no image overhead). The responsive flexbox layout with flex-wrap will adapt to narrow screens nicely. Just consider the theming consistency noted above, and this component'll be dead solid. ⚓

docs/src/routes/+layout.svelte (1)

1-123: LGTM!

This layout is a masterclass in design token discipline. The :root CSS variables define a complete and coherent colour system (surfaces, text ladder, edges, accent, focus), type scale (label/small/body), and spacing rhythm (4px-based). The fact that you've limited the palette to three surface tiers and documented the hierarchy in comments ("not everything tiny") shows real design thinking. Footer links correctly use rel="noreferrer" for security, and the global :focus-visible styling gives keyboard users a guaranteed focus ring. The monospace-throughout font choice is bold and fits the CLI-migration vibe perfectly. Well shipworthy! ⚓

docs/src/routes/+layout.ts (1)

1-2: LGTM!

Setting prerender = true and trailingSlash = 'always' ensures the planner renders to static HTML (GitHub Pages compatible) and keeps URLs consistent for anchor navigation (#reruns). Clean and intentional. ⚓

docs/src/lib/planner.ts (11)

1-27: LGTM!


28-103: LGTM!


105-128: LGTM!


139-180: LGTM!


182-209: LGTM!


211-252: LGTM!


254-290: LGTM!


292-399: LGTM!


403-438: LGTM!


440-462: LGTM!


464-479: LGTM!

docs/src/lib/preview-fixture.json (1)

1-177: LGTM!

docs/src/lib/index.ts (1)

1-2: LGTM!

docs/src/lib/planner.spec.ts (9)

1-43: LGTM!


45-116: LGTM!


118-143: LGTM!


145-185: LGTM!


187-218: LGTM!


220-260: LGTM!


262-294: LGTM!


296-329: LGTM!


331-346: Kyaa~! These helper functions are so cute and recursive, senpai! 💕

Everything's perfect desu~

package.json (1)

4-4: Aye, the workspace declaration be structurally sound. The "workspaces": ["docs"] enables Bun monorepo buildin' and pairs correctly with the catalog versioning below. The downstream GitHub Pages workflow (via runner --dir=docs install build) depends on this, and it'll work proper-like once ye fix the blockin' issues above.

.npmrc (1)

1-1: LGTM!

.gitignore (1)

21-22: LGTM!

.mcp.json (1)

1-8: LGTM!

.opencode/opencode.json (1)

1-6: LGTM!

docs/.gitignore (1)

1-23: LGTM!

docs/static/robots.txt (1)

1-3: LGTM!

docs/eslint.config.js (1)

1-38: Shiver me timbers, that flat config be seaworthy! Modern ESLint 9 with proper TypeScript and Svelte integration. The projectService: true (line 27) and parser: ts.parser override for Svelte files be exactly right fer type-aware linting, ye scurvy dog.

Svelte 5 compatibility—all hands on deck, it be solid! eslint-plugin-svelte version 3.19.0 includes explicit support fer Svelte 5 (released 30 May 2026, bless the seas), with svelte-eslint-parser updated to 1.7.0. The svelte.configs.recommended at line 14 be proper and shipshape, no doubts about it.

.opencode/svelte.json (1)

1-3: LGTM!

docs/tsconfig.json (1)

1-20: LGTM!

docs/vite.config.ts (1)

1-35: LGTM!

docs/src/app.d.ts (1)

1-13: LGTM!

Comment thread .github/workflows/pages.yml
Comment thread .github/workflows/pages.yml
Comment thread .github/workflows/pages.yml
Comment thread docs/package.json
Comment thread docs/README.md
Comment thread docs/src/app.html
Comment thread docs/src/lib/components/PathTable.svelte Outdated
Comment thread docs/src/lib/components/TreeLegend.svelte Outdated
Comment thread docs/src/lib/planner.ts
Comment thread docs/svelte.config.js
@kjanat kjanat added cr:skip Skip CodeRabbit review and removed cr:review Allow CodeRabbit review labels Jun 22, 2026
Escape generated shell args correctly, keep tree collapse state tied
to logical paths, and route tree icon colors through theme tokens.
@kjanat kjanat merged commit e045cb6 into master Jun 22, 2026
14 checks passed
@kjanat kjanat deleted the feat/site branch June 22, 2026 03:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cr:skip Skip CodeRabbit review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant