@hypercli/hq 0.1.4 → 0.2.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.
Files changed (51) hide show
  1. package/dist/commands/hq/configure/telegram.d.ts +7 -0
  2. package/dist/commands/hq/configure/telegram.d.ts.map +1 -0
  3. package/dist/commands/hq/configure/telegram.js +24 -0
  4. package/dist/commands/hq/configure/telegram.js.map +1 -0
  5. package/dist/commands/hq/setup.d.ts +2 -2
  6. package/dist/commands/hq/setup.d.ts.map +1 -1
  7. package/dist/commands/hq/setup.js +24 -33
  8. package/dist/commands/hq/setup.js.map +1 -1
  9. package/dist/commands/hq/spawn.d.ts +4 -0
  10. package/dist/commands/hq/spawn.d.ts.map +1 -1
  11. package/dist/commands/hq/spawn.js +32 -8
  12. package/dist/commands/hq/spawn.js.map +1 -1
  13. package/dist/commands/hq/start.d.ts +4 -2
  14. package/dist/commands/hq/start.d.ts.map +1 -1
  15. package/dist/commands/hq/start.js +49 -82
  16. package/dist/commands/hq/start.js.map +1 -1
  17. package/dist/commands/hq/status.js +2 -2
  18. package/dist/commands/hq/status.js.map +1 -1
  19. package/dist/commands/hq/stop-all.js +1 -1
  20. package/dist/commands/hq/stop-all.js.map +1 -1
  21. package/dist/config/index.d.ts +5 -0
  22. package/dist/config/index.d.ts.map +1 -1
  23. package/dist/config/index.js +30 -1
  24. package/dist/config/index.js.map +1 -1
  25. package/dist/config/schema.js +2 -2
  26. package/dist/config/schema.js.map +1 -1
  27. package/dist/services/claude.d.ts +17 -3
  28. package/dist/services/claude.d.ts.map +1 -1
  29. package/dist/services/claude.js +26 -10
  30. package/dist/services/claude.js.map +1 -1
  31. package/dist/services/telegram.d.ts +1 -1
  32. package/dist/services/telegram.d.ts.map +1 -1
  33. package/dist/services/telegram.js +3 -16
  34. package/dist/services/telegram.js.map +1 -1
  35. package/dist/services/tmux.d.ts +2 -0
  36. package/dist/services/tmux.d.ts.map +1 -1
  37. package/dist/services/tmux.js +22 -0
  38. package/dist/services/tmux.js.map +1 -1
  39. package/dist/utils/banner.d.ts.map +1 -1
  40. package/dist/utils/banner.js +20 -46
  41. package/dist/utils/banner.js.map +1 -1
  42. package/oclif.manifest.json +88 -27
  43. package/package.json +6 -1
  44. package/dist/config/setup.d.ts +0 -4
  45. package/dist/config/setup.d.ts.map +0 -1
  46. package/dist/config/setup.js +0 -148
  47. package/dist/config/setup.js.map +0 -1
  48. package/dist/utils/trust.d.ts +0 -13
  49. package/dist/utils/trust.d.ts.map +0 -1
  50. package/dist/utils/trust.js +0 -29
  51. package/dist/utils/trust.js.map +0 -1
