Sign In

@vruum/cli

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@vruum/cli - npm Package Compare versions

Comparing version
0.2.3
to
0.3.0
+2
-5
dist/commands/init.command.js

@@ -9,5 +9,4 @@ import { resolveApiUrl, resolveToken } from "../lib/config.js";

.command("init")
.description("Wire Vruum into every detected AI coding harness (MCP + skills + instructions)")
.option("--project-dir <dir>", "project root for instruction files", process.cwd())
.action(async (opts) => {
.description("Wire Vruum into every detected AI coding harness (MCP + skills)")
.action(async () => {
const token = await resolveToken();

@@ -23,3 +22,2 @@ if (!token) {

token,
projectRoot: opts.projectDir,
};

@@ -35,3 +33,2 @@ const results = [];

["skills", (o) => adapter.linkSkills(o)],
["instructions", (o) => adapter.writeInstructions(o)],
];

@@ -38,0 +35,0 @@ const stepResults = [];

@@ -60,9 +60,2 @@ /**

},
async writeInstructions() {
return {
step: "instructions",
status: "deferred",
detail: "AGENTS.md/CLAUDE.md emitter lands in VRU-469b",
};
},
};

@@ -144,9 +144,2 @@ /**

},
async writeInstructions() {
return {
step: "instructions",
status: "deferred",
detail: "AGENTS.md/CLAUDE.md emitter lands in VRU-469b",
};
},
};

@@ -72,9 +72,2 @@ /**

},
async writeInstructions() {
return {
step: "instructions",
status: "deferred",
detail: "AGENTS.md/CLAUDE.md emitter lands in VRU-469b",
};
},
};

@@ -1,23 +0,4 @@

/**
* Leaf helpers shared by `lib/harness.ts` and every per-harness adapter in this
* directory. This module imports ONLY node builtins — nothing adapter-related.
*
* Why a leaf: `harness.ts` registers the adapters (value imports), and an
* adapter needs `harnessHome`/`pathExists`/`isFile` plus the command runner. If
* those lived in `harness.ts`, an adapter's value import would close a runtime
* ESM cycle (`harness.ts → *.adapter.ts → harness.ts`) with a TDZ crash when an
* adapter module loads first (its own unit test). Putting them here breaks the
* back-edge: every side imports runtime helpers from `core`, and adapters pull
* the `HarnessAdapter`/`InitOptions`/`StepResult` *types* from `harness.ts` via
* `import type` (erased at runtime → no cycle). The graph stays a clean DAG.
*
* Consolidates the duplicate leaf helpers the parallel adapter branches each
* grew (`harnesses/core.ts` and `lib/harness-paths.ts`) into one module — the
* union of `harnessHome` + `pathExists` + `isFile` + the command-runner seam.
*/
import { execFile } from "node:child_process";
import { promises as fs } from "node:fs";
import { homedir } from "node:os";
import { promisify } from "node:util";
const execFileP = promisify(execFile);
import crossSpawn from "cross-spawn";
/** Home dir adapters resolve harness configs under (override in tests). */

@@ -47,5 +28,35 @@ export function harnessHome() {

}
const defaultRunner = async (cmd, args) => {
await execFileP(cmd, args);
};
/**
* Run a command with Windows-aware executable resolution.
*
* npm installs `npx`/`npm` as `.cmd` shims on Windows. Node's shell-free
* `execFile`/`spawn` does not resolve those through PATHEXT, while enabling a
* shell globally would make argument escaping both fragile and unsafe. The
* cross-spawn parser resolves the shim and escapes its arguments before it
* delegates to Node's child-process API.
*/
export async function runSpawnCommand(cmd, args, spawn = crossSpawn) {
await new Promise((resolve, reject) => {
const child = spawn(cmd, args, { stdio: ["ignore", "ignore", "pipe"] });
const stderrStream = child.stderr;
let stderr = "";
stderrStream.setEncoding("utf8");
stderrStream.on("data", (chunk) => {
stderr += chunk;
});
child.once("error", reject);
child.once("close", (code, signal) => {
if (code === 0) {
resolve();
return;
}
const reason = code === null
? `${cmd} exited due to signal ${String(signal)}`
: `${cmd} exited with code ${code}`;
const detail = stderr.trim();
reject(new Error(detail ? `${reason}: ${detail}` : reason));
});
});
}
const defaultRunner = runSpawnCommand;
let runner = defaultRunner;

@@ -52,0 +63,0 @@ /** Run an external command through the current runner (override in tests). */

@@ -115,9 +115,2 @@ /**

},
async writeInstructions() {
return {
step: "instructions",
status: "deferred",
detail: "AGENTS.md/instructions emitter lands in VRU-469b",
};
},
};

@@ -131,9 +131,2 @@ /**

},
async writeInstructions() {
return {
step: "instructions",
status: "deferred",
detail: "AGENTS.md emitter lands in VRU-469b",
};
},
};

@@ -21,5 +21,4 @@ /**

*
* `linkSkills`/`writeInstructions` are `deferred`, mirroring the Claude Code
* reference adapter (OpenCode reads `.agents/skills` natively — placement is
* settled in VRU-470; the AGENTS.md emitter is VRU-469b).
* `linkSkills` is deferred (OpenCode reads `.agents/skills` natively —
* placement is settled in VRU-470).
*

@@ -111,9 +110,2 @@ * Import discipline: runtime helpers come from `./core.js`; types come from

},
async writeInstructions() {
return {
step: "instructions",
status: "deferred",
detail: "AGENTS.md emitter lands in VRU-469b",
};
},
};

@@ -13,4 +13,4 @@ /**

*
* Scope: MCP registration only. `linkSkills` / `writeInstructions` are deferred
* (VRU-470 / VRU-469b), matching the reference adapter's posture.
* Scope: MCP registration only. `linkSkills` is deferred (VRU-470), matching
* the reference adapter's posture.
*

@@ -120,9 +120,2 @@ * Import discipline: runtime helpers come from `./core.js`; types come from

},
async writeInstructions() {
return {
step: "instructions",
status: "deferred",
detail: "AGENTS.md emitter lands in VRU-469b",
};
},
};

@@ -6,3 +6,3 @@ /**

* installed, register the Vruum MCP server (Bearer-authed — no interactive
* OAuth), link the portable skill set, and write the agent instruction files.
* OAuth) and link the portable skill set.
*

@@ -23,8 +23,8 @@ * `HarnessAdapter` is the extension point: adding a harness is adding one file

*
* Scope note: MCP registration is fully implemented. `linkSkills` /
* `writeInstructions` are interface-complete but their bodies are deferred —
* the published `@vruum/cli` ships no skills (those are the `@vruum/skills`
* package, and the portable SKILL.md placement is settled in VRU-470), and the
* AGENTS.md/CLAUDE.md emitter is VRU-469b. They return a `deferred` step so each
* adapter is a faithful, end-to-end-runnable shape today.
* MCP registration is implemented for every adapter. Skill installation is
* implemented where the harness has a stable skill directory; unsupported
* placements return a `deferred` skills step. Project instruction files are
* deliberately outside `vruum init`: silently editing a repository's
* AGENTS.md/CLAUDE.md would conflict with user-owned agent instructions and
* duplicate the installed Vruum skills.
*/

@@ -31,0 +31,0 @@ import { claudeCode } from "../harnesses/claude.adapter.js";

{
"name": "@vruum/cli",
"version": "0.2.3",
"version": "0.3.0",
"description": "Headless CLI for the Vruum revenue platform.",

@@ -51,5 +51,7 @@ "type": "module",

"dependencies": {
"commander": "^12.1.0"
"commander": "^12.1.0",
"cross-spawn": "^7.0.6"
},
"devDependencies": {
"@types/cross-spawn": "^6.0.6",
"@types/node": "^20.14.0",

@@ -56,0 +58,0 @@ "@yao-pkg/pkg": "^6.20.0",