pi-goosedump 0.4.0 → 0.5.0
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/index.ts +115 -4
- package/package.json +2 -2
package/index.ts
CHANGED
|
@@ -23,10 +23,11 @@ import { Type } from '@sinclair/typebox';
|
|
|
23
23
|
|
|
24
24
|
const require = createRequire(import.meta.url);
|
|
25
25
|
|
|
26
|
-
const GOOSEDUMP_VERSION = [0,
|
|
26
|
+
const GOOSEDUMP_VERSION = [0, 5, 0] as const;
|
|
27
27
|
|
|
28
28
|
interface GoosedumpListing {
|
|
29
29
|
id: string;
|
|
30
|
+
path: string | null;
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
interface GoosedumpMessage {
|
|
@@ -44,7 +45,7 @@ interface GoosedumpContextResult {
|
|
|
44
45
|
}
|
|
45
46
|
|
|
46
47
|
interface ListJson {
|
|
47
|
-
sessions: { id: string }[];
|
|
48
|
+
sessions: { id: string; path?: string | null }[];
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
interface ToolCallJson {
|
|
@@ -240,7 +241,10 @@ function runGoosedump(args: string[]): string {
|
|
|
240
241
|
|
|
241
242
|
function goosedumpList(): GoosedumpListing[] {
|
|
242
243
|
const json = JSON.parse(runGoosedump(['list', 'pi:*'])) as ListJson;
|
|
243
|
-
return (json.sessions ?? []).map((session) => ({
|
|
244
|
+
return (json.sessions ?? []).map((session) => ({
|
|
245
|
+
id: session.id,
|
|
246
|
+
path: session.path ?? null,
|
|
247
|
+
}));
|
|
244
248
|
}
|
|
245
249
|
|
|
246
250
|
function goosedumpContext(
|
|
@@ -941,9 +945,17 @@ export function createGoosedumpIntegration(
|
|
|
941
945
|
return;
|
|
942
946
|
}
|
|
943
947
|
|
|
948
|
+
let resumePath: string | null | undefined;
|
|
949
|
+
|
|
944
950
|
await ctx.ui.custom<void>(
|
|
945
951
|
(tui, theme, _kb, done) => {
|
|
946
952
|
let selectedIndex = 0;
|
|
953
|
+
let mode: 'list' | 'compact' = 'list';
|
|
954
|
+
let compactLines: string[] = [];
|
|
955
|
+
let compactScroll = 0;
|
|
956
|
+
let compactTitle = '';
|
|
957
|
+
|
|
958
|
+
const COMPACT_VIEWPORT = 20;
|
|
947
959
|
|
|
948
960
|
return {
|
|
949
961
|
render(width: number): string[] {
|
|
@@ -957,6 +969,39 @@ export function createGoosedumpIntegration(
|
|
|
957
969
|
|
|
958
970
|
const lines: string[] = [];
|
|
959
971
|
|
|
972
|
+
if (mode === 'compact') {
|
|
973
|
+
const title = accent(` Compact: ${truncateToWidth(compactTitle, 40)} `);
|
|
974
|
+
const topFill = borderFg(
|
|
975
|
+
'─'.repeat(Math.max(0, width - 4 - visibleWidth(title))),
|
|
976
|
+
);
|
|
977
|
+
lines.push(`${borderFg('╭─')}${title}${topFill}${borderFg('─╮')}`);
|
|
978
|
+
|
|
979
|
+
const total = compactLines.length;
|
|
980
|
+
const maxScroll = Math.max(0, total - COMPACT_VIEWPORT);
|
|
981
|
+
if (compactScroll > maxScroll) compactScroll = maxScroll;
|
|
982
|
+
const window = compactLines.slice(
|
|
983
|
+
compactScroll,
|
|
984
|
+
compactScroll + COMPACT_VIEWPORT,
|
|
985
|
+
);
|
|
986
|
+
for (const row of window) {
|
|
987
|
+
lines.push(makeRow(text(truncateToWidth(row, innerW)), innerW, border));
|
|
988
|
+
}
|
|
989
|
+
for (let i = window.length; i < COMPACT_VIEWPORT; i++) {
|
|
990
|
+
lines.push(makeRow('', innerW, border));
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
const position =
|
|
994
|
+
total > COMPACT_VIEWPORT
|
|
995
|
+
? `${compactScroll + 1}-${Math.min(compactScroll + COMPACT_VIEWPORT, total)} of ${total}`
|
|
996
|
+
: `${total} line${total === 1 ? '' : 's'}`;
|
|
997
|
+
lines.push(makeRow('', innerW, border));
|
|
998
|
+
lines.push(makeRow(dim(`↑↓ scroll esc back (${position})`), innerW, border));
|
|
999
|
+
lines.push(
|
|
1000
|
+
`${borderFg('╰')}${borderFg('─'.repeat(width - 2))}${borderFg('╯')}`,
|
|
1001
|
+
);
|
|
1002
|
+
return lines;
|
|
1003
|
+
}
|
|
1004
|
+
|
|
960
1005
|
// Top border
|
|
961
1006
|
const title = accent(' Goosedump Sessions ');
|
|
962
1007
|
const topFill = borderFg(
|
|
@@ -989,7 +1034,13 @@ export function createGoosedumpIntegration(
|
|
|
989
1034
|
|
|
990
1035
|
// Footer
|
|
991
1036
|
lines.push(makeRow('', innerW, border));
|
|
992
|
-
lines.push(
|
|
1037
|
+
lines.push(
|
|
1038
|
+
makeRow(
|
|
1039
|
+
dim('↑↓ navigate enter compact shift+enter resume esc close'),
|
|
1040
|
+
innerW,
|
|
1041
|
+
border,
|
|
1042
|
+
),
|
|
1043
|
+
);
|
|
993
1044
|
|
|
994
1045
|
// Bottom border
|
|
995
1046
|
lines.push(`${borderFg('╰')}${borderFg('─'.repeat(width - 2))}${borderFg('╯')}`);
|
|
@@ -998,6 +1049,35 @@ export function createGoosedumpIntegration(
|
|
|
998
1049
|
},
|
|
999
1050
|
|
|
1000
1051
|
handleInput(data: string): void {
|
|
1052
|
+
if (mode === 'compact') {
|
|
1053
|
+
if (matchesKey(data, Key.escape) || matchesKey(data, Key.ctrl('c'))) {
|
|
1054
|
+
mode = 'list';
|
|
1055
|
+
tui.requestRender();
|
|
1056
|
+
return;
|
|
1057
|
+
}
|
|
1058
|
+
if (matchesKey(data, Key.up)) {
|
|
1059
|
+
compactScroll = Math.max(0, compactScroll - 1);
|
|
1060
|
+
tui.requestRender();
|
|
1061
|
+
return;
|
|
1062
|
+
}
|
|
1063
|
+
if (matchesKey(data, Key.down)) {
|
|
1064
|
+
compactScroll += 1;
|
|
1065
|
+
tui.requestRender();
|
|
1066
|
+
return;
|
|
1067
|
+
}
|
|
1068
|
+
if (matchesKey(data, Key.pageUp)) {
|
|
1069
|
+
compactScroll = Math.max(0, compactScroll - COMPACT_VIEWPORT);
|
|
1070
|
+
tui.requestRender();
|
|
1071
|
+
return;
|
|
1072
|
+
}
|
|
1073
|
+
if (matchesKey(data, Key.pageDown)) {
|
|
1074
|
+
compactScroll += COMPACT_VIEWPORT;
|
|
1075
|
+
tui.requestRender();
|
|
1076
|
+
return;
|
|
1077
|
+
}
|
|
1078
|
+
return;
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1001
1081
|
if (matchesKey(data, Key.escape) || matchesKey(data, Key.ctrl('c'))) {
|
|
1002
1082
|
done(undefined);
|
|
1003
1083
|
return;
|
|
@@ -1014,6 +1094,31 @@ export function createGoosedumpIntegration(
|
|
|
1014
1094
|
tui.requestRender();
|
|
1015
1095
|
return;
|
|
1016
1096
|
}
|
|
1097
|
+
|
|
1098
|
+
if (matchesKey(data, Key.shift(Key.enter))) {
|
|
1099
|
+
resumePath = listings[selectedIndex]?.path;
|
|
1100
|
+
done(undefined);
|
|
1101
|
+
return;
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
if (matchesKey(data, Key.enter) || matchesKey(data, Key.return)) {
|
|
1105
|
+
const listing = listings[selectedIndex];
|
|
1106
|
+
if (!listing) return;
|
|
1107
|
+
compactTitle = listing.id;
|
|
1108
|
+
compactScroll = 0;
|
|
1109
|
+
try {
|
|
1110
|
+
const summary = goosedumpCompact(listing.id, { scope: 'lineage' }).trim();
|
|
1111
|
+
compactLines = summary
|
|
1112
|
+
? summary.split('\n')
|
|
1113
|
+
: ['No compact summary available for this session.'];
|
|
1114
|
+
} catch (err) {
|
|
1115
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1116
|
+
compactLines = [`Failed to compact session: ${msg}`];
|
|
1117
|
+
}
|
|
1118
|
+
mode = 'compact';
|
|
1119
|
+
tui.requestRender();
|
|
1120
|
+
return;
|
|
1121
|
+
}
|
|
1017
1122
|
},
|
|
1018
1123
|
|
|
1019
1124
|
invalidate(): void {},
|
|
@@ -1034,6 +1139,12 @@ export function createGoosedumpIntegration(
|
|
|
1034
1139
|
},
|
|
1035
1140
|
},
|
|
1036
1141
|
);
|
|
1142
|
+
|
|
1143
|
+
if (resumePath) {
|
|
1144
|
+
await ctx.switchSession(resumePath);
|
|
1145
|
+
} else if (resumePath === null) {
|
|
1146
|
+
ctx.ui.notify('Cannot resume: session file path is unavailable.', 'error');
|
|
1147
|
+
}
|
|
1037
1148
|
} catch (err) {
|
|
1038
1149
|
const message = err instanceof Error ? err.message : String(err);
|
|
1039
1150
|
ctx.ui.notify(`goosedump error: ${message}`, 'error');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-goosedump",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Coding agent context data browser plugin for pi",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"goosedump",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@earendil-works/pi-tui": "^0.78.0",
|
|
32
|
-
"@jarkkojs/goosedump": "^0.
|
|
32
|
+
"@jarkkojs/goosedump": "^0.5.0",
|
|
33
33
|
"@sinclair/typebox": "^0.34.49"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|