@agentstep/agent-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +45 -0
- package/src/auth/middleware.ts +38 -0
- package/src/backends/claude/args.ts +88 -0
- package/src/backends/claude/index.ts +193 -0
- package/src/backends/claude/permission-hook.ts +152 -0
- package/src/backends/claude/tool-bridge.ts +211 -0
- package/src/backends/claude/translator.ts +209 -0
- package/src/backends/claude/wrapper-script.ts +45 -0
- package/src/backends/codex/args.ts +69 -0
- package/src/backends/codex/auth.ts +35 -0
- package/src/backends/codex/index.ts +57 -0
- package/src/backends/codex/setup.ts +37 -0
- package/src/backends/codex/translator.ts +223 -0
- package/src/backends/codex/wrapper-script.ts +26 -0
- package/src/backends/factory/args.ts +45 -0
- package/src/backends/factory/auth.ts +30 -0
- package/src/backends/factory/index.ts +56 -0
- package/src/backends/factory/setup.ts +34 -0
- package/src/backends/factory/translator.ts +139 -0
- package/src/backends/factory/wrapper-script.ts +33 -0
- package/src/backends/gemini/args.ts +44 -0
- package/src/backends/gemini/auth.ts +30 -0
- package/src/backends/gemini/index.ts +53 -0
- package/src/backends/gemini/setup.ts +34 -0
- package/src/backends/gemini/translator.ts +139 -0
- package/src/backends/gemini/wrapper-script.ts +26 -0
- package/src/backends/opencode/args.ts +53 -0
- package/src/backends/opencode/auth.ts +53 -0
- package/src/backends/opencode/index.ts +70 -0
- package/src/backends/opencode/mcp.ts +67 -0
- package/src/backends/opencode/setup.ts +54 -0
- package/src/backends/opencode/translator.ts +168 -0
- package/src/backends/opencode/wrapper-script.ts +46 -0
- package/src/backends/registry.ts +38 -0
- package/src/backends/shared/ndjson.ts +29 -0
- package/src/backends/shared/translator-types.ts +69 -0
- package/src/backends/shared/wrap-prompt.ts +17 -0
- package/src/backends/types.ts +85 -0
- package/src/config/index.ts +95 -0
- package/src/db/agents.ts +185 -0
- package/src/db/api_keys.ts +78 -0
- package/src/db/batch.ts +142 -0
- package/src/db/client.ts +81 -0
- package/src/db/environments.ts +127 -0
- package/src/db/events.ts +208 -0
- package/src/db/memory.ts +143 -0
- package/src/db/migrations.ts +295 -0
- package/src/db/proxy.ts +37 -0
- package/src/db/sessions.ts +295 -0
- package/src/db/vaults.ts +110 -0
- package/src/errors.ts +53 -0
- package/src/handlers/agents.ts +194 -0
- package/src/handlers/batch.ts +41 -0
- package/src/handlers/docs.ts +87 -0
- package/src/handlers/environments.ts +154 -0
- package/src/handlers/events.ts +234 -0
- package/src/handlers/index.ts +12 -0
- package/src/handlers/memory.ts +141 -0
- package/src/handlers/openapi.ts +14 -0
- package/src/handlers/sessions.ts +223 -0
- package/src/handlers/stream.ts +76 -0
- package/src/handlers/threads.ts +26 -0
- package/src/handlers/ui/app.js +984 -0
- package/src/handlers/ui/index.html +112 -0
- package/src/handlers/ui/style.css +164 -0
- package/src/handlers/ui.ts +1281 -0
- package/src/handlers/vaults.ts +99 -0
- package/src/http.ts +35 -0
- package/src/index.ts +104 -0
- package/src/init.ts +227 -0
- package/src/openapi/registry.ts +8 -0
- package/src/openapi/schemas.ts +625 -0
- package/src/openapi/spec.ts +691 -0
- package/src/providers/apple.ts +220 -0
- package/src/providers/daytona.ts +217 -0
- package/src/providers/docker.ts +264 -0
- package/src/providers/e2b.ts +203 -0
- package/src/providers/fly.ts +276 -0
- package/src/providers/modal.ts +222 -0
- package/src/providers/podman.ts +206 -0
- package/src/providers/registry.ts +28 -0
- package/src/providers/shared.ts +11 -0
- package/src/providers/sprites.ts +55 -0
- package/src/providers/types.ts +73 -0
- package/src/providers/vercel.ts +208 -0
- package/src/proxy/forward.ts +111 -0
- package/src/queue/index.ts +111 -0
- package/src/sessions/actor.ts +53 -0
- package/src/sessions/bus.ts +155 -0
- package/src/sessions/driver.ts +818 -0
- package/src/sessions/grader.ts +120 -0
- package/src/sessions/interrupt.ts +14 -0
- package/src/sessions/sweeper.ts +136 -0
- package/src/sessions/threads.ts +126 -0
- package/src/sessions/tools.ts +50 -0
- package/src/shutdown.ts +78 -0
- package/src/sprite/client.ts +294 -0
- package/src/sprite/exec.ts +161 -0
- package/src/sprite/lifecycle.ts +339 -0
- package/src/sprite/pool.ts +65 -0
- package/src/sprite/setup.ts +159 -0
- package/src/state.ts +61 -0
- package/src/types.ts +339 -0
- package/src/util/clock.ts +7 -0
- package/src/util/ids.ts +11 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<meta http-equiv="cache-control" content="no-store, no-cache, must-revalidate" />
|
|
7
|
+
<meta http-equiv="pragma" content="no-cache" />
|
|
8
|
+
<meta http-equiv="expires" content="0" />
|
|
9
|
+
<title>AgentStep Gateway</title>
|
|
10
|
+
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><defs><linearGradient id='g' x1='0' y1='0' x2='1' y2='1'><stop offset='0%25' stop-color='%23eafb6e'/><stop offset='100%25' stop-color='%23b8fc5e'/></linearGradient></defs><circle cx='50' cy='50' r='40' fill='url(%23g)'/></svg>" />
|
|
11
|
+
<script src="https://cdn.jsdelivr.net/npm/marked@15/marked.min.js"></script>
|
|
12
|
+
<script src="https://cdn.jsdelivr.net/npm/dompurify@3/dist/purify.min.js"></script>
|
|
13
|
+
<link rel="preconnect" href="https://rsms.me/" />
|
|
14
|
+
<link rel="stylesheet" href="https://rsms.me/inter/inter.css" />
|
|
15
|
+
<style>__STYLE__</style>
|
|
16
|
+
</head>
|
|
17
|
+
<body>
|
|
18
|
+
<div id="app">
|
|
19
|
+
<!-- Header -->
|
|
20
|
+
<div class="header">
|
|
21
|
+
<h1>AgentStep Gateway</h1>
|
|
22
|
+
<div class="key-input">
|
|
23
|
+
<label style="font-size:11px;color:var(--dim);margin-right:4px">API Key</label>
|
|
24
|
+
<input type="password" id="apiKeyInput" placeholder="ck_..." />
|
|
25
|
+
<button class="btn-icon" onclick="toggleKeyVisibility()" id="keyEyeBtn" title="Show/hide key"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0"/><circle cx="12" cy="12" r="3"/></svg></button>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<!-- Tabs -->
|
|
30
|
+
<div class="tabs">
|
|
31
|
+
<button class="tab active" data-tab="chat">Chat</button>
|
|
32
|
+
<button class="tab" data-tab="config">Config</button>
|
|
33
|
+
<button class="tab" data-tab="events">Events</button>
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<!-- Content -->
|
|
37
|
+
<div class="content">
|
|
38
|
+
<!-- Chat Panel -->
|
|
39
|
+
<div class="panel active" id="panel-chat">
|
|
40
|
+
<div class="chat-layout">
|
|
41
|
+
<div class="chat-sidebar">
|
|
42
|
+
<div class="chat-sidebar-header">
|
|
43
|
+
<span>Sessions</span>
|
|
44
|
+
<button class="btn-icon" onclick="loadSessions()" title="Refresh"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M8 16H3v5"/></svg></button>
|
|
45
|
+
<button class="btn-icon" onclick="showNewSessionModal()" title="New"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M5 12h14"/><path d="M12 5v14"/></svg></button>
|
|
46
|
+
</div>
|
|
47
|
+
<div class="session-list" id="sessionList"></div>
|
|
48
|
+
</div>
|
|
49
|
+
<div class="chat-main">
|
|
50
|
+
<div class="messages" id="messages">
|
|
51
|
+
<div class="empty-state" id="chatEmpty">
|
|
52
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 100 100"><circle cx="50" cy="50" r="40" fill="#a3e635" opacity="0.3"/><circle cx="50" cy="50" r="20" fill="#a3e635" opacity="0.6"/></svg>
|
|
53
|
+
<p style="font-size:16px;font-weight:600;margin-bottom:4px">AgentStep Gateway</p>
|
|
54
|
+
<p style="font-size:12px">Select a session to continue, or click + to start a new one</p>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
<div class="chat-input-area" id="chatInputArea" style="display:none">
|
|
58
|
+
<div class="chat-input-wrap">
|
|
59
|
+
<textarea id="chatInput" placeholder="Message..." rows="1" onkeydown="handleChatKey(event)"></textarea>
|
|
60
|
+
<button class="btn btn-primary" onclick="sendMessage()">Send</button>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
<!-- Config Panel -->
|
|
68
|
+
<div class="panel" id="panel-config">
|
|
69
|
+
<div class="config-layout">
|
|
70
|
+
<div class="config-col">
|
|
71
|
+
<h2>Agents <button class="btn btn-sm btn-secondary" onclick="showCreateAgentModal()">+ New</button></h2>
|
|
72
|
+
<div class="card" id="agentsList"><p style="color:var(--dim);font-size:12px">Loading...</p></div>
|
|
73
|
+
</div>
|
|
74
|
+
<div class="config-col">
|
|
75
|
+
<h2>Environments <button class="btn btn-sm btn-secondary" onclick="showCreateEnvModal()">+ New</button></h2>
|
|
76
|
+
<div class="card" id="envsList"><p style="color:var(--dim);font-size:12px">Loading...</p></div>
|
|
77
|
+
</div>
|
|
78
|
+
<div class="config-col">
|
|
79
|
+
<h2>Secrets <button class="btn btn-sm btn-secondary" onclick="showCreateVaultModal()">+ New</button></h2>
|
|
80
|
+
<div class="card" id="vaultsList"><p style="color:var(--dim);font-size:12px">Loading...</p></div>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
|
|
85
|
+
<!-- Events Panel -->
|
|
86
|
+
<div class="panel" id="panel-events">
|
|
87
|
+
<div class="events-layout">
|
|
88
|
+
<div class="events-toolbar">
|
|
89
|
+
<select class="form-select" id="eventsSessionSelect" onchange="loadEvents()" style="width:280px">
|
|
90
|
+
<option value="">Select session...</option>
|
|
91
|
+
</select>
|
|
92
|
+
<button class="btn btn-sm btn-secondary" onclick="copyEvents()">Copy JSON</button>
|
|
93
|
+
<span id="eventsStats" style="margin-left:auto;font-size:11px;color:var(--dim)"></span>
|
|
94
|
+
</div>
|
|
95
|
+
<div class="events-list" id="eventsList">
|
|
96
|
+
<div class="empty-state">
|
|
97
|
+
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg>
|
|
98
|
+
<p>Select a session to inspect events</p>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
|
|
106
|
+
<!-- Modals container -->
|
|
107
|
+
<div id="modals"></div>
|
|
108
|
+
|
|
109
|
+
__INJECT__
|
|
110
|
+
<script>__SCRIPT__</script>
|
|
111
|
+
</body>
|
|
112
|
+
</html>
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
|
2
|
+
|
|
3
|
+
:root {
|
|
4
|
+
--bg: #0a0a0a; --surface: #171717; --surface2: #1e1e1e;
|
|
5
|
+
--border: rgba(255,255,255,0.08); --border-strong: rgba(255,255,255,0.14);
|
|
6
|
+
--heading: #fafafa; --body: #d4d4d4; --muted: #a3a3a3; --dim: #636363;
|
|
7
|
+
--accent: rgb(163, 230, 53); --accent-hover: rgb(190, 242, 100);
|
|
8
|
+
--error: #f87171; --success: #4ade80;
|
|
9
|
+
--font: 'Inter', -apple-system, sans-serif;
|
|
10
|
+
--mono: 'Geist Mono', 'SF Mono', ui-monospace, monospace;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
html, body { height: 100%; background: var(--bg); color: var(--body); font-family: var(--font); font-size: 14px; -webkit-font-smoothing: antialiased; }
|
|
14
|
+
a { color: var(--accent); text-decoration: none; }
|
|
15
|
+
input, select, textarea, button { font-family: inherit; font-size: inherit; }
|
|
16
|
+
|
|
17
|
+
/* Layout */
|
|
18
|
+
#app { display: flex; flex-direction: column; height: 100vh; }
|
|
19
|
+
.header { display: flex; align-items: center; height: 48px; border-bottom: 1px solid var(--border); padding: 0 16px; gap: 12px; flex-shrink: 0; }
|
|
20
|
+
.header h1 { font-size: 16px; font-weight: 600; color: var(--heading); }
|
|
21
|
+
.header .key-input { margin-left: auto; display: flex; align-items: center; gap: 8px; }
|
|
22
|
+
.header input[type="text"], .header input[type="password"] { background: var(--surface); border: 1px solid var(--border); border-radius: 6px; padding: 4px 10px; color: var(--body); font-size: 12px; width: 200px; }
|
|
23
|
+
|
|
24
|
+
/* Tabs */
|
|
25
|
+
.tabs { display: flex; gap: 2px; padding: 0 16px; border-bottom: 1px solid var(--border); flex-shrink: 0; }
|
|
26
|
+
.tab { padding: 8px 16px; font-size: 13px; font-weight: 500; color: var(--muted); cursor: pointer; border: none; background: none; border-bottom: 2px solid transparent; transition: all 0.15s; }
|
|
27
|
+
.tab:hover { color: var(--heading); }
|
|
28
|
+
.tab.active { color: var(--accent); border-bottom-color: var(--accent); }
|
|
29
|
+
|
|
30
|
+
/* Content */
|
|
31
|
+
.content { flex: 1; overflow: hidden; display: flex; }
|
|
32
|
+
.panel { display: none; flex: 1; overflow: hidden; }
|
|
33
|
+
.panel.active { display: flex; }
|
|
34
|
+
|
|
35
|
+
/* Chat */
|
|
36
|
+
.chat-layout { display: flex; flex: 1; overflow: hidden; }
|
|
37
|
+
.chat-sidebar { width: 220px; border-right: 1px solid var(--border); display: flex; flex-direction: column; flex-shrink: 0; }
|
|
38
|
+
.chat-sidebar-header { display: flex; align-items: center; height: 40px; padding: 0 12px; border-bottom: 1px solid var(--border); gap: 8px; }
|
|
39
|
+
.chat-sidebar-header span { flex: 1; font-size: 12px; font-weight: 500; color: var(--muted); }
|
|
40
|
+
.session-list { flex: 1; overflow-y: auto; padding: 4px; }
|
|
41
|
+
.session-item { display: flex; flex-direction: column; gap: 2px; padding: 6px 8px; border-radius: 6px; cursor: pointer; font-size: 12px; }
|
|
42
|
+
.session-item:hover { background: var(--surface); }
|
|
43
|
+
.session-item.active { background: var(--surface2); }
|
|
44
|
+
.session-item .title { color: var(--body); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
45
|
+
.session-item .meta { font-size: 10px; color: var(--dim); display: flex; justify-content: space-between; }
|
|
46
|
+
|
|
47
|
+
.chat-main { flex: 1; display: flex; flex-direction: column; overflow: hidden; }
|
|
48
|
+
.messages { flex: 1; overflow-y: auto; padding: 16px; display: flex; flex-direction: column; gap: 12px; }
|
|
49
|
+
.message { max-width: 720px; width: 100%; margin: 0 auto; }
|
|
50
|
+
.message.user { }
|
|
51
|
+
.message.assistant { }
|
|
52
|
+
.message-content { padding: 10px 14px; border-radius: 12px; font-size: 13px; line-height: 1.6; word-break: break-word; }
|
|
53
|
+
.message.user .message-content { white-space: pre-wrap; }
|
|
54
|
+
.message.user .message-content { background: var(--surface2); color: var(--body); }
|
|
55
|
+
.message.assistant .message-content { color: var(--heading); }
|
|
56
|
+
.message.tool .message-content { background: var(--surface); color: var(--muted); font-family: var(--mono); font-size: 11px; border: 1px solid var(--border); }
|
|
57
|
+
.message.error .message-content { background: #dc2626; color: #fff; border-radius: 8px; }
|
|
58
|
+
.message.error .message-role { color: #dc2626; }
|
|
59
|
+
.message-role { font-size: 10px; font-weight: 500; color: var(--dim); margin-bottom: 4px; text-transform: uppercase; letter-spacing: 0.05em; }
|
|
60
|
+
.typing { display: flex; align-items: center; gap: 8px; padding: 10px 14px; color: var(--muted); font-size: 13px; max-width: 720px; margin: 0 auto; }
|
|
61
|
+
.typing-dots { display: flex; gap: 3px; }
|
|
62
|
+
.typing-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--muted); animation: bounce 1.2s infinite; }
|
|
63
|
+
.typing-dot:nth-child(2) { animation-delay: 0.15s; }
|
|
64
|
+
.typing-dot:nth-child(3) { animation-delay: 0.3s; }
|
|
65
|
+
@keyframes bounce { 0%, 80%, 100% { transform: translateY(0); } 40% { transform: translateY(-6px); } }
|
|
66
|
+
|
|
67
|
+
.chat-input-area { padding: 12px 16px; border-top: 1px solid var(--border); }
|
|
68
|
+
.chat-input-wrap { max-width: 720px; margin: 0 auto; display: flex; gap: 8px; }
|
|
69
|
+
.chat-input-wrap textarea { flex: 1; background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 10px 14px; color: var(--body); resize: none; min-height: 42px; max-height: 150px; }
|
|
70
|
+
.chat-input-wrap textarea:focus { outline: none; border-color: var(--accent); }
|
|
71
|
+
.empty-state { display: flex; flex-direction: column; align-items: center; justify-content: center; flex: 1; gap: 12px; color: var(--dim); }
|
|
72
|
+
.empty-state svg { opacity: 0.3; }
|
|
73
|
+
|
|
74
|
+
/* Config */
|
|
75
|
+
.config-layout { flex: 1; display: flex; gap: 1px; background: var(--border); overflow: hidden; }
|
|
76
|
+
.config-col { flex: 1; display: flex; flex-direction: column; gap: 12px; overflow-y: auto; padding: 16px; background: var(--bg); }
|
|
77
|
+
.config-col h2 { font-size: 14px; font-weight: 600; color: var(--heading); display: flex; align-items: center; justify-content: space-between; }
|
|
78
|
+
.card { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 12px; }
|
|
79
|
+
.card-item { display: flex; justify-content: space-between; align-items: center; padding: 8px 0; border-bottom: 1px solid var(--border); }
|
|
80
|
+
.card-item:last-child { border-bottom: none; }
|
|
81
|
+
.card-item .name { font-size: 13px; color: var(--heading); }
|
|
82
|
+
.card-item .detail { font-size: 11px; color: var(--dim); font-family: var(--mono); }
|
|
83
|
+
|
|
84
|
+
/* Events */
|
|
85
|
+
.events-layout { flex: 1; display: flex; flex-direction: column; overflow: hidden; }
|
|
86
|
+
.events-toolbar { display: flex; align-items: center; gap: 8px; padding: 8px 16px; border-bottom: 1px solid var(--border); flex-shrink: 0; }
|
|
87
|
+
.events-list { flex: 1; overflow-y: auto; }
|
|
88
|
+
.event-row { display: flex; align-items: flex-start; gap: 8px; padding: 6px 16px; border-bottom: 1px solid var(--border); cursor: pointer; font-size: 12px; }
|
|
89
|
+
.event-row:hover { background: var(--surface); }
|
|
90
|
+
.event-row .seq { color: var(--dim); font-family: var(--mono); font-size: 10px; width: 28px; text-align: right; flex-shrink: 0; padding-top: 2px; }
|
|
91
|
+
.event-row .delta { color: var(--dim); font-family: var(--mono); font-size: 10px; flex-shrink: 0; padding-top: 2px; }
|
|
92
|
+
.event-row .tokens { color: #a78bfa; font-family: var(--mono); font-size: 10px; flex-shrink: 0; padding-top: 2px; }
|
|
93
|
+
.event-row .preview { flex: 1; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
94
|
+
.event-detail { padding: 4px 16px 8px 52px; }
|
|
95
|
+
.event-detail pre { background: var(--surface); border: 1px solid var(--border); border-radius: 6px; padding: 8px; font-family: var(--mono); font-size: 10px; color: var(--body); overflow-x: auto; max-height: 200px; overflow-y: auto; white-space: pre-wrap; }
|
|
96
|
+
|
|
97
|
+
/* Badges */
|
|
98
|
+
.badge { display: inline-block; padding: 1px 6px; border-radius: 4px; font-size: 10px; font-weight: 500; font-family: var(--mono); }
|
|
99
|
+
.badge-user { background: #1e3a5f; color: #60a5fa; }
|
|
100
|
+
.badge-agent { background: #064e3b; color: #34d399; }
|
|
101
|
+
.badge-status { background: #422006; color: #fbbf24; }
|
|
102
|
+
.badge-error { background: #450a0a; color: #f87171; }
|
|
103
|
+
.badge-span { background: #2e1065; color: #a78bfa; }
|
|
104
|
+
.badge-idle { background: var(--surface2); color: var(--muted); }
|
|
105
|
+
.badge-running { background: #064e3b; color: #34d399; }
|
|
106
|
+
|
|
107
|
+
/* Markdown in messages */
|
|
108
|
+
.message-content strong { color: var(--heading); font-weight: 600; }
|
|
109
|
+
.message-content em { font-style: italic; }
|
|
110
|
+
.message-content code { background: var(--surface); padding: 1px 5px; border-radius: 4px; font-family: var(--mono); font-size: 0.9em; }
|
|
111
|
+
.message-content pre { background: var(--surface); border: 1px solid var(--border); border-radius: 6px; padding: 10px 12px; margin: 8px 0; overflow-x: auto; font-family: var(--mono); font-size: 12px; line-height: 1.5; }
|
|
112
|
+
.message-content pre code { background: none; padding: 0; }
|
|
113
|
+
.message-content a { color: var(--accent); text-decoration: underline; }
|
|
114
|
+
/* Reset ALL margins inside message content — browser defaults cause spacing issues */
|
|
115
|
+
.message-content p, .message-content ul, .message-content ol,
|
|
116
|
+
.message-content li, .message-content h1, .message-content h2,
|
|
117
|
+
.message-content h3, .message-content h4, .message-content blockquote {
|
|
118
|
+
margin: 0 !important; padding: 0 !important;
|
|
119
|
+
}
|
|
120
|
+
.message-content ul, .message-content ol { padding-left: 1.5em !important; margin: 2px 0 !important; }
|
|
121
|
+
.message-content li { line-height: 1.5; }
|
|
122
|
+
.message-content p + p { margin-top: 8px !important; }
|
|
123
|
+
.message-content p + ul, .message-content p + ol { margin-top: 2px !important; }
|
|
124
|
+
.message-content ul + p, .message-content ol + p { margin-top: 8px !important; }
|
|
125
|
+
.message-content h1, .message-content h2, .message-content h3 { color: var(--heading); margin: 8px 0 2px !important; }
|
|
126
|
+
.message-content h1 { font-size: 1.3em; } .message-content h2 { font-size: 1.15em; } .message-content h3 { font-size: 1.05em; }
|
|
127
|
+
.badge-running { background: #064e3b; color: #34d399; }
|
|
128
|
+
|
|
129
|
+
/* Buttons */
|
|
130
|
+
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 10px 20px; border-radius: 10px; font-size: 13px; font-weight: 600; border: none; cursor: pointer; transition: all 0.15s; }
|
|
131
|
+
.btn-primary { background: linear-gradient(135deg, #e2f751, #a5fb3c); color: #0a0a0a; }
|
|
132
|
+
.btn-primary:hover { background: linear-gradient(135deg, #eafb6e, #b8fc5e); box-shadow: 0 0 16px 2px rgba(165, 251, 60, 0.25); }
|
|
133
|
+
.btn-secondary { background: var(--surface); color: var(--body); border: 1px solid var(--border); }
|
|
134
|
+
.btn-secondary:hover { background: var(--surface2); }
|
|
135
|
+
.btn-danger { background: transparent; color: var(--error); border: 1px solid var(--error); }
|
|
136
|
+
.btn-danger:hover { background: rgba(248,113,113,0.1); }
|
|
137
|
+
.btn-sm { padding: 4px 8px; font-size: 11px; }
|
|
138
|
+
.btn-icon { padding: 4px; border-radius: 6px; background: none; border: none; color: var(--muted); cursor: pointer; }
|
|
139
|
+
.btn-icon:hover { color: var(--heading); background: var(--surface); }
|
|
140
|
+
|
|
141
|
+
/* Forms */
|
|
142
|
+
.form-group { display: flex; flex-direction: column; gap: 4px; }
|
|
143
|
+
.form-label { font-size: 11px; font-weight: 500; color: var(--muted); }
|
|
144
|
+
.form-input, .form-select, .form-textarea { background: var(--surface); border: 1px solid var(--border); border-radius: 6px; padding: 6px 10px; color: var(--body); font-size: 13px; }
|
|
145
|
+
.form-input:focus, .form-select:focus, .form-textarea:focus { outline: none; border-color: var(--accent); }
|
|
146
|
+
.form-select { appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23a3a3a3' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 8px center; padding-right: 28px; }
|
|
147
|
+
|
|
148
|
+
/* Modal */
|
|
149
|
+
.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.6); display: flex; align-items: center; justify-content: center; z-index: 100; }
|
|
150
|
+
.modal { background: var(--bg); border: 1px solid var(--border-strong); border-radius: 12px; padding: 20px; width: 380px; max-width: 90vw; display: flex; flex-direction: column; gap: 16px; }
|
|
151
|
+
.modal h2 { font-size: 16px; font-weight: 600; color: var(--heading); }
|
|
152
|
+
.modal p { font-size: 12px; color: var(--muted); }
|
|
153
|
+
.modal-actions { display: flex; gap: 8px; justify-content: flex-end; }
|
|
154
|
+
|
|
155
|
+
/* Toast */
|
|
156
|
+
.toast { position: fixed; bottom: 16px; right: 16px; padding: 10px 16px; border-radius: 8px; font-size: 12px; z-index: 200; animation: fadeIn 0.2s; }
|
|
157
|
+
.toast-error { background: #450a0a; color: var(--error); border: 1px solid var(--error); }
|
|
158
|
+
.toast-success { background: #052e16; color: var(--success); border: 1px solid var(--success); }
|
|
159
|
+
@keyframes fadeIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
|
|
160
|
+
|
|
161
|
+
/* Scrollbar */
|
|
162
|
+
::-webkit-scrollbar { width: 6px; }
|
|
163
|
+
::-webkit-scrollbar-track { background: transparent; }
|
|
164
|
+
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
|