nemoris 0.1.10 → 0.1.11

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": "nemoris",
3
- "version": "0.1.10",
3
+ "version": "0.1.11",
4
4
  "type": "module",
5
5
  "description": "Personal AI agent runtime — persistent memory, delivery guarantees, task contracts, self-healing. Local-first, no cloud.",
6
6
  "license": "MIT",
@@ -246,7 +246,10 @@ export async function runTelegramPhase({ installDir, agentId, nonInteractive = f
246
246
  let token = null;
247
247
  let botUsername = null;
248
248
 
249
- console.log(`\n ${dimImpl("Need a bot token? Open Telegram → search @BotFather send /newbot → follow the steps.")}`);
249
+ console.log(`\n ${yellowImpl("!")} Create a new bot in BotFather for Nemoris.`);
250
+ console.log(` ${dimImpl("If you're migrating from OpenClaw, don't reuse your existing bot tokens —")}`);
251
+ console.log(` ${dimImpl("each agent needs its own. Only one process can poll a bot at a time.")}`);
252
+ console.log(`\n ${dimImpl("Open Telegram → search @BotFather → send /newbot → follow the steps.")}`);
250
253
  console.log(` ${dimImpl("After creating your bot, open it in Telegram and tap Start before coming back here.")}`);
251
254
  console.log(` ${dimImpl("Your input will be hidden as you type — just paste and press Enter.")}\n`);
252
255
 
@@ -329,6 +332,21 @@ export async function runTelegramPhase({ installDir, agentId, nonInteractive = f
329
332
  chatIdPending: !chatId,
330
333
  });
331
334
 
335
+ // Persist bot_username to runtime.toml for finish screen / status
336
+ if (botUsername) {
337
+ const runtimePath = path.join(installDir, "config", "runtime.toml");
338
+ try {
339
+ let runtime = fs.readFileSync(runtimePath, "utf8");
340
+ if (runtime.includes("[telegram]") && !runtime.includes("bot_username")) {
341
+ runtime = runtime.replace(
342
+ /(\[telegram\][^\[]*)/s,
343
+ (section) => section.trimEnd() + `\nbot_username = "${botUsername}"\n`
344
+ );
345
+ fs.writeFileSync(runtimePath, runtime);
346
+ }
347
+ } catch { /* non-fatal */ }
348
+ }
349
+
332
350
  // Store chat_id in state for later phases (e.g. hatch)
333
351
  const result = { configured: true, verified: false, botUsername, botToken: token, operatorChatId: chatId || "" };
334
352
 
@@ -56,6 +56,21 @@ function createLegacyPromptAdapter(prompter) {
56
56
  };
57
57
  }
58
58
 
59
+ function readTelegramBotName(installDir) {
60
+ try {
61
+ const runtime = readRuntimeConfig(installDir);
62
+ const tokenEnv = runtime?.telegram?.bot_token_env;
63
+ if (!tokenEnv) return null;
64
+ const token = process.env[tokenEnv];
65
+ if (!token) return null;
66
+ // Bot username is cached in runtime.toml if available
67
+ if (runtime?.telegram?.bot_username) return runtime.telegram.bot_username;
68
+ return null;
69
+ } catch {
70
+ return null;
71
+ }
72
+ }
73
+
59
74
  function readRuntimeConfig(installDir) {
60
75
  const runtimePath = path.join(installDir, "config", "runtime.toml");
61
76
  try {
@@ -418,29 +433,10 @@ async function runFastPathWizard({ installDir }) {
418
433
  });
419
434
  }
420
435
 
421
- // Post-setup guidance
422
- const { buildSetupChecklist, formatSetupChecklist } = await import("./setup-checklist.js");
423
- const checklist = buildSetupChecklist(installDir);
424
- const allConfigured = Object.values(checklist).every((c) => c.configured);
425
-
426
- await prompter.note(
427
- [
428
- `Agent "${agentName}" is ready.`,
429
- "",
430
- "Next steps:",
431
- " nemoris start Start the daemon",
432
- " nemoris chat Open interactive chat",
433
- ...(allConfigured ? [] : [
434
- "",
435
- "Optional:",
436
- ...(!checklist.telegram.configured ? [" nemoris setup telegram Connect Telegram"] : []),
437
- ...(!checklist.ollama.configured ? [" nemoris setup ollama Add local models"] : []),
438
- ]),
439
- ].join("\n"),
440
- "Setup Complete"
441
- );
442
-
443
436
  // Offer Telegram setup inline
437
+ const { buildSetupChecklist } = await import("./setup-checklist.js");
438
+ let checklist = buildSetupChecklist(installDir);
439
+
444
440
  if (!checklist.telegram.configured) {
445
441
  const wantTelegram = await prompter.confirm({
446
442
  message: "Set up Telegram now?",
@@ -451,10 +447,46 @@ async function runFastPathWizard({ installDir }) {
451
447
  installDir,
452
448
  agentId,
453
449
  });
450
+ checklist = buildSetupChecklist(installDir);
454
451
  }
455
452
  }
456
453
 
457
- await prompter.outro("Run: nemoris start");
454
+ // Auto-start daemon
455
+ let daemonPid = null;
456
+ try {
457
+ const { startDaemonCommand } = await import("../cli/runtime-control.js");
458
+ const result = await startDaemonCommand({ projectRoot: installDir });
459
+ const pidMatch = String(result.message || "").match(/pid\s+(\d+)/);
460
+ daemonPid = pidMatch ? pidMatch[1] : "started";
461
+ } catch {
462
+ // Non-fatal — user can start manually
463
+ }
464
+
465
+ // Strong finish screen
466
+ const telegramConfigured = checklist.telegram.configured || checklist.telegram.pending;
467
+ const botName = readTelegramBotName(installDir);
468
+ const finishLines = [
469
+ `Your agent is live`,
470
+ "",
471
+ ...(daemonPid
472
+ ? [` \u2713 Daemon running (pid ${daemonPid})`]
473
+ : [" \u26a0 Daemon not started \u2014 run: nemoris start"]),
474
+ "",
475
+ ...(telegramConfigured && botName
476
+ ? [
477
+ ` \u2192 Open Telegram and message @${botName}`,
478
+ " Your agent will introduce itself",
479
+ ]
480
+ : [
481
+ " \u2192 Run: nemoris chat Start talking now",
482
+ ]),
483
+ "",
484
+ " Or: nemoris chat Open terminal chat",
485
+ " nemoris status Check agent health",
486
+ ];
487
+
488
+ await prompter.note(finishLines.join("\n"), "");
489
+ await prompter.outro("");
458
490
 
459
491
  try {
460
492
  const pkg = JSON.parse(fs.readFileSync(new URL("../../package.json", import.meta.url), "utf8"));