Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
4a7b1e0
Merge pull request #51 from lorem-dev/main
lorem-dev Sep 8, 2026
231633d
chore(deps): bump toml in the cargo-minor-and-patch group (#52)
dependabot[bot] Sep 8, 2026
fed188d
chore(deps): bump actions/checkout from 5 to 7 (#53)
dependabot[bot] Sep 8, 2026
0eb6bbe
chore(deps): bump actions/upload-artifact from 6 to 7 (#54)
dependabot[bot] Sep 8, 2026
397dfa4
chore(deps): bump astral-sh/setup-uv from 7.6.0 to 10.0.1 (#57)
dependabot[bot] Sep 8, 2026
ca875f9
ci: take the release pipeline's action majors together (#58)
lorem-dev Sep 8, 2026
24fc53c
docs: record the dependency refresh in the changelog
lorem-dev Sep 8, 2026
879fa2d
chore: refresh the third-party notices versions
lorem-dev Sep 8, 2026
6e11b48
release: 0.7.1-rc.1
lorem-dev Sep 8, 2026
2f3108e
Merge pull request #59 from lorem-dev/release/0.7.1-rc.1
lorem-dev Sep 8, 2026
de470aa
test: move the cli end-to-end suite into e2e/cli
lorem-dev Sep 8, 2026
46d6160
docs: fix stale e2e paths left by the cli suite move
lorem-dev Sep 8, 2026
4dc5b1c
test: boot the renderer under a scripted backend
lorem-dev Sep 8, 2026
21fe82d
fix: address boot-smoke-test review findings
lorem-dev Sep 8, 2026
3a7593e
test: give the desktop suite a scenario-driven fixture
lorem-dev Sep 8, 2026
b235175
fix(e2e): zero animations earlier and prove the harness wiring
lorem-dev Sep 8, 2026
6637fa4
test: cover adding a repository and a failing clone
lorem-dev Sep 8, 2026
bb83fce
fix(desktop): stop treating a duplicate add as success
lorem-dev Sep 9, 2026
983cdd3
test: cover browsing, installing, and skill dependencies
lorem-dev Sep 9, 2026
e1ca532
fix(desktop): keep skills-page layout inert, tighten flows 3/11
lorem-dev Sep 9, 2026
df26bbb
test: cover tracking a project and a missing folder
lorem-dev Sep 9, 2026
34b303b
test: cover the settings page and an offered update
lorem-dev Sep 9, 2026
d0c4dc2
fix(e2e): drive config validity from the scenario
lorem-dev Sep 9, 2026
d56512c
test: cover installing, updating, and a refused mcp update
lorem-dev Sep 9, 2026
af5ba4e
test: rebuild mcp update regression test on the real path
lorem-dev Sep 9, 2026
09b10d3
test: prove the unmocked-command guard can actually fail
lorem-dev Sep 9, 2026
3be4def
style: run prettier over drifted renderer and e2e files
lorem-dev Sep 9, 2026
68eebc8
ci: run the desktop ui suite on every pull request
lorem-dev Sep 9, 2026
818a84a
fix(ci): scope the cli e2e job to the cli half only
lorem-dev Sep 9, 2026
cfd88f9
docs(e2e): repoint stale test:e2e refs at the cli half
lorem-dev Sep 9, 2026
8d139eb
fix(desktop): unstick repo-add cancel and notif log cutoff
lorem-dev Sep 9, 2026
4cf1504
fix(desktop): kind-only toast testid, unique skill tree node ids
lorem-dev Sep 9, 2026
ce7e5d1
test(e2e): strengthen mcp/projects assertions, fix a false claim
lorem-dev Sep 9, 2026
ea15fe6
docs: name test:e2e:cli as the submodule's actual trigger
lorem-dev Sep 9, 2026
d9331a3
docs(e2e): drop pointers to git-ignored design artifacts
lorem-dev Sep 9, 2026
6e35833
Merge pull request #60 from lorem-dev/feature/desktop-ui-e2e
lorem-dev Sep 9, 2026
012bfe7
docs: state in CHANGES.md what earns a changelog entry
lorem-dev Sep 9, 2026
27eb899
release: 0.7.1-rc.2
lorem-dev Sep 9, 2026
0e21f70
Merge pull request #61 from lorem-dev/release/0.7.1-rc.2
lorem-dev Sep 9, 2026
bb36052
release: 0.7.1
lorem-dev Sep 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 25 additions & 7 deletions .agents/skills/check-changes/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,21 @@ release.
Open `CHANGES.md` and extract every bullet under `## Development`.

4. **Cross-reference.**
For each commit that represents a user-visible change (type `feat`, `fix`,
`refactor`, or `perf`), check whether a corresponding bullet exists in the
Development section. A bullet does not need to quote the commit message
verbatim -- it only needs to describe the same change at a short summary
level.
`CHANGES.md` opens with a comment block stating what qualifies for an entry.
Read it first; it is authoritative and the rules below restate only what
this check needs.

A commit needs a bullet when it adds something a user can use, changes
behaviour they would be surprised by, removes something, or fixes a bug
that was BROKEN IN A RELEASED VERSION. A bullet does not need to quote the
commit message -- it only needs to describe the same change.

A commit does NOT need one when it is refactoring, a test, CI, an internal
rename, or a dependency bump with no user-visible effect. Nor when it fixes
a bug that never shipped: if the last released version did not have the
defect, the changelog has nothing to say about it. That case is common on a
long branch and is the one most often reported as a false gap -- check the
bug's origin before flagging a missing entry, not just the commit's type.

5. **Check each bullet against the length rule.**
Per the "Changelog Entries" section of CONTRIBUTING.md, a bullet is at most
Expand All @@ -45,15 +55,23 @@ release.
ones that exceed it, with their count. Do not measure released `## Version`
sections -- a section is frozen once cut and is never rewritten.

6. **Report findings.**
6. **Check the section against the entry-count limits.**
`CHANGES.md`'s comment block sets a soft limit of **10** bullets per version
section and a hard limit of **50**, counting every bullet across its
subsections. Report the count. Over the soft limit, name the entries that
look mergeable or cuttable. Over the hard limit, say plainly that the
release must not ship until they are merged or cut.

7. **Report findings.**
- List commits with NO changelog entry (missing entries -- these must be
added).
- List changelog bullets that appear to describe nothing in the commit
history (stale or speculative entries -- flag for author review).
- List bullets over the 25-word limit, each with its count, and propose a
shorter wording.
- Report the section's bullet count against the soft and hard limits.
- If everything matches, report "CHANGES.md is current."

7. **Do not edit CHANGES.md automatically.**
8. **Do not edit CHANGES.md automatically.**
Propose the missing bullets in your report and let the developer apply them.
The developer owns the changelog wording.
8 changes: 6 additions & 2 deletions .agents/skills/check-docs/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,12 @@ Verify that all project documentation is accurate and up to date.
(e.g., `1.0.0`) must match the version in root `package.json`.

6. **Check CHANGES.md structure.**
Confirm the file starts with a `## Development` section and that previous
release sections follow the `## Version X.Y.Z` heading format (no date).
Confirm the file carries its rules comment block, that `## Development` is
the first heading after it, and that previous release sections follow the
`## Version X.Y.Z` heading format (no date). The block sits above
`## Development` on purpose: `release-notes.mjs` extracts only from a
`## Version` heading to the next `## `, so anything above the first one
never reaches a GitHub release.

7. **Report.**
List every issue found (missing files, broken nav links, stale commands,
Expand Down
22 changes: 12 additions & 10 deletions .agents/skills/check-fixture-repo/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ its own README explains what each fixture drives.

## Isolation

The suite never touches the developer's machine state. `e2e/src/cli.ts` is the
The suite never touches the developer's machine state. `e2e/cli/src/cli.ts` is the
only way a spec can invoke the CLI, and it always sets **both**:

- `XDG_CONFIG_HOME`, which relocates `state.json` and `config.yaml`
Expand All @@ -42,13 +42,13 @@ the machine -- which is why the harness owns them rather than each spec.
### 1. Run the suite

```bash
pnpm test:e2e
pnpm test:e2e:cli
```

That is the whole check. The script behind it
(`scripts/e2e-prepare.mjs`) initializes the fixture submodule, force-pulls it to
the tip of its branch, and builds `target/debug/skillkeeper`; Jest then runs the
specs in `e2e/tests/`.
specs in `e2e/cli/tests/`.

Set `SKILLKEEPER_E2E_PIN_FIXTURE=1` to run against the fixture commit this
repository pins instead of pulling. CI does that for reproducibility; locally
Expand All @@ -61,11 +61,13 @@ to look:

| spec | covers | a failure means |
|---|---|---|
| `e2e/tests/fixture.spec.ts` | the submodule is checked out, ASCII-only, and still has the manifests and file modes the rest of the suite assumes | the **fixture** drifted |
| `e2e/tests/skills.spec.ts` | resolution schemes, `.skid.yml` identity, nested body paths, selective `+x`, guidance precedence, hook merge and consent, the delimited-text region, and both silent-failure modes of the resolver | the **product** changed |
| `e2e/tests/mcp.spec.ts` | preset discovery including the group-scoped file, parameter substitution, both ledger files, the `.gitignore` guard for the secrets file, rules rendering, instance-name allocation, the Codex stdio-only skip, and removal | the **product** changed |
| `e2e/tests/repair.spec.ts` | `verify` -> `repair` -> `verify`, directory pruning, the bounds that keep repair inside the repaired skill, and uninstall reversing hooks and guidance | the **product** changed |
| `e2e/tests/requires.spec.ts` | skill dependencies: every `repo lint` code the `requires` group triggers, the single-document `--json` form, both target-misuse exits, the transitive install closure, and the uninstall breakage report | the **product** changed |
| `e2e/cli/tests/fixture.spec.ts` | the submodule is checked out, ASCII-only, and still has the manifests and file modes the rest of the suite assumes | the **fixture** drifted |
| `e2e/cli/tests/skills.spec.ts` | resolution schemes, `.skid.yml` identity, nested body paths, selective `+x`, guidance precedence, hook merge and consent, the delimited-text region, and both silent-failure modes of the resolver | the **product** changed |
| `e2e/cli/tests/mcp.spec.ts` | preset discovery including the group-scoped file, parameter substitution, both ledger files, the `.gitignore` guard for the secrets file, rules rendering, instance-name allocation, the Codex stdio-only skip, and removal | the **product** changed |
| `e2e/cli/tests/mcp-oauth.spec.ts` | the oauth preset's exact per-agent native shape, the copilot skip, that no agent's config ever carries a client secret, and `repo lint` on the deliberately invalid oauth preset | the **product** changed |
| `e2e/cli/tests/mcp-parameters.spec.ts` | link rendering, description truncation, option-value validation on install, and every mcp lint warning a description or parameter can trigger | the **product** changed |
| `e2e/cli/tests/repair.spec.ts` | `verify` -> `repair` -> `verify`, directory pruning, the bounds that keep repair inside the repaired skill, and uninstall reversing hooks and guidance | the **product** changed |
| `e2e/cli/tests/requires.spec.ts` | skill dependencies: every `repo lint` code the `requires` group triggers, the single-document `--json` form, both target-misuse exits, the transitive install closure, and the uninstall breakage report | the **product** changed |

If `fixture.spec.ts` fails, fix or re-pin the fixture. If it passes and another
spec fails, the CLI's behaviour moved and the fixture is telling you so.
Expand All @@ -90,7 +92,7 @@ git -C examples/test-repo status --porcelain # expect clean
```

Every spec runs the CLI with throwaway `HOME` and `XDG_CONFIG_HOME`
(`e2e/src/cli.ts`), so a dirty tree here means a test wrote somewhere it should
(`e2e/cli/src/cli.ts`), so a dirty tree here means a test wrote somewhere it should
not have -- a blocker, and a harness defect rather than a product one.

Note that a force-pull may legitimately leave the submodule pointer moved; that
Expand All @@ -103,7 +105,7 @@ commit the bump on its own.
Jest already reports per-test results, so summarize rather than restate:

```
pnpm test:e2e: PASS / FAIL (N passed, N failed of 51)
pnpm test:e2e:cli: PASS / FAIL (N passed, N failed of 67)
failing spec(s): <file> -> <test name>
attributed to: fixture drift / product change / harness defect
working tree clean after: yes / no
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/backmerge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
open-backmerge-pr:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v7
with:
fetch-depth: 0

Expand Down
75 changes: 71 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v7
with:
# Fetch LFS blobs (png/ttf/woff2): the icon generator and the font
# assets read real bytes, not the LFS pointer text.
Expand Down Expand Up @@ -82,6 +82,9 @@ jobs:
- name: Type-check
run: pnpm typecheck

- name: Check formatting
run: pnpm format:check

- name: Test with coverage (90% gate)
# vitest run --coverage enforces the thresholds defined in vitest.config.ts.
# The build fails if lines or branches fall below 90%.
Expand All @@ -97,7 +100,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v7
with:
# Fetch LFS blobs (png/ttf/woff2): the icon generator and the font
# assets read real bytes, not the LFS pointer text.
Expand Down Expand Up @@ -228,7 +231,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v7
with:
# Nothing this job reads is LFS-tracked today, but fetch the blobs
# anyway: if a fixture or an asset the CLI touches ever becomes
Expand Down Expand Up @@ -262,10 +265,74 @@ jobs:

# The suite drives only the CLI crate, which does not link the webview, so
# the Tauri system libraries the `rust` job installs are not needed here.
# Explicitly the CLI half, not `pnpm test:e2e`: this job has no
# Playwright browser install, so the desktop half would fail with
# "browserType.launch: Executable doesn't exist" here. The desktop half
# runs in its own `desktop-e2e` job below, which does install Chromium.
- name: Run the end-to-end suite
# Pin the fixture to the commit this repository records: a CI run must be
# reproducible and fail for reasons in the diff, not because the fixture
# moved. Locally the same script force-pulls instead.
env:
SKILLKEEPER_E2E_PIN_FIXTURE: '1'
run: pnpm test:e2e
run: pnpm test:e2e:cli

desktop-e2e:
name: Desktop UI (Playwright)
runs-on: ubuntu-latest
timeout-minutes: 20

steps:
- name: Checkout repository
uses: actions/checkout@v7
with:
lfs: false
submodules: false

- name: Enable pnpm via corepack
run: corepack enable

- name: Set up Node.js with pnpm cache
uses: actions/setup-node@v5
with:
node-version: '24'
cache: pnpm

- name: Install dependencies (frozen lockfile)
run: pnpm install --frozen-lockfile

- name: Generate localization catalogs
run: pnpm run i18n

# Keyed on the whole lockfile, not just the Playwright package version:
# a browser build is ~150MB, so caching it is worth doing, but the key
# deliberately errs coarse. Keying on a parsed-out Playwright version
# instead would risk a bump the parsing misses reusing a stale,
# mismatched browser binary; hashing the full lockfile instead means an
# occasional needless re-download on an unrelated dependency bump,
# which is the safe direction to be wrong in.
- name: Cache the Playwright browser
id: playwright-cache
uses: actions/cache@v6
with:
path: ~/.cache/ms-playwright
key: playwright-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}

- name: Install Chromium
run: pnpm exec playwright install --with-deps chromium

# No separate "build the renderer" step here: playwright.config.ts
# chains `frontend:build` into the webServer command so every run
# boots a fresh bundle, and a build failure surfaces as the webServer
# failing to come up. A second, earlier build step would only repeat
# that work.
- name: Run the desktop UI suite
run: pnpm test:e2e:desktop

- name: Upload the report on failure
if: failure()
uses: actions/upload-artifact@v7
with:
name: playwright-report
path: playwright-report/
retention-days: 7
4 changes: 2 additions & 2 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v7
with:
# No LFS and no submodules on purpose. CodeQL reads source, not
# binary assets, and examples/test-repo is a fixture whose contents
Expand Down Expand Up @@ -106,7 +106,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v7
with:
lfs: false
submodules: false
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v7
with:
# mike needs full history plus the gh-pages branch it maintains.
fetch-depth: 0
Expand All @@ -54,7 +54,7 @@ jobs:
lfs: true

- name: Install uv
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1

- name: Configure git identity for mike
run: |
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v7
with:
# check-tag-branch.mjs asks whether the tag is reachable from main or
# develop, which needs the full history and those branch refs -- a
Expand Down Expand Up @@ -143,7 +143,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v7
with:
# The desktop build needs real binary assets (LFS-tracked fonts and
# icon source PNGs), not LFS pointer files.
Expand Down Expand Up @@ -266,7 +266,7 @@ jobs:
} >> "$GITHUB_ENV"

- name: Build the app (Tauri)
uses: tauri-apps/tauri-action@84b9d35b5fc46c1e45415bdb6144030364f7ebc5 # v0.6.2
uses: tauri-apps/tauri-action@1deb371b0cd8bd54025b384f1cd735e725c4060f # v1.0.0
env:
# macOS signing is injected via $GITHUB_ENV by "Configure Apple code
# signing" above, and only when a certificate secret is set. The
Expand Down Expand Up @@ -454,7 +454,7 @@ jobs:
# dir (linux/windows) and the cross-target dir (macOS --target).
# -----------------------------------------------------------------------
- name: Upload artifacts
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: skillkeeper-${{ github.ref_name }}-${{ matrix.target }}
path: |
Expand Down Expand Up @@ -488,7 +488,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v7

- name: Set up Node.js 22
uses: actions/setup-node@v5
Expand All @@ -503,7 +503,7 @@ jobs:
run: node scripts/release-notes.mjs

- name: Download all artifacts
uses: actions/download-artifact@v7
uses: actions/download-artifact@v8
with:
path: dist-all

Expand Down
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ Thumbs.db
# Storybook
apps/desktop/storybook-static/

# Playwright: `outputDir`'s default walks up from the config file's directory
# (e2e/desktop/) to the nearest package.json and appends test-results/ to
# THAT directory -- today that lands at the repository root (e2e/desktop/ has
# no package.json of its own), but that is one `e2e/desktop/package.json` away
# from moving to e2e/desktop/test-results/ (see e2e/cli/package.json for a
# sibling suite that already has one). No leading slash, so these match
# wherever it actually lands rather than assuming which.
test-results/
playwright-report/
blob-report/

# Documentation site (mkdocs + uv): uv caches the tools globally, but keep any
# local Python virtualenv and the rendered static site out of git.
.venv/
Expand Down
Loading
Loading