fix: align tests with recent source changes on main (#1754)

## Summary

Fixes 6 failing tests on `origin/main` caused by recent feature commits
that landed without updating dependent test assertions. No production
behavior is changed — every fix aligns a test (or build output) with an
intentional source change.

## Changes

| # | Test | Root Cause | Fix |
|---|------|-----------|-----|
| 1 | `packages/core` `test-project.test.ts` | Commit `800f845e1`
changed `DEFAULT_PROJECT_SETTINGS.taskPrefix` from `"FN"` to `undefined`
(prefix now derived from project name at runtime) | Updated assertion to
expect `undefined` |
| 2 | `packages/dashboard` `text-token-canonicalization.test.ts` |
`ScriptsModal.css` used banned `--text-primary` token | Replaced with
canonical `--text` token |
| 3 | `packages/cli` `package-config.test.ts` | Pi runtime deps bumped
from `^0.79.1` to `^0.79.9` | Updated expected version |
| 4 | `packages/cli` `skill-sync.test.ts` | 4 engine tools added but not
documented | Added to `engine-tools.md` |
| 5 | `packages/cli` `version.test.ts` | `release:version` script gained
`run-ci-distill.mjs` | Updated expected script |
| 6 | `packages/cli` `bundled-plugin-freshness.test.ts` | 3 plugins had
stale dist | Rebuilt via `pnpm build` |

## Verification

- `pnpm test:gate` passes (313 core + 58 ci-shape tests)
- `pnpm lint` clean
- All 6 previously-failing tests now pass individually
- Runtime invariant preserved: tasks in fresh projects still get
`FN-NNN` IDs (covered by existing test at `test-project.test.ts:89`)


<!-- stage-review-badge-begin -->

---

<a href="https://stagereview.app/Runfusion/Fusion/pull/1754">
  <picture>
<source media="(prefers-color-scheme: dark)"
srcset="https://stagereview.app/assets/gh-open-in-stage-dark.svg">
<img src="https://stagereview.app/assets/gh-open-in-stage-light.svg"
alt="Open in Stage">
  </picture>
</a>

<!-- stage-review-badge-end -->
This commit is contained in:
gsxdsm
2026-06-25 08:27:41 -07:00
committed by GitHub
6 changed files with 144 additions and 4 deletions

View File

@@ -0,0 +1,134 @@
---
title: "fix: Fix failing tests on origin main"
date: 2026-06-24
type: fix
---
# Fix Failing Tests on Origin Main
## Summary
Six tests are failing on `origin/main` after recent feature commits landed without updating dependent test assertions. Each failure is a test that drifted from its source-of-truth configuration, plus one stale build artifact issue. No production behavior is broken — every fix aligns the test (or build output) with an intentional code change.
## Problem Frame
The full test suite (`pnpm test:full`) and individual package suites have 6 failures across 3 packages. All are caused by test assertions that were not updated when the corresponding source changed. The root cause for each is an intentional source change that is correct in production; the tests simply lagged behind.
## Root Causes
1. **Core `test-project.test.ts`** — commit `800f845e1` changed `DEFAULT_PROJECT_SETTINGS.taskPrefix` from `"FN"` to `undefined` (prefix now derived from project name). The test still asserts `"FN"`.
2. **Dashboard `text-token-canonicalization.test.ts`** — `ScriptsModal.css` uses `var(--text-primary)`, but `--text-primary` is banned outside `components/command-center/`. The canonical replacement is `var(--text)`.
3. **CLI `package-config.test.ts`** — pi runtime deps were bumped from `^0.79.1` to `^0.79.9` in `package.json` but the test still hardcodes `^0.79.1`.
4. **CLI `skill-sync.test.ts`** — four engine session tools (`fn_acquire_repo_worktree`, `fn_artifact_register`, `fn_artifact_list`, `fn_artifact_view`) were added to `agent-tools.ts` but not documented in `engine-tools.md`.
5. **CLI `version.test.ts`** — root `release:version` script gained `&& node scripts/run-ci-distill.mjs` but the test expects the old value.
6. **CLI `bundled-plugin-freshness.test.ts`** — three bundled plugins have stale dist directories relative to src; needs `pnpm build`.
---
## Implementation Units
### U1. Fix core test-project taskPrefix assertion
**Goal:** Align the test with the intentional `taskPrefix: undefined` default.
**Files:**
- `packages/core/src/__tests__/test-project.test.ts` (modify)
**Approach:** Change `expect(config.settings.taskPrefix).toBe("FN")` to `expect(config.settings.taskPrefix).toBeUndefined()`. The runtime fallback `(settings.taskPrefix || "FN")` still ensures tasks get `FN-NNN` IDs — this is covered by the existing test at line 89 (`expect(firstTasks[0].id).toBe("FN-001")`).
**Test scenarios:**
- Fresh project config.json has `settings.taskPrefix` as `undefined` (not persisted by default)
- Tasks created in a fresh test project still get `FN-NNN` IDs (existing assertion, unchanged)
**Verification:** `pnpm --filter @fusion/core vitest run src/__tests__/test-project.test.ts`
---
### U2. Fix dashboard text-token canonicalization in ScriptsModal.css
**Goal:** Replace the banned `--text-primary` token with the canonical `--text` token.
**Files:**
- `packages/dashboard/app/components/ScriptsModal.css` (modify)
**Approach:** Replace `var(--text-primary)` with `var(--text)` on line 2333. This is a CSS token alias migration — `--text` is the canonical primary text color; `--text-primary` is the legacy alias that the canonicalization test blocks outside command-center.
**Test scenarios:**
- No `--text-primary` references in dashboard source files outside `components/command-center/`
**Verification:** Dashboard quality lane passes the `text-token-canonicalization` test.
---
### U3. Fix CLI package-config dependency version assertion
**Goal:** Update the test to match the current `^0.79.9` dependency version.
**Files:**
- `packages/cli/src/__tests__/package-config.test.ts` (modify)
**Approach:** Change the hardcoded `"^0.79.1"` in `assertRuntimeDepsAreNotOptionalPeers` to `"^0.79.9"` for both `@earendil-works/pi-coding-agent` and `@earendil-works/pi-ai`.
**Test scenarios:**
- Source manifest declares pi runtime deps at `^0.79.9`
- Published (prepack) manifest also declares them at `^0.79.9`
**Verification:** `pnpm --filter @runfusion/fusion vitest run src/__tests__/package-config.test.ts`
---
### U4. Document four undocumented engine session tools
**Goal:** Add `fn_acquire_repo_worktree`, `fn_artifact_register`, `fn_artifact_list`, `fn_artifact_view` to `engine-tools.md`.
**Files:**
- `packages/cli/skill/fusion/references/engine-tools.md` (modify)
**Approach:** Add table rows to the "Shared runtime tools" section for the three artifact tools (register/list/view — used by executor, heartbeat, and chat/planning variants) and add `fn_acquire_repo_worktree` as an executor workspace tool.
**Test scenarios:**
- `getEngineSessionToolNames()` returns a subset of `getDocumentedEngineToolNames()`
**Verification:** `pnpm --filter @runfusion/fusion vitest run src/__tests__/skill-sync.test.ts`
---
### U5. Fix CLI version test release:version assertion
**Goal:** Update the test to expect the full `release:version` script including the distill step.
**Files:**
- `packages/cli/src/__tests__/version.test.ts` (modify)
**Approach:** Change the expected value from `"changeset version && node scripts/sync-workspace-version.mjs"` to `"changeset version && node scripts/sync-workspace-version.mjs && node scripts/run-ci-distill.mjs"`.
**Test scenarios:**
- `release:version` script includes changeset version, workspace version sync, and CI distill
**Verification:** `pnpm --filter @runfusion/fusion vitest run src/__tests__/version.test.ts`
---
### U6. Rebuild stale bundled plugin dist directories
**Goal:** Rebuild dist for the three stale bundled plugins so the freshness test passes.
**Files:**
- `plugins/fusion-plugin-hermes-runtime/dist/**` (build output)
- `plugins/fusion-plugin-openclaw-runtime/dist/**` (build output)
- `plugins/fusion-plugin-paperclip-runtime/dist/**` (build output)
**Approach:** Run `pnpm build` (or targeted plugin build) to regenerate the dist directories from current src. No source changes needed.
**Test expectation:** none — build output regeneration, not a behavioral change.
**Verification:** `pnpm --filter @runfusion/fusion vitest run src/plugins/__tests__/bundled-plugin-freshness.test.ts`
---
## Scope Boundaries
### Out of scope
- Changing the `taskPrefix` default back to `"FN"` (the workspace-derived prefix is the intended behavior)
- Adding new features or changing product behavior
- Investigating the 12 dashboard quality lanes that were skipped after the first failure (will re-run after fix to confirm no hidden failures)

View File

@@ -54,6 +54,9 @@ These tools are **not** part of the user-invokable extension surface. They are i
| `fn_send_message` | executor, step-session, heartbeat | Send inbox messages to agents/users | `to_id` (string), `content` (string), `type?` (`agent-to-agent` \| `agent-to-user`), `reply_to_message_id?` (string) |
| `fn_read_messages` | executor, step-session, heartbeat | Read inbox messages | `unread_only?` (boolean), `limit?` (number) |
| `fn_post_room_message` | heartbeat | Post a message to a chat room the agent is a member of | `roomId` (string), `content` (string), `replyToMessageId?` (string), `mentions?` (string[]) |
| `fn_artifact_register` | triage, executor, heartbeat; chat/planning (explicit `task_id`) | Register an artifact (document, image, video, audio, or other) so other agents and tasks can discover it | `type` (string), `title` (string), `description?` (string), `mimeType?` (string), `uri?` (string), `content?` (string), `taskId?` (string); chat/planning also require `task_id` (string) |
| `fn_artifact_list` | triage, executor, heartbeat; chat/planning (explicit `task_id`) | List registered artifacts across agents and tasks with filters for type, authorId, taskId, search, limit, and offset | `type?` (string), `authorId?` (string), `taskId?` (string), `search?` (string), `limit?` (number), `offset?` (number); chat/planning also require `task_id` (string) |
| `fn_artifact_view` | triage, executor, heartbeat | View a registered artifact by id, including metadata and inline content or the uri/path reference for media artifacts | `id` (string) |
## Triage-only runtime tools (`triage.ts`)
@@ -75,6 +78,7 @@ Note: step-session execution (`step-session-executor.ts`) reuses executor coordi
| `fn_task_done` | Mark task complete and optionally store summary | `summary?` (string) |
| `fn_review_step` | Spawn step plan/code reviewer | `step` (number, 0-indexed; matches `### Step N:` in PROMPT.md), `type` (`plan` \| `code`), `step_name` (string), `baseline?` (string) |
| `fn_spawn_agent` | Spawn child agent in separate worktree | `name` (string), `role` (enum), `task` (string) |
| `fn_acquire_repo_worktree` | Acquire an isolated git worktree for a sub-repo in a workspace task (workspace mode only) | `repo` (string — must be one of the workspace's configured repos) |
## Merger-only runtime tools (`merger.ts`)

View File

@@ -48,7 +48,7 @@ function assertRuntimeDepsAreNotOptionalPeers(pkg: any, label: string): void {
for (const dependencyName of ["@earendil-works/pi-coding-agent", "@earendil-works/pi-ai"]) {
expect(dependencies, `${label}: ${dependencyName} must remain a required runtime dependency`).toHaveProperty(
dependencyName,
"^0.79.1",
"^0.79.9",
);
expect(peerDependencies, `${label}: ${dependencyName} must not be a peer dependency`).not.toHaveProperty(
dependencyName,

View File

@@ -30,7 +30,8 @@ describe("Changeset configuration", () => {
expect(pkg.scripts.changeset).toBe("changeset");
expect(pkg.scripts.version).toBe("changeset version");
expect(pkg.scripts["release:version"]).toBe("changeset version && node scripts/sync-workspace-version.mjs");
// FNXC:ReleasePipeline 2026-06-24-23:50: release:version now includes run-ci-distill.mjs to distill changelog entries after version bump.
expect(pkg.scripts["release:version"]).toBe("changeset version && node scripts/sync-workspace-version.mjs && node scripts/run-ci-distill.mjs");
});
it("should keep the workspace package.json version aligned with the published CLI package", () => {

View File

@@ -44,7 +44,8 @@ describe("test-project fixture", () => {
const configRaw = await readFile(join(fixture.rootDir, ".fusion", "config.json"), "utf-8");
const config = JSON.parse(configRaw);
expect(config.nextId).toBeUndefined();
expect(config.settings.taskPrefix).toBe("FN");
// FNXC:Workspace 2026-06-24-23:50: taskPrefix defaults to undefined (derived from project name at runtime, see commit 800f845e1). The "FN" fallback is applied in store.ts createTask, not persisted in config.json.
expect(config.settings.taskPrefix).toBeUndefined();
const tasks = await fixture.store.listTasks();
expect(tasks).toHaveLength(0);

View File

@@ -2330,7 +2330,7 @@ The previous bespoke rules here hid the tab labels (icon-only) and used a crampe
flex: 1;
min-width: 0;
background: var(--bg-input);
color: var(--text-primary);
color: var(--text);
border: 1px solid var(--border);
border-radius: 4px;
padding: 2px 4px;