Skip to content

fix: derive CLI version from git tags instead of hard-coded package.json#1221

Merged
cv merged 8 commits intomainfrom
fix/derive-version-from-git-tags
Apr 1, 2026
Merged

fix: derive CLI version from git tags instead of hard-coded package.json#1221
cv merged 8 commits intomainfrom
fix/derive-version-from-git-tags

Conversation

@cv
Copy link
Copy Markdown
Contributor

@cv cv commented Apr 1, 2026

Problem

nemoclaw -v reported v0.1.0 — a hard-coded value in package.json that was never updated when new v* git tags were created. The install.sh banner had the same issue.

Solution

Derive the version from git tags at runtime, with a layered fallback chain:

Install path Primary source Fallback
Dev clone (full repo) git describe --tags --match "v*" package.json
install.sh remote (shallow clone) git describe after explicit v* tag fetch .version file stamped during install
npm install -g (published tarball) .version stamped by prepublishOnly package.json

Pre-push hook

Added scripts/check-version-tag-sync.sh as a prek pre-push hook. When pushing a v* tag, it verifies package.json at the tagged commit has a matching version. Regular branch pushes are unaffected.

Files changed

  • bin/lib/version.js (new) — version resolver: git describe → .versionpackage.json
  • bin/nemoclaw.js — uses getVersion() instead of pkg.version
  • install.shresolve_installer_version() uses same fallback chain; fetches v* tags into shallow clones
  • package.jsonprepublishOnly stamps .version; files includes it in tarball
  • .gitignore — ignores generated .version
  • scripts/check-version-tag-sync.sh (new) — pre-push guard
  • .pre-commit-config.yaml — registers the pre-push hook
  • test/install-preflight.test.js — updated for new version resolution

Testing

  • All 740 tests pass
  • Verified all install paths (dev clone, shallow clone, tag divergence)
  • Verified pre-push hook blocks/passes correctly

Summary by CodeRabbit

  • New Features

    • CLI and installer now determine and display releases using git tags, stamped version files, or package metadata for more reliable version reporting.
    • Health poll retry counts and intervals for gateway operations are configurable via environment variables.
  • Chores

    • Added a pre-push check to ensure git tag and package.json version stay in sync.
    • .version files are now ignored.
  • Tests

    • Tests updated to accept git-describe style versions, use shorter CLI timeouts, and include minor typing/formatting refactors.

The -v flag and help output previously read the version from package.json,
which was hard-coded at 0.1.0 and never updated when new git tags were
created. This caused nemoclaw -v to report the wrong version.

Changes:
- Add bin/lib/version.js: resolves version from git describe, then
  .version file, then package.json as a last resort
- Update bin/nemoclaw.js to use getVersion() instead of pkg.version
- Update install.sh resolve_installer_version() with the same
  git -> .version -> package.json fallback chain
- Fetch v* tags into shallow clones during remote install so git
  describe works reliably, and stamp .version as belt-and-suspenders
- Stamp .version in prepublishOnly for npm tarball installs
- Add pre-push hook (scripts/check-version-tag-sync.sh) that blocks
  pushing a v* tag when package.json version doesn't match
- Update tests to reflect the new version resolution behavior
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 1, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Unifies version resolution to prefer Git tags, then a root .version file, then package.json. Adds a pre-push hook and a validation script to ensure tag ↔ package.json sync, integrates the resolver into CLI/installer, makes gateway polling windows configurable via env, and updates related tests.

Changes

