@mono-agent/agent-app 0.5.1 → 0.6.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/README.md +5 -0
- package/dist/adapter-send-tools.d.ts +7 -7
- package/dist/adapter-send-tools.d.ts.map +1 -1
- package/dist/adapter-send-tools.js +59 -50
- package/dist/adapter-send-tools.js.map +1 -1
- package/dist/app.js +8 -8
- package/dist/app.js.map +1 -1
- package/dist/channels.js +3 -3
- package/dist/channels.js.map +1 -1
- package/dist/cli.d.ts +14 -10
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +197 -162
- package/dist/cli.js.map +1 -1
- package/dist/config-reference.js +4 -4
- package/dist/config-reference.js.map +1 -1
- package/dist/consumer-contract.d.ts.map +1 -1
- package/dist/consumer-contract.js +5 -3
- package/dist/consumer-contract.js.map +1 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +126 -5
- package/dist/doctor.js.map +1 -1
- package/dist/init.d.ts +11 -22
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +25 -116
- package/dist/init.js.map +1 -1
- package/dist/interaction-bridge.d.ts +3 -3
- package/dist/interaction-bridge.d.ts.map +1 -1
- package/dist/memory-recall.d.ts +2 -2
- package/dist/memory-recall.d.ts.map +1 -1
- package/dist/memory-recall.js +3 -3
- package/dist/memory-recall.js.map +1 -1
- package/dist/modules/base.d.ts +25 -0
- package/dist/modules/base.d.ts.map +1 -0
- package/dist/{recipes → modules}/base.js +16 -11
- package/dist/modules/base.js.map +1 -0
- package/dist/modules/catalog.d.ts +12 -0
- package/dist/modules/catalog.d.ts.map +1 -0
- package/dist/modules/catalog.js +412 -0
- package/dist/modules/catalog.js.map +1 -0
- package/dist/modules/index.d.ts +8 -0
- package/dist/modules/index.d.ts.map +1 -0
- package/dist/modules/index.js +5 -0
- package/dist/modules/index.js.map +1 -0
- package/dist/modules/known-tools.d.ts +44 -0
- package/dist/modules/known-tools.d.ts.map +1 -0
- package/dist/modules/known-tools.js +88 -0
- package/dist/modules/known-tools.js.map +1 -0
- package/dist/modules/types.d.ts +73 -0
- package/dist/modules/types.d.ts.map +1 -0
- package/dist/{recipes → modules}/types.js +3 -3
- package/dist/{recipes → modules}/types.js.map +1 -1
- package/dist/posted-message-index.d.ts +2 -2
- package/dist/posted-message-index.js +2 -2
- package/dist/wizard/answers.d.ts +85 -0
- package/dist/wizard/answers.d.ts.map +1 -0
- package/dist/wizard/answers.js +231 -0
- package/dist/wizard/answers.js.map +1 -0
- package/dist/wizard/from-flags.d.ts +26 -0
- package/dist/wizard/from-flags.d.ts.map +1 -0
- package/dist/wizard/from-flags.js +44 -0
- package/dist/wizard/from-flags.js.map +1 -0
- package/dist/wizard/index.d.ts +11 -0
- package/dist/wizard/index.d.ts.map +1 -0
- package/dist/wizard/index.js +6 -0
- package/dist/wizard/index.js.map +1 -0
- package/dist/wizard/presets.d.ts +40 -0
- package/dist/wizard/presets.d.ts.map +1 -0
- package/dist/wizard/presets.js +85 -0
- package/dist/wizard/presets.js.map +1 -0
- package/dist/wizard/prompts.d.ts +52 -0
- package/dist/wizard/prompts.d.ts.map +1 -0
- package/dist/wizard/prompts.js +141 -0
- package/dist/wizard/prompts.js.map +1 -0
- package/dist/wizard/run.d.ts +19 -0
- package/dist/wizard/run.d.ts.map +1 -0
- package/dist/wizard/run.js +345 -0
- package/dist/wizard/run.js.map +1 -0
- package/package.json +17 -16
- package/schema/mono-agent.config.schema.json +5 -3
- package/skills/mono-agent-composer/SKILL.md +7 -7
- package/skills/mono-agent-composer/references/config-blueprint.md +7 -7
- package/skills/mono-agent-composer/references/discovery-questions.md +8 -6
- package/skills/mono-agent-composer/references/feature-coverage.md +10 -8
- package/skills/mono-agent-composer/references/package-map.md +5 -5
- package/skills/mono-agent-composer/references/playbooks.md +22 -22
- package/skills/mono-agent-composer/references/validation.md +3 -3
- package/dist/recipes/base.d.ts +0 -15
- package/dist/recipes/base.d.ts.map +0 -1
- package/dist/recipes/base.js.map +0 -1
- package/dist/recipes/catalog.d.ts +0 -4
- package/dist/recipes/catalog.d.ts.map +0 -1
- package/dist/recipes/catalog.js +0 -525
- package/dist/recipes/catalog.js.map +0 -1
- package/dist/recipes/index.d.ts +0 -11
- package/dist/recipes/index.d.ts.map +0 -1
- package/dist/recipes/index.js +0 -14
- package/dist/recipes/index.js.map +0 -1
- package/dist/recipes/types.d.ts +0 -70
- package/dist/recipes/types.d.ts.map +0 -1
- package/dist/setup.d.ts +0 -29
- package/dist/setup.d.ts.map +0 -1
- package/dist/setup.js +0 -97
- package/dist/setup.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { createInterface } from "node:readline/promises";
|
|
3
2
|
import { stat } from "node:fs/promises";
|
|
4
3
|
import { createRequire } from "node:module";
|
|
5
4
|
import { basename, resolve } from "node:path";
|
|
@@ -18,13 +17,15 @@ import { formatChannelFactValue } from "./channel-fact-format.js";
|
|
|
18
17
|
import { resolveChannelDrivers } from "./channels.js";
|
|
19
18
|
import { findUnknownAppConfigWarnings } from "./config-reference.js";
|
|
20
19
|
import { validateMonoAgentFolder } from "./doctor.js";
|
|
21
|
-
import { initMonoAgentFolder
|
|
20
|
+
import { initMonoAgentFolder } from "./init.js";
|
|
22
21
|
import { installComposerSkill } from "./install-skill.js";
|
|
23
22
|
import { runMetrics } from "./metrics.js";
|
|
24
|
-
import { findRecipe, RECIPE_CATALOG, recipeIds, resolveRecipeInputs } from "./recipes/index.js";
|
|
25
23
|
import { buildRunsHealthDisplay, RUNS_HEALTH_MAX_RUNS } from "./runs-health.js";
|
|
26
24
|
import { purgeSessions } from "./sessions.js";
|
|
27
|
-
import {
|
|
25
|
+
import { composeWizardPlan } from "./wizard/answers.js";
|
|
26
|
+
import { answersFromCli, isWithChannel } from "./wizard/from-flags.js";
|
|
27
|
+
import { findPreset, PRESET_CATALOG, presetAnswers, presetIds, RECIPE_TO_PRESET } from "./wizard/presets.js";
|
|
28
|
+
import { runInitWizard } from "./wizard/run.js";
|
|
28
29
|
import * as ui from "./ui.js";
|
|
29
30
|
const DEFAULT_LOG_LINES = 200;
|
|
30
31
|
// Node's maximum setInterval/setTimeout delay (2^31 - 1 ms, ~24.8 days). A
|
|
@@ -32,7 +33,7 @@ const DEFAULT_LOG_LINES = 200;
|
|
|
32
33
|
// busy-waiting; larger values silently overflow to a 1ms delay.
|
|
33
34
|
const KEEP_ALIVE_INTERVAL_MS = 2_147_483_647;
|
|
34
35
|
const BACKGROUND_COMMANDS = ["start", "restart", "stop", "status", "logs"];
|
|
35
|
-
const KNOWN_COMMANDS = ["init", "setup", "validate", "doctor", "config", "recipes", "start", "restart", "stop", "status", "logs", "tui", "web", "install-skill", "backfill", "audit-runs", "metrics", "memory"];
|
|
36
|
+
const KNOWN_COMMANDS = ["init", "setup", "validate", "doctor", "config", "recipes", "presets", "start", "restart", "stop", "status", "logs", "tui", "web", "install-skill", "backfill", "audit-runs", "metrics", "memory"];
|
|
36
37
|
export function parseCliArgs(argv) {
|
|
37
38
|
const [command, ...rest] = argv;
|
|
38
39
|
if (command === undefined || command === "help" || command === "--help" || command === "-h") {
|
|
@@ -44,16 +45,25 @@ export function parseCliArgs(argv) {
|
|
|
44
45
|
if (!KNOWN_COMMANDS.includes(command)) {
|
|
45
46
|
throw new Error(`Unknown command \`${command}\`. Expected ${KNOWN_COMMANDS.join(", ")}.`);
|
|
46
47
|
}
|
|
47
|
-
// `doctor`
|
|
48
|
-
//
|
|
49
|
-
|
|
48
|
+
// `doctor`/`setup`/`recipes` are aliases; normalize here so every downstream
|
|
49
|
+
// path (routing, env-file resolution, --consumer) applies unchanged. `doctor`
|
|
50
|
+
// → `validate`, `setup` → `init`, `recipes` → `presets`.
|
|
51
|
+
const cmd = (command === "doctor"
|
|
52
|
+
? "validate"
|
|
53
|
+
: command === "setup"
|
|
54
|
+
? "init"
|
|
55
|
+
: command === "recipes"
|
|
56
|
+
? "presets"
|
|
57
|
+
: command);
|
|
50
58
|
const isLogs = cmd === "logs";
|
|
51
59
|
let configPath;
|
|
52
60
|
let model;
|
|
53
61
|
let fallbackModels;
|
|
54
62
|
let memory;
|
|
63
|
+
let preset;
|
|
55
64
|
let recipe;
|
|
56
65
|
let withChannels;
|
|
66
|
+
let yes = false;
|
|
57
67
|
const positionals = [];
|
|
58
68
|
let envFile;
|
|
59
69
|
let target;
|
|
@@ -192,9 +202,15 @@ export function parseCliArgs(argv) {
|
|
|
192
202
|
memory = raw;
|
|
193
203
|
break;
|
|
194
204
|
}
|
|
205
|
+
case "--preset":
|
|
206
|
+
preset = requireValue(rest, ++i, flag);
|
|
207
|
+
break;
|
|
195
208
|
case "--recipe":
|
|
196
209
|
recipe = requireValue(rest, ++i, flag);
|
|
197
210
|
break;
|
|
211
|
+
case "--yes":
|
|
212
|
+
yes = true;
|
|
213
|
+
break;
|
|
198
214
|
case "--with":
|
|
199
215
|
withChannels = requireValue(rest, ++i, flag)
|
|
200
216
|
.split(",")
|
|
@@ -270,8 +286,10 @@ export function parseCliArgs(argv) {
|
|
|
270
286
|
...(model === undefined ? {} : { model }),
|
|
271
287
|
...(fallbackModels === undefined ? {} : { fallbackModels }),
|
|
272
288
|
...(memory === undefined ? {} : { memory }),
|
|
289
|
+
...(preset === undefined ? {} : { preset }),
|
|
273
290
|
...(recipe === undefined ? {} : { recipe }),
|
|
274
291
|
...(withChannels === undefined ? {} : { withChannels }),
|
|
292
|
+
...(yes ? { yes } : {}),
|
|
275
293
|
positionals,
|
|
276
294
|
...(envFile === undefined ? {} : { envFile }),
|
|
277
295
|
...(target === undefined ? {} : { target }),
|
|
@@ -332,36 +350,32 @@ function requireValue(args, index, flag) {
|
|
|
332
350
|
}
|
|
333
351
|
const HELP_COMMANDS = [
|
|
334
352
|
{
|
|
335
|
-
signature: "mono-agent init [--
|
|
353
|
+
signature: "mono-agent init [--preset <id>] [--with <csv>] [--yes] [--dry-run]\n" +
|
|
336
354
|
" [--model <ref>] [--fallback-models <csv>] [--memory lite|journal|bujo]",
|
|
337
355
|
lines: [
|
|
338
|
-
"Scaffold mono-agent
|
|
339
|
-
"
|
|
340
|
-
"
|
|
356
|
+
"Scaffold a mono-agent in the current folder. On a TTY with no flags, launches",
|
|
357
|
+
"the step-by-step wizard; with --yes or any flag, writes the default/preset",
|
|
358
|
+
"scaffold non-interactively. --preset seeds a blueprint, --with adds channels,",
|
|
359
|
+
"--dry-run previews. Existing files are never overwritten.",
|
|
341
360
|
],
|
|
342
361
|
},
|
|
343
362
|
{
|
|
344
|
-
signature: "mono-agent setup
|
|
345
|
-
|
|
346
|
-
lines: [
|
|
347
|
-
"Guided setup when attached to a TTY: choose a recipe, answer non-secret",
|
|
348
|
-
"inputs, select channel add-ons, scaffold, validate, and print the secrets",
|
|
349
|
-
"checklist. In non-TTY contexts it falls back to init-style flags.",
|
|
350
|
-
],
|
|
363
|
+
signature: "mono-agent setup",
|
|
364
|
+
lines: ["Alias of `init`."],
|
|
351
365
|
},
|
|
352
366
|
{
|
|
353
|
-
signature: "mono-agent
|
|
367
|
+
signature: "mono-agent presets list | show <id>",
|
|
354
368
|
lines: [
|
|
355
|
-
"List the
|
|
369
|
+
"List the built-in setup presets, or show one's generated config,",
|
|
356
370
|
".env.example, and follow-up checklist.",
|
|
357
371
|
],
|
|
358
372
|
},
|
|
359
373
|
{
|
|
360
|
-
signature: "mono-agent validate [--
|
|
374
|
+
signature: "mono-agent validate [--preset <id>] [--consumer <path>] [--config <path>] [--env-file <path>]",
|
|
361
375
|
lines: [
|
|
362
376
|
"Load every config section and report what would run, wait, or fail.",
|
|
363
377
|
"--consumer validates another agent folder read-only, including its .env.",
|
|
364
|
-
"With --
|
|
378
|
+
"With --preset, also report whether the preset's capabilities are live.",
|
|
365
379
|
"`mono-agent doctor` is an alias for this command.",
|
|
366
380
|
],
|
|
367
381
|
},
|
|
@@ -536,14 +550,12 @@ export async function runCli(argv) {
|
|
|
536
550
|
return 0;
|
|
537
551
|
case "init":
|
|
538
552
|
return await runInit(args);
|
|
539
|
-
case "setup":
|
|
540
|
-
return await runSetup(args);
|
|
541
553
|
case "validate":
|
|
542
554
|
return await runValidate(args);
|
|
543
555
|
case "config":
|
|
544
556
|
return await runConfig(args);
|
|
545
|
-
case "
|
|
546
|
-
return
|
|
557
|
+
case "presets":
|
|
558
|
+
return runPresets(args);
|
|
547
559
|
case "start":
|
|
548
560
|
return await runStart(args);
|
|
549
561
|
case "restart":
|
|
@@ -623,93 +635,83 @@ export async function runCli(argv) {
|
|
|
623
635
|
}
|
|
624
636
|
}
|
|
625
637
|
async function runInit(args) {
|
|
626
|
-
|
|
627
|
-
|
|
638
|
+
// On an interactive TTY with no overriding flags, walk the step-by-step wizard;
|
|
639
|
+
// any flag (or a piped/non-TTY invocation) takes the silent default/preset path.
|
|
640
|
+
const wantsWizard = process.stdin.isTTY === true && process.stdout.isTTY === true
|
|
641
|
+
&& args.yes !== true && args.preset === undefined && args.recipe === undefined
|
|
642
|
+
&& args.model === undefined && args.fallbackModels === undefined
|
|
643
|
+
&& args.memory === undefined && args.withChannels === undefined && args.dryRun !== true;
|
|
644
|
+
if (wantsWizard) {
|
|
645
|
+
// Existing-config pre-check — don't walk the wizard into a guaranteed no-op.
|
|
646
|
+
if (await pathExists(resolve(process.cwd(), "mono-agent.config.json"))) {
|
|
647
|
+
process.stdout.write(ui.hint("Found an existing mono-agent.config.json — `mono-agent init` never overwrites. Run `mono-agent validate`, or start in an empty folder.\n"));
|
|
648
|
+
return 0;
|
|
649
|
+
}
|
|
650
|
+
const outcome = await runInitWizard({ cwd: process.cwd() });
|
|
651
|
+
if (outcome.status === "cancelled") {
|
|
652
|
+
return 1;
|
|
653
|
+
}
|
|
654
|
+
const result = await initMonoAgentFolder({ dir: process.cwd(), answers: outcome.answers });
|
|
655
|
+
printInitResult(result);
|
|
656
|
+
const report = await validateMonoAgentFolder({ env: process.env, cwd: process.cwd(), configPath: result.configPath });
|
|
657
|
+
process.stdout.write("\n" + ui.heading("Validation"));
|
|
658
|
+
for (const section of report.sections) {
|
|
659
|
+
process.stdout.write(formatSection(section));
|
|
660
|
+
}
|
|
661
|
+
process.stdout.write(renderPlanCompleteness(result.plan.validateExpectations, "Selected capabilities", report));
|
|
662
|
+
printSecretsChecklist(result.plan.secrets);
|
|
663
|
+
printNextSteps(result.configPath);
|
|
664
|
+
return report.ok ? 0 : 1;
|
|
665
|
+
}
|
|
666
|
+
const presetId = resolveInitPresetId(args);
|
|
667
|
+
if (presetId === "unknown") {
|
|
628
668
|
return 1;
|
|
629
669
|
}
|
|
630
670
|
const withChannels = resolveWithChannels(args);
|
|
631
671
|
if (withChannels === "invalid") {
|
|
632
672
|
return 1;
|
|
633
673
|
}
|
|
634
|
-
const
|
|
635
|
-
dir: process.cwd(),
|
|
674
|
+
const answers = answersFromCli({
|
|
636
675
|
...(args.model === undefined ? {} : { model: args.model }),
|
|
637
676
|
...(args.fallbackModels === undefined ? {} : { fallbackModels: args.fallbackModels }),
|
|
638
677
|
...(args.memory === undefined ? {} : { memory: args.memory }),
|
|
639
|
-
...(recipe === undefined ? {} : { recipe }),
|
|
640
678
|
...(withChannels === undefined ? {} : { withChannels }),
|
|
641
|
-
|
|
679
|
+
...(presetId === undefined ? {} : { presetId }),
|
|
642
680
|
});
|
|
643
|
-
|
|
644
|
-
|
|
681
|
+
const result = await initMonoAgentFolder({ dir: process.cwd(), answers, dryRun: args.dryRun });
|
|
682
|
+
printInitResult(result);
|
|
683
|
+
printSecretsChecklist(result.plan.secrets);
|
|
684
|
+
printNextSteps(result.configPath);
|
|
645
685
|
return 0;
|
|
646
686
|
}
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
let collected;
|
|
661
|
-
try {
|
|
662
|
-
collected = await collectSetupOptions({
|
|
663
|
-
prompt: { question: (prompt) => rl.question(prompt) },
|
|
664
|
-
...(recipeArg === undefined ? {} : { recipe: recipeArg }),
|
|
665
|
-
...(args.model === undefined ? {} : { model: args.model }),
|
|
666
|
-
...(args.fallbackModels === undefined ? {} : { fallbackModels: args.fallbackModels }),
|
|
667
|
-
...(withChannelsArg === undefined ? {} : { withChannels: withChannelsArg }),
|
|
668
|
-
});
|
|
669
|
-
}
|
|
670
|
-
finally {
|
|
671
|
-
rl.close();
|
|
672
|
-
}
|
|
673
|
-
const result = await initMonoAgentFolder({
|
|
674
|
-
dir: process.cwd(),
|
|
675
|
-
...(collected.fallbackModels.length === 0 ? {} : { fallbackModels: collected.fallbackModels }),
|
|
676
|
-
...(args.memory === undefined ? {} : { memory: args.memory }),
|
|
677
|
-
recipe: collected.recipe,
|
|
678
|
-
recipeInputs: collected.recipeInputs,
|
|
679
|
-
withChannels: collected.withChannels,
|
|
680
|
-
dryRun: args.dryRun,
|
|
681
|
-
});
|
|
682
|
-
printInitResult(result, collected.recipe);
|
|
683
|
-
if (!result.dryRun) {
|
|
684
|
-
const report = await validateMonoAgentFolder({
|
|
685
|
-
env: process.env,
|
|
686
|
-
cwd: process.cwd(),
|
|
687
|
-
configPath: result.configPath,
|
|
688
|
-
});
|
|
689
|
-
process.stdout.write("\n" + ui.heading("Validation"));
|
|
690
|
-
for (const section of report.sections) {
|
|
691
|
-
process.stdout.write(formatSection(section));
|
|
687
|
+
/**
|
|
688
|
+
* Resolve the preset id for `init`: `--preset` wins, `--recipe` is a deprecated
|
|
689
|
+
* alias mapped to the preset that replaced it. Returns the preset id to compose
|
|
690
|
+
* from, `undefined` for the default scaffold, or `"unknown"` after emitting the
|
|
691
|
+
* error/hint (an unknown preset, or a retired recipe with no replacement).
|
|
692
|
+
*/
|
|
693
|
+
function resolveInitPresetId(args) {
|
|
694
|
+
if (args.preset !== undefined) {
|
|
695
|
+
const preset = findPreset(args.preset);
|
|
696
|
+
if (preset === undefined) {
|
|
697
|
+
process.stderr.write(ui.errorLine(`Unknown preset \`${args.preset}\`.`));
|
|
698
|
+
process.stderr.write(ui.hint(`Available presets: ${presetIds().join(", ")}. Run \`mono-agent presets list\`.`));
|
|
699
|
+
return "unknown";
|
|
692
700
|
}
|
|
693
|
-
|
|
694
|
-
printSecretsChecklist(collected.secrets);
|
|
695
|
-
printNextSteps(result.configPath, collected.recipe);
|
|
696
|
-
return report.ok ? 0 : 1;
|
|
697
|
-
}
|
|
698
|
-
printSecretsChecklist(collected.secrets);
|
|
699
|
-
printNextSteps(result.configPath, collected.recipe);
|
|
700
|
-
return 0;
|
|
701
|
-
}
|
|
702
|
-
function resolveRecipeArg(args) {
|
|
703
|
-
if (args.recipe === undefined) {
|
|
704
|
-
return undefined;
|
|
701
|
+
return preset.id;
|
|
705
702
|
}
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
703
|
+
if (args.recipe !== undefined) {
|
|
704
|
+
const preset = RECIPE_TO_PRESET.get(args.recipe);
|
|
705
|
+
if (preset === undefined) {
|
|
706
|
+
process.stderr.write(ui.errorLine(`Recipe \`${args.recipe}\` was retired; the wizard composes capabilities directly.`));
|
|
707
|
+
process.stderr.write(ui.hint(`Use \`mono-agent init --preset <id>\` (${presetIds().join(", ")}), or \`mono-agent init\` for the step-by-step wizard.`));
|
|
708
|
+
process.stderr.write(ui.hint("See the mono-agent-composer skill and docs/playbooks for capability recipes."));
|
|
709
|
+
return "unknown";
|
|
710
|
+
}
|
|
711
|
+
process.stderr.write(ui.hint(`--recipe is deprecated; using preset ${preset.id}. See \`mono-agent presets list\`.`));
|
|
712
|
+
return preset.id;
|
|
711
713
|
}
|
|
712
|
-
return
|
|
714
|
+
return undefined;
|
|
713
715
|
}
|
|
714
716
|
function resolveWithChannels(args) {
|
|
715
717
|
if (args.withChannels === undefined) {
|
|
@@ -723,7 +725,7 @@ function resolveWithChannels(args) {
|
|
|
723
725
|
}
|
|
724
726
|
return args.withChannels.filter(isWithChannel);
|
|
725
727
|
}
|
|
726
|
-
function printInitResult(result
|
|
728
|
+
function printInitResult(result) {
|
|
727
729
|
if (result.dryRun) {
|
|
728
730
|
process.stdout.write(ui.style.dim("Dry run — nothing was written.\n"));
|
|
729
731
|
}
|
|
@@ -737,31 +739,35 @@ function printInitResult(result, recipe) {
|
|
|
737
739
|
if (result.knowledgeFiles.length > 0) {
|
|
738
740
|
process.stdout.write(`\nIdentity references existing knowledge: ${ui.style.cyan(result.knowledgeFiles.join(", "))}\n`);
|
|
739
741
|
}
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
742
|
+
// Internal `provider:*` modules are auto-added for local models; they are an
|
|
743
|
+
// implementation detail, not a user-facing capability, so exclude them here.
|
|
744
|
+
const capabilities = result.plan.selectedModules.filter((module) => module.kind !== "provider");
|
|
745
|
+
if (capabilities.length > 0) {
|
|
746
|
+
process.stdout.write("\n" + ui.heading("Capabilities"));
|
|
747
|
+
for (const module of capabilities) {
|
|
748
|
+
process.stdout.write(` ${ui.style.cyan(module.title)} ${ui.style.dim(`(risk: ${riskColor(module.riskLevel)})`)}\n`);
|
|
744
749
|
}
|
|
745
750
|
}
|
|
751
|
+
if (result.plan.envExample !== undefined) {
|
|
752
|
+
process.stdout.write("\n" + ui.style.dim("Fill the secret placeholders in .env.example, then copy it to .env.\n"));
|
|
753
|
+
}
|
|
746
754
|
}
|
|
747
755
|
function printSecretsChecklist(secrets) {
|
|
748
756
|
process.stdout.write("\n" + ui.heading("Secrets checklist"));
|
|
749
757
|
if (secrets.length === 0) {
|
|
750
|
-
process.stdout.write(ui.style.dim("No
|
|
758
|
+
process.stdout.write(ui.style.dim("No secrets required by the selected capabilities.\n"));
|
|
751
759
|
return;
|
|
752
760
|
}
|
|
753
|
-
process.stdout.write(ui.style.dim("Copy .env.example to .env, then fill these variables. Secret values
|
|
761
|
+
process.stdout.write(ui.style.dim("Copy .env.example to .env, then fill these variables. Secret values are never written to JSON.\n"));
|
|
754
762
|
for (const secret of secrets) {
|
|
755
|
-
|
|
756
|
-
process.stdout.write(` ${ui.style.bold(key)} ${ui.style.dim(`- ${secret.label}: ${secret.description}`)}\n`);
|
|
763
|
+
process.stdout.write(` ${ui.style.bold(secret.envVar)} ${ui.style.dim(`- ${secret.label}: ${secret.description}`)}\n`);
|
|
757
764
|
}
|
|
758
765
|
}
|
|
759
|
-
function printNextSteps(configPath
|
|
760
|
-
const validateCmd = recipe === undefined ? "mono-agent validate" : `mono-agent validate --recipe ${recipe.id}`;
|
|
766
|
+
function printNextSteps(configPath) {
|
|
761
767
|
process.stdout.write("\n" +
|
|
762
768
|
ui.heading("Next steps") +
|
|
763
769
|
` ${ui.style.bold("1.")} Edit ${configPath} ${ui.style.dim("(model, channels, skills, memory, sandbox)")}\n` +
|
|
764
|
-
` ${ui.style.bold("2.")}
|
|
770
|
+
` ${ui.style.bold("2.")} mono-agent validate\n` +
|
|
765
771
|
` ${ui.style.bold("3.")} mono-agent start\n`);
|
|
766
772
|
}
|
|
767
773
|
async function runInstallSkill(args) {
|
|
@@ -792,14 +798,16 @@ async function runValidate(args) {
|
|
|
792
798
|
for (const section of report.sections) {
|
|
793
799
|
process.stdout.write(formatSection(section));
|
|
794
800
|
}
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
801
|
+
const preset = resolveValidatePreset(args);
|
|
802
|
+
if (preset === "unknown") {
|
|
803
|
+
return 1;
|
|
804
|
+
}
|
|
805
|
+
if (preset !== undefined) {
|
|
806
|
+
const plan = composeWizardPlan(presetAnswers(preset), {
|
|
807
|
+
dirBasename: basename(context.cwd),
|
|
808
|
+
skillsRootExists: false,
|
|
809
|
+
});
|
|
810
|
+
process.stdout.write(renderPlanCompleteness(plan.validateExpectations, `Preset: ${preset.id}`, report));
|
|
803
811
|
}
|
|
804
812
|
process.stdout.write(report.ok
|
|
805
813
|
? `\n${ui.style.green("✓ Config is ready to start.")}\n${ui.style.dim("Run `mono-agent config` for the full field-by-field view.")}\n`
|
|
@@ -808,15 +816,42 @@ async function runValidate(args) {
|
|
|
808
816
|
return report.ok ? 0 : 1;
|
|
809
817
|
}
|
|
810
818
|
/**
|
|
811
|
-
*
|
|
812
|
-
*
|
|
813
|
-
*
|
|
814
|
-
|
|
819
|
+
* Resolve the preset to check `validate` against: `--preset` wins, `--recipe` is a
|
|
820
|
+
* deprecated alias. Returns the preset, `undefined` (no capability check), or
|
|
821
|
+
* `"unknown"` after emitting the error/hint.
|
|
822
|
+
*/
|
|
823
|
+
function resolveValidatePreset(args) {
|
|
824
|
+
if (args.preset !== undefined) {
|
|
825
|
+
const preset = findPreset(args.preset);
|
|
826
|
+
if (preset === undefined) {
|
|
827
|
+
process.stderr.write(ui.errorLine(`Unknown preset \`${args.preset}\`.`));
|
|
828
|
+
process.stderr.write(ui.hint(`Available presets: ${presetIds().join(", ")}. Run \`mono-agent presets list\`.`));
|
|
829
|
+
return "unknown";
|
|
830
|
+
}
|
|
831
|
+
return preset;
|
|
832
|
+
}
|
|
833
|
+
if (args.recipe !== undefined) {
|
|
834
|
+
const preset = RECIPE_TO_PRESET.get(args.recipe);
|
|
835
|
+
if (preset === undefined) {
|
|
836
|
+
process.stderr.write(ui.errorLine(`Recipe \`${args.recipe}\` was retired; validate against a preset instead.`));
|
|
837
|
+
process.stderr.write(ui.hint(`Available presets: ${presetIds().join(", ")}. Run \`mono-agent presets list\`.`));
|
|
838
|
+
return "unknown";
|
|
839
|
+
}
|
|
840
|
+
process.stderr.write(ui.hint(`--recipe is deprecated; using preset ${preset.id}. See \`mono-agent presets list\`.`));
|
|
841
|
+
return preset;
|
|
842
|
+
}
|
|
843
|
+
return undefined;
|
|
844
|
+
}
|
|
845
|
+
/**
|
|
846
|
+
* Capability-aware completeness check: for each capability a preset (or module
|
|
847
|
+
* set) promises, report whether the matching doctor section reached the expected
|
|
848
|
+
* status. `waiting` stays non-fatal (it never changes the validate exit code) but
|
|
849
|
+
* is surfaced as "incomplete" so the operator knows what is left to wire up.
|
|
815
850
|
*/
|
|
816
|
-
function
|
|
817
|
-
let out = "\n" + ui.heading(
|
|
851
|
+
function renderPlanCompleteness(expectations, label, report) {
|
|
852
|
+
let out = "\n" + ui.heading(label);
|
|
818
853
|
let incomplete = 0;
|
|
819
|
-
for (const expectation of
|
|
854
|
+
for (const expectation of expectations) {
|
|
820
855
|
const section = report.sections.find((entry) => entry.id === expectation.sectionId);
|
|
821
856
|
const status = section?.status ?? "missing";
|
|
822
857
|
const met = status === expectation.mustBe;
|
|
@@ -830,8 +865,8 @@ function renderRecipeCompleteness(recipe, report) {
|
|
|
830
865
|
}
|
|
831
866
|
}
|
|
832
867
|
out += incomplete === 0
|
|
833
|
-
? `${ui.style.green(`✓
|
|
834
|
-
: ui.style.yellow(`⚠
|
|
868
|
+
? `${ui.style.green(`✓ ${label} is fully configured.`)}\n`
|
|
869
|
+
: ui.style.yellow(`⚠ ${label} incomplete: ${incomplete} capability(ies) not yet live.\n`);
|
|
835
870
|
return out;
|
|
836
871
|
}
|
|
837
872
|
function riskColor(risk) {
|
|
@@ -843,72 +878,72 @@ function riskColor(risk) {
|
|
|
843
878
|
}
|
|
844
879
|
return ui.style.green(risk);
|
|
845
880
|
}
|
|
846
|
-
/** `mono-agent
|
|
847
|
-
export function
|
|
848
|
-
let out = ui.banner("mono-agent", "
|
|
849
|
-
for (const
|
|
850
|
-
out += `${ui.style.bold(ui.style.cyan(
|
|
851
|
-
out += ` ${
|
|
852
|
-
out += ` ${ui.style.dim(
|
|
853
|
-
}
|
|
854
|
-
out += "\n" + ui.style.dim("Scaffold one with: mono-agent init --
|
|
881
|
+
/** `mono-agent presets list` — one block per preset. */
|
|
882
|
+
export function renderPresetList() {
|
|
883
|
+
let out = ui.banner("mono-agent", "presets") + "\n";
|
|
884
|
+
for (const preset of PRESET_CATALOG) {
|
|
885
|
+
out += `${ui.style.bold(ui.style.cyan(preset.id))} ${ui.style.dim(`[${riskColor(preset.riskLevel)}]`)}\n`;
|
|
886
|
+
out += ` ${preset.title}\n`;
|
|
887
|
+
out += ` ${ui.style.dim(preset.description)}\n`;
|
|
888
|
+
}
|
|
889
|
+
out += "\n" + ui.style.dim("Scaffold one with: mono-agent init --preset <id>\n");
|
|
890
|
+
out += ui.style.dim("Build interactively with: mono-agent init\n");
|
|
855
891
|
return out;
|
|
856
892
|
}
|
|
857
|
-
/** `mono-agent
|
|
858
|
-
export function
|
|
859
|
-
const
|
|
860
|
-
let out = ui.banner("mono-agent", `
|
|
861
|
-
out += `${ui.style.bold(
|
|
862
|
-
out += `${
|
|
863
|
-
if (
|
|
864
|
-
out += ui.style.dim(`Playbook: docs/playbooks/${
|
|
893
|
+
/** `mono-agent presets show <id>` — description, composed JSON, env example, checklist. */
|
|
894
|
+
export function renderPresetShow(preset) {
|
|
895
|
+
const plan = composeWizardPlan(presetAnswers(preset), { dirBasename: "your-agent", skillsRootExists: false });
|
|
896
|
+
let out = ui.banner("mono-agent", `preset: ${preset.id}`) + "\n";
|
|
897
|
+
out += `${ui.style.bold(preset.title)} ${ui.style.dim(`(risk: ${riskColor(preset.riskLevel)})`)}\n`;
|
|
898
|
+
out += `${preset.description}\n`;
|
|
899
|
+
if (preset.playbook !== undefined) {
|
|
900
|
+
out += ui.style.dim(`Playbook: docs/playbooks/${preset.playbook}\n`);
|
|
865
901
|
}
|
|
866
902
|
out += "\n" + ui.heading("Generated mono-agent.config.json");
|
|
867
|
-
out += JSON.stringify(
|
|
868
|
-
const envExample =
|
|
903
|
+
out += JSON.stringify(plan.configJson, null, 2) + "\n";
|
|
904
|
+
const envExample = plan.envExample;
|
|
869
905
|
if (envExample !== undefined && envExample.trim().length > 0) {
|
|
870
906
|
out += "\n" + ui.heading(".env.example");
|
|
871
907
|
out += envExample.endsWith("\n") ? envExample : envExample + "\n";
|
|
872
908
|
}
|
|
873
|
-
|
|
874
|
-
if (files.length > 0) {
|
|
909
|
+
if (plan.files.length > 0) {
|
|
875
910
|
out += "\n" + ui.heading("Scaffolded files");
|
|
876
|
-
for (const file of files) {
|
|
911
|
+
for (const file of plan.files) {
|
|
877
912
|
out += ` ${ui.style.cyan(file.path)}\n`;
|
|
878
913
|
}
|
|
879
914
|
}
|
|
880
|
-
if (
|
|
915
|
+
if (plan.validateExpectations.length > 0) {
|
|
881
916
|
out += "\n" + ui.heading("Follow-up checklist");
|
|
882
|
-
for (const expectation of
|
|
917
|
+
for (const expectation of plan.validateExpectations) {
|
|
883
918
|
const note = expectation.note === undefined ? "" : ` — ${expectation.note}`;
|
|
884
919
|
out += ` ${ui.style.gray("•")} ${expectation.sectionId} ${ui.style.dim(`must be ${expectation.mustBe}`)}${ui.style.dim(note)}\n`;
|
|
885
920
|
}
|
|
886
921
|
}
|
|
887
922
|
return out;
|
|
888
923
|
}
|
|
889
|
-
/** Dispatch `mono-agent
|
|
890
|
-
function
|
|
924
|
+
/** Dispatch `mono-agent presets list|show <id>`. */
|
|
925
|
+
function runPresets(args) {
|
|
891
926
|
const [sub, id] = args.positionals;
|
|
892
927
|
if (sub === undefined || sub === "list") {
|
|
893
|
-
process.stdout.write(
|
|
928
|
+
process.stdout.write(renderPresetList());
|
|
894
929
|
return 0;
|
|
895
930
|
}
|
|
896
931
|
if (sub === "show") {
|
|
897
932
|
if (id === undefined) {
|
|
898
|
-
process.stderr.write(ui.errorLine("Usage: mono-agent
|
|
899
|
-
process.stderr.write(ui.hint(`Available: ${
|
|
933
|
+
process.stderr.write(ui.errorLine("Usage: mono-agent presets show <id>."));
|
|
934
|
+
process.stderr.write(ui.hint(`Available: ${presetIds().join(", ")}.`));
|
|
900
935
|
return 2;
|
|
901
936
|
}
|
|
902
|
-
const
|
|
903
|
-
if (
|
|
904
|
-
process.stderr.write(ui.errorLine(`Unknown
|
|
905
|
-
process.stderr.write(ui.hint("Run
|
|
937
|
+
const preset = findPreset(id);
|
|
938
|
+
if (preset === undefined) {
|
|
939
|
+
process.stderr.write(ui.errorLine(`Unknown preset \`${id}\`.`));
|
|
940
|
+
process.stderr.write(ui.hint(`Available: ${presetIds().join(", ")}. Run \`mono-agent presets list\`.`));
|
|
906
941
|
return 1;
|
|
907
942
|
}
|
|
908
|
-
process.stdout.write(
|
|
943
|
+
process.stdout.write(renderPresetShow(preset));
|
|
909
944
|
return 0;
|
|
910
945
|
}
|
|
911
|
-
process.stderr.write(ui.errorLine(`Unknown
|
|
946
|
+
process.stderr.write(ui.errorLine(`Unknown presets subcommand \`${sub}\`. Expected list or show.`));
|
|
912
947
|
return 2;
|
|
913
948
|
}
|
|
914
949
|
const SOURCE_TAG = {
|