@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/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 === "--confirm") {
39
- if (options.confirm)
40
- throw new InstallerError("invalid_input", "--confirm may be supplied once");
41
- options.confirm = values[++index];
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 and issue a one-time confirmation digest."],
154
- ["--confirm <digest>", "Apply the exact unexpired preview after final revalidation."],
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, and expiry.",
184
- " 3. Run the exact Apply command printed by the preview before it expires.",
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] --confirm <digest> [selection options]",
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 and issue a one-time confirmation digest."],
265
- ["--confirm <digest>", "Apply the exact unexpired preview."],
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] --confirm <digest> [selection options]",
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 and issue a one-time confirmation digest."],
299
- ["--confirm <digest>", "Apply the exact unexpired preview."],
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] --confirm <digest>",
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
- ["--confirm <digest>", "Apply the exact unexpired preview."],
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] --confirm <digest>",
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
- ["--confirm <digest>", "Apply the exact unexpired preview."],
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>] --confirm <digest>",
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
- ["--confirm <digest>", "Apply the exact unexpired preview."],
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>] --confirm <digest>",
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
- ["--confirm <digest>", "Apply the exact unexpired preview."],
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] --confirm <digest>",
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
- ["--confirm <digest>", "Apply the exact unexpired preview."],
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>] --confirm <digest>",
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
- ["--confirm <digest>", "Apply the exact unexpired preview."],
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] --confirm <digest>",
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
- ["--confirm <digest>", "Apply the exact unexpired preview."],
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 requireConfirmationMode(options) {
635
- if (options.dryRun === Boolean(options.confirm))
636
- throw new InstallerError("invalid_input", "Use exactly one of --dry-run or --confirm <digest>");
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
- requireConfirmationMode(options);
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
- confirmationCommand: shellCommand(profileConfirmationArguments(request, options.scope, plan.digest)),
797
+ applyHint: applyHint(profileApplyArguments(request, options.scope)),
785
798
  }));
786
799
  }
787
800
  else {
788
- const applied = await applyAgentProfileChange(request, options.scope, options.confirm);
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 profileConfirmationArguments(request, scope, digest) {
813
+ function profileApplyArguments(request, scope) {
796
814
  if (request.action === "reconcile")
797
- return ["agent", "reconcile", ...scopeArguments(scope), "--confirm", digest];
815
+ return ["agent", "reconcile", ...scopeArguments(scope)];
798
816
  if (request.action === "critic-remove")
799
- return ["critic", "remove", request.name, ...scopeArguments(scope), "--confirm", digest];
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.confirm ||
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.confirm ||
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, --confirm, and --json");
894
- requireConfirmationMode(options);
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
- confirmationCommand: plan.confirmable
903
- ? shellCommand([
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
- const applied = await applyReconcile(options.scope, options.confirm);
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, --confirm, and --json");
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
- requireConfirmationMode(options);
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
- confirmationCommand: shellCommand([
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
- const plan = await apply(action, options.scope, options.confirm, process.cwd(), undefined, {}, selection, !options.noDependency);
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.confirm ||
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
- requireConfirmationMode(options);
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, --confirm, and --json");
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, --confirm, and --json");
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
- requireConfirmationMode(options);
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
- ...(plan.confirmable
1101
- ? {
1102
- confirmationCommand: shellCommand([
1103
- "config",
1104
- ...scopeArguments(options.scope),
1105
- ...configSelectionArguments(plan.selection),
1106
- "--confirm",
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
- const plan = await applyConfigSetup(selection, options.scope, options.confirm);
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
@@ -1,4 +1,4 @@
1
- import { LifecycleError, type Scope, type SupersededPlan } from "./lifecycle.js";
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, confirmationDigest: string, cwd?: string, home?: string): Promise<ConfigSetupPlan>;
66
+ export declare function applyConfigSetup(selection: ConfigSetupSelection, scope: Scope, cwd?: string, home?: string): Promise<ConfigSetupPlan>;
@@ -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, consumeReceipt, deploymentRoot, digest, LifecycleError, lifecycleRoot, readRegular, recoverTransaction, saveReceipt, sha256, withLifecycleLock, } from "./lifecycle.js";
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, plan_digest: planDigest, digest: planDigest },
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
- if (!built.plan.confirmable)
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, confirmationDigest, cwd = process.cwd(), home = homedir()) {
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 { ...built.plan, digest: confirmationDigest };
410
+ return built.plan;
429
411
  });
430
412
  }
431
413
  catch (error) {
@@ -1,4 +1,4 @@
1
- import { LifecycleError, type FileMutation, type Scope, type SupersededPlan, type TransactionOptions } from "./lifecycle.js";
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, confirmationDigest: string, cwd?: string, home?: string, options?: TransactionOptions & {
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, consumeReceipt, deploymentRoot, destination, digest, LifecycleError, lifecycleRoot, migrateLegacyDeploymentNamespace, migrateLegacyNamespaces, readRegular, recoverTransaction, saveReceipt, sha256, stable, withLifecycleLock, } from "./lifecycle.js";
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, plan_digest: planDigest, digest: planDigest },
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
- const built = await build(action, scope, cwd, home, selection, provisionDependency);
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, confirmationDigest, cwd = process.cwd(), home = homedir(), options = {}, selection, provisionDependency = true) {
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
  });