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 +265 -164
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -1
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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
|
|
2256
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
2639
|
-
const tabTitleManager = config.tabTitle.enabled ? new TabTitleManager({
|
|
2726
|
+
const identityModel = config.tabTitle.enabled ? new TabTitleIdentityModel({
|
|
2640
2727
|
projectName,
|
|
2641
|
-
|
|
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 (
|
|
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);
|