## Summary
First wave of package-internal code organization: split oversized
modules into domain-named files/folders while preserving public import
paths via re-exports, and refresh the line-count ratchet scoreboard.
- **Plan:**
`docs/plans/2026-07-14-001-refactor-package-code-organization-plan.md`
(multi-wave program; this PR lands U1–U4 + first U3/U6 slices)
- **Core types:** peel `types.ts` into
`types/{board,merge-queue,execution-and-ui,merge-policy,workflow-steps}.ts`
with browser-safe Vite alias preserved
- **Core TaskStore:** rename `remaining-ops-9` →
`task-commit-associations` (domain-named, not ordinal dump)
- **Engine executor:** peel pure helpers into
`executor/{browser-probe,requeue-loop,pseudo-pause,workflow-step-failures}.ts`
- **Engine heartbeat:** peel system prompts/procedures into
`agent-heartbeat-prompts.ts`
- **Ratchet:** one-time baseline truth-up + ratchet-down for touched
files
### Deferred to follow-up PRs (plan U5, U7–U9 + remaining waves)
- Self-healing folder split
- Further remaining-ops domain peels
- Dashboard `legacy.ts` / routes / UI monofiles
- CLI extension + TUI peels
## Test plan
- [x] `pnpm --filter @fusion/core exec tsc --noEmit`
- [x] `pnpm --filter @fusion/engine exec tsc --noEmit`
- [x] Focused vitest: `detect-pseudo-pause`,
`executor-browser-verification`, `clear-terminal-workflow-step-failures`
- [x] `node scripts/check-file-line-count.mjs` clean against updated
baseline
- [ ] CI merge gate (lint/typecheck/build/gate)
- [ ] Browser smoke: N/A for this PR (no dashboard UI route changes)
## Residual Review Findings
None. Review autofix applied dual-home wiring for
`clearTerminalWorkflowStepFailures` only.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added configurable heartbeat procedures for task and no-task scenarios
(including patrol-aware rendering).
* Improved agent-browser availability verification with clearer
availability/status reporting.
* Added detection for pseudo-pauses and review-handoff requests.
* Expanded core configuration/contract options for
execution/UI/localization, merges, merge queues, and workflow steps.
* **Bug Fixes**
* Improved handling of transient execute-requeue and workflow-step
retry/cleanup behavior, including better Windows path support.
* Preserved existing public interfaces during internal restructuring.
* **Documentation**
* Added a multi-phase roadmap for future package reorganization.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
46 lines
1.9 KiB
TypeScript
46 lines
1.9 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { TaskDeletedError } from "@fusion/core";
|
|
import { isTransientMissingTaskJsonError } from "../executor.js";
|
|
|
|
describe("isTransientMissingTaskJsonError", () => {
|
|
const task = {
|
|
id: "FN-5624",
|
|
worktree: "/tmp/worktrees/fn-5624",
|
|
};
|
|
|
|
it("matches ENOENT on worktree-scoped .fusion/tasks/<id>/task.json", () => {
|
|
const err = `ENOENT: no such file or directory, open '/tmp/worktrees/fn-5624/.fusion/tasks/FN-5624/task.json'`;
|
|
expect(isTransientMissingTaskJsonError(err, task)).toBe(true);
|
|
});
|
|
|
|
it("matches Windows worktree paths with backslash separators", () => {
|
|
const windowsTask = {
|
|
id: "FN-5624",
|
|
worktree: "C:\\worktrees\\fn-5624",
|
|
};
|
|
const err = "ENOENT: no such file or directory, open 'C:\\worktrees\\fn-5624\\.fusion\\tasks\\FN-5624\\task.json'";
|
|
|
|
expect(isTransientMissingTaskJsonError(err, windowsTask)).toBe(true);
|
|
});
|
|
|
|
it("does not treat a sibling worktree with the same prefix as contained", () => {
|
|
const err = "ENOENT: no such file or directory, open '/tmp/worktrees/fn-5624-copy/.fusion/tasks/FN-5624/task.json'";
|
|
|
|
expect(isTransientMissingTaskJsonError(err, task)).toBe(false);
|
|
});
|
|
|
|
it("does not match task.json parse failures", () => {
|
|
const err = "Failed to parse task.json at /tmp/worktrees/fn-5624/.fusion/tasks/FN-5624/task.json: Unexpected token";
|
|
expect(isTransientMissingTaskJsonError(err, task)).toBe(false);
|
|
});
|
|
|
|
it("does not match TaskDeletedError", () => {
|
|
expect(isTransientMissingTaskJsonError(new TaskDeletedError("FN-5624", new Date().toISOString()), task)).toBe(false);
|
|
});
|
|
|
|
it("does not match ENOENT for non-task.json paths", () => {
|
|
const err = `ENOENT: no such file or directory, open '/tmp/worktrees/fn-5624/.fusion/tasks/FN-5624/PROMPT.md'`;
|
|
expect(isTransientMissingTaskJsonError(err, task)).toBe(false);
|
|
});
|
|
});
|