@openape/ape-agent 2.9.0 → 2.9.1

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/bridge.mjs +56 -52
  2. package/package.json +2 -2
package/dist/bridge.mjs CHANGED
@@ -1541,7 +1541,62 @@ import { basename, join as join22 } from "path";
1541
1541
 
1542
1542
  // ../../packages/core/dist/index.js
1543
1543
  import * as jose from "jose";
1544
+ import { lookup } from "dns/promises";
1545
+ import { isIP } from "net";
1544
1546
  var HKDF_INFO = new TextEncoder().encode("openape-sealed-box-v1");
1547
+ function isBlockedAddress(ip) {
1548
+ const fam = isIP(ip);
1549
+ if (fam === 4) {
1550
+ const o3 = ip.split(".");
1551
+ const a2 = Number(o3[0]);
1552
+ const b2 = Number(o3[1]);
1553
+ if (a2 === 0) return true;
1554
+ if (a2 === 127) return true;
1555
+ if (a2 === 10) return true;
1556
+ if (a2 === 172 && b2 >= 16 && b2 <= 31) return true;
1557
+ if (a2 === 192 && b2 === 168) return true;
1558
+ if (a2 === 169 && b2 === 254) return true;
1559
+ if (a2 === 100 && b2 >= 64 && b2 <= 127) return true;
1560
+ return false;
1561
+ }
1562
+ const low = ip.toLowerCase().replace(/^\[|\]$/g, "");
1563
+ if (low === "::" || low === "::1") return true;
1564
+ if (low.startsWith("fe80")) return true;
1565
+ if (low.startsWith("fc") || low.startsWith("fd")) return true;
1566
+ const mapped = low.match(/^::ffff:(\d{1,3}(?:\.\d{1,3}){3})$/);
1567
+ if (mapped) return isBlockedAddress(mapped[1]);
1568
+ return false;
1569
+ }
1570
+ async function assertPublicUrl(rawUrl, opts = {}) {
1571
+ let url;
1572
+ try {
1573
+ url = new URL(rawUrl);
1574
+ } catch {
1575
+ throw new Error(`Invalid URL: ${rawUrl}`);
1576
+ }
1577
+ const allowedSchemes = opts.allowHttp === true ? /* @__PURE__ */ new Set(["https:", "http:"]) : /* @__PURE__ */ new Set(["https:"]);
1578
+ if (!allowedSchemes.has(url.protocol)) {
1579
+ const expected = opts.allowHttp === true ? "http(s)" : "https";
1580
+ throw new Error(`URL must use ${expected}:// (got ${url.protocol}//) \u2014 ${rawUrl}`);
1581
+ }
1582
+ const host = url.hostname.replace(/^\[|\]$/g, "");
1583
+ const addresses = [];
1584
+ if (isIP(host)) {
1585
+ addresses.push(host);
1586
+ } else {
1587
+ const results = await lookup(host, { all: true });
1588
+ for (const r3 of results) addresses.push(r3.address);
1589
+ }
1590
+ if (addresses.length === 0) {
1591
+ throw new Error(`Host did not resolve: ${host}`);
1592
+ }
1593
+ for (const addr of addresses) {
1594
+ if (isBlockedAddress(addr)) {
1595
+ throw new Error(`Refusing to fetch a private/loopback address (${addr}) for ${rawUrl}`);
1596
+ }
1597
+ }
1598
+ return url;
1599
+ }
1545
1600
 
1546
1601
  // ../../packages/grants/dist/index.js
1547
1602
  function normalizeSelector(selector) {
@@ -3090,8 +3145,6 @@ import { dirname, normalize, resolve } from "path";
3090
3145
  import { homedir as homedir23 } from "os";
3091
3146
  import { resolve as resolve2 } from "path";
3092
3147
  import process2 from "process";
3093
- import { lookup } from "dns/promises";
3094
- import { isIP } from "net";
3095
3148
  import { execFileSync } from "child_process";
3096
3149
  import { execFileSync as execFileSync2 } from "child_process";
3097
3150
  var DEFAULT_TIMEOUT_MS = 5 * 60 * 1e3;
@@ -3584,59 +3637,10 @@ var gitWorktreeTools = [
3584
3637
  }
3585
3638
  }
