heyhank 0.1.0 → 0.3.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.
- package/LICENSE +21 -0
- package/README.md +83 -10
- package/bin/cli.ts +7 -7
- package/bin/ctl.ts +42 -42
- package/dist/assets/{AgentsPage-BPhirnCe.js → AgentsPage-DqjDAcIw.js} +3 -3
- package/dist/assets/AssistantPage-C50CQFSB.js +2 -0
- package/dist/assets/BusinessPage-AY70tf1k.js +1 -0
- package/dist/assets/{CronManager-DDbz-yiT.js → CronManager-Dt7LLuRr.js} +1 -1
- package/dist/assets/HelpPage-tlGx7fQF.js +1 -0
- package/dist/assets/{IntegrationsPage-CrOitCmJ.js → IntegrationsPage-B4XOuHXu.js} +1 -1
- package/dist/assets/JarvisHUD-BDvuRd0I.js +120 -0
- package/dist/assets/MediaPage-CofV9Rd-.js +1 -0
- package/dist/assets/MemoryPage-Cj7FeqmJ.js +1 -0
- package/dist/assets/{PlatformDashboard-Do6F0O2p.js → PlatformDashboard-B9kXAlH1.js} +1 -1
- package/dist/assets/{Playground-Fc5cdc5p.js → Playground-Cka-pRkP.js} +1 -1
- package/dist/assets/{ProcessPanel-CslEiZkI.js → ProcessPanel-BqhQgfYj.js} +1 -1
- package/dist/assets/{PromptsPage-D2EhsdNO.js → PromptsPage-VveKc9uX.js} +2 -2
- package/dist/assets/RunsPage-DXVEk0AZ.js +1 -0
- package/dist/assets/{SandboxManager-a1AVI5q2.js → SandboxManager-DACcwfDF.js} +1 -1
- package/dist/assets/SettingsPage-jfuQh8Tu.js +51 -0
- package/dist/assets/SkillsMarketplace-DrigiApe.js +1 -0
- package/dist/assets/SocialMediaPage-DOh3IPe8.js +10 -0
- package/dist/assets/{TailscalePage-CHiFhZXF.js → TailscalePage-DLhJWATT.js} +1 -1
- package/dist/assets/TelephonyPage-9C4C3_ot.js +9 -0
- package/dist/assets/{TerminalPage-Drwyrnfd.js → TerminalPage-ChX-8Wu7.js} +1 -1
- package/dist/assets/{gemini-live-client-C7rqAW7G.js → gemini-live-client-C70FEtX2.js} +11 -8
- package/dist/assets/index-C6Q5UQHD.js +229 -0
- package/dist/assets/index-ZxGXgiV3.css +32 -0
- package/dist/assets/sw-register-BBYuk-kw.js +1 -0
- package/dist/assets/text-chat-client-BSbLJerZ.js +2 -0
- package/dist/assets/workbox-window.prod.es5-BBnX5xw4.js +2 -0
- package/dist/index.html +2 -2
- package/dist/sw.js +1 -1
- package/dist/{workbox-d2a0910a.js → workbox-080c8b91.js} +1 -1
- package/package.json +6 -1
- package/server/agent-executor.ts +102 -2
- package/server/agent-store.ts +3 -3
- package/server/agent-types.ts +11 -0
- package/server/assistant-store.ts +232 -6
- package/server/auth-manager.ts +9 -0
- package/server/cache-headers.ts +1 -1
- package/server/calendar-service.ts +10 -0
- package/server/ceo/document-store.ts +129 -0
- package/server/ceo/finance-store.ts +343 -0
- package/server/ceo/kpi-store.ts +208 -0
- package/server/ceo/memory-import.ts +277 -0
- package/server/ceo/news-store.ts +208 -0
- package/server/ceo/template-store.ts +134 -0
- package/server/ceo/time-tracking-store.ts +227 -0
- package/server/claude-auth-monitor.ts +128 -0
- package/server/claude-code-worker.ts +86 -0
- package/server/claude-session-discovery.ts +74 -1
- package/server/cli-launcher.ts +32 -10
- package/server/codex-adapter.ts +2 -2
- package/server/codex-ws-proxy.cjs +1 -1
- package/server/container-manager.ts +4 -4
- package/server/content-intelligence/content-engine.ts +1112 -0
- package/server/content-intelligence/platform-knowledge.ts +870 -0
- package/server/cron-store.ts +3 -3
- package/server/embedding-service.ts +49 -0
- package/server/event-bus-types.ts +13 -0
- package/server/execution-store.ts +54 -1
- package/server/federation/node-store.ts +5 -4
- package/server/fs-utils.ts +28 -1
- package/server/hank-notifications-store.ts +91 -0
- package/server/hank-tool-executor.ts +1835 -0
- package/server/hank-tools.ts +2107 -0
- package/server/image-pull-manager.ts +2 -2
- package/server/index.ts +25 -2
- package/server/llm-providers-streaming.ts +541 -0
- package/server/llm-providers.ts +12 -0
- package/server/marketplace.ts +249 -0
- package/server/mcp-registry.ts +158 -0
- package/server/memory-service.ts +296 -0
- package/server/obsidian-sync.ts +184 -0
- package/server/provider-manager.ts +5 -2
- package/server/provider-registry.ts +12 -0
- package/server/reminder-scheduler.ts +37 -1
- package/server/routes/agent-routes.ts +44 -1
- package/server/routes/assistant-routes.ts +198 -5
- package/server/routes/ceo-finance-kpi-routes.ts +167 -0
- package/server/routes/ceo-news-time-routes.ts +137 -0
- package/server/routes/ceo-routes.ts +99 -0
- package/server/routes/content-routes.ts +116 -0
- package/server/routes/email-routes.ts +147 -0
- package/server/routes/env-routes.ts +3 -3
- package/server/routes/fs-routes.ts +12 -9
- package/server/routes/hank-chat-routes.ts +592 -0
- package/server/routes/llm-routes.ts +12 -0
- package/server/routes/marketplace-routes.ts +63 -0
- package/server/routes/media-routes.ts +1 -1
- package/server/routes/memory-routes.ts +127 -0
- package/server/routes/platform-routes.ts +14 -675
- package/server/routes/sandbox-routes.ts +1 -1
- package/server/routes/settings-routes.ts +51 -1
- package/server/routes/socialmedia-routes.ts +152 -2
- package/server/routes/system-routes.ts +2 -2
- package/server/routes/team-routes.ts +71 -0
- package/server/routes/telephony-routes.ts +98 -18
- package/server/routes.ts +36 -9
- package/server/session-creation-service.ts +2 -2
- package/server/session-orchestrator.ts +54 -2
- package/server/session-types.ts +2 -0
- package/server/settings-manager.ts +50 -2
- package/server/skill-discovery.ts +68 -0
- package/server/socialmedia/adapters/browser-adapter.ts +179 -0
- package/server/socialmedia/adapters/postiz-adapter.ts +291 -14
- package/server/socialmedia/manager.ts +234 -15
- package/server/socialmedia/store.ts +51 -1
- package/server/socialmedia/types.ts +35 -2
- package/server/socialview/browser-manager.ts +150 -0
- package/server/socialview/extractors.ts +1298 -0
- package/server/socialview/image-describe.ts +188 -0
- package/server/socialview/library.ts +119 -0
- package/server/socialview/poster.ts +276 -0
- package/server/socialview/routes.ts +371 -0
- package/server/socialview/style-analyzer.ts +187 -0
- package/server/socialview/style-profiles.ts +67 -0
- package/server/socialview/types.ts +166 -0
- package/server/socialview/vision.ts +127 -0
- package/server/socialview/vnc-manager.ts +110 -0
- package/server/style-injector.ts +135 -0
- package/server/team-service.ts +239 -0
- package/server/team-store.ts +75 -0
- package/server/team-types.ts +52 -0
- package/server/telephony/audio-bridge.ts +281 -35
- package/server/telephony/audio-recorder.ts +132 -0
- package/server/telephony/call-manager.ts +803 -104
- package/server/telephony/call-types.ts +67 -1
- package/server/telephony/esl-client.ts +319 -0
- package/server/telephony/freeswitch-sync.ts +155 -0
- package/server/telephony/phone-utils.ts +63 -0
- package/server/telephony/telephony-store.ts +9 -8
- package/server/url-validator.ts +82 -0
- package/server/vault-markdown.ts +317 -0
- package/server/vault-migration.ts +121 -0
- package/server/vault-store.ts +466 -0
- package/server/vault-watcher.ts +59 -0
- package/server/vector-store.ts +210 -0
- package/server/voice-pipeline/gemini-live-adapter.ts +97 -0
- package/server/voice-pipeline/greeting-cache.ts +200 -0
- package/server/voice-pipeline/manager.ts +249 -0
- package/server/voice-pipeline/pipeline.ts +335 -0
- package/server/voice-pipeline/providers/index.ts +47 -0
- package/server/voice-pipeline/providers/llm-internal.ts +527 -0
- package/server/voice-pipeline/providers/stt-google.ts +157 -0
- package/server/voice-pipeline/providers/tts-google.ts +126 -0
- package/server/voice-pipeline/types.ts +247 -0
- package/server/ws-bridge-types.ts +6 -1
- package/dist/assets/AssistantPage-DJ-cMQfb.js +0 -1
- package/dist/assets/HelpPage-DMfkzERp.js +0 -1
- package/dist/assets/MediaPage-CE5rdvkC.js +0 -1
- package/dist/assets/RunsPage-C5BZF5Rx.js +0 -1
- package/dist/assets/SettingsPage-DirhjQrJ.js +0 -51
- package/dist/assets/SocialMediaPage-DBuM28vD.js +0 -1
- package/dist/assets/TelephonyPage-x0VV0fOo.js +0 -1
- package/dist/assets/index-C8M_PUmX.css +0 -32
- package/dist/assets/index-CEqZnThB.js +0 -204
- package/dist/assets/sw-register-LSSpj6RU.js +0 -1
- package/dist/assets/workbox-window.prod.es5-BIl4cyR9.js +0 -2
- package/server/socialmedia/adapters/ayrshare-adapter.ts +0 -169
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 The Vibe Company
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,26 +1,37 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="public/logo.svg" alt="HeyHank" width="80" />
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
<h1 align="center">HeyHank</h1>
|
|
6
|
+
<p align="center"><strong>Self-hosted web UI for running Claude Code and Codex agents.</strong></p>
|
|
7
|
+
<p align="center">Multi-session management with streaming, tool call visibility, and permission control.</p>
|
|
4
8
|
|
|
5
|
-
|
|
9
|
+
<p align="center">
|
|
10
|
+
<a href="https://www.npmjs.com/package/heyhank"><img src="https://img.shields.io/npm/v/heyhank.svg" alt="npm version" /></a>
|
|
11
|
+
<a href="https://www.npmjs.com/package/heyhank"><img src="https://img.shields.io/npm/dm/heyhank.svg" alt="npm downloads" /></a>
|
|
12
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="MIT License" /></a>
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
**Requirements:** [Bun](https://bun.sh) v1.0+ and [Claude Code](https://docs.anthropic.com/en/docs/claude-code) and/or [Codex](https://github.com/openai/codex) CLI.
|
|
6
18
|
|
|
7
19
|
```bash
|
|
8
20
|
bunx heyhank
|
|
9
21
|
```
|
|
10
22
|
|
|
11
|
-
|
|
23
|
+
Open [http://localhost:3456](http://localhost:3456).
|
|
12
24
|
|
|
13
|
-
|
|
25
|
+
### Install Globally
|
|
14
26
|
|
|
15
27
|
```bash
|
|
16
|
-
|
|
17
|
-
heyhank serve
|
|
28
|
+
bun install -g heyhank
|
|
18
29
|
|
|
19
|
-
#
|
|
30
|
+
# Register as a background service (launchd on macOS, systemd on Linux)
|
|
20
31
|
heyhank install
|
|
21
32
|
|
|
22
|
-
#
|
|
23
|
-
heyhank
|
|
33
|
+
# Start the service
|
|
34
|
+
heyhank start
|
|
24
35
|
```
|
|
25
36
|
|
|
26
37
|
## Features
|
|
@@ -30,11 +41,73 @@ heyhank status
|
|
|
30
41
|
- **Scheduled Agents** — Cron-based agent automation
|
|
31
42
|
- **Media Generation** — Image (Imagen 4) and video (Veo 3.1) generation
|
|
32
43
|
- **Social Media** — Multi-backend posting (Postiz, Buffer, Ayrshare)
|
|
44
|
+
- **Email Integration** — Multi-account IMAP/SMTP email via UI and voice
|
|
33
45
|
- **Telephony** — Voice calls via FreeSWITCH SIP integration
|
|
46
|
+
- **Personal Assistant** — Todos, notes, and reminders managed by voice or UI
|
|
34
47
|
- **Federation** — Connect multiple HeyHank instances across machines
|
|
35
48
|
- **Tailscale Funnel** — Public HTTPS access without port forwarding
|
|
36
49
|
- **PWA** — Installable on mobile and desktop
|
|
37
50
|
|
|
51
|
+
## CLI Commands
|
|
52
|
+
|
|
53
|
+
| Command | Description |
|
|
54
|
+
|---|---|
|
|
55
|
+
| `heyhank` | Start server in foreground (default) |
|
|
56
|
+
| `heyhank serve` | Start server in foreground (explicit) |
|
|
57
|
+
| `heyhank install` | Register as a background service (launchd/systemd) |
|
|
58
|
+
| `heyhank start` | Start the background service |
|
|
59
|
+
| `heyhank stop` | Stop the background service |
|
|
60
|
+
| `heyhank restart` | Restart the background service |
|
|
61
|
+
| `heyhank uninstall` | Remove the background service |
|
|
62
|
+
| `heyhank status` | Show service status |
|
|
63
|
+
| `heyhank logs` | Tail service log files |
|
|
64
|
+
|
|
65
|
+
**Options:** `--port <n>` overrides the default port (3456).
|
|
66
|
+
|
|
67
|
+
## Architecture
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
Browser (React)
|
|
71
|
+
<-> ws://localhost:3456/ws/browser/:session
|
|
72
|
+
HeyHank Server (Bun + Hono)
|
|
73
|
+
<-> ws://localhost:3456/ws/cli/:session
|
|
74
|
+
Claude Code / Codex CLI
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The server bridges the CLI's `--sdk-url` WebSocket (NDJSON) to a browser-friendly WebSocket.
|
|
78
|
+
|
|
79
|
+
## Authentication
|
|
80
|
+
|
|
81
|
+
The server auto-generates an auth token on first start, stored at `~/.heyhank/auth.json`.
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# Show the current token
|
|
85
|
+
bun run generate-token
|
|
86
|
+
|
|
87
|
+
# Force-regenerate a new token
|
|
88
|
+
bun run generate-token --force
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Or set via environment variable:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
HEYHANK_AUTH_TOKEN="my-secret-token" bunx heyhank
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Development
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
bun install
|
|
101
|
+
bun run dev
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Checks:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
bun run typecheck
|
|
108
|
+
bun run test
|
|
109
|
+
```
|
|
110
|
+
|
|
38
111
|
## License
|
|
39
112
|
|
|
40
113
|
MIT
|
package/bin/cli.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { fileURLToPath } from "node:url";
|
|
|
4
4
|
|
|
5
5
|
// Package root so the server can find dist/ regardless of CWD
|
|
6
6
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
-
process.env.
|
|
7
|
+
process.env.__HEYHANK_PACKAGE_ROOT = resolve(__dirname, "..");
|
|
8
8
|
|
|
9
9
|
const command = process.argv[2];
|
|
10
10
|
|
|
@@ -25,7 +25,7 @@ Server commands:
|
|
|
25
25
|
stop Stop the background service
|
|
26
26
|
restart Restart the background service
|
|
27
27
|
uninstall Remove the background service
|
|
28
|
-
status Show service status (or use '
|
|
28
|
+
status Show service status (or use 'heyhank status' when server is running)
|
|
29
29
|
logs Tail service log files
|
|
30
30
|
help Show this help message
|
|
31
31
|
|
|
@@ -35,7 +35,7 @@ Management commands (requires running server):
|
|
|
35
35
|
cron Manage scheduled jobs (list, get, create, update, delete, toggle, run)
|
|
36
36
|
skills Manage Claude Code skills (list, get, create, update, delete)
|
|
37
37
|
settings Manage settings (get, set)
|
|
38
|
-
assistant Manage the
|
|
38
|
+
assistant Manage the HeyHank Assistant (status, launch, stop, config)
|
|
39
39
|
|
|
40
40
|
Options:
|
|
41
41
|
--port <n> Override the default port (default: 3456)
|
|
@@ -105,13 +105,13 @@ switch (command) {
|
|
|
105
105
|
const { status } = await import("../server/service.js");
|
|
106
106
|
const result = await status();
|
|
107
107
|
if (!result.installed) {
|
|
108
|
-
console.log("
|
|
109
|
-
console.log("Run:
|
|
108
|
+
console.log("HeyHank is not installed as a service.");
|
|
109
|
+
console.log("Run: heyhank install");
|
|
110
110
|
} else if (result.running) {
|
|
111
|
-
console.log(`
|
|
111
|
+
console.log(`HeyHank is running (PID: ${result.pid})`);
|
|
112
112
|
console.log(` URL: http://localhost:${result.port}`);
|
|
113
113
|
} else {
|
|
114
|
-
console.log("
|
|
114
|
+
console.log("HeyHank is installed but not running.");
|
|
115
115
|
console.log("Check logs at ~/.heyhank/logs/");
|
|
116
116
|
}
|
|
117
117
|
}
|
package/bin/ctl.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
/**
|
|
3
|
-
* CLI handler module for `
|
|
4
|
-
* Each subcommand maps 1:1 to a
|
|
3
|
+
* CLI handler module for `heyhank` management subcommands.
|
|
4
|
+
* Each subcommand maps 1:1 to a HeyHank REST API endpoint.
|
|
5
5
|
* All output is JSON to stdout for easy parsing by both humans and AI agents.
|
|
6
6
|
*/
|
|
7
7
|
|
|
@@ -13,7 +13,7 @@ function getPort(argv: string[]): number {
|
|
|
13
13
|
const p = Number(argv[idx + 1]);
|
|
14
14
|
if (!Number.isNaN(p) && p > 0) return p;
|
|
15
15
|
}
|
|
16
|
-
return Number(process.env.COMPANION_PORT) || DEFAULT_PORT;
|
|
16
|
+
return Number(process.env.HEYHANK_PORT || process.env.COMPANION_PORT) || DEFAULT_PORT;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
function getBase(argv: string[]): string {
|
|
@@ -175,7 +175,7 @@ async function handleSessions(base: string, args: string[]): Promise<void> {
|
|
|
175
175
|
}
|
|
176
176
|
case "get": {
|
|
177
177
|
const id = rest[0];
|
|
178
|
-
if (!id) err("Usage:
|
|
178
|
+
if (!id) err("Usage: heyhank sessions get <sessionId>");
|
|
179
179
|
out(await apiGet(base, `/sessions/${encodeURIComponent(id)}`));
|
|
180
180
|
break;
|
|
181
181
|
}
|
|
@@ -195,33 +195,33 @@ async function handleSessions(base: string, args: string[]): Promise<void> {
|
|
|
195
195
|
}
|
|
196
196
|
case "kill": {
|
|
197
197
|
const id = rest[0];
|
|
198
|
-
if (!id) err("Usage:
|
|
198
|
+
if (!id) err("Usage: heyhank sessions kill <sessionId>");
|
|
199
199
|
out(await apiPost(base, `/sessions/${encodeURIComponent(id)}/kill`));
|
|
200
200
|
break;
|
|
201
201
|
}
|
|
202
202
|
case "relaunch": {
|
|
203
203
|
const id = rest[0];
|
|
204
|
-
if (!id) err("Usage:
|
|
204
|
+
if (!id) err("Usage: heyhank sessions relaunch <sessionId>");
|
|
205
205
|
out(await apiPost(base, `/sessions/${encodeURIComponent(id)}/relaunch`));
|
|
206
206
|
break;
|
|
207
207
|
}
|
|
208
208
|
case "archive": {
|
|
209
209
|
const id = rest[0];
|
|
210
|
-
if (!id) err("Usage:
|
|
210
|
+
if (!id) err("Usage: heyhank sessions archive <sessionId>");
|
|
211
211
|
out(await apiPost(base, `/sessions/${encodeURIComponent(id)}/archive`));
|
|
212
212
|
break;
|
|
213
213
|
}
|
|
214
214
|
case "rename": {
|
|
215
215
|
const id = rest[0];
|
|
216
216
|
const name = rest.slice(1).join(" ");
|
|
217
|
-
if (!id || !name) err("Usage:
|
|
217
|
+
if (!id || !name) err("Usage: heyhank sessions rename <sessionId> <name>");
|
|
218
218
|
out(await apiPatch(base, `/sessions/${encodeURIComponent(id)}/name`, { name }));
|
|
219
219
|
break;
|
|
220
220
|
}
|
|
221
221
|
case "send-message": {
|
|
222
222
|
const id = rest[0];
|
|
223
223
|
const content = rest.slice(1).join(" ");
|
|
224
|
-
if (!id || !content) err("Usage:
|
|
224
|
+
if (!id || !content) err("Usage: heyhank sessions send-message <sessionId> <message>");
|
|
225
225
|
out(await apiPost(base, `/sessions/${encodeURIComponent(id)}/message`, { content }));
|
|
226
226
|
break;
|
|
227
227
|
}
|
|
@@ -241,20 +241,20 @@ async function handleEnvs(base: string, args: string[]): Promise<void> {
|
|
|
241
241
|
}
|
|
242
242
|
case "get": {
|
|
243
243
|
const slug = rest[0];
|
|
244
|
-
if (!slug) err("Usage:
|
|
244
|
+
if (!slug) err("Usage: heyhank envs get <slug>");
|
|
245
245
|
out(await apiGet(base, `/envs/${encodeURIComponent(slug)}`));
|
|
246
246
|
break;
|
|
247
247
|
}
|
|
248
248
|
case "create": {
|
|
249
249
|
const flags = parseFlags(rest);
|
|
250
250
|
const vars = parseVars(rest);
|
|
251
|
-
if (!flags.name) err("Usage:
|
|
251
|
+
if (!flags.name) err("Usage: heyhank envs create --name <name> [--var KEY=VALUE ...]");
|
|
252
252
|
out(await apiPost(base, "/envs", { name: flags.name, variables: vars }));
|
|
253
253
|
break;
|
|
254
254
|
}
|
|
255
255
|
case "update": {
|
|
256
256
|
const slug = rest[0];
|
|
257
|
-
if (!slug) err("Usage:
|
|
257
|
+
if (!slug) err("Usage: heyhank envs update <slug> [--name <name>] [--var KEY=VALUE ...]");
|
|
258
258
|
const flagArgs = rest.slice(1);
|
|
259
259
|
const flags = parseFlags(flagArgs);
|
|
260
260
|
const vars = parseVars(flagArgs);
|
|
@@ -266,7 +266,7 @@ async function handleEnvs(base: string, args: string[]): Promise<void> {
|
|
|
266
266
|
}
|
|
267
267
|
case "delete": {
|
|
268
268
|
const slug = rest[0];
|
|
269
|
-
if (!slug) err("Usage:
|
|
269
|
+
if (!slug) err("Usage: heyhank envs delete <slug>");
|
|
270
270
|
out(await apiDelete(base, `/envs/${encodeURIComponent(slug)}`));
|
|
271
271
|
break;
|
|
272
272
|
}
|
|
@@ -286,14 +286,14 @@ async function handleCron(base: string, args: string[]): Promise<void> {
|
|
|
286
286
|
}
|
|
287
287
|
case "get": {
|
|
288
288
|
const id = rest[0];
|
|
289
|
-
if (!id) err("Usage:
|
|
289
|
+
if (!id) err("Usage: heyhank cron get <jobId>");
|
|
290
290
|
out(await apiGet(base, `/cron/jobs/${encodeURIComponent(id)}`));
|
|
291
291
|
break;
|
|
292
292
|
}
|
|
293
293
|
case "create": {
|
|
294
294
|
const flags = parseFlags(rest);
|
|
295
295
|
if (!flags.name || !flags.schedule || !flags.prompt)
|
|
296
|
-
err("Usage:
|
|
296
|
+
err("Usage: heyhank cron create --name <name> --schedule <cron|datetime> --prompt <prompt> [--cwd <path>] [--model <model>] [--env <slug>] [--recurring] [--backend <type>] [--permission-mode <mode>]");
|
|
297
297
|
const body: Record<string, unknown> = {
|
|
298
298
|
name: flags.name,
|
|
299
299
|
schedule: flags.schedule,
|
|
@@ -312,7 +312,7 @@ async function handleCron(base: string, args: string[]): Promise<void> {
|
|
|
312
312
|
}
|
|
313
313
|
case "update": {
|
|
314
314
|
const id = rest[0];
|
|
315
|
-
if (!id) err("Usage:
|
|
315
|
+
if (!id) err("Usage: heyhank cron update <jobId> [--name <n>] [--schedule <s>] [--prompt <p>] ...");
|
|
316
316
|
const flagArgs = rest.slice(1);
|
|
317
317
|
const flags = parseFlags(flagArgs);
|
|
318
318
|
const body: Record<string, unknown> = {};
|
|
@@ -330,25 +330,25 @@ async function handleCron(base: string, args: string[]): Promise<void> {
|
|
|
330
330
|
}
|
|
331
331
|
case "delete": {
|
|
332
332
|
const id = rest[0];
|
|
333
|
-
if (!id) err("Usage:
|
|
333
|
+
if (!id) err("Usage: heyhank cron delete <jobId>");
|
|
334
334
|
out(await apiDelete(base, `/cron/jobs/${encodeURIComponent(id)}`));
|
|
335
335
|
break;
|
|
336
336
|
}
|
|
337
337
|
case "toggle": {
|
|
338
338
|
const id = rest[0];
|
|
339
|
-
if (!id) err("Usage:
|
|
339
|
+
if (!id) err("Usage: heyhank cron toggle <jobId>");
|
|
340
340
|
out(await apiPost(base, `/cron/jobs/${encodeURIComponent(id)}/toggle`));
|
|
341
341
|
break;
|
|
342
342
|
}
|
|
343
343
|
case "run": {
|
|
344
344
|
const id = rest[0];
|
|
345
|
-
if (!id) err("Usage:
|
|
345
|
+
if (!id) err("Usage: heyhank cron run <jobId>");
|
|
346
346
|
out(await apiPost(base, `/cron/jobs/${encodeURIComponent(id)}/run`));
|
|
347
347
|
break;
|
|
348
348
|
}
|
|
349
349
|
case "executions": {
|
|
350
350
|
const id = rest[0];
|
|
351
|
-
if (!id) err("Usage:
|
|
351
|
+
if (!id) err("Usage: heyhank cron executions <jobId>");
|
|
352
352
|
out(await apiGet(base, `/cron/jobs/${encodeURIComponent(id)}/executions`));
|
|
353
353
|
break;
|
|
354
354
|
}
|
|
@@ -370,7 +370,7 @@ async function handleSettings(base: string, args: string[]): Promise<void> {
|
|
|
370
370
|
const body: Record<string, unknown> = {};
|
|
371
371
|
if (flags["anthropic-key"]) body.anthropicApiKey = flags["anthropic-key"];
|
|
372
372
|
if (flags["anthropic-model"]) body.anthropicModel = flags["anthropic-model"];
|
|
373
|
-
if (Object.keys(body).length === 0) err("Usage:
|
|
373
|
+
if (Object.keys(body).length === 0) err("Usage: heyhank settings set --anthropic-key <key> or --anthropic-model <model>");
|
|
374
374
|
out(await apiPut(base, "/settings", body));
|
|
375
375
|
break;
|
|
376
376
|
}
|
|
@@ -425,13 +425,13 @@ async function handleSkills(base: string, args: string[]): Promise<void> {
|
|
|
425
425
|
}
|
|
426
426
|
case "get": {
|
|
427
427
|
const slug = rest[0];
|
|
428
|
-
if (!slug) err("Usage:
|
|
428
|
+
if (!slug) err("Usage: heyhank skills get <slug>");
|
|
429
429
|
out(await apiGet(base, `/skills/${encodeURIComponent(slug)}`));
|
|
430
430
|
break;
|
|
431
431
|
}
|
|
432
432
|
case "create": {
|
|
433
433
|
const flags = parseFlags(rest);
|
|
434
|
-
if (!flags.name) err("Usage:
|
|
434
|
+
if (!flags.name) err("Usage: heyhank skills create --name <name> [--description <desc>] [--content <markdown>]");
|
|
435
435
|
const body: Record<string, unknown> = { name: flags.name };
|
|
436
436
|
if (flags.description) body.description = flags.description;
|
|
437
437
|
if (flags.content) body.content = flags.content;
|
|
@@ -440,15 +440,15 @@ async function handleSkills(base: string, args: string[]): Promise<void> {
|
|
|
440
440
|
}
|
|
441
441
|
case "update": {
|
|
442
442
|
const slug = rest[0];
|
|
443
|
-
if (!slug) err("Usage:
|
|
443
|
+
if (!slug) err("Usage: heyhank skills update <slug> --content <markdown>");
|
|
444
444
|
const flags = parseFlags(rest.slice(1));
|
|
445
|
-
if (!flags.content) err("Usage:
|
|
445
|
+
if (!flags.content) err("Usage: heyhank skills update <slug> --content <full SKILL.md content>");
|
|
446
446
|
out(await apiPut(base, `/skills/${encodeURIComponent(slug)}`, { content: flags.content }));
|
|
447
447
|
break;
|
|
448
448
|
}
|
|
449
449
|
case "delete": {
|
|
450
450
|
const slug = rest[0];
|
|
451
|
-
if (!slug) err("Usage:
|
|
451
|
+
if (!slug) err("Usage: heyhank skills delete <slug>");
|
|
452
452
|
out(await apiDelete(base, `/skills/${encodeURIComponent(slug)}`));
|
|
453
453
|
break;
|
|
454
454
|
}
|
|
@@ -463,18 +463,18 @@ function printCtlUsage(): void {
|
|
|
463
463
|
console.log(`
|
|
464
464
|
Management commands:
|
|
465
465
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
466
|
+
heyhank status Overall HeyHank status
|
|
467
|
+
heyhank sessions <subcommand> Manage sessions
|
|
468
|
+
heyhank envs <subcommand> Manage environment profiles
|
|
469
|
+
heyhank cron <subcommand> Manage scheduled jobs
|
|
470
|
+
heyhank skills <subcommand> Manage Claude Code skills
|
|
471
|
+
heyhank settings <subcommand> Manage settings
|
|
472
|
+
heyhank assistant <subcommand> Manage the HeyHank Assistant
|
|
473
473
|
|
|
474
474
|
Global options:
|
|
475
|
-
--port <n> Override the
|
|
475
|
+
--port <n> Override the HeyHank API port (default: 3456, or HEYHANK_PORT env)
|
|
476
476
|
|
|
477
|
-
Run '
|
|
477
|
+
Run 'heyhank <command>' without subcommand for available subcommands.
|
|
478
478
|
`);
|
|
479
479
|
}
|
|
480
480
|
|
|
@@ -488,27 +488,27 @@ export async function handleCtlCommand(command: string, rawArgv: string[]): Prom
|
|
|
488
488
|
await handleStatus(base);
|
|
489
489
|
break;
|
|
490
490
|
case "sessions":
|
|
491
|
-
if (argv.length === 0) err("Usage:
|
|
491
|
+
if (argv.length === 0) err("Usage: heyhank sessions <list|get|create|kill|relaunch|archive|rename|send-message>");
|
|
492
492
|
await handleSessions(base, argv);
|
|
493
493
|
break;
|
|
494
494
|
case "envs":
|
|
495
|
-
if (argv.length === 0) err("Usage:
|
|
495
|
+
if (argv.length === 0) err("Usage: heyhank envs <list|get|create|update|delete>");
|
|
496
496
|
await handleEnvs(base, argv);
|
|
497
497
|
break;
|
|
498
498
|
case "cron":
|
|
499
|
-
if (argv.length === 0) err("Usage:
|
|
499
|
+
if (argv.length === 0) err("Usage: heyhank cron <list|get|create|update|delete|toggle|run|executions>");
|
|
500
500
|
await handleCron(base, argv);
|
|
501
501
|
break;
|
|
502
502
|
case "settings":
|
|
503
|
-
if (argv.length === 0) err("Usage:
|
|
503
|
+
if (argv.length === 0) err("Usage: heyhank settings <get|set>");
|
|
504
504
|
await handleSettings(base, argv);
|
|
505
505
|
break;
|
|
506
506
|
case "skills":
|
|
507
|
-
if (argv.length === 0) err("Usage:
|
|
507
|
+
if (argv.length === 0) err("Usage: heyhank skills <list|get|create|update|delete>");
|
|
508
508
|
await handleSkills(base, argv);
|
|
509
509
|
break;
|
|
510
510
|
case "assistant":
|
|
511
|
-
if (argv.length === 0) err("Usage:
|
|
511
|
+
if (argv.length === 0) err("Usage: heyhank assistant <status|launch|stop|config>");
|
|
512
512
|
await handleAssistant(base, argv);
|
|
513
513
|
break;
|
|
514
514
|
case "ctl-help":
|
|
@@ -521,7 +521,7 @@ export async function handleCtlCommand(command: string, rawArgv: string[]): Prom
|
|
|
521
521
|
const message = e instanceof Error ? e.message : String(e);
|
|
522
522
|
// Check if it's a connection error
|
|
523
523
|
if (message.includes("ECONNREFUSED") || message.includes("fetch failed")) {
|
|
524
|
-
err(`Cannot connect to
|
|
524
|
+
err(`Cannot connect to HeyHank at ${base}. Is the server running?`);
|
|
525
525
|
}
|
|
526
526
|
err(message);
|
|
527
527
|
}
|