aienvmp 0.1.23 → 0.1.25

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.25
4
+
5
+ - Added a more explicit AI decision contract to `context --json`.
6
+ - Included project-local work allowance, environment-change review state, warning codes, and required follow-up commands.
7
+ - Clarified that local project work can continue while environment changes remain intent-gated and review-oriented.
8
+
9
+ ## 0.1.24
10
+
11
+ - Added a dashboard CI Readiness card for `doctor --strict security|policy|coordination|all`.
12
+ - Reused the same non-blocking warning engine so humans can pick CI enforcement scope without changing local operation.
13
+ - Surfaced matched warning codes per strict scope for faster AI and human review.
14
+
3
15
  ## 0.1.23
4
16
 
5
17
  - 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
@@ -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 # AI decision context + actions + compact step summary
83
+ aienvmp context --json # AI decision contract + 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.23",
3
+ "version": "0.1.25",
4
4
  "description": "AI-first environment maps and lightweight runtime SBOMs for shared development machines.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -63,11 +63,19 @@ function inventorySummary(inventory = {}) {
63
63
  }
64
64
 
65
65
  function contextDecision(warnings, intents) {
66
+ const warningCodes = warnings.map((warning) => warning.code);
66
67
  const reviewRequired = warnings.length > 0 || intents.length > 0;
68
+ const canChangeEnvironmentWithoutReview = !reviewRequired;
69
+ const mode = reviewRequired ? "review-first" : "project-local-work";
67
70
  return {
71
+ schemaVersion: 1,
72
+ mode,
68
73
  canProceed: !reviewRequired,
74
+ canContinueProjectLocalWork: true,
75
+ canChangeEnvironmentWithoutReview,
69
76
  safeForProjectLocalWork: warnings.length === 0,
70
77
  reviewRequired,
78
+ warningCodes,
71
79
  environmentChangeRequiresIntent: true,
72
80
  globalEnvironmentChangesRequireUserApproval: true,
73
81
  pendingIntentCount: intents.length,
@@ -80,6 +88,13 @@ function contextDecision(warnings, intents) {
80
88
  recommendedNextActions: warnings.length
81
89
  ? ["review warnings", "ask the user before environment changes", "record intent before changes"]
82
90
  : ["continue with project-local work", "run aienvmp intent before environment changes"],
83
- nextCommand: warnings.length ? "review warnings before changing environment" : "continue with project-local work"
91
+ requiredCommands: {
92
+ beforeEnvironmentChange: "aienvmp intent --actor agent:id --action planned-change --target <runtime|package-manager|docker>",
93
+ refreshAfterChange: "aienvmp sync",
94
+ recordAfterChange: "aienvmp record --actor agent:id --summary what-changed",
95
+ handoff: "aienvmp handoff --record --actor agent:id",
96
+ reviewPlan: "aienvmp plan"
97
+ },
98
+ nextCommand: reviewRequired ? "aienvmp plan" : "continue project-local work; use aienvmp intent before environment changes"
84
99
  };
85
100
  }
@@ -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
@@ -92,6 +92,7 @@ export function renderContext(manifest, timeline = [], warnings = [], intents =
92
92
  "",
93
93
  `Status: ${status}`,
94
94
  `Next: ${next}`,
95
+ "Project-local work: allowed; environment changes require intent and review when warnings or open intents exist.",
95
96
  `Trust: ${manifest.trust?.state || "observed"} (verified requires human or CI)`,
96
97
  `Workspace: ${manifest.workspace.path}`,
97
98
  `Node: ${manifest.runtimes.node || "not detected"}`,
@@ -294,6 +295,9 @@ const remediationRefs=r=>r.advisories?.length?\` - \${r.advisories.join(', ')}\`
294
295
  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
296
  const envSteps=manifest.planEnvironment||[];
296
297
  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>';
298
+ const ciReadiness=manifest.ciReadiness||[];
299
+ const ciHasFailure=ciReadiness.some(s=>s.status==='fail');
300
+ 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
301
  const card=(title,badge,body)=>\`<section class="card"><div class="card-head"><h2>\${title}</h2>\${badge||''}</div>\${body}</section>\`;
298
302
  const reviewRequired=warnings.length>0||intents.length>0;
299
303
  const recentChanges=timeline.slice(-8).length;
@@ -341,6 +345,8 @@ document.getElementById('app').innerHTML=\`
341
345
  <div style="height:14px"></div>
342
346
  \${card('Environment Steps',envSteps.length?'<span class="pill warn">'+envSteps.length+' items</span>':'<span class="pill off">none</span>',envStepsHtml)}
343
347
  <div style="height:14px"></div>
348
+ \${card('CI Readiness',ciHasFailure?'<span class="pill warn">review</span>':'<span class="pill">ready</span>',ciReadinessHtml)}
349
+ <div style="height:14px"></div>
344
350
  \${card('Environment Health',warnings.length?'<span class="pill warn">attention</span>':'<span class="pill">clear</span>',warnHtml)}
345
351
  <div style="height:14px"></div>
346
352
  \${card('Version Policy','<span class="pill">'+entries(policy).length+' rules</span>',policyHtml)}