@@ -50,6 +50,82 @@ Add `ANTHROPIC_API_KEY` with your Anthropic API key.
5050
5151---
5252
53+ ## How checkpoint-filter.ts Works
54+
55+ ` checkpoint-filter.ts ` is a working example of processing Perstack's event stream.
56+
57+ ### Event Stream
58+
59+ When you run ` perstack run --stream-events ` , it outputs JSON events to stdout:
60+
61+ ``` json
62+ {"type" :" callTool" ,"toolCall" :{"toolName" :" think" ,"args" :{"thought" :" ..." }}}
63+ {"type" :" callTool" ,"toolCall" :{"toolName" :" readTextFile" ,"args" :{"path" :" ..." }}}
64+ {"type" :" completeRun" ,"text" :" Final answer here" }
65+ ```
66+
67+ ### Processing Events
68+
69+ The filter reads stdin line by line, parses JSON, and formats human-readable output:
70+
71+ ``` typescript
72+ function formatEvent(event : Record <string , unknown >): string | null {
73+ const type = event .type as string
74+ switch (type ) {
75+ case " callTool" : {
76+ const toolCall = event .toolCall as Record <string , unknown >
77+ const toolName = toolCall ?.toolName as string
78+ const args = toolCall ?.args as Record <string , unknown >
79+ if (toolName === " think" ) {
80+ return ` 💭 ${args ?.thought } `
81+ }
82+ if (toolName === " readTextFile" ) {
83+ return ` 📖 Reading: ${args ?.path } `
84+ }
85+ // ... more tool handlers
86+ }
87+ case " completeRun" : {
88+ finalAnswer = event .text as string
89+ return " ✅ Done"
90+ }
91+ }
92+ }
93+ ```
94+
95+ ### Real-time Updates
96+
97+ The filter updates a GitHub comment in real-time using the GitHub API:
98+
99+ ``` typescript
100+ const res = await fetch (
101+ ` https://api.github.com/repos/${GITHUB_REPO }/issues/comments/${COMMENT_ID } ` ,
102+ {
103+ method: " PATCH" ,
104+ headers: { Authorization: ` Bearer ${GH_TOKEN } ` },
105+ body: JSON .stringify ({ body: formattedLog }),
106+ }
107+ )
108+ ```
109+
110+ ### Event Types
111+
112+ | Event Type | Description | Example Output |
113+ | ------------- | ------------------------------ | ----------------------- |
114+ | ` callTool ` | Tool invocation | ` 📖 Reading: src/app.ts ` |
115+ | ` completeRun ` | Run completed with final text | ` ✅ Done ` |
116+
117+ ### Tool-specific Formatting
118+
119+ | Tool Name | Icon | Output |
120+ | ------------------- | ---- | ------------------------------- |
121+ | ` think ` | 💭 | Thought content (truncated) |
122+ | ` readTextFile ` | 📖 | File path |
123+ | ` listDirectory ` | 📁 | Directory path |
124+ | ` exec ` | ⚡ | Command + args |
125+ | ` attemptCompletion ` | ✨ | "Generating answer..." |
126+
127+ ---
128+
53129## Trigger Conditions
54130
55131| Event | Trigger |
@@ -73,8 +149,8 @@ For OpenAI, add `OPENAI_API_KEY` secret instead.
73149
74150## Files
75151
76- | File | Purpose |
77- | ---------------------- | ----------------------- |
78- | ` issue-bot.yml ` | GitHub Actions workflow |
79- | ` checkpoint-filter.ts ` | Real-time log formatter |
80- | ` perstack.toml ` | Expert definition |
152+ | File | Purpose |
153+ | ---------------------- | ---------------------------------------- |
154+ | ` issue-bot.yml ` | GitHub Actions workflow |
155+ | ` checkpoint-filter.ts ` | Event stream processor (working example) |
156+ | ` perstack.toml ` | Expert definition |
0 commit comments