aienvmp 0.1.64 → 0.1.66
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/CHANGELOG.md +20 -0
- package/README.md +2 -1
- package/package.json +1 -1
- package/src/actions.js +1 -1
- package/src/cli.js +1 -1
- package/src/commands/resolve.js +35 -7
- package/src/render.js +13 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.66
|
|
4
|
+
|
|
5
|
+
- Added `aienvmp resolve --target <target>` to resolve all open intents for one environment target.
|
|
6
|
+
- Added `aienvmp resolve --all` to close all open intents after coordination.
|
|
7
|
+
- Added `resolve --json` output so AI agents can read resolved refs and counts directly.
|
|
8
|
+
- Kept single-intent `resolve --id` behavior for precise manual cleanup.
|
|
9
|
+
- Updated coordination recommended actions to point at target-based resolve.
|
|
10
|
+
- Updated CLI help and README command guidance for the simplified resolve flow.
|
|
11
|
+
- Added regression tests for target resolve, all resolve, JSON output, and coordination action commands.
|
|
12
|
+
|
|
13
|
+
## 0.1.65
|
|
14
|
+
|
|
15
|
+
- Added a dashboard `Next command` bar directly below the AI control strip.
|
|
16
|
+
- Chose the dashboard next command from preflight, top recommended action, collaboration, then status fallback.
|
|
17
|
+
- Added a short reason beside the next command so humans and AI agents know why it is suggested.
|
|
18
|
+
- Made the next command bar responsive and wrap long commands safely.
|
|
19
|
+
- Kept detailed recommended actions below the first-read dashboard area.
|
|
20
|
+
- Updated README wording to mention the single next command.
|
|
21
|
+
- Added dashboard regression coverage for next-command source and reason binding.
|
|
22
|
+
|
|
3
23
|
## 0.1.64
|
|
4
24
|
|
|
5
25
|
- Added a dashboard `AI control strip` above the existing audit area.
|
package/README.md
CHANGED
|
@@ -52,7 +52,7 @@ AIENV.md # Markdown env map for AI agents
|
|
|
52
52
|
- `status.json.nextAgent` tells the next AI what to read and whether to review first.
|
|
53
53
|
- `aiReadiness` gives a one-field ready/review signal for AI continuation.
|
|
54
54
|
- `collaboration` gives the shortest multi-agent env-change status, targets, and next command.
|
|
55
|
-
- `dashboard.html` starts with a 3-card AI control strip
|
|
55
|
+
- `dashboard.html` starts with a 3-card AI control strip plus one next command.
|
|
56
56
|
- `dependencyReadSet` lists manifests and lockfiles before package or security changes.
|
|
57
57
|
- `sbomRisk` gives AI a compact light-SBOM risk level, signals, and next command.
|
|
58
58
|
- `sbom.json.aiDependencyReview` connects SBOM risk, scanner confidence, and safe dependency-change steps.
|
|
@@ -94,6 +94,7 @@ aienvmp schema --json # stable output contract for AI/CI consumers
|
|
|
94
94
|
aienvmp plan --write # read-only action plan
|
|
95
95
|
aienvmp handoff --record # next-agent summary
|
|
96
96
|
aienvmp intent # record planned env change
|
|
97
|
+
aienvmp resolve --target dependency --actor agent:id
|
|
97
98
|
aienvmp record # record what changed
|
|
98
99
|
aienvmp checkpoint # record + sync + status + handoff after env change
|
|
99
100
|
aienvmp doctor --strict security|policy|coordination|all
|
package/package.json
CHANGED
package/src/actions.js
CHANGED
|
@@ -12,7 +12,7 @@ export function recommendedActions(manifest = {}, context = {}) {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
if (warnings.some((warning) => warning.code === "conflicting-open-intents")) {
|
|
15
|
-
actions.push(action("coordinate-agents", "high", "coordination", "Multiple agents are planning changes to the same environment target. Coordinate with the user before proceeding."));
|
|
15
|
+
actions.push(action("coordinate-agents", "high", "coordination", "Multiple agents are planning changes to the same environment target. Coordinate with the user before proceeding.", "aienvmp resolve --actor agent:id --target <target> --status resolved"));
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
if (warnings.some((warning) => warning.code === "multi-agent-records")) {
|
package/src/cli.js
CHANGED
|
@@ -137,7 +137,7 @@ Advanced:
|
|
|
137
137
|
aienvmp init [--dir .]
|
|
138
138
|
aienvmp scan [--dir .] [--deep] [--security]
|
|
139
139
|
aienvmp intent [--dir .] --actor agent:codex --action "install pnpm"
|
|
140
|
-
aienvmp resolve [--dir .] --actor human:you --id <intent-id
|
|
140
|
+
aienvmp resolve [--dir .] --actor human:you (--id <intent-id>|--target dependency|--all) [--status resolved|cancelled] [--json]
|
|
141
141
|
aienvmp record [--dir .] --actor agent:codex --summary "updated .nvmrc" [--target node] [--before 20] [--after 24]
|
|
142
142
|
aienvmp checkpoint [--dir .] --actor agent:codex --summary "updated dependency" [--target dependency]
|
|
143
143
|
aienvmp snippet [agents|codex|claude|gemini] [--write AGENTS.md]
|
package/src/commands/resolve.js
CHANGED
|
@@ -5,18 +5,32 @@ import { intentsPath, workspaceDir } from "../paths.js";
|
|
|
5
5
|
export async function resolveWorkspace(args) {
|
|
6
6
|
const dir = workspaceDir(args);
|
|
7
7
|
const actor = required(args.actor, "actor");
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
at:
|
|
8
|
+
const refs = await resolveIntentRefs(dir, args);
|
|
9
|
+
const now = new Date().toISOString();
|
|
10
|
+
const entries = refs.map((ref) => ({
|
|
11
|
+
at: now,
|
|
12
12
|
type: "intent-resolved",
|
|
13
13
|
actor,
|
|
14
14
|
ref,
|
|
15
15
|
status: args.status || "resolved",
|
|
16
16
|
reason: args.reason || ""
|
|
17
|
+
}));
|
|
18
|
+
for (const entry of entries) {
|
|
19
|
+
await appendJsonLine(intentsPath(dir), entry);
|
|
20
|
+
}
|
|
21
|
+
const output = {
|
|
22
|
+
status: args.status || "resolved",
|
|
23
|
+
count: entries.length,
|
|
24
|
+
refs,
|
|
25
|
+
actor,
|
|
26
|
+
reason: args.reason || ""
|
|
17
27
|
};
|
|
18
|
-
|
|
19
|
-
|
|
28
|
+
if (args.json) {
|
|
29
|
+
console.log(JSON.stringify(output, null, 2));
|
|
30
|
+
} else if (!args.quiet) {
|
|
31
|
+
console.log(`intents ${output.status}: ${output.count}${refs.length ? ` (${refs.join(", ")})` : ""}`);
|
|
32
|
+
}
|
|
33
|
+
return output;
|
|
20
34
|
}
|
|
21
35
|
|
|
22
36
|
function required(value, name) {
|
|
@@ -24,8 +38,22 @@ function required(value, name) {
|
|
|
24
38
|
return String(value);
|
|
25
39
|
}
|
|
26
40
|
|
|
27
|
-
async function
|
|
41
|
+
async function resolveIntentRefs(dir, args) {
|
|
28
42
|
const open = openIntents(await readJsonl(intentsPath(dir)));
|
|
43
|
+
if (args.all) return open.map((intent) => intent.id);
|
|
44
|
+
if (args.target) {
|
|
45
|
+
const target = String(args.target).trim().toLowerCase();
|
|
46
|
+
const refs = open
|
|
47
|
+
.filter((intent) => String(intent.target || "").trim().toLowerCase() === target)
|
|
48
|
+
.map((intent) => intent.id);
|
|
49
|
+
if (!refs.length) throw new Error(`resolve: no open intents for target "${target}"`);
|
|
50
|
+
return refs;
|
|
51
|
+
}
|
|
52
|
+
const requested = required(args.id || args.ref, "id");
|
|
53
|
+
return [await resolveIntentRef(open, requested)];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function resolveIntentRef(open, requested) {
|
|
29
57
|
const matches = open.filter((intent) => intent.id === requested || intent.id.startsWith(requested));
|
|
30
58
|
if (matches.length === 1) return matches[0].id;
|
|
31
59
|
if (matches.length > 1) {
|
package/src/render.js
CHANGED
|
@@ -388,6 +388,10 @@ h1,h2,h3,p{margin:0}h1{font-size:clamp(28px,4vw,46px);line-height:1.02;margin-to
|
|
|
388
388
|
.control-label{color:var(--muted);font-size:12px;font-weight:800;text-transform:uppercase;letter-spacing:.08em}
|
|
389
389
|
.control-value{margin-top:8px;font-size:24px;font-weight:850;color:var(--text);overflow-wrap:anywhere}
|
|
390
390
|
.control-next{margin-top:8px;color:var(--muted);font-size:12px;line-height:1.4;overflow-wrap:anywhere}
|
|
391
|
+
.nextbar{display:grid;grid-template-columns:auto 1fr auto;gap:12px;align-items:center;border:1px solid rgba(71,229,141,.34);background:rgba(13,24,21,.96);border-radius:8px;padding:13px 15px;margin:-2px 0 14px}
|
|
392
|
+
.nextbar b{color:var(--green);font-size:12px;text-transform:uppercase;letter-spacing:.08em}
|
|
393
|
+
.nextbar code{display:inline-block;max-width:100%;white-space:normal;overflow-wrap:anywhere}
|
|
394
|
+
.nextbar span{color:var(--muted);font-size:12px;overflow-wrap:anywhere}
|
|
391
395
|
.audit{display:grid;grid-template-columns:1.2fr repeat(3,minmax(0,.8fr));gap:12px;margin:14px 0}
|
|
392
396
|
.audit-item{border:1px solid var(--line);background:rgba(13,24,21,.92);border-radius:8px;padding:14px;min-width:0}
|
|
393
397
|
.audit-item.primary{background:linear-gradient(135deg,rgba(19,61,42,.88),rgba(9,19,16,.95))}
|
|
@@ -412,6 +416,7 @@ code{color:var(--code);background:#0a2017;border:1px solid #17462f;padding:2px 6
|
|
|
412
416
|
.path{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;color:var(--muted);font-size:12px;overflow-wrap:anywhere}
|
|
413
417
|
@media (max-width:860px){header,.layout{grid-template-columns:1fr}.metrics{grid-template-columns:repeat(2,1fr)}.grid{grid-template-columns:1fr}.agents{grid-template-columns:1fr}}
|
|
414
418
|
@media (max-width:860px){.control{grid-template-columns:1fr}}
|
|
419
|
+
@media (max-width:860px){.nextbar{grid-template-columns:1fr}}
|
|
415
420
|
@media (max-width:860px){.audit{grid-template-columns:1fr 1fr}}
|
|
416
421
|
@media (max-width:520px){.shell{padding:14px}.metrics{grid-template-columns:1fr}.event{grid-template-columns:1fr}h1{font-size:32px}}
|
|
417
422
|
@media (max-width:520px){.audit{grid-template-columns:1fr}}
|
|
@@ -466,6 +471,7 @@ const intentsHtml=intents.length?'<div class="timeline">'+intents.slice(-6).reve
|
|
|
466
471
|
const policyHtml=entries(policy).length?\`<table>\${rows(policy)}</table>\`:'<div class="okline">No explicit version policy set.</div>';
|
|
467
472
|
const actions=manifest.recommendedActions||[];
|
|
468
473
|
const actionsHtml=actions.length?'<div class="timeline">'+actions.slice(0,6).map(a=>\`<div class="event"><time>\${esc(a.priority)}</time><div><b>\${esc(a.category)}</b> \${esc(a.summary)}\${a.command?\`<div class="path">\${esc(a.command)}</div>\`:''}</div></div>\`).join('')+'</div>':'<div class="okline">No recommended actions. Continue project-local work.</div>';
|
|
474
|
+
const topAction=actions[0]||{};
|
|
469
475
|
const plan=manifest.planArtifacts||{};
|
|
470
476
|
const planHtml=plan.markdown||plan.json?\`<table><tr><th>Markdown</th><td>\${plan.markdown?'<a href="plan.md">plan.md</a>':'not written'}</td></tr><tr><th>JSON</th><td>\${plan.json?'<a href="plan.json">plan.json</a>':'not written'}</td></tr></table>\`:'<div class="okline">No plan artifacts yet. Run <code>aienvmp plan --write</code>.</div>';
|
|
471
477
|
const sbomArtifactHtml='<table><tr><th>JSON</th><td><a href="sbom.json">sbom.json</a></td></tr><tr><th>CDX Lite</th><td><a href="sbom.cdx.json">sbom.cdx.json</a></td></tr><tr><th>Command</th><td><code>aienvmp sbom --write</code></td></tr></table>';
|
|
@@ -518,6 +524,8 @@ const sbomRiskValue=riskSummary.level||'unknown';
|
|
|
518
524
|
const sbomRiskClass=['urgent','high','medium'].includes(sbomRiskValue)?'review':'ready';
|
|
519
525
|
const sbomRiskScore=riskSummary.score!==undefined?' ('+riskSummary.score+')':'';
|
|
520
526
|
const sbomRiskNext=riskSummary.next||aiDependencyReview.beforeDependencyChange?.[0]||'Run aienvmp sbom --json for dependency context.';
|
|
527
|
+
const nextCommand=manifest.preflight?.nextCommand||topAction.command||collaboration.nextCommand||'aienvmp status --json';
|
|
528
|
+
const nextReason=topAction.summary||collaboration.rule||riskSummary.next||'Read status/context before changing shared environment state.';
|
|
521
529
|
const coordination=manifest.preflight?.coordination||{};
|
|
522
530
|
const conflictTargets=coordination.conflictTargets||[];
|
|
523
531
|
const handoffFiles=nextAgent.dependencyFiles?.length?nextAgent.dependencyFiles:(dependencyReadSet[0]?[dependencyReadSet[0].manifest,...(dependencyReadSet[0].lockfiles||[])].filter(Boolean):[]);
|
|
@@ -537,6 +545,11 @@ document.getElementById('app').innerHTML=\`
|
|
|
537
545
|
\${controlCard('Collaboration',collaborationValue,collaboration.nextCommand||'aienvmp status --json',collaborationClass)}
|
|
538
546
|
\${controlCard('SBOM risk',sbomRiskValue+sbomRiskScore,sbomRiskNext,sbomRiskClass)}
|
|
539
547
|
</section>
|
|
548
|
+
<section class="nextbar" aria-label="Next command">
|
|
549
|
+
<b>Next command</b>
|
|
550
|
+
<code>\${esc(nextCommand)}</code>
|
|
551
|
+
<span>\${esc(nextReason)}</span>
|
|
552
|
+
</section>
|
|
540
553
|
<section class="audit" aria-label="Audit summary">
|
|
541
554
|
\${auditItem('AI decision',reviewRequired?'review required':'can proceed',nextAction,reviewRequired?'review':'primary')}
|
|
542
555
|
\${auditItem('AI readiness',aiReadiness.level||'unknown',aiReadinessHint,aiReadiness.level==='ready'?'primary':'review')}
|