@agentworkforce/cli 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@agentworkforce/cli` will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
package/README.md CHANGED
@@ -6,11 +6,17 @@ built-in one from `/personas/`, or a user-local one that extends a built-in.
6
6
 
7
7
  ```
8
8
  agent-workforce agent <persona>[@<tier>] [task...]
9
+ agent-workforce list [flags]
10
+ agent-workforce harness check
9
11
  ```
10
12
 
11
- - No `task` drops you into an interactive session with the harness.
12
- - `task...` given runs one-shot (via `usePersona().sendMessage()`) and streams
13
- output to stdout/stderr.
13
+ - `agent` — no `task` drops you into an interactive session with the harness;
14
+ a `task...` argument runs one-shot (via `usePersona().sendMessage()`) and
15
+ streams output to stdout/stderr.
16
+ - `list` — print the persona catalog as a table (or JSON). See
17
+ [`## List`](#list) below for every flag.
18
+ - `harness check` — probe which harnesses (`claude`, `codex`, `opencode`)
19
+ are installed. See [`## Harness check`](#harness-check) below.
14
20
 
15
21
  ## Install
16
22
 
@@ -53,6 +59,67 @@ agent-workforce agent posthog@best
53
59
  agent-workforce agent my-posthog@best
54
60
  ```
55
61
 
62
+ ## List
63
+
64
+ ```
65
+ agent-workforce list [flags]
66
+ ```
67
+
68
+ Prints the merged persona catalog — everything the `agent` subcommand would
69
+ accept as a selector — including cascade source (`library`, `home`, `pwd`),
70
+ harness, model, description, and tier ("rating"). One row per persona-tier
71
+ combination; by default only the **recommended tier per intent** is shown
72
+ (as declared in
73
+ `packages/workload-router/routing-profiles/default.json`).
74
+
75
+ ### Flags
76
+
77
+ | Flag | Default | Effect |
78
+ | --- | --- | --- |
79
+ | `--all` | off | Show every tier of every persona. Alias: `--no-recommended`. |
80
+ | `--recommended` | on | Only show the recommended tier per intent. Implicit default; mostly useful for undoing `--all` earlier in a wrapper script. |
81
+ | `--filter-rating <tier>` | — | Restrict to a single tier (`best` \| `best-value` \| `minimum`). **Implicitly turns off the recommended-only default**, so filtering by `best` shows every persona's `best` row even when that's not the recommended tier. |
82
+ | `--filter-harness <harness>` | — | Restrict to a single harness (`claude` \| `codex` \| `opencode`). Composable with `--filter-rating` and `--all`. |
83
+ | `--no-display-description` | off | Hide the `DESCRIPTION` column. `--display-description` re-enables it. |
84
+ | `--json` | off | Emit `{ "personas": [...] }` with one object per row. Same field set as the table, useful for scripting. |
85
+ | `-h`, `--help` | — | Print a one-line usage string and exit. |
86
+
87
+ Invalid values for `--filter-rating` / `--filter-harness` fail fast and list
88
+ the allowed values.
89
+
90
+ ### Examples
91
+
92
+ ```sh
93
+ # Default: one row per persona, recommended tier only
94
+ agent-workforce list
95
+
96
+ # See every tier
97
+ agent-workforce list --all
98
+
99
+ # Only the top tier across the catalog — independent of recommendations
100
+ agent-workforce list --filter-rating best
101
+
102
+ # All claude-harness personas (any tier)
103
+ agent-workforce list --all --filter-harness claude
104
+
105
+ # Compact table for a narrow terminal
106
+ agent-workforce list --no-display-description
107
+
108
+ # Machine-readable
109
+ agent-workforce list --json --filter-harness claude
110
+ ```
111
+
112
+ ## Harness check
113
+
114
+ ```
115
+ agent-workforce harness check
116
+ ```
117
+
118
+ Probes your PATH for each supported harness binary (`claude`, `codex`,
119
+ `opencode`) and prints a table with status (`ok` / `missing`), resolved
120
+ version, and the resolved path (or the error, for missing ones). Exit
121
+ code is always `0` — this command is diagnostic, not a gate.
122
+
56
123
  ## Personas
57
124
 
58
125
  A persona is a JSON object describing *what harness runs, which model, with
@@ -313,22 +380,34 @@ persona session, add it to the persona's `mcpServers` block.
313
380
  ### Interactive
314
381
 
315
382
  ```sh
316
- agent-workforce agent <persona>[@<tier>]
383
+ agent-workforce agent [--install-in-repo] [--clean] <persona>[@<tier>]
317
384
  ```
318
385
 
386
+ `--install-in-repo` and `--clean` are mutually exclusive — see
387
+ [**Clean mode**](#clean-mode) below.
388
+
319
389
  1. Resolves the persona, walks the cascade, resolves `$VAR` refs.
320
- 2. Runs skill install (`prpm install …`) if the persona declares any skills.
321
- 3. Execs the harness binary with stdio inherited:
390
+ 2. **Stages skills outside the repo by default** (claude interactive only
391
+ see **Skill staging** below). For codex / opencode, or when
392
+ `--install-in-repo` is passed, falls back to the legacy repo-relative
393
+ install path (`.claude/skills/`, `.agents/skills/`, `.skills/`).
394
+ 3. Runs skill install (`prpm install …`) if the persona declares any skills,
395
+ using the computed target (stage dir or repo).
396
+ 4. Execs the harness binary with stdio inherited:
322
397
  - `claude`: `claude --model <model> --append-system-prompt <prompt>
323
- --mcp-config '<json>' --strict-mcp-config`. Both flags are always passed
324
- so the session only sees the persona's declared MCP servers — see
325
- **MCP isolation** above.
398
+ --mcp-config '<json>' --strict-mcp-config [--plugin-dir <stage>]`. The
399
+ `--plugin-dir` flag is appended when the session uses out-of-repo
400
+ staging so Claude Code loads exactly the staged skills — and nothing
401
+ the repo happens to carry. Both MCP flags are always passed so the
402
+ session only sees the persona's declared MCP servers (see **MCP
403
+ isolation** above).
326
404
  - `codex`: `codex -m <model>` with the system prompt as the initial
