@hiveai/cli 0.12.3 → 0.12.4

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/dist/index.js CHANGED
@@ -2743,7 +2743,7 @@ ${SEED_FOOTER(stack)}` });
2743
2743
  }
2744
2744
 
2745
2745
  // src/commands/init.ts
2746
- var HAIVE_GITHUB_ACTION_REF = `v${"0.12.3"}`;
2746
+ var HAIVE_GITHUB_ACTION_REF = `v${"0.12.4"}`;
2747
2747
  var PROJECT_CONTEXT_TEMPLATE = `# Project context
2748
2748
 
2749
2749
  > Generated by \`haive init\`. Run \`haive init --bootstrap\` to auto-fill from your codebase,
@@ -2778,7 +2778,7 @@ This repo uses **hAIve** for shared context. The map:
2778
2778
  1. **Before editing** for a goal, call \`get_briefing\` (task + files/symbols) to load ranked context \u2014 or \`mem_relevant_to\` if project context is already loaded this session.
2779
2779
  2. **When an approach fails**, call \`mem_tried\` right away so the next agent skips the dead end.
2780
2780
  3. **Before closing** a substantive session, run the \`post_task\` prompt to capture what was learned.
2781
- 4. **Before final response**, run \`haive enforce finish\`. If it blocks, commit/push, bump/tag shippable releases, then rerun it.
2781
+ 4. **Before final response**, run \`haive enforce finish\`. If it blocks, commit/push, bump/tag shippable releases, wait for GitHub Actions to pass when applicable, then rerun it.
2782
2782
 
2783
2783
  If the haive MCP server is not available, tell the developer rather than silently skipping it.
2784
2784
 
@@ -2805,7 +2805,7 @@ This repository uses **hAIve**. Running \`haive init\` means the team expects ag
2805
2805
 
2806
2806
  - On failure: **\`mem_tried\`** immediately.
2807
2807
  - Before closing a substantive session: MCP prompt **\`post_task\`** when there is something worth capturing.
2808
- - Before final response: **\`haive enforce finish\`** must pass; it checks commit/push and release version/tag protocol.
2808
+ - Before final response: **\`haive enforce finish\`** must pass; it checks commit/push, release version/tag protocol, and GitHub Actions success for pushed HEAD when the repo has a GitHub remote.
2809
2809
 
2810
2810
  ## If haive MCP is missing
2811
2811
 
@@ -7440,7 +7440,7 @@ This creates/updates a single rolling recap that **get_briefing automatically su
7440
7440
 
7441
7441
  Calling \`mem_session_end\` also **clears the pending-distill marker** (if any), confirming that this session's learnings have been properly captured rather than left as an auto-recap skeleton.
7442
7442
 
7443
- ### 7. Verify the git/release exit protocol \u2014 always
7443
+ ### 7. Verify the git/release/pipeline exit protocol \u2014 always
7444
7444
  Run **\`haive enforce finish\`** before your final response.
7445
7445
 
7446
7446
  This executable gate checks the multi-agent git-sync decision:
@@ -7448,11 +7448,12 @@ This executable gate checks the multi-agent git-sync decision:
7448
7448
  - shippable package changes have a lockstep version bump
7449
7449
  - the release tag \`vX.Y.Z\` exists when a version was bumped
7450
7450
  - commits and tags have been pushed
7451
+ - the pushed HEAD's GitHub Actions workflow runs have completed successfully when the repo has a GitHub remote
7451
7452
  - agents never run \`npm publish\` (publication remains human-owned)
7452
7453
 
7453
- If it blocks, fix the reported Git/version/tag/push issue before telling the developer the task is done.
7454
+ If it blocks, fix the reported Git/version/tag/push/pipeline issue before telling the developer the task is done.
7454
7455
 
7455
- When done, respond with a brief summary: "Saved N memories: [list of IDs]. Session recap saved. hAIve finish gate passed."
7456
+ When done, respond with a brief summary: "Saved N memories: [list of IDs]. Session recap saved. hAIve finish gate passed; GitHub Actions passed when applicable."
7456
7457
  `;
7457
7458
  return {
7458
7459
  description: "Post-task reflection: capture what you learned before closing the session",
@@ -7531,7 +7532,7 @@ When done, respond with: "Imported N memories: [list of IDs]" or "Nothing action
7531
7532
  };
7532
7533
  }
7533
7534
  var SERVER_NAME = "haive";
