Skip to content

ci: dogfood git-mind suggest action with Claude CLI#294

Open
flyingrobots wants to merge 2 commits intomainfrom
feat/dogfood-suggest-action
Open

ci: dogfood git-mind suggest action with Claude CLI#294
flyingrobots wants to merge 2 commits intomainfrom
feat/dogfood-suggest-action

Conversation

@flyingrobots
Copy link
Owner

Summary

  • Add .github/workflows/gitmind-suggest.yml to run git mind suggest on every PR against main
  • Uses Claude CLI (claude -p --output-format json) as the suggestion agent
  • Dogfoods the existing composite action (action.yml) and review workflow (gitmind-review.yml)

Problem Statement

The composite action and review workflow exist but are never exercised on this repo. Adding the suggest trigger closes the loop — PRs get automated graph-relationship suggestions, and /gitmind accept|reject commands work via the existing review workflow.

ADR Compliance (Required)

Relevant ADR(s)

  • None

Compliance Declaration

  • This PR is fully compliant with all checked ADRs.

Architecture Laws Checklist (Hard Gates)

Canonical Truth & Context

  • Graph remains canonical truth (no dual truth with generated files).
  • No hidden worktree coupling introduced in core/domain/materialization paths.
  • Context-sensitive behavior is explicit (--at, --observer, --trust) or deterministically defaulted.
  • Resolved context is surfaced in output metadata where applicable.

Determinism & Provenance

  • Pure query/materialization paths remain deterministic for identical inputs.
  • Mutations/materializations include provenance receipts/envelopes where required.
  • Cache keys (if used) are derived only from semantic inputs + pinned versions.

Artifact Hygiene

  • No forbidden generated artifact paths are tracked.
  • Any generated artifacts intentionally tracked are in allowlisted publish paths only.
  • Pre-commit/CI policy checks updated or confirmed valid.

Contracts & Compatibility

  • Machine-facing outputs are schema-versioned.
  • Breaking contract changes include version bump + migration notes.
  • Backward compatibility impact is documented below.

Extension/Effects Safety (if applicable)

  • Extension behavior does not bypass capability restrictions.
  • Effectful operations use explicit plan/apply semantics and emit receipts.
  • Timeouts/resource bounds are defined for new script/effect paths.

Scope Control

  • PR is single-purpose/cohesive (no unrelated refactors).
  • Any non-essential refactor is split into separate PR(s) or explicitly justified.

Backward Compatibility

  • CLI/API contract changes: None
  • Data model/storage changes: None
  • Migration required?: No
  • User-facing behavior changes: None — CI-only change

Test Plan (Required)

Unit

  • Added/updated tests for changed logic
  • Commands: N/A — workflow-only change, no application code modified

Integration

  • Added/updated integration tests
  • Commands: The PR itself is the integration test — workflow triggers on this PR

Determinism

  • Determinism assertions included for relevant paths
  • Method: N/A
  • Commands: N/A

Contract/Schema

  • Schema validation updated/passing
  • Commands: npm run lint

Policy Gates

  • Mechanical architecture gates pass
  • Commands: npm test && npm run lint

Security / Trust Impact

  • Threat surface changed?: Uses ANTHROPIC_API_KEY secret (never exposed in logs)
  • Trust policy impact: None
  • Provenance/audit impact: None
  • New failure modes introduced: Suggest failure is non-blocking (continue-on-error: true)

Performance Impact

  • Hot path affected?: No
  • Expected impact (latency/memory/io): CI adds ~1-2 min for suggest step (non-blocking)
  • Benchmarks or profiling evidence: N/A

Observability / Debuggability

  • Errors are actionable and include context.
  • Logs/diagnostics added or updated where needed.
  • git mind status / diagnostics updated if writeback/eventing behavior changed.

Operational Notes

  • Feature flag (if any): Gated on ANTHROPIC_API_KEY secret — no key = skip
  • Rollback strategy: Delete workflow file
  • Operational caveats: Requires gh secret set ANTHROPIC_API_KEY to activate

Linked Issues / Milestones


Reviewer Quick Verdict Block (for maintainers)

MUST (Hard Gates)

•	PASS
•	CONDITIONAL
•	FAIL

SHOULD (Quality)

•	PASS
•	CONDITIONAL
•	FAIL

Verdict

•	APPROVE
•	APPROVE WITH CHANGES
•	REJECT

