@go-labs-sg/bb 2.44.0 → 2.45.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/command-manifest.json +1 -1
- package/command-reference.md +1 -1
- package/dist/index.js +216 -212
- package/package.json +1 -1
- package/role-aware-agent-guide.md +3 -2
package/README.md
CHANGED
|
@@ -508,6 +508,8 @@ Project and budget query payloads keep the Asana identities explicit: `asanaTask
|
|
|
508
508
|
|
|
509
509
|
Bill, claim, and quotation mutations accept only suppliers whose approval status is `APPROVED`. An active supplier that is `PENDING_APPROVAL`, `REJECTED`, or `SUPERSEDED` must be approved before it can be used.
|
|
510
510
|
|
|
511
|
+
Admin/Lead users can run `bb supplier approve <supplierId>` to directly re-approve a `REJECTED` supplier even when no pending approval request exists. This appends a new approval record and activity entry with the current responder/time, retains earlier approval and rejection history unchanged, and synchronizes QuickBooks; it does not send a requester reply email. Non-interactive direct re-approval requires `--allow-state-change --allow-external-write`, without `--allow-email`. An archived supplier remains archived and also needs Admin reactivation (`bb supplier reactivate --ids <supplierId>`) before new use. Reactivating alone does not change approval status. For a pending supplier, the command still resolves the current user's assigned request and queues the existing reply email.
|
|
512
|
+
|
|
511
513
|
| Area | Legacy handler labels (reference only; non-exhaustive) |
|
|
512
514
|
| --- | --- |
|
|
513
515
|
| **Budgets** | `list-budgets` (full payload by default; `--summary` or `--includeDetails false` for slim list), `get-budget`, `get-budget-items`, `get-budget-details`, `get-budget-categories`, `get-budget-versions`, `rename-budget-version`, `restore-budget-version`, `update-budget-status` (`ESTIMATE_ACCEPTED` requires win proof, auto-marks `PITCH` or `LOST` projects `WON`, and auto-creates an Asana Event Ops section from Prompt 5 tasks when enabled; Prompt 5 skips quantity-zero items, combines matching non-GO-internal suppliers, keeps each GO internal item separate, removes generated work that repeats another line item or group, and schedules applicable subtasks relative to the project start date; `--projectStatusOnCommercialRejection PITCH\|LOST` is required when rejecting the only accepted/closed budget on a commercial project), `mark-budget-won` (`<budgetId>` + proof file path; `PITCH` or `LOST` projects become `WON` automatically), `create-budget` / `update-budget` (`--payload`; cloned unavailable lines require `unavailableItemReviewAcknowledged: true`), `delete-budget`, `create-budget-approval` (also sends approval request emails), `create-estimate`, `send-estimate-to-contact-person` (same contact-person email workflow as web), `add-budget-items`, `update-budget-item`, `replace-budget-item`, `approve-unavailable-item-exception` (Lead/Admin), `remove-budget-item`, `reorder-budget-items`, `update-budget-item-supplier`, `mark-budget-items-not-utilized`, `restore-budget-item`, `create-placeholder-bill` (admin recovery), `create-budget-category`, `update-budget-category`, `delete-budget-category`, `update-budget-commission`, `delete-budget-commission`, `update-budget-discount`, `delete-budget-discount` (`--payload` where noted), `upload-budget-attachment` (`<budgetId>` + local file path; uses `attachment.requestBudgetAttachmentUpload` + PUT + `attachment.confirmBudgetAttachment`) |
|
package/command-manifest.json
CHANGED
|
@@ -4795,7 +4795,7 @@
|
|
|
4795
4795
|
{
|
|
4796
4796
|
"path": ["supplier", "approve"],
|
|
4797
4797
|
"legacyAliases": ["approve-supplier", "approve_supplier"],
|
|
4798
|
-
"summary": "Approve
|
|
4798
|
+
"summary": "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>.",
|
|
4799
4799
|
"globalOptions": [
|
|
4800
4800
|
{
|
|
4801
4801
|
"name": "--help",
|
package/command-reference.md
CHANGED
|
@@ -833,7 +833,7 @@ Effects: state-change, email.
|
|
|
833
833
|
|
|
834
834
|
## `bb supplier approve`
|
|
835
835
|
|
|
836
|
-
Approve
|
|
836
|
+
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>.
|
|
837
837
|
|
|
838
838
|
Legacy aliases: `approve-supplier`, `approve_supplier`.
|
|
839
839
|
|
package/dist/index.js
CHANGED
|
@@ -35,46 +35,46 @@ 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.
|
|
38
|
+
// ../../../node_modules/.bun/dotenv@18.0.5/node_modules/dotenv/dist/index.cjs
|
|
39
39
|
var require_dist = __commonJS(function(exports, module) {
|
|
40
|
-
var
|
|
40
|
+
var I = (e, o) => () => {
|
|
41
41
|
try {
|
|
42
42
|
return o || e((o = { exports: {} }).exports, o), o.exports;
|
|
43
43
|
} catch (t) {
|
|
44
44
|
throw o = 0, t;
|
|
45
45
|
}
|
|
46
46
|
};
|
|
47
|
-
var
|
|
48
|
-
function
|
|
47
|
+
var S = I((xe, U) => {
|
|
48
|
+
function G(e) {
|
|
49
49
|
return typeof e == "string" ? !["false", "0", "no", "off", ""].includes(e.toLowerCase()) : !!e;
|
|
50
50
|
}
|
|
51
|
-
function
|
|
52
|
-
let
|
|
53
|
-
for (let
|
|
54
|
-
let
|
|
55
|
-
|
|
51
|
+
function X(e = process.env) {
|
|
52
|
+
let o = {};
|
|
53
|
+
for (let t of ["ENCODING", "PATH", "QUIET", "DEBUG", "OVERRIDE", "FAST"]) {
|
|
54
|
+
let n = e[`DOTENV_${t}`] != null ? e[`DOTENV_${t}`] : e[`DOTENV_CONFIG_${t}`];
|
|
55
|
+
n != null && (o[t.toLowerCase()] = t === "ENCODING" || t === "PATH" ? n : G(n));
|
|
56
56
|
}
|
|
57
|
-
return
|
|
57
|
+
return o;
|
|
58
58
|
}
|
|
59
|
-
|
|
59
|
+
U.exports = { parseBoolean: G, optionsFromEnv: X };
|
|
60
60
|
});
|
|
61
|
-
var
|
|
62
|
-
var
|
|
61
|
+
var N = I((ye, x) => {
|
|
62
|
+
var Y = __require("fs"), j = __require("path"), z = __require("os"), { URL: Z, fileURLToPath: ee } = __require("url"), { parseBoolean: k, optionsFromEnv: B } = S(), te = /(?:^|^)\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++)
|
|
66
|
-
|
|
66
|
+
b[e] = 1;
|
|
67
67
|
for (let e = 97;e <= 122; e++)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
function
|
|
68
|
+
b[e] = 1;
|
|
69
|
+
b[45] = 1;
|
|
70
|
+
b[46] = 1;
|
|
71
|
+
b[95] = 1;
|
|
72
|
+
function re(e) {
|
|
73
73
|
let o = {}, t = e.toString();
|
|
74
74
|
t = t.replace(/\r\n?/mg, `
|
|
75
75
|
`);
|
|
76
76
|
let n;
|
|
77
|
-
for (;(n =
|
|
77
|
+
for (;(n = te.exec(t)) != null; ) {
|
|
78
78
|
let r = n[1], s = n[2] || "";
|
|
79
79
|
s = s.trim();
|
|
80
80
|
let i = s[0];
|
|
@@ -83,192 +83,182 @@ var require_dist = __commonJS(function(exports, module) {
|
|
|
83
83
|
}
|
|
84
84
|
return o;
|
|
85
85
|
}
|
|
86
|
-
function
|
|
86
|
+
function w(e) {
|
|
87
|
+
return e <= 32 ? e === 32 || e >= 9 && e <= 13 : e >= 160 && (e === 160 || e === 5760 || e >= 8192 && e <= 8202 || e === 8232 || e === 8233 || e === 8239 || e === 8287 || e === 12288 || e === 65279);
|
|
88
|
+
}
|
|
89
|
+
function O(e) {
|
|
90
|
+
return e === 10 || e === 8232 || e === 8233;
|
|
91
|
+
}
|
|
92
|
+
function oe(e) {
|
|
87
93
|
let o = {}, t = typeof e == "string" ? e : e.toString();
|
|
88
94
|
t.indexOf("\r") !== -1 && (t = t.replace(/\r\n?/g, `
|
|
89
95
|
`));
|
|
90
96
|
let n = t.length, r = 0;
|
|
91
97
|
for (;r < n; ) {
|
|
92
98
|
let s = t.charCodeAt(r);
|
|
93
|
-
for (;r < n && (s
|
|
99
|
+
for (;r < n && w(s); )
|
|
94
100
|
r++, s = t.charCodeAt(r);
|
|
95
101
|
if (r >= n)
|
|
96
102
|
break;
|
|
97
103
|
if (s === 35) {
|
|
98
|
-
for (;r < n && t.charCodeAt(r)
|
|
104
|
+
for (;r < n && !O(t.charCodeAt(r)); )
|
|
99
105
|
r++;
|
|
100
106
|
continue;
|
|
101
107
|
}
|
|
108
|
+
let i = -1;
|
|
102
109
|
if (s === 101 && r + 6 < n && t.charCodeAt(r + 1) === 120 && t.charCodeAt(r + 2) === 112 && t.charCodeAt(r + 3) === 111 && t.charCodeAt(r + 4) === 114 && t.charCodeAt(r + 5) === 116) {
|
|
103
|
-
let
|
|
104
|
-
if (
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
110
|
+
let v = t.charCodeAt(r + 6);
|
|
111
|
+
if (w(v)) {
|
|
112
|
+
let u = r + 7;
|
|
113
|
+
for (;u < n && w(t.charCodeAt(u)); )
|
|
114
|
+
u++;
|
|
115
|
+
b[t.charCodeAt(u)] && (i = r + 6, r = u);
|
|
116
|
+
} else
|
|
108
117
|
s = t.charCodeAt(r);
|
|
109
118
|
}
|
|
110
|
-
let
|
|
111
|
-
for (;r < n && (
|
|
119
|
+
let l = r, d = 0;
|
|
120
|
+
for (;r < n && (d = t.charCodeAt(r), b[d]); )
|
|
112
121
|
r++;
|
|
113
|
-
if (r ===
|
|
114
|
-
for (;r < n && t.charCodeAt(r)
|
|
122
|
+
if (r === l) {
|
|
123
|
+
for (;r < n && !O(t.charCodeAt(r)); )
|
|
115
124
|
r++;
|
|
116
125
|
continue;
|
|
117
126
|
}
|
|
118
|
-
let
|
|
119
|
-
if (r >= n && (
|
|
127
|
+
let p = t.slice(l, r), f = r;
|
|
128
|
+
if (r >= n && (d = 0), w(d))
|
|
120
129
|
do
|
|
121
|
-
r++,
|
|
122
|
-
while (
|
|
123
|
-
if (
|
|
124
|
-
r++;
|
|
125
|
-
else if (l === 58 && r + 1 < n && (t.charCodeAt(r + 1) === 32 || t.charCodeAt(r + 1) === 9))
|
|
130
|
+
r++, d = r < n ? t.charCodeAt(r) : 0;
|
|
131
|
+
while (w(d));
|
|
132
|
+
if (d === 61)
|
|
126
133
|
r++;
|
|
134
|
+
else if (d === 58 && r === f && r + 1 < n && w(t.charCodeAt(r + 1)))
|
|
135
|
+
r += 2;
|
|
127
136
|
else {
|
|
128
|
-
for (;r < n && t.charCodeAt(r)
|
|
137
|
+
for (r = i === -1 ? f : i;r < n && !O(t.charCodeAt(r)); )
|
|
129
138
|
r++;
|
|
130
139
|
continue;
|
|
131
140
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
continue;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
if (d === f)
|
|
141
|
+
let c = r, a = r;
|
|
142
|
+
for (;a < n && w(t.charCodeAt(a)); )
|
|
143
|
+
a++;
|
|
144
|
+
let g = t.charCodeAt(a), h, y = false;
|
|
145
|
+
if (g === 39 || g === 34 || g === 96) {
|
|
146
|
+
let v = t[a], u = t.indexOf(v, a + 1), m = -1, C = -1;
|
|
147
|
+
for (;u !== -1; ) {
|
|
148
|
+
let q = t.charCodeAt(u - 1) === 92, E = u + 1;
|
|
149
|
+
for (;E < n && !O(t.charCodeAt(E)) && w(t.charCodeAt(E)); )
|
|
150
|
+
E++;
|
|
151
|
+
if ((E === n || O(t.charCodeAt(E)) || t.charCodeAt(E) === 35) && (m = u, C = E), !q)
|
|
147
152
|
break;
|
|
148
|
-
|
|
153
|
+
u = t.indexOf(v, u + 1);
|
|
149
154
|
}
|
|
150
|
-
if (
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
let w = t.charCodeAt(p);
|
|
154
|
-
if (w === 35 || w === 10)
|
|
155
|
-
break;
|
|
156
|
-
p++;
|
|
157
|
-
}
|
|
158
|
-
let m = p;
|
|
159
|
-
for (;m > d; ) {
|
|
160
|
-
let w = t.charCodeAt(m - 1);
|
|
161
|
-
if (w === 32 || w === 9)
|
|
162
|
-
m--;
|
|
163
|
-
else
|
|
164
|
-
break;
|
|
165
|
-
}
|
|
166
|
-
if (u = t.slice(d, m), r = p, r < n && t.charCodeAt(r) === 35)
|
|
167
|
-
for (;r < n && t.charCodeAt(r) !== 10; )
|
|
168
|
-
r++;
|
|
169
|
-
} else {
|
|
170
|
-
for (u = t.slice(c, a), r = a + 1, f === 34 && u.indexOf("\\") !== -1 && (u = u.replace(/\\n/g, `
|
|
171
|
-
`).replace(/\\r/g, "\r"));r < n && ((s = t.charCodeAt(r)) === 32 || s === 9); )
|
|
172
|
-
r++;
|
|
173
|
-
if (r < n && t.charCodeAt(r) === 35)
|
|
174
|
-
for (;r < n && t.charCodeAt(r) !== 10; )
|
|
155
|
+
if (m !== -1) {
|
|
156
|
+
if (h = t.slice(a + 1, m), r = C, t.charCodeAt(r) === 35)
|
|
157
|
+
for (;r < n && !O(t.charCodeAt(r)); )
|
|
175
158
|
r++;
|
|
159
|
+
y = true;
|
|
176
160
|
}
|
|
177
|
-
} else {
|
|
178
|
-
let f = r, c = t.indexOf(`
|
|
179
|
-
`, r);
|
|
180
|
-
c === -1 && (c = n);
|
|
181
|
-
let a = t.indexOf("#", r);
|
|
182
|
-
(a === -1 || a > c) && (a = c);
|
|
183
|
-
let d = a;
|
|
184
|
-
for (;d > f; ) {
|
|
185
|
-
let p = t.charCodeAt(d - 1);
|
|
186
|
-
if (p === 32 || p === 9)
|
|
187
|
-
d--;
|
|
188
|
-
else
|
|
189
|
-
break;
|
|
190
|
-
}
|
|
191
|
-
u = f === d ? "" : t.slice(f, d), r = a === c ? a : c;
|
|
192
161
|
}
|
|
193
|
-
|
|
162
|
+
if (!y) {
|
|
163
|
+
let v = t.indexOf(`
|
|
164
|
+
`, c);
|
|
165
|
+
v === -1 && (v = n);
|
|
166
|
+
let u;
|
|
167
|
+
if (n < 4096)
|
|
168
|
+
u = t.indexOf("#", c), (u === -1 || u > v) && (u = v);
|
|
169
|
+
else
|
|
170
|
+
for (u = c;u < v && t.charCodeAt(u) !== 35; )
|
|
171
|
+
u++;
|
|
172
|
+
let m = c, C = u;
|
|
173
|
+
for (;m < C && w(t.charCodeAt(m)); )
|
|
174
|
+
m++;
|
|
175
|
+
for (;C > m && w(t.charCodeAt(C - 1)); )
|
|
176
|
+
C--;
|
|
177
|
+
let q = t.charCodeAt(m);
|
|
178
|
+
if (C - m >= 2 && (q === 39 || q === 34 || q === 96) && t.charCodeAt(C - 1) === q ? h = t.slice(m + 1, C - 1) : h = t.slice(m, C), r = u, u < v)
|
|
179
|
+
for (;r < n && !O(t.charCodeAt(r)); )
|
|
180
|
+
r++;
|
|
181
|
+
}
|
|
182
|
+
g === 34 && (y || a < r) && h.indexOf("\\") !== -1 && (h = h.replace(/\\n/g, `
|
|
183
|
+
`).replace(/\\r/g, "\r")), o[p] = h;
|
|
194
184
|
}
|
|
195
185
|
return o;
|
|
196
186
|
}
|
|
197
|
-
function
|
|
198
|
-
return o &&
|
|
187
|
+
function ne(e, o) {
|
|
188
|
+
return o && k(o.fast) ? oe(e) : re(e);
|
|
199
189
|
}
|
|
200
|
-
function
|
|
190
|
+
function T(e) {
|
|
201
191
|
console.log(`\u2506 ${e}`);
|
|
202
192
|
}
|
|
203
|
-
function
|
|
193
|
+
function se(e) {
|
|
204
194
|
console.error(`\u25C7 ${e}`);
|
|
205
195
|
}
|
|
206
|
-
function
|
|
207
|
-
return e[0] === "~" ?
|
|
196
|
+
function V(e) {
|
|
197
|
+
return e[0] === "~" ? j.join(z.homedir(), e.slice(1)) : e;
|
|
208
198
|
}
|
|
209
|
-
function
|
|
210
|
-
return { ...
|
|
199
|
+
function ie(e = {}) {
|
|
200
|
+
return { ...B(), ...e };
|
|
211
201
|
}
|
|
212
|
-
function
|
|
213
|
-
e =
|
|
214
|
-
let o =
|
|
202
|
+
function ce(e) {
|
|
203
|
+
e = ie(e);
|
|
204
|
+
let o = j.resolve(process.cwd(), ".env"), t = "utf8", n = process.env;
|
|
215
205
|
e && e.processEnv != null && (n = e.processEnv);
|
|
216
|
-
let r =
|
|
217
|
-
e && e.encoding ? t = e.encoding : r &&
|
|
218
|
-
let
|
|
206
|
+
let r = k(e && e.debug);
|
|
207
|
+
e && e.encoding ? t = e.encoding : r && T("no encoding is specified (UTF-8 is used by default)");
|
|
208
|
+
let s = [o];
|
|
219
209
|
if (e && e.path)
|
|
220
210
|
if (!Array.isArray(e.path))
|
|
221
|
-
|
|
211
|
+
s = [V(e.path)];
|
|
222
212
|
else {
|
|
223
|
-
|
|
213
|
+
s = [];
|
|
224
214
|
for (let c of e.path)
|
|
225
|
-
|
|
215
|
+
s.push(V(c));
|
|
226
216
|
}
|
|
227
|
-
let
|
|
228
|
-
for (let c of
|
|
217
|
+
let i, l = {}, d = { fast: e.fast };
|
|
218
|
+
for (let c of s)
|
|
229
219
|
try {
|
|
230
|
-
let a =
|
|
231
|
-
|
|
220
|
+
let a = A.parse(Y.readFileSync(c, { encoding: t }), d);
|
|
221
|
+
A.populate(l, a, e);
|
|
232
222
|
} catch (a) {
|
|
233
|
-
r &&
|
|
223
|
+
r && T(`failed to load ${c} ${a.message}`), i = a;
|
|
234
224
|
}
|
|
235
|
-
let
|
|
236
|
-
if (r || !
|
|
237
|
-
let c = Object.keys(
|
|
238
|
-
for (let
|
|
225
|
+
let p = A.populate(n, l, e), f = k(Object.prototype.hasOwnProperty.call(e, "quiet") ? e.quiet : B(n).quiet);
|
|
226
|
+
if (r || !f) {
|
|
227
|
+
let c = Object.keys(p).length, a = [];
|
|
228
|
+
for (let g of s)
|
|
239
229
|
try {
|
|
240
|
-
let
|
|
241
|
-
a.push(
|
|
242
|
-
} catch (
|
|
243
|
-
r &&
|
|
230
|
+
let h = j.relative(process.cwd(), g instanceof Z ? ee(g) : g);
|
|
231
|
+
a.push(h);
|
|
232
|
+
} catch (h) {
|
|
233
|
+
r && T(`failed to load ${g} ${h.message}`), i = h;
|
|
244
234
|
}
|
|
245
|
-
|
|
235
|
+
se(`injected env (${c}) from ${a.join(",")}`);
|
|
246
236
|
}
|
|
247
|
-
return
|
|
237
|
+
return i ? { parsed: l, error: i } : { parsed: l };
|
|
248
238
|
}
|
|
249
|
-
function
|
|
250
|
-
return
|
|
239
|
+
function ae(e) {
|
|
240
|
+
return A.configDotenv(e);
|
|
251
241
|
}
|
|
252
|
-
function
|
|
242
|
+
function le(e, o, t = {}) {
|
|
253
243
|
let n = !!(t && t.debug), r = !!(t && t.override), s = {};
|
|
254
244
|
if (e === null || typeof e != "object" || o === null || typeof o != "object") {
|
|
255
245
|
let i = new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");
|
|
256
246
|
throw i.code = "OBJECT_REQUIRED", i;
|
|
257
247
|
}
|
|
258
248
|
for (let i of Object.keys(o))
|
|
259
|
-
Object.prototype.hasOwnProperty.call(e, i) ? (r === true && (e[i] = o[i], s[i] = o[i]), n &&
|
|
249
|
+
Object.prototype.hasOwnProperty.call(e, i) ? (r === true && (e[i] = o[i], s[i] = o[i]), n && T(r === true ? `"${i}" is already defined and WAS overwritten` : `"${i}" is already defined and was NOT overwritten`)) : (e[i] = o[i], s[i] = o[i]);
|
|
260
250
|
return s;
|
|
261
251
|
}
|
|
262
|
-
var
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
252
|
+
var A = { configDotenv: ce, config: ae, parse: ne, populate: le };
|
|
253
|
+
x.exports.configDotenv = A.configDotenv;
|
|
254
|
+
x.exports.config = A.config;
|
|
255
|
+
x.exports.parse = A.parse;
|
|
256
|
+
x.exports.populate = A.populate;
|
|
257
|
+
x.exports = A;
|
|
268
258
|
});
|
|
269
|
-
var
|
|
270
|
-
var
|
|
271
|
-
function
|
|
259
|
+
var M = I((Te, W) => {
|
|
260
|
+
var _ = __require("child_process"), fe = __require("fs"), L = __require("path");
|
|
261
|
+
function ue(e) {
|
|
272
262
|
let o = ['"'], t = 0;
|
|
273
263
|
for (let n of e) {
|
|
274
264
|
if (n === "\\") {
|
|
@@ -279,7 +269,7 @@ var require_dist = __commonJS(function(exports, module) {
|
|
|
279
269
|
}
|
|
280
270
|
return o.push("\\".repeat(t * 2), '"'), o.join("");
|
|
281
271
|
}
|
|
282
|
-
function
|
|
272
|
+
function H(e, o = 1) {
|
|
283
273
|
for (let t = 0;t < o; t++) {
|
|
284
274
|
let n = [];
|
|
285
275
|
for (let r of e) {
|
|
@@ -290,47 +280,47 @@ var require_dist = __commonJS(function(exports, module) {
|
|
|
290
280
|
}
|
|
291
281
|
return e;
|
|
292
282
|
}
|
|
293
|
-
function
|
|
283
|
+
function P(e, o) {
|
|
294
284
|
let t = Object.keys(e).reverse().find((n) => n.toUpperCase() === o);
|
|
295
285
|
return t === undefined ? undefined : e[t];
|
|
296
286
|
}
|
|
297
|
-
function
|
|
298
|
-
let n = (
|
|
287
|
+
function de(e, o, t) {
|
|
288
|
+
let n = (P(o, "PATHEXT") || ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean), s = n.some((l) => e.toLowerCase().endsWith(l.toLowerCase())) ? ["", ...n] : [...n, ""], i = /[\\/]/.test(e) ? [t] : [t, ...(P(o, "PATH") || "").split(";")];
|
|
299
289
|
for (let l of i)
|
|
300
|
-
for (let
|
|
301
|
-
let
|
|
290
|
+
for (let d of s) {
|
|
291
|
+
let p = L.resolve(t, l.replace(/^"|"$/g, ""), e + d);
|
|
302
292
|
try {
|
|
303
|
-
if (
|
|
304
|
-
return
|
|
293
|
+
if (fe.statSync(p).isFile())
|
|
294
|
+
return p;
|
|
305
295
|
} catch {}
|
|
306
296
|
}
|
|
307
297
|
}
|
|
308
|
-
function
|
|
298
|
+
function pe(e, o, t) {
|
|
309
299
|
if (process.platform !== "win32")
|
|
310
|
-
return
|
|
311
|
-
let n = t.env || process.env, r =
|
|
300
|
+
return _.spawn(e, o, t);
|
|
301
|
+
let n = t.env || process.env, r = de(e, n, t.cwd || process.cwd());
|
|
312
302
|
if (r && /\.(?:exe|com)$/i.test(r))
|
|
313
|
-
return
|
|
314
|
-
let s = /\.(?:bat|cmd)$/i.test(r || e), i = [
|
|
315
|
-
for (let
|
|
316
|
-
i.push(
|
|
303
|
+
return _.spawn(r, o, t);
|
|
304
|
+
let s = /\.(?:bat|cmd)$/i.test(r || e), i = [H(L.normalize(r || e))];
|
|
305
|
+
for (let d of o)
|
|
306
|
+
i.push(H(ue(d), s ? 2 : 1));
|
|
317
307
|
let l = i.join(" ");
|
|
318
|
-
return
|
|
308
|
+
return _.spawn(P(n, "COMSPEC") || "cmd.exe", ["/d", "/v:off", "/s", "/c", `"${l}"`], { ...t, windowsVerbatimArguments: true });
|
|
319
309
|
}
|
|
320
|
-
|
|
310
|
+
W.exports = pe;
|
|
321
311
|
});
|
|
322
|
-
var
|
|
323
|
-
var
|
|
324
|
-
function
|
|
312
|
+
var K = I(($e, F) => {
|
|
313
|
+
var he = __require("fs"), ge = __require("os"), Q = __require("path"), me = __require("child_process"), ve = M(), R = N(), { optionsFromEnv: Ce } = S();
|
|
314
|
+
function $() {
|
|
325
315
|
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(`
|
|
326
316
|
`));
|
|
327
317
|
}
|
|
328
|
-
function
|
|
318
|
+
function we(e) {
|
|
329
319
|
let o = [], t = false, n, r, s, i, l = -1;
|
|
330
|
-
for (let
|
|
331
|
-
let f = e[
|
|
320
|
+
for (let p = 0;p < e.length; p++) {
|
|
321
|
+
let f = e[p];
|
|
332
322
|
if (f === "--") {
|
|
333
|
-
l =
|
|
323
|
+
l = p + 1;
|
|
334
324
|
break;
|
|
335
325
|
}
|
|
336
326
|
if (f === "--help" || f === "-h")
|
|
@@ -352,70 +342,70 @@ var require_dist = __commonJS(function(exports, module) {
|
|
|
352
342
|
continue;
|
|
353
343
|
}
|
|
354
344
|
if (f === "-f" || f === "--file" || f.startsWith("-f=") || f.startsWith("--file=")) {
|
|
355
|
-
let c = f.indexOf("="), a = c === -1 ? f : f.slice(0, c),
|
|
356
|
-
if (!
|
|
345
|
+
let c = f.indexOf("="), a = c === -1 ? f : f.slice(0, c), g = c === -1 ? e[++p] : f.slice(c + 1);
|
|
346
|
+
if (!g || g === "--")
|
|
357
347
|
return { error: `${a} requires a path` };
|
|
358
|
-
let
|
|
359
|
-
if (
|
|
348
|
+
let h = g.split(",").map((y) => y.trim()).filter(Boolean);
|
|
349
|
+
if (h.length === 0)
|
|
360
350
|
return { error: `${a} requires a path` };
|
|
361
|
-
o.push(...
|
|
351
|
+
o.push(...h), t = true;
|
|
362
352
|
continue;
|
|
363
353
|
}
|
|
364
354
|
if (f.startsWith("-"))
|
|
365
355
|
return { error: `unknown option: ${f}` };
|
|
366
|
-
l =
|
|
356
|
+
l = p;
|
|
367
357
|
break;
|
|
368
358
|
}
|
|
369
|
-
let
|
|
370
|
-
return { paths: o, pathSet: t, quiet: n, debug: r, override: s, fast: i, command:
|
|
359
|
+
let d = l === -1 ? [] : e.slice(l);
|
|
360
|
+
return { paths: o, pathSet: t, quiet: n, debug: r, override: s, fast: i, command: d };
|
|
371
361
|
}
|
|
372
|
-
function
|
|
373
|
-
return e[0] === "~" ?
|
|
362
|
+
function Ae(e) {
|
|
363
|
+
return e[0] === "~" ? Q.join(ge.homedir(), e.slice(1)) : e;
|
|
374
364
|
}
|
|
375
|
-
function
|
|
376
|
-
let o =
|
|
365
|
+
function Ee(e) {
|
|
366
|
+
let o = Ce(), t = { encoding: o.encoding || "utf8", quiet: o.quiet === true, debug: o.debug === true, override: o.override === true, fast: o.fast === true, paths: [".env"], defaultPath: true };
|
|
377
367
|
return o.path != null && (t.paths = [o.path], t.defaultPath = false), e.pathSet && (t.paths = e.paths, t.defaultPath = false), e.quiet != null && (t.quiet = e.quiet), e.debug != null && (t.debug = e.debug), e.override != null && (t.override = e.override), e.fast != null && (t.fast = e.fast), t;
|
|
378
368
|
}
|
|
379
|
-
function
|
|
369
|
+
function be(e) {
|
|
380
370
|
let o = {}, t = [], n = { override: e.override, debug: e.debug };
|
|
381
371
|
for (let s of e.paths) {
|
|
382
|
-
let i =
|
|
372
|
+
let i = Q.resolve(process.cwd(), Ae(s));
|
|
383
373
|
try {
|
|
384
|
-
let l =
|
|
385
|
-
|
|
374
|
+
let l = R.parse(he.readFileSync(i, { encoding: e.encoding }), { fast: e.fast });
|
|
375
|
+
R.populate(o, l, n), t.push(s);
|
|
386
376
|
} catch (l) {
|
|
387
377
|
if (e.debug && console.log(`\u2506 failed to load ${s} ${l.message}`), !(e.defaultPath && l.code === "ENOENT"))
|
|
388
378
|
throw l;
|
|
389
379
|
}
|
|
390
380
|
}
|
|
391
|
-
return { injected:
|
|
381
|
+
return { injected: R.populate(process.env, o, n), loadedPaths: t };
|
|
392
382
|
}
|
|
393
|
-
function
|
|
383
|
+
function J(e) {
|
|
394
384
|
let o = e[0];
|
|
395
385
|
if (o === "--help" || o === "-h") {
|
|
396
|
-
|
|
386
|
+
$();
|
|
397
387
|
return;
|
|
398
388
|
}
|
|
399
389
|
if (o !== "run") {
|
|
400
|
-
|
|
390
|
+
$(), process.exitCode = 1;
|
|
401
391
|
return;
|
|
402
392
|
}
|
|
403
|
-
let t =
|
|
393
|
+
let t = we(e.slice(1));
|
|
404
394
|
if (t.help) {
|
|
405
|
-
|
|
395
|
+
$();
|
|
406
396
|
return;
|
|
407
397
|
}
|
|
408
398
|
if (t.error) {
|
|
409
|
-
console.error(`dotenv: ${t.error}`),
|
|
399
|
+
console.error(`dotenv: ${t.error}`), $(), process.exitCode = 1;
|
|
410
400
|
return;
|
|
411
401
|
}
|
|
412
402
|
if (t.command.length === 0) {
|
|
413
|
-
|
|
403
|
+
$(), process.exitCode = 1;
|
|
414
404
|
return;
|
|
415
405
|
}
|
|
416
|
-
let n =
|
|
406
|
+
let n = Ee(t);
|
|
417
407
|
try {
|
|
418
|
-
let c =
|
|
408
|
+
let c = be(n);
|
|
419
409
|
if (!n.quiet) {
|
|
420
410
|
let a = `\u25C7 injected env (${Object.keys(c.injected).length})`;
|
|
421
411
|
c.loadedPaths.length > 0 && (a += ` from ${c.loadedPaths.join(", ")}`), console.error(a);
|
|
@@ -424,11 +414,11 @@ var require_dist = __commonJS(function(exports, module) {
|
|
|
424
414
|
console.error(`dotenv: ${c.message}`), process.exitCode = 1;
|
|
425
415
|
return;
|
|
426
416
|
}
|
|
427
|
-
let r = !!process.stdin.isTTY, s = process.platform !== "win32" && !r, i =
|
|
428
|
-
function
|
|
417
|
+
let r = !!process.stdin.isTTY, s = process.platform !== "win32" && !r, i = ve(t.command[0], t.command.slice(1), { stdio: "inherit", detached: s }), l = new Map, d = 0;
|
|
418
|
+
function p(c) {
|
|
429
419
|
if (!(!i.pid || i.exitCode !== null || i.signalCode !== null)) {
|
|
430
420
|
if (process.platform === "win32") {
|
|
431
|
-
|
|
421
|
+
me.spawnSync("taskkill", ["/pid", String(i.pid), "/T", "/F"], { stdio: "ignore" });
|
|
432
422
|
return;
|
|
433
423
|
}
|
|
434
424
|
try {
|
|
@@ -446,14 +436,14 @@ var require_dist = __commonJS(function(exports, module) {
|
|
|
446
436
|
for (let c of ["SIGINT", "SIGTERM", "SIGHUP", "SIGQUIT"]) {
|
|
447
437
|
let a = () => {
|
|
448
438
|
if (c === "SIGINT") {
|
|
449
|
-
if (
|
|
439
|
+
if (d++, r && process.platform !== "win32" && d === 1)
|
|
450
440
|
return;
|
|
451
|
-
if (
|
|
452
|
-
|
|
441
|
+
if (d > 1) {
|
|
442
|
+
p(d === 2 ? "SIGTERM" : "SIGKILL");
|
|
453
443
|
return;
|
|
454
444
|
}
|
|
455
445
|
}
|
|
456
|
-
|
|
446
|
+
p(c);
|
|
457
447
|
};
|
|
458
448
|
l.set(c, a), process.on(c, a);
|
|
459
449
|
}
|
|
@@ -463,16 +453,16 @@ var require_dist = __commonJS(function(exports, module) {
|
|
|
463
453
|
f(), typeof c == "number" ? process.exit(c) : (setInterval(() => {}, 1000), process.kill(process.pid, a));
|
|
464
454
|
});
|
|
465
455
|
}
|
|
466
|
-
|
|
467
|
-
|
|
456
|
+
F.exports = J;
|
|
457
|
+
F === __require.main && J(process.argv.slice(2));
|
|
468
458
|
});
|
|
469
|
-
var
|
|
470
|
-
var
|
|
471
|
-
module.exports =
|
|
472
|
-
module.exports.config =
|
|
473
|
-
module.exports.configDotenv =
|
|
474
|
-
module.exports.parse =
|
|
475
|
-
module.exports.populate =
|
|
459
|
+
var D = N();
|
|
460
|
+
var Oe = K();
|
|
461
|
+
module.exports = D;
|
|
462
|
+
module.exports.config = D.config;
|
|
463
|
+
module.exports.configDotenv = D.configDotenv;
|
|
464
|
+
module.exports.parse = D.parse;
|
|
465
|
+
module.exports.populate = D.populate;
|
|
476
466
|
});
|
|
477
467
|
|
|
478
468
|
// src/load-env.ts
|
|
@@ -8504,7 +8494,8 @@ var assertSensitiveWorkflowConfirmed = async (input) => {
|
|
|
8504
8494
|
await confirmCurrentCommand({
|
|
8505
8495
|
action: input.action,
|
|
8506
8496
|
target: input.entity,
|
|
8507
|
-
details: input.details
|
|
8497
|
+
details: input.details,
|
|
8498
|
+
effects: input.effects
|
|
8508
8499
|
});
|
|
8509
8500
|
return;
|
|
8510
8501
|
}
|
|
@@ -9953,6 +9944,17 @@ async function getSupplierDetails(supplierId) {
|
|
|
9953
9944
|
});
|
|
9954
9945
|
}
|
|
9955
9946
|
async function approveSupplier(supplierId) {
|
|
9947
|
+
const supplier = await api2.supplier.getSupplierById.query({ id: supplierId });
|
|
9948
|
+
if (supplier.status === ExtendedApprovalStatus.REJECTED) {
|
|
9949
|
+
await assertSensitiveWorkflowConfirmed({
|
|
9950
|
+
action: "Re-approve supplier",
|
|
9951
|
+
entity: `supplier ${supplierId}`,
|
|
9952
|
+
effects: ["state-change", "external-write"],
|
|
9953
|
+
details: supplier.active ? "and sync its details with QuickBooks; append a new approval and retain earlier history; no requester reply email is sent" : "and sync its details with QuickBooks; append a new approval and retain earlier history; it remains archived and no requester reply email is sent"
|
|
9954
|
+
});
|
|
9955
|
+
out(await api2.supplier.reapproveSupplier.mutate({ supplierId }));
|
|
9956
|
+
return;
|
|
9957
|
+
}
|
|
9956
9958
|
await assertSensitiveWorkflowConfirmed({
|
|
9957
9959
|
action: "Approve supplier",
|
|
9958
9960
|
entity: `supplier ${supplierId}`,
|
|
@@ -10894,6 +10896,8 @@ var effectsFor = (legacyTarget) => {
|
|
|
10894
10896
|
};
|
|
10895
10897
|
var titleCase = (value) => value.split("-").map((word) => `${word.slice(0, 1).toUpperCase()}${word.slice(1)}`).join(" ");
|
|
10896
10898
|
var summaryFor = (legacyTarget) => {
|
|
10899
|
+
if (legacyTarget === "approve-supplier")
|
|
10900
|
+
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>.";
|
|
10897
10901
|
if (legacyTarget === "search-existing-companies")
|
|
10898
10902
|
return "Search BB and QuickBooks companies without writes. --query <name> [--page <number>].";
|
|
10899
10903
|
if (legacyTarget === "use-existing-company")
|
|
@@ -11823,7 +11827,7 @@ Approvals
|
|
|
11823
11827
|
reject-bill <billId> --reason <text> (also sends requester reply email)
|
|
11824
11828
|
approve-budget <budgetId> (also sends requester reply email)
|
|
11825
11829
|
reject-budget <budgetId> --reason <text> (also sends requester reply email)
|
|
11826
|
-
approve-supplier <supplierId> (
|
|
11830
|
+
approve-supplier <supplierId> (approve a pending request, or Admin/Lead re-approve a rejected supplier)
|
|
11827
11831
|
reject-supplier <supplierId> --reason <text> (also sends requester reply email)
|
|
11828
11832
|
|
|
11829
11833
|
Companies & projects
|
|
@@ -12258,7 +12262,7 @@ Waiting for approval\u2026
|
|
|
12258
12262
|
}
|
|
12259
12263
|
configureAccessToken(accessToken);
|
|
12260
12264
|
}
|
|
12261
|
-
if (!resolvedCommand.isLegacyAlias && cmd !== "create-bill" && cmd !== "import-qbo-customer-invoice" && resolvedCommand.command.effects.length > 0) {
|
|
12265
|
+
if (!resolvedCommand.isLegacyAlias && cmd !== "create-bill" && cmd !== "import-qbo-customer-invoice" && cmd !== "approve-supplier" && resolvedCommand.command.effects.length > 0) {
|
|
12262
12266
|
await confirmCurrentCommand({
|
|
12263
12267
|
action: resolvedCommand.command.path.join(" "),
|
|
12264
12268
|
target: commandConfirmationTarget(resolvedCommand),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@go-labs-sg/bb",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.45.1",
|
|
4
4
|
"description": "Budget Builder CLI for AI agents — manage budgets, bills, claims, quotations, and customer invoices with explicit workflow previews for sensitive changes.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -25,7 +25,7 @@ The Budget Builder API, not the CLI, makes the final decision. A request may nee
|
|
|
25
25
|
2. A sufficient current database role: `USER`, `INSIDE_SALES`, `LEAD`, `ACCOUNTING_TEAM`, or `ADMIN`. Pending approval assignment does not preserve decision authority after a role change.
|
|
26
26
|
3. Access to the specific resource, commonly through creator ownership or project assignment as Business Development, Inside Sales, or Project Manager.
|
|
27
27
|
4. A compatible resource state, such as a bill being `DRAFT` or `REJECTED` before editing.
|
|
28
|
-
5. A pending approval record assigned to the current user for
|
|
28
|
+
5. A pending approval record assigned to the current user for request decisions. Direct Admin/Lead re-approval of a rejected supplier does not require a pending request.
|
|
29
29
|
6. Required evidence and consistent related records, such as payment proof, approved quotation coverage, or matching project/budget IDs.
|
|
30
30
|
|
|
31
31
|
Therefore, two users with the same role can receive different results for the same command and different resource IDs.
|
|
@@ -95,7 +95,8 @@ This table highlights the role-sensitive command groups an agent is most likely
|
|
|
95
95
|
| `bb project hub status`, `bb project hub setup`, and `bb project hub sync` | `ADMIN`, project creator, or project assignment as Business Development, Inside Sales, or Project Manager. Setup and sync also enforce Project Hub lifecycle/readiness checks. |
|
|
96
96
|
| `bb supplier update`, `bb item update`, `bb item category update` | Any active authenticated role. Normal-user supplier edits are submitted for approval by the shared API; item/category edits apply immediately. Human review and provider synchronization can temporarily block further supplier edits/new usage. |
|
|
97
97
|
| Edit/delete a bill or quotation | Usually creator or `ADMIN`, with a supported status. |
|
|
98
|
-
| `bb budget approve`, `bb budget reject`,
|
|
98
|
+
| `bb budget approve`, `bb budget reject`, and `bb supplier reject` | Current user must be the pending approver and currently have role `LEAD` or `ADMIN`. |
|
|
99
|
+
| `bb supplier approve` | `LEAD` or `ADMIN`. Pending suppliers require an assigned pending request; rejected suppliers can be directly re-approved without one. Re-approval preserves archive state and does not send a requester email. |
|
|
99
100
|
| `bb bill approve` and `bb bill reject` | Current user must be the pending approver and currently have role `ACCOUNTING_TEAM` for the finance/check stage or `ADMIN` for the final approval stage. |
|
|
100
101
|
| `bb quotation approve` and `bb quotation reject` | Current user must be the pending approver and currently have role `ADMIN`; a normal submitter cannot decide the quotation. |
|
|
101
102
|
| `bb bill status update ... CHECKED` | `ACCOUNTING_TEAM` or `ADMIN`. |
|