@memnexus-ai/cli 1.7.222 → 1.7.223
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/commands/memories.d.ts.map +1 -1
- package/dist/commands/memories.js +171 -77
- package/dist/commands/memories.js.map +1 -1
- package/dist/lib/renderable-retrieval.d.ts +164 -0
- package/dist/lib/renderable-retrieval.d.ts.map +1 -0
- package/dist/lib/renderable-retrieval.js +364 -0
- package/dist/lib/renderable-retrieval.js.map +1 -0
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memories.d.ts","sourceRoot":"","sources":["../../src/commands/memories.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,OAAO,EACL,gBAAgB,EAChB,yBAAyB,EACzB,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,KAAK,EAGN,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"memories.d.ts","sourceRoot":"","sources":["../../src/commands/memories.ts"],"names":[],"mappings":"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"}
|
|
@@ -77,6 +77,7 @@ Object.defineProperty(exports, "isNameConflictError", { enumerable: true, get: f
|
|
|
77
77
|
Object.defineProperty(exports, "getRetryAfterMs", { enumerable: true, get: function () { return retry_1.getRetryAfterMs; } });
|
|
78
78
|
Object.defineProperty(exports, "sleep", { enumerable: true, get: function () { return retry_1.sleep; } });
|
|
79
79
|
const formatters_1 = require("../lib/formatters");
|
|
80
|
+
const renderable_retrieval_1 = require("../lib/renderable-retrieval");
|
|
80
81
|
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
81
82
|
const spinner_1 = require("../lib/spinner");
|
|
82
83
|
const date_utils_1 = require("../lib/date-utils");
|
|
@@ -2471,26 +2472,40 @@ function registerMemoriesCommands(program) {
|
|
|
2471
2472
|
spinner?.stop();
|
|
2472
2473
|
throw (0, errors_1.unusableResponseError)('Memory search', responseShape(searchData));
|
|
2473
2474
|
}
|
|
2474
|
-
//
|
|
2475
|
-
//
|
|
2476
|
-
|
|
2477
|
-
|
|
2475
|
+
// Every render path below takes the renderable, never the raw body: the
|
|
2476
|
+
// factory normalizes {memory, score, matchedVia} AND maps meta.degraded
|
|
2477
|
+
// once, so no format can render a degraded result as healthy (#5124).
|
|
2478
|
+
const search = renderable_retrieval_1.RenderableSearchResult.fromApiResponse(searchData);
|
|
2479
|
+
// The headline is the first thing a caller reads and was unconditional:
|
|
2480
|
+
// "Found N results" over an incomplete gather reads as a full answer.
|
|
2481
|
+
if (search.health.degraded) {
|
|
2482
|
+
spinner?.warn(`Found ${search.results.length} results${(0, renderable_retrieval_1.degradationHeadlineSuffix)(search.health)}`);
|
|
2483
|
+
}
|
|
2484
|
+
else {
|
|
2485
|
+
spinner?.succeed(`Found ${search.results.length} results`);
|
|
2486
|
+
}
|
|
2487
|
+
// Degradation marker — stderr, before any format branch, so it reaches
|
|
2488
|
+
// the caller in every output mode including --id-only and --format json
|
|
2489
|
+
// where stdout must stay machine-parseable.
|
|
2490
|
+
const degradedLine = (0, renderable_retrieval_1.degradationWarningLine)(search.health);
|
|
2491
|
+
if (degradedLine) {
|
|
2492
|
+
console.error(chalk_1.default.yellow(degradedLine));
|
|
2478
2493
|
}
|
|
2479
|
-
spinner?.succeed(`Found ${searchData?.data?.length || 0} results`);
|
|
2480
2494
|
// Surface extraction failures (#2862). Failed memories are invisible to
|
|
2481
2495
|
// fact/entity search, so flag them on stderr where they won't pollute
|
|
2482
2496
|
// piped JSON. Callers in table mode also see an inline indicator below.
|
|
2483
|
-
const failedResultCount =
|
|
2497
|
+
const failedResultCount = search.results.filter((r) => {
|
|
2484
2498
|
const m = r?.memory ?? r;
|
|
2485
2499
|
return m && m.extractionStatus === 'failed';
|
|
2486
2500
|
}).length;
|
|
2487
2501
|
if (failedResultCount > 0 && !options.idOnly) {
|
|
2488
|
-
const total =
|
|
2502
|
+
const total = search.results.length;
|
|
2489
2503
|
console.error(chalk_1.default.yellow(`⚠ ${failedResultCount} of ${total} results have failed extraction (won\u2019t appear in fact/entity searches).`));
|
|
2490
2504
|
}
|
|
2491
|
-
// --id-only mode: output only IDs for piping
|
|
2505
|
+
// --id-only mode: output only IDs for piping. The degradation marker
|
|
2506
|
+
// already went to stderr above, so it survives the pipe.
|
|
2492
2507
|
if (options.idOnly) {
|
|
2493
|
-
const ids =
|
|
2508
|
+
const ids = search.results
|
|
2494
2509
|
.map((result) => result.memory?.id)
|
|
2495
2510
|
.filter((id) => id);
|
|
2496
2511
|
console.log(ids.join('\n'));
|
|
@@ -2498,12 +2513,12 @@ function registerMemoriesCommands(program) {
|
|
|
2498
2513
|
}
|
|
2499
2514
|
// --timeline mode: chronological display with timestamps and effective state
|
|
2500
2515
|
if (options.timeline) {
|
|
2501
|
-
displayTimelineResults(
|
|
2516
|
+
displayTimelineResults(search.results, options.query, previewLength, search.health);
|
|
2502
2517
|
return;
|
|
2503
2518
|
}
|
|
2504
2519
|
// --group-by conversation: group results by conversation ID
|
|
2505
2520
|
if (options.groupBy === 'conversation') {
|
|
2506
|
-
const results =
|
|
2521
|
+
const results = search.results;
|
|
2507
2522
|
const grouped = groupByConversation(results);
|
|
2508
2523
|
if (effectiveFormat === 'json' || effectiveFormat === 'yaml') {
|
|
2509
2524
|
// Convert Map to array for JSON/YAML serialization
|
|
@@ -2512,10 +2527,13 @@ function registerMemoriesCommands(program) {
|
|
|
2512
2527
|
memoryCount: memories.length,
|
|
2513
2528
|
memories: memories,
|
|
2514
2529
|
}));
|
|
2530
|
+
// Array-shaped payload: adding a health object would change the
|
|
2531
|
+
// top-level shape, so the marker for this path is the stderr line
|
|
2532
|
+
// emitted above.
|
|
2515
2533
|
(0, formatters_1.printOutput)(groupedArray, effectiveFormat);
|
|
2516
2534
|
}
|
|
2517
2535
|
else {
|
|
2518
|
-
displayGroupedSearch(grouped, options.query);
|
|
2536
|
+
displayGroupedSearch(grouped, options.query, search.health);
|
|
2519
2537
|
}
|
|
2520
2538
|
return;
|
|
2521
2539
|
}
|
|
@@ -2523,7 +2541,7 @@ function registerMemoriesCommands(program) {
|
|
|
2523
2541
|
if (effectiveFormat === 'llm') {
|
|
2524
2542
|
// LLM format: clean markdown without ANSI codes
|
|
2525
2543
|
// Extract nested memory objects for formatting
|
|
2526
|
-
const llmData =
|
|
2544
|
+
const llmData = search.results.map((result) => {
|
|
2527
2545
|
const m = result.memory;
|
|
2528
2546
|
return {
|
|
2529
2547
|
id: m.id,
|
|
@@ -2532,15 +2550,19 @@ function registerMemoriesCommands(program) {
|
|
|
2532
2550
|
createdAt: m.createdAt,
|
|
2533
2551
|
};
|
|
2534
2552
|
});
|
|
2553
|
+
const llmMarker = (0, renderable_retrieval_1.degradationSummaryLine)(search.health);
|
|
2554
|
+
if (llmMarker) {
|
|
2555
|
+
console.log(llmMarker);
|
|
2556
|
+
}
|
|
2535
2557
|
(0, formatters_1.printOutput)(llmData, 'llm', undefined, {
|
|
2536
|
-
totalCount:
|
|
2558
|
+
totalCount: search.total,
|
|
2537
2559
|
previewLength: Math.min(previewLength, 100), // Shorter preview for LLM
|
|
2538
2560
|
title: 'Search Results',
|
|
2539
2561
|
});
|
|
2540
2562
|
}
|
|
2541
2563
|
else if (effectiveFormat === 'compact') {
|
|
2542
2564
|
// Compact format: ID + date + first line
|
|
2543
|
-
const compactData =
|
|
2565
|
+
const compactData = search.results.map((result) => {
|
|
2544
2566
|
const m = result.memory;
|
|
2545
2567
|
return {
|
|
2546
2568
|
id: m.id,
|
|
@@ -2548,13 +2570,17 @@ function registerMemoriesCommands(program) {
|
|
|
2548
2570
|
createdAt: m.createdAt,
|
|
2549
2571
|
};
|
|
2550
2572
|
});
|
|
2573
|
+
const compactMarker = (0, renderable_retrieval_1.degradationSummaryLine)(search.health);
|
|
2574
|
+
if (compactMarker) {
|
|
2575
|
+
console.log(chalk_1.default.yellow(compactMarker));
|
|
2576
|
+
}
|
|
2551
2577
|
(0, formatters_1.printOutput)(compactData, 'compact');
|
|
2552
2578
|
}
|
|
2553
2579
|
else if (effectiveFormat === 'table' || !effectiveFormat) {
|
|
2554
2580
|
// Table format: default display with colors and borders
|
|
2555
2581
|
// Extract nested memory object from search results
|
|
2556
2582
|
// API returns: {data: [{memory: {...}, score: 0.66}]}
|
|
2557
|
-
const tableData =
|
|
2583
|
+
const tableData = search.results.map((result) => {
|
|
2558
2584
|
const m = result.memory; // Extract the nested memory object
|
|
2559
2585
|
const score = result.score;
|
|
2560
2586
|
// Smart truncation with term highlighting
|
|
@@ -2590,19 +2616,23 @@ function registerMemoriesCommands(program) {
|
|
|
2590
2616
|
columnWidths: tableWidths,
|
|
2591
2617
|
});
|
|
2592
2618
|
// Show search metadata
|
|
2593
|
-
const resultCount =
|
|
2594
|
-
const searchMethodUsed =
|
|
2619
|
+
const resultCount = search.total;
|
|
2620
|
+
const searchMethodUsed = search.searchMethod || effectiveMethod;
|
|
2595
2621
|
// Detect graph branches used
|
|
2596
2622
|
const allBranches = new Set();
|
|
2597
|
-
for (const r of
|
|
2623
|
+
for (const r of search.results) {
|
|
2598
2624
|
if (r.matchedVia) {
|
|
2599
2625
|
r.matchedVia.forEach((b) => allBranches.add(b));
|
|
2600
2626
|
}
|
|
2601
2627
|
}
|
|
2602
2628
|
const branchInfo = allBranches.size > 2 ? ` (branches: ${[...allBranches].join(', ')})` : '';
|
|
2603
2629
|
console.log(chalk_1.default.gray(`\nFound ${resultCount} results using ${searchMethodUsed} search${branchInfo}`));
|
|
2630
|
+
const tableMarker = (0, renderable_retrieval_1.degradationSummaryLine)(search.health);
|
|
2631
|
+
if (tableMarker) {
|
|
2632
|
+
console.log(chalk_1.default.yellow(tableMarker));
|
|
2633
|
+
}
|
|
2604
2634
|
// Show temporal filters if applied
|
|
2605
|
-
const temporal =
|
|
2635
|
+
const temporal = search.temporalMetadata;
|
|
2606
2636
|
if (temporal?.temporalFieldsIncluded) {
|
|
2607
2637
|
const filters = [];
|
|
2608
2638
|
if (temporal.eventTimeRange?.from)
|
|
@@ -2617,7 +2647,9 @@ function registerMemoriesCommands(program) {
|
|
|
2617
2647
|
else {
|
|
2618
2648
|
// JSON/YAML formats: pass raw or content-only data
|
|
2619
2649
|
if (options.contentOnly) {
|
|
2620
|
-
|
|
2650
|
+
// Array-shaped payload by contract ({id, createdAt, topics,
|
|
2651
|
+
// content}); the marker for this path is the stderr line above.
|
|
2652
|
+
const contentOnlyData = search.results.map((result) => {
|
|
2621
2653
|
const m = result.memory;
|
|
2622
2654
|
const obj = {
|
|
2623
2655
|
id: m.id,
|
|
@@ -2633,7 +2665,8 @@ function registerMemoriesCommands(program) {
|
|
|
2633
2665
|
(0, formatters_1.printOutput)(contentOnlyData, effectiveFormat);
|
|
2634
2666
|
}
|
|
2635
2667
|
else {
|
|
2636
|
-
|
|
2668
|
+
// Object-shaped payload: carries the health object when degraded.
|
|
2669
|
+
(0, formatters_1.printOutput)(search.toSerializable(), effectiveFormat);
|
|
2637
2670
|
}
|
|
2638
2671
|
}
|
|
2639
2672
|
}
|
|
@@ -2737,7 +2770,13 @@ function escapeRegex(str) {
|
|
|
2737
2770
|
/**
|
|
2738
2771
|
* Display search results in timeline format (chronological with timestamps and state)
|
|
2739
2772
|
*/
|
|
2740
|
-
function displayTimelineResults(results, query, previewLength) {
|
|
2773
|
+
function displayTimelineResults(results, query, previewLength, health) {
|
|
2774
|
+
// The marker prints before the "no results" return: an empty timeline over a
|
|
2775
|
+
// degraded gather is exactly the case that must not read as "nothing exists".
|
|
2776
|
+
const marker = (0, renderable_retrieval_1.degradationSummaryLine)(health);
|
|
2777
|
+
if (marker) {
|
|
2778
|
+
console.log(chalk_1.default.yellow(`\n${marker}`));
|
|
2779
|
+
}
|
|
2741
2780
|
if (results.length === 0) {
|
|
2742
2781
|
console.log(chalk_1.default.yellow('\nNo results found.'));
|
|
2743
2782
|
return;
|
|
@@ -3399,20 +3438,28 @@ function registerDigestCommand(memories) {
|
|
|
3399
3438
|
spinner.stop();
|
|
3400
3439
|
throw (0, errors_1.unusableResponseError)('Digest generation', responseShape(data));
|
|
3401
3440
|
}
|
|
3402
|
-
|
|
3441
|
+
// One construction path; the meta-vs-metadata mapping lives in the
|
|
3442
|
+
// factory (#5124).
|
|
3443
|
+
const renderable = renderable_retrieval_1.RenderableDigestResult.fromApiResponse(data);
|
|
3444
|
+
const { digest, metadata, sources, keyFacts, entities, effectiveStateBreakdown } = renderable;
|
|
3403
3445
|
if (metadata.sourcesUsed === 0) {
|
|
3404
3446
|
// Zero sources is a genuine empty result (exit 0), but it is not a
|
|
3405
3447
|
// success: the old "Digest generated from 0 memories" success glyph
|
|
3406
3448
|
// read as "here is your answer" when nothing was retrieved.
|
|
3407
3449
|
spinner.info('No sources met the relevance threshold for this query');
|
|
3408
3450
|
}
|
|
3451
|
+
else if (renderable.health.degraded) {
|
|
3452
|
+
spinner.warn(`Digest generated from ${metadata.sourcesUsed} memories across ` +
|
|
3453
|
+
`${metadata.conversationsSpanned} conversations` +
|
|
3454
|
+
(0, renderable_retrieval_1.degradationHeadlineSuffix)(renderable.health));
|
|
3455
|
+
}
|
|
3409
3456
|
else {
|
|
3410
3457
|
spinner.succeed(`Digest generated from ${metadata.sourcesUsed} memories across ${metadata.conversationsSpanned} conversations`);
|
|
3411
3458
|
}
|
|
3412
|
-
printRetrievalCaveats(
|
|
3459
|
+
printRetrievalCaveats(renderable);
|
|
3413
3460
|
// JSON/YAML output
|
|
3414
3461
|
if (options.format === 'json' || options.format === 'yaml') {
|
|
3415
|
-
(0, formatters_1.printOutput)(
|
|
3462
|
+
(0, formatters_1.printOutput)(renderable.toSerializable(), options.format);
|
|
3416
3463
|
return;
|
|
3417
3464
|
}
|
|
3418
3465
|
// LLM output — raw digest text only
|
|
@@ -3421,7 +3468,7 @@ function registerDigestCommand(memories) {
|
|
|
3421
3468
|
return;
|
|
3422
3469
|
}
|
|
3423
3470
|
// Default display with box formatting
|
|
3424
|
-
displayDigest(digest, metadata, sources, options, keyFacts, entities, effectiveStateBreakdown);
|
|
3471
|
+
displayDigest(digest, metadata, sources, options, keyFacts, entities, effectiveStateBreakdown, renderable.health);
|
|
3425
3472
|
}
|
|
3426
3473
|
catch (error) {
|
|
3427
3474
|
// KI-77: name the ceiling and give a narrower-query fix instead of the SDK's
|
|
@@ -3498,23 +3545,29 @@ function registerStatusCommand(memories) {
|
|
|
3498
3545
|
spinner.stop();
|
|
3499
3546
|
throw (0, errors_1.unusableResponseError)('Status report generation', responseShape(data));
|
|
3500
3547
|
}
|
|
3501
|
-
const
|
|
3548
|
+
const renderable = renderable_retrieval_1.RenderableDigestResult.fromApiResponse(data);
|
|
3549
|
+
const { digest, metadata, sources, keyFacts, entities, effectiveStateBreakdown } = renderable;
|
|
3502
3550
|
if (metadata.sourcesUsed === 0) {
|
|
3503
3551
|
spinner.info('No sources met the relevance threshold for this query');
|
|
3504
3552
|
}
|
|
3553
|
+
else if (renderable.health.degraded) {
|
|
3554
|
+
spinner.warn(`Status report from ${metadata.sourcesUsed} memories across ` +
|
|
3555
|
+
`${metadata.conversationsSpanned} conversations` +
|
|
3556
|
+
(0, renderable_retrieval_1.degradationHeadlineSuffix)(renderable.health));
|
|
3557
|
+
}
|
|
3505
3558
|
else {
|
|
3506
3559
|
spinner.succeed(`Status report from ${metadata.sourcesUsed} memories across ${metadata.conversationsSpanned} conversations`);
|
|
3507
3560
|
}
|
|
3508
|
-
printRetrievalCaveats(
|
|
3561
|
+
printRetrievalCaveats(renderable);
|
|
3509
3562
|
if (options.format === 'json' || options.format === 'yaml') {
|
|
3510
|
-
(0, formatters_1.printOutput)(
|
|
3563
|
+
(0, formatters_1.printOutput)(renderable.toSerializable(), options.format);
|
|
3511
3564
|
return;
|
|
3512
3565
|
}
|
|
3513
3566
|
if (options.format === 'llm') {
|
|
3514
3567
|
console.log(digest);
|
|
3515
3568
|
return;
|
|
3516
3569
|
}
|
|
3517
|
-
displayDigest(digest, metadata, sources, options, keyFacts, entities, effectiveStateBreakdown);
|
|
3570
|
+
displayDigest(digest, metadata, sources, options, keyFacts, entities, effectiveStateBreakdown, renderable.health);
|
|
3518
3571
|
}
|
|
3519
3572
|
catch (error) {
|
|
3520
3573
|
(0, errors_1.handleError)(error);
|
|
@@ -3547,10 +3600,16 @@ function responseShape(body) {
|
|
|
3547
3600
|
* including `--format json`, where the digest body must remain the only
|
|
3548
3601
|
* top-level JSON on stdout.
|
|
3549
3602
|
*
|
|
3550
|
-
*
|
|
3551
|
-
*
|
|
3603
|
+
* #5124: the degraded branch below read `meta.degraded` on a response that
|
|
3604
|
+
* carries the flag at `metadata.degraded`, so it had never fired on any real
|
|
3605
|
+
* response. It now reads `renderable.health`, which the factory populates from
|
|
3606
|
+
* the field the wire actually uses. Taking the renderable rather than two loose
|
|
3607
|
+
* `any` bags is what stops the same mistake being made again.
|
|
3608
|
+
*
|
|
3609
|
+
* @param renderable - The digest response, health already mapped
|
|
3552
3610
|
*/
|
|
3553
|
-
function printRetrievalCaveats(
|
|
3611
|
+
function printRetrievalCaveats(renderable) {
|
|
3612
|
+
const metadata = renderable.metadata;
|
|
3554
3613
|
const avg = typeof metadata?.averageRelevance === 'number' ? metadata.averageRelevance : null;
|
|
3555
3614
|
const avgLabel = avg === null ? 'unknown' : avg.toFixed(3);
|
|
3556
3615
|
if (metadata?.narrowWindowFallback) {
|
|
@@ -3563,30 +3622,18 @@ function printRetrievalCaveats(metadata, meta) {
|
|
|
3563
3622
|
'threshold and the sources span more than one project — this content may come ' +
|
|
3564
3623
|
'from a different project than the one you are working in.'));
|
|
3565
3624
|
}
|
|
3566
|
-
//
|
|
3567
|
-
//
|
|
3568
|
-
//
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
// Constrain them to an identifier shape and cap the count rather than
|
|
3573
|
-
// echoing arbitrary text: an unbounded string here is an injection channel
|
|
3574
|
-
// into agent context (and can carry ANSI escapes from a hostile apiUrl).
|
|
3575
|
-
const names = failures
|
|
3576
|
-
.map((b) => (typeof b === 'string' ? b : b?.branch || b?.name))
|
|
3577
|
-
.filter((n) => typeof n === 'string' && /^[A-Za-z0-9_-]{1,32}$/.test(n))
|
|
3578
|
-
.slice(0, 8);
|
|
3579
|
-
const detail = names.length
|
|
3580
|
-
? `failed branches: ${names.join(', ')}`
|
|
3581
|
-
: 'one or more retrieval branches failed';
|
|
3582
|
-
console.error(chalk_1.default.yellow(`⚠ Degraded retrieval — ${detail}. These results are incomplete; re-run before ` +
|
|
3583
|
-
'treating them as a full answer.'));
|
|
3625
|
+
// Degraded retrieval. Branch-name sanitising (identifier shape, capped count)
|
|
3626
|
+
// lives in the renderable factory now — branch names are server-supplied and
|
|
3627
|
+
// land on stderr, which agents read.
|
|
3628
|
+
const degradedLine = (0, renderable_retrieval_1.degradationWarningLine)(renderable.health);
|
|
3629
|
+
if (degradedLine) {
|
|
3630
|
+
console.error(chalk_1.default.yellow(degradedLine));
|
|
3584
3631
|
}
|
|
3585
3632
|
}
|
|
3586
3633
|
/**
|
|
3587
3634
|
* Display a formatted digest with header box and metadata footer
|
|
3588
3635
|
*/
|
|
3589
|
-
function displayDigest(digest, metadata, sources, options, keyFacts, entities, effectiveStateBreakdown) {
|
|
3636
|
+
function displayDigest(digest, metadata, sources, options, keyFacts, entities, effectiveStateBreakdown, health) {
|
|
3590
3637
|
const width = 66;
|
|
3591
3638
|
const border = '═'.repeat(width);
|
|
3592
3639
|
// Format header info
|
|
@@ -3600,6 +3647,12 @@ function displayDigest(digest, metadata, sources, options, keyFacts, entities, e
|
|
|
3600
3647
|
console.log(chalk_1.default.cyan(`║ ${headerLine1.padEnd(width - 2)}║`));
|
|
3601
3648
|
console.log(chalk_1.default.cyan(`║ ${headerLine2.padEnd(width - 2)}║`));
|
|
3602
3649
|
console.log(chalk_1.default.cyan(`╚${border}╝`));
|
|
3650
|
+
// Degradation marker inside the box output, so a reader of the digest text
|
|
3651
|
+
// itself sees it — not only the caller reading stderr.
|
|
3652
|
+
const digestMarker = (0, renderable_retrieval_1.degradationSummaryLine)(health);
|
|
3653
|
+
if (digestMarker) {
|
|
3654
|
+
console.log(chalk_1.default.yellow(digestMarker));
|
|
3655
|
+
}
|
|
3603
3656
|
// Digest content
|
|
3604
3657
|
console.log('');
|
|
3605
3658
|
console.log(digest);
|
|
@@ -3688,7 +3741,7 @@ function registerRecapCommand(memories) {
|
|
|
3688
3741
|
: undefined;
|
|
3689
3742
|
// Fetch memories: list endpoint (time-range browse) when no query is given;
|
|
3690
3743
|
// search endpoint (semantic ranking) when --query is provided.
|
|
3691
|
-
let
|
|
3744
|
+
let renderable;
|
|
3692
3745
|
if (options.query) {
|
|
3693
3746
|
const searchRequest = {
|
|
3694
3747
|
q: options.query,
|
|
@@ -3701,8 +3754,8 @@ function registerRecapCommand(memories) {
|
|
|
3701
3754
|
if (excludeTopicsParam)
|
|
3702
3755
|
searchRequest.excludeTopics = excludeTopicsParam;
|
|
3703
3756
|
const response = await retryRead(() => (0, api_client_1.getSdk)().memories.searchMemoriesGet(searchRequest));
|
|
3704
|
-
//
|
|
3705
|
-
|
|
3757
|
+
// Normalisation and the meta.degraded mapping both live in the factory.
|
|
3758
|
+
renderable = renderable_retrieval_1.RenderableSearchResult.fromApiResponse(response.data);
|
|
3706
3759
|
}
|
|
3707
3760
|
else {
|
|
3708
3761
|
// Issue #1628: search endpoint requires a query string; use list endpoint for
|
|
@@ -3717,9 +3770,12 @@ function registerRecapCommand(memories) {
|
|
|
3717
3770
|
if (excludeTopicsParam)
|
|
3718
3771
|
listRequest.excludeTopics = excludeTopicsParam;
|
|
3719
3772
|
const response = await retryRead(() => (0, api_client_1.getSdk)().memories.listMemories(listRequest));
|
|
3720
|
-
// Wrap in search-result shape expected by groupByConversation / displayRecap
|
|
3721
|
-
|
|
3773
|
+
// Wrap in search-result shape expected by groupByConversation / displayRecap.
|
|
3774
|
+
// The list endpoint runs no search branches, so it is healthy by construction.
|
|
3775
|
+
renderable = renderable_retrieval_1.RenderableSearchResult.fromListResponse(response.data);
|
|
3722
3776
|
}
|
|
3777
|
+
const health = renderable.health;
|
|
3778
|
+
let results = [...renderable.results];
|
|
3723
3779
|
// Client-side filtering as fallback (API exclude may not work with wildcard query)
|
|
3724
3780
|
if (options.excludeTopics) {
|
|
3725
3781
|
const excludeSet = new Set(options.excludeTopics.split(',').map((t) => t.trim().toLowerCase()));
|
|
@@ -3729,7 +3785,18 @@ function registerRecapCommand(memories) {
|
|
|
3729
3785
|
});
|
|
3730
3786
|
}
|
|
3731
3787
|
const truncated = results.length >= fetchLimit;
|
|
3732
|
-
|
|
3788
|
+
if (health.degraded) {
|
|
3789
|
+
spinner.warn(`Found ${results.length} memories${(0, renderable_retrieval_1.degradationHeadlineSuffix)(health)}`);
|
|
3790
|
+
}
|
|
3791
|
+
else {
|
|
3792
|
+
spinner.succeed(`Found ${results.length} memories`);
|
|
3793
|
+
}
|
|
3794
|
+
// stderr, before the zero-result return: "no memories in the last 24h"
|
|
3795
|
+
// over an incomplete gather is the exact wrong conclusion to record.
|
|
3796
|
+
const recapDegraded = (0, renderable_retrieval_1.degradationWarningLine)(health);
|
|
3797
|
+
if (recapDegraded) {
|
|
3798
|
+
console.error(chalk_1.default.yellow(recapDegraded));
|
|
3799
|
+
}
|
|
3733
3800
|
if (results.length === 0) {
|
|
3734
3801
|
console.log(chalk_1.default.yellow(`\nNo memories found in the last ${options.recent}.`));
|
|
3735
3802
|
return;
|
|
@@ -3746,7 +3813,7 @@ function registerRecapCommand(memories) {
|
|
|
3746
3813
|
// Group memories by conversation
|
|
3747
3814
|
const conversations = groupByConversation(results);
|
|
3748
3815
|
// Display recap
|
|
3749
|
-
displayRecap(conversations, options.recent);
|
|
3816
|
+
displayRecap(conversations, options.recent, health);
|
|
3750
3817
|
}
|
|
3751
3818
|
catch (error) {
|
|
3752
3819
|
(0, errors_1.handleError)(error);
|
|
@@ -3779,8 +3846,12 @@ function groupByConversation(results) {
|
|
|
3779
3846
|
/**
|
|
3780
3847
|
* Display recap output grouped by conversation
|
|
3781
3848
|
*/
|
|
3782
|
-
function displayRecap(conversations, duration) {
|
|
3849
|
+
function displayRecap(conversations, duration, health) {
|
|
3783
3850
|
console.log(chalk_1.default.cyan(`\n📅 Work Recap (last ${duration})`));
|
|
3851
|
+
const recapMarker = (0, renderable_retrieval_1.degradationSummaryLine)(health);
|
|
3852
|
+
if (recapMarker) {
|
|
3853
|
+
console.log(chalk_1.default.yellow(recapMarker));
|
|
3854
|
+
}
|
|
3784
3855
|
console.log(chalk_1.default.gray('═'.repeat(60)));
|
|
3785
3856
|
// Sort conversations by most recent activity
|
|
3786
3857
|
const sortedConversations = Array.from(conversations.entries()).sort((a, b) => {
|
|
@@ -3876,8 +3947,12 @@ function extractReferences(memories) {
|
|
|
3876
3947
|
/**
|
|
3877
3948
|
* Display search results grouped by conversation
|
|
3878
3949
|
*/
|
|
3879
|
-
function displayGroupedSearch(conversations, query) {
|
|
3950
|
+
function displayGroupedSearch(conversations, query, health) {
|
|
3880
3951
|
console.log(chalk_1.default.cyan(`\n🔍 Search Results for "${query}" (grouped by conversation)`));
|
|
3952
|
+
const groupedMarker = (0, renderable_retrieval_1.degradationSummaryLine)(health);
|
|
3953
|
+
if (groupedMarker) {
|
|
3954
|
+
console.log(chalk_1.default.yellow(groupedMarker));
|
|
3955
|
+
}
|
|
3881
3956
|
console.log(chalk_1.default.gray('═'.repeat(60)));
|
|
3882
3957
|
// Sort conversations by most recent activity
|
|
3883
3958
|
const sortedConversations = Array.from(conversations.entries()).sort((a, b) => {
|
|
@@ -3965,17 +4040,36 @@ function registerBuildContextCommand(memories) {
|
|
|
3965
4040
|
spinner.stop();
|
|
3966
4041
|
throw (0, errors_1.unusableResponseError)('Context briefing', responseShape(data));
|
|
3967
4042
|
}
|
|
3968
|
-
|
|
4043
|
+
// The API has been sending meta.degraded (with timedOutSections /
|
|
4044
|
+
// failedSections) here all along; the CLI dropped it. A briefing missing
|
|
4045
|
+
// its gotchas section reads exactly like a project with no gotchas.
|
|
4046
|
+
const briefing = renderable_retrieval_1.RenderableContextBriefing.fromApiResponse(data);
|
|
4047
|
+
const briefingHealth = briefing.health;
|
|
4048
|
+
if (briefingHealth.degraded) {
|
|
4049
|
+
spinner.warn(`Context briefing ready${(0, renderable_retrieval_1.degradationHeadlineSuffix)(briefingHealth)}`);
|
|
4050
|
+
}
|
|
4051
|
+
else {
|
|
4052
|
+
spinner.succeed('Context briefing ready');
|
|
4053
|
+
}
|
|
4054
|
+
const briefingDegraded = (0, renderable_retrieval_1.degradationWarningLine)(briefingHealth);
|
|
4055
|
+
if (briefingDegraded) {
|
|
4056
|
+
console.error(chalk_1.default.yellow(briefingDegraded));
|
|
4057
|
+
}
|
|
3969
4058
|
// JSON output
|
|
3970
4059
|
if (options.format === 'json' || options.format === 'yaml') {
|
|
3971
|
-
(0, formatters_1.printOutput)(
|
|
4060
|
+
(0, formatters_1.printOutput)(briefing.toSerializable(), options.format);
|
|
3972
4061
|
return;
|
|
3973
4062
|
}
|
|
3974
4063
|
// Human-readable output
|
|
3975
4064
|
console.log('');
|
|
4065
|
+
const briefingMarker = (0, renderable_retrieval_1.degradationSummaryLine)(briefingHealth);
|
|
4066
|
+
if (briefingMarker) {
|
|
4067
|
+
console.log(chalk_1.default.yellow(briefingMarker));
|
|
4068
|
+
console.log('');
|
|
4069
|
+
}
|
|
3976
4070
|
// Active Work
|
|
3977
|
-
if (data.activeWork) {
|
|
3978
|
-
const aw = data.activeWork;
|
|
4071
|
+
if (briefing.data.activeWork) {
|
|
4072
|
+
const aw = briefing.data.activeWork;
|
|
3979
4073
|
console.log(chalk_1.default.yellow.bold('Active Work'));
|
|
3980
4074
|
console.log(` You were working on: ${chalk_1.default.white(aw.title || '(untitled)')} (${chalk_1.default.gray(aw.conversationId)})`);
|
|
3981
4075
|
if (aw.lastMemory?.summary) {
|
|
@@ -3984,43 +4078,43 @@ function registerBuildContextCommand(memories) {
|
|
|
3984
4078
|
console.log('');
|
|
3985
4079
|
}
|
|
3986
4080
|
// Key Facts
|
|
3987
|
-
if (data.relevantFacts?.length) {
|
|
4081
|
+
if (briefing.data.relevantFacts?.length) {
|
|
3988
4082
|
console.log(chalk_1.default.cyan.bold('Key Facts'));
|
|
3989
|
-
for (const f of data.relevantFacts) {
|
|
4083
|
+
for (const f of briefing.data.relevantFacts) {
|
|
3990
4084
|
console.log(` ${chalk_1.default.gray('•')} ${f.subject} ${f.predicate} ${f.object}`);
|
|
3991
4085
|
}
|
|
3992
4086
|
console.log('');
|
|
3993
4087
|
}
|
|
3994
4088
|
// Gotchas
|
|
3995
|
-
if (data.gotchas?.length) {
|
|
4089
|
+
if (briefing.data.gotchas?.length) {
|
|
3996
4090
|
console.log(chalk_1.default.red.bold('Gotchas'));
|
|
3997
|
-
for (const g of data.gotchas) {
|
|
4091
|
+
for (const g of briefing.data.gotchas) {
|
|
3998
4092
|
console.log(` ${chalk_1.default.red('⚠')} ${chalk_1.default.bold(g.fact)} ${chalk_1.default.gray(`(${g.sourceCount} sources)`)}`);
|
|
3999
4093
|
}
|
|
4000
4094
|
console.log('');
|
|
4001
4095
|
}
|
|
4002
4096
|
// Recent Activity
|
|
4003
|
-
if (data.recentActivity?.length) {
|
|
4004
|
-
const hours = data.meta?.recentHours || 24;
|
|
4097
|
+
if (briefing.data.recentActivity?.length) {
|
|
4098
|
+
const hours = briefing.data.meta?.recentHours || 24;
|
|
4005
4099
|
console.log(chalk_1.default.green.bold(`Recent Activity (last ${hours}h)`));
|
|
4006
|
-
for (const a of data.recentActivity) {
|
|
4100
|
+
for (const a of briefing.data.recentActivity) {
|
|
4007
4101
|
const date = a.date ? (0, date_utils_1.formatApiDate)(a.date) : '';
|
|
4008
4102
|
console.log(` ${chalk_1.default.gray('•')} ${a.summary} ${chalk_1.default.gray(`(${date})`)}`);
|
|
4009
4103
|
}
|
|
4010
4104
|
console.log('');
|
|
4011
4105
|
}
|
|
4012
4106
|
// Patterns
|
|
4013
|
-
if (data.relatedPatterns?.length) {
|
|
4107
|
+
if (briefing.data.relatedPatterns?.length) {
|
|
4014
4108
|
console.log(chalk_1.default.magenta.bold('Relevant Patterns'));
|
|
4015
|
-
for (const p of data.relatedPatterns) {
|
|
4109
|
+
for (const p of briefing.data.relatedPatterns) {
|
|
4016
4110
|
const conf = p.confidence != null ? chalk_1.default.gray(` (${(p.confidence * 100).toFixed(0)}%)`) : '';
|
|
4017
4111
|
console.log(` ${chalk_1.default.gray('•')} ${p.pattern}${conf}`);
|
|
4018
4112
|
}
|
|
4019
4113
|
console.log('');
|
|
4020
4114
|
}
|
|
4021
4115
|
// Meta
|
|
4022
|
-
if (data.meta?.contextTerms?.length) {
|
|
4023
|
-
console.log(chalk_1.default.gray(`Search terms: ${data.meta.contextTerms.join(', ')}`));
|
|
4116
|
+
if (briefing.data.meta?.contextTerms?.length) {
|
|
4117
|
+
console.log(chalk_1.default.gray(`Search terms: ${briefing.data.meta.contextTerms.join(', ')}`));
|
|
4024
4118
|
}
|
|
4025
4119
|
}
|
|
4026
4120
|
catch (error) {
|