327
405
  positional `[PROMPT]`. (codex has no `--system-prompt` flag today.)
328
406
  - `opencode`: `opencode --model <model>` with the system prompt as the
329
407
  initial argument.
330
- 4. Runs the skill cleanup command on exit, regardless of exit status.
331
- 5. Propagates the harness's exit code.
408
+ 5. Runs the skill cleanup command on exit, regardless of exit status. In
409
+ stage-dir mode this is a single `rm -rf <stage-dir>`.
410
+ 6. Propagates the harness's exit code.
332
411
 
333
412
  Signals (SIGINT, SIGTERM) are forwarded to the child.
334
413
 
@@ -347,6 +426,154 @@ Env from the persona is passed through via `ExecuteOptions.env`. `mcpServers`
347
426
  is currently **ignored with a warning** in one-shot mode — the SDK workflow
348
427
  path doesn't thread MCP config yet.
349
428
 
429
+ One-shot mode still installs into the repo regardless of `--install-in-repo`;
430
+ out-of-repo staging only applies to the interactive path today because the
431
+ agent-relay workflow SDK doesn't yet thread `--plugin-dir` into the claude
432
+ agent adapter. `--install-in-repo` passed to a one-shot run prints a `note:`
433
+ and is a no-op.
434
+
435
+ ## Skill staging
436
+
437
+ By default, interactive `claude` sessions stage skills under the user's home
438
+ directory instead of the current repo. Nothing gets written to `.claude/` in
439
+ the working tree, and the session only sees the skills the persona declares
440
+ — never whatever skills the repo happens to carry on disk.
441
+
442
+ **Layout:**
443
+
444
+ ```
445
+ ~/.agent-workforce/
446
+ └── sessions/<personaId>-<timestamp>-<rand>/
447
+ └── claude/
448
+ └── plugin/ ← passed as --plugin-dir
449
+ ├── .claude-plugin/plugin.json ← generated scaffold
450
+ ├── skills → .claude/skills ← relative symlink
451
+ └── .claude/skills/<name>/SKILL.md ← prpm install output
452
+ ```
453
+
454
+ - **Stage dir** — `~/.agent-workforce/sessions/<id>/claude/plugin/`.
455
+ `<id>` is `<personaId>-<base36-timestamp>-<hex-random>` so parallel
456
+ sessions never collide.
457
+ - **Plugin wrapper** — the CLI writes a minimal `.claude-plugin/plugin.json`
458
+ (`{"name":"agent-workforce-session","version":"0.0.0",…}`) and a relative
459
+ symlink `skills → .claude/skills` so Claude Code's plugin layout
460
+ (`skills/<name>/SKILL.md`) resolves to prpm's actual output
461
+ (`.claude/skills/<name>/SKILL.md`) without moving any files.
462
+ - **prpm install** — still runs `npx -y prpm install <ref> --as claude`,
463
+ but inside `cd <stage-dir>` so the harness-conventional `.claude/skills/`
464
+ lands in the stage dir, not the repo.
465
+ - **Cleanup** — on exit, two cleanup scopes run. The workload-router removes
466
+ `<stage-dir>` (e.g. `.../sessions/<id>/claude/plugin/`) via its generated
467
+ `rm -rf` command. The CLI additionally removes the enclosing session root
468
+ (`.../sessions/<id>/`) so the mount dir and any empty parents don't
469
+ accumulate under `~/.agent-workforce/sessions/`. The provider lockfile
470
+ (`prpm.lock`) is inside the stage dir and goes with it — no repeat-run
471
+ resolution cache today. Restart cost is one prpm install per session.
472
+
473
+ **Opt-out — `--install-in-repo`:**
474
+
475
+ Pass `--install-in-repo` to fall back to the legacy behavior (skills land in
476
+ the repo's `.claude/skills/` directory, cleaned on exit):
477
+
478
+ ```sh
479
+ agent-workforce agent --install-in-repo code-reviewer@best
480
+ ```
481
+
482
+ Useful when you want to inspect the installed skills on disk, or when the
483
+ stage dir conflicts with something else (network filesystem, read-only
484
+ `$HOME`, etc.).
485
+
486
+ **Caveats for V1:**
487
+
488
+ - **Claude harness only.** codex and opencode continue to install into their
489
+ conventional repo-relative directories. The SDK throws if `installRoot` is
490
+ passed with a non-claude harness.
491
+ - **No cache layer yet.** Every interactive session runs a fresh prpm install
492
+ into a new stage dir. A `~/.agent-workforce/cache/` content-addressed cache
493
+ is planned but not wired up.
494
+ - **One-shot path unchanged.** See the paragraph under "One-shot" above.
495
+
496
+ ## Clean mode
497
+
498
+ `--clean` launches an interactive claude session inside a
499
+ [`@relayfile/local-mount`](https://www.npmjs.com/package/@relayfile/local-mount)
500
+ symlink mount that hides the repo's Claude Code configuration from the
501
+ session — so the model sees persona context + user-level context, and
502
+ nothing the repo itself declares.
503
+
504
+ ```sh
505
+ agent-workforce agent --clean <persona>[@<tier>]
506
+ ```
507
+
508
+ **What's hidden (gitignore semantics, at any depth):**
509
+
510
+ | Pattern | Rationale |
511
+ | --- | --- |
512
+ | `CLAUDE.md` | Repo-level project memory |
513
+ | `CLAUDE.local.md` | Developer-local project memory |
514
+ | `.claude` | Repo Claude Code config dir (settings, agents, skills, commands) |
515
+ | `.mcp.json` | Repo-declared MCP servers |
516
+
517
+ **What's preserved:**
518
+
519
+ - **User-level context** under `~/.claude/` — `CLAUDE.md`, skills, etc.
520
+ still load. `--clean` scrubs the *project*, not the user. To exclude
521
+ user-level context too, launch under a scratch `$HOME`.
522
+ - **Persona skills.** The `--plugin-dir` passed to claude resolves to an
523
+ absolute path *outside* the mount, so staged skills from
524
+ `~/.agent-workforce/sessions/<id>/claude/plugin/` load normally.
525
+ - **Keychain auth.** `--clean` does NOT pass `--bare`; it only hides
526
+ files via the mount. Claude Code's macOS keychain login stays active.
527
+ - **Persona `mcpServers`.** Still passed via `--mcp-config` — unaffected
528
+ by the mount. The repo's `.mcp.json` is hidden regardless.
529
+
530
+ ### Session layout
531
+
532
+ Both the skill install root and the clean mount live under a single
533
+ session directory. The session id (`<personaId>-<base36-timestamp>-<hex>`)
534
+ is generated once and both paths are derived from it:
535
+
536
+ ```
537
+ ~/.agent-workforce/
538
+ └── sessions/<personaId>-<timestamp>-<rand>/
539
+ ├── claude/
540
+ │ └── plugin/ ← passed as --plugin-dir
541
+ │ ├── .claude-plugin/plugin.json
542
+ │ ├── skills → .claude/skills
543
+ │ └── .claude/skills/<name>/SKILL.md
544
+ └── mount/ ← --clean: claude's cwd
545
+ └── <mirrored project tree, minus the hidden patterns>
546
+ ```
547
+
548
+ `@relayfile/local-mount` handles mount creation, process spawn,
549
+ SIGINT/SIGTERM forwarding, write syncback, and cleanup on exit. The
550
+ agent-workforce CLI just wires the paths and passes the persona's argv.
551
+
552
+ ### Interactions with other flags
553
+
554
+ - **`--clean` + `--install-in-repo` is rejected** — they ask for
555
+ incompatible things. `--install-in-repo` stages skills into the real
556
+ repo's `.claude/skills/`; `--clean` hides the real repo. Pick one.
557
+ - **`--clean` on codex/opencode is a warning no-op.** Only the claude
558
+ harness gets the mount (it's the only one whose native surface includes
559
+ the hidden patterns).
560
+ - **`--clean` on a one-shot run is a warning no-op.** The agent-relay
561
+ workflow SDK doesn't thread mount integration today; matches how
562
+ `--install-in-repo` behaves in one-shot mode.
563
+
564
+ ### Example
565
+
566
+ ```sh
567
+ # Interactive PostHog session with the repo's CLAUDE.md, .claude/, and
568
+ # .mcp.json hidden — session sees the persona's staged skills plus your
569
+ # user-level ~/.claude/CLAUDE.md, nothing else from this repo.
570
+ export POSTHOG_API_KEY=phx_…
571
+ agent-workforce agent --clean posthog@best
572
+ ```
573
+
574
+ On exit: mount is synced back to the real repo, then torn down; skill
575
+ stage dir is cleaned up by the existing `rm -rf` cleanup command.
576
+
350
577
  ## Selecting a harness per tier
351
578
 
352
579
  A persona's three tiers can use different harnesses. The built-in
package/dist/cli.d.ts CHANGED
@@ -1,3 +1,26 @@
1
1
  #!/usr/bin/env node
2
- export {};
2
+ import { type Harness } from '@agentworkforce/workload-router';
3
+ /** Patterns hidden from an interactive claude session when `--clean` is set.
4
+ * Applied by `@relayfile/local-mount` with gitignore semantics, so bare names
5
+ * match at any depth in the project tree (e.g. `.claude` hides both
6
+ * `./.claude/` and `./packages/foo/.claude/`). */
7
+ export declare const CLEAN_IGNORED_PATTERNS: readonly ["CLAUDE.md", "CLAUDE.local.md", ".claude", ".mcp.json"];
8
+ /**
9
+ * Decide whether `--clean` should engage for this run. Returns a warning
10
+ * string when the flag was requested but cannot apply (e.g. non-claude
11
+ * harness); callers emit the warning to stderr and proceed with
12
+ * `useClean: false`. Pure — no side effects, trivially testable.
13
+ */
14
+ export declare function decideCleanMode(harness: Harness, clean: boolean): {
15
+ useClean: boolean;
16
+ warning?: string;
17
+ };
18
+ export interface AgentFlags {
19
+ installInRepo: boolean;
20
+ clean: boolean;
21
+ }
22
+ export declare function parseAgentArgs(args: readonly string[]): {
23
+ flags: AgentFlags;
24
+ positional: string[];
25
+ };
3
26
  //# sourceMappingURL=cli.d.ts.map
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAOA,OAAO,EAOL,KAAK,OAAO,EAMb,MAAM,iCAAiC,CAAC;AA8OzC;;;kDAGkD;AAClD,eAAO,MAAM,sBAAsB,mEAKzB,CAAC;AAEX;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,OAAO,GACb;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CASzC;AAidD,MAAM,WAAW,UAAU;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG;IACvD,KAAK,EAAE,UAAU,CAAC;IAClB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAmCA"}