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.
Files changed (45) hide show
  1. package/dist/checks/check-claude-auth.d.ts +3 -0
  2. package/dist/checks/check-claude-auth.d.ts.map +1 -0
  3. package/dist/checks/check-claude-auth.js +22 -0
  4. package/dist/checks/check-claude-auth.js.map +1 -0
  5. package/dist/checks/check-tool.d.ts +14 -0
  6. package/dist/checks/check-tool.d.ts.map +1 -0
  7. package/dist/checks/check-tool.js +45 -0
  8. package/dist/checks/check-tool.js.map +1 -0
  9. package/dist/checks/detect-os.d.ts +8 -0
  10. package/dist/checks/detect-os.d.ts.map +1 -0
  11. package/dist/checks/detect-os.js +32 -0
  12. package/dist/checks/detect-os.js.map +1 -0
  13. package/dist/checks/detect-pm.d.ts +4 -0
  14. package/dist/checks/detect-pm.d.ts.map +1 -0
  15. package/dist/checks/detect-pm.js +20 -0
  16. package/dist/checks/detect-pm.js.map +1 -0
  17. package/dist/index.d.ts +2 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +273 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/install/install-options.d.ts +17 -0
  22. package/dist/install/install-options.d.ts.map +1 -0
  23. package/dist/install/install-options.js +120 -0
  24. package/dist/install/install-options.js.map +1 -0
  25. package/dist/install/run-install.d.ts +7 -0
  26. package/dist/install/run-install.d.ts.map +1 -0
  27. package/dist/install/run-install.js +30 -0
  28. package/dist/install/run-install.js.map +1 -0
  29. package/dist/setup/claude-md.d.ts +2 -0
  30. package/dist/setup/claude-md.d.ts.map +1 -0
  31. package/dist/setup/claude-md.js +59 -0
  32. package/dist/setup/claude-md.js.map +1 -0
  33. package/dist/setup/hq-config-wizard.d.ts +7 -0
  34. package/dist/setup/hq-config-wizard.d.ts.map +1 -0
  35. package/dist/setup/hq-config-wizard.js +119 -0
  36. package/dist/setup/hq-config-wizard.js.map +1 -0
  37. package/dist/setup/workspace-trust.d.ts +3 -0
  38. package/dist/setup/workspace-trust.d.ts.map +1 -0
  39. package/dist/setup/workspace-trust.js +14 -0
  40. package/dist/setup/workspace-trust.js.map +1 -0
  41. package/dist/ui/prompts.d.ts +10 -0
  42. package/dist/ui/prompts.d.ts.map +1 -0
  43. package/dist/ui/prompts.js +75 -0
  44. package/dist/ui/prompts.js.map +1 -0
  45. package/package.json +5 -3
@@ -0,0 +1,3 @@
1
+ export declare function isClaudeAuthenticated(): boolean;
2
+ export declare function runClaudeLogin(): Promise<boolean>;
3
+ //# sourceMappingURL=check-claude-auth.d.ts.map
@@ -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,4 @@
1
+ export type NodePm = "npm" | "bun" | "pnpm" | "yarn";
2
+ export declare function detectCallingPm(): NodePm;
3
+ export declare function detectAvailableNodePms(): NodePm[];
4
+ //# sourceMappingURL=detect-pm.d.ts.map
@@ -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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -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,7 @@
1
+ import type { InstallOption } from "./install-options.js";
2
+ export interface InstallResult {
3
+ success: boolean;
4
+ error?: string;
5
+ }
6
+ export declare function runInstallCommand(option: InstallOption): InstallResult;
7
+ //# sourceMappingURL=run-install.d.ts.map
@@ -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,2 @@
1
+ export declare function generateHqClaudeMd(projectsRoot: string): string;
2
+ //# sourceMappingURL=claude-md.d.ts.map
@@ -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,7 @@
1
+ export interface HqConfigResult {
2
+ projectsRoot: string;
3
+ hqDir: string;
4
+ telegramToken?: string;
5
+ }
6
+ export declare function runConfigWizard(): Promise<HqConfigResult>;
7
+ //# sourceMappingURL=hq-config-wizard.d.ts.map
@@ -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,3 @@
1
+ export declare function trustWorkspace(dir: string): void;
2
+ export declare function isWorkspaceTrusted(dir: string): boolean;
3
+ //# sourceMappingURL=workspace-trust.d.ts.map
@@ -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":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAU9D,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAA8B;IACrE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAElE,oCAAoC;IACpC,IAAI,OAAO,EAAE,EAAE,CAAC;QACf,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,QAAQ,wBAAwB,CAAC,CAAC;QACnD,OAAO;IACR,CAAC;IAED,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,QAAQ,oBAAoB,CAAC,CAAC;IAC5C,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,WAAW,OAAO,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAEzD,OAAO,IAAI,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,MAAM,CAAS;YACrC,OAAO,EAAE,iCAAiC,QAAQ,GAAG;YACrD,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;gBAC9B,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,IAAI,EAAE,GAAG,CAAC,IAAI;aACd,CAAC,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;YAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;QAED,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YACzB,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;YAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;QAED,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YACzB,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,iDAAiD,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAEnF,OAAO,IAAI,EAAE,CAAC;gBACb,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,MAAM,CAAS;oBACtC,OAAO,EAAE,oBAAoB;oBAC7B,OAAO,EAAE;wBACR,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE;wBACxC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;qBACpC;iBACD,CAAC,CAAC;gBAEH,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;oBACjD,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;oBAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACjB,CAAC;gBAED,IAAI,OAAO,EAAE,EAAE,CAAC;oBACf,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,QAAQ,GAAG,CAAC,CAAC;oBACpC,OAAO;gBACR,CAAC;gBAED,CAAC,CAAC,GAAG,CAAC,IAAI,CACT,2BAA2B,EAAE,CAAC,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,yCAAyC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAChH,CAAC;gBACF,yBAAyB;YAC1B,CAAC;QACF,CAAC;QAED,yCAAyC;QACzC,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC;QAC/D,IAAI,CAAC,cAAc,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;YAChD,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;YACxC,SAAS;QACV,CAAC;QAED,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC9D,MAAM,MAAM,GAAG,iBAAiB,CAAC,cAAc,CAAC,CAAC;QAEjD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,6CAA6C;YAC7C,IAAI,OAAO,EAAE,EAAE,CAAC;gBACf,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,QAAQ,0BAA0B,CAAC,CAAC;gBACrD,OAAO;YACR,CAAC;YAED,CAAC,CAAC,GAAG,CAAC,IAAI,CACT,iCAAiC,EAAE,CAAC,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,+GAA+G,CAC1K,CAAC;QACH,CAAC;aAAM,CAAC;YACP,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,wBAAwB,MAAM,CAAC,KAAK,IAAI,eAAe,EAAE,CAAC,CAAC;YACvE,CAAC,CAAC,GAAG,CAAC,OAAO,CACZ,iEAAiE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CACnF,CAAC;QACH,CAAC;QAED,oCAAoC;IACrC,CAAC;AACF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-hyper-hq",
3
- "version": "0.1.2",
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": "echo '#!/usr/bin/env node' | cat - dist/index.js > dist/index.tmp && mv dist/index.tmp dist/index.js",
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
- "@types/node": "^20.0.0"
46
+ "vitest": "4.0.18"
45
47
  }
46
48
  }