aienvmp 0.1.23 → 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,11 @@
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
+
3
9
  ## 0.1.23
4
10
 
5
11
  - Added compact `stepSummary` output to `context --json`.
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aienvmp",
3
- "version": "0.1.23",
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": {
@@ -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);
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)}