@herbertgao/pi-extensions 2026.8.12 → 2026.8.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -3
- package/THIRD_PARTY_NOTICES.md +4 -0
- package/node_modules/@luxusai/pi-hindsight/CHANGELOG.md +376 -0
- package/node_modules/@luxusai/pi-hindsight/README.md +92 -0
- package/node_modules/@luxusai/pi-hindsight/docs/adr/001-memory-lifecycle-and-scope.md +56 -0
- package/node_modules/@luxusai/pi-hindsight/docs/adr/002-explicit-routing-strategy-seam.md +169 -0
- package/node_modules/@luxusai/pi-hindsight/docs/adr/003-tui-memory-mode-vocabulary.md +107 -0
- package/node_modules/@luxusai/pi-hindsight/docs/adr/004-lifeos-dual-bank-design.md +89 -0
- package/node_modules/@luxusai/pi-hindsight/docs/adr/005-domain-banks-and-agent-first-surface.md +189 -0
- package/node_modules/@luxusai/pi-hindsight/docs/assets/logos/pi-hindsight-logo-dark.webp +0 -0
- package/node_modules/@luxusai/pi-hindsight/docs/assets/logos/pi-hindsight-logo-dark@2x.webp +0 -0
- package/node_modules/@luxusai/pi-hindsight/docs/coding-memory-evaluation.md +54 -0
- package/node_modules/@luxusai/pi-hindsight/docs/compatibility.md +75 -0
- package/node_modules/@luxusai/pi-hindsight/docs/hindsight-core-functions.md +300 -0
- package/node_modules/@luxusai/pi-hindsight/docs/mission-and-mental-model-quality.md +158 -0
- package/node_modules/@luxusai/pi-hindsight/docs/next-opt-out-design.md +164 -0
- package/node_modules/@luxusai/pi-hindsight/docs/risky-memory-modes.md +139 -0
- package/node_modules/@luxusai/pi-hindsight/docs/starter-mental-model-suggestions.md +74 -0
- package/node_modules/@luxusai/pi-hindsight/docs/surface-reference.md +261 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-operations.ts +151 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-selection.ts +18 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-settings-presenter.ts +46 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-templates.ts +383 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/banking.ts +240 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/knowledge-page-seed.ts +176 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/retain-strategies.ts +178 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/client/client-retry.ts +41 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/client/client.ts +386 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/client/fetch-compat.ts +39 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/client/timeout.ts +34 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-defaults.ts +140 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-editing-model.ts +61 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-editing-registry.ts +925 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-field-paths.ts +247 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-normalize.ts +547 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-writer.ts +480 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config.ts +182 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/config/setup-gate.ts +86 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-execute.ts +1010 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-parse.ts +175 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-plan.ts +425 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-presentation.ts +210 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-sessions.ts +817 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/index.ts +25 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/git-seed.ts +319 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-recall.ts +196 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-retain.ts +189 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-runtime.ts +65 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle.ts +260 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/mental-models.ts +244 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/observation-scopes.ts +59 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall-cleanup.ts +82 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall-visibility.ts +45 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall.ts +331 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-cursor.ts +354 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-job-builder.ts +66 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-receipts.ts +132 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain.ts +228 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-bank-template-operations.ts +74 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-config-operations.ts +16 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-control-operations.ts +648 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-diagnostics-operations.ts +105 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-identity.ts +68 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-operation-service.ts +71 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-operation-types.ts +13 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-recall-operations.ts +162 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-retain-operations.ts +131 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-scope.ts +104 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-session-operations.ts +37 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/operation-catalog.ts +893 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/reflect-presenter.ts +35 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/scope-migrate.ts +177 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/tools.ts +7 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/flush-presenter.ts +21 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/jsonl-queue-store.ts +112 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-delivery.ts +111 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-lock.ts +214 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-operations.ts +70 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue.ts +392 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/bank-template-presentation.ts +45 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/commands.ts +9 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/guided-setup.ts +860 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/prefill-input.ts +105 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-flow.ts +189 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-server-probe.ts +299 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-actions.ts +201 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-facts.ts +47 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-render.ts +239 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-types.ts +50 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui.ts +259 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/tool-presenters.ts +77 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/types.ts +534 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/diagnostics.ts +319 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/messages.ts +325 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/sanitize.ts +42 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/session-memory-meta.ts +244 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/session-operations.ts +56 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/session.ts +50 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/status-fields.ts +167 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/status-health.ts +207 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/status.ts +120 -0
- package/node_modules/@luxusai/pi-hindsight/extensions/version.ts +8 -0
- package/node_modules/@luxusai/pi-hindsight/package.json +118 -0
- package/node_modules/@luxusai/pi-hindsight/skills/hindsight-memory-doctor/SKILL.md +75 -0
- package/node_modules/@narumitw/pi-btw/package.json +2 -2
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +13 -0
- package/node_modules/pi-mcp-adapter/config.ts +10 -0
- package/node_modules/pi-mcp-adapter/dist/config.js +10 -0
- package/node_modules/pi-mcp-adapter/dist/config.js.map +1 -1
- package/node_modules/pi-mcp-adapter/init.ts +5 -1
- package/node_modules/pi-mcp-adapter/package.json +1 -1
- package/package.json +10 -4
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
export type ImportDocumentSummaryResult = {
|
|
2
|
+
documents: {
|
|
3
|
+
updateMode: string;
|
|
4
|
+
status: string;
|
|
5
|
+
rawMessageCount?: number;
|
|
6
|
+
messageCount?: number;
|
|
7
|
+
projectedMessageCount?: number;
|
|
8
|
+
rawBytes?: number;
|
|
9
|
+
projectedBytes?: number;
|
|
10
|
+
droppedToolResultCount?: number;
|
|
11
|
+
droppedToolResultBytes?: number;
|
|
12
|
+
droppedTools?: Array<{ name: string; count: number; bytes: number }>;
|
|
13
|
+
topDroppedTools?: Array<{ name: string; count: number; bytes: number }>;
|
|
14
|
+
keptToolErrorCount?: number;
|
|
15
|
+
keptToolErrorBytes?: number;
|
|
16
|
+
classificationReasonCounts?: Record<string, number>;
|
|
17
|
+
estimatedDocumentCount?: number;
|
|
18
|
+
estimatedChunkCount?: number;
|
|
19
|
+
importMode?: "curated" | "raw" | "forensic";
|
|
20
|
+
importQualityProfile?: "compatible" | "strict";
|
|
21
|
+
skipReason?: "already-imported" | "empty-curated-projection";
|
|
22
|
+
}[];
|
|
23
|
+
malformedLineCount?: number;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export type ImportSessionPresentationResult = ImportDocumentSummaryResult & {
|
|
27
|
+
dryRun: boolean;
|
|
28
|
+
messageCount: number;
|
|
29
|
+
checkpointPath: string;
|
|
30
|
+
manifestPath: string;
|
|
31
|
+
documentId?: string;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export type ImportProjectPresentationResult = {
|
|
35
|
+
dryRun: boolean;
|
|
36
|
+
sessionFiles: string[];
|
|
37
|
+
scanned: number;
|
|
38
|
+
documentCount: number;
|
|
39
|
+
messageCount: number;
|
|
40
|
+
malformedLineCount: number;
|
|
41
|
+
imported?: Array<{ documents: ImportDocumentSummaryResult["documents"] }>;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
function sumReasonCounts(
|
|
45
|
+
documents: ImportDocumentSummaryResult["documents"],
|
|
46
|
+
): Record<string, number> {
|
|
47
|
+
const counts: Record<string, number> = {};
|
|
48
|
+
for (const document of documents) {
|
|
49
|
+
for (const [reason, count] of Object.entries(document.classificationReasonCounts ?? {})) {
|
|
50
|
+
counts[reason] = (counts[reason] ?? 0) + count;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return counts;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function formatReasonCounts(counts: Record<string, number>): string {
|
|
57
|
+
return Object.entries(counts)
|
|
58
|
+
.filter((entry): entry is [string, number] => entry[1] > 0)
|
|
59
|
+
.sort(
|
|
60
|
+
([leftReason, leftCount], [rightReason, rightCount]) =>
|
|
61
|
+
rightCount - leftCount || leftReason.localeCompare(rightReason),
|
|
62
|
+
)
|
|
63
|
+
.map(([reason, count]) => `${reason}:${count}`)
|
|
64
|
+
.join(",");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const KEPT_SIGNAL_REASON_CATEGORIES = [
|
|
68
|
+
{ label: "user", reasons: ["user-text"] },
|
|
69
|
+
{ label: "assistant", reasons: ["assistant-text"] },
|
|
70
|
+
{ label: "tool-errors", reasons: ["tool-error-kept"] },
|
|
71
|
+
{ label: "workflow", reasons: ["message-kept"] },
|
|
72
|
+
] as const;
|
|
73
|
+
|
|
74
|
+
const DROPPED_NOISE_REASON_CATEGORIES = [
|
|
75
|
+
{ label: "successful-tools", reasons: ["successful-tool-output", "tool-filter-excluded"] },
|
|
76
|
+
{ label: "recalled-memory", reasons: ["recalled-memory"] },
|
|
77
|
+
{ label: "ui/process", reasons: ["ui-noise", "process-noise"] },
|
|
78
|
+
{ label: "oversized/repeated", reasons: ["oversized-output", "repeated-output"] },
|
|
79
|
+
{ label: "empty", reasons: ["tool-result-empty", "empty-projection"] },
|
|
80
|
+
] as const;
|
|
81
|
+
|
|
82
|
+
function formatReasonCategoryCounts(
|
|
83
|
+
counts: Record<string, number>,
|
|
84
|
+
categories: readonly { label: string; reasons: readonly string[] }[],
|
|
85
|
+
): string {
|
|
86
|
+
return categories
|
|
87
|
+
.map(({ label, reasons }) => {
|
|
88
|
+
const count = reasons.reduce((total, reason) => total + (counts[reason] ?? 0), 0);
|
|
89
|
+
return count > 0 ? `${label}:${count}` : undefined;
|
|
90
|
+
})
|
|
91
|
+
.filter((entry): entry is string => Boolean(entry))
|
|
92
|
+
.join(",");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function formatTopDroppedTools(documents: ImportDocumentSummaryResult["documents"]): string {
|
|
96
|
+
const totals = new Map<string, { count: number; bytes: number }>();
|
|
97
|
+
for (const document of documents) {
|
|
98
|
+
for (const tool of document.droppedTools ?? document.topDroppedTools ?? []) {
|
|
99
|
+
const current = totals.get(tool.name) ?? { count: 0, bytes: 0 };
|
|
100
|
+
totals.set(tool.name, {
|
|
101
|
+
count: current.count + tool.count,
|
|
102
|
+
bytes: current.bytes + tool.bytes,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return [...totals]
|
|
107
|
+
.map(([name, value]) => ({ name, ...value }))
|
|
108
|
+
.sort(
|
|
109
|
+
(left, right) =>
|
|
110
|
+
right.bytes - left.bytes || right.count - left.count || left.name.localeCompare(right.name),
|
|
111
|
+
)
|
|
112
|
+
.slice(0, 3)
|
|
113
|
+
.map((tool) => `${tool.name}:${tool.count}`)
|
|
114
|
+
.join(",");
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function importDocumentQualitySummary(result: ImportDocumentSummaryResult): string {
|
|
118
|
+
const rawMessages = result.documents.reduce(
|
|
119
|
+
(count, document) => count + (document.rawMessageCount ?? document.messageCount ?? 0),
|
|
120
|
+
0,
|
|
121
|
+
);
|
|
122
|
+
const projectedMessages = result.documents.reduce(
|
|
123
|
+
(count, document) => count + (document.projectedMessageCount ?? document.messageCount ?? 0),
|
|
124
|
+
0,
|
|
125
|
+
);
|
|
126
|
+
const droppedToolResults = result.documents.reduce(
|
|
127
|
+
(count, document) => count + (document.droppedToolResultCount ?? 0),
|
|
128
|
+
0,
|
|
129
|
+
);
|
|
130
|
+
const rawBytes = result.documents.reduce(
|
|
131
|
+
(count, document) => count + (document.rawBytes ?? 0),
|
|
132
|
+
0,
|
|
133
|
+
);
|
|
134
|
+
const projectedBytes = result.documents.reduce(
|
|
135
|
+
(count, document) => count + (document.projectedBytes ?? 0),
|
|
136
|
+
0,
|
|
137
|
+
);
|
|
138
|
+
const keptErrors = result.documents.reduce(
|
|
139
|
+
(count, document) => count + (document.keptToolErrorCount ?? 0),
|
|
140
|
+
0,
|
|
141
|
+
);
|
|
142
|
+
const estimatedChunks = result.documents.reduce(
|
|
143
|
+
(count, document) => count + (document.estimatedChunkCount ?? 0),
|
|
144
|
+
0,
|
|
145
|
+
);
|
|
146
|
+
const importModes = [
|
|
147
|
+
...new Set(result.documents.map((document) => document.importMode).filter(Boolean)),
|
|
148
|
+
].join(",");
|
|
149
|
+
const importProfiles = [
|
|
150
|
+
...new Set(
|
|
151
|
+
result.documents
|
|
152
|
+
.map((document) => document.importQualityProfile)
|
|
153
|
+
.filter((profile): profile is "strict" => profile === "strict"),
|
|
154
|
+
),
|
|
155
|
+
].join(",");
|
|
156
|
+
const summedReasonCounts = sumReasonCounts(result.documents);
|
|
157
|
+
const keptSignals = formatReasonCategoryCounts(summedReasonCounts, KEPT_SIGNAL_REASON_CATEGORIES);
|
|
158
|
+
const droppedNoise = formatReasonCategoryCounts(
|
|
159
|
+
summedReasonCounts,
|
|
160
|
+
DROPPED_NOISE_REASON_CATEGORIES,
|
|
161
|
+
);
|
|
162
|
+
const reasonCounts = formatReasonCounts(summedReasonCounts);
|
|
163
|
+
const topDroppedTools = formatTopDroppedTools(result.documents);
|
|
164
|
+
const skipReasons = [
|
|
165
|
+
...new Set(result.documents.map((document) => document.skipReason).filter(Boolean)),
|
|
166
|
+
].join(",");
|
|
167
|
+
const forensicWarning = importModes.includes("forensic")
|
|
168
|
+
? "; WARNING forensic mode preserves recalled memory blocks for audit-only use"
|
|
169
|
+
: "";
|
|
170
|
+
const qualityDetails = `${keptSignals ? `; keptSignals=${keptSignals}` : ""}${droppedNoise ? `; droppedNoise=${droppedNoise}` : ""}${reasonCounts ? `; reasons=${reasonCounts}` : ""}${topDroppedTools ? `; topDroppedTools=${topDroppedTools}` : ""}`;
|
|
171
|
+
return rawMessages || droppedToolResults || rawBytes || projectedBytes || skipReasons
|
|
172
|
+
? `; mode=${importModes || "unknown"}${importProfiles ? `; profile=${importProfiles}` : ""}; projected=${projectedMessages}/${rawMessages || projectedMessages} messages; droppedToolResults=${droppedToolResults}; keptToolErrors=${keptErrors}; estimatedChunks=${estimatedChunks}; bytes=${projectedBytes}/${rawBytes}${qualityDetails}${skipReasons ? `; skipReasons=${skipReasons}` : ""}${forensicWarning}`
|
|
173
|
+
: "";
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export function importDocumentSummary(result: ImportDocumentSummaryResult): string {
|
|
177
|
+
const modes = [...new Set(result.documents.map((document) => document.updateMode))].join(",");
|
|
178
|
+
const statuses = [...new Set(result.documents.map((document) => document.status))].join(",");
|
|
179
|
+
const malformed = result.malformedLineCount
|
|
180
|
+
? `; malformedLines=${result.malformedLineCount}`
|
|
181
|
+
: "";
|
|
182
|
+
return `documents=${result.documents.length}; update=${modes || "n/a"}; status=${statuses || "n/a"}${malformed}${importDocumentQualitySummary(result)}`;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export function renderImportSessionMessage(
|
|
186
|
+
result: ImportSessionPresentationResult,
|
|
187
|
+
source: "default" | "current" | { file: string } = "default",
|
|
188
|
+
): string {
|
|
189
|
+
const sourceLabel =
|
|
190
|
+
source === "current"
|
|
191
|
+
? "current session"
|
|
192
|
+
: typeof source === "object"
|
|
193
|
+
? `file=${source.file}`
|
|
194
|
+
: "";
|
|
195
|
+
const prefix = result.dryRun
|
|
196
|
+
? `Import preview${sourceLabel ? `: ${sourceLabel}` : ""}`
|
|
197
|
+
: `Imported${sourceLabel ? ` ${sourceLabel}` : ""}`;
|
|
198
|
+
return result.dryRun
|
|
199
|
+
? `${prefix}; messages=${result.messageCount}; ${importDocumentSummary(result)}; write=no; checkpoint=${result.checkpointPath}; manifest unchanged=${result.manifestPath}`
|
|
200
|
+
: `${prefix}; messages=${result.messageCount}; ${importDocumentSummary(result)}; first=${result.documentId}${source === "default" ? `; manifest=${result.manifestPath}` : ""}`;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export function renderProjectImportMessage(result: ImportProjectPresentationResult): string {
|
|
204
|
+
const documents = result.imported?.flatMap((session) => session.documents) ?? [];
|
|
205
|
+
const quality = documents.length ? importDocumentQualitySummary({ documents }) : "";
|
|
206
|
+
const summary = `sessions=${result.sessionFiles.length}/${result.scanned}; documents=${result.documentCount}; messages=${result.messageCount}; malformedLines=${result.malformedLineCount}${quality}`;
|
|
207
|
+
return result.dryRun
|
|
208
|
+
? `Project import preview: ${summary}; write=no`
|
|
209
|
+
: `Imported project sessions: ${summary}`;
|
|
210
|
+
}
|