refactor: unify runtime directories and environment variables to HAPI_HOME

Consolidate CLI and server runtime directories from ~/.config/hapi/ (CLI) and ~/.hapi-server/ (Server) to a single ~/.hapi/ directory. Unify environment variables from HAPI_HOME_DIR (CLI) and HAPI_BOT_DATA_DIR (Server) to a single HAPI_HOME variable across both applications. Update all documentation and configuration references accordingly. Bump bun-types to 1.3.5.
This commit is contained in:
weishu
2025-12-21 19:17:07 +08:00
parent bf72e0dc3b
commit 81852a3176
15 changed files with 28 additions and 26 deletions
+1 -1
View File
@@ -40,7 +40,7 @@ The CLI will prompt for `CLI_API_TOKEN` and save it locally.
- In a browser, open `WEBAPP_URL` and log in with `CLI_API_TOKEN`.
## CLI config file
You can store the token in `~/.config/hapi/settings.json` instead of an env var.
You can store the token in `~/.hapi/settings.json` instead of an env var.
Environment variables take priority over the file.
Example:
+3 -2
View File
@@ -39,6 +39,7 @@
"devDependencies": {
"@eslint/compat": "^1",
"@types/node": ">=20",
"bun-types": "^1.3.5",
"cross-env": "^10.1.0",
"dotenv": "^16.6.1",
"eslint": "^9",
@@ -65,7 +66,7 @@
},
"devDependencies": {
"@types/node": ">=20",
"bun-types": "^1.2.21",
"bun-types": "^1.3.5",
"typescript": "^5",
},
},
@@ -828,7 +829,7 @@
"buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="],
"bun-types": ["bun-types@1.3.4", "", { "dependencies": { "@types/node": "*" } }, "sha512-5ua817+BZPZOlNaRgGBpZJOSAQ9RQ17pkwPD0yR7CfJg+r8DgIILByFifDTa+IPDDxzf5VNhtNlcKqFzDgJvlQ=="],
"bun-types": ["bun-types@1.3.5", "", { "dependencies": { "@types/node": "*" } }, "sha512-inmAYe2PFLs0SUbFOWSVD24sg1jFlMPxOjOSSCYqUgn4Hsc3rDc7dFvfVYjFPNHtov6kgUeulV4SxbuIV/stPw=="],
"bundle-name": ["bundle-name@4.1.0", "", { "dependencies": { "run-applescript": "^7.0.0" } }, "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q=="],
+1 -1
View File
@@ -149,7 +149,7 @@ hapi daemon status
```
## Daemon Logs
- Daemon logs are stored in `~/.hapi-dev/logs/` (or `$HAPI_HOME_DIR/logs/`)
- Daemon logs are stored in `~/.hapi/logs/` (or `$HAPI_HOME/logs/`)
- Named with format: `YYYY-MM-DD-HH-MM-SS-daemon.log`
# Session Forking `claude` and sdk behavior
+2 -2
View File
@@ -37,10 +37,10 @@ Required:
- `CLI_API_TOKEN` - shared secret; must match the server
- `HAPI_BOT_URL` - server base URL (default: http://localhost:3006)
`CLI_API_TOKEN` can be set via env or stored in `~/.config/hapi/settings.json` (env wins).
`CLI_API_TOKEN` can be set via env or stored in `~/.hapi/settings.json` (env wins).
Optional:
- `HAPI_HOME_DIR` - config/data directory (default: ~/.config/hapi)
- `HAPI_HOME` - config/data directory (default: ~/.hapi)
- `HAPI_EXPERIMENTAL` - enable experimental features (true/1/yes)
- `HAPI_HTTP_MCP_URL` - default MCP target for `hapi mcp`
- `HAPI_CLAUDE_PATH` - path to a specific `claude` executable
+1
View File
@@ -105,6 +105,7 @@
"devDependencies": {
"@eslint/compat": "^1",
"@types/node": ">=20",
"bun-types": "^1.3.5",
"cross-env": "^10.1.0",
"dotenv": "^16.6.1",
"eslint": "^9",
+2 -2
View File
@@ -50,7 +50,7 @@ export async function handleAuthCommand(args: string[]): Promise<void> {
cliApiToken: token.trim()
}))
configuration._setCliApiToken(token.trim())
console.log(chalk.green('\nToken saved to ~/.config/hapi/settings.json'))
console.log(chalk.green(`\nToken saved to ${configuration.settingsFile}`))
} finally {
rl.close()
}
@@ -84,7 +84,7 @@ ${chalk.bold('Usage:')}
${chalk.bold('Token priority (highest to lowest):')}
1. CLI_API_TOKEN environment variable
2. ~/.config/hapi/settings.json
2. ~/.hapi/settings.json
3. Interactive prompt (on first run)
`)
}
+4 -4
View File
@@ -35,13 +35,13 @@ class Configuration {
const args = process.argv.slice(2)
this.isDaemonProcess = args.length >= 2 && args[0] === 'daemon' && (args[1] === 'start-sync')
// Directory configuration - Priority: HAPI_HOME_DIR env > default home dir
if (process.env.HAPI_HOME_DIR) {
// Directory configuration - Priority: HAPI_HOME env > default home dir
if (process.env.HAPI_HOME) {
// Expand ~ to home directory if present
const expandedPath = process.env.HAPI_HOME_DIR.replace(/^~/, homedir())
const expandedPath = process.env.HAPI_HOME.replace(/^~/, homedir())
this.happyHomeDir = expandedPath
} else {
this.happyHomeDir = join(homedir(), '.config', 'hapi')
this.happyHomeDir = join(homedir(), '.hapi')
}
this.logsDir = join(this.happyHomeDir, 'logs')
+2 -2
View File
@@ -222,7 +222,7 @@ Checks if machine ID exists in settings:
"platform": "darwin",
"happyCliVersion": "1.0.0",
"homeDir": "/Users/john",
"happyHomeDir": "/Users/john/.config/hapi"
"happyHomeDir": "/Users/john/.hapi"
},
"daemonState": {
"status": "running",
@@ -318,7 +318,7 @@ socket.emit('machine-update-metadata', {
"platform": "darwin",
"happyCliVersion": "1.0.1",
"homeDir": "/Users/john",
"happyHomeDir": "/Users/john/.config/hapi"
"happyHomeDir": "/Users/john/.hapi"
},
"expectedVersion": 1
}, callback)
+1 -1
View File
@@ -10,7 +10,7 @@
* and the daemon will not work properly!
*
* The integration test environment uses .env.integration-test which sets:
* - HAPI_HOME_DIR=~/.hapi-dev-test (DIFFERENT from dev's ~/.hapi-dev!)
* - HAPI_HOME=~/.hapi-dev-test (DIFFERENT from dev's ~/.hapi-dev!)
* - HAPI_BOT_URL=http://localhost:3006 (local hapi-server)
* - CLI_API_TOKEN=... (must match the server)
*/
+1 -1
View File
@@ -1,7 +1,7 @@
/**
* Minimal persistence functions for HAPI CLI
*
* Handles settings and private key storage in ~/.config/hapi/ (or HAPI_HOME_DIR override)
* Handles settings and private key storage in ~/.hapi/ (or HAPI_HOME override)
*/
import { FileHandle } from 'node:fs/promises'
+2 -2
View File
@@ -23,7 +23,7 @@ import packageJson from '../../package.json'
export function getEnvironmentInfo(): Record<string, any> {
return {
PWD: process.env.PWD,
HAPI_HOME_DIR: process.env.HAPI_HOME_DIR,
HAPI_HOME: process.env.HAPI_HOME,
HAPI_BOT_URL: process.env.HAPI_BOT_URL,
HAPI_PROJECT_ROOT: process.env.HAPI_PROJECT_ROOT,
CLI_API_TOKEN_SET: Boolean(process.env.CLI_API_TOKEN),
@@ -116,7 +116,7 @@ export async function runDoctorCommand(filter?: 'all' | 'daemon'): Promise<void>
// Environment
console.log(chalk.bold('\n🌍 Environment Variables'));
const env = getEnvironmentInfo();
console.log(`HAPI_HOME_DIR: ${env.HAPI_HOME_DIR ? chalk.green(env.HAPI_HOME_DIR) : chalk.gray('not set')}`);
console.log(`HAPI_HOME: ${env.HAPI_HOME ? chalk.green(env.HAPI_HOME) : chalk.gray('not set')}`);
console.log(`HAPI_BOT_URL: ${env.HAPI_BOT_URL ? chalk.green(env.HAPI_BOT_URL) : chalk.gray('not set')}`);
console.log(`CLI_API_TOKEN: ${env.CLI_API_TOKEN_SET ? chalk.green('set') : chalk.gray('not set')}`);
console.log(`DANGEROUSLY_LOG_TO_SERVER: ${env.DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING ? chalk.yellow('ENABLED') : chalk.gray('not set')}`);
+2 -2
View File
@@ -3,7 +3,7 @@
*
* Handles CLI_API_TOKEN initialization with priority:
* 1. Environment variable (highest - allows temporary override)
* 2. Settings file (~/.config/hapi/settings.json)
* 2. Settings file (~/.hapi/settings.json)
* 3. Interactive prompt (only when both above are missing)
*/
@@ -57,7 +57,7 @@ async function promptForToken(): Promise<string> {
if (!token.trim()) {
throw new Error('Token cannot be empty')
}
console.log(chalk.green('\nToken saved to ~/.config/hapi/settings.json'))
console.log(chalk.green(`\nToken saved to ${configuration.settingsFile}`))
return token.trim()
} finally {
rl.close()
+1 -1
View File
@@ -26,7 +26,7 @@ Optional:
- `WEBAPP_PORT` - HTTP port (default: 3006).
- `WEBAPP_URL` - public URL for Telegram Mini App button.
- `CORS_ORIGINS` - comma-separated origins, or `*`.
- `HAPI_BOT_DATA_DIR` - data directory (default: ~/.hapi-server).
- `HAPI_HOME` - data directory (default: ~/.hapi).
- `DB_PATH` - SQLite database path.
## Running
+2 -2
View File
@@ -2,7 +2,7 @@
"name": "hapi-server",
"private": true,
"version": "0.1.0",
"description": "Telegram Bot client for HAPI - control Claude Code sessions",
"description": "Telegram Bot client for HAPI - control Claude Code sessions",
"author": "Kirill Dubovitskiy",
"license": "MIT",
"type": "module",
@@ -23,7 +23,7 @@
},
"devDependencies": {
"@types/node": ">=20",
"bun-types": "^1.2.21",
"bun-types": "^1.3.5",
"typescript": "^5"
}
}
+3 -3
View File
@@ -110,11 +110,11 @@ class Configuration {
}
// Data directory
if (process.env.HAPI_BOT_DATA_DIR) {
const expandedPath = process.env.HAPI_BOT_DATA_DIR.replace(/^~/, homedir())
if (process.env.HAPI_HOME) {
const expandedPath = process.env.HAPI_HOME.replace(/^~/, homedir())
this.dataDir = expandedPath
} else {
this.dataDir = join(homedir(), '.hapi-server')
this.dataDir = join(homedir(), '.hapi')
}
// DB path (defaults inside dataDir)