@controlvector/cv-agent 1.8.0 → 1.9.0
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/dist/bundle.cjs +195 -11
- package/dist/bundle.cjs.map +2 -2
- package/dist/commands/agent.d.ts.map +1 -1
- package/dist/commands/agent.js +54 -0
- package/dist/commands/agent.js.map +1 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +143 -11
- package/dist/commands/setup.js.map +1 -1
- package/package.json +1 -1
package/dist/bundle.cjs
CHANGED
|
@@ -3834,18 +3834,84 @@ async function runSetup() {
|
|
|
3834
3834
|
console.log(source_default.gray(' Click "Add Integration" \u2192 "Allow" when prompted.'));
|
|
3835
3835
|
console.log(source_default.gray(" (You can do this later \u2014 setup will continue.)"));
|
|
3836
3836
|
console.log();
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
const hasClaudeMd = (0, import_node_fs.existsSync)((0, import_node_path.join)(cwd, "CLAUDE.md"));
|
|
3841
|
-
const repoName = (0, import_node_path.basename)(cwd);
|
|
3837
|
+
let cwd = process.cwd();
|
|
3838
|
+
let isGitRepo = (0, import_node_fs.existsSync)((0, import_node_path.join)(cwd, ".git"));
|
|
3839
|
+
let repoName = (0, import_node_path.basename)(cwd);
|
|
3842
3840
|
if (isGitRepo) {
|
|
3843
3841
|
console.log(source_default.green(" \u2713") + ` Git repo found: ${repoName}`);
|
|
3844
3842
|
} else {
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
console.log(
|
|
3843
|
+
const readline = await import("node:readline");
|
|
3844
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
3845
|
+
console.log(" No git repository found in this directory.");
|
|
3846
|
+
console.log();
|
|
3847
|
+
console.log(` ${source_default.cyan("a")} \u2014 Initialize a new project here: ${cwd}`);
|
|
3848
|
+
console.log(` ${source_default.cyan("b")} \u2014 Clone an existing repo from CV-Hub`);
|
|
3849
|
+
console.log();
|
|
3850
|
+
const choice = await new Promise((resolve) => {
|
|
3851
|
+
rl.question(" Choose [a/b]: ", (answer) => {
|
|
3852
|
+
rl.close();
|
|
3853
|
+
resolve(answer.trim().toLowerCase() || "a");
|
|
3854
|
+
});
|
|
3855
|
+
});
|
|
3856
|
+
if (choice === "b" && token) {
|
|
3857
|
+
try {
|
|
3858
|
+
console.log(source_default.gray(" Fetching your repositories..."));
|
|
3859
|
+
const controller = new AbortController();
|
|
3860
|
+
const timeout = setTimeout(() => controller.abort(), 15e3);
|
|
3861
|
+
const res = await fetch(`${hubUrl}/api/v1/repos?limit=50`, {
|
|
3862
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
3863
|
+
signal: controller.signal
|
|
3864
|
+
});
|
|
3865
|
+
clearTimeout(timeout);
|
|
3866
|
+
if (res.ok) {
|
|
3867
|
+
const data = await res.json();
|
|
3868
|
+
const repos = data.repositories || [];
|
|
3869
|
+
if (repos.length === 0) {
|
|
3870
|
+
console.log(source_default.yellow(" No repos found on CV-Hub. Initializing a new project instead."));
|
|
3871
|
+
} else {
|
|
3872
|
+
console.log();
|
|
3873
|
+
console.log(" Your CV-Hub repositories:");
|
|
3874
|
+
const displayRepos = repos.slice(0, 20);
|
|
3875
|
+
displayRepos.forEach((r, i) => {
|
|
3876
|
+
const desc = r.description ? source_default.gray(` \u2014 ${r.description.substring(0, 40)}`) : "";
|
|
3877
|
+
console.log(` ${source_default.cyan(String(i + 1).padStart(2))}. ${r.slug || r.name}${desc}`);
|
|
3878
|
+
});
|
|
3879
|
+
console.log();
|
|
3880
|
+
const rl2 = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
3881
|
+
const selection = await new Promise((resolve) => {
|
|
3882
|
+
rl2.question(` Select a repo [1-${displayRepos.length}]: `, (answer) => {
|
|
3883
|
+
rl2.close();
|
|
3884
|
+
resolve(answer.trim());
|
|
3885
|
+
});
|
|
3886
|
+
});
|
|
3887
|
+
const idx = parseInt(selection, 10) - 1;
|
|
3888
|
+
if (idx >= 0 && idx < displayRepos.length) {
|
|
3889
|
+
const repo = displayRepos[idx];
|
|
3890
|
+
const gitHost = "git.hub.controlvector.io";
|
|
3891
|
+
const slug = repo.slug || repo.name;
|
|
3892
|
+
const cloneUrl = `https://${username}:${token}@${gitHost}/${username}/${slug}.git`;
|
|
3893
|
+
console.log(source_default.gray(` Cloning ${username}/${slug}...`));
|
|
3894
|
+
(0, import_node_child_process.execSync)(`git clone ${cloneUrl} ${slug}`, { cwd, stdio: "pipe", timeout: 6e4 });
|
|
3895
|
+
cwd = (0, import_node_path.join)(cwd, slug);
|
|
3896
|
+
process.chdir(cwd);
|
|
3897
|
+
repoName = slug;
|
|
3898
|
+
isGitRepo = true;
|
|
3899
|
+
console.log(source_default.green(" \u2713") + ` Cloned ${username}/${slug}`);
|
|
3900
|
+
}
|
|
3901
|
+
}
|
|
3902
|
+
}
|
|
3903
|
+
} catch (err) {
|
|
3904
|
+
console.log(source_default.yellow(` Could not fetch repos: ${err.message}. Initializing instead.`));
|
|
3905
|
+
}
|
|
3906
|
+
}
|
|
3907
|
+
if (!isGitRepo) {
|
|
3908
|
+
console.log(" Initializing git repository...");
|
|
3909
|
+
(0, import_node_child_process.execSync)("git init && git checkout -b main", { cwd, stdio: "pipe" });
|
|
3910
|
+
console.log(source_default.green(" \u2713") + " Git repo initialized");
|
|
3911
|
+
}
|
|
3848
3912
|
}
|
|
3913
|
+
const hasClaudeMd = (0, import_node_fs.existsSync)((0, import_node_path.join)(cwd, "CLAUDE.md"));
|
|
3914
|
+
const hasCVDir = (0, import_node_fs.existsSync)((0, import_node_path.join)(cwd, ".cv"));
|
|
3849
3915
|
if (!hasClaudeMd) {
|
|
3850
3916
|
const template = `# ${repoName}
|
|
3851
3917
|
|
|
@@ -3933,16 +3999,76 @@ async function runSetup() {
|
|
|
3933
3999
|
}
|
|
3934
4000
|
}
|
|
3935
4001
|
console.log();
|
|
4002
|
+
let agentStatus = "";
|
|
4003
|
+
const pidFile = (0, import_node_path.join)((0, import_node_os2.homedir)(), ".config", "controlvector", "agent.pid");
|
|
4004
|
+
let agentRunning = false;
|
|
4005
|
+
try {
|
|
4006
|
+
const pid = parseInt((0, import_node_fs.readFileSync)(pidFile, "utf-8").trim(), 10);
|
|
4007
|
+
if (pid > 0) {
|
|
4008
|
+
process.kill(pid, 0);
|
|
4009
|
+
agentRunning = true;
|
|
4010
|
+
agentStatus = `running (PID ${pid})`;
|
|
4011
|
+
console.log(source_default.green(" \u2713") + ` Agent already running (PID ${pid})`);
|
|
4012
|
+
}
|
|
4013
|
+
} catch {
|
|
4014
|
+
}
|
|
4015
|
+
if (!agentRunning) {
|
|
4016
|
+
const readline = await import("node:readline");
|
|
4017
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
4018
|
+
const answer = await new Promise((resolve) => {
|
|
4019
|
+
rl.question(" Start the CV-Agent daemon? (Y/n): ", (a) => {
|
|
4020
|
+
rl.close();
|
|
4021
|
+
resolve(a.trim().toLowerCase() || "y");
|
|
4022
|
+
});
|
|
4023
|
+
});
|
|
4024
|
+
if (answer === "y" || answer === "yes" || answer === "") {
|
|
4025
|
+
const machName = (0, import_node_os2.hostname)().toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-");
|
|
4026
|
+
console.log(source_default.gray(` Starting agent as "${machName}"...`));
|
|
4027
|
+
try {
|
|
4028
|
+
const { spawn: spawnChild } = await import("node:child_process");
|
|
4029
|
+
const child = spawnChild("cva", [
|
|
4030
|
+
"agent",
|
|
4031
|
+
"--auto-approve",
|
|
4032
|
+
"--machine",
|
|
4033
|
+
machName,
|
|
4034
|
+
"--working-dir",
|
|
4035
|
+
cwd
|
|
4036
|
+
], {
|
|
4037
|
+
detached: true,
|
|
4038
|
+
stdio: "ignore",
|
|
4039
|
+
env: { ...process.env }
|
|
4040
|
+
});
|
|
4041
|
+
child.unref();
|
|
4042
|
+
if (child.pid) {
|
|
4043
|
+
(0, import_node_fs.mkdirSync)((0, import_node_path.join)((0, import_node_os2.homedir)(), ".config", "controlvector"), { recursive: true });
|
|
4044
|
+
(0, import_node_fs.writeFileSync)(pidFile, String(child.pid), { mode: 384 });
|
|
4045
|
+
agentStatus = `running (PID ${child.pid})`;
|
|
4046
|
+
console.log(source_default.green(" \u2713") + ` Agent started (PID ${child.pid}) \u2014 executor "${machName}"`);
|
|
4047
|
+
}
|
|
4048
|
+
} catch (err) {
|
|
4049
|
+
console.log(source_default.yellow(` Could not start agent: ${err.message}`));
|
|
4050
|
+
console.log(source_default.gray(" Start manually with: cva agent --auto-approve"));
|
|
4051
|
+
agentStatus = "not started";
|
|
4052
|
+
}
|
|
4053
|
+
} else {
|
|
4054
|
+
agentStatus = "not started";
|
|
4055
|
+
console.log(source_default.gray(" Start anytime with: cva agent --auto-approve"));
|
|
4056
|
+
}
|
|
4057
|
+
}
|
|
4058
|
+
console.log();
|
|
3936
4059
|
console.log(source_default.bold(" Setup Complete"));
|
|
3937
4060
|
console.log(source_default.gray(" " + "\u2500".repeat(40)));
|
|
3938
4061
|
console.log(` ${source_default.green("\u2713")} Authenticated as: ${source_default.cyan(username)}`);
|
|
3939
4062
|
console.log(` ${source_default.green("\u2713")} Repository: ${source_default.cyan(repoName)}`);
|
|
3940
4063
|
console.log(` ${source_default.green("\u2713")} CLAUDE.md: present`);
|
|
4064
|
+
if (agentStatus.startsWith("running")) {
|
|
4065
|
+
console.log(` ${source_default.green("\u2713")} Agent daemon: ${source_default.cyan(agentStatus)}`);
|
|
4066
|
+
}
|
|
3941
4067
|
console.log(source_default.gray(" " + "\u2500".repeat(40)));
|
|
3942
4068
|
console.log();
|
|
3943
4069
|
console.log(" What's next:");
|
|
3944
|
-
console.log(
|
|
3945
|
-
console.log(`
|
|
4070
|
+
console.log(" Open Claude.ai and try:");
|
|
4071
|
+
console.log(source_default.cyan(` "Create a task in ${repoName} to add a hello world index.html"`));
|
|
3946
4072
|
console.log();
|
|
3947
4073
|
console.log(source_default.gray(` Dashboard: ${appUrl}`));
|
|
3948
4074
|
console.log();
|
|
@@ -5410,6 +5536,64 @@ async function runAgent(options) {
|
|
|
5410
5536
|
console.log();
|
|
5411
5537
|
}
|
|
5412
5538
|
}
|
|
5539
|
+
{
|
|
5540
|
+
const isGitRepo = require("fs").existsSync(require("path").join(workingDir, ".git"));
|
|
5541
|
+
if (!isGitRepo) {
|
|
5542
|
+
console.log(source_default.gray(" Bootstrap: initializing git repo..."));
|
|
5543
|
+
try {
|
|
5544
|
+
(0, import_node_child_process5.execSync)("git init && git checkout -b main", { cwd: workingDir, stdio: "pipe" });
|
|
5545
|
+
} catch {
|
|
5546
|
+
}
|
|
5547
|
+
}
|
|
5548
|
+
const claudeMdPath = require("path").join(workingDir, "CLAUDE.md");
|
|
5549
|
+
if (!require("fs").existsSync(claudeMdPath)) {
|
|
5550
|
+
const name = require("path").basename(workingDir);
|
|
5551
|
+
const template = `# ${name}
|
|
5552
|
+
|
|
5553
|
+
## Overview
|
|
5554
|
+
[Describe your project here]
|
|
5555
|
+
|
|
5556
|
+
## Build & Run
|
|
5557
|
+
[How to build and run this project]
|
|
5558
|
+
`;
|
|
5559
|
+
try {
|
|
5560
|
+
require("fs").writeFileSync(claudeMdPath, template);
|
|
5561
|
+
console.log(source_default.gray(" Bootstrap: created CLAUDE.md"));
|
|
5562
|
+
} catch {
|
|
5563
|
+
}
|
|
5564
|
+
}
|
|
5565
|
+
const cvDir = require("path").join(workingDir, ".cv");
|
|
5566
|
+
if (!require("fs").existsSync(cvDir)) {
|
|
5567
|
+
try {
|
|
5568
|
+
require("fs").mkdirSync(cvDir, { recursive: true });
|
|
5569
|
+
} catch {
|
|
5570
|
+
}
|
|
5571
|
+
}
|
|
5572
|
+
if (creds.CV_HUB_PAT) {
|
|
5573
|
+
try {
|
|
5574
|
+
const existing = (0, import_node_child_process5.execSync)('git remote get-url cv-hub 2>/dev/null || echo ""', {
|
|
5575
|
+
cwd: workingDir,
|
|
5576
|
+
encoding: "utf8",
|
|
5577
|
+
timeout: 5e3
|
|
5578
|
+
}).trim();
|
|
5579
|
+
if (!existing) {
|
|
5580
|
+
const name = require("path").basename(workingDir);
|
|
5581
|
+
const gitHost = "git.hub.controlvector.io";
|
|
5582
|
+
let user = "user";
|
|
5583
|
+
try {
|
|
5584
|
+
const sharedPath = require("path").join(require("os").homedir(), ".config", "controlvector", "credentials.json");
|
|
5585
|
+
const shared = JSON.parse(require("fs").readFileSync(sharedPath, "utf-8"));
|
|
5586
|
+
if (shared.username) user = shared.username;
|
|
5587
|
+
} catch {
|
|
5588
|
+
}
|
|
5589
|
+
const remoteUrl = `https://${gitHost}/${user}/${name}.git`;
|
|
5590
|
+
(0, import_node_child_process5.execSync)(`git remote add cv-hub ${remoteUrl}`, { cwd: workingDir, stdio: "pipe" });
|
|
5591
|
+
console.log(source_default.gray(` Bootstrap: remote cv-hub \u2192 ${remoteUrl}`));
|
|
5592
|
+
}
|
|
5593
|
+
} catch {
|
|
5594
|
+
}
|
|
5595
|
+
}
|
|
5596
|
+
}
|
|
5413
5597
|
let detectedRepoId;
|
|
5414
5598
|
try {
|
|
5415
5599
|
const remoteUrl = (0, import_node_child_process5.execSync)("git remote get-url origin 2>/dev/null", {
|
|
@@ -6152,7 +6336,7 @@ function statusCommand() {
|
|
|
6152
6336
|
|
|
6153
6337
|
// src/index.ts
|
|
6154
6338
|
var program2 = new Command();
|
|
6155
|
-
program2.name("cva").description('CV-Hub Agent \u2014 bridges Claude Code with CV-Hub task dispatch.\n\nRun "cva setup" to get started.').version(true ? "1.
|
|
6339
|
+
program2.name("cva").description('CV-Hub Agent \u2014 bridges Claude Code with CV-Hub task dispatch.\n\nRun "cva setup" to get started.').version(true ? "1.9.0" : "1.6.0");
|
|
6156
6340
|
program2.addCommand(setupCommand());
|
|
6157
6341
|
program2.addCommand(agentCommand());
|
|
6158
6342
|
program2.addCommand(authCommand());
|