Skip to content

persona-kit: add parse/mount/sidecars/skills test suites (#70)#81

Merged
willwashburn merged 2 commits into
mainfrom
claude/resolve-github-issue-qVEU0
May 11, 2026
Merged

persona-kit: add parse/mount/sidecars/skills test suites (#70)#81
willwashburn merged 2 commits into
mainfrom
claude/resolve-github-issue-qVEU0

Conversation

@willwashburn
Copy link
Copy Markdown
Member

Summary

Partial completion of #70. The issue lists eight test files. The code on main already covers the cross-harness round-trips, env-binding precedence, JSON serialization, mount-policy threading, sidecar resolution, and the skill-install spawn / cleanup contract via the existing plan.test.ts, execute.test.ts, index.test.ts, inputs.test.ts, interactive-spec.test.ts, and env-refs.test.ts. This PR adds the four file-scoped suites the issue called out by name that were still missing from packages/persona-kit/src/.

  • parse.test.ts — schema validation for parsePersonaSpec and the helpers it delegates to (parseHarnessSettings, parseInputs, parsePermissions, parseMount, parseMcpServers, parseTags, parseSkills, etc.). Includes the issue's specific contracts: malformed tiers throws with a precise field path, malformed skills[i].source does not throw at parse time (deferred to plan time), input names must match [A-Z_][A-Z0-9_]*, and optional: true cannot be combined with default.
  • mount.test.tsapplyPersonaMount no-op path (undefined policy) plus the two error paths for a declared policy missing mountDir or personaId. The @relayfile/local-mount-backed branch is exercised end-to-end by the workforce CLI smoke test ([persona-kit 4/8] Migrate workforce CLI to use @agentworkforce/persona-kit #67) and is intentionally not unit-tested here, matching the issue's "mock in unit tests; real integration in CLI smoke" guidance.
  • sidecars.test.ts — extend-vs-overwrite restore semantics, sourcePath absoluteness check, LIFO dispose, and a buildPersonaSpawnPlanwritePersonaSidecars round-trip on a path-backed sidecar.
  • skills.test.tscleanupOnDispose true/false coverage for both per-install cleanupPaths and the session-install-root path, plus the empty-plan no-op path.

What was deliberately not added

  • load.test.tspersona-kit does not export a loadPersonas cascade today; the cascade lives in the workforce CLI, which is out of scope for this package's test suite.
  • Cross-harness fixture JSON files + snapshot tests — the existing plan.test.ts already iterates ['claude', 'codex', 'opencode'] and asserts the per-harness behavior the snapshots would freeze. Adding redundant fixture JSON would inflate the suite without catching anything the explicit tests don't already.
  • Property tests (fast-check) — flagged "optional but valuable" in the issue; skipped to avoid pulling a new dev dep into the package for marginal additional coverage.

These can be addressed in a follow-up PR if the team wants the fixture-bound snapshots and property-test layer; the existing assertions cover the same surface area imperatively.

Test plan

  • pnpm --filter @agentworkforce/persona-kit test — 119/119 pass locally
  • pnpm --filter @agentworkforce/persona-kit typecheck
  • pnpm --filter @agentworkforce/persona-kit lint
  • CI green on PR

Closes #70 (in part — leaving the issue open is fine if the team wants the fixture/property-test layer separately).

https://claude.ai/code/session_01UPVSZTvpB4yq4CFWD36Uwy


Generated by Claude Code

Closes #70 in part. The existing tests in execute.test.ts, plan.test.ts and
index.test.ts already cover the cross-harness round-trips and skill
materialization paths called out in the issue; this commit fills in the four
file-scoped suites the issue listed by name and were still missing.

- parse.test.ts: schema validation for parsePersonaSpec and the helpers it
  delegates to (parseHarnessSettings, parseInputs, parsePermissions,
  parseMount, parseMcpServers, parseTags, parseSkills, etc.). Covers the
  malformed-tier field-path message, the deferred-source contract for
  parseSkills (typos do not throw at parse time), the env-var input-name
  rule, and the optional+default conflict.
- mount.test.ts: applyPersonaMount no-op path (undefined policy) plus the
  two error paths for a declared policy missing mountDir or personaId.
  The relayfile-backed branch is exercised end-to-end by the workforce
  CLI smoke test (#67) and is intentionally not unit-tested here.
- sidecars.test.ts: extend-vs-overwrite restore semantics, sourcePath
  absoluteness check, LIFO dispose, and a buildPersonaSpawnPlan ->
  writePersonaSidecars round-trip on a path-backed sidecar.
- skills.test.ts: cleanupOnDispose true/false for both per-install
  cleanupPaths and the session-install-root path, plus the empty-plan
  no-op path.

All 119 tests in @agentworkforce/persona-kit pass locally.

https://claude.ai/code/session_01UPVSZTvpB4yq4CFWD36Uwy
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 11, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

Adds four Node.js test suites for persona-kit covering parsing/validation, mount policy application, sidecar file writing, and skill installation, including happy paths, error cases, and dispose/cleanup behaviors.

Changes

Persona-Kit Test Coverage

Layer / File(s) Summary
Schema Parsing & Validation
packages/persona-kit/src/parse.test.ts
Tests for parsePersonaSpec and validators. Verifies minimal-spec acceptance, unknown-field stripping, precise error messages for intent/tier/skill/permission/input mismatches, deferred validation of malformed skill sources, and sidecar path rules.
Mount Policy Application
packages/persona-kit/src/mount.test.ts
Tests for applyPersonaMount. Verifies undefined policy returns a no-op handle preserving cwd, the no-op path short-circuits validation, and declared policies missing mountDir or personaId reject with clear error messages.
Sidecar Writing & Disposal
packages/persona-kit/src/sidecars.test.ts
Tests for writePersonaSidecars and integration with buildPersonaSpawnPlan. Covers extend and overwrite modes with restoration on dispose(), new-file creation and cleanup, sourcePath absolute validation, LIFO disposal ordering, and an integration round-trip writing/removing disk-backed markdown.
Skill Installation & Cleanup
packages/persona-kit/src/skills.test.ts
Tests for runSkillInstalls. Verifies empty plans are no-ops, cleanupOnDispose controls artifact removal, sessionInstallRoot scaffolds .claude-plugin/plugin.json and is cleaned or preserved based on the flag, and dispose() is idempotent.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • AgentWorkforce/workforce#46 — Tests exercise sidecar markdown materialization and mount/write helpers related to that PR.
  • AgentWorkforce/workforce#74 — These tests validate behaviors (applyPersonaMount, writePersonaSidecars, runSkillInstalls, parse helpers) targeted by that PR.
  • AgentWorkforce/workforce#73 — Overlapping test coverage for parsing/mount/sidecar/skill functions introduced or moved in that PR.

Poem

🐰 A rabbit hops through test-lined fields,
Writes parse, mount, sidecars, skills with glee;
Each dispose folds the traces away,
Temp files vanish, assertions stay,
Hopping home — the suite is green and free.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically identifies the main change: adding four named test suites (parse/mount/sidecars/skills) to persona-kit, with the issue reference (#70) providing clear context.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, detailing each test suite added, what was deliberately omitted, and the test plan status.
Linked Issues check ✅ Passed The PR adds parse.test.ts, mount.test.ts, sidecars.test.ts, and skills.test.ts as specified in #70, covering schema validation, mount behavior, sidecar restore semantics, and skill cleanup—meeting the core coding requirements from the linked issue.
Out of Scope Changes check ✅ Passed All changes are focused on adding the four specified test files; no unrelated code modifications or out-of-scope changes detected beyond the explicitly scoped test suite additions.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/resolve-github-issue-qVEU0

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 3 additional findings.

Open in Devin Review

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/persona-kit/src/sidecars.test.ts`:
- Around line 99-115: The test currently only checks both files are removed and
doesn't prove LIFO; change it to use the same filename with dependent writes so
wrong order is detectable: create an initial file with content 'original', call
writePersonaSidecars twice for the same filename (e.g. 'CLAUDE.md') with
contents 'first' then 'second' (mode: 'overwrite'), assert the file now contains
'second', then call handle.dispose() and assert the file content was restored to
'original' (use writePersonaSidecars and handle.dispose to locate where to
change the test).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ba04d4f6-78ea-4e7d-a1fa-adb8ef4acfdd

📥 Commits

Reviewing files that changed from the base of the PR and between 81ea6d7 and d974dcf.

📒 Files selected for processing (4)
  • packages/persona-kit/src/mount.test.ts
  • packages/persona-kit/src/parse.test.ts
  • packages/persona-kit/src/sidecars.test.ts
  • packages/persona-kit/src/skills.test.ts

Comment thread packages/persona-kit/src/sidecars.test.ts Outdated
The previous test wrote two different filenames and asserted both were
removed on dispose — FIFO would have passed too. Switch to two writes
to the same filename in one call, with the file pre-seeded as
"original". Only LIFO dispose restores back through "first" to
"original"; FIFO would leave the file at "first".

Addresses CodeRabbit review feedback on PR #81.

https://claude.ai/code/session_01UPVSZTvpB4yq4CFWD36Uwy
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/persona-kit/src/sidecars.test.ts (1)

133-133: ⚡ Quick win

Avoid brittle positional assertion on sidecars.

Line 133 assumes a stable array order (plan.sidecars[0]). Prefer asserting membership so the test remains stable if ordering changes but behavior is still correct.

Suggested change
-    assert.equal(plan.sidecars[0]?.sourcePath, sourcePath);
+    assert.equal(
+      plan.sidecars.some((s) => s.sourcePath === sourcePath && s.filename === 'CLAUDE.md'),
+      true
+    );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/persona-kit/src/sidecars.test.ts` at line 133, The test currently
uses a brittle positional assertion assert.equal(plan.sidecars[0]?.sourcePath,
sourcePath); — change it to assert membership instead: verify that plan.sidecars
contains an entry whose sourcePath equals sourcePath (e.g., use
Array.prototype.some or find on plan.sidecars to assert presence). Update the
assertion in sidecars.test.ts to check that plan.sidecars.some(s => s.sourcePath
=== sourcePath) (or assert.ok(find) / assert.exists) so the test passes
regardless of array ordering while still validating the expected sidecar exists.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/persona-kit/src/sidecars.test.ts`:
- Line 133: The test currently uses a brittle positional assertion
assert.equal(plan.sidecars[0]?.sourcePath, sourcePath); — change it to assert
membership instead: verify that plan.sidecars contains an entry whose sourcePath
equals sourcePath (e.g., use Array.prototype.some or find on plan.sidecars to
assert presence). Update the assertion in sidecars.test.ts to check that
plan.sidecars.some(s => s.sourcePath === sourcePath) (or assert.ok(find) /
assert.exists) so the test passes regardless of array ordering while still
validating the expected sidecar exists.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9df68912-de0e-4acd-a478-1785ce3092e9

📥 Commits

Reviewing files that changed from the base of the PR and between d974dcf and 3608719.

📒 Files selected for processing (1)
  • packages/persona-kit/src/sidecars.test.ts

@willwashburn willwashburn merged commit a5e8df9 into main May 11, 2026
2 checks passed
@willwashburn willwashburn deleted the claude/resolve-github-issue-qVEU0 branch May 11, 2026 03:30
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.

[persona-kit 7/8] Comprehensive test suite for @agentworkforce/persona-kit

2 participants