@binaryandthread/cli 0.1.3 → 0.1.5
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/bin.js +135 -78
- package/dist/bin.js.map +1 -1
- package/dist/{chunk-IM3HF7NN.js → chunk-AAN4VWP3.js} +2 -2
- package/dist/{chunk-IM3HF7NN.js.map → chunk-AAN4VWP3.js.map} +1 -1
- package/dist/{chunk-7FH7BZ3I.js → chunk-VRNJLVHX.js} +230 -36
- package/dist/chunk-VRNJLVHX.js.map +1 -0
- package/dist/{interactive-DZ67P6UX.js → interactive-WFI5K77G.js} +2 -2
- package/dist/{prompts-GTC5VYM6.js → prompts-DDVV5RE6.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-7FH7BZ3I.js.map +0 -1
- /package/dist/{interactive-DZ67P6UX.js.map → interactive-WFI5K77G.js.map} +0 -0
- /package/dist/{prompts-GTC5VYM6.js.map → prompts-DDVV5RE6.js.map} +0 -0
package/dist/bin.js
CHANGED
|
@@ -7,10 +7,11 @@ import {
|
|
|
7
7
|
} from "./chunk-OVG37IIX.js";
|
|
8
8
|
import {
|
|
9
9
|
makePrompts
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-AAN4VWP3.js";
|
|
11
11
|
import {
|
|
12
12
|
BT_DEFAULT_PUBLISHABLE_KEY,
|
|
13
13
|
BT_DEFAULT_STORE_URL,
|
|
14
|
+
EXIT,
|
|
14
15
|
GLYPH,
|
|
15
16
|
RecoverableCartError,
|
|
16
17
|
StoreApiError,
|
|
@@ -27,24 +28,27 @@ import {
|
|
|
27
28
|
firstPrice,
|
|
28
29
|
fmtPrice,
|
|
29
30
|
formatCartLine,
|
|
31
|
+
formatFatal,
|
|
30
32
|
green,
|
|
31
33
|
header,
|
|
32
34
|
lineColour,
|
|
33
35
|
ok,
|
|
34
36
|
printResult,
|
|
35
37
|
productColours,
|
|
38
|
+
productLore,
|
|
36
39
|
redact,
|
|
37
40
|
registerStage,
|
|
38
41
|
registerView,
|
|
39
42
|
resolveLineItemRef,
|
|
40
43
|
resolveOutput,
|
|
44
|
+
resolveProduct,
|
|
41
45
|
rule,
|
|
42
46
|
runStage,
|
|
43
47
|
stageMarker,
|
|
44
48
|
versionLine,
|
|
45
49
|
warn,
|
|
46
50
|
working
|
|
47
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-VRNJLVHX.js";
|
|
48
52
|
import {
|
|
49
53
|
__require
|
|
50
54
|
} from "./chunk-7OCVIDC7.js";
|
|
@@ -73,7 +77,7 @@ function makeLogger(debug, write = (s) => process.stderr.write(s)) {
|
|
|
73
77
|
}
|
|
74
78
|
|
|
75
79
|
// src/version.ts
|
|
76
|
-
var VERSION = "0.1.
|
|
80
|
+
var VERSION = "0.1.5";
|
|
77
81
|
|
|
78
82
|
// src/eggs.ts
|
|
79
83
|
function teapot() {
|
|
@@ -102,6 +106,21 @@ function rmWardrobe() {
|
|
|
102
106
|
function force() {
|
|
103
107
|
return "--force-pushing to prod, are we. there's no --force here \u2014\n a commit to your wardrobe is already that decisive.";
|
|
104
108
|
}
|
|
109
|
+
function gitClone() {
|
|
110
|
+
return "no clone for a fit \u2014 each one's committed by hand. browse the originals \u2192 bt browse";
|
|
111
|
+
}
|
|
112
|
+
function gitStash() {
|
|
113
|
+
return "that's bt unstage here. your cart holds; nothing's lost.";
|
|
114
|
+
}
|
|
115
|
+
function gitPush() {
|
|
116
|
+
return "no remote for your wardrobe. the only push that ships \u2192 bt commit";
|
|
117
|
+
}
|
|
118
|
+
function gitPull() {
|
|
119
|
+
return "nothing to pull \u2014 the freshest designs land as drops \u2192 bt drops";
|
|
120
|
+
}
|
|
121
|
+
function gitReflog() {
|
|
122
|
+
return "nothing's ever truly lost here. your history \u2192 bt log";
|
|
123
|
+
}
|
|
105
124
|
var FORTUNES = [
|
|
106
125
|
'// "there are only two hard things in computer science: cache invalidation and naming things." \u2014 phil karlton',
|
|
107
126
|
'// "premature optimization is the root of all evil." \u2014 donald knuth',
|
|
@@ -180,50 +199,6 @@ function manPage(version) {
|
|
|
180
199
|
];
|
|
181
200
|
}
|
|
182
201
|
|
|
183
|
-
// src/errors.ts
|
|
184
|
-
var EXIT = {
|
|
185
|
-
OK: 0,
|
|
186
|
-
GENERIC: 1,
|
|
187
|
-
DATAERR: 65,
|
|
188
|
-
// EX_DATAERR — bad request / unprocessable / stale cart (400/409/422)
|
|
189
|
-
UNAVAILABLE: 69,
|
|
190
|
-
// EX_UNAVAILABLE — not found (404)
|
|
191
|
-
TEMPFAIL: 75,
|
|
192
|
-
// EX_TEMPFAIL — temporary: 5xx, network/exhausted, rate-limited (429)
|
|
193
|
-
NOPERM: 77
|
|
194
|
-
// EX_NOPERM — auth required / forbidden (401/403)
|
|
195
|
-
};
|
|
196
|
-
function messageOf(e) {
|
|
197
|
-
if (e instanceof Error && e.message) {
|
|
198
|
-
return e.message;
|
|
199
|
-
}
|
|
200
|
-
const s = String(e ?? "").trim();
|
|
201
|
-
return s || "unexpected error";
|
|
202
|
-
}
|
|
203
|
-
function classifyError(e) {
|
|
204
|
-
const message = String(redact(messageOf(e)));
|
|
205
|
-
if (e instanceof RecoverableCartError) {
|
|
206
|
-
return { code: EXIT.DATAERR, type: "stale_cart", status: e.status, message };
|
|
207
|
-
}
|
|
208
|
-
if (e instanceof StoreApiError) {
|
|
209
|
-
const s = e.status;
|
|
210
|
-
if (s === 401 || s === 403) return { code: EXIT.NOPERM, type: "auth", status: s, message };
|
|
211
|
-
if (s === 404) return { code: EXIT.UNAVAILABLE, type: "not_found", status: s, message };
|
|
212
|
-
if (s === 429) return { code: EXIT.TEMPFAIL, type: "rate_limited", status: s, message };
|
|
213
|
-
if (s === 0 || s === 408 || s >= 500) return { code: EXIT.TEMPFAIL, type: "upstream", status: s, message };
|
|
214
|
-
if (s >= 400) return { code: EXIT.DATAERR, type: "client_error", status: s, message };
|
|
215
|
-
}
|
|
216
|
-
return { code: EXIT.GENERIC, type: "error", message };
|
|
217
|
-
}
|
|
218
|
-
function formatFatal(e, json) {
|
|
219
|
-
const info = classifyError(e);
|
|
220
|
-
if (json) {
|
|
221
|
-
const envelope = { error: { code: info.code, type: info.type, message: info.message } };
|
|
222
|
-
return { out: JSON.stringify(envelope, null, 2), err: null, code: info.code };
|
|
223
|
-
}
|
|
224
|
-
return { out: null, err: `\u2717 ${info.message}`, code: info.code };
|
|
225
|
-
}
|
|
226
|
-
|
|
227
202
|
// src/is-main.ts
|
|
228
203
|
import { realpathSync } from "fs";
|
|
229
204
|
import { fileURLToPath } from "url";
|
|
@@ -312,19 +287,20 @@ function deleteToken(deps = {}) {
|
|
|
312
287
|
}
|
|
313
288
|
|
|
314
289
|
// src/commands/browse.ts
|
|
315
|
-
function productRow(p, stage, style) {
|
|
290
|
+
function productRow(p, index, stage, style) {
|
|
316
291
|
const { amount, currency } = firstPrice(p);
|
|
317
292
|
const { title, handle } = displayName(p);
|
|
318
293
|
const colours = colourMarker(productColours(p));
|
|
294
|
+
const ref = dim(style, `[${index + 1}]`.padEnd(4));
|
|
319
295
|
const parts = [
|
|
320
296
|
title.padEnd(22),
|
|
321
297
|
cyan(style, fmtPrice(amount, currency).padEnd(11)),
|
|
322
|
-
dim(style, handle.padEnd(
|
|
298
|
+
dim(style, handle.padEnd(30)),
|
|
323
299
|
stageMarker(stage)
|
|
324
300
|
];
|
|
325
|
-
const row = parts.join(" ")
|
|
301
|
+
const row = `${ref} ${parts.join(" ")}`.trimEnd();
|
|
326
302
|
return colours ? `${row}
|
|
327
|
-
|
|
303
|
+
${dim(style, colours)}` : row;
|
|
328
304
|
}
|
|
329
305
|
async function runBrowse(client, config, args) {
|
|
330
306
|
const style = brandOf(args);
|
|
@@ -344,9 +320,9 @@ async function runBrowse(client, config, args) {
|
|
|
344
320
|
lines.push(" peek at next \u2192 bt browse --branch=next");
|
|
345
321
|
} else {
|
|
346
322
|
lines.push(header(style, "bt browse \u2014 in stock"));
|
|
347
|
-
|
|
348
|
-
lines.push(productRow(p, stage, style));
|
|
349
|
-
}
|
|
323
|
+
rows.forEach(({ p, stage }, i) => {
|
|
324
|
+
lines.push(productRow(p, i, stage, style));
|
|
325
|
+
});
|
|
350
326
|
for (const d of drops) {
|
|
351
327
|
const dt = (d.title ?? d.handle ?? d.id).toString();
|
|
352
328
|
lines.push(
|
|
@@ -361,7 +337,7 @@ async function runBrowse(client, config, args) {
|
|
|
361
337
|
if (drops.length > 0) {
|
|
362
338
|
lines.push(" on next, before the web \u2192 bt drops");
|
|
363
339
|
}
|
|
364
|
-
lines.push(" view one \u2192 bt view <
|
|
340
|
+
lines.push(" view one \u2192 bt view <n|slug> \xB7 stage one \u2192 bt stage <n|slug> --size L");
|
|
365
341
|
}
|
|
366
342
|
return {
|
|
367
343
|
lines,
|
|
@@ -377,10 +353,10 @@ async function runBrowse(client, config, args) {
|
|
|
377
353
|
};
|
|
378
354
|
}
|
|
379
355
|
function registerBrowse(program, makeClient2, loadConfig2) {
|
|
380
|
-
program.command("browse").alias("ls").description("list what's in stock on a branch.").option("--branch <branch>", "main (live) or next (terminal-only drops)").option("--plain", "force the static table (
|
|
356
|
+
program.command("browse").alias("ls").description("list what's in stock on a branch.").option("--branch <branch>", "main (live) or next (terminal-only drops)").option("--pick", "opt into the arrow-key picker (default is the numbered table \u2014 use bt stage <n>)").option("--plain", "force the static table (the default; kept for back-compat)").action(async (opts) => {
|
|
381
357
|
const { json, brand } = resolveOutput(program);
|
|
382
|
-
if (
|
|
383
|
-
const { runInteractiveBrowse } = await import("./interactive-
|
|
358
|
+
if (opts.pick && !json && brand.color && process.stdout.isTTY && process.stdin.isTTY) {
|
|
359
|
+
const { runInteractiveBrowse } = await import("./interactive-WFI5K77G.js");
|
|
384
360
|
const handled = await runInteractiveBrowse(makeClient2(), loadConfig2(), { branch: opts.branch, brand });
|
|
385
361
|
if (handled) return;
|
|
386
362
|
}
|
|
@@ -497,6 +473,18 @@ function registerCart(program, makeClient2, loadConfig2) {
|
|
|
497
473
|
function supportedCountries(region) {
|
|
498
474
|
return (region.countries ?? []).map((c) => (c.iso_2 ?? "").toLowerCase()).filter((c) => c.length > 0);
|
|
499
475
|
}
|
|
476
|
+
var HEARTBEAT_EVERY_TICKS = 6;
|
|
477
|
+
function heartbeatLine(attempt, opts = {}) {
|
|
478
|
+
const everyTicks = opts.everyTicks ?? HEARTBEAT_EVERY_TICKS;
|
|
479
|
+
if (attempt <= 1 || (attempt - 1) % everyTicks !== 0) {
|
|
480
|
+
return null;
|
|
481
|
+
}
|
|
482
|
+
const intervalMs = opts.intervalMs ?? 5e3;
|
|
483
|
+
const elapsedS = Math.round((attempt - 1) * intervalMs / 1e3);
|
|
484
|
+
return working(
|
|
485
|
+
`still waiting for the browser hand-off, ${elapsedS}s in. ctrl-c is safe; resume with bt checkout --resume`
|
|
486
|
+
);
|
|
487
|
+
}
|
|
500
488
|
async function runCheckout(client, config, args, deps) {
|
|
501
489
|
const cartId = config.cart_id;
|
|
502
490
|
if (!cartId) {
|
|
@@ -562,7 +550,9 @@ async function runCheckout(client, config, args, deps) {
|
|
|
562
550
|
what: "couldn't attach a shipping method to your cart.",
|
|
563
551
|
fix: "this region may not have shipping configured yet \u2014 try again shortly, or re-stage."
|
|
564
552
|
})
|
|
565
|
-
]
|
|
553
|
+
],
|
|
554
|
+
exitCode: EXIT.GENERIC
|
|
555
|
+
// fail-closed, no order placed → non-zero (matches the shown exit 1)
|
|
566
556
|
};
|
|
567
557
|
}
|
|
568
558
|
const itemCount = cart.items.reduce((n, li) => n + (li.quantity ?? 1), 0);
|
|
@@ -616,7 +606,9 @@ async function runCheckout(client, config, args, deps) {
|
|
|
616
606
|
link: checkout_url
|
|
617
607
|
})
|
|
618
608
|
],
|
|
619
|
-
save
|
|
609
|
+
save,
|
|
610
|
+
exitCode: EXIT.TEMPFAIL
|
|
611
|
+
// lost the connection mid-poll → not confirmed → non-zero (75)
|
|
620
612
|
};
|
|
621
613
|
}
|
|
622
614
|
const lines = [];
|
|
@@ -648,7 +640,7 @@ async function runCheckout(client, config, args, deps) {
|
|
|
648
640
|
warn("your stage expired before checkout completed. nothing was charged.")
|
|
649
641
|
);
|
|
650
642
|
lines.push(" re-stage \u2192 bt stage <slug> then bt checkout");
|
|
651
|
-
return { lines, save, json: args.json ? { status: "expired" } : void 0 };
|
|
643
|
+
return { lines, save, json: args.json ? { status: "expired" } : void 0, exitCode: EXIT.TEMPFAIL };
|
|
652
644
|
}
|
|
653
645
|
lines.push("");
|
|
654
646
|
lines.push(
|
|
@@ -660,7 +652,13 @@ async function runCheckout(client, config, args, deps) {
|
|
|
660
652
|
link: checkout_url
|
|
661
653
|
})
|
|
662
654
|
);
|
|
663
|
-
return {
|
|
655
|
+
return {
|
|
656
|
+
lines,
|
|
657
|
+
save,
|
|
658
|
+
json: args.json ? { status: "timeout", checkout_url } : void 0,
|
|
659
|
+
exitCode: EXIT.TEMPFAIL
|
|
660
|
+
// handoff timed out → not placed → non-zero (matches the shown exit 75)
|
|
661
|
+
};
|
|
664
662
|
}
|
|
665
663
|
async function resolveDisplayId(client, orderId, email) {
|
|
666
664
|
if (!orderId) {
|
|
@@ -687,11 +685,13 @@ function maskEmail(email) {
|
|
|
687
685
|
function registerCheckout(program, makeClient2, loadConfig2) {
|
|
688
686
|
const action = async (opts) => {
|
|
689
687
|
const { json, brand } = resolveOutput(program);
|
|
690
|
-
const { makePrompts: makePrompts2 } = await import("./prompts-
|
|
688
|
+
const { makePrompts: makePrompts2 } = await import("./prompts-DDVV5RE6.js");
|
|
691
689
|
const { openCheckout } = await import("./browser-EO5EQUXQ.js");
|
|
692
690
|
const { pollUntilPlaced } = await import("./poll-O3VUD5WV.js");
|
|
693
691
|
const { saveConfig: saveConfig2 } = await import("./config-FXGCWC6Y.js");
|
|
694
692
|
const client = makeClient2();
|
|
693
|
+
const print = json ? () => {
|
|
694
|
+
} : (line) => process.stdout.write(line + "\n");
|
|
695
695
|
const res = await runCheckout(
|
|
696
696
|
client,
|
|
697
697
|
loadConfig2(),
|
|
@@ -699,11 +699,16 @@ function registerCheckout(program, makeClient2, loadConfig2) {
|
|
|
699
699
|
{
|
|
700
700
|
prompts: makePrompts2(),
|
|
701
701
|
open: (url) => openCheckout(url),
|
|
702
|
-
|
|
702
|
+
// Heartbeat the browser-hop wait so the terminal never looks hung (a dim, calm line every
|
|
703
|
+
// ~30s). Suppressed under --json (print is a no-op there).
|
|
704
|
+
poll: (sessionId) => pollUntilPlaced(client, sessionId, {
|
|
705
|
+
onTick: (attempt) => {
|
|
706
|
+
const line = heartbeatLine(attempt);
|
|
707
|
+
if (line) print(dim(brand, line));
|
|
708
|
+
}
|
|
709
|
+
}),
|
|
703
710
|
saveConfig: saveConfig2,
|
|
704
|
-
|
|
705
|
-
print: json ? () => {
|
|
706
|
-
} : (line) => process.stdout.write(line + "\n")
|
|
711
|
+
print
|
|
707
712
|
}
|
|
708
713
|
);
|
|
709
714
|
if (res.save && Object.keys(res.save).length > 0) {
|
|
@@ -1424,8 +1429,8 @@ function runInit(args) {
|
|
|
1424
1429
|
" buy heavyweight pieces from your terminal. zero setup \u2014 you're already pointed at the live store.",
|
|
1425
1430
|
"",
|
|
1426
1431
|
" the happy path:",
|
|
1427
|
-
" bt browse # the catalog
|
|
1428
|
-
" bt stage <
|
|
1432
|
+
" bt browse # the catalog, numbered",
|
|
1433
|
+
" bt stage <n|slug> --size L # add to your cart (a browse number, or a slug)",
|
|
1429
1434
|
" bt checkout # pay in your browser \u2014 cards never touch the terminal",
|
|
1430
1435
|
"",
|
|
1431
1436
|
" optional:",
|
|
@@ -1467,24 +1472,34 @@ async function runBuy(client, config, args, deps) {
|
|
|
1467
1472
|
return {
|
|
1468
1473
|
lines: [...staged.lines, "", ...checked.lines],
|
|
1469
1474
|
save: { ...staged.save ?? {}, ...checked.save ?? {} },
|
|
1470
|
-
json: args.json ? { cart_id: cartId, checkout: checked.json ?? null } : void 0
|
|
1475
|
+
json: args.json ? { cart_id: cartId, checkout: checked.json ?? null } : void 0,
|
|
1476
|
+
// forward the checkout outcome's exit code — bt buy runs the SAME money-path poll as bt
|
|
1477
|
+
// checkout, so a timed-out/failed composed checkout must not report success (d10).
|
|
1478
|
+
exitCode: checked.exitCode
|
|
1471
1479
|
};
|
|
1472
1480
|
}
|
|
1473
1481
|
function registerBuy(program, makeClient2, loadConfig2) {
|
|
1474
|
-
program.command("buy").argument("<handle>", "the
|
|
1482
|
+
program.command("buy").argument("<handle>", "the design: a slug, a bt browse number (3), or a fuzzy hint (termnl)").option("--size <size>", "garment size").option("--colour <colour>", "colour, e.g. white / black").description("stage + checkout in one \u2014 reserve, then open browser checkout. cards never touch the terminal.").action(async (handle, opts) => {
|
|
1475
1483
|
const { json, brand } = resolveOutput(program);
|
|
1476
|
-
const { makePrompts: makePrompts2 } = await import("./prompts-
|
|
1484
|
+
const { makePrompts: makePrompts2 } = await import("./prompts-DDVV5RE6.js");
|
|
1477
1485
|
const { openCheckout } = await import("./browser-EO5EQUXQ.js");
|
|
1478
1486
|
const { pollUntilPlaced } = await import("./poll-O3VUD5WV.js");
|
|
1479
1487
|
const { saveConfig: saveConfig2 } = await import("./config-FXGCWC6Y.js");
|
|
1480
1488
|
const client = makeClient2();
|
|
1489
|
+
const print = json ? () => {
|
|
1490
|
+
} : (line) => process.stdout.write(line + "\n");
|
|
1481
1491
|
const res = await runBuy(client, loadConfig2(), { handle, size: opts.size, colour: opts.colour, json, brand }, {
|
|
1482
1492
|
prompts: makePrompts2(),
|
|
1483
1493
|
open: (url) => openCheckout(url),
|
|
1484
|
-
|
|
1494
|
+
// Same heartbeat as bt checkout — bt buy's browser-hop wait is the identical 20-min poll.
|
|
1495
|
+
poll: (sessionId) => pollUntilPlaced(client, sessionId, {
|
|
1496
|
+
onTick: (attempt) => {
|
|
1497
|
+
const line = heartbeatLine(attempt);
|
|
1498
|
+
if (line) print(dim(brand, line));
|
|
1499
|
+
}
|
|
1500
|
+
}),
|
|
1485
1501
|
saveConfig: saveConfig2,
|
|
1486
|
-
print
|
|
1487
|
-
} : (line) => process.stdout.write(line + "\n")
|
|
1502
|
+
print
|
|
1488
1503
|
});
|
|
1489
1504
|
if (res.save && Object.keys(res.save).length > 0) {
|
|
1490
1505
|
saveConfig2(res.save);
|
|
@@ -1630,7 +1645,7 @@ function registerReport(program, makeClient2) {
|
|
|
1630
1645
|
const gOpts = program.opts();
|
|
1631
1646
|
const json = Boolean(gOpts.json);
|
|
1632
1647
|
const debug = process.argv.includes("--debug") || process.argv.includes("--verbose");
|
|
1633
|
-
const { makePrompts: makePrompts2 } = await import("./prompts-
|
|
1648
|
+
const { makePrompts: makePrompts2 } = await import("./prompts-DDVV5RE6.js");
|
|
1634
1649
|
const snapshot = gatherDoctorSnapshot({ color: gOpts.color });
|
|
1635
1650
|
const res = await runReport(
|
|
1636
1651
|
makeClient2(),
|
|
@@ -1641,6 +1656,43 @@ function registerReport(program, makeClient2) {
|
|
|
1641
1656
|
});
|
|
1642
1657
|
}
|
|
1643
1658
|
|
|
1659
|
+
// src/commands/blame.ts
|
|
1660
|
+
async function runBlame(client, config, args) {
|
|
1661
|
+
const slug = (args.handle ?? "").trim();
|
|
1662
|
+
if (!slug) {
|
|
1663
|
+
return { lines: blame().split("\n") };
|
|
1664
|
+
}
|
|
1665
|
+
const region = await client.resolveRegion(config.region);
|
|
1666
|
+
const picked = await resolveProduct(client, region, slug);
|
|
1667
|
+
const product = picked.product;
|
|
1668
|
+
if (!product) {
|
|
1669
|
+
return { lines: blame(slug).split("\n") };
|
|
1670
|
+
}
|
|
1671
|
+
const { handle } = displayName(product);
|
|
1672
|
+
const lore = productLore(product);
|
|
1673
|
+
const lines = [];
|
|
1674
|
+
if (picked.fuzzy && handle !== slug) {
|
|
1675
|
+
lines.push(working(`matched "${handle}" from "${slug}"`));
|
|
1676
|
+
}
|
|
1677
|
+
if (!lore.text) {
|
|
1678
|
+
lines.push(...blame(handle).split("\n"));
|
|
1679
|
+
return { lines, json: args.json ? { handle, lore: null } : void 0 };
|
|
1680
|
+
}
|
|
1681
|
+
lines.push(`blame ${handle}`);
|
|
1682
|
+
lines.push(` ${lore.text}`);
|
|
1683
|
+
for (const s of lore.sources) {
|
|
1684
|
+
lines.push(` source ${s.label} (${s.url})`);
|
|
1685
|
+
}
|
|
1686
|
+
return { lines, json: args.json ? { handle, lore } : void 0 };
|
|
1687
|
+
}
|
|
1688
|
+
function registerBlame(program, makeClient2, loadConfig2) {
|
|
1689
|
+
program.command("blame", { hidden: true }).argument("[slug]", "a design \u2014 a slug, a bt browse number, or a fuzzy hint").description("who's responsible for a design \u2014 its lore + sources (git blame, for motifs).").action(async (slug) => {
|
|
1690
|
+
const { json, brand } = resolveOutput(program);
|
|
1691
|
+
const res = await runBlame(makeClient2(), loadConfig2(), { handle: slug, json, brand });
|
|
1692
|
+
printResult(res, json);
|
|
1693
|
+
});
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1644
1696
|
// src/bin.ts
|
|
1645
1697
|
function makeClient() {
|
|
1646
1698
|
const { baseUrl, publishableKey } = resolveClientConfig();
|
|
@@ -1657,7 +1709,7 @@ function buildProgram() {
|
|
|
1657
1709
|
const program = new Command();
|
|
1658
1710
|
program.name("bt").description(
|
|
1659
1711
|
"the binary & thread terminal store. techno-minimalist clothing & lifestyle, bought with the ceremony of a deploy.\nprimary invocation: npx @binaryandthread/cli (a bare `bt` may collide with another binary)"
|
|
1660
|
-
).version(versionLine(VERSION), "-v, --version", "print the version").option("--json", "machine-readable output", false).option("--no-color", "disable ANSI colour + inline images (also honours NO_COLOR)").option("--debug, --verbose", "trace requests to stderr (redacted) \u2014 for bug reports (d15)");
|
|
1712
|
+
).version(versionLine(VERSION), "-v, --version", "print the version").option("--json", "machine-readable output", false).option("--no-color", "disable ANSI colour + inline images (also honours NO_COLOR)").option("--debug, --verbose", "trace requests to stderr (redacted) \u2014 for bug reports (d15)").showSuggestionAfterError();
|
|
1661
1713
|
program.addHelpText("beforeAll", "\n bt \u2014 the binary & thread terminal store. new here? \u2192 bt init\n");
|
|
1662
1714
|
program.command("brew").argument("[what]", "what to brew").description("we make clothing, not coffee.").action(() => {
|
|
1663
1715
|
process.stdout.write(teapot() + "\n");
|
|
@@ -1696,6 +1748,7 @@ function registerCommands(program) {
|
|
|
1696
1748
|
registerToken(program);
|
|
1697
1749
|
registerDoctor(program);
|
|
1698
1750
|
registerReport(program, makeClient);
|
|
1751
|
+
registerBlame(program, makeClient, loadConfig);
|
|
1699
1752
|
registerCart(program, makeClient, loadConfig);
|
|
1700
1753
|
registerCheckout(program, makeClient, loadConfig);
|
|
1701
1754
|
registerOrder(program, makeClient, loadConfig);
|
|
@@ -1731,7 +1784,11 @@ function registerEggs(program) {
|
|
|
1731
1784
|
program.command("ship", { hidden: true }).argument("[what]").action(() => print(shipIt()));
|
|
1732
1785
|
program.command("rm", { hidden: true }).allowUnknownOption().argument("[args...]").action(() => print(rmWardrobe()));
|
|
1733
1786
|
program.command("force", { hidden: true }).allowUnknownOption().argument("[args...]").action(() => print(force()));
|
|
1734
|
-
program.command("
|
|
1787
|
+
program.command("clone", { hidden: true }).allowUnknownOption().argument("[args...]").action(() => print(gitClone()));
|
|
1788
|
+
program.command("stash", { hidden: true }).allowUnknownOption().argument("[args...]").action(() => print(gitStash()));
|
|
1789
|
+
program.command("push", { hidden: true }).allowUnknownOption().argument("[args...]").action(() => print(gitPush()));
|
|
1790
|
+
program.command("pull", { hidden: true }).allowUnknownOption().argument("[args...]").action(() => print(gitPull()));
|
|
1791
|
+
program.command("reflog", { hidden: true }).allowUnknownOption().argument("[args...]").action(() => print(gitReflog()));
|
|
1735
1792
|
program.command("fortune").description("a coding fortune. real aphorisms only.").action(() => {
|
|
1736
1793
|
const seed = Math.floor(Date.now() / 1e3) % FORTUNES.length;
|
|
1737
1794
|
print(fortune(seed));
|