@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 CHANGED
@@ -75,8 +75,9 @@ global installs own `~/.config/opencode` and create its `package.json` when
75
75
  needed. Offline setups can provision the dependency by hand first:
76
76
  `npm install --save-exact @kisev/agentomatic`, then run
77
77
  `npx agentomatic install --dry-run` from that project so the executing version
78
- matches the installed package. Run the exact confirmation command
79
- printed by the preview. If the selected
78
+ matches the installed package. Apply by rerunning the install command without
79
+ `--dry-run` and confirming the printed plan summary, or by adding `--yes`
80
+ outside a terminal. If the selected
80
81
  assets need core integration, connect the package into the user-owned OpenCode
81
82
  configuration yourself or through the confirmed `config` command, which merges
82
83
  the `plugin` entry while preserving existing entries:
package/README.ru.md CHANGED
@@ -79,7 +79,8 @@ npx --yes @kisev/agentomatic@latest install --dry-run
79
79
  `npm install --save-exact @kisev/agentomatic`, затем запустить
80
80
  `npx agentomatic install --dry-run` из этого проекта, чтобы версия исполнения
81
81
  совпадала с установленным пакетом.
82
- Выполните точную команду подтверждения, которую выведет предварительный просмотр.
82
+ Примените изменение, повторив команду установки без `--dry-run` и подтвердив
83
+ напечатанную сводку плана, а вне терминала добавьте `--yes`.
83
84
  Если для выбранных файлов нужна основная интеграция, подключите пакет в
84
85
  пользовательскую конфигурацию OpenCode вручную или подтвержденной командой
85
86
  `config`, которая добавляет запись `plugin` с сохранением существующих записей:
@@ -1,4 +1,4 @@
1
- import { LifecycleError, type SupersededPlan, type FileMutation, type Scope, type TransactionOptions } from "./lifecycle.js";
1
+ import { LifecycleError, type FileMutation, type Scope, type TransactionOptions } from "./lifecycle.js";
2
2
  export { type Scope as AgentProfileScope } from "./lifecycle.js";
3
3
  export declare const FIXED_AGENT_ROLES: readonly ["manager", "architect", "mapper", "worker", "review", "critic"];
4
4
  export type FixedAgentRole = (typeof FIXED_AGENT_ROLES)[number];
@@ -47,7 +47,6 @@ export type AgentInventory = {
47
47
  collisions: string[];
48
48
  drift: string[];
49
49
  requires_restart: false;
50
- digest: string;
51
50
  };
52
51
  export type AgentProfileAction = "install" | "model-set" | "critic-add" | "critic-remove" | "reconcile" | "uninstall";
