@robota-sdk/agent-interface-session 3.0.0-beta.81

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.
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./session-capability-contracts-D1Oi21Hn.cjs");function t(e){return e.filter(e=>e.type===`assistant-done`).map(e=>e.fullText)}function n(e){return t(e).at(-1)}function r(e){return e.filter(e=>e.type===`tool-call`).map(e=>({id:e.id,name:e.name,args:e.args}))}function i(e){return e.filter(e=>e.type===`error`).map(e=>e.error)}function a(e){return e instanceof Error&&e.name===`TurnNotRunError`}exports.AGENT_DRIVER_ID=`agent`,exports.OWNER_DRIVER_ID=`owner`,exports.SESSION_CAPABILITY_MEMBER_KEYS=e.t,exports.isTurnNotRunError=a,exports.readAssistantReplies=t,exports.readErrors=i,exports.readLastAssistantText=n,exports.readToolCalls=r;
@@ -0,0 +1,239 @@
1
+ import { $ as TDriverId, A as IGoalEvent, B as TGoalStatus, C as TSessionCapabilityHost, Ct as TCompactTrigger, D as IBranchEvent, E as IAskRequestEvent, F as IPlanApprovalEvent, G as TPlanPhase, H as TInteractiveEventName, I as IPlanArtifact, J as IPeerTurnContext, K as TPlanStepStatus, L as IPlanStep, M as IGoalState, N as IInteractiveSessionEvents, O as IContextFileRefreshedEvent, P as IPermissionRequestEvent, Q as OWNER_DRIVER_ID, R as IPromptResolvedEvent, S as SESSION_CAPABILITY_MEMBER_KEYS, St as ICompactEvent, T as IActiveBranchPointer, U as TInteractivePermissionHandler, V as TGoalStopReason, W as TPermissionResultValue, X as ISubmitOptions, Y as ISessionRenamedEvent, Z as IUiIntentEvent, _ as ISessionPromptResolution, _t as TSkillActivationStatus, a as ISessionBackgroundTasks, at as isTurnNotRunError, b as ISessionTurnSubmission, bt as ISessionLoopState, c as ISessionCommands, ct as IMemoryEvent, d as ISessionEvents, dt as TContextReferenceLoadType, et as IExecutionResult, f as ISessionExecutionState, ft as TContextReferenceStatus, g as ISessionLifecycle, gt as TSkillActivationSource, h as ISessionIdentity, ht as TSkillActivationMode, i as ISessionBackgroundGroups, it as TTurnSource, j as IGoalProgressEntry, k as IDiffLine, l as ISessionConversationRead, lt as IMemoryReference, m as ISessionGoal, mt as TSkillActivationInvocation, n as IInteractiveSessionRecord, nt as ITurnNotRunError, o as ISessionCapabilityHost, ot as IToolSummary, p as ISessionExecutionWorkspace, pt as TMemoryType, q as AGENT_DRIVER_ID, r as ISessionAgentJobs, rt as TTurnNotRunReason, s as ISessionCapabilityMap, st as IContextReferenceItem, t as IInteractiveSession, tt as ITurnHandle, u as ISessionDriverAttribution, ut as ISkillActivationEvent, v as ISessionRuntimeTools, vt as IPromptFileReferenceRecord, w as TSessionCapabilityReadResult, x as ISessionWorkspaceLocation, xt as TSessionLoopPhase, y as ISessionTurnControl, yt as TPromptFileReferenceReason, z as IToolState } from "./session-contracts-BVCzd3uY.cjs";
2
+ import { IActionRequest, TActionResponse } from "@robota-sdk/agent-core";
3
+ //#region src/session-summary-contracts.d.ts
4
+ /** Projection used to render a resume picker. */
5
+ interface IResumableSessionSummary {
6
+ id: string;
7
+ name?: string;
8
+ cwd: string;
9
+ updatedAt: string;
10
+ messageCount: number;
11
+ preview: string;
12
+ }
13
+ //#endregion
14
+ //#region src/session-store-contracts.d.ts
15
+ /**
16
+ * One decode failure, located (TRANS-005).
17
+ *
18
+ * The TYPE lives here with the record it describes; the decoder that produces it is a mechanism and
19
+ * lives with the runtime that owns persistence. `path` is the machine-readable half and is kept
20
+ * separate from the human half on purpose: a caller that must CLASSIFY a failure cannot do it by
21
+ * reading prose. The rendering is dotted for members and bracketed for indices —
22
+ * `messages[2].timestamp` — and is empty at the root.
23
+ */
24
+ interface ISessionRecordDecodeIssue {
25
+ readonly path: string;
26
+ readonly message: string;
27
+ }
28
+ /**
29
+ * What a store concluded about one session id (TRANS-007).
30
+ *
31
+ * ## Why this is not `record | undefined`
32
+ *
33
+ * `undefined` was one value for four different situations — never saved, damaged, written by a build
34
+ * this one cannot read, and the read itself failed — so every consumer had to guess, and they guessed
35
+ * differently. The cost was not only an uninformative read: a consumer that loads a record to
36
+ * preserve the fields it does not own, and then saves, treats "damaged" as "no prior record" and
37
+ * OVERWRITES the damaged file with a fresh one. A type that makes the caller say which outcome it is
38
+ * handling is what stops that, because the compiler asks the question the caller was not asking.
39
+ *
40
+ * `missing` is a member HERE and deliberately not a member of the decoder's outcome: absence is a
41
+ * property of a store, not of a value — a file that is not there never reaches a decoder. This is
42
+ * the store, so it composes its own `missing` with the decoder's three.
43
+ */
44
+ type TSessionLoadOutcome = {
45
+ readonly status: 'valid';
46
+ readonly record: IInteractiveSessionRecord;
47
+ } |
48
+ /** No record for this id. The only outcome from which a recovery path may run. */
49
+ {
50
+ readonly status: 'missing';
51
+ } |
52
+ /** Present and not a session record. Never silently replaced, never overwritten. */
53
+ {
54
+ readonly status: 'corrupt';
55
+ readonly issues: readonly ISessionRecordDecodeIssue[];
56
+ } |
57
+ /** Present and written by a build this one does not read. Carries the version it saw. */
58
+ {
59
+ readonly status: 'unsupported';
60
+ readonly schemaVersion: number | undefined;
61
+ };
62
+ /**
63
+ * One entry in a store listing, carrying WHY it cannot be read when it cannot.
64
+ *
65
+ * A store that distinguishes four outcomes on `load` and then hides two of them from the surface a
66
+ * person browses has moved the defect rather than removed it: the difference a user experiences is
67
+ * between "my session vanished" and "my session needs a different build".
68
+ */
69
+ interface ISessionListEntry {
70
+ readonly id: string;
71
+ readonly outcome: TSessionLoadOutcome;
72
+ }
73
+ /** Persistence port for resumable interactive sessions. */
74
+ interface IInteractiveSessionStore {
75
+ save(session: IInteractiveSessionRecord): void;
76
+ load(id: string): TSessionLoadOutcome;
77
+ list(): readonly ISessionListEntry[];
78
+ delete(id: string): void;
79
+ }
80
+ //#endregion
81
+ //#region src/prompt-history-contracts.d.ts
82
+ /**
83
+ * SCREEN-1993 — prompt history: the prompts a person typed, across sessions and projects, as a
84
+ * derived append-only projection the terminal UI searches. The session record stays the owner of
85
+ * every message; this projection exists so a search never decodes a record and never crosses a
86
+ * workspace boundary.
87
+ */
88
+ /** One prompt as it was typed, with where and when. */
89
+ interface IPromptHistoryEntry {
90
+ /** ISO timestamp of the turn. */
91
+ readonly at: string;
92
+ readonly sessionId: string;
93
+ /** The project key: the workspace identity's worktree root, or the real path of the cwd. */
94
+ readonly project: string;
95
+ /** The typed text, trimmed. */
96
+ readonly text: string;
97
+ }
98
+ /** Appends one entry; a failure is the caller's to report, never swallowed here. */
99
+ interface IPromptHistoryWriter {
100
+ append(entry: IPromptHistoryEntry): void;
101
+ }
102
+ /** One block of a streamed read: entries newest-first, plus the lines the block could not read. */
103
+ interface IPromptHistoryBlock {
104
+ readonly entries: readonly IPromptHistoryEntry[];
105
+ /** Lines in this block that were not a well-formed entry — counted, never silently dropped. */
106
+ readonly skippedLines: number;
107
+ }
108
+ interface IPromptHistoryReadOptions {
109
+ /** Honoured between blocks: an aborted read yields no further block. */
110
+ readonly signal: AbortSignal;
111
+ }
112
+ /** Streams the history newest-first so the most recent prompts render before the rest is read. */
113
+ interface IPromptHistorySource {
114
+ read(options: IPromptHistoryReadOptions): AsyncIterable<IPromptHistoryBlock>;
115
+ }
116
+ //#endregion
117
+ //#region src/interaction-contracts.d.ts
118
+ /** One-way display events pushed by the framework to the channel. */
119
+ type InteractionEvent = {
120
+ type: 'user-message';
121
+ text: string;
122
+ } | {
123
+ type: 'assistant-chunk';
124
+ chunk: string;
125
+ } | {
126
+ type: 'assistant-done';
127
+ fullText: string;
128
+ } | {
129
+ type: 'tool-call';
130
+ id: string;
131
+ name: string;
132
+ args: unknown;
133
+ } | {
134
+ type: 'tool-result';
135
+ id: string;
136
+ name: string;
137
+ result: unknown;
138
+ } | {
139
+ type: 'command-result';
140
+ name: string;
141
+ output: string;
142
+ } | {
143
+ type: 'error';
144
+ error: Error;
145
+ };
146
+ interface ICommandInfo {
147
+ name: string;
148
+ description: string;
149
+ subcommands?: ICommandInfo[];
150
+ }
151
+ interface IInteractionChannel {
152
+ /** Framework registers input handler. Channel calls it when user submits text. */
153
+ onSubmit(handler: (text: string) => Promise<void>): void;
154
+ /** Framework pushes one-way display events. Fire-and-forget. */
155
+ write(event: InteractionEvent): void;
156
+ /**
157
+ * CMD-004 unified ask: request a structured answer (confirm/select/multi/text). The channel renders
158
+ * it per-environment (Ink dialog, web modal, programmatic preset) and resolves when the user answers
159
+ * or cancels. This is the sole "ask the user" seam; commands reach it via the session's ask handler.
160
+ */
161
+ askUser(request: IActionRequest): Promise<TActionResponse>;
162
+ /** Framework provides registered slash commands for autocomplete. */
163
+ setAvailableCommands(commands: ICommandInfo[]): void;
164
+ /** Signal whether session is busy (channel may disable input). */
165
+ setBusy(busy: boolean): void;
166
+ start(): Promise<void>;
167
+ stop(): Promise<void>;
168
+ }
169
+ /** A tool invocation observed from the interaction event stream. */
170
+ interface IToolCallObservation {
171
+ id: string;
172
+ name: string;
173
+ args: unknown;
174
+ }
175
+ /**
176
+ * Client-side interaction contract — the **dual** of {@link IInteractionChannel}. Where
177
+ * `IInteractionChannel` is what the framework *writes to*, `IAgentDriver` is what a **client** uses to
178
+ * *drive* the agent and *observe* its event stream. Implemented by the in-process programmatic driver,
179
+ * the remote client, and a built-binary test driver. Production-grade (embedding apps + the remote
180
+ * client are non-test clients), so it lives next to the framework-side port as the same seam's other
181
+ * face.
182
+ *
183
+ * Observation accessors are NOT methods that each adapter re-implements: an implementer exposes the raw
184
+ * {@link events} stream and delegates the accessors to the shared `read*` helpers below, so the
185
+ * filter/derivation logic exists exactly once.
186
+ */
187
+ interface IAgentDriver {
188
+ /** Start the underlying session/transport. Idempotent — a second call is a no-op. */
189
+ start(): Promise<void>;
190
+ /**
191
+ * Submit a user message. When called serially (await each `send`), resolves after the turn
192
+ * completes; a `send` issued mid-turn is queued and resolves once that queued turn runs.
193
+ */
194
+ send(text: string): Promise<void>;
195
+ /** Pre-answer the next `askUser` (CMD-004 unified ask). */
196
+ queueUserAction(response: TActionResponse): void;
197
+ /** The structured event stream observed from the agent, in order. */
198
+ readonly events: readonly InteractionEvent[];
199
+ /** Every completed assistant reply (`assistant-done` fullTexts), in order. */
200
+ assistantReplies(): string[];
201
+ /** The most recent completed assistant reply, or `undefined` if none yet. */
202
+ lastAssistantText(): string | undefined;
203
+ /** Tool-call observations captured during the run. */
204
+ toolCalls(): IToolCallObservation[];
205
+ /** Errors surfaced by the framework during the run. */
206
+ errors(): Error[];
207
+ /** Stop the underlying session/transport. */
208
+ stop(): Promise<void>;
209
+ }
210
+ /** Completed assistant replies (`assistant-done` fullTexts), in order. */
211
+ declare function readAssistantReplies(events: readonly InteractionEvent[]): string[];
212
+ /** The most recent completed assistant reply, or `undefined`. */
213
+ declare function readLastAssistantText(events: readonly InteractionEvent[]): string | undefined;
214
+ /** Tool-call observations, in order. */
215
+ declare function readToolCalls(events: readonly InteractionEvent[]): IToolCallObservation[];
216
+ /** Errors surfaced in the stream, in order. */
217
+ declare function readErrors(events: readonly InteractionEvent[]): Error[];
218
+ /**
219
+ * Terminal-handoff capability — a transport may optionally hand the real terminal to a child process
220
+ * (interactive input + output via the real TTY) and restore its display afterward.
221
+ *
222
+ * Implemented by interactive transports (e.g. the TUI suspends/resumes its rendering); a headless
223
+ * transport reports `canHandoffTerminal === false`. The contract is **platform-neutral** and never
224
+ * spawns a shell itself — the caller's `fn` spawns whatever child it wants with inherited stdio.
225
+ * (SSOT for the transport contract; agent-framework orchestrates and surfaces it to commands.)
226
+ */
227
+ interface ITerminalHandoff {
228
+ /** Whether an interactive terminal handoff is actually possible (an interactive TTY is present). */
229
+ readonly canHandoffTerminal: boolean;
230
+ /**
231
+ * Suspend the display, run `fn` (the caller spawns its child with inherited stdio), then restore
232
+ * the display — including when `fn` throws. Rejects without running `fn` when
233
+ * `canHandoffTerminal` is `false`.
234
+ */
235
+ runWithTerminal<T>(fn: () => Promise<T>): Promise<T>;
236
+ }
237
+ //#endregion
238
+ export { AGENT_DRIVER_ID, type IActiveBranchPointer, type IAgentDriver, type IAskRequestEvent, type IBranchEvent, type ICommandInfo, type ICompactEvent, type IContextFileRefreshedEvent, type IContextReferenceItem, type IDiffLine, type IExecutionResult, type IGoalEvent, type IGoalProgressEntry, type IGoalState, type IInteractionChannel, type IInteractiveSession, type IInteractiveSessionEvents, type IInteractiveSessionRecord, type IInteractiveSessionStore, type IMemoryEvent, type IMemoryReference, type IPeerTurnContext, type IPermissionRequestEvent, type IPlanApprovalEvent, type IPlanArtifact, type IPlanStep, type IPromptFileReferenceRecord, type IPromptHistoryBlock, type IPromptHistoryEntry, type IPromptHistoryReadOptions, type IPromptHistorySource, type IPromptHistoryWriter, type IPromptResolvedEvent, type IResumableSessionSummary, type ISessionAgentJobs, type ISessionBackgroundGroups, type ISessionBackgroundTasks, type ISessionCapabilityHost, type ISessionCapabilityMap, type ISessionCommands, type ISessionConversationRead, type ISessionDriverAttribution, type ISessionEvents, type ISessionExecutionState, type ISessionExecutionWorkspace, type ISessionGoal, type ISessionIdentity, type ISessionLifecycle, type ISessionListEntry, type ISessionLoopState, type ISessionPromptResolution, type ISessionRecordDecodeIssue, type ISessionRenamedEvent, type ISessionRuntimeTools, type ISessionTurnControl, type ISessionTurnSubmission, type ISessionWorkspaceLocation, type ISkillActivationEvent, type ISubmitOptions, type ITerminalHandoff, type IToolCallObservation, type IToolState, type IToolSummary, type ITurnHandle, type ITurnNotRunError, type IUiIntentEvent, type InteractionEvent, OWNER_DRIVER_ID, SESSION_CAPABILITY_MEMBER_KEYS, type TCompactTrigger, type TContextReferenceLoadType, type TContextReferenceStatus, type TDriverId, type TGoalStatus, type TGoalStopReason, type TInteractiveEventName, type TInteractivePermissionHandler, type TMemoryType, type TPermissionResultValue, type TPlanPhase, type TPlanStepStatus, type TPromptFileReferenceReason, type TSessionCapabilityHost, type TSessionCapabilityReadResult, type TSessionLoadOutcome, type TSessionLoopPhase, type TSkillActivationInvocation, type TSkillActivationMode, type TSkillActivationSource, type TSkillActivationStatus, type TTurnNotRunReason, type TTurnSource, isTurnNotRunError, readAssistantReplies, readErrors, readLastAssistantText, readToolCalls };
239
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/session-summary-contracts.ts","../../src/session-store-contracts.ts","../../src/prompt-history-contracts.ts","../../src/interaction-contracts.ts"],"mappings":";;;;UACiB;EACf;EACA;EACA;EACA;EACA;EACA;;;;;;;;;;;;;UCae;WACN;WACA;;;;;;;;;;;;;;;;;;KAmBC;WACG;WAA0B,QAAQ;;;;WAElC;;;;WAEA;WAA4B,iBAAiB;;;;WAE7C;WAAgC;;;;;;;;;UAS9B;WACN;WACA,SAAS;;;UAIH;EACf,KAAK,SAAS;EACd,KAAK,aAAa;EAClB,iBAAiB;EACjB,OAAO;;;;;;;;;;;UC3DQ;;WAEN;WACA;;WAEA;;WAEA;;;UAIM;EACf,OAAO,OAAO;;;UAIC;WACN,kBAAkB;;WAElB;;UAGM;;WAEN,QAAQ;;;UAIF;EACf,KAAK,SAAS,4BAA4B,cAAc;;;;;KC1B9C;EACN;EAAsB;;EACtB;EAAyB;;EACzB;EAAwB;;EACxB;EAAmB;EAAY;EAAc;;EAC7C;EAAqB;EAAY;EAAc;;EAC/C;EAAwB;EAAc;;EACtC;EAAe,OAAO;;UAEX;EACf;EACA;EACA,cAAc;;UAGC;;EAEf,SAAS,UAAU,iBAAiB;;EAGpC,MAAM,OAAO;;;;;;EAOb,QAAQ,SAAS,iBAAiB,QAAQ;;EAG1C,qBAAqB,UAAU;;EAG/B,QAAQ;EAER,SAAS;EACT,QAAQ;;;UAIO;EACf;EACA;EACA;;;;;;;;;;;;;;UAee;;EAEf,SAAS;;;;;EAKT,KAAK,eAAe;;EAEpB,gBAAgB,UAAU;;WAEjB,iBAAiB;;EAE1B;;EAEA;;EAEA,aAAa;;EAEb,UAAU;;EAEV,QAAQ;;;iBAQM,qBAAqB,iBAAiB;;iBAUtC,sBAAsB,iBAAiB;;iBAKvC,cAAc,iBAAiB,qBAAqB;;iBAOpD,WAAW,iBAAiB,qBAAqB;;;;;;;;;;UAehD;;WAEN;;;;;;EAOT,gBAAgB,GAAG,UAAU,QAAQ,KAAK,QAAQ"}
@@ -0,0 +1,239 @@
1
+ import { $ as TDriverId, A as IGoalEvent, B as TGoalStatus, C as TSessionCapabilityHost, Ct as TCompactTrigger, D as IBranchEvent, E as IAskRequestEvent, F as IPlanApprovalEvent, G as TPlanPhase, H as TInteractiveEventName, I as IPlanArtifact, J as IPeerTurnContext, K as TPlanStepStatus, L as IPlanStep, M as IGoalState, N as IInteractiveSessionEvents, O as IContextFileRefreshedEvent, P as IPermissionRequestEvent, Q as OWNER_DRIVER_ID, R as IPromptResolvedEvent, S as SESSION_CAPABILITY_MEMBER_KEYS, St as ICompactEvent, T as IActiveBranchPointer, U as TInteractivePermissionHandler, V as TGoalStopReason, W as TPermissionResultValue, X as ISubmitOptions, Y as ISessionRenamedEvent, Z as IUiIntentEvent, _ as ISessionPromptResolution, _t as TSkillActivationStatus, a as ISessionBackgroundTasks, at as isTurnNotRunError, b as ISessionTurnSubmission, bt as ISessionLoopState, c as ISessionCommands, ct as IMemoryEvent, d as ISessionEvents, dt as TContextReferenceLoadType, et as IExecutionResult, f as ISessionExecutionState, ft as TContextReferenceStatus, g as ISessionLifecycle, gt as TSkillActivationSource, h as ISessionIdentity, ht as TSkillActivationMode, i as ISessionBackgroundGroups, it as TTurnSource, j as IGoalProgressEntry, k as IDiffLine, l as ISessionConversationRead, lt as IMemoryReference, m as ISessionGoal, mt as TSkillActivationInvocation, n as IInteractiveSessionRecord, nt as ITurnNotRunError, o as ISessionCapabilityHost, ot as IToolSummary, p as ISessionExecutionWorkspace, pt as TMemoryType, q as AGENT_DRIVER_ID, r as ISessionAgentJobs, rt as TTurnNotRunReason, s as ISessionCapabilityMap, st as IContextReferenceItem, t as IInteractiveSession, tt as ITurnHandle, u as ISessionDriverAttribution, ut as ISkillActivationEvent, v as ISessionRuntimeTools, vt as IPromptFileReferenceRecord, w as TSessionCapabilityReadResult, x as ISessionWorkspaceLocation, xt as TSessionLoopPhase, y as ISessionTurnControl, yt as TPromptFileReferenceReason, z as IToolState } from "./session-contracts-BVCzd3uY.js";
2
+ import { IActionRequest, TActionResponse } from "@robota-sdk/agent-core";
3
+ //#region src/session-summary-contracts.d.ts
4
+ /** Projection used to render a resume picker. */
5
+ interface IResumableSessionSummary {
6
+ id: string;
7
+ name?: string;
8
+ cwd: string;
9
+ updatedAt: string;
10
+ messageCount: number;
11
+ preview: string;
12
+ }
13
+ //#endregion
14
+ //#region src/session-store-contracts.d.ts
15
+ /**
16
+ * One decode failure, located (TRANS-005).
17
+ *
18
+ * The TYPE lives here with the record it describes; the decoder that produces it is a mechanism and
19
+ * lives with the runtime that owns persistence. `path` is the machine-readable half and is kept
20
+ * separate from the human half on purpose: a caller that must CLASSIFY a failure cannot do it by
21
+ * reading prose. The rendering is dotted for members and bracketed for indices —
22
+ * `messages[2].timestamp` — and is empty at the root.
23
+ */
24
+ interface ISessionRecordDecodeIssue {
25
+ readonly path: string;
26
+ readonly message: string;
27
+ }
28
+ /**
29
+ * What a store concluded about one session id (TRANS-007).
30
+ *
31
+ * ## Why this is not `record | undefined`
32
+ *
33
+ * `undefined` was one value for four different situations — never saved, damaged, written by a build
34
+ * this one cannot read, and the read itself failed — so every consumer had to guess, and they guessed
35
+ * differently. The cost was not only an uninformative read: a consumer that loads a record to
36
+ * preserve the fields it does not own, and then saves, treats "damaged" as "no prior record" and
37
+ * OVERWRITES the damaged file with a fresh one. A type that makes the caller say which outcome it is
38
+ * handling is what stops that, because the compiler asks the question the caller was not asking.
39
+ *
40
+ * `missing` is a member HERE and deliberately not a member of the decoder's outcome: absence is a
41
+ * property of a store, not of a value — a file that is not there never reaches a decoder. This is
42
+ * the store, so it composes its own `missing` with the decoder's three.
43
+ */
44
+ type TSessionLoadOutcome = {
45
+ readonly status: 'valid';
46
+ readonly record: IInteractiveSessionRecord;
47
+ } |
48
+ /** No record for this id. The only outcome from which a recovery path may run. */
49
+ {
50
+ readonly status: 'missing';
51
+ } |
52
+ /** Present and not a session record. Never silently replaced, never overwritten. */
53
+ {
54
+ readonly status: 'corrupt';
55
+ readonly issues: readonly ISessionRecordDecodeIssue[];
56
+ } |
57
+ /** Present and written by a build this one does not read. Carries the version it saw. */
58
+ {
59
+ readonly status: 'unsupported';
60
+ readonly schemaVersion: number | undefined;
61
+ };
62
+ /**
63
+ * One entry in a store listing, carrying WHY it cannot be read when it cannot.
64
+ *
65
+ * A store that distinguishes four outcomes on `load` and then hides two of them from the surface a
66
+ * person browses has moved the defect rather than removed it: the difference a user experiences is
67
+ * between "my session vanished" and "my session needs a different build".
68
+ */
69
+ interface ISessionListEntry {
70
+ readonly id: string;
71
+ readonly outcome: TSessionLoadOutcome;
72
+ }
73
+ /** Persistence port for resumable interactive sessions. */
74
+ interface IInteractiveSessionStore {
75
+ save(session: IInteractiveSessionRecord): void;
76
+ load(id: string): TSessionLoadOutcome;
77
+ list(): readonly ISessionListEntry[];
78
+ delete(id: string): void;
79
+ }
80
+ //#endregion
81
+ //#region src/prompt-history-contracts.d.ts
82
+ /**
83
+ * SCREEN-1993 — prompt history: the prompts a person typed, across sessions and projects, as a
84
+ * derived append-only projection the terminal UI searches. The session record stays the owner of
85
+ * every message; this projection exists so a search never decodes a record and never crosses a
86
+ * workspace boundary.
87
+ */
88
+ /** One prompt as it was typed, with where and when. */
89
+ interface IPromptHistoryEntry {
90
+ /** ISO timestamp of the turn. */
91
+ readonly at: string;
92
+ readonly sessionId: string;
93
+ /** The project key: the workspace identity's worktree root, or the real path of the cwd. */
94
+ readonly project: string;
95
+ /** The typed text, trimmed. */
96
+ readonly text: string;
97
+ }
98
+ /** Appends one entry; a failure is the caller's to report, never swallowed here. */
99
+ interface IPromptHistoryWriter {
100
+ append(entry: IPromptHistoryEntry): void;
101
+ }
102
+ /** One block of a streamed read: entries newest-first, plus the lines the block could not read. */
103
+ interface IPromptHistoryBlock {
104
+ readonly entries: readonly IPromptHistoryEntry[];
105
+ /** Lines in this block that were not a well-formed entry — counted, never silently dropped. */
106
+ readonly skippedLines: number;
107
+ }
108
+ interface IPromptHistoryReadOptions {
109
+ /** Honoured between blocks: an aborted read yields no further block. */
110
+ readonly signal: AbortSignal;
111
+ }
112
+ /** Streams the history newest-first so the most recent prompts render before the rest is read. */
113
+ interface IPromptHistorySource {
114
+ read(options: IPromptHistoryReadOptions): AsyncIterable<IPromptHistoryBlock>;
115
+ }
116
+ //#endregion
117
+ //#region src/interaction-contracts.d.ts
118
+ /** One-way display events pushed by the framework to the channel. */
119
+ type InteractionEvent = {
120
+ type: 'user-message';
121
+ text: string;
122
+ } | {
123
+ type: 'assistant-chunk';
124
+ chunk: string;
125
+ } | {
126
+ type: 'assistant-done';
127
+ fullText: string;
128
+ } | {
129
+ type: 'tool-call';
130
+ id: string;
131
+ name: string;
132
+ args: unknown;
133
+ } | {
134
+ type: 'tool-result';
135
+ id: string;
136
+ name: string;
137
+ result: unknown;
138
+ } | {
139
+ type: 'command-result';
140
+ name: string;
141
+ output: string;
142
+ } | {
143
+ type: 'error';
144
+ error: Error;
145
+ };
146
+ interface ICommandInfo {
147
+ name: string;
148
+ description: string;
149
+ subcommands?: ICommandInfo[];
150
+ }
151
+ interface IInteractionChannel {
152
+ /** Framework registers input handler. Channel calls it when user submits text. */
153
+ onSubmit(handler: (text: string) => Promise<void>): void;
154
+ /** Framework pushes one-way display events. Fire-and-forget. */
155
+ write(event: InteractionEvent): void;
156
+ /**
157
+ * CMD-004 unified ask: request a structured answer (confirm/select/multi/text). The channel renders
158
+ * it per-environment (Ink dialog, web modal, programmatic preset) and resolves when the user answers
159
+ * or cancels. This is the sole "ask the user" seam; commands reach it via the session's ask handler.
160
+ */
161
+ askUser(request: IActionRequest): Promise<TActionResponse>;
162
+ /** Framework provides registered slash commands for autocomplete. */
163
+ setAvailableCommands(commands: ICommandInfo[]): void;
164
+ /** Signal whether session is busy (channel may disable input). */
165
+ setBusy(busy: boolean): void;
166
+ start(): Promise<void>;
167
+ stop(): Promise<void>;
168
+ }
169
+ /** A tool invocation observed from the interaction event stream. */
170
+ interface IToolCallObservation {
171
+ id: string;
172
+ name: string;
173
+ args: unknown;
174
+ }
175
+ /**
176
+ * Client-side interaction contract — the **dual** of {@link IInteractionChannel}. Where
177
+ * `IInteractionChannel` is what the framework *writes to*, `IAgentDriver` is what a **client** uses to
178
+ * *drive* the agent and *observe* its event stream. Implemented by the in-process programmatic driver,
179
+ * the remote client, and a built-binary test driver. Production-grade (embedding apps + the remote
180
+ * client are non-test clients), so it lives next to the framework-side port as the same seam's other
181
+ * face.
182
+ *
183
+ * Observation accessors are NOT methods that each adapter re-implements: an implementer exposes the raw
184
+ * {@link events} stream and delegates the accessors to the shared `read*` helpers below, so the
185
+ * filter/derivation logic exists exactly once.
186
+ */
187
+ interface IAgentDriver {
188
+ /** Start the underlying session/transport. Idempotent — a second call is a no-op. */
189
+ start(): Promise<void>;
190
+ /**
191
+ * Submit a user message. When called serially (await each `send`), resolves after the turn
192
+ * completes; a `send` issued mid-turn is queued and resolves once that queued turn runs.
193
+ */
194
+ send(text: string): Promise<void>;
195
+ /** Pre-answer the next `askUser` (CMD-004 unified ask). */
196
+ queueUserAction(response: TActionResponse): void;
197
+ /** The structured event stream observed from the agent, in order. */
198
+ readonly events: readonly InteractionEvent[];
199
+ /** Every completed assistant reply (`assistant-done` fullTexts), in order. */
200
+ assistantReplies(): string[];
201
+ /** The most recent completed assistant reply, or `undefined` if none yet. */
202
+ lastAssistantText(): string | undefined;
203
+ /** Tool-call observations captured during the run. */
204
+ toolCalls(): IToolCallObservation[];
205
+ /** Errors surfaced by the framework during the run. */
206
+ errors(): Error[];
207
+ /** Stop the underlying session/transport. */
208
+ stop(): Promise<void>;
209
+ }
210
+ /** Completed assistant replies (`assistant-done` fullTexts), in order. */
211
+ declare function readAssistantReplies(events: readonly InteractionEvent[]): string[];
212
+ /** The most recent completed assistant reply, or `undefined`. */
213
+ declare function readLastAssistantText(events: readonly InteractionEvent[]): string | undefined;
214
+ /** Tool-call observations, in order. */
215
+ declare function readToolCalls(events: readonly InteractionEvent[]): IToolCallObservation[];
216
+ /** Errors surfaced in the stream, in order. */
217
+ declare function readErrors(events: readonly InteractionEvent[]): Error[];
218
+ /**
219
+ * Terminal-handoff capability — a transport may optionally hand the real terminal to a child process
220
+ * (interactive input + output via the real TTY) and restore its display afterward.
221
+ *
222
+ * Implemented by interactive transports (e.g. the TUI suspends/resumes its rendering); a headless
223
+ * transport reports `canHandoffTerminal === false`. The contract is **platform-neutral** and never
224
+ * spawns a shell itself — the caller's `fn` spawns whatever child it wants with inherited stdio.
225
+ * (SSOT for the transport contract; agent-framework orchestrates and surfaces it to commands.)
226
+ */
227
+ interface ITerminalHandoff {
228
+ /** Whether an interactive terminal handoff is actually possible (an interactive TTY is present). */
229
+ readonly canHandoffTerminal: boolean;
230
+ /**
231
+ * Suspend the display, run `fn` (the caller spawns its child with inherited stdio), then restore
232
+ * the display — including when `fn` throws. Rejects without running `fn` when
233
+ * `canHandoffTerminal` is `false`.
234
+ */
235
+ runWithTerminal<T>(fn: () => Promise<T>): Promise<T>;
236
+ }
237
+ //#endregion
238
+ export { AGENT_DRIVER_ID, type IActiveBranchPointer, type IAgentDriver, type IAskRequestEvent, type IBranchEvent, type ICommandInfo, type ICompactEvent, type IContextFileRefreshedEvent, type IContextReferenceItem, type IDiffLine, type IExecutionResult, type IGoalEvent, type IGoalProgressEntry, type IGoalState, type IInteractionChannel, type IInteractiveSession, type IInteractiveSessionEvents, type IInteractiveSessionRecord, type IInteractiveSessionStore, type IMemoryEvent, type IMemoryReference, type IPeerTurnContext, type IPermissionRequestEvent, type IPlanApprovalEvent, type IPlanArtifact, type IPlanStep, type IPromptFileReferenceRecord, type IPromptHistoryBlock, type IPromptHistoryEntry, type IPromptHistoryReadOptions, type IPromptHistorySource, type IPromptHistoryWriter, type IPromptResolvedEvent, type IResumableSessionSummary, type ISessionAgentJobs, type ISessionBackgroundGroups, type ISessionBackgroundTasks, type ISessionCapabilityHost, type ISessionCapabilityMap, type ISessionCommands, type ISessionConversationRead, type ISessionDriverAttribution, type ISessionEvents, type ISessionExecutionState, type ISessionExecutionWorkspace, type ISessionGoal, type ISessionIdentity, type ISessionLifecycle, type ISessionListEntry, type ISessionLoopState, type ISessionPromptResolution, type ISessionRecordDecodeIssue, type ISessionRenamedEvent, type ISessionRuntimeTools, type ISessionTurnControl, type ISessionTurnSubmission, type ISessionWorkspaceLocation, type ISkillActivationEvent, type ISubmitOptions, type ITerminalHandoff, type IToolCallObservation, type IToolState, type IToolSummary, type ITurnHandle, type ITurnNotRunError, type IUiIntentEvent, type InteractionEvent, OWNER_DRIVER_ID, SESSION_CAPABILITY_MEMBER_KEYS, type TCompactTrigger, type TContextReferenceLoadType, type TContextReferenceStatus, type TDriverId, type TGoalStatus, type TGoalStopReason, type TInteractiveEventName, type TInteractivePermissionHandler, type TMemoryType, type TPermissionResultValue, type TPlanPhase, type TPlanStepStatus, type TPromptFileReferenceReason, type TSessionCapabilityHost, type TSessionCapabilityReadResult, type TSessionLoadOutcome, type TSessionLoopPhase, type TSkillActivationInvocation, type TSkillActivationMode, type TSkillActivationSource, type TSkillActivationStatus, type TTurnNotRunReason, type TTurnSource, isTurnNotRunError, readAssistantReplies, readErrors, readLastAssistantText, readToolCalls };
239
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/session-summary-contracts.ts","../../src/session-store-contracts.ts","../../src/prompt-history-contracts.ts","../../src/interaction-contracts.ts"],"mappings":";;;;UACiB;EACf;EACA;EACA;EACA;EACA;EACA;;;;;;;;;;;;;UCae;WACN;WACA;;;;;;;;;;;;;;;;;;KAmBC;WACG;WAA0B,QAAQ;;;;WAElC;;;;WAEA;WAA4B,iBAAiB;;;;WAE7C;WAAgC;;;;;;;;;UAS9B;WACN;WACA,SAAS;;;UAIH;EACf,KAAK,SAAS;EACd,KAAK,aAAa;EAClB,iBAAiB;EACjB,OAAO;;;;;;;;;;;UC3DQ;;WAEN;WACA;;WAEA;;WAEA;;;UAIM;EACf,OAAO,OAAO;;;UAIC;WACN,kBAAkB;;WAElB;;UAGM;;WAEN,QAAQ;;;UAIF;EACf,KAAK,SAAS,4BAA4B,cAAc;;;;;KC1B9C;EACN;EAAsB;;EACtB;EAAyB;;EACzB;EAAwB;;EACxB;EAAmB;EAAY;EAAc;;EAC7C;EAAqB;EAAY;EAAc;;EAC/C;EAAwB;EAAc;;EACtC;EAAe,OAAO;;UAEX;EACf;EACA;EACA,cAAc;;UAGC;;EAEf,SAAS,UAAU,iBAAiB;;EAGpC,MAAM,OAAO;;;;;;EAOb,QAAQ,SAAS,iBAAiB,QAAQ;;EAG1C,qBAAqB,UAAU;;EAG/B,QAAQ;EAER,SAAS;EACT,QAAQ;;;UAIO;EACf;EACA;EACA;;;;;;;;;;;;;;UAee;;EAEf,SAAS;;;;;EAKT,KAAK,eAAe;;EAEpB,gBAAgB,UAAU;;WAEjB,iBAAiB;;EAE1B;;EAEA;;EAEA,aAAa;;EAEb,UAAU;;EAEV,QAAQ;;;iBAQM,qBAAqB,iBAAiB;;iBAUtC,sBAAsB,iBAAiB;;iBAKvC,cAAc,iBAAiB,qBAAqB;;iBAOpD,WAAW,iBAAiB,qBAAqB;;;;;;;;;;UAehD;;WAEN;;;;;;EAOT,gBAAgB,GAAG,UAAU,QAAQ,KAAK,QAAQ"}
@@ -0,0 +1,2 @@
1
+ import{t as e}from"./session-capability-contracts-LonmBQKB.js";const t=`owner`,n=`agent`;function r(e){return e.filter(e=>e.type===`assistant-done`).map(e=>e.fullText)}function i(e){return r(e).at(-1)}function a(e){return e.filter(e=>e.type===`tool-call`).map(e=>({id:e.id,name:e.name,args:e.args}))}function o(e){return e.filter(e=>e.type===`error`).map(e=>e.error)}function s(e){return e instanceof Error&&e.name===`TurnNotRunError`}export{n as AGENT_DRIVER_ID,t as OWNER_DRIVER_ID,e as SESSION_CAPABILITY_MEMBER_KEYS,s as isTurnNotRunError,r as readAssistantReplies,o as readErrors,i as readLastAssistantText,a as readToolCalls};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/driver-contracts.ts","../../src/interaction-contracts.ts","../../src/turn-contracts.ts"],"sourcesContent":["/**\n * Driver-identity contracts (REMOTE-014 E5) and driver-routed command events (CMD-004 Phase 2).\n *\n * SSOT for the co-drive attribution id and the events that are routed/attributed by it. Split from\n * `session-contracts.ts` (which re-consumes these for the session surface and event map).\n */\n\nimport type { ITurnHandle, TTurnSource } from './turn-contracts.js';\nimport type { TUsageSurface } from '@robota-sdk/agent-interface-analytics';\nimport type { TCommandUiIntent } from '@robota-sdk/agent-interface-command';\n\n/**\n * REMOTE-014 E5 co-drive attribution: a stable, SERVER-ASSIGNED id for the driver of an input/turn. It is\n * DISPLAY/ATTRIBUTION ONLY — never an authorization input (the OWNER PRINCIPLE, REMOTE-006, governs\n * authorization; remote == local). Remote = the E3 `deviceId`; local = {@link OWNER_DRIVER_ID}; an\n * agent-wakeup/goal turn = {@link AGENT_DRIVER_ID}.\n */\nexport type TDriverId = string;\n\n/** The local operator (\"owner\") driver id — the default for a human turn with no explicit driver. */\nexport const OWNER_DRIVER_ID: TDriverId = 'owner';\n/** The reserved driver id for an autonomous (wakeup/goal/agent-initiated) turn — never the owner. */\nexport const AGENT_DRIVER_ID: TDriverId = 'agent';\n\n/** REMOTE-014 E5: options for `submit` — carries the SERVER-ASSIGNED driver id for co-drive attribution. */\nexport interface ISubmitOptions {\n /** Cancels only this submission, including while queued or preparing its turn. */\n readonly signal?: AbortSignal;\n readonly driverId?: TDriverId;\n /** Trusted product surface that accepted this turn; independent from the driver's identity. */\n readonly surface?: TUsageSurface;\n /**\n * PEER-002 (#1809): where this turn came from, when it is not an ordinary user prompt.\n *\n * Carried here beside `driverId` because it is the same KIND of fact and travels with it: both\n * describe the turn's origin, both are set by whoever accepted the submission, and neither is an\n * authorization input. What stops a caller from simply declaring itself a peer is not this field\n * — it is that a `'peer'` turn is REFUSED unless it also names the peer's driver id, so the\n * origin cannot be claimed without also being attributed.\n */\n readonly turnSource?: TTurnSource;\n /**\n * Called once, synchronously, the moment the submission is accepted — queued behind a running\n * turn or about to run — with the handle `submit` will later resolve to.\n *\n * `submit` on an idle session resolves only after the turn it started has finished, so a caller\n * that must answer as soon as the input is taken (a peer's delivery ack) cannot learn acceptance\n * from the returned promise. It must not throw: the turn is already accepted when it runs.\n */\n readonly onAccepted?: (handle: ITurnHandle) => void;\n /** A `'peer'` turn only: which message it answers and where an answer to it goes. */\n readonly peer?: IPeerTurnContext;\n}\n\n/**\n * What a peer turn needs beyond who sent it: the route of the answer. Set by the host that admitted\n * the message, never taken from it. A reply goes to `replyTo` and names `messageId`, so the model can\n * answer only the session that asked, and the asker can thread the answer. It grants nothing: what\n * the turn may do is the session's ordinary permissions' to decide.\n */\nexport interface IPeerTurnContext {\n /** The id of the message this turn answers. */\n readonly messageId: string;\n /** The session id a reply goes to: the sender's. */\n readonly replyTo: string;\n}\n\n/**\n * CMD-004 Phase 2: a command-issued UI intent, emitted as a fire-and-forget `ui_intent` session\n * event. Routed to the REQUESTING surface: `requesterDriverId` is stamped from the command-origin\n * driver id passed into `executeCommand` (the REMOTE-014 E5 server-assigned id for remote surfaces;\n * the active turn's driver only as a fallback for model-invoked commands). Other surfaces ignore it;\n * an intent needs no answer (no parking, no response promise). Serializable.\n */\nexport interface IUiIntentEvent {\n intent: TCommandUiIntent;\n /** The server-assigned driver id of the surface that issued the command (routing/display-only). */\n requesterDriverId?: TDriverId;\n}\n\n/**\n * CMD-004 Phase 2: the session was renamed (host-executed `session-rename` action). Broadcast so\n * every attached surface — including co-driving ones — updates its title. Serializable.\n */\nexport interface ISessionRenamedEvent {\n name: string;\n}\n","/**\n * Interaction-channel contracts — the request/response and display-event surface\n * between the assembly layer and transport channels.\n *\n * SSOT shared by agent-framework (createInteractiveRuntime) and agent-transport channels.\n */\n\n// CMD-004 unified action contract (SSOT in agent-core).\nimport type { IActionRequest, TActionResponse } from '@robota-sdk/agent-core';\n\n/** One-way display events pushed by the framework to the channel. */\nexport type InteractionEvent =\n | { type: 'user-message'; text: string }\n | { type: 'assistant-chunk'; chunk: string }\n | { type: 'assistant-done'; fullText: string }\n | { type: 'tool-call'; id: string; name: string; args: unknown }\n | { type: 'tool-result'; id: string; name: string; result: unknown }\n | { type: 'command-result'; name: string; output: string }\n | { type: 'error'; error: Error };\n\nexport interface ICommandInfo {\n name: string;\n description: string;\n subcommands?: ICommandInfo[];\n}\n\nexport interface IInteractionChannel {\n /** Framework registers input handler. Channel calls it when user submits text. */\n onSubmit(handler: (text: string) => Promise<void>): void;\n\n /** Framework pushes one-way display events. Fire-and-forget. */\n write(event: InteractionEvent): void;\n\n /**\n * CMD-004 unified ask: request a structured answer (confirm/select/multi/text). The channel renders\n * it per-environment (Ink dialog, web modal, programmatic preset) and resolves when the user answers\n * or cancels. This is the sole \"ask the user\" seam; commands reach it via the session's ask handler.\n */\n askUser(request: IActionRequest): Promise<TActionResponse>;\n\n /** Framework provides registered slash commands for autocomplete. */\n setAvailableCommands(commands: ICommandInfo[]): void;\n\n /** Signal whether session is busy (channel may disable input). */\n setBusy(busy: boolean): void;\n\n start(): Promise<void>;\n stop(): Promise<void>;\n}\n\n/** A tool invocation observed from the interaction event stream. */\nexport interface IToolCallObservation {\n id: string;\n name: string;\n args: unknown;\n}\n\n/**\n * Client-side interaction contract — the **dual** of {@link IInteractionChannel}. Where\n * `IInteractionChannel` is what the framework *writes to*, `IAgentDriver` is what a **client** uses to\n * *drive* the agent and *observe* its event stream. Implemented by the in-process programmatic driver,\n * the remote client, and a built-binary test driver. Production-grade (embedding apps + the remote\n * client are non-test clients), so it lives next to the framework-side port as the same seam's other\n * face.\n *\n * Observation accessors are NOT methods that each adapter re-implements: an implementer exposes the raw\n * {@link events} stream and delegates the accessors to the shared `read*` helpers below, so the\n * filter/derivation logic exists exactly once.\n */\nexport interface IAgentDriver {\n /** Start the underlying session/transport. Idempotent — a second call is a no-op. */\n start(): Promise<void>;\n /**\n * Submit a user message. When called serially (await each `send`), resolves after the turn\n * completes; a `send` issued mid-turn is queued and resolves once that queued turn runs.\n */\n send(text: string): Promise<void>;\n /** Pre-answer the next `askUser` (CMD-004 unified ask). */\n queueUserAction(response: TActionResponse): void;\n /** The structured event stream observed from the agent, in order. */\n readonly events: readonly InteractionEvent[];\n /** Every completed assistant reply (`assistant-done` fullTexts), in order. */\n assistantReplies(): string[];\n /** The most recent completed assistant reply, or `undefined` if none yet. */\n lastAssistantText(): string | undefined;\n /** Tool-call observations captured during the run. */\n toolCalls(): IToolCallObservation[];\n /** Errors surfaced by the framework during the run. */\n errors(): Error[];\n /** Stop the underlying session/transport. */\n stop(): Promise<void>;\n}\n\n// ── Shared pure accessors over an InteractionEvent stream ────────────────────────────────\n// The single home for \"what counts as a reply / tool call / error\". Every IAgentDriver implementer\n// delegates to these; no adapter re-implements the discriminated-union filters.\n\n/** Completed assistant replies (`assistant-done` fullTexts), in order. */\nexport function readAssistantReplies(events: readonly InteractionEvent[]): string[] {\n return events\n .filter(\n (e): e is Extract<InteractionEvent, { type: 'assistant-done' }> =>\n e.type === 'assistant-done',\n )\n .map((e) => e.fullText);\n}\n\n/** The most recent completed assistant reply, or `undefined`. */\nexport function readLastAssistantText(events: readonly InteractionEvent[]): string | undefined {\n return readAssistantReplies(events).at(-1);\n}\n\n/** Tool-call observations, in order. */\nexport function readToolCalls(events: readonly InteractionEvent[]): IToolCallObservation[] {\n return events\n .filter((e): e is Extract<InteractionEvent, { type: 'tool-call' }> => e.type === 'tool-call')\n .map((e) => ({ id: e.id, name: e.name, args: e.args }));\n}\n\n/** Errors surfaced in the stream, in order. */\nexport function readErrors(events: readonly InteractionEvent[]): Error[] {\n return events\n .filter((e): e is Extract<InteractionEvent, { type: 'error' }> => e.type === 'error')\n .map((e) => e.error);\n}\n\n/**\n * Terminal-handoff capability — a transport may optionally hand the real terminal to a child process\n * (interactive input + output via the real TTY) and restore its display afterward.\n *\n * Implemented by interactive transports (e.g. the TUI suspends/resumes its rendering); a headless\n * transport reports `canHandoffTerminal === false`. The contract is **platform-neutral** and never\n * spawns a shell itself — the caller's `fn` spawns whatever child it wants with inherited stdio.\n * (SSOT for the transport contract; agent-framework orchestrates and surfaces it to commands.)\n */\nexport interface ITerminalHandoff {\n /** Whether an interactive terminal handoff is actually possible (an interactive TTY is present). */\n readonly canHandoffTerminal: boolean;\n\n /**\n * Suspend the display, run `fn` (the caller spawns its child with inherited stdio), then restore\n * the display — including when `fn` throws. Rejects without running `fn` when\n * `canHandoffTerminal` is `false`.\n */\n runWithTerminal<T>(fn: () => Promise<T>): Promise<T>;\n}\n","/**\n * RUNTIME-003 — the identity of one submission, and the ways it can end.\n *\n * Split out of `session-contracts.ts`, which had grown past its size ratchet: turn identity is its\n * own subject, and the rule is to split rather than extend. Everything here is a TYPE — this package\n * is inert by rule, so the error is declared as a shape and constructed in `@robota-sdk/agent-framework`.\n */\n\nimport type { IPromptFileReferenceRecord } from './prompt-file-reference-types.js';\nimport type { IToolSummary } from './tool-summary-types.js';\nimport type { IContextWindowState, IHistoryEntry } from '@robota-sdk/agent-core';\nimport type { IUsageSnapshot } from '@robota-sdk/agent-interface-analytics';\n\n/**\n * RUNTIME-003: the identity of one submission, handed back to whoever made it.\n *\n * Without this a subscriber has only the session-global `complete` / `interrupted` / `error` events,\n * which say that A turn ended and never which one. Two callers listening at once are answered by\n * whichever fires first — measured in the MCP adapter, where the second `submit` was handed the\n * running turn's response as its own.\n *\n * `completed` ALWAYS settles, and that is the part worth stating. A session runs one turn at a time\n * and queues the rest, and a queued submission does not always get to run: the co-drive queue\n * coalesces a same-driver entry into the one behind it and drops at capacity. A handle that only\n * settled for submissions that ran would leave the others waiting forever, which is the hang this\n * type exists to make impossible — so a submission that never runs REJECTS with `TurnNotRunError`\n * and says which of those happened.\n */\nexport interface ITurnHandle {\n /** Minted when the submission is accepted, and kept if it waits in the queue before running. */\n readonly turnId: string;\n /** Resolves with THIS submission's result; rejects with `TurnNotRunError` if it never ran. */\n readonly completed: Promise<IExecutionResult>;\n}\n\n/** Why a submission never became a turn. */\nexport type TTurnNotRunReason =\n /** A later same-driver input replaced it in the queue (tail-coalesce). */\n | 'coalesced'\n /** The queue was at capacity when it arrived. */\n | 'dropped'\n /**\n * The queue was cleared before it ran — abort, cancel, or session shutdown.\n *\n * A separate `'shutdown'` member was declared here and never produced: shutdown clears the queue\n * through the same `clearPendingQueue`, so every entry it discards is already reported as\n * cancelled. Review found it, and a vocabulary member no code path can emit is a promise to the\n * consumer that nothing keeps — it would have them writing a branch that never runs.\n */\n | 'cancelled';\n\n/**\n * The error a rejected `ITurnHandle.completed` carries.\n *\n * Declared as a SHAPE here and constructed in `@robota-sdk/agent-framework`, because an interface\n * package is inert by rule — no classes, no runtime dependency edges. A consumer narrows on `name`\n * and reads `reason`; it does not need the constructor to do that.\n */\nexport interface ITurnNotRunError extends Error {\n readonly name: 'TurnNotRunError';\n readonly turnId: string;\n readonly reason: TTurnNotRunReason;\n}\n\n/**\n * Is this rejection the declared \"the turn never ran\" outcome, or a real failure?\n *\n * The narrowing the comment above prescribes, written ONCE. A consumer that catches\n * `completed`'s rejection has two different things in hand: an ordinary refusal, which it should\n * report to its caller as an outcome, and an exception from inside a turn, which it should let\n * surface. Review found the MCP adapter flattening both into a soft tool error and so hiding real\n * bugs behind a message that reads like a queue decision.\n *\n * A pure predicate over a shape — no class, no runtime dependency edge, the same category as the\n * event readers this package already exports. Each consumer spelling `error.name ===\n * 'TurnNotRunError'` for itself is how a second spelling of the same question appears, and then\n * disagrees.\n */\nexport function isTurnNotRunError(error: unknown): error is ITurnNotRunError {\n return error instanceof Error && error.name === 'TurnNotRunError';\n}\n\n/** Result of a completed prompt execution. */\nexport interface IExecutionResult {\n response: string;\n /** Present only when an aborted turn resolved with a partial result; never a successful reply. */\n interrupted?: true;\n history: IHistoryEntry[];\n toolSummaries: IToolSummary[];\n contextState: IContextWindowState;\n usage?: IUsageSnapshot;\n promptFileReferences?: IPromptFileReferenceRecord[];\n}\n\n/**\n * Origin of a turn — a human prompt, an agent-wakeup re-entry (FLOW-002), another session's\n * message (PEER-002, #1809), or a host-admitted external event (#1997).\n *\n * `'peer'` is a MEMBER rather than something a caller encodes into the prompt text, because #1809\n * requires a peer message to reach the runtime with EXPLICIT origin: an agent answering a peer must\n * be able to tell that it is answering a peer rather than its own operator, and prose inside the\n * input is not something code can branch on. WHICH peer it was travels in `driverId`, which stays\n * display attribution and never becomes an authorization input.\n *\n * Declared here rather than in `session-contracts.ts`, where it used to live: that file is at its\n * size ratchet and the rule is to split rather than extend, and turn origin belongs to turn identity\n * — the same reasoning that created this file.\n */\nexport type TTurnSource = 'user' | 'agent-wakeup' | 'peer' | 'external';\n"],"mappings":"+DAoBA,MAAa,EAA6B,QAE7B,EAA6B,QC4E1C,SAAgB,EAAqB,EAA+C,CAClF,OAAO,EACJ,OACE,GACC,EAAE,OAAS,gBACf,CAAC,CACA,IAAK,GAAM,EAAE,QAAQ,CAC1B,CAGA,SAAgB,EAAsB,EAAyD,CAC7F,OAAO,EAAqB,CAAM,CAAC,CAAC,GAAG,EAAE,CAC3C,CAGA,SAAgB,EAAc,EAA6D,CACzF,OAAO,EACJ,OAAQ,GAA6D,EAAE,OAAS,WAAW,CAAC,CAC5F,IAAK,IAAO,CAAE,GAAI,EAAE,GAAI,KAAM,EAAE,KAAM,KAAM,EAAE,IAAK,EAAE,CAC1D,CAGA,SAAgB,EAAW,EAA8C,CACvE,OAAO,EACJ,OAAQ,GAAyD,EAAE,OAAS,OAAO,CAAC,CACpF,IAAK,GAAM,EAAE,KAAK,CACvB,CC9CA,SAAgB,EAAkB,EAA2C,CAC3E,OAAO,aAAiB,OAAS,EAAM,OAAS,iBAClD"}
@@ -0,0 +1 @@
1
+ const e=Object.freeze({lifecycle:Object.freeze([`isInitialized`,`shutdown`]),turnSubmission:Object.freeze([`submit`]),turnControl:Object.freeze([`abort`,`cancelQueue`]),goal:Object.freeze([`setGoal`,`getGoalState`,`cancelGoal`]),executionState:Object.freeze([`isExecuting`,`getPendingPrompt`,`getPendingCount`]),driverAttribution:Object.freeze([`getActiveDriverId`]),conversationRead:Object.freeze([`getMessages`,`getContextState`]),identity:Object.freeze([`getSession`]),workspaceLocation:Object.freeze([`getCwd`]),commands:Object.freeze([`executeCommand`,`listCommands`]),runtimeTools:Object.freeze([`listRuntimeTools`,`invokeRuntimeTool`]),events:Object.freeze([`on`,`off`]),promptResolution:Object.freeze([`resolvePermission`,`resolveAsk`]),backgroundTasks:Object.freeze([`listBackgroundTasks`,`getBackgroundTask`,`cancelBackgroundTask`,`closeBackgroundTask`,`sendBackgroundTask`,`readBackgroundTaskLog`]),backgroundGroups:Object.freeze([`listBackgroundJobGroups`,`getBackgroundJobGroup`,`createBackgroundJobGroup`,`waitBackgroundJobGroup`]),executionWorkspace:Object.freeze([`getExecutionWorkspaceSnapshot`]),agentJobs:Object.freeze([`listAgentDefinitions`,`listAgentJobs`,`spawnAgentJob`,`sendAgentJob`,`cancelAgentJob`,`closeAgentJob`])});Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return e}});
@@ -0,0 +1,2 @@
1
+ const e=Object.freeze({lifecycle:Object.freeze([`isInitialized`,`shutdown`]),turnSubmission:Object.freeze([`submit`]),turnControl:Object.freeze([`abort`,`cancelQueue`]),goal:Object.freeze([`setGoal`,`getGoalState`,`cancelGoal`]),executionState:Object.freeze([`isExecuting`,`getPendingPrompt`,`getPendingCount`]),driverAttribution:Object.freeze([`getActiveDriverId`]),conversationRead:Object.freeze([`getMessages`,`getContextState`]),identity:Object.freeze([`getSession`]),workspaceLocation:Object.freeze([`getCwd`]),commands:Object.freeze([`executeCommand`,`listCommands`]),runtimeTools:Object.freeze([`listRuntimeTools`,`invokeRuntimeTool`]),events:Object.freeze([`on`,`off`]),promptResolution:Object.freeze([`resolvePermission`,`resolveAsk`]),backgroundTasks:Object.freeze([`listBackgroundTasks`,`getBackgroundTask`,`cancelBackgroundTask`,`closeBackgroundTask`,`sendBackgroundTask`,`readBackgroundTaskLog`]),backgroundGroups:Object.freeze([`listBackgroundJobGroups`,`getBackgroundJobGroup`,`createBackgroundJobGroup`,`waitBackgroundJobGroup`]),executionWorkspace:Object.freeze([`getExecutionWorkspaceSnapshot`]),agentJobs:Object.freeze([`listAgentDefinitions`,`listAgentJobs`,`spawnAgentJob`,`sendAgentJob`,`cancelAgentJob`,`closeAgentJob`])});export{e as t};
2
+ //# sourceMappingURL=session-capability-contracts-LonmBQKB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-capability-contracts-LonmBQKB.js","names":[],"sources":["../../src/session-capability-contracts.ts"],"sourcesContent":["import type { ISubmitOptions, TDriverId } from './driver-contracts.js';\nimport type {\n IGoalState,\n IInteractiveSessionEvents,\n TInteractiveEventName,\n TPermissionResultValue,\n} from './session-event-map.js';\nimport type { ITurnHandle } from './turn-contracts.js';\nimport type {\n IContextWindowState,\n IToolSchema,\n IToolExecutionResult,\n TToolParameters,\n TActionResponse,\n TUniversalMessage,\n} from '@robota-sdk/agent-core';\nimport type {\n ICommandListEntry,\n ICommandResult,\n TCommandInvocationSource,\n} from '@robota-sdk/agent-interface-command';\nimport type { ISubagentJobState } from '@robota-sdk/agent-interface-execution';\nimport type {\n IExecutionWorkspaceSnapshot,\n IExecutionWorkspaceSnapshotOptions,\n} from '@robota-sdk/agent-interface-execution';\nimport type {\n IBackgroundTaskInput,\n IBackgroundTaskListFilter,\n IBackgroundTaskLogCursor,\n IBackgroundTaskLogPage,\n IBackgroundTaskState,\n TBackgroundTaskIsolation,\n} from '@robota-sdk/agent-interface-execution';\nimport type {\n IBackgroundJobGroupCreateRequest,\n IBackgroundJobGroupState,\n} from '@robota-sdk/agent-interface-execution';\n\nexport interface ISessionLifecycle {\n /** True once the underlying session has been initialized. */\n readonly isInitialized: boolean;\n shutdown(options?: { reason?: string; message?: string }): Promise<void>;\n}\n\nexport interface ISessionTurnSubmission {\n submit(\n input: string,\n displayInput?: string,\n rawInput?: string,\n options?: ISubmitOptions,\n ): Promise<ITurnHandle>;\n}\n\nexport interface ISessionTurnControl {\n abort(): void;\n cancelQueue(): void;\n}\n\nexport interface ISessionGoal {\n setGoal(\n objective: string,\n options?: { maxIterations?: number; noProgressLimit?: number },\n ): Promise<IGoalState>;\n getGoalState(): IGoalState | null;\n cancelGoal(): IGoalState | null;\n}\n\nexport interface ISessionExecutionState {\n isExecuting(): boolean;\n getPendingPrompt(): string | null;\n getPendingCount(): number;\n}\n\nexport interface ISessionDriverAttribution {\n getActiveDriverId(): TDriverId | null;\n}\n\nexport interface ISessionConversationRead {\n getMessages(): TUniversalMessage[];\n getContextState(): IContextWindowState;\n}\n\nexport interface ISessionIdentity {\n getSession(): { getSessionId(): string };\n}\n\nexport interface ISessionWorkspaceLocation {\n getCwd(): string;\n}\n\n/** Direct execution uses the same permission-wrapped runtime as model tool calls. */\nexport interface ISessionRuntimeTools {\n listRuntimeTools(): Promise<IToolSchema[]>;\n invokeRuntimeTool(\n name: string,\n parameters: TToolParameters,\n options?: { signal?: AbortSignal },\n ): Promise<IToolExecutionResult>;\n}\n\nexport interface ISessionCommands {\n executeCommand(\n name: string,\n args: string,\n source?: TCommandInvocationSource,\n originDriverId?: TDriverId,\n ): Promise<ICommandResult | null>;\n listCommands(): ICommandListEntry[];\n}\n\nexport interface ISessionEvents {\n on<E extends TInteractiveEventName>(event: E, handler: IInteractiveSessionEvents[E]): void;\n off<E extends TInteractiveEventName>(event: E, handler: IInteractiveSessionEvents[E]): void;\n}\n\nexport interface ISessionPromptResolution {\n resolvePermission(id: string, result: TPermissionResultValue, answererDriverId?: TDriverId): void;\n resolveAsk(id: string, response: TActionResponse, answererDriverId?: TDriverId): void;\n}\n\nexport interface ISessionBackgroundTasks {\n listBackgroundTasks(filter?: IBackgroundTaskListFilter): IBackgroundTaskState[];\n getBackgroundTask(taskId: string): IBackgroundTaskState | undefined;\n cancelBackgroundTask(taskId: string, reason?: string): Promise<void>;\n closeBackgroundTask(taskId: string): Promise<void>;\n sendBackgroundTask(taskId: string, input: IBackgroundTaskInput): Promise<void>;\n readBackgroundTaskLog(\n taskId: string,\n cursor?: IBackgroundTaskLogCursor,\n ): Promise<IBackgroundTaskLogPage>;\n}\n\nexport interface ISessionBackgroundGroups {\n listBackgroundJobGroups(): IBackgroundJobGroupState[];\n getBackgroundJobGroup(groupId: string): IBackgroundJobGroupState | undefined;\n createBackgroundJobGroup(\n input: Omit<IBackgroundJobGroupCreateRequest, 'parentSessionId'>,\n ): IBackgroundJobGroupState;\n waitBackgroundJobGroup(groupId: string): Promise<IBackgroundJobGroupState>;\n}\n\nexport interface ISessionExecutionWorkspace {\n getExecutionWorkspaceSnapshot(\n options?: IExecutionWorkspaceSnapshotOptions,\n ): IExecutionWorkspaceSnapshot;\n}\n\nexport interface ISessionAgentJobs {\n listAgentDefinitions(): Array<{ name: string; description: string }>;\n listAgentJobs(): ISubagentJobState[];\n spawnAgentJob(input: {\n agentType: string;\n label: string;\n mode: 'foreground' | 'background';\n prompt: string;\n model?: string;\n isolation?: TBackgroundTaskIsolation;\n }): Promise<ISubagentJobState>;\n sendAgentJob(taskId: string, prompt: string): Promise<void>;\n cancelAgentJob(taskId: string, reason?: string): Promise<void>;\n closeAgentJob(taskId: string): Promise<void>;\n}\n\nexport interface ISessionCapabilityMap {\n lifecycle: ISessionLifecycle;\n turnSubmission: ISessionTurnSubmission;\n turnControl: ISessionTurnControl;\n goal: ISessionGoal;\n executionState: ISessionExecutionState;\n driverAttribution: ISessionDriverAttribution;\n conversationRead: ISessionConversationRead;\n identity: ISessionIdentity;\n workspaceLocation: ISessionWorkspaceLocation;\n commands: ISessionCommands;\n runtimeTools: ISessionRuntimeTools;\n events: ISessionEvents;\n promptResolution: ISessionPromptResolution;\n backgroundTasks: ISessionBackgroundTasks;\n backgroundGroups: ISessionBackgroundGroups;\n executionWorkspace: ISessionExecutionWorkspace;\n agentJobs: ISessionAgentJobs;\n}\n\nexport const SESSION_CAPABILITY_MEMBER_KEYS = Object.freeze({\n lifecycle: Object.freeze(['isInitialized', 'shutdown'] as const),\n turnSubmission: Object.freeze(['submit'] as const),\n turnControl: Object.freeze(['abort', 'cancelQueue'] as const),\n goal: Object.freeze(['setGoal', 'getGoalState', 'cancelGoal'] as const),\n executionState: Object.freeze(['isExecuting', 'getPendingPrompt', 'getPendingCount'] as const),\n driverAttribution: Object.freeze(['getActiveDriverId'] as const),\n conversationRead: Object.freeze(['getMessages', 'getContextState'] as const),\n identity: Object.freeze(['getSession'] as const),\n workspaceLocation: Object.freeze(['getCwd'] as const),\n commands: Object.freeze(['executeCommand', 'listCommands'] as const),\n runtimeTools: Object.freeze(['listRuntimeTools', 'invokeRuntimeTool'] as const),\n events: Object.freeze(['on', 'off'] as const),\n promptResolution: Object.freeze(['resolvePermission', 'resolveAsk'] as const),\n backgroundTasks: Object.freeze([\n 'listBackgroundTasks',\n 'getBackgroundTask',\n 'cancelBackgroundTask',\n 'closeBackgroundTask',\n 'sendBackgroundTask',\n 'readBackgroundTaskLog',\n ] as const),\n backgroundGroups: Object.freeze([\n 'listBackgroundJobGroups',\n 'getBackgroundJobGroup',\n 'createBackgroundJobGroup',\n 'waitBackgroundJobGroup',\n ] as const),\n executionWorkspace: Object.freeze(['getExecutionWorkspaceSnapshot'] as const),\n agentJobs: Object.freeze([\n 'listAgentDefinitions',\n 'listAgentJobs',\n 'spawnAgentJob',\n 'sendAgentJob',\n 'cancelAgentJob',\n 'closeAgentJob',\n ] as const),\n} satisfies {\n readonly [TKey in keyof ISessionCapabilityMap]: readonly (keyof ISessionCapabilityMap[TKey])[];\n});\n\n// ── Capability host contracts (HARNESS-103) ──────────────────────────────────\n// These TYPES stayed here when the host's runtime mechanism moved to `testing/`. An\n// `agent-interface-*` package must not contain runtime logic (project-structure.md), and the\n// repository's own placement rule is `contracts→agent-interface-*, doubles→owner /testing`. The\n// contract is the part that belongs in a contracts package; the 100-line prototype-walking\n// forwarder that satisfies it is a double factory and now lives where doubles live.\n\ntype TUnionToIntersection<T> = (T extends T ? (value: T) => void : never) extends (\n value: infer TIntersection,\n) => void\n ? TIntersection\n : never;\n\ntype TSelectedSessionPorts<TCapabilities extends Partial<ISessionCapabilityMap>> =\n TUnionToIntersection<Exclude<TCapabilities[keyof TCapabilities], undefined>>;\n\nexport interface ISessionCapabilityHost<\n TCapabilities extends Partial<ISessionCapabilityMap> = Partial<ISessionCapabilityMap>,\n> {\n readonly capabilities: Readonly<TCapabilities>;\n}\n\nexport type TSessionCapabilityHost<TCapabilities extends Partial<ISessionCapabilityMap>> =\n ISessionCapabilityHost<TCapabilities> & TSelectedSessionPorts<TCapabilities>;\n\nexport type TSessionCapabilityReadResult<TCapability> =\n Readonly<{ provided: false }> | Readonly<{ provided: true; value: TCapability }>;\n"],"mappings":"AAwLA,MAAa,EAAiC,OAAO,OAAO,CAC1D,UAAW,OAAO,OAAO,CAAC,gBAAiB,UAAU,CAAU,EAC/D,eAAgB,OAAO,OAAO,CAAC,QAAQ,CAAU,EACjD,YAAa,OAAO,OAAO,CAAC,QAAS,aAAa,CAAU,EAC5D,KAAM,OAAO,OAAO,CAAC,UAAW,eAAgB,YAAY,CAAU,EACtE,eAAgB,OAAO,OAAO,CAAC,cAAe,mBAAoB,iBAAiB,CAAU,EAC7F,kBAAmB,OAAO,OAAO,CAAC,mBAAmB,CAAU,EAC/D,iBAAkB,OAAO,OAAO,CAAC,cAAe,iBAAiB,CAAU,EAC3E,SAAU,OAAO,OAAO,CAAC,YAAY,CAAU,EAC/C,kBAAmB,OAAO,OAAO,CAAC,QAAQ,CAAU,EACpD,SAAU,OAAO,OAAO,CAAC,iBAAkB,cAAc,CAAU,EACnE,aAAc,OAAO,OAAO,CAAC,mBAAoB,mBAAmB,CAAU,EAC9E,OAAQ,OAAO,OAAO,CAAC,KAAM,KAAK,CAAU,EAC5C,iBAAkB,OAAO,OAAO,CAAC,oBAAqB,YAAY,CAAU,EAC5E,gBAAiB,OAAO,OAAO,CAC7B,sBACA,oBACA,uBACA,sBACA,qBACA,uBACF,CAAU,EACV,iBAAkB,OAAO,OAAO,CAC9B,0BACA,wBACA,2BACA,wBACF,CAAU,EACV,mBAAoB,OAAO,OAAO,CAAC,+BAA+B,CAAU,EAC5E,UAAW,OAAO,OAAO,CACvB,uBACA,gBACA,gBACA,eACA,iBACA,eACF,CAAU,CACZ,CAEC"}