* [AI] Add impeccable design skill wiring and project design context
Commit only the shareable parts of the impeccable frontend-design skill
setup: defensive hook wiring (.codex, .cursor, .github hooks that no-op
when the skill is not installed locally) and the generated design
context files (PRODUCT.md, DESIGN.md, DESIGN.json) derived from the
existing component-library tokens and themes. The skill payload itself
is gitignored; developers install it locally.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Recommend installing the impeccable skill to agents at boot
AGENTS.md documents the install step, a Claude Code SessionStart hook
surfaces it when the skill is missing from the checkout, and the Codex
and Copilot hook wiring echoes the same hint instead of silently
no-oping.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Mention DESIGN.json among committed design context files
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Keep DESIGN.json out of the repo as a generated artifact
It is a regenerable sidecar of DESIGN.md consumed only by the locally
installed impeccable live panel, so gitignore it like the skill payload.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Clarify that DESIGN.md hex values are the light-theme mapping
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* [AI] Fail agent hooks with an actionable error when jq is missing
The shared agent-hook scripts all parse their payload with jq but never
checked it exists. A missing jq made git-guard.sh block every Bash call
with a misleading 'could not parse the hook payload' message, while other
hooks silently failed open and skipped their checks (issue #8629).
Add require_jq to common.sh — called by every hook before its first jq
use — so a missing jq fails closed with a clear install message, distinct
from a malformed-payload error. The script name in the message is derived
from $0 rather than passed by each caller. The Cursor adapters emit a
static JSON deny (their deny() helper itself needs jq to build JSON) or
an advisory where blocking isn't possible, and AGENTS.md now documents
the prerequisite.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Address review: advisory wording for PostToolUse hooks, hook tests
PostToolUse hooks (format-edited-file, prefer-one-component) run after the
edit already happened, so a missing jq now reports 'Agent hook skipped'
instead of claiming a block. Exit 2 stays: it is the only exit code that
feeds stderr back to the agent. Add scripts/agent-hooks/test-hooks.sh, a
standalone runnable check covering the missing-jq path for every hook plus
malformed-JSON, missing-field, and guard-behavior cases, and soften the
release-note verb.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Remove standalone hook test script
Not wired into CI, so it only served as a manual check; the hook behavior
was verified by hand and the script isn't worth maintaining.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* [AI] Enable React Compiler for all monorepo packages with React code
The compiler was previously scoped to desktop-client/src only. Now:
- desktop-client's Vite build also compiles component-library source
(consumed as raw source through the same build), covering web,
desktop, and mobile bundles
- component-library's Storybook and Vitest pipelines apply the compiler
so they exercise the same compiled output
- docs (Docusaurus) enables babel-plugin-react-compiler for the site's
own React components
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PdcKq244khwKhedvLCwu7p
* [AI] Declare npm-run-all in component-library so its test script resolves
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PdcKq244khwKhedvLCwu7p
* [AI] Generalize React Compiler include to any workspace package source
Match packages/<name>/src instead of enumerating package names, so a
future workspace library with React components is compiled automatically.
Third-party code stays out via the babel plugin's default node_modules
exclude, which applies alongside a custom include.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PdcKq244khwKhedvLCwu7p
* [AI] Inline component-library test script instead of using npm-run-all
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PdcKq244khwKhedvLCwu7p
* [AI] Drop React Compiler from docs
The docs site is static content with a handful of simple components, so
auto-memoization buys nothing there, and an unscoped babel plugin would
also process Docusaurus theme code and every MDX page. Reverting keeps
the compiler where it pays off: desktop-client and component-library.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PdcKq244khwKhedvLCwu7p
---------
Co-authored-by: Claude <noreply@anthropic.com>
* [AI] Run agent hooks and skills in Codex-based harnesses (ChatGPT desktop app)
The ChatGPT desktop app (and Codex CLI/IDE) never picked up the repo's
agent skills or lifecycle hooks:
- Skills: Codex surfaces scan .agents/skills, not .claude/skills. Add a
symlink mirror so both harness families load the same skill files.
- Hooks: Codex lifecycle hooks are feature-flagged; enable them in the
project .codex/config.toml and document the trust steps (project
.codex layer trust + one-time /hooks trust) required for them to run.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FMdDFdaErx9dqieTGh8ETg
* [AI] Drop .agents/skills/README.md; document the mirror in AGENTS.md instead
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FMdDFdaErx9dqieTGh8ETg
* [AI] Ignore .agents/** in knip like .claude/**
The .agents/skills symlink mirror exposes skill reference files under a
path knip scanned, flagging highlight-element.js as an unused file.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FMdDFdaErx9dqieTGh8ETg
---------
Co-authored-by: Claude <noreply@anthropic.com>
* [AI] Add cross-platform hook keeping GitHub comments/issues in Chinese or pirate voice
Adds a shared agent hook that requires anything an agent posts to GitHub
(PR/issue comments, PR reviews, created issues) to be written in 简体中文
(preferred) or, failing that, a fun pirate voice — never plain English.
- scripts/agent-hooks/github-comment-style.sh: shared guard. Reads
tool_input.body/.title, allows CJK or pirate-flavoured text, blocks plain
English via exit 2. Fails open on malformed payloads.
- Wired for Claude (.claude/settings.json PreToolUse), Codex
(.codex/config.toml PreToolUse) and Cursor (beforeMCPExecution adapter).
- Documents the rule in AGENTS.md, the canonical pr-and-commit-rules.md and
the Cursor rule so platforms without hook support apply it manually.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lqu3eZi5djm2cPAEm3yVht
* [AI] Use a slug for the release-note filename; document slug naming in AGENTS.md
Release-note filenames don't need to be the PR number — a short descriptive
slug works too (the PR link is resolved at release time). Rename the new note
accordingly and note this in AGENTS.md's directory reference.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lqu3eZi5djm2cPAEm3yVht
* [autofix.ci] apply automated fixes
* [AI] Auto-label PRs with Chinese descriptions as "ai spam" via CodeRabbit
Add a CodeRabbit labeling instruction (auto_apply_labels is already on) that
applies the "ai spam" label when a PR description contains Chinese/CJK
characters — a strong signal of AI-generated spam for this English-language
project.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lqu3eZi5djm2cPAEm3yVht
* [AI] Exempt CodeRabbit-addressed comments from the Chinese/pirate voice hook
CodeRabbit parses its commands (@coderabbitai review/resolve/etc.) as plain
English, so the github-comment-style guard now skips any comment mentioning
@coderabbitai / @coderabbit instead of forcing it into Chinese or pirate.
Documented the exception in the canonical and Cursor rule files.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lqu3eZi5djm2cPAEm3yVht
* [AI] Key CodeRabbit voice exemption on authorship, not mentions
The hook only ever runs on the agent's own outgoing comments, so CodeRabbit's
own comments are already out of scope (it posts under its own identity). Drop
the @coderabbitai mention bypass — a comment merely name-dropping the bot is
still the agent's prose and must follow the Chinese/pirate rule, closing an
easy plain-English bypass. Docs updated to match.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lqu3eZi5djm2cPAEm3yVht
* [AI] Pin CodeRabbit reviews to English
CodeRabbit was reading AGENTS.md / pr-and-commit-rules.md (which ask
contributors to comment in Chinese/pirate) and applying that to its own
reviews, posting them in Chinese. Set `language: en-US` and `tone_instructions`
so the bot's own reviews, summaries and replies stay in English; the
Chinese/pirate rule is for contributor/agent comments, not CodeRabbit.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lqu3eZi5djm2cPAEm3yVht
* [AI] Replace Chinese/pirate comment voice with a robot-emoji prefix
Scrap the 简体中文/pirate voice scheme (and its CodeRabbit language override and
Chinese-based "ai spam" label) in favour of one simple rule: every GitHub
comment, review or issue an agent posts must be prefixed with 🤖. The shared
guard now blocks any body — or, for issues, title — that doesn't start with the
robot emoji; docs and per-platform wiring updated to match. .coderabbit.yaml is
restored to its original state.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lqu3eZi5djm2cPAEm3yVht
* [AI] Silence SC1007 false positive on CDPATH= cd in Cursor MCP adapter
shellcheck flags the intentional `CDPATH= cd` empty-env prefix as SC1007
(mistaking it for an assignment). Add a scoped inline disable directive on that
line; behaviour is unchanged.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lqu3eZi5djm2cPAEm3yVht
* [AI] Fail closed on guard execution errors in Cursor MCP adapter
The adapter previously allowed the call on any non-0/2 exit from
github-comment-style.sh, so a broken or missing guard would silently disable
enforcement. Deny on unexpected exits instead (matching guard-shell.sh), with a
message that marks it as an execution problem rather than a real policy denial.
The shared guard still fails open on malformed payloads (its own exit-0 choice).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lqu3eZi5djm2cPAEm3yVht
* [AI] Add hook requiring a blank PR template when agents create PRs
New shared guard pr-template-blank.sh blocks mcp__github__create_pull_request
unless the body is the repo's PR template, unmodified (cosmetic whitespace
aside) — agents must leave it blank for the human, per AGENTS.md. Wired for
Claude (PreToolUse), Codex (PreToolUse) and Cursor (the beforeMCPExecution
adapter now dispatches per-tool to the right guard). Docs and a release note
updated.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lqu3eZi5djm2cPAEm3yVht
* [AI] Simplify agent-hook guard scripts
- github-comment-style.sh: fold the empty/whitespace-only case into the
prefix check, dropping a redundant tr subshell per field.
- pr-template-blank.sh: drop the dead CR strip in canon() (the trailing
whitespace sub already removes a trailing carriage return).
- before-mcp-github.sh: emit the constant allow payload with printf instead
of spawning jq on the common (allow) path.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* [AI] Drop duplicated PR-template/robot-emoji rules now that hooks enforce them
The PR-template-blank and GitHub-comment robot-emoji-prefix rules are enforced
by cross-platform hooks, so the copies scattered across AGENTS.md and the
Cursor rules file are redundant. Remove them and point at the canonical
pr-and-commit-rules.md, which keeps the full rule (including the PR-template
Chinese exception that no hook can enforce). Also delete the internal
PR-template-guard release note.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* [AI] Drop "enforced by hooks" wording from the PR/comment rule docs
State the rules plainly without the meta-commentary about hook enforcement.
Keeps the actual rules (don't fill the PR template, prefix GitHub
comments/reviews/issues with 🤖, the Chinese exception, and the
your-own-comments-only note) intact.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* [AI] Trim enforcement meta-commentary; shorten robot-emoji release note
Drop the "isn't enforced automatically" / "handled by tooling" framing from
AGENTS.md and pr-and-commit-rules.md (keeping the rule and the "apply it
yourself" responsibility), and shorten the robot-emoji-prefix release note.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* [AI] Fail closed on unreadable payloads in the GitHub agent guards
Align the new guards with the git-guard.sh / guard-shell.sh convention: fail
closed when the hook payload can't be read, fail open only on a genuinely
absent optional field.
- github-comment-style.sh: block on invalid JSON / missing / non-object
.tool_input; allow only an absent body/title within a valid object.
- before-mcp-github.sh: deny on a jq parse failure / missing .tool_name
instead of falling through to allow.
- pr-template-blank.sh: an absent/null body now fails open (previously it
normalized to "" and wrongly blocked PR creation); an empty-string body is
still treated as a real non-template submission.
- .codex/config.toml: describe the full guard scope (comment body + issue
title) in the hook comment and statusMessage.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* [AI] Replace mechanical agent rules with shared agent hooks + nano-staged
Move the mechanical "remember to run X" rules out of AGENTS.md and the
agent guidance docs into deterministic, cross-agent hooks, and migrate
the pre-commit runner from lint-staged to nano-staged.
- Add shared hook scripts in scripts/agent-hooks/ (git-guard,
format-edited-file, no-strict-ignore-new-file, prefer-one-component,
check-on-stop, common helpers) wired for Claude (.claude/settings.json),
Codex (.codex/config.toml), and Cursor (.cursor/hooks.json + adapters).
- Enforce "avoid enum" via a new actual/no-enum lint rule, grandfathering
the two existing declarations in .oxlintrc.json overrides.
- Migrate lint-staged -> nano-staged (.nano-staged.json, .husky/pre-commit,
package.json).
- Trim AGENTS.md, .github/agents/pr-and-commit-rules.md, the Cursor rule,
and the committing skill down to the rules that aren't auto-enforced.
- Add release note 8089.md.
* [AI] Align PR-title wording in AGENTS.md with canonical rules
* [AI] Fix check-on-stop hook on bash 3.2 and TSV column collapse
The Stop hook silently no-op'd in two ways:
- `declare -A` isn't supported on stock macOS bash 3.2, and the
slash/hyphen path subscript aborted under `set -u`. Dedupe via a
space-padded string match instead.
- jq emitted an empty middle TSV field for a package with test but no
typecheck; tab is IFS-whitespace so `read` collapsed it and shifted the
columns (eslint-plugin-actual then ran neither). Emit non-empty
sentinels (-, yes/no) so no field can collapse.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
* [AI] Consolidate loot-core connection: default web path, electron split, drop .browser
* [autofix.ci] apply automated fixes
* [AI] Replace browser-preload .browser extension with package.json subpath imports
Use the imports field in desktop-client/package.json with conditional
resolution (electron → empty stub, default → real implementation) to
eliminate the last .browser file extension from the codebase.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Refactor connection imports to use @actual-app/core
* Implement connection mock for desktop-client tests and update import path
* [AI] Fix formatting and update imports after master merge
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* [AI] Fix connection mock in TransactionsTable tests and use electron-renderer condition
Wire up the manual connection mock for TransactionsTable tests since the
__mocks__ directory was removed, and restore electron-renderer condition
in loot-core package.json exports.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* [autofix.ci] apply automated fixes
* [AI] Remove redundant resolveExtensions from vite configs
These arrays were identical to Vite's built-in default and served no purpose.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* [AI] Remove remaining resolveExtensions from vite/vitest configs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* [AI] Fix build failures: update browser-preload import path and condition
- Change loot-core/shared/platform to @actual-app/core/shared/platform
- Use electron-renderer condition for #browser-preload to match vite resolve
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* [AI] Remove redundant resolveExtensions from api and loot-core desktop configs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Remove '*.browser.ts' extension and alias resolutions
Removed the special '*.browser.ts' file extension and file resolutions via alias, preferring conditions.
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* [AI] Publish loot-core (@actual-app/core) nightly first in workflow
* [autofix.ci] apply automated fixes
* Refactor imports and update configuration
- Updated .oxfmtrc.json to change "parent" to ["parent", "subpath"].
- Removed unnecessary blank lines in various TypeScript files to improve code readability.
- Adjusted import order in reports and rules files for consistency.
* Add workflow steps to pack and publish the core package nightly
* Remove nightly tag from npm publish command in workflow for core package
* Update post-build script comment to reflect correct workspace command for loot-core declarations
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* [AI] Switch typecheck from tsc to tsgo and fix Menu type narrowing
* [autofix.ci] apply automated fixes
* Add .gitignore for dist directory, update typecheck script in package.json to use -b flag, and remove noEmit option from tsconfig.json files in ci-actions and desktop-electron packages. Introduce typesVersions in loot-core package.json for improved type handling.
* Refactor SelectedTransactionsButton to improve type safety and readability. Updated items prop to use spread operator for conditional rendering of menu items, ensuring proper type annotations with MenuItem. This change enhances the clarity of the component's structure and maintains TypeScript compliance.
* Update tsconfig.json in desktop-electron package to maintain consistent formatting for plugins section. No functional changes made.
* [autofix.ci] apply automated fixes
* Update package.json and yarn.lock to add TypeScript 5.8.0 dependency. Adjust typesVersions in loot-core package.json for improved type handling. Enhance tsconfig.json in sync-server package to enable strictFunctionTypes for better type safety.
* Enhance tsconfig.json in ci-actions package by adding composite option for improved project references and build performance.
* [AI] Revert typescript to 5.9.3 for ts-node compatibility
Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>
* [AI] Update yarn.lock after TypeScript version change
Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>
* Refactor Menu component for improved type safety and readability. Updated type assertions for Menu.line and Menu.label, simplified type checks in filtering and selection logic, and enhanced conditional rendering of menu items. This change ensures better TypeScript compliance and maintains clarity in the component's structure.
* Refactor Select and OpenIdForm components to improve type safety and simplify logic. Updated item mapping to handle Menu.line more effectively, enhancing clarity in selection processes. Adjusted SelectedTransactionsButton to streamline item creation and improve readability.
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>
* [AI] Extract PR/commit rules into shared agent skill
Deduplicate PR and commit instructions from AGENTS.md into a standalone
skill file at .github/agents/pr-and-commit-rules.md. This single source
of truth is consumed by both Claude Code (via CLAUDE.md @-import) and
Cursor (via .cursor/rules/pr-and-commit.mdc with alwaysApply: true).
AGENTS.md now references the shared file instead of repeating the rules
in three separate sections.
https://claude.ai/code/session_01KkHg7MYXrTyDkTw6u98Vam
* Add release notes for PR #7153
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* lint: patch some no-empty-function violations
* docs: update ESLint rules and remove unused loadOwner function in UserAccess component
* refactor: remove getRemoteFile function and associated method from budget file handlers
* chore: disable docstring checks in coderabbit configuration
* docs: Add comprehensive developer documentation
- Add development-setup.md with environment setup and essential commands
- Add testing.md documenting Lage, Vitest, and Playwright workflows
- Add code-style.md with TypeScript, React, and coding conventions
- Add troubleshooting.md for common development issues
- Enhance contributing/index.md with development workflow section
- Expand project-details/index.md with detailed package descriptions
- Enhance architecture.md with technical details and remove outdated references
- Update AGENTS.md to reflect docs are now part of monorepo
- Fix outdated command examples and Node.js version references
- Update sidebar to include new documentation sections
* fix: Correct link path in code-style.md
* docs: Update documentation references and remove outdated notes
- Clarify that the documentation website is now part of the monorepo in AGENTS.md
- Remove the import organization section from code-style.md to streamline guidelines
- Update project-details/index.md to reflect the current status of the documentation website
* Update release-notes workflow to exclude AGENTS.md from non-docs file checks
* Update release-notes workflow to remove AGENTS.md exclusion and add upcoming release notes for missing information in Agents.md
* Refactor documentation to streamline testing and project structure guidelines
- Removed outdated test commands from AGENTS.md and development-setup.md for clarity.
- Updated code-style.md to correct a formatting issue in the contribution checklist.
- Consolidated package command references in project-details/index.md to focus on essential information.
- Enhanced troubleshooting documentation by removing redundant steps and clarifying solutions.
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #6120
---------
Co-authored-by: Matt Fiddaman <github@m.fiddaman.uk>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>