heyhank 0.1.0

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 (199) hide show
  1. package/README.md +40 -0
  2. package/bin/cli.ts +168 -0
  3. package/bin/ctl.ts +528 -0
  4. package/bin/generate-token.ts +28 -0
  5. package/dist/apple-touch-icon.png +0 -0
  6. package/dist/assets/AgentsPage-BPhirnCe.js +7 -0
  7. package/dist/assets/AssistantPage-DJ-cMQfb.js +1 -0
  8. package/dist/assets/CronManager-DDbz-yiT.js +1 -0
  9. package/dist/assets/HelpPage-DMfkzERp.js +1 -0
  10. package/dist/assets/IntegrationsPage-CrOitCmJ.js +1 -0
  11. package/dist/assets/MediaPage-CE5rdvkC.js +1 -0
  12. package/dist/assets/PlatformDashboard-Do6F0O2p.js +1 -0
  13. package/dist/assets/Playground-Fc5cdc5p.js +109 -0
  14. package/dist/assets/ProcessPanel-CslEiZkI.js +2 -0
  15. package/dist/assets/PromptsPage-D2EhsdNO.js +4 -0
  16. package/dist/assets/RunsPage-C5BZF5Rx.js +1 -0
  17. package/dist/assets/SandboxManager-a1AVI5q2.js +8 -0
  18. package/dist/assets/SettingsPage-DirhjQrJ.js +51 -0
  19. package/dist/assets/SocialMediaPage-DBuM28vD.js +1 -0
  20. package/dist/assets/TailscalePage-CHiFhZXF.js +1 -0
  21. package/dist/assets/TelephonyPage-x0VV0fOo.js +1 -0
  22. package/dist/assets/TerminalPage-Drwyrnfd.js +1 -0
  23. package/dist/assets/gemini-audio-t-TSU-To.js +17 -0
  24. package/dist/assets/gemini-live-client-C7rqAW7G.js +166 -0
  25. package/dist/assets/index-C8M_PUmX.css +32 -0
  26. package/dist/assets/index-CEqZnThB.js +204 -0
  27. package/dist/assets/sw-register-LSSpj6RU.js +1 -0
  28. package/dist/assets/time-ago-B6r_l9u1.js +1 -0
  29. package/dist/assets/workbox-window.prod.es5-BIl4cyR9.js +2 -0
  30. package/dist/favicon-32-original.png +0 -0
  31. package/dist/favicon-32.png +0 -0
  32. package/dist/favicon.ico +0 -0
  33. package/dist/favicon.svg +8 -0
  34. package/dist/fonts/MesloLGSNerdFontMono-Bold.woff2 +0 -0
  35. package/dist/fonts/MesloLGSNerdFontMono-Regular.woff2 +0 -0
  36. package/dist/heyhank-mascot-poster.png +0 -0
  37. package/dist/heyhank-mascot.mp4 +0 -0
  38. package/dist/heyhank-mascot.webm +0 -0
  39. package/dist/icon-192-original.png +0 -0
  40. package/dist/icon-192.png +0 -0
  41. package/dist/icon-512-original.png +0 -0
  42. package/dist/icon-512.png +0 -0
  43. package/dist/index.html +21 -0
  44. package/dist/logo-192.png +0 -0
  45. package/dist/logo-512.png +0 -0
  46. package/dist/logo-codex.svg +14 -0
  47. package/dist/logo-docker.svg +4 -0
  48. package/dist/logo-original.png +0 -0
  49. package/dist/logo.png +0 -0
  50. package/dist/logo.svg +14 -0
  51. package/dist/manifest.json +24 -0
  52. package/dist/push-sw.js +34 -0
  53. package/dist/sw.js +1 -0
  54. package/dist/workbox-d2a0910a.js +1 -0
  55. package/package.json +109 -0
  56. package/server/agent-cron-migrator.ts +85 -0
  57. package/server/agent-executor.ts +357 -0
  58. package/server/agent-store.ts +185 -0
  59. package/server/agent-timeout.ts +107 -0
  60. package/server/agent-types.ts +122 -0
  61. package/server/ai-validation-settings.ts +37 -0
  62. package/server/ai-validator.ts +181 -0
  63. package/server/anthropic-provider-migration.ts +48 -0
  64. package/server/assistant-store.ts +272 -0
  65. package/server/auth-manager.ts +150 -0
  66. package/server/auto-approve.ts +153 -0
  67. package/server/auto-namer.ts +36 -0
  68. package/server/backend-adapter.ts +54 -0
  69. package/server/cache-headers.ts +61 -0
  70. package/server/calendar-service.ts +434 -0
  71. package/server/claude-adapter.ts +889 -0
  72. package/server/claude-container-auth.ts +30 -0
  73. package/server/claude-session-discovery.ts +157 -0
  74. package/server/claude-session-history.ts +410 -0
  75. package/server/cli-launcher.ts +1303 -0
  76. package/server/codex-adapter.ts +3027 -0
  77. package/server/codex-container-auth.ts +24 -0
  78. package/server/codex-home.ts +27 -0
  79. package/server/codex-ws-proxy.cjs +226 -0
  80. package/server/commands-discovery.ts +81 -0
  81. package/server/constants.ts +7 -0
  82. package/server/container-manager.ts +1053 -0
  83. package/server/cost-tracker.ts +222 -0
  84. package/server/cron-scheduler.ts +243 -0
  85. package/server/cron-store.ts +148 -0
  86. package/server/cron-types.ts +63 -0
  87. package/server/email-service.ts +354 -0
  88. package/server/env-manager.ts +161 -0
  89. package/server/event-bus-types.ts +75 -0
  90. package/server/event-bus.ts +124 -0
  91. package/server/execution-store.ts +170 -0
  92. package/server/federation/node-connection.ts +190 -0
  93. package/server/federation/node-manager.ts +366 -0
  94. package/server/federation/node-store.ts +86 -0
  95. package/server/federation/node-types.ts +121 -0
  96. package/server/fs-utils.ts +15 -0
  97. package/server/git-utils.ts +421 -0
  98. package/server/github-pr.ts +379 -0
  99. package/server/google-media.ts +342 -0
  100. package/server/image-pull-manager.ts +279 -0
  101. package/server/index.ts +491 -0
  102. package/server/internal-ai.ts +237 -0
  103. package/server/kill-switch.ts +99 -0
  104. package/server/llm-providers.ts +342 -0
  105. package/server/logger.ts +259 -0
  106. package/server/mcp-registry.ts +401 -0
  107. package/server/message-bus.ts +271 -0
  108. package/server/message-delivery.ts +128 -0
  109. package/server/metrics-collector.ts +350 -0
  110. package/server/metrics-types.ts +108 -0
  111. package/server/middleware/managed-auth.ts +195 -0
  112. package/server/novnc-proxy.ts +99 -0
  113. package/server/path-resolver.ts +186 -0
  114. package/server/paths.ts +13 -0
  115. package/server/pr-poller.ts +162 -0
  116. package/server/prompt-manager.ts +211 -0
  117. package/server/protocol/claude-upstream/README.md +19 -0
  118. package/server/protocol/claude-upstream/sdk.d.ts.txt +1943 -0
  119. package/server/protocol/codex-upstream/ClientNotification.ts.txt +5 -0
  120. package/server/protocol/codex-upstream/ClientRequest.ts.txt +60 -0
  121. package/server/protocol/codex-upstream/README.md +18 -0
  122. package/server/protocol/codex-upstream/ServerNotification.ts.txt +41 -0
  123. package/server/protocol/codex-upstream/ServerRequest.ts.txt +16 -0
  124. package/server/protocol/codex-upstream/v2/DynamicToolCallParams.ts.txt +6 -0
  125. package/server/protocol/codex-upstream/v2/DynamicToolCallResponse.ts.txt +6 -0
  126. package/server/protocol-monitor.ts +50 -0
  127. package/server/provider-manager.ts +111 -0
  128. package/server/provider-registry.ts +393 -0
  129. package/server/push-notifications.ts +221 -0
  130. package/server/recorder.ts +374 -0
  131. package/server/recording-hub/compat-validator.ts +284 -0
  132. package/server/recording-hub/diagnostics.ts +299 -0
  133. package/server/recording-hub/hub-config.ts +19 -0
  134. package/server/recording-hub/hub-routes.ts +236 -0
  135. package/server/recording-hub/hub-store.ts +265 -0
  136. package/server/recording-hub/replay-adapter.ts +207 -0
  137. package/server/relay-client.ts +320 -0
  138. package/server/reminder-scheduler.ts +38 -0
  139. package/server/replay.ts +78 -0
  140. package/server/routes/agent-routes.ts +264 -0
  141. package/server/routes/assistant-routes.ts +90 -0
  142. package/server/routes/cron-routes.ts +103 -0
  143. package/server/routes/env-routes.ts +95 -0
  144. package/server/routes/federation-routes.ts +76 -0
  145. package/server/routes/fs-routes.ts +622 -0
  146. package/server/routes/git-routes.ts +97 -0
  147. package/server/routes/llm-routes.ts +166 -0
  148. package/server/routes/media-routes.ts +135 -0
  149. package/server/routes/metrics-routes.ts +13 -0
  150. package/server/routes/platform-routes.ts +1379 -0
  151. package/server/routes/prompt-routes.ts +67 -0
  152. package/server/routes/provider-routes.ts +109 -0
  153. package/server/routes/sandbox-routes.ts +127 -0
  154. package/server/routes/settings-routes.ts +285 -0
  155. package/server/routes/skills-routes.ts +100 -0
  156. package/server/routes/socialmedia-routes.ts +208 -0
  157. package/server/routes/system-routes.ts +228 -0
  158. package/server/routes/tailscale-routes.ts +22 -0
  159. package/server/routes/telephony-routes.ts +259 -0
  160. package/server/routes.ts +1379 -0
  161. package/server/sandbox-manager.ts +168 -0
  162. package/server/service.ts +718 -0
  163. package/server/session-creation-service.ts +457 -0
  164. package/server/session-git-info.ts +104 -0
  165. package/server/session-names.ts +67 -0
  166. package/server/session-orchestrator.ts +824 -0
  167. package/server/session-state-machine.ts +207 -0
  168. package/server/session-store.ts +146 -0
  169. package/server/session-types.ts +511 -0
  170. package/server/settings-manager.ts +149 -0
  171. package/server/shared-context.ts +157 -0
  172. package/server/socialmedia/adapter.ts +15 -0
  173. package/server/socialmedia/adapters/ayrshare-adapter.ts +169 -0
  174. package/server/socialmedia/adapters/buffer-adapter.ts +299 -0
  175. package/server/socialmedia/adapters/postiz-adapter.ts +298 -0
  176. package/server/socialmedia/manager.ts +227 -0
  177. package/server/socialmedia/store.ts +98 -0
  178. package/server/socialmedia/types.ts +89 -0
  179. package/server/tailscale-manager.ts +451 -0
  180. package/server/telephony/audio-bridge.ts +331 -0
  181. package/server/telephony/call-manager.ts +457 -0
  182. package/server/telephony/call-types.ts +108 -0
  183. package/server/telephony/telephony-store.ts +119 -0
  184. package/server/terminal-manager.ts +240 -0
  185. package/server/update-checker.ts +192 -0
  186. package/server/usage-limits.ts +225 -0
  187. package/server/web-push.d.ts +51 -0
  188. package/server/worktree-tracker.ts +84 -0
  189. package/server/ws-auth.ts +41 -0
  190. package/server/ws-bridge-browser-ingest.ts +72 -0
  191. package/server/ws-bridge-browser.ts +112 -0
  192. package/server/ws-bridge-cli-ingest.ts +81 -0
  193. package/server/ws-bridge-codex.ts +266 -0
  194. package/server/ws-bridge-controls.ts +20 -0
  195. package/server/ws-bridge-persist.ts +66 -0
  196. package/server/ws-bridge-publish.ts +79 -0
  197. package/server/ws-bridge-replay.ts +61 -0
  198. package/server/ws-bridge-types.ts +121 -0
  199. package/server/ws-bridge.ts +1240 -0
