Summary
Every subcommand of ruvector graph prints success-shaped output for work it never performs. --create says it is creating a node and creates nothing; --query echoes the Cypher and executes nothing; --relate is declared as an option but has no handler at all; --info advertises "Show graph info and stats" and prints a capability banner with no stats. All exit 0.
The command never instantiates GraphDatabase. It requires @ruvector/graph-node only to check that it is present, then falls through to console.log.
This matters because the failure is invisible: with the package correctly installed, a user gets Creating node: Person and an exit code of 0, and nothing has happened. Nothing distinguishes that from a working write.
Environment
ruvector 0.2.41 · @ruvector/graph-node 2.0.4 · node v22.23.0 · darwin arm64. ruvector doctor reports all checks passed, including ✓ @ruvector/graph-node installed.
Observed
$ ruvector graph --create Person --properties '{"name":"Alice"}'
Creating node: Person
Properties: { "name": "Alice" }
$ echo $?
0
Nothing is written — no file appears, and there is nowhere for it to go (see below).
$ ruvector graph --query "MATCH (n) RETURN n"
Cypher Query: MATCH (n) RETURN n
Note: Full Cypher execution requires running ruvector-server
$ ruvector graph --relate "a:KNOWS:b"
(no output beyond the banner — the option is parsed and ignored)
$ ruvector graph --info
@ruvector/graph-node is available!
Platform: darwin-arm64
Available operations: --query / --create / --relate
--info's help string is "Show graph info and stats". It reports neither; it duplicates what doctor already prints.
Cause
In bin/cli.js, the graph action (around line 1770) handles each option with console.log only. The --query branch carries the comment:
// Actual implementation would execute the query
--relate has no if (options.relate) block at all.
Notably the code to do this correctly already exists in the same file — the demo --graph path (around line 2871) does const g = new GraphDatabase() and calls createNode / createEdge / query against it. The graph command could use the same approach.
A second, blocking gap
Even with handlers, the command has no way to address a stored graph. There is no --path / --db / --storage option, and:
const { GraphDatabase } = require('@ruvector/graph-node');
new GraphDatabase(); // constructor arity 0
// isPersistent() === false, getStoragePath() === null, stats() === {}
So any node created by the CLI would vanish at process exit, and --query would always run against an empty in-memory graph. A storage-path option looks necessary for the command to be useful at all, unless the intent is that everything goes through ruvector server.
Suggested resolution
Any of these would be an improvement over the current state, in descending order of preference:
- Implement the subcommands against
GraphDatabase, and add a --path option so the graph persists.
- If Cypher genuinely requires
ruvector server, make --query exit non-zero with that message instead of printing it as a note after echoing the query, and drop --create/--relate until they work.
- At minimum, do not print
Creating node: … when nothing is created, and fix --info's help text to match what it does.
Point 2 is the important one: a stub that exits 0 with encouraging output is worse than a missing feature, because it is indistinguishable from success in a script.
Unrelated minor bug spotted alongside: ruvector info prints Core Version: [object Object] — it interpolates core.version without calling it, since @ruvector/core exports it as a function. Called properly it returns 0.1.29.
Summary
Every subcommand of
ruvector graphprints success-shaped output for work it never performs.--createsays it is creating a node and creates nothing;--queryechoes the Cypher and executes nothing;--relateis declared as an option but has no handler at all;--infoadvertises "Show graph info and stats" and prints a capability banner with no stats. All exit 0.The command never instantiates
GraphDatabase. Itrequires@ruvector/graph-nodeonly to check that it is present, then falls through toconsole.log.This matters because the failure is invisible: with the package correctly installed, a user gets
Creating node: Personand an exit code of 0, and nothing has happened. Nothing distinguishes that from a working write.Environment
ruvector 0.2.41 · @ruvector/graph-node 2.0.4 · node v22.23.0 · darwin arm64.
ruvector doctorreports all checks passed, including✓ @ruvector/graph-node installed.Observed
Nothing is written — no file appears, and there is nowhere for it to go (see below).
--info's help string is "Show graph info and stats". It reports neither; it duplicates whatdoctoralready prints.Cause
In
bin/cli.js, thegraphaction (around line 1770) handles each option withconsole.logonly. The--querybranch carries the comment:// Actual implementation would execute the query--relatehas noif (options.relate)block at all.Notably the code to do this correctly already exists in the same file — the
demo --graphpath (around line 2871) doesconst g = new GraphDatabase()and callscreateNode/createEdge/queryagainst it. Thegraphcommand could use the same approach.A second, blocking gap
Even with handlers, the command has no way to address a stored graph. There is no
--path/--db/--storageoption, and:So any node created by the CLI would vanish at process exit, and
--querywould always run against an empty in-memory graph. A storage-path option looks necessary for the command to be useful at all, unless the intent is that everything goes throughruvector server.Suggested resolution
Any of these would be an improvement over the current state, in descending order of preference:
GraphDatabase, and add a--pathoption so the graph persists.ruvector server, make--queryexit non-zero with that message instead of printing it as a note after echoing the query, and drop--create/--relateuntil they work.Creating node: …when nothing is created, and fix--info's help text to match what it does.Point 2 is the important one: a stub that exits 0 with encouraging output is worse than a missing feature, because it is indistinguishable from success in a script.
Unrelated minor bug spotted alongside:
ruvector infoprintsCore Version: [object Object]— it interpolatescore.versionwithout calling it, since@ruvector/coreexports it as a function. Called properly it returns 0.1.29.