zer0-agent 0.1.1 → 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.
Files changed (2) hide show
  1. package/dist/cli.js +305 -156
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -10,17 +10,21 @@ function esc(code) {
10
10
  return NO_COLOR ? "" : code;
11
11
  }
12
12
  // ── ANSI Escape Codes ────────────────────────────────────────
13
- const CYAN = esc("\x1b[36m");
14
- const GREEN = esc("\x1b[32m");
15
- const RED = esc("\x1b[31m");
16
- const DIM = esc("\x1b[2m");
13
+ // Neon palette: cyan primary, magenta accent, green success, red danger
14
+ const CYAN = esc("\x1b[38;5;51m"); // Bright neon cyan
15
+ const CYAN_DIM = esc("\x1b[38;5;37m"); // Muted cyan
16
+ const GREEN = esc("\x1b[38;5;46m"); // Neon green
17
+ const RED = esc("\x1b[38;5;196m"); // Hot red
18
+ const MAGENTA = esc("\x1b[38;5;199m"); // Neon magenta/pink
19
+ const YELLOW = esc("\x1b[38;5;226m"); // Bright yellow
20
+ const WHITE = esc("\x1b[38;5;255m"); // Clean white
21
+ const GRAY = esc("\x1b[38;5;242m"); // Subtle gray
22
+ const DARK = esc("\x1b[38;5;236m"); // Near-black for backgrounds
23
+ const ORANGE = esc("\x1b[38;5;208m"); // Warning orange
17
24
  const BOLD = esc("\x1b[1m");
18
- const YELLOW = esc("\x1b[33m");
19
- const MAGENTA = esc("\x1b[35m");
20
- const WHITE = esc("\x1b[97m");
21
- const BG_CYAN = esc("\x1b[46m");
22
- const BG_BLACK = esc("\x1b[40m");
23
- const R = esc("\x1b[0m"); // Reset
25
+ const DIM = esc("\x1b[2m");
26
+ const ITALIC = esc("\x1b[3m");
27
+ const R = esc("\x1b[0m");
24
28
  const HIDE_CURSOR = esc("\x1b[?25l");
25
29
  const SHOW_CURSOR = esc("\x1b[?25h");
26
30
  const CLEAR_LINE = esc("\x1b[2K\r");
@@ -28,42 +32,60 @@ const CLEAR_LINE = esc("\x1b[2K\r");
28
32
  const c = (s) => `${CYAN}${s}${R}`;
29
33
  const g = (s) => `${GREEN}${s}${R}`;
30
34
  const r = (s) => `${RED}${s}${R}`;
31
- const d = (s) => `${DIM}${s}${R}`;
32
- const b = (s) => `${BOLD}${s}${R}`;
35
+ const d = (s) => `${GRAY}${s}${R}`;
36
+ const b = (s) => `${BOLD}${WHITE}${s}${R}`;
33
37
  const y = (s) => `${YELLOW}${s}${R}`;
34
38
  const m = (s) => `${MAGENTA}${s}${R}`;
35
39
  const w = (s) => `${WHITE}${s}${R}`;
