@inceptionstack/roundhouse 0.3.7 → 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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inceptionstack/roundhouse",
3
- "version": "0.3.7",
3
+ "version": "0.3.9",
4
4
  "type": "module",
5
5
  "description": "Multi-platform chat gateway that routes messages through a configured AI agent",
6
6
  "license": "MIT",
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("At least one --user USERNAME is required.");
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("", "Storing secrets in psst...");
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("", "Configuring...");
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("", "Pairing with Telegram...");
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: Store secrets
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
@@ -39,7 +39,7 @@ export const DEFAULT_CONFIG: GatewayConfig = {
39
39
  cwd: homedir(),
40
40
  },
41
41
  chat: {
42
- botUsername: "roundhouse_bot",
42
+ botUsername: "",
43
43
  allowedUsers: [],
44
44
  adapters: {
45
45
  telegram: { mode: "polling" },
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;