@@ -1,148 +0,0 @@
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
- import { isWorkspaceTrusted, trustWorkspace } from "../utils/trust.js";
6
- import { CONFIG_PATH, configExists, loadConfig } from "./index.js";
7
- function expandHome(path) {
8
- if (path.startsWith("~/"))
9
- return resolve(homedir(), path.slice(2));
10
- return path;
11
- }
12
- export async function runSetup(force = false) {
13
- if (!force && configExists()) {
14
- return loadConfig();
15
- }
16
- p.intro("Welcome to Hyper HQ — Claude Code Command Center");
17
- p.note("No configuration file found.\n" + "Let's get you set up. This will only take a moment.", "First-time setup");
18
- // Step 1: Projects root
19
- const projectsRoot = await p.text({
20
- message: "Where do your projects live?",
21
- placeholder: "~/work",
22
- defaultValue: "~/work",
23
- validate(value) {
24
- if (!value?.trim())
25
- return "Please enter a path";
26
- return undefined;
27
- },
28
- });
29
- if (p.isCancel(projectsRoot)) {
30
- p.cancel("Setup cancelled.");
31
- process.exit(0);
32
- }
33
- const expandedRoot = expandHome(projectsRoot);
34
- // Step 2: Ensure directory exists
35
- if (!existsSync(expandedRoot)) {
36
- const create = await p.confirm({
37
- message: `Directory ${expandedRoot} doesn't exist. Create it?`,
38
- initialValue: true,
39
- });
40
- if (p.isCancel(create) || !create) {
41
- p.cancel("Setup cancelled.");
42
- process.exit(0);
43
- }
44
- mkdirSync(expandedRoot, { recursive: true });
45
- p.log.success(`Created ${expandedRoot}`);
46
- }
47
- // Step 3: HQ directory
48
- const hqDir = await p.text({
49
- message: "Where should the HQ session folder live?",
50
- placeholder: "./hyper-hq",
51
- defaultValue: "./hyper-hq",
52
- validate(value) {
53
- if (!value?.trim())
54
- return "Please enter a path";
55
- return undefined;
56
- },
57
- });
58
- if (p.isCancel(hqDir)) {
59
- p.cancel("Setup cancelled.");
60
- process.exit(0);
61
- }
62
- // Resolve hq dir relative to projects root
63
- const expandedHqDir = hqDir.startsWith("/") ? hqDir : resolve(expandedRoot, hqDir);
64
- if (!existsSync(expandedHqDir)) {
65
- mkdirSync(expandedHqDir, { recursive: true });
66
- p.log.success(`Created HQ directory: ${expandedHqDir}`);
67
- }
68
- // Step 4: Workspace trust — auto-trust both HQ dir and projects root
69
- for (const dir of [expandedHqDir, expandedRoot]) {
70
- if (!isWorkspaceTrusted(dir)) {
71
- trustWorkspace(dir);
72
- p.log.success(`Trusted ${dir} for Claude Code.`);
73
- }
74
- }
75
- // Step 5: Telegram
76
- const useTelegram = await p.confirm({
77
- message: "Do you want to enable Telegram integration?",
78
- initialValue: false,
79
- });
80
- if (p.isCancel(useTelegram)) {
81
- p.cancel("Setup cancelled.");
82
- process.exit(0);
83
- }
84
- let hqBotToken = "";
85
- if (useTelegram) {
86
- p.note("1. Open Telegram and message @BotFather\n" +
87
- "2. Send /newbot and follow the prompts\n" +
88
- "3. Copy the token BotFather gives you", "Create a Telegram bot");
89
- const token = await p.text({
90
- message: "Paste your Telegram bot token:",
91
- placeholder: "your-bot-token-from-botfather",
92
- validate(value) {
93
- if (!value?.trim())
94
- return "Please enter a token";
95
- if (!value?.includes(":"))
96
- return "That doesn't look like a bot token (should contain a colon)";
97
- return undefined;
98
- },
99
- });
100
- if (p.isCancel(token)) {
101
- p.cancel("Setup cancelled.");
102
- process.exit(0);
103
- }
104
- hqBotToken = token;
105
- }
106
- // Build TOML config
107
- const lines = [
108
- "# Hyper HQ — Claude Code Command Center",
109
- "",
110
- `projects_root = "${projectsRoot}"`,
111
- "",
112
- "[hq]",
113
- 'name = "hyper-hq"',
114
- `dir = "${hqDir}"`,
115
- 'spawn_mode = "same-dir"',
116
- "capacity = 32",
117
- "",
118
- "[claude]",
119
- 'permission_mode = "default"',
120
- "",
121
- "[telegram]",
122
- ];
123
- if (hqBotToken) {
124
- lines.push(`hq_bot_token = "${hqBotToken}"`);
125
- }
126
- else {
127
- lines.push("# Telegram is disabled. To enable later, add:");
128
- lines.push('# hq_bot_token = "YOUR_BOT_TOKEN"');
129
- }
130
- 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', "");
131
- const configContent = lines.join("\n");
132
- // Write config
133
- const configDir = dirname(CONFIG_PATH);
134
- if (!existsSync(configDir)) {
135
- mkdirSync(configDir, { recursive: true });
136
- }
137
- writeFileSync(CONFIG_PATH, configContent, { encoding: "utf-8", mode: 0o600 });
138
- chmodSync(CONFIG_PATH, 0o600);
139
- p.note(CONFIG_PATH, "Config saved to");
140
- if (!useTelegram) {
141
- p.log.info("Telegram is disabled. Sessions will use Remote Control only (claude.ai/code + mobile).");
142
- p.log.info("You can enable Telegram later by adding a bot token to your config file.");
143
- }
144
- return loadConfig();
145
- }
146
- // Backwards compat — start.ts calls this
147
- export const runSetupIfNeeded = () => runSetup(false);
148
- //# sourceMappingURL=setup.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/config/setup.ts"],"names":[],"mappings":"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"}
@@ -1,13 +0,0 @@
1
- /**
2
- * Check if a directory (or any ancestor) is trusted by Claude Code.
3
- * Workspace trust is stored as project dirs under ~/.claude/projects/
4
- * with path encoded using dashes (e.g. /Users/foo/work → -Users-foo-work).
5
- * Subdirectories of trusted workspaces are also trusted.
6
- */
7
- export declare function isWorkspaceTrusted(dir: string): boolean;
8
- /**
9
- * Trust a directory for Claude Code by creating its project entry.
10
- * This is equivalent to running `claude` in the directory and accepting the trust dialog.
11
- */
12
- export declare function trustWorkspace(dir: string): void;
13
- //# sourceMappingURL=trust.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"trust.d.ts","sourceRoot":"","sources":["../../src/utils/trust.ts"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAQvD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAGhD"}
@@ -1,29 +0,0 @@
1
- import { existsSync, mkdirSync } from "node:fs";
2
- import { homedir } from "node:os";
3
- import { dirname, resolve } from "node:path";
4
- const CLAUDE_PROJECTS_DIR = resolve(homedir(), ".claude/projects");
5
- /**
6
- * Check if a directory (or any ancestor) is trusted by Claude Code.
7
- * Workspace trust is stored as project dirs under ~/.claude/projects/
8
- * with path encoded using dashes (e.g. /Users/foo/work → -Users-foo-work).
9
- * Subdirectories of trusted workspaces are also trusted.
10
- */
11
- export function isWorkspaceTrusted(dir) {
12
- let current = dir;
13
- while (current !== "/") {
14
- const encoded = current.replace(/\//g, "-");
15
- if (existsSync(resolve(CLAUDE_PROJECTS_DIR, encoded)))
16
- return true;
17
- current = dirname(current);
18
- }
19
- return false;
20
- }
21
- /**
22
- * Trust a directory for Claude Code by creating its project entry.
23
- * This is equivalent to running `claude` in the directory and accepting the trust dialog.
24
- */
25
- export function trustWorkspace(dir) {
26
- const encoded = dir.replace(/\//g, "-");
27
- mkdirSync(resolve(CLAUDE_PROJECTS_DIR, encoded), { recursive: true });
28
- }
29
- //# sourceMappingURL=trust.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"trust.js","sourceRoot":"","sources":["../../src/utils/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,OAAO,EAAE,MAAM,WAAW,CAAC;AAE7C,MAAM,mBAAmB,GAAG,OAAO,CAAC,OAAO,EAAE,EAAE,kBAAkB,CAAC,CAAC;AAEnE;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC7C,IAAI,OAAO,GAAG,GAAG,CAAC;IAClB,OAAO,OAAO,KAAK,GAAG,EAAE,CAAC;QACxB,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC5C,IAAI,UAAU,CAAC,OAAO,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QACnE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACzC,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACxC,SAAS,CAAC,OAAO,CAAC,mBAAmB,EAAE,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AACvE,CAAC"}