3586
3639
  ];
3587
- function isBlockedAddress(ip) {
3588
- const fam = isIP(ip);
3589
- if (fam === 4) {
3590
- const o3 = ip.split(".");
3591
- const a2 = Number(o3[0]);
3592
- const b2 = Number(o3[1]);
3593
- if (a2 === 0) return true;
3594
- if (a2 === 127) return true;
3595
- if (a2 === 10) return true;
3596
- if (a2 === 172 && b2 >= 16 && b2 <= 31) return true;
3597
- if (a2 === 192 && b2 === 168) return true;
3598
- if (a2 === 169 && b2 === 254) return true;
3599
- if (a2 === 100 && b2 >= 64 && b2 <= 127) return true;
3600
- return false;
3601
- }
3602
- const low = ip.toLowerCase().replace(/^\[|\]$/g, "");
3603
- if (low === "::" || low === "::1") return true;
3604
- if (low.startsWith("fe80")) return true;
3605
- if (low.startsWith("fc") || low.startsWith("fd")) return true;
3606
- const mapped = low.match(/^::ffff:(\d{1,3}(?:\.\d{1,3}){3})$/);
3607
- if (mapped) return isBlockedAddress(mapped[1]);
3608
- return false;
3609
- }
3610
- async function assertPublicUrl(rawUrl) {
3611
- let url;
3612
- try {
3613
- url = new URL(rawUrl);
3614
- } catch {
3615
- throw new Error(`Invalid URL: ${rawUrl}`);
3616
- }
3617
- if (url.protocol !== "https:" && url.protocol !== "http:") {
3618
- throw new Error(`url must be http(s) (got ${url.protocol})`);
3619
- }
3620
- const host = url.hostname.replace(/^\[|\]$/g, "");
3621
- const addresses = [];
3622
- if (isIP(host)) {
3623
- addresses.push(host);
3624
- } else {
3625
- const results = await lookup(host, { all: true });
3626
- for (const r3 of results) addresses.push(r3.address);
3627
- }
3628
- if (addresses.length === 0) throw new Error(`Host did not resolve: ${host}`);
3629
- for (const addr of addresses) {
3630
- if (isBlockedAddress(addr)) {
3631
- throw new Error(`Refusing to fetch a private/loopback address (${addr}) for ${rawUrl}`);
3632
- }
3633
- }
3634
- return url;
3635
- }
3636
3640
  async function safeFetch(rawUrl, init2 = {}, maxRedirects = 5) {
3637
3641
  let current = rawUrl;
3638
3642
  for (let hop = 0; hop <= maxRedirects; hop += 1) {
3639
- await assertPublicUrl(current);
3643
+ await assertPublicUrl(current, { allowHttp: true });
3640
3644
  const res = await fetch(current, { ...init2, redirect: "manual" });
3641
3645
  if (res.status >= 300 && res.status < 400) {
3642
3646
  const location = res.headers.get("location");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openape/ape-agent",
3
- "version": "2.9.0",
3
+ "version": "2.9.1",
4
4
  "description": "OpenApe agent runtime: per-agent process that connects to chat.openape.ai, runs the LLM loop with tools + cron tasks, and streams replies back to owners.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -23,8 +23,8 @@
23
23
  "ofetch": "^1.4.1",
24
24
  "ws": "^8.18.0",
25
25
  "yaml": "^2.8.0",
26
+ "@openape/apes": "1.29.1",
26
27
  "@openape/cli-auth": "0.5.0",
27
- "@openape/apes": "1.29.0",
28
28
  "@openape/prompt-injection-detector": "0.1.0"
29
29
  },
30
30
  "devDependencies": {