@sonnechasser/ntrp 0.1.1 → 0.1.2

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/README.md CHANGED
@@ -14,32 +14,32 @@ NTRP sits on top of your CRM exports and activity data, computes five vital sign
14
14
  npm install -g @sonnechasser/ntrp
15
15
  ```
16
16
 
17
- Verify:
18
-
19
- ```bash
20
- ntrp setup check
21
- ```
22
-
23
17
  ## Activate your license
24
18
 
25
- Most commands require a license key.
19
+ NTRP requires a license key from purchase. Keys are delivered after checkout via [ntrp.sonnechasser.com](https://ntrp.sonnechasser.com) (Lemon Squeezy).
20
+
21
+ **On first launch**, `ntrp` will prompt you to paste your key. You can also activate manually:
26
22
 
27
23
  ```bash
28
24
  ntrp activate NTRP-XXXX-XXXX-XXXX
29
25
  ```
30
26
 
31
- In the interactive REPL, use `/activate NTRP-XXXX-XXXX-XXXX`.
32
-
33
- Purchase a license at [ntrp.sonnechasser.com](https://ntrp.sonnechasser.com).
27
+ In the REPL: `/activate NTRP-XXXX-XXXX-XXXX`
34
28
 
35
29
  ## Quick start
36
30
 
37
- Launch the conversational REPL:
31
+ Launch the interactive REPL (license prompt runs first if needed):
38
32
 
39
33
  ```bash
40
34
  ntrp
41
35
  ```
42
36
 
37
+ Verify setup:
38
+
39
+ ```bash
40
+ ntrp setup check
41
+ ```
42
+
43
43
  On first run, complete `/onboard` to set up your company profile, or load sample data:
44
44
 
45
45
  - Type `use demo data` in the REPL, or
package/dist/index.js CHANGED
@@ -3080,6 +3080,15 @@ import chalk5 from "chalk";
3080
3080
  function renderLogo() {
3081
3081
  return LOGO_LINES.map((line, i) => chalk5.hex(GRADIENT[i % GRADIENT.length])(line));
3082
3082
  }
3083
+ function printCenteredLogo() {
3084
+ const width = termWidth();
3085
+ const logo = renderLogo();
3086
+ const maxLogoW = Math.max(...logo.map((l) => visibleWidth(l)));
3087
+ const offset = " ".repeat(Math.max(0, Math.floor((width - maxLogoW) / 2)));
3088
+ console.log();
3089
+ for (const line of logo) console.log(offset + line);
3090
+ console.log();
3091
+ }
3083
3092
  function printReplHeader(version) {
3084
3093
  const width = termWidth();
3085
3094
  const cardW = Math.min(width - 2, 120);
@@ -4656,12 +4665,13 @@ __export(onboard_exports, {
4656
4665
  import chalk7 from "chalk";
4657
4666
  import ora from "ora";
4658
4667
  async function handler2(args, ctx) {
4659
- const { flags } = parseArgs2(args, ["force"]);
4668
+ const { flags } = parseArgs2(args, ["force", "skip-brand"]);
4660
4669
  const force = getBool(flags, "force");
4670
+ const skipBrand = getBool(flags, "skip-brand");
4661
4671
  const priorProfile = loadProfile();
4662
4672
  const configured = isProfileConfigured(priorProfile);
4663
4673
  let existing = configured ? priorProfile : null;
4664
- printBrand();
4674
+ if (!skipBrand) printCenteredLogo();
4665
4675
  const session = createPromptSession(ctx.rl, ctx);
4666
4676
  try {
4667
4677
  if (configured && !force) {
@@ -4964,15 +4974,6 @@ async function editField(session, p, field) {
4964
4974
  }
4965
4975
  }
4966
4976
  }
4967
- function printBrand() {
4968
- const width = termWidth();
4969
- const logo = renderLogo();
4970
- const maxLogoW = Math.max(...logo.map((l) => visibleWidth(l)));
4971
- const offset = " ".repeat(Math.max(0, Math.floor((width - maxLogoW) / 2)));
4972
- console.log();
4973
- for (const line of logo) console.log(offset + line);
4974
- console.log();
4975
- }
4976
4977
  function printIntro() {
4977
4978
  console.log(" " + bold("Let's set up your company profile."));
4978
4979
  console.log(" " + chalk7.dim("NTRP will research your business so every answer,"));
@@ -5036,7 +5037,6 @@ var init_onboard = __esm({
5036
5037
  init_markdown();
5037
5038
  init_theme();
5038
5039
  init_banner();
5039
- init_layout();
5040
5040
  init_prompts();
5041
5041
  init_repl_api();
5042
5042
  init_store();
@@ -22675,12 +22675,99 @@ paragraph that flows into all AI surfaces.`
22675
22675
  }
