@inceptionstack/roundhouse 0.3.8 → 0.3.9
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/package.json +1 -1
- package/src/cli/setup.ts +41 -13
- package/src/config.ts +1 -1
- package/src/types.ts +2 -0
package/package.json
CHANGED
package/src/cli/setup.ts
CHANGED
|
@@ -189,7 +189,10 @@ export function parseSetupArgs(argv: string[]): SetupOptions {
|
|
|
189
189
|
);
|
|
190
190
|
}
|
|
191
191
|
if (opts.users.length === 0) {
|
|
192
|
-
throw new Error(
|
|
192
|
+
throw new Error(
|
|
193
|
+
"At least one --user USERNAME is required.\n" +
|
|
194
|
+
"This is your Telegram username (without @).",
|
|
195
|
+
);
|
|
193
196
|
}
|
|
194
197
|
for (const ext of opts.extensions) {
|
|
195
198
|
if (!EXTENSION_NAME_RE.test(ext)) {
|
|
@@ -254,9 +257,23 @@ async function stepPreflight(opts: SetupOptions): Promise<void> {
|
|
|
254
257
|
const hasAws =
|
|
255
258
|
process.env.AWS_ACCESS_KEY_ID ||
|
|
256
259
|
process.env.AWS_PROFILE ||
|
|
257
|
-
await fileExists(resolve(homedir(), ".aws", "credentials"))
|
|
260
|
+
await fileExists(resolve(homedir(), ".aws", "credentials")) ||
|
|
261
|
+
await fileExists(resolve(homedir(), ".aws", "config"));
|
|
262
|
+
|
|
263
|
+
// Also check instance metadata (EC2 IAM role)
|
|
264
|
+
let hasInstanceRole = false;
|
|
265
|
+
if (!hasAws) {
|
|
266
|
+
try {
|
|
267
|
+
const result = execSafe("curl", ["-sf", "--max-time", "2",
|
|
268
|
+
"http://169.254.169.254/latest/meta-data/iam/security-credentials/"], { silent: true });
|
|
269
|
+
hasInstanceRole = result.length > 0;
|
|
270
|
+
} catch {}
|
|
271
|
+
}
|
|
272
|
+
|
|
258
273
|
if (hasAws) {
|
|
259
274
|
ok("AWS credentials found");
|
|
275
|
+
} else if (hasInstanceRole) {
|
|
276
|
+
ok("AWS credentials found (instance IAM role)");
|
|
260
277
|
} else {
|
|
261
278
|
warn("AWS credentials not found — configure before first use");
|
|
262
279
|
}
|
|
@@ -436,7 +453,7 @@ async function stepInstallPackages(opts: SetupOptions): Promise<void> {
|
|
|
436
453
|
async function stepStoreSecrets(opts: SetupOptions, botInfo: BotInfo): Promise<void> {
|
|
437
454
|
if (!opts.psst) return;
|
|
438
455
|
|
|
439
|
-
step("
|
|
456
|
+
step("⑥", "Storing secrets in psst...");
|
|
440
457
|
|
|
441
458
|
const secrets: [string, string][] = [
|
|
442
459
|
["TELEGRAM_BOT_TOKEN", opts.botToken],
|
|
@@ -477,7 +494,7 @@ async function stepConfigure(
|
|
|
477
494
|
botInfo: BotInfo,
|
|
478
495
|
pairResult: PairResult | null,
|
|
479
496
|
): Promise<void> {
|
|
480
|
-
step("
|
|
497
|
+
step("⑦", "Configuring...");
|
|
481
498
|
|
|
482
499
|
await mkdir(ROUNDHOUSE_DIR, { recursive: true });
|
|
483
500
|
await mkdir(dirname(PI_SETTINGS_PATH), { recursive: true });
|
|
@@ -602,6 +619,10 @@ async function stepConfigure(
|
|
|
602
619
|
if (!envLines.some((l) => l.startsWith("AWS_DEFAULT_REGION="))) {
|
|
603
620
|
envLines.push(`AWS_DEFAULT_REGION=${existingEnv.AWS_DEFAULT_REGION ?? '"us-east-1"'}`);
|
|
604
621
|
}
|
|
622
|
+
// Pi agent requires AWS_REGION (not just AWS_DEFAULT_REGION) to discover Bedrock models
|
|
623
|
+
if (!envLines.some((l) => l.startsWith("AWS_REGION="))) {
|
|
624
|
+
envLines.push(`AWS_REGION=${existingEnv.AWS_REGION ?? existingEnv.AWS_DEFAULT_REGION ?? '"us-east-1"'}`);
|
|
625
|
+
}
|
|
605
626
|
}
|
|
606
627
|
|
|
607
628
|
await atomicWriteText(ENV_PATH, envLines.join("\n") + "\n");
|
|
@@ -609,7 +630,7 @@ async function stepConfigure(
|
|
|
609
630
|
}
|
|
610
631
|
|
|
611
632
|
async function stepPair(opts: SetupOptions, botInfo: BotInfo): Promise<PairResult | null> {
|
|
612
|
-
step("
|
|
633
|
+
step("⑤", "Pairing with Telegram...");
|
|
613
634
|
|
|
614
635
|
// Skip if chat IDs already known
|
|
615
636
|
if (opts.notifyChatIds.length > 0) {
|
|
@@ -651,6 +672,11 @@ async function stepPair(opts: SetupOptions, botInfo: BotInfo): Promise<PairResul
|
|
|
651
672
|
|
|
652
673
|
if (result) {
|
|
653
674
|
ok(`Paired with @${result.username} (user id: ${result.userId}, chat: ${result.chatId})`);
|
|
675
|
+
// Add paired username to allowedUsers if not already present
|
|
676
|
+
const lcUsername = result.username.toLowerCase();
|
|
677
|
+
if (!opts.users.some((u) => u.toLowerCase() === lcUsername)) {
|
|
678
|
+
opts.users.push(result.username);
|
|
679
|
+
}
|
|
654
680
|
return result;
|
|
655
681
|
}
|
|
656
682
|
|
|
@@ -814,12 +840,12 @@ export async function cmdSetup(argv: string[]): Promise<void> {
|
|
|
814
840
|
// Phase 2: Install packages
|
|
815
841
|
await stepInstallPackages(opts);
|
|
816
842
|
|
|
817
|
-
// Phase 3:
|
|
818
|
-
await stepStoreSecrets(opts, botInfo);
|
|
819
|
-
|
|
820
|
-
// Phase 4: Pair (before config, so we can include chat ID)
|
|
843
|
+
// Phase 3: Pair (before secrets/config, so paired username is included)
|
|
821
844
|
const pairResult = await stepPair(opts, botInfo);
|
|
822
845
|
|
|
846
|
+
// Phase 4: Store secrets (after pairing, so ALLOWED_USERS includes paired user)
|
|
847
|
+
await stepStoreSecrets(opts, botInfo);
|
|
848
|
+
|
|
823
849
|
// Phase 5: Write config (includes pair data)
|
|
824
850
|
await stepConfigure(opts, botInfo, pairResult);
|
|
825
851
|
|
|
@@ -951,18 +977,20 @@ function printDryRun(opts: SetupOptions): void {
|
|
|
951
977
|
log(`Would install: npm install -g psst-cli`);
|
|
952
978
|
log(`Would initialize psst vault`);
|
|
953
979
|
log(`Would install: pi-psst extension`);
|
|
954
|
-
log(`Would store TELEGRAM_BOT_TOKEN, BOT_USERNAME, ALLOWED_USERS in psst`);
|
|
955
980
|
}
|
|
956
981
|
for (const ext of opts.extensions) log(`Would install extension: ${ext}`);
|
|
982
|
+
if (!opts.nonInteractive && opts.notifyChatIds.length === 0) {
|
|
983
|
+
log(`Would pair via Telegram (interactive)`);
|
|
984
|
+
}
|
|
985
|
+
if (opts.psst) {
|
|
986
|
+
log(`Would store TELEGRAM_BOT_TOKEN, BOT_USERNAME, ALLOWED_USERS in psst`);
|
|
987
|
+
}
|
|
957
988
|
log(`Would configure: ~/.pi/agent/settings.json`);
|
|
958
989
|
log(` Set defaultProvider: ${opts.provider}`);
|
|
959
990
|
log(` Set defaultModel: ${opts.model}`);
|
|
960
991
|
log(`Would write: ~/.roundhouse/gateway.config.json`);
|
|
961
992
|
log(`Would write: ~/.roundhouse/env${opts.psst ? " (non-secret config only)" : ""}`);
|
|
962
993
|
log(`Would register ${BOT_COMMANDS.length} bot commands`);
|
|
963
|
-
if (!opts.nonInteractive && opts.notifyChatIds.length === 0) {
|
|
964
|
-
log(`Would pair via Telegram (interactive)`);
|
|
965
|
-
}
|
|
966
994
|
if (opts.systemd) log(`Would install systemd service`);
|
|
967
995
|
log("\nNo changes made.\n");
|
|
968
996
|
}
|
package/src/config.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -98,6 +98,8 @@ export interface AgentRouter {
|
|
|
98
98
|
// ── Gateway config ───────────────────────────────────
|
|
99
99
|
|
|
100
100
|
export interface GatewayConfig {
|
|
101
|
+
/** Config schema version for future migrations */
|
|
102
|
+
_version?: number;
|
|
101
103
|
agent: {
|
|
102
104
|
type: string;
|
|
103
105
|
[key: string]: unknown;
|