create-hyper-hq 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 +3 -0
- package/dist/checks/check-tool.d.ts.map +1 -0
- package/dist/checks/check-tool.js +23 -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 +213 -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 +129 -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 @@
|
|
|
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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
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
|
+
//# 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"}
|
|
@@ -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,213 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawn } 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 { isToolInstalled } 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
|
+
async function main() {
|
|
16
|
+
// Step 0: Welcome banner
|
|
17
|
+
p.intro(pc.bold("create-hyper-hq"));
|
|
18
|
+
p.note("HQ is an always-on Claude Code command center that runs in a\n" +
|
|
19
|
+
"tmux session. Once started, you can control it from claude.ai,\n" +
|
|
20
|
+
"the Claude mobile app, or Telegram.\n\n" +
|
|
21
|
+
"Let's make sure you have everything you need.", "Welcome to Hyper HQ Setup!");
|
|
22
|
+
// Step 1: Detect environment
|
|
23
|
+
const platform = detectPlatform();
|
|
24
|
+
const systemPms = detectSystemPms();
|
|
25
|
+
const callingPm = detectCallingPm();
|
|
26
|
+
const availableNodePms = detectAvailableNodePms();
|
|
27
|
+
const installContext = {
|
|
28
|
+
callingPm,
|
|
29
|
+
availableNodePms,
|
|
30
|
+
systemPms,
|
|
31
|
+
os: platform.os,
|
|
32
|
+
isRoot: platform.isRoot,
|
|
33
|
+
};
|
|
34
|
+
// Step 2: Check hyper CLI
|
|
35
|
+
p.log.step("Checking for hyper CLI...");
|
|
36
|
+
if (!isToolInstalled("hyper")) {
|
|
37
|
+
await installOrWaitLoop({
|
|
38
|
+
toolName: "hyper",
|
|
39
|
+
toolUrl: "https://hyperdev.saulo.engineer/cli/install",
|
|
40
|
+
description: "The hyper CLI is the main command-line tool for HyperDev.",
|
|
41
|
+
options: getInstallOptions("hyper", installContext),
|
|
42
|
+
checkFn: () => isToolInstalled("hyper"),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
p.log.success("hyper is installed.");
|
|
47
|
+
}
|
|
48
|
+
// Step 3: Check claude CLI
|
|
49
|
+
p.log.step("Checking for Claude CLI...");
|
|
50
|
+
if (!isToolInstalled("claude")) {
|
|
51
|
+
await installOrWaitLoop({
|
|
52
|
+
toolName: "claude",
|
|
53
|
+
toolUrl: "https://claude.ai/code",
|
|
54
|
+
description: "Claude Code is the AI coding assistant that powers HQ sessions.",
|
|
55
|
+
options: getInstallOptions("claude", installContext),
|
|
56
|
+
checkFn: () => isToolInstalled("claude"),
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
p.log.success("Claude CLI is installed.");
|
|
61
|
+
}
|
|
62
|
+
// Step 4: Check tmux
|
|
63
|
+
p.log.step("Checking for tmux...");
|
|
64
|
+
if (platform.os === "windows") {
|
|
65
|
+
p.log.warn("tmux is not available natively on Windows.");
|
|
66
|
+
p.note("tmux requires a Linux environment. HQ works inside WSL\n" +
|
|
67
|
+
"(Windows Subsystem for Linux).\n\n" +
|
|
68
|
+
"If you're running this from WSL, tmux can be installed with\n" +
|
|
69
|
+
"your Linux distro's package manager.\n\n" +
|
|
70
|
+
"If you're running this from Windows directly, please install\n" +
|
|
71
|
+
"WSL first: " +
|
|
72
|
+
pc.cyan("https://learn.microsoft.com/windows/wsl/install") +
|
|
73
|
+
"\nThen re-run this setup from inside WSL.");
|
|
74
|
+
const wslChoice = await p.select({
|
|
75
|
+
message: "What would you like to do?",
|
|
76
|
+
options: [
|
|
77
|
+
{ label: "I'm in WSL, continue", value: "wsl" },
|
|
78
|
+
{ label: "Cancel", value: "cancel" },
|
|
79
|
+
],
|
|
80
|
+
});
|
|
81
|
+
if (p.isCancel(wslChoice) || wslChoice === "cancel") {
|
|
82
|
+
p.cancel("Setup cancelled.");
|
|
83
|
+
process.exit(0);
|
|
84
|
+
}
|
|
85
|
+
// Re-detect as Linux
|
|
86
|
+
const wslContext = {
|
|
87
|
+
...installContext,
|
|
88
|
+
os: "linux",
|
|
89
|
+
};
|
|
90
|
+
if (!isToolInstalled("tmux")) {
|
|
91
|
+
await installOrWaitLoop({
|
|
92
|
+
toolName: "tmux",
|
|
93
|
+
toolUrl: "https://github.com/tmux/tmux",
|
|
94
|
+
description: "tmux is a terminal multiplexer that keeps HQ sessions running\nin the background, even after you close your terminal.",
|
|
95
|
+
options: getInstallOptions("tmux", wslContext),
|
|
96
|
+
checkFn: () => isToolInstalled("tmux"),
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
else if (!isToolInstalled("tmux")) {
|
|
101
|
+
await installOrWaitLoop({
|
|
102
|
+
toolName: "tmux",
|
|
103
|
+
toolUrl: "https://github.com/tmux/tmux",
|
|
104
|
+
description: "tmux is a terminal multiplexer that keeps HQ sessions running\nin the background, even after you close your terminal.",
|
|
105
|
+
options: getInstallOptions("tmux", installContext),
|
|
106
|
+
checkFn: () => isToolInstalled("tmux"),
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
p.log.success("tmux is installed.");
|
|
111
|
+
}
|
|
112
|
+
// Step 5: Check claude authentication
|
|
113
|
+
p.log.step("Checking Claude authentication...");
|
|
114
|
+
if (!isClaudeAuthenticated()) {
|
|
115
|
+
p.log.warn("Not authenticated with Claude.");
|
|
116
|
+
p.log.message(" You need to log in to Claude to use HQ.");
|
|
117
|
+
p.log.step("Running `claude auth login`...");
|
|
118
|
+
const authSuccess = await runClaudeLogin();
|
|
119
|
+
if (!authSuccess) {
|
|
120
|
+
const retryOrSkip = await p.select({
|
|
121
|
+
message: "Authentication failed or was cancelled. What would you like to do?",
|
|
122
|
+
options: [
|
|
123
|
+
{ label: "Retry", value: "retry" },
|
|
124
|
+
{ label: "Skip (HQ won't work without auth)", value: "skip" },
|
|
125
|
+
{ label: "Cancel", value: "cancel" },
|
|
126
|
+
],
|
|
127
|
+
});
|
|
128
|
+
if (p.isCancel(retryOrSkip) || retryOrSkip === "cancel") {
|
|
129
|
+
p.cancel("Setup cancelled.");
|
|
130
|
+
process.exit(0);
|
|
131
|
+
}
|
|
132
|
+
if (retryOrSkip === "retry") {
|
|
133
|
+
p.log.step("Running `claude auth login`...");
|
|
134
|
+
const retrySuccess = await runClaudeLogin();
|
|
135
|
+
if (!retrySuccess) {
|
|
136
|
+
p.log.warn("Authentication still failed. Continuing setup — you can run `claude auth login` manually.");
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
p.log.success("Claude authentication successful.");
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
p.log.warn("Skipping authentication. HQ requires Claude auth to function properly.");
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
p.log.success("Claude authentication successful.");
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
p.log.success("Claude is authenticated.");
|
|
152
|
+
}
|
|
153
|
+
// Step 6: Config wizard
|
|
154
|
+
p.log.step("Configuring HQ...");
|
|
155
|
+
const config = await runConfigWizard();
|
|
156
|
+
// Step 7: Trust workspaces + write CLAUDE.md
|
|
157
|
+
p.log.step("Trusting workspace directories...");
|
|
158
|
+
for (const dir of [config.hqDir, config.projectsRoot]) {
|
|
159
|
+
if (!isWorkspaceTrusted(dir)) {
|
|
160
|
+
trustWorkspace(dir);
|
|
161
|
+
p.log.success(`Trusted ${dir}`);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
p.log.info(`${dir} is already trusted`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// Generate CLAUDE.md
|
|
168
|
+
p.log.step("Generating CLAUDE.md for HQ session...");
|
|
169
|
+
const claudeMdPath = `${config.hqDir}/CLAUDE.md`;
|
|
170
|
+
if (!existsSync(config.hqDir)) {
|
|
171
|
+
mkdirSync(config.hqDir, { recursive: true });
|
|
172
|
+
}
|
|
173
|
+
writeFileSync(claudeMdPath, generateHqClaudeMd(config.projectsRoot), "utf-8");
|
|
174
|
+
p.log.success(`${claudeMdPath} created`);
|
|
175
|
+
// Step 8: All set!
|
|
176
|
+
p.log.success("All set! HQ is ready to go.");
|
|
177
|
+
const startNow = await p.select({
|
|
178
|
+
message: "Start HQ now?",
|
|
179
|
+
options: [
|
|
180
|
+
{ label: "Yes, start HQ", value: "yes" },
|
|
181
|
+
{ label: "No, I'll start it later", value: "no" },
|
|
182
|
+
],
|
|
183
|
+
});
|
|
184
|
+
if (p.isCancel(startNow)) {
|
|
185
|
+
p.cancel("Setup cancelled.");
|
|
186
|
+
process.exit(0);
|
|
187
|
+
}
|
|
188
|
+
p.log.message(` (You can always run ${pc.cyan("`hyper hq start`")} to launch HQ)`);
|
|
189
|
+
if (startNow === "yes") {
|
|
190
|
+
p.log.step("Starting HQ...");
|
|
191
|
+
const child = spawn("hyper", ["hq", "start"], {
|
|
192
|
+
stdio: "inherit",
|
|
193
|
+
detached: false,
|
|
194
|
+
});
|
|
195
|
+
await new Promise((resolve) => {
|
|
196
|
+
child.on("close", () => resolve());
|
|
197
|
+
child.on("error", (err) => {
|
|
198
|
+
p.log.error(`Failed to start HQ: ${err.message}`);
|
|
199
|
+
resolve();
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
p.outro(pc.green("Hyper HQ setup complete!"));
|
|
204
|
+
}
|
|
205
|
+
main().catch((err) => {
|
|
206
|
+
if (err instanceof Error && err.message === "User force closed the prompt with CTRL+C") {
|
|
207
|
+
process.stdout.write("\nSetup cancelled.\n");
|
|
208
|
+
process.exit(0);
|
|
209
|
+
}
|
|
210
|
+
console.error(err);
|
|
211
|
+
process.exit(1);
|
|
212
|
+
});
|
|
213
|
+
//# 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,CAmJ/D"}
|
|
@@ -0,0 +1,129 @@
|
|
|
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: "~/work",
|
|
16
|
+
defaultValue: "~/work",
|
|
17
|
+
validate(value) {
|
|
18
|
+
if (!value?.trim())
|
|
19
|
+
return "Please enter a path";
|
|
20
|
+
return undefined;
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
if (p.isCancel(projectsRootRaw)) {
|
|
24
|
+
p.cancel("Setup cancelled.");
|
|
25
|
+
process.exit(0);
|
|
26
|
+
}
|
|
27
|
+
const projectsRoot = expandHome(projectsRootRaw);
|
|
28
|
+
// Ensure directory exists
|
|
29
|
+
if (!existsSync(projectsRoot)) {
|
|
30
|
+
const create = await p.confirm({
|
|
31
|
+
message: `Directory ${projectsRoot} doesn't exist. Create it?`,
|
|
32
|
+
initialValue: true,
|
|
33
|
+
});
|
|
34
|
+
if (p.isCancel(create) || !create) {
|
|
35
|
+
p.cancel("Setup cancelled.");
|
|
36
|
+
process.exit(0);
|
|
37
|
+
}
|
|
38
|
+
mkdirSync(projectsRoot, { recursive: true });
|
|
39
|
+
p.log.success(`Created ${projectsRoot}`);
|
|
40
|
+
}
|
|
41
|
+
// Step 2: HQ working directory
|
|
42
|
+
const hqDirRaw = await p.text({
|
|
43
|
+
message: "HQ working directory (relative to projects root)?",
|
|
44
|
+
placeholder: "./hyper-hq",
|
|
45
|
+
defaultValue: "./hyper-hq",
|
|
46
|
+
validate(value) {
|
|
47
|
+
if (!value?.trim())
|
|
48
|
+
return "Please enter a path";
|
|
49
|
+
return undefined;
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
if (p.isCancel(hqDirRaw)) {
|
|
53
|
+
p.cancel("Setup cancelled.");
|
|
54
|
+
process.exit(0);
|
|
55
|
+
}
|
|
56
|
+
const hqDirInput = hqDirRaw;
|
|
57
|
+
const hqDir = hqDirInput.startsWith("/") ? hqDirInput : resolve(projectsRoot, hqDirInput);
|
|
58
|
+
if (!existsSync(hqDir)) {
|
|
59
|
+
mkdirSync(hqDir, { recursive: true });
|
|
60
|
+
p.log.success(`Created HQ directory: ${hqDir}`);
|
|
61
|
+
}
|
|
62
|
+
// Step 3: Telegram integration
|
|
63
|
+
const useTelegram = await p.confirm({
|
|
64
|
+
message: "Enable Telegram integration?",
|
|
65
|
+
initialValue: false,
|
|
66
|
+
});
|
|
67
|
+
if (p.isCancel(useTelegram)) {
|
|
68
|
+
p.cancel("Setup cancelled.");
|
|
69
|
+
process.exit(0);
|
|
70
|
+
}
|
|
71
|
+
let telegramToken;
|
|
72
|
+
if (useTelegram) {
|
|
73
|
+
p.note("1. Open Telegram and message @BotFather\n" +
|
|
74
|
+
"2. Send /newbot and follow the prompts\n" +
|
|
75
|
+
"3. Copy the token BotFather gives you", "Create a Telegram bot");
|
|
76
|
+
const token = await p.text({
|
|
77
|
+
message: "Paste your Telegram bot token:",
|
|
78
|
+
placeholder: "your-bot-token-from-botfather",
|
|
79
|
+
validate(value) {
|
|
80
|
+
if (!value?.trim())
|
|
81
|
+
return "Please enter a token";
|
|
82
|
+
if (!value?.includes(":"))
|
|
83
|
+
return "That doesn't look like a bot token (should contain a colon)";
|
|
84
|
+
return undefined;
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
if (p.isCancel(token)) {
|
|
88
|
+
p.cancel("Setup cancelled.");
|
|
89
|
+
process.exit(0);
|
|
90
|
+
}
|
|
91
|
+
telegramToken = token;
|
|
92
|
+
}
|
|
93
|
+
// Build TOML config (using expanded absolute paths)
|
|
94
|
+
const lines = [
|
|
95
|
+
"# Hyper HQ — Claude Code Command Center",
|
|
96
|
+
"",
|
|
97
|
+
`projects_root = "${projectsRoot}"`,
|
|
98
|
+
"",
|
|
99
|
+
"[hq]",
|
|
100
|
+
'name = "hyper-hq"',
|
|
101
|
+
`dir = "${hqDir}"`,
|
|
102
|
+
'spawn_mode = "same-dir"',
|
|
103
|
+
"capacity = 32",
|
|
104
|
+
"",
|
|
105
|
+
"[claude]",
|
|
106
|
+
'permission_mode = "default"',
|
|
107
|
+
"",
|
|
108
|
+
"[telegram]",
|
|
109
|
+
];
|
|
110
|
+
if (telegramToken) {
|
|
111
|
+
lines.push(`hq_bot_token = "${telegramToken}"`);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
lines.push("# Telegram is disabled. To enable later, add:");
|
|
115
|
+
lines.push('# hq_bot_token = "YOUR_BOT_TOKEN"');
|
|
116
|
+
}
|
|
117
|
+
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', "");
|
|
118
|
+
const configContent = lines.join("\n");
|
|
119
|
+
// Write config with mode 0o600
|
|
120
|
+
const configDir = dirname(CONFIG_PATH);
|
|
121
|
+
if (!existsSync(configDir)) {
|
|
122
|
+
mkdirSync(configDir, { recursive: true });
|
|
123
|
+
}
|
|
124
|
+
writeFileSync(CONFIG_PATH, configContent, { encoding: "utf-8", mode: 0o600 });
|
|
125
|
+
chmodSync(CONFIG_PATH, 0o600);
|
|
126
|
+
p.log.success(`Config saved to ${CONFIG_PATH} (mode 0600)`);
|
|
127
|
+
return { projectsRoot, hqDir, telegramToken };
|
|
128
|
+
}
|
|
129
|
+
//# 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.3",
|
|
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
|
}
|