Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
3b17f14
Add Simon as sample app #24
joshuafolkken May 5, 2026
5ac1c03
Fix playwright.config.ts to use defineConfig directly #24
joshuafolkken May 5, 2026
6dda828
Revert playwright.config.ts to create_playwright_config #24
joshuafolkken May 5, 2026
a319320
Restore noEmitOnError false for library type generation #24
joshuafolkken May 5, 2026
19855e7
Fix playwright config and update project files #24
joshuafolkken May 7, 2026
d2e709b
Move E2E tests to e2e/ directory to match testDir config #24
joshuafolkken May 7, 2026
ab0a324
Fix playwright testMatch to find .e2e.ts files #24
joshuafolkken May 7, 2026
9f64ba0
Fix playwright.config.ts to use build and preview #24
joshuafolkken May 7, 2026
0e4dc81
Fix playwright webServer to use pnpm run #24
joshuafolkken May 7, 2026
d740cb1
Add workers 1 to playwright config to prevent SQLite lock #24
joshuafolkken May 7, 2026
351903b
Fix security vulnerabilities by updating vite-plugin-pwa to 1.3.0 #24
joshuafolkken May 7, 2026
1a503a8
Fix security vulnerabilities by pinning safe dependency versions #24
joshuafolkken May 7, 2026
5a45c63
Merge remote-tracking branch 'origin/main' into 24-add-simon-as-sampl…
joshuafolkken May 9, 2026
6e4ac9a
Use production build for pre-push E2E tests (Vite 8 dev server CSS re…
joshuafolkken May 9, 2026
685f0c1
Switch pre-push E2E to PLAYWRIGHT_PREVIEW var to reliably trigger pre…
joshuafolkken May 9, 2026
84b6764
Use lefthook env: key for PLAYWRIGHT_PREVIEW to correctly set env #24
joshuafolkken May 9, 2026
b2ba2fb
Clean wrangler state before pre-push E2E to avoid SQLite locking #24
joshuafolkken May 9, 2026
e6f8ca2
Fix pre-push E2E hook to use --workers=1 for preview server stability
joshuafolkken May 9, 2026
49dff58
Fix preview mode E2E to run with single worker via config
joshuafolkken May 9, 2026
96cfcd8
Convert arrow function methods to method shorthand per project conven…
joshuafolkken May 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
54 changes: 18 additions & 36 deletions .github/workflows/auto-tag.yml
Original file line number Diff line number Diff line change
@@ -1,38 +1,49 @@
name: Auto Tag on Version Change

on:
push:
branches: [main]
paths:
- 'package.json'
repository_dispatch:
types: [ci-passed-on-main]

jobs:
create-tag:
name: Create Git Tag if Version Changed
runs-on: ubuntu-latest
permissions:
contents: write
actions: read
steps:
- name: Checkout code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
ref: ${{ github.event.client_payload.sha }}
fetch-depth: 2

- name: Setup Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '24'

- name: Check if package.json changed
id: pkg_changed
run: |
if git diff HEAD~1 --name-only | grep -q '^package.json$'; then
echo "changed=true" >> $GITHUB_OUTPUT
echo "✅ package.json changed in this commit"
else
echo "changed=false" >> $GITHUB_OUTPUT
echo "ℹ️ package.json not changed, skipping tag creation"
fi

- name: Get current version
id: current_version
if: steps.pkg_changed.outputs.changed == 'true'
run: |
VERSION=$(node -p "require('./package.json').version")
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Current version: $VERSION"

- name: Check if version changed
id: version_check
if: steps.pkg_changed.outputs.changed == 'true'
env:
CURRENT_VERSION: ${{ steps.current_version.outputs.version }}
run: |
Expand All @@ -54,38 +65,9 @@ jobs:
echo "ℹ️ First commit, creating tag"
fi

- name: Wait for CI to pass on this commit
id: ci_gate
if: steps.version_check.outputs.changed == 'true'
env:
SHA: ${{ github.sha }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
for attempt in $(seq 1 18); do
result=$(gh run list --workflow ci.yml --repo "$GITHUB_REPOSITORY" \
--json headSha,conclusion,status \
--jq "[.[] | select(.headSha == \"$SHA\")] | .[0] | .conclusion // .status // \"none\"" 2>/dev/null || echo "none")
case "$result" in
success)
echo "passed=true" >> $GITHUB_OUTPUT
echo "✅ CI passed, proceeding with tag creation"
exit 0
;;
failure | cancelled | timed_out)
echo "passed=false" >> $GITHUB_OUTPUT
echo "⚠️ CI $result on this commit, skipping tag creation"
exit 0
;;
esac
echo "CI status: $result (attempt $attempt/18)"
sleep 10
done
echo "passed=false" >> $GITHUB_OUTPUT
echo "⏱️ Timed out waiting for CI"