Cohort / File(s) Summary
Ignore & Hook Config
\.gitignore, \.pre-commit-config.yaml
Add .version to .gitignore; register a local pre-push hook version-tag-sync running scripts/check-version-tag-sync.sh (always_run, pass_filenames: false, priority: 10).
Version Resolver
bin/lib/version.js
New getVersion() helper: tries git describe --tags --match "v*" (strip v), then root .version, then package.json version; suppresses intermediate errors; exports getVersion.
CLI Integration
bin/nemoclaw.js
Replace direct package.json reads with getVersion() for help() and --version output; remove redundant package.json requires.
Installer
install.sh
resolve_installer_version() now prefers git tags → .versionpackage.json; shallow clone path fetches tag refs and stamps .version to ensure reliable resolution in clones.
Version Validation Script
scripts/check-version-tag-sync.sh
Add script that compares refs/tags/v* (sans v) to package.json version at the tagged commit; supports --check mode and stdin-driven pre-push validation; exits non-zero on mismatch.
Onboard Polling Config
bin/lib/onboard.js
Add envInt(name, fallback) and make gateway health/recovery polling count and interval configurable via NEMOCLAW_HEALTH_POLL_COUNT and NEMOCLAW_HEALTH_POLL_INTERVAL (defaults preserved).
Tests — Version, CLI, Typings & Refactors
test/install-preflight.test.js, test/cli.test.js, test/uninstall.test.js, nemoclaw/src/blueprint/snapshot.test.ts, nemoclaw/src/blueprint/runner.test.ts, nemoclaw/src/blueprint/state.test.ts
Loosen version expectations to accept git-describe formats; adjust SCRIPT_DIR sourcing order; inject poll env vars into CLI test runner and reduce timeouts; add type-only fs imports for mocks; refactor/formatting-only test updates.
Misc
\.version, small test/type tweaks
Add .version to ignore; minor whitespace/type-annotation/test adjustments across files.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI
    participant GitRepo
    participant VersionFile as .version
    participant PkgJSON as package.json

    User->>CLI: Request version (e.g., --version)
    CLI->>GitRepo: git describe --tags --match "v*"
    alt Git tags exist
        GitRepo-->>CLI: Return tag (e.g., v1.2.3)
        CLI->>CLI: Strip leading 'v'
        CLI-->>User: Display version
    else No git tags
        CLI->>VersionFile: Read .version
        alt .version exists
            VersionFile-->>CLI: Return version
            CLI-->>User: Display version
        else .version missing
            CLI->>PkgJSON: Read version field
            PkgJSON-->>CLI: Return version
            CLI-->>User: Display version
        end
    end
Loading
sequenceDiagram
    participant Dev
    participant Git
    participant PrePush
    participant Validator as check-version-tag-sync.sh
    participant Repo
    participant PkgJSON

    Dev->>Git: git push
    Git->>PrePush: Invoke pre-push hooks with pushed refs (stdin)
    PrePush->>Validator: Run script with refs
    Validator->>Repo: For each refs/tags/v* get tag name and commit SHA
    loop For each tag
        Validator->>Repo: Read package.json at commit SHA
        Repo-->>Validator: package.json content
        Validator->>Validator: Compare tag (sans 'v') vs package.json.version
        alt Match
            Validator-->>PrePush: Log success
        else Mismatch
            Validator-->>PrePush: Log error
        end
    end
    alt Any mismatch
        PrePush-->>Dev: Reject push (non-zero)
    else
        PrePush-->>Dev: Allow push
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hopped through tags and files so bright,

Sniffed a .version in the night,
If tags were shy I peeked the stack,
Then read package.json — kept on track,
Now pushes hum and versions match. 🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the main change: deriving CLI version from git tags instead of hard-coded package.json, which is the core objective and primary change across the codebase.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/derive-version-from-git-tags

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

@cv cv requested review from ericksoa and kjw3 April 1, 2026 03:01
Copy link
Copy Markdown
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: 1

🧹 Nitpick comments (1)
scripts/check-version-tag-sync.sh (1)

24-29: Use ^{commit} to peel tag OIDs to commits when reading package.json.

The pre-push hook receives local_sha directly from git, which for annotated tags can be a tag object OID rather than a commit OID. While git show <tag-object>:package.json would fail, this scenario doesn't currently apply since the repository has no v* tags. However, applying the defensive fix ensures the script handles annotated tags correctly if they're used in the future.

🔧 Suggested fix
 while IFS=' ' read -r local_ref local_sha _remote_ref _remote_sha; do
   # Only care about v* tag pushes
   case "$local_ref" in
     refs/tags/v*)
       tag="${local_ref#refs/tags/}"
