Skip to content

feat(push): support .acaiignore for custom path/glob exclusions#11

Open
QT-7274 wants to merge 2 commits into
acai-sh:mainfrom
QT-7274:feat/acaiignore-support
Open

feat(push): support .acaiignore for custom path/glob exclusions#11
QT-7274 wants to merge 2 commits into
acai-sh:mainfrom
QT-7274:feat/acaiignore-support

Conversation

@QT-7274
Copy link
Copy Markdown

@QT-7274 QT-7274 commented May 21, 2026

Why

The hardcoded `IGNORED_REF_DIRS` set (extended in #10) covers common build-artifact directories, but real projects always have edge cases — vendored snapshots, generated fixtures, legacy code that should not register ACIDs, project-specific cache dirs, or stack-specific patterns like `*.egg-info` that exact-name matching cannot express.

This PR adds an optional `.acaiignore` file at the repo root, parsed at `acai push` time. The matcher is applied during the file walk in `listRepoFiles`/`walkFiles`, so excluded paths are skipped before spec parsing and ACID reference scanning — same scope as `IGNORED_REF_DIRS`.

Built on top of #10

This branch is opened against `main` for review convenience but logically depends on #10 (extended defaults + features/ exemption). I'll rebase if #10 lands first.

Supported syntax (gitignore subset)

  • blank lines and `#`-prefixed lines are ignored
  • segment patterns (no `/`): match any path segment, e.g. `target` matches `foo/target/bar`
  • prefix patterns (containing `/`): match a relative path prefix, e.g. `src/legacy/` only matches under `src/`
  • leading `/`: anchors the pattern to the repo root, e.g. `/build-cache` only matches the top-level directory
  • trailing `/`: stripped — we always match against directory entries
  • ``: single-segment glob (`[^/]`), enabling patterns like `*.egg-info` that the exact-name set cannot express

Intentionally NOT supported

  • `**` multi-segment matching
  • `!pattern` negation (parser ignores them rather than crashing)

These are kept simple and predictable for v1. Both can be added later if there is demand.

Precedence

`IGNORED_REF_DIRS` > `.acaiignore` > default scan. The two ignore mechanisms compose (union). The features/ exemption from #10 still applies — `.acaiignore` cannot accidentally hide `features//` unless you target it explicitly.

Tests

8 new cases added to `src/core/push.test.ts`:

  • missing `.acaiignore` is a no-op
  • segment patterns ignore matching directories anywhere in the tree
  • prefix patterns (containing `/`) match relative path prefixes only
  • leading slash anchors a pattern to the repo root
  • single-segment `*` glob matches any single segment
  • comments and blank lines are skipped
  • negation lines (`!pattern`) are skipped (unsupported, no crash)
  • file-level patterns (e.g. `snapshot.json`) ignore matching files

`AGENT=1 bun test src/core/push.test.ts` → 30 pass, 0 fail.

🤖 Co-authored-by Claude

drogbaqu and others added 2 commits May 21, 2026 19:40
The default IGNORED_REF_DIRS only excluded
.git/node_modules/coverage/dist/tmp/states/.agents, which left common
build-artifact directories on the scan path. On large repos this could
push the JSON payload past V8's max string length and produce
"Invalid string length" errors during `acai push --all`.

Changes:

- Extend IGNORED_REF_DIRS with common build/cache dirs:
  target, build, out, bin, obj, .next, .nuxt, .svelte-kit, .turbo,
  .cache, .parcel-cache, .vite, .astro, DerivedData, Pods,
  __pycache__, .venv, venv, .tox, .mypy_cache, .pytest_cache,
  .ruff_cache, vendor, .idea, .vscode, .DS_Store.

- Intentionally do NOT add 'src-tauri'. It contains real Rust source
  under src-tauri/src/** that should be scanned. The heavy artifact
  is src-tauri/target/, which is already covered by the 'target' entry.

- This set still uses exact-name matching. Glob patterns like
  '*.egg-info' are intentionally NOT supported here; a separate change
  introduces .acaiignore for that.

- Always descend into the canonical features/ tree even if a
  subdirectory's name collides with an ignored build dir
  (e.g. features/build/login.feature.yaml for product 'build').

Tests: 4 new cases in push.test.ts cover target/build/.next/vendor/
__pycache__ exclusion, src-tauri/src descent, and features/build
descent.

Co-Authored-By: Claude <[email protected]>
Adds an optional `.acaiignore` file at the repo root, parsed at
`acai push` time. The matcher is applied during the file walk in
`listRepoFiles`/`walkFiles`, so excluded paths are skipped before
spec parsing and ACID reference scanning.

Supported syntax (gitignore subset):

- blank lines and `#`-prefixed lines are ignored
- segment patterns (no `/`): match any path segment, e.g. `target`
  matches `foo/target/bar`
- prefix patterns (containing `/`): match a relative path prefix,
  e.g. `src/legacy/` only matches under `src/`
- leading `/`: anchors the pattern to the repo root, e.g.
  `/build-cache` only matches the top-level directory
- trailing `/`: stripped (we always match against directory entries)
- `*`: single-segment glob (`[^/]*`); enables patterns like
  `*.egg-info` that the exact-name `IGNORED_REF_DIRS` set cannot
  express

Intentionally NOT supported (kept simple and predictable):

- `**` multi-segment matching
- `!pattern` negation (parser ignores them rather than crashing)

Precedence: `IGNORED_REF_DIRS` > `.acaiignore` > default scan.
The two ignore mechanisms compose (union).

The features/ exemption introduced in the previous commit still
applies — `.acaiignore` cannot accidentally hide `features/<x>/`
unless you target it explicitly.

Tests: 8 new cases in push.test.ts cover missing file no-op,
segment patterns, prefix patterns, anchored patterns, `*` glob,
comments/blank lines, unsupported negation graceful skip, and
file-level patterns.

Co-Authored-By: Claude <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant