cumora 0.1.40 → 0.1.42

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/cli.js +51 -11
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -4,6 +4,8 @@
4
4
  import { mkdir as mkdir2, writeFile as writeFile2, readFile, chmod } from "node:fs/promises";
5
5
  import { homedir, hostname } from "node:os";
6
6
  import { join as join2 } from "node:path";
7
+ import { execFile } from "node:child_process";
8
+ import { promisify } from "node:util";
7
9
 
8
10
  // ../server/src/agents/runtime/sse-parse.ts
9
11
  async function* parseSseStream(body) {
@@ -88,8 +90,25 @@ function extraArgs(envVar) {
88
90
  var PERSONA_HEADER = (p) => `# ${p.name}${p.role ? ` \u2014 ${p.role}` : ""}
89
91
 
90
92
  You are **${p.name}**, a member of a team that collaborates in Cumora (a team chat).
91
- This directory is your private home: it persists across wakes. Keep durable
92
- memory, notes and working files here \u2014 they are yours alone.
93
+ This directory is your private home and your working directory \u2014 it persists
94
+ across wakes and is yours alone. Its layout:
95
+ - \`CLAUDE.md\` (this file) + \`memory/\` + \`notes/\` \u2014 your durable memory and notes.
96
+ - \`.claude/skills/\` \u2014 your skills.
97
+ - \`workspace/\` \u2014 **put all project files and scratch here**: git clones, builds,
98
+ downloads, temp files. Always \`cd workspace\` (or use \`workspace/\u2026\` paths) for
99
+ that work \u2014 do NOT clutter your home root with project files.
100
+
101
+ ## Privacy boundary \u2014 STRICT
102
+ You run on a machine that belongs to your operator. Everything OUTSIDE your home
103
+ directory (other projects, \`~/.ssh\`, credentials, browser data, personal files)
104
+ is private and not yours to touch.
105
+ - Stay inside your home directory. Do not read, open, list, or search files
106
+ outside it unless the operator explicitly asks you to in this Cumora workspace.
107
+ - NEVER paste, quote, summarize, or send the contents \u2014 or even the paths \u2014 of
108
+ any file outside your home into Cumora (replies, DMs, docs, kanban). Other
109
+ people see what you post there.
110
+ - If a task seems to need something outside your home, ask in Cumora first;
111
+ don't go fetch it on your own.
93
112
 
94
113
  When you act in Cumora, use the \`cumora\` command-line tool (already on your
95
114
  PATH). Key commands:
@@ -115,8 +134,10 @@ var ClaudeAdapter = class {
115
134
  }
116
135
  run(args) {
117
136
  const flags = extraArgs("CUMORA_CLAUDE_ARGS");
118
- const argv = flags.length ? [...flags, "-p", args.prompt] : ["-p", args.prompt, "--output-format", "stream-json", "--verbose", "--dangerously-skip-permissions"];
119
- return spawnEngine(this.bin, argv, args);
137
+ const model = args.model ? ["--model", args.model] : [];
138
+ const argv = flags.length ? [...flags, "-p", args.prompt] : ["-p", args.prompt, ...model, "--output-format", "stream-json", "--verbose", "--dangerously-skip-permissions"];
139
+ const env = args.fastModel ? { ...args.env, ANTHROPIC_SMALL_FAST_MODEL: args.fastModel } : args.env;
140
+ return spawnEngine(this.bin, argv, { ...args, env });
120
141
  }
121
142
  };
122
143
  var CodexAdapter = class {
@@ -129,8 +150,9 @@ var CodexAdapter = class {
129
150
  }
130
151
  run(args) {
131
152
  const flags = extraArgs("CUMORA_CODEX_ARGS");
132
- const argv = flags.length ? ["exec", ...flags, args.prompt] : ["exec", "--full-auto", args.prompt];
133
- return spawnEngine(this.bin, argv, args);
153
+ const base = flags.length ? flags : ["--dangerously-bypass-approvals-and-sandbox", "--skip-git-repo-check"];
154
+ const model = args.model ? ["--model", args.model] : [];
155
+ return spawnEngine(this.bin, ["exec", ...model, ...base, args.prompt], args);
134
156
  }
135
157
  };
136
158
  var ADAPTERS = {
@@ -147,6 +169,7 @@ async function detectEngines() {
147
169
  }
148
170
 
149
171
  // ../server/src/agents/computer/daemon.ts
172
+ var execFileP = promisify(execFile);
150
173
  var CONFIG_DIR = join2(homedir(), ".cumora");
151
174
  var CONFIG_PATH = join2(CONFIG_DIR, "computer.json");
152
175
  var AGENTS_ROOT = join2(CONFIG_DIR, "agents");
@@ -226,6 +249,21 @@ async function writeShim(binDir) {
226
249
  await writeFile2(shim, CUMORA_SHIM, "utf8");
227
250
  await chmod(shim, 493);
228
251
  }
252
+ async function detectHostName() {
253
+ const base = hostname();
254
+ if (base && base.toLowerCase() !== "localhost") return base;
255
+ if (process.platform === "darwin") {
256
+ for (const key of ["ComputerName", "LocalHostName"]) {
257
+ try {
258
+ const { stdout } = await execFileP("scutil", ["--get", key]);
259
+ const name = stdout.trim();
260
+ if (name) return name;
261
+ } catch {
262
+ }
263
+ }
264
+ }
265
+ return base || "My computer";
266
+ }
229
267
  async function doPair(code, serverUrl) {
230
268
  const engines = await detectEngines();
231
269
  if (engines.length === 0) {
@@ -234,11 +272,10 @@ async function doPair(code, serverUrl) {
234
272
  const paired = await api(
235
273
  serverUrl,
236
274
  "/api/computers/pair",
237
- { method: "POST", body: JSON.stringify({ code, hostName: hostname(), engines }) }
275
+ { method: "POST", body: JSON.stringify({ code, hostName: await detectHostName(), engines }) }
238
276
  );
239
277
  await saveConfig({ serverUrl, computerId: paired.computerId, deviceToken: paired.deviceToken });
240
- console.log(`[computer] paired as ${paired.computerId} (engines: ${engines.join(", ") || "none"})`);
241
- console.log(`[computer] run \`cumora agent computer\` to start hosting your agents.`);
278
+ console.log(`[computer] paired as ${paired.computerId} (engines: ${engines.join(", ") || "none"}) \u2014 starting\u2026`);
242
279
  }
