@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 +1026 -371
- package/dist/index.js.map +1 -1
- package/dist/investigation/verbosity-cli.js +7 -1
- package/dist/investigation/verbosity-cli.js.map +1 -1
- package/dist/mcp/server.js +145 -7
- package/dist/mcp/server.js.map +1 -1
- package/package.json +1 -1
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
|
|
2454
|
-
const n = Number(
|
|
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:
|
|
5310
|
-
return
|
|
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:
|
|
5314
|
-
return
|
|
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:
|
|
5318
|
-
return
|
|
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
|
|
13976
|
-
if (!
|
|
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
|
|
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
|
|
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 (
|
|
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 (
|
|
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
|
|
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
|
|
19051
|
+
return invalid2("Invalid key format");
|
|
18785
19052
|
}
|
|
18786
19053
|
const parts = key.replace("NTRP-", "").split("-");
|
|
18787
19054
|
if (parts.length !== 3) {
|
|
18788
|
-
return
|
|
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
|
|
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
|
|
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
|
-
|
|
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("
|
|
19231
|
+
console.error(chalk38.dim(" Or type /upgrade for checkout + paste flow.\n"));
|
|
18844
19232
|
process.exit(1);
|
|
18845
19233
|
}
|
|
18846
|
-
|
|
18847
|
-
|
|
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
|
-
|
|
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: () =>
|
|
19605
|
+
handler: () => handler27
|
|
18961
19606
|
});
|
|
18962
|
-
import
|
|
18963
|
-
async function
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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(" " +
|
|
19057
|
-
console.log(" " +
|
|
19058
|
-
console.log(" " +
|
|
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(" " +
|
|
19705
|
+
console.log(" " + chalk42.dim(`Audience: ${ctx.scope.audience}`));
|
|
19061
19706
|
}
|
|
19062
19707
|
if (ctx.scope.time_horizon) {
|
|
19063
|
-
console.log(" " +
|
|
19708
|
+
console.log(" " + chalk42.dim(`Period: ${ctx.scope.time_horizon}`));
|
|
19064
19709
|
}
|
|
19065
19710
|
console.log();
|
|
19066
19711
|
console.log(
|
|
19067
|
-
" " +
|
|
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
|
-
" " +
|
|
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(" " +
|
|
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(" " +
|
|
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(" " +
|
|
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(" " +
|
|
19183
|
-
console.log(" " +
|
|
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(" " +
|
|
19831
|
+
console.log(" " + chalk42.dim(l));
|
|
19187
19832
|
}
|
|
19188
19833
|
if (draft.markdown.split("\n").length > 24) {
|
|
19189
|
-
console.log(" " +
|
|
19834
|
+
console.log(" " + chalk42.dim("\u2026"));
|
|
19190
19835
|
}
|
|
19191
|
-
console.log(" " +
|
|
19836
|
+
console.log(" " + chalk42.dim("\u2500".repeat(56)));
|
|
19192
19837
|
console.log();
|
|
19193
19838
|
if (!ctx.rl) {
|
|
19194
|
-
console.log(" " +
|
|
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(" " +
|
|
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(" " +
|
|
19223
|
-
console.log(" " +
|
|
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(" " +
|
|
19876
|
+
console.log(" " + chalk42.red("AI interpretation needs an LLM API key saved in config."));
|
|
19232
19877
|
console.log(
|
|
19233
|
-
" " +
|
|
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(" " +
|
|
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
|
|
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(" " +
|
|
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(" " +
|
|
20052
|
-
console.log(" " +
|
|
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(" " +
|
|
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(" " +
|
|
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(" " +
|
|
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" ?
|
|
20788
|
+
const color = sev === "critical" ? chalk43.red : sev === "warning" ? chalk43.yellow : chalk43.blue;
|
|
20144
20789
|
console.log();
|
|
20145
|
-
console.log(" " + color(`[${sev}]`) + " " +
|
|
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(" " +
|
|
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: () =>
|
|
20917
|
+
handler: () => handler28
|
|
20273
20918
|
});
|
|
20274
|
-
import
|
|
20275
|
-
async function
|
|
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(" " +
|
|
20927
|
+
console.log(" " + chalk44.dim("Ask a question about your pipeline in plain English."));
|
|
20283
20928
|
console.log(
|
|
20284
|
-
" " +
|
|
20929
|
+
" " + chalk44.dim("Example: ") + paint("accent", "/ask which deals are stuck the longest?")
|
|
20285
20930
|
);
|
|
20286
|
-
console.log(" " +
|
|
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(" " +
|
|
20299
|
-
console.log(" " +
|
|
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: () =>
|
|
20990
|
+
handler: () => handler29
|
|
20346
20991
|
});
|
|
20347
|
-
import
|
|
20992
|
+
import chalk45 from "chalk";
|
|
20348
20993
|
import ora11 from "ora";
|
|
20349
|
-
async function
|
|
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(" " +
|
|
20357
|
-
console.log(" " +
|
|
20358
|
-
console.log(" " +
|
|
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(
|
|
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(
|
|
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: () =>
|
|
21229
|
+
handler: () => handler30
|
|
20585
21230
|
});
|
|
20586
|
-
import
|
|
21231
|
+
import chalk46 from "chalk";
|
|
20587
21232
|
import ora12 from "ora";
|
|
20588
|
-
async function
|
|
21233
|
+
async function handler30(args, ctx) {
|
|
20589
21234
|
const feedbackText = args.join(" ").trim();
|
|
20590
21235
|
if (!feedbackText) {
|
|
20591
21236
|
console.log();
|
|
20592
|
-
console.log(" " +
|
|
21237
|
+
console.log(" " + chalk46.dim("Tell NTRP something it got wrong or doesn't know yet."));
|
|
20593
21238
|
console.log(
|
|
20594
|
-
" " +
|
|
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(" " +
|
|
20603
|
-
console.log(" " +
|
|
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(" " +
|
|
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(" " +
|
|
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: () =>
|
|
21290
|
+
handler: () => handler31
|
|
20646
21291
|
});
|
|
20647
21292
|
import ora13 from "ora";
|
|
20648
|
-
import
|
|
20649
|
-
async function
|
|
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(" " +
|
|
20653
|
-
console.log(" " +
|
|
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(" " +
|
|
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(" " +
|
|
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: () =>
|
|
21365
|
+
handler: () => handler32
|
|
20721
21366
|
});
|
|
20722
|
-
import
|
|
20723
|
-
async function
|
|
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(" " +
|
|
20728
|
-
console.log(" " +
|
|
20729
|
-
console.log(" " +
|
|
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.") + " " +
|
|
20742
|
-
console.log(" " +
|
|
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: () =>
|
|
21402
|
+
handler: () => handler33
|
|
20758
21403
|
});
|
|
20759
|
-
import
|
|
20760
|
-
async function
|
|
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(" " +
|
|
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(" " +
|
|
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" ?
|
|
20788
|
-
console.log(" " +
|
|
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(" " +
|
|
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: () =>
|
|
21504
|
+
handler: () => handler34
|
|
20860
21505
|
});
|
|
20861
|
-
import
|
|
20862
|
-
async function
|
|
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(" " +
|
|
20868
|
-
console.log(" " + paint("accent", "/rate good") +
|
|
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(" " +
|
|
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(" " +
|
|
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.") + " " +
|
|
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.") + " " +
|
|
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: () =>
|
|
21561
|
+
handler: () => handler35
|
|
20917
21562
|
});
|
|
20918
|
-
import
|
|
21563
|
+
import chalk51 from "chalk";
|
|
20919
21564
|
import ora14 from "ora";
|
|
20920
|
-
async function
|
|
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(" " +
|
|
20927
|
-
console.log(" " +
|
|
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(" " +
|
|
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(" " +
|
|
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(" " +
|
|
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
|
-
" " +
|
|
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(" " +
|
|
20963
|
-
for (const f of staged) console.log(" " +
|
|
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(" " +
|
|
20970
|
-
console.log(" " +
|
|
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: () =>
|
|
21631
|
+
handler: () => handler36
|
|
20987
21632
|
});
|
|
20988
|
-
import
|
|
20989
|
-
async function
|
|
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(" " +
|
|
20999
|
-
console.log(" " +
|
|
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(" " +
|
|
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(" " +
|
|
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 ??
|
|
21023
|
-
const exch =
|
|
21024
|
-
console.log(` ${
|
|
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(" " +
|
|
21671
|
+
console.log(" " + chalk52.dim("\u2500".repeat(58)));
|
|
21027
21672
|
console.log(
|
|
21028
|
-
" " +
|
|
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(" " +
|
|
21042
|
-
console.log(" " +
|
|
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(" " +
|
|
21693
|
+
console.log(" " + chalk52.red(`Ambiguous ID "${idArg}" matches ${matches.length} sessions:`));
|
|
21049
21694
|
for (const m of matches) {
|
|
21050
|
-
console.log(" " +
|
|
21695
|
+
console.log(" " + chalk52.dim(` ${m.id}`));
|
|
21051
21696
|
}
|
|
21052
|
-
console.log(" " +
|
|
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(" " +
|
|
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}`)) +
|
|
21712
|
+
console.log(" " + paint("accent", bold(`Session ${session.id}`)) + chalk52.dim(` \xB7 ${dateStr}`));
|
|
21068
21713
|
if (session.summary) {
|
|
21069
|
-
console.log(" " +
|
|
21714
|
+
console.log(" " + chalk52.dim("Summary: ") + session.summary);
|
|
21070
21715
|
}
|
|
21071
|
-
console.log(" " +
|
|
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(" " +
|
|
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(" " +
|
|
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(" " +
|
|
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: () =>
|
|
21753
|
+
handler: () => handler37
|
|
21109
21754
|
});
|
|
21110
|
-
import
|
|
21111
|
-
async function
|
|
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(" " +
|
|
21115
|
-
console.log(" " +
|
|
21116
|
-
console.log(" " +
|
|
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(" " +
|
|
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(" " +
|
|
21137
|
-
console.log(" " +
|
|
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(" " +
|
|
21144
|
-
console.log(" " +
|
|
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(" " +
|
|
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(" " +
|
|
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: () =>
|
|
21836
|
+
handler: () => handler38
|
|
21192
21837
|
});
|
|
21193
|
-
import
|
|
21194
|
-
async function
|
|
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(" " +
|
|
21843
|
+
console.log(" " + chalk54.dim("Session name: ") + paint("accent", ctx.sessionName));
|
|
21199
21844
|
} else {
|
|
21200
|
-
console.log(" " +
|
|
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(" " +
|
|
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(" " +
|
|
21216
|
-
console.log(" " +
|
|
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: () =>
|
|
21884
|
+
handler: () => handler39
|
|
21240
21885
|
});
|
|
21241
21886
|
import { join as join22 } from "path";
|
|
21242
21887
|
import ora15 from "ora";
|
|
21243
|
-
import
|
|
21244
|
-
async function
|
|
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(" " +
|
|
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(" " +
|
|
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(" " +
|
|
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(" " +
|
|
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(" " +
|
|
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(" " +
|
|
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 ??
|
|
21332
|
-
const 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(" " +
|
|
21336
|
-
console.log(" " + paint("accent", "/switch <name>") +
|
|
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: () =>
|
|
21996
|
+
handler: () => handler40
|
|
21352
21997
|
});
|
|
21353
|
-
import
|
|
21354
|
-
async function
|
|
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(" " +
|
|
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 ${
|
|
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 ?
|
|
22043
|
+
" " + paint("success", "\u2713") + ` Auto-failover ${session.autoFailover ? chalk56.bold("on") : chalk56.bold("off")} for this session.`
|
|
21399
22044
|
);
|
|
21400
|
-
if (persist) console.log(" " +
|
|
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(" " +
|
|
21407
|
-
console.log(" " +
|
|
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(" " +
|
|
21416
|
-
console.log(" " +
|
|
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: ${
|
|
21424
|
-
console.log(" " +
|
|
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(" " +
|
|
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(
|
|
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") :
|
|
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(
|
|
22091
|
+
console.log(chalk56.bold(" Active stack"));
|
|
21447
22092
|
console.log(` ${formatActiveStack(ctx)}`);
|
|
21448
22093
|
if (sessionOverride) {
|
|
21449
|
-
console.log(
|
|
22094
|
+
console.log(chalk56.dim(" (session override \u2014 /provider reset to use default)"));
|
|
21450
22095
|
} else {
|
|
21451
|
-
console.log(
|
|
22096
|
+
console.log(chalk56.dim(` (config default: ${cfg.primary})`));
|
|
21452
22097
|
}
|
|
21453
22098
|
console.log();
|
|
21454
|
-
console.log(` Auto-failover: ${autoFailover ? paint("success", "on") :
|
|
21455
|
-
console.log(
|
|
21456
|
-
console.log(
|
|
21457
|
-
console.log(
|
|
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: () =>
|
|
22122
|
+
handler: () => handler41
|
|
21478
22123
|
});
|
|
21479
|
-
import
|
|
21480
|
-
async function
|
|
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(" " +
|
|
21490
|
-
console.log(" " +
|
|
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 ${
|
|
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(" " +
|
|
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(
|
|
22159
|
+
console.log(chalk57.bold(" Inference settings"));
|
|
21515
22160
|
console.log(` Active: ${paint("accent", formatActiveStack(ctx))}`);
|
|
21516
22161
|
if (sessionTier) {
|
|
21517
|
-
console.log(
|
|
22162
|
+
console.log(chalk57.dim(" (session tier override)"));
|
|
21518
22163
|
} else {
|
|
21519
|
-
console.log(
|
|
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(
|
|
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" ? "" :
|
|
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(
|
|
21536
|
-
console.log(
|
|
21537
|
-
console.log(
|
|
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: () =>
|
|
22203
|
+
handler: () => handler42
|
|
21559
22204
|
});
|
|
21560
|
-
import
|
|
21561
|
-
async function
|
|
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(" " +
|
|
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(" " +
|
|
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(" " +
|
|
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(" " +
|
|
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: ${
|
|
22250
|
+
" " + paint("success", "\u2713") + ` Model: ${chalk58.bold(modelId)}` + (persist ? chalk58.dim(" (saved as default)") : chalk58.dim(" (this session)"))
|
|
21606
22251
|
);
|
|
21607
|
-
console.log(" " +
|
|
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(
|
|
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(" " +
|
|
22265
|
+
console.log(" " + chalk58.dim("No override \u2014 tier defaults apply."));
|
|
21621
22266
|
}
|
|
21622
22267
|
console.log(` Active stack: ${formatActiveStack(ctx)}`);
|
|
21623
|
-
console.log(
|
|
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: () =>
|
|
22443
|
+
handler: () => handler43
|
|
21799
22444
|
});
|
|
21800
22445
|
import { spawnSync } from "child_process";
|
|
21801
|
-
import
|
|
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
|
|
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(
|
|
21823
|
-
console.log(
|
|
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(
|
|
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(
|
|
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(
|
|
21845
|
-
console.log(
|
|
21846
|
-
console.log(
|
|
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(
|
|
22496
|
+
console.log(chalk59.red(` Could not install ${NPM_PACKAGE}.`));
|
|
21852
22497
|
if (detail) {
|
|
21853
|
-
console.log(
|
|
22498
|
+
console.log(chalk59.dim(` ${detail.split("\n").join("\n ")}`));
|
|
21854
22499
|
}
|
|
21855
|
-
console.log(
|
|
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
|
|
21959
|
-
if (typeof
|
|
21960
|
-
entry.handler =
|
|
21961
|
-
return
|
|
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
|
|
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(
|
|
22688
|
-
console.error(
|
|
22689
|
-
console.error(
|
|
22690
|
-
console.error(
|
|
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
|
-
|
|
22701
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
" " +
|
|
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(" " +
|
|
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
|
|
23506
|
+
import chalk62 from "chalk";
|
|
22855
23507
|
function printLicenseRequired(command) {
|
|
22856
|
-
|
|
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
|
-
" " +
|
|
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
|
-
" " +
|
|
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
|
-
" " +
|
|
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
|
|
22957
|
-
if (!
|
|
22958
|
-
console.error(
|
|
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
|
|
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
|
-
|
|
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
|
|
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 ?
|
|
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 ?
|
|
23030
|
-
const meta = `${formatSessionId(s.id, s.name)} ${
|
|
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 =
|
|
23037
|
-
const current = opts?.markCurrent && s.id === ctx?.sessionId ?
|
|
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 =
|
|
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} ${
|
|
23725
|
+
lines.push(`${label} ${state} ${chalk63.dim(truncateVisible(item.detail, detailW))}`);
|
|
23078
23726
|
}
|
|
23079
23727
|
if (recent) {
|
|
23080
|
-
lines.push(`${
|
|
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)} ${
|
|
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(` ${
|
|
23748
|
+
lines.push(` ${chalk63.dim("(none yet)")}`);
|
|
23101
23749
|
lines.push(
|
|
23102
23750
|
truncateVisible(
|
|
23103
|
-
` ${nextAction.command ? actionHint(nextAction.label, nextAction.command, 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
|
-
` ${
|
|
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(` ${
|
|
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(` ${
|
|
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(` ${
|
|
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) =>
|
|
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 ?
|
|
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 +
|
|
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)}`) +
|
|
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
|
|
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 ?
|
|
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} ${
|
|
23380
|
-
console.log(" " +
|
|
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") + " " +
|
|
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
|
-
" " +
|
|
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
|
-
" " +
|
|
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
|
-
" " +
|
|
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 " +
|
|
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(" " +
|
|
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(" " +
|
|
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(" " +
|
|
23569
|
-
console.log(" " +
|
|
23570
|
-
console.log(" " +
|
|
23571
|
-
console.log(" " +
|
|
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))} ${
|
|
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))} ${
|
|
24245
|
+
console.log(` ${paint("accent", padRight(cmd, adminMaxW))} ${chalk64.dim(desc)}`);
|
|
23596
24246
|
}
|
|
23597
24247
|
console.log();
|
|
23598
|
-
console.log(" " +
|
|
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
|
|
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
|
-
|
|
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
|
|
23716
|
-
if (!
|
|
24365
|
+
const lic2 = await refreshLicenseOnline();
|
|
24366
|
+
if (!lic2.valid) {
|
|
23717
24367
|
if (isStructuredOutput(ctx.execution)) {
|
|
23718
|
-
emitError(cmd || "ntrp", new NtrpError("license_invalid",
|
|
24368
|
+
emitError(cmd || "ntrp", new NtrpError("license_invalid", lic2.message, 3 /* Auth */));
|
|
23719
24369
|
}
|
|
23720
|
-
console.error(
|
|
23721
|
-
${
|
|
23722
|
-
console.error(
|
|
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
|
-
" " +
|
|
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
|
-
|
|
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(
|
|
24394
|
+
console.error(chalk65.red(` Unknown command: ${result.token}`));
|
|
23745
24395
|
}
|
|
23746
|
-
console.error(
|
|
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));
|