@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/sf-cli.js
CHANGED
|
@@ -2,13 +2,37 @@
|
|
|
2
2
|
// @bun
|
|
3
3
|
|
|
4
4
|
// src/sf-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"]);
|
|
@@ -1000,13 +1048,13 @@ var ACCOUNT_DIRS = new Glob("*/sessions");
|
|
|
1000
1048
|
import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
|
|
1001
1049
|
import { homedir as homedir5 } from "os";
|
|
1002
1050
|
import { dirname as dirname7, join as join9, resolve as resolve4 } from "path";
|
|
1003
|
-
import
|
|
1051
|
+
import process17 from "process";
|
|
1004
1052
|
|
|
1005
1053
|
// ../kit/src/picker.ts
|
|
1006
1054
|
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync } from "fs";
|
|
1007
1055
|
import { homedir as homedir4 } from "os";
|
|
1008
1056
|
import { dirname as dirname4, join as join6 } from "path";
|
|
1009
|
-
import
|
|
1057
|
+
import process15 from "process";
|
|
1010
1058
|
|
|
1011
1059
|
// ../kit/src/picker/score.ts
|
|
1012
1060
|
var MATCH = 16;
|
|
@@ -1109,6 +1157,14 @@ var KEYS = {
|
|
|
1109
1157
|
"\x1B[B": "down",
|
|
1110
1158
|
"\x1BOB": "down",
|
|
1111
1159
|
"\x0E": "down",
|
|
1160
|
+
"\x1B[5~": "pageup",
|
|
1161
|
+
"\x1B[6~": "pagedown",
|
|
1162
|
+
"\x1B[H": "home",
|
|
1163
|
+
"\x1B[1~": "home",
|
|
1164
|
+
"\x1BOH": "home",
|
|
1165
|
+
"\x1B[F": "end",
|
|
1166
|
+
"\x1B[4~": "end",
|
|
1167
|
+
"\x1BOF": "end",
|
|
1112
1168
|
"\r": "enter",
|
|
1113
1169
|
"\n": "enter",
|
|
1114
1170
|
"\x03": "cancel",
|
|
@@ -1117,7 +1173,10 @@ var KEYS = {
|
|
|
1117
1173
|
"\b": "erase",
|
|
1118
1174
|
"\x15": "clear",
|
|
1119
1175
|
"\x17": "word",
|
|
1120
|
-
"\t": "tab"
|
|
1176
|
+
"\t": "tab",
|
|
1177
|
+
"\x1F": "help",
|
|
1178
|
+
"\x1BOP": "help",
|
|
1179
|
+
"\x1B[11~": "help"
|
|
1121
1180
|
};
|
|
1122
1181
|
var CTRL_KEY = /^ctrl-[abd-gkln-z]$/;
|
|
1123
1182
|
function repeat(value, count) {
|
|
@@ -1187,7 +1246,7 @@ function parseKeys(input, paste = { active: false }, ctrls = []) {
|
|
|
1187
1246
|
});
|
|
1188
1247
|
}
|
|
1189
1248
|
function createState(rows, { multi = false, prompt = "> ", query = "", header = "", expect = [], searched = Number.POSITIVE_INFINITY } = {}) {
|
|
1190
|
-
const state = { rows: [], items: [], styles: [], searchable: [], searched, header, expect, key: "", status: "", query, matches: [], cursor: 0, marked: new Set, multi, prompt, done: undefined };
|
|
1249
|
+
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 };
|
|
1191
1250
|
return withRows(state, rows);
|
|
1192
1251
|
}
|
|
1193
1252
|
function withRows(state, rows, header = state.header) {
|
|
@@ -1209,6 +1268,8 @@ function highlighted(state) {
|
|
|
1209
1268
|
function press(state, key) {
|
|
1210
1269
|
if (state.done !== undefined)
|
|
1211
1270
|
return state;
|
|
1271
|
+
if (state.help)
|
|
1272
|
+
return { ...state, help: false };
|
|
1212
1273
|
if (typeof key === "object") {
|
|
1213
1274
|
if ("text" in key)
|
|
1214
1275
|
return withQuery(state, state.query + key.text);
|
|
@@ -1219,8 +1280,18 @@ function press(state, key) {
|
|
|
1219
1280
|
return move(state, -1);
|
|
1220
1281
|
case "down":
|
|
1221
1282
|
return move(state, 1);
|
|
1283
|
+
case "pageup":
|
|
1284
|
+
return move(state, -state.page);
|
|
1285
|
+
case "pagedown":
|
|
1286
|
+
return move(state, state.page);
|
|
1287
|
+
case "home":
|
|
1288
|
+
return move(state, -state.matches.length);
|
|
1289
|
+
case "end":
|
|
1290
|
+
return move(state, state.matches.length);
|
|
1222
1291
|
case "cancel":
|
|
1223
1292
|
return { ...state, done: "cancel" };
|
|
1293
|
+
case "help":
|
|
1294
|
+
return { ...state, help: true };
|
|
1224
1295
|
case "erase":
|
|
1225
1296
|
return withQuery(state, [...state.query].slice(0, -1).join(""));
|
|
1226
1297
|
case "clear":
|
|
@@ -1249,11 +1320,11 @@ function chosen(state) {
|
|
|
1249
1320
|
|
|
1250
1321
|
// ../kit/src/picker/terminal.ts
|
|
1251
1322
|
import { openSync } from "fs";
|
|
1252
|
-
import
|
|
1323
|
+
import process14 from "process";
|
|
1253
1324
|
import tty from "tty";
|
|
1254
1325
|
|
|
1255
1326
|
// ../kit/src/picker/preview.ts
|
|
1256
|
-
import
|
|
1327
|
+
import process13 from "process";
|
|
1257
1328
|
|
|
1258
1329
|
// ../kit/src/shell.ts
|
|
1259
1330
|
var SEPARATORS = new Set([`
|
|
@@ -1322,7 +1393,7 @@ async function runPreview(template, line, signal, hidden = []) {
|
|
|
1322
1393
|
${previewCommand(template, line, hidden)}`], { stdin: "ignore", stdout: "pipe", stderr: "ignore", detached: true });
|
|
1323
1394
|
const stop = () => {
|
|
1324
1395
|
try {
|
|
1325
|
-
|
|
1396
|
+
process13.kill(-proc.pid, "SIGKILL");
|
|
1326
1397
|
} catch {
|
|
1327
1398
|
proc.kill();
|
|
1328
1399
|
}
|
|
@@ -1400,7 +1471,18 @@ function fitStyled(line, width, plain = identity) {
|
|
|
1400
1471
|
function caretColumn(state, layout) {
|
|
1401
1472
|
return Math.min(layout.listWidth, Bun.stringWidth(state.prompt) + Bun.stringWidth(state.query) + 1);
|
|
1402
1473
|
}
|
|
1474
|
+
function helpLines(state, layout, theme) {
|
|
1475
|
+
const lines = [
|
|
1476
|
+
"type to filter, up, down, ctrl-p, ctrl-n, pgup, pgdn, home, end move",
|
|
1477
|
+
`enter picks${state.multi ? ", tab marks" : ""}, ctrl-u clears the query, ctrl-w a word, esc or ctrl-c cancels`,
|
|
1478
|
+
...state.expect.length > 0 ? [`${state.expect.join(", ")} end the pick as this command asks`] : []
|
|
1479
|
+
];
|
|
1480
|
+
const title = "keys, any key closes this help";
|
|
1481
|
+
return [{ text: theme.accent(title), width: title.length }, ...lines.map((line) => fit(` ${line}`, layout.listWidth, theme.label))];
|
|
1482
|
+
}
|
|
1403
1483
|
function listLines(state, layout, theme) {
|
|
1484
|
+
if (state.help)
|
|
1485
|
+
return helpLines(state, layout, theme);
|
|
1404
1486
|
const header = state.header === "" ? [] : state.header.split(`
|
|
1405
1487
|
`).map((line) => fitStyled(line, layout.listWidth, theme.label));
|
|
1406
1488
|
const rows = Math.max(1, layout.listHeight - 2 - header.length);
|
|
@@ -1409,7 +1491,8 @@ function listLines(state, layout, theme) {
|
|
|
1409
1491
|
const marks = (state.marked.size > 0 ? ` (${state.marked.size} marked)` : "") + (state.status === "" ? "" : ` ${state.status}`);
|
|
1410
1492
|
const promptWidth = Bun.stringWidth(state.prompt);
|
|
1411
1493
|
const query = fit(state.query, Math.max(1, layout.listWidth - promptWidth), identity);
|
|
1412
|
-
const
|
|
1494
|
+
const place = state.matches.length > rows ? ` (${state.cursor + 1} of ${state.matches.length})` : "";
|
|
1495
|
+
const count = fit(` ${state.matches.length}/${state.items.length}${place}${marks}`, layout.listWidth, theme.label);
|
|
1413
1496
|
const lines = [{ text: theme.accent(state.prompt) + query.text, width: promptWidth + query.width }, count, ...header];
|
|
1414
1497
|
if (state.matches.length === 0)
|
|
1415
1498
|
lines.push(fit(" no match", layout.listWidth, theme.label));
|
|
@@ -1436,6 +1519,7 @@ function render(state, layout, theme, preview = []) {
|
|
|
1436
1519
|
|
|
1437
1520
|
// ../kit/src/picker/terminal.ts
|
|
1438
1521
|
var PREVIEW_DELAY_MS = 120;
|
|
1522
|
+
var ESCAPE_WAIT_MS = 30;
|
|
1439
1523
|
var OPEN = { ctrl: "open" };
|
|
1440
1524
|
var HIDE_CURSOR = "\x1B[?25l";
|
|
1441
1525
|
var SHOW_CURSOR = "\x1B[?25h";
|
|
@@ -1453,7 +1537,7 @@ function openTerminal() {
|
|
|
1453
1537
|
} catch {
|
|
1454
1538
|
return fail("no terminal to read keys from (/dev/tty)");
|
|
1455
1539
|
}
|
|
1456
|
-
const out =
|
|
1540
|
+
const out = process14.stderr;
|
|
1457
1541
|
let resize;
|
|
1458
1542
|
return {
|
|
1459
1543
|
get columns() {
|
|
@@ -1491,20 +1575,29 @@ async function select(rows, settings, terminal = openTerminal()) {
|
|
|
1491
1575
|
let shownLine;
|
|
1492
1576
|
let finish;
|
|
1493
1577
|
let restored = false;
|
|
1578
|
+
let escape;
|
|
1579
|
+
let caret;
|
|
1494
1580
|
function draw(clear = false) {
|
|
1495
1581
|
if (restored)
|
|
1496
1582
|
return;
|
|
1497
1583
|
const layout = layoutFor({ columns: terminal.columns, rows: terminal.rows }, settings.height, settings.preview !== undefined, settings.previewPosition);
|
|
1498
1584
|
let frame = HIDE_CURSOR;
|
|
1499
1585
|
if (reserved !== layout.height || clear) {
|
|
1586
|
+
frame += clear && caret !== undefined ? up(Math.floor((caret - 1) / terminal.columns)) : "";
|
|
1500
1587
|
frame += CLEAR_BELOW + `
|
|
1501
1588
|
`.repeat(layout.height - 1) + up(layout.height - 1);
|
|
1502
1589
|
reserved = layout.height;
|
|
1503
1590
|
}
|
|
1591
|
+
caret = caretColumn(state, layout);
|
|
1504
1592
|
frame += `\r${render(state, layout, theme, preview).map((line) => `\x1B[2K${line}`).join(`
|
|
1505
|
-
`)}${up(layout.height - 1)}\r\x1B[${
|
|
1593
|
+
`)}${up(layout.height - 1)}\r\x1B[${caret}G${SHOW_CURSOR}`;
|
|
1506
1594
|
terminal.write(frame);
|
|
1507
1595
|
}
|
|
1596
|
+
function pageSize() {
|
|
1597
|
+
const headerLines = state.header === "" ? 0 : state.header.split(`
|
|
1598
|
+
`).length;
|
|
1599
|
+
return Math.max(1, layoutFor({ columns: terminal.columns, rows: terminal.rows }, settings.height, settings.preview !== undefined, settings.previewPosition).listHeight - 2 - headerLines);
|
|
1600
|
+
}
|
|
1508
1601
|
function refreshPreview() {
|
|
1509
1602
|
const at = highlighted(state);
|
|
1510
1603
|
if (settings.preview === undefined || at === shownLine)
|
|
@@ -1534,6 +1627,7 @@ async function select(rows, settings, terminal = openTerminal()) {
|
|
|
1534
1627
|
return;
|
|
1535
1628
|
restored = true;
|
|
1536
1629
|
clearTimeout(previewTimer);
|
|
1630
|
+
clearTimeout(escape);
|
|
1537
1631
|
previewing.abort();
|
|
1538
1632
|
terminal.write(`${CLEAR_BELOW}${PASTE_OFF}${SHOW_CURSOR}`);
|
|
1539
1633
|
terminal.close();
|
|
@@ -1572,7 +1666,7 @@ async function select(rows, settings, terminal = openTerminal()) {
|
|
|
1572
1666
|
if (key === OPEN || typeof key === "object" && "ctrl" in key && key.ctrl === reload?.key)
|
|
1573
1667
|
await reloadRows();
|
|
1574
1668
|
else
|
|
1575
|
-
state = press(state, key);
|
|
1669
|
+
state = press({ ...state, page: pageSize() }, key);
|
|
1576
1670
|
}
|
|
1577
1671
|
} finally {
|
|
1578
1672
|
draining = false;
|
|
@@ -1585,6 +1679,20 @@ async function select(rows, settings, terminal = openTerminal()) {
|
|
|
1585
1679
|
draw();
|
|
1586
1680
|
}
|
|
1587
1681
|
function onChunk(chunk) {
|
|
1682
|
+
if (escape !== undefined) {
|
|
1683
|
+
clearTimeout(escape);
|
|
1684
|
+
escape = undefined;
|
|
1685
|
+
chunk = `\x1B${chunk}`;
|
|
1686
|
+
} else if (chunk === "\x1B") {
|
|
1687
|
+
escape = setTimeout(() => {
|
|
1688
|
+
escape = undefined;
|
|
1689
|
+
takeKeys("\x1B");
|
|
1690
|
+
}, ESCAPE_WAIT_MS);
|
|
1691
|
+
return;
|
|
1692
|
+
}
|
|
1693
|
+
takeKeys(chunk);
|
|
1694
|
+
}
|
|
1695
|
+
function takeKeys(chunk) {
|
|
1588
1696
|
const keys = parseKeys(chunk, paste, [...settings.expect ?? [], ...reload?.key === undefined ? [] : [reload.key]]);
|
|
1589
1697
|
if (busy && keys.includes("cancel")) {
|
|
1590
1698
|
stop();
|
|
@@ -1596,9 +1704,9 @@ async function select(rows, settings, terminal = openTerminal()) {
|
|
|
1596
1704
|
const ended = new Promise((resolve) => {
|
|
1597
1705
|
finish = resolve;
|
|
1598
1706
|
});
|
|
1599
|
-
|
|
1707
|
+
process14.once("exit", restore);
|
|
1600
1708
|
for (const signal of SIGNALS)
|
|
1601
|
-
|
|
1709
|
+
process14.once(signal, stop);
|
|
1602
1710
|
try {
|
|
1603
1711
|
terminal.write(PASTE_ON);
|
|
1604
1712
|
terminal.listen(onChunk, () => draw(true));
|
|
@@ -1611,8 +1719,8 @@ async function select(rows, settings, terminal = openTerminal()) {
|
|
|
1611
1719
|
await ended;
|
|
1612
1720
|
} finally {
|
|
1613
1721
|
for (const signal of SIGNALS)
|
|
1614
|
-
|
|
1615
|
-
|
|
1722
|
+
process14.off(signal, stop);
|
|
1723
|
+
process14.off("exit", restore);
|
|
1616
1724
|
restore();
|
|
1617
1725
|
}
|
|
1618
1726
|
return state.done === "accept" ? { rows: chosen(state), key: state.key, query: state.query } : undefined;
|
|
@@ -1650,7 +1758,7 @@ function heightFor(count) {
|
|
|
1650
1758
|
return String(Math.max(15, Math.ceil((count + 4) / 0.6)));
|
|
1651
1759
|
}
|
|
1652
1760
|
function historyFile(name) {
|
|
1653
|
-
return join6(
|
|
1761
|
+
return join6(process15.env.XDG_CACHE_HOME ?? join6(homedir4(), ".cache"), name, "history.json");
|
|
1654
1762
|
}
|
|
1655
1763
|
function history(name) {
|
|
1656
1764
|
try {
|
|
@@ -1661,12 +1769,12 @@ function history(name) {
|
|
|
1661
1769
|
}
|
|
1662
1770
|
}
|
|
1663
1771
|
function runs(name) {
|
|
1664
|
-
return history(name)[
|
|
1772
|
+
return history(name)[process15.cwd()] ?? [];
|
|
1665
1773
|
}
|
|
1666
1774
|
function record(name, run) {
|
|
1667
1775
|
const all = history(name);
|
|
1668
1776
|
const file = historyFile(name);
|
|
1669
|
-
all[
|
|
1777
|
+
all[process15.cwd()] = [run, ...(all[process15.cwd()] ?? []).filter((earlier) => earlier.id !== run.id)].slice(0, REMEMBERED);
|
|
1670
1778
|
mkdirSync2(dirname4(file), { recursive: true });
|
|
1671
1779
|
writeFileSync(file, JSON.stringify(all));
|
|
1672
1780
|
}
|
|
@@ -1690,12 +1798,10 @@ function list(rows) {
|
|
|
1690
1798
|
}
|
|
1691
1799
|
|
|
1692
1800
|
// ../kit/src/prompt.ts
|
|
1693
|
-
import
|
|
1694
|
-
var
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
function readKeys(input) {
|
|
1698
|
-
return (input.match(KEY_SEQUENCES2) ?? []).flatMap((sequence) => KEYS2[sequence] ?? (CONTROL3.test(sequence) ? [] : [{ text: sequence }]));
|
|
1801
|
+
import process16 from "process";
|
|
1802
|
+
var PROMPT_KEYS = new Set(["up", "down", "pageup", "pagedown", "home", "end", "enter", "cancel", "erase"]);
|
|
1803
|
+
function readKeys(input, paste = { active: false }) {
|
|
1804
|
+
return parseKeys(input, paste).filter((key) => typeof key === "object" ? "text" in key : PROMPT_KEYS.has(key));
|
|
1699
1805
|
}
|
|
1700
1806
|
async function input2(question, { default: fallback, mask = false, validate, ...settings } = {}) {
|
|
1701
1807
|
let value = "";
|
|
@@ -1729,27 +1835,34 @@ async function input2(question, { default: fallback, mask = false, validate, ...
|
|
|
1729
1835
|
function answer(colors, question, state, picked) {
|
|
1730
1836
|
return state === "enter" ? `${colors.green("\u2713")} ${question} ${colors.cyan(picked)}` : `${colors.red("\u2717")} ${question} ${colors.dim("cancelled")}`;
|
|
1731
1837
|
}
|
|
1732
|
-
async function ask(question, { hint, terminal =
|
|
1838
|
+
async function ask(question, { hint, terminal = process16 }, render, press) {
|
|
1733
1839
|
const { stdin, stderr } = terminal;
|
|
1734
|
-
if (
|
|
1840
|
+
if (!isInteractive(terminal))
|
|
1735
1841
|
fail(`cannot ask "${question}" off a terminal`, 2, hint);
|
|
1736
1842
|
const colors = paint(stderr);
|
|
1737
|
-
let drawn =
|
|
1843
|
+
let drawn = [];
|
|
1844
|
+
let current = "asking";
|
|
1738
1845
|
let outcome;
|
|
1846
|
+
const columns = () => stderr.columns || 80;
|
|
1739
1847
|
const draw = (state) => {
|
|
1740
|
-
const frame = render(colors, state, { columns:
|
|
1741
|
-
|
|
1848
|
+
const frame = render(colors, state, { columns: columns(), rows: stderr.rows || 24 });
|
|
1849
|
+
const rows = drawn.reduce((sum, line) => sum + Math.max(1, Math.ceil(Bun.stringWidth(line) / columns())), 0);
|
|
1850
|
+
stderr.write(`${rows > 1 ? `\x1B[${rows - 1}A` : ""}\r\x1B[0J${frame.join(`
|
|
1742
1851
|
`)}`);
|
|
1743
|
-
drawn = frame
|
|
1852
|
+
drawn = frame;
|
|
1853
|
+
current = state;
|
|
1744
1854
|
};
|
|
1855
|
+
const redraw = () => draw(current);
|
|
1856
|
+
const paste = { active: false };
|
|
1745
1857
|
try {
|
|
1858
|
+
stderr.on?.("resize", redraw);
|
|
1746
1859
|
stdin.setRawMode(true);
|
|
1747
1860
|
stdin.resume();
|
|
1748
|
-
stderr.write("\x1B[?25l");
|
|
1861
|
+
stderr.write("\x1B[?25l\x1B[?2004h");
|
|
1749
1862
|
draw("asking");
|
|
1750
1863
|
return await new Promise((resolve) => {
|
|
1751
1864
|
function onData(data) {
|
|
1752
|
-
for (const key of readKeys(data.toString())) {
|
|
1865
|
+
for (const key of readKeys(data.toString(), paste)) {
|
|
1753
1866
|
const pressed = press(key);
|
|
1754
1867
|
if (pressed !== undefined) {
|
|
1755
1868
|
settle(pressed);
|
|
@@ -1771,9 +1884,10 @@ async function ask(question, { hint, terminal = process14 }, render, press) {
|
|
|
1771
1884
|
stdin.on("end", onEnd);
|
|
1772
1885
|
});
|
|
1773
1886
|
} finally {
|
|
1887
|
+
stderr.off?.("resize", redraw);
|
|
1774
1888
|
draw(outcome ?? "cancel");
|
|
1775
1889
|
stderr.write(`
|
|
1776
|
-
\x1B[?25h`);
|
|
1890
|
+
\x1B[?25h\x1B[?2004l`);
|
|
1777
1891
|
stdin.setRawMode(false);
|
|
1778
1892
|
stdin.pause();
|
|
1779
1893
|
}
|
|
@@ -2137,13 +2251,12 @@ class Redactor {
|
|
|
2137
2251
|
var LABEL_FORMAT = ["project", "project.config_files", "project.environment_file", "project.working_dir"].map((label) => `{{.Label "com.docker.compose.${label}"}}`).join("\t");
|
|
2138
2252
|
var COMPOSE_FILE_VAR = /^\s*(?:export\s+)?COMPOSE_FILE\s*=\s*\S/m;
|
|
2139
2253
|
var COMPOSE_FILES = ["compose.yaml", "compose.yml", "docker-compose.yaml", "docker-compose.yml"];
|
|
2140
|
-
var SKIPPED2 = new Set(["node_modules", "vendor", "dist", "build", "target", "venv", "__pycache__"]);
|
|
2141
2254
|
var ACTIONS = ["shell", "logs", "restart", "up", "stop", "build"];
|
|
2142
2255
|
function from(dir, command) {
|
|
2143
2256
|
return dir === "." ? command : ["env", "-C", dir, ...command];
|
|
2144
2257
|
}
|
|
2145
2258
|
function children(dir = ".") {
|
|
2146
|
-
return readdirSync(dir, { withFileTypes: true }).filter((child) => child.isDirectory() && !child.name.startsWith(".") && !
|
|
2259
|
+
return readdirSync(dir, { withFileTypes: true }).filter((child) => child.isDirectory() && !child.name.startsWith(".") && !SKIPPED_FOLDERS.has(child.name)).map((child) => child.name).sort();
|
|
2147
2260
|
}
|
|
2148
2261
|
function up2(dir) {
|
|
2149
2262
|
const dirs = [];
|
|
@@ -2326,7 +2439,7 @@ async function consoleAt(dir) {
|
|
|
2326
2439
|
const php = stack === undefined ? undefined : phpService((await services(stack)).map((service) => service.name));
|
|
2327
2440
|
if (stack !== undefined && php !== undefined)
|
|
2328
2441
|
return { dir, run: [...stack.run, "exec", php, "bin/console"], list: { ...stack.list, argv: [...stack.list.argv, "exec", "-T", php, "bin/console"] } };
|
|
2329
|
-
return { dir, run: from(dir, ["php", "bin/console"]), list: { argv: ["php", "bin/console"], cwd: resolve4(dir), env:
|
|
2442
|
+
return { dir, run: from(dir, ["php", "bin/console"]), list: { argv: ["php", "bin/console"], cwd: resolve4(dir), env: process17.env } };
|
|
2330
2443
|
}
|
|
2331
2444
|
async function consoles() {
|
|
2332
2445
|
const here = up2(".").find((dir) => existsSync5(join9(dir, "bin/console")));
|
|
@@ -2334,7 +2447,7 @@ async function consoles() {
|
|
|
2334
2447
|
return Promise.all([...new Set(dirs)].map(consoleAt));
|
|
2335
2448
|
}
|
|
2336
2449
|
function cached(dir) {
|
|
2337
|
-
return join9(
|
|
2450
|
+
return join9(process17.env.XDG_CACHE_HOME ?? join9(homedir5(), ".cache"), "sf", `${resolve4(dir).replaceAll("/", "%")}.json`);
|
|
2338
2451
|
}
|
|
2339
2452
|
function fromCache(dir) {
|
|
2340
2453
|
try {
|
|
@@ -2428,7 +2541,7 @@ async function answered(command, ask) {
|
|
|
2428
2541
|
return { argv, given };
|
|
2429
2542
|
}
|
|
2430
2543
|
function interactive() {
|
|
2431
|
-
return
|
|
2544
|
+
return isInteractive();
|
|
2432
2545
|
}
|
|
2433
2546
|
async function execute(emitting, typed, recorded, command) {
|
|
2434
2547
|
if (emitting) {
|
|
@@ -2475,7 +2588,7 @@ async function hidden(flag, rest) {
|
|
|
2475
2588
|
return 0;
|
|
2476
2589
|
}
|
|
2477
2590
|
if (refreshed)
|
|
2478
|
-
Bun.spawn([
|
|
2591
|
+
Bun.spawn([process17.execPath, process17.argv[1], "--rows"], { stdio: ["ignore", "ignore", "ignore"] }).unref();
|
|
2479
2592
|
list(byRecency(found, runs("sf"), key2).map((entry) => ({
|
|
2480
2593
|
label: [key2(entry), signature(entry.command)].filter(Boolean).join(" "),
|
|
2481
2594
|
hint: entry.command.description,
|
|
@@ -2535,7 +2648,7 @@ async function sf(args) {
|
|
|
2535
2648
|
const picked = await pick(rows(found), {
|
|
2536
2649
|
prompt: "sf> ",
|
|
2537
2650
|
searched: 1,
|
|
2538
|
-
preview: `${
|
|
2651
|
+
preview: `${process17.execPath} ${process17.argv[1]} --show {1} {2}`,
|
|
2539
2652
|
reload: refreshed ? { onOpen: true, run: async () => ({ rows: rows(await entries2(true)) }) } : undefined
|
|
2540
2653
|
});
|
|
2541
2654
|
const entry = picked && (await entries2(false)).find((candidate) => candidate.app.dir === picked.hidden[0] && candidate.command.name === picked.hidden[1]);
|
|
@@ -2543,4 +2656,4 @@ async function sf(args) {
|
|
|
2543
2656
|
}
|
|
2544
2657
|
|
|
2545
2658
|
// src/sf-cli.ts
|
|
2546
|
-
|
|
2659
|
+
process18.exitCode = await runMain({ name: "sf", run: sf });
|