Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions .claude/commands/setup-statusline.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ Output: Raw JSON status data

## Status File

Auto-build writes status to `.auto-claude-status` in your project root:
Auto-build writes status to `.aperant-status` in your project root:

```json
{
Expand Down Expand Up @@ -121,7 +121,7 @@ When active, you'll see these indicators:
## Troubleshooting

### Status not showing?
1. Check if `.auto-claude-status` exists in your project root
1. Check if `.aperant-status` exists in your project root
2. Verify the path to `statusline.py` is correct
3. Try running the command manually: `python auto-claude/statusline.py --format compact`
Comment on lines +124 to 126
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Use one canonical path name throughout this guide.

Line 124 moved to .aperant-status, but Lines 126/139/145/150 still instruct auto-claude/statusline.py. This mixed naming creates a broken/ambiguous setup path for users.

Proposed doc fix
-3. Try running the command manually: `python auto-claude/statusline.py --format compact`
+3. Try running the command manually: `python aperant/statusline.py --format compact`
...
-python auto-claude/statusline.py --format compact
+python aperant/statusline.py --format compact
...
-python auto-claude/statusline.py --format compact --spec 001-my-feature
+python aperant/statusline.py --format compact --spec 001-my-feature
...
-python ~/projects/my-app/auto-claude/statusline.py --format compact --project-dir ~/projects/my-app
+python ~/projects/my-app/aperant/statusline.py --format compact --project-dir ~/projects/my-app

Also applies to: 139-150

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/commands/setup-statusline.md around lines 124 - 126, The guide
currently mixes two path names — `.aperant-status` and
`auto-claude/statusline.py` — causing ambiguity; pick one canonical path (e.g.,
`.aperant-status/statusline.py` or `auto-claude/statusline.py`) and update all
occurrences in the document so they match consistently (references in the
checklist, the "Try running the command" example, and the later steps around
lines 139–150). Search for strings `.aperant-status` and
`auto-claude/statusline.py` and replace them with the chosen canonical path in
the setup-statusline.md content, and ensure the example command (the `python ...
--format compact` line) and any path-verification steps reference that same
canonical path.


Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,16 @@ lerna-debug.log*
.worktrees/

# ===========================
# Auto Claude Generated
# Aperant Generated
# ===========================
.aperant/
.auto-claude/
.planning/
.planning-archive/
.auto-build-security.json
.aperant-security.json
.auto-claude-security.json
.aperant-status
.auto-claude-status
.claude_settings.json
.update-metadata.json
Expand Down
10 changes: 5 additions & 5 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,10 @@ Your context window will be automatically compacted as it approaches its limit,

### Resetting PR Review State

To fully clear all PR review data so reviews run fresh, delete/reset these three things in `.auto-claude/github/`:
To fully clear all PR review data so reviews run fresh, delete/reset these three things in `.aperant/github/`:

1. `rm .auto-claude/github/pr/logs_*.json` — review log files
2. `rm .auto-claude/github/pr/review_*.json` — review result files
1. `rm .aperant/github/pr/logs_*.json` — review log files
2. `rm .aperant/github/pr/review_*.json` — review result files
3. Reset `pr/index.json` to `{"reviews": [], "last_updated": null}`
4. Reset `bot_detection_state.json` to `{"reviewed_commits": {}}` — this is the gatekeeper; without clearing it, the bot detector skips already-seen commits
Comment on lines +85 to 90
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Use full paths consistently in reset steps 3-4.

In the same instruction block, steps 1-2 use explicit .aperant/github/... paths but steps 3-4 switch to relative names. Please make 3-4 explicit too to avoid targeting the wrong files.

Suggested doc patch
-3. Reset `pr/index.json` to `{"reviews": [], "last_updated": null}`
-4. Reset `bot_detection_state.json` to `{"reviewed_commits": {}}` — this is the gatekeeper; without clearing it, the bot detector skips already-seen commits
+3. Reset `.aperant/github/pr/index.json` to `{"reviews": [], "last_updated": null}`
+4. Reset `.aperant/github/bot_detection_state.json` to `{"reviewed_commits": {}}` — this is the gatekeeper; without clearing it, the bot detector skips already-seen commits
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
To fully clear all PR review data so reviews run fresh, delete/reset these three things in `.aperant/github/`:
1. `rm .auto-claude/github/pr/logs_*.json` — review log files
2. `rm .auto-claude/github/pr/review_*.json` — review result files
1. `rm .aperant/github/pr/logs_*.json` — review log files
2. `rm .aperant/github/pr/review_*.json` — review result files
3. Reset `pr/index.json` to `{"reviews": [], "last_updated": null}`
4. Reset `bot_detection_state.json` to `{"reviewed_commits": {}}` — this is the gatekeeper; without clearing it, the bot detector skips already-seen commits
To fully clear all PR review data so reviews run fresh, delete/reset these three things in `.aperant/github/`:
1. `rm .aperant/github/pr/logs_*.json` — review log files
2. `rm .aperant/github/pr/review_*.json` — review result files
3. Reset `.aperant/github/pr/index.json` to `{"reviews": [], "last_updated": null}`
4. Reset `.aperant/github/bot_detection_state.json` to `{"reviewed_commits": {}}` — this is the gatekeeper; without clearing it, the bot detector skips already-seen commits
🧰 Tools
🪛 LanguageTool

[uncategorized] ~85-~85: The official name of this software platform is spelled with a capital “H”.
Context: ...esh, delete/reset these three things in .aperant/github/: 1. `rm .aperant/github/pr/logs_*.js...

