@normful/picadillo 3.0.0 → 4.0.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/CHANGELOG.md +17 -0
- package/README.md +6 -0
- package/extensions/overstory.ts +207 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
## [4.0.0] - 2026-02-17
|
|
2
|
+
|
|
3
|
+
### 🚀 Features
|
|
4
|
+
|
|
5
|
+
- *(extension)* Add overstory extension boilerplate and logic
|
|
6
|
+
|
|
7
|
+
### 📚 Documentation
|
|
8
|
+
|
|
9
|
+
- Add overstory extension to README
|
|
10
|
+
|
|
11
|
+
### ⚙️ Miscellaneous Tasks
|
|
12
|
+
|
|
13
|
+
- Shorten package.json description, fix overstory repo URL
|
|
1
14
|
## [3.0.0] - 2026-02-17
|
|
2
15
|
|
|
3
16
|
### 🚀 Features
|
|
@@ -12,6 +25,10 @@
|
|
|
12
25
|
### 📚 Documentation
|
|
13
26
|
|
|
14
27
|
- Update README with reorganized skills and extensions sections
|
|
28
|
+
|
|
29
|
+
### ⚙️ Miscellaneous Tasks
|
|
30
|
+
|
|
31
|
+
- Release 3.0.0
|
|
15
32
|
## [2.0.3] - 2026-02-16
|
|
16
33
|
|
|
17
34
|
### 📚 Documentation
|
package/README.md
CHANGED
|
@@ -67,6 +67,12 @@ Hooks to automatically run `gt prime` and `gt mail` from [gastown](https://githu
|
|
|
67
67
|
Hooks to automatically run [mulch](https://github.com/jayminwest/mulch) for
|
|
68
68
|
recording and retrieving structured project learnings.
|
|
69
69
|
|
|
70
|
+
### overstory
|
|
71
|
+
|
|
72
|
+
Hooks to automatically run `overstory prime` and `overstory mail check` from
|
|
73
|
+
[overstory](https://github.com/jayminwest/overstory/), along with logging tool
|
|
74
|
+
start/end, session end events, and integration with mulch for learning.
|
|
75
|
+
|
|
70
76
|
## Parrot Extension Demo
|
|
71
77
|
|
|
72
78
|
[](https://asciinema.org/a/788693)
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
2
|
+
import type { ExecResult } from "@mariozechner/pi-coding-agent";
|
|
3
|
+
|
|
4
|
+
export type { ExecResult };
|
|
5
|
+
export const OVERSTORY_MESSAGE_TYPE = "overstory";
|
|
6
|
+
|
|
7
|
+
export async function overstoryPrime(
|
|
8
|
+
execFn: ExtensionAPI["exec"],
|
|
9
|
+
forCompact = false,
|
|
10
|
+
): Promise<string> {
|
|
11
|
+
let primeText = "";
|
|
12
|
+
try {
|
|
13
|
+
const { stdout } = await execFn("overstory", [
|
|
14
|
+
"prime",
|
|
15
|
+
"--agent",
|
|
16
|
+
"orchestrator",
|
|
17
|
+
...(forCompact ? ["--compact"] : []),
|
|
18
|
+
]);
|
|
19
|
+
primeText = stdout;
|
|
20
|
+
} catch (e) {
|
|
21
|
+
console.error("overstory prime failed:", e);
|
|
22
|
+
}
|
|
23
|
+
return primeText;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export async function overstoryMailCheck(
|
|
27
|
+
execFn: ExtensionAPI["exec"],
|
|
28
|
+
): Promise<string> {
|
|
29
|
+
let mailText = "";
|
|
30
|
+
try {
|
|
31
|
+
const { stdout } = await execFn("overstory", [
|
|
32
|
+
"mail",
|
|
33
|
+
"check",
|
|
34
|
+
"--inject",
|
|
35
|
+
"--agent",
|
|
36
|
+
"orchestrator",
|
|
37
|
+
]);
|
|
38
|
+
mailText = stdout;
|
|
39
|
+
} catch (e) {
|
|
40
|
+
console.error("overstory mail check failed:", e);
|
|
41
|
+
}
|
|
42
|
+
return mailText;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export async function logToolStart(
|
|
46
|
+
execFn: ExtensionAPI["exec"],
|
|
47
|
+
toolName: string,
|
|
48
|
+
): Promise<void> {
|
|
49
|
+
try {
|
|
50
|
+
await execFn("overstory", [
|
|
51
|
+
"log",
|
|
52
|
+
"tool-start",
|
|
53
|
+
"--agent",
|
|
54
|
+
"orchestrator",
|
|
55
|
+
"--tool-name",
|
|
56
|
+
toolName,
|
|
57
|
+
]);
|
|
58
|
+
} catch (e) {
|
|
59
|
+
console.error("overstory log tool-start failed:", e);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export async function logToolEnd(
|
|
64
|
+
execFn: ExtensionAPI["exec"],
|
|
65
|
+
toolName: string,
|
|
66
|
+
): Promise<void> {
|
|
67
|
+
try {
|
|
68
|
+
await execFn("overstory", [
|
|
69
|
+
"log",
|
|
70
|
+
"tool-end",
|
|
71
|
+
"--agent",
|
|
72
|
+
"orchestrator",
|
|
73
|
+
"--tool-name",
|
|
74
|
+
toolName,
|
|
75
|
+
]);
|
|
76
|
+
} catch (e) {
|
|
77
|
+
console.error("overstory log tool-end failed:", e);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export async function logSessionEnd(
|
|
82
|
+
execFn: ExtensionAPI["exec"],
|
|
83
|
+
): Promise<void> {
|
|
84
|
+
try {
|
|
85
|
+
await execFn("overstory", [
|
|
86
|
+
"log",
|
|
87
|
+
"session-end",
|
|
88
|
+
"--agent",
|
|
89
|
+
"orchestrator",
|
|
90
|
+
]);
|
|
91
|
+
} catch (e) {
|
|
92
|
+
console.error("overstory log session-end failed:", e);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export async function mulchLearn(
|
|
97
|
+
execFn: ExtensionAPI["exec"],
|
|
98
|
+
): Promise<string> {
|
|
99
|
+
let primeText = "";
|
|
100
|
+
try {
|
|
101
|
+
const { stdout } = await execFn("mulch", ["learn"]);
|
|
102
|
+
primeText = stdout;
|
|
103
|
+
} catch (e) {
|
|
104
|
+
console.error("mulch learn failed:", e);
|
|
105
|
+
}
|
|
106
|
+
return primeText;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export async function handleSessionStart(
|
|
110
|
+
execFn: ExtensionAPI["exec"],
|
|
111
|
+
sendMessage: ExtensionAPI["sendMessage"],
|
|
112
|
+
): Promise<void> {
|
|
113
|
+
const primeText = await overstoryPrime(execFn);
|
|
114
|
+
if (!primeText) return;
|
|
115
|
+
|
|
116
|
+
const mailText = await overstoryMailCheck(execFn);
|
|
117
|
+
sendMessage(
|
|
118
|
+
{
|
|
119
|
+
customType: OVERSTORY_MESSAGE_TYPE,
|
|
120
|
+
content: primeText + "\n\n" + mailText,
|
|
121
|
+
display: true,
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
deliverAs: "followUp",
|
|
125
|
+
triggerTurn: true,
|
|
126
|
+
},
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export function handleBeforeAgentStart(mailText: string) {
|
|
131
|
+
return {
|
|
132
|
+
message: {
|
|
133
|
+
customType: OVERSTORY_MESSAGE_TYPE,
|
|
134
|
+
content: mailText,
|
|
135
|
+
display: true,
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export async function handleToolExecutionEnd(
|
|
141
|
+
execFn: ExtensionAPI["exec"],
|
|
142
|
+
event: { toolName: string },
|
|
143
|
+
): Promise<void> {
|
|
144
|
+
logToolEnd(execFn, event.toolName);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export async function handleToolExecutionStart(
|
|
148
|
+
execFn: ExtensionAPI["exec"],
|
|
149
|
+
event: { toolName: string },
|
|
150
|
+
): Promise<void> {
|
|
151
|
+
logToolStart(execFn, event.toolName);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export async function handleSessionCompact(
|
|
155
|
+
execFn: ExtensionAPI["exec"],
|
|
156
|
+
sendMessage: ExtensionAPI["sendMessage"],
|
|
157
|
+
): Promise<void> {
|
|
158
|
+
const primeText = await overstoryPrime(execFn, true);
|
|
159
|
+
if (!primeText) return;
|
|
160
|
+
|
|
161
|
+
sendMessage(
|
|
162
|
+
{
|
|
163
|
+
customType: OVERSTORY_MESSAGE_TYPE,
|
|
164
|
+
content: primeText,
|
|
165
|
+
display: true,
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
deliverAs: "followUp",
|
|
169
|
+
triggerTurn: true,
|
|
170
|
+
},
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export async function handleSessionShutdown(
|
|
175
|
+
execFn: ExtensionAPI["exec"],
|
|
176
|
+
): Promise<void> {
|
|
177
|
+
await Promise.all([logSessionEnd(execFn), mulchLearn(execFn)]);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export default function (pi: ExtensionAPI) {
|
|
181
|
+
pi.on("session_start", async (_event, _ctx) => {
|
|
182
|
+
await handleSessionStart(pi.exec, pi.sendMessage);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
pi.on("before_agent_start", async (_event, _ctx) => {
|
|
186
|
+
const mailText = await overstoryMailCheck(pi.exec);
|
|
187
|
+
return handleBeforeAgentStart(mailText);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
pi.on("tool_execution_end", async (event, _ctx) => {
|
|
191
|
+
// Fire-and-forget: don't await, let it run in background
|
|
192
|
+
void handleToolExecutionEnd(pi.exec, event);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
pi.on("tool_execution_start", async (event, _ctx) => {
|
|
196
|
+
// Fire-and-forget: don't await, let it run in background
|
|
197
|
+
void handleToolExecutionStart(pi.exec, event);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
pi.on("session_compact", async (_event, _ctx) => {
|
|
201
|
+
await handleSessionCompact(pi.exec, pi.sendMessage);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
pi.on("session_shutdown", async (_event, _ctx) => {
|
|
205
|
+
await handleSessionShutdown(pi.exec);
|
|
206
|
+
});
|
|
207
|
+
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@normful/picadillo",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"private": false,
|
|
5
|
-
"description": "pi agent skills
|
|
5
|
+
"description": "pi agent skills & extensions: run-in-tmux, parrot, mulch, overstory",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"pi",
|
|
8
8
|
"pi-coding-agent",
|