@wrongstack/core 0.306.4 → 0.307.1
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/dist/chronicle/index.js +957 -953
- package/dist/chronicle/metrics-ingest.d.ts +55 -0
- package/dist/chronicle/metrics-schema.d.ts +86 -0
- package/dist/chronicle/metrics-store.d.ts +5 -120
- package/dist/chronicle/project-server.js +1083 -1084
- package/dist/chronicle/sqlite-journal-quota.d.ts +39 -0
- package/dist/chronicle/sqlite-journal-schema.d.ts +25 -0
- package/dist/chronicle/sqlite-journal.d.ts +12 -177
- package/dist/coordination/agents/index.js +1803 -1701
- package/dist/coordination/agents/project-agent-capture.d.ts +48 -0
- package/dist/coordination/agents/project-agent-identity.d.ts +3 -129
- package/dist/coordination/agents/project-agent-roster.d.ts +17 -0
- package/dist/coordination/agents/types.d.ts +6 -9
- package/dist/coordination/index.js +6051 -5880
- package/dist/coordination/mail-tools.d.ts +1 -1
- package/dist/coordination/mailbox-http-actor-query.d.ts +16 -0
- package/dist/coordination/mailbox-http-router.d.ts +0 -48
- package/dist/coordination/mailbox-http-sse.d.ts +12 -0
- package/dist/coordination/mailbox-message-types.d.ts +71 -0
- package/dist/coordination/mailbox-predicates.d.ts +13 -0
- package/dist/coordination/mailbox-project-server.js +1 -1
- package/dist/coordination/mailbox-session-sync.d.ts +8 -0
- package/dist/coordination/mailbox-types.d.ts +6 -793
- package/dist/core/agent-loop-context.d.ts +28 -0
- package/dist/core/agent-loop-detector.d.ts +25 -0
- package/dist/core/fallback-doctor.d.ts +72 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.js +1859 -1335
- package/dist/defaults/index.js +3647 -3559
- package/dist/execution/autonomy-brain-llm.d.ts +55 -0
- package/dist/execution/autonomy-brain.d.ts +3 -156
- package/dist/execution/compaction-budget.d.ts +38 -0
- package/dist/execution/compaction-core.d.ts +3 -170
- package/dist/execution/compaction-elision.d.ts +58 -0
- package/dist/execution/council-orchestrator-helpers.d.ts +39 -0
- package/dist/execution/council-orchestrator.d.ts +3 -42
- package/dist/execution/council-response-parser.d.ts +56 -0
- package/dist/execution/index.js +2475 -2449
- package/dist/execution/prompt-enhancer.js +11 -3
- package/dist/execution/tool-executor-guard.d.ts +18 -0
- package/dist/execution/tool-executor-runner.d.ts +12 -0
- package/dist/execution/tool-executor.d.ts +0 -75
- package/dist/goal/index.js +19 -6
- package/dist/hq/index.js +8 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +8021 -7405
- package/dist/infrastructure/index.js +3 -1
- package/dist/kernel/events/agent-events.d.ts +2 -0
- package/dist/kernel/events/provider-events.d.ts +13 -0
- package/dist/plugin/index.js +2590 -2561
- package/dist/plugins/auto-review-config.d.ts +53 -0
- package/dist/plugins/auto-review-git.d.ts +19 -0
- package/dist/plugins/auto-review-plugin.d.ts +2 -140
- package/dist/plugins/review-finding-verification.d.ts +7 -0
- package/dist/prompts/index.d.ts +1 -0
- package/dist/prompts/index.js +601 -0
- package/dist/prompts/prompt-journal.d.ts +103 -0
- package/dist/security/index.js +627 -652
- package/dist/security/permission-explain.d.ts +19 -0
- package/dist/security/permission-policy.d.ts +0 -101
- package/dist/security/yolo-risk.d.ts +5 -4
- package/dist/session-catalog/index.js +220 -212
- package/dist/session-catalog/project-server.js +227 -219
- package/dist/session-catalog/store-rebuild.d.ts +9 -0
- package/dist/session-catalog/store-schema.d.ts +48 -0
- package/dist/session-catalog/store.d.ts +0 -17
- package/dist/storage/director-state.d.ts +6 -0
- package/dist/storage/file-session-writer.d.ts +2 -58
- package/dist/storage/index.d.ts +2 -1
- package/dist/storage/index.js +2057 -1925
- package/dist/storage/orphan-lock-cleaner.d.ts +15 -0
- package/dist/storage/queue-store.d.ts +6 -0
- package/dist/storage/session-recovery.d.ts +9 -0
- package/dist/storage/session-store/rename-session.d.ts +16 -0
- package/dist/storage/session-store/resume-session.d.ts +26 -0
- package/dist/storage/session-store/session-store-clear.d.ts +11 -0
- package/dist/storage/session-store/session-store-index.d.ts +13 -0
- package/dist/storage/session-store.d.ts +1 -129
- package/dist/storage/session-summary-tracker.d.ts +39 -0
- package/dist/storage/session-write-buffer.d.ts +43 -0
- package/dist/storage/session-writer/session-writer-flush.d.ts +4 -0
- package/dist/storage/session-writer/session-writer-summary-tracker.d.ts +28 -0
- package/dist/tools/fallback-agent-model-assign-tool.d.ts +18 -0
- package/dist/tools/fallback-leader-model-set-tool.d.ts +18 -0
- package/dist/tools/fallback-manage-tools.d.ts +8 -45
- package/dist/tools/fallback-profile-manage-tool.d.ts +16 -0
- package/dist/tools/fallback-provider-key-set-tool.d.ts +17 -0
- package/dist/tools/fallback-provider-manage-tool.d.ts +26 -0
- package/dist/tools/index.js +5124 -5071
- package/dist/types/config/root.d.ts +7 -2
- package/dist/types/default-config.d.ts +1 -1
- package/dist/types/index.d.ts +54 -55
- package/dist/types/index.js +953 -932
- package/dist/types/runtime-capability-manifest.d.ts +5 -5
- package/dist/types/session-markers.d.ts +12 -0
- package/dist/types/session-markers.js +19 -0
- package/dist/worktree/worktree-manager.d.ts +1 -1
- package/instructions/agents/architect.md +2 -0
- package/instructions/agents/code-reviewer.md +1 -0
- package/instructions/agents/debugger.md +2 -0
- package/instructions/agents/executor.md +2 -0
- package/instructions/agents/explore.md +3 -1
- package/instructions/agents/refactor.md +2 -0
- package/instructions/agents/reviewer.md +1 -0
- package/instructions/coordination/subagent-baseline.md +68 -7
- package/instructions/llm/prompt-enhancer.md +2 -1
- package/instructions/sections/tool/common-patterns.md +30 -0
- package/instructions/sections/tool/delegation-compact.md +3 -1
- package/instructions/sections/tool/delegation-full.md +5 -1
- package/instructions/system-lite.md +32 -4
- package/instructions/system-pro.md +63 -9
- package/instructions/system.md +56 -11
- package/package.json +9 -5
|
@@ -1,625 +1,91 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
* Agents can leave notes for specific agents or broadcast to all. Each agent
|
|
5
|
-
* periodically checks the mailbox or retrieves messages via tool calls.
|
|
6
|
-
*
|
|
7
|
-
* ## Cross-session communication
|
|
8
|
-
*
|
|
9
|
-
* The mailbox is stored at **project level** (`~/.wrongstack/projects/<slug>/_mailbox.sqlite`, owned by one detached
|
|
10
|
-
* project server and reached over IPC),
|
|
11
|
-
* so agents in different terminal sessions / WebUI tabs working on the same
|
|
12
|
-
* canonical project can communicate live, even when they run in different
|
|
13
|
-
* processes, clients, branches, or linked Git worktrees.
|
|
14
|
-
*
|
|
15
|
-
* ## Agent registration
|
|
16
|
-
*
|
|
17
|
-
* Every agent that uses the mailbox registers itself with a heartbeat.
|
|
18
|
-
* Other agents can discover online agents via `getOnlineAgents()`.
|
|
19
|
-
* Stale agents (no heartbeat > 60s) are pruned automatically.
|
|
20
|
-
*
|
|
21
|
-
* ## Read receipts
|
|
22
|
-
*
|
|
23
|
-
* Each message tracks per-recipient read status via a `readBy` map:
|
|
24
|
-
* `{ "agentId": "ISO8601" }`. When agent X reads a message, its entry
|
|
25
|
-
* is added. The WebUI shows who read what and when.
|
|
26
|
-
*
|
|
27
|
-
* @module mailbox-types
|
|
28
|
-
*/
|
|
29
|
-
import { type MailboxMessageType } from './mailbox-type-properties.js';
|
|
1
|
+
import type { MailboxMessageType } from './mailbox-type-properties.js';
|
|
2
|
+
import type { MailboxAudience, MailboxMessage, MailboxSessionAffinity, MailboxTaskContext } from './mailbox-message-types.js';
|
|
30
3
|
export { MAILBOX_TYPE_PROPERTIES, type MailboxMessageType, type MailboxTypeCategory, } from './mailbox-type-properties.js';
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
*
|
|
36
|
-
* ───── Type semantics — decision matrix for senders ──────────────────────
|
|
37
|
-
*
|
|
38
|
-
* ## Categories
|
|
39
|
-
*
|
|
40
|
-
* | Category | Types | Purpose |
|
|
41
|
-
* |--------------|---------------------------------------|--------------------------------|
|
|
42
|
-
* | Actionable | `ask`, `assign`, `steer`, `review` | Require a substantive response |
|
|
43
|
-
* | Informational| `note`, `btw`, `result`, `status` | Consume for context, no action |
|
|
44
|
-
* | Routing | `broadcast` | Multi-recipient envelope |
|
|
45
|
-
* | Control | `control` | Out-of-band signal (no render) |
|
|
46
|
-
*
|
|
47
|
-
* ## Per-type contract
|
|
48
|
-
*
|
|
49
|
-
* ### Actionable types
|
|
50
|
-
*
|
|
51
|
-
* | Type | When to send | Recipient must |
|
|
52
|
-
* |----------|-----------------------------------------------------|----------------------------------------------------|
|
|
53
|
-
* | `ask` | Blocking question — you need an answer to proceed | Answer as soon as possible; the sender is waiting. |
|
|
54
|
-
* | `assign` | Delegating a task | Accept or decline; act on it when current op allows. |
|
|
55
|
-
* | `steer` | Mid-task direction change — the recipient is | Pause current approach, adjust per instruction, |
|
|
56
|
-
* | | already working on something and you need them | then resume. Rendered first in the mailbox block. |
|
|
57
|
-
* | | to change course NOW | |
|
|
58
|
-
* | `review` | Requesting a code/doc/PR review (passive) | Inspect when convenient; no immediate reply needed.|
|
|
59
|
-
*
|
|
60
|
-
* ### Informational types
|
|
61
|
-
*
|
|
62
|
-
* | Type | When to send | Recipient must |
|
|
63
|
-
* |----------|-----------------------------------------------------|----------------------------------------------------|
|
|
64
|
-
* | `note` | General-purpose FYI — a message that isn't any | Read for context; no reply needed. The untyped |
|
|
65
|
-
* | | of the more specific types | default for directed messages. |
|
|
66
|
-
* | `btw` | Low-priority aside — "by the way" | Absorb the information and stay on current task; |
|
|
67
|
-
* | | | no reply needed. Injected via BTW block (separate |
|
|
68
|
-
* | | | from the main mailbox fold) to minimise disruption.|
|
|
69
|
-
* | `result` | Subagent/task completion notice — share the | Factor into next decision; treat as evidence, not |
|
|
70
|
-
* | | outcome of finished work | a new task. |
|
|
71
|
-
* | `status` | Agent or system status update (heartbeat, spawn, | Use to avoid redundant work; never act on it as |
|
|
72
|
-
* | | task progress, error). Machine-generated. | a task or question. |
|
|
73
|
-
* | `broadcast` | Multi-recipient envelope — the same message for | Read if addressed to you (direct, alias, session, |
|
|
74
|
-
* | | every agent on the project. Auto-selected when | or `*`). The `*` recipient means "everyone". |
|
|
75
|
-
* | | `to` is `"*"` or `"@session"` in `mail_send`. | |
|
|
76
|
-
*
|
|
77
|
-
* ### Control type
|
|
78
|
-
*
|
|
79
|
-
* | Type | When to send | Recipient must |
|
|
80
|
-
* |----------|-----------------------------------------------------|----------------------------------------------------|
|
|
81
|
-
* | `control`| Out-of-band signal (interrupt, halt, redirect). | NEVER folded into conversation content. The agent |
|
|
82
|
-
* | | Machine-generated by the runtime, not by agents. | loop intercepts it separately. `control:interrupt` |
|
|
83
|
-
* | | | causes a cooperative halt at the next iteration |
|
|
84
|
-
* | | | boundary. |
|
|
85
|
-
*
|
|
86
|
-
* ───── Dispatch behavior (runtime contract) ──────────────────────────────
|
|
87
|
-
*
|
|
88
|
-
* The mailbox system enforces these dispatch rules:
|
|
89
|
-
*
|
|
90
|
-
* 1. **Send-side**: `mail_send` auto-defaults the type: `broadcast` when
|
|
91
|
-
* `to` is `"*"` or `"@session:..."`, otherwise `note`.
|
|
92
|
-
* 2. **Send-side validation**: `assign` always requires a specific `to`
|
|
93
|
-
* (not `"*"`). `control` is reserved for runtime use — agents passing it
|
|
94
|
-
* via the tool surface will be rejected.
|
|
95
|
-
* 3. **Render-order guarantee**: `steer` messages are ALWAYS rendered first
|
|
96
|
-
* in `buildMailboxBlock()`, before any other type, to ensure mid-task
|
|
97
|
-
* direction changes are seen before other action items.
|
|
98
|
-
* 4. **Control isolation**: `control`-type messages are filtered by
|
|
99
|
-
* `injectPendingMailboxMessages()` and NEVER enter the folded
|
|
100
|
-
* conversation block — they are out-of-band signals only.
|
|
101
|
-
* 5. **Background routing**: in `background` delivery mode, only the
|
|
102
|
-
* actionable message types (`steer`, `ask`, `assign`, `result`,
|
|
103
|
-
* `review`) are escalated; `note`, `btw`, `status`, and `broadcast`
|
|
104
|
-
* are suppressed to minimise disruption during tool work.
|
|
105
|
-
* 6. **Awareness polling**: `btw` messages intercepted by background
|
|
106
|
-
* polling are queued via `setBtwNote()` for injection at a safe loop
|
|
107
|
-
* boundary, not folded inline.
|
|
108
|
-
* 7. **Agent registry**: `getAgentStatuses()` reads the dedicated `agents`
|
|
109
|
-
* table, not mailbox message content. That table is populated by
|
|
110
|
-
* `registerAgent` / `heartbeat` — never by `status`-type messages, which
|
|
111
|
-
* are ordinary mail and carry no presence meaning. There is no fallback
|
|
112
|
-
* that derives presence from message content: the registry is either the
|
|
113
|
-
* owner's table or nothing. (It was `_mailbox.registry.json` before the
|
|
114
|
-
* SQLite cutover; both that file and the derive-from-messages fallback are
|
|
115
|
-
* gone.)
|
|
116
|
-
* 8. **Request-scoped context**: delivered raw mailbox blocks are removed
|
|
117
|
-
* after one successful provider evaluation. Durable assistant/tool/task
|
|
118
|
-
* consequences remain; routine mail does not occupy later requests.
|
|
119
|
-
*
|
|
120
|
-
* When a type is missing from any dispatch table, the fallback is:
|
|
121
|
-
* - Render with `📨 <TYPE>` label (generic emoji prefix)
|
|
122
|
-
* - Route inline (not background)
|
|
123
|
-
* - No special instruction added
|
|
124
|
-
*/
|
|
125
|
-
/**
|
|
126
|
-
* Which class of agent may consume a mailbox message.
|
|
127
|
-
*
|
|
128
|
-
* `leaders` is a delivery boundary, not merely a UI hint: agent-loop and
|
|
129
|
-
* inbox readers must exclude these messages for subagents. The optional
|
|
130
|
-
* persisted field keeps older JSONL records backwards-compatible (`all`).
|
|
131
|
-
*/
|
|
132
|
-
export type MailboxAudience = 'all' | 'leaders';
|
|
133
|
-
/** Return the stable base portion of a session-qualified mailbox identity. */
|
|
134
|
-
export declare function mailboxIdentityBase(agentId: string): string;
|
|
135
|
-
/** Whether a mailbox identity belongs to the session's main/leader agent. */
|
|
136
|
-
export declare function isMailboxLeader(agentId: string, role?: string): boolean;
|
|
137
|
-
/**
|
|
138
|
-
* Whether a sender identity belongs to a named agent family.
|
|
139
|
-
*
|
|
140
|
-
* Matches the family id exactly, or as the `<family>-<suffix>` prefix that a
|
|
141
|
-
* spawned worker carries. Both forms occur in practice for the same logical
|
|
142
|
-
* sender: a pipeline agent may post under its plain id (`dep-watcher`, which
|
|
143
|
-
* `makeDependencyWatcherConfig` sends as), or a subagent may post under the
|
|
144
|
-
* name it was spawned with — `host-subagent-factory` sets `ctx.agentId` from
|
|
145
|
-
* the spawn name, so the tech-stack worker spawned as
|
|
146
|
-
* `tech-stack-package.json` writes mail from `tech-stack-package.json@<tag>`.
|
|
147
|
-
* A consumer gating on the plain family id with `===` would silently reject
|
|
148
|
-
* its own pipeline.
|
|
149
|
-
*
|
|
150
|
-
* Same shape as the existing `chimera` / `chimera-*` check in
|
|
151
|
-
* `applyMailboxSendPolicy` and `host-subagent-factory`.
|
|
152
|
-
*
|
|
153
|
-
* Session/process qualifiers are stripped first, so `<family>@<tag>` and
|
|
154
|
-
* `<family>#<pid>` match too.
|
|
155
|
-
*/
|
|
156
|
-
export declare function isMailboxSenderInFamily(senderId: string, family: string): boolean;
|
|
157
|
-
/** Whether a message may be consumed by the supplied agent identity. */
|
|
158
|
-
export declare function isMailboxMessageVisibleTo(message: Pick<MailboxMessage, 'audience'>, agentId: string, role?: string): boolean;
|
|
159
|
-
/**
|
|
160
|
-
* Shape of the optional secondary lookup the leader filter performs when a
|
|
161
|
-
* message arrives without an affinity token (legacy sender / older build).
|
|
162
|
-
*
|
|
163
|
-
* `resolveChimeraReportSessionId(reportId)` returns the persisted
|
|
164
|
-
* `ReviewReport.sessionId` for that report id, or `undefined` when the
|
|
165
|
-
* report is unknown. May be sync or async — the filter awaits the result.
|
|
166
|
-
*/
|
|
167
|
-
export interface MailboxSessionAffinityContext {
|
|
168
|
-
/**
|
|
169
|
-
* Look up the originating session id of a chimera report by its report id.
|
|
170
|
-
* Return `undefined` for unknown reports. Sync or async.
|
|
171
|
-
*/
|
|
172
|
-
resolveChimeraReportSessionId?: ((reportId: string) => string | undefined | Promise<string | undefined>) | undefined;
|
|
173
|
-
/**
|
|
174
|
-
* Legacy / one-shot opt-in. The flag has TWO consultation points inside
|
|
175
|
-
* {@link acceptMailboxMessageForSession}:
|
|
176
|
-
*
|
|
177
|
-
* 1. When the recipient does not pass a `currentSessionId` (rule 2),
|
|
178
|
-
* a token-bearing message is accepted iff this is `true`.
|
|
179
|
-
* 2. When a token-bearing message lacks a resolvable `sessionId` AND
|
|
180
|
-
* the persisted-report resolver returns no match (rule 5), the
|
|
181
|
-
* message is accepted iff this is `true`.
|
|
182
|
-
*
|
|
183
|
-
* Token-LESS messages are NOT gated by this flag — they are accepted
|
|
184
|
-
* unconditionally by rule 1 as the discriminator for legitimate
|
|
185
|
-
* subagent `result` / `review` traffic that does not stamp an affinity
|
|
186
|
-
* token (task-auctioneer, cascade handlers, legacy senders).
|
|
187
|
-
*
|
|
188
|
-
* This flag does NOT override an explicit mismatch: a message that
|
|
189
|
-
* carries `sessionAffinity.sessionId !== currentSessionId` is dropped
|
|
190
|
-
* regardless of this flag, because the sender explicitly claimed a
|
|
191
|
-
* different session — honoring it would re-open the leak.
|
|
192
|
-
*
|
|
193
|
-
* Default `false`.
|
|
194
|
-
*/
|
|
195
|
-
allowUnscoped?: boolean | undefined;
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* Decide whether a mailbox message belongs to the recipient's current session
|
|
199
|
-
* and should therefore be delivered to the leader's inbox.
|
|
200
|
-
*
|
|
201
|
-
* The actual code path is:
|
|
202
|
-
*
|
|
203
|
-
* 1. {@link isAffectedBySessionAffinity} check. If the message has no
|
|
204
|
-
* affinity token, the filter does NOT apply and the message is accepted.
|
|
205
|
-
* This is the **discriminator** that protects legitimate subagent
|
|
206
|
-
* `result` / `review` traffic (task-auctioneer, cascade handlers) from
|
|
207
|
-
* collateral drops — they do not stamp an affinity token, so they fall
|
|
208
|
-
* through here. When a token is present, every token is enforced regardless
|
|
209
|
-
* of its optional `kind`; malformed or unrecognized kinds must not bypass
|
|
210
|
-
* a mismatched `sessionAffinity.sessionId`.
|
|
211
|
-
* 2. No-session-id branch. If the recipient did not pass a `currentSessionId`,
|
|
212
|
-
* accept only when `ctx.allowUnscoped === true`. Default: **fail-closed**
|
|
213
|
-
* (drop) — the safe behavior, not a silent fail-open.
|
|
214
|
-
* 3. Explicit `sessionAffinity.sessionId` match. If the sender stamped a
|
|
215
|
-
* session id and it does not match the recipient's current session id,
|
|
216
|
-
* drop immediately. The sender claimed a different session; honoring it
|
|
217
|
-
* would re-open the cross-session leak. This drop happens even when
|
|
218
|
-
* `allowUnscoped` is set — a wrong session is misconfiguration, not a
|
|
219
|
-
* legacy case.
|
|
220
|
-
* 4. Persisted-report fallback. If the token lacks a `sessionId` but carries
|
|
221
|
-
* a `reportId`, await `ctx.resolveChimeraReportSessionId(reportId)` and
|
|
222
|
-
* accept if the persisted `ReviewReport.sessionId` matches. Accepts
|
|
223
|
-
* sync or async resolvers.
|
|
224
|
-
* 5. `allowUnscoped` opt-in. If the previous steps did not accept and
|
|
225
|
-
* `ctx.allowUnscoped === true`, accept (legacy / one-shot tool
|
|
226
|
-
* compatibility).
|
|
227
|
-
* 6. Otherwise drop (`false`).
|
|
228
|
-
*
|
|
229
|
-
* PR #314 guard contract: presence checks intentionally use strict
|
|
230
|
-
* `!== undefined` comparisons for both the affinity token and its optional
|
|
231
|
-
* fields. Do not simplify them to nullish checks: malformed persisted `null`
|
|
232
|
-
* values must remain on the token-bearing path and fail closed in the shape
|
|
233
|
-
* guard rather than being treated as absent.
|
|
234
|
-
*
|
|
235
|
-
* Trust note: the filter accepts the sender-asserted `sessionAffinity.sessionId`
|
|
236
|
-
* without store cross-check (rule 3). The persisted-report fallback (rule 4)
|
|
237
|
-
* is the only server-side check. A sender that fabricates both an affinity
|
|
238
|
-
* token and a persisted report could impersonate another session — guard
|
|
239
|
-
* chimera's send path so only the actual originating session can stamp the
|
|
240
|
-
* token, and do not relax rule 3.
|
|
241
|
-
*
|
|
242
|
-
* The helper is side-effect-free except for awaiting the optional resolver.
|
|
243
|
-
* It lives next to {@link isMailboxMessageVisibleTo} so mailbox consumers
|
|
244
|
-
* can compose both filters without taking a dependency on the persistence
|
|
245
|
-
* layer.
|
|
246
|
-
*/
|
|
247
|
-
export declare function acceptMailboxMessageForSession(message: Pick<MailboxMessage, 'type' | 'sessionAffinity'>, currentSessionId: string | undefined, ctx?: MailboxSessionAffinityContext): Promise<boolean>;
|
|
248
|
-
/**
|
|
249
|
-
* Synchronous wrapper for callers that cannot await the resolver
|
|
250
|
-
* (e.g. legacy event handlers). If `ctx.resolveChimeraReportSessionId` is
|
|
251
|
-
* async, it is called without awaiting and the result is ignored — the
|
|
252
|
-
* rule degrades to "match affinity.sessionId, otherwise drop unless
|
|
253
|
-
* allowUnscoped".
|
|
254
|
-
*
|
|
255
|
-
* Prefer {@link acceptMailboxMessageForSession} whenever the caller can
|
|
256
|
-
* await.
|
|
257
|
-
*/
|
|
258
|
-
export declare function acceptMailboxMessageForSessionSync(message: Pick<MailboxMessage, 'type' | 'sessionAffinity'>, currentSessionId: string | undefined, ctx?: MailboxSessionAffinityContext): boolean;
|
|
259
|
-
/** Category + expectsReply are provided by MAILBOX_TYPE_PROPERTIES directly. */
|
|
260
|
-
/**
|
|
261
|
-
* Validate that a given (type, to) pair is internally consistent.
|
|
262
|
-
* Throws when the combination breaks a fundamental rule.
|
|
263
|
-
*/
|
|
264
|
-
export declare function validateSendType(type: MailboxMessageType, to: string): void;
|
|
265
|
-
/**
|
|
266
|
-
* Per-recipient read status. `readBy` maps agentId → ISO8601 timestamp of
|
|
267
|
-
* when that agent first read the message. An empty map means unread by all.
|
|
268
|
-
*/
|
|
269
|
-
export interface ReadReceipts {
|
|
270
|
-
[agentId: string]: string;
|
|
271
|
-
}
|
|
272
|
-
export interface MailboxMessage {
|
|
273
|
-
/** Unique message id (UUID). */
|
|
274
|
-
id: string;
|
|
275
|
-
/** Sender agent id. */
|
|
276
|
-
from: string;
|
|
277
|
-
/** Recipient agent id, or '*' for broadcast. */
|
|
278
|
-
to: string;
|
|
279
|
-
/** Message category. */
|
|
280
|
-
type: MailboxMessageType;
|
|
281
|
-
/** Delivery audience. Omitted legacy values mean `all`. */
|
|
282
|
-
audience?: MailboxAudience | undefined;
|
|
283
|
-
/** Short subject line — one sentence. */
|
|
284
|
-
subject: string;
|
|
285
|
-
/** Full message content. */
|
|
286
|
-
body: string;
|
|
287
|
-
/** Priority — high priority messages surface first. */
|
|
288
|
-
priority: 'low' | 'normal' | 'high';
|
|
289
|
-
/**
|
|
290
|
-
* Per-recipient read receipts. agentId → ISO8601 when they first read it.
|
|
291
|
-
* Replaces the old single `read: boolean` + `readAt` fields.
|
|
292
|
-
*/
|
|
293
|
-
readBy: ReadReceipts;
|
|
294
|
-
/** Has any recipient acted on / completed this? */
|
|
295
|
-
completed: boolean;
|
|
296
|
-
/** Who completed it (agentId). */
|
|
297
|
-
completedBy?: string | undefined;
|
|
298
|
-
/** Optional summary of what happened after handling. */
|
|
299
|
-
outcome?: string | undefined;
|
|
300
|
-
/** ISO8601 — when the message was sent. */
|
|
301
|
-
timestamp: string;
|
|
302
|
-
/** ISO8601 — when the message was marked complete. */
|
|
303
|
-
completedAt?: string | undefined;
|
|
304
|
-
/**
|
|
305
|
-
* ISO8601 — when the message was soft-deleted. When present, the
|
|
306
|
-
* default `Mailbox.query()` filter excludes the message from the
|
|
307
|
-
* normal inbox view; {@link Mailbox.restore} clears the
|
|
308
|
-
* field to undo the delete. Hard deletes (removing the line from
|
|
309
|
-
* the JSONL) are reserved for the CLI and never happen via the
|
|
310
|
-
* server route handlers.
|
|
311
|
-
*/
|
|
312
|
-
deletedAt?: string | undefined;
|
|
313
|
-
/** When the soft-delete happened, the agentId that issued it. */
|
|
314
|
-
deletedBy?: string | undefined;
|
|
315
|
-
/** If this is a reply, the id of the parent message. */
|
|
316
|
-
replyTo?: string | undefined;
|
|
317
|
-
/** For assign-type messages — task context for agent discovery. */
|
|
318
|
-
taskContext?: MailboxTaskContext | undefined;
|
|
319
|
-
/** Session id of the sender. Enables cross-session communication. */
|
|
320
|
-
senderSessionId?: string | undefined;
|
|
321
|
-
/**
|
|
322
|
-
* Session-affinity token persisted on the message. When set, the
|
|
323
|
-
* recipient's leader filter uses it to drop the message if the
|
|
324
|
-
* recipient's current session id does not match. See
|
|
325
|
-
* {@link MailboxSessionAffinity} for the contract.
|
|
326
|
-
*/
|
|
327
|
-
sessionAffinity?: MailboxSessionAffinity | undefined;
|
|
328
|
-
/**
|
|
329
|
-
* ISO8601 — when the message expires. Set at send time from `ttlMs`
|
|
330
|
-
* (default: 24h via AUTO_COMPACT_DEFAULT_TTL_MS). The auto-compaction
|
|
331
|
-
* sweep removes messages whose `expiresAt` is in the past. When
|
|
332
|
-
* undefined, the compaction sweep uses the default TTL from the
|
|
333
|
-
* caller's options.
|
|
334
|
-
*/
|
|
335
|
-
expiresAt?: string | undefined;
|
|
336
|
-
}
|
|
337
|
-
export interface MailboxTaskContext {
|
|
338
|
-
/** The role that should handle this task (e.g. "tech-stack", "audit-log"). */
|
|
339
|
-
agentRole?: string | undefined;
|
|
340
|
-
/** Human-readable agent name (e.g. "Tesla (Executor)"). */
|
|
341
|
-
agentName?: string | undefined;
|
|
342
|
-
/** Task id if already assigned via coordinator. */
|
|
343
|
-
taskId?: string | undefined;
|
|
344
|
-
/** Current task status. */
|
|
345
|
-
status?: 'pending' | 'in_progress' | 'completed' | 'failed' | undefined;
|
|
346
|
-
}
|
|
4
|
+
export { expandMailboxCapabilities, hasMailboxCapability, MAILBOX_CAPABILITY_IMPLICATIONS, type MailboxActorContext, type MailboxAuthMode, type MailboxCapability, type MailboxPrincipalKind, } from './mailbox-auth-types.js';
|
|
5
|
+
export { isActionRequiredForActor, isMailboxLeader, isMailboxMessageVisibleTo, isMailboxReceiptRecordV2, isMailboxSenderInFamily, mailboxIdentityBase, normalizeRecipient, SESSION_RECIPIENT_PREFIX, sessionRecipient, validateSendType, } from './mailbox-predicates.js';
|
|
6
|
+
export { acceptMailboxMessageForSession, acceptMailboxMessageForSessionSync, type MailboxSessionAffinityContext, } from './mailbox-session-sync.js';
|
|
7
|
+
export { type ActorMailboxMessage, type MailboxAudience, type MailboxLegacyReportSessionAffinity, type MailboxMessage, type MailboxReceiptRecordV2, type MailboxScopedSessionAffinity, type MailboxSessionAffinity, type MailboxTaskContext, type ReadReceipts, } from './mailbox-message-types.js';
|
|
347
8
|
export interface RegisteredAgent {
|
|
348
|
-
/** Unique agent id. */
|
|
349
9
|
agentId: string;
|
|
350
|
-
/** Session id this agent belongs to. */
|
|
351
10
|
sessionId: string;
|
|
352
|
-
/** Human-readable name. */
|
|
353
11
|
name: string;
|
|
354
|
-
/** Role (e.g. "leader", "tech-stack", "bug-hunter"). */
|
|
355
12
|
role?: string | undefined;
|
|
356
|
-
/** Current status. */
|
|
357
13
|
status: 'idle' | 'running' | 'streaming' | 'waiting_user' | 'error';
|
|
358
|
-
/** Current tool being executed, if any. */
|
|
359
14
|
currentTool?: string | undefined;
|
|
360
|
-
/** Current task description. */
|
|
361
15
|
currentTask?: string | undefined;
|
|
362
|
-
/** Iteration count so far. */
|
|
363
16
|
iterations: number;
|
|
364
|
-
/** Tool calls so far. */
|
|
365
17
|
toolCalls: number;
|
|
366
|
-
/** ISO8601 — registered at. */
|
|
367
18
|
registeredAt: string;
|
|
368
|
-
/** ISO8601 — last heartbeat (updated on every mailbox op). */
|
|
369
19
|
lastSeenAt: string;
|
|
370
|
-
/** Which process registered this agent (PID). */
|
|
371
20
|
pid: number;
|
|
372
|
-
/** Where the agent is running (e.g. "cli", "webui"). */
|
|
373
21
|
source?: 'cli' | 'webui' | 'mcp' | 'acp' | 'http' | undefined;
|
|
374
22
|
}
|
|
375
23
|
export interface MailboxAgentStatus {
|
|
376
|
-
/** Agent id. */
|
|
377
24
|
agentId: string;
|
|
378
|
-
/** Human-readable name. */
|
|
379
25
|
name: string;
|
|
380
|
-
/** Role. */
|
|
381
26
|
role?: string | undefined;
|
|
382
|
-
/** Session id. */
|
|
383
27
|
sessionId: string;
|
|
384
|
-
/** Current status. */
|
|
385
28
|
status: 'idle' | 'running' | 'streaming' | 'waiting_user' | 'error' | 'offline';
|
|
386
|
-
/** Current tool being executed, if any. */
|
|
387
29
|
currentTool?: string | undefined;
|
|
388
|
-
/** Current task description. */
|
|
389
30
|
currentTask?: string | undefined;
|
|
390
|
-
/** Iteration count so far. */
|
|
391
31
|
iterations: number;
|
|
392
|
-
/** Tool calls so far. */
|
|
393
32
|
toolCalls: number;
|
|
394
|
-
/** ISO8601 — last activity timestamp. */
|
|
395
33
|
lastActivityAt: string;
|
|
396
|
-
/** ISO8601 — last heartbeat. */
|
|
397
34
|
lastSeenAt: string;
|
|
398
|
-
/** Whether this agent is currently online (heartbeat within threshold). */
|
|
399
35
|
online: boolean;
|
|
400
|
-
/** Which process. */
|
|
401
36
|
pid: number;
|
|
402
|
-
/** Source. */
|
|
403
37
|
source?: 'cli' | 'webui' | 'mcp' | 'acp' | 'http' | undefined;
|
|
404
38
|
}
|
|
405
39
|
export interface MailboxQuery {
|
|
406
|
-
/**
|
|
407
|
-
* Restrict the result to these message ids.
|
|
408
|
-
*
|
|
409
|
-
* Exists so a caller that already knows which messages it cares about can
|
|
410
|
-
* ask about exactly those instead of pulling a set and scanning it. The
|
|
411
|
-
* HTTP bridge's per-actor visibility checks did the latter — answering
|
|
412
|
-
* "is this one message mine?" by materializing every message addressed to
|
|
413
|
-
* the actor, which on a busy project meant a full table read (plus the
|
|
414
|
-
* whole receipt table, plus a retention projection per row) for every
|
|
415
|
-
* single `ack`.
|
|
416
|
-
*
|
|
417
|
-
* An empty array matches nothing. Untrusted request codecs deliberately do
|
|
418
|
-
* NOT accept this field — `validateQuery` whitelists, so it stays a
|
|
419
|
-
* server-side narrowing rather than something a caller can widen.
|
|
420
|
-
*/
|
|
421
40
|
ids?: readonly string[] | undefined;
|
|
422
|
-
/** Filter by recipient agent id. */
|
|
423
41
|
to?: string | undefined;
|
|
424
|
-
/** Filter by sender agent id. */
|
|
425
42
|
from?: string | undefined;
|
|
426
|
-
/** Only messages unread by this agent. */
|
|
427
43
|
unreadBy?: string | undefined;
|
|
428
|
-
/** Trusted caller role used with `unreadBy` for audience filtering. */
|
|
429
44
|
readerRole?: string | undefined;
|
|
430
|
-
/** Only incomplete messages. */
|
|
431
45
|
incompleteOnly?: boolean | undefined;
|
|
432
|
-
/**
|
|
433
|
-
* Internal trusted-read option: retain folded per-actor receipt state so a
|
|
434
|
-
* boundary can derive an actor-safe projection. Untrusted query codecs must
|
|
435
|
-
* never accept this field from request payloads.
|
|
436
|
-
*/
|
|
437
46
|
includeReceiptState?: boolean | undefined;
|
|
438
|
-
/** Filter by message type. */
|
|
439
47
|
type?: MailboxMessageType | undefined;
|
|
440
|
-
/** Filter by priority (>= this level). */
|
|
441
48
|
minPriority?: 'low' | 'normal' | 'high' | undefined;
|
|
442
|
-
/** Maximum number of messages to return. */
|
|
443
49
|
limit?: number | undefined;
|
|
444
|
-
/** ISO8601 — only messages after this timestamp. */
|
|
445
50
|
since?: string | undefined;
|
|
446
|
-
/** Filter by the sender's session id (`MailboxMessage.senderSessionId`). */
|
|
447
51
|
sessionId?: string | undefined;
|
|
448
|
-
/**
|
|
449
|
-
* Include soft-deleted messages (where `deletedAt` is set). When
|
|
450
|
-
* `false` (the default), soft-deleted messages are filtered out so
|
|
451
|
-
* the normal inbox view stays clean. The "trash" view passes
|
|
452
|
-
* `true` to surface them.
|
|
453
|
-
*/
|
|
454
52
|
includeDeleted?: boolean | undefined;
|
|
455
|
-
/**
|
|
456
|
-
* Filter by replyTo parent message id (UUID). When set, only messages
|
|
457
|
-
* whose `replyTo` exactly matches this value are returned. An empty
|
|
458
|
-
* string matches nothing — empty strings are technically allowed by
|
|
459
|
-
* `send()` (it passes through `MailboxSendInput.replyTo` directly with
|
|
460
|
-
* no normalization), but are never produced by chimera/execution callers.
|
|
461
|
-
* The query filter is exact-match.
|
|
462
|
-
* Useful for polling the response to a specific `ask` message.
|
|
463
|
-
*/
|
|
464
53
|
replyTo?: string | undefined;
|
|
465
54
|
}
|
|
466
|
-
/** Canonical prefix for mail addressed to every agent in one session. */
|
|
467
|
-
export declare const SESSION_RECIPIENT_PREFIX = "@session:";
|
|
468
|
-
/** Build the canonical recipient address for a session-scoped broadcast. */
|
|
469
|
-
export declare function sessionRecipient(sessionId: string): string;
|
|
470
|
-
/**
|
|
471
|
-
* Normalize a recipient address.
|
|
472
|
-
*
|
|
473
|
-
* - `"all"` (any casing) is canonicalized to `'*'`.
|
|
474
|
-
* - `"@session"` (any casing) is canonicalized to
|
|
475
|
-
* `"@session:<sessionId>"`; callers must provide the sender's session id.
|
|
476
|
-
* - Already-canonical `"@session:<sessionId>"` addresses are preserved.
|
|
477
|
-
*/
|
|
478
|
-
export declare function normalizeRecipient(to: string, sessionId?: string): string;
|
|
479
55
|
export interface MailboxSendInput {
|
|
480
|
-
/** Sender agent id. */
|
|
481
56
|
from: string;
|
|
482
|
-
/** Recipient agent id, '*' / "all" for project broadcast, or "@session" for the sender's session. */
|
|
483
57
|
to: string;
|
|
484
|
-
/** Message category. */
|
|
485
58
|
type: MailboxMessageType;
|
|
486
|
-
/** Restrict consumption to main/leader agents. Default: `all`. */
|
|
487
59
|
audience?: MailboxAudience | undefined;
|
|
488
|
-
/** Short subject line. */
|
|
489
60
|
subject: string;
|
|
490
|
-
/** Full message content. */
|
|
491
61
|
body: string;
|
|
492
|
-
/** Priority. Default: 'normal'. */
|
|
493
62
|
priority?: 'low' | 'normal' | 'high' | undefined;
|
|
494
|
-
/** If replying, the id of the parent message. */
|
|
495
63
|
replyTo?: string | undefined;
|
|
496
|
-
/** Task context for assign-type messages. */
|
|
497
64
|
taskContext?: MailboxTaskContext | undefined;
|
|
498
|
-
/** Sender session id. Required when `to` is the `"@session"` alias. */
|
|
499
65
|
senderSessionId?: string | undefined;
|
|
500
|
-
/**
|
|
501
|
-
* Session-affinity token. When set, the recipient's mailbox filter uses it
|
|
502
|
-
* to drop the message if the recipient's current session id does not match.
|
|
503
|
-
*
|
|
504
|
-
* Why two fields instead of one: a chimera report is generated by a reviewer
|
|
505
|
-
* subagent that runs inside the originating session (so `senderSessionId`
|
|
506
|
-
* is correct), but a mailbox envelope may also be relayed by an outer
|
|
507
|
-
* pipeline (auto-review cascade, broadcast wrapper) where the recipient
|
|
508
|
-
* needs to know which session the report *belongs to*, not who *physically
|
|
509
|
-
* called send()*. `sessionId` carries the originating session;
|
|
510
|
-
* `reportId` carries the chimera report id so the leader's filter
|
|
511
|
-
* can also look the report up in the persisted review-report store.
|
|
512
|
-
*
|
|
513
|
-
* A session-affinity token is **required** for any `chimera.*` review
|
|
514
|
-
* delivery wrapper — this is the trust boundary that prevents a leader
|
|
515
|
-
* from acting on reports emitted by another session, even when those
|
|
516
|
-
* reports land in its mailbox.
|
|
517
|
-
*/
|
|
518
66
|
sessionAffinity?: MailboxSessionAffinity | undefined;
|
|
519
|
-
/**
|
|
520
|
-
* Time-to-live in milliseconds. When set, the message's `expiresAt` is
|
|
521
|
-
* computed as `now + ttlMs` at send time. The auto-compaction sweep
|
|
522
|
-
* removes expired messages. Default: none (use compaction sweep default).
|
|
523
|
-
*/
|
|
524
67
|
ttlMs?: number | undefined;
|
|
525
68
|
}
|
|
526
|
-
/**
|
|
527
|
-
* Session-affinity token carried on a mailbox message.
|
|
528
|
-
*
|
|
529
|
-
* The token is the *only* signal a recipient's leader filter uses to decide
|
|
530
|
-
* whether a chimera report belongs to the recipient's own session. Without
|
|
531
|
-
* it, any leader that polls the project-wide mailbox would see — and feel
|
|
532
|
-
* compelled to act on — chimera reports emitted by every other session in
|
|
533
|
-
* the project.
|
|
534
|
-
*/
|
|
535
|
-
export type MailboxSessionAffinity = MailboxScopedSessionAffinity | MailboxLegacyReportSessionAffinity;
|
|
536
|
-
export interface MailboxScopedSessionAffinity {
|
|
537
|
-
/**
|
|
538
|
-
* The originating session id. The recipient's leader filter compares this
|
|
539
|
-
* against its own current session id and drops the message on mismatch.
|
|
540
|
-
*/
|
|
541
|
-
sessionId: string;
|
|
542
|
-
/**
|
|
543
|
-
* Originating chimera report id (UUID). Used as a secondary lookup only
|
|
544
|
-
* when the message is a legacy report token without `sessionId`.
|
|
545
|
-
*/
|
|
546
|
-
reportId?: string | undefined;
|
|
547
|
-
/** Free-form tag for filtering / metrics, e.g. `'chimera.review'`. */
|
|
548
|
-
kind?: string | undefined;
|
|
549
|
-
}
|
|
550
|
-
export interface MailboxLegacyReportSessionAffinity {
|
|
551
|
-
/**
|
|
552
|
-
* Legacy report-only tokens deliberately omit `sessionId`; any present
|
|
553
|
-
* session id is authoritative and must be checked before report lookup.
|
|
554
|
-
*/
|
|
555
|
-
sessionId?: undefined;
|
|
556
|
-
/** Originating chimera report id (UUID) used for persisted-session lookup. */
|
|
557
|
-
reportId: string;
|
|
558
|
-
/** Free-form tag for filtering / metrics, e.g. `'chimera.review'`. */
|
|
559
|
-
kind?: string | undefined;
|
|
560
|
-
}
|
|
561
|
-
/**
|
|
562
|
-
* Append-only ack record stored in the JSONL alongside messages.
|
|
563
|
-
*
|
|
564
|
-
* Instead of rewriting the entire mailbox file to mark a message as read or
|
|
565
|
-
* completed, we append a small ack record. At read time, ack records are
|
|
566
|
-
* folded into their target messages. The `__ack` discriminator distinguishes
|
|
567
|
-
* ack records from regular messages.
|
|
568
|
-
*
|
|
569
|
-
* Compaction (autoCompact / purgeStale) folds these into the messages and
|
|
570
|
-
* removes the ack lines from the file, keeping the file bounded.
|
|
571
|
-
*/
|
|
572
69
|
export interface AckRecord {
|
|
573
|
-
/** Discriminator — always `true` to distinguish from MailboxMessage. */
|
|
574
70
|
__ack: true;
|
|
575
|
-
/** The message this ack applies to. */
|
|
576
71
|
messageId: string;
|
|
577
|
-
/** Agent acknowledging the message. */
|
|
578
72
|
readerId: string;
|
|
579
|
-
/** ISO8601 timestamp of the ack. */
|
|
580
73
|
timestamp: string;
|
|
581
|
-
/** Was the message read? */
|
|
582
74
|
read: boolean;
|
|
583
|
-
/** Was the message marked completed? */
|
|
584
75
|
completed?: boolean | undefined;
|
|
585
|
-
/** Who completed it (when completed === true). */
|
|
586
76
|
completedBy?: string | undefined;
|
|
587
|
-
/** Optional outcome summary. */
|
|
588
77
|
outcome?: string | undefined;
|
|
589
|
-
/**
|
|
590
|
-
* Soft-delete or restore the target message.
|
|
591
|
-
* - `true`: set `deletedAt`/`deletedBy` on the message
|
|
592
|
-
* - `false`: clear `deletedAt`/`deletedBy` on the message
|
|
593
|
-
* - `undefined`: not a delete/restore operation (backward-compat default)
|
|
594
|
-
*
|
|
595
|
-
* When `deleted` is `true`, `deletedBy` records who performed the delete.
|
|
596
|
-
*/
|
|
597
78
|
deleted?: boolean | undefined;
|
|
598
|
-
/** Who deleted the message (set when `deleted === true`). */
|
|
599
79
|
deletedBy?: string | undefined;
|
|
600
80
|
}
|
|
601
81
|
export interface MailboxAckInput {
|
|
602
|
-
/** Message id to acknowledge. */
|
|
603
82
|
messageId: string;
|
|
604
|
-
/** Agent id of who is reading/acking. */
|
|
605
83
|
readerId: string;
|
|
606
|
-
/** Mark as read by this agent? Defaults to true if not specified. */
|
|
607
84
|
read?: boolean | undefined;
|
|
608
|
-
/** Mark as completed? */
|
|
609
85
|
completed?: boolean | undefined;
|
|
610
|
-
/** Optional outcome summary. */
|
|
611
86
|
outcome?: string | undefined;
|
|
612
87
|
}
|
|
613
|
-
/**
|
|
614
|
-
* Batch acknowledgment input — applies a batch of acks under a single file
|
|
615
|
-
* lock + single file rewrite. Each entry has the same shape as
|
|
616
|
-
* {@link MailboxAckInput} minus the per-batch defaults documented on
|
|
617
|
-
* `ackMany`. Use this when an agent is acking several fresh messages at
|
|
618
|
-
* once (the common case in the mailbox loop) — it collapses N full-file
|
|
619
|
-
* rewrites into one.
|
|
620
|
-
*/
|
|
621
88
|
export interface MailboxAckBatchInput {
|
|
622
|
-
/** Ack entries to apply. */
|
|
623
89
|
acks: MailboxAckInput[];
|
|
624
90
|
}
|
|
625
91
|
export interface AgentRegistrationInput {
|
|
@@ -632,35 +98,21 @@ export interface AgentRegistrationInput {
|
|
|
632
98
|
}
|
|
633
99
|
export type ClientSource = 'repl' | 'tui' | 'webui' | 'http';
|
|
634
100
|
export interface RegisteredClient {
|
|
635
|
-
/** Unique client id. */
|
|
636
101
|
clientId: string;
|
|
637
|
-
/** Session/project context id. */
|
|
638
102
|
sessionId: string;
|
|
639
|
-
/** Human-readable name (e.g. "TUI [main]", "WebUI [chrome]"). */
|
|
640
103
|
name: string;
|
|
641
|
-
/** Client type. */
|
|
642
104
|
source: ClientSource;
|
|
643
|
-
/** ISO8601 — registered at. */
|
|
644
105
|
registeredAt: string;
|
|
645
|
-
/** ISO8601 — last heartbeat. */
|
|
646
106
|
lastSeenAt: string;
|
|
647
|
-
/** Which process. */
|
|
648
107
|
pid: number;
|
|
649
108
|
}
|
|
650
109
|
export interface ClientStatus {
|
|
651
|
-
/** Client id. */
|
|
652
110
|
clientId: string;
|
|
653
|
-
/** Human-readable name. */
|
|
654
111
|
name: string;
|
|
655
|
-
/** Client type. */
|
|
656
112
|
source: ClientSource;
|
|
657
|
-
/** Session id. */
|
|
658
113
|
sessionId: string;
|
|
659
|
-
/** ISO8601 — last activity timestamp. */
|
|
660
114
|
lastSeenAt: string;
|
|
661
|
-
/** Whether this client is currently online (heartbeat within threshold). */
|
|
662
115
|
online: boolean;
|
|
663
|
-
/** Which process. */
|
|
664
116
|
pid: number;
|
|
665
117
|
}
|
|
666
118
|
export interface ClientRegistrationInput {
|
|
@@ -672,7 +124,6 @@ export interface ClientRegistrationInput {
|
|
|
672
124
|
}
|
|
673
125
|
export interface ClientHeartbeatInput {
|
|
674
126
|
clientId: string;
|
|
675
|
-
/** Active session id for this client. When present, updates the registry entry. */
|
|
676
127
|
sessionId?: string | undefined;
|
|
677
128
|
}
|
|
678
129
|
export interface AgentHeartbeatInput {
|
|
@@ -684,302 +135,64 @@ export interface AgentHeartbeatInput {
|
|
|
684
135
|
toolCalls?: number | undefined;
|
|
685
136
|
}
|
|
686
137
|
export interface PurgeOptions {
|
|
687
|
-
/**
|
|
688
|
-
* Purge completed messages older than this many milliseconds.
|
|
689
|
-
* Default: 1 day (86_400_000 ms)
|
|
690
|
-
*/
|
|
691
138
|
completedMaxAgeMs?: number | undefined;
|
|
692
|
-
/**
|
|
693
|
-
* Purge incomplete messages older than this many milliseconds.
|
|
694
|
-
* Default: 7 days (604_800_000 ms)
|
|
695
|
-
*/
|
|
696
139
|
incompleteMaxAgeMs?: number | undefined;
|
|
697
140
|
}
|
|
698
141
|
export interface PurgeResult {
|
|
699
|
-
/** Messages removed because they were completed and too old. */
|
|
700
142
|
completedPurged: number;
|
|
701
|
-
/** Messages removed because they were incomplete and too old. */
|
|
702
143
|
incompletePurged: number;
|
|
703
|
-
/** Total messages removed. */
|
|
704
144
|
totalPurged: number;
|
|
705
|
-
/** Messages remaining in the mailbox after purge. */
|
|
706
145
|
remaining: number;
|
|
707
146
|
}
|
|
708
147
|
export interface AutoCompactOptions {
|
|
709
|
-
/**
|
|
710
|
-
* Remove messages read by ALL currently-online agents that are older
|
|
711
|
-
* than this many milliseconds since the last read receipt was stamped.
|
|
712
|
-
* Default: 10 minutes (AUTO_COMPACT_READ_MAX_AGE_MS).
|
|
713
|
-
*/
|
|
714
148
|
readMaxAgeMs?: number | undefined;
|
|
715
|
-
/**
|
|
716
|
-
* Default TTL for messages without an explicit `expiresAt`. Messages
|
|
717
|
-
* whose `timestamp` is older than `now - defaultTtlMs` are removed.
|
|
718
|
-
* Default: 24 hours (AUTO_COMPACT_DEFAULT_TTL_MS).
|
|
719
|
-
*/
|
|
720
149
|
defaultTtlMs?: number | undefined;
|
|
721
|
-
/**
|
|
722
|
-
* Per-message-type TTL overrides, consulted before `defaultTtlMs` for
|
|
723
|
-
* messages with no explicit `expiresAt`. Keyed by `MailboxMessageType`.
|
|
724
|
-
* Default: {@link AUTO_COMPACT_TYPE_TTL_MS} (transient `status` chatter
|
|
725
|
-
* expires in 30 minutes instead of 24 hours).
|
|
726
|
-
*/
|
|
727
150
|
typeTtlMs?: Readonly<Record<string, number>> | undefined;
|
|
728
|
-
/**
|
|
729
|
-
* Also run `purgeStale` logic in the same pass — purge completed
|
|
730
|
-
* messages older than this many ms. Default: 1 day.
|
|
731
|
-
*/
|
|
732
151
|
completedMaxAgeMs?: number | undefined;
|
|
733
|
-
/**
|
|
734
|
-
* Also run `purgeStale` logic in the same pass — purge incomplete
|
|
735
|
-
* messages older than this many ms. Default: 7 days.
|
|
736
|
-
*/
|
|
737
152
|
incompleteMaxAgeMs?: number | undefined;
|
|
738
|
-
/**
|
|
739
|
-
* Interval for the background auto-compact timer.
|
|
740
|
-
* Default: 5 minutes (AUTO_COMPACT_INTERVAL_MS).
|
|
741
|
-
*/
|
|
742
153
|
intervalMs?: number | undefined;
|
|
743
|
-
/**
|
|
744
|
-
* Also run `purgeStale` logic in the same pass (completed > 1 day,
|
|
745
|
-
* incomplete > 7 days). Default: true.
|
|
746
|
-
*/
|
|
747
154
|
includePurgeStale?: boolean | undefined;
|
|
748
155
|
}
|
|
749
156
|
export interface AutoCompactResult {
|
|
750
|
-
/** Messages removed because they were read by all online agents. */
|
|
751
157
|
readByAllRemoved: number;
|
|
752
|
-
/** Messages removed because their TTL expired (explicit or default). */
|
|
753
158
|
expiredRemoved: number;
|
|
754
|
-
/** Messages removed by the purgeStale pass (if enabled). */
|
|
755
159
|
stalePurged: number;
|
|
756
|
-
/** Total messages removed. */
|
|
757
160
|
totalRemoved: number;
|
|
758
|
-
/** Messages remaining in the mailbox after compaction. */
|
|
759
161
|
remaining: number;
|
|
760
162
|
}
|
|
761
163
|
export interface Mailbox {
|
|
762
|
-
/** Send a message. Returns the created message. */
|
|
763
164
|
send(input: MailboxSendInput): Promise<MailboxMessage>;
|
|
764
|
-
/** Query messages matching criteria. */
|
|
765
165
|
query(query: MailboxQuery): Promise<MailboxMessage[]>;
|
|
766
|
-
/** Acknowledge a message (read/complete). Returns updated message. */
|
|
767
166
|
ack(input: MailboxAckInput): Promise<MailboxMessage | null>;
|
|
768
|
-
/**
|
|
769
|
-
* Acknowledge many messages in one shot. Acquires the file lock once and
|
|
770
|
-
* rewrites the message file once, regardless of how many acks are in the
|
|
771
|
-
* batch. Returns the messages that were actually updated (messages whose
|
|
772
|
-
* ids are not in the file are skipped silently).
|
|
773
|
-
*
|
|
774
|
-
* This is the preferred path when an agent has multiple fresh messages
|
|
775
|
-
* to receipt at once — the per-message {@link ack} path does a full
|
|
776
|
-
* read-modify-rewrite of the mailbox file for every call.
|
|
777
|
-
*/
|
|
778
167
|
ackMany(input: MailboxAckBatchInput): Promise<MailboxMessage[]>;
|
|
779
|
-
/**
|
|
780
|
-
* Soft-delete a message. Sets `deletedAt` to the current timestamp
|
|
781
|
-
* and records the acting agent in `deletedBy`. Reversible via
|
|
782
|
-
* {@link restore}. The default `query()` filter hides the message
|
|
783
|
-
* once `deletedAt` is set; pass `includeDeleted: true` to see the
|
|
784
|
-
* trash.
|
|
785
|
-
*/
|
|
786
168
|
softDelete(mailId: string, by: string): Promise<MailboxMessage | null>;
|
|
787
|
-
/**
|
|
788
|
-
* Undo a {@link softDelete}. Clears `deletedAt` and `deletedBy` on
|
|
789
|
-
* the message. No-op (returns the message as-is) if the message is
|
|
790
|
-
* not soft-deleted.
|
|
791
|
-
*/
|
|
792
169
|
restore(mailId: string): Promise<MailboxMessage | null>;
|
|
793
|
-
/** Get a snapshot of online/offline agents and their current tasks. */
|
|
794
170
|
getAgentStatuses(): Promise<MailboxAgentStatus[]>;
|
|
795
|
-
/**
|
|
796
|
-
* Get only online agents (heartbeat within 60s).
|
|
797
|
-
* Useful for "who can I talk to right now?" queries.
|
|
798
|
-
*/
|
|
799
171
|
getOnlineAgents(): Promise<MailboxAgentStatus[]>;
|
|
800
|
-
/**
|
|
801
|
-
* Register an agent. Called once per agent on first mailbox use.
|
|
802
|
-
* Subsequent calls are idempotent — they update lastSeenAt.
|
|
803
|
-
*/
|
|
804
172
|
registerAgent(input: AgentRegistrationInput): Promise<void>;
|
|
805
|
-
/** Remove an agent from the registry entirely. Called on session shutdown. */
|
|
806
173
|
deregisterAgent(agentId: string): Promise<void>;
|
|
807
|
-
/**
|
|
808
|
-
* Update agent heartbeat and optional status fields.
|
|
809
|
-
* Called periodically (every tool call / iteration).
|
|
810
|
-
*/
|
|
811
174
|
heartbeat(input: AgentHeartbeatInput): Promise<void>;
|
|
812
|
-
/**
|
|
813
|
-
* Count unread messages for a specific agent.
|
|
814
|
-
* Used for "new mail" notifications without pulling full message bodies.
|
|
815
|
-
*/
|
|
816
175
|
unreadCount(forAgentId: string, sessionId?: string): Promise<number>;
|
|
817
|
-
/** Close and flush any pending writes. */
|
|
818
176
|
close(): Promise<void>;
|
|
819
|
-
/**
|
|
820
|
-
* Delete all messages from the mailbox file.
|
|
821
|
-
* Agents and read receipts are preserved; only messages are cleared.
|
|
822
|
-
*/
|
|
823
177
|
clearAll(): Promise<void>;
|
|
824
|
-
/**
|
|
825
|
-
* Purge orphaned and stale messages from the mailbox.
|
|
826
|
-
*
|
|
827
|
-
* Stale messages are:
|
|
828
|
-
* - Completed messages older than `completedMaxAgeMs` (default: 1 day)
|
|
829
|
-
* - Incomplete messages older than `incompleteMaxAgeMs` (default: 7 days)
|
|
830
|
-
*
|
|
831
|
-
* This does NOT touch agent registrations or client registry.
|
|
832
|
-
*/
|
|
833
178
|
purgeStale(opts?: PurgeOptions): Promise<PurgeResult>;
|
|
834
|
-
/**
|
|
835
|
-
* Auto-compact: remove messages that are no longer needed.
|
|
836
|
-
*
|
|
837
|
-
* Two cleanup passes run in a single file rewrite:
|
|
838
|
-
* 1. **Read-by-all**: Messages read by every currently-online agent,
|
|
839
|
-
* older than `readMaxAgeMs` (default 10 min).
|
|
840
|
-
* 2. **Expired**: Messages whose `expiresAt` is in the past, or whose
|
|
841
|
-
* `timestamp` is older than `defaultTtlMs` (default 24h) when no
|
|
842
|
-
* explicit `expiresAt` is set.
|
|
843
|
-
*
|
|
844
|
-
* Also runs `purgeStale` logic (completed > 1 day, incomplete > 7 days)
|
|
845
|
-
* in the same pass to avoid a second rewrite.
|
|
846
|
-
*/
|
|
847
179
|
autoCompact(opts?: AutoCompactOptions): Promise<AutoCompactResult>;
|
|
848
|
-
/**
|
|
849
|
-
* Start a background timer that periodically calls `autoCompact`.
|
|
850
|
-
* Returns a dispose function that stops the timer. Idempotent —
|
|
851
|
-
* calling start twice replaces the prior timer.
|
|
852
|
-
*/
|
|
853
180
|
startAutoCompactTimer(opts?: AutoCompactOptions): () => void;
|
|
854
|
-
/**
|
|
855
|
-
* Register a client (REPL/TUI/WebUI). Called once per client on startup.
|
|
856
|
-
* Subsequent calls are idempotent — they update lastSeenAt.
|
|
857
|
-
*/
|
|
858
181
|
registerClient(input: ClientRegistrationInput): Promise<void>;
|
|
859
|
-
/**
|
|
860
|
-
* Update client heartbeat. Called periodically (every 15s for clients).
|
|
861
|
-
*/
|
|
862
182
|
clientHeartbeat(input: ClientHeartbeatInput): Promise<void>;
|
|
863
|
-
/** Remove a client immediately on clean shutdown. */
|
|
864
183
|
deregisterClient(clientId: string): Promise<void>;
|
|
865
|
-
/**
|
|
866
|
-
* Get snapshot of online/offline clients and their last activity.
|
|
867
|
-
*/
|
|
868
184
|
getClientStatuses(): Promise<ClientStatus[]>;
|
|
869
|
-
/**
|
|
870
|
-
* Explicitly purge stale clients from the registry.
|
|
871
|
-
* Removes client entries whose lastSeenAt is older than CLIENT_STALE_MS.
|
|
872
|
-
* Returns the number of entries purged.
|
|
873
|
-
*/
|
|
874
185
|
purgeClients(): Promise<number>;
|
|
875
186
|
}
|
|
876
|
-
export { expandMailboxCapabilities, hasMailboxCapability, MAILBOX_CAPABILITY_IMPLICATIONS, type MailboxActorContext, type MailboxAuthMode, type MailboxCapability, type MailboxPrincipalKind, } from './mailbox-auth-types.js';
|
|
877
|
-
/**
|
|
878
|
-
* Per-recipient delivery/action state for a single message.
|
|
879
|
-
*
|
|
880
|
-
* Keyed by actor ID. Each entry tracks when the actor read, completed,
|
|
881
|
-
* or otherwise interacted with the message — independently of other actors.
|
|
882
|
-
*/
|
|
883
187
|
export interface MailboxRecipientState {
|
|
884
|
-
/** Actor ID this state belongs to. */
|
|
885
188
|
actorId: string;
|
|
886
|
-
/** ISO8601 — when this actor first read the message. */
|
|
887
189
|
readAt?: string | undefined;
|
|
888
|
-
/** ISO8601 — when this actor completed the message. */
|
|
889
190
|
completedAt?: string | undefined;
|
|
890
|
-
/** Who recorded the completion (usually same as actorId). */
|
|
891
191
|
completedBy?: string | undefined;
|
|
892
|
-
/** Optional outcome summary recorded by this actor. */
|
|
893
|
-
outcome?: string | undefined;
|
|
894
|
-
}
|
|
895
|
-
/**
|
|
896
|
-
* V2 JSONL receipt record. Appended alongside messages and v1 ack records.
|
|
897
|
-
*
|
|
898
|
-
* Has an explicit `__mailboxReceipt: 2` discriminator so:
|
|
899
|
-
* 1. The v2 reader folds these into per-actor `MailboxRecipientState`.
|
|
900
|
-
* 2. A v1 reader ignores the unknown JSON line (no `__ack` field).
|
|
901
|
-
*
|
|
902
|
-
* Fold algebra (applied during materialization):
|
|
903
|
-
* - Keyed by `(messageId, actorId)`.
|
|
904
|
-
* - `read`: first-write-wins (earliest read timestamp is preserved).
|
|
905
|
-
* - `completed`: monotonic upward (once `true`, cannot revert unless an
|
|
906
|
-
* explicit reopen record with `completed: false` is appended).
|
|
907
|
-
* - `outcome`: last-write-wins.
|
|
908
|
-
* - Duplicate records (same messageId, actorId, timestamp): idempotent no-ops.
|
|
909
|
-
*/
|
|
910
|
-
export interface MailboxReceiptRecordV2 {
|
|
911
|
-
/** Discriminator — always `2` to distinguish from messages and v1 acks. */
|
|
912
|
-
__mailboxReceipt: 2;
|
|
913
|
-
/** Target message this receipt applies to. */
|
|
914
|
-
messageId: string;
|
|
915
|
-
/** Actor this receipt belongs to. */
|
|
916
|
-
actorId: string;
|
|
917
|
-
/** ISO8601 — when the receipt event occurred. */
|
|
918
|
-
timestamp: string;
|
|
919
|
-
/** Was the message read by this actor? */
|
|
920
|
-
read?: boolean | undefined;
|
|
921
|
-
/** Was the message completed by this actor? */
|
|
922
|
-
completed?: boolean | undefined;
|
|
923
|
-
/** Optional outcome summary. */
|
|
924
192
|
outcome?: string | undefined;
|
|
925
193
|
}
|
|
926
|
-
/**
|
|
927
|
-
* Check if a parsed JSONL value is a v2 receipt record.
|
|
928
|
-
* Validates the discriminator AND required structural fields.
|
|
929
|
-
*/
|
|
930
|
-
export declare function isMailboxReceiptRecordV2(value: unknown): value is MailboxReceiptRecordV2;
|
|
931
|
-
/**
|
|
932
|
-
* Materialized message with per-actor recipient state.
|
|
933
|
-
*
|
|
934
|
-
* This is the internal representation after folding all v1 acks and v2
|
|
935
|
-
* receipt records. It carries both the legacy fields (for backward
|
|
936
|
-
* compatibility) and the new actor-specific state map.
|
|
937
|
-
*
|
|
938
|
-
* `legacyGlobalCompletion` is set ONLY for historical v1 fan-out messages
|
|
939
|
-
* that were globally completed. It is never set for new v2 writes.
|
|
940
|
-
*/
|
|
941
194
|
export interface MailboxMessageProjection extends MailboxMessage {
|
|
942
|
-
/** Per-actor delivery/action state, keyed by actorId. */
|
|
943
195
|
recipientState: Readonly<Record<string, MailboxRecipientState>>;
|
|
944
|
-
/**
|
|
945
|
-
* True ONLY for historical v1 fan-out messages that were globally completed
|
|
946
|
-
* (completed before the v2 migration). These remain globally suppressed to
|
|
947
|
-
* prevent upgrade re-delivery. New v2 writes NEVER set this.
|
|
948
|
-
*/
|
|
949
|
-
legacyGlobalCompletion?: boolean | undefined;
|
|
950
|
-
}
|
|
951
|
-
/**
|
|
952
|
-
* Self-facing message — what a specific actor sees.
|
|
953
|
-
*
|
|
954
|
-
* This does NOT extend `MailboxMessage` because self-facing responses must NOT
|
|
955
|
-
* contain aggregate receipt metadata (`readBy`, `completedBy`, `completedAt`,
|
|
956
|
-
* `outcome`) that would leak other actors' activity. Only actor-specific
|
|
957
|
-
* derived fields are added on top of the non-sensitive message fields.
|
|
958
|
-
*/
|
|
959
|
-
export interface ActorMailboxMessage extends Omit<MailboxMessage, 'readBy' | 'completed' | 'completedBy' | 'completedAt' | 'outcome'> {
|
|
960
|
-
/** Has this actor read the message? */
|
|
961
|
-
readByMe: boolean;
|
|
962
|
-
/** Has this actor completed the message? */
|
|
963
|
-
completedByMe: boolean;
|
|
964
|
-
/** Does this message require action from this actor? */
|
|
965
|
-
actionRequiredForMe: boolean;
|
|
966
|
-
/** This actor's outcome, if any. */
|
|
967
|
-
myOutcome?: string | undefined;
|
|
968
|
-
/**
|
|
969
|
-
* True for historical v1 fan-out messages that were globally completed.
|
|
970
|
-
* Lets the UI distinguish "completed by me" from "completed globally
|
|
971
|
-
* before migration."
|
|
972
|
-
*/
|
|
973
196
|
legacyGlobalCompletion?: boolean | undefined;
|
|
974
197
|
}
|
|
975
|
-
/**
|
|
976
|
-
* Derive `actionRequiredForMe` from the canonical type properties and actor state.
|
|
977
|
-
*
|
|
978
|
-
* Defined as:
|
|
979
|
-
* `MAILBOX_TYPE_PROPERTIES[type].requiresAction && visible && !completedByMe && !deleted && !legacyGlobalCompletion`
|
|
980
|
-
*
|
|
981
|
-
* For historical legacy-global messages, `actionRequiredForMe` is always false
|
|
982
|
-
* because the message is suppressed and should not re-enter any actor's flow.
|
|
983
|
-
*/
|
|
984
|
-
export declare function isActionRequiredForActor(message: Pick<MailboxMessage, 'type' | 'deletedAt' | 'completed'>, projection: Pick<ActorMailboxMessage, 'completedByMe' | 'legacyGlobalCompletion'>): boolean;
|
|
985
198
|
//# sourceMappingURL=mailbox-types.d.ts.map
|