Part of the persona-kit consolidation. Depends on #66. This is issue 4 of 8.
Goal
Rewrite packages/cli/ to consume @agentworkforce/persona-kit's top-level orchestration API (buildPersonaSpawnPlan + executePersonaSpawnPlan) instead of the imperative skills/mount/sidecar/input wiring it has today. CLI becomes a thin shell over persona-kit.
After this PR, the CLI's spawn flow reads top-to-bottom:
const loaded = loadPersonas({ cwd, searchDirs });
const spec = loaded.byId.get(personaId);
const persona = resolvePersonaTier(spec, tier);
const plan = buildPersonaSpawnPlan(persona, { cwd, installRoot, envOverrides });
const handle = await executePersonaSpawnPlan(plan, { cwd });
try {
const child = childProcess.spawn(plan.cli, plan.args, { cwd, env: plan.env, stdio: 'inherit' });
await waitForExit(child);
} finally {
await handle.dispose();
}
Everything fancy that's currently in cli.ts (sidecar resolution, mount apply, skills install, input rendering, configfile materialization) is now persona-kit's job.
Files to touch
packages/cli/src/local-personas.ts
- Delete inline persona-loading logic; import
loadPersonas and resolvePersonaTier from @agentworkforce/persona-kit instead.
- Keep CLI-specific concerns: persona-picker UX, override-merging UX (printing what got overridden, etc.), warnings collection.
- The cascade-search-dirs configuration stays here (CLI knows about
$AGENT_WORKFORCE_HOME etc.); pass the resolved dirs into persona-kit's loadPersonas.
packages/cli/src/cli.ts
- Replace the inline skills install loop with a call to
executePersonaSpawnPlan (or runSkillInstalls if the CLI wants its own orchestration for progress UX — pick one and stick with it; default to the top-level executor).
- Replace inline sidecar writes with persona-kit's
writePersonaSidecars.
- Replace inline mount apply with persona-kit's
applyPersonaMount.
- Replace inline
buildInteractiveSpec calls with buildPersonaSpawnPlan (which composes them).
- Replace inline input env-binding with
plan.env.
- The CLI keeps: argv parsing (commander/yargs/whatever),
agentworkforce subcommands, persona-picker prompts, session recording, routing-profile lookup (still imported from @agentworkforce/workload-router).
- Drop direct imports of
@agentworkforce/harness-kit — everything is via persona-kit now.
Other CLI files
- grep for any other
@agentworkforce/harness-kit or persona-symbol imports from @agentworkforce/workload-router and rewire to persona-kit.
packages/cli/package.json
- Add
@agentworkforce/persona-kit as a workspace dep.
- Drop
@agentworkforce/harness-kit (workload-router still needed for routing profiles + persona catalog).
Tasks
Tests / Smoke checks
Constraints
- No user-visible UX regressions. If something looked, sounded, or smelled different to a CLI user before/after this PR, that's a bug.
- harness-kit is still in the monorepo (gets deleted in 6/8). The CLI should not import from it after this PR; the package itself stays.
- workload-router still exists and the CLI still imports
personaCatalog and routing types from it. Don't touch those imports.
Verification
Reference
Plan section 1.4.
Part of the persona-kit consolidation. Depends on #66. This is issue 4 of 8.
Goal
Rewrite
packages/cli/to consume@agentworkforce/persona-kit's top-level orchestration API (buildPersonaSpawnPlan+executePersonaSpawnPlan) instead of the imperative skills/mount/sidecar/input wiring it has today. CLI becomes a thin shell over persona-kit.After this PR, the CLI's spawn flow reads top-to-bottom:
Everything fancy that's currently in
cli.ts(sidecar resolution, mount apply, skills install, input rendering, configfile materialization) is now persona-kit's job.Files to touch
packages/cli/src/local-personas.tsloadPersonasandresolvePersonaTierfrom@agentworkforce/persona-kitinstead.$AGENT_WORKFORCE_HOMEetc.); pass the resolved dirs into persona-kit'sloadPersonas.packages/cli/src/cli.tsexecutePersonaSpawnPlan(orrunSkillInstallsif the CLI wants its own orchestration for progress UX — pick one and stick with it; default to the top-level executor).writePersonaSidecars.applyPersonaMount.buildInteractiveSpeccalls withbuildPersonaSpawnPlan(which composes them).plan.env.agentworkforcesubcommands, persona-picker prompts, session recording, routing-profile lookup (still imported from@agentworkforce/workload-router).@agentworkforce/harness-kit— everything is via persona-kit now.Other CLI files
@agentworkforce/harness-kitor persona-symbol imports from@agentworkforce/workload-routerand rewire to persona-kit.packages/cli/package.json@agentworkforce/persona-kitas a workspace dep.@agentworkforce/harness-kit(workload-router still needed for routing profiles + persona catalog).Tasks
local-personas.tsto delegate toloadPersonas+resolvePersonaTier.cli.tsto usebuildPersonaSpawnPlan+executePersonaSpawnPlan.onProgress?: (event: ProgressEvent) => voidoption onExecuteOptionsand add it in this PR. Document the event shape.)@agentworkforce/harness-kitimports insidepackages/cli/; remove all.Tests / Smoke checks
pnpm --filter @agentworkforce/cli testpasses.agentworkforce <persona-id>for a persona that exercises every field (skills, mount, claudeMdContent, inputs) — actually run it interactively against:npx skills addcommands run, same files written, same harness argv.executePersonaSpawnPlan(...).dispose()(called via the CLI's exit handler) leaves the cwd in the same state it was in before the run — no.claude/skills/<name>/directories, no half-written sidecars.Constraints
personaCatalogand routing types from it. Don't touch those imports.Verification
pnpm -r buildandpnpm -r testpass.agentworkforceagainst fixture personas pass.@agentworkforce/harness-kitinsidepackages/cli/returns zero hits.Reference
Plan section 1.4.