22676
22676
  });
22677
22677
 
22678
+ // src/license/activation.ts
22679
+ import chalk58 from "chalk";
22680
+ function hasValidLicense() {
22681
+ return checkLicense().valid;
22682
+ }
22683
+ async function ensureLicenseActivated(ctx) {
22684
+ if (hasValidLicense()) return false;
22685
+ if (!process.stdin.isTTY) {
22686
+ 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."));
22691
+ console.error();
22692
+ process.exit(1);
22693
+ }
22694
+ printCenteredLogo();
22695
+ 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
+ );
22699
+ 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
+ }
22724
+ }
22725
+ var PURCHASE_URL;
22726
+ var init_activation = __esm({
22727
+ "src/license/activation.ts"() {
22728
+ "use strict";
22729
+ init_prompts();
22730
+ init_store();
22731
+ init_banner();
22732
+ init_theme();
22733
+ init_verify();
22734
+ PURCHASE_URL = "https://ntrp.sonnechasser.com";
22735
+ }
22736
+ });
22737
+
22738
+ // src/license/gate.ts
22739
+ function isLicenseGated(command) {
22740
+ return !UNGATED_COMMANDS.has(command);
22741
+ }
22742
+ var UNGATED_COMMANDS;
22743
+ var init_gate2 = __esm({
22744
+ "src/license/gate.ts"() {
22745
+ "use strict";
22746
+ UNGATED_COMMANDS = /* @__PURE__ */ new Set([
22747
+ "activate",
22748
+ "config",
22749
+ "profile",
22750
+ "onboard",
22751
+ "setup",
22752
+ "help",
22753
+ "home",
22754
+ "exit",
22755
+ "quit",
22756
+ "clear",
22757
+ "scratch",
22758
+ "cleanup",
22759
+ "deactivate-demo",
22760
+ "update"
22761
+ ]);
22762
+ }
22763
+ });
22764
+
22678
22765
  // src/conversation/router.ts
22679
22766
  var router_exports = {};
22680
22767
  __export(router_exports, {
22681
22768
  conversationRouter: () => conversationRouter
22682
22769
  });
