@withone/cli 1.56.1 → 1.57.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.
package/README.md CHANGED
@@ -280,6 +280,18 @@ one actions knowledge shopify 67890abcdef
280
280
 
281
281
  Always read the knowledge before executing. It tells you exactly what parameters are required, what format they need, and any platform-specific quirks.
282
282
 
283
+ In `--agent` mode the response is a **digest**: request-building sections in full (method/URL, headers, description, enforcement rules, required and optional parameters, sample request, gotchas, error handling) plus a table of contents for the rest. Response shapes, response-field tables, and worked examples — the bulk of every large doc — are loaded on demand:
284
+
285
+ ```bash
286
+ one --agent actions knowledge github <actionId> # digest + sections[] table of contents
287
+ one --agent actions knowledge github <actionId> --section "Response Fields" # one section, by heading or id
288
+ one --agent actions knowledge github <actionId> --section response,examples # several, by alias
289
+ one --agent actions knowledge github <actionId> --full # whole document
290
+ one --agent actions knowledge github <actionId> --toc # every section id, no document
291
+ ```
292
+
293
+ The JSON carries `truncated`, `sections[]` (the omitted sections: id, heading, chars), and `more` (the commands to load the rest); the markdown ends with the same notice so it is never mistaken for the complete doc. Small documents are returned whole. Section requests are served from the local cache. Human (non-agent) output always prints the full document; `--section` works there too.
294
+
283
295
  ### `one actions execute <platform> <actionId> <connectionKey>`
284
296
 
285
297
  Execute an API action on a connected platform.
@@ -354,6 +366,7 @@ Knowledge and search commands also support cache flags:
354
366
  ```bash
355
367
  one actions knowledge gmail <actionId> --no-cache # Skip cache, fetch fresh
356
368
  one actions knowledge gmail <actionId> --cache-status # Check cache status
369
+ one actions knowledge gmail <actionId> --section response # Served from the cached doc, no fetch
357
370
  one actions search gmail "send email" --no-cache # Skip cache for search
358
371
  one actions execute gmail <actionId> <key> --no-cache # Fresh action-details lookup
359
372
  ```
@@ -364,7 +377,7 @@ Note: execution responses are never cached — the action always runs live. Only
364
377
 
365
378
  ### `one mem` — unified memory store
366
379
 
367
- One ships a local memory store (a real Postgres process bootstrapped on demand via the bundled `embedded-postgres` plugin, with a `postgres` plugin for remote/self-hosted) that backs both user-authored notes and synced platform data. **Zero-config** — the first `one mem` call on a fresh machine auto-initializes the cluster at `~/.one/pg/cluster/` and writes a daemon PID file so subsequent CLI invocations reuse it.
380
+ One ships a local memory store (a real Postgres process bootstrapped on demand via the bundled `embedded-postgres` plugin, with a `postgres` plugin for remote/self-hosted) that backs both user-authored notes and synced platform data. **Zero-config** — the first `one mem` call on a fresh machine auto-initializes the cluster at `~/.one/pg/cluster/` and writes a daemon PID file so subsequent CLI invocations reuse it. The daemon listens on port 5434, moving to the next free port if another program already holds it; pin a port with `one mem config set embedded-postgres.port <n>`.
368
381
 
