@kenkaiiii/gg-boss 4.3.149 → 4.3.151
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/README.md +168 -0
- package/dist/{chunk-ZNVFGIDI.js → chunk-JFMWBELU.js} +28 -7
- package/dist/{chunk-ZNVFGIDI.js.map → chunk-JFMWBELU.js.map} +1 -1
- package/dist/cli.js +250 -60
- package/dist/cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +4 -4
package/dist/cli.js
CHANGED
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
use_app_default,
|
|
44
44
|
use_input_default,
|
|
45
45
|
use_stdout_default
|
|
46
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-JFMWBELU.js";
|
|
47
47
|
import "./chunk-QT366Y52.js";
|
|
48
48
|
import {
|
|
49
49
|
source_default
|
|
@@ -86,8 +86,49 @@ var import_react2 = __toESM(require_react(), 1);
|
|
|
86
86
|
// src/discover.ts
|
|
87
87
|
init_esm_shims();
|
|
88
88
|
import fs2 from "fs/promises";
|
|
89
|
+
import { createReadStream } from "fs";
|
|
90
|
+
import readline from "readline";
|
|
91
|
+
import os from "os";
|
|
89
92
|
import path2 from "path";
|
|
90
93
|
async function discoverProjects() {
|
|
94
|
+
const [gg, cc, cx] = await Promise.all([
|
|
95
|
+
discoverGgcoderProjects(),
|
|
96
|
+
discoverClaudeProjects(),
|
|
97
|
+
discoverCodexProjects()
|
|
98
|
+
]);
|
|
99
|
+
const byPath = /* @__PURE__ */ new Map();
|
|
100
|
+
for (const p of [...gg, ...cc, ...cx]) {
|
|
101
|
+
const existing = byPath.get(p.path);
|
|
102
|
+
if (!existing) {
|
|
103
|
+
byPath.set(p.path, p);
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
byPath.set(p.path, {
|
|
107
|
+
name: existing.name,
|
|
108
|
+
path: existing.path,
|
|
109
|
+
lastActiveMs: Math.max(existing.lastActiveMs, p.lastActiveMs),
|
|
110
|
+
lastActiveDisplay: "",
|
|
111
|
+
// recomputed below
|
|
112
|
+
sources: mergeSources(existing.sources, p.sources)
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
const merged = Array.from(byPath.values()).map((p) => ({
|
|
116
|
+
...p,
|
|
117
|
+
lastActiveDisplay: formatRelativeTime(p.lastActiveMs)
|
|
118
|
+
}));
|
|
119
|
+
merged.sort((a, b) => b.lastActiveMs - a.lastActiveMs);
|
|
120
|
+
return merged;
|
|
121
|
+
}
|
|
122
|
+
var SOURCE_ORDER = {
|
|
123
|
+
ggcoder: 0,
|
|
124
|
+
"claude-code": 1,
|
|
125
|
+
codex: 2
|
|
126
|
+
};
|
|
127
|
+
function mergeSources(a, b) {
|
|
128
|
+
const set = /* @__PURE__ */ new Set([...a, ...b]);
|
|
129
|
+
return Array.from(set).sort((x, y) => SOURCE_ORDER[x] - SOURCE_ORDER[y]);
|
|
130
|
+
}
|
|
131
|
+
async function discoverGgcoderProjects() {
|
|
91
132
|
const sessionsDir = getAppPaths().sessionsDir;
|
|
92
133
|
let entries;
|
|
93
134
|
try {
|
|
@@ -98,46 +139,177 @@ async function discoverProjects() {
|
|
|
98
139
|
const results = [];
|
|
99
140
|
for (const entry of entries) {
|
|
100
141
|
const dir = path2.join(sessionsDir, entry);
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
stat = await fs2.stat(dir);
|
|
104
|
-
} catch {
|
|
105
|
-
continue;
|
|
106
|
-
}
|
|
107
|
-
if (!stat.isDirectory()) continue;
|
|
108
|
-
let files;
|
|
109
|
-
try {
|
|
110
|
-
files = await fs2.readdir(dir);
|
|
111
|
-
} catch {
|
|
112
|
-
continue;
|
|
113
|
-
}
|
|
114
|
-
const sessionFiles = files.filter((f) => f.endsWith(".jsonl"));
|
|
115
|
-
if (sessionFiles.length === 0) continue;
|
|
116
|
-
let maxMtime = 0;
|
|
117
|
-
for (const f of sessionFiles) {
|
|
118
|
-
try {
|
|
119
|
-
const s = await fs2.stat(path2.join(dir, f));
|
|
120
|
-
if (s.mtimeMs > maxMtime) maxMtime = s.mtimeMs;
|
|
121
|
-
} catch {
|
|
122
|
-
}
|
|
123
|
-
}
|
|
142
|
+
const mtime = await maxJsonlMtime(dir);
|
|
143
|
+
if (mtime === null) continue;
|
|
124
144
|
const decoded = "/" + entry.replace(/_/g, "/");
|
|
125
|
-
|
|
126
|
-
const pathStat = await fs2.stat(decoded);
|
|
127
|
-
if (!pathStat.isDirectory()) continue;
|
|
128
|
-
} catch {
|
|
129
|
-
continue;
|
|
130
|
-
}
|
|
145
|
+
if (!await isDirectory(decoded)) continue;
|
|
131
146
|
results.push({
|
|
132
147
|
name: path2.basename(decoded),
|
|
133
148
|
path: decoded,
|
|
134
|
-
lastActiveMs:
|
|
135
|
-
lastActiveDisplay: formatRelativeTime(
|
|
149
|
+
lastActiveMs: mtime,
|
|
150
|
+
lastActiveDisplay: formatRelativeTime(mtime),
|
|
151
|
+
sources: ["ggcoder"]
|
|
136
152
|
});
|
|
137
153
|
}
|
|
138
|
-
results.sort((a, b) => b.lastActiveMs - a.lastActiveMs);
|
|
139
154
|
return results;
|
|
140
155
|
}
|
|
156
|
+
async function discoverClaudeProjects() {
|
|
157
|
+
const projectsDir = path2.join(os.homedir(), ".claude", "projects");
|
|
158
|
+
let entries;
|
|
159
|
+
try {
|
|
160
|
+
entries = await fs2.readdir(projectsDir);
|
|
161
|
+
} catch {
|
|
162
|
+
return [];
|
|
163
|
+
}
|
|
164
|
+
const results = await Promise.all(
|
|
165
|
+
entries.map(async (entry) => {
|
|
166
|
+
const dir = path2.join(projectsDir, entry);
|
|
167
|
+
const mtime = await maxJsonlMtime(dir);
|
|
168
|
+
if (mtime === null) return null;
|
|
169
|
+
const cwd = await readFirstFromJsonlDir(dir, claudeCwdExtractor) ?? fallbackDashDecode(entry);
|
|
170
|
+
if (!cwd) return null;
|
|
171
|
+
if (!await isDirectory(cwd)) return null;
|
|
172
|
+
return {
|
|
173
|
+
name: path2.basename(cwd),
|
|
174
|
+
path: cwd,
|
|
175
|
+
lastActiveMs: mtime,
|
|
176
|
+
lastActiveDisplay: formatRelativeTime(mtime),
|
|
177
|
+
sources: ["claude-code"]
|
|
178
|
+
};
|
|
179
|
+
})
|
|
180
|
+
);
|
|
181
|
+
return results.filter((p) => p !== null);
|
|
182
|
+
}
|
|
183
|
+
async function discoverCodexProjects() {
|
|
184
|
+
const sessionsDir = path2.join(os.homedir(), ".codex", "sessions");
|
|
185
|
+
if (!await isDirectory(sessionsDir)) return [];
|
|
186
|
+
const files = await collectJsonlFiles(sessionsDir, 4);
|
|
187
|
+
if (files.length === 0) return [];
|
|
188
|
+
files.sort((a, b) => b.mtime - a.mtime);
|
|
189
|
+
const byCwd = /* @__PURE__ */ new Map();
|
|
190
|
+
for (const f of files) {
|
|
191
|
+
const cwd = await readFirstFromFile(f.path, codexCwdExtractor);
|
|
192
|
+
if (!cwd) continue;
|
|
193
|
+
const prev = byCwd.get(cwd);
|
|
194
|
+
if (prev === void 0 || f.mtime > prev) byCwd.set(cwd, f.mtime);
|
|
195
|
+
}
|
|
196
|
+
const results = [];
|
|
197
|
+
for (const [cwd, mtime] of byCwd) {
|
|
198
|
+
if (!await isDirectory(cwd)) continue;
|
|
199
|
+
results.push({
|
|
200
|
+
name: path2.basename(cwd),
|
|
201
|
+
path: cwd,
|
|
202
|
+
lastActiveMs: mtime,
|
|
203
|
+
lastActiveDisplay: formatRelativeTime(mtime),
|
|
204
|
+
sources: ["codex"]
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
return results;
|
|
208
|
+
}
|
|
209
|
+
async function isDirectory(p) {
|
|
210
|
+
try {
|
|
211
|
+
const s = await fs2.stat(p);
|
|
212
|
+
return s.isDirectory();
|
|
213
|
+
} catch {
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
async function maxJsonlMtime(dir) {
|
|
218
|
+
if (!await isDirectory(dir)) return null;
|
|
219
|
+
const files = await collectJsonlFiles(dir, 2);
|
|
220
|
+
if (files.length === 0) return null;
|
|
221
|
+
let max = 0;
|
|
222
|
+
for (const f of files) if (f.mtime > max) max = f.mtime;
|
|
223
|
+
return max > 0 ? max : null;
|
|
224
|
+
}
|
|
225
|
+
async function collectJsonlFiles(dir, maxDepth) {
|
|
226
|
+
const out = [];
|
|
227
|
+
await walk(dir, 0);
|
|
228
|
+
return out;
|
|
229
|
+
async function walk(current, depth) {
|
|
230
|
+
let entries;
|
|
231
|
+
try {
|
|
232
|
+
entries = await fs2.readdir(current, { withFileTypes: true });
|
|
233
|
+
} catch {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
for (const e of entries) {
|
|
237
|
+
const full = path2.join(current, e.name);
|
|
238
|
+
if (e.isFile() && e.name.endsWith(".jsonl")) {
|
|
239
|
+
try {
|
|
240
|
+
const s = await fs2.stat(full);
|
|
241
|
+
out.push({ path: full, mtime: s.mtimeMs });
|
|
242
|
+
} catch {
|
|
243
|
+
}
|
|
244
|
+
} else if (e.isDirectory() && depth < maxDepth) {
|
|
245
|
+
await walk(full, depth + 1);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
var claudeCwdExtractor = (line) => {
|
|
251
|
+
try {
|
|
252
|
+
const parsed = JSON.parse(line);
|
|
253
|
+
if (typeof parsed.cwd === "string" && parsed.cwd.startsWith("/")) return parsed.cwd;
|
|
254
|
+
} catch {
|
|
255
|
+
}
|
|
256
|
+
return null;
|
|
257
|
+
};
|
|
258
|
+
var CODEX_CWD_RE = /<cwd>([^<]+)<\/cwd>/;
|
|
259
|
+
var codexCwdExtractor = (line) => {
|
|
260
|
+
try {
|
|
261
|
+
const parsed = JSON.parse(line);
|
|
262
|
+
const cwd = parsed.payload?.cwd;
|
|
263
|
+
if (typeof cwd === "string" && cwd.startsWith("/")) return cwd;
|
|
264
|
+
} catch {
|
|
265
|
+
}
|
|
266
|
+
const m = CODEX_CWD_RE.exec(line);
|
|
267
|
+
if (m && m[1] && m[1].startsWith("/")) return m[1];
|
|
268
|
+
return null;
|
|
269
|
+
};
|
|
270
|
+
async function readFirstFromJsonlDir(dir, extractor) {
|
|
271
|
+
const files = await collectJsonlFiles(dir, 2);
|
|
272
|
+
if (files.length === 0) return null;
|
|
273
|
+
files.sort((a, b) => b.mtime - a.mtime);
|
|
274
|
+
for (const f of files) {
|
|
275
|
+
const v = await readFirstFromFile(f.path, extractor);
|
|
276
|
+
if (v) return v;
|
|
277
|
+
}
|
|
278
|
+
return null;
|
|
279
|
+
}
|
|
280
|
+
async function readFirstFromFile(file, extractor) {
|
|
281
|
+
return new Promise((resolve) => {
|
|
282
|
+
const stream = createReadStream(file, { encoding: "utf-8" });
|
|
283
|
+
const rl = readline.createInterface({ input: stream, crlfDelay: Infinity });
|
|
284
|
+
let lines = 0;
|
|
285
|
+
let done = false;
|
|
286
|
+
const MAX_LINES = 200;
|
|
287
|
+
const finish = (value) => {
|
|
288
|
+
if (done) return;
|
|
289
|
+
done = true;
|
|
290
|
+
resolve(value);
|
|
291
|
+
rl.close();
|
|
292
|
+
stream.destroy();
|
|
293
|
+
};
|
|
294
|
+
rl.on("line", (line) => {
|
|
295
|
+
if (done) return;
|
|
296
|
+
lines++;
|
|
297
|
+
if (lines > MAX_LINES) {
|
|
298
|
+
finish(null);
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
const v = extractor(line);
|
|
302
|
+
if (v) finish(v);
|
|
303
|
+
});
|
|
304
|
+
rl.on("close", () => finish(null));
|
|
305
|
+
rl.on("error", () => finish(null));
|
|
306
|
+
stream.on("error", () => finish(null));
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
function fallbackDashDecode(entry) {
|
|
310
|
+
if (!entry.startsWith("-")) return null;
|
|
311
|
+
return "/" + entry.slice(1).replace(/-/g, "/");
|
|
312
|
+
}
|
|
141
313
|
function formatRelativeTime(ms) {
|
|
142
314
|
if (ms === 0) return "\u2014";
|
|
143
315
|
const diff = Date.now() - ms;
|
|
@@ -164,7 +336,7 @@ init_esm_shims();
|
|
|
164
336
|
// package.json
|
|
165
337
|
var package_default = {
|
|
166
338
|
name: "@kenkaiiii/gg-boss",
|
|
167
|
-
version: "4.3.
|
|
339
|
+
version: "4.3.151",
|
|
168
340
|
type: "module",
|
|
169
341
|
description: "Orchestrator agent that drives multiple ggcoder sessions across projects from a single chat",
|
|
170
342
|
license: "MIT",
|
|
@@ -334,6 +506,14 @@ function GradientText({ text }) {
|
|
|
334
506
|
// src/link-command.tsx
|
|
335
507
|
var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
|
|
336
508
|
var VISIBLE_ROWS = 12;
|
|
509
|
+
function sourceBadge(sources) {
|
|
510
|
+
if (sources.length > 1) return { label: "[mix]", color: COLORS.success };
|
|
511
|
+
const only = sources[0];
|
|
512
|
+
if (only === "ggcoder") return { label: "[gg ]", color: COLORS.accent };
|
|
513
|
+
if (only === "claude-code") return { label: "[cc ]", color: COLORS.warning };
|
|
514
|
+
if (only === "codex") return { label: "[cx ]", color: COLORS.primary };
|
|
515
|
+
return { label: "[?? ]", color: COLORS.textDim };
|
|
516
|
+
}
|
|
337
517
|
function LinkScreen({ projects, initialSelected, onDone }) {
|
|
338
518
|
const [cursor, setCursor] = (0, import_react2.useState)(0);
|
|
339
519
|
const [selected, setSelected] = (0, import_react2.useState)(new Set(initialSelected));
|
|
@@ -406,11 +586,14 @@ function LinkScreen({ projects, initialSelected, onDone }) {
|
|
|
406
586
|
const arrow = isCursor ? "\u276F" : " ";
|
|
407
587
|
const nameColor = isCursor ? COLORS.primary : isSelected ? COLORS.success : COLORS.text;
|
|
408
588
|
const checkboxColor = isSelected ? COLORS.success : COLORS.textDim;
|
|
589
|
+
const badge = sourceBadge(p.sources);
|
|
409
590
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { children: [
|
|
410
591
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: COLORS.primary, children: arrow }),
|
|
411
592
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { children: " " }),
|
|
412
593
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: checkboxColor, children: checkbox }),
|
|
413
594
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { children: " " }),
|
|
595
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: badge.color, children: badge.label }),
|
|
596
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { children: " " }),
|
|
414
597
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: nameColor, bold: isCursor, children: p.name }),
|
|
415
598
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: COLORS.textDim, children: " " }),
|
|
416
599
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: COLORS.textDim, children: p.lastActiveDisplay })
|
|
@@ -1219,13 +1402,13 @@ init_esm_shims();
|
|
|
1219
1402
|
import { spawn as spawn2 } from "child_process";
|
|
1220
1403
|
import fs3 from "fs";
|
|
1221
1404
|
import path3 from "path";
|
|
1222
|
-
import
|
|
1405
|
+
import os2 from "os";
|
|
1223
1406
|
var PACKAGE_NAME = "@kenkaiiii/gg-boss";
|
|
1224
1407
|
var REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
|
|
1225
1408
|
var CHECK_INTERVAL_MS = 60 * 60 * 1e3;
|
|
1226
1409
|
var FETCH_TIMEOUT_MS = 1e4;
|
|
1227
1410
|
function getStateFilePath() {
|
|
1228
|
-
return path3.join(
|
|
1411
|
+
return path3.join(os2.homedir(), ".gg", "boss", "update-state.json");
|
|
1229
1412
|
}
|
|
1230
1413
|
function readState() {
|
|
1231
1414
|
try {
|
|
@@ -1391,7 +1574,7 @@ function BossAppInner({ boss, resetUI }) {
|
|
|
1391
1574
|
const state = useBossState();
|
|
1392
1575
|
const { exit } = use_app_default();
|
|
1393
1576
|
const { stdout } = use_stdout_default();
|
|
1394
|
-
const { resizeKey, columns } = useTerminalSize();
|
|
1577
|
+
const { resizeKey, columns, rows } = useTerminalSize();
|
|
1395
1578
|
const runStartRef = (0, import_react11.useRef)(null);
|
|
1396
1579
|
runStartRef.current = state.runStartMs;
|
|
1397
1580
|
const charCountRef = (0, import_react11.useRef)(0);
|
|
@@ -1399,11 +1582,8 @@ function BossAppInner({ boss, resetUI }) {
|
|
|
1399
1582
|
const realTokensAccumRef = (0, import_react11.useRef)(0);
|
|
1400
1583
|
realTokensAccumRef.current = state.bossInputTokens;
|
|
1401
1584
|
const [lastUserMessage, setLastUserMessage] = (0, import_react11.useState)("");
|
|
1402
|
-
const
|
|
1403
|
-
null
|
|
1404
|
-
);
|
|
1585
|
+
const overlay = state.overlay;
|
|
1405
1586
|
const [currentRadio, setCurrentRadio] = (0, import_react11.useState)(() => getCurrentStation());
|
|
1406
|
-
const [staticKey, setStaticKey] = (0, import_react11.useState)(0);
|
|
1407
1587
|
const [updatePending, setUpdatePending] = (0, import_react11.useState)(
|
|
1408
1588
|
() => getPendingUpdate(VERSION) !== null
|
|
1409
1589
|
);
|
|
@@ -1443,13 +1623,15 @@ function BossAppInner({ boss, resetUI }) {
|
|
|
1443
1623
|
);
|
|
1444
1624
|
const openOverlay = (0, import_react11.useCallback)(
|
|
1445
1625
|
(next) => {
|
|
1446
|
-
setOverlay(next);
|
|
1626
|
+
bossStore.setOverlay(next);
|
|
1627
|
+
if (resetUI) resetUI();
|
|
1447
1628
|
},
|
|
1448
|
-
[]
|
|
1629
|
+
[resetUI]
|
|
1449
1630
|
);
|
|
1450
1631
|
const closeOverlay = (0, import_react11.useCallback)(() => {
|
|
1451
|
-
setOverlay(null);
|
|
1452
|
-
|
|
1632
|
+
bossStore.setOverlay(null);
|
|
1633
|
+
if (resetUI) resetUI();
|
|
1634
|
+
}, [resetUI]);
|
|
1453
1635
|
void stdout;
|
|
1454
1636
|
const handleDoubleExit = useDoublePress(
|
|
1455
1637
|
(pending) => bossStore.setExitPending(pending),
|
|
@@ -1484,10 +1666,9 @@ function BossAppInner({ boss, resetUI }) {
|
|
|
1484
1666
|
bossStore.appendInfo(buildHelpText(), "info");
|
|
1485
1667
|
return true;
|
|
1486
1668
|
case "clear":
|
|
1487
|
-
resetUI?.();
|
|
1488
1669
|
bossStore.clearHistory();
|
|
1670
|
+
resetUI?.();
|
|
1489
1671
|
await boss.resetConversation();
|
|
1490
|
-
setStaticKey((k) => k + 1);
|
|
1491
1672
|
bossStore.appendInfo("Session cleared.", "info");
|
|
1492
1673
|
return true;
|
|
1493
1674
|
case "model-boss":
|
|
@@ -1543,8 +1724,14 @@ function BossAppInner({ boss, resetUI }) {
|
|
|
1543
1724
|
}
|
|
1544
1725
|
handleDoubleExit();
|
|
1545
1726
|
};
|
|
1727
|
+
if (rows < 14) {
|
|
1728
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { flexDirection: "column", width: columns, paddingX: 1, marginTop: 1, children: [
|
|
1729
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { bold: true, color: COLORS.accent, children: "Terminal too small" }),
|
|
1730
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { color: COLORS.primary, children: `Resize to at least 14 rows to use GG Boss (currently ${rows}).` })
|
|
1731
|
+
] });
|
|
1732
|
+
}
|
|
1546
1733
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { flexDirection: "column", width: columns, children: [
|
|
1547
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Static, { items: staticItems, style: { width: "100%" }, children: (item) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { flexDirection: "column", paddingRight: 1, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(StaticRowView, { row: item }) }, item.id) },
|
|
1734
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Static, { items: staticItems, style: { width: "100%" }, children: (item) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { flexDirection: "column", paddingRight: 1, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(StaticRowView, { row: item }) }, item.id) }, resizeKey),
|
|
1548
1735
|
overlay === "tasks" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(BossTasksOverlay, { boss, workers: state.workers, onClose: closeOverlay }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
1549
1736
|
state.streaming && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(StreamingTurnView, { turn: state.streaming, isRunning: state.phase === "working" }),
|
|
1550
1737
|
state.phase === "working" && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
@@ -1696,6 +1883,7 @@ function WorkerStatusBar({
|
|
|
1696
1883
|
pendingMessages
|
|
1697
1884
|
}) {
|
|
1698
1885
|
const theme = useTheme();
|
|
1886
|
+
const { columns } = useTerminalSize();
|
|
1699
1887
|
const working = workers.filter((w) => w.status === "working");
|
|
1700
1888
|
const errored = workers.filter((w) => w.status === "error");
|
|
1701
1889
|
const idleCount = workers.length - working.length - errored.length;
|
|
@@ -1734,19 +1922,21 @@ function WorkerStatusBar({
|
|
|
1734
1922
|
] }) }, "idle")
|
|
1735
1923
|
);
|
|
1736
1924
|
}
|
|
1737
|
-
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { paddingX: 1, children: [
|
|
1925
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { paddingX: 1, width: columns, flexShrink: 1, children: [
|
|
1738
1926
|
anyWorking && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(AnimationActiveSentinel, {}),
|
|
1739
|
-
|
|
1740
|
-
i
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1927
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { wrap: "truncate", children: [
|
|
1928
|
+
slots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react11.default.Fragment, { children: [
|
|
1929
|
+
i > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { color: theme.border, children: " \u2502 " }),
|
|
1930
|
+
slot
|
|
1931
|
+
] }, i)),
|
|
1932
|
+
pendingMessages > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
1933
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { color: theme.textDim, children: " " }),
|
|
1934
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { color: theme.warning, children: [
|
|
1935
|
+
pendingMessages,
|
|
1936
|
+
" message",
|
|
1937
|
+
pendingMessages === 1 ? "" : "s",
|
|
1938
|
+
" queued"
|
|
1939
|
+
] })
|
|
1750
1940
|
] })
|
|
1751
1941
|
] })
|
|
1752
1942
|
] });
|