-      check_tag "$tag" "$local_sha" || errors=$((errors + 1))
+      commit_sha="$(git -C "$ROOT" rev-parse "${local_sha}^{commit}" 2>/dev/null || true)"
+      if [[ -z "$commit_sha" ]]; then
+        echo "${RED}✗${RESET} Tag ${tag}: could not resolve commit from ${local_sha:0:8}" >&2
+        errors=$((errors + 1))
+      else
+        check_tag "$tag" "$commit_sha" || errors=$((errors + 1))
+      fi
       ;;
   esac
 done

Also applies to: 84-90

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

In `@scripts/check-version-tag-sync.sh` around lines 24 - 29, The git show calls
in version_at_commit (and the similar block around lines 84-90) may receive tag
object OIDs for annotated tags; update the git invocations to peel tag OIDs to
commits by appending ^{commit} to the SHA (e.g., use "${sha}^{commit}" when
calling git show) so git reads package.json from the underlying commit even when
given an annotated tag OID; change both occurrences (the version_at_commit
function and the other git-show usage) accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@install.sh`:
- Around line 29-35: The git command assignment for git_ver can fail under set
-euo pipefail and abort the script; change the assignment in the block that sets
git_ver so the git describe failure doesn't cause exit (e.g., make the command
tolerant by appending "|| true" or using "|| echo ''" after git -C "$SCRIPT_DIR"
describe --tags --match 'v*' 2>/dev/null), keep the sed 's/^v//' processing as
before, and leave the subsequent [[ -n "$git_ver" ]] check and the .version /
package.json fallbacks intact; update the git_ver assignment line only
(referenced symbol: git_ver and the git -C "$SCRIPT_DIR" describe invocation).

---

Nitpick comments:
In `@scripts/check-version-tag-sync.sh`:
- Around line 24-29: The git show calls in version_at_commit (and the similar
block around lines 84-90) may receive tag object OIDs for annotated tags; update
the git invocations to peel tag OIDs to commits by appending ^{commit} to the
SHA (e.g., use "${sha}^{commit}" when calling git show) so git reads
package.json from the underlying commit even when given an annotated tag OID;
change both occurrences (the version_at_commit function and the other git-show
usage) accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6857b7f0-9f8d-4a35-8cfd-2fa581579374

📥 Commits

Reviewing files that changed from the base of the PR and between 71b4141 and 940f599.

📒 Files selected for processing (7)
  • .gitignore
  • .pre-commit-config.yaml
  • bin/lib/version.js
  • bin/nemoclaw.js
  • install.sh
  • scripts/check-version-tag-sync.sh
  • test/install-preflight.test.js

Comment thread install.sh
Copy link
Copy Markdown
Contributor

@ericksoa ericksoa left a comment

Choose a reason for hiding this comment

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

lgtm

@ericksoa
Copy link
Copy Markdown
Contributor

ericksoa commented Apr 1, 2026

revoke prior approval, please fix build issue + coderabbit feedback, thx

- snapshot.test.ts: replace forbidden import() type annotation in
  importOriginal generic with a top-level type-only import
- onboard.js: make health-poll count and interval configurable via
  NEMOCLAW_HEALTH_POLL_COUNT and NEMOCLAW_HEALTH_POLL_INTERVAL env vars
  (defaults unchanged for production)
- cli.test.js: set poll count=1 and interval=0 in test helper to
  eliminate ~40s of unnecessary sleep in gateway recovery tests
- cli.test.js: reduce test timeouts from 25s to 10s accordingly
- Apply Prettier formatting fixes from pre-commit hooks
Copy link
Copy Markdown
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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@bin/lib/onboard.js`:
- Around line 2149-2151: The code uses
Number(process.env.NEMOCLAW_HEALTH_POLL_COUNT) || 5 and
Number(process.env.NEMOCLAW_HEALTH_POLL_INTERVAL) || 2 which drops valid "0" and
accepts invalid numeric shapes; update the parsing to explicitly validate and
sanitize these env vars (e.g., parseInt/Number, check isFinite, clamp to a safe
integer range, and fall back to defaults only when the parsed value is NaN or
out-of-range) before using them as loop bounds/delays (variables:
healthPollCount, healthPollInterval); also change the polling loop (for (...) {
...; if (i < healthPollCount - 1) await sleep(healthPollInterval * 1000); }) so
the code does not sleep after the final attempt; apply the same validation
pattern to the other occurrences mentioned (the additional uses around the same
logic).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 773bd8cb-2368-4920-88ef-07039da96cf0

