pi-goosedump 0.13.7 → 0.13.9
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.ts +73 -19
- package/package.json +2 -2
package/dist/index.ts
CHANGED
|
@@ -725,6 +725,7 @@ import {
|
|
|
725
725
|
mkdirSync,
|
|
726
726
|
readFileSync as readFileSync3,
|
|
727
727
|
renameSync,
|
|
728
|
+
statSync as statSync2,
|
|
728
729
|
unlinkSync,
|
|
729
730
|
writeFileSync
|
|
730
731
|
} from "node:fs";
|
|
@@ -851,7 +852,26 @@ function validateGoosedumpSettings(path) {
|
|
|
851
852
|
}
|
|
852
853
|
var isNumberValue = (value) => typeof value === "number";
|
|
853
854
|
var isBooleanValue = (value) => typeof value === "boolean";
|
|
855
|
+
var settingsCache = null;
|
|
856
|
+
function settingsStamp(path) {
|
|
857
|
+
try {
|
|
858
|
+
const stat = statSync2(path);
|
|
859
|
+
return `${stat.mtimeMs}:${stat.size}:${stat.ino}`;
|
|
860
|
+
} catch {
|
|
861
|
+
return "missing";
|
|
862
|
+
}
|
|
863
|
+
}
|
|
854
864
|
function resolveWorkspaceSettings(cwd, includeProject) {
|
|
865
|
+
const globalPath = globalSettingsPath();
|
|
866
|
+
const projectPath = includeProject ? projectSettingsPath(cwd) : undefined;
|
|
867
|
+
const key = `${globalPath}|${settingsStamp(globalPath)}|${projectPath ?? ""}|${projectPath ? settingsStamp(projectPath) : ""}`;
|
|
868
|
+
if (settingsCache?.key === key)
|
|
869
|
+
return settingsCache.value;
|
|
870
|
+
const value = computeWorkspaceSettings(cwd, includeProject);
|
|
871
|
+
settingsCache = { key, value };
|
|
872
|
+
return value;
|
|
873
|
+
}
|
|
874
|
+
function computeWorkspaceSettings(cwd, includeProject) {
|
|
855
875
|
const globalObj = readJsonObject(globalSettingsPath());
|
|
856
876
|
const projectObj = includeProject ? readJsonObject(projectSettingsPath(cwd)) : undefined;
|
|
857
877
|
const goosedump = {
|
|
@@ -905,6 +925,7 @@ function updateScopedGoosedumpSetting(cwd, scope, update) {
|
|
|
905
925
|
delete root.goosedump;
|
|
906
926
|
else
|
|
907
927
|
root.goosedump = next;
|
|
928
|
+
settingsCache = null;
|
|
908
929
|
writeJsonObjectAtomically(path, root);
|
|
909
930
|
}
|
|
910
931
|
function readScopedGoosedumpSettings(cwd, scope) {
|
|
@@ -983,12 +1004,22 @@ function latestCompaction(branchEntries) {
|
|
|
983
1004
|
}
|
|
984
1005
|
return;
|
|
985
1006
|
}
|
|
1007
|
+
|
|
1008
|
+
class BranchPositions {
|
|
1009
|
+
positions = new Map;
|
|
1010
|
+
constructor(branchEntries) {
|
|
1011
|
+
branchEntries.forEach((entry, index) => this.positions.set(entry.id, index));
|
|
1012
|
+
}
|
|
1013
|
+
boundaryStartIndex(compaction) {
|
|
1014
|
+
const kept = this.positions.get(compaction.firstKeptEntryId);
|
|
1015
|
+
if (kept !== undefined)
|
|
1016
|
+
return kept;
|
|
1017
|
+
const own = this.positions.get(compaction.id);
|
|
1018
|
+
return own !== undefined ? own + 1 : 0;
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
986
1021
|
function compactionBoundaryStartIndex(branchEntries, compaction) {
|
|
987
|
-
|
|
988
|
-
if (keptIndex >= 0)
|
|
989
|
-
return keptIndex;
|
|
990
|
-
const compactionIndex = branchEntries.findIndex((entry) => entry.id === compaction.id);
|
|
991
|
-
return compactionIndex >= 0 ? compactionIndex + 1 : 0;
|
|
1022
|
+
return new BranchPositions(branchEntries).boundaryStartIndex(compaction);
|
|
992
1023
|
}
|
|
993
1024
|
function activeHistoryStartIndex(branchEntries) {
|
|
994
1025
|
const compaction = latestCompaction(branchEntries);
|
|
@@ -1022,12 +1053,13 @@ function buildCompactRange(branchEntries, firstKeptEntryId) {
|
|
|
1022
1053
|
const untilIndex = branchEntries.findIndex((entry) => entry.id === firstKeptEntryId);
|
|
1023
1054
|
if (untilIndex < 0)
|
|
1024
1055
|
return;
|
|
1056
|
+
const positions = new BranchPositions(branchEntries);
|
|
1025
1057
|
let from;
|
|
1026
1058
|
for (let i = Math.min(untilIndex - 1, branchEntries.length - 1);i >= 0; i -= 1) {
|
|
1027
1059
|
const entry = branchEntries[i];
|
|
1028
1060
|
if (!isCompactionEntry(entry))
|
|
1029
1061
|
continue;
|
|
1030
|
-
const boundaryStart =
|
|
1062
|
+
const boundaryStart = positions.boundaryStartIndex(entry);
|
|
1031
1063
|
if (boundaryStart < untilIndex) {
|
|
1032
1064
|
from = branchEntries[boundaryStart]?.id;
|
|
1033
1065
|
break;
|
|
@@ -2406,6 +2438,7 @@ ${formattedContent}` : summary;
|
|
|
2406
2438
|
var renderGooseSessionsResult = renderGooseDumpSessionsResult;
|
|
2407
2439
|
|
|
2408
2440
|
// src/tools.ts
|
|
2441
|
+
var MAX_ENTRY_IDS = 50;
|
|
2409
2442
|
function memoryDisabledResult() {
|
|
2410
2443
|
return textResult(MEMORY_DISABLED_MESSAGE);
|
|
2411
2444
|
}
|
|
@@ -2600,6 +2633,7 @@ ${text}`);
|
|
|
2600
2633
|
registerPair("goosedump_get", "goose_get", Type3.Object({
|
|
2601
2634
|
ids: Type3.Array(Type3.String(), {
|
|
2602
2635
|
minItems: 1,
|
|
2636
|
+
maxItems: MAX_ENTRY_IDS,
|
|
2603
2637
|
description: PARAM_DESCRIPTIONS.entryIds
|
|
2604
2638
|
}),
|
|
2605
2639
|
...historyBranchParams()
|
|
@@ -3025,12 +3059,13 @@ async function runSettingsEditor(ctx) {
|
|
|
3025
3059
|
async function runSearchPanel(ctx, query, executablePath) {
|
|
3026
3060
|
const OVERLAY_WIDTH = 84;
|
|
3027
3061
|
const VIEWPORT = 18;
|
|
3028
|
-
const
|
|
3062
|
+
const MAX_PAGES = 10;
|
|
3029
3063
|
const wrapWidth = OVERLAY_WIDTH - 4;
|
|
3030
3064
|
await ctx.ui.custom((tui, theme, _kb, done) => {
|
|
3031
3065
|
const target = currentSessionTarget(ctx);
|
|
3032
3066
|
const colors = overlayColors(theme);
|
|
3033
3067
|
let entries = [];
|
|
3068
|
+
const snippets = new WeakMap;
|
|
3034
3069
|
let error = null;
|
|
3035
3070
|
let mode = "results";
|
|
3036
3071
|
let selected = 0;
|
|
@@ -3038,9 +3073,11 @@ async function runSearchPanel(ctx, query, executablePath) {
|
|
|
3038
3073
|
let detailLines = [];
|
|
3039
3074
|
let detailScroll = 0;
|
|
3040
3075
|
let detailEntry = null;
|
|
3076
|
+
let truncated = false;
|
|
3077
|
+
const controller = new AbortController;
|
|
3041
3078
|
async function runSearch() {
|
|
3042
3079
|
try {
|
|
3043
|
-
const first = await goosedumpSearch(target, query, { scope: "lineage", page: 1 },
|
|
3080
|
+
const first = await goosedumpSearch(target, query, { scope: "lineage", page: 1 }, controller.signal, executablePath);
|
|
3044
3081
|
if (first.length === 0) {
|
|
3045
3082
|
entries = [];
|
|
3046
3083
|
error = `No results for "${query}"`;
|
|
@@ -3048,22 +3085,34 @@ async function runSearchPanel(ctx, query, executablePath) {
|
|
|
3048
3085
|
scroll = 0;
|
|
3049
3086
|
return;
|
|
3050
3087
|
}
|
|
3088
|
+
const search = (page) => goosedumpSearch(target, query, { scope: "lineage", page }, controller.signal, executablePath);
|
|
3051
3089
|
const all = [...first];
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
all.push(...
|
|
3057
|
-
|
|
3058
|
-
|
|
3090
|
+
let lastPage = 1;
|
|
3091
|
+
let complete = false;
|
|
3092
|
+
const second = await search(2);
|
|
3093
|
+
if (second.length < first.length) {
|
|
3094
|
+
all.push(...second);
|
|
3095
|
+
complete = true;
|
|
3096
|
+
} else {
|
|
3097
|
+
all.push(...second);
|
|
3098
|
+
const rest = await Promise.all(Array.from({ length: MAX_PAGES - 2 }, (_unused, index) => search(index + 3)));
|
|
3099
|
+
for (const [index, page] of rest.entries()) {
|
|
3100
|
+
all.push(...page);
|
|
3101
|
+
lastPage = index + 3;
|
|
3102
|
+
if (page.length < first.length) {
|
|
3103
|
+
complete = true;
|
|
3104
|
+
break;
|
|
3105
|
+
}
|
|
3106
|
+
}
|
|
3059
3107
|
}
|
|
3108
|
+
truncated = !complete && lastPage >= MAX_PAGES;
|
|
3060
3109
|
entries = all;
|
|
3061
3110
|
error = null;
|
|
3062
3111
|
selected = 0;
|
|
3063
3112
|
scroll = 0;
|
|
3064
3113
|
} catch (err) {
|
|
3065
3114
|
entries = [];
|
|
3066
|
-
error = err instanceof Error ? err.message : String(err);
|
|
3115
|
+
error = controller.signal.aborted ? "Search cancelled." : err instanceof Error ? err.message : String(err);
|
|
3067
3116
|
} finally {
|
|
3068
3117
|
tui.requestRender();
|
|
3069
3118
|
}
|
|
@@ -3075,7 +3124,7 @@ async function runSearchPanel(ctx, query, executablePath) {
|
|
|
3075
3124
|
}
|
|
3076
3125
|
async function loadDetail(id) {
|
|
3077
3126
|
try {
|
|
3078
|
-
const messages = await goosedumpShow(target, { ids: [id] },
|
|
3127
|
+
const messages = await goosedumpShow(target, { ids: [id] }, controller.signal, executablePath);
|
|
3079
3128
|
const msg = messages.length > 0 ? messages[0] : null;
|
|
3080
3129
|
detailEntry = msg;
|
|
3081
3130
|
const entryHeader = msg ? `${colors.accent(colors.bold(`[${msg.id}]`))} ${colors.muted(`${msg.role}:`)}` : "";
|
|
@@ -3106,11 +3155,15 @@ async function runSearchPanel(ctx, query, executablePath) {
|
|
|
3106
3155
|
}
|
|
3107
3156
|
return [
|
|
3108
3157
|
header,
|
|
3109
|
-
...overlayViewport(colors, width, entries, scroll, VIEWPORT, "↑↓ navigate enter expand esc close", (count) => `entr${count === 1 ? "y" : "ies"}`, (entry, absolute) => {
|
|
3158
|
+
...overlayViewport(colors, width, entries, scroll, VIEWPORT, truncated ? `first ${entries.length} results ↑↓ navigate enter expand esc close` : "↑↓ navigate enter expand esc close", (count) => `entr${count === 1 ? "y" : "ies"}`, (entry, absolute) => {
|
|
3110
3159
|
const isSelected = absolute === selected;
|
|
3111
3160
|
const cursor = isSelected ? colors.accent(colors.bold("▶")) : " ";
|
|
3112
3161
|
const idText = isSelected ? colors.accent(colors.bold(entry.id)) : colors.text(entry.id);
|
|
3113
|
-
|
|
3162
|
+
let snippet = snippets.get(entry);
|
|
3163
|
+
if (snippet === undefined) {
|
|
3164
|
+
snippet = Buffer.from(compactLine(entry.content), "utf16le").toString("utf16le");
|
|
3165
|
+
snippets.set(entry, snippet);
|
|
3166
|
+
}
|
|
3114
3167
|
return ` ${cursor} ${idText} ${colors.muted(entry.role)} ${colors.dim(snippet)}`;
|
|
3115
3168
|
}),
|
|
3116
3169
|
overlayFooter(colors, width)
|
|
@@ -3123,6 +3176,7 @@ async function runSearchPanel(ctx, query, executablePath) {
|
|
|
3123
3176
|
tui.requestRender();
|
|
3124
3177
|
return;
|
|
3125
3178
|
}
|
|
3179
|
+
controller.abort();
|
|
3126
3180
|
done(undefined);
|
|
3127
3181
|
return;
|
|
3128
3182
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-goosedump",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.9",
|
|
4
4
|
"description": "Pi extension for goosedump session search, durable memory, session management, and compaction",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"compaction",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"ci:test": "npm test"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@jarkkojs/goosedump": "^0.13.
|
|
40
|
+
"@jarkkojs/goosedump": "^0.13.9"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@earendil-works/pi-coding-agent": "^0.84.2",
|