@kisev/agentomatic 11.0.0-dev.54.g26e86b0b9fcd → 11.0.0-dev.55.g6d90f51aeff6
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 +3 -2
- package/README.ru.md +2 -1
- package/dist/agent-profiles.d.ts +2 -9
- package/dist/agent-profiles.js +6 -45
- package/dist/cli-output.d.ts +3 -3
- package/dist/cli-output.js +8 -37
- package/dist/cli.js +96 -75
- package/dist/config-setup.d.ts +2 -7
- package/dist/config-setup.js +5 -23
- package/dist/installer.d.ts +2 -7
- package/dist/installer.js +4 -25
- package/dist/lifecycle.d.ts +0 -21
- package/dist/lifecycle.js +1 -196
- package/dist/reconcile.d.ts +2 -7
- package/dist/reconcile.js +5 -30
- package/package.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -15,6 +15,7 @@ function parseOptions(values) {
|
|
|
15
15
|
global: false,
|
|
16
16
|
dryRun: false,
|
|
17
17
|
json: false,
|
|
18
|
+
yes: false,
|
|
18
19
|
selectionFlag: false,
|
|
19
20
|
};
|
|
20
21
|
for (let index = 0; index < values.length; index += 1) {
|
|
@@ -35,12 +36,10 @@ function parseOptions(values) {
|
|
|
35
36
|
throw new InstallerError("invalid_input", "--dry-run may be supplied once");
|
|
36
37
|
options.dryRun = true;
|
|
37
38
|
}
|
|
38
|
-
else if (value === "--
|
|
39
|
-
if (options.
|
|
40
|
-
throw new InstallerError("invalid_input", "--
|
|
41
|
-
options.
|
|
42
|
-
if (!options.confirm)
|
|
43
|
-
throw new InstallerError("invalid_input", "--confirm requires a digest");
|
|
39
|
+
else if (value === "--yes") {
|
|
40
|
+
if (options.yes)
|
|
41
|
+
throw new InstallerError("invalid_input", "--yes may be supplied once");
|
|
42
|
+
options.yes = true;
|
|
44
43
|
}
|
|
45
44
|
else if (value === "--provider") {
|
|
46
45
|
options.provider = values[++index];
|
|
@@ -150,8 +149,8 @@ function rootHelp() {
|
|
|
150
149
|
"Common options:",
|
|
151
150
|
...helpRows([
|
|
152
151
|
["--global", "Use global scope; project scope is the default."],
|
|
153
|
-
["--dry-run", "Preview a mutation
|
|
154
|
-
["--
|
|
152
|
+
["--dry-run", "Preview a mutation without changing anything."],
|
|
153
|
+
["--yes", "Apply without the interactive final confirmation (required outside a terminal)."],
|
|
155
154
|
["--json", "Emit stable machine-readable output when supported."],
|
|
156
155
|
["--help", "Show this help and exit."],
|
|
157
156
|
["--version", "Show the package version and exit."],
|
|
@@ -180,8 +179,9 @@ function rootHelp() {
|
|
|
180
179
|
"",
|
|
181
180
|
"Safe mutation workflow:",
|
|
182
181
|
" 1. Run the command with --dry-run.",
|
|
183
|
-
" 2. Review the target, operations, conflicts, restart requirement
|
|
184
|
-
" 3. Run the
|
|
182
|
+
" 2. Review the target, operations, conflicts, and restart requirement.",
|
|
183
|
+
" 3. Run the command without --dry-run; confirm the summary when asked",
|
|
184
|
+
" (add --yes to skip the question or to apply outside a terminal).",
|
|
185
185
|
" 4. Restart OpenCode when the applied plan requires it.",
|
|
186
186
|
" install and uninstall never edit opencode.json; the config command is the",
|
|
187
187
|
" confirmed path for configuration fragments. No command installs portable skills.",
|
|
@@ -258,11 +258,11 @@ function contextualHelp(arguments_) {
|
|
|
258
258
|
if (domain === "install")
|
|
259
259
|
return commandHelp("install", "Select and deploy package-owned OpenCode integration assets.", [
|
|
260
260
|
"agentomatic install [--global] --dry-run [selection options]",
|
|
261
|
-
"agentomatic install [--global] --
|
|
261
|
+
"agentomatic install [--global] [--dry-run | --yes] [selection options]",
|
|
262
262
|
], [
|
|
263
263
|
["--global", "Use global scope; project scope is the default."],
|
|
264
|
-
["--dry-run", "Preview operations
|
|
265
|
-
["--
|
|
264
|
+
["--dry-run", "Preview operations without changing anything."],
|
|
265
|
+
["--yes", "Apply without the interactive final confirmation."],
|
|
266
266
|
["--no-dependency", "Skip provisioning the persistent npm dependency for the core plugin."],
|
|
267
267
|
["--commands <list|none>", "Select installed-skill adapters."],
|
|
268
268
|
["--skill-commands <list|none>", "Select installed-skill adapters."],
|
|
@@ -292,11 +292,11 @@ function contextualHelp(arguments_) {
|
|
|
292
292
|
if (domain === "config")
|
|
293
293
|
return commandHelp("config", "Connect the package and recommended fragments into user configuration files.", [
|
|
294
294
|
"agentomatic config [--global] --dry-run [selection options]",
|
|
295
|
-
"agentomatic config [--global] --
|
|
295
|
+
"agentomatic config [--global] [--dry-run | --yes] [selection options]",
|
|
296
296
|
], [
|
|
297
297
|
["--global", "Use global scope; project scope is the default."],
|
|
298
|
-
["--dry-run", "Preview config operations
|
|
299
|
-
["--
|
|
298
|
+
["--dry-run", "Preview config operations without changing anything."],
|
|
299
|
+
["--yes", "Apply without the interactive final confirmation."],
|
|
300
300
|
["--targets <list|none>", `Select targets: ${CONFIG_TARGETS.join(", ")}.`],
|
|
301
301
|
[
|
|
302
302
|
"--fragments <list|none>",
|
|
@@ -325,11 +325,11 @@ function contextualHelp(arguments_) {
|
|
|
325
325
|
if (domain === "uninstall")
|
|
326
326
|
return commandHelp("uninstall", "Remove package-owned integration assets safely.", [
|
|
327
327
|
"agentomatic uninstall [--global] --dry-run",
|
|
328
|
-
"agentomatic uninstall [--global] --
|
|
328
|
+
"agentomatic uninstall [--global] [--dry-run | --yes]",
|
|
329
329
|
], [
|
|
330
330
|
["--global", "Use global scope; project scope is the default."],
|
|
331
331
|
["--dry-run", "Preview removals, archives, and conflicts."],
|
|
332
|
-
["--
|
|
332
|
+
["--yes", "Apply without the interactive final confirmation."],
|
|
333
333
|
["--json", "Emit stable machine-readable output."],
|
|
334
334
|
["--help", "Show this command help and exit."],
|
|
335
335
|
], [
|
|
@@ -361,11 +361,11 @@ function contextualHelp(arguments_) {
|
|
|
361
361
|
if (domain === "reconcile")
|
|
362
362
|
return commandHelp("reconcile", "Classify current and historical assets and retire exact-owned entries.", [
|
|
363
363
|
"agentomatic reconcile [--global] --dry-run",
|
|
364
|
-
"agentomatic reconcile [--global] --
|
|
364
|
+
"agentomatic reconcile [--global] [--dry-run | --yes]",
|
|
365
365
|
], [
|
|
366
366
|
["--global", "Reconcile global scope; project scope is the default."],
|
|
367
367
|
["--dry-run", "Preview classifications, archives, and blockers."],
|
|
368
|
-
["--
|
|
368
|
+
["--yes", "Apply without the interactive final confirmation."],
|
|
369
369
|
["--json", "Emit stable machine-readable output."],
|
|
370
370
|
["--help", "Show this command help and exit."],
|
|
371
371
|
], [
|
|
@@ -386,7 +386,7 @@ function contextualHelp(arguments_) {
|
|
|
386
386
|
return commandHelp("agent configure", "Choose an agent model interactively or with explicit options.", [
|
|
387
387
|
"agentomatic agent configure [name] [--global] --dry-run",
|
|
388
388
|
"agentomatic agent configure <name> [--global] --model <provider/model> [--variant <id>] --dry-run",
|
|
389
|
-
"agentomatic agent configure <name> [--global] --model <provider/model> [--variant <id>] --
|
|
389
|
+
"agentomatic agent configure <name> [--global] --model <provider/model> [--variant <id>] [--dry-run | --yes]",
|
|
390
390
|
], [
|
|
391
391
|
["--global", "Use global scope; project scope is the default."],
|
|
392
392
|
["--provider <id>", "Provider when --model is not provider/model."],
|
|
@@ -394,7 +394,7 @@ function contextualHelp(arguments_) {
|
|
|
394
394
|
["--variant <id>", "Set an optional model variant."],
|
|
395
395
|
["--clear-variant", "Remove the configured variant."],
|
|
396
396
|
["--dry-run", "Preview the profile change."],
|
|
397
|
-
["--
|
|
397
|
+
["--yes", "Apply without the interactive final confirmation."],
|
|
398
398
|
["--json", "Emit stable machine-readable output."],
|
|
399
399
|
["--help", "Show this command help and exit."],
|
|
400
400
|
], [
|
|
@@ -418,7 +418,7 @@ function contextualHelp(arguments_) {
|
|
|
418
418
|
if (domain === "agent" && operation === "model-set")
|
|
419
419
|
return commandHelp("agent model-set", "Set one agent model and optional variant directly.", [
|
|
420
420
|
"agentomatic agent model-set <name> [--global] --model <provider/model> [--variant <id>] --dry-run",
|
|
421
|
-
"agentomatic agent model-set <name> [--global] --model <provider/model> [--variant <id>] --
|
|
421
|
+
"agentomatic agent model-set <name> [--global] --model <provider/model> [--variant <id>] [--dry-run | --yes]",
|
|
422
422
|
], [
|
|
423
423
|
["--global", "Use global scope; project scope is the default."],
|
|
424
424
|
["--provider <id>", "Provider when --model is not provider/model."],
|
|
@@ -426,7 +426,7 @@ function contextualHelp(arguments_) {
|
|
|
426
426
|
["--variant <id>", "Set an optional model variant."],
|
|
427
427
|
["--clear-variant", "Remove the configured variant."],
|
|
428
428
|
["--dry-run", "Preview the profile change."],
|
|
429
|
-
["--
|
|
429
|
+
["--yes", "Apply without the interactive final confirmation."],
|
|
430
430
|
["--json", "Emit stable machine-readable output."],
|
|
431
431
|
["--help", "Show this command help and exit."],
|
|
432
432
|
], [
|
|
@@ -459,11 +459,11 @@ function contextualHelp(arguments_) {
|
|
|
459
459
|
if (domain === "agent" && operation === "reconcile")
|
|
460
460
|
return commandHelp("agent reconcile", "Re-render managed agent files from saved profile configuration.", [
|
|
461
461
|
"agentomatic agent reconcile [--global] --dry-run",
|
|
462
|
-
"agentomatic agent reconcile [--global] --
|
|
462
|
+
"agentomatic agent reconcile [--global] [--dry-run | --yes]",
|
|
463
463
|
], [
|
|
464
464
|
["--global", "Use global scope; project scope is the default."],
|
|
465
465
|
["--dry-run", "Preview rendered agent changes and conflicts."],
|
|
466
|
-
["--
|
|
466
|
+
["--yes", "Apply without the interactive final confirmation."],
|
|
467
467
|
["--json", "Emit stable machine-readable output."],
|
|
468
468
|
["--help", "Show this command help and exit."],
|
|
469
469
|
], [
|
|
@@ -488,14 +488,14 @@ function contextualHelp(arguments_) {
|
|
|
488
488
|
return commandHelp("critic add", "Add an additional named critic with a selected model.", [
|
|
489
489
|
"agentomatic critic add [name] [--global] --dry-run",
|
|
490
490
|
"agentomatic critic add <name> [--global] --model <provider/model> [--variant <id>] --dry-run",
|
|
491
|
-
"agentomatic critic add <name> [--global] --model <provider/model> [--variant <id>] --
|
|
491
|
+
"agentomatic critic add <name> [--global] --model <provider/model> [--variant <id>] [--dry-run | --yes]",
|
|
492
492
|
], [
|
|
493
493
|
["--global", "Use global scope; project scope is the default."],
|
|
494
494
|
["--provider <id>", "Provider when --model is not provider/model."],
|
|
495
495
|
["--model <id>", "Exact provider/model or model paired with --provider."],
|
|
496
496
|
["--variant <id>", "Set an optional model variant."],
|
|
497
497
|
["--dry-run", "Preview critic creation and pool changes."],
|
|
498
|
-
["--
|
|
498
|
+
["--yes", "Apply without the interactive final confirmation."],
|
|
499
499
|
["--json", "Emit stable machine-readable output."],
|
|
500
500
|
["--help", "Show this command help and exit."],
|
|
501
501
|
], [
|
|
@@ -517,11 +517,11 @@ function contextualHelp(arguments_) {
|
|
|
517
517
|
if (domain === "critic" && operation === "remove")
|
|
518
518
|
return commandHelp("critic remove", "Remove a package-managed additional critic.", [
|
|
519
519
|
"agentomatic critic remove <name> [--global] --dry-run",
|
|
520
|
-
"agentomatic critic remove <name> [--global] --
|
|
520
|
+
"agentomatic critic remove <name> [--global] [--dry-run | --yes]",
|
|
521
521
|
], [
|
|
522
522
|
["--global", "Use global scope; project scope is the default."],
|
|
523
523
|
["--dry-run", "Preview critic removal and pool changes."],
|
|
524
|
-
["--
|
|
524
|
+
["--yes", "Apply without the interactive final confirmation."],
|
|
525
525
|
["--json", "Emit stable machine-readable output."],
|
|
526
526
|
["--help", "Show this command help and exit."],
|
|
527
527
|
], [
|
|
@@ -631,9 +631,22 @@ function selectionArguments(selection) {
|
|
|
631
631
|
selection.plugins.join(",") || "none",
|
|
632
632
|
];
|
|
633
633
|
}
|
|
634
|
-
function
|
|
635
|
-
|
|
636
|
-
|
|
634
|
+
function interactiveTerminal() {
|
|
635
|
+
return Boolean(process.stdin.isTTY && process.stderr.isTTY);
|
|
636
|
+
}
|
|
637
|
+
function requireApplyMode(options) {
|
|
638
|
+
if (options.dryRun && options.yes)
|
|
639
|
+
throw new InstallerError("invalid_input", "Use either --dry-run or --yes, not both");
|
|
640
|
+
if (!options.dryRun && !options.yes && !interactiveTerminal())
|
|
641
|
+
throw new InstallerError("invalid_input", "Applying outside a terminal requires --yes; use --dry-run to preview");
|
|
642
|
+
}
|
|
643
|
+
async function confirmSummary() {
|
|
644
|
+
const choice = await selectOption("Apply these changes?", ["Yes", "No"]);
|
|
645
|
+
if (choice !== 0)
|
|
646
|
+
throw new InstallerError("cancelled", "Cancelled before apply");
|
|
647
|
+
}
|
|
648
|
+
function applyHint(command) {
|
|
649
|
+
return `${shellCommand(command)} (confirm interactively; add --yes outside a terminal)`;
|
|
637
650
|
}
|
|
638
651
|
function exactModel(options) {
|
|
639
652
|
if (!options.model)
|
|
@@ -773,7 +786,7 @@ async function interactiveSelection(options, action = "model-set") {
|
|
|
773
786
|
}
|
|
774
787
|
}
|
|
775
788
|
async function runProfile(request, options) {
|
|
776
|
-
|
|
789
|
+
requireApplyMode(options);
|
|
777
790
|
if (options.dryRun) {
|
|
778
791
|
const plan = await previewAgentProfileChange(request, options.scope);
|
|
779
792
|
if (options.json)
|
|
@@ -781,22 +794,27 @@ async function runProfile(request, options) {
|
|
|
781
794
|
else
|
|
782
795
|
process.stdout.write(renderPlan(plan, {
|
|
783
796
|
applied: false,
|
|
784
|
-
|
|
797
|
+
applyHint: applyHint(profileApplyArguments(request, options.scope)),
|
|
785
798
|
}));
|
|
786
799
|
}
|
|
787
800
|
else {
|
|
788
|
-
|
|
801
|
+
if (!options.yes) {
|
|
802
|
+
const plan = await previewAgentProfileChange(request, options.scope);
|
|
803
|
+
process.stdout.write(renderPlan(plan, { applied: false }));
|
|
804
|
+
await confirmSummary();
|
|
805
|
+
}
|
|
806
|
+
const applied = await applyAgentProfileChange(request, options.scope);
|
|
789
807
|
if (options.json)
|
|
790
808
|
process.stdout.write(`${JSON.stringify(applied, null, 2)}\n`);
|
|
791
809
|
else
|
|
792
810
|
process.stdout.write(renderPlan(applied.plan, { applied: true }));
|
|
793
811
|
}
|
|
794
812
|
}
|
|
795
|
-
function
|
|
813
|
+
function profileApplyArguments(request, scope) {
|
|
796
814
|
if (request.action === "reconcile")
|
|
797
|
-
return ["agent", "reconcile", ...scopeArguments(scope)
|
|
815
|
+
return ["agent", "reconcile", ...scopeArguments(scope)];
|
|
798
816
|
if (request.action === "critic-remove")
|
|
799
|
-
return ["critic", "remove", request.name, ...scopeArguments(scope)
|
|
817
|
+
return ["critic", "remove", request.name, ...scopeArguments(scope)];
|
|
800
818
|
const command = request.action === "critic-add"
|
|
801
819
|
? ["critic", "add", request.name]
|
|
802
820
|
: ["agent", "model-set", request.name];
|
|
@@ -805,7 +823,6 @@ function profileConfirmationArguments(request, scope, digest) {
|
|
|
805
823
|
command.push("--variant", request.variant);
|
|
806
824
|
else if (request.action === "model-set")
|
|
807
825
|
command.push("--clear-variant");
|
|
808
|
-
command.push("--confirm", digest);
|
|
809
826
|
return command;
|
|
810
827
|
}
|
|
811
828
|
async function run(arguments_) {
|
|
@@ -850,7 +867,7 @@ async function run(arguments_) {
|
|
|
850
867
|
rest.unshift(operation);
|
|
851
868
|
const options = parseOptions(rest);
|
|
852
869
|
if (options.dryRun ||
|
|
853
|
-
options.
|
|
870
|
+
options.yes ||
|
|
854
871
|
options.name ||
|
|
855
872
|
options.provider ||
|
|
856
873
|
options.model ||
|
|
@@ -870,7 +887,7 @@ async function run(arguments_) {
|
|
|
870
887
|
rest.unshift(operation);
|
|
871
888
|
const options = parseOptions(rest);
|
|
872
889
|
if (options.dryRun ||
|
|
873
|
-
options.
|
|
890
|
+
options.yes ||
|
|
874
891
|
options.name ||
|
|
875
892
|
options.provider ||
|
|
876
893
|
options.model ||
|
|
@@ -890,8 +907,8 @@ async function run(arguments_) {
|
|
|
890
907
|
options.model ||
|
|
891
908
|
options.variant !== undefined ||
|
|
892
909
|
options.selectionFlag)
|
|
893
|
-
throw new InstallerError("invalid_input", "reconcile accepts only --global, --dry-run, --
|
|
894
|
-
|
|
910
|
+
throw new InstallerError("invalid_input", "reconcile accepts only --global, --dry-run, --yes, and --json");
|
|
911
|
+
requireApplyMode(options);
|
|
895
912
|
if (options.dryRun) {
|
|
896
913
|
const plan = await previewReconcile(options.scope);
|
|
897
914
|
if (options.json)
|
|
@@ -899,18 +916,18 @@ async function run(arguments_) {
|
|
|
899
916
|
else
|
|
900
917
|
process.stdout.write(renderReconcile(plan, {
|
|
901
918
|
applied: false,
|
|
902
|
-
|
|
903
|
-
?
|
|
904
|
-
"reconcile",
|
|
905
|
-
...scopeArguments(options.scope),
|
|
906
|
-
"--confirm",
|
|
907
|
-
plan.confirmation_digest ?? plan.digest,
|
|
908
|
-
])
|
|
919
|
+
applyHint: plan.confirmable
|
|
920
|
+
? applyHint(["reconcile", ...scopeArguments(options.scope)])
|
|
909
921
|
: undefined,
|
|
910
922
|
}));
|
|
911
923
|
}
|
|
912
924
|
else {
|
|
913
|
-
|
|
925
|
+
if (!options.yes) {
|
|
926
|
+
const plan = await previewReconcile(options.scope);
|
|
927
|
+
process.stdout.write(renderReconcile(plan, { applied: false }));
|
|
928
|
+
await confirmSummary();
|
|
929
|
+
}
|
|
930
|
+
const applied = await applyReconcile(options.scope);
|
|
914
931
|
if (options.json)
|
|
915
932
|
process.stdout.write(`${JSON.stringify(applied, null, 2)}\n`);
|
|
916
933
|
else
|
|
@@ -932,7 +949,7 @@ async function run(arguments_) {
|
|
|
932
949
|
(action === "uninstall" && options.selectionFlag))
|
|
933
950
|
throw new InstallerError("invalid_input", action === "install"
|
|
934
951
|
? "install does not accept model options or positional arguments"
|
|
935
|
-
: "uninstall accepts only --global, --dry-run, --
|
|
952
|
+
: "uninstall accepts only --global, --dry-run, --yes, and --json");
|
|
936
953
|
if (action === "install" &&
|
|
937
954
|
options.selectionFlag &&
|
|
938
955
|
(options.commands === undefined ||
|
|
@@ -944,7 +961,7 @@ async function run(arguments_) {
|
|
|
944
961
|
? installerSelection(options)
|
|
945
962
|
: await interactiveInstallerSelection()
|
|
946
963
|
: undefined;
|
|
947
|
-
|
|
964
|
+
requireApplyMode(options);
|
|
948
965
|
if (options.dryRun) {
|
|
949
966
|
const plan = await preview(action, options.scope, process.cwd(), undefined, selection, !options.noDependency);
|
|
950
967
|
if (options.json)
|
|
@@ -952,18 +969,21 @@ async function run(arguments_) {
|
|
|
952
969
|
else
|
|
953
970
|
process.stdout.write(renderPlan(plan, {
|
|
954
971
|
applied: false,
|
|
955
|
-
|
|
972
|
+
applyHint: applyHint([
|
|
956
973
|
action,
|
|
957
974
|
...scopeArguments(options.scope),
|
|
958
975
|
...(action === "install" ? selectionArguments(plan.selection) : []),
|
|
959
976
|
...(options.noDependency ? ["--no-dependency"] : []),
|
|
960
|
-
"--confirm",
|
|
961
|
-
plan.digest,
|
|
962
977
|
]),
|
|
963
978
|
}));
|
|
964
979
|
}
|
|
965
980
|
else {
|
|
966
|
-
|
|
981
|
+
if (!options.yes) {
|
|
982
|
+
const plan = await preview(action, options.scope, process.cwd(), undefined, selection, !options.noDependency);
|
|
983
|
+
process.stdout.write(renderPlan(plan, { applied: false }));
|
|
984
|
+
await confirmSummary();
|
|
985
|
+
}
|
|
986
|
+
const plan = await apply(action, options.scope, process.cwd(), undefined, {}, selection, !options.noDependency);
|
|
967
987
|
if (options.json)
|
|
968
988
|
process.stdout.write(`${JSON.stringify({ status: "ok", applied: true, requires_restart: plan.requires_restart, plan }, null, 2)}\n`);
|
|
969
989
|
else
|
|
@@ -981,7 +1001,7 @@ async function run(arguments_) {
|
|
|
981
1001
|
if (domain === "agent" && operation === "list") {
|
|
982
1002
|
const options = parseOptions(rest);
|
|
983
1003
|
if (options.dryRun ||
|
|
984
|
-
options.
|
|
1004
|
+
options.yes ||
|
|
985
1005
|
options.name ||
|
|
986
1006
|
options.provider ||
|
|
987
1007
|
options.model ||
|
|
@@ -999,7 +1019,7 @@ async function run(arguments_) {
|
|
|
999
1019
|
const options = parseOptions(rest);
|
|
1000
1020
|
if (options.selectionFlag)
|
|
1001
1021
|
throw new InstallerError("invalid_input", "agent configure does not accept selection options");
|
|
1002
|
-
|
|
1022
|
+
requireApplyMode(options);
|
|
1003
1023
|
const model = exactModel(options);
|
|
1004
1024
|
const selected = options.name && model
|
|
1005
1025
|
? {
|
|
@@ -1031,7 +1051,7 @@ async function run(arguments_) {
|
|
|
1031
1051
|
options.model ||
|
|
1032
1052
|
options.variant !== undefined ||
|
|
1033
1053
|
options.selectionFlag)
|
|
1034
|
-
throw new InstallerError("invalid_input", "agent reconcile accepts only --global, --dry-run, --
|
|
1054
|
+
throw new InstallerError("invalid_input", "agent reconcile accepts only --global, --dry-run, --yes, and --json");
|
|
1035
1055
|
await runProfile({ action: "reconcile" }, options);
|
|
1036
1056
|
return;
|
|
1037
1057
|
}
|
|
@@ -1082,14 +1102,14 @@ async function run(arguments_) {
|
|
|
1082
1102
|
options.commands !== undefined ||
|
|
1083
1103
|
options.agents !== undefined ||
|
|
1084
1104
|
options.plugins !== undefined)
|
|
1085
|
-
throw new InstallerError("invalid_input", "config accepts only --global, --targets, --fragments, --dry-run, --
|
|
1105
|
+
throw new InstallerError("invalid_input", "config accepts only --global, --targets, --fragments, --dry-run, --yes, and --json");
|
|
1086
1106
|
if (options.selectionFlag &&
|
|
1087
1107
|
(options.configTargets === undefined || options.configFragments === undefined))
|
|
1088
1108
|
throw new InstallerError("invalid_input", "Non-TTY config requires both --targets and --fragments");
|
|
1089
1109
|
const selection = options.selectionFlag
|
|
1090
1110
|
? normalizeConfigSelection(options.scope, configSelectionFromOptions(options))
|
|
1091
1111
|
: await interactiveConfigSelection(options);
|
|
1092
|
-
|
|
1112
|
+
requireApplyMode(options);
|
|
1093
1113
|
if (options.dryRun) {
|
|
1094
1114
|
const plan = await previewConfigSetup(selection, options.scope);
|
|
1095
1115
|
if (options.json)
|
|
@@ -1097,21 +1117,22 @@ async function run(arguments_) {
|
|
|
1097
1117
|
else
|
|
1098
1118
|
process.stdout.write(renderConfigSetup(plan, {
|
|
1099
1119
|
applied: false,
|
|
1100
|
-
|
|
1101
|
-
?
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
plan.confirmation_digest ?? plan.digest,
|
|
1108
|
-
]),
|
|
1109
|
-
}
|
|
1110
|
-
: {}),
|
|
1120
|
+
applyHint: plan.confirmable
|
|
1121
|
+
? applyHint([
|
|
1122
|
+
"config",
|
|
1123
|
+
...scopeArguments(options.scope),
|
|
1124
|
+
...configSelectionArguments(plan.selection),
|
|
1125
|
+
])
|
|
1126
|
+
: undefined,
|
|
1111
1127
|
}));
|
|
1112
1128
|
}
|
|
1113
1129
|
else {
|
|
1114
|
-
|
|
1130
|
+
if (!options.yes) {
|
|
1131
|
+
const plan = await previewConfigSetup(selection, options.scope);
|
|
1132
|
+
process.stdout.write(renderConfigSetup(plan, { applied: false }));
|
|
1133
|
+
await confirmSummary();
|
|
1134
|
+
}
|
|
1135
|
+
const plan = await applyConfigSetup(selection, options.scope);
|
|
1115
1136
|
if (options.json)
|
|
1116
1137
|
process.stdout.write(`${JSON.stringify({ status: "ok", applied: true, requires_restart: plan.requires_restart, plan }, null, 2)}\n`);
|
|
1117
1138
|
else
|
package/dist/config-setup.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LifecycleError, type Scope
|
|
1
|
+
import { LifecycleError, type Scope } from "./lifecycle.js";
|
|
2
2
|
export declare class ConfigSetupError extends LifecycleError {
|
|
3
3
|
}
|
|
4
4
|
export declare const CONFIG_TARGETS: readonly ["opencode", "tui", "kilo", "mimo"];
|
|
@@ -57,15 +57,10 @@ export type ConfigSetupPlan = {
|
|
|
57
57
|
fragment: FragmentName;
|
|
58
58
|
reason: string;
|
|
59
59
|
}>;
|
|
60
|
-
plan_digest: string;
|
|
61
|
-
digest: string;
|
|
62
|
-
confirmation_digest?: string;
|
|
63
|
-
receipt_expires_at?: string;
|
|
64
|
-
superseded_plan?: SupersededPlan;
|
|
65
60
|
requires_restart: boolean;
|
|
66
61
|
confirmable: boolean;
|
|
67
62
|
};
|
|
68
63
|
export declare function normalizeConfigSelection(scope: Scope, value?: Partial<ConfigSetupSelection>): ConfigSetupSelection;
|
|
69
64
|
export declare function defaultConfigSelection(scope: Scope, cwd?: string, home?: string): Promise<ConfigSetupSelection>;
|
|
70
65
|
export declare function previewConfigSetup(selection: ConfigSetupSelection, scope: Scope, cwd?: string, home?: string): Promise<ConfigSetupPlan>;
|
|
71
|
-
export declare function applyConfigSetup(selection: ConfigSetupSelection, scope: Scope,
|
|
66
|
+
export declare function applyConfigSetup(selection: ConfigSetupSelection, scope: Scope, cwd?: string, home?: string): Promise<ConfigSetupPlan>;
|
package/dist/config-setup.js
CHANGED
|
@@ -3,7 +3,7 @@ import { homedir } from "node:os";
|
|
|
3
3
|
import { dirname, join, resolve } from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { requirePackageVersion } from "./package-metadata.js";
|
|
6
|
-
import { applyTransaction,
|
|
6
|
+
import { applyTransaction, deploymentRoot, LifecycleError, lifecycleRoot, readRegular, recoverTransaction, sha256, withLifecycleLock, } from "./lifecycle.js";
|
|
7
7
|
import { applyJsoncEdits, parseJsonc } from "./jsonc.js";
|
|
8
8
|
const PACKAGE_NAME = "@kisev/agentomatic";
|
|
9
9
|
const LEGACY_PACKAGE_NAME = "@kisev/skills-opencode";
|
|
@@ -360,9 +360,8 @@ async function build(selection, scope, cwd = process.cwd(), home = homedir()) {
|
|
|
360
360
|
requires_restart: sorted.some((item) => item.operation === "create" || item.operation === "update"),
|
|
361
361
|
confirmable: mutations.length > 0,
|
|
362
362
|
};
|
|
363
|
-
const planDigest = digest(base);
|
|
364
363
|
return {
|
|
365
|
-
plan: { ...base
|
|
364
|
+
plan: { ...base },
|
|
366
365
|
mutations,
|
|
367
366
|
allowedRoots: [...allowedRoots],
|
|
368
367
|
};
|
|
@@ -375,16 +374,7 @@ export async function previewConfigSetup(selection, scope, cwd = process.cwd(),
|
|
|
375
374
|
const built = await build(selection, scope, cwd, home);
|
|
376
375
|
if (await recoverTransaction(root, stateRoot, built.allowedRoots))
|
|
377
376
|
throw new ConfigSetupError("recovered_transaction", "Recovered an interrupted transaction; request a fresh plan");
|
|
378
|
-
|
|
379
|
-
return built.plan;
|
|
380
|
-
const receipt = await saveReceipt(stateRoot, "config-setup", scope, root, { plan_digest: built.plan.plan_digest }, Date.now(), built.plan.plan_digest);
|
|
381
|
-
return {
|
|
382
|
-
...built.plan,
|
|
383
|
-
digest: receipt.digest,
|
|
384
|
-
confirmation_digest: receipt.digest,
|
|
385
|
-
receipt_expires_at: receipt.expires_at,
|
|
386
|
-
...(receipt.superseded_plan ? { superseded_plan: receipt.superseded_plan } : {}),
|
|
387
|
-
};
|
|
377
|
+
return built.plan;
|
|
388
378
|
});
|
|
389
379
|
}
|
|
390
380
|
catch (error) {
|
|
@@ -395,7 +385,7 @@ export async function previewConfigSetup(selection, scope, cwd = process.cwd(),
|
|
|
395
385
|
throw error;
|
|
396
386
|
}
|
|
397
387
|
}
|
|
398
|
-
export async function applyConfigSetup(selection, scope,
|
|
388
|
+
export async function applyConfigSetup(selection, scope, cwd = process.cwd(), home = homedir()) {
|
|
399
389
|
const stateRoot = lifecycleRoot(scope, cwd, home);
|
|
400
390
|
const root = deploymentRoot(scope, cwd, home);
|
|
401
391
|
try {
|
|
@@ -403,14 +393,6 @@ export async function applyConfigSetup(selection, scope, confirmationDigest, cwd
|
|
|
403
393
|
const built = await build(selection, scope, cwd, home);
|
|
404
394
|
if (await recoverTransaction(root, stateRoot, built.allowedRoots))
|
|
405
395
|
throw new ConfigSetupError("recovered_transaction", "Recovered an interrupted transaction; request a fresh plan");
|
|
406
|
-
const receipt = (await consumeReceipt(stateRoot, {
|
|
407
|
-
digest: confirmationDigest,
|
|
408
|
-
kind: "config-setup",
|
|
409
|
-
scope,
|
|
410
|
-
root,
|
|
411
|
-
}));
|
|
412
|
-
if (built.plan.plan_digest !== (receipt.plan_digest ?? digest(receipt)))
|
|
413
|
-
throw new ConfigSetupError("stale_plan", "Config setup plan changed after preview");
|
|
414
396
|
if (!built.plan.confirmable)
|
|
415
397
|
throw new ConfigSetupError("invalid_state", "Config setup plan has no applicable changes");
|
|
416
398
|
await applyTransaction(root, stateRoot, built.mutations, {
|
|
@@ -425,7 +407,7 @@ export async function applyConfigSetup(selection, scope, confirmationDigest, cwd
|
|
|
425
407
|
}
|
|
426
408
|
},
|
|
427
409
|
});
|
|
428
|
-
return
|
|
410
|
+
return built.plan;
|
|
429
411
|
});
|
|
430
412
|
}
|
|
431
413
|
catch (error) {
|
package/dist/installer.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LifecycleError, type FileMutation, type Scope, type
|
|
1
|
+
import { LifecycleError, type FileMutation, type Scope, type TransactionOptions } from "./lifecycle.js";
|
|
2
2
|
import { CATALOG } from "./catalog.js";
|
|
3
3
|
import { type FixedAgentRole } from "./agent-profiles.js";
|
|
4
4
|
import { type DependencyPlan, type DependencyRunner } from "./self-install.js";
|
|
@@ -29,11 +29,6 @@ export type Plan = {
|
|
|
29
29
|
dependency?: DependencyPlan & {
|
|
30
30
|
applied?: "changed" | "unchanged" | "skipped";
|
|
31
31
|
};
|
|
32
|
-
plan_digest: string;
|
|
33
|
-
confirmation_digest?: string;
|
|
34
|
-
superseded_plan?: SupersededPlan;
|
|
35
|
-
digest: string;
|
|
36
|
-
receipt_expires_at?: string;
|
|
37
32
|
requires_restart: boolean;
|
|
38
33
|
};
|
|
39
34
|
type ManifestFile = {
|
|
@@ -56,7 +51,7 @@ export declare class InstallerError extends LifecycleError {
|
|
|
56
51
|
}
|
|
57
52
|
export declare function archiveMutations(candidates: readonly ArchiveCandidate[], scope: Scope, cwd: string, home: string, sourceVersion: string): Promise<FileMutation[]>;
|
|
58
53
|
export declare function preview(action: Action, scope: Scope, cwd?: string, home?: string, selection?: Partial<InstallerSelection>, provisionDependency?: boolean): Promise<Plan>;
|
|
59
|
-
export declare function apply(action: Action, scope: Scope,
|
|
54
|
+
export declare function apply(action: Action, scope: Scope, cwd?: string, home?: string, options?: TransactionOptions & {
|
|
60
55
|
dependencyRunner?: DependencyRunner;
|
|
61
56
|
}, selection?: Partial<InstallerSelection>, provisionDependency?: boolean): Promise<Plan>;
|
|
62
57
|
export declare function result(plan: Plan, applied: boolean): string;
|
package/dist/installer.js
CHANGED
|
@@ -4,7 +4,7 @@ import { homedir } from "node:os";
|
|
|
4
4
|
import { dirname, join, resolve } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
import { buildAgentProfilePlan, listAgentProfiles, validateBuiltAgentProfilePlan, } from "./agent-profiles.js";
|
|
7
|
-
import { applyTransaction, archiveRoot,
|
|
7
|
+
import { applyTransaction, archiveRoot, deploymentRoot, destination, LifecycleError, lifecycleRoot, migrateLegacyDeploymentNamespace, migrateLegacyNamespaces, readRegular, recoverTransaction, sha256, stable, withLifecycleLock, } from "./lifecycle.js";
|
|
8
8
|
import { CATALOG } from "./catalog.js";
|
|
9
9
|
import { FIXED_AGENT_ROLES } from "./agent-profiles.js";
|
|
10
10
|
import { readPackageVersion } from "./package-metadata.js";
|
|
@@ -627,9 +627,8 @@ async function build(action, scope, cwd = process.cwd(), home = homedir(), reque
|
|
|
627
627
|
item.path.startsWith("commands/") ||
|
|
628
628
|
item.path.startsWith("plugins/")),
|
|
629
629
|
};
|
|
630
|
-
const planDigest = digest(base);
|
|
631
630
|
return {
|
|
632
|
-
plan: { ...base
|
|
631
|
+
plan: { ...base },
|
|
633
632
|
mutations,
|
|
634
633
|
expectedManifest: manifestContent,
|
|
635
634
|
profiles,
|
|
@@ -645,16 +644,7 @@ export async function preview(action, scope, cwd = process.cwd(), home = homedir
|
|
|
645
644
|
return await withLifecycleLock(stateRoot, async () => {
|
|
646
645
|
if (await recoverTransaction(root, stateRoot, [archiveRoot(scope, cwd, home)]))
|
|
647
646
|
throw new InstallerError("recovered_transaction", "Recovered an interrupted transaction; request a fresh plan");
|
|
648
|
-
|
|
649
|
-
const receipt = await saveReceipt(stateRoot, `installer:${action}`, scope, root, { plan_digest: built.plan.digest }, Date.now(), built.plan.digest);
|
|
650
|
-
return {
|
|
651
|
-
...built.plan,
|
|
652
|
-
plan_digest: built.plan.digest,
|
|
653
|
-
confirmation_digest: receipt.digest,
|
|
654
|
-
digest: receipt.digest,
|
|
655
|
-
receipt_expires_at: receipt.expires_at,
|
|
656
|
-
...(receipt.superseded_plan ? { superseded_plan: receipt.superseded_plan } : {}),
|
|
657
|
-
};
|
|
647
|
+
return (await build(action, scope, cwd, home, selection, provisionDependency)).plan;
|
|
658
648
|
});
|
|
659
649
|
}
|
|
660
650
|
catch (error) {
|
|
@@ -665,7 +655,7 @@ export async function preview(action, scope, cwd = process.cwd(), home = homedir
|
|
|
665
655
|
throw error;
|
|
666
656
|
}
|
|
667
657
|
}
|
|
668
|
-
export async function apply(action, scope,
|
|
658
|
+
export async function apply(action, scope, cwd = process.cwd(), home = homedir(), options = {}, selection, provisionDependency = true) {
|
|
669
659
|
const { dependencyRunner, ...transactionOptions } = options;
|
|
670
660
|
const stateRoot = lifecycleRoot(scope, cwd, home);
|
|
671
661
|
const root = deploymentRoot(scope, cwd, home);
|
|
@@ -675,17 +665,7 @@ export async function apply(action, scope, confirmationDigest, cwd = process.cwd
|
|
|
675
665
|
await migrateLegacyDeploymentNamespace(root);
|
|
676
666
|
if (await recoverTransaction(root, stateRoot, [archiveRoot(scope, cwd, home)]))
|
|
677
667
|
throw new InstallerError("recovered_transaction", "Recovered an interrupted transaction; request a fresh plan");
|
|
678
|
-
const receipt = (await consumeReceipt(stateRoot, {
|
|
679
|
-
digest: confirmationDigest,
|
|
680
|
-
kind: `installer:${action}`,
|
|
681
|
-
scope,
|
|
682
|
-
root,
|
|
683
|
-
}));
|
|
684
668
|
const built = await build(action, scope, cwd, home, selection, provisionDependency);
|
|
685
|
-
const savedPlanDigest = receipt.plan_digest ??
|
|
686
|
-
receipt.digest;
|
|
687
|
-
if (built.plan.digest !== savedPlanDigest)
|
|
688
|
-
throw new InstallerError("stale_plan", "Installer plan changed after preview");
|
|
689
669
|
if (built.plan.operations.some((item) => item.operation === "conflict" &&
|
|
690
670
|
(item.reason === "unmanaged_file" ||
|
|
691
671
|
item.reason === "v1.0.0_agent_ownership_mismatch" ||
|
|
@@ -719,7 +699,6 @@ export async function apply(action, scope, confirmationDigest, cwd = process.cwd
|
|
|
719
699
|
: undefined;
|
|
720
700
|
return {
|
|
721
701
|
...built.plan,
|
|
722
|
-
digest: confirmationDigest,
|
|
723
702
|
...(dependencyOutcome ? { dependency: dependencyOutcome } : {}),
|
|
724
703
|
};
|
|
725
704
|
});
|