@critiquedotsh/harness 0.1.10 → 0.1.12
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 +1016 -870
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -21318,708 +21318,452 @@ 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
|
-
.rail-
|
|
21399
|
-
.
|
|
21400
|
-
|
|
21401
|
-
|
|
21402
|
-
.
|
|
21403
|
-
|
|
21404
|
-
.
|
|
21405
|
-
.session-
|
|
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
|
-
.
|
|
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{grid-template-columns:minmax(0,1fr) 1px var(--changes-w)}
|
|
21369
|
+
.shell.rail-off .rail{display:none}
|
|
21370
|
+
.shell.changes-off{grid-template-columns:var(--rail-w) minmax(0,1fr)}
|
|
21371
|
+
.shell.changes-off .gutter,.shell.changes-off .changes{display:none}
|
|
21372
|
+
.shell.rail-off.changes-off{grid-template-columns:minmax(0,1fr)}
|
|
21373
|
+
.shell.term-off .term{display:none}
|
|
21374
|
+
.gutter{background:var(--line);cursor:col-resize}
|
|
21375
|
+
|
|
21376
|
+
/* sidebar */
|
|
21377
|
+
.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}
|
|
21378
|
+
.rail-top{height:34px;display:flex;align-items:center;justify-content:space-between;padding:0 4px}
|
|
21379
|
+
.brand{display:inline-flex;align-items:center;gap:9px;color:var(--fg);font-weight:650;font-size:13px;min-width:0}
|
|
21380
|
+
.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)}
|
|
21381
|
+
.brand span:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
21382
|
+
.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)}
|
|
21383
|
+
.rail .plus:hover{background:var(--hover);border-color:var(--line-strong)}
|
|
21384
|
+
.rail-search{position:relative}
|
|
21385
|
+
.rail-search svg{position:absolute;left:10px;top:9px;color:var(--faint);pointer-events:none}
|
|
21386
|
+
.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}
|
|
21387
|
+
.rail .search:focus{border-color:var(--line);background:rgba(255,255,255,.025)}
|
|
21388
|
+
#sessions{display:flex;flex-direction:column;gap:2px;min-height:0;overflow:auto;overscroll-behavior:contain;padding-right:1px;flex:1}
|
|
21389
|
+
.session-row{display:grid;grid-template-columns:minmax(0,1fr) 28px;gap:2px;align-items:center;border-radius:8px}
|
|
21390
|
+
.session-row:hover,.session-row.on{background:var(--hover)}
|
|
21391
|
+
.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}
|
|
21392
|
+
.session-row.on .session-item{color:var(--fg)}
|
|
21393
|
+
.session-delete{width:26px;height:26px;border:0;background:transparent;color:transparent;border-radius:7px;display:grid;place-items:center}
|
|
21394
|
+
.session-row:hover .session-delete{color:var(--faint)}
|
|
21395
|
+
.session-delete:hover{background:rgba(239,119,112,.1)!important;color:var(--red)!important}
|
|
21396
|
+
.rail-footer{border-top:1px solid var(--line);padding-top:8px;display:grid;gap:5px}
|
|
21397
|
+
.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}
|
|
21398
|
+
.rail-footer button:hover{background:var(--hover);color:var(--fg)}
|
|
21399
|
+
.repo-mini{padding:4px 9px;color:var(--faint);font:10.5px ui-monospace,Menlo,monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
21400
|
+
|
|
21401
|
+
/* main */
|
|
21402
|
+
.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)}
|
|
21403
|
+
.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}
|
|
21404
|
+
.topbar-left{display:flex;align-items:center;gap:9px;min-width:0;flex:1}
|
|
21405
|
+
.session-title{min-width:0;font-size:12.5px;font-weight:600;color:var(--fg);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
21406
|
+
.top-actions{display:flex;align-items:center;gap:5px;min-width:0}
|
|
21407
|
+
.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}
|
|
21408
|
+
.icon-btn{width:30px;padding:0}
|
|
21409
|
+
.icon-btn:hover,.toolbar-btn:hover,.icon-btn.on,.toolbar-btn.on{background:var(--hover);color:var(--fg);border-color:var(--line)}
|
|
21410
|
+
.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}
|
|
21411
|
+
.top-status,.badge{max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--faint);font-size:11px}
|
|
21412
|
+
.badge.err{color:var(--red)}
|
|
21413
|
+
#stop{color:var(--red);background:rgba(239,119,112,.08)}
|
|
21414
|
+
main{min-height:0;overflow:auto;overscroll-behavior:contain;scrollbar-gutter:stable}
|
|
21415
|
+
#empty{max-width:700px;margin:17vh auto 0;padding:0 28px 44px}
|
|
21416
|
+
#empty h1{margin:0 0 10px;font-size:27px;line-height:1.2;font-weight:520;letter-spacing:-.04em;color:var(--fg)}
|
|
21417
|
+
#empty p{margin:0;color:var(--muted);font-size:13px;line-height:1.6;max-width:540px}
|
|
21418
|
+
.empty-actions{display:flex;flex-wrap:wrap;gap:7px;margin-top:22px}
|
|
21419
|
+
.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}
|
|
21420
|
+
.empty-actions button:hover{background:var(--hover);color:var(--fg)}
|
|
21421
|
+
#feed{display:none;max-width:780px;margin:0 auto;padding:30px 28px 38px}
|
|
21422
|
+
#feed.on{display:block}
|
|
21423
|
+
.turn{margin:0 0 34px;position:relative}
|
|
21424
|
+
.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}
|
|
21425
|
+
.reply{margin:0;color:#e9e3da;font-size:14px;line-height:1.63;word-break:break-word}
|
|
21426
|
+
.reply>*:first-child{margin-top:0}.reply>*:last-child{margin-bottom:0}
|
|
21427
|
+
.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}
|
|
21428
|
+
.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}
|
|
21429
|
+
.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)}
|
|
21430
|
+
.reply a{color:#a9c8ff;text-decoration:none}.reply a:hover{text-decoration:underline}
|
|
21431
|
+
.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}
|
|
21432
|
+
.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)}
|
|
21433
|
+
.reply hr{border:0;border-top:1px solid var(--line);margin:16px 0}
|
|
21434
|
+
.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}
|
|
21435
|
+
.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}
|
|
21436
|
+
.reply .md-code code{background:none;border:0;padding:0}
|
|
21437
|
+
.md-table{margin:10px 0 14px;overflow:auto;border:1px solid var(--line);border-radius:10px;background:#121210}
|
|
21438
|
+
.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}
|
|
21439
|
+
|
|
21440
|
+
/* activity: each tool is its own row */
|
|
21441
|
+
.activity{display:grid;gap:5px;margin:9px 0 13px}
|
|
21442
|
+
.tool-event,.think{margin:0;border:0;background:transparent;color:var(--muted);font-size:11.5px}
|
|
21443
|
+
.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}
|
|
21444
|
+
.tool-event summary::-webkit-details-marker,.think summary::-webkit-details-marker{display:none}
|
|
21445
|
+
.tool-event summary:hover,.think summary:hover{background:var(--hover);color:var(--fg)}
|
|
21446
|
+
.tool-dot{width:7px;height:7px;border-radius:999px;background:var(--faint);flex:0 0 auto}
|
|
21447
|
+
.tool-event.running .tool-dot{background:var(--amber);box-shadow:0 0 0 3px rgba(224,170,67,.08)}
|
|
21448
|
+
.tool-event.done .tool-dot{background:var(--green)}
|
|
21449
|
+
.tool-event.failed .tool-dot{background:var(--red)}
|
|
21450
|
+
.tool-name{font-family:ui-monospace,Menlo,monospace;color:#c5bdb1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
21451
|
+
.tool-phase{color:var(--faint)}
|
|
21452
|
+
.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}
|
|
21453
|
+
.think{margin:6px 0;color:var(--faint)}
|
|
21454
|
+
.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}
|
|
21455
|
+
.note,.alert,.review-card{margin:10px 0;padding:8px 10px;border-radius:8px;line-height:1.5;word-break:break-word;font-size:12px}
|
|
21456
|
+
.note{padding:5px 2px;background:transparent;border:0;color:var(--faint);font-family:ui-monospace,Menlo,monospace}
|
|
21457
|
+
.alert{background:rgba(239,119,112,.07);border:1px solid rgba(239,119,112,.18);color:#f0b8b4}
|
|
21458
|
+
.review-card{background:rgba(85,216,140,.045);border:1px solid rgba(85,216,140,.18);color:#d8e7dd}
|
|
21459
|
+
.trust{display:none}
|
|
21460
|
+
.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}
|
|
21461
|
+
|
|
21462
|
+
/* composer */
|
|
21463
|
+
.dock{padding:8px 18px 14px;background:linear-gradient(180deg,transparent,rgba(15,15,14,.96) 18%)}
|
|
21464
|
+
.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)}
|
|
21465
|
+
.composer-line{display:flex;align-items:flex-end;gap:5px}
|
|
21466
|
+
.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)}
|
|
21467
|
+
.composer-line textarea::placeholder{color:#716b63}
|
|
21468
|
+
.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}
|
|
21469
|
+
.round-btn:hover,.plus-btn:hover,.mic-btn:hover,.mic-btn.on{background:var(--hover);color:var(--fg)}
|
|
21470
|
+
.composer-foot{display:flex;align-items:center;gap:6px;padding:3px 3px 1px;min-height:36px}
|
|
21471
|
+
.composer-left,.composer-right{display:flex;align-items:center;gap:5px;min-width:0}.composer-right{margin-left:auto;flex:0 0 auto}
|
|
21472
|
+
.pick{position:relative}
|
|
21473
|
+
.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}
|
|
21474
|
+
.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)}
|
|
21475
|
+
.pick-open .caret,#model-open .caret{opacity:.45;font-size:9px}
|
|
21476
|
+
.model-ico{width:15px!important;height:15px!important;display:block;flex:0 0 auto;border-radius:4px}
|
|
21477
|
+
.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}
|
|
21478
|
+
.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}
|
|
21479
|
+
.pick-menu.open,#model-menu.open,#mention.open,.cmd-pop.open,.branch-menu.open,.ship-menu.open{display:grid}
|
|
21480
|
+
.pick-menu{bottom:36px;left:0;min-width:210px;max-height:300px;overflow:auto;overscroll-behavior:contain;padding:5px}
|
|
21481
|
+
#model-menu{right:0;bottom:36px;width:310px;max-height:360px;grid-template-rows:auto minmax(0,1fr);overscroll-behavior:contain}
|
|
21482
|
+
#model-filter{width:100%;height:39px;background:#121211;border:0;border-bottom:1px solid var(--line);padding:0 11px;outline:0;font-size:12px}
|
|
21483
|
+
#model-list{overflow:auto;overscroll-behavior:contain;max-height:310px;padding:5px}
|
|
21484
|
+
.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}
|
|
21485
|
+
.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)}
|
|
21486
|
+
#model{position:absolute;opacity:0;pointer-events:none;width:0;height:0}
|
|
21487
|
+
#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)}
|
|
21488
|
+
#send:hover{transform:translateY(-1px);filter:brightness(1.04)}#send.steer{background:#bfe8cf;color:#142219}#send:disabled{opacity:.45;cursor:not-allowed}
|
|
21489
|
+
#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)}
|
|
21490
|
+
.autonomy-pill.auto{color:var(--amber);border-color:rgba(224,170,67,.24);background:rgba(224,170,67,.055)}
|
|
21491
|
+
.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}
|
|
21492
|
+
.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)}
|
|
21493
|
+
.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)}
|
|
21494
|
+
#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}
|
|
21495
|
+
|
|
21496
|
+
/* terminal */
|
|
21497
|
+
.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)}
|
|
21498
|
+
|
|
21499
|
+
/* workspace */
|
|
21500
|
+
.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)}
|
|
21501
|
+
#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}
|
|
21502
|
+
|
|
21503
|
+
/* overlays */
|
|
21504
|
+
.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)}
|
|
21505
|
+
#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)}
|
|
21506
|
+
.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)}
|
|
21507
|
+
|
|
21508
|
+
/* command browser */
|
|
21509
|
+
.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}
|
|
21510
|
+
|
|
21511
|
+
/* settings */
|
|
21512
|
+
.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)}
|
|
21513
|
+
.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)}
|
|
21514
|
+
.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}
|
|
21515
|
+
#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}
|
|
21516
|
+
.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)}
|
|
21517
|
+
|
|
21518
|
+
/* resume picker */
|
|
21519
|
+
.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}
|
|
21520
|
+
|
|
21521
|
+
@media(max-width:1100px){.shell,.shell.changes-off{grid-template-columns:var(--rail-w) minmax(0,1fr)}.shell.rail-off,.shell.rail-off.changes-off{grid-template-columns: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)}}
|
|
21522
|
+
@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
21523
|
</style>
|
|
21690
21524
|
</head>
|
|
21691
21525
|
<body${remote ? ' class="remote"' : ""}>
|
|
21692
21526
|
<div class="shell">
|
|
21693
21527
|
<aside class="rail">
|
|
21694
21528
|
<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>
|
|
21529
|
+
<div class="brand"><div class="mark" title="CritiqueCode">C</div><span>CritiqueCode</span></div>
|
|
21697
21530
|
</div>
|
|
21698
|
-
<
|
|
21699
|
-
<button type="button" class="plus" id="new-session" title="New session" aria-label="New session">
|
|
21531
|
+
<button type="button" class="plus" id="new-session" title="New session">
|
|
21700
21532
|
<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
|
|
21533
|
+
New chat
|
|
21702
21534
|
</button>
|
|
21703
|
-
<
|
|
21704
|
-
|
|
21535
|
+
<div class="rail-search">
|
|
21536
|
+
<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>
|
|
21537
|
+
<input id="session-search" class="search" placeholder="Search chats" autocomplete="off">
|
|
21538
|
+
</div>
|
|
21705
21539
|
<div id="sessions"></div>
|
|
21540
|
+
<div class="rail-footer">
|
|
21541
|
+
<button type="button" id="fork-session" title="Fork this conversation">
|
|
21542
|
+
<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>
|
|
21543
|
+
Fork chat
|
|
21544
|
+
</button>
|
|
21545
|
+
<button type="button" id="rail-settings">
|
|
21546
|
+
<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>
|
|
21547
|
+
Settings
|
|
21548
|
+
</button>
|
|
21549
|
+
<div class="repo-mini" title="${repositoryRoot}">${repositoryName} \xB7 ${branch}</div>
|
|
21706
21550
|
</div>
|
|
21707
21551
|
</aside>
|
|
21552
|
+
|
|
21708
21553
|
<div class="stage">
|
|
21709
|
-
<header>
|
|
21710
|
-
|
|
21711
|
-
<
|
|
21712
|
-
|
|
21554
|
+
<header class="topbar">
|
|
21555
|
+
<div class="topbar-left">
|
|
21556
|
+
<button type="button" class="icon-btn" id="toggle-rail" title="Chats" aria-label="Toggle chats">
|
|
21557
|
+
<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>
|
|
21558
|
+
</button>
|
|
21559
|
+
<button type="button" class="icon-btn top-new-chat" id="top-new-session" title="New chat" aria-label="New chat">
|
|
21560
|
+
<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>
|
|
21561
|
+
</button>
|
|
21562
|
+
<div class="session-title" id="session-title"><span id="session-label">New session</span></div>
|
|
21713
21563
|
</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>
|
|
21564
|
+
<div class="top-actions">
|
|
21565
|
+
<span class="top-status" id="status" hidden></span>
|
|
21566
|
+
<button type="button" class="toolbar-btn" id="changes-pill" title="Open workspace">
|
|
21567
|
+
<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>
|
|
21568
|
+
<span class="toolbar-label">Changes</span><span class="count" id="changes-count">0</span>
|
|
21569
|
+
<span hidden id="changes-plus">+0</span><span hidden id="changes-minus">\u22120</span>
|
|
21570
|
+
</button>
|
|
21571
|
+
<button type="button" class="icon-btn" id="toggle-term" title="Terminal" aria-label="Toggle terminal">
|
|
21572
|
+
<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>
|
|
21573
|
+
</button>
|
|
21574
|
+
<button type="button" class="icon-btn" id="toggle-changes" title="Workspace" aria-label="Toggle workspace">
|
|
21575
|
+
<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>
|
|
21576
|
+
</button>
|
|
21577
|
+
<button type="button" class="icon-btn" id="studio-open" title="Settings" aria-label="Settings">
|
|
21578
|
+
<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>
|
|
21579
|
+
</button>
|
|
21580
|
+
<button type="button" class="icon-btn" id="stop" title="Stop run" aria-label="Stop" hidden>\u25A0</button>
|
|
21741
21581
|
</div>
|
|
21582
|
+
<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
21583
|
</header>
|
|
21584
|
+
|
|
21743
21585
|
<main>
|
|
21744
21586
|
<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>
|
|
21587
|
+
<h1>What are we building?</h1>
|
|
21588
|
+
<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>
|
|
21589
|
+
<div class="empty-actions">
|
|
21590
|
+
<button type="button" data-starter="Review the current changes and tell me what needs fixing">Review current changes</button>
|
|
21591
|
+
<button type="button" data-starter="Explain this repository and its main architecture">Explain the repository</button>
|
|
21592
|
+
<button type="button" id="empty-commands">Browse commands</button>
|
|
21593
|
+
</div>
|
|
21760
21594
|
</div>
|
|
21761
21595
|
<div id="feed"></div>
|
|
21762
21596
|
</main>
|
|
21597
|
+
|
|
21763
21598
|
<div class="term" id="term">
|
|
21764
21599
|
<header>
|
|
21765
|
-
<span>Terminal \xB7 repo root
|
|
21600
|
+
<span>Terminal \xB7 repo root</span>
|
|
21766
21601
|
<span>
|
|
21767
|
-
<label class="always-row"><input type="checkbox" id="term-bg">
|
|
21602
|
+
<label class="always-row"><input type="checkbox" id="term-bg"> background</label>
|
|
21768
21603
|
<div class="pick" data-pick="term-timeout">
|
|
21769
21604
|
<button type="button" class="pick-open" id="term-timeout-open" aria-haspopup="listbox" aria-expanded="false">60s <span class="caret">\u25BE</span></button>
|
|
21770
21605
|
<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>
|
|
21606
|
+
<select id="term-timeout" aria-label="Timeout"><option value="60000">60s</option><option value="180000">3m</option><option value="600000">10m</option></select>
|
|
21776
21607
|
</div>
|
|
21777
21608
|
<button type="button" id="term-clear">Clear</button>
|
|
21778
21609
|
</span>
|
|
21779
21610
|
</header>
|
|
21780
21611
|
<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>
|
|
21612
|
+
<form id="term-form"><input id="term-input" autocomplete="off" spellcheck="false" placeholder="Run a command in this repository\u2026"></form>
|
|
21784
21613
|
</div>
|
|
21614
|
+
|
|
21785
21615
|
<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
21616
|
<div class="composer">
|
|
21801
|
-
<div id="mention">
|
|
21802
|
-
<div id="mention-list"></div>
|
|
21803
|
-
</div>
|
|
21617
|
+
<div id="mention"><div id="mention-list"></div></div>
|
|
21804
21618
|
<div class="composer-line">
|
|
21805
21619
|
<div class="cmds">
|
|
21806
|
-
<button type="button" class="plus-btn" id="cmd-open" aria-haspopup="menu" aria-expanded="false" title="
|
|
21620
|
+
<button type="button" class="plus-btn" id="cmd-open" aria-haspopup="menu" aria-expanded="false" title="Add context or browse commands">+</button>
|
|
21807
21621
|
<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>
|
|
21622
|
+
<button type="button" id="commands-open">Commands & skills\u2026</button>
|
|
21623
|
+
<button type="button" id="attach">Attach repository path\u2026</button>
|
|
21624
|
+
<button type="button" data-cmd="/login">Login / connect inference</button>
|
|
21825
21625
|
</div>
|
|
21826
21626
|
</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>
|
|
21627
|
+
<textarea id="input" rows="1" placeholder="Message CritiqueCode\u2026" title="Type / for commands and skills, @ to add context"></textarea>
|
|
21833
21628
|
<button type="button" class="mic-btn" id="voice" title="Voice input" aria-label="Voice input">
|
|
21834
21629
|
<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
21630
|
</button>
|
|
21836
21631
|
</div>
|
|
21837
21632
|
<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>
|
|
21633
|
+
<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
21634
|
<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">
|
|
21635
|
+
<div class="composer-left">
|
|
21859
21636
|
<div class="pick" data-pick="mode">
|
|
21860
21637
|
<button type="button" class="pick-open" id="mode-open" aria-haspopup="listbox" aria-expanded="false">Agent <span class="caret">\u25BE</span></button>
|
|
21861
21638
|
<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>
|
|
21639
|
+
<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
21640
|
</div>
|
|
21869
21641
|
<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>
|
|
21642
|
+
<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
21643
|
<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>
|
|
21644
|
+
<select id="autonomy" aria-label="Approval mode"><option value="ask">Ask</option><option value="auto">Auto approve</option></select>
|
|
21876
21645
|
</div>
|
|
21877
21646
|
<div class="model-wrap pick">
|
|
21878
21647
|
<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>
|
|
21648
|
+
<div id="model-menu"><input id="model-filter" placeholder="Search models\u2026" autocomplete="off"><div id="model-list"></div></div>
|
|
21883
21649
|
<select id="model" aria-label="Author model">${options}</select>
|
|
21884
21650
|
</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>
|
|
21651
|
+
</div>
|
|
21652
|
+
<div class="composer-right">
|
|
21653
|
+
<button type="button" id="review-run" title="Run an independent review">Review</button>
|
|
21654
|
+
<button type="button" id="send" aria-label="Send" title="Send">
|
|
21655
|
+
<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>
|
|
21656
|
+
</button>
|
|
21907
21657
|
</div>
|
|
21908
21658
|
</div>
|
|
21909
21659
|
</div>
|
|
21910
21660
|
</div>
|
|
21911
21661
|
</div>
|
|
21912
|
-
|
|
21662
|
+
|
|
21663
|
+
<div class="gutter" id="gutter" title="Resize workspace"></div>
|
|
21913
21664
|
<aside class="changes" id="changes-pane">
|
|
21914
21665
|
<header>
|
|
21915
21666
|
<h2>Workspace</h2>
|
|
21916
|
-
<button type="button" class="icon-btn" id="close-changes" title="
|
|
21917
|
-
<div class="sum" id="changes-sum"
|
|
21667
|
+
<button type="button" class="icon-btn" id="close-changes" title="Close workspace" aria-label="Close workspace">\xD7</button>
|
|
21668
|
+
<div class="sum" id="changes-sum">${branch}</div>
|
|
21669
|
+
<ol class="gate" id="ship-gate"></ol>
|
|
21918
21670
|
</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>
|
|
21671
|
+
<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
21672
|
<div class="work-stack">
|
|
21926
21673
|
<div class="workspace" id="tab-tree">
|
|
21927
|
-
<input id="grep" placeholder="
|
|
21674
|
+
<input id="grep" placeholder="Find file or text\u2026">
|
|
21928
21675
|
<div class="tree" id="tree"></div>
|
|
21929
21676
|
<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>
|
|
21677
|
+
<div class="diff-title-wrap">
|
|
21678
|
+
<button type="button" id="all-changes" class="diff-back" hidden>\u2190 All changes</button>
|
|
21679
|
+
<b id="diff-title">Working changes</b>
|
|
21936
21680
|
</div>
|
|
21681
|
+
<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
21682
|
</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>
|
|
21683
|
+
<div class="diff" id="diff"><div class="diff-loading">Open Workspace to inspect working-tree diffs.</div></div>
|
|
21684
|
+
<pre id="file-view" hidden></pre><iframe id="preview" hidden sandbox="allow-same-origin" title="Preview"></iframe>
|
|
21952
21685
|
</div>
|
|
21686
|
+
<div class="workspace" id="tab-findings" hidden><input id="find-filter" placeholder="Filter findings\u2026"><div id="find-list" class="tree"></div></div>
|
|
21687
|
+
<div class="workspace" id="tab-timeline" hidden><div id="timeline" class="tree"></div></div>
|
|
21688
|
+
<div class="compare" id="tab-compare" hidden><div id="compare-left"></div><div id="compare-right"></div></div>
|
|
21953
21689
|
</div>
|
|
21954
21690
|
<div class="change-list" id="change-list"></div>
|
|
21955
21691
|
</aside>
|
|
21956
21692
|
</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>
|
|
21693
|
+
|
|
21694
|
+
<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>
|
|
21695
|
+
|
|
21696
|
+
<div class="palette" id="palette"><input id="palette-q" placeholder="Commands and skills\u2026" autocomplete="off"><div id="palette-list"></div></div>
|
|
21697
|
+
|
|
21698
|
+
<div class="sheet" id="command-sheet"><div class="card command-card">
|
|
21699
|
+
<div class="sheet-head"><h3>Commands & skills</h3><button type="button" id="close-commands" aria-label="Close">\xD7</button></div>
|
|
21700
|
+
<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
21701
|
</div></div>
|
|
22015
|
-
|
|
22016
|
-
|
|
22017
|
-
|
|
22018
|
-
|
|
22019
|
-
|
|
22020
|
-
<button type="button" id="
|
|
21702
|
+
|
|
21703
|
+
<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>
|
|
21704
|
+
|
|
21705
|
+
<div class="sheet" id="studio-sheet"><div class="card settings-card">
|
|
21706
|
+
<nav class="settings-nav">
|
|
21707
|
+
<div class="settings-nav-head"><b>Settings</b><button type="button" class="settings-close" id="close-studio" aria-label="Close settings">\xD7</button></div>
|
|
21708
|
+
<div class="settings-mobile-tabs" style="display:contents">
|
|
21709
|
+
<button type="button" class="on" data-settings-tab="general">General</button>
|
|
21710
|
+
<button type="button" data-settings-tab="models">Models</button>
|
|
21711
|
+
<button type="button" data-settings-tab="usage">Usage</button>
|
|
21712
|
+
<button type="button" data-settings-tab="skills">Skills</button>
|
|
21713
|
+
<button type="button" data-settings-tab="approvals">Approvals</button>
|
|
21714
|
+
<button type="button" data-settings-tab="connections">Connections</button>
|
|
21715
|
+
</div>
|
|
21716
|
+
</nav>
|
|
21717
|
+
<div class="settings-content">
|
|
21718
|
+
<section class="settings-panel on" data-settings-panel="general">
|
|
21719
|
+
<h2>General</h2><p class="sub">Keep the chat surface quiet; the controls that matter less live here.</p>
|
|
21720
|
+
<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>
|
|
21721
|
+
<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>
|
|
21722
|
+
<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>
|
|
21723
|
+
<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>
|
|
21724
|
+
<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>
|
|
21725
|
+
${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>` : ""}
|
|
21726
|
+
<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>
|
|
21727
|
+
</section>
|
|
21728
|
+
|
|
21729
|
+
<section class="settings-panel" data-settings-panel="models">
|
|
21730
|
+
<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>
|
|
21731
|
+
<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>
|
|
21732
|
+
<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>
|
|
21733
|
+
<div id="studio-indep" class="settings-note"></div>
|
|
21734
|
+
</section>
|
|
21735
|
+
|
|
21736
|
+
<section class="settings-panel" data-settings-panel="usage">
|
|
21737
|
+
<h2>Usage</h2><p class="sub">Token and cost usage for this loaded chat, plus server-side phase/model totals when available.</p>
|
|
21738
|
+
<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>
|
|
21739
|
+
<div class="usage-chart" id="usage-chart"><div class="usage-empty">Usage appears here as model calls complete.</div></div>
|
|
21740
|
+
<h3>By phase</h3><div class="breakdown" id="usage-phase"></div>
|
|
21741
|
+
<h3>By model</h3><div class="breakdown" id="usage-model"></div>
|
|
21742
|
+
<pre id="cost-panel" hidden></pre>
|
|
21743
|
+
</section>
|
|
21744
|
+
|
|
21745
|
+
<section class="settings-panel" data-settings-panel="skills">
|
|
21746
|
+
<h2>Skills</h2><p class="sub">Skills extend the author with repository- or agent-specific guidance.</p>
|
|
21747
|
+
<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>
|
|
21748
|
+
<div id="skill-list" class="skill-list" style="margin-top:10px"></div>
|
|
21749
|
+
</section>
|
|
21750
|
+
|
|
21751
|
+
<section class="settings-panel" data-settings-panel="approvals">
|
|
21752
|
+
<h2>Approvals</h2><p class="sub">Recent command approval decisions on this machine.</p>
|
|
21753
|
+
<div id="audit-panel" class="audit-list"></div>
|
|
21754
|
+
</section>
|
|
21755
|
+
|
|
21756
|
+
<section class="settings-panel" data-settings-panel="connections">
|
|
21757
|
+
<h2>Connections</h2><p class="sub">Store provider keys locally for BYOK routes.</p>
|
|
21758
|
+
<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>
|
|
21759
|
+
<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>
|
|
21760
|
+
<div class="modal-actions"><button type="button" id="save-key">Store key</button></div>
|
|
21761
|
+
</section>
|
|
22021
21762
|
</div>
|
|
22022
21763
|
</div></div>
|
|
21764
|
+
|
|
21765
|
+
<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>
|
|
21766
|
+
<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
21767
|
<script type="application/json" id="boot">${bootJson}</script>
|
|
22024
21768
|
<script type="application/json" id="model-icons">${iconsJson}</script>
|
|
22025
21769
|
<script type="application/json" id="thinking-boot">${thinkingJson}</script>
|
|
@@ -22076,6 +21820,12 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22076
21820
|
var busy = false;
|
|
22077
21821
|
var promptQueue = [];
|
|
22078
21822
|
var applyingSnapshot = false;
|
|
21823
|
+
var usageHistory = [];
|
|
21824
|
+
var studioCosts = null;
|
|
21825
|
+
var workspaceRefreshTimer = null;
|
|
21826
|
+
var workspacePollTimer = null;
|
|
21827
|
+
var thinkingStartedAt = 0;
|
|
21828
|
+
var thinkingTimer = null;
|
|
22079
21829
|
var thinkingEl = document.getElementById("thinking");
|
|
22080
21830
|
if (thinkingEl) {
|
|
22081
21831
|
(thinkingBoot.levels || []).forEach(function (level) {
|
|
@@ -22146,8 +21896,12 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22146
21896
|
}
|
|
22147
21897
|
|
|
22148
21898
|
function modelIconHtml(option) {
|
|
22149
|
-
var
|
|
22150
|
-
|
|
21899
|
+
var provider = option && (option.getAttribute("data-provider") || "") || "other";
|
|
21900
|
+
var raw = option && (option.getAttribute("data-icon") || iconMap[provider] || "");
|
|
21901
|
+
if (raw) return raw;
|
|
21902
|
+
var label = option && (option.text || option.value) || provider || "model";
|
|
21903
|
+
var letter = String(label).replace(/^[^a-z0-9]+/i, "").charAt(0).toUpperCase() || "M";
|
|
21904
|
+
return "<span class=\\"model-fallback\\" aria-hidden=\\"true\\">" + esc(letter) + "</span>";
|
|
22151
21905
|
}
|
|
22152
21906
|
|
|
22153
21907
|
function setPickLabel(openId, text, iconHtml) {
|
|
@@ -22269,6 +22023,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22269
22023
|
render();
|
|
22270
22024
|
menu.className = "pick-menu open";
|
|
22271
22025
|
open.setAttribute("aria-expanded", "true");
|
|
22026
|
+
trapWheel(menu);
|
|
22272
22027
|
}
|
|
22273
22028
|
});
|
|
22274
22029
|
menu.addEventListener("click", function (e) { e.stopPropagation(); });
|
|
@@ -22504,10 +22259,22 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22504
22259
|
if (modelEl) modelEl.disabled = false;
|
|
22505
22260
|
sendEl.className = busy ? "steer" : "";
|
|
22506
22261
|
sendEl.setAttribute("aria-label", busy ? "Queue follow-up" : "Send");
|
|
22507
|
-
|
|
22262
|
+
sendEl.title = busy ? "Queue follow-up" : "Send";
|
|
22263
|
+
inputEl.placeholder = busy ? "Queue a follow-up\u2026" : "Message CritiqueCode\u2026";
|
|
22508
22264
|
var stop = document.getElementById("stop");
|
|
22509
22265
|
if (stop) stop.hidden = !busy;
|
|
22510
|
-
if (
|
|
22266
|
+
if (busy && !workspacePollTimer) {
|
|
22267
|
+
workspacePollTimer = setInterval(function () { refreshWorkspaceSnapshot(false); }, 1800);
|
|
22268
|
+
}
|
|
22269
|
+
if (!busy && workspacePollTimer) {
|
|
22270
|
+
clearInterval(workspacePollTimer);
|
|
22271
|
+
workspacePollTimer = null;
|
|
22272
|
+
}
|
|
22273
|
+
if (!busy) finishThinkingTimer();
|
|
22274
|
+
if (was && !busy) {
|
|
22275
|
+
refreshWorkspaceSnapshot(true);
|
|
22276
|
+
flushQueue(false);
|
|
22277
|
+
}
|
|
22511
22278
|
}
|
|
22512
22279
|
|
|
22513
22280
|
function renderQueue() {
|
|
@@ -22541,6 +22308,11 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22541
22308
|
}
|
|
22542
22309
|
|
|
22543
22310
|
function dispatchPrompt(text) {
|
|
22311
|
+
var normalized = text.trim().toLowerCase();
|
|
22312
|
+
if (normalized === "/resume" || normalized === "resume") {
|
|
22313
|
+
showResumePicker();
|
|
22314
|
+
return;
|
|
22315
|
+
}
|
|
22544
22316
|
if (text === "/login" || text === "login") {
|
|
22545
22317
|
startLogin();
|
|
22546
22318
|
return;
|
|
@@ -22591,6 +22363,29 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22591
22363
|
resetUsage();
|
|
22592
22364
|
}
|
|
22593
22365
|
|
|
22366
|
+
function deleteSession(id, title) {
|
|
22367
|
+
if (!id) return;
|
|
22368
|
+
var name = title || "this chat";
|
|
22369
|
+
if (!window.confirm("Delete " + name + "? This cannot be undone.")) return;
|
|
22370
|
+
var path = "/api/sessions/" + encodeURIComponent(id);
|
|
22371
|
+
api("DELETE", path).then(function (res) {
|
|
22372
|
+
if (res.ok) return res;
|
|
22373
|
+
if (res.status !== 404 && res.status !== 405) return res;
|
|
22374
|
+
return api("POST", "/api/sessions/delete", { id: id });
|
|
22375
|
+
}).then(function (res) {
|
|
22376
|
+
if (!res || !res.ok) {
|
|
22377
|
+
if (!res) return;
|
|
22378
|
+
return readError(res, "Session deletion is not available in this build.").then(function (msg) { addBlock("alert", msg); });
|
|
22379
|
+
}
|
|
22380
|
+
return api("GET", "/api/snapshot").then(function (fresh) {
|
|
22381
|
+
if (!fresh.ok) return;
|
|
22382
|
+
return fresh.json().then(function (body) {
|
|
22383
|
+
if (body.sessions) renderSessions(body.sessions, body.session_id || body.id || activeSessionId);
|
|
22384
|
+
});
|
|
22385
|
+
});
|
|
22386
|
+
}).catch(function () { addBlock("alert", "Could not delete that chat."); });
|
|
22387
|
+
}
|
|
22388
|
+
|
|
22594
22389
|
function renderSessions(list, activeId) {
|
|
22595
22390
|
allSessions = list || allSessions;
|
|
22596
22391
|
if (!sessionsEl) return;
|
|
@@ -22599,20 +22394,104 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22599
22394
|
(allSessions || []).filter(function (item) {
|
|
22600
22395
|
return !q || String(item.title || "").toLowerCase().indexOf(q) >= 0;
|
|
22601
22396
|
}).forEach(function (item) {
|
|
22397
|
+
var row = document.createElement("div");
|
|
22398
|
+
row.className = "session-row" + (item.id === activeId ? " on" : "");
|
|
22602
22399
|
var btn = document.createElement("button");
|
|
22603
22400
|
btn.type = "button";
|
|
22604
|
-
btn.className = "session-item"
|
|
22401
|
+
btn.className = "session-item";
|
|
22605
22402
|
btn.textContent = item.title || "Session";
|
|
22606
22403
|
btn.title = item.title || item.id;
|
|
22607
22404
|
btn.addEventListener("click", function () {
|
|
22608
22405
|
if (item.id === activeSessionId) return;
|
|
22406
|
+
api("POST", "/api/sessions/select", { id: item.id }).catch(function () { addBlock("alert", "Could not open that chat."); });
|
|
22407
|
+
if (window.innerWidth <= 760) { layout.rail = false; applyLayout(); }
|
|
22408
|
+
});
|
|
22409
|
+
btn.addEventListener("dblclick", function (e) {
|
|
22410
|
+
e.preventDefault();
|
|
22411
|
+
e.stopPropagation();
|
|
22412
|
+
var next = window.prompt("Rename chat", item.title || "Session");
|
|
22413
|
+
if (!next) return;
|
|
22414
|
+
renameSession(item.id, next.trim());
|
|
22415
|
+
});
|
|
22416
|
+
var del = document.createElement("button");
|
|
22417
|
+
del.type = "button";
|
|
22418
|
+
del.className = "session-delete";
|
|
22419
|
+
del.title = "Delete chat";
|
|
22420
|
+
del.setAttribute("aria-label", "Delete " + (item.title || "chat"));
|
|
22421
|
+
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>";
|
|
22422
|
+
del.addEventListener("click", function (e) { e.stopPropagation(); deleteSession(item.id, item.title || "this chat"); });
|
|
22423
|
+
row.appendChild(btn); row.appendChild(del); sessionsEl.appendChild(row);
|
|
22424
|
+
});
|
|
22425
|
+
activeSessionId = activeId || activeSessionId;
|
|
22426
|
+
}
|
|
22427
|
+
|
|
22428
|
+
function renameSession(id, title) {
|
|
22429
|
+
if (!id || !title) return;
|
|
22430
|
+
api("POST", "/api/sessions/rename", { id: id, title: title }).then(function (res) {
|
|
22431
|
+
if (!res.ok) return readError(res, "Could not rename that chat.").then(function (msg) { addBlock("alert", msg); });
|
|
22432
|
+
return res.json().then(function (body) {
|
|
22433
|
+
if (body.sessions) renderSessions(body.sessions, body.id || activeSessionId);
|
|
22434
|
+
if (body.title) setSessionTitle(body.title);
|
|
22435
|
+
});
|
|
22436
|
+
}).catch(function () { addBlock("alert", "Could not rename that chat."); });
|
|
22437
|
+
}
|
|
22438
|
+
|
|
22439
|
+
function showResumePicker() {
|
|
22440
|
+
showFeed();
|
|
22441
|
+
turnEl = null;
|
|
22442
|
+
assistantEl = null;
|
|
22443
|
+
var wrap = document.createElement("div");
|
|
22444
|
+
wrap.className = "resume-picker";
|
|
22445
|
+
var head = document.createElement("div");
|
|
22446
|
+
head.className = "resume-head";
|
|
22447
|
+
var title = document.createElement("strong");
|
|
22448
|
+
title.textContent = "Resume a chat";
|
|
22449
|
+
var hint = document.createElement("span");
|
|
22450
|
+
hint.textContent = String((allSessions || []).length) + " chats";
|
|
22451
|
+
head.appendChild(title);
|
|
22452
|
+
head.appendChild(hint);
|
|
22453
|
+
wrap.appendChild(head);
|
|
22454
|
+
var list = document.createElement("div");
|
|
22455
|
+
list.className = "resume-list";
|
|
22456
|
+
var sessions = (allSessions || []).filter(function (item) { return item.id !== activeSessionId; });
|
|
22457
|
+
if (!sessions.length) {
|
|
22458
|
+
var empty = document.createElement("div");
|
|
22459
|
+
empty.className = "resume-empty";
|
|
22460
|
+
empty.textContent = "No other chats yet.";
|
|
22461
|
+
list.appendChild(empty);
|
|
22462
|
+
}
|
|
22463
|
+
sessions.forEach(function (item) {
|
|
22464
|
+
var row = document.createElement("button");
|
|
22465
|
+
row.type = "button";
|
|
22466
|
+
row.className = "resume-chat";
|
|
22467
|
+
var copy = document.createElement("span");
|
|
22468
|
+
copy.className = "resume-copy";
|
|
22469
|
+
var chatTitle = document.createElement("strong");
|
|
22470
|
+
chatTitle.textContent = item.title || "Untitled chat";
|
|
22471
|
+
copy.appendChild(chatTitle);
|
|
22472
|
+
if (item.updated_at || item.created_at) {
|
|
22473
|
+
var time = document.createElement("span");
|
|
22474
|
+
var value = item.updated_at || item.created_at;
|
|
22475
|
+
try {
|
|
22476
|
+
time.textContent = new Date(value).toLocaleString([], { dateStyle: "medium", timeStyle: "short" });
|
|
22477
|
+
} catch (e) { time.textContent = ""; }
|
|
22478
|
+
copy.appendChild(time);
|
|
22479
|
+
}
|
|
22480
|
+
var arrow = document.createElement("span");
|
|
22481
|
+
arrow.className = "resume-arrow";
|
|
22482
|
+
arrow.textContent = "\u203A";
|
|
22483
|
+
row.appendChild(copy);
|
|
22484
|
+
row.appendChild(arrow);
|
|
22485
|
+
row.addEventListener("click", function () {
|
|
22609
22486
|
api("POST", "/api/sessions/select", { id: item.id }).catch(function () {
|
|
22610
|
-
addBlock("alert", "Could not
|
|
22487
|
+
addBlock("alert", "Could not resume that chat.");
|
|
22611
22488
|
});
|
|
22612
22489
|
});
|
|
22613
|
-
|
|
22490
|
+
list.appendChild(row);
|
|
22614
22491
|
});
|
|
22615
|
-
|
|
22492
|
+
wrap.appendChild(list);
|
|
22493
|
+
feedEl.appendChild(wrap);
|
|
22494
|
+
scrollMain();
|
|
22616
22495
|
}
|
|
22617
22496
|
|
|
22618
22497
|
function replayEvents(events) {
|
|
@@ -22640,12 +22519,14 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22640
22519
|
showFeed();
|
|
22641
22520
|
turnEl = null;
|
|
22642
22521
|
assistantEl = null;
|
|
22522
|
+
var copy = text == null ? "" : String(text);
|
|
22523
|
+
if (className === "note") {
|
|
22524
|
+
var last = feedEl.lastElementChild;
|
|
22525
|
+
if (last && last.classList.contains("note") && last.textContent === copy) return last;
|
|
22526
|
+
}
|
|
22643
22527
|
var node = document.createElement("div");
|
|
22644
22528
|
node.className = className;
|
|
22645
|
-
node.textContent =
|
|
22646
|
-
if (className !== "note") {
|
|
22647
|
-
stampTrust(node, trust || (className === "review-card" ? "evidence" : className === "alert" ? "unverified" : "unverified"));
|
|
22648
|
-
}
|
|
22529
|
+
node.textContent = copy;
|
|
22649
22530
|
feedEl.appendChild(node);
|
|
22650
22531
|
scrollMain();
|
|
22651
22532
|
return node;
|
|
@@ -22681,112 +22562,165 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22681
22562
|
scrollMain();
|
|
22682
22563
|
}
|
|
22683
22564
|
|
|
22684
|
-
function
|
|
22685
|
-
if (name === "critique_task") return;
|
|
22565
|
+
function activityRoot() {
|
|
22686
22566
|
if (!turnEl) {
|
|
22687
22567
|
showFeed();
|
|
22688
22568
|
turnEl = document.createElement("div");
|
|
22689
22569
|
turnEl.className = "turn";
|
|
22690
22570
|
feedEl.appendChild(turnEl);
|
|
22691
22571
|
}
|
|
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);
|
|
22572
|
+
var root = turnEl.querySelector(".activity");
|
|
22573
|
+
if (!root) {
|
|
22574
|
+
root = document.createElement("div");
|
|
22575
|
+
root.className = "activity";
|
|
22576
|
+
if (assistantEl) turnEl.insertBefore(root, assistantEl);
|
|
22577
|
+
else turnEl.appendChild(root);
|
|
22714
22578
|
}
|
|
22579
|
+
return root;
|
|
22580
|
+
}
|
|
22581
|
+
|
|
22582
|
+
function humanToolName(name) {
|
|
22583
|
+
return String(name || "tool").replace(/_/g, " ");
|
|
22584
|
+
}
|
|
22585
|
+
|
|
22586
|
+
function addTool(name, phase, detail) {
|
|
22587
|
+
if (name === "critique_task") return;
|
|
22588
|
+
var root = activityRoot();
|
|
22589
|
+
var node = document.createElement("details");
|
|
22590
|
+
var state = /fail|error|denied/i.test(String(phase || "")) ? "failed" : /start|run|progress/i.test(String(phase || "")) ? "running" : "done";
|
|
22591
|
+
node.className = "tool-event " + state;
|
|
22592
|
+
if (detail) node.open = false;
|
|
22593
|
+
var summary = document.createElement("summary");
|
|
22594
|
+
var dot = document.createElement("span"); dot.className = "tool-dot";
|
|
22595
|
+
var label = document.createElement("span"); label.className = "tool-name"; label.textContent = humanToolName(name);
|
|
22596
|
+
var p = document.createElement("span"); p.className = "tool-phase"; p.textContent = phase || "";
|
|
22597
|
+
summary.appendChild(dot); summary.appendChild(label); if (phase) summary.appendChild(p);
|
|
22598
|
+
node.appendChild(summary);
|
|
22599
|
+
if (detail) { var body = document.createElement("div"); body.className = "tool-detail"; body.textContent = detail; node.appendChild(body); }
|
|
22600
|
+
root.appendChild(node);
|
|
22601
|
+
scheduleWorkspaceRefresh();
|
|
22715
22602
|
scrollMain();
|
|
22716
22603
|
}
|
|
22717
22604
|
|
|
22718
|
-
function
|
|
22719
|
-
if (
|
|
22720
|
-
|
|
22721
|
-
|
|
22722
|
-
|
|
22723
|
-
|
|
22605
|
+
function finishThinkingTimer() {
|
|
22606
|
+
if (thinkingTimer) { clearInterval(thinkingTimer); thinkingTimer = null; }
|
|
22607
|
+
var node = turnEl && turnEl.querySelector(".think");
|
|
22608
|
+
if (node && thinkingStartedAt && !applyingSnapshot) {
|
|
22609
|
+
var s = node.querySelector("summary span:last-child");
|
|
22610
|
+
if (s) s.textContent = "Thinking \xB7 " + Math.max(1, Math.round((Date.now() - thinkingStartedAt) / 1000)) + "s";
|
|
22724
22611
|
}
|
|
22725
|
-
|
|
22612
|
+
thinkingStartedAt = 0;
|
|
22613
|
+
}
|
|
22614
|
+
|
|
22615
|
+
function addThink(text) {
|
|
22616
|
+
var root = activityRoot();
|
|
22617
|
+
var node = root.querySelector(".think");
|
|
22726
22618
|
if (!node) {
|
|
22727
22619
|
node = document.createElement("details");
|
|
22728
22620
|
node.className = "think";
|
|
22729
|
-
|
|
22730
|
-
|
|
22731
|
-
|
|
22732
|
-
|
|
22733
|
-
|
|
22621
|
+
var summary = document.createElement("summary");
|
|
22622
|
+
summary.innerHTML = "<span class=\\"tool-dot\\"></span><span>Thinking</span>";
|
|
22623
|
+
var body = document.createElement("div");
|
|
22624
|
+
node.appendChild(summary); node.appendChild(body); root.appendChild(node);
|
|
22625
|
+
if (!applyingSnapshot) {
|
|
22626
|
+
thinkingStartedAt = Date.now();
|
|
22627
|
+
thinkingTimer = setInterval(function () {
|
|
22628
|
+
if (!thinkingStartedAt) return;
|
|
22629
|
+
var label = summary.querySelector("span:last-child");
|
|
22630
|
+
if (label) label.textContent = "Thinking \xB7 " + Math.max(1, Math.round((Date.now() - thinkingStartedAt) / 1000)) + "s";
|
|
22631
|
+
}, 1000);
|
|
22632
|
+
}
|
|
22633
|
+
}
|
|
22634
|
+
var bodyEl = node.querySelector("div");
|
|
22635
|
+
if (bodyEl) bodyEl.textContent = (bodyEl.textContent || "") + (text || "");
|
|
22734
22636
|
scrollMain();
|
|
22735
22637
|
}
|
|
22736
22638
|
|
|
22737
22639
|
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();
|
|
22640
|
+
tokensIn = 0; tokensOut = 0; tokensReason = 0; contextUsed = 0;
|
|
22641
|
+
lastInput = 0; lastOutput = 0; lastReason = 0; costUsd = 0; usageHistory = [];
|
|
22642
|
+
renderUsagePanel(studioCosts);
|
|
22752
22643
|
}
|
|
22753
22644
|
|
|
22754
22645
|
function addUsage(ev) {
|
|
22755
22646
|
lastInput = Number(ev.input_tokens || 0);
|
|
22756
22647
|
lastOutput = Number(ev.output_tokens || 0);
|
|
22757
22648
|
lastReason = Number(ev.reasoning_tokens || 0);
|
|
22758
|
-
tokensIn += lastInput;
|
|
22759
|
-
|
|
22760
|
-
|
|
22761
|
-
|
|
22649
|
+
tokensIn += lastInput; tokensOut += lastOutput; tokensReason += lastReason;
|
|
22650
|
+
var eventCost = Number(ev.cost_usd || 0);
|
|
22651
|
+
if (!eventCost) eventCost = estimateUsageCostUsd(lastInput, lastOutput, lastReason);
|
|
22652
|
+
costUsd += eventCost;
|
|
22762
22653
|
contextUsed = lastInput + lastOutput + lastReason;
|
|
22763
|
-
|
|
22764
|
-
|
|
22765
|
-
|
|
22766
|
-
|
|
22654
|
+
usageHistory.push({
|
|
22655
|
+
input: lastInput, output: lastOutput, reasoning: lastReason,
|
|
22656
|
+
cost: Number(ev.cost_usd || 0), model: ev.model || "", phase: ev.source || ev.phase || "author", at: Date.now()
|
|
22657
|
+
});
|
|
22658
|
+
if (usageHistory.length > 80) usageHistory = usageHistory.slice(-80);
|
|
22659
|
+
renderUsagePanel(studioCosts);
|
|
22660
|
+
}
|
|
22661
|
+
|
|
22662
|
+
function updateContextRing() { renderUsagePanel(studioCosts); }
|
|
22663
|
+
|
|
22664
|
+
function fmtNum(value) { return Number(value || 0).toLocaleString(); }
|
|
22665
|
+
function fmtCost(value) { return "$" + Number(value || 0).toFixed(Number(value || 0) < 1 ? 4 : 2); }
|
|
22666
|
+
|
|
22667
|
+
function estimateUsageCostUsd(input, output, reasoning) {
|
|
22668
|
+
return Number(input || 0) * 0.0000001 + Number(output || 0) * 0.0000004 + Number(reasoning || 0) * 0.0000002;
|
|
22669
|
+
}
|
|
22670
|
+
|
|
22671
|
+
function renderBars(targetId, rows) {
|
|
22672
|
+
var target = document.getElementById(targetId);
|
|
22673
|
+
if (!target) return;
|
|
22674
|
+
target.innerHTML = "";
|
|
22675
|
+
if (!rows || !rows.length) { target.innerHTML = "<div class=\\"usage-empty\\" style=\\"height:52px\\">No data yet</div>"; return; }
|
|
22676
|
+
var max = Math.max.apply(null, rows.map(function (r) { return r.value; }).concat([1]));
|
|
22677
|
+
rows.slice(0, 10).forEach(function (row) {
|
|
22678
|
+
var el = document.createElement("div"); el.className = "break-row";
|
|
22679
|
+
var name = document.createElement("span"); name.textContent = row.label;
|
|
22680
|
+
var track = document.createElement("div"); track.className = "break-track";
|
|
22681
|
+
var fill = document.createElement("div"); fill.className = "break-fill"; fill.style.width = Math.max(2, row.value / max * 100) + "%"; track.appendChild(fill);
|
|
22682
|
+
var val = document.createElement("span"); val.className = "break-val"; val.textContent = fmtNum(row.value);
|
|
22683
|
+
el.appendChild(name); el.appendChild(track); el.appendChild(val); target.appendChild(el);
|
|
22684
|
+
});
|
|
22685
|
+
}
|
|
22686
|
+
|
|
22687
|
+
function renderUsagePanel(costs) {
|
|
22688
|
+
var totalInput = costs && Number(costs.total_input || 0) || tokensIn;
|
|
22689
|
+
var totalOutput = costs && Number(costs.total_output || 0) || tokensOut;
|
|
22690
|
+
var ui = document.getElementById("usage-input"); if (ui) ui.textContent = fmtNum(totalInput);
|
|
22691
|
+
var uo = document.getElementById("usage-output"); if (uo) uo.textContent = fmtNum(totalOutput);
|
|
22692
|
+
var ur = document.getElementById("usage-reason"); if (ur) ur.textContent = fmtNum(tokensReason);
|
|
22693
|
+
var reported = costUsd || (costs && Number(costs.total_cost_usd || 0)) || 0;
|
|
22694
|
+
var display = reported > 0 ? reported : (costs && Number(costs.estimated_cost_usd || 0)) || estimateUsageCostUsd(totalInput, totalOutput, tokensReason);
|
|
22695
|
+
var estimated = reported <= 0 && display > 0;
|
|
22696
|
+
var uc = document.getElementById("usage-cost");
|
|
22697
|
+
if (uc) uc.textContent = (estimated ? "~" : "") + fmtCost(display);
|
|
22698
|
+
var chart = document.getElementById("usage-chart");
|
|
22699
|
+
if (chart) {
|
|
22700
|
+
if (!usageHistory.length) chart.innerHTML = "<div class=\\"usage-empty\\">Usage appears here as model calls complete.</div>";
|
|
22701
|
+
else {
|
|
22702
|
+
var vals = usageHistory.map(function (r) { return r.input + r.output + r.reasoning; });
|
|
22703
|
+
var max = Math.max.apply(null, vals.concat([1]));
|
|
22704
|
+
var w = 640, h = 150, gap = 2, bw = Math.max(2, (w - (vals.length - 1) * gap) / vals.length);
|
|
22705
|
+
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("");
|
|
22706
|
+
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>";
|
|
22707
|
+
}
|
|
22708
|
+
}
|
|
22709
|
+
var phaseRows = [];
|
|
22710
|
+
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) }); });
|
|
22711
|
+
else {
|
|
22712
|
+
var phase = {}; usageHistory.forEach(function (r) { var k=r.phase||"author"; phase[k]=(phase[k]||0)+r.input+r.output+r.reasoning; });
|
|
22713
|
+
Object.keys(phase).forEach(function (k) { phaseRows.push({label:k,value:phase[k]}); });
|
|
22767
22714
|
}
|
|
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";
|
|
22715
|
+
renderBars("usage-phase", phaseRows);
|
|
22716
|
+
var modelRows = [];
|
|
22717
|
+
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)}); });
|
|
22718
|
+
else {
|
|
22719
|
+
var models={}; usageHistory.forEach(function(r){var k=r.model||"current model";models[k]=(models[k]||0)+r.input+r.output+r.reasoning;});
|
|
22720
|
+
Object.keys(models).forEach(function(k){modelRows.push({label:k.replace(/^openrouter\\//,""),value:models[k]});});
|
|
22721
|
+
}
|
|
22722
|
+
modelRows.sort(function(a,b){return b.value-a.value;});
|
|
22723
|
+
renderBars("usage-model", modelRows);
|
|
22790
22724
|
}
|
|
22791
22725
|
|
|
22792
22726
|
function addAgent(detail, phase) {
|
|
@@ -22816,101 +22750,186 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22816
22750
|
if (btn) btn.innerHTML = "\u2387 " + esc(currentBranch) + " <span class=\\"caret\\">\u25BE</span>";
|
|
22817
22751
|
}
|
|
22818
22752
|
|
|
22753
|
+
function normalizeChangeFiles(data) {
|
|
22754
|
+
var files = (data && data.files) || [];
|
|
22755
|
+
if ((!files || !files.length) && data && data.changed_paths && data.changed_paths.length) {
|
|
22756
|
+
files = data.changed_paths.map(function (path) { return { path: path, added: 0, deleted: 0, kind: "modified" }; });
|
|
22757
|
+
}
|
|
22758
|
+
return files || [];
|
|
22759
|
+
}
|
|
22760
|
+
|
|
22761
|
+
function renderPatchInto(container, patch, path) {
|
|
22762
|
+
var head = document.createElement("div");
|
|
22763
|
+
head.className = "diff-file-head";
|
|
22764
|
+
head.textContent = path;
|
|
22765
|
+
container.appendChild(head);
|
|
22766
|
+
var body = document.createElement("div");
|
|
22767
|
+
body.className = "diff-patch";
|
|
22768
|
+
var patchStr = String(patch || "");
|
|
22769
|
+
if (!patchStr.trim()) {
|
|
22770
|
+
var empty = document.createElement("div");
|
|
22771
|
+
empty.className = "hunk";
|
|
22772
|
+
empty.textContent = "No textual diff available.";
|
|
22773
|
+
body.appendChild(empty);
|
|
22774
|
+
container.appendChild(body);
|
|
22775
|
+
return;
|
|
22776
|
+
}
|
|
22777
|
+
var oldLn = 0;
|
|
22778
|
+
var newLn = 0;
|
|
22779
|
+
patchStr.split("\\n").forEach(function (line) {
|
|
22780
|
+
if (line.indexOf("@@") === 0) {
|
|
22781
|
+
var hunk = line.match(/@@ -(\\d+)(?:,\\d+)? \\+(\\d+)/);
|
|
22782
|
+
if (hunk) { oldLn = Number(hunk[1]) - 1; newLn = Number(hunk[2]) - 1; }
|
|
22783
|
+
var hunkEl = document.createElement("div");
|
|
22784
|
+
hunkEl.className = "hunk";
|
|
22785
|
+
hunkEl.textContent = line;
|
|
22786
|
+
body.appendChild(hunkEl);
|
|
22787
|
+
return;
|
|
22788
|
+
}
|
|
22789
|
+
if (line.indexOf("diff ") === 0 || line.indexOf("index ") === 0 || line.indexOf("---") === 0 || line.indexOf("+++") === 0) {
|
|
22790
|
+
var meta = document.createElement("div");
|
|
22791
|
+
meta.className = "hunk";
|
|
22792
|
+
meta.textContent = line;
|
|
22793
|
+
body.appendChild(meta);
|
|
22794
|
+
return;
|
|
22795
|
+
}
|
|
22796
|
+
var kind = "ctx";
|
|
22797
|
+
var left = "";
|
|
22798
|
+
var right = "";
|
|
22799
|
+
if (line.charAt(0) === "+") { kind = "add"; newLn += 1; right = String(newLn); }
|
|
22800
|
+
else if (line.charAt(0) === "-") { kind = "del"; oldLn += 1; left = String(oldLn); }
|
|
22801
|
+
else { oldLn += 1; newLn += 1; left = String(oldLn); right = String(newLn); }
|
|
22802
|
+
var row = document.createElement("div");
|
|
22803
|
+
row.className = "row " + kind;
|
|
22804
|
+
var a = document.createElement("span"); a.className = "ln"; a.textContent = left;
|
|
22805
|
+
var b = document.createElement("span"); b.className = "ln"; b.textContent = right;
|
|
22806
|
+
var code = document.createElement("span"); code.className = "code"; code.textContent = line;
|
|
22807
|
+
row.appendChild(a); row.appendChild(b); row.appendChild(code);
|
|
22808
|
+
body.appendChild(row);
|
|
22809
|
+
});
|
|
22810
|
+
container.appendChild(body);
|
|
22811
|
+
}
|
|
22812
|
+
|
|
22813
|
+
function loadAllDiffs(files) {
|
|
22814
|
+
var diffEl = document.getElementById("diff");
|
|
22815
|
+
var view = document.getElementById("file-view");
|
|
22816
|
+
var preview = document.getElementById("preview");
|
|
22817
|
+
var title = document.getElementById("diff-title");
|
|
22818
|
+
var back = document.getElementById("all-changes");
|
|
22819
|
+
if (back) back.hidden = true;
|
|
22820
|
+
if (title) title.textContent = files.length + (files.length === 1 ? " changed file" : " changed files");
|
|
22821
|
+
if (diffEl) { diffEl.hidden = false; diffEl.innerHTML = ""; }
|
|
22822
|
+
if (view) view.hidden = true;
|
|
22823
|
+
if (preview) preview.hidden = true;
|
|
22824
|
+
if (!files || !files.length) {
|
|
22825
|
+
if (diffEl) diffEl.innerHTML = "<div class=\\"diff-loading\\">No changed files.</div>";
|
|
22826
|
+
return;
|
|
22827
|
+
}
|
|
22828
|
+
var loading = document.createElement("div");
|
|
22829
|
+
loading.className = "diff-loading";
|
|
22830
|
+
loading.textContent = "Loading diffs\u2026";
|
|
22831
|
+
if (diffEl) diffEl.appendChild(loading);
|
|
22832
|
+
var paths = files.map(function (f) { return f.path; });
|
|
22833
|
+
Promise.all(paths.map(function (path) {
|
|
22834
|
+
return api("GET", "/api/changes?path=" + encodeURIComponent(path))
|
|
22835
|
+
.then(function (res) { return res.json().then(function (body) { return { path: path, patch: body.patch }; }); })
|
|
22836
|
+
.catch(function () { return { path: path, patch: "" }; });
|
|
22837
|
+
})).then(function (results) {
|
|
22838
|
+
if (!diffEl) return;
|
|
22839
|
+
diffEl.innerHTML = "";
|
|
22840
|
+
results.forEach(function (result) {
|
|
22841
|
+
var section = document.createElement("section");
|
|
22842
|
+
section.className = "diff-file";
|
|
22843
|
+
renderPatchInto(section, result.patch || "No textual diff available.", result.path);
|
|
22844
|
+
diffEl.appendChild(section);
|
|
22845
|
+
});
|
|
22846
|
+
});
|
|
22847
|
+
}
|
|
22848
|
+
|
|
22849
|
+
function loadFileContent(path, btn) {
|
|
22850
|
+
selectedPath = path;
|
|
22851
|
+
document.querySelectorAll(".tree button").forEach(function (el) {
|
|
22852
|
+
el.classList.toggle("on", el.getAttribute("data-path") === path);
|
|
22853
|
+
});
|
|
22854
|
+
if (btn) btn.classList.add("on");
|
|
22855
|
+
var title = document.getElementById("diff-title");
|
|
22856
|
+
var diffEl = document.getElementById("diff");
|
|
22857
|
+
var view = document.getElementById("file-view");
|
|
22858
|
+
var preview = document.getElementById("preview");
|
|
22859
|
+
var back = document.getElementById("all-changes");
|
|
22860
|
+
if (back) back.hidden = false;
|
|
22861
|
+
if (title) title.textContent = path;
|
|
22862
|
+
if (diffEl) diffEl.hidden = true;
|
|
22863
|
+
if (preview) preview.hidden = true;
|
|
22864
|
+
if (view) {
|
|
22865
|
+
view.hidden = false;
|
|
22866
|
+
view.textContent = "Loading\u2026";
|
|
22867
|
+
}
|
|
22868
|
+
var pane = document.getElementById("changes-pane");
|
|
22869
|
+
if (pane) pane.classList.add("open");
|
|
22870
|
+
api("GET", "/api/file?path=" + encodeURIComponent(path))
|
|
22871
|
+
.then(function (res) {
|
|
22872
|
+
if (!res.ok) throw new Error("Could not load file");
|
|
22873
|
+
return res.json();
|
|
22874
|
+
})
|
|
22875
|
+
.then(function (file) {
|
|
22876
|
+
if (view) {
|
|
22877
|
+
view.hidden = false;
|
|
22878
|
+
view.textContent = String(file.text || "");
|
|
22879
|
+
}
|
|
22880
|
+
if (preview && /\\.html?$/i.test(path)) {
|
|
22881
|
+
preview.hidden = false;
|
|
22882
|
+
preview.srcdoc = String(file.text || "");
|
|
22883
|
+
}
|
|
22884
|
+
})
|
|
22885
|
+
.catch(function () {
|
|
22886
|
+
if (view) view.textContent = "Could not load " + path;
|
|
22887
|
+
});
|
|
22888
|
+
}
|
|
22889
|
+
|
|
22819
22890
|
function renderChanges(data) {
|
|
22820
22891
|
var list = document.getElementById("change-list");
|
|
22821
22892
|
var sum = document.getElementById("changes-sum");
|
|
22822
|
-
var files = (data
|
|
22823
|
-
var
|
|
22824
|
-
var
|
|
22893
|
+
var files = normalizeChangeFiles(data);
|
|
22894
|
+
var computedAdded = files.reduce(function (n, f) { return n + Number(f.added || 0); }, 0);
|
|
22895
|
+
var computedDeleted = files.reduce(function (n, f) { return n + Number(f.deleted || 0); }, 0);
|
|
22896
|
+
var added = Number(data && data.added || 0) || computedAdded;
|
|
22897
|
+
var deleted = Number(data && data.deleted || 0) || computedDeleted;
|
|
22825
22898
|
var branch = data && (data.branch || data.text) ? (data.branch || data.text) : currentBranch;
|
|
22826
22899
|
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;
|
|
22900
|
+
if (sum) sum.textContent = branch + " \xB7 " + files.length + (files.length === 1 ? " changed file" : " changed files") + ((added || deleted) ? " \xB7 +" + added + " \u2212" + deleted : "");
|
|
22901
|
+
var count = document.getElementById("changes-count"); if (count) count.textContent = String(files.length);
|
|
22902
|
+
var plus = document.getElementById("changes-plus"); var minus = document.getElementById("changes-minus");
|
|
22903
|
+
if (plus) plus.textContent = "+" + added; if (minus) minus.textContent = "\u2212" + deleted;
|
|
22904
|
+
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
22905
|
fileKinds = {};
|
|
22835
22906
|
files.forEach(function (file) { fileKinds[file.path] = file.kind || (file.untracked ? "untracked" : "modified"); });
|
|
22836
22907
|
if (list) {
|
|
22837
22908
|
list.innerHTML = "";
|
|
22838
22909
|
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);
|
|
22910
|
+
var btn = document.createElement("button"); btn.type = "button"; btn.className = "change-file";
|
|
22911
|
+
btn.innerHTML = "<span></span><span><span class=\\"plus\\">+" + Number(file.added || 0) + "</span> <span class=\\"minus\\">\u2212" + Number(file.deleted || 0) + "</span></span>";
|
|
22912
|
+
btn.querySelector("span").textContent = file.path; btn.addEventListener("click", function () { loadFileContent(file.path, btn); }); list.appendChild(btn);
|
|
22846
22913
|
});
|
|
22847
22914
|
}
|
|
22848
22915
|
setPaths(files.map(function (file) { return file.path; }));
|
|
22849
22916
|
loadTree();
|
|
22917
|
+
if (!selectedPath) {
|
|
22918
|
+
loadAllDiffs(files);
|
|
22919
|
+
}
|
|
22850
22920
|
}
|
|
22851
22921
|
|
|
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
|
-
}
|
|
22922
|
+
function scheduleWorkspaceRefresh() {
|
|
22923
|
+
if (workspaceRefreshTimer) clearTimeout(workspaceRefreshTimer);
|
|
22924
|
+
workspaceRefreshTimer = setTimeout(function () { refreshWorkspaceSnapshot(false); }, 450);
|
|
22925
|
+
}
|
|
22926
|
+
|
|
22927
|
+
function refreshWorkspaceSnapshot(force) {
|
|
22928
|
+
if (workspaceRefreshTimer) { clearTimeout(workspaceRefreshTimer); workspaceRefreshTimer = null; }
|
|
22929
|
+
return api("GET", "/api/snapshot").then(function (res) { return res.ok ? res.json() : null; }).then(function (s) {
|
|
22930
|
+
if (!s) return;
|
|
22931
|
+
if (s.files || s.changed_paths) renderChanges(s);
|
|
22932
|
+
if (force && s.sessions) renderSessions(s.sessions, s.active_session_id || activeSessionId);
|
|
22914
22933
|
}).catch(function () {});
|
|
22915
22934
|
}
|
|
22916
22935
|
|
|
@@ -23043,6 +23062,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23043
23062
|
break;
|
|
23044
23063
|
case "busy":
|
|
23045
23064
|
setBusy(ev.busy);
|
|
23065
|
+
if (!ev.busy) scheduleWorkspaceRefresh();
|
|
23046
23066
|
break;
|
|
23047
23067
|
case "ended":
|
|
23048
23068
|
setBusy(false);
|
|
@@ -23069,6 +23089,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23069
23089
|
if (thinkingEl && s.thinking_level) thinkingEl.value = s.thinking_level;
|
|
23070
23090
|
syncPick("mode");
|
|
23071
23091
|
syncPick("autonomy");
|
|
23092
|
+
syncAutonomyVisual();
|
|
23072
23093
|
syncPick("thinking");
|
|
23073
23094
|
syncPick("review-depth");
|
|
23074
23095
|
syncPick("review-lens");
|
|
@@ -23080,7 +23101,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23080
23101
|
if (s.events && s.events.length) replayEvents(s.events);
|
|
23081
23102
|
else if (s.last_review_text) setReview(s.last_review_text);
|
|
23082
23103
|
if (s.pending_exec) showExec(s.pending_exec);
|
|
23083
|
-
if (s.files) renderChanges(s);
|
|
23104
|
+
if (s.files || s.changed_paths) renderChanges(s);
|
|
23084
23105
|
if (s.ended) {
|
|
23085
23106
|
setStatus("Session ended", "err");
|
|
23086
23107
|
addBlock("note", "Session ended \xB7 " + s.ended);
|
|
@@ -23134,56 +23155,109 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23134
23155
|
});
|
|
23135
23156
|
}
|
|
23136
23157
|
|
|
23158
|
+
function cleanSkillDescription(s) {
|
|
23159
|
+
var desc = String(s && s.description || "").trim();
|
|
23160
|
+
var constraint = String(s && s.constraint || "").trim();
|
|
23161
|
+
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 "";
|
|
23162
|
+
return desc;
|
|
23163
|
+
}
|
|
23164
|
+
|
|
23165
|
+
function renderSkills(rows) {
|
|
23166
|
+
var skills = document.getElementById("skill-list");
|
|
23167
|
+
if (!skills) return;
|
|
23168
|
+
skills.innerHTML = "";
|
|
23169
|
+
(rows || []).forEach(function (s) {
|
|
23170
|
+
var row = document.createElement("div"); row.className = "skill-row";
|
|
23171
|
+
var head = document.createElement("div"); head.className = "skill-head";
|
|
23172
|
+
var name = document.createElement("b"); name.textContent = s.name || s.id || "Skill";
|
|
23173
|
+
var source = document.createElement("span"); source.className = "skill-source"; source.textContent = s.source || "skill";
|
|
23174
|
+
head.appendChild(name); head.appendChild(source); row.appendChild(head);
|
|
23175
|
+
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);
|
|
23176
|
+
if (s.origin) { var origin = document.createElement("div"); origin.className = "skill-origin"; origin.textContent = s.origin; row.appendChild(origin); }
|
|
23177
|
+
skills.appendChild(row);
|
|
23178
|
+
});
|
|
23179
|
+
if (!rows || !rows.length) skills.innerHTML = "<div class=\\"settings-note\\">No skills discovered.</div>";
|
|
23180
|
+
}
|
|
23181
|
+
|
|
23182
|
+
function renderAudit(rows) {
|
|
23183
|
+
var audit = document.getElementById("audit-panel"); if (!audit) return; audit.innerHTML = "";
|
|
23184
|
+
(rows || []).slice().reverse().slice(0, 80).forEach(function (a) {
|
|
23185
|
+
var row = document.createElement("div"); row.className = "audit-row";
|
|
23186
|
+
var at = document.createElement("span"); at.textContent = a.at ? new Date(a.at).toLocaleString() : "";
|
|
23187
|
+
var decision = document.createElement("span"); decision.textContent = (a.decision || "") + (a.scope ? " \xB7 " + a.scope : "");
|
|
23188
|
+
var code = document.createElement("code"); code.textContent = a.preview || a.purpose || "";
|
|
23189
|
+
row.appendChild(at); row.appendChild(decision); row.appendChild(code); audit.appendChild(row);
|
|
23190
|
+
});
|
|
23191
|
+
if (!rows || !rows.length) audit.innerHTML = "<div class=\\"settings-note\\">No approval decisions yet.</div>";
|
|
23192
|
+
}
|
|
23193
|
+
|
|
23137
23194
|
function loadStudio() {
|
|
23138
23195
|
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;
|
|
23196
|
+
var author = document.getElementById("studio-author"); var review = document.getElementById("studio-review");
|
|
23197
|
+
if (author && modelEl) { author.innerHTML = modelEl.innerHTML; author.value = modelEl.value; }
|
|
23142
23198
|
if (review && modelEl) review.innerHTML = modelEl.innerHTML;
|
|
23143
23199
|
if (body.badges) {
|
|
23200
|
+
if (review && body.badges.review && body.badges.review.id) review.value = body.badges.review.id;
|
|
23144
23201
|
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.";
|
|
23202
|
+
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
23203
|
}
|
|
23149
|
-
var skills = document.getElementById("skill-list");
|
|
23150
23204
|
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);
|
|
23205
|
+
renderSkills(body.skills || []);
|
|
23206
|
+
studioCosts = body.costs || studioCosts;
|
|
23207
|
+
renderUsagePanel(studioCosts);
|
|
23208
|
+
renderAudit(body.audit || []);
|
|
23160
23209
|
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
|
-
}
|
|
23210
|
+
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(""); }
|
|
23211
|
+
var left = document.getElementById("compare-left"); var right = document.getElementById("compare-right");
|
|
23212
|
+
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
23213
|
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");
|
|
23214
|
+
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); });
|
|
23215
|
+
syncPick("studio-author"); syncPick("studio-review"); syncPick("key-kind");
|
|
23216
|
+
trapScrollableMenus();
|
|
23184
23217
|
}).catch(function () {});
|
|
23185
23218
|
}
|
|
23186
23219
|
|
|
23220
|
+
function openSheet(id) { var el = document.getElementById(id); if (el) el.className = "sheet open"; }
|
|
23221
|
+
function closeSheet(id) { var el = document.getElementById(id); if (el) el.className = "sheet"; }
|
|
23222
|
+
|
|
23223
|
+
function renderCommandBrowser() {
|
|
23224
|
+
var list = document.getElementById("command-list"); var search = document.getElementById("command-search");
|
|
23225
|
+
if (!list) return;
|
|
23226
|
+
var q = String(search && search.value || ""); list.innerHTML = "";
|
|
23227
|
+
rankSlashItems(slashCatalog(), q).slice(0, 80).forEach(function (item) {
|
|
23228
|
+
var row = document.createElement("button"); row.type = "button"; row.className = "command-row";
|
|
23229
|
+
var code = document.createElement("span"); code.className = "command-code"; code.textContent = item.value;
|
|
23230
|
+
var desc = document.createElement("span"); desc.className = "command-desc"; desc.textContent = item.description || item.label || "";
|
|
23231
|
+
var kind = document.createElement("span"); kind.className = "command-kind"; kind.textContent = item.kind;
|
|
23232
|
+
row.appendChild(code); row.appendChild(desc); row.appendChild(kind);
|
|
23233
|
+
row.addEventListener("click", function () { closeSheet("command-sheet"); inputEl.value = item.value + " "; inputEl.focus(); autosizeInput(); });
|
|
23234
|
+
list.appendChild(row);
|
|
23235
|
+
});
|
|
23236
|
+
}
|
|
23237
|
+
|
|
23238
|
+
function showCommands() { closePicks(); renderCommandBrowser(); openSheet("command-sheet"); var q = document.getElementById("command-search"); if (q) setTimeout(function(){ q.focus(); }, 0); }
|
|
23239
|
+
|
|
23240
|
+
function selectSettingsTab(name) {
|
|
23241
|
+
document.querySelectorAll("[data-settings-tab]").forEach(function (b) { b.classList.toggle("on", b.getAttribute("data-settings-tab") === name); });
|
|
23242
|
+
document.querySelectorAll("[data-settings-panel]").forEach(function (p) { p.classList.toggle("on", p.getAttribute("data-settings-panel") === name); });
|
|
23243
|
+
if (name === "usage") renderUsagePanel(studioCosts);
|
|
23244
|
+
}
|
|
23245
|
+
|
|
23246
|
+
function autosizeInput() { inputEl.style.height = "auto"; inputEl.style.height = Math.min(190, Math.max(44, inputEl.scrollHeight)) + "px"; }
|
|
23247
|
+
|
|
23248
|
+
function trapWheel(el) {
|
|
23249
|
+
if (!el || el.dataset.wheelTrap === "1") return;
|
|
23250
|
+
el.dataset.wheelTrap = "1";
|
|
23251
|
+
el.addEventListener("wheel", function (e) {
|
|
23252
|
+
e.stopPropagation();
|
|
23253
|
+
var top = el.scrollTop <= 0; var bottom = Math.ceil(el.scrollTop + el.clientHeight) >= el.scrollHeight;
|
|
23254
|
+
if ((e.deltaY < 0 && top) || (e.deltaY > 0 && bottom)) e.preventDefault();
|
|
23255
|
+
}, { passive: false });
|
|
23256
|
+
}
|
|
23257
|
+
function trapScrollableMenus() {
|
|
23258
|
+
[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);
|
|
23259
|
+
}
|
|
23260
|
+
|
|
23187
23261
|
function connect() {
|
|
23188
23262
|
if (es) {
|
|
23189
23263
|
es.close();
|
|
@@ -23219,7 +23293,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23219
23293
|
|
|
23220
23294
|
function submitText(raw, steerNow) {
|
|
23221
23295
|
var text = (raw == null ? inputEl.value : raw).trim();
|
|
23222
|
-
if (raw == null && text) inputEl.value = "";
|
|
23296
|
+
if (raw == null && text) { inputEl.value = ""; autosizeInput(); }
|
|
23223
23297
|
if (!text) {
|
|
23224
23298
|
if (steerNow) flushQueue(true);
|
|
23225
23299
|
return;
|
|
@@ -23241,6 +23315,18 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23241
23315
|
});
|
|
23242
23316
|
}
|
|
23243
23317
|
|
|
23318
|
+
on("commands-open", "click", function () { var pop=document.getElementById("cmd-pop"); if(pop) pop.classList.remove("open"); showCommands(); });
|
|
23319
|
+
on("empty-commands", "click", showCommands);
|
|
23320
|
+
on("close-commands", "click", function () { closeSheet("command-sheet"); });
|
|
23321
|
+
var commandSearch = document.getElementById("command-search");
|
|
23322
|
+
if (commandSearch) commandSearch.addEventListener("input", renderCommandBrowser);
|
|
23323
|
+
document.querySelectorAll("[data-starter]").forEach(function (btn) { btn.addEventListener("click", function () { inputEl.value = btn.getAttribute("data-starter") || ""; autosizeInput(); inputEl.focus(); }); });
|
|
23324
|
+
document.querySelectorAll("[data-settings-tab]").forEach(function (btn) { btn.addEventListener("click", function () { selectSettingsTab(btn.getAttribute("data-settings-tab")); }); });
|
|
23325
|
+
on("rail-settings", "click", function () { loadStudio(); openSheet("studio-sheet"); });
|
|
23326
|
+
on("close-legend", "click", function () { closeSheet("legend-sheet"); });
|
|
23327
|
+
inputEl.addEventListener("input", autosizeInput);
|
|
23328
|
+
trapScrollableMenus();
|
|
23329
|
+
|
|
23244
23330
|
sendEl.addEventListener("click", function () { submitText(null, false); });
|
|
23245
23331
|
on("queue-send", "click", function () { flushQueue(true); });
|
|
23246
23332
|
on("queue-clear", "click", function () { promptQueue = []; renderQueue(); });
|
|
@@ -23256,6 +23342,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23256
23342
|
modelMenu.className = "open";
|
|
23257
23343
|
modelOpen.setAttribute("aria-expanded", "true");
|
|
23258
23344
|
renderModelList();
|
|
23345
|
+
trapWheel(document.getElementById("model-list"));
|
|
23259
23346
|
if (modelFilter) modelFilter.focus();
|
|
23260
23347
|
}
|
|
23261
23348
|
});
|
|
@@ -23277,11 +23364,28 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23277
23364
|
if (thinkingEl) thinkingEl.addEventListener("change", function () {
|
|
23278
23365
|
saveSetting({ thinking_level: thinkingEl.value });
|
|
23279
23366
|
});
|
|
23280
|
-
|
|
23281
|
-
api("POST", "/api/sessions", {})
|
|
23282
|
-
|
|
23283
|
-
|
|
23284
|
-
|
|
23367
|
+
function createNewSession() {
|
|
23368
|
+
api("POST", "/api/sessions", {})
|
|
23369
|
+
.then(function (res) {
|
|
23370
|
+
if (!res.ok) {
|
|
23371
|
+
return readError(res, "Could not start a new session.").then(function (msg) { addBlock("alert", msg); });
|
|
23372
|
+
}
|
|
23373
|
+
if (window.innerWidth <= 760) {
|
|
23374
|
+
layout.rail = false;
|
|
23375
|
+
applyLayout();
|
|
23376
|
+
}
|
|
23377
|
+
inputEl.focus();
|
|
23378
|
+
})
|
|
23379
|
+
.catch(function () { addBlock("alert", "Could not start a new session."); });
|
|
23380
|
+
}
|
|
23381
|
+
on("new-session", "click", createNewSession);
|
|
23382
|
+
on("top-new-session", "click", createNewSession);
|
|
23383
|
+
on("all-changes", "click", function () {
|
|
23384
|
+
selectedPath = "";
|
|
23385
|
+
var back = document.getElementById("all-changes");
|
|
23386
|
+
if (back) back.hidden = true;
|
|
23387
|
+
refreshWorkspaceSnapshot(false).then(function () {
|
|
23388
|
+
document.querySelectorAll(".tree button.on").forEach(function (el) { el.classList.remove("on"); });
|
|
23285
23389
|
});
|
|
23286
23390
|
});
|
|
23287
23391
|
on("fork-session", "click", function () {
|
|
@@ -23294,6 +23398,11 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23294
23398
|
var searchEl = document.getElementById("session-search");
|
|
23295
23399
|
if (searchEl) searchEl.addEventListener("input", function () { renderSessions(allSessions, activeSessionId); });
|
|
23296
23400
|
|
|
23401
|
+
function syncAutonomyVisual() {
|
|
23402
|
+
var open = document.getElementById("autonomy-open"); var sel = document.getElementById("autonomy");
|
|
23403
|
+
if (open && sel) open.classList.toggle("auto", sel.value === "auto");
|
|
23404
|
+
}
|
|
23405
|
+
|
|
23297
23406
|
function renderChips() {
|
|
23298
23407
|
var el = document.getElementById("ref-chips");
|
|
23299
23408
|
if (!el) return;
|
|
@@ -23359,21 +23468,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23359
23468
|
return;
|
|
23360
23469
|
}
|
|
23361
23470
|
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
|
-
}
|
|
23471
|
+
loadFileContent(node.path, btn);
|
|
23377
23472
|
});
|
|
23378
23473
|
into.appendChild(btn);
|
|
23379
23474
|
if (node.dir && !collapsed) renderTreeNodes(node.children || [], depth + 1, into);
|
|
@@ -23452,7 +23547,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23452
23547
|
if (!selectedPath) return;
|
|
23453
23548
|
api("POST", "/api/changes/revert", { path: selectedPath }).then(function (res) {
|
|
23454
23549
|
if (!res.ok) return readError(res, "Could not reject that file.").then(function (msg) { addBlock("alert", msg); });
|
|
23455
|
-
|
|
23550
|
+
refreshWorkspaceSnapshot(true);
|
|
23456
23551
|
}).catch(function () {});
|
|
23457
23552
|
});
|
|
23458
23553
|
on("accept-file", "click", function () {
|
|
@@ -23545,7 +23640,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23545
23640
|
var modeEl = document.getElementById("mode");
|
|
23546
23641
|
var autonomyEl = document.getElementById("autonomy");
|
|
23547
23642
|
if (modeEl) modeEl.addEventListener("change", function () { saveSetting({ agent_mode: modeEl.value }); });
|
|
23548
|
-
if (autonomyEl) autonomyEl.addEventListener("change", function () { saveSetting({ autonomy: autonomyEl.value }); });
|
|
23643
|
+
if (autonomyEl) autonomyEl.addEventListener("change", function () { saveSetting({ autonomy: autonomyEl.value }); syncAutonomyVisual(); });
|
|
23549
23644
|
|
|
23550
23645
|
feedEl.addEventListener("click", function (e) {
|
|
23551
23646
|
var btn = e.target.closest && e.target.closest(".copy");
|
|
@@ -23589,7 +23684,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23589
23684
|
}
|
|
23590
23685
|
|
|
23591
23686
|
var shell = document.querySelector(".shell");
|
|
23592
|
-
var layout = { rail:
|
|
23687
|
+
var layout = { rail: window.innerWidth > 760, changes: false, term: false };
|
|
23593
23688
|
try {
|
|
23594
23689
|
var saved = localStorage.getItem("critique.code-web.layout");
|
|
23595
23690
|
if (saved) layout = Object.assign(layout, JSON.parse(saved));
|
|
@@ -23602,7 +23697,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23602
23697
|
var pane = document.getElementById("changes-pane");
|
|
23603
23698
|
if (pane) pane.classList.toggle("open", !!layout.changes);
|
|
23604
23699
|
var railBtn = document.getElementById("toggle-rail");
|
|
23605
|
-
if (railBtn) railBtn.
|
|
23700
|
+
if (railBtn) railBtn.classList.toggle("on", !!layout.rail);
|
|
23606
23701
|
try { localStorage.setItem("critique.code-web.layout", JSON.stringify(layout)); } catch (e) {}
|
|
23607
23702
|
}
|
|
23608
23703
|
applyLayout();
|
|
@@ -23764,15 +23859,8 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23764
23859
|
}).join("");
|
|
23765
23860
|
if (sheet) sheet.className = "sheet open";
|
|
23766
23861
|
});
|
|
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
|
-
});
|
|
23862
|
+
on("studio-open", "click", function () { loadStudio(); selectSettingsTab("general"); openSheet("studio-sheet"); });
|
|
23863
|
+
on("close-studio", "click", function () { closeSheet("studio-sheet"); });
|
|
23776
23864
|
on("save-key", "click", function () {
|
|
23777
23865
|
var kind = document.getElementById("key-kind");
|
|
23778
23866
|
var value = document.getElementById("key-value");
|
|
@@ -23796,7 +23884,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23796
23884
|
if (sheet) sheet.className = "sheet";
|
|
23797
23885
|
if (res.ok) {
|
|
23798
23886
|
if (body.branch) setBranchLabel(body.branch);
|
|
23799
|
-
|
|
23887
|
+
refreshWorkspaceSnapshot(true);
|
|
23800
23888
|
loadBranches();
|
|
23801
23889
|
}
|
|
23802
23890
|
}); });
|
|
@@ -23845,6 +23933,19 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23845
23933
|
}
|
|
23846
23934
|
if (paletteQ) paletteQ.addEventListener("input", renderPalette);
|
|
23847
23935
|
renderPalette();
|
|
23936
|
+
var themeLight = document.getElementById("theme-light");
|
|
23937
|
+
function applyTheme(light) {
|
|
23938
|
+
document.documentElement.setAttribute("data-theme", light ? "light" : "dark");
|
|
23939
|
+
try { localStorage.setItem("critique-code-theme", light ? "light" : "dark"); } catch (e) {}
|
|
23940
|
+
}
|
|
23941
|
+
if (themeLight) {
|
|
23942
|
+
var savedTheme = "";
|
|
23943
|
+
try { savedTheme = localStorage.getItem("critique-code-theme") || ""; } catch (e) {}
|
|
23944
|
+
var useLight = savedTheme === "light";
|
|
23945
|
+
themeLight.checked = useLight;
|
|
23946
|
+
applyTheme(useLight);
|
|
23947
|
+
themeLight.addEventListener("change", function () { applyTheme(themeLight.checked); });
|
|
23948
|
+
}
|
|
23848
23949
|
document.querySelectorAll(".work-tabs button").forEach(function (btn) {
|
|
23849
23950
|
btn.addEventListener("click", function () {
|
|
23850
23951
|
document.querySelectorAll(".work-tabs button").forEach(function (el) { el.classList.remove("on"); });
|
|
@@ -23912,8 +24013,12 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23912
24013
|
addBlock("alert", "Could not load this session. Refresh the loopback tab.");
|
|
23913
24014
|
});
|
|
23914
24015
|
renderModelList();
|
|
24016
|
+
renderCommandBrowser();
|
|
24017
|
+
autosizeInput();
|
|
24018
|
+
syncAutonomyVisual();
|
|
23915
24019
|
updateContextRing();
|
|
23916
24020
|
loadStudio();
|
|
24021
|
+
refreshWorkspaceSnapshot(false);
|
|
23917
24022
|
connect();
|
|
23918
24023
|
})();
|
|
23919
24024
|
</script>
|
|
@@ -28610,7 +28715,8 @@ ${prior}`.trim();
|
|
|
28610
28715
|
source: "author",
|
|
28611
28716
|
model: authorModelId(implementer[0]),
|
|
28612
28717
|
input_tokens: turn.usage?.input_tokens ?? 0,
|
|
28613
|
-
output_tokens: turn.usage?.output_tokens ?? 0
|
|
28718
|
+
output_tokens: turn.usage?.output_tokens ?? 0,
|
|
28719
|
+
cost_usd: turn.usage?.cost_usd
|
|
28614
28720
|
});
|
|
28615
28721
|
const output = typeof turn.output === "string" ? turn.output : JSON.stringify(turn.output);
|
|
28616
28722
|
noteWithheld(output);
|
|
@@ -30551,6 +30657,12 @@ function commandPaletteItems(state) {
|
|
|
30551
30657
|
function emptyTokens() {
|
|
30552
30658
|
return { input_tokens: 0, output_tokens: 0 };
|
|
30553
30659
|
}
|
|
30660
|
+
function estimateUsageCostUsd(input, output, reasoning = 0) {
|
|
30661
|
+
const inCost = input * 1e-7;
|
|
30662
|
+
const outCost = output * 4e-7;
|
|
30663
|
+
const reasonCost = reasoning * 2e-7;
|
|
30664
|
+
return inCost + outCost + reasonCost;
|
|
30665
|
+
}
|
|
30554
30666
|
function costBreakdown(entries) {
|
|
30555
30667
|
const by_phase = {
|
|
30556
30668
|
author: emptyTokens(),
|
|
@@ -30560,6 +30672,7 @@ function costBreakdown(entries) {
|
|
|
30560
30672
|
const by_model = {};
|
|
30561
30673
|
let total_input = 0;
|
|
30562
30674
|
let total_output = 0;
|
|
30675
|
+
let total_cost_usd = 0;
|
|
30563
30676
|
for (const entry of entries) {
|
|
30564
30677
|
const phase = by_phase[entry.source];
|
|
30565
30678
|
phase.input_tokens += entry.input_tokens;
|
|
@@ -30569,8 +30682,10 @@ function costBreakdown(entries) {
|
|
|
30569
30682
|
model.output_tokens += entry.output_tokens;
|
|
30570
30683
|
total_input += entry.input_tokens;
|
|
30571
30684
|
total_output += entry.output_tokens;
|
|
30685
|
+
total_cost_usd += Number(entry.cost_usd || 0);
|
|
30572
30686
|
}
|
|
30573
|
-
|
|
30687
|
+
const estimated_cost_usd = total_cost_usd > 0 ? total_cost_usd : estimateUsageCostUsd(total_input, total_output);
|
|
30688
|
+
return { by_phase, by_model, total_input, total_output, total_cost_usd, estimated_cost_usd };
|
|
30574
30689
|
}
|
|
30575
30690
|
function skillPanelRows(skills) {
|
|
30576
30691
|
return skills.map((skill) => {
|
|
@@ -31190,6 +31305,29 @@ exit ${code2 ?? "killed"}
|
|
|
31190
31305
|
send(res, 200, { ok: true, id: chat.id });
|
|
31191
31306
|
return;
|
|
31192
31307
|
}
|
|
31308
|
+
if (req.method === "POST" && path2 === "/api/sessions/rename") {
|
|
31309
|
+
const body = await readJson(req);
|
|
31310
|
+
const id4 = String(body.id ?? activeId).trim();
|
|
31311
|
+
const title = String(body.title ?? "").trim().slice(0, 120);
|
|
31312
|
+
const chat = chats.find((item) => item.id === id4);
|
|
31313
|
+
if (!chat) {
|
|
31314
|
+
send(res, 404, { error: "unknown session" });
|
|
31315
|
+
return;
|
|
31316
|
+
}
|
|
31317
|
+
if (!title) {
|
|
31318
|
+
send(res, 400, { error: "title required" });
|
|
31319
|
+
return;
|
|
31320
|
+
}
|
|
31321
|
+
chat.title = title;
|
|
31322
|
+
persistChats();
|
|
31323
|
+
if (chat.id === activeId) {
|
|
31324
|
+
emit({ type: "title", title: chat.title, id: chat.id, sessions: sessionSummaries() });
|
|
31325
|
+
} else {
|
|
31326
|
+
emit({ type: "session_list", sessions: sessionSummaries(), id: activeId });
|
|
31327
|
+
}
|
|
31328
|
+
send(res, 200, { ok: true, id: chat.id, title: chat.title, sessions: sessionSummaries() });
|
|
31329
|
+
return;
|
|
31330
|
+
}
|
|
31193
31331
|
if (req.method === "GET" && path2 === "/api/tree") {
|
|
31194
31332
|
const prefix = url2.searchParams.get("prefix")?.trim() ?? "";
|
|
31195
31333
|
const entries = listWorkspaceTree(repositoryRoot, 2e3, prefix);
|
|
@@ -31501,12 +31639,20 @@ ${extras.join("\n\n")}` : text);
|
|
|
31501
31639
|
const cursor = await new FileReviewCheckpointStore(storeRoot).load();
|
|
31502
31640
|
const skills = await discoverCritiqueCodeSkills({ cwd: repositoryRoot, env });
|
|
31503
31641
|
const suppressed = new Set(ops.state().suppressions.map((item) => item.fingerprint));
|
|
31642
|
+
const chatUsage = activeChat().events.filter((event) => event.type === "usage").map((event) => ({
|
|
31643
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
31644
|
+
source: "author",
|
|
31645
|
+
model,
|
|
31646
|
+
input_tokens: Number(event.input_tokens || 0),
|
|
31647
|
+
output_tokens: Number(event.output_tokens || 0),
|
|
31648
|
+
cost_usd: event.cost_usd
|
|
31649
|
+
}));
|
|
31504
31650
|
send(res, 200, {
|
|
31505
31651
|
...snapshot(),
|
|
31506
31652
|
badges: dualModelBadges({ author_model: model, review_models: reviewModels }),
|
|
31507
31653
|
palette: commandPaletteItems({ watch: watchOn, autonomy, voice: false }),
|
|
31508
31654
|
skills: skillPanelRows(skills),
|
|
31509
|
-
costs: costBreakdown(ops.state().costs),
|
|
31655
|
+
costs: costBreakdown([...ops.state().costs, ...chatUsage]),
|
|
31510
31656
|
audit: approvalLog,
|
|
31511
31657
|
timeline: checkpointTimeline({
|
|
31512
31658
|
cursor: cursor ? {
|