aienvmp 0.1.22 → 0.1.24

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,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.24
4
+
5
+ - Added a dashboard CI Readiness card for `doctor --strict security|policy|coordination|all`.
6
+ - Reused the same non-blocking warning engine so humans can pick CI enforcement scope without changing local operation.
7
+ - Surfaced matched warning codes per strict scope for faster AI and human review.
8
+
9
+ ## 0.1.23
10
+
11
+ - Added compact `stepSummary` output to `context --json`.
12
+ - Reused the AI plan step model so preflight context can show remediation and environment drift summaries.
13
+ - Kept full step details in `aienvmp plan` while keeping context lightweight.
14
+
3
15
  ## 0.1.22
4
16
 
5
17
  - Reworked the README around Quick Start, AI Usage, CI Usage, and outputs.
package/README.md CHANGED
@@ -66,6 +66,7 @@ npx aienvmp snippet agents
66
66
  ## CI Usage
67
67
 
68
68
  Use the GitHub Action to write the env map, plan, dashboard, and optional strict checks. See [examples/github-action.yml](examples/github-action.yml).
69
+ The dashboard shows which strict scopes are CI-ready before you enforce them.
69
70
 
70
71
  ```yaml
71
72
  - uses: soovwv/aienvmp@main
@@ -79,7 +80,7 @@ Use the GitHub Action to write the env map, plan, dashboard, and optional strict
79
80
  ```bash
80
81
  aienvmp sync # update env map, light SBOM, ledger, dashboard
81
82
  aienvmp context # AI preflight brief
82
- aienvmp context --json # machine-readable AI decision context + recommended actions
83
+ aienvmp context --json # AI decision context + actions + compact step summary
83
84
  aienvmp plan # read-only AI action plan for drift and remediation
84
85
  aienvmp handoff # next-agent handoff summary + recommended actions
85
86
  aienvmp intent # record a planned env change
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aienvmp",
3
- "version": "0.1.22",
3
+ "version": "0.1.24",
4
4
  "description": "AI-first environment maps and lightweight runtime SBOMs for shared development machines.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -5,6 +5,7 @@ import { intentsPath, manifestPath, timelinePath, workspaceDir } from "../paths.
5
5
  import { renderContext } from "../render.js";
6
6
  import { loadPolicy, policyWarnings } from "../policy.js";
7
7
  import { recommendedActions } from "../actions.js";
8
+ import { buildPlan, compactStepSummary } from "./plan.js";
8
9
 
