@ghostystudio/cli 0.2.0 → 0.3.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.
Files changed (2) hide show
  1. package/dist/index.js +35 -6
  2. 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.2.0"}`,
278
+ "user-agent": `ghosty-cli/${"0.3.0"}`,
279
279
  ...opts.body !== void 0 ? { "content-type": "application/json" } : {},
280
280
  ...opts.headers
281
281
  },
@@ -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";
@@ -338,7 +361,9 @@ async function agentsSet(id, v) {
338
361
  if (v.model) body.model = v.model;
339
362
  if (v.prompt) body.prompt = v.prompt;
340
363
  if (v["prompt-file"]) body.prompt = await readFile2(v["prompt-file"], "utf8");
341
- if (!Object.keys(body).length) throw usage("Nothing to change.", "Use --name, --model, --prompt or --prompt-file.");
364
+ const env = parseEnv(v.env);
365
+ if (env) body.env = env;
366
+ if (!Object.keys(body).length) throw usage("Nothing to change.", "Use --name, --model, --prompt, --prompt-file or --env.");
342
367
  const r = await api(agentPath(id), { method: "PATCH", body });
343
368
  out(r, () => `${lavender("\u2713")} Updated ${Object.keys(body).join(", ")}.`);
344
369
  }
@@ -670,7 +695,7 @@ async function scheduleCmd(sub, agent, arg, v) {
670
695
  });
671
696
  throw e;
672
697
  }
673
- if (v.title) await api(convPath(agent, `/${enc3(sid)}`), { method: "PATCH", body: { title: v.title } });
698
+ if (v.title && created) await api(convPath(agent, `/${enc3(sid)}`), { method: "PATCH", body: { title: v.title } });
674
699
  const p = r.programado;
675
700
  return out(
676
701
  { scheduled: p },
@@ -699,8 +724,9 @@ ${bold("Session")}
699
724
 
700
725
  ${bold("Agents")}
701
726
  agents ls List your agents
727
+ agents create Create an agent --name [--engine] [--model] [--prompt | --prompt-file FILE] [--env K=V,\u2026]
702
728
  agents get <id> Show an agent's config [--fields name,model,prompt]
703
- agents set <id> Change identity [--name] [--model] [--prompt | --prompt-file FILE]
729
+ agents set <id> Change identity [--name] [--model] [--prompt | --prompt-file FILE] [--env K=V,\u2026]
704
730
  agents restart <id> Restart so the next turn loads new files/skills/MCP
705
731
 
706
732
  ${bold("Configure an agent")}
@@ -747,6 +773,8 @@ async function main() {
747
773
  fields: { type: "string" },
748
774
  name: { type: "string" },
749
775
  model: { type: "string" },
776
+ engine: { type: "string" },
777
+ env: { type: "string" },
750
778
  prompt: { type: "string" },
751
779
  "prompt-file": { type: "string" },
752
780
  file: { type: "string" },
@@ -765,7 +793,7 @@ async function main() {
765
793
  });
766
794
  globals.json = Boolean(v.json);
767
795
  globals.token = v.token;
768
- if (v.version) return out({ version: "0.2.0" }, () => "0.2.0");
796
+ if (v.version) return out({ version: "0.3.0" }, () => "0.3.0");
769
797
  const [cmd, sub, a1, a2] = pos;
770
798
  if (!cmd || v.help || cmd === "help") return showHelp();
771
799
  switch (cmd) {
@@ -789,10 +817,11 @@ async function main() {
789
817
  }
790
818
  case "agents":
791
819
  if (sub === "ls" || sub === "list" || !sub) return agentsLs();
820
+ if (sub === "create" || sub === "new") return agentsCreate(v);
792
821
  if (sub === "get") return agentsGet(a1, v.fields);
793
822
  if (sub === "set") return agentsSet(a1, v);
794
823
  if (sub === "restart") return agentsRestart(a1);
795
- throw usage(`Unknown agents subcommand: ${sub}.`, "Try: ghosty agents ls | get | set | restart");
824
+ throw usage(`Unknown agents subcommand: ${sub}.`, "Try: ghosty agents ls | create | get | set | restart");
796
825
  case "files":
797
826
  return filesCmd(sub, a1, a2, v);
798
827
  case "skills":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ghostystudio/cli",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Official Ghosty Studio CLI — configure, test and chat with your agents from the terminal. Built for humans and coding agents.",
5
5
  "type": "module",
6
6
  "bin": {