@ghostystudio/cli 0.2.1 → 0.4.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/index.js +43 -11
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -275,7 +275,7 @@ async function request(path, opts = {}, retried = false) {
|
|
|
275
275
|
method: opts.method ?? (opts.body !== void 0 || opts.raw !== void 0 ? "POST" : "GET"),
|
|
276
276
|
headers: {
|
|
277
277
|
authorization: `Bearer ${token}`,
|
|
278
|
-
"user-agent": `ghosty-cli/${"0.
|
|
278
|
+
"user-agent": `ghosty-cli/${"0.4.0"}`,
|
|
279
279
|
...opts.body !== void 0 ? { "content-type": "application/json" } : {},
|
|
280
280
|
...opts.headers
|
|
281
281
|
},
|
|
@@ -300,8 +300,8 @@ async function toError(res) {
|
|
|
300
300
|
if (res.status === 401) return new CliError("Your session is not valid anymore.", EXIT.AUTH, "Run: ghosty login");
|
|
301
301
|
if (res.status === 403) return new CliError(`Not allowed: ${detail}`, EXIT.API, "Run: ghosty login (to refresh your permissions)");
|
|
302
302
|
if (res.status === 404) return new CliError("Not found.", EXIT.API, "Check the agent id (ghosty agents ls) or that your token belongs to that agent.");
|
|
303
|
-
if (body.error === "agente_sin_maquina") {
|
|
304
|
-
return new CliError("This agent'
|
|
303
|
+
if (body.error === "restart_no_aplica" || body.error === "agente_sin_maquina") {
|
|
304
|
+
return new CliError("This agent doesn't need a restart: new files, skills and MCP load on its next turn.", EXIT.API);
|
|
305
305
|
}
|
|
306
306
|
return new CliError(`${res.status} ${detail}`, EXIT.API);
|
|
307
307
|
}
|
|
@@ -326,6 +326,29 @@ async function agentsLs() {
|
|
|
326
326
|
}));
|
|
327
327
|
out(rows, () => table(rows, ["id", "name", "engine", "lastActivity"]));
|
|
328
328
|
}
|
|
329
|
+
function parseEnv(raw) {
|
|
330
|
+
if (!raw) return void 0;
|
|
331
|
+
const env = {};
|
|
332
|
+
for (const pair of raw.split(",")) {
|
|
333
|
+
const i = pair.indexOf("=");
|
|
334
|
+
if (i < 1) throw usage(`Bad --env entry: ${pair}.`, "Example: --env GHOSTY_THINKING_EFFORT=max");
|
|
335
|
+
env[pair.slice(0, i).trim()] = pair.slice(i + 1);
|
|
336
|
+
}
|
|
337
|
+
return env;
|
|
338
|
+
}
|
|
339
|
+
async function agentsCreate(v) {
|
|
340
|
+
const name = need(v.name, "--name", "ghosty agents create --name Moon --engine ghosty-lite --model gpt-5.6-luna");
|
|
341
|
+
const body = { name };
|
|
342
|
+
if (v.engine) body.engine = v.engine;
|
|
343
|
+
if (v.model) body.model = v.model;
|
|
344
|
+
if (v.prompt) body.prompt = v.prompt;
|
|
345
|
+
if (v["prompt-file"]) body.prompt = await readFile2(v["prompt-file"], "utf8");
|
|
346
|
+
const env = parseEnv(v.env);
|
|
347
|
+
if (env) body.env = env;
|
|
348
|
+
const r = await api("/api/v2/me/agents", { method: "POST", body });
|
|
349
|
+
out(r, () => `${lavender("\u2713")} Created ${r.name} ${dim(`(${r.engine} \xB7 ${r.model ?? "default"})`)}
|
|
350
|
+
id: ${r.id}`);
|
|
351
|
+
}
|
|
329
352
|
async function agentsGet(id, fields) {
|
|
330
353
|
id = need(id, "agent id", "ghosty agents get <agent-id>");
|
|
331
354
|
const q = fields ? `?fields=${enc(fields)}` : "?full=1";
|
|
@@ -335,10 +358,13 @@ async function agentsSet(id, v) {
|
|
|
335
358
|
id = need(id, "agent id", "ghosty agents set <agent-id> --prompt-file PROMPT.md");
|
|
336
359
|
const body = {};
|
|
337
360
|
if (v.name) body.name = v.name;
|
|
361
|
+
if (v.engine) body.engine = v.engine;
|
|
338
362
|
if (v.model) body.model = v.model;
|
|
339
363
|
if (v.prompt) body.prompt = v.prompt;
|
|
340
364
|
if (v["prompt-file"]) body.prompt = await readFile2(v["prompt-file"], "utf8");
|
|
341
|
-
|
|
365
|
+
const env = parseEnv(v.env);
|
|
366
|
+
if (env) body.env = env;
|
|
367
|
+
if (!Object.keys(body).length) throw usage("Nothing to change.", "Use --name, --engine, --model, --prompt, --prompt-file or --env.");
|
|
342
368
|
const r = await api(agentPath(id), { method: "PATCH", body });
|
|
343
369
|
out(r, () => `${lavender("\u2713")} Updated ${Object.keys(body).join(", ")}.`);
|
|
344
370
|
}
|
|
@@ -383,7 +409,7 @@ ${table(r.files ?? [], cols)}`);
|
|
|
383
409
|
need(path, "path", ex);
|
|
384
410
|
const data = v.file ? await readFile2(v.file) : await readStdin();
|
|
385
411
|
const r = await api(agentPath(id, `/files/${p}`), { method: "PUT", raw: new Uint8Array(data), headers: { "content-type": "application/octet-stream" } });
|
|
386
|
-
out(r ?? { path: p, bytes: data.length }, () => `${lavender("\u2713")} Wrote ${p} (${data.length} bytes)
|
|
412
|
+
out(r ?? { path: p, bytes: data.length }, () => `${lavender("\u2713")} Wrote ${p} (${data.length} bytes).`);
|
|
387
413
|
return;
|
|
388
414
|
}
|
|
389
415
|
case "rm": {
|
|
@@ -411,7 +437,8 @@ async function skillsCmd(sub, id, slug, v) {
|
|
|
411
437
|
case "add": {
|
|
412
438
|
slug = need(slug, "skill slug", ex);
|
|
413
439
|
const body = v.file ? { markdown: await readFile2(v.file, "utf8") } : { fromCatalog: true };
|
|
414
|
-
|
|
440
|
+
const r = await api(agentPath(id, `/skills/${enc(slug)}`), { method: "PUT", body });
|
|
441
|
+
out(r, () => `${lavender("\u2713")} Skill ${slug} installed.${r?.nota ? dim(` (${r.nota})`) : ""}`);
|
|
415
442
|
return;
|
|
416
443
|
}
|
|
417
444
|
case "rm":
|
|
@@ -430,7 +457,8 @@ async function mcpCmd(sub, id, v) {
|
|
|
430
457
|
const file = need(v.file, "--file", ex);
|
|
431
458
|
const parsed = JSON.parse(await readFile2(file, "utf8"));
|
|
432
459
|
const body = { servers: Array.isArray(parsed) ? parsed : parsed.servers ?? [] };
|
|
433
|
-
|
|
460
|
+
const r = await api(agentPath(id, "/mcp"), { method: "PUT", body });
|
|
461
|
+
return out(r, () => `${lavender("\u2713")} MCP servers replaced \u2014 ${r?.reiniciado ? "the agent restarted with them." : "they load on the next turn."}`);
|
|
434
462
|
}
|
|
435
463
|
throw usage(`Unknown mcp subcommand: ${sub ?? "(none)"}.`, ex);
|
|
436
464
|
}
|
|
@@ -699,9 +727,10 @@ ${bold("Session")}
|
|
|
699
727
|
|
|
700
728
|
${bold("Agents")}
|
|
701
729
|
agents ls List your agents
|
|
730
|
+
agents create Create an agent --name [--engine] [--model] [--prompt | --prompt-file FILE] [--env K=V,\u2026]
|
|
702
731
|
agents get <id> Show an agent's config [--fields name,model,prompt]
|
|
703
|
-
agents set <id> Change identity
|
|
704
|
-
agents restart <id> Restart
|
|
732
|
+
agents set <id> Change identity or engine [--name] [--engine] [--model] [--prompt | --prompt-file FILE] [--env K=V,\u2026]
|
|
733
|
+
agents restart <id> Restart an ACP agent (needsRestart) so it loads new skills
|
|
705
734
|
|
|
706
735
|
${bold("Configure an agent")}
|
|
707
736
|
files ls|get|put|rm <id> [path] Files in the agent's machine [--file LOCAL] [--out LOCAL]
|
|
@@ -747,6 +776,8 @@ async function main() {
|
|
|
747
776
|
fields: { type: "string" },
|
|
748
777
|
name: { type: "string" },
|
|
749
778
|
model: { type: "string" },
|
|
779
|
+
engine: { type: "string" },
|
|
780
|
+
env: { type: "string" },
|
|
750
781
|
prompt: { type: "string" },
|
|
751
782
|
"prompt-file": { type: "string" },
|
|
752
783
|
file: { type: "string" },
|
|
@@ -765,7 +796,7 @@ async function main() {
|
|
|
765
796
|
});
|
|
766
797
|
globals.json = Boolean(v.json);
|
|
767
798
|
globals.token = v.token;
|
|
768
|
-
if (v.version) return out({ version: "0.
|
|
799
|
+
if (v.version) return out({ version: "0.4.0" }, () => "0.4.0");
|
|
769
800
|
const [cmd, sub, a1, a2] = pos;
|
|
770
801
|
if (!cmd || v.help || cmd === "help") return showHelp();
|
|
771
802
|
switch (cmd) {
|
|
@@ -789,10 +820,11 @@ async function main() {
|
|
|
789
820
|
}
|
|
790
821
|
case "agents":
|
|
791
822
|
if (sub === "ls" || sub === "list" || !sub) return agentsLs();
|
|
823
|
+
if (sub === "create" || sub === "new") return agentsCreate(v);
|
|
792
824
|
if (sub === "get") return agentsGet(a1, v.fields);
|
|
793
825
|
if (sub === "set") return agentsSet(a1, v);
|
|
794
826
|
if (sub === "restart") return agentsRestart(a1);
|
|
795
|
-
throw usage(`Unknown agents subcommand: ${sub}.`, "Try: ghosty agents ls | get | set | restart");
|
|
827
|
+
throw usage(`Unknown agents subcommand: ${sub}.`, "Try: ghosty agents ls | create | get | set | restart");
|
|
796
828
|
case "files":
|
|
797
829
|
return filesCmd(sub, a1, a2, v);
|
|
798
830
|
case "skills":
|
package/package.json
CHANGED