@dylanpiercey/work 0.0.146 → 0.0.147
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/_Bv4lCw13.js +2 -0
- package/dist/{_OZ9nLhXp.js → _DGEhqy7E.js} +69 -17
- package/dist/index.mjs +5910 -5755
- package/dist/public/assets/_2xuRGdn_.js +1 -0
- package/dist/public/assets/_B12ZGJAK.js +1 -0
- package/dist/public/assets/_BJJj6Bgs.js +1 -0
- package/dist/public/assets/_BONsa0p1.js +1 -0
- package/dist/public/assets/_BaWHj3BA.js +1 -0
- package/dist/public/assets/_Bbw6USJg.js +1 -0
- package/dist/public/assets/_BlpiJD5o.js +1 -0
- package/dist/public/assets/_C9l_aW0n.js +1 -0
- package/dist/public/assets/{_Bkg2RxMC.js → _CbHNdeDU.js} +4 -4
- package/dist/public/assets/_CbHNdeDU.js.br +0 -0
- package/dist/public/assets/_Cr0wBZa1.js +1 -0
- package/dist/public/assets/_Cr0wBZa1.js.br +0 -0
- package/dist/public/assets/_DIXWDGWP.js +1 -0
- package/dist/public/assets/_D_3kwekz.js +1 -0
- package/dist/public/assets/_Ddu-G-hH.js +1 -0
- package/dist/public/assets/{_BJq6B3f8.js → _DsOQV4Jf.js} +20 -20
- package/dist/public/assets/_DsOQV4Jf.js.br +0 -0
- package/dist/public/assets/_DxNtl6PJ.js +1 -0
- package/dist/public/assets/_IH_dHn2Z.js +1 -0
- package/dist/public/assets/_NutY1vka.js +1 -0
- package/dist/public/assets/_Q11TJ5W0.js +1 -0
- package/dist/public/assets/_SRRkeWJi.js +1 -0
- package/dist/public/assets/_a5rTuRF3.js +1 -0
- package/dist/public/assets/_kv7st39T.js +1 -0
- package/dist/public/assets/_okmh0c7M.js +1 -0
- package/dist/public/assets/app-page-CS4w1M-v.css +1 -0
- package/dist/public/assets/app-page-CS4w1M-v.css.br +0 -0
- package/dist/public/assets/diff-view-BcgXlDbY.css +1 -0
- package/dist/public/assets/diff-view-BcgXlDbY.css.br +0 -0
- package/dist/public/assets/diff-view-YLo1KhOq.js +2 -0
- package/dist/public/assets/icon-arrow-down-CYif_Qat.css +1 -0
- package/dist/public/assets/icon-arrow-down-CYif_Qat.css.br +0 -0
- package/dist/public/assets/new-B000kC3p.js +1 -0
- package/dist/public/assets/settings-B000kC3p.js +1 -0
- package/dist/public/assets/w-B000kC3p.js +1 -0
- package/dist/public/assets/w._-B000kC3p.js +1 -0
- package/dist/public/assets/w._-CE1vFHA1.js +1 -0
- package/lib/setup/doctor.d.mts +1 -1
- package/lib/setup/doctor.mjs +32 -5
- package/package.json +1 -1
- package/scripts/migrate.mjs +1 -1
- package/dist/_CCA0c-I0.js +0 -2
- package/dist/public/assets/_2f6GkTCF.js +0 -1
- package/dist/public/assets/_BJq6B3f8.js.br +0 -0
- package/dist/public/assets/_BRiyTqqx.js +0 -1
- package/dist/public/assets/_BXJd6h5q.js +0 -1
- package/dist/public/assets/_Bc7wOUYH.js +0 -1
- package/dist/public/assets/_Bkg2RxMC.js.br +0 -0
- package/dist/public/assets/_BnihlWIp.js +0 -1
- package/dist/public/assets/_C-wKjwXX.js +0 -1
- package/dist/public/assets/_C408Iqy7.js +0 -1
- package/dist/public/assets/_CVunWnOY.js +0 -1
- package/dist/public/assets/_CeK9LJkw.js +0 -1
- package/dist/public/assets/_CgfKx3kO.js +0 -1
- package/dist/public/assets/_DCCIL6WI.js +0 -1
- package/dist/public/assets/_DQDxPXHD.js +0 -1
- package/dist/public/assets/_DRLjyh60.js +0 -1
- package/dist/public/assets/_DlE-V9GA.js +0 -1
- package/dist/public/assets/_DzgxFeeE.js +0 -1
- package/dist/public/assets/_Xp-Chjfv.js +0 -1
- package/dist/public/assets/_b6v9fOcC.js +0 -1
- package/dist/public/assets/_oalV3UwK.js +0 -1
- package/dist/public/assets/_oalV3UwK.js.br +0 -0
- package/dist/public/assets/_vQM4oRsw.js +0 -1
- package/dist/public/assets/_xiuhy85t.js +0 -1
- package/dist/public/assets/app-page-IRq6b-Ob.css +0 -1
- package/dist/public/assets/app-page-IRq6b-Ob.css.br +0 -0
- package/dist/public/assets/diff-view-6-VC0hOC.css +0 -1
- package/dist/public/assets/diff-view-6-VC0hOC.css.br +0 -0
- package/dist/public/assets/diff-view-CHN5eqyz.js +0 -2
- package/dist/public/assets/icon-arrow-down-Dcmmz4Cl.css +0 -1
- package/dist/public/assets/icon-arrow-down-Dcmmz4Cl.css.br +0 -0
- package/dist/public/assets/new-BpPnfh6F.js +0 -1
- package/dist/public/assets/settings-BpPnfh6F.js +0 -1
- package/dist/public/assets/w-BpPnfh6F.js +0 -1
- package/dist/public/assets/w._-B5NuNac4.js +0 -1
- package/dist/public/assets/w._-BpPnfh6F.js +0 -1
|
@@ -426,6 +426,20 @@ function setupPath(base = process.env.PATH || "") {
|
|
|
426
426
|
const seen = /* @__PURE__ */ new Set();
|
|
427
427
|
return [...base.split(path.delimiter), ...extra].filter((p) => p && !seen.has(p) && seen.add(p)).join(path.delimiter);
|
|
428
428
|
}
|
|
429
|
+
/** setupPath() split once per PATH value: `which` runs for every tool on
|
|
430
|
+
* every probe and rebuilt the list each time. */
|
|
431
|
+
var dirsFor = {
|
|
432
|
+
base: void 0,
|
|
433
|
+
dirs: []
|
|
434
|
+
};
|
|
435
|
+
function setupDirs() {
|
|
436
|
+
const base = process.env.PATH || "";
|
|
437
|
+
if (dirsFor.base !== base) dirsFor = {
|
|
438
|
+
base,
|
|
439
|
+
dirs: setupPath(base).split(path.delimiter)
|
|
440
|
+
};
|
|
441
|
+
return dirsFor.dirs;
|
|
442
|
+
}
|
|
429
443
|
/** `~/…` for anything under the home directory — every path here is for
|
|
430
444
|
* display (Settings rows, `work doctor`), never re-used to exec. */
|
|
431
445
|
function tilde(p) {
|
|
@@ -434,7 +448,7 @@ function tilde(p) {
|
|
|
434
448
|
}
|
|
435
449
|
/** Absolute path of `bin` on setupPath(), or null. */
|
|
436
450
|
function which(bin) {
|
|
437
|
-
for (const dir of
|
|
451
|
+
for (const dir of setupDirs()) {
|
|
438
452
|
const full = path.join(dir, bin);
|
|
439
453
|
try {
|
|
440
454
|
if (fs.statSync(full).isFile()) return full;
|
|
@@ -500,14 +514,29 @@ function ghKnownHosts() {
|
|
|
500
514
|
}
|
|
501
515
|
return [...text.matchAll(/^([A-Za-z0-9.-]+):\s*$/gm)].map((m) => m[1]);
|
|
502
516
|
}
|
|
517
|
+
/** Agent scan memo. Every app page render, skills scan and session
|
|
518
|
+
* create asks; the answer only moves when something is installed, and
|
|
519
|
+
* the doctor probe (which every install runs) refreshes it. */
|
|
520
|
+
var AGENTS_MEMO_MS = 3e4;
|
|
521
|
+
var agentsMemo = null;
|
|
503
522
|
/**
|
|
504
523
|
* Every agent CLI instance on PATH, per family: the plain binary and any
|
|
505
524
|
* numeric-suffixed siblings (`claude1`, `cursor-agent2`). Sync — a PATH
|
|
506
525
|
* scan is cheap and the boot handler needs it without awaiting. First hit
|
|
507
|
-
* on PATH wins per name, like the shell.
|
|
526
|
+
* on PATH wins per name, like the shell. `fresh` rescans regardless of
|
|
527
|
+
* the memo.
|
|
508
528
|
*/
|
|
509
|
-
function discoverAgents() {
|
|
510
|
-
|
|
529
|
+
function discoverAgents(fresh = false) {
|
|
530
|
+
if (!fresh && agentsMemo && Date.now() - agentsMemo.at < AGENTS_MEMO_MS) return agentsMemo.value;
|
|
531
|
+
const value = scanAgents();
|
|
532
|
+
agentsMemo = {
|
|
533
|
+
at: Date.now(),
|
|
534
|
+
value
|
|
535
|
+
};
|
|
536
|
+
return value;
|
|
537
|
+
}
|
|
538
|
+
function scanAgents() {
|
|
539
|
+
const dirs = setupDirs();
|
|
511
540
|
const seenDirs = /* @__PURE__ */ new Set();
|
|
512
541
|
const seen = /* @__PURE__ */ new Map();
|
|
513
542
|
for (const dir of dirs) {
|
|
@@ -614,7 +643,7 @@ async function doctor(opts = {}) {
|
|
|
614
643
|
mise: t.mise
|
|
615
644
|
};
|
|
616
645
|
});
|
|
617
|
-
const agents = discoverAgents();
|
|
646
|
+
const agents = discoverAgents(true);
|
|
618
647
|
const missing = [];
|
|
619
648
|
for (const t of tools) if (t.required && !t.installed) missing.push(t.id);
|
|
620
649
|
if (!github.some((h) => h.authed)) missing.push("github-auth");
|
|
@@ -798,9 +827,15 @@ function shared(fn, ttlMs) {
|
|
|
798
827
|
//#region src/server/events.ts
|
|
799
828
|
var listeners = /* @__PURE__ */ new Set();
|
|
800
829
|
function publish(type, data) {
|
|
830
|
+
publishJson(type, data === void 0 ? void 0 : JSON.stringify(data), data);
|
|
831
|
+
}
|
|
832
|
+
/** Publish with the payload already serialized (a producer that had to
|
|
833
|
+
* stringify it anyway, e.g. for change detection, hands the string in). */
|
|
834
|
+
function publishJson(type, dataJson, data) {
|
|
801
835
|
const event = {
|
|
802
836
|
type,
|
|
803
|
-
data
|
|
837
|
+
data,
|
|
838
|
+
frame: dataJson === void 0 ? JSON.stringify({ type }) : `{"type":${JSON.stringify(type)},"data":${dataJson}}`
|
|
804
839
|
};
|
|
805
840
|
for (const listener of [...listeners]) try {
|
|
806
841
|
listener(event);
|
|
@@ -6689,7 +6724,7 @@ function publishChange(sessionId) {
|
|
|
6689
6724
|
const row = get("SELECT workspace_id FROM sessions WHERE id = ?", sessionId);
|
|
6690
6725
|
if (row?.workspace_id) {
|
|
6691
6726
|
const workspaceId = row.workspace_id;
|
|
6692
|
-
import("./
|
|
6727
|
+
import("./_Bv4lCw13.js").then((m) => m.notifySessionsChanged(workspaceId));
|
|
6693
6728
|
return;
|
|
6694
6729
|
}
|
|
6695
6730
|
publish("sessions.changed");
|
|
@@ -8216,6 +8251,7 @@ async function disposeSession(id) {
|
|
|
8216
8251
|
"-t",
|
|
8217
8252
|
tmuxName(id)
|
|
8218
8253
|
]).catch(() => {});
|
|
8254
|
+
forgetPanes();
|
|
8219
8255
|
clearTmuxStarted(id);
|
|
8220
8256
|
clearAgentPhase(id);
|
|
8221
8257
|
db.prepare("DELETE FROM sessions WHERE id = ?").run(id);
|
|
@@ -8234,9 +8270,18 @@ function tmuxWasStarted(id) {
|
|
|
8234
8270
|
function clearTmuxStarted(id) {
|
|
8235
8271
|
tmuxStarted.delete(id);
|
|
8236
8272
|
}
|
|
8237
|
-
/** SSE payload: session rows + live tmux/hook state so clients don't refetch.
|
|
8273
|
+
/** SSE payload: session rows + live tmux/hook state so clients don't refetch.
|
|
8274
|
+
* Coalesced per workspace: a turn boundary lands as a burst of phase
|
|
8275
|
+
* transitions (hook, then scrape), and each one cost a list-panes spawn
|
|
8276
|
+
* and a broadcast for a list that came out the same. */
|
|
8277
|
+
var EMIT_DEBOUNCE_MS = 50;
|
|
8278
|
+
var pendingEmits = /* @__PURE__ */ new Map();
|
|
8238
8279
|
function notifySessionsChanged(workspaceId) {
|
|
8239
|
-
|
|
8280
|
+
clearTimeout(pendingEmits.get(workspaceId));
|
|
8281
|
+
pendingEmits.set(workspaceId, setTimeout(() => {
|
|
8282
|
+
pendingEmits.delete(workspaceId);
|
|
8283
|
+
emitSessionsChanged(workspaceId);
|
|
8284
|
+
}, EMIT_DEBOUNCE_MS));
|
|
8240
8285
|
}
|
|
8241
8286
|
async function emitSessionsChanged(workspaceId) {
|
|
8242
8287
|
try {
|
|
@@ -8321,13 +8366,20 @@ async function panePids() {
|
|
|
8321
8366
|
return new Set((await listPanes() || []).map((p) => p.pid));
|
|
8322
8367
|
}
|
|
8323
8368
|
/** Every tmux pane, one `list-panes` for everyone who wants one: session
|
|
8324
|
-
* state, pane pids
|
|
8325
|
-
* and a field costs tmux nothing while a spawn costs
|
|
8326
|
-
*
|
|
8327
|
-
*
|
|
8328
|
-
*
|
|
8329
|
-
*
|
|
8330
|
-
|
|
8369
|
+
* state, pane pids, the activity scraper and every phase transition ask
|
|
8370
|
+
* within a short span, and a field costs tmux nothing while a spawn costs
|
|
8371
|
+
* ~10 ms on macOS. The reuse window sits well under the scraper's 2 s
|
|
8372
|
+
* cadence; the one reader that must not see a stale answer — a
|
|
8373
|
+
* kill-session followed by a state read — drops the window with
|
|
8374
|
+
* `forgetPanes`. Null when tmux did not answer (server down, transient
|
|
8375
|
+
* failure): callers that clear state on "no panes" must not clear it on
|
|
8376
|
+
* "no answer". */
|
|
8377
|
+
var PANES_REUSE_MS = 400;
|
|
8378
|
+
var panesShared = shared(listPanesNow, PANES_REUSE_MS);
|
|
8379
|
+
var listPanes = () => panesShared();
|
|
8380
|
+
function forgetPanes() {
|
|
8381
|
+
panesShared = shared(listPanesNow, PANES_REUSE_MS);
|
|
8382
|
+
}
|
|
8331
8383
|
async function listPanesNow() {
|
|
8332
8384
|
const out = await tmux([
|
|
8333
8385
|
"list-panes",
|
|
@@ -8639,4 +8691,4 @@ function sleep(ms) {
|
|
|
8639
8691
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
8640
8692
|
}
|
|
8641
8693
|
//#endregion
|
|
8642
|
-
export {
|
|
8694
|
+
export { disabledAgents as $, clearAgentPhase as A, deleteSubscription as B, reportsWorking as C, gh as Ct, agentFromCommand as D, config as Dt, agentFamily as E, tmux as Et, getInstance as F, subscribe as G, saveSubscription as H, iconSvg as I, shared as J, subscriberCount as K, manifest as L, setScrapedPhase as M, setSessionViewers as N, agentLabel as O, ACCENT_RE as P, allPrefs as Q, normalizeAccent as R, readHookPayload as S, TMUX_SOCKET as St, agentBadge as T, run$1 as Tt, publish as U, pushPublicKey as V, publishJson as W, withLock as X, swr as Y, agentChoices as Z, sendToSession as _, toolById as _t, ensureTmuxServer as a, setSetting as at, tmuxWasStarted as b, get as bt, killSession as c, ghKnownHosts as ct, listSessions as d, setupPath as dt, enabledAgents as et, markTmuxStarted as f, which as ft, renameSession as g, agentLabel$1 as gt, panePids as h, agentById as ht, disposeSessions as i, setPref as it, setAgentPhase as j, agentMeta as k, killWorkspaceSessions as l, miseInstalls as lt, notifySessionsChanged as m, TOOLS as mt, clearTmuxStarted as n, preferredAgent as nt, forgetPanes as o, discoverAgents as ot, newSessionArgs as p, DEFAULT_GITHUB_HOST as pt, subscriberJoins as q, createSession as r, setDisabledAgents as rt, getSession as s, doctor as st, cleanEnv as t, getSetting as tt, listPanes as u, miseVersions as ut, sessionStates as v, all as vt, blankRow as w, git as wt, AGENTS as x, workspacePath as xt, tmuxName as y, db as yt, setInstance as z };
|