@inceptionstack/roundhouse 0.3.11 → 0.3.13
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/README.md +2 -1
- package/package.json +1 -1
- package/src/cli/cli.ts +29 -5
- package/src/cli/doctor/checks/credentials.ts +1 -1
- package/src/cli/setup.ts +6 -6
- package/src/config.ts +19 -5
package/README.md
CHANGED
|
@@ -95,7 +95,8 @@ roundhouse install # installs as systemd service, starts automatically
|
|
|
95
95
|
roundhouse <command>
|
|
96
96
|
|
|
97
97
|
Commands:
|
|
98
|
-
start Start the gateway
|
|
98
|
+
start Start the gateway daemon
|
|
99
|
+
run Run the gateway in foreground
|
|
99
100
|
tui [thread] Open agent TUI on a gateway session
|
|
100
101
|
install Install as a systemd daemon (requires sudo)
|
|
101
102
|
uninstall Remove the systemd daemon
|
package/package.json
CHANGED
package/src/cli/cli.ts
CHANGED
|
@@ -56,6 +56,28 @@ function systemctl(verb: string, message?: string): void {
|
|
|
56
56
|
// ── Commands ────────────────────────────────────────
|
|
57
57
|
|
|
58
58
|
async function cmdStart() {
|
|
59
|
+
// If systemd service is installed, start via systemctl
|
|
60
|
+
const serviceInstalled = run(`systemctl list-unit-files ${SERVICE_NAME}.service`, { silent: true }).includes(SERVICE_NAME);
|
|
61
|
+
if (serviceInstalled) {
|
|
62
|
+
const isActive = run(`systemctl is-active ${SERVICE_NAME}`, { silent: true }) === "active";
|
|
63
|
+
if (isActive) {
|
|
64
|
+
console.log("Roundhouse is already running.");
|
|
65
|
+
console.log(" Use: roundhouse restart to restart");
|
|
66
|
+
console.log(" roundhouse status to check status");
|
|
67
|
+
console.log(" roundhouse logs to tail logs");
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
systemctl("start", "Daemon started.");
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// No systemd service — fall back to foreground
|
|
75
|
+
console.log("No systemd service found. Running in foreground (use Ctrl+C to stop)...");
|
|
76
|
+
console.log(" Tip: run 'roundhouse install' to set up the systemd daemon.\n");
|
|
77
|
+
await cmdRun();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async function cmdRun() {
|
|
59
81
|
process.env.ROUNDHOUSE_CONFIG = CONFIG_PATH;
|
|
60
82
|
const indexPath = resolve(__dirname, "..", "index.ts");
|
|
61
83
|
const jsPath = resolve(__dirname, "..", "dist", "index.js");
|
|
@@ -117,15 +139,15 @@ async function cmdInstall() {
|
|
|
117
139
|
const binPath = run("which roundhouse", { silent: true });
|
|
118
140
|
const nodePath = run("which node", { silent: true }) || process.execPath;
|
|
119
141
|
const tsxPath = resolve(__dirname, "..", "..", "node_modules", ".bin", "tsx");
|
|
120
|
-
const srcIndex = resolve(__dirname, "..", "index.ts");
|
|
121
142
|
|
|
122
143
|
let execStart: string;
|
|
123
144
|
if (binPath) {
|
|
124
|
-
execStart = `${nodePath} ${binPath}
|
|
145
|
+
execStart = `${nodePath} ${binPath} run`;
|
|
125
146
|
} else {
|
|
126
|
-
// No global install —
|
|
147
|
+
// No global install — run CLI via tsx with 'run' subcommand
|
|
127
148
|
const tsxBin = run("which tsx", { silent: true }) || tsxPath;
|
|
128
|
-
|
|
149
|
+
const cliPath = resolve(__dirname, "cli.ts");
|
|
150
|
+
execStart = `${tsxBin} ${cliPath} run`;
|
|
129
151
|
}
|
|
130
152
|
|
|
131
153
|
// Compute PATH that includes node's bin dir (for mise/nvm setups)
|
|
@@ -417,7 +439,8 @@ Usage:
|
|
|
417
439
|
Commands:
|
|
418
440
|
setup One-command install & configure (also works via npx)
|
|
419
441
|
pair Pair Telegram account for notifications
|
|
420
|
-
start Start the gateway
|
|
442
|
+
start Start the gateway daemon
|
|
443
|
+
run Run the gateway in foreground
|
|
421
444
|
tui [thread] Open agent TUI on a gateway session
|
|
422
445
|
install Install as a systemd daemon (requires sudo)
|
|
423
446
|
uninstall Remove the systemd daemon
|
|
@@ -600,6 +623,7 @@ const commands: Record<string, () => void | Promise<void>> = {
|
|
|
600
623
|
setup: () => cmdSetup(process.argv.slice(3)),
|
|
601
624
|
pair: () => cmdPair(process.argv.slice(3)),
|
|
602
625
|
start: cmdStart,
|
|
626
|
+
run: cmdRun,
|
|
603
627
|
install: cmdInstall,
|
|
604
628
|
uninstall: cmdUninstall,
|
|
605
629
|
update: cmdUpdate,
|
|
@@ -22,7 +22,7 @@ export const credentialChecks: DoctorCheck[] = [
|
|
|
22
22
|
return {
|
|
23
23
|
id: "telegram-token", category: "credentials", name: "Telegram bot token",
|
|
24
24
|
status: "fail", summary: "TELEGRAM_BOT_TOKEN not set",
|
|
25
|
-
details: ["Set TELEGRAM_BOT_TOKEN in your environment or ~/.roundhouse
|
|
25
|
+
details: ["Set TELEGRAM_BOT_TOKEN in your environment or ~/.roundhouse/.env"],
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
if (!/^\d+:[A-Za-z0-9_-]+$/.test(token)) {
|
package/src/cli/setup.ts
CHANGED
|
@@ -630,7 +630,7 @@ async function stepConfigure(
|
|
|
630
630
|
}
|
|
631
631
|
|
|
632
632
|
await atomicWriteText(ENV_PATH, envLines.join("\n") + "\n");
|
|
633
|
-
ok(`~/.roundhouse
|
|
633
|
+
ok(`~/.roundhouse/.env${opts.psst ? " (non-secret config only)" : ""}`);
|
|
634
634
|
}
|
|
635
635
|
|
|
636
636
|
async function stepPair(opts: SetupOptions, botInfo: BotInfo): Promise<PairResult | null> {
|
|
@@ -740,12 +740,12 @@ async function stepInstallSystemd(opts: SetupOptions): Promise<void> {
|
|
|
740
740
|
}
|
|
741
741
|
}
|
|
742
742
|
|
|
743
|
-
// Build ExecStart
|
|
743
|
+
// Build ExecStart — uses `roundhouse run` (foreground mode for systemd)
|
|
744
744
|
let execStart: string;
|
|
745
745
|
if (psstBin) {
|
|
746
|
-
execStart = `${psstBin} run ${nodeBin} ${roundhouseBin}
|
|
746
|
+
execStart = `${psstBin} run ${nodeBin} ${roundhouseBin} run`;
|
|
747
747
|
} else {
|
|
748
|
-
execStart = `${nodeBin} ${roundhouseBin}
|
|
748
|
+
execStart = `${nodeBin} ${roundhouseBin} run`;
|
|
749
749
|
}
|
|
750
750
|
|
|
751
751
|
// Always include env file for non-secret config (AWS_PROFILE, etc)
|
|
@@ -873,7 +873,7 @@ export async function cmdSetup(argv: string[]): Promise<void> {
|
|
|
873
873
|
}
|
|
874
874
|
log(` Bot: @${botInfo.username}`);
|
|
875
875
|
log(` Memory: ${opts.extensions.some((e) => e.includes("pi-memory")) ? "agent-managed" : "roundhouse-managed"}`);
|
|
876
|
-
log(` Secrets: ${opts.psst ? "psst vault (encrypted)" : "~/.roundhouse
|
|
876
|
+
log(` Secrets: ${opts.psst ? "psst vault (encrypted)" : "~/.roundhouse/.env (plaintext)"}`);
|
|
877
877
|
log(` Send /status to @${botInfo.username} on Telegram.\n`);
|
|
878
878
|
} catch (err: any) {
|
|
879
879
|
log("\n━━━━━━━━━━━━━━━━━━━");
|
|
@@ -993,7 +993,7 @@ function printDryRun(opts: SetupOptions): void {
|
|
|
993
993
|
log(` Set defaultProvider: ${opts.provider}`);
|
|
994
994
|
log(` Set defaultModel: ${opts.model}`);
|
|
995
995
|
log(`Would write: ~/.roundhouse/gateway.config.json`);
|
|
996
|
-
log(`Would write: ~/.roundhouse
|
|
996
|
+
log(`Would write: ~/.roundhouse/.env${opts.psst ? " (non-secret config only)" : ""}`);
|
|
997
997
|
log(`Would register ${BOT_COMMANDS.length} bot commands`);
|
|
998
998
|
if (opts.systemd) log(`Would install systemd service`);
|
|
999
999
|
log("\nNo changes made.\n");
|
package/src/config.ts
CHANGED
|
@@ -21,7 +21,10 @@ export const LEGACY_CONFIG_DIR = resolve(homedir(), ".config", "roundhouse");
|
|
|
21
21
|
/** Active config directory — use ROUNDHOUSE_DIR */
|
|
22
22
|
export const CONFIG_DIR = ROUNDHOUSE_DIR;
|
|
23
23
|
export const CONFIG_PATH = resolve(ROUNDHOUSE_DIR, "gateway.config.json");
|
|
24
|
-
export const ENV_FILE_PATH = resolve(ROUNDHOUSE_DIR, "env");
|
|
24
|
+
export const ENV_FILE_PATH = resolve(ROUNDHOUSE_DIR, ".env");
|
|
25
|
+
|
|
26
|
+
/** Legacy env file name (deprecated) */
|
|
27
|
+
export const LEGACY_ENV_FILE_PATH = resolve(ROUNDHOUSE_DIR, "env");
|
|
25
28
|
|
|
26
29
|
/** Cron directories */
|
|
27
30
|
export const CRON_JOBS_DIR = resolve(ROUNDHOUSE_DIR, "crons");
|
|
@@ -109,15 +112,26 @@ export async function resolveConfigPath(): Promise<{ path: string; legacy: boole
|
|
|
109
112
|
let envFileWarned = false;
|
|
110
113
|
|
|
111
114
|
export async function resolveEnvFilePath(): Promise<string> {
|
|
115
|
+
// Canonical: ~/.roundhouse/.env
|
|
112
116
|
if (await fileExists(ENV_FILE_PATH)) return ENV_FILE_PATH;
|
|
113
|
-
|
|
114
|
-
if (await fileExists(
|
|
117
|
+
// Legacy: ~/.roundhouse/env (old name, same directory)
|
|
118
|
+
if (await fileExists(LEGACY_ENV_FILE_PATH)) {
|
|
119
|
+
if (!envFileWarned) {
|
|
120
|
+
envFileWarned = true;
|
|
121
|
+
console.warn(`[roundhouse] \u26a0\ufe0f Env file found at legacy path: ${LEGACY_ENV_FILE_PATH}`);
|
|
122
|
+
console.warn(`[roundhouse] Rename it to ${ENV_FILE_PATH} \u2014 legacy name will be removed in a future version.`);
|
|
123
|
+
}
|
|
124
|
+
return LEGACY_ENV_FILE_PATH;
|
|
125
|
+
}
|
|
126
|
+
// Legacy: ~/.config/roundhouse/env (old directory)
|
|
127
|
+
const legacyDirEnv = resolve(LEGACY_CONFIG_DIR, "env");
|
|
128
|
+
if (await fileExists(legacyDirEnv)) {
|
|
115
129
|
if (!envFileWarned) {
|
|
116
130
|
envFileWarned = true;
|
|
117
|
-
console.warn(`[roundhouse] \u26a0\ufe0f Env file found at legacy path: ${
|
|
131
|
+
console.warn(`[roundhouse] \u26a0\ufe0f Env file found at legacy path: ${legacyDirEnv}`);
|
|
118
132
|
console.warn(`[roundhouse] Move it to ${ENV_FILE_PATH} \u2014 legacy path will be removed in a future version.`);
|
|
119
133
|
}
|
|
120
|
-
return
|
|
134
|
+
return legacyDirEnv;
|
|
121
135
|
}
|
|
122
136
|
return ENV_FILE_PATH;
|
|
123
137
|
}
|