- name: Check if tag already exists
id: tag_check
if: steps.version_check.outputs.changed == 'true' && steps.ci_gate.outputs.passed == 'true'
if: steps.version_check.outputs.changed == 'true'
env:
VERSION: ${{ steps.current_version.outputs.version }}
run: |
Expand All @@ -101,7 +83,7 @@ jobs:

- name: Create and push tag
id: create_tag
if: steps.version_check.outputs.changed == 'true' && steps.ci_gate.outputs.passed == 'true' && steps.tag_check.outputs.exists == 'false'
if: steps.version_check.outputs.changed == 'true' && steps.tag_check.outputs.exists == 'false'
env:
VERSION: ${{ steps.current_version.outputs.version }}
run: |
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4

- name: Install pnpm
uses: pnpm/action-setup@903f9c1a6ebcba6cf41d87230be49611ac97822e # v6.0.3
uses: pnpm/action-setup@8912a9102ac27614460f54aedde9e1e7f9aec20d # v6.0.5

- name: Setup Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
Expand Down Expand Up @@ -116,7 +116,7 @@ jobs:
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4

- name: Install pnpm
uses: pnpm/action-setup@903f9c1a6ebcba6cf41d87230be49611ac97822e # v6.0.3
uses: pnpm/action-setup@8912a9102ac27614460f54aedde9e1e7f9aec20d # v6.0.5

- name: Setup Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
Expand Down
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@

engine-strict=true
minimum-release-age=1440
confirmModulesPurge=false
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

pnpm confirmModulesPurge configuration option documentation

💡 Result:

The confirmModulesPurge configuration option in pnpm controls whether to show the interactive confirmation prompt when pnpm needs to remove and reinstall the node_modules directory from scratch (e.g., due to layout version mismatch).[1][2][3] It corresponds to the confirm-modules-purge key in configuration files. By default, the prompt is shown (equivalent to true). Set it to false to suppress the prompt and automatically proceed with the purge.[1][2] Configuration methods: - In .npmrc (project or user level): confirm-modules-purge=false[1][2] - CLI override: --config.confirmModulesPurge=false[3] - Flags like --yes or --force also bypass the prompt by setting this internally.[4][1] Note: This is a non-auth setting, so it may be excluded from global config.yaml (marked in configFileKey.ts).[2] Most non-registry settings go in pnpm-workspace.yaml, but sources specify .npmrc for this one.[5][2] As of pnpm 11.x (current as of 2026), official docs do not yet list it explicitly, but it was added via PR #11125 in March 2026.[1][2] Example in .npmrc: confirm-modules-purge=false This avoids needing --yes or --force every time for non-interactive scripts or CI.[1][3]

Citations:


Use kebab-case for the pnpm configuration key: confirm-modules-purge=false instead of confirmModulesPurge=false

The .npmrc file requires kebab-case formatting for configuration keys. The setting confirmModulesPurge uses camelCase, which pnpm will not recognize. Change line 6 to:

confirm-modules-purge=false

This option controls whether pnpm shows an interactive confirmation prompt when purging node_modules, and setting it to false is appropriate for CI/automation scenarios.

🤖 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 @.npmrc at line 6, Replace the camelCase pnpm config key with kebab-case:
change the setting named confirmModulesPurge to confirm-modules-purge in the
.npmrc so pnpm recognizes it (leave the value as false for CI/automation).

10 changes: 6 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ GitHub operations use the `gh` CLI. Authenticate once with `gh auth login`; no a

- **NEVER** remove or modify entries in `pnpm.overrides` without explicit user approval.
- After running `pnpm update`, `josh latest`, or any dependency-update command, verify that `pnpm.overrides` is unchanged **and** that `devDependencies` versions still respect the overrides. If any entry was removed, modified, or bumped past an override, restore it immediately.
- **NEVER** modify the `devEngines` field in `package.json` without explicit user confirmation. `devEngines` pins the required development toolchain (e.g. pnpm version); silently changing it can break CI or other contributors' environments. After any dependency-update command, verify `devEngines` is unchanged. If it was modified, restore it immediately and ask the user before making any change.

## Code Change Rules

