pi-posthorse 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -47
- package/index.ts +726 -317
- package/package.json +12 -9
- package/ui.ts +17 -7
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-posthorse",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "Posthorse: fresh context, same journey.
|
|
5
|
+
"description": "Posthorse: fresh context, same journey. No-summary context rollover for Pi, with sparse budget reminders, handoffs, notes, and history.",
|
|
6
6
|
"keywords": ["pi-package", "pi-extension", "context", "posthorse", "rollover"],
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
@@ -11,16 +11,17 @@
|
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"files": ["index.ts", "ui.ts"],
|
|
13
13
|
"engines": {
|
|
14
|
-
"node": ">=
|
|
14
|
+
"node": ">=24.12.0"
|
|
15
15
|
},
|
|
16
|
+
"packageManager": "npm@12.1.0",
|
|
16
17
|
"pi": {
|
|
17
18
|
"extensions": ["./index.ts"],
|
|
18
19
|
"image": "https://raw.githubusercontent.com/fitchmultz/pi-posthorse/main/diagram.png"
|
|
19
20
|
},
|
|
20
21
|
"scripts": {
|
|
21
|
-
"check": "tsc
|
|
22
|
+
"check": "tsc",
|
|
22
23
|
"check:compat": "npm run check && npm test && npm run test:native",
|
|
23
|
-
"test:native": "node --import ./test/pi-loader.ts --test test/
|
|
24
|
+
"test:native": "node --import ./test/pi-loader.ts --test test/host.test.mjs",
|
|
24
25
|
"test": "node --import ./test/pi-loader.ts --test test/*.test.ts",
|
|
25
26
|
"prepublishOnly": "npm test && npm run check"
|
|
26
27
|
},
|
|
@@ -41,9 +42,11 @@
|
|
|
41
42
|
}
|
|
42
43
|
},
|
|
43
44
|
"devDependencies": {
|
|
44
|
-
"@earendil-works/pi-
|
|
45
|
-
"@earendil-works/pi-
|
|
46
|
-
"
|
|
47
|
-
"
|
|
45
|
+
"@earendil-works/pi-ai": "0.87.1",
|
|
46
|
+
"@earendil-works/pi-coding-agent": "0.87.1",
|
|
47
|
+
"@earendil-works/pi-tui": "0.87.1",
|
|
48
|
+
"@types/node": "24.19.0",
|
|
49
|
+
"typebox": "1.3.34",
|
|
50
|
+
"typescript": "7.0.2"
|
|
48
51
|
}
|
|
49
52
|
}
|
package/ui.ts
CHANGED
|
@@ -7,8 +7,8 @@ export type PosthorseDisplay =
|
|
|
7
7
|
| { kind: "notes-list" | "notes-search"; count: number; page?: { offset: number; end: number; total: number } }
|
|
8
8
|
| { kind: "note-read"; offset: number; end: number; total: number }
|
|
9
9
|
| { kind: "note-write" | "note-append" | "new-context" }
|
|
10
|
-
| { kind: "history-search"; entries: Array<{ headerLength: number; length: number }>; footerLength?: number }
|
|
11
|
-
| { kind: "history-read"; headerLength: number; offset: number; end: number; total: number };
|
|
10
|
+
| { kind: "history-search"; entries: Array<{ headerLength: number; length: number }>; footerLength?: number; more?: boolean; skipped?: number }
|
|
11
|
+
| { kind: "history-read"; headerLength: number; offset: number; end: number; total: number; imageOffset?: number; imageEnd?: number; imageTotal?: number };
|
|
12
12
|
|
|
13
13
|
type ToolName = "notes" | "history" | "get_context_remaining" | "new_context";
|
|
14
14
|
const titles: Record<ToolName, string> = { notes: "Notes", history: "History", get_context_remaining: "Context budget", new_context: "New context" };
|
|
@@ -62,7 +62,7 @@ export function toolCards(name: ToolName): Pick<ToolDefinition, "renderCall" | "
|
|
|
62
62
|
const args = argsOf(rawArgs);
|
|
63
63
|
const action = name === "notes" || name === "history" ? ` · ${argument(args.op, "op")}` : name === "new_context" ? " · request" : "";
|
|
64
64
|
const status = context.isError ? " · error" : context.isPartial ? context.executionStarted ? " · running" : " · preparing" : "";
|
|
65
|
-
const target = args.op === "search" ? ` · “${argument(args.query, "query")}”` : name === "notes" && args.op !== "list" ? ` · ${argument(args.path, "path")}` : name === "history" && args.op === "read" ? ` · ${argument(args.id, "id")}` : "";
|
|
65
|
+
const target = args.op === "search" ? ` · “${argument(args.query, "query")}”` : name === "notes" && (args.op !== "list" || args.path !== undefined) ? ` · ${argument(args.path, "path")}` : name === "history" && args.op === "read" ? ` · ${argument(args.id, "id")}` : "";
|
|
66
66
|
const label = `${context.isPartial ? "…" : context.expanded ? "▾" : "▸"} ${titles[name]}${action}${status}${target}`;
|
|
67
67
|
return {
|
|
68
68
|
invalidate() {},
|
|
@@ -72,6 +72,7 @@ export function toolCards(name: ToolName): Pick<ToolDefinition, "renderCall" | "
|
|
|
72
72
|
const details = [
|
|
73
73
|
name === "history" && args.op === "search" ? `Scope: ${args.all === true ? "all project sessions" : "current branch"}` : "",
|
|
74
74
|
args.offset !== undefined ? `Offset: ${typeof args.offset === "number" ? n(args.offset) : "[invalid offset]"}` : "",
|
|
75
|
+
args.imageOffset !== undefined ? `Image offset: ${typeof args.imageOffset === "number" ? n(args.imageOffset) : "[invalid image offset]"}` : "",
|
|
75
76
|
args.limit !== undefined ? `Limit: ${typeof args.limit === "number" ? n(args.limit) : "[invalid limit]"}` : "",
|
|
76
77
|
].filter(Boolean).join(" · ");
|
|
77
78
|
return [...new Text(heading, 0, 0).render(width), ...textBlock(details, theme, "muted").render(width)];
|
|
@@ -102,9 +103,18 @@ export function toolCards(name: ToolName): Pick<ToolDefinition, "renderCall" | "
|
|
|
102
103
|
case "note-read": summary = pageSummary(display); break;
|
|
103
104
|
case "note-write": summary = args.content === "" ? "Cleared note" : "Saved note"; break;
|
|
104
105
|
case "note-append": summary = "Appended to note"; break;
|
|
105
|
-
case "history-search": if (Array.isArray(display.entries) && (!display.entries.length || sections)) summary = `${display.entries.length ? `${n(display.entries.length)} matches` : "No matches"} · ${args.all === true ? "all sessions" : "current branch"}${display.footerLength ? "\nMore results; continue with cursor" : ""}`; break;
|
|
106
|
-
case "history-read":
|
|
107
|
-
|
|
106
|
+
case "history-search": if (Array.isArray(display.entries) && (!display.entries.length || sections)) summary = `${display.entries.length ? `${n(display.entries.length)} matches` : "No matches"} · ${args.all === true ? "all sessions" : "current branch"}${display.skipped ? ` · ${n(display.skipped)} in context skipped` : ""}${(display.more ?? display.footerLength) ? "\nMore results; continue with cursor" : ""}`; break;
|
|
107
|
+
case "history-read":
|
|
108
|
+
summary = pageSummary(display);
|
|
109
|
+
if (display.imageTotal && display.imageEnd !== undefined) {
|
|
110
|
+
summary = summary.split("\n")[0];
|
|
111
|
+
summary += `\nImages ${n(display.imageOffset ?? 0)}–${n(display.imageEnd)} of ${n(display.imageTotal)}`;
|
|
112
|
+
if (display.end < display.total || display.imageEnd < display.imageTotal) {
|
|
113
|
+
summary = `Next offset ${n(display.end)}\nimageOffset ${n(display.imageEnd)}\n${summary}`;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
break;
|
|
117
|
+
case "new-context": summary = "Requested after foreground tools succeed.\nBackground work continues."; break;
|
|
108
118
|
}
|
|
109
119
|
}
|
|
110
120
|
if (!context.isError && !isPartial && (display?.kind === "notes-list" || display?.kind === "notes-search") && display.page && (display.page.offset || display.page.end < display.page.total)) summary += `\n${pageSummary(display.page)}`;
|
|
@@ -180,5 +190,5 @@ export function registerPosthorseMessages(pi: ExtensionAPI): void {
|
|
|
180
190
|
return { handled: true };
|
|
181
191
|
});
|
|
182
192
|
};
|
|
183
|
-
for (const type of ["context-window", "posthorse-reminder"
|
|
193
|
+
for (const type of ["context-window", "posthorse-reminder"]) pi.registerMessageRenderer(type, renderer);
|
|
184
194
|
}
|