Skip to content

fix(elizaos): use actual CLI version when rewriting workspace:* deps in scaffolded projects#6698

Open
ninglinLiu wants to merge 1 commit intoelizaOS:developfrom
ninglinLiu:fix/cli-scaffold-uses-hardcoded-version
Open

fix(elizaos): use actual CLI version when rewriting workspace:* deps in scaffolded projects#6698
ninglinLiu wants to merge 1 commit intoelizaOS:developfrom
ninglinLiu:fix/cli-scaffold-uses-hardcoded-version

Conversation

@ninglinLiu
Copy link
Copy Markdown

@ninglinLiu ninglinLiu commented Mar 30, 2026

Problem

elizaos create calls fixPackageJson to replace workspace:* references
in a scaffolded project's package.json. The replacement was hardcoded to
"^1.0.0" which is already behind the current release (2.0.0-alpha.109)
and will grow more stale with every release.

Users scaffolding TypeScript examples that depend on elizaos packages receive
an incorrect (stale) semver range, causing bun install / npm install to
resolve the wrong version.

Fix

Read the version from the CLI's own package.json at runtime — the same
approach already used in commands/version.ts.

Changes

  • packages/elizaos/src/commands/create.ts: add getCliVersion() helper,
    replace hardcoded "^1.0.0" with `^${getCliVersion()}`, export
    fixPackageJson for testability
  • packages/elizaos/src/__tests__/create.test.ts: 5 new unit tests

Testing

cd packages/elizaos
bun test   # 22 tests pass (17 pre-existing + 5 new)

<!-- greptile_comment -->

<h3>Greptile Summary</h3>

This PR fixes a stale hardcoded `"^1.0.0"` semver range in `elizaos create` by reading the actual installed CLI version from `package.json` at runtime, ensuring scaffolded projects always get the correct version of elizaOS dependencies.

**Key changes:**
- Adds `getCliVersion()` helper in `create.ts` that resolves the CLI's `package.json` via `__dirname` (the same path strategy used in `version.ts`)
- Replaces the hardcoded `"^1.0.0"` with `` `^${getCliVersion()}` `` in the `workspace:*` substitution loop
- Exports `fixPackageJson` so it can be unit-tested
- Adds 5 well-targeted unit tests covering the new behaviour as well as existing edge cases (devDeps/peerDeps, non-workspace values, `private` flag removal, missing file)

The fix is correct and the path resolution (`__dirname + ../../package.json`) resolves to the package root both from source (`src/commands/`) and from the compiled output (`dist/commands/`). Two minor style observations are noted inline: `getCliVersion()` lacks the error-handling fallback present in the sibling `version.ts`, and the version is re-read from disk on each `workspace:*` entry rather than once per `fixPackageJson` call.

<h3>Confidence Score: 5/5</h3>

Safe to merge — the core fix is correct and all remaining findings are minor P2 style suggestions.

Both changed files are well-implemented: the version resolution path is correct for source and dist layouts, and the new tests give good coverage. The only open items are a missing error-handling fallback (a robustness suggestion matching `version.ts` style) and a trivial per-iteration file read, neither of which affect correctness in normal usage.

No files require special attention.

<h3>Important Files Changed</h3>




| Filename | Overview |
|----------|----------|
| packages/elizaos/src/commands/create.ts | Adds `getCliVersion()` to read the CLI's own `package.json` at runtime and uses it to replace `workspace:*` dependencies; `fixPackageJson` is also exported for testability. Two minor style issues: missing fallback error handling (unlike `version.ts`) and the version is re-read from disk per dep entry instead of once. |
| packages/elizaos/src/__tests__/create.test.ts | New test file with 5 unit tests covering workspace:* replacement, devDeps/peerDeps, non-workspace dep preservation, private flag removal, and no-op on missing file. Good coverage for the new behaviour. |

</details>



<h3>Sequence Diagram</h3>

```mermaid
sequenceDiagram
    participant User
    participant CLI as elizaos create
    participant copy as copyExample()
    participant fix as fixPackageJson()
    participant ver as getCliVersion()
    participant pkg as CLI package.json

    User->>CLI: elizaos create
    CLI->>copy: copyExample(name, lang, dest)
    copy->>fix: fixPackageJson(dest/package.json)
    fix->>ver: getCliVersion()
    ver->>pkg: fs.readFileSync(__dirname/../../package.json)
    pkg-->>ver: { version: "2.0.0-alpha.109" }
    ver-->>fix: "2.0.0-alpha.109"
    fix->>fix: replace workspace:* → ^2.0.0-alpha.109
    fix->>fix: delete pkg.private
    fix-->>copy: done
    copy-->>CLI: done
    CLI-->>User: Project scaffolded with correct version

Comments Outside Diff (1)

  1. packages/elizaos/src/commands/create.ts, line 114-123 (link)

    P2 getCliVersion() invoked on every workspace:* entry

    getCliVersion() reads and parses package.json from disk on each loop iteration. For a scaffolded project with several workspace:* deps across dependencies, devDependencies, and peerDependencies, this means multiple redundant file-system reads. The version can be resolved once before the loop:

    export function fixPackageJson(filePath: string): void {
      if (!fs.existsSync(filePath)) return;
    
      const content = fs.readFileSync(filePath, "utf-8");
      const pkg = JSON.parse(content) as Record<string, unknown>;
      const cliVersion = getCliVersion(); // resolve once
    
      const fixDeps = (deps: Record<string, string> | undefined) => {
        if (!deps) return;
        for (const [key, value] of Object.entries(deps)) {
          if (value === "workspace:*") {
            deps[key] = `^${cliVersion}`;
          }
        }
      };
      // ...
    }

Reviews (1): Last reviewed commit: "fix(elizaos): replace hardcoded ^1.0.0 w..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

…PackageJson

Workspace: * references in scaffolded package.json were replaced with ^1.0.0 regardless of the installed CLI version. Read the version from the CLI own package.json at runtime (same pattern as version.ts). Export fixPackageJson and add 5 unit tests.
Made-with: Cursor
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 30, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0e3b52ba-1f76-429b-a8ce-49833a274da0

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

Comment on lines +19 to +24
function getCliVersion(): string {
const pkgPath = path.join(__dirname, "..", "..", "package.json");
const content = fs.readFileSync(pkgPath, "utf-8");
const pkg = JSON.parse(content) as { version: string };
return pkg.version;
}
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.

P2 Missing error-handling fallback (unlike version.ts)

The sibling version.ts wraps the same path resolution in a try/catch with a fallback one directory higher. getCliVersion() has no fallback, so if the path resolution ever fails (e.g., unusual install layouts or bundler outputs that shift __dirname), fixPackageJson will throw an unhandled error and crash the CLI during elizaos create.

Consider mirroring the pattern from version.ts:

function getCliVersion(): string {
  const primaryPath = path.join(__dirname, "..", "..", "package.json");
  try {
    const pkg = JSON.parse(fs.readFileSync(primaryPath, "utf-8")) as { version: string };
    return pkg.version;
  } catch {
    // Fallback for unusual install layouts (mirrors version.ts)
    const fallbackPath = path.join(__dirname, "..", "..", "..", "package.json");
    const pkg = JSON.parse(fs.readFileSync(fallbackPath, "utf-8")) as { version: string };
    return pkg.version;
  }
}

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.

1 participant