diffprism 0.28.0 → 0.31.0

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.
@@ -1,13 +1,14 @@
1
1
  import {
2
2
  analyze,
3
3
  consumeReviewResult,
4
+ detectWorktree,
4
5
  getCurrentBranch,
5
6
  getDiff,
6
7
  isServerAlive,
7
8
  readReviewResult,
8
9
  readWatchFile,
9
10
  startReview
10
- } from "./chunk-VPIL4KYB.js";
11
+ } from "./chunk-OJ723D6Z.js";
11
12
 
12
13
  // packages/mcp-server/src/index.ts
13
14
  import fs from "fs";
@@ -29,6 +30,7 @@ async function reviewViaGlobalServer(serverInfo, diffRef, options) {
29
30
  };
30
31
  }
31
32
  const briefing = analyze(diffSet);
33
+ const worktreeInfo = detectWorktree({ cwd });
32
34
  const payload = {
33
35
  reviewId: "",
34
36
  // Server assigns the real ID
@@ -39,7 +41,12 @@ async function reviewViaGlobalServer(serverInfo, diffRef, options) {
39
41
  title: options.title,
40
42
  description: options.description,
41
43
  reasoning: options.reasoning,
42
- currentBranch
44
+ currentBranch,
45
+ worktree: worktreeInfo.isWorktree ? {
46
+ isWorktree: true,
47
+ worktreePath: worktreeInfo.worktreePath,
48
+ mainWorktreePath: worktreeInfo.mainWorktreePath
49
+ } : void 0
43
50
  }
44
51
  };
