@go-labs-sg/bb 3.0.0 → 3.2.0

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/dist/index.js CHANGED
@@ -35,16 +35,16 @@ var __toESM = (mod, isNodeMode, target) => {
35
35
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
36
36
  var __require = import.meta.require;
37
37
 
38
- // ../../../node_modules/.bun/dotenv@18.0.7/node_modules/dotenv/dist/index.cjs
38
+ // ../../../node_modules/.bun/dotenv@18.0.8/node_modules/dotenv/dist/index.cjs
39
39
  var require_dist = __commonJS(function(exports, module) {
40
- var k = (e, n) => () => {
40
+ var j = (e, n) => () => {
41
41
  try {
42
42
  return n || e((n = { exports: {} }).exports, n), n.exports;
43
43
  } catch (t) {
44
44
  throw n = 0, t;
45
45
  }
46
46
  };
47
- var I = k((xe, U) => {
47
+ var k = j((xe, U) => {
48
48
  function G(e) {
49
49
  return typeof e == "string" ? !["false", "0", "no", "off", ""].includes(e.toLowerCase()) : !!e;
50
50
  }
@@ -58,8 +58,8 @@ var require_dist = __commonJS(function(exports, module) {
58
58
  }
59
59
  U.exports = { parseBoolean: G, optionsFromEnv: Y };
60
60
  });
61
- var N = k((ye, x) => {
62
- var z = __require("fs"), S = __require("path"), Z = __require("os"), { URL: ee, fileURLToPath: te } = __require("url"), { parseBoolean: $, optionsFromEnv: B } = I(), re = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg, b = new Uint8Array(256);
61
+ var N = j((ye, x) => {
62
+ var z = __require("fs"), I = __require("path"), Z = __require("os"), { URL: ee, fileURLToPath: te } = __require("url"), { parseBoolean: $, optionsFromEnv: B } = k(), re = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg, b = new Uint8Array(256);
63
63
  for (let e = 48;e <= 57; e++)
64
64
  b[e] = 1;
65
65
  for (let e = 65;e <= 90; e++)
@@ -124,7 +124,7 @@ var require_dist = __commonJS(function(exports, module) {
124
124
  r++;
125
125
  continue;
126
126
  }
127
- let p = t.slice(l, r), f = r;
127
+ let h = t.slice(l, r), f = r;
128
128
  if (r >= o && (d = 0), w(d))
129
129
  do
130
130
  r++, d = r < o ? t.charCodeAt(r) : 0;
@@ -141,8 +141,8 @@ var require_dist = __commonJS(function(exports, module) {
141
141
  let c = r, a = r;
142
142
  for (;a < o && w(t.charCodeAt(a)); )
143
143
  a++;
144
- let h = t.charCodeAt(a), g, y = false;
145
- if (h === 39 || h === 34 || h === 96) {
144
+ let g = t.charCodeAt(a), p, y = false;
145
+ if (g === 39 || g === 34 || g === 96) {
146
146
  let v = t[a], u = t.indexOf(v, a + 1), m = -1, C = -1;
147
147
  for (;u !== -1; ) {
148
148
  let O = t.charCodeAt(u - 1) === 92, E = u + 1;
@@ -153,7 +153,7 @@ var require_dist = __commonJS(function(exports, module) {
153
153
  u = t.indexOf(v, u + 1);
154
154
  }
155
155
  if (m !== -1) {
156
- if (g = t.slice(a + 1, m), r = C, t.charCodeAt(r) === 35)
156
+ if (p = t.slice(a + 1, m), r = C, t.charCodeAt(r) === 35)
157
157
  for (;r < o && !q(t.charCodeAt(r)); )
158
158
  r++;
159
159
  y = true;
@@ -175,12 +175,12 @@ var require_dist = __commonJS(function(exports, module) {
175
175
  for (;C > m && w(t.charCodeAt(C - 1)); )
176
176
  C--;
177
177
  let O = t.charCodeAt(m);
178
- if (C - m >= 2 && (O === 39 || O === 34 || O === 96) && t.charCodeAt(C - 1) === O ? g = t.slice(m + 1, C - 1) : g = t.slice(m, C), r = u, u < v)
178
+ if (p = t.slice(m, C), p.includes("\u2028") || p.includes("\u2029") ? p = p.replace(/^(['"`])([\s\S]*)\1$/mg, "$2") : C - m >= 2 && (O === 39 || O === 34 || O === 96) && t.charCodeAt(C - 1) === O && (p = t.slice(m + 1, C - 1)), r = u, u < v)
179
179
  for (;r < o && !q(t.charCodeAt(r)); )
180
180
  r++;
181
181
  }
182
- h === 34 && (y || a < r) && g.indexOf("\\") !== -1 && (g = g.replace(/\\n/g, `
183
- `).replace(/\\r/g, "\r")), n[p] = g;
182
+ g === 34 && (y || a < r) && p.indexOf("\\") !== -1 && (p = p.replace(/\\n/g, `
183
+ `).replace(/\\r/g, "\r")), n[h] = p;
184
184
  }
185
185
  return n;
186
186
  }
@@ -194,7 +194,7 @@ var require_dist = __commonJS(function(exports, module) {
194
194
  console.error(`\u25C7 ${e}`);
195
195
  }
196
196
  function V(e) {
197
- return e[0] === "~" ? S.join(Z.homedir(), e.slice(1)) : e;
197
+ return e[0] === "~" ? I.join(Z.homedir(), e.slice(1)) : e;
198
198
  }
199
199
  function ce(e = {}) {
200
200
  let n = { ...e };
@@ -204,7 +204,7 @@ var require_dist = __commonJS(function(exports, module) {
204
204
  }
205
205
  function ae(e) {
206
206
  e = ce(e);
207
- let n = S.resolve(process.cwd(), ".env"), t = "utf8", o = process.env;
207
+ let n = I.resolve(process.cwd(), ".env"), t = "utf8", o = process.env;
208
208
  e && e.processEnv != null && (o = e.processEnv);
209
209
  let r = $(e && e.debug);
210
210
  e && e.encoding ? t = e.encoding : r && T("no encoding is specified (UTF-8 is used by default)");
@@ -225,15 +225,15 @@ var require_dist = __commonJS(function(exports, module) {
225
225
  } catch (a) {
226
226
  r && T(`failed to load ${c} ${a.message}`), i = a;
227
227
  }
228
- let p = A.populate(o, l, e), f = $(Object.prototype.hasOwnProperty.call(e, "quiet") ? e.quiet : B(o).quiet);
228
+ let h = A.populate(o, l, e), f = $(Object.prototype.hasOwnProperty.call(e, "quiet") ? e.quiet : B(o).quiet);
229
229
  if (r || !f) {
230
- let c = Object.keys(p).length, a = [];
231
- for (let h of s)
230
+ let c = Object.keys(h).length, a = [];
231
+ for (let g of s)
232
232
  try {
233
- let g = S.relative(process.cwd(), h instanceof ee ? te(h) : h);
234
- a.push(g);
235
- } catch (g) {
236
- r && T(`failed to load ${h} ${g.message}`), i = g;
233
+ let p = I.relative(process.cwd(), g instanceof ee ? te(g) : g);
234
+ a.push(p);
235
+ } catch (p) {
236
+ r && T(`failed to load ${g} ${p.message}`), i = p;
237
237
  }
238
238
  ie(`injected env (${c}) from ${a.join(",")}`);
239
239
  }
@@ -259,7 +259,7 @@ var require_dist = __commonJS(function(exports, module) {
259
259
  x.exports.populate = A.populate;
260
260
  x.exports = A;
261
261
  });
262
- var M = k((Te, W) => {
262
+ var M = j((Te, W) => {
263
263
  var _ = __require("child_process"), ue = __require("fs"), L = __require("path");
264
264
  function de(e) {
265
265
  let n = ['"'], t = 0;
@@ -291,10 +291,10 @@ var require_dist = __commonJS(function(exports, module) {
291
291
  let o = (P(n, "PATHEXT") || ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean), s = o.some((l) => e.toLowerCase().endsWith(l.toLowerCase())) ? ["", ...o] : [...o, ""], i = /[\\/]/.test(e) ? [t] : [t, ...(P(n, "PATH") || "").split(";")];
292
292
  for (let l of i)
293
293
  for (let d of s) {
294
- let p = L.resolve(t, l.replace(/^"|"$/g, ""), e + d);
294
+ let h = L.resolve(t, l.replace(/^"|"$/g, ""), e + d);
295
295
  try {
296
- if (ue.statSync(p).isFile())
297
- return p;
296
+ if (ue.statSync(h).isFile())
297
+ return h;
298
298
  } catch {}
299
299
  }
300
300
  }
@@ -312,18 +312,18 @@ var require_dist = __commonJS(function(exports, module) {
312
312
  }
313
313
  W.exports = he;
314
314
  });
315
- var X = k(($e, F) => {
316
- var ge = __require("fs"), me = __require("os"), Q = __require("path"), ve = __require("child_process"), Ce = M(), R = N(), { optionsFromEnv: J } = I();
315
+ var X = j(($e, F) => {
316
+ var ge = __require("fs"), me = __require("os"), Q = __require("path"), ve = __require("child_process"), Ce = M(), R = N(), { optionsFromEnv: J } = k();
317
317
  function D() {
318
318
  console.log(["Usage: dotenv run [--help] [-q|--quiet] [--debug] [--override] [--fast] [-f|--file <paths>] [--] <command> [args...]", "", "Run a command with environment variables from a .env file.", "Place dotenv options before the command; all following arguments go to the command.", "", "Options:", " -f, --file <paths> .env paths, comma-separated or repeated (default: .env)", " -q, --quiet suppress the injected env message", " --debug enable debug logging", " --override override existing environment variables", " --fast use the faster character-scanner parser", "", "Environment variables (DOTENV_CONFIG_* names remain as fallbacks):", " DOTENV_PATH, DOTENV_ENCODING, DOTENV_QUIET,", " DOTENV_DEBUG, DOTENV_OVERRIDE,", " DOTENV_FAST"].join(`
319
319
  `));
320
320
  }
321
321
  function we(e) {
322
322
  let n = [], t = false, o, r, s, i, l = -1;
323
- for (let p = 0;p < e.length; p++) {
324
- let f = e[p];
323
+ for (let h = 0;h < e.length; h++) {
324
+ let f = e[h];
325
325
  if (f === "--") {
326
- l = p + 1;
326
+ l = h + 1;
327
327
  break;
328
328
  }
329
329
  if (f === "--help" || f === "-h")
@@ -345,18 +345,18 @@ var require_dist = __commonJS(function(exports, module) {
345
345
  continue;
346
346
  }
347
347
  if (f === "-f" || f === "--file" || f.startsWith("-f=") || f.startsWith("--file=")) {
348
- let c = f.indexOf("="), a = c === -1 ? f : f.slice(0, c), h = c === -1 ? e[++p] : f.slice(c + 1);
349
- if (!h || h === "--")
348
+ let c = f.indexOf("="), a = c === -1 ? f : f.slice(0, c), g = c === -1 ? e[++h] : f.slice(c + 1);
349
+ if (!g || g === "--")
350
350
  return { error: `${a} requires a path` };
351
- let g = h.split(",").map((y) => y.trim()).filter(Boolean);
352
- if (g.length === 0)
351
+ let p = g.split(",").map((y) => y.trim()).filter(Boolean);
352
+ if (p.length === 0)
353
353
  return { error: `${a} requires a path` };
354
- n.push(...g), t = true;
354
+ n.push(...p), t = true;
355
355
  continue;
356
356
  }
357
357
  if (f.startsWith("-"))
358
358
  return { error: `unknown option: ${f}` };
359
- l = p;
359
+ l = h;
360
360
  break;
361
361
  }
362
362
  let d = l === -1 ? [] : e.slice(l);
@@ -410,15 +410,15 @@ var require_dist = __commonJS(function(exports, module) {
410
410
  try {
411
411
  let c = be(o);
412
412
  if (!(o.quiet == null ? J().quiet : o.quiet)) {
413
- let h = `\u25C7 injected env (${Object.keys(c.injected).length})`;
414
- c.loadedPaths.length > 0 && (h += ` from ${c.loadedPaths.join(", ")}`), console.error(h);
413
+ let g = `\u25C7 injected env (${Object.keys(c.injected).length})`;
414
+ c.loadedPaths.length > 0 && (g += ` from ${c.loadedPaths.join(", ")}`), console.error(g);
415
415
  }
416
416
  } catch (c) {
417
417
  console.error(`dotenv: ${c.message}`), process.exitCode = 1;
418
418
  return;
419
419
  }
420
420
  let r = !!process.stdin.isTTY, s = process.platform !== "win32" && !r, i = Ce(t.command[0], t.command.slice(1), { stdio: "inherit", detached: s }), l = new Map, d = 0;
421
- function p(c) {
421
+ function h(c) {
422
422
  if (!(!i.pid || i.exitCode !== null || i.signalCode !== null)) {
423
423
  if (process.platform === "win32") {
424
424
  ve.spawnSync("taskkill", ["/pid", String(i.pid), "/T", "/F"], { stdio: "ignore" });
@@ -442,11 +442,11 @@ var require_dist = __commonJS(function(exports, module) {
442
442
  if (d++, r && process.platform !== "win32" && d === 1)
443
443
  return;
444
444
  if (d > 1) {
445
- p(d === 2 ? "SIGTERM" : "SIGKILL");
445
+ h(d === 2 ? "SIGTERM" : "SIGKILL");
446
446
  return;
447
447
  }
448
448
  }
449
- p(c);
449
+ h(c);
450
450
  };
451
451
  l.set(c, a), process.on(c, a);
452
452
  }
@@ -459,13 +459,13 @@ var require_dist = __commonJS(function(exports, module) {
459
459
  F.exports = K;
460
460
  F === __require.main && K(process.argv.slice(2));
461
461
  });
462
- var j = N();
462
+ var S = N();
463
463
  var qe = X();
464
- module.exports = j;
465
- module.exports.config = j.config;
466
- module.exports.configDotenv = j.configDotenv;
467
- module.exports.parse = j.parse;
468
- module.exports.populate = j.populate;
464
+ module.exports = S;
465
+ module.exports.config = S.config;
466
+ module.exports.configDotenv = S.configDotenv;
467
+ module.exports.parse = S.parse;
468
+ module.exports.populate = S.populate;
469
469
  });
470
470
 
471
471
  // src/load-env.ts
@@ -512,7 +512,7 @@ var createPkcePair = () => {
512
512
  verifier
513
513
  };
514
514
  };
515
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/util.js
515
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/util.js
516
516
  function getEnumValues(entries) {
517
517
  const numericValues = Object.values(entries).filter((v) => typeof v === "number");
518
518
  const values = Object.entries(entries).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_, v]) => v);
@@ -858,6 +858,18 @@ function prefixIssues(path, issues) {
858
858
  function unwrapMessage(message) {
859
859
  return typeof message === "string" ? message : message?.message;
860
860
  }
861
+ function sizeCaps(defChecks) {
862
+ const caps = [];
863
+ for (const ch of defChecks ?? []) {
864
+ const d = ch._zod.def;
865
+ if (!/_(length|size)$|_equals$/.test(d.check))
866
+ break;
867
+ const max = d.maximum ?? d.length ?? d.size;
868
+ if (max >= 0)
869
+ caps.push([max, ch]);
870
+ }
871
+ return caps;
872
+ }
861
873
  function attachSchema(issues, start, inst) {
862
874
  var _a;
863
875
  for (let i = start;i < issues.length; i++) {
@@ -1055,7 +1067,7 @@ function constantCatch(value) {
1055
1067
  return fn;
1056
1068
  }
1057
1069
 
1058
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/core.js
1070
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/core.js
1059
1071
  var _a;
1060
1072
  var _zodDesc = { value: undefined, enumerable: false };
1061
1073
  var _E = "captureStackTrace" in Error ? Error : null;
@@ -1173,7 +1185,7 @@ function config2(newConfig) {
1173
1185
  Object.assign(globalConfig, newConfig);
1174
1186
  return globalConfig;
1175
1187
  }
1176
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/errors.js
1188
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/errors.js
1177
1189
  function _getMessage() {
1178
1190
  const internals = this._zod;
1179
1191
  internals.message ?? (internals.message = JSON.stringify(internals.def, jsonStringifyReplacer, 2));
@@ -1288,7 +1300,7 @@ function formatError(error, mapper = (issue) => issue.message) {
1288
1300
  return fieldErrors;
1289
1301
  }
1290
1302
 
1291
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/parse.js
1303
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/parse.js
1292
1304
  function finalizeParams(callee, params) {
1293
1305
  return { callee: params?.callee ?? callee, Err: params?.Err };
1294
1306
  }
@@ -1435,7 +1447,7 @@ var _safeEncodeAsync = (_Err) => async (schema, value, _ctx) => {
1435
1447
  var _safeDecodeAsync = (_Err) => async (schema, value, _ctx) => {
1436
1448
  return _safeParseAsync(_Err)(schema, value, _ctx);
1437
1449
  };
1438
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/regexes.js
1450
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/regexes.js
1439
1451
  var cuid = /^[cC][0-9a-z]{6,}$/;
1440
1452
  var cuid2 = /^[0-9a-z]+$/;
1441
1453
  var ulid = /^[0-7][0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{25}$/;
@@ -1493,7 +1505,7 @@ var _null = /^null$/i;
1493
1505
  var lowercase = /^[^A-Z]*$/;
1494
1506
  var uppercase = /^[^a-z]*$/;
1495
1507
 
1496
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/checks.js
1508
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/checks.js
1497
1509
  var $ZodCheck = /* @__PURE__ */ $constructor("$ZodCheck", (inst, def) => {
1498
1510
  var _a;
1499
1511
  inst._zod ?? (inst._zod = {});
@@ -1809,7 +1821,7 @@ var $ZodCheckOverwrite = /* @__PURE__ */ $constructor("$ZodCheckOverwrite", (ins
1809
1821
  };
1810
1822
  });
1811
1823
 
1812
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/doc.js
1824
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/doc.js
1813
1825
  class Doc {
1814
1826
  constructor(args = [], closed = {}) {
1815
1827
  this.content = [];
@@ -1851,14 +1863,14 @@ ${content.join(`
1851
1863
  }
1852
1864
  }
1853
1865
 
1854
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/versions.js
1866
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/versions.js
1855
1867
  var version = {
1856
1868
  major: 4,
1857
1869
  minor: 6,
1858
- patch: 5
1870
+ patch: 7
1859
1871
  };
1860
1872
 
1861
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/schemas.js
1873
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/schemas.js
1862
1874
  var $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
1863
1875
  var _a;
1864
1876
  inst ?? (inst = {});
@@ -2424,6 +2436,29 @@ var $ZodNever = /* @__PURE__ */ $constructor("$ZodNever", (inst, def) => {
2424
2436
  return payload;
2425
2437
  };
2426
2438
  });
2439
+ function capSize(inst, size) {
2440
+ const caps = sizeCaps(inst._zod.def.checks);
2441
+ if (!caps.length)
2442
+ return;
2443
+ const cap = Math.min(...caps.map((c) => c[0]));
2444
+ const parse = inst._zod.parse;
2445
+ inst._zod.parse = (payload, ctx) => {
2446
+ const n = size(payload.value);
2447
+ if (n > cap && !ctx?.skipChecks && ctx?.direction !== "backward") {
2448
+ for (const [max, ch] of sizeCaps(inst._zod.def.checks)) {
2449
+ if (n > max && ch._zod.def.when(payload)) {
2450
+ const start = payload.issues.length;
2451
+ ch._zod.check(payload);
2452
+ payload.issues[start].continue = false;
2453
+ attachSchema(payload.issues, start, inst);
2454
+ return payload;
2455
+ }
2456
+ }
2457
+ }
2458
+ return parse(payload, ctx);
2459
+ };
2460
+ }
2461
+ var arraySize = (input) => Array.isArray(input) ? input.length : -1;
2427
2462
  function handleArrayResult(result, final, index) {
2428
2463
  if (result.issues.length) {
2429
2464
  final.issues.push(...prefixIssues(index, result.issues));
@@ -2467,6 +2502,7 @@ var $ZodArray = /* @__PURE__ */ $constructor("$ZodArray", (inst, def) => {
2467
2502
  }
2468
2503
  return payload;
2469
2504
  };
2505
+ capSize(inst, arraySize);
2470
2506
  });
2471
2507
  function handlePropertyResult(result, final, key, input, optin, optout) {
2472
2508
  const isPresent = key in input;
@@ -3249,7 +3285,7 @@ function handleRefineResult(result, payload, input, inst) {
3249
3285
  payload.issues.push(issue(_iss));
3250
3286
  }
3251
3287
  }
3252
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/memoizer.js
3288
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/memoizer.js
3253
3289
  class $ZodCyclicError extends Error {
3254
3290
  constructor() {
3255
3291
  super(`Cannot parse a reference cycle that closes through a transform`);
@@ -3518,7 +3554,7 @@ function isBackEdge(ctx, value) {
3518
3554
  const backEdges = ctx[STATE]?.backEdges;
3519
3555
  return backEdges !== undefined && isRef(value) && backEdges.has(value);
3520
3556
  }
3521
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/locales/en.js
3557
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/locales/en.js
3522
3558
  var error = () => {
3523
3559
  const Sizable = {
3524
3560
  string: { unit: "characters", verb: "to have" },
@@ -3640,7 +3676,7 @@ function en_default() {
3640
3676
  localeError: error()
3641
3677
  };
3642
3678
  }
3643
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/registries.js
3679
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/registries.js
3644
3680
  var _a2;
3645
3681
  class $ZodRegistry {
3646
3682
  constructor() {
@@ -3687,7 +3723,7 @@ function registry() {
3687
3723
  }
3688
3724
  (_a2 = globalThis).__zod_globalRegistry ?? (_a2.__zod_globalRegistry = registry());
3689
3725
  var globalRegistry = globalThis.__zod_globalRegistry;
3690
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/api.js
3726
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/api.js
3691
3727
  function snapshotChecks(def) {
3692
3728
  if (def.checks)
3693
3729
  def.checks = [...def.checks];
@@ -4141,7 +4177,7 @@ function _check(fn, params) {
4141
4177
  ch._zod.check = fn;
4142
4178
  return ch;
4143
4179
  }
4144
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/to-json-schema.js
4180
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/to-json-schema.js
4145
4181
  function assignProps(target, ...sources) {
4146
4182
  for (const source of sources) {
4147
4183
  for (const key of Reflect.ownKeys(source)) {
@@ -4664,7 +4700,7 @@ var createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params) =
4664
4700
  extractDefs(ctx, schema);
4665
4701
  return finalize(ctx, schema);
4666
4702
  };
4667
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/json-schema-processors.js
4703
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/json-schema-processors.js
4668
4704
  var narrowMin = (agg, key, value) => {
4669
4705
  if (agg[key] === undefined || value > agg[key])
4670
4706
  agg[key] = value;
@@ -5093,7 +5129,7 @@ var optionalProcessor = (schema, ctx, _json, params) => {
5093
5129
  const seen = ctx.seen.get(schema);
5094
5130
  seen.ref = def.innerType;
5095
5131
  };
5096
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/classic/errors.js
5132
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/classic/errors.js
5097
5133
  var _installedErrorProtos = /* @__PURE__ */ new WeakSet([Object.prototype, Error.prototype]);
5098
5134
  function _lazyMethod(proto, key, make) {
5099
5135
  Object.defineProperty(proto, key, {
@@ -5138,7 +5174,7 @@ var ZodRealError = /* @__PURE__ */ $constructor("ZodError", initializer2, undefi
5138
5174
  Parent: Error
5139
5175
  });
5140
5176
 
5141
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/classic/parse.js
5177
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/classic/parse.js
5142
5178
  var parse2 = /* @__PURE__ */ _parse(ZodRealError);
5143
5179
  var parseAsync = /* @__PURE__ */ _parseAsync(ZodRealError);
5144
5180
  var safeParse = /* @__PURE__ */ _safeParse(ZodRealError);
@@ -5152,7 +5188,7 @@ var safeDecode = /* @__PURE__ */ _safeDecode(ZodRealError);
5152
5188
  var safeEncodeAsync = /* @__PURE__ */ _safeEncodeAsync(ZodRealError);
5153
5189
  var safeDecodeAsync = /* @__PURE__ */ _safeDecodeAsync(ZodRealError);
5154
5190
 
5155
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/classic/schemas.js
5191
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/classic/schemas.js
5156
5192
  function _ensureDefaultLocale() {
5157
5193
  if (!globalConfig.localeError)
5158
5194
  config2(en_default());
@@ -7687,7 +7723,7 @@ var parseQuotationReferences = (input, commandName) => {
7687
7723
  const allocation = requireObject(raw, label);
7688
7724
  const amount = Number(allocation.amount);
7689
7725
  if (!Number.isFinite(amount) || amount < 0 || !Number.isInteger(amount * 100)) {
7690
- throw validationError(`${label}.amount must be a non-negative cent value.`);
7726
+ throw validationError(`${label}.amount must be a non-negative dollar amount (ex-GST) with at most 2 decimal places.`);
7691
7727
  }
7692
7728
  return {
7693
7729
  budgetItemId: requiredString(allocation.budgetItemId, `${label}.budgetItemId`),
@@ -7740,7 +7776,7 @@ var parseBillLineAmounts = (input, commandName) => {
7740
7776
  const line = requireObject(raw, label);
7741
7777
  const amount = Number(line.amount);
7742
7778
  if (!Number.isFinite(amount) || amount < 0 || !Number.isInteger(amount * 100)) {
7743
- throw validationError(`${label}.amount must be a non-negative cent value.`);
7779
+ throw validationError(`${label}.amount must be a non-negative dollar amount (ex-GST) with at most 2 decimal places.`);
7744
7780
  }
7745
7781
  return {
7746
7782
  budgetItemId: requiredString(line.budgetItemId, `${label}.budgetItemId`),
@@ -9230,7 +9266,7 @@ async function updateBillStatus(opts) {
9230
9266
  entity: `bill ${opts.id}`,
9231
9267
  details: `to ${opts.status}`
9232
9268
  });
9233
- const bill = opts.paymentProofPath ? await api2.bill.getById.query({ id: opts.id }) : null;
9269
+ const bill = opts.paymentProofPath ? await api2.bill.getPayment.query({ id: opts.id }) : null;
9234
9270
  const paymentProof = bill && opts.paymentProofPath ? await stageBillPaymentProof(bill.projectId, opts.paymentProofPath) : undefined;
9235
9271
  try {
9236
9272
  const result = await api2.bill.updateStatus.mutate({
@@ -9260,7 +9296,7 @@ var recordExternalBillPayment = async (opts) => {
9260
9296
  entity: `bill ${opts.id}`,
9261
9297
  details: `already paid on ${opts.paymentDate}; reference ${opts.paymentReference}; QBO account ${opts.paymentAccount}. No money is transferred.`
9262
9298
  });
9263
- const bill = await api2.bill.getById.query({ id: opts.id });
9299
+ const bill = await api2.bill.getPayment.query({ id: opts.id });
9264
9300
  const proof = !bill.externalPayment && opts.paymentProofPath ? await stageBillPaymentProof(bill.projectId, opts.paymentProofPath) : undefined;
9265
9301
  try {
9266
9302
  out(await api2.bill.recordExternalPayment.mutate({
@@ -9272,7 +9308,7 @@ var recordExternalBillPayment = async (opts) => {
9272
9308
  }));
9273
9309
  } catch (error) {
9274
9310
  try {
9275
- const latest = await api2.bill.getById.query({ id: opts.id });
9311
+ const latest = await api2.bill.getPayment.query({ id: opts.id });
9276
9312
  if (latest.externalPayment?.paymentAccount === opts.paymentAccount && latest.paymentReference === opts.paymentReference.trim() && latest.paymentDate?.toISOString().slice(0, 10) === opts.paymentDate) {
9277
9313
  out({
9278
9314
  ...latest,
@@ -9309,6 +9345,15 @@ async function patchBillInvoiceNumber(id, invoiceNumber) {
9309
9345
  var getBillAttachments = async (input) => {
9310
9346
  out(await api2.bill.getAttachments.query(input));
9311
9347
  };
9348
+ var getBillApprovals = async (input) => {
9349
+ out(await api2.bill.getApprovals.query(input));
9350
+ };
9351
+ var getBillLineItems = async (input) => {
9352
+ out(await api2.bill.getLineItems.query(input));
9353
+ };
9354
+ var getBillPayment = async (id) => {
9355
+ out(await api2.bill.getPayment.query({ id }));
9356
+ };
9312
9357
  async function stageBillAttachmentsFromPaths(projectId, filePaths) {
9313
9358
  const attachments = [];
9314
9359
  for (const filePath of filePaths) {
@@ -9867,6 +9912,9 @@ async function getQuotationDetails(id) {
9867
9912
  const result = await api2.quotation.getById.query({ id });
9868
9913
  out(result);
9869
9914
  }
9915
+ var getQuotationLineItems = async (input) => {
9916
+ out(await api2.quotation.getLineItems.query(input));
9917
+ };
9870
9918
  async function createQuotationFromPayload(raw) {
9871
9919
  const input = parseCreateQuotationPayload(raw);
9872
9920
  const result = await api2.quotation.createDraft.mutate(input);
@@ -9935,6 +9983,18 @@ var getCustomerInvoice = async (batchId) => {
9935
9983
  const result = await api2.customerInvoice.getInvoiceDetail.query({ batchId });
9936
9984
  out(result);
9937
9985
  };
9986
+ var getCustomerInvoiceInvoices = async (batchId) => {
9987
+ out(await api2.customerInvoice.getInvoices.query({ batchId }));
9988
+ };
9989
+ var getCustomerInvoiceLines = async (input) => {
9990
+ out(await api2.customerInvoice.getInvoiceLines.query(input));
9991
+ };
9992
+ var getCustomerInvoiceApprovals = async (input) => {
9993
+ out(await api2.customerInvoice.getApprovals.query(input));
9994
+ };
9995
+ var getCustomerInvoiceHistory = async (input) => {
9996
+ out(await api2.customerInvoice.getHistory.query(input));
9997
+ };
9938
9998
  var getCustomerInvoiceEmailContext = async (batchId) => {
9939
9999
  const result = await api2.customerInvoice.getInvoiceEmailContext.query({
9940
10000
  batchId
@@ -10817,6 +10877,9 @@ async function getFinancialOverview(input) {
10817
10877
  var getRecentErrors = async (input) => {
10818
10878
  out(await api2.errorLog.getRecentErrors.query(input));
10819
10879
  };
10880
+ var getError = async (errorId) => {
10881
+ out(await api2.errorLog.getErrorById.query({ errorId }));
10882
+ };
10820
10883
  var countErrors = async (input) => {
10821
10884
  out(await api2.errorLog.countErrors.query(input));
10822
10885
  };
@@ -11013,7 +11076,7 @@ var payloadHelp = {
11013
11076
  },
11014
11077
  "update-project": {
11015
11078
  required: "id: string; name: string; companyId: string; contactPersonId: string; asanaTaskId: string; insideSalesId: string; businessDevelopmentId: string; venue: string; dateRange: {from: ISO date}",
11016
- optional: "dateRange.to: ISO date; projectManagerId: string; pax: string; description: string; slackChannelId/slackChannelUrl/slackChannelName: strings (supply all three); requestQboAccountantNotification: boolean; confirmEstimateInvalidation: boolean",
11079
+ optional: "dateRange.to: ISO date; projectManagerId: string; pax: string; description: string; slackChannelId/slackChannelUrl/slackChannelName: strings (supply all three); requestQboAccountantNotification: boolean; confirmEstimateInvalidation: boolean. Changing companyId requires a contactPersonId from the new company; the company change itself does not reject existing estimates or touch existing invoices, but date, pax or venue changes in the same save still require confirmEstimateInvalidation.",
11017
11080
  example: '{"id":"<project-id>","name":"Launch","companyId":"<company-id>","contactPersonId":"<contact-id>","asanaTaskId":"<asana-task-id>","insideSalesId":"<user-id>","businessDevelopmentId":"<user-id>","venue":"Hall","dateRange":{"from":"2026-10-01T09:00:00Z"}}'
11018
11081
  },
11019
11082
  "create-supplier": {
@@ -11329,6 +11392,28 @@ var summaryFor = (legacyTarget) => {
11329
11392
  return "Approve your assigned pending quotation as a current Admin. Claim the captured revision and exact allocation selection after signing; concurrent changes conflict and roll back the decision, signed attachment and email/outbox. Refresh and review the current content before retrying.";
11330
11393
  if (legacyTarget === "approve-supplier")
11331
11394
  return "Approve a pending supplier request and send a requester reply email, or directly re-approve a rejected supplier as Admin/Lead without a pending request or email. QuickBooks is synchronized; archived suppliers remain archived. Argument: <supplierId>.";
11395
+ if (legacyTarget === "get-bill-details")
11396
+ return "Get a bill's summary as shown in the web app: status, amounts, people, payment and line totals. Use get-bill-line-items, get-bill-approvals, get-bill-attachments or get-bill-payment for more detail. Argument: <billId>.";
11397
+ if (legacyTarget === "get-bill-line-items")
11398
+ return "List a bill's line items with budget-item and quotation-allocation detail. <billId> [--limit 1-100] [--cursor <token>] Newest first. Returns { items, pageInfo }; follow nextCursor.";
11399
+ if (legacyTarget === "get-bill-approvals")
11400
+ return "List a bill's approval requests with approver, requester and responder. <billId> [--limit 1-50] [--cursor <token>] Newest first. Returns { items, pageInfo }; follow nextCursor.";
11401
+ if (legacyTarget === "get-bill-payment")
11402
+ return "Get a bill's payment status, reference, date, tracking URL, QuickBooks link and external payment. Argument: <billId>.";
11403
+ if (legacyTarget === "get-quotation")
11404
+ return "Get a quotation as shown in the web app: status, amounts, people, line totals, files and approvals. Use get-quotation-line-items for budget-item detail. Argument: <quotationId>.";
11405
+ if (legacyTarget === "get-customer-invoice")
11406
+ return "Get an invoice batch as shown in the web app: status, totals, people, approvals and invoice summaries. Use get-customer-invoice-invoices, get-customer-invoice-lines, get-customer-invoice-approvals or get-customer-invoice-history for more detail. Argument: <batchId>.";
11407
+ if (legacyTarget === "get-customer-invoice-invoices")
11408
+ return "List a batch's invoices with QuickBooks id/doc number, issue/due dates, amounts, sync state and sender. Argument: <batchId>.";
11409
+ if (legacyTarget === "get-customer-invoice-lines")
11410
+ return "List one invoice's lines (name, description, QuickBooks item/tax code, quantity, amounts). <invoiceId> [--limit 1-100] [--cursor <token>] Newest first. Returns { items, pageInfo }; follow nextCursor.";
11411
+ if (legacyTarget === "get-customer-invoice-approvals")
11412
+ return "List an invoice batch's approval requests with approver, requester and responder. <batchId> [--limit 1-50] [--cursor <token>] Newest first. Returns { items, pageInfo }; follow nextCursor.";
11413
+ if (legacyTarget === "get-customer-invoice-history")
11414
+ return "List an invoice batch's status history (batch/invoice status changes, source, note, actor). <batchId> [--limit 1-100] [--cursor <token>] Newest first. Returns { items, pageInfo }; follow nextCursor.";
11415
+ if (legacyTarget === "get-quotation-line-items")
11416
+ return "List a quotation's line items with budget-item, supplier and budget detail. <quotationId> [--limit 1-100] [--cursor <token>] Newest first. Returns { items, pageInfo }; follow nextCursor.";
11332
11417
  if (legacyTarget === "get-bill-attachments")
11333
11418
  return "List bill attachments with cursor pagination. <billId> [--limit 1-50] [--cursor <token>] Newest first. Returns { items, pageInfo }; follow nextCursor.";
11334
11419
  if (legacyTarget === "get-budget-categories")
@@ -11388,10 +11473,12 @@ var summaryFor = (legacyTarget) => {
11388
11473
  return "List one cursor page of active item categories ({ items, pageInfo }; --limit/--cursor/--direction, optional --name/--sortBy/--sortDir). --page/--perPage are rejected.";
11389
11474
  if (legacyTarget === "count-item-categories")
11390
11475
  return "Count active item categories matching --name: { totalCount }.";
11476
+ if (legacyTarget === "list-webhook-deliveries")
11477
+ return "Admin-only: list webhook deliveries newest first. Returns { items, pageInfo }; follow pageInfo.nextCursor (or previousCursor with --direction backward). Cursors are opaque and filter-bound; raw delivery ids are rejected.";
11391
11478
  if (legacyTarget === "list-integration-operations")
11392
11479
  return "List one cursor page of integration operations, newest first ({ items, pageInfo }; --limit/--cursor/--direction). --page/--perPage are rejected. Admin only.";
11393
11480
  if (legacyTarget === "count-integration-operations")
11394
- return "Count integration operations matching filters: { totalCount, filterOptions }. Admin only.";
11481
+ return "Provider filter options for integration operations: { filterOptions }. No total; filter flags are accepted but do not change the result. Admin only.";
11395
11482
  if (legacyTarget === "count-items")
11396
11483
  return "Count catalogue items matching filters: total plus category and supplier facets (each ignores its own filter).";
11397
11484
  if (legacyTarget === "count-budgets")
@@ -11406,17 +11493,17 @@ var summaryFor = (legacyTarget) => {
11406
11493
  return "Get budget details. Omit --includeInactive for active budgets only; --includeInactive is an Admin-only historical read.";
11407
11494
  }
11408
11495
  if (legacyTarget === "create-bill") {
11409
- return "Create a bill or claim with an approved supplier. All amount fields exclude GST: amount is the portion billed; extractedAmount is the full invoice subtotal; lineAmounts and quotationAllocations also exclude GST. Example: 1800 + 162 GST = 1962 total requires amount=1800 and extractedAmount=1800 for a full bill. The CLI does not strip GST from input. --draft-only guarantees DRAFT without email or external writes; otherwise unpaid creation skips email permission but keeps external-write permission.";
11496
+ return "Create a bill or claim with an approved supplier. All amount fields exclude GST: amount is the portion billed; extractedAmount is the full invoice subtotal; lineAmounts and quotationAllocations also exclude GST. Example: 1800 + 162 GST = 1962 total requires amount=1800 and extractedAmount=1800 for a full bill. The CLI does not strip GST from input. If the selected quotations cannot split the bill amount across every selected line (a line without a quoted amount that cannot be derived from the quotation total), pass lineAmounts; updates that keep the same amount and lines reuse the existing line amounts. --draft-only guarantees DRAFT without email or external writes; otherwise unpaid creation skips email permission but keeps external-write permission.";
11410
11497
  }
11411
11498
  if (legacyTarget === "record-external-bill-payment")
11412
11499
  return "Record an already-made payment on an APPROVED bill or claim, with no email and no money transfer. Requires <billId> --paymentReference --paymentDate YYYY-MM-DD --paymentAccount <QBO account ID> [--paymentProof receipt.pdf]. Reuses settled QBO payment links or queues one dated payment from the selected account. Exact retries are safe; do not pay again while reconciliation is pending.";
11413
11500
  if (legacyTarget === "list-external-payment-accounts")
11414
11501
  return "List active QuickBooks bank and credit-card account IDs for recording external payments (admin only).";
11415
11502
  if (legacyTarget === "update-bill") {
11416
- return "Update a bill or claim with a partial payload including id; omitted fields are preserved. Comment-only updates are allowed on approved/paid bills without altering financial data or QuickBooks. All amount fields exclude GST: amount is the portion billed; extractedAmount is the full invoice subtotal; lineAmounts and quotationAllocations also exclude GST. Example: 1800 + 162 GST = 1962 total requires amount=1800 and extractedAmount=1800 for a full bill. The CLI does not strip GST from input. Re-read and verify both amount fields and allocations after correcting a gross/net mistake.";
11503
+ return "Update a bill or claim with a partial payload including id; omitted fields are preserved. Comment-only updates are allowed on approved/paid bills without altering financial data or QuickBooks. All amount fields exclude GST: amount is the portion billed; extractedAmount is the full invoice subtotal; lineAmounts and quotationAllocations also exclude GST. Example: 1800 + 162 GST = 1962 total requires amount=1800 and extractedAmount=1800 for a full bill. The CLI does not strip GST from input. If the selected quotations cannot split the bill amount across every selected line (a line without a quoted amount that cannot be derived from the quotation total), pass lineAmounts; updates that keep the same amount and lines reuse the existing line amounts. Re-read and verify both amount fields and allocations after correcting a gross/net mistake.";
11417
11504
  }
11418
11505
  if (legacyTarget === "validate-bill-selection") {
11419
- return "Validate the approved supplier and selected bill line items.";
11506
+ return "Validate the approved supplier and selected bill line items. Supplier bills need approved quotation sources (quotationIds, legacy quotationId, or quotationAllocations with lineAmounts) for every line that is not quotation-exempt (Go Internal lines, or projects/budgets created before the quotation cutoff). With billId, lines already on the bill keep their stored sources unless new sources are supplied. Exemption is decided by the server, so there is no --quotation-exempt flag here. Amounts (amount, lineAmounts, quotationAllocations) are ex-GST dollars with at most 2 decimal places.";
11420
11507
  }
11421
11508
  if (legacyTarget === "create-quotation") {
11422
11509
  return 'Create a quotation with an approved supplier using --payload JSON. Include projectId, budgetId, supplierId, budgetItemIds, amountWithoutGst, gstAmount, and one uploaded attachment in attachments. Multiple budget items require lineAmounts: [{"budgetItemId":"<first-id>","amount":750},{"budgetItemId":"<second-id>","amount":450}], covering every selected budget-item ID exactly once and summing to amountWithoutGst. Amounts exclude GST; use gstAmount: 0 for no GST. Example: amountWithoutGst: 1200 with line amounts 750 and 450.';
@@ -11446,6 +11533,8 @@ var summaryFor = (legacyTarget) => {
11446
11533
  return "Admin-only: send a signed webhook.test event to one endpoint. Argument: <endpointId>.";
11447
11534
  if (legacyTarget === "replay-webhook-delivery")
11448
11535
  return "Admin-only: resend a finished webhook delivery with the same eventId on a fresh attempt chain. Argument: <deliveryId>.";
11536
+ if (legacyTarget === "get-error")
11537
+ return "Admin-only: one error log with full diagnostics (stack, cause, request details, metadata, AI summary, resolution). Argument: <errorId>. error recent list returns table columns only.";
11449
11538
  if (legacyTarget === "get-webhook-delivery")
11450
11539
  return "Admin-only: one webhook delivery with payload and attempts (status codes, errors, durations). Argument: <deliveryId>.";
11451
11540
  if (legacyTarget === "list-webhook-event-types")
@@ -11732,6 +11821,27 @@ var registry2 = [
11732
11821
  ]),
11733
11822
  legacyCommand("attach-bill-documents", ["bill", "document", "attach"]),
11734
11823
  legacyCommand("get-bill-details", ["bill", "get"]),
11824
+ legacyCommand("get-bill-line-items", ["bill", "line-item", "list"], [], [
11825
+ {
11826
+ name: "--limit <1-100>",
11827
+ description: "Rows per page. Output is { items, pageInfo }."
11828
+ },
11829
+ {
11830
+ name: "--cursor <token>",
11831
+ description: "pageInfo.nextCursor from the last page, unchanged; pages forward only."
11832
+ }
11833
+ ]),
11834
+ legacyCommand("get-bill-approvals", ["bill", "approval", "list"], [], [
11835
+ {
11836
+ name: "--limit <1-50>",
11837
+ description: "Rows per page. Output is { items, pageInfo }."
11838
+ },
11839
+ {
11840
+ name: "--cursor <token>",
11841
+ description: "pageInfo.nextCursor from the last page, unchanged; pages forward only."
11842
+ }
11843
+ ]),
11844
+ legacyCommand("get-bill-payment", ["bill", "payment", "get"]),
11735
11845
  legacyCommand("list-quotations", ["quotation", "list"], [], [
11736
11846
  {
11737
11847
  name: "--limit <1-100>",
@@ -11748,6 +11858,16 @@ var registry2 = [
11748
11858
  ]),
11749
11859
  legacyCommand("count-quotations", ["quotation", "count"]),
11750
11860
  legacyCommand("get-quotation", ["quotation", "get"]),
11861
+ legacyCommand("get-quotation-line-items", ["quotation", "line-item", "list"], [], [
11862
+ {
11863
+ name: "--limit <1-100>",
11864
+ description: "Rows per page. Output is { items, pageInfo }."
11865
+ },
11866
+ {
11867
+ name: "--cursor <token>",
11868
+ description: "pageInfo.nextCursor from the last page, unchanged; pages forward only."
11869
+ }
11870
+ ]),
11751
11871
  legacyCommand("upload-quotation-attachment", [
11752
11872
  "quotation",
11753
11873
  "attachment",
@@ -11814,6 +11934,41 @@ var registry2 = [
11814
11934
  ]),
11815
11935
  legacyCommand("count-customer-invoices", ["customer-invoice", "count"]),
11816
11936
  legacyCommand("get-customer-invoice", ["customer-invoice", "get"]),
11937
+ legacyCommand("get-customer-invoice-invoices", [
11938
+ "customer-invoice",
11939
+ "invoice",
11940
+ "list"
11941
+ ]),
11942
+ legacyCommand("get-customer-invoice-lines", ["customer-invoice", "line", "list"], [], [
11943
+ {
11944
+ name: "--limit <1-100>",
11945
+ description: "Rows per page. Output is { items, pageInfo }."
11946
+ },
11947
+ {
11948
+ name: "--cursor <token>",
11949
+ description: "pageInfo.nextCursor from the last page, unchanged; pages forward only."
11950
+ }
11951
+ ]),
11952
+ legacyCommand("get-customer-invoice-approvals", ["customer-invoice", "approval", "list"], [], [
11953
+ {
11954
+ name: "--limit <1-50>",
11955
+ description: "Rows per page. Output is { items, pageInfo }."
11956
+ },
11957
+ {
11958
+ name: "--cursor <token>",
11959
+ description: "pageInfo.nextCursor from the last page, unchanged; pages forward only."
11960
+ }
11961
+ ]),
11962
+ legacyCommand("get-customer-invoice-history", ["customer-invoice", "history", "list"], [], [
11963
+ {
11964
+ name: "--limit <1-100>",
11965
+ description: "Rows per page. Output is { items, pageInfo }."
11966
+ },
11967
+ {
11968
+ name: "--cursor <token>",
11969
+ description: "pageInfo.nextCursor from the last page, unchanged; pages forward only."
11970
+ }
11971
+ ]),
11817
11972
  legacyCommand("get-customer-invoice-email-context", [
11818
11973
  "customer-invoice",
11819
11974
  "email-context",
@@ -12293,6 +12448,7 @@ var registry2 = [
12293
12448
  description: "Same filters as error recent list; returns independent totalCount."
12294
12449
  }
12295
12450
  ]),
12451
+ legacyCommand("get-error", ["error", "get"]),
12296
12452
  legacyCommand("get-error-metrics", ["error", "metrics", "get"]),
12297
12453
  legacyCommand("list-integration-operations", ["integration", "operation", "list"], [], [
12298
12454
  {
@@ -12336,7 +12492,32 @@ var registry2 = [
12336
12492
  legacyCommand("delete-webhook-endpoint", ["webhook", "endpoint", "delete"]),
12337
12493
  legacyCommand("rotate-webhook-secret", ["webhook", "secret", "rotate"]),
12338
12494
  legacyCommand("send-webhook-test-event", ["webhook", "endpoint", "test"]),
12339
- legacyCommand("list-webhook-deliveries", ["webhook", "delivery", "list"]),
12495
+ legacyCommand("list-webhook-deliveries", ["webhook", "delivery", "list"], [], [
12496
+ {
12497
+ name: "--endpointId <id>",
12498
+ description: "Only deliveries to this endpoint."
12499
+ },
12500
+ {
12501
+ name: "--status <PENDING|SUCCEEDED|FAILED,...>",
12502
+ description: "Comma-separated delivery statuses."
12503
+ },
12504
+ {
12505
+ name: "--eventType <type>",
12506
+ description: "Exact event type, e.g. bill.approved."
12507
+ },
12508
+ {
12509
+ name: "--limit <n>",
12510
+ description: "Rows per cursor page (1..100; default 20)."
12511
+ },
12512
+ {
12513
+ name: "--cursor <token>",
12514
+ description: "Opaque token from pageInfo.nextCursor or pageInfo.previousCursor; bound to the same filters."
12515
+ },
12516
+ {
12517
+ name: "--direction <value>",
12518
+ description: "forward or backward (default forward; backward requires cursor)."
12519
+ }
12520
+ ]),
12340
12521
  legacyCommand("get-webhook-delivery", ["webhook", "delivery", "get"]),
12341
12522
  legacyCommand("replay-webhook-delivery", ["webhook", "delivery", "replay"]),
12342
12523
  legacyCommand("list-inbound-sources", ["inbound", "source", "list"], [], [
@@ -12921,6 +13102,24 @@ var rejectRetiredPageFlags = (flags) => {
12921
13102
  throw new Error(`--${key} is retired; use --limit/--cursor, or the matching count command for totals.`);
12922
13103
  }
12923
13104
  };
13105
+ var parseDetailFeedPage = (command, idLabel, positional, flags, maxLimit) => {
13106
+ const id = positional[0];
13107
+ if (!id)
13108
+ throw new Error(`${command} requires ${idLabel}`);
13109
+ rejectRetiredPageFlags(flags);
13110
+ for (const key of ["limit", "cursor"])
13111
+ rejectBareFlag(flags, key);
13112
+ if (flags.direction !== undefined)
13113
+ throw new Error(`${command} pages forward only; follow pageInfo.nextCursor with --cursor.`);
13114
+ const cursor = getFlag(flags, "cursor");
13115
+ if (cursor === "" || (cursor?.length ?? 0) > 8192)
13116
+ throw new Error("--cursor must be a non-empty opaque token of at most 8192 characters.");
13117
+ const limitFlag = getFlag(flags, "limit");
13118
+ const limit = limitFlag === undefined ? undefined : Number(limitFlag);
13119
+ if (limit !== undefined && (!Number.isInteger(limit) || limit < 1 || limit > maxLimit))
13120
+ throw new Error(`--limit must be an integer from 1 to ${maxLimit}.`);
13121
+ return { id, limit, cursor };
13122
+ };
12924
13123
  var parseBillFilterFlags = (flags) => {
12925
13124
  const statusRaw = getFlag(flags, "status");
12926
13125
  const createdByIdsRaw = getFlag(flags, "createdByIds");
@@ -13201,13 +13400,17 @@ Bills
13201
13400
  upload-bill-attachment <billId> <filePath...> [--file <path>] [--files <csv>] Attach invoice/supporting files as BILL attachments to any bill status, including PAID bills
13202
13401
  attach-bill-payment-receipt <billId> <filePath...> [--file <path>] [--files <csv>] Attach Wise/payment-proof PDFs as BILL_PAYMENT_PROOF attachments
13203
13402
  attach-bill-documents <billId> [--invoice <path>] [--invoices <csv>] [--paymentProof|--payment-proof|--proof <path>] [--paymentProofs|--payment-proofs|--proofs <csv>] Attach invoice and/or payment proof files with separate BB attachment types
13204
- get-bill-details <billId>
13403
+ get-bill-details <billId> Bill summary as shown in the web app (status, amounts, people, payment, line totals)
13404
+ get-bill-line-items <billId> [--limit 1-100] [--cursor <token>] Line items with budget-item/quotation detail; { items, pageInfo }
13405
+ get-bill-approvals <billId> [--limit 1-50] [--cursor <token>] Approval requests with approver/requester/responder; { items, pageInfo }
13406
+ get-bill-payment <billId> Payment status, reference, date, tracking URL, QuickBooks link and external payment
13205
13407
 
13206
13408
  Quotations
13207
13409
  list-quotations [--projectId] [--budgetId] [--supplierId] [--status CSV] [--createdBy CSV] [--search] [--limit 1-100] [--cursor <token>] [--direction forward|backward]
13208
13410
  Newest first; returns { items, pageInfo }. Follow nextCursor/previousCursor with the same filters. --page/--pageSize/--perPage are rejected; --requesterIds remains an alias for --createdBy.
13209
13411
  count-quotations [--projectId] [--budgetId] [--supplierId] [--status CSV] [--createdBy CSV] [--search] [--includeMetrics true|false] totalCount, status facets (ignore --status) and optional amount metrics
13210
- get-quotation <quotationId>
13412
+ get-quotation <quotationId> Quotation as shown in the web app (status, amounts, people, line totals, files, approvals)
13413
+ get-quotation-line-items <quotationId> [--limit 1-100] [--cursor <token>] Line items with budget-item detail; { items, pageInfo }
13211
13414
  upload-quotation-attachment <projectId> <filePath> Upload one PDF, JPEG, or PNG up to 20MB; returns attachment JSON for a quotation payload.
13212
13415
  cleanup-staged-quotation-attachments <projectId> --keys <csv> Queue cleanup of unattached quotation uploads; returns operation IDs.
13213
13416
  create-quotation --payload '<json>' (quotation.createDraft; requires amountWithoutGst, gstAmount, and lineAmounts [{budgetItemId, amount}] for multiple budgetItemIds; amounts before GST must sum to amountWithoutGst)
@@ -13227,7 +13430,11 @@ Customer invoices
13227
13430
  Returns { items, pageInfo }; follow nextCursor/previousCursor with the same filters and sort. --page/--perPage are rejected.
13228
13431
  No scope flag lists invoices globally. --projectId uses the project scope. A positional budgetId is a backward-compatible shortcut for --budgetIds.
13229
13432
  count-customer-invoices [budgetId] [same filter flags as list-customer-invoices] totalCount, lifecycle status facets (ignore --status) and amount metrics; no paging or sort flags
13230
- get-customer-invoice <batchId>
13433
+ get-customer-invoice <batchId> Batch as shown in the web app: status, totals, people, approvals and invoice summaries
13434
+ get-customer-invoice-invoices <batchId> Invoices with QuickBooks identity, dates and sync state
13435
+ get-customer-invoice-lines <invoiceId> [--limit 1-100] [--cursor <token>] One invoice's lines; { items, pageInfo }
13436
+ get-customer-invoice-approvals <batchId> [--limit 1-50] [--cursor <token>] Approval requests with approver/requester/responder; { items, pageInfo }
13437
+ get-customer-invoice-history <batchId> [--limit 1-100] [--cursor <token>] Status history; { items, pageInfo }
13231
13438
  get-customer-invoice-email-context <batchId> Contact, required CC, budget, and project context for composing an invoice email.
13232
13439
  preview-qbo-customer-invoice <budgetId> <qboInvoiceId> Preview an invoice selected from list-available-qbo-customer-invoices; works on accepted/closed estimates.
13233
13440
  import-qbo-customer-invoice <budgetId> <qboInvoiceId> --token <previewToken> Confirm the reviewed BB-only link; requires --allow-state-change --allow-financial-write in automation.
@@ -13267,7 +13474,7 @@ Companies & projects
13267
13474
  delete-company <id>
13268
13475
  list-projects [--companyId] [--name] [--status|--statuses CSV] [--active true|false] [--wonFrom ISO] [--wonTo ISO] [--wonWithinDays N] [--limit 1-100] [--cursor] [--direction forward|backward] [--sortBy name|createdAt|status|companyName|wonAt] [--sortDir asc|desc]
13269
13476
  Returns { items, pageInfo }; pass nextCursor with direction forward or previousCursor with direction backward. Legacy --page/--perPage are rejected.
13270
- --sortBy wonAt orders by when the project was marked WON (unwon projects last). Each project includes wonAt, wonById, wonBy and wonAtEstimated (true for backfilled dates).
13477
+ --sortBy wonAt orders by when the project was marked WON (unwon projects last). Each project includes wonAt, wonBy { id, name } and wonAtEstimated (true for backfilled dates).
13271
13478
  count-projects [--companyId] [--name] [--status|--statuses CSV] [--active true|false] [--wonFrom ISO] [--wonTo ISO] [--wonWithinDays N]
13272
13479
  Returns independent { totalCount, counts: { status, active: { true, false } } }; no pagination or sorting flags.
13273
13480
  list-project-hubs [--q] [--status CSV] [--sortBy startDate|name|companyName|status] [--sortDir asc|desc] [--limit 1-100] [--cursor <token>] [--direction forward|backward]
@@ -13277,7 +13484,7 @@ Companies & projects
13277
13484
  get-project <id>
13278
13485
  Budget overview totalRevenue includes Estimate Accepted and Estimate Closed budgets only.
13279
13486
  create-project --name --companyId --contactPersonId --insideSalesId --businessDevelopmentId --venue --startDate <ISO> [--projectManagerId <userId>] [--asanaTaskId] [--asanaSearch <text>] [--slackChannelId --slackChannelUrl --slackChannelName] [--pax] [--endDate <ISO>] [--description]
13280
- update-project --payload '<json>' (project.updateProject; warns before estimate-affecting changes reject linked estimates; optional projectManagerId and requestQboAccountantNotification)
13487
+ update-project --payload '<json>' (project.updateProject; warns before estimate-affecting changes reject linked estimates; a companyId change (with a contactPersonId from that company) does not itself reject estimates or touch invoices, but date/pax/venue changes in the same save still do; optional projectManagerId and requestQboAccountantNotification)
13281
13488
  delete-project <id>
13282
13489
  check-project-reconciliation <id> Run the same live reconciliation review as the web app without changing status.
13283
13490
  reconcile-project <id> Rerun all checks transactionally and mark an eligible WON project RECONCILED.
@@ -13344,12 +13551,13 @@ Dashboard & users
13344
13551
  Errors
13345
13552
  get-recent-errors [--cursor] [--direction forward|backward] [--limit] [--severity] [--status] [--timeFrame] (admin)
13346
13553
  count-errors [--severity] [--status] [--timeFrame] (admin)
13554
+ get-error <errorId> Full diagnostics: stack, cause, request, metadata (admin)
13347
13555
  get-error-metrics (admin)
13348
13556
 
13349
13557
  Automation (admin)
13350
13558
  list-integration-operations [--search] [--destination <provider,...>] [--status <PENDING|PROCESSING|FAILED|COMPLETED,...>] [--limit 1-100] [--cursor <token>] [--direction forward|backward]
13351
13559
  Newest first; returns { items, pageInfo }. Follow nextCursor/previousCursor with the same filters. --page/--perPage are rejected.
13352
- count-integration-operations [same filter flags] totalCount plus provider filter options
13560
+ count-integration-operations [same filter flags] provider filter options only (no total; filters do not change the result)
13353
13561
  get-integration-operation <operationId> (one job: who queued it, what it is for, saved progress, Retry state)
13354
13562
  retry-integration-operation <operationId> [--confirmExternalStateReconciled true|false] [--outboundEmailResolution ACCEPTED|NOT_ACCEPTED_RETRY] [--providerMessageId <id>] (QuickBooks jobs with a saved attempt check QuickBooks first: applied changes finish without resending, unapplied ones are sent again)
13355
13563
  reconcile-resource-operation <operationId> (admin: check a QuickBooks invoice/company/item job outcome without retrying; same check Retry runs first)
@@ -13363,7 +13571,7 @@ Webhooks (admin)
13363
13571
  delete-webhook-endpoint <endpointId>
13364
13572
  rotate-webhook-secret <endpointId> [--previousSecretTtlHours <0-168>] (prints the new secret once)
13365
13573
  send-webhook-test-event <endpointId>
13366
- list-webhook-deliveries [--endpointId] [--status PENDING|SUCCEEDED|FAILED] [--eventType] [--cursor] [--limit]
13574
+ list-webhook-deliveries [--endpointId] [--status <PENDING|SUCCEEDED|FAILED,...>] [--eventType] [--limit 1-100] [--cursor <token>] [--direction forward|backward] (newest first; prints items + pageInfo)
13367
13575
  get-webhook-delivery <deliveryId> (attempts with response codes)
13368
13576
  replay-webhook-delivery <deliveryId> (same eventId, new attempt chain)
13369
13577
 
@@ -14345,22 +14553,25 @@ Waiting for approval\u2026
14345
14553
  break;
14346
14554
  }
14347
14555
  case "get-bill-attachments": {
14556
+ const page = parseDetailFeedPage("get-bill-attachments", "<billId>", positional, flags, 50);
14557
+ await getBillAttachments(page);
14558
+ break;
14559
+ }
14560
+ case "get-bill-approvals": {
14561
+ const page = parseDetailFeedPage("get-bill-approvals", "<billId>", positional, flags, 50);
14562
+ await getBillApprovals(page);
14563
+ break;
14564
+ }
14565
+ case "get-bill-line-items": {
14566
+ const page = parseDetailFeedPage("get-bill-line-items", "<billId>", positional, flags, 100);
14567
+ await getBillLineItems(page);
14568
+ break;
14569
+ }
14570
+ case "get-bill-payment": {
14348
14571
  const id = positional[0];
14349
14572
  if (!id)
14350
- throw new Error("get-bill-attachments requires <billId>");
14351
- rejectRetiredPageFlags(flags);
14352
- for (const key of ["limit", "cursor"])
14353
- rejectBareFlag(flags, key);
14354
- if (flags.direction !== undefined)
14355
- throw new Error("get-bill-attachments pages forward only; follow pageInfo.nextCursor with --cursor.");
14356
- const cursor = getFlag(flags, "cursor");
14357
- if (cursor === "" || (cursor?.length ?? 0) > 8192)
14358
- throw new Error("--cursor must be a non-empty opaque token of at most 8192 characters.");
14359
- const limitFlag = getFlag(flags, "limit");
14360
- const limit = limitFlag === undefined ? undefined : Number(limitFlag);
14361
- if (limit !== undefined && (!Number.isInteger(limit) || limit < 1 || limit > 50))
14362
- throw new Error("--limit must be an integer from 1 to 50.");
14363
- await getBillAttachments({ id, limit, cursor });
14573
+ throw new Error("get-bill-payment requires <billId>");
14574
+ await getBillPayment(id);
14364
14575
  break;
14365
14576
  }
14366
14577
  case "stage-bill-attachment": {
@@ -14489,6 +14700,11 @@ Waiting for approval\u2026
14489
14700
  await getQuotationDetails(id);
14490
14701
  break;
14491
14702
  }
14703
+ case "get-quotation-line-items": {
14704
+ const page = parseDetailFeedPage("get-quotation-line-items", "<quotationId>", positional, flags, 100);
14705
+ await getQuotationLineItems(page);
14706
+ break;
14707
+ }
14492
14708
  case "upload-quotation-attachment": {
14493
14709
  const [projectId, filePath] = positional;
14494
14710
  if (!projectId || !filePath) {
@@ -14664,6 +14880,28 @@ Waiting for approval\u2026
14664
14880
  await getCustomerInvoice(batchId);
14665
14881
  break;
14666
14882
  }
14883
+ case "get-customer-invoice-invoices": {
14884
+ const batchId = positional[0];
14885
+ if (!batchId)
14886
+ throw new Error("get-customer-invoice-invoices requires <batchId>");
14887
+ await getCustomerInvoiceInvoices(batchId);
14888
+ break;
14889
+ }
14890
+ case "get-customer-invoice-lines": {
14891
+ const page = parseDetailFeedPage("get-customer-invoice-lines", "<invoiceId>", positional, flags, 100);
14892
+ await getCustomerInvoiceLines(page);
14893
+ break;
14894
+ }
14895
+ case "get-customer-invoice-approvals": {
14896
+ const page = parseDetailFeedPage("get-customer-invoice-approvals", "<batchId>", positional, flags, 50);
14897
+ await getCustomerInvoiceApprovals(page);
14898
+ break;
14899
+ }
14900
+ case "get-customer-invoice-history": {
14901
+ const page = parseDetailFeedPage("get-customer-invoice-history", "<batchId>", positional, flags, 100);
14902
+ await getCustomerInvoiceHistory(page);
14903
+ break;
14904
+ }
14667
14905
  case "get-customer-invoice-email-context": {
14668
14906
  const batchId = positional[0];
14669
14907
  if (!batchId) {
@@ -15579,6 +15817,13 @@ Waiting for approval\u2026
15579
15817
  }
15580
15818
  break;
15581
15819
  }
15820
+ case "get-error": {
15821
+ const id = positional[0];
15822
+ if (!id)
15823
+ throw new Error("get-error requires <errorId>");
15824
+ await getError(id);
15825
+ break;
15826
+ }
15582
15827
  case "get-error-metrics": {
15583
15828
  await getErrorMetrics();
15584
15829
  break;
@@ -15594,7 +15839,7 @@ Waiting for approval\u2026
15594
15839
  if (cmd === "count-integration-operations") {
15595
15840
  for (const key of ["limit", "cursor", "direction"])
15596
15841
  if (flags[key] !== undefined)
15597
- throw new Error(`count-integration-operations does not accept --${key}; totals use filters only.`);
15842
+ throw new Error(`count-integration-operations does not accept --${key}; it takes filter flags only.`);
15598
15843
  await countIntegrationOperations(filters);
15599
15844
  break;
15600
15845
  }
@@ -15704,14 +15949,22 @@ Waiting for approval\u2026
15704
15949
  break;
15705
15950
  }
15706
15951
  case "list-webhook-deliveries": {
15707
- const status = getFlag(flags, "status");
15708
- if (status && status !== "PENDING" && status !== "SUCCEEDED" && status !== "FAILED")
15709
- throw new Error("--status must be PENDING, SUCCEEDED or FAILED");
15952
+ const statuses = (getFlag(flags, "status") ?? "").split(",").map((value) => value.trim()).filter(Boolean);
15953
+ for (const status of statuses)
15954
+ if (status !== "PENDING" && status !== "SUCCEEDED" && status !== "FAILED")
15955
+ throw new Error("--status must be PENDING, SUCCEEDED or FAILED (comma-separated)");
15956
+ const cursor = getFlag(flags, "cursor");
15957
+ const direction = parseProjectDirection(getFlag(flags, "direction"));
15958
+ if (direction === "backward" && !cursor)
15959
+ throw new Error("--direction backward requires --cursor <token>.");
15710
15960
  await listWebhookDeliveries({
15711
15961
  endpointId: getFlag(flags, "endpointId"),
15712
- status,
15962
+ ...statuses.length ? {
15963
+ status: statuses
15964
+ } : {},
15713
15965
  eventType: getFlag(flags, "eventType"),
15714
- cursor: getFlag(flags, "cursor"),
15966
+ cursor,
15967
+ direction,
15715
15968
  limit: parsePositiveIntFlag(getFlag(flags, "limit"), "--limit")
15716
15969
  });
15717
15970
  break;