@timurproko/a1 0.2.6-dev.734 → 0.2.6-dev.736

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 (28) hide show
  1. package/dist/app/session-shell/index.d.ts +2 -2
  2. package/dist/app/session-shell/index.js +1 -1
  3. package/dist/app/session-shell/session-shell-root.d.ts +9 -1
  4. package/dist/app/session-shell/session-shell-root.js +56 -47
  5. package/dist/app/session-shell/session-shell.d.ts +37 -9
  6. package/dist/app/session-shell/session-shell.js +266 -446
  7. package/dist/app/session-shell/shell-host.d.ts +105 -0
  8. package/dist/app/session-shell/shell-host.js +523 -0
  9. package/dist/cli/session-context.js +6 -3
  10. package/dist/composition/owned-ui.js +45 -25
  11. package/dist/contracts/owned-ui/index.d.ts +1 -1
  12. package/dist/contracts/owned-ui/session-presenters.d.ts +35 -8
  13. package/dist/features/launch/index.d.ts +1 -1
  14. package/dist/features/launch/index.js +1 -1
  15. package/dist/features/launch/session-context.d.ts +1 -0
  16. package/dist/features/launch/session-context.js +1 -0
  17. package/dist/foundation/lifecycle/index.d.ts +1 -1
  18. package/dist/foundation/lifecycle/index.js +1 -1
  19. package/dist/foundation/lifecycle/session-repository-context.d.ts +8 -2
  20. package/dist/foundation/lifecycle/session-repository-context.js +200 -65
  21. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +11 -0
  22. package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +18 -2
  23. package/dist/native/darwin-arm64/manifest.json +1 -1
  24. package/dist/native/linux-x64/manifest.json +1 -1
  25. package/dist/native/win32-x64/manifest.json +2 -2
  26. package/dist/native/win32-x64/process-guardian.exe +0 -0
  27. package/docs/architecture/ui-reference-provenance.md +1 -1
  28. package/package.json +1 -1
@@ -12,7 +12,7 @@ import { createPiSessionPresenters } from "../integrations/pi/session-presenters
12
12
  import { ClipboardDiagnosticCapture } from "../app/session-shell/clipboard-diagnostics.js";
13
13
  import { createOwnedUiClipboardServices } from "../app/session-shell/clipboard-services.js";
14
14
  import { createPiKeybindingsHost } from "../integrations/pi/components/shell-shared-facade.js";
15
- import { OwnedUiSessionShell } from "../app/session-shell/session-shell.js";
15
+ import { OwnedUiSessionPresenter, OwnedUiTerminalHost, sessionTerminalHostOptions, } from "../app/session-shell/session-shell.js";
16
16
  import { OwnedSettingsManager } from "../ui/settings/manager.js";
17
17
  import { createPiTerminalBridge } from "../integrations/pi/tui-runtime/presentation-adapter.js";
18
18
  import { createOwnedRouteHost } from "./settings-route-host.js";
