pi-goosedump 0.13.6 → 0.13.8
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 +10 -10
- package/dist/index.ts +155 -106
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# pi-goosedump
|
|
2
2
|
|
|
3
3
|
Pi extension for session search, durable memory, session management, and
|
|
4
|
-
compaction. Canonical tools use the `
|
|
4
|
+
compaction. Canonical tools use the `goosedump_` prefix (with legacy `goose_` aliases supported).
|
|
5
5
|
|
|
6
6
|
## Install
|
|
7
7
|
|
|
@@ -15,20 +15,20 @@ packaged binary.
|
|
|
15
15
|
|
|
16
16
|
## Tools
|
|
17
17
|
|
|
18
|
-
- `
|
|
19
|
-
- `
|
|
20
|
-
- `
|
|
21
|
-
- `
|
|
22
|
-
- `
|
|
23
|
-
- `
|
|
18
|
+
- `goosedump_search` and `goosedump_grep` find session entries.
|
|
19
|
+
- `goosedump_get` expands entry IDs to full content.
|
|
20
|
+
- `goosedump_remember`, `goosedump_recall`, and `goosedump_forget` manage durable memory.
|
|
21
|
+
- `goosedump_memory_status` reports memory storage health.
|
|
22
|
+
- `goosedump_compact` compacts the current Pi session.
|
|
23
|
+
- `goosedump_sessions` lists or deletes sessions for the current project.
|
|
24
24
|
|
|
25
|
-
Search and grep return entry IDs; call `
|
|
25
|
+
Search and grep return entry IDs; call `goosedump_get` before relying on their
|
|
26
26
|
content. Non-Pi providers require an explicit session ID.
|
|
27
27
|
|
|
28
28
|
## Commands
|
|
29
29
|
|
|
30
|
-
`/
|
|
31
|
-
`/
|
|
30
|
+
`/goosedump-search`, `/goosedump-compact`, `/goosedump-sessions`, `/goosedump-forget`,
|
|
31
|
+
`/goosedump-memory-status`, and `/goosedump-settings`.
|
|
32
32
|
|
|
33
33
|
## Settings
|
|
34
34
|
|
package/dist/index.ts
CHANGED
|
@@ -685,7 +685,7 @@ async function goosedumpCompact(target, options, signal, executablePath) {
|
|
|
685
685
|
continue;
|
|
686
686
|
}
|
|
687
687
|
}
|
|
688
|
-
return { summary:
|
|
688
|
+
return { summary: "", warning: output.stderr.trim() };
|
|
689
689
|
}
|
|
690
690
|
function currentSessionTarget(ctx) {
|
|
691
691
|
const sessionManager = ctx.sessionManager;
|
|
@@ -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";
|
|
@@ -740,7 +741,7 @@ function settingSpecFromSchema(schema) {
|
|
|
740
741
|
return { kind: "number", min: minimum, max: maximum };
|
|
741
742
|
}
|
|
742
743
|
var GOOSEDUMP_SETTING_SPECS = Object.fromEntries(GOOSEDUMP_SETTING_KEYS.map((key) => [key, settingSpecFromSchema(GOOSEDUMP_SETTING_SCHEMAS[key])]));
|
|
743
|
-
var MEMORY_DISABLED_MESSAGE = "Durable memory is disabled. Set goosedump.enableMemory to true in settings (or /
|
|
744
|
+
var MEMORY_DISABLED_MESSAGE = "Durable memory is disabled. Set goosedump.enableMemory to true in settings (or /goosedump-settings).";
|
|
744
745
|
function isValidGoosedumpSettingValue(key, value) {
|
|
745
746
|
return Value3.Check(GOOSEDUMP_SETTING_SCHEMAS[key], value);
|
|
746
747
|
}
|
|
@@ -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;
|
|
@@ -1715,27 +1747,27 @@ function hideMemoryActivity(ctx) {
|
|
|
1715
1747
|
|
|
1716
1748
|
// src/policy.ts
|
|
1717
1749
|
var GOOSEDUMP_TOOL_NAMES = [
|
|
1718
|
-
"
|
|
1719
|
-
"
|
|
1720
|
-
"
|
|
1721
|
-
"
|
|
1722
|
-
"
|
|
1723
|
-
"
|
|
1724
|
-
"
|
|
1725
|
-
"
|
|
1726
|
-
"
|
|
1750
|
+
"goosedump_remember",
|
|
1751
|
+
"goosedump_recall",
|
|
1752
|
+
"goosedump_forget",
|
|
1753
|
+
"goosedump_memory_status",
|
|
1754
|
+
"goosedump_search",
|
|
1755
|
+
"goosedump_get",
|
|
1756
|
+
"goosedump_grep",
|
|
1757
|
+
"goosedump_compact",
|
|
1758
|
+
"goosedump_sessions"
|
|
1727
1759
|
];
|
|
1728
1760
|
var GOOSE_TOOL_NAMES = GOOSEDUMP_TOOL_NAMES;
|
|
1729
1761
|
var LEGACY_TO_CANONICAL_TOOL_NAMES = {
|
|
1730
|
-
goose_remember: "
|
|
1731
|
-
goose_recall: "
|
|
1732
|
-
goose_forget: "
|
|
1733
|
-
goose_memory_status: "
|
|
1734
|
-
goose_search: "
|
|
1735
|
-
goose_get: "
|
|
1736
|
-
goose_grep: "
|
|
1737
|
-
goose_compact: "
|
|
1738
|
-
goose_sessions: "
|
|
1762
|
+
goose_remember: "goosedump_remember",
|
|
1763
|
+
goose_recall: "goosedump_recall",
|
|
1764
|
+
goose_forget: "goosedump_forget",
|
|
1765
|
+
goose_memory_status: "goosedump_memory_status",
|
|
1766
|
+
goose_search: "goosedump_search",
|
|
1767
|
+
goose_get: "goosedump_get",
|
|
1768
|
+
goose_grep: "goosedump_grep",
|
|
1769
|
+
goose_compact: "goosedump_compact",
|
|
1770
|
+
goose_sessions: "goosedump_sessions"
|
|
1739
1771
|
};
|
|
1740
1772
|
function resolveCanonicalToolName(name) {
|
|
1741
1773
|
if (GOOSEDUMP_TOOL_NAMES.includes(name)) {
|
|
@@ -1762,14 +1794,14 @@ var PARAM_DESCRIPTIONS = {
|
|
|
1762
1794
|
sessionsDeleteId: "Session ID to delete (required for action: delete)"
|
|
1763
1795
|
};
|
|
1764
1796
|
var HISTORY_TARGET_GUIDELINE = "Default to the current Pi session; non-Pi providers require an explicit session ID.";
|
|
1765
|
-
var HISTORY_WORKFLOW_GUIDELINE = "Prefer
|
|
1766
|
-
var PREFER_REMEMBER = "Prefer
|
|
1767
|
-
var PREFER_RECALL = "Prefer
|
|
1768
|
-
var PREFER_HISTORY = "Prefer
|
|
1769
|
-
var PREFER_COMPACT = "Prefer
|
|
1770
|
-
var PREFER_SESSIONS = "Prefer
|
|
1797
|
+
var HISTORY_WORKFLOW_GUIDELINE = "Prefer goosedump_search or goosedump_grep for candidate entry IDs, then goosedump_get before quoting or acting on prior session content.";
|
|
1798
|
+
var PREFER_REMEMBER = "Prefer goosedump_remember after milestones instead of restating durable facts in prompts.";
|
|
1799
|
+
var PREFER_RECALL = "Prefer goosedump_recall over re-asking the user or re-deriving settled project context.";
|
|
1800
|
+
var PREFER_HISTORY = "Prefer goosedump_search or goosedump_grep, then goosedump_get, over replaying full history or guessing prior work.";
|
|
1801
|
+
var PREFER_COMPACT = "Prefer goosedump_compact when context is large, repetitive, or nearing limits; optional keep:N keeps the last N user turns.";
|
|
1802
|
+
var PREFER_SESSIONS = "Prefer goosedump_sessions for cwd session discovery/delete; use goosedump_forget / goosedump_memory_status to maintain durable memory.";
|
|
1771
1803
|
var CANONICAL_GOOSE_TOOL_POLICIES = {
|
|
1772
|
-
|
|
1804
|
+
goosedump_remember: {
|
|
1773
1805
|
description: "Preferred for background memory learning after milestones. Extracts evidence-backed claims for later recall; defaults to the current Pi session.",
|
|
1774
1806
|
snippet: "Persist important context from the current or another session into durable memory",
|
|
1775
1807
|
preference: PREFER_REMEMBER,
|
|
@@ -1779,7 +1811,7 @@ var CANONICAL_GOOSE_TOOL_POLICIES = {
|
|
|
1779
1811
|
"Defaults to the current Pi session; pass provider/session to learn from another agent session."
|
|
1780
1812
|
]
|
|
1781
1813
|
},
|
|
1782
|
-
|
|
1814
|
+
goosedump_recall: {
|
|
1783
1815
|
description: "Preferred for durable project memory before re-asking the user or re-deriving settled decisions. Returns provenance-backed claims, never instructions.",
|
|
1784
1816
|
snippet: "Recall durable context from earlier sessions",
|
|
1785
1817
|
preference: PREFER_RECALL,
|
|
@@ -1792,59 +1824,59 @@ var CANONICAL_GOOSE_TOOL_POLICIES = {
|
|
|
1792
1824
|
"Filter with type when you already know the memory kind (decision, fact, preference, procedure, lesson)."
|
|
1793
1825
|
]
|
|
1794
1826
|
},
|
|
1795
|
-
|
|
1827
|
+
goosedump_forget: {
|
|
1796
1828
|
description: "Preferred for tombstoning stale or wrong durable memory by mem_ ID or provider:session.",
|
|
1797
1829
|
snippet: "Remove obsolete entries from durable memory store",
|
|
1798
1830
|
guidelines: [
|
|
1799
|
-
"Call
|
|
1831
|
+
"Call goosedump_forget when stored memory is stale, wrong, or should no longer be recalled.",
|
|
1800
1832
|
"Target a memory ID (mem_...) or a provider:session to drop that session's retained sources.",
|
|
1801
|
-
"Forgotten content leaves a tombstone; use
|
|
1833
|
+
"Forgotten content leaves a tombstone; use goosedump_memory_status to inspect remaining store health."
|
|
1802
1834
|
]
|
|
1803
1835
|
},
|
|
1804
|
-
|
|
1836
|
+
goosedump_memory_status: {
|
|
1805
1837
|
description: "Preferred for diagnosing empty recall, missing embeddings, or unexpected durable-memory volume.",
|
|
1806
1838
|
snippet: "Inspect durable memory health and statistics",
|
|
1807
1839
|
guidelines: [
|
|
1808
|
-
"Call
|
|
1840
|
+
"Call goosedump_memory_status when diagnosing empty recall, missing embeddings, or unexpected memory volume.",
|
|
1809
1841
|
"Useful before or after bulk learn/forget operations."
|
|
1810
1842
|
]
|
|
1811
1843
|
},
|
|
1812
|
-
|
|
1813
|
-
description: "Preferred for ranked session-history search. Returns compact entry IDs; expand hits with
|
|
1844
|
+
goosedump_search: {
|
|
1845
|
+
description: "Preferred for ranked session-history search. Returns compact entry IDs; expand hits with goosedump_get. Defaults to the current Pi session.",
|
|
1814
1846
|
snippet: "Search session history by ranked relevance",
|
|
1815
1847
|
preference: PREFER_HISTORY,
|
|
1816
1848
|
guidelines: [
|
|
1817
1849
|
PREFER_HISTORY,
|
|
1818
|
-
"Call
|
|
1850
|
+
"Call goosedump_search to recover relevant prior work from this or another coding-agent session.",
|
|
1819
1851
|
HISTORY_WORKFLOW_GUIDELINE,
|
|
1820
1852
|
'Default scope is "lineage" (active branch); use scope: "all" for every branch in the session.',
|
|
1821
1853
|
"Page results with page when the first page is incomplete.",
|
|
1822
1854
|
HISTORY_TARGET_GUIDELINE
|
|
1823
1855
|
]
|
|
1824
1856
|
},
|
|
1825
|
-
|
|
1826
|
-
description: "Preferred for expanding
|
|
1857
|
+
goosedump_get: {
|
|
1858
|
+
description: "Preferred for expanding goosedump_search/goosedump_grep entry IDs to full content. Defaults to the current Pi session.",
|
|
1827
1859
|
snippet: "Expand session entries by ID to full content",
|
|
1828
1860
|
guidelines: [
|
|
1829
|
-
"Prefer
|
|
1861
|
+
"Prefer goosedump_get after goosedump_search or goosedump_grep; do not guess full prior content from overviews.",
|
|
1830
1862
|
"Pass only the IDs you need; full transcripts are expensive.",
|
|
1831
1863
|
'Default scope is "lineage" (active branch); use scope: "all" for every branch in the session.',
|
|
1832
1864
|
HISTORY_TARGET_GUIDELINE
|
|
1833
1865
|
]
|
|
1834
1866
|
},
|
|
1835
|
-
|
|
1836
|
-
description: "Preferred for glob/substring filtering of session history when ranked search is too fuzzy. Expand hits with
|
|
1867
|
+
goosedump_grep: {
|
|
1868
|
+
description: "Preferred for glob/substring filtering of session history when ranked search is too fuzzy. Expand hits with goosedump_get. Defaults to the current Pi session.",
|
|
1837
1869
|
snippet: "Filter session history by glob pattern",
|
|
1838
1870
|
preference: PREFER_HISTORY,
|
|
1839
1871
|
guidelines: [
|
|
1840
1872
|
PREFER_HISTORY,
|
|
1841
|
-
"Call
|
|
1873
|
+
"Call goosedump_grep for exact substring or glob matches when ranked search is too fuzzy.",
|
|
1842
1874
|
HISTORY_WORKFLOW_GUIDELINE,
|
|
1843
1875
|
'Default scope is "lineage" (active branch); use scope: "all" for every branch in the session.',
|
|
1844
1876
|
HISTORY_TARGET_GUIDELINE
|
|
1845
1877
|
]
|
|
1846
1878
|
},
|
|
1847
|
-
|
|
1879
|
+
goosedump_compact: {
|
|
1848
1880
|
description: "Preferred for proactive session compaction when context is large or nearing limits. Optional keep:N; runs through Pi's compaction flow.",
|
|
1849
1881
|
snippet: "Compact session history; optionally keep recent user turns",
|
|
1850
1882
|
preference: PREFER_COMPACT,
|
|
@@ -1855,7 +1887,7 @@ var CANONICAL_GOOSE_TOOL_POLICIES = {
|
|
|
1855
1887
|
"Successful compaction may queue background memory learning."
|
|
1856
1888
|
]
|
|
1857
1889
|
},
|
|
1858
|
-
|
|
1890
|
+
goosedump_sessions: {
|
|
1859
1891
|
description: "Preferred for listing or deleting coding-agent sessions scoped to the current working directory.",
|
|
1860
1892
|
snippet: "List or delete coding agent sessions for current directory",
|
|
1861
1893
|
preference: PREFER_SESSIONS,
|
|
@@ -2062,20 +2094,20 @@ function formatExpandedMemoryStatus(content, theme) {
|
|
|
2062
2094
|
function renderGooseDumpRememberCall(args, theme, ...rest) {
|
|
2063
2095
|
const context = rest[0] ?? {};
|
|
2064
2096
|
const target = args?.session ? `${args?.provider ?? "pi"}:${args.session}` : "current session";
|
|
2065
|
-
const text = clampLineToWidth(`${renderToolLabel(theme, "
|
|
2097
|
+
const text = clampLineToWidth(`${renderToolLabel(theme, "goosedump_remember")} ${theme.fg("accent", target)}`, context.width);
|
|
2066
2098
|
return upsertTextComponent(context.lastComponent, text);
|
|
2067
2099
|
}
|
|
2068
2100
|
var renderGooseRememberCall = renderGooseDumpRememberCall;
|
|
2069
2101
|
function renderGooseDumpRememberResult(result, options, theme, ...rest) {
|
|
2070
2102
|
const { isPartial, isError, expanded, width } = resolveRenderResultContext(options, rest);
|
|
2071
2103
|
if (isPartial)
|
|
2072
|
-
return renderPendingResult("pending
|
|
2104
|
+
return renderPendingResult("pending goosedump_remember", width, theme);
|
|
2073
2105
|
const content = result.content?.[0]?.text ?? "";
|
|
2074
2106
|
if (isError || result.isError) {
|
|
2075
2107
|
return renderErrorResult(content, {
|
|
2076
2108
|
expanded,
|
|
2077
2109
|
width,
|
|
2078
|
-
fallback: "
|
|
2110
|
+
fallback: "goosedump_remember failed",
|
|
2079
2111
|
theme
|
|
2080
2112
|
});
|
|
2081
2113
|
}
|
|
@@ -2098,20 +2130,20 @@ function renderGooseDumpRecallCall(args, theme, ...rest) {
|
|
|
2098
2130
|
args?.history && "history"
|
|
2099
2131
|
].filter(Boolean);
|
|
2100
2132
|
const flagsBadge = flags.length > 0 ? theme.fg("dim", ` [${flags.join(", ")}]`) : "";
|
|
2101
|
-
const text = clampLineToWidth(`${renderToolLabel(theme, "
|
|
2133
|
+
const text = clampLineToWidth(`${renderToolLabel(theme, "goosedump_recall")} ${theme.fg("accent", query)}${flagsBadge}`, context.width);
|
|
2102
2134
|
return upsertTextComponent(context.lastComponent, text);
|
|
2103
2135
|
}
|
|
2104
2136
|
var renderGooseRecallCall = renderGooseDumpRecallCall;
|
|
2105
2137
|
function renderGooseDumpRecallResult(result, options, theme, ...rest) {
|
|
2106
2138
|
const { isPartial, isError, expanded, width } = resolveRenderResultContext(options, rest);
|
|
2107
2139
|
if (isPartial)
|
|
2108
|
-
return renderPendingResult("pending
|
|
2140
|
+
return renderPendingResult("pending goosedump_recall", width, theme);
|
|
2109
2141
|
const content = result.content?.[0]?.text ?? "";
|
|
2110
2142
|
if (isError || result.isError) {
|
|
2111
2143
|
return renderErrorResult(content, {
|
|
2112
2144
|
expanded,
|
|
2113
2145
|
width,
|
|
2114
|
-
fallback: "
|
|
2146
|
+
fallback: "goosedump_recall failed",
|
|
2115
2147
|
theme
|
|
2116
2148
|
});
|
|
2117
2149
|
}
|
|
@@ -2139,20 +2171,20 @@ var renderGooseRecallResult = renderGooseDumpRecallResult;
|
|
|
2139
2171
|
function renderGooseDumpForgetCall(args, theme, ...rest) {
|
|
2140
2172
|
const context = rest[0] ?? {};
|
|
2141
2173
|
const target = args?.target ? String(args.target) : '""';
|
|
2142
|
-
const text = clampLineToWidth(`${renderToolLabel(theme, "
|
|
2174
|
+
const text = clampLineToWidth(`${renderToolLabel(theme, "goosedump_forget")} ${theme.fg("accent", target)}`, context.width);
|
|
2143
2175
|
return upsertTextComponent(context.lastComponent, text);
|
|
2144
2176
|
}
|
|
2145
2177
|
var renderGooseForgetCall = renderGooseDumpForgetCall;
|
|
2146
2178
|
function renderGooseDumpForgetResult(result, options, theme, ...rest) {
|
|
2147
2179
|
const { isPartial, isError, expanded, width } = resolveRenderResultContext(options, rest);
|
|
2148
2180
|
if (isPartial)
|
|
2149
|
-
return renderPendingResult("pending
|
|
2181
|
+
return renderPendingResult("pending goosedump_forget", width, theme);
|
|
2150
2182
|
const content = result.content?.[0]?.text ?? "";
|
|
2151
2183
|
if (isError || result.isError) {
|
|
2152
2184
|
return renderErrorResult(content, {
|
|
2153
2185
|
expanded,
|
|
2154
2186
|
width,
|
|
2155
|
-
fallback: "
|
|
2187
|
+
fallback: "goosedump_forget failed",
|
|
2156
2188
|
theme
|
|
2157
2189
|
});
|
|
2158
2190
|
}
|
|
@@ -2163,20 +2195,20 @@ function renderGooseDumpForgetResult(result, options, theme, ...rest) {
|
|
|
2163
2195
|
var renderGooseForgetResult = renderGooseDumpForgetResult;
|
|
2164
2196
|
function renderGooseDumpMemoryStatusCall(_args, theme, ...rest) {
|
|
2165
2197
|
const context = rest[0] ?? {};
|
|
2166
|
-
const text = clampLineToWidth(renderToolLabel(theme, "
|
|
2198
|
+
const text = clampLineToWidth(renderToolLabel(theme, "goosedump_memory_status"), context.width);
|
|
2167
2199
|
return upsertTextComponent(context.lastComponent, text);
|
|
2168
2200
|
}
|
|
2169
2201
|
var renderGooseMemoryStatusCall = renderGooseDumpMemoryStatusCall;
|
|
2170
2202
|
function renderGooseDumpMemoryStatusResult(result, options, theme, ...rest) {
|
|
2171
2203
|
const { isPartial, isError, expanded, width } = resolveRenderResultContext(options, rest);
|
|
2172
2204
|
if (isPartial)
|
|
2173
|
-
return renderPendingResult("pending
|
|
2205
|
+
return renderPendingResult("pending goosedump_memory_status", width, theme);
|
|
2174
2206
|
const content = result.content?.[0]?.text ?? "";
|
|
2175
2207
|
if (isError || result.isError) {
|
|
2176
2208
|
return renderErrorResult(content, {
|
|
2177
2209
|
expanded,
|
|
2178
2210
|
width,
|
|
2179
|
-
fallback: "
|
|
2211
|
+
fallback: "goosedump_memory_status failed",
|
|
2180
2212
|
theme
|
|
2181
2213
|
});
|
|
2182
2214
|
}
|
|
@@ -2214,20 +2246,20 @@ function renderGooseDumpSearchCall(args, theme, ...rest) {
|
|
|
2214
2246
|
args?.page && args.page > 1 && `page=${args.page}`
|
|
2215
2247
|
].filter(Boolean);
|
|
2216
2248
|
const flagsBadge = flags.length > 0 ? theme.fg("dim", ` [${flags.join(", ")}]`) : "";
|
|
2217
|
-
const text = clampLineToWidth(`${renderToolLabel(theme, "
|
|
2249
|
+
const text = clampLineToWidth(`${renderToolLabel(theme, "goosedump_search")} ${theme.fg("accent", query)}${target}${flagsBadge}`, context.width);
|
|
2218
2250
|
return upsertTextComponent(context.lastComponent, text);
|
|
2219
2251
|
}
|
|
2220
2252
|
var renderGooseSearchCall = renderGooseDumpSearchCall;
|
|
2221
2253
|
function renderGooseDumpSearchResult(result, options, theme, ...rest) {
|
|
2222
2254
|
const { isPartial, isError, expanded, width } = resolveRenderResultContext(options, rest);
|
|
2223
2255
|
if (isPartial)
|
|
2224
|
-
return renderPendingResult("pending
|
|
2256
|
+
return renderPendingResult("pending goosedump_search", width, theme);
|
|
2225
2257
|
const content = result.content?.[0]?.text ?? "";
|
|
2226
2258
|
if (isError || result.isError) {
|
|
2227
2259
|
return renderErrorResult(content, {
|
|
2228
2260
|
expanded,
|
|
2229
2261
|
width,
|
|
2230
|
-
fallback: "
|
|
2262
|
+
fallback: "goosedump_search failed",
|
|
2231
2263
|
theme
|
|
2232
2264
|
});
|
|
2233
2265
|
}
|
|
@@ -2259,17 +2291,17 @@ function renderGooseDumpGetCall(args, theme, ...rest) {
|
|
|
2259
2291
|
const ids = Array.isArray(args?.ids) ? args.ids : [];
|
|
2260
2292
|
const idsDisplay = ids.length <= 3 ? ids.join(", ") : `${ids.slice(0, 3).join(", ")}… (${ids.length})`;
|
|
2261
2293
|
const target = args?.session ? theme.fg("dim", ` in ${args.provider ?? "pi"}:${args.session}`) : "";
|
|
2262
|
-
const text = clampLineToWidth(`${renderToolLabel(theme, "
|
|
2294
|
+
const text = clampLineToWidth(`${renderToolLabel(theme, "goosedump_get")} ${theme.fg("accent", `[${idsDisplay}]`)}${target}`, context.width);
|
|
2263
2295
|
return upsertTextComponent(context.lastComponent, text);
|
|
2264
2296
|
}
|
|
2265
2297
|
var renderGooseGetCall = renderGooseDumpGetCall;
|
|
2266
2298
|
function renderGooseDumpGetResult(result, options, theme, ...rest) {
|
|
2267
2299
|
const { isPartial, isError, expanded, width } = resolveRenderResultContext(options, rest);
|
|
2268
2300
|
if (isPartial)
|
|
2269
|
-
return renderPendingResult("pending
|
|
2301
|
+
return renderPendingResult("pending goosedump_get", width, theme);
|
|
2270
2302
|
const content = result.content?.[0]?.text ?? "";
|
|
2271
2303
|
if (isError || result.isError) {
|
|
2272
|
-
return renderErrorResult(content, { expanded, width, fallback: "
|
|
2304
|
+
return renderErrorResult(content, { expanded, width, fallback: "goosedump_get failed", theme });
|
|
2273
2305
|
}
|
|
2274
2306
|
if (content.startsWith("No entries found")) {
|
|
2275
2307
|
return upsertTextComponent(rest[0]?.lastComponent, clampLineToWidth(summaryLine("no entries found", { theme, style: "dim" }), width));
|
|
@@ -2297,20 +2329,20 @@ function renderGooseDumpGrepCall(args, theme, ...rest) {
|
|
|
2297
2329
|
const target = args?.session ? theme.fg("dim", ` in ${args.provider ?? "pi"}:${args.session}`) : "";
|
|
2298
2330
|
const flags = [args?.scope && args.scope !== "lineage" && `scope=${args.scope}`].filter(Boolean);
|
|
2299
2331
|
const flagsBadge = flags.length > 0 ? theme.fg("dim", ` [${flags.join(", ")}]`) : "";
|
|
2300
|
-
const text = clampLineToWidth(`${renderToolLabel(theme, "
|
|
2332
|
+
const text = clampLineToWidth(`${renderToolLabel(theme, "goosedump_grep")} ${theme.fg("accent", pattern)}${target}${flagsBadge}`, context.width);
|
|
2301
2333
|
return upsertTextComponent(context.lastComponent, text);
|
|
2302
2334
|
}
|
|
2303
2335
|
var renderGooseGrepCall = renderGooseDumpGrepCall;
|
|
2304
2336
|
function renderGooseDumpGrepResult(result, options, theme, ...rest) {
|
|
2305
2337
|
const { isPartial, isError, expanded, width } = resolveRenderResultContext(options, rest);
|
|
2306
2338
|
if (isPartial)
|
|
2307
|
-
return renderPendingResult("pending
|
|
2339
|
+
return renderPendingResult("pending goosedump_grep", width, theme);
|
|
2308
2340
|
const content = result.content?.[0]?.text ?? "";
|
|
2309
2341
|
if (isError || result.isError) {
|
|
2310
2342
|
return renderErrorResult(content, {
|
|
2311
2343
|
expanded,
|
|
2312
2344
|
width,
|
|
2313
|
-
fallback: "
|
|
2345
|
+
fallback: "goosedump_grep failed",
|
|
2314
2346
|
theme
|
|
2315
2347
|
});
|
|
2316
2348
|
}
|
|
@@ -2335,20 +2367,20 @@ function renderGooseDumpCompactCall(args, theme, ...rest) {
|
|
|
2335
2367
|
const context = rest[0] ?? {};
|
|
2336
2368
|
const flags = args?.keep ? [theme.fg("dim", `keep=${args.keep}`)] : [];
|
|
2337
2369
|
const flagsBadge = flags.length > 0 ? ` [${flags.join(", ")}]` : "";
|
|
2338
|
-
const text = clampLineToWidth(`${renderToolLabel(theme, "
|
|
2370
|
+
const text = clampLineToWidth(`${renderToolLabel(theme, "goosedump_compact")}${flagsBadge}`, context.width);
|
|
2339
2371
|
return upsertTextComponent(context.lastComponent, text);
|
|
2340
2372
|
}
|
|
2341
2373
|
var renderGooseCompactCall = renderGooseDumpCompactCall;
|
|
2342
2374
|
function renderGooseDumpCompactResult(result, options, theme, ...rest) {
|
|
2343
2375
|
const { isPartial, isError, expanded, width } = resolveRenderResultContext(options, rest);
|
|
2344
2376
|
if (isPartial)
|
|
2345
|
-
return renderPendingResult("pending
|
|
2377
|
+
return renderPendingResult("pending goosedump_compact", width, theme);
|
|
2346
2378
|
const content = result.content?.[0]?.text ?? "";
|
|
2347
2379
|
if (isError || result.isError) {
|
|
2348
2380
|
return renderErrorResult(content, {
|
|
2349
2381
|
expanded,
|
|
2350
2382
|
width,
|
|
2351
|
-
fallback: "
|
|
2383
|
+
fallback: "goosedump_compact failed",
|
|
2352
2384
|
theme
|
|
2353
2385
|
});
|
|
2354
2386
|
}
|
|
@@ -2362,20 +2394,20 @@ function renderGooseDumpSessionsCall(args, theme, ...rest) {
|
|
|
2362
2394
|
const context = rest[0] ?? {};
|
|
2363
2395
|
const action = args?.action ?? "list";
|
|
2364
2396
|
const target = args?.session ? `${args?.provider ?? "pi"}:${args.session}` : `(${args?.provider ?? "pi"})`;
|
|
2365
|
-
const text = clampLineToWidth(`${renderToolLabel(theme, "
|
|
2397
|
+
const text = clampLineToWidth(`${renderToolLabel(theme, "goosedump_sessions")} ${theme.fg("accent", action)} ${theme.fg("dim", target)}`, context.width);
|
|
2366
2398
|
return upsertTextComponent(context.lastComponent, text);
|
|
2367
2399
|
}
|
|
2368
2400
|
var renderGooseSessionsCall = renderGooseDumpSessionsCall;
|
|
2369
2401
|
function renderGooseDumpSessionsResult(result, options, theme, ...rest) {
|
|
2370
2402
|
const { isPartial, isError, expanded, width } = resolveRenderResultContext(options, rest);
|
|
2371
2403
|
if (isPartial)
|
|
2372
|
-
return renderPendingResult("pending
|
|
2404
|
+
return renderPendingResult("pending goosedump_sessions", width, theme);
|
|
2373
2405
|
const content = result.content?.[0]?.text ?? "";
|
|
2374
2406
|
if (isError || result.isError) {
|
|
2375
2407
|
return renderErrorResult(content, {
|
|
2376
2408
|
expanded,
|
|
2377
2409
|
width,
|
|
2378
|
-
fallback: "
|
|
2410
|
+
fallback: "goosedump_sessions failed",
|
|
2379
2411
|
theme
|
|
2380
2412
|
});
|
|
2381
2413
|
}
|
|
@@ -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
|
}
|
|
@@ -2456,7 +2489,7 @@ function boundedHistoryResult(text) {
|
|
|
2456
2489
|
return textResult(text);
|
|
2457
2490
|
return textResult(`${output.content}
|
|
2458
2491
|
|
|
2459
|
-
[Output truncated: showing ${output.outputLines} of ${output.totalLines} lines ` + `and ${output.outputBytes} of ${output.totalBytes} bytes. ` + "Use
|
|
2492
|
+
[Output truncated: showing ${output.outputLines} of ${output.totalLines} lines ` + `and ${output.outputBytes} of ${output.totalBytes} bytes. ` + "Use goosedump_get with fewer IDs or a narrower goosedump_grep pattern.]");
|
|
2460
2493
|
}
|
|
2461
2494
|
function resolveHistoryTarget(ctx, tool, params) {
|
|
2462
2495
|
const provider = params.provider ?? "pi";
|
|
@@ -2504,7 +2537,7 @@ function registerGooseTools(pi, deps) {
|
|
|
2504
2537
|
pi.registerTool(defineGooseTool(canonicalName, parameters, handler, renderers));
|
|
2505
2538
|
pi.registerTool(defineGooseTool(legacyName, parameters, handler, renderers));
|
|
2506
2539
|
}
|
|
2507
|
-
registerPair("
|
|
2540
|
+
registerPair("goosedump_remember", "goose_remember", Type3.Object({ ...historyTargetParams() }), async (params, _signal, ctx, toolName) => {
|
|
2508
2541
|
const disabled = requireMemoryEnabled(ctx);
|
|
2509
2542
|
if (disabled)
|
|
2510
2543
|
return disabled;
|
|
@@ -2518,7 +2551,7 @@ function registerGooseTools(pi, deps) {
|
|
|
2518
2551
|
});
|
|
2519
2552
|
return textResult(accepted ? `Memory learning started for ${resolved.target}.` : `Memory learning dropped for ${resolved.target}: another inference task is active.`);
|
|
2520
2553
|
}, { renderCall: renderGooseRememberCall, renderResult: renderGooseRememberResult });
|
|
2521
|
-
registerPair("
|
|
2554
|
+
registerPair("goosedump_recall", "goose_recall", Type3.Object({
|
|
2522
2555
|
query: Type3.String({ description: PARAM_DESCRIPTIONS.memoryQuery }),
|
|
2523
2556
|
type: Type3.Optional(Type3.Union(GOOSE_MEMORY_TYPES.map((type) => Type3.Literal(type)), { description: PARAM_DESCRIPTIONS.memoryType })),
|
|
2524
2557
|
allProjects: Type3.Optional(Type3.Boolean({
|
|
@@ -2555,7 +2588,7 @@ function registerGooseTools(pi, deps) {
|
|
|
2555
2588
|
return textResult(`No durable memory for "${params.query}"`);
|
|
2556
2589
|
return textResult(formatMemoryHits(hits));
|
|
2557
2590
|
}, { renderCall: renderGooseRecallCall, renderResult: renderGooseRecallResult });
|
|
2558
|
-
registerPair("
|
|
2591
|
+
registerPair("goosedump_forget", "goose_forget", Type3.Object({
|
|
2559
2592
|
target: Type3.String({
|
|
2560
2593
|
description: PARAM_DESCRIPTIONS.forgetTarget
|
|
2561
2594
|
})
|
|
@@ -2569,13 +2602,13 @@ function registerGooseTools(pi, deps) {
|
|
|
2569
2602
|
const res = await goosedumpMemoryForget(params.target.trim(), signal, nativeExecutablePath);
|
|
2570
2603
|
return textResult(res);
|
|
2571
2604
|
}, { renderCall: renderGooseForgetCall, renderResult: renderGooseForgetResult });
|
|
2572
|
-
registerPair("
|
|
2605
|
+
registerPair("goosedump_memory_status", "goose_memory_status", Type3.Object({}), async (_params, signal, ctx) => {
|
|
2573
2606
|
const disabled = requireMemoryEnabled(ctx);
|
|
2574
2607
|
if (disabled)
|
|
2575
2608
|
return disabled;
|
|
2576
2609
|
return textResult(await goosedumpMemoryStatus(signal, nativeExecutablePath));
|
|
2577
2610
|
}, { renderCall: renderGooseMemoryStatusCall, renderResult: renderGooseMemoryStatusResult });
|
|
2578
|
-
registerPair("
|
|
2611
|
+
registerPair("goosedump_search", "goose_search", Type3.Object({
|
|
2579
2612
|
query: Type3.String({ description: PARAM_DESCRIPTIONS.searchQuery }),
|
|
2580
2613
|
...historyBranchParams(),
|
|
2581
2614
|
page: Type3.Optional(Type3.Integer({
|
|
@@ -2597,9 +2630,10 @@ function registerGooseTools(pi, deps) {
|
|
|
2597
2630
|
|
|
2598
2631
|
${text}`);
|
|
2599
2632
|
}, { renderCall: renderGooseSearchCall, renderResult: renderGooseSearchResult });
|
|
2600
|
-
registerPair("
|
|
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()
|
|
@@ -2613,7 +2647,7 @@ ${text}`);
|
|
|
2613
2647
|
}
|
|
2614
2648
|
return boundedHistoryResult(formatMessagesFull(messages));
|
|
2615
2649
|
}, { renderCall: renderGooseGetCall, renderResult: renderGooseGetResult });
|
|
2616
|
-
registerPair("
|
|
2650
|
+
registerPair("goosedump_grep", "goose_grep", Type3.Object({
|
|
2617
2651
|
pattern: Type3.String({ description: PARAM_DESCRIPTIONS.pattern }),
|
|
2618
2652
|
...historyBranchParams()
|
|
2619
2653
|
}), async (params, signal, ctx, toolName) => {
|
|
@@ -2626,7 +2660,7 @@ ${text}`);
|
|
|
2626
2660
|
}
|
|
2627
2661
|
return boundedHistoryResult(formatMessagesCompact(messages));
|
|
2628
2662
|
}, { renderCall: renderGooseGrepCall, renderResult: renderGooseGrepResult });
|
|
2629
|
-
registerPair("
|
|
2663
|
+
registerPair("goosedump_compact", "goose_compact", Type3.Object({
|
|
2630
2664
|
keep: Type3.Optional(Type3.Integer({
|
|
2631
2665
|
minimum: 1,
|
|
2632
2666
|
description: PARAM_DESCRIPTIONS.keep
|
|
@@ -2641,7 +2675,7 @@ ${text}`);
|
|
|
2641
2675
|
}
|
|
2642
2676
|
return textResult(compactStartedMessage(keep, result === "queued"));
|
|
2643
2677
|
}, { renderCall: renderGooseCompactCall, renderResult: renderGooseCompactResult });
|
|
2644
|
-
registerPair("
|
|
2678
|
+
registerPair("goosedump_sessions", "goose_sessions", Type3.Object({
|
|
2645
2679
|
action: Type3.Optional(Type3.Union([Type3.Literal("list"), Type3.Literal("delete")], {
|
|
2646
2680
|
default: "list",
|
|
2647
2681
|
description: PARAM_DESCRIPTIONS.sessionsAction
|
|
@@ -3025,7 +3059,7 @@ 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);
|
|
@@ -3038,9 +3072,11 @@ async function runSearchPanel(ctx, query, executablePath) {
|
|
|
3038
3072
|
let detailLines = [];
|
|
3039
3073
|
let detailScroll = 0;
|
|
3040
3074
|
let detailEntry = null;
|
|
3075
|
+
let truncated = false;
|
|
3076
|
+
const controller = new AbortController;
|
|
3041
3077
|
async function runSearch() {
|
|
3042
3078
|
try {
|
|
3043
|
-
const first = await goosedumpSearch(target, query, { scope: "lineage", page: 1 },
|
|
3079
|
+
const first = await goosedumpSearch(target, query, { scope: "lineage", page: 1 }, controller.signal, executablePath);
|
|
3044
3080
|
if (first.length === 0) {
|
|
3045
3081
|
entries = [];
|
|
3046
3082
|
error = `No results for "${query}"`;
|
|
@@ -3048,22 +3084,34 @@ async function runSearchPanel(ctx, query, executablePath) {
|
|
|
3048
3084
|
scroll = 0;
|
|
3049
3085
|
return;
|
|
3050
3086
|
}
|
|
3087
|
+
const search = (page) => goosedumpSearch(target, query, { scope: "lineage", page }, controller.signal, executablePath);
|
|
3051
3088
|
const all = [...first];
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
all.push(...
|
|
3057
|
-
|
|
3058
|
-
|
|
3089
|
+
let lastPage = 1;
|
|
3090
|
+
let complete = false;
|
|
3091
|
+
const second = await search(2);
|
|
3092
|
+
if (second.length < first.length) {
|
|
3093
|
+
all.push(...second);
|
|
3094
|
+
complete = true;
|
|
3095
|
+
} else {
|
|
3096
|
+
all.push(...second);
|
|
3097
|
+
const rest = await Promise.all(Array.from({ length: MAX_PAGES - 2 }, (_unused, index) => search(index + 3)));
|
|
3098
|
+
for (const [index, page] of rest.entries()) {
|
|
3099
|
+
all.push(...page);
|
|
3100
|
+
lastPage = index + 3;
|
|
3101
|
+
if (page.length < first.length) {
|
|
3102
|
+
complete = true;
|
|
3103
|
+
break;
|
|
3104
|
+
}
|
|
3105
|
+
}
|
|
3059
3106
|
}
|
|
3107
|
+
truncated = !complete && lastPage >= MAX_PAGES;
|
|
3060
3108
|
entries = all;
|
|
3061
3109
|
error = null;
|
|
3062
3110
|
selected = 0;
|
|
3063
3111
|
scroll = 0;
|
|
3064
3112
|
} catch (err) {
|
|
3065
3113
|
entries = [];
|
|
3066
|
-
error = err instanceof Error ? err.message : String(err);
|
|
3114
|
+
error = controller.signal.aborted ? "Search cancelled." : err instanceof Error ? err.message : String(err);
|
|
3067
3115
|
} finally {
|
|
3068
3116
|
tui.requestRender();
|
|
3069
3117
|
}
|
|
@@ -3075,7 +3123,7 @@ async function runSearchPanel(ctx, query, executablePath) {
|
|
|
3075
3123
|
}
|
|
3076
3124
|
async function loadDetail(id) {
|
|
3077
3125
|
try {
|
|
3078
|
-
const messages = await goosedumpShow(target, { ids: [id] },
|
|
3126
|
+
const messages = await goosedumpShow(target, { ids: [id] }, controller.signal, executablePath);
|
|
3079
3127
|
const msg = messages.length > 0 ? messages[0] : null;
|
|
3080
3128
|
detailEntry = msg;
|
|
3081
3129
|
const entryHeader = msg ? `${colors.accent(colors.bold(`[${msg.id}]`))} ${colors.muted(`${msg.role}:`)}` : "";
|
|
@@ -3106,7 +3154,7 @@ async function runSearchPanel(ctx, query, executablePath) {
|
|
|
3106
3154
|
}
|
|
3107
3155
|
return [
|
|
3108
3156
|
header,
|
|
3109
|
-
...overlayViewport(colors, width, entries, scroll, VIEWPORT, "↑↓ navigate enter expand esc close", (count) => `entr${count === 1 ? "y" : "ies"}`, (entry, absolute) => {
|
|
3157
|
+
...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
3158
|
const isSelected = absolute === selected;
|
|
3111
3159
|
const cursor = isSelected ? colors.accent(colors.bold("▶")) : " ";
|
|
3112
3160
|
const idText = isSelected ? colors.accent(colors.bold(entry.id)) : colors.text(entry.id);
|
|
@@ -3123,6 +3171,7 @@ async function runSearchPanel(ctx, query, executablePath) {
|
|
|
3123
3171
|
tui.requestRender();
|
|
3124
3172
|
return;
|
|
3125
3173
|
}
|
|
3174
|
+
controller.abort();
|
|
3126
3175
|
done(undefined);
|
|
3127
3176
|
return;
|
|
3128
3177
|
}
|
|
@@ -3561,13 +3610,13 @@ ${renderToolRoutingPolicy()}`
|
|
|
3561
3610
|
compaction.syncCompactCounters(ctx);
|
|
3562
3611
|
compaction.updateStatus(ctx);
|
|
3563
3612
|
};
|
|
3564
|
-
registerGooseCommand("
|
|
3565
|
-
registerGooseCommand("
|
|
3613
|
+
registerGooseCommand("goosedump-settings", "Edit goosedump settings", openSettingsEditor);
|
|
3614
|
+
registerGooseCommand("goosedump-compact", "Compact the current session now; optionally keep the last N user turns", async (args, ctx) => {
|
|
3566
3615
|
let keep = null;
|
|
3567
3616
|
if (args.trim()) {
|
|
3568
3617
|
const match = args.trim().match(/^keep:(\d+)$/);
|
|
3569
3618
|
if (!match) {
|
|
3570
|
-
ctx.ui.notify("Usage: /
|
|
3619
|
+
ctx.ui.notify("Usage: /goosedump-compact [keep:N], where N >= 1", "error");
|
|
3571
3620
|
return;
|
|
3572
3621
|
}
|
|
3573
3622
|
keep = Number(match[1]);
|
|
@@ -3585,16 +3634,16 @@ ${renderToolRoutingPolicy()}`
|
|
|
3585
3634
|
ctx.ui.notify(compactStartedMessage(keep, result === "queued"), "info");
|
|
3586
3635
|
}
|
|
3587
3636
|
});
|
|
3588
|
-
registerGooseCommand("
|
|
3637
|
+
registerGooseCommand("goosedump-search", "Search the current session history", async (args, ctx) => {
|
|
3589
3638
|
const query = args.trim() || (await ctx.ui.input("Search query:", ""))?.trim() || "";
|
|
3590
3639
|
if (query.length === 0)
|
|
3591
3640
|
return;
|
|
3592
3641
|
await runSearchPanel(ctx, query, nativeExecutablePath);
|
|
3593
3642
|
});
|
|
3594
|
-
registerGooseCommand("
|
|
3643
|
+
registerGooseCommand("goosedump-sessions", "List, resume, or delete sessions for the current working directory", async (_args, ctx) => {
|
|
3595
3644
|
await runSessionsPanel(ctx, nativeExecutablePath);
|
|
3596
3645
|
});
|
|
3597
|
-
registerGooseCommand("
|
|
3646
|
+
registerGooseCommand("goosedump-forget", "Remove a durable memory entry or remembered session", async (args, ctx) => {
|
|
3598
3647
|
if (!isMemoryEnabled(ctx.cwd, projectSettingsTrusted(ctx))) {
|
|
3599
3648
|
ctx.ui.notify(MEMORY_DISABLED_MESSAGE, "warning");
|
|
3600
3649
|
return;
|
|
@@ -3605,7 +3654,7 @@ ${renderToolRoutingPolicy()}`
|
|
|
3605
3654
|
const res = await goosedumpMemoryForget(target, undefined, nativeExecutablePath);
|
|
3606
3655
|
ctx.ui.notify(res, "info");
|
|
3607
3656
|
});
|
|
3608
|
-
registerGooseCommand("
|
|
3657
|
+
registerGooseCommand("goosedump-memory-status", "Show durable memory storage health and type counts", async (_args, ctx) => {
|
|
3609
3658
|
if (!isMemoryEnabled(ctx.cwd, projectSettingsTrusted(ctx))) {
|
|
3610
3659
|
ctx.ui.notify(MEMORY_DISABLED_MESSAGE, "warning");
|
|
3611
3660
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-goosedump",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.8",
|
|
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.8"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@earendil-works/pi-coding-agent": "^0.84.2",
|