45
52
  const createResponse = await fetch(
@@ -76,7 +83,7 @@ async function reviewViaGlobalServer(serverInfo, diffRef, options) {
76
83
  async function startMcpServer() {
77
84
  const server = new McpServer({
78
85
  name: "diffprism",
79
- version: true ? "0.28.0" : "0.0.0-dev"
86
+ version: true ? "0.31.0" : "0.0.0-dev"
80
87
  });
81
88
  server.tool(
82
89
  "open_review",
@@ -353,6 +360,374 @@ async function startMcpServer() {
353
360
  }
354
361
  }
355
362
  );
363
+ server.tool(
364
+ "get_diff",
365
+ "Get a structured diff (DiffSet) for local git changes. Returns file-level and hunk-level change data as JSON without opening a browser. Use this to inspect what changed before deciding whether to open a full review.",
366
+ {
367
+ diff_ref: z.string().describe(
368
+ 'Git diff reference: "staged", "unstaged", "working-copy" (staged+unstaged grouped), or a ref range like "HEAD~3..HEAD"'
369
+ )
370
+ },
371
+ async ({ diff_ref }) => {
372
+ try {
373
+ const cwd = process.cwd();
374
+ const { diffSet } = getDiff(diff_ref, { cwd });
375
+ return {
376
+ content: [
377
+ {
378
+ type: "text",
379
+ text: JSON.stringify(diffSet, null, 2)
380
+ }
381
+ ]
382
+ };
383
+ } catch (err) {
384
+ const message = err instanceof Error ? err.message : String(err);
385
+ return {
386
+ content: [
387
+ {
388
+ type: "text",
389
+ text: `Error: ${message}`
390
+ }
391
+ ],
392
+ isError: true
393
+ };
394
+ }
395
+ }
396
+ );
397
+ server.tool(
398
+ "analyze_diff",
399
+ "Analyze local git changes and return a ReviewBriefing with summary, file triage (critical/notable/mechanical), impact detection (affected modules, tests, dependencies, breaking changes), complexity scores, test coverage gaps, and pattern flags (security issues, TODOs, console.logs). Same analysis shown in the DiffPrism briefing bar, but returned as JSON without opening a browser.",
400
+ {
401
+ diff_ref: z.string().describe(
402
+ 'Git diff reference: "staged", "unstaged", "working-copy" (staged+unstaged grouped), or a ref range like "HEAD~3..HEAD"'
403
+ )
404
+ },
405
+ async ({ diff_ref }) => {
406
+ try {
407
+ const cwd = process.cwd();
408
+ const { diffSet } = getDiff(diff_ref, { cwd });
409
+ if (diffSet.files.length === 0) {
410
+ return {
411
+ content: [
412
+ {
413
+ type: "text",
414
+ text: JSON.stringify({
415
+ summary: "No changes to analyze.",
416
+ triage: { critical: [], notable: [], mechanical: [] },
417
+ impact: {
418
+ affectedModules: [],
419
+ affectedTests: [],
420
+ publicApiChanges: false,
421
+ breakingChanges: [],
422
+ newDependencies: []
423
+ },
424
+ verification: { testsPass: null, typeCheck: null, lintClean: null },
425
+ fileStats: []
426
+ }, null, 2)
427
+ }
428
+ ]
429
+ };
430
+ }
431
+ const briefing = analyze(diffSet);
432
+ return {
433
+ content: [
434
+ {
435
+ type: "text",
436
+ text: JSON.stringify(briefing, null, 2)
437
+ }
438
+ ]
439
+ };
440
+ } catch (err) {
441
+ const message = err instanceof Error ? err.message : String(err);
442
+ return {
443
+ content: [
444
+ {
445
+ type: "text",
446
+ text: `Error: ${message}`
447
+ }
448
+ ],
449
+ isError: true
450
+ };
451
+ }
452
+ }
453
+ );
454
+ server.tool(
455
+ "add_annotation",
456
+ "Post a structured finding (annotation) to a review session. Use this to flag issues, suggest improvements, or ask questions about specific lines of code in a review. Requires a running global server (`diffprism server`).",
457
+ {
458
+ session_id: z.string().describe("Review session ID from open_review"),
459
+ file: z.string().describe("File path within the diff to annotate"),
460
+ line: z.number().describe("Line number to annotate"),
461
+ body: z.string().describe("The annotation text \u2014 your finding, suggestion, or question"),
462
+ type: z.enum(["finding", "suggestion", "question", "warning"]).describe("Type of annotation"),
463
+ confidence: z.number().min(0).max(1).optional().describe("Confidence in the finding (0-1, defaults to 1)"),
464
+ category: z.enum([
465
+ "security",
466
+ "performance",
467
+ "convention",
468
+ "correctness",
469
+ "complexity",
470
+ "test-coverage",
471
+ "documentation",
472
+ "other"
473
+ ]).optional().describe("Category of the finding (defaults to 'other')"),
474
+ source_agent: z.string().optional().describe("Agent identifier (e.g., 'security-reviewer')")
475
+ },
476
+ async ({
477
+ session_id,
478
+ file,
479
+ line,
480
+ body,
481
+ type,
482
+ confidence,
483
+ category,
484
+ source_agent
485
+ }) => {
486
+ try {
487
+ const serverInfo = await isServerAlive();
488
+ if (!serverInfo) {
489
+ return {
490
+ content: [
491
+ {
492
+ type: "text",
493
+ text: "No global server running. Start one with `diffprism server`."
494
+ }
495
+ ],
496
+ isError: true
497
+ };
498
+ }
499
+ const response = await fetch(
500
+ `http://localhost:${serverInfo.httpPort}/api/reviews/${session_id}/annotations`,
501
+ {
502
+ method: "POST",
503
+ headers: { "Content-Type": "application/json" },
504
+ body: JSON.stringify({
505
+ file,
506
+ line,
507
+ body,
508
+ type,
509
+ confidence: confidence ?? 1,
510
+ category: category ?? "other",
511
+ source: {
512
+ agent: source_agent ?? "unknown",
513
+ tool: "add_annotation"
514
+ }
515
+ })
516
+ }
517
+ );
518
+ if (!response.ok) {
519
+ const errorData = await response.json().catch(() => ({}));
520
+ const errorMsg = errorData.error ?? `Server returned ${response.status}`;
521
+ return {
522
+ content: [
523
+ {
524
+ type: "text",
525
+ text: `Error: ${errorMsg}`
526
+ }
527
+ ],
528
+ isError: true
529
+ };
530
+ }
531
+ const data = await response.json();
532
+ return {
533
+ content: [
534
+ {
535
+ type: "text",
536
+ text: JSON.stringify(
537
+ { annotationId: data.annotationId, sessionId: session_id },
538
+ null,
539
+ 2
540
+ )
541
+ }
542
+ ]
543
+ };
544
+ } catch (err) {
545
+ const message = err instanceof Error ? err.message : String(err);
546
+ return {
547
+ content: [
548
+ {
549
+ type: "text",
550
+ text: `Error: ${message}`
551
+ }
552
+ ],
553
+ isError: true
554
+ };
555
+ }
556
+ }
557
+ );
558
+ server.tool(
559
+ "get_review_state",
560
+ "Get the current state of a review session including session summary and annotations. Returns session metadata, status, and any agent annotations. Use this to check on a review's progress or read agent findings.",
561
+ {
562
+ session_id: z.string().optional().describe(
563
+ "Review session ID. If omitted, uses the most recently created session."
564
+ )
565
+ },
566
+ async ({ session_id }) => {
567
+ try {
568
+ const sessionId = session_id ?? lastGlobalSessionId;
569
+ if (!sessionId) {
570
+ return {
571
+ content: [
572
+ {
573
+ type: "text",
574
+ text: "No session ID provided and no recent session available."
575
+ }
576
+ ],
577
+ isError: true
578
+ };
579
+ }
580
+ const serverInfo = await isServerAlive();
581
+ if (!serverInfo) {
582
+ return {
583
+ content: [
584
+ {
585
+ type: "text",
586
+ text: "No global server running. Start one with `diffprism server`."
587
+ }
588
+ ],
589
+ isError: true
590
+ };
591
+ }
592
+ const [sessionResponse, annotationsResponse] = await Promise.all([
593
+ fetch(
594
+ `http://localhost:${serverInfo.httpPort}/api/reviews/${sessionId}`
595
+ ),
596
+ fetch(
597
+ `http://localhost:${serverInfo.httpPort}/api/reviews/${sessionId}/annotations`
598
+ )
599
+ ]);
600
+ if (!sessionResponse.ok) {
601
+ return {
602
+ content: [
603
+ {
604
+ type: "text",
605
+ text: `Session not found: ${sessionId}`
606
+ }
607
+ ],
608
+ isError: true
609
+ };
610
+ }
611
+ const session = await sessionResponse.json();
612
+ const annotations = annotationsResponse.ok ? await annotationsResponse.json() : { annotations: [] };
613
+ return {
614
+ content: [
615
+ {
616
+ type: "text",
617
+ text: JSON.stringify(
618
+ {
619
+ session,
620
+ annotations: annotations.annotations
621
+ },
622
+ null,
623
+ 2
624
+ )
625
+ }
626
+ ]
627
+ };
628
+ } catch (err) {
629
+ const message = err instanceof Error ? err.message : String(err);
630
+ return {
631
+ content: [
632
+ {
633
+ type: "text",
634
+ text: `Error: ${message}`
635
+ }
636
+ ],
637
+ isError: true
638
+ };
639
+ }
640
+ }
641
+ );
642
+ server.tool(
643
+ "flag_for_attention",
644
+ "Mark specific files in a review session for human attention. Posts warning annotations for each flagged file. Use this to highlight files that need careful human review. Requires a running global server (`diffprism server`).",
645
+ {
646
+ session_id: z.string().optional().describe(
647
+ "Review session ID. If omitted, uses the most recently created session."
648
+ ),
649
+ files: z.array(
650
+ z.object({
651
+ path: z.string().describe("File path to flag for attention"),
652
+ reason: z.string().describe("Why this file needs human attention"),
653
+ line: z.number().optional().describe("Specific line to highlight (defaults to 1)")
654
+ })
655
+ ).describe("Files to flag for human attention"),
656
+ source_agent: z.string().optional().describe("Agent identifier (e.g., 'security-reviewer')")
657
+ },
658
+ async ({ session_id, files, source_agent }) => {
659
+ try {
660
+ const sessionId = session_id ?? lastGlobalSessionId;
661
+ if (!sessionId) {
662
+ return {
663
+ content: [
664
+ {
665
+ type: "text",
666
+ text: "No session ID provided and no recent session available."
667
+ }
668
+ ],
669
+ isError: true
670
+ };
671
+ }
672
+ const serverInfo = await isServerAlive();
673
+ if (!serverInfo) {
674
+ return {
675
+ content: [
676
+ {
677
+ type: "text",
678
+ text: "No global server running. Start one with `diffprism server`."
679
+ }
680
+ ],
681
+ isError: true
682
+ };
683
+ }
684
+ let flagged = 0;
685
+ for (const file of files) {
686
+ const response = await fetch(
687
+ `http://localhost:${serverInfo.httpPort}/api/reviews/${sessionId}/annotations`,
688
+ {
689
+ method: "POST",
690
+ headers: { "Content-Type": "application/json" },
691
+ body: JSON.stringify({
692
+ file: file.path,
693
+ line: file.line ?? 1,
694
+ body: file.reason,
695
+ type: "warning",
696
+ confidence: 1,
697
+ category: "other",
698
+ source: {
699
+ agent: source_agent ?? "flag_for_attention",
700
+ tool: "flag_for_attention"
701
+ }
702
+ })
703
+ }
704
+ );
705
+ if (response.ok) {
706
+ flagged++;
707
+ }
708
+ }
709
+ return {
710
+ content: [
711
+ {
712
+ type: "text",
713
+ text: JSON.stringify({ flagged, sessionId }, null, 2)
714
+ }
715
+ ]
716
+ };
717
+ } catch (err) {
718
+ const message = err instanceof Error ? err.message : String(err);
719
+ return {
720
+ content: [
721
+ {
722
+ type: "text",
723
+ text: `Error: ${message}`
724
+ }
725
+ ],
726
+ isError: true
727
+ };
728
+ }
729
+ }
730
+ );
356
731
  const transport = new StdioServerTransport();
357
732
  await server.connect(transport);
358
733
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "diffprism",
3
- "version": "0.28.0",
3
+ "version": "0.31.0",
4
4
  "type": "module",
5
5
  "description": "Local-first code review tool for agent-generated code changes",
6
6
  "bin": {
@@ -0,0 +1 @@
1
+ :root{--diff-background-color:initial;--diff-text-color:initial;--diff-font-family:Consolas,Courier,monospace;--diff-selection-background-color:#b3d7ff;--diff-selection-text-color:var(--diff-text-color);--diff-gutter-insert-background-color:#d6fedb;--diff-gutter-insert-text-color:var(--diff-text-color);--diff-gutter-delete-background-color:#fadde0;--diff-gutter-delete-text-color:var(--diff-text-color);--diff-gutter-selected-background-color:#fffce0;--diff-gutter-selected-text-color:var(--diff-text-color);--diff-code-insert-background-color:#eaffee;--diff-code-insert-text-color:var(--diff-text-color);--diff-code-delete-background-color:#fdeff0;--diff-code-delete-text-color:var(--diff-text-color);--diff-code-insert-edit-background-color:#c0dc91;--diff-code-insert-edit-text-color:var(--diff-text-color);--diff-code-delete-edit-background-color:#f39ea2;--diff-code-delete-edit-text-color:var(--diff-text-color);--diff-code-selected-background-color:#fffce0;--diff-code-selected-text-color:var(--diff-text-color);--diff-omit-gutter-line-color:#cb2a1d}.diff{background-color:var(--diff-background-color);border-collapse:collapse;color:var(--diff-text-color);table-layout:fixed;width:100%}.diff::-moz-selection{background-color:#b3d7ff;background-color:var(--diff-selection-background-color);color:var(--diff-text-color);color:var(--diff-selection-text-color)}.diff::selection{background-color:#b3d7ff;background-color:var(--diff-selection-background-color);color:var(--diff-text-color);color:var(--diff-selection-text-color)}.diff td{padding-bottom:0;padding-top:0;vertical-align:top}.diff-line{font-family:Consolas,Courier,monospace;font-family:var(--diff-font-family);line-height:1.5}.diff-gutter>a{color:inherit;display:block}.diff-gutter{cursor:pointer;padding:0 1ch;text-align:right;-webkit-user-select:none;-moz-user-select:none;user-select:none}.diff-gutter-insert{background-color:#d6fedb;background-color:var(--diff-gutter-insert-background-color);color:var(--diff-text-color);color:var(--diff-gutter-insert-text-color)}.diff-gutter-delete{background-color:#fadde0;background-color:var(--diff-gutter-delete-background-color);color:var(--diff-text-color);color:var(--diff-gutter-delete-text-color)}.diff-gutter-omit{cursor:default}.diff-gutter-selected{background-color:#fffce0;background-color:var(--diff-gutter-selected-background-color);color:var(--diff-text-color);color:var(--diff-gutter-selected-text-color)}.diff-code{word-wrap:break-word;padding:0 0 0 .5em;white-space:pre-wrap;word-break:break-all}.diff-code-edit{color:inherit}.diff-code-insert{background-color:#eaffee;background-color:var(--diff-code-insert-background-color);color:var(--diff-text-color);color:var(--diff-code-insert-text-color)}.diff-code-insert .diff-code-edit{background-color:#c0dc91;background-color:var(--diff-code-insert-edit-background-color);color:var(--diff-text-color);color:var(--diff-code-insert-edit-text-color)}.diff-code-delete{background-color:#fdeff0;background-color:var(--diff-code-delete-background-color);color:var(--diff-text-color);color:var(--diff-code-delete-text-color)}.diff-code-delete .diff-code-edit{background-color:#f39ea2;background-color:var(--diff-code-delete-edit-background-color);color:var(--diff-text-color);color:var(--diff-code-delete-edit-text-color)}.diff-code-selected{background-color:#fffce0;background-color:var(--diff-code-selected-background-color);color:var(--diff-text-color);color:var(--diff-code-selected-text-color)}.diff-widget-content{vertical-align:top}.diff-gutter-col{width:7ch}.diff-gutter-omit{height:0}.diff-gutter-omit:before{background-color:#cb2a1d;background-color:var(--diff-omit-gutter-line-color);content:" ";display:block;height:100%;margin-left:4.6ch;overflow:hidden;white-space:pre;width:2px}.diff-decoration{line-height:1.5;-webkit-user-select:none;-moz-user-select:none;user-select:none}.diff-decoration-content{font-family:Consolas,Courier,monospace;font-family:var(--diff-font-family);padding:0}*,:before,:after{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / .5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / .5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.\!container{width:100%!important}.container{width:100%}@media(min-width:640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media(min-width:768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media(min-width:1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media(min-width:1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media(min-width:1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.visible{visibility:visible}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{top:0;right:0;bottom:0;left:0}.right-0{right:0}.right-2{right:.5rem}.top-2{top:.5rem}.top-full{top:100%}.z-50{z-index:50}.col-span-2{grid-column:span 2 / span 2}.mx-4{margin-left:1rem;margin-right:1rem}.mx-auto{margin-left:auto;margin-right:auto}.mb-0\.5{margin-bottom:.125rem}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mr-1\.5{margin-right:.375rem}.mr-2{margin-right:.5rem}.mr-3{margin-right:.75rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.hidden{display:none}.h-12{height:3rem}.h-16{height:4rem}.h-2{height:.5rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-6{height:1.5rem}.h-8{height:2rem}.h-full{height:100%}.h-screen{height:100vh}.max-h-64{max-height:16rem}.min-h-0{min-height:0px}.w-12{width:3rem}.w-16{width:4rem}.w-2{width:.5rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-52{width:13rem}.w-6{width:1.5rem}.w-8{width:2rem}.w-80{width:20rem}.w-\[280px\]{width:280px}.w-full{width:100%}.w-px{width:1px}.min-w-0{min-width:0px}.max-w-\[180px\]{max-width:180px}.max-w-sm{max-width:24rem}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}@keyframes ping{75%,to{transform:scale(2);opacity:0}}.animate-ping{animation:ping 1s cubic-bezier(0,0,.2,1) infinite}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-x-6{-moz-column-gap:1.5rem;column-gap:1.5rem}.gap-y-3{row-gap:.75rem}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-l{border-left-width:1px}.border-l-2{border-left-width:2px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-accent{border-color:var(--color-accent)}.border-blue-300{--tw-border-opacity:1;border-color:rgb(147 197 253 / var(--tw-border-opacity, 1))}.border-border{border-color:var(--color-border)}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1))}.border-gray-500\/30{border-color:#6b72804d}.border-green-300{--tw-border-opacity:1;border-color:rgb(134 239 172 / var(--tw-border-opacity, 1))}.border-green-500\/30{border-color:#22c55e4d}.border-green-600\/30{border-color:#16a34a4d}.border-orange-300{--tw-border-opacity:1;border-color:rgb(253 186 116 / var(--tw-border-opacity, 1))}.border-purple-300{--tw-border-opacity:1;border-color:rgb(216 180 254 / var(--tw-border-opacity, 1))}.border-red-300{--tw-border-opacity:1;border-color:rgb(252 165 165 / var(--tw-border-opacity, 1))}.border-red-500\/30{border-color:#ef44444d}.border-transparent{border-color:transparent}.border-yellow-300{--tw-border-opacity:1;border-color:rgb(253 224 71 / var(--tw-border-opacity, 1))}.border-yellow-500\/30{border-color:#eab3084d}.border-t-accent{border-top-color:var(--color-accent)}.bg-background{background-color:var(--color-background)}.bg-black\/50{background-color:#00000080}.bg-blue-100{--tw-bg-opacity:1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.bg-blue-400{--tw-bg-opacity:1;background-color:rgb(96 165 250 / var(--tw-bg-opacity, 1))}.bg-blue-500{--tw-bg-opacity:1;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))}.bg-border{background-color:var(--color-border)}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.bg-gray-600\/20{background-color:#4b556333}.bg-green-100{--tw-bg-opacity:1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.bg-green-400{--tw-bg-opacity:1;background-color:rgb(74 222 128 / var(--tw-bg-opacity, 1))}.bg-green-500{--tw-bg-opacity:1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-green-600\/20{background-color:#16a34a33}.bg-orange-100{--tw-bg-opacity:1;background-color:rgb(255 237 213 / var(--tw-bg-opacity, 1))}.bg-purple-100{--tw-bg-opacity:1;background-color:rgb(243 232 255 / var(--tw-bg-opacity, 1))}.bg-red-100{--tw-bg-opacity:1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.bg-red-600\/20{background-color:#dc262633}.bg-surface{background-color:var(--color-surface)}.bg-yellow-100{--tw-bg-opacity:1;background-color:rgb(254 249 195 / var(--tw-bg-opacity, 1))}.bg-yellow-600\/20{background-color:#ca8a0433}.p-0\.5{padding:.125rem}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.pb-3{padding-bottom:.75rem}.pr-6{padding-right:1.5rem}.pt-3{padding-top:.75rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-\[10px\]{font-size:10px}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.tracking-wide{letter-spacing:.025em}.text-accent{color:var(--color-accent)}.text-blue-500{--tw-text-opacity:1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.text-blue-700{--tw-text-opacity:1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.text-cyan-500{--tw-text-opacity:1;color:rgb(6 182 212 / var(--tw-text-opacity, 1))}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-green-400{--tw-text-opacity:1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.text-green-600{--tw-text-opacity:1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-green-700{--tw-text-opacity:1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-orange-500{--tw-text-opacity:1;color:rgb(249 115 22 / var(--tw-text-opacity, 1))}.text-orange-700{--tw-text-opacity:1;color:rgb(194 65 12 / var(--tw-text-opacity, 1))}.text-purple-500{--tw-text-opacity:1;color:rgb(168 85 247 / var(--tw-text-opacity, 1))}.text-purple-700{--tw-text-opacity:1;color:rgb(126 34 206 / var(--tw-text-opacity, 1))}.text-red-400{--tw-text-opacity:1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.text-red-500{--tw-text-opacity:1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-red-700{--tw-text-opacity:1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.text-text-primary{color:var(--color-text-primary)}.text-text-secondary{color:var(--color-text-secondary)}.text-yellow-400{--tw-text-opacity:1;color:rgb(250 204 21 / var(--tw-text-opacity, 1))}.text-yellow-500{--tw-text-opacity:1;color:rgb(234 179 8 / var(--tw-text-opacity, 1))}.text-yellow-700{--tw-text-opacity:1;color:rgb(161 98 7 / var(--tw-text-opacity, 1))}.opacity-0{opacity:0}.opacity-40{opacity:.4}.opacity-75{opacity:.75}.shadow-lg{--tw-shadow:0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-100{transition-duration:.1s}:root{--color-background: #ffffff;--color-surface: #f6f8fa;--color-border: #d0d7de;--color-text-primary: #1f2328;--color-text-secondary: #656d76;--color-accent: #0969da;--color-diff-bg: #ffffff;--color-diff-text: #1f2328;--color-gutter-bg: #f6f8fa;--color-gutter-text: #656d76;--color-gutter-border: #d0d7de;--color-diff-insert-bg: rgba(46, 160, 67, .15);--color-diff-insert-gutter-bg: rgba(46, 160, 67, .2);--color-diff-insert-gutter-text: #1a7f37;--color-diff-delete-bg: rgba(248, 81, 73, .15);--color-diff-delete-gutter-bg: rgba(248, 81, 73, .2);--color-diff-delete-gutter-text: #cf222e;--color-hunk-bg: rgba(9, 105, 218, .1);--color-hunk-border: #d0d7de;--color-hunk-gutter-bg: rgba(9, 105, 218, .15);--color-hunk-gutter-text: #0969da;--color-hunk-content-text: #656d76;--color-diff-edit-insert: rgba(46, 160, 67, .4);--color-diff-edit-delete: rgba(248, 81, 73, .4);--color-split-divider: #d0d7de;--color-widget-bg: #f6f8fa;--color-comment-btn-bg: #238636;--color-comment-indicator: #0969da;--color-scrollbar-track: #ffffff;--color-scrollbar-thumb: #d0d7de;--color-scrollbar-thumb-hover: #afb8c1;--color-token-comment: #6e7781;--color-token-punctuation: #1f2328;--color-token-property: #0550ae;--color-token-string: #0a3069;--color-token-operator: #cf222e;--color-token-keyword: #cf222e;--color-token-function: #8250df;--color-token-variable: #953800;--color-added: rgba(46, 160, 67, .44);--color-deleted: rgba(248, 81, 73, .44)}.dark{--color-background: #0d1117;--color-surface: #161b22;--color-border: #30363d;--color-text-primary: #e6edf3;--color-text-secondary: #8b949e;--color-accent: #58a6ff;--color-diff-bg: #0d1117;--color-diff-text: #e6edf3;--color-gutter-bg: #161b22;--color-gutter-text: #8b949e;--color-gutter-border: #30363d;--color-diff-insert-bg: rgba(46, 160, 67, .15);--color-diff-insert-gutter-bg: rgba(46, 160, 67, .2);--color-diff-insert-gutter-text: #7ee787;--color-diff-delete-bg: rgba(248, 81, 73, .15);--color-diff-delete-gutter-bg: rgba(248, 81, 73, .2);--color-diff-delete-gutter-text: #f85149;--color-hunk-bg: rgba(88, 166, 255, .1);--color-hunk-border: #30363d;--color-hunk-gutter-bg: rgba(88, 166, 255, .15);--color-hunk-gutter-text: #58a6ff;--color-hunk-content-text: #8b949e;--color-diff-edit-insert: rgba(46, 160, 67, .4);--color-diff-edit-delete: rgba(248, 81, 73, .4);--color-split-divider: #30363d;--color-widget-bg: #161b22;--color-comment-btn-bg: #238636;--color-comment-indicator: #58a6ff;--color-scrollbar-track: #0d1117;--color-scrollbar-thumb: #30363d;--color-scrollbar-thumb-hover: #484f58;--color-token-comment: #8b949e;--color-token-punctuation: #e6edf3;--color-token-property: #79c0ff;--color-token-string: #a5d6ff;--color-token-operator: #ff7b72;--color-token-keyword: #ff7b72;--color-token-function: #d2a8ff;--color-token-variable: #ffa657;--color-added: rgba(46, 160, 67, .44);--color-deleted: rgba(248, 81, 73, .44)}.diff-unified,.diff-split{background-color:var(--color-diff-bg);color:var(--color-diff-text);font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;font-size:13px;line-height:20px}.diff-unified .diff-gutter,.diff-split .diff-gutter{background-color:var(--color-gutter-bg);color:var(--color-gutter-text);border-right:1px solid var(--color-gutter-border);padding:0 8px;min-width:50px;text-align:right;-webkit-user-select:none;-moz-user-select:none;user-select:none;cursor:default}.diff-unified .diff-gutter-col,.diff-split .diff-gutter-col{width:60px;min-width:60px}.diff-unified .diff-code,.diff-split .diff-code{padding:0 12px;white-space:pre}.diff-unified .diff-code-insert,.diff-split .diff-code-insert{background-color:var(--color-diff-insert-bg)}.diff-unified .diff-code-insert .diff-code-text,.diff-split .diff-code-insert .diff-code-text{background-color:transparent}.diff-unified .diff-gutter-insert,.diff-split .diff-gutter-insert{background-color:var(--color-diff-insert-gutter-bg);color:var(--color-diff-insert-gutter-text)}.diff-unified .diff-code-delete,.diff-split .diff-code-delete{background-color:var(--color-diff-delete-bg)}.diff-unified .diff-code-delete .diff-code-text,.diff-split .diff-code-delete .diff-code-text{background-color:transparent}.diff-unified .diff-gutter-delete,.diff-split .diff-gutter-delete{background-color:var(--color-diff-delete-gutter-bg);color:var(--color-diff-delete-gutter-text)}.diff-unified .diff-code-normal,.diff-split .diff-code-normal{background-color:transparent}.diff-unified .diff-gutter-normal,.diff-split .diff-gutter-normal{background-color:var(--color-gutter-bg)}.diff-unified .diff-hunk-header,.diff-split .diff-hunk-header{background-color:var(--color-hunk-bg);border-top:1px solid var(--color-hunk-border);border-bottom:1px solid var(--color-hunk-border)}.diff-unified .diff-hunk-header-gutter,.diff-split .diff-hunk-header-gutter{background-color:var(--color-hunk-gutter-bg);color:var(--color-hunk-gutter-text)}.diff-unified .diff-hunk-header-content,.diff-split .diff-hunk-header-content{color:var(--color-hunk-content-text);padding:4px 12px;font-style:italic}.diff-unified .diff-code-edit .diff-code-text .diff-code-edit-text,.diff-split .diff-code-edit .diff-code-text .diff-code-edit-text{background-color:var(--color-diff-edit-insert);border-radius:2px}.diff-unified .diff-code-delete .diff-code-text .diff-code-edit-text,.diff-split .diff-code-delete .diff-code-text .diff-code-edit-text{background-color:var(--color-diff-edit-delete);border-radius:2px}.diff-unified table,.diff-split table{width:100%;border-collapse:collapse;table-layout:fixed}.diff-unified td,.diff-split td{vertical-align:top}.diff-split .diff-split-side-new .diff-gutter{border-left:1px solid var(--color-split-divider)}.diff-unified .token.comment,.diff-unified .token.prolog,.diff-unified .token.doctype,.diff-unified .token.cdata,.diff-split .token.comment,.diff-split .token.prolog,.diff-split .token.doctype,.diff-split .token.cdata{color:var(--color-token-comment)}.diff-unified .token.punctuation,.diff-split .token.punctuation{color:var(--color-token-punctuation)}.diff-unified .token.property,.diff-unified .token.tag,.diff-unified .token.boolean,.diff-unified .token.number,.diff-unified .token.constant,.diff-unified .token.symbol,.diff-split .token.property,.diff-split .token.tag,.diff-split .token.boolean,.diff-split .token.number,.diff-split .token.constant,.diff-split .token.symbol{color:var(--color-token-property)}.diff-unified .token.selector,.diff-unified .token.attr-name,.diff-unified .token.string,.diff-unified .token.char,.diff-unified .token.builtin,.diff-split .token.selector,.diff-split .token.attr-name,.diff-split .token.string,.diff-split .token.char,.diff-split .token.builtin{color:var(--color-token-string)}.diff-unified .token.operator,.diff-unified .token.entity,.diff-unified .token.url,.diff-split .token.operator,.diff-split .token.entity,.diff-split .token.url{color:var(--color-token-operator)}.diff-unified .token.atrule,.diff-unified .token.attr-value,.diff-unified .token.keyword,.diff-split .token.atrule,.diff-split .token.attr-value,.diff-split .token.keyword{color:var(--color-token-keyword)}.diff-unified .token.function,.diff-unified .token.class-name,.diff-split .token.function,.diff-split .token.class-name{color:var(--color-token-function)}.diff-unified .token.regex,.diff-unified .token.important,.diff-unified .token.variable,.diff-split .token.regex,.diff-split .token.important,.diff-split .token.variable{color:var(--color-token-variable)}.diff-unified .token.string,.diff-split .token.string{color:var(--color-token-string)}.diff-hunk-focused{outline:2px solid var(--color-accent);outline-offset:-2px}.diff-unified .diff-gutter,.diff-split .diff-gutter{cursor:pointer;position:relative}.diff-gutter-add-comment{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:3px;background-color:var(--color-comment-btn-bg);color:#fff;font-size:12px;font-weight:700;line-height:1;position:absolute;left:2px;top:50%;transform:translateY(-50%)}.diff-comment-indicator{display:inline-block;width:6px;height:6px;border-radius:50%;background-color:var(--color-comment-indicator);position:absolute;left:4px;top:50%;transform:translateY(-50%)}.diff-widget{background-color:var(--color-widget-bg)}.diff-widget-content{padding:0}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:var(--color-scrollbar-track)}::-webkit-scrollbar-thumb{background:var(--color-scrollbar-thumb);border-radius:4px}::-webkit-scrollbar-thumb:hover{background:var(--color-scrollbar-thumb-hover)}.placeholder\:text-text-secondary::-moz-placeholder{color:var(--color-text-secondary)}.placeholder\:text-text-secondary::placeholder{color:var(--color-text-secondary)}.hover\:border-blue-400:hover{--tw-border-opacity:1;border-color:rgb(96 165 250 / var(--tw-border-opacity, 1))}.hover\:border-gray-400:hover{--tw-border-opacity:1;border-color:rgb(156 163 175 / var(--tw-border-opacity, 1))}.hover\:border-green-400:hover{--tw-border-opacity:1;border-color:rgb(74 222 128 / var(--tw-border-opacity, 1))}.hover\:border-red-400:hover{--tw-border-opacity:1;border-color:rgb(248 113 113 / var(--tw-border-opacity, 1))}.hover\:bg-blue-200:hover{--tw-bg-opacity:1;background-color:rgb(191 219 254 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-200:hover{--tw-bg-opacity:1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.hover\:bg-green-200:hover{--tw-bg-opacity:1;background-color:rgb(187 247 208 / var(--tw-bg-opacity, 1))}.hover\:bg-green-500\/10:hover{background-color:#22c55e1a}.hover\:bg-red-200:hover{--tw-bg-opacity:1;background-color:rgb(254 202 202 / var(--tw-bg-opacity, 1))}.hover\:text-accent:hover{color:var(--color-accent)}.hover\:text-green-500:hover{--tw-text-opacity:1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.hover\:text-red-700:hover{--tw-text-opacity:1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.hover\:text-text-primary:hover{color:var(--color-text-primary)}.focus\:border-accent:focus{border-color:var(--color-accent)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-1:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-accent:focus{--tw-ring-color:var(--color-accent)}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.group:hover .group-hover\:text-text-primary{color:var(--color-text-primary)}.group\/comment:hover .group-hover\/comment\:opacity-100,.group:hover .group-hover\:opacity-100{opacity:1}.group:hover .group-hover\:opacity-40{opacity:.4}.dark\:border-blue-500\/30:is(.dark *){border-color:#3b82f64d}.dark\:border-gray-500\/30:is(.dark *){border-color:#6b72804d}.dark\:border-green-400\/30:is(.dark *){border-color:#4ade804d}.dark\:border-green-500\/30:is(.dark *){border-color:#22c55e4d}.dark\:border-orange-500\/30:is(.dark *){border-color:#f973164d}.dark\:border-purple-500\/30:is(.dark *){border-color:#a855f74d}.dark\:border-red-500\/30:is(.dark *){border-color:#ef44444d}.dark\:border-yellow-500\/30:is(.dark *){border-color:#eab3084d}.dark\:bg-blue-600\/20:is(.dark *){background-color:#2563eb33}.dark\:bg-gray-600\/20:is(.dark *){background-color:#4b556333}.dark\:bg-green-600\/20:is(.dark *){background-color:#16a34a33}.dark\:bg-orange-600\/20:is(.dark *){background-color:#ea580c33}.dark\:bg-purple-600\/20:is(.dark *){background-color:#9333ea33}.dark\:bg-red-600\/20:is(.dark *){background-color:#dc262633}.dark\:bg-yellow-600\/20:is(.dark *){background-color:#ca8a0433}.dark\:text-blue-400:is(.dark *){--tw-text-opacity:1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.dark\:text-cyan-400:is(.dark *){--tw-text-opacity:1;color:rgb(34 211 238 / var(--tw-text-opacity, 1))}.dark\:text-gray-400:is(.dark *){--tw-text-opacity:1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.dark\:text-green-400:is(.dark *){--tw-text-opacity:1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.dark\:text-orange-400:is(.dark *){--tw-text-opacity:1;color:rgb(251 146 60 / var(--tw-text-opacity, 1))}.dark\:text-purple-400:is(.dark *){--tw-text-opacity:1;color:rgb(192 132 252 / var(--tw-text-opacity, 1))}.dark\:text-red-400:is(.dark *){--tw-text-opacity:1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.dark\:text-yellow-400:is(.dark *){--tw-text-opacity:1;color:rgb(250 204 21 / var(--tw-text-opacity, 1))}.dark\:hover\:border-blue-500\/50:hover:is(.dark *){border-color:#3b82f680}.dark\:hover\:border-gray-500\/50:hover:is(.dark *){border-color:#6b728080}.dark\:hover\:border-green-500\/50:hover:is(.dark *){border-color:#22c55e80}.dark\:hover\:border-red-500\/50:hover:is(.dark *){border-color:#ef444480}.dark\:hover\:bg-blue-600\/30:hover:is(.dark *){background-color:#2563eb4d}.dark\:hover\:bg-gray-500\/30:hover:is(.dark *){background-color:#6b72804d}.dark\:hover\:bg-gray-600\/30:hover:is(.dark *){background-color:#4b55634d}.dark\:hover\:bg-green-600\/30:hover:is(.dark *){background-color:#16a34a4d}.dark\:hover\:bg-red-600\/30:hover:is(.dark *){background-color:#dc26264d}.dark\:hover\:text-red-400:hover:is(.dark *){--tw-text-opacity:1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}