@agentworkforce/cli 0.9.0 → 0.11.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 +15 -0
- package/README.md +80 -13
- package/dist/cli.d.ts +46 -3
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +218 -19
- package/dist/cli.js.map +1 -1
- package/dist/cli.test.js +181 -7
- package/dist/cli.test.js.map +1 -1
- package/dist/launch-metadata.d.ts +53 -0
- package/dist/launch-metadata.d.ts.map +1 -0
- package/dist/launch-metadata.js +192 -0
- package/dist/launch-metadata.js.map +1 -0
- package/dist/launch-metadata.test.d.ts +2 -0
- package/dist/launch-metadata.test.d.ts.map +1 -0
- package/dist/launch-metadata.test.js +152 -0
- package/dist/launch-metadata.test.js.map +1 -0
- package/dist/local-personas.d.ts +30 -1
- package/dist/local-personas.d.ts.map +1 -1
- package/dist/local-personas.js +247 -15
- package/dist/local-personas.js.map +1 -1
- package/dist/local-personas.test.js +228 -1
- package/dist/local-personas.test.js.map +1 -1
- package/dist/persona-install.d.ts.map +1 -1
- package/dist/persona-install.js +105 -7
- package/dist/persona-install.js.map +1 -1
- package/dist/persona-install.test.js +43 -0
- package/dist/persona-install.test.js.map +1 -1
- package/package.json +4 -3
package/dist/cli.js
CHANGED
|
@@ -5,10 +5,11 @@ import { appendFileSync, existsSync, mkdirSync, readFileSync, rmSync, statSync,
|
|
|
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, routingProfiles, useSelection } from '@agentworkforce/workload-router';
|
|
8
|
+
import { HARNESS_VALUES, PERSONA_TAGS, PERSONA_TIERS, personaCatalog, resolveSidecar, routingProfiles, useSelection } from '@agentworkforce/workload-router';
|
|
9
9
|
import { buildInteractiveSpec, detectHarnesses, formatDropWarnings, MissingPersonaInputError, renderPersonaInputs, resolvePersonaInputs, resolveMcpServersLenient, resolveStringMapLenient } from '@agentworkforce/harness-kit';
|
|
10
|
-
import { launchOnMount } from '@relayfile/local-mount';
|
|
10
|
+
import { launchOnMount, readAgentDotfiles } from '@relayfile/local-mount';
|
|
11
11
|
import ora from 'ora';
|
|
12
|
+
import { startLaunchMetadataRecording } from './launch-metadata.js';
|
|
12
13
|
import { buildPersonaSourceDirectories, defaultCwdPersonaDir, loadLocalPersonas, loadPersonaSourceConfig, normalizePersonaDir, savePersonaSourceConfig } from './local-personas.js';
|
|
13
14
|
import { installPersonas } from './persona-install.js';
|
|
14
15
|
const USAGE = `Usage: agentworkforce <command> [args...]
|
|
@@ -26,6 +27,8 @@ Commands:
|
|
|
26
27
|
--save-default Persist --to as defaultCreateTarget in
|
|
27
28
|
~/.agentworkforce/workforce/config.json.
|
|
28
29
|
--install-in-repo Same behavior as agent.
|
|
30
|
+
--no-launch-metadata
|
|
31
|
+
Same behavior as agent.
|
|
29
32
|
agent [flags] <persona>[@<tier>]
|
|
30
33
|
Run a persona. Tier one of: ${PERSONA_TIERS.join(' | ')}
|
|
31
34
|
(default: best-value). Drops into an interactive harness
|
|
@@ -46,6 +49,10 @@ Commands:
|
|
|
46
49
|
are hidden from the session. Codex
|
|
47
50
|
sessions never mount and ignore
|
|
48
51
|
this flag.
|
|
52
|
+
--no-launch-metadata
|
|
53
|
+
Disable launch metadata recording.
|
|
54
|
+
Also disabled by
|
|
55
|
+
AGENTWORKFORCE_LAUNCH_METADATA=0.
|
|
49
56
|
list [flags] List available personas from the cascade (cwd →
|
|
50
57
|
configured persona dirs → library). By default shows
|
|
51
58
|
one row per persona at the recommended tier for its
|
|
@@ -165,7 +172,10 @@ function parseSelector(sel) {
|
|
|
165
172
|
if ('error' in result)
|
|
166
173
|
die(result.error, false);
|
|
167
174
|
const kind = local.byId.has(key) ? 'local' : 'repo';
|
|
168
|
-
|
|
175
|
+
if (kind === 'local') {
|
|
176
|
+
return { kind, source: local.sources.get(result.id) ?? 'cwd', spec: result, tier };
|
|
177
|
+
}
|
|
178
|
+
return { kind, source: 'library', spec: result, tier };
|
|
169
179
|
}
|
|
170
180
|
/**
|
|
171
181
|
* Resolve the `<harness>` placeholder used in persona systemPrompts.
|
|
@@ -187,6 +197,7 @@ function buildSelection(spec, tier, kind) {
|
|
|
187
197
|
...rawRuntime,
|
|
188
198
|
systemPrompt: resolveSystemPromptPlaceholders(rawRuntime.systemPrompt, rawRuntime.harness)
|
|
189
199
|
};
|
|
200
|
+
const sidecar = resolveSidecar(spec, tier);
|
|
190
201
|
return {
|
|
191
202
|
personaId: spec.id,
|
|
192
203
|
tier,
|
|
@@ -196,7 +207,18 @@ function buildSelection(spec, tier, kind) {
|
|
|
196
207
|
...(spec.inputs ? { inputs: spec.inputs } : {}),
|
|
197
208
|
...(spec.env ? { env: spec.env } : {}),
|
|
198
209
|
...(spec.mcpServers ? { mcpServers: spec.mcpServers } : {}),
|
|
199
|
-
...(spec.permissions ? { permissions: spec.permissions } : {})
|
|
210
|
+
...(spec.permissions ? { permissions: spec.permissions } : {}),
|
|
211
|
+
...(spec.mount ? { mount: spec.mount } : {}),
|
|
212
|
+
...(sidecar.claudeMd ? { claudeMd: sidecar.claudeMd } : {}),
|
|
213
|
+
...(sidecar.claudeMdContent ? { claudeMdContent: sidecar.claudeMdContent } : {}),
|
|
214
|
+
...(sidecar.claudeMd || sidecar.claudeMdContent
|
|
215
|
+
? { claudeMdMode: sidecar.claudeMdMode }
|
|
216
|
+
: {}),
|
|
217
|
+
...(sidecar.agentsMd ? { agentsMd: sidecar.agentsMd } : {}),
|
|
218
|
+
...(sidecar.agentsMdContent ? { agentsMdContent: sidecar.agentsMdContent } : {}),
|
|
219
|
+
...(sidecar.agentsMd || sidecar.agentsMdContent
|
|
220
|
+
? { agentsMdMode: sidecar.agentsMdMode }
|
|
221
|
+
: {})
|
|
200
222
|
};
|
|
201
223
|
}
|
|
202
224
|
function emitDropWarnings(lines) {
|
|
@@ -368,7 +390,12 @@ export const CLEAN_IGNORED_PATTERNS = [
|
|
|
368
390
|
'CLAUDE.md',
|
|
369
391
|
'CLAUDE.local.md',
|
|
370
392
|
'.claude',
|
|
371
|
-
'.mcp.json'
|
|
393
|
+
'.mcp.json',
|
|
394
|
+
// Per-persona AGENTS.md sidecars get materialized into the mount when
|
|
395
|
+
// running under opencode; without this the user's real-cwd AGENTS.md
|
|
396
|
+
// would copy in (masking the persona content) and writes from
|
|
397
|
+
// onBeforeLaunch would sync back out.
|
|
398
|
+
'AGENTS.md'
|
|
372
399
|
];
|
|
373
400
|
/**
|
|
374
401
|
* Skill-install artifacts that should never be copied into the mount nor
|
|
@@ -392,8 +419,32 @@ export const SKILL_INSTALL_IGNORED_PATTERNS = [
|
|
|
392
419
|
'.skills',
|
|
393
420
|
// provider lockfiles written at the repo root
|
|
394
421
|
'prpm.lock',
|
|
395
|
-
'skills-lock.json'
|
|
422
|
+
'skills-lock.json',
|
|
423
|
+
// Per-persona AGENTS.md sidecars (opencode harness) get materialized
|
|
424
|
+
// into the mount; hide so the real-cwd AGENTS.md isn't copied in and
|
|
425
|
+
// the persona-written copy doesn't sync back out.
|
|
426
|
+
'AGENTS.md'
|
|
396
427
|
];
|
|
428
|
+
export function buildRelayfileMountPatterns(input) {
|
|
429
|
+
const dotfiles = readAgentDotfiles(input.projectDir, {
|
|
430
|
+
agentName: input.personaId
|
|
431
|
+
});
|
|
432
|
+
const builtInIgnored = input.harness === 'claude'
|
|
433
|
+
? CLEAN_IGNORED_PATTERNS
|
|
434
|
+
: SKILL_INSTALL_IGNORED_PATTERNS;
|
|
435
|
+
return {
|
|
436
|
+
ignoredPatterns: [
|
|
437
|
+
...dotfiles.ignoredPatterns,
|
|
438
|
+
...(input.mount?.ignoredPatterns ?? []),
|
|
439
|
+
...builtInIgnored,
|
|
440
|
+
...(input.configFilePaths ?? [])
|
|
441
|
+
],
|
|
442
|
+
readonlyPatterns: [
|
|
443
|
+
...dotfiles.readonlyPatterns,
|
|
444
|
+
...(input.mount?.readonlyPatterns ?? [])
|
|
445
|
+
]
|
|
446
|
+
};
|
|
447
|
+
}
|
|
397
448
|
/**
|
|
398
449
|
* Build the block appended to `<mount>/.git/info/exclude` so untracked-and-
|
|
399
450
|
* hidden files (e.g. `.claude/skills/` materialized by skill installs, or
|
|
@@ -465,6 +516,96 @@ export function configureGitForMount(mountDir, patterns) {
|
|
|
465
516
|
}
|
|
466
517
|
}
|
|
467
518
|
}
|
|
519
|
+
/**
|
|
520
|
+
* Resolve the sidecar for a given selection + harness, returning the
|
|
521
|
+
* persona-author content the runtime should materialize into the mount.
|
|
522
|
+
* Returns `{}` when no sidecar applies (no path/content set, or harness
|
|
523
|
+
* doesn't support sidecar files at all). Read errors surface as a warning
|
|
524
|
+
* string so the caller can drop the sidecar gracefully rather than
|
|
525
|
+
* failing the whole session.
|
|
526
|
+
*/
|
|
527
|
+
export function loadSidecarForSelection(selection) {
|
|
528
|
+
const harness = selection.runtime.harness;
|
|
529
|
+
if (harness !== 'claude' && harness !== 'opencode')
|
|
530
|
+
return {};
|
|
531
|
+
if (harness === 'claude') {
|
|
532
|
+
if (selection.claudeMdContent) {
|
|
533
|
+
return {
|
|
534
|
+
sidecar: {
|
|
535
|
+
mountFile: 'CLAUDE.md',
|
|
536
|
+
personaContent: selection.claudeMdContent,
|
|
537
|
+
mode: selection.claudeMdMode ?? 'overwrite'
|
|
538
|
+
}
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
if (selection.claudeMd) {
|
|
542
|
+
try {
|
|
543
|
+
const content = readFileSync(selection.claudeMd, 'utf8');
|
|
544
|
+
return {
|
|
545
|
+
sidecar: {
|
|
546
|
+
mountFile: 'CLAUDE.md',
|
|
547
|
+
personaContent: content,
|
|
548
|
+
mode: selection.claudeMdMode ?? 'overwrite'
|
|
549
|
+
}
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
catch (err) {
|
|
553
|
+
return { warning: `claudeMd: could not read ${selection.claudeMd}: ${err.message}` };
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
return {};
|
|
557
|
+
}
|
|
558
|
+
if (selection.agentsMdContent) {
|
|
559
|
+
return {
|
|
560
|
+
sidecar: {
|
|
561
|
+
mountFile: 'AGENTS.md',
|
|
562
|
+
personaContent: selection.agentsMdContent,
|
|
563
|
+
mode: selection.agentsMdMode ?? 'overwrite'
|
|
564
|
+
}
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
if (selection.agentsMd) {
|
|
568
|
+
try {
|
|
569
|
+
const content = readFileSync(selection.agentsMd, 'utf8');
|
|
570
|
+
return {
|
|
571
|
+
sidecar: {
|
|
572
|
+
mountFile: 'AGENTS.md',
|
|
573
|
+
personaContent: content,
|
|
574
|
+
mode: selection.agentsMdMode ?? 'overwrite'
|
|
575
|
+
}
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
catch (err) {
|
|
579
|
+
return { warning: `agentsMd: could not read ${selection.agentsMd}: ${err.message}` };
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
return {};
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* Compute the bytes to write into the mount for a sidecar. In `extend`
|
|
586
|
+
* mode, prepends the user's real-cwd file (if any) joined to the persona
|
|
587
|
+
* content with `\n\n---\n\n`. Pure — exposed for unit tests.
|
|
588
|
+
*/
|
|
589
|
+
export function buildSidecarBody(sidecar, realCwdDir) {
|
|
590
|
+
if (sidecar.mode === 'extend') {
|
|
591
|
+
const realPath = join(realCwdDir, sidecar.mountFile);
|
|
592
|
+
try {
|
|
593
|
+
const realContent = readFileSync(realPath, 'utf8');
|
|
594
|
+
return `${realContent}\n\n---\n\n${sidecar.personaContent}`;
|
|
595
|
+
}
|
|
596
|
+
catch (err) {
|
|
597
|
+
// Only "missing path" errors degrade to overwrite. Real I/O
|
|
598
|
+
// problems (EACCES, EISDIR, …) propagate so callers see them
|
|
599
|
+
// instead of silently dropping the user's CLAUDE.md/AGENTS.md.
|
|
600
|
+
const code = err.code;
|
|
601
|
+
if (code === 'ENOENT' || code === 'ENOTDIR') {
|
|
602
|
+
return sidecar.personaContent;
|
|
603
|
+
}
|
|
604
|
+
throw err;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
return sidecar.personaContent;
|
|
608
|
+
}
|
|
468
609
|
/**
|
|
469
610
|
* Decide whether to run the interactive session inside a
|
|
470
611
|
* `@relayfile/local-mount` sandbox.
|
|
@@ -482,7 +623,7 @@ export function decideCleanMode(harness, installInRepo = false) {
|
|
|
482
623
|
}
|
|
483
624
|
return { useClean: false };
|
|
484
625
|
}
|
|
485
|
-
async function runInteractive(selection, options
|
|
626
|
+
async function runInteractive(selection, options) {
|
|
486
627
|
const inputResolution = resolvePersonaInputs(selection.inputs, selection.inputValues, process.env);
|
|
487
628
|
const renderedSystemPrompt = renderPersonaInputs(selection.runtime.systemPrompt, inputResolution.values);
|
|
488
629
|
const effectiveSelection = {
|
|
@@ -500,6 +641,21 @@ async function runInteractive(selection, options = {}) {
|
|
|
500
641
|
// below). The --install-in-repo flag forces legacy in-repo installs
|
|
501
642
|
// across the board.
|
|
502
643
|
const useClean = decideCleanMode(runtime.harness, options.installInRepo === true).useClean;
|
|
644
|
+
// Per-persona CLAUDE.md / AGENTS.md: load the author content if any. The
|
|
645
|
+
// file is materialized into the mount inside onBeforeLaunch (claude/
|
|
646
|
+
// opencode default). Without a mount (codex, --install-in-repo) we
|
|
647
|
+
// skip-and-warn — writing into the real cwd would pollute the user's
|
|
648
|
+
// repo and is explicitly out of scope.
|
|
649
|
+
const sidecarLookup = loadSidecarForSelection(effectiveSelection);
|
|
650
|
+
if (sidecarLookup.warning) {
|
|
651
|
+
process.stderr.write(`warning: ${sidecarLookup.warning}\n`);
|
|
652
|
+
}
|
|
653
|
+
const resolvedSidecar = useClean ? sidecarLookup.sidecar : undefined;
|
|
654
|
+
if (sidecarLookup.sidecar && !useClean) {
|
|
655
|
+
process.stderr.write(`warning: persona declares ${sidecarLookup.sidecar.mountFile} but no sandbox mount is available (` +
|
|
656
|
+
`${runtime.harness === 'codex' ? 'codex harness has no mount' : '--install-in-repo disengages the mount'})` +
|
|
657
|
+
`; skipping sidecar materialization to avoid writing into your repo.\n`);
|
|
658
|
+
}
|
|
503
659
|
// A session dir is needed whenever we either (a) stage skills out-of-repo
|
|
504
660
|
// via claude's installRoot, or (b) open a mount. Both engage for claude/
|
|
505
661
|
// opencode by default; --install-in-repo disengages both.
|
|
@@ -511,6 +667,14 @@ async function runInteractive(selection, options = {}) {
|
|
|
511
667
|
const ctx = useSelection(effectiveSelection, installRoot !== undefined ? { installRoot } : {});
|
|
512
668
|
const { install } = ctx;
|
|
513
669
|
process.stderr.write(`→ ${personaId} [${tier}] via ${runtime.harness} (${runtime.model})\n`);
|
|
670
|
+
const startLaunchMetadataForLaunch = (cwd = process.cwd()) => startLaunchMetadataRecording({
|
|
671
|
+
selection: effectiveSelection,
|
|
672
|
+
personaSpec: options.personaSpec,
|
|
673
|
+
personaSource: options.personaSource,
|
|
674
|
+
cwd,
|
|
675
|
+
noLaunchMetadata: options.noLaunchMetadata,
|
|
676
|
+
env: process.env
|
|
677
|
+
});
|
|
514
678
|
const inputEnv = inputResolution.values;
|
|
515
679
|
const callerEnv = { ...process.env, ...inputEnv };
|
|
516
680
|
const envResolution = resolveStringMapLenient(effectiveSelection.env, callerEnv, 'env');
|
|
@@ -608,9 +772,7 @@ async function runInteractive(selection, options = {}) {
|
|
|
608
772
|
// copied in from the real repo nor synced back on exit.
|
|
609
773
|
if (useClean && sessionRoot) {
|
|
610
774
|
const mountDir = sessionMountDir(sessionRoot);
|
|
611
|
-
|
|
612
|
-
? [...CLEAN_IGNORED_PATTERNS]
|
|
613
|
-
: [...SKILL_INSTALL_IGNORED_PATTERNS];
|
|
775
|
+
let launchMetadata;
|
|
614
776
|
// Anything we materialize into the mount via onBeforeLaunch must be
|
|
615
777
|
// hidden from the mount-mirror in both directions: without this, any
|
|
616
778
|
// opencode.json already present in the real repo would be copied into
|
|
@@ -618,9 +780,13 @@ async function runInteractive(selection, options = {}) {
|
|
|
618
780
|
// fresh write from onBeforeLaunch would sync back out on exit and
|
|
619
781
|
// pollute the user's working tree. Added dynamically so this stays
|
|
620
782
|
// generic for any future configFile producer.
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
783
|
+
const { ignoredPatterns, readonlyPatterns } = buildRelayfileMountPatterns({
|
|
784
|
+
projectDir: process.cwd(),
|
|
785
|
+
personaId,
|
|
786
|
+
harness: runtime.harness,
|
|
787
|
+
mount: effectiveSelection.mount,
|
|
788
|
+
configFilePaths: spec.configFiles.map((file) => file.path)
|
|
789
|
+
});
|
|
624
790
|
process.stderr.write(`• sandbox mount → ${mountDir}\n`);
|
|
625
791
|
// Three-stage SIGINT handler layered on top of launchOnMount's own signal
|
|
626
792
|
// forwarding. launchOnMount catches the first SIGINT to kill the child
|
|
@@ -696,6 +862,7 @@ async function runInteractive(selection, options = {}) {
|
|
|
696
862
|
// `git push` to persist work — local-only commits evaporate with
|
|
697
863
|
// the session.
|
|
698
864
|
includeGit: true,
|
|
865
|
+
readonlyPatterns,
|
|
699
866
|
// Second Ctrl-C aborts this signal → local-mount skips autosync's
|
|
700
867
|
// draining reconcile and returns the partial syncBack count. Cleanup
|
|
701
868
|
// still runs, so there's no leaked mount dir.
|
|
@@ -726,7 +893,7 @@ async function runInteractive(selection, options = {}) {
|
|
|
726
893
|
process.stderr.write(`✓ ${message}\n`);
|
|
727
894
|
}
|
|
728
895
|
},
|
|
729
|
-
onBeforeLaunch: (dir) => {
|
|
896
|
+
onBeforeLaunch: async (dir) => {
|
|
730
897
|
// Run before install / configFile writes so the freshly written
|
|
731
898
|
// files (e.g. `.opencode/`, `opencode.json`) aren't yet present
|
|
732
899
|
// when we run `git ls-files` to pick skip-worktree candidates —
|
|
@@ -745,6 +912,11 @@ async function runInteractive(selection, options = {}) {
|
|
|
745
912
|
mkdirSync(dirname(target), { recursive: true });
|
|
746
913
|
writeFileSync(target, file.contents, 'utf8');
|
|
747
914
|
}
|
|
915
|
+
if (resolvedSidecar) {
|
|
916
|
+
const body = buildSidecarBody(resolvedSidecar, process.cwd());
|
|
917
|
+
writeFileSync(join(dir, resolvedSidecar.mountFile), body, 'utf8');
|
|
918
|
+
}
|
|
919
|
+
launchMetadata = await startLaunchMetadataForLaunch(dir);
|
|
748
920
|
}
|
|
749
921
|
});
|
|
750
922
|
return result.exitCode;
|
|
@@ -779,6 +951,7 @@ async function runInteractive(selection, options = {}) {
|
|
|
779
951
|
syncSpinner.stop();
|
|
780
952
|
syncSpinner = undefined;
|
|
781
953
|
}
|
|
954
|
+
await launchMetadata?.stop();
|
|
782
955
|
process.removeListener('SIGINT', forceExitHandler);
|
|
783
956
|
// When the install ran inside the mount, its cleanup paths are
|
|
784
957
|
// mount-relative (e.g. `.skills/<name>`, `skills/<name>`) and
|
|
@@ -792,6 +965,7 @@ async function runInteractive(selection, options = {}) {
|
|
|
792
965
|
removeSessionRoot(sessionRoot);
|
|
793
966
|
}
|
|
794
967
|
}
|
|
968
|
+
const launchMetadata = await startLaunchMetadataForLaunch();
|
|
795
969
|
return new Promise((resolve) => {
|
|
796
970
|
let settled = false;
|
|
797
971
|
const finish = (code) => {
|
|
@@ -800,7 +974,7 @@ async function runInteractive(selection, options = {}) {
|
|
|
800
974
|
settled = true;
|
|
801
975
|
runCleanup(install.cleanupCommand, install.cleanupCommandString);
|
|
802
976
|
removeSessionRoot(sessionRoot);
|
|
803
|
-
resolve(code);
|
|
977
|
+
void launchMetadata.stop().finally(() => resolve(code));
|
|
804
978
|
};
|
|
805
979
|
const child = spawn(spec.bin, finalArgs, {
|
|
806
980
|
stdio: 'inherit',
|
|
@@ -1454,6 +1628,20 @@ function formatPersonaShow(spec, source, tiers, tierNote) {
|
|
|
1454
1628
|
lines.push(` deny: ${perms.deny.join(', ')}`);
|
|
1455
1629
|
}
|
|
1456
1630
|
lines.push('');
|
|
1631
|
+
lines.push('MOUNT');
|
|
1632
|
+
const mount = spec.mount;
|
|
1633
|
+
if (!mount || (!mount.ignoredPatterns?.length && !mount.readonlyPatterns?.length)) {
|
|
1634
|
+
lines.push(' (none)');
|
|
1635
|
+
}
|
|
1636
|
+
else {
|
|
1637
|
+
if (mount.ignoredPatterns?.length) {
|
|
1638
|
+
lines.push(` ignored: ${mount.ignoredPatterns.join(', ')}`);
|
|
1639
|
+
}
|
|
1640
|
+
if (mount.readonlyPatterns?.length) {
|
|
1641
|
+
lines.push(` readonly: ${mount.readonlyPatterns.join(', ')}`);
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
lines.push('');
|
|
1457
1645
|
lines.push('ENV');
|
|
1458
1646
|
const envKeys = Object.keys(spec.env ?? {});
|
|
1459
1647
|
if (envKeys.length === 0) {
|
|
@@ -1584,7 +1772,10 @@ async function runAgentSelector(selector, flags, inputValues) {
|
|
|
1584
1772
|
...(inputValues ? { inputValues } : {})
|
|
1585
1773
|
};
|
|
1586
1774
|
const code = await runInteractive(selection, {
|
|
1587
|
-
installInRepo: flags.installInRepo
|
|
1775
|
+
installInRepo: flags.installInRepo,
|
|
1776
|
+
noLaunchMetadata: flags.noLaunchMetadata,
|
|
1777
|
+
personaSpec: target.spec,
|
|
1778
|
+
personaSource: target.source
|
|
1588
1779
|
});
|
|
1589
1780
|
process.exit(code);
|
|
1590
1781
|
}
|
|
@@ -1641,7 +1832,7 @@ export async function main() {
|
|
|
1641
1832
|
await runAgentSelector(selector, flags);
|
|
1642
1833
|
}
|
|
1643
1834
|
export function parseAgentArgs(args) {
|
|
1644
|
-
const flags = { installInRepo: false };
|
|
1835
|
+
const flags = { installInRepo: false, noLaunchMetadata: false };
|
|
1645
1836
|
const positional = [];
|
|
1646
1837
|
let seenDoubleDash = false;
|
|
1647
1838
|
for (const arg of args) {
|
|
@@ -1657,6 +1848,10 @@ export function parseAgentArgs(args) {
|
|
|
1657
1848
|
flags.installInRepo = true;
|
|
1658
1849
|
continue;
|
|
1659
1850
|
}
|
|
1851
|
+
if (arg === '--no-launch-metadata') {
|
|
1852
|
+
flags.noLaunchMetadata = true;
|
|
1853
|
+
continue;
|
|
1854
|
+
}
|
|
1660
1855
|
if (arg === '-h' || arg === '--help') {
|
|
1661
1856
|
process.stdout.write(USAGE);
|
|
1662
1857
|
process.exit(0);
|
|
@@ -1666,7 +1861,7 @@ export function parseAgentArgs(args) {
|
|
|
1666
1861
|
return { flags, positional };
|
|
1667
1862
|
}
|
|
1668
1863
|
export function parseCreateArgs(args) {
|
|
1669
|
-
const flags = { installInRepo: false, saveDefault: false };
|
|
1864
|
+
const flags = { installInRepo: false, noLaunchMetadata: false, saveDefault: false };
|
|
1670
1865
|
let seenDoubleDash = false;
|
|
1671
1866
|
const positional = [];
|
|
1672
1867
|
const valueOf = (i, flag) => {
|
|
@@ -1690,6 +1885,10 @@ export function parseCreateArgs(args) {
|
|
|
1690
1885
|
flags.installInRepo = true;
|
|
1691
1886
|
continue;
|
|
1692
1887
|
}
|
|
1888
|
+
if (arg === '--no-launch-metadata') {
|
|
1889
|
+
flags.noLaunchMetadata = true;
|
|
1890
|
+
continue;
|
|
1891
|
+
}
|
|
1693
1892
|
if (arg === '--to') {
|
|
1694
1893
|
flags.to = valueOf(i, arg);
|
|
1695
1894
|
i += 1;
|
|
@@ -1700,7 +1899,7 @@ export function parseCreateArgs(args) {
|
|
|
1700
1899
|
continue;
|
|
1701
1900
|
}
|
|
1702
1901
|
if (arg === '-h' || arg === '--help') {
|
|
1703
|
-
process.stdout.write('Usage: agentworkforce create [--to <cwd|user|dir:n|library|path>] [--save-default] [--install-in-repo]\n');
|
|
1902
|
+
process.stdout.write('Usage: agentworkforce create [--to <cwd|user|dir:n|library|path>] [--save-default] [--install-in-repo] [--no-launch-metadata]\n');
|
|
1704
1903
|
process.exit(0);
|
|
1705
1904
|
}
|
|
1706
1905
|
positional.push(arg);
|