paseo-follow-up 1.2.0-beta.2 → 1.2.0-beta.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 +2 -2
- package/package.json +1 -1
- package/server/inbox.ts +18 -1
package/README.md
CHANGED
|
@@ -101,7 +101,7 @@ The content comes from a new `needs_you` tool that every root agent gets while t
|
|
|
101
101
|
Install the beta:
|
|
102
102
|
|
|
103
103
|
```sh
|
|
104
|
-
paseo plugin update follow-through --version 1.2.0-beta.
|
|
104
|
+
paseo plugin update follow-through --version 1.2.0-beta.3
|
|
105
105
|
# or, for a fresh install:
|
|
106
106
|
paseo plugin install npm:paseo-follow-up@beta
|
|
107
107
|
```
|
|
@@ -117,7 +117,7 @@ Betas publish to npm's `beta` dist-tag, so `paseo plugin update` without `--vers
|
|
|
117
117
|
## How it works
|
|
118
118
|
|
|
119
119
|
- The workspace's main agent owns its PRs, tasks, questions, the spec link and the Done call. Other agents in the workspace can register PRs and check status.
|
|
120
|
-
- **Auto-send** is on for every workspace tracked for the first time (1.2.0-beta.
|
|
120
|
+
- **Auto-send** is on for every workspace tracked for the first time (1.2.0-beta.3), so review threads and red CI go to the agent without you. Workspaces tracked before keep their setting. Turn it off per workspace and each repair batch waits for your click; with it on, Follow-up sends batches itself once the agent is idle, after fresh permission and Session Guard checks.
|
|
121
121
|
- Follow-up never merges, turns on merge when ready, requests reviewers or archives on its own. **Merge** re-checks the stack, lists any PRs underneath that would merge first, and asks again.
|
|
122
122
|
- A merged PR is not the end: tasks such as production checks and open questions keep the workspace open until the main agent declares Done and everything has settled.
|
|
123
123
|
- Answers go out only when you click Send. Follow-up never answers for you.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "paseo-follow-up",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.2.0-beta.
|
|
4
|
+
"version": "1.2.0-beta.3",
|
|
5
5
|
"description": "Follow every workspace PR stack in Paseo, answer agent questions, batch repairs for the main agent, and see what needs you.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"files": [
|
package/server/inbox.ts
CHANGED
|
@@ -90,6 +90,8 @@ export type InboxOptions = {
|
|
|
90
90
|
guard: () => Promise<GuardPause[] | null>;
|
|
91
91
|
now?: () => number;
|
|
92
92
|
graceMs?: number;
|
|
93
|
+
/** How long a turn end waits for Paseo to stop reporting "running" (F7). Tests shorten it. */
|
|
94
|
+
settleMs?: number; settleStepMs?: number;
|
|
93
95
|
};
|
|
94
96
|
/** Decides the brief step for one event from the entry before and after it. */
|
|
95
97
|
export type BriefDecider = (prev: Entry, next: Entry, at: string) => BriefEvent | null;
|
|
@@ -128,6 +130,21 @@ export class Inbox {
|
|
|
128
130
|
private cache: { at: number; agents: AgentInfo[]; workspaces: { id: string; name: string }[] } | null = null;
|
|
129
131
|
constructor(directory: string, private o: InboxOptions) { this.store = new InboxStore(directory); }
|
|
130
132
|
private now() { return this.o.now?.() ?? Date.now(); }
|
|
133
|
+
/**
|
|
134
|
+
* Paseo still reports "running" for a moment after a turn completes, so a status read at turn end would make
|
|
135
|
+
* every plain finish look like background work (F7) and flag nothing. Re-read until the agent leaves "running"
|
|
136
|
+
* or the window ends; only an agent still running after it counts as running.
|
|
137
|
+
*/
|
|
138
|
+
private async settledStatus(agentId: string): Promise<string | null> {
|
|
139
|
+
const read = () => this.o.directory.agent(agentId).then(a => a?.status ?? null, () => null);
|
|
140
|
+
const step = this.o.settleStepMs ?? 500, steps = Math.max(1, Math.ceil((this.o.settleMs ?? 6_000) / step));
|
|
141
|
+
let status = await read();
|
|
142
|
+
for (let i = 0; i < steps && (status === "running" || status === "initializing"); i++) {
|
|
143
|
+
await new Promise(r => setTimeout(r, step));
|
|
144
|
+
status = await read();
|
|
145
|
+
}
|
|
146
|
+
return status;
|
|
147
|
+
}
|
|
131
148
|
private iso() { return new Date(this.now()).toISOString(); }
|
|
132
149
|
private async on() { try { return (await this.o.enabled()).enable_inbox; } catch { return true; } }
|
|
133
150
|
|
|
@@ -247,7 +264,7 @@ export class Inbox {
|
|
|
247
264
|
const reply = [...items].reverse().find(i => (i as { type?: string })?.type === "assistant_message") as { text?: string } | undefined;
|
|
248
265
|
// F7: needs_you kind=done means nothing for the developer, and while Paseo still shows the agent running
|
|
249
266
|
// (background work) its own running state is enough. Neither flags; a decision, action or review still does.
|
|
250
|
-
const status = await this.
|
|
267
|
+
const status = await this.settledStatus(agent.id);
|
|
251
268
|
const quiet = finishIsQuiet(stated.agent?.kind ?? null, status);
|
|
252
269
|
// The ask replaces the reply's last line as the reason's detail (§4); the fallback keeps the old detail.
|
|
253
270
|
const brief = await this.creator(root.rootId, turnId, "", "finished", stated, !quiet || stated.agent?.kind === "done", quiet);
|