369
382
  ```bash
370
383
  # User memories — works immediately on a new install
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-OLQ55K6B.js";
7
7
  import {
8
8
  getBackend
9
- } from "./chunk-VH46MAE4.js";
9
+ } from "./chunk-IMU2X3ZV.js";
10
10
 
11
11
  // src/commands/mem/sql.ts
12
12
  async function memSqlCommand(sql) {
@@ -1456,12 +1456,333 @@ var postgresPlugin = {
1456
1456
  };
1457
1457
 
1458
1458
  // src/lib/memory/plugins/embedded-postgres/index.ts
1459
+ import path2 from "path";
1460
+
1461
+ // src/lib/memory/plugins/embedded-postgres/daemon.ts
1459
1462
  import fs from "fs";
1460
1463
  import net from "net";
1461
1464
  import path from "path";
1462
1465
  import { createRequire } from "module";
1463
- import { spawn } from "child_process";
1466
+ import { spawn, spawnSync } from "child_process";
1464
1467
  var requireFromHere = createRequire(import.meta.url);
1468
+ var PG_PORT_OFFSET = 1e3;
1469
+ var PORT_SEARCH_SPAN = 20;
1470
+ var LOG_MAX_BYTES = 10 * 1024 * 1024;
1471
+ var LOG_KEEP_BYTES = 1024 * 1024;
1472
+ var DEFAULT_STOP_TIMEOUT_MS = 15e3;
1473
+ var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
1474
+ function pidFilePath(dataDir) {
1475
+ return path.join(dataDir, ".pgserve.json");
1476
+ }
1477
+ function readPidFile(dataDir) {
1478
+ try {
1479
+ return JSON.parse(fs.readFileSync(pidFilePath(dataDir), "utf8"));
1480
+ } catch {
1481
+ return null;
1482
+ }
1483
+ }
1484
+ function writePidFile(dataDir, rec) {
1485
+ fs.mkdirSync(dataDir, { recursive: true });
1486
+ fs.writeFileSync(pidFilePath(dataDir), JSON.stringify(rec, null, 2), { mode: 384 });
1487
+ }
1488
+ function isPidAlive(pid) {
1489
+ try {
1490
+ process.kill(pid, 0);
1491
+ return true;
1492
+ } catch {
1493
+ return false;
1494
+ }
1495
+ }
1496
+ async function waitForExit(pid, timeoutMs) {
1497
+ const deadline = Date.now() + timeoutMs;
1498
+ while (isPidAlive(pid)) {
1499
+ if (Date.now() >= deadline) return false;
1500
+ await sleep(50);
1501
+ }
1502
+ return true;
1503
+ }
1504
+ function signal(pid, sig) {
1505
+ try {
1506
+ process.kill(pid, sig);
1507
+ } catch {
1508
+ }
1509
+ }
1510
+ function canBind(host, port) {
1511
+ return new Promise((resolve) => {
1512
+ const server = net.createServer();
1513
+ server.once("error", () => resolve(false));
1514
+ server.listen({ port, host, exclusive: true }, () => server.close(() => resolve(true)));
1515
+ });
1516
+ }
1517
+ async function portPairFree(host, port) {
1518
+ return port + PG_PORT_OFFSET <= 65535 && await canBind(host, port) && await canBind("127.0.0.1", port + PG_PORT_OFFSET);
1519
+ }
1520
+ async function choosePort(host, preferred, explicit) {
1521
+ if (await portPairFree(host, preferred)) return preferred;
1522
+ const hint = 'set a different "memory.embedded-postgres.port" in ~/.one/config.json';
1523
+ if (explicit) {
1524
+ throw new Error(
1525
+ `Port ${preferred} (or ${preferred + PG_PORT_OFFSET}, its internal Postgres port) on ${host} is already in use by another program, so the embedded Postgres can't start there. Free it, or ${hint}.`
1526
+ );
1527
+ }
1528
+ for (let port = preferred + 1; port <= preferred + PORT_SEARCH_SPAN; port++) {
1529
+ if (await portPairFree(host, port)) return port;
1530
+ }
1531
+ throw new Error(
1532
+ `Ports ${preferred}-${preferred + PORT_SEARCH_SPAN} on ${host} are all already in use, so the embedded Postgres can't start. Free one, or ${hint}.`
1533
+ );
1534
+ }
1535
+ function readRange(file, start, length) {
1536
+ const fd = fs.openSync(file, "r");
1537
+ try {
1538
+ const buf = Buffer.alloc(length);
1539
+ const n = fs.readSync(fd, buf, 0, length, start);
1540
+ return buf.subarray(0, n);
1541
+ } finally {
1542
+ fs.closeSync(fd);
1543
+ }
1544
+ }
1545
+ function fileSize(file) {
1546
+ try {
1547
+ return fs.statSync(file).size;
1548
+ } catch {
1549
+ return 0;
1550
+ }
1551
+ }
1552
+ function trimLog(logPath, maxBytes = LOG_MAX_BYTES, keepBytes = LOG_KEEP_BYTES) {
1553
+ const size = fileSize(logPath);
1554
+ if (size <= maxBytes) return;
1555
+ const tail = readRange(logPath, size - keepBytes, keepBytes);
1556
+ const nl = tail.indexOf(10);
1557
+ const kept = nl === -1 ? tail : tail.subarray(nl + 1);
1558
+ const notice = `[one] pgserve.log passed ${maxBytes} bytes; kept the last ${kept.length} (${(/* @__PURE__ */ new Date()).toISOString()})
1559
+ `;
1560
+ fs.writeFileSync(logPath, Buffer.concat([Buffer.from(notice), kept]));
1561
+ }
1562
+ function logSince(logPath, offset, maxBytes = 2e3) {
1563
+ const size = fileSize(logPath);
1564
+ const start = Math.max(offset, size - maxBytes);
1565
+ if (size <= start) return "";
1566
+ return readRange(logPath, start, size - start).toString("utf8").replace(/\x1b\[[0-9;]*m/g, "").trim();
1567
+ }
1568
+ function lockIsStale(lockPath, ttlMs) {
1569
+ try {
1570
+ if (Date.now() - fs.statSync(lockPath).mtimeMs > ttlMs) return true;
1571
+ const { pid } = JSON.parse(fs.readFileSync(lockPath, "utf8"));
1572
+ return typeof pid === "number" && !isPidAlive(pid);
1573
+ } catch {
1574
+ return false;
1575
+ }
1576
+ }
1577
+ async function withStartupLock(dataDir, waitMs, fn) {
1578
+ const lockPath = path.join(dataDir, ".pgserve.lock");
1579
+ const deadline = Date.now() + waitMs;
1580
+ for (; ; ) {
1581
+ try {
1582
+ fs.writeFileSync(lockPath, JSON.stringify({ pid: process.pid, startedAt: Date.now() }), { flag: "wx" });
1583
+ break;
1584
+ } catch (err) {
1585
+ if (err.code !== "EEXIST") throw err;
1586
+ }
1587
+ if (lockIsStale(lockPath, waitMs)) {
1588
+ fs.rmSync(lockPath, { force: true });
1589
+ continue;
1590
+ }
1591
+ if (Date.now() >= deadline) {
1592
+ throw new Error(`Timed out waiting for another \`one\` process to start the embedded Postgres (lock: ${lockPath}).`);
1593
+ }
1594
+ await sleep(100);
1595
+ }
1596
+ try {
1597
+ return await fn();
1598
+ } finally {
1599
+ fs.rmSync(lockPath, { force: true });
1600
+ }
1601
+ }
1602
+ function readPostmasterPid(clusterDir) {
1603
+ try {
1604
+ const lines = fs.readFileSync(path.join(clusterDir, "postmaster.pid"), "utf8").split("\n");
1605
+ const pid = Number.parseInt(lines[0] ?? "", 10);
1606
+ const port = Number.parseInt(lines[3] ?? "", 10);
1607
+ return pid > 0 && port > 0 ? { pid, port } : null;
1608
+ } catch {
1609
+ return null;
1610
+ }
1611
+ }
1612
+ function pgserveOwner(postmasterPid, deps) {
1613
+ const ppid = deps.processInfo(postmasterPid)?.ppid;
1614
+ if (!ppid || ppid <= 1) return null;
1615
+ const command = deps.processInfo(ppid)?.command ?? "";
1616
+ return /pgserve[\\/]bin[\\/]postgres-server\.js/.test(command) ? ppid : null;
1617
+ }
1618
+ async function stopStaleCluster(clusterDir, deps, timeoutMs) {
1619
+ const holder = readPostmasterPid(clusterDir);
1620
+ if (!holder || !isPidAlive(holder.pid)) return;
1621
+ if (await deps.probe(holder.port, "postmaster") !== "ours") return;
1622
+ const owner = pgserveOwner(holder.pid, deps);
1623
+ if (owner !== null) {
1624
+ signal(owner, "SIGTERM");
1625
+ if (!await waitForExit(owner, timeoutMs)) signal(owner, "SIGKILL");
1626
+ }
1627
+ if (!isPidAlive(holder.pid)) return;
1628
+ signal(holder.pid, "SIGINT");
1629
+ if (!await waitForExit(holder.pid, timeoutMs)) {
1630
+ throw new Error(
1631
+ `The embedded Postgres (PID ${holder.pid}) is holding ${clusterDir} and did not stop. Stop it (kill ${holder.pid}) and retry.`
1632
+ );
1633
+ }
1634
+ }
1635
+ async function findHealthyDaemon(dataDir, deps) {
1636
+ const rec = readPidFile(dataDir);
1637
+ if (!rec || !isPidAlive(rec.pid)) return null;
1638
+ return await deps.probe(rec.port, "router") === "ours" ? rec.port : null;
1639
+ }
1640
+ function pgserveArgs(cfg, clusterDir, port) {
1641
+ const args = [
1642
+ "--data",
1643
+ clusterDir,
1644
+ "--port",
1645
+ String(port),
1646
+ "--host",
1647
+ cfg.host,
1648
+ "--log",
1649
+ cfg.logLevel,
1650
+ "--no-stats",
1651
+ // Single process. In cluster mode a worker that can't bind the port is
1652
+ // re-forked immediately, forever, each crash logging a full stack trace.
1653
+ "--no-cluster"
1654
+ ];
1655
+ if (cfg.pgvector) args.push("--pgvector");
1656
+ return args;
1657
+ }
1658
+ async function waitUntilServing(child, cfg, port, deps, log) {
1659
+ const deadline = Date.now() + cfg.startupTimeoutMs;
1660
+ const details = () => {
1661
+ const tail = logSince(log.path, log.offset);
1662
+ return `
1663
+ Log: ${log.path}${tail ? `
1664
+ ${tail}` : ""}`;
1665
+ };
1666
+ for (; ; ) {
1667
+ const exit = child.exitStatus();
1668
+ if (exit) throw new Error(`pgserve exited (${exit}) before it was ready.${details()}`);
1669
+ if (await deps.probe(port, "router") === "ours") return;
1670
+ if (Date.now() >= deadline) {
1671
+ throw new Error(
1672
+ `pgserve did not start serving on ${cfg.host}:${port} within ${Math.round(cfg.startupTimeoutMs / 1e3)}s.${details()}`
1673
+ );
1674
+ }
1675
+ await sleep(250);
1676
+ }
1677
+ }
1678
+ async function ensureRunning(cfg, deps) {
1679
+ const reused = await findHealthyDaemon(cfg.dataDir, deps);
1680
+ if (reused !== null) return reused;
1681
+ fs.mkdirSync(cfg.dataDir, { recursive: true });
1682
+ const stopTimeoutMs = deps.stopTimeoutMs ?? DEFAULT_STOP_TIMEOUT_MS;
1683
+ return withStartupLock(cfg.dataDir, cfg.startupTimeoutMs + 3 * stopTimeoutMs, async () => {
1684
+ const raced = await findHealthyDaemon(cfg.dataDir, deps);
1685
+ if (raced !== null) return raced;
1686
+ const clusterDir = path.join(cfg.dataDir, "cluster");
1687
+ fs.mkdirSync(clusterDir, { recursive: true });
1688
+ await stopStaleCluster(clusterDir, deps, stopTimeoutMs);
1689
+ const port = await choosePort(cfg.host, cfg.port, cfg.portExplicit);
1690
+ const logPath = path.join(cfg.dataDir, "pgserve.log");
1691
+ trimLog(logPath);
1692
+ const log = { path: logPath, offset: fileSize(logPath) };
1693
+ const fd = fs.openSync(logPath, "a");
1694
+ let child;
1695
+ try {
1696
+ child = deps.spawnPgserve(pgserveArgs(cfg, clusterDir, port), fd);
1697
+ } finally {
1698
+ fs.closeSync(fd);
1699
+ }
1700
+ await waitUntilServing(child, cfg, port, deps, log);
1701
+ writePidFile(cfg.dataDir, {
1702
+ pid: child.pid,
1703
+ port,
1704
+ dataDir: cfg.dataDir,
1705
+ startedAt: (/* @__PURE__ */ new Date()).toISOString()
1706
+ });
1707
+ return port;
1708
+ });
1709
+ }
1710
+ function sameDir(a, b) {
1711
+ const norm = (p) => {
1712
+ let r = path.resolve(p);
1713
+ try {
1714
+ r = fs.realpathSync.native(r);
1715
+ } catch {
1716
+ }
1717
+ return process.platform === "win32" ? r.toLowerCase() : r;
1718
+ };
1719
+ return a !== "" && norm(a) === norm(b);
1720
+ }
1721
+ async function probeDataDirectory(Client, target, clusterDir) {
1722
+ const client = new Client({ ...target, connectionTimeoutMillis: 3e3, query_timeout: 3e3 });
1723
+ client.on("error", () => {
1724
+ });
1725
+ try {
1726
+ await client.connect();
1727
+ } catch (err) {
1728
+ return err.code === "ECONNREFUSED" ? "down" : "other";
1729
+ }
1730
+ try {
1731
+ const { rows } = await client.query("SHOW data_directory");
1732
+ return sameDir(String(rows[0]?.data_directory ?? ""), clusterDir) ? "ours" : "other";
1733
+ } catch {
1734
+ return "other";
1735
+ } finally {
1736
+ await client.end().catch(() => {
1737
+ });
1738
+ }
1739
+ }
1740
+ function resolvePgserveBin() {
1741
+ const pkg = requireFromHere.resolve("pgserve/package.json");
1742
+ return path.resolve(path.dirname(pkg), "bin/pgserve-wrapper.cjs");
1743
+ }
1744
+ function spawnPgserve(args, logFd, cwd) {
1745
+ const child = spawn(process.execPath, [resolvePgserveBin(), ...args], {
1746
+ detached: true,
1747
+ stdio: ["ignore", logFd, logFd],
1748
+ // pgserve resolves the bundled bun binary relative to its own package
1749
+ // location, not cwd, so cwd doesn't matter — but pin it for clarity.
1750
+ cwd
1751
+ });
1752
+ let status = null;
1753
+ child.once("error", (err) => {
1754
+ status = `failed to start: ${err.message}`;
1755
+ });
1756
+ child.once("exit", (code, sig) => {
1757
+ status = sig ? `signal ${sig}` : `code ${code}`;
1758
+ });
1759
+ child.unref();
1760
+ if (typeof child.pid !== "number") {
1761
+ throw new Error("Failed to spawn pgserve \u2014 no PID returned.");
1762
+ }
1763
+ return { pid: child.pid, exitStatus: () => status };
1764
+ }
1765
+ function processInfo(pid) {
1766
+ if (process.platform === "win32") return null;
1767
+ const res = spawnSync("ps", ["-o", "ppid=", "-o", "command=", "-p", String(pid)], { encoding: "utf8" });
1768
+ const match = /^(\d+)\s+(.*)$/.exec((res.stdout ?? "").trim());
1769
+ return match ? { ppid: Number(match[1]), command: match[2] } : null;
1770
+ }
1771
+ function nodeDaemonDeps(cfg, Client, router) {
1772
+ const clusterDir = path.join(cfg.dataDir, "cluster");
1773
+ const direct = { user: "postgres", password: "postgres", database: "postgres" };
1774
+ return {
1775
+ probe: (port, via) => probeDataDirectory(
1776
+ Client,
1777
+ via === "router" ? { host: cfg.host, port, ...router } : { host: "127.0.0.1", port, ...direct },
1778
+ clusterDir
1779
+ ),
1780
+ spawnPgserve: (args, logFd) => spawnPgserve(args, logFd, cfg.dataDir),
1781
+ processInfo
1782
+ };
1783
+ }
1784
+
1785
+ // src/lib/memory/plugins/embedded-postgres/index.ts
1465
1786
  var BASE_CAPABILITIES = {
1466
1787
  vectorSearch: true,
1467
1788
  fullTextSearch: true,
@@ -1477,13 +1798,14 @@ var DEFAULTS = {
1477
1798
  // `path.join(homeDir(), ...)` here would capture the home directory before
1478
1799
  // ONE_HOME could take effect. See lib/home.ts.
1479
1800
  get dataDir() {
1480
- return path.join(homeDir(), ".one", "pg");
1801
+ return path2.join(homeDir(), ".one", "pg");
1481
1802
  },
1482
1803
  database: "one_mem",
1483
1804
  schema: "public",
1484
1805
  pgvector: true,
1485
1806
  host: "127.0.0.1",
1486
1807
  port: 5434,
1808
+ portExplicit: false,
1487
1809
  // pgserve auto-provisions databases; the bundled superuser is `postgres`
1488
1810
  // with no password by default. We don't expose the password to the user
1489
1811
  // since the daemon only listens on 127.0.0.1.
@@ -1501,6 +1823,7 @@ function parseConfig2(raw) {
1501
1823
  pgvector: r.pgvector ?? DEFAULTS.pgvector,
1502
1824
  host: r.host ?? DEFAULTS.host,
1503
1825
  port: r.port ?? DEFAULTS.port,
1826
+ portExplicit: r.port !== void 0,
1504
1827
  user: r.user ?? DEFAULTS.user,
1505
1828
  password: r.password ?? DEFAULTS.password,
1506
1829
  logLevel: r.logLevel ?? DEFAULTS.logLevel,
@@ -1547,104 +1870,6 @@ function wrapClient2(pool) {
1547
1870
  }
1548
1871
  };
1549
1872
  }
1550
- function pidFilePath(dataDir) {
1551
- return path.join(dataDir, ".pgserve.json");
1552
- }
1553
- function readPidFile(dataDir) {
1554
- try {
1555
- const raw = fs.readFileSync(pidFilePath(dataDir), "utf8");
1556
- return JSON.parse(raw);
1557
- } catch {
1558
- return null;
1559
- }
1560
- }
1561
- function writePidFile(dataDir, rec) {
1562
- fs.mkdirSync(dataDir, { recursive: true });
1563
- fs.writeFileSync(pidFilePath(dataDir), JSON.stringify(rec, null, 2), { mode: 384 });
1564
- }
1565
- function isPidAlive(pid) {
1566
- try {
1567
- process.kill(pid, 0);
1568
- return true;
1569
- } catch {
1570
- return false;
1571
- }
1572
- }
1573
- async function isPortListening(host, port, timeoutMs = 1e3) {
1574
- return new Promise((resolve) => {
1575
- const socket = new net.Socket();
1576
- let resolved = false;
1577
- const finish = (ok) => {
1578
- if (resolved) return;
1579
- resolved = true;
1580
- socket.destroy();
1581
- resolve(ok);
1582
- };
1583
- socket.setTimeout(timeoutMs);
1584
- socket.once("connect", () => finish(true));
1585
- socket.once("timeout", () => finish(false));
1586
- socket.once("error", () => finish(false));
1587
- socket.connect(port, host);
1588
- });
1589
- }
1590
- async function waitForPort(host, port, deadlineAt) {
1591
- while (Date.now() < deadlineAt) {
1592
- if (await isPortListening(host, port)) return;
1593
- await new Promise((r) => setTimeout(r, 250));
1594
- }
1595
- throw new Error(
1596
- `pgserve did not start listening on ${host}:${port} within ${Math.round((deadlineAt - Date.now() + 3e4) / 1e3)}s. Check the data dir for the postgres log, or remove ${path.basename(pidFilePath("<dataDir>"))} and retry.`
1597
- );
1598
- }
1599
- function resolvePgserveBin() {
1600
- const pkg = requireFromHere.resolve("pgserve/package.json");
1601
- return path.resolve(path.dirname(pkg), "bin/pgserve-wrapper.cjs");
1602
- }
1603
- async function ensureRunning(cfg) {
1604
- const existing = readPidFile(cfg.dataDir);
1605
- if (existing && isPidAlive(existing.pid)) {
1606
- if (await isPortListening(cfg.host, existing.port)) {
1607
- cfg.port = existing.port;
1608
- return;
1609
- }
1610
- }
1611
- fs.mkdirSync(cfg.dataDir, { recursive: true });
1612
- const clusterDir = path.join(cfg.dataDir, "cluster");
1613
- fs.mkdirSync(clusterDir, { recursive: true });
1614
- const args = [
1615
- "--data",
1616
- clusterDir,
1617
- "--port",
1618
- String(cfg.port),
1619
- "--host",
1620
- cfg.host,
1621
- "--log",
1622
- cfg.logLevel,
1623
- "--no-stats"
1624
- ];
1625
- if (cfg.pgvector) args.push("--pgvector");
1626
- const bin = resolvePgserveBin();
1627
- const out = fs.openSync(path.join(cfg.dataDir, "pgserve.log"), "a");
1628
- const child = spawn(process.execPath, [bin, ...args], {
1629
- detached: true,
1630
- stdio: ["ignore", out, out],
1631
- // pgserve resolves the bundled bun binary relative to its own package
1632
- // location, not cwd, so cwd doesn't matter — but pin it for clarity.
1633
- cwd: cfg.dataDir
1634
- });
1635
- child.unref();
1636
- if (typeof child.pid !== "number") {
1637
- throw new Error("Failed to spawn pgserve \u2014 no PID returned.");
1638
- }
1639
- const deadlineAt = Date.now() + cfg.startupTimeoutMs;
1640
- await waitForPort(cfg.host, cfg.port, deadlineAt);
1641
- writePidFile(cfg.dataDir, {
1642
- pid: child.pid,
1643
- port: cfg.port,
1644
- dataDir: cfg.dataDir,
1645
- startedAt: (/* @__PURE__ */ new Date()).toISOString()
1646
- });
1647
- }
1648
1873
  async function probePgvector(client) {
1649
1874
  try {
1650
1875
  await client.query("CREATE EXTENSION IF NOT EXISTS vector");
@@ -1662,12 +1887,20 @@ var LazyEmbeddedPostgresBackend = class {
1662
1887
  }
1663
1888
  async ensure() {
1664
1889
  if (this.backend) return this.backend;
1665
- await ensureRunning(this.config);
1666
1890
  const pgMod = await import("pg").catch((err) => {
1667
1891
  const msg = err instanceof Error ? err.message : String(err);
1668
1892
  throw new Error(`pg is not installed. Run \`npm i pg\` or pick a different backend. (${msg})`);
1669
1893
  });
1670
- const PoolCtor = pgMod.Pool ?? pgMod.default.Pool;
1894
+ const pgExports = pgMod.Pool ? pgMod : pgMod.default;
1895
+ const PoolCtor = pgExports.Pool;
1896
+ this.config.port = await ensureRunning(
1897
+ this.config,
1898
+ nodeDaemonDeps(this.config, pgExports.Client, {
1899
+ user: this.config.user,
1900
+ password: this.config.password,
1901
+ database: this.config.database
1902
+ })
1903
+ );
1671
1904
  const pool = new PoolCtor({
1672
1905
  host: this.config.host,
1673
1906
  port: this.config.port,
@@ -10,7 +10,7 @@ import {
10
10
  import {
11
11
  getBackend,
12
12
  upsertRecord
13
- } from "./chunk-VH46MAE4.js";
13
+ } from "./chunk-IMU2X3ZV.js";
14
14
 
15
15
  // src/commands/mem/migrate.ts
16
16
  import fs4 from "fs";