@@ -28,7 +28,8 @@ export async function composeOwnedUi(options = {}) {
28
28
  const sessionRuntimeId = ownedSurfaces ? process.env[PRODUCT_IDENTITY.environment.sessionRuntimeId] : undefined;
29
29
  const inspectSessionProcess = options.inspectProcess;
30
30
  let sessionRuntimeIdentity = null;
31
- let activeSessionIdentity = null;
31
+ // Invariant: one entry per agent of this runtime; each agent holds its own claim, and the runtime's exit releases all.
32
+ const activeSessionIdentities = new Map();
32
33
  let sessionRuntimeRefreshTimer = null;
33
34
  let sessionRuntimeRefresh = Promise.resolve();
34
35
  let sessionRuntimeDisposed = false;
@@ -39,19 +40,41 @@ export async function composeOwnedUi(options = {}) {
39
40
  return await sessionRuntimeIdentity;
40
41
  };
41
42
  const queueSessionRuntimeRefresh = () => {
42
- if (sessionRuntimeDisposed || activeSessionIdentity === null || sessionRuntimeId === undefined || inspectSessionProcess === undefined)
43
+ if (sessionRuntimeDisposed || activeSessionIdentities.size === 0 || sessionRuntimeId === undefined || inspectSessionProcess === undefined)
43
44
  return;
44
45
  sessionRuntimeRefresh = sessionRuntimeRefresh.then(async () => {
45
- const identity = activeSessionIdentity;
46
- if (sessionRuntimeDisposed || identity === null)
46
+ if (sessionRuntimeDisposed)
47
47
  return;
48
48
  const owner = await runtimeIdentity();
49
49
  if (owner === null)
50
50
  return;
51
51
  const { registerSessionRepositoryRuntime } = await import("../foundation/lifecycle/session-repository-context.js");
52
- await registerSessionRepositoryRuntime(identity, sessionRuntimeId, owner, { inspectProcess: inspectSessionProcess });
52
+ for (const [agentId, identity] of activeSessionIdentities) {
53
+ if (sessionRuntimeDisposed)
54
+ return;
55
+ await registerSessionRepositoryRuntime(identity, sessionRuntimeId, owner, {
56
+ inspectProcess: inspectSessionProcess,
57
+ ...(agentId === undefined ? {} : { agentId }),
58
+ }).catch(() => undefined);
59
+ }
53
60
  }).catch(() => undefined);
54
61
  };
62
+ /** The repository context reader for one agent; undefined names the primary agent, the only one composed today. */
63
+ const repositoryContextReaderFor = (agentId) => async (sessionId, sessionFile, signal) => {
64
+ const owner = await runtimeIdentity();
65
+ if (owner === null || sessionRuntimeId === undefined || inspectSessionProcess === undefined)
66
+ return null;
67
+ const identity = { sessionId, sessionFile };
68
+ activeSessionIdentities.set(agentId, identity);
69
+ const { activateSessionRepositoryContext } = await import("../foundation/lifecycle/session-repository-context.js");
70
+ const context = await activateSessionRepositoryContext(identity, sessionRuntimeId, owner, {
71
+ signal,
72
+ inspectProcess: inspectSessionProcess,
73
+ ...(agentId === undefined ? {} : { agentId }),
74
+ });
75
+ armSessionRuntimeRefresh();
76
+ return context;
77
+ };
55
78
  const armSessionRuntimeRefresh = () => {
56
79
  if (sessionRuntimeRefreshTimer !== null)
57
80
  return;
@@ -87,18 +110,7 @@ export async function composeOwnedUi(options = {}) {
87
110
  try {
88
111
  backend = await host.create({
89
112
  cwd,
90
- ...(ownedSurfaces ? {
91
- repositoryContextReader: async (sessionId, sessionFile, signal) => {
92
- const owner = await runtimeIdentity();
93
- if (owner === null || sessionRuntimeId === undefined || inspectSessionProcess === undefined)
94
- return null;
95
- activeSessionIdentity = { sessionId, sessionFile };
96
- const { activateSessionRepositoryContext } = await import("../foundation/lifecycle/session-repository-context.js");
97
- const context = await activateSessionRepositoryContext(activeSessionIdentity, sessionRuntimeId, owner, { signal, inspectProcess: inspectSessionProcess });
98
- armSessionRuntimeRefresh();
99
- return context;
100
- },
101
- } : {}),
113
+ ...(ownedSurfaces ? { repositoryContextReader: repositoryContextReaderFor(undefined) } : {}),
102
114
  ...(options.sessionPath === undefined ? {} : { sessionPath: options.sessionPath }),
103
115
  ...(options.sessionSelection === undefined ? {} : { sessionSelection: options.sessionSelection }),
104
116
  ...(options.sessionForkPrompt === undefined ? {} : { sessionForkPrompt: options.sessionForkPrompt }),
@@ -140,7 +152,7 @@ export async function composeOwnedUi(options = {}) {
140
152
  return { rows: width => renderPiShellChangelogLines(markdown, width).map(row => nativeHyperlinkStyle(row)) };
141
153
  },
142
154
  hotkeys: async () => {
143
- const presentation = shell.hotkeysPresentation();
155
+ const presentation = presenter.hotkeysPresentation();
144
156
  const { renderPiShellHotkeySections } = await import("../integrations/pi/components/shell-hotkey-sections.js");
145
157
  return { sections: width => renderPiShellHotkeySections(presentation, width) };
146
158
  },
@@ -194,10 +206,12 @@ export async function composeOwnedUi(options = {}) {
194
206
  // keybinding registry is applied before any presenter is built, so none of them reads Pi's defaults.
195
207
  const keybindings = createPiKeybindingsHost({ profile: ownedSurfaces ? "a1" : "pi", agentDir: backend.identity.agentDir });
196
208
  const clipboardServices = ownedSurfaces ? createOwnedUiClipboardServices() : null;
197
- let shell;
209
+ let createdTerminalHost;
210
+ let terminalHost;
211
+ let presenter;
198
212
  let releaseNoteAcknowledgement = null;
199
213
  try {
200
- shell = new OwnedUiSessionShell({
214
+ const presenterOptions = {
201
215
  presenters: createPiSessionPresenters(backend),
202
216
  engine: {
203
217
  backend,
@@ -236,9 +250,15 @@ export async function composeOwnedUi(options = {}) {
236
250
  ...promptHistory,
237
251
  editor: await import("../integrations/pi/components/history-editor-loader.js").then(module => module.loadHistoryEditor()),
238
252
  } }),
239
- });
253
+ };
254
+ // Invariant: one terminal host owns the process terminal; the session presenter reaches it only through
255
+ // the host and paints once attached.
256
+ terminalHost = createdTerminalHost = new OwnedUiTerminalHost(sessionTerminalHostOptions(presenterOptions));
257
+ presenter = new OwnedUiSessionPresenter(terminalHost, presenterOptions);
258
+ terminalHost.attach(presenter);
240
259
  }
241
260
  catch (error) {
261
+ await createdTerminalHost?.dispose().catch(() => undefined);
242
262
  unsubscribeAccent();
243
263
  await releaseNoteClaim?.release();
244
264
  clipboardDiagnostics?.dispose();
@@ -273,14 +293,14 @@ export async function composeOwnedUi(options = {}) {
273
293
  if (exitNoticePath)
274
294
  exitNotice = import("../app/session-shell/exit-notice.js")
275
295
  .then(module => module.armExitNotice(backend, exitNoticePath), () => null);
276
- shell.start();
296
+ presenter.start();
277
297
  void announceNewerRelease().catch(() => undefined);
278
298
  },
279
299
  flush: () => backend.session.flushEvents(),
280
- waitUntilStopped: () => shell.waitUntilStopped(),
300
+ waitUntilStopped: () => presenter.waitUntilStopped(),
281
301
  dispose: async () => {
282
302
  try {
283
- await shell.dispose();
303
+ await terminalHost.dispose();
284
304
  // Invariant: cleared only once the terminal is restored; a failed dispose leaves it armed.
285
305
  (await exitNotice)?.clear();
286
306
  await releaseNoteAcknowledgement?.catch(() => undefined);
@@ -5,7 +5,7 @@ export type { OwnedUiExtensionAutocompleteItem, OwnedUiExtensionAutocompleteProv
5
5
  export { OWNED_UI_CONTRACT_VERSION } from "./model.js";
6
6
  export type { OwnedUiBackgroundSettingsPort, OwnedUiBackgroundStyle, OwnedUiBlockStatus, OwnedUiCommand, OwnedUiCommandOutcome, OwnedUiCorrelationId, OwnedUiCustomization, OwnedUiDiagnostics, OwnedUiDialog, OwnedUiEditorState, OwnedUiEntityId, OwnedUiEvent, OwnedUiFooterView, OwnedUiImageAttachment, OwnedUiLifecycle, OwnedUiModelInfo, OwnedUiOverlay, OwnedUiPromptSuggestionGeneratorPort, OwnedUiPromptSuggestionIdentity, OwnedUiPromptSuggestionReasoning, OwnedUiPromptSuggestionRequest, OwnedUiPromptSuggestionResult, OwnedUiPromptSuggestionState, OwnedUiQuitOutroSettings, OwnedUiQuitOutroSettingsPort, OwnedUiSessionId, OwnedUiSessionViewModel, OwnedUiSeverity, OwnedUiSlotId, OwnedUiSnapshot, OwnedUiStatusView, OwnedUiTerminalSurface, OwnedUiThinkingLevel, OwnedUiToolRendering, OwnedUiToolResultPart, OwnedUiToolState, OwnedUiTranscriptBlock, OwnedUiTranscriptBlockKind, OwnedUiTranscriptImageReference, OwnedUiUsageView, OwnedUiViewportSettings, OwnedUiViewportSettingsPort, } from "./model.js";
7
7
  export type { OwnedUiExtensionPort, OwnedUiSessionBackend, OwnedUiSessionCatalogPort, OwnedUiSessionFactory, OwnedUiSessionIdentityPort, OwnedUiSessionPort, OwnedUiSessionRequest, OwnedUiSessionSettingsPort, OwnedUiWorkflowPort, } from "./session-backend.js";
8
- export type { OwnedUiDialogHost, OwnedUiInputSurface, OwnedUiSessionPresenters, OwnedUiShortcutDescription, OwnedUiTranscriptRendererPort, } from "./session-presenters.js";
8
+ export type { OwnedUiDialogHost, OwnedUiInputSurface, OwnedUiPresenterHost, OwnedUiSessionPresenter, OwnedUiSessionPresenters, OwnedUiShortcutDescription, OwnedUiTerminalHost, OwnedUiTranscriptRendererPort, } from "./session-presenters.js";
9
9
  export { OWNED_UI_HIDDEN_COMMAND_NAMES, OWNED_UI_MODELS_COMMAND_NAME, OWNED_UI_WORKFLOW_COMMAND_NAMES, } from "./session-workflows.js";
10
10
  export type { OwnedUiAmbientAuthentication, OwnedUiAuthenticationProviderOption, OwnedUiAuthenticationProviderStatus, OwnedUiBashWorkflowResult, OwnedUiCacheWarmingPresentation, OwnedUiCommandResult, OwnedUiExtensionResourceSummary, OwnedUiExtensionSourceSummary, OwnedUiHiddenWorkflowCommandName, OwnedUiJsonValue, OwnedUiModelsCommandName, OwnedUiModelsContext, OwnedUiModelsRefreshResult, OwnedUiProjectTrustContext, OwnedUiProjectTrustUpdate, OwnedUiReleaseUpdate, OwnedUiResourceSummary, OwnedUiScopedModelDescriptor, OwnedUiScopedModelsContext, OwnedUiScopedModelsRefreshResult, OwnedUiSessionInfoPresentation, OwnedUiSessionProductMode, OwnedUiSessionResumeMetadata, OwnedUiSessionSettingKey, OwnedUiSessionSettingsSnapshot, OwnedUiSettingEffectHandler, OwnedUiSettingOwner, OwnedUiSettingOwnerHandlers, OwnedUiSettingsThinkingLevel, OwnedUiVisualExtensionSupport, OwnedUiWorkflowAutocompleteCommand, OwnedUiWorkflowCommandName, OwnedUiWorkflowInteractionHost, OwnedUiWorkflowInteractionRequest, OwnedUiWorkflowLoginNotification, OwnedUiWorkflowLoginStart, OwnedUiWorkflowMessage, OwnedUiWorkflowMessageKind, OwnedUiWorkflowOption, OwnedUiWorkflowOutcome, OwnedUiWorkflowPresentation, OwnedUiWorkflowRequest, OwnedUiWorkflowResult, OwnedUiWorkflowRoute, } from "./session-workflows.js";
11
11
  export { acceptsTranscriptUpdate, transcriptToolState } from "./transcript-lifecycle.js";
@@ -11,21 +11,48 @@ export interface OwnedUiInputSurface {
11
11
  setFocused?(focused: boolean): void;
12
12
  dispose?(): void;
13
13
  }
14
- /** The shell's side of a presenter: where the selector is shown and how its choices reach the session. */
15
- export interface OwnedUiDialogHost {
16
- /** True once the shell is disposed; a presenter that awaited stops before showing anything. */
17
- readonly disposed: boolean;
18
- setInputSurface(surface: OwnedUiInputSurface | null): void;
19
- requestRender(): void;
14
+ /**
15
+ * The terminal as one session presenter sees it. A render request from a presenter that is not the host's
16
+ * active presenter paints nothing; the presenter keeps its state current and paints once it is attached.
17
+ */
18
+ export interface OwnedUiPresenterHost {
19
+ requestRender(force?: boolean): void;
20
20
  viewport(): {
21
21
  readonly columns: number;
22
22
  readonly rows: number;
23
23
  };
24
+ /** Present only where the shell holds frames while an optional selector module loads. */
25
+ beginPresentationHold?(): () => void;
26
+ }
27
+ /** One engine session's presentation: its transcript, editor, controllers, and dialogs, and nothing terminal-wide. */
28
+ export interface OwnedUiSessionPresenter {
29
+ render(width: number): readonly string[];
30
+ handleInput(data: string): void;
31
+ invalidate(): void;
32
+ setFocused(focused: boolean): void;
33
+ start(): void;
34
+ waitUntilStopped(): Promise<void>;
35
+ dispose(): Promise<void>;
36
+ }
37
+ /** Owns the process terminal and shows exactly one active presenter. */
38
+ export interface OwnedUiTerminalHost<Presenter extends OwnedUiSessionPresenter = OwnedUiSessionPresenter> {
39
+ /** Makes the presenter active; its first frame is a full paint. */
40
+ attach(presenter: Presenter): void;
41
+ active(): Presenter | null;
42
+ /** No-op unless `from` is the active presenter. */
43
+ requestRender(from: Presenter, force?: boolean): void;
44
+ start(): void;
45
+ /** Ends the terminal: every presenter is released, the quit presentation plays, and the terminal is restored. */
46
+ dispose(): Promise<void>;
47
+ }
48
+ /** The shell's side of a presenter: where the selector is shown and how its choices reach the session. */
49
+ export interface OwnedUiDialogHost extends OwnedUiPresenterHost {
50
+ /** True once the shell is disposed; a presenter that awaited stops before showing anything. */
51
+ readonly disposed: boolean;
52
+ setInputSurface(surface: OwnedUiInputSurface | null): void;
24
53
  appendWorkflowStatus(text: string): void;
25
54
  appendWorkflowResult(result: OwnedUiWorkflowResult): void;
26
55
  runWorkflow(request: OwnedUiWorkflowRequest): Promise<OwnedUiCommandResult>;
27
- /** Present only where the shell holds frames while an optional selector module loads. */
28
- beginPresentationHold?(): () => void;
29
56
  /** Present only where the surface can change TUI mode; false means overlays block the switch. */
30
57
  switchTuiMode?(mode: "regular" | "fullscreen"): boolean;
31
58
  }
@@ -8,7 +8,7 @@ export { configurationRootForProfile, resolveLaunchProfilePaths, resolvePromptHi
8
8
  export type { LaunchProfilePathOptions, LaunchProfilePaths } from "./profile-paths.js";
9
9
  export { prepareInteractiveLaunch } from "./prepare-launch.js";
10
10
  export type { PrepareInteractiveLaunchOptions, PreparedInteractiveLaunch } from "./prepare-launch.js";
11
- export { updateSessionRepositoryContext } from "./session-context.js";
11
+ export { PRIMARY_SESSION_AGENT_ID, updateSessionRepositoryContext } from "./session-context.js";
12
12
  export type { SessionContextOutcome, SessionContextRequest, SessionContextRuntime } from "./session-context.js";
13
13
  export { runSelectedInteractiveRuntime, selectInteractiveRuntime } from "./runtime-selection.js";
14
14
  export type { InteractiveRuntimeRunners, InteractiveRuntimeSelection, OwnedUiProfileId } from "./runtime-selection.js";
@@ -3,5 +3,5 @@ export { PI_PROFILE_RESOURCE_DIRECTORIES, initializeProductProfile } from "./ini
3
3
  export { interactiveLaunchIntent, parseSessionSelection } from "./intent.js";
4
4
  export { configurationRootForProfile, resolveLaunchProfilePaths, resolvePromptHistoryDataDir } from "./profile-paths.js";
5
5
  export { prepareInteractiveLaunch } from "./prepare-launch.js";
6
- export { updateSessionRepositoryContext } from "./session-context.js";
6
+ export { PRIMARY_SESSION_AGENT_ID, updateSessionRepositoryContext } from "./session-context.js";
7
7
  export { runSelectedInteractiveRuntime, selectInteractiveRuntime } from "./runtime-selection.js";
@@ -1,4 +1,5 @@
1
1
  import { type NativeProcessIdentity, type SessionRepositoryIdentity, type SessionWorktreeInventoryEntry } from "../../foundation/lifecycle/index.js";
2
+ export { PRIMARY_SESSION_AGENT_ID } from "../../foundation/lifecycle/index.js";
2
3
  export type SessionContextRequest = {
3
4
  readonly action: "link-worktree";
4
5
  readonly path: string;
@@ -1,4 +1,5 @@
1
1
  import { clearSessionRepositoryContext, listSessionRepositoryWorktrees, setSessionRepositoryContext, } from "../../foundation/lifecycle/index.js";
2
+ export { PRIMARY_SESSION_AGENT_ID } from "../../foundation/lifecycle/index.js";
2
3
  export async function updateSessionRepositoryContext(identity, request, runtime) {
3
4
  const options = { runtimeId: runtime.runtimeId, inspectProcess: runtime.inspectProcess };
4
5
  if (request.action === "unlink-worktree") {
@@ -7,7 +7,7 @@ export { resolveCohortEndpoint, resolveProductPaths } from "./paths.js";
7
7
  export type { CohortEndpointPaths, ProductPaths } from "./paths.js";
8
8
  export { parseSessionSelection, sessionSelectionArguments } from "./session-selection.js";
9
9
  export type { SessionSelection } from "./session-selection.js";
10
- export { activateSessionRepositoryContext, clearSessionRepositoryContext, listSessionRepositoryWorktrees, readSessionRepositoryContext, registerSessionRepositoryRuntime, releaseSessionRepositoryRuntime, setSessionRepositoryContext, } from "./session-repository-context.js";
10
+ export { PRIMARY_SESSION_AGENT_ID, activateSessionRepositoryContext, clearSessionRepositoryContext, listSessionRepositoryWorktrees, readSessionRepositoryContext, registerSessionRepositoryRuntime, releaseSessionRepositoryRuntime, setSessionRepositoryContext, } from "./session-repository-context.js";
11
11
  export type { SessionRepositoryContext, SessionRepositoryContextOptions, SessionRepositoryIdentity, SessionWorktreeInventoryEntry, SessionWorktreeStatus, } from "./session-repository-context.js";
12
12
  export { createSupervisorStartupAttempt, publishSupervisorStartupResult, readSupervisorStartupResult, supervisorStartupFailure, supervisorStartupReady, supervisorStartupResultPath, } from "./supervisor-startup.js";
13
13
  export type { SupervisorStartupAttemptIdentity, SupervisorStartupResult } from "./supervisor-startup.js";
@@ -2,5 +2,5 @@ export { assertLaunchInstance, assertLaunchInstanceOutcome, assertLaunchInstance
2
2
  export { assertDimensions, assertLaunchProfileId, assertNativeProcessIdentity, assertTransparentTerminalLaunchProfile } from "./model.js";
3
3
  export { resolveCohortEndpoint, resolveProductPaths } from "./paths.js";
4
4
  export { parseSessionSelection, sessionSelectionArguments } from "./session-selection.js";
5
- export { activateSessionRepositoryContext, clearSessionRepositoryContext, listSessionRepositoryWorktrees, readSessionRepositoryContext, registerSessionRepositoryRuntime, releaseSessionRepositoryRuntime, setSessionRepositoryContext, } from "./session-repository-context.js";
5
+ export { PRIMARY_SESSION_AGENT_ID, activateSessionRepositoryContext, clearSessionRepositoryContext, listSessionRepositoryWorktrees, readSessionRepositoryContext, registerSessionRepositoryRuntime, releaseSessionRepositoryRuntime, setSessionRepositoryContext, } from "./session-repository-context.js";
6
6
  export { createSupervisorStartupAttempt, publishSupervisorStartupResult, readSupervisorStartupResult, supervisorStartupFailure, supervisorStartupReady, supervisorStartupResultPath, } from "./supervisor-startup.js";
@@ -1,4 +1,6 @@
1
1
  import type { NativeProcessIdentity } from "./model.js";
2
+ /** Records without an agent id were written by a single-agent release and belong to its one agent. */
3
+ export declare const PRIMARY_SESSION_AGENT_ID = "primary";
2
4
  export interface SessionRepositoryIdentity {
3
5
  readonly sessionId: string;
4
6
  readonly sessionFile: string;
@@ -10,20 +12,24 @@ export interface SessionRepositoryContext {
10
12
  export type SessionWorktreeStatus = "current" | "busy" | "available" | "unverifiable";
11
13
  export interface SessionWorktreeInventoryEntry extends SessionRepositoryContext {
12
14
  readonly status: SessionWorktreeStatus;
15
+ /** Agent holding the claim within its runtime; null when the worktree is unclaimed or unverifiable. */
16
+ readonly agentId: string | null;
13
17
  }
14
18
  export interface SessionRepositoryContextOptions {
15
19
  readonly dataDir?: string;
16
20
  readonly signal?: AbortSignal;
17
21
  readonly runtimeId?: string;
22
+ /** Agent within the runtime that owns the claim; defaults to the primary agent. */
23
+ readonly agentId?: string;
18
24
  readonly runtimeIdentity?: NativeProcessIdentity;
19
25
  readonly inspectProcess?: (pid: number) => Promise<NativeProcessIdentity | null>;
20
26
  readonly lockTimeoutMs?: number;
21
27
  }
22
28
  /** Publish the exact live runtime that may acquire a delivery worktree. */
23
29
  export declare function registerSessionRepositoryRuntime(identity: SessionRepositoryIdentity, runtimeId: string, runtimeIdentity: NativeProcessIdentity, options?: SessionRepositoryContextOptions): Promise<void>;
24
- /** Revalidate a durable association and acquire its live claim for this runtime. */
30
+ /** Revalidate a durable association and acquire its live claim for this runtime's agent; sibling agents' claims stay. */
25
31
  export declare function activateSessionRepositoryContext(identity: SessionRepositoryIdentity, runtimeId: string, runtimeIdentity: NativeProcessIdentity, options?: SessionRepositoryContextOptions): Promise<SessionRepositoryContext | null>;
26
- /** Release only this exact runtime generation's cooperative editing claims. */
32
+ /** Release every agent's cooperative editing claims held by this exact runtime generation. */
27
33
  export declare function releaseSessionRepositoryRuntime(runtimeId: string, runtimeIdentity: NativeProcessIdentity, options?: SessionRepositoryContextOptions): Promise<void>;
28
34
  /** Persist one explicit same-repository worktree association after atomically claiming it. */
29
35
  export declare function setSessionRepositoryContext(identity: SessionRepositoryIdentity, worktreePath: string, options?: SessionRepositoryContextOptions): Promise<SessionRepositoryContext>;