@codegrammer/co-od 0.1.3 → 0.1.4

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.
@@ -0,0 +1 @@
1
+ export declare function run(args: string[]): Promise<void>;
@@ -0,0 +1,168 @@
1
+ import * as api from "../api-client.js";
2
+ import { getAdapter } from "../adapters/index.js";
3
+ import { writeFileSync, mkdirSync, existsSync } from "node:fs";
4
+ import { join, basename } from "node:path";
5
+ import { homedir } from "node:os";
6
+ function parseArgs(args) {
7
+ const parsed = {
8
+ dir: process.cwd(),
9
+ provider: "claude",
10
+ };
11
+ for (let i = 0; i < args.length; i++) {
12
+ if (args[i] === "--dir" && args[i + 1]) {
13
+ parsed.dir = args[++i];
14
+ }
15
+ else if (args[i] === "--name" && args[i + 1]) {
16
+ parsed.name = args[++i];
17
+ }
18
+ else if (args[i] === "--provider" && args[i + 1]) {
19
+ parsed.provider = args[++i];
20
+ }
21
+ else if (args[i] === "--server" && args[i + 1]) {
22
+ parsed.server = args[++i];
23
+ }
24
+ else if (!args[i].startsWith("--") && !parsed.name) {
25
+ parsed.name = args[i];
26
+ }
27
+ }
28
+ return parsed;
29
+ }
30
+ function timestamp() {
31
+ return new Date().toISOString().slice(11, 19);
32
+ }
33
+ export async function run(args) {
34
+ if (args.includes("--help") || args.includes("-h")) {
35
+ console.error(`Usage: co-od init [name] [--dir <path>] [--provider claude|codex|openclaw]
36
+
37
+ Sets up a new co-ode project:
38
+ 1. Creates a room on co-od.dev
39
+ 2. Links it to your local project directory
40
+ 3. Adds a default agent
41
+ 4. Generates a .co-od config file
42
+ 5. Ready to go — start giving tasks
43
+
44
+ Examples:
45
+ co-od init # Uses current dir name as room name
46
+ co-od init "my-saas-app" # Custom room name
47
+ co-od init --provider codex # Use Codex as default agent
48
+ co-od init --dir ~/projects/app # Different directory
49
+ `);
50
+ process.exit(0);
51
+ }
52
+ const parsed = parseArgs(args);
53
+ if (parsed.server) {
54
+ process.env.CO_ODE_SERVER = parsed.server;
55
+ }
56
+ // Ensure logged in
57
+ const token = api.getSessionToken();
58
+ if (!token) {
59
+ console.error(`[${timestamp()}] Not logged in. Run: co-od login`);
60
+ process.exit(1);
61
+ }
62
+ const projectDir = parsed.dir;
63
+ const roomName = parsed.name || basename(projectDir);
64
+ console.error(`\n co-od init\n`);
65
+ console.error(` project: ${projectDir}`);
66
+ console.error(` room: ${roomName}`);
67
+ console.error(` provider: ${parsed.provider}\n`);
68
+ // Step 1: Check provider is available
69
+ console.error(` [1/5] Checking ${parsed.provider} CLI...`);
70
+ const adapter = getAdapter(parsed.provider);
71
+ const available = await adapter.available();
72
+ if (!available) {
73
+ console.error(` ✗ ${adapter.name} not found on PATH`);
74
+ console.error(` Install it first, then run co-od init again.`);
75
+ process.exit(1);
76
+ }
77
+ console.error(` ✓ ${adapter.name} available`);
78
+ // Step 2: Create room
79
+ console.error(` [2/5] Creating room "${roomName}"...`);
80
+ let roomId;
81
+ try {
82
+ const res = await api.post("/api/rooms", { name: roomName });
83
+ roomId = res.roomId || res.room?._id || "";
84
+ if (!roomId)
85
+ throw new Error("No room ID returned");
86
+ console.error(` ✓ Room created: ${roomId.slice(0, 12)}...`);
87
+ }
88
+ catch (err) {
89
+ console.error(` ✗ Failed to create room: ${err}`);
90
+ process.exit(1);
91
+ }
92
+ // Step 3: Add default agent
93
+ console.error(` [3/5] Adding default agent...`);
94
+ let agentId;
95
+ try {
96
+ const agentName = parsed.provider === "codex" ? "Codex Builder"
97
+ : parsed.provider === "openclaw" ? "OpenClaw Agent"
98
+ : "Claude Builder";
99
+ const res = await api.post(`/api/rooms/${roomId}/agents`, {
100
+ name: agentName,
101
+ type: "builder",
102
+ executionMode: parsed.provider === "codex" ? "local_codex" : "local_claude_code",
103
+ provider: parsed.provider === "codex" ? "openai"
104
+ : parsed.provider === "openclaw" ? "openclaw"
105
+ : "anthropic",
106
+ permissions: {
107
+ "fs.read": true,
108
+ "fs.write": true,
109
+ "fs.applyPatch": true,
110
+ "exec.run": true,
111
+ "net.egress": false,
112
+ "ports.expose": false,
113
+ "secrets.read": false,
114
+ },
115
+ });
116
+ agentId = res.agentId || "";
117
+ console.error(` ✓ Agent "${agentName}" added`);
118
+ }
119
+ catch (err) {
120
+ console.error(` ✗ Failed to add agent: ${err}`);
121
+ agentId = "";
122
+ }
123
+ // Step 4: Save config
124
+ console.error(` [4/5] Saving config...`);
125
+ const config = {
126
+ roomId,
127
+ roomName,
128
+ projectDir,
129
+ provider: parsed.provider,
130
+ agentId,
131
+ server: api.getBaseUrl(),
132
+ createdAt: new Date().toISOString(),
133
+ };
134
+ // Save to project dir
135
+ const configPath = join(projectDir, ".co-od.json");
136
+ try {
137
+ writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
138
+ console.error(` ✓ ${configPath}`);
139
+ }
140
+ catch {
141
+ console.error(` ✗ Could not write ${configPath}`);
142
+ }
143
+ // Also save room mapping to global config
144
+ const globalConfigDir = join(homedir(), ".co-od");
145
+ const roomsMapPath = join(globalConfigDir, "rooms.json");
146
+ try {
147
+ mkdirSync(globalConfigDir, { recursive: true });
148
+ let rooms = {};
149
+ if (existsSync(roomsMapPath)) {
150
+ rooms = JSON.parse(require("node:fs").readFileSync(roomsMapPath, "utf-8"));
151
+ }
152
+ rooms[roomId] = { roomId, projectDir, name: roomName };
153
+ writeFileSync(roomsMapPath, JSON.stringify(rooms, null, 2) + "\n", "utf-8");
154
+ }
155
+ catch {
156
+ // Non-fatal
157
+ }
158
+ // Step 5: Done
159
+ console.error(` [5/5] Ready!\n`);
160
+ console.error(` Your room is live. Next steps:\n`);
161
+ console.error(` co-od run ${roomId.slice(0, 12)} "describe your task" # run a single task`);
162
+ console.error(` co-od daemon ${roomId.slice(0, 12)} --auto-execute # autonomous mode`);
163
+ console.error(` co-od share # invite teammates\n`);
164
+ console.error(` Or open in browser:`);
165
+ console.error(` ${api.getBaseUrl()}/rooms/${roomId}\n`);
166
+ // Output JSON for scripting
167
+ console.log(JSON.stringify(config, null, 2));
168
+ }
package/dist/index.js CHANGED
@@ -2,11 +2,12 @@
2
2
  "use strict";
