@m0xoo/openboard 1.0.13 → 1.0.15
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/README.md +2 -1
- package/package.json +1 -1
- package/packages/client/dist/assets/index-A8hU3crn.css +1 -0
- package/packages/client/dist/assets/index-UoAzXFQl.js +158 -0
- package/packages/client/dist/index.html +2 -2
- package/packages/server/dist/agents/opencode.events.js +39 -32
- package/packages/server/dist/gh-worker.js +82 -0
- package/packages/server/dist/index.js +2 -0
- package/packages/client/dist/assets/index-B8sYFX2d.css +0 -1
- package/packages/client/dist/assets/index-BVnFqWqB.js +0 -145
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
<title>OpenBoard</title>
|
|
7
7
|
<meta name="description" content="A local project management board — create boards, columns, and tickets." />
|
|
8
8
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
9
|
-
<script type="module" crossorigin src="/assets/index-
|
|
10
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
9
|
+
<script type="module" crossorigin src="/assets/index-UoAzXFQl.js"></script>
|
|
10
|
+
<link rel="stylesheet" crossorigin href="/assets/index-A8hU3crn.css">
|
|
11
11
|
</head>
|
|
12
12
|
<body>
|
|
13
13
|
<div id="root"></div>
|
|
@@ -51,6 +51,7 @@ export async function setupOpencodeEventListener(events, opencodeClient, session
|
|
|
51
51
|
const processedMessages = new Set();
|
|
52
52
|
const processedTools = new Set();
|
|
53
53
|
const activeParts = new Map();
|
|
54
|
+
let rawSessionCost = 0;
|
|
54
55
|
try {
|
|
55
56
|
for await (const event of events.stream) {
|
|
56
57
|
// FILTER for events belonging solely to THIS session
|
|
@@ -121,6 +122,9 @@ export async function setupOpencodeEventListener(events, opencodeClient, session
|
|
|
121
122
|
// Handle Text Messages (Wait for assistant message to complete)
|
|
122
123
|
if (event.type === 'message.updated') {
|
|
123
124
|
const info = event.properties.info;
|
|
125
|
+
if (info.cost) {
|
|
126
|
+
rawSessionCost += info.cost;
|
|
127
|
+
}
|
|
124
128
|
if (info.role === 'assistant' && info.time?.completed && !processedMessages.has(info.id)) {
|
|
125
129
|
processedMessages.add(info.id);
|
|
126
130
|
try {
|
|
@@ -128,12 +132,22 @@ export async function setupOpencodeEventListener(events, opencodeClient, session
|
|
|
128
132
|
if (messagesRes.data) {
|
|
129
133
|
const targetMsg = messagesRes.data.find((m) => m.info.id === info.id);
|
|
130
134
|
if (targetMsg && targetMsg.parts) {
|
|
135
|
+
let combinedText = '';
|
|
131
136
|
for (const part of targetMsg.parts) {
|
|
132
137
|
if (part.type === 'text' && part.text?.trim()) {
|
|
138
|
+
combinedText += (combinedText ? '\n\n' : '') + part.text.trim();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (combinedText) {
|
|
142
|
+
const existing = activeParts.get(info.id); // info.id is messageID
|
|
143
|
+
if (existing) {
|
|
144
|
+
commentRepository.update(existing.commentId, combinedText);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
133
147
|
commentRepository.create({
|
|
134
148
|
ticketId: ticket.id,
|
|
135
149
|
author: 'opencode',
|
|
136
|
-
content:
|
|
150
|
+
content: combinedText
|
|
137
151
|
});
|
|
138
152
|
}
|
|
139
153
|
}
|
|
@@ -146,33 +160,19 @@ export async function setupOpencodeEventListener(events, opencodeClient, session
|
|
|
146
160
|
}
|
|
147
161
|
}
|
|
148
162
|
// Handle Tool Completions and Reasoning Real-Time
|
|
163
|
+
// (WE NOW IGNORE THESE AS PER USER REQUEST TO ONLY SHOW IMPORTANT COMMENTS)
|
|
149
164
|
if (event.type === 'message.part.updated') {
|
|
150
165
|
const part = event.properties.part;
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
processedTools.add(part.id);
|
|
154
|
-
let content = `Executed \`${part.tool}\``;
|
|
155
|
-
if (part.state.title)
|
|
156
|
-
content += `\n*${part.state.title}*`;
|
|
157
|
-
commentRepository.create({
|
|
158
|
-
ticketId: ticket.id,
|
|
159
|
-
author: 'opencode',
|
|
160
|
-
content: content
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
// 2. Handle final reasoning/thoughts block (if not caught by deltas)
|
|
164
|
-
if (part.type === 'reasoning' && !processedTools.has(part.id)) {
|
|
165
|
-
processedTools.add(part.id);
|
|
166
|
-
// If we already tracked this via deltas, don't recreate it
|
|
167
|
-
if (!activeParts.has(part.id) && part.text && part.text.trim()) {
|
|
168
|
-
commentRepository.create({
|
|
169
|
-
ticketId: ticket.id,
|
|
170
|
-
author: 'opencode (thought)',
|
|
171
|
-
content: part.text.trim()
|
|
172
|
-
});
|
|
173
|
-
}
|
|
166
|
+
if (part.type === 'step-finish' && part.cost) {
|
|
167
|
+
rawSessionCost += part.cost;
|
|
174
168
|
}
|
|
175
169
|
}
|
|
170
|
+
/*
|
|
171
|
+
if (event.type === 'message.part.updated') {
|
|
172
|
+
const part = event.properties.part;
|
|
173
|
+
// ... logic removed ...
|
|
174
|
+
}
|
|
175
|
+
*/
|
|
176
176
|
// Handle Session Idle (Task Completed)
|
|
177
177
|
if (event.type === 'session.idle') {
|
|
178
178
|
console.log(`[opencode-agent] Agent task completed (idle) for ticket ${ticket.id}.`);
|
|
@@ -188,7 +188,8 @@ export async function setupOpencodeEventListener(events, opencodeClient, session
|
|
|
188
188
|
agent_type: agentType,
|
|
189
189
|
status: 'done',
|
|
190
190
|
port: 4096,
|
|
191
|
-
url: agentUrl
|
|
191
|
+
url: agentUrl,
|
|
192
|
+
total_cost: rawSessionCost > 0 ? Number(rawSessionCost.toFixed(4)) : undefined
|
|
192
193
|
});
|
|
193
194
|
if (agentType === 'code_review') {
|
|
194
195
|
try {
|
|
@@ -313,7 +314,7 @@ export async function setupOpencodeEventListener(events, opencodeClient, session
|
|
|
313
314
|
commentRepository.create({
|
|
314
315
|
ticketId: ticket.id,
|
|
315
316
|
author: 'System',
|
|
316
|
-
content: `🚀 **Pull Request Updated**\n\nThe agent has updated the existing PR:\n${prUrl}`
|
|
317
|
+
content: `🚀 **Pull Request Updated**\n\nThe agent has updated the existing PR:\n${prUrl}${rawSessionCost > 0 ? `\n\n**Total Cost:** $${rawSessionCost.toFixed(4)}` : ''}`
|
|
317
318
|
});
|
|
318
319
|
}
|
|
319
320
|
else {
|
|
@@ -322,7 +323,7 @@ export async function setupOpencodeEventListener(events, opencodeClient, session
|
|
|
322
323
|
commentRepository.create({
|
|
323
324
|
ticketId: ticket.id,
|
|
324
325
|
author: 'System',
|
|
325
|
-
content: `🚀 **Pull Request Created**\n\nThe agent has proposed the following changes in a PR. Check it out:\n${prUrl}`
|
|
326
|
+
content: `🚀 **Pull Request Created**\n\nThe agent has proposed the following changes in a PR. Check it out:\n${prUrl}${rawSessionCost > 0 ? `\n\n**Total Cost:** $${rawSessionCost.toFixed(4)}` : ''}`
|
|
326
327
|
});
|
|
327
328
|
}
|
|
328
329
|
// Add PR URL to the active agent session so the UI displays the code review button
|
|
@@ -332,7 +333,9 @@ export async function setupOpencodeEventListener(events, opencodeClient, session
|
|
|
332
333
|
status: 'done',
|
|
333
334
|
port: 4096,
|
|
334
335
|
url: agentUrl,
|
|
335
|
-
pr_url: prUrl
|
|
336
|
+
pr_url: prUrl,
|
|
337
|
+
pr_status: 'OPEN',
|
|
338
|
+
total_cost: rawSessionCost > 0 ? Number(rawSessionCost.toFixed(4)) : undefined
|
|
336
339
|
});
|
|
337
340
|
}
|
|
338
341
|
else {
|
|
@@ -340,7 +343,7 @@ export async function setupOpencodeEventListener(events, opencodeClient, session
|
|
|
340
343
|
commentRepository.create({
|
|
341
344
|
ticketId: ticket.id,
|
|
342
345
|
author: 'System',
|
|
343
|
-
content: `ℹ️ **Task Completed (No Changes)**\n\nThe agent finished the task but did not make any code changes
|
|
346
|
+
content: `ℹ️ **Task Completed (No Changes)**\n\nThe agent finished the task but did not make any code changes.${rawSessionCost > 0 ? `\n\n**Total Cost:** $${rawSessionCost.toFixed(4)}` : ''}`
|
|
344
347
|
});
|
|
345
348
|
}
|
|
346
349
|
}
|
|
@@ -376,8 +379,12 @@ export async function setupOpencodeEventListener(events, opencodeClient, session
|
|
|
376
379
|
if (event.type === 'message.part.delta') {
|
|
377
380
|
const partID = event.properties.partID;
|
|
378
381
|
const delta = event.properties.delta;
|
|
379
|
-
if
|
|
380
|
-
|
|
382
|
+
// To know if this part is 'text', we check if we've seen it as text in a part.updated
|
|
383
|
+
// or if it belongs to an assistant message we want to track.
|
|
384
|
+
// However, to satisfy "one comment per section", we should group by messageID.
|
|
385
|
+
const messageID = event.properties.messageID;
|
|
386
|
+
if (delta && messageID) {
|
|
387
|
+
let tracking = activeParts.get(messageID);
|
|
381
388
|
if (!tracking) {
|
|
382
389
|
// create initial comment
|
|
383
390
|
const comment = commentRepository.create({
|
|
@@ -386,7 +393,7 @@ export async function setupOpencodeEventListener(events, opencodeClient, session
|
|
|
386
393
|
content: delta
|
|
387
394
|
});
|
|
388
395
|
tracking = { commentId: comment.id, fullText: delta };
|
|
389
|
-
activeParts.set(
|
|
396
|
+
activeParts.set(messageID, tracking);
|
|
390
397
|
}
|
|
391
398
|
else {
|
|
392
399
|
// update existing comment
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { ticketRepository } from './repositories/ticket.repository.js';
|
|
2
|
+
import { commentRepository } from './repositories/comment.repository.js';
|
|
3
|
+
import { execFile } from 'child_process';
|
|
4
|
+
import { promisify } from 'util';
|
|
5
|
+
import { getDb } from './db/database.js';
|
|
6
|
+
const execFileAsync = promisify(execFile);
|
|
7
|
+
export class GhWorker {
|
|
8
|
+
interval = null;
|
|
9
|
+
isPolling = false;
|
|
10
|
+
start() {
|
|
11
|
+
console.log('[gh-worker] Starting GitHub PR status worker...');
|
|
12
|
+
this.poll();
|
|
13
|
+
this.interval = setInterval(() => this.poll(), 10_000); // Every 60 seconds
|
|
14
|
+
}
|
|
15
|
+
stop() {
|
|
16
|
+
if (this.interval) {
|
|
17
|
+
clearInterval(this.interval);
|
|
18
|
+
this.interval = null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
async poll() {
|
|
22
|
+
if (this.isPolling)
|
|
23
|
+
return;
|
|
24
|
+
this.isPolling = true;
|
|
25
|
+
try {
|
|
26
|
+
// Find all tickets with a PR URL that isn't merged or closed
|
|
27
|
+
const db = getDb();
|
|
28
|
+
const rows = db.prepare('SELECT * FROM tickets').all();
|
|
29
|
+
for (const row of rows) {
|
|
30
|
+
let sessions = [];
|
|
31
|
+
try {
|
|
32
|
+
sessions = JSON.parse(row.agent_sessions);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (!sessions || sessions.length === 0)
|
|
38
|
+
continue;
|
|
39
|
+
for (let i = sessions.length - 1; i >= 0; i--) {
|
|
40
|
+
const session = sessions[i];
|
|
41
|
+
if (session.pr_url && (!session.pr_status || session.pr_status === 'OPEN')) {
|
|
42
|
+
try {
|
|
43
|
+
const { stdout } = await execFileAsync('gh', ['pr', 'view', session.pr_url, '--json', 'state'], { shell: true });
|
|
44
|
+
const data = JSON.parse(stdout);
|
|
45
|
+
const newState = data.state; // 'OPEN', 'MERGED', 'CLOSED'
|
|
46
|
+
if (newState && newState !== session.pr_status) {
|
|
47
|
+
console.log(`[gh-worker] PR status changed from ${session.pr_status} to ${newState} for ticket ${row.id}`);
|
|
48
|
+
// Update this specific session
|
|
49
|
+
session.pr_status = newState;
|
|
50
|
+
ticketRepository.updateAgentSession(row.id, session);
|
|
51
|
+
if (newState === 'MERGED') {
|
|
52
|
+
commentRepository.create({
|
|
53
|
+
ticketId: row.id,
|
|
54
|
+
author: 'System',
|
|
55
|
+
content: `🎉 **Pull Request Merged!**\n\nThe PR [${session.pr_url}](${session.pr_url}) has been merged.`
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
else if (newState === 'CLOSED') {
|
|
59
|
+
commentRepository.create({
|
|
60
|
+
ticketId: row.id,
|
|
61
|
+
author: 'System',
|
|
62
|
+
content: `🚫 **Pull Request Closed**\n\nThe PR [${session.pr_url}](${session.pr_url}) was closed without merging.`
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
catch (e) {
|
|
68
|
+
console.warn(`[gh-worker] Failed to check PR status for ${session.pr_url}: ${e.message}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
console.error('[gh-worker] Polling error:', err);
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
this.isPolling = false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
export const ghWorker = new GhWorker();
|
|
@@ -6,6 +6,7 @@ import { columnsRouter } from './routes/columns.router.js';
|
|
|
6
6
|
import { ticketsRouter } from './routes/tickets.router.js';
|
|
7
7
|
import { columnConfigRouter } from './routes/column-config.router.js';
|
|
8
8
|
import { sseManager } from './sse.js';
|
|
9
|
+
import { ghWorker } from './gh-worker.js';
|
|
9
10
|
import path from 'path';
|
|
10
11
|
import { fileURLToPath } from 'url';
|
|
11
12
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -14,6 +15,7 @@ const PORT = process.env.PORT ?? 3001;
|
|
|
14
15
|
async function start() {
|
|
15
16
|
await initDb();
|
|
16
17
|
console.log('[openboard] Database ready');
|
|
18
|
+
ghWorker.start();
|
|
17
19
|
const app = express();
|
|
18
20
|
app.use(cors({ origin: process.env.CLIENT_ORIGIN ? process.env.CLIENT_ORIGIN.split(',') : ['http://localhost:5173', 'http://localhost:4173'] }));
|
|
19
21
|
app.use(express.json());
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
@import"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap";:root,[data-theme=dark]{--color-bg: #0a0a0a;--color-surface: #111111;--color-surface-2: #1a1a1a;--color-surface-3: #222222;--color-border: rgba(255, 255, 255, .08);--color-border-hover: rgba(255, 255, 255, .16);--color-text-primary: #ededed;--color-text-secondary: #a1a1aa;--color-text-muted: #52525b;--color-text-on-accent: #ffffff;--color-accent: #5e6ad2;--color-accent-hover: #6b7ae2;--color-accent-subtle: rgba(94, 106, 210, .15);--color-priority-low: #3b82f6;--color-priority-medium: #f59e0b;--color-priority-high: #f97316;--color-priority-urgent: #ef4444;--color-success: #22c55e;--color-error: #ef4444;--shadow-sm: 0 1px 2px rgba(0, 0, 0, .5);--shadow-md: 0 4px 12px rgba(0, 0, 0, .6);--shadow-lg: 0 8px 32px rgba(0, 0, 0, .7);--scrollbar-thumb: rgba(255, 255, 255, .1);--scrollbar-track: transparent}[data-theme=light]{--color-bg: #f4f4f5;--color-surface: #ffffff;--color-surface-2: #f4f4f5;--color-surface-3: #e4e4e7;--color-border: rgba(0, 0, 0, .08);--color-border-hover: rgba(0, 0, 0, .16);--color-text-primary: #09090b;--color-text-secondary: #52525b;--color-text-muted: #a1a1aa;--color-text-on-accent: #ffffff;--color-accent: #5e6ad2;--color-accent-hover: #4f59c2;--color-accent-subtle: rgba(94, 106, 210, .1);--color-priority-low: #2563eb;--color-priority-medium: #d97706;--color-priority-high: #ea580c;--color-priority-urgent: #dc2626;--color-success: #16a34a;--color-error: #dc2626;--shadow-sm: 0 1px 2px rgba(0, 0, 0, .06);--shadow-md: 0 4px 12px rgba(0, 0, 0, .08);--shadow-lg: 0 8px 32px rgba(0, 0, 0, .12);--scrollbar-thumb: rgba(0, 0, 0, .12);--scrollbar-track: transparent}:root{--space-1: 4px;--space-2: 8px;--space-3: 12px;--space-4: 16px;--space-5: 20px;--space-6: 24px;--space-8: 32px;--space-10: 40px;--space-12: 48px;--radius-sm: 4px;--radius-md: 6px;--radius-lg: 10px;--radius-xl: 16px;--radius-full: 9999px;--font-sans: "Inter", system-ui, -apple-system, sans-serif;--font-mono: "Fira Code", "Cascadia Code", monospace;--text-xs: 11px;--text-sm: 13px;--text-base: 14px;--text-md: 15px;--text-lg: 17px;--text-xl: 20px;--text-2xl: 24px;--line-height-tight: 1.25;--line-height-normal: 1.5;--transition-fast: 80ms ease;--transition-normal: .15s ease;--transition-slow: .25s ease;--sidebar-width: 220px;--topbar-height: 48px;--column-width: 280px}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}html{font-size:16px;-webkit-text-size-adjust:100%}body{font-family:var(--font-sans);font-size:var(--text-base);line-height:var(--line-height-normal);background-color:var(--color-bg);color:var(--color-text-primary);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;overflow:hidden}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:var(--scrollbar-track)}::-webkit-scrollbar-thumb{background:var(--scrollbar-thumb);border-radius:var(--radius-full)}::-webkit-scrollbar-thumb:hover{background:var(--color-border-hover)}.text-primary{color:var(--color-text-primary)}.text-secondary{color:var(--color-text-secondary)}.text-muted{color:var(--color-text-muted)}.text-xs{font-size:var(--text-xs)}.text-sm{font-size:var(--text-sm)}.text-base{font-size:var(--text-base)}.text-md{font-size:var(--text-md)}.text-lg{font-size:var(--text-lg)}.font-medium{font-weight:500}.font-semibold{font-weight:600}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.flex{display:flex}.flex-col{flex-direction:column}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:var(--space-1)}.gap-2{gap:var(--space-2)}.gap-3{gap:var(--space-3)}.gap-4{gap:var(--space-4)}.flex-1{flex:1}.min-w-0{min-width:0}.overflow-hidden{overflow:hidden}.overflow-auto{overflow:auto}.w-full{width:100%}.h-full{height:100%}button{font-family:inherit;cursor:pointer;border:none;background:none;outline:none;transition:background var(--transition-normal),color var(--transition-normal),opacity var(--transition-fast)}button:disabled{opacity:.4;cursor:not-allowed}input,textarea{font-family:inherit;color:inherit;background:none;border:none;outline:none}a{color:inherit;text-decoration:none}:focus-visible{outline:2px solid var(--color-accent);outline-offset:2px;border-radius:var(--radius-sm)}._sidebar_1y03c_1{width:var(--sidebar-width);height:100vh;background:var(--color-surface);border-right:1px solid var(--color-border);display:flex;flex-direction:column;flex-shrink:0;overflow:hidden}._header_1y03c_23{height:var(--topbar-height);display:flex;align-items:center;padding:0 var(--space-4);border-bottom:1px solid var(--color-border)}._logo_1y03c_39{display:flex;align-items:center;gap:var(--space-2);font-size:var(--text-sm);font-weight:600;color:var(--color-text-primary);letter-spacing:-.01em}._logo_1y03c_39 svg{color:var(--color-accent)}._section_1y03c_67{display:flex;align-items:center;justify-content:space-between;padding:var(--space-4) var(--space-4) var(--space-2)}._sectionLabel_1y03c_81{font-size:var(--text-xs);font-weight:500;color:var(--color-text-muted);text-transform:uppercase;letter-spacing:.06em}._newBtn_1y03c_97{width:20px;height:20px;border-radius:var(--radius-sm);display:flex;align-items:center;justify-content:center;color:var(--color-text-muted);transition:background var(--transition-normal),color var(--transition-normal)}._newBtn_1y03c_97:hover{background:var(--color-surface-2);color:var(--color-text-primary)}._nav_1y03c_129{flex:1;overflow-y:auto;padding:var(--space-1) var(--space-2)}._boardItem_1y03c_141{position:relative;border-radius:var(--radius-md);margin-bottom:1px}._boardBtn_1y03c_153{width:100%;display:flex;align-items:center;gap:var(--space-2);padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);font-size:var(--text-sm);color:var(--color-text-secondary);text-align:left;transition:background var(--transition-normal),color var(--transition-normal)}._boardBtn_1y03c_153:hover{background:var(--color-surface-2);color:var(--color-text-primary)}._boardItem_1y03c_141._active_1y03c_189 ._boardBtn_1y03c_153{background:var(--color-accent-subtle);color:var(--color-text-primary)}._boardDot_1y03c_199{width:6px;height:6px;border-radius:50%;background:var(--color-text-muted);flex-shrink:0;transition:background var(--transition-normal)}._boardItem_1y03c_141._active_1y03c_189 ._boardDot_1y03c_199{background:var(--color-accent)}._actions_1y03c_225{position:absolute;right:var(--space-2);top:50%;transform:translateY(-50%);display:flex;gap:2px}._action_1y03c_225{width:22px;height:22px;display:flex;align-items:center;justify-content:center;border-radius:var(--radius-sm);color:var(--color-text-muted);transition:background var(--transition-fast),color var(--transition-fast)}._action_1y03c_225:hover{background:var(--color-surface-3);color:var(--color-text-primary)}._inlineEdit_1y03c_275{width:100%;padding:var(--space-2) var(--space-3);font-size:var(--text-sm);color:var(--color-text-primary);background:var(--color-surface-2);border-radius:var(--radius-md);border:1px solid var(--color-accent)}._overlay_1kuf8_1{position:fixed;top:0;right:0;bottom:0;left:0;background:#0009;display:flex;align-items:center;justify-content:center;z-index:100;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);animation:_fadeIn_1kuf8_1 .15s ease}@keyframes _fadeIn_1kuf8_1{0%{opacity:0}to{opacity:1}}._dialog_1kuf8_45{background:var(--color-surface-2);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:var(--space-6);max-width:340px;width:90%;box-shadow:var(--shadow-lg);animation:_slideIn_1kuf8_1 .15s ease}@keyframes _slideIn_1kuf8_1{0%{transform:translateY(-8px);opacity:0}to{transform:translateY(0);opacity:1}}._message_1kuf8_91{font-size:var(--text-sm);color:var(--color-text-secondary);line-height:var(--line-height-normal);margin-bottom:var(--space-6)}._actions_1kuf8_105{display:flex;justify-content:flex-end;gap:var(--space-2)}._cancel_1kuf8_117{padding:var(--space-2) var(--space-4);border-radius:var(--radius-md);font-size:var(--text-sm);font-weight:500;color:var(--color-text-secondary);border:1px solid var(--color-border);background:transparent;transition:background var(--transition-normal),color var(--transition-normal)}._cancel_1kuf8_117:hover{background:var(--color-surface-3);color:var(--color-text-primary)}._confirm_1kuf8_149{padding:var(--space-2) var(--space-4);border-radius:var(--radius-md);font-size:var(--text-sm);font-weight:500;color:#fff;background:var(--color-error);transition:opacity var(--transition-fast)}._confirm_1kuf8_149:hover{opacity:.85}._overlay_e33j2_1{position:fixed;top:0;right:0;bottom:0;left:0;background:#000000a6;display:flex;align-items:flex-start;justify-content:center;padding-top:80px;z-index:100;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);animation:_fadeIn_e33j2_1 .15s ease}@keyframes _fadeIn_e33j2_1{0%{opacity:0}to{opacity:1}}._modal_e33j2_47{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-xl);width:600px;max-width:calc(100vw - 32px);max-height:calc(100vh - 120px);overflow-y:auto;box-shadow:var(--shadow-lg);animation:_slideIn_e33j2_1 .15s cubic-bezier(.16,1,.3,1);display:flex;flex-direction:column}@keyframes _slideIn_e33j2_1{0%{transform:translateY(-16px);opacity:0}to{transform:translateY(0);opacity:1}}._header_e33j2_99{display:flex;align-items:center;justify-content:space-between;padding:var(--space-6) var(--space-8);border-bottom:1px solid var(--color-border)}._header_e33j2_99 h2{margin:0;font-size:var(--text-lg);font-weight:600;color:var(--color-text-primary)}._closeBtn_e33j2_129{width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:var(--radius-md);color:var(--color-text-muted);background:transparent;border:none;cursor:pointer;transition:background var(--transition-fast),color var(--transition-fast)}._closeBtn_e33j2_129:hover{background:var(--color-surface-2);color:var(--color-text-primary)}._content_e33j2_167{padding:var(--space-8);display:flex;flex-direction:column;gap:var(--space-6)}._field_e33j2_181{display:flex;flex-direction:column;gap:var(--space-2)}._field_e33j2_181 label{font-size:var(--text-xs);font-weight:500;color:var(--color-text-muted);text-transform:uppercase;letter-spacing:.06em}._input_e33j2_209{width:100%;padding:var(--space-3) var(--space-4);background:var(--color-surface-2);border:1px solid var(--color-border);border-radius:var(--radius-md);font-size:var(--text-sm);color:var(--color-text-primary);transition:border-color var(--transition-fast)}._input_e33j2_209:focus{outline:none;border-color:var(--color-accent)}._workspacesSection_e33j2_241{display:flex;flex-direction:column;gap:var(--space-4)}._sectionHeader_e33j2_253{display:flex;justify-content:space-between;align-items:center}._sectionHeader_e33j2_253 h3{margin:0;font-size:var(--text-xs);font-weight:500;color:var(--color-text-muted);text-transform:uppercase;letter-spacing:.06em}._addBtn_e33j2_283{display:flex;align-items:center;gap:var(--space-1);font-size:var(--text-xs);font-weight:500;color:var(--color-accent);background:transparent;border:none;cursor:pointer;padding:var(--space-1) var(--space-2);border-radius:var(--radius-sm);transition:background var(--transition-fast)}._addBtn_e33j2_283:hover{background:color-mix(in srgb,var(--color-accent) 10%,transparent)}._workspaceList_e33j2_321{display:flex;flex-direction:column;gap:var(--space-3)}._workspaceRow_e33j2_333{display:flex;gap:var(--space-2);align-items:center}._select_e33j2_345{padding:var(--space-2) var(--space-3);background:var(--color-surface-2);border:1px solid var(--color-border);border-radius:var(--radius-md);font-size:var(--text-xs);color:var(--color-text-primary);cursor:pointer}._pathInputWrapper_e33j2_365{flex:1;display:flex;align-items:center;gap:var(--space-2);padding:0 var(--space-3);background:var(--color-surface-2);border:1px solid var(--color-border);border-radius:var(--radius-md);transition:border-color var(--transition-fast)}._pathInputWrapper_e33j2_365:focus-within{border-color:var(--color-accent)}._pathInputWrapper_e33j2_365 svg{color:var(--color-text-muted)}._pathInput_e33j2_365{flex:1;padding:var(--space-2) 0;background:transparent;border:none;font-size:var(--text-sm);color:var(--color-text-primary)}._pathInput_e33j2_365:focus{outline:none}._removeBtn_e33j2_431{width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:var(--radius-md);color:var(--color-text-muted);background:transparent;border:none;cursor:pointer;transition:background var(--transition-fast),color var(--transition-fast)}._removeBtn_e33j2_431:hover{background:color-mix(in srgb,var(--color-error) 12%,transparent);color:var(--color-error)}._footer_e33j2_469{display:flex;align-items:center;justify-content:flex-end;gap:var(--space-2);padding:var(--space-6) var(--space-8);border-top:1px solid var(--color-border)}._cancelBtn_e33j2_487{padding:var(--space-2) var(--space-4);border-radius:var(--radius-md);font-size:var(--text-sm);font-weight:500;color:var(--color-text-secondary);border:1px solid var(--color-border);background:transparent;cursor:pointer;transition:background var(--transition-normal)}._cancelBtn_e33j2_487:hover{background:var(--color-surface-2)}._saveBtn_e33j2_519{padding:var(--space-2) var(--space-4);border-radius:var(--radius-md);font-size:var(--text-sm);font-weight:500;color:var(--color-text-on-accent);background:var(--color-accent);border:none;cursor:pointer;transition:opacity var(--transition-fast)}._saveBtn_e33j2_519:hover:not(:disabled){opacity:.85}._saveBtn_e33j2_519:disabled{opacity:.4;cursor:not-allowed}._badge_1qhnp_1{display:inline-flex;align-items:center;border-radius:var(--radius-full);font-weight:500;background:color-mix(in srgb,var(--priority-color) 15%,transparent);color:var(--priority-color);white-space:nowrap}._sm_1qhnp_21{font-size:var(--text-xs);padding:2px 7px}._md_1qhnp_31{font-size:var(--text-sm);padding:var(--space-1) var(--space-3)}._card_mtqwy_1{background:var(--color-surface-2);border:1px solid var(--color-border);border-radius:var(--radius-md);padding:var(--space-3);cursor:pointer;transition:background var(--transition-fast),border-color var(--transition-fast),box-shadow var(--transition-fast),transform var(--transition-fast);-webkit-user-select:none;user-select:none;position:relative}._card_mtqwy_1:hover{background:var(--color-surface-3);border-color:var(--color-border-hover);box-shadow:var(--shadow-sm)}._card_mtqwy_1._dragging_mtqwy_37{box-shadow:var(--shadow-md);cursor:grabbing}._needsApprovalCard_mtqwy_47{border-color:#f59e0b99!important;background:linear-gradient(to bottom right,rgba(245,158,11,.05),var(--color-surface-2))!important;animation:_pulseBorder_mtqwy_1 2s infinite ease-in-out}._needsApprovalCard_mtqwy_47:hover{border-color:#f59e0b!important;background:linear-gradient(to bottom right,rgba(245,158,11,.08),var(--color-surface-3))!important}@keyframes _pulseBorder_mtqwy_1{0%{box-shadow:0 0 #f59e0b66}70%{box-shadow:0 0 0 6px #f59e0b00}to{box-shadow:0 0 #f59e0b00}}._title_mtqwy_97{font-size:var(--text-sm);font-weight:500;color:var(--color-text-primary);line-height:var(--line-height-tight);margin-bottom:var(--space-1)}._titleWithPr_mtqwy_113{padding-right:64px}._prButtonOverlay_mtqwy_121{position:absolute;top:var(--space-2);right:var(--space-2);z-index:10}._description_mtqwy_135{font-size:var(--text-xs);color:var(--color-text-muted);line-height:var(--line-height-normal);margin-bottom:var(--space-2);display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}._footer_mtqwy_159{display:flex;align-items:center;justify-content:space-between;margin-top:var(--space-2)}._left_mtqwy_173{display:flex;align-items:center;gap:var(--space-2)}._inspectBtn_mtqwy_185{display:inline-flex;align-items:center;gap:var(--space-1);font-size:var(--text-xs);font-weight:500;padding:var(--space-1) var(--space-2);border-radius:var(--radius-sm);text-decoration:none;transition:background var(--transition-fast),color var(--transition-fast)}._processingBtn_mtqwy_209{color:var(--color-accent);background:rgba(var(--color-accent-rgb),.1)}._processingBtn_mtqwy_209:hover{background:rgba(var(--color-accent-rgb),.2)}._doneBtn_mtqwy_227{color:#10b981;background:#10b9811a}._doneBtn_mtqwy_227:hover{background:#10b98133}._blockedBtn_mtqwy_245{color:#ef4444;background:#ef44441a}._blockedBtn_mtqwy_245:hover{background:#ef444433}._needsApprovalBtn_mtqwy_263{color:#f59e0b;background:#f59e0b1a}._needsApprovalBtn_mtqwy_263:hover{background:#f59e0b33}._processingIcon_mtqwy_281{animation:_pulse_mtqwy_1 2s infinite ease-in-out}@keyframes _pulse_mtqwy_1{0%{opacity:.4}50%{opacity:1}to{opacity:.4}}._overlay_1ypt0_1{position:fixed;top:0;right:0;bottom:0;left:0;background:#000000a6;display:flex;align-items:flex-start;justify-content:center;padding-top:80px;z-index:50;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);animation:_fadeIn_1ypt0_1 .15s ease}@keyframes _fadeIn_1ypt0_1{0%{opacity:0}to{opacity:1}}._modal_1ypt0_47{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-xl);width:600px;max-width:calc(100vw - 32px);max-height:calc(100vh - 120px);display:flex;flex-direction:column;overflow:hidden;box-shadow:var(--shadow-lg);animation:_slideIn_1ypt0_1 .15s cubic-bezier(.16,1,.3,1)}._content_1ypt0_75{overflow-y:auto;flex:1}@keyframes _slideIn_1ypt0_1{0%{transform:translateY(-16px);opacity:0}to{transform:translateY(0);opacity:1}}._header_1ypt0_109{display:flex;align-items:center;justify-content:space-between;padding:var(--space-6) var(--space-8);border-bottom:1px solid var(--color-border);flex-shrink:0}._meta_1ypt0_127{display:flex;align-items:center;gap:var(--space-2)}._statusBadge_1ypt0_151{display:flex;align-items:center;gap:4px;font-size:var(--text-xs);font-weight:500;padding:2px 8px;border-radius:var(--radius-full);text-decoration:none;transition:background var(--transition-fast),color var(--transition-fast)}._statusBadge_1ypt0_151._processing_1ypt0_175{color:var(--color-accent);background:rgba(var(--color-accent-rgb),.1)}._statusBadge_1ypt0_151._processing_1ypt0_175:hover{background:rgba(var(--color-accent-rgb),.2)}._statusBadge_1ypt0_151._done_1ypt0_193{color:#10b981;background:#10b9811a}._statusBadge_1ypt0_151._done_1ypt0_193:hover{background:#10b98133}._statusBadge_1ypt0_151._blocked_1ypt0_211{color:#ef4444;background:#ef44441a}._statusBadge_1ypt0_151._blocked_1ypt0_211:hover{background:#ef444433}._statusBadge_1ypt0_151._needsApproval_1ypt0_229{color:#f59e0b;background:#f59e0b1a}._statusBadge_1ypt0_151._needsApproval_1ypt0_229:hover{background:#f59e0b33}._columnTag_1ypt0_247{font-size:var(--text-xs);color:var(--color-text-muted);font-weight:500;background:var(--color-surface-2);border:1px solid var(--color-border);border-radius:var(--radius-full);padding:2px 8px}._closeBtn_1ypt0_267{width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:var(--radius-md);color:var(--color-text-muted);transition:background var(--transition-fast),color var(--transition-fast)}._closeBtn_1ypt0_267:hover{background:var(--color-surface-2);color:var(--color-text-primary)}._headerRight_1ypt0_299{display:flex;align-items:center;gap:var(--space-3)}._sessionBtn_1ypt0_311{display:inline-flex;align-items:center;gap:var(--space-1);font-size:var(--text-xs);font-weight:500;color:var(--color-text-secondary);background:var(--color-surface-2);border:1px solid var(--color-border);padding:var(--space-1) var(--space-3);border-radius:var(--radius-md);text-decoration:none;transition:all var(--transition-fast)}._sessionBtn_1ypt0_311:hover{background:var(--color-surface-3);color:var(--color-text-primary);border-color:var(--color-border-hover)}._body_1ypt0_353{padding:var(--space-8);display:flex;flex-direction:column}._titleInput_1ypt0_365{width:100%;padding:var(--space-2) var(--space-4) 2px;font-size:var(--text-xl);font-weight:600;color:var(--color-text-primary);line-height:var(--line-height-tight);background:transparent;border:none;resize:none;display:block;border-radius:var(--radius-md);transition:background var(--transition-fast)}._titleInput_1ypt0_365:focus{background:var(--color-surface-2);outline:none}._titleInput_1ypt0_365::placeholder{color:var(--color-text-muted)}._descInput_1ypt0_413{width:100%;padding:var(--space-2) var(--space-4) var(--space-3);margin-top:var(--space-1);font-size:var(--text-sm);color:var(--color-text-secondary);line-height:var(--line-height-normal);background:transparent;resize:vertical;border:none;display:block;border-radius:var(--radius-md);transition:background var(--transition-fast)}._descInput_1ypt0_413:focus{background:var(--color-surface-2);outline:none}._descInput_1ypt0_413::placeholder{color:var(--color-text-muted)}._section_1ypt0_461{padding:var(--space-6) var(--space-8);border-top:1px solid var(--color-border)}._sectionLabel_1ypt0_471{font-size:var(--text-xs);font-weight:500;color:var(--color-text-muted);text-transform:uppercase;letter-spacing:.06em;margin-bottom:var(--space-2);display:block}._priorities_1ypt0_491{display:flex;gap:var(--space-2);flex-wrap:wrap}._priorityBtn_1ypt0_503{padding:var(--space-1) var(--space-3);border-radius:var(--radius-full);font-size:var(--text-xs);font-weight:500;color:var(--color-text-secondary);border:1px solid var(--color-border);transition:all var(--transition-fast)}._priorityBtn_1ypt0_503:hover{border-color:var(--priority-color);color:var(--priority-color)}._priorityBtn_1ypt0_503._selected_1ypt0_533{background:color-mix(in srgb,var(--priority-color) 15%,transparent);border-color:var(--priority-color);color:var(--priority-color)}._footer_1ypt0_545{display:flex;align-items:center;justify-content:space-between;padding:var(--space-6) var(--space-8);border-top:1px solid var(--color-border);flex-shrink:0}._footerActions_1ypt0_563{display:flex;gap:var(--space-2)}._deleteBtn_1ypt0_573{display:flex;align-items:center;gap:var(--space-1);font-size:var(--text-sm);color:var(--color-text-muted);padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);transition:background var(--transition-fast),color var(--transition-fast)}._deleteBtn_1ypt0_573:hover{background:color-mix(in srgb,var(--color-error) 12%,transparent);color:var(--color-error)}._cancelBtn_1ypt0_605{padding:var(--space-2) var(--space-4);border-radius:var(--radius-md);font-size:var(--text-sm);font-weight:500;color:var(--color-text-secondary);border:1px solid var(--color-border);transition:background var(--transition-normal)}._cancelBtn_1ypt0_605:hover{background:var(--color-surface-2)}._saveBtn_1ypt0_633{padding:var(--space-2) var(--space-4);border-radius:var(--radius-md);font-size:var(--text-sm);font-weight:500;color:var(--color-text-on-accent);background:var(--color-accent);transition:opacity var(--transition-fast)}._saveBtn_1ypt0_633:hover:not(:disabled){opacity:.85}._saveBtn_1ypt0_633:disabled{opacity:.4;cursor:not-allowed}._commentsSection_1ypt0_671{padding:var(--space-8);border-top:1px solid var(--color-border);display:flex;flex-direction:column;gap:var(--space-6)}._commentList_1ypt0_687{display:flex;flex-direction:column;gap:12px;max-height:250px;overflow-y:auto;padding-right:4px}._comment_1ypt0_671{background:var(--color-surface-2);padding:var(--space-4) var(--space-5);border-radius:var(--radius-lg);border:1px solid var(--color-border)}._commentHeader_1ypt0_719{display:flex;justify-content:space-between;align-items:center;margin-bottom:var(--space-1);font-size:var(--text-xs)}._commentAuthor_1ypt0_735{font-weight:600;color:var(--color-text-main);display:flex;align-items:center;gap:4px}._botIcon_1ypt0_751{color:var(--color-accent)}._commentDate_1ypt0_759{color:var(--color-text-muted)}._commentContent_1ypt0_767{font-size:.875rem;line-height:1.4;white-space:pre-wrap;word-break:break-word}._noComments_1ypt0_781{text-align:center;padding:24px;color:var(--color-text-muted);font-size:.875rem;font-style:italic}._addComment_1ypt0_797{display:flex;gap:8px;margin-top:8px}._commentInput_1ypt0_809{flex:1;background:var(--color-surface-2);border:1px solid var(--color-border);border-radius:var(--radius-md);padding:var(--space-3) var(--space-4);font-size:var(--text-sm);color:var(--color-text-primary);outline:none;transition:all var(--transition-fast)}._commentInput_1ypt0_809:focus{border-color:var(--color-accent)}._sendBtn_1ypt0_841{background:var(--color-accent);color:var(--color-text-on-accent);border:none;border-radius:6px;width:36px;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:opacity var(--transition-fast)}._sendBtn_1ypt0_841:disabled{opacity:.5;cursor:not-allowed}._sendBtn_1ypt0_841:not(:disabled):hover{opacity:.9}._agentHistoryList_1ypt0_887{display:flex;flex-direction:column;gap:var(--space-3);margin-top:var(--space-3)}._historyItem_1ypt0_901{background:var(--color-surface-2);border:1px solid var(--color-border);border-radius:var(--radius-md);padding:var(--space-3);display:flex;flex-direction:column;gap:var(--space-2)}._historyMeta_1ypt0_921{display:flex;align-items:center;justify-content:space-between}._historyCol_1ypt0_933{font-size:var(--text-sm);font-weight:500;color:var(--color-text-primary)}._historyStatus_1ypt0_945{font-size:var(--text-xs);font-weight:600;text-transform:uppercase;letter-spacing:.05em;padding:2px 6px;border-radius:var(--radius-sm)}._historyStatus_1ypt0_945._processing_1ypt0_175{background:rgba(var(--color-accent-rgb),.15);color:var(--color-accent)}._historyStatus_1ypt0_945._done_1ypt0_193{background:#10b98126;color:#10b981}._historyStatus_1ypt0_945._blocked_1ypt0_211{background:#ef444426;color:#ef4444}._historyStatus_1ypt0_945._needs_approval_1ypt0_993{background:#f59e0b26;color:#f59e0b}._historyLinks_1ypt0_1003{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-3)}._historyLink_1ypt0_1003{align-self:flex-start;display:inline-flex;align-items:center;gap:4px;font-size:var(--text-xs);font-weight:500;color:var(--color-accent);text-decoration:none;transition:opacity var(--transition-fast)}._historyLink_1ypt0_1003:hover{opacity:.8;text-decoration:underline}._historyError_1ypt0_1051{font-size:var(--text-xs);color:var(--color-error);background:color-mix(in srgb,var(--color-error) 10%,transparent);padding:var(--space-2);border-radius:var(--radius-sm);white-space:pre-wrap;word-break:break-all}._overlay_9jvqp_1{position:fixed;top:0;right:0;bottom:0;left:0;background:#000000a6;display:flex;align-items:flex-start;justify-content:center;padding-top:80px;z-index:50;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);animation:_fadeIn_9jvqp_1 .15s ease}@keyframes _fadeIn_9jvqp_1{0%{opacity:0}to{opacity:1}}._modal_9jvqp_47{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-xl);width:500px;max-width:calc(100vw - 32px);box-shadow:var(--shadow-lg);animation:_slideIn_9jvqp_1 .15s cubic-bezier(.16,1,.3,1)}@keyframes _slideIn_9jvqp_1{0%{transform:translateY(-16px);opacity:0}to{transform:translateY(0);opacity:1}}._header_9jvqp_91{display:flex;align-items:center;justify-content:space-between;padding:var(--space-6) var(--space-8);border-bottom:1px solid var(--color-border);font-size:var(--text-lg);font-weight:600}._closeBtn_9jvqp_111{width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:var(--radius-md);color:var(--color-text-muted);transition:background var(--transition-fast),color var(--transition-fast)}._closeBtn_9jvqp_111:hover{background:var(--color-surface-2);color:var(--color-text-primary)}._body_9jvqp_143{padding:var(--space-8);display:flex;flex-direction:column;gap:var(--space-6)}._formGroup_9jvqp_157{display:flex;flex-direction:column;gap:var(--space-2)}._label_9jvqp_169{font-size:var(--text-sm);font-weight:500;color:var(--color-text-primary)}._select_9jvqp_181,._input_9jvqp_183{width:100%;background:var(--color-surface-2);border:1px solid var(--color-border);border-radius:var(--radius-md);padding:var(--space-3) var(--space-4);font-size:var(--text-sm);color:var(--color-text-primary);outline:none;transition:all var(--transition-fast)}._select_9jvqp_181:focus,._input_9jvqp_183:focus{border-color:var(--color-accent)}._footer_9jvqp_217{display:flex;align-items:center;justify-content:flex-end;padding:var(--space-6) var(--space-8);border-top:1px solid var(--color-border);gap:var(--space-3)}._cancelBtn_9jvqp_235{padding:var(--space-2) var(--space-4);border-radius:var(--radius-md);font-size:var(--text-sm);font-weight:500;color:var(--color-text-secondary);border:1px solid var(--color-border);transition:background var(--transition-normal)}._cancelBtn_9jvqp_235:hover{background:var(--color-surface-2)}._saveBtn_9jvqp_263{padding:var(--space-2) var(--space-4);border-radius:var(--radius-md);font-size:var(--text-sm);font-weight:500;color:var(--color-text-on-accent);background:var(--color-accent);transition:opacity var(--transition-fast)}._saveBtn_9jvqp_263:hover:not(:disabled){opacity:.85}._saveBtn_9jvqp_263:disabled{opacity:.4;cursor:not-allowed}._column_1sqby_1{width:var(--column-width);flex-shrink:0;display:flex;flex-direction:column;background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);max-height:calc(100vh - var(--topbar-height) - 48px)}._header_1sqby_25{position:relative;padding:var(--space-3) var(--space-3) var(--space-2);border-bottom:1px solid var(--color-border);flex-shrink:0}._headerRow_1sqby_39{display:flex;align-items:center;gap:var(--space-2)}._name_1sqby_51{font-size:var(--text-sm);font-weight:600;color:var(--color-text-primary);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._count_1sqby_73{font-size:var(--text-xs);color:var(--color-text-muted);background:var(--color-surface-2);border-radius:var(--radius-full);padding:1px 7px;font-weight:500}._headerActions_1sqby_91{display:flex;gap:2px}._iconBtn_1sqby_101{width:24px;height:24px;display:flex;align-items:center;justify-content:center;border-radius:var(--radius-sm);color:var(--color-text-muted);transition:background var(--transition-fast),color var(--transition-fast)}._iconBtn_1sqby_101:hover{background:var(--color-surface-2);color:var(--color-text-primary)}._headerInput_1sqby_133{width:100%;font-size:var(--text-sm);font-weight:600;color:var(--color-text-primary);background:var(--color-surface-2);border:1px solid var(--color-accent);border-radius:var(--radius-sm);padding:var(--space-1) var(--space-2)}._menu_1sqby_155{position:absolute;top:calc(100% + 4px);right:var(--space-2);background:var(--color-surface-2);border:1px solid var(--color-border);border-radius:var(--radius-md);box-shadow:var(--shadow-md);z-index:20;min-width:160px;overflow:hidden;animation:_menuIn_1sqby_1 .1s ease}@keyframes _menuIn_1sqby_1{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}._menuItem_1sqby_207{display:flex;align-items:center;gap:var(--space-2);width:100%;padding:var(--space-2) var(--space-3);font-size:var(--text-sm);color:var(--color-text-secondary);text-align:left;transition:background var(--transition-fast),color var(--transition-fast)}._menuItem_1sqby_207:hover{background:var(--color-surface-3);color:var(--color-text-primary)}._menuItem_1sqby_207._danger_1sqby_241:hover{background:color-mix(in srgb,var(--color-error) 12%,transparent);color:var(--color-error)}._body_1sqby_251{flex:1;overflow-y:auto;overflow-x:hidden;padding:var(--space-2);display:flex;flex-direction:column;gap:var(--space-2);min-height:80px;scroll-behavior:smooth;-webkit-overflow-scrolling:touch}._empty_1sqby_281{font-size:var(--text-xs);color:var(--color-text-muted);text-align:center;padding:var(--space-8) 0}._addTicketInput_1sqby_295{padding:2px}._ticketInput_1sqby_303{width:100%;padding:var(--space-2) var(--space-3);font-size:var(--text-sm);color:var(--color-text-primary);background:var(--color-surface-2);border:1px solid var(--color-accent);border-radius:var(--radius-md)}._addBtn_1sqby_323{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-3);width:100%;font-size:var(--text-sm);color:var(--color-text-muted);border-top:1px solid var(--color-border);border-radius:0 0 var(--radius-lg) var(--radius-lg);transition:background var(--transition-fast),color var(--transition-fast);flex-shrink:0}._addBtn_1sqby_323:hover{background:var(--color-surface-2);color:var(--color-text-primary)}._botIcon_1sqby_361{color:var(--color-accent);margin-right:4px;animation:_pulse_1sqby_1 2s infinite ease-in-out}@keyframes _pulse_1sqby_1{0%{opacity:.6}50%{opacity:1}to{opacity:.6}}._settingsPanel_1sqby_401{position:absolute;top:calc(100% + 4px);left:var(--space-2);right:var(--space-2);background:var(--color-surface-2);border:1px solid var(--color-border);border-radius:var(--radius-md);box-shadow:var(--shadow-lg);z-index:30;padding:var(--space-3);display:flex;flex-direction:column;gap:var(--space-3);animation:_menuIn_1sqby_1 .15s ease-out}._settingsHeader_1sqby_435{display:flex;align-items:center;gap:var(--space-2);font-size:var(--text-xs);font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:var(--color-text-muted);border-bottom:1px solid var(--color-border);padding-bottom:var(--space-2)}._settingGroup_1sqby_461{display:flex;flex-direction:column;gap:var(--space-1)}._settingLabel_1sqby_473{font-size:10px;font-weight:600;color:var(--color-text-muted)}._settingSelect_1sqby_485{width:100%;background:var(--color-surface-3);border:1px solid var(--color-border);border-radius:var(--radius-sm);padding:var(--space-1) var(--space-2);font-size:var(--text-xs);color:var(--color-text-primary);outline:none}._onFinishRow_1sqby_507{display:flex;align-items:center;gap:var(--space-1);color:var(--color-text-muted)}._wrapper_1i3ou_1{display:flex;flex-direction:column;height:100vh;overflow:hidden}._topbar_1i3ou_15{height:var(--topbar-height);display:flex;align-items:center;padding:0 var(--space-6);border-bottom:1px solid var(--color-border);flex-shrink:0;gap:var(--space-4)}._boardName_1i3ou_35{font-size:var(--text-md);font-weight:600;color:var(--color-text-primary);letter-spacing:-.01em}._spacer_1i3ou_49{flex:1}._configBtn_1i3ou_57{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:var(--radius-md);color:var(--color-text-muted);transition:all var(--transition-normal);cursor:pointer}._configBtn_1i3ou_57:hover{background:var(--color-surface-hover);color:var(--color-text-primary)}._columnsArea_1i3ou_91{display:flex;gap:var(--space-4);padding:var(--space-4) var(--space-6);overflow-x:auto;overflow-y:hidden;flex:1;align-items:flex-start}._addColBtn_1i3ou_111{display:flex;align-items:center;gap:var(--space-2);flex-shrink:0;padding:var(--space-3) var(--space-4);font-size:var(--text-sm);font-weight:500;color:var(--color-text-muted);border:1px dashed var(--color-border);border-radius:var(--radius-lg);width:180px;transition:border-color var(--transition-normal),color var(--transition-normal),background var(--transition-normal);white-space:nowrap;align-self:flex-start}._addColBtn_1i3ou_111:hover{border-color:var(--color-accent);color:var(--color-accent);background:var(--color-accent-subtle)}._newColumn_1i3ou_159{flex-shrink:0;width:200px;align-self:flex-start}._newColumnInput_1i3ou_171{width:100%;padding:var(--space-3) var(--space-4);font-size:var(--text-sm);font-weight:500;color:var(--color-text-primary);background:var(--color-surface);border:1px solid var(--color-accent);border-radius:var(--radius-lg)}._emptyView_1i3ou_195{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-4);color:var(--color-text-muted)}._emptyTitle_1i3ou_215{font-size:var(--text-lg);font-weight:600;color:var(--color-text-secondary)}._emptySubtitle_1i3ou_227{font-size:var(--text-sm);color:var(--color-text-muted);max-width:280px;text-align:center;line-height:var(--line-height-normal)}._loadingColumns_1i3ou_245{display:flex;gap:var(--space-4)}._skeleton_1i3ou_255{width:var(--column-width);height:300px;background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);animation:_pulse_1i3ou_1 1.5s ease-in-out infinite}@keyframes _pulse_1i3ou_1{0%,to{opacity:1}50%{opacity:.4}}._switcher_vhltw_1{display:flex;align-items:center;gap:var(--space-1);padding:var(--space-1) var(--space-3);border-radius:var(--radius-md);font-size:var(--text-xs);font-weight:500;color:var(--color-text-muted);border:1px solid var(--color-border);transition:background var(--transition-fast),color var(--transition-fast)}._switcher_vhltw_1:hover{background:var(--color-surface-2);color:var(--color-text-primary)}._shell_8hnwn_1{display:flex;height:100vh;width:100vw;overflow:hidden}._main_8hnwn_15{flex:1;display:flex;flex-direction:column;min-width:0;overflow:hidden}._topBar_8hnwn_31{height:var(--topbar-height);display:flex;align-items:center;justify-content:flex-end;padding:0 var(--space-4);border-bottom:1px solid var(--color-border);flex-shrink:0}._spacer_8hnwn_51{flex:1}._content_8hnwn_59{flex:1;overflow:hidden;display:flex;flex-direction:column}
|