nemoris 0.1.11 → 0.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nemoris",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
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",
@@ -498,16 +498,25 @@ export async function startDirectDaemon({
498
498
  if (fsImpl.existsSync(srcCliPath)) {
499
499
  cliEntryPath = srcCliPath;
500
500
  } else {
501
- try {
502
- const { execFileSync } = await import("node:child_process");
503
- const whichOut = execFileSync("which", ["nemoris"], { encoding: "utf8", timeout: 3000 }).trim();
504
- if (whichOut) {
505
- cliEntryPath = whichOut;
506
- }
507
- } catch { /* which not available */ }
501
+ // Resolve cli.js from this module's own package — the `which nemoris`
502
+ // path is a shell wrapper, not a Node.js file, so we can't pass it
503
+ // to `node` directly.
504
+ const __dirname = path.dirname(new URL(import.meta.url).pathname);
505
+ const packageCliPath = path.join(__dirname, "..", "cli.js");
506
+ if (fsImpl.existsSync(packageCliPath)) {
507
+ cliEntryPath = packageCliPath;
508
+ } else {
509
+ // Last resort: try which nemoris and hope it's a node script
510
+ try {
511
+ const { execFileSync } = await import("node:child_process");
512
+ const whichOut = execFileSync("which", ["nemoris"], { encoding: "utf8", timeout: 3000 }).trim();
513
+ if (whichOut) {
514
+ cliEntryPath = whichOut;
515
+ }
516
+ } catch { /* which not available */ }
517
+ }
508
518
  }
509
519
  if (!cliEntryPath) {
510
- // Fallback: resolve from this module's own package
511
520
  const __dirname = path.dirname(new URL(import.meta.url).pathname);
512
521
  cliEntryPath = path.join(__dirname, "..", "cli.js");
513
522
  }
package/src/cli.js CHANGED
@@ -70,6 +70,11 @@ printVersionAndExit();
70
70
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
71
71
  const parentEnvPath = resolveEnvPath(__dirname);
72
72
  loadParentEnv(parentEnvPath);
73
+ // Also load source repo .env as fallback (dev mode: CWD is source, installDir is elsewhere)
74
+ const cwdEnvPath = path.join(process.cwd(), ".env");
75
+ if (cwdEnvPath !== parentEnvPath && fs.existsSync(cwdEnvPath)) {
76
+ loadParentEnv(cwdEnvPath);
77
+ }
73
78
 
74
79
  const { main } = await import("./cli-main.js");
75
80
  const exitCode = await main(process.argv);
@@ -316,9 +316,16 @@ async function buildProviderSelectionOptions(provider, key, { fetchImpl = global
316
316
  const extra = fetchedModels
317
317
  .filter((m) => {
318
318
  if (curatedIds.has(m.id)) return false;
319
- // For large catalogs, only show models from known vendors
319
+ const rawId = m.id.replace(/^openrouter\//, "").replace(/^openai-codex\//, "").replace(/^anthropic\//, "");
320
+ // For direct provider APIs, only show that provider's models
321
+ if (provider === "anthropic") {
322
+ return rawId.startsWith("claude-");
323
+ }
324
+ if (provider === "openai") {
325
+ return rawId.startsWith("gpt-") || rawId.startsWith("o1") || rawId.startsWith("o3") || rawId.startsWith("o4");
326
+ }
327
+ // For large catalogs (OpenRouter), only show models from known vendors
320
328
  if (fetchedModels.length > 50) {
321
- const rawId = m.id.replace(/^openrouter\//, "").replace(/^openai-codex\//, "").replace(/^anthropic\//, "");
322
329
  const vendor = rawId.split("/")[0];
323
330
  return KNOWN_VENDORS.has(vendor);
324
331
  }
@@ -380,7 +387,11 @@ async function promptForProviderModels(provider, key, tui, { fetchImpl = globalT
380
387
  let activeOptions = options;
381
388
  const chosen = [];
382
389
  const manualOptionValue = "__custom__";
383
- const defaultModelValue = options.find((item) => !String(item.value).startsWith("__"))?.value || "";
390
+ // Use first curated model as placeholder for custom entry, not a "new" or extra model
391
+ const defaultModelValue = options.find((item) => {
392
+ const v = String(item.value);
393
+ return !v.startsWith("__") && !v.startsWith("\u2605");
394
+ })?.value || "";
384
395
 
385
396
  console.log(`\n ${cyan(`Choose ${provider === "openrouter" ? "OpenRouter" : provider === "openai" ? "OpenAI" : "Anthropic"} models`)}`);
386
397
  console.log(` ${dim("Pick up to three models. The first is your default. The others are fallbacks when the default is slow or unavailable.")}`);
@@ -743,6 +754,12 @@ export async function runAuthPhase(installDir, options = {}) {
743
754
  if (validatedKeys.openrouter) {
744
755
  envKeys.OPENROUTER_API_KEY = validatedKeys.openrouter;
745
756
  }
757
+ // Enable provider mode when any remote provider is configured
758
+ const hasRemoteProvider = !!(envKeys.NEMORIS_ANTHROPIC_API_KEY || envKeys.OPENROUTER_API_KEY || envKeys.NEMORIS_OPENAI_API_KEY);
759
+ if (hasRemoteProvider) {
760
+ envKeys.NEMORIS_ALLOW_PROVIDER_MODE = "1";
761
+ envKeys.NEMORIS_ALLOW_REMOTE_PROVIDER_MODE = "1";
762
+ }
746
763
  if (Object.keys(envKeys).length > 0) {
747
764
  writeEnvFile(installDir, envKeys);
748
765
  }
@@ -437,16 +437,18 @@ async function runFastPathWizard({ installDir }) {
437
437
  const { buildSetupChecklist } = await import("./setup-checklist.js");
438
438
  let checklist = buildSetupChecklist(installDir);
439
439
 
440
+ let telegramBotUsername = null;
440
441
  if (!checklist.telegram.configured) {
441
442
  const wantTelegram = await prompter.confirm({
442
443
  message: "Set up Telegram now?",
443
444
  initialValue: false,
444
445
  });
445
446
  if (wantTelegram) {
446
- await runTelegramPhase({
447
+ const tgResult = await runTelegramPhase({
447
448
  installDir,
448
449
  agentId,
449
450
  });
451
+ telegramBotUsername = tgResult?.botUsername || null;
450
452
  checklist = buildSetupChecklist(installDir);
451
453
  }
452
454
  }
@@ -464,7 +466,7 @@ async function runFastPathWizard({ installDir }) {
464
466
 
465
467
  // Strong finish screen
466
468
  const telegramConfigured = checklist.telegram.configured || checklist.telegram.pending;
467
- const botName = readTelegramBotName(installDir);
469
+ const botName = telegramBotUsername || readTelegramBotName(installDir);
468
470
  const finishLines = [
469
471
  `Your agent is live`,
470
472
  "",