3
3
  const VERSION = "0.1.0";
4
4
  const COMMANDS = {
5
+ init: { desc: "Set up a new co-ode project", usage: "co-od init [name] [--dir <path>] [--provider claude|codex|openclaw]" },
5
6
  login: { desc: "Authenticate with co-ode", usage: "co-od login [--token <t>]" },
6
7
  rooms: { desc: "List your rooms", usage: "co-od rooms [--json]" },
7
8
  run: { desc: "Execute a single task in a room", usage: "co-od run <room> <goal> [--provider claude|codex|openclaw] [--dir <path>] [--json]" },
8
9
  join: { desc: "Join a room as an interactive agent", usage: "co-od join <room> [--invite-token <tok>] [--dir <path>]" },
9
- daemon: { desc: "Autonomous watch mode for a room", usage: "co-od daemon <room> [--as <name>] [--auto-execute] [--watch <events>]" },
10
+ daemon: { desc: "Autonomous watch mode for a room", usage: "co-od daemon <room> [--as <name>] [--auto-execute] [--handoff-to <agent>]" },
10
11
  share: { desc: "Generate a relay code for teammates", usage: "co-od share [--provider claude|codex|openclaw]" },
11
12
  connect: { desc: "Connect to a relay via code", usage: "co-od connect <code>" },
12
13
  status: { desc: "Show current login and running state", usage: "co-od status [--json]" },
@@ -58,6 +59,11 @@ async function main() {
58
59
  }
59
60
  // Route to command
60
61
  switch (command) {
62
+ case "init": {
63
+ const { run } = await import("./commands/init.js");
64
+ await run(commandArgs);
65
+ break;
66
+ }
61
67
  case "login": {
62
68
  const { run } = await import("./commands/login.js");
63
69
  await run(commandArgs);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codegrammer/co-od",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "CLI for co-ode \u2014 run AI agents in shared rooms from the command line",
5
5
  "type": "module",
6
6
  "bin": {