7534
- var SERVER_VERSION = "0.12.3";
7535
+ var SERVER_VERSION = "0.12.4";
7535
7536
  function jsonResult(data) {
7536
7537
  return {
7537
7538
  content: [
@@ -13001,7 +13002,7 @@ function registerDoctor(program2) {
13001
13002
  fix: "Edit .ai/haive.config.json: set autoSessionEnd: true (or re-run `haive init` without --manual)."
13002
13003
  });
13003
13004
  }
13004
- findings.push(...await collectInstallFindings(root, "0.12.3"));
13005
+ findings.push(...await collectInstallFindings(root, "0.12.4"));
13005
13006
  findings.push(...await collectToolchainFindings(root));
13006
13007
  try {
13007
13008
  const legacyRaw = execSync3("haive-mcp --version", {
@@ -13009,7 +13010,7 @@ function registerDoctor(program2) {
13009
13010
  timeout: 3e3,
13010
13011
  stdio: ["ignore", "pipe", "ignore"]
13011
13012
  }).trim();
13012
- const cliVersion = "0.12.3";
13013
+ const cliVersion = "0.12.4";
13013
13014
  if (legacyRaw && legacyRaw !== cliVersion) {
13014
13015
  findings.push({
13015
13016
  severity: "warn",
@@ -14371,6 +14372,7 @@ async function buildFinishReport(dir) {
14371
14372
  code: "release-version-not-required",
14372
14373
  message: "No shippable package code changed since upstream; no version/tag required."
14373
14374
  });
14375
+ findings.push(...await verifyGithubActionsForHead(root, status));
14374
14376
  return finishReport(root, initialized, mode, findings, config);
14375
14377
  }
14376
14378
  findings.push({
@@ -14457,6 +14459,7 @@ async function buildFinishReport(dir) {
14457
14459
  impact: 10
14458
14460
  });
14459
14461
  }
14462
+ findings.push(...await verifyGithubActionsForHead(root, status));
14460
14463
  return finishReport(root, initialized, mode, findings, config);
14461
14464
  }
14462
14465
  function finishReport(root, initialized, mode, findings, config) {
@@ -14600,7 +14603,7 @@ async function buildEnforcementReport(dir, stage, sessionId) {
14600
14603
  findings: [{ severity: "info", code: "enforcement-off", message: "hAIve enforcement is disabled." }]
14601
14604
  });
14602
14605
  }
14603
- findings.push(...await inspectIntegrationVersions(root, "0.12.3"));
14606
+ findings.push(...await inspectIntegrationVersions(root, "0.12.4"));
14604
14607
  if (config.enforcement?.requireBriefingFirst !== false && stage !== "ci") {
14605
14608
  const hasBriefing = await hasRecentBriefingMarker2(paths, sessionId);
14606
14609
  findings.push(hasBriefing ? { severity: "ok", code: "briefing-loaded", message: "A recent hAIve briefing marker exists." } : {
@@ -15152,6 +15155,108 @@ async function remoteTagExists(root, tag) {
15152
15155
  return null;
15153
15156
  }
15154
15157
  }
15158
+ async function verifyGithubActionsForHead(root, status) {
15159
+ if (!status.upstream) return [];
15160
+ if (status.ahead > 0) {
15161
+ return [{
15162
+ severity: "info",
15163
+ code: "github-actions-waiting-for-push",
15164
+ message: "GitHub Actions verification waits until HEAD is pushed."
15165
+ }];
15166
+ }
15167
+ const remote = await githubRemoteForCurrentBranch(root);
15168
+ if (!remote) {
15169
+ return [{
15170
+ severity: "info",
15171
+ code: "github-actions-not-applicable",
15172
+ message: "No GitHub remote was detected; GitHub Actions pipeline verification was skipped."
15173
+ }];
15174
+ }
15175
+ const sha = (await runCommand4("git", ["rev-parse", "HEAD"], root).catch(() => "")).trim();
15176
+ if (!sha) {
15177
+ return [{
15178
+ severity: "error",
15179
+ code: "github-actions-head-unreadable",
15180
+ message: "Could not read HEAD SHA for GitHub Actions verification.",
15181
+ fix: "Run `git rev-parse HEAD`, then verify GitHub Actions manually before finishing.",
15182
+ impact: 30
15183
+ }];
15184
+ }
15185
+ let runs;
15186
+ try {
15187
+ const raw = await runCommand4("gh", [
15188
+ "run",
15189
+ "list",
15190
+ "--commit",
15191
+ sha,
15192
+ "--limit",
15193
+ "50",
15194
+ "--json",
15195
+ "conclusion,databaseId,name,status,workflowName"
15196
+ ], root);
15197
+ runs = JSON.parse(raw);
15198
+ } catch {
15199
+ return [{
15200
+ severity: "error",
15201
+ code: "github-actions-unverified",
15202
+ message: "Could not verify GitHub Actions runs for HEAD.",
15203
+ fix: "Install/authenticate GitHub CLI, then run `gh run list --commit $(git rev-parse HEAD)` and ensure every workflow is successful before finishing.",
15204
+ reason: `Detected GitHub remote ${remote}, but hAIve could not query workflow runs.`,
15205
+ impact: 50
15206
+ }];
15207
+ }
15208
+ if (runs.length === 0) {
15209
+ return [{
15210
+ severity: "error",
15211
+ code: "github-actions-runs-missing",
15212
+ message: "No GitHub Actions runs were found for HEAD.",
15213
+ fix: "Wait for GitHub to create the workflow runs, or verify that the push was not skipped by a `[skip ci]` head commit; rerun `haive enforce finish` after the runs appear.",
15214
+ impact: 50
15215
+ }];
15216
+ }
15217
+ const pending = runs.filter((run) => run.status !== "completed");
15218
+ if (pending.length > 0) {
15219
+ return [{
15220
+ severity: "error",
15221
+ code: "github-actions-pending",
15222
+ message: `${pending.length}/${runs.length} GitHub Actions workflow run(s) for HEAD are still pending: ${formatGithubRunNames(pending)}.`,
15223
+ fix: "Wait for the runs to finish (`gh run watch <run-id> --exit-status`), then rerun `haive enforce finish`.",
15224
+ impact: 50
15225
+ }];
15226
+ }
15227
+ const failed = runs.filter((run) => run.conclusion !== "success");
15228
+ if (failed.length > 0) {
15229
+ return [{
15230
+ severity: "error",
15231
+ code: "github-actions-failed",
15232
+ message: `${failed.length}/${runs.length} GitHub Actions workflow run(s) for HEAD did not pass: ${formatGithubRunNames(failed)}.`,
15233
+ fix: "Inspect the failed run logs with `gh run view <run-id> --log`, fix the issue, push the fix, then rerun `haive enforce finish`.",
15234
+ impact: 80
15235
+ }];
15236
+ }
15237
+ return [{
15238
+ severity: "ok",
15239
+ code: "github-actions-pass",
15240
+ message: `All ${runs.length} GitHub Actions workflow run(s) for HEAD completed successfully.`
15241
+ }];
15242
+ }
15243
+ async function githubRemoteForCurrentBranch(root) {
15244
+ const branch = (await runCommand4("git", ["branch", "--show-current"], root).catch(() => "")).trim();
15245
+ const branchRemote = branch ? (await runCommand4("git", ["config", "--get", `branch.${branch}.remote`], root).catch(() => "")).trim() : "";
15246
+ const remoteName = branchRemote || "origin";
15247
+ const remoteUrl = (await runCommand4("git", ["config", "--get", `remote.${remoteName}.url`], root).catch(() => "")).trim();
15248
+ if (!isGithubRemoteUrl(remoteUrl)) return null;
15249
+ return remoteUrl;
15250
+ }
15251
+ function isGithubRemoteUrl(url) {
15252
+ return /(^git@github\.com:|github\.com[/:])/.test(url);
15253
+ }
15254
+ function formatGithubRunNames(runs) {
15255
+ return runs.slice(0, 6).map((run) => {
15256
+ const label = run.workflowName ?? run.name ?? "workflow";
15257
+ return run.databaseId ? `${label}#${run.databaseId}` : label;
15258
+ }).join(", ");
15259
+ }
15155
15260
  function buildScore(findings, threshold = 80) {
15156
15261
  const checks = {
15157
15262
  total: findings.length,
@@ -15608,7 +15713,7 @@ function shellQuote(value) {
15608
15713
 
15609
15714
  // src/index.ts
15610
15715
  var program = new Command56();
15611
- program.name("haive").description("hAIve - repo-native memory and context policy for coding-agent harnesses").version("0.12.3").option("--advanced", "show maintenance and experimental commands in help");
15716
+ program.name("haive").description("hAIve - repo-native memory and context policy for coding-agent harnesses").version("0.12.4").option("--advanced", "show maintenance and experimental commands in help");
15612
15717
  registerInit(program);
15613
15718
  registerWelcome(program);
15614
15719
  registerResolveProject(program);