@critiquedotsh/harness 0.1.10 → 0.1.11
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/cli.js +1015 -870
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -21318,708 +21318,451 @@ function critiqueCodeWebPage(input) {
|
|
|
21318
21318
|
<title>CritiqueCode</title>
|
|
21319
21319
|
<style>
|
|
21320
21320
|
:root {
|
|
21321
|
-
--bg
|
|
21322
|
-
--rail
|
|
21323
|
-
--
|
|
21324
|
-
--
|
|
21325
|
-
--
|
|
21326
|
-
--
|
|
21327
|
-
--
|
|
21328
|
-
--
|
|
21329
|
-
--
|
|
21330
|
-
--
|
|
21331
|
-
--
|
|
21332
|
-
--
|
|
21333
|
-
--
|
|
21334
|
-
--
|
|
21335
|
-
--
|
|
21336
|
-
|
|
21337
|
-
|
|
21338
|
-
|
|
21339
|
-
|
|
21340
|
-
|
|
21341
|
-
|
|
21342
|
-
|
|
21343
|
-
|
|
21344
|
-
|
|
21345
|
-
|
|
21346
|
-
|
|
21347
|
-
|
|
21348
|
-
|
|
21349
|
-
|
|
21350
|
-
|
|
21351
|
-
|
|
21352
|
-
|
|
21353
|
-
|
|
21354
|
-
|
|
21355
|
-
|
|
21356
|
-
|
|
21357
|
-
|
|
21358
|
-
|
|
21359
|
-
|
|
21360
|
-
|
|
21361
|
-
|
|
21362
|
-
|
|
21363
|
-
|
|
21364
|
-
|
|
21365
|
-
|
|
21366
|
-
|
|
21367
|
-
.
|
|
21368
|
-
.
|
|
21369
|
-
.
|
|
21370
|
-
.
|
|
21371
|
-
.
|
|
21372
|
-
.
|
|
21373
|
-
.
|
|
21374
|
-
|
|
21375
|
-
|
|
21376
|
-
.
|
|
21377
|
-
.
|
|
21378
|
-
.
|
|
21379
|
-
.
|
|
21380
|
-
.
|
|
21381
|
-
.
|
|
21382
|
-
.
|
|
21383
|
-
.
|
|
21384
|
-
.
|
|
21385
|
-
.
|
|
21386
|
-
.
|
|
21387
|
-
|
|
21388
|
-
.
|
|
21389
|
-
.
|
|
21390
|
-
.
|
|
21391
|
-
|
|
21392
|
-
|
|
21393
|
-
.
|
|
21394
|
-
.
|
|
21395
|
-
|
|
21396
|
-
|
|
21397
|
-
.rail {
|
|
21398
|
-
.
|
|
21399
|
-
|
|
21400
|
-
|
|
21401
|
-
.
|
|
21402
|
-
.
|
|
21403
|
-
|
|
21404
|
-
.session-
|
|
21405
|
-
.
|
|
21406
|
-
.
|
|
21407
|
-
.
|
|
21408
|
-
.
|
|
21409
|
-
.
|
|
21410
|
-
.
|
|
21411
|
-
.
|
|
21412
|
-
|
|
21413
|
-
|
|
21414
|
-
#
|
|
21415
|
-
|
|
21416
|
-
|
|
21417
|
-
.
|
|
21418
|
-
.
|
|
21419
|
-
.
|
|
21420
|
-
|
|
21421
|
-
.
|
|
21422
|
-
.
|
|
21423
|
-
.
|
|
21424
|
-
.
|
|
21425
|
-
.
|
|
21426
|
-
.
|
|
21427
|
-
.
|
|
21428
|
-
.
|
|
21429
|
-
.
|
|
21430
|
-
.
|
|
21431
|
-
.
|
|
21432
|
-
.
|
|
21433
|
-
.
|
|
21434
|
-
.
|
|
21435
|
-
.
|
|
21436
|
-
.
|
|
21437
|
-
.
|
|
21438
|
-
|
|
21439
|
-
|
|
21440
|
-
.
|
|
21441
|
-
.
|
|
21442
|
-
.
|
|
21443
|
-
.
|
|
21444
|
-
.
|
|
21445
|
-
.
|
|
21446
|
-
.
|
|
21447
|
-
.
|
|
21448
|
-
.
|
|
21449
|
-
.
|
|
21450
|
-
.
|
|
21451
|
-
|
|
21452
|
-
.
|
|
21453
|
-
.
|
|
21454
|
-
.
|
|
21455
|
-
.
|
|
21456
|
-
.
|
|
21457
|
-
.
|
|
21458
|
-
.
|
|
21459
|
-
.
|
|
21460
|
-
|
|
21461
|
-
|
|
21462
|
-
.
|
|
21463
|
-
.
|
|
21464
|
-
.
|
|
21465
|
-
.
|
|
21466
|
-
.
|
|
21467
|
-
.
|
|
21468
|
-
.
|
|
21469
|
-
.
|
|
21470
|
-
.
|
|
21471
|
-
.
|
|
21472
|
-
.
|
|
21473
|
-
.
|
|
21474
|
-
.
|
|
21475
|
-
.
|
|
21476
|
-
.
|
|
21477
|
-
.
|
|
21478
|
-
|
|
21479
|
-
.
|
|
21480
|
-
|
|
21481
|
-
#
|
|
21482
|
-
#
|
|
21483
|
-
.
|
|
21484
|
-
.
|
|
21485
|
-
|
|
21486
|
-
|
|
21487
|
-
#
|
|
21488
|
-
#
|
|
21489
|
-
.
|
|
21490
|
-
.
|
|
21491
|
-
.
|
|
21492
|
-
.
|
|
21493
|
-
|
|
21494
|
-
|
|
21495
|
-
|
|
21496
|
-
.
|
|
21497
|
-
|
|
21498
|
-
|
|
21499
|
-
.
|
|
21500
|
-
.
|
|
21501
|
-
|
|
21502
|
-
|
|
21503
|
-
.
|
|
21504
|
-
|
|
21505
|
-
|
|
21506
|
-
|
|
21507
|
-
|
|
21508
|
-
.
|
|
21509
|
-
|
|
21510
|
-
|
|
21511
|
-
.
|
|
21512
|
-
.
|
|
21513
|
-
.
|
|
21514
|
-
|
|
21515
|
-
.
|
|
21516
|
-
|
|
21517
|
-
|
|
21518
|
-
.
|
|
21519
|
-
|
|
21520
|
-
|
|
21521
|
-
.
|
|
21522
|
-
.cmds { position: relative; }
|
|
21523
|
-
.cmd-pop { display: none; position: absolute; left: 0; bottom: 36px; width: 240px; background: #161616; border: 1px solid var(--line); border-radius: 4px; padding: 6px; z-index: 5; box-shadow: 0 18px 40px rgba(0,0,0,.4); }
|
|
21524
|
-
.cmd-pop.open { display: grid; gap: 2px; }
|
|
21525
|
-
.cmds button, .cmd-pop button { background: transparent; border: 0; color: var(--muted); padding: 7px 8px; border-radius: 2px; font-size: 12px; text-align: left; width: 100%; }
|
|
21526
|
-
.cmds > #cmd-open { width: 32px; height: 32px; padding: 0; border: 0; font-size: 18px; line-height: 1; }
|
|
21527
|
-
.cmds button:hover, .cmd-pop button:hover { background: rgba(255,236,222,.05); color: var(--fg); }
|
|
21528
|
-
.bar-right { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-shrink: 0; }
|
|
21529
|
-
.model-chip { color: var(--muted); font-size: 12px; max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
21530
|
-
#model { max-width: 220px; background: transparent; border: 0; color: var(--muted); font-size: 12px; padding: 4px 0; outline: none; }
|
|
21531
|
-
#model:hover, #model:focus { color: var(--fg); }
|
|
21532
|
-
#send { min-width: 72px; height: 32px; border: 0; border-radius: 2px; background: var(--accent); color: #fff; display: grid; place-items: center; padding: 0 12px; font-size: 12px; font-weight: 650; letter-spacing: .04em; text-transform: uppercase; }
|
|
21533
|
-
#send:hover { transform: translateY(-1px); }
|
|
21534
|
-
#send.steer { background: #3dd68c; }
|
|
21535
|
-
#send:disabled, textarea:disabled { opacity: .4; cursor: not-allowed; }
|
|
21536
|
-
.queue { margin: 0 8px 8px; border: 1px solid var(--line); border-radius: 12px; background: #141414; }
|
|
21537
|
-
.queue[hidden] { display: none; }
|
|
21538
|
-
.queue-item { padding: 10px 12px; color: var(--fg); font-size: 13px; white-space: pre-wrap; border-bottom: 1px solid var(--line); }
|
|
21539
|
-
.queue-bar { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 10px; color: var(--muted); font-size: 12px; }
|
|
21540
|
-
.queue-bar button { border: 0; background: transparent; color: var(--muted); font-size: 12px; padding: 4px 6px; border-radius: 8px; }
|
|
21541
|
-
.queue-bar button:hover { color: var(--fg); background: rgba(255,255,255,.05); }
|
|
21542
|
-
.queue-bar .now { color: var(--fg); }
|
|
21543
|
-
.model-wrap { position: relative; }
|
|
21544
|
-
#model-open { max-width: 220px; background: transparent; border: 1px solid var(--line); border-radius: 2px; color: var(--muted); font-size: 12px; padding: 6px 10px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
21545
|
-
#model-open:hover, #model-open[aria-expanded="true"] { color: var(--fg); border-color: rgba(255,255,255,.2); }
|
|
21546
|
-
#model-menu { display: none; position: absolute; right: 0; bottom: 36px; width: 280px; max-height: 320px; overflow: hidden; background: #161616; border: 1px solid var(--line); border-radius: 14px; box-shadow: 0 18px 40px rgba(0,0,0,.4); z-index: 5; }
|
|
21547
|
-
#model-menu.open { display: grid; grid-template-rows: auto 1fr; }
|
|
21548
|
-
#model-filter { width: 100%; background: #101010; border: 0; border-bottom: 1px solid var(--line); color: var(--fg); padding: 10px 12px; outline: none; font-size: 12px; }
|
|
21549
|
-
#model-list { overflow: auto; max-height: 260px; padding: 6px; }
|
|
21550
|
-
#model-list button { display: block; width: 100%; text-align: left; border: 0; background: transparent; color: var(--muted); padding: 8px 10px; border-radius: 8px; font-size: 12px; }
|
|
21551
|
-
#model-list button:hover, #model-list button.on { background: rgba(255,255,255,.06); color: var(--fg); }
|
|
21552
|
-
.ctx-wrap { position: relative; display: inline-flex; }
|
|
21553
|
-
.ctx { min-width: 52px; height: 28px; padding: 0 8px; border: 1px solid var(--line); background: transparent; color: var(--muted); border-radius: 2px; font: 11px/1 ui-monospace, Menlo, monospace; display: inline-flex; align-items: center; gap: 6px; }
|
|
21554
|
-
.ctx svg { display: block; flex-shrink: 0; }
|
|
21555
|
-
.ctx svg { display: block; }
|
|
21556
|
-
.ctx .track { fill: none; stroke: rgba(255,255,255,.12); stroke-width: 2.4; }
|
|
21557
|
-
.ctx .fill { fill: none; stroke: #ececec; stroke-width: 2.4; stroke-linecap: round; transform: rotate(-90deg); transform-origin: 12px 12px; }
|
|
21558
|
-
#ctx-tip { display: none; position: absolute; right: 0; top: 32px; width: max-content; max-width: 240px; background: #161616; border: 1px solid var(--line); border-radius: 10px; padding: 8px 10px; color: var(--fg); font-size: 12px; z-index: 6; box-shadow: 0 12px 28px rgba(0,0,0,.35); }
|
|
21559
|
-
.ctx-wrap:hover #ctx-tip, .ctx-wrap:focus-within #ctx-tip { display: block; }
|
|
21560
|
-
#model { position: absolute; opacity: 0; pointer-events: none; width: 0; height: 0; }
|
|
21561
|
-
#modal { display: none; position: fixed; inset: 0; background: rgba(0,0,0,.55); align-items: center; justify-content: center; padding: 24px; z-index: 4; }
|
|
21562
|
-
#modal.open { display: flex; }
|
|
21563
|
-
.dialog { width: min(520px, 100%); background: #161616; border: 1px solid var(--line); border-radius: 16px; padding: 18px; }
|
|
21564
|
-
.dialog h3 { margin: 0 0 8px; font-size: 15px; font-weight: 600; }
|
|
21565
|
-
.dialog .purpose { color: var(--muted); font-size: 13px; }
|
|
21566
|
-
.preview { max-height: 240px; overflow: auto; white-space: pre-wrap; word-break: break-word; margin: 12px 0 16px; padding: 12px; background: #101010; border-radius: 10px; font-family: ui-monospace, Menlo, monospace; font-size: 12px; color: var(--muted); }
|
|
21567
|
-
.modal-actions { display: flex; gap: 8px; justify-content: flex-end; flex-wrap: wrap; }
|
|
21568
|
-
.modal-actions button { border: 1px solid var(--line); background: #1c1c1c; border-radius: 10px; padding: 8px 12px; }
|
|
21569
|
-
.modal-actions .deny { color: var(--err); }
|
|
21570
|
-
.modal-actions #always { color: var(--muted); }
|
|
21571
|
-
.modal-actions #approve { background: #ececec; color: #111; border-color: transparent; }
|
|
21572
|
-
.always-row { display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: 12px; padding: 4px 8px 0; }
|
|
21573
|
-
.always-row input { accent-color: #ececec; }
|
|
21574
|
-
@media (max-width: 1100px) {
|
|
21575
|
-
.shell, .shell.rail-off { grid-template-columns: var(--rail-w) 1fr; }
|
|
21576
|
-
.gutter { display: none; }
|
|
21577
|
-
.changes { display: none; }
|
|
21578
|
-
.shell:not(.changes-off) .changes,
|
|
21579
|
-
.changes.open { display: grid; position: fixed; inset: 0 0 0 auto; width: min(400px, 100%); z-index: 3; box-shadow: -16px 0 40px rgba(0,0,0,.45); }
|
|
21580
|
-
}
|
|
21581
|
-
@media (max-width: 720px) {
|
|
21582
|
-
.shell, .shell.rail-off { grid-template-columns: 1fr; }
|
|
21583
|
-
.rail { display: none; }
|
|
21584
|
-
.shell:not(.rail-off) .rail {
|
|
21585
|
-
display: flex; position: fixed; inset: 0 auto 0 0; width: min(280px, 86vw); z-index: 5;
|
|
21586
|
-
box-shadow: 16px 0 40px rgba(0,0,0,.45);
|
|
21587
|
-
}
|
|
21588
|
-
header { padding: 12px 16px 4px; }
|
|
21589
|
-
.dock { padding: 0 12px calc(16px + env(safe-area-inset-bottom)); }
|
|
21590
|
-
.bar { flex-wrap: wrap; }
|
|
21591
|
-
.bar-right { margin-left: 0; width: 100%; justify-content: flex-end; }
|
|
21592
|
-
.composer-foot { flex-wrap: wrap; }
|
|
21593
|
-
.composer-actions { flex-wrap: wrap; }
|
|
21594
|
-
body.remote .composer textarea { min-height: 88px; font-size: 16px; }
|
|
21595
|
-
body.remote #send { min-width: 88px; height: 40px; }
|
|
21596
|
-
}
|
|
21597
|
-
.composer {
|
|
21598
|
-
position: relative;
|
|
21599
|
-
max-width: 780px;
|
|
21600
|
-
padding: 6px;
|
|
21601
|
-
border-radius: 16px;
|
|
21602
|
-
background:
|
|
21603
|
-
linear-gradient(180deg, rgba(255,236,222,.04), transparent 28%),
|
|
21604
|
-
var(--panel);
|
|
21605
|
-
border: 1px solid rgba(255,236,222,.12);
|
|
21606
|
-
box-shadow: 0 18px 40px rgba(0,0,0,.28), inset 0 1px 0 rgba(255,236,222,.06);
|
|
21607
|
-
}
|
|
21608
|
-
.composer textarea { min-height: 44px; max-height: 180px; padding: 10px 8px; font-size: 14px; }
|
|
21609
|
-
.composer textarea::placeholder { color: #7c746a; }
|
|
21610
|
-
.composer-line { display: flex; align-items: flex-end; gap: 6px; }
|
|
21611
|
-
.composer-line textarea { flex: 1; min-width: 0; }
|
|
21612
|
-
.plus-btn, .mic-btn {
|
|
21613
|
-
width: 32px; height: 32px; flex-shrink: 0; border: 0; border-radius: 999px;
|
|
21614
|
-
background: transparent; color: var(--muted); display: grid; place-items: center;
|
|
21615
|
-
}
|
|
21616
|
-
.plus-btn:hover, .mic-btn:hover, .mic-btn.on { color: var(--fg); background: rgba(255,236,222,.06); }
|
|
21617
|
-
.composer-foot { display: flex; align-items: center; gap: 8px; padding: 2px 4px 2px; }
|
|
21618
|
-
.branch-wrap { position: relative; }
|
|
21619
|
-
.branch-menu { display: none; position: absolute; left: 0; bottom: 34px; min-width: 200px; max-height: 240px; overflow: auto; background: #171614; border: 1px solid var(--line); border-radius: 12px; padding: 6px; z-index: 8; }
|
|
21620
|
-
.host-chip { color: var(--faint); font-size: 12px; display: inline-flex; align-items: center; gap: 6px; }
|
|
21621
|
-
.composer-foot .bar-right { margin-left: auto; }
|
|
21622
|
-
#file-view { white-space: pre-wrap; font: 12px ui-monospace, Menlo, monospace; padding: 12px; color: var(--muted); overflow: auto; min-height: 0; }
|
|
21623
|
-
#preview { width: 100%; min-height: 0; height: 100%; border: 0; background: #fff; }
|
|
21624
|
-
.pick { position: relative; }
|
|
21625
|
-
.pick-open, #model-open, #thinking-open {
|
|
21626
|
-
display: inline-flex; align-items: center; gap: 7px;
|
|
21627
|
-
max-width: 220px; height: 30px; padding: 0 10px;
|
|
21628
|
-
background: rgba(255,236,222,.03); border: 1px solid var(--line); border-radius: 8px;
|
|
21629
|
-
color: var(--muted); font-size: 12px; white-space: nowrap; overflow: hidden;
|
|
21630
|
-
}
|
|
21631
|
-
.pick-open:hover, #model-open:hover, #thinking-open:hover,
|
|
21632
|
-
.pick-open[aria-expanded="true"], #model-open[aria-expanded="true"], #thinking-open[aria-expanded="true"] {
|
|
21633
|
-
color: var(--fg); border-color: rgba(255,236,222,.22); background: rgba(255,236,222,.06);
|
|
21634
|
-
}
|
|
21635
|
-
.pick-open .caret, #model-open .caret, #thinking-open .caret { opacity: .45; margin-left: 2px; }
|
|
21636
|
-
.model-ico { display: block; flex-shrink: 0; border-radius: 4px; }
|
|
21637
|
-
#model-open { max-width: 240px; }
|
|
21638
|
-
.pick-menu, #model-menu, #mention {
|
|
21639
|
-
display: none; position: absolute; z-index: 8;
|
|
21640
|
-
min-width: 220px; max-height: 320px; overflow: hidden;
|
|
21641
|
-
background: #171614; border: 1px solid rgba(255,236,222,.14); border-radius: 12px;
|
|
21642
|
-
box-shadow: 0 22px 50px rgba(0,0,0,.45);
|
|
21643
|
-
}
|
|
21644
|
-
.pick-menu.open, #model-menu.open, #mention.open { display: grid; }
|
|
21645
|
-
.pick-menu { right: 0; bottom: 36px; padding: 6px; }
|
|
21646
|
-
#model-menu { right: 0; bottom: 36px; width: 300px; grid-template-rows: auto 1fr; }
|
|
21647
|
-
#mention {
|
|
21648
|
-
left: 12px; bottom: calc(100% - 8px); width: min(480px, calc(100% - 24px));
|
|
21649
|
-
}
|
|
21650
|
-
.term .pick-menu { bottom: auto; top: 28px; }
|
|
21651
|
-
.pick-menu button, #model-list button, #mention-list button {
|
|
21652
|
-
display: flex; align-items: center; gap: 8px; width: 100%;
|
|
21653
|
-
text-align: left; border: 0; background: transparent; color: var(--muted);
|
|
21654
|
-
padding: 8px 10px; border-radius: 8px; font-size: 12px;
|
|
21655
|
-
}
|
|
21656
|
-
.pick-menu button:hover, .pick-menu button.on,
|
|
21657
|
-
#model-list button:hover, #model-list button.on,
|
|
21658
|
-
#mention-list button:hover, #mention-list button.on {
|
|
21659
|
-
background: rgba(255,236,222,.06); color: var(--fg);
|
|
21660
|
-
}
|
|
21661
|
-
.pick-menu button .meta, #mention-list button .meta { margin-left: auto; color: var(--faint); font-size: 11px; }
|
|
21662
|
-
#model-filter {
|
|
21663
|
-
width: 100%; background: #12110f; border: 0; border-bottom: 1px solid var(--line);
|
|
21664
|
-
color: var(--fg); padding: 10px 12px; outline: none; font-size: 12px;
|
|
21665
|
-
}
|
|
21666
|
-
#model-list, #mention-list { overflow: auto; max-height: 260px; padding: 6px; }
|
|
21667
|
-
.mention-k { font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--faint); padding: 8px 10px 4px; }
|
|
21668
|
-
#send {
|
|
21669
|
-
min-width: 72px; height: 32px; border: 0; border-radius: 8px;
|
|
21670
|
-
background: var(--accent); color: #fff; display: grid; place-items: center;
|
|
21671
|
-
padding: 0 14px; font-size: 12px; font-weight: 650; letter-spacing: .04em; text-transform: uppercase;
|
|
21672
|
-
}
|
|
21673
|
-
#send:hover { transform: translateY(-1px); }
|
|
21674
|
-
#send.steer { background: var(--live); color: #102016; }
|
|
21675
|
-
#send:disabled, textarea:disabled { opacity: .4; cursor: not-allowed; }
|
|
21676
|
-
#mode, #autonomy, #model, #thinking, #review-depth, #review-lens, #term-timeout, #studio-author, #studio-review, #key-kind {
|
|
21677
|
-
position: absolute; opacity: 0; pointer-events: none; width: 0; height: 0;
|
|
21678
|
-
}
|
|
21679
|
-
.sheet .pick-menu { bottom: auto; top: 32px; left: 0; right: auto; }
|
|
21680
|
-
.bar { gap: 6px; }
|
|
21681
|
-
.bar-right { display: flex; align-items: center; gap: 6px; margin-left: auto; flex-shrink: 0; flex-wrap: wrap; justify-content: flex-end; }
|
|
21682
|
-
.chip { display: inline-flex; align-items: center; gap: 6px; }
|
|
21683
|
-
.prompt { border-radius: 14px; background: var(--prompt); }
|
|
21684
|
-
.reply { color: #e8e2d8; }
|
|
21685
|
-
#empty h1 { color: #8a8378; font-weight: 500; }
|
|
21686
|
-
.rail .plus, .diff-actions button, .workspace button {
|
|
21687
|
-
transition: border-color .2s var(--ease), color .2s var(--ease), background .2s var(--ease);
|
|
21688
|
-
}
|
|
21321
|
+
--bg:#0f0f0e;
|
|
21322
|
+
--rail:#141412;
|
|
21323
|
+
--surface:#181816;
|
|
21324
|
+
--surface-2:#1d1c19;
|
|
21325
|
+
--surface-3:#23211e;
|
|
21326
|
+
--hover:rgba(255,255,255,.055);
|
|
21327
|
+
--line:rgba(255,244,232,.09);
|
|
21328
|
+
--line-strong:rgba(255,244,232,.16);
|
|
21329
|
+
--fg:#f3eee6;
|
|
21330
|
+
--muted:#aaa197;
|
|
21331
|
+
--faint:#736d65;
|
|
21332
|
+
--green:#55d88c;
|
|
21333
|
+
--amber:#e0aa43;
|
|
21334
|
+
--red:#ef7770;
|
|
21335
|
+
--blue:#8fb7ff;
|
|
21336
|
+
--brand:#e72b2b;
|
|
21337
|
+
--primary:#f1ece4;
|
|
21338
|
+
--primary-fg:#171613;
|
|
21339
|
+
--shadow:0 24px 80px rgba(0,0,0,.48);
|
|
21340
|
+
--ease:cubic-bezier(.2,.8,.2,1);
|
|
21341
|
+
--rail-w:252px;
|
|
21342
|
+
--changes-w:390px;
|
|
21343
|
+
--top-h:48px;
|
|
21344
|
+
}
|
|
21345
|
+
html[data-theme="light"]{
|
|
21346
|
+
--bg:#f6f4ef;
|
|
21347
|
+
--rail:#eeeae3;
|
|
21348
|
+
--surface:#fff;
|
|
21349
|
+
--surface-2:#f3f0ea;
|
|
21350
|
+
--surface-3:#e9e4dc;
|
|
21351
|
+
--hover:rgba(0,0,0,.045);
|
|
21352
|
+
--line:rgba(20,18,14,.1);
|
|
21353
|
+
--line-strong:rgba(20,18,14,.16);
|
|
21354
|
+
--fg:#1a1814;
|
|
21355
|
+
--muted:#5f5a52;
|
|
21356
|
+
--faint:#8a837a;
|
|
21357
|
+
--primary:#1a1814;
|
|
21358
|
+
--primary-fg:#f6f4ef;
|
|
21359
|
+
--shadow:0 24px 80px rgba(0,0,0,.12);
|
|
21360
|
+
}
|
|
21361
|
+
*{box-sizing:border-box}
|
|
21362
|
+
[hidden]{display:none!important}
|
|
21363
|
+
html,body{margin:0;width:100%;height:100%;height:100dvh;overflow:hidden;background:var(--bg);color:var(--fg);font-family:"IBM Plex Sans","Helvetica Neue",ui-sans-serif,system-ui,sans-serif;font-size:14px;letter-spacing:-.015em}
|
|
21364
|
+
button,input,textarea,select{font:inherit;color:inherit}
|
|
21365
|
+
button{cursor:pointer}
|
|
21366
|
+
button:focus-visible,input:focus-visible,textarea:focus-visible{outline:2px solid rgba(143,183,255,.75);outline-offset:2px}
|
|
21367
|
+
.shell{display:grid;grid-template-columns:var(--rail-w) minmax(0,1fr) 1px var(--changes-w);height:100dvh;overflow:hidden}
|
|
21368
|
+
.shell.rail-off{--rail-w:0px}
|
|
21369
|
+
.shell.rail-off .rail{display:none}
|
|
21370
|
+
.shell.changes-off{--changes-w:0px}
|
|
21371
|
+
.shell.changes-off .gutter,.shell.changes-off .changes{display:none}
|
|
21372
|
+
.shell.term-off .term{display:none}
|
|
21373
|
+
.gutter{background:var(--line);cursor:col-resize}
|
|
21374
|
+
|
|
21375
|
+
/* sidebar */
|
|
21376
|
+
.rail{min-width:0;background:var(--rail);border-right:1px solid var(--line);padding:10px 9px 9px;display:flex;flex-direction:column;gap:9px;overflow:hidden}
|
|
21377
|
+
.rail-top{height:34px;display:flex;align-items:center;justify-content:space-between;padding:0 4px}
|
|
21378
|
+
.brand{display:inline-flex;align-items:center;gap:9px;color:var(--fg);font-weight:650;font-size:13px;min-width:0}
|
|
21379
|
+
.mark{width:26px;height:26px;border-radius:7px;background:var(--brand);display:grid;place-items:center;color:#fff;font:700 11px ui-monospace,Menlo,monospace;box-shadow:inset 0 1px 0 rgba(255,255,255,.12)}
|
|
21380
|
+
.brand span:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
21381
|
+
.rail .plus{height:36px;width:100%;border:1px solid var(--line);background:transparent;color:var(--fg);border-radius:9px;display:flex;align-items:center;justify-content:flex-start;gap:9px;padding:0 10px;font-size:12.5px;transition:.16s var(--ease)}
|
|
21382
|
+
.rail .plus:hover{background:var(--hover);border-color:var(--line-strong)}
|
|
21383
|
+
.rail-search{position:relative}
|
|
21384
|
+
.rail-search svg{position:absolute;left:10px;top:9px;color:var(--faint);pointer-events:none}
|
|
21385
|
+
.rail .search{width:100%;height:34px;background:transparent;border:1px solid transparent;border-radius:8px;padding:0 10px 0 31px;color:var(--fg);outline:0;font-size:12px}
|
|
21386
|
+
.rail .search:focus{border-color:var(--line);background:rgba(255,255,255,.025)}
|
|
21387
|
+
#sessions{display:flex;flex-direction:column;gap:2px;min-height:0;overflow:auto;overscroll-behavior:contain;padding-right:1px;flex:1}
|
|
21388
|
+
.session-row{display:grid;grid-template-columns:minmax(0,1fr) 28px;gap:2px;align-items:center;border-radius:8px}
|
|
21389
|
+
.session-row:hover,.session-row.on{background:var(--hover)}
|
|
21390
|
+
.session-item{width:100%;min-width:0;text-align:left;border:0;background:transparent;color:var(--muted);padding:8px 9px;border-radius:8px;font-size:12.5px;line-height:1.35;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
21391
|
+
.session-row.on .session-item{color:var(--fg)}
|
|
21392
|
+
.session-delete{width:26px;height:26px;border:0;background:transparent;color:transparent;border-radius:7px;display:grid;place-items:center}
|
|
21393
|
+
.session-row:hover .session-delete{color:var(--faint)}
|
|
21394
|
+
.session-delete:hover{background:rgba(239,119,112,.1)!important;color:var(--red)!important}
|
|
21395
|
+
.rail-footer{border-top:1px solid var(--line);padding-top:8px;display:grid;gap:5px}
|
|
21396
|
+
.rail-footer button{height:34px;border:0;background:transparent;color:var(--muted);border-radius:8px;text-align:left;padding:0 9px;display:flex;align-items:center;gap:9px;font-size:12px}
|
|
21397
|
+
.rail-footer button:hover{background:var(--hover);color:var(--fg)}
|
|
21398
|
+
.repo-mini{padding:4px 9px;color:var(--faint);font:10.5px ui-monospace,Menlo,monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
21399
|
+
|
|
21400
|
+
/* main */
|
|
21401
|
+
.stage{display:grid;grid-template-rows:var(--top-h) minmax(0,1fr) auto auto;min-width:0;min-height:0;height:100dvh;overflow:hidden;background:var(--bg)}
|
|
21402
|
+
.topbar{height:var(--top-h);display:flex;align-items:center;gap:10px;padding:0 14px;border-bottom:1px solid var(--line);background:rgba(15,15,14,.86);backdrop-filter:blur(16px);z-index:2}
|
|
21403
|
+
.topbar-left{display:flex;align-items:center;gap:9px;min-width:0;flex:1}
|
|
21404
|
+
.session-title{min-width:0;font-size:12.5px;font-weight:600;color:var(--fg);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
21405
|
+
.top-actions{display:flex;align-items:center;gap:5px;min-width:0}
|
|
21406
|
+
.icon-btn,.toolbar-btn{border:1px solid transparent;background:transparent;color:var(--muted);border-radius:8px;display:inline-flex;align-items:center;justify-content:center;gap:7px;height:30px;padding:0 8px;font-size:11.5px;white-space:nowrap}
|
|
21407
|
+
.icon-btn{width:30px;padding:0}
|
|
21408
|
+
.icon-btn:hover,.toolbar-btn:hover,.icon-btn.on,.toolbar-btn.on{background:var(--hover);color:var(--fg);border-color:var(--line)}
|
|
21409
|
+
.toolbar-btn .count{min-width:18px;height:18px;padding:0 5px;border-radius:999px;background:rgba(255,255,255,.07);display:inline-grid;place-items:center;color:var(--fg);font:10px ui-monospace,Menlo,monospace}
|
|
21410
|
+
.top-status,.badge{max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--faint);font-size:11px}
|
|
21411
|
+
.badge.err{color:var(--red)}
|
|
21412
|
+
#stop{color:var(--red);background:rgba(239,119,112,.08)}
|
|
21413
|
+
main{min-height:0;overflow:auto;overscroll-behavior:contain;scrollbar-gutter:stable}
|
|
21414
|
+
#empty{max-width:700px;margin:17vh auto 0;padding:0 28px 44px}
|
|
21415
|
+
#empty h1{margin:0 0 10px;font-size:27px;line-height:1.2;font-weight:520;letter-spacing:-.04em;color:var(--fg)}
|
|
21416
|
+
#empty p{margin:0;color:var(--muted);font-size:13px;line-height:1.6;max-width:540px}
|
|
21417
|
+
.empty-actions{display:flex;flex-wrap:wrap;gap:7px;margin-top:22px}
|
|
21418
|
+
.empty-actions button{height:32px;border:1px solid var(--line);background:transparent;border-radius:8px;color:var(--muted);padding:0 10px;font-size:11.5px}
|
|
21419
|
+
.empty-actions button:hover{background:var(--hover);color:var(--fg)}
|
|
21420
|
+
#feed{display:none;max-width:780px;margin:0 auto;padding:30px 28px 38px}
|
|
21421
|
+
#feed.on{display:block}
|
|
21422
|
+
.turn{margin:0 0 34px;position:relative}
|
|
21423
|
+
.prompt{max-width:82%;margin:0 0 18px auto;background:var(--surface-2);border:1px solid var(--line);border-radius:16px 16px 5px 16px;padding:11px 14px;line-height:1.5;white-space:pre-wrap;word-break:break-word;color:var(--fg);font-size:13.5px}
|
|
21424
|
+
.reply{margin:0;color:#e9e3da;font-size:14px;line-height:1.63;word-break:break-word}
|
|
21425
|
+
.reply>*:first-child{margin-top:0}.reply>*:last-child{margin-bottom:0}
|
|
21426
|
+
.reply h1,.reply h2,.reply h3,.reply h4{color:var(--fg);font-weight:620;letter-spacing:-.03em;line-height:1.3;margin:20px 0 9px}
|
|
21427
|
+
.reply h1{font-size:19px}.reply h2{font-size:16.5px}.reply h3{font-size:14.5px}.reply h4{font-size:13.5px;color:#ddd6cc}
|
|
21428
|
+
.reply p{margin:0 0 11px}.reply ul,.reply ol{margin:0 0 12px;padding-left:1.25em}.reply li{margin:0 0 4px}.reply li::marker{color:var(--faint)}
|
|
21429
|
+
.reply a{color:#a9c8ff;text-decoration:none}.reply a:hover{text-decoration:underline}
|
|
21430
|
+
.reply code{font:12px ui-monospace,Menlo,monospace;background:rgba(255,255,255,.055);border:1px solid var(--line);border-radius:5px;padding:1px 5px}
|
|
21431
|
+
.reply blockquote{margin:0 0 12px;padding:7px 11px;border-left:2px solid var(--line-strong);color:var(--muted);background:rgba(255,255,255,.02)}
|
|
21432
|
+
.reply hr{border:0;border-top:1px solid var(--line);margin:16px 0}
|
|
21433
|
+
.md-code{position:relative;background:#11110f;border:1px solid var(--line);border-radius:10px;padding:30px 12px 12px;overflow:auto;font:12px ui-monospace,Menlo,monospace;line-height:1.55}
|
|
21434
|
+
.md-code .copy{position:absolute;right:7px;top:7px;border:1px solid var(--line);background:var(--surface);color:var(--muted);border-radius:6px;padding:3px 7px;font-size:10.5px}
|
|
21435
|
+
.reply .md-code code{background:none;border:0;padding:0}
|
|
21436
|
+
.md-table{margin:10px 0 14px;overflow:auto;border:1px solid var(--line);border-radius:10px;background:#121210}
|
|
21437
|
+
.reply table{width:100%;border-collapse:collapse;font-size:12.5px}.reply th,.reply td{padding:8px 10px;text-align:left;vertical-align:top;border-bottom:1px solid var(--line)}.reply th{color:var(--muted);font-weight:600;font-size:11px;background:rgba(255,255,255,.025)}.reply tr:last-child td{border-bottom:0}
|
|
21438
|
+
|
|
21439
|
+
/* activity: each tool is its own row */
|
|
21440
|
+
.activity{display:grid;gap:5px;margin:9px 0 13px}
|
|
21441
|
+
.tool-event,.think{margin:0;border:0;background:transparent;color:var(--muted);font-size:11.5px}
|
|
21442
|
+
.tool-event summary,.think summary{list-style:none;display:flex;align-items:center;gap:8px;min-height:28px;width:max-content;max-width:100%;padding:4px 7px;border-radius:7px;cursor:pointer;user-select:none}
|
|
21443
|
+
.tool-event summary::-webkit-details-marker,.think summary::-webkit-details-marker{display:none}
|
|
21444
|
+
.tool-event summary:hover,.think summary:hover{background:var(--hover);color:var(--fg)}
|
|
21445
|
+
.tool-dot{width:7px;height:7px;border-radius:999px;background:var(--faint);flex:0 0 auto}
|
|
21446
|
+
.tool-event.running .tool-dot{background:var(--amber);box-shadow:0 0 0 3px rgba(224,170,67,.08)}
|
|
21447
|
+
.tool-event.done .tool-dot{background:var(--green)}
|
|
21448
|
+
.tool-event.failed .tool-dot{background:var(--red)}
|
|
21449
|
+
.tool-name{font-family:ui-monospace,Menlo,monospace;color:#c5bdb1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
21450
|
+
.tool-phase{color:var(--faint)}
|
|
21451
|
+
.tool-detail{margin:2px 0 4px 21px;max-width:min(680px,calc(100vw - 64px));padding:9px 10px;border-left:1px solid var(--line);color:#918a81;white-space:pre-wrap;word-break:break-word;font:11px/1.5 ui-monospace,Menlo,monospace}
|
|
21452
|
+
.think{margin:6px 0;color:var(--faint)}
|
|
21453
|
+
.think>div{margin:2px 0 4px 21px;padding-left:10px;border-left:1px solid var(--line);white-space:pre-wrap;word-break:break-word;font-size:11.5px;line-height:1.5;color:#858078}
|
|
21454
|
+
.note,.alert,.review-card{margin:10px 0;padding:8px 10px;border-radius:8px;line-height:1.5;word-break:break-word;font-size:12px}
|
|
21455
|
+
.note{padding:5px 2px;background:transparent;border:0;color:var(--faint);font-family:ui-monospace,Menlo,monospace}
|
|
21456
|
+
.alert{background:rgba(239,119,112,.07);border:1px solid rgba(239,119,112,.18);color:#f0b8b4}
|
|
21457
|
+
.review-card{background:rgba(85,216,140,.045);border:1px solid rgba(85,216,140,.18);color:#d8e7dd}
|
|
21458
|
+
.trust{display:none}
|
|
21459
|
+
.agent{margin:6px 0;padding:7px 9px;border-left:1px solid var(--line);color:var(--muted);font-size:11.5px}.agent.running{border-left-color:var(--amber)}.agent b{color:var(--fg);font-weight:560}
|
|
21460
|
+
|
|
21461
|
+
/* composer */
|
|
21462
|
+
.dock{padding:8px 18px 14px;background:linear-gradient(180deg,transparent,rgba(15,15,14,.96) 18%)}
|
|
21463
|
+
.composer{position:relative;max-width:800px;margin:0 auto;background:var(--surface);border:1px solid var(--line-strong);border-radius:17px;padding:6px;box-shadow:0 16px 42px rgba(0,0,0,.25),inset 0 1px 0 rgba(255,255,255,.035)}
|
|
21464
|
+
.composer-line{display:flex;align-items:flex-end;gap:5px}
|
|
21465
|
+
.composer-line textarea{flex:1;min-width:0;width:100%;min-height:44px;max-height:190px;resize:none;background:transparent;border:0;padding:9px 7px;outline:0;line-height:1.5;font-size:14px;color:var(--fg)}
|
|
21466
|
+
.composer-line textarea::placeholder{color:#716b63}
|
|
21467
|
+
.round-btn,.plus-btn,.mic-btn{width:32px;height:32px;flex:0 0 auto;border:0;border-radius:9px;background:transparent;color:var(--muted);display:grid;place-items:center}
|
|
21468
|
+
.round-btn:hover,.plus-btn:hover,.mic-btn:hover,.mic-btn.on{background:var(--hover);color:var(--fg)}
|
|
21469
|
+
.composer-foot{display:flex;align-items:center;gap:6px;padding:3px 3px 1px;min-height:36px}
|
|
21470
|
+
.composer-left,.composer-right{display:flex;align-items:center;gap:5px;min-width:0}.composer-right{margin-left:auto;flex:0 0 auto}
|
|
21471
|
+
.pick{position:relative}
|
|
21472
|
+
.pick-open,#model-open{height:30px;max-width:190px;display:inline-flex;align-items:center;gap:7px;padding:0 9px;border:1px solid transparent;border-radius:8px;background:transparent;color:var(--muted);font-size:11.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
21473
|
+
.pick-open:hover,#model-open:hover,.pick-open[aria-expanded="true"],#model-open[aria-expanded="true"]{background:var(--hover);border-color:var(--line);color:var(--fg)}
|
|
21474
|
+
.pick-open .caret,#model-open .caret{opacity:.45;font-size:9px}
|
|
21475
|
+
.model-ico{width:15px!important;height:15px!important;display:block;flex:0 0 auto;border-radius:4px}
|
|
21476
|
+
.model-fallback{width:15px;height:15px;display:inline-grid;place-items:center;border-radius:4px;background:rgba(255,255,255,.08);color:var(--fg);font:700 8px ui-monospace,Menlo,monospace;flex:0 0 auto}
|
|
21477
|
+
.pick-menu,#model-menu,#mention,.cmd-pop,.branch-menu,.ship-menu{display:none;position:absolute;z-index:20;background:#171715;border:1px solid var(--line-strong);border-radius:12px;box-shadow:var(--shadow);overflow:hidden}
|
|
21478
|
+
.pick-menu.open,#model-menu.open,#mention.open,.cmd-pop.open,.branch-menu.open,.ship-menu.open{display:grid}
|
|
21479
|
+
.pick-menu{bottom:36px;left:0;min-width:210px;max-height:300px;overflow:auto;overscroll-behavior:contain;padding:5px}
|
|
21480
|
+
#model-menu{right:0;bottom:36px;width:310px;max-height:360px;grid-template-rows:auto minmax(0,1fr);overscroll-behavior:contain}
|
|
21481
|
+
#model-filter{width:100%;height:39px;background:#121211;border:0;border-bottom:1px solid var(--line);padding:0 11px;outline:0;font-size:12px}
|
|
21482
|
+
#model-list{overflow:auto;overscroll-behavior:contain;max-height:310px;padding:5px}
|
|
21483
|
+
.pick-menu button,#model-list button,#mention-list button{width:100%;min-height:34px;border:0;background:transparent;color:var(--muted);border-radius:8px;padding:7px 9px;text-align:left;display:flex;align-items:center;gap:8px;font-size:11.5px}
|
|
21484
|
+
.pick-menu button:hover,.pick-menu button.on,#model-list button:hover,#model-list button.on,#mention-list button:hover,#mention-list button.on{background:var(--hover);color:var(--fg)}
|
|
21485
|
+
#model{position:absolute;opacity:0;pointer-events:none;width:0;height:0}
|
|
21486
|
+
#send{width:34px;height:34px;border:0;border-radius:10px;background:var(--primary);color:var(--primary-fg);display:grid;place-items:center;padding:0;transition:.14s var(--ease)}
|
|
21487
|
+
#send:hover{transform:translateY(-1px);filter:brightness(1.04)}#send.steer{background:#bfe8cf;color:#142219}#send:disabled{opacity:.45;cursor:not-allowed}
|
|
21488
|
+
#review-run{height:30px;padding:0 10px;border:1px solid var(--line);border-radius:8px;background:transparent;color:var(--muted);font-size:11.5px}#review-run:hover{background:var(--hover);color:var(--fg)}
|
|
21489
|
+
.autonomy-pill.auto{color:var(--amber);border-color:rgba(224,170,67,.24);background:rgba(224,170,67,.055)}
|
|
21490
|
+
.chips{display:flex;flex-wrap:wrap;gap:4px;padding:0 7px 4px}.chip{display:inline-flex;align-items:center;gap:5px;border-radius:7px;background:rgba(255,255,255,.055);padding:3px 7px;color:var(--muted);font-size:10.5px;cursor:pointer}
|
|
21491
|
+
.queue{margin:2px 5px 6px;border:1px solid var(--line);border-radius:10px;background:#141412}.queue-item{padding:8px 10px;color:var(--fg);font-size:12px;white-space:pre-wrap;border-bottom:1px solid var(--line)}.queue-item button{float:right;border:0;background:transparent;color:var(--faint);font-size:10px}.queue-bar{display:flex;align-items:center;justify-content:space-between;padding:6px 9px;color:var(--muted);font-size:10.5px}.queue-bar button{border:0;background:transparent;color:var(--muted);font-size:10.5px}.queue-bar .now{color:var(--fg)}
|
|
21492
|
+
.cmds{position:relative}.cmd-pop{left:0;bottom:38px;width:220px;padding:5px}.cmd-pop button{height:34px;border:0;background:transparent;color:var(--muted);border-radius:8px;padding:0 9px;text-align:left;font-size:11.5px}.cmd-pop button:hover{background:var(--hover);color:var(--fg)}
|
|
21493
|
+
#mention{left:8px;bottom:calc(100% - 4px);width:min(500px,calc(100% - 16px));max-height:330px}#mention-list{overflow:auto;overscroll-behavior:contain;padding:5px}.mention-k{font-size:9px;letter-spacing:.08em;text-transform:uppercase;color:var(--faint);padding:7px 9px 3px}.pick-menu button .meta,#mention-list button .meta{margin-left:auto;color:var(--faint);font-size:10px}
|
|
21494
|
+
|
|
21495
|
+
/* terminal */
|
|
21496
|
+
.term{border-top:1px solid var(--line);background:#0d0d0c;display:grid;grid-template-rows:auto minmax(70px,1fr) auto;max-height:220px}.term header{height:32px;display:flex;align-items:center;justify-content:space-between;padding:0 10px;color:var(--faint);font-size:10.5px}.term header>span{display:flex;align-items:center;gap:6px}.term pre{margin:0;padding:8px 11px;overflow:auto;overscroll-behavior:contain;font:11px/1.5 ui-monospace,Menlo,monospace;color:#bbb4aa}.term form{display:flex;padding:5px 8px 8px}.term input{flex:1;height:31px;background:#141412;border:1px solid var(--line);border-radius:7px;padding:0 9px;outline:0;font:11px ui-monospace,Menlo,monospace}.term button{border:0;background:transparent;color:var(--muted);font-size:10.5px}.term .pick-menu{bottom:auto;top:30px}.always-row{display:flex;align-items:center;gap:7px;color:var(--muted);font-size:11px}.always-row input{accent-color:var(--amber)}
|
|
21497
|
+
|
|
21498
|
+
/* workspace */
|
|
21499
|
+
.changes{min-width:0;min-height:0;height:100dvh;background:var(--rail);border-left:1px solid var(--line);display:grid;grid-template-rows:auto auto minmax(0,1fr);overflow:hidden}.changes>header{padding:11px 10px 8px;display:grid;grid-template-columns:minmax(0,1fr) auto;gap:3px 8px;align-items:center}.changes h2{margin:0;font-size:12.5px;font-weight:620}.changes .sum{grid-column:1/-1;color:var(--faint);font:10.5px ui-monospace,Menlo,monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.work-tabs{display:flex;gap:2px;padding:0 7px 7px;border-bottom:1px solid var(--line)}.work-tabs button{height:27px;border:0;background:transparent;color:var(--muted);font-size:10.5px;border-radius:7px;padding:0 8px}.work-tabs button.on{background:var(--hover);color:var(--fg)}.work-stack{min-height:0;overflow:hidden;display:grid}.work-stack>*{min-height:0;height:100%}.workspace{min-height:0;padding:7px;display:grid;gap:6px;overflow:hidden}.workspace input{width:100%;height:32px;background:#121211;border:1px solid var(--line);border-radius:8px;padding:0 9px;outline:0;font-size:11px}.tree{min-height:0;overflow:auto;overscroll-behavior:contain;font:11px ui-monospace,Menlo,monospace}.tree button{width:100%;min-height:27px;border:0;background:transparent;color:var(--muted);border-radius:6px;text-align:left;display:flex;align-items:center;gap:6px;padding:4px 6px}.tree button:hover,.tree button.on{background:var(--hover);color:var(--fg)}.tree .twist{width:9px;flex:0 0 auto;opacity:.55;font-size:8px}.tree .kind-untracked,.tree .kind-added{color:#83d7a4}.tree .kind-modified{color:#e6c36a}.tree .kind-deleted{color:var(--red);text-decoration:line-through}.tree .kind-renamed{color:var(--blue)}
|
|
21500
|
+
#tab-tree{grid-template-rows:auto minmax(110px,.8fr) auto minmax(180px,1.25fr)}#tab-findings,#tab-timeline{grid-template-rows:auto minmax(0,1fr)}.diff-head{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:7px;align-items:center;padding:5px 2px}.diff-title-wrap{min-width:0;display:flex;align-items:center;gap:8px}.diff-back{flex:0 0 auto;border:0;background:transparent;color:var(--muted);padding:3px 5px;border-radius:6px;font-size:10.5px}.diff-back:hover{color:var(--fg);background:var(--hover)}.diff-head b,#diff-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:10.5px ui-monospace,Menlo,monospace;color:var(--fg)}.diff-actions{display:flex;gap:4px}.diff-actions button{height:27px;border:1px solid var(--line);background:transparent;border-radius:7px;padding:0 7px;color:var(--muted);font-size:10px}.diff-actions button:hover{background:var(--hover);color:var(--fg)}.diff-actions .danger{color:var(--red)}.diff{min-height:0;overflow:auto;overscroll-behavior:contain;padding-bottom:14px;border:1px solid var(--line);border-radius:8px;background:#10100f;font:11px/1.5 ui-monospace,Menlo,monospace}.diff-file+.diff-file{border-top:1px solid var(--line-strong);margin-top:10px;padding-top:5px}.diff-file-head{position:sticky;top:0;z-index:2;padding:8px 10px;background:#151513;border-bottom:1px solid var(--line);color:var(--fg);font:600 11px ui-monospace,Menlo,monospace}.diff-loading{padding:14px;color:var(--faint);font-size:11px}.diff .hunk{color:var(--faint);padding:6px 8px 3px;background:rgba(255,255,255,.02)}.diff .row{display:grid;grid-template-columns:36px 36px minmax(0,1fr)}.diff .ln{color:#5e5953;text-align:right;padding:0 6px;user-select:none}.diff .add{background:rgba(85,216,140,.08);color:#bae7ca}.diff .del{background:rgba(239,119,112,.09);color:#efc3c0}.diff .ctx{color:#aaa39a}.diff .code{white-space:pre-wrap;word-break:break-word;padding-right:7px}#file-view{margin:0;white-space:pre-wrap;font:11px/1.5 ui-monospace,Menlo,monospace;padding:10px;color:var(--muted);overflow:auto;border:1px solid var(--line);border-radius:8px;background:#10100f}#preview{width:100%;height:100%;min-height:0;border:0;background:#fff;border-radius:8px}.compare{display:grid;grid-template-columns:1fr 1fr;gap:7px;padding:8px;font:11px ui-monospace,Menlo,monospace;overflow:auto}.find-row{width:100%;text-align:left;border:0;background:transparent;color:var(--muted);padding:7px;border-radius:7px;font-size:11px}.find-row:hover{background:var(--hover);color:var(--fg)}.change-list{display:none}.gate{display:none}
|
|
21501
|
+
|
|
21502
|
+
/* overlays */
|
|
21503
|
+
.sheet{display:none;position:fixed;inset:0;z-index:50;background:rgba(0,0,0,.55);align-items:center;justify-content:center;padding:20px;backdrop-filter:blur(4px)}.sheet.open{display:flex}.sheet .card{width:min(640px,95vw);max-height:84vh;overflow:auto;overscroll-behavior:contain;background:#161614;border:1px solid var(--line-strong);border-radius:14px;padding:16px;box-shadow:var(--shadow)}.sheet h3{margin:0 0 12px;font-size:15px}.sheet label{display:block;color:var(--muted);font-size:11px;margin:9px 0 4px}.sheet input,.sheet select,.sheet textarea.plain{width:100%;background:#11110f;border:1px solid var(--line);border-radius:8px;padding:8px;outline:0}.modal-actions{display:flex;justify-content:flex-end;gap:7px;flex-wrap:wrap;margin-top:12px}.modal-actions button{min-height:32px;border:1px solid var(--line);background:var(--surface);border-radius:8px;padding:0 10px;color:var(--muted)}.modal-actions button:hover{color:var(--fg);border-color:var(--line-strong)}.modal-actions .deny{color:var(--red)}
|
|
21504
|
+
#modal{display:none;position:fixed;inset:0;z-index:60;background:rgba(0,0,0,.58);align-items:center;justify-content:center;padding:20px}#modal.open{display:flex}.dialog{width:min(520px,100%);background:#161614;border:1px solid var(--line-strong);border-radius:14px;padding:16px;box-shadow:var(--shadow)}.dialog h3{margin:0 0 7px;font-size:15px}.dialog .purpose{color:var(--muted);font-size:12px}.preview{max-height:240px;overflow:auto;overscroll-behavior:contain;white-space:pre-wrap;word-break:break-word;margin:11px 0 14px;padding:10px;background:#10100f;border:1px solid var(--line);border-radius:8px;font:11px/1.5 ui-monospace,Menlo,monospace;color:var(--muted)}
|
|
21505
|
+
.palette{display:none;position:fixed;z-index:65;inset:12vh 0 auto;margin:auto;width:min(560px,92vw);background:#161614;border:1px solid var(--line-strong);border-radius:13px;padding:7px;box-shadow:var(--shadow)}.palette.open{display:block}.palette input{width:100%;height:39px;background:#11110f;border:1px solid var(--line);border-radius:8px;padding:0 10px;outline:0}.palette button{width:100%;min-height:34px;border:0;background:transparent;color:var(--muted);text-align:left;border-radius:8px;padding:6px 8px;font-size:11.5px}.palette button:hover{background:var(--hover);color:var(--fg)}
|
|
21506
|
+
|
|
21507
|
+
/* command browser */
|
|
21508
|
+
.command-card{width:min(720px,95vw)!important;padding:0!important;overflow:hidden!important}.sheet-head{height:50px;padding:0 15px;border-bottom:1px solid var(--line);display:flex;align-items:center;justify-content:space-between}.sheet-head h3{margin:0}.sheet-head button{border:0;background:transparent;color:var(--muted);width:30px;height:30px;border-radius:7px}.sheet-head button:hover{background:var(--hover);color:var(--fg)}.command-body{padding:12px;display:grid;grid-template-rows:auto minmax(0,1fr);gap:9px;max-height:72vh}.command-body input{margin:0}.command-list{min-height:0;overflow:auto;overscroll-behavior:contain;display:grid;gap:3px}.command-row{display:grid;grid-template-columns:140px minmax(0,1fr) auto;gap:10px;align-items:start;border:0;background:transparent;border-radius:9px;padding:9px 10px;text-align:left;color:var(--muted)}.command-row:hover{background:var(--hover);color:var(--fg)}.command-code{font:11px ui-monospace,Menlo,monospace;color:#d2cbc1}.command-desc{font-size:11.5px;line-height:1.4}.command-kind{font-size:9.5px;color:var(--faint);text-transform:uppercase;letter-spacing:.06em}
|
|
21509
|
+
|
|
21510
|
+
/* settings */
|
|
21511
|
+
.settings-card{width:min(980px,96vw)!important;height:min(720px,92vh);max-height:92vh!important;padding:0!important;overflow:hidden!important;display:grid;grid-template-columns:190px minmax(0,1fr);background:#151513!important}.settings-nav{border-right:1px solid var(--line);padding:13px 9px;display:flex;flex-direction:column;gap:3px;min-height:0}.settings-nav-head{display:flex;align-items:center;justify-content:space-between;padding:4px 7px 12px}.settings-nav-head b{font-size:13px}.settings-nav button[data-settings-tab]{height:33px;border:0;background:transparent;color:var(--muted);border-radius:8px;text-align:left;padding:0 9px;font-size:11.5px}.settings-nav button[data-settings-tab]:hover,.settings-nav button[data-settings-tab].on{background:var(--hover);color:var(--fg)}.settings-close{width:28px;height:28px;border:0;background:transparent;color:var(--muted);border-radius:7px}.settings-close:hover{background:var(--hover);color:var(--fg)}.settings-content{min-width:0;min-height:0;overflow:auto;overscroll-behavior:contain;padding:24px 26px 34px}.settings-panel{display:none;max-width:720px}.settings-panel.on{display:block}.settings-panel h2{margin:0 0 4px;font-size:18px;letter-spacing:-.03em}.settings-panel>.sub{margin:0 0 22px;color:var(--muted);font-size:12px;line-height:1.5}.setting-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:24px;align-items:center;padding:13px 0;border-top:1px solid var(--line)}.setting-copy b{display:block;font-size:12.5px;font-weight:580;margin-bottom:3px}.setting-copy span{display:block;color:var(--muted);font-size:11.5px;line-height:1.45}.setting-control{min-width:190px;display:flex;justify-content:flex-end}.setting-control .pick-menu{bottom:auto;top:36px;right:0;left:auto;max-height:300px;overflow:auto;overscroll-behavior:contain}.setting-control .pick-open{border-color:var(--line);background:rgba(255,255,255,.025);min-width:180px;justify-content:space-between}.setting-control input[type=password]{width:240px;height:34px;background:#11110f;border:1px solid var(--line);border-radius:8px;padding:0 9px}.settings-note{border:1px solid var(--line);background:rgba(255,255,255,.025);border-radius:9px;padding:10px 11px;color:var(--muted);font-size:11.5px;line-height:1.5}.settings-note.warn{border-color:rgba(224,170,67,.22);background:rgba(224,170,67,.045)}
|
|
21512
|
+
.usage-cards{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;margin:14px 0 18px}.usage-card{border:1px solid var(--line);border-radius:10px;padding:10px;background:rgba(255,255,255,.018)}.usage-card span{display:block;color:var(--faint);font-size:9.5px;text-transform:uppercase;letter-spacing:.06em;margin-bottom:6px}.usage-card b{font:600 17px ui-monospace,Menlo,monospace;color:var(--fg)}.usage-chart{height:180px;border:1px solid var(--line);border-radius:10px;background:#11110f;padding:9px;margin-bottom:16px}.usage-chart svg{display:block;width:100%;height:100%;overflow:visible}.usage-empty{height:100%;display:grid;place-items:center;color:var(--faint);font-size:11px}.breakdown{display:grid;gap:7px;margin:8px 0 20px}.break-row{display:grid;grid-template-columns:120px minmax(0,1fr) 90px;gap:9px;align-items:center;font-size:10.5px;color:var(--muted)}.break-track{height:6px;background:rgba(255,255,255,.05);border-radius:999px;overflow:hidden}.break-fill{height:100%;background:#847d74;border-radius:999px}.break-val{text-align:right;font:10.5px ui-monospace,Menlo,monospace;color:var(--faint)}
|
|
21513
|
+
.skill-list{display:grid;gap:7px}.skill-row{border:1px solid var(--line);border-radius:9px;padding:10px 11px;background:rgba(255,255,255,.015)}.skill-head{display:flex;align-items:center;gap:8px;margin-bottom:4px}.skill-head b{font-size:12px}.skill-source{padding:2px 6px;border-radius:999px;background:rgba(255,255,255,.055);color:var(--faint);font-size:9.5px}.skill-desc{color:var(--muted);font-size:11.5px;line-height:1.45}.skill-origin{margin-top:5px;color:var(--faint);font:9.5px ui-monospace,Menlo,monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.audit-list{display:grid;gap:5px}.audit-row{display:grid;grid-template-columns:120px 90px minmax(0,1fr);gap:8px;padding:7px 0;border-top:1px solid var(--line);color:var(--muted);font-size:10.5px}.audit-row code{color:#c9c1b7;font-size:10px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
21514
|
+
#mode,#autonomy,#thinking,#review-depth,#review-lens,#term-timeout,#studio-author,#studio-review,#key-kind{position:absolute;opacity:0;pointer-events:none;width:0;height:0}.hidden-config{display:none!important}
|
|
21515
|
+
.branch-menu{left:0;bottom:36px;min-width:220px;max-height:260px;overflow:auto;overscroll-behavior:contain;padding:5px}.branch-menu button,.ship-menu button{width:100%;border:0;background:transparent;color:var(--muted);padding:7px 9px;text-align:left;border-radius:7px;font-size:11px}.branch-menu button:hover,.ship-menu button:hover{background:var(--hover);color:var(--fg)}.ship-menu{right:0;bottom:36px;min-width:210px;padding:5px}.ship-wrap{position:relative}.meta-btn{height:29px;border:1px solid var(--line);background:transparent;border-radius:8px;padding:0 8px;color:var(--muted);font-size:10.5px}.meta-btn:hover{background:var(--hover);color:var(--fg)}
|
|
21516
|
+
|
|
21517
|
+
/* resume picker */
|
|
21518
|
+
.resume-picker{border-radius:14px;background:#161614;overflow:hidden;border:1px solid var(--line)}.resume-head{display:flex;justify-content:space-between;align-items:center;padding:11px 13px;border-bottom:1px solid var(--line)}.resume-head strong{font-size:12px;font-weight:600}.resume-head span{color:var(--faint);font-size:10.5px}.resume-list{padding:5px;max-height:330px;overflow:auto;overscroll-behavior:contain}.resume-chat{width:100%;border:0;background:transparent;color:var(--fg);padding:9px 10px;border-radius:8px;display:flex;align-items:center;gap:12px;text-align:left}.resume-chat:hover{background:var(--hover)}.resume-copy{min-width:0;flex:1;display:grid;gap:3px}.resume-copy strong{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px;font-weight:500}.resume-copy span{color:var(--faint);font-size:10px}.resume-arrow{color:var(--faint);font-size:18px}.resume-empty{padding:18px 12px;color:var(--faint);text-align:center;font-size:11px}
|
|
21519
|
+
|
|
21520
|
+
@media(max-width:1100px){.shell,.shell.rail-off{grid-template-columns:var(--rail-w) minmax(0,1fr)}.gutter{display:none}.changes{display:none}.shell:not(.changes-off) .changes,.changes.open{display:grid;position:fixed;inset:0 0 0 auto;width:min(420px,100%);z-index:40;box-shadow:-18px 0 50px rgba(0,0,0,.45)}}
|
|
21521
|
+
@media(max-width:760px){:root{--top-h:46px}.shell,.shell.rail-off{grid-template-columns:1fr}.rail{display:none}.shell:not(.rail-off) .rail{display:flex;position:fixed;inset:0 auto 0 0;width:min(285px,88vw);z-index:45;box-shadow:20px 0 50px rgba(0,0,0,.5)}.topbar{padding:0 10px}.top-actions .toolbar-label{display:none}.top-actions{gap:2px}.toolbar-btn{padding:0 7px}.dock{padding:6px 9px calc(10px + env(safe-area-inset-bottom))}.composer{border-radius:15px}.composer-line textarea{font-size:16px;min-height:46px}.composer-foot{padding-top:2px}.composer-left .pick[data-pick="mode"],.composer-left .pick[data-pick="autonomy"]{display:none}#model-open{max-width:155px}.prompt{max-width:90%;font-size:13.5px}#feed{padding:22px 15px 30px}.settings-card{width:100vw!important;height:100dvh;max-height:100dvh!important;border-radius:0!important;border:0!important;grid-template-columns:1fr}.settings-nav{border-right:0;border-bottom:1px solid var(--line);padding:8px;display:grid;grid-template-columns:1fr auto;gap:5px}.settings-nav-head{grid-column:1/-1;padding:2px 4px 4px}.settings-nav button[data-settings-tab]{display:none}.settings-nav button[data-settings-tab].on{display:none}.settings-mobile-tabs{display:flex!important;grid-column:1/-1;gap:3px;overflow:auto;padding-bottom:1px}.settings-mobile-tabs button{display:block!important;flex:0 0 auto;height:29px!important;padding:0 8px!important}.settings-content{padding:18px 15px 30px}.setting-row{grid-template-columns:1fr;gap:8px}.setting-control{justify-content:flex-start;min-width:0}.setting-control .pick-open{width:100%;max-width:100%}.setting-control .pick{width:100%}.setting-control .pick-menu{left:0;right:auto;width:100%;max-width:100%}.usage-cards{grid-template-columns:1fr 1fr}.break-row{grid-template-columns:88px minmax(0,1fr) 68px}.command-row{grid-template-columns:110px minmax(0,1fr)}.command-kind{display:none}.sheet{padding:0}.command-card{width:100vw!important;height:100dvh;max-height:100dvh!important;border-radius:0!important}.command-body{max-height:calc(100dvh - 50px)}#empty{margin-top:12vh;padding:0 18px}.top-status{display:none}.diff-head{min-height:39px;gap:6px}.diff-title-wrap{overflow:hidden}#diff-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.diff-actions{overflow-x:auto;max-width:52vw;scrollbar-width:none}.diff-actions::-webkit-scrollbar{display:none}.diff-actions button{flex:0 0 auto}.diff,#file-view{border-radius:10px;font-size:10.5px}.diff .row{grid-template-columns:30px 30px minmax(0,1fr)}.diff .ln{padding:0 4px}.diff-file-head{padding:8px}.resume-picker{width:100%;margin:12px 0 24px;border-radius:12px}.resume-list{max-height:min(360px,48dvh)}.resume-chat{min-height:48px}}
|
|
21689
21522
|
</style>
|
|
21690
21523
|
</head>
|
|
21691
21524
|
<body${remote ? ' class="remote"' : ""}>
|
|
21692
21525
|
<div class="shell">
|
|
21693
21526
|
<aside class="rail">
|
|
21694
21527
|
<div class="rail-top">
|
|
21695
|
-
<div class="mark" title="CritiqueCode">C</div>
|
|
21696
|
-
<button type="button" class="icon-btn" id="toggle-rail" title="Hide sessions" aria-label="Hide sessions">\u2039</button>
|
|
21528
|
+
<div class="brand"><div class="mark" title="CritiqueCode">C</div><span>CritiqueCode</span></div>
|
|
21697
21529
|
</div>
|
|
21698
|
-
<
|
|
21699
|
-
<button type="button" class="plus" id="new-session" title="New session" aria-label="New session">
|
|
21530
|
+
<button type="button" class="plus" id="new-session" title="New session">
|
|
21700
21531
|
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M7 2v10M2 7h10" stroke="currentColor" stroke-width="1.4"/></svg>
|
|
21701
|
-
New
|
|
21532
|
+
New chat
|
|
21702
21533
|
</button>
|
|
21703
|
-
<
|
|
21704
|
-
|
|
21534
|
+
<div class="rail-search">
|
|
21535
|
+
<svg width="13" height="13" viewBox="0 0 14 14" fill="none"><circle cx="6" cy="6" r="3.8" stroke="currentColor"/><path d="m9 9 3 3" stroke="currentColor"/></svg>
|
|
21536
|
+
<input id="session-search" class="search" placeholder="Search chats" autocomplete="off">
|
|
21537
|
+
</div>
|
|
21705
21538
|
<div id="sessions"></div>
|
|
21539
|
+
<div class="rail-footer">
|
|
21540
|
+
<button type="button" id="fork-session" title="Fork this conversation">
|
|
21541
|
+
<svg width="14" height="14" viewBox="0 0 16 16" fill="none"><path d="M5 3v5m0 0c0 2 1.5 3 3.5 3H11m-6-3c0-2 1.5-3 3.5-3H11" stroke="currentColor"/><circle cx="4" cy="2.5" r="1.4" stroke="currentColor"/><circle cx="12" cy="4.5" r="1.4" stroke="currentColor"/><circle cx="12" cy="11.5" r="1.4" stroke="currentColor"/></svg>
|
|
21542
|
+
Fork chat
|
|
21543
|
+
</button>
|
|
21544
|
+
<button type="button" id="rail-settings">
|
|
21545
|
+
<svg width="14" height="14" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="2.2" stroke="currentColor"/><path d="M8 2.2v1.3M8 12.5v1.3M13.8 8h-1.3M3.5 8H2.2M12.1 3.9l-.9.9M4.8 11.2l-.9.9M12.1 12.1l-.9-.9M4.8 4.8l-.9-.9" stroke="currentColor"/></svg>
|
|
21546
|
+
Settings
|
|
21547
|
+
</button>
|
|
21548
|
+
<div class="repo-mini" title="${repositoryRoot}">${repositoryName} \xB7 ${branch}</div>
|
|
21706
21549
|
</div>
|
|
21707
21550
|
</aside>
|
|
21551
|
+
|
|
21708
21552
|
<div class="stage">
|
|
21709
|
-
<header>
|
|
21710
|
-
|
|
21711
|
-
<
|
|
21712
|
-
|
|
21553
|
+
<header class="topbar">
|
|
21554
|
+
<div class="topbar-left">
|
|
21555
|
+
<button type="button" class="icon-btn" id="toggle-rail" title="Chats" aria-label="Toggle chats">
|
|
21556
|
+
<svg width="15" height="15" viewBox="0 0 16 16" fill="none"><rect x="2" y="2.5" width="12" height="11" rx="1.7" stroke="currentColor"/><path d="M5.5 3v10" stroke="currentColor"/></svg>
|
|
21557
|
+
</button>
|
|
21558
|
+
<button type="button" class="icon-btn top-new-chat" id="top-new-session" title="New chat" aria-label="New chat">
|
|
21559
|
+
<svg width="15" height="15" viewBox="0 0 16 16" fill="none"><path d="M8 3v10M3 8h10" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/></svg>
|
|
21560
|
+
</button>
|
|
21561
|
+
<div class="session-title" id="session-title"><span id="session-label">New session</span></div>
|
|
21713
21562
|
</div>
|
|
21714
|
-
<div class="
|
|
21715
|
-
<span class="
|
|
21716
|
-
<
|
|
21717
|
-
|
|
21718
|
-
|
|
21719
|
-
|
|
21720
|
-
|
|
21721
|
-
<
|
|
21722
|
-
|
|
21723
|
-
|
|
21724
|
-
|
|
21725
|
-
|
|
21726
|
-
|
|
21727
|
-
|
|
21728
|
-
|
|
21729
|
-
|
|
21730
|
-
|
|
21731
|
-
<div id="ctx-tip">0 / 200,000 tokens</div>
|
|
21732
|
-
</span>
|
|
21733
|
-
<button type="button" class="icon-btn" id="toggle-term" title="Show or hide terminal" aria-label="Toggle terminal">\u2325</button>
|
|
21734
|
-
<button type="button" class="icon-btn" id="toggle-changes" title="Show or hide workspace" aria-label="Toggle workspace">\u2630</button>
|
|
21735
|
-
<span class="badge model" id="model-badge" title="${model}">author ${modelShort}</span>
|
|
21736
|
-
<span class="badge model" id="review-badge" title="${reviewModel}">review ${reviewModel}</span>
|
|
21737
|
-
<button type="button" class="icon-btn" id="trust-open" title="Trust legend">?</button>
|
|
21738
|
-
<button type="button" class="icon-btn" id="palette-open" title="Command palette">\u2318</button>
|
|
21739
|
-
<button type="button" class="icon-btn" id="studio-open" title="Settings">\u2699</button>
|
|
21740
|
-
<button type="button" class="icon-btn" id="stop" title="Stop" hidden>\u25A0</button>
|
|
21563
|
+
<div class="top-actions">
|
|
21564
|
+
<span class="top-status" id="status" hidden></span>
|
|
21565
|
+
<button type="button" class="toolbar-btn" id="changes-pill" title="Open workspace">
|
|
21566
|
+
<svg width="14" height="14" viewBox="0 0 16 16" fill="none"><path d="M3 4h10M3 8h10M3 12h10" stroke="currentColor"/><circle cx="5" cy="4" r="1" fill="currentColor"/><circle cx="11" cy="8" r="1" fill="currentColor"/></svg>
|
|
21567
|
+
<span class="toolbar-label">Changes</span><span class="count" id="changes-count">0</span>
|
|
21568
|
+
<span hidden id="changes-plus">+0</span><span hidden id="changes-minus">\u22120</span>
|
|
21569
|
+
</button>
|
|
21570
|
+
<button type="button" class="icon-btn" id="toggle-term" title="Terminal" aria-label="Toggle terminal">
|
|
21571
|
+
<svg width="15" height="15" viewBox="0 0 16 16" fill="none"><rect x="1.7" y="2.5" width="12.6" height="10.5" rx="1.5" stroke="currentColor"/><path d="m4 6 2 2-2 2M8 10h3" stroke="currentColor"/></svg>
|
|
21572
|
+
</button>
|
|
21573
|
+
<button type="button" class="icon-btn" id="toggle-changes" title="Workspace" aria-label="Toggle workspace">
|
|
21574
|
+
<svg width="15" height="15" viewBox="0 0 16 16" fill="none"><path d="M2.2 3.3h11.6v9.4H2.2zM10.2 3.3v9.4" stroke="currentColor"/></svg>
|
|
21575
|
+
</button>
|
|
21576
|
+
<button type="button" class="icon-btn" id="studio-open" title="Settings" aria-label="Settings">
|
|
21577
|
+
<svg width="15" height="15" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="2.2" stroke="currentColor"/><path d="M8 2.2v1.3M8 12.5v1.3M13.8 8h-1.3M3.5 8H2.2M12.1 3.9l-.9.9M4.8 11.2l-.9.9M12.1 12.1l-.9-.9M4.8 4.8l-.9-.9" stroke="currentColor"/></svg>
|
|
21578
|
+
</button>
|
|
21579
|
+
<button type="button" class="icon-btn" id="stop" title="Stop run" aria-label="Stop" hidden>\u25A0</button>
|
|
21741
21580
|
</div>
|
|
21581
|
+
<span id="files-badge" hidden></span><span id="cost" hidden></span><span id="auto-badge" hidden></span><span id="watch-badge" hidden></span><span id="model-badge" hidden></span><span id="review-badge" hidden></span>
|
|
21742
21582
|
</header>
|
|
21583
|
+
|
|
21743
21584
|
<main>
|
|
21744
21585
|
<div id="empty">
|
|
21745
|
-
<h1>
|
|
21746
|
-
<
|
|
21747
|
-
|
|
21748
|
-
|
|
21749
|
-
|
|
21750
|
-
</
|
|
21751
|
-
|
|
21752
|
-
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 12V8m0 0a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm8-4v4m0 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4zM6 8h4" stroke="currentColor" stroke-width="1.2"/></svg>
|
|
21753
|
-
<span>Main branch (<strong>${branch}</strong>)</span>
|
|
21754
|
-
</li>
|
|
21755
|
-
<li>
|
|
21756
|
-
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="5.5" stroke="currentColor" stroke-width="1.2"/><path d="M8 5.5V8l2 1.5" stroke="currentColor" stroke-width="1.2"/></svg>
|
|
21757
|
-
<span>Loopback only \xB7 ${repositoryName}</span>
|
|
21758
|
-
</li>
|
|
21759
|
-
</ul>
|
|
21586
|
+
<h1>What are we building?</h1>
|
|
21587
|
+
<p>Ask CritiqueCode to implement, debug, explain, or review this repository. Type <strong>/</strong> for commands and skills, or <strong>@</strong> to attach files and other chats.</p>
|
|
21588
|
+
<div class="empty-actions">
|
|
21589
|
+
<button type="button" data-starter="Review the current changes and tell me what needs fixing">Review current changes</button>
|
|
21590
|
+
<button type="button" data-starter="Explain this repository and its main architecture">Explain the repository</button>
|
|
21591
|
+
<button type="button" id="empty-commands">Browse commands</button>
|
|
21592
|
+
</div>
|
|
21760
21593
|
</div>
|
|
21761
21594
|
<div id="feed"></div>
|
|
21762
21595
|
</main>
|
|
21596
|
+
|
|
21763
21597
|
<div class="term" id="term">
|
|
21764
21598
|
<header>
|
|
21765
|
-
<span>Terminal \xB7 repo root
|
|
21599
|
+
<span>Terminal \xB7 repo root</span>
|
|
21766
21600
|
<span>
|
|
21767
|
-
<label class="always-row"><input type="checkbox" id="term-bg">
|
|
21601
|
+
<label class="always-row"><input type="checkbox" id="term-bg"> background</label>
|
|
21768
21602
|
<div class="pick" data-pick="term-timeout">
|
|
21769
21603
|
<button type="button" class="pick-open" id="term-timeout-open" aria-haspopup="listbox" aria-expanded="false">60s <span class="caret">\u25BE</span></button>
|
|
21770
21604
|
<div class="pick-menu" id="term-timeout-menu"></div>
|
|
21771
|
-
<select id="term-timeout" aria-label="Timeout">
|
|
21772
|
-
<option value="60000">60s</option>
|
|
21773
|
-
<option value="180000">3m</option>
|
|
21774
|
-
<option value="600000">10m</option>
|
|
21775
|
-
</select>
|
|
21605
|
+
<select id="term-timeout" aria-label="Timeout"><option value="60000">60s</option><option value="180000">3m</option><option value="600000">10m</option></select>
|
|
21776
21606
|
</div>
|
|
21777
21607
|
<button type="button" id="term-clear">Clear</button>
|
|
21778
21608
|
</span>
|
|
21779
21609
|
</header>
|
|
21780
21610
|
<pre id="term-out"></pre>
|
|
21781
|
-
<form id="term-form">
|
|
21782
|
-
<input id="term-input" autocomplete="off" spellcheck="false" placeholder="Run a command in this repository\u2026">
|
|
21783
|
-
</form>
|
|
21611
|
+
<form id="term-form"><input id="term-input" autocomplete="off" spellcheck="false" placeholder="Run a command in this repository\u2026"></form>
|
|
21784
21612
|
</div>
|
|
21613
|
+
|
|
21785
21614
|
<div class="dock">
|
|
21786
|
-
<div class="composer-actions">
|
|
21787
|
-
<button type="button" class="changes-pill" id="changes-pill" title="Show workspace">
|
|
21788
|
-
Changes <span class="plus" id="changes-plus">+0</span> <span class="minus" id="changes-minus">-0</span>
|
|
21789
|
-
</button>
|
|
21790
|
-
<div class="ship-wrap">
|
|
21791
|
-
<button type="button" class="ship-btn" id="ship-commit">Create Branch & Commit</button>
|
|
21792
|
-
<button type="button" class="ship-caret" id="ship-menu-open" aria-haspopup="menu" aria-expanded="false" aria-label="Commit actions">\u25BE</button>
|
|
21793
|
-
<div class="ship-menu" id="ship-menu" role="menu">
|
|
21794
|
-
<button type="button" id="commit-current">Commit to current branch</button>
|
|
21795
|
-
<button type="button" id="commit-new">Create branch & commit</button>
|
|
21796
|
-
<button type="button" id="undo-menu">Undo last commit</button>
|
|
21797
|
-
</div>
|
|
21798
|
-
</div>
|
|
21799
|
-
</div>
|
|
21800
21615
|
<div class="composer">
|
|
21801
|
-
<div id="mention">
|
|
21802
|
-
<div id="mention-list"></div>
|
|
21803
|
-
</div>
|
|
21616
|
+
<div id="mention"><div id="mention-list"></div></div>
|
|
21804
21617
|
<div class="composer-line">
|
|
21805
21618
|
<div class="cmds">
|
|
21806
|
-
<button type="button" class="plus-btn" id="cmd-open" aria-haspopup="menu" aria-expanded="false" title="
|
|
21619
|
+
<button type="button" class="plus-btn" id="cmd-open" aria-haspopup="menu" aria-expanded="false" title="Add context or browse commands">+</button>
|
|
21807
21620
|
<div class="cmd-pop" id="cmd-pop" role="menu">
|
|
21808
|
-
<button type="button"
|
|
21809
|
-
<button type="button"
|
|
21810
|
-
<button type="button" data-cmd="/
|
|
21811
|
-
<button type="button" data-cmd="/critique">Critique CLI</button>
|
|
21812
|
-
<button type="button" data-cmd="/checkpoint">Checkpoint</button>
|
|
21813
|
-
<button type="button" data-cmd="/rollback">Rollback</button>
|
|
21814
|
-
<button type="button" data-cmd="/explain">Explain</button>
|
|
21815
|
-
<button type="button" data-cmd="/dismiss">Dismiss</button>
|
|
21816
|
-
<button type="button" data-cmd="/watch on">Watch</button>
|
|
21817
|
-
<button type="button" data-cmd="/status">Status</button>
|
|
21818
|
-
<button type="button" data-cmd="/doctor">Doctor</button>
|
|
21819
|
-
<button type="button" data-cmd="/repair">Repair</button>
|
|
21820
|
-
<button type="button" data-cmd="/ship">Ship</button>
|
|
21821
|
-
<button type="button" data-cmd="/skills">Skills</button>
|
|
21822
|
-
<button type="button" data-cmd="/login" id="login">Login</button>
|
|
21823
|
-
<button type="button" id="attach">Attach path</button>
|
|
21824
|
-
<button type="button" data-cmd="/exit">Exit</button>
|
|
21621
|
+
<button type="button" id="commands-open">Commands & skills\u2026</button>
|
|
21622
|
+
<button type="button" id="attach">Attach repository path\u2026</button>
|
|
21623
|
+
<button type="button" data-cmd="/login">Login / connect inference</button>
|
|
21825
21624
|
</div>
|
|
21826
21625
|
</div>
|
|
21827
|
-
<textarea id="input" rows="1" placeholder="
|
|
21828
|
-
<div class="pick" data-pick="thinking">
|
|
21829
|
-
<button type="button" class="pick-open" id="thinking-open" aria-haspopup="listbox" aria-expanded="false">Medium <span class="caret">\u25BE</span></button>
|
|
21830
|
-
<div class="pick-menu" id="thinking-menu"></div>
|
|
21831
|
-
<select id="thinking" aria-label="Thinking level"></select>
|
|
21832
|
-
</div>
|
|
21626
|
+
<textarea id="input" rows="1" placeholder="Message CritiqueCode\u2026" title="Type / for commands and skills, @ to add context"></textarea>
|
|
21833
21627
|
<button type="button" class="mic-btn" id="voice" title="Voice input" aria-label="Voice input">
|
|
21834
21628
|
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><rect x="5" y="2" width="4" height="7" rx="2" stroke="currentColor" stroke-width="1.2"/><path d="M3.5 7.5a3.5 3.5 0 0 0 7 0M7 11v1.5" stroke="currentColor" stroke-width="1.2"/></svg>
|
|
21835
21629
|
</button>
|
|
21836
21630
|
</div>
|
|
21837
21631
|
<div class="chips" id="ref-chips"></div>
|
|
21838
|
-
<div class="queue" id="queue" hidden>
|
|
21839
|
-
<div id="queue-list"></div>
|
|
21840
|
-
<div class="queue-bar">
|
|
21841
|
-
<span id="queue-label">Queued \u21B5 to Send</span>
|
|
21842
|
-
<div>
|
|
21843
|
-
<button type="button" id="queue-clear">Clear</button>
|
|
21844
|
-
<button type="button" class="now" id="queue-send">Send now</button>
|
|
21845
|
-
</div>
|
|
21846
|
-
</div>
|
|
21847
|
-
</div>
|
|
21632
|
+
<div class="queue" id="queue" hidden><div id="queue-list"></div><div class="queue-bar"><span id="queue-label"></span><div><button type="button" id="queue-clear">Clear</button><button type="button" class="now" id="queue-send">Send now</button></div></div></div>
|
|
21848
21633
|
<div class="composer-foot">
|
|
21849
|
-
<div class="
|
|
21850
|
-
<button type="button" class="meta-btn" id="branch-open" aria-haspopup="listbox" title="Switch branch">\u2387 ${branch} <span class="caret">\u25BE</span></button>
|
|
21851
|
-
<div class="branch-menu" id="branch-menu"></div>
|
|
21852
|
-
</div>
|
|
21853
|
-
<span class="host-chip" title="Loopback only. The author stays on this machine.">
|
|
21854
|
-
<svg width="13" height="13" viewBox="0 0 16 16" fill="none"><rect x="2" y="3" width="12" height="8" rx="1.2" stroke="currentColor" stroke-width="1.2"/><path d="M5 13h6" stroke="currentColor" stroke-width="1.2"/></svg>
|
|
21855
|
-
This Mac
|
|
21856
|
-
</span>
|
|
21857
|
-
<label class="always-row"><input type="checkbox" id="always-approve"> Always approve</label>
|
|
21858
|
-
<div class="bar-right">
|
|
21634
|
+
<div class="composer-left">
|
|
21859
21635
|
<div class="pick" data-pick="mode">
|
|
21860
21636
|
<button type="button" class="pick-open" id="mode-open" aria-haspopup="listbox" aria-expanded="false">Agent <span class="caret">\u25BE</span></button>
|
|
21861
21637
|
<div class="pick-menu" id="mode-menu"></div>
|
|
21862
|
-
<select id="mode" aria-label="Agent
|
|
21863
|
-
<option value="agent">Agent</option>
|
|
21864
|
-
<option value="plan">Plan</option>
|
|
21865
|
-
<option value="ask">Ask</option>
|
|
21866
|
-
<option value="debug">Debug</option>
|
|
21867
|
-
</select>
|
|
21638
|
+
<select id="mode" aria-label="Mode"><option value="agent">Agent</option><option value="plan">Plan</option><option value="ask">Ask</option><option value="debug">Debug</option></select>
|
|
21868
21639
|
</div>
|
|
21869
21640
|
<div class="pick" data-pick="autonomy">
|
|
21870
|
-
<button type="button" class="pick-open" id="autonomy-open" aria-haspopup="listbox" aria-expanded="false">Ask <span class="caret">\u25BE</span></button>
|
|
21641
|
+
<button type="button" class="pick-open autonomy-pill" id="autonomy-open" aria-haspopup="listbox" aria-expanded="false">Ask <span class="caret">\u25BE</span></button>
|
|
21871
21642
|
<div class="pick-menu" id="autonomy-menu"></div>
|
|
21872
|
-
<select id="autonomy" aria-label="
|
|
21873
|
-
<option value="ask">Ask</option>
|
|
21874
|
-
<option value="auto">Auto</option>
|
|
21875
|
-
</select>
|
|
21643
|
+
<select id="autonomy" aria-label="Approval mode"><option value="ask">Ask</option><option value="auto">Auto approve</option></select>
|
|
21876
21644
|
</div>
|
|
21877
21645
|
<div class="model-wrap pick">
|
|
21878
21646
|
<button type="button" id="model-open" aria-haspopup="listbox" aria-expanded="false">${modelShort} <span class="caret">\u25BE</span></button>
|
|
21879
|
-
<div id="model-menu">
|
|
21880
|
-
<input id="model-filter" placeholder="Search models\u2026" autocomplete="off">
|
|
21881
|
-
<div id="model-list"></div>
|
|
21882
|
-
</div>
|
|
21647
|
+
<div id="model-menu"><input id="model-filter" placeholder="Search models\u2026" autocomplete="off"><div id="model-list"></div></div>
|
|
21883
21648
|
<select id="model" aria-label="Author model">${options}</select>
|
|
21884
21649
|
</div>
|
|
21885
|
-
|
|
21886
|
-
|
|
21887
|
-
|
|
21888
|
-
|
|
21889
|
-
<
|
|
21890
|
-
|
|
21891
|
-
<option value="quick">quick</option>
|
|
21892
|
-
<option value="paranoid">paranoid</option>
|
|
21893
|
-
</select>
|
|
21894
|
-
</div>
|
|
21895
|
-
<div class="pick" data-pick="review-lens">
|
|
21896
|
-
<button type="button" class="pick-open" id="review-lens-open" aria-haspopup="listbox">general <span class="caret">\u25BE</span></button>
|
|
21897
|
-
<div class="pick-menu" id="review-lens-menu"></div>
|
|
21898
|
-
<select id="review-lens" aria-label="Review lens">
|
|
21899
|
-
<option value="general">general</option>
|
|
21900
|
-
<option value="security">security</option>
|
|
21901
|
-
<option value="performance">performance</option>
|
|
21902
|
-
<option value="reliability">reliability</option>
|
|
21903
|
-
<option value="stress">stress</option>
|
|
21904
|
-
</select>
|
|
21905
|
-
</div>
|
|
21906
|
-
<button type="button" id="send" aria-label="Send">Send</button>
|
|
21650
|
+
</div>
|
|
21651
|
+
<div class="composer-right">
|
|
21652
|
+
<button type="button" id="review-run" title="Run an independent review">Review</button>
|
|
21653
|
+
<button type="button" id="send" aria-label="Send" title="Send">
|
|
21654
|
+
<svg width="15" height="15" viewBox="0 0 16 16" fill="none"><path d="M8 13V3m0 0L4.5 6.5M8 3l3.5 3.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
21655
|
+
</button>
|
|
21907
21656
|
</div>
|
|
21908
21657
|
</div>
|
|
21909
21658
|
</div>
|
|
21910
21659
|
</div>
|
|
21911
21660
|
</div>
|
|
21912
|
-
|
|
21661
|
+
|
|
21662
|
+
<div class="gutter" id="gutter" title="Resize workspace"></div>
|
|
21913
21663
|
<aside class="changes" id="changes-pane">
|
|
21914
21664
|
<header>
|
|
21915
21665
|
<h2>Workspace</h2>
|
|
21916
|
-
<button type="button" class="icon-btn" id="close-changes" title="
|
|
21917
|
-
<div class="sum" id="changes-sum"
|
|
21666
|
+
<button type="button" class="icon-btn" id="close-changes" title="Close workspace" aria-label="Close workspace">\xD7</button>
|
|
21667
|
+
<div class="sum" id="changes-sum">${branch}</div>
|
|
21668
|
+
<ol class="gate" id="ship-gate"></ol>
|
|
21918
21669
|
</header>
|
|
21919
|
-
<div class="work-tabs">
|
|
21920
|
-
<button type="button" data-tab="tree" class="on">Tree</button>
|
|
21921
|
-
<button type="button" data-tab="findings">Findings</button>
|
|
21922
|
-
<button type="button" data-tab="timeline">Checkpoints</button>
|
|
21923
|
-
<button type="button" data-tab="compare">Compare</button>
|
|
21924
|
-
</div>
|
|
21670
|
+
<div class="work-tabs"><button type="button" data-tab="tree" class="on">Files</button><button type="button" data-tab="findings">Findings</button><button type="button" data-tab="timeline">History</button><button type="button" data-tab="compare">Compare</button></div>
|
|
21925
21671
|
<div class="work-stack">
|
|
21926
21672
|
<div class="workspace" id="tab-tree">
|
|
21927
|
-
<input id="grep" placeholder="
|
|
21673
|
+
<input id="grep" placeholder="Find file or text\u2026">
|
|
21928
21674
|
<div class="tree" id="tree"></div>
|
|
21929
21675
|
<div class="diff-head">
|
|
21930
|
-
<
|
|
21931
|
-
|
|
21932
|
-
<
|
|
21933
|
-
<button type="button" id="reject-file">Reject</button>
|
|
21934
|
-
<button type="button" id="commit">Commit</button>
|
|
21935
|
-
<button type="button" id="undo">Undo commit</button>
|
|
21676
|
+
<div class="diff-title-wrap">
|
|
21677
|
+
<button type="button" id="all-changes" class="diff-back" hidden>\u2190 All changes</button>
|
|
21678
|
+
<b id="diff-title">Working changes</b>
|
|
21936
21679
|
</div>
|
|
21680
|
+
<div class="diff-actions"><button type="button" id="accept-file">Keep</button><button type="button" id="reject-file" class="danger">Discard</button><button type="button" id="commit">Commit</button><button type="button" id="undo" title="Soft undo last commit">Undo</button></div>
|
|
21937
21681
|
</div>
|
|
21938
|
-
<div class="diff" id="diff"><div class="
|
|
21939
|
-
<pre id="file-view" hidden></pre>
|
|
21940
|
-
<iframe id="preview" hidden sandbox="allow-same-origin" title="Preview"></iframe>
|
|
21941
|
-
</div>
|
|
21942
|
-
<div class="workspace" id="tab-findings" hidden>
|
|
21943
|
-
<input id="find-filter" placeholder="Filter findings\u2026">
|
|
21944
|
-
<div id="find-list" class="tree"></div>
|
|
21945
|
-
</div>
|
|
21946
|
-
<div class="workspace" id="tab-timeline" hidden>
|
|
21947
|
-
<div id="timeline" class="tree"></div>
|
|
21948
|
-
</div>
|
|
21949
|
-
<div class="compare" id="tab-compare" hidden>
|
|
21950
|
-
<div id="compare-left"></div>
|
|
21951
|
-
<div id="compare-right"></div>
|
|
21682
|
+
<div class="diff" id="diff"><div class="diff-loading">Open Workspace to inspect working-tree diffs.</div></div>
|
|
21683
|
+
<pre id="file-view" hidden></pre><iframe id="preview" hidden sandbox="allow-same-origin" title="Preview"></iframe>
|
|
21952
21684
|
</div>
|
|
21685
|
+
<div class="workspace" id="tab-findings" hidden><input id="find-filter" placeholder="Filter findings\u2026"><div id="find-list" class="tree"></div></div>
|
|
21686
|
+
<div class="workspace" id="tab-timeline" hidden><div id="timeline" class="tree"></div></div>
|
|
21687
|
+
<div class="compare" id="tab-compare" hidden><div id="compare-left"></div><div id="compare-right"></div></div>
|
|
21953
21688
|
</div>
|
|
21954
21689
|
<div class="change-list" id="change-list"></div>
|
|
21955
21690
|
</aside>
|
|
21956
21691
|
</div>
|
|
21957
|
-
|
|
21958
|
-
|
|
21959
|
-
|
|
21960
|
-
|
|
21961
|
-
|
|
21962
|
-
|
|
21963
|
-
|
|
21964
|
-
|
|
21965
|
-
<button type="button" id="always">Always approve</button>
|
|
21966
|
-
<button type="button" id="approve">Approve</button>
|
|
21967
|
-
</div>
|
|
21968
|
-
</div>
|
|
21969
|
-
</div>
|
|
21970
|
-
<div class="palette" id="palette">
|
|
21971
|
-
<input id="palette-q" placeholder="Commands and skills\u2026" autocomplete="off">
|
|
21972
|
-
<div id="palette-list"></div>
|
|
21973
|
-
</div>
|
|
21974
|
-
<div class="sheet" id="legend-sheet"><div class="card"><h3>Trust classes</h3><div id="legend-body"></div></div></div>
|
|
21975
|
-
<div class="sheet" id="studio-sheet"><div class="card">
|
|
21976
|
-
<h3>Settings</h3>
|
|
21977
|
-
<label>Author model</label>
|
|
21978
|
-
<div class="pick" data-pick="studio-author">
|
|
21979
|
-
<button type="button" class="pick-open" id="studio-author-open" aria-haspopup="listbox" aria-expanded="false">Author <span class="caret">\u25BE</span></button>
|
|
21980
|
-
<div class="pick-menu" id="studio-author-menu"></div>
|
|
21981
|
-
<select id="studio-author" aria-label="Author model"></select>
|
|
21982
|
-
</div>
|
|
21983
|
-
<label>Review model (independent)</label>
|
|
21984
|
-
<div class="pick" data-pick="studio-review">
|
|
21985
|
-
<button type="button" class="pick-open" id="studio-review-open" aria-haspopup="listbox" aria-expanded="false">Review <span class="caret">\u25BE</span></button>
|
|
21986
|
-
<div class="pick-menu" id="studio-review-menu"></div>
|
|
21987
|
-
<select id="studio-review" aria-label="Review model"></select>
|
|
21988
|
-
</div>
|
|
21989
|
-
<p id="studio-indep" class="note"></p>
|
|
21990
|
-
<label>API key kind</label>
|
|
21991
|
-
<div class="pick" data-pick="key-kind">
|
|
21992
|
-
<button type="button" class="pick-open" id="key-kind-open" aria-haspopup="listbox" aria-expanded="false">Key <span class="caret">\u25BE</span></button>
|
|
21993
|
-
<div class="pick-menu" id="key-kind-menu"></div>
|
|
21994
|
-
<select id="key-kind" aria-label="API key kind"></select>
|
|
21995
|
-
</div>
|
|
21996
|
-
<label>Key</label><input id="key-value" type="password" autocomplete="off">
|
|
21997
|
-
<div class="modal-actions">
|
|
21998
|
-
<button type="button" id="save-key">Store key</button>
|
|
21999
|
-
<button type="button" id="close-studio">Close</button>
|
|
22000
|
-
</div>
|
|
22001
|
-
<h3>Skills</h3><div id="skill-list"></div>
|
|
22002
|
-
<h3>Cost</h3><pre id="cost-panel"></pre>
|
|
22003
|
-
<h3>Approvals</h3><pre id="audit-panel"></pre>
|
|
22004
|
-
</div></div>
|
|
22005
|
-
<div class="sheet" id="commit-sheet"><div class="card">
|
|
22006
|
-
<h3 id="commit-sheet-title">Commit</h3>
|
|
22007
|
-
<label id="commit-branch-wrap" hidden>Branch name<input id="commit-branch" autocomplete="off"></label>
|
|
22008
|
-
<label>Message</label>
|
|
22009
|
-
<textarea class="plain" id="commit-msg" rows="6"></textarea>
|
|
22010
|
-
<div class="modal-actions">
|
|
22011
|
-
<button type="button" id="commit-cancel">Cancel</button>
|
|
22012
|
-
<button type="button" id="commit-go">Commit</button>
|
|
22013
|
-
</div>
|
|
21692
|
+
|
|
21693
|
+
<div id="modal"><div class="dialog"><h3>Run this command?</h3><div class="purpose" id="exec-purpose"></div><div class="preview" id="exec-preview"></div><div class="modal-actions"><button type="button" class="deny" id="deny">Deny</button><button type="button" id="always-session">Approve for session</button><button type="button" id="always">Always approve</button><button type="button" id="approve">Approve once</button></div></div></div>
|
|
21694
|
+
|
|
21695
|
+
<div class="palette" id="palette"><input id="palette-q" placeholder="Commands and skills\u2026" autocomplete="off"><div id="palette-list"></div></div>
|
|
21696
|
+
|
|
21697
|
+
<div class="sheet" id="command-sheet"><div class="card command-card">
|
|
21698
|
+
<div class="sheet-head"><h3>Commands & skills</h3><button type="button" id="close-commands" aria-label="Close">\xD7</button></div>
|
|
21699
|
+
<div class="command-body"><input id="command-search" placeholder="Search commands and skills\u2026" autocomplete="off"><div id="command-list" class="command-list"></div></div>
|
|
22014
21700
|
</div></div>
|
|
22015
|
-
|
|
22016
|
-
|
|
22017
|
-
|
|
22018
|
-
|
|
22019
|
-
|
|
22020
|
-
<button type="button" id="
|
|
21701
|
+
|
|
21702
|
+
<div class="sheet" id="legend-sheet"><div class="card"><h3>Trust & verification</h3><div id="legend-body"></div><div class="modal-actions"><button type="button" id="close-legend">Close</button></div></div></div>
|
|
21703
|
+
|
|
21704
|
+
<div class="sheet" id="studio-sheet"><div class="card settings-card">
|
|
21705
|
+
<nav class="settings-nav">
|
|
21706
|
+
<div class="settings-nav-head"><b>Settings</b><button type="button" class="settings-close" id="close-studio" aria-label="Close settings">\xD7</button></div>
|
|
21707
|
+
<div class="settings-mobile-tabs" style="display:contents">
|
|
21708
|
+
<button type="button" class="on" data-settings-tab="general">General</button>
|
|
21709
|
+
<button type="button" data-settings-tab="models">Models</button>
|
|
21710
|
+
<button type="button" data-settings-tab="usage">Usage</button>
|
|
21711
|
+
<button type="button" data-settings-tab="skills">Skills</button>
|
|
21712
|
+
<button type="button" data-settings-tab="approvals">Approvals</button>
|
|
21713
|
+
<button type="button" data-settings-tab="connections">Connections</button>
|
|
21714
|
+
</div>
|
|
21715
|
+
</nav>
|
|
21716
|
+
<div class="settings-content">
|
|
21717
|
+
<section class="settings-panel on" data-settings-panel="general">
|
|
21718
|
+
<h2>General</h2><p class="sub">Keep the chat surface quiet; the controls that matter less live here.</p>
|
|
21719
|
+
<div class="setting-row"><div class="setting-copy"><b>Thinking level</b><span>How much reasoning budget the author can use.</span></div><div class="setting-control"><div class="pick" data-pick="thinking"><button type="button" class="pick-open" id="thinking-open" aria-haspopup="listbox" aria-expanded="false">Medium <span class="caret">\u25BE</span></button><div class="pick-menu" id="thinking-menu"></div><select id="thinking" aria-label="Thinking level"></select></div></div></div>
|
|
21720
|
+
<div class="setting-row"><div class="setting-copy"><b>Appearance</b><span>Switch between dark and light surfaces.</span></div><div class="setting-control"><label class="always-row"><input type="checkbox" id="theme-light"> Light mode</label></div></div>
|
|
21721
|
+
<div class="setting-row"><div class="setting-copy"><b>Command approval</b><span>Auto approval can execute commands without asking. It is deliberately kept out of the main composer.</span></div><div class="setting-control"><label class="always-row"><input type="checkbox" id="always-approve"> Always approve</label></div></div>
|
|
21722
|
+
<div class="setting-row"><div class="setting-copy"><b>Repository</b><span>${repositoryRoot}</span></div><div class="setting-control"><span class="repo-mini">${branch}</span></div></div>
|
|
21723
|
+
<div class="setting-row"><div class="setting-copy"><b>Web surface</b><span>${listenTitle}</span></div><div class="setting-control"><span class="repo-mini">${listenLabel} ${listen}</span></div></div>
|
|
21724
|
+
${portalLabel ? `<div class="setting-row"><div class="setting-copy"><b>Remote portals</b><span>Outbound control links; the author still runs on this machine.</span></div><div class="setting-control"><span class="repo-mini">${escapeHtml(portalLabel)}</span></div></div>` : ""}
|
|
21725
|
+
<div class="hidden-config"><select id="review-depth"><option value="standard">standard</option><option value="quick">quick</option><option value="paranoid">paranoid</option></select><select id="review-lens"><option value="general">general</option><option value="security">security</option><option value="performance">performance</option><option value="reliability">reliability</option><option value="stress">stress</option></select><div id="review-depth-menu"></div><button id="review-depth-open"></button><div id="review-lens-menu"></div><button id="review-lens-open"></button></div>
|
|
21726
|
+
</section>
|
|
21727
|
+
|
|
21728
|
+
<section class="settings-panel" data-settings-panel="models">
|
|
21729
|
+
<h2>Models</h2><p class="sub">Choose the author and independent reviewer. Model icons are rendered for every row, with a provider fallback when a model-specific mark is unavailable.</p>
|
|
21730
|
+
<div class="setting-row"><div class="setting-copy"><b>Author model</b><span>Writes and edits the repository.</span></div><div class="setting-control"><div class="pick" data-pick="studio-author"><button type="button" class="pick-open" id="studio-author-open" aria-haspopup="listbox" aria-expanded="false">Author <span class="caret">\u25BE</span></button><div class="pick-menu" id="studio-author-menu"></div><select id="studio-author" aria-label="Author model"></select></div></div></div>
|
|
21731
|
+
<div class="setting-row"><div class="setting-copy"><b>Review model</b><span>Prefer a different model family for genuinely independent review.</span></div><div class="setting-control"><div class="pick" data-pick="studio-review"><button type="button" class="pick-open" id="studio-review-open" aria-haspopup="listbox" aria-expanded="false">Review <span class="caret">\u25BE</span></button><div class="pick-menu" id="studio-review-menu"></div><select id="studio-review" aria-label="Review model"></select></div></div></div>
|
|
21732
|
+
<div id="studio-indep" class="settings-note"></div>
|
|
21733
|
+
</section>
|
|
21734
|
+
|
|
21735
|
+
<section class="settings-panel" data-settings-panel="usage">
|
|
21736
|
+
<h2>Usage</h2><p class="sub">Token and cost usage for this loaded chat, plus server-side phase/model totals when available.</p>
|
|
21737
|
+
<div class="usage-cards"><div class="usage-card"><span>Input</span><b id="usage-input">0</b></div><div class="usage-card"><span>Output</span><b id="usage-output">0</b></div><div class="usage-card"><span>Reasoning</span><b id="usage-reason">0</b></div><div class="usage-card"><span>Cost</span><b id="usage-cost">$0.00</b></div></div>
|
|
21738
|
+
<div class="usage-chart" id="usage-chart"><div class="usage-empty">Usage appears here as model calls complete.</div></div>
|
|
21739
|
+
<h3>By phase</h3><div class="breakdown" id="usage-phase"></div>
|
|
21740
|
+
<h3>By model</h3><div class="breakdown" id="usage-model"></div>
|
|
21741
|
+
<pre id="cost-panel" hidden></pre>
|
|
21742
|
+
</section>
|
|
21743
|
+
|
|
21744
|
+
<section class="settings-panel" data-settings-panel="skills">
|
|
21745
|
+
<h2>Skills</h2><p class="sub">Skills extend the author with repository- or agent-specific guidance.</p>
|
|
21746
|
+
<div class="settings-note">Repository and agent skills are treated as guidance, not as permission to execute commands or as proof that a check passed. That safety rule applies once here instead of being repeated as every skill's description.</div>
|
|
21747
|
+
<div id="skill-list" class="skill-list" style="margin-top:10px"></div>
|
|
21748
|
+
</section>
|
|
21749
|
+
|
|
21750
|
+
<section class="settings-panel" data-settings-panel="approvals">
|
|
21751
|
+
<h2>Approvals</h2><p class="sub">Recent command approval decisions on this machine.</p>
|
|
21752
|
+
<div id="audit-panel" class="audit-list"></div>
|
|
21753
|
+
</section>
|
|
21754
|
+
|
|
21755
|
+
<section class="settings-panel" data-settings-panel="connections">
|
|
21756
|
+
<h2>Connections</h2><p class="sub">Store provider keys locally for BYOK routes.</p>
|
|
21757
|
+
<div class="setting-row"><div class="setting-copy"><b>Provider</b><span>Choose which credential to store.</span></div><div class="setting-control"><div class="pick" data-pick="key-kind"><button type="button" class="pick-open" id="key-kind-open" aria-haspopup="listbox" aria-expanded="false">Provider <span class="caret">\u25BE</span></button><div class="pick-menu" id="key-kind-menu"></div><select id="key-kind" aria-label="API key kind"></select></div></div></div>
|
|
21758
|
+
<div class="setting-row"><div class="setting-copy"><b>API key</b><span>Saved by the local CritiqueCode runtime.</span></div><div class="setting-control"><input id="key-value" type="password" autocomplete="off" placeholder="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022"></div></div>
|
|
21759
|
+
<div class="modal-actions"><button type="button" id="save-key">Store key</button></div>
|
|
21760
|
+
</section>
|
|
22021
21761
|
</div>
|
|
22022
21762
|
</div></div>
|
|
21763
|
+
|
|
21764
|
+
<div class="sheet" id="commit-sheet"><div class="card"><h3 id="commit-sheet-title">Commit</h3><label id="commit-branch-wrap" hidden>Branch name<input id="commit-branch" autocomplete="off"></label><label>Message</label><textarea class="plain" id="commit-msg" rows="6"></textarea><div class="modal-actions"><button type="button" id="commit-cancel">Cancel</button><button type="button" id="commit-go">Commit</button></div></div></div>
|
|
21765
|
+
<div class="sheet" id="import-sheet"><div class="card"><h3>Import into repository</h3><label>Repo-relative path</label><input id="import-path"><div class="modal-actions"><button type="button" id="import-cancel">Cancel</button><button type="button" id="import-go">Write file</button></div></div></div>
|
|
22023
21766
|
<script type="application/json" id="boot">${bootJson}</script>
|
|
22024
21767
|
<script type="application/json" id="model-icons">${iconsJson}</script>
|
|
22025
21768
|
<script type="application/json" id="thinking-boot">${thinkingJson}</script>
|
|
@@ -22076,6 +21819,12 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22076
21819
|
var busy = false;
|
|
22077
21820
|
var promptQueue = [];
|
|
22078
21821
|
var applyingSnapshot = false;
|
|
21822
|
+
var usageHistory = [];
|
|
21823
|
+
var studioCosts = null;
|
|
21824
|
+
var workspaceRefreshTimer = null;
|
|
21825
|
+
var workspacePollTimer = null;
|
|
21826
|
+
var thinkingStartedAt = 0;
|
|
21827
|
+
var thinkingTimer = null;
|
|
22079
21828
|
var thinkingEl = document.getElementById("thinking");
|
|
22080
21829
|
if (thinkingEl) {
|
|
22081
21830
|
(thinkingBoot.levels || []).forEach(function (level) {
|
|
@@ -22146,8 +21895,12 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22146
21895
|
}
|
|
22147
21896
|
|
|
22148
21897
|
function modelIconHtml(option) {
|
|
22149
|
-
var
|
|
22150
|
-
|
|
21898
|
+
var provider = option && (option.getAttribute("data-provider") || "") || "other";
|
|
21899
|
+
var raw = option && (option.getAttribute("data-icon") || iconMap[provider] || "");
|
|
21900
|
+
if (raw) return raw;
|
|
21901
|
+
var label = option && (option.text || option.value) || provider || "model";
|
|
21902
|
+
var letter = String(label).replace(/^[^a-z0-9]+/i, "").charAt(0).toUpperCase() || "M";
|
|
21903
|
+
return "<span class=\\"model-fallback\\" aria-hidden=\\"true\\">" + esc(letter) + "</span>";
|
|
22151
21904
|
}
|
|
22152
21905
|
|
|
22153
21906
|
function setPickLabel(openId, text, iconHtml) {
|
|
@@ -22269,6 +22022,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22269
22022
|
render();
|
|
22270
22023
|
menu.className = "pick-menu open";
|
|
22271
22024
|
open.setAttribute("aria-expanded", "true");
|
|
22025
|
+
trapWheel(menu);
|
|
22272
22026
|
}
|
|
22273
22027
|
});
|
|
22274
22028
|
menu.addEventListener("click", function (e) { e.stopPropagation(); });
|
|
@@ -22504,10 +22258,22 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22504
22258
|
if (modelEl) modelEl.disabled = false;
|
|
22505
22259
|
sendEl.className = busy ? "steer" : "";
|
|
22506
22260
|
sendEl.setAttribute("aria-label", busy ? "Queue follow-up" : "Send");
|
|
22507
|
-
|
|
22261
|
+
sendEl.title = busy ? "Queue follow-up" : "Send";
|
|
22262
|
+
inputEl.placeholder = busy ? "Queue a follow-up\u2026" : "Message CritiqueCode\u2026";
|
|
22508
22263
|
var stop = document.getElementById("stop");
|
|
22509
22264
|
if (stop) stop.hidden = !busy;
|
|
22510
|
-
if (
|
|
22265
|
+
if (busy && !workspacePollTimer) {
|
|
22266
|
+
workspacePollTimer = setInterval(function () { refreshWorkspaceSnapshot(false); }, 1800);
|
|
22267
|
+
}
|
|
22268
|
+
if (!busy && workspacePollTimer) {
|
|
22269
|
+
clearInterval(workspacePollTimer);
|
|
22270
|
+
workspacePollTimer = null;
|
|
22271
|
+
}
|
|
22272
|
+
if (!busy) finishThinkingTimer();
|
|
22273
|
+
if (was && !busy) {
|
|
22274
|
+
refreshWorkspaceSnapshot(true);
|
|
22275
|
+
flushQueue(false);
|
|
22276
|
+
}
|
|
22511
22277
|
}
|
|
22512
22278
|
|
|
22513
22279
|
function renderQueue() {
|
|
@@ -22541,6 +22307,11 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22541
22307
|
}
|
|
22542
22308
|
|
|
22543
22309
|
function dispatchPrompt(text) {
|
|
22310
|
+
var normalized = text.trim().toLowerCase();
|
|
22311
|
+
if (normalized === "/resume" || normalized === "resume") {
|
|
22312
|
+
showResumePicker();
|
|
22313
|
+
return;
|
|
22314
|
+
}
|
|
22544
22315
|
if (text === "/login" || text === "login") {
|
|
22545
22316
|
startLogin();
|
|
22546
22317
|
return;
|
|
@@ -22591,6 +22362,29 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22591
22362
|
resetUsage();
|
|
22592
22363
|
}
|
|
22593
22364
|
|
|
22365
|
+
function deleteSession(id, title) {
|
|
22366
|
+
if (!id) return;
|
|
22367
|
+
var name = title || "this chat";
|
|
22368
|
+
if (!window.confirm("Delete " + name + "? This cannot be undone.")) return;
|
|
22369
|
+
var path = "/api/sessions/" + encodeURIComponent(id);
|
|
22370
|
+
api("DELETE", path).then(function (res) {
|
|
22371
|
+
if (res.ok) return res;
|
|
22372
|
+
if (res.status !== 404 && res.status !== 405) return res;
|
|
22373
|
+
return api("POST", "/api/sessions/delete", { id: id });
|
|
22374
|
+
}).then(function (res) {
|
|
22375
|
+
if (!res || !res.ok) {
|
|
22376
|
+
if (!res) return;
|
|
22377
|
+
return readError(res, "Session deletion is not available in this build.").then(function (msg) { addBlock("alert", msg); });
|
|
22378
|
+
}
|
|
22379
|
+
return api("GET", "/api/snapshot").then(function (fresh) {
|
|
22380
|
+
if (!fresh.ok) return;
|
|
22381
|
+
return fresh.json().then(function (body) {
|
|
22382
|
+
if (body.sessions) renderSessions(body.sessions, body.session_id || body.id || activeSessionId);
|
|
22383
|
+
});
|
|
22384
|
+
});
|
|
22385
|
+
}).catch(function () { addBlock("alert", "Could not delete that chat."); });
|
|
22386
|
+
}
|
|
22387
|
+
|
|
22594
22388
|
function renderSessions(list, activeId) {
|
|
22595
22389
|
allSessions = list || allSessions;
|
|
22596
22390
|
if (!sessionsEl) return;
|
|
@@ -22599,20 +22393,104 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22599
22393
|
(allSessions || []).filter(function (item) {
|
|
22600
22394
|
return !q || String(item.title || "").toLowerCase().indexOf(q) >= 0;
|
|
22601
22395
|
}).forEach(function (item) {
|
|
22396
|
+
var row = document.createElement("div");
|
|
22397
|
+
row.className = "session-row" + (item.id === activeId ? " on" : "");
|
|
22602
22398
|
var btn = document.createElement("button");
|
|
22603
22399
|
btn.type = "button";
|
|
22604
|
-
btn.className = "session-item"
|
|
22400
|
+
btn.className = "session-item";
|
|
22605
22401
|
btn.textContent = item.title || "Session";
|
|
22606
22402
|
btn.title = item.title || item.id;
|
|
22607
22403
|
btn.addEventListener("click", function () {
|
|
22608
22404
|
if (item.id === activeSessionId) return;
|
|
22405
|
+
api("POST", "/api/sessions/select", { id: item.id }).catch(function () { addBlock("alert", "Could not open that chat."); });
|
|
22406
|
+
if (window.innerWidth <= 760) { layout.rail = false; applyLayout(); }
|
|
22407
|
+
});
|
|
22408
|
+
btn.addEventListener("dblclick", function (e) {
|
|
22409
|
+
e.preventDefault();
|
|
22410
|
+
e.stopPropagation();
|
|
22411
|
+
var next = window.prompt("Rename chat", item.title || "Session");
|
|
22412
|
+
if (!next) return;
|
|
22413
|
+
renameSession(item.id, next.trim());
|
|
22414
|
+
});
|
|
22415
|
+
var del = document.createElement("button");
|
|
22416
|
+
del.type = "button";
|
|
22417
|
+
del.className = "session-delete";
|
|
22418
|
+
del.title = "Delete chat";
|
|
22419
|
+
del.setAttribute("aria-label", "Delete " + (item.title || "chat"));
|
|
22420
|
+
del.innerHTML = "<svg width=\\"13\\" height=\\"13\\" viewBox=\\"0 0 16 16\\" fill=\\"none\\"><path d=\\"M3.5 4.5h9M6 4.5V3h4v1.5M5 6.5v6M8 6.5v6M11 6.5v6M4.5 4.5l.5 9h6l.5-9\\" stroke=\\"currentColor\\" stroke-linecap=\\"round\\"/></svg>";
|
|
22421
|
+
del.addEventListener("click", function (e) { e.stopPropagation(); deleteSession(item.id, item.title || "this chat"); });
|
|
22422
|
+
row.appendChild(btn); row.appendChild(del); sessionsEl.appendChild(row);
|
|
22423
|
+
});
|
|
22424
|
+
activeSessionId = activeId || activeSessionId;
|
|
22425
|
+
}
|
|
22426
|
+
|
|
22427
|
+
function renameSession(id, title) {
|
|
22428
|
+
if (!id || !title) return;
|
|
22429
|
+
api("POST", "/api/sessions/rename", { id: id, title: title }).then(function (res) {
|
|
22430
|
+
if (!res.ok) return readError(res, "Could not rename that chat.").then(function (msg) { addBlock("alert", msg); });
|
|
22431
|
+
return res.json().then(function (body) {
|
|
22432
|
+
if (body.sessions) renderSessions(body.sessions, body.id || activeSessionId);
|
|
22433
|
+
if (body.title) setSessionTitle(body.title);
|
|
22434
|
+
});
|
|
22435
|
+
}).catch(function () { addBlock("alert", "Could not rename that chat."); });
|
|
22436
|
+
}
|
|
22437
|
+
|
|
22438
|
+
function showResumePicker() {
|
|
22439
|
+
showFeed();
|
|
22440
|
+
turnEl = null;
|
|
22441
|
+
assistantEl = null;
|
|
22442
|
+
var wrap = document.createElement("div");
|
|
22443
|
+
wrap.className = "resume-picker";
|
|
22444
|
+
var head = document.createElement("div");
|
|
22445
|
+
head.className = "resume-head";
|
|
22446
|
+
var title = document.createElement("strong");
|
|
22447
|
+
title.textContent = "Resume a chat";
|
|
22448
|
+
var hint = document.createElement("span");
|
|
22449
|
+
hint.textContent = String((allSessions || []).length) + " chats";
|
|
22450
|
+
head.appendChild(title);
|
|
22451
|
+
head.appendChild(hint);
|
|
22452
|
+
wrap.appendChild(head);
|
|
22453
|
+
var list = document.createElement("div");
|
|
22454
|
+
list.className = "resume-list";
|
|
22455
|
+
var sessions = (allSessions || []).filter(function (item) { return item.id !== activeSessionId; });
|
|
22456
|
+
if (!sessions.length) {
|
|
22457
|
+
var empty = document.createElement("div");
|
|
22458
|
+
empty.className = "resume-empty";
|
|
22459
|
+
empty.textContent = "No other chats yet.";
|
|
22460
|
+
list.appendChild(empty);
|
|
22461
|
+
}
|
|
22462
|
+
sessions.forEach(function (item) {
|
|
22463
|
+
var row = document.createElement("button");
|
|
22464
|
+
row.type = "button";
|
|
22465
|
+
row.className = "resume-chat";
|
|
22466
|
+
var copy = document.createElement("span");
|
|
22467
|
+
copy.className = "resume-copy";
|
|
22468
|
+
var chatTitle = document.createElement("strong");
|
|
22469
|
+
chatTitle.textContent = item.title || "Untitled chat";
|
|
22470
|
+
copy.appendChild(chatTitle);
|
|
22471
|
+
if (item.updated_at || item.created_at) {
|
|
22472
|
+
var time = document.createElement("span");
|
|
22473
|
+
var value = item.updated_at || item.created_at;
|
|
22474
|
+
try {
|
|
22475
|
+
time.textContent = new Date(value).toLocaleString([], { dateStyle: "medium", timeStyle: "short" });
|
|
22476
|
+
} catch (e) { time.textContent = ""; }
|
|
22477
|
+
copy.appendChild(time);
|
|
22478
|
+
}
|
|
22479
|
+
var arrow = document.createElement("span");
|
|
22480
|
+
arrow.className = "resume-arrow";
|
|
22481
|
+
arrow.textContent = "\u203A";
|
|
22482
|
+
row.appendChild(copy);
|
|
22483
|
+
row.appendChild(arrow);
|
|
22484
|
+
row.addEventListener("click", function () {
|
|
22609
22485
|
api("POST", "/api/sessions/select", { id: item.id }).catch(function () {
|
|
22610
|
-
addBlock("alert", "Could not
|
|
22486
|
+
addBlock("alert", "Could not resume that chat.");
|
|
22611
22487
|
});
|
|
22612
22488
|
});
|
|
22613
|
-
|
|
22489
|
+
list.appendChild(row);
|
|
22614
22490
|
});
|
|
22615
|
-
|
|
22491
|
+
wrap.appendChild(list);
|
|
22492
|
+
feedEl.appendChild(wrap);
|
|
22493
|
+
scrollMain();
|
|
22616
22494
|
}
|
|
22617
22495
|
|
|
22618
22496
|
function replayEvents(events) {
|
|
@@ -22640,12 +22518,14 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22640
22518
|
showFeed();
|
|
22641
22519
|
turnEl = null;
|
|
22642
22520
|
assistantEl = null;
|
|
22521
|
+
var copy = text == null ? "" : String(text);
|
|
22522
|
+
if (className === "note") {
|
|
22523
|
+
var last = feedEl.lastElementChild;
|
|
22524
|
+
if (last && last.classList.contains("note") && last.textContent === copy) return last;
|
|
22525
|
+
}
|
|
22643
22526
|
var node = document.createElement("div");
|
|
22644
22527
|
node.className = className;
|
|
22645
|
-
node.textContent =
|
|
22646
|
-
if (className !== "note") {
|
|
22647
|
-
stampTrust(node, trust || (className === "review-card" ? "evidence" : className === "alert" ? "unverified" : "unverified"));
|
|
22648
|
-
}
|
|
22528
|
+
node.textContent = copy;
|
|
22649
22529
|
feedEl.appendChild(node);
|
|
22650
22530
|
scrollMain();
|
|
22651
22531
|
return node;
|
|
@@ -22681,112 +22561,165 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22681
22561
|
scrollMain();
|
|
22682
22562
|
}
|
|
22683
22563
|
|
|
22684
|
-
function
|
|
22685
|
-
if (name === "critique_task") return;
|
|
22564
|
+
function activityRoot() {
|
|
22686
22565
|
if (!turnEl) {
|
|
22687
22566
|
showFeed();
|
|
22688
22567
|
turnEl = document.createElement("div");
|
|
22689
22568
|
turnEl.className = "turn";
|
|
22690
22569
|
feedEl.appendChild(turnEl);
|
|
22691
22570
|
}
|
|
22692
|
-
var
|
|
22693
|
-
if (!
|
|
22694
|
-
|
|
22695
|
-
|
|
22696
|
-
|
|
22697
|
-
|
|
22698
|
-
var list = document.createElement("div");
|
|
22699
|
-
list.className = "step-list";
|
|
22700
|
-
steps.appendChild(summary);
|
|
22701
|
-
steps.appendChild(list);
|
|
22702
|
-
if (assistantEl) turnEl.insertBefore(steps, assistantEl);
|
|
22703
|
-
else turnEl.appendChild(steps);
|
|
22704
|
-
}
|
|
22705
|
-
var listEl = steps.querySelector(".step-list");
|
|
22706
|
-
var line = (name || "tool") + " " + (phase || "");
|
|
22707
|
-
if (detail) line += "\\n" + detail;
|
|
22708
|
-
listEl.textContent = (listEl.textContent ? listEl.textContent + "\\n" : "") + line;
|
|
22709
|
-
if (!steps.querySelector(".trust")) {
|
|
22710
|
-
var t = document.createElement("div");
|
|
22711
|
-
t.className = "trust unverified";
|
|
22712
|
-
t.textContent = name === "critique_cli" ? "Not Evidence \xB7 sidecar JSON" : "Not Evidence";
|
|
22713
|
-
steps.insertBefore(t, steps.firstChild);
|
|
22571
|
+
var root = turnEl.querySelector(".activity");
|
|
22572
|
+
if (!root) {
|
|
22573
|
+
root = document.createElement("div");
|
|
22574
|
+
root.className = "activity";
|
|
22575
|
+
if (assistantEl) turnEl.insertBefore(root, assistantEl);
|
|
22576
|
+
else turnEl.appendChild(root);
|
|
22714
22577
|
}
|
|
22578
|
+
return root;
|
|
22579
|
+
}
|
|
22580
|
+
|
|
22581
|
+
function humanToolName(name) {
|
|
22582
|
+
return String(name || "tool").replace(/_/g, " ");
|
|
22583
|
+
}
|
|
22584
|
+
|
|
22585
|
+
function addTool(name, phase, detail) {
|
|
22586
|
+
if (name === "critique_task") return;
|
|
22587
|
+
var root = activityRoot();
|
|
22588
|
+
var node = document.createElement("details");
|
|
22589
|
+
var state = /fail|error|denied/i.test(String(phase || "")) ? "failed" : /start|run|progress/i.test(String(phase || "")) ? "running" : "done";
|
|
22590
|
+
node.className = "tool-event " + state;
|
|
22591
|
+
if (detail) node.open = false;
|
|
22592
|
+
var summary = document.createElement("summary");
|
|
22593
|
+
var dot = document.createElement("span"); dot.className = "tool-dot";
|
|
22594
|
+
var label = document.createElement("span"); label.className = "tool-name"; label.textContent = humanToolName(name);
|
|
22595
|
+
var p = document.createElement("span"); p.className = "tool-phase"; p.textContent = phase || "";
|
|
22596
|
+
summary.appendChild(dot); summary.appendChild(label); if (phase) summary.appendChild(p);
|
|
22597
|
+
node.appendChild(summary);
|
|
22598
|
+
if (detail) { var body = document.createElement("div"); body.className = "tool-detail"; body.textContent = detail; node.appendChild(body); }
|
|
22599
|
+
root.appendChild(node);
|
|
22600
|
+
scheduleWorkspaceRefresh();
|
|
22715
22601
|
scrollMain();
|
|
22716
22602
|
}
|
|
22717
22603
|
|
|
22718
|
-
function
|
|
22719
|
-
if (
|
|
22720
|
-
|
|
22721
|
-
|
|
22722
|
-
|
|
22723
|
-
|
|
22604
|
+
function finishThinkingTimer() {
|
|
22605
|
+
if (thinkingTimer) { clearInterval(thinkingTimer); thinkingTimer = null; }
|
|
22606
|
+
var node = turnEl && turnEl.querySelector(".think");
|
|
22607
|
+
if (node && thinkingStartedAt && !applyingSnapshot) {
|
|
22608
|
+
var s = node.querySelector("summary span:last-child");
|
|
22609
|
+
if (s) s.textContent = "Thinking \xB7 " + Math.max(1, Math.round((Date.now() - thinkingStartedAt) / 1000)) + "s";
|
|
22724
22610
|
}
|
|
22725
|
-
|
|
22611
|
+
thinkingStartedAt = 0;
|
|
22612
|
+
}
|
|
22613
|
+
|
|
22614
|
+
function addThink(text) {
|
|
22615
|
+
var root = activityRoot();
|
|
22616
|
+
var node = root.querySelector(".think");
|
|
22726
22617
|
if (!node) {
|
|
22727
22618
|
node = document.createElement("details");
|
|
22728
22619
|
node.className = "think";
|
|
22729
|
-
|
|
22730
|
-
|
|
22731
|
-
|
|
22732
|
-
|
|
22733
|
-
|
|
22620
|
+
var summary = document.createElement("summary");
|
|
22621
|
+
summary.innerHTML = "<span class=\\"tool-dot\\"></span><span>Thinking</span>";
|
|
22622
|
+
var body = document.createElement("div");
|
|
22623
|
+
node.appendChild(summary); node.appendChild(body); root.appendChild(node);
|
|
22624
|
+
if (!applyingSnapshot) {
|
|
22625
|
+
thinkingStartedAt = Date.now();
|
|
22626
|
+
thinkingTimer = setInterval(function () {
|
|
22627
|
+
if (!thinkingStartedAt) return;
|
|
22628
|
+
var label = summary.querySelector("span:last-child");
|
|
22629
|
+
if (label) label.textContent = "Thinking \xB7 " + Math.max(1, Math.round((Date.now() - thinkingStartedAt) / 1000)) + "s";
|
|
22630
|
+
}, 1000);
|
|
22631
|
+
}
|
|
22632
|
+
}
|
|
22633
|
+
var bodyEl = node.querySelector("div");
|
|
22634
|
+
if (bodyEl) bodyEl.textContent = (bodyEl.textContent || "") + (text || "");
|
|
22734
22635
|
scrollMain();
|
|
22735
22636
|
}
|
|
22736
22637
|
|
|
22737
22638
|
function resetUsage() {
|
|
22738
|
-
tokensIn = 0;
|
|
22739
|
-
|
|
22740
|
-
|
|
22741
|
-
contextUsed = 0;
|
|
22742
|
-
lastInput = 0;
|
|
22743
|
-
lastOutput = 0;
|
|
22744
|
-
lastReason = 0;
|
|
22745
|
-
costUsd = 0;
|
|
22746
|
-
var el = document.getElementById("cost");
|
|
22747
|
-
if (el) {
|
|
22748
|
-
el.hidden = true;
|
|
22749
|
-
el.textContent = "";
|
|
22750
|
-
}
|
|
22751
|
-
updateContextRing();
|
|
22639
|
+
tokensIn = 0; tokensOut = 0; tokensReason = 0; contextUsed = 0;
|
|
22640
|
+
lastInput = 0; lastOutput = 0; lastReason = 0; costUsd = 0; usageHistory = [];
|
|
22641
|
+
renderUsagePanel(studioCosts);
|
|
22752
22642
|
}
|
|
22753
22643
|
|
|
22754
22644
|
function addUsage(ev) {
|
|
22755
22645
|
lastInput = Number(ev.input_tokens || 0);
|
|
22756
22646
|
lastOutput = Number(ev.output_tokens || 0);
|
|
22757
22647
|
lastReason = Number(ev.reasoning_tokens || 0);
|
|
22758
|
-
tokensIn += lastInput;
|
|
22759
|
-
|
|
22760
|
-
|
|
22761
|
-
|
|
22648
|
+
tokensIn += lastInput; tokensOut += lastOutput; tokensReason += lastReason;
|
|
22649
|
+
var eventCost = Number(ev.cost_usd || 0);
|
|
22650
|
+
if (!eventCost) eventCost = estimateUsageCostUsd(lastInput, lastOutput, lastReason);
|
|
22651
|
+
costUsd += eventCost;
|
|
22762
22652
|
contextUsed = lastInput + lastOutput + lastReason;
|
|
22763
|
-
|
|
22764
|
-
|
|
22765
|
-
|
|
22766
|
-
|
|
22653
|
+
usageHistory.push({
|
|
22654
|
+
input: lastInput, output: lastOutput, reasoning: lastReason,
|
|
22655
|
+
cost: Number(ev.cost_usd || 0), model: ev.model || "", phase: ev.source || ev.phase || "author", at: Date.now()
|
|
22656
|
+
});
|
|
22657
|
+
if (usageHistory.length > 80) usageHistory = usageHistory.slice(-80);
|
|
22658
|
+
renderUsagePanel(studioCosts);
|
|
22659
|
+
}
|
|
22660
|
+
|
|
22661
|
+
function updateContextRing() { renderUsagePanel(studioCosts); }
|
|
22662
|
+
|
|
22663
|
+
function fmtNum(value) { return Number(value || 0).toLocaleString(); }
|
|
22664
|
+
function fmtCost(value) { return "$" + Number(value || 0).toFixed(Number(value || 0) < 1 ? 4 : 2); }
|
|
22665
|
+
|
|
22666
|
+
function estimateUsageCostUsd(input, output, reasoning) {
|
|
22667
|
+
return Number(input || 0) * 0.0000001 + Number(output || 0) * 0.0000004 + Number(reasoning || 0) * 0.0000002;
|
|
22668
|
+
}
|
|
22669
|
+
|
|
22670
|
+
function renderBars(targetId, rows) {
|
|
22671
|
+
var target = document.getElementById(targetId);
|
|
22672
|
+
if (!target) return;
|
|
22673
|
+
target.innerHTML = "";
|
|
22674
|
+
if (!rows || !rows.length) { target.innerHTML = "<div class=\\"usage-empty\\" style=\\"height:52px\\">No data yet</div>"; return; }
|
|
22675
|
+
var max = Math.max.apply(null, rows.map(function (r) { return r.value; }).concat([1]));
|
|
22676
|
+
rows.slice(0, 10).forEach(function (row) {
|
|
22677
|
+
var el = document.createElement("div"); el.className = "break-row";
|
|
22678
|
+
var name = document.createElement("span"); name.textContent = row.label;
|
|
22679
|
+
var track = document.createElement("div"); track.className = "break-track";
|
|
22680
|
+
var fill = document.createElement("div"); fill.className = "break-fill"; fill.style.width = Math.max(2, row.value / max * 100) + "%"; track.appendChild(fill);
|
|
22681
|
+
var val = document.createElement("span"); val.className = "break-val"; val.textContent = fmtNum(row.value);
|
|
22682
|
+
el.appendChild(name); el.appendChild(track); el.appendChild(val); target.appendChild(el);
|
|
22683
|
+
});
|
|
22684
|
+
}
|
|
22685
|
+
|
|
22686
|
+
function renderUsagePanel(costs) {
|
|
22687
|
+
var totalInput = costs && Number(costs.total_input || 0) || tokensIn;
|
|
22688
|
+
var totalOutput = costs && Number(costs.total_output || 0) || tokensOut;
|
|
22689
|
+
var ui = document.getElementById("usage-input"); if (ui) ui.textContent = fmtNum(totalInput);
|
|
22690
|
+
var uo = document.getElementById("usage-output"); if (uo) uo.textContent = fmtNum(totalOutput);
|
|
22691
|
+
var ur = document.getElementById("usage-reason"); if (ur) ur.textContent = fmtNum(tokensReason);
|
|
22692
|
+
var reported = costUsd || (costs && Number(costs.total_cost_usd || 0)) || 0;
|
|
22693
|
+
var display = reported > 0 ? reported : (costs && Number(costs.estimated_cost_usd || 0)) || estimateUsageCostUsd(totalInput, totalOutput, tokensReason);
|
|
22694
|
+
var estimated = reported <= 0 && display > 0;
|
|
22695
|
+
var uc = document.getElementById("usage-cost");
|
|
22696
|
+
if (uc) uc.textContent = (estimated ? "~" : "") + fmtCost(display);
|
|
22697
|
+
var chart = document.getElementById("usage-chart");
|
|
22698
|
+
if (chart) {
|
|
22699
|
+
if (!usageHistory.length) chart.innerHTML = "<div class=\\"usage-empty\\">Usage appears here as model calls complete.</div>";
|
|
22700
|
+
else {
|
|
22701
|
+
var vals = usageHistory.map(function (r) { return r.input + r.output + r.reasoning; });
|
|
22702
|
+
var max = Math.max.apply(null, vals.concat([1]));
|
|
22703
|
+
var w = 640, h = 150, gap = 2, bw = Math.max(2, (w - (vals.length - 1) * gap) / vals.length);
|
|
22704
|
+
var rects = vals.map(function (v, i) { var bh = Math.max(2, v / max * 126); var x = i * (bw + gap); return "<rect x=\\"" + x.toFixed(1) + "\\" y=\\"" + (140 - bh).toFixed(1) + "\\" width=\\"" + bw.toFixed(1) + "\\" height=\\"" + bh.toFixed(1) + "\\" rx=\\"1.5\\" fill=\\"#827b72\\"><title>" + fmtNum(v) + " tokens</title></rect>"; }).join("");
|
|
22705
|
+
chart.innerHTML = "<svg viewBox=\\"0 0 640 150\\" preserveAspectRatio=\\"none\\" aria-label=\\"Token usage by model call\\"><line x1=\\"0\\" y1=\\"140\\" x2=\\"640\\" y2=\\"140\\" stroke=\\"rgba(255,255,255,.08)\\"/>" + rects + "</svg>";
|
|
22706
|
+
}
|
|
22707
|
+
}
|
|
22708
|
+
var phaseRows = [];
|
|
22709
|
+
if (costs && costs.by_phase) Object.keys(costs.by_phase).forEach(function (k) { var v = costs.by_phase[k] || {}; phaseRows.push({ label:k, value:Number(v.input_tokens||0)+Number(v.output_tokens||0) }); });
|
|
22710
|
+
else {
|
|
22711
|
+
var phase = {}; usageHistory.forEach(function (r) { var k=r.phase||"author"; phase[k]=(phase[k]||0)+r.input+r.output+r.reasoning; });
|
|
22712
|
+
Object.keys(phase).forEach(function (k) { phaseRows.push({label:k,value:phase[k]}); });
|
|
22767
22713
|
}
|
|
22768
|
-
|
|
22769
|
-
|
|
22770
|
-
|
|
22771
|
-
|
|
22772
|
-
|
|
22773
|
-
|
|
22774
|
-
|
|
22775
|
-
|
|
22776
|
-
|
|
22777
|
-
var ring = document.getElementById("ctx-ring");
|
|
22778
|
-
if (fill) fill.setAttribute("stroke-dashoffset", String(circ * (1 - pct)));
|
|
22779
|
-
var text = used.toLocaleString() + " / " + contextCap.toLocaleString() + " tokens"
|
|
22780
|
-
+ "\\n" + Math.round(pct * 100) + "% of this chat"
|
|
22781
|
-
+ "\\ninput " + lastInput.toLocaleString()
|
|
22782
|
-
+ " \xB7 output " + lastOutput.toLocaleString()
|
|
22783
|
-
+ (lastReason ? " \xB7 reasoning " + lastReason.toLocaleString() : "")
|
|
22784
|
-
+ (costUsd ? "\\n$" + costUsd.toFixed(4) : "");
|
|
22785
|
-
if (tip) tip.textContent = text;
|
|
22786
|
-
var label = document.getElementById("ctx-label");
|
|
22787
|
-
if (label) label.textContent = "ctx " + Math.round(pct * 100) + "%";
|
|
22788
|
-
if (ring) ring.title = text.replace(/\\n/g, " \xB7 ");
|
|
22789
|
-
if (fill) fill.style.stroke = pct > 0.85 ? "#e36d6d" : pct > 0.6 ? "#d4a017" : "#ececec";
|
|
22714
|
+
renderBars("usage-phase", phaseRows);
|
|
22715
|
+
var modelRows = [];
|
|
22716
|
+
if (costs && costs.by_model) Object.keys(costs.by_model).forEach(function (k) { var v=costs.by_model[k]||{}; modelRows.push({label:k.replace(/^openrouter\\//,""),value:Number(v.input_tokens||0)+Number(v.output_tokens||0)}); });
|
|
22717
|
+
else {
|
|
22718
|
+
var models={}; usageHistory.forEach(function(r){var k=r.model||"current model";models[k]=(models[k]||0)+r.input+r.output+r.reasoning;});
|
|
22719
|
+
Object.keys(models).forEach(function(k){modelRows.push({label:k.replace(/^openrouter\\//,""),value:models[k]});});
|
|
22720
|
+
}
|
|
22721
|
+
modelRows.sort(function(a,b){return b.value-a.value;});
|
|
22722
|
+
renderBars("usage-model", modelRows);
|
|
22790
22723
|
}
|
|
22791
22724
|
|
|
22792
22725
|
function addAgent(detail, phase) {
|
|
@@ -22816,101 +22749,186 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22816
22749
|
if (btn) btn.innerHTML = "\u2387 " + esc(currentBranch) + " <span class=\\"caret\\">\u25BE</span>";
|
|
22817
22750
|
}
|
|
22818
22751
|
|
|
22752
|
+
function normalizeChangeFiles(data) {
|
|
22753
|
+
var files = (data && data.files) || [];
|
|
22754
|
+
if ((!files || !files.length) && data && data.changed_paths && data.changed_paths.length) {
|
|
22755
|
+
files = data.changed_paths.map(function (path) { return { path: path, added: 0, deleted: 0, kind: "modified" }; });
|
|
22756
|
+
}
|
|
22757
|
+
return files || [];
|
|
22758
|
+
}
|
|
22759
|
+
|
|
22760
|
+
function renderPatchInto(container, patch, path) {
|
|
22761
|
+
var head = document.createElement("div");
|
|
22762
|
+
head.className = "diff-file-head";
|
|
22763
|
+
head.textContent = path;
|
|
22764
|
+
container.appendChild(head);
|
|
22765
|
+
var body = document.createElement("div");
|
|
22766
|
+
body.className = "diff-patch";
|
|
22767
|
+
var patchStr = String(patch || "");
|
|
22768
|
+
if (!patchStr.trim()) {
|
|
22769
|
+
var empty = document.createElement("div");
|
|
22770
|
+
empty.className = "hunk";
|
|
22771
|
+
empty.textContent = "No textual diff available.";
|
|
22772
|
+
body.appendChild(empty);
|
|
22773
|
+
container.appendChild(body);
|
|
22774
|
+
return;
|
|
22775
|
+
}
|
|
22776
|
+
var oldLn = 0;
|
|
22777
|
+
var newLn = 0;
|
|
22778
|
+
patchStr.split("\\n").forEach(function (line) {
|
|
22779
|
+
if (line.indexOf("@@") === 0) {
|
|
22780
|
+
var hunk = line.match(/@@ -(\\d+)(?:,\\d+)? \\+(\\d+)/);
|
|
22781
|
+
if (hunk) { oldLn = Number(hunk[1]) - 1; newLn = Number(hunk[2]) - 1; }
|
|
22782
|
+
var hunkEl = document.createElement("div");
|
|
22783
|
+
hunkEl.className = "hunk";
|
|
22784
|
+
hunkEl.textContent = line;
|
|
22785
|
+
body.appendChild(hunkEl);
|
|
22786
|
+
return;
|
|
22787
|
+
}
|
|
22788
|
+
if (line.indexOf("diff ") === 0 || line.indexOf("index ") === 0 || line.indexOf("---") === 0 || line.indexOf("+++") === 0) {
|
|
22789
|
+
var meta = document.createElement("div");
|
|
22790
|
+
meta.className = "hunk";
|
|
22791
|
+
meta.textContent = line;
|
|
22792
|
+
body.appendChild(meta);
|
|
22793
|
+
return;
|
|
22794
|
+
}
|
|
22795
|
+
var kind = "ctx";
|
|
22796
|
+
var left = "";
|
|
22797
|
+
var right = "";
|
|
22798
|
+
if (line.charAt(0) === "+") { kind = "add"; newLn += 1; right = String(newLn); }
|
|
22799
|
+
else if (line.charAt(0) === "-") { kind = "del"; oldLn += 1; left = String(oldLn); }
|
|
22800
|
+
else { oldLn += 1; newLn += 1; left = String(oldLn); right = String(newLn); }
|
|
22801
|
+
var row = document.createElement("div");
|
|
22802
|
+
row.className = "row " + kind;
|
|
22803
|
+
var a = document.createElement("span"); a.className = "ln"; a.textContent = left;
|
|
22804
|
+
var b = document.createElement("span"); b.className = "ln"; b.textContent = right;
|
|
22805
|
+
var code = document.createElement("span"); code.className = "code"; code.textContent = line;
|
|
22806
|
+
row.appendChild(a); row.appendChild(b); row.appendChild(code);
|
|
22807
|
+
body.appendChild(row);
|
|
22808
|
+
});
|
|
22809
|
+
container.appendChild(body);
|
|
22810
|
+
}
|
|
22811
|
+
|
|
22812
|
+
function loadAllDiffs(files) {
|
|
22813
|
+
var diffEl = document.getElementById("diff");
|
|
22814
|
+
var view = document.getElementById("file-view");
|
|
22815
|
+
var preview = document.getElementById("preview");
|
|
22816
|
+
var title = document.getElementById("diff-title");
|
|
22817
|
+
var back = document.getElementById("all-changes");
|
|
22818
|
+
if (back) back.hidden = true;
|
|
22819
|
+
if (title) title.textContent = files.length + (files.length === 1 ? " changed file" : " changed files");
|
|
22820
|
+
if (diffEl) { diffEl.hidden = false; diffEl.innerHTML = ""; }
|
|
22821
|
+
if (view) view.hidden = true;
|
|
22822
|
+
if (preview) preview.hidden = true;
|
|
22823
|
+
if (!files || !files.length) {
|
|
22824
|
+
if (diffEl) diffEl.innerHTML = "<div class=\\"diff-loading\\">No changed files.</div>";
|
|
22825
|
+
return;
|
|
22826
|
+
}
|
|
22827
|
+
var loading = document.createElement("div");
|
|
22828
|
+
loading.className = "diff-loading";
|
|
22829
|
+
loading.textContent = "Loading diffs\u2026";
|
|
22830
|
+
if (diffEl) diffEl.appendChild(loading);
|
|
22831
|
+
var paths = files.map(function (f) { return f.path; });
|
|
22832
|
+
Promise.all(paths.map(function (path) {
|
|
22833
|
+
return api("GET", "/api/changes?path=" + encodeURIComponent(path))
|
|
22834
|
+
.then(function (res) { return res.json().then(function (body) { return { path: path, patch: body.patch }; }); })
|
|
22835
|
+
.catch(function () { return { path: path, patch: "" }; });
|
|
22836
|
+
})).then(function (results) {
|
|
22837
|
+
if (!diffEl) return;
|
|
22838
|
+
diffEl.innerHTML = "";
|
|
22839
|
+
results.forEach(function (result) {
|
|
22840
|
+
var section = document.createElement("section");
|
|
22841
|
+
section.className = "diff-file";
|
|
22842
|
+
renderPatchInto(section, result.patch || "No textual diff available.", result.path);
|
|
22843
|
+
diffEl.appendChild(section);
|
|
22844
|
+
});
|
|
22845
|
+
});
|
|
22846
|
+
}
|
|
22847
|
+
|
|
22848
|
+
function loadFileContent(path, btn) {
|
|
22849
|
+
selectedPath = path;
|
|
22850
|
+
document.querySelectorAll(".tree button").forEach(function (el) {
|
|
22851
|
+
el.classList.toggle("on", el.getAttribute("data-path") === path);
|
|
22852
|
+
});
|
|
22853
|
+
if (btn) btn.classList.add("on");
|
|
22854
|
+
var title = document.getElementById("diff-title");
|
|
22855
|
+
var diffEl = document.getElementById("diff");
|
|
22856
|
+
var view = document.getElementById("file-view");
|
|
22857
|
+
var preview = document.getElementById("preview");
|
|
22858
|
+
var back = document.getElementById("all-changes");
|
|
22859
|
+
if (back) back.hidden = false;
|
|
22860
|
+
if (title) title.textContent = path;
|
|
22861
|
+
if (diffEl) diffEl.hidden = true;
|
|
22862
|
+
if (preview) preview.hidden = true;
|
|
22863
|
+
if (view) {
|
|
22864
|
+
view.hidden = false;
|
|
22865
|
+
view.textContent = "Loading\u2026";
|
|
22866
|
+
}
|
|
22867
|
+
var pane = document.getElementById("changes-pane");
|
|
22868
|
+
if (pane) pane.classList.add("open");
|
|
22869
|
+
api("GET", "/api/file?path=" + encodeURIComponent(path))
|
|
22870
|
+
.then(function (res) {
|
|
22871
|
+
if (!res.ok) throw new Error("Could not load file");
|
|
22872
|
+
return res.json();
|
|
22873
|
+
})
|
|
22874
|
+
.then(function (file) {
|
|
22875
|
+
if (view) {
|
|
22876
|
+
view.hidden = false;
|
|
22877
|
+
view.textContent = String(file.text || "");
|
|
22878
|
+
}
|
|
22879
|
+
if (preview && /\\.html?$/i.test(path)) {
|
|
22880
|
+
preview.hidden = false;
|
|
22881
|
+
preview.srcdoc = String(file.text || "");
|
|
22882
|
+
}
|
|
22883
|
+
})
|
|
22884
|
+
.catch(function () {
|
|
22885
|
+
if (view) view.textContent = "Could not load " + path;
|
|
22886
|
+
});
|
|
22887
|
+
}
|
|
22888
|
+
|
|
22819
22889
|
function renderChanges(data) {
|
|
22820
22890
|
var list = document.getElementById("change-list");
|
|
22821
22891
|
var sum = document.getElementById("changes-sum");
|
|
22822
|
-
var files = (data
|
|
22823
|
-
var
|
|
22824
|
-
var
|
|
22892
|
+
var files = normalizeChangeFiles(data);
|
|
22893
|
+
var computedAdded = files.reduce(function (n, f) { return n + Number(f.added || 0); }, 0);
|
|
22894
|
+
var computedDeleted = files.reduce(function (n, f) { return n + Number(f.deleted || 0); }, 0);
|
|
22895
|
+
var added = Number(data && data.added || 0) || computedAdded;
|
|
22896
|
+
var deleted = Number(data && data.deleted || 0) || computedDeleted;
|
|
22825
22897
|
var branch = data && (data.branch || data.text) ? (data.branch || data.text) : currentBranch;
|
|
22826
22898
|
if (branch) setBranchLabel(branch);
|
|
22827
|
-
if (sum) sum.textContent = branch + "
|
|
22828
|
-
var
|
|
22829
|
-
var minus = document.getElementById("changes-minus");
|
|
22830
|
-
if (plus) plus.textContent = "+" + added;
|
|
22831
|
-
if (
|
|
22832
|
-
var ship = document.getElementById("ship-commit");
|
|
22833
|
-
if (ship) ship.disabled = files.length === 0;
|
|
22899
|
+
if (sum) sum.textContent = branch + " \xB7 " + files.length + (files.length === 1 ? " changed file" : " changed files") + ((added || deleted) ? " \xB7 +" + added + " \u2212" + deleted : "");
|
|
22900
|
+
var count = document.getElementById("changes-count"); if (count) count.textContent = String(files.length);
|
|
22901
|
+
var plus = document.getElementById("changes-plus"); var minus = document.getElementById("changes-minus");
|
|
22902
|
+
if (plus) plus.textContent = "+" + added; if (minus) minus.textContent = "\u2212" + deleted;
|
|
22903
|
+
var pill = document.getElementById("changes-pill"); if (pill) pill.title = files.length ? files.length + " changed file" + (files.length === 1 ? "" : "s") + " \xB7 +" + added + " \u2212" + deleted : "No working-tree changes";
|
|
22834
22904
|
fileKinds = {};
|
|
22835
22905
|
files.forEach(function (file) { fileKinds[file.path] = file.kind || (file.untracked ? "untracked" : "modified"); });
|
|
22836
22906
|
if (list) {
|
|
22837
22907
|
list.innerHTML = "";
|
|
22838
22908
|
files.forEach(function (file) {
|
|
22839
|
-
var btn = document.createElement("button");
|
|
22840
|
-
btn.
|
|
22841
|
-
btn.
|
|
22842
|
-
btn.innerHTML = "<span></span><span><span class=\\"plus\\">+" + file.added + "</span> <span class=\\"minus\\">\u2212" + file.deleted + "</span></span>";
|
|
22843
|
-
btn.querySelector("span").textContent = file.path;
|
|
22844
|
-
btn.addEventListener("click", function () { loadDiff(file.path, btn); });
|
|
22845
|
-
list.appendChild(btn);
|
|
22909
|
+
var btn = document.createElement("button"); btn.type = "button"; btn.className = "change-file";
|
|
22910
|
+
btn.innerHTML = "<span></span><span><span class=\\"plus\\">+" + Number(file.added || 0) + "</span> <span class=\\"minus\\">\u2212" + Number(file.deleted || 0) + "</span></span>";
|
|
22911
|
+
btn.querySelector("span").textContent = file.path; btn.addEventListener("click", function () { loadFileContent(file.path, btn); }); list.appendChild(btn);
|
|
22846
22912
|
});
|
|
22847
22913
|
}
|
|
22848
22914
|
setPaths(files.map(function (file) { return file.path; }));
|
|
22849
22915
|
loadTree();
|
|
22916
|
+
if (!selectedPath) {
|
|
22917
|
+
loadAllDiffs(files);
|
|
22918
|
+
}
|
|
22850
22919
|
}
|
|
22851
22920
|
|
|
22852
|
-
function
|
|
22853
|
-
|
|
22854
|
-
|
|
22855
|
-
|
|
22856
|
-
|
|
22857
|
-
|
|
22858
|
-
|
|
22859
|
-
|
|
22860
|
-
|
|
22861
|
-
|
|
22862
|
-
|
|
22863
|
-
var diffEl = document.getElementById("diff");
|
|
22864
|
-
var view = document.getElementById("file-view");
|
|
22865
|
-
if (!diffEl) return;
|
|
22866
|
-
diffEl.hidden = false;
|
|
22867
|
-
if (view) view.hidden = true;
|
|
22868
|
-
diffEl.innerHTML = "";
|
|
22869
|
-
var patch = String(body.patch || "");
|
|
22870
|
-
if (!patch) {
|
|
22871
|
-
diffEl.innerHTML = "<div class=\\"hunk\\">No diff for this file.</div>";
|
|
22872
|
-
return;
|
|
22873
|
-
}
|
|
22874
|
-
var oldLn = 0;
|
|
22875
|
-
var newLn = 0;
|
|
22876
|
-
patch.split("\\n").forEach(function (line) {
|
|
22877
|
-
if (line.indexOf("@@") === 0) {
|
|
22878
|
-
var hunk = line.match(/@@ -(\\d+)(?:,\\d+)? \\+(\\d+)/);
|
|
22879
|
-
if (hunk) { oldLn = Number(hunk[1]) - 1; newLn = Number(hunk[2]) - 1; }
|
|
22880
|
-
var head = document.createElement("div");
|
|
22881
|
-
head.className = "hunk";
|
|
22882
|
-
head.textContent = line;
|
|
22883
|
-
diffEl.appendChild(head);
|
|
22884
|
-
return;
|
|
22885
|
-
}
|
|
22886
|
-
if (line.indexOf("diff ") === 0 || line.indexOf("index ") === 0 || line.indexOf("---") === 0 || line.indexOf("+++") === 0) {
|
|
22887
|
-
var meta = document.createElement("div");
|
|
22888
|
-
meta.className = "hunk";
|
|
22889
|
-
meta.textContent = line;
|
|
22890
|
-
diffEl.appendChild(meta);
|
|
22891
|
-
return;
|
|
22892
|
-
}
|
|
22893
|
-
var kind = "ctx";
|
|
22894
|
-
var left = "";
|
|
22895
|
-
var right = "";
|
|
22896
|
-
if (line.charAt(0) === "+") { kind = "add"; newLn += 1; right = String(newLn); }
|
|
22897
|
-
else if (line.charAt(0) === "-") { kind = "del"; oldLn += 1; left = String(oldLn); }
|
|
22898
|
-
else { oldLn += 1; newLn += 1; left = String(oldLn); right = String(newLn); }
|
|
22899
|
-
var row = document.createElement("div");
|
|
22900
|
-
row.className = "row " + kind;
|
|
22901
|
-
var a = document.createElement("span"); a.className = "ln"; a.textContent = left;
|
|
22902
|
-
var b = document.createElement("span"); b.className = "ln"; b.textContent = right;
|
|
22903
|
-
var code = document.createElement("span"); code.className = "code"; code.textContent = line;
|
|
22904
|
-
row.appendChild(a); row.appendChild(b); row.appendChild(code);
|
|
22905
|
-
diffEl.appendChild(row);
|
|
22906
|
-
});
|
|
22907
|
-
var preview = document.getElementById("preview");
|
|
22908
|
-
preview.hidden = !/\\.html?$/i.test(path);
|
|
22909
|
-
if (!preview.hidden) {
|
|
22910
|
-
api("GET", "/api/file?path=" + encodeURIComponent(path)).then(function (res) { return res.json(); }).then(function (file) {
|
|
22911
|
-
preview.srcdoc = String(file.text || "");
|
|
22912
|
-
}).catch(function () {});
|
|
22913
|
-
}
|
|
22921
|
+
function scheduleWorkspaceRefresh() {
|
|
22922
|
+
if (workspaceRefreshTimer) clearTimeout(workspaceRefreshTimer);
|
|
22923
|
+
workspaceRefreshTimer = setTimeout(function () { refreshWorkspaceSnapshot(false); }, 450);
|
|
22924
|
+
}
|
|
22925
|
+
|
|
22926
|
+
function refreshWorkspaceSnapshot(force) {
|
|
22927
|
+
if (workspaceRefreshTimer) { clearTimeout(workspaceRefreshTimer); workspaceRefreshTimer = null; }
|
|
22928
|
+
return api("GET", "/api/snapshot").then(function (res) { return res.ok ? res.json() : null; }).then(function (s) {
|
|
22929
|
+
if (!s) return;
|
|
22930
|
+
if (s.files || s.changed_paths) renderChanges(s);
|
|
22931
|
+
if (force && s.sessions) renderSessions(s.sessions, s.active_session_id || activeSessionId);
|
|
22914
22932
|
}).catch(function () {});
|
|
22915
22933
|
}
|
|
22916
22934
|
|
|
@@ -23043,6 +23061,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23043
23061
|
break;
|
|
23044
23062
|
case "busy":
|
|
23045
23063
|
setBusy(ev.busy);
|
|
23064
|
+
if (!ev.busy) scheduleWorkspaceRefresh();
|
|
23046
23065
|
break;
|
|
23047
23066
|
case "ended":
|
|
23048
23067
|
setBusy(false);
|
|
@@ -23069,6 +23088,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23069
23088
|
if (thinkingEl && s.thinking_level) thinkingEl.value = s.thinking_level;
|
|
23070
23089
|
syncPick("mode");
|
|
23071
23090
|
syncPick("autonomy");
|
|
23091
|
+
syncAutonomyVisual();
|
|
23072
23092
|
syncPick("thinking");
|
|
23073
23093
|
syncPick("review-depth");
|
|
23074
23094
|
syncPick("review-lens");
|
|
@@ -23080,7 +23100,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23080
23100
|
if (s.events && s.events.length) replayEvents(s.events);
|
|
23081
23101
|
else if (s.last_review_text) setReview(s.last_review_text);
|
|
23082
23102
|
if (s.pending_exec) showExec(s.pending_exec);
|
|
23083
|
-
if (s.files) renderChanges(s);
|
|
23103
|
+
if (s.files || s.changed_paths) renderChanges(s);
|
|
23084
23104
|
if (s.ended) {
|
|
23085
23105
|
setStatus("Session ended", "err");
|
|
23086
23106
|
addBlock("note", "Session ended \xB7 " + s.ended);
|
|
@@ -23134,56 +23154,109 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23134
23154
|
});
|
|
23135
23155
|
}
|
|
23136
23156
|
|
|
23157
|
+
function cleanSkillDescription(s) {
|
|
23158
|
+
var desc = String(s && s.description || "").trim();
|
|
23159
|
+
var constraint = String(s && s.constraint || "").trim();
|
|
23160
|
+
if (!desc || desc === constraint || /Untrusted text. Cannot grant a shell or treat checks as Evidence./i.test(desc) || /Built-in. Wins on name collision/i.test(desc)) return "";
|
|
23161
|
+
return desc;
|
|
23162
|
+
}
|
|
23163
|
+
|
|
23164
|
+
function renderSkills(rows) {
|
|
23165
|
+
var skills = document.getElementById("skill-list");
|
|
23166
|
+
if (!skills) return;
|
|
23167
|
+
skills.innerHTML = "";
|
|
23168
|
+
(rows || []).forEach(function (s) {
|
|
23169
|
+
var row = document.createElement("div"); row.className = "skill-row";
|
|
23170
|
+
var head = document.createElement("div"); head.className = "skill-head";
|
|
23171
|
+
var name = document.createElement("b"); name.textContent = s.name || s.id || "Skill";
|
|
23172
|
+
var source = document.createElement("span"); source.className = "skill-source"; source.textContent = s.source || "skill";
|
|
23173
|
+
head.appendChild(name); head.appendChild(source); row.appendChild(head);
|
|
23174
|
+
var desc = document.createElement("div"); desc.className = "skill-desc"; desc.textContent = cleanSkillDescription(s) || "Available to the author when this task matches the skill."; row.appendChild(desc);
|
|
23175
|
+
if (s.origin) { var origin = document.createElement("div"); origin.className = "skill-origin"; origin.textContent = s.origin; row.appendChild(origin); }
|
|
23176
|
+
skills.appendChild(row);
|
|
23177
|
+
});
|
|
23178
|
+
if (!rows || !rows.length) skills.innerHTML = "<div class=\\"settings-note\\">No skills discovered.</div>";
|
|
23179
|
+
}
|
|
23180
|
+
|
|
23181
|
+
function renderAudit(rows) {
|
|
23182
|
+
var audit = document.getElementById("audit-panel"); if (!audit) return; audit.innerHTML = "";
|
|
23183
|
+
(rows || []).slice().reverse().slice(0, 80).forEach(function (a) {
|
|
23184
|
+
var row = document.createElement("div"); row.className = "audit-row";
|
|
23185
|
+
var at = document.createElement("span"); at.textContent = a.at ? new Date(a.at).toLocaleString() : "";
|
|
23186
|
+
var decision = document.createElement("span"); decision.textContent = (a.decision || "") + (a.scope ? " \xB7 " + a.scope : "");
|
|
23187
|
+
var code = document.createElement("code"); code.textContent = a.preview || a.purpose || "";
|
|
23188
|
+
row.appendChild(at); row.appendChild(decision); row.appendChild(code); audit.appendChild(row);
|
|
23189
|
+
});
|
|
23190
|
+
if (!rows || !rows.length) audit.innerHTML = "<div class=\\"settings-note\\">No approval decisions yet.</div>";
|
|
23191
|
+
}
|
|
23192
|
+
|
|
23137
23193
|
function loadStudio() {
|
|
23138
23194
|
api("GET", "/api/studio").then(function (res) { return res.json(); }).then(function (body) {
|
|
23139
|
-
var author = document.getElementById("studio-author");
|
|
23140
|
-
|
|
23141
|
-
if (author && modelEl) author.innerHTML = modelEl.innerHTML;
|
|
23195
|
+
var author = document.getElementById("studio-author"); var review = document.getElementById("studio-review");
|
|
23196
|
+
if (author && modelEl) { author.innerHTML = modelEl.innerHTML; author.value = modelEl.value; }
|
|
23142
23197
|
if (review && modelEl) review.innerHTML = modelEl.innerHTML;
|
|
23143
23198
|
if (body.badges) {
|
|
23199
|
+
if (review && body.badges.review && body.badges.review.id) review.value = body.badges.review.id;
|
|
23144
23200
|
var indep = document.getElementById("studio-indep");
|
|
23145
|
-
if (indep) indep.textContent = body.badges.independent
|
|
23146
|
-
? "Reviewer is a different model than the author."
|
|
23147
|
-
: "Author and review currently share a model \u2014 pick a distinct review model.";
|
|
23201
|
+
if (indep) { indep.className = "settings-note" + (body.badges.independent ? "" : " warn"); indep.textContent = body.badges.independent ? "Independent reviewer enabled \u2014 author and reviewer use different models." : "Author and reviewer currently share the same model. Pick a different reviewer for stronger independence."; }
|
|
23148
23202
|
}
|
|
23149
|
-
var skills = document.getElementById("skill-list");
|
|
23150
23203
|
if (body.skills) slashSkills = body.skills;
|
|
23151
|
-
|
|
23152
|
-
|
|
23153
|
-
|
|
23154
|
-
|
|
23155
|
-
}
|
|
23156
|
-
var cost = document.getElementById("cost-panel");
|
|
23157
|
-
if (cost && body.costs) cost.textContent = JSON.stringify(body.costs, null, 2);
|
|
23158
|
-
var audit = document.getElementById("audit-panel");
|
|
23159
|
-
if (audit) audit.textContent = JSON.stringify(body.audit || [], null, 2);
|
|
23204
|
+
renderSkills(body.skills || []);
|
|
23205
|
+
studioCosts = body.costs || studioCosts;
|
|
23206
|
+
renderUsagePanel(studioCosts);
|
|
23207
|
+
renderAudit(body.audit || []);
|
|
23160
23208
|
var tl = document.getElementById("timeline");
|
|
23161
|
-
if (tl) {
|
|
23162
|
-
|
|
23163
|
-
|
|
23164
|
-
}).join("");
|
|
23165
|
-
}
|
|
23166
|
-
var left = document.getElementById("compare-left");
|
|
23167
|
-
var right = document.getElementById("compare-right");
|
|
23168
|
-
if (body.compare && left && right) {
|
|
23169
|
-
left.textContent = (body.compare.left.model || "") + "\\nonly:\\n" + (body.compare.only_left || []).join("\\n");
|
|
23170
|
-
right.textContent = (body.compare.right.model || "") + "\\nonly:\\n" + (body.compare.only_right || []).join("\\n");
|
|
23171
|
-
}
|
|
23209
|
+
if (tl) { tl.innerHTML = (body.timeline || []).map(function (n) { return "<button type=\\"button\\" class=\\"find-row\\">" + esc(n.kind) + " \xB7 " + esc(n.label || n.conclusion || n.id) + "</button>"; }).join(""); }
|
|
23210
|
+
var left = document.getElementById("compare-left"); var right = document.getElementById("compare-right");
|
|
23211
|
+
if (body.compare && left && right) { left.textContent = (body.compare.left.model || "") + "\\nonly:\\n" + (body.compare.only_left || []).join("\\n"); right.textContent = (body.compare.right.model || "") + "\\nonly:\\n" + (body.compare.only_right || []).join("\\n"); }
|
|
23172
23212
|
var kind = document.getElementById("key-kind");
|
|
23173
|
-
if (kind && kind.options.length === 0) {
|
|
23174
|
-
|
|
23175
|
-
|
|
23176
|
-
opt.value = c.kind;
|
|
23177
|
-
opt.textContent = c.label;
|
|
23178
|
-
kind.appendChild(opt);
|
|
23179
|
-
});
|
|
23180
|
-
}
|
|
23181
|
-
syncPick("studio-author");
|
|
23182
|
-
syncPick("studio-review");
|
|
23183
|
-
syncPick("key-kind");
|
|
23213
|
+
if (kind && kind.options.length === 0) (boot.credentials || []).forEach(function (c) { var opt = document.createElement("option"); opt.value = c.kind; opt.textContent = c.label; kind.appendChild(opt); });
|
|
23214
|
+
syncPick("studio-author"); syncPick("studio-review"); syncPick("key-kind");
|
|
23215
|
+
trapScrollableMenus();
|
|
23184
23216
|
}).catch(function () {});
|
|
23185
23217
|
}
|
|
23186
23218
|
|
|
23219
|
+
function openSheet(id) { var el = document.getElementById(id); if (el) el.className = "sheet open"; }
|
|
23220
|
+
function closeSheet(id) { var el = document.getElementById(id); if (el) el.className = "sheet"; }
|
|
23221
|
+
|
|
23222
|
+
function renderCommandBrowser() {
|
|
23223
|
+
var list = document.getElementById("command-list"); var search = document.getElementById("command-search");
|
|
23224
|
+
if (!list) return;
|
|
23225
|
+
var q = String(search && search.value || ""); list.innerHTML = "";
|
|
23226
|
+
rankSlashItems(slashCatalog(), q).slice(0, 80).forEach(function (item) {
|
|
23227
|
+
var row = document.createElement("button"); row.type = "button"; row.className = "command-row";
|
|
23228
|
+
var code = document.createElement("span"); code.className = "command-code"; code.textContent = item.value;
|
|
23229
|
+
var desc = document.createElement("span"); desc.className = "command-desc"; desc.textContent = item.description || item.label || "";
|
|
23230
|
+
var kind = document.createElement("span"); kind.className = "command-kind"; kind.textContent = item.kind;
|
|
23231
|
+
row.appendChild(code); row.appendChild(desc); row.appendChild(kind);
|
|
23232
|
+
row.addEventListener("click", function () { closeSheet("command-sheet"); inputEl.value = item.value + " "; inputEl.focus(); autosizeInput(); });
|
|
23233
|
+
list.appendChild(row);
|
|
23234
|
+
});
|
|
23235
|
+
}
|
|
23236
|
+
|
|
23237
|
+
function showCommands() { closePicks(); renderCommandBrowser(); openSheet("command-sheet"); var q = document.getElementById("command-search"); if (q) setTimeout(function(){ q.focus(); }, 0); }
|
|
23238
|
+
|
|
23239
|
+
function selectSettingsTab(name) {
|
|
23240
|
+
document.querySelectorAll("[data-settings-tab]").forEach(function (b) { b.classList.toggle("on", b.getAttribute("data-settings-tab") === name); });
|
|
23241
|
+
document.querySelectorAll("[data-settings-panel]").forEach(function (p) { p.classList.toggle("on", p.getAttribute("data-settings-panel") === name); });
|
|
23242
|
+
if (name === "usage") renderUsagePanel(studioCosts);
|
|
23243
|
+
}
|
|
23244
|
+
|
|
23245
|
+
function autosizeInput() { inputEl.style.height = "auto"; inputEl.style.height = Math.min(190, Math.max(44, inputEl.scrollHeight)) + "px"; }
|
|
23246
|
+
|
|
23247
|
+
function trapWheel(el) {
|
|
23248
|
+
if (!el || el.dataset.wheelTrap === "1") return;
|
|
23249
|
+
el.dataset.wheelTrap = "1";
|
|
23250
|
+
el.addEventListener("wheel", function (e) {
|
|
23251
|
+
e.stopPropagation();
|
|
23252
|
+
var top = el.scrollTop <= 0; var bottom = Math.ceil(el.scrollTop + el.clientHeight) >= el.scrollHeight;
|
|
23253
|
+
if ((e.deltaY < 0 && top) || (e.deltaY > 0 && bottom)) e.preventDefault();
|
|
23254
|
+
}, { passive: false });
|
|
23255
|
+
}
|
|
23256
|
+
function trapScrollableMenus() {
|
|
23257
|
+
[document.getElementById("model-list"), document.getElementById("studio-author-menu"), document.getElementById("studio-review-menu"), document.getElementById("key-kind-menu"), document.getElementById("thinking-menu"), document.getElementById("mention-list")].forEach(trapWheel);
|
|
23258
|
+
}
|
|
23259
|
+
|
|
23187
23260
|
function connect() {
|
|
23188
23261
|
if (es) {
|
|
23189
23262
|
es.close();
|
|
@@ -23219,7 +23292,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23219
23292
|
|
|
23220
23293
|
function submitText(raw, steerNow) {
|
|
23221
23294
|
var text = (raw == null ? inputEl.value : raw).trim();
|
|
23222
|
-
if (raw == null && text) inputEl.value = "";
|
|
23295
|
+
if (raw == null && text) { inputEl.value = ""; autosizeInput(); }
|
|
23223
23296
|
if (!text) {
|
|
23224
23297
|
if (steerNow) flushQueue(true);
|
|
23225
23298
|
return;
|
|
@@ -23241,6 +23314,18 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23241
23314
|
});
|
|
23242
23315
|
}
|
|
23243
23316
|
|
|
23317
|
+
on("commands-open", "click", function () { var pop=document.getElementById("cmd-pop"); if(pop) pop.classList.remove("open"); showCommands(); });
|
|
23318
|
+
on("empty-commands", "click", showCommands);
|
|
23319
|
+
on("close-commands", "click", function () { closeSheet("command-sheet"); });
|
|
23320
|
+
var commandSearch = document.getElementById("command-search");
|
|
23321
|
+
if (commandSearch) commandSearch.addEventListener("input", renderCommandBrowser);
|
|
23322
|
+
document.querySelectorAll("[data-starter]").forEach(function (btn) { btn.addEventListener("click", function () { inputEl.value = btn.getAttribute("data-starter") || ""; autosizeInput(); inputEl.focus(); }); });
|
|
23323
|
+
document.querySelectorAll("[data-settings-tab]").forEach(function (btn) { btn.addEventListener("click", function () { selectSettingsTab(btn.getAttribute("data-settings-tab")); }); });
|
|
23324
|
+
on("rail-settings", "click", function () { loadStudio(); openSheet("studio-sheet"); });
|
|
23325
|
+
on("close-legend", "click", function () { closeSheet("legend-sheet"); });
|
|
23326
|
+
inputEl.addEventListener("input", autosizeInput);
|
|
23327
|
+
trapScrollableMenus();
|
|
23328
|
+
|
|
23244
23329
|
sendEl.addEventListener("click", function () { submitText(null, false); });
|
|
23245
23330
|
on("queue-send", "click", function () { flushQueue(true); });
|
|
23246
23331
|
on("queue-clear", "click", function () { promptQueue = []; renderQueue(); });
|
|
@@ -23256,6 +23341,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23256
23341
|
modelMenu.className = "open";
|
|
23257
23342
|
modelOpen.setAttribute("aria-expanded", "true");
|
|
23258
23343
|
renderModelList();
|
|
23344
|
+
trapWheel(document.getElementById("model-list"));
|
|
23259
23345
|
if (modelFilter) modelFilter.focus();
|
|
23260
23346
|
}
|
|
23261
23347
|
});
|
|
@@ -23277,11 +23363,28 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23277
23363
|
if (thinkingEl) thinkingEl.addEventListener("change", function () {
|
|
23278
23364
|
saveSetting({ thinking_level: thinkingEl.value });
|
|
23279
23365
|
});
|
|
23280
|
-
|
|
23281
|
-
api("POST", "/api/sessions", {})
|
|
23282
|
-
|
|
23283
|
-
|
|
23284
|
-
|
|
23366
|
+
function createNewSession() {
|
|
23367
|
+
api("POST", "/api/sessions", {})
|
|
23368
|
+
.then(function (res) {
|
|
23369
|
+
if (!res.ok) {
|
|
23370
|
+
return readError(res, "Could not start a new session.").then(function (msg) { addBlock("alert", msg); });
|
|
23371
|
+
}
|
|
23372
|
+
if (window.innerWidth <= 760) {
|
|
23373
|
+
layout.rail = false;
|
|
23374
|
+
applyLayout();
|
|
23375
|
+
}
|
|
23376
|
+
inputEl.focus();
|
|
23377
|
+
})
|
|
23378
|
+
.catch(function () { addBlock("alert", "Could not start a new session."); });
|
|
23379
|
+
}
|
|
23380
|
+
on("new-session", "click", createNewSession);
|
|
23381
|
+
on("top-new-session", "click", createNewSession);
|
|
23382
|
+
on("all-changes", "click", function () {
|
|
23383
|
+
selectedPath = "";
|
|
23384
|
+
var back = document.getElementById("all-changes");
|
|
23385
|
+
if (back) back.hidden = true;
|
|
23386
|
+
refreshWorkspaceSnapshot(false).then(function () {
|
|
23387
|
+
document.querySelectorAll(".tree button.on").forEach(function (el) { el.classList.remove("on"); });
|
|
23285
23388
|
});
|
|
23286
23389
|
});
|
|
23287
23390
|
on("fork-session", "click", function () {
|
|
@@ -23294,6 +23397,11 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23294
23397
|
var searchEl = document.getElementById("session-search");
|
|
23295
23398
|
if (searchEl) searchEl.addEventListener("input", function () { renderSessions(allSessions, activeSessionId); });
|
|
23296
23399
|
|
|
23400
|
+
function syncAutonomyVisual() {
|
|
23401
|
+
var open = document.getElementById("autonomy-open"); var sel = document.getElementById("autonomy");
|
|
23402
|
+
if (open && sel) open.classList.toggle("auto", sel.value === "auto");
|
|
23403
|
+
}
|
|
23404
|
+
|
|
23297
23405
|
function renderChips() {
|
|
23298
23406
|
var el = document.getElementById("ref-chips");
|
|
23299
23407
|
if (!el) return;
|
|
@@ -23359,21 +23467,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23359
23467
|
return;
|
|
23360
23468
|
}
|
|
23361
23469
|
addRef(node.path);
|
|
23362
|
-
|
|
23363
|
-
else {
|
|
23364
|
-
selectedPath = node.path;
|
|
23365
|
-
var title = document.getElementById("diff-title");
|
|
23366
|
-
if (title) title.textContent = node.path;
|
|
23367
|
-
api("GET", "/api/file?path=" + encodeURIComponent(node.path)).then(function (res) { return res.json(); }).then(function (file) {
|
|
23368
|
-
var view = document.getElementById("file-view");
|
|
23369
|
-
var diffEl = document.getElementById("diff");
|
|
23370
|
-
if (diffEl) diffEl.hidden = true;
|
|
23371
|
-
if (view) {
|
|
23372
|
-
view.hidden = false;
|
|
23373
|
-
view.textContent = file.text || "";
|
|
23374
|
-
}
|
|
23375
|
-
}).catch(function () {});
|
|
23376
|
-
}
|
|
23470
|
+
loadFileContent(node.path, btn);
|
|
23377
23471
|
});
|
|
23378
23472
|
into.appendChild(btn);
|
|
23379
23473
|
if (node.dir && !collapsed) renderTreeNodes(node.children || [], depth + 1, into);
|
|
@@ -23452,7 +23546,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23452
23546
|
if (!selectedPath) return;
|
|
23453
23547
|
api("POST", "/api/changes/revert", { path: selectedPath }).then(function (res) {
|
|
23454
23548
|
if (!res.ok) return readError(res, "Could not reject that file.").then(function (msg) { addBlock("alert", msg); });
|
|
23455
|
-
|
|
23549
|
+
refreshWorkspaceSnapshot(true);
|
|
23456
23550
|
}).catch(function () {});
|
|
23457
23551
|
});
|
|
23458
23552
|
on("accept-file", "click", function () {
|
|
@@ -23545,7 +23639,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23545
23639
|
var modeEl = document.getElementById("mode");
|
|
23546
23640
|
var autonomyEl = document.getElementById("autonomy");
|
|
23547
23641
|
if (modeEl) modeEl.addEventListener("change", function () { saveSetting({ agent_mode: modeEl.value }); });
|
|
23548
|
-
if (autonomyEl) autonomyEl.addEventListener("change", function () { saveSetting({ autonomy: autonomyEl.value }); });
|
|
23642
|
+
if (autonomyEl) autonomyEl.addEventListener("change", function () { saveSetting({ autonomy: autonomyEl.value }); syncAutonomyVisual(); });
|
|
23549
23643
|
|
|
23550
23644
|
feedEl.addEventListener("click", function (e) {
|
|
23551
23645
|
var btn = e.target.closest && e.target.closest(".copy");
|
|
@@ -23589,7 +23683,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23589
23683
|
}
|
|
23590
23684
|
|
|
23591
23685
|
var shell = document.querySelector(".shell");
|
|
23592
|
-
var layout = { rail:
|
|
23686
|
+
var layout = { rail: window.innerWidth > 760, changes: false, term: false };
|
|
23593
23687
|
try {
|
|
23594
23688
|
var saved = localStorage.getItem("critique.code-web.layout");
|
|
23595
23689
|
if (saved) layout = Object.assign(layout, JSON.parse(saved));
|
|
@@ -23602,7 +23696,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23602
23696
|
var pane = document.getElementById("changes-pane");
|
|
23603
23697
|
if (pane) pane.classList.toggle("open", !!layout.changes);
|
|
23604
23698
|
var railBtn = document.getElementById("toggle-rail");
|
|
23605
|
-
if (railBtn) railBtn.
|
|
23699
|
+
if (railBtn) railBtn.classList.toggle("on", !!layout.rail);
|
|
23606
23700
|
try { localStorage.setItem("critique.code-web.layout", JSON.stringify(layout)); } catch (e) {}
|
|
23607
23701
|
}
|
|
23608
23702
|
applyLayout();
|
|
@@ -23764,15 +23858,8 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23764
23858
|
}).join("");
|
|
23765
23859
|
if (sheet) sheet.className = "sheet open";
|
|
23766
23860
|
});
|
|
23767
|
-
on("studio-open", "click", function () {
|
|
23768
|
-
|
|
23769
|
-
var sheet = document.getElementById("studio-sheet");
|
|
23770
|
-
if (sheet) sheet.className = "sheet open";
|
|
23771
|
-
});
|
|
23772
|
-
on("close-studio", "click", function () {
|
|
23773
|
-
var sheet = document.getElementById("studio-sheet");
|
|
23774
|
-
if (sheet) sheet.className = "sheet";
|
|
23775
|
-
});
|
|
23861
|
+
on("studio-open", "click", function () { loadStudio(); selectSettingsTab("general"); openSheet("studio-sheet"); });
|
|
23862
|
+
on("close-studio", "click", function () { closeSheet("studio-sheet"); });
|
|
23776
23863
|
on("save-key", "click", function () {
|
|
23777
23864
|
var kind = document.getElementById("key-kind");
|
|
23778
23865
|
var value = document.getElementById("key-value");
|
|
@@ -23796,7 +23883,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23796
23883
|
if (sheet) sheet.className = "sheet";
|
|
23797
23884
|
if (res.ok) {
|
|
23798
23885
|
if (body.branch) setBranchLabel(body.branch);
|
|
23799
|
-
|
|
23886
|
+
refreshWorkspaceSnapshot(true);
|
|
23800
23887
|
loadBranches();
|
|
23801
23888
|
}
|
|
23802
23889
|
}); });
|
|
@@ -23845,6 +23932,19 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23845
23932
|
}
|
|
23846
23933
|
if (paletteQ) paletteQ.addEventListener("input", renderPalette);
|
|
23847
23934
|
renderPalette();
|
|
23935
|
+
var themeLight = document.getElementById("theme-light");
|
|
23936
|
+
function applyTheme(light) {
|
|
23937
|
+
document.documentElement.setAttribute("data-theme", light ? "light" : "dark");
|
|
23938
|
+
try { localStorage.setItem("critique-code-theme", light ? "light" : "dark"); } catch (e) {}
|
|
23939
|
+
}
|
|
23940
|
+
if (themeLight) {
|
|
23941
|
+
var savedTheme = "";
|
|
23942
|
+
try { savedTheme = localStorage.getItem("critique-code-theme") || ""; } catch (e) {}
|
|
23943
|
+
var useLight = savedTheme === "light";
|
|
23944
|
+
themeLight.checked = useLight;
|
|
23945
|
+
applyTheme(useLight);
|
|
23946
|
+
themeLight.addEventListener("change", function () { applyTheme(themeLight.checked); });
|
|
23947
|
+
}
|
|
23848
23948
|
document.querySelectorAll(".work-tabs button").forEach(function (btn) {
|
|
23849
23949
|
btn.addEventListener("click", function () {
|
|
23850
23950
|
document.querySelectorAll(".work-tabs button").forEach(function (el) { el.classList.remove("on"); });
|
|
@@ -23912,8 +24012,12 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23912
24012
|
addBlock("alert", "Could not load this session. Refresh the loopback tab.");
|
|
23913
24013
|
});
|
|
23914
24014
|
renderModelList();
|
|
24015
|
+
renderCommandBrowser();
|
|
24016
|
+
autosizeInput();
|
|
24017
|
+
syncAutonomyVisual();
|
|
23915
24018
|
updateContextRing();
|
|
23916
24019
|
loadStudio();
|
|
24020
|
+
refreshWorkspaceSnapshot(false);
|
|
23917
24021
|
connect();
|
|
23918
24022
|
})();
|
|
23919
24023
|
</script>
|
|
@@ -28610,7 +28714,8 @@ ${prior}`.trim();
|
|
|
28610
28714
|
source: "author",
|
|
28611
28715
|
model: authorModelId(implementer[0]),
|
|
28612
28716
|
input_tokens: turn.usage?.input_tokens ?? 0,
|
|
28613
|
-
output_tokens: turn.usage?.output_tokens ?? 0
|
|
28717
|
+
output_tokens: turn.usage?.output_tokens ?? 0,
|
|
28718
|
+
cost_usd: turn.usage?.cost_usd
|
|
28614
28719
|
});
|
|
28615
28720
|
const output = typeof turn.output === "string" ? turn.output : JSON.stringify(turn.output);
|
|
28616
28721
|
noteWithheld(output);
|
|
@@ -30551,6 +30656,12 @@ function commandPaletteItems(state) {
|
|
|
30551
30656
|
function emptyTokens() {
|
|
30552
30657
|
return { input_tokens: 0, output_tokens: 0 };
|
|
30553
30658
|
}
|
|
30659
|
+
function estimateUsageCostUsd(input, output, reasoning = 0) {
|
|
30660
|
+
const inCost = input * 1e-7;
|
|
30661
|
+
const outCost = output * 4e-7;
|
|
30662
|
+
const reasonCost = reasoning * 2e-7;
|
|
30663
|
+
return inCost + outCost + reasonCost;
|
|
30664
|
+
}
|
|
30554
30665
|
function costBreakdown(entries) {
|
|
30555
30666
|
const by_phase = {
|
|
30556
30667
|
author: emptyTokens(),
|
|
@@ -30560,6 +30671,7 @@ function costBreakdown(entries) {
|
|
|
30560
30671
|
const by_model = {};
|
|
30561
30672
|
let total_input = 0;
|
|
30562
30673
|
let total_output = 0;
|
|
30674
|
+
let total_cost_usd = 0;
|
|
30563
30675
|
for (const entry of entries) {
|
|
30564
30676
|
const phase = by_phase[entry.source];
|
|
30565
30677
|
phase.input_tokens += entry.input_tokens;
|
|
@@ -30569,8 +30681,10 @@ function costBreakdown(entries) {
|
|
|
30569
30681
|
model.output_tokens += entry.output_tokens;
|
|
30570
30682
|
total_input += entry.input_tokens;
|
|
30571
30683
|
total_output += entry.output_tokens;
|
|
30684
|
+
total_cost_usd += Number(entry.cost_usd || 0);
|
|
30572
30685
|
}
|
|
30573
|
-
|
|
30686
|
+
const estimated_cost_usd = total_cost_usd > 0 ? total_cost_usd : estimateUsageCostUsd(total_input, total_output);
|
|
30687
|
+
return { by_phase, by_model, total_input, total_output, total_cost_usd, estimated_cost_usd };
|
|
30574
30688
|
}
|
|
30575
30689
|
function skillPanelRows(skills) {
|
|
30576
30690
|
return skills.map((skill) => {
|
|
@@ -31190,6 +31304,29 @@ exit ${code2 ?? "killed"}
|
|
|
31190
31304
|
send(res, 200, { ok: true, id: chat.id });
|
|
31191
31305
|
return;
|
|
31192
31306
|
}
|
|
31307
|
+
if (req.method === "POST" && path2 === "/api/sessions/rename") {
|
|
31308
|
+
const body = await readJson(req);
|
|
31309
|
+
const id4 = String(body.id ?? activeId).trim();
|
|
31310
|
+
const title = String(body.title ?? "").trim().slice(0, 120);
|
|
31311
|
+
const chat = chats.find((item) => item.id === id4);
|
|
31312
|
+
if (!chat) {
|
|
31313
|
+
send(res, 404, { error: "unknown session" });
|
|
31314
|
+
return;
|
|
31315
|
+
}
|
|
31316
|
+
if (!title) {
|
|
31317
|
+
send(res, 400, { error: "title required" });
|
|
31318
|
+
return;
|
|
31319
|
+
}
|
|
31320
|
+
chat.title = title;
|
|
31321
|
+
persistChats();
|
|
31322
|
+
if (chat.id === activeId) {
|
|
31323
|
+
emit({ type: "title", title: chat.title, id: chat.id, sessions: sessionSummaries() });
|
|
31324
|
+
} else {
|
|
31325
|
+
emit({ type: "session_list", sessions: sessionSummaries(), id: activeId });
|
|
31326
|
+
}
|
|
31327
|
+
send(res, 200, { ok: true, id: chat.id, title: chat.title, sessions: sessionSummaries() });
|
|
31328
|
+
return;
|
|
31329
|
+
}
|
|
31193
31330
|
if (req.method === "GET" && path2 === "/api/tree") {
|
|
31194
31331
|
const prefix = url2.searchParams.get("prefix")?.trim() ?? "";
|
|
31195
31332
|
const entries = listWorkspaceTree(repositoryRoot, 2e3, prefix);
|
|
@@ -31501,12 +31638,20 @@ ${extras.join("\n\n")}` : text);
|
|
|
31501
31638
|
const cursor = await new FileReviewCheckpointStore(storeRoot).load();
|
|
31502
31639
|
const skills = await discoverCritiqueCodeSkills({ cwd: repositoryRoot, env });
|
|
31503
31640
|
const suppressed = new Set(ops.state().suppressions.map((item) => item.fingerprint));
|
|
31641
|
+
const chatUsage = activeChat().events.filter((event) => event.type === "usage").map((event) => ({
|
|
31642
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
31643
|
+
source: "author",
|
|
31644
|
+
model,
|
|
31645
|
+
input_tokens: Number(event.input_tokens || 0),
|
|
31646
|
+
output_tokens: Number(event.output_tokens || 0),
|
|
31647
|
+
cost_usd: event.cost_usd
|
|
31648
|
+
}));
|
|
31504
31649
|
send(res, 200, {
|
|
31505
31650
|
...snapshot(),
|
|
31506
31651
|
badges: dualModelBadges({ author_model: model, review_models: reviewModels }),
|
|
31507
31652
|
palette: commandPaletteItems({ watch: watchOn, autonomy, voice: false }),
|
|
31508
31653
|
skills: skillPanelRows(skills),
|
|
31509
|
-
costs: costBreakdown(ops.state().costs),
|
|
31654
|
+
costs: costBreakdown([...ops.state().costs, ...chatUsage]),
|
|
31510
31655
|
audit: approvalLog,
|
|
31511
31656
|
timeline: checkpointTimeline({
|
|
31512
31657
|
cursor: cursor ? {
|