devharness 0.9.8 → 0.9.9
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 +15 -0
- package/build/block-events.d.ts +3 -5
- package/build/block-events.d.ts.map +1 -1
- package/build/block-events.js +6 -24
- package/build/block-events.js.map +1 -1
- package/build/block-events.test.js +10 -7
- package/build/block-events.test.js.map +1 -1
- package/build/cdp-manager.d.ts +7 -0
- package/build/cdp-manager.d.ts.map +1 -1
- package/build/cdp-manager.js +9 -0
- package/build/cdp-manager.js.map +1 -1
- package/build/cli/index.d.ts +26 -0
- package/build/cli/index.d.ts.map +1 -0
- package/build/cli/index.js +290 -0
- package/build/cli/index.js.map +1 -0
- package/build/cli/process-tree.d.ts +21 -0
- package/build/cli/process-tree.d.ts.map +1 -0
- package/build/cli/process-tree.js +51 -0
- package/build/cli/process-tree.js.map +1 -0
- package/build/cli/session-match.d.ts +37 -0
- package/build/cli/session-match.d.ts.map +1 -0
- package/build/cli/session-match.js +55 -0
- package/build/cli/session-match.js.map +1 -0
- package/build/cli/session-match.test.d.ts +17 -0
- package/build/cli/session-match.test.d.ts.map +1 -0
- package/build/cli/session-match.test.js +125 -0
- package/build/cli/session-match.test.js.map +1 -0
- package/build/config.d.ts +1 -1
- package/build/config.d.ts.map +1 -1
- package/build/config.js +1 -0
- package/build/config.js.map +1 -1
- package/build/connection-manager.d.ts.map +1 -1
- package/build/connection-manager.js +6 -1
- package/build/connection-manager.js.map +1 -1
- package/build/index.js +57 -4
- package/build/index.js.map +1 -1
- package/build/mcp-supervisor.js +43 -0
- package/build/mcp-supervisor.js.map +1 -1
- package/build/network-monitor.d.ts +13 -2
- package/build/network-monitor.d.ts.map +1 -1
- package/build/network-monitor.js +38 -2
- package/build/network-monitor.js.map +1 -1
- package/build/network-monitor.test.js +50 -0
- package/build/network-monitor.test.js.map +1 -1
- package/build/plugin-session-start-hook.test.d.ts +10 -0
- package/build/plugin-session-start-hook.test.d.ts.map +1 -0
- package/build/plugin-session-start-hook.test.js +187 -0
- package/build/plugin-session-start-hook.test.js.map +1 -0
- package/build/session-endpoint.d.ts +72 -0
- package/build/session-endpoint.d.ts.map +1 -0
- package/build/session-endpoint.js +220 -0
- package/build/session-endpoint.js.map +1 -0
- package/build/session-endpoint.test.d.ts +10 -0
- package/build/session-endpoint.test.d.ts.map +1 -0
- package/build/session-endpoint.test.js +202 -0
- package/build/session-endpoint.test.js.map +1 -0
- package/build/session-events.d.ts +28 -0
- package/build/session-events.d.ts.map +1 -0
- package/build/session-events.js +38 -0
- package/build/session-events.js.map +1 -0
- package/build/session-events.test.d.ts +8 -0
- package/build/session-events.test.d.ts.map +1 -0
- package/build/session-events.test.js +56 -0
- package/build/session-events.test.js.map +1 -0
- package/build/session-identity.d.ts +56 -0
- package/build/session-identity.d.ts.map +1 -0
- package/build/session-identity.js +96 -0
- package/build/session-identity.js.map +1 -0
- package/build/session-identity.test.d.ts +9 -0
- package/build/session-identity.test.d.ts.map +1 -0
- package/build/session-identity.test.js +126 -0
- package/build/session-identity.test.js.map +1 -0
- package/build/session-messages.d.ts +70 -0
- package/build/session-messages.d.ts.map +1 -0
- package/build/session-messages.js +139 -0
- package/build/session-messages.js.map +1 -0
- package/build/tool-response.d.ts +40 -1
- package/build/tool-response.d.ts.map +1 -1
- package/build/tool-response.js.map +1 -1
- package/build/tools/console-tools.d.ts +4 -0
- package/build/tools/console-tools.d.ts.map +1 -1
- package/build/tools/console-tools.js +55 -1
- package/build/tools/console-tools.js.map +1 -1
- package/build/tools/inspect-worker-meta.test.d.ts +9 -0
- package/build/tools/inspect-worker-meta.test.d.ts.map +1 -0
- package/build/tools/inspect-worker-meta.test.js +122 -0
- package/build/tools/inspect-worker-meta.test.js.map +1 -0
- package/build/tools/inspection-tools.d.ts +12 -5
- package/build/tools/inspection-tools.d.ts.map +1 -1
- package/build/tools/inspection-tools.js +86 -5
- package/build/tools/inspection-tools.js.map +1 -1
- package/build/tools/issues-tools.d.ts +3 -3
- package/build/tools/message-tools.d.ts +51 -0
- package/build/tools/message-tools.d.ts.map +1 -0
- package/build/tools/message-tools.js +250 -0
- package/build/tools/message-tools.js.map +1 -0
- package/build/tools/message-tools.test.d.ts +9 -0
- package/build/tools/message-tools.test.d.ts.map +1 -0
- package/build/tools/message-tools.test.js +332 -0
- package/build/tools/message-tools.test.js.map +1 -0
- package/build/tools/network-tools.js +1 -1
- package/build/tools/network-tools.js.map +1 -1
- package/build/tools/replay-tools.d.ts +3 -3
- package/build/tools/server-tools.d.ts +3 -3
- package/build/worker-targets.d.ts +75 -0
- package/build/worker-targets.d.ts.map +1 -0
- package/build/worker-targets.js +171 -0
- package/build/worker-targets.js.map +1 -0
- package/build/worker-targets.test.d.ts +8 -0
- package/build/worker-targets.test.d.ts.map +1 -0
- package/build/worker-targets.test.js +118 -0
- package/build/worker-targets.test.js.map +1 -0
- package/docs/instructions.md +23 -12
- package/docs/messages.md +150 -0
- package/package.json +2 -1
- package/plugin/skills/devharness/SKILL.md +36 -8
- package/plugin/skills/devharness/references/tool-categories.md +8 -1
|
@@ -41,7 +41,7 @@ export declare function createIssuesTools(executeToolCall: ExecuteToolCall, getS
|
|
|
41
41
|
fromComment: z.ZodOptional<z.ZodNumber>;
|
|
42
42
|
allowPrivilegedSteps: z.ZodOptional<z.ZodBoolean>;
|
|
43
43
|
}, "strict", z.ZodTypeAny, {
|
|
44
|
-
action: "link" | "list" | "publish" | "sync" | "import" | "pullSequence" | "
|
|
44
|
+
action: "link" | "resolve" | "list" | "publish" | "sync" | "import" | "pullSequence" | "acknowledge" | "comment" | "create" | "workOn";
|
|
45
45
|
type?: "bug" | "feature" | undefined;
|
|
46
46
|
status?: "fixed" | "acknowledged" | "pending" | "in_progress" | "implemented" | undefined;
|
|
47
47
|
search?: string | undefined;
|
|
@@ -64,7 +64,7 @@ export declare function createIssuesTools(executeToolCall: ExecuteToolCall, getS
|
|
|
64
64
|
fromComment?: number | undefined;
|
|
65
65
|
allowPrivilegedSteps?: boolean | undefined;
|
|
66
66
|
}, {
|
|
67
|
-
action: "link" | "list" | "publish" | "sync" | "import" | "pullSequence" | "
|
|
67
|
+
action: "link" | "resolve" | "list" | "publish" | "sync" | "import" | "pullSequence" | "acknowledge" | "comment" | "create" | "workOn";
|
|
68
68
|
type?: "bug" | "feature" | undefined;
|
|
69
69
|
status?: "fixed" | "acknowledged" | "pending" | "in_progress" | "implemented" | undefined;
|
|
70
70
|
search?: string | undefined;
|
|
@@ -94,7 +94,7 @@ export declare function createIssuesTools(executeToolCall: ExecuteToolCall, getS
|
|
|
94
94
|
} | undefined;
|
|
95
95
|
};
|
|
96
96
|
handler: (args: {
|
|
97
|
-
action: "link" | "list" | "publish" | "sync" | "import" | "pullSequence" | "
|
|
97
|
+
action: "link" | "resolve" | "list" | "publish" | "sync" | "import" | "pullSequence" | "acknowledge" | "comment" | "create" | "workOn";
|
|
98
98
|
type?: "bug" | "feature" | undefined;
|
|
99
99
|
status?: "fixed" | "acknowledged" | "pending" | "in_progress" | "implemented" | undefined;
|
|
100
100
|
search?: string | undefined;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message tool - text between two devharness sessions on this machine.
|
|
3
|
+
*
|
|
4
|
+
* Transport is `src/session-messages.ts`: one append-only JSONL mailbox per
|
|
5
|
+
* session under `~/.devharness/messages/`. Discovery reuses the dashboard
|
|
6
|
+
* hub's session registry, which already holds every live session's short id,
|
|
7
|
+
* pid and project directory.
|
|
8
|
+
*/
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
export declare function createMessageTools(): {
|
|
11
|
+
message: {
|
|
12
|
+
description: string;
|
|
13
|
+
zodSchema: z.ZodObject<{
|
|
14
|
+
action: z.ZodEnum<["sessions", "send", "read", "reply"]>;
|
|
15
|
+
to: z.ZodOptional<z.ZodString>;
|
|
16
|
+
text: z.ZodOptional<z.ZodString>;
|
|
17
|
+
replyTo: z.ZodOptional<z.ZodString>;
|
|
18
|
+
waitForReplyMs: z.ZodOptional<z.ZodNumber>;
|
|
19
|
+
pollIntervalMs: z.ZodOptional<z.ZodNumber>;
|
|
20
|
+
}, "strict", z.ZodTypeAny, {
|
|
21
|
+
action: "sessions" | "send" | "read" | "reply";
|
|
22
|
+
text?: string | undefined;
|
|
23
|
+
replyTo?: string | undefined;
|
|
24
|
+
to?: string | undefined;
|
|
25
|
+
pollIntervalMs?: number | undefined;
|
|
26
|
+
waitForReplyMs?: number | undefined;
|
|
27
|
+
}, {
|
|
28
|
+
action: "sessions" | "send" | "read" | "reply";
|
|
29
|
+
text?: string | undefined;
|
|
30
|
+
replyTo?: string | undefined;
|
|
31
|
+
to?: string | undefined;
|
|
32
|
+
pollIntervalMs?: number | undefined;
|
|
33
|
+
waitForReplyMs?: number | undefined;
|
|
34
|
+
}>;
|
|
35
|
+
inputSchema: import("zod-to-json-schema").JsonSchema7Type & {
|
|
36
|
+
$schema?: string | undefined;
|
|
37
|
+
definitions?: {
|
|
38
|
+
[key: string]: import("zod-to-json-schema").JsonSchema7Type;
|
|
39
|
+
} | undefined;
|
|
40
|
+
};
|
|
41
|
+
handler: (args: {
|
|
42
|
+
action: "sessions" | "send" | "read" | "reply";
|
|
43
|
+
text?: string | undefined;
|
|
44
|
+
replyTo?: string | undefined;
|
|
45
|
+
to?: string | undefined;
|
|
46
|
+
pollIntervalMs?: number | undefined;
|
|
47
|
+
waitForReplyMs?: number | undefined;
|
|
48
|
+
}, abortSignal?: AbortSignal) => Promise<any>;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=message-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-tools.d.ts","sourceRoot":"","sources":["../../src/tools/message-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAyDxB,wBAAgB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgOjC"}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message tool - text between two devharness sessions on this machine.
|
|
3
|
+
*
|
|
4
|
+
* Transport is `src/session-messages.ts`: one append-only JSONL mailbox per
|
|
5
|
+
* session under `~/.devharness/messages/`. Discovery reuses the dashboard
|
|
6
|
+
* hub's session registry, which already holds every live session's short id,
|
|
7
|
+
* pid and project directory.
|
|
8
|
+
*/
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
import { createTool } from '../validation-helpers.js';
|
|
11
|
+
import { createSuccessResponse, createErrorResponse } from '../messages.js';
|
|
12
|
+
import { getProjectDir } from '../helpers/paths.js';
|
|
13
|
+
import { getSessionInfo } from './dashboard-tools.js';
|
|
14
|
+
import { listSessionRecords } from '../session-endpoint.js';
|
|
15
|
+
import { resolveSessionName } from '../session-identity.js';
|
|
16
|
+
import { appendEvent } from '../session-events.js';
|
|
17
|
+
import { isValidMailboxId, getMailboxPath, getMessagesDir, listMailboxIds, readMailbox, readCursor, writeCursor, sendMessage, waitForMailbox, } from '../session-messages.js';
|
|
18
|
+
const messageSchema = z.object({
|
|
19
|
+
action: z.enum(['sessions', 'send', 'read', 'reply'])
|
|
20
|
+
.describe('sessions (list reachable sessions and this one\'s mailbox path), send (write to another session), read (take new messages from this session\'s mailbox), reply (answer a message by id)'),
|
|
21
|
+
to: z.string().optional()
|
|
22
|
+
.describe('send: recipient mailbox id, as reported by action sessions'),
|
|
23
|
+
text: z.string().optional()
|
|
24
|
+
.describe('send/reply: the message body'),
|
|
25
|
+
replyTo: z.string().optional()
|
|
26
|
+
.describe('reply: id of the message being answered - the reply goes to its sender'),
|
|
27
|
+
waitForReplyMs: z.number().int().positive().max(300000).optional()
|
|
28
|
+
.describe('send/reply: hold the call open until a message arrives in this session\'s mailbox, or this many ms elapse (max 300000). Returns on any arrival, not only a tagged reply.'),
|
|
29
|
+
pollIntervalMs: z.number().int().min(100).max(5000).optional()
|
|
30
|
+
.describe('send/reply: interval between mailbox checks while waiting (default 500)'),
|
|
31
|
+
}).strict();
|
|
32
|
+
const DEFAULT_POLL_INTERVAL_MS = 500;
|
|
33
|
+
function buildMeta(action, self, extra) {
|
|
34
|
+
return {
|
|
35
|
+
tool: 'message',
|
|
36
|
+
action,
|
|
37
|
+
timestamp: Date.now(),
|
|
38
|
+
message: { action, self, ...extra },
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/** One line per message, newest last, for the rendered response. */
|
|
42
|
+
function formatMessages(messages) {
|
|
43
|
+
return messages
|
|
44
|
+
.map(m => `- [${m.id.slice(0, 8)}] from ${m.from}${m.replyTo ? ` (reply to ${m.replyTo.slice(0, 8)})` : ''} at ${m.at}\n ${m.text}`)
|
|
45
|
+
.join('\n');
|
|
46
|
+
}
|
|
47
|
+
export function createMessageTools() {
|
|
48
|
+
return {
|
|
49
|
+
message: createTool('Text between two devharness sessions on this machine. Actions: sessions (who is reachable), send (write to another session, optionally holding the call open for a reply), read (take new messages), reply (answer a message by id).', messageSchema, async (args, abortSignal) => {
|
|
50
|
+
const self = resolveSessionName(getSessionInfo()?.shortId);
|
|
51
|
+
const pollIntervalMs = args.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
52
|
+
switch (args.action) {
|
|
53
|
+
// ---- sessions ------------------------------------------------------
|
|
54
|
+
case 'sessions': {
|
|
55
|
+
// The endpoint records are written by the live child and swept by
|
|
56
|
+
// a pid check, so they carry both identity and liveness. The
|
|
57
|
+
// dashboard hub holds the same sessions but prunes only on a clean
|
|
58
|
+
// socket close, which reports a replaced child as still running.
|
|
59
|
+
const records = listSessionRecords();
|
|
60
|
+
const mailboxIds = await listMailboxIds();
|
|
61
|
+
const rows = [];
|
|
62
|
+
const seen = new Set();
|
|
63
|
+
for (const record of records) {
|
|
64
|
+
const id = record.shortId ?? `pid-${record.pid}`;
|
|
65
|
+
if (seen.has(id))
|
|
66
|
+
continue;
|
|
67
|
+
seen.add(id);
|
|
68
|
+
rows.push({ id, pid: record.pid, cwd: record.cwd, live: true, self: id === self });
|
|
69
|
+
}
|
|
70
|
+
// A mailbox with no session behind it is one that has exited.
|
|
71
|
+
// Listing it keeps a reply to a dead session visible, not silent.
|
|
72
|
+
for (const id of mailboxIds) {
|
|
73
|
+
if (seen.has(id))
|
|
74
|
+
continue;
|
|
75
|
+
seen.add(id);
|
|
76
|
+
rows.push({ id, live: false, self: id === self });
|
|
77
|
+
}
|
|
78
|
+
if (!seen.has(self)) {
|
|
79
|
+
rows.push({ id: self, pid: process.pid, live: true, self: true });
|
|
80
|
+
}
|
|
81
|
+
const response = createSuccessResponse('MESSAGE_SESSIONS', {
|
|
82
|
+
self,
|
|
83
|
+
mailboxPath: getMailboxPath(self),
|
|
84
|
+
messagesDir: getMessagesDir(),
|
|
85
|
+
sessionList: rows
|
|
86
|
+
.map(r => `- ${r.id}${r.self ? ' (this session)' : ''} - ${r.live ? 'live' : 'no process'}${r.cwd ? ` - ${r.cwd}` : ''}`)
|
|
87
|
+
.join('\n'),
|
|
88
|
+
count: rows.length,
|
|
89
|
+
});
|
|
90
|
+
return { ...response, _meta: buildMeta('sessions', self, { sessions: rows }) };
|
|
91
|
+
}
|
|
92
|
+
// ---- send / reply --------------------------------------------------
|
|
93
|
+
case 'send':
|
|
94
|
+
case 'reply': {
|
|
95
|
+
if (!args.text) {
|
|
96
|
+
return createErrorResponse('MESSAGE_INVALID_ARGS', {
|
|
97
|
+
message: `message({ action: '${args.action}' }) requires text.`,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
let target;
|
|
101
|
+
let replyTo;
|
|
102
|
+
if (args.action === 'reply') {
|
|
103
|
+
if (!args.replyTo) {
|
|
104
|
+
return createErrorResponse('MESSAGE_INVALID_ARGS', {
|
|
105
|
+
message: "message({ action: 'reply' }) requires replyTo - the id of the message being answered.",
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
const own = await readMailbox(self);
|
|
109
|
+
const original = own.find(m => m.id === args.replyTo || m.id.startsWith(args.replyTo));
|
|
110
|
+
if (!original) {
|
|
111
|
+
return createErrorResponse('MESSAGE_TARGET_UNKNOWN', {
|
|
112
|
+
target: args.replyTo,
|
|
113
|
+
reason: `No message with id "${args.replyTo}" in this session's mailbox`,
|
|
114
|
+
self,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
target = original.from;
|
|
118
|
+
replyTo = original.id;
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
if (!args.to) {
|
|
122
|
+
return createErrorResponse('MESSAGE_INVALID_ARGS', {
|
|
123
|
+
message: "message({ action: 'send' }) requires to - a mailbox id from message({ action: 'sessions' }).",
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
target = args.to;
|
|
127
|
+
}
|
|
128
|
+
if (!isValidMailboxId(target)) {
|
|
129
|
+
return createErrorResponse('MESSAGE_TARGET_UNKNOWN', {
|
|
130
|
+
target,
|
|
131
|
+
reason: 'Not a valid mailbox id (letters, digits, dot, dash, underscore; 64 chars max)',
|
|
132
|
+
self,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
if (target === self) {
|
|
136
|
+
return createErrorResponse('MESSAGE_INVALID_ARGS', {
|
|
137
|
+
message: `"${target}" is this session's own mailbox - a message to it would never reach another agent.`,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
// The line count is taken BEFORE the append: a reply that lands
|
|
141
|
+
// between the append and the first poll sits past this offset and
|
|
142
|
+
// is returned, rather than being counted as already-read.
|
|
143
|
+
const fromLine = args.waitForReplyMs ? (await readMailbox(self)).length : 0;
|
|
144
|
+
// Where `read` had got to. A mailbox with unread lines sits behind
|
|
145
|
+
// fromLine, and advancing the cursor past them would drop them.
|
|
146
|
+
const cursorBefore = args.waitForReplyMs ? await readCursor(self) : 0;
|
|
147
|
+
const sent = await sendMessage({
|
|
148
|
+
from: self,
|
|
149
|
+
fromCwd: getProjectDir(),
|
|
150
|
+
to: target,
|
|
151
|
+
text: args.text,
|
|
152
|
+
...(replyTo ? { replyTo } : {}),
|
|
153
|
+
});
|
|
154
|
+
// The recipient's Monitor watches its event stream, not its
|
|
155
|
+
// mailbox, so the arrival is announced there.
|
|
156
|
+
await appendEvent(target, 'message', {
|
|
157
|
+
from: self,
|
|
158
|
+
id: sent.id,
|
|
159
|
+
detail: `Message from ${self}: ${args.text.slice(0, 120)}`,
|
|
160
|
+
resolve: "message({ action: 'read' })",
|
|
161
|
+
});
|
|
162
|
+
// A typo mints a mailbox nothing ever reads, and nothing removes
|
|
163
|
+
// one, so the sessions listing grows a fictional peer per slip.
|
|
164
|
+
// Refusing would block a genuine first message to a session whose
|
|
165
|
+
// server is suspended, which has neither record nor mailbox, so the
|
|
166
|
+
// state is reported rather than enforced.
|
|
167
|
+
const targetListening = listSessionRecords()
|
|
168
|
+
.some(r => (r.shortId ?? `pid-${r.pid}`) === target);
|
|
169
|
+
if (!args.waitForReplyMs) {
|
|
170
|
+
const response = createSuccessResponse('MESSAGE_SENT', {
|
|
171
|
+
to: target,
|
|
172
|
+
id: sent.id,
|
|
173
|
+
shortId: sent.id.slice(0, 8),
|
|
174
|
+
mailboxPath: getMailboxPath(target),
|
|
175
|
+
deliveryNote: targetListening
|
|
176
|
+
? ''
|
|
177
|
+
: `\n\n**No session is listening as \`${target}\` right now.** It reads this when it next starts, or the id is a typo and nothing ever will - check \`message({ action: 'sessions' })\`.`,
|
|
178
|
+
});
|
|
179
|
+
return { ...response, _meta: buildMeta(args.action, self, { sent, targetListening }) };
|
|
180
|
+
}
|
|
181
|
+
const waitStart = Date.now();
|
|
182
|
+
const received = await waitForMailbox(self, fromLine, {
|
|
183
|
+
timeoutMs: args.waitForReplyMs,
|
|
184
|
+
pollIntervalMs,
|
|
185
|
+
abortSignal,
|
|
186
|
+
});
|
|
187
|
+
const waitElapsedMs = Date.now() - waitStart;
|
|
188
|
+
if (received.length === 0) {
|
|
189
|
+
return {
|
|
190
|
+
...createErrorResponse('MESSAGE_REPLY_TIMEOUT', {
|
|
191
|
+
to: target,
|
|
192
|
+
timeoutMs: args.waitForReplyMs,
|
|
193
|
+
id: sent.id.slice(0, 8),
|
|
194
|
+
self,
|
|
195
|
+
mailboxPath: getMailboxPath(self),
|
|
196
|
+
}),
|
|
197
|
+
_meta: buildMeta(args.action, self, { sent, waitTimedOut: true, waitElapsedMs }),
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
// The wait consumed these lines, so the cursor moves past them and
|
|
201
|
+
// a later `read` does not hand back the same messages - but only
|
|
202
|
+
// when `read` had already caught up. With unread lines behind
|
|
203
|
+
// fromLine there is no cursor value that means "those unread, these
|
|
204
|
+
// read", so the cursor stays put and `read` returns the backlog
|
|
205
|
+
// together with what the wait already showed. Repeating a message
|
|
206
|
+
// is recoverable; losing one is not.
|
|
207
|
+
if (cursorBefore >= fromLine) {
|
|
208
|
+
await writeCursor(self, fromLine + received.length);
|
|
209
|
+
}
|
|
210
|
+
const response = createSuccessResponse('MESSAGE_REPLY_RECEIVED', {
|
|
211
|
+
to: target,
|
|
212
|
+
count: received.length,
|
|
213
|
+
elapsedMs: waitElapsedMs,
|
|
214
|
+
messageList: formatMessages(received),
|
|
215
|
+
// A cursor cannot express "those unread, these read", so with a
|
|
216
|
+
// backlog behind fromLine it stays put and `read` hands these
|
|
217
|
+
// back a second time. Acting on them twice is the failure that
|
|
218
|
+
// silence here would cause.
|
|
219
|
+
repeatNote: cursorBefore < fromLine
|
|
220
|
+
? `\n\n**Unread messages sit behind these**, so the cursor did not move: \`message({ action: 'read' })\` returns the backlog AND repeats the message(s) above once. Treat a repeat as already handled.`
|
|
221
|
+
: '',
|
|
222
|
+
});
|
|
223
|
+
return {
|
|
224
|
+
...response,
|
|
225
|
+
_meta: buildMeta(args.action, self, { sent, received, waitTimedOut: false, waitElapsedMs }),
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
// ---- read ----------------------------------------------------------
|
|
229
|
+
case 'read': {
|
|
230
|
+
const all = await readMailbox(self);
|
|
231
|
+
const cursor = await readCursor(self);
|
|
232
|
+
// A mailbox deleted while a cursor survives would slice past the
|
|
233
|
+
// end and return nothing forever; clamp to the current length.
|
|
234
|
+
const from = Math.min(cursor, all.length);
|
|
235
|
+
const fresh = all.slice(from);
|
|
236
|
+
await writeCursor(self, all.length);
|
|
237
|
+
const response = createSuccessResponse('MESSAGE_INBOX', {
|
|
238
|
+
self,
|
|
239
|
+
count: fresh.length,
|
|
240
|
+
total: all.length,
|
|
241
|
+
mailboxPath: getMailboxPath(self),
|
|
242
|
+
messageList: fresh.length ? formatMessages(fresh) : '(nothing new)',
|
|
243
|
+
});
|
|
244
|
+
return { ...response, _meta: buildMeta('read', self, { received: fresh }) };
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}),
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=message-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-tools.js","sourceRoot":"","sources":["../../src/tools/message-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the `message` tool and its mailbox transport.
|
|
3
|
+
*
|
|
4
|
+
* Every case runs against a temporary DEVHARNESS_DIR, so the mailboxes are the
|
|
5
|
+
* real files the tool writes in production rather than a mock of them - the
|
|
6
|
+
* cursor and the blocking wait are both defined by what is on disk.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=message-tools.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-tools.test.d.ts","sourceRoot":"","sources":["../../src/tools/message-tools.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|