aienvmp 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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.13
4
+
5
+ - Added `recommendedActions` to AI handoff output.
6
+ - Added a Recommended Actions dashboard card for human review.
7
+ - Reused the same advisory action engine across context, doctor, handoff, and dashboard.
8
+
3
9
  ## 0.1.12
4
10
 
5
11
  - Added AI-readable `recommendedActions` to `context --json` and `doctor --json`.
package/README.md CHANGED
@@ -56,7 +56,7 @@ npx aienvmp snippet agents
56
56
  aienvmp sync # update env map, light SBOM, ledger, dashboard
57
57
  aienvmp context # AI preflight brief
58
58
  aienvmp context --json # machine-readable AI decision context + recommended actions
59
- aienvmp handoff # next-agent handoff summary
59
+ aienvmp handoff # next-agent handoff summary + recommended actions
60
60
  aienvmp intent # record a planned env change
61
61
  aienvmp record # record what changed
62
62
  aienvmp doctor --ci # strict CI check
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aienvmp",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "description": "AI-first environment maps and lightweight runtime SBOMs for shared development machines.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -7,6 +7,7 @@ import { openIntents, readJsonl, readTimeline } from "../timeline.js";
7
7
  import { dashboardPath, intentsPath, manifestPath, timelinePath, workspaceDir } from "../paths.js";
8
8
  import { renderDashboard } from "../render.js";
9
9
  import { loadPolicy, policyWarnings } from "../policy.js";
10
+ import { recommendedActions } from "../actions.js";
10
11
 
11
12
  export async function dashWorkspace(args) {
12
13
  const dir = workspaceDir(args);
@@ -16,7 +17,7 @@ export async function dashWorkspace(args) {
16
17
  const intents = openIntents(await readJsonl(intentsPath(dir)));
17
18
  const policy = await loadPolicy(dir);
18
19
  const warnings = [...diagnose(manifest, { timeline, intents }), ...policyWarnings(manifest, policy)];
19
- const html = renderDashboard(manifest, timeline, warnings, intents, policy);
20
+ const html = renderDashboard({ ...manifest, recommendedActions: recommendedActions(manifest, { warnings, intents }) }, timeline, warnings, intents, policy);
20
21
  const out = dashboardPath(dir);
21
22
  await fs.mkdir(path.dirname(out), { recursive: true });
22
23
  await fs.writeFile(out, html, "utf8");
@@ -5,6 +5,7 @@ import { intentsPath, manifestPath, timelinePath, workspaceDir } from "../paths.
5
5
  import { renderHandoff } from "../render.js";
6
6
  import { openIntents, readJsonl, readTimeline } from "../timeline.js";
7
7
  import { changedTrust } from "../trust.js";
8
+ import { recommendedActions } from "../actions.js";
8
9
 
9
10
  export async function handoffWorkspace(args) {
10
11
  const dir = workspaceDir(args);
@@ -42,6 +43,7 @@ async function recordHandoff(file, handoff, actor) {
42
43
 
43
44
  export function buildHandoff(manifest, timeline = [], warnings = [], intents = [], policy = {}) {
44
45
  const reviewRequired = warnings.length > 0 || intents.length > 0;
46
+ const actions = recommendedActions(manifest, { warnings, intents });
45
47
  return {
46
48
  status: reviewRequired ? "review-required" : "clear",
47
49
  trust: manifest.trust || {},
@@ -63,6 +65,7 @@ export function buildHandoff(manifest, timeline = [], warnings = [], intents = [
63
65
  },
64
66
  openIntents: intents.slice(-5).reverse(),
65
67
  warnings,
68
+ recommendedActions: actions,
66
69
  recentChanges: timeline.slice(-5).reverse(),
67
70
  mustNotDo: [
68
71
  "do not change global runtimes without user approval",
package/src/render.js CHANGED
@@ -149,6 +149,9 @@ export function renderHandoff(handoff) {
149
149
  "Warnings:",
150
150
  ...(handoff.warnings.length ? handoff.warnings.map((w) => `- ${w.message}`) : ["- none"]),
151
151
  "",
152
+ "Recommended actions:",
153
+ ...(handoff.recommendedActions?.length ? handoff.recommendedActions.map((item) => `- [${item.priority}] ${item.summary}${item.command ? ` (${item.command})` : ""}`) : ["- none"]),
154
+ "",
152
155
  "Recent changes:",
153
156
  ...(handoff.recentChanges.length ? handoff.recentChanges.map((t) => `- ${formatTimeline(t)}`) : ["- none"]),
154
157
  "",
@@ -234,6 +237,8 @@ const warnHtml=warnings.length?'<div class="warnings">'+warnings.map(w=>\`<div c
234
237
  const timelineHtml=timeline.length?'<div class="timeline">'+timeline.slice(-8).reverse().map(t=>\`<div class="event"><time>\${esc(t.at.replace('T',' ').slice(0,16))}</time><div><b>\${esc(t.actor||'system')}</b> \${esc(timelineLabel(t))}</div></div>\`).join('')+'</div>':'<div class="okline">No previous environment changes recorded.</div>';
235
238
  const intentsHtml=intents.length?'<div class="timeline">'+intents.slice(-6).reverse().map(i=>\`<div class="event"><time>\${esc(i.at.replace('T',' ').slice(0,16))}</time><div><b>\${esc(i.actor)}</b> plans \${esc(i.action)}</div></div>\`).join('')+'</div>':'<div class="okline">No pending agent intents recorded.</div>';
236
239
  const policyHtml=entries(policy).length?\`<table>\${rows(policy)}</table>\`:'<div class="okline">No explicit version policy set.</div>';
240
+ const actions=manifest.recommendedActions||[];
241
+ 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>';
237
242
  const card=(title,badge,body)=>\`<section class="card"><div class="card-head"><h2>\${title}</h2>\${badge||''}</div>\${body}</section>\`;
238
243
  const reviewRequired=warnings.length>0||intents.length>0;
239
244
  const recentChanges=timeline.slice(-8).length;
@@ -273,6 +278,8 @@ document.getElementById('app').innerHTML=\`
273
278
  \${card('Security Summary',sec.enabled?'<span class="pill warn">security</span>':'<span class="pill off">basic</span>',securityHtml)}
274
279
  </div>
275
280
  <aside>
281
+ \${card('Recommended Actions','<span class="pill">'+actions.length+' actions</span>',actionsHtml)}
282
+ <div style="height:14px"></div>
276
283
  \${card('Environment Health',warnings.length?'<span class="pill warn">attention</span>':'<span class="pill">clear</span>',warnHtml)}
277
284
  <div style="height:14px"></div>
278
285
  \${card('Version Policy','<span class="pill">'+entries(policy).length+' rules</span>',policyHtml)}