53
52
  export type AgentProfileRequest = {
@@ -70,11 +69,6 @@ export type AgentProfilePlan = {
70
69
  root: string;
71
70
  operations: AgentProfileOperation[];
72
71
  critic_pool: string[];
73
- plan_digest: string;
74
- confirmation_digest?: string;
75
- superseded_plan?: SupersededPlan;
76
- digest: string;
77
- receipt_expires_at?: string;
78
72
  requires_restart: boolean;
79
73
  };
80
74
  export type AgentProfileResult = {
@@ -101,7 +95,6 @@ export type LegacyAgentOwnership = {
101
95
  type BuiltPlan = {
102
96
  plan: AgentProfilePlan;
103
97
  mutations: FileMutation[];
104
- inventoryDigest: string;
105
98
  config: AgentProfileConfig;
106
99
  manifest?: DeploymentManifest;
107
100
  expectedConfig?: Buffer;
@@ -116,7 +109,7 @@ export declare function buildAgentProfilePlan(request: AgentProfileRequest, scop
116
109
  export declare function validateBuiltAgentProfilePlan(built: BuiltPlan): Promise<void>;
117
110
  export declare function listAgentProfiles(scope: Scope, cwd?: string, home?: string): Promise<AgentInventory>;
118
111
  export declare function previewAgentProfileChange(request: AgentProfileRequest, scope: Scope, cwd?: string, home?: string): Promise<AgentProfilePlan>;
119
- export declare function applyAgentProfileChange(request: AgentProfileRequest, scope: Scope, confirmationDigest: string, cwd?: string, home?: string, options?: TransactionOptions): Promise<AgentProfileResult>;
112
+ export declare function applyAgentProfileChange(request: AgentProfileRequest, scope: Scope, cwd?: string, home?: string, options?: TransactionOptions): Promise<AgentProfileResult>;
120
113
  export declare function availableModels(): Promise<string[]>;
121
114
  export declare function availableModelVariants(model: string): Promise<string[]>;
122
115
  export declare function inspectFileMode(path: string): Promise<number | undefined>;
@@ -4,7 +4,7 @@ import { homedir } from "node:os";
4
4
  import { dirname, resolve } from "node:path";
5
5
  import { promisify } from "node:util";
6
6
  import { fileURLToPath } from "node:url";
7
- import { applyTransaction, consumeReceipt, deploymentRoot, destination, digest, LifecycleError, lifecycleRoot, listDirectRegular, readRegular, recoverTransaction, saveReceipt, sha256, stable, withLifecycleLock, } from "./lifecycle.js";
7
+ import { applyTransaction, deploymentRoot, destination, LifecycleError, lifecycleRoot, listDirectRegular, readRegular, recoverTransaction, sha256, stable, withLifecycleLock, } from "./lifecycle.js";
8
8
  import { readPackageVersion } from "./package-metadata.js";
9
9
  export const FIXED_AGENT_ROLES = [
10
10
  "manager",
@@ -258,7 +258,7 @@ function desiredManifest(scope, config, rendered, canonical, names = desiredName
258
258
  kind: NAME_PATTERN.test(name) ? "fixed" : "additional-critic",
259
259
  template: role,
260
260
  canonical_sha256: sha256(canonical[role]),
261
- configuration_sha256: digest(selection),
261
+ configuration_sha256: sha256(stable(selection)),
262
262
  rendered_sha256: sha256(rendered[name]),
263
263
  };
264
264
  }
@@ -326,9 +326,6 @@ function legacyIsExact(legacy, current) {
326
326
  sha256(content) === record.sha256);
327
327
  });
328
328
  }
329
- function planDigestBase(plan, inventoryDigest, request) {
330
- return digest({ plan, inventory_digest: inventoryDigest, request });
331
- }
332
329
  export async function buildAgentProfilePlan(request, scope, cwd = process.cwd(), home = homedir(), legacy, selectedAgents) {
333
330
  const root = deploymentRoot(scope, cwd, home);
334
331
  const [state, canonical, agentFiles] = await Promise.all([
@@ -512,19 +509,6 @@ export async function buildAgentProfilePlan(request, scope, cwd = process.cwd(),
512
509
  expected: { sha256: sha256(state.manifestRaw) },
513
510
  });
514
511
  }
515
- const inventoryDigest = digest({
516
- package_version: packageVersion(),
517
- canonical: Object.fromEntries(FIXED_AGENT_ROLES.map((role) => [role, sha256(canonical[role])])),
518
- desired_configuration: config,
519
- desired_manifest: finalManifest ?? null,
520
- config: state.configRaw?.toString("base64") ?? null,
521
- manifest: state.manifestRaw?.toString("base64") ?? null,
522
- agents: agentFiles.map((item) => ({
523
- name: item.name,
524
- sha256: sha256(item.content),
525
- mode: item.mode,
526
- })),
527
- });
528
512
  const base = {
529
513
  schema_version: 1,
530
514
  domain: "agent-profiles",
@@ -535,16 +519,12 @@ export async function buildAgentProfilePlan(request, scope, cwd = process.cwd(),
535
519
  critic_pool: desired?.critic_pool ?? finalManifest?.critic_pool ?? [],
536
520
  requires_restart: mutations.some((item) => item.path.startsWith("agents/")),
537
521
  };
538
- const planDigest = planDigestBase(base, inventoryDigest, request);
539
522
  const plan = {
540
523
  ...base,
541
- plan_digest: planDigest,
542
- digest: planDigest,
543
524
  };
544
525
  return {
545
526
  plan,
546
527
  mutations,
547
- inventoryDigest,
548
528
  config,
549
529
  manifest: finalManifest,
550
530
  expectedConfig: names.length ? configContent : state.configRaw,
@@ -648,42 +628,23 @@ export async function listAgentProfiles(scope, cwd = process.cwd(), home = homed
648
628
  drift,
649
629
  requires_restart: false,
650
630
  };
651
- return { ...base, digest: digest(base) };
631
+ return { ...base };
652
632
  }
653
633
  export async function previewAgentProfileChange(request, scope, cwd = process.cwd(), home = homedir()) {
654
634
  const stateRoot = lifecycleRoot(scope, cwd, home);
655
635
  return withLifecycleLock(stateRoot, async () => {
656
636
  if (await recoverTransaction(deploymentRoot(scope, cwd, home), stateRoot))
657
637
  throw new AgentProfileError("recovered_transaction", "Recovered an interrupted transaction; request a fresh plan");
658
- const built = await buildAgentProfilePlan(request, scope, cwd, home);
659
- const receipt = await saveReceipt(stateRoot, `agent:${request.action}`, scope, built.plan.root, { request, plan_digest: built.plan.digest }, Date.now(), built.plan.digest);
660
- return {
661
- ...built.plan,
662
- plan_digest: built.plan.digest,
663
- confirmation_digest: receipt.digest,
664
- digest: receipt.digest,
665
- receipt_expires_at: receipt.expires_at,
666
- ...(receipt.superseded_plan ? { superseded_plan: receipt.superseded_plan } : {}),
667
- };
638
+ return (await buildAgentProfilePlan(request, scope, cwd, home)).plan;
668
639
  });
669
640
  }
670
- export async function applyAgentProfileChange(request, scope, confirmationDigest, cwd = process.cwd(), home = homedir(), options = {}) {
641
+ export async function applyAgentProfileChange(request, scope, cwd = process.cwd(), home = homedir(), options = {}) {
671
642
  const stateRoot = lifecycleRoot(scope, cwd, home);
672
643
  const root = deploymentRoot(scope, cwd, home);
673
644
  return withLifecycleLock(stateRoot, async () => {
674
645
  if (await recoverTransaction(root, stateRoot))
675
646
  throw new AgentProfileError("recovered_transaction", "Recovered an interrupted transaction; request a fresh plan");
676
- const receipt = (await consumeReceipt(stateRoot, {
677
- digest: confirmationDigest,
678
- kind: `agent:${request.action}`,
679
- scope,
680
- root,
681
- }));
682
- if (stable(receipt.request) !== stable(request))
683
- throw new AgentProfileError("confirmation_unknown", "Saved confirmation belongs to a different request");
684
647
  const built = await buildAgentProfilePlan(request, scope, cwd, home);
685
- if (built.plan.digest !== (receipt.plan_digest ?? receipt.digest))
686
- throw new AgentProfileError("stale_plan", "Agent inventory changed after preview");
687
648
  if (built.plan.operations.some((item) => item.operation === "conflict" && item.reason.includes("collision")))
688
649
  throw new AgentProfileError("collision", "Exact-name user-owned collision blocks apply");
689
650
  if (request.action !== "uninstall" &&
@@ -710,7 +671,7 @@ export async function applyAgentProfileChange(request, scope, confirmationDigest
710
671
  status: "ok",
711
672
  applied: true,
712
673
  requires_restart: built.plan.requires_restart,
713
- plan: { ...built.plan, digest: confirmationDigest },
674
+ plan: built.plan,
714
675
  };
715
676
  });
716
677
  }
@@ -8,12 +8,12 @@ type DisplayPlan = InstallerPlan | AgentProfilePlan;
8
8
  export declare function terminalSafe(value: string): string;
9
9
  export declare function renderPlan(plan: DisplayPlan, options: {
10
10
  applied: boolean;
11
- confirmationCommand?: string;
11
+ applyHint?: string;
12
12
  hint?: string;
13
13
  }): string;
14
14
  export declare function renderConfigSetup(plan: ConfigSetupPlan, options: {
15
15
  applied: boolean;
16
- confirmationCommand?: string;
16
+ applyHint?: string;
17
17
  hint?: string;
18
18
  }): string;
19
19
  export declare function renderInventory(inventory: AgentInventory): string;
@@ -21,7 +21,7 @@ export declare function shellCommand(arguments_: readonly string[]): string;
21
21
  export declare function scopeArguments(scope: Scope): [] | ["--global"];
22
22
  export declare function renderReconcile(plan: ReconcilePlan, options: {
23
23
  applied: boolean;
24
- confirmationCommand?: string;
24
+ applyHint?: string;
25
25
  }): string;
26
26
  export declare function renderDoctor(report: DoctorReport): string;
27
27
  export {};
@@ -119,20 +119,8 @@ export function renderPlan(plan, options) {
119
119
  lines.push(options.applied
120
120
  ? `Restart required: ${plan.requires_restart ? "yes" : "no"}`
121
121
  : `Restart after apply: ${plan.requires_restart ? "yes" : "no"}`);
122
- if (!options.applied) {
123
- if (plan.superseded_plan)
124
- lines.push("", "Superseded plan:", ` kind: ${terminalSafe(plan.superseded_plan.kind)}`, ` confirmation: ${terminalSafe(plan.superseded_plan.confirmation_digest)}`, ` created: ${terminalSafe(plan.superseded_plan.created_at)}`, ` expires: ${terminalSafe(plan.superseded_plan.expires_at)}`);
125
- if (plan.receipt_expires_at)
126
- lines.push(`Confirmation expires: ${plan.receipt_expires_at}`);
127
- if ("plan_digest" in plan)
128
- lines.push(`Plan digest: ${plan.plan_digest}`);
129
- if (plan.confirmation_digest ?? plan.digest) {
130
- lines.push(`Confirmation digest: ${plan.confirmation_digest ?? plan.digest}`);
131
- lines.push(`Digest: ${plan.confirmation_digest ?? plan.digest}`);
132
- }
133
- if (options.confirmationCommand)
134
- lines.push("", "Apply:", ` ${options.confirmationCommand}`);
135
- }
122
+ if (!options.applied && options.applyHint)
123
+ lines.push("", "Apply:", ` ${options.applyHint}`);
136
124
  if (options.applied && options.hint)
137
125
  lines.push("", "Next:", ` ${options.hint}`);
138
126
  return `${lines.join("\n")}\n`;
@@ -159,20 +147,10 @@ export function renderConfigSetup(plan, options) {
159
147
  ? `Restart required: ${plan.requires_restart ? "yes" : "no"}`
160
148
  : `Restart after apply: ${plan.requires_restart ? "yes" : "no"}`);
161
149
  if (!options.applied) {
162
- if (!plan.confirmable) {
150
+ if (!plan.confirmable)
163
151
  lines.push("", "No configuration changes are required.");
164
- }
165
- else {
166
- if (plan.superseded_plan)
167
- lines.push("", "Superseded plan:", ` kind: ${terminalSafe(plan.superseded_plan.kind)}`, ` confirmation: ${terminalSafe(plan.superseded_plan.confirmation_digest)}`, ` created: ${terminalSafe(plan.superseded_plan.created_at)}`, ` expires: ${terminalSafe(plan.superseded_plan.expires_at)}`);
168
- lines.push("", `Plan digest: ${plan.plan_digest}`);
169
- if (plan.receipt_expires_at)
170
- lines.push(`Confirmation expires: ${plan.receipt_expires_at}`);
171
- if (plan.confirmation_digest ?? plan.digest)
172
- lines.push(`Confirmation digest: ${plan.confirmation_digest ?? plan.digest}`, `Digest: ${plan.confirmation_digest ?? plan.digest}`);
173
- if (options.confirmationCommand)
174
- lines.push("", "Apply:", ` ${options.confirmationCommand}`);
175
- }
152
+ else if (options.applyHint)
153
+ lines.push("", "Apply:", ` ${options.applyHint}`);
176
154
  }
177
155
  if (options.applied && options.hint)
178
156
  lines.push("", "Next:", ` ${options.hint}`);
@@ -251,22 +229,15 @@ export function renderReconcile(plan, options) {
251
229
  if (blocked) {
252
230
  lines.push("", "Blocked:");
253
231
  if (plan.modified_managed.length)
254
- lines.push(` Update managed assets first: ${shellCommand(["install", ...scopeArguments(plan.scope), "--dry-run"])}`, " Apply the exact confirmation command from that installer preview, then build a new reconcile preview.");
232
+ lines.push(` Update managed assets first: ${shellCommand(["install", ...scopeArguments(plan.scope), "--dry-run"])}`, " Apply that installer plan, then build a new reconcile preview.");
255
233
  if (plan.conflicts.length)
256
234
  lines.push(" Manually resolve every ownership conflict listed above before reconciling.");
257
235
  }
258
236
  else if (!plan.confirmable) {
259
237
  lines.push("", "No reconciliation changes are required.");
260
238
  }
261
- else if (options.confirmationCommand) {
262
- if (plan.superseded_plan)
263
- lines.push("", "Superseded plan:", ` kind: ${terminalSafe(plan.superseded_plan.kind)}`, ` confirmation: ${terminalSafe(plan.superseded_plan.confirmation_digest)}`, ` created: ${terminalSafe(plan.superseded_plan.created_at)}`, ` expires: ${terminalSafe(plan.superseded_plan.expires_at)}`);
264
- lines.push("", `Plan digest: ${plan.plan_digest}`);
265
- if (plan.receipt_expires_at)
266
- lines.push(`Confirmation expires: ${plan.receipt_expires_at}`);
267
- if (plan.confirmation_digest ?? plan.digest)
268
- lines.push(`Confirmation digest: ${plan.confirmation_digest ?? plan.digest}`, `Digest: ${plan.confirmation_digest ?? plan.digest}`);
269
- lines.push("", "Apply:", ` ${options.confirmationCommand}`);
239
+ else if (options.applyHint) {
240
+ lines.push("", "Apply:", ` ${options.applyHint}`);
270
241
  }
271
242
  }
272
243
  return `${lines.join("\n")}\n`;