22683
- import chalk58 from "chalk";
22770
+ import chalk59 from "chalk";
22684
22771
  async function conversationRouter(input, ctx) {
22685
22772
  if (ctx.oneShot || (ctx.wizardDepth ?? 0) > 0) {
22686
22773
  return { handled: false };
@@ -22690,7 +22777,7 @@ async function conversationRouter(input, ctx) {
22690
22777
  if (FRESH_START_RE.test(line)) {
22691
22778
  console.log();
22692
22779
  console.log(
22693
- " " + chalk58.dim("Start a fresh analysis? This keeps prior sessions \u2014 say ") + chalk58.cyan("yes") + chalk58.dim(" to confirm or ") + chalk58.cyan("/home") + chalk58.dim(" for the dashboard.")
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.")
22694
22781
  );
22695
22782
  console.log();
22696
22783
  return { handled: true };
@@ -22724,7 +22811,7 @@ async function conversationRouter(input, ctx) {
22724
22811
  }
22725
22812
  if (phase === "compute") {
22726
22813
  console.log();
22727
- console.log(" " + chalk58.dim("Analysis running \u2014 wait for it to finish before typing another question."));
22814
+ console.log(" " + chalk59.dim("Analysis running \u2014 wait for it to finish before typing another question."));
22728
22815
  console.log();
22729
22816
  return { handled: true };
22730
22817
  }
@@ -22764,7 +22851,13 @@ var init_router = __esm({
22764
22851
  });
22765
22852
 
22766
22853
  // src/cli/dispatch.ts
22767
- import chalk59 from "chalk";
22854
+ import chalk60 from "chalk";
22855
+ 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();
22860
+ }
22768
22861
  function handledResult(command, summary, ctx) {
22769
22862
  return {
22770
22863
  kind: "handled",
@@ -22791,6 +22884,10 @@ async function dispatch(input, ctx) {
22791
22884
  if (first.startsWith("/")) {
22792
22885
  const name = first.slice(1);
22793
22886
  if (hasCommand(name)) {
22887
+ if (!ctx.oneShot && isLicenseGated(name) && !hasValidLicense()) {
22888
+ printLicenseRequired(`/${name}`);
22889
+ return { kind: "handled" };
22890
+ }
22794
22891
  const summary = await runSlashCommand(name, tokens.slice(1), ctx);
22795
22892
  return handledResult(name, summary, ctx);
22796
22893
  }
@@ -22798,10 +22895,18 @@ async function dispatch(input, ctx) {
22798
22895
  return suggestion ? { kind: "unknown", token: first, suggestion: `/${suggestion}` } : { kind: "unknown", token: first };
22799
22896
  }
22800
22897
  if (hasCommand(first)) {
22898
+ if (!ctx.oneShot && isLicenseGated(first) && !hasValidLicense()) {
22899
+ printLicenseRequired(first);
22900
+ return { kind: "handled" };
22901
+ }
22801
22902
  const summary = await runSlashCommand(first, tokens.slice(1), ctx);
22802
22903
  return handledResult(first, summary, ctx);
22803
22904
  }
22804
22905
  if (!ctx.oneShot) {
22906
+ if (!hasValidLicense()) {
22907
+ printLicenseRequired("this action");
22908
+ return { kind: "handled" };
22909
+ }
22805
22910
  const { conversationRouter: conversationRouter2 } = await Promise.resolve().then(() => (init_router(), router_exports));
22806
22911
  const routed = await conversationRouter2(line, ctx);
22807
22912
  if (routed.handled) {
@@ -22815,7 +22920,7 @@ async function dispatch(input, ctx) {
22815
22920
  if (tokens.length === 1) {
22816
22921
  if (/^\d$/.test(first)) {
22817
22922
  console.log(
22818
- " " + chalk59.dim("Looks like a menu pick \u2014 run ") + paint("accent", "/new") + chalk59.dim(" to start (pick Demo, then choose your analysis type).")
22923
+ " " + chalk60.dim("Looks like a menu pick \u2014 run ") + paint("accent", "/new") + chalk60.dim(" to start (pick Demo, then choose your analysis type).")
22819
22924
  );
22820
22925
  return { kind: "handled" };
22821
22926
  }
@@ -22838,19 +22943,19 @@ async function dispatch(input, ctx) {
22838
22943
  return { kind: "handled", summary };
22839
22944
  }
22840
22945
  console.log(
22841
- " " + chalk59.dim("Not in Q&A yet \u2014 confirm scope, load data, and run analysis first. Type ") + paint("accent", "/home") + chalk59.dim(" for status.")
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.")
22842
22947
  );
22843
22948
  return { kind: "handled" };
22844
22949
  }
22845
22950
  console.log(
22846
- " " + chalk59.dim("Natural-language questions run in the interactive REPL. Start with ") + paint("accent", "ntrp") + chalk59.dim(" and ask after analysis.")
22951
+ " " + chalk60.dim("Natural-language questions run in the interactive REPL. Start with ") + paint("accent", "ntrp") + chalk60.dim(" and ask after analysis.")
22847
22952
  );
22848
22953
  return { kind: "handled" };
22849
22954
  }
22850
22955
  async function runSlashCommand(name, args, ctx) {
22851
22956
  const handler42 = await resolveHandler(name);
22852
22957
  if (!handler42) {
22853
- console.error(chalk59.red(` Unknown command: /${name}`));
22958
+ console.error(chalk60.red(` Unknown command: /${name}`));
22854
22959
  return void 0;
22855
22960
  }
22856
22961
  const result = await handler42(args, ctx);
@@ -22861,6 +22966,7 @@ async function runNaturalLanguage2(input, ctx) {
22861
22966
  const result = await mod.runNaturalLanguage(input, ctx);
22862
22967
  return result ?? void 0;
22863
22968
  }
22969
+ var PURCHASE_URL2;
22864
22970
  var init_dispatch = __esm({
22865
22971
  "src/cli/dispatch.ts"() {
22866
22972
  "use strict";
@@ -22870,6 +22976,9 @@ var init_dispatch = __esm({
22870
22976
  init_repl_globals();
22871
22977
  init_registry2();
22872
22978
  init_theme();
22979
+ init_activation();
22980
+ init_gate2();
22981
+ PURCHASE_URL2 = "https://ntrp.sonnechasser.com";
22873
22982
  }
22874
22983
  });
22875
22984
 
@@ -22879,7 +22988,7 @@ __export(welcome_exports, {
22879
22988
  GRADIENT: () => GRADIENT,
22880
22989
  printWelcome: () => printWelcome
22881
22990
  });
22882
- import chalk60 from "chalk";
22991
+ import chalk61 from "chalk";
22883
22992
  function resolveSessionSummary(input) {
22884
22993
  if (input.scope?.intent_summary?.trim()) return input.scope.intent_summary.trim();
22885
22994
  if (input.summary?.trim()) return input.summary.trim();
@@ -22913,19 +23022,19 @@ function sessionSummaryText(s) {
22913
23022
  summary: s.summary,
22914
23023
  dataset: s.dataset
22915
23024
  });
22916
- return summary === NO_SUMMARY ? chalk60.dim(summary) : summary;
23025
+ return summary === NO_SUMMARY ? chalk61.dim(summary) : summary;
22917
23026
  }
22918
23027
  function formatLastSessionLine(s, colW, ctx, opts) {
22919
23028
  const phase = sessionPhaseLabel(s, ctx);
22920
- const current = opts?.markCurrent && s.id === ctx?.sessionId ? chalk60.dim(" \xB7 current") : "";
22921
- const meta = `${formatSessionId(s.id, s.name)} ${chalk60.dim("\xB7")} ${chalk60.dim(lensBadgeLabel(s.analysis))} ${chalk60.dim("\xB7")} ${paint("accent", phase)} ${chalk60.dim("\xB7")} ${sessionSummaryText(s)}${current}`;
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}`;
22922
23031
  return truncateVisible(` ${meta}`, colW);
22923
23032
  }
22924
23033
  function formatActiveSessionLine(s, colW, ctx, opts) {
22925
23034
  const indent = " ";
22926
23035
  const idPart = formatSessionId(s.id, s.name);
22927
- const status = chalk60.dim(` \xB7 ${sessionStatusSuffix(s)}`);
22928
- const current = opts?.markCurrent && s.id === ctx?.sessionId ? chalk60.dim(" \xB7 current") : "";
23036
+ const status = chalk61.dim(` \xB7 ${sessionStatusSuffix(s)}`);
23037
+ const current = opts?.markCurrent && s.id === ctx?.sessionId ? chalk61.dim(" \xB7 current") : "";
22929
23038
  const suffix = `${status}${current}`;
22930
23039
  const summaryBudget = Math.max(8, colW - visibleWidth(indent) - visibleWidth(idPart) - visibleWidth(suffix) - 2);
22931
23040
  const summaryPart = truncateVisible(sessionSummaryText(s), summaryBudget);
@@ -22962,13 +23071,13 @@ function buildSystemLines(colW, statusRows, recent) {
22962
23071
  const lines = [""];
22963
23072
  lines.push(sectionHeading("System"));
22964
23073
  for (const item of statusRows) {
22965
- const label = chalk60.dim(padRight(item.label, 8));
23074
+ const label = chalk61.dim(padRight(item.label, 8));
22966
23075
  const state = padRight(item.state, 10);
22967
23076
  const detailW = Math.max(1, colW - 21);
22968
- lines.push(`${label} ${state} ${chalk60.dim(truncateVisible(item.detail, detailW))}`);
23077
+ lines.push(`${label} ${state} ${chalk61.dim(truncateVisible(item.detail, detailW))}`);
22969
23078
  }
22970
23079
  if (recent) {
22971
- lines.push(`${chalk60.dim(padRight("last used", 8))} ${chalk60.dim(recent)}`);
23080
+ lines.push(`${chalk61.dim(padRight("last used", 8))} ${chalk61.dim(recent)}`);
22972
23081
  }
22973
23082
  return lines;
22974
23083
  }
@@ -22978,7 +23087,7 @@ function buildHelpLines(colW, unfinishedCount) {
22978
23087
  lines.push(sectionHeading(section.heading));
22979
23088
  for (const entry of section.entries) {
22980
23089
  const desc = entry.dynamicDescription ? entry.dynamicDescription(unfinishedCount) : entry.description;
22981
- const text = ` ${paint("accent", entry.command)} ${chalk60.dim(desc)}`;
23090
+ const text = ` ${paint("accent", entry.command)} ${chalk61.dim(desc)}`;
22982
23091
  lines.push(truncateVisible(text, colW));
22983
23092
  }
22984
23093
  }
@@ -22988,10 +23097,10 @@ function buildLastSessionLines(colW, ctx, lastSession, nextAction, emptyDataHint
22988
23097
  const lines = [""];
22989
23098
  lines.push(sectionHeading("Last Session"));
22990
23099
  if (!lastSession) {
22991
- lines.push(` ${chalk60.dim("(none yet)")}`);
23100
+ lines.push(` ${chalk61.dim("(none yet)")}`);
22992
23101
  lines.push(
22993
23102
  truncateVisible(
22994
- ` ${nextAction.command ? actionHint(nextAction.label, nextAction.command, nextAction.detail) : `${chalk60.dim(nextAction.label)} ${chalk60.dim(nextAction.detail)}`}`,
23103
+ ` ${nextAction.command ? actionHint(nextAction.label, nextAction.command, nextAction.detail) : `${chalk61.dim(nextAction.label)} ${chalk61.dim(nextAction.detail)}`}`,
22995
23104
  colW
22996
23105
  )
22997
23106
  );
@@ -23002,7 +23111,7 @@ function buildLastSessionLines(colW, ctx, lastSession, nextAction, emptyDataHint
23002
23111
  if (!isCurrent) {
23003
23112
  lines.push(
23004
23113
  truncateVisible(
23005
- ` ${chalk60.dim("Resume:")} ${paint("accent", `/session ${lastSession.id.slice(-4)}`)}`,
23114
+ ` ${chalk61.dim("Resume:")} ${paint("accent", `/session ${lastSession.id.slice(-4)}`)}`,
23006
23115
  colW
23007
23116
  )
23008
23117
  );
@@ -23011,7 +23120,7 @@ function buildLastSessionLines(colW, ctx, lastSession, nextAction, emptyDataHint
23011
23120
  truncateVisible(` ${actionHint(nextAction.label, nextAction.command, nextAction.detail)}`, colW)
23012
23121
  );
23013
23122
  } else {
23014
- lines.push(truncateVisible(` ${chalk60.dim(nextAction.label)} ${chalk60.dim(nextAction.detail)}`, colW));
23123
+ lines.push(truncateVisible(` ${chalk61.dim(nextAction.label)} ${chalk61.dim(nextAction.detail)}`, colW));
23015
23124
  }
23016
23125
  if (isCurrent && emptyDataHint) {
23017
23126
  lines.push(truncateVisible(` ${emptyDataHint}`, colW));
@@ -23022,14 +23131,14 @@ function buildActiveSessionsLines(colW, ctx, activeSessions) {
23022
23131
  const lines = [""];
23023
23132
  lines.push(sectionHeading("Active Sessions"));
23024
23133
  if (activeSessions.length === 0) {
23025
- lines.push(` ${chalk60.dim("(none in progress)")}`);
23134
+ lines.push(` ${chalk61.dim("(none in progress)")}`);
23026
23135
  return lines;
23027
23136
  }
23028
23137
  for (const s of activeSessions.slice(0, 5)) {
23029
23138
  lines.push(formatActiveSessionLine(s, colW, ctx, { markCurrent: true }));
23030
23139
  }
23031
23140
  if (activeSessions.length > 5) {
23032
- lines.push(` ${chalk60.dim(`+${activeSessions.length - 5} more \xB7 `)}${paint("accent", "/session")}`);
23141
+ lines.push(` ${chalk61.dim(`+${activeSessions.length - 5} more \xB7 `)}${paint("accent", "/session")}`);
23033
23142
  }
23034
23143
  return lines;
23035
23144
  }
@@ -23039,7 +23148,7 @@ async function printWelcome(ctx, version) {
23039
23148
  const innerW = cardW - 2;
23040
23149
  const contentW = innerW - 2;
23041
23150
  const outerPad = " ".repeat(Math.max(0, Math.floor((width - cardW) / 2)));
23042
- const border = (ch) => chalk60.dim(ch);
23151
+ const border = (ch) => chalk61.dim(ch);
23043
23152
  const push = (line) => console.log(outerPad + line);
23044
23153
  const fitCell = (content, width2) => {
23045
23154
  if (visibleWidth(content) > width2) return truncateVisible(content, width2);
@@ -23112,7 +23221,7 @@ async function printWelcome(ctx, version) {
23112
23221
  ctx,
23113
23222
  unfinishedCount: unfinishedSessions.length
23114
23223
  });
23115
- const emptyDataHint = !hasData ? savedSessions.length > 0 ? chalk60.dim("Run ") + paint("accent", "/session") + chalk60.dim(" to resume a saved analysis, or ") + paint("accent", "/new") + chalk60.dim(" for a fresh start") : chalk60.dim("Run ") + paint("accent", "/new") + chalk60.dim(" \u2192 pick Demo to explore sample data") : null;
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;
23116
23225
  const colW = useWideLayout ? leftW : contentW;
23117
23226
  const rightColW = useWideLayout ? rightW : contentW;
23118
23227
  const systemLines = buildSystemLines(colW, statusRows, recent);
@@ -23127,14 +23236,14 @@ async function printWelcome(ctx, version) {
23127
23236
  const logoOffset = " ".repeat(Math.max(0, Math.floor((cardW - maxLogoW) / 2)));
23128
23237
  for (const line of logo) push(logoOffset + line);
23129
23238
  const taglineOffset = " ".repeat(Math.max(0, Math.floor((cardW - visibleWidth(TAGLINE)) / 2)));
23130
- push(taglineOffset + chalk60.dim(TAGLINE));
23239
+ push(taglineOffset + chalk61.dim(TAGLINE));
23131
23240
  push("");
23132
23241
  }
23133
23242
  const versionTag = ` v${version} `;
23134
23243
  const gap = Math.max(0, innerW - versionTag.length);
23135
23244
  const gapL = Math.floor(gap / 2);
23136
23245
  push(
23137
- border(`\u256D${"\u2500".repeat(gapL)}`) + chalk60.dim(versionTag) + border(`${"\u2500".repeat(gap - gapL)}\u256E`)
23246
+ border(`\u256D${"\u2500".repeat(gapL)}`) + chalk61.dim(versionTag) + border(`${"\u2500".repeat(gap - gapL)}\u256E`)
23138
23247
  );
23139
23248
  if (useWideLayout) {
23140
23249
  const leftLines = [...systemLines, ...helpLines];
@@ -23228,7 +23337,7 @@ __export(repl_exports, {
23228
23337
  import { createInterface as createInterface2 } from "readline/promises";
23229
23338
  import { clearLine as clearLine2, cursorTo as cursorTo2 } from "readline";
23230
23339
  import ora16 from "ora";
23231
- import chalk61 from "chalk";
23340
+ import chalk62 from "chalk";
23232
23341
  function buildPrompt(ctx) {
23233
23342
  return buildConversationPrompt(ctx);
23234
23343
  }
@@ -23263,12 +23372,12 @@ function renderInlineSuggestion(rl, prompt) {
23263
23372
  const suffix = cursor === line.length ? inlineCommandSuggestion(line) : null;
23264
23373
  clearLine2(process.stdout, 0);
23265
23374
  cursorTo2(process.stdout, 0);
23266
- process.stdout.write(prompt + line + (suffix ? chalk61.dim(suffix) : ""));
23375
+ process.stdout.write(prompt + line + (suffix ? chalk62.dim(suffix) : ""));
23267
23376
  cursorTo2(process.stdout, visibleLength(prompt) + cursor);
23268
23377
  }
23269
23378
  function appendTurnLine(current, promptLabel, currentSummary) {
23270
- const currentLine = currentSummary ? `${promptLabel} ${current} ${chalk61.white("\u2192")} ${currentSummary}` : `${promptLabel} ${current}`;
23271
- console.log(" " + chalk61.dim(currentLine));
23379
+ const currentLine = currentSummary ? `${promptLabel} ${current} ${chalk62.white("\u2192")} ${currentSummary}` : `${promptLabel} ${current}`;
23380
+ console.log(" " + chalk62.dim(currentLine));
23272
23381
  console.log();
23273
23382
  }
23274
23383
  async function goHome(ctx, version, history, opts) {
@@ -23278,7 +23387,7 @@ async function goHome(ctx, version, history, opts) {
23278
23387
  process.stdout.write("\x1B[2J\x1B[H");
23279
23388
  if (opts?.banner) {
23280
23389
  console.log();
23281
- console.log(" " + paint("accent", "\u2713") + " " + chalk61.dim(opts.banner));
23390
+ console.log(" " + paint("accent", "\u2713") + " " + chalk62.dim(opts.banner));
23282
23391
  }
23283
23392
  await printWelcome(ctx, version);
23284
23393
  }
@@ -23301,11 +23410,11 @@ async function handleDispatchResult(result, ctx, version, history) {
23301
23410
  case "unknown":
23302
23411
  if (result.suggestion) {
23303
23412
  console.log(
23304
- " " + chalk61.red(`Unknown command: ${result.token}.`) + chalk61.dim(" Did you mean ") + paint("accent", result.suggestion) + chalk61.dim("?")
23413
+ " " + chalk62.red(`Unknown command: ${result.token}.`) + chalk62.dim(" Did you mean ") + paint("accent", result.suggestion) + chalk62.dim("?")
23305
23414
  );
23306
23415
  } else {
23307
23416
  console.log(
23308
- " " + chalk61.red(`Unknown command: ${result.token}`) + chalk61.dim(" Type ") + paint("accent", "/help") + chalk61.dim(" to see available commands.")
23417
+ " " + chalk62.red(`Unknown command: ${result.token}`) + chalk62.dim(" Type ") + paint("accent", "/help") + chalk62.dim(" to see available commands.")
23309
23418
  );
23310
23419
  }
23311
23420
  break;
@@ -23329,7 +23438,7 @@ async function runRepl(ctx, version) {
23329
23438
  ctx.rl = rl;
23330
23439
  console.log();
23331
23440
  console.log(
23332
- " " + chalk61.dim("What do you want to look at? ") + chalk61.dim('(e.g. "pipeline health", "is NRR real?", "board deck on Q3")')
23441
+ " " + chalk62.dim("What do you want to look at? ") + chalk62.dim('(e.g. "pipeline health", "is NRR real?", "board deck on Q3")')
23333
23442
  );
23334
23443
  console.log();
23335
23444
  if (ctx.pendingUpdateCheck) {
@@ -23359,7 +23468,7 @@ async function runRepl(ctx, version) {
23359
23468
  return;
23360
23469
  }
23361
23470
  sigintPrimed = true;
23362
- console.log("\n " + chalk61.dim("Type /exit to quit, or press Ctrl+C again."));
23471
+ console.log("\n " + chalk62.dim("Type /exit to quit, or press Ctrl+C again."));
23363
23472
  };
23364
23473
  rl.on("SIGINT", sigintHandler);
23365
23474
  function shutdownRepl() {
@@ -23430,7 +23539,7 @@ async function runRepl(ctx, version) {
23430
23539
  }
23431
23540
  }
23432
23541
  } else {
23433
- console.error(" " + chalk61.red("Error: " + String(err.message ?? err)));
23542
+ console.error(" " + chalk62.red("Error: " + String(err.message ?? err)));
23434
23543
  }
23435
23544
  }
23436
23545
  history.push({ input: line, summary });
@@ -23448,7 +23557,7 @@ async function runRepl(ctx, version) {
23448
23557
  } else {
23449
23558
  await closeSession(ctx);
23450
23559
  }
23451
- console.log(" " + chalk61.dim(randomGoodbye()));
23560
+ console.log(" " + chalk62.dim(randomGoodbye()));
23452
23561
  }
23453
23562
  function printHelpOneShot() {
23454
23563
  printHelp();
@@ -23456,10 +23565,10 @@ function printHelpOneShot() {
23456
23565
  function printHelp() {
23457
23566
  console.log();
23458
23567
  console.log(" " + sectionHeading("Conversation"));
23459
- console.log(" " + chalk61.dim("Type what you want to investigate \u2014 no slash needed."));
23460
- console.log(" " + chalk61.dim("Paste a CSV path or say ") + paint("accent", '"use demo data"') + chalk61.dim(" to load data."));
23461
- console.log(" " + chalk61.dim("After analysis, ask questions in plain English."));
23462
- console.log(" " + chalk61.dim("Say ") + paint("accent", '"ship a board deck"') + chalk61.dim(" to draft a handoff prompt."));
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."));
23463
23572
  console.log();
23464
23573
  console.log(" " + sectionHeading("Shortcuts"));
23465
23574
  const shortcuts = [
@@ -23472,7 +23581,7 @@ function printHelp() {
23472
23581
  ];
23473
23582
  const maxW = Math.max(...shortcuts.map(([c]) => c.length)) + 2;
23474
23583
  for (const [cmd, desc] of shortcuts) {
23475
- console.log(` ${paint("accent", padRight(cmd, maxW))} ${chalk61.dim(desc)}`);
23584
+ console.log(` ${paint("accent", padRight(cmd, maxW))} ${chalk62.dim(desc)}`);
23476
23585
  }
23477
23586
  console.log();
23478
23587
  console.log(" " + sectionHeading("Admin"));
@@ -23483,10 +23592,10 @@ function printHelp() {
23483
23592
  ];
23484
23593
  const adminMaxW = Math.max(...admin.map(([c]) => c.length)) + 2;
23485
23594
  for (const [cmd, desc] of admin) {
23486
- console.log(` ${paint("accent", padRight(cmd, adminMaxW))} ${chalk61.dim(desc)}`);
23595
+ console.log(` ${paint("accent", padRight(cmd, adminMaxW))} ${chalk62.dim(desc)}`);
23487
23596
  }
23488
23597
  console.log();
23489
- console.log(" " + chalk61.dim("Power-user commands (") + paint("accent", "/new") + chalk61.dim(", ") + paint("accent", "/diagnose") + chalk61.dim(", ") + paint("accent", "/metrics") + chalk61.dim(") remain available."));
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."));
23490
23599
  console.log();
23491
23600
  }
23492
23601
  var REPL_BUILTINS, ANSI_PATTERN, GOODBYES;
@@ -23560,30 +23669,17 @@ init_global_admin();
23560
23669
  init_repl_globals();
23561
23670
  init_repl();
23562
23671
  init_verify();
23672
+ init_activation();
23673
+ init_gate2();
23563
23674
  init_profile();
23564
23675
  init_theme();
23565
23676
  init_emit();
23566
23677
  init_errors2();
23567
23678
  init_types2();
23568
23679
  init_version();
23569
- import chalk62 from "chalk";
23680
+ import chalk63 from "chalk";
23570
23681
  var VERSION = getInstalledVersion();
23571
- var UNGATED = /* @__PURE__ */ new Set([
23572
- "activate",
23573
- "config",
23574
- "profile",
23575
- "onboard",
23576
- "setup",
23577
- "help",
23578
- "home",
23579
- "exit",
23580
- "quit",
23581
- "clear",
23582
- "scratch",
23583
- "cleanup",
23584
- "deactivate-demo",
23585
- "update"
23586
- ]);
23682
+ var UNGATED = UNGATED_COMMANDS;
23587
23683
  var DB_COMMANDS = /* @__PURE__ */ new Set(["actions", "ask", "backmeup", "demo", "diagnose", "export", "handoff", "ingest", "metrics", "new", "playbook", "publish", "report", "reset", "segment", "session", "status", "strategy"]);
23588
23684
  function firstToken(input) {
23589
23685
  const trimmed = input.trim();
@@ -23608,7 +23704,7 @@ async function main() {
23608
23704
  quiet: args.globals.quiet
23609
23705
  });
23610
23706
  if (!ctx.execution.color) {
23611
- chalk62.level = 0;
23707
+ chalk63.level = 0;
23612
23708
  }
23613
23709
  if (args.globals.stdin) {
23614
23710
  args.input = (await readStdin()).trim();
@@ -23621,16 +23717,16 @@ async function main() {
23621
23717
  if (isStructuredOutput(ctx.execution)) {
23622
23718
  emitError(cmd || "ntrp", new NtrpError("license_invalid", lic.message, 3 /* Auth */));
23623
23719
  }
23624
- console.error(chalk62.red(`
23720
+ console.error(chalk63.red(`
23625
23721
  ${lic.message}`));
23626
- console.error(chalk62.dim(" Purchase a license at https://ntrp.sonnechasser.com\n"));
23722
+ console.error(chalk63.dim(" Purchase a license at https://ntrp.sonnechasser.com\n"));
23627
23723
  process.exit(1);
23628
23724
  }
23629
23725
  }
23630
23726
  const PROFILE_HINT_SKIP = /* @__PURE__ */ new Set(["onboard", "setup", "config", "activate", "help", "home", "exit", "quit", "clear", "profile"]);
23631
23727
  if (!isProfileConfigured() && !PROFILE_HINT_SKIP.has(cmd) && !ctx.execution.quiet) {
23632
23728
  console.error(
23633
- " " + chalk62.dim("Tip: run ") + paint("accent", "ntrp") + chalk62.dim(" interactively to set up your company profile for richer answers.")
23729
+ " " + chalk63.dim("Tip: run ") + paint("accent", "ntrp") + chalk63.dim(" interactively to set up your company profile for richer answers.")
23634
23730
  );
23635
23731
  }
23636
23732
  const result = await dispatch(args.input, ctx);
@@ -23642,12 +23738,12 @@ async function main() {
23642
23738
  }
23643
23739
  if (result.suggestion) {
23644
23740
  console.error(
23645
- chalk62.red(` Unknown command: ${result.token}.`) + chalk62.dim(" Did you mean ") + paint("accent", result.suggestion) + chalk62.dim("?")
23741
+ chalk63.red(` Unknown command: ${result.token}.`) + chalk63.dim(" Did you mean ") + paint("accent", result.suggestion) + chalk63.dim("?")
23646
23742
  );
23647
23743
  } else {
23648
- console.error(chalk62.red(` Unknown command: ${result.token}`));
23744
+ console.error(chalk63.red(` Unknown command: ${result.token}`));
23649
23745
  }
23650
- console.error(chalk62.dim(" Run 'ntrp' for the interactive prompt."));
23746
+ console.error(chalk63.dim(" Run 'ntrp' for the interactive prompt."));
23651
23747
  process.exit(1);
23652
23748
  break;
23653
23749
  case "help":
@@ -23668,10 +23764,11 @@ async function main() {
23668
23764
  }
23669
23765
  return DB_COMMANDS.has(cmd);
23670
23766
  }
23767
+ const showedActivation = await ensureLicenseActivated(ctx);
23671
23768
  if (!isProfileConfigured()) {
23672
23769
  try {
23673
23770
  const { handler: onboard } = await Promise.resolve().then(() => (init_onboard(), onboard_exports));
23674
- await onboard([], ctx);
23771
+ await onboard(showedActivation ? ["--skip-brand"] : [], ctx);
23675
23772
  } catch (err) {
23676
23773
  if (err instanceof GlobalReplCommandError) {
23677
23774
  if (err.command === "exit") {