mirror of
https://github.com/profullstack/logicsrc.git
synced 2026-10-03 13:17:07 +00:00
logicsrc CLI 0.2.0: every LogicSRC tool is a word after logicsrc (#157)
OpenContext, OpenCreds, OpenOntology and OpenPRD were already registered under the umbrella. Three were not: - `logicsrc openmcp …`: OpenMCP lives in its own repository, so it is a dependency (@logicsrc/openmcp ^0.3.1, which exports ./cli for this) and every argument goes untouched to the same main the standalone binary runs. Imported on first use, because the catalog is node:sqlite (Node 24) while the rest of the CLI runs on 18; below the floor that one word says so and offers the standalone installer, which brings its own Node. - `logicsrc openspec <anything else>`: import, export and change stay ours; any other word (init, list, validate, archive, show) runs OpenSpec.dev's own CLI (@fission-ai/openspec) as the group's default subcommand, flags intact. One command for a repo in compatibility mode, and the OpenSpec.dev half is upstream itself rather than a copy that would drift. - `logicsrc mcp`: the LogicSRC MCP server (@profullstack/logicsrc-mcp) over stdio, spawned as a child because it owns the process's stdio. build:cli now builds that workspace. README gets a table of every word and the standalone name it mirrors; the OpenMCP spec page and doc mention the umbrella form. Claude-Session: https://claude.ai/code/session_01Qh2dieNyPZ4Hx5g3XNJ1Eo Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
0f6326e910
commit
8951e824d5
11 changed files with 1466 additions and 12 deletions
63
packages/cli/src/openmcp.ts
Normal file
63
packages/cli/src/openmcp.ts
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
import type { Command } from "commander";
|
||||
|
||||
/**
|
||||
* `logicsrc openmcp …`
|
||||
*
|
||||
* OpenMCP is the one LogicSRC command that lives outside this monorepo
|
||||
* (github.com/logicsrc/openmcp, published as `@logicsrc/openmcp`), so unlike
|
||||
* `vault`, `prd` and `context` it cannot register commander commands here.
|
||||
* Instead every argument after `openmcp` is handed, untouched, to the same
|
||||
* `main(argv)` the standalone `openmcp` binary runs, so `logicsrc openmcp
|
||||
* relays` and `openmcp relays` are one contract and can never drift.
|
||||
*
|
||||
* The import is deferred to the action because the catalog keeps its records
|
||||
* in `node:sqlite`, which is Node 24, while the rest of this CLI runs on 18.
|
||||
* A box on an older Node keeps every other command and gets a plain sentence
|
||||
* from this one instead of a stack trace about a built-in it has never heard
|
||||
* of.
|
||||
*/
|
||||
export const OPENMCP_PACKAGE = "@logicsrc/openmcp";
|
||||
export const OPENMCP_MIN_NODE = 24;
|
||||
|
||||
export function openmcpNodeMessage(version: string = process.version): string {
|
||||
return [
|
||||
`logicsrc openmcp needs Node ${OPENMCP_MIN_NODE} or newer, and this is ${version}.`,
|
||||
" mise use -g node@lts # then re-run",
|
||||
" curl -fsSL https://openmcp.logicsrc.com/install.sh | sh # or the standalone command, which brings its own Node 24",
|
||||
].join("\n");
|
||||
}
|
||||
|
||||
/** Is this Node new enough for the catalog? */
|
||||
export function meetsOpenmcpNode(version: string = process.version): boolean {
|
||||
return Number.parseInt(version.replace(/^v/, ""), 10) >= OPENMCP_MIN_NODE;
|
||||
}
|
||||
|
||||
type OpenmcpMain = (argv: string[]) => Promise<number>;
|
||||
|
||||
/** Loaded on first use, and swapped out in tests. */
|
||||
export async function loadOpenmcpMain(): Promise<OpenmcpMain> {
|
||||
const mod = (await import(`${OPENMCP_PACKAGE}/cli`)) as { main: OpenmcpMain };
|
||||
return mod.main;
|
||||
}
|
||||
|
||||
export function registerOpenMcpCommands(program: Command, load: () => Promise<OpenmcpMain> = loadOpenmcpMain): void {
|
||||
program
|
||||
.command("openmcp")
|
||||
.description(
|
||||
"OpenMCP: the open catalog of MCP relays. relays, find, call, add, probe, serve, and the rest of the " +
|
||||
"standalone `openmcp` command, handed through as typed. `logicsrc openmcp help` lists them.",
|
||||
)
|
||||
.argument("[args...]", "Arguments for openmcp, exactly as the standalone command takes them")
|
||||
.allowUnknownOption()
|
||||
.passThroughOptions()
|
||||
.helpOption(false)
|
||||
.action(async (args: string[]) => {
|
||||
if (!meetsOpenmcpNode()) {
|
||||
console.error(openmcpNodeMessage());
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
const main = await load();
|
||||
process.exitCode = await main(args.length ? args : ["help"]);
|
||||
});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue