0agent 1.0.54 → 1.0.56

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.
package/bin/chat.js CHANGED
@@ -1192,7 +1192,14 @@ process.stdin.on('keypress', (_char, key) => {
1192
1192
  sessionId = null;
1193
1193
  streaming = false;
1194
1194
  streamLineCount = 0;
1195
- messageQueue.length = 0; // also clear queue — fresh start
1195
+ messageQueue.length = 0;
1196
+
1197
+ // Kill any OS-level processes spawned by GUI/shell capabilities
1198
+ // (python3 GUI scripts, bash subprocesses) so nothing keeps running
1199
+ import('node:child_process').then(({ execSync: _exec }) => {
1200
+ try { _exec('pkill -f "0agent_gui_" 2>/dev/null; pkill -f "0agent-bg-" 2>/dev/null; true', { stdio: 'ignore' }); } catch {}
1201
+ }).catch(() => {});
1202
+
1196
1203
  res();
1197
1204
  rl.prompt();
1198
1205
  }
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * preuninstall — runs automatically before `npm uninstall -g 0agent`
4
+ *
5
+ * Kills the daemon and ALL processes spawned by 0agent so nothing
6
+ * keeps running (e.g. opening Brave) after the package is removed.
7
+ */
8
+
9
+ import { execSync } from 'node:child_process';
10
+ import { existsSync, readFileSync, unlinkSync } from 'node:fs';
11
+ import { resolve } from 'node:path';
12
+ import { homedir } from 'node:os';
13
+
14
+ const AGENT_DIR = resolve(homedir(), '.0agent');
15
+ const PID_PATH = resolve(AGENT_DIR, 'daemon.pid');
16
+
17
+ function run(cmd) {
18
+ try { execSync(cmd, { stdio: 'ignore', timeout: 5000 }); } catch {}
19
+ }
20
+
21
+ process.stdout.write(' Stopping 0agent daemon and background processes…\n');
22
+
23
+ // 1. Kill daemon by PID file
24
+ if (existsSync(PID_PATH)) {
25
+ try {
26
+ const pid = parseInt(readFileSync(PID_PATH, 'utf8').trim(), 10);
27
+ if (!isNaN(pid)) process.kill(pid, 'SIGTERM');
28
+ } catch {}
29
+ try { unlinkSync(PID_PATH); } catch {}
30
+ }
31
+
32
+ // 2. Kill by process name (catches daemons started by chat.js or other means)
33
+ run('pkill -f "daemon.mjs" 2>/dev/null; true');
34
+
35
+ // 3. Kill any GUI Python scripts still running
36
+ run('pkill -f "0agent_gui_" 2>/dev/null; true');
37
+ run('pkill -f "0agent-bg-" 2>/dev/null; true');
38
+
39
+ // 4. Free port 4200 (last resort)
40
+ run('lsof -ti:4200 | xargs kill -9 2>/dev/null; true');
41
+
42
+ // 5. Remove any launchd plists that 0agent may have registered
43
+ // (prevents apps from being re-launched on login)
44
+ const launchAgentsDir = resolve(homedir(), 'Library', 'LaunchAgents');
45
+ if (existsSync(launchAgentsDir)) {
46
+ try {
47
+ const { readdirSync } = await import('node:fs');
48
+ for (const f of readdirSync(launchAgentsDir)) {
49
+ if (f.includes('0agent') || f.includes('zeroagent')) {
50
+ const plistPath = resolve(launchAgentsDir, f);
51
+ run(`launchctl unload "${plistPath}" 2>/dev/null; true`);
52
+ try { unlinkSync(plistPath); } catch {}
53
+ process.stdout.write(` Removed launchd plist: ${f}\n`);
54
+ }
55
+ }
56
+ } catch {}
57
+ }
58
+
59
+ // 6. Remove 0agent crontab entries (if any were ever added)
60
+ run('crontab -l 2>/dev/null | grep -v "0agent" | crontab - 2>/dev/null; true');
61
+
62
+ process.stdout.write(' ✓ 0agent stopped and cleaned up\n');
package/dist/daemon.mjs CHANGED
@@ -2348,7 +2348,7 @@ var ShellCapability;
2348
2348
  var init_ShellCapability = __esm({
2349
2349
  "packages/daemon/src/capabilities/ShellCapability.ts"() {
2350
2350
  "use strict";
2351
- ShellCapability = class {
2351
+ ShellCapability = class _ShellCapability {
2352
2352
  name = "shell_exec";
2353
2353
  description = "Execute shell commands in the working directory.";
2354
2354
  toolDefinition = {
@@ -2363,10 +2363,24 @@ var init_ShellCapability = __esm({
2363
2363
  required: ["command"]
2364
2364
  }
2365
2365
  };
2366
- async execute(input, cwd) {
2366
+ // Commands that create persistent OS-level scheduled tasks.
2367
+ // These must never run autonomously — they survive uninstall and can
2368
+ // re-open apps (e.g. Brave) on every login or on a timer.
2369
+ static PERSISTENT_TASK_PATTERN = /crontab\s+-[eilr]|launchctl\s+load|launchctl\s+bootstrap|systemctl\s+enable|at\s+\d|make\s+login\s+item|LaunchAgents|LaunchDaemons|loginitems/i;
2370
+ async execute(input, cwd, signal) {
2367
2371
  let command = String(input.command ?? "");
2368
2372
  const timeout = Number(input.timeout_ms ?? 3e4);
2369
2373
  const start = Date.now();
2374
+ if (_ShellCapability.PERSISTENT_TASK_PATTERN.test(command)) {
2375
+ return {
2376
+ success: false,
2377
+ output: `Blocked: "${command.slice(0, 80)}" creates a persistent scheduled task (cron/launchd/login item). These survive uninstall and can keep launching apps autonomously. Ask the user explicitly before scheduling any persistent OS task.`,
2378
+ duration_ms: 0
2379
+ };
2380
+ }
2381
+ if (signal?.aborted) {
2382
+ return { success: false, output: "Cancelled.", duration_ms: 0 };
2383
+ }
2370
2384
  if (/&\s*$/.test(command) && !/[>|].*&\s*$/.test(command)) {
2371
2385
  const logFile = `/tmp/0agent-bg-${Date.now()}.log`;
2372
2386
  command = command.replace(/\s*&\s*$/, ` > ${logFile} 2>&1 &`);
@@ -2374,30 +2388,43 @@ var init_ShellCapability = __esm({
2374
2388
  return new Promise((resolve_) => {
2375
2389
  const chunks = [];
2376
2390
  let settled = false;
2377
- const done = (code, signal) => {
2391
+ const done = (code, killedBySignal) => {
2378
2392
  if (settled) return;
2379
2393
  settled = true;
2394
+ signal?.removeEventListener("abort", onAbort);
2380
2395
  clearTimeout(timer);
2381
2396
  const output = chunks.join("").trim();
2382
- const success = code === 0 || code === null && !!signal;
2397
+ const success = code === 0 || code === null && !!killedBySignal;
2383
2398
  resolve_({
2384
2399
  success,
2385
- output: output || (success ? "(no output)" : `exit ${code ?? signal}`),
2400
+ output: output || (success ? "(no output)" : `exit ${code ?? killedBySignal}`),
2386
2401
  duration_ms: Date.now() - start,
2387
- ...!success && { error: `exit ${code ?? signal}` }
2402
+ ...!success && { error: `exit ${code ?? killedBySignal}` }
2388
2403
  });
2389
2404
  };
2390
2405
  const proc = spawn2("bash", ["-c", command], {
2391
2406
  cwd,
2392
2407
  env: { ...process.env, TERM: "dumb" }
2393
- // DO NOT set `timeout` here — we manage it manually via timer
2394
- // so we can resolve on `exit` rather than waiting for `close`
2395
2408
  });
2409
+ const onAbort = () => {
2410
+ try {
2411
+ proc.kill("SIGKILL");
2412
+ } catch {
2413
+ }
2414
+ if (!settled) {
2415
+ settled = true;
2416
+ signal?.removeEventListener("abort", onAbort);
2417
+ clearTimeout(timer);
2418
+ resolve_({ success: false, output: chunks.join("").trim() || "Cancelled.", duration_ms: Date.now() - start });
2419
+ }
2420
+ };
2421
+ signal?.addEventListener("abort", onAbort, { once: true });
2396
2422
  proc.stdout.on("data", (d) => chunks.push(d.toString()));
2397
2423
  proc.stderr.on("data", (d) => chunks.push(d.toString()));
2398
2424
  proc.on("exit", (code) => done(code));
2399
2425
  proc.on("error", (err) => {
2400
2426
  settled = true;
2427
+ signal?.removeEventListener("abort", onAbort);
2401
2428
  clearTimeout(timer);
2402
2429
  resolve_({ success: false, output: err.message, error: err.message, duration_ms: Date.now() - start });
2403
2430
  });
@@ -2408,6 +2435,7 @@ var init_ShellCapability = __esm({
2408
2435
  } catch {
2409
2436
  }
2410
2437
  settled = true;
2438
+ signal?.removeEventListener("abort", onAbort);
2411
2439
  const output = chunks.join("").trim();
2412
2440
  resolve_({
2413
2441
  success: false,
@@ -2558,7 +2586,7 @@ var init_MemoryCapability = __esm({
2558
2586
  });
2559
2587
 
2560
2588
  // packages/daemon/src/capabilities/GUICapability.ts
2561
- import { spawnSync as spawnSync4 } from "node:child_process";
2589
+ import { spawn as spawn3, spawnSync as spawnSync4 } from "node:child_process";
2562
2590
  import { writeFileSync as writeFileSync2, unlinkSync } from "node:fs";
2563
2591
  import { resolve as resolve3 } from "node:path";
2564
2592
  import { tmpdir, platform as platform2 } from "node:os";
@@ -2571,7 +2599,7 @@ var init_GUICapability = __esm({
2571
2599
  description = "Automate desktop GUI \u2014 click, type, screenshot, hotkeys, find text on screen.";
2572
2600
  toolDefinition = {
2573
2601
  name: "gui_automation",
2574
- description: 'Automate desktop GUI interactions. Take screenshots to see the current screen state, click on buttons/links/fields, type text, press keyboard shortcuts, scroll, open apps. IMPORTANT: Limit screenshots to at most 3 per task \u2014 avoid re-screenshotting if you already know the layout. Prefer targeted actions (click, find_and_click, hotkey) over repeated screenshots. Use get_cursor_pos to check cursor position without a full screenshot. To open a website, ALWAYS use action="open_url" \u2014 never open_app + new tab, which creates duplicate windows.',
2602
+ description: "Desktop GUI automation \u2014 ONLY use for tasks that explicitly require controlling the screen. DO NOT use for coding, research, file edits, or any task that does not need the desktop UI. Actions: click, type, hotkey, scroll, find_and_click, open_url, open_app. screenshot: use sparingly \u2014 only when you cannot proceed without seeing the current screen. Max 2 per task. To open a website use open_url (reuses existing browser tab, never opens duplicate windows).",
2575
2603
  input_schema: {
2576
2604
  type: "object",
2577
2605
  properties: {
@@ -2595,22 +2623,60 @@ var init_GUICapability = __esm({
2595
2623
  required: ["action"]
2596
2624
  }
2597
2625
  };
2598
- async execute(input, _cwd) {
2626
+ async execute(input, _cwd, signal) {
2599
2627
  const action = String(input.action ?? "").toLowerCase().trim();
2600
2628
  const start = Date.now();
2601
2629
  const script = this._buildScript(action, input);
2602
2630
  if (!script) {
2603
2631
  return { success: false, output: `Unknown GUI action: "${action}". Valid: screenshot, click, double_click, right_click, move, type, hotkey, scroll, drag, find_and_click, get_screen_size, get_cursor_pos, open_url, open_app`, duration_ms: 0 };
2604
2632
  }
2633
+ if (signal?.aborted) {
2634
+ return { success: false, output: "Cancelled.", duration_ms: 0 };
2635
+ }
2605
2636
  const tmpFile = resolve3(tmpdir(), `0agent_gui_${Date.now()}.py`);
2606
2637
  writeFileSync2(tmpFile, script, "utf8");
2607
- const result = spawnSync4("python3", [tmpFile], { timeout: 3e4, encoding: "utf8" });
2638
+ const runPy = (file) => new Promise((res) => {
2639
+ const proc = spawn3("python3", [file], { env: process.env });
2640
+ const out = [];
2641
+ const err = [];
2642
+ let settled = false;
2643
+ const finish = (code) => {
2644
+ if (settled) return;
2645
+ settled = true;
2646
+ signal?.removeEventListener("abort", onAbort);
2647
+ clearTimeout(timer);
2648
+ res({ stdout: out.join(""), stderr: err.join(""), code });
2649
+ };
2650
+ const onAbort = () => {
2651
+ try {
2652
+ proc.kill("SIGKILL");
2653
+ } catch {
2654
+ }
2655
+ finish(null);
2656
+ };
2657
+ signal?.addEventListener("abort", onAbort, { once: true });
2658
+ proc.stdout.on("data", (d) => out.push(d.toString()));
2659
+ proc.stderr.on("data", (d) => err.push(d.toString()));
2660
+ proc.on("exit", finish);
2661
+ proc.on("error", () => finish(-1));
2662
+ const timer = setTimeout(() => {
2663
+ try {
2664
+ proc.kill("SIGKILL");
2665
+ } catch {
2666
+ }
2667
+ finish(null);
2668
+ }, 3e4);
2669
+ });
2670
+ let result = await runPy(tmpFile);
2608
2671
  try {
2609
2672
  unlinkSync(tmpFile);
2610
2673
  } catch {
2611
2674
  }
2612
- if (result.status !== 0) {
2613
- const err = String(result.stderr ?? "").trim();
2675
+ if (signal?.aborted) {
2676
+ return { success: false, output: "Cancelled.", duration_ms: Date.now() - start };
2677
+ }
2678
+ if (result.code !== 0 && result.code !== null) {
2679
+ const err = result.stderr.trim();
2614
2680
  if (err.includes("No module named") || err.includes("ModuleNotFoundError")) {
2615
2681
  const missing = err.includes("pyautogui") ? "pyautogui pillow pytesseract" : err.includes("PIL") ? "pillow" : err.includes("tesseract") ? "pytesseract" : "pyautogui pillow";
2616
2682
  const install = spawnSync4("pip3", ["install", ...missing.split(" "), "-q"], {
@@ -2620,17 +2686,15 @@ var init_GUICapability = __esm({
2620
2686
  if (install.status !== 0) {
2621
2687
  return { success: false, output: `Auto-install failed: ${install.stderr?.slice(0, 200)}. Run: pip3 install ${missing}`, duration_ms: Date.now() - start };
2622
2688
  }
2623
- const retry = spawnSync4("python3", [tmpFile], { timeout: 3e4, encoding: "utf8" });
2624
2689
  writeFileSync2(tmpFile, script, "utf8");
2625
- const retry2 = spawnSync4("python3", [tmpFile], { timeout: 3e4, encoding: "utf8" });
2690
+ result = await runPy(tmpFile);
2626
2691
  try {
2627
2692
  unlinkSync(tmpFile);
2628
2693
  } catch {
2629
2694
  }
2630
- if (retry2.status === 0) {
2631
- return { success: true, output: retry2.stdout.trim() || "Done", duration_ms: Date.now() - start };
2632
- }
2633
- return { success: false, output: retry2.stderr?.trim() || "Unknown error after install", duration_ms: Date.now() - start };
2695
+ if (signal?.aborted) return { success: false, output: "Cancelled.", duration_ms: Date.now() - start };
2696
+ if (result.code === 0) return { success: true, output: result.stdout.trim() || "Done", duration_ms: Date.now() - start };
2697
+ return { success: false, output: result.stderr.trim() || "Unknown error after install", duration_ms: Date.now() - start };
2634
2698
  }
2635
2699
  if (err.includes("accessibility") || err.includes("permission") || err.includes("AXIsProcessTrusted")) {
2636
2700
  return {
@@ -2830,12 +2894,41 @@ chrome_running = subprocess.run(['pgrep', '-x', 'Google Chrome'], capture_output
2830
2894
  firefox_running = subprocess.run(['pgrep', '-x', 'firefox'], capture_output=True).returncode == 0
2831
2895
  safari_running = subprocess.run(['pgrep', '-x', 'Safari'], capture_output=True).returncode == 0
2832
2896
 
2897
+ import urllib.parse
2898
+ domain = urllib.parse.urlparse(url).netloc
2899
+
2833
2900
  if chrome_running:
2834
- # Open in existing Chrome window \u2014 no new window created
2835
- script = f'tell application "Google Chrome" to open location "{url}"'
2836
- subprocess.run(['osascript', '-e', script])
2837
- subprocess.run(['osascript', '-e', 'tell application "Google Chrome" to activate'])
2838
- print(f"Navigated Chrome to: {url}")
2901
+ # Check if URL domain is already open in an existing tab \u2014 switch to it instead of opening new tab
2902
+ check_script = f"""
2903
+ tell application "Google Chrome"
2904
+ set foundTab to false
2905
+ repeat with w in every window
2906
+ set tabIdx to 1
2907
+ repeat with t in every tab of w
2908
+ if URL of t contains "{domain}" then
2909
+ set active tab index of w to tabIdx
2910
+ set index of w to 1
2911
+ set foundTab to true
2912
+ exit repeat
2913
+ end if
2914
+ set tabIdx to tabIdx + 1
2915
+ end repeat
2916
+ if foundTab then exit repeat
2917
+ end repeat
2918
+ if foundTab then
2919
+ activate
2920
+ return "switched"
2921
+ else
2922
+ tell front window to make new tab with properties {{URL:"{url}"}}
2923
+ activate
2924
+ return "new-tab"
2925
+ end if
2926
+ end tell"""
2927
+ r = subprocess.run(['osascript', '-e', check_script], capture_output=True, text=True)
2928
+ if r.stdout.strip() == "switched":
2929
+ print(f"Switched to existing Chrome tab: {url}")
2930
+ else:
2931
+ print(f"Opened new Chrome tab: {url}")
2839
2932
  elif firefox_running:
2840
2933
  script = f'tell application "Firefox" to open location "{url}"'
2841
2934
  subprocess.run(['osascript', '-e', script])
@@ -3038,13 +3131,13 @@ var init_CapabilityRegistry = __esm({
3038
3131
  getToolDefinitions() {
3039
3132
  return [...this.capabilities.values()].map((c) => c.toolDefinition);
3040
3133
  }
3041
- async execute(toolName, input, cwd) {
3134
+ async execute(toolName, input, cwd, signal) {
3042
3135
  const cap = this.capabilities.get(toolName);
3043
3136
  if (!cap) {
3044
3137
  return { success: false, output: `Unknown capability: ${toolName}`, duration_ms: 0 };
3045
3138
  }
3046
3139
  try {
3047
- return await cap.execute(input, cwd);
3140
+ return await cap.execute(input, cwd, signal);
3048
3141
  } catch (err) {
3049
3142
  return {
3050
3143
  success: false,
@@ -3074,7 +3167,7 @@ var init_capabilities = __esm({
3074
3167
  });
3075
3168
 
3076
3169
  // packages/daemon/src/AgentExecutor.ts
3077
- import { spawn as spawn3 } from "node:child_process";
3170
+ import { spawn as spawn4 } from "node:child_process";
3078
3171
  import { writeFileSync as writeFileSync3, readFileSync as readFileSync3, readdirSync as readdirSync2, mkdirSync as mkdirSync2, existsSync as existsSync3 } from "node:fs";
3079
3172
  import { resolve as resolve4, dirname as dirname2, relative } from "node:path";
3080
3173
  var SELF_MOD_PATTERN, AgentExecutor;
@@ -3172,7 +3265,7 @@ var init_AgentExecutor = __esm({
3172
3265
  this.onStep(`\u25B6 ${tc.name}(${this.summariseInput(tc.name, tc.input)})`);
3173
3266
  let result;
3174
3267
  try {
3175
- const capResult = await this.registry.execute(tc.name, tc.input, this.cwd);
3268
+ const capResult = await this.registry.execute(tc.name, tc.input, this.cwd, signal);
3176
3269
  result = capResult.output;
3177
3270
  if (capResult.fallback_used) {
3178
3271
  this.onStep(` (used fallback: ${capResult.fallback_used})`);
@@ -3236,7 +3329,7 @@ var init_AgentExecutor = __esm({
3236
3329
  shellExec(command, timeoutMs) {
3237
3330
  return new Promise((resolve16) => {
3238
3331
  const chunks = [];
3239
- const proc = spawn3("bash", ["-c", command], {
3332
+ const proc = spawn4("bash", ["-c", command], {
3240
3333
  cwd: this.cwd,
3241
3334
  env: { ...process.env, TERM: "dumb" },
3242
3335
  timeout: timeoutMs
@@ -3404,12 +3497,14 @@ content = element.text if element else page.get_all_text()` : `content = page.ge
3404
3497
  `- Use relative paths from the working directory`,
3405
3498
  `- Be concise in your final response: state what was done and where to find it`,
3406
3499
  ``,
3407
- `GUI Automation (gui_automation tool):`,
3408
- `- ALWAYS call gui_automation({action:"screenshot"}) first to see what is on screen`,
3409
- `- Use the OCR output to find element coordinates before clicking`,
3410
- `- After clicking or typing, take another screenshot to confirm the result`,
3500
+ `GUI Automation (gui_automation tool) \u2014 ONLY use when the task explicitly requires controlling the desktop UI:`,
3501
+ `- DO NOT take screenshots for general tasks, coding, research, or anything that doesn't need the screen`,
3502
+ `- Only screenshot when you genuinely cannot proceed without seeing the current screen state`,
3503
+ `- Prefer find_and_click, hotkey, open_url, and type over repeated screenshots`,
3504
+ `- Max 2 screenshots per task \u2014 if you've already seen the screen, act on that knowledge`,
3411
3505
  `- Use find_and_click to click on text by name rather than guessing coordinates`,
3412
3506
  `- Use hotkey for keyboard shortcuts: "cmd+c", "ctrl+v", "alt+tab", "cmd+space"`,
3507
+ `- To open a website: use open_url \u2014 it reuses the existing browser tab`,
3413
3508
  ...hasMemory ? [
3414
3509
  ``,
3415
3510
  `Memory (CRITICAL \u2014 write EVERYTHING you learn):`,
@@ -3555,7 +3650,7 @@ var init_ExecutionVerifier = __esm({
3555
3650
  import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as existsSync6 } from "node:fs";
3556
3651
  import { resolve as resolve6, dirname as dirname3 } from "node:path";
3557
3652
  import { fileURLToPath } from "node:url";
3558
- import { execSync as execSync4, spawn as spawn4 } from "node:child_process";
3653
+ import { execSync as execSync4, spawn as spawn5 } from "node:child_process";
3559
3654
  function isRuntimeBug(error) {
3560
3655
  if (TASK_FAILURE_PATTERNS.some((p) => p.test(error))) return false;
3561
3656
  return RUNTIME_BUG_PATTERNS.some((p) => p.test(error));
@@ -3790,7 +3885,7 @@ Rules:
3790
3885
  restartDaemon() {
3791
3886
  const bundlePath = resolve6(this.projectRoot, "dist", "daemon.mjs");
3792
3887
  if (existsSync6(bundlePath)) {
3793
- const child = spawn4(process.execPath, [bundlePath], {
3888
+ const child = spawn5(process.execPath, [bundlePath], {
3794
3889
  detached: true,
3795
3890
  stdio: "ignore",
3796
3891
  env: process.env
@@ -7293,7 +7388,7 @@ git checkout <commit> graph/ # restore graph files
7293
7388
  };
7294
7389
 
7295
7390
  // packages/daemon/src/CodespaceManager.ts
7296
- import { execSync as execSync5, spawn as spawn5 } from "node:child_process";
7391
+ import { execSync as execSync5, spawn as spawn6 } from "node:child_process";
7297
7392
  var BROWSER_PORT_REMOTE = 3e3;
7298
7393
  var BROWSER_PORT_LOCAL = 3001;
7299
7394
  var DISPLAY_NAME = "0agent-browser";
@@ -7388,7 +7483,7 @@ var CodespaceManager = class {
7388
7483
  async openTunnel(name) {
7389
7484
  this.closeTunnel();
7390
7485
  console.log(`[Codespace] Opening tunnel port ${BROWSER_PORT_REMOTE} \u2192 localhost:${BROWSER_PORT_LOCAL}...`);
7391
- this.forwardProcess = spawn5(
7486
+ this.forwardProcess = spawn6(
7392
7487
  "gh",
7393
7488
  ["codespace", "ports", "forward", `${BROWSER_PORT_REMOTE}:${BROWSER_PORT_LOCAL}`, "--codespace", name],
7394
7489
  { stdio: ["ignore", "ignore", "ignore"] }
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "0agent",
3
- "version": "1.0.54",
3
+ "version": "1.0.56",
4
4
  "description": "A persistent, learning AI agent that runs on your machine. An agent that learns.",
5
5
  "private": false,
6
6
  "license": "Apache-2.0",
7
7
  "type": "module",
8
8
  "bin": {
9
- "0agent": "./bin/0agent.js",
10
- "0agent-chat": "./bin/chat.js"
9
+ "0agent": "bin/0agent.js",
10
+ "0agent-chat": "bin/chat.js"
11
11
  },
12
12
  "files": [
13
13
  "bin/",
@@ -21,6 +21,7 @@
21
21
  "test": "turbo run test",
22
22
  "lint": "turbo run lint",
23
23
  "postinstall": "node bin/postinstall.js",
24
+ "preuninstall": "node bin/preuninstall.js",
24
25
  "prepublishOnly": "pnpm build --filter='!@0agent/dashboard' --filter='!@0agent/core-native' && node scripts/bundle.mjs"
25
26
  },
26
27
  "dependencies": {
@@ -53,7 +54,7 @@
53
54
  ],
54
55
  "repository": {
55
56
  "type": "git",
56
- "url": "https://github.com/cadetmaze/0agentv1"
57
+ "url": "git+https://github.com/cadetmaze/0agentv1.git"
57
58
  },
58
59
  "homepage": "https://github.com/cadetmaze/0agentv1#readme",
59
60
  "packageManager": "pnpm@9.12.0"