@agent-compose/sdk 0.8.1 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/__tests__/perf-sampler.test.d.ts +10 -0
- package/dist/agent/agent-context.d.ts +1 -1
- package/dist/agent/agent-loop.d.ts +5 -1
- package/dist/agent/desktop-open.d.ts +184 -0
- package/dist/agent/perf-sampler.d.ts +99 -0
- package/dist/agent/services-manifest.d.ts +88 -0
- package/dist/agent/services-restore.d.ts +58 -0
- package/dist/client.d.ts +189 -15
- package/dist/display.d.ts +17 -0
- package/dist/index.d.ts +14 -5
- package/dist/index.js +1625 -120
- package/dist/runtimes/_cli-agent.d.ts +372 -2
- package/dist/runtimes/claude-code.d.ts +12 -0
- package/dist/runtimes/codex.buildcommand.test.d.ts +9 -0
- package/dist/runtimes/codex.d.ts +8 -0
- package/dist/runtimes/openai-desktop.js +1555 -120
- package/dist/runtimes/session-env.test.d.ts +14 -0
- package/dist/sandbox/sizes.d.ts +120 -30
- package/dist/sandbox.d.ts +1 -1
- package/dist/types/api-conversations.d.ts +476 -1
- package/dist/types/api-factory.d.ts +164 -7
- package/dist/types/api-runs.d.ts +23 -1
- package/dist/types/protocol.d.ts +32 -1
- package/dist/types/runtime.d.ts +120 -0
- package/dist/types/workflow-metadata.d.ts +6 -5
- package/package.json +1 -1
- package/src/agent/agent-context.ts +128 -28
- package/src/agent/agent-loop.ts +10 -3
- package/src/agent/desktop-open.ts +418 -0
- package/src/agent/perf-sampler.ts +202 -0
- package/src/agent/services-manifest.ts +356 -0
- package/src/agent/services-restore.ts +195 -0
- package/src/client.ts +384 -32
- package/src/display.ts +44 -1
- package/src/index.ts +74 -7
- package/src/runtimes/_cli-agent.ts +1160 -67
- package/src/runtimes/claude-code.ts +187 -12
- package/src/runtimes/codex.ts +65 -2
- package/src/sandbox/providers/e2b.ts +8 -4
- package/src/sandbox/providers/local.ts +16 -4
- package/src/sandbox/sizes.ts +127 -44
- package/src/sandbox.ts +8 -0
- package/src/types/api-conversations.ts +461 -2
- package/src/types/api-factory.ts +165 -7
- package/src/types/api-runs.ts +25 -1
- package/src/types/protocol.ts +30 -1
- package/src/types/runtime.ts +122 -0
- package/src/types/workflow-metadata.ts +6 -5
|
@@ -95,15 +95,44 @@ export interface ConversationRow {
|
|
|
95
95
|
unreadCount?: number;
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
/** Agent-author identity decoration (mirrors the server's `agentAuthor`
|
|
99
|
+
* on message rows and stream payloads): rows authored by a user's agent
|
|
100
|
+
* that is not the conversation's resident agent — the assistant's
|
|
101
|
+
* delegated sends, review briefs, and PEER-SESSION messages
|
|
102
|
+
* (`sourceChannel: 'session'`). The persona `name` is the author label;
|
|
103
|
+
* `avatarSeed` is the agent's own generated orb; the owner names WHOSE
|
|
104
|
+
* agent it is. */
|
|
105
|
+
export interface ConversationAgentAuthor {
|
|
106
|
+
agentId: string;
|
|
107
|
+
name: string;
|
|
108
|
+
avatarSeed: string;
|
|
109
|
+
ownerUserId: string | null;
|
|
110
|
+
ownerName: string | null;
|
|
111
|
+
}
|
|
112
|
+
|
|
98
113
|
export interface ConversationMessageRow {
|
|
99
114
|
id: string;
|
|
100
115
|
authorKind: string;
|
|
101
116
|
authorId: string | null;
|
|
117
|
+
/** The author's display name, resolved server-side — a HUMAN author's
|
|
118
|
+
* display name, or an attributable AGENT author's persona name (see
|
|
119
|
+
* `agentAuthor`). Null for resident-agent/system rows; absent on older
|
|
120
|
+
* servers. */
|
|
121
|
+
authorLabel?: string | null;
|
|
122
|
+
/** Sender identity for foreign-agent and peer-session rows — render the
|
|
123
|
+
* persona name + its avatarSeed FIRST, before any session/runtime
|
|
124
|
+
* fallback (the one resolution order; streamed and settled renders are
|
|
125
|
+
* identical). Null/absent on resident-agent, session channel-post, and
|
|
126
|
+
* older-server rows. */
|
|
127
|
+
agentAuthor?: ConversationAgentAuthor | null;
|
|
102
128
|
parts: ConversationMessagePart[];
|
|
103
129
|
threadRootId: string | null;
|
|
104
130
|
reactions: Record<string, string[]>;
|
|
105
131
|
replyCount: number;
|
|
106
132
|
lastReplyAt: string | null;
|
|
133
|
+
/** When the author last edited the content; null/absent = never edited
|
|
134
|
+
* (absent on older servers). */
|
|
135
|
+
editedAt?: string | null;
|
|
107
136
|
createdAt: string;
|
|
108
137
|
/** Thread-root facepile (≤3) — present only on roots with replies. */
|
|
109
138
|
replyAuthors?: Array<{ kind: string; id: string | null }>;
|
|
@@ -112,6 +141,12 @@ export interface ConversationMessageRow {
|
|
|
112
141
|
* rows to the session (title + runtime mark), never a resident agent.
|
|
113
142
|
* Null once the session is deleted; absent on older servers. */
|
|
114
143
|
sourceSessionId?: string | null;
|
|
144
|
+
/** THE ORIGIN SURFACE (ADR-0073 §6.5): the ingress the row arrived over —
|
|
145
|
+
* 'sms' / 'phone' / 'voice' on inbound user rows, 'assistant' on
|
|
146
|
+
* delegated sends, 'session' on peer session→session messages (whose
|
|
147
|
+
* author identity rides `agentAuthor`). Null/absent = an ordinary
|
|
148
|
+
* in-app send or an older server. */
|
|
149
|
+
sourceChannel?: "sms" | "phone" | "voice" | "assistant" | "session" | null;
|
|
115
150
|
/** Set on a session-transcript row RELAYED from a channel mention
|
|
116
151
|
* (ADR-0057 Seam 3) — the channel it arrived from. Null once the
|
|
117
152
|
* channel is deleted; absent on older servers. */
|
|
@@ -130,9 +165,44 @@ export interface ConversationsPage {
|
|
|
130
165
|
/** Sessions page — each row additionally carries its resident
|
|
131
166
|
* executor substrate (ADR-0037 §8): `"cloud"` = persistent server-side
|
|
132
167
|
* sandbox (pickers render the ☁ marker), `"local"` = bridge daemon,
|
|
133
|
-
* null = no durable session record yet
|
|
168
|
+
* null = no durable session record yet — and, on diff-review spawns,
|
|
169
|
+
* `reviewOf`: the session this row was born to REVIEW (id + its current
|
|
170
|
+
* alias/title; a deleted reviewed conversation degrades to a bare id
|
|
171
|
+
* ref). Null/absent for ordinary sessions and older servers. */
|
|
134
172
|
export interface SessionsPage {
|
|
135
|
-
conversations: Array<ConversationRow & {
|
|
173
|
+
conversations: Array<ConversationRow & {
|
|
174
|
+
sessionExecutor: "local" | "cloud" | null;
|
|
175
|
+
reviewOf?: { conversationId: string; alias: string | null; title: string | null; head?: string | null } | null;
|
|
176
|
+
}>;
|
|
177
|
+
next_cursor: string | null;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** One 15-minute sandbox perf rollup bucket from
|
|
181
|
+
* GET /conversations/:id/perf-history (session_perf_rollups). Null
|
|
182
|
+
* utilization fields = the guest never reported that resource in the
|
|
183
|
+
* bucket — never zero-filled. */
|
|
184
|
+
export interface SessionPerfBucket {
|
|
185
|
+
/** Start of the bucket, ISO 8601. */
|
|
186
|
+
bucket_start: string;
|
|
187
|
+
/** Guest samples folded into the bucket (turn + sweep lanes). */
|
|
188
|
+
samples: number;
|
|
189
|
+
cpu_busy_p50: number | null;
|
|
190
|
+
cpu_busy_p95: number | null;
|
|
191
|
+
mem_used_p50: number | null;
|
|
192
|
+
mem_used_p95: number | null;
|
|
193
|
+
disk_used_p95: number | null;
|
|
194
|
+
load1_max: number | null;
|
|
195
|
+
/** Seconds within the bucket any resource sat ≥90% (capped at 900). */
|
|
196
|
+
saturated_seconds: number;
|
|
197
|
+
vcpu: number | null;
|
|
198
|
+
provider: string;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/** Newest-first, keyset-paginated (house list envelope). */
|
|
202
|
+
export interface SessionPerfHistoryPage {
|
|
203
|
+
object: "list";
|
|
204
|
+
data: SessionPerfBucket[];
|
|
205
|
+
has_more: boolean;
|
|
136
206
|
next_cursor: string | null;
|
|
137
207
|
}
|
|
138
208
|
|
|
@@ -162,16 +232,31 @@ export interface ConversationDetail {
|
|
|
162
232
|
* with a drive branch and a resolvable factory; null/absent = main
|
|
163
233
|
* only (read loosely — older servers omit it). */
|
|
164
234
|
sessionDrive?: { factorySlug: string; branch: string } | null;
|
|
235
|
+
/** THE REVIEWER MARKER (diff-review spawns): non-null ⇒ this session was
|
|
236
|
+
* born to review that conversation's diff. Null for ordinary sessions;
|
|
237
|
+
* absent on older servers (read loosely). */
|
|
238
|
+
sessionReviewOf?: string | null;
|
|
165
239
|
viewerLastReadAt: string | null;
|
|
166
240
|
/** The caller's role in this conversation (ADR-0045) — drives client
|
|
167
241
|
* affordances only; the server remains the authority on every action.
|
|
168
242
|
* Public channels report implicit `write` for non-member teammates. */
|
|
169
243
|
viewerRole: ConversationMemberRole;
|
|
244
|
+
/** Provenance when `viewerRole` is DERIVED rather than held: the project
|
|
245
|
+
* (ADR-0045 read floor) or attached channel (ADR-0057) the viewer
|
|
246
|
+
* follows this conversation through. Null/absent for real members —
|
|
247
|
+
* clients use it to explain read-only honestly ("You follow this
|
|
248
|
+
* session through <project>…"). Absent on older servers. */
|
|
249
|
+
viewerRoleVia?: { kind: "project" | "channel"; id: string; name: string | null } | null;
|
|
170
250
|
/** SSE replay watermark: the conversation's highest durable stream-event
|
|
171
251
|
* id at hydrate time — everything at or below it is already folded into
|
|
172
252
|
* `messages`. Seed the stream's first `Last-Event-ID` from it instead of
|
|
173
253
|
* 0 (0 replays the entire history). Absent on older servers. */
|
|
174
254
|
streamCursor?: number;
|
|
255
|
+
/** Windowed hydrate (2026-08-17): `messages` is the NEWEST window
|
|
256
|
+
* (default 50; `limit` caps at 200). Non-null = older transcript
|
|
257
|
+
* exists — page it with `GET /conversations/:id/messages?before=` +
|
|
258
|
+
* this opaque cursor. Absent on older servers. */
|
|
259
|
+
olderCursor?: string | null;
|
|
175
260
|
messages: ConversationMessageRow[];
|
|
176
261
|
}
|
|
177
262
|
|
|
@@ -251,6 +336,15 @@ export interface CreateCloudSessionInput {
|
|
|
251
336
|
* seeds re-applied on every fresh acquire. Paths under .claude/ only;
|
|
252
337
|
* strict base64; 256KB decoded total (server-capped). */
|
|
253
338
|
seedFiles?: Array<{ path: string; contentB64: string; mode: "write" | "append" }>;
|
|
339
|
+
/** DIFF REVIEW spawn: the conversation whose proposed changes this
|
|
340
|
+
* session is born to review. Server-resolved: on a graph-plane drive
|
|
341
|
+
* the new session's branch is minted as a FORK of the reviewed branch
|
|
342
|
+
* (its working dir IS the proposal, `.review/` comparison materials
|
|
343
|
+
* included); on the legacy plane the spawn degrades to an ordinary
|
|
344
|
+
* session. Requires a human caller and a chat session on the reviewed
|
|
345
|
+
* session's factory; 409 `review_of_review` when the target is itself
|
|
346
|
+
* a review session. */
|
|
347
|
+
reviewOfConversationId?: string;
|
|
254
348
|
}
|
|
255
349
|
|
|
256
350
|
export interface CloudSessionCreated {
|
|
@@ -327,6 +421,15 @@ export interface SessionForked {
|
|
|
327
421
|
conversationId: string;
|
|
328
422
|
}
|
|
329
423
|
|
|
424
|
+
/** Result of holding a session's background-work busy lease
|
|
425
|
+
* (`POST /conversations/:id/background-work`). While the lease is live the
|
|
426
|
+
* between-turns park/suspend leaves the session's VM running; it lapses on
|
|
427
|
+
* its own — re-hold to extend. */
|
|
428
|
+
export interface BackgroundWorkHeld {
|
|
429
|
+
/** ISO timestamp the lease now runs to. */
|
|
430
|
+
leaseUntil: string;
|
|
431
|
+
}
|
|
432
|
+
|
|
330
433
|
// ── Session branch proposals (ADR-0053) ─────────────────────────────────────
|
|
331
434
|
// Every cloud session works on its own factory-drive branch; the whole branch
|
|
332
435
|
// is the unit of review, like a PR. Wire shapes mirror
|
|
@@ -364,6 +467,217 @@ export interface SessionChangeSet {
|
|
|
364
467
|
truncated: boolean;
|
|
365
468
|
/** Open `factory_file_conflicts` rows from this session's prior merges. */
|
|
366
469
|
openConflicts: number;
|
|
470
|
+
/** Graph plane only (additive — absent elsewhere): the opaque cursor for
|
|
471
|
+
* the NEXT page of `changes` — pass it back as `after` on
|
|
472
|
+
* `getSessionChanges`. Null = last page. */
|
|
473
|
+
nextAfter?: string | null;
|
|
474
|
+
/** The serving plane (additive): `"graph"` when the change set is served
|
|
475
|
+
* from the commit graph (paginated, head-anchored); absent = legacy. */
|
|
476
|
+
plane?: "graph";
|
|
477
|
+
/** MERGE GATE (merge-gate spec, additive — absent on older servers):
|
|
478
|
+
* null = ungated. Present: whether THIS caller's merge lands directly
|
|
479
|
+
* (`canMerge` — an owner or named approver) or stages a kind='merge'
|
|
480
|
+
* approval instead (`mergeSessionChanges` answers 202
|
|
481
|
+
* `SessionMergeGated`), plus the resolved approver set. */
|
|
482
|
+
mergeGate?: {
|
|
483
|
+
enabled: true;
|
|
484
|
+
canMerge: boolean;
|
|
485
|
+
approvers: Array<{ userId: string; label: string | null }>;
|
|
486
|
+
} | null;
|
|
487
|
+
/** The OPEN kind='merge' approval already waiting on this session's
|
|
488
|
+
* branch, if any (additive — absent on older servers). */
|
|
489
|
+
pendingApprovalId?: string | null;
|
|
490
|
+
/** DIFF REVIEW (additive — absent on older servers): notes written back
|
|
491
|
+
* by a spawned review session, whether they predate the served diff
|
|
492
|
+
* (`reviewStale` — the changed-file signature no longer matches), the
|
|
493
|
+
* bound review session's conversation + whether it is still live, and
|
|
494
|
+
* whether the deployment offers reviews at all (`reviewEnabled`; false
|
|
495
|
+
* hides the affordance). Reviews are USER-TRIGGERED only — binding
|
|
496
|
+
* rides `POST /conversations/:id/changes/review`, and notes arrive
|
|
497
|
+
* through the review session's own gated write-back. */
|
|
498
|
+
reviewNotes?: string | null;
|
|
499
|
+
reviewStale?: boolean;
|
|
500
|
+
reviewEnabled?: boolean;
|
|
501
|
+
reviewSessionConversationId?: string | null;
|
|
502
|
+
reviewSessionActive?: boolean;
|
|
503
|
+
/** BOUND (additive): the bound review session — the FOLLOW-UP LOOP's
|
|
504
|
+
* driver — exists and is not ended (a parked reviewer between turns is
|
|
505
|
+
* bound but not active). Not publish rights: every reviewer of the
|
|
506
|
+
* diff owns its own document; concurrent reviewers are first-class,
|
|
507
|
+
* bounded at spawn (`reviewer_cap`). */
|
|
508
|
+
reviewSessionBound?: boolean;
|
|
509
|
+
/** The AUTOMATIC follow-up loop (additive): armed (default true) + how
|
|
510
|
+
* many automatic rounds ran since the last human-triggered review
|
|
511
|
+
* (hard cap 2; a manual re-review resets it). */
|
|
512
|
+
reviewAutoFollowup?: boolean;
|
|
513
|
+
reviewAutoRounds?: number;
|
|
514
|
+
/** The OPT-IN main-advance auto-rebase reflex (additive — absent on
|
|
515
|
+
* older servers; default OFF): armed ⇒ when main moves and a preflight
|
|
516
|
+
* proves the fold clean, the platform rebases this session's branch
|
|
517
|
+
* from main headlessly. Toggled via `setSessionAutoRebase`. */
|
|
518
|
+
autoRebaseFromMain?: boolean;
|
|
519
|
+
/** STRUCTURED review suggestions beside the notes (additive — absent on
|
|
520
|
+
* older servers): individually actionable {id, path, title, rationale,
|
|
521
|
+
* patch} entries the review session wrote back, status-stamped
|
|
522
|
+
* `"proposed"` by the server (`"accepted"`/`"rejected"` are reserved for
|
|
523
|
+
* the human decision pass). */
|
|
524
|
+
reviewSuggestions?: ReviewSuggestion[];
|
|
525
|
+
/** THE REVIEWER MARKER (additive — absent on older servers): non-null ⇒
|
|
526
|
+
* THIS session was born to review that conversation's diff. Its own
|
|
527
|
+
* branch is a fork of the reviewed branch and can never merge
|
|
528
|
+
* (`mergeable` false, merge 409s `fork_branch_unmergeable`), and it is
|
|
529
|
+
* refused as a review target (409 `review_of_review`). */
|
|
530
|
+
reviewOfConversationId?: string | null;
|
|
531
|
+
/** PER-REVIEWER review documents (additive — absent on older servers;
|
|
532
|
+
* owner ask 2026-08-22): EVERY reviewer's published document for this
|
|
533
|
+
* diff, newest publish first — parallel reviewers each own one. The
|
|
534
|
+
* flat `reviewNotes`/`reviewSuggestions` above are derived aggregates
|
|
535
|
+
* (the primary document's notes; the reviewer-stamped union); this is
|
|
536
|
+
* the grouped truth the review panel renders. Page 1 only — cursor
|
|
537
|
+
* pages serve an empty array. */
|
|
538
|
+
reviewDocuments?: SessionReviewDocument[];
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/** One reviewer's published review document
|
|
542
|
+
* (`SessionChangeSet.reviewDocuments`). `stale` compares the head this
|
|
543
|
+
* document was published against with the served diff. */
|
|
544
|
+
export interface SessionReviewDocument {
|
|
545
|
+
reviewerConversationId: string;
|
|
546
|
+
/** The reviewer session's @alias / title, when its conversation still
|
|
547
|
+
* exists (a deleted reviewer degrades to the bare id). */
|
|
548
|
+
reviewerAlias: string | null;
|
|
549
|
+
reviewerTitle: string | null;
|
|
550
|
+
notes: string;
|
|
551
|
+
suggestions: ReviewSuggestion[];
|
|
552
|
+
/** ISO timestamp of this document's last publish. */
|
|
553
|
+
publishedAt: string;
|
|
554
|
+
/** The diff head published against (null = pre-stamp reviewer). */
|
|
555
|
+
signature: string | null;
|
|
556
|
+
/** Display form of `signature` ("head cd741f27"). */
|
|
557
|
+
headShort: string | null;
|
|
558
|
+
stale: boolean;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/** One STRUCTURED, individually actionable suggestion a review session
|
|
562
|
+
* wrote back beside its notes (`SessionChangeSet.reviewSuggestions`). */
|
|
563
|
+
export interface ReviewSuggestion {
|
|
564
|
+
/** Reviewer-minted stable id — survives full-replace re-posts. */
|
|
565
|
+
id: string;
|
|
566
|
+
/** The changed file the suggestion targets (always in the change set —
|
|
567
|
+
* the writeback refuses paths outside it). */
|
|
568
|
+
path: string;
|
|
569
|
+
title: string;
|
|
570
|
+
rationale: string;
|
|
571
|
+
/** Unified-diff hunk targeting the PROPOSED side of `path`. */
|
|
572
|
+
patch: string;
|
|
573
|
+
/** Server-stamped `"proposed"` at writeback; the HUMAN decision routes
|
|
574
|
+
* (`POST …/changes/suggestions/:suggestionId/decide` / `…/decide-all`)
|
|
575
|
+
* are the only writers of the rest — `"accepted"` (the patch landed on
|
|
576
|
+
* the session branch), `"rejected"`, or `"stale"` (an accept found the
|
|
577
|
+
* file drifted since review; nothing was written). */
|
|
578
|
+
status: "proposed" | "accepted" | "rejected" | "stale";
|
|
579
|
+
/** REVIEWER IDENTITY (additive — present on the flat
|
|
580
|
+
* `SessionChangeSet.reviewSuggestions` union; owner ask 2026-08-22):
|
|
581
|
+
* which reviewer's document this entry came from. Ids are unique only
|
|
582
|
+
* PER REVIEWER — the decide-one route takes `reviewerConversationId`
|
|
583
|
+
* when two reviewers reused an id (409 `ambiguous_suggestion`
|
|
584
|
+
* otherwise). */
|
|
585
|
+
reviewerConversationId?: string;
|
|
586
|
+
reviewerAlias?: string | null;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/** One suggestion in the review write-back (`publishReviewNotes` /
|
|
590
|
+
* `agentc review publish`): `ReviewSuggestion` minus `status` — the server
|
|
591
|
+
* stamps every stored entry `"proposed"`, so a reviewer can never claim
|
|
592
|
+
* acceptance. `path` must name a file in the change set (refused
|
|
593
|
+
* otherwise). */
|
|
594
|
+
export interface ReviewSuggestionInput {
|
|
595
|
+
id: string;
|
|
596
|
+
path: string;
|
|
597
|
+
title: string;
|
|
598
|
+
rationale: string;
|
|
599
|
+
patch: string;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/** `POST /conversations/:id/review-notes` — the review session publishing
|
|
603
|
+
* its whole review document (full replace: notes AND suggestions
|
|
604
|
+
* together). Gated to the bound review session's own toolbelt key. */
|
|
605
|
+
export interface ReviewNotesPublished {
|
|
606
|
+
ok: true;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
/** `POST /conversations/:id/review-git-credential` — one fresh short-lived
|
|
610
|
+
* credential for the review git remote, minted per git operation by the
|
|
611
|
+
* sandbox's credential helper (`agentc review git-credential`). Gated to
|
|
612
|
+
* the review session's own toolbelt key; never stored, never reused. */
|
|
613
|
+
export interface ReviewGitCredential {
|
|
614
|
+
/** The stable, credential-free remote URL (`https://host/git/<disk>`). */
|
|
615
|
+
url: string;
|
|
616
|
+
username: string;
|
|
617
|
+
password: string;
|
|
618
|
+
/** ISO timestamp the credential expires — informational (the helper
|
|
619
|
+
* mints anew per operation). */
|
|
620
|
+
expiresAt: string;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
/** `POST /conversations/:id/changes/suggestions/:suggestionId/decide` —
|
|
624
|
+
* the post-call truth for that suggestion (an accept that found drift
|
|
625
|
+
* answers `"stale"`; repeats on a settled row are no-ops). */
|
|
626
|
+
export interface ReviewSuggestionDecision {
|
|
627
|
+
object: "review_suggestion_decision";
|
|
628
|
+
conversationId: string;
|
|
629
|
+
id: string;
|
|
630
|
+
status: ReviewSuggestion["status"];
|
|
631
|
+
/** PER-REVIEWER documents (additive): whose document the decided
|
|
632
|
+
* suggestion lives in — null on older servers / legacy ids. */
|
|
633
|
+
reviewerConversationId?: string | null;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
/** `POST /conversations/:id/changes/suggestions/decide-all` — every stored
|
|
637
|
+
* suggestion's post-call status (only `"proposed"` rows flip). */
|
|
638
|
+
export interface ReviewSuggestionDecisions {
|
|
639
|
+
object: "review_suggestion_decisions";
|
|
640
|
+
conversationId: string;
|
|
641
|
+
results: Array<{ id: string; status: ReviewSuggestion["status"]; reviewerConversationId?: string | null }>;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
/** `GET /conversations/:id/changes/stats` — the changes chip's aggregate
|
|
645
|
+
* +added/−removed line counts, cached server-side per (base, theirsHead).
|
|
646
|
+
* `unavailable` = no cheap head anchors (legacy plane, unbranched) — the
|
|
647
|
+
* chip degrades to its file count, never fake zeros. */
|
|
648
|
+
export type SessionChangeStats =
|
|
649
|
+
| { object: "session_change_stats"; conversationId: string; state: "unavailable" }
|
|
650
|
+
| {
|
|
651
|
+
object: "session_change_stats"; conversationId: string; state: "ok";
|
|
652
|
+
additions: number; deletions: number; files: number;
|
|
653
|
+
/** True when the count is partial (list truncated / file cap). */
|
|
654
|
+
truncated: boolean;
|
|
655
|
+
base: string; theirsHead: string;
|
|
656
|
+
};
|
|
657
|
+
|
|
658
|
+
/** `POST /conversations/:id/changes/review` — binds a just-spawned review
|
|
659
|
+
* session to the reviewed session and stamps the diff signature the
|
|
660
|
+
* review covers. */
|
|
661
|
+
export interface SessionDiffReviewBound {
|
|
662
|
+
object: "session_diff_review";
|
|
663
|
+
conversationId: string;
|
|
664
|
+
reviewSessionConversationId: string;
|
|
665
|
+
reviewDiffSignature: string;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
/** 202 from `POST /conversations/:id/changes/merge` on a merge-GATED
|
|
669
|
+
* session when the caller is not an approver: nothing merged — the ask
|
|
670
|
+
* froze into (`approval_required`) or converged on (`approval_pending`) a
|
|
671
|
+
* kind='merge' approval routed to the approvers. */
|
|
672
|
+
export interface SessionMergeGated {
|
|
673
|
+
object: "session_merge_gated";
|
|
674
|
+
conversationId: string;
|
|
675
|
+
code: "approval_required" | "approval_pending";
|
|
676
|
+
approvalId: string;
|
|
677
|
+
branch?: string;
|
|
678
|
+
changeCount?: number;
|
|
679
|
+
openConflicts?: number;
|
|
680
|
+
approvers: Array<{ userId: string; label: string | null }>;
|
|
367
681
|
}
|
|
368
682
|
|
|
369
683
|
/** Per-file accounting of one session branch merge — the merge core's
|
|
@@ -412,6 +726,81 @@ export interface SessionDiscardReport {
|
|
|
412
726
|
discarded: true;
|
|
413
727
|
}
|
|
414
728
|
|
|
729
|
+
/** One row of the conflict preflight (`GET /conversations/:id/changes/preflight`)
|
|
730
|
+
* — the branch-side change decorated with the REAL merge's own per-file
|
|
731
|
+
* disposition, computed report-only: `fastForward` lands as-is (main
|
|
732
|
+
* untouched at the path), `skip` is already-equal on both sides,
|
|
733
|
+
* `conflict` would 409 the merge today. `autoMerge` is the legacy plane's
|
|
734
|
+
* clean-diff3 class — never emitted on the graph plane. */
|
|
735
|
+
export interface SessionPreflightFileRow {
|
|
736
|
+
path: string;
|
|
737
|
+
kind: "add" | "modify" | "delete";
|
|
738
|
+
disposition: "fastForward" | "autoMerge" | "conflict" | "skip";
|
|
739
|
+
/** Set on `conflict` rows only. */
|
|
740
|
+
conflictReason: "same_region" | "binary" | "delete_vs_edit" | null;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
/** `GET /conversations/:id/changes/preflight` — see conflicts AHEAD of the
|
|
744
|
+
* merge: report-only, no writes, no locks. `unavailable` = no cheap head
|
|
745
|
+
* anchors (legacy plane, unbranched) or the classification faulted — the
|
|
746
|
+
* caller degrades honestly, never fake zeros. `pending` = a cold compute
|
|
747
|
+
* outlived the first-response deadline; poll again to collect it. */
|
|
748
|
+
export type SessionChangePreflight =
|
|
749
|
+
| { object: "session_change_preflight"; conversationId: string; state: "unavailable" }
|
|
750
|
+
| {
|
|
751
|
+
object: "session_change_preflight"; conversationId: string; state: "pending";
|
|
752
|
+
base: string; oursHead: string; theirsHead: string;
|
|
753
|
+
}
|
|
754
|
+
| {
|
|
755
|
+
object: "session_change_preflight"; conversationId: string; state: "ok";
|
|
756
|
+
branch: string;
|
|
757
|
+
base: string;
|
|
758
|
+
/** main's head — the exact commit the dispositions were computed against. */
|
|
759
|
+
oursHead: string;
|
|
760
|
+
/** the session branch's head. */
|
|
761
|
+
theirsHead: string;
|
|
762
|
+
files: SessionPreflightFileRow[];
|
|
763
|
+
conflictCount: number;
|
|
764
|
+
/** Page caps hit — dispositions cover a floor, honestly. */
|
|
765
|
+
truncated: boolean;
|
|
766
|
+
};
|
|
767
|
+
|
|
768
|
+
/** Result of `POST /conversations/:id/changes/rebase` — current main
|
|
769
|
+
* folded INTO the session branch (the reverse merge; main untouched).
|
|
770
|
+
* `rebased` advanced the branch by one merge commit (`rebaseCommit`)
|
|
771
|
+
* and future diffs/merges use the new base. `rebased_with_conflicts`
|
|
772
|
+
* folded the clean remainder (`foldCommit`, null when nothing folded) and
|
|
773
|
+
* KEPT the branch's version for `conflictPaths` — each is recorded as a
|
|
774
|
+
* conflict row and the session was told in-conversation to reconcile. */
|
|
775
|
+
export interface SessionRebaseReport {
|
|
776
|
+
object: "session_rebase_report";
|
|
777
|
+
conversationId: string;
|
|
778
|
+
branch: string;
|
|
779
|
+
outcome: "noop" | "rebased" | "rebased_with_conflicts";
|
|
780
|
+
/** main's head at rebase — the branch's new effective base on a clean
|
|
781
|
+
* rebase. */
|
|
782
|
+
mainHead: string;
|
|
783
|
+
rebaseCommit?: string;
|
|
784
|
+
foldCommit?: string | null;
|
|
785
|
+
folded?: { added: number; modified: number; deleted: number; skipped: number };
|
|
786
|
+
baselineAdvanced?: boolean;
|
|
787
|
+
/** Capped at 100 on the wire; `conflictCount` is the true total. */
|
|
788
|
+
conflictPaths?: string[];
|
|
789
|
+
conflictCount?: number;
|
|
790
|
+
conflictsTruncated?: boolean;
|
|
791
|
+
/** True when the gateway truncated its conflict list — the fold was
|
|
792
|
+
* skipped whole (an unlisted conflicted path must never be overwritten). */
|
|
793
|
+
foldSkipped?: boolean;
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
/** Result of `POST /conversations/:id/changes/autorebase` — the opt-in
|
|
797
|
+
* main-advance auto-rebase reflex's new state. */
|
|
798
|
+
export interface SessionAutoRebaseState {
|
|
799
|
+
object: "session_autorebase";
|
|
800
|
+
conversationId: string;
|
|
801
|
+
autoRebaseFromMain: boolean;
|
|
802
|
+
}
|
|
803
|
+
|
|
415
804
|
/** The sender's page stamp (HUD bar sends) — persisted server-side, never
|
|
416
805
|
* echoed back on the wire. Mirrors the server's `PageContext` schema. */
|
|
417
806
|
export interface ConversationPageContext {
|
|
@@ -435,6 +824,15 @@ export interface SendConversationMessageInput {
|
|
|
435
824
|
* work and a coalesced follow-up turn will answer it. NOT an error. */
|
|
436
825
|
export type ConversationTurnState = "none" | "started" | "queued";
|
|
437
826
|
|
|
827
|
+
/** One @-mentioned user the server DROPPED as a non-member — the mention
|
|
828
|
+
* ping went to nobody, and the response says so instead of staying
|
|
829
|
+
* silent. `name` is the label the sender's own text carried for the
|
|
830
|
+
* mention (picked in the typeahead — no new information). */
|
|
831
|
+
export interface UnnotifiedMention {
|
|
832
|
+
userId: string;
|
|
833
|
+
name: string;
|
|
834
|
+
}
|
|
835
|
+
|
|
438
836
|
export interface SendConversationMessageResult {
|
|
439
837
|
/** The persisted user message's id. */
|
|
440
838
|
messageId: string;
|
|
@@ -447,6 +845,10 @@ export interface SendConversationMessageResult {
|
|
|
447
845
|
* each runs its own turn in its own conversation. Absent on older
|
|
448
846
|
* servers and non-channel sends. */
|
|
449
847
|
relayedSessionIds?: string[];
|
|
848
|
+
/** Mentioned users whose ping was dropped by the member filter (a
|
|
849
|
+
* private channel pings members only; a DM pings only the pair) —
|
|
850
|
+
* present only when non-empty. Absent on older servers. */
|
|
851
|
+
unnotifiedMentions?: UnnotifiedMention[];
|
|
450
852
|
}
|
|
451
853
|
|
|
452
854
|
/** Response of the presence heartbeat (ADR-0037 §6): a fresh agent-liveness
|
|
@@ -517,6 +919,63 @@ export interface SessionChannelMessagePosted {
|
|
|
517
919
|
threadRootId?: string | null;
|
|
518
920
|
}
|
|
519
921
|
|
|
922
|
+
/** Result of `POST /session-messages` — one session's agent messaging
|
|
923
|
+
* ANOTHER session's conversation (`agentc session message @alias`). Unlike
|
|
924
|
+
* a channel post, this DOES wake the target's turn machinery: `turn` is
|
|
925
|
+
* the server's verdict ('started' | 'queued' | 'parked' — the agent-to-
|
|
926
|
+
* agent exchange damper landed the message without waking anyone). */
|
|
927
|
+
export interface SessionDirectMessageSent {
|
|
928
|
+
object: "session_message";
|
|
929
|
+
messageId: string;
|
|
930
|
+
target: { conversationId: string; alias: string | null; title: string | null };
|
|
931
|
+
turn: "started" | "queued" | "parked";
|
|
932
|
+
/** Honest posture line — delivery is not completion. */
|
|
933
|
+
note: string;
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
/** One branch claim, as the claim/release routes serialize it. */
|
|
937
|
+
export interface BranchClaimInfo {
|
|
938
|
+
id: string;
|
|
939
|
+
branch: string;
|
|
940
|
+
targetConversationId: string;
|
|
941
|
+
holderConversationId: string;
|
|
942
|
+
targetLabel: string;
|
|
943
|
+
holderLabel: string;
|
|
944
|
+
reason: string | null;
|
|
945
|
+
claimedAt: string;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
/** Result of `POST /session-branch-claims` — write authority over the
|
|
949
|
+
* target session's drive branch transferred to the calling session, plus
|
|
950
|
+
* the mount material the CLI uses to FUSE-mount the branch in-guest. */
|
|
951
|
+
export interface BranchClaimGranted {
|
|
952
|
+
object: "branch_claim";
|
|
953
|
+
claim: BranchClaimInfo;
|
|
954
|
+
/** True = the caller already held this claim (re-mint / re-mount path). */
|
|
955
|
+
reclaimedOwn: boolean;
|
|
956
|
+
branch: string;
|
|
957
|
+
token: string;
|
|
958
|
+
gatewayWsUrl: string;
|
|
959
|
+
expiresAtS: number;
|
|
960
|
+
diskId: string;
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
/** Result of `POST /session-branch-claims/release` (and the human reclaim
|
|
964
|
+
* door) — the claims this call closed. */
|
|
965
|
+
export interface BranchClaimsReleased {
|
|
966
|
+
object: "branch_claim.release";
|
|
967
|
+
released: BranchClaimInfo[];
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
/** `GET /conversations/:id/branch-claim` — one session's claim state: the
|
|
971
|
+
* live claim ON its branch (null = writable there), and the claims it
|
|
972
|
+
* HOLDS on other sessions' branches. */
|
|
973
|
+
export interface BranchClaimState {
|
|
974
|
+
object: "branch_claim.state";
|
|
975
|
+
claimedBy: BranchClaimInfo | null;
|
|
976
|
+
holds: BranchClaimInfo[];
|
|
977
|
+
}
|
|
978
|
+
|
|
520
979
|
/** One agent on the team, as listed by `GET /api/v1/agents`. Bridge-runtime
|
|
521
980
|
* rows additionally carry live presence (`online`, from the daemon's
|
|
522
981
|
* heartbeat within the server's TTL) and the hosting machine's label. */
|