typebulb 0.20.4 → 0.21.1
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 +5 -3
- package/dist/agents/claude/client.js +179 -178
- package/dist/agents/claude/styles.css +184 -7
- package/dist/agents/pi/client.js +295 -292
- package/dist/agents/pi/matchu-patchu.ts +2332 -0
- package/dist/agents/pi/styles.css +184 -7
- package/dist/index.js +271 -225
- package/dist/servers.js +119 -110
- package/package.json +4 -2
|
@@ -70,8 +70,11 @@ body {
|
|
|
70
70
|
line-height: 1.55;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
.
|
|
73
|
+
.app { display: flex; flex-direction: column; height: 100vh; }
|
|
74
|
+
/* The transcript region. position:relative anchors the overlaid (absolute) statusbar and banners to
|
|
75
|
+
THIS box, not the app: with a composer below the pills stay over the transcript's bottom edge
|
|
76
|
+
instead of landing on the input panel. */
|
|
77
|
+
.chat { position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; }
|
|
75
78
|
|
|
76
79
|
/* Bottom status strip, overlaid (not in flow) on the chat — which runs
|
|
77
80
|
full-height to the very bottom. The strip itself has NO fill, so the message
|
|
@@ -236,6 +239,154 @@ body {
|
|
|
236
239
|
stay opaque over the message text the strip lets through. */
|
|
237
240
|
.token.busy { border-color: var(--accent); --shimmer-base: var(--panel); --shimmer-mix: 25%; }
|
|
238
241
|
|
|
242
|
+
/* ── The composer (TB-Agent-Composer.md): the prompt panel under the transcript. In flow (not
|
|
243
|
+
overlaid like the statusbar) — it owns real height and must never cover content. ── */
|
|
244
|
+
.composer { position: relative; flex: none; background: var(--bg); }
|
|
245
|
+
/* A 4px drag zone centered on the composer's top border; z-index lifts it above the input-wrap
|
|
246
|
+
border so the line itself is grabbable. */
|
|
247
|
+
.splitter {
|
|
248
|
+
position: relative;
|
|
249
|
+
height: 4px;
|
|
250
|
+
margin-top: -2px;
|
|
251
|
+
margin-bottom: -2px;
|
|
252
|
+
z-index: 5;
|
|
253
|
+
cursor: row-resize;
|
|
254
|
+
background: transparent;
|
|
255
|
+
flex-shrink: 0;
|
|
256
|
+
}
|
|
257
|
+
.splitter:hover { background: color-mix(in srgb, var(--accent) 25%, transparent); }
|
|
258
|
+
.input-wrap { position: relative; border-top: 1px solid var(--border); }
|
|
259
|
+
.composer-input {
|
|
260
|
+
width: 100%;
|
|
261
|
+
display: block;
|
|
262
|
+
resize: none; /* height is splitter-driven (inline style), not the native handle */
|
|
263
|
+
border: none;
|
|
264
|
+
border-radius: 0;
|
|
265
|
+
background: var(--bg);
|
|
266
|
+
color: var(--fg);
|
|
267
|
+
font: inherit;
|
|
268
|
+
font-size: .9rem;
|
|
269
|
+
line-height: 1.45;
|
|
270
|
+
/* Right padding clears the three overlaid 28px buttons: .5rem inset + 3×28px + 2×.15rem gaps. */
|
|
271
|
+
padding: .5rem 6.2rem .5rem .75rem;
|
|
272
|
+
}
|
|
273
|
+
.composer-input:focus { outline: none; }
|
|
274
|
+
.composer-input:disabled { opacity: .6; }
|
|
275
|
+
.composer-input::placeholder { color: var(--muted); }
|
|
276
|
+
/* The icons.ts shell: one span, sized HERE (never by svg attrs), the material/custom svg filling
|
|
277
|
+
it. 14px default; context classes (.btn-icon, .caret-tri, …) override. */
|
|
278
|
+
.icon { display: inline-flex; align-items: center; justify-content: center; width: 14px; height: 14px; flex: none; }
|
|
279
|
+
.icon svg { width: 100%; height: 100%; display: block; }
|
|
280
|
+
/* The overlay row, bottom-anchored to the textarea's right edge: send/stop is the primary CTA;
|
|
281
|
+
+ (new conversation) and the clipboard clip are the quiet secondaries to its left. */
|
|
282
|
+
.composer-act, .composer-new, .composer-clip {
|
|
283
|
+
position: absolute;
|
|
284
|
+
bottom: .5rem;
|
|
285
|
+
width: 28px;
|
|
286
|
+
height: 28px;
|
|
287
|
+
display: flex;
|
|
288
|
+
align-items: center;
|
|
289
|
+
justify-content: center;
|
|
290
|
+
padding: 0;
|
|
291
|
+
margin: 0;
|
|
292
|
+
appearance: none;
|
|
293
|
+
border: none;
|
|
294
|
+
border-radius: 50%;
|
|
295
|
+
cursor: pointer;
|
|
296
|
+
transition: background .15s, color .15s, transform .08s;
|
|
297
|
+
}
|
|
298
|
+
/* Send/stop are CIRCLE GLYPHS (play_circle / stop_circle — typebulb.com's play look): the icon IS
|
|
299
|
+
the button, no painted disc. One size for all three — the circles' diameter and the paperclip's
|
|
300
|
+
ink height are both 800/960 of the material viewBox, so equal boxes = equal visual height. */
|
|
301
|
+
.composer-act .icon, .composer-new .icon, .composer-clip .icon { width: 24px; height: 24px; }
|
|
302
|
+
.composer-act { right: .5rem; background: transparent; }
|
|
303
|
+
.composer-act.send { color: var(--accent); }
|
|
304
|
+
.composer-act.send:hover:not(:disabled) { color: color-mix(in srgb, var(--accent) 80%, white); background: color-mix(in srgb, var(--accent) 10%, transparent); }
|
|
305
|
+
.composer-act.stop { color: var(--err); }
|
|
306
|
+
.composer-act.stop:hover { color: color-mix(in srgb, var(--err) 80%, white); background: color-mix(in srgb, var(--err) 10%, transparent); }
|
|
307
|
+
.composer-act:active, .composer-new:active, .composer-clip:active { transform: scale(.94); }
|
|
308
|
+
.composer-act:disabled, .composer-new:disabled, .composer-clip:disabled { opacity: .5; cursor: default; }
|
|
309
|
+
.composer-new {
|
|
310
|
+
/* offset = act's right inset (.5rem) + act width (28px) + gap (.15rem) */
|
|
311
|
+
right: calc(.5rem + 28px + .15rem);
|
|
312
|
+
background: transparent;
|
|
313
|
+
color: var(--muted);
|
|
314
|
+
}
|
|
315
|
+
.composer-new:hover:not(:disabled) { color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
|
|
316
|
+
.composer-clip {
|
|
317
|
+
/* one more button-width left of .composer-new */
|
|
318
|
+
right: calc(.5rem + 2 * (28px + .15rem));
|
|
319
|
+
background: transparent;
|
|
320
|
+
color: var(--muted);
|
|
321
|
+
}
|
|
322
|
+
.composer-clip:hover:not(:disabled) { color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
|
|
323
|
+
.composer-err { padding: .3rem .75rem; color: var(--err); font-size: .78rem; }
|
|
324
|
+
/* The ambient status line (TB-Agent-Composer-Toolkit.md Piece 2): one slim kind-tinted row above the
|
|
325
|
+
input — a retry/compaction in progress, an extension notice, a recipe's transient result. */
|
|
326
|
+
.composer-status { padding: .3rem .75rem; font-size: .78rem; color: var(--muted); }
|
|
327
|
+
.composer-status.warning { color: color-mix(in srgb, var(--err) 55%, var(--fg)); }
|
|
328
|
+
.composer-status.error { color: var(--err); }
|
|
329
|
+
/* The pending-queue strip (parity #2): queued steer/follow-up texts above the input. Block rows,
|
|
330
|
+
not a flex column — .queue-row's overflow:hidden would zero flex min-heights (the .dlg-opts
|
|
331
|
+
lesson). */
|
|
332
|
+
.composer-queue { padding: .15rem .75rem 0; }
|
|
333
|
+
.queue-row { font-size: .78rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
334
|
+
.queue-tag { color: var(--accent); font-size: .68rem; text-transform: uppercase; letter-spacing: .05em; margin-right: .5rem; }
|
|
335
|
+
/* The @-file-mention popup, anchored above the composer. */
|
|
336
|
+
.at-popup {
|
|
337
|
+
position: absolute;
|
|
338
|
+
bottom: calc(100% + .25rem);
|
|
339
|
+
left: 1rem;
|
|
340
|
+
right: 1rem;
|
|
341
|
+
max-width: 600px;
|
|
342
|
+
max-height: 280px;
|
|
343
|
+
overflow-y: auto;
|
|
344
|
+
background: var(--panel);
|
|
345
|
+
border: 1px solid var(--border);
|
|
346
|
+
border-radius: 10px;
|
|
347
|
+
box-shadow: 0 8px 30px rgba(0, 0, 0, .35);
|
|
348
|
+
padding: .25rem;
|
|
349
|
+
z-index: 10;
|
|
350
|
+
}
|
|
351
|
+
.at-row {
|
|
352
|
+
padding: .35rem .55rem;
|
|
353
|
+
border-radius: 6px;
|
|
354
|
+
cursor: pointer;
|
|
355
|
+
font-family: ui-monospace, Menlo, monospace;
|
|
356
|
+
font-size: .82rem;
|
|
357
|
+
white-space: nowrap;
|
|
358
|
+
overflow: hidden;
|
|
359
|
+
text-overflow: ellipsis;
|
|
360
|
+
}
|
|
361
|
+
.at-row.active { background: color-mix(in srgb, var(--accent) 18%, transparent); }
|
|
362
|
+
.at-row:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); }
|
|
363
|
+
/* The '/' palette rides the same popup chrome; its rows pair a command with a muted description. */
|
|
364
|
+
.slash-desc { color: var(--muted); font-size: .74rem; margin-left: .6rem; }
|
|
365
|
+
/* The composer's dialog modal (TB-Agent-Composer-Toolkit.md Piece 3) rides the trust-modal chrome; these
|
|
366
|
+
are only its extra fields. Select options reuse .at-row inside a bordered scroll box. */
|
|
367
|
+
/* Block, NOT flex: .at-row's overflow:hidden zeroes flex min-heights, squashing a long option
|
|
368
|
+
list (pi can return the whole OpenRouter catalog); block rows keep their natural height and
|
|
369
|
+
the box scrolls. */
|
|
370
|
+
.composer-dlg .dlg-opts {
|
|
371
|
+
max-height: 40vh; overflow-y: auto;
|
|
372
|
+
border: 1px solid var(--border); border-radius: 8px; padding: .25rem;
|
|
373
|
+
}
|
|
374
|
+
.composer-dlg .dlg-input, .composer-dlg .dlg-editor {
|
|
375
|
+
font: inherit; font-size: .85rem; color: var(--fg); background: transparent;
|
|
376
|
+
border: 1px solid var(--border); border-radius: 7px; padding: .4rem .6rem; width: 100%;
|
|
377
|
+
}
|
|
378
|
+
.composer-dlg .dlg-input:focus, .composer-dlg .dlg-editor:focus { outline: none; border-color: var(--accent); }
|
|
379
|
+
.composer-dlg .dlg-editor { min-height: 8rem; resize: vertical; }
|
|
380
|
+
.composer-dlg .dlg-filter { margin-top: .4rem; }
|
|
381
|
+
.at-empty { padding: .6rem; color: var(--muted); font-size: .85rem; text-align: center; }
|
|
382
|
+
/* The driver's in-flight assistant message — visibly provisional next to landed bubbles; the
|
|
383
|
+
durable row replaces it when the entry hits the transcript. */
|
|
384
|
+
.bubble.draft { opacity: .9; }
|
|
385
|
+
.draft-wait { color: var(--muted); }
|
|
386
|
+
/* Pasted-image thumbnails under a user message that @-mentions .typebulb/paste files. */
|
|
387
|
+
.paste-thumbs { margin-top: .4rem; }
|
|
388
|
+
.paste-thumb { display: block; max-width: min(360px, 100%); max-height: 240px; margin-top: .3rem; border: 1px solid var(--border); border-radius: 8px; }
|
|
389
|
+
|
|
239
390
|
/* Session list — shares the popover chrome (.picker above); these are
|
|
240
391
|
just its own dimensions. */
|
|
241
392
|
.picker { width: min(440px, calc(100vw - 2rem)); }
|
|
@@ -601,13 +752,16 @@ a.server-port:hover { text-decoration: underline; }
|
|
|
601
752
|
.trust-toggle { font-size: .76rem; height: 1.45rem; padding: 0 .5rem; color: var(--muted); justify-self: center; }
|
|
602
753
|
.trust-toggle:hover, .trust-toggle.on { color: var(--accent); border-color: var(--accent); }
|
|
603
754
|
.server-stop, .bulb-launch { width: 1.7rem; padding: 0; border-radius: 50%; margin-left: .4rem; }
|
|
604
|
-
.btn-icon {
|
|
755
|
+
.btn-icon { width: 16px; height: 16px; }
|
|
605
756
|
/* A stopped bulb's play button is dormant — the title is the primary launch target — so it's
|
|
606
757
|
hidden until the row is hovered or keyboard-selected. visibility (not display) reserves its slot,
|
|
607
758
|
so the name column doesn't shift when it appears. Painted the fold-marker green, matching the
|
|
608
759
|
:port link: green is the live-app axis (play to launch → :port to open it), distinct from the
|
|
609
760
|
blue source/name. The green even travels left→right as a bulb goes stopped→running. */
|
|
610
761
|
.bulb-launch { color: var(--fold-marker); visibility: hidden; }
|
|
762
|
+
/* A right triangle's visual mass sits left of its bounding box, so geometric centring reads
|
|
763
|
+
too-far-left in a round button — shift the play glyph. */
|
|
764
|
+
.bulb-launch .icon svg { transform: translateX(1px); }
|
|
611
765
|
.server-row:hover .bulb-launch, .server-row.active .bulb-launch { visibility: visible; }
|
|
612
766
|
.bulb-launch:hover { border-color: var(--fold-marker); background: color-mix(in srgb, var(--fold-marker) 12%, transparent); }
|
|
613
767
|
/* Launching: stays visible (hover-independent) and shimmers until the row flips to a stop button,
|
|
@@ -1118,6 +1272,23 @@ a.server-port:hover { text-decoration: underline; }
|
|
|
1118
1272
|
color: var(--fg); font-weight: 600;
|
|
1119
1273
|
}
|
|
1120
1274
|
.bulb-code .hljs-symbol, .bulb-code .hljs-bullet, .bulb-code .hljs-punctuation { color: var(--muted); }
|
|
1275
|
+
/* Draft-streaming bulb card (#draftBulbCard): the code view wearing a progress header — never a
|
|
1276
|
+
live mount; the durable row's BulbEmbed takes this slot when the entry lands. Cap tighter than
|
|
1277
|
+
.bulb-code's resting 480px: ambient progress, not reading material. */
|
|
1278
|
+
.md .bulb-streaming { flex-direction: column; }
|
|
1279
|
+
.md .bulb-streaming > .bulb-code { max-height: 220px; border-radius: 0 0 8px 8px; }
|
|
1280
|
+
.bulb-streaming-head {
|
|
1281
|
+
display: flex;
|
|
1282
|
+
align-items: baseline;
|
|
1283
|
+
gap: .45rem;
|
|
1284
|
+
padding: .3rem .85rem;
|
|
1285
|
+
border-radius: 8px 8px 0 0;
|
|
1286
|
+
/* A notch above the file-label bars inside the listing, so the header owns the card. */
|
|
1287
|
+
background: color-mix(in srgb, var(--fg) 10%, var(--tool-bg));
|
|
1288
|
+
font-size: .78rem;
|
|
1289
|
+
color: var(--muted);
|
|
1290
|
+
}
|
|
1291
|
+
.bulb-streaming-count { margin-left: auto; font-variant-numeric: tabular-nums; }
|
|
1121
1292
|
.md .bulb-embed.err {
|
|
1122
1293
|
padding: .6rem .8rem;
|
|
1123
1294
|
font-family: ui-monospace, monospace;
|
|
@@ -1167,7 +1338,7 @@ a.server-port:hover { text-decoration: underline; }
|
|
|
1167
1338
|
}
|
|
1168
1339
|
/* The shared disclosure triangle (caret() in messageList.ts). flex:none so a squeezed row can't
|
|
1169
1340
|
crush it; the digest row has no flex gap, so its spacing rides the marker. */
|
|
1170
|
-
.caret-tri {
|
|
1341
|
+
.caret-tri { width: 10px; height: 10px; transition: transform .15s ease; }
|
|
1171
1342
|
.caret-tri.open { transform: rotate(90deg); }
|
|
1172
1343
|
.tool-digest .caret-tri { margin-right: .5rem; }
|
|
1173
1344
|
/* Plain bold — an accent verb reads as a hyperlink; accent is reserved for the file-path link. */
|
|
@@ -1180,7 +1351,7 @@ a.server-port:hover { text-decoration: underline; }
|
|
|
1180
1351
|
answer). Same caret/row shape as a tool head, italic muted label. */
|
|
1181
1352
|
.turn-summary { color: var(--muted); font-size: .85rem; }
|
|
1182
1353
|
.turn-summary-text { font-style: italic; }
|
|
1183
|
-
.fork-icon { vertical-align: -1px; margin-right: .15rem; }
|
|
1354
|
+
.fork-icon { width: 11px; height: 11px; vertical-align: -1px; margin-right: .15rem; }
|
|
1184
1355
|
.turn-summary:hover .turn-summary-text { color: var(--fg); }
|
|
1185
1356
|
|
|
1186
1357
|
/* An expanded abandoned-branch (fork) stub renders its orphan messages here — set apart from the live
|
|
@@ -1307,9 +1478,15 @@ a.server-port:hover { text-decoration: underline; }
|
|
|
1307
1478
|
.tool-key { color: var(--muted); margin-right: .6rem; user-select: text; }
|
|
1308
1479
|
.tool-val { display: inline; margin: 0; font: inherit; white-space: pre-wrap; word-break: break-word; }
|
|
1309
1480
|
/* Line-banded unified-diff view (± lines only): the same add/remove band colors as
|
|
1310
|
-
.diff-new/.diff-old; a muted ⋯ row separates hunks.
|
|
1481
|
+
.diff-new/.diff-old; a muted ⋯ row separates hunks. The ± marker is ::before content in a
|
|
1482
|
+
reserved gutter — visible (the non-color cue colorblind readers need) but outside the DOM
|
|
1483
|
+
text, so selection-copy grabs only the code. min-height keeps blank changed lines from
|
|
1484
|
+
collapsing now that they carry no marker char. */
|
|
1311
1485
|
.udiff { white-space: pre-wrap; word-break: break-word; }
|
|
1312
|
-
.udiff-line { padding: 0 .2rem; }
|
|
1486
|
+
.udiff-line { position: relative; padding: 0 .2rem 0 1.05rem; min-height: 1lh; }
|
|
1487
|
+
.udiff-line::before { position: absolute; left: .25rem; }
|
|
1488
|
+
.udiff-add::before { content: '+'; }
|
|
1489
|
+
.udiff-del::before { content: '-'; }
|
|
1313
1490
|
.udiff-add { background: color-mix(in srgb, var(--diff-add) 24%, transparent); }
|
|
1314
1491
|
.udiff-del { background: color-mix(in srgb, var(--err) 24%, transparent); }
|
|
1315
1492
|
.udiff-gap { color: var(--muted); user-select: none; }
|