Expand Down Expand Up @@ -140,6 +141,7 @@ Before every `git commit` — including follow-up commits on the same branch —
- **No commits** unless explicitly requested by the user
- **No PR merges, branch deletions, force pushes, or other shared-state mutations** unless explicitly requested in the current turn. The default end state is PR still OPEN — do not run `gh pr merge` on your own. **Exception**: invoking `fullrun` or `fullrun new` is explicit authorization to merge; use `pnpm josh followup --merge` in that flow.
- For git operations: use `pnpm josh git`
- **Recovery after failed push**: If `pnpm josh git -y` fails at the push step (e.g. pre-push hook blocked), fix the issue, push manually, then run `pnpm josh pr` (or `pnpm josh git -y --skip-commit --skip-push`) to create the PR. **Never** use `gh pr create` directly — it bypasses `closes #N` generation and the Issue will not auto-close.
- **Start-of-conversation git status is a stale snapshot.** The `gitStatus` block in the environment preamble is captured once at session start and never refreshes. Before acting on any assumption about working-tree / index / stash / branch state, run `git status` live first. Never report state or propose a plan based on the snapshot alone.

## Collaboration Workflow
Expand All @@ -155,16 +157,16 @@ Before every `git commit` — including follow-up commits on the same branch —

#### `fullrun` — Full execution (plan → implement → PR → completion notify)

- `fullrun #<N>`: Read Issue #N → **normalize the title**: if the title is not in English or can be phrased more clearly/conventionally, derive a better English title and run `gh issue edit <N> --title "<title>"` → **add `in-progress` label** (create if missing: `gh label create "in-progress" --color "#0075ca" --description "Work is actively in progress" 2>/dev/null || true`, then `gh issue edit <N> --add-label "in-progress"`) → post the agreed plan only if the Issue body is blank (use `gh issue edit <N> --body "<plan>"`); if the body already has content, skip the plan-posting step → implement → `pnpm josh bump minor` → `pnpm josh git -y` → run `/review` skill → `pnpm josh followup --merge`. Issue plan comments MUST be written in English. Before implementing, run `git switch main && git pull`, then `josh latest` (includes `pnpm audit`; fix with `overrides` in `package.json` if vulnerabilities found). **After `josh latest`: verify `pnpm.overrides` was not modified — if any override was auto-removed or changed, investigate why it existed and restore it before proceeding (do NOT remove intentional overrides without user approval).** After committing, run the `/review` skill on the completed PR diff; fix all high/medium-priority findings and re-run until clean before proceeding to `followup`. When running `pnpm josh followup --merge`, compose an implementation summary in English and pass it via `--notify-message`. Format: `"Implemented <title>:\n- <change1>\n- <change2>\n..."`. **`pnpm josh followup --merge` waits for CI, verifies AI review findings, sends the completion notification, then merges — all in one step. If AI review blockers are found, followup exits non-zero; fix the findings and re-run `pnpm josh followup --merge`.**
- `fullrun new` or `fullrun new "<title>"`: Shortcut that combines `kickoff new` + `fullrun #<N>` into a single run. Steps: (1) Derive an English title from the conversation, or use the provided title. (2) Create Issue: `gh issue create --title "<title>" --body "<body>"`. Capture the new Issue number `<N>`. (3) Add `in-progress` label: `gh label create "in-progress" --color "#0075ca" --description "Work is actively in progress" 2>/dev/null || true`, then `gh issue edit <N> --add-label "in-progress"`. (4) Post the agreed plan in English. (5) Run `git switch main && git pull`. (6) Run `josh latest`. **After `josh latest`: verify `pnpm.overrides` was not modified — if any override was auto-removed or changed, restore it before proceeding.** (7) Implement. (8) `pnpm josh bump minor`. (9) `pnpm josh git -y "<title> #<N>"`. (10) Run `/review` skill on the completed PR diff; fix all high/medium-priority findings and re-run until clean. (11) `pnpm josh followup "<title> #<N>" --merge --notify-message "Implemented <title>:\n- <change1>\n- <change2>\n..."`.
- `fullrun #<N>`: Read Issue #N → **normalize the title**: if the title is not in English or can be phrased more clearly/conventionally, derive a better English title and run `gh issue edit <N> --title "<title>"` → **add `in-progress` label** (create if missing: `gh label create "in-progress" --color "#0075ca" --description "Work is actively in progress" 2>/dev/null || true`, then `gh issue edit <N> --add-label "in-progress"`) → post the agreed plan only if the Issue body is blank (use `gh issue edit <N> --body "<plan>"`); if the body already has content, skip the plan-posting step → implement → `pnpm josh bump minor` → `pnpm josh git -y` → run `/review` skill → `pnpm josh followup --merge`. Issue plan comments MUST be written in English. Before implementing, run `git switch main && git pull`, then `josh latest` (includes `pnpm audit`; fix with `overrides` in `package.json` if vulnerabilities found). **After `josh latest`: verify `pnpm.overrides` was not modified — if any override was auto-removed or changed, investigate why it existed and restore it before proceeding (do NOT remove intentional overrides without user approval). Also verify `devEngines` is unchanged — restore it and ask the user before making any change if it was modified.** After committing, run the `/review` skill on the completed PR diff; fix all high/medium-priority findings and re-run until clean before proceeding to `followup`. When running `pnpm josh followup --merge`, compose an implementation summary in English and pass it via `--notify-message`. Format: `"Implemented <title>:\n- <change1>\n- <change2>\n..."`. **`pnpm josh followup --merge` waits for CI, verifies AI review findings, sends the completion notification, then merges — all in one step. If AI review blockers are found, followup exits non-zero; fix the findings and re-run `pnpm josh followup --merge`.**
- `fullrun new` or `fullrun new "<title>"`: Shortcut that combines `kickoff new` + `fullrun #<N>` into a single run. Steps: (1) Derive an English title from the conversation, or use the provided title. (2) Create Issue: `gh issue create --title "<title>" --body "<body>"`. Capture the new Issue number `<N>`. (3) Add `in-progress` label: `gh label create "in-progress" --color "#0075ca" --description "Work is actively in progress" 2>/dev/null || true`, then `gh issue edit <N> --add-label "in-progress"`. (4) Post the agreed plan in English. (5) If the working tree already has staged or modified files (e.g., user pre-staged kit/config changes), stash them first: `git stash`. (6) Run `git switch main && git pull`. (7) Run `josh latest` — **mandatory, never skip even if the working tree had modifications**. **After `josh latest`: verify `pnpm.overrides` was not modified — if any override was auto-removed or changed, restore it before proceeding. Also verify `devEngines` is unchanged — restore it and ask the user before making any change if it was modified. If you stashed changes in step 5, restore them now: `git stash pop`.** (8) Implement. (9) `pnpm josh bump minor`. (10) `pnpm josh git -y "<title> #<N>"`. (11) Run `/review` skill on the completed PR diff; fix all high/medium-priority findings and re-run until clean. (12) `pnpm josh followup "<title> #<N>" --merge --notify-message "Implemented <title>:\n- <change1>\n- <change2>\n..."`.

