@crazx/dsh-api-session-controller 0.1.2-alpha.3.zw.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/LICENSE +21 -0
  2. package/README.i18n.yaml +6 -0
  3. package/README.md +74 -0
  4. package/README.zh.md +74 -0
  5. package/lib/client.js +2724 -0
  6. package/lib/index.js +2826 -0
  7. package/lib/invariant.js +13 -0
  8. package/lib/typert.host.d.ts +3 -0
  9. package/lib/typert.host.js +2574 -0
  10. package/lib/typert.remote-client.d.ts +67 -0
  11. package/lib/typert.remote-client.js +1119 -0
  12. package/lib/types/agent.d.ts +156 -0
  13. package/lib/types/agent.js +537 -0
  14. package/lib/types/catalog.d.ts +11 -0
  15. package/lib/types/catalog.js +58 -0
  16. package/lib/types/client/contract/events.d.ts +71 -0
  17. package/lib/types/client/contract/events.js +91 -0
  18. package/lib/types/client/contract/session.d.ts +150 -0
  19. package/lib/types/client/contract/session.js +2 -0
  20. package/lib/types/client/contract/sessions.d.ts +125 -0
  21. package/lib/types/client/contract/sessions.js +2 -0
  22. package/lib/types/client/contract/snapshot.d.ts +82 -0
  23. package/lib/types/client/contract/snapshot.js +2 -0
  24. package/lib/types/client/index.d.ts +30 -0
  25. package/lib/types/client/index.js +48 -0
  26. package/lib/types/client/ordered-baseline.d.ts +12 -0
  27. package/lib/types/client/ordered-baseline.js +41 -0
  28. package/lib/types/client/scope.d.ts +36 -0
  29. package/lib/types/client/scope.js +54 -0
  30. package/lib/types/client/sessions/history-records.d.ts +22 -0
  31. package/lib/types/client/sessions/history-records.js +31 -0
  32. package/lib/types/client/sessions/lineage.d.ts +38 -0
  33. package/lib/types/client/sessions/lineage.js +56 -0
  34. package/lib/types/client/sessions/manager.d.ts +280 -0
  35. package/lib/types/client/sessions/manager.js +894 -0
  36. package/lib/types/client/sessions/notifier.d.ts +39 -0
  37. package/lib/types/client/sessions/notifier.js +98 -0
  38. package/lib/types/client/sessions/projection-store.d.ts +108 -0
  39. package/lib/types/client/sessions/projection-store.js +129 -0
  40. package/lib/types/client/sessions/queue-mirror.d.ts +26 -0
  41. package/lib/types/client/sessions/queue-mirror.js +61 -0
  42. package/lib/types/client/sessions/remotes.d.ts +30 -0
  43. package/lib/types/client/sessions/remotes.js +8 -0
  44. package/lib/types/client/sessions/service.d.ts +349 -0
  45. package/lib/types/client/sessions/service.js +574 -0
  46. package/lib/types/client/sessions/session.d.ts +294 -0
  47. package/lib/types/client/sessions/session.js +711 -0
  48. package/lib/types/client/time-zone.d.ts +8 -0
  49. package/lib/types/client/time-zone.js +14 -0
  50. package/lib/types/client/transport.d.ts +73 -0
  51. package/lib/types/client/transport.js +106 -0
  52. package/lib/types/commands.d.ts +69 -0
  53. package/lib/types/commands.js +544 -0
  54. package/lib/types/control.d.ts +23 -0
  55. package/lib/types/control.js +192 -0
  56. package/lib/types/file-references.d.ts +27 -0
  57. package/lib/types/file-references.js +69 -0
  58. package/lib/types/history.d.ts +31 -0
  59. package/lib/types/history.js +376 -0
  60. package/lib/types/index.d.ts +171 -0
  61. package/lib/types/index.js +424 -0
  62. package/lib/types/invariant.d.ts +9 -0
  63. package/lib/types/invariant.js +12 -0
  64. package/lib/types/list.d.ts +53 -0
  65. package/lib/types/list.js +405 -0
  66. package/lib/types/model-selection-projection.d.ts +8 -0
  67. package/lib/types/model-selection-projection.js +66 -0
  68. package/lib/types/remote-events.d.ts +8 -0
  69. package/lib/types/remote-events.js +2 -0
  70. package/lib/types/skill-catalog.d.ts +28 -0
  71. package/lib/types/skill-catalog.js +192 -0
  72. package/lib/types/types.d.ts +505 -0
  73. package/lib/types/types.js +6 -0
  74. package/package.json +154 -0