@@ -0,0 +1,168 @@
1
+ import {
2
+ mkdirSync,
3
+ readdirSync,
4
+ readFileSync,
5
+ writeFileSync,
6
+ unlinkSync,
7
+ existsSync,
8
+ } from "node:fs";
9
+ import { join } from "node:path";
10
+ import { homedir } from "node:os";
11
+
12
+ // ─── Types ──────────────────────────────────────────────────────────────────
13
+
14
+ export interface HeyHankSandbox {
15
+ name: string;
16
+ slug: string;
17
+ /** Shell script to run inside the container before the CLI session starts */
18
+ initScript?: string;
19
+ createdAt: number;
20
+ updatedAt: number;
21
+ }
22
+
23
+ /** Fields that can be updated via the update API */
24
+ export interface SandboxUpdateFields {
25
+ name?: string;
26
+ initScript?: string;
27
+ }
28
+
29
+ // ─── Paths ──────────────────────────────────────────────────────────────────
30
+
31
+ const HEYHANK_DIR = join(homedir(), ".heyhank");
32
+ const SANDBOXES_DIR = join(HEYHANK_DIR, "sandboxes");
33
+
34
+ function ensureDir(): void {
35
+ mkdirSync(SANDBOXES_DIR, { recursive: true });
36
+ }
37
+
38
+ /** Validate that a slug contains only safe characters (prevents path traversal) */
39
+ function validateSlug(slug: string): void {
40
+ if (!/^[a-z0-9-]+$/.test(slug)) {
41
+ throw new Error("Invalid slug: must contain only lowercase alphanumeric characters and hyphens");
42
+ }
43
+ }
44
+
45
+ function filePath(slug: string): string {
46
+ validateSlug(slug);
47
+ return join(SANDBOXES_DIR, `${slug}.json`);
48
+ }
49
+
50
+ // ─── Helpers ────────────────────────────────────────────────────────────────
51
+
52
+ function slugify(name: string): string {
53
+ return name
54
+ .toLowerCase()
55
+ .replace(/\s+/g, "-")
56
+ .replace(/[^a-z0-9-]/g, "")
57
+ .replace(/-+/g, "-")
58
+ .replace(/^-|-$/g, "");
59
+ }
60
+
61
+ // ─── CRUD ───────────────────────────────────────────────────────────────────
62
+
63
+ export function listSandboxes(): HeyHankSandbox[] {
64
+ ensureDir();
65
+ try {
66
+ const files = readdirSync(SANDBOXES_DIR).filter((f) => f.endsWith(".json"));
67
+ const sandboxes: HeyHankSandbox[] = [];
68
+ for (const file of files) {
69
+ try {
70
+ const raw = readFileSync(join(SANDBOXES_DIR, file), "utf-8");
71
+ sandboxes.push(JSON.parse(raw));
72
+ } catch {
73
+ // Skip corrupt files
74
+ }
75
+ }
76
+ sandboxes.sort((a, b) => a.name.localeCompare(b.name));
77
+ return sandboxes;
78
+ } catch {
79
+ return [];
80
+ }
81
+ }
82
+
83
+ export function getSandbox(slug: string): HeyHankSandbox | null {
84
+ ensureDir();
85
+ try {
86
+ const raw = readFileSync(filePath(slug), "utf-8");
87
+ return JSON.parse(raw) as HeyHankSandbox;
88
+ } catch {
89
+ return null;
90
+ }
91
+ }
92
+
93
+ export function createSandbox(
94
+ name: string,
95
+ opts?: { initScript?: string },
96
+ ): HeyHankSandbox {
97
+ if (!name || !name.trim()) throw new Error("Sandbox name is required");
98
+ const slug = slugify(name.trim());
99
+ if (!slug) throw new Error("Sandbox name must contain alphanumeric characters");
100
+
101
+ ensureDir();
102
+ if (existsSync(filePath(slug))) {
103
+ throw new Error(`A sandbox with a similar name already exists ("${slug}")`);
104
+ }
105
+
106
+ const now = Date.now();
107
+ const sandbox: HeyHankSandbox = {
108
+ name: name.trim(),
109
+ slug,
110
+ createdAt: now,
111
+ updatedAt: now,
112
+ };
113
+
114
+ // Apply optional fields if provided
115
+ if (opts) {
116
+ if (opts.initScript !== undefined) sandbox.initScript = opts.initScript;
117
+ }
118
+
119
+ writeFileSync(filePath(slug), JSON.stringify(sandbox, null, 2), "utf-8");
120
+ return sandbox;
121
+ }
122
+
123
+ export function updateSandbox(
124
+ slug: string,
125
+ updates: SandboxUpdateFields,
126
+ ): HeyHankSandbox | null {
127
+ ensureDir();
128
+ const existing = getSandbox(slug);
129
+ if (!existing) return null;
130
+
131
+ const newName = updates.name?.trim() || existing.name;
132
+ const newSlug = slugify(newName);
133
+ if (!newSlug) throw new Error("Sandbox name must contain alphanumeric characters");
134
+
135
+ // If name changed, check for slug collision with a different sandbox
136
+ if (newSlug !== slug && existsSync(filePath(newSlug))) {
137
+ throw new Error(`A sandbox with a similar name already exists ("${newSlug}")`);
138
+ }
139
+
140
+ const sandbox: HeyHankSandbox = {
141
+ ...existing,
142
+ name: newName,
143
+ slug: newSlug,
144
+ updatedAt: Date.now(),
145
+ };
146
+
147
+ // Apply field updates (only override if explicitly provided)
148
+ if (updates.initScript !== undefined) sandbox.initScript = updates.initScript;
149
+
150
+ // If slug changed, delete old file
151
+ if (newSlug !== slug) {
152
+ try { unlinkSync(filePath(slug)); } catch { /* ok */ }
153
+ }
154
+
155
+ writeFileSync(filePath(newSlug), JSON.stringify(sandbox, null, 2), "utf-8");
156
+ return sandbox;
157
+ }
158
+
159
+ export function deleteSandbox(slug: string): boolean {
160
+ ensureDir();
161
+ if (!existsSync(filePath(slug))) return false;
162
+ try {
163
+ unlinkSync(filePath(slug));
164
+ return true;
165
+ } catch {
166
+ return false;
167
+ }
168
+ }