@songsid/agend 2.1.7-beta.4 → 2.1.7-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/README.zh-TW.md +2 -0
- package/dist/agent-cli-instructions.md +5 -0
- package/dist/agent-cli.js +13 -0
- package/dist/agent-cli.js.map +1 -1
- package/dist/agent-endpoint.js +1 -0
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/backend/codex-session-lookup.d.ts +59 -0
- package/dist/backend/codex-session-lookup.js +139 -0
- package/dist/backend/codex-session-lookup.js.map +1 -0
- package/dist/backend/codex.d.ts +37 -9
- package/dist/backend/codex.js +204 -38
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/grok.js +51 -0
- package/dist/backend/grok.js.map +1 -1
- package/dist/backend/types.d.ts +12 -0
- package/dist/backend/types.js.map +1 -1
- package/dist/channel/mcp-tools.js +2 -0
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/cli.js +137 -124
- package/dist/cli.js.map +1 -1
- package/dist/completion-install.d.ts +32 -0
- package/dist/completion-install.js +125 -1
- package/dist/completion-install.js.map +1 -1
- package/dist/config-validator.js +4 -0
- package/dist/config-validator.js.map +1 -1
- package/dist/daemon.d.ts +12 -1
- package/dist/daemon.js +186 -27
- package/dist/daemon.js.map +1 -1
- package/dist/delivery-outbox.d.ts +199 -6
- package/dist/delivery-outbox.js +602 -44
- package/dist/delivery-outbox.js.map +1 -1
- package/dist/delivery-outbox.test.js +268 -14
- package/dist/delivery-outbox.test.js.map +1 -1
- package/dist/delivery-queue-evidence.d.ts +15 -0
- package/dist/delivery-queue-evidence.js +35 -0
- package/dist/delivery-queue-evidence.js.map +1 -0
- package/dist/delivery-queue-evidence.test.d.ts +1 -0
- package/dist/delivery-queue-evidence.test.js +23 -0
- package/dist/delivery-queue-evidence.test.js.map +1 -0
- package/dist/delivery-reconciliation.d.ts +49 -0
- package/dist/delivery-reconciliation.js +296 -0
- package/dist/delivery-reconciliation.js.map +1 -0
- package/dist/delivery-reconciliation.test.d.ts +1 -0
- package/dist/delivery-reconciliation.test.js +411 -0
- package/dist/delivery-reconciliation.test.js.map +1 -0
- package/dist/fleet-manager.d.ts +10 -1
- package/dist/fleet-manager.js +109 -32
- package/dist/fleet-manager.js.map +1 -1
- package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +10 -0
- package/dist/instance-lifecycle.d.ts +13 -0
- package/dist/instance-lifecycle.js +105 -21
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/instructions.d.ts +6 -0
- package/dist/instructions.js +9 -0
- package/dist/instructions.js.map +1 -1
- package/dist/locale.js +8 -0
- package/dist/locale.js.map +1 -1
- package/dist/ls-rows.d.ts +50 -0
- package/dist/ls-rows.js +152 -0
- package/dist/ls-rows.js.map +1 -0
- package/dist/outbound-handlers.d.ts +3 -0
- package/dist/outbound-handlers.js +38 -2
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +8 -0
- package/dist/outbound-schemas.js +15 -0
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/pane-write-lock.d.ts +2 -0
- package/dist/pane-write-lock.js +19 -0
- package/dist/pane-write-lock.js.map +1 -1
- package/dist/quickstart.js +9 -3
- package/dist/quickstart.js.map +1 -1
- package/dist/remote-credential-check.d.ts +26 -7
- package/dist/remote-credential-check.js +157 -10
- package/dist/remote-credential-check.js.map +1 -1
- package/dist/scheduler/scheduler.d.ts +5 -1
- package/dist/scheduler/scheduler.js +60 -20
- package/dist/scheduler/scheduler.js.map +1 -1
- package/dist/scheduler/scheduler.test.js +41 -2
- package/dist/scheduler/scheduler.test.js.map +1 -1
- package/dist/scheduler/types.d.ts +1 -1
- package/dist/tmux-manager.d.ts +3 -3
- package/dist/tmux-manager.js +6 -6
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tool-permissions.js +6 -6
- package/dist/tool-permissions.js.map +1 -1
- package/dist/transcript-monitor.d.ts +3 -1
- package/dist/transcript-monitor.js +15 -0
- package/dist/transcript-monitor.js.map +1 -1
- package/dist/transcript-sources.d.ts +9 -0
- package/dist/transcript-sources.js +14 -0
- package/dist/transcript-sources.js.map +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/ui/dashboard.html +7 -5
- package/dist/ui/view.html +138 -45
- package/dist/usage/usage-api.js +30 -0
- package/dist/usage/usage-api.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { EventEmitter } from "node:events";
|
|
2
|
+
import type { QueueResumePolicy } from "./delivery-queue-evidence.js";
|
|
2
3
|
export declare const DURABLE_DELIVERY_MAX_ATTEMPTS = 8;
|
|
3
4
|
export declare const DURABLE_DELIVERY_MAX_AGE_MS: number;
|
|
4
5
|
export declare const DURABLE_DELIVERY_ABORT_BACKOFF_MS = 5000;
|
|
5
6
|
export interface DaemonDeliveryPort {
|
|
6
|
-
begin(deliveryId: string, targetBootId: string, attemptNo: number): "begun" | "duplicate" | "stale";
|
|
7
|
+
begin(deliveryId: string, targetBootId: string, attemptNo: number, evidence?: DeliveryAttemptEvidence): "begun" | "duplicate" | "stale";
|
|
8
|
+
markEnterStarted(deliveryId: string, targetBootId: string, attemptNo: number): boolean;
|
|
7
9
|
abort(deliveryId: string, targetBootId: string, attemptNo: number, reason: string): boolean;
|
|
8
10
|
complete(deliveryId: string, targetBootId: string, attemptNo: number, outcome: "delivered" | "failed" | "uncertain", evidence?: string): boolean;
|
|
9
11
|
retryBeforeBegin(deliveryId: string, targetBootId: string, attemptNo: number, reason: string, delayMs?: number): boolean;
|
|
10
12
|
}
|
|
11
|
-
export type OutboxState = "queued" | "delivering" | "submission_started" | "retry_wait" | "delivered" | "failed" | "uncertain" | "cancelled";
|
|
13
|
+
export type OutboxState = "queued" | "delivering" | "submission_started" | "reconciliation_pending" | "retry_wait" | "delivered" | "failed" | "uncertain" | "cancelled";
|
|
12
14
|
export interface NewOutboxDelivery {
|
|
13
15
|
operationId: string;
|
|
14
16
|
sourceKey: string;
|
|
@@ -39,6 +41,143 @@ export interface OutboxDelivery {
|
|
|
39
41
|
responseDeliveredAt: string | null;
|
|
40
42
|
nextAttemptAt: string | null;
|
|
41
43
|
lastError: string | null;
|
|
44
|
+
reconciliationPending: boolean;
|
|
45
|
+
}
|
|
46
|
+
export type DeliveryStatusSelector = {
|
|
47
|
+
deliveryId: string;
|
|
48
|
+
operationId?: never;
|
|
49
|
+
correlationId?: never;
|
|
50
|
+
messageId?: never;
|
|
51
|
+
limit?: never;
|
|
52
|
+
cursor?: never;
|
|
53
|
+
} | {
|
|
54
|
+
operationId: string;
|
|
55
|
+
deliveryId?: never;
|
|
56
|
+
correlationId?: never;
|
|
57
|
+
messageId?: never;
|
|
58
|
+
limit?: number;
|
|
59
|
+
cursor?: string;
|
|
60
|
+
} | {
|
|
61
|
+
correlationId: string;
|
|
62
|
+
deliveryId?: never;
|
|
63
|
+
operationId?: never;
|
|
64
|
+
messageId?: never;
|
|
65
|
+
limit?: number;
|
|
66
|
+
cursor?: string;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* #856: the `message_id` a receiver sees in the envelope header. Lets an
|
|
70
|
+
* agent check that a peer message it is about to act on was really
|
|
71
|
+
* delivered by the fleet — a model can "see" one nobody sent.
|
|
72
|
+
*/
|
|
73
|
+
| {
|
|
74
|
+
messageId: string;
|
|
75
|
+
deliveryId?: never;
|
|
76
|
+
operationId?: never;
|
|
77
|
+
correlationId?: never;
|
|
78
|
+
limit?: number;
|
|
79
|
+
cursor?: string;
|
|
80
|
+
};
|
|
81
|
+
/** The one mapping from validated tool/CLI arguments to a selector. */
|
|
82
|
+
export declare function deliveryStatusSelector(args: {
|
|
83
|
+
delivery_id?: string;
|
|
84
|
+
operation_id?: string;
|
|
85
|
+
correlation_id?: string;
|
|
86
|
+
message_id?: string;
|
|
87
|
+
limit?: number;
|
|
88
|
+
cursor?: string;
|
|
89
|
+
}): DeliveryStatusSelector;
|
|
90
|
+
/** sha256 of a delivered text, as hex. The same function hashes admission and paste. */
|
|
91
|
+
export declare function deliveryContentDigest(text: string): string;
|
|
92
|
+
/** #926 reminders and overdue notices; never themselves the subject of a failure notice. */
|
|
93
|
+
export declare const REPLY_OBLIGATION_NOTICE_KIND = "reply_obligation_notice";
|
|
94
|
+
export interface DeliveryStatusItem {
|
|
95
|
+
delivery_id: string;
|
|
96
|
+
operation_id: string;
|
|
97
|
+
correlation_id: string | null;
|
|
98
|
+
source_instance: string;
|
|
99
|
+
target_instance: string;
|
|
100
|
+
kind: string;
|
|
101
|
+
state: OutboxState;
|
|
102
|
+
attempt_no: number;
|
|
103
|
+
created_at: string;
|
|
104
|
+
updated_at: string;
|
|
105
|
+
status_summary: string;
|
|
106
|
+
error_summary: string | null;
|
|
107
|
+
safe_to_retry: boolean;
|
|
108
|
+
/** Fleet message ID of the delivered envelope, when it had one. */
|
|
109
|
+
message_id: string | null;
|
|
110
|
+
/** sha256 of the delivered text as admitted (#856). */
|
|
111
|
+
content_sha256: string | null;
|
|
112
|
+
/**
|
|
113
|
+
* The text as admitted — only on a `message_id` query by the row's own
|
|
114
|
+
* source or target: the caller already sent or received it, and verifying
|
|
115
|
+
* a value (a SHA, a PR number) needs the text, not just its digest. Every
|
|
116
|
+
* other query, and operator reads, stay redacted as before (#982).
|
|
117
|
+
*/
|
|
118
|
+
content?: string | null;
|
|
119
|
+
/** #926: the reply this request is owed, when it asked for one. */
|
|
120
|
+
reply_obligation?: {
|
|
121
|
+
state: "open" | "answered";
|
|
122
|
+
opened_at: string;
|
|
123
|
+
last_asked_at: string;
|
|
124
|
+
nudged_at: string | null;
|
|
125
|
+
overdue_notified_at: string | null;
|
|
126
|
+
answered_at: string | null;
|
|
127
|
+
} | null;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* #926: a peer asked with `requires_reply` and the owner has not answered it
|
|
131
|
+
* through the fleet yet. Terminal text is not an answer: only a message the
|
|
132
|
+
* owner sends back to the requester with the same correlation_id closes it.
|
|
133
|
+
*/
|
|
134
|
+
export interface ReplyObligation {
|
|
135
|
+
correlationId: string;
|
|
136
|
+
requesterInstance: string;
|
|
137
|
+
ownerInstance: string;
|
|
138
|
+
requestDeliveryId: string;
|
|
139
|
+
openedAt: string;
|
|
140
|
+
lastAskedAt: string;
|
|
141
|
+
state: "open" | "answered";
|
|
142
|
+
nudgedAt: string | null;
|
|
143
|
+
overdueNotifiedAt: string | null;
|
|
144
|
+
answeredAt: string | null;
|
|
145
|
+
answeredDeliveryId: string | null;
|
|
146
|
+
}
|
|
147
|
+
export interface DeliveryStatusPage {
|
|
148
|
+
items: DeliveryStatusItem[];
|
|
149
|
+
next_cursor: string | null;
|
|
150
|
+
}
|
|
151
|
+
export type DurableSubmissionMode = "idle_submit" | "native_queue_handoff" | "steer" | "raw_paste";
|
|
152
|
+
/** Checkpoint committed with begin, before any pane paste can occur. */
|
|
153
|
+
export interface DeliveryAttemptEvidence {
|
|
154
|
+
backend: string;
|
|
155
|
+
backendVersion?: string | null;
|
|
156
|
+
windowId: string | null;
|
|
157
|
+
transcriptPath: string | null;
|
|
158
|
+
transcriptOffset: number | null;
|
|
159
|
+
transcriptSessionId: string | null;
|
|
160
|
+
submissionMode: DurableSubmissionMode;
|
|
161
|
+
queueResumePolicy?: QueueResumePolicy;
|
|
162
|
+
/** sha256 of the text the target daemon received, before formatting (#856). */
|
|
163
|
+
pastedContentSha256?: string | null;
|
|
164
|
+
/** sha256 of the exact string handed to the pane write (#856). */
|
|
165
|
+
pastedBytesSha256?: string | null;
|
|
166
|
+
}
|
|
167
|
+
export interface DeliveryReconciliationCandidate extends OutboxDelivery {
|
|
168
|
+
attempt: {
|
|
169
|
+
targetDaemonBootId: string;
|
|
170
|
+
attemptNo: number;
|
|
171
|
+
backend: string | null;
|
|
172
|
+
backendVersion: string | null;
|
|
173
|
+
windowId: string | null;
|
|
174
|
+
transcriptPath: string | null;
|
|
175
|
+
transcriptOffset: number | null;
|
|
176
|
+
transcriptSessionId: string | null;
|
|
177
|
+
submissionMode: DurableSubmissionMode | null;
|
|
178
|
+
queueResumePolicy: QueueResumePolicy | null;
|
|
179
|
+
enterStartedAt: string | null;
|
|
180
|
+
};
|
|
42
181
|
}
|
|
43
182
|
export interface ClaimedOutboxDelivery extends OutboxDelivery {
|
|
44
183
|
targetDaemonBootId: string;
|
|
@@ -48,6 +187,45 @@ export declare class DeliveryOutbox extends EventEmitter {
|
|
|
48
187
|
private readonly db;
|
|
49
188
|
readonly managerBootId: string;
|
|
50
189
|
constructor(dbPath: string, managerBootId?: string);
|
|
190
|
+
/**
|
|
191
|
+
* #926: a delivered `requires_reply` request opens (or, asked again,
|
|
192
|
+
* re-opens) the owner's obligation. Runs inside the delivered transition.
|
|
193
|
+
* An answer admitted before the request finished its submission proof —
|
|
194
|
+
* an owner can reply while the daemon is still confirming — counts.
|
|
195
|
+
*/
|
|
196
|
+
private openReplyObligation;
|
|
197
|
+
/** The owner's message back to the requester on the same correlation_id answers it — at admission. */
|
|
198
|
+
private answerReplyObligation;
|
|
199
|
+
/**
|
|
200
|
+
* #926 safety net 1: remind an owner that has not answered. `turn-ended`
|
|
201
|
+
* reminds once per ask, after the grace (a reply seconds after the ask is
|
|
202
|
+
* normal); `restart` reminds once per restart, because the interrupted turn
|
|
203
|
+
* does not resume on its own. Marked in the same transaction as the notice.
|
|
204
|
+
*/
|
|
205
|
+
remindReplyObligations(ownerInstance: string, opts: {
|
|
206
|
+
now?: Date;
|
|
207
|
+
graceMs: number;
|
|
208
|
+
reason: "turn-ended" | "restart";
|
|
209
|
+
since?: Date;
|
|
210
|
+
}): number;
|
|
211
|
+
/**
|
|
212
|
+
* #926 safety net 2 (poll-on-timeout, in code): tell the requester once when
|
|
213
|
+
* the owner is not working and nothing has come back for `overdueMs` since
|
|
214
|
+
* the last ask or reminder. A still-working owner is never reported.
|
|
215
|
+
*/
|
|
216
|
+
notifyOverdueReplyObligations(opts: {
|
|
217
|
+
now?: Date;
|
|
218
|
+
overdueMs: number;
|
|
219
|
+
ownerIdle: (owner: string) => boolean;
|
|
220
|
+
}): number;
|
|
221
|
+
/** A system notice as a durable row, like #929's outcome notices; the key makes it idempotent. */
|
|
222
|
+
private insertReplyObligationNotice;
|
|
223
|
+
/** The owner's open obligations, oldest first (#926). */
|
|
224
|
+
openReplyObligations(ownerInstance: string): ReplyObligation[];
|
|
225
|
+
getReplyObligation(correlationId: string, requesterInstance: string, ownerInstance: string): ReplyObligation | undefined;
|
|
226
|
+
/** Rows admitted before #856 get the same message_id / digest a new row would. */
|
|
227
|
+
private backfillMessageEvidence;
|
|
228
|
+
private ensureColumn;
|
|
51
229
|
/** Commit admission before returning success. Duplicate source keys return their original row. */
|
|
52
230
|
admit(input: NewOutboxDelivery): {
|
|
53
231
|
delivery: OutboxDelivery;
|
|
@@ -55,19 +233,29 @@ export declare class DeliveryOutbox extends EventEmitter {
|
|
|
55
233
|
};
|
|
56
234
|
get(deliveryId: string): OutboxDelivery | undefined;
|
|
57
235
|
getByOperation(sourceInstance: string, operationId: string): OutboxDelivery[];
|
|
236
|
+
/**
|
|
237
|
+
* Query only rows owned by the authenticated instance as source or target.
|
|
238
|
+
* This method accepts caller identity separately from user arguments so a
|
|
239
|
+
* caller cannot widen its own visibility with a forged source name.
|
|
240
|
+
*/
|
|
241
|
+
queryStatusForInstance(callerInstance: string, selector: DeliveryStatusSelector): DeliveryStatusPage;
|
|
242
|
+
/** Open the existing outbox without migrations or writes for the operator CLI. */
|
|
243
|
+
static queryStatusReadOnly(dbPath: string, selector: DeliveryStatusSelector): DeliveryStatusPage;
|
|
58
244
|
listPending(): OutboxDelivery[];
|
|
59
245
|
nextRetryAt(): string | null;
|
|
60
246
|
/** Claim the earliest eligible target row; one caller owns each target lane. */
|
|
61
247
|
claimNext(managerBootId: string, targetBootIdFor: (target: string) => string | null, blockedTargets: ReadonlySet<string>): ClaimedOutboxDelivery | undefined;
|
|
62
248
|
/** Idempotent begin permit, committed immediately before the pane side effect. */
|
|
63
|
-
begin(deliveryId: string, targetBootId: string, attemptNo: number): "begun" | "duplicate" | "stale";
|
|
249
|
+
begin(deliveryId: string, targetBootId: string, attemptNo: number, evidence?: DeliveryAttemptEvidence): "begun" | "duplicate" | "stale";
|
|
250
|
+
/** Write-ahead fence: commit before tmux is allowed to receive Enter. */
|
|
251
|
+
markEnterStarted(deliveryId: string, targetBootId: string, attemptNo: number): boolean;
|
|
64
252
|
/** Safe only when the caller can prove no pane write occurred for this attempt. */
|
|
65
253
|
abort(deliveryId: string, targetBootId: string, attemptNo: number, reason: string): boolean;
|
|
66
254
|
complete(deliveryId: string, targetBootId: string, attemptNo: number, outcome: "delivered" | "failed" | "uncertain", evidence?: string): boolean;
|
|
67
255
|
/** Transient pre-submit failure: state is retryable and the same row keeps its FIFO position. */
|
|
68
256
|
retryBeforeBegin(deliveryId: string, targetBootId: string, attemptNo: number, reason: string, delayMs?: number): boolean;
|
|
69
257
|
failBeforeBegin(deliveryId: string, reason: string): boolean;
|
|
70
|
-
/**
|
|
258
|
+
/** Bound both unavailable rows and unresolved reconciliation without stealing a live lease. */
|
|
71
259
|
expireStale(nowMs?: number, maxAgeMs?: number): number;
|
|
72
260
|
/** Next queued/retry expiry for bounded maintenance scheduling. */
|
|
73
261
|
nextExpiryAt(): string | null;
|
|
@@ -75,14 +263,19 @@ export declare class DeliveryOutbox extends EventEmitter {
|
|
|
75
263
|
/** Old process leases are recoverable; an old submission attempt needs evidence reconciliation. */
|
|
76
264
|
recoverForBoot(managerBootId: string): {
|
|
77
265
|
queued: number;
|
|
78
|
-
|
|
266
|
+
reconciliationPending: number;
|
|
79
267
|
};
|
|
80
268
|
/** Atomically create a post-restart notice for an accepted operation whose response was not recorded. */
|
|
81
269
|
admitPostRestartOutcomeNotice(parent: OutboxDelivery, currentSourceBootId: string): OutboxDelivery | undefined;
|
|
82
270
|
recoverTargetGeneration(targetInstance: string, currentTargetBootId: string): {
|
|
83
271
|
queued: number;
|
|
84
|
-
|
|
272
|
+
reconciliationPending: number;
|
|
85
273
|
};
|
|
274
|
+
/** Fence in-flight writes before an in-process target stop begins. */
|
|
275
|
+
markTargetReconciliationPending(targetInstance: string, targetBootId: string): number;
|
|
276
|
+
getReconciliationCandidates(targetInstance: string): DeliveryReconciliationCandidate[];
|
|
277
|
+
/** Atomically settle one old attempt using only its boot/attempt fence. */
|
|
278
|
+
reconcileAttempt(deliveryId: string, targetBootId: string, attemptNo: number, outcome: "delivered" | "retry_wait" | "uncertain", evidence: string): boolean;
|
|
86
279
|
getUnansweredAccepted(sourceInstance: string, currentBootId: string): OutboxDelivery[];
|
|
87
280
|
close(): void;
|
|
88
281
|
/** Must be called inside the same SQLite transaction as the terminal transition. */
|