@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 +8 -0
- package/README.md +109 -70
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +68 -20
- package/dist/cli.js.map +1 -1
- package/dist/cli.test.js +126 -33
- package/dist/cli.test.js.map +1 -1
- package/dist/local-personas.d.ts +4 -2
- package/dist/local-personas.d.ts.map +1 -1
- package/dist/local-personas.js +129 -26
- package/dist/local-personas.js.map +1 -1
- package/dist/local-personas.test.js +292 -54
- package/dist/local-personas.test.js.map +1 -1
- package/package.json +4 -4
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**
|
|
5
|
-
|
|
6
|
-
|
|
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.
|
|
63
|
-
|
|
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
|
|
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
|
|
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-
|
|
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
|
-
@
|
|
213
|
+
@acme/personas
|
|
213
214
|
├── package.json
|
|
214
215
|
└── personas/
|
|
215
|
-
├──
|
|
216
|
-
|
|
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": "@
|
|
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
|
-
|
|
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.
|
|
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
|
|
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-
|
|
459
|
+
`~/.agentworkforce/workforce/personas/my-reviewer.json`:
|
|
452
460
|
|
|
453
461
|
```json
|
|
454
462
|
{
|
|
455
|
-
"id": "my-
|
|
456
|
-
"extends": "
|
|
457
|
-
"
|
|
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
|
|
462
|
-
|
|
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/
|
|
477
|
+
`<cwd>/.agentworkforce/workforce/personas/code-reviewer.json`:
|
|
471
478
|
|
|
472
479
|
```json
|
|
473
480
|
{
|
|
474
|
-
"id": "
|
|
475
|
-
"
|
|
481
|
+
"id": "code-reviewer",
|
|
482
|
+
"systemPrompt": "Review with this repository's compatibility checklist first."
|
|
476
483
|
}
|
|
477
484
|
```
|
|
478
485
|
|
|
479
|
-
Resolving `
|
|
480
|
-
|
|
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
|
|
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/
|
|
488
|
-
{ "id": "
|
|
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/
|
|
491
|
-
{ "id": "
|
|
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 `
|
|
502
|
+
Resolving `reviewer-prod`:
|
|
495
503
|
|
|
496
|
-
- Start with
|
|
497
|
-
- Layer user `
|
|
498
|
-
- Layer cwd `
|
|
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": "
|
|
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": "
|
|
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
|
|
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
|
|
592
|
-
|
|
593
|
-
|
|
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:
|
|
790
|
-
`--disallowedTools`, `--permission-mode`). codex and
|
|
791
|
-
warning and fall back to their defaults when `permissions`
|
|
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
|
-
|
|
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
|
-
|
|
801
|
-
|
|
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-
|
|
809
|
-
"extends": "
|
|
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,
|
|
821
|
-
merged list. If you
|
|
822
|
-
|
|
823
|
-
|
|
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
|
|
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
|
-
|
|
1072
|
-
agentworkforce agent
|
|
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.
|
|
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":";AAiBA,OAAO,
|
|
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
|
|
121
|
-
agentworkforce agent
|
|
122
|
-
agentworkforce agent
|
|
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
|
|
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 =
|
|
199
|
+
const byId = listBuiltInPersonas().find((p) => p.id === key);
|
|
162
200
|
if (byId)
|
|
163
201
|
return byId;
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
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
|
|
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
|
|
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 (
|
|
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 =
|
|
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
|
|
1864
|
+
for (const spec of listBuiltInPersonas()) {
|
|
1817
1865
|
byId.set(spec.id, {
|
|
1818
1866
|
id: spec.id,
|
|
1819
1867
|
intent: spec.intent,
|