#### `queue` — Sequential multi-issue fullrun

`queue #N1 #N2 #N3 ...` runs `fullrun` for each issue in order. All issues must already exist (no `new` variant).

**Steps:**

1. Run `git switch main && git pull`, then `josh latest` once (before the first issue). Verify `pnpm.overrides` is unchanged after `josh latest`.
1. If the working tree already has staged or modified files, stash them first: `git stash`. Run `git switch main && git pull`, then `josh latest` once (before the first issue) — **mandatory, never skip**. Verify `pnpm.overrides` and `devEngines` are unchanged after `josh latest`. If you stashed changes, restore them: `git stash pop`.
2. For each issue `#<N>` in the supplied order:
a. From the 2nd issue onward: run `git switch main && git pull` to incorporate the previous PR's merge.
b. Execute the full `fullrun #<N>` flow: normalize title → add `in-progress` label → post plan if body is blank → implement → `pnpm josh bump minor` → `pnpm josh git -y "<title> #<N>"` → run `/review` skill → `pnpm josh followup "<title> #<N>" --merge --notify-message "Implemented <title>:\n- ..."` (sends per-issue completion notification and merges, exactly as `fullrun` does).
Expand All @@ -174,7 +176,7 @@ Before every `git commit` — including follow-up commits on the same branch —
**Key rules:**

- Invoking `queue` is explicit authorization to merge each PR (same as `fullrun`).
- `josh latest` runs only once, before the first issue.
- `josh latest` runs only once, before the first issue. If files were pre-staged when `queue` was invoked, they must be stashed before `josh latest` and restored after.
- All `kickoff`/`fullrun` mid-workflow stop rules (confirmation notification, AI review blocker handling, etc.) apply within each issue's execution.

#### AI reviewer comment scan (automatic in `pnpm josh followup`)
Expand Down
Loading
Loading