opencode-zellij 0.0.13 → 0.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -39,7 +39,7 @@ async function installedPackageMetadata(installRoot) {
39
39
  try {
40
40
  const content = await readFile(join(packageDir(installRoot), "package.json"), "utf8");
41
41
  const pkg = JSON.parse(content);
42
- if (isRecord$1(pkg)) return {
42
+ if (isRecord$2(pkg)) return {
43
43
  name: typeof pkg.name === "string" ? pkg.name : void 0,
44
44
  version: typeof pkg.version === "string" ? pkg.version : void 0,
45
45
  main: typeof pkg.main === "string" ? pkg.main : void 0
@@ -107,7 +107,7 @@ async function findInstallContext(importMetaUrl) {
107
107
  try {
108
108
  const content = await readFile(packageJsonPath, "utf8");
109
109
  const pkg = JSON.parse(content);
110
- if (isRecord$1(pkg) && pkg.name === "opencode-zellij" && typeof pkg.version === "string" && pkg.version.length > 0) {
110
+ if (isRecord$2(pkg) && pkg.name === "opencode-zellij" && typeof pkg.version === "string" && pkg.version.length > 0) {
111
111
  const installRoot = dirname(dirname(dir));
112
112
  if (existsSync(join(installRoot, "package.json"))) return {
113
113
  installRoot,
@@ -124,7 +124,7 @@ async function findInstallContext(importMetaUrl) {
124
124
  dir = parent;
125
125
  }
126
126
  }
127
- function isRecord$1(value) {
127
+ function isRecord$2(value) {
128
128
  return typeof value === "object" && value !== null;
129
129
  }
130
130
  function isAutoUpdatableSpec(spec) {
@@ -143,7 +143,7 @@ async function fetchLatestVersion(fetchImpl = globalThis.fetch) {
143
143
  return;
144
144
  }
145
145
  const data = await response.json();
146
- if (isRecord$1(data) && typeof data.latest === "string") return data.latest;
146
+ if (isRecord$2(data) && typeof data.latest === "string") return data.latest;
147
147
  debug("npm registry response missing latest tag");
148
148
  return;
149
149
  } catch (cause) {
@@ -584,7 +584,7 @@ function numericProperty(object, keys) {
584
584
  }
585
585
  }
586
586
  }
587
- function stringProperty$1(object, keys) {
587
+ function stringProperty$2(object, keys) {
588
588
  for (const key of keys) {
589
589
  const value = object[key];
590
590
  if (typeof value === "string") return value;
@@ -643,7 +643,7 @@ function parsePaneExists(listPanesJson, paneId) {
643
643
  function tabNameProperty(object, tabId) {
644
644
  if (tabId === void 0) return void 0;
645
645
  if (numericProperty(object, ["tab_id", "tabId"]) !== tabId) return void 0;
646
- const name = stringProperty$1(object, ["name", "title"]);
646
+ const name = stringProperty$2(object, ["name", "title"]);
647
647
  return typeof name === "string" ? name : void 0;
648
648
  }
649
649
  function findTabName(value, tabId) {
@@ -2226,41 +2226,21 @@ function exitAfterCleanup(signal, code) {
2226
2226
  //#endregion
2227
2227
  //#region src/zellij/tab-title-events.ts
2228
2228
  const execFileAsync = promisify(execFile);
2229
- function isRecord(value) {
2229
+ function isRecord$1(value) {
2230
2230
  return typeof value === "object" && value !== null;
2231
2231
  }
2232
- function stringProperty(object, key) {
2232
+ function stringProperty$1(object, key) {
2233
2233
  const value = object[key];
2234
2234
  return typeof value === "string" ? value : void 0;
2235
2235
  }
2236
- function nestedStringProperty(object, key, nestedKey) {
2236
+ function nestedStringProperty$1(object, key, nestedKey) {
2237
2237
  const nested = object[key];
2238
- if (!isRecord(nested)) return void 0;
2239
- return stringProperty(nested, nestedKey);
2240
- }
2241
- function sessionStatusProperty(object) {
2242
- const status = object.status;
2243
- if (!isRecord(status)) return void 0;
2244
- if (status.type === "idle" || status.type === "busy") return { type: status.type };
2245
- if (status.type === "retry") return {
2246
- type: "retry",
2247
- attempt: typeof status.attempt === "number" ? status.attempt : 0,
2248
- message: typeof status.message === "string" ? status.message : "",
2249
- next: typeof status.next === "number" ? status.next : 0
2250
- };
2251
- }
2252
- function inputRequestID(object) {
2253
- return stringProperty(object, "id") ?? stringProperty(object, "requestID") ?? stringProperty(object, "permissionID");
2238
+ if (!isRecord$1(nested)) return void 0;
2239
+ return stringProperty$1(nested, nestedKey);
2254
2240
  }
2255
- function inputState(object) {
2256
- return (stringProperty(object, "status") ?? stringProperty(object, "state") ?? stringProperty(object, "type"))?.toLowerCase();
2257
- }
2258
- function isResolvedInputState(state) {
2259
- return state === "approved" || state === "denied" || state === "rejected" || state === "resolved" || state === "replied";
2260
- }
2261
- function deletedSessionID(event) {
2262
- if (!isRecord(event.properties)) return void 0;
2263
- return nestedStringProperty(event.properties, "info", "id") ?? stringProperty(event.properties, "sessionID");
2241
+ function deletedSessionID$1(event) {
2242
+ if (!isRecord$1(event.properties)) return void 0;
2243
+ return nestedStringProperty$1(event.properties, "info", "id") ?? stringProperty$1(event.properties, "sessionID");
2264
2244
  }
2265
2245
  async function readGitBranch(worktree) {
2266
2246
  return (await execFileAsync("git", [
@@ -2285,70 +2265,6 @@ async function getInitialBranch(worktree, readBranch = readGitBranch) {
2285
2265
  function shouldReadInitialBranch(zellij) {
2286
2266
  return Boolean(zellij);
2287
2267
  }
2288
- function handleTabTitleEvent(tabTitleManager, event) {
2289
- if (event.type === "server.instance.disposed" || event.type === "global.disposed") return tabTitleManager.destroy?.();
2290
- if (!isRecord(event.properties)) return;
2291
- const properties = event.properties;
2292
- switch (event.type) {
2293
- case "session.status": {
2294
- const sessionID = stringProperty(properties, "sessionID");
2295
- const status = sessionStatusProperty(properties);
2296
- if (sessionID && status) if (status.type === "idle") tabTitleManager.markSessionIdle(sessionID);
2297
- else tabTitleManager.updateSessionStatus(sessionID, status);
2298
- break;
2299
- }
2300
- case "session.idle": {
2301
- const sessionID = stringProperty(properties, "sessionID");
2302
- if (sessionID) tabTitleManager.markSessionIdle(sessionID);
2303
- break;
2304
- }
2305
- case "session.error": {
2306
- const sessionID = stringProperty(properties, "sessionID");
2307
- if (sessionID) tabTitleManager.markSessionIdle(sessionID);
2308
- break;
2309
- }
2310
- case "vcs.branch.updated":
2311
- tabTitleManager.setBranch(stringProperty(properties, "branch"));
2312
- break;
2313
- case "question.asked":
2314
- case "permission.asked": {
2315
- const id = inputRequestID(properties);
2316
- const sessionID = stringProperty(properties, "sessionID");
2317
- if (id && sessionID) {
2318
- tabTitleManager.markNeedsInput(id, sessionID);
2319
- tabTitleManager.updateSessionStatus(sessionID, { type: "busy" });
2320
- }
2321
- break;
2322
- }
2323
- case "permission.updated": {
2324
- const id = inputRequestID(properties);
2325
- const sessionID = stringProperty(properties, "sessionID");
2326
- const state = inputState(properties);
2327
- if (id && isResolvedInputState(state)) {
2328
- tabTitleManager.clearNeedsInput(id);
2329
- if (sessionID) tabTitleManager.updateSessionStatus(sessionID, { type: "busy" });
2330
- } else if (id && sessionID) {
2331
- tabTitleManager.markNeedsInput(id, sessionID);
2332
- tabTitleManager.updateSessionStatus(sessionID, { type: "busy" });
2333
- }
2334
- break;
2335
- }
2336
- case "question.replied":
2337
- case "question.rejected":
2338
- case "permission.replied": {
2339
- const id = inputRequestID(properties);
2340
- const sessionID = stringProperty(properties, "sessionID");
2341
- if (id) tabTitleManager.clearNeedsInput(id);
2342
- if (sessionID) tabTitleManager.updateSessionStatus(sessionID, { type: "busy" });
2343
- break;
2344
- }
2345
- case "session.deleted": {
2346
- const sessionID = deletedSessionID(event);
2347
- if (sessionID) tabTitleManager.removeSession(sessionID);
2348
- break;
2349
- }
2350
- }
2351
- }
2352
2268
  //#endregion
2353
2269
  //#region src/zellij/tab-title.ts
2354
2270
  const defaultTabTitleEmojis = {
@@ -2367,10 +2283,237 @@ function sanitizeTitle(title, maxLength = 90) {
2367
2283
  if (chars.length > maxLength) cleaned = `${chars.slice(0, maxLength - 1).join("")}…`;
2368
2284
  return cleaned;
2369
2285
  }
2370
- var TabTitleManager = class {
2286
+ function isRecord(value) {
2287
+ return typeof value === "object" && value !== null;
2288
+ }
2289
+ function stringProperty(object, key) {
2290
+ const value = object[key];
2291
+ return typeof value === "string" ? value : void 0;
2292
+ }
2293
+ function nestedStringProperty(object, key, nestedKey) {
2294
+ const nested = object[key];
2295
+ if (!isRecord(nested)) return void 0;
2296
+ return stringProperty(nested, nestedKey);
2297
+ }
2298
+ function sessionStatusType(properties) {
2299
+ const status = properties.status;
2300
+ if (!isRecord(status)) return void 0;
2301
+ const type = status.type;
2302
+ if (type === "idle" || type === "busy") return type;
2303
+ if (type === "retry") return "retry";
2304
+ }
2305
+ function inputRequestID(properties) {
2306
+ return stringProperty(properties, "id") ?? stringProperty(properties, "requestID") ?? stringProperty(properties, "permissionID");
2307
+ }
2308
+ function inputState(properties) {
2309
+ return (stringProperty(properties, "status") ?? stringProperty(properties, "state") ?? stringProperty(properties, "type"))?.toLowerCase();
2310
+ }
2311
+ function isResolvedInputState(state) {
2312
+ return state === "approved" || state === "denied" || state === "rejected" || state === "resolved" || state === "replied";
2313
+ }
2314
+ function deletedSessionID(properties) {
2315
+ return nestedStringProperty(properties, "info", "id") ?? stringProperty(properties, "sessionID");
2316
+ }
2317
+ var TabTitleIdentityModel = class {
2318
+ ready;
2319
+ projectName;
2320
+ branchName;
2321
+ worktree;
2322
+ readBranch;
2323
+ refreshGeneration = 0;
2324
+ constructor(options) {
2325
+ this.projectName = options.projectName;
2326
+ this.worktree = options.worktree;
2327
+ this.readBranch = options.readBranch;
2328
+ this.ready = this.refreshBranch("initial");
2329
+ }
2330
+ async refreshBranch(_reason) {
2331
+ const generation = ++this.refreshGeneration;
2332
+ try {
2333
+ const result = await this.readBranch(this.worktree);
2334
+ if (generation !== this.refreshGeneration) return;
2335
+ const trimmed = result.trim() || void 0;
2336
+ this.branchName = trimmed;
2337
+ } catch (error) {
2338
+ if (generation !== this.refreshGeneration) return;
2339
+ debug("refreshBranch failed", errorMessage(error));
2340
+ }
2341
+ }
2342
+ handleEvent(event) {
2343
+ if (event.type === "vcs.branch.updated") return this.refreshBranch("vcs.branch.updated");
2344
+ }
2345
+ };
2346
+ var TabTitleActivityModel = class {
2347
+ status = "idle";
2348
+ worktreeDirectory;
2349
+ sessions = /* @__PURE__ */ new Map();
2350
+ scopedSessions = /* @__PURE__ */ new Set();
2371
2351
  runningSessions = /* @__PURE__ */ new Set();
2372
2352
  pendingInputs = /* @__PURE__ */ new Map();
2373
- branchName;
2353
+ constructor(options) {
2354
+ this.worktreeDirectory = options.worktreeDirectory;
2355
+ }
2356
+ getSession(sessionID) {
2357
+ return this.scopedSessions.has(sessionID) ? this.sessions.get(sessionID) : void 0;
2358
+ }
2359
+ hasPendingInput(sessionID, requestID) {
2360
+ return this.pendingInputs.has(`${sessionID}:${requestID}`);
2361
+ }
2362
+ handleEvent(event) {
2363
+ if (!isRecord(event.properties)) return;
2364
+ const properties = event.properties;
2365
+ switch (event.type) {
2366
+ case "session.created":
2367
+ case "session.updated": {
2368
+ const info = properties.info;
2369
+ if (isRecord(info)) {
2370
+ const id = stringProperty(info, "id");
2371
+ if (id) this.storeSession(id, info);
2372
+ }
2373
+ break;
2374
+ }
2375
+ case "session.status": {
2376
+ const sessionID = stringProperty(properties, "sessionID");
2377
+ const statusType = sessionStatusType(properties);
2378
+ if (sessionID && statusType) {
2379
+ if (statusType === "idle") {
2380
+ if (this.runningSessions.has(sessionID)) {
2381
+ this.runningSessions.delete(sessionID);
2382
+ this.updateStatus();
2383
+ }
2384
+ } else if (statusType === "busy" || statusType === "retry") {
2385
+ if (this.scopedSessions.has(sessionID)) {
2386
+ this.runningSessions.add(sessionID);
2387
+ this.updateStatus();
2388
+ }
2389
+ }
2390
+ }
2391
+ break;
2392
+ }
2393
+ case "session.idle":
2394
+ case "session.error": {
2395
+ const sessionID = stringProperty(properties, "sessionID");
2396
+ if (sessionID && this.runningSessions.has(sessionID)) {
2397
+ this.runningSessions.delete(sessionID);
2398
+ this.updateStatus();
2399
+ }
2400
+ break;
2401
+ }
2402
+ case "question.asked":
2403
+ case "permission.asked": {
2404
+ const id = inputRequestID(properties);
2405
+ const sessionID = stringProperty(properties, "sessionID");
2406
+ if (id && sessionID && this.scopedSessions.has(sessionID)) {
2407
+ this.pendingInputs.set(`${sessionID}:${id}`, sessionID);
2408
+ this.runningSessions.add(sessionID);
2409
+ this.updateStatus();
2410
+ }
2411
+ break;
2412
+ }
2413
+ case "permission.updated": {
2414
+ const id = inputRequestID(properties);
2415
+ const sessionID = stringProperty(properties, "sessionID");
2416
+ const state = inputState(properties);
2417
+ if (id && isResolvedInputState(state)) {
2418
+ this.pendingInputs.delete(`${sessionID}:${id}`);
2419
+ if (sessionID && this.runningSessions.has(sessionID)) this.runningSessions.add(sessionID);
2420
+ this.updateStatus();
2421
+ } else if (id && sessionID && this.scopedSessions.has(sessionID)) {
2422
+ this.pendingInputs.set(`${sessionID}:${id}`, sessionID);
2423
+ this.runningSessions.add(sessionID);
2424
+ this.updateStatus();
2425
+ }
2426
+ break;
2427
+ }
2428
+ case "question.replied":
2429
+ case "question.rejected":
2430
+ case "permission.replied": {
2431
+ const id = inputRequestID(properties);
2432
+ const sessionID = stringProperty(properties, "sessionID");
2433
+ if (id) this.pendingInputs.delete(`${sessionID}:${id}`);
2434
+ if (sessionID && this.runningSessions.has(sessionID)) this.runningSessions.add(sessionID);
2435
+ this.updateStatus();
2436
+ break;
2437
+ }
2438
+ case "session.deleted": {
2439
+ const sessionID = deletedSessionID(properties);
2440
+ if (sessionID) {
2441
+ this.removeSessionAndDescendants(sessionID);
2442
+ this.updateStatus();
2443
+ }
2444
+ break;
2445
+ }
2446
+ }
2447
+ }
2448
+ storeSession(id, info) {
2449
+ const directory = stringProperty(info, "directory");
2450
+ const parentID = stringProperty(info, "parentID");
2451
+ this.sessions.set(id, {
2452
+ directory,
2453
+ parentID
2454
+ });
2455
+ const isDirectlyScoped = directory === this.worktreeDirectory;
2456
+ const isDescendantScoped = parentID ? this.scopedSessions.has(parentID) : false;
2457
+ if (this.scopedSessions.has(id) || isDirectlyScoped || isDescendantScoped) this.scopedSessions.add(id);
2458
+ }
2459
+ removeSessionAndDescendants(rootID) {
2460
+ const toRemove = /* @__PURE__ */ new Set();
2461
+ toRemove.add(rootID);
2462
+ let changed = true;
2463
+ while (changed) {
2464
+ changed = false;
2465
+ for (const [id, session] of this.sessions) if (!toRemove.has(id) && session.parentID && toRemove.has(session.parentID)) {
2466
+ toRemove.add(id);
2467
+ changed = true;
2468
+ }
2469
+ }
2470
+ for (const id of toRemove) {
2471
+ this.sessions.delete(id);
2472
+ this.scopedSessions.delete(id);
2473
+ this.runningSessions.delete(id);
2474
+ }
2475
+ for (const [key, sessionID] of [...this.pendingInputs.entries()]) if (toRemove.has(sessionID)) this.pendingInputs.delete(key);
2476
+ }
2477
+ updateStatus() {
2478
+ if (this.pendingInputs.size > 0) this.status = "needs-input";
2479
+ else if (this.runningSessions.size > 0) this.status = "running";
2480
+ else this.status = "idle";
2481
+ }
2482
+ };
2483
+ var TabTitleActor = class {
2484
+ ready;
2485
+ identity;
2486
+ activity;
2487
+ emojis;
2488
+ constructor(options) {
2489
+ this.identity = options.identity;
2490
+ this.activity = options.activity;
2491
+ this.emojis = {
2492
+ ...defaultTabTitleEmojis,
2493
+ ...options.emojis
2494
+ };
2495
+ this.ready = this.identity.ready;
2496
+ }
2497
+ get context() {
2498
+ return {
2499
+ projectName: this.identity.projectName,
2500
+ branchName: this.identity.branchName,
2501
+ status: this.activity.status
2502
+ };
2503
+ }
2504
+ get title() {
2505
+ return formatTabTitle({
2506
+ ...this.context,
2507
+ emojis: this.emojis
2508
+ });
2509
+ }
2510
+ async handleEvent(event) {
2511
+ this.activity.handleEvent(event);
2512
+ const identityResult = this.identity.handleEvent(event);
2513
+ if (identityResult instanceof Promise) await identityResult;
2514
+ }
2515
+ };
2516
+ var TabTitleManager = class {
2374
2517
  desiredTitle;
2375
2518
  lastSyncedTitle;
2376
2519
  debounceTimer;
@@ -2381,7 +2524,6 @@ var TabTitleManager = class {
2381
2524
  debounceMs;
2382
2525
  retryInitialMs;
2383
2526
  retryMaxMs;
2384
- projectName;
2385
2527
  cli;
2386
2528
  emojis;
2387
2529
  enabled;
@@ -2390,9 +2532,8 @@ var TabTitleManager = class {
2390
2532
  originalTabTitleLoaded = false;
2391
2533
  originalTabTitlePromise;
2392
2534
  destroyPromise;
2535
+ actor;
2393
2536
  constructor(options) {
2394
- this.projectName = options.projectName;
2395
- this.branchName = options.branchName?.trim() || void 0;
2396
2537
  this.cli = options.cli ?? new ZellijCli();
2397
2538
  this.emojis = {
2398
2539
  ...defaultTabTitleEmojis,
@@ -2401,65 +2542,12 @@ var TabTitleManager = class {
2401
2542
  this.debounceMs = options.debounceMs ?? 300;
2402
2543
  this.retryInitialMs = options.retryInitialMs ?? 250;
2403
2544
  this.retryMaxMs = options.retryMaxMs ?? 5e3;
2404
- this.enabled = Boolean(process.env.ZELLIJ);
2405
- }
2406
- setBranch(branch) {
2407
- const trimmed = branch?.trim() || void 0;
2408
- if (this.branchName === trimmed) return;
2409
- this.branchName = trimmed;
2410
- this.scheduleUpdate();
2411
- }
2412
- updateSessionStatus(sessionID, status) {
2413
- const isRunning = status.type === "busy" || status.type === "retry";
2414
- const wasRunning = this.runningSessions.has(sessionID);
2415
- if (isRunning) {
2416
- if (!wasRunning) {
2417
- this.runningSessions.add(sessionID);
2418
- this.scheduleUpdate();
2419
- }
2420
- } else if (wasRunning) {
2421
- this.runningSessions.delete(sessionID);
2422
- this.scheduleUpdate();
2423
- }
2424
- }
2425
- markSessionIdle(sessionID) {
2426
- if (this.runningSessions.delete(sessionID)) this.scheduleUpdate();
2427
- }
2428
- removeSession(sessionID) {
2429
- const hadRunning = this.runningSessions.delete(sessionID);
2430
- let hadPendingInput = false;
2431
- for (const [id, pendingSessionID] of this.pendingInputs) if (pendingSessionID === sessionID) {
2432
- this.pendingInputs.delete(id);
2433
- hadPendingInput = true;
2434
- }
2435
- if (!hadRunning && !hadPendingInput) return;
2436
- this.scheduleUpdate();
2437
- }
2438
- markNeedsInput(id, sessionID) {
2439
- if (this.pendingInputs.get(id) === sessionID) return;
2440
- this.pendingInputs.set(id, sessionID);
2441
- this.scheduleUpdate();
2442
- }
2443
- clearNeedsInput(id) {
2444
- if (!this.pendingInputs.delete(id)) return;
2445
- this.scheduleUpdate();
2446
- }
2447
- get isBusy() {
2448
- return this.runningSessions.size > 0;
2449
- }
2450
- get needsInput() {
2451
- return this.pendingInputs.size > 0;
2452
- }
2453
- get status() {
2454
- if (this.needsInput) return "needs-input";
2455
- if (this.isBusy) return "running";
2456
- return "idle";
2545
+ this.enabled = Boolean(process.env.ZELLIJ || process.env.ZELLIJ_SESSION_NAME);
2546
+ this.actor = options.actor;
2457
2547
  }
2458
2548
  buildTitle() {
2459
2549
  return sanitizeTitle(formatTabTitle({
2460
- projectName: this.projectName,
2461
- branchName: this.branchName,
2462
- status: this.status,
2550
+ ...this.actor.context,
2463
2551
  emojis: this.emojis
2464
2552
  }));
2465
2553
  }
@@ -2635,10 +2723,18 @@ function createZellijPtyPlugin(dependencies = {}) {
2635
2723
  registerShutdownCleanup();
2636
2724
  const workspaceRoot = getWorkspaceRoot(input);
2637
2725
  const projectName = getProjectName(workspaceRoot);
2638
- const branchName = config.tabTitle.enabled && shouldReadInitialBranch(process.env.ZELLIJ) ? await getInitialBranch(workspaceRoot) : void 0;
2639
- const tabTitleManager = config.tabTitle.enabled ? new TabTitleManager({
2726
+ const identityModel = config.tabTitle.enabled ? new TabTitleIdentityModel({
2640
2727
  projectName,
2641
- branchName,
2728
+ worktree: workspaceRoot,
2729
+ readBranch: async (worktree) => shouldReadInitialBranch(process.env.ZELLIJ || process.env.ZELLIJ_SESSION_NAME) ? await getInitialBranch(worktree) ?? "" : ""
2730
+ }) : void 0;
2731
+ const activityModel = config.tabTitle.enabled ? new TabTitleActivityModel({ worktreeDirectory: workspaceRoot }) : void 0;
2732
+ const actor = identityModel && activityModel ? new TabTitleActor({
2733
+ identity: identityModel,
2734
+ activity: activityModel
2735
+ }) : void 0;
2736
+ const tabTitleManager = config.tabTitle.enabled && actor ? new TabTitleManager({
2737
+ actor,
2642
2738
  debounceMs: config.tabTitle.debounceMs,
2643
2739
  emojis: {
2644
2740
  idle: config.tabTitle.emojiIdle,
@@ -2672,19 +2768,24 @@ function createZellijPtyPlugin(dependencies = {}) {
2672
2768
  }
2673
2769
  });
2674
2770
  subscriberManager.setLifecycleHooks(completionNotifications ? { onSessionTerminal: (event) => void completionNotifications.handleSessionTerminal(event).catch((error) => debug("completion notification lifecycle hook failed", errorMessage(error))) } : void 0);
2771
+ if (actor) await actor.ready;
2675
2772
  tabTitleManager?.renderImmediate().catch((error) => debug("initial tab title render failed", errorMessage(error)));
2676
2773
  if (config.autoUpdate) (dependencies.startAutoUpdateCheck ?? startAutoUpdateCheck)(client, dependencies.importMetaUrl ?? import.meta.url);
2677
2774
  return {
2678
2775
  async event(input) {
2679
2776
  const event = input.event;
2680
- if (tabTitleManager) await handleTabTitleEvent(tabTitleManager, event);
2777
+ if (actor && tabTitleManager) {
2778
+ await actor.handleEvent(event);
2779
+ if (event.type === "server.instance.disposed" || event.type === "global.disposed") await tabTitleManager.destroy();
2780
+ else tabTitleManager.scheduleUpdate();
2781
+ }
2681
2782
  if (event.type === "server.instance.disposed" || event.type === "global.disposed") {
2682
2783
  completionNotifications?.clearAll();
2683
2784
  completionNotifications?.dispose();
2684
2785
  subscriberManager.setLifecycleHooks(void 0);
2685
2786
  }
2686
2787
  if (event.type === "session.deleted") {
2687
- const sessionID = deletedSessionID(event);
2788
+ const sessionID = deletedSessionID$1(event);
2688
2789
  if (!sessionID) return;
2689
2790
  const sessions = sessionManager.listByOpenCodeSession(sessionID);
2690
2791
  for (const session of sessions) completionNotifications?.clearSession(session.id);