@agent-commons/cli 0.1.18 → 0.2.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/bin.js +106 -35
- package/package.json +2 -2
package/dist/bin.js
CHANGED
|
@@ -106,7 +106,7 @@ var sym = {
|
|
|
106
106
|
bullet: import_chalk.default.dim("\u2022"),
|
|
107
107
|
dot: import_chalk.default.dim("\xB7")
|
|
108
108
|
};
|
|
109
|
-
function banner(version = "0.
|
|
109
|
+
function banner(version = "0.2.0") {
|
|
110
110
|
const line = import_chalk.default.cyan(" \u2500".padEnd(2) + "\u2500".repeat(44));
|
|
111
111
|
console.log("");
|
|
112
112
|
console.log(line);
|
|
@@ -482,7 +482,7 @@ function agentsCommand() {
|
|
|
482
482
|
process.exit(1);
|
|
483
483
|
}
|
|
484
484
|
});
|
|
485
|
-
cmd.command("create").description("Create a new agent").requiredOption("--name <name>", "Agent name").option("--instructions <text>", "System instructions").option("--provider <provider>", "Model provider (openai|anthropic|google|groq)", "openai").option("--model <id>", "Model ID", "gpt-
|
|
485
|
+
cmd.command("create").description("Create a new agent").requiredOption("--name <name>", "Agent name").option("--instructions <text>", "System instructions").option("--provider <provider>", "Model provider (openai|anthropic|google|groq|openrouter|xai|ollama|custom)", "openai").option("--model <id>", "Model ID", "gpt-5.4-mini").option("--model-api-key <key>", "Provider API key (BYOK)").option("--model-base-url <url>", "Base URL for custom or local OpenAI-compatible providers").option("--json", "Output as JSON").action(async (opts) => {
|
|
486
486
|
const cfg = loadConfig();
|
|
487
487
|
if (!cfg.initiator) {
|
|
488
488
|
console.error(c.error("No initiator set. Run `agc login` first."));
|
|
@@ -496,7 +496,9 @@ function agentsCommand() {
|
|
|
496
496
|
instructions: opts.instructions,
|
|
497
497
|
owner: cfg.initiator,
|
|
498
498
|
modelProvider: opts.provider,
|
|
499
|
-
modelId: opts.model
|
|
499
|
+
modelId: opts.model,
|
|
500
|
+
modelApiKey: opts.modelApiKey,
|
|
501
|
+
modelBaseUrl: opts.modelBaseUrl
|
|
500
502
|
});
|
|
501
503
|
const agent = res?.data ?? res;
|
|
502
504
|
spinner.stop();
|
|
@@ -645,7 +647,7 @@ function sessionsCommand() {
|
|
|
645
647
|
process.exit(1);
|
|
646
648
|
}
|
|
647
649
|
});
|
|
648
|
-
cmd.command("create").description("Create a new session").option("--agent <agentId>", "Agent ID").option("--title <title>", "Session title").option("--model <id>", "Model ID (e.g. gpt-
|
|
650
|
+
cmd.command("create").description("Create a new session").option("--agent <agentId>", "Agent ID").option("--title <title>", "Session title").option("--model <id>", "Model ID (e.g. gpt-5.4-mini, claude-sonnet-4-6)").option("--provider <provider>", "Model provider").option("--json", "Output as JSON").action(async (opts) => {
|
|
649
651
|
const cfg = loadConfig();
|
|
650
652
|
const agentId = opts.agent ?? cfg.defaultAgentId;
|
|
651
653
|
if (!agentId) {
|
|
@@ -1267,11 +1269,12 @@ ${fileSection}
|
|
|
1267
1269
|
### MANDATORY RULES \u2014 READ CAREFULLY
|
|
1268
1270
|
|
|
1269
1271
|
1. **Call cli_* tools immediately and directly.** Do NOT create tasks (createTask) for local file operations. Do NOT delegate to sub-agents. Do NOT ask the user to run commands themselves.
|
|
1270
|
-
2. **
|
|
1271
|
-
3. **
|
|
1272
|
-
4. **
|
|
1273
|
-
5.
|
|
1274
|
-
6. **
|
|
1272
|
+
2. **Own the request through completion.** Continue across tool calls, process polling, retries, debugging, and verification. Do not stop after describing a plan or asking whether to proceed when the request is already clear.
|
|
1273
|
+
3. **Use actual tool output as evidence.** Summarize the important result; do not fabricate success or dump noisy logs unless they help diagnose a failure.
|
|
1274
|
+
4. **Never fabricate results.** Wait for the real tool output before responding.
|
|
1275
|
+
5. **Sensitive paths are blocked** (.ssh, .gnupg, .aws, .env, credentials). Attempting to access them will return an error.
|
|
1276
|
+
6. ${autoApprove ? "**cli_write_file and cli_run_command execute immediately** \u2014 auto-approve is active, no user confirmation is required." : "**cli_write_file and cli_run_command require the user to confirm** before executing \u2014 you will see the result after they approve."}
|
|
1277
|
+
7. **Git commits must carry the agc co-author trailer.** Always include \`--trailer "Co-Authored-By: <AgentName> (agc) <agc-agent@users.noreply.github.com>"\` when running \`git commit\`. The CLI injects this automatically \u2014 do not omit it or pass \`--no-trailer\`.
|
|
1275
1278
|
|
|
1276
1279
|
### Available CLI tools
|
|
1277
1280
|
|
|
@@ -1304,12 +1307,12 @@ ${fileSection}
|
|
|
1304
1307
|
|
|
1305
1308
|
For long commands like \`npx create-next-app@latest my-app --yes\`:
|
|
1306
1309
|
|
|
1307
|
-
1. Call \`cli_start_process\` \u2014 returns \`{processId, status: "running"}\` immediately.
|
|
1308
|
-
2. Call \`cli_wait_for_process\` with \`{"processId": "...", "wait_seconds": 60}
|
|
1309
|
-
3. Repeat step 2 until \`status\` is \`"done"\` or \`"error"
|
|
1310
|
-
4.
|
|
1310
|
+
1. Call \`cli_start_process\` \u2014 it returns \`{processId, status: "running"}\` immediately.
|
|
1311
|
+
2. Call \`cli_wait_for_process\` with \`{"processId": "...", "wait_seconds": 60}\`.
|
|
1312
|
+
3. Repeat step 2 until \`status\` is \`"done"\` or \`"error"\`; diagnose and repair errors when possible.
|
|
1313
|
+
4. Continue with the rest of the assignment and verify the final outcome before responding.
|
|
1311
1314
|
|
|
1312
|
-
|
|
1315
|
+
Do not end the turn merely because a process is still running. Keep polling within the same run. Progress events may be streamed by the client, but the final answer comes only after completion or a genuine blocker.
|
|
1313
1316
|
|
|
1314
1317
|
### Example \u2014 scaffolding a Next.js project
|
|
1315
1318
|
|
|
@@ -1317,18 +1320,14 @@ Never hold the user in silence. Between each \`cli_wait_for_process\` call, tell
|
|
|
1317
1320
|
cli_start_process: {"command": "npx", "args": ["create-next-app@latest", "my-app", "--yes"], "cwd": "Desktop"}
|
|
1318
1321
|
\u2192 {processId: "proc_1a2b", status: "running"}
|
|
1319
1322
|
|
|
1320
|
-
Tell user: "Started! Installing dependencies, this takes a minute or two. Checking in 60s\u2026"
|
|
1321
|
-
|
|
1322
1323
|
cli_wait_for_process: {"processId": "proc_1a2b", "wait_seconds": 60}
|
|
1323
1324
|
\u2192 {status: "running", elapsedSec: 60, stdout: "Creating project...
|
|
1324
1325
|
Installing packages\u2026"}
|
|
1325
1326
|
|
|
1326
|
-
Tell user: "Still installing \u2014 here's output so far: [stdout]. Checking again\u2026"
|
|
1327
|
-
|
|
1328
1327
|
cli_wait_for_process: {"processId": "proc_1a2b", "wait_seconds": 60}
|
|
1329
1328
|
\u2192 {status: "done", exitCode: 0, elapsedSec: 93, stdout: "Success! Created my-app"}
|
|
1330
1329
|
|
|
1331
|
-
|
|
1330
|
+
Continue by running the requested checks and opening/inspecting the app when the assignment requires it.
|
|
1332
1331
|
\`\`\`
|
|
1333
1332
|
`;
|
|
1334
1333
|
}
|
|
@@ -1350,6 +1349,65 @@ function injectAgcTrailer(command, args, agentId, agentName) {
|
|
|
1350
1349
|
const identity = agentName ? `${agentName} (agc)` : agentId ? `agc/${agentId}` : "agc agent";
|
|
1351
1350
|
return [...args, "--trailer", `Co-Authored-By: ${identity} <agc-agent@users.noreply.github.com>`];
|
|
1352
1351
|
}
|
|
1352
|
+
var AGC_HOOK_MARKER = "# agc-session:";
|
|
1353
|
+
var HOOK_BACKUP_SUFFIX = ".agc-backup";
|
|
1354
|
+
function findGitDir(rootDir) {
|
|
1355
|
+
const gitPath = (0, import_path3.join)(rootDir, ".git");
|
|
1356
|
+
if (!(0, import_fs3.existsSync)(gitPath)) return null;
|
|
1357
|
+
const s = (0, import_fs3.statSync)(gitPath);
|
|
1358
|
+
if (s.isDirectory()) return gitPath;
|
|
1359
|
+
if (s.isFile()) {
|
|
1360
|
+
const content = (0, import_fs3.readFileSync)(gitPath, "utf8");
|
|
1361
|
+
const match = content.match(/^gitdir:\s*(.+)$/m);
|
|
1362
|
+
if (match) return match[1].trim();
|
|
1363
|
+
}
|
|
1364
|
+
return null;
|
|
1365
|
+
}
|
|
1366
|
+
function installGitHook(rootDir, sessionId, agentId, agentName) {
|
|
1367
|
+
const gitDir = findGitDir(rootDir);
|
|
1368
|
+
if (!gitDir) return;
|
|
1369
|
+
const hooksDir = (0, import_path3.join)(gitDir, "hooks");
|
|
1370
|
+
(0, import_fs3.mkdirSync)(hooksDir, { recursive: true });
|
|
1371
|
+
const hookPath = (0, import_path3.join)(hooksDir, "prepare-commit-msg");
|
|
1372
|
+
if ((0, import_fs3.existsSync)(hookPath)) {
|
|
1373
|
+
const existing = (0, import_fs3.readFileSync)(hookPath, "utf8");
|
|
1374
|
+
if (!existing.includes(AGC_HOOK_MARKER)) {
|
|
1375
|
+
(0, import_fs3.writeFileSync)(hookPath + HOOK_BACKUP_SUFFIX, existing, { mode: 493 });
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
const identity = agentName ? `${agentName} (agc)` : agentId ? `agc/${agentId}` : "agc agent";
|
|
1379
|
+
const trailer = `Co-Authored-By: ${identity} <agc-agent@users.noreply.github.com>`;
|
|
1380
|
+
const chainLine = (0, import_fs3.existsSync)(hookPath + HOOK_BACKUP_SUFFIX) ? `
|
|
1381
|
+
# chain pre-existing hook
|
|
1382
|
+
"$(dirname "$0")/prepare-commit-msg${HOOK_BACKUP_SUFFIX}" "$@" 2>/dev/null || true
|
|
1383
|
+
` : "";
|
|
1384
|
+
const hook = `#!/bin/sh
|
|
1385
|
+
${AGC_HOOK_MARKER}${sessionId}
|
|
1386
|
+
COMMIT_MSG_FILE="$1"
|
|
1387
|
+
COMMIT_SOURCE="$2"
|
|
1388
|
+
${chainLine}
|
|
1389
|
+
case "$COMMIT_SOURCE" in merge|squash) exit 0 ;; esac
|
|
1390
|
+
TRAILER="${trailer}"
|
|
1391
|
+
grep -qF "$TRAILER" "$COMMIT_MSG_FILE" 2>/dev/null && exit 0
|
|
1392
|
+
printf '\\n%s\\n' "$TRAILER" >> "$COMMIT_MSG_FILE"
|
|
1393
|
+
`;
|
|
1394
|
+
(0, import_fs3.writeFileSync)(hookPath, hook, { mode: 493 });
|
|
1395
|
+
}
|
|
1396
|
+
function removeGitHook(rootDir) {
|
|
1397
|
+
const gitDir = findGitDir(rootDir);
|
|
1398
|
+
if (!gitDir) return;
|
|
1399
|
+
const hookPath = (0, import_path3.join)(gitDir, "hooks", "prepare-commit-msg");
|
|
1400
|
+
if (!(0, import_fs3.existsSync)(hookPath)) return;
|
|
1401
|
+
const content = (0, import_fs3.readFileSync)(hookPath, "utf8");
|
|
1402
|
+
if (!content.includes(AGC_HOOK_MARKER)) return;
|
|
1403
|
+
const backupPath = hookPath + HOOK_BACKUP_SUFFIX;
|
|
1404
|
+
if ((0, import_fs3.existsSync)(backupPath)) {
|
|
1405
|
+
(0, import_fs3.writeFileSync)(hookPath, (0, import_fs3.readFileSync)(backupPath, "utf8"), { mode: 493 });
|
|
1406
|
+
(0, import_fs3.unlinkSync)(backupPath);
|
|
1407
|
+
} else {
|
|
1408
|
+
(0, import_fs3.unlinkSync)(hookPath);
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1353
1411
|
function safePath(root, userPath) {
|
|
1354
1412
|
const abs = (0, import_path3.resolve)(root, userPath);
|
|
1355
1413
|
const rel = (0, import_path3.relative)(root, abs);
|
|
@@ -1841,7 +1899,7 @@ function runCommand() {
|
|
|
1841
1899
|
...cfg.initiator && { initiatorId: cfg.initiator },
|
|
1842
1900
|
...cliContext && { cliContext }
|
|
1843
1901
|
};
|
|
1844
|
-
if (opts.noStream) {
|
|
1902
|
+
if (opts.noStream && !localEnabled) {
|
|
1845
1903
|
const spinner = spin("Running\u2026");
|
|
1846
1904
|
try {
|
|
1847
1905
|
const result = await client.run.once(params);
|
|
@@ -1917,7 +1975,8 @@ Session: ${sessionId} (resume with: agc run --session ${sessionId} "<prompt>")`
|
|
|
1917
1975
|
} else if (event.type === "final") {
|
|
1918
1976
|
if (hasOutput) process.stdout.write("\n");
|
|
1919
1977
|
const e = event;
|
|
1920
|
-
|
|
1978
|
+
const finalText = e.content ?? e.payload?.content ?? e.payload?.text ?? e.payload?.message;
|
|
1979
|
+
if (finalText && !hasOutput) console.log(finalText);
|
|
1921
1980
|
if (sessionId) console.log(c.dim(`
|
|
1922
1981
|
Session: ${sessionId} (resume with: agc run --session ${sessionId} "<prompt>")`));
|
|
1923
1982
|
break;
|
|
@@ -2039,23 +2098,27 @@ function chatCommand() {
|
|
|
2039
2098
|
process.exit(1);
|
|
2040
2099
|
}
|
|
2041
2100
|
}
|
|
2101
|
+
let agentName;
|
|
2042
2102
|
let walletLine = "";
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
const
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2103
|
+
await Promise.allSettled([
|
|
2104
|
+
client.agents.get(agentId).then((res) => {
|
|
2105
|
+
agentName = (res?.data ?? res)?.name;
|
|
2106
|
+
}),
|
|
2107
|
+
client.wallets.primary(agentId).then(async (primary) => {
|
|
2108
|
+
const w = primary?.data ?? primary;
|
|
2109
|
+
if (w?.id) {
|
|
2110
|
+
const bal = await client.wallets.balance(w.id).catch(() => null);
|
|
2111
|
+
const b = bal?.data ?? bal;
|
|
2112
|
+
const addr = `${w.address.slice(0, 6)}\u2026${w.address.slice(-4)}`;
|
|
2113
|
+
const usdc = b?.usdc ?? "0";
|
|
2114
|
+
walletLine = `${addr} ${c.bold(usdc + " USDC")}`;
|
|
2115
|
+
}
|
|
2116
|
+
})
|
|
2117
|
+
]);
|
|
2055
2118
|
console.log(`
|
|
2056
2119
|
${c.bold("Agent Commons Chat")}`);
|
|
2057
2120
|
const headerRows = [
|
|
2058
|
-
["Agent", agentId],
|
|
2121
|
+
["Agent", agentName ? `${agentName} ${c.dim(agentId)}` : agentId],
|
|
2059
2122
|
["Session", c.id(sessionId) + (isResume ? c.dim(" (resumed)") : c.dim(" (new)"))]
|
|
2060
2123
|
];
|
|
2061
2124
|
if (walletLine) headerRows.push(["Wallet", walletLine]);
|
|
@@ -2068,9 +2131,12 @@ ${c.bold("Agent Commons Chat")}`);
|
|
|
2068
2131
|
localToolsCfg = {
|
|
2069
2132
|
rootDir,
|
|
2070
2133
|
sessionId,
|
|
2134
|
+
agentId,
|
|
2135
|
+
agentName,
|
|
2071
2136
|
appendLog: (record) => appendSessionLog(sessionId, record),
|
|
2072
2137
|
permissions: /* @__PURE__ */ new Map()
|
|
2073
2138
|
};
|
|
2139
|
+
installGitHook(rootDir, sessionId, agentId, agentName);
|
|
2074
2140
|
appendSessionLog(sessionId, {
|
|
2075
2141
|
type: "local_tools_enabled",
|
|
2076
2142
|
rootDir,
|
|
@@ -2334,10 +2400,15 @@ ${sym.fail} ${c.error(event.message ?? "Stream error")}`);
|
|
|
2334
2400
|
rl.resume();
|
|
2335
2401
|
rl.prompt();
|
|
2336
2402
|
});
|
|
2403
|
+
const cleanup = () => {
|
|
2404
|
+
if (localToolsCfg) removeGitHook(localToolsCfg.rootDir);
|
|
2405
|
+
};
|
|
2337
2406
|
rl.on("close", () => {
|
|
2407
|
+
cleanup();
|
|
2338
2408
|
process.exit(0);
|
|
2339
2409
|
});
|
|
2340
2410
|
process.on("SIGINT", () => {
|
|
2411
|
+
cleanup();
|
|
2341
2412
|
console.log(c.dim(`
|
|
2342
2413
|
Session preserved. Resume with: agc chat --resume ${sessionId}`));
|
|
2343
2414
|
process.exit(130);
|
|
@@ -3801,7 +3872,7 @@ async function pickAgentInteractively(action) {
|
|
|
3801
3872
|
return agentId;
|
|
3802
3873
|
}
|
|
3803
3874
|
var program = new import_commander16.Command();
|
|
3804
|
-
program.name("agc").description("Agent Commons CLI \u2014 interact with the Agent Commons platform").version("0.
|
|
3875
|
+
program.name("agc").description("Agent Commons CLI \u2014 interact with the Agent Commons platform").version("0.2.0", "-v, --version").action(async () => {
|
|
3805
3876
|
await interactiveMenu();
|
|
3806
3877
|
});
|
|
3807
3878
|
program.addCommand(loginCommand());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-commons/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Agent Commons CLI — chat, run, and manage agents from your terminal",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"commander": "^12.1.0",
|
|
17
17
|
"ora": "^8.1.1",
|
|
18
18
|
"pdf-parse": "^1.1.1",
|
|
19
|
-
"@agent-commons/sdk": "0.
|
|
19
|
+
"@agent-commons/sdk": "0.2.0"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@types/node": "^22.10.2",
|