@dalmasonto/taskflow-mcp 1.0.35 → 2.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/README.md +138 -193
- package/dist/attachment-download.d.ts +74 -0
- package/dist/attachment-download.js +193 -0
- package/dist/attachment-download.js.map +1 -0
- package/dist/attachments.d.ts +23 -0
- package/dist/attachments.js +66 -0
- package/dist/attachments.js.map +1 -0
- package/dist/client.d.ts +206 -0
- package/dist/client.js +279 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +137 -18
- package/dist/config.js +187 -106
- package/dist/config.js.map +1 -0
- package/dist/connect.d.ts +89 -0
- package/dist/connect.js +269 -0
- package/dist/connect.js.map +1 -0
- package/dist/doctor.d.ts +24 -0
- package/dist/doctor.js +120 -0
- package/dist/doctor.js.map +1 -0
- package/dist/events.d.ts +186 -0
- package/dist/events.js +407 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.js +121 -218
- package/dist/index.js.map +1 -0
- package/dist/instructions.d.ts +12 -0
- package/dist/instructions.js +114 -0
- package/dist/instructions.js.map +1 -0
- package/dist/mint.d.ts +62 -0
- package/dist/mint.js +135 -0
- package/dist/mint.js.map +1 -0
- package/dist/mirror.d.ts +68 -0
- package/dist/mirror.js +103 -0
- package/dist/mirror.js.map +1 -0
- package/dist/pane-queue.d.ts +29 -0
- package/dist/pane-queue.js +35 -0
- package/dist/pane-queue.js.map +1 -0
- package/dist/prompts.d.ts +79 -0
- package/dist/prompts.js +211 -0
- package/dist/prompts.js.map +1 -0
- package/dist/resolve.d.ts +72 -0
- package/dist/resolve.js +89 -0
- package/dist/resolve.js.map +1 -0
- package/dist/runtime.d.ts +54 -0
- package/dist/runtime.js +321 -0
- package/dist/runtime.js.map +1 -0
- package/dist/server.d.ts +56 -0
- package/dist/server.js +793 -0
- package/dist/server.js.map +1 -0
- package/dist/session-identifier.d.ts +48 -0
- package/dist/session-identifier.js +44 -0
- package/dist/session-identifier.js.map +1 -0
- package/dist/sessions-store.d.ts +38 -0
- package/dist/sessions-store.js +88 -0
- package/dist/sessions-store.js.map +1 -0
- package/dist/tmux.d.ts +200 -0
- package/dist/tmux.js +580 -0
- package/dist/tmux.js.map +1 -0
- package/hooks/metadata.mjs +99 -0
- package/hooks/permission-prompt.mjs +100 -0
- package/hooks/taskflow-hook.mjs +499 -0
- package/hooks/tool-logging.mjs +63 -0
- package/package.json +38 -29
- package/dist/agent-registry.d.ts +0 -28
- package/dist/agent-registry.js +0 -158
- package/dist/db.d.ts +0 -5
- package/dist/db.js +0 -220
- package/dist/helpers.d.ts +0 -21
- package/dist/helpers.js +0 -27
- package/dist/resources.d.ts +0 -2
- package/dist/resources.js +0 -89
- package/dist/retry.d.ts +0 -34
- package/dist/retry.js +0 -94
- package/dist/sse.d.ts +0 -10
- package/dist/sse.js +0 -824
- package/dist/tmux-bridge.d.ts +0 -13
- package/dist/tmux-bridge.js +0 -217
- package/dist/tools/activity.d.ts +0 -39
- package/dist/tools/activity.js +0 -152
- package/dist/tools/agent-inbox.d.ts +0 -12
- package/dist/tools/agent-inbox.js +0 -272
- package/dist/tools/agent.d.ts +0 -14
- package/dist/tools/agent.js +0 -168
- package/dist/tools/analytics.d.ts +0 -21
- package/dist/tools/analytics.js +0 -191
- package/dist/tools/checkpoint.d.ts +0 -27
- package/dist/tools/checkpoint.js +0 -105
- package/dist/tools/notifications.d.ts +0 -31
- package/dist/tools/notifications.js +0 -59
- package/dist/tools/projects.d.ts +0 -55
- package/dist/tools/projects.js +0 -112
- package/dist/tools/settings.d.ts +0 -19
- package/dist/tools/settings.js +0 -73
- package/dist/tools/tasks.d.ts +0 -105
- package/dist/tools/tasks.js +0 -403
- package/dist/tools/terminal.d.ts +0 -4
- package/dist/tools/terminal.js +0 -98
- package/dist/tools/timer.d.ts +0 -37
- package/dist/tools/timer.js +0 -154
- package/dist/types.d.ts +0 -83
- package/dist/types.js +0 -30
package/dist/events.js
ADDED
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Listen to the agent's server-sent event stream so messages reach the terminal
|
|
3
|
+
* the instant they are sent.
|
|
4
|
+
*
|
|
5
|
+
* This is v1's tmux-bridge idea (`task_flow/mcp-server/src/tmux-bridge.ts`):
|
|
6
|
+
* hold a stream open for the life of the session and inject on arrival, instead
|
|
7
|
+
* of polling. Polling made delivery as slow as the interval and cost a request
|
|
8
|
+
* per tick even in silence.
|
|
9
|
+
*
|
|
10
|
+
* It cannot use `EventSource`: agents authenticate with `Authorization: Agent
|
|
11
|
+
* <key>`, and EventSource cannot set headers. Node's fetch can, so the SSE frame
|
|
12
|
+
* parsing is done here — it is a small, well-specified format.
|
|
13
|
+
*/
|
|
14
|
+
/** Backoff between reconnects: fast first retry, then double, capped. */
|
|
15
|
+
const RECONNECT_BASE_MS = 1_000;
|
|
16
|
+
const RECONNECT_MAX_MS = 30_000;
|
|
17
|
+
/**
|
|
18
|
+
* Treat the stream as dead after this long with NOTHING on it — not even a
|
|
19
|
+
* keep-alive comment.
|
|
20
|
+
*
|
|
21
|
+
* A dropped connection does not reliably surface as an error: when the server
|
|
22
|
+
* goes away mid-stream, `reader.read()` can stay pending forever, so the
|
|
23
|
+
* listener sits there believing it is connected while nothing is delivered.
|
|
24
|
+
* Waiting for an error is waiting for an event that never comes; the only sound
|
|
25
|
+
* signal is the absence of expected traffic. The server sends SSE keep-alives
|
|
26
|
+
* every ~15s, so silence well past that means the stream is gone.
|
|
27
|
+
*/
|
|
28
|
+
const STREAM_IDLE_TIMEOUT_MS = 45_000;
|
|
29
|
+
/**
|
|
30
|
+
* Hard cap on the SSE read buffer (#44). Frames here are id-only and tiny; a
|
|
31
|
+
* buffer this large means the server is streaming a frame that never terminates
|
|
32
|
+
* with `\n\n`. Because bytes keep arriving, the idle watchdog never trips — so
|
|
33
|
+
* without this cap the buffer would grow to OOM. Past it we abort and reconnect.
|
|
34
|
+
*/
|
|
35
|
+
const MAX_STREAM_BUFFER_BYTES = 1_048_576; // 1 MiB
|
|
36
|
+
/**
|
|
37
|
+
* Hold the stream open, reconnecting with backoff.
|
|
38
|
+
*
|
|
39
|
+
* Never rejects: a stream that cannot connect retries quietly forever, because
|
|
40
|
+
* the agent must keep working whether or not the dashboard is reachable.
|
|
41
|
+
*/
|
|
42
|
+
export function startAgentEventStream(options) {
|
|
43
|
+
const log = options.log ?? (() => { });
|
|
44
|
+
const doFetch = options.fetchImpl ?? fetch;
|
|
45
|
+
const url = `${options.server.replace(/\/+$/, "")}/api/taskflow/agents/events`;
|
|
46
|
+
let stopped = false;
|
|
47
|
+
let attempt = 0;
|
|
48
|
+
let everConnected = false;
|
|
49
|
+
let controller = null;
|
|
50
|
+
let retryTimer = null;
|
|
51
|
+
const scheduleRetry = () => {
|
|
52
|
+
if (stopped)
|
|
53
|
+
return;
|
|
54
|
+
const ceiling = Math.min(RECONNECT_BASE_MS * 2 ** attempt, RECONNECT_MAX_MS);
|
|
55
|
+
const delay = Math.round(ceiling / 2 + Math.random() * (ceiling / 2));
|
|
56
|
+
attempt += 1;
|
|
57
|
+
retryTimer = setTimeout(connect, delay);
|
|
58
|
+
retryTimer.unref?.();
|
|
59
|
+
};
|
|
60
|
+
const connect = async () => {
|
|
61
|
+
if (stopped)
|
|
62
|
+
return;
|
|
63
|
+
controller = new AbortController();
|
|
64
|
+
try {
|
|
65
|
+
const res = await doFetch(url, {
|
|
66
|
+
headers: { Authorization: `Agent ${options.key}`, Accept: "text/event-stream" },
|
|
67
|
+
signal: controller.signal,
|
|
68
|
+
});
|
|
69
|
+
if (!res.ok || !res.body) {
|
|
70
|
+
scheduleRetry();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
attempt = 0;
|
|
74
|
+
log("event stream connected");
|
|
75
|
+
// A RE-connect may have missed messages while it was down; let the caller
|
|
76
|
+
// catch up. The first connect needs no catch-up — nothing was missed yet.
|
|
77
|
+
if (everConnected)
|
|
78
|
+
void options.onReconnect?.();
|
|
79
|
+
everConnected = true;
|
|
80
|
+
// Parse SSE frames. `data:` may be split across TCP chunks, so text is
|
|
81
|
+
// buffered until a blank line terminates the frame.
|
|
82
|
+
const reader = res.body.getReader();
|
|
83
|
+
const decoder = new TextDecoder();
|
|
84
|
+
let buffer = "";
|
|
85
|
+
// Watchdog: abort a stream that has gone quiet, which forces the read to
|
|
86
|
+
// settle and drops us into the reconnect path. Created AFTER getReader()
|
|
87
|
+
// (which can throw) and cleared in the finally below, so a throw between
|
|
88
|
+
// connect and the loop can never leak a watchdog — a leaked one would
|
|
89
|
+
// close over the reassigned `controller` and abort the NEXT live
|
|
90
|
+
// connection every ~15s (#44).
|
|
91
|
+
let lastActivity = Date.now();
|
|
92
|
+
const watchdog = setInterval(() => {
|
|
93
|
+
if (Date.now() - lastActivity > STREAM_IDLE_TIMEOUT_MS) {
|
|
94
|
+
log("event stream idle — assuming it died, reconnecting");
|
|
95
|
+
controller?.abort();
|
|
96
|
+
}
|
|
97
|
+
}, Math.floor(STREAM_IDLE_TIMEOUT_MS / 3));
|
|
98
|
+
watchdog.unref?.();
|
|
99
|
+
try {
|
|
100
|
+
for (;;) {
|
|
101
|
+
const { done, value } = await reader.read();
|
|
102
|
+
if (done)
|
|
103
|
+
break;
|
|
104
|
+
// Any byte counts as life, keep-alive comments included.
|
|
105
|
+
lastActivity = Date.now();
|
|
106
|
+
buffer += decoder.decode(value, { stream: true });
|
|
107
|
+
let boundary = buffer.indexOf("\n\n");
|
|
108
|
+
while (boundary !== -1) {
|
|
109
|
+
const frame = buffer.slice(0, boundary);
|
|
110
|
+
buffer = buffer.slice(boundary + 2);
|
|
111
|
+
handleFrame(frame, options);
|
|
112
|
+
boundary = buffer.indexOf("\n\n");
|
|
113
|
+
}
|
|
114
|
+
// A frame that never terminates would grow `buffer` unbounded while
|
|
115
|
+
// bytes keep arriving (so the watchdog never trips) — cap it and force a
|
|
116
|
+
// reconnect instead of growing to OOM (#44).
|
|
117
|
+
if (buffer.length > MAX_STREAM_BUFFER_BYTES) {
|
|
118
|
+
log("event stream buffer exceeded cap without a frame terminator — reconnecting");
|
|
119
|
+
controller?.abort();
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
clearInterval(watchdog);
|
|
126
|
+
}
|
|
127
|
+
if (!stopped) {
|
|
128
|
+
log("event stream closed by server");
|
|
129
|
+
scheduleRetry();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
if (!stopped) {
|
|
134
|
+
log(`event stream error: ${err.message.split("\n")[0]}`);
|
|
135
|
+
scheduleRetry();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
void connect();
|
|
140
|
+
return {
|
|
141
|
+
stop: () => {
|
|
142
|
+
stopped = true;
|
|
143
|
+
if (retryTimer)
|
|
144
|
+
clearTimeout(retryTimer);
|
|
145
|
+
controller?.abort();
|
|
146
|
+
},
|
|
147
|
+
reconnectNow: () => {
|
|
148
|
+
if (stopped)
|
|
149
|
+
return;
|
|
150
|
+
// Abort settles the pending read, which lands in the reconnect path.
|
|
151
|
+
// Reset the backoff: this is a known-cause drop, not a flapping server.
|
|
152
|
+
attempt = 0;
|
|
153
|
+
controller?.abort();
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
/** Pull the `data:` lines out of one SSE frame and dispatch a message event. */
|
|
158
|
+
export function handleFrame(frame, options) {
|
|
159
|
+
const data = frame
|
|
160
|
+
.split("\n")
|
|
161
|
+
.filter((line) => line.startsWith("data:"))
|
|
162
|
+
.map((line) => line.slice(5).trimStart())
|
|
163
|
+
.join("\n");
|
|
164
|
+
if (!data)
|
|
165
|
+
return;
|
|
166
|
+
let envelope;
|
|
167
|
+
try {
|
|
168
|
+
envelope = JSON.parse(data);
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
// A prompt being ANSWERED is an update, not a creation — the row was created
|
|
174
|
+
// when the question appeared. So prompts are routed before the created-only
|
|
175
|
+
// filter below, or every answer would be dropped.
|
|
176
|
+
if (envelope.c?.endsWith(":prompts")) {
|
|
177
|
+
if (isAnsweredPrompt(envelope.d))
|
|
178
|
+
void options.onPromptAnswered?.(envelope.d);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
// Terminal keys: fields are projected inline, so act straight off the event.
|
|
182
|
+
// Broadcast to the whole project — the handler filters by `agent`.
|
|
183
|
+
if (envelope.c?.endsWith(":terminal_inputs")) {
|
|
184
|
+
const row = envelope.d;
|
|
185
|
+
if (row && typeof row.agent === "number" && typeof row.keys === "string") {
|
|
186
|
+
void options.onTerminalKey?.({ agent: row.agent, keys: row.keys });
|
|
187
|
+
}
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
// Creations AND edits matter for delivery (#107): an edited message is the
|
|
191
|
+
// sender saying "proceed with THIS version", so it must reach the pane again.
|
|
192
|
+
// Deletes stay silent — there is nothing new for the agent to read.
|
|
193
|
+
if (envelope.e !== "created" && envelope.e !== "updated")
|
|
194
|
+
return;
|
|
195
|
+
// Every table in a project shares the `project:{id}:*` room family, and a chat
|
|
196
|
+
// event is now id-only — indistinguishable from an id-only task or read-cursor
|
|
197
|
+
// row except by the group name. Without this check every task edit would be
|
|
198
|
+
// typed into the agent's pane as though someone had spoken to it.
|
|
199
|
+
if (!envelope.c?.endsWith(":messages"))
|
|
200
|
+
return;
|
|
201
|
+
const row = envelope.d;
|
|
202
|
+
// The id is all the wire carries, and all that is needed: the body is fetched
|
|
203
|
+
// back over the authorized read API, which re-checks the channel roster.
|
|
204
|
+
// Requiring `body_markdown` here is what silently killed live delivery when
|
|
205
|
+
// chat became id-only — the guard rejected every real event.
|
|
206
|
+
if (!row || typeof row.id !== "number")
|
|
207
|
+
return;
|
|
208
|
+
void options.onMessage(row, envelope.e);
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Whether a message should be delivered to THIS agent's terminal.
|
|
212
|
+
*
|
|
213
|
+
* Every message the agent can see is delivered EXCEPT its own — an agent must
|
|
214
|
+
* stay aware of all channel traffic so it can chat / add information (#40 review).
|
|
215
|
+
* Whether it may ACT on the message is a SEPARATE signal (`canActOnMessage`)
|
|
216
|
+
* surfaced as guidance in the notice, NOT a delivery gate. Its own messages are
|
|
217
|
+
* still skipped: echoing them back reads as a new instruction and could loop the
|
|
218
|
+
* agent against itself.
|
|
219
|
+
*/
|
|
220
|
+
export function shouldDeliver(message, selfAgentId) {
|
|
221
|
+
if (message.sender_kind === "agent" && message.sender_agent === selfAgentId)
|
|
222
|
+
return false;
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Whether THIS agent is a TARGET of the message and may act on it — build,
|
|
227
|
+
* execute, take ownership. A non-target still RECEIVES the message (to reply or
|
|
228
|
+
* add information) but must not act; `formatIncoming` says so.
|
|
229
|
+
*
|
|
230
|
+
* - An empty/absent target set is a broadcast: everyone may act.
|
|
231
|
+
* - Otherwise the agent may act only if it is one of the AGENT targets. A
|
|
232
|
+
* message tagged only at users leaves every agent a non-target.
|
|
233
|
+
*/
|
|
234
|
+
export function canActOnMessage(message, selfAgentId) {
|
|
235
|
+
if (message.targets && message.targets.length > 0) {
|
|
236
|
+
return message.targets.some((t) => t.kind === "agent" && t.id === selfAgentId);
|
|
237
|
+
}
|
|
238
|
+
// Back-compat: rows written before `targets` carry only the single
|
|
239
|
+
// `target_agent`. Null there is a broadcast.
|
|
240
|
+
if (message.target_agent != null)
|
|
241
|
+
return message.target_agent === selfAgentId;
|
|
242
|
+
return true;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* How much of a notice may be typed into the pane.
|
|
246
|
+
*
|
|
247
|
+
* The notice is delivered by TYPING it into a live tmux pane, so it has to stay
|
|
248
|
+
* bounded — but the old 240-char cap silently ate the tail of any real message.
|
|
249
|
+
* A request lost its second half mid-sentence and the agent answered the half it
|
|
250
|
+
* got, with nothing indicating more existed.
|
|
251
|
+
*/
|
|
252
|
+
const MAX_NOTICE_CHARS = 1_000;
|
|
253
|
+
/** Bytes as something a human (or an agent deciding whether to read it) can judge. */
|
|
254
|
+
function humanSize(bytes) {
|
|
255
|
+
if (bytes < 1024)
|
|
256
|
+
return `${bytes} B`;
|
|
257
|
+
if (bytes < 1024 * 1024)
|
|
258
|
+
return `${Math.round(bytes / 1024)} KB`;
|
|
259
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* The one-line notice typed into the agent's pane for an incoming message.
|
|
263
|
+
*
|
|
264
|
+
* Attachments are listed explicitly. A pushed message used to carry body text
|
|
265
|
+
* only, so a file arrived invisibly: the agent read the message, answered it,
|
|
266
|
+
* and never learned anything was attached. Name, size and url are all included
|
|
267
|
+
* so the agent can decide whether to pull the file without another round trip.
|
|
268
|
+
*
|
|
269
|
+
* The manifest is built FIRST and the body flexes into whatever room is left.
|
|
270
|
+
* If something has to be dropped it must be prose, never the pointer to the
|
|
271
|
+
* files — the manifest is precisely what tells the agent there is more to fetch.
|
|
272
|
+
*/
|
|
273
|
+
/**
|
|
274
|
+
* The context block appended to a notice: the ids an agent needs to act on the
|
|
275
|
+
* message without a round trip — scope a query to the project, act on the task,
|
|
276
|
+
* reply to the right person, or `mark_read` the message. Gated on `project`
|
|
277
|
+
* (a real delivered message always has one; the bare wire event does not), and
|
|
278
|
+
* kept on ONE line — a newline would submit the prompt early. Like the
|
|
279
|
+
* attachment manifest, it is never the part that gets truncated.
|
|
280
|
+
*/
|
|
281
|
+
function contextSuffix(message) {
|
|
282
|
+
if (message.project == null)
|
|
283
|
+
return "";
|
|
284
|
+
const parts = [
|
|
285
|
+
`project=${message.project}`,
|
|
286
|
+
`channel=${message.channel}`,
|
|
287
|
+
`message=${message.id}`,
|
|
288
|
+
];
|
|
289
|
+
if (message.task != null)
|
|
290
|
+
parts.push(`task=${message.task}`);
|
|
291
|
+
const sender = message.sender_user != null
|
|
292
|
+
? `user:${message.sender_user}`
|
|
293
|
+
: message.sender_agent != null
|
|
294
|
+
? `agent:${message.sender_agent}`
|
|
295
|
+
: null;
|
|
296
|
+
if (sender)
|
|
297
|
+
parts.push(`from=${sender}`);
|
|
298
|
+
return ` ⟦ctx ${parts.join(" ")}⟧`;
|
|
299
|
+
}
|
|
300
|
+
export function formatIncoming(message, attachments = [], selfAgentId, edited = false) {
|
|
301
|
+
const who = message.sender_label || (message.sender_kind === "user" ? "User" : "Agent");
|
|
302
|
+
// #40 review: a non-target still receives the message but is told, clearly and
|
|
303
|
+
// up front, NOT to act on it — only to reply / add information if useful. When
|
|
304
|
+
// selfAgentId is unknown, or the agent is a target/broadcast recipient, there
|
|
305
|
+
// is no guard and the message reads normally.
|
|
306
|
+
const guard = selfAgentId != null && !canActOnMessage(message, selfAgentId)
|
|
307
|
+
? "🚫 DO NOT ACT — you are not the target of this message. You may reply or add information in chat, but do not build or execute on it. "
|
|
308
|
+
: "";
|
|
309
|
+
// #107: an edit is redelivered so the agent proceeds from the REVISED words —
|
|
310
|
+
// said explicitly, or the agent reads it as a brand-new (duplicate) request.
|
|
311
|
+
const head = edited
|
|
312
|
+
? `[taskflow] ${guard}✏️ EDITED message from ${who} (supersedes the earlier version — continue from this revision): `
|
|
313
|
+
: `[taskflow] ${guard}Message from ${who}: `;
|
|
314
|
+
const manifest = attachments.length
|
|
315
|
+
? ` 📎 ${attachments.length} attachment${attachments.length === 1 ? "" : "s"}: ` +
|
|
316
|
+
attachments.map((a) => `${a.name} (${humanSize(a.size_bytes)}) ${a.url}`).join("; ")
|
|
317
|
+
: "";
|
|
318
|
+
const ctx = contextSuffix(message);
|
|
319
|
+
// Newlines would submit the prompt early; collapse before measuring so the
|
|
320
|
+
// budget reflects what is actually typed.
|
|
321
|
+
const body = message.body_markdown.replace(/\s+/gu, " ").trim();
|
|
322
|
+
// The manifest AND the context block are pointers the agent must keep; only
|
|
323
|
+
// the prose flexes into the room left after them.
|
|
324
|
+
const room = MAX_NOTICE_CHARS - head.length - manifest.length - ctx.length;
|
|
325
|
+
if (body.length <= room)
|
|
326
|
+
return `${head}${body}${manifest}${ctx}`;
|
|
327
|
+
// Say so. A truncated notice that looks complete is how a request gets
|
|
328
|
+
// half-answered; the agent needs to know to go and read the rest.
|
|
329
|
+
const hint = " …[truncated — call check_messages for the full message]";
|
|
330
|
+
const kept = body.slice(0, Math.max(0, room - hint.length));
|
|
331
|
+
return `${head}${kept}${hint}${manifest}${ctx}`;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* The keystrokes that answer a prompt, as verified against a live Claude Code
|
|
335
|
+
* session — not inferred from the UI's appearance.
|
|
336
|
+
*
|
|
337
|
+
* SINGLE-select: the number HIGHLIGHTS the option; Enter submits it.
|
|
338
|
+
* press "2" -> option 2 highlighted, still waiting
|
|
339
|
+
* press Enter -> "You selected: Green"
|
|
340
|
+
*
|
|
341
|
+
* This one was wrong here until 2026-07-21. The comment claimed the number both
|
|
342
|
+
* selected and submitted, so the agent was left sitting on a prompt the
|
|
343
|
+
* dashboard already showed as answered — the worst shape of failure, because
|
|
344
|
+
* the human sees a completed action and the agent sees nothing.
|
|
345
|
+
*
|
|
346
|
+
* MULTI-select: numbers TOGGLE checkboxes, then Right opens the review screen
|
|
347
|
+
* ("Ready to submit your answers?" — 1. Submit / 2. Cancel). This function only
|
|
348
|
+
* REACHES that screen; the submit key is appended once by keystrokesForPrompt,
|
|
349
|
+
* because a multi-question set lands on the identical screen. Verified live
|
|
350
|
+
* 2026-07-21: a single multi-select question sat on that review screen because
|
|
351
|
+
* nothing pressed the final key.
|
|
352
|
+
* press "1" -> [✔] Lint
|
|
353
|
+
* press "3" -> [✔] Tests
|
|
354
|
+
* press Right -> review screen (submit handled by the caller)
|
|
355
|
+
*
|
|
356
|
+
* Getting this wrong is not a cosmetic bug: sending a single digit to a
|
|
357
|
+
* multi-select ticks one box and leaves the agent still waiting, and sending
|
|
358
|
+
* Enter instead of Right submits an empty answer.
|
|
359
|
+
*/
|
|
360
|
+
export function answerKeystrokes(choices, kind) {
|
|
361
|
+
if (!choices.length)
|
|
362
|
+
return [];
|
|
363
|
+
if (kind !== "multi")
|
|
364
|
+
return [String(choices[0]), "Enter"];
|
|
365
|
+
// Toggle each, then Right to open the review screen. The submit at that screen
|
|
366
|
+
// is NOT here — it is shared with multi-question sets and owned by
|
|
367
|
+
// keystrokesForPrompt. A trailing "1" here (as it was) highlighted submit
|
|
368
|
+
// without an Enter and left the agent waiting, the same bug single-select had.
|
|
369
|
+
return [...choices.map(String), "Right"];
|
|
370
|
+
}
|
|
371
|
+
/** The numbers a human chose, from whichever field carries them. */
|
|
372
|
+
export function chosenNumbers(prompt) {
|
|
373
|
+
if (prompt.answer_json) {
|
|
374
|
+
try {
|
|
375
|
+
const parsed = JSON.parse(prompt.answer_json);
|
|
376
|
+
if (Array.isArray(parsed))
|
|
377
|
+
return parsed.filter((n) => typeof n === "number");
|
|
378
|
+
}
|
|
379
|
+
catch {
|
|
380
|
+
/* fall through to the single value */
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
return prompt.answer != null ? [prompt.answer] : [];
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Whether this event is a human decision this agent should act on.
|
|
387
|
+
*
|
|
388
|
+
* `answered` and `cancelled` are BOTH actionable: cancel is the other button on
|
|
389
|
+
* the review screen, and reaching it means replaying every answer first, so it
|
|
390
|
+
* is just as much a keystroke sequence as submit.
|
|
391
|
+
*
|
|
392
|
+
* `answered_by` is what separates a human cancel from the agent clearing its own
|
|
393
|
+
* prompt — it times out, or someone answers in the terminal directly, and the
|
|
394
|
+
* row is marked cancelled with nobody attributed. Firing keys for that would
|
|
395
|
+
* type digits at a screen the agent has already left.
|
|
396
|
+
*/
|
|
397
|
+
export function isAnsweredPrompt(row) {
|
|
398
|
+
const prompt = row;
|
|
399
|
+
if (!prompt || typeof prompt.id !== "number")
|
|
400
|
+
return false;
|
|
401
|
+
if (prompt.answer == null && !prompt.answer_json)
|
|
402
|
+
return false;
|
|
403
|
+
if (prompt.status === "answered")
|
|
404
|
+
return true;
|
|
405
|
+
return prompt.status === "cancelled" && prompt.answered_by != null;
|
|
406
|
+
}
|
|
407
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Bin entry: load `.taskflow.json`, build the MCP server, and serve over stdio.
|
|
4
|
+
*
|
|
5
|
+
* A configuration failure prints a clear message to stderr and exits non-zero so
|
|
6
|
+
* the human fixes the credential file rather than getting a silent dead server.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|