Wires up the composite action (action.yml) to run on every PR against
main, using Claude CLI as the suggestion agent. Includes guards for
draft PRs, bot authors, and missing ANTHROPIC_API_KEY. Non-blocking
via continue-on-error so suggest failures never prevent merge.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 24, 2026

Summary by CodeRabbit

  • New Features

    • Added GitHub Actions workflow to provide automated PR suggestions on pull request events
    • Migrated Git hook from post-commit to pre-push to process commits before pushing
    • Pre-push hook conditionally executes suggestion step when configured
  • Tests

    • Expanded test coverage for Git hook installation and configuration

Walkthrough

This PR introduces a GitHub Actions workflow for git-mind suggest on PRs, migrates hook execution from post-commit to pre-push timing, updates corresponding CLI text and help documentation, and adds comprehensive test coverage for the new hook installation behavior.

Changes

Cohort / File(s) Summary
GitHub Actions Workflow Setup
.github/workflows/gitmind-suggest.yml
Adds new PR-triggered workflow with conditional gating on ANTHROPIC_API_KEY presence. Executes Node.js setup, dependency installation, Claude CLI installation, and invokes git-mind suggest action with JSON output format. Implements concurrency control and skips for drafts and dependabot.
Hook Installation Logic
src/cli/commands.js
Replaces post-commit hook with pre-push hook. New PRE_PUSH_SCRIPT computes commit range (new branch vs. update), iterates over commits running process-commit per SHA, and conditionally executes git-mind suggest if GITMIND_AGENT environment variable is set. Updates messaging and error reporting.
CLI Help Text
bin/git-mind.js
Updates install-hooks command description from "Install post-commit Git hook" to "Install pre-push Git hook (directives + suggest)".
Hook Installation Tests
test/hooks.test.js
Adds new test suite covering hook creation, file permissions, preservation of existing hooks, GITMIND_AGENT conditional guard, unconditional process-commit execution, and exit code guarantees.

Sequence Diagram

sequenceDiagram
    actor Dev as Developer
    participant Git as Git Pre-Push Hook
    participant PM as git-mind<br/>process-commit
    participant SG as git-mind<br/>suggest
    participant Agent as Claude Agent

    Dev->>Git: git push (new/updated branch)
    activate Git
    Git->>Git: Compute commit range<br/>(new branch vs. update)
    loop For each commit SHA
        Git->>PM: npx git-mind process-commit [SHA]
        activate PM
        PM->>PM: Process commit directives
        deactivate PM
    end
    alt GITMIND_AGENT is set
        Git->>SG: npx git-mind suggest
        activate SG
        SG->>Agent: Request review (Claude)
        activate Agent
        Agent-->>SG: Suggestions JSON
        deactivate Agent
        deactivate SG
    end
    Git-->>Dev: exit 0
    deactivate Git
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~28 minutes


Poem

From post to pre, the hook soars high,
Each push now summons Claude nearby,
Pre-push commits in review array,
Agents converge without delay,
Git-mind suggests before they fly! ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Changes to src/cli/commands.js and bin/git-mind.js replace post-commit hooks with pre-push hooks—a behavioral change not listed in issue #293 requirements and not justified in the PR description. Either revert the post-commit-to-pre-push hook migration to a separate PR with full justification and testing, or update the PR description to document this scope expansion and its rationale.
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed Title clearly and concisely summarizes the primary change: adding CI infrastructure to dogfood the git-mind suggest action with Claude CLI.
Description check ✅ Passed PR description is comprehensive, addresses all required template sections (summary, problem statement, ADR compliance, architecture gates, scope control, backward compatibility, test plan, security/operational notes), and directly maps to issue #293 objectives.
Linked Issues check ✅ Passed All coding requirements from issue #293 are met: workflow created with correct trigger events, Claude CLI agent configured, guards implemented (drafts, bots, API key), continue-on-error set, fetch-depth: 0 for full history, and concurrency control defined.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/dogfood-suggest-action

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cbf4b9dea4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +60 to +64
uses: ./
with:
agent: 'claude -p --output-format json'
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Run trusted action code when exposing repository secrets

This step executes the local action from the PR checkout (uses: ./) while injecting ANTHROPIC_API_KEY, and on pull_request events that action code is sourced from the PR head. A contributor can modify action.yml or scripts it runs (including npm ci lifecycle hooks in the composite action) to exfiltrate the secret during CI, so this workflow should run trusted code from the base branch when secrets are present (for example via pull_request_target + trusted checkout) or avoid passing secrets to PR-head code.

