bashio 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +338 -266
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -579,8 +579,11 @@ var AddShortcutCommand = class extends Command {
|
|
|
579
579
|
};
|
|
580
580
|
|
|
581
581
|
// src/cli/commands/AuthCommand.ts
|
|
582
|
-
import { input as input3, password, select } from "@inquirer/prompts";
|
|
583
582
|
import { Command as Command2 } from "clipanion";
|
|
583
|
+
import pc4 from "picocolors";
|
|
584
|
+
|
|
585
|
+
// src/core/auth.ts
|
|
586
|
+
import { input as input3, password, select } from "@inquirer/prompts";
|
|
584
587
|
import pc3 from "picocolors";
|
|
585
588
|
|
|
586
589
|
// src/providers/base.ts
|
|
@@ -932,6 +935,205 @@ function createSpinner(text) {
|
|
|
932
935
|
});
|
|
933
936
|
}
|
|
934
937
|
|
|
938
|
+
// src/core/auth.ts
|
|
939
|
+
function showWelcomeBanner() {
|
|
940
|
+
const cyan = pc3.cyan;
|
|
941
|
+
const dim = pc3.dim;
|
|
942
|
+
const width = 58;
|
|
943
|
+
const ansiRegex = new RegExp(
|
|
944
|
+
`${String.fromCharCode(27)}\\[[0-9;]*[a-zA-Z]`,
|
|
945
|
+
"g"
|
|
946
|
+
);
|
|
947
|
+
const stripAnsi2 = (str) => str.replace(ansiRegex, "");
|
|
948
|
+
const visibleLength = (str) => stripAnsi2(str).length;
|
|
949
|
+
const pad = (text, len) => {
|
|
950
|
+
const padding = len - visibleLength(text);
|
|
951
|
+
return text + " ".repeat(Math.max(0, padding));
|
|
952
|
+
};
|
|
953
|
+
const line = (content) => cyan(" \u2502") + pad(content, width) + cyan("\u2502");
|
|
954
|
+
console.log();
|
|
955
|
+
console.log(cyan(` \u250C${"\u2500".repeat(width)}\u2510`));
|
|
956
|
+
console.log(line(""));
|
|
957
|
+
console.log(
|
|
958
|
+
line(
|
|
959
|
+
` ${pc3.bold(pc3.white("\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557"))}`
|
|
960
|
+
)
|
|
961
|
+
);
|
|
962
|
+
console.log(
|
|
963
|
+
line(
|
|
964
|
+
` ${pc3.bold(pc3.white("\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557"))}`
|
|
965
|
+
)
|
|
966
|
+
);
|
|
967
|
+
console.log(
|
|
968
|
+
line(
|
|
969
|
+
` ${pc3.bold(pc3.white("\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551"))}`
|
|
970
|
+
)
|
|
971
|
+
);
|
|
972
|
+
console.log(
|
|
973
|
+
line(
|
|
974
|
+
` ${pc3.bold(pc3.white("\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551"))}`
|
|
975
|
+
)
|
|
976
|
+
);
|
|
977
|
+
console.log(
|
|
978
|
+
line(
|
|
979
|
+
` ${pc3.bold(pc3.white("\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D"))}`
|
|
980
|
+
)
|
|
981
|
+
);
|
|
982
|
+
console.log(
|
|
983
|
+
line(
|
|
984
|
+
` ${pc3.bold(pc3.white("\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D"))}`
|
|
985
|
+
)
|
|
986
|
+
);
|
|
987
|
+
console.log(line(""));
|
|
988
|
+
console.log(line(dim(" Natural language to shell commands.")));
|
|
989
|
+
console.log(line(dim(" Stop Googling, start doing.")));
|
|
990
|
+
console.log(line(""));
|
|
991
|
+
console.log(cyan(` \u2514${"\u2500".repeat(width)}\u2518`));
|
|
992
|
+
console.log();
|
|
993
|
+
}
|
|
994
|
+
async function runAuthSetup(showBanner = true) {
|
|
995
|
+
if (showBanner) {
|
|
996
|
+
showWelcomeBanner();
|
|
997
|
+
}
|
|
998
|
+
console.log(pc3.bold(" Bashio Setup\n"));
|
|
999
|
+
const provider = await select({
|
|
1000
|
+
message: "Select your AI provider:",
|
|
1001
|
+
choices: [
|
|
1002
|
+
{
|
|
1003
|
+
value: "claude",
|
|
1004
|
+
name: "Claude (Anthropic)",
|
|
1005
|
+
description: "Use Anthropic API key"
|
|
1006
|
+
},
|
|
1007
|
+
{
|
|
1008
|
+
value: "openai",
|
|
1009
|
+
name: "ChatGPT (OpenAI)",
|
|
1010
|
+
description: "Use OpenAI API key"
|
|
1011
|
+
},
|
|
1012
|
+
{
|
|
1013
|
+
value: "ollama",
|
|
1014
|
+
name: "Ollama (Local)",
|
|
1015
|
+
description: "Free, runs on your machine"
|
|
1016
|
+
},
|
|
1017
|
+
{
|
|
1018
|
+
value: "openrouter",
|
|
1019
|
+
name: "OpenRouter",
|
|
1020
|
+
description: "Pay per use, multiple models"
|
|
1021
|
+
}
|
|
1022
|
+
]
|
|
1023
|
+
});
|
|
1024
|
+
let credentials;
|
|
1025
|
+
let model;
|
|
1026
|
+
switch (provider) {
|
|
1027
|
+
case "claude": {
|
|
1028
|
+
const apiKey = await password({
|
|
1029
|
+
message: "Enter your Anthropic API key:",
|
|
1030
|
+
mask: "*"
|
|
1031
|
+
});
|
|
1032
|
+
credentials = { type: "api_key", apiKey };
|
|
1033
|
+
model = await select({
|
|
1034
|
+
message: "Select model:",
|
|
1035
|
+
choices: CLAUDE_MODELS.map((m) => ({
|
|
1036
|
+
value: m.value,
|
|
1037
|
+
name: m.label
|
|
1038
|
+
}))
|
|
1039
|
+
});
|
|
1040
|
+
break;
|
|
1041
|
+
}
|
|
1042
|
+
case "openai": {
|
|
1043
|
+
const apiKey = await password({
|
|
1044
|
+
message: "Enter your OpenAI API key:",
|
|
1045
|
+
mask: "*"
|
|
1046
|
+
});
|
|
1047
|
+
credentials = { type: "api_key", apiKey };
|
|
1048
|
+
model = await select({
|
|
1049
|
+
message: "Select model:",
|
|
1050
|
+
choices: OPENAI_MODELS.map((m) => ({
|
|
1051
|
+
value: m.value,
|
|
1052
|
+
name: m.label
|
|
1053
|
+
}))
|
|
1054
|
+
});
|
|
1055
|
+
break;
|
|
1056
|
+
}
|
|
1057
|
+
case "ollama": {
|
|
1058
|
+
const host = await input3({
|
|
1059
|
+
message: "Ollama host:",
|
|
1060
|
+
default: "http://localhost:11434"
|
|
1061
|
+
});
|
|
1062
|
+
credentials = { type: "local", host };
|
|
1063
|
+
const spinner2 = createSpinner("Checking Ollama connection...").start();
|
|
1064
|
+
const availableModels = await OllamaProvider.getAvailableModels(host);
|
|
1065
|
+
if (availableModels.length === 0) {
|
|
1066
|
+
spinner2.fail("Could not connect to Ollama or no models installed");
|
|
1067
|
+
console.log(pc3.yellow("\nMake sure Ollama is running: ollama serve"));
|
|
1068
|
+
console.log(pc3.yellow("Install a model: ollama pull llama3.2\n"));
|
|
1069
|
+
return false;
|
|
1070
|
+
}
|
|
1071
|
+
spinner2.succeed(`Found ${availableModels.length} models`);
|
|
1072
|
+
const modelChoices = availableModels.map((m) => ({
|
|
1073
|
+
value: m,
|
|
1074
|
+
name: m
|
|
1075
|
+
}));
|
|
1076
|
+
model = await select({
|
|
1077
|
+
message: "Select model:",
|
|
1078
|
+
choices: modelChoices
|
|
1079
|
+
});
|
|
1080
|
+
break;
|
|
1081
|
+
}
|
|
1082
|
+
case "openrouter": {
|
|
1083
|
+
const apiKey = await password({
|
|
1084
|
+
message: "Enter your OpenRouter API key:",
|
|
1085
|
+
mask: "*"
|
|
1086
|
+
});
|
|
1087
|
+
credentials = { type: "api_key", apiKey };
|
|
1088
|
+
model = await select({
|
|
1089
|
+
message: "Select model:",
|
|
1090
|
+
choices: OPENROUTER_MODELS.map((m) => ({
|
|
1091
|
+
value: m.value,
|
|
1092
|
+
name: m.label
|
|
1093
|
+
}))
|
|
1094
|
+
});
|
|
1095
|
+
break;
|
|
1096
|
+
}
|
|
1097
|
+
default:
|
|
1098
|
+
throw new Error(`Unknown provider: ${provider}`);
|
|
1099
|
+
}
|
|
1100
|
+
const config = {
|
|
1101
|
+
version: 1,
|
|
1102
|
+
provider,
|
|
1103
|
+
model,
|
|
1104
|
+
credentials,
|
|
1105
|
+
settings: {
|
|
1106
|
+
confirmBeforeExecute: true,
|
|
1107
|
+
historyEnabled: true,
|
|
1108
|
+
historyRetentionDays: 30,
|
|
1109
|
+
historyMaxEntries: 2e3,
|
|
1110
|
+
autoConfirmShortcuts: false
|
|
1111
|
+
}
|
|
1112
|
+
};
|
|
1113
|
+
const spinner = createSpinner("Validating credentials...").start();
|
|
1114
|
+
try {
|
|
1115
|
+
const providerInstance = createProvider(config);
|
|
1116
|
+
const valid = await providerInstance.validateCredentials();
|
|
1117
|
+
if (!valid) {
|
|
1118
|
+
spinner.fail("Invalid credentials");
|
|
1119
|
+
return false;
|
|
1120
|
+
}
|
|
1121
|
+
spinner.succeed("Credentials valid");
|
|
1122
|
+
} catch (err) {
|
|
1123
|
+
spinner.fail(
|
|
1124
|
+
`Validation failed: ${err instanceof Error ? err.message : "Unknown error"}`
|
|
1125
|
+
);
|
|
1126
|
+
return false;
|
|
1127
|
+
}
|
|
1128
|
+
saveConfig(config);
|
|
1129
|
+
console.log();
|
|
1130
|
+
logger.success("Configuration saved!");
|
|
1131
|
+
console.log(pc3.gray(` Provider: ${provider}`));
|
|
1132
|
+
console.log(pc3.gray(` Model: ${model}`));
|
|
1133
|
+
console.log();
|
|
1134
|
+
return true;
|
|
1135
|
+
}
|
|
1136
|
+
|
|
935
1137
|
// src/cli/commands/AuthCommand.ts
|
|
936
1138
|
var AuthCommand = class extends Command2 {
|
|
937
1139
|
static paths = [["auth"], ["--auth"]];
|
|
@@ -940,167 +1142,34 @@ var AuthCommand = class extends Command2 {
|
|
|
940
1142
|
examples: [["Configure AI provider", "$0 --auth"]]
|
|
941
1143
|
});
|
|
942
1144
|
async execute() {
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
value: "claude",
|
|
949
|
-
name: "Claude (Anthropic)",
|
|
950
|
-
description: "Use Anthropic API key"
|
|
951
|
-
},
|
|
952
|
-
{
|
|
953
|
-
value: "openai",
|
|
954
|
-
name: "ChatGPT (OpenAI)",
|
|
955
|
-
description: "Use OpenAI API key"
|
|
956
|
-
},
|
|
957
|
-
{
|
|
958
|
-
value: "ollama",
|
|
959
|
-
name: "Ollama (Local)",
|
|
960
|
-
description: "Free, runs on your machine"
|
|
961
|
-
},
|
|
962
|
-
{
|
|
963
|
-
value: "openrouter",
|
|
964
|
-
name: "OpenRouter",
|
|
965
|
-
description: "Pay per use, multiple models"
|
|
966
|
-
}
|
|
967
|
-
]
|
|
968
|
-
});
|
|
969
|
-
let credentials;
|
|
970
|
-
let model;
|
|
971
|
-
switch (provider) {
|
|
972
|
-
case "claude": {
|
|
973
|
-
const apiKey = await password({
|
|
974
|
-
message: "Enter your Anthropic API key:",
|
|
975
|
-
mask: "*"
|
|
976
|
-
});
|
|
977
|
-
credentials = { type: "api_key", apiKey };
|
|
978
|
-
model = await select({
|
|
979
|
-
message: "Select model:",
|
|
980
|
-
choices: CLAUDE_MODELS.map((m) => ({
|
|
981
|
-
value: m.value,
|
|
982
|
-
name: m.label
|
|
983
|
-
}))
|
|
984
|
-
});
|
|
985
|
-
break;
|
|
986
|
-
}
|
|
987
|
-
case "openai": {
|
|
988
|
-
const apiKey = await password({
|
|
989
|
-
message: "Enter your OpenAI API key:",
|
|
990
|
-
mask: "*"
|
|
991
|
-
});
|
|
992
|
-
credentials = { type: "api_key", apiKey };
|
|
993
|
-
model = await select({
|
|
994
|
-
message: "Select model:",
|
|
995
|
-
choices: OPENAI_MODELS.map((m) => ({
|
|
996
|
-
value: m.value,
|
|
997
|
-
name: m.label
|
|
998
|
-
}))
|
|
999
|
-
});
|
|
1000
|
-
break;
|
|
1001
|
-
}
|
|
1002
|
-
case "ollama": {
|
|
1003
|
-
const host = await input3({
|
|
1004
|
-
message: "Ollama host:",
|
|
1005
|
-
default: "http://localhost:11434"
|
|
1006
|
-
});
|
|
1007
|
-
credentials = { type: "local", host };
|
|
1008
|
-
const spinner2 = createSpinner("Checking Ollama connection...").start();
|
|
1009
|
-
const availableModels = await OllamaProvider.getAvailableModels(host);
|
|
1010
|
-
if (availableModels.length === 0) {
|
|
1011
|
-
spinner2.fail("Could not connect to Ollama or no models installed");
|
|
1012
|
-
console.log(pc3.yellow("\nMake sure Ollama is running: ollama serve"));
|
|
1013
|
-
console.log(pc3.yellow("Install a model: ollama pull llama3.2\n"));
|
|
1014
|
-
return 1;
|
|
1015
|
-
}
|
|
1016
|
-
spinner2.succeed(`Found ${availableModels.length} models`);
|
|
1017
|
-
const modelChoices = availableModels.map((m) => ({
|
|
1018
|
-
value: m,
|
|
1019
|
-
name: m
|
|
1020
|
-
}));
|
|
1021
|
-
model = await select({
|
|
1022
|
-
message: "Select model:",
|
|
1023
|
-
choices: modelChoices
|
|
1024
|
-
});
|
|
1025
|
-
break;
|
|
1026
|
-
}
|
|
1027
|
-
case "openrouter": {
|
|
1028
|
-
const apiKey = await password({
|
|
1029
|
-
message: "Enter your OpenRouter API key:",
|
|
1030
|
-
mask: "*"
|
|
1031
|
-
});
|
|
1032
|
-
credentials = { type: "api_key", apiKey };
|
|
1033
|
-
model = await select({
|
|
1034
|
-
message: "Select model:",
|
|
1035
|
-
choices: OPENROUTER_MODELS.map((m) => ({
|
|
1036
|
-
value: m.value,
|
|
1037
|
-
name: m.label
|
|
1038
|
-
}))
|
|
1039
|
-
});
|
|
1040
|
-
break;
|
|
1041
|
-
}
|
|
1042
|
-
default:
|
|
1043
|
-
throw new Error(`Unknown provider: ${provider}`);
|
|
1044
|
-
}
|
|
1045
|
-
const config = {
|
|
1046
|
-
version: 1,
|
|
1047
|
-
provider,
|
|
1048
|
-
model,
|
|
1049
|
-
credentials,
|
|
1050
|
-
settings: {
|
|
1051
|
-
confirmBeforeExecute: true,
|
|
1052
|
-
historyEnabled: true,
|
|
1053
|
-
historyRetentionDays: 30,
|
|
1054
|
-
historyMaxEntries: 2e3,
|
|
1055
|
-
autoConfirmShortcuts: false
|
|
1056
|
-
}
|
|
1057
|
-
};
|
|
1058
|
-
const spinner = createSpinner("Validating credentials...").start();
|
|
1059
|
-
try {
|
|
1060
|
-
const providerInstance = createProvider(config);
|
|
1061
|
-
const valid = await providerInstance.validateCredentials();
|
|
1062
|
-
if (!valid) {
|
|
1063
|
-
spinner.fail("Invalid credentials");
|
|
1064
|
-
return 1;
|
|
1065
|
-
}
|
|
1066
|
-
spinner.succeed("Credentials valid");
|
|
1067
|
-
} catch (err) {
|
|
1068
|
-
spinner.fail(
|
|
1069
|
-
`Validation failed: ${err instanceof Error ? err.message : "Unknown error"}`
|
|
1145
|
+
const success = await runAuthSetup();
|
|
1146
|
+
if (success) {
|
|
1147
|
+
console.log(
|
|
1148
|
+
pc4.green("You're all set! Try:"),
|
|
1149
|
+
pc4.cyan("b find all png files")
|
|
1070
1150
|
);
|
|
1071
|
-
|
|
1151
|
+
console.log();
|
|
1072
1152
|
}
|
|
1073
|
-
|
|
1074
|
-
console.log();
|
|
1075
|
-
logger.success("Configuration saved!");
|
|
1076
|
-
console.log(pc3.gray(` Provider: ${provider}`));
|
|
1077
|
-
console.log(pc3.gray(` Model: ${model}`));
|
|
1078
|
-
console.log();
|
|
1079
|
-
console.log(
|
|
1080
|
-
pc3.green("You're all set! Try:"),
|
|
1081
|
-
pc3.cyan("b find all png files")
|
|
1082
|
-
);
|
|
1083
|
-
console.log();
|
|
1084
|
-
return 0;
|
|
1153
|
+
return success ? 0 : 1;
|
|
1085
1154
|
}
|
|
1086
1155
|
};
|
|
1087
1156
|
|
|
1088
1157
|
// src/cli/commands/ClearHistoryCommand.ts
|
|
1089
1158
|
import { confirm } from "@inquirer/prompts";
|
|
1090
1159
|
import { Command as Command3, Option as Option2 } from "clipanion";
|
|
1091
|
-
import
|
|
1160
|
+
import pc6 from "picocolors";
|
|
1092
1161
|
|
|
1093
1162
|
// src/utils/danger-ui.ts
|
|
1094
|
-
import
|
|
1163
|
+
import pc5 from "picocolors";
|
|
1095
1164
|
var renderDangerBanner = (message, label = "DANGER") => {
|
|
1096
1165
|
const labelText = ` ${label} `;
|
|
1097
1166
|
const spacer = " ";
|
|
1098
1167
|
const contentLength = labelText.length + spacer.length + message.length;
|
|
1099
1168
|
const innerWidth = contentLength + 2;
|
|
1100
1169
|
const border = "\u2500".repeat(innerWidth);
|
|
1101
|
-
const top =
|
|
1102
|
-
const middle = ` ${
|
|
1103
|
-
const bottom =
|
|
1170
|
+
const top = pc5.red(` \u250C${border}\u2510`);
|
|
1171
|
+
const middle = ` ${pc5.red("\u2502 ")}` + pc5.bgRed(pc5.white(labelText)) + pc5.red(`${spacer}${message}`) + pc5.red(" \u2502");
|
|
1172
|
+
const bottom = pc5.red(` \u2514${border}\u2518`);
|
|
1104
1173
|
return [top, middle, bottom];
|
|
1105
1174
|
};
|
|
1106
1175
|
|
|
@@ -1122,14 +1191,14 @@ var ClearHistoryCommand = class extends Command3 {
|
|
|
1122
1191
|
});
|
|
1123
1192
|
async execute() {
|
|
1124
1193
|
if (!this.all && !this.olderThan) {
|
|
1125
|
-
console.log(
|
|
1126
|
-
console.log(
|
|
1127
|
-
console.log(
|
|
1194
|
+
console.log(pc6.bold("\n Clear History\n"));
|
|
1195
|
+
console.log(pc6.gray(" Options:"));
|
|
1196
|
+
console.log(pc6.gray(" --all Clear all history"));
|
|
1128
1197
|
console.log(
|
|
1129
|
-
|
|
1198
|
+
pc6.gray(" --older-than N Clear entries older than N days")
|
|
1130
1199
|
);
|
|
1131
1200
|
console.log();
|
|
1132
|
-
console.log(
|
|
1201
|
+
console.log(pc6.dim(" Example: b --clear-history --older-than 30\n"));
|
|
1133
1202
|
return 1;
|
|
1134
1203
|
}
|
|
1135
1204
|
const currentCount = getHistoryCount();
|
|
@@ -1192,7 +1261,7 @@ var ClearHistoryCommand = class extends Command3 {
|
|
|
1192
1261
|
|
|
1193
1262
|
// src/cli/commands/ConfigCommand.ts
|
|
1194
1263
|
import { Command as Command4 } from "clipanion";
|
|
1195
|
-
import
|
|
1264
|
+
import pc7 from "picocolors";
|
|
1196
1265
|
var ConfigCommand = class extends Command4 {
|
|
1197
1266
|
static paths = [["config"], ["--config"]];
|
|
1198
1267
|
static usage = Command4.Usage({
|
|
@@ -1202,7 +1271,7 @@ var ConfigCommand = class extends Command4 {
|
|
|
1202
1271
|
async execute() {
|
|
1203
1272
|
if (!configExists()) {
|
|
1204
1273
|
logger.warn("Bashio is not configured yet.");
|
|
1205
|
-
console.log(
|
|
1274
|
+
console.log(pc7.gray("Run 'b --auth' to set up your AI provider.\n"));
|
|
1206
1275
|
return 1;
|
|
1207
1276
|
}
|
|
1208
1277
|
const config = loadConfig();
|
|
@@ -1210,21 +1279,21 @@ var ConfigCommand = class extends Command4 {
|
|
|
1210
1279
|
logger.error("Failed to load configuration.");
|
|
1211
1280
|
return 1;
|
|
1212
1281
|
}
|
|
1213
|
-
console.log(
|
|
1214
|
-
console.log(` Provider: ${
|
|
1215
|
-
console.log(` Model: ${
|
|
1216
|
-
console.log(` Auth: ${
|
|
1282
|
+
console.log(pc7.bold("\n Bashio Configuration\n"));
|
|
1283
|
+
console.log(` Provider: ${pc7.cyan(config.provider)}`);
|
|
1284
|
+
console.log(` Model: ${pc7.cyan(config.model)}`);
|
|
1285
|
+
console.log(` Auth: ${pc7.green("Configured")}`);
|
|
1217
1286
|
const settings = config.settings;
|
|
1218
1287
|
console.log();
|
|
1219
|
-
console.log(
|
|
1288
|
+
console.log(pc7.bold(" Settings"));
|
|
1220
1289
|
console.log(
|
|
1221
|
-
` History: ${settings?.historyEnabled !== false ?
|
|
1290
|
+
` History: ${settings?.historyEnabled !== false ? pc7.green("enabled") : pc7.gray("disabled")}`
|
|
1222
1291
|
);
|
|
1223
1292
|
console.log(
|
|
1224
|
-
` Auto-confirm shortcuts: ${settings?.autoConfirmShortcuts ?
|
|
1293
|
+
` Auto-confirm shortcuts: ${settings?.autoConfirmShortcuts ? pc7.green("enabled") : pc7.gray("disabled")}`
|
|
1225
1294
|
);
|
|
1226
1295
|
console.log();
|
|
1227
|
-
console.log(
|
|
1296
|
+
console.log(pc7.gray(` Config file: ${getConfigPath()}`));
|
|
1228
1297
|
console.log();
|
|
1229
1298
|
return 0;
|
|
1230
1299
|
}
|
|
@@ -1234,7 +1303,7 @@ var ConfigCommand = class extends Command4 {
|
|
|
1234
1303
|
import * as readline from "readline";
|
|
1235
1304
|
import { confirm as confirm2, input as input4 } from "@inquirer/prompts";
|
|
1236
1305
|
import { Command as Command5, Option as Option3 } from "clipanion";
|
|
1237
|
-
import
|
|
1306
|
+
import pc8 from "picocolors";
|
|
1238
1307
|
|
|
1239
1308
|
// src/core/executor.ts
|
|
1240
1309
|
import { spawn } from "child_process";
|
|
@@ -1398,18 +1467,21 @@ var DefaultCommand = class extends Command5 {
|
|
|
1398
1467
|
context
|
|
1399
1468
|
);
|
|
1400
1469
|
}
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1470
|
+
let currentConfig = config;
|
|
1471
|
+
if (!configExists() || !currentConfig) {
|
|
1472
|
+
const success = await runAuthSetup();
|
|
1473
|
+
if (!success) {
|
|
1474
|
+
return 1;
|
|
1475
|
+
}
|
|
1476
|
+
console.log(pc8.green("Setup complete! Running your command...\n"));
|
|
1477
|
+
currentConfig = loadConfig();
|
|
1478
|
+
if (!currentConfig) {
|
|
1479
|
+
logger.error("Failed to load configuration after setup.");
|
|
1480
|
+
return 1;
|
|
1481
|
+
}
|
|
1410
1482
|
}
|
|
1411
1483
|
const queryText = this.query.join(" ").trim();
|
|
1412
|
-
const provider = createProvider(
|
|
1484
|
+
const provider = createProvider(currentConfig);
|
|
1413
1485
|
const spinner = createSpinner("Generating command...").start();
|
|
1414
1486
|
let generatedCommand;
|
|
1415
1487
|
try {
|
|
@@ -1436,41 +1508,41 @@ var DefaultCommand = class extends Command5 {
|
|
|
1436
1508
|
});
|
|
1437
1509
|
}
|
|
1438
1510
|
showHelp() {
|
|
1439
|
-
console.log(
|
|
1511
|
+
console.log(pc8.bold("\n Bashio - Natural language to shell commands\n"));
|
|
1440
1512
|
console.log(" Usage:");
|
|
1441
|
-
console.log(
|
|
1442
|
-
console.log(
|
|
1513
|
+
console.log(pc8.cyan(" b <natural language query>"));
|
|
1514
|
+
console.log(pc8.cyan(" b <shortcut> [arguments]"));
|
|
1443
1515
|
console.log();
|
|
1444
1516
|
console.log(" Examples:");
|
|
1445
|
-
console.log(
|
|
1446
|
-
console.log(
|
|
1447
|
-
console.log(
|
|
1517
|
+
console.log(pc8.gray(" b find all files larger than 100mb"));
|
|
1518
|
+
console.log(pc8.gray(" b kill whatever is running on port 3000"));
|
|
1519
|
+
console.log(pc8.gray(" b killport 3000") + pc8.cyan(" (shortcut)"));
|
|
1448
1520
|
console.log();
|
|
1449
1521
|
console.log(" Commands:");
|
|
1450
|
-
console.log(
|
|
1522
|
+
console.log(pc8.gray(" b --auth Configure AI provider"));
|
|
1451
1523
|
console.log(
|
|
1452
|
-
|
|
1524
|
+
pc8.gray(" b --config View current configuration")
|
|
1453
1525
|
);
|
|
1454
|
-
console.log(
|
|
1455
|
-
console.log(
|
|
1456
|
-
console.log(
|
|
1457
|
-
console.log(
|
|
1458
|
-
console.log(
|
|
1526
|
+
console.log(pc8.gray(" b --model Change AI model"));
|
|
1527
|
+
console.log(pc8.gray(" b --shortcuts List all shortcuts"));
|
|
1528
|
+
console.log(pc8.gray(" b --add-shortcut Add a new shortcut"));
|
|
1529
|
+
console.log(pc8.gray(" b --remove-shortcut Remove a shortcut"));
|
|
1530
|
+
console.log(pc8.gray(" b --edit-shortcuts Edit shortcuts in editor"));
|
|
1459
1531
|
console.log();
|
|
1460
1532
|
console.log(" History & Stats:");
|
|
1461
|
-
console.log(
|
|
1462
|
-
console.log(
|
|
1463
|
-
console.log(
|
|
1464
|
-
console.log(
|
|
1533
|
+
console.log(pc8.gray(" b --history View command history"));
|
|
1534
|
+
console.log(pc8.gray(" b --stats View usage statistics"));
|
|
1535
|
+
console.log(pc8.gray(" b --clear-history Clear command history"));
|
|
1536
|
+
console.log(pc8.gray(" b --suggest-shortcuts Suggest new shortcuts"));
|
|
1465
1537
|
console.log();
|
|
1466
|
-
console.log(
|
|
1538
|
+
console.log(pc8.gray(" b --help Show help"));
|
|
1467
1539
|
console.log();
|
|
1468
1540
|
}
|
|
1469
1541
|
async executeWithConfirmation(command, source, context) {
|
|
1470
1542
|
let currentCommand = command;
|
|
1471
1543
|
console.log();
|
|
1472
1544
|
if (source === "shortcut" && context.shortcutName) {
|
|
1473
|
-
console.log(
|
|
1545
|
+
console.log(pc8.gray(` [shortcut: ${context.shortcutName}]`));
|
|
1474
1546
|
}
|
|
1475
1547
|
logger.command(currentCommand);
|
|
1476
1548
|
console.log();
|
|
@@ -1479,7 +1551,7 @@ var DefaultCommand = class extends Command5 {
|
|
|
1479
1551
|
if (action === "explain") {
|
|
1480
1552
|
if (source === "shortcut") {
|
|
1481
1553
|
console.log(
|
|
1482
|
-
|
|
1554
|
+
pc8.gray("\n This command comes from a shortcut, not AI.\n")
|
|
1483
1555
|
);
|
|
1484
1556
|
} else {
|
|
1485
1557
|
const explainConfig = loadConfig();
|
|
@@ -1492,8 +1564,8 @@ var DefaultCommand = class extends Command5 {
|
|
|
1492
1564
|
const explanation = await provider.explainCommand(currentCommand);
|
|
1493
1565
|
explainSpinner.stop();
|
|
1494
1566
|
console.log();
|
|
1495
|
-
console.log(
|
|
1496
|
-
console.log(
|
|
1567
|
+
console.log(pc8.bold(" Explanation:"));
|
|
1568
|
+
console.log(pc8.gray(` ${explanation.split("\n").join("\n ")}`));
|
|
1497
1569
|
console.log();
|
|
1498
1570
|
} catch {
|
|
1499
1571
|
explainSpinner.fail("Failed to get explanation");
|
|
@@ -1555,7 +1627,7 @@ var DefaultCommand = class extends Command5 {
|
|
|
1555
1627
|
if (danger) {
|
|
1556
1628
|
console.log();
|
|
1557
1629
|
if (context.shortcutName) {
|
|
1558
|
-
console.log(
|
|
1630
|
+
console.log(pc8.gray(` [shortcut: ${context.shortcutName}]`));
|
|
1559
1631
|
}
|
|
1560
1632
|
logger.command(command);
|
|
1561
1633
|
console.log();
|
|
@@ -1618,13 +1690,13 @@ var DefaultCommand = class extends Command5 {
|
|
|
1618
1690
|
console.log(line);
|
|
1619
1691
|
}
|
|
1620
1692
|
console.log();
|
|
1621
|
-
console.log(
|
|
1693
|
+
console.log(pc8.yellow(" Reasons:"));
|
|
1622
1694
|
for (const reason of reasons) {
|
|
1623
|
-
console.log(
|
|
1695
|
+
console.log(pc8.yellow(` - ${reason}`));
|
|
1624
1696
|
}
|
|
1625
1697
|
console.log();
|
|
1626
|
-
console.log(
|
|
1627
|
-
console.log(
|
|
1698
|
+
console.log(pc8.gray(" Command:"));
|
|
1699
|
+
console.log(pc8.cyan(` ${command}`));
|
|
1628
1700
|
console.log();
|
|
1629
1701
|
return confirm2({
|
|
1630
1702
|
message: "Proceed with this command?",
|
|
@@ -1637,7 +1709,7 @@ var DefaultCommand = class extends Command5 {
|
|
|
1637
1709
|
input: process.stdin,
|
|
1638
1710
|
output: process.stdout
|
|
1639
1711
|
});
|
|
1640
|
-
process.stdout.write(`${
|
|
1712
|
+
process.stdout.write(`${pc8.green("?")} ${pc8.bold("Edit command:")} `);
|
|
1641
1713
|
rl.write(currentCommand);
|
|
1642
1714
|
rl.on("line", (answer) => {
|
|
1643
1715
|
rl.close();
|
|
@@ -1657,7 +1729,7 @@ var DefaultCommand = class extends Command5 {
|
|
|
1657
1729
|
// src/cli/commands/EditShortcutsCommand.ts
|
|
1658
1730
|
import { spawn as spawn2 } from "child_process";
|
|
1659
1731
|
import { Command as Command6 } from "clipanion";
|
|
1660
|
-
import
|
|
1732
|
+
import pc9 from "picocolors";
|
|
1661
1733
|
var EditShortcutsCommand = class extends Command6 {
|
|
1662
1734
|
static paths = [["edit-shortcuts"], ["--edit-shortcuts"]];
|
|
1663
1735
|
static usage = Command6.Usage({
|
|
@@ -1673,15 +1745,15 @@ var EditShortcutsCommand = class extends Command6 {
|
|
|
1673
1745
|
const editor = process.env.EDITOR || process.env.VISUAL || this.getDefaultEditor();
|
|
1674
1746
|
if (!editor) {
|
|
1675
1747
|
logger.error("No editor found. Set $EDITOR environment variable.");
|
|
1676
|
-
console.log(
|
|
1748
|
+
console.log(pc9.gray(`
|
|
1677
1749
|
Example: export EDITOR=vim`));
|
|
1678
|
-
console.log(
|
|
1679
|
-
console.log(
|
|
1750
|
+
console.log(pc9.gray(` Or: export EDITOR="code --wait"`));
|
|
1751
|
+
console.log(pc9.gray(`
|
|
1680
1752
|
File location: ${filePath}
|
|
1681
1753
|
`));
|
|
1682
1754
|
return 1;
|
|
1683
1755
|
}
|
|
1684
|
-
console.log(
|
|
1756
|
+
console.log(pc9.gray(`
|
|
1685
1757
|
Opening ${filePath} in ${editor}...
|
|
1686
1758
|
`));
|
|
1687
1759
|
return new Promise((resolve) => {
|
|
@@ -1703,7 +1775,7 @@ var EditShortcutsCommand = class extends Command6 {
|
|
|
1703
1775
|
});
|
|
1704
1776
|
child.on("error", (err) => {
|
|
1705
1777
|
logger.error(`Failed to open editor: ${err.message}`);
|
|
1706
|
-
console.log(
|
|
1778
|
+
console.log(pc9.gray(`
|
|
1707
1779
|
File location: ${filePath}
|
|
1708
1780
|
`));
|
|
1709
1781
|
resolve(1);
|
|
@@ -1724,10 +1796,10 @@ var EditShortcutsCommand = class extends Command6 {
|
|
|
1724
1796
|
|
|
1725
1797
|
// src/cli/commands/HistoryCommand.ts
|
|
1726
1798
|
import { Command as Command7, Option as Option4 } from "clipanion";
|
|
1727
|
-
import
|
|
1799
|
+
import pc11 from "picocolors";
|
|
1728
1800
|
|
|
1729
1801
|
// src/utils/table.ts
|
|
1730
|
-
import
|
|
1802
|
+
import pc10 from "picocolors";
|
|
1731
1803
|
var BOX = {
|
|
1732
1804
|
topLeft: "\u250C",
|
|
1733
1805
|
topRight: "\u2510",
|
|
@@ -1784,7 +1856,7 @@ function wrapText(text, maxWidth) {
|
|
|
1784
1856
|
function renderTable(options) {
|
|
1785
1857
|
const { columns, data, title } = options;
|
|
1786
1858
|
if (title) {
|
|
1787
|
-
console.log(
|
|
1859
|
+
console.log(pc10.bold(`
|
|
1788
1860
|
${title}
|
|
1789
1861
|
`));
|
|
1790
1862
|
}
|
|
@@ -1793,20 +1865,20 @@ function renderTable(options) {
|
|
|
1793
1865
|
topBorder += BOX.horizontal.repeat(columns[i].width + 2);
|
|
1794
1866
|
topBorder += i < columns.length - 1 ? BOX.topMid : BOX.topRight;
|
|
1795
1867
|
}
|
|
1796
|
-
console.log(
|
|
1868
|
+
console.log(pc10.dim(topBorder));
|
|
1797
1869
|
let headerRow = ` ${BOX.vertical}`;
|
|
1798
1870
|
for (const col of columns) {
|
|
1799
|
-
headerRow += ` ${
|
|
1871
|
+
headerRow += ` ${pc10.bold(padString(col.header, col.width, col.align))} ${BOX.vertical}`;
|
|
1800
1872
|
}
|
|
1801
1873
|
console.log(
|
|
1802
|
-
|
|
1874
|
+
pc10.dim(headerRow.slice(0, 2)) + headerRow.slice(2, -1) + pc10.dim(BOX.vertical)
|
|
1803
1875
|
);
|
|
1804
1876
|
let headerSep = ` ${BOX.leftMid}`;
|
|
1805
1877
|
for (let i = 0; i < columns.length; i++) {
|
|
1806
1878
|
headerSep += BOX.horizontal.repeat(columns[i].width + 2);
|
|
1807
1879
|
headerSep += i < columns.length - 1 ? BOX.midMid : BOX.rightMid;
|
|
1808
1880
|
}
|
|
1809
|
-
console.log(
|
|
1881
|
+
console.log(pc10.dim(headerSep));
|
|
1810
1882
|
for (const row of data) {
|
|
1811
1883
|
const wrappedColumns = columns.map((col) => {
|
|
1812
1884
|
const value = row[col.key] || "";
|
|
@@ -1826,7 +1898,7 @@ function renderTable(options) {
|
|
|
1826
1898
|
dataRow += ` ${cellValue} ${BOX.vertical}`;
|
|
1827
1899
|
}
|
|
1828
1900
|
console.log(
|
|
1829
|
-
|
|
1901
|
+
pc10.dim(dataRow.slice(0, 2)) + dataRow.slice(2, -1) + pc10.dim(BOX.vertical)
|
|
1830
1902
|
);
|
|
1831
1903
|
}
|
|
1832
1904
|
}
|
|
@@ -1835,7 +1907,7 @@ function renderTable(options) {
|
|
|
1835
1907
|
bottomBorder += BOX.horizontal.repeat(columns[i].width + 2);
|
|
1836
1908
|
bottomBorder += i < columns.length - 1 ? BOX.bottomMid : BOX.bottomRight;
|
|
1837
1909
|
}
|
|
1838
|
-
console.log(
|
|
1910
|
+
console.log(pc10.dim(bottomBorder));
|
|
1839
1911
|
}
|
|
1840
1912
|
|
|
1841
1913
|
// src/cli/commands/HistoryCommand.ts
|
|
@@ -1867,10 +1939,10 @@ var HistoryCommand = class extends Command7 {
|
|
|
1867
1939
|
title = "Recent Command History";
|
|
1868
1940
|
}
|
|
1869
1941
|
if (entries.length === 0) {
|
|
1870
|
-
console.log(
|
|
1942
|
+
console.log(pc11.bold(`
|
|
1871
1943
|
${title}
|
|
1872
1944
|
`));
|
|
1873
|
-
console.log(
|
|
1945
|
+
console.log(pc11.gray(" No history entries found.\n"));
|
|
1874
1946
|
return 0;
|
|
1875
1947
|
}
|
|
1876
1948
|
const data = entries.map((entry, index) => ({
|
|
@@ -1885,32 +1957,32 @@ var HistoryCommand = class extends Command7 {
|
|
|
1885
1957
|
title,
|
|
1886
1958
|
columns: [
|
|
1887
1959
|
{ header: "#", key: "num", width: 3, align: "right" },
|
|
1888
|
-
{ header: "Command", key: "command", width: 35, color:
|
|
1889
|
-
{ header: "Query", key: "query", width: 25, color:
|
|
1960
|
+
{ header: "Command", key: "command", width: 35, color: pc11.yellow },
|
|
1961
|
+
{ header: "Query", key: "query", width: 25, color: pc11.gray },
|
|
1890
1962
|
{
|
|
1891
1963
|
header: "Source",
|
|
1892
1964
|
key: "source",
|
|
1893
1965
|
width: 8,
|
|
1894
|
-
color: (v) => v.trim() === "ai" ?
|
|
1966
|
+
color: (v) => v.trim() === "ai" ? pc11.blue(v) : pc11.cyan(v)
|
|
1895
1967
|
},
|
|
1896
1968
|
{ header: "Status", key: "status", width: 10 },
|
|
1897
1969
|
{ header: "Time", key: "time", width: 10 }
|
|
1898
1970
|
],
|
|
1899
1971
|
data
|
|
1900
1972
|
});
|
|
1901
|
-
console.log(
|
|
1973
|
+
console.log(pc11.dim(`
|
|
1902
1974
|
Showing ${entries.length} entries
|
|
1903
1975
|
`));
|
|
1904
1976
|
return 0;
|
|
1905
1977
|
}
|
|
1906
1978
|
getStatusDisplay(entry) {
|
|
1907
1979
|
if (entry.executed === 0) {
|
|
1908
|
-
return `${
|
|
1980
|
+
return `${pc11.gray("\u25CB")} skipped`;
|
|
1909
1981
|
}
|
|
1910
1982
|
if (entry.exitCode === 0) {
|
|
1911
|
-
return `${
|
|
1983
|
+
return `${pc11.green("\u2713")} success`;
|
|
1912
1984
|
}
|
|
1913
|
-
return `${
|
|
1985
|
+
return `${pc11.red("\u2717")} exit:${entry.exitCode}`;
|
|
1914
1986
|
}
|
|
1915
1987
|
getTimeAgo(isoString) {
|
|
1916
1988
|
const date = new Date(isoString);
|
|
@@ -1931,7 +2003,7 @@ var HistoryCommand = class extends Command7 {
|
|
|
1931
2003
|
import * as readline2 from "readline";
|
|
1932
2004
|
import { select as select2 } from "@inquirer/prompts";
|
|
1933
2005
|
import { Command as Command8 } from "clipanion";
|
|
1934
|
-
import
|
|
2006
|
+
import pc12 from "picocolors";
|
|
1935
2007
|
var selectWithEsc = async (config) => {
|
|
1936
2008
|
const controller = new AbortController();
|
|
1937
2009
|
const input6 = process.stdin;
|
|
@@ -1971,7 +2043,7 @@ var ModelCommand = class extends Command8 {
|
|
|
1971
2043
|
if (!configExists()) {
|
|
1972
2044
|
logger.warn("Bashio is not configured yet.");
|
|
1973
2045
|
console.log(
|
|
1974
|
-
|
|
2046
|
+
pc12.gray("Run 'b --auth' to set up your AI provider first.\n")
|
|
1975
2047
|
);
|
|
1976
2048
|
return 1;
|
|
1977
2049
|
}
|
|
@@ -1980,10 +2052,10 @@ var ModelCommand = class extends Command8 {
|
|
|
1980
2052
|
logger.error("Failed to load configuration.");
|
|
1981
2053
|
return 1;
|
|
1982
2054
|
}
|
|
1983
|
-
console.log(
|
|
1984
|
-
console.log(
|
|
1985
|
-
console.log(
|
|
1986
|
-
console.log(
|
|
2055
|
+
console.log(pc12.bold("\n Change AI Model\n"));
|
|
2056
|
+
console.log(pc12.gray(` Current provider: ${config.provider}`));
|
|
2057
|
+
console.log(pc12.gray(` Current model: ${config.model}`));
|
|
2058
|
+
console.log(pc12.dim(" Press Esc to cancel\n"));
|
|
1987
2059
|
let newModel;
|
|
1988
2060
|
try {
|
|
1989
2061
|
switch (config.provider) {
|
|
@@ -2016,7 +2088,7 @@ var ModelCommand = class extends Command8 {
|
|
|
2016
2088
|
spinner.stop();
|
|
2017
2089
|
if (availableModels.length === 0) {
|
|
2018
2090
|
logger.warn("No models found. Make sure Ollama is running.");
|
|
2019
|
-
console.log(
|
|
2091
|
+
console.log(pc12.gray("\n Install a model: ollama pull llama3.2\n"));
|
|
2020
2092
|
return 1;
|
|
2021
2093
|
}
|
|
2022
2094
|
newModel = await selectWithEsc({
|
|
@@ -2046,7 +2118,7 @@ var ModelCommand = class extends Command8 {
|
|
|
2046
2118
|
}
|
|
2047
2119
|
} catch (error) {
|
|
2048
2120
|
if (isPromptExit(error)) {
|
|
2049
|
-
console.log(
|
|
2121
|
+
console.log(pc12.dim("\n Cancelled.\n"));
|
|
2050
2122
|
return 0;
|
|
2051
2123
|
}
|
|
2052
2124
|
throw error;
|
|
@@ -2067,7 +2139,7 @@ var ModelCommand = class extends Command8 {
|
|
|
2067
2139
|
// src/cli/commands/RemoveShortcutCommand.ts
|
|
2068
2140
|
import { confirm as confirm3 } from "@inquirer/prompts";
|
|
2069
2141
|
import { Command as Command9, Option as Option5 } from "clipanion";
|
|
2070
|
-
import
|
|
2142
|
+
import pc13 from "picocolors";
|
|
2071
2143
|
var RemoveShortcutCommand = class extends Command9 {
|
|
2072
2144
|
static paths = [["remove-shortcut"], ["--remove-shortcut"]];
|
|
2073
2145
|
static usage = Command9.Usage({
|
|
@@ -2082,9 +2154,9 @@ var RemoveShortcutCommand = class extends Command9 {
|
|
|
2082
2154
|
return 1;
|
|
2083
2155
|
}
|
|
2084
2156
|
console.log();
|
|
2085
|
-
console.log(
|
|
2157
|
+
console.log(pc13.gray(` Template: ${shortcut.template}`));
|
|
2086
2158
|
if (shortcut.description) {
|
|
2087
|
-
console.log(
|
|
2159
|
+
console.log(pc13.gray(` Description: ${shortcut.description}`));
|
|
2088
2160
|
}
|
|
2089
2161
|
console.log();
|
|
2090
2162
|
for (const line of renderDangerBanner(
|
|
@@ -2110,7 +2182,7 @@ var RemoveShortcutCommand = class extends Command9 {
|
|
|
2110
2182
|
|
|
2111
2183
|
// src/cli/commands/ShortcutsCommand.ts
|
|
2112
2184
|
import { Command as Command10 } from "clipanion";
|
|
2113
|
-
import
|
|
2185
|
+
import pc14 from "picocolors";
|
|
2114
2186
|
var ShortcutsCommand = class extends Command10 {
|
|
2115
2187
|
static paths = [["shortcuts"], ["--shortcuts"]];
|
|
2116
2188
|
static usage = Command10.Usage({
|
|
@@ -2121,8 +2193,8 @@ var ShortcutsCommand = class extends Command10 {
|
|
|
2121
2193
|
const shortcuts = listShortcuts();
|
|
2122
2194
|
const names = Object.keys(shortcuts);
|
|
2123
2195
|
if (names.length === 0) {
|
|
2124
|
-
console.log(
|
|
2125
|
-
console.log(
|
|
2196
|
+
console.log(pc14.yellow("\n No shortcuts configured yet.\n"));
|
|
2197
|
+
console.log(pc14.gray(" Add one with: b --add-shortcut\n"));
|
|
2126
2198
|
return 0;
|
|
2127
2199
|
}
|
|
2128
2200
|
const data = names.map((name) => {
|
|
@@ -2136,19 +2208,19 @@ var ShortcutsCommand = class extends Command10 {
|
|
|
2136
2208
|
renderTable({
|
|
2137
2209
|
title: "Your Shortcuts",
|
|
2138
2210
|
columns: [
|
|
2139
|
-
{ header: "Name", key: "name", width: 15, color:
|
|
2211
|
+
{ header: "Name", key: "name", width: 15, color: pc14.cyan },
|
|
2140
2212
|
{
|
|
2141
2213
|
header: "Command Template",
|
|
2142
2214
|
key: "template",
|
|
2143
2215
|
width: 45,
|
|
2144
|
-
color:
|
|
2216
|
+
color: pc14.white
|
|
2145
2217
|
},
|
|
2146
|
-
{ header: "Arguments", key: "args", width: 15, color:
|
|
2218
|
+
{ header: "Arguments", key: "args", width: 15, color: pc14.gray }
|
|
2147
2219
|
],
|
|
2148
2220
|
data
|
|
2149
2221
|
});
|
|
2150
2222
|
console.log(
|
|
2151
|
-
|
|
2223
|
+
pc14.dim(
|
|
2152
2224
|
`
|
|
2153
2225
|
Total: ${names.length} shortcut${names.length === 1 ? "" : "s"}
|
|
2154
2226
|
`
|
|
@@ -2160,7 +2232,7 @@ var ShortcutsCommand = class extends Command10 {
|
|
|
2160
2232
|
|
|
2161
2233
|
// src/cli/commands/StatsCommand.ts
|
|
2162
2234
|
import { Command as Command11 } from "clipanion";
|
|
2163
|
-
import
|
|
2235
|
+
import pc15 from "picocolors";
|
|
2164
2236
|
var StatsCommand = class extends Command11 {
|
|
2165
2237
|
static paths = [["--stats"]];
|
|
2166
2238
|
static usage = Command11.Usage({
|
|
@@ -2169,7 +2241,7 @@ var StatsCommand = class extends Command11 {
|
|
|
2169
2241
|
});
|
|
2170
2242
|
async execute() {
|
|
2171
2243
|
const stats = getStats();
|
|
2172
|
-
console.log(
|
|
2244
|
+
console.log(pc15.bold("\n Bashio Usage Statistics\n"));
|
|
2173
2245
|
renderTable({
|
|
2174
2246
|
title: "Overview",
|
|
2175
2247
|
columns: [
|
|
@@ -2216,13 +2288,13 @@ var StatsCommand = class extends Command11 {
|
|
|
2216
2288
|
title: "Most Used Commands",
|
|
2217
2289
|
columns: [
|
|
2218
2290
|
{ header: "#", key: "rank", width: 3, align: "right" },
|
|
2219
|
-
{ header: "Command", key: "command", width: 45, color:
|
|
2291
|
+
{ header: "Command", key: "command", width: 45, color: pc15.cyan },
|
|
2220
2292
|
{ header: "Uses", key: "uses", width: 8, align: "right" },
|
|
2221
2293
|
{
|
|
2222
2294
|
header: "Source",
|
|
2223
2295
|
key: "source",
|
|
2224
2296
|
width: 10,
|
|
2225
|
-
color: (v) => v.trim() === "ai" ?
|
|
2297
|
+
color: (v) => v.trim() === "ai" ? pc15.blue(v) : pc15.cyan(v)
|
|
2226
2298
|
}
|
|
2227
2299
|
],
|
|
2228
2300
|
data: stats.topQueries.map((q, i) => ({
|
|
@@ -2241,7 +2313,7 @@ var StatsCommand = class extends Command11 {
|
|
|
2241
2313
|
// src/cli/commands/SuggestShortcutsCommand.ts
|
|
2242
2314
|
import { confirm as confirm4, input as input5 } from "@inquirer/prompts";
|
|
2243
2315
|
import { Command as Command12, Option as Option6 } from "clipanion";
|
|
2244
|
-
import
|
|
2316
|
+
import pc16 from "picocolors";
|
|
2245
2317
|
|
|
2246
2318
|
// src/core/learning.ts
|
|
2247
2319
|
function suggestShortcutNameFromCommand(command) {
|
|
@@ -2314,35 +2386,35 @@ var SuggestShortcutsCommand = class extends Command12 {
|
|
|
2314
2386
|
async execute() {
|
|
2315
2387
|
const thresholdNum = Number.parseInt(this.threshold, 10) || 3;
|
|
2316
2388
|
const suggestions = getShortcutSuggestions(thresholdNum);
|
|
2317
|
-
console.log(
|
|
2389
|
+
console.log(pc16.bold("\n Shortcut Suggestions\n"));
|
|
2318
2390
|
if (suggestions.length === 0) {
|
|
2319
2391
|
console.log(
|
|
2320
|
-
|
|
2392
|
+
pc16.gray(
|
|
2321
2393
|
" No suggestions yet. Use Bashio more to get personalized suggestions."
|
|
2322
2394
|
)
|
|
2323
2395
|
);
|
|
2324
2396
|
console.log(
|
|
2325
|
-
|
|
2397
|
+
pc16.dim(` (Commands need to be used ${thresholdNum}+ times)
|
|
2326
2398
|
`)
|
|
2327
2399
|
);
|
|
2328
2400
|
return 0;
|
|
2329
2401
|
}
|
|
2330
2402
|
console.log(
|
|
2331
|
-
|
|
2403
|
+
pc16.dim(
|
|
2332
2404
|
` Found ${suggestions.length} frequently used commands that could be shortcuts:
|
|
2333
2405
|
`
|
|
2334
2406
|
)
|
|
2335
2407
|
);
|
|
2336
2408
|
for (const suggestion of suggestions) {
|
|
2337
|
-
console.log(
|
|
2338
|
-
console.log(` ${
|
|
2409
|
+
console.log(pc16.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
2410
|
+
console.log(` ${pc16.yellow("Command:")} ${pc16.cyan(suggestion.command)}`);
|
|
2339
2411
|
console.log(
|
|
2340
|
-
` ${
|
|
2412
|
+
` ${pc16.yellow("Used:")} ${pc16.white(suggestion.useCount.toString())} times`
|
|
2341
2413
|
);
|
|
2342
2414
|
console.log();
|
|
2343
2415
|
const action = await this.promptCreateShortcut();
|
|
2344
2416
|
if (action === "exit") {
|
|
2345
|
-
console.log(
|
|
2417
|
+
console.log(pc16.dim("\n Exiting suggestions.\n"));
|
|
2346
2418
|
return 0;
|
|
2347
2419
|
}
|
|
2348
2420
|
if (action === "yes") {
|
|
@@ -2383,7 +2455,7 @@ var SuggestShortcutsCommand = class extends Command12 {
|
|
|
2383
2455
|
markPatternAsSuggested(suggestion.command);
|
|
2384
2456
|
logger.success(`\u2713 Created shortcut: ${finalName}`);
|
|
2385
2457
|
console.log(
|
|
2386
|
-
|
|
2458
|
+
pc16.dim(
|
|
2387
2459
|
` Usage: b ${finalName}${args2.length > 0 ? ` ${args2.map((a) => `<${a}>`).join(" ")}` : ""}`
|
|
2388
2460
|
)
|
|
2389
2461
|
);
|
|
@@ -2393,7 +2465,7 @@ var SuggestShortcutsCommand = class extends Command12 {
|
|
|
2393
2465
|
console.log();
|
|
2394
2466
|
}
|
|
2395
2467
|
}
|
|
2396
|
-
console.log(
|
|
2468
|
+
console.log(pc16.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n"));
|
|
2397
2469
|
return 0;
|
|
2398
2470
|
}
|
|
2399
2471
|
async promptCreateShortcut() {
|
|
@@ -2439,41 +2511,41 @@ var SuggestShortcutsCommand = class extends Command12 {
|
|
|
2439
2511
|
const boxWidth = 50;
|
|
2440
2512
|
const line = "\u2500".repeat(boxWidth);
|
|
2441
2513
|
console.log();
|
|
2442
|
-
console.log(
|
|
2514
|
+
console.log(pc16.red(` \u250C${line}\u2510`));
|
|
2443
2515
|
console.log(
|
|
2444
|
-
|
|
2516
|
+
pc16.red(" \u2502") + pc16.bold(pc16.red(" \u274C Shortcut Already Exists")) + " ".repeat(boxWidth - 27) + pc16.red("\u2502")
|
|
2445
2517
|
);
|
|
2446
|
-
console.log(
|
|
2518
|
+
console.log(pc16.red(` \u251C${line}\u2524`));
|
|
2447
2519
|
const nameLabel = " Name: ";
|
|
2448
2520
|
const nameValue = name;
|
|
2449
2521
|
const namePadding = boxWidth - nameLabel.length - nameValue.length + 2;
|
|
2450
2522
|
console.log(
|
|
2451
|
-
|
|
2523
|
+
pc16.red(" \u2502") + pc16.gray(nameLabel) + pc16.white(nameValue) + " ".repeat(Math.max(0, namePadding)) + pc16.red("\u2502")
|
|
2452
2524
|
);
|
|
2453
2525
|
const cmdLabel = " Command: ";
|
|
2454
2526
|
const cmdValue = shortcut.template.length > 35 ? `${shortcut.template.slice(0, 32)}...` : shortcut.template;
|
|
2455
2527
|
const cmdPadding = boxWidth - cmdLabel.length - cmdValue.length + 2;
|
|
2456
2528
|
console.log(
|
|
2457
|
-
|
|
2529
|
+
pc16.red(" \u2502") + pc16.gray(cmdLabel) + pc16.cyan(cmdValue) + " ".repeat(Math.max(0, cmdPadding)) + pc16.red("\u2502")
|
|
2458
2530
|
);
|
|
2459
2531
|
if (shortcut.args && shortcut.args.length > 0) {
|
|
2460
2532
|
const argsLabel = " Args: ";
|
|
2461
2533
|
const argsValue = shortcut.args.join(", ");
|
|
2462
2534
|
const argsPadding = boxWidth - argsLabel.length - argsValue.length + 2;
|
|
2463
2535
|
console.log(
|
|
2464
|
-
|
|
2536
|
+
pc16.red(" \u2502") + pc16.gray(argsLabel) + pc16.yellow(argsValue) + " ".repeat(Math.max(0, argsPadding)) + pc16.red("\u2502")
|
|
2465
2537
|
);
|
|
2466
2538
|
}
|
|
2467
|
-
console.log(
|
|
2539
|
+
console.log(pc16.red(` \u2514${line}\u2518`));
|
|
2468
2540
|
console.log();
|
|
2469
|
-
console.log(
|
|
2541
|
+
console.log(pc16.yellow(" Please enter a different name:\n"));
|
|
2470
2542
|
}
|
|
2471
2543
|
};
|
|
2472
2544
|
|
|
2473
2545
|
// src/cli/index.ts
|
|
2474
2546
|
var pkg = {
|
|
2475
2547
|
name: "bashio",
|
|
2476
|
-
version: "0.
|
|
2548
|
+
version: "0.6.0"
|
|
2477
2549
|
};
|
|
2478
2550
|
var notifier = updateNotifier({
|
|
2479
2551
|
pkg,
|