@leanlabsinnov/codegraph 0.1.7 → 0.1.8
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/README.md +2 -0
- package/dist/bin.js +1 -1
- package/dist/{chunk-OJ2SQ3YV.js → chunk-WU6GFDTU.js} +188 -10
- package/dist/chunk-WU6GFDTU.js.map +1 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-OJ2SQ3YV.js.map +0 -1
package/README.md
CHANGED
|
@@ -54,6 +54,8 @@ See [client setup docs](https://github.com/Cirilcetra/codegraph/blob/main/docs/c
|
|
|
54
54
|
| `codegraph wipe [path]` | Delete a repo's graph rows (`--yes` skips prompt) |
|
|
55
55
|
| `codegraph serve [--port N] [--host H]` | Boot the MCP server (default `:3748`) |
|
|
56
56
|
| `codegraph doctor` | Health check: Node, config, API keys, Kuzu, LLM |
|
|
57
|
+
| `codegraph update` | Check npm for a newer release and upgrade the global CLI |
|
|
58
|
+
| `codegraph update --check` | Show installed vs latest without installing |
|
|
57
59
|
| `codegraph config show` | Print resolved `~/.codegraph/config.json` |
|
|
58
60
|
| `codegraph config llm set [preset]` | Switch LLM preset (interactive picker if no arg) |
|
|
59
61
|
| `codegraph config llm test` | Round-trip the configured provider |
|
package/dist/bin.js
CHANGED
|
@@ -4585,17 +4585,188 @@ shutting down (${signal})...
|
|
|
4585
4585
|
});
|
|
4586
4586
|
}
|
|
4587
4587
|
|
|
4588
|
+
// src/commands/update.ts
|
|
4589
|
+
import { execFile as execFile2, spawn as spawn2 } from "child_process";
|
|
4590
|
+
import { promisify as promisify2 } from "util";
|
|
4591
|
+
import { confirm as confirm2 } from "@inquirer/prompts";
|
|
4592
|
+
import kleur8 from "kleur";
|
|
4593
|
+
|
|
4594
|
+
// src/version.ts
|
|
4595
|
+
import { createRequire as createRequire2 } from "module";
|
|
4596
|
+
import { dirname as dirname6, join as join5 } from "path";
|
|
4597
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
4598
|
+
var require3 = createRequire2(import.meta.url);
|
|
4599
|
+
var PACKAGE_NAME = "@leanlabsinnov/codegraph";
|
|
4600
|
+
function readPackageJson() {
|
|
4601
|
+
const pkgPath = join5(dirname6(fileURLToPath3(import.meta.url)), "..", "package.json");
|
|
4602
|
+
return require3(pkgPath);
|
|
4603
|
+
}
|
|
4604
|
+
var pkg = readPackageJson();
|
|
4605
|
+
var PACKAGE_VERSION = pkg.version;
|
|
4606
|
+
function isGlobalInstall() {
|
|
4607
|
+
try {
|
|
4608
|
+
const dir = dirname6(fileURLToPath3(import.meta.url));
|
|
4609
|
+
return dir.includes("node_modules") && dir.includes("@leanlabsinnov");
|
|
4610
|
+
} catch {
|
|
4611
|
+
return false;
|
|
4612
|
+
}
|
|
4613
|
+
}
|
|
4614
|
+
|
|
4615
|
+
// src/commands/update.ts
|
|
4616
|
+
var execFileAsync2 = promisify2(execFile2);
|
|
4617
|
+
function compareSemver(a, b) {
|
|
4618
|
+
const pa = a.split("-")[0]?.split(".").map((n) => Number.parseInt(n, 10) || 0) ?? [];
|
|
4619
|
+
const pb = b.split("-")[0]?.split(".").map((n) => Number.parseInt(n, 10) || 0) ?? [];
|
|
4620
|
+
for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
|
|
4621
|
+
const diff = (pa[i] ?? 0) - (pb[i] ?? 0);
|
|
4622
|
+
if (diff !== 0) return diff;
|
|
4623
|
+
}
|
|
4624
|
+
return 0;
|
|
4625
|
+
}
|
|
4626
|
+
async function fetchLatestVersion(tag = "latest") {
|
|
4627
|
+
const spec = tag === "latest" ? PACKAGE_NAME : `${PACKAGE_NAME}@${tag}`;
|
|
4628
|
+
const { stdout } = await execFileAsync2(
|
|
4629
|
+
"npm",
|
|
4630
|
+
["view", spec, "version", "--json"],
|
|
4631
|
+
{ env: process.env, timeout: 3e4 }
|
|
4632
|
+
);
|
|
4633
|
+
const trimmed = stdout.trim();
|
|
4634
|
+
if (trimmed.startsWith('"')) {
|
|
4635
|
+
return JSON.parse(trimmed);
|
|
4636
|
+
}
|
|
4637
|
+
return trimmed.replace(/^"|"$/g, "");
|
|
4638
|
+
}
|
|
4639
|
+
function runNpmGlobalInstall(tag) {
|
|
4640
|
+
const spec = tag === "latest" ? `${PACKAGE_NAME}@latest` : `${PACKAGE_NAME}@${tag}`;
|
|
4641
|
+
return new Promise((resolve3, reject) => {
|
|
4642
|
+
const child = spawn2("npm", ["install", "-g", spec], {
|
|
4643
|
+
stdio: "inherit",
|
|
4644
|
+
env: process.env,
|
|
4645
|
+
shell: process.platform === "win32"
|
|
4646
|
+
});
|
|
4647
|
+
child.on("error", reject);
|
|
4648
|
+
child.on("close", (code) => {
|
|
4649
|
+
if (code === 0) resolve3();
|
|
4650
|
+
else reject(new Error(`npm install -g exited with code ${code ?? "unknown"}`));
|
|
4651
|
+
});
|
|
4652
|
+
});
|
|
4653
|
+
}
|
|
4654
|
+
async function runUpdateCommand(opts = {}) {
|
|
4655
|
+
const tag = opts.tag ?? "latest";
|
|
4656
|
+
const current = PACKAGE_VERSION;
|
|
4657
|
+
const spinner = makeSpinner(`Checking npm for ${PACKAGE_NAME}@${tag}`).start();
|
|
4658
|
+
let latest;
|
|
4659
|
+
try {
|
|
4660
|
+
latest = await fetchLatestVersion(tag);
|
|
4661
|
+
spinner.succeed(`Latest on npm (@${tag}): ${kleur8.cyan(latest)}`);
|
|
4662
|
+
} catch (err) {
|
|
4663
|
+
spinner.fail("Could not reach the npm registry");
|
|
4664
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
4665
|
+
console.log(kleur8.dim(` ${msg}`));
|
|
4666
|
+
console.log(
|
|
4667
|
+
kleur8.yellow(
|
|
4668
|
+
` Try manually: npm install -g ${PACKAGE_NAME}@${tag === "latest" ? "latest" : tag}`
|
|
4669
|
+
)
|
|
4670
|
+
);
|
|
4671
|
+
process.exitCode = 1;
|
|
4672
|
+
return;
|
|
4673
|
+
}
|
|
4674
|
+
console.log(kleur8.dim(` installed: ${current}`));
|
|
4675
|
+
const cmp = compareSemver(current, latest);
|
|
4676
|
+
if (cmp === 0) {
|
|
4677
|
+
console.log(kleur8.green().bold("\n\u2713 You are already on the latest version."));
|
|
4678
|
+
return;
|
|
4679
|
+
}
|
|
4680
|
+
if (cmp > 0) {
|
|
4681
|
+
console.log(
|
|
4682
|
+
kleur8.yellow(
|
|
4683
|
+
`
|
|
4684
|
+
! Installed version (${current}) is newer than npm @${tag} (${latest}). You may be on a local tarball or pre-release build.`
|
|
4685
|
+
)
|
|
4686
|
+
);
|
|
4687
|
+
if (opts.check) return;
|
|
4688
|
+
} else {
|
|
4689
|
+
console.log(
|
|
4690
|
+
kleur8.yellow(`
|
|
4691
|
+
\u2191 Update available: ${kleur8.bold(current)} \u2192 ${kleur8.bold(latest)}`)
|
|
4692
|
+
);
|
|
4693
|
+
}
|
|
4694
|
+
if (opts.check) {
|
|
4695
|
+
console.log(kleur8.dim("\nRun `codegraph update` (without --check) to install."));
|
|
4696
|
+
return;
|
|
4697
|
+
}
|
|
4698
|
+
if (!isGlobalInstall()) {
|
|
4699
|
+
console.log(
|
|
4700
|
+
kleur8.yellow(
|
|
4701
|
+
"\n! This looks like a local/dev install (not a global npm package)."
|
|
4702
|
+
)
|
|
4703
|
+
);
|
|
4704
|
+
console.log(
|
|
4705
|
+
kleur8.dim(
|
|
4706
|
+
" Global update via npm may not replace the binary you are running.\n From the monorepo: pnpm -r build && cd packages/cli && pnpm pack\n Then: sudo npm install -g ./leanlabsinnov-codegraph-<version>.tgz"
|
|
4707
|
+
)
|
|
4708
|
+
);
|
|
4709
|
+
if (!opts.yes) {
|
|
4710
|
+
const proceed = await confirm2({
|
|
4711
|
+
message: "Try `npm install -g` anyway?",
|
|
4712
|
+
default: false
|
|
4713
|
+
});
|
|
4714
|
+
if (!proceed) return;
|
|
4715
|
+
}
|
|
4716
|
+
}
|
|
4717
|
+
if (!opts.yes) {
|
|
4718
|
+
const install = await confirm2({
|
|
4719
|
+
message: `Install ${PACKAGE_NAME}@${tag === "latest" ? latest : tag} globally via npm?`,
|
|
4720
|
+
default: true
|
|
4721
|
+
});
|
|
4722
|
+
if (!install) {
|
|
4723
|
+
console.log(kleur8.dim("Cancelled."));
|
|
4724
|
+
return;
|
|
4725
|
+
}
|
|
4726
|
+
}
|
|
4727
|
+
console.log();
|
|
4728
|
+
const installSpinner = makeSpinner(`Installing ${PACKAGE_NAME}@${tag}`).start();
|
|
4729
|
+
installSpinner.stop();
|
|
4730
|
+
try {
|
|
4731
|
+
await runNpmGlobalInstall(tag);
|
|
4732
|
+
} catch (err) {
|
|
4733
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
4734
|
+
console.log(kleur8.red().bold(`
|
|
4735
|
+
\u2717 Update failed: ${msg}`));
|
|
4736
|
+
if (/EACCES|permission denied/i.test(msg)) {
|
|
4737
|
+
console.log(
|
|
4738
|
+
kleur8.yellow(
|
|
4739
|
+
`
|
|
4740
|
+
hint: retry with sudo:
|
|
4741
|
+
sudo npm install -g ${PACKAGE_NAME}@${tag === "latest" ? "latest" : tag}`
|
|
4742
|
+
)
|
|
4743
|
+
);
|
|
4744
|
+
}
|
|
4745
|
+
process.exitCode = 1;
|
|
4746
|
+
return;
|
|
4747
|
+
}
|
|
4748
|
+
console.log(
|
|
4749
|
+
kleur8.green().bold(`
|
|
4750
|
+
\u2713 Updated. Run \`codegraph --version\` in a new shell to confirm.`)
|
|
4751
|
+
);
|
|
4752
|
+
console.log(
|
|
4753
|
+
kleur8.dim(
|
|
4754
|
+
" Restart `codegraph serve` if it is running so the MCP server uses the new build."
|
|
4755
|
+
)
|
|
4756
|
+
);
|
|
4757
|
+
}
|
|
4758
|
+
|
|
4588
4759
|
// src/commands/view.ts
|
|
4589
4760
|
import { exec } from "child_process";
|
|
4590
|
-
import
|
|
4761
|
+
import kleur9 from "kleur";
|
|
4591
4762
|
var DEFAULT_HOST2 = "127.0.0.1";
|
|
4592
4763
|
function openBrowser(url) {
|
|
4593
4764
|
const cmd = process.platform === "darwin" ? `open "${url}"` : process.platform === "win32" ? `start "" "${url}"` : `xdg-open "${url}"`;
|
|
4594
4765
|
exec(cmd, (err) => {
|
|
4595
4766
|
if (err) {
|
|
4596
4767
|
process.stderr.write(
|
|
4597
|
-
`${
|
|
4598
|
-
${
|
|
4768
|
+
`${kleur9.yellow("!")} Could not open browser automatically. Open manually:
|
|
4769
|
+
${kleur9.cyan(url)}
|
|
4599
4770
|
`
|
|
4600
4771
|
);
|
|
4601
4772
|
}
|
|
@@ -4615,23 +4786,23 @@ async function runViewCommand(opts = {}) {
|
|
|
4615
4786
|
const host = opts.host ?? DEFAULT_HOST2;
|
|
4616
4787
|
const port = opts.port ?? MCP_PORT;
|
|
4617
4788
|
const viewerUrl = `http://${host}:${port}/viewer`;
|
|
4618
|
-
process.stdout.write(
|
|
4789
|
+
process.stdout.write(kleur9.dim(`Checking server at http://${host}:${port}/healthz \u2026
|
|
4619
4790
|
`));
|
|
4620
4791
|
const up = await isServerUp(host, port);
|
|
4621
4792
|
if (!up) {
|
|
4622
4793
|
process.stdout.write(
|
|
4623
4794
|
[
|
|
4624
4795
|
"",
|
|
4625
|
-
`${
|
|
4796
|
+
`${kleur9.red("\u2717")} CodeGraph server is not running.`,
|
|
4626
4797
|
"",
|
|
4627
|
-
` Start it with: ${
|
|
4628
|
-
` Then re-run: ${
|
|
4798
|
+
` Start it with: ${kleur9.cyan("codegraph serve")}`,
|
|
4799
|
+
` Then re-run: ${kleur9.cyan("codegraph view")}`,
|
|
4629
4800
|
""
|
|
4630
4801
|
].join("\n")
|
|
4631
4802
|
);
|
|
4632
4803
|
process.exit(1);
|
|
4633
4804
|
}
|
|
4634
|
-
process.stdout.write(`${
|
|
4805
|
+
process.stdout.write(`${kleur9.green("\u2713")} Server is up. Opening ${kleur9.cyan(viewerUrl)} \u2026
|
|
4635
4806
|
`);
|
|
4636
4807
|
openBrowser(viewerUrl);
|
|
4637
4808
|
}
|
|
@@ -4639,7 +4810,7 @@ async function runViewCommand(opts = {}) {
|
|
|
4639
4810
|
// src/program.ts
|
|
4640
4811
|
function buildProgram() {
|
|
4641
4812
|
const program = new Command();
|
|
4642
|
-
program.name("codegraph").description("Live, queryable knowledge graph for your codebase").version(
|
|
4813
|
+
program.name("codegraph").description("Live, queryable knowledge graph for your codebase").version(PACKAGE_VERSION).option("--verbose", "Print full stack traces on error").hook("preAction", (thisCommand) => {
|
|
4643
4814
|
const opts = thisCommand.optsWithGlobals();
|
|
4644
4815
|
if (opts.verbose) process.env.CODEGRAPH_VERBOSE = "1";
|
|
4645
4816
|
});
|
|
@@ -4671,6 +4842,13 @@ function buildProgram() {
|
|
|
4671
4842
|
program.command("doctor").description("Check environment, config, LLM credentials, and Kuzu DB health").action(async () => {
|
|
4672
4843
|
await runDoctorCommand();
|
|
4673
4844
|
});
|
|
4845
|
+
program.command("update").description("Check npm for a newer release and upgrade the global CLI").option("--check", "Only show installed vs latest version; do not install").option("--yes", "Skip confirmation and run npm install -g immediately").option("--tag <tag>", "npm dist-tag to install (default: latest)", "latest").action(async (opts) => {
|
|
4846
|
+
await runUpdateCommand({
|
|
4847
|
+
check: opts.check === true,
|
|
4848
|
+
yes: opts.yes === true,
|
|
4849
|
+
...opts.tag !== void 0 ? { tag: opts.tag } : {}
|
|
4850
|
+
});
|
|
4851
|
+
});
|
|
4674
4852
|
program.command("wipe").description("Delete a single repo's slice (with [path]) or the entire on-disk graph").argument("[path]", "Repo path. Omit to wipe the whole graph directory.").option("--yes", "Skip the confirmation prompt", false).action(async (repoPath, opts) => {
|
|
4675
4853
|
await runWipeCommand({
|
|
4676
4854
|
...repoPath ? { repoPath } : {},
|
|
@@ -4707,4 +4885,4 @@ export {
|
|
|
4707
4885
|
renderError,
|
|
4708
4886
|
buildProgram
|
|
4709
4887
|
};
|
|
4710
|
-
//# sourceMappingURL=chunk-
|
|
4888
|
+
//# sourceMappingURL=chunk-WU6GFDTU.js.map
|