pi-goosedump 0.9.13 → 0.10.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/README.md +3 -0
- package/index.ts +108 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,6 +20,8 @@ If the goosedump binary cannot be resolved, the extension disables itself.
|
|
|
20
20
|
|
|
21
21
|
- **goose_search:** ranks messages by query relevance; returns compact entry
|
|
22
22
|
overviews with IDs.
|
|
23
|
+
- **goose_recall:** searches durable memory harvested from earlier compactions,
|
|
24
|
+
scoped to the current working directory by default.
|
|
23
25
|
- **goose_get:** expands specific entry IDs to their full content.
|
|
24
26
|
- **goose_grep:** filters messages by glob pattern; returns compact entries
|
|
25
27
|
with IDs.
|
|
@@ -35,6 +37,7 @@ current branch) or `all`. Targets are always provider-qualified
|
|
|
35
37
|
|
|
36
38
|
```
|
|
37
39
|
goose_search({ query: "bug fix" })
|
|
40
|
+
goose_recall({ query: "prior architecture decision" })
|
|
38
41
|
goose_search({ query: "auth", scope: "all", page: 2 })
|
|
39
42
|
goose_get({ ids: ["entry-a", "entry-b"] })
|
|
40
43
|
goose_get({ ids: ["entry-a"], provider: "claude", session: "1f6b1eba-…" })
|
package/index.ts
CHANGED
|
@@ -55,6 +55,17 @@ interface GoosedumpMessage {
|
|
|
55
55
|
content: string;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
interface GoosedumpMemoryHit {
|
|
59
|
+
hash: string;
|
|
60
|
+
kind: string;
|
|
61
|
+
text: string;
|
|
62
|
+
score: number;
|
|
63
|
+
provider: string;
|
|
64
|
+
context_id: string;
|
|
65
|
+
entry_id: string;
|
|
66
|
+
path: string;
|
|
67
|
+
}
|
|
68
|
+
|
|
58
69
|
// A `content` part of a pi-native message line.
|
|
59
70
|
interface PiPartJson {
|
|
60
71
|
type: string;
|
|
@@ -234,6 +245,32 @@ function parsePiMessages(output: string): GoosedumpMessage[] {
|
|
|
234
245
|
return messages;
|
|
235
246
|
}
|
|
236
247
|
|
|
248
|
+
function parseMemoryHits(output: string): GoosedumpMemoryHit[] {
|
|
249
|
+
const value = JSON.parse(output) as unknown;
|
|
250
|
+
if (!Array.isArray(value)) throw new Error('goosedump recall returned invalid JSON');
|
|
251
|
+
return value.filter(
|
|
252
|
+
(item): item is GoosedumpMemoryHit =>
|
|
253
|
+
isRecord(item) &&
|
|
254
|
+
typeof item.hash === 'string' &&
|
|
255
|
+
typeof item.kind === 'string' &&
|
|
256
|
+
typeof item.text === 'string' &&
|
|
257
|
+
typeof item.score === 'number' &&
|
|
258
|
+
typeof item.provider === 'string' &&
|
|
259
|
+
typeof item.context_id === 'string' &&
|
|
260
|
+
typeof item.entry_id === 'string' &&
|
|
261
|
+
typeof item.path === 'string',
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function formatMemoryHits(hits: GoosedumpMemoryHit[]): string {
|
|
266
|
+
return hits
|
|
267
|
+
.map(
|
|
268
|
+
(hit) =>
|
|
269
|
+
`[${hit.hash}] ${hit.kind} (${hit.provider}:${hit.context_id}/${hit.entry_id})\n${hit.text}`,
|
|
270
|
+
)
|
|
271
|
+
.join('\n\n---\n\n');
|
|
272
|
+
}
|
|
273
|
+
|
|
237
274
|
const ANSI_SGR = new RegExp(String.fromCharCode(27) + '\\[[0-9;]*m', 'g');
|
|
238
275
|
|
|
239
276
|
function compactLine(content: string): string {
|
|
@@ -367,6 +404,18 @@ function goosedumpShow(
|
|
|
367
404
|
return parsePiMessages(runGoosedump(args));
|
|
368
405
|
}
|
|
369
406
|
|
|
407
|
+
async function goosedumpRecall(
|
|
408
|
+
query: string,
|
|
409
|
+
options: { provider?: string; path?: string; limit?: number } = {},
|
|
410
|
+
signal?: AbortSignal,
|
|
411
|
+
): Promise<GoosedumpMemoryHit[]> {
|
|
412
|
+
const args = ['recall', query, '--limit', String(options.limit ?? 5)];
|
|
413
|
+
if (options.provider) args.push('--provider', options.provider);
|
|
414
|
+
if (options.path) args.push('--path', options.path);
|
|
415
|
+
const output = await runGoosedumpAsync(args, signal);
|
|
416
|
+
return parseMemoryHits(output);
|
|
417
|
+
}
|
|
418
|
+
|
|
370
419
|
// Resolve a goosedump 0.9 `provider:id` target. An explicit contextId is the
|
|
371
420
|
// target id already; for pi it falls back to the current session. Other
|
|
372
421
|
// providers have no current session and require an explicit id.
|
|
@@ -1169,6 +1218,65 @@ export function createGoosedumpIntegration(
|
|
|
1169
1218
|
|
|
1170
1219
|
function register(pi: ExtensionAPI): void {
|
|
1171
1220
|
if (shouldRegisterTool) {
|
|
1221
|
+
pi.registerTool(
|
|
1222
|
+
defineTool({
|
|
1223
|
+
name: 'goose_recall',
|
|
1224
|
+
label: 'goose_recall',
|
|
1225
|
+
description:
|
|
1226
|
+
'Recall durable context harvested from earlier compactions. Searches the current project by default and returns full remembered entries with provenance.',
|
|
1227
|
+
promptSnippet: 'Recall durable context from earlier sessions',
|
|
1228
|
+
promptGuidelines: [
|
|
1229
|
+
'Use goose_recall for decisions, evidence, and context that may have disappeared from the current session.',
|
|
1230
|
+
'Results include their original provider, session, entry, and working-directory provenance.',
|
|
1231
|
+
'The current project is searched by default; set allProjects only when cross-project context is appropriate.',
|
|
1232
|
+
],
|
|
1233
|
+
parameters: Type.Object({
|
|
1234
|
+
query: Type.String({ description: 'Persistent-memory search query' }),
|
|
1235
|
+
provider: Type.Optional(
|
|
1236
|
+
Type.Union(
|
|
1237
|
+
GOOSE_PROVIDERS.map((provider) => Type.Literal(provider)),
|
|
1238
|
+
{
|
|
1239
|
+
description: 'Optional source-provider filter',
|
|
1240
|
+
},
|
|
1241
|
+
),
|
|
1242
|
+
),
|
|
1243
|
+
allProjects: Type.Optional(
|
|
1244
|
+
Type.Boolean({
|
|
1245
|
+
default: false,
|
|
1246
|
+
description: 'Search memory from every working directory',
|
|
1247
|
+
}),
|
|
1248
|
+
),
|
|
1249
|
+
limit: Type.Optional(
|
|
1250
|
+
Type.Integer({
|
|
1251
|
+
minimum: 1,
|
|
1252
|
+
maximum: 20,
|
|
1253
|
+
default: 5,
|
|
1254
|
+
description: 'Maximum remembered entries to return',
|
|
1255
|
+
}),
|
|
1256
|
+
),
|
|
1257
|
+
}),
|
|
1258
|
+
async execute(_id, params, signal, _onUpdate, ctx): Promise<AgentToolResult<void>> {
|
|
1259
|
+
if (!goosedumpAvailable) return goosedumpUnavailableResult();
|
|
1260
|
+
try {
|
|
1261
|
+
const hits = await goosedumpRecall(
|
|
1262
|
+
params.query,
|
|
1263
|
+
{
|
|
1264
|
+
provider: params.provider,
|
|
1265
|
+
path: params.allProjects ? undefined : ctx.cwd,
|
|
1266
|
+
limit: params.limit,
|
|
1267
|
+
},
|
|
1268
|
+
signal,
|
|
1269
|
+
);
|
|
1270
|
+
if (hits.length === 0) return textResult(`No durable memory for "${params.query}"`);
|
|
1271
|
+
return textResult(formatMemoryHits(hits));
|
|
1272
|
+
} catch (err) {
|
|
1273
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1274
|
+
return textResult(`goosedump error: ${message}`);
|
|
1275
|
+
}
|
|
1276
|
+
},
|
|
1277
|
+
}),
|
|
1278
|
+
);
|
|
1279
|
+
|
|
1172
1280
|
pi.registerTool(
|
|
1173
1281
|
defineTool({
|
|
1174
1282
|
name: 'goose_search',
|