@khorsheed/dsh-local-agent 0.2.0-rc.1 → 0.2.0

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 (57) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.en.md +23 -164
  3. package/README.i18n.yaml +2 -2
  4. package/README.md +23 -164
  5. package/lib/client.js +23707 -4768
  6. package/lib/index.js +827 -62
  7. package/lib/member-bridge.js +195 -25
  8. package/lib/tool-factory.js +52 -19
  9. package/lib/typert.host.js +1440 -353
  10. package/lib/typert.remote-client.d.ts +43 -3
  11. package/lib/typert.remote-client.js +973 -335
  12. package/lib/types/client/FamilyCard.d.ts +37 -0
  13. package/lib/types/client/FamilyCard.js +55 -0
  14. package/lib/types/client/HarnessModelPicker.d.ts +21 -1
  15. package/lib/types/client/HarnessModelPicker.js +31 -3
  16. package/lib/types/client/MemberLiveNode.js +38 -4
  17. package/lib/types/client/ModelListSection.d.ts +49 -0
  18. package/lib/types/client/ModelListSection.js +132 -0
  19. package/lib/types/client/ProviderAuthBlock.d.ts +10 -2
  20. package/lib/types/client/ProviderAuthBlock.js +13 -6
  21. package/lib/types/client/auth-status.d.ts +6 -0
  22. package/lib/types/client/auth-status.js +8 -0
  23. package/lib/types/client/harness-cards.d.ts +72 -0
  24. package/lib/types/client/harness-cards.js +57 -0
  25. package/lib/types/client/icons.d.ts +2 -1
  26. package/lib/types/client/icons.js +1 -0
  27. package/lib/types/client/index.d.ts +32 -7
  28. package/lib/types/client/index.js +66 -9
  29. package/lib/types/client/locales.d.ts +25 -1
  30. package/lib/types/client/locales.js +50 -2
  31. package/lib/types/client/model-directory-scope.d.ts +14 -0
  32. package/lib/types/client/model-directory-scope.js +20 -0
  33. package/lib/types/gateway.d.ts +49 -1
  34. package/lib/types/gateway.js +89 -0
  35. package/lib/types/index.d.ts +91 -38
  36. package/lib/types/index.js +190 -58
  37. package/lib/types/live-stream.d.ts +11 -0
  38. package/lib/types/live-stream.js +26 -0
  39. package/lib/types/member-bridge.d.ts +11 -1
  40. package/lib/types/member-bridge.js +81 -13
  41. package/lib/types/member-channel.d.ts +44 -1
  42. package/lib/types/member-channel.js +65 -2
  43. package/lib/types/member-controls.d.ts +8 -0
  44. package/lib/types/member-controls.js +15 -2
  45. package/lib/types/mode-skills.d.ts +18 -0
  46. package/lib/types/mode-skills.js +56 -0
  47. package/lib/types/model-list.d.ts +55 -0
  48. package/lib/types/model-list.js +101 -0
  49. package/lib/types/preset-tool-host.d.ts +70 -0
  50. package/lib/types/preset-tool-host.js +210 -0
  51. package/lib/types/tool-factory.d.ts +9 -3
  52. package/lib/types/tool-factory.js +55 -18
  53. package/lib/types/types.d.ts +62 -5
  54. package/package.json +27 -23
  55. package/lib/invariant.js +0 -85
  56. package/lib/types/invariant.d.ts +0 -16
  57. package/lib/types/invariant.js +0 -105
