@go-labs-sg/bb 3.0.0 → 3.1.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());
@@ -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")
@@ -11391,7 +11476,7 @@ var summaryFor = (legacyTarget) => {
11391
11476
  if (legacyTarget === "list-integration-operations")
11392
11477
  return "List one cursor page of integration operations, newest first ({ items, pageInfo }; --limit/--cursor/--direction). --page/--perPage are rejected. Admin only.";
11393
11478
  if (legacyTarget === "count-integration-operations")
11394
- return "Count integration operations matching filters: { totalCount, filterOptions }. Admin only.";
11479
+ return "Provider filter options for integration operations: { filterOptions }. No total; filter flags are accepted but do not change the result. Admin only.";
11395
11480
  if (legacyTarget === "count-items")
11396
11481
  return "Count catalogue items matching filters: total plus category and supplier facets (each ignores its own filter).";
11397
11482
  if (legacyTarget === "count-budgets")
@@ -11446,6 +11531,8 @@ var summaryFor = (legacyTarget) => {
11446
11531
  return "Admin-only: send a signed webhook.test event to one endpoint. Argument: <endpointId>.";
11447
11532
  if (legacyTarget === "replay-webhook-delivery")
11448
11533
  return "Admin-only: resend a finished webhook delivery with the same eventId on a fresh attempt chain. Argument: <deliveryId>.";
11534
+ if (legacyTarget === "get-error")
11535
+ 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
11536
  if (legacyTarget === "get-webhook-delivery")
11450
11537
  return "Admin-only: one webhook delivery with payload and attempts (status codes, errors, durations). Argument: <deliveryId>.";
11451
11538
  if (legacyTarget === "list-webhook-event-types")
@@ -11732,6 +11819,27 @@ var registry2 = [
11732
11819
  ]),
11733
11820
  legacyCommand("attach-bill-documents", ["bill", "document", "attach"]),
11734
11821
  legacyCommand("get-bill-details", ["bill", "get"]),
11822
+ legacyCommand("get-bill-line-items", ["bill", "line-item", "list"], [], [
11823
+ {
11824
+ name: "--limit <1-100>",
11825
+ description: "Rows per page. Output is { items, pageInfo }."
11826
+ },
11827
+ {
11828
+ name: "--cursor <token>",
11829
+ description: "pageInfo.nextCursor from the last page, unchanged; pages forward only."
11830
+ }
11831
+ ]),
11832
+ legacyCommand("get-bill-approvals", ["bill", "approval", "list"], [], [
11833
+ {
11834
+ name: "--limit <1-50>",
11835
+ description: "Rows per page. Output is { items, pageInfo }."
11836
+ },
11837
+ {
11838
+ name: "--cursor <token>",
11839
+ description: "pageInfo.nextCursor from the last page, unchanged; pages forward only."
11840
+ }
11841
+ ]),
11842
+ legacyCommand("get-bill-payment", ["bill", "payment", "get"]),
11735
11843
  legacyCommand("list-quotations", ["quotation", "list"], [], [
11736
11844
  {
11737
11845
  name: "--limit <1-100>",
@@ -11748,6 +11856,16 @@ var registry2 = [
11748
11856
  ]),
11749
11857
  legacyCommand("count-quotations", ["quotation", "count"]),
11750
11858
  legacyCommand("get-quotation", ["quotation", "get"]),
11859
+ legacyCommand("get-quotation-line-items", ["quotation", "line-item", "list"], [], [
11860
+ {
11861
+ name: "--limit <1-100>",
11862
+ description: "Rows per page. Output is { items, pageInfo }."
11863
+ },
11864
+ {
11865
+ name: "--cursor <token>",
11866
+ description: "pageInfo.nextCursor from the last page, unchanged; pages forward only."
11867
+ }
11868
+ ]),
11751
11869
  legacyCommand("upload-quotation-attachment", [
11752
11870
  "quotation",
11753
11871
  "attachment",
@@ -11814,6 +11932,41 @@ var registry2 = [
11814
11932
  ]),
11815
11933
  legacyCommand("count-customer-invoices", ["customer-invoice", "count"]),
11816
11934
  legacyCommand("get-customer-invoice", ["customer-invoice", "get"]),
11935
+ legacyCommand("get-customer-invoice-invoices", [
11936
+ "customer-invoice",
11937
+ "invoice",
11938
+ "list"
11939
+ ]),
11940
+ legacyCommand("get-customer-invoice-lines", ["customer-invoice", "line", "list"], [], [
11941
+ {
11942
+ name: "--limit <1-100>",
11943
+ description: "Rows per page. Output is { items, pageInfo }."
11944
+ },
11945
+ {
11946
+ name: "--cursor <token>",
11947
+ description: "pageInfo.nextCursor from the last page, unchanged; pages forward only."
11948
+ }
11949
+ ]),
11950
+ legacyCommand("get-customer-invoice-approvals", ["customer-invoice", "approval", "list"], [], [
11951
+ {
11952
+ name: "--limit <1-50>",
11953
+ description: "Rows per page. Output is { items, pageInfo }."
11954
+ },
11955
+ {
11956
+ name: "--cursor <token>",
11957
+ description: "pageInfo.nextCursor from the last page, unchanged; pages forward only."
11958
+ }
11959
+ ]),
11960
+ legacyCommand("get-customer-invoice-history", ["customer-invoice", "history", "list"], [], [
11961
+ {
11962
+ name: "--limit <1-100>",
11963
+ description: "Rows per page. Output is { items, pageInfo }."
11964
+ },
11965
+ {
11966
+ name: "--cursor <token>",
11967
+ description: "pageInfo.nextCursor from the last page, unchanged; pages forward only."
11968
+ }
11969
+ ]),
11817
11970
  legacyCommand("get-customer-invoice-email-context", [
11818
11971
  "customer-invoice",
11819
11972
  "email-context",
@@ -12293,6 +12446,7 @@ var registry2 = [
12293
12446
  description: "Same filters as error recent list; returns independent totalCount."
12294
12447
  }
12295
12448
  ]),
12449
+ legacyCommand("get-error", ["error", "get"]),
12296
12450
  legacyCommand("get-error-metrics", ["error", "metrics", "get"]),
12297
12451
  legacyCommand("list-integration-operations", ["integration", "operation", "list"], [], [
12298
12452
  {
@@ -12921,6 +13075,24 @@ var rejectRetiredPageFlags = (flags) => {
12921
13075
  throw new Error(`--${key} is retired; use --limit/--cursor, or the matching count command for totals.`);
12922
13076
  }
12923
13077
  };
13078
+ var parseDetailFeedPage = (command, idLabel, positional, flags, maxLimit) => {
13079
+ const id = positional[0];
13080
+ if (!id)
13081
+ throw new Error(`${command} requires ${idLabel}`);
13082
+ rejectRetiredPageFlags(flags);
13083
+ for (const key of ["limit", "cursor"])
13084
+ rejectBareFlag(flags, key);
13085
+ if (flags.direction !== undefined)
13086
+ throw new Error(`${command} pages forward only; follow pageInfo.nextCursor with --cursor.`);
13087
+ const cursor = getFlag(flags, "cursor");
13088
+ if (cursor === "" || (cursor?.length ?? 0) > 8192)
13089
+ throw new Error("--cursor must be a non-empty opaque token of at most 8192 characters.");
13090
+ const limitFlag = getFlag(flags, "limit");
13091
+ const limit = limitFlag === undefined ? undefined : Number(limitFlag);
13092
+ if (limit !== undefined && (!Number.isInteger(limit) || limit < 1 || limit > maxLimit))
13093
+ throw new Error(`--limit must be an integer from 1 to ${maxLimit}.`);
13094
+ return { id, limit, cursor };
13095
+ };
12924
13096
  var parseBillFilterFlags = (flags) => {
12925
13097
  const statusRaw = getFlag(flags, "status");
12926
13098
  const createdByIdsRaw = getFlag(flags, "createdByIds");
@@ -13201,13 +13373,17 @@ Bills
13201
13373
  upload-bill-attachment <billId> <filePath...> [--file <path>] [--files <csv>] Attach invoice/supporting files as BILL attachments to any bill status, including PAID bills
13202
13374
  attach-bill-payment-receipt <billId> <filePath...> [--file <path>] [--files <csv>] Attach Wise/payment-proof PDFs as BILL_PAYMENT_PROOF attachments
13203
13375
  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>
13376
+ get-bill-details <billId> Bill summary as shown in the web app (status, amounts, people, payment, line totals)
13377
+ get-bill-line-items <billId> [--limit 1-100] [--cursor <token>] Line items with budget-item/quotation detail; { items, pageInfo }
13378
+ get-bill-approvals <billId> [--limit 1-50] [--cursor <token>] Approval requests with approver/requester/responder; { items, pageInfo }
13379
+ get-bill-payment <billId> Payment status, reference, date, tracking URL, QuickBooks link and external payment
13205
13380
 
13206
13381
  Quotations
13207
13382
  list-quotations [--projectId] [--budgetId] [--supplierId] [--status CSV] [--createdBy CSV] [--search] [--limit 1-100] [--cursor <token>] [--direction forward|backward]
13208
13383
  Newest first; returns { items, pageInfo }. Follow nextCursor/previousCursor with the same filters. --page/--pageSize/--perPage are rejected; --requesterIds remains an alias for --createdBy.
13209
13384
  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>
13385
+ get-quotation <quotationId> Quotation as shown in the web app (status, amounts, people, line totals, files, approvals)
13386
+ get-quotation-line-items <quotationId> [--limit 1-100] [--cursor <token>] Line items with budget-item detail; { items, pageInfo }
13211
13387
  upload-quotation-attachment <projectId> <filePath> Upload one PDF, JPEG, or PNG up to 20MB; returns attachment JSON for a quotation payload.
13212
13388
  cleanup-staged-quotation-attachments <projectId> --keys <csv> Queue cleanup of unattached quotation uploads; returns operation IDs.
13213
13389
  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 +13403,11 @@ Customer invoices
13227
13403
  Returns { items, pageInfo }; follow nextCursor/previousCursor with the same filters and sort. --page/--perPage are rejected.
13228
13404
  No scope flag lists invoices globally. --projectId uses the project scope. A positional budgetId is a backward-compatible shortcut for --budgetIds.
13229
13405
  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>
13406
+ get-customer-invoice <batchId> Batch as shown in the web app: status, totals, people, approvals and invoice summaries
13407
+ get-customer-invoice-invoices <batchId> Invoices with QuickBooks identity, dates and sync state
13408
+ get-customer-invoice-lines <invoiceId> [--limit 1-100] [--cursor <token>] One invoice's lines; { items, pageInfo }
13409
+ get-customer-invoice-approvals <batchId> [--limit 1-50] [--cursor <token>] Approval requests with approver/requester/responder; { items, pageInfo }
13410
+ get-customer-invoice-history <batchId> [--limit 1-100] [--cursor <token>] Status history; { items, pageInfo }
13231
13411
  get-customer-invoice-email-context <batchId> Contact, required CC, budget, and project context for composing an invoice email.
13232
13412
  preview-qbo-customer-invoice <budgetId> <qboInvoiceId> Preview an invoice selected from list-available-qbo-customer-invoices; works on accepted/closed estimates.
13233
13413
  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 +13447,7 @@ Companies & projects
13267
13447
  delete-company <id>
13268
13448
  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
13449
  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).
13450
+ --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
13451
  count-projects [--companyId] [--name] [--status|--statuses CSV] [--active true|false] [--wonFrom ISO] [--wonTo ISO] [--wonWithinDays N]
13272
13452
  Returns independent { totalCount, counts: { status, active: { true, false } } }; no pagination or sorting flags.
13273
13453
  list-project-hubs [--q] [--status CSV] [--sortBy startDate|name|companyName|status] [--sortDir asc|desc] [--limit 1-100] [--cursor <token>] [--direction forward|backward]
@@ -13277,7 +13457,7 @@ Companies & projects
13277
13457
  get-project <id>
13278
13458
  Budget overview totalRevenue includes Estimate Accepted and Estimate Closed budgets only.
13279
13459
  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)
13460
+ 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
13461
  delete-project <id>
13282
13462
  check-project-reconciliation <id> Run the same live reconciliation review as the web app without changing status.
13283
13463
  reconcile-project <id> Rerun all checks transactionally and mark an eligible WON project RECONCILED.
@@ -13344,12 +13524,13 @@ Dashboard & users
13344
13524
  Errors
13345
13525
  get-recent-errors [--cursor] [--direction forward|backward] [--limit] [--severity] [--status] [--timeFrame] (admin)
13346
13526
  count-errors [--severity] [--status] [--timeFrame] (admin)
13527
+ get-error <errorId> Full diagnostics: stack, cause, request, metadata (admin)
13347
13528
  get-error-metrics (admin)
13348
13529
 
13349
13530
  Automation (admin)
13350
13531
  list-integration-operations [--search] [--destination <provider,...>] [--status <PENDING|PROCESSING|FAILED|COMPLETED,...>] [--limit 1-100] [--cursor <token>] [--direction forward|backward]
13351
13532
  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
13533
+ count-integration-operations [same filter flags] provider filter options only (no total; filters do not change the result)
13353
13534
  get-integration-operation <operationId> (one job: who queued it, what it is for, saved progress, Retry state)
13354
13535
  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
13536
  reconcile-resource-operation <operationId> (admin: check a QuickBooks invoice/company/item job outcome without retrying; same check Retry runs first)
@@ -14345,22 +14526,25 @@ Waiting for approval\u2026
14345
14526
  break;
14346
14527
  }
14347
14528
  case "get-bill-attachments": {
14529
+ const page = parseDetailFeedPage("get-bill-attachments", "<billId>", positional, flags, 50);
14530
+ await getBillAttachments(page);
14531
+ break;
14532
+ }
14533
+ case "get-bill-approvals": {
14534
+ const page = parseDetailFeedPage("get-bill-approvals", "<billId>", positional, flags, 50);
14535
+ await getBillApprovals(page);
14536
+ break;
14537
+ }
14538
+ case "get-bill-line-items": {
14539
+ const page = parseDetailFeedPage("get-bill-line-items", "<billId>", positional, flags, 100);
14540
+ await getBillLineItems(page);
14541
+ break;
14542
+ }
14543
+ case "get-bill-payment": {
14348
14544
  const id = positional[0];
14349
14545
  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 });
14546
+ throw new Error("get-bill-payment requires <billId>");
14547
+ await getBillPayment(id);
14364
14548
  break;
14365
14549
  }
14366
14550
  case "stage-bill-attachment": {
@@ -14489,6 +14673,11 @@ Waiting for approval\u2026
14489
14673
  await getQuotationDetails(id);
14490
14674
  break;
14491
14675
  }
14676
+ case "get-quotation-line-items": {
14677
+ const page = parseDetailFeedPage("get-quotation-line-items", "<quotationId>", positional, flags, 100);
14678
+ await getQuotationLineItems(page);
14679
+ break;
14680
+ }
14492
14681
  case "upload-quotation-attachment": {
14493
14682
  const [projectId, filePath] = positional;
14494
14683
  if (!projectId || !filePath) {
@@ -14664,6 +14853,28 @@ Waiting for approval\u2026
14664
14853
  await getCustomerInvoice(batchId);
14665
14854
  break;
14666
14855
  }
14856
+ case "get-customer-invoice-invoices": {
14857
+ const batchId = positional[0];
14858
+ if (!batchId)
14859
+ throw new Error("get-customer-invoice-invoices requires <batchId>");
14860
+ await getCustomerInvoiceInvoices(batchId);
14861
+ break;
14862
+ }
14863
+ case "get-customer-invoice-lines": {
14864
+ const page = parseDetailFeedPage("get-customer-invoice-lines", "<invoiceId>", positional, flags, 100);
14865
+ await getCustomerInvoiceLines(page);
14866
+ break;
14867
+ }
14868
+ case "get-customer-invoice-approvals": {
14869
+ const page = parseDetailFeedPage("get-customer-invoice-approvals", "<batchId>", positional, flags, 50);
14870
+ await getCustomerInvoiceApprovals(page);
14871
+ break;
14872
+ }
14873
+ case "get-customer-invoice-history": {
14874
+ const page = parseDetailFeedPage("get-customer-invoice-history", "<batchId>", positional, flags, 100);
14875
+ await getCustomerInvoiceHistory(page);
14876
+ break;
14877
+ }
14667
14878
  case "get-customer-invoice-email-context": {
14668
14879
  const batchId = positional[0];
14669
14880
  if (!batchId) {
@@ -15579,6 +15790,13 @@ Waiting for approval\u2026
15579
15790
  }
15580
15791
  break;
15581
15792
  }
15793
+ case "get-error": {
15794
+ const id = positional[0];
15795
+ if (!id)
15796
+ throw new Error("get-error requires <errorId>");
15797
+ await getError(id);
15798
+ break;
15799
+ }
15582
15800
  case "get-error-metrics": {
15583
15801
  await getErrorMetrics();
15584
15802
  break;
@@ -15594,7 +15812,7 @@ Waiting for approval\u2026
15594
15812
  if (cmd === "count-integration-operations") {
15595
15813
  for (const key of ["limit", "cursor", "direction"])
15596
15814
  if (flags[key] !== undefined)
15597
- throw new Error(`count-integration-operations does not accept --${key}; totals use filters only.`);
15815
+ throw new Error(`count-integration-operations does not accept --${key}; it takes filter flags only.`);
15598
15816
  await countIntegrationOperations(filters);
15599
15817
  break;
15600
15818
  }