openzoo 0.50.74 → 0.50.75

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/lib/botlog.js +25 -2
  2. package/package.json +1 -1
package/lib/botlog.js CHANGED
@@ -9,6 +9,9 @@
9
9
  * Default is QUIET: only milestones and problems. `--verbose` / OPENZOO_DEBUG=1
10
10
  * restores the firehose (it is still the right thing for debugging the wire).
11
11
  */
12
+ import fsSync from 'node:fs';
13
+ import osMod from 'node:os';
14
+ import pathMod from 'node:path';
12
15
  import { privateKeyToAccount } from 'viem/accounts';
13
16
 
14
17
  const NOISE = [
@@ -30,6 +33,8 @@ const NOISE = [
30
33
  ];
31
34
 
32
35
  const MILESTONE = [
36
+ /zoo POST :8402 model=/, // one line per turn: which bot asked which model
37
+ /<< zoo (200|4\d\d|5\d\d)/, // one line per turn: how it ended
33
38
  /mcp ready/,
34
39
  /mcp \S+ (mode=|FAIL|tools=\d+|re-attach|attached|appeared)/,
35
40
  /mcp \S+ To let bots drive your real Chrome/,
@@ -49,11 +54,29 @@ export function isBotMilestone(line) {
49
54
  return MILESTONE.some((re) => re.test(s));
50
55
  }
51
56
 
52
- export function makeBotLogger({ verbose = false, write = (m) => console.error(m) } = {}) {
57
+ /**
58
+ * Terminal gets milestones (or everything with verbose); the FULL stream is
59
+ * always appended to `file` so quiet mode never destroys evidence.
60
+ * Default file: ~/.openzoo/bot.log (truncated at start of each run).
61
+ */
62
+ export function makeBotLogger({ verbose = false, write = (m) => console.error(m), file = defaultBotLogPath(), fsMod = null } = {}) {
63
+ let fd = null;
64
+ if (file) {
65
+ try {
66
+ const fsx = fsMod || fsSync;
67
+ fsx.mkdirSync(pathMod.dirname(file), { recursive: true });
68
+ fd = fsx.openSync(file, 'w');
69
+ fsx.writeSync(fd, `# openzoo bot full log ${new Date().toISOString()}\n`);
70
+ } catch { fd = null; }
71
+ }
53
72
  return (m) => {
73
+ if (fd != null) { try { (fsMod || fsSync).writeSync(fd, `${new Date().toISOString()} ${m}\n`); } catch { /* disk full etc. */ } }
54
74
  if (verbose || isBotMilestone(m)) write(` backend: ${m}`);
55
75
  };
56
76
  }
77
+ export function defaultBotLogPath(home = osMod.homedir()) {
78
+ return pathMod.join(home, '.openzoo', 'bot.log');
79
+ }
57
80
 
58
81
  /**
59
82
  * The block a new user needs before anything else. `balances` is optional
@@ -86,7 +109,7 @@ export function payBannerLines({ solana, evm, balances = null, whop = 'https://w
86
109
  lines.push(`openzoo: CHROME attached to your real browser (${chromeMode}).`);
87
110
  }
88
111
  lines.push('openzoo: FIRST type in any bot: "set up Grok Ship for ~/path/to/repo" — or just give it work.');
89
- lines.push('openzoo: QUIET add --verbose to see every request the app makes.');
112
+ lines.push('openzoo: QUIET add --verbose to see every request the app makes; the full stream is always in ~/.openzoo/bot.log');
90
113
  return lines;
91
114
  }
92
115
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openzoo",
3
- "version": "0.50.74",
3
+ "version": "0.50.75",
4
4
  "description": "Local x402-paying proxy + MCP server for openzoo.fun — point any OpenAI-compatible harness (Cursor, Claude Code, aider, SDKs) at localhost and it pays per call from a local burner wallet. Solana and Base rails live; Robinhood experimental.",
5
5
  "license": "MIT",
6
6
  "type": "module",