@todoforai/edge 0.13.5 → 0.13.7

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/index.js +167 -23
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -48187,6 +48187,12 @@ class ApiClient {
48187
48187
  updateAgentSettings(agentId, agentSettingsId, updates) {
48188
48188
  return this.request("PUT", `/api/v1/agents/${agentId}/settings`, { agentSettingsId, updates });
48189
48189
  }
48190
+ getGlobalAgentSettings() {
48191
+ return this.request("GET", "/api/v1/agents/global");
48192
+ }
48193
+ updateGlobalAgentSettings(updates) {
48194
+ return this.request("PUT", "/api/v1/agents/global", updates);
48195
+ }
48190
48196
  setAgentEdgeMcpConfig(agentId, agentSettingsId, edgeId, mcpName, config) {
48191
48197
  return this.request("PUT", `/api/v1/agents/${agentId}/edge-mcp-config`, { agentSettingsId, edgeId, mcpName, config });
48192
48198
  }
@@ -48974,7 +48980,8 @@ var tool_catalog_default = {
48974
48980
  capabilities: "Create & manage TODOs, run workflows, API access",
48975
48981
  statusCmd: "todoai --help >/dev/null 2>&1",
48976
48982
  installCmd: "bun add -g @todoforai/cli",
48977
- versionCmd: "todoai --version 2>/dev/null | head -1"
48983
+ versionCmd: "todoai --version 2>/dev/null | head -1",
48984
+ preinstall: true
48978
48985
  },
48979
48986
  newman: {
48980
48987
  category: "testing",
@@ -48985,6 +48992,16 @@ var tool_catalog_default = {
48985
48992
  capabilities: "Run API test collections, CI/CD integration, HTML reports",
48986
48993
  versionCmd: "newman --version 2>/dev/null | head -1"
48987
48994
  },
48995
+ curl: {
48996
+ category: "networking",
48997
+ pkg: "curl",
48998
+ installer: "system",
48999
+ label: "curl",
49000
+ statusCmd: "curl --version >/dev/null 2>&1",
49001
+ capabilities: "HTTP/HTTPS/FTP client: GET/POST/PUT/DELETE, headers, auth, file upload/download, follow redirects, cookies, TLS.",
49002
+ versionCmd: "curl --version 2>/dev/null | head -1",
49003
+ preinstall: true
49004
+ },
48988
49005
  cloudflared: {
48989
49006
  category: "networking",
48990
49007
  pkg: "cloudflared",
@@ -49091,6 +49108,7 @@ var tool_catalog_default = {
49091
49108
  capabilities: "Spawn a TODO for AI sub-agent (FluidAgent) from the CLI; pipe stdin in, get an answer out",
49092
49109
  description: 'Run a sub-agent task from a shell block. Usage: `todoforai-subagent [-m model] [-s :preset|@file|text] [--tools read,grep,bash] "<question>"`. Pipe stdin to include input context. Presets: :review, :explore, :plan, :summarize. Auth via TODOFORAI_API_KEY (auto-injected by edge).',
49093
49110
  versionCmd: "todoforai-subagent --version 2>/dev/null | head -1",
49111
+ installCmd: "bun add -g @todoforai/subagent",
49094
49112
  preinstall: true
49095
49113
  },
49096
49114
  "todoforai-review": {
@@ -49101,6 +49119,7 @@ var tool_catalog_default = {
49101
49119
  capabilities: "Review a git diff with a sub-agent: assess goal, find issues, suggest simpler approaches",
49102
49120
  description: 'Capture `git diff` and ask a read-only sub-agent to review it. Usage: `todoforai-review [--repo <path>] [--against <ref>] "<goal>"`. Default diffs uncommitted changes vs HEAD. Wraps `todoforai-subagent --sysmsg :review --tools read,grep,bash`.',
49103
49121
  versionCmd: "todoforai-review --version 2>/dev/null | head -1",
49122
+ installCmd: "bun add -g @todoforai/review",
49104
49123
  preinstall: true
49105
49124
  },
49106
49125
  "todoforai-explore": {
@@ -49111,6 +49130,7 @@ var tool_catalog_default = {
49111
49130
  capabilities: "Explore a codebase with a sub-agent: map structure, find patterns, surface relevant files",
49112
49131
  description: 'Ask a read-only sub-agent to explore a codebase. Usage: `todoforai-explore [--repo <path>] "<question>"`. Sub-agent uses read/grep/bash to investigate and reports findings with file:line citations. Wraps `todoforai-subagent --sysmsg :explore`.',
49113
49132
  versionCmd: "todoforai-explore --version 2>/dev/null | head -1",
49133
+ installCmd: "bun add -g @todoforai/explore",
49114
49134
  preinstall: true
49115
49135
  },
49116
49136
  "todoforai-summary": {
@@ -49121,7 +49141,71 @@ var tool_catalog_default = {
49121
49141
  capabilities: "Summarize files or piped input via a sub-agent",
49122
49142
  description: 'Summarize file contents or stdin. Usage: `todoforai-summary [-f <file>]... [<files...>] [<focus>]` or `cat x | todoforai-summary "focus"`. Wraps `todoforai-subagent --sysmsg :summarize`.',
49123
49143
  versionCmd: "todoforai-summary --version 2>/dev/null | head -1",
49144
+ installCmd: "bun add -g @todoforai/summary",
49124
49145
  preinstall: true
49146
+ },
49147
+ ripgrep: {
49148
+ category: "development",
49149
+ pkg: "ripgrep",
49150
+ installer: "binary",
49151
+ label: "ripgrep (rg)",
49152
+ capabilities: "Fast recursive grep with regex, .gitignore-aware, parallel, unicode-correct",
49153
+ description: "Fast code/text search. Usage: `rg <pattern> [path]`, `-i` case-insensitive, `-l` files only, `-t <lang>` filter by language, `-g '<glob>'` filter by glob, `-C N` context. Prefer over `grep -r`.",
49154
+ versionCmd: "rg --version 2>/dev/null | head -1",
49155
+ preinstall: true,
49156
+ binary: {
49157
+ "linux-x86_64": { url: "https://github.com/BurntSushi/ripgrep/releases/download/14.1.1/ripgrep-14.1.1-x86_64-unknown-linux-musl.tar.gz", archive: "tar.gz", extract: "ripgrep-14.1.1-x86_64-unknown-linux-musl/rg" },
49158
+ "linux-aarch64": { url: "https://github.com/BurntSushi/ripgrep/releases/download/14.1.1/ripgrep-14.1.1-aarch64-unknown-linux-gnu.tar.gz", archive: "tar.gz", extract: "ripgrep-14.1.1-aarch64-unknown-linux-gnu/rg" },
49159
+ "darwin-x86_64": { url: "https://github.com/BurntSushi/ripgrep/releases/download/14.1.1/ripgrep-14.1.1-x86_64-apple-darwin.tar.gz", archive: "tar.gz", extract: "ripgrep-14.1.1-x86_64-apple-darwin/rg" },
49160
+ "darwin-aarch64": { url: "https://github.com/BurntSushi/ripgrep/releases/download/14.1.1/ripgrep-14.1.1-aarch64-apple-darwin.tar.gz", archive: "tar.gz", extract: "ripgrep-14.1.1-aarch64-apple-darwin/rg" },
49161
+ "windows-x86_64": { url: "https://github.com/BurntSushi/ripgrep/releases/download/14.1.1/ripgrep-14.1.1-x86_64-pc-windows-msvc.zip", archive: "zip", extract: "ripgrep-14.1.1-x86_64-pc-windows-msvc/rg.exe" }
49162
+ },
49163
+ binName: "rg"
49164
+ },
49165
+ fd: {
49166
+ category: "development",
49167
+ pkg: "fd-find",
49168
+ installer: "binary",
49169
+ label: "fd",
49170
+ capabilities: "Fast user-friendly find replacement: regex by default, .gitignore-aware, parallel",
49171
+ description: "Find files/dirs by name. Usage: `fd <pattern> [path]`, `-e <ext>` filter by extension, `-t f|d` type, `-H` include hidden, `-x <cmd>` exec per match.",
49172
+ versionCmd: "fd --version 2>/dev/null | head -1",
49173
+ preinstall: true,
49174
+ binary: {
49175
+ "linux-x86_64": { url: "https://github.com/sharkdp/fd/releases/download/v10.2.0/fd-v10.2.0-x86_64-unknown-linux-musl.tar.gz", archive: "tar.gz", extract: "fd-v10.2.0-x86_64-unknown-linux-musl/fd" },
49176
+ "linux-aarch64": { url: "https://github.com/sharkdp/fd/releases/download/v10.2.0/fd-v10.2.0-aarch64-unknown-linux-gnu.tar.gz", archive: "tar.gz", extract: "fd-v10.2.0-aarch64-unknown-linux-gnu/fd" },
49177
+ "darwin-x86_64": { url: "https://github.com/sharkdp/fd/releases/download/v10.2.0/fd-v10.2.0-x86_64-apple-darwin.tar.gz", archive: "tar.gz", extract: "fd-v10.2.0-x86_64-apple-darwin/fd" },
49178
+ "darwin-aarch64": { url: "https://github.com/sharkdp/fd/releases/download/v10.2.0/fd-v10.2.0-aarch64-apple-darwin.tar.gz", archive: "tar.gz", extract: "fd-v10.2.0-aarch64-apple-darwin/fd" },
49179
+ "windows-x86_64": { url: "https://github.com/sharkdp/fd/releases/download/v10.2.0/fd-v10.2.0-x86_64-pc-windows-msvc.zip", archive: "zip", extract: "fd-v10.2.0-x86_64-pc-windows-msvc/fd.exe" }
49180
+ },
49181
+ binName: "fd"
49182
+ },
49183
+ jq: {
49184
+ category: "development",
49185
+ pkg: "jq",
49186
+ installer: "binary",
49187
+ label: "jq",
49188
+ capabilities: "Command-line JSON processor: query, filter, transform, format JSON streams",
49189
+ description: "JSON pipeline tool. Usage: `cat x.json | jq '.field'`, `jq -r` raw output, `jq '.[] | select(.k==\"v\")'`, `jq -s` slurp array. Pairs well with curl/rg.",
49190
+ versionCmd: "jq --version 2>/dev/null | head -1",
49191
+ preinstall: true,
49192
+ binary: {
49193
+ "linux-x86_64": { url: "https://github.com/jqlang/jq/releases/download/jq-1.7.1/jq-linux-amd64", archive: "raw" },
49194
+ "linux-aarch64": { url: "https://github.com/jqlang/jq/releases/download/jq-1.7.1/jq-linux-arm64", archive: "raw" },
49195
+ "darwin-x86_64": { url: "https://github.com/jqlang/jq/releases/download/jq-1.7.1/jq-macos-amd64", archive: "raw" },
49196
+ "darwin-aarch64": { url: "https://github.com/jqlang/jq/releases/download/jq-1.7.1/jq-macos-arm64", archive: "raw" },
49197
+ "windows-x86_64": { url: "https://github.com/jqlang/jq/releases/download/jq-1.7.1/jq-windows-amd64.exe", archive: "raw" }
49198
+ },
49199
+ binName: "jq"
49200
+ },
49201
+ patch: {
49202
+ category: "development",
49203
+ pkg: "patch",
49204
+ installer: "system",
49205
+ label: "GNU patch",
49206
+ capabilities: "Apply unified/context diff patches to files; reverse, dry-run, fuzzy matching",
49207
+ description: "Apply diffs. Usage: `patch -p1 < changes.diff` (strip 1 leading path component), `--dry-run` to preview, `-R` to reverse, `-N` skip already-applied. Reads unified (`diff -u`) or context diffs.",
49208
+ versionCmd: "patch --version 2>/dev/null | head -1"
49125
49209
  }
49126
49210
  };
49127
49211
 
@@ -49230,11 +49314,17 @@ function toolPathEntries() {
49230
49314
  }
49231
49315
  function buildEnvWithTools() {
49232
49316
  const env = { ...process.env };
49233
- env.PATH = toolPathEntries().join(path3.delimiter) + path3.delimiter + (env.PATH || "");
49317
+ const existingPath = env.PATH ?? env.Path ?? env.path ?? "";
49318
+ if (os3.platform() === "win32") {
49319
+ delete env.Path;
49320
+ delete env.path;
49321
+ }
49322
+ env.PATH = toolPathEntries().join(path3.delimiter) + path3.delimiter + existingPath;
49234
49323
  return env;
49235
49324
  }
49236
49325
  function whichWithTools(name) {
49237
- const dirs = [...toolPathEntries(), ...(process.env.PATH || "").split(path3.delimiter)];
49326
+ const rawPath = process.env.PATH ?? process.env.Path ?? process.env.path ?? "";
49327
+ const dirs = [...toolPathEntries(), ...rawPath.split(path3.delimiter)];
49238
49328
  const exts = os3.platform() === "win32" ? [".exe", ".cmd", ".bat", ""] : [""];
49239
49329
  for (const dir of dirs) {
49240
49330
  for (const ext of exts) {
@@ -49365,6 +49455,30 @@ function installWithNpm(name, pkg) {
49365
49455
  throw new Error(`npm install failed (exit ${result.status}) | stderr: ${stderr || "(empty)"} | stdout: ${stdout || "(empty)"}`);
49366
49456
  }
49367
49457
  }
49458
+ function installWithBun(name, pkg) {
49459
+ const TIMEOUT_MS = 120000;
49460
+ log2("info", `Installing ${name} via bun (${pkg})`);
49461
+ fs3.mkdirSync(TOOLS_DIR, { recursive: true });
49462
+ const result = spawnSync("bun", ["add", "--cwd", TOOLS_DIR, pkg], {
49463
+ stdio: "pipe",
49464
+ timeout: TIMEOUT_MS,
49465
+ shell: true
49466
+ });
49467
+ const stderr = result.stderr?.toString().trim() || "";
49468
+ const stdout = result.stdout?.toString().trim() || "";
49469
+ if (result.error) {
49470
+ throw new Error(`bun add failed: ${result.error.message} | stderr: ${stderr || "(empty)"} | stdout: ${stdout || "(empty)"}`);
49471
+ }
49472
+ if (result.signal) {
49473
+ throw new Error(`bun add killed by ${result.signal}${result.signal === "SIGTERM" ? ` (likely timed out after ${TIMEOUT_MS / 1000}s)` : ""} | stderr: ${stderr || "(empty)"}`);
49474
+ }
49475
+ if (result.status === null) {
49476
+ throw new Error(`bun add: null exit code (likely timed out after ${TIMEOUT_MS / 1000}s) | stderr: ${stderr || "(empty)"} | stdout: ${stdout || "(empty)"}`);
49477
+ }
49478
+ if (result.status !== 0) {
49479
+ throw new Error(`bun add failed (exit ${result.status}) | stderr: ${stderr || "(empty)"} | stdout: ${stdout || "(empty)"}`);
49480
+ }
49481
+ }
49368
49482
  function installWithPip(name, pkg) {
49369
49483
  const venvDir = path3.join(TOOLS_DIR, "venv");
49370
49484
  const venvPython = os3.platform() === "win32" ? path3.join(venvDir, "Scripts", "python.exe") : path3.join(venvDir, "bin", "python");
@@ -49427,9 +49541,13 @@ function installWithPip(name, pkg) {
49427
49541
  }
49428
49542
  var INSTALLERS = {
49429
49543
  npm: installWithNpm,
49544
+ bun: installWithBun,
49430
49545
  pip: installWithPip,
49431
49546
  binary: async (name, _pkg) => {
49432
49547
  await installBinary(name);
49548
+ },
49549
+ system: () => {
49550
+ log2("warn", "system-installer tools are not auto-installed; install via apt/brew");
49433
49551
  }
49434
49552
  };
49435
49553
  var installing = new Set;
@@ -49474,6 +49592,8 @@ function uninstallTool(name) {
49474
49592
  }
49475
49593
  } else if (installerType === "npm") {
49476
49594
  spawnSync("npm", ["uninstall", "--prefix", TOOLS_DIR, pkg], { stdio: "pipe", timeout: 30000, shell: true });
49595
+ } else if (installerType === "bun") {
49596
+ spawnSync("bun", ["remove", "--cwd", TOOLS_DIR, pkg], { stdio: "pipe", timeout: 30000, shell: true });
49477
49597
  } else if (installerType === "pip") {
49478
49598
  const venvPython = os3.platform() === "win32" ? path3.join(TOOLS_DIR, "venv", "Scripts", "python.exe") : path3.join(TOOLS_DIR, "venv", "bin", "python");
49479
49599
  const python = fs3.existsSync(venvPython) ? venvPython : "python3";
@@ -49698,9 +49818,11 @@ import fs4 from "fs";
49698
49818
  // node_modules/fflate/esm/index.mjs
49699
49819
  import { createRequire as createRequire2 } from "module";
49700
49820
  var require2 = createRequire2("/");
49821
+ var _a;
49701
49822
  var Worker2;
49823
+ var isMarkedAsUntransferable;
49702
49824
  try {
49703
- Worker2 = require2("worker_threads").Worker;
49825
+ _a = require2("worker_threads"), Worker2 = _a.Worker, isMarkedAsUntransferable = _a.isMarkedAsUntransferable;
49704
49826
  } catch (e) {}
49705
49827
  var u8 = Uint8Array;
49706
49828
  var u16 = Uint16Array;
@@ -50357,7 +50479,7 @@ var fltn = function(d, p, t, o) {
50357
50479
  var val = d[k], n = p + k, op = o;
50358
50480
  if (Array.isArray(val))
50359
50481
  op = mrg(o, val[1]), val = val[0];
50360
- if (val instanceof u8)
50482
+ if (ArrayBuffer.isView(val))
50361
50483
  t[n] = [val, op];
50362
50484
  else {
50363
50485
  t[n += "/"] = [new u8(0), op];
@@ -50440,14 +50562,28 @@ var slzh = function(d, b) {
50440
50562
  return b + 30 + b2(d, b + 26) + b2(d, b + 28);
50441
50563
  };
50442
50564
  var zh = function(d, b, z) {
50443
- var fnl = b2(d, b + 28), fn = strFromU8(d.subarray(b + 46, b + 46 + fnl), !(b2(d, b + 8) & 2048)), es = b + 46 + fnl, bs = b4(d, b + 20);
50444
- var _a2 = z && bs == 4294967295 ? z64e(d, es) : [bs, b4(d, b + 24), b4(d, b + 42)], sc = _a2[0], su = _a2[1], off = _a2[2];
50445
- return [b2(d, b + 10), sc, su, fn, es + b2(d, b + 30) + b2(d, b + 32), off];
50565
+ var fnl = b2(d, b + 28), efl = b2(d, b + 30), fn = strFromU8(d.subarray(b + 46, b + 46 + fnl), !(b2(d, b + 8) & 2048)), es = b + 46 + fnl;
50566
+ var _a2 = z64hs(d, es, efl, z, b4(d, b + 20), b4(d, b + 24), b4(d, b + 42)), sc = _a2[0], su = _a2[1], off = _a2[2];
50567
+ return [b2(d, b + 10), sc, su, fn, es + efl + b2(d, b + 32), off];
50446
50568
  };
50447
- var z64e = function(d, b) {
50448
- for (;b2(d, b) != 1; b += 4 + b2(d, b + 2))
50449
- ;
50450
- return [b8(d, b + 12), b8(d, b + 4), b8(d, b + 20)];
50569
+ var z64hs = function(d, b, l, z, sc, su, off) {
50570
+ var nsc = sc == 4294967295, nsu = su == 4294967295, noff = off == 4294967295, e = b + l;
50571
+ var nf = nsc + nsu + noff;
50572
+ if (z && nf) {
50573
+ for (;b + 4 < e; b += 4 + b2(d, b + 2)) {
50574
+ if (b2(d, b) == 1) {
50575
+ return [
50576
+ nsc ? b8(d, b + 4 + 8 * nsu) : sc,
50577
+ nsu ? b8(d, b + 4) : su,
50578
+ noff ? b8(d, b + 4 + 8 * (nsu + nsc)) : off,
50579
+ 1
50580
+ ];
50581
+ }
50582
+ }
50583
+ if (z < 2)
50584
+ err(13);
50585
+ }
50586
+ return [sc, su, off, 0];
50451
50587
  };
50452
50588
  var exfl = function(ex) {
50453
50589
  var le = 0;
@@ -50561,7 +50697,7 @@ function unzipSync(data, opts) {
50561
50697
  if (!c)
50562
50698
  return {};
50563
50699
  var o = b4(data, e + 16);
50564
- var z = o == 4294967295 || c == 65535;
50700
+ var z = b4(data, e - 20) == 117853008;
50565
50701
  if (z) {
50566
50702
  var ze = b4(data, e - 12);
50567
50703
  z = b4(data, ze) == 101075792;
@@ -51095,15 +51231,11 @@ class LinuxSyscallDetector {
51095
51231
  return;
51096
51232
  const fgPid = await getForegroundPid(pid);
51097
51233
  const sc2 = fgPid != null ? await readSyscall(fgPid) : null;
51098
- if (sc2 && sc2.nr === READ_NR && sc2.fd === 0 && fgPid != null && rootStdin) {
51099
- const leafStdin = await readFdTarget(fgPid, 0);
51100
- if (leafStdin === rootStdin) {
51101
- if (!signalled && ++pausedTicks >= GRACE_TICKS) {
51102
- signalled = true;
51103
- onPaused();
51104
- }
51105
- } else {
51106
- pausedTicks = 0;
51234
+ const leafTarget = sc2 && sc2.nr === READ_NR && sc2.fd >= 0 && fgPid != null ? await readFdTarget(fgPid, sc2.fd) : null;
51235
+ if (isTerminalReadPause(sc2, leafTarget, rootStdin)) {
51236
+ if (!signalled && ++pausedTicks >= GRACE_TICKS) {
51237
+ signalled = true;
51238
+ onPaused();
51107
51239
  }
51108
51240
  } else {
51109
51241
  pausedTicks = 0;
@@ -51122,6 +51254,17 @@ class LinuxSyscallDetector {
51122
51254
  };
51123
51255
  }
51124
51256
  }
51257
+ function isTerminalReadPause(sc2, leafTarget, rootStdin) {
51258
+ if (!sc2 || sc2.nr !== READ_NR || sc2.fd < 0)
51259
+ return false;
51260
+ if (!leafTarget || !rootStdin)
51261
+ return false;
51262
+ if (leafTarget === rootStdin)
51263
+ return true;
51264
+ if (leafTarget === "/dev/tty" && rootStdin.startsWith("/dev/pts/"))
51265
+ return true;
51266
+ return false;
51267
+ }
51125
51268
  async function readSyscall(pid) {
51126
51269
  try {
51127
51270
  const raw = (await readFile(`/proc/${pid}/syscall`, "utf-8")).trim();
@@ -51167,7 +51310,8 @@ var IS_WIN = os6.platform() === "win32";
51167
51310
  var HAS_BUN = typeof globalThis.Bun !== "undefined";
51168
51311
  var HAS_BUN_TERMINAL = HAS_BUN && typeof Bun.Terminal === "function";
51169
51312
  function whichSync(name) {
51170
- const dirs = (process.env.PATH || "").split(path5.delimiter);
51313
+ const rawPath = process.env.PATH ?? process.env.Path ?? process.env.path ?? "";
51314
+ const dirs = rawPath.split(path5.delimiter);
51171
51315
  const exts = IS_WIN ? ["", ".exe", ".cmd", ".bat"] : [""];
51172
51316
  for (const dir of dirs) {
51173
51317
  for (const ext of exts) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@todoforai/edge",
3
- "version": "0.13.5",
3
+ "version": "0.13.7",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "todoforai-edge": "dist/index.js"