wispy-cli 2.6.1 → 2.6.3
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/bin/wispy.mjs +162 -1
- package/package.json +1 -1
package/bin/wispy.mjs
CHANGED
|
@@ -881,6 +881,167 @@ if (args[0] === "model") {
|
|
|
881
881
|
process.exit(1);
|
|
882
882
|
}
|
|
883
883
|
|
|
884
|
+
// ── config sub-command ────────────────────────────────────────────────────────
|
|
885
|
+
if (args[0] === "config") {
|
|
886
|
+
const { loadConfig, saveConfig, WISPY_DIR, CONFIG_PATH } = await import(
|
|
887
|
+
path.join(__dirname, "..", "core", "config.mjs")
|
|
888
|
+
);
|
|
889
|
+
const sub = args[1];
|
|
890
|
+
const config = await loadConfig();
|
|
891
|
+
|
|
892
|
+
if (!sub || sub === "show") {
|
|
893
|
+
// wispy config — interactive config menu
|
|
894
|
+
const { select: cfgSelect } = await import("@inquirer/prompts");
|
|
895
|
+
|
|
896
|
+
// Show current status first
|
|
897
|
+
const providers = config.providers ? Object.keys(config.providers) : (config.provider ? [config.provider] : []);
|
|
898
|
+
const providerStr = providers.length > 0 ? providers.join(", ") : _dim("not set");
|
|
899
|
+
const defaultProv = config.defaultProvider ?? config.provider ?? _dim("not set");
|
|
900
|
+
const security = config.security ?? config.securityLevel ?? _dim("not set");
|
|
901
|
+
const language = config.language ?? _dim("auto");
|
|
902
|
+
const wsName = config.workstream ?? "default";
|
|
903
|
+
|
|
904
|
+
console.log(`\n${_bold("Wispy Config")}\n`);
|
|
905
|
+
console.log(` Providers: ${providerStr}`);
|
|
906
|
+
console.log(` Default: ${defaultProv}`);
|
|
907
|
+
console.log(` Security: ${security}`);
|
|
908
|
+
console.log(` Language: ${language}`);
|
|
909
|
+
console.log(` Workstream: ${wsName}`);
|
|
910
|
+
console.log(` Config file: ${_dim(CONFIG_PATH)}`);
|
|
911
|
+
console.log("");
|
|
912
|
+
|
|
913
|
+
const action = await cfgSelect({
|
|
914
|
+
message: "What do you want to change?",
|
|
915
|
+
choices: [
|
|
916
|
+
{ name: "Providers — add/remove AI providers", value: "provider" },
|
|
917
|
+
{ name: "Security — change trust level", value: "security" },
|
|
918
|
+
{ name: "Language — set preferred language", value: "language" },
|
|
919
|
+
{ name: "Channels — configure messaging bots", value: "channels" },
|
|
920
|
+
{ name: "Server — cloud/server settings", value: "server" },
|
|
921
|
+
{ name: "View raw config (JSON)", value: "raw" },
|
|
922
|
+
{ name: "Reset everything", value: "reset" },
|
|
923
|
+
{ name: "Done", value: "done" },
|
|
924
|
+
],
|
|
925
|
+
});
|
|
926
|
+
|
|
927
|
+
if (action === "done") {
|
|
928
|
+
process.exit(0);
|
|
929
|
+
} else if (action === "raw") {
|
|
930
|
+
const display = JSON.parse(JSON.stringify(config));
|
|
931
|
+
if (display.providers) {
|
|
932
|
+
for (const [k, v] of Object.entries(display.providers)) {
|
|
933
|
+
if (v.apiKey) v.apiKey = v.apiKey.slice(0, 6) + "..." + v.apiKey.slice(-4);
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
console.log(JSON.stringify(display, null, 2));
|
|
937
|
+
} else if (action === "reset") {
|
|
938
|
+
const { confirm: cfgConfirm } = await import("@inquirer/prompts");
|
|
939
|
+
const yes = await cfgConfirm({ message: "Reset all configuration?", default: false });
|
|
940
|
+
if (yes) {
|
|
941
|
+
const { writeFile: wf } = await import("node:fs/promises");
|
|
942
|
+
await wf(CONFIG_PATH, "{}\n");
|
|
943
|
+
console.log(`${_green("✓")} Config reset. Run 'wispy setup' to reconfigure.`);
|
|
944
|
+
}
|
|
945
|
+
} else {
|
|
946
|
+
// Delegate to setup wizard step
|
|
947
|
+
const { OnboardingWizard } = await import(
|
|
948
|
+
path.join(__dirname, "..", "core", "onboarding.mjs")
|
|
949
|
+
);
|
|
950
|
+
const wizard = new OnboardingWizard();
|
|
951
|
+
await wizard.runStep(action);
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
} else if (sub === "get") {
|
|
955
|
+
// wispy config get <key>
|
|
956
|
+
const key = args[2];
|
|
957
|
+
if (!key) { console.error(_red("Usage: wispy config get <key>")); process.exit(2); }
|
|
958
|
+
const val = key.split(".").reduce((o, k) => o?.[k], config);
|
|
959
|
+
if (val === undefined) {
|
|
960
|
+
console.log(_dim(`(not set)`));
|
|
961
|
+
} else {
|
|
962
|
+
console.log(typeof val === "object" ? JSON.stringify(val, null, 2) : String(val));
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
} else if (sub === "set") {
|
|
966
|
+
// wispy config set <key> <value>
|
|
967
|
+
const key = args[2];
|
|
968
|
+
const value = args.slice(3).join(" ");
|
|
969
|
+
if (!key || !value) { console.error(_red("Usage: wispy config set <key> <value>")); process.exit(2); }
|
|
970
|
+
|
|
971
|
+
// Parse value
|
|
972
|
+
let parsed = value;
|
|
973
|
+
if (value === "true") parsed = true;
|
|
974
|
+
else if (value === "false") parsed = false;
|
|
975
|
+
else if (/^\d+$/.test(value)) parsed = parseInt(value);
|
|
976
|
+
|
|
977
|
+
// Set nested key
|
|
978
|
+
const keys = key.split(".");
|
|
979
|
+
let obj = config;
|
|
980
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
981
|
+
if (!obj[keys[i]]) obj[keys[i]] = {};
|
|
982
|
+
obj = obj[keys[i]];
|
|
983
|
+
}
|
|
984
|
+
obj[keys[keys.length - 1]] = parsed;
|
|
985
|
+
await saveConfig(config);
|
|
986
|
+
console.log(`${_green("✓")} ${key} = ${parsed}`);
|
|
987
|
+
|
|
988
|
+
} else if (sub === "delete" || sub === "unset") {
|
|
989
|
+
// wispy config delete <key>
|
|
990
|
+
const key = args[2];
|
|
991
|
+
if (!key) { console.error(_red("Usage: wispy config delete <key>")); process.exit(2); }
|
|
992
|
+
const keys = key.split(".");
|
|
993
|
+
let obj = config;
|
|
994
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
995
|
+
if (!obj[keys[i]]) break;
|
|
996
|
+
obj = obj[keys[i]];
|
|
997
|
+
}
|
|
998
|
+
delete obj[keys[keys.length - 1]];
|
|
999
|
+
await saveConfig(config);
|
|
1000
|
+
console.log(`${_green("✓")} ${key} removed`);
|
|
1001
|
+
|
|
1002
|
+
} else if (sub === "reset") {
|
|
1003
|
+
// wispy config reset
|
|
1004
|
+
const { confirm } = await import("@inquirer/prompts");
|
|
1005
|
+
const yes = await confirm({ message: "Reset all configuration? This cannot be undone.", default: false });
|
|
1006
|
+
if (yes) {
|
|
1007
|
+
const { writeFile } = await import("node:fs/promises");
|
|
1008
|
+
await writeFile(CONFIG_PATH, "{}\n");
|
|
1009
|
+
console.log(`${_green("✓")} Config reset. Run 'wispy setup' to reconfigure.`);
|
|
1010
|
+
} else {
|
|
1011
|
+
console.log(_dim("Cancelled."));
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
} else if (sub === "path") {
|
|
1015
|
+
// wispy config path
|
|
1016
|
+
console.log(CONFIG_PATH);
|
|
1017
|
+
|
|
1018
|
+
} else if (sub === "edit") {
|
|
1019
|
+
// wispy config edit — open in $EDITOR
|
|
1020
|
+
const editor = process.env.EDITOR ?? process.env.VISUAL ?? "nano";
|
|
1021
|
+
const { spawn: sp } = await import("node:child_process");
|
|
1022
|
+
sp(editor, [CONFIG_PATH], { stdio: "inherit" });
|
|
1023
|
+
|
|
1024
|
+
} else {
|
|
1025
|
+
console.log(`
|
|
1026
|
+
${_bold("wispy config")} — manage configuration
|
|
1027
|
+
|
|
1028
|
+
${_cyan("wispy config")} Show current config (keys masked)
|
|
1029
|
+
${_cyan("wispy config get <key>")} Get a specific value (dot notation)
|
|
1030
|
+
${_cyan("wispy config set <key> <val>")} Set a value
|
|
1031
|
+
${_cyan("wispy config delete <key>")} Remove a key
|
|
1032
|
+
${_cyan("wispy config reset")} Reset to defaults
|
|
1033
|
+
${_cyan("wispy config path")} Show config file path
|
|
1034
|
+
${_cyan("wispy config edit")} Open in $EDITOR
|
|
1035
|
+
|
|
1036
|
+
${_dim("Examples:")}
|
|
1037
|
+
${_dim("wispy config get defaultProvider")}
|
|
1038
|
+
${_dim("wispy config set security careful")}
|
|
1039
|
+
${_dim("wispy config set language ko")}
|
|
1040
|
+
`);
|
|
1041
|
+
}
|
|
1042
|
+
process.exit(0);
|
|
1043
|
+
}
|
|
1044
|
+
|
|
884
1045
|
// ── status sub-command ────────────────────────────────────────────────────────
|
|
885
1046
|
if (args[0] === "status") {
|
|
886
1047
|
// Try the enhanced status from onboarding.mjs first
|
|
@@ -1909,7 +2070,7 @@ const _KNOWN_COMMANDS = new Set([
|
|
|
1909
2070
|
"ws", "trust", "where", "handoff", "skill", "teach", "improve", "dry",
|
|
1910
2071
|
"setup", "init", "update", "status", "connect", "disconnect", "sync",
|
|
1911
2072
|
"deploy", "migrate", "cron", "audit", "log", "server", "node", "channel",
|
|
1912
|
-
"auth", "tui", "help", "doctor", "completion", "version",
|
|
2073
|
+
"auth", "config", "model", "tui", "help", "doctor", "completion", "version",
|
|
1913
2074
|
// serve flags (handled below)
|
|
1914
2075
|
"--serve", "--telegram", "--discord", "--slack", "--server",
|
|
1915
2076
|
"--help", "-h", "--version", "-v", "--debug", "--tui",
|