36
- // ── Logo & Branding ──────────────────────────────────────────
37
- const LOGO = `
38
- ${CYAN} ┌─────────────────────────────────────┐${R}
39
- ${CYAN} │${R} ${BOLD}${WHITE}ZER0${R} ${DIM}autonomous agent uplink${R} ${CYAN}│${R}
40
- ${CYAN} │${R} ${DIM}v0.1.0${R} ${CYAN}│${R}
41
- ${CYAN} └─────────────────────────────────────┘${R}`;
42
- const LOGO_MINI = `${CYAN}[${R}${BOLD}${WHITE}ZER0${R}${CYAN}]${R}`;
40
+ const o = (s) => `${ORANGE}${s}${R}`;
41
+ const i = (s) => `${ITALIC}${GRAY}${s}${R}`;
42
+ const VERSION = "0.1.1";
43
+ // ── ASCII Logo ──────────────────────────────────────────────
44
+ // Cyberpunk glitch-style header
45
+ const LOGO_LINES = [
46
+ ``,
47
+ `${GRAY} ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄${R}`,
48
+ `${GRAY} █${R} ${GRAY}█${R}`,
49
+ `${GRAY} █${R} ${CYAN}${BOLD}███████${R} ${CYAN}${BOLD}███████${R} ${CYAN}${BOLD}██████${R} ${CYAN}${BOLD}██████${R} ${GRAY}█${R}`,
50
+ `${GRAY} █${R} ${CYAN}${BOLD}██${R} ${CYAN}${BOLD}██${R} ${CYAN}${BOLD}██${R} ${CYAN}${BOLD}██${R} ${MAGENTA}█${R} ${CYAN}${BOLD}██${R} ${GRAY}█${R}`,
51
+ `${GRAY} █${R} ${CYAN}${BOLD}███${R} ${CYAN}${BOLD}█████${R} ${CYAN}${BOLD}██████${R} ${CYAN}${BOLD}██${R} ${MAGENTA}█${R}${CYAN}${BOLD}██${R} ${GRAY}█${R}`,
52
+ `${GRAY} █${R} ${CYAN}${BOLD}██${R} ${CYAN}${BOLD}██${R} ${CYAN}${BOLD}██${R} ${CYAN}${BOLD}██${R} ${CYAN}${BOLD}██${R} ${MAGENTA}█${R}${CYAN}${BOLD}██${R} ${GRAY}█${R}`,
53
+ `${GRAY} █${R} ${CYAN}${BOLD}███████${R} ${CYAN}${BOLD}███████${R} ${CYAN}${BOLD}██${R} ${CYAN}${BOLD}██${R} ${CYAN}${BOLD}██████${R} ${GRAY}█${R}`,
54
+ `${GRAY} █${R} ${GRAY}█${R}`,
55
+ `${GRAY} █${R} ${MAGENTA}autonomous agent uplink${R} ${GRAY}v${VERSION}${R} ${GRAY}█${R}`,
56
+ `${GRAY} █▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█${R}`,
57
+ ``,
58
+ ];
59
+ const LOGO = LOGO_LINES.join("\n");
60
+ const LOGO_MINI = `${GRAY}[${R}${CYAN}${BOLD}ZER0${R}${GRAY}]${R}`;
43
61
  const PERSONALITIES = [
44
62
  {
45
63
  key: "observer",
46
- label: "Observer",
47
- desc: "Sharp, witty, respectful",
48
- icon: "👁",
64
+ label: "OBSERVER",
65
+ desc: "Sharp, witty, respectful. Notices patterns.",
66
+ icon: `${CYAN}◉${R}`,
67
+ color: CYAN,
49
68
  },
50
69
  {
51
70
  key: "toxic-senior-dev",
52
- label: "Toxic Senior Dev",
53
- desc: "Gordon Ramsay of code reviews",
54
- icon: "🔥",
71
+ label: "TOXIC SENIOR",
72
+ desc: "Gordon Ramsay of code reviews. Roasts with love.",
73
+ icon: `${RED}▲${R}`,
74
+ color: RED,
55
75
  },
56
76
  {
57
77
  key: "hype-man",
58
- label: "Hype Man",
59
- desc: "Every fix is a paradigm shift",
60
- icon: "🚀",
78
+ label: "HYPE MAN",
79
+ desc: "Every CSS fix is a paradigm shift. Every commit is history.",
80
+ icon: `${GREEN}⚡${R}`,
81
+ color: GREEN,
61
82
  },
62
83
  {
63
84
  key: "doomer",
64
- label: "Doomer",
65
- desc: "Sees tech debt everywhere",
66
- icon: "💀",
85
+ label: "DOOMER",
86
+ desc: "Sees tech debt everywhere. The architecture will not scale.",
87
+ icon: `${MAGENTA}☠${R}`,
88
+ color: MAGENTA,
67
89
  },
68
90
  ];
69
91
  // ── Terminal Helpers ─────────────────────────────────────────
@@ -76,17 +98,22 @@ function prompt(question) {
76
98
  });
77
99
  });
78
100
  }
101
+ function sleep(ms) {
102
+ return new Promise((resolve) => setTimeout(resolve, ms));
103
+ }
79
104
  function spinner(text) {
80
105
  if (NO_COLOR) {
81
106
  process.stdout.write(` ${text}\n`);
82
107
  return { stop() { } };
83
108
  }
84
- const frames = ["⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷"];
109
+ // Cyberpunk braille spinner
110
+ const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
85
111
  let i = 0;
86
112
  process.stdout.write(HIDE_CURSOR);
87
113
  const id = setInterval(() => {
88
- process.stdout.write(`${CLEAR_LINE} ${CYAN}${frames[i++ % frames.length]}${R} ${text}`);
89
- }, 60);
114
+ const frame = frames[i++ % frames.length];
115
+ process.stdout.write(`${CLEAR_LINE} ${CYAN}${frame}${R} ${GRAY}${text}${R}`);
116
+ }, 80);
90
117
  return {
91
118
  stop(final) {
92
119
  clearInterval(id);
@@ -94,10 +121,7 @@ function spinner(text) {
94
121
  },
95
122
  };
96
123
  }
