@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/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.
|
|
79
|
-
|
|
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` с сохранением существующих записей:
|
package/dist/agent-profiles.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LifecycleError, type
|
|
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,
|
|
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>;
|
package/dist/agent-profiles.js
CHANGED
|
@@ -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,
|
|
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:
|
|
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
|
|
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
|
-
|
|
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,
|
|
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:
|
|
674
|
+
plan: built.plan,
|
|
714
675
|
};
|
|
715
676
|
});
|
|
716
677
|
}
|
package/dist/cli-output.d.ts
CHANGED
|
@@ -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
|
-
|
|
11
|
+
applyHint?: string;
|
|
12
12
|
hint?: string;
|
|
13
13
|
}): string;
|
|
14
14
|
export declare function renderConfigSetup(plan: ConfigSetupPlan, options: {
|
|
15
15
|
applied: boolean;
|
|
16
|
-
|
|
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
|
-
|
|
24
|
+
applyHint?: string;
|
|
25
25
|
}): string;
|
|
26
26
|
export declare function renderDoctor(report: DoctorReport): string;
|
|
27
27
|
export {};
|
package/dist/cli-output.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
|
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.
|
|
262
|
-
|
|
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`;
|