📥 Commits

Reviewing files that changed from the base of the PR and between 940f599 and 26bbb0f.

📒 Files selected for processing (4)
  • bin/lib/onboard.js
  • nemoclaw/src/blueprint/snapshot.test.ts
  • test/cli.test.js
  • test/uninstall.test.js
✅ Files skipped from review due to trivial changes (2)
  • nemoclaw/src/blueprint/snapshot.test.ts
  • test/uninstall.test.js

Comment thread bin/lib/onboard.js Outdated
Comment on lines +2149 to +2151
const healthPollCount = Number(process.env.NEMOCLAW_HEALTH_POLL_COUNT) || 5;
const healthPollInterval = Number(process.env.NEMOCLAW_HEALTH_POLL_INTERVAL) || 2;
for (let i = 0; i < healthPollCount; i++) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Validate poll env values before using them as loop bounds/delays.

Using Number(...) || default drops valid "0" values, accepts invalid numeric shapes, and can produce unsafe loop behavior. Also, recovery currently sleeps after the final poll attempt.

Proposed fix
-        const healthPollCount = Number(process.env.NEMOCLAW_HEALTH_POLL_COUNT) || 5;
-        const healthPollInterval = Number(process.env.NEMOCLAW_HEALTH_POLL_INTERVAL) || 2;
+        const parsedHealthPollCount = Number.parseInt(
+          process.env.NEMOCLAW_HEALTH_POLL_COUNT ?? "",
+          10,
+        );
+        const parsedHealthPollInterval = Number(process.env.NEMOCLAW_HEALTH_POLL_INTERVAL);
+        const healthPollCount =
+          Number.isInteger(parsedHealthPollCount) && parsedHealthPollCount > 0
+            ? parsedHealthPollCount
+            : 5;
+        const healthPollInterval =
+          Number.isFinite(parsedHealthPollInterval) && parsedHealthPollInterval >= 0
+            ? parsedHealthPollInterval
+            : 2;
@@
-  const recoveryPollCount = Number(process.env.NEMOCLAW_HEALTH_POLL_COUNT) || 10;
-  const recoveryPollInterval = Number(process.env.NEMOCLAW_HEALTH_POLL_INTERVAL) || 2;
+  const parsedRecoveryPollCount = Number.parseInt(
+    process.env.NEMOCLAW_HEALTH_POLL_COUNT ?? "",
+    10,
+  );
+  const parsedRecoveryPollInterval = Number(process.env.NEMOCLAW_HEALTH_POLL_INTERVAL);
+  const recoveryPollCount =
+    Number.isInteger(parsedRecoveryPollCount) && parsedRecoveryPollCount > 0
+      ? parsedRecoveryPollCount
+      : 10;
+  const recoveryPollInterval =
+    Number.isFinite(parsedRecoveryPollInterval) && parsedRecoveryPollInterval >= 0
+      ? parsedRecoveryPollInterval
+      : 2;
@@
-    sleep(recoveryPollInterval);
+    if (i < recoveryPollCount - 1) sleep(recoveryPollInterval);

Also applies to: 2160-2160, 2242-2244, 2256-2256

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

In `@bin/lib/onboard.js` around lines 2149 - 2151, The code uses
Number(process.env.NEMOCLAW_HEALTH_POLL_COUNT) || 5 and
Number(process.env.NEMOCLAW_HEALTH_POLL_INTERVAL) || 2 which drops valid "0" and
accepts invalid numeric shapes; update the parsing to explicitly validate and
sanitize these env vars (e.g., parseInt/Number, check isFinite, clamp to a safe
integer range, and fall back to defaults only when the parsed value is NaN or
out-of-range) before using them as loop bounds/delays (variables:
healthPollCount, healthPollInterval); also change the polling loop (for (...) {
...; if (i < healthPollCount - 1) await sleep(healthPollInterval * 1000); }) so
the code does not sleep after the final attempt; apply the same validation
pattern to the other occurrences mentioned (the additional uses around the same
logic).

