@hoox-sh/hoox-cli 0.11.3 → 0.11.4
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 +158 -41
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -25548,6 +25548,33 @@ var init_cloudflare_service = __esm(() => {
|
|
|
25548
25548
|
init_wrangler_output();
|
|
25549
25549
|
});
|
|
25550
25550
|
|
|
25551
|
+
// src/utils/fs-secure.ts
|
|
25552
|
+
var exports_fs_secure = {};
|
|
25553
|
+
__export(exports_fs_secure, {
|
|
25554
|
+
secureSecretFile: () => secureSecretFile,
|
|
25555
|
+
secureChmod: () => secureChmod,
|
|
25556
|
+
ensureSecretDir: () => ensureSecretDir,
|
|
25557
|
+
SECRET_FILE_MODE: () => SECRET_FILE_MODE,
|
|
25558
|
+
SECRET_DIR_MODE: () => SECRET_DIR_MODE
|
|
25559
|
+
});
|
|
25560
|
+
import { chmodSync as chmodSync3, mkdirSync as mkdirSync3 } from "fs";
|
|
25561
|
+
function secureChmod(path4, mode) {
|
|
25562
|
+
try {
|
|
25563
|
+
chmodSync3(path4, mode);
|
|
25564
|
+
} catch {}
|
|
25565
|
+
}
|
|
25566
|
+
function ensureSecretDir(dir) {
|
|
25567
|
+
try {
|
|
25568
|
+
mkdirSync3(dir, { recursive: true, mode: SECRET_DIR_MODE });
|
|
25569
|
+
} catch {}
|
|
25570
|
+
secureChmod(dir, SECRET_DIR_MODE);
|
|
25571
|
+
}
|
|
25572
|
+
function secureSecretFile(path4) {
|
|
25573
|
+
secureChmod(path4, SECRET_FILE_MODE);
|
|
25574
|
+
}
|
|
25575
|
+
var SECRET_FILE_MODE = 384, SECRET_DIR_MODE = 448;
|
|
25576
|
+
var init_fs_secure = () => {};
|
|
25577
|
+
|
|
25551
25578
|
// src/services/prerequisites/prerequisites-service.ts
|
|
25552
25579
|
class PrerequisitesService {
|
|
25553
25580
|
MINIMUM_WRANGLER = "3.88.0";
|
|
@@ -28583,6 +28610,10 @@ function formatSuccess(message, opts) {
|
|
|
28583
28610
|
function formatError2(error51, opts = {}) {
|
|
28584
28611
|
const message = typeof error51 === "string" ? error51 : error51.message;
|
|
28585
28612
|
const cliError = error51 instanceof CLIError ? error51 : null;
|
|
28613
|
+
const write = (s) => {
|
|
28614
|
+
process.stderr.write(s);
|
|
28615
|
+
process.stdout.write(s);
|
|
28616
|
+
};
|
|
28586
28617
|
if (opts.json) {
|
|
28587
28618
|
const output = {
|
|
28588
28619
|
success: false,
|
|
@@ -28596,12 +28627,12 @@ function formatError2(error51, opts = {}) {
|
|
|
28596
28627
|
if (opts.suggestions && opts.suggestions.length > 0) {
|
|
28597
28628
|
output.suggestions = opts.suggestions;
|
|
28598
28629
|
}
|
|
28599
|
-
|
|
28630
|
+
write(JSON.stringify(output) + `
|
|
28600
28631
|
`);
|
|
28601
28632
|
return;
|
|
28602
28633
|
}
|
|
28603
28634
|
if (opts.quiet) {
|
|
28604
|
-
|
|
28635
|
+
write(`${message}
|
|
28605
28636
|
`);
|
|
28606
28637
|
return;
|
|
28607
28638
|
}
|
|
@@ -28611,13 +28642,13 @@ function formatError2(error51, opts = {}) {
|
|
|
28611
28642
|
titleParts.push(theme.textSubtle(`[${cliError.code}]`));
|
|
28612
28643
|
}
|
|
28613
28644
|
titleParts.push(theme.text(message));
|
|
28614
|
-
|
|
28645
|
+
write(`${titleParts.join(" ")}
|
|
28615
28646
|
`);
|
|
28616
28647
|
if (cliError?.details) {
|
|
28617
28648
|
const detailLines = cliError.details.split(`
|
|
28618
28649
|
`).filter((l) => l.length > 0);
|
|
28619
28650
|
for (const line of detailLines) {
|
|
28620
|
-
|
|
28651
|
+
write(` ${theme.textMuted(line)}
|
|
28621
28652
|
`);
|
|
28622
28653
|
}
|
|
28623
28654
|
}
|
|
@@ -28625,24 +28656,24 @@ function formatError2(error51, opts = {}) {
|
|
|
28625
28656
|
const hasSuggestions = !!opts.suggestions && opts.suggestions.length > 0;
|
|
28626
28657
|
if (hasHint || hasSuggestions) {
|
|
28627
28658
|
if (inCard) {
|
|
28628
|
-
|
|
28659
|
+
write(` ${theme.border(icons.pipe)}
|
|
28629
28660
|
`);
|
|
28630
28661
|
}
|
|
28631
28662
|
if (hasHint) {
|
|
28632
|
-
|
|
28663
|
+
write(` ${inCard ? theme.border(icons.pipe) : " "} ${theme.dim("\u21B3 hint:")} ${theme.value(cliError.hint)}
|
|
28633
28664
|
`);
|
|
28634
28665
|
}
|
|
28635
28666
|
if (hasSuggestions) {
|
|
28636
28667
|
const sugText = opts.suggestions.map((s) => `'${s}'`).join(", ");
|
|
28637
|
-
|
|
28668
|
+
write(` ${inCard ? theme.border(icons.pipe) : " "} ${theme.dim("did you mean:")} ${theme.accent(sugText)} ${theme.dim("?")}
|
|
28638
28669
|
`);
|
|
28639
28670
|
}
|
|
28640
28671
|
if (inCard) {
|
|
28641
|
-
|
|
28672
|
+
write(` ${theme.border(icons.pipe)}
|
|
28642
28673
|
`);
|
|
28643
28674
|
}
|
|
28644
28675
|
} else if (inCard && !cliError?.details) {
|
|
28645
|
-
|
|
28676
|
+
write(` ${theme.border(icons.pipe)}
|
|
28646
28677
|
`);
|
|
28647
28678
|
}
|
|
28648
28679
|
}
|
|
@@ -29189,6 +29220,8 @@ async function createDevVars(config2, secrets, opts) {
|
|
|
29189
29220
|
const dir = `${worker.path}`;
|
|
29190
29221
|
try {
|
|
29191
29222
|
await Bun.write(filePath, content);
|
|
29223
|
+
const { secureSecretFile: secureSecretFile2 } = await Promise.resolve().then(() => (init_fs_secure(), exports_fs_secure));
|
|
29224
|
+
secureSecretFile2(filePath);
|
|
29192
29225
|
if (!opts?.quiet) {
|
|
29193
29226
|
formatSuccess(`Created ${filePath}`, opts);
|
|
29194
29227
|
}
|
|
@@ -29196,6 +29229,8 @@ async function createDevVars(config2, secrets, opts) {
|
|
|
29196
29229
|
const { mkdir } = await import("fs/promises");
|
|
29197
29230
|
await mkdir(dir, { recursive: true });
|
|
29198
29231
|
await Bun.write(filePath, content);
|
|
29232
|
+
const { secureSecretFile: secureSecretFile2 } = await Promise.resolve().then(() => (init_fs_secure(), exports_fs_secure));
|
|
29233
|
+
secureSecretFile2(filePath);
|
|
29199
29234
|
if (!opts?.quiet) {
|
|
29200
29235
|
formatSuccess(`Created ${filePath}`, opts);
|
|
29201
29236
|
}
|
|
@@ -29586,9 +29621,10 @@ async function runInitCommand(options, globalOpts, isNonInteractive) {
|
|
|
29586
29621
|
}
|
|
29587
29622
|
// src/services/setup/setup-service.ts
|
|
29588
29623
|
import {
|
|
29589
|
-
chmodSync as
|
|
29624
|
+
chmodSync as chmodSync4,
|
|
29590
29625
|
existsSync as existsSync7,
|
|
29591
|
-
mkdirSync as
|
|
29626
|
+
mkdirSync as mkdirSync4,
|
|
29627
|
+
readdirSync as readdirSync3,
|
|
29592
29628
|
readFileSync as readFileSync3,
|
|
29593
29629
|
statSync as statSync2,
|
|
29594
29630
|
writeFileSync as writeFileSync2
|
|
@@ -29663,9 +29699,38 @@ function parseEnvFile(text2) {
|
|
|
29663
29699
|
}
|
|
29664
29700
|
function safeChmod(path4, mode) {
|
|
29665
29701
|
try {
|
|
29666
|
-
|
|
29702
|
+
chmodSync4(path4, mode);
|
|
29667
29703
|
} catch {}
|
|
29668
29704
|
}
|
|
29705
|
+
function loadExistingKeysFromDisk() {
|
|
29706
|
+
const setupEnv = join7(KEYS_DIR, "setup.env");
|
|
29707
|
+
if (!existsSync7(setupEnv))
|
|
29708
|
+
return null;
|
|
29709
|
+
let text2;
|
|
29710
|
+
try {
|
|
29711
|
+
text2 = readFileSync3(setupEnv, "utf-8");
|
|
29712
|
+
} catch {
|
|
29713
|
+
return null;
|
|
29714
|
+
}
|
|
29715
|
+
const map2 = parseEnvFile(text2);
|
|
29716
|
+
const required2 = [
|
|
29717
|
+
"INTERNAL_KEY_BINDING",
|
|
29718
|
+
"AGENT_INTERNAL_KEY",
|
|
29719
|
+
"SESSION_SECRET",
|
|
29720
|
+
"WEBHOOK_API_KEY_BINDING",
|
|
29721
|
+
"TELEGRAM_INTERNAL_KEY_BINDING",
|
|
29722
|
+
"TRADE_INTERNAL_KEY",
|
|
29723
|
+
"API_SERVICE_KEY_BINDING"
|
|
29724
|
+
];
|
|
29725
|
+
const keys = {};
|
|
29726
|
+
for (const name of required2) {
|
|
29727
|
+
const v = map2.get(name);
|
|
29728
|
+
if (!v)
|
|
29729
|
+
return null;
|
|
29730
|
+
keys[name] = v;
|
|
29731
|
+
}
|
|
29732
|
+
return keys;
|
|
29733
|
+
}
|
|
29669
29734
|
|
|
29670
29735
|
class SetupService {
|
|
29671
29736
|
onProgress;
|
|
@@ -29676,7 +29741,20 @@ class SetupService {
|
|
|
29676
29741
|
}
|
|
29677
29742
|
async generateKeys(skip = false) {
|
|
29678
29743
|
if (skip) {
|
|
29679
|
-
|
|
29744
|
+
const existing = loadExistingKeysFromDisk();
|
|
29745
|
+
if (existing) {
|
|
29746
|
+
this.onProgress({
|
|
29747
|
+
type: "info",
|
|
29748
|
+
step: "keys",
|
|
29749
|
+
message: "Using existing keys from .keys/setup.env (--skip-keys)"
|
|
29750
|
+
});
|
|
29751
|
+
return existing;
|
|
29752
|
+
}
|
|
29753
|
+
this.onProgress({
|
|
29754
|
+
type: "info",
|
|
29755
|
+
step: "keys",
|
|
29756
|
+
message: "Skipped (no existing .keys/setup.env)"
|
|
29757
|
+
});
|
|
29680
29758
|
return null;
|
|
29681
29759
|
}
|
|
29682
29760
|
this.onProgress({
|
|
@@ -29695,9 +29773,9 @@ class SetupService {
|
|
|
29695
29773
|
API_SERVICE_KEY_BINDING: internalKey
|
|
29696
29774
|
};
|
|
29697
29775
|
if (!existsSync7(KEYS_DIR)) {
|
|
29698
|
-
|
|
29776
|
+
mkdirSync4(KEYS_DIR, { recursive: true });
|
|
29699
29777
|
} else if (!statSync2(KEYS_DIR).isDirectory()) {
|
|
29700
|
-
|
|
29778
|
+
mkdirSync4(KEYS_DIR, { recursive: true });
|
|
29701
29779
|
}
|
|
29702
29780
|
safeChmod(KEYS_DIR, 448);
|
|
29703
29781
|
const setupEnvPath = join7(KEYS_DIR, "setup.env");
|
|
@@ -30071,36 +30149,38 @@ class SetupService {
|
|
|
30071
30149
|
];
|
|
30072
30150
|
return markers.some((p3) => existsSync7(p3));
|
|
30073
30151
|
}
|
|
30074
|
-
|
|
30075
|
-
this.onProgress({
|
|
30076
|
-
type: "step-start",
|
|
30077
|
-
step: "workers",
|
|
30078
|
-
message: "Checking worker submodules..."
|
|
30079
|
-
});
|
|
30152
|
+
listMissingWorkers() {
|
|
30080
30153
|
const workerDirs = [
|
|
30081
30154
|
...ALL_WORKERS,
|
|
30082
30155
|
...TOOLING_WORKERS,
|
|
30083
30156
|
"dashboard"
|
|
30084
30157
|
];
|
|
30085
30158
|
const missing = [];
|
|
30086
|
-
const gitmodulesPath = ".gitmodules";
|
|
30087
30159
|
for (const name of workerDirs) {
|
|
30088
30160
|
const dir = `workers/${workerFsDir(name)}`;
|
|
30089
30161
|
try {
|
|
30090
30162
|
const gitEntry = readFileSync3(join7(dir, ".git"), "utf-8").trim();
|
|
30091
30163
|
if (gitEntry.startsWith("gitdir:") || gitEntry.length > 0) {
|
|
30092
|
-
if (!this.isWorkerTreePopulated(dir, name))
|
|
30164
|
+
if (!this.isWorkerTreePopulated(dir, name))
|
|
30093
30165
|
missing.push(name);
|
|
30094
|
-
}
|
|
30095
30166
|
} else if (!this.isWorkerTreePopulated(dir, name)) {
|
|
30096
30167
|
missing.push(name);
|
|
30097
30168
|
}
|
|
30098
30169
|
} catch {
|
|
30099
|
-
if (!this.isWorkerTreePopulated(dir, name))
|
|
30170
|
+
if (!this.isWorkerTreePopulated(dir, name))
|
|
30100
30171
|
missing.push(name);
|
|
30101
|
-
}
|
|
30102
30172
|
}
|
|
30103
30173
|
}
|
|
30174
|
+
return missing;
|
|
30175
|
+
}
|
|
30176
|
+
async ensureWorkers() {
|
|
30177
|
+
this.onProgress({
|
|
30178
|
+
type: "step-start",
|
|
30179
|
+
step: "workers",
|
|
30180
|
+
message: "Checking worker submodules..."
|
|
30181
|
+
});
|
|
30182
|
+
const missing = this.listMissingWorkers();
|
|
30183
|
+
const gitmodulesPath = ".gitmodules";
|
|
30104
30184
|
if (missing.length === 0) {
|
|
30105
30185
|
this.onProgress({
|
|
30106
30186
|
type: "step-complete",
|
|
@@ -30155,14 +30235,17 @@ class SetupService {
|
|
|
30155
30235
|
];
|
|
30156
30236
|
const toBuild = [];
|
|
30157
30237
|
for (const pkg of packages) {
|
|
30238
|
+
let built = false;
|
|
30158
30239
|
try {
|
|
30159
|
-
|
|
30160
|
-
|
|
30161
|
-
|
|
30240
|
+
if (existsSync7(pkg.dist) && statSync2(pkg.dist).isDirectory()) {
|
|
30241
|
+
const entries = readdirSync3(pkg.dist);
|
|
30242
|
+
built = entries.some((e) => e.endsWith(".js"));
|
|
30162
30243
|
}
|
|
30163
30244
|
} catch {
|
|
30164
|
-
|
|
30245
|
+
built = false;
|
|
30165
30246
|
}
|
|
30247
|
+
if (!built)
|
|
30248
|
+
toBuild.push(pkg.name);
|
|
30166
30249
|
}
|
|
30167
30250
|
if (toBuild.length === 0) {
|
|
30168
30251
|
this.onProgress({
|
|
@@ -30479,13 +30562,21 @@ class SetupService {
|
|
|
30479
30562
|
results.success = false;
|
|
30480
30563
|
return results;
|
|
30481
30564
|
}
|
|
30482
|
-
const
|
|
30483
|
-
|
|
30565
|
+
const missingAfterClone = await this.ensureWorkers();
|
|
30566
|
+
const stillMissing = this.listMissingWorkers();
|
|
30567
|
+
if (stillMissing.length > 0) {
|
|
30568
|
+
steps.push({
|
|
30569
|
+
step: "workers",
|
|
30570
|
+
success: false,
|
|
30571
|
+
message: `Missing worker trees: ${stillMissing.join(", ")}. Run: git submodule update --init --recursive`
|
|
30572
|
+
});
|
|
30484
30573
|
this.onProgress({
|
|
30485
|
-
type: "
|
|
30574
|
+
type: "step-error",
|
|
30486
30575
|
step: "workers",
|
|
30487
|
-
message: "
|
|
30576
|
+
message: missingAfterClone.length > 0 ? "Workers still missing after clone attempt \u2014 aborting setup." : "Workers missing \u2014 aborting setup."
|
|
30488
30577
|
});
|
|
30578
|
+
results.success = false;
|
|
30579
|
+
return results;
|
|
30489
30580
|
}
|
|
30490
30581
|
const built = await this.ensurePackages();
|
|
30491
30582
|
if (!built) {
|
|
@@ -30494,6 +30585,8 @@ class SetupService {
|
|
|
30494
30585
|
success: false,
|
|
30495
30586
|
message: "Package build failed \u2014 check dependencies"
|
|
30496
30587
|
});
|
|
30588
|
+
results.success = false;
|
|
30589
|
+
return results;
|
|
30497
30590
|
}
|
|
30498
30591
|
this.fixWranglerConfigs();
|
|
30499
30592
|
const keys = await this.generateKeys(options.skipKeys);
|
|
@@ -30644,6 +30737,14 @@ async function runOnboard(options, fmt) {
|
|
|
30644
30737
|
if (process.exitCode && process.exitCode !== 0) {
|
|
30645
30738
|
return;
|
|
30646
30739
|
}
|
|
30740
|
+
const configReady = await Bun.file("wrangler.jsonc").exists();
|
|
30741
|
+
if (!configReady) {
|
|
30742
|
+
if (!quiet) {
|
|
30743
|
+
formatError2(new CLIError("Onboard stopped: workspace config was not written (init cancelled or incomplete).", 1 /* ERROR */, undefined, false, "Re-run `hoox onboard` or `hoox init` to finish configuration, then `hoox setup`."), fmt);
|
|
30744
|
+
}
|
|
30745
|
+
process.exitCode = 1 /* ERROR */;
|
|
30746
|
+
return;
|
|
30747
|
+
}
|
|
30647
30748
|
if (options.token) {
|
|
30648
30749
|
process.env.CLOUDFLARE_API_TOKEN = options.token;
|
|
30649
30750
|
}
|
|
@@ -33130,6 +33231,8 @@ async function handleInit(opts) {
|
|
|
33130
33231
|
await Bun.write(tmpPath, envContent);
|
|
33131
33232
|
await Bun.write(".env.local", envContent);
|
|
33132
33233
|
await Bun.file(tmpPath).delete().catch(() => {});
|
|
33234
|
+
const { secureSecretFile: secureSecretFile2 } = await Promise.resolve().then(() => (init_fs_secure(), exports_fs_secure));
|
|
33235
|
+
secureSecretFile2(".env.local");
|
|
33133
33236
|
if (!opts.quiet)
|
|
33134
33237
|
formatSuccess(".env.local written", opts);
|
|
33135
33238
|
log.step("Writing .dev.vars files...");
|
|
@@ -33144,6 +33247,8 @@ async function handleInit(opts) {
|
|
|
33144
33247
|
].join(`
|
|
33145
33248
|
`);
|
|
33146
33249
|
await Bun.write(`${workerPath}/.dev.vars`, content);
|
|
33250
|
+
const { secureSecretFile: chmodDev } = await Promise.resolve().then(() => (init_fs_secure(), exports_fs_secure));
|
|
33251
|
+
chmodDev(`${workerPath}/.dev.vars`);
|
|
33147
33252
|
if (!opts.quiet)
|
|
33148
33253
|
formatSuccess(`Created ${workerPath}/.dev.vars`, opts);
|
|
33149
33254
|
}
|
|
@@ -33220,6 +33325,8 @@ async function handleGenerateDevVars(opts) {
|
|
|
33220
33325
|
].join(`
|
|
33221
33326
|
`);
|
|
33222
33327
|
await Bun.write(`${workerPath}/.dev.vars`, content);
|
|
33328
|
+
const { secureSecretFile: secureSecretFile2 } = await Promise.resolve().then(() => (init_fs_secure(), exports_fs_secure));
|
|
33329
|
+
secureSecretFile2(`${workerPath}/.dev.vars`);
|
|
33223
33330
|
count++;
|
|
33224
33331
|
}
|
|
33225
33332
|
formatSuccess(`Generated .dev.vars for ${count} worker(s)`, opts);
|
|
@@ -33467,7 +33574,7 @@ class SecretsService {
|
|
|
33467
33574
|
const path5 = configPath ?? "wrangler.jsonc";
|
|
33468
33575
|
const file2 = Bun.file(path5);
|
|
33469
33576
|
if (!await file2.exists()) {
|
|
33470
|
-
throw new Error(`Config file not found: ${path5}
|
|
33577
|
+
throw new Error(`Config file not found: ${path5}. Run 'hoox onboard' (or 'hoox init') to create one.`);
|
|
33471
33578
|
}
|
|
33472
33579
|
const text2 = await file2.text();
|
|
33473
33580
|
const config2 = parse6(text2);
|
|
@@ -33550,6 +33657,8 @@ class SecretsService {
|
|
|
33550
33657
|
const devVarsPath = `${worker.path}/.dev.vars`;
|
|
33551
33658
|
try {
|
|
33552
33659
|
await Bun.write(devVarsPath, content);
|
|
33660
|
+
const { secureSecretFile: secureSecretFile2 } = await Promise.resolve().then(() => (init_fs_secure(), exports_fs_secure));
|
|
33661
|
+
secureSecretFile2(devVarsPath);
|
|
33553
33662
|
return { ok: true, value: devVarsPath };
|
|
33554
33663
|
} catch (err) {
|
|
33555
33664
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -33797,6 +33906,8 @@ async function updateDevVars(filePath, key, value) {
|
|
|
33797
33906
|
await Bun.write(filePath, `${key}=${value}
|
|
33798
33907
|
`);
|
|
33799
33908
|
}
|
|
33909
|
+
const { secureSecretFile: secureSecretFile2 } = await Promise.resolve().then(() => (init_fs_secure(), exports_fs_secure));
|
|
33910
|
+
secureSecretFile2(filePath);
|
|
33800
33911
|
}
|
|
33801
33912
|
function registerSecretsSubcommands(secretsCmd, service = "config") {
|
|
33802
33913
|
secretsCmd.command("list [worker]").summary("List secrets for all workers or a specific worker").description(`List the secrets declared in wrangler.jsonc for workers.
|
|
@@ -33870,7 +33981,7 @@ EXAMPLES:
|
|
|
33870
33981
|
const svc = await SecretsService.create();
|
|
33871
33982
|
const declared = svc.listSecrets(workerName);
|
|
33872
33983
|
if (!declared.includes(secretName) && declared.length > 0) {
|
|
33873
|
-
throw new CLIError(`Secret "${secretName}" is not declared for worker "${workerName}".
|
|
33984
|
+
throw new CLIError(`Secret "${secretName}" is not declared for worker "${workerName}". Declared secrets: ${declared.join(", ")}`, 2 /* INVALID_USAGE */);
|
|
33874
33985
|
}
|
|
33875
33986
|
const value = await promptSecret(`Enter value for "${secretName}"`);
|
|
33876
33987
|
if (!value) {
|
|
@@ -34053,7 +34164,8 @@ EXAMPLES:
|
|
|
34053
34164
|
}
|
|
34054
34165
|
|
|
34055
34166
|
// src/commands/config/keys-subcommands.ts
|
|
34056
|
-
import { existsSync as existsSync9
|
|
34167
|
+
import { existsSync as existsSync9 } from "fs";
|
|
34168
|
+
init_fs_secure();
|
|
34057
34169
|
init_theme();
|
|
34058
34170
|
function generateKey(bytes = 32) {
|
|
34059
34171
|
const buf = new Uint8Array(bytes);
|
|
@@ -34079,9 +34191,7 @@ EXAMPLES:
|
|
|
34079
34191
|
hoox config keys generate`).action(withErrorHandling(async (_2, cmd) => {
|
|
34080
34192
|
const opts = getFormatOptions(cmd);
|
|
34081
34193
|
const keysDir = ".keys";
|
|
34082
|
-
|
|
34083
|
-
mkdirSync4(keysDir, { recursive: true });
|
|
34084
|
-
}
|
|
34194
|
+
ensureSecretDir(keysDir);
|
|
34085
34195
|
const meshKey = generateKey();
|
|
34086
34196
|
const keys = {
|
|
34087
34197
|
INTERNAL_KEY_BINDING: meshKey,
|
|
@@ -34096,7 +34206,13 @@ EXAMPLES:
|
|
|
34096
34206
|
const filePath = `${keysDir}/${name.toLowerCase()}.env`;
|
|
34097
34207
|
await Bun.write(filePath, `${name}=${value}
|
|
34098
34208
|
`);
|
|
34209
|
+
secureSecretFile(filePath);
|
|
34099
34210
|
}
|
|
34211
|
+
await Bun.write(`${keysDir}/setup.env`, `# Generated by hoox keys generate
|
|
34212
|
+
` + Object.entries(keys).map(([k, v]) => `${k}=${v}`).join(`
|
|
34213
|
+
`) + `
|
|
34214
|
+
`);
|
|
34215
|
+
secureSecretFile(`${keysDir}/setup.env`);
|
|
34100
34216
|
formatSuccess(`Generated ${Object.keys(keys).length} keys in ${keysDir}/`, opts);
|
|
34101
34217
|
if (!opts.quiet && !opts.json) {
|
|
34102
34218
|
process.stdout.write(`${theme.warning("!")} Keep these keys secret. Add ${keysDir}/ to .gitignore.
|
|
@@ -41850,7 +41966,8 @@ program2.exitOverride((err) => {
|
|
|
41850
41966
|
const match = err.message.match(/'([^']+)'/);
|
|
41851
41967
|
const badArg = match?.[1] ?? "";
|
|
41852
41968
|
const suggestion = suggestForCommand(program2, badArg);
|
|
41853
|
-
|
|
41969
|
+
const cleanMsg = err.message.replace(/\n?\(Did you mean[^)]*\)\s*/gi, "").trim();
|
|
41970
|
+
formatError2(new CLIError(cleanMsg, 2 /* INVALID_USAGE */, undefined, false), suggestion ? { ...errFmtOpts, suggestions: [suggestion] } : errFmtOpts);
|
|
41854
41971
|
process.exitCode = 2 /* INVALID_USAGE */;
|
|
41855
41972
|
throw err;
|
|
41856
41973
|
}
|