Useful? React with 👍 / 👎.

…ggest (#293)

Post-commit fires on every rebase replay, creating orphan edges. Pre-push
runs once before commits leave the machine — processes directives via
git rev-list and runs suggest when GITMIND_AGENT is set. Always exits 0.
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/cli/commands.js (1)

309-311: ⚠️ Potential issue | 🟡 Minor

Stale JSDoc: processCommitCmd still documents the old post-commit hook context.

-/**
- * Process a commit's directives (called by post-commit hook).
+ * Process a commit's directives (called by pre-push hook).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/cli/commands.js` around lines 309 - 311, The JSDoc above processCommitCmd
is stale — it still says "called by post-commit hook" and doesn't reflect the
function's current behavior/parameters; update the JSDoc for processCommitCmd to
accurately describe its purpose, real invocation context, and parameters (e.g.,
cwd) and any return value or side effects so the comment matches the
implementation; locate the comment immediately above the processCommitCmd
function declaration and replace the outdated hook-specific text with a concise,
accurate description of when and how processCommitCmd is used.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/gitmind-suggest.yml:
- Around line 18-20: The current GitHub Actions workflow if condition only
excludes 'dependabot[bot]' which allows other automation actors to trigger the
job and consume API quota; update the if condition used in the workflow (the if:
> block) to also exclude known automation actors such as 'renovate[bot]' and
'github-actions[bot]' (and any organization-specific bot names you use)
alongside 'dependabot[bot]' so that those actors are skipped when evaluating the
job run.
- Around line 18-20: The workflow currently only excludes 'dependabot[bot]';
update the if conditional in the gitmind-suggest.yml workflow (the "if:"
expression) to broadly exclude bot actors by replacing or extending the
github.actor check with a suffix test such as !endsWith(github.actor, '[bot]')
(e.g. use "!github.event.pull_request.draft && !endsWith(github.actor,
'[bot]')") so renovate[bot], github-actions[bot], and other bot actors are
skipped as well.
- Around line 54-56: The workflow currently installs `@anthropic-ai/claude-code`
without a fixed version; update the install step so the global npm install pins
the package to the exact safe version (e.g., change the command that currently
reads npm install -g `@anthropic-ai/claude-code` to install the exact release,
such as npm install -g `@anthropic-ai/claude-code`@1.0.108) to prevent
unintentionally running unvetted code and allow Dependabot to manage future
updates.
- Around line 54-56: Replace the deprecated and unpinned npm installation in the
"Install Claude CLI" step (currently using `npm install -g
`@anthropic-ai/claude-code``) with the native installer and pin to a known stable
release; specifically, remove the npm command and invoke the native installer
with the correct syntax `bash -s VERSION`, using a pinned VERSION (for example
`1.0.108`) instead of `--version` so the workflow installs a fixed, auditable
Claude CLI release.

In `@src/cli/commands.js`:
- Around line 259-263: When remote_sha is all zeros (new branch) the code
currently sets RANGE="HEAD~10..HEAD" which picks commits from the checked-out
branch; change that to use the pushed tip instead so we run against the branch
being pushed. Replace the HEAD-based range with
RANGE="${local_sha}~10..${local_sha}" (use the existing local_sha variable) so
process-commit and suggest operate on the last 10 commits ending at local_sha;
keep the else branch for the normal "${remote_sha}..${local_sha}" case.

In `@test/hooks.test.js`:
- Around line 130-138: The test causes installHooks to set process.exitCode = 1
and never restores it; wrap the call to installHooks (or capture
process.exitCode before the call) and restore it after the assertion so the
global exit code is not leaked. Specifically, in the test case that calls
installHooks, save const originalExitCode = process.exitCode (or undefined), run
installHooks(tempDir), perform the existing assertions on the hook file, then
reset process.exitCode = originalExitCode (or delete it) — alternatively assert
that process.exitCode === 1 and then reset it — to ensure no side-effect remains
after the test.
- Line 108: Remove the redundant explicit mkdir call that creates join(tempDir,
'.git', 'hooks') after running git init; instead rely on git init to create the
hooks dir and replace the mkdir invocation with an assertion that the directory
exists (or let the test fail if it does not) so missing directories in the test
environment are surfaced—update the test to reference the same tempDir and check
that join(tempDir, '.git', 'hooks') exists rather than creating it with mkdir.

---

Outside diff comments:
In `@src/cli/commands.js`:
- Around line 309-311: The JSDoc above processCommitCmd is stale — it still says
"called by post-commit hook" and doesn't reflect the function's current
behavior/parameters; update the JSDoc for processCommitCmd to accurately
describe its purpose, real invocation context, and parameters (e.g., cwd) and
any return value or side effects so the comment matches the implementation;
locate the comment immediately above the processCommitCmd function declaration
and replace the outdated hook-specific text with a concise, accurate description
of when and how processCommitCmd is used.

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 122981a and 561c33b.

📒 Files selected for processing (4)
  • .github/workflows/gitmind-suggest.yml
  • bin/git-mind.js
  • src/cli/commands.js
  • test/hooks.test.js

Comment on lines +18 to +20
if: >
!github.event.pull_request.draft &&
github.actor != 'dependabot[bot]'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Bot guard only excludes dependabot[bot] — other automation actors will consume API quota.

renovate[bot], github-actions[bot], and custom bots are not excluded. Unless intentional, tighten the guard.

🤖 Proposed fix
     if: >
       !github.event.pull_request.draft &&
-      github.actor != 'dependabot[bot]'
+      github.actor != 'dependabot[bot]' &&
+      !endsWith(github.actor, '[bot]')
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if: >
!github.event.pull_request.draft &&
github.actor != 'dependabot[bot]'
if: >
!github.event.pull_request.draft &&
github.actor != 'dependabot[bot]' &&
!endsWith(github.actor, '[bot]')
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/gitmind-suggest.yml around lines 18 - 20, The current
GitHub Actions workflow if condition only excludes 'dependabot[bot]' which
allows other automation actors to trigger the job and consume API quota; update
the if condition used in the workflow (the if: > block) to also exclude known
automation actors such as 'renovate[bot]' and 'github-actions[bot]' (and any
organization-specific bot names you use) alongside 'dependabot[bot]' so that
those actors are skipped when evaluating the job run.

🧹 Nitpick | 🔵 Trivial

Bot guard only excludes dependabot[bot] — other automation actors will consume API credits.

renovate[bot], github-actions[bot], and any custom bot actors are not excluded. Unless intentional, add a broader guard.

🤖 Proposed fix
     if: >
       !github.event.pull_request.draft &&
-      github.actor != 'dependabot[bot]'
+      github.actor != 'dependabot[bot]' &&
+      github.actor != 'renovate[bot]' &&
+      !endsWith(github.actor, '[bot]')
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/gitmind-suggest.yml around lines 18 - 20, The workflow
currently only excludes 'dependabot[bot]'; update the if conditional in the
gitmind-suggest.yml workflow (the "if:" expression) to broadly exclude bot
actors by replacing or extending the github.actor check with a suffix test such
as !endsWith(github.actor, '[bot]') (e.g. use "!github.event.pull_request.draft
&& !endsWith(github.actor, '[bot]')") so renovate[bot], github-actions[bot], and
other bot actors are skipped as well.

Comment on lines +54 to +56
- name: Install Claude CLI
if: steps.check-key.outputs.skip != 'true'
run: npm install -g @anthropic-ai/claude-code
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

@anthropic-ai/claude-code npm package latest version

💡 Result:

The latest published version of @anthropic-ai/claude-code on npm is 1.0.108. [1]

Source: npm package “Versions” tab shows Version 1.0.108 and “Last publish 5 hours ago.” [1]

References

  1. @anthropic-ai/claude-code (npm, versions tab)

Pin @anthropic-ai/claude-code to an exact version; unpinned global installs are indefensible.

Line 56: npm install -g @anthropic-ai/claude-code`` fetches whatever the registry serves on the next run. One semver bump (malicious or accidental) and your workflow executes unknown code with ANTHROPIC_API_KEY access. No audit trail, no rollback, silent failure. Current stable is `1.0.108` — pin it and let Dependabot handle updates.

Fix
-        run: npm install -g `@anthropic-ai/claude-code`
+        run: npm install -g `@anthropic-ai/claude-code`@1.0.108
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Install Claude CLI
if: steps.check-key.outputs.skip != 'true'
run: npm install -g @anthropic-ai/claude-code
- name: Install Claude CLI
if: steps.check-key.outputs.skip != 'true'
run: npm install -g `@anthropic-ai/claude-code`@1.0.108
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/gitmind-suggest.yml around lines 54 - 56, The workflow
currently installs `@anthropic-ai/claude-code` without a fixed version; update the
install step so the global npm install pins the package to the exact safe
version (e.g., change the command that currently reads npm install -g
`@anthropic-ai/claude-code` to install the exact release, such as npm install -g
`@anthropic-ai/claude-code`@1.0.108) to prevent unintentionally running unvetted
code and allow Dependabot to manage future updates.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Anthropic Claude CLI npm deprecated official documentation

💡 Result:

Anthropic’s official Claude Code (Claude CLI) docs state that “NPM installation is deprecated” and recommend using the native installation method instead; to migrate an existing npm install to native, run claude install. The same page still shows the legacy command npm install -g @anthropic-ai/claude-code`` under “NPM installation (deprecated)”. [1]

Recent Claude CLI release notes also mention an added deprecation notification for npm installations, pointing users to run claude install and to the same “getting started” documentation page. [2]

Sources:
[1] Anthropic Claude Code Docs – “Set up Claude Code” → “NPM installation (deprecated)”
[2] Claude CLI Release Notes (notes referencing npm-install deprecation notice)


🌐 Web query:

@anthropic-ai/claude-code npm package latest version

💡 Result:

The latest published version of the @anthropic-ai/claude-code npm package is 1.0.108 (last published ~5 hours ago). [1]

Source: npm package “Versions” tab. [1]


🌐 Web query:

Anthropic Claude CLI native installer setup github

💡 Result:

  • Official GitHub repo (Claude Code CLI): anthropics/claude-code (README includes install commands and project details). [1]
  • Native (binary) installer setup (Beta): Anthropic’s official setup docs recommend installing via the hosted installer scripts (not a GitHub “native installer” release asset): [2]
    • macOS / Linux / WSL: curl -fsSL https://claude.ai/install.sh | bash
    • Windows (PowerShell): irm https://claude.ai/install.ps1 | iex
    • You can also pin a version (e.g., ... | bash -s 1.0.58) and, if you already have Claude Code installed, start native install via claude install. [2]
  • Alternative install path (Node): npm install -g @anthropic-ai/claude-code`` (also documented in the repo + docs). [1][2]

🌐 Web query:

Claude CLI binary path installation $HOME/.claude/bin official documentation

💡 Result:

Anthropic’s official Claude Code docs do not state that the CLI binary installs to $HOME/.claude/bin. In the official docs, ~/.claude/ is used for Claude Code’s user configuration, while the claude executable comes from your install method. (docs.anthropic.com)

Official install methods & where the claude binary comes from:

  • Global npm install (standard):

    • Install: npm install -g @anthropic-ai/claude-code`` (docs.anthropic.com)
    • Binary path is your global npm “bin” directory (varies by system). To see the exact location:
      which claude
      npm prefix -g
      ls -l "$(npm prefix -g)/bin/claude"
  • Native binary install (beta):

    • Install via the official script (macOS/Linux/WSL): curl -fsSL https://claude.ai/install.sh | bash (docs.anthropic.com)
    • After install, Anthropic recommends running:
      claude doctor
      to verify the installation type/version. (docs.anthropic.com)

Citations:


npm install -g @anthropic-ai/claude-code`` is deprecated AND unpinned — this step will break.

"Installation via npm is deprecated. Use one of the recommended methods below." Anthropic's official documentation and release notes are explicit about this. The package itself now ships with a deprecation notification for npm installations.

Beyond deprecation, the install is unpinned — every run silently picks up whatever the registry serves, with no auditability or rollback path if a breaking release lands.

🚑 Proposed fix — switch to the native installer at the current version
      - name: Install Claude CLI
        if: steps.check-key.outputs.skip != 'true'
-       run: npm install -g `@anthropic-ai/claude-code`
+       run: curl -fsSL https://claude.ai/install.sh | bash -s 1.0.108

(The proposed fix in the original comment uses an incorrect version number 2.1.52 and malformed syntax --version; the correct native installer syntax is bash -s VERSION where VERSION is the pinned release like 1.0.108.)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/gitmind-suggest.yml around lines 54 - 56, Replace the
deprecated and unpinned npm installation in the "Install Claude CLI" step
(currently using `npm install -g `@anthropic-ai/claude-code``) with the native
installer and pin to a known stable release; specifically, remove the npm
command and invoke the native installer with the correct syntax `bash -s
VERSION`, using a pinned VERSION (for example `1.0.108`) instead of `--version`
so the workflow installs a fixed, auditable Claude CLI release.

Comment on lines +259 to +263
if [ "$remote_sha" = "$ZERO" ]; then
RANGE="HEAD~10..HEAD" # new branch — use last 10
else
RANGE="\${remote_sha}..\${local_sha}"
fi
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

HEAD~10..HEAD is the wrong range for new branch pushes — it processes the wrong commits.

When remote_sha is all-zeros (new branch), HEAD is the currently checked-out ref, which is NOT necessarily the branch being pushed. A user can do git push origin feature-branch while sitting on main; every process-commit call and the suggest invocation will run against main's last 10 commits, not feature-branch's.

local_sha is the exact tip being pushed and is always available at this point in the loop.

🐛 Proposed fix
-    RANGE="HEAD~10..HEAD"  # new branch — use last 10
+    RANGE="${local_sha}~10..${local_sha}"  # new branch — use last 10
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/cli/commands.js` around lines 259 - 263, When remote_sha is all zeros
(new branch) the code currently sets RANGE="HEAD~10..HEAD" which picks commits
from the checked-out branch; change that to use the pushed tip instead so we run
against the branch being pushed. Replace the HEAD-based range with
RANGE="${local_sha}~10..${local_sha}" (use the existing local_sha variable) so
process-commit and suggest operate on the last 10 commits ending at local_sha;
keep the else branch for the normal "${remote_sha}..${local_sha}" case.

beforeEach(async () => {
tempDir = await mkdtemp(join(tmpdir(), 'gitmind-test-'));
execSync('git init', { cwd: tempDir, stdio: 'ignore' });
await mkdir(join(tempDir, '.git', 'hooks'), { recursive: true });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Redundant mkdirgit init already creates .git/hooks.

git init at line 107 unconditionally creates .git/hooks. The mkdir with { recursive: true } is a no-op in the happy path and masks any scenario where the directory is unexpectedly absent (which would be a test-environment signal worth catching, not silently creating).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/hooks.test.js` at line 108, Remove the redundant explicit mkdir call
that creates join(tempDir, '.git', 'hooks') after running git init; instead rely
on git init to create the hooks dir and replace the mkdir invocation with an
assertion that the directory exists (or let the test fail if it does not) so
missing directories in the test environment are surfaced—update the test to
reference the same tempDir and check that join(tempDir, '.git', 'hooks') exists
rather than creating it with mkdir.

Comment on lines +130 to +138
it('does not overwrite existing hook', async () => {
const existingContent = '#!/bin/sh\necho "existing hook"';
await writeFile(join(tempDir, '.git', 'hooks', 'pre-push'), existingContent);

await installHooks(tempDir);

const prePush = await readFile(join(tempDir, '.git', 'hooks', 'pre-push'), 'utf-8');
expect(prePush).toBe(existingContent);
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

process.exitCode side-effect leaks out of this test and will poison the runner's exit code.

installHooks sets process.exitCode = 1 when a hook already exists (see src/cli/commands.js line 296). This test deliberately triggers that path but never restores process.exitCode afterward. Any subsequent test — or the Vitest process itself — will inherit exit code 1, making the suite appear failed even when every assertion passes.

Fix: capture and restore process.exitCode around the call, or assert + reset it explicitly.

🔥 Proposed fix
  it('does not overwrite existing hook', async () => {
    const existingContent = '#!/bin/sh\necho "existing hook"';
    await writeFile(join(tempDir, '.git', 'hooks', 'pre-push'), existingContent);

+   const prevExitCode = process.exitCode;
    await installHooks(tempDir);
+   expect(process.exitCode).toBe(1);
+   process.exitCode = prevExitCode;

    const prePush = await readFile(join(tempDir, '.git', 'hooks', 'pre-push'), 'utf-8');
    expect(prePush).toBe(existingContent);
  });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/hooks.test.js` around lines 130 - 138, The test causes installHooks to
set process.exitCode = 1 and never restores it; wrap the call to installHooks
(or capture process.exitCode before the call) and restore it after the assertion
so the global exit code is not leaked. Specifically, in the test case that calls
installHooks, save const originalExitCode = process.exitCode (or undefined), run
installHooks(tempDir), perform the existing assertions on the hook file, then
reset process.exitCode = originalExitCode (or delete it) — alternatively assert
that process.exitCode === 1 and then reset it — to ensure no side-effect remains
after the test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dogfood git-mind suggest action with Claude CLI

1 participant