(GITHUB)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@CLAUDE.md` around lines 85 - 90, Update steps 3 and 4 to use the same
explicit path prefix as steps 1-2 so they target the correct files;
specifically, change references to `pr/index.json` and
`bot_detection_state.json` to `.aperant/github/pr/index.json` and
`.aperant/github/bot_detection_state.json` and show the exact reset contents
`{"reviews": [], "last_updated": null}` and `{"reviewed_commits": {}}`
respectively.


Expand Down Expand Up @@ -217,7 +217,7 @@ const readTool = tool({

### Spec Directory Structure

Each spec in `.auto-claude/specs/XXX-name/` contains: `spec.md`, `requirements.json`, `context.json`, `implementation_plan.json`, `qa_report.md`, `QA_FIX_REQUEST.md`
Each spec in `.aperant/specs/XXX-name/` contains: `spec.md`, `requirements.json`, `context.json`, `implementation_plan.json`, `qa_report.md`, `QA_FIX_REQUEST.md`

### Memory System (Graphiti)

Expand Down Expand Up @@ -355,5 +355,5 @@ npm run dev # Development mode with HMR
npm run dev:debug # Debug mode with verbose output
npm run dev:mcp # Electron MCP server for AI debugging

# Project data: .auto-claude/specs/ (gitignored)
# Project data: .aperant/specs/ (gitignored)
```
6 changes: 3 additions & 3 deletions apps/desktop/e2e/flows.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,9 +231,9 @@ test.describe('E2E Flow Verification (Mock-based)', () => {
const projectPath = TEST_PROJECT_DIR;
expect(existsSync(projectPath)).toBe(true);

// Check for auto-claude directory detection
const autoBuildPath = path.join(projectPath, 'auto-claude');
expect(existsSync(autoBuildPath)).toBe(true);
// Check for aperant directory detection
const aperantPath = path.join(projectPath, '.aperant');
expect(existsSync(aperantPath)).toBe(true);
Comment on lines +234 to +236
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Assertion cannot pass because fixture setup still creates auto-claude/ paths.

At Line 236, the .aperant existence check is correct for the rename, but this file still creates and writes test data under auto-claude/ (e.g., Line 25, Line 37, and other path joins). That makes this assertion deterministically fail (matches the pipeline error).

💡 Proposed fix (align all test fixtures/paths in this file to .aperant)
 function setupTestEnvironment(): void {
   TEST_DATA_DIR = mkdtempSync(path.join(os.tmpdir(), 'auto-claude-ui-e2e-'));
   TEST_PROJECT_DIR = path.join(TEST_DATA_DIR, 'test-project');
   mkdirSync(TEST_PROJECT_DIR, { recursive: true });
-  mkdirSync(path.join(TEST_PROJECT_DIR, 'auto-claude', 'specs'), { recursive: true });
+  mkdirSync(path.join(TEST_PROJECT_DIR, '.aperant', 'specs'), { recursive: true });
 }

 function createTestSpec(specId: string, status: 'pending' | 'in_progress' | 'completed' = 'pending'): void {
-  const specDir = path.join(TEST_PROJECT_DIR, 'auto-claude', 'specs', specId);
+  const specDir = path.join(TEST_PROJECT_DIR, '.aperant', 'specs', specId);
   mkdirSync(specDir, { recursive: true });
@@
-    const specDir = path.join(TEST_PROJECT_DIR, 'auto-claude', 'specs', '001-test-spec');
+    const specDir = path.join(TEST_PROJECT_DIR, '.aperant', 'specs', '001-test-spec');
@@
-    const specsDir = path.join(TEST_PROJECT_DIR, 'auto-claude', 'specs');
+    const specsDir = path.join(TEST_PROJECT_DIR, '.aperant', 'specs');
@@
-    const specDir = path.join(TEST_PROJECT_DIR, 'auto-claude', 'specs', specId);
+    const specDir = path.join(TEST_PROJECT_DIR, '.aperant', 'specs', specId);
@@
       TEST_PROJECT_DIR,
-      'auto-claude',
+      '.aperant',
       'specs',
       '001-task',
       'implementation_plan.json'
@@
       TEST_PROJECT_DIR,
-      'auto-claude',
+      '.aperant',
       'specs',
       '001-review',
       'qa_report.md'
@@
       TEST_PROJECT_DIR,
-      'auto-claude',
+      '.aperant',
       'specs',
       '001-reject',
       'QA_FIX_REQUEST.md'
🧰 Tools
🪛 GitHub Actions: E2E

[error] 236-236: E2E test failed: aperant directory detection assertion. Expected existsSync('.aperant') to be true but it was false.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/desktop/e2e/flows.e2e.ts` around lines 234 - 236, The assertion checking
for aperantPath (const aperantPath = path.join(projectPath, '.aperant')) fails
because test fixtures still create/write under "auto-claude/" paths; update all
fixture path joins and writes in this file (e.g., any occurrences that build
paths or write files for "auto-claude" around the top-level fixtures and helper
usages) to use ".aperant" instead so that existsSync(aperantPath) returns true;
search for string "auto-claude" and replace with ".aperant" in path.join and
file-write calls referenced by the flows.e2e.ts test so the fixture setup aligns
with the renamed directory.


cleanupTestEnvironment();
});
Expand Down
22 changes: 11 additions & 11 deletions apps/desktop/prompts/coder.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ You are continuing work on an autonomous development task. This is a **FRESH con
environment at the start of each prompt in the "YOUR ENVIRONMENT" section. Pay close attention to:

- **Working Directory**: This is your root - all paths are relative to here
- **Spec Location**: Where your spec files live (usually `./auto-claude/specs/{spec-name}/`)
- **Spec Location**: Where your spec files live (usually `./.aperant/specs/{spec-name}/`)
- **Isolation Mode**: If present, you are in an isolated worktree (see below)

**RULES:**
Expand Down Expand Up @@ -57,9 +57,9 @@ You may see absolute paths like `/e/projects/myapp/prod/src/file.ts` in:
```bash
# Verify you're still in the worktree
pwd
# Should show: .../.auto-claude/worktrees/tasks/{spec-name}/
# Should show: .../.aperant/worktrees/tasks/{spec-name}/
# Or (legacy): .../.worktrees/{spec-name}/
# Or (PR review): .../.auto-claude/github/pr/worktrees/{pr-number}/
# Or (PR review): .../.aperant/github/pr/worktrees/{pr-number}/
# NOT: /path/to/main/project
```

Expand Down Expand Up @@ -140,7 +140,7 @@ pwd && ls -la
find . -name "implementation_plan.json" -type f 2>/dev/null | head -5

# 3. Set SPEC_DIR based on what you find (example - adjust path as needed)
SPEC_DIR="./auto-claude/specs/YOUR-SPEC-NAME" # Replace with actual path from step 2
SPEC_DIR="./.aperant/specs/YOUR-SPEC-NAME" # Replace with actual path from step 2

# 4. Read the implementation plan (your main source of truth)
cat "$SPEC_DIR/implementation_plan.json"
Expand Down Expand Up @@ -791,7 +791,7 @@ The system **automatically scans for secrets** before every commit. If secrets a
api_key = os.environ.get("API_KEY")
```
3. **Update .env.example** - Add placeholder for the new variable
4. **Re-stage and retry** - `git add . ':!.auto-claude' && git commit ...`
4. **Re-stage and retry** - `git add . ':!.aperant' && git commit ...`

**If it's a false positive:**
- Add the file pattern to `.secretsignore` in the project root
Expand All @@ -803,22 +803,22 @@ The system **automatically scans for secrets** before every commit. If secrets a
# FIRST: Make sure you're in the working directory root (check YOUR ENVIRONMENT section at top)
pwd # Should match your working directory

# Add all files EXCEPT .auto-claude directory (spec files should never be committed)
git add . ':!.auto-claude'
# Add all files EXCEPT .aperant directory (spec files should never be committed)
git add . ':!.aperant'

# If git add fails with "pathspec did not match", you have a path problem:
# 1. Run pwd to see where you are
# 2. Run git status to see what git sees
# 3. Adjust your paths accordingly

git commit -m "auto-claude: Complete [subtask-id] - [subtask description]
git commit -m "aperant: Complete [subtask-id] - [subtask description]

- Files modified: [list]
- Verification: [type] - passed
- Phase progress: [X]/[Y] subtasks complete"
```

**CRITICAL**: The `:!.auto-claude` pathspec exclusion ensures spec files are NEVER committed.
**CRITICAL**: The `:!.aperant` pathspec exclusion ensures spec files are NEVER committed.
These are internal tracking files that must stay local.

### DO NOT Push to Remote
Expand Down Expand Up @@ -851,7 +851,7 @@ Next phase (if applicable): [phase-name]
=== END SESSION N ===
```

**Note:** The `build-progress.txt` file is in `.auto-claude/specs/` which is gitignored.
**Note:** The `build-progress.txt` file is in `.aperant/specs/` which is gitignored.
Do NOT try to commit it - the framework tracks progress automatically.

---
Expand Down Expand Up @@ -881,7 +881,7 @@ All subtasks completed!
Workflow type: [type]
Total phases: [N]
Total subtasks: [N]
Branch: auto-claude/[feature-name]
Branch: aperant/[feature-name]

Ready for human review and merge.
```
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/prompts/planner.md
Original file line number Diff line number Diff line change
Expand Up @@ -741,7 +741,7 @@ The following files are gitignored and should NOT be committed:
- `init.sh` - tracked locally only
- `build-progress.txt` - tracked locally only

These files live in `.auto-claude/specs/` which is gitignored. The orchestrator handles syncing them between worktrees and the main project.
These files live in `.aperant/specs/` which is gitignored. The orchestrator handles syncing them between worktrees and the main project.

**Only code changes should be committed** - spec metadata stays local.

Expand Down
16 changes: 8 additions & 8 deletions apps/desktop/prompts/qa_fixer.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ You are the **QA Fix Agent** in an autonomous development process. The QA Review
### NEVER edit qa_report.md
The `qa_report.md` file belongs to the QA Reviewer. You must NEVER modify it. The reviewer writes the verdict; you implement fixes. If you change the report status (e.g., to "FIXES_APPLIED"), the orchestrator won't recognize it as a valid verdict and your fixes will be wasted.

### Fix in the PROJECT SOURCE, not in .auto-claude/specs/
All your code changes, documentation additions, and new files must go into the **project source tree** (the actual codebase). Never create deliverable files inside `.auto-claude/specs/` — that directory contains gitignored metadata (spec, plan, QA report). The QA reviewer evaluates the project source, not spec artifacts.
### Fix in the PROJECT SOURCE, not in .aperant/specs/
All your code changes, documentation additions, and new files must go into the **project source tree** (the actual codebase). Never create deliverable files inside `.aperant/specs/` — that directory contains gitignored metadata (spec, plan, QA report). The QA reviewer evaluates the project source, not spec artifacts.

**Example:** If QA says "missing route inventory document", create it in the project root (e.g., `docs/route-policy.md` or `ROUTE_POLICY.md`), NOT in `.auto-claude/specs/route_access_policy.md`.
**Example:** If QA says "missing route inventory document", create it in the project root (e.g., `docs/route-policy.md` or `ROUTE_POLICY.md`), NOT in `.aperant/specs/route_access_policy.md`.

### Fix CODE issues with CODE, not documentation
If QA reports a missing test, write the test. If QA reports a code bug, fix the code. Don't write a markdown document explaining why the code is fine — write the code that makes it fine.
Expand Down Expand Up @@ -204,7 +204,7 @@ Escaping the worktree causes:
pwd

# 2. Verify the target is within your worktree
# If pwd shows: /path/to/.auto-claude/worktrees/tasks/spec-name/
# If pwd shows: /path/to/.aperant/worktrees/tasks/spec-name/
# Then: cd ./apps/desktop ✅ SAFE
# But: cd /path/to/parent/project ❌ FORBIDDEN - ESCAPES ISOLATION

Expand Down Expand Up @@ -338,8 +338,8 @@ ls -la [path-to-files] # Make sure the path is correct from your current locati
# FIRST: Make sure you're in the working directory root
pwd # Should match your working directory

# Add all files EXCEPT .auto-claude directory (spec files should never be committed)
git add . ':!.auto-claude'
# Add all files EXCEPT .aperant directory (spec files should never be committed)
git add . ':!.aperant'

# If git add fails with "pathspec did not match", you have a path problem:
# 1. Run pwd to see where you are
Expand All @@ -360,7 +360,7 @@ Verified:
QA Fix Session: [N]"
```

**CRITICAL**: The `:!.auto-claude` pathspec exclusion ensures spec files are NEVER committed.
**CRITICAL**: The `:!.aperant` pathspec exclusion ensures spec files are NEVER committed.

**NOTE**: Do NOT push to remote. All work stays local until user reviews and approves.

Expand Down Expand Up @@ -490,7 +490,7 @@ npx prisma migrate dev --name [name]

### Write Deliverables to the Project, Not Spec Artifacts
- All new files (docs, tests, code) go in the project source tree
- NEVER create deliverable files in `.auto-claude/specs/` — that directory is gitignored metadata
- NEVER create deliverable files in `.aperant/specs/` — that directory is gitignored metadata

### Git Configuration - NEVER MODIFY
**CRITICAL**: You MUST NOT modify git user configuration. Never run:
Expand Down
4 changes: 2 additions & 2 deletions apps/desktop/prompts/qa_reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ cat > qa_report.md << 'EOF'
[QA Report content]
EOF

# Note: qa_report.md and implementation_plan.json are in .auto-claude/specs/ (gitignored)
# Note: qa_report.md and implementation_plan.json are in .aperant/specs/ (gitignored)
# Do NOT commit them - the framework tracks QA status automatically
# Only commit actual code changes to the project
```
Expand Down Expand Up @@ -517,7 +517,7 @@ Once fixes are complete:

EOF

# Note: QA_FIX_REQUEST.md and implementation_plan.json are in .auto-claude/specs/ (gitignored)
# Note: QA_FIX_REQUEST.md and implementation_plan.json are in .aperant/specs/ (gitignored)
# Do NOT commit them - the framework tracks QA status automatically
# Only commit actual code fixes to the project
```
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src/__tests__/e2e/smoke.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ function setupTestDirs(): void {
TEST_PROJECT_PATH = path.join(TEST_DIR, 'test-project');
mkdirSync(TEST_PROJECT_PATH, { recursive: true });
// Create a minimal project structure
mkdirSync(path.join(TEST_PROJECT_PATH, '.auto-claude'), { recursive: true });
mkdirSync(path.join(TEST_PROJECT_PATH, '.aperant'), { recursive: true });
}

// Cleanup test directories
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ let PLAN_PATH: string;
// Setup test directories
function setupTestDirs(): void {
TEST_DIR = mkdtempSync(path.join(tmpdir(), 'rate-limit-recovery-test-'));
TEST_SPEC_DIR = path.join(TEST_DIR, '.auto-claude/specs/001-test-feature');
TEST_SPEC_DIR = path.join(TEST_DIR, '.aperant/specs/001-test-feature');
PLAN_PATH = path.join(TEST_SPEC_DIR, 'implementation_plan.json');
mkdirSync(TEST_SPEC_DIR, { recursive: true });
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ function setupTestDirs(): void {
// Create secure temp directory with random suffix
TEST_DIR = mkdtempSync(path.join(tmpdir(), 'task-lifecycle-test-'));
TEST_PROJECT_PATH = path.join(TEST_DIR, 'test-project');
TEST_SPEC_DIR = path.join(TEST_PROJECT_PATH, '.auto-claude/specs/001-test-feature');
TEST_SPEC_DIR = path.join(TEST_PROJECT_PATH, '.aperant/specs/001-test-feature');
mkdirSync(TEST_SPEC_DIR, { recursive: true });
}

Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src/__tests__/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ if (typeof global.requestAnimationFrame === 'undefined') {
}

// Test data directory for isolated file operations
export const TEST_DATA_DIR = '/tmp/auto-claude-ui-tests';
export const TEST_DATA_DIR = '/tmp/aperant-ui-tests';

// Create fresh test directory before each test
beforeEach(() => {
Expand Down
28 changes: 14 additions & 14 deletions apps/desktop/src/main/__tests__/file-watcher.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ describe('FileWatcher concurrency', () => {
// -------------------------------------------------------------------------
describe('deduplication: second watch() with same specDir is a no-op', () => {
it('should only create one FSWatcher when watch() is called twice with the same specDir while the first is still in-flight', async () => {
const specDir = '/project/.auto-claude/specs/001-task';
const specDir = '/project/.aperant/specs/001-task';
const taskId = 'task-1';

// To create a real async gap we need an existing watcher whose close() is slow.
Expand Down Expand Up @@ -111,8 +111,8 @@ describe('FileWatcher concurrency', () => {
describe('supersession: watch() with different specDir replaces the in-flight call', () => {
it('should let the second call win when the first is awaiting close()', async () => {
const taskId = 'task-2';
const specDir1 = path.join('/project', '.auto-claude', 'specs', '001-first');
const specDir2 = path.join('/project', '.auto-claude', 'specs', '002-second');
const specDir1 = path.join('/project', '.aperant', 'specs', '001-first');
const specDir2 = path.join('/project', '.aperant', 'specs', '002-second');

// First call installs an existing watcher (simulate: the watcher for
// specDir1 is already set up so the second watch() needs to close it).
Expand Down Expand Up @@ -148,8 +148,8 @@ describe('FileWatcher concurrency', () => {

it('first watch() bails when pendingWatches changes to a different specDir', async () => {
const taskId = 'task-super';
const specDir1 = path.join('/project', '.auto-claude', 'specs', 'super-first');
const specDir2 = path.join('/project', '.auto-claude', 'specs', 'super-second');
const specDir1 = path.join('/project', '.aperant', 'specs', 'super-first');
const specDir2 = path.join('/project', '.aperant', 'specs', 'super-second');

// Make the first watcher's close() slow so we can interleave.
let resolveFirstClose!: () => void;
Expand Down Expand Up @@ -187,7 +187,7 @@ describe('FileWatcher concurrency', () => {
describe('cancellation: unwatch() during in-flight watch() prevents watcher creation', () => {
it('should not create a watcher when unwatch() is called before the async gap resolves', async () => {
const taskId = 'task-3';
const specDir = '/project/.auto-claude/specs/003-cancel';
const specDir = '/project/.aperant/specs/003-cancel';

// There's no pre-existing watcher, so watch() won't call close(). But it
// does go async (chokidar.watch is sync but we can test the cancellation
Expand All @@ -207,7 +207,7 @@ describe('FileWatcher concurrency', () => {
);

// Start a second watch() — it will await the slow close().
const specDir2 = '/project/.auto-claude/specs/003-cancel-v2';
const specDir2 = '/project/.aperant/specs/003-cancel-v2';
const watchPromise = fw.watch(taskId, specDir2);

// While watch() is in-flight, call unwatch().
Expand All @@ -231,8 +231,8 @@ describe('FileWatcher concurrency', () => {
it('should cancel pending watch() calls and clear pendingWatches', async () => {
const taskId1 = 'task-4a';
const taskId2 = 'task-4b';
const specDir1 = '/project/.auto-claude/specs/004a';
const specDir2 = '/project/.auto-claude/specs/004b';
const specDir1 = '/project/.aperant/specs/004a';
const specDir2 = '/project/.aperant/specs/004b';

// Set up slow-close scenario for taskId1 (so watch() is in-flight).
await fw.watch(taskId1, specDir1);
Expand All @@ -243,7 +243,7 @@ describe('FileWatcher concurrency', () => {
);

// Start a new watch for taskId1 with a different specDir — this is now in-flight.
const newSpecDir1 = '/project/.auto-claude/specs/004a-v2';
const newSpecDir1 = '/project/.aperant/specs/004a-v2';
const watchPromise1 = fw.watch(taskId1, newSpecDir1);

// Start a fresh watch for taskId2.
Expand All @@ -262,7 +262,7 @@ describe('FileWatcher concurrency', () => {

// pendingWatches should be cleared (we verify indirectly: a fresh
// watch() call for taskId1 must succeed without treating it as a duplicate).
const specDirFresh = path.join('/project', '.auto-claude', 'specs', '004a-fresh');
const specDirFresh = path.join('/project', '.aperant', 'specs', '004a-fresh');
await fw.watch(taskId1, specDirFresh);
expect(fw.isWatching(taskId1)).toBe(true);
expect(fw.getWatchedSpecDir(taskId1)).toBe(specDirFresh);
Expand All @@ -275,7 +275,7 @@ describe('FileWatcher concurrency', () => {
describe('getWatchedSpecDir()', () => {
it('returns the specDir that was passed to watch()', async () => {
const taskId = 'task-5';
const specDir = path.join('/project', '.auto-claude', 'specs', '005-specdir');
const specDir = path.join('/project', '.aperant', 'specs', '005-specdir');

await fw.watch(taskId, specDir);

Expand All @@ -288,8 +288,8 @@ describe('FileWatcher concurrency', () => {

it('returns updated specDir after re-watch with different specDir', async () => {
const taskId = 'task-5b';
const specDir1 = path.join('/project', '.auto-claude', 'specs', '005b-first');
const specDir2 = path.join('/project', '.auto-claude', 'specs', '005b-second');
const specDir1 = path.join('/project', '.aperant', 'specs', '005b-first');
const specDir2 = path.join('/project', '.aperant', 'specs', '005b-second');

await fw.watch(taskId, specDir1);
expect(fw.getWatchedSpecDir(taskId)).toBe(specDir1);
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src/main/__tests__/insights-config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ describe('InsightsConfig', () => {

it('should build process env with profile settings', async () => {
const config = new InsightsConfig();
vi.spyOn(config, 'loadAutoBuildEnv').mockReturnValue({ CUSTOM_ENV: '1' });
vi.spyOn(config, 'loadAperantEnv').mockReturnValue({ CUSTOM_ENV: '1' });

const env = await config.getProcessEnv();

Expand Down
Loading
Loading