@agentworkforce/cli 0.14.0 → 0.15.1

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 CHANGED
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.15.1] - 2026-05-08
11
+
10
12
  ### Added
11
13
 
12
14
  - `agentworkforce agent` now records launch metadata for direct harness
@@ -30,6 +32,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
30
32
  `--save-in-directory=<target>` (also accepted as
31
33
  `--save-in-directory <target>`). The old name is no longer recognized.
32
34
 
35
+ ## [0.15.0] - 2026-05-08
36
+
37
+ ### Released
38
+
39
+ - v0.15.0
40
+
33
41
  ## [0.14.0] - 2026-05-08
34
42
 
35
43
  ### Released
package/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # agentworkforce CLI
2
2
 
3
3
  A thin command-line front end for the workload-router. Spawns the harness CLI
4
- (`claude`, `codex`, `opencode`) configured by a selected **persona** either a
5
- built-in one from `/personas/`, or an installed/local one that extends a lower
6
- source.
4
+ (`claude`, `codex`, `opencode`) configured by a selected **persona** from the
5
+ project-local layer, configured source directories, or the small internal
6
+ built-in system catalog.
7
7
 
8
8
  ```
9
9
  agentworkforce create [--save-in-directory=<target>] [--save-default] [--install-in-repo] [--no-launch-metadata]
@@ -59,8 +59,9 @@ agentworkforce agent <persona>[@<tier>]
59
59
  1. A **cwd-local** id (files in `<cwd>/.agentworkforce/workforce/personas/*.json`)
60
60
  2. A configured persona source dir, in order. The default is
61
61
  `~/.agentworkforce/workforce/personas/*.json`.
62
- 3. A **library** persona — by intent first (e.g. `review`), then by id
63
- (e.g. `code-reviewer`)
62
+ 3. An internal **library** persona — by intent first, then by id. The built-in
63
+ library is system-only; optional personas such as `code-reviewer` come from
64
+ installed persona packs.
64
65
  - `<tier>` — `best` | `best-value` | `minimum`. Defaults to `best-value`.
65
66
 
66
67
  Unknown persona prints the full catalog with each entry's origin.
@@ -80,7 +81,7 @@ persona inputs:
80
81
  | Input | Meaning |
81
82
  | --- | --- |
82
83
  | `TARGET_DIR` | Absolute directory where the new `<id>.json` persona file should be written. |
83
- | `CREATE_MODE` | `local` writes only JSON; `built-in` also updates catalog/routing/test/docs integration. |
84
+ | `CREATE_MODE` | `local` writes only JSON; `built-in` is reserved for internal/system personas and also updates catalog/routing/test/docs integration. |
84
85
 
85
86
  Targets:
86
87
 
@@ -119,7 +120,7 @@ agentworkforce create --save-in-directory=dir:1
119
120
  # Create in an explicit checked-out persona directory and make that the default
120
121
  agentworkforce create --save-in-directory=../team-personas/personas --save-default
121
122
 
122
- # Create a built-in persona in this repo's /personas catalog
123
+ # Create an internal/system built-in persona in this repo's /personas catalog
123
124
  agentworkforce create --save-in-directory=library
124
125
  ```
125
126
 
@@ -129,13 +130,11 @@ agentworkforce create --save-in-directory=library
129
130
  agentworkforce create
130
131
 
131
132
  # Interactive code reviewer
132
- agentworkforce agent review@best-value
133
-
134
- # Interactive PostHog session (library persona, needs POSTHOG_API_KEY)
135
- agentworkforce agent posthog@best
133
+ agentworkforce install @agentworkforce/personas-core --persona code-reviewer
134
+ agentworkforce agent code-reviewer@best-value
136
135
 
137
136
  # Interactive against a local override
138
- agentworkforce agent my-posthog@best
137
+ agentworkforce agent my-reviewer@best
139
138
  ```
140
139
 
141
140
  ## Install persona packs
@@ -158,6 +157,8 @@ Npm package specs are resolved with `npm pack`, so npm auth, npm config,
158
157
  private packages, tags, and versions work the same way they do for npm:
159
158
 
160
159
  ```sh
160
+ agentworkforce install @agentworkforce/personas-core
161
+ agentworkforce install @agentworkforce/personas-core@0.8.0 --persona code-reviewer
161
162
  agentworkforce install @agentrelay/personas
162
163
  agentworkforce install @agentrelay/personas@1.2.3
163
164
  agentworkforce install @agentrelay/personas@latest
@@ -176,8 +177,8 @@ By default, every `*.json` file in the pack's persona directory is copied.
176
177
  Use repeated `--persona <id>` flags to install a subset by persona `id`:
177
178
 
178
179
  ```sh
180
+ agentworkforce install @agentworkforce/personas-core --persona code-reviewer
179
181
  agentworkforce install @agentrelay/personas --persona relay-orchestrator
180
- agentworkforce install @agentrelay/personas --persona relay-orchestrator --persona code-reviewer
181
182
  ```
182
183
 
183
184
  If any requested id is missing, the command exits non-zero before copying
@@ -209,19 +210,18 @@ basename if they are expected to be installed together.
209
210
  A pack can contain multiple personas:
210
211
 
211
212
  ```text
212
- @agentrelay/personas
213
+ @acme/personas
213
214
  ├── package.json
214
215
  └── personas/
215
- ├── relay-orchestrator.json
216
- ├── code-reviewer.json
217
- └── e2e-validator.json
216
+ ├── reviewer.json
217
+ └── release-runner.json
218
218
  ```
219
219
 
220
220
  `package.json` may declare the persona directory:
221
221
 
222
222
  ```json
223
223
  {
224
- "name": "@agentrelay/personas",
224
+ "name": "@acme/personas",
225
225
  "version": "1.2.3",
226
226
  "files": ["personas"],
227
227
  "keywords": ["agentworkforce-personas"],
@@ -427,7 +427,9 @@ MCP servers to attach*. Full library shape:
427
427
  }
428
428
  ```
429
429
 
430
- See `/personas/*.json` for all built-ins.
430
+ The repo built-in catalog is intentionally system-only and currently contains
431
+ `persona-maker`. Optional reusable personas are installed from packs such as
432
+ `@agentworkforce/personas-core` or `@agentrelay/personas`.
431
433
 
432
434
  ## Local personas & the cascade
433
435
 
@@ -437,7 +439,7 @@ wins):
437
439
  1. `<cwd>/.agentworkforce/workforce/personas/*.json` — **cwd**
438
440
  2. Configurable persona source dirs, in order. Default:
439
441
  `~/.agentworkforce/workforce/personas/*.json` — **user**
440
- 3. Built-in personas in `/personas/` — **library**
442
+ 3. Internal built-in system personas in `/personas/` — **library**
441
443
 
442
444
  Local files are **partial overlays**: only the fields you set replace the
443
445
  inherited value. Everything else cascades through from below.
@@ -446,56 +448,62 @@ Set `AGENT_WORKFORCE_HOME` to move the `~/.agentworkforce/workforce` config
446
448
  root. The legacy `AGENT_WORKFORCE_CONFIG_DIR` env var is still honored as a
447
449
  direct override for the default user persona directory.
448
450
 
449
- ### Minimal override: add your API key
451
+ ### Minimal override
452
+
453
+ Install the core pack first so `code-reviewer` exists in a lower layer:
454
+
455
+ ```sh
456
+ agentworkforce install @agentworkforce/personas-core --persona code-reviewer
457
+ ```
450
458
 
451
- `~/.agentworkforce/workforce/personas/my-posthog.json`:
459
+ `~/.agentworkforce/workforce/personas/my-reviewer.json`:
452
460
 
453
461
  ```json
454
462
  {
455
- "id": "my-posthog",
456
- "extends": "posthog",
457
- "env": { "POSTHOG_API_KEY": "$POSTHOG_API_KEY" }
463
+ "id": "my-reviewer",
464
+ "extends": "code-reviewer",
465
+ "systemPrompt": "Review this repository's API compatibility and migration risks. Lead with blockers."
458
466
  }
459
467
  ```
460
468
 
461
- That inherits every field from the library `posthog` persona, then layers your
462
- `env` on top. `agentworkforce agent my-posthog@best` now works as long as
463
- `POSTHOG_API_KEY` is exported in your shell.
469
+ That inherits every field from the installed `code-reviewer` persona, then
470
+ layers your local prompt on top.
464
471
 
465
472
  ### Same-id override (implicit extends)
466
473
 
467
474
  If your file's `id` matches a persona in a lower layer and you omit `extends`,
468
475
  the loader implicitly inherits from that same-id base:
469
476
 
470
- `<cwd>/.agentworkforce/workforce/personas/posthog.json`:
477
+ `<cwd>/.agentworkforce/workforce/personas/code-reviewer.json`:
471
478
 
472
479
  ```json
473
480
  {
474
- "id": "posthog",
475
- "env": { "POSTHOG_API_KEY": "$POSTHOG_API_KEY" }
481
+ "id": "code-reviewer",
482
+ "systemPrompt": "Review with this repository's compatibility checklist first."
476
483
  }
477
484
  ```
478
485
 
479
- Resolving `posthog` now hits this cwd override first; it inherits the rest
480
- (MCP, tiers, description, etc.) from the library `posthog`.
486
+ Resolving `code-reviewer` now hits this cwd override first; it inherits the
487
+ rest from the installed lower-layer `code-reviewer`.
481
488
 
482
489
  ### Cascade chain
483
490
 
484
- A cwd file can extend a user or configured-dir file, which extends the library:
491
+ A cwd file can extend a user or configured-dir file, which can extend an
492
+ installed pack persona or the internal library:
485
493
 
486
494
  ```
487
- ~/.agentworkforce/workforce/personas/ph-base.json:
488
- { "id": "ph-base", "extends": "posthog", "env": { "POSTHOG_ORG": "acme" } }
495
+ ~/.agentworkforce/workforce/personas/reviewer-base.json:
496
+ { "id": "reviewer-base", "extends": "code-reviewer", "systemPrompt": "Review with org-wide API compatibility rules." }
489
497
 
490
- <cwd>/.agentworkforce/workforce/personas/ph-prod.json:
491
- { "id": "ph-prod", "extends": "ph-base", "env": { "POSTHOG_API_KEY": "$PROD_KEY" } }
498
+ <cwd>/.agentworkforce/workforce/personas/reviewer-prod.json:
499
+ { "id": "reviewer-prod", "extends": "reviewer-base", "systemPrompt": "Add this service's migration checklist." }
492
500
  ```
493
501
 
494
- Resolving `ph-prod`:
502
+ Resolving `reviewer-prod`:
495
503
 
496
- - Start with library `posthog` (MCP, tiers, prompt, )
497
- - Layer user `ph-base` on top (adds `POSTHOG_ORG=acme`)
498
- - Layer cwd `ph-prod` on top (adds `POSTHOG_API_KEY`)
504
+ - Start with installed `code-reviewer` (tiers, skills, prompt, ...)
505
+ - Layer user `reviewer-base` on top
506
+ - Layer cwd `reviewer-prod` on top
499
507
 
500
508
  `extends` is resolved **strictly against lower layers** — cwd extends configured
501
509
  dirs or library, configured dirs extend lower configured dirs or library, and
@@ -506,7 +514,7 @@ library has no `extends`.
506
514
  ```jsonc
507
515
  {
508
516
  "id": "my-agent", // required
509
- "extends": "posthog", // optional; implicit same-id if omitted
517
+ "extends": "code-reviewer", // optional; implicit same-id if omitted
510
518
  "description": "…", // replaces base description
511
519
  "skills": [ … ], // replaces entire skills array
512
520
  "inputs": { // prompt-visible runtime inputs; union by key
@@ -572,7 +580,7 @@ Minimal local persona:
572
580
  ```json
573
581
  {
574
582
  "id": "my-reviewer",
575
- "extends": "review",
583
+ "extends": "code-reviewer",
576
584
  "description": "Reviews this project with local conventions.",
577
585
  "systemPrompt": "Focus on this repository's API compatibility rules and summarize only blocking issues."
578
586
  }
@@ -580,17 +588,18 @@ Minimal local persona:
580
588
 
581
589
  ### Built-in persona
582
590
 
583
- Built-in personas live in the repo's `/personas` catalog and require full
584
- workload-router integration:
591
+ Built-in personas live in the repo's `/personas` catalog, are reserved for
592
+ required internal/system surface, and require workload-router integration:
585
593
 
586
594
  ```sh
587
595
  agentworkforce create --save-in-directory=library
588
596
  ```
589
597
 
590
598
  The persona maker receives `CREATE_MODE=built-in`, so it should write
591
- `personas/<id>.json`, update the intent list/catalog registration/routing
592
- profile/test fixture/README, regenerate `src/generated/personas.ts`, and run
593
- the repo check.
599
+ `personas/<id>.json`, update the internal catalog registration/routing/tests/docs
600
+ as needed, regenerate `src/generated/personas.ts`, and run the repo check.
601
+ Optional generic or domain personas should be published through persona packs
602
+ instead.
594
603
 
595
604
  ### Full persona file
596
605
 
@@ -786,27 +795,56 @@ mount rules (`.agentignore` / `.agentreadonly`) for that.
786
795
  - **Tool patterns** are passed through verbatim; use the harness's native
787
796
  grammar. For Claude Code: `Bash(<pattern>)`, `mcp__<server>` (all tools
788
797
  from that server), `mcp__<server>__<tool>` (specific tool).
789
- - **Harness support today:** only `claude` is wired (flags: `--allowedTools`,
790
- `--disallowedTools`, `--permission-mode`). codex and opencode emit a
791
- warning and fall back to their defaults when `permissions` is set.
798
+ - **Harness support today:** only `claude` is wired for `permissions` (flags:
799
+ `--allowedTools`, `--disallowedTools`, `--permission-mode`). codex and
800
+ opencode emit a warning and fall back to their defaults when `permissions`
801
+ is set.
792
802
  - **Cascade merge:** `allow` and `deny` are unions across layers (deduped on
793
803
  merge); `mode` is replaced by the topmost layer that sets it. So the
794
804
  library can declare the minimum-viable allow list, a user or configured
795
805
  persona source can layer shared denies, and cwd can add per-project patterns
796
806
  — they all compose.
797
807
 
798
- ### Example: PostHog with auto-approve
808
+ ## Codex Sandbox Settings
809
+
810
+ Codex-backed tiers can set Codex launch policy inside `harnessSettings`:
811
+
812
+ ```jsonc
813
+ {
814
+ "tiers": {
815
+ "best": {
816
+ "harness": "codex",
817
+ "model": "openai-codex/gpt-5.3-codex",
818
+ "systemPrompt": "…",
819
+ "harnessSettings": {
820
+ "reasoning": "high",
821
+ "timeoutSeconds": 1200,
822
+ "sandboxMode": "workspace-write",
823
+ "approvalPolicy": "on-request",
824
+ "workspaceWriteNetworkAccess": true,
825
+ "webSearch": true
826
+ }
827
+ }
828
+ }
829
+ }
830
+ ```
831
+
832
+ `sandboxMode` maps to Codex `--sandbox` (`read-only`, `workspace-write`, or
833
+ `danger-full-access`), `approvalPolicy` maps to `--ask-for-approval`,
834
+ `workspaceWriteNetworkAccess` maps to
835
+ `-c sandbox_workspace_write.network_access=<bool>`, and `webSearch` maps to
836
+ `--search`. Prefer `workspace-write` plus `workspaceWriteNetworkAccess` for
837
+ package or registry discovery so filesystem writes stay sandboxed.
838
+
839
+ ### Example: narrowing inherited auto-approval
799
840
 
800
- The built-in `posthog` persona declares `permissions.allow = ["mcp__posthog"]`
801
- so that once you've authenticated (either by passing `POSTHOG_API_KEY` up
802
- front or via Claude's OAuth flow), subsequent analytics tool calls don't
803
- prompt. To narrow the auto-approval to read-only tools, override in a local
804
- persona:
841
+ If an installed lower-layer persona declares broad permissions, a local override
842
+ can add narrower tool patterns for project workflows:
805
843
 
806
844
  ```json
807
845
  {
808
- "id": "my-posthog",
809
- "extends": "posthog",
846
+ "id": "my-analytics",
847
+ "extends": "analytics-reader",
810
848
  "permissions": {
811
849
  "allow": [
812
850
  "mcp__posthog__projects-get",
@@ -817,10 +855,10 @@ persona:
817
855
  }
818
856
  ```
819
857
 
820
- Because `allow` is a union, the base's `"mcp__posthog"` would still be in the
821
- merged list. If you want to *shrink* the allow list in a local override,
822
- include a comment explaining why there's currently no "replace" knob, only
823
- union. (File an issue if you need one.)
858
+ Because `allow` is a union, any broad allow pattern from the base persona would
859
+ still be in the merged list. If you need to shrink an allow list, create a
860
+ standalone local persona or update the lower-layer pack persona; overlays only
861
+ append.
824
862
 
825
863
  ## MCP servers
826
864
 
@@ -909,12 +947,14 @@ cascade/extends merge and before prompt input substitution.
909
947
  Opt out for one launch:
910
948
 
911
949
  ```sh
950
+ agentworkforce install @agentworkforce/personas-core --persona code-reviewer
912
951
  agentworkforce agent --no-launch-metadata code-reviewer@best
913
952
  ```
914
953
 
915
954
  Opt out through the environment:
916
955
 
917
956
  ```sh
957
+ agentworkforce install @agentworkforce/personas-core --persona code-reviewer
918
958
  AGENTWORKFORCE_LAUNCH_METADATA=0 agentworkforce agent code-reviewer@best
919
959
  ```
920
960
 
@@ -962,6 +1002,7 @@ Pass `--install-in-repo` to fall back to the legacy behavior (skills land in
962
1002
  the repo's `.claude/skills/` directory, cleaned on exit):
963
1003
 
964
1004
  ```sh
1005
+ agentworkforce install @agentworkforce/personas-core --persona code-reviewer
965
1006
  agentworkforce agent --install-in-repo code-reviewer@best
966
1007
  ```
967
1008
 
@@ -1065,11 +1106,11 @@ agentworkforce CLI just wires the paths and passes the persona's argv.
1065
1106
  ### Example
1066
1107
 
1067
1108
  ```sh
1068
- # Interactive PostHog session with the repo's CLAUDE.md, .claude/, and
1109
+ # Interactive persona session with the repo's CLAUDE.md, .claude/, and
1069
1110
  # .mcp.json hidden — session sees the persona's staged skills plus your
1070
1111
  # user-level ~/.claude/CLAUDE.md, nothing else from this repo.
1071
- export POSTHOG_API_KEY=phx_…
1072
- agentworkforce agent posthog@best
1112
+ agentworkforce install @agentworkforce/personas-core --persona code-reviewer
1113
+ agentworkforce agent code-reviewer@best
1073
1114
  ```
1074
1115
 
1075
1116
  On exit: mount is synced back to the real repo, then torn down; skill
@@ -1077,9 +1118,7 @@ stage dir is cleaned up by the existing `rm -rf` cleanup command.
1077
1118
 
1078
1119
  ## Selecting a harness per tier
1079
1120
 
1080
- A persona's three tiers can use different harnesses. The built-in
1081
- `npm-provenance-publisher` has `best` on codex and `best-value` on opencode,
1082
- for example.
1121
+ A persona's three tiers can use different harnesses.
1083
1122
 
1084
1123
  If a persona uses MCP, keep every tier on `claude` — only the claude harness
1085
1124
  wires MCP at spawn time today.
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -5,7 +5,7 @@ import { appendFileSync, existsSync, mkdirSync, readFileSync, readSync, rmSync,
5
5
  import { constants, homedir } from 'node:os';
6
6
  import { dirname, isAbsolute, join, resolve as resolvePath } from 'node:path';
7
7
  import { pathToFileURL } from 'node:url';
8
- import { HARNESS_VALUES, PERSONA_TAGS, PERSONA_TIERS, personaCatalog, resolveSidecar, routingProfiles, useSelection } from '@agentworkforce/workload-router';
8
+ import { HARNESS_VALUES, PERSONA_TAGS, PERSONA_TIERS, listBuiltInPersonas, personaCatalog, resolveSidecar, routingProfiles, useSelection } from '@agentworkforce/workload-router';
9
9
  import { buildInteractiveSpec, detectHarnesses, formatDropWarnings, MissingPersonaInputError, renderPersonaInputs, resolvePersonaInputs, resolveMcpServersLenient, resolveStringMapLenient } from '@agentworkforce/harness-kit';
10
10
  import { launchOnMount, readAgentDotfiles } from '@relayfile/local-mount';
11
11
  import ora from 'ora';
@@ -117,11 +117,11 @@ configured persona dir is ~/.agentworkforce/workforce/personas.
117
117
  Examples:
118
118
  agentworkforce create
119
119
  agentworkforce create --save-in-directory=user
120
- agentworkforce agent npm-provenance-publisher@best
121
- agentworkforce agent my-posthog@best
122
- agentworkforce agent review@best-value
120
+ agentworkforce install @agentworkforce/personas-core --persona code-reviewer
121
+ agentworkforce agent code-reviewer@best-value
122
+ agentworkforce agent my-reviewer@best
123
123
  agentworkforce list
124
- agentworkforce show posthog
124
+ agentworkforce show code-reviewer
125
125
  agentworkforce install @agentrelay/personas --persona relay-orchestrator
126
126
  agentworkforce install ./local-personas --overwrite
127
127
  agentworkforce sources list
@@ -151,6 +151,44 @@ const local = loadLocalPersonas();
151
151
  for (const warning of local.warnings) {
152
152
  process.stderr.write(`warning: ${warning}\n`);
153
153
  }
154
+ function collectKnownPersonas() {
155
+ const byName = new Map();
156
+ for (const spec of local.byId.values()) {
157
+ byName.set(spec.id, {
158
+ name: spec.id,
159
+ description: spec.description
160
+ });
161
+ }
162
+ for (const spec of listBuiltInPersonas()) {
163
+ if (byName.has(spec.id))
164
+ continue;
165
+ byName.set(spec.id, {
166
+ name: spec.id,
167
+ description: spec.description
168
+ });
169
+ }
170
+ return [...byName.values()].sort((a, b) => a.name.localeCompare(b.name));
171
+ }
172
+ function formatNameDescriptionTable(rows) {
173
+ const headers = {
174
+ name: 'NAME',
175
+ description: 'DESCRIPTION'
176
+ };
177
+ const rendered = rows.map((r) => ({
178
+ name: r.name,
179
+ description: r.description.replace(/\s+/g, ' ').trim()
180
+ }));
181
+ const nameWidth = Math.max(headers.name.length, ...rendered.map((r) => r.name.length));
182
+ const termWidth = process.stderr.isTTY && typeof process.stderr.columns === 'number'
183
+ ? process.stderr.columns
184
+ : 120;
185
+ const descBudget = Math.max(headers.description.length, Math.max(32, termWidth - nameWidth - 3));
186
+ const truncate = (text) => text.length <= descBudget
187
+ ? text
188
+ : `${text.slice(0, Math.max(1, descBudget - 3)).trimEnd()}...`;
189
+ const line = (row) => `${row.name.padEnd(nameWidth)} | ${truncate(row.description)}`.trimEnd();
190
+ return [line(headers), ...rendered.map(line)].join('\n');
191
+ }
154
192
  function resolveSpec(key) {
155
193
  const localSpec = local.byId.get(key);
156
194
  if (localSpec)
@@ -158,18 +196,15 @@ function resolveSpec(key) {
158
196
  const catalogAsIntent = personaCatalog[key];
159
197
  if (catalogAsIntent)
160
198
  return catalogAsIntent;
161
- const byId = Object.values(personaCatalog).find((p) => p.id === key);
199
+ const byId = listBuiltInPersonas().find((p) => p.id === key);
162
200
  if (byId)
163
201
  return byId;
164
- const repoListing = Object.values(personaCatalog)
165
- .slice()
166
- .sort((a, b) => a.id.localeCompare(b.id))
167
- .map((p) => ` ${p.id} (intent: ${p.intent})`);
168
- const localListing = [...local.byId.values()]
169
- .sort((a, b) => a.id.localeCompare(b.id))
170
- .map((p) => ` ${p.id} (${local.sources.get(p.id) ?? 'local'})`);
171
- const listing = [...repoListing, ...localListing].join('\n');
172
- return { error: `Unknown persona "${key}". Known personas:\n${listing}` };
202
+ const packHint = 'Optional first-party personas are installed from packs, for example:\n' +
203
+ ' agentworkforce install @agentworkforce/personas-core\n' +
204
+ ' agentworkforce install @agentrelay/personas';
205
+ return {
206
+ error: `Unknown persona "${key}". Known personas:\n${formatNameDescriptionTable(collectKnownPersonas())}\n\n${packHint}`
207
+ };
173
208
  }
174
209
  function parseSelector(sel) {
175
210
  const at = sel.indexOf('@');
@@ -716,7 +751,7 @@ async function runInteractive(selection, options) {
716
751
  const resolvedMcp = mcpResolution.servers;
717
752
  // In session mode the install command is never `:` — it at minimum runs
718
753
  // the plugin scaffold (mkdir + manifest + symlink) so `--plugin-dir` has a
719
- // valid target even for skill-less personas like posthog. Gate on the
754
+ // valid target even for skill-less local personas. Gate on the
720
755
  // command string rather than `installs.length` so we don't skip that.
721
756
  const skillIds = install.plan.installs.map((i) => i.skillId).join(', ');
722
757
  const installLabel = install.plan.installs.length === 0
@@ -735,6 +770,7 @@ async function runInteractive(selection, options) {
735
770
  personaId,
736
771
  model: runtime.model,
737
772
  systemPrompt: runtime.systemPrompt,
773
+ harnessSettings: runtime.harnessSettings,
738
774
  mcpServers: resolvedMcp,
739
775
  permissions: effectiveSelection.permissions,
740
776
  ...(installRoot !== undefined ? { pluginDirs: [installRoot] } : {})
@@ -1341,7 +1377,7 @@ function collectPersonaRows() {
1341
1377
  pushSpec(spec, local.sources.get(id) ?? 'library');
1342
1378
  seen.add(id);
1343
1379
  }
1344
- for (const spec of Object.values(personaCatalog)) {
1380
+ for (const spec of listBuiltInPersonas()) {
1345
1381
  if (seen.has(spec.id))
1346
1382
  continue;
1347
1383
  pushSpec(spec, 'library');
@@ -1481,7 +1517,7 @@ function runList(args) {
1481
1517
  return false;
1482
1518
  if (applyRecommended) {
1483
1519
  const rule = recommendedByIntent[r.intent];
1484
- if (!rule || r.rating !== rule.tier)
1520
+ if (r.rating !== (rule?.tier ?? 'best-value'))
1485
1521
  return false;
1486
1522
  }
1487
1523
  return true;
@@ -1555,7 +1591,7 @@ function resolveShowTarget(selector, all) {
1555
1591
  spec = byIntent;
1556
1592
  }
1557
1593
  else {
1558
- const byId = Object.values(personaCatalog).find((p) => p.id === key);
1594
+ const byId = listBuiltInPersonas().find((p) => p.id === key);
1559
1595
  if (byId)
1560
1596
  spec = byId;
1561
1597
  }
@@ -1689,6 +1725,18 @@ function formatPersonaShow(spec, source, tiers, tierNote) {
1689
1725
  lines.push(` model: ${rt.model}`);
1690
1726
  lines.push(` reasoning: ${rt.harnessSettings.reasoning}`);
1691
1727
  lines.push(` timeout: ${rt.harnessSettings.timeoutSeconds}s`);
1728
+ if (rt.harnessSettings.sandboxMode) {
1729
+ lines.push(` sandbox: ${rt.harnessSettings.sandboxMode}`);
1730
+ }
1731
+ if (rt.harnessSettings.approvalPolicy) {
1732
+ lines.push(` approvals: ${rt.harnessSettings.approvalPolicy}`);
1733
+ }
1734
+ if (rt.harnessSettings.workspaceWriteNetworkAccess !== undefined) {
1735
+ lines.push(` network: ${rt.harnessSettings.workspaceWriteNetworkAccess}`);
1736
+ }
1737
+ if (rt.harnessSettings.webSearch !== undefined) {
1738
+ lines.push(` webSearch: ${rt.harnessSettings.webSearch}`);
1739
+ }
1692
1740
  lines.push(' systemPrompt:');
1693
1741
  lines.push(indent(rt.systemPrompt, ' '));
1694
1742
  }
@@ -1813,7 +1861,7 @@ async function runAgentSelector(selector, flags, inputValues) {
1813
1861
  */
1814
1862
  export function buildPickCandidates() {
1815
1863
  const byId = new Map();
1816
- for (const spec of Object.values(personaCatalog)) {
1864
+ for (const spec of listBuiltInPersonas()) {
1817
1865
  byId.set(spec.id, {
1818
1866
  id: spec.id,
1819
1867
  intent: spec.intent,