@@ -82,6 +82,11 @@ let LocalAgentGateway = (() => {
82
82
  let _sessions_decorators;
83
83
  let _memberOf_decorators;
84
84
  let _harnessModel_decorators;
85
+ let _checkEndpoint_decorators;
86
+ let _endpointAuth_decorators;
87
+ let _configureEndpoint_decorators;
88
+ let _modelList_decorators;
89
+ let _configureModelList_decorators;
85
90
  let _memberModel_decorators;
86
91
  let _setMemberModel_decorators;
87
92
  let _memberConfiguration_decorators;
@@ -108,6 +113,11 @@ let LocalAgentGateway = (() => {
108
113
  _sessions_decorators = [Remote('sessions')];
109
114
  _memberOf_decorators = [Remote('memberOf')];
110
115
  _harnessModel_decorators = [Remote('harnessModel')];
116
+ _checkEndpoint_decorators = [Remote('checkEndpoint')];
117
+ _endpointAuth_decorators = [Remote('endpointAuth')];
118
+ _configureEndpoint_decorators = [Remote('configureEndpoint')];
119
+ _modelList_decorators = [Remote('modelList')];
120
+ _configureModelList_decorators = [Remote('configureModelList')];
111
121
  _memberModel_decorators = [Remote('memberModel')];
112
122
  _setMemberModel_decorators = [Remote('setMemberModel')];
113
123
  _memberConfiguration_decorators = [Remote('memberConfiguration')];
@@ -131,6 +141,11 @@ let LocalAgentGateway = (() => {
131
141
  __esDecorate(this, null, _sessions_decorators, { kind: "method", name: "sessions", static: false, private: false, access: { has: obj => "sessions" in obj, get: obj => obj.sessions }, metadata: _metadata }, null, _instanceExtraInitializers);
132
142
  __esDecorate(this, null, _memberOf_decorators, { kind: "method", name: "memberOf", static: false, private: false, access: { has: obj => "memberOf" in obj, get: obj => obj.memberOf }, metadata: _metadata }, null, _instanceExtraInitializers);
133
143
  __esDecorate(this, null, _harnessModel_decorators, { kind: "method", name: "harnessModel", static: false, private: false, access: { has: obj => "harnessModel" in obj, get: obj => obj.harnessModel }, metadata: _metadata }, null, _instanceExtraInitializers);
144
+ __esDecorate(this, null, _checkEndpoint_decorators, { kind: "method", name: "checkEndpoint", static: false, private: false, access: { has: obj => "checkEndpoint" in obj, get: obj => obj.checkEndpoint }, metadata: _metadata }, null, _instanceExtraInitializers);
145
+ __esDecorate(this, null, _endpointAuth_decorators, { kind: "method", name: "endpointAuth", static: false, private: false, access: { has: obj => "endpointAuth" in obj, get: obj => obj.endpointAuth }, metadata: _metadata }, null, _instanceExtraInitializers);
146
+ __esDecorate(this, null, _configureEndpoint_decorators, { kind: "method", name: "configureEndpoint", static: false, private: false, access: { has: obj => "configureEndpoint" in obj, get: obj => obj.configureEndpoint }, metadata: _metadata }, null, _instanceExtraInitializers);
147
+ __esDecorate(this, null, _modelList_decorators, { kind: "method", name: "modelList", static: false, private: false, access: { has: obj => "modelList" in obj, get: obj => obj.modelList }, metadata: _metadata }, null, _instanceExtraInitializers);
148
+ __esDecorate(this, null, _configureModelList_decorators, { kind: "method", name: "configureModelList", static: false, private: false, access: { has: obj => "configureModelList" in obj, get: obj => obj.configureModelList }, metadata: _metadata }, null, _instanceExtraInitializers);
134
149
  __esDecorate(this, null, _memberModel_decorators, { kind: "method", name: "memberModel", static: false, private: false, access: { has: obj => "memberModel" in obj, get: obj => obj.memberModel }, metadata: _metadata }, null, _instanceExtraInitializers);
135
150
  __esDecorate(this, null, _setMemberModel_decorators, { kind: "method", name: "setMemberModel", static: false, private: false, access: { has: obj => "setMemberModel" in obj, get: obj => obj.setMemberModel }, metadata: _metadata }, null, _instanceExtraInitializers);
136
151
  __esDecorate(this, null, _memberConfiguration_decorators, { kind: "method", name: "memberConfiguration", static: false, private: false, access: { has: obj => "memberConfiguration" in obj, get: obj => obj.memberConfiguration }, metadata: _metadata }, null, _instanceExtraInitializers);
@@ -330,6 +345,80 @@ let LocalAgentGateway = (() => {
330
345
  ? info
331
346
  : { ...info, lastObserved: observed });
332
347
  }
348
+ /**
349
+ * Verify one harness's saved endpoint from the host — the settings card's
350
+ * verify button. The answer is the harness's human-readable verdict text.
351
+ * Session-less by design: the commands channel needs a main agent session,
352
+ * which a settings card may not have. Null when the harness is unknown or
353
+ * declares no probe (the card then hides the button — declare-and-degrade).
354
+ * @param name - the harness name.
355
+ * @returns the verdict text, or null.
356
+ */
357
+ async checkEndpoint(name) {
358
+ const harness = this.ctx.localAgent.get(name);
359
+ if (typeof harness?.checkEndpoint !== 'function')
360
+ return null;
361
+ return harness.checkEndpoint(this.ctx.localAgent.homeDir(name));
362
+ }
363
+ /**
364
+ * The settings card's read of one harness's resolved endpoint state —
365
+ * baseUrl verbatim, credentials as presence booleans (secrets never cross).
366
+ * Session-less like the rest of the gateway. Null when the harness is
367
+ * unknown or declares no endpoint face (the card then hides the form).
368
+ * @param name - the harness name.
369
+ * @returns the resolved per-field state, or null.
370
+ */
371
+ async endpointAuth(name) {
372
+ const harness = this.ctx.localAgent.get(name);
373
+ if (harness?.endpointAuth === undefined)
374
+ return null;
375
+ return harness.endpointAuth.read(this.ctx.localAgent.homeDir(name));
376
+ }
377
+ /**
378
+ * Apply one endpoint-credential edit into the harness's own credential
379
+ * store (a string sets, null clears, absent leaves), answering the
380
+ * post-write resolved state so the card can flip immediately. The write
381
+ * deliberately bypasses the volatile row-config channel — a credential
382
+ * never lands in the profile patch document. Null when the harness is
383
+ * unknown or declares no endpoint face.
384
+ * @param name - the harness name.
385
+ * @param fields - the field edits.
386
+ * @returns the post-write resolved state, or null.
387
+ */
388
+ async configureEndpoint(name, fields) {
389
+ const harness = this.ctx.localAgent.get(name);
390
+ if (harness?.endpointAuth === undefined)
391
+ return null;
392
+ await harness.endpointAuth.write(this.ctx.localAgent.homeDir(name), fields);
393
+ return harness.endpointAuth.read(this.ctx.localAgent.homeDir(name));
394
+ }
395
+ /**
396
+ * The settings card's read of one harness's curated model list — ordered
397
+ * identifiers, first is the default. Null when the harness is unknown or
398
+ * declares no list face (the card then hides the editor).
399
+ * @param name - the harness name.
400
+ * @returns the ordered list, or null.
401
+ */
402
+ async modelList(name) {
403
+ const harness = this.ctx.localAgent.get(name);
404
+ if (harness?.modelList === undefined)
405
+ return null;
406
+ return harness.modelList.read(this.ctx.localAgent.homeDir(name));
407
+ }
408
+ /**
409
+ * Replace one harness's curated model list wholesale (reorders, removals
410
+ * and additions all ride the same write), answering the list as persisted.
411
+ * Null when the harness is unknown or declares no list face.
412
+ * @param name - the harness name.
413
+ * @param models - the new ordered list.
414
+ * @returns the persisted list, or null.
415
+ */
416
+ async configureModelList(name, models) {
417
+ const harness = this.ctx.localAgent.get(name);
418
+ if (harness?.modelList === undefined)
419
+ return null;
420
+ return harness.modelList.write(this.ctx.localAgent.homeDir(name), models);
421
+ }
333
422
  /**
334
423
  * The model surface of one member — the composer's picker read. The
335
424
  * delegation record's requested model rides in from the core so the broker
@@ -22,7 +22,7 @@ import type { CommandInvocation, CommandResult } from '@deepseek-ai/dsh-commands
22
22
  import type { ContentBlock, TokenUsage } from '@deepseek-ai/dsh-llm';
23
23
  import type { Session, SessionHeader } from '@deepseek-ai/dsh-session';
24
24
  import type { SubagentRun } from '@deepseek-ai/dsh-subagent';
25
- import type { DelegationCallOptions, LocalAgentDelegationInfo, LocalAgentDelegationIntent, LocalAgentDelegationRecord, LocalAgentEffectiveSettings, LocalAgentMemberRun, LocalAgentModelBroker, LocalAgentMemberBinding, LocalAgentMemberControlState, LocalAgentMemberInbox, LocalAgentMemberConfiguration, LocalAgentControlReceipt, LocalAgentAppliedConfiguration, LocalAgentRosterRow, LocalAgentRunProgress, LocalAgentSessionRecord, LocalAgentStatus, LocalAgentToolCalls } from './types.ts';
25
+ import type { DelegationCallOptions, LocalAgentDelegationInfo, LocalAgentDelegationIntent, LocalAgentDelegationRecord, LocalAgentEffectiveSettings, LocalAgentEndpointAuthFields, LocalAgentEndpointAuthState, LocalAgentMemberRun, LocalAgentModelBroker, LocalAgentMemberBinding, LocalAgentMemberControlState, LocalAgentMemberInbox, LocalAgentMemberConfiguration, LocalAgentControlReceipt, LocalAgentAppliedConfiguration, LocalAgentRosterRow, LocalAgentRunProgress, LocalAgentSessionRecord, LocalAgentStatus, LocalAgentToolCalls } from './types.ts';
26
26
  import { MemberInbox } from './member-inbox.ts';
27
27
  /** Stable Cordis plugin name. */
28
28
  export declare const name = "local-agent";
@@ -33,6 +33,7 @@ export type { DelegationCallOptions, LocalAgentCredentialState, DelegationExecTa
33
33
  export type { LocalAgentMemberMessage, MemberMessageOutcome, RoomMemberMessageGate, RoomMemberMessageReceipt, } from './types.ts';
34
34
  export { delegationEnv } from './env.ts';
35
35
  export { ModelDirectoryCache, extendModelDirectory, modelDirectoryContextKey } from './model-directory.ts';
36
+ export { MODEL_LIST_FILE, firstModelOf, normalizeModelList, readModelList, readModelListSync, writeModelList } from './model-list.ts';
36
37
  export { MemberConfigurationController } from './member-control.ts';
37
38
  export type { MemberConfigurationAdapter, MemberControlStorage, MemberControlRecord } from './member-control.ts';
38
39
  export { FileMemberControlStorage } from './member-control-storage.ts';
@@ -229,9 +230,7 @@ export interface LocalAgentHarness {
229
230
  homeEnvVar: string;
230
231
  /**
231
232
  * Subagent provider name this harness delegates through, when it has one.
232
- * A harness without delegation is record-and-login only. The core invariant
233
- * cross-checks this against the mounted subagent providers, so a record
234
- * that names a provider the composition does not mount fails loud.
233
+ * A harness without delegation is record-and-login only.
235
234
  */
236
235
  delegationProvider?: string;
237
236
  /**
@@ -275,6 +274,39 @@ export interface LocalAgentHarness {
275
274
  */
276
275
  isAuthenticated?: (homeDir: string) => Promise<boolean>;
277
276
  /**
277
+ * Optional host-side endpoint verification (the settings card's verify
278
+ * button): a cheap, token-free probe of the SAVED endpoint configuration,
279
+ * answered as human-readable verdict text. It rides the session-less
280
+ * gateway Remote (`checkEndpoint`) because a settings card may have no
281
+ * main agent session to run a slash command through. Absent means the
282
+ * harness has no such probe and the card must not offer the button.
283
+ */
284
+ checkEndpoint?: (homeDir: string) => Promise<string>;
285
+ /**
286
+ * Optional endpoint-credential face for the settings card: a read of the
287
+ * resolved per-field state (secrets as booleans, never echoed) and a write
288
+ * that applies edits into the harness's OWN credential store. The card
289
+ * talks to it through the session-less gateway Remotes
290
+ * (`endpointAuth`/`configureEndpoint`) instead of the volatile row-config
291
+ * channel — a credential never belongs in the profile patch document, and
292
+ * that channel rejects writes a deployment cannot explain. Absent means
293
+ * the card renders no endpoint form.
294
+ */
295
+ endpointAuth?: {
296
+ read(homeDir: string): Promise<LocalAgentEndpointAuthState>;
297
+ write(homeDir: string, fields: LocalAgentEndpointAuthFields): Promise<void>;
298
+ };
299
+ /**
300
+ * Optional curated model-list face: an ORDERED list of model identifiers
301
+ * the harness persists in its own store (its first entry is the harness's
302
+ * default model). The settings card edits it through the session-less
303
+ * `modelList`/`configureModelList` gateway Remotes. Absent means the card
304
+ * renders no model-list editor.
305
+ */
306
+ modelList?: {
307
+ read(homeDir: string): Promise<readonly string[]>;
308
+ write(homeDir: string, models: readonly string[]): Promise<readonly string[]>;
309
+ }; /**
278
310
  * The credential marker's modification stamp (epoch ms), undefined when no
279
311
  * credential exists. Two consumers: the manual-login watch requires a stamp
280
312
  * NEWER than the watch start (a stale marker must not read as a fresh
@@ -616,9 +648,9 @@ export declare class LocalAgentRegistry {
616
648
  /**
617
649
  * Per-(parent session, provider) FIFO of delegation intents. The family
618
650
  * resume tool stages exactly one intent per call before awaiting
619
- * `ctx.subagents.start()`, and the owning provider consumes exactly one per
620
- * start, so fresh and resume rounds stay paired even under parallel
621
- * delegations from one parent.
651
+ * `ctx.subagents.startActivation()`, and the owning provider consumes
652
+ * exactly one per start, so fresh and resume rounds stay paired even under
653
+ * parallel delegations from one parent.
622
654
  */
623
655
  private readonly delegationIntents;
624
656
  /**
@@ -671,10 +703,12 @@ export declare class LocalAgentRegistry {
671
703
  * - **facade-tracked** ({@link trackRun}): runs started through
672
704
  * {@link LocalAgentRegistry.start} / {@link LocalAgentRegistry.resume},
673
705
  * carrying the fused AbortController whose signal reached
674
- * `ctx.subagents.start`; cancel aborts it.
706
+ * `ctx.subagents.startActivation`; cancel aborts the pre-publication
707
+ * signal and disposes the published activation.
675
708
  * - **tool-registered** ({@link trackDelegationRun}): runs the family tool
676
- * starts directly through `ctx.subagents.start`, carrying an explicit
677
- * cancel lever (its fused controller); cancel calls it.
709
+ * starts directly through `ctx.subagents.startActivation`, carrying an
710
+ * explicit cancel lever (its fused controller plus the activation's
711
+ * dispose); cancel calls it.
678
712
  *
679
713
  * Every entry clears itself when the run's result settles (any stop
680
714
  * reason), and facade entries also stop their heartbeat timer then.
@@ -917,9 +951,10 @@ export declare class LocalAgentRegistry {
917
951
  /**
918
952
  * Stage one delegation intent for a provider's next `start()`. The family
919
953
  * resume tool stages exactly one intent per call before awaiting
920
- * `ctx.subagents.start()`; the provider consumes exactly one per start via
921
- * {@link takeDelegationIntent}, so the per-(parent, provider) FIFO pairs
922
- * fresh and resume rounds even under parallel delegations from one parent.
954
+ * `ctx.subagents.startActivation()`; the provider consumes exactly one per
955
+ * start via {@link takeDelegationIntent}, so the per-(parent, provider)
956
+ * FIFO pairs fresh and resume rounds even under parallel delegations from
957
+ * one parent.
923
958
  * @param parentSessionId - the delegating parent session id.
924
959
  * @param provider - the `ctx.subagents` provider name.
925
960
  * @param intent - the fresh or resume intent for the next start.
@@ -936,7 +971,7 @@ export declare class LocalAgentRegistry {
936
971
  takeDelegationIntent(parentSessionId: string, provider: string): LocalAgentDelegationIntent | undefined;
937
972
  /**
938
973
  * Remove one previously staged intent by reference, returning whether it was
939
- * still queued. The delegation facade calls this when `ctx.subagents.start()`
974
+ * still queued. The delegation facade calls this when `ctx.subagents.startActivation()`
940
975
  * throws: an intent the provider never consumed must not linger in the FIFO,
941
976
  * where the NEXT same-(parent, provider) start would misconsume it as its own
942
977
  * (orphan-intent crosstalk). When the provider already consumed the intent
@@ -950,9 +985,7 @@ export declare class LocalAgentRegistry {
950
985
  */
951
986
  unstageDelegationIntent(parentSessionId: string, provider: string, intent: LocalAgentDelegationIntent): boolean;
952
987
  /**
953
- * Every recorded delegation, in recording order. The invariant companion
954
- * cross-checks each record's provider against the mounted subagent
955
- * providers so a provider rename cannot leave a stale resume mapping.
988
+ * Every recorded delegation, in recording order.
956
989
  * @returns the recorded delegations.
957
990
  */
958
991
  listDelegations(): readonly LocalAgentDelegationRecord[];
@@ -1107,7 +1140,9 @@ export declare class LocalAgentRegistry {
1107
1140
  * {@link unstageDelegationIntent} (a no-op once the provider consumed it).
1108
1141
  *
1109
1142
  * The returned run is tracked under its `run.id` (== the new dsh child
1110
- * session id) until `run.result` settles; {@link cancel} aborts it by that
1143
+ * session id, minted here and carried to the provider through the staged
1144
+ * intent — host 0.2.1's `startActivation` never surfaces it on the
1145
+ * activation) until `run.result` settles; {@link cancel} aborts it by that
1111
1146
  * id. Note on trust: cordis plugins share one process, so the ownership
1112
1147
  * checks here and in {@link resume} guard against caller MISTAKES, not
1113
1148
  * against a malicious plugin — their real protection target is untrusted
@@ -1137,12 +1172,12 @@ export declare class LocalAgentRegistry {
1137
1172
  * without staging; the provider still takes the authoritative lock inside
1138
1173
  * its `start()`;
1139
1174
  * 4. live parent agent resolution (`ctx.agents.get`) — a harness hard
1140
- * constraint, since `ctx.subagents.start` requires a live parent;
1175
+ * constraint, since `ctx.subagents.startActivation` requires a live parent;
1141
1176
  * 5. child-session REATTACH when `ctx.sessions.get(childSessionId)` is
1142
1177
  * undefined (recipe below; `opts.reattach === false` disables this step
1143
1178
  * and fails loud on a non-live child instead);
1144
1179
  * 6. stage `{ kind: 'resume', childSessionId, cliSessionId }` and, in the
1145
- * same synchronous flow, `await ctx.subagents.start(provider, …)`;
1180
+ * same synchronous flow, `await ctx.subagents.startActivation({…})`;
1146
1181
  * 7. on start failure, roll the intent back via
1147
1182
  * {@link unstageDelegationIntent} (no-op once consumed);
1148
1183
  * 8. on success, track the run under `childSessionId` for {@link cancel}
@@ -1155,8 +1190,12 @@ export declare class LocalAgentRegistry {
1155
1190
  * const handle = await ctx.sessionPersistence.open(SessionId(childSessionId), 'write')
1156
1191
  * try {
1157
1192
  * const cold = await handle.read(0)
1193
+ * // Close a turn a restart interrupted, or the next round's turn/start
1194
+ * // makes the stored log unreadable.
1195
+ * const closers = interruptedTurnClosers(cold.events)
1196
+ * if (closers.length > 0) await handle.append(closers)
1158
1197
  * const session = ctx.sessions.prepare(SessionId(childSessionId), {
1159
- * seed: [...cold.events],
1198
+ * seed: [...cold.events, ...closers],
1160
1199
  * meta: structuredClone(handle.header),
1161
1200
  * inheritedEventCount: handle.inheritedEventCount,
1162
1201
  * eventState: cold.eventState,
@@ -1164,7 +1203,7 @@ export declare class LocalAgentRegistry {
1164
1203
  * // The seeded constructor's session/end-seed marker lands before enter()
1165
1204
  * // installs publication hooks — push the unstored suffix through the
1166
1205
  * // handle directly, or the writer's contiguous cursor diverges.
1167
- * const unstored = session.snapshotEvents().slice(cold.events.length)
1206
+ * const unstored = session.snapshotEvents().slice(cold.events.length + closers.length)
1168
1207
  * if (unstored.length > 0) await handle.append(unstored)
1169
1208
  * const detach = ctx.sessions.enter(session)
1170
1209
  * try { ctx.sessions.announce(session) }
@@ -1196,11 +1235,12 @@ export declare class LocalAgentRegistry {
1196
1235
  */
1197
1236
  resume(parentSessionId: string, provider: string, childSessionId: string, prompt: ContentBlock[], options?: DelegationCallOptions): Promise<SubagentRun>;
1198
1237
  /**
1199
- * Cancel an in-flight facade-started run by its dsh child session id: aborts
1200
- * the internal controller whose (fused) signal was passed to
1201
- * `ctx.subagents.start`, which is the canonical cancellation channel for a
1202
- * one-shot run. The provider settles the run with an `aborted`-class stop
1203
- * reason. A caller holding the `SubagentRun` may also `run.dispose()`.
1238
+ * Cancel an in-flight facade-started run by its dsh child session id:
1239
+ * aborts the internal controller (the pre-publication channel fused into
1240
+ * the activation's start signal) and disposes the activation — host 0.2.1's
1241
+ * canonical POST-publication cancellation, which settles the run with an
1242
+ * `aborted`-class stop reason. A caller holding the `SubagentRun` may also
1243
+ * `run.dispose()`.
1204
1244
  * @param childSessionId - the dsh child session id of the run to cancel.
1205
1245
  * @returns whether an in-flight run was found and signalled (false on a
1206
1246
  * miss — never a silent success, never a throw).
@@ -1210,16 +1250,17 @@ export declare class LocalAgentRegistry {
1210
1250
  * Register a NON-facade in-flight delegation run with the active-delegation
1211
1251
  * registry, keyed by the dsh child session id, so the `/local-agent stop`
1212
1252
  * command and {@link cancel} can reach it. This is the family TOOL's entry
1213
- * point: the tool starts its runs through `ctx.subagents.start` directly
1214
- * (not the facade), so without this registration its in-flight runs would
1215
- * be invisible to the stop command. The caller owns the cancel lever — a
1216
- * controller fused with the run's request signal, aborted exactly like the
1217
- * facade's tracked controller. The entry clears itself when the run's
1218
- * result settles (any stop reason); an existing facade entry for the same
1219
- * child session wins (it already owns cancellation and progress).
1220
- * @param childSessionId - the dsh child session id (the run id).
1221
- * @param run - the published subagent run.
1222
- * @param cancel - the lever that aborts the run's request signal.
1253
+ * point: the tool starts its runs through `ctx.subagents.startActivation`
1254
+ * directly (not the facade), so without this registration its in-flight
1255
+ * runs would be invisible to the stop command. The caller owns the cancel
1256
+ * lever — aborting the fused controller (pre-publication) and disposing the
1257
+ * activation (post-publication), the same channels the facade drives. The
1258
+ * entry clears itself when the run's result settles (any stop reason); an
1259
+ * existing facade entry for the same child session wins (it already owns
1260
+ * cancellation and progress).
1261
+ * @param childSessionId - the dsh child session id.
1262
+ * @param run - the published subagent run (the tool's activation adapter).
1263
+ * @param cancel - the lever that cancels the run.
1223
1264
  */
1224
1265
  trackDelegationRun(childSessionId: string, run: SubagentRun, cancel: () => void): void;
1225
1266
  /**
@@ -1267,7 +1308,7 @@ export declare class LocalAgentRegistry {
1267
1308
  * from persistence when it is not — a host restart evicts every child from
1268
1309
  * the live store. This is the public entry of the facade resume's reattach
1269
1310
  * recipe for callers that start resume rounds WITHOUT the facade (the
1270
- * family subagent tool starts runs directly through `ctx.subagents.start`;
1311
+ * family subagent tool starts runs directly through `ctx.subagents.startActivation`;
1271
1312
  * without this call the provider refuses the resume as "not live").
1272
1313
  * Idempotent; a child that was never persisted fails through the
1273
1314
  * persistence layer's own not-found error.
@@ -1299,6 +1340,18 @@ export declare class LocalAgentRegistry {
1299
1340
  * @param session - the live child session to sync.
1300
1341
  */
1301
1342
  syncChildSession(session: Session, strict?: boolean): Promise<void>;
1343
+ /**
1344
+ * One sync pass. While the write handle is open the host routes every live
1345
+ * append into the writer's buffer, so the routed events are drained first
1346
+ * (`sessions.flush`: drain + flush) and only what is STILL missing — events
1347
+ * from before the handle opened, or a host that routes nothing — goes in
1348
+ * explicitly, bounded to the events that existed before the drain. Appending
1349
+ * routed-but-undrained events explicitly as well would land them twice: the
1350
+ * explicit write wins, the buffered copy then fails contiguity forever, and
1351
+ * every later flush — the host's tool-execution checkpoint included —
1352
+ * throws "append seq mismatch".
1353
+ */
1354
+ private syncChildSessionOnce;
1302
1355
  /**
1303
1356
  * Get or open the child session's registry-owned WRITE handle (the
1304
1357
  * {@link childWriteHandles} cache). When the caller carries the session