@sonnechasser/ntrp 0.1.2 → 0.1.3

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/dist/index.js CHANGED
@@ -2392,7 +2392,7 @@ function secretPromptLine(question) {
2392
2392
  return ` ${paint("accent", "\u25B8")} ${bold(question)} ${chalk2.dim("(hidden \u2014 paste once, Enter)")} `;
2393
2393
  }
2394
2394
  function stripTerminalArtifacts(input) {
2395
- return input.replace(/\x1b\[[0-9;]*[a-zA-Z~]/g, "").replace(/\x1b\][^\x07]*(\x07|\x1b\\)/g, "");
2395
+ return input.replace(/\x1b\[[0-9;]*[a-zA-Z~]/g, "").replace(/\x1b\][^\x07]*(\x07|\x1b\\)/g, "").replace(/\x1b\[200~/g, "").replace(/\x1b\[201~/g, "");
2396
2396
  }
2397
2397
  function renderQuestion(question, defaultValue) {
2398
2398
  const base = ` ${marker()}${bold(question)}`;
@@ -2450,8 +2450,8 @@ function createPromptSession(existing, ctx) {
2450
2450
  for (; ; ) {
2451
2451
  const raw = (await rl.question(renderQuestion(`Your pick [1-${choices.length}]`, defaultLabel))).trim();
2452
2452
  assertNotGlobalReplCommand(raw);
2453
- const pick = raw || defaultLabel || "";
2454
- const n = Number(pick);
2453
+ const pick2 = raw || defaultLabel || "";
2454
+ const n = Number(pick2);
2455
2455
  if (Number.isInteger(n) && n >= 1 && n <= choices.length) {
2456
2456
  return choices[n - 1].value;
2457
2457
  }
@@ -2579,12 +2579,18 @@ function createPromptSession(existing, ctx) {
2579
2579
  console.log(" " + chalk2.dim("Try again \u2014 paste the key once, then Enter."));
2580
2580
  }
2581
2581
  }
2582
+ async function askPressEnter(message) {
2583
+ await rl.question(
2584
+ ` ${paint("accent", "\u25B8")} ${bold(message)} ${chalk2.dim("(Enter)")} `
2585
+ );
2586
+ }
2582
2587
  return {
2583
2588
  ask,
2584
2589
  askRequired,
2585
2590
  confirm,
2586
2591
  choose,
2587
2592
  askMulti,
2593
+ askPressEnter,
2588
2594
  askSecret,
2589
2595
  close: () => {
2590
2596
  if (ctx && existing) {
@@ -5306,16 +5312,16 @@ async function runGlobalAdminCommand(command, line, ctx) {
5306
5312
  const args = tokens.slice(1);
5307
5313
  switch (command) {
5308
5314
  case "scratch": {
5309
- const { handler: handler42 } = await Promise.resolve().then(() => (init_scratch(), scratch_exports));
5310
- return handler42(args, ctx);
5315
+ const { handler: handler44 } = await Promise.resolve().then(() => (init_scratch(), scratch_exports));
5316
+ return handler44(args, ctx);
5311
5317
  }
5312
5318
  case "cleanup": {
5313
- const { handler: handler42 } = await Promise.resolve().then(() => (init_cleanup(), cleanup_exports));
5314
- return handler42(args, ctx);
5319
+ const { handler: handler44 } = await Promise.resolve().then(() => (init_cleanup(), cleanup_exports));
5320
+ return handler44(args, ctx);
5315
5321
  }
5316
5322
  case "deactivate-demo": {
5317
- const { handler: handler42 } = await Promise.resolve().then(() => (init_deactivate_demo(), deactivate_demo_exports));
5318
- return handler42(args, ctx);
5323
+ const { handler: handler44 } = await Promise.resolve().then(() => (init_deactivate_demo(), deactivate_demo_exports));
5324
+ return handler44(args, ctx);
5319
5325
  }
5320
5326
  default:
5321
5327
  return void 0;
@@ -13972,12 +13978,12 @@ async function handleDraftHandoff(input) {
13972
13978
  };
13973
13979
  }
13974
13980
  async function executeToolCall(name, input, ctx) {
13975
- const handler42 = HANDLERS[name];
13976
- if (!handler42) {
13981
+ const handler44 = HANDLERS[name];
13982
+ if (!handler44) {
13977
13983
  return JSON.stringify({ error: `Unknown tool '${name}'` });
13978
13984
  }
13979
13985
  const start = Date.now();
13980
- const rawResult = await handler42(input, ctx);
13986
+ const rawResult = await handler44(input, ctx);
13981
13987
  const safeResult = stripPII(rawResult);
13982
13988
  const resultJson = JSON.stringify(safeResult);
13983
13989
  const duration = Date.now() - start;
@@ -14861,19 +14867,19 @@ async function promptForNewPath(ctx) {
14861
14867
  description: "Set up now, load data later"
14862
14868
  }
14863
14869
  ];
14864
- const pick = await prompts.choose(
14870
+ const pick2 = await prompts.choose(
14865
14871
  "Where should we start?",
14866
14872
  startChoices,
14867
14873
  { default: isDemoEnabled() ? "demo" : "file" }
14868
14874
  );
14869
- if (pick === "demo") {
14875
+ if (pick2 === "demo") {
14870
14876
  const lens2 = await prompts.choose("What kind of analysis?", [
14871
14877
  { value: "gtm_health", label: "Pipeline health", description: "Vital signs \u2014 motion, handoffs, stuck deals" },
14872
14878
  { value: "revenue_metrics", label: "SaaS metrics", description: "ARR, retention, pipeline efficiency" }
14873
14879
  ], { default: "gtm_health" });
14874
14880
  return { source: { kind: "demo" }, lens: lens2 };
14875
14881
  }
14876
- if (pick === "empty") {
14882
+ if (pick2 === "empty") {
14877
14883
  return { source: { kind: "empty" }, lens: "gtm_health" };
14878
14884
  }
14879
14885
  const path = (await prompts.ask("Path to the CSV file")).trim();
@@ -18767,47 +18773,418 @@ var init_config = __esm({
18767
18773
  init_argparse();
18768
18774
  init_prompts();
18769
18775
  init_theme();
18770
- SECRET_KEYS = /* @__PURE__ */ new Set(["api-key", "openai-api-key", "license-key"]);
18776
+ SECRET_KEYS = /* @__PURE__ */ new Set(["api-key", "openai-api-key", "license-key", "license-instance-id"]);
18777
+ }
18778
+ });
18779
+
18780
+ // src/license/trial-policy.ts
18781
+ function getCheckoutUrl() {
18782
+ return process.env.NTRP_UPGRADE_URL ?? process.env.NTRP_PURCHASE_URL ?? process.env.NTRP_CHECKOUT_URL ?? PRO_CHECKOUT_URL;
18783
+ }
18784
+ function evaluateTrial(activatedAt, now2 = /* @__PURE__ */ new Date()) {
18785
+ const daysSince = Math.floor((now2.getTime() - activatedAt.getTime()) / 864e5);
18786
+ if (daysSince >= TRIAL_GRACE_END_DAYS) {
18787
+ return {
18788
+ phase: "expired",
18789
+ daysSinceActivation: daysSince,
18790
+ daysUntilLockout: 0,
18791
+ shouldNudge: false
18792
+ };
18793
+ }
18794
+ if (daysSince >= TRIAL_FULL_DAYS) {
18795
+ return {
18796
+ phase: "grace",
18797
+ daysSinceActivation: daysSince,
18798
+ daysUntilLockout: TRIAL_GRACE_END_DAYS - daysSince,
18799
+ shouldNudge: true
18800
+ };
18801
+ }
18802
+ return {
18803
+ phase: "active",
18804
+ daysSinceActivation: daysSince,
18805
+ daysUntilLockout: TRIAL_GRACE_END_DAYS - daysSince,
18806
+ shouldNudge: false
18807
+ };
18808
+ }
18809
+ function formatTrialActiveMessage(daysSince) {
18810
+ const daysLeft = TRIAL_FULL_DAYS - daysSince;
18811
+ if (daysLeft <= 0) return "trial license";
18812
+ const dayWord = daysLeft === 1 ? "day" : "days";
18813
+ return `trial license (${daysLeft} ${dayWord} remaining)`;
18814
+ }
18815
+ var TRIAL_FULL_DAYS, TRIAL_GRACE_END_DAYS, PRO_CHECKOUT_URL;
18816
+ var init_trial_policy = __esm({
18817
+ "src/license/trial-policy.ts"() {
18818
+ "use strict";
18819
+ TRIAL_FULL_DAYS = 11;
18820
+ TRIAL_GRACE_END_DAYS = 30;
18821
+ PRO_CHECKOUT_URL = "https://sonnechasser.lemonsqueezy.com/checkout/buy/d62d35a2-a369-4cf5-a88b-328223866b5f";
18822
+ }
18823
+ });
18824
+
18825
+ // src/license/upgrade-whimsy.ts
18826
+ function pick(items) {
18827
+ return items[Math.floor(Math.random() * items.length)] ?? items[0];
18828
+ }
18829
+ function randomGraceNudge(daysLeft) {
18830
+ return pick(GRACE_NUDGES)(daysLeft);
18831
+ }
18832
+ function randomCutoffNudge() {
18833
+ return pick(CUTOFF_NUDGES);
18834
+ }
18835
+ function randomBlockedNudge() {
18836
+ return pick(BLOCKED_WHILE_CUTOFF);
18837
+ }
18838
+ function randomUpgradeHeadline(daysLeft) {
18839
+ return pick(UPGRADE_HEADLINES)(daysLeft);
18840
+ }
18841
+ function randomUpgradeSubtitle(reason) {
18842
+ return pick(UPGRADE_SUBTITLES)(reason);
18843
+ }
18844
+ function randomProActivatedLine() {
18845
+ return pick(PRO_ACTIVATED_LINES);
18846
+ }
18847
+ var GRACE_NUDGES, CUTOFF_NUDGES, BLOCKED_WHILE_CUTOFF, UPGRADE_HEADLINES, UPGRADE_SUBTITLES, PRO_ACTIVATED_LINES;
18848
+ var init_upgrade_whimsy = __esm({
18849
+ "src/license/upgrade-whimsy.ts"() {
18850
+ "use strict";
18851
+ init_trial_policy();
18852
+ GRACE_NUDGES = [
18853
+ (d) => `Hey \u2014 you still good on this? ${d} day${d === 1 ? "" : "s"} left. /upgrade when it makes sense.`,
18854
+ (d) => `Just checking in. ${d} day${d === 1 ? "" : "s"} before this quietly stops working. /upgrade.`,
18855
+ (d) => `No rush, but not forever either. ${d} day${d === 1 ? "" : "s"} \u2014 /upgrade.`,
18856
+ (d) => `You've had a good run. ${d} day${d === 1 ? "" : "s"} of wiggle room left. /upgrade if you're staying.`,
18857
+ (d) => `Still here? Cool. ${d} day${d === 1 ? "" : "s"} and then I'll need a yes from you. /upgrade.`,
18858
+ (d) => `Didn't want to bug you. ${d} day${d === 1 ? "" : "s"} though \u2014 /upgrade.`,
18859
+ (d) => `The ${TRIAL_FULL_DAYS}-day thing was real. You're in extra time \u2014 ${d} day${d === 1 ? "" : "s"}. /upgrade.`,
18860
+ (d) => `I'll leave you alone after this. ${d} day${d === 1 ? "" : "s"} \u2014 /upgrade or we part ways.`,
18861
+ (d) => `Genuinely hope you stick around. ${d} day${d === 1 ? "" : "s"} to decide. /upgrade.`,
18862
+ (d) => `Not trying to be pushy. ${d} day${d === 1 ? "" : "s"} is just what's left. /upgrade.`,
18863
+ (d) => `You've been at this a while \u2014 ${d} day${d === 1 ? "" : "s"} before the door closes. /upgrade.`,
18864
+ (d) => `Wanted to give you a heads up: ${d} day${d === 1 ? "" : "s"}. /upgrade keeps you in.`,
18865
+ (d) => `If you're still into it, cool. ${d} day${d === 1 ? "" : "s"} \u2014 /upgrade.`,
18866
+ (d) => `Last friendly ping. ${d} day${d === 1 ? "" : "s"}. /upgrade.`
18867
+ ];
18868
+ CUTOFF_NUDGES = [
18869
+ "Okay \u2014 that's the line. /upgrade and you're back.",
18870
+ "We're paused until you say yes. /upgrade.",
18871
+ "Didn't want it to end like this. /upgrade if you want in again.",
18872
+ "Time's up. /upgrade \u2014 takes a minute.",
18873
+ "I'll be here. You just need to /upgrade first.",
18874
+ "That's all I can do on the free side. /upgrade.",
18875
+ "Door's closed for now. /upgrade opens it."
18876
+ ];
18877
+ BLOCKED_WHILE_CUTOFF = [
18878
+ "Can't do that until you're back in \u2014 /upgrade.",
18879
+ "You're on the outside for now. /upgrade first.",
18880
+ "Need you on Pro for this. /upgrade \u2014 quick.",
18881
+ "Not available on the trial anymore. /upgrade, then try again."
18882
+ ];
18883
+ UPGRADE_HEADLINES = [
18884
+ () => "Still with us?",
18885
+ () => "Quick thing",
18886
+ (d) => d !== void 0 ? `${d} day${d === 1 ? "" : "s"} left` : "Let's sort this",
18887
+ () => "Wanted to check in",
18888
+ () => "One small step",
18889
+ () => "Stay?"
18890
+ ];
18891
+ UPGRADE_SUBTITLES = [
18892
+ (r) => r === "expired" ? "Trial's over. Checkout, key in your email, paste below." : r === "grace" ? `You've had ${TRIAL_FULL_DAYS} days plus a little extra. This is the part where you decide.` : "Checkout, email, paste. That's it.",
18893
+ (r) => r === "expired" ? "Nothing else changes. Same session, same data." : r === "grace" ? "I'm not in a hurry. The clock kind of is." : "No call. No runaround.",
18894
+ (r) => r === "expired" ? "Your work's still here. You just need a key." : r === "grace" ? "Stay if you want \u2014 just need to hear from you first." : "Sixty seconds, give or take."
18895
+ ];
18896
+ PRO_ACTIVATED_LINES = [
18897
+ "Good \u2014 you're in. Pick up where you left off.",
18898
+ "All set. Let's go.",
18899
+ "Thanks. Same place you were.",
18900
+ "Done. Back to it.",
18901
+ "Appreciate it.",
18902
+ "You're good. Continue."
18903
+ ];
18904
+ }
18905
+ });
18906
+
18907
+ // src/license/normalize.ts
18908
+ function normalizeLicenseKeyInput(raw) {
18909
+ let key = raw.trim();
18910
+ key = key.replace(/^\[>\s*/, "");
18911
+ key = key.replace(/^\[\s*▶\s*/, "");
18912
+ key = key.replace(/^▶\s*/, "");
18913
+ key = key.replace(/\s+/g, "");
18914
+ if (NTRP_PREFIX.test(key)) {
18915
+ return `NTRP-${key.replace(/^NTRP-/i, "").toLowerCase()}`;
18916
+ }
18917
+ if (UUID_KEY.test(key)) return key.toLowerCase();
18918
+ return key;
18919
+ }
18920
+ function detectLicenseFormat(key) {
18921
+ if (NTRP_PREFIX.test(key)) return "ntrp";
18922
+ if (UUID_KEY.test(key)) return "lemonsqueezy";
18923
+ return "unknown";
18924
+ }
18925
+ var NTRP_PREFIX, UUID_KEY;
18926
+ var init_normalize = __esm({
18927
+ "src/license/normalize.ts"() {
18928
+ "use strict";
18929
+ NTRP_PREFIX = /^NTRP-/i;
18930
+ UUID_KEY = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
18931
+ }
18932
+ });
18933
+
18934
+ // src/license/lemonsqueezy.ts
18935
+ import { hostname } from "os";
18936
+ function invalid(message) {
18937
+ return {
18938
+ valid: false,
18939
+ edition: "trial",
18940
+ expiresAt: null,
18941
+ message
18942
+ };
18943
+ }
18944
+ function editionFromMeta(meta) {
18945
+ const label = `${meta?.variant_name ?? ""} ${meta?.product_name ?? ""}`.toLowerCase();
18946
+ if (label.includes("trial")) return "trial";
18947
+ if (label.includes("team")) return "team";
18948
+ return "pro";
18949
+ }
18950
+ function expiresAtFromKey(licenseKey) {
18951
+ if (!licenseKey?.expires_at) return null;
18952
+ const parsed = new Date(licenseKey.expires_at);
18953
+ return Number.isNaN(parsed.getTime()) ? null : parsed;
18954
+ }
18955
+ function statusMessage(edition, expiresAt, meta) {
18956
+ const product = meta?.variant_name || meta?.product_name;
18957
+ const base = product ? `${edition} license (${product})` : `${edition} license`;
18958
+ return expiresAt ? `${base} (expires ${expiresAt.toISOString().slice(0, 10)})` : base;
18959
+ }
18960
+ function mapLsFailure(error, licenseKey) {
18961
+ const status = licenseKey?.status?.toLowerCase();
18962
+ if (status === "expired") {
18963
+ return invalid("Time's up \u2014 /upgrade and paste your key.");
18964
+ }
18965
+ if (status === "disabled") {
18966
+ return invalid("License disabled. Contact support or purchase a new license.");
18967
+ }
18968
+ if (error?.toLowerCase().includes("activation limit")) {
18969
+ return invalid(
18970
+ "License activation limit reached. Deactivate an old machine in your Lemon Squeezy account, then try again."
18971
+ );
18972
+ }
18973
+ return invalid(error?.trim() || "Could not activate license key");
18974
+ }
18975
+ async function postLicense(path, fields) {
18976
+ const body = new URLSearchParams(fields);
18977
+ const res = await fetch(`${LICENSE_API}/${path}`, {
18978
+ method: "POST",
18979
+ headers: { Accept: "application/json" },
18980
+ body,
18981
+ signal: AbortSignal.timeout(15e3)
18982
+ });
18983
+ const data = await res.json();
18984
+ if (!res.ok && !data.error) {
18985
+ throw new Error(`License server error (${res.status})`);
18986
+ }
18987
+ return data;
18988
+ }
18989
+ function defaultInstanceName() {
18990
+ const host = hostname().replace(/[^\w.-]/g, "-").slice(0, 48) || "machine";
18991
+ const user = (process.env.USER || process.env.USERNAME || "user").replace(/[^\w.-]/g, "-").slice(0, 15);
18992
+ return `ntrp-${host}-${user}`;
18993
+ }
18994
+ async function activateLemonSqueezyLicense(licenseKey, instanceName = defaultInstanceName()) {
18995
+ const data = await postLicense("activate", {
18996
+ license_key: licenseKey,
18997
+ instance_name: instanceName
18998
+ });
18999
+ if (!data.activated) {
19000
+ return mapLsFailure(data.error, data.license_key);
19001
+ }
19002
+ const edition = editionFromMeta(data.meta);
19003
+ const expiresAt = expiresAtFromKey(data.license_key);
19004
+ const instanceId = data.instance?.id;
19005
+ if (!instanceId) {
19006
+ return invalid("Activation succeeded but no instance id was returned. Try again.");
19007
+ }
19008
+ return {
19009
+ valid: true,
19010
+ edition,
19011
+ expiresAt,
19012
+ message: statusMessage(edition, expiresAt, data.meta),
19013
+ instanceId
19014
+ };
19015
+ }
19016
+ async function validateLemonSqueezyLicense(licenseKey, instanceId) {
19017
+ const data = await postLicense("validate", {
19018
+ license_key: licenseKey,
19019
+ instance_id: instanceId
19020
+ });
19021
+ if (!data.valid) {
19022
+ return mapLsFailure(data.error, data.license_key);
19023
+ }
19024
+ const edition = editionFromMeta(data.meta);
19025
+ const expiresAt = expiresAtFromKey(data.license_key);
19026
+ return {
19027
+ valid: true,
19028
+ edition,
19029
+ expiresAt,
19030
+ message: statusMessage(edition, expiresAt, data.meta)
19031
+ };
19032
+ }
19033
+ var LICENSE_API;
19034
+ var init_lemonsqueezy = __esm({
19035
+ "src/license/lemonsqueezy.ts"() {
19036
+ "use strict";
19037
+ LICENSE_API = "https://api.lemonsqueezy.com/v1/licenses";
18771
19038
  }
18772
19039
  });
18773
19040
 
18774
19041
  // src/license/verify.ts
18775
19042
  import { createHmac } from "crypto";
18776
19043
  function validateLicenseKey(key) {
18777
- const invalid = (msg) => ({
19044
+ const invalid2 = (msg) => ({
18778
19045
  valid: false,
18779
19046
  edition: "trial",
18780
19047
  expiresAt: null,
18781
19048
  message: msg
18782
19049
  });
18783
19050
  if (!key || !key.startsWith("NTRP-")) {
18784
- return invalid("Invalid key format");
19051
+ return invalid2("Invalid key format");
18785
19052
  }
18786
19053
  const parts = key.replace("NTRP-", "").split("-");
18787
19054
  if (parts.length !== 3) {
18788
- return invalid("Invalid key format");
19055
+ return invalid2("Invalid key format");
18789
19056
  }
18790
19057
  const [payload, meta, signature] = parts;
18791
19058
  const dataToSign = `${payload}-${meta}`;
18792
19059
  const expectedSig = createHmac("sha256", SIGNING_SECRET).update(dataToSign).digest("hex").slice(0, 8);
18793
19060
  if (signature !== expectedSig) {
18794
- return invalid("Invalid license key");
19061
+ return invalid2("Invalid license key");
18795
19062
  }
18796
19063
  const editionCode = meta.slice(0, 2);
18797
19064
  const expiryHex = meta.slice(2);
18798
19065
  const edition = editionCode === "01" ? "pro" : editionCode === "02" ? "team" : "trial";
18799
19066
  const expiryTs = parseInt(expiryHex, 16);
18800
19067
  const expiresAt = expiryTs > 0 ? new Date(expiryTs * 1e3) : null;
18801
- if (expiresAt && expiresAt < /* @__PURE__ */ new Date()) {
18802
- return invalid(`License expired on ${expiresAt.toISOString().slice(0, 10)}`);
19068
+ if (expiresAt && expiresAt < /* @__PURE__ */ new Date() && edition !== "trial") {
19069
+ return invalid2(`License expired on ${expiresAt.toISOString().slice(0, 10)}`);
18803
19070
  }
18804
19071
  return {
18805
19072
  valid: true,
18806
19073
  edition,
18807
19074
  expiresAt,
18808
- message: `${edition} license${expiresAt ? ` (expires ${expiresAt.toISOString().slice(0, 10)})` : " (perpetual)"}`
19075
+ message: edition === "trial" ? "trial license" : `${edition} license${expiresAt ? ` (expires ${expiresAt.toISOString().slice(0, 10)})` : " (perpetual)"}`
19076
+ };
19077
+ }
19078
+ function trialActivatedAt() {
19079
+ const stored = getConfigValue("license-activated-at");
19080
+ if (stored) {
19081
+ const parsed = new Date(stored);
19082
+ if (!Number.isNaN(parsed.getTime())) return parsed;
19083
+ }
19084
+ const now2 = /* @__PURE__ */ new Date();
19085
+ setConfigValue("license-activated-at", now2.toISOString());
19086
+ return now2;
19087
+ }
19088
+ function recordLicenseActivation(edition) {
19089
+ if (edition === "trial") {
19090
+ setConfigValue("license-activated-at", (/* @__PURE__ */ new Date()).toISOString());
19091
+ } else {
19092
+ deleteConfigValue("license-activated-at");
19093
+ }
19094
+ }
19095
+ function applyTrialPolicy(result) {
19096
+ if (result.edition !== "trial") return result;
19097
+ const trial = evaluateTrial(trialActivatedAt());
19098
+ if (trial.phase === "expired") {
19099
+ return {
19100
+ valid: false,
19101
+ edition: "trial",
19102
+ expiresAt: result.expiresAt,
19103
+ message: randomCutoffNudge(),
19104
+ trialPhase: "expired",
19105
+ shouldNudgeUpgrade: false,
19106
+ daysUntilLockout: 0
19107
+ };
19108
+ }
19109
+ const message = trial.phase === "grace" ? `trial license (grace \u2014 ${trial.daysUntilLockout} day${trial.daysUntilLockout === 1 ? "" : "s"} until lockout)` : formatTrialActiveMessage(trial.daysSinceActivation);
19110
+ return {
19111
+ ...result,
19112
+ message,
19113
+ trialPhase: trial.phase,
19114
+ shouldNudgeUpgrade: trial.shouldNudge,
19115
+ daysUntilLockout: trial.daysUntilLockout
18809
19116
  };
18810
19117
  }
19118
+ function storedLicenseProvider(key) {
19119
+ const configured = getConfigValue("license-provider");
19120
+ if (configured === "ntrp" || configured === "lemonsqueezy") return configured;
19121
+ return detectLicenseFormat(key) === "lemonsqueezy" ? "lemonsqueezy" : "ntrp";
19122
+ }
19123
+ function checkLemonSqueezyLicense(key) {
19124
+ const instanceId = getConfigValue("license-instance-id");
19125
+ if (!instanceId) {
19126
+ return {
19127
+ valid: false,
19128
+ edition: "trial",
19129
+ expiresAt: null,
19130
+ message: "License not activated on this machine. Run: ntrp activate <key>"
19131
+ };
19132
+ }
19133
+ const edition = getConfigValue("license-edition") ?? "pro";
19134
+ const base = {
19135
+ valid: true,
19136
+ edition,
19137
+ expiresAt: null,
19138
+ message: `${edition} license`
19139
+ };
19140
+ return applyTrialPolicy(base);
19141
+ }
19142
+ async function activateLicenseKey(rawKey) {
19143
+ const key = normalizeLicenseKeyInput(rawKey);
19144
+ const format = detectLicenseFormat(key);
19145
+ if (format === "unknown") {
19146
+ return {
19147
+ valid: false,
19148
+ edition: "trial",
19149
+ expiresAt: null,
19150
+ message: "Invalid key format"
19151
+ };
19152
+ }
19153
+ if (format === "ntrp") {
19154
+ const result = validateLicenseKey(key);
19155
+ if (!result.valid) return result;
19156
+ setConfigValue("license-key", key);
19157
+ setConfigValue("license-provider", "ntrp");
19158
+ deleteConfigValue("license-instance-id");
19159
+ deleteConfigValue("license-edition");
19160
+ recordLicenseActivation(result.edition);
19161
+ return checkLicense();
19162
+ }
19163
+ const activated = await activateLemonSqueezyLicense(key);
19164
+ if (!activated.valid || !activated.instanceId) return activated;
19165
+ setConfigValue("license-key", key);
19166
+ setConfigValue("license-provider", "lemonsqueezy");
19167
+ setConfigValue("license-instance-id", activated.instanceId);
19168
+ setConfigValue("license-edition", activated.edition);
19169
+ recordLicenseActivation(activated.edition);
19170
+ return checkLicense();
19171
+ }
19172
+ async function refreshLicenseOnline() {
19173
+ const key = getConfigValue("license-key");
19174
+ if (!key || storedLicenseProvider(key) !== "lemonsqueezy") {
19175
+ return checkLicense();
19176
+ }
19177
+ const instanceId = getConfigValue("license-instance-id");
19178
+ if (!instanceId) return checkLicense();
19179
+ try {
19180
+ const result = await validateLemonSqueezyLicense(key, instanceId);
19181
+ if (!result.valid) return result;
19182
+ setConfigValue("license-edition", result.edition);
19183
+ return checkLicense();
19184
+ } catch {
19185
+ return checkLicense();
19186
+ }
19187
+ }
18811
19188
  function checkLicense() {
18812
19189
  const key = getConfigValue("license-key");
18813
19190
  if (!key) {
@@ -18818,13 +19195,24 @@ function checkLicense() {
18818
19195
  message: "No license key found. Run: ntrp activate <key>"
18819
19196
  };
18820
19197
  }
18821
- return validateLicenseKey(key);
19198
+ if (storedLicenseProvider(key) === "lemonsqueezy") {
19199
+ return checkLemonSqueezyLicense(key);
19200
+ }
19201
+ const result = validateLicenseKey(key);
19202
+ if (!result.valid || result.edition !== "trial") {
19203
+ return result;
19204
+ }
19205
+ return applyTrialPolicy(result);
18822
19206
  }
18823
19207
  var SIGNING_SECRET;
18824
19208
  var init_verify = __esm({
18825
19209
  "src/license/verify.ts"() {
18826
19210
  "use strict";
18827
19211
  init_store();
19212
+ init_trial_policy();
19213
+ init_upgrade_whimsy();
19214
+ init_normalize();
19215
+ init_lemonsqueezy();
18828
19216
  SIGNING_SECRET = "ntrp-gtm-health-2026";
18829
19217
  }
18830
19218
  });
@@ -18840,27 +19228,282 @@ async function handler24(args, _ctx) {
18840
19228
  const key = positional[0];
18841
19229
  if (!key) {
18842
19230
  console.error(chalk38.red("\n Usage: /activate <key>"));
18843
- console.error(chalk38.dim(" License key format: NTRP-XXXX-XXXX-XXXX\n"));
19231
+ console.error(chalk38.dim(" Or type /upgrade for checkout + paste flow.\n"));
18844
19232
  process.exit(1);
18845
19233
  }
18846
- const result = validateLicenseKey(key);
18847
- if (!result.valid) {
19234
+ try {
19235
+ const result = await activateLicenseKey(key);
19236
+ if (!result.valid) {
19237
+ console.error(chalk38.red(`
19238
+ ${result.message}
19239
+ `));
19240
+ process.exit(1);
19241
+ }
19242
+ console.log(chalk38.green(`
19243
+ License activated: ${result.message}
19244
+ `));
19245
+ } catch (err) {
19246
+ const message = err instanceof Error ? err.message : "License activation failed";
18848
19247
  console.error(chalk38.red(`
18849
- Invalid license key: ${result.message}
19248
+ ${message}
18850
19249
  `));
19250
+ console.error(chalk38.dim(" Check your network connection and try again.\n"));
18851
19251
  process.exit(1);
18852
19252
  }
18853
- setConfigValue("license-key", key);
18854
- console.log(chalk38.green(`
18855
- License activated: ${result.message}
18856
- `));
18857
19253
  }
18858
19254
  var init_activate = __esm({
18859
19255
  "src/commands/activate.ts"() {
18860
19256
  "use strict";
19257
+ init_verify();
19258
+ init_argparse();
19259
+ }
19260
+ });
19261
+
19262
+ // src/ui/open-browser.ts
19263
+ import { spawn } from "child_process";
19264
+ import { platform } from "os";
19265
+ function openInBrowser(url) {
19266
+ return new Promise((resolve9, reject) => {
19267
+ let cmd;
19268
+ let args;
19269
+ switch (platform()) {
19270
+ case "darwin":
19271
+ cmd = "open";
19272
+ args = [url];
19273
+ break;
19274
+ case "win32":
19275
+ cmd = "cmd";
19276
+ args = ["/c", "start", "", url];
19277
+ break;
19278
+ default:
19279
+ cmd = "xdg-open";
19280
+ args = [url];
19281
+ break;
19282
+ }
19283
+ const child = spawn(cmd, args, { detached: true, stdio: "ignore" });
19284
+ child.on("error", reject);
19285
+ child.unref();
19286
+ resolve9();
19287
+ });
19288
+ }
19289
+ var init_open_browser = __esm({
19290
+ "src/ui/open-browser.ts"() {
19291
+ "use strict";
19292
+ }
19293
+ });
19294
+
19295
+ // src/license/upgrade.ts
19296
+ var upgrade_exports = {};
19297
+ __export(upgrade_exports, {
19298
+ getUpgradeUrl: () => getUpgradeUrl,
19299
+ hasStoredLicenseKey: () => hasStoredLicenseKey,
19300
+ isTrialCutoff: () => isTrialCutoff,
19301
+ isTrialGrace: () => isTrialGrace,
19302
+ openCheckoutInBrowser: () => openCheckoutInBrowser,
19303
+ printGraceNudge: () => printGraceNudge,
19304
+ printLicenseBlocked: () => printLicenseBlocked,
19305
+ promptForLicenseKey: () => promptForLicenseKey,
19306
+ promptOpenCheckout: () => promptOpenCheckout,
19307
+ resolveUpgradeReason: () => resolveUpgradeReason,
19308
+ runUpgradeFlow: () => runUpgradeFlow
19309
+ });
19310
+ import chalk39 from "chalk";
19311
+ function getUpgradeUrl() {
19312
+ return getCheckoutUrl();
19313
+ }
19314
+ function isTrialCutoff(lic) {
19315
+ return lic.trialPhase === "expired";
19316
+ }
19317
+ function isTrialGrace(lic) {
19318
+ return lic.trialPhase === "grace";
19319
+ }
19320
+ function printLicenseBlocked(context) {
19321
+ const lic = checkLicense();
19322
+ console.log();
19323
+ if (isTrialCutoff(lic)) {
19324
+ console.log(" " + chalk39.yellow(randomBlockedNudge()));
19325
+ } else {
19326
+ console.log(chalk39.red(` A license is required for ${context}.`));
19327
+ console.log(
19328
+ " " + chalk39.dim("Type ") + paint("accent", "/upgrade") + chalk39.dim(" or ") + paint("accent", "/checkout") + chalk39.dim(" to get a license.")
19329
+ );
19330
+ }
19331
+ console.log();
19332
+ }
19333
+ function printGraceNudge(lic) {
19334
+ if (!lic.shouldNudgeUpgrade || lic.daysUntilLockout === void 0) return;
19335
+ console.log(" " + chalk39.yellow(randomGraceNudge(lic.daysUntilLockout)));
19336
+ console.log();
19337
+ }
19338
+ function headlineFor(reason, lic) {
19339
+ return randomUpgradeHeadline(lic.daysUntilLockout);
19340
+ }
19341
+ function subtitleFor(reason) {
19342
+ return randomUpgradeSubtitle(reason);
19343
+ }
19344
+ async function promptOpenCheckout(ctx) {
19345
+ const url = getUpgradeUrl();
19346
+ console.log(" " + chalk39.dim(url));
19347
+ if (!process.stdin.isTTY || process.env.NTRP_NO_BROWSER_OPEN === "1") {
19348
+ console.log();
19349
+ return;
19350
+ }
19351
+ const session = createPromptSession(ctx.rl, ctx);
19352
+ try {
19353
+ console.log();
19354
+ await session.askPressEnter("Open checkout in your browser");
19355
+ try {
19356
+ await openInBrowser(url);
19357
+ console.log(" " + chalk39.green("\u2713 Browser opened"));
19358
+ console.log(" " + chalk39.dim("Complete signup in your browser, then paste your key below."));
19359
+ } catch {
19360
+ console.log(" " + chalk39.yellow("Couldn't open browser \u2014 copy the URL above."));
19361
+ }
19362
+ console.log();
19363
+ } finally {
19364
+ session.close();
19365
+ }
19366
+ }
19367
+ async function openCheckoutInBrowser() {
19368
+ const url = getUpgradeUrl();
19369
+ console.log();
19370
+ console.log(" " + chalk39.dim(url));
19371
+ if (!process.stdin.isTTY) {
19372
+ console.log();
19373
+ return;
19374
+ }
19375
+ try {
19376
+ await openInBrowser(url);
19377
+ console.log(" " + chalk39.green("\u2713 Browser opened"));
19378
+ } catch {
19379
+ console.log(" " + chalk39.yellow("Couldn't open browser \u2014 copy the URL above."));
19380
+ }
19381
+ console.log(" " + chalk39.dim("After signup, paste your key with /activate or /upgrade."));
19382
+ console.log();
19383
+ }
19384
+ async function promptForLicenseKey(ctx) {
19385
+ const session = createPromptSession(ctx.rl, ctx);
19386
+ try {
19387
+ for (; ; ) {
19388
+ const key = await session.askSecret("Paste your license key", { confirm: false });
19389
+ if (!key.trim()) {
19390
+ console.log(" " + chalk39.red("A license key is required."));
19391
+ continue;
19392
+ }
19393
+ let result;
19394
+ try {
19395
+ result = await activateLicenseKey(key.trim());
19396
+ } catch (err) {
19397
+ const message = err instanceof Error ? err.message : "License activation failed";
19398
+ console.log(" " + chalk39.red(message));
19399
+ console.log(" " + chalk39.dim("Check your network connection and try again."));
19400
+ console.log();
19401
+ continue;
19402
+ }
19403
+ if (!result.valid) {
19404
+ console.log(" " + chalk39.red(result.message));
19405
+ console.log(" " + chalk39.dim(`Use the key from your purchase email, or try again: ${getUpgradeUrl()}`));
19406
+ console.log();
19407
+ continue;
19408
+ }
19409
+ console.log();
19410
+ console.log(chalk39.green(` \u2713 ${randomProActivatedLine()}`));
19411
+ console.log();
19412
+ return true;
19413
+ }
19414
+ } finally {
19415
+ session.close();
19416
+ }
19417
+ }
19418
+ async function runUpgradeFlow(ctx, reason) {
19419
+ const lic = checkLicense();
19420
+ printCenteredLogo();
19421
+ console.log(" " + bold(headlineFor(reason, lic)));
19422
+ console.log(" " + chalk39.dim(subtitleFor(reason)));
19423
+ console.log();
19424
+ await promptOpenCheckout(ctx);
19425
+ console.log(" " + chalk39.dim("Paste your license key when it arrives by email"));
19426
+ console.log();
19427
+ return promptForLicenseKey(ctx);
19428
+ }
19429
+ function resolveUpgradeReason() {
19430
+ const lic = checkLicense();
19431
+ if (isTrialCutoff(lic)) return "expired";
19432
+ if (isTrialGrace(lic)) return "grace";
19433
+ return "convert";
19434
+ }
19435
+ function hasStoredLicenseKey() {
19436
+ return Boolean(getConfigValue("license-key"));
19437
+ }
19438
+ var init_upgrade = __esm({
19439
+ "src/license/upgrade.ts"() {
19440
+ "use strict";
19441
+ init_prompts();
18861
19442
  init_store();
19443
+ init_banner();
19444
+ init_theme();
18862
19445
  init_verify();
19446
+ init_trial_policy();
19447
+ init_upgrade_whimsy();
19448
+ init_open_browser();
19449
+ }
19450
+ });
19451
+
19452
+ // src/commands/upgrade.ts
19453
+ var upgrade_exports2 = {};
19454
+ __export(upgrade_exports2, {
19455
+ handler: () => handler25
19456
+ });
19457
+ import chalk40 from "chalk";
19458
+ async function handler25(args, ctx) {
19459
+ const { flags } = parseArgs2(args);
19460
+ const lic = await refreshLicenseOnline();
19461
+ if (getBool(flags, "url", "checkout")) {
19462
+ console.log(getUpgradeUrl());
19463
+ return;
19464
+ }
19465
+ if (lic.valid && lic.edition !== "trial" && lic.trialPhase !== "grace") {
19466
+ console.log();
19467
+ console.log(chalk40.green(" You're already on a paid license."));
19468
+ console.log(" " + chalk40.dim(`${lic.message}`));
19469
+ console.log(" " + chalk40.dim(`Need another seat? ${getUpgradeUrl()}`));
19470
+ console.log();
19471
+ return;
19472
+ }
19473
+ if (!process.stdin.isTTY) {
19474
+ console.error(chalk40.red("\n /upgrade requires an interactive terminal.\n"));
19475
+ console.error(chalk40.dim(` Purchase at ${getUpgradeUrl()}
19476
+ `));
19477
+ console.error(chalk40.dim(" Then run: ntrp activate <your-pro-key>\n"));
19478
+ process.exit(1);
19479
+ }
19480
+ const reason = resolveUpgradeReason();
19481
+ const activated = await runUpgradeFlow(ctx, reason);
19482
+ if (!activated) {
19483
+ process.exit(1);
19484
+ }
19485
+ }
19486
+ var init_upgrade2 = __esm({
19487
+ "src/commands/upgrade.ts"() {
19488
+ "use strict";
18863
19489
  init_argparse();
19490
+ init_upgrade();
19491
+ init_verify();
19492
+ }
19493
+ });
19494
+
19495
+ // src/commands/checkout.ts
19496
+ var checkout_exports = {};
19497
+ __export(checkout_exports, {
19498
+ handler: () => handler26
19499
+ });
19500
+ async function handler26(_args, _ctx) {
19501
+ await openCheckoutInBrowser();
19502
+ }
19503
+ var init_checkout = __esm({
19504
+ "src/commands/checkout.ts"() {
19505
+ "use strict";
19506
+ init_upgrade();
18864
19507
  }
18865
19508
  });
18866
19509
 
@@ -18903,7 +19546,9 @@ function setupCheck() {
18903
19546
  },
18904
19547
  license: {
18905
19548
  valid: license.valid,
18906
- message: license.message
19549
+ message: license.message,
19550
+ trial_phase: license.trialPhase ?? null,
19551
+ days_until_lockout: license.daysUntilLockout ?? null
18907
19552
  }
18908
19553
  };
18909
19554
  }
@@ -18957,10 +19602,10 @@ var init_setup = __esm({
18957
19602
  // src/commands/setup.ts
18958
19603
  var setup_exports = {};
18959
19604
  __export(setup_exports, {
18960
- handler: () => handler25
19605
+ handler: () => handler27
18961
19606
  });
18962
- import chalk39 from "chalk";
18963
- async function handler25(args, ctx) {
19607
+ import chalk41 from "chalk";
19608
+ async function handler27(args, ctx) {
18964
19609
  const { positional, flags } = parseArgs2(args);
18965
19610
  const sub = positional[0] ?? "check";
18966
19611
  try {
@@ -18972,7 +19617,7 @@ async function handler25(args, ctx) {
18972
19617
  return;
18973
19618
  }
18974
19619
  console.log();
18975
- console.log(chalk39.bold(" Setup Check"));
19620
+ console.log(chalk41.bold(" Setup Check"));
18976
19621
  console.log(` NTRP home: ${result.ntrp_home}`);
18977
19622
  console.log(` Writable: ${result.writable ? "yes" : "no"}`);
18978
19623
  console.log(` Profile: ${result.profile.exists ? "ready" : "missing"} (${result.profile.path})`);
@@ -19018,7 +19663,7 @@ async function handler25(args, ctx) {
19018
19663
  emitResult("setup", result);
19019
19664
  return;
19020
19665
  }
19021
- console.log(chalk39.green(`
19666
+ console.log(chalk41.green(`
19022
19667
  Agent setup written for ${profile.company_name || "NTRP"}.
19023
19668
  `));
19024
19669
  return;
@@ -19030,7 +19675,7 @@ async function handler25(args, ctx) {
19030
19675
  if (isStructuredOutput(ctx.execution)) {
19031
19676
  emitError("setup", err);
19032
19677
  }
19033
- console.error(chalk39.red(String(err)));
19678
+ console.error(chalk41.red(String(err)));
19034
19679
  process.exit(err instanceof NtrpError ? err.exitCode : 1);
19035
19680
  }
19036
19681
  }
@@ -19046,25 +19691,25 @@ var init_setup2 = __esm({
19046
19691
  });
19047
19692
 
19048
19693
  // src/conversation/orchestrator.ts
19049
- import chalk40 from "chalk";
19694
+ import chalk42 from "chalk";
19050
19695
  import { writeFileSync as writeFileSync12 } from "fs";
19051
19696
  import { join as join17 } from "path";
19052
19697
  function printScopeProposal(ctx) {
19053
19698
  if (!ctx.scope) return;
19054
19699
  const lens = ctx.scope.primary_lens === "revenue_metrics" ? "SaaS metrics" : "pipeline health";
19055
19700
  console.log();
19056
- console.log(" " + chalk40.bold("Proposed focus"));
19057
- console.log(" " + chalk40.dim(`Lens: `) + paint("accent", lens));
19058
- console.log(" " + chalk40.dim(`Intent: ${ctx.scope.intent_summary}`));
19701
+ console.log(" " + chalk42.bold("Proposed focus"));
19702
+ console.log(" " + chalk42.dim(`Lens: `) + paint("accent", lens));
19703
+ console.log(" " + chalk42.dim(`Intent: ${ctx.scope.intent_summary}`));
19059
19704
  if (ctx.scope.audience) {
19060
- console.log(" " + chalk40.dim(`Audience: ${ctx.scope.audience}`));
19705
+ console.log(" " + chalk42.dim(`Audience: ${ctx.scope.audience}`));
19061
19706
  }
19062
19707
  if (ctx.scope.time_horizon) {
19063
- console.log(" " + chalk40.dim(`Period: ${ctx.scope.time_horizon}`));
19708
+ console.log(" " + chalk42.dim(`Period: ${ctx.scope.time_horizon}`));
19064
19709
  }
19065
19710
  console.log();
19066
19711
  console.log(
19067
- " " + chalk40.dim("Confirm? ") + chalk40.cyan("yes") + chalk40.dim(" \xB7 ") + chalk40.cyan("adjust")
19712
+ " " + chalk42.dim("Confirm? ") + chalk42.cyan("yes") + chalk42.dim(" \xB7 ") + chalk42.cyan("adjust")
19068
19713
  );
19069
19714
  console.log();
19070
19715
  }
@@ -19075,7 +19720,7 @@ async function handleDeterministic(input, ctx) {
19075
19720
  if (!ctx[ORIENT_HINT_PRINTED]) {
19076
19721
  console.log();
19077
19722
  console.log(
19078
- " " + chalk40.dim("What do you want to look at? ") + chalk40.dim('(e.g. "pipeline health", "is NRR real?", "board deck on Q3")')
19723
+ " " + chalk42.dim("What do you want to look at? ") + chalk42.dim('(e.g. "pipeline health", "is NRR real?", "board deck on Q3")')
19079
19724
  );
19080
19725
  console.log();
19081
19726
  ctx[ORIENT_HINT_PRINTED] = true;
@@ -19088,7 +19733,7 @@ async function handleDeterministic(input, ctx) {
19088
19733
  saveSessionState(ctx);
19089
19734
  recordMessage(ctx, "user", line);
19090
19735
  if (proposal.clarifying_question) {
19091
- console.log(" " + chalk40.dim(proposal.clarifying_question));
19736
+ console.log(" " + chalk42.dim(proposal.clarifying_question));
19092
19737
  recordMessage(ctx, "agent", proposal.clarifying_question);
19093
19738
  return "Scope proposed";
19094
19739
  }
@@ -19100,7 +19745,7 @@ async function handleDeterministic(input, ctx) {
19100
19745
  recordMessage(ctx, "user", line);
19101
19746
  if (isScopeAdjustInput(line)) {
19102
19747
  console.log();
19103
- console.log(" " + chalk40.dim("What should we focus on instead?"));
19748
+ console.log(" " + chalk42.dim("What should we focus on instead?"));
19104
19749
  ctx.scope = void 0;
19105
19750
  saveSessionState(ctx);
19106
19751
  return "Scope cleared";
@@ -19173,25 +19818,25 @@ async function handleDeliverFlow(input, ctx) {
19173
19818
  const draft = await buildDeliverableDraft(ctx, target);
19174
19819
  if (!draft) {
19175
19820
  console.log();
19176
- console.log(" " + chalk40.red("Nothing to ship yet \u2014 load data and run analysis first."));
19821
+ console.log(" " + chalk42.red("Nothing to ship yet \u2014 load data and run analysis first."));
19177
19822
  console.log();
19178
19823
  ctx.deliverIntent = false;
19179
19824
  return;
19180
19825
  }
19181
19826
  console.log();
19182
- console.log(" " + chalk40.bold("Deliverable preview"));
19183
- console.log(" " + chalk40.dim("\u2500".repeat(56)));
19827
+ console.log(" " + chalk42.bold("Deliverable preview"));
19828
+ console.log(" " + chalk42.dim("\u2500".repeat(56)));
19184
19829
  const preview = draft.markdown.split("\n").slice(0, 24);
19185
19830
  for (const l of preview) {
19186
- console.log(" " + chalk40.dim(l));
19831
+ console.log(" " + chalk42.dim(l));
19187
19832
  }
19188
19833
  if (draft.markdown.split("\n").length > 24) {
19189
- console.log(" " + chalk40.dim("\u2026"));
19834
+ console.log(" " + chalk42.dim("\u2026"));
19190
19835
  }
19191
- console.log(" " + chalk40.dim("\u2500".repeat(56)));
19836
+ console.log(" " + chalk42.dim("\u2500".repeat(56)));
19192
19837
  console.log();
19193
19838
  if (!ctx.rl) {
19194
- console.log(" " + chalk40.dim("Run interactively to confirm write."));
19839
+ console.log(" " + chalk42.dim("Run interactively to confirm write."));
19195
19840
  return;
19196
19841
  }
19197
19842
  const prompts = createPromptSession(ctx.rl, ctx);
@@ -19199,7 +19844,7 @@ async function handleDeliverFlow(input, ctx) {
19199
19844
  const ok = await prompts.confirm("Write handoff prompt to exports and mark delivered?", true);
19200
19845
  if (!ok) {
19201
19846
  ctx.deliverIntent = false;
19202
- console.log(" " + chalk40.dim("Kept as preview only \u2014 session not marked delivered."));
19847
+ console.log(" " + chalk42.dim("Kept as preview only \u2014 session not marked delivered."));
19203
19848
  return "Preview only";
19204
19849
  }
19205
19850
  } finally {
@@ -19219,8 +19864,8 @@ async function handleDeliverFlow(input, ctx) {
19219
19864
  saveSessionState(ctx);
19220
19865
  console.log();
19221
19866
  console.log(" " + paint("accent", `Handoff prompt ready (${target})`));
19222
- console.log(" " + chalk40.dim(out));
19223
- console.log(" " + chalk40.dim("Paste into another agent to build the deliverable."));
19867
+ console.log(" " + chalk42.dim(out));
19868
+ console.log(" " + chalk42.dim("Paste into another agent to build the deliverable."));
19224
19869
  console.log();
19225
19870
  recordMessage(ctx, "user", input);
19226
19871
  recordMessage(ctx, "agent", `Wrote ${target} handoff prompt to ${out}`);
@@ -19228,11 +19873,11 @@ async function handleDeliverFlow(input, ctx) {
19228
19873
  }
19229
19874
  async function handleExploreWithoutKey(ctx) {
19230
19875
  console.log();
19231
- console.log(" " + chalk40.red("AI interpretation needs an LLM API key saved in config."));
19876
+ console.log(" " + chalk42.red("AI interpretation needs an LLM API key saved in config."));
19232
19877
  console.log(
19233
- " " + chalk40.dim("Set with: ") + paint("accent", "/config set api-key") + chalk40.dim(" (Anthropic) or ") + paint("accent", "/config set openai-api-key")
19878
+ " " + chalk42.dim("Set with: ") + paint("accent", "/config set api-key") + chalk42.dim(" (Anthropic) or ") + paint("accent", "/config set openai-api-key")
19234
19879
  );
19235
- console.log(" " + chalk40.dim("Number crunching works without a key \u2014 only Q&A in the REPL needs one."));
19880
+ console.log(" " + chalk42.dim("Number crunching works without a key \u2014 only Q&A in the REPL needs one."));
19236
19881
  if (ctx.gapAudit) {
19237
19882
  printGapCard(ctx.gapAudit);
19238
19883
  }
@@ -19999,7 +20644,7 @@ __export(nl_exports, {
19999
20644
  runNaturalLanguage: () => runNaturalLanguage
20000
20645
  });
20001
20646
  import ora10 from "ora";
20002
- import chalk41 from "chalk";
20647
+ import chalk43 from "chalk";
20003
20648
  async function runNaturalLanguage(input, ctx) {
20004
20649
  if (isSmokeProtocolTrigger(input)) {
20005
20650
  recordMessage(ctx, "user", input);
@@ -20014,7 +20659,7 @@ async function runNaturalLanguage(input, ctx) {
20014
20659
  return extractSummary(result.answer);
20015
20660
  } catch (err) {
20016
20661
  spinner2.fail("Smoke protocol failed");
20017
- console.error(" " + chalk41.red(String(err.message ?? err)));
20662
+ console.error(" " + chalk43.red(String(err.message ?? err)));
20018
20663
  console.log();
20019
20664
  return;
20020
20665
  }
@@ -20048,8 +20693,8 @@ async function runNaturalLanguage(input, ctx) {
20048
20693
  spinner2.succeed(metricsFirst ? "Session context ready" : "Health snapshot ready");
20049
20694
  } catch (err) {
20050
20695
  spinner2.fail("Could not compute health snapshot");
20051
- console.error(" " + chalk41.red(String(err.message ?? err)));
20052
- console.log(" " + chalk41.dim("Run ") + paint("accent", "/new") + chalk41.dim(" \u2192 pick Demo to load sample data."));
20696
+ console.error(" " + chalk43.red(String(err.message ?? err)));
20697
+ console.log(" " + chalk43.dim("Run ") + paint("accent", "/new") + chalk43.dim(" \u2192 pick Demo to load sample data."));
20053
20698
  console.log();
20054
20699
  return;
20055
20700
  }
@@ -20087,7 +20732,7 @@ async function runNaturalLanguage(input, ctx) {
20087
20732
  break;
20088
20733
  case "thinking":
20089
20734
  spinner.stop();
20090
- console.log(" " + chalk41.dim.italic(event.text));
20735
+ console.log(" " + chalk43.dim.italic(event.text));
20091
20736
  spinner.start("Thinking\u2026");
20092
20737
  break;
20093
20738
  case "answer":
@@ -20107,7 +20752,7 @@ async function runNaturalLanguage(input, ctx) {
20107
20752
  }
20108
20753
  } catch (err) {
20109
20754
  spinner.fail("Error while investigating");
20110
- console.error(" " + chalk41.red(String(err.message ?? err)));
20755
+ console.error(" " + chalk43.red(String(err.message ?? err)));
20111
20756
  console.log();
20112
20757
  return;
20113
20758
  } finally {
@@ -20117,7 +20762,7 @@ async function runNaturalLanguage(input, ctx) {
20117
20762
  ctx.conversation = distillThread(rawHistory);
20118
20763
  }
20119
20764
  if (!lastAnswer) {
20120
- console.log(" " + chalk41.dim("(no answer returned)"));
20765
+ console.log(" " + chalk43.dim("(no answer returned)"));
20121
20766
  } else {
20122
20767
  recordMessage(ctx, "agent", lastAnswer);
20123
20768
  saveSessionState(ctx);
@@ -20140,12 +20785,12 @@ function extractSummary(text) {
20140
20785
  }
20141
20786
  function printFindingInline(finding) {
20142
20787
  const sev = finding.severity;
20143
- const color = sev === "critical" ? chalk41.red : sev === "warning" ? chalk41.yellow : chalk41.blue;
20788
+ const color = sev === "critical" ? chalk43.red : sev === "warning" ? chalk43.yellow : chalk43.blue;
20144
20789
  console.log();
20145
- console.log(" " + color(`[${sev}]`) + " " + chalk41.bold(finding.segment));
20790
+ console.log(" " + color(`[${sev}]`) + " " + chalk43.bold(finding.segment));
20146
20791
  printMarkdown(finding.finding, { indent: 2 });
20147
20792
  const play = finding.recommended_plays?.[0];
20148
- if (play) console.log(" " + chalk41.dim("\u2192 " + play.play_name + " \u2014 " + play.rationale));
20793
+ if (play) console.log(" " + chalk43.dim("\u2192 " + play.play_name + " \u2014 " + play.rationale));
20149
20794
  }
20150
20795
  var init_nl = __esm({
20151
20796
  "src/cli/nl.ts"() {
@@ -20269,21 +20914,21 @@ var init_ask = __esm({
20269
20914
  // src/commands/ask.ts
20270
20915
  var ask_exports = {};
20271
20916
  __export(ask_exports, {
20272
- handler: () => handler26
20917
+ handler: () => handler28
20273
20918
  });
20274
- import chalk42 from "chalk";
20275
- async function handler26(args, ctx) {
20919
+ import chalk44 from "chalk";
20920
+ async function handler28(args, ctx) {
20276
20921
  const question = args.join(" ").trim();
20277
20922
  if (!question) {
20278
20923
  if (isStructuredOutput(ctx.execution)) {
20279
20924
  emitError("ask", new NtrpError("question_required", "Ask requires a question.", 2 /* Usage */));
20280
20925
  }
20281
20926
  console.log();
20282
- console.log(" " + chalk42.dim("Ask a question about your pipeline in plain English."));
20927
+ console.log(" " + chalk44.dim("Ask a question about your pipeline in plain English."));
20283
20928
  console.log(
20284
- " " + chalk42.dim("Example: ") + paint("accent", "/ask which deals are stuck the longest?")
20929
+ " " + chalk44.dim("Example: ") + paint("accent", "/ask which deals are stuck the longest?")
20285
20930
  );
20286
- console.log(" " + chalk42.dim("Or just type your question at the prompt \u2014 no slash needed."));
20931
+ console.log(" " + chalk44.dim("Or just type your question at the prompt \u2014 no slash needed."));
20287
20932
  console.log();
20288
20933
  return;
20289
20934
  }
@@ -20295,8 +20940,8 @@ async function handler26(args, ctx) {
20295
20940
  return;
20296
20941
  }
20297
20942
  console.log();
20298
- console.log(" " + chalk42.red("Ask runs only in the interactive REPL."));
20299
- console.log(" " + chalk42.dim("Start with ") + paint("accent", "ntrp") + chalk42.dim(", set LLM keys via /config, then ask in plain English."));
20943
+ console.log(" " + chalk44.red("Ask runs only in the interactive REPL."));
20944
+ console.log(" " + chalk44.dim("Start with ") + paint("accent", "ntrp") + chalk44.dim(", set LLM keys via /config, then ask in plain English."));
20300
20945
  console.log();
20301
20946
  return;
20302
20947
  }
@@ -20342,20 +20987,20 @@ var init_ask2 = __esm({
20342
20987
  // src/commands/metrics.ts
20343
20988
  var metrics_exports = {};
20344
20989
  __export(metrics_exports, {
20345
- handler: () => handler27
20990
+ handler: () => handler29
20346
20991
  });
20347
- import chalk43 from "chalk";
20992
+ import chalk45 from "chalk";
20348
20993
  import ora11 from "ora";
20349
- async function handler27(args, ctx) {
20994
+ async function handler29(args, ctx) {
20350
20995
  await hydrateAnalysisFromPersistedState(ctx);
20351
20996
  const { flags } = parseArgs2(args, ["findings"]);
20352
20997
  const segmentFilter = getString(flags, "segment");
20353
20998
  const withFindings = getBool(flags, "findings");
20354
20999
  if (withFindings && !canUseReplAi(ctx)) {
20355
21000
  console.log();
20356
- console.log(" " + chalk43.red("AI findings run only in the interactive REPL."));
20357
- console.log(" " + chalk43.dim("Metrics numbers compute without a key \u2014 omit --findings for numbers only."));
20358
- console.log(" " + chalk43.dim("Start with ") + paint("accent", "ntrp") + chalk43.dim(", set LLM keys via /config, then /metrics --findings."));
21001
+ console.log(" " + chalk45.red("AI findings run only in the interactive REPL."));
21002
+ console.log(" " + chalk45.dim("Metrics numbers compute without a key \u2014 omit --findings for numbers only."));
21003
+ console.log(" " + chalk45.dim("Start with ") + paint("accent", "ntrp") + chalk45.dim(", set LLM keys via /config, then /metrics --findings."));
20359
21004
  console.log();
20360
21005
  return;
20361
21006
  }
@@ -20421,7 +21066,7 @@ async function handler27(args, ctx) {
20421
21066
  }
20422
21067
  } else if (segmentFilter) {
20423
21068
  console.log();
20424
- console.log(chalk43.red(` No segment matching "${segmentFilter}".`));
21069
+ console.log(chalk45.red(` No segment matching "${segmentFilter}".`));
20425
21070
  console.log();
20426
21071
  } else {
20427
21072
  renderMetricsReport(ctx, result.metrics.aggregate.metrics, result.coverage, result.data_source_type, {
@@ -20433,7 +21078,7 @@ async function handler27(args, ctx) {
20433
21078
  }
20434
21079
  } catch (err) {
20435
21080
  spinner.fail("Metrics computation failed");
20436
- console.error(chalk43.red(String(err)));
21081
+ console.error(chalk45.red(String(err)));
20437
21082
  process.exit(1);
20438
21083
  }
20439
21084
  }
@@ -20581,17 +21226,17 @@ OUTPUT FORMAT \u2014 STRICT JSON only, no preamble, no markdown fences:
20581
21226
  // src/commands/feedback.ts
20582
21227
  var feedback_exports = {};
20583
21228
  __export(feedback_exports, {
20584
- handler: () => handler28
21229
+ handler: () => handler30
20585
21230
  });
20586
- import chalk44 from "chalk";
21231
+ import chalk46 from "chalk";
20587
21232
  import ora12 from "ora";
20588
- async function handler28(args, ctx) {
21233
+ async function handler30(args, ctx) {
20589
21234
  const feedbackText = args.join(" ").trim();
20590
21235
  if (!feedbackText) {
20591
21236
  console.log();
20592
- console.log(" " + chalk44.dim("Tell NTRP something it got wrong or doesn't know yet."));
21237
+ console.log(" " + chalk46.dim("Tell NTRP something it got wrong or doesn't know yet."));
20593
21238
  console.log(
20594
- " " + chalk44.dim("Example: ") + paint("accent", '/feedback "We have SDRs, not BDRs"')
21239
+ " " + chalk46.dim("Example: ") + paint("accent", '/feedback "We have SDRs, not BDRs"')
20595
21240
  );
20596
21241
  console.log();
20597
21242
  return;
@@ -20599,8 +21244,8 @@ async function handler28(args, ctx) {
20599
21244
  const profile = loadProfile();
20600
21245
  if (!profile) {
20601
21246
  console.log();
20602
- console.log(" " + chalk44.red("No company profile found."));
20603
- console.log(" " + chalk44.dim("Run ") + paint("accent", "/onboard") + chalk44.dim(" first to create one."));
21247
+ console.log(" " + chalk46.red("No company profile found."));
21248
+ console.log(" " + chalk46.dim("Run ") + paint("accent", "/onboard") + chalk46.dim(" first to create one."));
20604
21249
  console.log();
20605
21250
  return;
20606
21251
  }
@@ -20608,7 +21253,7 @@ async function handler28(args, ctx) {
20608
21253
  assertReplAi(ctx);
20609
21254
  } catch (err) {
20610
21255
  console.log();
20611
- console.log(" " + chalk44.red(String(err.message ?? err)));
21256
+ console.log(" " + chalk46.red(String(err.message ?? err)));
20612
21257
  console.log();
20613
21258
  return;
20614
21259
  }
@@ -20624,7 +21269,7 @@ async function handler28(args, ctx) {
20624
21269
  ${result.change_summary}`);
20625
21270
  } catch (err) {
20626
21271
  spinner.fail("Couldn't apply feedback");
20627
- console.log(" " + chalk44.dim(String(err.message ?? err)));
21272
+ console.log(" " + chalk46.dim(String(err.message ?? err)));
20628
21273
  }
20629
21274
  }
20630
21275
  var init_feedback = __esm({
@@ -20642,15 +21287,15 @@ var init_feedback = __esm({
20642
21287
  // src/commands/recap.ts
20643
21288
  var recap_exports = {};
20644
21289
  __export(recap_exports, {
20645
- handler: () => handler29
21290
+ handler: () => handler31
20646
21291
  });
20647
21292
  import ora13 from "ora";
20648
- import chalk45 from "chalk";
20649
- async function handler29(_args, ctx) {
21293
+ import chalk47 from "chalk";
21294
+ async function handler31(_args, ctx) {
20650
21295
  if (ctx.messages.length === 0) {
20651
21296
  console.log();
20652
- console.log(" " + chalk45.dim("Nothing to recap \u2014 no NL exchanges this session."));
20653
- console.log(" " + chalk45.dim("Ask a plain-English question first, then run /recap."));
21297
+ console.log(" " + chalk47.dim("Nothing to recap \u2014 no NL exchanges this session."));
21298
+ console.log(" " + chalk47.dim("Ask a plain-English question first, then run /recap."));
20654
21299
  console.log();
20655
21300
  return;
20656
21301
  }
@@ -20658,7 +21303,7 @@ async function handler29(_args, ctx) {
20658
21303
  assertReplAi(ctx);
20659
21304
  } catch (err) {
20660
21305
  console.log();
20661
- console.log(" " + chalk45.red(String(err.message ?? err)));
21306
+ console.log(" " + chalk47.red(String(err.message ?? err)));
20662
21307
  console.log();
20663
21308
  return;
20664
21309
  }
@@ -20700,7 +21345,7 @@ ${conversationLines.join("\n\n")}`,
20700
21345
  return `${exchangeCount} exchange${exchangeCount === 1 ? "" : "s"} summarized`;
20701
21346
  } catch (err) {
20702
21347
  spinner.fail("Recap failed");
20703
- console.error(" " + chalk45.red(String(err.message ?? err)));
21348
+ console.error(" " + chalk47.red(String(err.message ?? err)));
20704
21349
  console.log();
20705
21350
  }
20706
21351
  }
@@ -20717,16 +21362,16 @@ var init_recap = __esm({
20717
21362
  // src/commands/remember.ts
20718
21363
  var remember_exports = {};
20719
21364
  __export(remember_exports, {
20720
- handler: () => handler30
21365
+ handler: () => handler32
20721
21366
  });
20722
- import chalk46 from "chalk";
20723
- async function handler30(args, ctx) {
21367
+ import chalk48 from "chalk";
21368
+ async function handler32(args, ctx) {
20724
21369
  let text = args.join(" ").trim();
20725
21370
  if (!text) {
20726
21371
  console.log();
20727
- console.log(" " + chalk46.dim("Teach me something durable about the business."));
20728
- console.log(" " + chalk46.dim("Example: ") + paint("accent", "/remember we only sell to FinServ above 500 employees"));
20729
- console.log(" " + chalk46.dim("Prefix with ") + paint("accent", "decision:") + chalk46.dim(" or ") + paint("accent", "preference:") + chalk46.dim(" to tag it."));
21372
+ console.log(" " + chalk48.dim("Teach me something durable about the business."));
21373
+ console.log(" " + chalk48.dim("Example: ") + paint("accent", "/remember we only sell to FinServ above 500 employees"));
21374
+ console.log(" " + chalk48.dim("Prefix with ") + paint("accent", "decision:") + chalk48.dim(" or ") + paint("accent", "preference:") + chalk48.dim(" to tag it."));
20730
21375
  console.log();
20731
21376
  return;
20732
21377
  }
@@ -20738,8 +21383,8 @@ async function handler30(args, ctx) {
20738
21383
  }
20739
21384
  const fact = addFact({ text, kind, source: "user", session_id: ctx.sessionId });
20740
21385
  console.log();
20741
- console.log(" " + paint("accent", "Noted.") + " " + chalk46.dim(`I'll carry this into future analyses${kind !== "fact" ? ` (${kind})` : ""}.`));
20742
- console.log(" " + chalk46.dim("\u2022 " + fact.text));
21386
+ console.log(" " + paint("accent", "Noted.") + " " + chalk48.dim(`I'll carry this into future analyses${kind !== "fact" ? ` (${kind})` : ""}.`));
21387
+ console.log(" " + chalk48.dim("\u2022 " + fact.text));
20743
21388
  console.log();
20744
21389
  return "Saved to memory";
20745
21390
  }
@@ -20754,16 +21399,16 @@ var init_remember = __esm({
20754
21399
  // src/commands/recall.ts
20755
21400
  var recall_exports = {};
20756
21401
  __export(recall_exports, {
20757
- handler: () => handler31
21402
+ handler: () => handler33
20758
21403
  });
20759
- import chalk47 from "chalk";
20760
- async function handler31(args, _ctx) {
21404
+ import chalk49 from "chalk";
21405
+ async function handler33(args, _ctx) {
20761
21406
  const query = args.join(" ").trim();
20762
21407
  if (query) {
20763
21408
  const block = await buildMemoryBlock(query, { maxFacts: 6, maxLedger: 5, maxStrategies: 3, maxWins: 3, maxKnowledge: 3 });
20764
21409
  console.log();
20765
21410
  if (!block) {
20766
- console.log(" " + chalk47.dim(`Nothing in memory about "${query}" yet.`));
21411
+ console.log(" " + chalk49.dim(`Nothing in memory about "${query}" yet.`));
20767
21412
  console.log();
20768
21413
  return;
20769
21414
  }
@@ -20777,22 +21422,22 @@ async function handler31(args, _ctx) {
20777
21422
  const ledger = listLedger().slice(-8).reverse();
20778
21423
  console.log();
20779
21424
  if (facts.length === 0 && ledger.length === 0) {
20780
- console.log(" " + chalk47.dim("Memory is empty. Teach me with ") + paint("accent", "/remember <fact>") + chalk47.dim("."));
21425
+ console.log(" " + chalk49.dim("Memory is empty. Teach me with ") + paint("accent", "/remember <fact>") + chalk49.dim("."));
20781
21426
  console.log();
20782
21427
  return;
20783
21428
  }
20784
21429
  if (facts.length > 0) {
20785
21430
  console.log(" " + paint("accent", "What I know about your business"));
20786
21431
  for (const f of facts) {
20787
- const tag = f.kind !== "fact" ? chalk47.dim(` (${f.kind})`) : "";
20788
- console.log(" " + chalk47.dim("\u2022 ") + f.text + tag);
21432
+ const tag = f.kind !== "fact" ? chalk49.dim(` (${f.kind})`) : "";
21433
+ console.log(" " + chalk49.dim("\u2022 ") + f.text + tag);
20789
21434
  }
20790
21435
  console.log();
20791
21436
  }
20792
21437
  if (ledger.length > 0) {
20793
21438
  console.log(" " + paint("accent", "Analyses I've already run"));
20794
21439
  for (const l of ledger) {
20795
- console.log(" " + chalk47.dim("\u2022 ") + chalk47.dim(`${l.question} \u2192 ${l.summary}`));
21440
+ console.log(" " + chalk49.dim("\u2022 ") + chalk49.dim(`${l.question} \u2192 ${l.summary}`));
20796
21441
  }
20797
21442
  console.log();
20798
21443
  }
@@ -20856,29 +21501,29 @@ var init_feedback2 = __esm({
20856
21501
  // src/commands/rate.ts
20857
21502
  var rate_exports = {};
20858
21503
  __export(rate_exports, {
20859
- handler: () => handler32
21504
+ handler: () => handler34
20860
21505
  });
20861
- import chalk48 from "chalk";
20862
- async function handler32(args, ctx) {
21506
+ import chalk50 from "chalk";
21507
+ async function handler34(args, ctx) {
20863
21508
  const verdict = (args[0] ?? "").toLowerCase();
20864
21509
  const note = args.slice(1).join(" ").trim();
20865
21510
  if (!verdict || !POSITIVE.has(verdict) && !NEGATIVE.has(verdict)) {
20866
21511
  console.log();
20867
- console.log(" " + chalk48.dim("Tell me how the last answer landed so I improve."));
20868
- console.log(" " + paint("accent", "/rate good") + chalk48.dim(" or ") + paint("accent", "/rate bad <what was off>"));
21512
+ console.log(" " + chalk50.dim("Tell me how the last answer landed so I improve."));
21513
+ console.log(" " + paint("accent", "/rate good") + chalk50.dim(" or ") + paint("accent", "/rate bad <what was off>"));
20869
21514
  console.log();
20870
21515
  return;
20871
21516
  }
20872
21517
  if (!ctx.lastExchange) {
20873
21518
  console.log();
20874
- console.log(" " + chalk48.dim("Nothing to rate yet \u2014 ask a question first, then rate the answer."));
21519
+ console.log(" " + chalk50.dim("Nothing to rate yet \u2014 ask a question first, then rate the answer."));
20875
21520
  console.log();
20876
21521
  return;
20877
21522
  }
20878
21523
  const rating = POSITIVE.has(verdict) ? "positive" : "negative";
20879
21524
  if (rating === "negative" && !note) {
20880
21525
  console.log();
20881
- console.log(" " + chalk48.yellow("Add a quick note so I know what to fix:"));
21526
+ console.log(" " + chalk50.yellow("Add a quick note so I know what to fix:"));
20882
21527
  console.log(" " + paint("accent", "/rate bad you ignored the enterprise segment"));
20883
21528
  console.log();
20884
21529
  return;
@@ -20892,9 +21537,9 @@ async function handler32(args, ctx) {
20892
21537
  });
20893
21538
  console.log();
20894
21539
  if (rating === "positive") {
20895
- console.log(" " + paint("accent", "Noted \u2014 glad that helped.") + " " + chalk48.dim("I'll keep that approach for similar questions."));
21540
+ console.log(" " + paint("accent", "Noted \u2014 glad that helped.") + " " + chalk50.dim("I'll keep that approach for similar questions."));
20896
21541
  } else {
20897
- console.log(" " + paint("accent", "Got it \u2014 thank you.") + " " + chalk48.dim("I'll adjust and won't repeat that."));
21542
+ console.log(" " + paint("accent", "Got it \u2014 thank you.") + " " + chalk50.dim("I'll adjust and won't repeat that."));
20898
21543
  }
20899
21544
  console.log();
20900
21545
  return rating === "positive" ? "Feedback: helpful" : "Feedback: needs adjustment";
@@ -20913,18 +21558,18 @@ var init_rate = __esm({
20913
21558
  // src/commands/knowledge.ts
20914
21559
  var knowledge_exports = {};
20915
21560
  __export(knowledge_exports, {
20916
- handler: () => handler33
21561
+ handler: () => handler35
20917
21562
  });
20918
- import chalk49 from "chalk";
21563
+ import chalk51 from "chalk";
20919
21564
  import ora14 from "ora";
20920
- async function handler33(args, ctx) {
21565
+ async function handler35(args, ctx) {
20921
21566
  const sub = (args[0] ?? "list").toLowerCase();
20922
21567
  if (sub === "add") {
20923
21568
  const path = args.slice(1).join(" ").trim();
20924
21569
  if (!path) {
20925
21570
  console.log();
20926
- console.log(" " + chalk49.red("knowledge add requires a file path."));
20927
- console.log(" " + chalk49.dim("Example: ") + paint("accent", "/knowledge add ~/Downloads/plg-benchmarks-2026.pdf"));
21571
+ console.log(" " + chalk51.red("knowledge add requires a file path."));
21572
+ console.log(" " + chalk51.dim("Example: ") + paint("accent", "/knowledge add ~/Downloads/plg-benchmarks-2026.pdf"));
20928
21573
  console.log();
20929
21574
  return;
20930
21575
  }
@@ -20933,12 +21578,12 @@ async function handler33(args, ctx) {
20933
21578
  const result = await addKnowledgeFile(path);
20934
21579
  spin?.succeed(`Indexed "${result.title}"`);
20935
21580
  console.log();
20936
- console.log(" " + chalk49.dim(`${result.chunks} passage${result.chunks === 1 ? "" : "s"} indexed and available to the analyst.`));
21581
+ console.log(" " + chalk51.dim(`${result.chunks} passage${result.chunks === 1 ? "" : "s"} indexed and available to the analyst.`));
20937
21582
  console.log();
20938
21583
  return `Indexed ${result.chunks} passages`;
20939
21584
  } catch (err) {
20940
21585
  spin?.fail("Knowledge ingest failed");
20941
- console.error(" " + chalk49.red(String(err.message ?? err)));
21586
+ console.error(" " + chalk51.red(String(err.message ?? err)));
20942
21587
  console.log();
20943
21588
  return;
20944
21589
  }
@@ -20948,26 +21593,26 @@ async function handler33(args, ctx) {
20948
21593
  const staged = listKnowledgeDirFiles(getKnowledgeDir());
20949
21594
  console.log();
20950
21595
  if (docs.length === 0) {
20951
- console.log(" " + chalk49.dim("No knowledge indexed yet."));
21596
+ console.log(" " + chalk51.dim("No knowledge indexed yet."));
20952
21597
  } else {
20953
21598
  console.log(" " + paint("accent", "Indexed Knowledge"));
20954
21599
  for (const d of docs) {
20955
21600
  console.log(
20956
- " " + chalk49.dim("\u2022 ") + chalk49.bold(d.title) + chalk49.dim(` (${d.chunks} passage${d.chunks === 1 ? "" : "s"}${d.source_path ? `, ${d.source_path.split("/").pop()}` : ""})`)
21601
+ " " + chalk51.dim("\u2022 ") + chalk51.bold(d.title) + chalk51.dim(` (${d.chunks} passage${d.chunks === 1 ? "" : "s"}${d.source_path ? `, ${d.source_path.split("/").pop()}` : ""})`)
20957
21602
  );
20958
21603
  }
20959
21604
  }
20960
21605
  if (staged.length > 0) {
20961
21606
  console.log();
20962
- console.log(" " + chalk49.dim("Staged in ~/.ntrp/knowledge (run ") + paint("accent", "/knowledge add <file>") + chalk49.dim(" to index):"));
20963
- for (const f of staged) console.log(" " + chalk49.dim(" - " + f));
21607
+ console.log(" " + chalk51.dim("Staged in ~/.ntrp/knowledge (run ") + paint("accent", "/knowledge add <file>") + chalk51.dim(" to index):"));
21608
+ for (const f of staged) console.log(" " + chalk51.dim(" - " + f));
20964
21609
  }
20965
21610
  console.log();
20966
21611
  return `${docs.length} doc${docs.length === 1 ? "" : "s"} indexed`;
20967
21612
  }
20968
21613
  console.log();
20969
- console.log(" " + chalk49.red(`Unknown knowledge subcommand: ${sub}`));
20970
- console.log(" " + chalk49.dim("Use ") + paint("accent", "/knowledge add <file>") + chalk49.dim(" or ") + paint("accent", "/knowledge list") + chalk49.dim("."));
21614
+ console.log(" " + chalk51.red(`Unknown knowledge subcommand: ${sub}`));
21615
+ console.log(" " + chalk51.dim("Use ") + paint("accent", "/knowledge add <file>") + chalk51.dim(" or ") + paint("accent", "/knowledge list") + chalk51.dim("."));
20971
21616
  console.log();
20972
21617
  return;
20973
21618
  }
@@ -20983,10 +21628,10 @@ var init_knowledge2 = __esm({
20983
21628
  // src/commands/sessions.ts
20984
21629
  var sessions_exports = {};
20985
21630
  __export(sessions_exports, {
20986
- handler: () => handler34
21631
+ handler: () => handler36
20987
21632
  });
20988
- import chalk50 from "chalk";
20989
- async function handler34(args, _ctx) {
21633
+ import chalk52 from "chalk";
21634
+ async function handler36(args, _ctx) {
20990
21635
  const sub = args[0] ?? "list";
20991
21636
  if (sub === "list" || !args[0]) {
20992
21637
  return showList();
@@ -20995,8 +21640,8 @@ async function handler34(args, _ctx) {
20995
21640
  const idArg = args[1];
20996
21641
  if (!idArg) {
20997
21642
  console.log();
20998
- console.log(" " + chalk50.red("Usage: /sessions show <id>"));
20999
- console.log(" " + chalk50.dim("Use a full session ID or 4-char suffix."));
21643
+ console.log(" " + chalk52.red("Usage: /sessions show <id>"));
21644
+ console.log(" " + chalk52.dim("Use a full session ID or 4-char suffix."));
21000
21645
  console.log();
21001
21646
  return;
21002
21647
  }
@@ -21008,24 +21653,24 @@ function showList() {
21008
21653
  const sessions = listSessions({ limit: 10 });
21009
21654
  if (sessions.length === 0) {
21010
21655
  console.log();
21011
- console.log(" " + chalk50.dim("No sessions yet. Ask a question to start your first session."));
21656
+ console.log(" " + chalk52.dim("No sessions yet. Ask a question to start your first session."));
21012
21657
  console.log();
21013
21658
  return;
21014
21659
  }
21015
21660
  console.log();
21016
21661
  console.log(" " + paint("accent", bold("Session History")));
21017
- console.log(" " + chalk50.dim("\u2500".repeat(58)));
21662
+ console.log(" " + chalk52.dim("\u2500".repeat(58)));
21018
21663
  for (const s of sessions) {
21019
21664
  const date = s.created_at?.slice(0, 10) ?? s.id.slice(0, 10);
21020
21665
  const shortId = s.id.slice(-4);
21021
21666
  const nameTag = s.name ? paint("accent", `[${s.name}]`) + " " : "";
21022
- const summary = s.summary ?? chalk50.dim("(no summary)");
21023
- const exch = chalk50.dim(`${s.exchange_count} exch.`);
21024
- console.log(` ${chalk50.dim(date)} ${shortId} ${nameTag}${padRight(summary, 36)} ${exch}`);
21667
+ const summary = s.summary ?? chalk52.dim("(no summary)");
21668
+ const exch = chalk52.dim(`${s.exchange_count} exch.`);
21669
+ console.log(` ${chalk52.dim(date)} ${shortId} ${nameTag}${padRight(summary, 36)} ${exch}`);
21025
21670
  }
21026
- console.log(" " + chalk50.dim("\u2500".repeat(58)));
21671
+ console.log(" " + chalk52.dim("\u2500".repeat(58)));
21027
21672
  console.log(
21028
- " " + chalk50.dim(`${sessions.length} session${sessions.length === 1 ? "" : "s"} \xB7 `) + paint("accent", "/sessions show <id>") + chalk50.dim(" to review \xB7 ") + paint("accent", "/resume") + chalk50.dim(" to continue")
21673
+ " " + chalk52.dim(`${sessions.length} session${sessions.length === 1 ? "" : "s"} \xB7 `) + paint("accent", "/sessions show <id>") + chalk52.dim(" to review \xB7 ") + paint("accent", "/resume") + chalk52.dim(" to continue")
21029
21674
  );
21030
21675
  console.log();
21031
21676
  return `${sessions.length} session${sessions.length === 1 ? "" : "s"} listed`;
@@ -21038,18 +21683,18 @@ function showSession(idArg) {
21038
21683
  }
21039
21684
  if (matches.length === 0) {
21040
21685
  console.log();
21041
- console.log(" " + chalk50.red(`No session found matching "${idArg}".`));
21042
- console.log(" " + chalk50.dim("Use /sessions to see available session IDs."));
21686
+ console.log(" " + chalk52.red(`No session found matching "${idArg}".`));
21687
+ console.log(" " + chalk52.dim("Use /sessions to see available session IDs."));
21043
21688
  console.log();
21044
21689
  return;
21045
21690
  }
21046
21691
  if (matches.length > 1) {
21047
21692
  console.log();
21048
- console.log(" " + chalk50.red(`Ambiguous ID "${idArg}" matches ${matches.length} sessions:`));
21693
+ console.log(" " + chalk52.red(`Ambiguous ID "${idArg}" matches ${matches.length} sessions:`));
21049
21694
  for (const m of matches) {
21050
- console.log(" " + chalk50.dim(` ${m.id}`));
21695
+ console.log(" " + chalk52.dim(` ${m.id}`));
21051
21696
  }
21052
- console.log(" " + chalk50.dim("Use a longer ID to disambiguate."));
21697
+ console.log(" " + chalk52.dim("Use a longer ID to disambiguate."));
21053
21698
  console.log();
21054
21699
  return;
21055
21700
  }
@@ -21057,18 +21702,18 @@ function showSession(idArg) {
21057
21702
  const session = loadSessionFile(entry.id);
21058
21703
  if (!session) {
21059
21704
  console.log();
21060
- console.log(" " + chalk50.red(`Could not read session file for ${entry.id}.`));
21705
+ console.log(" " + chalk52.red(`Could not read session file for ${entry.id}.`));
21061
21706
  console.log();
21062
21707
  return;
21063
21708
  }
21064
21709
  const shortId = session.id.slice(-4);
21065
21710
  const dateStr = session.created_at?.slice(0, 10) ?? session.id.slice(0, 10);
21066
21711
  console.log();
21067
- console.log(" " + paint("accent", bold(`Session ${session.id}`)) + chalk50.dim(` \xB7 ${dateStr}`));
21712
+ console.log(" " + paint("accent", bold(`Session ${session.id}`)) + chalk52.dim(` \xB7 ${dateStr}`));
21068
21713
  if (session.summary) {
21069
- console.log(" " + chalk50.dim("Summary: ") + session.summary);
21714
+ console.log(" " + chalk52.dim("Summary: ") + session.summary);
21070
21715
  }
21071
- console.log(" " + chalk50.dim("\u2500".repeat(40)));
21716
+ console.log(" " + chalk52.dim("\u2500".repeat(40)));
21072
21717
  let exchangeNum = 0;
21073
21718
  for (let i = 0; i < session.messages.length; i++) {
21074
21719
  const msg = session.messages[i];
@@ -21076,14 +21721,14 @@ function showSession(idArg) {
21076
21721
  if (msg.role === "user") {
21077
21722
  exchangeNum++;
21078
21723
  console.log();
21079
- console.log(" " + chalk50.dim(`[${exchangeNum}]`) + " " + chalk50.bold("USER") + chalk50.dim(` (${time})`));
21724
+ console.log(" " + chalk52.dim(`[${exchangeNum}]`) + " " + chalk52.bold("USER") + chalk52.dim(` (${time})`));
21080
21725
  console.log(" " + msg.content);
21081
21726
  } else {
21082
21727
  console.log();
21083
- console.log(" " + chalk50.bold("AGENT") + chalk50.dim(` (${time})`));
21728
+ console.log(" " + chalk52.bold("AGENT") + chalk52.dim(` (${time})`));
21084
21729
  if (msg.content.length > 200) {
21085
21730
  console.log(" " + msg.content.slice(0, 200) + "\u2026");
21086
- console.log(" " + chalk50.dim(`(truncated \u2014 ${msg.content.length.toLocaleString()} chars)`));
21731
+ console.log(" " + chalk52.dim(`(truncated \u2014 ${msg.content.length.toLocaleString()} chars)`));
21087
21732
  } else {
21088
21733
  console.log(" " + msg.content);
21089
21734
  }
@@ -21105,22 +21750,22 @@ var init_sessions = __esm({
21105
21750
  // src/commands/resume.ts
21106
21751
  var resume_exports = {};
21107
21752
  __export(resume_exports, {
21108
- handler: () => handler35
21753
+ handler: () => handler37
21109
21754
  });
21110
- import chalk51 from "chalk";
21111
- async function handler35(args, ctx) {
21755
+ import chalk53 from "chalk";
21756
+ async function handler37(args, ctx) {
21112
21757
  if (ctx.resumedFromId && !args[0]) {
21113
21758
  console.log();
21114
- console.log(" " + chalk51.yellow("Already resumed session ") + paint("accent", ctx.resumedFromId.slice(-4)));
21115
- console.log(" " + chalk51.dim("Context: " + (ctx.resumedSessionSummary ?? "(no summary)")));
21116
- console.log(" " + chalk51.dim("Use ") + paint("accent", "/resume <id>") + chalk51.dim(" to resume a specific session."));
21759
+ console.log(" " + chalk53.yellow("Already resumed session ") + paint("accent", ctx.resumedFromId.slice(-4)));
21760
+ console.log(" " + chalk53.dim("Context: " + (ctx.resumedSessionSummary ?? "(no summary)")));
21761
+ console.log(" " + chalk53.dim("Use ") + paint("accent", "/resume <id>") + chalk53.dim(" to resume a specific session."));
21117
21762
  console.log();
21118
21763
  return;
21119
21764
  }
21120
21765
  const all2 = listSessions().filter((s) => s.exchange_count > 0 && s.id !== ctx.sessionId);
21121
21766
  if (all2.length === 0) {
21122
21767
  console.log();
21123
- console.log(" " + chalk51.dim("No prior sessions with NL exchanges to resume."));
21768
+ console.log(" " + chalk53.dim("No prior sessions with NL exchanges to resume."));
21124
21769
  console.log();
21125
21770
  return;
21126
21771
  }
@@ -21133,15 +21778,15 @@ async function handler35(args, ctx) {
21133
21778
  }
21134
21779
  if (matches.length === 0) {
21135
21780
  console.log();
21136
- console.log(" " + chalk51.red(`No session found matching "${idArg}".`));
21137
- console.log(" " + chalk51.dim("Use /sessions to see available IDs."));
21781
+ console.log(" " + chalk53.red(`No session found matching "${idArg}".`));
21782
+ console.log(" " + chalk53.dim("Use /sessions to see available IDs."));
21138
21783
  console.log();
21139
21784
  return;
21140
21785
  }
21141
21786
  if (matches.length > 1) {
21142
21787
  console.log();
21143
- console.log(" " + chalk51.red(`Ambiguous ID "${idArg}" \u2014 matches ${matches.length} sessions.`));
21144
- console.log(" " + chalk51.dim("Use a longer ID to disambiguate."));
21788
+ console.log(" " + chalk53.red(`Ambiguous ID "${idArg}" \u2014 matches ${matches.length} sessions.`));
21789
+ console.log(" " + chalk53.dim("Use a longer ID to disambiguate."));
21145
21790
  console.log();
21146
21791
  return;
21147
21792
  }
@@ -21152,7 +21797,7 @@ async function handler35(args, ctx) {
21152
21797
  const session = loadSessionFile(targetId);
21153
21798
  if (!session) {
21154
21799
  console.log();
21155
- console.log(" " + chalk51.red(`Could not read session file for ${targetId}.`));
21800
+ console.log(" " + chalk53.red(`Could not read session file for ${targetId}.`));
21156
21801
  console.log();
21157
21802
  return;
21158
21803
  }
@@ -21173,7 +21818,7 @@ async function handler35(args, ctx) {
21173
21818
  const shortId = targetId.slice(-4);
21174
21819
  console.log();
21175
21820
  console.log(" " + paint("accent", `Resumed session ${shortId}`));
21176
- console.log(" " + chalk51.dim("Context: ") + summary);
21821
+ console.log(" " + chalk53.dim("Context: ") + summary);
21177
21822
  console.log();
21178
21823
  return `Resumed ${shortId}`;
21179
21824
  }
@@ -21188,16 +21833,16 @@ var init_resume = __esm({
21188
21833
  // src/commands/name.ts
21189
21834
  var name_exports = {};
21190
21835
  __export(name_exports, {
21191
- handler: () => handler36
21836
+ handler: () => handler38
21192
21837
  });
21193
- import chalk52 from "chalk";
21194
- async function handler36(args, ctx) {
21838
+ import chalk54 from "chalk";
21839
+ async function handler38(args, ctx) {
21195
21840
  if (args.length === 0) {
21196
21841
  console.log();
21197
21842
  if (ctx.sessionName) {
21198
- console.log(" " + chalk52.dim("Session name: ") + paint("accent", ctx.sessionName));
21843
+ console.log(" " + chalk54.dim("Session name: ") + paint("accent", ctx.sessionName));
21199
21844
  } else {
21200
- console.log(" " + chalk52.dim("No name set. Usage: ") + paint("accent", "/name <label>"));
21845
+ console.log(" " + chalk54.dim("No name set. Usage: ") + paint("accent", "/name <label>"));
21201
21846
  }
21202
21847
  console.log();
21203
21848
  return;
@@ -21205,15 +21850,15 @@ async function handler36(args, ctx) {
21205
21850
  const label = args.join(" ").trim();
21206
21851
  if (label.length > MAX_NAME_LENGTH) {
21207
21852
  console.log();
21208
- console.log(" " + chalk52.red(`Name too long (${label.length} chars). Max is ${MAX_NAME_LENGTH}.`));
21853
+ console.log(" " + chalk54.red(`Name too long (${label.length} chars). Max is ${MAX_NAME_LENGTH}.`));
21209
21854
  console.log();
21210
21855
  return `Too long (max ${MAX_NAME_LENGTH})`;
21211
21856
  }
21212
21857
  const existing = findSessionByName(label);
21213
21858
  if (existing && existing.id !== ctx.sessionId) {
21214
21859
  console.log();
21215
- console.log(" " + chalk52.yellow(`"${label}" is already used by session ${existing.id.slice(-4)}.`));
21216
- console.log(" " + chalk52.dim("Use ") + paint("accent", `/switch ${label}`) + chalk52.dim(" to jump to it instead."));
21860
+ console.log(" " + chalk54.yellow(`"${label}" is already used by session ${existing.id.slice(-4)}.`));
21861
+ console.log(" " + chalk54.dim("Use ") + paint("accent", `/switch ${label}`) + chalk54.dim(" to jump to it instead."));
21217
21862
  console.log();
21218
21863
  return `"${label}" taken \u2014 use /switch`;
21219
21864
  }
@@ -21236,19 +21881,19 @@ var init_name = __esm({
21236
21881
  // src/commands/switch.ts
21237
21882
  var switch_exports = {};
21238
21883
  __export(switch_exports, {
21239
- handler: () => handler37
21884
+ handler: () => handler39
21240
21885
  });
21241
21886
  import { join as join22 } from "path";
21242
21887
  import ora15 from "ora";
21243
- import chalk53 from "chalk";
21244
- async function handler37(args, ctx) {
21888
+ import chalk55 from "chalk";
21889
+ async function handler39(args, ctx) {
21245
21890
  if (args.length === 0) {
21246
21891
  return listNamedSessions(ctx);
21247
21892
  }
21248
21893
  const targetName = args.join(" ").trim();
21249
21894
  if (ctx.sessionName && ctx.sessionName.toLowerCase() === targetName.toLowerCase()) {
21250
21895
  console.log();
21251
- console.log(" " + chalk53.dim("Already in session ") + paint("accent", ctx.sessionName));
21896
+ console.log(" " + chalk55.dim("Already in session ") + paint("accent", ctx.sessionName));
21252
21897
  console.log();
21253
21898
  return;
21254
21899
  }
@@ -21263,7 +21908,7 @@ async function handler37(args, ctx) {
21263
21908
  if (existing) {
21264
21909
  const session = loadSessionFile(existing.id);
21265
21910
  if (!session) {
21266
- console.log(" " + chalk53.red(`Could not read session file for ${existing.id}.`));
21911
+ console.log(" " + chalk55.red(`Could not read session file for ${existing.id}.`));
21267
21912
  console.log();
21268
21913
  return;
21269
21914
  }
@@ -21287,10 +21932,10 @@ async function handler37(args, ctx) {
21287
21932
  console.log();
21288
21933
  console.log(" " + paint("accent", `Switched to "${targetName}"`));
21289
21934
  if (session.summary) {
21290
- console.log(" " + chalk53.dim("Context: ") + session.summary);
21935
+ console.log(" " + chalk55.dim("Context: ") + session.summary);
21291
21936
  }
21292
21937
  const exch = session.exchange_count ?? Math.floor(session.messages.length / 2);
21293
- console.log(" " + chalk53.dim(`${exch} prior exchange${exch === 1 ? "" : "s"} loaded`));
21938
+ console.log(" " + chalk55.dim(`${exch} prior exchange${exch === 1 ? "" : "s"} loaded`));
21294
21939
  console.log();
21295
21940
  return `Switched to "${targetName}"`;
21296
21941
  } else {
@@ -21313,13 +21958,13 @@ function listNamedSessions(ctx) {
21313
21958
  const named = all2.filter((s) => s.name);
21314
21959
  if (named.length === 0) {
21315
21960
  console.log();
21316
- console.log(" " + chalk53.dim("No named sessions. Use ") + paint("accent", "/name <label>") + chalk53.dim(" to name one."));
21961
+ console.log(" " + chalk55.dim("No named sessions. Use ") + paint("accent", "/name <label>") + chalk55.dim(" to name one."));
21317
21962
  console.log();
21318
21963
  return;
21319
21964
  }
21320
21965
  console.log();
21321
21966
  console.log(" " + paint("accent", bold("Named Sessions")));
21322
- console.log(" " + chalk53.dim("\u2500".repeat(50)));
21967
+ console.log(" " + chalk55.dim("\u2500".repeat(50)));
21323
21968
  const byName = /* @__PURE__ */ new Map();
21324
21969
  for (const s of named) {
21325
21970
  const key = s.name.toLowerCase();
@@ -21328,12 +21973,12 @@ function listNamedSessions(ctx) {
21328
21973
  for (const [, s] of byName) {
21329
21974
  const isActive = ctx.sessionName?.toLowerCase() === s.name.toLowerCase();
21330
21975
  const marker2 = isActive ? paint("accent", " \u25C0") : "";
21331
- const summary = s.summary ?? chalk53.dim("(no summary)");
21332
- const exch = chalk53.dim(`${s.exchange_count} exch.`);
21976
+ const summary = s.summary ?? chalk55.dim("(no summary)");
21977
+ const exch = chalk55.dim(`${s.exchange_count} exch.`);
21333
21978
  console.log(` ${paint("accent", s.name)} ${summary} ${exch}${marker2}`);
21334
21979
  }
21335
- console.log(" " + chalk53.dim("\u2500".repeat(50)));
21336
- console.log(" " + paint("accent", "/switch <name>") + chalk53.dim(" to jump to a session"));
21980
+ console.log(" " + chalk55.dim("\u2500".repeat(50)));
21981
+ console.log(" " + paint("accent", "/switch <name>") + chalk55.dim(" to jump to a session"));
21337
21982
  console.log();
21338
21983
  return `${byName.size} named session${byName.size === 1 ? "" : "s"}`;
21339
21984
  }
@@ -21348,10 +21993,10 @@ var init_switch = __esm({
21348
21993
  // src/commands/provider.ts
21349
21994
  var provider_exports = {};
21350
21995
  __export(provider_exports, {
21351
- handler: () => handler38
21996
+ handler: () => handler40
21352
21997
  });
21353
- import chalk54 from "chalk";
21354
- async function handler38(args, ctx) {
21998
+ import chalk56 from "chalk";
21999
+ async function handler40(args, ctx) {
21355
22000
  const { positional, flags } = parseArgs2(args, ["default"]);
21356
22001
  const sub = positional[0]?.toLowerCase();
21357
22002
  if (!sub || sub === "list") {
@@ -21363,7 +22008,7 @@ async function handler38(args, ctx) {
21363
22008
  if (!ctx.oneShot) saveSessionState(ctx);
21364
22009
  console.log();
21365
22010
  console.log(" " + paint("success", "\u2713") + " Session engine reset \u2014 using config defaults.");
21366
- console.log(" " + chalk54.dim(`Default: ${loadLlmConfig().primary}`));
22011
+ console.log(" " + chalk56.dim(`Default: ${loadLlmConfig().primary}`));
21367
22012
  console.log();
21368
22013
  return;
21369
22014
  }
@@ -21376,7 +22021,7 @@ async function handler38(args, ctx) {
21376
22021
  setConfigValue("llm-auto-failover", session.autoFailover ? "on" : "off");
21377
22022
  }
21378
22023
  console.log();
21379
- console.log(" " + paint("success", "\u2713") + ` Saved ${chalk54.bold(active)} as default engine.`);
22024
+ console.log(" " + paint("success", "\u2713") + ` Saved ${chalk56.bold(active)} as default engine.`);
21380
22025
  console.log();
21381
22026
  return;
21382
22027
  }
@@ -21395,16 +22040,16 @@ async function handler38(args, ctx) {
21395
22040
  }
21396
22041
  console.log();
21397
22042
  console.log(
21398
- " " + paint("success", "\u2713") + ` Auto-failover ${session.autoFailover ? chalk54.bold("on") : chalk54.bold("off")} for this session.`
22043
+ " " + paint("success", "\u2713") + ` Auto-failover ${session.autoFailover ? chalk56.bold("on") : chalk56.bold("off")} for this session.`
21399
22044
  );
21400
- if (persist) console.log(" " + chalk54.dim("Also saved as config default."));
22045
+ if (persist) console.log(" " + chalk56.dim("Also saved as config default."));
21401
22046
  console.log();
21402
22047
  return;
21403
22048
  }
21404
22049
  if (!PROVIDERS.includes(sub)) {
21405
22050
  console.log();
21406
- console.log(" " + chalk54.red(`Unknown engine: ${sub}`));
21407
- console.log(" " + chalk54.dim("Usage: /provider [anthropic|openai|list|reset|save|failover on|off]"));
22051
+ console.log(" " + chalk56.red(`Unknown engine: ${sub}`));
22052
+ console.log(" " + chalk56.dim("Usage: /provider [anthropic|openai|list|reset|save|failover on|off]"));
21408
22053
  console.log();
21409
22054
  return;
21410
22055
  }
@@ -21412,19 +22057,19 @@ async function handler38(args, ctx) {
21412
22057
  if (!hasProviderKey(provider)) {
21413
22058
  const keyHint = provider === "anthropic" ? "api-key" : "openai-api-key";
21414
22059
  console.log();
21415
- console.log(" " + chalk54.red(`No ${provider} key configured.`));
21416
- console.log(" " + chalk54.dim(`Run `) + paint("accent", `/config set ${keyHint}`) + chalk54.dim(" to add one."));
22060
+ console.log(" " + chalk56.red(`No ${provider} key configured.`));
22061
+ console.log(" " + chalk56.dim(`Run `) + paint("accent", `/config set ${keyHint}`) + chalk56.dim(" to add one."));
21417
22062
  console.log();
21418
22063
  return;
21419
22064
  }
21420
22065
  ensureLlmSession(ctx).provider = provider;
21421
22066
  if (!ctx.oneShot) saveSessionState(ctx);
21422
22067
  console.log();
21423
- console.log(" " + paint("success", "\u2713") + ` Active engine: ${chalk54.bold(provider)}`);
21424
- console.log(" " + chalk54.dim(`Stack: ${formatActiveStack(ctx)}`));
22068
+ console.log(" " + paint("success", "\u2713") + ` Active engine: ${chalk56.bold(provider)}`);
22069
+ console.log(" " + chalk56.dim(`Stack: ${formatActiveStack(ctx)}`));
21425
22070
  const others = availableEngineLabels().filter((p) => p !== provider);
21426
22071
  if (others.length > 0) {
21427
- console.log(" " + chalk54.dim(`Also available: ${others.join(", ")}`));
22072
+ console.log(" " + chalk56.dim(`Also available: ${others.join(", ")}`));
21428
22073
  }
21429
22074
  console.log();
21430
22075
  }
@@ -21435,26 +22080,26 @@ function printStatus(ctx) {
21435
22080
  const autoFailover = resolveAutoFailoverEnabled(ctx);
21436
22081
  const engines = countAvailableEngines();
21437
22082
  console.log();
21438
- console.log(chalk54.bold(" LLM engines"));
22083
+ console.log(chalk56.bold(" LLM engines"));
21439
22084
  console.log(` Available: ${engines} engine${engines === 1 ? "" : "s"}`);
21440
22085
  for (const p of PROVIDERS) {
21441
- const key = hasProviderKey(p) ? paint("success", "\u2713") : chalk54.dim("\xB7");
22086
+ const key = hasProviderKey(p) ? paint("success", "\u2713") : chalk56.dim("\xB7");
21442
22087
  const marker2 = p === active ? paint("accent", " \u25BA active") : "";
21443
22088
  console.log(` ${key} ${p}${marker2}`);
21444
22089
  }
21445
22090
  console.log();
21446
- console.log(chalk54.bold(" Active stack"));
22091
+ console.log(chalk56.bold(" Active stack"));
21447
22092
  console.log(` ${formatActiveStack(ctx)}`);
21448
22093
  if (sessionOverride) {
21449
- console.log(chalk54.dim(" (session override \u2014 /provider reset to use default)"));
22094
+ console.log(chalk56.dim(" (session override \u2014 /provider reset to use default)"));
21450
22095
  } else {
21451
- console.log(chalk54.dim(` (config default: ${cfg.primary})`));
22096
+ console.log(chalk56.dim(` (config default: ${cfg.primary})`));
21452
22097
  }
21453
22098
  console.log();
21454
- console.log(` Auto-failover: ${autoFailover ? paint("success", "on") : chalk54.dim("off")}`);
21455
- console.log(chalk54.dim(" /provider anthropic|openai \u2014 switch engine"));
21456
- console.log(chalk54.dim(" /provider failover on|off \u2014 rate-limit safety net"));
21457
- console.log(chalk54.dim(" /provider save \u2014 persist active engine to config"));
22099
+ console.log(` Auto-failover: ${autoFailover ? paint("success", "on") : chalk56.dim("off")}`);
22100
+ console.log(chalk56.dim(" /provider anthropic|openai \u2014 switch engine"));
22101
+ console.log(chalk56.dim(" /provider failover on|off \u2014 rate-limit safety net"));
22102
+ console.log(chalk56.dim(" /provider save \u2014 persist active engine to config"));
21458
22103
  console.log();
21459
22104
  }
21460
22105
  var PROVIDERS;
@@ -21474,10 +22119,10 @@ var init_provider = __esm({
21474
22119
  // src/commands/tier.ts
21475
22120
  var tier_exports = {};
21476
22121
  __export(tier_exports, {
21477
- handler: () => handler39
22122
+ handler: () => handler41
21478
22123
  });
21479
- import chalk55 from "chalk";
21480
- async function handler39(args, ctx) {
22124
+ import chalk57 from "chalk";
22125
+ async function handler41(args, ctx) {
21481
22126
  const { positional, flags } = parseArgs2(args, ["default"]);
21482
22127
  const sub = positional[0]?.toLowerCase();
21483
22128
  if (!sub || sub === "list") {
@@ -21486,8 +22131,8 @@ async function handler39(args, ctx) {
21486
22131
  }
21487
22132
  if (!TIERS.includes(sub)) {
21488
22133
  console.log();
21489
- console.log(" " + chalk55.red(`Unknown tier: ${sub}`));
21490
- console.log(" " + chalk55.dim("Usage: /tier [high|medium|low|list] [--default]"));
22134
+ console.log(" " + chalk57.red(`Unknown tier: ${sub}`));
22135
+ console.log(" " + chalk57.dim("Usage: /tier [high|medium|low|list] [--default]"));
21491
22136
  console.log();
21492
22137
  return;
21493
22138
  }
@@ -21501,9 +22146,9 @@ async function handler39(args, ctx) {
21501
22146
  }
21502
22147
  console.log();
21503
22148
  console.log(
21504
- " " + paint("success", "\u2713") + ` Inference tier set to ${chalk55.bold(tier.toUpperCase())}` + (persist ? chalk55.dim(" (saved as default)") : chalk55.dim(" (this session)"))
22149
+ " " + paint("success", "\u2713") + ` Inference tier set to ${chalk57.bold(tier.toUpperCase())}` + (persist ? chalk57.dim(" (saved as default)") : chalk57.dim(" (this session)"))
21505
22150
  );
21506
- console.log(" " + chalk55.dim(`Stack: ${formatActiveStack(ctx)}`));
22151
+ console.log(" " + chalk57.dim(`Stack: ${formatActiveStack(ctx)}`));
21507
22152
  console.log();
21508
22153
  }
21509
22154
  function printCatalog(ctx) {
@@ -21511,30 +22156,30 @@ function printCatalog(ctx) {
21511
22156
  const active = resolveModelForActive(ctx, "agentic_investigation");
21512
22157
  const sessionTier = ctx.llm?.tier;
21513
22158
  console.log();
21514
- console.log(chalk55.bold(" Inference settings"));
22159
+ console.log(chalk57.bold(" Inference settings"));
21515
22160
  console.log(` Active: ${paint("accent", formatActiveStack(ctx))}`);
21516
22161
  if (sessionTier) {
21517
- console.log(chalk55.dim(" (session tier override)"));
22162
+ console.log(chalk57.dim(" (session tier override)"));
21518
22163
  } else {
21519
- console.log(chalk55.dim(` Config default tier: ${cfg.tier.toUpperCase()}`));
22164
+ console.log(chalk57.dim(` Config default tier: ${cfg.tier.toUpperCase()}`));
21520
22165
  }
21521
22166
  console.log();
21522
22167
  for (const tier of TIERS) {
21523
- console.log(chalk55.bold(` ${tier.toUpperCase()}`));
22168
+ console.log(chalk57.bold(` ${tier.toUpperCase()}`));
21524
22169
  for (const provider of ["anthropic", "openai"]) {
21525
22170
  const models = listCatalogEntries(provider).filter((m) => m.tier === tier);
21526
22171
  for (const m of models) {
21527
22172
  const isActive = provider === active.provider && tier === active.tier && m.id === active.modelId;
21528
22173
  const marker2 = isActive ? paint("accent", "\u25BA ") : " ";
21529
- const status = m.status === "active" ? "" : chalk55.yellow(` [${m.status}]`);
22174
+ const status = m.status === "active" ? "" : chalk57.yellow(` [${m.status}]`);
21530
22175
  console.log(`${marker2}${provider}/${m.id}${status} \u2014 ${m.display_name}`);
21531
22176
  }
21532
22177
  }
21533
22178
  console.log();
21534
22179
  }
21535
- console.log(chalk55.dim(" /tier high|medium|low \u2014 set tier for this session"));
21536
- console.log(chalk55.dim(" /tier high --default \u2014 also save as config default"));
21537
- console.log(chalk55.dim(" /provider anthropic|openai \u2014 switch engine"));
22180
+ console.log(chalk57.dim(" /tier high|medium|low \u2014 set tier for this session"));
22181
+ console.log(chalk57.dim(" /tier high --default \u2014 also save as config default"));
22182
+ console.log(chalk57.dim(" /provider anthropic|openai \u2014 switch engine"));
21538
22183
  console.log();
21539
22184
  }
21540
22185
  var TIERS;
@@ -21555,10 +22200,10 @@ var init_tier = __esm({
21555
22200
  // src/commands/model.ts
21556
22201
  var model_exports = {};
21557
22202
  __export(model_exports, {
21558
- handler: () => handler40
22203
+ handler: () => handler42
21559
22204
  });
21560
- import chalk56 from "chalk";
21561
- async function handler40(args, ctx) {
22205
+ import chalk58 from "chalk";
22206
+ async function handler42(args, ctx) {
21562
22207
  const { positional, flags } = parseArgs2(args, ["default"]);
21563
22208
  const sub = positional[0]?.toLowerCase();
21564
22209
  if (sub === "clear") {
@@ -21568,7 +22213,7 @@ async function handler40(args, ctx) {
21568
22213
  if (!ctx.oneShot) saveSessionState(ctx);
21569
22214
  console.log();
21570
22215
  console.log(" " + paint("success", "\u2713") + " Model override cleared \u2014 using tier defaults.");
21571
- console.log(" " + chalk56.dim(`Stack: ${formatActiveStack(ctx)}`));
22216
+ console.log(" " + chalk58.dim(`Stack: ${formatActiveStack(ctx)}`));
21572
22217
  console.log();
21573
22218
  return;
21574
22219
  }
@@ -21576,7 +22221,7 @@ async function handler40(args, ctx) {
21576
22221
  const modelId = positional[1];
21577
22222
  if (!modelId) {
21578
22223
  console.log();
21579
- console.log(" " + chalk56.red("Usage: /model set <model-id> [--default]"));
22224
+ console.log(" " + chalk58.red("Usage: /model set <model-id> [--default]"));
21580
22225
  console.log();
21581
22226
  return;
21582
22227
  }
@@ -21585,13 +22230,13 @@ async function handler40(args, ctx) {
21585
22230
  const entry = getCatalogEntry(modelId);
21586
22231
  if (providerErr) {
21587
22232
  console.log();
21588
- console.log(" " + chalk56.red(providerErr));
22233
+ console.log(" " + chalk58.red(providerErr));
21589
22234
  console.log();
21590
22235
  return;
21591
22236
  }
21592
22237
  if (!entry) {
21593
22238
  console.log();
21594
- console.log(" " + chalk56.yellow("\u26A0") + ` Unknown model ${modelId} \u2014 saving for active engine anyway.`);
22239
+ console.log(" " + chalk58.yellow("\u26A0") + ` Unknown model ${modelId} \u2014 saving for active engine anyway.`);
21595
22240
  }
21596
22241
  const persist = getBool(flags, "default");
21597
22242
  if (persist) {
@@ -21602,25 +22247,25 @@ async function handler40(args, ctx) {
21602
22247
  }
21603
22248
  console.log();
21604
22249
  console.log(
21605
- " " + paint("success", "\u2713") + ` Model: ${chalk56.bold(modelId)}` + (persist ? chalk56.dim(" (saved as default)") : chalk56.dim(" (this session)"))
22250
+ " " + paint("success", "\u2713") + ` Model: ${chalk58.bold(modelId)}` + (persist ? chalk58.dim(" (saved as default)") : chalk58.dim(" (this session)"))
21606
22251
  );
21607
- console.log(" " + chalk56.dim(`Stack: ${formatActiveStack(ctx)}`));
22252
+ console.log(" " + chalk58.dim(`Stack: ${formatActiveStack(ctx)}`));
21608
22253
  console.log();
21609
22254
  return;
21610
22255
  }
21611
22256
  const sessionOverride = ctx.llm?.modelOverride;
21612
22257
  const globalOverride = getConfigValue("llm-model-override");
21613
22258
  console.log();
21614
- console.log(chalk56.bold(" Model"));
22259
+ console.log(chalk58.bold(" Model"));
21615
22260
  if (sessionOverride) {
21616
22261
  console.log(` Session override: ${paint("accent", sessionOverride)}`);
21617
22262
  } else if (globalOverride) {
21618
22263
  console.log(` Config default: ${paint("accent", globalOverride)}`);
21619
22264
  } else {
21620
- console.log(" " + chalk56.dim("No override \u2014 tier defaults apply."));
22265
+ console.log(" " + chalk58.dim("No override \u2014 tier defaults apply."));
21621
22266
  }
21622
22267
  console.log(` Active stack: ${formatActiveStack(ctx)}`);
21623
- console.log(chalk56.dim(" /model set <id> \xB7 /model clear \xB7 /tier list \xB7 /provider list"));
22268
+ console.log(chalk58.dim(" /model set <id> \xB7 /model clear \xB7 /tier list \xB7 /provider list"));
21624
22269
  console.log();
21625
22270
  }
21626
22271
  var init_model = __esm({
@@ -21795,10 +22440,10 @@ var init_registry = __esm({
21795
22440
  // src/commands/update.ts
21796
22441
  var update_exports = {};
21797
22442
  __export(update_exports, {
21798
- handler: () => handler41
22443
+ handler: () => handler43
21799
22444
  });
21800
22445
  import { spawnSync } from "child_process";
21801
- import chalk57 from "chalk";
22446
+ import chalk59 from "chalk";
21802
22447
  function tailLines(text, count = 5) {
21803
22448
  return text.split("\n").map((line) => line.trimEnd()).filter((line) => line.length > 0).slice(-count).join("\n");
21804
22449
  }
@@ -21814,19 +22459,19 @@ function runGlobalInstall() {
21814
22459
  const output = [result.stdout, result.stderr].filter(Boolean).join("\n");
21815
22460
  return { ok: result.status === 0, output };
21816
22461
  }
21817
- async function handler41(_args, _ctx) {
22462
+ async function handler43(_args, _ctx) {
21818
22463
  const current = getInstalledVersion();
21819
22464
  const latest = await fetchLatestVersion(1e4);
21820
22465
  if (!latest) {
21821
22466
  console.log();
21822
- console.log(chalk57.yellow(" Could not reach the npm registry."));
21823
- console.log(chalk57.dim(` Try manually: npm install -g ${NPM_PACKAGE}`));
22467
+ console.log(chalk59.yellow(" Could not reach the npm registry."));
22468
+ console.log(chalk59.dim(` Try manually: npm install -g ${NPM_PACKAGE}`));
21824
22469
  console.log();
21825
22470
  return;
21826
22471
  }
21827
22472
  if (!isNewerVersion(latest, current)) {
21828
22473
  console.log();
21829
- console.log(chalk57.green(` \u2713 You're on the latest version (v${current})`));
22474
+ console.log(chalk59.green(` \u2713 You're on the latest version (v${current})`));
21830
22475
  console.log();
21831
22476
  return;
21832
22477
  }
@@ -21835,24 +22480,24 @@ async function handler41(_args, _ctx) {
21835
22480
  const { ok, output } = runGlobalInstall();
21836
22481
  if (ok) {
21837
22482
  invalidateUpdateCheckCache();
21838
- console.log(chalk57.green(` \u2713 Updated! Restart NTRP to use v${latest}`));
22483
+ console.log(chalk59.green(` \u2713 Updated! Restart NTRP to use v${latest}`));
21839
22484
  console.log();
21840
22485
  return;
21841
22486
  }
21842
22487
  const lower = output.toLowerCase();
21843
22488
  if (lower.includes("eacces") || lower.includes("permission denied") || lower.includes("eperm")) {
21844
- console.log(chalk57.red(` Could not install ${NPM_PACKAGE} (permission denied).`));
21845
- console.log(chalk57.dim(` Try: sudo npm install -g ${NPM_PACKAGE}`));
21846
- console.log(chalk57.dim(` Or fix npm global permissions: ${PERMISSIONS_URL}`));
22489
+ console.log(chalk59.red(` Could not install ${NPM_PACKAGE} (permission denied).`));
22490
+ console.log(chalk59.dim(` Try: sudo npm install -g ${NPM_PACKAGE}`));
22491
+ console.log(chalk59.dim(` Or fix npm global permissions: ${PERMISSIONS_URL}`));
21847
22492
  console.log();
21848
22493
  return;
21849
22494
  }
21850
22495
  const detail = tailLines(output);
21851
- console.log(chalk57.red(` Could not install ${NPM_PACKAGE}.`));
22496
+ console.log(chalk59.red(` Could not install ${NPM_PACKAGE}.`));
21852
22497
  if (detail) {
21853
- console.log(chalk57.dim(` ${detail.split("\n").join("\n ")}`));
22498
+ console.log(chalk59.dim(` ${detail.split("\n").join("\n ")}`));
21854
22499
  }
21855
- console.log(chalk57.dim(` Try manually: npm install -g ${NPM_PACKAGE}`));
22500
+ console.log(chalk59.dim(` Try manually: npm install -g ${NPM_PACKAGE}`));
21856
22501
  console.log();
21857
22502
  }
21858
22503
  var PERMISSIONS_URL;
@@ -21955,10 +22600,10 @@ async function resolveHandler(name) {
21955
22600
  try {
21956
22601
  const mod = await importHandler(runtimePath);
21957
22602
  if (!mod) return null;
21958
- const handler42 = mod.handler;
21959
- if (typeof handler42 !== "function") return null;
21960
- entry.handler = handler42;
21961
- return handler42;
22603
+ const handler44 = mod.handler;
22604
+ if (typeof handler44 !== "function") return null;
22605
+ entry.handler = handler44;
22606
+ return handler44;
21962
22607
  } catch (err) {
21963
22608
  console.error(`Failed to load handler for /${name}:`, err);
21964
22609
  return null;
@@ -22010,6 +22655,10 @@ async function importHandler(runtimePath) {
22010
22655
  return Promise.resolve().then(() => (init_config(), config_exports));
22011
22656
  case "../commands/activate.js":
22012
22657
  return Promise.resolve().then(() => (init_activate(), activate_exports));
22658
+ case "../commands/upgrade.js":
22659
+ return Promise.resolve().then(() => (init_upgrade2(), upgrade_exports2));
22660
+ case "../commands/checkout.js":
22661
+ return Promise.resolve().then(() => (init_checkout(), checkout_exports));
22013
22662
  case "../commands/onboard.js":
22014
22663
  return Promise.resolve().then(() => (init_onboard(), onboard_exports));
22015
22664
  case "../commands/setup.js":
@@ -22655,6 +23304,30 @@ handler: ../commands/activate.ts
22655
23304
 
22656
23305
  Activate NTRP with your license key (format: NTRP-XXXX-XXXX-XXXX). Most
22657
23306
  commands require a valid license.`
23307
+ },
23308
+ {
23309
+ name: "upgrade",
23310
+ raw: `---
23311
+ name: upgrade
23312
+ description: Upgrade trial to Pro \u2014 checkout + paste key
23313
+ section: Settings
23314
+ handler: ../commands/upgrade.ts
23315
+ ---
23316
+
23317
+ Open the Pro checkout page and paste your new license key without leaving
23318
+ the REPL. Use during trial grace or after cutoff. Flags: --url (print checkout URL only).`
23319
+ },
23320
+ {
23321
+ name: "checkout",
23322
+ raw: `---
23323
+ name: checkout
23324
+ description: Open signup checkout in your browser
23325
+ section: Settings
23326
+ handler: ../commands/checkout.ts
23327
+ ---
23328
+
23329
+ Opens the Lemon Squeezy checkout page in your default browser. Use anytime
23330
+ you need a trial or Pro license key.`
22658
23331
  },
22659
23332
  {
22660
23333
  name: "feedback",
@@ -22676,7 +23349,7 @@ paragraph that flows into all AI surfaces.`
22676
23349
  });
22677
23350
 
22678
23351
  // src/license/activation.ts
22679
- import chalk58 from "chalk";
23352
+ import chalk60 from "chalk";
22680
23353
  function hasValidLicense() {
22681
23354
  return checkLicense().valid;
22682
23355
  }
@@ -22684,54 +23357,31 @@ async function ensureLicenseActivated(ctx) {
22684
23357
  if (hasValidLicense()) return false;
22685
23358
  if (!process.stdin.isTTY) {
22686
23359
  console.error();
22687
- console.error(chalk58.red(" A license key is required."));
22688
- console.error(chalk58.dim(` Purchase at ${PURCHASE_URL}`));
22689
- console.error(chalk58.dim(" Then run: ntrp activate <key>"));
22690
- console.error(chalk58.dim(" Or set NTRP_LICENSE_KEY for headless use."));
23360
+ console.error(chalk60.red(" A license key is required."));
23361
+ console.error(chalk60.dim(` Sign up: ${getUpgradeUrl()}`));
23362
+ console.error(chalk60.dim(" Then run: ntrp activate <key>"));
23363
+ console.error(chalk60.dim(" Or set NTRP_LICENSE_KEY for headless use."));
22691
23364
  console.error();
22692
23365
  process.exit(1);
22693
23366
  }
23367
+ const lic = checkLicense();
23368
+ if (hasStoredLicenseKey() && isTrialCutoff(lic)) {
23369
+ return runUpgradeFlow(ctx, "expired");
23370
+ }
22694
23371
  printCenteredLogo();
22695
23372
  console.log(" " + bold("Activate your license"));
22696
- console.log(
22697
- " " + chalk58.dim("Purchase at ") + paint("accent", PURCHASE_URL) + chalk58.dim(" \u2014 your key is delivered after checkout.")
22698
- );
23373
+ console.log(" " + chalk60.dim("Don't have a key yet? Sign up (free trial or Pro), then paste it below."));
22699
23374
  console.log();
22700
- const session = createPromptSession(ctx.rl, ctx);
22701
- try {
22702
- for (; ; ) {
22703
- const key = await session.askSecret("Paste your license key", { confirm: false });
22704
- if (!key.trim()) {
22705
- console.log(" " + chalk58.red("A license key is required to use NTRP."));
22706
- continue;
22707
- }
22708
- const result = validateLicenseKey(key.trim());
22709
- if (!result.valid) {
22710
- console.log(" " + chalk58.red(result.message));
22711
- console.log(" " + chalk58.dim(`Check the key from your purchase email or ${PURCHASE_URL}`));
22712
- console.log();
22713
- continue;
22714
- }
22715
- setConfigValue("license-key", key.trim());
22716
- console.log();
22717
- console.log(chalk58.green(` \u2713 License activated: ${result.message}`));
22718
- console.log();
22719
- return true;
22720
- }
22721
- } finally {
22722
- session.close();
22723
- }
23375
+ await promptOpenCheckout(ctx);
23376
+ return promptForLicenseKey(ctx);
22724
23377
  }
22725
- var PURCHASE_URL;
22726
23378
  var init_activation = __esm({
22727
23379
  "src/license/activation.ts"() {
22728
23380
  "use strict";
22729
- init_prompts();
22730
- init_store();
22731
23381
  init_banner();
22732
23382
  init_theme();
22733
23383
  init_verify();
22734
- PURCHASE_URL = "https://ntrp.sonnechasser.com";
23384
+ init_upgrade();
22735
23385
  }
22736
23386
  });
22737
23387
 
@@ -22757,7 +23407,9 @@ var init_gate2 = __esm({
22757
23407
  "scratch",
22758
23408
  "cleanup",
22759
23409
  "deactivate-demo",
22760
- "update"
23410
+ "update",
23411
+ "upgrade",
23412
+ "checkout"
22761
23413
  ]);
22762
23414
  }
22763
23415
  });
@@ -22767,7 +23419,7 @@ var router_exports = {};
22767
23419
  __export(router_exports, {
22768
23420
  conversationRouter: () => conversationRouter
22769
23421
  });
22770
- import chalk59 from "chalk";
23422
+ import chalk61 from "chalk";
22771
23423
  async function conversationRouter(input, ctx) {
22772
23424
  if (ctx.oneShot || (ctx.wizardDepth ?? 0) > 0) {
22773
23425
  return { handled: false };
@@ -22777,7 +23429,7 @@ async function conversationRouter(input, ctx) {
22777
23429
  if (FRESH_START_RE.test(line)) {
22778
23430
  console.log();
22779
23431
  console.log(
22780
- " " + chalk59.dim("Start a fresh analysis? This keeps prior sessions \u2014 say ") + chalk59.cyan("yes") + chalk59.dim(" to confirm or ") + chalk59.cyan("/home") + chalk59.dim(" for the dashboard.")
23432
+ " " + chalk61.dim("Start a fresh analysis? This keeps prior sessions \u2014 say ") + chalk61.cyan("yes") + chalk61.dim(" to confirm or ") + chalk61.cyan("/home") + chalk61.dim(" for the dashboard.")
22781
23433
  );
22782
23434
  console.log();
22783
23435
  return { handled: true };
@@ -22811,7 +23463,7 @@ async function conversationRouter(input, ctx) {
22811
23463
  }
22812
23464
  if (phase === "compute") {
22813
23465
  console.log();
22814
- console.log(" " + chalk59.dim("Analysis running \u2014 wait for it to finish before typing another question."));
23466
+ console.log(" " + chalk61.dim("Analysis running \u2014 wait for it to finish before typing another question."));
22815
23467
  console.log();
22816
23468
  return { handled: true };
22817
23469
  }
@@ -22851,12 +23503,9 @@ var init_router = __esm({
22851
23503
  });
22852
23504
 
22853
23505
  // src/cli/dispatch.ts
22854
- import chalk60 from "chalk";
23506
+ import chalk62 from "chalk";
22855
23507
  function printLicenseRequired(command) {
22856
- console.log();
22857
- console.log(chalk60.red(` A license is required for ${command}.`));
22858
- console.log(chalk60.dim(` Purchase at ${PURCHASE_URL2} or run /activate <key>.`));
22859
- console.log();
23508
+ printLicenseBlocked(command);
22860
23509
  }
22861
23510
  function handledResult(command, summary, ctx) {
22862
23511
  return {
@@ -22920,7 +23569,7 @@ async function dispatch(input, ctx) {
22920
23569
  if (tokens.length === 1) {
22921
23570
  if (/^\d$/.test(first)) {
22922
23571
  console.log(
22923
- " " + chalk60.dim("Looks like a menu pick \u2014 run ") + paint("accent", "/new") + chalk60.dim(" to start (pick Demo, then choose your analysis type).")
23572
+ " " + chalk62.dim("Looks like a menu pick \u2014 run ") + paint("accent", "/new") + chalk62.dim(" to start (pick Demo, then choose your analysis type).")
22924
23573
  );
22925
23574
  return { kind: "handled" };
22926
23575
  }
@@ -22943,22 +23592,22 @@ async function dispatch(input, ctx) {
22943
23592
  return { kind: "handled", summary };
22944
23593
  }
22945
23594
  console.log(
22946
- " " + chalk60.dim("Not in Q&A yet \u2014 confirm scope, load data, and run analysis first. Type ") + paint("accent", "/home") + chalk60.dim(" for status.")
23595
+ " " + chalk62.dim("Not in Q&A yet \u2014 confirm scope, load data, and run analysis first. Type ") + paint("accent", "/home") + chalk62.dim(" for status.")
22947
23596
  );
22948
23597
  return { kind: "handled" };
22949
23598
  }
22950
23599
  console.log(
22951
- " " + chalk60.dim("Natural-language questions run in the interactive REPL. Start with ") + paint("accent", "ntrp") + chalk60.dim(" and ask after analysis.")
23600
+ " " + chalk62.dim("Natural-language questions run in the interactive REPL. Start with ") + paint("accent", "ntrp") + chalk62.dim(" and ask after analysis.")
22952
23601
  );
22953
23602
  return { kind: "handled" };
22954
23603
  }
22955
23604
  async function runSlashCommand(name, args, ctx) {
22956
- const handler42 = await resolveHandler(name);
22957
- if (!handler42) {
22958
- console.error(chalk60.red(` Unknown command: /${name}`));
23605
+ const handler44 = await resolveHandler(name);
23606
+ if (!handler44) {
23607
+ console.error(chalk62.red(` Unknown command: /${name}`));
22959
23608
  return void 0;
22960
23609
  }
22961
- const result = await handler42(args, ctx);
23610
+ const result = await handler44(args, ctx);
22962
23611
  return result ?? void 0;
22963
23612
  }
22964
23613
  async function runNaturalLanguage2(input, ctx) {
@@ -22966,7 +23615,6 @@ async function runNaturalLanguage2(input, ctx) {
22966
23615
  const result = await mod.runNaturalLanguage(input, ctx);
22967
23616
  return result ?? void 0;
22968
23617
  }
22969
- var PURCHASE_URL2;
22970
23618
  var init_dispatch = __esm({
22971
23619
  "src/cli/dispatch.ts"() {
22972
23620
  "use strict";
@@ -22978,7 +23626,7 @@ var init_dispatch = __esm({
22978
23626
  init_theme();
22979
23627
  init_activation();
22980
23628
  init_gate2();
22981
- PURCHASE_URL2 = "https://ntrp.sonnechasser.com";
23629
+ init_upgrade();
22982
23630
  }
22983
23631
  });
22984
23632
 
@@ -22988,7 +23636,7 @@ __export(welcome_exports, {
22988
23636
  GRADIENT: () => GRADIENT,
22989
23637
  printWelcome: () => printWelcome
22990
23638
  });
22991
- import chalk61 from "chalk";
23639
+ import chalk63 from "chalk";
22992
23640
  function resolveSessionSummary(input) {
22993
23641
  if (input.scope?.intent_summary?.trim()) return input.scope.intent_summary.trim();
22994
23642
  if (input.summary?.trim()) return input.summary.trim();
@@ -23022,19 +23670,19 @@ function sessionSummaryText(s) {
23022
23670
  summary: s.summary,
23023
23671
  dataset: s.dataset
23024
23672
  });
23025
- return summary === NO_SUMMARY ? chalk61.dim(summary) : summary;
23673
+ return summary === NO_SUMMARY ? chalk63.dim(summary) : summary;
23026
23674
  }
23027
23675
  function formatLastSessionLine(s, colW, ctx, opts) {
23028
23676
  const phase = sessionPhaseLabel(s, ctx);
23029
- const current = opts?.markCurrent && s.id === ctx?.sessionId ? chalk61.dim(" \xB7 current") : "";
23030
- const meta = `${formatSessionId(s.id, s.name)} ${chalk61.dim("\xB7")} ${chalk61.dim(lensBadgeLabel(s.analysis))} ${chalk61.dim("\xB7")} ${paint("accent", phase)} ${chalk61.dim("\xB7")} ${sessionSummaryText(s)}${current}`;
23677
+ const current = opts?.markCurrent && s.id === ctx?.sessionId ? chalk63.dim(" \xB7 current") : "";
23678
+ const meta = `${formatSessionId(s.id, s.name)} ${chalk63.dim("\xB7")} ${chalk63.dim(lensBadgeLabel(s.analysis))} ${chalk63.dim("\xB7")} ${paint("accent", phase)} ${chalk63.dim("\xB7")} ${sessionSummaryText(s)}${current}`;
23031
23679
  return truncateVisible(` ${meta}`, colW);
23032
23680
  }
23033
23681
  function formatActiveSessionLine(s, colW, ctx, opts) {
23034
23682
  const indent = " ";
23035
23683
  const idPart = formatSessionId(s.id, s.name);
23036
- const status = chalk61.dim(` \xB7 ${sessionStatusSuffix(s)}`);
23037
- const current = opts?.markCurrent && s.id === ctx?.sessionId ? chalk61.dim(" \xB7 current") : "";
23684
+ const status = chalk63.dim(` \xB7 ${sessionStatusSuffix(s)}`);
23685
+ const current = opts?.markCurrent && s.id === ctx?.sessionId ? chalk63.dim(" \xB7 current") : "";
23038
23686
  const suffix = `${status}${current}`;
23039
23687
  const summaryBudget = Math.max(8, colW - visibleWidth(indent) - visibleWidth(idPart) - visibleWidth(suffix) - 2);
23040
23688
  const summaryPart = truncateVisible(sessionSummaryText(s), summaryBudget);
@@ -23071,13 +23719,13 @@ function buildSystemLines(colW, statusRows, recent) {
23071
23719
  const lines = [""];
23072
23720
  lines.push(sectionHeading("System"));
23073
23721
  for (const item of statusRows) {
23074
- const label = chalk61.dim(padRight(item.label, 8));
23722
+ const label = chalk63.dim(padRight(item.label, 8));
23075
23723
  const state = padRight(item.state, 10);
23076
23724
  const detailW = Math.max(1, colW - 21);
23077
- lines.push(`${label} ${state} ${chalk61.dim(truncateVisible(item.detail, detailW))}`);
23725
+ lines.push(`${label} ${state} ${chalk63.dim(truncateVisible(item.detail, detailW))}`);
23078
23726
  }
23079
23727
  if (recent) {
23080
- lines.push(`${chalk61.dim(padRight("last used", 8))} ${chalk61.dim(recent)}`);
23728
+ lines.push(`${chalk63.dim(padRight("last used", 8))} ${chalk63.dim(recent)}`);
23081
23729
  }
23082
23730
  return lines;
23083
23731
  }
@@ -23087,7 +23735,7 @@ function buildHelpLines(colW, unfinishedCount) {
23087
23735
  lines.push(sectionHeading(section.heading));
23088
23736
  for (const entry of section.entries) {
23089
23737
  const desc = entry.dynamicDescription ? entry.dynamicDescription(unfinishedCount) : entry.description;
23090
- const text = ` ${paint("accent", entry.command)} ${chalk61.dim(desc)}`;
23738
+ const text = ` ${paint("accent", entry.command)} ${chalk63.dim(desc)}`;
23091
23739
  lines.push(truncateVisible(text, colW));
23092
23740
  }
23093
23741
  }
@@ -23097,10 +23745,10 @@ function buildLastSessionLines(colW, ctx, lastSession, nextAction, emptyDataHint
23097
23745
  const lines = [""];
23098
23746
  lines.push(sectionHeading("Last Session"));
23099
23747
  if (!lastSession) {
23100
- lines.push(` ${chalk61.dim("(none yet)")}`);
23748
+ lines.push(` ${chalk63.dim("(none yet)")}`);
23101
23749
  lines.push(
23102
23750
  truncateVisible(
23103
- ` ${nextAction.command ? actionHint(nextAction.label, nextAction.command, nextAction.detail) : `${chalk61.dim(nextAction.label)} ${chalk61.dim(nextAction.detail)}`}`,
23751
+ ` ${nextAction.command ? actionHint(nextAction.label, nextAction.command, nextAction.detail) : `${chalk63.dim(nextAction.label)} ${chalk63.dim(nextAction.detail)}`}`,
23104
23752
  colW
23105
23753
  )
23106
23754
  );
@@ -23111,7 +23759,7 @@ function buildLastSessionLines(colW, ctx, lastSession, nextAction, emptyDataHint
23111
23759
  if (!isCurrent) {
23112
23760
  lines.push(
23113
23761
  truncateVisible(
23114
- ` ${chalk61.dim("Resume:")} ${paint("accent", `/session ${lastSession.id.slice(-4)}`)}`,
23762
+ ` ${chalk63.dim("Resume:")} ${paint("accent", `/session ${lastSession.id.slice(-4)}`)}`,
23115
23763
  colW
23116
23764
  )
23117
23765
  );
@@ -23120,7 +23768,7 @@ function buildLastSessionLines(colW, ctx, lastSession, nextAction, emptyDataHint
23120
23768
  truncateVisible(` ${actionHint(nextAction.label, nextAction.command, nextAction.detail)}`, colW)
23121
23769
  );
23122
23770
  } else {
23123
- lines.push(truncateVisible(` ${chalk61.dim(nextAction.label)} ${chalk61.dim(nextAction.detail)}`, colW));
23771
+ lines.push(truncateVisible(` ${chalk63.dim(nextAction.label)} ${chalk63.dim(nextAction.detail)}`, colW));
23124
23772
  }
23125
23773
  if (isCurrent && emptyDataHint) {
23126
23774
  lines.push(truncateVisible(` ${emptyDataHint}`, colW));
@@ -23131,14 +23779,14 @@ function buildActiveSessionsLines(colW, ctx, activeSessions) {
23131
23779
  const lines = [""];
23132
23780
  lines.push(sectionHeading("Active Sessions"));
23133
23781
  if (activeSessions.length === 0) {
23134
- lines.push(` ${chalk61.dim("(none in progress)")}`);
23782
+ lines.push(` ${chalk63.dim("(none in progress)")}`);
23135
23783
  return lines;
23136
23784
  }
23137
23785
  for (const s of activeSessions.slice(0, 5)) {
23138
23786
  lines.push(formatActiveSessionLine(s, colW, ctx, { markCurrent: true }));
23139
23787
  }
23140
23788
  if (activeSessions.length > 5) {
23141
- lines.push(` ${chalk61.dim(`+${activeSessions.length - 5} more \xB7 `)}${paint("accent", "/session")}`);
23789
+ lines.push(` ${chalk63.dim(`+${activeSessions.length - 5} more \xB7 `)}${paint("accent", "/session")}`);
23142
23790
  }
23143
23791
  return lines;
23144
23792
  }
@@ -23148,7 +23796,7 @@ async function printWelcome(ctx, version) {
23148
23796
  const innerW = cardW - 2;
23149
23797
  const contentW = innerW - 2;
23150
23798
  const outerPad = " ".repeat(Math.max(0, Math.floor((width - cardW) / 2)));
23151
- const border = (ch) => chalk61.dim(ch);
23799
+ const border = (ch) => chalk63.dim(ch);
23152
23800
  const push = (line) => console.log(outerPad + line);
23153
23801
  const fitCell = (content, width2) => {
23154
23802
  if (visibleWidth(content) > width2) return truncateVisible(content, width2);
@@ -23221,7 +23869,7 @@ async function printWelcome(ctx, version) {
23221
23869
  ctx,
23222
23870
  unfinishedCount: unfinishedSessions.length
23223
23871
  });
23224
- const emptyDataHint = !hasData ? savedSessions.length > 0 ? chalk61.dim("Run ") + paint("accent", "/session") + chalk61.dim(" to resume a saved analysis, or ") + paint("accent", "/new") + chalk61.dim(" for a fresh start") : chalk61.dim("Run ") + paint("accent", "/new") + chalk61.dim(" \u2192 pick Demo to explore sample data") : null;
23872
+ const emptyDataHint = !hasData ? savedSessions.length > 0 ? chalk63.dim("Run ") + paint("accent", "/session") + chalk63.dim(" to resume a saved analysis, or ") + paint("accent", "/new") + chalk63.dim(" for a fresh start") : chalk63.dim("Run ") + paint("accent", "/new") + chalk63.dim(" \u2192 pick Demo to explore sample data") : null;
23225
23873
  const colW = useWideLayout ? leftW : contentW;
23226
23874
  const rightColW = useWideLayout ? rightW : contentW;
23227
23875
  const systemLines = buildSystemLines(colW, statusRows, recent);
@@ -23236,14 +23884,14 @@ async function printWelcome(ctx, version) {
23236
23884
  const logoOffset = " ".repeat(Math.max(0, Math.floor((cardW - maxLogoW) / 2)));
23237
23885
  for (const line of logo) push(logoOffset + line);
23238
23886
  const taglineOffset = " ".repeat(Math.max(0, Math.floor((cardW - visibleWidth(TAGLINE)) / 2)));
23239
- push(taglineOffset + chalk61.dim(TAGLINE));
23887
+ push(taglineOffset + chalk63.dim(TAGLINE));
23240
23888
  push("");
23241
23889
  }
23242
23890
  const versionTag = ` v${version} `;
23243
23891
  const gap = Math.max(0, innerW - versionTag.length);
23244
23892
  const gapL = Math.floor(gap / 2);
23245
23893
  push(
23246
- border(`\u256D${"\u2500".repeat(gapL)}`) + chalk61.dim(versionTag) + border(`${"\u2500".repeat(gap - gapL)}\u256E`)
23894
+ border(`\u256D${"\u2500".repeat(gapL)}`) + chalk63.dim(versionTag) + border(`${"\u2500".repeat(gap - gapL)}\u256E`)
23247
23895
  );
23248
23896
  if (useWideLayout) {
23249
23897
  const leftLines = [...systemLines, ...helpLines];
@@ -23337,7 +23985,7 @@ __export(repl_exports, {
23337
23985
  import { createInterface as createInterface2 } from "readline/promises";
23338
23986
  import { clearLine as clearLine2, cursorTo as cursorTo2 } from "readline";
23339
23987
  import ora16 from "ora";
23340
- import chalk62 from "chalk";
23988
+ import chalk64 from "chalk";
23341
23989
  function buildPrompt(ctx) {
23342
23990
  return buildConversationPrompt(ctx);
23343
23991
  }
@@ -23372,12 +24020,12 @@ function renderInlineSuggestion(rl, prompt) {
23372
24020
  const suffix = cursor === line.length ? inlineCommandSuggestion(line) : null;
23373
24021
  clearLine2(process.stdout, 0);
23374
24022
  cursorTo2(process.stdout, 0);
23375
- process.stdout.write(prompt + line + (suffix ? chalk62.dim(suffix) : ""));
24023
+ process.stdout.write(prompt + line + (suffix ? chalk64.dim(suffix) : ""));
23376
24024
  cursorTo2(process.stdout, visibleLength(prompt) + cursor);
23377
24025
  }
23378
24026
  function appendTurnLine(current, promptLabel, currentSummary) {
23379
- const currentLine = currentSummary ? `${promptLabel} ${current} ${chalk62.white("\u2192")} ${currentSummary}` : `${promptLabel} ${current}`;
23380
- console.log(" " + chalk62.dim(currentLine));
24027
+ const currentLine = currentSummary ? `${promptLabel} ${current} ${chalk64.white("\u2192")} ${currentSummary}` : `${promptLabel} ${current}`;
24028
+ console.log(" " + chalk64.dim(currentLine));
23381
24029
  console.log();
23382
24030
  }
23383
24031
  async function goHome(ctx, version, history, opts) {
@@ -23387,7 +24035,7 @@ async function goHome(ctx, version, history, opts) {
23387
24035
  process.stdout.write("\x1B[2J\x1B[H");
23388
24036
  if (opts?.banner) {
23389
24037
  console.log();
23390
- console.log(" " + paint("accent", "\u2713") + " " + chalk62.dim(opts.banner));
24038
+ console.log(" " + paint("accent", "\u2713") + " " + chalk64.dim(opts.banner));
23391
24039
  }
23392
24040
  await printWelcome(ctx, version);
23393
24041
  }
@@ -23410,11 +24058,11 @@ async function handleDispatchResult(result, ctx, version, history) {
23410
24058
  case "unknown":
23411
24059
  if (result.suggestion) {
23412
24060
  console.log(
23413
- " " + chalk62.red(`Unknown command: ${result.token}.`) + chalk62.dim(" Did you mean ") + paint("accent", result.suggestion) + chalk62.dim("?")
24061
+ " " + chalk64.red(`Unknown command: ${result.token}.`) + chalk64.dim(" Did you mean ") + paint("accent", result.suggestion) + chalk64.dim("?")
23414
24062
  );
23415
24063
  } else {
23416
24064
  console.log(
23417
- " " + chalk62.red(`Unknown command: ${result.token}`) + chalk62.dim(" Type ") + paint("accent", "/help") + chalk62.dim(" to see available commands.")
24065
+ " " + chalk64.red(`Unknown command: ${result.token}`) + chalk64.dim(" Type ") + paint("accent", "/help") + chalk64.dim(" to see available commands.")
23418
24066
  );
23419
24067
  }
23420
24068
  break;
@@ -23438,7 +24086,7 @@ async function runRepl(ctx, version) {
23438
24086
  ctx.rl = rl;
23439
24087
  console.log();
23440
24088
  console.log(
23441
- " " + chalk62.dim("What do you want to look at? ") + chalk62.dim('(e.g. "pipeline health", "is NRR real?", "board deck on Q3")')
24089
+ " " + chalk64.dim("What do you want to look at? ") + chalk64.dim('(e.g. "pipeline health", "is NRR real?", "board deck on Q3")')
23442
24090
  );
23443
24091
  console.log();
23444
24092
  if (ctx.pendingUpdateCheck) {
@@ -23468,7 +24116,7 @@ async function runRepl(ctx, version) {
23468
24116
  return;
23469
24117
  }
23470
24118
  sigintPrimed = true;
23471
- console.log("\n " + chalk62.dim("Type /exit to quit, or press Ctrl+C again."));
24119
+ console.log("\n " + chalk64.dim("Type /exit to quit, or press Ctrl+C again."));
23472
24120
  };
23473
24121
  rl.on("SIGINT", sigintHandler);
23474
24122
  function shutdownRepl() {
@@ -23539,7 +24187,7 @@ async function runRepl(ctx, version) {
23539
24187
  }
23540
24188
  }
23541
24189
  } else {
23542
- console.error(" " + chalk62.red("Error: " + String(err.message ?? err)));
24190
+ console.error(" " + chalk64.red("Error: " + String(err.message ?? err)));
23543
24191
  }
23544
24192
  }
23545
24193
  history.push({ input: line, summary });
@@ -23557,7 +24205,7 @@ async function runRepl(ctx, version) {
23557
24205
  } else {
23558
24206
  await closeSession(ctx);
23559
24207
  }
23560
- console.log(" " + chalk62.dim(randomGoodbye()));
24208
+ console.log(" " + chalk64.dim(randomGoodbye()));
23561
24209
  }
23562
24210
  function printHelpOneShot() {
23563
24211
  printHelp();
@@ -23565,14 +24213,16 @@ function printHelpOneShot() {
23565
24213
  function printHelp() {
23566
24214
  console.log();
23567
24215
  console.log(" " + sectionHeading("Conversation"));
23568
- console.log(" " + chalk62.dim("Type what you want to investigate \u2014 no slash needed."));
23569
- console.log(" " + chalk62.dim("Paste a CSV path or say ") + paint("accent", '"use demo data"') + chalk62.dim(" to load data."));
23570
- console.log(" " + chalk62.dim("After analysis, ask questions in plain English."));
23571
- console.log(" " + chalk62.dim("Say ") + paint("accent", '"ship a board deck"') + chalk62.dim(" to draft a handoff prompt."));
24216
+ console.log(" " + chalk64.dim("Type what you want to investigate \u2014 no slash needed."));
24217
+ console.log(" " + chalk64.dim("Paste a CSV path or say ") + paint("accent", '"use demo data"') + chalk64.dim(" to load data."));
24218
+ console.log(" " + chalk64.dim("After analysis, ask questions in plain English."));
24219
+ console.log(" " + chalk64.dim("Say ") + paint("accent", '"ship a board deck"') + chalk64.dim(" to draft a handoff prompt."));
23572
24220
  console.log();
23573
24221
  console.log(" " + sectionHeading("Shortcuts"));
23574
24222
  const shortcuts = [
23575
24223
  ["/home", "Status dashboard"],
24224
+ ["/upgrade", "Trial \u2192 Pro checkout + key paste"],
24225
+ ["/checkout", "Open signup in browser"],
23576
24226
  ["/update", "Upgrade to the latest version"],
23577
24227
  ["/handoff", "Export or agent prompts"],
23578
24228
  ["/demo", "Load demo data"],
@@ -23581,7 +24231,7 @@ function printHelp() {
23581
24231
  ];
23582
24232
  const maxW = Math.max(...shortcuts.map(([c]) => c.length)) + 2;
23583
24233
  for (const [cmd, desc] of shortcuts) {
23584
- console.log(` ${paint("accent", padRight(cmd, maxW))} ${chalk62.dim(desc)}`);
24234
+ console.log(` ${paint("accent", padRight(cmd, maxW))} ${chalk64.dim(desc)}`);
23585
24235
  }
23586
24236
  console.log();
23587
24237
  console.log(" " + sectionHeading("Admin"));
@@ -23592,10 +24242,10 @@ function printHelp() {
23592
24242
  ];
23593
24243
  const adminMaxW = Math.max(...admin.map(([c]) => c.length)) + 2;
23594
24244
  for (const [cmd, desc] of admin) {
23595
- console.log(` ${paint("accent", padRight(cmd, adminMaxW))} ${chalk62.dim(desc)}`);
24245
+ console.log(` ${paint("accent", padRight(cmd, adminMaxW))} ${chalk64.dim(desc)}`);
23596
24246
  }
23597
24247
  console.log();
23598
- console.log(" " + chalk62.dim("Power-user commands (") + paint("accent", "/new") + chalk62.dim(", ") + paint("accent", "/diagnose") + chalk62.dim(", ") + paint("accent", "/metrics") + chalk62.dim(") remain available."));
24248
+ console.log(" " + chalk64.dim("Power-user commands (") + paint("accent", "/new") + chalk64.dim(", ") + paint("accent", "/diagnose") + chalk64.dim(", ") + paint("accent", "/metrics") + chalk64.dim(") remain available."));
23599
24249
  console.log();
23600
24250
  }
23601
24251
  var REPL_BUILTINS, ANSI_PATTERN, GOODBYES;
@@ -23677,7 +24327,7 @@ init_emit();
23677
24327
  init_errors2();
23678
24328
  init_types2();
23679
24329
  init_version();
23680
- import chalk63 from "chalk";
24330
+ import chalk65 from "chalk";
23681
24331
  var VERSION = getInstalledVersion();
23682
24332
  var UNGATED = UNGATED_COMMANDS;
23683
24333
  var DB_COMMANDS = /* @__PURE__ */ new Set(["actions", "ask", "backmeup", "demo", "diagnose", "export", "handoff", "ingest", "metrics", "new", "playbook", "publish", "report", "reset", "segment", "session", "status", "strategy"]);
@@ -23704,7 +24354,7 @@ async function main() {
23704
24354
  quiet: args.globals.quiet
23705
24355
  });
23706
24356
  if (!ctx.execution.color) {
23707
- chalk63.level = 0;
24357
+ chalk65.level = 0;
23708
24358
  }
23709
24359
  if (args.globals.stdin) {
23710
24360
  args.input = (await readStdin()).trim();
@@ -23712,21 +24362,21 @@ async function main() {
23712
24362
  if (args.oneShot) {
23713
24363
  const cmd = firstToken(args.input);
23714
24364
  if (!UNGATED.has(cmd)) {
23715
- const lic = checkLicense();
23716
- if (!lic.valid) {
24365
+ const lic2 = await refreshLicenseOnline();
24366
+ if (!lic2.valid) {
23717
24367
  if (isStructuredOutput(ctx.execution)) {
23718
- emitError(cmd || "ntrp", new NtrpError("license_invalid", lic.message, 3 /* Auth */));
24368
+ emitError(cmd || "ntrp", new NtrpError("license_invalid", lic2.message, 3 /* Auth */));
23719
24369
  }
23720
- console.error(chalk63.red(`
23721
- ${lic.message}`));
23722
- console.error(chalk63.dim(" Purchase a license at https://ntrp.sonnechasser.com\n"));
24370
+ console.error(chalk65.red(`
24371
+ ${lic2.message}`));
24372
+ console.error(chalk65.dim(" Trial's over \u2014 /upgrade and paste your key.\n"));
23723
24373
  process.exit(1);
23724
24374
  }
23725
24375
  }
23726
24376
  const PROFILE_HINT_SKIP = /* @__PURE__ */ new Set(["onboard", "setup", "config", "activate", "help", "home", "exit", "quit", "clear", "profile"]);
23727
24377
  if (!isProfileConfigured() && !PROFILE_HINT_SKIP.has(cmd) && !ctx.execution.quiet) {
23728
24378
  console.error(
23729
- " " + chalk63.dim("Tip: run ") + paint("accent", "ntrp") + chalk63.dim(" interactively to set up your company profile for richer answers.")
24379
+ " " + chalk65.dim("Tip: run ") + paint("accent", "ntrp") + chalk65.dim(" interactively to set up your company profile for richer answers.")
23730
24380
  );
23731
24381
  }
23732
24382
  const result = await dispatch(args.input, ctx);
@@ -23738,12 +24388,12 @@ async function main() {
23738
24388
  }
23739
24389
  if (result.suggestion) {
23740
24390
  console.error(
23741
- chalk63.red(` Unknown command: ${result.token}.`) + chalk63.dim(" Did you mean ") + paint("accent", result.suggestion) + chalk63.dim("?")
24391
+ chalk65.red(` Unknown command: ${result.token}.`) + chalk65.dim(" Did you mean ") + paint("accent", result.suggestion) + chalk65.dim("?")
23742
24392
  );
23743
24393
  } else {
23744
- console.error(chalk63.red(` Unknown command: ${result.token}`));
24394
+ console.error(chalk65.red(` Unknown command: ${result.token}`));
23745
24395
  }
23746
- console.error(chalk63.dim(" Run 'ntrp' for the interactive prompt."));
24396
+ console.error(chalk65.dim(" Run 'ntrp' for the interactive prompt."));
23747
24397
  process.exit(1);
23748
24398
  break;
23749
24399
  case "help":
@@ -23765,6 +24415,11 @@ async function main() {
23765
24415
  return DB_COMMANDS.has(cmd);
23766
24416
  }
23767
24417
  const showedActivation = await ensureLicenseActivated(ctx);
24418
+ const lic = await refreshLicenseOnline();
24419
+ if (lic.shouldNudgeUpgrade) {
24420
+ const { printGraceNudge: printGraceNudge2 } = await Promise.resolve().then(() => (init_upgrade(), upgrade_exports));
24421
+ printGraceNudge2(lic);
24422
+ }
23768
24423
  if (!isProfileConfigured()) {
23769
24424
  try {
23770
24425
  const { handler: onboard } = await Promise.resolve().then(() => (init_onboard(), onboard_exports));