cv added 5 commits March 31, 2026 20:24
Apply the same import type fs + importOriginal<typeof fs>() pattern
from snapshot.test.ts to runner.test.ts and state.test.ts for
consistency.
Replace Number(env) || default with a dedicated envInt() helper that
handles 0 correctly (Number('0') || 5 would silently fall back to 5),
rejects non-finite values, and clamps to non-negative integers.
The recovery loop in recoverGatewayRuntime slept unconditionally after
every iteration, including the last one. Guard with the same
i < count - 1 check used in startGatewayWithOptions.
@cv cv merged commit 39e9b1f into main Apr 1, 2026
8 checks passed
@cv cv deleted the fix/derive-version-from-git-tags branch April 1, 2026 04:12
realkim93 added a commit to realkim93/NemoClaw that referenced this pull request Apr 1, 2026
Merge origin/main into feat/jetson-orin-nano-support to resolve
conflicts from recent changes (NVIDIA#1208, NVIDIA#1200, NVIDIA#836, NVIDIA#1221, NVIDIA#1223).

Jetson detection now leverages main's UNIFIED_MEMORY_GPU_TAGS
with added jetson flag and /proc/device-tree fallback.

All 116 tests pass.
laitingsheng pushed a commit that referenced this pull request Apr 2, 2026
…son (#1221)

## Problem

`nemoclaw -v` reported `v0.1.0` — a hard-coded value in `package.json`
that was never updated when new `v*` git tags were created. The
`install.sh` banner had the same issue.

## Solution

Derive the version from git tags at runtime, with a layered fallback
chain:

| Install path | Primary source | Fallback |
|---|---|---|
| Dev clone (full repo) | `git describe --tags --match "v*"` |
`package.json` |
| `install.sh` remote (shallow clone) | `git describe` after explicit
`v*` tag fetch | `.version` file stamped during install |
| `npm install -g` (published tarball) | `.version` stamped by
`prepublishOnly` | `package.json` |

### Pre-push hook

Added `scripts/check-version-tag-sync.sh` as a prek pre-push hook. When
pushing a `v*` tag, it verifies `package.json` at the tagged commit has
a matching version. Regular branch pushes are unaffected.

## Files changed

- **`bin/lib/version.js`** (new) — version resolver: git describe →
`.version` → `package.json`
- **`bin/nemoclaw.js`** — uses `getVersion()` instead of `pkg.version`
- **`install.sh`** — `resolve_installer_version()` uses same fallback
chain; fetches `v*` tags into shallow clones
- **`package.json`** — `prepublishOnly` stamps `.version`; `files`
includes it in tarball
- **`.gitignore`** — ignores generated `.version`
- **`scripts/check-version-tag-sync.sh`** (new) — pre-push guard
- **`.pre-commit-config.yaml`** — registers the pre-push hook
- **`test/install-preflight.test.js`** — updated for new version
resolution

## Testing

- All 740 tests pass
- Verified all install paths (dev clone, shallow clone, tag divergence)
- Verified pre-push hook blocks/passes correctly


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* CLI and installer now determine and display releases using git tags,
stamped version files, or package metadata for more reliable version
reporting.
* Health poll retry counts and intervals for gateway operations are
configurable via environment variables.

* **Chores**
* Added a pre-push check to ensure git tag and package.json version stay
in sync.
  * `.version` files are now ignored.

* **Tests**
* Tests updated to accept git-describe style versions, use shorter CLI
timeouts, and include minor typing/formatting refactors.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
lakamsani pushed a commit to lakamsani/NemoClaw that referenced this pull request Apr 4, 2026
…son (NVIDIA#1221)

## Problem

`nemoclaw -v` reported `v0.1.0` — a hard-coded value in `package.json`
that was never updated when new `v*` git tags were created. The
`install.sh` banner had the same issue.

## Solution

Derive the version from git tags at runtime, with a layered fallback
chain:

| Install path | Primary source | Fallback |
|---|---|---|
| Dev clone (full repo) | `git describe --tags --match "v*"` |
`package.json` |
| `install.sh` remote (shallow clone) | `git describe` after explicit
`v*` tag fetch | `.version` file stamped during install |
| `npm install -g` (published tarball) | `.version` stamped by
`prepublishOnly` | `package.json` |

### Pre-push hook

Added `scripts/check-version-tag-sync.sh` as a prek pre-push hook. When
pushing a `v*` tag, it verifies `package.json` at the tagged commit has
a matching version. Regular branch pushes are unaffected.

## Files changed

- **`bin/lib/version.js`** (new) — version resolver: git describe →
`.version` → `package.json`
- **`bin/nemoclaw.js`** — uses `getVersion()` instead of `pkg.version`
- **`install.sh`** — `resolve_installer_version()` uses same fallback
chain; fetches `v*` tags into shallow clones
- **`package.json`** — `prepublishOnly` stamps `.version`; `files`
includes it in tarball
- **`.gitignore`** — ignores generated `.version`
- **`scripts/check-version-tag-sync.sh`** (new) — pre-push guard
- **`.pre-commit-config.yaml`** — registers the pre-push hook
- **`test/install-preflight.test.js`** — updated for new version
resolution

## Testing

- All 740 tests pass
- Verified all install paths (dev clone, shallow clone, tag divergence)
- Verified pre-push hook blocks/passes correctly


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* CLI and installer now determine and display releases using git tags,
stamped version files, or package metadata for more reliable version
reporting.
* Health poll retry counts and intervals for gateway operations are
configurable via environment variables.

* **Chores**
* Added a pre-push check to ensure git tag and package.json version stay
in sync.
  * `.version` files are now ignored.

* **Tests**
* Tests updated to accept git-describe style versions, use shorter CLI
timeouts, and include minor typing/formatting refactors.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
gemini2026 pushed a commit to gemini2026/NemoClaw that referenced this pull request Apr 14, 2026
…son (NVIDIA#1221)

## Problem

`nemoclaw -v` reported `v0.1.0` — a hard-coded value in `package.json`
that was never updated when new `v*` git tags were created. The
`install.sh` banner had the same issue.

## Solution

Derive the version from git tags at runtime, with a layered fallback
chain:

| Install path | Primary source | Fallback |
|---|---|---|
| Dev clone (full repo) | `git describe --tags --match "v*"` |
`package.json` |
| `install.sh` remote (shallow clone) | `git describe` after explicit
`v*` tag fetch | `.version` file stamped during install |
| `npm install -g` (published tarball) | `.version` stamped by
`prepublishOnly` | `package.json` |

### Pre-push hook

Added `scripts/check-version-tag-sync.sh` as a prek pre-push hook. When
pushing a `v*` tag, it verifies `package.json` at the tagged commit has
a matching version. Regular branch pushes are unaffected.

## Files changed

- **`bin/lib/version.js`** (new) — version resolver: git describe →
`.version` → `package.json`
- **`bin/nemoclaw.js`** — uses `getVersion()` instead of `pkg.version`
- **`install.sh`** — `resolve_installer_version()` uses same fallback
chain; fetches `v*` tags into shallow clones
- **`package.json`** — `prepublishOnly` stamps `.version`; `files`
includes it in tarball
- **`.gitignore`** — ignores generated `.version`
- **`scripts/check-version-tag-sync.sh`** (new) — pre-push guard
- **`.pre-commit-config.yaml`** — registers the pre-push hook
- **`test/install-preflight.test.js`** — updated for new version
resolution

## Testing

- All 740 tests pass
- Verified all install paths (dev clone, shallow clone, tag divergence)
- Verified pre-push hook blocks/passes correctly


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* CLI and installer now determine and display releases using git tags,
stamped version files, or package metadata for more reliable version
reporting.
* Health poll retry counts and intervals for gateway operations are
configurable via environment variables.

* **Chores**
* Added a pre-push check to ensure git tag and package.json version stay
in sync.
  * `.version` files are now ignored.

* **Tests**
* Tests updated to accept git-describe style versions, use shorter CLI
timeouts, and include minor typing/formatting refactors.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
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.

2 participants