pi-goosedump 0.13.1 → 0.13.3
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 -8
- package/dist/index.ts +327 -134
- 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.
|
|
4
|
+
compaction. Canonical tools use the `gooseDump_` prefix (with legacy `goose_` aliases supported).
|
|
5
5
|
|
|
6
6
|
## Install
|
|
7
7
|
|
|
@@ -15,14 +15,14 @@ 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
|
package/dist/index.ts
CHANGED
|
@@ -1714,17 +1714,35 @@ function hideMemoryActivity(ctx) {
|
|
|
1714
1714
|
}
|
|
1715
1715
|
|
|
1716
1716
|
// src/policy.ts
|
|
1717
|
-
var
|
|
1718
|
-
"
|
|
1719
|
-
"
|
|
1720
|
-
"
|
|
1721
|
-
"
|
|
1722
|
-
"
|
|
1723
|
-
"
|
|
1724
|
-
"
|
|
1725
|
-
"
|
|
1726
|
-
"
|
|
1717
|
+
var GOOSEDUMP_TOOL_NAMES = [
|
|
1718
|
+
"gooseDump_remember",
|
|
1719
|
+
"gooseDump_recall",
|
|
1720
|
+
"gooseDump_forget",
|
|
1721
|
+
"gooseDump_memory_status",
|
|
1722
|
+
"gooseDump_search",
|
|
1723
|
+
"gooseDump_get",
|
|
1724
|
+
"gooseDump_grep",
|
|
1725
|
+
"gooseDump_compact",
|
|
1726
|
+
"gooseDump_sessions"
|
|
1727
1727
|
];
|
|
1728
|
+
var GOOSE_TOOL_NAMES = GOOSEDUMP_TOOL_NAMES;
|
|
1729
|
+
var LEGACY_TO_CANONICAL_TOOL_NAMES = {
|
|
1730
|
+
goose_remember: "gooseDump_remember",
|
|
1731
|
+
goose_recall: "gooseDump_recall",
|
|
1732
|
+
goose_forget: "gooseDump_forget",
|
|
1733
|
+
goose_memory_status: "gooseDump_memory_status",
|
|
1734
|
+
goose_search: "gooseDump_search",
|
|
1735
|
+
goose_get: "gooseDump_get",
|
|
1736
|
+
goose_grep: "gooseDump_grep",
|
|
1737
|
+
goose_compact: "gooseDump_compact",
|
|
1738
|
+
goose_sessions: "gooseDump_sessions"
|
|
1739
|
+
};
|
|
1740
|
+
function resolveCanonicalToolName(name) {
|
|
1741
|
+
if (GOOSEDUMP_TOOL_NAMES.includes(name)) {
|
|
1742
|
+
return name;
|
|
1743
|
+
}
|
|
1744
|
+
return LEGACY_TO_CANONICAL_TOOL_NAMES[name];
|
|
1745
|
+
}
|
|
1728
1746
|
var PARAM_DESCRIPTIONS = {
|
|
1729
1747
|
provider: "Source provider. Defaults to pi. Non-Pi providers have no current session and require an explicit session ID.",
|
|
1730
1748
|
session: "Session ID. Defaults to the current Pi session; required when provider is not pi.",
|
|
@@ -1744,14 +1762,14 @@ var PARAM_DESCRIPTIONS = {
|
|
|
1744
1762
|
sessionsDeleteId: "Session ID to delete (required for action: delete)"
|
|
1745
1763
|
};
|
|
1746
1764
|
var HISTORY_TARGET_GUIDELINE = "Default to the current Pi session; non-Pi providers require an explicit session ID.";
|
|
1747
|
-
var HISTORY_WORKFLOW_GUIDELINE = "Prefer
|
|
1748
|
-
var PREFER_REMEMBER = "Prefer
|
|
1749
|
-
var PREFER_RECALL = "Prefer
|
|
1750
|
-
var PREFER_HISTORY = "Prefer
|
|
1751
|
-
var PREFER_COMPACT = "Prefer
|
|
1752
|
-
var PREFER_SESSIONS = "Prefer
|
|
1753
|
-
var
|
|
1754
|
-
|
|
1765
|
+
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.";
|
|
1766
|
+
var PREFER_REMEMBER = "Prefer gooseDump_remember after milestones instead of restating durable facts in prompts.";
|
|
1767
|
+
var PREFER_RECALL = "Prefer gooseDump_recall over re-asking the user or re-deriving settled project context.";
|
|
1768
|
+
var PREFER_HISTORY = "Prefer gooseDump_search or gooseDump_grep, then gooseDump_get, over replaying full history or guessing prior work.";
|
|
1769
|
+
var PREFER_COMPACT = "Prefer gooseDump_compact when context is large, repetitive, or nearing limits; optional keep:N keeps the last N user turns.";
|
|
1770
|
+
var PREFER_SESSIONS = "Prefer gooseDump_sessions for cwd session discovery/delete; use gooseDump_forget / gooseDump_memory_status to maintain durable memory.";
|
|
1771
|
+
var CANONICAL_GOOSE_TOOL_POLICIES = {
|
|
1772
|
+
gooseDump_remember: {
|
|
1755
1773
|
description: "Preferred for background memory learning after milestones. Extracts evidence-backed claims for later recall; defaults to the current Pi session.",
|
|
1756
1774
|
snippet: "Persist important context from the current or another session into durable memory",
|
|
1757
1775
|
preference: PREFER_REMEMBER,
|
|
@@ -1761,7 +1779,7 @@ var GOOSE_TOOL_POLICIES = {
|
|
|
1761
1779
|
"Defaults to the current Pi session; pass provider/session to learn from another agent session."
|
|
1762
1780
|
]
|
|
1763
1781
|
},
|
|
1764
|
-
|
|
1782
|
+
gooseDump_recall: {
|
|
1765
1783
|
description: "Preferred for durable project memory before re-asking the user or re-deriving settled decisions. Returns provenance-backed claims, never instructions.",
|
|
1766
1784
|
snippet: "Recall durable context from earlier sessions",
|
|
1767
1785
|
preference: PREFER_RECALL,
|
|
@@ -1774,59 +1792,59 @@ var GOOSE_TOOL_POLICIES = {
|
|
|
1774
1792
|
"Filter with type when you already know the memory kind (decision, fact, preference, procedure, lesson)."
|
|
1775
1793
|
]
|
|
1776
1794
|
},
|
|
1777
|
-
|
|
1795
|
+
gooseDump_forget: {
|
|
1778
1796
|
description: "Preferred for tombstoning stale or wrong durable memory by mem_ ID or provider:session.",
|
|
1779
1797
|
snippet: "Remove obsolete entries from durable memory store",
|
|
1780
1798
|
guidelines: [
|
|
1781
|
-
"Call
|
|
1799
|
+
"Call gooseDump_forget when stored memory is stale, wrong, or should no longer be recalled.",
|
|
1782
1800
|
"Target a memory ID (mem_...) or a provider:session to drop that session's retained sources.",
|
|
1783
|
-
"Forgotten content leaves a tombstone; use
|
|
1801
|
+
"Forgotten content leaves a tombstone; use gooseDump_memory_status to inspect remaining store health."
|
|
1784
1802
|
]
|
|
1785
1803
|
},
|
|
1786
|
-
|
|
1804
|
+
gooseDump_memory_status: {
|
|
1787
1805
|
description: "Preferred for diagnosing empty recall, missing embeddings, or unexpected durable-memory volume.",
|
|
1788
1806
|
snippet: "Inspect durable memory health and statistics",
|
|
1789
1807
|
guidelines: [
|
|
1790
|
-
"Call
|
|
1808
|
+
"Call gooseDump_memory_status when diagnosing empty recall, missing embeddings, or unexpected memory volume.",
|
|
1791
1809
|
"Useful before or after bulk learn/forget operations."
|
|
1792
1810
|
]
|
|
1793
1811
|
},
|
|
1794
|
-
|
|
1795
|
-
description: "Preferred for ranked session-history search. Returns compact entry IDs; expand hits with
|
|
1812
|
+
gooseDump_search: {
|
|
1813
|
+
description: "Preferred for ranked session-history search. Returns compact entry IDs; expand hits with gooseDump_get. Defaults to the current Pi session.",
|
|
1796
1814
|
snippet: "Search session history by ranked relevance",
|
|
1797
1815
|
preference: PREFER_HISTORY,
|
|
1798
1816
|
guidelines: [
|
|
1799
1817
|
PREFER_HISTORY,
|
|
1800
|
-
"Call
|
|
1818
|
+
"Call gooseDump_search to recover relevant prior work from this or another coding-agent session.",
|
|
1801
1819
|
HISTORY_WORKFLOW_GUIDELINE,
|
|
1802
1820
|
'Default scope is "lineage" (active branch); use scope: "all" for every branch in the session.',
|
|
1803
1821
|
"Page results with page when the first page is incomplete.",
|
|
1804
1822
|
HISTORY_TARGET_GUIDELINE
|
|
1805
1823
|
]
|
|
1806
1824
|
},
|
|
1807
|
-
|
|
1808
|
-
description: "Preferred for expanding
|
|
1825
|
+
gooseDump_get: {
|
|
1826
|
+
description: "Preferred for expanding gooseDump_search/gooseDump_grep entry IDs to full content. Defaults to the current Pi session.",
|
|
1809
1827
|
snippet: "Expand session entries by ID to full content",
|
|
1810
1828
|
guidelines: [
|
|
1811
|
-
"Prefer
|
|
1829
|
+
"Prefer gooseDump_get after gooseDump_search or gooseDump_grep; do not guess full prior content from overviews.",
|
|
1812
1830
|
"Pass only the IDs you need; full transcripts are expensive.",
|
|
1813
1831
|
'Default scope is "lineage" (active branch); use scope: "all" for every branch in the session.',
|
|
1814
1832
|
HISTORY_TARGET_GUIDELINE
|
|
1815
1833
|
]
|
|
1816
1834
|
},
|
|
1817
|
-
|
|
1818
|
-
description: "Preferred for glob/substring filtering of session history when ranked search is too fuzzy. Expand hits with
|
|
1835
|
+
gooseDump_grep: {
|
|
1836
|
+
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.",
|
|
1819
1837
|
snippet: "Filter session history by glob pattern",
|
|
1820
1838
|
preference: PREFER_HISTORY,
|
|
1821
1839
|
guidelines: [
|
|
1822
1840
|
PREFER_HISTORY,
|
|
1823
|
-
"Call
|
|
1841
|
+
"Call gooseDump_grep for exact substring or glob matches when ranked search is too fuzzy.",
|
|
1824
1842
|
HISTORY_WORKFLOW_GUIDELINE,
|
|
1825
1843
|
'Default scope is "lineage" (active branch); use scope: "all" for every branch in the session.',
|
|
1826
1844
|
HISTORY_TARGET_GUIDELINE
|
|
1827
1845
|
]
|
|
1828
1846
|
},
|
|
1829
|
-
|
|
1847
|
+
gooseDump_compact: {
|
|
1830
1848
|
description: "Preferred for proactive session compaction when context is large or nearing limits. Optional keep:N; runs through Pi's compaction flow.",
|
|
1831
1849
|
snippet: "Compact session history; optionally keep recent user turns",
|
|
1832
1850
|
preference: PREFER_COMPACT,
|
|
@@ -1837,7 +1855,7 @@ var GOOSE_TOOL_POLICIES = {
|
|
|
1837
1855
|
"Successful compaction may queue background memory learning."
|
|
1838
1856
|
]
|
|
1839
1857
|
},
|
|
1840
|
-
|
|
1858
|
+
gooseDump_sessions: {
|
|
1841
1859
|
description: "Preferred for listing or deleting coding-agent sessions scoped to the current working directory.",
|
|
1842
1860
|
snippet: "List or delete coding agent sessions for current directory",
|
|
1843
1861
|
preference: PREFER_SESSIONS,
|
|
@@ -1848,6 +1866,28 @@ var GOOSE_TOOL_POLICIES = {
|
|
|
1848
1866
|
]
|
|
1849
1867
|
}
|
|
1850
1868
|
};
|
|
1869
|
+
var GOOSE_TOOL_POLICIES = new Proxy(CANONICAL_GOOSE_TOOL_POLICIES, {
|
|
1870
|
+
get(target, prop, receiver) {
|
|
1871
|
+
if (typeof prop === "string" && prop in LEGACY_TO_CANONICAL_TOOL_NAMES) {
|
|
1872
|
+
const canonical = LEGACY_TO_CANONICAL_TOOL_NAMES[prop];
|
|
1873
|
+
return Reflect.get(target, canonical, receiver);
|
|
1874
|
+
}
|
|
1875
|
+
return Reflect.get(target, prop, receiver);
|
|
1876
|
+
},
|
|
1877
|
+
has(target, prop) {
|
|
1878
|
+
return prop in target || typeof prop === "string" && prop in LEGACY_TO_CANONICAL_TOOL_NAMES;
|
|
1879
|
+
},
|
|
1880
|
+
ownKeys(target) {
|
|
1881
|
+
return Reflect.ownKeys(target);
|
|
1882
|
+
},
|
|
1883
|
+
getOwnPropertyDescriptor(target, prop) {
|
|
1884
|
+
return Reflect.getOwnPropertyDescriptor(target, prop);
|
|
1885
|
+
}
|
|
1886
|
+
});
|
|
1887
|
+
function getGooseToolPolicy(name) {
|
|
1888
|
+
const canonical = resolveCanonicalToolName(name);
|
|
1889
|
+
return canonical ? CANONICAL_GOOSE_TOOL_POLICIES[canonical] : undefined;
|
|
1890
|
+
}
|
|
1851
1891
|
function renderToolRoutingPolicy(options = {}) {
|
|
1852
1892
|
const title = options.title ?? "Goose tool policy:";
|
|
1853
1893
|
const seen = new Set;
|
|
@@ -1934,22 +1974,108 @@ function upsertTextComponent(lastComponent, text) {
|
|
|
1934
1974
|
}
|
|
1935
1975
|
|
|
1936
1976
|
// src/tool-renderers.ts
|
|
1937
|
-
function
|
|
1977
|
+
function formatExpandedRecall(content, theme) {
|
|
1978
|
+
const boldFn = typeof theme?.bold === "function" ? theme.bold.bind(theme) : (t) => t;
|
|
1979
|
+
const fg = typeof theme?.fg === "function" ? theme.fg.bind(theme) : (_s, t) => t;
|
|
1980
|
+
return content.split(`
|
|
1981
|
+
`).map((line) => {
|
|
1982
|
+
const headMatch = line.match(/^(\s*)(\[mem_[^\]]+\])(\s+.*)$/);
|
|
1983
|
+
if (headMatch) {
|
|
1984
|
+
const [, indent, memId, rest] = headMatch;
|
|
1985
|
+
return `${indent} ${fg("accent", boldFn(memId))}${rest}`;
|
|
1986
|
+
}
|
|
1987
|
+
if (/^\s*(Match|Evidence|Relationships):/.test(line)) {
|
|
1988
|
+
return fg("muted", boldFn(line.trim()));
|
|
1989
|
+
}
|
|
1990
|
+
return line;
|
|
1991
|
+
}).join(`
|
|
1992
|
+
`);
|
|
1993
|
+
}
|
|
1994
|
+
function formatExpandedTranscriptLines(content, theme) {
|
|
1995
|
+
const boldFn = typeof theme?.bold === "function" ? theme.bold.bind(theme) : (t) => t;
|
|
1996
|
+
const fg = typeof theme?.fg === "function" ? theme.fg.bind(theme) : (_s, t) => t;
|
|
1997
|
+
return content.split(`
|
|
1998
|
+
`).map((line) => {
|
|
1999
|
+
const match = line.match(/^(\s*)(\[#[^\]]+\])(\s+([a-zA-Z_-]+):)?(\s*.*)$/);
|
|
2000
|
+
if (match) {
|
|
2001
|
+
const [, indent, id, , role, restText] = match;
|
|
2002
|
+
const styledId = fg("accent", boldFn(id));
|
|
2003
|
+
const styledRole = role ? ` ${fg("muted", `${role}:`)}` : "";
|
|
2004
|
+
const styledRest = restText ? ` ${restText.trimStart()}` : "";
|
|
2005
|
+
return `${indent} ${styledId}${styledRole}${styledRest}`;
|
|
2006
|
+
}
|
|
2007
|
+
return line;
|
|
2008
|
+
}).join(`
|
|
2009
|
+
`);
|
|
2010
|
+
}
|
|
2011
|
+
function formatExpandedGet(content, theme) {
|
|
2012
|
+
const boldFn = typeof theme?.bold === "function" ? theme.bold.bind(theme) : (t) => t;
|
|
2013
|
+
const fg = typeof theme?.fg === "function" ? theme.fg.bind(theme) : (_s, t) => t;
|
|
2014
|
+
return content.split(`
|
|
2015
|
+
`).map((line) => {
|
|
2016
|
+
const headerMatch = line.match(/^(\[#[^\]]+\])\s*([a-zA-Z_-]+)?:?$/);
|
|
2017
|
+
if (headerMatch) {
|
|
2018
|
+
const styledId = fg("accent", boldFn(headerMatch[1]));
|
|
2019
|
+
const styledRole = headerMatch[2] ? ` ${fg("muted", `${headerMatch[2]}:`)}` : "";
|
|
2020
|
+
return ` ${styledId}${styledRole}`;
|
|
2021
|
+
}
|
|
2022
|
+
if (line.trim() === "---") {
|
|
2023
|
+
return fg("dim", "───");
|
|
2024
|
+
}
|
|
2025
|
+
return line ? ` ${line}` : "";
|
|
2026
|
+
}).join(`
|
|
2027
|
+
`);
|
|
2028
|
+
}
|
|
2029
|
+
function formatExpandedSessions(content, theme) {
|
|
2030
|
+
const boldFn = typeof theme?.bold === "function" ? theme.bold.bind(theme) : (t) => t;
|
|
2031
|
+
const fg = typeof theme?.fg === "function" ? theme.fg.bind(theme) : (_s, t) => t;
|
|
2032
|
+
return content.split(`
|
|
2033
|
+
`).map((line) => {
|
|
2034
|
+
const match = line.match(/^(\s*)-\s+(\S+)(\s+\(active\))?(\s+\[.*?\])?(.*)$/);
|
|
2035
|
+
if (match) {
|
|
2036
|
+
const [, indent, sessionId, activePart, metaPart, extra] = match;
|
|
2037
|
+
const bullet = fg("dim", "•");
|
|
2038
|
+
const styledId = fg("accent", boldFn(sessionId));
|
|
2039
|
+
const styledActive = activePart ? ` ${fg("accent", boldFn("● active"))}` : "";
|
|
2040
|
+
const styledMeta = metaPart ? ` ${fg("dim", metaPart.trim())}` : "";
|
|
2041
|
+
return `${indent} ${bullet} ${styledId}${styledActive}${styledMeta}${extra ?? ""}`;
|
|
2042
|
+
}
|
|
2043
|
+
if (line.startsWith("Sessions for ")) {
|
|
2044
|
+
return fg("dim", line);
|
|
2045
|
+
}
|
|
2046
|
+
return line;
|
|
2047
|
+
}).join(`
|
|
2048
|
+
`);
|
|
2049
|
+
}
|
|
2050
|
+
function formatExpandedMemoryStatus(content, theme) {
|
|
2051
|
+
try {
|
|
2052
|
+
const parsed = JSON.parse(content);
|
|
2053
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
2054
|
+
const boldFn = typeof theme?.bold === "function" ? theme.bold.bind(theme) : (t) => t;
|
|
2055
|
+
const fg = typeof theme?.fg === "function" ? theme.fg.bind(theme) : (_s, t) => t;
|
|
2056
|
+
return Object.entries(parsed).map(([k, v]) => ` ${fg("muted", k)}: ${fg("accent", boldFn(String(v)))}`).join(`
|
|
2057
|
+
`);
|
|
2058
|
+
}
|
|
2059
|
+
} catch {}
|
|
2060
|
+
return content;
|
|
2061
|
+
}
|
|
2062
|
+
function renderGooseDumpRememberCall(args, theme, ...rest) {
|
|
1938
2063
|
const context = rest[0] ?? {};
|
|
1939
2064
|
const target = args?.session ? `${args?.provider ?? "pi"}:${args.session}` : "current session";
|
|
1940
|
-
const text = clampLineToWidth(`${renderToolLabel(theme, "
|
|
2065
|
+
const text = clampLineToWidth(`${renderToolLabel(theme, "gooseDump_remember")} ${theme.fg("accent", target)}`, context.width);
|
|
1941
2066
|
return upsertTextComponent(context.lastComponent, text);
|
|
1942
2067
|
}
|
|
1943
|
-
|
|
2068
|
+
var renderGooseRememberCall = renderGooseDumpRememberCall;
|
|
2069
|
+
function renderGooseDumpRememberResult(result, options, theme, ...rest) {
|
|
1944
2070
|
const { isPartial, isError, expanded, width } = resolveRenderResultContext(options, rest);
|
|
1945
2071
|
if (isPartial)
|
|
1946
|
-
return renderPendingResult("pending
|
|
2072
|
+
return renderPendingResult("pending gooseDump_remember", width, theme);
|
|
1947
2073
|
const content = result.content?.[0]?.text ?? "";
|
|
1948
2074
|
if (isError || result.isError) {
|
|
1949
2075
|
return renderErrorResult(content, {
|
|
1950
2076
|
expanded,
|
|
1951
2077
|
width,
|
|
1952
|
-
fallback: "
|
|
2078
|
+
fallback: "gooseDump_remember failed",
|
|
1953
2079
|
theme
|
|
1954
2080
|
});
|
|
1955
2081
|
}
|
|
@@ -1961,7 +2087,8 @@ function renderGooseRememberResult(result, options, theme, ...rest) {
|
|
|
1961
2087
|
});
|
|
1962
2088
|
return upsertTextComponent(rest[0]?.lastComponent, clampLineToWidth(summary, width));
|
|
1963
2089
|
}
|
|
1964
|
-
|
|
2090
|
+
var renderGooseRememberResult = renderGooseDumpRememberResult;
|
|
2091
|
+
function renderGooseDumpRecallCall(args, theme, ...rest) {
|
|
1965
2092
|
const context = rest[0] ?? {};
|
|
1966
2093
|
const query = typeof args?.query === "string" ? `"${args.query}"` : '""';
|
|
1967
2094
|
const flags = [
|
|
@@ -1971,16 +2098,22 @@ function renderGooseRecallCall(args, theme, ...rest) {
|
|
|
1971
2098
|
args?.history && "history"
|
|
1972
2099
|
].filter(Boolean);
|
|
1973
2100
|
const flagsBadge = flags.length > 0 ? theme.fg("dim", ` [${flags.join(", ")}]`) : "";
|
|
1974
|
-
const text = clampLineToWidth(`${renderToolLabel(theme, "
|
|
2101
|
+
const text = clampLineToWidth(`${renderToolLabel(theme, "gooseDump_recall")} ${theme.fg("accent", query)}${flagsBadge}`, context.width);
|
|
1975
2102
|
return upsertTextComponent(context.lastComponent, text);
|
|
1976
2103
|
}
|
|
1977
|
-
|
|
2104
|
+
var renderGooseRecallCall = renderGooseDumpRecallCall;
|
|
2105
|
+
function renderGooseDumpRecallResult(result, options, theme, ...rest) {
|
|
1978
2106
|
const { isPartial, isError, expanded, width } = resolveRenderResultContext(options, rest);
|
|
1979
2107
|
if (isPartial)
|
|
1980
|
-
return renderPendingResult("pending
|
|
2108
|
+
return renderPendingResult("pending gooseDump_recall", width, theme);
|
|
1981
2109
|
const content = result.content?.[0]?.text ?? "";
|
|
1982
2110
|
if (isError || result.isError) {
|
|
1983
|
-
return renderErrorResult(content, {
|
|
2111
|
+
return renderErrorResult(content, {
|
|
2112
|
+
expanded,
|
|
2113
|
+
width,
|
|
2114
|
+
fallback: "gooseDump_recall failed",
|
|
2115
|
+
theme
|
|
2116
|
+
});
|
|
1984
2117
|
}
|
|
1985
2118
|
if (content.startsWith("No durable memory") || content.startsWith("Durable memory is disabled") || content.startsWith("Memory recall dropped")) {
|
|
1986
2119
|
return upsertTextComponent(rest[0]?.lastComponent, clampLineToWidth(summaryLine(content, { theme, style: "dim" }), width));
|
|
@@ -1994,46 +2127,56 @@ function renderGooseRecallResult(result, options, theme, ...rest) {
|
|
|
1994
2127
|
theme,
|
|
1995
2128
|
style: "success"
|
|
1996
2129
|
});
|
|
2130
|
+
const formattedContent = expanded ? formatExpandedRecall(content, theme) : content;
|
|
1997
2131
|
const body = expanded ? `${summary}
|
|
1998
2132
|
|
|
1999
|
-
${
|
|
2133
|
+
${formattedContent}` : summary;
|
|
2000
2134
|
return upsertTextComponent(rest[0]?.lastComponent, clampLinesToWidth(body.split(`
|
|
2001
2135
|
`), width).join(`
|
|
2002
2136
|
`));
|
|
2003
2137
|
}
|
|
2004
|
-
|
|
2138
|
+
var renderGooseRecallResult = renderGooseDumpRecallResult;
|
|
2139
|
+
function renderGooseDumpForgetCall(args, theme, ...rest) {
|
|
2005
2140
|
const context = rest[0] ?? {};
|
|
2006
2141
|
const target = args?.target ? String(args.target) : '""';
|
|
2007
|
-
const text = clampLineToWidth(`${renderToolLabel(theme, "
|
|
2142
|
+
const text = clampLineToWidth(`${renderToolLabel(theme, "gooseDump_forget")} ${theme.fg("accent", target)}`, context.width);
|
|
2008
2143
|
return upsertTextComponent(context.lastComponent, text);
|
|
2009
2144
|
}
|
|
2010
|
-
|
|
2145
|
+
var renderGooseForgetCall = renderGooseDumpForgetCall;
|
|
2146
|
+
function renderGooseDumpForgetResult(result, options, theme, ...rest) {
|
|
2011
2147
|
const { isPartial, isError, expanded, width } = resolveRenderResultContext(options, rest);
|
|
2012
2148
|
if (isPartial)
|
|
2013
|
-
return renderPendingResult("pending
|
|
2149
|
+
return renderPendingResult("pending gooseDump_forget", width, theme);
|
|
2014
2150
|
const content = result.content?.[0]?.text ?? "";
|
|
2015
2151
|
if (isError || result.isError) {
|
|
2016
|
-
return renderErrorResult(content, {
|
|
2152
|
+
return renderErrorResult(content, {
|
|
2153
|
+
expanded,
|
|
2154
|
+
width,
|
|
2155
|
+
fallback: "gooseDump_forget failed",
|
|
2156
|
+
theme
|
|
2157
|
+
});
|
|
2017
2158
|
}
|
|
2018
2159
|
const isFailure = content.toLowerCase().includes("error");
|
|
2019
2160
|
const summary = summaryLine(content, { theme, style: isFailure ? "error" : "success" });
|
|
2020
2161
|
return upsertTextComponent(rest[0]?.lastComponent, clampLineToWidth(summary, width));
|
|
2021
2162
|
}
|
|
2022
|
-
|
|
2163
|
+
var renderGooseForgetResult = renderGooseDumpForgetResult;
|
|
2164
|
+
function renderGooseDumpMemoryStatusCall(_args, theme, ...rest) {
|
|
2023
2165
|
const context = rest[0] ?? {};
|
|
2024
|
-
const text = clampLineToWidth(renderToolLabel(theme, "
|
|
2166
|
+
const text = clampLineToWidth(renderToolLabel(theme, "gooseDump_memory_status"), context.width);
|
|
2025
2167
|
return upsertTextComponent(context.lastComponent, text);
|
|
2026
2168
|
}
|
|
2027
|
-
|
|
2169
|
+
var renderGooseMemoryStatusCall = renderGooseDumpMemoryStatusCall;
|
|
2170
|
+
function renderGooseDumpMemoryStatusResult(result, options, theme, ...rest) {
|
|
2028
2171
|
const { isPartial, isError, expanded, width } = resolveRenderResultContext(options, rest);
|
|
2029
2172
|
if (isPartial)
|
|
2030
|
-
return renderPendingResult("pending
|
|
2173
|
+
return renderPendingResult("pending gooseDump_memory_status", width, theme);
|
|
2031
2174
|
const content = result.content?.[0]?.text ?? "";
|
|
2032
2175
|
if (isError || result.isError) {
|
|
2033
2176
|
return renderErrorResult(content, {
|
|
2034
2177
|
expanded,
|
|
2035
2178
|
width,
|
|
2036
|
-
fallback: "
|
|
2179
|
+
fallback: "gooseDump_memory_status failed",
|
|
2037
2180
|
theme
|
|
2038
2181
|
});
|
|
2039
2182
|
}
|
|
@@ -2053,14 +2196,16 @@ function renderGooseMemoryStatusResult(result, options, theme, ...rest) {
|
|
|
2053
2196
|
summaryText = firstLine;
|
|
2054
2197
|
}
|
|
2055
2198
|
const summary = summaryLine(summaryText, { hidden: !expanded, theme, style: "success" });
|
|
2199
|
+
const formattedContent = expanded ? formatExpandedMemoryStatus(content, theme) : content;
|
|
2056
2200
|
const body = expanded ? `${summary}
|
|
2057
2201
|
|
|
2058
|
-
${
|
|
2202
|
+
${formattedContent}` : summary;
|
|
2059
2203
|
return upsertTextComponent(rest[0]?.lastComponent, clampLinesToWidth(body.split(`
|
|
2060
2204
|
`), width).join(`
|
|
2061
2205
|
`));
|
|
2062
2206
|
}
|
|
2063
|
-
|
|
2207
|
+
var renderGooseMemoryStatusResult = renderGooseDumpMemoryStatusResult;
|
|
2208
|
+
function renderGooseDumpSearchCall(args, theme, ...rest) {
|
|
2064
2209
|
const context = rest[0] ?? {};
|
|
2065
2210
|
const query = typeof args?.query === "string" ? `"${args.query}"` : '""';
|
|
2066
2211
|
const target = args?.session ? theme.fg("dim", ` in ${args.provider ?? "pi"}:${args.session}`) : "";
|
|
@@ -2069,16 +2214,22 @@ function renderGooseSearchCall(args, theme, ...rest) {
|
|
|
2069
2214
|
args?.page && args.page > 1 && `page=${args.page}`
|
|
2070
2215
|
].filter(Boolean);
|
|
2071
2216
|
const flagsBadge = flags.length > 0 ? theme.fg("dim", ` [${flags.join(", ")}]`) : "";
|
|
2072
|
-
const text = clampLineToWidth(`${renderToolLabel(theme, "
|
|
2217
|
+
const text = clampLineToWidth(`${renderToolLabel(theme, "gooseDump_search")} ${theme.fg("accent", query)}${target}${flagsBadge}`, context.width);
|
|
2073
2218
|
return upsertTextComponent(context.lastComponent, text);
|
|
2074
2219
|
}
|
|
2075
|
-
|
|
2220
|
+
var renderGooseSearchCall = renderGooseDumpSearchCall;
|
|
2221
|
+
function renderGooseDumpSearchResult(result, options, theme, ...rest) {
|
|
2076
2222
|
const { isPartial, isError, expanded, width } = resolveRenderResultContext(options, rest);
|
|
2077
2223
|
if (isPartial)
|
|
2078
|
-
return renderPendingResult("pending
|
|
2224
|
+
return renderPendingResult("pending gooseDump_search", width, theme);
|
|
2079
2225
|
const content = result.content?.[0]?.text ?? "";
|
|
2080
2226
|
if (isError || result.isError) {
|
|
2081
|
-
return renderErrorResult(content, {
|
|
2227
|
+
return renderErrorResult(content, {
|
|
2228
|
+
expanded,
|
|
2229
|
+
width,
|
|
2230
|
+
fallback: "gooseDump_search failed",
|
|
2231
|
+
theme
|
|
2232
|
+
});
|
|
2082
2233
|
}
|
|
2083
2234
|
if (content.startsWith("No results")) {
|
|
2084
2235
|
return upsertTextComponent(rest[0]?.lastComponent, clampLineToWidth(summaryLine(content, { theme, style: "dim" }), width));
|
|
@@ -2094,28 +2245,31 @@ function renderGooseSearchResult(result, options, theme, ...rest) {
|
|
|
2094
2245
|
theme,
|
|
2095
2246
|
style: "success"
|
|
2096
2247
|
});
|
|
2248
|
+
const formattedContent = expanded ? formatExpandedTranscriptLines(content, theme) : content;
|
|
2097
2249
|
const body = expanded ? `${summary}
|
|
2098
2250
|
|
|
2099
|
-
${
|
|
2251
|
+
${formattedContent}` : summary;
|
|
2100
2252
|
return upsertTextComponent(rest[0]?.lastComponent, clampLinesToWidth(body.split(`
|
|
2101
2253
|
`), width).join(`
|
|
2102
2254
|
`));
|
|
2103
2255
|
}
|
|
2104
|
-
|
|
2256
|
+
var renderGooseSearchResult = renderGooseDumpSearchResult;
|
|
2257
|
+
function renderGooseDumpGetCall(args, theme, ...rest) {
|
|
2105
2258
|
const context = rest[0] ?? {};
|
|
2106
2259
|
const ids = Array.isArray(args?.ids) ? args.ids : [];
|
|
2107
2260
|
const idsDisplay = ids.length <= 3 ? ids.join(", ") : `${ids.slice(0, 3).join(", ")}… (${ids.length})`;
|
|
2108
2261
|
const target = args?.session ? theme.fg("dim", ` in ${args.provider ?? "pi"}:${args.session}`) : "";
|
|
2109
|
-
const text = clampLineToWidth(`${renderToolLabel(theme, "
|
|
2262
|
+
const text = clampLineToWidth(`${renderToolLabel(theme, "gooseDump_get")} ${theme.fg("accent", `[${idsDisplay}]`)}${target}`, context.width);
|
|
2110
2263
|
return upsertTextComponent(context.lastComponent, text);
|
|
2111
2264
|
}
|
|
2112
|
-
|
|
2265
|
+
var renderGooseGetCall = renderGooseDumpGetCall;
|
|
2266
|
+
function renderGooseDumpGetResult(result, options, theme, ...rest) {
|
|
2113
2267
|
const { isPartial, isError, expanded, width } = resolveRenderResultContext(options, rest);
|
|
2114
2268
|
if (isPartial)
|
|
2115
|
-
return renderPendingResult("pending
|
|
2269
|
+
return renderPendingResult("pending gooseDump_get", width, theme);
|
|
2116
2270
|
const content = result.content?.[0]?.text ?? "";
|
|
2117
2271
|
if (isError || result.isError) {
|
|
2118
|
-
return renderErrorResult(content, { expanded, width, fallback: "
|
|
2272
|
+
return renderErrorResult(content, { expanded, width, fallback: "gooseDump_get failed", theme });
|
|
2119
2273
|
}
|
|
2120
2274
|
if (content.startsWith("No entries found")) {
|
|
2121
2275
|
return upsertTextComponent(rest[0]?.lastComponent, clampLineToWidth(summaryLine("no entries found", { theme, style: "dim" }), width));
|
|
@@ -2128,29 +2282,37 @@ function renderGooseGetResult(result, options, theme, ...rest) {
|
|
|
2128
2282
|
theme,
|
|
2129
2283
|
style: "success"
|
|
2130
2284
|
});
|
|
2285
|
+
const formattedContent = expanded ? formatExpandedGet(content, theme) : content;
|
|
2131
2286
|
const body = expanded ? `${summary}
|
|
2132
2287
|
|
|
2133
|
-
${
|
|
2288
|
+
${formattedContent}` : summary;
|
|
2134
2289
|
return upsertTextComponent(rest[0]?.lastComponent, clampLinesToWidth(body.split(`
|
|
2135
2290
|
`), width).join(`
|
|
2136
2291
|
`));
|
|
2137
2292
|
}
|
|
2138
|
-
|
|
2293
|
+
var renderGooseGetResult = renderGooseDumpGetResult;
|
|
2294
|
+
function renderGooseDumpGrepCall(args, theme, ...rest) {
|
|
2139
2295
|
const context = rest[0] ?? {};
|
|
2140
2296
|
const pattern = typeof args?.pattern === "string" ? `/${args.pattern}/` : "//";
|
|
2141
2297
|
const target = args?.session ? theme.fg("dim", ` in ${args.provider ?? "pi"}:${args.session}`) : "";
|
|
2142
2298
|
const flags = [args?.scope && args.scope !== "lineage" && `scope=${args.scope}`].filter(Boolean);
|
|
2143
2299
|
const flagsBadge = flags.length > 0 ? theme.fg("dim", ` [${flags.join(", ")}]`) : "";
|
|
2144
|
-
const text = clampLineToWidth(`${renderToolLabel(theme, "
|
|
2300
|
+
const text = clampLineToWidth(`${renderToolLabel(theme, "gooseDump_grep")} ${theme.fg("accent", pattern)}${target}${flagsBadge}`, context.width);
|
|
2145
2301
|
return upsertTextComponent(context.lastComponent, text);
|
|
2146
2302
|
}
|
|
2147
|
-
|
|
2303
|
+
var renderGooseGrepCall = renderGooseDumpGrepCall;
|
|
2304
|
+
function renderGooseDumpGrepResult(result, options, theme, ...rest) {
|
|
2148
2305
|
const { isPartial, isError, expanded, width } = resolveRenderResultContext(options, rest);
|
|
2149
2306
|
if (isPartial)
|
|
2150
|
-
return renderPendingResult("pending
|
|
2307
|
+
return renderPendingResult("pending gooseDump_grep", width, theme);
|
|
2151
2308
|
const content = result.content?.[0]?.text ?? "";
|
|
2152
2309
|
if (isError || result.isError) {
|
|
2153
|
-
return renderErrorResult(content, {
|
|
2310
|
+
return renderErrorResult(content, {
|
|
2311
|
+
expanded,
|
|
2312
|
+
width,
|
|
2313
|
+
fallback: "gooseDump_grep failed",
|
|
2314
|
+
theme
|
|
2315
|
+
});
|
|
2154
2316
|
}
|
|
2155
2317
|
if (content.startsWith("No matches")) {
|
|
2156
2318
|
return upsertTextComponent(rest[0]?.lastComponent, clampLineToWidth(summaryLine(content, { theme, style: "dim" }), width));
|
|
@@ -2160,50 +2322,60 @@ function renderGooseGrepResult(result, options, theme, ...rest) {
|
|
|
2160
2322
|
`).filter((l) => l.trim().length > 0).length;
|
|
2161
2323
|
const unit = count === 1 ? "match" : "matches";
|
|
2162
2324
|
const summary = summaryLine(`${count} ${unit}`, { hidden: !expanded, theme, style: "success" });
|
|
2325
|
+
const formattedContent = expanded ? formatExpandedTranscriptLines(content, theme) : content;
|
|
2163
2326
|
const body = expanded ? `${summary}
|
|
2164
2327
|
|
|
2165
|
-
${
|
|
2328
|
+
${formattedContent}` : summary;
|
|
2166
2329
|
return upsertTextComponent(rest[0]?.lastComponent, clampLinesToWidth(body.split(`
|
|
2167
2330
|
`), width).join(`
|
|
2168
2331
|
`));
|
|
2169
2332
|
}
|
|
2170
|
-
|
|
2333
|
+
var renderGooseGrepResult = renderGooseDumpGrepResult;
|
|
2334
|
+
function renderGooseDumpCompactCall(args, theme, ...rest) {
|
|
2171
2335
|
const context = rest[0] ?? {};
|
|
2172
2336
|
const flags = args?.keep ? [theme.fg("dim", `keep=${args.keep}`)] : [];
|
|
2173
2337
|
const flagsBadge = flags.length > 0 ? ` [${flags.join(", ")}]` : "";
|
|
2174
|
-
const text = clampLineToWidth(`${renderToolLabel(theme, "
|
|
2338
|
+
const text = clampLineToWidth(`${renderToolLabel(theme, "gooseDump_compact")}${flagsBadge}`, context.width);
|
|
2175
2339
|
return upsertTextComponent(context.lastComponent, text);
|
|
2176
2340
|
}
|
|
2177
|
-
|
|
2341
|
+
var renderGooseCompactCall = renderGooseDumpCompactCall;
|
|
2342
|
+
function renderGooseDumpCompactResult(result, options, theme, ...rest) {
|
|
2178
2343
|
const { isPartial, isError, expanded, width } = resolveRenderResultContext(options, rest);
|
|
2179
2344
|
if (isPartial)
|
|
2180
|
-
return renderPendingResult("pending
|
|
2345
|
+
return renderPendingResult("pending gooseDump_compact", width, theme);
|
|
2181
2346
|
const content = result.content?.[0]?.text ?? "";
|
|
2182
2347
|
if (isError || result.isError) {
|
|
2183
|
-
return renderErrorResult(content, {
|
|
2348
|
+
return renderErrorResult(content, {
|
|
2349
|
+
expanded,
|
|
2350
|
+
width,
|
|
2351
|
+
fallback: "gooseDump_compact failed",
|
|
2352
|
+
theme
|
|
2353
|
+
});
|
|
2184
2354
|
}
|
|
2185
2355
|
const style = content.includes("already in progress") ? "warning" : content.includes("Nothing to compact") ? "dim" : "success";
|
|
2186
2356
|
const summary = summaryLine(content.split(`
|
|
2187
2357
|
`)[0] || "compaction completed", { theme, style });
|
|
2188
2358
|
return upsertTextComponent(rest[0]?.lastComponent, clampLineToWidth(summary, width));
|
|
2189
2359
|
}
|
|
2190
|
-
|
|
2360
|
+
var renderGooseCompactResult = renderGooseDumpCompactResult;
|
|
2361
|
+
function renderGooseDumpSessionsCall(args, theme, ...rest) {
|
|
2191
2362
|
const context = rest[0] ?? {};
|
|
2192
2363
|
const action = args?.action ?? "list";
|
|
2193
2364
|
const target = args?.session ? `${args?.provider ?? "pi"}:${args.session}` : `(${args?.provider ?? "pi"})`;
|
|
2194
|
-
const text = clampLineToWidth(`${renderToolLabel(theme, "
|
|
2365
|
+
const text = clampLineToWidth(`${renderToolLabel(theme, "gooseDump_sessions")} ${theme.fg("accent", action)} ${theme.fg("dim", target)}`, context.width);
|
|
2195
2366
|
return upsertTextComponent(context.lastComponent, text);
|
|
2196
2367
|
}
|
|
2197
|
-
|
|
2368
|
+
var renderGooseSessionsCall = renderGooseDumpSessionsCall;
|
|
2369
|
+
function renderGooseDumpSessionsResult(result, options, theme, ...rest) {
|
|
2198
2370
|
const { isPartial, isError, expanded, width } = resolveRenderResultContext(options, rest);
|
|
2199
2371
|
if (isPartial)
|
|
2200
|
-
return renderPendingResult("pending
|
|
2372
|
+
return renderPendingResult("pending gooseDump_sessions", width, theme);
|
|
2201
2373
|
const content = result.content?.[0]?.text ?? "";
|
|
2202
2374
|
if (isError || result.isError) {
|
|
2203
2375
|
return renderErrorResult(content, {
|
|
2204
2376
|
expanded,
|
|
2205
2377
|
width,
|
|
2206
|
-
fallback: "
|
|
2378
|
+
fallback: "gooseDump_sessions failed",
|
|
2207
2379
|
theme
|
|
2208
2380
|
});
|
|
2209
2381
|
}
|
|
@@ -2223,13 +2395,15 @@ function renderGooseSessionsResult(result, options, theme, ...rest) {
|
|
|
2223
2395
|
theme,
|
|
2224
2396
|
style: "success"
|
|
2225
2397
|
});
|
|
2398
|
+
const formattedContent = expanded ? formatExpandedSessions(content, theme) : content;
|
|
2226
2399
|
const body = expanded ? `${summary}
|
|
2227
2400
|
|
|
2228
|
-
${
|
|
2401
|
+
${formattedContent}` : summary;
|
|
2229
2402
|
return upsertTextComponent(rest[0]?.lastComponent, clampLinesToWidth(body.split(`
|
|
2230
2403
|
`), width).join(`
|
|
2231
2404
|
`));
|
|
2232
2405
|
}
|
|
2406
|
+
var renderGooseSessionsResult = renderGooseDumpSessionsResult;
|
|
2233
2407
|
|
|
2234
2408
|
// src/tools.ts
|
|
2235
2409
|
function memoryDisabledResult() {
|
|
@@ -2282,7 +2456,7 @@ function boundedHistoryResult(text) {
|
|
|
2282
2456
|
return textResult(text);
|
|
2283
2457
|
return textResult(`${output.content}
|
|
2284
2458
|
|
|
2285
|
-
[Output truncated: showing ${output.outputLines} of ${output.totalLines} lines ` + `and ${output.outputBytes} of ${output.totalBytes} bytes. ` + "Use
|
|
2459
|
+
[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.]");
|
|
2286
2460
|
}
|
|
2287
2461
|
function resolveHistoryTarget(ctx, tool, params) {
|
|
2288
2462
|
const provider = params.provider ?? "pi";
|
|
@@ -2297,7 +2471,10 @@ function resolveHistoryTarget(ctx, tool, params) {
|
|
|
2297
2471
|
};
|
|
2298
2472
|
}
|
|
2299
2473
|
function gooseToolMeta(name) {
|
|
2300
|
-
const policy =
|
|
2474
|
+
const policy = getGooseToolPolicy(name);
|
|
2475
|
+
if (!policy) {
|
|
2476
|
+
throw new Error(`Unknown goose tool policy: ${name}`);
|
|
2477
|
+
}
|
|
2301
2478
|
return {
|
|
2302
2479
|
name,
|
|
2303
2480
|
label: name,
|
|
@@ -2312,7 +2489,7 @@ function defineGooseTool(name, parameters, handler, renderers) {
|
|
|
2312
2489
|
parameters,
|
|
2313
2490
|
async execute(_id, params, signal, _onUpdate, ctx) {
|
|
2314
2491
|
try {
|
|
2315
|
-
return await handler(params, signal, ctx);
|
|
2492
|
+
return await handler(params, signal, ctx, name);
|
|
2316
2493
|
} catch (err) {
|
|
2317
2494
|
return goosedumpErrorResult(err);
|
|
2318
2495
|
}
|
|
@@ -2323,11 +2500,15 @@ function defineGooseTool(name, parameters, handler, renderers) {
|
|
|
2323
2500
|
}
|
|
2324
2501
|
function registerGooseTools(pi, deps) {
|
|
2325
2502
|
const { nativeExecutablePath, enqueueRemember, requestCompaction, runNonCompactInference } = deps;
|
|
2326
|
-
|
|
2503
|
+
function registerPair(canonicalName, legacyName, parameters, handler, renderers) {
|
|
2504
|
+
pi.registerTool(defineGooseTool(canonicalName, parameters, handler, renderers));
|
|
2505
|
+
pi.registerTool(defineGooseTool(legacyName, parameters, handler, renderers));
|
|
2506
|
+
}
|
|
2507
|
+
registerPair("gooseDump_remember", "goose_remember", Type3.Object({ ...historyTargetParams() }), async (params, _signal, ctx, toolName) => {
|
|
2327
2508
|
const disabled = requireMemoryEnabled(ctx);
|
|
2328
2509
|
if (disabled)
|
|
2329
2510
|
return disabled;
|
|
2330
|
-
const resolved = resolveHistoryTarget(ctx,
|
|
2511
|
+
const resolved = resolveHistoryTarget(ctx, toolName, params);
|
|
2331
2512
|
if (!resolved.ok)
|
|
2332
2513
|
return resolved.result;
|
|
2333
2514
|
const accepted = enqueueRemember(resolved.target, ctx, (message) => {
|
|
@@ -2336,8 +2517,8 @@ function registerGooseTools(pi, deps) {
|
|
|
2336
2517
|
}
|
|
2337
2518
|
});
|
|
2338
2519
|
return textResult(accepted ? `Memory learning started for ${resolved.target}.` : `Memory learning dropped for ${resolved.target}: another inference task is active.`);
|
|
2339
|
-
}, { renderCall: renderGooseRememberCall, renderResult: renderGooseRememberResult })
|
|
2340
|
-
|
|
2520
|
+
}, { renderCall: renderGooseRememberCall, renderResult: renderGooseRememberResult });
|
|
2521
|
+
registerPair("gooseDump_recall", "goose_recall", Type3.Object({
|
|
2341
2522
|
query: Type3.String({ description: PARAM_DESCRIPTIONS.memoryQuery }),
|
|
2342
2523
|
type: Type3.Optional(Type3.Union(GOOSE_MEMORY_TYPES.map((type) => Type3.Literal(type)), { description: PARAM_DESCRIPTIONS.memoryType })),
|
|
2343
2524
|
allProjects: Type3.Optional(Type3.Boolean({
|
|
@@ -2373,28 +2554,28 @@ function registerGooseTools(pi, deps) {
|
|
|
2373
2554
|
if (hits.length === 0)
|
|
2374
2555
|
return textResult(`No durable memory for "${params.query}"`);
|
|
2375
2556
|
return textResult(formatMemoryHits(hits));
|
|
2376
|
-
}, { renderCall: renderGooseRecallCall, renderResult: renderGooseRecallResult })
|
|
2377
|
-
|
|
2557
|
+
}, { renderCall: renderGooseRecallCall, renderResult: renderGooseRecallResult });
|
|
2558
|
+
registerPair("gooseDump_forget", "goose_forget", Type3.Object({
|
|
2378
2559
|
target: Type3.String({
|
|
2379
2560
|
description: PARAM_DESCRIPTIONS.forgetTarget
|
|
2380
2561
|
})
|
|
2381
|
-
}), async (params, signal, ctx) => {
|
|
2562
|
+
}), async (params, signal, ctx, toolName) => {
|
|
2382
2563
|
const disabled = requireMemoryEnabled(ctx);
|
|
2383
2564
|
if (disabled)
|
|
2384
2565
|
return disabled;
|
|
2385
2566
|
if (params.target.trim().length === 0) {
|
|
2386
|
-
return textResult(
|
|
2567
|
+
return textResult(`${toolName} error: target is required`);
|
|
2387
2568
|
}
|
|
2388
2569
|
const res = await goosedumpMemoryForget(params.target.trim(), signal, nativeExecutablePath);
|
|
2389
2570
|
return textResult(res);
|
|
2390
|
-
}, { renderCall: renderGooseForgetCall, renderResult: renderGooseForgetResult })
|
|
2391
|
-
|
|
2571
|
+
}, { renderCall: renderGooseForgetCall, renderResult: renderGooseForgetResult });
|
|
2572
|
+
registerPair("gooseDump_memory_status", "goose_memory_status", Type3.Object({}), async (_params, signal, ctx) => {
|
|
2392
2573
|
const disabled = requireMemoryEnabled(ctx);
|
|
2393
2574
|
if (disabled)
|
|
2394
2575
|
return disabled;
|
|
2395
2576
|
return textResult(await goosedumpMemoryStatus(signal, nativeExecutablePath));
|
|
2396
|
-
}, { renderCall: renderGooseMemoryStatusCall, renderResult: renderGooseMemoryStatusResult })
|
|
2397
|
-
|
|
2577
|
+
}, { renderCall: renderGooseMemoryStatusCall, renderResult: renderGooseMemoryStatusResult });
|
|
2578
|
+
registerPair("gooseDump_search", "goose_search", Type3.Object({
|
|
2398
2579
|
query: Type3.String({ description: PARAM_DESCRIPTIONS.searchQuery }),
|
|
2399
2580
|
...historyBranchParams(),
|
|
2400
2581
|
page: Type3.Optional(Type3.Integer({
|
|
@@ -2402,8 +2583,8 @@ function registerGooseTools(pi, deps) {
|
|
|
2402
2583
|
default: 1,
|
|
2403
2584
|
description: PARAM_DESCRIPTIONS.page
|
|
2404
2585
|
}))
|
|
2405
|
-
}), async (params, signal, ctx) => {
|
|
2406
|
-
const resolved = resolveHistoryTarget(ctx,
|
|
2586
|
+
}), async (params, signal, ctx, toolName) => {
|
|
2587
|
+
const resolved = resolveHistoryTarget(ctx, toolName, params);
|
|
2407
2588
|
if (!resolved.ok)
|
|
2408
2589
|
return resolved.result;
|
|
2409
2590
|
const page = params.page ?? 1;
|
|
@@ -2415,15 +2596,15 @@ function registerGooseTools(pi, deps) {
|
|
|
2415
2596
|
return textResult(`Results for "${params.query}" (page ${page}):
|
|
2416
2597
|
|
|
2417
2598
|
${text}`);
|
|
2418
|
-
}, { renderCall: renderGooseSearchCall, renderResult: renderGooseSearchResult })
|
|
2419
|
-
|
|
2599
|
+
}, { renderCall: renderGooseSearchCall, renderResult: renderGooseSearchResult });
|
|
2600
|
+
registerPair("gooseDump_get", "goose_get", Type3.Object({
|
|
2420
2601
|
ids: Type3.Array(Type3.String(), {
|
|
2421
2602
|
minItems: 1,
|
|
2422
2603
|
description: PARAM_DESCRIPTIONS.entryIds
|
|
2423
2604
|
}),
|
|
2424
2605
|
...historyBranchParams()
|
|
2425
|
-
}), async (params, signal, ctx) => {
|
|
2426
|
-
const resolved = resolveHistoryTarget(ctx,
|
|
2606
|
+
}), async (params, signal, ctx, toolName) => {
|
|
2607
|
+
const resolved = resolveHistoryTarget(ctx, toolName, params);
|
|
2427
2608
|
if (!resolved.ok)
|
|
2428
2609
|
return resolved.result;
|
|
2429
2610
|
const messages = await goosedumpShow(resolved.target, { scope: resolved.scope, ids: params.ids }, signal, nativeExecutablePath);
|
|
@@ -2431,12 +2612,12 @@ ${text}`);
|
|
|
2431
2612
|
return textResult("No entries found for the given IDs.");
|
|
2432
2613
|
}
|
|
2433
2614
|
return boundedHistoryResult(formatMessagesFull(messages));
|
|
2434
|
-
}, { renderCall: renderGooseGetCall, renderResult: renderGooseGetResult })
|
|
2435
|
-
|
|
2615
|
+
}, { renderCall: renderGooseGetCall, renderResult: renderGooseGetResult });
|
|
2616
|
+
registerPair("gooseDump_grep", "goose_grep", Type3.Object({
|
|
2436
2617
|
pattern: Type3.String({ description: PARAM_DESCRIPTIONS.pattern }),
|
|
2437
2618
|
...historyBranchParams()
|
|
2438
|
-
}), async (params, signal, ctx) => {
|
|
2439
|
-
const resolved = resolveHistoryTarget(ctx,
|
|
2619
|
+
}), async (params, signal, ctx, toolName) => {
|
|
2620
|
+
const resolved = resolveHistoryTarget(ctx, toolName, params);
|
|
2440
2621
|
if (!resolved.ok)
|
|
2441
2622
|
return resolved.result;
|
|
2442
2623
|
const messages = await goosedumpGrep(resolved.target, params.pattern, { scope: resolved.scope }, signal, nativeExecutablePath);
|
|
@@ -2444,8 +2625,8 @@ ${text}`);
|
|
|
2444
2625
|
return textResult(`No matches for "${params.pattern}"`);
|
|
2445
2626
|
}
|
|
2446
2627
|
return boundedHistoryResult(formatMessagesCompact(messages));
|
|
2447
|
-
}, { renderCall: renderGooseGrepCall, renderResult: renderGooseGrepResult })
|
|
2448
|
-
|
|
2628
|
+
}, { renderCall: renderGooseGrepCall, renderResult: renderGooseGrepResult });
|
|
2629
|
+
registerPair("gooseDump_compact", "goose_compact", Type3.Object({
|
|
2449
2630
|
keep: Type3.Optional(Type3.Integer({
|
|
2450
2631
|
minimum: 1,
|
|
2451
2632
|
description: PARAM_DESCRIPTIONS.keep
|
|
@@ -2459,8 +2640,8 @@ ${text}`);
|
|
|
2459
2640
|
return textResult("Nothing to compact (session too small).");
|
|
2460
2641
|
}
|
|
2461
2642
|
return textResult(compactStartedMessage(keep, result === "queued"));
|
|
2462
|
-
}, { renderCall: renderGooseCompactCall, renderResult: renderGooseCompactResult })
|
|
2463
|
-
|
|
2643
|
+
}, { renderCall: renderGooseCompactCall, renderResult: renderGooseCompactResult });
|
|
2644
|
+
registerPair("gooseDump_sessions", "goose_sessions", Type3.Object({
|
|
2464
2645
|
action: Type3.Optional(Type3.Union([Type3.Literal("list"), Type3.Literal("delete")], {
|
|
2465
2646
|
default: "list",
|
|
2466
2647
|
description: PARAM_DESCRIPTIONS.sessionsAction
|
|
@@ -2469,7 +2650,7 @@ ${text}`);
|
|
|
2469
2650
|
session: Type3.Optional(Type3.String({
|
|
2470
2651
|
description: PARAM_DESCRIPTIONS.sessionsDeleteId
|
|
2471
2652
|
}))
|
|
2472
|
-
}), async (params, signal, ctx) => {
|
|
2653
|
+
}), async (params, signal, ctx, toolName) => {
|
|
2473
2654
|
const action = params.action ?? "list";
|
|
2474
2655
|
const provider = params.provider ?? "pi";
|
|
2475
2656
|
const currentTarget = currentSessionTarget(ctx);
|
|
@@ -2477,7 +2658,7 @@ ${text}`);
|
|
|
2477
2658
|
const cwdSessions = sessions.filter((s) => s.cwd === ctx.cwd && s.provider === provider);
|
|
2478
2659
|
if (action === "delete") {
|
|
2479
2660
|
if (!params.session) {
|
|
2480
|
-
return textResult(
|
|
2661
|
+
return textResult(`${toolName} error: session ID is required for action: delete`);
|
|
2481
2662
|
}
|
|
2482
2663
|
const target = formatTarget(provider, params.session);
|
|
2483
2664
|
if (!cwdSessions.some((session) => session.id === params.session)) {
|
|
@@ -2504,7 +2685,7 @@ ${text}`);
|
|
|
2504
2685
|
|
|
2505
2686
|
${lines.join(`
|
|
2506
2687
|
`)}`);
|
|
2507
|
-
}, { renderCall: renderGooseSessionsCall, renderResult: renderGooseSessionsResult })
|
|
2688
|
+
}, { renderCall: renderGooseSessionsCall, renderResult: renderGooseSessionsResult });
|
|
2508
2689
|
}
|
|
2509
2690
|
|
|
2510
2691
|
// src/tui.ts
|
|
@@ -2588,7 +2769,7 @@ class NumberInputSubmenu {
|
|
|
2588
2769
|
}
|
|
2589
2770
|
render(width) {
|
|
2590
2771
|
return [
|
|
2591
|
-
|
|
2772
|
+
` \x1B[1m${this.title}\x1B[22m ${this.hint(`· current ${this.currentValue ?? "inherit"} · ${this.min}-${this.max}`)}`,
|
|
2592
2773
|
"",
|
|
2593
2774
|
...this.input.render(width),
|
|
2594
2775
|
"",
|
|
@@ -2609,14 +2790,15 @@ function overlayColors(theme) {
|
|
|
2609
2790
|
text: (s) => theme.fg("text", s),
|
|
2610
2791
|
dim: (s) => theme.fg("dim", s),
|
|
2611
2792
|
muted: (s) => theme.fg("muted", s),
|
|
2612
|
-
bold: (s) => theme.bold?.(s) ?? s
|
|
2793
|
+
bold: (s) => theme.bold?.(s) ?? s,
|
|
2794
|
+
error: (s) => theme.fg("error", s)
|
|
2613
2795
|
};
|
|
2614
2796
|
}
|
|
2615
2797
|
function overlayInnerWidth(width) {
|
|
2616
2798
|
return Math.max(1, width - 4);
|
|
2617
2799
|
}
|
|
2618
2800
|
function overlayHeader(colors, width, title) {
|
|
2619
|
-
const styled = colors.accent(` ${title} `);
|
|
2801
|
+
const styled = colors.accent(colors.bold(` ${title} `));
|
|
2620
2802
|
const fill = colors.borderFg("─".repeat(Math.max(0, width - 4 - visibleWidth2(styled))));
|
|
2621
2803
|
return `${colors.borderFg("╭─")}${styled}${fill}${colors.borderFg("─╮")}`;
|
|
2622
2804
|
}
|
|
@@ -2625,8 +2807,9 @@ function overlayFooter(colors, width) {
|
|
|
2625
2807
|
}
|
|
2626
2808
|
function overlayError(colors, width, message) {
|
|
2627
2809
|
const innerW = overlayInnerWidth(width);
|
|
2810
|
+
const errorFn = colors.error ?? colors.muted;
|
|
2628
2811
|
return [
|
|
2629
|
-
makeRow(colors.
|
|
2812
|
+
makeRow(errorFn(colors.bold(message)), innerW, colors.border),
|
|
2630
2813
|
makeRow(colors.dim("esc close"), innerW, colors.border)
|
|
2631
2814
|
];
|
|
2632
2815
|
}
|
|
@@ -2760,7 +2943,7 @@ async function runSettingsEditor(ctx) {
|
|
|
2760
2943
|
} else if (tab === "help") {
|
|
2761
2944
|
const shortcutWidth = Math.max(visibleWidth2("Shortcut"), ...helpRows.map(([shortcut]) => visibleWidth2(shortcut)));
|
|
2762
2945
|
const descriptionWidth = Math.max(1, innerW - shortcutWidth - 4);
|
|
2763
|
-
content.push(
|
|
2946
|
+
content.push(` ${bold(text(pad("Shortcut", shortcutWidth)))} ${bold(text("Description"))}`, dim(` ${"─".repeat(shortcutWidth)} ${"─".repeat(Math.min(descriptionWidth, 40))}`), ...helpRows.map(([shortcut, description]) => ` ${accent(bold(pad(shortcut, shortcutWidth)))} ${text(truncateToWidth2(description, descriptionWidth))}`));
|
|
2764
2947
|
} else {
|
|
2765
2948
|
const labelWidth = Math.max(...specs.map(({ key }) => visibleWidth2(settingLabel(key))));
|
|
2766
2949
|
for (const [index, entry] of specs.entries()) {
|
|
@@ -2768,11 +2951,16 @@ async function runSettingsEditor(ctx) {
|
|
|
2768
2951
|
const inherited = projectSettings[entry.key] === undefined;
|
|
2769
2952
|
const value = projectSettings[entry.key] ?? globalSettings[entry.key];
|
|
2770
2953
|
const valueText = `[ ${formatSettingDisplayValue(entry.key, value)} ]`;
|
|
2771
|
-
const renderedValue = inherited ? dim(valueText) : selected ? accent(valueText) : text(valueText);
|
|
2772
|
-
const cursor = selected ? accent("›") : " ";
|
|
2773
|
-
|
|
2954
|
+
const renderedValue = inherited ? dim(valueText) : selected ? accent(bold(valueText)) : text(valueText);
|
|
2955
|
+
const cursor = selected ? accent(bold("›")) : " ";
|
|
2956
|
+
const label = pad(settingLabel(entry.key), labelWidth);
|
|
2957
|
+
const renderedLabel = selected ? text(bold(label)) : text(label);
|
|
2958
|
+
content.push(`${cursor} ${renderedLabel} ${renderedValue}`);
|
|
2774
2959
|
}
|
|
2775
2960
|
}
|
|
2961
|
+
if (!editor) {
|
|
2962
|
+
content.push("", dim(" tab switch tab · ↑↓ navigate · enter edit · esc close"));
|
|
2963
|
+
}
|
|
2776
2964
|
return [
|
|
2777
2965
|
overlayHeader(colors, width, "Goosedump Settings"),
|
|
2778
2966
|
...content.map((line) => makeRow(line, innerW, colors.border)),
|
|
@@ -2849,6 +3037,7 @@ async function runSearchPanel(ctx, query, executablePath) {
|
|
|
2849
3037
|
let scroll = 0;
|
|
2850
3038
|
let detailLines = [];
|
|
2851
3039
|
let detailScroll = 0;
|
|
3040
|
+
let detailEntry = null;
|
|
2852
3041
|
async function runSearch() {
|
|
2853
3042
|
try {
|
|
2854
3043
|
const first = await goosedumpSearch(target, query, { scope: "lineage", page: 1 }, undefined, executablePath);
|
|
@@ -2887,8 +3076,12 @@ async function runSearchPanel(ctx, query, executablePath) {
|
|
|
2887
3076
|
async function loadDetail(id) {
|
|
2888
3077
|
try {
|
|
2889
3078
|
const messages = await goosedumpShow(target, { ids: [id] }, undefined, executablePath);
|
|
2890
|
-
const
|
|
2891
|
-
|
|
3079
|
+
const msg = messages.length > 0 ? messages[0] : null;
|
|
3080
|
+
detailEntry = msg;
|
|
3081
|
+
const entryHeader = msg ? `${colors.accent(colors.bold(`[${msg.id}]`))} ${colors.muted(`${msg.role}:`)}` : "";
|
|
3082
|
+
const content = msg ? msg.content : "No content for this entry.";
|
|
3083
|
+
const wrapped = wrapTextWithAnsi(content, wrapWidth);
|
|
3084
|
+
detailLines = entryHeader ? [entryHeader, "", ...wrapped] : wrapped;
|
|
2892
3085
|
detailScroll = 0;
|
|
2893
3086
|
mode = "detail";
|
|
2894
3087
|
} catch (err) {
|
|
@@ -2900,7 +3093,7 @@ async function runSearchPanel(ctx, query, executablePath) {
|
|
|
2900
3093
|
}
|
|
2901
3094
|
return {
|
|
2902
3095
|
render(width) {
|
|
2903
|
-
const header = overlayHeader(colors, width, `Goosedump search: ${truncateToWidth2(query, 44)}`);
|
|
3096
|
+
const header = mode === "detail" && detailEntry ? overlayHeader(colors, width, `Goosedump Entry: [${detailEntry.id}] (${detailEntry.role})`) : overlayHeader(colors, width, `Goosedump search: ${truncateToWidth2(query, 44)}`);
|
|
2904
3097
|
if (error) {
|
|
2905
3098
|
return [header, ...overlayError(colors, width, error), overlayFooter(colors, width)];
|
|
2906
3099
|
}
|
|
@@ -2915,8 +3108,8 @@ async function runSearchPanel(ctx, query, executablePath) {
|
|
|
2915
3108
|
header,
|
|
2916
3109
|
...overlayViewport(colors, width, entries, scroll, VIEWPORT, "↑↓ navigate enter expand esc close", (count) => `entr${count === 1 ? "y" : "ies"}`, (entry, absolute) => {
|
|
2917
3110
|
const isSelected = absolute === selected;
|
|
2918
|
-
const cursor = isSelected ? colors.accent("▶") : " ";
|
|
2919
|
-
const idText = isSelected ? colors.accent(entry.id) : colors.text(entry.id);
|
|
3111
|
+
const cursor = isSelected ? colors.accent(colors.bold("▶")) : " ";
|
|
3112
|
+
const idText = isSelected ? colors.accent(colors.bold(entry.id)) : colors.text(entry.id);
|
|
2920
3113
|
const snippet = compactLine(entry.content);
|
|
2921
3114
|
return ` ${cursor} ${idText} ${colors.muted(entry.role)} ${colors.dim(snippet)}`;
|
|
2922
3115
|
}),
|
|
@@ -3164,11 +3357,11 @@ async function runSessionsPanel(ctx, executablePath) {
|
|
|
3164
3357
|
const isSelected = absolute === selected;
|
|
3165
3358
|
const isActive = currentTarget === formatTarget(s.provider, s.id);
|
|
3166
3359
|
const key = `${s.provider}:${s.id}`;
|
|
3167
|
-
const cursor = isSelected ? colors.accent("▶") : " ";
|
|
3360
|
+
const cursor = isSelected ? colors.accent(colors.bold("▶")) : " ";
|
|
3168
3361
|
const indent = " ".repeat(row.depth * 2);
|
|
3169
3362
|
const toggle = row.hasChildren ? expandedNodes.has(key) ? colors.muted("−") : colors.muted("+") : " ";
|
|
3170
|
-
const activeMark = isActive ? colors.accent("
|
|
3171
|
-
const idText = isSelected ? colors.accent(s.id) : colors.text(s.id);
|
|
3363
|
+
const activeMark = isActive ? colors.accent(colors.bold("● active")) : "";
|
|
3364
|
+
const idText = isSelected ? colors.accent(colors.bold(s.id)) : colors.text(s.id);
|
|
3172
3365
|
const providerTag = colors.muted(`[${s.provider}]`);
|
|
3173
3366
|
const countTag = colors.dim(`${s.count} entries`);
|
|
3174
3367
|
const dateTag = s.from ? colors.dim(new Date(s.from).toLocaleDateString()) : "";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-goosedump",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.3",
|
|
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.3"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@earendil-works/pi-coding-agent": "^0.84.2",
|