@jango-blockchained/hoox-cli 0.10.0 → 0.10.1
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 +90 -32
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -36515,7 +36515,8 @@ import { spawn } from "child_process";
|
|
|
36515
36515
|
import { createRequire } from "module";
|
|
36516
36516
|
import { resolve as resolve6, dirname as dirname3, join as join8 } from "path";
|
|
36517
36517
|
import { fileURLToPath } from "url";
|
|
36518
|
-
import { existsSync as existsSync10 } from "fs";
|
|
36518
|
+
import { existsSync as existsSync10, realpathSync } from "fs";
|
|
36519
|
+
import { homedir as homedir5 } from "os";
|
|
36519
36520
|
|
|
36520
36521
|
// src/services/perf/endpoint-resolver.ts
|
|
36521
36522
|
import { readFileSync as readFileSync5 } from "fs";
|
|
@@ -36568,13 +36569,39 @@ function collectTuiCandidates() {
|
|
|
36568
36569
|
const cwdRequire = createRequire(join8(process.cwd(), "package.json"));
|
|
36569
36570
|
pushPackageEntries(candidates, cwdRequire);
|
|
36570
36571
|
} catch {}
|
|
36572
|
+
const bunGlobal = join8(homedir5(), ".bun", "install", "global", "node_modules", TUI_PKG);
|
|
36573
|
+
pushPackageRootEntries(candidates, bunGlobal);
|
|
36574
|
+
const npmGlobal = process.env.npm_config_prefix?.trim();
|
|
36575
|
+
if (npmGlobal) {
|
|
36576
|
+
pushPackageRootEntries(candidates, join8(npmGlobal, "lib", "node_modules", TUI_PKG));
|
|
36577
|
+
}
|
|
36578
|
+
pushFromWhich(candidates, "hoox-tui");
|
|
36571
36579
|
return [...new Set(candidates)];
|
|
36572
36580
|
}
|
|
36581
|
+
function pushPackageRootEntries(candidates, root) {
|
|
36582
|
+
if (!root || !existsSync10(root))
|
|
36583
|
+
return;
|
|
36584
|
+
candidates.push(join8(root, "dist", "main.js"), join8(root, "src", "main.tsx"), join8(root, "bin", "hoox-tui.js"), join8(root, "src", "main.ts"));
|
|
36585
|
+
}
|
|
36573
36586
|
function pushPackageEntries(candidates, req) {
|
|
36574
36587
|
try {
|
|
36575
36588
|
const pkgJsonPath = req.resolve(`${TUI_PKG}/package.json`);
|
|
36576
|
-
|
|
36577
|
-
|
|
36589
|
+
pushPackageRootEntries(candidates, dirname3(pkgJsonPath));
|
|
36590
|
+
} catch {}
|
|
36591
|
+
}
|
|
36592
|
+
function pushFromWhich(candidates, binName) {
|
|
36593
|
+
try {
|
|
36594
|
+
const which = Bun.which(binName);
|
|
36595
|
+
if (!which)
|
|
36596
|
+
return;
|
|
36597
|
+
let binPath = which;
|
|
36598
|
+
try {
|
|
36599
|
+
binPath = realpathSync(which);
|
|
36600
|
+
} catch {}
|
|
36601
|
+
const binDir = dirname3(binPath);
|
|
36602
|
+
const pkgRoot = resolve6(binDir, "..");
|
|
36603
|
+
pushPackageRootEntries(candidates, pkgRoot);
|
|
36604
|
+
candidates.push(binPath);
|
|
36578
36605
|
} catch {}
|
|
36579
36606
|
}
|
|
36580
36607
|
function resolveTUIEntry() {
|
|
@@ -36591,14 +36618,19 @@ function resolveTUIEntry() {
|
|
|
36591
36618
|
` Runtime root: ${runtime.root ?? "(none)"} [${runtime.source}]`,
|
|
36592
36619
|
` Global repo: ${globalRepo}`,
|
|
36593
36620
|
"",
|
|
36594
|
-
"Fix options:",
|
|
36595
|
-
"
|
|
36596
|
-
"
|
|
36597
|
-
"
|
|
36598
|
-
"
|
|
36599
|
-
" \
|
|
36621
|
+
"Fix options (pick one):",
|
|
36622
|
+
"",
|
|
36623
|
+
" 1) Lightweight \u2014 install the TUI package globally:",
|
|
36624
|
+
" bun add -g @jango-blockchained/hoox-tui",
|
|
36625
|
+
"",
|
|
36626
|
+
" 2) Full runtime \u2014 clone monorepo into ~/.hoox/repo:",
|
|
36627
|
+
" hoox doctor --fix-runtime",
|
|
36628
|
+
"",
|
|
36629
|
+
" 3) Dev \u2014 run inside a hoox checkout, or set:",
|
|
36630
|
+
" export HOOX_REPO=/path/to/hoox",
|
|
36631
|
+
" export HOOX_TUI_ENTRY=/path/to/packages/tui/src/main.tsx",
|
|
36600
36632
|
"",
|
|
36601
|
-
"Then re-run:
|
|
36633
|
+
"Then re-run: hx tui"
|
|
36602
36634
|
].join(`
|
|
36603
36635
|
`), 1 /* ERROR */);
|
|
36604
36636
|
}
|
|
@@ -36790,14 +36822,14 @@ TUI exited with code ${code}
|
|
|
36790
36822
|
init_dist4();
|
|
36791
36823
|
init_src();
|
|
36792
36824
|
import { join as join10 } from "path";
|
|
36793
|
-
import { homedir as
|
|
36825
|
+
import { homedir as homedir6 } from "os";
|
|
36794
36826
|
|
|
36795
36827
|
// src/services/runtime/runtime-service.ts
|
|
36796
36828
|
init_src();
|
|
36797
|
-
import { existsSync as existsSync11 } from "fs";
|
|
36829
|
+
import { existsSync as existsSync11, lstatSync as lstatSync2, readlinkSync, rmSync } from "fs";
|
|
36798
36830
|
import { mkdir } from "fs/promises";
|
|
36799
36831
|
import { join as join9 } from "path";
|
|
36800
|
-
var
|
|
36832
|
+
var DEFAULT_HOOX_RUNTIME_REPO = "https://github.com/jango-blockchained/hoox.git";
|
|
36801
36833
|
function firstExisting(paths) {
|
|
36802
36834
|
for (const p3 of paths) {
|
|
36803
36835
|
if (existsSync11(p3))
|
|
@@ -36832,26 +36864,48 @@ async function runCommand(cmd, cwd) {
|
|
|
36832
36864
|
]);
|
|
36833
36865
|
return { ok: code === 0, stdout: stdout2, stderr };
|
|
36834
36866
|
}
|
|
36867
|
+
function isBrokenSymlink(path6) {
|
|
36868
|
+
try {
|
|
36869
|
+
if (!lstatSync2(path6).isSymbolicLink())
|
|
36870
|
+
return false;
|
|
36871
|
+
return !existsSync11(path6);
|
|
36872
|
+
} catch {
|
|
36873
|
+
return false;
|
|
36874
|
+
}
|
|
36875
|
+
}
|
|
36835
36876
|
async function ensureGlobalRuntime(options = {}) {
|
|
36836
36877
|
const log2 = options.onLog ?? (() => {});
|
|
36837
|
-
const repoUrl = options.repoUrl ??
|
|
36878
|
+
const repoUrl = options.repoUrl ?? DEFAULT_HOOX_RUNTIME_REPO;
|
|
36838
36879
|
const repoPath = getHooxRepoPath();
|
|
36839
36880
|
const hooxHome = getHooxHome();
|
|
36840
36881
|
await mkdir(hooxHome, { recursive: true });
|
|
36841
36882
|
let cloned = false;
|
|
36842
36883
|
if (!isHooxSetupRoot(repoPath)) {
|
|
36843
|
-
if (existsSync11(repoPath)) {
|
|
36844
|
-
|
|
36845
|
-
|
|
36846
|
-
|
|
36847
|
-
|
|
36848
|
-
|
|
36849
|
-
|
|
36850
|
-
|
|
36851
|
-
|
|
36884
|
+
if (existsSync11(repoPath) || isBrokenSymlink(repoPath)) {
|
|
36885
|
+
if (isBrokenSymlink(repoPath)) {
|
|
36886
|
+
let target = "";
|
|
36887
|
+
try {
|
|
36888
|
+
target = readlinkSync(repoPath);
|
|
36889
|
+
} catch {}
|
|
36890
|
+
log2(`Removing broken runtime symlink ${repoPath}` + (target ? ` \u2192 ${target}` : ""));
|
|
36891
|
+
rmSync(repoPath, { force: true });
|
|
36892
|
+
} else {
|
|
36893
|
+
throw new Error(`Path exists but is not a Hoox monorepo: ${repoPath}
|
|
36894
|
+
` + ` Expected wrangler.jsonc + packages/cli/package.json.
|
|
36895
|
+
` + ` Remove it or set HOOX_REPO to a valid checkout, then retry.
|
|
36896
|
+
` + ` Lightweight alternative: bun add -g @jango-blockchained/hoox-tui`);
|
|
36897
|
+
}
|
|
36898
|
+
}
|
|
36899
|
+
if (!isHooxSetupRoot(repoPath)) {
|
|
36900
|
+
log2(`Cloning ${repoUrl} \u2192 ${repoPath}`);
|
|
36901
|
+
const parent = hooxHome;
|
|
36902
|
+
const clone2 = await runCommand(["git", "clone", "--depth", "1", repoUrl, repoPath], parent);
|
|
36903
|
+
if (!clone2.ok) {
|
|
36904
|
+
throw new Error(`git clone failed:
|
|
36852
36905
|
${clone2.stderr || clone2.stdout}`.trim());
|
|
36906
|
+
}
|
|
36907
|
+
cloned = true;
|
|
36853
36908
|
}
|
|
36854
|
-
cloned = true;
|
|
36855
36909
|
} else {
|
|
36856
36910
|
log2(`Runtime already present: ${repoPath}`);
|
|
36857
36911
|
}
|
|
@@ -37146,7 +37200,7 @@ Hoox doctor
|
|
|
37146
37200
|
ok: status.isSetupRoot,
|
|
37147
37201
|
required: globalRequired,
|
|
37148
37202
|
label: "Global runtime (~/.hoox/repo)",
|
|
37149
|
-
detail: status.isSetupRoot ? "
|
|
37203
|
+
detail: status.isSetupRoot ? "monorepo markers present" : status.repoPresent ? "path exists but is not a setup monorepo" : runtime.root ? "optional (runtime resolved elsewhere)" : "missing \u2014 run: hoox doctor --fix-runtime"
|
|
37150
37204
|
},
|
|
37151
37205
|
{
|
|
37152
37206
|
ok: runtime.root !== null,
|
|
@@ -37179,7 +37233,8 @@ Hoox doctor
|
|
|
37179
37233
|
printSecurityHygieneSection();
|
|
37180
37234
|
if (failed > 0 || !status.isSetupRoot) {
|
|
37181
37235
|
process.stdout.write(theme.dim(`Tip: HOOX_HOME overrides ~/.hoox \xB7 HOOX_REPO forces the monorepo path
|
|
37182
|
-
` + `
|
|
37236
|
+
` + ` Lightweight TUI: bun add -g @jango-blockchained/hoox-tui
|
|
37237
|
+
` + ` Full runtime: hoox doctor --fix-runtime
|
|
37183
37238
|
` + ` Operator plane: hoox doctor --security
|
|
37184
37239
|
|
|
37185
37240
|
`));
|
|
@@ -37187,7 +37242,7 @@ Hoox doctor
|
|
|
37187
37242
|
return failed === 0 ? 0 /* SUCCESS */ : 1 /* ERROR */;
|
|
37188
37243
|
}
|
|
37189
37244
|
function printSecurityHygieneSection(env = process.env) {
|
|
37190
|
-
const configPath = join10(
|
|
37245
|
+
const configPath = join10(homedir6(), ".hoox", "config.json");
|
|
37191
37246
|
const lines = collectSecurityHygiene(env, { configPath });
|
|
37192
37247
|
process.stdout.write(theme.heading(`Security hygiene
|
|
37193
37248
|
`));
|
|
@@ -37205,7 +37260,7 @@ async function runSecurityDoctor(options) {
|
|
|
37205
37260
|
env.HOOX_API_URL = options.apiUrl;
|
|
37206
37261
|
}
|
|
37207
37262
|
const profile = resolveOperatorTransportProfile(env);
|
|
37208
|
-
const configPath = join10(
|
|
37263
|
+
const configPath = join10(homedir6(), ".hoox", "config.json");
|
|
37209
37264
|
const hygiene = collectSecurityHygiene(env, { configPath });
|
|
37210
37265
|
const isLocal = profile.apiBase.includes("localhost") || profile.apiBase.includes("127.0.0.1");
|
|
37211
37266
|
const shouldProbe = options.probe === true || options.probe !== false && !isLocal;
|
|
@@ -37272,18 +37327,21 @@ function registerDoctorCommand(program2) {
|
|
|
37272
37327
|
|
|
37273
37328
|
Resolution order for the tool/runtime root:
|
|
37274
37329
|
1. HOOX_REPO environment variable
|
|
37275
|
-
2. Walk up from the current directory for a hoox
|
|
37276
|
-
3. $HOME/.hoox/repo (managed global clone)
|
|
37330
|
+
2. Walk up from the current directory for a hoox monorepo checkout
|
|
37331
|
+
3. $HOME/.hoox/repo (managed global clone of github.com/jango-blockchained/hoox)
|
|
37332
|
+
|
|
37333
|
+
TUI (outside a monorepo) \u2014 preferred lightweight path:
|
|
37334
|
+
bun add -g @jango-blockchained/hoox-tui
|
|
37277
37335
|
|
|
37278
37336
|
SECURITY:
|
|
37279
37337
|
hoox doctor --security Hygiene + optional /v1/health probes (Access / Bearer)
|
|
37280
37338
|
|
|
37281
37339
|
EXAMPLES:
|
|
37282
37340
|
hoox doctor
|
|
37283
|
-
hoox doctor --fix-runtime Clone + bun install into ~/.hoox/repo
|
|
37341
|
+
hoox doctor --fix-runtime Clone monorepo + bun install into ~/.hoox/repo
|
|
37284
37342
|
hoox doctor --security
|
|
37285
37343
|
hoox doctor --security --api-url https://mgmt.example.com
|
|
37286
|
-
HOOX_REPO=~/Git/hoox
|
|
37344
|
+
HOOX_REPO=~/Git/hoox hoox doctor`).option("--fix-runtime", "Clone the Hoox monorepo into ~/.hoox/repo and install dependencies").option("--repo-url <url>", "Git URL used with --fix-runtime", undefined).option("--security", "Operator-plane security hygiene + optional management probes").option("--api-url <url>", "Management API base for --security probes (sets HOOX_API_URL for the check)").option("--probe", "Force /v1/health probes even for localhost").option("--no-probe", "Skip network probes with --security").action(withErrorHandling(async (options, cmd) => {
|
|
37287
37345
|
const fmt = getFormatOptions(cmd);
|
|
37288
37346
|
if (options.security) {
|
|
37289
37347
|
process.exitCode = await runSecurityDoctor({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jango-blockchained/hoox-cli",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"description": "Hoox CLI — manage Cloudflare Workers, infrastructure, secrets, and deployments (@jango-blockchained/hoox-cli)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -36,7 +36,8 @@
|
|
|
36
36
|
},
|
|
37
37
|
"repository": {
|
|
38
38
|
"type": "git",
|
|
39
|
-
"url": "git+https://github.com/jango-blockchained/hoox
|
|
39
|
+
"url": "git+https://github.com/jango-blockchained/hoox.git",
|
|
40
|
+
"directory": "packages/cli"
|
|
40
41
|
},
|
|
41
42
|
"keywords": [
|
|
42
43
|
"cloudflare",
|