@bhooai/nexus-graphql 2.0.11 → 2.0.13
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/package.json +6 -1
- package/src/builtin/helloSubgraph.ts +38 -0
- package/src/builtin/index.ts +3 -0
- package/src/explorer/explorerHtml.ts +1642 -0
- package/src/federation/createFederatedGateway.ts +6 -1
- package/src/federation/executor.ts +81 -6
- package/src/federation/parseMetadata.ts +13 -11
- package/src/gateway/graphqlHttpHandler.ts +31 -4
- package/src/index.ts +4 -1
- package/src/mutationCsrf.ts +25 -0
|
@@ -0,0 +1,1642 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GraphQL Explorer HTML — served from the backend at GET /graphql (Accept: text/html),
|
|
3
|
+
* GET /graphiql and GET /explorer.
|
|
4
|
+
*
|
|
5
|
+
* Zero build dependency: loads GraphiQL 3 + graphql 16 via CDN, wraps in a
|
|
6
|
+
* BhooAI Nexus branded chrome (glass-card, mesh, aurora tokens) so the
|
|
7
|
+
* playground feels native to the framework. Includes a tiny AI assistant panel
|
|
8
|
+
* that POSTs to /ai/chat (if the AI server is configured) with the schema SDL
|
|
9
|
+
* as context to generate queries from natural language.
|
|
10
|
+
*
|
|
11
|
+
* No auth guard — the explorer is public when introspection is enabled, just
|
|
12
|
+
* like POST /graphql. Disable with `graphql.explorer: false` in nexus.config.ts.
|
|
13
|
+
*/
|
|
14
|
+
const AURORA_CSS = `.agent-shell { display:flex; flex-direction:column; height:100vh; height:100dvh; overflow:hidden; background:#040b18; isolation:isolate; }
|
|
15
|
+
.agent-shell::before { position:fixed; inset:0; z-index:0; pointer-events:none; content:""; opacity:.5;
|
|
16
|
+
background-image:linear-gradient(rgba(95,164,241,.05) 1px, transparent 1px), linear-gradient(90deg, rgba(95,164,241,.05) 1px, transparent 1px);
|
|
17
|
+
background-size:48px 48px; mask-image:linear-gradient(to bottom, black, transparent 78%); }
|
|
18
|
+
.agent-aurora { position:fixed; inset:0; z-index:0; overflow:hidden; pointer-events:none; }
|
|
19
|
+
.agent-aurora i { position:absolute; border-radius:50%; filter:blur(90px); opacity:.55; mix-blend-mode:screen; will-change:transform; }
|
|
20
|
+
.agent-aurora i:nth-child(1) { width:44rem; height:44rem; top:-12rem; left:-8rem; background:radial-gradient(circle at 35% 35%, rgba(84,183,255,.5), transparent 68%); animation:agent-drift-a 30s ease-in-out infinite alternate; }
|
|
21
|
+
.agent-aurora i:nth-child(2) { width:40rem; height:40rem; right:-10rem; bottom:-8rem; background:radial-gradient(circle at 60% 60%, rgba(159,123,255,.45), transparent 68%); animation:agent-drift-b 36s ease-in-out infinite alternate; }
|
|
22
|
+
.agent-aurora i:nth-child(3) { width:34rem; height:34rem; top:24%; left:46%; background:radial-gradient(circle at 50% 50%, rgba(243,110,184,.3), transparent 70%); animation:agent-drift-c 26s ease-in-out infinite alternate; }
|
|
23
|
+
@keyframes agent-drift-a { from { transform:translate3d(0,0,0) scale(1); } to { transform:translate3d(10rem,6rem,0) scale(1.18); } }
|
|
24
|
+
@keyframes agent-drift-b { from { transform:translate3d(0,0,0) scale(1.05); } to { transform:translate3d(-9rem,-5rem,0) scale(.9); } }
|
|
25
|
+
@keyframes agent-drift-c { from { transform:translate3d(0,0,0) scale(.95); } to { transform:translate3d(-7rem,9rem,0) scale(1.15); } }
|
|
26
|
+
.agent-shell > .agent-header,
|
|
27
|
+
.agent-shell > .agent-workspace,
|
|
28
|
+
.agent-shell > .agent-footer { position:relative; z-index:1; }
|
|
29
|
+
|
|
30
|
+
.agent-header { position:relative; z-index:20; flex:0 0 auto; background:linear-gradient(180deg, rgba(9,24,48,.9), rgba(4,14,29,.74)); border-bottom:1px solid rgba(112,168,228,.2); box-shadow:inset 0 1px 0 rgba(255,255,255,.05), 0 12px 40px rgba(2,8,20,.45); backdrop-filter:blur(26px); -webkit-backdrop-filter:blur(26px); }
|
|
31
|
+
.agent-header::after { position:absolute; left:24px; right:24px; bottom:-1px; height:1px; content:""; background:linear-gradient(90deg, transparent, rgba(84,183,255,.55), rgba(159,123,255,.5), transparent); pointer-events:none; }
|
|
32
|
+
.agent-header-inner { display:flex; align-items:center; gap:.7rem; row-gap:.5rem; flex-wrap:wrap; width:calc(100% - 48px); max-width:1400px; margin:0 auto; padding:.72rem 0; }
|
|
33
|
+
.agent-urlbar { display:flex; align-items:center; gap:.4rem; width:calc(100% - 48px); max-width:1400px; margin:0 auto; padding:.32rem 0 .5rem; }
|
|
34
|
+
.agent-urlbar-input { flex:1; min-width:0; display:flex; align-items:center; gap:.5rem; padding:.3rem .4rem .3rem .75rem; border:1px solid rgba(112,168,228,.22); border-radius:.6rem; background:rgba(4,14,29,.5); color:#9fb3d0; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.66rem; transition:border-color .14s, box-shadow .14s, background .14s; }
|
|
35
|
+
.agent-urlbar-input:focus-within { border-color:rgba(84,183,255,.55); box-shadow:0 0 0 2px rgba(84,183,255,.14); background:rgba(8,25,48,.6); }
|
|
36
|
+
.agent-urlbar-lock { flex:0 0 auto; color:#5ef0b3; font-size:.7rem; line-height:1; }
|
|
37
|
+
.agent-urlbar-field { flex:1; min-width:0; border:0; outline:none; color:#dcecff; background:transparent; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.68rem; caret-color:#54b7ff; }
|
|
38
|
+
.agent-urlbar-field::placeholder { color:#4b647f; }
|
|
39
|
+
.agent-urlbar-btn { display:grid; place-items:center; flex:0 0 auto; width:1.7rem; height:1.7rem; border:1px solid rgba(112,168,228,.24); border-radius:.5rem; color:#8fb8e4; background:rgba(84,183,255,.08); font-size:.78rem; line-height:1; cursor:pointer; transition:border-color .14s, color .14s, background .14s, transform .14s; }
|
|
40
|
+
.agent-urlbar-btn:hover { border-color:rgba(84,183,255,.55); color:#bfe9ff; background:rgba(84,183,255,.16); transform:translateY(-1px); }
|
|
41
|
+
.agent-urlbar-btn.copied { color:#6df0bb; border-color:rgba(52,211,153,.5); background:rgba(16,185,129,.14); }
|
|
42
|
+
.agent-urlbar-note { flex:0 0 auto; color:#4d6378; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.56rem; letter-spacing:.04em; }
|
|
43
|
+
.agent-header .agent-select-wrap { min-width:0; }
|
|
44
|
+
.agent-header .agent-select { min-width:0; text-overflow:ellipsis; }
|
|
45
|
+
.agent-back { display:inline-flex; align-items:center; gap:.45rem; padding:.5rem .8rem; border:1px solid rgba(84,183,255,.34); border-radius:.6rem; color:#9fd4ff; background:rgba(84,183,255,.1); font-size:.68rem; font-weight:700; letter-spacing:.02em; cursor:pointer; transition:border-color .15s, color .15s, background .15s, transform .15s; }
|
|
46
|
+
.agent-back:hover { border-color:rgba(84,183,255,.7); color:#fff; background:rgba(84,183,255,.2); transform:translateY(-1px); }
|
|
47
|
+
.agent-brand { display:inline-flex; align-items:center; gap:.75rem; margin:0; }
|
|
48
|
+
.agent-brand-badge { position:relative; display:grid; place-items:center; width:2.25rem; height:2.25rem; border-radius:.7rem; border:1px solid rgba(84,183,255,.42); background:linear-gradient(135deg, rgba(38,130,225,.32), rgba(90,67,183,.26)); box-shadow:0 0 20px rgba(58,149,255,.32), inset 0 1px rgba(255,255,255,.16); }
|
|
49
|
+
.agent-brand-badge::after { position:absolute; inset:0; border-radius:.7rem; content:""; background:radial-gradient(120% 120% at 50% 0%, rgba(120,200,255,.28), transparent 55%); }
|
|
50
|
+
.agent-brand-dot { position:relative; z-index:1; width:.52rem; height:.52rem; border-radius:50%; background:#5ef0b3; box-shadow:0 0 12px rgba(94,240,179,.95), 0 0 26px rgba(94,240,179,.45); }
|
|
51
|
+
.agent-brand-text { display:flex; flex-direction:column; gap:.12rem; line-height:1.1; }
|
|
52
|
+
.agent-brand-name { color:#f1f8ff; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.8rem; font-weight:800; letter-spacing:.16em; text-transform:uppercase; }
|
|
53
|
+
.agent-brand-name em { color:#63bdff; font-style:normal; text-shadow:0 0 18px rgba(84,183,255,.5); }
|
|
54
|
+
.agent-brand-sub { color:#4f6b8c; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.55rem; letter-spacing:.14em; text-transform:uppercase; }
|
|
55
|
+
.agent-spacer { flex:1; }
|
|
56
|
+
|
|
57
|
+
/* ── Unified tooltip — single style for every [data-tip] element on the page ── */
|
|
58
|
+
[data-tip]{ position:relative; }
|
|
59
|
+
[data-tip]::after{ position:absolute; left:50%; bottom:calc(100% + 8px); transform:translateX(-50%) translateY(2px); z-index:120; padding:.35rem .6rem; border:1px solid rgba(112,168,228,.28); border-radius:.45rem; background:linear-gradient(160deg, rgba(10,28,55,.97), rgba(6,16,36,.98)); color:#dcecff; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.56rem; font-weight:600; letter-spacing:.03em; line-height:1.4; white-space:nowrap; content:attr(data-tip); opacity:0; visibility:hidden; pointer-events:none; box-shadow:0 12px 32px rgba(0,0,0,.4), inset 0 1px rgba(255,255,255,.06); backdrop-filter:blur(18px) saturate(140%); -webkit-backdrop-filter:blur(18px) saturate(140%); transition:opacity .16s ease, transform .16s ease, visibility .16s; }
|
|
60
|
+
[data-tip]::before{ position:absolute; left:50%; bottom:calc(100% + 4px); transform:translateX(-50%) rotate(45deg); z-index:119; width:.5rem; height:.5rem; border-right:1px solid rgba(112,168,228,.28); border-bottom:1px solid rgba(112,168,228,.28); background:rgba(10,28,55,.98); content:""; opacity:0; visibility:hidden; pointer-events:none; transition:opacity .16s ease, visibility .16s; }
|
|
61
|
+
[data-tip]:hover::after, [data-tip]:hover::before,
|
|
62
|
+
[data-tip]:focus-visible::after, [data-tip]:focus-visible::before{ opacity:1; visibility:visible; transform:translateX(-50%) translateY(0); }
|
|
63
|
+
[data-tip]:hover::before, [data-tip]:focus-visible::before{ transform:translateX(-50%) rotate(45deg); }
|
|
64
|
+
/* Tooltip below for elements near the top edge (e.g. header buttons). */
|
|
65
|
+
[data-tip="bottom"]::after, [data-tip-bottom]::after{ bottom:auto; top:calc(100% + 8px); transform:translateX(-50%) translateY(-2px); }
|
|
66
|
+
[data-tip="bottom"]::before, [data-tip-bottom]::before{ bottom:auto; top:calc(100% + 4px); transform:translateX(-50%) rotate(45deg); }
|
|
67
|
+
[data-tip="bottom"]:hover::after, [data-tip-bottom]:hover::after{ transform:translateX(-50%) translateY(0); }
|
|
68
|
+
[data-theme="light"] [data-tip]::after{ background:linear-gradient(160deg, rgba(255,255,255,.98), rgba(238,245,255,.98)); color:#0b1220; border-color:rgba(60,110,180,.24); box-shadow:0 12px 32px rgba(20,50,100,.16), inset 0 1px rgba(255,255,255,.7); }
|
|
69
|
+
[data-theme="light"] [data-tip]::before{ background:#f2f7ff; border-color:rgba(60,110,180,.24); }
|
|
70
|
+
.agent-status { display:inline-flex; align-items:center; gap:.42rem; padding:.4rem .7rem; border:1px solid rgba(52,211,153,.32); border-radius:999px; background:rgba(16,185,129,.12); color:#7ee8bd; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.58rem; font-weight:700; letter-spacing:.1em; text-transform:uppercase; }
|
|
71
|
+
.agent-status-dot { width:.42rem; height:.42rem; border-radius:50%; background:#5ef0b3; box-shadow:0 0 10px rgba(94,240,179,.9); animation:agent-pulse 2.4s ease-in-out infinite; }
|
|
72
|
+
.agent-select-wrap { display:inline-flex; align-items:center; gap:.42rem; padding:.22rem .3rem .22rem .6rem; border:1px solid rgba(112,168,228,.2); border-radius:.6rem; background:rgba(20,46,79,.3); transition:border-color .14s, background .14s, box-shadow .14s; }
|
|
73
|
+
.agent-select-wrap:focus-within { border-color:rgba(84,183,255,.55); background:rgba(20,46,79,.5); box-shadow:0 0 0 2px rgba(84,183,255,.15); }
|
|
74
|
+
.agent-select-label { color:#53708f; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.54rem; letter-spacing:.13em; text-transform:uppercase; white-space:nowrap; }
|
|
75
|
+
.agent-select { appearance:auto; -webkit-appearance:auto; padding:.42rem .55rem; border:0; border-radius:.4rem; outline:none; color:#dcecff; background:#0e1b33; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.64rem; font-weight:500; line-height:1.3; max-width:220px; min-height:1.9rem; cursor:pointer; color-scheme:dark; transition:background .14s, box-shadow .14s; }
|
|
76
|
+
.agent-select:hover { background:#132a4d; }
|
|
77
|
+
.agent-select:focus-visible { box-shadow:0 0 0 2px rgba(84,183,255,.35); }
|
|
78
|
+
.agent-select option { background:#0b1024; color:#e5f4ff; padding:.4rem .6rem; font-size:.64rem; }
|
|
79
|
+
.agent-select option:checked { background:#16325c; color:#fff; }
|
|
80
|
+
.agent-select optgroup { background:#0b1024; color:#63bdff; font-style:normal; font-size:.6rem; padding:.3rem .5rem; }
|
|
81
|
+
.agent-select optgroup option { background:#0b1024; color:#dcecff; font-style:normal; }
|
|
82
|
+
.agent-select optgroup option:hover { background:#1c3f6e; color:#fff; }
|
|
83
|
+
.agent-actions { display:inline-flex; align-items:center; gap:.45rem; }
|
|
84
|
+
.agent-clear { display:inline-flex; align-items:center; gap:.4rem; padding:.5rem .75rem; border:1px solid rgba(112,168,228,.24); border-radius:.6rem; color:#8fb8e4; background:rgba(84,183,255,.08); font-size:.66rem; font-weight:700; cursor:pointer; transition:border-color .15s, color .15s, background .15s, transform .15s; }
|
|
85
|
+
.agent-clear:hover { border-color:rgba(84,183,255,.55); color:#bfe9ff; background:rgba(84,183,255,.16); transform:translateY(-1px); }
|
|
86
|
+
.agent-clear.danger { border-color:rgba(251,113,133,.3); color:#f8c0cd; background:rgba(244,63,94,.1); }
|
|
87
|
+
.agent-clear.danger:hover { border-color:rgba(251,113,133,.55); color:#ffe4e6; background:rgba(244,63,94,.24); }
|
|
88
|
+
.agent-modes { display:inline-flex; gap:.25rem; padding:.25rem; border:1px solid rgba(112,168,228,.2); border-radius:.6rem; background:rgba(20,46,79,.28); }
|
|
89
|
+
.agent-mode { padding:.42rem .7rem; border:1px solid transparent; border-radius:.45rem; color:#7d94b2; background:transparent; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.62rem; font-weight:700; letter-spacing:.08em; cursor:pointer; transition:color .14s, background .14s, border-color .14s, box-shadow .14s; }
|
|
90
|
+
.agent-mode:hover { color:#dcecff; }
|
|
91
|
+
.agent-mode.mode-plan.active { color:#ffd479; background:linear-gradient(135deg, rgba(245,158,11,.28), rgba(180,83,9,.16)); border-color:rgba(255,196,107,.4); box-shadow:0 0 14px rgba(245,158,11,.2); }
|
|
92
|
+
.agent-mode.mode-auto.active { color:#6df0bb; background:linear-gradient(135deg, rgba(16,185,129,.26), rgba(6,95,70,.16)); border-color:rgba(52,211,153,.4); box-shadow:0 0 14px rgba(16,185,129,.2); }
|
|
93
|
+
.agent-mode.mode-build.active { color:#bfe9ff; background:linear-gradient(135deg, rgba(40,137,235,.34), rgba(76,83,212,.22)); border-color:rgba(84,183,255,.5); box-shadow:0 0 16px rgba(84,183,255,.24), inset 0 1px rgba(255,255,255,.08); }
|
|
94
|
+
|
|
95
|
+
.agent-workspace { flex:1 1 auto; min-height:0; min-width:0; display:flex; width:calc(100% - 48px); max-width:1400px; margin:0 auto; }
|
|
96
|
+
.agent-main { flex:1 1 auto; min-width:0; min-height:0; overflow-y:auto; overflow-x:hidden; padding:2rem 1.75rem 1.5rem; }
|
|
97
|
+
.agent-side { flex:0 0 360px; min-width:0; min-height:0; overflow-y:auto; overflow-x:hidden; border-left:1px solid rgba(112,168,228,.13); background:rgba(4,15,31,.4); padding:1.4rem 0 1.3rem 1.2rem; }
|
|
98
|
+
.agent-side-backdrop { position:fixed; inset:0; z-index:45; background:rgba(2,8,20,.5); backdrop-filter:blur(2px); -webkit-backdrop-filter:blur(2px); animation:agent-fade .2s ease both; }
|
|
99
|
+
@keyframes agent-fade { from { opacity:0; } to { opacity:1; } }
|
|
100
|
+
.agent-side-toggle { display:none; grid:place-items:center / none; place-items:center; width:2.1rem; height:2.1rem; padding:0; border:1px solid rgba(112,168,228,.24); border-radius:.6rem; color:#8fb8e4; background:rgba(84,183,255,.08); font-size:.85rem; line-height:1; cursor:pointer; transition:border-color .15s, color .15s, background .15s, transform .15s; }
|
|
101
|
+
.agent-side-toggle:hover { border-color:rgba(84,183,255,.55); color:#bfe9ff; background:rgba(84,183,255,.16); }
|
|
102
|
+
.agent-side-toggle.on { color:#9fe8ff; border-color:rgba(99,189,255,.6); background:rgba(40,137,235,.2); }
|
|
103
|
+
.agent-side-inner { display:flex; flex-direction:column; gap:1.1rem; }
|
|
104
|
+
.agent-side-head { display:flex; align-items:center; gap:.5rem; color:#6e8aaa; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.6rem; letter-spacing:.13em; }
|
|
105
|
+
.agent-side-title { font-weight:800; color:#63bdff; }
|
|
106
|
+
.agent-side-badge { padding:.08rem .45rem; border-radius:999px; color:#ffd479; background:rgba(245,158,11,.16); border:1px solid rgba(255,196,107,.3); font-size:.6rem; font-weight:800; }
|
|
107
|
+
.agent-side-batch { display:flex; gap:.4rem; }
|
|
108
|
+
.agent-side-batch-btn { padding:.34rem .6rem; border-radius:.45rem; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.58rem; font-weight:700; cursor:pointer; transition:filter .14s, transform .14s; }
|
|
109
|
+
.agent-side-batch-btn.allow { border:1px solid rgba(52,211,153,.4); color:#a7f3d0; background:linear-gradient(135deg, rgba(16,185,129,.55), rgba(5,150,105,.45)); }
|
|
110
|
+
.agent-side-batch-btn.deny { border:1px solid rgba(251,113,133,.4); color:#fecdd3; background:linear-gradient(135deg, rgba(244,63,94,.5), rgba(159,18,57,.42)); }
|
|
111
|
+
.agent-side-batch-btn:hover { filter:brightness(1.14); transform:translateY(-1px); }
|
|
112
|
+
.agent-side-section { display:flex; flex-direction:column; gap:.4rem; }
|
|
113
|
+
.agent-side-section-head { display:flex; align-items:center; gap:.4rem; }
|
|
114
|
+
.agent-side-section-title { color:#536c8c; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.56rem; letter-spacing:.16em; text-transform:uppercase; }
|
|
115
|
+
.agent-side-section-badge { padding:.05rem .42rem; border-radius:999px; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.56rem; font-weight:800; line-height:1.4; border:1px solid; }
|
|
116
|
+
.agent-side-section-badge.approval { color:#ffd479; border-color:rgba(255,196,107,.32); background:rgba(245,158,11,.14); }
|
|
117
|
+
.agent-side-section-badge.running { color:#8ed6ff; border-color:rgba(84,183,255,.34); background:rgba(84,183,255,.12); }
|
|
118
|
+
.agent-side-section-badge.done { color:#6df0bb; border-color:rgba(52,211,153,.3); background:rgba(16,185,129,.12); }
|
|
119
|
+
.agent-side-section-badge.zero { opacity:.45; }
|
|
120
|
+
.agent-side-empty { margin:0; color:#45597a; font-size:.64rem; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; }
|
|
121
|
+
.agent-task-row { display:flex; align-items:center; gap:.45rem; padding:.4rem .55rem; border:1px solid rgba(112,168,228,.17); border-radius:.55rem; background:rgba(8,25,48,.6); box-shadow:inset 0 1px rgba(255,255,255,.04); cursor:pointer; transition:border-color .14s, background .14s, transform .14s; }
|
|
122
|
+
.agent-task-row:hover { border-color:rgba(84,183,255,.5); background:rgba(84,183,255,.1); transform:translateY(-1px); }
|
|
123
|
+
.agent-task-dot { width:.4rem; height:.4rem; flex:0 0 auto; border-radius:50%; background:#54b7ff; box-shadow:0 0 8px rgba(84,183,255,.7); }
|
|
124
|
+
.agent-task-dot.running { animation:agent-pulse 1s ease-in-out infinite; }
|
|
125
|
+
.agent-task-dot.ok, .agent-task-dot.approved { background:#5ef0b3; box-shadow:0 0 8px rgba(94,240,179,.8); }
|
|
126
|
+
.agent-task-dot.error, .agent-task-dot.denied { background:#fb7185; box-shadow:0 0 8px rgba(244,63,94,.7); }
|
|
127
|
+
.agent-task-dot.approval { background:#fbbf24; box-shadow:0 0 8px rgba(251,191,36,.7); animation:agent-pulse 1s ease-in-out infinite; }
|
|
128
|
+
.agent-task-summary { flex:1; min-width:0; color:#9fb3d0; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.6rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
129
|
+
.agent-task-actions { display:inline-flex; gap:.3rem; flex:0 0 auto; }
|
|
130
|
+
.agent-task-allow, .agent-task-deny { padding:.2rem .45rem; border-radius:.4rem; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.56rem; font-weight:700; cursor:pointer; transition:filter .14s; }
|
|
131
|
+
.agent-task-allow { border:1px solid rgba(52,211,153,.4); color:#a7f3d0; background:rgba(16,185,129,.22); }
|
|
132
|
+
.agent-task-deny { border:1px solid rgba(251,113,133,.4); color:#fecdd3; background:rgba(244,63,94,.22); }
|
|
133
|
+
.agent-task-allow:hover, .agent-task-deny:hover { filter:brightness(1.15); }
|
|
134
|
+
.agent-list { display:flex; flex-direction:column; gap:1rem; }
|
|
135
|
+
.agent-empty { margin:3.5rem 0 0; color:#64758e; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.72rem; line-height:1.9; text-align:center; }
|
|
136
|
+
.agent-empty b { color:#54b7ff; font-weight:600; }
|
|
137
|
+
.agent-hint { display:block; margin-top:.6rem; font-size:.6rem; color:#4c5d77; line-height:1.9; }
|
|
138
|
+
.agent-hint b { color:#7c8fa9; font-weight:600; }
|
|
139
|
+
.agent-approval-actions { display:flex; gap:.5rem; padding:.6rem .85rem; border-top:1px solid rgba(112,168,228,.12); }
|
|
140
|
+
.agent-allow { padding:.45rem .85rem; border:1px solid rgba(52,211,153,.4); border-radius:.5rem; color:#a7f3d0; background:linear-gradient(135deg, rgba(16,185,129,.6), rgba(5,150,105,.5)); font-size:.68rem; font-weight:700; cursor:pointer; transition:filter .15s, transform .15s; }
|
|
141
|
+
.agent-allow:hover { filter:brightness(1.12); transform:translateY(-1px); }
|
|
142
|
+
.agent-deny { padding:.45rem .85rem; border:1px solid rgba(251,113,133,.4); border-radius:.5rem; color:#fecdd3; background:linear-gradient(135deg, rgba(244,63,94,.55), rgba(159,18,57,.48)); font-size:.68rem; font-weight:700; cursor:pointer; transition:filter .15s, transform .15s; }
|
|
143
|
+
.agent-deny:hover { filter:brightness(1.12); transform:translateY(-1px); }
|
|
144
|
+
|
|
145
|
+
.agent-row-user { display:flex; justify-content:flex-end; }
|
|
146
|
+
.agent-row-agent { display:flex; justify-content:flex-start; }
|
|
147
|
+
.agent-msg { display:flex; flex-direction:column; gap:.35rem; max-width:88%; min-width:0; }
|
|
148
|
+
.agent-role { display:inline-flex; align-items:center; gap:.45rem; color:#6e8aaa; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.58rem; letter-spacing:.13em; text-transform:uppercase; }
|
|
149
|
+
.agent-role-user { justify-content:flex-end; }
|
|
150
|
+
.agent-role-agent { justify-content:flex-start; }
|
|
151
|
+
.agent-bubble { padding:.75rem .95rem; border:1px solid rgba(112,168,228,.2); border-radius:.8rem; color:#dcecff; background:linear-gradient(145deg, rgba(13,35,67,.5), rgba(10,17,40,.5)); font-size:.86rem; line-height:1.7; white-space:pre-wrap; overflow-wrap:anywhere; word-break:break-word; box-shadow:0 14px 42px rgba(0,0,0,.14); }
|
|
152
|
+
.agent-row-user .agent-bubble { border-color:rgba(84,183,255,.4); background:linear-gradient(145deg, rgba(22,70,122,.5), rgba(46,41,112,.42)); color:#eaf7ff; box-shadow:inset 0 1px rgba(255,255,255,.06), 0 14px 42px rgba(0,0,0,.16); }
|
|
153
|
+
.agent-msg pre { margin:0; }
|
|
154
|
+
|
|
155
|
+
.agent-tool { border:1px solid rgba(112,168,228,.2); border-radius:.8rem; background:rgba(8,25,48,.7); box-shadow:inset 0 1px rgba(255,255,255,.04), 0 14px 42px rgba(0,0,0,.16); font-family:ui-monospace, SFMono-Regular, Consolas, monospace; overflow:hidden; backdrop-filter:blur(12px); -webkit-backdrop-filter:blur(12px); }
|
|
156
|
+
.agent-tool-head { display:flex; align-items:center; gap:.5rem; padding:.5rem .8rem; border-bottom:1px solid rgba(112,168,228,.12); color:#e2e8f0; font-size:.7rem; cursor:pointer; user-select:none; flex-wrap:wrap; }
|
|
157
|
+
.agent-tool-head .agent-tool-name { flex:0 0 auto; }
|
|
158
|
+
.agent-tool-head .agent-tool-summary { min-width:80px; }
|
|
159
|
+
.agent-tool-dot { width:.42rem; height:.42rem; flex:0 0 auto; border-radius:50%; background:#54b7ff; box-shadow:0 0 10px rgba(84,183,255,.8); animation:agent-pulse 1s ease-in-out infinite; }
|
|
160
|
+
@keyframes agent-pulse { 0%,100% { opacity:1; } 50% { opacity:.3; } }
|
|
161
|
+
.agent-tool.ok .agent-tool-dot { background:#5ef0b3; box-shadow:0 0 10px rgba(94,240,179,.8); animation:none; }
|
|
162
|
+
.agent-tool.err .agent-tool-dot { background:#fb7185; box-shadow:0 0 10px rgba(244,63,94,.8); animation:none; }
|
|
163
|
+
.agent-tool-name { color:#5cbaff; font-weight:700; flex:0 0 auto; }
|
|
164
|
+
.agent-tool.err .agent-tool-name { color:#fda4af; }
|
|
165
|
+
.agent-tool-summary { flex:1; min-width:0; color:#cfe3fb; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.66rem; letter-spacing:.01em; }
|
|
166
|
+
.agent-tool.err .agent-tool-summary { color:#fda4af; }
|
|
167
|
+
.agent-tool-status { flex:0 0 auto; padding:.12rem .42rem; border-radius:.35rem; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.52rem; font-weight:800; letter-spacing:.06em; text-transform:uppercase; border:1px solid transparent; }
|
|
168
|
+
.agent-tool-status.running { color:#8ed6ff; background:rgba(84,183,255,.12); border-color:rgba(84,183,255,.25); }
|
|
169
|
+
.agent-tool-status.ok { color:#6df0bb; background:rgba(16,185,129,.12); border-color:rgba(52,211,153,.22); }
|
|
170
|
+
.agent-tool-status.err { color:#fda4af; background:rgba(244,63,94,.12); border-color:rgba(244,63,94,.22); }
|
|
171
|
+
.agent-tool-badge { display:inline-flex; align-items:center; gap:.28rem; padding:.18rem .46rem; border-radius:.4rem; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.54rem; font-weight:800; letter-spacing:.07em; text-transform:uppercase; border:1px solid; flex:0 0 auto; line-height:1; }
|
|
172
|
+
.agent-tool-badge i { font-style:normal; font-size:.62rem; opacity:.9; }
|
|
173
|
+
.badge-read { color:#8ed6ff; border-color:rgba(84,183,255,.32); background:rgba(84,183,255,.14); }
|
|
174
|
+
.badge-write { color:#c4b5fd; border-color:rgba(139,92,246,.32); background:rgba(139,92,246,.13); }
|
|
175
|
+
.badge-edit { color:#6df0bb; border-color:rgba(52,211,153,.32); background:rgba(16,185,129,.14); }
|
|
176
|
+
.badge-bash { color:#fcd34d; border-color:rgba(245,158,11,.3); background:rgba(245,158,11,.13); }
|
|
177
|
+
.badge-grep { color:#f59e0b; border-color:rgba(245,158,11,.22); background:rgba(245,158,11,.08); }
|
|
178
|
+
.badge-glob { color:#93c5fd; border-color:rgba(96,165,250,.22); background:rgba(59,130,246,.08); }
|
|
179
|
+
.badge-list { color:#94a3b8; border-color:rgba(148,163,184,.22); background:rgba(148,163,184,.08); }
|
|
180
|
+
.badge-search { color:#67e8f9; border-color:rgba(6,182,212,.22); background:rgba(6,182,212,.08); }
|
|
181
|
+
.badge-generic { color:#9fd4ff; border-color:rgba(84,183,255,.22); background:rgba(84,183,255,.08); }
|
|
182
|
+
|
|
183
|
+
.agent-badge { display:flex; flex-direction:column; border:1px solid rgba(112,168,228,.22); border-radius:999px; background:linear-gradient(160deg, rgba(16,38,70,.5), rgba(8,20,42,.58)); box-shadow:inset 0 1px rgba(255,255,255,.05), 0 10px 26px rgba(0,0,0,.2); overflow:hidden; animation:agent-rise .28s cubic-bezier(.22,1,.36,1) both; transition:border-color .15s, border-radius .15s, transform .15s; }
|
|
184
|
+
.agent-badge:hover { border-color:rgba(84,183,255,.45); transform:translateY(-1px); }
|
|
185
|
+
.agent-badge-head { display:flex; align-items:center; gap:.5rem; padding:.42rem .8rem; color:#e2e8f0; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.7rem; cursor:pointer; user-select:none; }
|
|
186
|
+
.agent-badge-dot { width:.42rem; height:.42rem; flex:0 0 auto; border-radius:50%; background:#54b7ff; box-shadow:0 0 8px rgba(84,183,255,.7); animation:agent-pulse 1s ease-in-out infinite; }
|
|
187
|
+
.agent-badge.ok .agent-badge-dot { background:#5ef0b3; box-shadow:0 0 8px rgba(94,240,179,.7); animation:none; }
|
|
188
|
+
.agent-badge.err .agent-badge-dot { background:#fb7185; box-shadow:0 0 8px rgba(244,63,94,.7); animation:none; }
|
|
189
|
+
.agent-badge-name { color:#9fd4ff; font-weight:700; flex:0 0 auto; letter-spacing:.04em; }
|
|
190
|
+
.agent-badge.err .agent-badge-name { color:#fda4af; }
|
|
191
|
+
.agent-badge-param { flex:1; min-width:0; color:#9fb3d0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
192
|
+
.agent-badge.err .agent-badge-param { color:#fda4af; }
|
|
193
|
+
.agent-badge.expanded { border-radius:.85rem; }
|
|
194
|
+
.agent-toggle { display:inline-flex; align-items:center; justify-content:center; width:1.35rem; height:1.35rem; flex:0 0 auto; border:1px solid rgba(112,168,228,.22); border-radius:.4rem; color:#8fb8e4; background:transparent; font-family:inherit; font-size:.6rem; line-height:1; cursor:pointer; transition:border-color .14s, color .14s, background .14s; }
|
|
195
|
+
.agent-toggle:hover { border-color:rgba(84,183,255,.5); color:#bfe9ff; background:rgba(84,183,255,.1); }
|
|
196
|
+
.agent-tool-code { position:relative; border-top:1px solid rgba(112,168,228,.1); background:rgba(0,0,0,.3); }
|
|
197
|
+
.agent-tool-code .agent-tool-output { border-top:0; padding-top:2rem; }
|
|
198
|
+
.agent-copy { position:absolute; top:.5rem; right:.6rem; z-index:2; padding:.22rem .5rem; border:1px solid rgba(112,168,228,.28); border-radius:.4rem; color:#8fb8e4; background:rgba(4,14,29,.8); font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.56rem; cursor:pointer; transition:border-color .14s, color .14s; }
|
|
199
|
+
.agent-copy:hover { border-color:rgba(84,183,255,.55); color:#bfe9ff; }
|
|
200
|
+
.agent-diff { max-height:280px; overflow:auto; padding:2.2rem .6rem .6rem; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.7rem; line-height:1.6; }
|
|
201
|
+
.diff-line { display:flex; gap:.4rem; padding:.05rem 0; white-space:pre-wrap; word-break:break-word; }
|
|
202
|
+
.diff-marker { width:1ch; flex:0 0 auto; opacity:.7; }
|
|
203
|
+
.diff-line.diff-hunk { color:#67c8ff; background:rgba(84,183,255,.1); }
|
|
204
|
+
.diff-line.diff-add { color:#6df0bb; background:rgba(16,185,129,.16); }
|
|
205
|
+
.diff-line.diff-del { color:#fda4af; background:rgba(244,63,94,.16); }
|
|
206
|
+
.diff-line.diff-meta { color:#718ba7; }
|
|
207
|
+
.agent-timer { display:flex; align-items:center; gap:.45rem; padding:.4rem .85rem 0; }
|
|
208
|
+
.agent-timer-bar { height:.28rem; flex:0 0 auto; border-radius:999px; background:linear-gradient(90deg,#fbbf24,#f59e0b); box-shadow:0 0 8px rgba(245,158,11,.35); transition:width .25s linear; }
|
|
209
|
+
.agent-timer-label { color:#ffd479; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.56rem; }
|
|
210
|
+
.agent-tool-out { margin:0; padding:.55rem .85rem; border-top:1px solid rgba(112,168,228,.14); background:rgba(255,255,255,.035); color:#a6bfd8; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.72rem; line-height:1.65; white-space:pre-wrap; word-break:break-word; }
|
|
211
|
+
.agent-tool-output { margin:0; max-height:280px; overflow:auto; padding:.85rem .95rem; color:#e8f2ff; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.82rem; line-height:1.75; white-space:pre-wrap; word-break:break-word; }
|
|
212
|
+
.agent-tool-output .hljs { display:block; background:transparent; color:#e8f2ff; }
|
|
213
|
+
.agent-tool-output .hljs-keyword, .agent-tool-output .hljs-selector-tag, .agent-tool-output .hljs-meta .hljs-keyword { color:#c792ea; }
|
|
214
|
+
.agent-tool-output .hljs-string, .agent-tool-output .hljs-attr, .agent-tool-output .hljs-regexp, .agent-tool-output .hljs-template-string { color:#7fe0a8; }
|
|
215
|
+
.agent-tool-output .hljs-number, .agent-tool-output .hljs-literal, .agent-tool-output .hljs-symbol, .agent-tool-output .hljs-bullet, .agent-tool-output .hljs-params { color:#e2a76f; }
|
|
216
|
+
.agent-tool-output .hljs-comment, .agent-tool-output .hljs-quote { color:#6b85a3; font-style:italic; }
|
|
217
|
+
.agent-tool-output .hljs-title, .agent-tool-output .hljs-title.function_, .agent-tool-output .hljs-function .hljs-title, .agent-tool-output .hljs-section { color:#82c6ff; }
|
|
218
|
+
.agent-tool-output .hljs-built_in, .agent-tool-output .hljs-selector-class, .agent-tool-output .hljs-selector-id { color:#e5c07b; }
|
|
219
|
+
.agent-tool-output .hljs-tag, .agent-tool-output .hljs-name, .agent-tool-output .hljs-variable, .agent-tool-output .hljs-template-variable { color:#f18ac6; }
|
|
220
|
+
.agent-tool-output .hljs-meta, .agent-tool-output .hljs-doctag { color:#56b6c2; }
|
|
221
|
+
|
|
222
|
+
.agent-typing { display:inline-flex; align-items:center; gap:.4rem; color:#6e8aaa; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.66rem; }
|
|
223
|
+
.agent-typing .agent-cursor { display:inline-block; width:.5rem; height:1rem; background:#54b7ff; box-shadow:0 0 8px rgba(84,183,255,.7); animation:agent-blink 1s steps(1) infinite; }
|
|
224
|
+
@keyframes agent-blink { 50% { opacity:0; } }
|
|
225
|
+
|
|
226
|
+
.agent-error { width:calc(100% - 48px); max-width:1400px; margin:0 auto; padding:.5rem .2rem 0; color:#fda4af; font-size:.74rem; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; }
|
|
227
|
+
.agent-notice { width:calc(100% - 48px); max-width:1400px; margin:0 auto; padding:.5rem .2rem 0; color:#8fa5c0; font-size:.7rem; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-style:italic; }
|
|
228
|
+
.agent-footer { position:relative; z-index:20; flex:0 0 auto; border-top:1px solid rgba(112,168,228,.15); background:rgba(4,14,29,.62); backdrop-filter:blur(24px); -webkit-backdrop-filter:blur(24px); }
|
|
229
|
+
.agent-footer-bar { display:flex; align-items:center; gap:.9rem; flex-wrap:wrap; width:calc(100% - 48px); max-width:1400px; margin:0 auto; padding:.6rem 0 .15rem; }
|
|
230
|
+
.agent-footer-hint { margin-left:auto; color:#4d6378; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.58rem; letter-spacing:.04em; }
|
|
231
|
+
.agent-footer-inner { display:flex; align-items:flex-end; gap:.7rem; width:calc(100% - 48px); max-width:1400px; margin:0 auto; padding:.7rem 0 .95rem; }
|
|
232
|
+
.agent-input { flex:1; padding:.7rem .85rem; border:1px solid rgba(112,168,228,.24); border-radius:.6rem; outline:none; resize:none; color:#e8f2ff; background:rgba(255,255,255,.05); font:inherit; font-size:.84rem; line-height:1.55; transition:border-color .14s, box-shadow .14s, background .14s; }
|
|
233
|
+
.agent-input::placeholder { color:#5b7392; }
|
|
234
|
+
.agent-input:focus { border-color:rgba(84,183,255,.6); box-shadow:0 0 0 3px rgba(84,183,255,.14); background:rgba(255,255,255,.08); }
|
|
235
|
+
.agent-send { padding:.7rem 1.15rem; border:1px solid rgba(84,183,255,.55); border-radius:.6rem; color:#fff; background:linear-gradient(135deg, rgba(38,130,225,.75), rgba(90,67,183,.65)); box-shadow:0 8px 24px rgba(84,183,255,.28); font-size:.8rem; font-weight:800; cursor:pointer; transition:transform .15s, filter .15s, opacity .15s; }
|
|
236
|
+
.agent-send:hover:not(:disabled) { filter:brightness(1.1); transform:translateY(-1px); }
|
|
237
|
+
.agent-send:disabled { opacity:.4; cursor:not-allowed; }
|
|
238
|
+
|
|
239
|
+
/* ── Redesign additions — aurora glass, animations, todos, hero ─────── */
|
|
240
|
+
.agent-mode:active { transform:scale(.95); }
|
|
241
|
+
.agent-tool { background:linear-gradient(160deg, rgba(16,38,70,.55), rgba(8,20,42,.62)); border-color:rgba(112,168,228,.24); box-shadow:inset 0 1px rgba(255,255,255,.06), 0 18px 50px rgba(0,0,0,.28); backdrop-filter:blur(20px) saturate(140%); -webkit-backdrop-filter:blur(20px) saturate(140%); animation:agent-rise .3s cubic-bezier(.22,1,.36,1) both; transition:border-color .16s, transform .16s, box-shadow .16s; }
|
|
242
|
+
.agent-tool:hover { transform:translateY(-2px); border-color:rgba(84,183,255,.4); }
|
|
243
|
+
.agent-row-user, .agent-row-agent { animation:agent-rise .28s cubic-bezier(.22,1,.36,1) both; }
|
|
244
|
+
.agent-bubble { background:linear-gradient(160deg, rgba(16,38,70,.5), rgba(8,20,42,.56)); border-color:rgba(112,168,228,.22); box-shadow:inset 0 1px rgba(255,255,255,.05), 0 18px 50px rgba(0,0,0,.24); backdrop-filter:blur(18px) saturate(135%); -webkit-backdrop-filter:blur(18px) saturate(135%); }
|
|
245
|
+
.agent-row-user .agent-bubble { background:linear-gradient(160deg, rgba(22,70,122,.58), rgba(46,41,112,.5)); border-color:rgba(84,183,255,.42); }
|
|
246
|
+
.agent-tool-body { animation:agent-open .18s cubic-bezier(.22,1,.36,1); }
|
|
247
|
+
@keyframes agent-rise { from { opacity:0; transform:translateY(10px); filter:blur(2px); } to { opacity:1; transform:translateY(0); filter:blur(0); } }
|
|
248
|
+
@keyframes agent-open { from { opacity:0; transform:translateY(-4px); } to { opacity:1; transform:translateY(0); } }
|
|
249
|
+
|
|
250
|
+
.agent-side-section-head { cursor:pointer; user-select:none; transition:color .12s; }
|
|
251
|
+
.agent-side-section-head:hover { color:#dcecff; }
|
|
252
|
+
.agent-side-chevron { display:inline-block; font-size:.58rem; color:#45597a; transition:transform .16s; }
|
|
253
|
+
.agent-side-chevron.collapsed { transform:rotate(-90deg); }
|
|
254
|
+
|
|
255
|
+
.agent-todos-add { display:flex; gap:.4rem; }
|
|
256
|
+
.agent-todos-input { flex:1; min-width:0; padding:.42rem .55rem; border:1px solid rgba(112,168,228,.22); border-radius:.5rem; outline:none; color:#e5f4ff; background:rgba(20,46,79,.32); font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.62rem; transition:border-color .14s, box-shadow .14s; }
|
|
257
|
+
.agent-todos-input::placeholder { color:#536c8c; }
|
|
258
|
+
.agent-todos-input:focus { border-color:rgba(84,183,255,.55); box-shadow:0 0 0 2px rgba(84,183,255,.15); }
|
|
259
|
+
.agent-todos-add-btn { flex:0 0 auto; width:1.9rem; border:1px solid rgba(84,183,255,.4); border-radius:.5rem; color:#bfe9ff; background:linear-gradient(135deg, rgba(38,130,225,.5), rgba(90,67,183,.45)); font-size:1rem; line-height:1; cursor:pointer; transition:filter .14s, transform .14s; }
|
|
260
|
+
.agent-todos-add-btn:hover { filter:brightness(1.15); }
|
|
261
|
+
.agent-todos-add-btn:active { transform:scale(.94); }
|
|
262
|
+
.agent-todos-add-btn:disabled { opacity:.4; cursor:not-allowed; }
|
|
263
|
+
.agent-todos-progress { display:flex; align-items:center; gap:.45rem; }
|
|
264
|
+
.agent-todos-progress-bar { flex:0 0 auto; height:.24rem; border-radius:999px; background:linear-gradient(90deg, #3f9bff, #6cd9ff); box-shadow:0 0 8px rgba(84,183,255,.5); transition:width .25s ease; }
|
|
265
|
+
.agent-todos-progress span { color:#6e8aaa; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.56rem; }
|
|
266
|
+
.agent-todo-row { display:flex; align-items:center; gap:.45rem; padding:.38rem .5rem; border:1px solid rgba(112,168,228,.16); border-radius:.5rem; background:rgba(8,25,48,.55); box-shadow:inset 0 1px rgba(255,255,255,.04); transition:border-color .14s, background .14s; }
|
|
267
|
+
.agent-todo-row:hover { border-color:rgba(84,183,255,.4); background:rgba(84,183,255,.08); }
|
|
268
|
+
.agent-todo-check { display:grid; place-items:center; width:1.05rem; height:1.05rem; flex:0 0 auto; border:1px solid rgba(112,168,228,.4); border-radius:.3rem; color:transparent; background:rgba(255,255,255,.05); font-size:.6rem; cursor:pointer; transition:all .14s; }
|
|
269
|
+
.agent-todo-check.on { border-color:rgba(52,211,153,.55); color:#0b241b; background:#5ef0b3; box-shadow:0 0 8px rgba(94,240,179,.5); }
|
|
270
|
+
.agent-todo-text { flex:1; min-width:0; color:#cfe3fb; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.62rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
271
|
+
.agent-todo-row.done .agent-todo-text { color:#5b7392; text-decoration:line-through; }
|
|
272
|
+
.agent-todo-del { flex:0 0 auto; width:1.2rem; height:1.2rem; border:0; border-radius:.3rem; color:#6e8aaa; background:transparent; font-size:.9rem; line-height:1; cursor:pointer; transition:color .12s, background .12s; }
|
|
273
|
+
.agent-todo-del:hover { color:#fecdd3; background:rgba(244,63,94,.16); }
|
|
274
|
+
|
|
275
|
+
.agent-hero { display:flex; flex-direction:column; align-items:center; gap:.6rem; margin:5vh auto 0; max-width:640px; padding:2.5rem 2rem; text-align:center; border:1px solid rgba(112,168,228,.2); border-radius:1.2rem; background:linear-gradient(160deg, rgba(16,38,70,.5), rgba(8,20,42,.55)); box-shadow:inset 0 1px rgba(255,255,255,.06), 0 24px 70px rgba(0,0,0,.3); backdrop-filter:blur(22px) saturate(140%); -webkit-backdrop-filter:blur(22px) saturate(140%); animation:agent-rise .4s cubic-bezier(.22,1,.36,1) both; }
|
|
276
|
+
.agent-hero-orb { position:relative; display:grid; place-items:center; width:74px; height:74px; margin-bottom:.4rem; border:1px solid rgba(84,183,255,.35); border-radius:50%; background:radial-gradient(circle, rgba(57,170,255,.4), rgba(56,58,179,.16) 46%, transparent 70%); box-shadow:0 0 34px rgba(58,149,255,.35), inset 0 0 24px rgba(94,119,255,.18); animation:agent-orbit-spin 14s linear infinite; }
|
|
277
|
+
.agent-hero-orb::before { position:absolute; width:70%; height:26%; border:1px solid rgba(112,206,255,.6); border-radius:50%; content:""; transform:rotate(-28deg); }
|
|
278
|
+
.agent-hero-orb span { width:6px; height:6px; border-radius:50%; background:#5ef0b3; box-shadow:0 0 12px #5ef0b3; z-index:1; }
|
|
279
|
+
@keyframes agent-orbit-spin { to { transform:rotate(360deg); } }
|
|
280
|
+
.agent-hero h2 { margin:.4rem 0 0; color:#f1f8ff; font-size:1.5rem; letter-spacing:-.03em; }
|
|
281
|
+
.agent-hero h2 em { color:#6fcaff; font-style:normal; text-shadow:0 0 24px rgba(80,183,255,.4); }
|
|
282
|
+
.agent-hero p { margin:0; color:#8fa5c0; font-size:.78rem; line-height:1.7; }
|
|
283
|
+
.agent-hero-chips { display:flex; flex-wrap:wrap; justify-content:center; gap:.5rem; margin-top:.9rem; }
|
|
284
|
+
.agent-hero-chip { padding:.5rem .8rem; border:1px solid rgba(112,168,228,.28); border-radius:999px; color:#a8d8ff; background:rgba(84,183,255,.08); font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.64rem; cursor:pointer; transition:border-color .14s, background .14s, transform .14s; }
|
|
285
|
+
.agent-hero-chip:hover { border-color:rgba(84,183,255,.6); background:rgba(84,183,255,.16); transform:translateY(-2px); }
|
|
286
|
+
.agent-hero .agent-hint { margin-top:.6rem; }
|
|
287
|
+
|
|
288
|
+
.agent-suggest { position:fixed; z-index:70; left:50%; bottom:4.4rem; transform:translateX(-50%); display:flex; flex-direction:column; gap:.55rem; width:min(560px, calc(100vw - 32px)); padding:.95rem 1.1rem; border:1px solid rgba(255,196,107,.38); border-radius:.9rem; background:linear-gradient(160deg, rgba(48,34,10,.92), rgba(26,18,40,.9)); box-shadow:inset 0 1px rgba(255,255,255,.06), 0 24px 70px rgba(0,0,0,.5), 0 0 30px rgba(245,158,11,.14); backdrop-filter:blur(22px) saturate(140%); -webkit-backdrop-filter:blur(22px) saturate(140%); animation:agent-rise .25s cubic-bezier(.22,1,.36,1) both; }
|
|
289
|
+
.agent-suggest-close { position:absolute; top:.55rem; right:.55rem; width:1.4rem; height:1.4rem; display:grid; place-items:center; border:1px solid rgba(255,196,107,.28); border-radius:.4rem; color:#b98a3a; background:rgba(0,0,0,.25); font-size:.7rem; line-height:1; cursor:pointer; transition:color .14s, border-color .14s, background .14s; }
|
|
290
|
+
.agent-suggest-close:hover { color:#ffe4b3; border-color:rgba(255,196,107,.6); background:rgba(245,158,11,.2); }
|
|
291
|
+
.agent-suggest-head { display:flex; align-items:baseline; gap:.55rem; flex-wrap:wrap; padding-right:1.4rem; }
|
|
292
|
+
.agent-suggest-title { color:#ffd479; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.62rem; font-weight:800; letter-spacing:.14em; text-transform:uppercase; text-shadow:0 0 14px rgba(245,158,11,.35); }
|
|
293
|
+
.agent-suggest-sub { color:#8a7a58; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.58rem; }
|
|
294
|
+
.agent-suggest-chips { display:flex; flex-wrap:wrap; gap:.45rem; }
|
|
295
|
+
.agent-suggest-chips .agent-hero-chip { border-color:rgba(255,196,107,.38); color:#ffe3a3; background:rgba(245,158,11,.12); }
|
|
296
|
+
.agent-suggest-chips .agent-hero-chip:hover { border-color:rgba(255,196,107,.68); background:rgba(245,158,11,.22); transform:translateY(-2px); }
|
|
297
|
+
|
|
298
|
+
.agent-enhance { position:fixed; z-index:70; left:50%; bottom:4.4rem; transform:translateX(-50%); display:flex; flex-direction:column; gap:.6rem; width:min(560px, calc(100vw - 32px)); max-height:70vh; overflow:auto; padding:.95rem 1.1rem; border:1px solid rgba(99,189,255,.4); border-radius:.9rem; background:linear-gradient(160deg, rgba(14,42,78,.94), rgba(26,18,40,.92)); box-shadow:inset 0 1px rgba(255,255,255,.06), 0 24px 70px rgba(0,0,0,.5), 0 0 30px rgba(84,183,255,.16); backdrop-filter:blur(22px) saturate(140%); -webkit-backdrop-filter:blur(22px) saturate(140%); animation:agent-rise .25s cubic-bezier(.22,1,.36,1) both; }
|
|
299
|
+
.agent-enhance-head { display:flex; align-items:baseline; gap:.55rem; flex-wrap:wrap; padding-right:1.4rem; }
|
|
300
|
+
.agent-enhance-title { color:#8ed6ff; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.62rem; font-weight:800; letter-spacing:.14em; text-transform:uppercase; text-shadow:0 0 14px rgba(84,183,255,.4); }
|
|
301
|
+
.agent-enhance-sub { color:#6d8fb2; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.58rem; }
|
|
302
|
+
.agent-enhance-input { width:100%; padding:.6rem .75rem; border:1px solid rgba(112,168,228,.26); border-radius:.6rem; outline:none; resize:vertical; color:#e8f2ff; background:rgba(255,255,255,.06); font:inherit; font-size:.8rem; line-height:1.55; transition:border-color .14s, box-shadow .14s; }
|
|
303
|
+
.agent-enhance-input:focus { border-color:rgba(99,189,255,.6); box-shadow:0 0 0 3px rgba(84,183,255,.14); }
|
|
304
|
+
.agent-enhance-label { color:#5f7b9c; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.56rem; letter-spacing:.13em; text-transform:uppercase; }
|
|
305
|
+
.agent-enhance-bubble { padding:.7rem .85rem; border:1px solid rgba(112,168,228,.22); border-radius:.7rem; color:#dcecff; background:linear-gradient(160deg, rgba(16,38,70,.5), rgba(8,20,42,.56)); font-size:.8rem; line-height:1.7; white-space:pre-wrap; overflow-wrap:anywhere; }
|
|
306
|
+
.agent-enhance-features { display:flex; flex-direction:column; gap:.5rem; }
|
|
307
|
+
.agent-enhance-chips { display:flex; flex-wrap:wrap; gap:.45rem; }
|
|
308
|
+
.agent-enhance-chip { padding:.42rem .7rem; border:1px solid rgba(112,168,228,.3); border-radius:999px; color:#a8d8ff; background:rgba(84,183,255,.08); font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.62rem; cursor:pointer; transition:border-color .14s, background .14s, transform .14s; }
|
|
309
|
+
.agent-enhance-chip:hover { border-color:rgba(99,189,255,.6); background:rgba(84,183,255,.16); transform:translateY(-1px); }
|
|
310
|
+
.agent-enhance-chip.on { border-color:rgba(94,240,179,.55); color:#7ee8bd; background:rgba(16,185,129,.16); }
|
|
311
|
+
.agent-enhance-actions { display:flex; gap:.5rem; }
|
|
312
|
+
.agent-enhance-btn { padding:.5rem .95rem; border:1px solid rgba(99,189,255,.55); border-radius:.55rem; color:#eaf7ff; background:linear-gradient(135deg, rgba(38,130,225,.7), rgba(90,67,183,.6)); box-shadow:0 6px 18px rgba(84,183,255,.24); font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.68rem; font-weight:800; cursor:pointer; transition:filter .15s, transform .15s, opacity .15s; }
|
|
313
|
+
.agent-enhance-btn:hover:not(:disabled) { filter:brightness(1.1); transform:translateY(-1px); }
|
|
314
|
+
.agent-enhance-btn:disabled { opacity:.45; cursor:not-allowed; }
|
|
315
|
+
.agent-enhance-btn.ghost { border-color:rgba(112,168,228,.3); color:#9fb3d0; background:rgba(84,183,255,.08); box-shadow:none; }
|
|
316
|
+
.agent-enhance-error { color:#fda4af; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.66rem; }
|
|
317
|
+
.agent-enhance-opt { display:flex; align-items:center; gap:.5rem; padding-top:.5rem; border-top:1px dashed rgba(112,168,228,.16); cursor:pointer; user-select:none; }
|
|
318
|
+
.agent-enhance-check { display:grid; place-items:center; width:1rem; height:1rem; flex:0 0 auto; border:1px solid rgba(112,168,228,.4); border-radius:.3rem; color:#0b241b; background:rgba(255,255,255,.05); font-size:.62rem; line-height:1; transition:border-color .14s, background .14s; }
|
|
319
|
+
.agent-enhance-check.on { border-color:rgba(94,240,179,.6); background:#5ef0b3; box-shadow:0 0 8px rgba(94,240,179,.45); }
|
|
320
|
+
.agent-enhance-opt-label { color:#7d94b2; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.6rem; }
|
|
321
|
+
.agent-enhance-toggle { display:inline-flex; align-items:center; gap:.42rem; padding:.4rem .7rem; border:1px solid rgba(112,168,228,.22); border-radius:.6rem; color:#9fd4ff; background:rgba(84,183,255,.08); font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.6rem; font-weight:700; letter-spacing:.1em; text-transform:uppercase; cursor:pointer; transition:border-color .14s, color .14s, background .14s, box-shadow .14s, transform .14s; }
|
|
322
|
+
.agent-enhance-toggle:hover:not(:disabled) { color:#dcecff; border-color:rgba(99,189,255,.5); transform:translateY(-1px); }
|
|
323
|
+
.agent-enhance-toggle.on { color:#9fe8ff; border-color:rgba(99,189,255,.6); background:linear-gradient(135deg, rgba(40,137,235,.3), rgba(90,67,183,.22)); box-shadow:0 0 14px rgba(84,183,255,.25); }
|
|
324
|
+
.agent-enhance-toggle:disabled { opacity:.4; cursor:not-allowed; }
|
|
325
|
+
|
|
326
|
+
.agent-settings-btn { display:grid; place-items:center; width:2.1rem; height:2.1rem; padding:0; border:1px solid rgba(112,168,228,.24); border-radius:.6rem; color:#8fb8e4; background:rgba(84,183,255,.08); font-size:.9rem; line-height:1; cursor:pointer; transition:border-color .15s, color .15s, background .15s, transform .15s; }
|
|
327
|
+
.agent-settings-btn:hover { border-color:rgba(84,183,255,.55); color:#bfe9ff; background:rgba(84,183,255,.16); transform:translateY(-1px); }
|
|
328
|
+
.agent-settings-btn.on { color:#9fe8ff; border-color:rgba(99,189,255,.6); background:linear-gradient(135deg, rgba(40,137,235,.3), rgba(90,67,183,.22)); box-shadow:0 0 14px rgba(84,183,255,.25); }
|
|
329
|
+
|
|
330
|
+
.agent-settings { position:fixed; z-index:65; top:0; right:0; bottom:0; width:min(340px, 92vw); display:flex; flex-direction:column; border-left:1px solid rgba(112,168,228,.2); background:linear-gradient(180deg, rgba(10,28,55,.97), rgba(6,15,34,.98)); box-shadow:-18px 0 60px rgba(0,0,0,.5); backdrop-filter:blur(22px) saturate(140%); -webkit-backdrop-filter:blur(22px) saturate(140%); animation:agent-fade .18s ease both; }
|
|
331
|
+
.agent-settings-head { display:flex; align-items:center; justify-content:space-between; padding:1rem 1.1rem; border-bottom:1px solid rgba(112,168,228,.14); }
|
|
332
|
+
.agent-settings-title { color:#8ed6ff; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.66rem; font-weight:800; letter-spacing:.14em; text-transform:uppercase; text-shadow:0 0 14px rgba(84,183,255,.4); }
|
|
333
|
+
.agent-settings-body { flex:1 1 auto; min-height:0; overflow-y:auto; padding:1rem 1.1rem 1.5rem; display:flex; flex-direction:column; gap:1.2rem; }
|
|
334
|
+
.agent-settings-section { display:flex; flex-direction:column; gap:.6rem; }
|
|
335
|
+
.agent-settings-row { display:flex; align-items:center; justify-content:space-between; gap:.5rem; padding:.55rem .7rem; border:1px solid rgba(112,168,228,.16); border-radius:.6rem; background:rgba(8,25,48,.55); cursor:pointer; user-select:none; transition:border-color .14s, background .14s; }
|
|
336
|
+
.agent-settings-row:hover { border-color:rgba(84,183,255,.4); background:rgba(84,183,255,.08); }
|
|
337
|
+
.agent-settings-row-label { color:#cfe3fb; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.62rem; }
|
|
338
|
+
.agent-settings-field { display:flex; flex-direction:column; gap:.3rem; }
|
|
339
|
+
.agent-settings-field span { color:#5f7b9c; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.56rem; letter-spacing:.13em; text-transform:uppercase; }
|
|
340
|
+
.agent-settings-field .agent-select { width:100%; max-width:none; }
|
|
341
|
+
.agent-default-row { display:flex; align-items:center; gap:.5rem; margin-top:.2rem; }
|
|
342
|
+
.agent-default-btn { padding:.42rem .7rem; border:1px solid rgba(84,183,255,.34); border-radius:.5rem; color:#bfe9ff; background:linear-gradient(135deg, rgba(38,130,225,.28), rgba(90,67,183,.18)); font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.6rem; font-weight:800; letter-spacing:.06em; cursor:pointer; transition:filter .14s, border-color .14s, background .14s, opacity .14s; }
|
|
343
|
+
.agent-default-btn:hover:not(:disabled) { filter:brightness(1.15); border-color:rgba(84,183,255,.55); }
|
|
344
|
+
.agent-default-btn:disabled { opacity:.45; cursor:default; }
|
|
345
|
+
.agent-default-btn.is-default { color:#6df0bb; border-color:rgba(52,211,153,.32); background:rgba(16,185,129,.12); }
|
|
346
|
+
.agent-default-hint { color:#5f7b9c; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.56rem; }
|
|
347
|
+
|
|
348
|
+
.agent-thinking { border:1px dashed rgba(112,168,228,.28); border-radius:.85rem; background:rgba(8,22,45,.4); overflow:hidden; animation:agent-rise .3s cubic-bezier(.22,1,.36,1) both; }
|
|
349
|
+
.agent-thinking-head { display:flex; align-items:center; gap:.5rem; padding:.55rem .85rem; color:#8fa8c8; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; cursor:pointer; user-select:none; transition:background .14s; flex-wrap:wrap; }
|
|
350
|
+
.agent-thinking-head:hover { background:rgba(84,183,255,.07); }
|
|
351
|
+
.agent-thinking-dot { width:.42rem; height:.42rem; flex:0 0 auto; border-radius:50%; background:#54b7ff; box-shadow:0 0 8px rgba(84,183,255,.6); }
|
|
352
|
+
.agent-thinking-name { color:#9fd4ff; font-size:.62rem; font-weight:800; letter-spacing:.12em; text-transform:uppercase; }
|
|
353
|
+
.agent-thinking-summary { flex:0 1 auto; min-width:0; color:#5f7b9c; font-size:.6rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
354
|
+
.agent-thinking-current { display:inline-flex; align-items:center; gap:.3rem; flex:1 1 auto; min-width:0; padding:.14rem .42rem; border-radius:.4rem; background:rgba(84,183,255,.08); border:1px solid rgba(112,168,228,.14); font-size:.6rem; overflow:hidden; }
|
|
355
|
+
.agent-thinking-current-text { flex:1; min-width:0; color:#cfe3fb; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
356
|
+
.agent-thinking-current .agent-tool-badge { padding:.1rem .32rem; font-size:.48rem; }
|
|
357
|
+
.agent-thinking-live { color:#8ed6ff; font-size:.52rem; font-weight:800; animation:agent-pulse 1s ease-in-out infinite; }
|
|
358
|
+
.agent-thinking-more { flex:0 0 auto; padding:.14rem .46rem; border-radius:999px; color:#ffd479; background:rgba(245,158,11,.14); border:1px solid rgba(255,196,107,.3); font-size:.56rem; font-weight:800; }
|
|
359
|
+
.agent-thinking-preview { display:flex; align-items:center; gap:.4rem; padding:.42rem .75rem; border-top:1px dashed rgba(112,168,228,.16); background:rgba(8,25,48,.35); cursor:pointer; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.62rem; }
|
|
360
|
+
.agent-thinking-preview-dot { width:.34rem; height:.34rem; flex:0 0 auto; border-radius:50%; background:#54b7ff; box-shadow:0 0 6px rgba(84,183,255,.6); animation:agent-pulse 1s ease-in-out infinite; }
|
|
361
|
+
.agent-thinking-preview-summary { flex:1; min-width:0; color:#cfe3fb; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
362
|
+
.agent-thinking-preview-status { flex:0 0 auto; padding:.1rem .36rem; border-radius:.3rem; font-size:.52rem; font-weight:800; text-transform:uppercase; }
|
|
363
|
+
.agent-thinking-preview-status.running { color:#8ed6ff; background:rgba(84,183,255,.12); border:1px solid rgba(84,183,255,.22); }
|
|
364
|
+
.agent-thinking-preview-status.ok { color:#6df0bb; background:rgba(16,185,129,.1); border:1px solid rgba(52,211,153,.18); }
|
|
365
|
+
.agent-thinking-preview-status.err { color:#fda4af; background:rgba(244,63,94,.1); border:1px solid rgba(244,63,94,.18); }
|
|
366
|
+
.agent-thinking-body { display:flex; flex-direction:column; gap:.5rem; padding:.6rem .85rem .85rem; border-top:1px dashed rgba(112,168,228,.16); }
|
|
367
|
+
.agent-thinking-body .agent-tool { box-shadow:none; }
|
|
368
|
+
.agent-thinking.collapsed .agent-thinking-head { background:rgba(8,25,48,.2); }
|
|
369
|
+
|
|
370
|
+
.agent-team { display:flex; flex-direction:column; gap:.6rem; padding:.85rem 1rem; border:1px solid rgba(84,183,255,.32); border-radius:.85rem; background:linear-gradient(160deg, rgba(16,38,70,.55), rgba(26,16,64,.42)); box-shadow:inset 0 1px rgba(255,255,255,.05), 0 16px 44px rgba(0,0,0,.24); backdrop-filter:blur(16px); -webkit-backdrop-filter:blur(16px); animation:agent-rise .3s cubic-bezier(.22,1,.36,1) both; }
|
|
371
|
+
.agent-team-head { display:flex; align-items:baseline; gap:.55rem; flex-wrap:wrap; }
|
|
372
|
+
.agent-team-title { color:#8ed6ff; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.62rem; font-weight:800; letter-spacing:.14em; text-transform:uppercase; text-shadow:0 0 14px rgba(84,183,255,.4); }
|
|
373
|
+
.agent-team-stage { color:#6d8fb2; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.6rem; }
|
|
374
|
+
.agent-team-grid { display:flex; flex-wrap:wrap; gap:.5rem; }
|
|
375
|
+
.agent-team-member { display:inline-flex; align-items:center; gap:.45rem; padding:.42rem .68rem; border:1px solid rgba(112,168,228,.18); border-radius:999px; background:rgba(8,25,48,.6); color:#9fb3d0; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.6rem; font-weight:600; transition:border-color .14s, color .14s; }
|
|
376
|
+
.agent-team-dot { width:.4rem; height:.4rem; flex:0 0 auto; border-radius:50%; background:#54b7ff; box-shadow:0 0 8px rgba(84,183,255,.7); animation:agent-pulse 1s ease-in-out infinite; }
|
|
377
|
+
.agent-team-member.done { color:#7ee8bd; border-color:rgba(52,211,153,.3); }
|
|
378
|
+
.agent-team-member.done .agent-team-dot { background:#5ef0b3; box-shadow:0 0 8px rgba(94,240,179,.8); animation:none; }
|
|
379
|
+
.agent-team-member.pending { opacity:.55; }
|
|
380
|
+
.agent-team-member.pending .agent-team-dot { animation:none; opacity:.4; }
|
|
381
|
+
.agent-team-spinner { width:.5rem; height:.5rem; flex:0 0 auto; border:2px solid rgba(84,183,255,.25); border-top-color:#54b7ff; border-radius:50%; animation:agent-spin .8s linear infinite; }
|
|
382
|
+
@keyframes agent-spin { to { transform:rotate(360deg); } }
|
|
383
|
+
.agent-team-toggle { display:inline-flex; align-items:center; gap:.42rem; padding:.4rem .7rem; border:1px solid rgba(112,168,228,.22); border-radius:.6rem; color:#7d94b2; background:rgba(20,46,79,.28); font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.6rem; font-weight:700; letter-spacing:.1em; text-transform:uppercase; cursor:pointer; transition:border-color .14s, color .14s, background .14s, box-shadow .14s, transform .14s; }
|
|
384
|
+
.agent-team-toggle:hover { color:#dcecff; border-color:rgba(84,183,255,.5); transform:translateY(-1px); }
|
|
385
|
+
.agent-team-toggle.on { color:#9fe8ff; border-color:rgba(84,183,255,.55); background:linear-gradient(135deg, rgba(40,137,235,.3), rgba(90,67,183,.22)); box-shadow:0 0 14px rgba(84,183,255,.25); }
|
|
386
|
+
.agent-team-toggle-dot { width:.4rem; height:.4rem; border-radius:50%; background:#4b647f; }
|
|
387
|
+
.agent-team-toggle.on .agent-team-toggle-dot { background:#5ef0b3; box-shadow:0 0 8px rgba(94,240,179,.9); }
|
|
388
|
+
|
|
389
|
+
.agent-typing { display:inline-flex; align-items:center; gap:.55rem; padding:.4rem .7rem; border:1px solid rgba(112,168,228,.16); border-radius:999px; color:#6e8aaa; background:rgba(8,25,48,.5); font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.62rem; }
|
|
390
|
+
.agent-typing-label { letter-spacing:.08em; text-transform:uppercase; font-size:.56rem; }
|
|
391
|
+
.agent-dots { display:inline-flex; gap:.24rem; }
|
|
392
|
+
.agent-dots i { width:.32rem; height:.32rem; border-radius:50%; background:#54b7ff; box-shadow:0 0 8px rgba(84,183,255,.7); animation:agent-bounce 1.2s ease-in-out infinite; }
|
|
393
|
+
.agent-dots i:nth-child(2) { animation-delay:.16s; }
|
|
394
|
+
.agent-dots i:nth-child(3) { animation-delay:.32s; }
|
|
395
|
+
@keyframes agent-bounce { 0%,60%,100% { transform:translateY(0); opacity:.5; } 30% { transform:translateY(-4px); opacity:1; } }
|
|
396
|
+
|
|
397
|
+
.agent-toast { position:fixed; top:4.5rem; right:1.5rem; z-index:60; padding:.6rem .9rem; border:1px solid rgba(84,183,255,.35); border-radius:.6rem; color:#dcecff; background:linear-gradient(160deg, rgba(16,38,70,.85), rgba(8,20,42,.9)); box-shadow:0 14px 40px rgba(0,0,0,.4); backdrop-filter:blur(20px) saturate(140%); font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.68rem; animation:agent-open .22s cubic-bezier(.22,1,.36,1); }
|
|
398
|
+
|
|
399
|
+
/* ── Alert toast (top-right) — success / error / info states ── */
|
|
400
|
+
.agent-alert { position:fixed; top:4.2rem; right:1.25rem; z-index:200; display:none; align-items:flex-start; gap:.6rem; max-width:340px; padding:.65rem .8rem; border:1px solid rgba(84,183,255,.35); border-radius:.7rem; color:#dcecff; background:linear-gradient(160deg, rgba(16,38,70,.94), rgba(8,20,42,.97)); box-shadow:0 14px 44px rgba(0,0,0,.5), inset 0 1px rgba(255,255,255,.06); backdrop-filter:blur(20px) saturate(140%); -webkit-backdrop-filter:blur(20px) saturate(140%); font-family:ui-monospace, SFMono-Regular, Consolas, monospace; }
|
|
401
|
+
.agent-alert.show { display:flex; animation:agent-rise .24s cubic-bezier(.22,1,.36,1); }
|
|
402
|
+
.agent-alert-mark { flex:0 0 auto; display:grid; place-items:center; width:1.5rem; height:1.5rem; border-radius:.45rem; color:#6df0bb; font-size:.85rem; font-weight:800; border:1px solid rgba(52,211,153,.45); background:linear-gradient(135deg, rgba(16,185,129,.3), rgba(6,95,70,.22)); box-shadow:0 0 12px rgba(52,211,153,.25); }
|
|
403
|
+
.agent-alert-body { flex:1; min-width:0; display:flex; flex-direction:column; gap:.15rem; }
|
|
404
|
+
.agent-alert-title { color:#7ee8bd; font-size:.62rem; font-weight:800; letter-spacing:.1em; text-transform:uppercase; }
|
|
405
|
+
.agent-alert-msg { color:#cfe3fb; font-size:.64rem; line-height:1.5; word-break:break-word; }
|
|
406
|
+
.agent-alert-close { flex:0 0 auto; display:grid; place-items:center; width:1.2rem; height:1.2rem; border:0; border-radius:.35rem; color:#7d94b2; background:transparent; font-size:.9rem; line-height:1; cursor:pointer; transition:color .12s, background .12s; }
|
|
407
|
+
.agent-alert-close:hover { color:#fecdd3; background:rgba(244,63,94,.16); }
|
|
408
|
+
.agent-alert.hide { display:none; }
|
|
409
|
+
/* Error state */
|
|
410
|
+
.agent-alert.is-error { border-color:rgba(251,113,133,.5); }
|
|
411
|
+
.agent-alert.is-error .agent-alert-mark { color:#fda4af; border-color:rgba(251,113,133,.5); background:linear-gradient(135deg, rgba(244,63,94,.3), rgba(159,18,57,.22)); box-shadow:0 0 12px rgba(244,63,94,.28); }
|
|
412
|
+
.agent-alert.is-error .agent-alert-title { color:#fda4af; }
|
|
413
|
+
.agent-alert.is-error .agent-alert-msg { color:#fecdd3; }
|
|
414
|
+
/* Info state */
|
|
415
|
+
.agent-alert.is-info { border-color:rgba(84,183,255,.5); }
|
|
416
|
+
.agent-alert.is-info .agent-alert-mark { color:#8ed6ff; border-color:rgba(84,183,255,.5); background:linear-gradient(135deg, rgba(38,130,225,.3), rgba(90,67,183,.24)); box-shadow:0 0 12px rgba(84,183,255,.28); }
|
|
417
|
+
.agent-alert.is-info .agent-alert-title { color:#8ed6ff; }
|
|
418
|
+
.agent-alert.is-info .agent-alert-msg { color:#cfe3fb; }
|
|
419
|
+
.agent-scroll-down { position:fixed; right:1.6rem; bottom:6.5rem; z-index:55; display:grid; place-items:center; width:2.5rem; height:2.5rem; border:1px solid rgba(84,183,255,.4); border-radius:50%; color:#bfe9ff; background:linear-gradient(160deg, rgba(16,38,70,.85), rgba(8,20,42,.9)); box-shadow:0 10px 30px rgba(0,0,0,.35), 0 0 16px rgba(84,183,255,.2); backdrop-filter:blur(18px); font-size:1rem; cursor:pointer; transition:transform .14s, filter .14s; animation:agent-rise .2s cubic-bezier(.22,1,.36,1) both; }
|
|
420
|
+
.agent-scroll-down:hover { filter:brightness(1.15); transform:translateY(-2px); }
|
|
421
|
+
.agent-scroll-down:active { transform:scale(.92); }
|
|
422
|
+
|
|
423
|
+
.agent-explorer { position:fixed; inset:0; z-index:80; display:flex; align-items:center; justify-content:center; padding:1rem; background:rgba(2,8,20,.62); backdrop-filter:blur(3px); -webkit-backdrop-filter:blur(3px); animation:agent-fade .18s ease both; }
|
|
424
|
+
.agent-explorer-card { display:flex; flex-direction:column; width:min(600px, 100%); max-height:78vh; border:1px solid rgba(99,189,255,.28); border-radius:.9rem; background:linear-gradient(160deg, rgba(12,34,64,.96), rgba(6,16,36,.98)); box-shadow:inset 0 1px rgba(255,255,255,.06), 0 30px 90px rgba(0,0,0,.6), 0 0 40px rgba(84,183,255,.12); overflow:hidden; animation:agent-rise .22s cubic-bezier(.22,1,.36,1) both; }
|
|
425
|
+
.agent-explorer-head { display:flex; align-items:center; justify-content:space-between; padding:.85rem 1rem; border-bottom:1px solid rgba(112,168,228,.16); }
|
|
426
|
+
.agent-explorer-title { color:#8ed6ff; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.68rem; font-weight:800; letter-spacing:.14em; text-transform:uppercase; text-shadow:0 0 14px rgba(84,183,255,.4); }
|
|
427
|
+
.agent-explorer-note { margin:0; padding:.5rem 1rem 0; color:#5f7b9c; font-size:.6rem; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; }
|
|
428
|
+
.agent-explorer-bar { display:flex; align-items:center; gap:.5rem; padding:.6rem .75rem; border-bottom:1px solid rgba(112,168,228,.1); }
|
|
429
|
+
.agent-explorer-up { flex:0 0 auto; width:1.9rem; height:1.9rem; padding:0; border:1px solid rgba(112,168,228,.3); border-radius:.45rem; color:#9fd4ff; background:rgba(84,183,255,.1); font-size:.85rem; cursor:pointer; transition:border-color .12s, background .12s, color .12s, opacity .12s; }
|
|
430
|
+
.agent-explorer-up:hover:not(:disabled) { border-color:rgba(84,183,255,.65); color:#fff; background:rgba(84,183,255,.2); }
|
|
431
|
+
.agent-explorer-up:disabled { opacity:.35; cursor:default; }
|
|
432
|
+
.agent-explorer-crumbs { flex:1 1 auto; min-width:0; display:flex; align-items:center; flex-wrap:wrap; gap:.1rem; overflow:hidden; }
|
|
433
|
+
.agent-explorer-crumb { display:inline-flex; align-items:center; white-space:nowrap; color:#45597a; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.62rem; }
|
|
434
|
+
.agent-explorer-sep { margin:0 .1rem; opacity:.6; }
|
|
435
|
+
.agent-explorer-crumb-btn { padding:.16rem .34rem; border:1px solid transparent; border-radius:.35rem; color:#9fc3ea; background:transparent; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.62rem; cursor:pointer; transition:color .12s, background .12s, border-color .12s; }
|
|
436
|
+
.agent-explorer-crumb-btn:hover { color:#dcecff; background:rgba(84,183,255,.1); }
|
|
437
|
+
.agent-explorer-crumb-btn.on { color:#63bdff; background:rgba(40,137,235,.16); border-color:rgba(84,183,255,.3); }
|
|
438
|
+
.agent-explorer-roots { flex:0 0 auto; display:flex; gap:.3rem; }
|
|
439
|
+
.agent-explorer-root { max-width:180px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; padding:.18rem .5rem; border:1px solid rgba(245,158,11,.32); border-radius:.4rem; color:#ffd479; background:rgba(245,158,11,.1); font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.56rem; cursor:pointer; transition:filter .12s, background .12s; }
|
|
440
|
+
.agent-explorer-root:hover { filter:brightness(1.15); background:rgba(245,158,11,.18); }
|
|
441
|
+
.agent-explorer-body { flex:1 1 auto; min-height:0; overflow-y:auto; padding:.4rem .5rem; }
|
|
442
|
+
.agent-explorer-list { display:flex; flex-direction:column; gap:.15rem; }
|
|
443
|
+
.agent-explorer-row { display:flex; align-items:center; gap:.5rem; padding:.28rem .45rem; border-radius:.5rem; transition:background .12s; }
|
|
444
|
+
.agent-explorer-row:hover { background:rgba(84,183,255,.07); }
|
|
445
|
+
.agent-explorer-name { flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; padding:.22rem .4rem; border:1px solid transparent; border-radius:.4rem; color:#cfe3fb; background:transparent; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.72rem; text-align:left; cursor:pointer; transition:color .12s, background .12s, border-color .12s; }
|
|
446
|
+
.agent-explorer-name:hover { color:#fff; background:rgba(40,137,235,.14); border-color:rgba(84,183,255,.25); }
|
|
447
|
+
.agent-explorer-tag { flex:0 0 auto; padding:.1rem .42rem; border-radius:999px; color:#6df0bb; border:1px solid rgba(52,211,153,.32); background:rgba(16,185,129,.12); font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.52rem; font-weight:700; letter-spacing:.06em; text-transform:uppercase; }
|
|
448
|
+
.agent-explorer-use { flex:0 0 auto; padding:.24rem .6rem; border:1px solid rgba(84,183,255,.4); border-radius:.4rem; color:#9fd4ff; background:rgba(84,183,255,.12); font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.56rem; font-weight:700; cursor:pointer; transition:border-color .12s, background .12s, color .12s, transform .12s; }
|
|
449
|
+
.agent-explorer-use:hover { border-color:rgba(84,183,255,.75); color:#fff; background:rgba(40,137,235,.28); transform:translateY(-1px); }
|
|
450
|
+
.agent-explorer-empty, .agent-explorer-error { margin:0; padding:1rem .6rem; color:#45597a; font-size:.64rem; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; }
|
|
451
|
+
.agent-explorer-error { color:#fda4af; }
|
|
452
|
+
.agent-explorer-foot { display:flex; align-items:center; gap:.6rem; justify-content:space-between; padding:.7rem .9rem; border-top:1px solid rgba(112,168,228,.14); }
|
|
453
|
+
.agent-explorer-current { flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:#6e8aaa; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.6rem; }
|
|
454
|
+
.agent-explorer-actions { flex:0 0 auto; display:flex; gap:.4rem; }
|
|
455
|
+
.agent-explorer-btn { padding:.4rem .8rem; border:1px solid rgba(84,183,255,.4); border-radius:.5rem; color:#9fd4ff; background:linear-gradient(135deg, rgba(40,137,235,.3), rgba(90,67,183,.22)); font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.62rem; font-weight:700; cursor:pointer; transition:filter .14s, transform .14s, opacity .14s; }
|
|
456
|
+
.agent-explorer-btn:hover:not(:disabled) { filter:brightness(1.18); transform:translateY(-1px); }
|
|
457
|
+
.agent-explorer-btn:disabled { opacity:.4; cursor:default; }
|
|
458
|
+
.agent-explorer-btn.ghost { background:transparent; border-color:rgba(112,168,228,.25); color:#8fb8e4; }
|
|
459
|
+
.agent-explorer-browse { width:100%; margin-top:.45rem; padding:.4rem .6rem; border:1px dashed rgba(112,168,228,.3); border-radius:.5rem; color:#8fb8e4; background:rgba(84,183,255,.06); font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.6rem; font-weight:700; cursor:pointer; transition:border-color .12s, background .12s, color .12s; }
|
|
460
|
+
.agent-explorer-browse:hover { border-color:rgba(84,183,255,.6); color:#bfe9ff; background:rgba(84,183,255,.12); }
|
|
461
|
+
.agent-workspace-btn { display:grid; place-items:center; padding:.4rem .55rem; border:1px solid rgba(112,168,228,.24); border-radius:.55rem; color:#8fb8e4; background:rgba(84,183,255,.08); font-size:.82rem; line-height:1; cursor:pointer; transition:border-color .14s, color .14s, background .14s, transform .14s; }
|
|
462
|
+
.agent-workspace-btn:hover { border-color:rgba(84,183,255,.55); color:#bfe9ff; background:rgba(84,183,255,.16); transform:translateY(-1px); }
|
|
463
|
+
.agent-workspace-btn.on { color:#9fe8ff; border-color:rgba(99,189,255,.6); background:rgba(40,137,235,.2); }
|
|
464
|
+
|
|
465
|
+
.agent-tabs { display:inline-flex; gap:.2rem; padding:.18rem; border:1px solid rgba(112,168,228,.18); border-radius:.6rem; background:rgba(8,25,48,.5); }
|
|
466
|
+
.agent-tab { padding:.32rem .7rem; border:1px solid transparent; border-radius:.45rem; color:#7d94b2; background:transparent; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.6rem; font-weight:700; letter-spacing:.08em; cursor:pointer; transition:color .14s, background .14s, border-color .14s; }
|
|
467
|
+
.agent-tab:hover { color:#dcecff; }
|
|
468
|
+
.agent-tab.on { color:#bfe9ff; background:linear-gradient(135deg, rgba(38,130,225,.4), rgba(90,67,183,.28)); border-color:rgba(84,183,255,.45); box-shadow:0 0 12px rgba(84,183,255,.22); }
|
|
469
|
+
|
|
470
|
+
.agent-output { display:flex; flex-direction:column; gap:.7rem; }
|
|
471
|
+
.agent-output-head { display:flex; align-items:center; gap:.6rem; padding:.5rem 0; border-bottom:1px solid rgba(112,168,228,.12); }
|
|
472
|
+
.agent-output-title { color:#63bdff; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.66rem; font-weight:800; letter-spacing:.12em; text-transform:uppercase; }
|
|
473
|
+
.agent-output-count { color:#5f7b9c; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.58rem; }
|
|
474
|
+
.agent-output-clear { margin-left:auto; padding:.3rem .6rem; border:1px solid rgba(112,168,228,.28); border-radius:.4rem; color:#8fb8e4; background:rgba(84,183,255,.08); font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.58rem; cursor:pointer; transition:border-color .12s, background .12s; }
|
|
475
|
+
.agent-output-clear:hover { border-color:rgba(84,183,255,.5); background:rgba(84,183,255,.14); }
|
|
476
|
+
.agent-output-empty { color:#45597a; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.64rem; text-align:center; padding:2rem 1rem; }
|
|
477
|
+
.agent-output-list { display:flex; flex-direction:column; gap:.5rem; }
|
|
478
|
+
.agent-output-row { border:1px solid rgba(112,168,228,.2); border-radius:.7rem; background:rgba(8,25,48,.55); overflow:hidden; }
|
|
479
|
+
.agent-output-row.running { border-color:rgba(84,183,255,.4); }
|
|
480
|
+
.agent-output-row.ok { border-color:rgba(52,211,153,.25); }
|
|
481
|
+
.agent-output-row.err { border-color:rgba(251,113,133,.3); }
|
|
482
|
+
.agent-output-row-head { display:flex; align-items:center; gap:.5rem; padding:.5rem .7rem; cursor:pointer; }
|
|
483
|
+
.agent-output-dot { width:.42rem; height:.42rem; border-radius:50%; background:#5f7b9c; }
|
|
484
|
+
.agent-output-dot.running { background:#54b7ff; box-shadow:0 0 8px rgba(84,183,255,.7); animation:agent-pulse 1s ease-in-out infinite; }
|
|
485
|
+
.agent-output-name { color:#9fd4ff; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.62rem; font-weight:700; }
|
|
486
|
+
.agent-output-summary { flex:1; color:#9fb3d0; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.6rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
487
|
+
.agent-output-status { color:#5f7b9c; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.56rem; text-transform:uppercase; }
|
|
488
|
+
.agent-output-body { border-top:1px solid rgba(112,168,228,.1); background:rgba(0,0,0,.2); padding:.5rem; }
|
|
489
|
+
|
|
490
|
+
.agent-preview { display:flex; flex-direction:column; gap:.6rem; height:100%; min-height:60vh; }
|
|
491
|
+
.agent-preview-bar { display:flex; align-items:center; gap:.5rem; flex-wrap:wrap; padding:.5rem .7rem; border:1px solid rgba(112,168,228,.2); border-radius:.7rem; background:rgba(8,25,48,.6); }
|
|
492
|
+
.agent-preview-label { color:#9fd4ff; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.6rem; font-weight:700; }
|
|
493
|
+
.agent-preview-badge { padding:.15rem .4rem; border-radius:999px; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.56rem; font-weight:700; text-transform:uppercase; }
|
|
494
|
+
.agent-preview-badge.running { color:#7ee8bd; background:rgba(16,185,129,.15); border:1px solid rgba(52,211,153,.3); }
|
|
495
|
+
.agent-preview-badge.building { color:#8ed6ff; background:rgba(84,183,255,.15); border:1px solid rgba(84,183,255,.3); }
|
|
496
|
+
.agent-preview-badge.error { color:#fecdd3; background:rgba(244,63,94,.15); border:1px solid rgba(251,113,133,.3); }
|
|
497
|
+
.agent-preview-badge.stopped, .agent-preview-badge.not_found { color:#ffd479; background:rgba(245,158,11,.12); border:1px solid rgba(255,196,107,.3); }
|
|
498
|
+
.agent-preview-actions { display:inline-flex; gap:.35rem; margin-left:auto; }
|
|
499
|
+
.agent-preview-btn, .agent-preview-link { padding:.3rem .6rem; border:1px solid rgba(84,183,255,.35); border-radius:.45rem; color:#9fd4ff; background:rgba(84,183,255,.1); font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.58rem; font-weight:700; cursor:pointer; text-decoration:none; transition:filter .12s, background .12s; }
|
|
500
|
+
.agent-preview-btn:hover, .agent-preview-link:hover { filter:brightness(1.15); background:rgba(84,183,255,.18); }
|
|
501
|
+
.agent-preview-btn:disabled { opacity:.4; cursor:not-allowed; }
|
|
502
|
+
.agent-preview-btn.ghost { border-color:rgba(112,168,228,.25); color:#8fb8e4; background:transparent; }
|
|
503
|
+
.agent-preview-error { padding:.5rem .7rem; border:1px solid rgba(251,113,133,.3); border-radius:.5rem; color:#fecdd3; background:rgba(244,63,94,.1); font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.62rem; white-space:pre-wrap; }
|
|
504
|
+
.agent-preview-empty { color:#6e8aaa; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.64rem; line-height:1.7; text-align:center; padding:2rem 1rem; border:1px dashed rgba(112,168,228,.2); border-radius:.7rem; background:rgba(8,25,48,.4); }
|
|
505
|
+
.agent-preview-empty b { color:#9fd4ff; }
|
|
506
|
+
.agent-preview-empty code { background:rgba(84,183,255,.12); padding:.1em .3em; border-radius:.3em; }
|
|
507
|
+
.agent-preview-hint { color:#4d6378; font-size:.6rem; margin-top:.6rem; }
|
|
508
|
+
.agent-preview-frame { flex:1 1 auto; width:100%; min-height:420px; border:1px solid rgba(112,168,228,.2); border-radius:.7rem; background:#fff; }
|
|
509
|
+
.agent-preview-note { color:#4d6378; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.56rem; text-align:center; }
|
|
510
|
+
.agent-preview-note a { color:#6fcaff; }
|
|
511
|
+
|
|
512
|
+
.agent-side-actions { display:inline-flex; gap:.3rem; margin-left:auto; }
|
|
513
|
+
.agent-side-action { padding:.18rem .5rem; border:1px solid rgba(112,168,228,.28); border-radius:.4rem; color:#8fb8e4; background:rgba(84,183,255,.08); font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.54rem; cursor:pointer; transition:border-color .12s, background .12s, color .12s; }
|
|
514
|
+
.agent-side-action:hover { border-color:rgba(84,183,255,.6); color:#bfe9ff; background:rgba(84,183,255,.16); }
|
|
515
|
+
|
|
516
|
+
.agent-markdown { white-space:normal; overflow-wrap:break-word; font-family:system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; font-size:.85rem; line-height:1.72; color:#dcecff; }
|
|
517
|
+
.agent-markdown > :first-child { margin-top:0; }
|
|
518
|
+
.agent-markdown > :last-child { margin-bottom:0; }
|
|
519
|
+
.agent-markdown h1, .agent-markdown h2, .agent-markdown h3, .agent-markdown h4 { margin:1.1em 0 .5em; color:#eef8ff; line-height:1.3; letter-spacing:-.02em; }
|
|
520
|
+
.agent-markdown h1 { font-size:1.28rem; } .agent-markdown h2 { font-size:1.12rem; } .agent-markdown h3 { font-size:1rem; } .agent-markdown h4 { font-size:.92rem; }
|
|
521
|
+
.agent-markdown p { margin:.5em 0; }
|
|
522
|
+
.agent-markdown a { color:#6fcaff; text-decoration:none; border-bottom:1px solid rgba(111,202,255,.35); }
|
|
523
|
+
.agent-markdown a:hover { color:#bfe9ff; }
|
|
524
|
+
.agent-markdown ul, .agent-markdown ol { margin:.5em 0; padding-left:1.4em; }
|
|
525
|
+
.agent-markdown li { margin:.2em 0; }
|
|
526
|
+
.agent-markdown strong { color:#fff; font-weight:700; }
|
|
527
|
+
.agent-markdown em { color:#cfdfff; }
|
|
528
|
+
.agent-markdown blockquote { margin:.6em 0; padding:.25em .9em; border-left:3px solid #54b7ff; color:#8fa5c0; background:rgba(84,183,255,.06); border-radius:0 .5rem .5rem 0; }
|
|
529
|
+
.agent-markdown code { font-family:"Cascadia Code", ui-monospace, monospace; font-size:.8em; padding:.15em .35em; border-radius:.3em; background:rgba(84,183,255,.12); color:#9fd4ff; }
|
|
530
|
+
.agent-markdown pre { margin:.7em 0; padding:.8em .9em; overflow:auto; border:1px solid rgba(112,168,228,.18); border-radius:.6rem; background:rgba(0,0,0,.35); }
|
|
531
|
+
.agent-markdown pre code { padding:0; background:none; font-size:.78rem; color:#e8f2ff; }
|
|
532
|
+
.agent-markdown pre code.hljs { display:block; background:transparent; }
|
|
533
|
+
.agent-markdown table { width:100%; margin:.7em 0; border-collapse:collapse; font-size:.8rem; }
|
|
534
|
+
.agent-markdown th, .agent-markdown td { padding:.4em .6em; border:1px solid rgba(112,168,228,.18); text-align:left; }
|
|
535
|
+
.agent-markdown th { background:rgba(84,183,255,.08); color:#bfe9ff; }
|
|
536
|
+
.agent-markdown hr { margin:1em 0; border:0; height:1px; background:rgba(112,168,228,.15); }
|
|
537
|
+
.agent-markdown .hljs { display:block; background:transparent; color:#e8f2ff; }
|
|
538
|
+
.agent-markdown .hljs-keyword, .agent-markdown .hljs-selector-tag, .agent-markdown .hljs-meta .hljs-keyword { color:#c792ea; }
|
|
539
|
+
.agent-markdown .hljs-string, .agent-markdown .hljs-attr, .agent-markdown .hljs-regexp, .agent-markdown .hljs-template-string { color:#7fe0a8; }
|
|
540
|
+
.agent-markdown .hljs-number, .agent-markdown .hljs-literal, .agent-markdown .hljs-symbol, .agent-markdown .hljs-bullet, .agent-markdown .hljs-params { color:#e2a76f; }
|
|
541
|
+
.agent-markdown .hljs-comment, .agent-markdown .hljs-quote { color:#6b85a3; font-style:italic; }
|
|
542
|
+
.agent-markdown .hljs-title, .agent-markdown .hljs-title.function_, .agent-markdown .hljs-function .hljs-title, .agent-markdown .hljs-section { color:#82c6ff; }
|
|
543
|
+
.agent-markdown .hljs-built_in, .agent-markdown .hljs-selector-class, .agent-markdown .hljs-selector-id { color:#e5c07b; }
|
|
544
|
+
.agent-markdown .hljs-tag, .agent-markdown .hljs-name, .agent-markdown .hljs-variable, .agent-markdown .hljs-template-variable { color:#f18ac6; }
|
|
545
|
+
.agent-markdown .hljs-meta, .agent-markdown .hljs-doctag { color:#56b6c2; }
|
|
546
|
+
|
|
547
|
+
/* ── Two-pane split diff (edit old_string / new_string) ───────────────── */
|
|
548
|
+
.agent-split { display:flex; flex-direction:column; border-top:1px solid rgba(112,168,228,.12); background:rgba(0,0,0,.28); overflow:hidden; }
|
|
549
|
+
.agent-split-head { display:flex; align-items:center; gap:.5rem; padding:.45rem .7rem; border-bottom:1px solid rgba(112,168,228,.12); background:linear-gradient(180deg, rgba(16,38,70,.5), rgba(8,20,42,.55)); font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.56rem; letter-spacing:.06em; text-transform:uppercase; }
|
|
550
|
+
.agent-split-head-left { flex:1; color:#fda4af; }
|
|
551
|
+
.agent-split-head-right { flex:1; color:#6df0bb; text-align:right; }
|
|
552
|
+
.split-badge { display:inline-block; padding:.05rem .35rem; border-radius:.3rem; font-size:.52rem; font-weight:800; letter-spacing:.08em; vertical-align:middle; margin:0 .25rem; }
|
|
553
|
+
.split-badge.del { color:#fecdd3; background:rgba(244,63,94,.22); border:1px solid rgba(244,63,94,.35); }
|
|
554
|
+
.split-badge.add { color:#a7f3d0; background:rgba(16,185,129,.22); border:1px solid rgba(16,185,129,.35); }
|
|
555
|
+
.agent-split-grid { display:grid; grid-template-columns:1fr 1fr; min-height:0; max-height:420px; }
|
|
556
|
+
.agent-split-pane { position:relative; min-width:0; overflow:auto; background:rgba(0,0,0,.18); scrollbar-width:thin; scrollbar-color:rgba(112,168,228,.3) transparent; }
|
|
557
|
+
.agent-split-pane.pane-left { border-right:1px solid rgba(112,168,228,.12); }
|
|
558
|
+
.agent-split-pane .agent-copy { position:sticky; top:.4rem; float:right; margin:.4rem .4rem 0 0; z-index:3; }
|
|
559
|
+
.split-pane-label { position:sticky; top:0; z-index:2; padding:.28rem .6rem; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.52rem; letter-spacing:.1em; text-transform:uppercase; backdrop-filter:blur(8px); }
|
|
560
|
+
.pane-left .split-pane-label { color:#fda4af; background:rgba(244,63,94,.1); border-bottom:1px solid rgba(244,63,94,.18); }
|
|
561
|
+
.pane-right .split-pane-label { color:#6df0bb; background:rgba(16,185,129,.1); border-bottom:1px solid rgba(16,185,129,.18); }
|
|
562
|
+
.split-lines { padding:.5rem 0 .6rem; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.7rem; line-height:1.65; }
|
|
563
|
+
.split-line { display:flex; gap:.35rem; padding:.02rem .5rem; white-space:pre-wrap; word-break:break-word; }
|
|
564
|
+
.split-line.del { color:#fecdd3; background:rgba(244,63,94,.14); }
|
|
565
|
+
.split-line.add { color:#a7f3d0; background:rgba(16,185,129,.14); }
|
|
566
|
+
.split-line.context { color:#cfe3fb; }
|
|
567
|
+
.split-line.hunk { color:#67c8ff; background:rgba(84,183,255,.08); font-size:.62rem; letter-spacing:.02em; border-top:1px dashed rgba(84,183,255,.22); border-bottom:1px dashed rgba(84,183,255,.22); margin:.25rem 0; padding:.2rem .5rem; }
|
|
568
|
+
.split-line.empty { background:rgba(112,168,228,.04); min-height:1.15em; }
|
|
569
|
+
.split-num { flex:0 0 2.2rem; text-align:right; color:#3e5573; font-size:.62rem; user-select:none; }
|
|
570
|
+
.split-marker { flex:0 0 1ch; text-align:center; opacity:.7; }
|
|
571
|
+
.split-line.del .split-marker { color:#fb7185; }
|
|
572
|
+
.split-line.add .split-marker { color:#34d399; }
|
|
573
|
+
.split-text { flex:1 1 auto; min-width:0; }
|
|
574
|
+
.split-text .hljs { background:transparent; }
|
|
575
|
+
.split-hunk { opacity:.9; }
|
|
576
|
+
@media (max-width:760px) { .agent-split-grid { grid-template-columns:1fr; max-height:none; } .agent-split-pane.pane-left { border-right:0; border-bottom:1px solid rgba(112,168,228,.12); } .agent-split-pane { max-height:260px; } }
|
|
577
|
+
|
|
578
|
+
@media (max-width:1100px) {
|
|
579
|
+
.agent-side { flex-basis:320px; }
|
|
580
|
+
.agent-bubble { max-width:100%; }
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
@media (max-width:1024px) {
|
|
584
|
+
.agent-side { position:fixed; top:0; right:0; bottom:0; z-index:50; width:min(340px, 88vw); border-left:1px solid rgba(112,168,228,.2); background:linear-gradient(180deg, rgba(10,28,55,.98), rgba(6,15,34,.98)); box-shadow:-18px 0 60px rgba(0,0,0,.5); backdrop-filter:blur(22px) saturate(140%); -webkit-backdrop-filter:blur(22px) saturate(140%); transform:translateX(100%); transition:transform .24s cubic-bezier(.22,1,.36,1); }
|
|
585
|
+
.agent-side.open { transform:translateX(0); }
|
|
586
|
+
.agent-side-toggle { display:grid; }
|
|
587
|
+
.agent-main { padding-right:1.4rem; }
|
|
588
|
+
|
|
589
|
+
.agent-shell.agent-side-on > .agent-workspace { z-index:60; }
|
|
590
|
+
.agent-shell.agent-side-on > .agent-workspace .agent-side { top:3.8rem; height:calc(100dvh - 3.8rem); }
|
|
591
|
+
.agent-shell.agent-side-on > .agent-header { z-index:63; }
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
@media (max-width:860px) {
|
|
595
|
+
.agent-header-inner, .agent-workspace, .agent-error, .agent-notice, .agent-footer-inner, .agent-footer-bar { width:100%; max-width:none; }
|
|
596
|
+
.agent-header-inner { padding:.6rem .9rem; }
|
|
597
|
+
.agent-workspace { padding:0; }
|
|
598
|
+
.agent-main { padding:1.2rem .9rem; }
|
|
599
|
+
.agent-brand-sub, .agent-status { display:none; }
|
|
600
|
+
.agent-select { max-width:150px; }
|
|
601
|
+
.agent-select-label { display:none; }
|
|
602
|
+
.agent-footer-inner, .agent-footer-bar { padding:.75rem .9rem; }
|
|
603
|
+
.agent-footer-bar { padding-bottom:.2rem; }
|
|
604
|
+
.agent-footer-hint { display:none; }
|
|
605
|
+
.agent-modes { flex-wrap:wrap; }
|
|
606
|
+
.agent-mode { padding:.4rem .55rem; font-size:.58rem; }
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
@media (max-width:640px) {
|
|
610
|
+
.agent-main { padding:1rem .75rem; }
|
|
611
|
+
.agent-msg { max-width:100%; }
|
|
612
|
+
.agent-bubble { font-size:.82rem; padding:.65rem .8rem; }
|
|
613
|
+
.agent-row-user .agent-bubble, .agent-row-agent .agent-bubble { max-width:100%; }
|
|
614
|
+
.agent-tool-head { padding:.45rem .65rem; font-size:.66rem; }
|
|
615
|
+
.agent-badge-head { padding:.4rem .65rem; font-size:.66rem; }
|
|
616
|
+
.agent-list { gap:.8rem; }
|
|
617
|
+
.agent-hero { margin:2vh auto 0; padding:1.5rem 1rem; }
|
|
618
|
+
.agent-hero h2 { font-size:1.25rem; }
|
|
619
|
+
.agent-footer-bar { gap:.45rem; }
|
|
620
|
+
.agent-footer-inner { gap:.5rem; }
|
|
621
|
+
.agent-input { font-size:.8rem; }
|
|
622
|
+
.agent-send { padding:.65rem .9rem; font-size:.76rem; }
|
|
623
|
+
.agent-team-toggle, .agent-enhance-toggle { padding:.36rem .55rem; font-size:.56rem; }
|
|
624
|
+
.agent-workspace-btn { padding:.36rem .5rem; font-size:.72rem; }
|
|
625
|
+
.agent-enhance, .agent-suggest { bottom:3.9rem; width:calc(100vw - 16px); }
|
|
626
|
+
.agent-toast { right:.9rem; top:3.6rem; }
|
|
627
|
+
.agent-scroll-down { right:1rem; bottom:6rem; }
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
@media (max-width:480px) {
|
|
631
|
+
.agent-header-inner { padding:.5rem .7rem; }
|
|
632
|
+
.agent-brand-badge { width:1.9rem; height:1.9rem; }
|
|
633
|
+
.agent-brand-name { font-size:.68rem; }
|
|
634
|
+
.agent-brand-text { display:none; }
|
|
635
|
+
.agent-clear { padding:.45rem .6rem; font-size:.62rem; }
|
|
636
|
+
.agent-settings-btn, .agent-side-toggle { width:1.9rem; height:1.9rem; font-size:.8rem; }
|
|
637
|
+
.agent-settings { width:100vw; }
|
|
638
|
+
.agent-side { width:88vw; }
|
|
639
|
+
.agent-modes { width:100%; }
|
|
640
|
+
.agent-mode { flex:1; text-align:center; }
|
|
641
|
+
.agent-team-toggle, .agent-enhance-toggle { flex:1; justify-content:center; }
|
|
642
|
+
.agent-workspace-btn { flex:1; justify-content:center; }
|
|
643
|
+
.agent-footer-bar { display:flex; }
|
|
644
|
+
.agent-footer-inner { flex-wrap:nowrap; }
|
|
645
|
+
.agent-hero-chips { flex-direction:column; width:100%; }
|
|
646
|
+
.agent-hero-chip { width:100%; text-align:center; }
|
|
647
|
+
}`;
|
|
648
|
+
|
|
649
|
+
export interface ExplorerOptions {
|
|
650
|
+
endpoint?: string;
|
|
651
|
+
title?: string;
|
|
652
|
+
appName?: string;
|
|
653
|
+
sdl?: string;
|
|
654
|
+
introspection?: boolean;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
export function getExplorerHtml(opts: ExplorerOptions = {}): string {
|
|
658
|
+
const endpoint = opts.endpoint ?? '/graphql';
|
|
659
|
+
const title = opts.title ?? 'BhooAI Nexus — GraphQL Sandbox';
|
|
660
|
+
const appName = opts.appName ?? 'backend';
|
|
661
|
+
const introspection = opts.introspection !== false;
|
|
662
|
+
const sdlPreview = opts.sdl ? opts.sdl.slice(0, 4000).replace(/`/g, '\\`').replace(/\$/g, '\\$') : '';
|
|
663
|
+
const rawSdl = opts.sdl ?? '';
|
|
664
|
+
const operations = extractOperations(rawSdl);
|
|
665
|
+
const defaultQuery = buildDefaultQuery(operations);
|
|
666
|
+
|
|
667
|
+
// CDN versions pinned to avoid breaking changes
|
|
668
|
+
const CDN = {
|
|
669
|
+
graphiqlCss: 'https://unpkg.com/graphiql@3.6.0/graphiql.min.css',
|
|
670
|
+
graphiqlJs: 'https://unpkg.com/graphiql@3.6.0/graphiql.min.js',
|
|
671
|
+
hljsCss: 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css',
|
|
672
|
+
hljsJs: 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js',
|
|
673
|
+
react: 'https://unpkg.com/react@18/umd/react.production.min.js',
|
|
674
|
+
reactDom: 'https://unpkg.com/react-dom@18/umd/react-dom.production.min.js',
|
|
675
|
+
graphqlWs: 'https://unpkg.com/graphql-ws@5/umd/graphql-ws.min.js',
|
|
676
|
+
};
|
|
677
|
+
|
|
678
|
+
return `<!doctype html>
|
|
679
|
+
<html lang="en">
|
|
680
|
+
<head>
|
|
681
|
+
<meta charset="utf-8" />
|
|
682
|
+
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
|
683
|
+
<title>${escapeHtml(title)}</title>
|
|
684
|
+
<link rel="stylesheet" href="${CDN.graphiqlCss}" />
|
|
685
|
+
<link rel="stylesheet" href="${CDN.hljsCss}" />
|
|
686
|
+
<style>
|
|
687
|
+
:root{ color-scheme: dark light; }
|
|
688
|
+
*{box-sizing:border-box}
|
|
689
|
+
html,body{height:100%;margin:0;padding:0}
|
|
690
|
+
/* ── AURORA GLASS THEME — copied verbatim from bhooai-agent AGENT_CSS ── */
|
|
691
|
+
${AURORA_CSS}
|
|
692
|
+
/* ── full-width overrides (explorer is edge-to-edge, not centered 1400px) ── */
|
|
693
|
+
.agent-header-inner, .agent-workspace { width:100%; max-width:none; margin:0; padding-inline:1rem; }
|
|
694
|
+
.agent-header::after { left:1rem; right:1rem; }
|
|
695
|
+
.agent-main { padding:.8rem 1rem 1rem; }
|
|
696
|
+
.agent-side { flex:0 0 380px; padding:1rem .8rem 1rem 1rem; }
|
|
697
|
+
@media (max-width: 960px){ .agent-side { display:none; } }
|
|
698
|
+
/* ── GraphiQL aurora theming (override its light-mode CDN defaults) ──
|
|
699
|
+
GraphiQL's CDN only applies its dark palette via body.graphiql-dark or
|
|
700
|
+
prefers-color-scheme — without that class everything renders light.
|
|
701
|
+
Our overrides target BOTH body classes AND the raw selectors so they
|
|
702
|
+
win the cascade over the CDN defaults for .graphiql-main, sidebar,
|
|
703
|
+
editors, toolbar, sessions, footer and doc-explorer. */
|
|
704
|
+
body.graphiql-dark .graphiql-container, body.graphiql-light .graphiql-container,
|
|
705
|
+
.graphiql-container,
|
|
706
|
+
.graphiql-container .CodeMirror-info,
|
|
707
|
+
.graphiql-container .CodeMirror-lint-tooltip,
|
|
708
|
+
.graphiql-dialog,
|
|
709
|
+
.graphiql-dialog-overlay,
|
|
710
|
+
.graphiql-tooltip {
|
|
711
|
+
/* GraphiQL HSL tokens → aurora palette */
|
|
712
|
+
--color-primary: 205, 100%, 66%; /* #54b7ff blue */
|
|
713
|
+
--color-secondary: 258, 100%, 77%; /* #9f7bff violet */
|
|
714
|
+
--color-tertiary: 188, 100%, 52%;
|
|
715
|
+
--color-info: 208, 100%, 56%;
|
|
716
|
+
--color-success: 158, 70%, 55%; /* #5ef0b3 mint */
|
|
717
|
+
--color-warning: 41, 100%, 63%;
|
|
718
|
+
--color-error: 352, 96%, 68%; /* #fb7185 rose */
|
|
719
|
+
--color-neutral: 215, 45%, 74%;
|
|
720
|
+
--color-base: 220, 60%, 6%; /* dark base: #040b18 */
|
|
721
|
+
--alpha-secondary: .85;
|
|
722
|
+
--alpha-tertiary: .55;
|
|
723
|
+
--alpha-background-heavy: .16;
|
|
724
|
+
--alpha-background-medium: .09;
|
|
725
|
+
--alpha-background-light: .05;
|
|
726
|
+
--font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
|
|
727
|
+
--font-family-mono: ui-monospace, SFMono-Regular, Consolas, monospace;
|
|
728
|
+
--editor-background: rgba(8, 25, 48, .55);
|
|
729
|
+
--popover-box-shadow: 0 24px 70px rgba(0,0,0,.5), 0 0 30px rgba(84,183,255,.14);
|
|
730
|
+
--popover-border: 1px solid rgba(112,168,228,.24);
|
|
731
|
+
--session-header-height: 44px;
|
|
732
|
+
--sidebar-width: 48px;
|
|
733
|
+
--toolbar-width: 36px;
|
|
734
|
+
}
|
|
735
|
+
/* main editor surface: glass, translucent so aurora shows through */
|
|
736
|
+
.graphiql-container { background: transparent; height:100%; }
|
|
737
|
+
.graphiql-container .graphiql-main, .graphiql-container .graphiql-sessions { background: transparent; }
|
|
738
|
+
/* .graphiql-editors — the big white card holding query editor + result pane */
|
|
739
|
+
.graphiql-container .graphiql-editors {
|
|
740
|
+
background: linear-gradient(160deg, rgba(16,38,70,.55), rgba(8,20,42,.62));
|
|
741
|
+
border: 1px solid rgba(112,168,228,.18);
|
|
742
|
+
box-shadow: inset 0 1px rgba(255,255,255,.05), 0 18px 50px rgba(0,0,0,.28);
|
|
743
|
+
backdrop-filter: blur(18px) saturate(135%); -webkit-backdrop-filter: blur(18px) saturate(135%);
|
|
744
|
+
border-radius: .9rem;
|
|
745
|
+
}
|
|
746
|
+
/* query editor section (toolbar + codemirror) */
|
|
747
|
+
.graphiql-container .graphiql-query-editor { border-bottom-color: rgba(112,168,228,.14); background: transparent; }
|
|
748
|
+
/* left sidebar (icon rail: docs/history/plugins) */
|
|
749
|
+
.graphiql-container .graphiql-sidebar { background: linear-gradient(180deg, rgba(9,24,48,.6), rgba(4,14,29,.4)); border-right: 1px solid rgba(112,168,228,.14); }
|
|
750
|
+
.graphiql-container .graphiql-sidebar button { color: #6e8aaa; border-radius: .5rem; transition: color .14s, background .14s; }
|
|
751
|
+
.graphiql-container .graphiql-sidebar button:hover { color: #dcecff; background: rgba(84,183,255,.12); }
|
|
752
|
+
.graphiql-container .graphiql-sidebar button.active { color: #8ed6ff; background: rgba(84,183,255,.16); box-shadow: 0 0 12px rgba(84,183,255,.25); }
|
|
753
|
+
.graphiql-container .graphiql-sidebar button > svg { fill: currentColor; }
|
|
754
|
+
/* vertical toolbar next to query editor */
|
|
755
|
+
.graphiql-container .graphiql-toolbar { background: linear-gradient(180deg, rgba(9,24,48,.5), rgba(4,14,29,.3)); border-right: 1px solid rgba(112,168,228,.12); }
|
|
756
|
+
.graphiql-container .graphiql-toolbar button { color: #6e8aaa; border-radius: .45rem; }
|
|
757
|
+
.graphiql-container .graphiql-toolbar button:hover { color: #dcecff; background: rgba(84,183,255,.12); }
|
|
758
|
+
.graphiql-container .graphiql-toolbar button.active { color: #8ed6ff; background: rgba(84,183,255,.16); }
|
|
759
|
+
.graphiql-container .graphiql-toolbar-icon { color: currentColor; }
|
|
760
|
+
/* editor-tools row (Variables / Headers / Prettify toggles + drag handle) */
|
|
761
|
+
.graphiql-container .graphiql-editor-tools { background: rgba(4,14,29,.35); border-top: 1px solid rgba(112,168,228,.1); }
|
|
762
|
+
.graphiql-container .graphiql-editor-tools button { color: #6e8aaa; }
|
|
763
|
+
.graphiql-container .graphiql-editor-tools button:hover { color: #dcecff; background: rgba(84,183,255,.1); border-radius:.4rem; }
|
|
764
|
+
.graphiql-container .graphiql-editor-tools button.active { color: #8ed6ff; border-bottom-color: #54b7ff; }
|
|
765
|
+
/* session header (tabs + execute) */
|
|
766
|
+
.graphiql-container .graphiql-session-header { border-bottom:1px solid rgba(112,168,228,.14); background:linear-gradient(180deg, rgba(9,24,48,.55), rgba(4,14,29,.35)); backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px); }
|
|
767
|
+
.graphiql-container .graphiql-session-header-right button, .graphiql-container .graphiql-toolbar button { color:#9fb3d0; }
|
|
768
|
+
.graphiql-container .graphiql-session-header-right button:hover, .graphiql-container .graphiql-toolbar button:hover { color:#dcecff; background:rgba(84,183,255,.14); }
|
|
769
|
+
/* response footer */
|
|
770
|
+
.graphiql-container .graphiql-footer { border-top-color: rgba(112,168,228,.14); background: rgba(4,14,29,.35); }
|
|
771
|
+
/* doc explorer panel (opens from sidebar) */
|
|
772
|
+
.graphiql-container .graphiql-doc-explorer { background: linear-gradient(160deg, rgba(16,38,70,.6), rgba(8,20,42,.66)); backdrop-filter: blur(18px) saturate(135%); -webkit-backdrop-filter: blur(18px) saturate(135%); border-left: 1px solid rgba(112,168,228,.14); }
|
|
773
|
+
.graphiql-container .graphiql-doc-explorer-header, .graphiql-container .graphiql-doc-explorer-section-title { color: #9fd4ff; border-color: rgba(112,168,228,.14); background: transparent; }
|
|
774
|
+
.graphiql-container .graphiql-doc-explorer-section-content, .graphiql-container .graphiql-doc-explorer-item { color: #cfe3fb; background: transparent; }
|
|
775
|
+
.graphiql-container .graphiql-doc-explorer-item:hover { background: rgba(84,183,255,.1); }
|
|
776
|
+
.graphiql-container .graphiql-doc-explorer-field-name { color: #8ed6ff; }
|
|
777
|
+
.graphiql-container .graphiql-doc-explorer-type-name { color: #c4b5fd; }
|
|
778
|
+
.graphiql-container .graphiql-doc-explorer-argument-name { color: #7fe0a8; }
|
|
779
|
+
.graphiql-container .graphiql-doc-explorer-search-input, .graphiql-container .graphiql-doc-explorer-search input[type=text], .graphiql-container .graphiql-doc-explorer-search input { background: rgba(255,255,255,.06); border:1px solid rgba(112,168,228,.22); color:#e8f2ff; }
|
|
780
|
+
.graphiql-container .graphiql-doc-explorer-back { color: #9fd4ff; }
|
|
781
|
+
/* history panel inside graphiql */
|
|
782
|
+
.graphiql-container .graphiql-history-item { color:#cfe3fb; border-color: rgba(112,168,228,.14); background: rgba(8,25,48,.55); }
|
|
783
|
+
.graphiql-container .graphiql-history-item:hover { background: rgba(84,183,255,.1); }
|
|
784
|
+
.graphiql-container .graphiql-history-header { color: #5f7b9c; border-color: rgba(112,168,228,.14); }
|
|
785
|
+
/* dropdown menus + buttons */
|
|
786
|
+
.graphiql-container .graphiql-dropdown-content { background: linear-gradient(160deg, rgba(12,34,64,.97), rgba(6,16,36,.98)); border:1px solid rgba(99,189,255,.3); box-shadow: 0 16px 40px rgba(0,0,0,.5); }
|
|
787
|
+
.graphiql-container .graphiql-dropdown-item { color: #cfe3fb; }
|
|
788
|
+
.graphiql-container .graphiql-dropdown-item:hover { background: rgba(84,183,255,.15); color:#fff; }
|
|
789
|
+
.graphiql-container .graphiql-button { border-color: rgba(112,168,228,.24); color: #9fd4ff; background: rgba(84,183,255,.1); }
|
|
790
|
+
.graphiql-container .graphiql-button:hover { border-color: rgba(84,183,255,.55); color:#fff; background: rgba(84,183,255,.18); }
|
|
791
|
+
/* result pane */
|
|
792
|
+
.graphiql-container .graphiql-response-result, .graphiql-container pre.result-window, .graphiql-container .result-window {
|
|
793
|
+
font-family:var(--font-family-mono, ui-monospace, monospace);
|
|
794
|
+
}
|
|
795
|
+
.graphiql-container .result-window, .graphiql-container .result-window * { background: transparent; }
|
|
796
|
+
/* docs sidebar inside GraphiQL */
|
|
797
|
+
.graphiql-container .graphiql-docs { background:linear-gradient(160deg, rgba(16,38,70,.6), rgba(8,20,42,.66)); backdrop-filter:blur(18px) saturate(135%); -webkit-backdrop-filter:blur(18px) saturate(135%); color:#dcecff; }
|
|
798
|
+
.graphiql-container .graphiql-docs .graphiql-docs-description, .graphiql-container .graphiql-docs-section, .graphiql-container .graphiql-docs-category-item { color:#cfe3fb; background:transparent; border-color:rgba(112,168,228,.14); }
|
|
799
|
+
.graphiql-container .graphiql-docs .graphiql-docs-category-item:hover { background:rgba(84,183,255,.1); }
|
|
800
|
+
.graphiql-container .graphiql-docs .graphiql-docs-type { color:#8ed6ff; }
|
|
801
|
+
.graphiql-container .graphiql-docs .doc-category-item .field-name { color:#8ed6ff; }
|
|
802
|
+
.graphiql-container .graphiql-docs .doc-category-item .type-name { color:#c4b5fd; }
|
|
803
|
+
/* editor panes + CodeMirror */
|
|
804
|
+
.graphiql-container .CodeMirror, .graphiql-container .result-window, .graphiql-container .graphiql-editor, .graphiql-container pre.CodeMirror-code { background: rgba(8,25,48,.35); }
|
|
805
|
+
.graphiql-container .cm-s-graphiql { background: transparent !important; color:#cfe3fb; }
|
|
806
|
+
.graphiql-container .cm-s-graphiql .CodeMirror-gutters { background:rgba(4,14,29,.4); border-right:1px solid rgba(112,168,228,.12); }
|
|
807
|
+
.graphiql-container .cm-s-graphiql .CodeMirror-linenumber { color:#45597a; }
|
|
808
|
+
.graphiql-container .cm-s-graphiql .CodeMirror-cursor { border-left:2px solid #54b7ff; }
|
|
809
|
+
.graphiql-container .cm-s-graphiql .CodeMirror-selected, .graphiql-container .cm-s-graphiql .CodeMirror-focused .CodeMirror-selected { background:rgba(84,183,255,.22); }
|
|
810
|
+
.graphiql-container .cm-s-graphiql .CodeMirror-matchingbracket { color:#5ef0b3 !important; border-bottom:1px solid #5ef0b3; }
|
|
811
|
+
.graphiql-container .cm-s-graphiql .CodeMirror-activeline-background { background:rgba(84,183,255,.07); }
|
|
812
|
+
/* CodeMirror syntax colors → aurora (match hljs theme) */
|
|
813
|
+
.graphiql-container .cm-s-graphiql .cm-keyword { color:#c792ea; }
|
|
814
|
+
.graphiql-container .cm-s-graphiql .cm-def { color:#82c6ff; }
|
|
815
|
+
.graphiql-container .cm-s-graphiql .cm-property, .graphiql-container .cm-s-graphiql .cm-variable { color:#e8f2ff; }
|
|
816
|
+
.graphiql-container .cm-s-graphiql .cm-variable-2 { color:#7fe0a8; }
|
|
817
|
+
.graphiql-container .cm-s-graphiql .cm-punctuation, .graphiql-container .cm-s-graphiql .cm-operator { color:#8fa8c8; }
|
|
818
|
+
.graphiql-container .cm-s-graphiql .cm-string, .graphiql-container .cm-s-graphiql .cm-string-2 { color:#7fe0a8; }
|
|
819
|
+
.graphiql-container .cm-s-graphiql .cm-number, .graphiql-container .cm-s-graphiql .cm-atom { color:#e2a76f; }
|
|
820
|
+
.graphiql-container .cm-s-graphiql .cm-comment { color:#6b85a3; font-style:italic; }
|
|
821
|
+
.graphiql-container .cm-s-graphiql .cm-attribute { color:#e5c07b; }
|
|
822
|
+
.graphiql-container .cm-s-graphiql .cm-qualifier, .graphiql-container .cm-s-graphiql .cm-builtin { color:#56b6c2; }
|
|
823
|
+
/* toolbar / tabs / buttons */
|
|
824
|
+
.graphiql-container .graphiql-tab, .graphiql-container .graphiql-tab-button, .graphiql-container .graphiql-tab.active { border-color:rgba(112,168,228,.18); background:rgba(8,25,48,.5); color:#9fb3d0; }
|
|
825
|
+
.graphiql-container .graphiql-tab.active { color:#8ed6ff; border-bottom-color:rgba(84,183,255,.6); background:rgba(84,183,255,.1); }
|
|
826
|
+
.graphiql-container .graphiql-tab:hover { color:#dcecff; }
|
|
827
|
+
.graphiql-container button.graphiql-toolbar-button, .graphiql-container .graphiql-toolbar { background:transparent; }
|
|
828
|
+
.graphiql-container .graphiql-execute-button { background:linear-gradient(135deg, rgba(38,130,225,.75), rgba(90,67,183,.65)) !important; border:1px solid rgba(84,183,255,.55); box-shadow:0 0 14px rgba(84,183,255,.35); }
|
|
829
|
+
.graphiql-container .graphiql-execute-button:hover { filter:brightness(1.15); }
|
|
830
|
+
/* dialogs + tooltips + autocomplete */
|
|
831
|
+
.graphiql-dialog, .graphiql-dialog-overlay { background:rgba(2,8,20,.62); }
|
|
832
|
+
.graphiql-dialog-container { background:linear-gradient(160deg, rgba(23,55,96,.97), rgba(14,32,62,.98)) !important; border:1px solid rgba(99,189,255,.4); box-shadow:0 30px 90px rgba(0,0,0,.55); backdrop-filter:blur(22px); }
|
|
833
|
+
.graphiql-dialog-close { display:grid; place-items:center; width:1.9rem; height:1.9rem; border:1px solid rgba(251,113,133,.55); border-radius:.55rem; background:linear-gradient(135deg, rgba(244,63,94,.85), rgba(159,18,57,.8)); color:#fff !important; cursor:pointer; box-shadow:0 6px 18px rgba(244,63,94,.4); transition:filter .14s, transform .14s, box-shadow .14s; }
|
|
834
|
+
.graphiql-dialog-close:hover { filter:brightness(1.15); transform:rotate(90deg); box-shadow:0 8px 22px rgba(244,63,94,.55); }
|
|
835
|
+
.graphiql-dialog-close svg { fill:none; stroke:currentColor; stroke-width:2; }
|
|
836
|
+
.graphiql-dialog-title { color:#bfe9ff; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.7rem; font-weight:800; letter-spacing:.12em; text-transform:uppercase; }
|
|
837
|
+
.graphiql-dialog-section-title { color:#bfe9ff; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.62rem; font-weight:700; letter-spacing:.08em; text-transform:uppercase; }
|
|
838
|
+
.graphiql-container .CodeMirror-hints { background:linear-gradient(160deg, rgba(12,34,64,.97), rgba(6,16,36,.98)); border:1px solid rgba(99,189,255,.3); box-shadow:0 16px 40px rgba(0,0,0,.5); }
|
|
839
|
+
.graphiql-container .CodeMirror-hint { color:#cfe3fb; }
|
|
840
|
+
.graphiql-container .CodeMirror-hint-active { background:rgba(84,183,255,.22); color:#fff; }
|
|
841
|
+
.graphiql-tooltip { background:linear-gradient(160deg, rgba(10,28,55,.97), rgba(6,16,36,.98)); color:#dcecff; border:1px solid rgba(112,168,228,.28); border-radius:.45rem; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.56rem; font-weight:600; letter-spacing:.03em; line-height:1.4; padding:.35rem .6rem; box-shadow:0 12px 32px rgba(0,0,0,.4), inset 0 1px rgba(255,255,255,.06); backdrop-filter:blur(18px) saturate(140%); -webkit-backdrop-filter:blur(18px) saturate(140%); }
|
|
842
|
+
/* GraphiQL variables/editor inputs */
|
|
843
|
+
.graphiql-container input[type=text], .graphiql-container input[type=search], .graphiql-container textarea { background:rgba(255,255,255,.05); border-color:rgba(112,168,228,.24); color:#e8f2ff; }
|
|
844
|
+
.graphiql-container input:focus, .graphiql-container textarea:focus { border-color:rgba(84,183,255,.6); box-shadow:0 0 0 3px rgba(84,183,255,.14); }
|
|
845
|
+
/* light theme: GraphiQL back to light vars + light glass surfaces */
|
|
846
|
+
[data-theme="light"] .graphiql-container,
|
|
847
|
+
[data-theme="light"] .graphiql-container .CodeMirror-info,
|
|
848
|
+
[data-theme="light"] .graphiql-dialog,
|
|
849
|
+
[data-theme="light"] .graphiql-tooltip {
|
|
850
|
+
--color-base: 216, 40%, 98%;
|
|
851
|
+
--color-neutral: 219, 28%, 32%;
|
|
852
|
+
--alpha-background-light: .6;
|
|
853
|
+
--editor-background: rgba(255,255,255,.8);
|
|
854
|
+
--popover-box-shadow: 0 14px 40px rgba(20,50,100,.14);
|
|
855
|
+
--popover-border: 1px solid rgba(60,110,180,.18);
|
|
856
|
+
}
|
|
857
|
+
[data-theme="light"] .graphiql-tooltip { background:linear-gradient(160deg, rgba(255,255,255,.98), rgba(238,245,255,.98)); color:#0b1220; border-color:rgba(60,110,180,.24); box-shadow:0 12px 32px rgba(20,50,100,.16), inset 0 1px rgba(255,255,255,.7); }
|
|
858
|
+
[data-theme="light"] .graphiql-dialog-close { color:#fff !important; border-color:rgba(225,29,72,.55); background:linear-gradient(135deg, rgba(225,29,72,.85), rgba(159,18,57,.8)); box-shadow:0 6px 18px rgba(225,29,72,.35); }
|
|
859
|
+
[data-theme="light"] .graphiql-dialog-close:hover { filter:brightness(1.12); }
|
|
860
|
+
[data-theme="light"] .graphiql-dialog-title, [data-theme="light"] .graphiql-dialog-section-title { color:#1d6fd0; }
|
|
861
|
+
[data-theme="light"] .graphiql-container .graphiql-editors { background: rgba(255,255,255,.72); border-color: rgba(60,110,180,.16); box-shadow: inset 0 1px rgba(255,255,255,.6), 0 18px 50px rgba(20,50,100,.1); }
|
|
862
|
+
[data-theme="light"] .graphiql-container .graphiql-sidebar { background: rgba(255,255,255,.6); border-right-color: rgba(60,110,180,.14); }
|
|
863
|
+
[data-theme="light"] .graphiql-container .graphiql-toolbar { background: rgba(255,255,255,.55); border-right-color: rgba(60,110,180,.12); }
|
|
864
|
+
[data-theme="light"] .graphiql-container .graphiql-sidebar button, [data-theme="light"] .graphiql-container .graphiql-toolbar button, [data-theme="light"] .graphiql-container .graphiql-editor-tools button { color:#5a6b84; }
|
|
865
|
+
[data-theme="light"] .graphiql-container .graphiql-sidebar button.active, [data-theme="light"] .graphiql-container .graphiql-toolbar button.active { color:#1d6fd0; background:rgba(29,111,208,.14); }
|
|
866
|
+
[data-theme="light"] .graphiql-container .graphiql-editor-tools { background: rgba(240,246,255,.7); border-top-color: rgba(60,110,180,.12); }
|
|
867
|
+
[data-theme="light"] .graphiql-container .graphiql-session-header { background:linear-gradient(180deg, rgba(255,255,255,.85), rgba(235,242,252,.7)); border-bottom-color:rgba(60,110,180,.14); }
|
|
868
|
+
[data-theme="light"] .graphiql-container .graphiql-doc-explorer, [data-theme="light"] .graphiql-container .graphiql-docs { background:rgba(255,255,255,.82); color:#16233c; border-left-color:rgba(60,110,180,.14); }
|
|
869
|
+
[data-theme="light"] .graphiql-container .graphiql-doc-explorer-header, [data-theme="light"] .graphiql-container .graphiql-doc-explorer-section-title { color:#1d6fd0; }
|
|
870
|
+
[data-theme="light"] .graphiql-container .graphiql-doc-explorer-section-content, [data-theme="light"] .graphiql-container .graphiql-doc-explorer-item { color:#3a4c68; }
|
|
871
|
+
[data-theme="light"] .graphiql-container .graphiql-history-item { color:#3a4c68; background:rgba(255,255,255,.7); border-color:rgba(60,110,180,.12); }
|
|
872
|
+
[data-theme="light"] .graphiql-container .graphiql-footer { background: rgba(240,246,255,.7); border-top-color:rgba(60,110,180,.12); }
|
|
873
|
+
[data-theme="light"] .graphiql-container .graphiql-docs .graphiql-docs-section, [data-theme="light"] .graphiql-container .graphiql-docs .graphiql-docs-description { color:#3a4c68; }
|
|
874
|
+
[data-theme="light"] .graphiql-container .CodeMirror, [data-theme="light"] .graphiql-container pre.CodeMirror-code { background:rgba(255,255,255,.85); }
|
|
875
|
+
[data-theme="light"] .graphiql-container .cm-s-graphiql { color:#1c2a44; }
|
|
876
|
+
[data-theme="light"] .graphiql-container .cm-s-graphiql .CodeMirror-gutters { background:rgba(230,240,252,.9); border-right-color:rgba(60,110,180,.12); }
|
|
877
|
+
[data-theme="light"] .graphiql-container .cm-s-graphiql .CodeMirror-linenumber { color:#7a8db0; }
|
|
878
|
+
[data-theme="light"] .graphiql-container .graphiql-tab, [data-theme="light"] .graphiql-container .graphiql-tab.active { background:rgba(255,255,255,.8); color:#3a4c68; border-color:rgba(60,110,180,.14); }
|
|
879
|
+
[data-theme="light"] .graphiql-container .graphiql-tab.active { color:#1d6fd0; border-bottom-color:rgba(29,111,208,.6); }
|
|
880
|
+
[data-theme="light"] .graphiql-container input[type=text], [data-theme="light"] .graphiql-container textarea { background:rgba(255,255,255,.9); color:#16233c; border-color:rgba(60,110,180,.2); }
|
|
881
|
+
/* ── explorer-specific glass (reuses agent tokens) ── */
|
|
882
|
+
.graphiql-panel { display:flex; flex-direction:column; min-width:0; min-height:0; border:1px solid rgba(112,168,228,.18); border-radius:.9rem; background:linear-gradient(160deg, rgba(16,38,70,.45), rgba(8,20,42,.5)); box-shadow:inset 0 1px rgba(255,255,255,.05), 0 18px 50px rgba(0,0,0,.24); backdrop-filter:blur(18px) saturate(135%); -webkit-backdrop-filter:blur(18px) saturate(135%); overflow:hidden; animation:agent-rise .3s cubic-bezier(.22,1,.36,1) both; }
|
|
883
|
+
#graphiql{flex:1; min-height:0; min-width:0; overflow:hidden}
|
|
884
|
+
.graphiql-container{height:100% !important; width:100%; min-width:0; overflow:hidden}
|
|
885
|
+
.graphiql-container .graphiql-editors{min-width:0}
|
|
886
|
+
/* Hide GraphiQL/CodeMirror off-screen measurement nodes (left:-1000px) that
|
|
887
|
+
bleed over the sidebar and block the History toggle button. */
|
|
888
|
+
#graphiql [style*="left: -1000px"], #graphiql [style*="left:-1000px"],
|
|
889
|
+
#graphiql .CodeMirror-measure, #graphiql .CodeMirror-measure *{pointer-events:none !important}
|
|
890
|
+
#graphiql [style*="left: -1000px"], #graphiql [style*="left:-1000px"]{visibility:hidden !important}
|
|
891
|
+
.panel-head{padding:.6rem .85rem; font-size:.6rem; letter-spacing:.13em; text-transform:uppercase; color:#5f7b9c; border-bottom:1px solid rgba(112,168,228,.12); display:flex; justify-content:space-between; align-items:center; font-family:ui-monospace, SFMono-Regular, Consolas, monospace}
|
|
892
|
+
.ai-hint{font-size:.6rem; color:#5f7b9c; font-family:ui-monospace, SFMono-Regular, Consolas, monospace}
|
|
893
|
+
.ops{padding:.6rem .7rem; display:flex; flex-direction:column; gap:.4rem}
|
|
894
|
+
.ops .op{padding:.5rem .65rem; border:1px solid rgba(112,168,228,.17); border-radius:.55rem; background:rgba(8,25,48,.6); box-shadow:inset 0 1px rgba(255,255,255,.04); cursor:pointer; display:flex; justify-content:space-between; align-items:center; gap:.5rem; transition:border-color .14s, background .14s, transform .14s; animation:agent-rise .25s cubic-bezier(.22,1,.36,1) both}
|
|
895
|
+
.ops .op:hover{border-color:rgba(84,183,255,.5); background:rgba(84,183,255,.1); transform:translateY(-1px)}
|
|
896
|
+
.ops .op b{font-size:.66rem; color:#dcecff; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-weight:600}
|
|
897
|
+
.ops .op > span{font-size:.52rem; padding:.14rem .45rem; border-radius:999px; background:rgba(84,183,255,.15); color:#8ed6ff; border:1px solid rgba(84,183,255,.25); font-weight:700; letter-spacing:.06em; text-transform:uppercase; flex:0 0 auto}
|
|
898
|
+
.ops .op.mutation > span{background:rgba(243,110,184,.15); color:#fda4c7; border-color:rgba(243,110,184,.25)}
|
|
899
|
+
.history{padding:.5rem .7rem; border-top:1px solid rgba(112,168,228,.12); max-height:9rem; overflow:auto}
|
|
900
|
+
.history div{font-size:.6rem; padding:.35rem .5rem; border-radius:.45rem; cursor:pointer; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; color:#9fb3d0; font-family:ui-monospace, SFMono-Regular, Consolas, monospace}
|
|
901
|
+
.history div:hover{background:rgba(84,183,255,.1)}
|
|
902
|
+
.graphiql-history-clear{border:0; background:transparent; color:#5f7b9c; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.56rem; font-weight:700; letter-spacing:.06em; text-transform:uppercase; cursor:pointer; padding:.1rem .3rem; border-radius:.35rem; transition:color .12s, background .12s}
|
|
903
|
+
.graphiql-history-clear:hover{color:#fda4af; background:rgba(244,63,94,.12)}
|
|
904
|
+
.panel-head-actions{display:inline-flex; align-items:center; gap:.25rem}
|
|
905
|
+
.graphiql-history-btn{border:1px solid rgba(112,168,228,.22); background:rgba(84,183,255,.08); color:#8fb8e4; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.56rem; font-weight:700; letter-spacing:.06em; text-transform:uppercase; cursor:pointer; padding:.12rem .4rem; border-radius:.4rem; transition:color .12s, border-color .12s, background .12s}
|
|
906
|
+
.graphiql-history-btn:hover{color:#bfe9ff; border-color:rgba(84,183,255,.55); background:rgba(84,183,255,.16)}
|
|
907
|
+
.graphiql-history-btn.active{color:#8ed6ff; border-color:rgba(84,183,255,.6); background:rgba(84,183,255,.2); box-shadow:0 0 8px rgba(84,183,255,.25)}
|
|
908
|
+
/* Type details */
|
|
909
|
+
.type-details{padding:0 .7rem .7rem; display:flex; flex-direction:column; gap:.5rem; min-width:0}
|
|
910
|
+
.type-details details{border:1px solid rgba(112,168,228,.17); border-radius:.55rem; background:rgba(8,25,48,.6); box-shadow:inset 0 1px rgba(255,255,255,.04); overflow:hidden; transition:border-color .14s, background .14s, transform .14s}
|
|
911
|
+
.type-details details:hover{border-color:rgba(84,183,255,.5); background:rgba(84,183,255,.1); transform:translateY(-1px)}
|
|
912
|
+
.type-details summary{cursor:pointer; padding:.5rem .65rem; list-style:none; display:flex; justify-content:space-between; align-items:center; gap:.6rem; font-size:.66rem; color:#dcecff; font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-weight:700; transition:background .14s}
|
|
913
|
+
.type-details summary::-webkit-details-marker{display:none}
|
|
914
|
+
.type-details summary:hover{background:rgba(84,183,255,.1)}
|
|
915
|
+
.type-details summary .type-name{min-width:0; display:inline-flex; align-items:center; gap:.45rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
|
|
916
|
+
.type-details summary .type-name b{overflow:hidden; text-overflow:ellipsis}
|
|
917
|
+
.type-details .type-icon{flex:0 0 auto; display:grid; place-items:center; width:1.25rem; height:1.25rem; border-radius:.4rem; font-size:.55rem; font-weight:800; letter-spacing:.04em; border:1px solid rgba(84,183,255,.35); background:linear-gradient(135deg, rgba(38,130,225,.3), rgba(90,67,183,.26)); color:#9fd4ff; box-shadow:0 0 10px rgba(84,183,255,.18)}
|
|
918
|
+
.type-details .type-icon.kind-input{color:#c4b5fd; border-color:rgba(139,92,246,.4); background:linear-gradient(135deg, rgba(124,58,237,.3), rgba(90,67,183,.26))}
|
|
919
|
+
.type-details .type-icon.kind-enum{color:#ffd479; border-color:rgba(245,158,11,.4); background:linear-gradient(135deg, rgba(245,158,11,.26), rgba(180,83,9,.2))}
|
|
920
|
+
.type-details .type-icon.kind-scalar{color:#6df0bb; border-color:rgba(52,211,153,.4); background:linear-gradient(135deg, rgba(16,185,129,.26), rgba(6,95,70,.2))}
|
|
921
|
+
.type-details .type-kind{flex:0 0 auto; font-size:.5rem; padding:.12rem .4rem; border-radius:999px; background:rgba(159,123,255,.15); color:#c4b5fd; border:1px solid rgba(139,92,246,.3); font-weight:800; letter-spacing:.08em; text-transform:uppercase}
|
|
922
|
+
.type-details .type-chevron{flex:0 0 auto; display:grid; place-items:center; width:1.1rem; height:1.1rem; border-radius:.35rem; color:#5f7b9c; font-size:.6rem; transition:transform .18s, color .14s, background .14s}
|
|
923
|
+
.type-details summary:hover .type-chevron{color:#9fd4ff; background:rgba(84,183,255,.14)}
|
|
924
|
+
.type-details details[open] .type-chevron{transform:rotate(90deg)}
|
|
925
|
+
.type-details .type-body{padding:.6rem .7rem .7rem .85rem; display:flex; flex-direction:column; gap:.5rem}
|
|
926
|
+
.type-details .type-desc{margin:0; font-size:.58rem; color:#5f7b9c; line-height:1.55; padding:.35rem .6rem; border-radius:.45rem; background:rgba(84,183,255,.05); border-left:2px solid rgba(84,183,255,.3)}
|
|
927
|
+
.type-details .type-subhead{font-size:.5rem; letter-spacing:.13em; text-transform:uppercase; color:#5f7b9c; font-weight:800; padding-left:.15rem}
|
|
928
|
+
.type-details .type-fields{display:flex; flex-direction:column; gap:.4rem; min-width:0}
|
|
929
|
+
.type-details .type-field{font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.6rem; padding:.34rem .55rem; border-radius:.45rem; background:rgba(8,25,48,.6); color:#dcecff; display:flex; justify-content:space-between; align-items:center; gap:.5rem; min-width:0; border:1px solid rgba(112,168,228,.17); box-shadow:inset 0 1px rgba(255,255,255,.04); transition:border-color .14s, transform .14s, background .14s}
|
|
930
|
+
.type-details .type-field:hover{border-color:rgba(84,183,255,.5); transform:translateY(-1px); background:rgba(84,183,255,.1)}
|
|
931
|
+
.type-details .type-field > span{min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
|
|
932
|
+
.type-details .type-field code.hljs{display:inline; background:transparent; padding:0; color:#e8f2ff; white-space:nowrap}
|
|
933
|
+
.type-details .type-field b{color:#8ed6ff; font-weight:600}
|
|
934
|
+
.type-details .type-field .tok-arg{color:#ffd479}
|
|
935
|
+
.type-details .type-field .tok-type{color:#c4b5fd}
|
|
936
|
+
.type-details .type-field-arrow{flex:0 0 auto; display:inline-flex; align-items:center; gap:.28rem; font-size:.54rem; font-weight:800; letter-spacing:.06em; text-transform:uppercase; color:#9fd4ff; cursor:pointer; padding:.22rem .45rem; border-radius:.4rem; border:1px solid rgba(84,183,255,.35); background:rgba(84,183,255,.1); transition:border-color .12s, background .12s, color .12s, transform .12s}
|
|
937
|
+
.type-details .type-field-arrow:hover{color:#eaf7ff; border-color:rgba(84,183,255,.65); background:rgba(40,137,235,.24); transform:translateX(2px)}
|
|
938
|
+
.type-filter{margin:.45rem .7rem 0; padding:.42rem .6rem; border-radius:.5rem; border:1px solid rgba(112,168,228,.22); background:rgba(20,46,79,.32); color:#e5f4ff; font-size:.62rem; width:calc(100% - 1.4rem); outline:none; transition:border-color .14s, box-shadow .14s}
|
|
939
|
+
.type-filter::placeholder{color:#536c8c}
|
|
940
|
+
.type-filter:focus{border-color:rgba(84,183,255,.55); box-shadow:0 0 0 2px rgba(84,183,255,.15)}
|
|
941
|
+
/* FAB + chat popup (agent glass) */
|
|
942
|
+
.fab{position:fixed; right:1.25rem; bottom:1.25rem; width:3.4rem; height:3.4rem; border-radius:50%; border:1px solid rgba(84,183,255,.42); background:linear-gradient(135deg, rgba(38,130,225,.75), rgba(90,67,183,.65)); color:#fff; font-size:1.25rem; font-weight:800; cursor:pointer; box-shadow:0 0 24px rgba(58,149,255,.4), 0 10px 30px rgba(0,0,0,.4); display:grid; place-items:center; z-index:30; transition:transform .15s, filter .15s; animation:agent-rise .3s cubic-bezier(.22,1,.36,1) both}
|
|
943
|
+
.fab:hover{transform:translateY(-2px); filter:brightness(1.12)}
|
|
944
|
+
.fab:active{transform:scale(.94)}
|
|
945
|
+
.ai-popup{position:fixed; right:1.25rem; bottom:5.4rem; width:24rem; max-width:calc(100vw - 2rem); height:32rem; max-height:70vh; border:1px solid rgba(99,189,255,.28); border-radius:.9rem; background:linear-gradient(160deg, rgba(12,34,64,.96), rgba(6,16,36,.98)); box-shadow:inset 0 1px rgba(255,255,255,.06), 0 30px 90px rgba(0,0,0,.6), 0 0 40px rgba(84,183,255,.12); display:flex; flex-direction:column; overflow:hidden; z-index:30; backdrop-filter:blur(22px) saturate(140%); -webkit-backdrop-filter:blur(22px) saturate(140%); animation:agent-rise .25s cubic-bezier(.22,1,.36,1) both}
|
|
946
|
+
.ai-popup[hidden]{display:none !important}
|
|
947
|
+
.ai-popup-head{padding:.6rem .8rem; display:flex; justify-content:space-between; align-items:center; border-bottom:1px solid rgba(112,168,228,.14); font-size:.62rem; letter-spacing:.12em; text-transform:uppercase; color:#5f7b9c; font-family:ui-monospace, SFMono-Regular, Consolas, monospace}
|
|
948
|
+
.ai-popup-head button{border:1px solid rgba(112,168,228,.24); background:rgba(84,183,255,.08); color:#9fd4ff; width:1.7rem; height:1.7rem; border-radius:.45rem; cursor:pointer; transition:border-color .14s, color .14s}
|
|
949
|
+
.ai-popup-head button:hover{border-color:rgba(84,183,255,.55); color:#fff}
|
|
950
|
+
.ai-chat{flex:1; overflow:auto; padding:.75rem; display:flex; flex-direction:column; gap:.55rem}
|
|
951
|
+
.ai-chat .msg{display:flex; flex-direction:column; max-width:88%; gap:.3rem; animation:agent-rise .25s cubic-bezier(.22,1,.36,1) both}
|
|
952
|
+
.ai-chat .msg.user{align-self:flex-end; align-items:flex-end}
|
|
953
|
+
.ai-chat .msg.ai{align-self:flex-start; align-items:flex-start}
|
|
954
|
+
.ai-chat .bubble{padding:.6rem .8rem; border:1px solid rgba(112,168,228,.22); border-radius:.8rem; color:#dcecff; background:linear-gradient(160deg, rgba(16,38,70,.5), rgba(8,20,42,.56)); font-size:.78rem; line-height:1.65; white-space:pre-wrap; overflow-wrap:anywhere; word-break:break-word; box-shadow:inset 0 1px rgba(255,255,255,.05), 0 14px 42px rgba(0,0,0,.2); backdrop-filter:blur(18px) saturate(135%); -webkit-backdrop-filter:blur(18px) saturate(135%)}
|
|
955
|
+
.ai-chat .user .bubble{border-color:rgba(84,183,255,.42); background:linear-gradient(160deg, rgba(22,70,122,.58), rgba(46,41,112,.5)); color:#eaf7ff}
|
|
956
|
+
.ai-chat .bubble pre{margin:.4rem 0 0; padding:.55rem .7rem; border-radius:.55rem; background:#000; border:1px solid rgba(112,168,228,.12); font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:.64rem; overflow:auto; white-space:pre-wrap}
|
|
957
|
+
.ai-chat .bubble pre .hljs{background:transparent; padding:0; color:#e8f2ff}
|
|
958
|
+
.ai-chat .insert{margin-top:.4rem; padding:.28rem .6rem; border-radius:.45rem; border:1px solid rgba(84,183,255,.4); background:rgba(84,183,255,.12); color:#9fd4ff; font-size:.58rem; font-weight:700; cursor:pointer; transition:border-color .14s, background .14s, transform .14s; font-family:ui-monospace, SFMono-Regular, Consolas, monospace}
|
|
959
|
+
.ai-chat .insert:hover{border-color:rgba(84,183,255,.75); color:#fff; background:rgba(40,137,235,.28); transform:translateY(-1px)}
|
|
960
|
+
.ai-chat .typing{font-size:.6rem; color:#6e8aaa; font-style:italic}
|
|
961
|
+
.ai-form{padding:.65rem; border-top:1px solid rgba(112,168,228,.14); display:flex; gap:.5rem; align-items:flex-end}
|
|
962
|
+
.ai-form textarea{flex:1; min-height:2.4rem; max-height:6rem; border-radius:.55rem; border:1px solid rgba(112,168,228,.24); background:rgba(255,255,255,.05); color:#e8f2ff; padding:.5rem .65rem; font-size:.76rem; resize:none; outline:none; transition:border-color .14s, box-shadow .14s}
|
|
963
|
+
.ai-form textarea::placeholder{color:#5b7392}
|
|
964
|
+
.ai-form textarea:focus{border-color:rgba(84,183,255,.6); box-shadow:0 0 0 3px rgba(84,183,255,.14)}
|
|
965
|
+
.ai-form button{padding:.55rem 1rem; border:1px solid rgba(84,183,255,.55); border-radius:.55rem; color:#fff; background:linear-gradient(135deg, rgba(38,130,225,.75), rgba(90,67,183,.65)); box-shadow:0 8px 24px rgba(84,183,255,.28); font-size:.7rem; font-weight:800; cursor:pointer; white-space:nowrap; transition:transform .15s, filter .15s}
|
|
966
|
+
.ai-form button:hover:not(:disabled){filter:brightness(1.1); transform:translateY(-1px)}
|
|
967
|
+
.ai-form button:disabled{opacity:.4; cursor:not-allowed}
|
|
968
|
+
/* Theme (dark only) */
|
|
969
|
+
/* Light theme overrides */
|
|
970
|
+
[data-theme="light"] body{background:#eef3fb; color:#0b1220}
|
|
971
|
+
[data-theme="light"] .agent-shell{background:#eef3fb}
|
|
972
|
+
[data-theme="light"] .agent-shell::before{opacity:.25; background-image:linear-gradient(rgba(30,80,160,.06) 1px, transparent 1px), linear-gradient(90deg, rgba(30,80,160,.06) 1px, transparent 1px)}
|
|
973
|
+
[data-theme="light"] .agent-aurora i{opacity:.22; mix-blend-mode:multiply}
|
|
974
|
+
[data-theme="light"] .agent-header{background:linear-gradient(180deg, rgba(255,255,255,.9), rgba(235,242,252,.8)); border-bottom-color:rgba(60,110,180,.18)}
|
|
975
|
+
[data-theme="light"] .agent-brand-name{color:#0b1220}
|
|
976
|
+
[data-theme="light"] .agent-brand-sub{color:#5a6b84}
|
|
977
|
+
[data-theme="light"] .graphiql-panel{background:linear-gradient(160deg, rgba(255,255,255,.7), rgba(240,246,255,.75)); border-color:rgba(60,110,180,.16); box-shadow:inset 0 1px rgba(255,255,255,.6), 0 18px 50px rgba(20,50,100,.12)}
|
|
978
|
+
[data-theme="light"] .panel-head{color:#4a5c78; border-bottom-color:rgba(60,110,180,.14)}
|
|
979
|
+
[data-theme="light"] .ops .op{background:rgba(255,255,255,.72); border-color:rgba(60,110,180,.16); box-shadow:inset 0 1px rgba(255,255,255,.6)}
|
|
980
|
+
[data-theme="light"] .ops .op b{color:#0b1220}
|
|
981
|
+
[data-theme="light"] .ops .op:hover{background:rgba(84,183,255,.14)}
|
|
982
|
+
[data-theme="light"] .type-details details{background:rgba(255,255,255,.72); border-color:rgba(60,110,180,.16); box-shadow:inset 0 1px rgba(255,255,255,.6)}
|
|
983
|
+
[data-theme="light"] .type-details details:hover{background:rgba(84,183,255,.14); border-color:rgba(60,110,180,.3)}
|
|
984
|
+
[data-theme="light"] .type-details summary{color:#0b1220}
|
|
985
|
+
[data-theme="light"] .type-details summary:hover{background:rgba(84,183,255,.14)}
|
|
986
|
+
[data-theme="light"] .type-details .type-desc{color:#5a6b84; background:rgba(60,110,180,.06); border-left-color:rgba(60,110,180,.35)}
|
|
987
|
+
[data-theme="light"] .type-details .type-field{background:rgba(255,255,255,.72); color:#0b1220; border-color:rgba(60,110,180,.16); box-shadow:inset 0 1px rgba(255,255,255,.6)}
|
|
988
|
+
[data-theme="light"] .type-details .type-field:hover{background:rgba(84,183,255,.14); border-color:rgba(60,110,180,.3)}
|
|
989
|
+
[data-theme="light"] .type-details .type-field b{color:#1d6fd0}
|
|
990
|
+
[data-theme="light"] .type-details .type-field .hljs{color:#0b1220}
|
|
991
|
+
[data-theme="light"] .ai-hint, [data-theme="light"] .type-details .type-desc{color:#5a6b84}
|
|
992
|
+
[data-theme="light"] .history div{color:#3a4c68}
|
|
993
|
+
[data-theme="light"] .ai-popup{background:linear-gradient(160deg, rgba(255,255,255,.96), rgba(238,245,255,.97)); border-color:rgba(60,110,180,.2)}
|
|
994
|
+
[data-theme="light"] .ai-chat .bubble{background:rgba(240,246,255,.8); color:#16233c; border-color:rgba(60,110,180,.18)}
|
|
995
|
+
[data-theme="light"] .ai-chat .user .bubble{background:linear-gradient(160deg, rgba(84,183,255,.35), rgba(120,110,230,.3)); color:#0b1220}
|
|
996
|
+
[data-theme="light"] .ai-chat .bubble pre{background:#000; border-color:rgba(112,168,228,.15)}
|
|
997
|
+
[data-theme="light"] .ai-chat .bubble pre .hljs{color:#e8f2ff}
|
|
998
|
+
[data-theme="light"] .type-filter{background:rgba(255,255,255,.8); color:#0b1220; border-color:rgba(60,110,180,.2)}
|
|
999
|
+
@media (max-width: 960px){ .ai-popup{right:.75rem; left:.75rem; width:auto} }
|
|
1000
|
+
</style>
|
|
1001
|
+
</head>
|
|
1002
|
+
<body class="graphiql-dark">
|
|
1003
|
+
<div class="agent-shell">
|
|
1004
|
+
<div class="agent-aurora"><i></i><i></i><i></i></div>
|
|
1005
|
+
|
|
1006
|
+
<header class="agent-header">
|
|
1007
|
+
<div class="agent-header-inner">
|
|
1008
|
+
<span class="agent-brand">
|
|
1009
|
+
<span class="agent-brand-badge"><span class="agent-brand-dot"></span></span>
|
|
1010
|
+
<span class="agent-brand-text">
|
|
1011
|
+
<span class="agent-brand-name">${escapeHtml(appName)} <em>GraphQL</em></span>
|
|
1012
|
+
<span class="agent-brand-sub">${escapeHtml(endpoint)} · ${introspection ? 'introspection on' : 'introspection off'}</span>
|
|
1013
|
+
</span>
|
|
1014
|
+
</span>
|
|
1015
|
+
<span class="agent-spacer"></span>
|
|
1016
|
+
<span class="agent-status"><span class="agent-status-dot"></span>Live</span>
|
|
1017
|
+
<span class="agent-select-wrap"><span class="agent-select-label">POST</span><span class="agent-select-label" style="color:#9fd4ff">${escapeHtml(endpoint)}</span></span>
|
|
1018
|
+
</div>
|
|
1019
|
+
<div class="agent-urlbar">
|
|
1020
|
+
<span class="agent-urlbar-lock" title="Secure connection">🔒</span>
|
|
1021
|
+
<span class="agent-urlbar-input">
|
|
1022
|
+
<input class="agent-urlbar-field" id="urlbar" type="text" aria-label="GraphQL endpoint URL" spellcheck="false" />
|
|
1023
|
+
</span>
|
|
1024
|
+
<button class="agent-urlbar-btn" id="urlbar-copy" aria-label="Copy URL" title="Copy URL"><svg viewBox="0 0 24 24" width="13" height="13" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg></button>
|
|
1025
|
+
<button class="agent-urlbar-btn" id="urlbar-refresh" aria-label="Reload explorer" title="Reload">↻</button>
|
|
1026
|
+
<span class="agent-urlbar-note">POST</span>
|
|
1027
|
+
</div>
|
|
1028
|
+
</header>
|
|
1029
|
+
|
|
1030
|
+
<main class="agent-workspace">
|
|
1031
|
+
<section class="agent-main graphiql-panel">
|
|
1032
|
+
<div class="panel-head"><span>Explorer</span><span style="opacity:.6">GraphiQL 3</span></div>
|
|
1033
|
+
<div id="graphiql">Loading…</div>
|
|
1034
|
+
</section>
|
|
1035
|
+
|
|
1036
|
+
<aside class="agent-side">
|
|
1037
|
+
<div class="panel-head" style="border-radius:.6rem .6rem 0 0"><span>Available Operations</span><span style="opacity:.6">${operations.length ? operations.length + ' fields' : 'no schema'}</span></div>
|
|
1038
|
+
<div class="ops" id="ops">
|
|
1039
|
+
${operations.length ? operations.map(op => `
|
|
1040
|
+
<div class="op ${op.type === 'Mutation' ? 'mutation' : ''}" data-query="${escapeHtml(op.example)}">
|
|
1041
|
+
<b>${escapeHtml(op.field)}${op.args ? `<span style="font-weight:400; opacity:.7">(${escapeHtml(op.args)})</span>` : ''}</b>
|
|
1042
|
+
<span>${op.type}</span>
|
|
1043
|
+
</div>`).join('') : `<div class="ai-hint" style="padding:8px">No typedefs discovered yet. <b>hello</b> is always available — try <code>{ hello }</code> below.<br>Add more: <code>npx nexus make:subgraph post --app backend</code> (creates a real Post model).<br><br>SDL preview:<br><pre style="white-space:pre-wrap; font-size:11px; opacity:.7">${escapeHtml(rawSdl.slice(0,600) || 'empty')}</pre></div>`}
|
|
1044
|
+
</div>
|
|
1045
|
+
<div class="ai-hint" style="padding:0 .8rem .6rem">Click a field to insert its example. Open <b>Docs</b> in GraphiQL (left) to browse full schema. Builtin: <code>hello</code> + <code>ping(message)</code> always visible; added subgraphs appear live via introspection.</div>
|
|
1046
|
+
|
|
1047
|
+
<div class="panel-head" style="margin-top:.4rem; border-radius:.6rem .6rem 0 0"><span>History</span><span class="panel-head-actions"><button id="history-clear" class="graphiql-history-clear" title="Clear history">Clear</button><button id="history-toggle" class="graphiql-history-btn" title="Toggle history">Show</button></span></div>
|
|
1048
|
+
<div class="history" id="history" hidden><div class="ai-hint" style="padding:8px">No history yet</div></div>
|
|
1049
|
+
|
|
1050
|
+
<div class="panel-head" style="margin-top:.4rem; border-radius:.6rem .6rem 0 0"><span>Type Details</span><span style="opacity:.6" id="types-count">loading…</span></div>
|
|
1051
|
+
<input class="type-filter" id="type-filter" placeholder="Filter types/fields…" />
|
|
1052
|
+
<div class="type-details" id="types"><div class="ai-hint" style="padding:8px">Loading complete schema via introspection…</div></div>
|
|
1053
|
+
|
|
1054
|
+
</aside>
|
|
1055
|
+
</main>
|
|
1056
|
+
</div>
|
|
1057
|
+
|
|
1058
|
+
<!-- Alert toast (top-right corner) — shows URL copied / query copied / success / failure -->
|
|
1059
|
+
<div class="agent-alert hide" id="agent-alert" role="status">
|
|
1060
|
+
<div class="agent-alert-mark" id="agent-alert-mark">✓</div>
|
|
1061
|
+
<div class="agent-alert-body">
|
|
1062
|
+
<strong class="agent-alert-title" id="agent-alert-title">Success</strong>
|
|
1063
|
+
<span class="agent-alert-msg" id="agent-alert-msg"></span>
|
|
1064
|
+
</div>
|
|
1065
|
+
<button class="agent-alert-close" id="agent-alert-close" aria-label="Dismiss" title="Dismiss">×</button>
|
|
1066
|
+
</div>
|
|
1067
|
+
|
|
1068
|
+
<!-- AI Assistant FAB + Chat Popup -->
|
|
1069
|
+
<button id="ai-fab" class="fab" aria-label="AI Assistant" title="AI Assistant">✦</button>
|
|
1070
|
+
<div id="ai-popup" class="ai-popup" hidden>
|
|
1071
|
+
<div class="ai-popup-head"><span>AI Assistant <span style="opacity:.6" id="ai-model-label"></span></span><button id="ai-close" aria-label="Close">×</button></div>
|
|
1072
|
+
<div id="ai-chat" class="ai-chat"><div class="ai-hint" style="padding:8px">Hi! Describe what you want in GraphQL and I’ll generate a query from your live schema. Try: “Show posts with authors”.</div></div>
|
|
1073
|
+
<form id="ai-form" class="ai-form">
|
|
1074
|
+
<textarea id="ai-prompt" placeholder="Ask about your schema, e.g. 'Show the 5 latest posts with author names'" rows="2"></textarea>
|
|
1075
|
+
<button type="submit" id="ai-send">Send</button>
|
|
1076
|
+
</form>
|
|
1077
|
+
<div id="ai-status" class="ai-hint" style="padding:6px 12px"></div>
|
|
1078
|
+
</div>
|
|
1079
|
+
|
|
1080
|
+
<script src="${CDN.hljsJs}"></script>
|
|
1081
|
+
<script crossorigin src="${CDN.react}"></script>
|
|
1082
|
+
<script crossorigin src="${CDN.reactDom}"></script>
|
|
1083
|
+
<script src="${CDN.graphiqlJs}"></script>
|
|
1084
|
+
<script>
|
|
1085
|
+
const endpoint = ${JSON.stringify(endpoint)};
|
|
1086
|
+
const sdlPreview = ${JSON.stringify(sdlPreview)};
|
|
1087
|
+
const rawSdlClient = ${JSON.stringify(rawSdl.slice(0,4000))};
|
|
1088
|
+
const STORAGE_KEY = 'nexus-graphql-history';
|
|
1089
|
+
|
|
1090
|
+
// \u2192 Unified tooltips: convert every native title to a styled data-tip
|
|
1091
|
+
// so all tooltips share one look (header, urlbar, history, FAB, fields...).
|
|
1092
|
+
function initTooltips(root){
|
|
1093
|
+
(root || document).querySelectorAll('[title]').forEach(function(el){
|
|
1094
|
+
if (el.hasAttribute('data-tip') || el.getAttribute('title') === '') return;
|
|
1095
|
+
el.setAttribute('data-tip', el.getAttribute('title'));
|
|
1096
|
+
el.removeAttribute('title');
|
|
1097
|
+
});
|
|
1098
|
+
}
|
|
1099
|
+
initTooltips(document);
|
|
1100
|
+
|
|
1101
|
+
// \u2192 Alert toast (top-right) — show success / error / info messages.
|
|
1102
|
+
const agentAlert = document.getElementById('agent-alert');
|
|
1103
|
+
const agentAlertClose = document.getElementById('agent-alert-close');
|
|
1104
|
+
const agentAlertMark = document.getElementById('agent-alert-mark');
|
|
1105
|
+
const agentAlertTitle = document.getElementById('agent-alert-title');
|
|
1106
|
+
const agentAlertMsg = document.getElementById('agent-alert-msg');
|
|
1107
|
+
let agentAlertTimer = null;
|
|
1108
|
+
function showAlert(title, msg, kind){
|
|
1109
|
+
if (!agentAlert || !agentAlertTitle || !agentAlertMsg) return;
|
|
1110
|
+
kind = kind || 'success';
|
|
1111
|
+
agentAlert.classList.remove('is-error', 'is-info');
|
|
1112
|
+
if (kind === 'error') agentAlert.classList.add('is-error');
|
|
1113
|
+
else if (kind === 'info') agentAlert.classList.add('is-info');
|
|
1114
|
+
agentAlertMark.textContent = kind === 'error' ? '!' : kind === 'info' ? 'i' : '✓';
|
|
1115
|
+
agentAlertTitle.textContent = title;
|
|
1116
|
+
agentAlertMsg.textContent = msg;
|
|
1117
|
+
agentAlert.classList.remove('hide');
|
|
1118
|
+
agentAlert.classList.add('show');
|
|
1119
|
+
if (agentAlertTimer) clearTimeout(agentAlertTimer);
|
|
1120
|
+
agentAlertTimer = setTimeout(function(){
|
|
1121
|
+
agentAlert.classList.remove('show');
|
|
1122
|
+
agentAlert.classList.add('hide');
|
|
1123
|
+
}, 3500);
|
|
1124
|
+
}
|
|
1125
|
+
if (agentAlertClose) {
|
|
1126
|
+
agentAlertClose.addEventListener('click', function(){
|
|
1127
|
+
agentAlert.classList.remove('show');
|
|
1128
|
+
agentAlert.classList.add('hide');
|
|
1129
|
+
if (agentAlertTimer) clearTimeout(agentAlertTimer);
|
|
1130
|
+
});
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
// \u2192 Editable/copyable URL bar (below the header) — shows the live GraphQL endpoint.
|
|
1134
|
+
const urlbar = document.getElementById('urlbar');
|
|
1135
|
+
const copyBtn = document.getElementById('urlbar-copy');
|
|
1136
|
+
const refreshBtn = document.getElementById('urlbar-refresh');
|
|
1137
|
+
if (urlbar) {
|
|
1138
|
+
const fullUrl = window.location.origin + endpoint;
|
|
1139
|
+
urlbar.value = fullUrl;
|
|
1140
|
+
urlbar.addEventListener('focus', function () { this.select(); });
|
|
1141
|
+
if (copyBtn) {
|
|
1142
|
+
copyBtn.addEventListener('click', function () {
|
|
1143
|
+
const val = urlbar.value;
|
|
1144
|
+
function done() {
|
|
1145
|
+
copyBtn.classList.add('copied');
|
|
1146
|
+
copyBtn.innerHTML = '<svg viewBox="0 0 24 24" width="13" height="13" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="20 6 9 17 4 12"/></svg>';
|
|
1147
|
+
showAlert('URL copied', 'GraphQL endpoint copied to clipboard.', 'success');
|
|
1148
|
+
setTimeout(function () {
|
|
1149
|
+
copyBtn.classList.remove('copied');
|
|
1150
|
+
copyBtn.innerHTML = '<svg viewBox="0 0 24 24" width="13" height="13" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>';
|
|
1151
|
+
}, 1200);
|
|
1152
|
+
}
|
|
1153
|
+
function fail() {
|
|
1154
|
+
showAlert('Copy failed', 'Could not copy the URL to your clipboard.', 'error');
|
|
1155
|
+
}
|
|
1156
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
1157
|
+
navigator.clipboard.writeText(val).then(done, function () { urlbar.select(); try { document.execCommand('copy'); done(); } catch (e) { fail(); } });
|
|
1158
|
+
} else {
|
|
1159
|
+
urlbar.select();
|
|
1160
|
+
try { document.execCommand('copy'); done(); } catch (e) { fail(); }
|
|
1161
|
+
}
|
|
1162
|
+
});
|
|
1163
|
+
}
|
|
1164
|
+
if (refreshBtn) refreshBtn.addEventListener('click', function () { location.reload(); });
|
|
1165
|
+
// After executing a query, append it (URL-encoded) so the bar stays in sync.
|
|
1166
|
+
// Mutations also append a fresh csrf token so the copied URL works when the
|
|
1167
|
+
// nexus_csrf cookie is present (same browser/device).
|
|
1168
|
+
window.__updateUrlbar = function (q, token) {
|
|
1169
|
+
if (!urlbar || !q || !q.trim()) return;
|
|
1170
|
+
if (q.indexOf('__schema') !== -1 || q.indexOf('__type') !== -1) return; // ignore introspection
|
|
1171
|
+
let url = window.location.origin + endpoint + '?query=' + encodeURIComponent(q);
|
|
1172
|
+
if (token && /^\s*mutation\b/.test(q)) url += '&csrf=' + encodeURIComponent(token);
|
|
1173
|
+
urlbar.value = url;
|
|
1174
|
+
};
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
let csrfToken = null;
|
|
1178
|
+
|
|
1179
|
+
// \u2192 Dark-only theme — force GraphiQL's dark palette (its CDN ignores
|
|
1180
|
+
// [data-theme] unless body.graphiql-dark is present).
|
|
1181
|
+
document.documentElement.setAttribute('data-theme', 'dark');
|
|
1182
|
+
document.body.classList.add('graphiql-dark');
|
|
1183
|
+
|
|
1184
|
+
// ── highlight.js helper (mirrors Agent.tsx highlightCode) ──
|
|
1185
|
+
function escapeHtml(s){ return s.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"'); }
|
|
1186
|
+
function highlightCode(code, lang){
|
|
1187
|
+
try{
|
|
1188
|
+
var hl = window.hljs;
|
|
1189
|
+
if(hl){
|
|
1190
|
+
if(lang && hl.getLanguage(lang)) return hl.highlight(code, { language: lang }).value;
|
|
1191
|
+
return hl.highlightAuto(code).value;
|
|
1192
|
+
}
|
|
1193
|
+
}catch(e){}
|
|
1194
|
+
return escapeHtml(code);
|
|
1195
|
+
}
|
|
1196
|
+
async function ensureCsrf(){
|
|
1197
|
+
if(csrfToken) return csrfToken;
|
|
1198
|
+
try{
|
|
1199
|
+
const r = await fetch('/csrf-token', { credentials: 'include' });
|
|
1200
|
+
if(r.ok){ const j = await r.json(); if(j && j.token) csrfToken = j.token; }
|
|
1201
|
+
if(!csrfToken){
|
|
1202
|
+
const m = document.cookie.match(/(?:^|; )csrf_token=([^;]+)/);
|
|
1203
|
+
if(m) csrfToken = decodeURIComponent(m[1]);
|
|
1204
|
+
}
|
|
1205
|
+
if(!csrfToken){
|
|
1206
|
+
const m2 = document.cookie.match(/(?:^|; )XSRF-TOKEN=([^;]+)/);
|
|
1207
|
+
if(m2) csrfToken = decodeURIComponent(m2[1]);
|
|
1208
|
+
}
|
|
1209
|
+
}catch(e){}
|
|
1210
|
+
return csrfToken;
|
|
1211
|
+
}
|
|
1212
|
+
// prefetch csrf in background
|
|
1213
|
+
ensureCsrf();
|
|
1214
|
+
|
|
1215
|
+
async function fetcher(params, opts) {
|
|
1216
|
+
try {
|
|
1217
|
+
const token = await ensureCsrf();
|
|
1218
|
+
const headers = { 'Content-Type': 'application/json', ...(opts && opts.headers ? opts.headers : {}) };
|
|
1219
|
+
if(token) headers['X-CSRF-Token'] = token;
|
|
1220
|
+
// Mutations require a CSRF token passed as an argument (body.csrf).
|
|
1221
|
+
const payload = Object.assign({}, params);
|
|
1222
|
+
if (token && params && params.query && /^\s*mutation\b/.test(params.query)) {
|
|
1223
|
+
payload.csrf = token;
|
|
1224
|
+
if (payload.variables && typeof payload.variables === 'object') {
|
|
1225
|
+
const vars = Object.assign({}, payload.variables);
|
|
1226
|
+
vars.csrf = token;
|
|
1227
|
+
payload.variables = vars;
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
return fetch(endpoint, {
|
|
1231
|
+
method: 'POST',
|
|
1232
|
+
credentials: 'include',
|
|
1233
|
+
headers: headers,
|
|
1234
|
+
body: JSON.stringify(payload),
|
|
1235
|
+
}).then(function(r){
|
|
1236
|
+
if(!r.ok) throw new Error('GraphiQL request failed: ' + r.status);
|
|
1237
|
+
if (typeof window.__updateUrlbar === 'function' && params && params.query) window.__updateUrlbar(params.query, token);
|
|
1238
|
+
return r.json();
|
|
1239
|
+
}).then(function(json){
|
|
1240
|
+
if (json && json.errors && json.errors.length) {
|
|
1241
|
+
showAlert('Query error', (json.errors[0] && json.errors[0].message) || 'The query returned errors.', 'error');
|
|
1242
|
+
} else if (params && params.query && params.query.indexOf('__schema') === -1) {
|
|
1243
|
+
showAlert('Success', 'Query executed successfully.', 'success');
|
|
1244
|
+
}
|
|
1245
|
+
return json;
|
|
1246
|
+
});
|
|
1247
|
+
} catch(e) {
|
|
1248
|
+
console.error('GraphiQL fetcher error:', e);
|
|
1249
|
+
showAlert('Request failed', (e && e.message) || 'Could not reach the GraphQL endpoint.', 'error');
|
|
1250
|
+
return Promise.reject(e);
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
function saveHistory(query) {
|
|
1255
|
+
if (!query || !query.trim()) return;
|
|
1256
|
+
try {
|
|
1257
|
+
const list = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]');
|
|
1258
|
+
const next = [query, ...list.filter(q => q !== query)].slice(0, 20);
|
|
1259
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(next));
|
|
1260
|
+
renderHistory();
|
|
1261
|
+
} catch {}
|
|
1262
|
+
}
|
|
1263
|
+
function renderHistory() {
|
|
1264
|
+
const el = document.getElementById('history');
|
|
1265
|
+
if (!el) return;
|
|
1266
|
+
try {
|
|
1267
|
+
const list = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]');
|
|
1268
|
+
el.innerHTML = list.length ? list.map(q => \`<div data-tip="\${q.replace(/"/g,'"')}" title="\${q.replace(/"/g,'"')}">\${q.slice(0,80)}</div>\`).join('') : '<div style="opacity:.5">No history yet</div>';
|
|
1269
|
+
el.querySelectorAll('div').forEach(div => div.addEventListener('click', () => {
|
|
1270
|
+
const q = div.getAttribute('title');
|
|
1271
|
+
if (window._graphiql) window._graphiql.setQuery(q);
|
|
1272
|
+
}));
|
|
1273
|
+
} catch {}
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
const historyClearBtn = document.getElementById('history-clear');
|
|
1277
|
+
if (historyClearBtn) {
|
|
1278
|
+
historyClearBtn.addEventListener('click', () => {
|
|
1279
|
+
try { localStorage.removeItem(STORAGE_KEY); } catch {}
|
|
1280
|
+
renderHistory();
|
|
1281
|
+
});
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
const historyToggleBtn = document.getElementById('history-toggle');
|
|
1285
|
+
const historyPanel = document.getElementById('history');
|
|
1286
|
+
if (historyToggleBtn && historyPanel) {
|
|
1287
|
+
const sync = () => {
|
|
1288
|
+
historyToggleBtn.textContent = historyPanel.hidden ? 'Show' : 'Hide';
|
|
1289
|
+
historyToggleBtn.classList.toggle('active', !historyPanel.hidden);
|
|
1290
|
+
};
|
|
1291
|
+
sync();
|
|
1292
|
+
historyToggleBtn.addEventListener('click', () => {
|
|
1293
|
+
historyPanel.hidden = !historyPanel.hidden;
|
|
1294
|
+
sync();
|
|
1295
|
+
});
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
|
|
1299
|
+
// Mount GraphiQL
|
|
1300
|
+
const defaultQuery = ${JSON.stringify(defaultQuery)};
|
|
1301
|
+
const root = ReactDOM.createRoot(document.getElementById('graphiql'));
|
|
1302
|
+
const graphiql = React.createElement(GraphiQL, {
|
|
1303
|
+
fetcher,
|
|
1304
|
+
defaultQuery,
|
|
1305
|
+
onEditQuery: (q) => saveHistory(q),
|
|
1306
|
+
isHeadersEditorEnabled: true,
|
|
1307
|
+
shouldPersistHeaders: true,
|
|
1308
|
+
});
|
|
1309
|
+
root.render(graphiql);
|
|
1310
|
+
// Expose for AI/history/ops
|
|
1311
|
+
window._graphiql = {
|
|
1312
|
+
setQuery: (q) => {
|
|
1313
|
+
try { localStorage.setItem('graphiql:query', q); location.reload(); } catch { alert(q); }
|
|
1314
|
+
}
|
|
1315
|
+
};
|
|
1316
|
+
// Click operation → insert example
|
|
1317
|
+
function bindOps() {
|
|
1318
|
+
document.querySelectorAll('#ops .op').forEach(el => {
|
|
1319
|
+
el.addEventListener('click', () => {
|
|
1320
|
+
const q = el.getAttribute('data-query');
|
|
1321
|
+
if (q) {
|
|
1322
|
+
try { localStorage.setItem('graphiql:query', q); location.reload(); } catch {}
|
|
1323
|
+
}
|
|
1324
|
+
});
|
|
1325
|
+
});
|
|
1326
|
+
}
|
|
1327
|
+
bindOps();
|
|
1328
|
+
renderHistory();
|
|
1329
|
+
|
|
1330
|
+
// Live introspection refresh — discovers hello + any added subgraph and renders full type details
|
|
1331
|
+
(function refreshOpsFromIntrospection(){
|
|
1332
|
+
const INTROSPECTION_QUERY = '{ __schema { queryType { name fields { name description args { name description type { name kind ofType { name kind ofType { name kind } } } } type { name kind ofType { name kind ofType { name kind } } } } } mutationType { name fields { name description args { name description type { name kind ofType { name kind } } } type { name kind ofType { name kind } } } } subscriptionType { name fields { name description args { name description type { name kind ofType { name kind } } } type { name kind ofType { name kind } } } } types { name kind description fields(includeDeprecated:false) { name description args { name description type { name kind ofType { name kind } } } type { name kind ofType { name kind ofType { name kind } } } } inputFields { name description type { name kind ofType { name kind } } } enumValues { name description } } } }';
|
|
1333
|
+
function typeToString(t){
|
|
1334
|
+
if(!t) return '';
|
|
1335
|
+
if(t.kind==='NON_NULL') return typeToString(t.ofType) + '!';
|
|
1336
|
+
if(t.kind==='LIST') return '[' + typeToString(t.ofType) + ']';
|
|
1337
|
+
return t.name || '';
|
|
1338
|
+
}
|
|
1339
|
+
function escapeTd(s){ return s.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"'); }
|
|
1340
|
+
ensureCsrf().then(function(token){
|
|
1341
|
+
const headers = {'Content-Type':'application/json'};
|
|
1342
|
+
if(token) headers['X-CSRF-Token'] = token;
|
|
1343
|
+
return fetch(endpoint, { method:'POST', credentials:'include', headers: headers, body: JSON.stringify({ query: INTROSPECTION_QUERY }) });
|
|
1344
|
+
})
|
|
1345
|
+
.then(function(r){ return r.ok ? r.json() : null; })
|
|
1346
|
+
.then(function(json){
|
|
1347
|
+
const schema = json && json.data && json.data.__schema;
|
|
1348
|
+
if (!schema) return;
|
|
1349
|
+
const qFields = (schema.queryType && schema.queryType.fields) || [];
|
|
1350
|
+
const mFields = (schema.mutationType && schema.mutationType.fields) || [];
|
|
1351
|
+
const sFields = (schema.subscriptionType && schema.subscriptionType.fields) || [];
|
|
1352
|
+
// Ops panel
|
|
1353
|
+
if (qFields.length || mFields.length || sFields.length){
|
|
1354
|
+
const opsEl = document.getElementById('ops');
|
|
1355
|
+
if (opsEl){
|
|
1356
|
+
const currentCount = opsEl.querySelectorAll('.op').length;
|
|
1357
|
+
const total = qFields.length + mFields.length + sFields.length;
|
|
1358
|
+
if (total > currentCount){
|
|
1359
|
+
function fieldToExample(type, name, args){
|
|
1360
|
+
const argStr = args && args.length ? '(' + args.map(function(a){ return a.name + ': "demo"'; }).join(', ') + ')' : '';
|
|
1361
|
+
if (type==='Query'){ if (name==='hello') return 'query Demo {\\n hello\\n}'; if (name==='ping') return 'query Demo {\\n ping(message: "hi")\\n}'; return 'query Demo {\\n ' + name + argStr + '\\n}'; }
|
|
1362
|
+
if (type==='Mutation') return 'mutation Demo {\\n ' + name + argStr + '\\n}';
|
|
1363
|
+
return 'subscription Demo {\\n ' + name + argStr + '\\n}';
|
|
1364
|
+
}
|
|
1365
|
+
const rows = [];
|
|
1366
|
+
qFields.forEach(function(f){ rows.push({type:'Query', field:f.name, args:(f.args||[]).map(function(a){return a.name;}).join(', '), typeStr: typeToString(f.type), desc: f.description, example: fieldToExample('Query', f.name, f.args)}); });
|
|
1367
|
+
mFields.forEach(function(f){ rows.push({type:'Mutation', field:f.name, args:(f.args||[]).map(function(a){return a.name;}).join(', '), typeStr: typeToString(f.type), desc: f.description, example: fieldToExample('Mutation', f.name, f.args)}); });
|
|
1368
|
+
sFields.forEach(function(f){ rows.push({type:'Subscription', field:f.name, args:(f.args||[]).map(function(a){return a.name;}).join(', '), typeStr: typeToString(f.type), desc: f.description, example: fieldToExample('Subscription', f.name, f.args)}); });
|
|
1369
|
+
const head = opsEl.previousElementSibling;
|
|
1370
|
+
if (head) head.lastElementChild.textContent = rows.length + ' fields';
|
|
1371
|
+
opsEl.innerHTML = rows.map(function(op){
|
|
1372
|
+
const ret = op.typeStr ? '<span style="opacity:.6; font-weight:400">: ' + escapeTd(op.typeStr) + '</span>' : '';
|
|
1373
|
+
const desc = op.desc ? '<div style="font-size:10px; opacity:.6; margin-top:2px">' + escapeTd(op.desc.slice(0,120)) + '</div>' : '';
|
|
1374
|
+
return '<div class="op ' + (op.type==='Mutation'?'mutation':'') + '" data-query="' + op.example.replace(/"/g,'"') + '"><div><b>' + escapeTd(op.field) + (op.args ? '<span style="font-weight:400; opacity:.7">(' + escapeTd(op.args) + ')</span>' : '') + ret + '</b>' + desc + '</div><span>' + op.type + '</span></div>';
|
|
1375
|
+
}).join('');
|
|
1376
|
+
bindOps();
|
|
1377
|
+
const hint = document.querySelector('.ops + .ai-hint');
|
|
1378
|
+
if (hint) hint.textContent = 'Live from introspection — includes hello + discovered subgraphs (posts, etc.). Click to insert.';
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
// Type details panel
|
|
1383
|
+
const typesEl = document.getElementById('types');
|
|
1384
|
+
const countEl = document.getElementById('types-count');
|
|
1385
|
+
const filterEl = document.getElementById('type-filter');
|
|
1386
|
+
if (!typesEl || !schema.types) return;
|
|
1387
|
+
const ignore = ['String','Int','Float','Boolean','ID','__Schema','__Type','__TypeKind','__Field','__InputValue','__EnumValue','__Directive','_Any','_Entity','_Service'];
|
|
1388
|
+
const userTypes = schema.types.filter(function(t){ return !t.name.startsWith('__') && !t.name.startsWith('_') && ignore.indexOf(t.name)===-1; });
|
|
1389
|
+
userTypes.sort(function(a,b){ return a.name.localeCompare(b.name); });
|
|
1390
|
+
if (countEl) countEl.textContent = userTypes.length + ' types';
|
|
1391
|
+
function renderTypes(filter){
|
|
1392
|
+
const q = (filter||'').toLowerCase();
|
|
1393
|
+
const filtered = q ? userTypes.filter(function(t){ return t.name.toLowerCase().indexOf(q)!==-1 || (t.fields && t.fields.some(function(f){ return f.name.toLowerCase().indexOf(q)!==-1; })); }) : userTypes;
|
|
1394
|
+
if (!filtered.length){ typesEl.innerHTML = '<div class="ai-hint" style="padding:8px">No types match “' + escapeTd(filter) + '”.</div>'; return; }
|
|
1395
|
+
typesEl.innerHTML = filtered.map(function(t){
|
|
1396
|
+
const kind = t.kind || 'OBJECT';
|
|
1397
|
+
const kindIcon = kind==='INPUT_OBJECT' ? '( )' : kind==='ENUM' ? 'A-Z' : kind==='SCALAR' ? 'S' : 'T';
|
|
1398
|
+
const iconCls = kind==='INPUT_OBJECT' ? 'kind-input' : kind==='ENUM' ? 'kind-enum' : kind==='SCALAR' ? 'kind-scalar' : '';
|
|
1399
|
+
const kindLabel = kind.replace(/_/g,' ').toLowerCase();
|
|
1400
|
+
const desc = t.description ? '<div class="type-desc">' + escapeTd(t.description.slice(0,300)) + '</div>' : '';
|
|
1401
|
+
function fieldSig(f){
|
|
1402
|
+
const fType = typeToString(f.type);
|
|
1403
|
+
const fArgs = f.args && f.args.length ? '(' + f.args.map(function(a){ return '<span class="tok-arg">' + escapeTd(a.name) + '</span>: ' + '<span class="tok-type">' + escapeTd(typeToString(a.type)) + '</span>'; }).join(', ') + ')' : '';
|
|
1404
|
+
return escapeTd(f.name) + fArgs + ': ' + '<span class="tok-type">' + escapeTd(fType) + '</span>';
|
|
1405
|
+
}
|
|
1406
|
+
let fieldsHtml = '';
|
|
1407
|
+
if (t.fields && t.fields.length){
|
|
1408
|
+
fieldsHtml = '<span class="type-subhead">Fields</span><div class="type-fields">' + t.fields.map(function(f){
|
|
1409
|
+
const fDesc = f.description ? '<span style="opacity:.6"> — ' + escapeTd(f.description.slice(0,70)) + '</span>' : '';
|
|
1410
|
+
return '<div class="type-field"><span><code class="hljs">' + fieldSig(f) + '</code>' + fDesc + '</span><span class="type-field-arrow" data-field-query="' + escapeTd(f.name) + '" title="Insert ' + escapeTd(f.name) + '">Insert →</span></div>';
|
|
1411
|
+
}).join('') + '</div>';
|
|
1412
|
+
} else if (t.inputFields && t.inputFields.length){
|
|
1413
|
+
fieldsHtml = '<span class="type-subhead">Input Fields</span><div class="type-fields">' + t.inputFields.map(function(f){
|
|
1414
|
+
const fType = typeToString(f.type);
|
|
1415
|
+
return '<div class="type-field"><span><code class="hljs">' + escapeTd(f.name) + ': ' + '<span class="tok-type">' + escapeTd(fType) + '</span></code></span></div>';
|
|
1416
|
+
}).join('') + '</div>';
|
|
1417
|
+
} else if (t.enumValues && t.enumValues.length){
|
|
1418
|
+
fieldsHtml = '<span class="type-subhead">Enum Values</span><div class="type-fields">' + t.enumValues.map(function(v){
|
|
1419
|
+
return '<div class="type-field"><span><b>' + escapeTd(v.name) + '</b>' + (v.description ? '<span style="opacity:.6"> — ' + escapeTd(v.description.slice(0,50)) + '</span>' : '') + '</span></div>';
|
|
1420
|
+
}).join('') + '</div>';
|
|
1421
|
+
}
|
|
1422
|
+
const open = (t.name==='Query' || t.name==='Post' || t.name==='Message') ? ' open' : '';
|
|
1423
|
+
return '<details' + open + '><summary><span class="type-name"><span class="type-icon ' + iconCls + '">' + kindIcon + '</span><b>' + escapeTd(t.name) + '</b></span><span style="display:inline-flex;align-items:center;gap:.35rem;flex:0 0 auto"><span class="type-kind">' + escapeTd(kindLabel) + '</span><span class="type-chevron">›</span></span></summary><div class="type-body">' + desc + fieldsHtml + '</div></details>';
|
|
1424
|
+
}).join('');
|
|
1425
|
+
initTooltips(typesEl);
|
|
1426
|
+
}
|
|
1427
|
+
renderTypes('');
|
|
1428
|
+
// Insert a field's name into the editor when its chip is clicked
|
|
1429
|
+
// (delegated so re-renders after filtering keep working).
|
|
1430
|
+
typesEl.addEventListener('click', function(ev){
|
|
1431
|
+
var t = ev.target;
|
|
1432
|
+
if (!t || !t.classList) return;
|
|
1433
|
+
if (t.classList.contains('type-field-arrow')){
|
|
1434
|
+
var name = t.getAttribute('data-field-query');
|
|
1435
|
+
if (name && window._graphiql){
|
|
1436
|
+
window._graphiql.setQuery('{ ' + name + ' }');
|
|
1437
|
+
showAlert('Query copied', 'Inserted { ' + name + ' } into the editor.', 'success');
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
});
|
|
1441
|
+
if (filterEl){
|
|
1442
|
+
filterEl.addEventListener('input', function(){ renderTypes(filterEl.value); });
|
|
1443
|
+
}
|
|
1444
|
+
}).catch(function(){
|
|
1445
|
+
const el=document.getElementById('types'); if(el) el.innerHTML='<div class="ai-hint" style="padding:8px">Introspection failed. SDL preview:<pre style="white-space:pre-wrap; font-size:11px; opacity:.7">' + escapeTd(rawSdlClient.slice(0,800) || 'empty') + '</pre></div>';
|
|
1446
|
+
const c=document.getElementById('types-count'); if(c) c.textContent='—';
|
|
1447
|
+
});
|
|
1448
|
+
})();
|
|
1449
|
+
|
|
1450
|
+
// AI Assistant — FAB + chat popup (replaces old single-button generate)
|
|
1451
|
+
const aiFab = document.getElementById('ai-fab');
|
|
1452
|
+
const aiPopup = document.getElementById('ai-popup');
|
|
1453
|
+
const aiClose = document.getElementById('ai-close');
|
|
1454
|
+
const aiForm = document.getElementById('ai-form');
|
|
1455
|
+
const aiPrompt = document.getElementById('ai-prompt');
|
|
1456
|
+
const aiChat = document.getElementById('ai-chat');
|
|
1457
|
+
const aiStatus = document.getElementById('ai-status');
|
|
1458
|
+
const aiModelLabel = document.getElementById('ai-model-label');
|
|
1459
|
+
const CHAT_KEY = 'nexus-ai-chat';
|
|
1460
|
+
let aiProvider = 'auto';
|
|
1461
|
+
let aiModel = '';
|
|
1462
|
+
function loadChat(){ try{ return JSON.parse(localStorage.getItem(CHAT_KEY) || '[]'); }catch{ return []; } }
|
|
1463
|
+
function saveChat(list){ try{ localStorage.setItem(CHAT_KEY, JSON.stringify(list.slice(-20))); }catch{} }
|
|
1464
|
+
function escapeChatHtml(s){ return s.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); }
|
|
1465
|
+
function extractQuery(text){
|
|
1466
|
+
if(!text) return null;
|
|
1467
|
+
const m = text.match(/\`\`\`graphql([\\s\\S]*?)\`\`\`/) || text.match(/\`\`\`([\\s\\S]*?)\`\`\`/) || text.match(/\\{[\\s\\S]*\\}/);
|
|
1468
|
+
return m ? (m[1] || m[0]).trim() : (text.includes('{') ? text.trim() : null);
|
|
1469
|
+
}
|
|
1470
|
+
function renderChat(){
|
|
1471
|
+
const list = loadChat();
|
|
1472
|
+
if(!list.length){
|
|
1473
|
+
aiChat.innerHTML = '<div class="ai-hint" style="padding:8px">Hi! I can see your live schema. Ask me to generate queries, explain types, or debug errors.</div>';
|
|
1474
|
+
return;
|
|
1475
|
+
}
|
|
1476
|
+
aiChat.innerHTML = list.map(function(it){
|
|
1477
|
+
const isUser = it.role==='user';
|
|
1478
|
+
const safe = escapeChatHtml(it.content);
|
|
1479
|
+
const hasCode = !isUser && it.content.includes('{');
|
|
1480
|
+
const code = hasCode ? '<pre><code class="hljs">' + highlightCode((extractQuery(it.content) || it.content).slice(0,2000), 'graphql') + '</code></pre>' : '';
|
|
1481
|
+
const btn = hasCode ? '<button class="insert" data-query="' + escapeChatHtml(extractQuery(it.content) || '').replace(/"/g,'"') + '">Insert query</button>' : '';
|
|
1482
|
+
return '<div class="msg ' + (isUser?'user':'ai') + '"><div class="bubble">' + (isUser? safe : safe.replace(/\\n/g,'<br>')) + code + btn + '</div></div>';
|
|
1483
|
+
}).join('');
|
|
1484
|
+
aiChat.querySelectorAll('.insert').forEach(function(b){
|
|
1485
|
+
b.addEventListener('click', function(){
|
|
1486
|
+
const q = b.getAttribute('data-query');
|
|
1487
|
+
if(q){ try{ localStorage.setItem('graphiql:query', q); location.reload(); }catch{ alert(q); } }
|
|
1488
|
+
});
|
|
1489
|
+
});
|
|
1490
|
+
aiChat.scrollTop = aiChat.scrollHeight;
|
|
1491
|
+
}
|
|
1492
|
+
renderChat();
|
|
1493
|
+
async function resolveAiConfig(){
|
|
1494
|
+
try{
|
|
1495
|
+
const s = await fetch('/admin/ai/status', {credentials:'include'}).then(function(r){ return r.ok ? r.json() : null; });
|
|
1496
|
+
if(s){ aiProvider = s.defaultProvider || s.autoResolvesTo || 'auto'; aiModel = s.schemaModel || ''; if(!aiModel){ const p = await fetch('/admin/ai/providers', {credentials:'include'}).then(function(r){ return r.ok ? r.json() : null; }); const en = p && p.providers && p.providers.find(function(x){ return x.enabled && x.defaultModel; }); if(en && en.defaultModel) aiModel = en.defaultModel; } }
|
|
1497
|
+
}catch(e){}
|
|
1498
|
+
if(!aiModel) aiModel = 'llama3.1:8b';
|
|
1499
|
+
if(aiModelLabel) aiModelLabel.textContent = '(' + aiProvider + '/' + aiModel + ')';
|
|
1500
|
+
}
|
|
1501
|
+
resolveAiConfig();
|
|
1502
|
+
if(aiFab && aiPopup){
|
|
1503
|
+
aiFab.addEventListener('click', function(){ aiPopup.hidden = !aiPopup.hidden; if(!aiPopup.hidden) { renderChat(); aiPrompt.focus(); } });
|
|
1504
|
+
if(aiClose) aiClose.addEventListener('click', function(){ aiPopup.hidden = true; });
|
|
1505
|
+
}
|
|
1506
|
+
function setChatTyping(on){
|
|
1507
|
+
let el = document.getElementById('ai-typing');
|
|
1508
|
+
if(on){
|
|
1509
|
+
if(!el){ el = document.createElement('div'); el.id='ai-typing'; el.className='typing'; el.textContent='AI is thinking…'; aiChat.appendChild(el); }
|
|
1510
|
+
aiChat.scrollTop = aiChat.scrollHeight;
|
|
1511
|
+
} else if(el){ el.remove(); }
|
|
1512
|
+
}
|
|
1513
|
+
if(aiForm){
|
|
1514
|
+
aiForm.addEventListener('submit', async function(e){
|
|
1515
|
+
e.preventDefault();
|
|
1516
|
+
const prompt = aiPrompt.value.trim();
|
|
1517
|
+
if(!prompt) return;
|
|
1518
|
+
const history = loadChat();
|
|
1519
|
+
history.push({ role:'user', content: prompt, ts: Date.now() });
|
|
1520
|
+
saveChat(history);
|
|
1521
|
+
renderChat();
|
|
1522
|
+
aiPrompt.value = '';
|
|
1523
|
+
const btn = document.getElementById('ai-send');
|
|
1524
|
+
if(btn) btn.disabled = true;
|
|
1525
|
+
if(aiStatus) aiStatus.textContent = 'Thinking…';
|
|
1526
|
+
setChatTyping(true);
|
|
1527
|
+
try{
|
|
1528
|
+
await resolveAiConfig();
|
|
1529
|
+
const messages = [{ role:'system', content:'You are a helpful GraphQL assistant. You have the live schema SDL (preview: ' + sdlPreview.slice(0,2000) + '). Answer concisely. When asked to generate a query, return the query in a \`\`\`graphql code block and briefly explain.' }];
|
|
1530
|
+
const recent = history.slice(-8);
|
|
1531
|
+
recent.forEach(function(m){ messages.push({ role: m.role, content: m.content }); });
|
|
1532
|
+
const csrf = await ensureCsrf();
|
|
1533
|
+
const aiHeaders = {'Content-Type':'application/json'};
|
|
1534
|
+
if(csrf) aiHeaders['X-CSRF-Token'] = csrf;
|
|
1535
|
+
const res = await fetch('/ai/chat/completions', { method:'POST', credentials: 'include', headers: aiHeaders, body: JSON.stringify({ model: aiModel, provider: aiProvider, messages: messages, stream:false }) });
|
|
1536
|
+
let text = '';
|
|
1537
|
+
if(res.ok){
|
|
1538
|
+
const data = await res.json();
|
|
1539
|
+
text = (data.choices && data.choices[0] && data.choices[0].message && data.choices[0].message.content) || data.content || data.query || '';
|
|
1540
|
+
} else {
|
|
1541
|
+
const errText = await res.text().catch(function(){ return ''; });
|
|
1542
|
+
throw new Error(errText || 'AI not configured');
|
|
1543
|
+
}
|
|
1544
|
+
if(!text) text = 'I could not generate a response. Try rephrasing.';
|
|
1545
|
+
history.push({ role:'assistant', content: text, ts: Date.now() });
|
|
1546
|
+
saveChat(history);
|
|
1547
|
+
renderChat();
|
|
1548
|
+
if(aiStatus) aiStatus.textContent = 'Responded (' + aiProvider + '/' + aiModel + ')';
|
|
1549
|
+
// auto offer insert if contains query
|
|
1550
|
+
const q = extractQuery(text);
|
|
1551
|
+
if(q && q.includes('{') && !text.includes('I could not')){
|
|
1552
|
+
// highlight that query is insertable via button in bubble
|
|
1553
|
+
}
|
|
1554
|
+
} catch(err){
|
|
1555
|
+
const fallback = 'query AiDemo {\\n # Fallback for: ' + prompt.replace(/\\n/g,' ') + '\\n __typename\\n}';
|
|
1556
|
+
const msg = 'AI unavailable: ' + (err && err.message ? err.message : 'error') + '\\n\\nFallback query:\\n\`\`\`graphql\\n' + fallback + '\\n\`\`\`' ;
|
|
1557
|
+
history.push({ role:'assistant', content: msg, ts: Date.now() });
|
|
1558
|
+
saveChat(history);
|
|
1559
|
+
renderChat();
|
|
1560
|
+
if(aiStatus) aiStatus.textContent = 'AI unavailable — inserted fallback. Configure provider in Admin → AI Agents.';
|
|
1561
|
+
} finally {
|
|
1562
|
+
setChatTyping(false);
|
|
1563
|
+
if(btn) btn.disabled = false;
|
|
1564
|
+
if(aiStatus) setTimeout(function(){ aiStatus.textContent=''; }, 6000);
|
|
1565
|
+
}
|
|
1566
|
+
});
|
|
1567
|
+
}
|
|
1568
|
+
</script>
|
|
1569
|
+
</body>
|
|
1570
|
+
</html>`;
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
function extractOperations(sdl: string): Array<{ type: string; field: string; args: string; example: string }> {
|
|
1574
|
+
const ops: Array<{ type: string; field: string; args: string; example: string }> = [];
|
|
1575
|
+
// Support both `type Query` and `extend type Query`, and strip federation noise like @key/@link
|
|
1576
|
+
const cleaned = sdl
|
|
1577
|
+
.replace(/extend\s+schema\s*@\s*link[^\n]*/g, '')
|
|
1578
|
+
.replace(/@\s*key\s*\([^)]*\)/g, '')
|
|
1579
|
+
.replace(/@\s*extends\b/g, '')
|
|
1580
|
+
.replace(/@\s*external\b/g, '');
|
|
1581
|
+
const typeRegex = /(?:extend\s+)?type\s+(Query|Mutation|Subscription)\s*\{([^}]*)\}/g;
|
|
1582
|
+
let m: RegExpExecArray | null;
|
|
1583
|
+
while ((m = typeRegex.exec(cleaned))) {
|
|
1584
|
+
const type = m[1]!;
|
|
1585
|
+
const body = m[2]!;
|
|
1586
|
+
const fieldRegex = /(\w+)\s*(\([^)]*\))?\s*:/g;
|
|
1587
|
+
let f: RegExpExecArray | null;
|
|
1588
|
+
while ((f = fieldRegex.exec(body))) {
|
|
1589
|
+
const field = f[1]!;
|
|
1590
|
+
if (field.startsWith('_')) continue;
|
|
1591
|
+
const args = (f[2] ?? '').replace(/\s+/g, ' ').trim();
|
|
1592
|
+
let example = '';
|
|
1593
|
+
if (type === 'Query') {
|
|
1594
|
+
if (field === 'hello') example = 'query Demo {\n hello\n}';
|
|
1595
|
+
else if (field === 'ping') example = 'query Demo {\n ping(message: "hi")\n}';
|
|
1596
|
+
else example = `query Demo {\n ${field}${args ? `(${args.replace(/:\s*[^,)]+/g, ': "demo"').replace(/[()]/g, '')})` : ''}\n}`;
|
|
1597
|
+
if (args && !['hello', 'ping'].includes(field)) {
|
|
1598
|
+
const demoArgs = args.replace(/(\w+)\s*:\s*[^,)]+/g, '$1: "demo"');
|
|
1599
|
+
example = `query Demo {\n ${field}${demoArgs}\n}`;
|
|
1600
|
+
}
|
|
1601
|
+
} else if (type === 'Mutation') {
|
|
1602
|
+
if (field === 'echo') example = 'mutation Demo {\n echo(input: "hello")\n}';
|
|
1603
|
+
else example = `mutation Demo {\n ${field}${args ? `(${args.replace(/(\w+)\s*:\s*[^,)]+/g, '$1: "demo"')})` : ''}\n}`;
|
|
1604
|
+
} else {
|
|
1605
|
+
example = `subscription Demo {\n ${field}${args ? `(${args.replace(/(\w+)\s*:\s*[^,)]+/g, '$1: "demo"')})` : ''}\n}`;
|
|
1606
|
+
}
|
|
1607
|
+
ops.push({ type, field, args: args.replace(/[()]/g, ''), example });
|
|
1608
|
+
}
|
|
1609
|
+
}
|
|
1610
|
+
if (ops.length === 0 && sdl.includes('hello')) {
|
|
1611
|
+
ops.push({ type: 'Query', field: 'hello', args: '', example: 'query Demo {\n hello\n}' });
|
|
1612
|
+
if (sdl.includes('ping')) ops.push({ type: 'Query', field: 'ping', args: 'message: String', example: 'query Demo {\n ping(message: "hi")\n}' });
|
|
1613
|
+
}
|
|
1614
|
+
// De-dupe by field name, keep first occurrence
|
|
1615
|
+
const seen = new Set<string>();
|
|
1616
|
+
const uniq: typeof ops = [];
|
|
1617
|
+
for (const o of ops) if (!seen.has(o.field)) { seen.add(o.field); uniq.push(o); }
|
|
1618
|
+
return uniq.slice(0, 30);
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
function buildDefaultQuery(ops: ReturnType<typeof extractOperations>): string {
|
|
1622
|
+
if (!ops.length) return '# No schema found — try { hello } — add a subgraph with: npx nexus make:subgraph demo --app backend\n\nquery Demo {\n hello\n ping(message: "hi")\n}';
|
|
1623
|
+
const lines = ops.map(o => {
|
|
1624
|
+
if (o.field === 'hello') return ' hello';
|
|
1625
|
+
if (o.field === 'ping') return ' ping(message: "hi")';
|
|
1626
|
+
if (o.type === 'Mutation') return ` # ${o.field} — use as mutation`;
|
|
1627
|
+
if (o.type === 'Subscription') return ` # ${o.field} — use as subscription`;
|
|
1628
|
+
return ` ${o.field}`;
|
|
1629
|
+
});
|
|
1630
|
+
return `# Welcome to Nexus GraphQL Sandbox
|
|
1631
|
+
# Available: ${ops.map(o => o.field).join(', ')}
|
|
1632
|
+
# Click any operation on the right or Docs ← to explore
|
|
1633
|
+
# Press Ctrl+Enter to run
|
|
1634
|
+
|
|
1635
|
+
query Demo {
|
|
1636
|
+
${lines.join('\n')}
|
|
1637
|
+
}`;
|
|
1638
|
+
}
|
|
1639
|
+
|
|
1640
|
+
function escapeHtml(s: string): string {
|
|
1641
|
+
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
1642
|
+
}
|