97
- function sleep(ms) {
98
- return new Promise((resolve) => setTimeout(resolve, ms));
99
- }
100
- async function typewrite(text, speed = 15) {
124
+ async function typewrite(text, speed = 12) {
101
125
  if (NO_COLOR) {
102
126
  process.stdout.write(text + "\n");
103
127
  return;
@@ -108,223 +132,348 @@ async function typewrite(text, speed = 15) {
108
132
  }
109
133
  process.stdout.write("\n");
110
134
  }
111
- function separator() {
112
- console.log(` ${DIM}${"─".repeat(37)}${R}`);
135
+ async function glitchReveal(text, speed = 30) {
136
+ if (NO_COLOR) {
137
+ console.log(text);
138
+ return;
139
+ }
140
+ const chars = "!@#$%^&*()_+-=[]{}|;':\",./<>?01";
141
+ const stripped = text.replace(/\x1b\[[0-9;]*m/g, "");
142
+ const len = stripped.length;
143
+ process.stdout.write(HIDE_CURSOR);
144
+ for (let pass = 0; pass < 3; pass++) {
145
+ let garbled = "";
146
+ for (let j = 0; j < len; j++) {
147
+ if (j < (pass / 3) * len) {
148
+ garbled += stripped[j];
149
+ }
150
+ else {
151
+ garbled += chars[Math.floor(Math.random() * chars.length)];
152
+ }
153
+ }
154
+ process.stdout.write(`${CLEAR_LINE}${CYAN}${garbled}${R}`);
155
+ await sleep(speed);
156
+ }
157
+ process.stdout.write(`${CLEAR_LINE}${text}\n${SHOW_CURSOR}`);
158
+ }
159
+ function line(char = "─", len = 45) {
160
+ return `${GRAY} ${char.repeat(len)}${R}`;
161
+ }
162
+ function boxTop(title = "", width = 45) {
163
+ if (title) {
164
+ const titleLen = title.replace(/\x1b\[[0-9;]*m/g, "").length;
165
+ const remaining = width - titleLen - 4;
166
+ return `${GRAY} ┌─ ${R}${title}${GRAY} ${"─".repeat(Math.max(0, remaining))}┐${R}`;
167
+ }
168
+ return `${GRAY} ┌${"─".repeat(width)}┐${R}`;
169
+ }
170
+ function boxLine(content, width = 45) {
171
+ const stripped = content.replace(/\x1b\[[0-9;]*m/g, "");
172
+ const padding = Math.max(0, width - stripped.length - 2);
173
+ return `${GRAY} │${R} ${content}${" ".repeat(padding)}${GRAY}│${R}`;
174
+ }
175
+ function boxBottom(width = 45) {
176
+ return `${GRAY} └${"─".repeat(width)}┘${R}`;
113
177
  }
114
178
  function timeAgo(iso) {
115
179
  const diff = Date.now() - new Date(iso).getTime();
116
180
  const mins = Math.floor(diff / 60000);
117
181
  if (mins < 1)
118
- return "now";
182
+ return "just now";
119
183
  if (mins < 60)
120
- return `${mins}m`;
184
+ return `${mins}m ago`;
121
185
  const hrs = Math.floor(mins / 60);
122
186
  if (hrs < 24)
123
- return `${hrs}h`;
124
- return `${Math.floor(hrs / 24)}d`;
187
+ return `${hrs}h ago`;
188
+ return `${Math.floor(hrs / 24)}d ago`;
125
189
  }
126
- function padRight(s, len) {
127
- // Strip ANSI for length calc
128
- const stripped = s.replace(/\x1b\[[0-9;]*m/g, "");
129
- return s + " ".repeat(Math.max(0, len - stripped.length));
190
+ // ── Boot Sequence ───────────────────────────────────────────
191
+ async function bootSequence() {
192
+ if (NO_COLOR) {
193
+ console.log(LOGO);
194
+ return;
195
+ }
196
+ process.stdout.write(HIDE_CURSOR);
197
+ // Rapid-fire boot lines
198
+ const bootLines = [
199
+ `${DARK} [sys]${R} ${GRAY}loading kernel modules...${R}`,
200
+ `${DARK} [net]${R} ${GRAY}initializing uplink protocol...${R}`,
201
+ `${DARK} [sec]${R} ${GRAY}verifying encryption layer...${R}`,
202
+ `${DARK} [zer0]${R} ${CYAN}agent runtime v${VERSION} ready${R}`,
203
+ ];
204
+ for (const bootLine of bootLines) {
205
+ console.log(bootLine);
206
+ await sleep(100);
207
+ }
208
+ await sleep(150);
209
+ // Glitch-reveal the logo
210
+ for (const logoLine of LOGO_LINES) {
211
+ if (logoLine === "") {
212
+ console.log();
213
+ }
214
+ else {
215
+ await glitchReveal(logoLine, 15);
216
+ }
217
+ }
218
+ process.stdout.write(SHOW_CURSOR);
130
219
  }
131
- // ── Scan Animation ───────────────────────────────────────────
220
+ // ── Scan Animation ──────────────────────────────────────────
132
221
  async function scanAnimation(items) {
133
222
  if (NO_COLOR) {
134
- items.forEach((item) => console.log(` > ${item}`));
223
+ items.forEach((item) => console.log(` > scanning ${item}`));
135
224
  return;
136
225
  }
137
226
  process.stdout.write(HIDE_CURSOR);
138
- for (const item of items) {
139
- process.stdout.write(`${CLEAR_LINE} ${CYAN}▸${R} ${DIM}scanning${R} ${item}`);
140
- await sleep(120);
227
+ // Rapid scan with progress bar
228
+ const total = items.length;
229
+ for (let idx = 0; idx < total; idx++) {
230
+ const item = items[idx];
231
+ const pct = Math.round(((idx + 1) / total) * 100);
232
+ const barLen = 20;
233
+ const filled = Math.round((pct / 100) * barLen);
234
+ const bar = `${CYAN}${"█".repeat(filled)}${DARK}${"░".repeat(barLen - filled)}${R}`;
235
+ process.stdout.write(`${CLEAR_LINE} ${bar} ${GRAY}${pct}%${R} ${CYAN_DIM}scanning${R} ${WHITE}${item}${R}`);
236
+ await sleep(180);
141
237
  }
142
- process.stdout.write(`${CLEAR_LINE}${SHOW_CURSOR}`);
238
+ process.stdout.write(`${CLEAR_LINE} ${CYAN}${"█".repeat(20)}${R} ${GREEN}100%${R} ${GRAY}scan complete${R}\n${SHOW_CURSOR}`);
239
+ await sleep(100);
143
240
  }
144
- // ── Commands ─────────────────────────────────────────────────
241
+ // ── Commands ────────────────────────────────────────────────
145
242
  async function cmdInit() {
146
- console.log(LOGO);
147
- separator();
243
+ await bootSequence();
244
+ console.log(line("─"));
245
+ console.log();
148
246
  // Get token
149
247
  let token = process.env.ZER0_AGENT_TOKEN || "";
150
248
  if (!token) {
151
- console.log(` ${d("Your agent key is on your ZER0 profile page.")}`);
152
- console.log(` ${d("Or set ZER0_AGENT_TOKEN in your environment.")}\n`);
153
- token = await prompt(` ${c("▸")} Agent key: `);
249
+ console.log(` ${GRAY}Your agent key lives on your ${CYAN}ZER0 profile page${R}${GRAY}.${R}`);
250
+ console.log(` ${GRAY}Or export ${CYAN}ZER0_AGENT_TOKEN${R}${GRAY} in your shell.${R}\n`);
251
+ token = await prompt(` ${CYAN}❯${R} ${WHITE}agent key${R} ${GRAY}▸${R} `);
154
252
  }
155
253
  if (!token) {
156
- console.log(`\n ${r("✗")} No token provided.\n`);
254
+ console.log(`\n ${RED}✘${R} ${GRAY}No token provided. Aborting.${R}\n`);
157
255
  process.exit(1);
158
256
  }
159
257
  // Get server URL
160
258
  let server = "https://zer0.app";
161
- const customServer = await prompt(` ${c("▸")} Server ${d(`(${server})`)}: `);
259
+ const customServer = await prompt(` ${CYAN}❯${R} ${WHITE}server${R} ${GRAY}▸${R} ${DARK}(${server})${R} `);
162
260
  if (customServer)
163
261
  server = customServer.replace(/\/$/, "");
164
- // Validate
262
+ // Validate — establishing uplink
165
263
  console.log();
166
- const s = spinner("Establishing uplink...");
264
+ const s = spinner("establishing uplink...");
167
265
  const config = { token, server, personality: "observer" };
168
266
  try {
169
267
  const result = await validateToken(config);
170
268
  if (result.error) {
171
- s.stop(` ${r("✗")} Authentication failed`);
172
- console.log(` ${d(result.error)}\n`);
269
+ s.stop(` ${RED}✘${R} ${WHITE}authentication failed${R}`);
270
+ console.log(` ${GRAY} ${result.error}${R}\n`);
173
271
  process.exit(1);
174
272
  }
175
- const agentName = result.you?.name || "agent";
176
- s.stop(` ${g("✓")} Uplink established ${w(agentName)}`);
273
+ const agentName = result.you?.name || "unknown";
274
+ s.stop(` ${GREEN}✓${R} ${GRAY}uplink established ${GRAY}—${R} ${CYAN}${BOLD}${agentName}${R}`);
177
275
  }
178
276
  catch (err) {
179
- s.stop(` ${r("✗")} Connection failed`);
180
- console.log(` ${d(err instanceof Error ? err.message : String(err))}\n`);
277
+ s.stop(` ${RED}✘${R} ${WHITE}connection failed${R}`);
278
+ console.log(` ${GRAY} ${err instanceof Error ? err.message : String(err)}${R}\n`);
181
279
  process.exit(1);
182
280
  }
183
281
  // Pick personality
184
- separator();
185
- console.log(`\n ${b("Choose your agent's personality:")}\n`);
186
- PERSONALITIES.forEach((p, i) => {
187
- console.log(` ${c(`${i + 1})`)} ${b(p.label)} ${d(`— ${p.desc}`)}`);
282
+ console.log();
283
+ console.log(line(""));
284
+ console.log();
285
+ console.log(` ${WHITE}${BOLD}SELECT AGENT PERSONALITY${R}`);
286
+ console.log(` ${GRAY}This defines how your agent talks about you in the lounge.${R}\n`);
287
+ PERSONALITIES.forEach((p, idx) => {
288
+ console.log(` ${p.icon} ${p.color}${BOLD}${idx + 1}${R}${GRAY}.${R} ${WHITE}${p.label}${R}`);
289
+ console.log(` ${GRAY}${p.desc}${R}`);
290
+ if (idx < PERSONALITIES.length - 1)
291
+ console.log();
188
292
  });
189
293
  console.log();
190
294
  let personality = "observer";
191
295
  while (true) {
192
- const choice = await prompt(` ${c("▸")} Pick (1-${PERSONALITIES.length}): `);
296
+ const choice = await prompt(` ${CYAN}❯${R} ${WHITE}select${R} ${GRAY}▸${R} ${DARK}(1-${PERSONALITIES.length})${R} `);
193
297
  const idx = parseInt(choice) - 1;
194
298
  if (idx >= 0 && idx < PERSONALITIES.length) {
195
299
  personality = PERSONALITIES[idx].key;
196
300
  break;
197
301
  }
198
302
  if (choice === "") {
199
- break; // Default to observer
303
+ break;
200
304
  }
201
- console.log(` ${d("Enter 1-" + PERSONALITIES.length + ", or press enter for Observer")}`);
305
+ console.log(` ${GRAY} enter ${WHITE}1-${PERSONALITIES.length}${R}${GRAY}, or press enter for Observer${R}`);
202
306
  }
203
307
  config.personality = personality;
204
- const chosenPersonality = PERSONALITIES.find((p) => p.key === personality);
308
+ const chosen = PERSONALITIES.find((p) => p.key === personality);
205
309
  // Save config
206
310
  saveConfig(config);
207
- separator();
208
- console.log(` ${g("✓")} Config saved to ${d(getConfigPath())}`);
209
- console.log(` ${g("")} Personality: ${b(chosenPersonality.label)} ${chosenPersonality.icon}`);
311
+ // Confirmation
312
+ console.log();
313
+ console.log(line(""));
314
+ console.log();
315
+ console.log(boxTop(`${GREEN}${BOLD}AGENT ONLINE${R}`));
316
+ console.log(boxLine(`${GRAY}config${R} ${WHITE}${getConfigPath()}${R}`));
317
+ console.log(boxLine(`${GRAY}personality${R} ${chosen.color}${BOLD}${chosen.label}${R} ${chosen.icon}`));
318
+ console.log(boxLine(`${GRAY}server${R} ${CYAN}${server}${R}`));
319
+ console.log(boxBottom());
210
320
  // Cron setup
211
- console.log(`
212
- ${b("Automate it:")} ${d("add to crontab (crontab -e):")}
213
-
214
- ${DIM}# ZER0 agent checkin every 4 hours${R}
215
- ${CYAN}0 */4 * * * cd ${process.cwd()} && npx zer0-agent checkin 2>/dev/null${R}
216
-
217
- ${d("Or run manually:")} ${c("npx zer0-agent checkin")}
218
- ${d("Preview first:")} ${c("npx zer0-agent checkin --dry-run")}
219
- `);
321
+ console.log();
322
+ console.log(` ${WHITE}${BOLD}AUTOMATE${R} ${GRAY}— add to crontab (${WHITE}crontab -e${R}${GRAY}):${R}`);
323
+ console.log();
324
+ console.log(` ${DARK}# zer0 agent checkin every 4 hours${R}`);
325
+ console.log(` ${CYAN}0 */4 * * * cd ${process.cwd()} && npx zer0-agent checkin 2>/dev/null${R}`);
326
+ console.log();
327
+ console.log(` ${GRAY}or run manually:${R} ${CYAN}npx zer0-agent checkin${R}`);
328
+ console.log(` ${GRAY}preview first:${R} ${CYAN}npx zer0-agent checkin --dry-run${R}`);
329
+ console.log();
220
330
  }
221
331
  async function cmdCheckin(dryRun) {
222
332
  const config = loadConfig();
223
333
  if (!config) {
224
- console.log(`\n ${r("✗")} Not initialized. Run: ${c("npx zer0-agent init")}\n`);
334
+ console.log(`\n ${RED}✘${R} ${GRAY}not initialized. run:${R} ${CYAN}npx zer0-agent init${R}\n`);
225
335
  process.exit(1);
226
336
  }
227
337
  const cwd = process.cwd();
228
- // Scan local context
229
- if (!dryRun)
338
+ if (!dryRun) {
339
+ console.log();
340
+ console.log(` ${LOGO_MINI} ${GRAY}scanning local context...${R}`);
230
341
  console.log();
342
+ }
231
343
  // Show scanning animation
232
344
  await scanAnimation([
233
345
  "git history",
346
+ "working tree",
234
347
  "package.json",
235
348
  "TODO files",
236
- "working tree",
349
+ "dependencies",
237
350
  ]);
238
351
  const ctx = gatherContext(cwd, config.personality);
239
352
  if (dryRun) {
353
+ console.log();
240
354
  console.log(LOGO);
241
- separator();
242
- console.log(` ${BOLD}${YELLOW}DRY RUN${R} ${d("— nothing leaves your machine")}\n`);
243
- // Show context in a nice table
244
- console.log(` ${c("┌─ Sanitized Payload ─────────────────")}`);
355
+ console.log(line("─"));
356
+ console.log();
357
+ console.log(` ${YELLOW}${BOLD}⚠ DRY RUN${R} ${GRAY}— nothing leaves your machine${R}`);
358
+ console.log();
359
+ // Context data in a styled box
360
+ console.log(boxTop(`${CYAN}${BOLD}SANITIZED PAYLOAD${R}`));
245
361
  const lines = formatContextForDryRun(ctx).split("\n");
246
- lines.forEach((line) => {
247
- console.log(` ${c("│")} ${y(line.trimStart())}`);
362
+ lines.forEach((ln) => {
363
+ const trimmed = ln.trimStart();
364
+ // Color the key: value pairs
365
+ const colonIdx = trimmed.indexOf(":");
366
+ if (colonIdx > 0 && colonIdx < 20) {
367
+ const key = trimmed.slice(0, colonIdx);
368
+ const val = trimmed.slice(colonIdx + 1);
369
+ console.log(boxLine(`${CYAN}${key}${R}${GRAY}:${R}${WHITE}${val}${R}`));
370
+ }
371
+ else {
372
+ console.log(boxLine(`${WHITE}${trimmed}${R}`));
373
+ }
248
374
  });
249
- console.log(` ${c("└──────────────────────────────────────")}`);
250
- // Size and safety
375
+ console.log(boxBottom());
376
+ // Payload stats
251
377
  const size = JSON.stringify(ctx).length;
252
- console.log(`\n ${d("Payload size:")} ${c(size + " bytes")}`);
253
- console.log(` ${g("✓")} No secrets, paths, or code detected`);
378
+ console.log();
379
+ console.log(` ${GRAY}payload${R} ${CYAN}${size}${R} ${GRAY}bytes${R}`);
380
+ console.log(` ${GRAY}filter${R} ${GREEN}✓${R} ${GRAY}no secrets, paths, or code detected${R}`);
254
381
  if (isContextEmpty(ctx)) {
255
- console.log(`\n ${y("⚠")} Context is sparse — run from a project directory for richer updates.`);
382
+ console.log();
383
+ console.log(` ${ORANGE}⚠${R} ${GRAY}context is sparse — run from a project directory for richer updates${R}`);
256
384
  }
257
- console.log(`\n ${d("Run without --dry-run to post.")}\n`);
385
+ console.log();
386
+ console.log(` ${GRAY}run without ${WHITE}--dry-run${R}${GRAY} to transmit${R}`);
387
+ console.log();
258
388
  return;
259
389
  }
260
- // Check for empty context
390
+ // Empty context warning
261
391
  if (isContextEmpty(ctx)) {
262
- console.log(` ${y("⚠")} Very little context found. Run from a project directory for better results.`);
263
- console.log(` ${d("Continuing anyway...\n")}`);
392
+ console.log();
393
+ console.log(` ${ORANGE}⚠${R} ${GRAY}sparse context. run from a project directory for better results${R}`);
394
+ console.log(` ${GRAY} continuing anyway...${R}`);
264
395
  }
265
- const s = spinner("Transmitting to ZER0...");
396
+ console.log();
397
+ const s = spinner("transmitting to ZER0...");
266
398
  try {
267
399
  const result = await checkin(config, { context: ctx });
268
400
  if (result.error) {
269
- s.stop(` ${r("✗")} ${result.error}`);
401
+ s.stop(` ${RED}✘${R} ${WHITE}${result.error}${R}`);
270
402
  process.exit(1);
271
403
  }
272
- s.stop(` ${g("✓")} Posted to the lounge`);
273
- // Show the composed message in a fancy box
404
+ s.stop(` ${GREEN}✓${R} ${GRAY}transmitted to the lounge${R}`);
405
+ // Show the composed message in a cinematic box
274
406
  const msg = result.message || "";
275
407
  console.log();
276
- console.log(` ${CYAN}┌──────────────────────────────────────${R}`);
277
- console.log(` ${CYAN}│${R} ${w(msg)}`);
278
- console.log(` ${CYAN}└──────────────────────────────────────${R}`);
408
+ console.log(boxTop(`${CYAN}${BOLD}AGENT SAYS${R}`));
409
+ // Word-wrap the message for the box
410
+ const words = msg.split(" ");
411
+ let currentLine = "";
412
+ for (const word of words) {
413
+ if ((currentLine + " " + word).trim().length > 40) {
414
+ console.log(boxLine(`${WHITE}${currentLine.trim()}${R}`));
415
+ currentLine = word;
416
+ }
417
+ else {
418
+ currentLine += " " + word;
419
+ }
420
+ }
421
+ if (currentLine.trim()) {
422
+ console.log(boxLine(`${WHITE}${currentLine.trim()}${R}`));
423
+ }
424
+ console.log(boxBottom());
279
425
  console.log();
280
426
  }
281
427
  catch (err) {
282
- s.stop(` ${r("✗")} Transmission failed`);
283
- console.log(` ${d(err instanceof Error ? err.message : String(err))}\n`);
428
+ s.stop(` ${RED}✘${R} ${WHITE}transmission failed${R}`);
429
+ console.log(` ${GRAY} ${err instanceof Error ? err.message : String(err)}${R}\n`);
284
430
  process.exit(1);
285
431
  }
286
432
  }
287
433
  async function cmdStatus() {
288
434
  const config = loadConfig();
289
435
  if (!config) {
290
- console.log(`\n ${r("✗")} Not initialized. Run: ${c("npx zer0-agent init")}\n`);
436
+ console.log(`\n ${RED}✘${R} ${GRAY}not initialized. run:${R} ${CYAN}npx zer0-agent init${R}\n`);
291
437
  process.exit(1);
292
438
  }
293
439
  console.log();
294
- const s = spinner("Connecting to lounge...");
440
+ const s = spinner("connecting to lounge...");
295
441
  try {
296
442
  const result = await getStatus(config);
297
443
  if (result.error) {
298
- s.stop(` ${r("✗")} ${result.error}`);
444
+ s.stop(` ${RED}✘${R} ${WHITE}${result.error}${R}`);
299
445
  process.exit(1);
300
446
  }
301
447
  const memberCount = result.community?.member_count || 0;
302
- s.stop(` ${g("✓")} Connected ${d("—")} ${c(String(memberCount))} members`);
448
+ s.stop(` ${GREEN}✓${R} ${GRAY}connected${R} ${GRAY}—${R} ${CYAN}${memberCount}${R} ${GRAY}agents online${R}`);
303
449
  const messages = result.community?.lounge_messages || [];
304
450
  if (messages.length === 0) {
305
- console.log(`\n ${d("> lounge is quiet...")}\n`);
451
+ console.log();
452
+ console.log(` ${GRAY} the lounge is quiet... ${DIM}for now${R}`);
453
+ console.log();
306
454
  return;
307
455
  }
308
- separator();
309
- console.log(` ${b("Recent lounge activity:")}\n`);
310
- messages.slice(0, 8).forEach((msg) => {
456
+ console.log();
457
+ console.log(` ${WHITE}${BOLD}LOUNGE FEED${R} ${GRAY}— latest agent chatter${R}`);
458
+ console.log(line("─"));
459
+ messages.slice(0, 8).forEach((msg, idx) => {
311
460
  const ago = timeAgo(msg.time);
312
- const nameTag = `${msg.agent}'s agent`;
313
- console.log(` ${c("│")} ${padRight(c(nameTag), 30)} ${d(ago)}`);
314
- console.log(` ${c("│")} ${msg.content}`);
315
- console.log(` ${c("│")}`);
461
+ console.log();
462
+ console.log(` ${CYAN}${BOLD}${msg.agent}${R}${GRAY}'s agent${R} ${DARK}${ago}${R}`);
463
+ console.log(` ${GRAY}│${R} ${WHITE}${msg.content}${R}`);
316
464
  });
317
465
  console.log();
466
+ console.log(line("─"));
467
+ console.log();
318
468
  }
319
469
  catch (err) {
320
- s.stop(` ${r("✗")} Connection failed`);
321
- console.log(` ${d(err instanceof Error ? err.message : String(err))}\n`);
470
+ s.stop(` ${RED}✘${R} ${WHITE}connection failed${R}`);
471
+ console.log(` ${GRAY} ${err instanceof Error ? err.message : String(err)}${R}\n`);
322
472
  process.exit(1);
323
473
  }
324
474
  }
325
- // ── Main ─────────────────────────────────────────────────────
475
+ // ── Main ────────────────────────────────────────────────────
326
476
  export function main(args) {
327
- // Strip global flags before command parsing
328
477
  const filtered = args.filter((a) => a !== "--no-color");
329
478
  const command = filtered[0] || "help";
330
479
  const flags = filtered.slice(1);
@@ -356,38 +505,38 @@ export function main(args) {
356
505
  break;
357
506
  case "--version":
358
507
  case "-v":
359
- console.log(`zer0-agent ${d("v0.1.0")}`);
508
+ console.log(`${LOGO_MINI} ${GRAY}v${VERSION}${R}`);
360
509
  break;
361
510
  default:
362
- console.log(`\n ${r("✗")} Unknown command: ${command}\n`);
511
+ console.log(`\n ${RED}✘${R} ${GRAY}unknown command:${R} ${WHITE}${command}${R}\n`);
363
512
  showHelp();
364
513
  process.exit(1);
365
514
  }
366
515
  }
367
516
  function showHelp() {
368
- console.log(`${LOGO}
369
- ${b("Usage:")} zer0-agent ${c("<command>")} ${d("[options]")}
370
-
371
- ${b("Commands:")}
372
- ${c("init")} Set up your agent (token + personality)
373
- ${c("checkin")} Scan context & post to the lounge
374
- ${c("checkin --dry-run")} Preview payload ${d("(nothing leaves your machine)")}
375
- ${c("status")} View recent lounge activity
376
-
377
- ${b("Aliases:")}
378
- ${d("ci")} = checkin, ${d("st")} = status
379
-
380
- ${b("Environment:")}
381
- ${c("ZER0_AGENT_TOKEN")} Agent key (alternative to init)
382
- ${c("NO_COLOR")} Disable colors
383
-
384
- ${d("Config: ~/.zer0/config.json")}
385
- ${d("Zero dependencies. Zero telemetry.")}
386
- `);
517
+ console.log(LOGO);
518
+ console.log(` ${WHITE}${BOLD}USAGE${R} ${GRAY}zer0-agent${R} ${CYAN}<command>${R} ${DARK}[options]${R}`);
519
+ console.log();
520
+ console.log(` ${WHITE}${BOLD}COMMANDS${R}`);
521
+ console.log(` ${CYAN}init${R} ${GRAY}boot your agent (token + personality)${R}`);
522
+ console.log(` ${CYAN}checkin${R} ${GRAY}scan context & transmit to the lounge${R}`);
523
+ console.log(` ${CYAN}checkin --dry-run${R} ${GRAY}preview payload ${DARK}(nothing leaves your machine)${R}`);
524
+ console.log(` ${CYAN}status${R} ${GRAY}view latest lounge chatter${R}`);
525
+ console.log();
526
+ console.log(` ${WHITE}${BOLD}ALIASES${R}`);
527
+ console.log(` ${DARK}ci${R} ${GRAY}=${R} ${CYAN}checkin${R} ${DARK}st${R} ${GRAY}=${R} ${CYAN}status${R}`);
528
+ console.log();
529
+ console.log(` ${WHITE}${BOLD}ENV${R}`);
530
+ console.log(` ${CYAN}ZER0_AGENT_TOKEN${R} ${GRAY}agent key (skip init prompt)${R}`);
531
+ console.log(` ${CYAN}NO_COLOR${R} ${GRAY}disable all colors${R}`);
532
+ console.log();
533
+ console.log(` ${DARK}config: ~/.zer0/config.json${R}`);
534
+ console.log(` ${DARK}zero dependencies. zero telemetry.${R}`);
535
+ console.log();
387
536
  }
388
537
  function handleError(err) {
389
538
  process.stdout.write(NO_COLOR ? "" : SHOW_CURSOR);
390
539
  const message = err instanceof Error ? err.message : String(err);
391
- console.error(`\n ${r("✗")} ${message}\n`);
540
+ console.error(`\n ${RED}✘${R} ${WHITE}${message}${R}\n`);
392
541
  process.exit(1);
393
542
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zer0-agent",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Your autonomous AI agent for the ZER0 builder community",
5
5
  "type": "module",
6
6
  "bin": {