New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

krow-cli

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

krow-cli - npm Package Compare versions

Comparing version
0.1.0
to
0.2.0
+27
-3
dist/cli.js

@@ -22,3 +22,2 @@ #!/usr/bin/env node

import path from "path";
import os from "os";
import { fileURLToPath } from "url";

@@ -66,2 +65,3 @@ function outputJSON(data) {

if (options.force) args.push("--force");
if (options.global) args.push("--global");
args.push("--home", options.home);

@@ -84,6 +84,30 @@ return new Promise((resolve, reject) => {

}
function runInstallerRemove(options) {
const installerPath = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../install/krow.mjs");
const args = ["remove"];
if (options.global) args.push("--global");
args.push("--home", options.home);
return new Promise((resolve, reject) => {
const child = spawn(process.execPath, [installerPath, ...args], { stdio: "inherit" });
child.on("error", reject);
child.on("exit", (code, signal) => {
if (signal) {
reject(new Error(`Installer exited due to signal ${signal}`));
return;
}
if (code === 0) {
resolve();
return;
}
reject(new Error(`Installer exited with code ${code ?? 1}`));
});
});
}
var program = new Command().name("krow").description("Agent harness CLI").version("0.1.0");
program.command("init").description("Install Codex, Claude Code, and Gemini CLI wrappers").option("--force", "Overwrite managed files even if they already exist").option("--home <dir>", "Target home directory", os.homedir()).action(async (options) => {
await runInstallerInit({ force: Boolean(options.force), home: options.home });
program.command("init").description("Install Codex, Claude Code, and Gemini CLI wrappers (local by default, use -g for global)").option("--force", "Overwrite managed files even if they already exist").option("-g, --global", "Install to home directory (global)").option("--home <dir>", "Target directory", process.cwd()).action(async (options) => {
await runInstallerInit({ force: Boolean(options.force), global: Boolean(options.global), home: options.home });
});
program.command("remove").description("Remove installed Codex, Claude Code, and Gemini CLI wrappers").option("-g, --global", "Remove from home directory (global)").option("--home <dir>", "Target directory", process.cwd()).action(async (options) => {
await runInstallerRemove({ global: Boolean(options.global), home: options.home });
});
program.command("start").description("Start a new workflow").argument("<description>", "Task description").action((description) => {

@@ -90,0 +114,0 @@ const result = createWorkflow(description);

@@ -191,6 +191,13 @@ #!/usr/bin/env node

"Usage:",
" krow init [--force] [--home <dir>]",
" krow init [--force] [-g | --global] [--home <dir>]",
" krow remove [-g | --global] [--home <dir>]",
"",
"Commands:",
" init Install Codex $krow, Claude Code /krow, and Gemini CLI /krow wrappers",
" init Install Codex $krow, Claude Code /krow, and Gemini CLI /krow wrappers",
" remove Remove installed Codex, Claude Code, and Gemini CLI wrappers",
"",
"Flags:",
" --force Overwrite managed files even if they already exist",
" -g, --global Install to / remove from home directory (global)",
" --home <dir> Target directory override",
].join("\n") + "\n",

@@ -203,3 +210,4 @@ );

let force = false;
let home = os.homedir();
let global = false;
let home = null;

@@ -212,2 +220,6 @@ for (let index = 1; index < argv.length; index += 1) {

}
if (value === "--global" || value === "-g") {
global = true;
continue;
}
if (value === "--home" && argv[index + 1]) {

@@ -220,3 +232,3 @@ home = argv[index + 1];

return { command, force, home };
return { command, force, global, home };
}

@@ -251,3 +263,6 @@

export async function runInit({ force, home }) {
export async function runInit({ force, global: isGlobal, home }) {
if (home == null) {
home = isGlobal ? os.homedir() : process.cwd();
}
const scriptDir = path.dirname(fileURLToPath(import.meta.url));

@@ -289,11 +304,72 @@ const packageRoot = path.resolve(scriptDir, "..");

export async function runRemove({ global: isGlobal, home }) {
if (home == null) {
home = isGlobal ? os.homedir() : process.cwd();
}
const targets = [
{
label: "Codex $krow skill",
path: path.join(home, ".codex", "skills", "krow", "SKILL.md"),
},
{
label: "Claude Code /krow command",
path: path.join(home, ".claude", "commands", "krow.md"),
},
{
label: "Gemini CLI /krow command",
path: path.join(home, ".gemini", "commands", "krow.toml"),
},
];
const results = [];
for (const target of targets) {
const exists = await pathExists(target.path);
if (!exists) {
results.push({ ...target, status: "skipped (not found)" });
continue;
}
const content = await fs.readFile(target.path, "utf8");
if (!content.includes(MANAGED_MARKER)) {
results.push({ ...target, status: "skipped (not managed by krow)" });
continue;
}
await fs.unlink(target.path);
results.push({ ...target, status: "removed" });
// Try to remove empty parent directories
let dir = path.dirname(target.path);
while (dir !== home && dir !== path.dirname(dir)) {
try {
await fs.rmdir(dir);
dir = path.dirname(dir);
} catch {
break;
}
}
}
process.stdout.write(
[
`Remove targets in ${home}`,
...results.map((result) => `${result.status}: ${result.label} -> ${result.path}`),
].join("\n") + "\n",
);
}
export async function main() {
const parsed = parseArgs(process.argv.slice(2));
if (parsed.command !== "init") {
printUsage();
process.exitCode = parsed.command ? 1 : 0;
if (parsed.command === "init") {
await runInit(parsed);
return;
}
if (parsed.command === "remove") {
await runRemove(parsed);
return;
}
await runInit(parsed);
printUsage();
process.exitCode = parsed.command ? 1 : 0;
}

@@ -300,0 +376,0 @@

+1
-1
{
"name": "krow-cli",
"version": "0.1.0",
"version": "0.2.0",
"description": "A host-agnostic agent harness for coding work",

@@ -5,0 +5,0 @@ "type": "module",