@kylecheng3146/agent-ops 0.1.12 → 0.1.13
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.
|
@@ -6,6 +6,7 @@ import { formatOperationPlan } from "../plan-output.js";
|
|
|
6
6
|
import { toPublicInstallPlan } from "../public-plan.js";
|
|
7
7
|
export function formatInstallPlan(plan) {
|
|
8
8
|
const hooks = plan.manifest.hooks ?? [];
|
|
9
|
+
const detectedVerification = plan.detectedVerification;
|
|
9
10
|
return formatOperationPlan({
|
|
10
11
|
title: "Installation plan",
|
|
11
12
|
metadata: [
|
|
@@ -17,6 +18,12 @@ export function formatInstallPlan(plan) {
|
|
|
17
18
|
: [
|
|
18
19
|
"Hooks:",
|
|
19
20
|
...hooks.map((hook) => ` - ${hook.harness}: ${hook.path} (${hook.events.join(", ")})`)
|
|
21
|
+
]),
|
|
22
|
+
...(detectedVerification.length === 0
|
|
23
|
+
? []
|
|
24
|
+
: [
|
|
25
|
+
"Detected verifiers (review before confirming):",
|
|
26
|
+
...detectedVerification.map((command) => ` - ${command.id}: ${command.command} ${command.args.join(" ")}`.trimEnd())
|
|
20
27
|
])
|
|
21
28
|
],
|
|
22
29
|
operations: toPublicInstallPlan(plan).operations
|
|
@@ -3,6 +3,7 @@ import { okEnvelope } from "../output.js";
|
|
|
3
3
|
import { formatOperationPlan } from "../plan-output.js";
|
|
4
4
|
import { toPublicUpdatePlan } from "../public-plan.js";
|
|
5
5
|
export function formatUpdatePlan(plan) {
|
|
6
|
+
const detectedVerification = plan.installation.detectedVerification;
|
|
6
7
|
return formatOperationPlan({
|
|
7
8
|
title: "Update plan",
|
|
8
9
|
metadata: [
|
|
@@ -12,7 +13,13 @@ export function formatUpdatePlan(plan) {
|
|
|
12
13
|
? "none"
|
|
13
14
|
: plan.migrationSteps
|
|
14
15
|
.map(({ fromVersion, toVersion }) => `${fromVersion} -> ${toVersion}`)
|
|
15
|
-
.join(", ")}
|
|
16
|
+
.join(", ")}`,
|
|
17
|
+
...(detectedVerification.length === 0
|
|
18
|
+
? []
|
|
19
|
+
: [
|
|
20
|
+
"Detected verifiers (review before confirming):",
|
|
21
|
+
...detectedVerification.map((command) => ` - ${command.id}: ${command.command} ${command.args.join(" ")}`.trimEnd())
|
|
22
|
+
])
|
|
16
23
|
],
|
|
17
24
|
operations: toPublicUpdatePlan(plan).installation.operations
|
|
18
25
|
});
|
|
@@ -42,7 +42,8 @@ export function toPublicInstallPlan(plan) {
|
|
|
42
42
|
profiles: plan.profiles,
|
|
43
43
|
capabilities: plan.capabilities,
|
|
44
44
|
manifest: plan.manifest,
|
|
45
|
-
operations: toPublicOperations(plan.operations)
|
|
45
|
+
operations: toPublicOperations(plan.operations),
|
|
46
|
+
detectedVerification: plan.detectedVerification
|
|
46
47
|
};
|
|
47
48
|
}
|
|
48
49
|
export function toPublicUpdatePlan(plan) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { lstat, readFile } from "node:fs/promises";
|
|
2
2
|
import { CONFIG_SCHEMA_VERSION, MANIFEST_SCHEMA_VERSION } from "../contracts.js";
|
|
3
|
+
import { discoverProject } from "../discovery/index.js";
|
|
3
4
|
import { sha256 } from "../fs/hash.js";
|
|
4
5
|
import { applyManagedBlock, managedBlockMarkers, removeManagedBlock } from "../fs/managed-block.js";
|
|
5
6
|
import { formatInstallManifest, parseInstallManifest } from "../fs/manifest.js";
|
|
@@ -40,16 +41,50 @@ async function readCurrentFile(root, path) {
|
|
|
40
41
|
throw error;
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Converts a stack-detected verifier proposal into a verification command.
|
|
46
|
+
* Proposal IDs use a colon-separated namespace (e.g. "node:test"); config
|
|
47
|
+
* IDs must be kebab-case identifiers.
|
|
48
|
+
*/
|
|
49
|
+
function verificationCommandFromProposal(proposal) {
|
|
50
|
+
return {
|
|
51
|
+
id: proposal.id.replace(/:/g, "-"),
|
|
52
|
+
command: proposal.command,
|
|
53
|
+
args: proposal.args,
|
|
54
|
+
cwd: proposal.cwd,
|
|
55
|
+
required: proposal.required,
|
|
56
|
+
evidence: proposal.evidence
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Verification commands are never invented for a project that already
|
|
61
|
+
* declares them; detection only fills the gap while the field is empty, so
|
|
62
|
+
* a deliberate "remove all verifiers" edit is not silently reversed by a
|
|
63
|
+
* different stack adapter next run.
|
|
64
|
+
*/
|
|
65
|
+
async function detectVerificationCommands(root) {
|
|
66
|
+
const discovery = await discoverProject(root);
|
|
67
|
+
if (discovery.kind !== "project") {
|
|
68
|
+
return [];
|
|
69
|
+
}
|
|
70
|
+
return discovery.proposals
|
|
71
|
+
.filter((proposal) => proposal.confidence === "high")
|
|
72
|
+
.map(verificationCommandFromProposal);
|
|
73
|
+
}
|
|
74
|
+
function formatConfig(profiles, existing, reviewTargets = [], detectedCommands = []) {
|
|
44
75
|
// Absent reviewRoles means external review is disabled; an empty selection
|
|
45
76
|
// must therefore omit the field rather than write an empty array.
|
|
46
77
|
const reviewRoles = reviewTargets.length > 0
|
|
47
78
|
? [{ role: "independent-review", targets: [...reviewTargets] }]
|
|
48
79
|
: existing?.reviewRoles;
|
|
80
|
+
const verification = existing?.verification !== undefined &&
|
|
81
|
+
existing.verification.commands.length > 0
|
|
82
|
+
? existing.verification
|
|
83
|
+
: { commands: detectedCommands };
|
|
49
84
|
return `${JSON.stringify({
|
|
50
85
|
schemaVersion: CONFIG_SCHEMA_VERSION,
|
|
51
86
|
profiles,
|
|
52
|
-
verification
|
|
87
|
+
verification,
|
|
53
88
|
features: existing?.features ?? {
|
|
54
89
|
stopVerification: {
|
|
55
90
|
enabled: false
|
|
@@ -92,7 +127,11 @@ async function planConfig(root, profiles, existingManifest, suppliedConfig, revi
|
|
|
92
127
|
}
|
|
93
128
|
existingConfig = result.value;
|
|
94
129
|
}
|
|
95
|
-
const
|
|
130
|
+
const detectedCommands = existingConfig === undefined ||
|
|
131
|
+
existingConfig.verification.commands.length === 0
|
|
132
|
+
? await detectVerificationCommands(root)
|
|
133
|
+
: [];
|
|
134
|
+
const content = formatConfig(profiles, existingConfig, reviewTargets, detectedCommands);
|
|
96
135
|
return {
|
|
97
136
|
operation: {
|
|
98
137
|
kind: "write",
|
|
@@ -105,7 +144,8 @@ async function planConfig(root, profiles, existingManifest, suppliedConfig, revi
|
|
|
105
144
|
path: CONFIG_PATH,
|
|
106
145
|
hash: sha256(content),
|
|
107
146
|
owner: "agent-ops"
|
|
108
|
-
}
|
|
147
|
+
},
|
|
148
|
+
detectedVerification: detectedCommands
|
|
109
149
|
};
|
|
110
150
|
}
|
|
111
151
|
function pathKey(path) {
|
|
@@ -528,6 +568,7 @@ export async function createInstallPlan(options) {
|
|
|
528
568
|
profiles: resolved.profiles,
|
|
529
569
|
capabilities: resolved.capabilities,
|
|
530
570
|
manifest,
|
|
531
|
-
operations
|
|
571
|
+
operations,
|
|
572
|
+
detectedVerification: config.detectedVerification
|
|
532
573
|
};
|
|
533
574
|
}
|