@punkcode/cli 0.1.17 → 0.1.18
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.
|
@@ -10,10 +10,10 @@ import {
|
|
|
10
10
|
signIn,
|
|
11
11
|
usePunkStore,
|
|
12
12
|
version
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-NW32U73H.js";
|
|
14
14
|
|
|
15
15
|
// src/ui/App.tsx
|
|
16
|
-
import { useEffect as useEffect3, useRef, useState as useState3 } from "react";
|
|
16
|
+
import { useEffect as useEffect3, useRef as useRef2, useState as useState3 } from "react";
|
|
17
17
|
|
|
18
18
|
// src/ui/LoginDialog.tsx
|
|
19
19
|
import { useState, useEffect, useCallback } from "react";
|
|
@@ -208,7 +208,7 @@ function PasswordInput({ onSubmit }) {
|
|
|
208
208
|
}
|
|
209
209
|
|
|
210
210
|
// src/ui/Dashboard.tsx
|
|
211
|
-
import { useState as useState2, useEffect as useEffect2 } from "react";
|
|
211
|
+
import { useState as useState2, useEffect as useEffect2, useRef } from "react";
|
|
212
212
|
import { Box as Box2, Text as Text2, useApp, useInput as useInput2, useStdout } from "ink";
|
|
213
213
|
import { Badge } from "@inkjs/ui";
|
|
214
214
|
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
@@ -238,18 +238,44 @@ function Dashboard({ store, connection, overlay }) {
|
|
|
238
238
|
const server = usePunkStore(store, (s) => s.server);
|
|
239
239
|
const connectedAt = usePunkStore(store, (s) => s.connectedAt);
|
|
240
240
|
const auth = usePunkStore(store, (s) => s.auth);
|
|
241
|
+
const sessionProjects = usePunkStore(store, (s) => s.sessionProjects);
|
|
242
|
+
const [focusMode, setFocusMode] = useState2(false);
|
|
243
|
+
const [focusedSessionIdx, setFocusedSessionIdx] = useState2(0);
|
|
244
|
+
const knownSessionIds = Object.keys(sessionProjects);
|
|
245
|
+
const focusedSessionId = focusMode ? knownSessionIds[focusedSessionIdx] : null;
|
|
246
|
+
const hasMultipleSessions = knownSessionIds.length > 1;
|
|
247
|
+
const filteredActivity = focusedSessionId ? activityLog.filter((e) => e.sessionId === focusedSessionId) : activityLog;
|
|
241
248
|
const [now, setNow] = useState2(Date.now());
|
|
242
249
|
useEffect2(() => {
|
|
243
250
|
const timer = setInterval(() => setNow(Date.now()), 1e3);
|
|
244
251
|
return () => clearInterval(timer);
|
|
245
252
|
}, []);
|
|
253
|
+
const [selectedIdx, setSelectedIdx] = useState2(-1);
|
|
254
|
+
const [userScrolled, setUserScrolled] = useState2(false);
|
|
255
|
+
const prevLogLength = useRef(filteredActivity.length);
|
|
256
|
+
useEffect2(() => {
|
|
257
|
+
if (filteredActivity.length > prevLogLength.current && !userScrolled) {
|
|
258
|
+
setSelectedIdx(filteredActivity.length - 1);
|
|
259
|
+
}
|
|
260
|
+
prevLogLength.current = filteredActivity.length;
|
|
261
|
+
}, [filteredActivity.length, userScrolled]);
|
|
262
|
+
useEffect2(() => {
|
|
263
|
+
setSelectedIdx(filteredActivity.length - 1);
|
|
264
|
+
setUserScrolled(false);
|
|
265
|
+
}, [focusedSessionId]);
|
|
266
|
+
const [detailEntry, setDetailEntry] = useState2(null);
|
|
267
|
+
const effectiveIdx = selectedIdx === -1 ? filteredActivity.length - 1 : selectedIdx;
|
|
246
268
|
useInput2((input, key) => {
|
|
247
269
|
if (input === "q" || input === "c" && key.ctrl) {
|
|
248
270
|
connection?.disconnect();
|
|
249
271
|
exit();
|
|
250
272
|
}
|
|
251
273
|
if (input === "r") connection?.reconnect();
|
|
252
|
-
if (input === "c" && !key.ctrl)
|
|
274
|
+
if (input === "c" && !key.ctrl) {
|
|
275
|
+
store.getState().clearActivity();
|
|
276
|
+
setSelectedIdx(-1);
|
|
277
|
+
setUserScrolled(false);
|
|
278
|
+
}
|
|
253
279
|
if (input === "l") {
|
|
254
280
|
connection?.disconnect();
|
|
255
281
|
clearAuth();
|
|
@@ -258,6 +284,35 @@ function Dashboard({ store, connection, overlay }) {
|
|
|
258
284
|
store.getState().addActivity({ icon: "\u25CF", message: "Logged out" });
|
|
259
285
|
store.getState().setScreen("login");
|
|
260
286
|
}
|
|
287
|
+
if (input === "g" && knownSessionIds.length > 0) {
|
|
288
|
+
setFocusMode((f) => !f);
|
|
289
|
+
setFocusedSessionIdx(0);
|
|
290
|
+
}
|
|
291
|
+
if (focusMode && key.leftArrow) {
|
|
292
|
+
setFocusedSessionIdx((i) => (i - 1 + knownSessionIds.length) % knownSessionIds.length);
|
|
293
|
+
}
|
|
294
|
+
if (focusMode && key.rightArrow) {
|
|
295
|
+
setFocusedSessionIdx((i) => (i + 1) % knownSessionIds.length);
|
|
296
|
+
}
|
|
297
|
+
if (key.return && !detailEntry && effectiveIdx >= 0 && effectiveIdx < filteredActivity.length) {
|
|
298
|
+
setDetailEntry(filteredActivity[effectiveIdx]);
|
|
299
|
+
}
|
|
300
|
+
if ((key.escape || key.return) && detailEntry) {
|
|
301
|
+
setDetailEntry(null);
|
|
302
|
+
}
|
|
303
|
+
if (!detailEntry && key.upArrow && filteredActivity.length > 0) {
|
|
304
|
+
setUserScrolled(true);
|
|
305
|
+
setSelectedIdx((prev) => Math.max(0, (prev === -1 ? filteredActivity.length - 1 : prev) - 1));
|
|
306
|
+
}
|
|
307
|
+
if (!detailEntry && key.downArrow && filteredActivity.length > 0) {
|
|
308
|
+
const next = selectedIdx + 1;
|
|
309
|
+
if (next >= filteredActivity.length - 1) {
|
|
310
|
+
setUserScrolled(false);
|
|
311
|
+
setSelectedIdx(filteredActivity.length - 1);
|
|
312
|
+
} else {
|
|
313
|
+
setSelectedIdx(next);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
261
316
|
});
|
|
262
317
|
const sessionList = Object.values(sessions);
|
|
263
318
|
const uptime = connectedAt ? formatDuration(now - connectedAt) : "-";
|
|
@@ -266,8 +321,14 @@ function Dashboard({ store, connection, overlay }) {
|
|
|
266
321
|
const headerHeight = 8;
|
|
267
322
|
const sessionHeight = Math.max(sessionList.length, 1) + 5;
|
|
268
323
|
const footerHeight = 1;
|
|
269
|
-
const
|
|
270
|
-
const
|
|
324
|
+
const visibleCount = Math.max(termHeight - headerHeight - sessionHeight - footerHeight - 4, 4);
|
|
325
|
+
const tabBarHeight = focusMode ? 1 : 0;
|
|
326
|
+
const adjustedVisibleCount = visibleCount - tabBarHeight;
|
|
327
|
+
let viewStart = Math.max(0, filteredActivity.length - adjustedVisibleCount);
|
|
328
|
+
if (effectiveIdx < viewStart) viewStart = effectiveIdx;
|
|
329
|
+
if (effectiveIdx >= viewStart + adjustedVisibleCount) viewStart = effectiveIdx - adjustedVisibleCount + 1;
|
|
330
|
+
viewStart = Math.max(0, viewStart);
|
|
331
|
+
const visibleActivity = filteredActivity.slice(viewStart, viewStart + adjustedVisibleCount);
|
|
271
332
|
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", width: termWidth, height: termHeight, children: [
|
|
272
333
|
/* @__PURE__ */ jsxs2(Box2, { flexDirection: "row", justifyContent: "space-between", width: termWidth - 2, paddingX: 1, children: [
|
|
273
334
|
/* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
|
|
@@ -330,15 +391,19 @@ function Dashboard({ store, connection, overlay }) {
|
|
|
330
391
|
] }),
|
|
331
392
|
/* @__PURE__ */ jsxs2(Box2, { children: [
|
|
332
393
|
/* @__PURE__ */ jsx2(Text2, { color: theme.accent, bold: true, children: "<c> ".padEnd(10) }),
|
|
333
|
-
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Clear
|
|
394
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Clear Activity" })
|
|
395
|
+
] }),
|
|
396
|
+
/* @__PURE__ */ jsxs2(Box2, { children: [
|
|
397
|
+
/* @__PURE__ */ jsx2(Text2, { color: theme.accent, bold: true, children: "<g> ".padEnd(10) }),
|
|
398
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Group Activity" })
|
|
334
399
|
] }),
|
|
335
400
|
/* @__PURE__ */ jsxs2(Box2, { children: [
|
|
336
401
|
/* @__PURE__ */ jsx2(Text2, { color: theme.accent, bold: true, children: "<l> ".padEnd(10) }),
|
|
337
402
|
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Logout" })
|
|
338
403
|
] }),
|
|
339
404
|
/* @__PURE__ */ jsxs2(Box2, { children: [
|
|
340
|
-
/* @__PURE__ */ jsx2(Text2, { color: theme.accent, bold: true, children: "<
|
|
341
|
-
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "
|
|
405
|
+
/* @__PURE__ */ jsx2(Text2, { color: theme.accent, bold: true, children: "<enter> ".padEnd(10) }),
|
|
406
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Activity Details" })
|
|
342
407
|
] })
|
|
343
408
|
] }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
344
409
|
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
@@ -350,8 +415,14 @@ function Dashboard({ store, connection, overlay }) {
|
|
|
350
415
|
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
351
416
|
/* @__PURE__ */ jsx2(Text2, { color: theme.accent, bold: true, children: "c" }),
|
|
352
417
|
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: " clear " }),
|
|
418
|
+
/* @__PURE__ */ jsx2(Text2, { color: theme.accent, bold: true, children: "g" }),
|
|
419
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: " group" })
|
|
420
|
+
] }),
|
|
421
|
+
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
353
422
|
/* @__PURE__ */ jsx2(Text2, { color: theme.accent, bold: true, children: "l" }),
|
|
354
|
-
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: " logout" })
|
|
423
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: " logout " }),
|
|
424
|
+
/* @__PURE__ */ jsx2(Text2, { color: theme.accent, bold: true, children: "enter" }),
|
|
425
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: " details" })
|
|
355
426
|
] })
|
|
356
427
|
] }) }),
|
|
357
428
|
termWidth >= 120 && /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", alignItems: "flex-end", justifyContent: "center", children: LOGO.map((line, i) => /* @__PURE__ */ jsx2(Text2, { color: theme.logo, children: line }, i)) })
|
|
@@ -384,7 +455,10 @@ function Dashboard({ store, connection, overlay }) {
|
|
|
384
455
|
)
|
|
385
456
|
] }),
|
|
386
457
|
/* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", marginX: 1, flexGrow: 1, children: [
|
|
387
|
-
buildTopBorderJsx(
|
|
458
|
+
buildTopBorderJsx(
|
|
459
|
+
overlay ? "Login" : focusMode && focusedSessionId ? `Activity: ${sessionProjects[focusedSessionId]?.project ?? focusedSessionId.slice(0, 8)}` : filteredActivity.length > adjustedVisibleCount ? `Activity (${effectiveIdx + 1}/${filteredActivity.length})` : "Activity",
|
|
460
|
+
boxWidth
|
|
461
|
+
),
|
|
388
462
|
/* @__PURE__ */ jsx2(
|
|
389
463
|
Box2,
|
|
390
464
|
{
|
|
@@ -396,23 +470,117 @@ function Dashboard({ store, connection, overlay }) {
|
|
|
396
470
|
flexGrow: 1,
|
|
397
471
|
alignItems: overlay ? "center" : void 0,
|
|
398
472
|
justifyContent: overlay ? "center" : void 0,
|
|
399
|
-
children: overlay ?? (
|
|
473
|
+
children: overlay ?? (detailEntry ? (
|
|
474
|
+
/* Detail view */
|
|
475
|
+
/* @__PURE__ */ jsx2(DetailView, { entry: detailEntry, sessionProjects })
|
|
476
|
+
) : /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
477
|
+
focusMode && knownSessionIds.length > 0 && /* @__PURE__ */ jsxs2(Box2, { marginBottom: 1, gap: 1, children: [
|
|
478
|
+
knownSessionIds.map((sid, i) => {
|
|
479
|
+
const sp = sessionProjects[sid];
|
|
480
|
+
const isFocused = i === focusedSessionIdx;
|
|
481
|
+
return /* @__PURE__ */ jsx2(Text2, { children: isFocused ? /* @__PURE__ */ jsxs2(Text2, { bold: true, children: [
|
|
482
|
+
"[",
|
|
483
|
+
sp?.project ?? sid.slice(0, 8),
|
|
484
|
+
":",
|
|
485
|
+
sid.slice(0, 8),
|
|
486
|
+
"]"
|
|
487
|
+
] }) : /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
488
|
+
" ",
|
|
489
|
+
sp?.project ?? sid.slice(0, 8),
|
|
490
|
+
":",
|
|
491
|
+
sid.slice(0, 8),
|
|
492
|
+
" "
|
|
493
|
+
] }) }, sid);
|
|
494
|
+
}),
|
|
495
|
+
/* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
496
|
+
" ",
|
|
497
|
+
"\u2190",
|
|
498
|
+
"/",
|
|
499
|
+
"\u2192",
|
|
500
|
+
" switch g all"
|
|
501
|
+
] })
|
|
502
|
+
] }),
|
|
503
|
+
visibleActivity.length === 0 ? /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Waiting for events..." }) : visibleActivity.map((entry, i) => /* @__PURE__ */ jsx2(
|
|
504
|
+
ActivityRow,
|
|
505
|
+
{
|
|
506
|
+
entry,
|
|
507
|
+
termWidth,
|
|
508
|
+
isSelected: viewStart + i === effectiveIdx,
|
|
509
|
+
sessionProjects: hasMultipleSessions && !focusMode ? sessionProjects : void 0
|
|
510
|
+
},
|
|
511
|
+
`${entry.timestamp}-${i}`
|
|
512
|
+
))
|
|
513
|
+
] }))
|
|
400
514
|
}
|
|
401
515
|
)
|
|
402
516
|
] }),
|
|
403
517
|
/* @__PURE__ */ jsxs2(Box2, { paddingX: 1, justifyContent: "space-between", width: termWidth - 2, children: [
|
|
518
|
+
/* @__PURE__ */ jsx2(Box2, { gap: 2, children: detailEntry ? /* @__PURE__ */ jsx2(Fragment, { children: /* @__PURE__ */ jsxs2(Text2, { children: [
|
|
519
|
+
/* @__PURE__ */ jsx2(Text2, { color: theme.accent, bold: true, children: "esc" }),
|
|
520
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: " close" })
|
|
521
|
+
] }) }) : overlay ? /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
522
|
+
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
523
|
+
/* @__PURE__ */ jsx2(Text2, { color: theme.accent, bold: true, children: "e" }),
|
|
524
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: " email" })
|
|
525
|
+
] }),
|
|
526
|
+
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
527
|
+
/* @__PURE__ */ jsx2(Text2, { color: theme.accent, bold: true, children: "q" }),
|
|
528
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: " quit" })
|
|
529
|
+
] })
|
|
530
|
+
] }) : focusMode ? /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
531
|
+
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
532
|
+
/* @__PURE__ */ jsx2(Text2, { color: theme.accent, bold: true, children: "\u2190\u2192" }),
|
|
533
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: " switch" })
|
|
534
|
+
] }),
|
|
535
|
+
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
536
|
+
/* @__PURE__ */ jsx2(Text2, { color: theme.accent, bold: true, children: "g" }),
|
|
537
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: " all" })
|
|
538
|
+
] }),
|
|
539
|
+
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
540
|
+
/* @__PURE__ */ jsx2(Text2, { color: theme.accent, bold: true, children: "\u2191\u2193" }),
|
|
541
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: " scroll" })
|
|
542
|
+
] }),
|
|
543
|
+
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
544
|
+
/* @__PURE__ */ jsx2(Text2, { color: theme.accent, bold: true, children: "enter" }),
|
|
545
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: " details" })
|
|
546
|
+
] }),
|
|
547
|
+
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
548
|
+
/* @__PURE__ */ jsx2(Text2, { color: theme.accent, bold: true, children: "q" }),
|
|
549
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: " quit" })
|
|
550
|
+
] })
|
|
551
|
+
] }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
552
|
+
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
553
|
+
/* @__PURE__ */ jsx2(Text2, { color: theme.accent, bold: true, children: "\u2191\u2193" }),
|
|
554
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: " scroll" })
|
|
555
|
+
] }),
|
|
556
|
+
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
557
|
+
/* @__PURE__ */ jsx2(Text2, { color: theme.accent, bold: true, children: "enter" }),
|
|
558
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: " details" })
|
|
559
|
+
] }),
|
|
560
|
+
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
561
|
+
/* @__PURE__ */ jsx2(Text2, { color: theme.accent, bold: true, children: "g" }),
|
|
562
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: " group" })
|
|
563
|
+
] }),
|
|
564
|
+
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
565
|
+
/* @__PURE__ */ jsx2(Text2, { color: theme.accent, bold: true, children: "c" }),
|
|
566
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: " clear" })
|
|
567
|
+
] }),
|
|
568
|
+
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
569
|
+
/* @__PURE__ */ jsx2(Text2, { color: theme.accent, bold: true, children: "r" }),
|
|
570
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: " reconnect" })
|
|
571
|
+
] }),
|
|
572
|
+
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
573
|
+
/* @__PURE__ */ jsx2(Text2, { color: theme.accent, bold: true, children: "l" }),
|
|
574
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: " logout" })
|
|
575
|
+
] }),
|
|
576
|
+
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
577
|
+
/* @__PURE__ */ jsx2(Text2, { color: theme.accent, bold: true, children: "q" }),
|
|
578
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: " quit" })
|
|
579
|
+
] })
|
|
580
|
+
] }) }),
|
|
404
581
|
/* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
405
582
|
"punk v",
|
|
406
583
|
version
|
|
407
|
-
] }),
|
|
408
|
-
/* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
409
|
-
sessionList.length,
|
|
410
|
-
" session",
|
|
411
|
-
sessionList.length !== 1 ? "s" : "",
|
|
412
|
-
" ",
|
|
413
|
-
"\xB7",
|
|
414
|
-
" ",
|
|
415
|
-
stripProtocol(server)
|
|
416
584
|
] })
|
|
417
585
|
] })
|
|
418
586
|
] });
|
|
@@ -457,7 +625,54 @@ function SessionRow({ session, now, col }) {
|
|
|
457
625
|
col.showExtras && /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: session.effort ?? "" })
|
|
458
626
|
] });
|
|
459
627
|
}
|
|
460
|
-
function
|
|
628
|
+
function DetailView({ entry, sessionProjects }) {
|
|
629
|
+
const time = new Date(entry.timestamp).toLocaleTimeString("en-US", {
|
|
630
|
+
hour12: false,
|
|
631
|
+
hour: "2-digit",
|
|
632
|
+
minute: "2-digit",
|
|
633
|
+
second: "2-digit"
|
|
634
|
+
});
|
|
635
|
+
const date = new Date(entry.timestamp).toLocaleDateString("en-US", {
|
|
636
|
+
year: "numeric",
|
|
637
|
+
month: "short",
|
|
638
|
+
day: "numeric"
|
|
639
|
+
});
|
|
640
|
+
const sp = entry.sessionId ? sessionProjects[entry.sessionId] : null;
|
|
641
|
+
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", paddingY: 1, children: [
|
|
642
|
+
/* @__PURE__ */ jsx2(Box2, { gap: 1, children: /* @__PURE__ */ jsxs2(Text2, { bold: true, children: [
|
|
643
|
+
entry.icon,
|
|
644
|
+
" ",
|
|
645
|
+
entry.message
|
|
646
|
+
] }) }),
|
|
647
|
+
/* @__PURE__ */ jsx2(Text2, { children: " " }),
|
|
648
|
+
/* @__PURE__ */ jsxs2(Box2, { children: [
|
|
649
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Time: ".padEnd(12) }),
|
|
650
|
+
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
651
|
+
date,
|
|
652
|
+
" ",
|
|
653
|
+
time
|
|
654
|
+
] })
|
|
655
|
+
] }),
|
|
656
|
+
entry.sessionId && /* @__PURE__ */ jsxs2(Box2, { children: [
|
|
657
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Session: ".padEnd(12) }),
|
|
658
|
+
/* @__PURE__ */ jsx2(Text2, { children: entry.sessionId })
|
|
659
|
+
] }),
|
|
660
|
+
sp && /* @__PURE__ */ jsxs2(Box2, { children: [
|
|
661
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Project: ".padEnd(12) }),
|
|
662
|
+
/* @__PURE__ */ jsx2(Text2, { children: sp.project })
|
|
663
|
+
] }),
|
|
664
|
+
entry.data && Object.entries(entry.data).map(([key, value]) => {
|
|
665
|
+
if (value == null) return null;
|
|
666
|
+
const strValue = typeof value === "string" ? value : JSON.stringify(value);
|
|
667
|
+
if (!strValue) return null;
|
|
668
|
+
return /* @__PURE__ */ jsxs2(Box2, { children: [
|
|
669
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: (key + ":").padEnd(12) }),
|
|
670
|
+
/* @__PURE__ */ jsx2(Text2, { children: strValue })
|
|
671
|
+
] }, key);
|
|
672
|
+
})
|
|
673
|
+
] });
|
|
674
|
+
}
|
|
675
|
+
function ActivityRow({ entry, termWidth, isSelected, sessionProjects }) {
|
|
461
676
|
const time = new Date(entry.timestamp).toLocaleTimeString("en-US", {
|
|
462
677
|
hour12: false,
|
|
463
678
|
hour: "2-digit",
|
|
@@ -467,21 +682,25 @@ function ActivityRow({ entry, termWidth }) {
|
|
|
467
682
|
const iconColor = entry.icon === "\u2713" ? theme.success : entry.icon === "\u2717" ? theme.error : entry.icon === "\u25B6" ? theme.primary : entry.icon === "\u27F3" ? theme.warning : "white";
|
|
468
683
|
const sessionStr = entry.sessionId ? entry.sessionId.slice(0, 8) : "";
|
|
469
684
|
const detailStr = entry.detail ?? "";
|
|
685
|
+
const marker = isSelected ? "\u25B8 " : " ";
|
|
686
|
+
const sp = sessionProjects && entry.sessionId ? sessionProjects[entry.sessionId] : null;
|
|
470
687
|
return /* @__PURE__ */ jsxs2(Box2, { children: [
|
|
471
|
-
/* @__PURE__ */
|
|
688
|
+
/* @__PURE__ */ jsx2(Text2, { color: isSelected ? theme.primary : void 0, bold: isSelected, children: marker }),
|
|
689
|
+
/* @__PURE__ */ jsxs2(Text2, { dimColor: !isSelected, children: [
|
|
472
690
|
time,
|
|
473
691
|
" "
|
|
474
692
|
] }),
|
|
693
|
+
sp && /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: `${sp.project.slice(0, 8)}:${sessionStr}`.padEnd(18) }),
|
|
475
694
|
/* @__PURE__ */ jsxs2(Text2, { color: iconColor, bold: true, children: [
|
|
476
695
|
entry.icon,
|
|
477
696
|
" "
|
|
478
697
|
] }),
|
|
479
|
-
/* @__PURE__ */ jsx2(Text2, { children: entry.message }),
|
|
480
|
-
termWidth >= 80 && sessionStr && /* @__PURE__ */ jsxs2(Text2, { dimColor:
|
|
698
|
+
/* @__PURE__ */ jsx2(Text2, { bold: isSelected, children: entry.message }),
|
|
699
|
+
!sp && termWidth >= 80 && sessionStr && /* @__PURE__ */ jsxs2(Text2, { dimColor: !isSelected, children: [
|
|
481
700
|
" ",
|
|
482
701
|
sessionStr
|
|
483
702
|
] }),
|
|
484
|
-
termWidth >= 80 && detailStr && /* @__PURE__ */ jsxs2(Text2, { dimColor:
|
|
703
|
+
termWidth >= 80 && detailStr && /* @__PURE__ */ jsxs2(Text2, { dimColor: !isSelected, children: [
|
|
485
704
|
" ",
|
|
486
705
|
detailStr
|
|
487
706
|
] })
|
|
@@ -528,7 +747,7 @@ function App({ server, idToken, options }) {
|
|
|
528
747
|
}
|
|
529
748
|
return s;
|
|
530
749
|
});
|
|
531
|
-
const connectionRef =
|
|
750
|
+
const connectionRef = useRef2(null);
|
|
532
751
|
const screen = usePunkStore(store, (s) => s.screen);
|
|
533
752
|
useEffect3(() => {
|
|
534
753
|
if (screen !== "connecting") return;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/version.ts
|
|
4
|
-
var version = "0.1.
|
|
4
|
+
var version = "0.1.18";
|
|
5
5
|
|
|
6
6
|
// src/lib/auth.ts
|
|
7
7
|
import fs from "fs";
|
|
@@ -1292,6 +1292,8 @@ var PunkConnection = class {
|
|
|
1292
1292
|
handlePrompt(msg) {
|
|
1293
1293
|
const { id, prompt, sessionId, workingDirectory, images, options } = msg;
|
|
1294
1294
|
const { store } = this;
|
|
1295
|
+
const projectName = workingDirectory ? path3.basename(workingDirectory) : id.slice(0, 8);
|
|
1296
|
+
store.getState().registerSession(id, projectName);
|
|
1295
1297
|
store.getState().addSession(id, {
|
|
1296
1298
|
requestId: id,
|
|
1297
1299
|
prompt,
|
|
@@ -1305,7 +1307,8 @@ var PunkConnection = class {
|
|
|
1305
1307
|
icon: "\u25B6",
|
|
1306
1308
|
message: "Session started",
|
|
1307
1309
|
sessionId: id,
|
|
1308
|
-
detail: workingDirectory ? path3.basename(workingDirectory) : void 0
|
|
1310
|
+
detail: workingDirectory ? path3.basename(workingDirectory) : void 0,
|
|
1311
|
+
data: { prompt: prompt.slice(0, 500), workingDirectory, model: options?.model, effort: options?.effort }
|
|
1309
1312
|
});
|
|
1310
1313
|
const handle = runClaude(
|
|
1311
1314
|
{ prompt, sessionId, workingDirectory, images, options },
|
|
@@ -1324,10 +1327,12 @@ var PunkConnection = class {
|
|
|
1324
1327
|
},
|
|
1325
1328
|
onToolUse: (toolId, name, input, parentToolUseId) => {
|
|
1326
1329
|
this.send("response", { type: "tool_use", id: toolId, name, input, requestId: id, parent_tool_use_id: parentToolUseId ?? null });
|
|
1330
|
+
const inputStr = typeof input === "string" ? input : JSON.stringify(input);
|
|
1327
1331
|
store.getState().addActivity({
|
|
1328
1332
|
icon: "\u25B6",
|
|
1329
1333
|
message: `Tool: ${name}`,
|
|
1330
|
-
sessionId: id
|
|
1334
|
+
sessionId: id,
|
|
1335
|
+
data: { toolName: name, input: inputStr?.slice(0, 500) }
|
|
1331
1336
|
});
|
|
1332
1337
|
},
|
|
1333
1338
|
onToolResult: (toolUseId, content, isError) => {
|
|
@@ -1343,13 +1348,14 @@ var PunkConnection = class {
|
|
|
1343
1348
|
this.send("response", { type: "error", message, requestId: id });
|
|
1344
1349
|
this.activeSessions.delete(id);
|
|
1345
1350
|
store.getState().updateSession(id, { status: "error" });
|
|
1346
|
-
store.getState().addActivity({ icon: "\u2717", message: `Error: ${message}`, sessionId: id });
|
|
1351
|
+
store.getState().addActivity({ icon: "\u2717", message: `Error: ${message}`, sessionId: id, data: { error: message } });
|
|
1347
1352
|
},
|
|
1348
1353
|
onPermissionRequest: (req) => {
|
|
1349
1354
|
store.getState().addActivity({
|
|
1350
1355
|
icon: "\u25CF",
|
|
1351
1356
|
message: `Permission: ${req.toolName}`,
|
|
1352
|
-
sessionId: id
|
|
1357
|
+
sessionId: id,
|
|
1358
|
+
data: { toolName: req.toolName, input: JSON.stringify(req.input).slice(0, 500), reason: req.reason, blockedPath: req.blockedPath }
|
|
1353
1359
|
});
|
|
1354
1360
|
this.socket.emit("permission-request", {
|
|
1355
1361
|
requestId: id,
|
|
@@ -1557,7 +1563,8 @@ function fitToPayloadLimit(messages) {
|
|
|
1557
1563
|
|
|
1558
1564
|
// src/ui/store.ts
|
|
1559
1565
|
import { createStore, useStore } from "zustand";
|
|
1560
|
-
var MAX_ACTIVITY_ENTRIES =
|
|
1566
|
+
var MAX_ACTIVITY_ENTRIES = 500;
|
|
1567
|
+
var SESSION_COLORS = ["magenta", "blue", "magentaBright", "blueBright", "white", "gray"];
|
|
1561
1568
|
var createPunkStore = (server) => createStore((set) => ({
|
|
1562
1569
|
// Initial state
|
|
1563
1570
|
screen: "login",
|
|
@@ -1569,6 +1576,7 @@ var createPunkStore = (server) => createStore((set) => ({
|
|
|
1569
1576
|
connectedAt: null,
|
|
1570
1577
|
sessions: {},
|
|
1571
1578
|
activityLog: [],
|
|
1579
|
+
sessionProjects: {},
|
|
1572
1580
|
// Actions
|
|
1573
1581
|
setScreen: (screen) => set({ screen }),
|
|
1574
1582
|
setAuth: (auth) => set({ auth }),
|
|
@@ -1594,7 +1602,17 @@ var createPunkStore = (server) => createStore((set) => ({
|
|
|
1594
1602
|
{ ...entry, timestamp: Date.now() }
|
|
1595
1603
|
]
|
|
1596
1604
|
})),
|
|
1597
|
-
clearActivity: () => set({ activityLog: [] })
|
|
1605
|
+
clearActivity: () => set({ activityLog: [] }),
|
|
1606
|
+
registerSession: (id, project) => set((s) => {
|
|
1607
|
+
if (s.sessionProjects[id]) return s;
|
|
1608
|
+
const colorIdx = Object.keys(s.sessionProjects).length % SESSION_COLORS.length;
|
|
1609
|
+
return {
|
|
1610
|
+
sessionProjects: {
|
|
1611
|
+
...s.sessionProjects,
|
|
1612
|
+
[id]: { project, color: SESSION_COLORS[colorIdx] }
|
|
1613
|
+
}
|
|
1614
|
+
};
|
|
1615
|
+
})
|
|
1598
1616
|
}));
|
|
1599
1617
|
function usePunkStore(store, selector) {
|
|
1600
1618
|
return useStore(store, selector);
|
package/dist/cli.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
refreshIdToken,
|
|
9
9
|
signIn,
|
|
10
10
|
version
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-NW32U73H.js";
|
|
12
12
|
|
|
13
13
|
// src/cli.ts
|
|
14
14
|
import { program } from "commander";
|
|
@@ -135,7 +135,7 @@ async function runHeadless(server, idToken, options) {
|
|
|
135
135
|
async function runTui(server, options) {
|
|
136
136
|
const { render } = await import("ink");
|
|
137
137
|
const { createElement } = await import("react");
|
|
138
|
-
const { App } = await import("./App-
|
|
138
|
+
const { App } = await import("./App-GTPBJCS2.js");
|
|
139
139
|
const idToken = options.token ? options.token : void 0;
|
|
140
140
|
process.stdout.write("\x1B[?1049h");
|
|
141
141
|
process.stdout.write("\x1B[H");
|