@@ -0,0 +1,349 @@
1
+ /**
2
+ * ClientSessions: root sessions service — list snapshot store (manager
3
+ * projection; carries `current`, the persisted selection every
4
+ * session-scoped surface keys off), Agent scope tree (mintScope pattern: no-op plugin
5
+ * Fiber + ctx.extend scope tag; one scope per session, agent id === session
6
+ * id), stable SessionBinding cache, breadcrumb-route projection.
7
+ *
8
+ * Scope lifecycle is stage-driven: a scope is minted lazily on first
9
+ * resolution (pure — resolution has no side effects and is render-safe);
10
+ * the event window and deferred teardown key off the STAGED session, which
11
+ * follows `list.current` exactly. Staging is the open signal: the window
12
+ * opens ⟺ the session is on stage (the stage is `current`; the staged
13
+ * state can widen to a multi-pane list later). A session leaving the list
14
+ * tears its scope down immediately unless it is the staged one, whose scope
15
+ * survives frozen (read-only view) until the stage moves on.
16
+ */
17
+ import type { Context } from '@deepseek-ai/cordis';
18
+ import type { SubagentAddress } from '@deepseek-ai/dsh-subagent/client';
19
+ import type { SessionId } from '@deepseek-ai/dsh-session/types';
20
+ import type { WorkspaceId } from '@deepseek-ai/dsh-workspace/types';
21
+ import type { SessionJob as JobView } from '../../types.ts';
22
+ import type { SessionProjectionMap } from '@deepseek-ai/dsh-session-projection/types';
23
+ import { type SnapshotStore } from '@deepseek-ai/dsh-client-store';
24
+ import type { RemoteFailure, RemoteResult } from '@deepseek-ai/dsh-typert-protocol';
25
+ import type { SessionEventSource } from '../contract/events.ts';
26
+ import type { SessionFace } from '../contract/session.ts';
27
+ import type { AgentContext, ISessions } from '../contract/sessions.ts';
28
+ import { SessionManager } from './manager.ts';
29
+ import type { SessionRemotes } from './remotes.ts';
30
+ import type { SessionListPhase, SessionSearchResultItem, SubagentCatalogSnapshot } from './manager.ts';
31
+ /** Session list row projected from the host list RPC plus live stream increments. */
32
+ export interface SessionSummary {
33
+ id: SessionId;
34
+ /** Latest durable log-backed title, absent until the host projects one. */
35
+ title?: string;
36
+ /** Human-facing label: durable title, project basename, then session id. */
37
+ displayTitle: string;
38
+ cwd?: string;
39
+ parentId?: SessionId;
40
+ /** Coarse durable origin for navigation filtering; not a continuation capability. */
41
+ origin?: 'subagent';
42
+ running: boolean;
43
+ /** Finished while not selected and not yet opened — the sidebar's green "done" reminder. Absent = false. */
44
+ completed?: boolean;
45
+ /**
46
+ * Empty-log bit (host summary derivation mirror). New Session reuses a blank
47
+ * one targeting the same workspace. Filtering stays with the consumer: the
48
+ * store carries every row, while the Workspace browser shows only the
49
+ * selected blank entry.
50
+ */
51
+ blank: boolean;
52
+ updatedAt: number;
53
+ /** Current host-computed projection values retained by the object layer. */
54
+ projectionValues?: Readonly<Partial<SessionProjectionMap>>;
55
+ }
56
+ /**
57
+ * Session list store shape. `current` rides the same snapshot (arbitrated:
58
+ * the single useSessions standard hook reads list and selection together —
59
+ * sidebar highlighting and current-session consumers share one fact source).
60
+ */
61
+ export interface SessionListState {
62
+ /** Host-list order; addressed breadcrumb-only rows are excluded. */
63
+ ids: SessionId[];
64
+ /** Host rows plus the current addressed subagent route used by navigation. */
65
+ byId: Record<SessionId, SessionSummary>;
66
+ current: SessionId | undefined;
67
+ /** Arrival lifecycle projected 1:1 from the manager snapshot (see SessionListPhase): empty-with-ready means "truly no sessions". */
68
+ phase: SessionListPhase;
69
+ /** Direct durable catalogs keyed by their selected parent address. */
70
+ subagentsByParent: Readonly<Record<SessionId, SubagentCatalogSnapshot>>;
71
+ /**
72
+ * Background jobs each session can see, mirrored last-wins from Session
73
+ * Controller's control baseline and `jobs` frames. A missing key is an empty
74
+ * set, so consumers read absence rather than a sentinel.
75
+ */
76
+ jobsBySession: Readonly<Record<SessionId, readonly JobView[]>>;
77
+ /** Current session's catalog-derived address, absent on ordinary navigation. */
78
+ currentAddress: SubagentAddress | undefined;
79
+ }
80
+ /** Structured session-create failure. */
81
+ export declare class SessionCreateError extends Error {
82
+ readonly rpcError: RemoteFailure;
83
+ readonly requestedSessionId: SessionId | undefined;
84
+ readonly name = "SessionCreateError";
85
+ /**
86
+ * @param rpcError - Host business or folded transport error.
87
+ * @param requestedSessionId - caller-preallocated id used for later stream/list reconciliation.
88
+ */
89
+ constructor(rpcError: RemoteFailure, requestedSessionId: SessionId | undefined);
90
+ }
91
+ /** Structured session-fork failure. */
92
+ export declare class SessionForkError extends Error {
93
+ readonly rpcError: RemoteFailure;
94
+ readonly sourceSessionId: SessionId;
95
+ readonly name = "SessionForkError";
96
+ /**
97
+ * @param rpcError - Host business or folded transport error.
98
+ * @param sourceSessionId - the session the fork was cut from.
99
+ */
100
+ constructor(rpcError: RemoteFailure, sourceSessionId: SessionId);
101
+ }
102
+ /** Identity-stable logical binding for one materialized Client Session. */
103
+ export interface SessionBinding {
104
+ readonly sessionId: SessionId;
105
+ /** The outward session face only — feature code never sees the concrete class. */
106
+ readonly session: SessionFace;
107
+ /** Contiguous event window reserved for Conversation assembly. */
108
+ readonly eventSource: SessionEventSource;
109
+ readonly ctx: AgentContext;
110
+ }
111
+ export { scopeOf } from '../scope.ts';
112
+ /** Root sessions service: list store, current selection, object-layer manager, scope tree, bindings, and breadcrumb routes. */
113
+ export declare class ClientSessions implements ISessions {
114
+ private readonly rootCtx;
115
+ /**
116
+ * The wire schema's own result bound, re-exposed for presentation plugins as
117
+ * injected data. Not per-connection state: the `session.search` response
118
+ * schema caps `items` at this constant, so every transport (fixture included)
119
+ * reports the same number.
120
+ */
121
+ readonly searchResultLimit = 20;
122
+ /** List snapshot store (list RPC + host stream increments; re-pulled on reconnect) — the useSessions standard feed, current included. */
123
+ readonly list: SnapshotStore<SessionListState>;
124
+ /** The object-layer instance cluster and frame dispatch entry. */
125
+ private readonly manager;
126
+ /**
127
+ * Persisted selection cell (the durable half of `list.current`). Private on
128
+ * purpose: reads go through the list snapshot; writes through {@link
129
+ * ClientSessions.open} / {@link ClientSessions.clear}. Projection
130
+ * validates it against the live list instead of destructively pruning, so a
131
+ * selection survives transient list states (reconnect re-pull) and
132
+ * resurfaces when its session returns.
133
+ */
134
+ private readonly selection;
135
+ private readonly scopes;
136
+ /** In-flight scope drops remain here after records leave `scopes`, so root disposal can await quiescence. */
137
+ private readonly scopeDrops;
138
+ /**
139
+ * The staged session id — follows `list.current` exactly, holding its last
140
+ * defined value across masked gaps (a transiently absent selection blanks
141
+ * `current` without moving the stage, so reconnect re-pulls and removals
142
+ * keep the staged scope's frozen view alive until the stage moves on).
143
+ */
144
+ private watched;
145
+ /** Removed-while-staged sessions whose teardown waits for the stage to move away. */
146
+ private readonly deferredRemovals;
147
+ /**
148
+ * @param ctx - client root context (scope fibers mount under it).
149
+ * @param remote - generated Remote namespaces shared with every Session.
150
+ */
151
+ constructor(rootCtx: Context, remote: SessionRemotes);
152
+ /**
153
+ * Select a listed or retained catalog-addressed session as current.
154
+ * @param id - listed or addressed session id.
155
+ */
156
+ open(id: SessionId): void;
157
+ /**
158
+ * Open a healthy catalog child through its direct-parent address.
159
+ * @param address - catalog-derived parent and child ids.
160
+ */
161
+ openSubagent(address: SubagentAddress): void;
162
+ /**
163
+ * Resolve an already discovered direct-parent address without opening it.
164
+ * Feature plugins use this to avoid Agent-bound RPCs in persisted child views.
165
+ * @param id - possible addressed child id.
166
+ * @returns The retained address, when present.
167
+ */
168
+ subagentAddress(id: SessionId): SubagentAddress | undefined;
169
+ /**
170
+ * Inform the Session Controller whether a catalog menu is consuming membership updates.
171
+ * @param parentSessionId - selected parent.
172
+ * @param open - menu state.
173
+ */
174
+ setSubagentCatalogOpen(parentSessionId: SessionId, open: boolean): void;
175
+ /**
176
+ * Refresh one direct-child catalog.
177
+ * @param parentSessionId - catalog owner.
178
+ */
179
+ refreshSubagents(parentSessionId: SessionId): Promise<void>;
180
+ /**
181
+ * Clear the current selection so the layout shows the no-session empty
182
+ * state (new-session affordance and the workspace preselection flow).
183
+ * Wipes the persisted selection too — a reload stays on empty until the
184
+ * user opens or starts a session. The staged scope keeps its frozen view
185
+ * per the masked-gap contract until the next open() moves the stage.
186
+ */
187
+ clear(): void;
188
+ /**
189
+ * Refresh the real Session baseline, reusing an in-flight pull.
190
+ * @returns completion of the current or newly started baseline pull.
191
+ */
192
+ refresh(): Promise<void>;
193
+ /**
194
+ * Search the Host's visible message-content index. Results stay
195
+ * request-local; the list snapshot remains the metadata authority.
196
+ * @param query - non-blank literal phrase.
197
+ * @param signal - cancellation for a superseded search.
198
+ * @returns bounded results or a business/transport error.
199
+ */
200
+ search(query: string, signal: AbortSignal): Promise<RemoteResult<{
201
+ items: SessionSearchResultItem[];
202
+ hasMore: boolean;
203
+ }>>;
204
+ /**
205
+ * Apply one Session Controller live-control frame.
206
+ * @param frame - baseline or live control replacement.
207
+ */
208
+ handleControlFrame(frame: Parameters<SessionManager['handleControlFrame']>[0]): void;
209
+ /**
210
+ * Apply one remotely forwarded Session-list addition.
211
+ * @param summary - current Host summary for the added Session.
212
+ */
213
+ handleSessionAdded(summary: Parameters<SessionManager['handleSessionAdded']>[0]): void;
214
+ /**
215
+ * Apply one remotely forwarded Session removal.
216
+ * @param sessionId - removed Session identity.
217
+ */
218
+ handleSessionRemoved(sessionId: Parameters<SessionManager['handleSessionRemoved']>[0]): void;
219
+ /**
220
+ * Apply one remotely forwarded running-state change.
221
+ * @param args - Session identity and current Agent running state.
222
+ */
223
+ handleSessionStatus(...args: Parameters<SessionManager['handleSessionStatus']>): void;
224
+ /**
225
+ * Apply one remotely forwarded list-activity change.
226
+ * @param args - Session identity and durable activity timestamp.
227
+ */
228
+ handleSessionActivity(...args: Parameters<SessionManager['handleSessionActivity']>): void;
229
+ /**
230
+ * Apply one remotely forwarded Agent failure.
231
+ * @param args - Session identity and caller-visible failure description.
232
+ */
233
+ handleSessionError(...args: Parameters<SessionManager['handleSessionError']>): void;
234
+ /** Rebuild the Session baseline and every opened window after connection. */
235
+ handleConnected(): void;
236
+ /**
237
+ * Create a session on the host. Resolution guarantee: by the time the
238
+ * promise resolves, the created session is in the list store and
239
+ * {@link ClientSessions.binding} resolves it — callers (New Session
240
+ * draft hand-off) may address the scope synchronously, without waiting a
241
+ * notifier flush. The synchronous projection below makes this structural
242
+ * rather than an accident of microtask ordering.
243
+ * @param opts - target workspace or directory and an optional preallocated id.
244
+ * @returns the new session id.
245
+ * @throws {SessionCreateError} with the requested id.
246
+ */
247
+ create(opts?: {
248
+ workspaceId?: WorkspaceId;
249
+ cwd?: string;
250
+ sessionId?: SessionId;
251
+ }): Promise<SessionId>;
252
+ /**
253
+ * Fork a session from a completed-turn prefix of the source (same
254
+ * synchronous-addressability guarantee as {@link ClientSessions.create}:
255
+ * on resolution the child is in the list store and open() can target it).
256
+ * @param opts - source session id, the optional event seq anchoring the
257
+ * cut (the boundary is the first turn/end at or after it; an in-log
258
+ * anchor in an open turn is unavailable rather than clipped backward),
259
+ * and whether to increment an inherited durable title before resolving.
260
+ * A fractional anchor floors to a real event seq: the frozen nodes of an
261
+ * interrupted turn carry flow-ordering seqs between two events, and the
262
+ * wire takes integers only.
263
+ * @returns the child session id.
264
+ * @throws {SessionForkError} with the source id.
265
+ * @throws {Error} when a requested child-title rename fails after creation.
266
+ */
267
+ fork(opts: {
268
+ sessionId: SessionId;
269
+ atSeq?: number;
270
+ increaseTitle?: boolean;
271
+ }): Promise<SessionId>;
272
+ /**
273
+ * Resolve an Agent-scoped context view (use-and-discard).
274
+ * @param id - session id (the agent identity — 1:1 same axis).
275
+ * @returns scoped ctx, or undefined for a session neither listed nor already scoped.
276
+ */
277
+ scope(id: SessionId): AgentContext | undefined;
278
+ /**
279
+ * Materialize the Agent scope named by a validated Host Remote Event.
280
+ * The first successful Session-list baseline becomes authoritative for its
281
+ * lifetime; until then, transport streams may address the scope in either
282
+ * arrival order.
283
+ * @param id - Host-projected Agent identity (the matching Session id).
284
+ * @returns the identity-stable Agent Context.
285
+ */
286
+ resolveAgentScope(id: SessionId): AgentContext;
287
+ /**
288
+ * Read the Agent scope tag off a context. Service-method boundary: fetch
289
+ * bundles must reach scope resolution through ctx.sessions — a cross-bundle
290
+ * value import of the standalone helper would inline a second module
291
+ * instance whose private tag Symbol never matches.
292
+ * @param ctx - any client context.
293
+ * @returns the session id, or undefined on root contexts.
294
+ */
295
+ scopeOf(ctx: Context): SessionId | undefined;
296
+ /**
297
+ * Resolve the business Session behind an Agent-scoped context — the one
298
+ * hop every scoped consumer (event listeners, per-session controllers)
299
+ * takes from ctx-space into object-space (the client mirror of host
300
+ * `agent.session`). Same service-method boundary as
301
+ * {@link ClientSessions.scopeOf}.
302
+ * @param ctx - an Agent-scoped context.
303
+ * @returns the session face, or undefined when the ctx is untagged or its scope was pruned.
304
+ */
305
+ sessionOf(ctx: Context): SessionFace | undefined;
306
+ /**
307
+ * Resolve the stable session binding (scope-addressed assembly feed). Pure
308
+ * resolution — no staging, no window side effects.
309
+ * @param id - session id.
310
+ * @returns binding, or undefined for a session neither listed nor already scoped.
311
+ */
312
+ binding(id: SessionId): SessionBinding | undefined;
313
+ /**
314
+ * Move the stage to the list's current session: sweep teardowns deferred
315
+ * behind the previous occupant and pull the new occupant's history window.
316
+ * Staging IS the open signal — the window opens ⟺ the session is on stage
317
+ * — and open() is idempotent (an in-flight or completed open no-ops; a
318
+ * failed one retries the next time current is touched).
319
+ */
320
+ private followCurrent;
321
+ /**
322
+ * Lazily mint the scope + binding for an eligible session. Eligibility and
323
+ * prune share one predicate: listed on the host or selected
324
+ * through a retained subagent address. Breadcrumb-only ancestors remain
325
+ * summary data and do not keep scopes alive.
326
+ */
327
+ private resolve;
328
+ /** Materialize one scope after its caller establishes that the id may be addressed. */
329
+ private materializeScope;
330
+ /** The one aliveness predicate shared by scope mint and prune: host-listed or currently addressed. */
331
+ private eligible;
332
+ /** Project the manager's list snapshot into the store (title derivation is display-only). */
333
+ private projectList;
334
+ /** Tear down scope + instance for no-longer-eligible sessions off stage; the staged one defers until the stage moves. */
335
+ private pruneScopes;
336
+ private startScopeDrop;
337
+ private drainScopeDrops;
338
+ /**
339
+ * One teardown for the whole per-session axis: the scope
340
+ * fiber (cascading every actx-registered effect: input shell, slash
341
+ * controller, popup, plugin stores, listeners), the session-keyed slot
342
+ * registrations and the Session instance itself — the host session log is the
343
+ * durable truth, a reopen lazily rebuilds and backfills via open().
344
+ */
345
+ private dropScope;
346
+ /** Run deferred teardowns whose session is no longer staged (called when the stage moves). */
347
+ private sweepDeferred;
348
+ }
349
+ //# sourceMappingURL=service.d.ts.map