@kaynooo/cli-docker 0.6.0 → 0.8.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/dc-cli.js +94 -47
- package/dist/dlog-cli.js +94 -47
- package/dist/dx-cli.js +176 -69
- package/dist/sf-cli.js +194 -81
- package/package.json +3 -3
- package/src/dc.ts +2 -2
- package/src/dx.ts +2 -2
- package/src/sf.ts +2 -2
- package/src/stack.ts +2 -3
package/dist/dx-cli.js
CHANGED
|
@@ -2,13 +2,37 @@
|
|
|
2
2
|
// @bun
|
|
3
3
|
|
|
4
4
|
// src/dx-cli.ts
|
|
5
|
-
import
|
|
5
|
+
import process18 from "process";
|
|
6
6
|
// ../kit/src/args.ts
|
|
7
|
-
import
|
|
7
|
+
import process9 from "process";
|
|
8
8
|
import { parseArgs } from "util";
|
|
9
9
|
|
|
10
|
+
// ../kit/src/format.ts
|
|
11
|
+
import process7 from "process";
|
|
12
|
+
|
|
13
|
+
// ../kit/src/mode.ts
|
|
14
|
+
import process2 from "process";
|
|
15
|
+
var MODES = new Set(["terminal", "ci", "agent", "pipe"]);
|
|
16
|
+
var AGENT_VARIABLES = ["CLAUDECODE", "AI_AGENT"];
|
|
17
|
+
function isSet(value) {
|
|
18
|
+
return value !== undefined && value !== "" && value !== "0" && value.toLowerCase() !== "false";
|
|
19
|
+
}
|
|
20
|
+
function outputMode(stream = process2.stdout, env = process2.env) {
|
|
21
|
+
const chosen = env.KIT_MODE;
|
|
22
|
+
if (chosen !== undefined && MODES.has(chosen))
|
|
23
|
+
return chosen;
|
|
24
|
+
if (AGENT_VARIABLES.some((name) => isSet(env[name])))
|
|
25
|
+
return "agent";
|
|
26
|
+
if (stream.isTTY === true)
|
|
27
|
+
return "terminal";
|
|
28
|
+
return isSet(env.CI) ? "ci" : "pipe";
|
|
29
|
+
}
|
|
30
|
+
function isInteractive(streams = process2) {
|
|
31
|
+
return streams.stdin?.isTTY === true && streams.stderr?.isTTY === true;
|
|
32
|
+
}
|
|
33
|
+
|
|
10
34
|
// ../kit/src/style.ts
|
|
11
|
-
import
|
|
35
|
+
import process6 from "process";
|
|
12
36
|
|
|
13
37
|
// ../../node_modules/.bun/@kaynooo+utils@2.31.2+d0769e28dc4dad16/node_modules/@kaynooo/utils/dist/chunk-mtetydvc.js
|
|
14
38
|
function x(s) {
|
|
@@ -275,13 +299,13 @@ var t = le();
|
|
|
275
299
|
import { existsSync as existsSync2, readFileSync, statSync } from "fs";
|
|
276
300
|
import { homedir as homedir2 } from "os";
|
|
277
301
|
import { join as join3, resolve as resolve2 } from "path";
|
|
278
|
-
import
|
|
302
|
+
import process5 from "process";
|
|
279
303
|
|
|
280
304
|
// ../kit/src/config.ts
|
|
281
305
|
import { existsSync } from "fs";
|
|
282
306
|
import { dirname, join, resolve } from "path";
|
|
283
|
-
import
|
|
284
|
-
function findUp(names, from =
|
|
307
|
+
import process3 from "process";
|
|
308
|
+
function findUp(names, from = process3.cwd(), stop = () => false) {
|
|
285
309
|
const wanted = typeof names === "string" ? [names] : names;
|
|
286
310
|
for (let dir = resolve(from);; dir = dirname(dir)) {
|
|
287
311
|
const found = wanted.map((name) => join(dir, name)).find((path) => existsSync(path));
|
|
@@ -295,9 +319,9 @@ function findUp(names, from = process2.cwd(), stop = () => false) {
|
|
|
295
319
|
// ../kit/src/user-config.ts
|
|
296
320
|
import { homedir } from "os";
|
|
297
321
|
import { join as join2 } from "path";
|
|
298
|
-
import
|
|
322
|
+
import process4 from "process";
|
|
299
323
|
function configBase(where = {}) {
|
|
300
|
-
const xdg = where.xdg ?? (where.home === undefined ?
|
|
324
|
+
const xdg = where.xdg ?? (where.home === undefined ? process4.env.XDG_CONFIG_HOME : undefined);
|
|
301
325
|
return xdg !== undefined && xdg !== "" ? xdg : join2(where.home ?? homedir(), ".config");
|
|
302
326
|
}
|
|
303
327
|
function userConfigPath(bin, where = {}) {
|
|
@@ -330,10 +354,30 @@ function isColorSpec(spec) {
|
|
|
330
354
|
return Number.isInteger(spec) && spec >= 0 && spec <= 255;
|
|
331
355
|
return typeof spec === "string" && spec.trim() !== "" && spec.trim().split(SPACES).every((token) => STYLES.has(token) || HEX.test(token));
|
|
332
356
|
}
|
|
333
|
-
|
|
357
|
+
var CUBE = [0, 95, 135, 175, 215, 255];
|
|
358
|
+
function cubeLevel(channel) {
|
|
359
|
+
return CUBE.reduce((best, value, level) => Math.abs(value - channel) < Math.abs(CUBE[best] - channel) ? level : best, 0);
|
|
360
|
+
}
|
|
361
|
+
function nearest256(hex) {
|
|
362
|
+
const rgb = [1, 3, 5].map((at) => Number.parseInt(hex.slice(at, at + 2), 16));
|
|
363
|
+
const levels = rgb.map(cubeLevel);
|
|
364
|
+
const cube = levels.map((level) => CUBE[level]);
|
|
365
|
+
const grey = Math.min(23, Math.max(0, Math.round((rgb.reduce((sum, channel) => sum + channel, 0) / 3 - 8) / 10)));
|
|
366
|
+
const greyValue = 8 + grey * 10;
|
|
367
|
+
const distance = (colour) => colour.reduce((sum, channel, at) => sum + (channel - rgb[at]) ** 2, 0);
|
|
368
|
+
return distance([greyValue, greyValue, greyValue]) < distance(cube) ? 232 + grey : 16 + 36 * levels[0] + 6 * levels[1] + levels[2];
|
|
369
|
+
}
|
|
370
|
+
function hasTrueColor(env) {
|
|
371
|
+
return env.COLORTERM === "truecolor" || env.COLORTERM === "24bit";
|
|
372
|
+
}
|
|
373
|
+
function tinted(colors, spec, env = process5.env) {
|
|
334
374
|
if (typeof spec === "number")
|
|
335
375
|
return colors.ansi256(spec);
|
|
336
|
-
return spec.trim().split(SPACES).reduce((chain, token) =>
|
|
376
|
+
return spec.trim().split(SPACES).reduce((chain, token) => {
|
|
377
|
+
if (HEX.test(token))
|
|
378
|
+
return hasTrueColor(env) ? chain.hex(token) : chain.ansi256(nearest256(token));
|
|
379
|
+
return chain[token] ?? chain;
|
|
380
|
+
}, colors);
|
|
337
381
|
}
|
|
338
382
|
function isRecord(value) {
|
|
339
383
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -417,7 +461,7 @@ function warnOnce(message) {
|
|
|
417
461
|
function isPath(chosen) {
|
|
418
462
|
return chosen.includes("/") || chosen.endsWith(".json");
|
|
419
463
|
}
|
|
420
|
-
function loadTheme({ env =
|
|
464
|
+
function loadTheme({ env = process5.env, from = process5.cwd(), home = homedir2(), warn = warnOnce } = {}) {
|
|
421
465
|
const theme = { colors: { ...DEFAULT.colors }, glyphs: { ...DEFAULT.glyphs }, accents: [...DEFAULT.accents], bins: Object.create(null) };
|
|
422
466
|
const sources = [];
|
|
423
467
|
const chosen = env.KIT_THEME ?? "";
|
|
@@ -447,7 +491,7 @@ function loadTheme({ env = process4.env, from = process4.cwd(), home = homedir2(
|
|
|
447
491
|
var current;
|
|
448
492
|
var currentKey = "";
|
|
449
493
|
function activeTheme() {
|
|
450
|
-
const key = `${
|
|
494
|
+
const key = `${process5.cwd()}\x00${process5.env.KIT_THEME ?? ""}\x00${process5.env.XDG_CONFIG_HOME ?? ""}`;
|
|
451
495
|
if (current === undefined || key !== currentKey) {
|
|
452
496
|
current = loadTheme();
|
|
453
497
|
currentKey = key;
|
|
@@ -456,20 +500,20 @@ function activeTheme() {
|
|
|
456
500
|
}
|
|
457
501
|
|
|
458
502
|
// ../kit/src/style.ts
|
|
459
|
-
function takesControlCodes(stream, env =
|
|
460
|
-
return stream.isTTY === true && env.NO_COLOR === undefined && env.NODE_DISABLE_COLORS === undefined && env.TERM !== "dumb";
|
|
503
|
+
function takesControlCodes(stream, env = process6.env) {
|
|
504
|
+
return stream.isTTY === true && env.NO_COLOR === undefined && env.NODE_DISABLE_COLORS === undefined && env.TERM !== "dumb" && outputMode(stream, env) === "terminal";
|
|
461
505
|
}
|
|
462
|
-
function paint(stream, env =
|
|
506
|
+
function paint(stream, env = process6.env) {
|
|
463
507
|
return le({ stream: { isTTY: takesControlCodes(stream, env) }, env });
|
|
464
508
|
}
|
|
465
|
-
function role(name, stream, env =
|
|
509
|
+
function role(name, stream, env = process6.env) {
|
|
466
510
|
const colors = paint(stream, env);
|
|
467
|
-
return takesControlCodes(stream, env) ? tinted(colors, activeTheme().theme.colors[name]) : colors;
|
|
511
|
+
return takesControlCodes(stream, env) ? tinted(colors, activeTheme().theme.colors[name], env) : colors;
|
|
468
512
|
}
|
|
469
513
|
var STATUS_WORDS = {
|
|
470
514
|
passed: ["passed", "success", "succeeded", "ok"],
|
|
471
515
|
failed: ["failed", "failure", "error", "errored"],
|
|
472
|
-
running: ["running", "in_progress", "started"],
|
|
516
|
+
running: ["running", "in_progress", "started", "holding"],
|
|
473
517
|
queued: ["queued", "waiting", "pending", "created", "blocked", "scheduled"],
|
|
474
518
|
skipped: ["skipped", "cancelled", "canceled", "manual"]
|
|
475
519
|
};
|
|
@@ -481,32 +525,35 @@ function upTo(text, separator) {
|
|
|
481
525
|
return end === -1 ? text : text.slice(0, end);
|
|
482
526
|
}
|
|
483
527
|
var ESCAPE = String.fromCharCode(27);
|
|
528
|
+
function jsonText(value, replacer, { stream = process7.stdout, env = process7.env } = {}) {
|
|
529
|
+
return JSON.stringify(value, replacer, outputMode(stream, env) === "agent" ? undefined : 2);
|
|
530
|
+
}
|
|
484
531
|
function printJson(value) {
|
|
485
|
-
console.log(
|
|
532
|
+
console.log(jsonText(value));
|
|
486
533
|
}
|
|
487
534
|
|
|
488
535
|
// ../kit/src/help.ts
|
|
489
|
-
import
|
|
536
|
+
import process8 from "process";
|
|
490
537
|
var OPTIONAL = /\[[^\]]+\]/g;
|
|
491
538
|
var USAGE_PREFIX = /^usage:\s*/i;
|
|
492
539
|
var FULL_STOP = /\.$/;
|
|
493
|
-
function usageLine(usage, colors = paint(
|
|
540
|
+
function usageLine(usage, colors = paint(process8.stdout)) {
|
|
494
541
|
return `${colors.bold("Usage:")} ${usage.replace(USAGE_PREFIX, "").replaceAll(OPTIONAL, (part) => colors.dim(part))}`;
|
|
495
542
|
}
|
|
496
|
-
function helpText(usage, options, colors = paint(
|
|
543
|
+
function helpText(usage, options, colors = paint(process8.stdout), { examples = [], replaces, exits = [] } = {}) {
|
|
497
544
|
return [usageLine(usage, colors), ...replacesRows(replaces, colors), "", colors.bold("Options:"), ...optionRows(options, colors), ...exitRows(exits, colors), ...exampleRows(examples, colors)].join(`
|
|
498
545
|
`);
|
|
499
546
|
}
|
|
500
|
-
function exitRows(exits, colors = paint(
|
|
547
|
+
function exitRows(exits, colors = paint(process8.stdout)) {
|
|
501
548
|
if (exits.length === 0)
|
|
502
549
|
return [];
|
|
503
550
|
const width = Math.max(...exits.map(([code]) => String(code).length));
|
|
504
551
|
return ["", colors.bold("Exits:"), ...exits.map(([code, meaning]) => ` ${colors.cyan(String(code).padEnd(width))} ${meaning}`)];
|
|
505
552
|
}
|
|
506
|
-
function replacesRows(replaces, colors = paint(
|
|
507
|
-
return replaces === undefined ? [] : ["", `${colors.bold("Instead of:")} ${replaces}`];
|
|
553
|
+
function replacesRows(replaces, colors = paint(process8.stdout)) {
|
|
554
|
+
return replaces === undefined || outputMode() === "agent" ? [] : ["", `${colors.bold("Instead of:")} ${replaces}`];
|
|
508
555
|
}
|
|
509
|
-
function wantsHelpJson(env =
|
|
556
|
+
function wantsHelpJson(env = process8.env) {
|
|
510
557
|
return env.KIT_HELP === "json";
|
|
511
558
|
}
|
|
512
559
|
function description(usage, { examples = [], replaces, exits } = {}, options) {
|
|
@@ -525,12 +572,12 @@ function description(usage, { examples = [], replaces, exits } = {}, options) {
|
|
|
525
572
|
...options === undefined ? {} : { options: Object.entries(options).map(([name, { short, description }]) => ({ name, ...short === undefined ? {} : { short }, ...description === undefined ? {} : { description } })) }
|
|
526
573
|
};
|
|
527
574
|
}
|
|
528
|
-
function exampleRows(examples, colors = paint(
|
|
529
|
-
if (examples.length === 0)
|
|
575
|
+
function exampleRows(examples, colors = paint(process8.stdout)) {
|
|
576
|
+
if (examples.length === 0 || outputMode() === "agent")
|
|
530
577
|
return [];
|
|
531
578
|
return ["", colors.bold("Examples:"), ...examples.map((example) => typeof example === "string" ? ` ${example}` : ` ${example[0]} ${colors.dim(`# ${example[1]}`)}`)];
|
|
532
579
|
}
|
|
533
|
-
function optionRows(options, colors = paint(
|
|
580
|
+
function optionRows(options, colors = paint(process8.stdout)) {
|
|
534
581
|
const rows = Object.entries(options).map(([name, option]) => {
|
|
535
582
|
const short = option.short === undefined ? " " : `${colors.cyan(`-${option.short}`)}, `;
|
|
536
583
|
const named = option.choices === undefined ? "<value>" : `<${option.choices.join("|")}>`;
|
|
@@ -580,7 +627,6 @@ var DASHES = /^-+/;
|
|
|
580
627
|
function jsonOption(holds) {
|
|
581
628
|
return { type: "boolean", description: holds === undefined ? "print JSON" : `print JSON: ${holds}` };
|
|
582
629
|
}
|
|
583
|
-
|
|
584
630
|
class Exit extends Error {
|
|
585
631
|
code;
|
|
586
632
|
hint;
|
|
@@ -624,7 +670,7 @@ var OUTPUT_OPTIONS = {
|
|
|
624
670
|
color: { type: "string", description: "auto (on a terminal alone), always or never" },
|
|
625
671
|
plain: { type: "boolean", description: "plain text, no colour or spinner: --color never" }
|
|
626
672
|
};
|
|
627
|
-
function applyOutput(color, plain, env =
|
|
673
|
+
function applyOutput(color, plain, env = process9.env) {
|
|
628
674
|
const when = plain === true ? "never" : color ?? "auto";
|
|
629
675
|
if (when === "auto")
|
|
630
676
|
return;
|
|
@@ -801,13 +847,13 @@ var CLOSE_LINK = `${ESC}]8;;${ESC}\\`;
|
|
|
801
847
|
// ../kit/src/cli.ts
|
|
802
848
|
import { readFileSync as readFileSync2, realpathSync } from "fs";
|
|
803
849
|
import { dirname as dirname3, join as join5 } from "path";
|
|
804
|
-
import
|
|
850
|
+
import process11 from "process";
|
|
805
851
|
|
|
806
852
|
// ../kit/src/usage.ts
|
|
807
853
|
import { appendFileSync, mkdirSync } from "fs";
|
|
808
854
|
import { homedir as homedir3 } from "os";
|
|
809
855
|
import { dirname as dirname2, isAbsolute, join as join4 } from "path";
|
|
810
|
-
import
|
|
856
|
+
import process10 from "process";
|
|
811
857
|
|
|
812
858
|
// ../kit/src/logs.ts
|
|
813
859
|
var DAY_MS = 24 * 60 * 60 * 1000;
|
|
@@ -821,14 +867,14 @@ var usageError;
|
|
|
821
867
|
function noteUsageError(message) {
|
|
822
868
|
usageError = message;
|
|
823
869
|
}
|
|
824
|
-
function stateHome(env =
|
|
870
|
+
function stateHome(env = process10.env) {
|
|
825
871
|
const dir = env.XDG_STATE_HOME;
|
|
826
872
|
return dir !== undefined && isAbsolute(dir) ? dir : join4(homedir3(), ".local", "state");
|
|
827
873
|
}
|
|
828
|
-
function usagePath(env =
|
|
874
|
+
function usagePath(env = process10.env) {
|
|
829
875
|
return join4(stateHome(env), CLI_FOLDER, "usage.jsonl");
|
|
830
876
|
}
|
|
831
|
-
function usageRecorded(env =
|
|
877
|
+
function usageRecorded(env = process10.env) {
|
|
832
878
|
const off = env.KAYNOOO_CLI_NO_USAGE;
|
|
833
879
|
return env.NODE_ENV !== "test" && (off === undefined || off === "" || off === "0");
|
|
834
880
|
}
|
|
@@ -842,7 +888,7 @@ function usageEntry(bin, command, argv, code, now = new Date) {
|
|
|
842
888
|
usageError = undefined;
|
|
843
889
|
return { at: now.toISOString(), bin, ...command === undefined ? {} : { command }, flags: flagNames(argv), code, ...unknown === undefined ? {} : { unknown } };
|
|
844
890
|
}
|
|
845
|
-
function recordUsage(entry, env =
|
|
891
|
+
function recordUsage(entry, env = process10.env) {
|
|
846
892
|
if (!usageRecorded(env))
|
|
847
893
|
return;
|
|
848
894
|
try {
|
|
@@ -860,8 +906,8 @@ var LEVEL_OPTIONS = {
|
|
|
860
906
|
};
|
|
861
907
|
var TOP_OPTIONS = { ...LEVEL_OPTIONS, version: { type: "boolean", short: "v", description: "print the version" } };
|
|
862
908
|
function printError(prefix, message, hint, cause) {
|
|
863
|
-
const colors = paint(
|
|
864
|
-
const styled = takesControlCodes(
|
|
909
|
+
const colors = paint(process11.stderr);
|
|
910
|
+
const styled = takesControlCodes(process11.stderr);
|
|
865
911
|
const head = styled ? `${colors.red.bold("error")} ${colors.dim(`${prefix}:`)}` : `error: ${prefix}:`;
|
|
866
912
|
const under = (label, text, tint) => text === undefined ? "" : `
|
|
867
913
|
${styled ? tint(label) : `${label}:`} ${text}`;
|
|
@@ -954,7 +1000,7 @@ function packageVersion(entry = Bun.main) {
|
|
|
954
1000
|
return "0.0.0";
|
|
955
1001
|
}
|
|
956
1002
|
}
|
|
957
|
-
async function runMain({ name, version, run, redact, usage }, argv =
|
|
1003
|
+
async function runMain({ name, version, run, redact, usage }, argv = process11.argv.slice(2)) {
|
|
958
1004
|
if (argv[0] === COMPLETE)
|
|
959
1005
|
return printCandidates(leafCandidates(run, argv.slice(1)));
|
|
960
1006
|
if (argv.length === 1 && (argv[0] === "--version" || argv[0] === "-v")) {
|
|
@@ -985,6 +1031,8 @@ function composeError({ code, stderr }) {
|
|
|
985
1031
|
`).at(-1) ?? "";
|
|
986
1032
|
return last === "" ? `exit ${code}` : last;
|
|
987
1033
|
}
|
|
1034
|
+
// ../kit/src/folders.ts
|
|
1035
|
+
var SKIPPED_FOLDERS = new Set(["node_modules", "vendor", "dist", "build", "target", "coverage", "venv", "__pycache__"]);
|
|
988
1036
|
// ../kit/src/secrets.ts
|
|
989
1037
|
var SECRET_PART = /token|secret|passw|credential|private|dsn|apikey|accesskey|key$/i;
|
|
990
1038
|
var SECRET_WORDS = new Set(["key", "pass", "pwd", "auth", "salt", "cookie", "session", "jwt", "ssn", "iban", "card", "cvv", "otp"]);
|
|
@@ -997,7 +1045,7 @@ var {Glob } = globalThis.Bun;
|
|
|
997
1045
|
var SESSION_FILES = new Glob("*.json");
|
|
998
1046
|
var ACCOUNT_DIRS = new Glob("*/sessions");
|
|
999
1047
|
// src/dx.ts
|
|
1000
|
-
import
|
|
1048
|
+
import process17 from "process";
|
|
1001
1049
|
|
|
1002
1050
|
// ../env/src/files.ts
|
|
1003
1051
|
import { chmod, chown, readdir, realpath, rename, rm, stat, writeFile } from "fs/promises";
|
|
@@ -1353,7 +1401,7 @@ class Redactor {
|
|
|
1353
1401
|
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync } from "fs";
|
|
1354
1402
|
import { homedir as homedir4 } from "os";
|
|
1355
1403
|
import { dirname as dirname5, join as join7 } from "path";
|
|
1356
|
-
import
|
|
1404
|
+
import process15 from "process";
|
|
1357
1405
|
|
|
1358
1406
|
// ../kit/src/picker/score.ts
|
|
1359
1407
|
var MATCH = 16;
|
|
@@ -1456,6 +1504,14 @@ var KEYS = {
|
|
|
1456
1504
|
"\x1B[B": "down",
|
|
1457
1505
|
"\x1BOB": "down",
|
|
1458
1506
|
"\x0E": "down",
|
|
1507
|
+
"\x1B[5~": "pageup",
|
|
1508
|
+
"\x1B[6~": "pagedown",
|
|
1509
|
+
"\x1B[H": "home",
|
|
1510
|
+
"\x1B[1~": "home",
|
|
1511
|
+
"\x1BOH": "home",
|
|
1512
|
+
"\x1B[F": "end",
|
|
1513
|
+
"\x1B[4~": "end",
|
|
1514
|
+
"\x1BOF": "end",
|
|
1459
1515
|
"\r": "enter",
|
|
1460
1516
|
"\n": "enter",
|
|
1461
1517
|
"\x03": "cancel",
|
|
@@ -1464,7 +1520,10 @@ var KEYS = {
|
|
|
1464
1520
|
"\b": "erase",
|
|
1465
1521
|
"\x15": "clear",
|
|
1466
1522
|
"\x17": "word",
|
|
1467
|
-
"\t": "tab"
|
|
1523
|
+
"\t": "tab",
|
|
1524
|
+
"\x1F": "help",
|
|
1525
|
+
"\x1BOP": "help",
|
|
1526
|
+
"\x1B[11~": "help"
|
|
1468
1527
|
};
|
|
1469
1528
|
var CTRL_KEY = /^ctrl-[abd-gkln-z]$/;
|
|
1470
1529
|
function repeat(value, count) {
|
|
@@ -1534,7 +1593,7 @@ function parseKeys(input, paste = { active: false }, ctrls = []) {
|
|
|
1534
1593
|
});
|
|
1535
1594
|
}
|
|
1536
1595
|
function createState(rows, { multi = false, prompt = "> ", query = "", header = "", expect = [], searched = Number.POSITIVE_INFINITY } = {}) {
|
|
1537
|
-
const state = { rows: [], items: [], styles: [], searchable: [], searched, header, expect, key: "", status: "", query, matches: [], cursor: 0, marked: new Set, multi, prompt, done: undefined };
|
|
1596
|
+
const state = { rows: [], items: [], styles: [], searchable: [], searched, header, expect, key: "", status: "", query, matches: [], cursor: 0, help: false, page: 10, marked: new Set, multi, prompt, done: undefined };
|
|
1538
1597
|
return withRows(state, rows);
|
|
1539
1598
|
}
|
|
1540
1599
|
function withRows(state, rows, header = state.header) {
|
|
@@ -1556,6 +1615,8 @@ function highlighted(state) {
|
|
|
1556
1615
|
function press(state, key) {
|
|
1557
1616
|
if (state.done !== undefined)
|
|
1558
1617
|
return state;
|
|
1618
|
+
if (state.help)
|
|
1619
|
+
return { ...state, help: false };
|
|
1559
1620
|
if (typeof key === "object") {
|
|
1560
1621
|
if ("text" in key)
|
|
1561
1622
|
return withQuery(state, state.query + key.text);
|
|
@@ -1566,8 +1627,18 @@ function press(state, key) {
|
|
|
1566
1627
|
return move(state, -1);
|
|
1567
1628
|
case "down":
|
|
1568
1629
|
return move(state, 1);
|
|
1630
|
+
case "pageup":
|
|
1631
|
+
return move(state, -state.page);
|
|
1632
|
+
case "pagedown":
|
|
1633
|
+
return move(state, state.page);
|
|
1634
|
+
case "home":
|
|
1635
|
+
return move(state, -state.matches.length);
|
|
1636
|
+
case "end":
|
|
1637
|
+
return move(state, state.matches.length);
|
|
1569
1638
|
case "cancel":
|
|
1570
1639
|
return { ...state, done: "cancel" };
|
|
1640
|
+
case "help":
|
|
1641
|
+
return { ...state, help: true };
|
|
1571
1642
|
case "erase":
|
|
1572
1643
|
return withQuery(state, [...state.query].slice(0, -1).join(""));
|
|
1573
1644
|
case "clear":
|
|
@@ -1596,11 +1667,11 @@ function chosen(state) {
|
|
|
1596
1667
|
|
|
1597
1668
|
// ../kit/src/picker/terminal.ts
|
|
1598
1669
|
import { openSync } from "fs";
|
|
1599
|
-
import
|
|
1670
|
+
import process14 from "process";
|
|
1600
1671
|
import tty from "tty";
|
|
1601
1672
|
|
|
1602
1673
|
// ../kit/src/picker/preview.ts
|
|
1603
|
-
import
|
|
1674
|
+
import process13 from "process";
|
|
1604
1675
|
|
|
1605
1676
|
// ../kit/src/shell.ts
|
|
1606
1677
|
var SEPARATORS = new Set([`
|
|
@@ -1669,7 +1740,7 @@ async function runPreview(template, line, signal, hidden = []) {
|
|
|
1669
1740
|
${previewCommand(template, line, hidden)}`], { stdin: "ignore", stdout: "pipe", stderr: "ignore", detached: true });
|
|
1670
1741
|
const stop = () => {
|
|
1671
1742
|
try {
|
|
1672
|
-
|
|
1743
|
+
process13.kill(-proc.pid, "SIGKILL");
|
|
1673
1744
|
} catch {
|
|
1674
1745
|
proc.kill();
|
|
1675
1746
|
}
|
|
@@ -1747,7 +1818,18 @@ function fitStyled(line, width, plain = identity) {
|
|
|
1747
1818
|
function caretColumn(state, layout) {
|
|
1748
1819
|
return Math.min(layout.listWidth, Bun.stringWidth(state.prompt) + Bun.stringWidth(state.query) + 1);
|
|
1749
1820
|
}
|
|
1821
|
+
function helpLines(state, layout, theme) {
|
|
1822
|
+
const lines = [
|
|
1823
|
+
"type to filter, up, down, ctrl-p, ctrl-n, pgup, pgdn, home, end move",
|
|
1824
|
+
`enter picks${state.multi ? ", tab marks" : ""}, ctrl-u clears the query, ctrl-w a word, esc or ctrl-c cancels`,
|
|
1825
|
+
...state.expect.length > 0 ? [`${state.expect.join(", ")} end the pick as this command asks`] : []
|
|
1826
|
+
];
|
|
1827
|
+
const title = "keys, any key closes this help";
|
|
1828
|
+
return [{ text: theme.accent(title), width: title.length }, ...lines.map((line) => fit(` ${line}`, layout.listWidth, theme.label))];
|
|
1829
|
+
}
|
|
1750
1830
|
function listLines(state, layout, theme) {
|
|
1831
|
+
if (state.help)
|
|
1832
|
+
return helpLines(state, layout, theme);
|
|
1751
1833
|
const header = state.header === "" ? [] : state.header.split(`
|
|
1752
1834
|
`).map((line) => fitStyled(line, layout.listWidth, theme.label));
|
|
1753
1835
|
const rows = Math.max(1, layout.listHeight - 2 - header.length);
|
|
@@ -1756,7 +1838,8 @@ function listLines(state, layout, theme) {
|
|
|
1756
1838
|
const marks = (state.marked.size > 0 ? ` (${state.marked.size} marked)` : "") + (state.status === "" ? "" : ` ${state.status}`);
|
|
1757
1839
|
const promptWidth = Bun.stringWidth(state.prompt);
|
|
1758
1840
|
const query = fit(state.query, Math.max(1, layout.listWidth - promptWidth), identity);
|
|
1759
|
-
const
|
|
1841
|
+
const place = state.matches.length > rows ? ` (${state.cursor + 1} of ${state.matches.length})` : "";
|
|
1842
|
+
const count = fit(` ${state.matches.length}/${state.items.length}${place}${marks}`, layout.listWidth, theme.label);
|
|
1760
1843
|
const lines = [{ text: theme.accent(state.prompt) + query.text, width: promptWidth + query.width }, count, ...header];
|
|
1761
1844
|
if (state.matches.length === 0)
|
|
1762
1845
|
lines.push(fit(" no match", layout.listWidth, theme.label));
|
|
@@ -1783,6 +1866,7 @@ function render(state, layout, theme, preview = []) {
|
|
|
1783
1866
|
|
|
1784
1867
|
// ../kit/src/picker/terminal.ts
|
|
1785
1868
|
var PREVIEW_DELAY_MS = 120;
|
|
1869
|
+
var ESCAPE_WAIT_MS = 30;
|
|
1786
1870
|
var OPEN = { ctrl: "open" };
|
|
1787
1871
|
var HIDE_CURSOR = "\x1B[?25l";
|
|
1788
1872
|
var SHOW_CURSOR = "\x1B[?25h";
|
|
@@ -1800,7 +1884,7 @@ function openTerminal() {
|
|
|
1800
1884
|
} catch {
|
|
1801
1885
|
return fail("no terminal to read keys from (/dev/tty)");
|
|
1802
1886
|
}
|
|
1803
|
-
const out =
|
|
1887
|
+
const out = process14.stderr;
|
|
1804
1888
|
let resize;
|
|
1805
1889
|
return {
|
|
1806
1890
|
get columns() {
|
|
@@ -1838,20 +1922,29 @@ async function select(rows, settings, terminal = openTerminal()) {
|
|
|
1838
1922
|
let shownLine;
|
|
1839
1923
|
let finish;
|
|
1840
1924
|
let restored = false;
|
|
1925
|
+
let escape;
|
|
1926
|
+
let caret;
|
|
1841
1927
|
function draw(clear = false) {
|
|
1842
1928
|
if (restored)
|
|
1843
1929
|
return;
|
|
1844
1930
|
const layout = layoutFor({ columns: terminal.columns, rows: terminal.rows }, settings.height, settings.preview !== undefined, settings.previewPosition);
|
|
1845
1931
|
let frame = HIDE_CURSOR;
|
|
1846
1932
|
if (reserved !== layout.height || clear) {
|
|
1933
|
+
frame += clear && caret !== undefined ? up(Math.floor((caret - 1) / terminal.columns)) : "";
|
|
1847
1934
|
frame += CLEAR_BELOW + `
|
|
1848
1935
|
`.repeat(layout.height - 1) + up(layout.height - 1);
|
|
1849
1936
|
reserved = layout.height;
|
|
1850
1937
|
}
|
|
1938
|
+
caret = caretColumn(state, layout);
|
|
1851
1939
|
frame += `\r${render(state, layout, theme, preview).map((line) => `\x1B[2K${line}`).join(`
|
|
1852
|
-
`)}${up(layout.height - 1)}\r\x1B[${
|
|
1940
|
+
`)}${up(layout.height - 1)}\r\x1B[${caret}G${SHOW_CURSOR}`;
|
|
1853
1941
|
terminal.write(frame);
|
|
1854
1942
|
}
|
|
1943
|
+
function pageSize() {
|
|
1944
|
+
const headerLines = state.header === "" ? 0 : state.header.split(`
|
|
1945
|
+
`).length;
|
|
1946
|
+
return Math.max(1, layoutFor({ columns: terminal.columns, rows: terminal.rows }, settings.height, settings.preview !== undefined, settings.previewPosition).listHeight - 2 - headerLines);
|
|
1947
|
+
}
|
|
1855
1948
|
function refreshPreview() {
|
|
1856
1949
|
const at = highlighted(state);
|
|
1857
1950
|
if (settings.preview === undefined || at === shownLine)
|
|
@@ -1881,6 +1974,7 @@ async function select(rows, settings, terminal = openTerminal()) {
|
|
|
1881
1974
|
return;
|
|
1882
1975
|
restored = true;
|
|
1883
1976
|
clearTimeout(previewTimer);
|
|
1977
|
+
clearTimeout(escape);
|
|
1884
1978
|
previewing.abort();
|
|
1885
1979
|
terminal.write(`${CLEAR_BELOW}${PASTE_OFF}${SHOW_CURSOR}`);
|
|
1886
1980
|
terminal.close();
|
|
@@ -1919,7 +2013,7 @@ async function select(rows, settings, terminal = openTerminal()) {
|
|
|
1919
2013
|
if (key === OPEN || typeof key === "object" && "ctrl" in key && key.ctrl === reload?.key)
|
|
1920
2014
|
await reloadRows();
|
|
1921
2015
|
else
|
|
1922
|
-
state = press(state, key);
|
|
2016
|
+
state = press({ ...state, page: pageSize() }, key);
|
|
1923
2017
|
}
|
|
1924
2018
|
} finally {
|
|
1925
2019
|
draining = false;
|
|
@@ -1932,6 +2026,20 @@ async function select(rows, settings, terminal = openTerminal()) {
|
|
|
1932
2026
|
draw();
|
|
1933
2027
|
}
|
|
1934
2028
|
function onChunk(chunk) {
|
|
2029
|
+
if (escape !== undefined) {
|
|
2030
|
+
clearTimeout(escape);
|
|
2031
|
+
escape = undefined;
|
|
2032
|
+
chunk = `\x1B${chunk}`;
|
|
2033
|
+
} else if (chunk === "\x1B") {
|
|
2034
|
+
escape = setTimeout(() => {
|
|
2035
|
+
escape = undefined;
|
|
2036
|
+
takeKeys("\x1B");
|
|
2037
|
+
}, ESCAPE_WAIT_MS);
|
|
2038
|
+
return;
|
|
2039
|
+
}
|
|
2040
|
+
takeKeys(chunk);
|
|
2041
|
+
}
|
|
2042
|
+
function takeKeys(chunk) {
|
|
1935
2043
|
const keys = parseKeys(chunk, paste, [...settings.expect ?? [], ...reload?.key === undefined ? [] : [reload.key]]);
|
|
1936
2044
|
if (busy && keys.includes("cancel")) {
|
|
1937
2045
|
stop();
|
|
@@ -1943,9 +2051,9 @@ async function select(rows, settings, terminal = openTerminal()) {
|
|
|
1943
2051
|
const ended = new Promise((resolve) => {
|
|
1944
2052
|
finish = resolve;
|
|
1945
2053
|
});
|
|
1946
|
-
|
|
2054
|
+
process14.once("exit", restore);
|
|
1947
2055
|
for (const signal of SIGNALS)
|
|
1948
|
-
|
|
2056
|
+
process14.once(signal, stop);
|
|
1949
2057
|
try {
|
|
1950
2058
|
terminal.write(PASTE_ON);
|
|
1951
2059
|
terminal.listen(onChunk, () => draw(true));
|
|
@@ -1958,8 +2066,8 @@ async function select(rows, settings, terminal = openTerminal()) {
|
|
|
1958
2066
|
await ended;
|
|
1959
2067
|
} finally {
|
|
1960
2068
|
for (const signal of SIGNALS)
|
|
1961
|
-
|
|
1962
|
-
|
|
2069
|
+
process14.off(signal, stop);
|
|
2070
|
+
process14.off("exit", restore);
|
|
1963
2071
|
restore();
|
|
1964
2072
|
}
|
|
1965
2073
|
return state.done === "accept" ? { rows: chosen(state), key: state.key, query: state.query } : undefined;
|
|
@@ -1997,7 +2105,7 @@ function heightFor(count) {
|
|
|
1997
2105
|
return String(Math.max(15, Math.ceil((count + 4) / 0.6)));
|
|
1998
2106
|
}
|
|
1999
2107
|
function historyFile(name) {
|
|
2000
|
-
return join7(
|
|
2108
|
+
return join7(process15.env.XDG_CACHE_HOME ?? join7(homedir4(), ".cache"), name, "history.json");
|
|
2001
2109
|
}
|
|
2002
2110
|
function history(name) {
|
|
2003
2111
|
try {
|
|
@@ -2008,12 +2116,12 @@ function history(name) {
|
|
|
2008
2116
|
}
|
|
2009
2117
|
}
|
|
2010
2118
|
function runs(name) {
|
|
2011
|
-
return history(name)[
|
|
2119
|
+
return history(name)[process15.cwd()] ?? [];
|
|
2012
2120
|
}
|
|
2013
2121
|
function record(name, run) {
|
|
2014
2122
|
const all = history(name);
|
|
2015
2123
|
const file = historyFile(name);
|
|
2016
|
-
all[
|
|
2124
|
+
all[process15.cwd()] = [run, ...(all[process15.cwd()] ?? []).filter((earlier) => earlier.id !== run.id)].slice(0, REMEMBERED);
|
|
2017
2125
|
mkdirSync2(dirname5(file), { recursive: true });
|
|
2018
2126
|
writeFileSync(file, JSON.stringify(all));
|
|
2019
2127
|
}
|
|
@@ -2037,7 +2145,7 @@ function list(rows) {
|
|
|
2037
2145
|
}
|
|
2038
2146
|
|
|
2039
2147
|
// src/picker.ts
|
|
2040
|
-
import
|
|
2148
|
+
import process16 from "process";
|
|
2041
2149
|
|
|
2042
2150
|
// src/stack.ts
|
|
2043
2151
|
import { existsSync as existsSync4, readdirSync, readFileSync as readFileSync4 } from "fs";
|
|
@@ -2045,13 +2153,12 @@ import { dirname as dirname6, join as join8, relative, resolve as resolve3 } fro
|
|
|
2045
2153
|
var LABEL_FORMAT = ["project", "project.config_files", "project.environment_file", "project.working_dir"].map((label) => `{{.Label "com.docker.compose.${label}"}}`).join("\t");
|
|
2046
2154
|
var COMPOSE_FILE_VAR = /^\s*(?:export\s+)?COMPOSE_FILE\s*=\s*\S/m;
|
|
2047
2155
|
var COMPOSE_FILES = ["compose.yaml", "compose.yml", "docker-compose.yaml", "docker-compose.yml"];
|
|
2048
|
-
var SKIPPED2 = new Set(["node_modules", "vendor", "dist", "build", "target", "venv", "__pycache__"]);
|
|
2049
2156
|
var ACTIONS = ["shell", "logs", "restart", "up", "stop", "build"];
|
|
2050
2157
|
function from(dir, command) {
|
|
2051
2158
|
return dir === "." ? command : ["env", "-C", dir, ...command];
|
|
2052
2159
|
}
|
|
2053
2160
|
function children(dir = ".") {
|
|
2054
|
-
return readdirSync(dir, { withFileTypes: true }).filter((child) => child.isDirectory() && !child.name.startsWith(".") && !
|
|
2161
|
+
return readdirSync(dir, { withFileTypes: true }).filter((child) => child.isDirectory() && !child.name.startsWith(".") && !SKIPPED_FOLDERS.has(child.name)).map((child) => child.name).sort();
|
|
2055
2162
|
}
|
|
2056
2163
|
function up2(dir) {
|
|
2057
2164
|
const dirs = [];
|
|
@@ -2207,7 +2314,7 @@ async function logsOf(stack, name) {
|
|
|
2207
2314
|
var KEYS2 = { "ctrl-l": "logs", "ctrl-r": "restart", "ctrl-x": "stop", "ctrl-b": "build" };
|
|
2208
2315
|
var KEY_LABELS = { "ctrl-l": "Logs", "ctrl-r": "Restart", "ctrl-x": "Stop", "ctrl-b": "Rebuild" };
|
|
2209
2316
|
function row(service) {
|
|
2210
|
-
const colors = paint(
|
|
2317
|
+
const colors = paint(process16.stderr);
|
|
2211
2318
|
const dir = service.stack.dir;
|
|
2212
2319
|
const project = service.stack.project;
|
|
2213
2320
|
const name = project === undefined ? service.name : `${colors.dim(`${project}:`)}${service.name}`;
|
|
@@ -2223,7 +2330,7 @@ async function pickService(services) {
|
|
|
2223
2330
|
expect: Object.keys(KEYS2),
|
|
2224
2331
|
searched: 1,
|
|
2225
2332
|
height: heightFor(services.length),
|
|
2226
|
-
preview: `${
|
|
2333
|
+
preview: `${process16.execPath} ${process16.argv[1]} --show {1} {2} {4}`
|
|
2227
2334
|
});
|
|
2228
2335
|
const service = services.find((candidate) => key(candidate) === picked?.hidden[2]);
|
|
2229
2336
|
return picked === undefined || service === undefined ? undefined : { service, key: picked.key };
|
|
@@ -2243,7 +2350,7 @@ var options = {
|
|
|
2243
2350
|
follow: { type: "boolean", negative: "print the logs once and exit instead of following them" }
|
|
2244
2351
|
};
|
|
2245
2352
|
function table2(services) {
|
|
2246
|
-
const colors = paint(
|
|
2353
|
+
const colors = paint(process17.stdout);
|
|
2247
2354
|
const keys = services.map(key);
|
|
2248
2355
|
const width = Math.max(...keys.map((name) => name.length));
|
|
2249
2356
|
const states = Math.max(...services.map((service) => service.state.length));
|
|
@@ -2286,7 +2393,7 @@ async function hidden(flag, rest, services) {
|
|
|
2286
2393
|
const service = await serviceNamed(dir, name, project);
|
|
2287
2394
|
if (service === undefined)
|
|
2288
2395
|
return 0;
|
|
2289
|
-
const colors = paint(
|
|
2396
|
+
const colors = paint(process17.stdout);
|
|
2290
2397
|
console.log(`${colors[stateColor(service.state)](service.status || service.state)} ${colors.dim(service.image)}${service.ports ? ` ${colors.cyan(service.ports)}` : ""}
|
|
2291
2398
|
`);
|
|
2292
2399
|
console.log(await logsOf(service.stack, name));
|
|
@@ -2304,8 +2411,8 @@ async function followMasked(command) {
|
|
|
2304
2411
|
const decoder = new TextDecoder;
|
|
2305
2412
|
const proc = Bun.spawn(command, { stdio: ["inherit", "pipe", "inherit"] });
|
|
2306
2413
|
for await (const chunk of proc.stdout)
|
|
2307
|
-
|
|
2308
|
-
|
|
2414
|
+
process17.stdout.write(redactor.push(decoder.decode(chunk, { stream: true })));
|
|
2415
|
+
process17.stdout.write(redactor.end());
|
|
2309
2416
|
return proc.exited;
|
|
2310
2417
|
}
|
|
2311
2418
|
async function dx(args) {
|
|
@@ -2325,7 +2432,7 @@ async function dx(args) {
|
|
|
2325
2432
|
let service;
|
|
2326
2433
|
let action;
|
|
2327
2434
|
if (named === undefined) {
|
|
2328
|
-
const interactive =
|
|
2435
|
+
const interactive = isInteractive() && parsed.values.json !== true;
|
|
2329
2436
|
if (!interactive) {
|
|
2330
2437
|
if (emit)
|
|
2331
2438
|
fail("the picker needs a terminal", 1);
|
|
@@ -2367,4 +2474,4 @@ async function dx(args) {
|
|
|
2367
2474
|
}
|
|
2368
2475
|
|
|
2369
2476
|
// src/dx-cli.ts
|
|
2370
|
-
|
|
2477
|
+
process18.exitCode = await runMain({ name: "dx", run: dx });
|