create-hyper-hq 0.1.2 → 0.1.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/checks/check-claude-auth.d.ts +3 -0
- package/dist/checks/check-claude-auth.d.ts.map +1 -0
- package/dist/checks/check-claude-auth.js +22 -0
- package/dist/checks/check-claude-auth.js.map +1 -0
- package/dist/checks/check-tool.d.ts +14 -0
- package/dist/checks/check-tool.d.ts.map +1 -0
- package/dist/checks/check-tool.js +45 -0
- package/dist/checks/check-tool.js.map +1 -0
- package/dist/checks/detect-os.d.ts +8 -0
- package/dist/checks/detect-os.d.ts.map +1 -0
- package/dist/checks/detect-os.js +32 -0
- package/dist/checks/detect-os.js.map +1 -0
- package/dist/checks/detect-pm.d.ts +4 -0
- package/dist/checks/detect-pm.d.ts.map +1 -0
- package/dist/checks/detect-pm.js +20 -0
- package/dist/checks/detect-pm.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +273 -0
- package/dist/index.js.map +1 -0
- package/dist/install/install-options.d.ts +17 -0
- package/dist/install/install-options.d.ts.map +1 -0
- package/dist/install/install-options.js +120 -0
- package/dist/install/install-options.js.map +1 -0
- package/dist/install/run-install.d.ts +7 -0
- package/dist/install/run-install.d.ts.map +1 -0
- package/dist/install/run-install.js +30 -0
- package/dist/install/run-install.js.map +1 -0
- package/dist/setup/claude-md.d.ts +2 -0
- package/dist/setup/claude-md.d.ts.map +1 -0
- package/dist/setup/claude-md.js +59 -0
- package/dist/setup/claude-md.js.map +1 -0
- package/dist/setup/hq-config-wizard.d.ts +7 -0
- package/dist/setup/hq-config-wizard.d.ts.map +1 -0
- package/dist/setup/hq-config-wizard.js +119 -0
- package/dist/setup/hq-config-wizard.js.map +1 -0
- package/dist/setup/workspace-trust.d.ts +3 -0
- package/dist/setup/workspace-trust.d.ts.map +1 -0
- package/dist/setup/workspace-trust.js +14 -0
- package/dist/setup/workspace-trust.js.map +1 -0
- package/dist/ui/prompts.d.ts +10 -0
- package/dist/ui/prompts.d.ts.map +1 -0
- package/dist/ui/prompts.js +75 -0
- package/dist/ui/prompts.js.map +1 -0
- package/package.json +5 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-claude-auth.d.ts","sourceRoot":"","sources":["../../src/checks/check-claude-auth.ts"],"names":[],"mappings":"AAEA,wBAAgB,qBAAqB,IAAI,OAAO,CAM/C;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAcvD"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
2
|
+
export function isClaudeAuthenticated() {
|
|
3
|
+
const result = spawnSync("claude", ["auth", "status"], {
|
|
4
|
+
encoding: "utf-8",
|
|
5
|
+
timeout: 10000,
|
|
6
|
+
});
|
|
7
|
+
return result.status === 0;
|
|
8
|
+
}
|
|
9
|
+
export async function runClaudeLogin() {
|
|
10
|
+
return new Promise((resolve) => {
|
|
11
|
+
const child = spawn("claude", ["auth", "login"], {
|
|
12
|
+
stdio: "inherit",
|
|
13
|
+
});
|
|
14
|
+
child.on("close", (code) => {
|
|
15
|
+
resolve(code === 0);
|
|
16
|
+
});
|
|
17
|
+
child.on("error", () => {
|
|
18
|
+
resolve(false);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=check-claude-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-claude-auth.js","sourceRoot":"","sources":["../../src/checks/check-claude-auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEtD,MAAM,UAAU,qBAAqB;IACpC,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE;QACtD,QAAQ,EAAE,OAAO;QACjB,OAAO,EAAE,KAAK;KACd,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc;IACnC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC9B,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;YAChD,KAAK,EAAE,SAAS;SAChB,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YAC1B,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC;QACrB,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACtB,OAAO,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare function isToolInstalled(name: string): boolean;
|
|
2
|
+
export declare function getToolVersion(name: string): string | null;
|
|
3
|
+
/**
|
|
4
|
+
* Extract a semver string (x.y.z) from arbitrary version output.
|
|
5
|
+
* Returns null if no semver is found.
|
|
6
|
+
*/
|
|
7
|
+
export declare function parseSemver(output: string): string | null;
|
|
8
|
+
/**
|
|
9
|
+
* Fetch the latest published version of an npm package.
|
|
10
|
+
* Uses `npm view` directly — npm is always available when invoked via `npm create`.
|
|
11
|
+
* Returns null on failure.
|
|
12
|
+
*/
|
|
13
|
+
export declare function getLatestNpmVersion(packageName: string): string | null;
|
|
14
|
+
//# sourceMappingURL=check-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-tool.d.ts","sourceRoot":"","sources":["../../src/checks/check-tool.ts"],"names":[],"mappings":"AAMA,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOrD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ1D;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGzD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOtE"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
function getLoginShell() {
|
|
3
|
+
return process.env["SHELL"] ?? "/bin/bash";
|
|
4
|
+
}
|
|
5
|
+
export function isToolInstalled(name) {
|
|
6
|
+
const shell = getLoginShell();
|
|
7
|
+
const result = spawnSync(shell, ["-l", "-c", `which ${name}`], {
|
|
8
|
+
encoding: "utf-8",
|
|
9
|
+
timeout: 5000,
|
|
10
|
+
});
|
|
11
|
+
return result.status === 0;
|
|
12
|
+
}
|
|
13
|
+
export function getToolVersion(name) {
|
|
14
|
+
const shell = getLoginShell();
|
|
15
|
+
const result = spawnSync(shell, ["-l", "-c", `${name} --version`], {
|
|
16
|
+
encoding: "utf-8",
|
|
17
|
+
timeout: 5000,
|
|
18
|
+
});
|
|
19
|
+
if (result.status !== 0)
|
|
20
|
+
return null;
|
|
21
|
+
return result.stdout.trim() || null;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Extract a semver string (x.y.z) from arbitrary version output.
|
|
25
|
+
* Returns null if no semver is found.
|
|
26
|
+
*/
|
|
27
|
+
export function parseSemver(output) {
|
|
28
|
+
const match = output.match(/(\d+\.\d+\.\d+)/);
|
|
29
|
+
return match ? (match[1] ?? null) : null;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Fetch the latest published version of an npm package.
|
|
33
|
+
* Uses `npm view` directly — npm is always available when invoked via `npm create`.
|
|
34
|
+
* Returns null on failure.
|
|
35
|
+
*/
|
|
36
|
+
export function getLatestNpmVersion(packageName) {
|
|
37
|
+
const result = spawnSync("npm", ["view", packageName, "version"], {
|
|
38
|
+
encoding: "utf-8",
|
|
39
|
+
timeout: 10000,
|
|
40
|
+
});
|
|
41
|
+
if (result.status !== 0)
|
|
42
|
+
return null;
|
|
43
|
+
return result.stdout.trim() || null;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=check-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-tool.js","sourceRoot":"","sources":["../../src/checks/check-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,SAAS,aAAa;IACrB,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,WAAW,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY;IAC3C,MAAM,KAAK,GAAG,aAAa,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,IAAI,EAAE,CAAC,EAAE;QAC9D,QAAQ,EAAE,OAAO;QACjB,OAAO,EAAE,IAAI;KACb,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY;IAC1C,MAAM,KAAK,GAAG,aAAa,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,YAAY,CAAC,EAAE;QAClE,QAAQ,EAAE,OAAO;QACjB,OAAO,EAAE,IAAI;KACb,CAAC,CAAC;IACH,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,MAAc;IACzC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAC9C,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,WAAmB;IACtD,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE;QACjE,QAAQ,EAAE,OAAO;QACjB,OAAO,EAAE,KAAK;KACd,CAAC,CAAC;IACH,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;AACrC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface PlatformInfo {
|
|
2
|
+
os: "macos" | "linux" | "windows";
|
|
3
|
+
distroId: string | null;
|
|
4
|
+
isRoot: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare function detectPlatform(): PlatformInfo;
|
|
7
|
+
export declare function detectSystemPms(): string[];
|
|
8
|
+
//# sourceMappingURL=detect-os.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-os.d.ts","sourceRoot":"","sources":["../../src/checks/detect-os.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC5B,EAAE,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;IAClC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,OAAO,CAAC;CAChB;AAYD,wBAAgB,cAAc,IAAI,YAAY,CAa7C;AASD,wBAAgB,eAAe,IAAI,MAAM,EAAE,CAE1C"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
function getLinuxDistroId() {
|
|
4
|
+
try {
|
|
5
|
+
const osRelease = readFileSync("/etc/os-release", "utf-8");
|
|
6
|
+
const match = osRelease.match(/^ID=(.+)$/m);
|
|
7
|
+
return match?.[1]?.replace(/"/g, "") ?? null;
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export function detectPlatform() {
|
|
14
|
+
const platform = process.platform;
|
|
15
|
+
const isRoot = process.getuid?.() === 0;
|
|
16
|
+
if (platform === "darwin") {
|
|
17
|
+
return { os: "macos", distroId: null, isRoot };
|
|
18
|
+
}
|
|
19
|
+
if (platform === "linux") {
|
|
20
|
+
return { os: "linux", distroId: getLinuxDistroId(), isRoot };
|
|
21
|
+
}
|
|
22
|
+
return { os: "windows", distroId: null, isRoot };
|
|
23
|
+
}
|
|
24
|
+
const SYSTEM_PMS = ["brew", "apt", "dnf", "pacman", "apk", "zypper", "port", "conda"];
|
|
25
|
+
function isOnPath(name) {
|
|
26
|
+
const result = spawnSync("which", [name], { encoding: "utf-8", timeout: 3000 });
|
|
27
|
+
return result.status === 0;
|
|
28
|
+
}
|
|
29
|
+
export function detectSystemPms() {
|
|
30
|
+
return SYSTEM_PMS.filter(isOnPath);
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=detect-os.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-os.js","sourceRoot":"","sources":["../../src/checks/detect-os.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAQvC,SAAS,gBAAgB;IACxB,IAAI,CAAC;QACJ,MAAM,SAAS,GAAG,YAAY,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;QAC3D,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAC5C,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC;AAED,MAAM,UAAU,cAAc;IAC7B,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,KAAK,CAAC,CAAC;IAExC,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC3B,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAChD,CAAC;IAED,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QAC1B,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,EAAE,MAAM,EAAE,CAAC;IAC9D,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AAEtF,SAAS,QAAQ,CAAC,IAAY;IAC7B,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAChF,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,eAAe;IAC9B,OAAO,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-pm.d.ts","sourceRoot":"","sources":["../../src/checks/detect-pm.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AAErD,wBAAgB,eAAe,IAAI,MAAM,CAMxC;AASD,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,CAEjD"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
export function detectCallingPm() {
|
|
3
|
+
const userAgent = process.env["npm_config_user_agent"] ?? "";
|
|
4
|
+
if (userAgent.startsWith("bun"))
|
|
5
|
+
return "bun";
|
|
6
|
+
if (userAgent.startsWith("pnpm"))
|
|
7
|
+
return "pnpm";
|
|
8
|
+
if (userAgent.startsWith("yarn"))
|
|
9
|
+
return "yarn";
|
|
10
|
+
return "npm";
|
|
11
|
+
}
|
|
12
|
+
const NODE_PMS = ["npm", "bun", "pnpm", "yarn"];
|
|
13
|
+
function isOnPath(name) {
|
|
14
|
+
const result = spawnSync("which", [name], { encoding: "utf-8", timeout: 3000 });
|
|
15
|
+
return result.status === 0;
|
|
16
|
+
}
|
|
17
|
+
export function detectAvailableNodePms() {
|
|
18
|
+
return NODE_PMS.filter(isOnPath);
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=detect-pm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-pm.js","sourceRoot":"","sources":["../../src/checks/detect-pm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAI/C,MAAM,UAAU,eAAe;IAC9B,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,IAAI,EAAE,CAAC;IAC7D,IAAI,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9C,IAAI,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IAChD,IAAI,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IAChD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,MAAM,QAAQ,GAAa,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAE1D,SAAS,QAAQ,CAAC,IAAY;IAC7B,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAChF,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,sBAAsB;IACrC,OAAO,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AAClC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
3
|
+
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
4
|
+
import * as p from "@clack/prompts";
|
|
5
|
+
import pc from "picocolors";
|
|
6
|
+
import { isClaudeAuthenticated, runClaudeLogin } from "./checks/check-claude-auth.js";
|
|
7
|
+
import { getLatestNpmVersion, getToolVersion, isToolInstalled, parseSemver, } from "./checks/check-tool.js";
|
|
8
|
+
import { detectPlatform, detectSystemPms } from "./checks/detect-os.js";
|
|
9
|
+
import { detectAvailableNodePms, detectCallingPm } from "./checks/detect-pm.js";
|
|
10
|
+
import { getInstallOptions } from "./install/install-options.js";
|
|
11
|
+
import { generateHqClaudeMd } from "./setup/claude-md.js";
|
|
12
|
+
import { runConfigWizard } from "./setup/hq-config-wizard.js";
|
|
13
|
+
import { isWorkspaceTrusted, trustWorkspace } from "./setup/workspace-trust.js";
|
|
14
|
+
import { installOrWaitLoop } from "./ui/prompts.js";
|
|
15
|
+
function phase(step, total, title) {
|
|
16
|
+
p.log.step(pc.bold(`${step} of ${total}: ${title}`));
|
|
17
|
+
}
|
|
18
|
+
async function checkAndUpdateTool(name, npmPackage, callingPm) {
|
|
19
|
+
const rawVersion = getToolVersion(name);
|
|
20
|
+
const installed = rawVersion ? parseSemver(rawVersion) : null;
|
|
21
|
+
const latest = getLatestNpmVersion(npmPackage);
|
|
22
|
+
if (installed && latest && installed !== latest) {
|
|
23
|
+
p.log.warn(`${name} is installed (v${installed}), but v${latest} is available.`);
|
|
24
|
+
if (name === "claude") {
|
|
25
|
+
p.log.info(" Note: if you installed via the native installer (curl), it auto-updates.");
|
|
26
|
+
}
|
|
27
|
+
const updateChoice = await p.select({
|
|
28
|
+
message: "Would you like to update?",
|
|
29
|
+
options: name === "claude"
|
|
30
|
+
? [
|
|
31
|
+
{
|
|
32
|
+
label: `Yes, update via npm (npm install -g ${npmPackage})`,
|
|
33
|
+
value: "npm",
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
label: "Yes, update via brew (brew upgrade claude-code)",
|
|
37
|
+
value: "brew",
|
|
38
|
+
},
|
|
39
|
+
{ label: "No, continue with current version", value: "skip" },
|
|
40
|
+
{ label: "Cancel", value: "cancel" },
|
|
41
|
+
]
|
|
42
|
+
: [
|
|
43
|
+
{
|
|
44
|
+
label: `Yes, update now (${callingPm} install -g ${npmPackage})`,
|
|
45
|
+
value: "update",
|
|
46
|
+
},
|
|
47
|
+
{ label: "No, continue with current version", value: "skip" },
|
|
48
|
+
{ label: "Cancel", value: "cancel" },
|
|
49
|
+
],
|
|
50
|
+
});
|
|
51
|
+
if (p.isCancel(updateChoice) || updateChoice === "cancel") {
|
|
52
|
+
p.cancel("Setup cancelled.");
|
|
53
|
+
process.exit(0);
|
|
54
|
+
}
|
|
55
|
+
if (updateChoice === "skip") {
|
|
56
|
+
p.log.info(`Continuing with ${name} v${installed}.`);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
let cmd;
|
|
60
|
+
let args;
|
|
61
|
+
if (updateChoice === "brew") {
|
|
62
|
+
cmd = "brew";
|
|
63
|
+
args = ["upgrade", "claude-code"];
|
|
64
|
+
}
|
|
65
|
+
else if (updateChoice === "npm") {
|
|
66
|
+
cmd = "npm";
|
|
67
|
+
args = ["install", "-g", npmPackage];
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
cmd = callingPm;
|
|
71
|
+
args = callingPm === "yarn" ? ["global", "add", npmPackage] : ["install", "-g", npmPackage];
|
|
72
|
+
}
|
|
73
|
+
const result = spawnSync(cmd, args, { stdio: "inherit", encoding: "utf-8" });
|
|
74
|
+
if (result.status === 0) {
|
|
75
|
+
p.log.success(`${name} updated to v${latest}`);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
p.log.warn("Update failed. Continuing with the installed version.");
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
const v = installed ? ` (v${installed})` : "";
|
|
83
|
+
p.log.success(`${name} is installed${v}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
async function main() {
|
|
87
|
+
const TOTAL_PHASES = 3;
|
|
88
|
+
// ─── Welcome ───
|
|
89
|
+
p.intro(pc.bold("create-hyper-hq"));
|
|
90
|
+
p.note("HQ is an always-on Claude Code command center that runs in a\n" +
|
|
91
|
+
"tmux session. Once started, you can control it from claude.ai,\n" +
|
|
92
|
+
"the Claude mobile app, or Telegram.\n\n" +
|
|
93
|
+
"We'll get you set up in 3 quick steps.", "Welcome to Hyper HQ!");
|
|
94
|
+
// ─── Phase 1: Dependency checks ───
|
|
95
|
+
phase(1, TOTAL_PHASES, "Making sure you have the essentials");
|
|
96
|
+
const platform = detectPlatform();
|
|
97
|
+
const systemPms = detectSystemPms();
|
|
98
|
+
const callingPm = detectCallingPm();
|
|
99
|
+
const availableNodePms = detectAvailableNodePms();
|
|
100
|
+
const installContext = {
|
|
101
|
+
callingPm,
|
|
102
|
+
availableNodePms,
|
|
103
|
+
systemPms,
|
|
104
|
+
os: platform.os,
|
|
105
|
+
isRoot: platform.isRoot,
|
|
106
|
+
};
|
|
107
|
+
// Check hyper CLI
|
|
108
|
+
p.log.message(` ${pc.dim("hyper CLI")}`);
|
|
109
|
+
if (!isToolInstalled("hyper")) {
|
|
110
|
+
await installOrWaitLoop({
|
|
111
|
+
toolName: "hyper",
|
|
112
|
+
toolUrl: "https://hyperdev.saulo.engineer/cli/install",
|
|
113
|
+
description: "The hyper CLI is the main command-line tool for HyperDev.",
|
|
114
|
+
options: getInstallOptions("hyper", installContext),
|
|
115
|
+
checkFn: () => isToolInstalled("hyper"),
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
await checkAndUpdateTool("hyper", "@hypercli/cli", callingPm);
|
|
120
|
+
}
|
|
121
|
+
// Check Claude CLI
|
|
122
|
+
p.log.message(` ${pc.dim("Claude Code CLI")}`);
|
|
123
|
+
if (!isToolInstalled("claude")) {
|
|
124
|
+
await installOrWaitLoop({
|
|
125
|
+
toolName: "claude",
|
|
126
|
+
toolUrl: "https://claude.ai/code",
|
|
127
|
+
description: "Claude Code is the AI coding assistant that powers HQ sessions.",
|
|
128
|
+
options: getInstallOptions("claude", installContext),
|
|
129
|
+
checkFn: () => isToolInstalled("claude"),
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
await checkAndUpdateTool("claude", "@anthropic-ai/claude-code", callingPm);
|
|
134
|
+
}
|
|
135
|
+
// Check tmux
|
|
136
|
+
p.log.message(` ${pc.dim("tmux")}`);
|
|
137
|
+
if (platform.os === "windows") {
|
|
138
|
+
p.log.warn("tmux is not available natively on Windows.");
|
|
139
|
+
p.note("tmux requires a Linux environment. HQ works inside WSL\n" +
|
|
140
|
+
"(Windows Subsystem for Linux).\n\n" +
|
|
141
|
+
"If you're running this from Windows directly, install WSL first:\n" +
|
|
142
|
+
pc.cyan("https://learn.microsoft.com/windows/wsl/install") +
|
|
143
|
+
"\nThen re-run this setup from inside WSL.");
|
|
144
|
+
const wslChoice = await p.select({
|
|
145
|
+
message: "What would you like to do?",
|
|
146
|
+
options: [
|
|
147
|
+
{ label: "I'm in WSL, continue", value: "wsl" },
|
|
148
|
+
{ label: "Cancel", value: "cancel" },
|
|
149
|
+
],
|
|
150
|
+
});
|
|
151
|
+
if (p.isCancel(wslChoice) || wslChoice === "cancel") {
|
|
152
|
+
p.cancel("Setup cancelled.");
|
|
153
|
+
process.exit(0);
|
|
154
|
+
}
|
|
155
|
+
if (!isToolInstalled("tmux")) {
|
|
156
|
+
await installOrWaitLoop({
|
|
157
|
+
toolName: "tmux",
|
|
158
|
+
toolUrl: "https://github.com/tmux/tmux",
|
|
159
|
+
description: "tmux keeps HQ sessions running in the background,\neven after you close your terminal.",
|
|
160
|
+
options: getInstallOptions("tmux", { ...installContext, os: "linux" }),
|
|
161
|
+
checkFn: () => isToolInstalled("tmux"),
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
else if (!isToolInstalled("tmux")) {
|
|
166
|
+
await installOrWaitLoop({
|
|
167
|
+
toolName: "tmux",
|
|
168
|
+
toolUrl: "https://github.com/tmux/tmux",
|
|
169
|
+
description: "tmux keeps HQ sessions running in the background,\neven after you close your terminal.",
|
|
170
|
+
options: getInstallOptions("tmux", installContext),
|
|
171
|
+
checkFn: () => isToolInstalled("tmux"),
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
p.log.success("tmux is installed");
|
|
176
|
+
}
|
|
177
|
+
// Check Claude auth
|
|
178
|
+
p.log.message(` ${pc.dim("Claude authentication")}`);
|
|
179
|
+
if (!isClaudeAuthenticated()) {
|
|
180
|
+
p.log.warn("Not authenticated with Claude yet.");
|
|
181
|
+
p.log.step("Opening Claude login...");
|
|
182
|
+
const authSuccess = await runClaudeLogin();
|
|
183
|
+
if (!authSuccess) {
|
|
184
|
+
const retryOrSkip = await p.select({
|
|
185
|
+
message: "Auth didn't go through. What now?",
|
|
186
|
+
options: [
|
|
187
|
+
{ label: "Try again", value: "retry" },
|
|
188
|
+
{ label: "Skip for now (HQ won't work without auth)", value: "skip" },
|
|
189
|
+
{ label: "Cancel", value: "cancel" },
|
|
190
|
+
],
|
|
191
|
+
});
|
|
192
|
+
if (p.isCancel(retryOrSkip) || retryOrSkip === "cancel") {
|
|
193
|
+
p.cancel("Setup cancelled.");
|
|
194
|
+
process.exit(0);
|
|
195
|
+
}
|
|
196
|
+
if (retryOrSkip === "retry") {
|
|
197
|
+
const retrySuccess = await runClaudeLogin();
|
|
198
|
+
if (retrySuccess) {
|
|
199
|
+
p.log.success("Authenticated with Claude");
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
p.log.warn("Still no luck. You can run `claude auth login` later.");
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
p.log.warn("Skipping auth — remember to run `claude auth login` before starting HQ.");
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
p.log.success("Authenticated with Claude");
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
p.log.success("Claude is authenticated");
|
|
215
|
+
}
|
|
216
|
+
// ─── Phase 2: Configuration ───
|
|
217
|
+
phase(2, TOTAL_PHASES, "Pick your settings");
|
|
218
|
+
const config = await runConfigWizard();
|
|
219
|
+
// ─── Phase 3: Finishing touches ───
|
|
220
|
+
phase(3, TOTAL_PHASES, "Setting everything up");
|
|
221
|
+
// Trust workspaces
|
|
222
|
+
for (const dir of [config.hqDir, config.projectsRoot]) {
|
|
223
|
+
if (!isWorkspaceTrusted(dir)) {
|
|
224
|
+
trustWorkspace(dir);
|
|
225
|
+
p.log.success(`Trusted ${dir}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
// Generate CLAUDE.md
|
|
229
|
+
const claudeMdPath = `${config.hqDir}/CLAUDE.md`;
|
|
230
|
+
if (!existsSync(config.hqDir)) {
|
|
231
|
+
mkdirSync(config.hqDir, { recursive: true });
|
|
232
|
+
}
|
|
233
|
+
writeFileSync(claudeMdPath, generateHqClaudeMd(config.projectsRoot), "utf-8");
|
|
234
|
+
p.log.success(`Created ${claudeMdPath}`);
|
|
235
|
+
// ─── Done! ───
|
|
236
|
+
p.log.success(pc.green(pc.bold("All set! HQ is ready to go.")));
|
|
237
|
+
const startNow = await p.select({
|
|
238
|
+
message: "Start HQ now?",
|
|
239
|
+
options: [
|
|
240
|
+
{ label: "Yes, let's go!", value: "yes" },
|
|
241
|
+
{ label: "Not right now", value: "no" },
|
|
242
|
+
],
|
|
243
|
+
});
|
|
244
|
+
if (p.isCancel(startNow)) {
|
|
245
|
+
p.cancel("Setup cancelled.");
|
|
246
|
+
process.exit(0);
|
|
247
|
+
}
|
|
248
|
+
p.log.message(` You can always run ${pc.cyan("hyper hq start")} to launch HQ.`);
|
|
249
|
+
if (startNow === "yes") {
|
|
250
|
+
p.log.step("Starting HQ...");
|
|
251
|
+
const child = spawn("hyper", ["hq", "start"], {
|
|
252
|
+
stdio: "inherit",
|
|
253
|
+
detached: false,
|
|
254
|
+
});
|
|
255
|
+
await new Promise((resolve) => {
|
|
256
|
+
child.on("close", () => resolve());
|
|
257
|
+
child.on("error", (err) => {
|
|
258
|
+
p.log.error(`Failed to start HQ: ${err.message}`);
|
|
259
|
+
resolve();
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
p.outro(pc.green("Hyper HQ setup complete!"));
|
|
264
|
+
}
|
|
265
|
+
main().catch((err) => {
|
|
266
|
+
if (err instanceof Error && err.message === "User force closed the prompt with CTRL+C") {
|
|
267
|
+
process.stdout.write("\nSetup cancelled.\n");
|
|
268
|
+
process.exit(0);
|
|
269
|
+
}
|
|
270
|
+
console.error(err);
|
|
271
|
+
process.exit(1);
|
|
272
|
+
});
|
|
273
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface InstallOption {
|
|
2
|
+
label: string;
|
|
3
|
+
value: string;
|
|
4
|
+
command?: string;
|
|
5
|
+
args?: string[];
|
|
6
|
+
sudo?: boolean;
|
|
7
|
+
hint?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface InstallContext {
|
|
10
|
+
callingPm: string;
|
|
11
|
+
availableNodePms: string[];
|
|
12
|
+
systemPms: string[];
|
|
13
|
+
os: "macos" | "linux" | "windows";
|
|
14
|
+
isRoot: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare function getInstallOptions(tool: "hyper" | "claude" | "tmux", context: InstallContext): InstallOption[];
|
|
17
|
+
//# sourceMappingURL=install-options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-options.d.ts","sourceRoot":"","sources":["../../src/install/install-options.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,EAAE,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;IAClC,MAAM,EAAE,OAAO,CAAC;CAChB;AAwBD,wBAAgB,iBAAiB,CAChC,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,EACjC,OAAO,EAAE,cAAc,GACrB,aAAa,EAAE,CAwGjB"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
const MANUAL_OPTION = {
|
|
2
|
+
label: "I'll install it myself and let you know",
|
|
3
|
+
value: "manual",
|
|
4
|
+
};
|
|
5
|
+
const CANCEL_OPTION = {
|
|
6
|
+
label: "Cancel",
|
|
7
|
+
value: "cancel",
|
|
8
|
+
};
|
|
9
|
+
function nodePmInstallOption(pm, pkg) {
|
|
10
|
+
const installArg = pm === "yarn" ? "global add" : "install -g";
|
|
11
|
+
const args = [...installArg.split(" "), pkg];
|
|
12
|
+
return {
|
|
13
|
+
label: `${pm} ${installArg} ${pkg}`,
|
|
14
|
+
value: pm,
|
|
15
|
+
command: pm,
|
|
16
|
+
args,
|
|
17
|
+
sudo: false,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export function getInstallOptions(tool, context) {
|
|
21
|
+
const { callingPm, availableNodePms, systemPms, os, isRoot } = context;
|
|
22
|
+
const options = [];
|
|
23
|
+
if (tool === "hyper") {
|
|
24
|
+
// Calling PM first, then others
|
|
25
|
+
const pmsOrdered = [callingPm, ...availableNodePms.filter((pm) => pm !== callingPm)];
|
|
26
|
+
for (const pm of pmsOrdered) {
|
|
27
|
+
options.push(nodePmInstallOption(pm, "@hypercli/cli"));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
else if (tool === "claude") {
|
|
31
|
+
// Native installer first (recommended)
|
|
32
|
+
if (os !== "windows") {
|
|
33
|
+
options.push({
|
|
34
|
+
label: "curl -fsSL https://claude.ai/install.sh | bash (recommended, auto-updates)",
|
|
35
|
+
value: "native",
|
|
36
|
+
command: "bash",
|
|
37
|
+
args: ["-c", "curl -fsSL https://claude.ai/install.sh | bash"],
|
|
38
|
+
sudo: false,
|
|
39
|
+
hint: "recommended, auto-updates",
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
// Brew cask if available
|
|
43
|
+
if (systemPms.includes("brew")) {
|
|
44
|
+
options.push({
|
|
45
|
+
label: "brew install --cask claude-code",
|
|
46
|
+
value: "brew",
|
|
47
|
+
command: "brew",
|
|
48
|
+
args: ["install", "--cask", "claude-code"],
|
|
49
|
+
sudo: false,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
// npm (deprecated)
|
|
53
|
+
if (availableNodePms.includes("npm")) {
|
|
54
|
+
options.push({
|
|
55
|
+
label: "npm install -g @anthropic-ai/claude-code (deprecated)",
|
|
56
|
+
value: "npm",
|
|
57
|
+
command: "npm",
|
|
58
|
+
args: ["install", "-g", "@anthropic-ai/claude-code"],
|
|
59
|
+
sudo: false,
|
|
60
|
+
hint: "deprecated",
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else if (tool === "tmux") {
|
|
65
|
+
if (os === "macos") {
|
|
66
|
+
if (systemPms.includes("brew")) {
|
|
67
|
+
options.push({
|
|
68
|
+
label: "brew install tmux",
|
|
69
|
+
value: "brew",
|
|
70
|
+
command: "brew",
|
|
71
|
+
args: ["install", "tmux"],
|
|
72
|
+
sudo: false,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
if (systemPms.includes("port")) {
|
|
76
|
+
options.push({
|
|
77
|
+
label: isRoot ? "port install tmux" : "sudo port install tmux",
|
|
78
|
+
value: "port",
|
|
79
|
+
command: isRoot ? "port" : "sudo",
|
|
80
|
+
args: isRoot ? ["install", "tmux"] : ["port", "install", "tmux"],
|
|
81
|
+
sudo: !isRoot,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else if (os === "linux") {
|
|
86
|
+
const linuxPmOptions = [
|
|
87
|
+
{ pm: "apt", cmd: "apt", args: ["install", "-y", "tmux"] },
|
|
88
|
+
{ pm: "dnf", cmd: "dnf", args: ["install", "-y", "tmux"] },
|
|
89
|
+
{ pm: "pacman", cmd: "pacman", args: ["-S", "--noconfirm", "tmux"] },
|
|
90
|
+
{ pm: "apk", cmd: "apk", args: ["add", "tmux"] },
|
|
91
|
+
{ pm: "zypper", cmd: "zypper", args: ["install", "-y", "tmux"] },
|
|
92
|
+
];
|
|
93
|
+
for (const { pm, cmd, args } of linuxPmOptions) {
|
|
94
|
+
if (systemPms.includes(pm)) {
|
|
95
|
+
const needsSudo = !isRoot;
|
|
96
|
+
options.push({
|
|
97
|
+
label: needsSudo ? `sudo ${cmd} ${args.join(" ")}` : `${cmd} ${args.join(" ")}`,
|
|
98
|
+
value: pm,
|
|
99
|
+
command: needsSudo ? "sudo" : cmd,
|
|
100
|
+
args: needsSudo ? [cmd, ...args] : args,
|
|
101
|
+
sudo: needsSudo,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// conda available on any OS
|
|
107
|
+
if (systemPms.includes("conda")) {
|
|
108
|
+
options.push({
|
|
109
|
+
label: "conda install -c conda-forge tmux",
|
|
110
|
+
value: "conda",
|
|
111
|
+
command: "conda",
|
|
112
|
+
args: ["install", "-c", "conda-forge", "tmux"],
|
|
113
|
+
sudo: false,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
options.push(MANUAL_OPTION, CANCEL_OPTION);
|
|
118
|
+
return options;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=install-options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-options.js","sourceRoot":"","sources":["../../src/install/install-options.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-install.d.ts","sourceRoot":"","sources":["../../src/install/run-install.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,CA8BtE"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
export function runInstallCommand(option) {
|
|
3
|
+
if (!option.command || !option.args) {
|
|
4
|
+
return { success: false, error: "No command specified for this install option." };
|
|
5
|
+
}
|
|
6
|
+
try {
|
|
7
|
+
const result = spawnSync(option.command, option.args, {
|
|
8
|
+
stdio: "inherit",
|
|
9
|
+
encoding: "utf-8",
|
|
10
|
+
});
|
|
11
|
+
if (result.error) {
|
|
12
|
+
return { success: false, error: result.error.message };
|
|
13
|
+
}
|
|
14
|
+
if (result.status !== 0) {
|
|
15
|
+
const stderr = typeof result.stderr === "string" ? result.stderr.trim() : "";
|
|
16
|
+
return {
|
|
17
|
+
success: false,
|
|
18
|
+
error: stderr || `Command exited with code ${result.status}`,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
return { success: true };
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
return {
|
|
25
|
+
success: false,
|
|
26
|
+
error: err instanceof Error ? err.message : String(err),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=run-install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-install.js","sourceRoot":"","sources":["../../src/install/run-install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAQ/C,MAAM,UAAU,iBAAiB,CAAC,MAAqB;IACtD,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACrC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,+CAA+C,EAAE,CAAC;IACnF,CAAC;IAED,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE;YACrD,KAAK,EAAE,SAAS;YAChB,QAAQ,EAAE,OAAO;SACjB,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAClB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACxD,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7E,OAAO;gBACN,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,MAAM,IAAI,4BAA4B,MAAM,CAAC,MAAM,EAAE;aAC5D,CAAC;QACH,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC1B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,OAAO;YACN,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACvD,CAAC;IACH,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-md.d.ts","sourceRoot":"","sources":["../../src/setup/claude-md.ts"],"names":[],"mappings":"AAAA,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAyD/D"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export function generateHqClaudeMd(projectsRoot) {
|
|
2
|
+
return `# Hyper HQ — Claude Code Command Center
|
|
3
|
+
|
|
4
|
+
You are **Hyper HQ**, an always-running Claude Code instance that serves as a command center.
|
|
5
|
+
Calm, decisive, and always in control.
|
|
6
|
+
|
|
7
|
+
## Your Role
|
|
8
|
+
|
|
9
|
+
You are a persistent Claude Code session running in remote-control server mode.
|
|
10
|
+
Users connect to you from claude.ai/code, mobile apps, or via Telegram.
|
|
11
|
+
|
|
12
|
+
## On Startup
|
|
13
|
+
|
|
14
|
+
When this session first starts, immediately:
|
|
15
|
+
1. If Telegram is available, use the \`reply\` tool to send: "Hyper HQ is online. Ready for orders."
|
|
16
|
+
2. Run \`hyper hq list --json\` to get the current project inventory.
|
|
17
|
+
|
|
18
|
+
## Capabilities
|
|
19
|
+
|
|
20
|
+
1. **Spawn new Claude sessions** for any project using the \`hyper hq\` CLI
|
|
21
|
+
2. **Receive and act on messages** via Telegram (if configured)
|
|
22
|
+
3. **Manage running sessions** — start, stop, check status
|
|
23
|
+
4. **Coordinate work** across multiple projects
|
|
24
|
+
|
|
25
|
+
## Key Commands
|
|
26
|
+
|
|
27
|
+
\`\`\`bash
|
|
28
|
+
hyper hq spawn <project> # Spawn session for a project
|
|
29
|
+
hyper hq spawn <project> --worktree <branch> # Spawn on existing worktree
|
|
30
|
+
hyper hq spawn <project> --new-worktree <branch> # Create worktree + spawn
|
|
31
|
+
hyper hq status # Check all running sessions
|
|
32
|
+
hyper hq stop <project> # Stop a session
|
|
33
|
+
hyper hq stop-all # Stop everything
|
|
34
|
+
hyper hq list # List all projects and worktrees
|
|
35
|
+
hyper hq list --json # JSON output for parsing
|
|
36
|
+
hyper hq config # Show current configuration
|
|
37
|
+
\`\`\`
|
|
38
|
+
|
|
39
|
+
## Handling Requests
|
|
40
|
+
|
|
41
|
+
When a user asks to open/start/spawn a session:
|
|
42
|
+
|
|
43
|
+
1. Parse the request for: **project name** and optionally **worktree** (existing or new)
|
|
44
|
+
2. Run \`hyper hq list --json\` to verify the project exists
|
|
45
|
+
3. Run the appropriate spawn command
|
|
46
|
+
4. Reply with confirmation, session name, and remind them to check **claude.ai/code**
|
|
47
|
+
|
|
48
|
+
## Important Notes
|
|
49
|
+
|
|
50
|
+
- Projects root: ${projectsRoot}
|
|
51
|
+
- Logs: ~/.config/hyper/logs/
|
|
52
|
+
- The \`wt\` (worktrunk) command manages worktrees
|
|
53
|
+
- Config: ~/.config/hyper/hq.toml
|
|
54
|
+
|
|
55
|
+
## Package Management
|
|
56
|
+
- Use bun, never npm
|
|
57
|
+
`;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=claude-md.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-md.js","sourceRoot":"","sources":["../../src/setup/claude-md.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,kBAAkB,CAAC,YAAoB;IACtD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAgDW,YAAY;;;;;;;CAO9B,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hq-config-wizard.d.ts","sourceRoot":"","sources":["../../src/setup/hq-config-wizard.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,cAAc;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AASD,wBAAsB,eAAe,IAAI,OAAO,CAAC,cAAc,CAAC,CA2I/D"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { chmodSync, existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
|
+
import * as p from "@clack/prompts";
|
|
5
|
+
const CONFIG_PATH = resolve(homedir(), ".config", "hyper", "hq.toml");
|
|
6
|
+
function expandHome(path) {
|
|
7
|
+
if (path.startsWith("~/"))
|
|
8
|
+
return resolve(homedir(), path.slice(2));
|
|
9
|
+
return path;
|
|
10
|
+
}
|
|
11
|
+
export async function runConfigWizard() {
|
|
12
|
+
// Step 1: Projects root
|
|
13
|
+
const projectsRootRaw = await p.text({
|
|
14
|
+
message: "Where are your projects?",
|
|
15
|
+
placeholder: "~/projects",
|
|
16
|
+
defaultValue: "~/projects",
|
|
17
|
+
});
|
|
18
|
+
if (p.isCancel(projectsRootRaw)) {
|
|
19
|
+
p.cancel("Setup cancelled.");
|
|
20
|
+
process.exit(0);
|
|
21
|
+
}
|
|
22
|
+
const projectsRoot = expandHome(projectsRootRaw);
|
|
23
|
+
// Ensure directory exists
|
|
24
|
+
if (!existsSync(projectsRoot)) {
|
|
25
|
+
const create = await p.confirm({
|
|
26
|
+
message: `Directory ${projectsRoot} doesn't exist. Create it?`,
|
|
27
|
+
initialValue: true,
|
|
28
|
+
});
|
|
29
|
+
if (p.isCancel(create) || !create) {
|
|
30
|
+
p.cancel("Setup cancelled.");
|
|
31
|
+
process.exit(0);
|
|
32
|
+
}
|
|
33
|
+
mkdirSync(projectsRoot, { recursive: true });
|
|
34
|
+
p.log.success(`Created ${projectsRoot}`);
|
|
35
|
+
}
|
|
36
|
+
// Step 2: HQ working directory
|
|
37
|
+
const hqDirRaw = await p.text({
|
|
38
|
+
message: "HQ working directory (relative to projects root)?",
|
|
39
|
+
placeholder: "./hyper-hq",
|
|
40
|
+
defaultValue: "./hyper-hq",
|
|
41
|
+
});
|
|
42
|
+
if (p.isCancel(hqDirRaw)) {
|
|
43
|
+
p.cancel("Setup cancelled.");
|
|
44
|
+
process.exit(0);
|
|
45
|
+
}
|
|
46
|
+
const hqDirInput = hqDirRaw;
|
|
47
|
+
const hqDir = hqDirInput.startsWith("/") ? hqDirInput : resolve(projectsRoot, hqDirInput);
|
|
48
|
+
if (!existsSync(hqDir)) {
|
|
49
|
+
mkdirSync(hqDir, { recursive: true });
|
|
50
|
+
p.log.success(`Created HQ directory: ${hqDir}`);
|
|
51
|
+
}
|
|
52
|
+
// Step 3: Telegram integration
|
|
53
|
+
const useTelegram = await p.confirm({
|
|
54
|
+
message: "Enable Telegram integration?",
|
|
55
|
+
initialValue: false,
|
|
56
|
+
});
|
|
57
|
+
if (p.isCancel(useTelegram)) {
|
|
58
|
+
p.cancel("Setup cancelled.");
|
|
59
|
+
process.exit(0);
|
|
60
|
+
}
|
|
61
|
+
let telegramToken;
|
|
62
|
+
if (useTelegram) {
|
|
63
|
+
p.note("1. Open Telegram and message @BotFather\n" +
|
|
64
|
+
"2. Send /newbot and follow the prompts\n" +
|
|
65
|
+
"3. Copy the token BotFather gives you", "Create a Telegram bot");
|
|
66
|
+
const token = await p.text({
|
|
67
|
+
message: "Paste your Telegram bot token:",
|
|
68
|
+
placeholder: "your-bot-token-from-botfather",
|
|
69
|
+
validate(value) {
|
|
70
|
+
if (!value?.trim())
|
|
71
|
+
return "Please enter a token";
|
|
72
|
+
if (!value?.includes(":"))
|
|
73
|
+
return "That doesn't look like a bot token (should contain a colon)";
|
|
74
|
+
return undefined;
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
if (p.isCancel(token)) {
|
|
78
|
+
p.cancel("Setup cancelled.");
|
|
79
|
+
process.exit(0);
|
|
80
|
+
}
|
|
81
|
+
telegramToken = token;
|
|
82
|
+
}
|
|
83
|
+
// Build TOML config (using expanded absolute paths)
|
|
84
|
+
const lines = [
|
|
85
|
+
"# Hyper HQ — Claude Code Command Center",
|
|
86
|
+
"",
|
|
87
|
+
`projects_root = "${projectsRoot}"`,
|
|
88
|
+
"",
|
|
89
|
+
"[hq]",
|
|
90
|
+
'name = "hyper-hq"',
|
|
91
|
+
`dir = "${hqDir}"`,
|
|
92
|
+
'spawn_mode = "same-dir"',
|
|
93
|
+
"capacity = 32",
|
|
94
|
+
"",
|
|
95
|
+
"[claude]",
|
|
96
|
+
'permission_mode = "default"',
|
|
97
|
+
"",
|
|
98
|
+
"[telegram]",
|
|
99
|
+
];
|
|
100
|
+
if (telegramToken) {
|
|
101
|
+
lines.push(`hq_bot_token = "${telegramToken}"`);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
lines.push("# Telegram is disabled. To enable later, add:");
|
|
105
|
+
lines.push('# hq_bot_token = "YOUR_BOT_TOKEN"');
|
|
106
|
+
}
|
|
107
|
+
lines.push("", "[telegram.project_bots]", "# Add dedicated bots for specific projects:", '# my-project = "BOT_TOKEN"', "", "# [projects.my-org]", '# type = "group" # Treat subfolders as separate projects', "");
|
|
108
|
+
const configContent = lines.join("\n");
|
|
109
|
+
// Write config with mode 0o600
|
|
110
|
+
const configDir = dirname(CONFIG_PATH);
|
|
111
|
+
if (!existsSync(configDir)) {
|
|
112
|
+
mkdirSync(configDir, { recursive: true });
|
|
113
|
+
}
|
|
114
|
+
writeFileSync(CONFIG_PATH, configContent, { encoding: "utf-8", mode: 0o600 });
|
|
115
|
+
chmodSync(CONFIG_PATH, 0o600);
|
|
116
|
+
p.log.success(`Config saved to ${CONFIG_PATH} (mode 0600)`);
|
|
117
|
+
return { projectsRoot, hqDir, telegramToken };
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=hq-config-wizard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hq-config-wizard.js","sourceRoot":"","sources":["../../src/setup/hq-config-wizard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-trust.d.ts","sourceRoot":"","sources":["../../src/setup/workspace-trust.ts"],"names":[],"mappings":"AAUA,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEhD;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEvD"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
const CLAUDE_PROJECTS_DIR = resolve(homedir(), ".claude", "projects");
|
|
5
|
+
function encodePath(dir) {
|
|
6
|
+
return dir.replace(/\//g, "-");
|
|
7
|
+
}
|
|
8
|
+
export function trustWorkspace(dir) {
|
|
9
|
+
mkdirSync(resolve(CLAUDE_PROJECTS_DIR, encodePath(dir)), { recursive: true });
|
|
10
|
+
}
|
|
11
|
+
export function isWorkspaceTrusted(dir) {
|
|
12
|
+
return existsSync(resolve(CLAUDE_PROJECTS_DIR, encodePath(dir)));
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=workspace-trust.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-trust.js","sourceRoot":"","sources":["../../src/setup/workspace-trust.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,mBAAmB,GAAG,OAAO,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AAEtE,SAAS,UAAU,CAAC,GAAW;IAC9B,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAW;IACzC,SAAS,CAAC,OAAO,CAAC,mBAAmB,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC/E,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC7C,OAAO,UAAU,CAAC,OAAO,CAAC,mBAAmB,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { InstallOption } from "../install/install-options.js";
|
|
2
|
+
export interface InstallOrWaitLoopOptions {
|
|
3
|
+
toolName: string;
|
|
4
|
+
toolUrl: string;
|
|
5
|
+
description: string;
|
|
6
|
+
options: InstallOption[];
|
|
7
|
+
checkFn: () => boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function installOrWaitLoop(opts: InstallOrWaitLoopOptions): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/ui/prompts.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAGnE,MAAM,WAAW,wBAAwB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,OAAO,EAAE,MAAM,OAAO,CAAC;CACvB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0FrF"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
2
|
+
import pc from "picocolors";
|
|
3
|
+
import { runInstallCommand } from "../install/run-install.js";
|
|
4
|
+
export async function installOrWaitLoop(opts) {
|
|
5
|
+
const { toolName, toolUrl, description, options, checkFn } = opts;
|
|
6
|
+
// Already installed — nothing to do
|
|
7
|
+
if (checkFn()) {
|
|
8
|
+
p.log.success(`${toolName} is already installed.`);
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
p.log.warn(`${toolName} is not installed.`);
|
|
12
|
+
p.log.message(` ${description}\n ${pc.cyan(toolUrl)}`);
|
|
13
|
+
while (true) {
|
|
14
|
+
const choice = await p.select({
|
|
15
|
+
message: `How would you like to install ${toolName}?`,
|
|
16
|
+
options: options.map((opt) => ({
|
|
17
|
+
label: opt.label,
|
|
18
|
+
value: opt.value,
|
|
19
|
+
hint: opt.hint,
|
|
20
|
+
})),
|
|
21
|
+
});
|
|
22
|
+
if (p.isCancel(choice)) {
|
|
23
|
+
p.cancel("Setup cancelled.");
|
|
24
|
+
process.exit(0);
|
|
25
|
+
}
|
|
26
|
+
if (choice === "cancel") {
|
|
27
|
+
p.cancel("Setup cancelled.");
|
|
28
|
+
process.exit(0);
|
|
29
|
+
}
|
|
30
|
+
if (choice === "manual") {
|
|
31
|
+
p.log.message(` Take your time! Here are some resources:\n ${pc.cyan(toolUrl)}`);
|
|
32
|
+
while (true) {
|
|
33
|
+
const proceed = await p.select({
|
|
34
|
+
message: "Ready to continue?",
|
|
35
|
+
options: [
|
|
36
|
+
{ label: "Continue", value: "continue" },
|
|
37
|
+
{ label: "Cancel", value: "cancel" },
|
|
38
|
+
],
|
|
39
|
+
});
|
|
40
|
+
if (p.isCancel(proceed) || proceed === "cancel") {
|
|
41
|
+
p.cancel("Setup cancelled.");
|
|
42
|
+
process.exit(0);
|
|
43
|
+
}
|
|
44
|
+
if (checkFn()) {
|
|
45
|
+
p.log.success(`Found ${toolName}!`);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
p.log.warn(`Hmm, I still can't find ${pc.bold(`\`${toolName}\``)} on your PATH.\n Installation guide: ${pc.cyan(toolUrl)}`);
|
|
49
|
+
// Loop back to ask again
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Auto-install: find the matching option
|
|
53
|
+
const selectedOption = options.find((o) => o.value === choice);
|
|
54
|
+
if (!selectedOption || !selectedOption.command) {
|
|
55
|
+
p.log.error("Unknown option selected.");
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
p.log.step(`Running: ${selectedOption.label.split(" ")[0]}`);
|
|
59
|
+
const result = runInstallCommand(selectedOption);
|
|
60
|
+
if (result.success) {
|
|
61
|
+
// Re-check after install (using login shell)
|
|
62
|
+
if (checkFn()) {
|
|
63
|
+
p.log.success(`${toolName} installed successfully!`);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
p.log.warn(`Install command succeeded but ${pc.bold(`\`${toolName}\``)} is still not found on PATH.\n You may need to open a new terminal. The tool should be available after that.`);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
p.log.error(`Installation failed: ${result.error ?? "unknown error"}`);
|
|
70
|
+
p.log.message(` You may need to open a new terminal or install manually:\n ${pc.cyan(toolUrl)}`);
|
|
71
|
+
}
|
|
72
|
+
// Re-offer options (loop continues)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/ui/prompts.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-hyper-hq",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Set up Hyper HQ — always-on Claude Code command center",
|
|
6
6
|
"author": "Saulo Vallory <saulo@toki.life>",
|
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
},
|
|
32
32
|
"scripts": {
|
|
33
33
|
"build": "tsc",
|
|
34
|
-
"postbuild": "
|
|
34
|
+
"postbuild": "bash scripts/postbuild.sh",
|
|
35
|
+
"test": "vitest run",
|
|
35
36
|
"dev": "tsc --watch",
|
|
36
37
|
"typecheck": "tsc --noEmit"
|
|
37
38
|
},
|
|
@@ -40,7 +41,8 @@
|
|
|
40
41
|
"picocolors": "^1.1.0"
|
|
41
42
|
},
|
|
42
43
|
"devDependencies": {
|
|
44
|
+
"@types/node": "^20.0.0",
|
|
43
45
|
"typescript": "^5.4.0",
|
|
44
|
-
"
|
|
46
|
+
"vitest": "4.0.18"
|
|
45
47
|
}
|
|
46
48
|
}
|