pi-weave 0.1.3 → 0.1.5
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/package.json +1 -1
- package/skills/weave-notepad/SKILL.md +1 -1
- package/src/pi/index.ts +57 -10
- package/src/pi/viewer/tui/run.ts +8 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-weave",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "An agent-native knowledge workspace for your life and your code. Smart notepad + repository exploration, readable by humans and agents alike.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: weave-notepad
|
|
3
|
-
description: Take and retrieve durable notes in the pi-weave vault. Use when the user asks to remember something or to start/add to a note (aliases: notes, ai note, note-taking, note-taker), or when answering questions about past decisions, people, or projects. Also handles interview note-taking where raw dictations are appended AND expanded.
|
|
3
|
+
description: "Take and retrieve durable notes in the pi-weave vault. Use when the user asks to remember something or to start/add to a note (aliases: notes, ai note, note-taking, note-taker), or when answering questions about past decisions, people, or projects. Also handles interview note-taking where raw dictations are appended AND expanded."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Weave Notepad
|
package/src/pi/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
1
|
+
import type { ExtensionAPI, ExtensionCommandContext, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import {
|
|
3
3
|
buildRepoIndex,
|
|
4
4
|
findGitRoot,
|
|
@@ -32,6 +32,32 @@ export default function piWeave(pi: ExtensionAPI): void {
|
|
|
32
32
|
// Session-scoped viewer: lazy start on first /weave-view, never from the
|
|
33
33
|
// factory (extension rules); idempotent stop on session_shutdown.
|
|
34
34
|
let viewer: ViewerServer | null = null;
|
|
35
|
+
let lastCtx: ExtensionContext | ExtensionCommandContext | null = null;
|
|
36
|
+
let lastStatusText: string | undefined = undefined;
|
|
37
|
+
let isActive = false;
|
|
38
|
+
|
|
39
|
+
function updateStatus(ctx?: ExtensionContext | ExtensionCommandContext, text?: string): void {
|
|
40
|
+
if (ctx) lastCtx = ctx;
|
|
41
|
+
const c = ctx || lastCtx;
|
|
42
|
+
if (!c?.ui?.setStatus) return;
|
|
43
|
+
if (text !== undefined) {
|
|
44
|
+
lastStatusText = text;
|
|
45
|
+
}
|
|
46
|
+
if (!lastStatusText) {
|
|
47
|
+
c.ui.setStatus("weave", undefined);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
let theme: { fg?: (slot: string, text: string) => string } | undefined;
|
|
51
|
+
try {
|
|
52
|
+
theme = (c.ui as unknown as { theme?: { fg?: (slot: string, text: string) => string } })?.theme;
|
|
53
|
+
} catch {
|
|
54
|
+
// ignore
|
|
55
|
+
}
|
|
56
|
+
const indicator = (isActive || inFlightDeepScans.size > 0)
|
|
57
|
+
? (theme?.fg ? theme.fg("accent", "●") : "●")
|
|
58
|
+
: (theme?.fg ? theme.fg("dim", "○") : "○");
|
|
59
|
+
c.ui.setStatus("weave", `${indicator} ${lastStatusText}`);
|
|
60
|
+
}
|
|
35
61
|
|
|
36
62
|
pi.on("session_shutdown", async () => {
|
|
37
63
|
const server = viewer;
|
|
@@ -39,9 +65,19 @@ export default function piWeave(pi: ExtensionAPI): void {
|
|
|
39
65
|
await server?.stop();
|
|
40
66
|
});
|
|
41
67
|
|
|
68
|
+
pi.on("agent_start", async (_event, ctx) => {
|
|
69
|
+
isActive = true;
|
|
70
|
+
updateStatus(ctx);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
pi.on("agent_end", async (_event, ctx) => {
|
|
74
|
+
isActive = false;
|
|
75
|
+
updateStatus(ctx);
|
|
76
|
+
});
|
|
77
|
+
|
|
42
78
|
pi.on("session_start", async (_event, ctx) => {
|
|
43
79
|
const status = await getWorkspaceStatus(ctx.cwd);
|
|
44
|
-
ctx
|
|
80
|
+
updateStatus(ctx, formatStatusLine(status));
|
|
45
81
|
|
|
46
82
|
if (!ctx.hasUI) return;
|
|
47
83
|
const repo = status.repository;
|
|
@@ -105,13 +141,13 @@ export default function piWeave(pi: ExtensionAPI): void {
|
|
|
105
141
|
// Compute the settled status here (no git-lock contention) and let
|
|
106
142
|
// the background scan restore it when it finishes.
|
|
107
143
|
const status = await getWorkspaceStatus(ctx.cwd);
|
|
108
|
-
startDeepScan(root, ctx, status);
|
|
144
|
+
startDeepScan(root, ctx, status, updateStatus);
|
|
109
145
|
}
|
|
110
146
|
return; // the background scan owns the status line until it settles
|
|
111
147
|
}
|
|
112
148
|
|
|
113
149
|
const status = await getWorkspaceStatus(ctx.cwd);
|
|
114
|
-
ctx
|
|
150
|
+
updateStatus(ctx, formatStatusLine(status));
|
|
115
151
|
},
|
|
116
152
|
});
|
|
117
153
|
|
|
@@ -156,15 +192,26 @@ export async function deepScanDone(root: string): Promise<void | undefined> {
|
|
|
156
192
|
* cancellation is reported via a notification. `baseStatus` is the workspace
|
|
157
193
|
* status captured before the scan and restored when it settles.
|
|
158
194
|
*/
|
|
159
|
-
function startDeepScan(
|
|
195
|
+
function startDeepScan(
|
|
196
|
+
root: string,
|
|
197
|
+
ctx: ExtensionCommandContext,
|
|
198
|
+
baseStatus: WorkspaceStatus,
|
|
199
|
+
updateStatus: (ctx?: ExtensionContext | ExtensionCommandContext, text?: string) => void,
|
|
200
|
+
): void {
|
|
160
201
|
const controller = new AbortController();
|
|
161
|
-
|
|
202
|
+
let doneResolve: () => void;
|
|
203
|
+
const done = new Promise<void>((resolve) => {
|
|
204
|
+
doneResolve = resolve;
|
|
205
|
+
});
|
|
206
|
+
inFlightDeepScans.set(root, { controller, done });
|
|
207
|
+
|
|
208
|
+
void (async () => {
|
|
162
209
|
try {
|
|
163
|
-
ctx
|
|
210
|
+
updateStatus(ctx, "🧵 deep scan: starting…");
|
|
164
211
|
const outcome = await deepScanRepository(root, ctx, {
|
|
165
212
|
onProgress: ({ current, total, path }) => {
|
|
166
213
|
const pct = total > 0 ? Math.round((current / total) * 100) : 100;
|
|
167
|
-
ctx
|
|
214
|
+
updateStatus(ctx, `🧵 deep scan: ${current}/${total} (${pct}%) — ${path}`);
|
|
168
215
|
},
|
|
169
216
|
signal: controller.signal,
|
|
170
217
|
});
|
|
@@ -183,9 +230,9 @@ function startDeepScan(root: string, ctx: ExtensionCommandContext, baseStatus: W
|
|
|
183
230
|
} finally {
|
|
184
231
|
// Restore the settled status before removing the map entry, so a caller
|
|
185
232
|
// awaiting deepScanDone() observes the settled status line.
|
|
186
|
-
ctx.ui.setStatus("weave", formatStatusLine(baseStatus));
|
|
187
233
|
inFlightDeepScans.delete(root);
|
|
234
|
+
updateStatus(ctx, formatStatusLine(baseStatus));
|
|
235
|
+
doneResolve!();
|
|
188
236
|
}
|
|
189
237
|
})();
|
|
190
|
-
inFlightDeepScans.set(root, { controller, done });
|
|
191
238
|
}
|
package/src/pi/viewer/tui/run.ts
CHANGED
|
@@ -60,7 +60,14 @@ export async function runWeaveViewTui(ctx: ExtensionCommandContext): Promise<voi
|
|
|
60
60
|
|
|
61
61
|
// Refresh the status line after close (a /weave-scan may have landed meanwhile).
|
|
62
62
|
const status = await getWorkspaceStatus(ctx.cwd);
|
|
63
|
-
|
|
63
|
+
let theme: { fg?: (slot: string, text: string) => string } | undefined;
|
|
64
|
+
try {
|
|
65
|
+
theme = (ctx.ui as unknown as { theme?: { fg?: (slot: string, text: string) => string } })?.theme;
|
|
66
|
+
} catch {
|
|
67
|
+
// ignore
|
|
68
|
+
}
|
|
69
|
+
const indicator = theme?.fg ? theme.fg("dim", "○") : "○";
|
|
70
|
+
ctx.ui.setStatus("weave", `${indicator} ${formatStatusLine(status)}`);
|
|
64
71
|
}
|
|
65
72
|
|
|
66
73
|
/** Test seam: build the model the explorer opens with, without a terminal. */
|