@sonnechasser/ntrp 2.1.10 → 2.1.12
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 +338 -174
- package/dist/mcp/server.js +251 -139
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1719,8 +1719,10 @@ var init_prefs = __esm({
|
|
|
1719
1719
|
// src/voice/copy.ts
|
|
1720
1720
|
var copy_exports = {};
|
|
1721
1721
|
__export(copy_exports, {
|
|
1722
|
+
EXPORT_PICKUP_PHRASE: () => EXPORT_PICKUP_PHRASE,
|
|
1722
1723
|
voiceAuthFailureAlert: () => voiceAuthFailureAlert,
|
|
1723
1724
|
voiceAuthFailureHint: () => voiceAuthFailureHint,
|
|
1725
|
+
voiceExportPickupNudge: () => voiceExportPickupNudge,
|
|
1724
1726
|
voiceGapLoadCta: () => voiceGapLoadCta,
|
|
1725
1727
|
voiceGapReadyCta: () => voiceGapReadyCta,
|
|
1726
1728
|
voiceHandoffAddendum: () => voiceHandoffAddendum,
|
|
@@ -1873,6 +1875,34 @@ function voiceHealthGloss(status, prefs) {
|
|
|
1873
1875
|
}
|
|
1874
1876
|
});
|
|
1875
1877
|
}
|
|
1878
|
+
function voiceExportPickupNudge(input, prefs) {
|
|
1879
|
+
const v = voice(prefs);
|
|
1880
|
+
const phrase = EXPORT_PICKUP_PHRASE;
|
|
1881
|
+
if (input.inboxReady) {
|
|
1882
|
+
return pick(v, {
|
|
1883
|
+
robotic: `Open your desktop AI. Tell it to ${phrase}.`,
|
|
1884
|
+
composed: `Open your desktop AI and tell it to ${phrase}.`,
|
|
1885
|
+
casual: `This terminal is not your AI. Open it and tell it to ${phrase}.`,
|
|
1886
|
+
loose: {
|
|
1887
|
+
light: `Written. Open your desktop AI and tell it to ${phrase}.`,
|
|
1888
|
+
medium: `This CLI cannot see your AI. Open it. Tell it to ${phrase}.`,
|
|
1889
|
+
dark: `The file is on disk. Your AI is not in this window. Open it and ${phrase}.`,
|
|
1890
|
+
heavy: `NTRP wrote it. This window is not your AI. Open the desktop app and ${phrase}.`
|
|
1891
|
+
}
|
|
1892
|
+
});
|
|
1893
|
+
}
|
|
1894
|
+
return pick(v, {
|
|
1895
|
+
robotic: `Your desktop AI cannot see this folder. Type /inbox set, then tell that AI to ${phrase}.`,
|
|
1896
|
+
composed: `These files are on disk. Set a pickup folder (/inbox set), then tell your desktop AI to ${phrase}.`,
|
|
1897
|
+
casual: `Your AI cannot see this folder. Type /inbox set, then tell it to ${phrase}.`,
|
|
1898
|
+
loose: {
|
|
1899
|
+
light: `Your AI cannot see this folder yet. Type /inbox set, then tell it to ${phrase}.`,
|
|
1900
|
+
medium: `This folder is invisible to your AI. Type /inbox set, then tell it to ${phrase}.`,
|
|
1901
|
+
dark: `Your AI cannot see this terminal. Type /inbox set, then ${phrase}.`,
|
|
1902
|
+
heavy: `This window is not your AI. Type /inbox set, then ${phrase}.`
|
|
1903
|
+
}
|
|
1904
|
+
});
|
|
1905
|
+
}
|
|
1876
1906
|
function voiceHandoffAddendum(prefs) {
|
|
1877
1907
|
const v = voice(prefs);
|
|
1878
1908
|
return [
|
|
@@ -1887,11 +1917,13 @@ function pick(prefs, map) {
|
|
|
1887
1917
|
if (typeof entry === "string") return entry;
|
|
1888
1918
|
return entry[prefs.roast];
|
|
1889
1919
|
}
|
|
1920
|
+
var EXPORT_PICKUP_PHRASE;
|
|
1890
1921
|
var init_copy = __esm({
|
|
1891
1922
|
"src/voice/copy.ts"() {
|
|
1892
1923
|
"use strict";
|
|
1893
1924
|
init_catalog();
|
|
1894
1925
|
init_prefs();
|
|
1926
|
+
EXPORT_PICKUP_PHRASE = "pick up the latest NTRP handoff";
|
|
1895
1927
|
}
|
|
1896
1928
|
});
|
|
1897
1929
|
|
|
@@ -2244,8 +2276,10 @@ var init_verbosity = __esm({
|
|
|
2244
2276
|
// src/trace/result-block.ts
|
|
2245
2277
|
var result_block_exports = {};
|
|
2246
2278
|
__export(result_block_exports, {
|
|
2279
|
+
VITAL_PROBLEM_READ: () => VITAL_PROBLEM_READ,
|
|
2247
2280
|
buildVitalHeadlines: () => buildVitalHeadlines,
|
|
2248
2281
|
formatDuration: () => formatDuration,
|
|
2282
|
+
formatVitalCall: () => formatVitalCall,
|
|
2249
2283
|
headlinesFromFindingCards: () => headlinesFromFindingCards,
|
|
2250
2284
|
printArtifactLine: () => printArtifactLine,
|
|
2251
2285
|
printMetricsResultBlock: () => printMetricsResultBlock,
|
|
@@ -2269,12 +2303,32 @@ function flagLabel(vitals, status) {
|
|
|
2269
2303
|
function deltaCell(delta) {
|
|
2270
2304
|
if (!delta) return " ";
|
|
2271
2305
|
const rounded = Math.round(delta.delta);
|
|
2272
|
-
if (rounded === 0) return
|
|
2306
|
+
if (rounded === 0) return " ";
|
|
2273
2307
|
if (rounded < 0) {
|
|
2274
2308
|
return paint("error", `\u25BC ${String(Math.abs(rounded)).padStart(2)} `);
|
|
2275
2309
|
}
|
|
2276
2310
|
return paint("success", `\u25B2 ${String(rounded).padStart(2)} `);
|
|
2277
2311
|
}
|
|
2312
|
+
function otherRedLabels(health) {
|
|
2313
|
+
return health.vital_signs.filter((v) => v.status === "red" && v.vital_sign !== health.gating_vital_sign).map((v) => VITAL_SIGN_LABELS[v.vital_sign]);
|
|
2314
|
+
}
|
|
2315
|
+
function formatVitalCall(health) {
|
|
2316
|
+
const gateName = VITAL_SIGN_LABELS[health.gating_vital_sign];
|
|
2317
|
+
const gating = health.vital_signs.find((v) => v.vital_sign === health.gating_vital_sign);
|
|
2318
|
+
const read = VITAL_PROBLEM_READ[health.gating_vital_sign];
|
|
2319
|
+
const alsoRed = otherRedLabels(health);
|
|
2320
|
+
const dollars = health.total_value_at_risk;
|
|
2321
|
+
const head = dollars != null && dollars > 0 ? `${formatCurrency(dollars)} at risk.` : "No dollar-weighted risk.";
|
|
2322
|
+
let start = `Start with ${gateName}`;
|
|
2323
|
+
if (gating && gating.dollar_value != null && gating.dollar_value > 0) {
|
|
2324
|
+
start += `: ${formatCurrency(gating.dollar_value)} ${read}`;
|
|
2325
|
+
}
|
|
2326
|
+
start += ".";
|
|
2327
|
+
if (alsoRed.length > 0) {
|
|
2328
|
+
start += ` Also red: ${alsoRed.join(", ")}.`;
|
|
2329
|
+
}
|
|
2330
|
+
return `${head} ${start}`;
|
|
2331
|
+
}
|
|
2278
2332
|
function printVitalResultBlock(health, opts = {}) {
|
|
2279
2333
|
const vitals = health.vital_signs;
|
|
2280
2334
|
const deltaBySign = new Map((opts.deltas ?? []).map((d) => [d.vital_sign, d]));
|
|
@@ -2291,18 +2345,25 @@ function printVitalResultBlock(health, opts = {}) {
|
|
|
2291
2345
|
console.log(` ${dot} ${label} ${score} ${delta} ${flag}`.trimEnd());
|
|
2292
2346
|
}
|
|
2293
2347
|
console.log();
|
|
2348
|
+
printVitalCall(health);
|
|
2349
|
+
printFindingsList(opts.findings ?? []);
|
|
2350
|
+
}
|
|
2351
|
+
function printVitalCall(health) {
|
|
2352
|
+
const gateName = VITAL_SIGN_LABELS[health.gating_vital_sign];
|
|
2353
|
+
const gating = health.vital_signs.find((v) => v.vital_sign === health.gating_vital_sign);
|
|
2354
|
+
const read = VITAL_PROBLEM_READ[health.gating_vital_sign];
|
|
2355
|
+
const alsoRed = otherRedLabels(health);
|
|
2294
2356
|
const dollars = health.total_value_at_risk;
|
|
2295
|
-
const
|
|
2296
|
-
|
|
2297
|
-
if (
|
|
2298
|
-
|
|
2299
|
-
console.log(
|
|
2300
|
-
` ${paint("success", formatCurrency(dollars))} ${chalk5.dim("at risk")} ${chalk5.dim("\u2014")} ${chalk5.dim("held back by")} ${paint("accent", gating)}${chalk5.dim(why)}`
|
|
2301
|
-
);
|
|
2302
|
-
} else {
|
|
2303
|
-
console.log(` ${chalk5.dim("No dollar-weighted risk detected")} ${chalk5.dim("\u2014")} ${chalk5.dim("held back by")} ${paint("accent", gating)}`);
|
|
2357
|
+
const head = dollars != null && dollars > 0 ? `${paint("success", formatCurrency(dollars))} at risk.` : "No dollar-weighted risk.";
|
|
2358
|
+
let start = `Start with ${paint("accent", gateName)}`;
|
|
2359
|
+
if (gating && gating.dollar_value != null && gating.dollar_value > 0) {
|
|
2360
|
+
start += `: ${formatCurrency(gating.dollar_value)} ${read}`;
|
|
2304
2361
|
}
|
|
2305
|
-
|
|
2362
|
+
start += ".";
|
|
2363
|
+
if (alsoRed.length > 0) {
|
|
2364
|
+
start += ` Also red: ${alsoRed.join(", ")}.`;
|
|
2365
|
+
}
|
|
2366
|
+
console.log(` ${head} ${start}`);
|
|
2306
2367
|
}
|
|
2307
2368
|
function printMetricsResultBlock(metrics, opts = {}) {
|
|
2308
2369
|
const flagged = metrics.filter((m) => !m.unavailable_reason && (m.status === "red" || m.status === "yellow"));
|
|
@@ -2327,53 +2388,54 @@ function printMetricsResultBlock(metrics, opts = {}) {
|
|
|
2327
2388
|
function printFindingsList(findings) {
|
|
2328
2389
|
if (findings.length === 0) return;
|
|
2329
2390
|
console.log();
|
|
2330
|
-
console.log(` ${chalk5.bold("Findings")}`);
|
|
2331
2391
|
findings.slice(0, 3).forEach((f, i) => {
|
|
2332
2392
|
console.log(` ${chalk5.dim(`${i + 1}.`)} ${f.text}`);
|
|
2333
2393
|
});
|
|
2334
2394
|
}
|
|
2335
2395
|
function printArtifactLine(path, description) {
|
|
2336
2396
|
console.log();
|
|
2337
|
-
const label = description?.trim() || "
|
|
2338
|
-
console.log(` ${chalk5.dim(label)} ${chalk5.dim("\u2192")} ${path}`);
|
|
2339
|
-
console.log(` ${chalk5.dim("Run with --verbose for per-vital detail.")}`);
|
|
2397
|
+
const label = description?.trim() || "Saved report";
|
|
2398
|
+
console.log(` ${chalk5.dim(label)} ${chalk5.dim("\u2192")} ${chalk5.dim(path)}`);
|
|
2340
2399
|
console.log();
|
|
2341
2400
|
}
|
|
2401
|
+
function problemPhrase(vs, who) {
|
|
2402
|
+
const read = VITAL_PROBLEM_READ[vs.vital_sign];
|
|
2403
|
+
const dollars = vs.dollar_value != null && vs.dollar_value > 0 ? formatCurrency(vs.dollar_value) : null;
|
|
2404
|
+
const prefix = who || VITAL_SIGN_LABELS[vs.vital_sign];
|
|
2405
|
+
if (dollars) return `${prefix}: ${dollars} ${read}`;
|
|
2406
|
+
return `${prefix}: ${VITAL_SIGN_LABELS[vs.vital_sign]} ${Math.round(vs.score)}`;
|
|
2407
|
+
}
|
|
2342
2408
|
function buildVitalHeadlines(health, segments = []) {
|
|
2343
|
-
const findings = [];
|
|
2344
|
-
const gating = health.vital_signs.find((v) => v.vital_sign === health.gating_vital_sign);
|
|
2345
|
-
if (gating) {
|
|
2346
|
-
const label = VITAL_SIGN_LABELS[gating.vital_sign];
|
|
2347
|
-
const dollars = gating.dollar_value != null && gating.dollar_value > 0 ? ` \u2014 ${formatCurrency(gating.dollar_value)} ${gating.dollar_label ?? ""}`.trimEnd() : "";
|
|
2348
|
-
const severity = gating.status === "red" ? "critical" : gating.status === "yellow" ? "warn" : "info";
|
|
2349
|
-
findings.push({
|
|
2350
|
-
severity,
|
|
2351
|
-
text: `${label} ${Math.round(gating.score)}${dollars}`
|
|
2352
|
-
});
|
|
2353
|
-
}
|
|
2354
2409
|
const extras = [];
|
|
2355
|
-
const
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
for (const { vs, segment } of sourceVitals) {
|
|
2359
|
-
if (vs.status === "green") continue;
|
|
2360
|
-
if (vs.vital_sign === health.gating_vital_sign && !segment) continue;
|
|
2361
|
-
if (vs.dollar_value == null || vs.dollar_value <= 0) continue;
|
|
2362
|
-
const label = VITAL_SIGN_LABELS[vs.vital_sign];
|
|
2363
|
-
const who = segment ? `${segment}: ` : "";
|
|
2410
|
+
const push = (vs, who) => {
|
|
2411
|
+
if (vs.status === "green") return;
|
|
2412
|
+
if (vs.dollar_value == null || vs.dollar_value <= 0) return;
|
|
2364
2413
|
extras.push({
|
|
2365
2414
|
severity: vs.status === "red" ? "critical" : "warn",
|
|
2366
|
-
text:
|
|
2415
|
+
text: problemPhrase(vs, who),
|
|
2367
2416
|
dollars: vs.dollar_value
|
|
2368
2417
|
});
|
|
2418
|
+
};
|
|
2419
|
+
if (segments.length > 0) {
|
|
2420
|
+
for (const s of segments) {
|
|
2421
|
+
for (const vs of s.result.vital_signs) {
|
|
2422
|
+
push(vs, s.segment.name);
|
|
2423
|
+
}
|
|
2424
|
+
}
|
|
2425
|
+
} else {
|
|
2426
|
+
for (const vs of health.vital_signs) {
|
|
2427
|
+
if (vs.vital_sign === health.gating_vital_sign) continue;
|
|
2428
|
+
push(vs);
|
|
2429
|
+
}
|
|
2369
2430
|
}
|
|
2370
2431
|
extras.sort((a, b) => b.dollars - a.dollars);
|
|
2432
|
+
const findings = [];
|
|
2371
2433
|
for (const extra of extras) {
|
|
2372
2434
|
if (findings.length >= 3) break;
|
|
2373
2435
|
if (findings.some((f) => f.text === extra.text)) continue;
|
|
2374
2436
|
findings.push({ severity: extra.severity, text: extra.text });
|
|
2375
2437
|
}
|
|
2376
|
-
return findings
|
|
2438
|
+
return findings;
|
|
2377
2439
|
}
|
|
2378
2440
|
function headlinesFromFindingCards(cards) {
|
|
2379
2441
|
return cards.slice(0, 3).map((card) => ({
|
|
@@ -2381,11 +2443,19 @@ function headlinesFromFindingCards(cards) {
|
|
|
2381
2443
|
text: stripFindingMarkdown(card.finding)
|
|
2382
2444
|
}));
|
|
2383
2445
|
}
|
|
2446
|
+
var VITAL_PROBLEM_READ;
|
|
2384
2447
|
var init_result_block = __esm({
|
|
2385
2448
|
"src/trace/result-block.ts"() {
|
|
2386
2449
|
"use strict";
|
|
2387
2450
|
init_formatters();
|
|
2388
2451
|
init_theme();
|
|
2452
|
+
VITAL_PROBLEM_READ = {
|
|
2453
|
+
freshness: "stale",
|
|
2454
|
+
flow_rate: "stuck",
|
|
2455
|
+
drop_rate: "lost at handoff",
|
|
2456
|
+
signal_to_noise: "misdirected effort",
|
|
2457
|
+
thread_depth: "single-threaded"
|
|
2458
|
+
};
|
|
2389
2459
|
}
|
|
2390
2460
|
});
|
|
2391
2461
|
|
|
@@ -2480,11 +2550,10 @@ var init_renderer = __esm({
|
|
|
2480
2550
|
}
|
|
2481
2551
|
const line = `${summary} \xB7 ${formatDuration(durationMs)}`;
|
|
2482
2552
|
if (this.useSpinner() && this.spinner) {
|
|
2483
|
-
this.spinner.
|
|
2553
|
+
this.spinner.stop();
|
|
2484
2554
|
this.spinner = null;
|
|
2485
|
-
return;
|
|
2486
2555
|
}
|
|
2487
|
-
console.log(` ${chalk6.green("\u2713")} ${line}`);
|
|
2556
|
+
console.log(` ${chalk6.green("\u2713")} ${chalk6.dim(line)}`);
|
|
2488
2557
|
}
|
|
2489
2558
|
persistDim(message) {
|
|
2490
2559
|
const spinning = this.spinner?.isSpinning;
|
|
@@ -2888,6 +2957,7 @@ __export(handoff_skill_exports, {
|
|
|
2888
2957
|
persistHandoffSkillFiles: () => persistHandoffSkillFiles,
|
|
2889
2958
|
persistStandingSkill: () => persistStandingSkill,
|
|
2890
2959
|
pickupContextFromEvent: () => pickupContextFromEvent,
|
|
2960
|
+
printExportPickupNudge: () => printExportPickupNudge,
|
|
2891
2961
|
printHandoffDelivered: () => printHandoffDelivered,
|
|
2892
2962
|
printStandingSkill: () => printStandingSkill
|
|
2893
2963
|
});
|
|
@@ -3126,11 +3196,14 @@ function maybePrintAiInboxNudge() {
|
|
|
3126
3196
|
)
|
|
3127
3197
|
);
|
|
3128
3198
|
}
|
|
3199
|
+
function printExportPickupNudge(opts) {
|
|
3200
|
+
console.log(" " + chalk7.dim(voiceExportPickupNudge(opts)));
|
|
3201
|
+
}
|
|
3129
3202
|
function printHandoffDelivered(event, opts = {}) {
|
|
3130
3203
|
persistHandoffSkillFiles(event);
|
|
3131
3204
|
console.log();
|
|
3132
3205
|
console.log(" " + paint("accent", `Handoff ready (${kindLabel(event.kind)})`));
|
|
3133
|
-
|
|
3206
|
+
printExportPickupNudge({ inboxReady: Boolean(event.inbox_path) });
|
|
3134
3207
|
if (opts.body) {
|
|
3135
3208
|
console.log(" " + chalk7.dim("File body (--print)"));
|
|
3136
3209
|
printPlainBlock(opts.body);
|
|
@@ -3162,6 +3235,7 @@ var init_handoff_skill = __esm({
|
|
|
3162
3235
|
init_store();
|
|
3163
3236
|
init_theme();
|
|
3164
3237
|
init_export_kinds();
|
|
3238
|
+
init_copy();
|
|
3165
3239
|
STANDING_SKILL_NAME = "SKILL.md";
|
|
3166
3240
|
ARCHIVE_PICKUP_NAME = "pickup.md";
|
|
3167
3241
|
INBOX_PICKUP_NAME = "latest-pickup.md";
|
|
@@ -10686,7 +10760,7 @@ ${strategy.objective}
|
|
|
10686
10760
|
` : "";
|
|
10687
10761
|
const workstreamSection = strategy.workstreams.length > 0 ? `
|
|
10688
10762
|
## Workstreams
|
|
10689
|
-
${strategy.workstreams.map(
|
|
10763
|
+
${strategy.workstreams.map(formatWorkstreamMarkdown).join("\n")}
|
|
10690
10764
|
` : "";
|
|
10691
10765
|
const constraintsSection = filterOperatorLines(strategy.constraints).length > 0 ? `
|
|
10692
10766
|
## Constraints
|
|
@@ -10742,7 +10816,7 @@ ${strategy.objective}
|
|
|
10742
10816
|
` : "";
|
|
10743
10817
|
const workstreamSection = strategy.workstreams.length > 0 ? `
|
|
10744
10818
|
## Workstreams
|
|
10745
|
-
${strategy.workstreams.map(
|
|
10819
|
+
${strategy.workstreams.map(formatWorkstreamMarkdown).join("\n")}
|
|
10746
10820
|
` : "";
|
|
10747
10821
|
const assumptions = filterOperatorLines(strategy.assumptions);
|
|
10748
10822
|
const assumptionsSection = assumptions.length > 0 ? `
|
|
@@ -10789,7 +10863,7 @@ ${frontmatter}
|
|
|
10789
10863
|
].filter((p) => p != null && String(p).length > 0);
|
|
10790
10864
|
return parts.join("\n\n") + "\n";
|
|
10791
10865
|
}
|
|
10792
|
-
function
|
|
10866
|
+
function formatWorkstreamMarkdown(ws) {
|
|
10793
10867
|
const lines = [];
|
|
10794
10868
|
lines.push(`### ${ws.order}. ${ws.title}`);
|
|
10795
10869
|
lines.push(`- Problem: ${ws.problem}`);
|
|
@@ -12152,6 +12226,7 @@ function resetContextForSwitch(ctx, opts) {
|
|
|
12152
12226
|
ctx.thinkState = opts.thinkState;
|
|
12153
12227
|
ctx.pendingAsk = opts.pendingAsk;
|
|
12154
12228
|
ctx.lastCraftJobId = opts.lastCraftJobId;
|
|
12229
|
+
ctx.lastStrategyBrief = void 0;
|
|
12155
12230
|
ctx.gapAudit = void 0;
|
|
12156
12231
|
ctx.deliverIntent = false;
|
|
12157
12232
|
ctx.computeInProgress = false;
|
|
@@ -14827,6 +14902,8 @@ var init_guide_slides = __esm({
|
|
|
14827
14902
|
"",
|
|
14828
14903
|
"Hit Enter by accident on \u23CE yes? Type b or back \u2014 that rewinds to the focus card. The same word leaves a strategy or think overlay. It does not unload demo data or undo compute; /scratch or a new session is the blunt reset.",
|
|
14829
14904
|
"",
|
|
14905
|
+
"After a strategy brief, the terminal shows the call, the exams, the next date, and what ships. Type more or expand for the full plan. The library and handoff files already hold every step.",
|
|
14906
|
+
"",
|
|
14830
14907
|
"Empty dataset? Load a sample with \u23CE use demo data, paste a CSV path, or /ingest. When the gap card says the formulas can compute, \u23CE go ahead runs the local math.",
|
|
14831
14908
|
"",
|
|
14832
14909
|
"Vital signs and SaaS metrics compute without an AI key. Every score that has a dollar translation shows it \u2014 that's the point of the stethoscope."
|
|
@@ -14835,7 +14912,7 @@ var init_guide_slides = __esm({
|
|
|
14835
14912
|
"Power-user slash commands still work. They stay hidden from /help: /new, /diagnose, /metrics, /ingest, /session.",
|
|
14836
14913
|
'"use demo data" loads a fitted sample book. Company profile is optional. In scripts, /demo --no-profile.',
|
|
14837
14914
|
'After compute, the prompt returns to \u203A. Brief is the default depth; type "go deep" for the long read.',
|
|
14838
|
-
"/home shows phase status. /help lists conversation shortcuts and the Keys legend (\u23CE, b/back, cancel)."
|
|
14915
|
+
"/home shows phase status. /help lists conversation shortcuts and the Keys legend (\u23CE, b/back, more/expand, cancel)."
|
|
14839
14916
|
]
|
|
14840
14917
|
};
|
|
14841
14918
|
ASK = {
|
|
@@ -14881,7 +14958,7 @@ var init_guide_slides = __esm({
|
|
|
14881
14958
|
lines: [
|
|
14882
14959
|
'We think of handoff as a quiet bridge: NTRP writes a board deck or brief into a folder you choose; your desktop AI (Claude, ChatGPT, Cursor, \u2026) opens it. You teach that AI a standing finder once \u2014 then later you just say "pick up the latest NTRP handoff."',
|
|
14883
14960
|
"",
|
|
14884
|
-
'"ship a board deck" or /handoff lands files in ~/Documents/ntrp-inbox by default (/inbox set to change). During demo or company setup \u2014 or anytime \u2014 /inbox skill prints the finder to paste once. After that, each
|
|
14961
|
+
'"ship a board deck" or /handoff lands files in ~/Documents/ntrp-inbox by default (/inbox set to change). During demo or company setup \u2014 or anytime \u2014 /inbox skill prints the finder to paste once. After that, each write prints "Handoff ready" without a paste block, then tells you to leave this terminal and pick up the latest NTRP handoff in your desktop AI.',
|
|
14885
14962
|
"",
|
|
14886
14963
|
"Skipped earlier? We ask once when you load your own data. Or /inbox set ~/Documents/ntrp-inbox, then /inbox skill. /handoff skill reprints the same finder."
|
|
14887
14964
|
],
|
|
@@ -14911,6 +14988,8 @@ var init_guide_slides = __esm({
|
|
|
14911
14988
|
"",
|
|
14912
14989
|
"At the confirm card, \u23CE yes builds that plan once. Type keep going to keep working until the plan is ready \u2014 the same armed-Enter pattern as use demo data and go ahead. If you see Best so far, the prompt returns to \u203A and \u23CE keep going continues. Plan ready? Type /strategy review later to check milestones against new vitals.",
|
|
14913
14990
|
"",
|
|
14991
|
+
"The printed brief is short on purpose: the call, the exams, the next date, and what ships. Type more (or expand) for the full plan. The library and handoff files already hold every step.",
|
|
14992
|
+
"",
|
|
14914
14993
|
"When a vital is red, /playbook names a matching play \u2014 and outcomes from reviews annotate the catalog with what actually hit here. /remember stores a durable fact; /rate bad <reason> writes a calibration. Optional ~/.ntrp/ANALYST.md is standing voice and priorities (it never overrides safety rules).",
|
|
14915
14994
|
"",
|
|
14916
14995
|
"Handy later: /sessions show, /session <id> pickup, /end (transcript + brief), /home, /progress, /help."
|
|
@@ -30500,20 +30579,7 @@ function renderCraftHandoffMarkdown(opts) {
|
|
|
30500
30579
|
lines.push("## Workstreams");
|
|
30501
30580
|
lines.push("");
|
|
30502
30581
|
for (const ws of plan.workstreams) {
|
|
30503
|
-
lines.push(
|
|
30504
|
-
lines.push("");
|
|
30505
|
-
lines.push(`- Problem: ${ws.problem}`);
|
|
30506
|
-
if (ws.rationale && !isGenericWorkstreamRationale(ws.rationale)) {
|
|
30507
|
-
lines.push(`- Why this order: ${ws.rationale}`);
|
|
30508
|
-
}
|
|
30509
|
-
if (ws.actions[0]) lines.push(`- First action (48h): ${ws.actions[0]}`);
|
|
30510
|
-
lines.push(`- Effort: ~${Math.round(ws.effort_hours)} team-hours`);
|
|
30511
|
-
lines.push(
|
|
30512
|
-
`- Exam: ${ws.expected_outcome.metric} ${ws.expected_outcome.baseline} \u2192 ${ws.expected_outcome.target_range} by ${ws.expected_outcome.check_date} (${ws.expected_outcome.measured_by})`
|
|
30513
|
-
);
|
|
30514
|
-
lines.push(
|
|
30515
|
-
`- Contingency: if ${ws.contingency.trigger} (check ${ws.contingency.trigger_check_date}) \u2192 ${ws.contingency.fallback}`
|
|
30516
|
-
);
|
|
30582
|
+
lines.push(formatWorkstreamMarkdown(ws).trimEnd());
|
|
30517
30583
|
lines.push("");
|
|
30518
30584
|
}
|
|
30519
30585
|
if (opts.roundtableDigest) {
|
|
@@ -30793,93 +30859,183 @@ var init_llm_attribution = __esm({
|
|
|
30793
30859
|
|
|
30794
30860
|
// src/output/strategy-brief.ts
|
|
30795
30861
|
import chalk24 from "chalk";
|
|
30796
|
-
function
|
|
30862
|
+
function collectWrapped(lines, text, width, prefix = INDENT, style) {
|
|
30797
30863
|
for (const line of wrapWords(text, width)) {
|
|
30798
|
-
|
|
30864
|
+
lines.push(prefix + (style ? style(line) : line));
|
|
30799
30865
|
}
|
|
30800
30866
|
}
|
|
30801
|
-
function outcomeLine(outcome) {
|
|
30802
|
-
|
|
30867
|
+
function outcomeLine(outcome, dateStyle) {
|
|
30868
|
+
const by = dateStyle === "accent" ? paint("accent", `by ${outcome.check_date}`) : chalk24.dim(`by ${outcome.check_date}`);
|
|
30869
|
+
return `${chalk24.bold(outcome.metric)}: ${outcome.baseline} ${chalk24.dim("\u2192")} ${chalk24.bold(outcome.target_range)} ${by}`;
|
|
30870
|
+
}
|
|
30871
|
+
function soonestByDue(items) {
|
|
30872
|
+
if (items.length === 0) return void 0;
|
|
30873
|
+
return [...items].sort((a, b) => a.due.localeCompare(b.due) || 0)[0];
|
|
30803
30874
|
}
|
|
30804
|
-
function
|
|
30805
|
-
|
|
30806
|
-
|
|
30807
|
-
|
|
30875
|
+
function altitudeLine(text) {
|
|
30876
|
+
const sentence = findingHeadline(text) || text.trim();
|
|
30877
|
+
return truncateVisible(sentence, FOH_PROSE_MAX);
|
|
30878
|
+
}
|
|
30879
|
+
function coverageLine(plan, stats) {
|
|
30880
|
+
const totalHours = plan.workstreams.reduce((sum, ws) => sum + ws.effort_hours, 0);
|
|
30881
|
+
const hours = `~${Math.round(totalHours)} total team hours across ${plan.workstreams.length} workstream${plan.workstreams.length === 1 ? "" : "s"}`;
|
|
30882
|
+
if (stats.total_targets <= 0) return chalk24.dim(hours);
|
|
30883
|
+
const coverage = `${stats.measurable_targets} of ${stats.total_targets} targets can be measured with current data`;
|
|
30884
|
+
const coverageStyled = stats.measurable_targets === stats.total_targets ? paint("success", coverage) : chalk24.hex("#eab308")(coverage);
|
|
30885
|
+
return `${coverageStyled}${chalk24.dim(` \xB7 ${hours}`)}`;
|
|
30886
|
+
}
|
|
30887
|
+
function renderFohWorkstream(ws, width) {
|
|
30888
|
+
const lines = [];
|
|
30889
|
+
lines.push(`${INDENT}${paint("accent", `${ws.order}.`)} ${chalk24.bold(ws.title)}`);
|
|
30890
|
+
lines.push(`${INDENT} ${outcomeLine(ws.expected_outcome, "accent")}`);
|
|
30891
|
+
const next = soonestByDue(ws.milestones);
|
|
30892
|
+
if (next) {
|
|
30893
|
+
lines.push(`${INDENT} Next ${paint("accent", next.due)} ${next.label}`);
|
|
30894
|
+
}
|
|
30895
|
+
const ship = soonestByDue(ws.deliverables);
|
|
30896
|
+
if (ship) {
|
|
30897
|
+
lines.push(`${INDENT} Ship ${paint("accent", ship.due)} ${ship.label}`);
|
|
30898
|
+
}
|
|
30899
|
+
lines.push("");
|
|
30900
|
+
return lines;
|
|
30901
|
+
}
|
|
30902
|
+
function renderBohWorkstream(ws, width) {
|
|
30903
|
+
const lines = [];
|
|
30904
|
+
lines.push(`${INDENT}${paint("accent", `${ws.order}.`)} ${chalk24.bold(ws.title)}`);
|
|
30905
|
+
collectWrapped(lines, ws.problem, width - 5, INDENT + " ", (s) => chalk24.dim(s));
|
|
30906
|
+
lines.push(`${INDENT} ${outcomeLine(ws.expected_outcome, "dim")}`);
|
|
30808
30907
|
for (const li of ws.leading_indicators) {
|
|
30809
|
-
|
|
30908
|
+
lines.push(`${INDENT} ${chalk24.dim("Lead:")} ${outcomeLine(li, "dim")}`);
|
|
30810
30909
|
}
|
|
30811
30910
|
if (ws.actions.length > 0) {
|
|
30812
|
-
|
|
30911
|
+
lines.push(`${INDENT} ${chalk24.dim("First steps")}`);
|
|
30813
30912
|
for (const action of ws.actions.slice(0, 3)) {
|
|
30814
|
-
|
|
30913
|
+
collectWrapped(lines, `- ${action}`, width - 7, INDENT + " ", (s) => chalk24.dim(s));
|
|
30815
30914
|
}
|
|
30816
30915
|
}
|
|
30817
30916
|
if (ws.milestones.length > 0) {
|
|
30818
|
-
|
|
30917
|
+
lines.push(`${INDENT} ${chalk24.dim("Milestones")}`);
|
|
30819
30918
|
for (const m of ws.milestones) {
|
|
30820
|
-
|
|
30919
|
+
lines.push(`${INDENT} ${paint("accent", m.due)} ${m.label}`);
|
|
30821
30920
|
}
|
|
30822
30921
|
}
|
|
30823
30922
|
if (ws.deliverables.length > 0) {
|
|
30824
|
-
|
|
30923
|
+
lines.push(`${INDENT} ${chalk24.dim("Deliverables")}`);
|
|
30825
30924
|
for (const d of ws.deliverables) {
|
|
30826
|
-
|
|
30925
|
+
lines.push(`${INDENT} ${chalk24.dim("[ ]")} ${d.label} ${chalk24.dim(`due ${d.due}`)}`);
|
|
30827
30926
|
}
|
|
30828
30927
|
}
|
|
30829
|
-
|
|
30928
|
+
collectWrapped(
|
|
30929
|
+
lines,
|
|
30830
30930
|
`If ${ws.contingency.trigger} (check ${ws.contingency.trigger_check_date}), then ${ws.contingency.fallback}`,
|
|
30831
30931
|
width - 5,
|
|
30832
30932
|
INDENT + " ",
|
|
30833
30933
|
(s) => chalk24.dim(s)
|
|
30834
30934
|
);
|
|
30835
|
-
|
|
30836
|
-
|
|
30935
|
+
lines.push(`${INDENT} ${chalk24.dim(`~${Math.round(ws.effort_hours)} team hours`)}`);
|
|
30936
|
+
lines.push("");
|
|
30937
|
+
return lines;
|
|
30837
30938
|
}
|
|
30838
|
-
function
|
|
30939
|
+
function renderOperatorList(title, items, width) {
|
|
30940
|
+
const lines = [];
|
|
30941
|
+
if (items.length === 0) return lines;
|
|
30942
|
+
lines.push(`${INDENT}${chalk24.dim(title)}`);
|
|
30943
|
+
for (const item of items) {
|
|
30944
|
+
collectWrapped(lines, `- ${item}`, width - 2, INDENT, (s) => chalk24.dim(s));
|
|
30945
|
+
}
|
|
30946
|
+
lines.push("");
|
|
30947
|
+
return lines;
|
|
30948
|
+
}
|
|
30949
|
+
function renderStrategyBrief(plan, stats, opts = {}) {
|
|
30950
|
+
const mode = opts.mode ?? "foh";
|
|
30839
30951
|
const width = Math.min(termWidth() - 4, 92);
|
|
30840
|
-
|
|
30841
|
-
|
|
30952
|
+
const lines = [""];
|
|
30953
|
+
lines.push(
|
|
30842
30954
|
`${INDENT}${chalk24.bold(`Strategy brief \u2014 ${plan.title}`)} ${chalk24.dim(`confidence ${plan.confidence.toFixed(2)} \xB7 ${plan.priority} priority \xB7 review ${plan.review_cadence.toLowerCase()}`)}`
|
|
30843
30955
|
);
|
|
30844
|
-
|
|
30845
|
-
|
|
30846
|
-
|
|
30847
|
-
|
|
30848
|
-
|
|
30849
|
-
|
|
30850
|
-
|
|
30851
|
-
printWorkstream(ws, width);
|
|
30852
|
-
}
|
|
30853
|
-
const constraints = filterOperatorLines(plan.constraints);
|
|
30854
|
-
if (constraints.length > 0) {
|
|
30855
|
-
console.log(`${INDENT}${chalk24.dim("Constraints")}`);
|
|
30856
|
-
for (const c of constraints) {
|
|
30857
|
-
printWrapped(`- ${c}`, width - 2, INDENT, (s) => chalk24.dim(s));
|
|
30956
|
+
if (mode === "foh") {
|
|
30957
|
+
collectWrapped(lines, altitudeLine(plan.summary_30k), width, INDENT);
|
|
30958
|
+
lines.push("");
|
|
30959
|
+
collectWrapped(lines, altitudeLine(plan.objective), width, INDENT, (s) => paint("accent", s));
|
|
30960
|
+
lines.push("");
|
|
30961
|
+
for (const ws of plan.workstreams) {
|
|
30962
|
+
lines.push(...renderFohWorkstream(ws, width));
|
|
30858
30963
|
}
|
|
30859
|
-
|
|
30860
|
-
|
|
30861
|
-
|
|
30862
|
-
|
|
30863
|
-
|
|
30864
|
-
|
|
30865
|
-
|
|
30964
|
+
} else {
|
|
30965
|
+
lines.push(INDENT + chalk24.dim(hr(width)));
|
|
30966
|
+
lines.push(`${INDENT}${chalk24.dim("The Call")}`);
|
|
30967
|
+
collectWrapped(lines, plan.summary_30k, width);
|
|
30968
|
+
lines.push("");
|
|
30969
|
+
collectWrapped(lines, `Objective: ${plan.objective}`, width, INDENT, (s) => paint("accent", s));
|
|
30970
|
+
lines.push("");
|
|
30971
|
+
for (const ws of plan.workstreams) {
|
|
30972
|
+
lines.push(...renderBohWorkstream(ws, width));
|
|
30866
30973
|
}
|
|
30867
|
-
|
|
30974
|
+
lines.push(
|
|
30975
|
+
...renderOperatorList("Constraints", filterOperatorLines(plan.constraints), width)
|
|
30976
|
+
);
|
|
30977
|
+
lines.push(
|
|
30978
|
+
...renderOperatorList(
|
|
30979
|
+
"Assumptions (not verified, not targets)",
|
|
30980
|
+
filterOperatorLines(plan.assumptions),
|
|
30981
|
+
width
|
|
30982
|
+
)
|
|
30983
|
+
);
|
|
30984
|
+
lines.push(...renderOperatorList("Risks", filterOperatorLines(plan.risks), width));
|
|
30868
30985
|
}
|
|
30869
|
-
|
|
30870
|
-
|
|
30871
|
-
|
|
30872
|
-
|
|
30873
|
-
printWrapped(`- ${r}`, width - 2, INDENT, (s) => chalk24.dim(s));
|
|
30874
|
-
}
|
|
30875
|
-
console.log();
|
|
30986
|
+
lines.push(INDENT + chalk24.dim(hr(width)));
|
|
30987
|
+
lines.push(`${INDENT}${coverageLine(plan, stats)}`);
|
|
30988
|
+
if (opts.hint) {
|
|
30989
|
+
lines.push(`${INDENT}${chalk24.dim(STRATEGY_BRIEF_EXPAND_HINT)}`);
|
|
30876
30990
|
}
|
|
30877
|
-
|
|
30878
|
-
|
|
30879
|
-
|
|
30880
|
-
|
|
30881
|
-
console.log(
|
|
30882
|
-
|
|
30991
|
+
lines.push("");
|
|
30992
|
+
return lines.join("\n");
|
|
30993
|
+
}
|
|
30994
|
+
function printStrategyBrief(plan, stats, opts = {}) {
|
|
30995
|
+
console.log(renderStrategyBrief(plan, stats, opts));
|
|
30996
|
+
}
|
|
30997
|
+
function resolveStrategyBriefMode(host) {
|
|
30998
|
+
return isVerbose(host.execution) ? "boh" : "foh";
|
|
30999
|
+
}
|
|
31000
|
+
function presentStrategyBrief(host, plan, stats, notices = [], meta = {}) {
|
|
31001
|
+
const mode = resolveStrategyBriefMode(host);
|
|
31002
|
+
printStrategyBrief(plan, stats, { mode, hint: mode === "foh" && !host.oneShot });
|
|
31003
|
+
printStrategyBriefFooter(notices, meta);
|
|
31004
|
+
host.lastStrategyBrief = { plan, stats, notices, meta };
|
|
31005
|
+
}
|
|
31006
|
+
function expandLastStrategyBrief(host) {
|
|
31007
|
+
const last = host.lastStrategyBrief;
|
|
31008
|
+
if (!last) return false;
|
|
31009
|
+
printStrategyBrief(last.plan, last.stats, { mode: "boh", hint: false });
|
|
31010
|
+
printStrategyBriefFooter(last.notices, last.meta);
|
|
31011
|
+
return true;
|
|
31012
|
+
}
|
|
31013
|
+
function isBriefExpandInput(input) {
|
|
31014
|
+
return /^(more|expand)\s*[.!]?\s*$/i.test(input.trim());
|
|
31015
|
+
}
|
|
31016
|
+
function planFromStrategy(strategy) {
|
|
31017
|
+
return {
|
|
31018
|
+
title: strategy.title,
|
|
31019
|
+
objective: strategy.objective || strategy.goal,
|
|
31020
|
+
summary_30k: strategy.raw_excerpt || strategy.goal,
|
|
31021
|
+
hypothesis: strategy.hypothesis,
|
|
31022
|
+
target_segment: strategy.target_segment,
|
|
31023
|
+
priority: strategy.priority,
|
|
31024
|
+
review_cadence: strategy.review_cadence,
|
|
31025
|
+
confidence: strategy.confidence,
|
|
31026
|
+
constraints: strategy.constraints,
|
|
31027
|
+
assumptions: strategy.assumptions,
|
|
31028
|
+
risks: strategy.risks,
|
|
31029
|
+
workstreams: strategy.workstreams
|
|
31030
|
+
};
|
|
31031
|
+
}
|
|
31032
|
+
function statsFromPlan(plan) {
|
|
31033
|
+
let total = 0;
|
|
31034
|
+
for (const ws of plan.workstreams) {
|
|
31035
|
+
total += 1;
|
|
31036
|
+
total += ws.leading_indicators.length;
|
|
31037
|
+
}
|
|
31038
|
+
return { measurable_targets: total, total_targets: total };
|
|
30883
31039
|
}
|
|
30884
31040
|
function printStrategyBriefFooter(notices, meta) {
|
|
30885
31041
|
if (usedGroundedFallback(notices)) {
|
|
@@ -30898,7 +31054,10 @@ function printCraftWrapUp(opts) {
|
|
|
30898
31054
|
);
|
|
30899
31055
|
}
|
|
30900
31056
|
const handoff = opts.inbox_path ?? opts.handoff_path;
|
|
30901
|
-
if (handoff)
|
|
31057
|
+
if (handoff) {
|
|
31058
|
+
console.log(INDENT + chalk24.dim(handoff));
|
|
31059
|
+
printExportPickupNudge({ inboxReady: Boolean(opts.inbox_path) });
|
|
31060
|
+
}
|
|
30902
31061
|
} else {
|
|
30903
31062
|
console.log(INDENT + paint("accent", "Best so far."));
|
|
30904
31063
|
const path = opts.library_path ?? opts.handoff_path ?? opts.inbox_path;
|
|
@@ -30918,15 +31077,20 @@ function printCraftWrapUp(opts) {
|
|
|
30918
31077
|
}
|
|
30919
31078
|
console.log();
|
|
30920
31079
|
}
|
|
30921
|
-
var INDENT;
|
|
31080
|
+
var STRATEGY_BRIEF_EXPAND_HINT, INDENT, FOH_PROSE_MAX;
|
|
30922
31081
|
var init_strategy_brief = __esm({
|
|
30923
31082
|
"src/output/strategy-brief.ts"() {
|
|
30924
31083
|
"use strict";
|
|
30925
31084
|
init_theme();
|
|
30926
31085
|
init_layout();
|
|
31086
|
+
init_formatters();
|
|
30927
31087
|
init_strategy_signal();
|
|
30928
31088
|
init_llm_attribution();
|
|
31089
|
+
init_handoff_skill();
|
|
31090
|
+
init_verbosity();
|
|
31091
|
+
STRATEGY_BRIEF_EXPAND_HINT = "Type more to show the full brief.";
|
|
30929
31092
|
INDENT = " ";
|
|
31093
|
+
FOH_PROSE_MAX = 220;
|
|
30930
31094
|
}
|
|
30931
31095
|
});
|
|
30932
31096
|
|
|
@@ -31287,8 +31451,7 @@ async function runStrategistSession(ctx) {
|
|
|
31287
31451
|
console.log();
|
|
31288
31452
|
return;
|
|
31289
31453
|
}
|
|
31290
|
-
|
|
31291
|
-
printStrategyBriefFooter(notices, meta);
|
|
31454
|
+
presentStrategyBrief(ctx, plan, stats, notices, meta);
|
|
31292
31455
|
console.log();
|
|
31293
31456
|
let saved = false;
|
|
31294
31457
|
if (ctx.rl) {
|
|
@@ -31347,14 +31510,14 @@ async function ensureSnapshot(ctx) {
|
|
|
31347
31510
|
}
|
|
31348
31511
|
function printCraftReplResult(ctx, result, objective) {
|
|
31349
31512
|
if (result.plan) {
|
|
31350
|
-
|
|
31513
|
+
presentStrategyBrief(ctx, result.plan, {
|
|
31351
31514
|
measurable_targets: result.measurable_targets,
|
|
31352
31515
|
total_targets: result.total_targets
|
|
31353
|
-
});
|
|
31516
|
+
}, result.notices, result.usage);
|
|
31354
31517
|
} else {
|
|
31355
31518
|
console.log(" " + chalk25.dim("(No plan produced)"));
|
|
31519
|
+
printStrategyBriefFooter(result.notices, result.usage);
|
|
31356
31520
|
}
|
|
31357
|
-
printStrategyBriefFooter(result.notices, result.usage);
|
|
31358
31521
|
if (result.library_path) creditStrategySession(ctx);
|
|
31359
31522
|
printCraftWrapUp({
|
|
31360
31523
|
status: result.status,
|
|
@@ -31964,7 +32127,7 @@ function matchDefinitionExplainer(input) {
|
|
|
31964
32127
|
}
|
|
31965
32128
|
return getMetricExplainer(id);
|
|
31966
32129
|
}
|
|
31967
|
-
function
|
|
32130
|
+
function printWrapped(text, indent = " ") {
|
|
31968
32131
|
for (const line of wrapWords(text, 78)) {
|
|
31969
32132
|
console.log(indent + line);
|
|
31970
32133
|
}
|
|
@@ -31981,10 +32144,10 @@ function tryKeylessDefinitionAnswer(ctx, input) {
|
|
|
31981
32144
|
console.log(" " + chalk29.dim(explainer.tagline));
|
|
31982
32145
|
console.log();
|
|
31983
32146
|
console.log(" " + bold("Meaning"));
|
|
31984
|
-
|
|
32147
|
+
printWrapped(explainer.meaning, " ");
|
|
31985
32148
|
console.log();
|
|
31986
32149
|
console.log(" " + bold("How NTRP calculates it"));
|
|
31987
|
-
|
|
32150
|
+
printWrapped(explainer.how_computed, " ");
|
|
31988
32151
|
for (const f of explainer.formula_lines) {
|
|
31989
32152
|
console.log(" " + paint("accent", f));
|
|
31990
32153
|
}
|
|
@@ -32055,8 +32218,6 @@ async function advanceAfterScopeConfirm(ctx) {
|
|
|
32055
32218
|
const offered = await offerDemoToAnswer(ctx);
|
|
32056
32219
|
if (offered) return "Demo loaded and analysis started";
|
|
32057
32220
|
if (audit.can_compute) {
|
|
32058
|
-
console.log();
|
|
32059
|
-
console.log(" " + chalk30.dim("Computing so I can answer\u2026"));
|
|
32060
32221
|
await runConversationCompute(ctx);
|
|
32061
32222
|
recordMessage(ctx, "agent", "Scope confirmed. Analysis started.");
|
|
32062
32223
|
return "Analysis started";
|
|
@@ -33346,12 +33507,6 @@ async function resumePendingAsk(ctx) {
|
|
|
33346
33507
|
if (!pending?.text) return false;
|
|
33347
33508
|
ctx.computeInProgress = false;
|
|
33348
33509
|
if (canUseReplAi(ctx)) {
|
|
33349
|
-
console.log();
|
|
33350
|
-
console.log(
|
|
33351
|
-
" " + chalk32.dim(
|
|
33352
|
-
pending.keylessAnswered ? "Picking up your question with the connected engine\u2026" : "Picking up your question\u2026"
|
|
33353
|
-
)
|
|
33354
|
-
);
|
|
33355
33510
|
console.log();
|
|
33356
33511
|
const { runNaturalLanguage: runNaturalLanguage3 } = await Promise.resolve().then(() => (init_nl(), nl_exports));
|
|
33357
33512
|
await runNaturalLanguage3(pending.text, ctx);
|
|
@@ -33633,7 +33788,7 @@ async function runDiagnoseTrace(options) {
|
|
|
33633
33788
|
kind: "phase_end",
|
|
33634
33789
|
phase: "compute",
|
|
33635
33790
|
durationMs: Date.now() - computeStarted,
|
|
33636
|
-
summary: "
|
|
33791
|
+
summary: "Pipeline scored"
|
|
33637
33792
|
});
|
|
33638
33793
|
computeEnded = true;
|
|
33639
33794
|
}
|
|
@@ -33663,7 +33818,7 @@ async function runDiagnoseTrace(options) {
|
|
|
33663
33818
|
kind: "phase_end",
|
|
33664
33819
|
phase: "compute",
|
|
33665
33820
|
durationMs: Date.now() - computeStarted,
|
|
33666
|
-
summary: "
|
|
33821
|
+
summary: "Pipeline scored"
|
|
33667
33822
|
});
|
|
33668
33823
|
}
|
|
33669
33824
|
if (fullResult && fullResult.segments.length > 0) {
|
|
@@ -33671,7 +33826,7 @@ async function runDiagnoseTrace(options) {
|
|
|
33671
33826
|
kind: "phase_end",
|
|
33672
33827
|
phase: "segments",
|
|
33673
33828
|
durationMs: Date.now() - (segmentsStarted ?? Date.now()),
|
|
33674
|
-
summary:
|
|
33829
|
+
summary: `${fullResult.segments.length} segment${fullResult.segments.length === 1 ? "" : "s"}`
|
|
33675
33830
|
});
|
|
33676
33831
|
}
|
|
33677
33832
|
if (!fullResult) {
|
|
@@ -33777,7 +33932,7 @@ async function runDiagnoseTrace(options) {
|
|
|
33777
33932
|
});
|
|
33778
33933
|
const reportPath = ctx ? await writeSilentMarkdownReport(ctx, fullResult, collectedFindings) : null;
|
|
33779
33934
|
if (reportPath) {
|
|
33780
|
-
bus.emit({ kind: "artifact", path: reportPath, description: "
|
|
33935
|
+
bus.emit({ kind: "artifact", path: reportPath, description: "Saved report" });
|
|
33781
33936
|
} else if (ctx?.events instanceof EventBus) {
|
|
33782
33937
|
bus.emit({ kind: "artifact", path: logPathForRun(ctx.events.runId), description: "Run log" });
|
|
33783
33938
|
}
|
|
@@ -33998,7 +34153,7 @@ async function runSegmentDiagnose(options, ctx) {
|
|
|
33998
34153
|
kind: "phase_end",
|
|
33999
34154
|
phase: "compute",
|
|
34000
34155
|
durationMs: Date.now() - t0,
|
|
34001
|
-
summary: "
|
|
34156
|
+
summary: "Pipeline scored"
|
|
34002
34157
|
});
|
|
34003
34158
|
} catch (err) {
|
|
34004
34159
|
bus.emit({ kind: "debug", message: String(err) });
|
|
@@ -34048,7 +34203,7 @@ async function runSegmentDiagnose(options, ctx) {
|
|
|
34048
34203
|
}
|
|
34049
34204
|
const reportPath = await writeSilentMarkdownReport2(ctx, result, []);
|
|
34050
34205
|
if (reportPath) {
|
|
34051
|
-
bus.emit({ kind: "artifact", path: reportPath, description: "
|
|
34206
|
+
bus.emit({ kind: "artifact", path: reportPath, description: "Saved report" });
|
|
34052
34207
|
}
|
|
34053
34208
|
return buildDiagnoseSummary(match.result, []);
|
|
34054
34209
|
}
|
|
@@ -36679,6 +36834,7 @@ async function handler10(args, _ctx) {
|
|
|
36679
36834
|
if (event.inbox_path) {
|
|
36680
36835
|
console.log(chalk43.dim(` Inbox: ${event.inbox_path}`));
|
|
36681
36836
|
}
|
|
36837
|
+
printExportPickupNudge({ inboxReady: Boolean(event.inbox_path) });
|
|
36682
36838
|
console.log();
|
|
36683
36839
|
return filepath;
|
|
36684
36840
|
} catch (err) {
|
|
@@ -36695,6 +36851,7 @@ var init_export = __esm({
|
|
|
36695
36851
|
init_path_safety();
|
|
36696
36852
|
init_argparse();
|
|
36697
36853
|
init_exports_registry();
|
|
36854
|
+
init_handoff_skill();
|
|
36698
36855
|
init_segments();
|
|
36699
36856
|
}
|
|
36700
36857
|
});
|
|
@@ -36793,6 +36950,7 @@ async function handler11(args, _ctx) {
|
|
|
36793
36950
|
if (event.inbox_path) {
|
|
36794
36951
|
console.log(chalk44.dim(` Inbox: ${event.inbox_path}`));
|
|
36795
36952
|
}
|
|
36953
|
+
printExportPickupNudge({ inboxReady: Boolean(event.inbox_path) });
|
|
36796
36954
|
console.log();
|
|
36797
36955
|
return folder;
|
|
36798
36956
|
} catch (err) {
|
|
@@ -36810,6 +36968,7 @@ var init_backmeup = __esm({
|
|
|
36810
36968
|
init_formatters();
|
|
36811
36969
|
init_path_safety();
|
|
36812
36970
|
init_exports_registry();
|
|
36971
|
+
init_handoff_skill();
|
|
36813
36972
|
EVIDENCE_FILENAMES = {
|
|
36814
36973
|
freshness: "freshness.csv",
|
|
36815
36974
|
flow_rate: "flow-rate.csv",
|
|
@@ -38394,7 +38553,7 @@ async function handler16(args, ctx) {
|
|
|
38394
38553
|
emitResult("strategy", result);
|
|
38395
38554
|
return;
|
|
38396
38555
|
}
|
|
38397
|
-
renderStrategyResult(result);
|
|
38556
|
+
renderStrategyResult(result, ctx);
|
|
38398
38557
|
} catch (err) {
|
|
38399
38558
|
if (isStructuredOutput(ctx.execution)) emitError(first === "craft" ? "strategy.craft" : "strategy", err);
|
|
38400
38559
|
console.error(chalk50.red(` ${err instanceof Error ? err.message : String(err)}`));
|
|
@@ -38550,10 +38709,10 @@ function craftJsonData(result) {
|
|
|
38550
38709
|
stop_reason: result.stop_reason ?? null
|
|
38551
38710
|
};
|
|
38552
38711
|
}
|
|
38553
|
-
function renderStrategyResult(result) {
|
|
38712
|
+
function renderStrategyResult(result, ctx) {
|
|
38554
38713
|
switch (result.action) {
|
|
38555
38714
|
case "craft":
|
|
38556
|
-
renderCraftResult(result);
|
|
38715
|
+
renderCraftResult(result, ctx);
|
|
38557
38716
|
return;
|
|
38558
38717
|
case "review":
|
|
38559
38718
|
return;
|
|
@@ -38569,8 +38728,7 @@ function renderStrategyResult(result) {
|
|
|
38569
38728
|
printStrategyList(result.strategies);
|
|
38570
38729
|
return;
|
|
38571
38730
|
case "show":
|
|
38572
|
-
|
|
38573
|
-
printStrategyDetail(result.strategy);
|
|
38731
|
+
printStrategyShow(result.strategy, ctx);
|
|
38574
38732
|
if (result.sources.length > 0) {
|
|
38575
38733
|
console.log(chalk50.hex("#14b8a6")(" Sources"));
|
|
38576
38734
|
for (const source of result.sources) {
|
|
@@ -38587,17 +38745,17 @@ function renderStrategyResult(result) {
|
|
|
38587
38745
|
return;
|
|
38588
38746
|
}
|
|
38589
38747
|
}
|
|
38590
|
-
function renderCraftResult(result) {
|
|
38748
|
+
function renderCraftResult(result, ctx) {
|
|
38591
38749
|
if (result.plan) {
|
|
38592
|
-
|
|
38750
|
+
presentStrategyBrief(ctx, result.plan, {
|
|
38593
38751
|
measurable_targets: result.measurable_targets,
|
|
38594
38752
|
total_targets: result.total_targets
|
|
38595
|
-
});
|
|
38753
|
+
}, result.notices, result.usage);
|
|
38596
38754
|
} else {
|
|
38597
38755
|
console.log();
|
|
38598
38756
|
console.log(" " + chalk50.dim("(No plan produced)"));
|
|
38757
|
+
printStrategyBriefFooter(result.notices, result.usage);
|
|
38599
38758
|
}
|
|
38600
|
-
printStrategyBriefFooter(result.notices, result.usage);
|
|
38601
38759
|
printCraftWrapUp({
|
|
38602
38760
|
status: result.status,
|
|
38603
38761
|
library_path: result.library_path,
|
|
@@ -38628,29 +38786,21 @@ function printStrategySummary(strategy) {
|
|
|
38628
38786
|
console.log(` ${strategy.goal}`);
|
|
38629
38787
|
console.log();
|
|
38630
38788
|
}
|
|
38631
|
-
function
|
|
38632
|
-
|
|
38633
|
-
|
|
38634
|
-
|
|
38635
|
-
|
|
38636
|
-
|
|
38637
|
-
|
|
38638
|
-
console.log();
|
|
38639
|
-
if (strategy.linked_play_ids.length > 0) {
|
|
38640
|
-
console.log(chalk50.hex("#14b8a6")(" Linked Plays"));
|
|
38641
|
-
console.log(` ${strategy.linked_play_ids.join(", ")}`);
|
|
38642
|
-
console.log();
|
|
38643
|
-
}
|
|
38644
|
-
if (strategy.success_metrics.length > 0) {
|
|
38645
|
-
console.log(chalk50.hex("#14b8a6")(" Success Metrics"));
|
|
38646
|
-
for (const metric of strategy.success_metrics) {
|
|
38647
|
-
console.log(` - ${metric.name}${metric.target ? `: ${metric.target}` : ""}`);
|
|
38789
|
+
function printStrategyShow(strategy, ctx) {
|
|
38790
|
+
if (strategy.workstreams.length > 0) {
|
|
38791
|
+
const plan = planFromStrategy(strategy);
|
|
38792
|
+
presentStrategyBrief(ctx, plan, statsFromPlan(plan));
|
|
38793
|
+
if (strategy.library_path) {
|
|
38794
|
+
console.log(" " + chalk50.dim(strategy.library_path));
|
|
38795
|
+
console.log();
|
|
38648
38796
|
}
|
|
38797
|
+
return;
|
|
38798
|
+
}
|
|
38799
|
+
printStrategySummary(strategy);
|
|
38800
|
+
if (strategy.library_path) {
|
|
38801
|
+
console.log(" " + chalk50.dim(strategy.library_path));
|
|
38649
38802
|
console.log();
|
|
38650
38803
|
}
|
|
38651
|
-
console.log(chalk50.hex("#14b8a6")(" Experiment Design"));
|
|
38652
|
-
console.log(` ${strategy.experiment_design}`);
|
|
38653
|
-
console.log();
|
|
38654
38804
|
}
|
|
38655
38805
|
function statusBadge3(status) {
|
|
38656
38806
|
switch (status) {
|
|
@@ -40129,7 +40279,7 @@ async function handler28(args, ctx) {
|
|
|
40129
40279
|
bus.emit({
|
|
40130
40280
|
kind: "artifact",
|
|
40131
40281
|
path: logPathForRun(bus.runId),
|
|
40132
|
-
description: "
|
|
40282
|
+
description: "Saved log"
|
|
40133
40283
|
});
|
|
40134
40284
|
} catch (err) {
|
|
40135
40285
|
bus.emit({ kind: "debug", message: String(err) });
|
|
@@ -45071,8 +45221,6 @@ async function ingestFromChat(ctx, filePath) {
|
|
|
45071
45221
|
printGapCard(audit);
|
|
45072
45222
|
if (audit.can_compute && ctx.scope?.confirmed_at) {
|
|
45073
45223
|
if (ctx.pendingAsk) {
|
|
45074
|
-
console.log();
|
|
45075
|
-
console.log(" " + chalk88.dim("Computing so I can answer\u2026"));
|
|
45076
45224
|
await runConversationCompute(ctx);
|
|
45077
45225
|
return true;
|
|
45078
45226
|
}
|
|
@@ -45156,8 +45304,6 @@ async function loadDemoFromChat(ctx, scenario, opts = {}) {
|
|
|
45156
45304
|
const audit = await refreshGapAudit(ctx);
|
|
45157
45305
|
const shouldAuto = opts.autoCompute || Boolean(ctx.pendingAsk && audit.can_compute && ctx.scope?.confirmed_at);
|
|
45158
45306
|
if (shouldAuto && audit.can_compute) {
|
|
45159
|
-
console.log();
|
|
45160
|
-
console.log(" " + chalk88.dim("Computing so I can answer\u2026"));
|
|
45161
45307
|
await runConversationCompute(ctx);
|
|
45162
45308
|
return true;
|
|
45163
45309
|
}
|
|
@@ -45936,6 +46082,18 @@ function handleBackNavigation(ctx, line) {
|
|
|
45936
46082
|
}
|
|
45937
46083
|
return null;
|
|
45938
46084
|
}
|
|
46085
|
+
function handleBriefExpand(ctx, line) {
|
|
46086
|
+
if (!isBriefExpandInput(line)) return null;
|
|
46087
|
+
if (!ctx.lastStrategyBrief) return null;
|
|
46088
|
+
const phase = resolveConversationPhase(ctx);
|
|
46089
|
+
if (phase === "scope" || phase === "awaiting_data" || phase === "strategize" || phase === "think" || phase === "deliver") {
|
|
46090
|
+
return null;
|
|
46091
|
+
}
|
|
46092
|
+
recordMessage(ctx, "user", line);
|
|
46093
|
+
expandLastStrategyBrief(ctx);
|
|
46094
|
+
recordMessage(ctx, "agent", "Full strategy brief");
|
|
46095
|
+
return { handled: true, summary: "Full strategy brief" };
|
|
46096
|
+
}
|
|
45939
46097
|
async function conversationRouter(input, ctx) {
|
|
45940
46098
|
if (ctx.oneShot || (ctx.wizardDepth ?? 0) > 0) {
|
|
45941
46099
|
return { handled: false };
|
|
@@ -45995,6 +46153,8 @@ async function conversationRouter(input, ctx) {
|
|
|
45995
46153
|
}
|
|
45996
46154
|
const backResult = handleBackNavigation(ctx, line);
|
|
45997
46155
|
if (backResult) return backResult;
|
|
46156
|
+
const expandResult = handleBriefExpand(ctx, line);
|
|
46157
|
+
if (expandResult) return expandResult;
|
|
45998
46158
|
if (/^\S+$/.test(line) && !/^\d$/.test(line)) {
|
|
45999
46159
|
const { resolveSessionByToken: resolveSessionByToken2 } = await Promise.resolve().then(() => (init_context2(), context_exports));
|
|
46000
46160
|
if (resolveSessionByToken2(line, { printErrors: false }) !== void 0) {
|
|
@@ -46106,6 +46266,7 @@ var init_router = __esm({
|
|
|
46106
46266
|
init_demo();
|
|
46107
46267
|
init_scope();
|
|
46108
46268
|
init_pending_ask();
|
|
46269
|
+
init_strategy_brief();
|
|
46109
46270
|
FRESH_START_RE = /\b(start (over|fresh)|new analysis|start again|reset session)\b/i;
|
|
46110
46271
|
CANCEL_ESCAPE_RE = /^(cancel|stop|abort|quit|never\s?mind|nevermind|forget it)\s*[.!]?\s*$/i;
|
|
46111
46272
|
}
|
|
@@ -47210,6 +47371,9 @@ function printHelp() {
|
|
|
47210
47371
|
console.log(
|
|
47211
47372
|
" " + chalk96.dim("On ") + paint("accent", "/settings") + chalk96.dim(" menus, ") + paint("accent", "b") + chalk96.dim(" leaves the hub (same as Done).")
|
|
47212
47373
|
);
|
|
47374
|
+
console.log(
|
|
47375
|
+
" " + paint("accent", "more") + chalk96.dim(" / ") + paint("accent", "expand") + chalk96.dim(" Shows the full strategy brief after the short summary.")
|
|
47376
|
+
);
|
|
47213
47377
|
console.log(
|
|
47214
47378
|
" " + paint("accent", "cancel") + chalk96.dim(" Drops the current modal overlay (strategy, think, ship, unconfirmed scope).")
|
|
47215
47379
|
);
|