9
10
  export async function contextWorkspace(args) {
10
11
  const dir = workspaceDir(args);
@@ -16,11 +17,13 @@ export async function contextWorkspace(args) {
16
17
  const warnings = [...diagnose(manifest, { timeline, intents }), ...policyWarnings(manifest, policy)];
17
18
  const decision = contextDecision(warnings, intents);
18
19
  const actions = recommendedActions(manifest, { warnings, intents });
20
+ const stepSummary = compactStepSummary(buildPlan(manifest, warnings, intents, policy));
19
21
  if (args.json) {
20
22
  console.log(JSON.stringify({
21
23
  status: warnings.length ? "review-required" : "clear",
22
24
  decision,
23
25
  recommendedActions: actions,
26
+ stepSummary,
24
27
  trust: manifest.trust || {},
25
28
  guidance: decision,
26
29
  workspace: manifest.workspace,
@@ -8,6 +8,7 @@ import { dashboardPath, intentsPath, manifestPath, planJsonPath, planMdPath, tim
8
8
  import { renderDashboard } from "../render.js";
9
9
  import { loadPolicy, policyWarnings } from "../policy.js";
10
10
  import { recommendedActions } from "../actions.js";
11
+ import { strictResult } from "./doctor.js";
11
12
 
12
13
  export async function dashWorkspace(args) {
13
14
  const dir = workspaceDir(args);
@@ -20,7 +21,14 @@ export async function dashWorkspace(args) {
20
21
  const planArtifacts = await detectedPlanArtifacts(dir);
21
22
  const planRemediation = await detectedPlanRemediation(dir);
22
23
  const planEnvironment = await detectedPlanEnvironment(dir);
23
- const html = renderDashboard({ ...manifest, recommendedActions: recommendedActions(manifest, { warnings, intents }), planArtifacts, planRemediation, planEnvironment }, timeline, warnings, intents, policy);
24
+ const html = renderDashboard({
25
+ ...manifest,
26
+ recommendedActions: recommendedActions(manifest, { warnings, intents }),
27
+ planArtifacts,
28
+ planRemediation,
29
+ planEnvironment,
30
+ ciReadiness: ciReadiness(warnings)
31
+ }, timeline, warnings, intents, policy);
24
32
  const out = dashboardPath(dir);
25
33
  await fs.mkdir(path.dirname(out), { recursive: true });
26
34
  await fs.writeFile(out, html, "utf8");
@@ -29,6 +37,17 @@ export async function dashWorkspace(args) {
29
37
  return { dashboard: out };
30
38
  }
31
39
 
40
+ function ciReadiness(warnings) {
41
+ return ["security", "policy", "coordination", "all"].map((scope) => {
42
+ const result = strictResult(warnings, { strict: scope });
43
+ return {
44
+ scope,
45
+ status: result.fail ? "fail" : "pass",
46
+ matchedWarningCodes: result.matchedWarningCodes
47
+ };
48
+ });
49
+ }
50
+
32
51
  async function detectedPlanArtifacts(dir) {
33
52
  const json = planJsonPath(dir);
34
53
  const markdown = planMdPath(dir);
@@ -66,6 +66,22 @@ export function buildPlan(manifest, warnings = [], intents = [], policy = {}) {
66
66
  };
67
67
  }
68
68
 
69
+ export function compactStepSummary(plan = {}) {
70
+ return {
71
+ remediation: (plan.remediationSteps || []).slice(0, 3).map((item) => ({
72
+ package: item.package,
73
+ severity: item.severity,
74
+ fixVersions: (item.fixVersions || []).slice(0, 3),
75
+ advisoryIds: (item.advisories || []).map((advisory) => advisory.id || advisory.title).filter(Boolean).slice(0, 3)
76
+ })),
77
+ environment: (plan.environmentSteps || []).slice(0, 3).map((item) => ({
78
+ code: item.code,
79
+ category: item.category,
80
+ summary: item.summary
81
+ }))
82
+ };
83
+ }
84
+
69
85
  function environmentSteps(warnings = []) {
70
86
  return warnings
71
87
  .filter((warning) => warning.code !== "security-vulnerabilities")
package/src/render.js CHANGED
@@ -294,6 +294,9 @@ const remediationRefs=r=>r.advisories?.length?\` - \${r.advisories.join(', ')}\`
294
294
  const remediationHtml=remediation.length?'<div class="timeline">'+remediation.map(r=>\`<div class="event"><time>\${esc(r.severity)}</time><div><b>\${esc(r.package)}</b> \${esc(remediationFix(r))}\${esc(remediationRefs(r))}</div></div>\`).join('')+'</div>':'<div class="okline">No remediation steps in the current plan.</div>';
295
295
  const envSteps=manifest.planEnvironment||[];
296
296
  const envStepsHtml=envSteps.length?'<div class="timeline">'+envSteps.map(s=>\`<div class="event"><time>\${esc(s.category)}</time><div><b>\${esc(s.code)}</b> \${esc(s.summary)}</div></div>\`).join('')+'</div>':'<div class="okline">No environment steps in the current plan.</div>';
297
+ const ciReadiness=manifest.ciReadiness||[];
298
+ const ciHasFailure=ciReadiness.some(s=>s.status==='fail');
299
+ const ciReadinessHtml=ciReadiness.length?'<table>'+ciReadiness.map(s=>\`<tr><th>\${esc(s.scope)}</th><td><code>\${esc(s.status)}</code>\${s.matchedWarningCodes?.length?\` \${esc(s.matchedWarningCodes.join(', '))}\`:''}</td></tr>\`).join('')+'</table>':'<div class="okline">Run <code>aienvmp doctor --strict security|policy|coordination|all</code> to choose CI enforcement scope.</div>';
297
300
  const card=(title,badge,body)=>\`<section class="card"><div class="card-head"><h2>\${title}</h2>\${badge||''}</div>\${body}</section>\`;
298
301
  const reviewRequired=warnings.length>0||intents.length>0;
299
302
  const recentChanges=timeline.slice(-8).length;
@@ -341,6 +344,8 @@ document.getElementById('app').innerHTML=\`
341
344
  <div style="height:14px"></div>
342
345
  \${card('Environment Steps',envSteps.length?'<span class="pill warn">'+envSteps.length+' items</span>':'<span class="pill off">none</span>',envStepsHtml)}
343
346
  <div style="height:14px"></div>
347
+ \${card('CI Readiness',ciHasFailure?'<span class="pill warn">review</span>':'<span class="pill">ready</span>',ciReadinessHtml)}
348
+ <div style="height:14px"></div>
344
349
  \${card('Environment Health',warnings.length?'<span class="pill warn">attention</span>':'<span class="pill">clear</span>',warnHtml)}
345
350
  <div style="height:14px"></div>
346
351
  \${card('Version Policy','<span class="pill">'+entries(policy).length+' rules</span>',policyHtml)}