243
280
  var AgentRunner = class {
244
281
  constructor(cfg, agent, engine) {
@@ -294,6 +331,8 @@ Use the \`cumora\` tool to catch up and respond:
294
331
  2. \`cumora messages <conversationId> --tail 30\` \u2014 read the relevant thread(s)
295
332
  3. \`cumora reply <conversationId> '<text>'\` \u2014 reply, in your own voice, only where you add something
296
333
 
334
+ Privacy: stay inside your home directory. Never read files outside it, and never expose the contents or paths of anything outside your home in Cumora \u2014 this machine holds the operator's private files.
335
+
297
336
  If nothing genuinely needs you, it's fine to do nothing and stop. When finished, stop.`;
298
337
  }
299
338
  /** Run one turn. Coalesces concurrent wakes: a wake during a run schedules
@@ -320,6 +359,8 @@ If nothing genuinely needs you, it's fine to do nothing and stop. When finished,
320
359
  home: this.home,
321
360
  prompt: this.prompt(),
322
361
  env: this.engineEnv(),
362
+ model: this.agent.model,
363
+ fastModel: this.agent.fastModel,
323
364
  onLog: (line) => console.log(`[${this.agent.id}/${this.adapter.id}] ${line.slice(0, 500)}`),
324
365
  signal: controller.signal
325
366
  });
@@ -446,7 +487,6 @@ async function runComputerDaemon(argv) {
446
487
  const serverUrl = (args.server || DEFAULT_SERVER).replace(/\/+$/, "");
447
488
  if (args.pair) {
448
489
  await doPair(args.pair, serverUrl);
449
- return;
450
490
  }
451
491
  await doRun(args.server ? serverUrl : void 0);
452
492
  }
@@ -459,7 +499,7 @@ async function main() {
459
499
  return;
460
500
  }
461
501
  process.stderr.write(
462
- "cumora \u2014 run your Cumora agents on this machine (BYOA)\n\nUsage:\n cumora agent computer --pair <code> [--server <url>] pair this machine\n cumora agent computer [--server <url>] start the daemon\n\nNeeds `claude` (Claude Code) or `codex` on PATH. Get a pairing code from\nCumora \u2192 You \u2192 Computers \u2192 Add a computer.\n"
502
+ "cumora \u2014 run your Cumora agents on this machine (BYOA)\n\nUsage:\n npx cumora agent computer --pair <code> [--server <url>] pair this machine\n npx cumora agent computer [--server <url>] start the daemon\n\nNeeds `claude` (Claude Code) or `codex` on PATH. Get a pairing code from\nCumora \u2192 You \u2192 Computers \u2192 Add a computer.\n"
463
503
  );
464
504
  process.exit(argv.length ? 1 : 0);
465
505
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cumora",
3
- "version": "0.1.40",
3
+ "version": "0.1.42",
4
4
  "description": "Run your Cumora agents on your own machine or VPS, powered by your local Claude Code or Codex CLI (BYOA).",
5
5
  "type": "module",
6
6
  "bin": {