@electric-agent/studio 1.1.0 → 1.3.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/dist/bridge/claude-code-docker.d.ts +27 -1
- package/dist/bridge/claude-code-docker.d.ts.map +1 -1
- package/dist/bridge/claude-code-docker.js +171 -43
- package/dist/bridge/claude-code-docker.js.map +1 -1
- package/dist/bridge/claude-code-sprites.d.ts +24 -0
- package/dist/bridge/claude-code-sprites.d.ts.map +1 -1
- package/dist/bridge/claude-code-sprites.js +177 -39
- package/dist/bridge/claude-code-sprites.js.map +1 -1
- package/dist/bridge/claude-md-generator.d.ts +1 -0
- package/dist/bridge/claude-md-generator.d.ts.map +1 -1
- package/dist/bridge/claude-md-generator.js +64 -7
- package/dist/bridge/claude-md-generator.js.map +1 -1
- package/dist/bridge/codex-docker.d.ts +65 -0
- package/dist/bridge/codex-docker.d.ts.map +1 -0
- package/dist/bridge/codex-docker.js +242 -0
- package/dist/bridge/codex-docker.js.map +1 -0
- package/dist/bridge/codex-json-parser.d.ts +31 -0
- package/dist/bridge/codex-json-parser.d.ts.map +1 -0
- package/dist/bridge/codex-json-parser.js +274 -0
- package/dist/bridge/codex-json-parser.js.map +1 -0
- package/dist/bridge/codex-md-generator.d.ts +14 -0
- package/dist/bridge/codex-md-generator.d.ts.map +1 -0
- package/dist/bridge/codex-md-generator.js +45 -0
- package/dist/bridge/codex-md-generator.js.map +1 -0
- package/dist/bridge/codex-sprites.d.ts +59 -0
- package/dist/bridge/codex-sprites.d.ts.map +1 -0
- package/dist/bridge/codex-sprites.js +237 -0
- package/dist/bridge/codex-sprites.js.map +1 -0
- package/dist/bridge/create-app-skill.d.ts +11 -0
- package/dist/bridge/create-app-skill.d.ts.map +1 -0
- package/dist/bridge/create-app-skill.js +39 -0
- package/dist/bridge/create-app-skill.js.map +1 -0
- package/dist/bridge/index.d.ts +0 -3
- package/dist/bridge/index.d.ts.map +1 -1
- package/dist/bridge/index.js +0 -3
- package/dist/bridge/index.js.map +1 -1
- package/dist/bridge/stream-json-parser.d.ts +0 -2
- package/dist/bridge/stream-json-parser.d.ts.map +1 -1
- package/dist/bridge/stream-json-parser.js +0 -18
- package/dist/bridge/stream-json-parser.js.map +1 -1
- package/dist/client/assets/index-Bq9zwhHj.css +1 -0
- package/dist/client/assets/index-Dgpqg5fv.js +234 -0
- package/dist/client/index.html +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/sandbox/daytona.js +4 -4
- package/dist/sandbox/daytona.js.map +1 -1
- package/dist/sandbox/docker.d.ts +0 -1
- package/dist/sandbox/docker.d.ts.map +1 -1
- package/dist/sandbox/docker.js +10 -42
- package/dist/sandbox/docker.js.map +1 -1
- package/dist/sandbox/sprites.d.ts +0 -6
- package/dist/sandbox/sprites.d.ts.map +1 -1
- package/dist/sandbox/sprites.js +4 -36
- package/dist/sandbox/sprites.js.map +1 -1
- package/dist/sandbox/types.d.ts +0 -8
- package/dist/sandbox/types.d.ts.map +1 -1
- package/dist/server.d.ts +2 -5
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +195 -160
- package/dist/server.js.map +1 -1
- package/dist/session-auth.d.ts +3 -0
- package/dist/session-auth.d.ts.map +1 -0
- package/dist/session-auth.js +11 -0
- package/dist/session-auth.js.map +1 -0
- package/dist/sessions.d.ts +0 -2
- package/dist/sessions.d.ts.map +1 -1
- package/dist/sessions.js.map +1 -1
- package/package.json +2 -2
- package/dist/client/assets/index-BeZ6CTGd.css +0 -1
- package/dist/client/assets/index-DRLXdDNp.js +0 -241
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SessionBridge implementation that runs Codex CLI inside a Sprites
|
|
3
|
+
* sandbox via the Sprites SDK session API, communicating via exec --json NDJSON.
|
|
4
|
+
*
|
|
5
|
+
* The bridge translates Codex's exec --json output into EngineEvents
|
|
6
|
+
* and writes them to the Durable Stream for the UI.
|
|
7
|
+
*
|
|
8
|
+
* Codex runs in one-shot mode (`codex exec --json`) and exits after completing.
|
|
9
|
+
* On iterate (follow-up message), the bridge respawns Codex with the new prompt.
|
|
10
|
+
*/
|
|
11
|
+
import type { EngineEvent } from "@electric-agent/protocol";
|
|
12
|
+
import type { Sprite } from "@fly/sprites";
|
|
13
|
+
import type { StreamConnectionInfo } from "../streams.js";
|
|
14
|
+
import type { SessionBridge } from "./types.js";
|
|
15
|
+
export interface CodexSpritesConfig {
|
|
16
|
+
/** Initial prompt (the user's app description or task) */
|
|
17
|
+
prompt: string;
|
|
18
|
+
/** Working directory inside the sprite */
|
|
19
|
+
cwd: string;
|
|
20
|
+
/** Model to use (default: o4-mini) */
|
|
21
|
+
model?: string;
|
|
22
|
+
/** Additional CLI flags */
|
|
23
|
+
extraFlags?: string[];
|
|
24
|
+
}
|
|
25
|
+
export declare class CodexSpritesBridge implements SessionBridge {
|
|
26
|
+
readonly sessionId: string;
|
|
27
|
+
readonly streamUrl: string;
|
|
28
|
+
readonly streamHeaders: Record<string, string>;
|
|
29
|
+
private sprite;
|
|
30
|
+
private config;
|
|
31
|
+
private writer;
|
|
32
|
+
private parser;
|
|
33
|
+
private agentEventCallbacks;
|
|
34
|
+
private completeCallbacks;
|
|
35
|
+
private closed;
|
|
36
|
+
private cmd;
|
|
37
|
+
/** Codex thread ID captured from thread.started — used for resume */
|
|
38
|
+
private codexThreadId;
|
|
39
|
+
/** Whether a Codex process is currently running */
|
|
40
|
+
private running;
|
|
41
|
+
/** Whether the parser already emitted a session_end */
|
|
42
|
+
private resultReceived;
|
|
43
|
+
constructor(sessionId: string, connection: StreamConnectionInfo, sprite: Sprite, config: CodexSpritesConfig);
|
|
44
|
+
emit(event: EngineEvent): Promise<void>;
|
|
45
|
+
sendCommand(cmd: Record<string, unknown>): Promise<void>;
|
|
46
|
+
sendGateResponse(_gate: string, _value: Record<string, unknown>): Promise<void>;
|
|
47
|
+
onAgentEvent(cb: (event: EngineEvent) => void): void;
|
|
48
|
+
onComplete(cb: (success: boolean) => void): void;
|
|
49
|
+
start(): Promise<void>;
|
|
50
|
+
close(): void;
|
|
51
|
+
/**
|
|
52
|
+
* Spawn a new Codex process. Called for both the initial prompt
|
|
53
|
+
* and follow-up iterate messages.
|
|
54
|
+
*/
|
|
55
|
+
private spawnCodex;
|
|
56
|
+
private handleLine;
|
|
57
|
+
private dispatchEvent;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=codex-sprites.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-sprites.d.ts","sourceRoot":"","sources":["../../src/bridge/codex-sprites.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAE3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAE1C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AAEzD,OAAO,KAAK,EAAE,aAAa,EAAiB,MAAM,YAAY,CAAA;AAE9D,MAAM,WAAW,kBAAkB;IAClC,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAA;IACd,0CAA0C;IAC1C,GAAG,EAAE,MAAM,CAAA;IACX,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,2BAA2B;IAC3B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CACrB;AAED,qBAAa,kBAAmB,YAAW,aAAa;IACvD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAE9C,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,mBAAmB,CAA0C;IACrE,OAAO,CAAC,iBAAiB,CAAwC;IACjE,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,GAAG,CAA6B;IAExC,qEAAqE;IACrE,OAAO,CAAC,aAAa,CAAsB;IAC3C,mDAAmD;IACnD,OAAO,CAAC,OAAO,CAAQ;IACvB,uDAAuD;IACvD,OAAO,CAAC,cAAc,CAAQ;gBAG7B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,oBAAoB,EAChC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,kBAAkB;IAerB,IAAI,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAMvC,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAWxD,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrF,YAAY,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,GAAG,IAAI;IAIpD,UAAU,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI;IAI1C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5B,KAAK,IAAI,IAAI;IAgBb;;;OAGG;IACH,OAAO,CAAC,UAAU;IAyFlB,OAAO,CAAC,UAAU;IAWlB,OAAO,CAAC,aAAa;CA6CrB"}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SessionBridge implementation that runs Codex CLI inside a Sprites
|
|
3
|
+
* sandbox via the Sprites SDK session API, communicating via exec --json NDJSON.
|
|
4
|
+
*
|
|
5
|
+
* The bridge translates Codex's exec --json output into EngineEvents
|
|
6
|
+
* and writes them to the Durable Stream for the UI.
|
|
7
|
+
*
|
|
8
|
+
* Codex runs in one-shot mode (`codex exec --json`) and exits after completing.
|
|
9
|
+
* On iterate (follow-up message), the bridge respawns Codex with the new prompt.
|
|
10
|
+
*/
|
|
11
|
+
import * as readline from "node:readline";
|
|
12
|
+
import { DurableStream } from "@durable-streams/client";
|
|
13
|
+
import { ts } from "@electric-agent/protocol";
|
|
14
|
+
import { SpriteCommand } from "@fly/sprites";
|
|
15
|
+
import { createCodexJsonParser } from "./codex-json-parser.js";
|
|
16
|
+
export class CodexSpritesBridge {
|
|
17
|
+
sessionId;
|
|
18
|
+
streamUrl;
|
|
19
|
+
streamHeaders;
|
|
20
|
+
sprite;
|
|
21
|
+
config;
|
|
22
|
+
writer;
|
|
23
|
+
parser = createCodexJsonParser();
|
|
24
|
+
agentEventCallbacks = [];
|
|
25
|
+
completeCallbacks = [];
|
|
26
|
+
closed = false;
|
|
27
|
+
cmd = null;
|
|
28
|
+
/** Codex thread ID captured from thread.started — used for resume */
|
|
29
|
+
codexThreadId = null;
|
|
30
|
+
/** Whether a Codex process is currently running */
|
|
31
|
+
running = false;
|
|
32
|
+
/** Whether the parser already emitted a session_end */
|
|
33
|
+
resultReceived = false;
|
|
34
|
+
constructor(sessionId, connection, sprite, config) {
|
|
35
|
+
this.sessionId = sessionId;
|
|
36
|
+
this.streamUrl = connection.url;
|
|
37
|
+
this.streamHeaders = connection.headers;
|
|
38
|
+
this.sprite = sprite;
|
|
39
|
+
this.config = config;
|
|
40
|
+
this.writer = new DurableStream({
|
|
41
|
+
url: connection.url,
|
|
42
|
+
headers: connection.headers,
|
|
43
|
+
contentType: "application/json",
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
async emit(event) {
|
|
47
|
+
if (this.closed)
|
|
48
|
+
return;
|
|
49
|
+
const msg = { source: "server", ...event };
|
|
50
|
+
await this.writer.append(JSON.stringify(msg));
|
|
51
|
+
}
|
|
52
|
+
async sendCommand(cmd) {
|
|
53
|
+
if (this.closed)
|
|
54
|
+
return;
|
|
55
|
+
if (cmd.command === "iterate" && typeof cmd.request === "string") {
|
|
56
|
+
this.spawnCodex(cmd.request);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
console.log(`[codex-sprites] Ignoring unsupported command: ${cmd.command}`);
|
|
60
|
+
}
|
|
61
|
+
async sendGateResponse(_gate, _value) {
|
|
62
|
+
// Codex exec --json doesn't support stdin user messages mid-run
|
|
63
|
+
}
|
|
64
|
+
onAgentEvent(cb) {
|
|
65
|
+
this.agentEventCallbacks.push(cb);
|
|
66
|
+
}
|
|
67
|
+
onComplete(cb) {
|
|
68
|
+
this.completeCallbacks.push(cb);
|
|
69
|
+
}
|
|
70
|
+
async start() {
|
|
71
|
+
if (this.closed)
|
|
72
|
+
return;
|
|
73
|
+
this.spawnCodex(this.config.prompt);
|
|
74
|
+
}
|
|
75
|
+
close() {
|
|
76
|
+
this.closed = true;
|
|
77
|
+
if (this.cmd) {
|
|
78
|
+
try {
|
|
79
|
+
this.cmd.kill();
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// Process may already be dead
|
|
83
|
+
}
|
|
84
|
+
this.cmd = null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// -----------------------------------------------------------------------
|
|
88
|
+
// Private helpers
|
|
89
|
+
// -----------------------------------------------------------------------
|
|
90
|
+
/**
|
|
91
|
+
* Spawn a new Codex process. Called for both the initial prompt
|
|
92
|
+
* and follow-up iterate messages.
|
|
93
|
+
*/
|
|
94
|
+
spawnCodex(prompt) {
|
|
95
|
+
// Kill any existing process
|
|
96
|
+
if (this.cmd) {
|
|
97
|
+
try {
|
|
98
|
+
this.cmd.kill();
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
// Already dead
|
|
102
|
+
}
|
|
103
|
+
this.cmd = null;
|
|
104
|
+
}
|
|
105
|
+
// Reset parser state for the new process
|
|
106
|
+
this.parser = createCodexJsonParser();
|
|
107
|
+
this.resultReceived = false;
|
|
108
|
+
this.running = true;
|
|
109
|
+
const model = this.config.model ?? "o4-mini";
|
|
110
|
+
// Build the codex CLI command
|
|
111
|
+
const codexArgs = [
|
|
112
|
+
"exec",
|
|
113
|
+
"--json",
|
|
114
|
+
"--full-auto",
|
|
115
|
+
"--model",
|
|
116
|
+
model,
|
|
117
|
+
...(this.config.extraFlags ?? []),
|
|
118
|
+
"-q",
|
|
119
|
+
prompt,
|
|
120
|
+
];
|
|
121
|
+
// Escape for bash — use bash -c with properly escaped args
|
|
122
|
+
const escapedArgs = codexArgs.map((a) => `'${a.replace(/'/g, "'\\''")}'`).join(" ");
|
|
123
|
+
const fullCmd = `source /etc/profile.d/npm-global.sh 2>/dev/null; source /etc/profile.d/electric-agent.sh 2>/dev/null; cd '${this.config.cwd}' && codex ${escapedArgs}`;
|
|
124
|
+
// Use SpriteCommand with tty:true (for streaming)
|
|
125
|
+
this.cmd = new SpriteCommand(this.sprite, "bash", ["-c", fullCmd], {
|
|
126
|
+
tty: true,
|
|
127
|
+
});
|
|
128
|
+
this.cmd.start();
|
|
129
|
+
console.log(`[codex-sprites] Started: session=${this.sessionId}`);
|
|
130
|
+
const currentCmd = this.cmd;
|
|
131
|
+
// Read stdout line by line (exec --json NDJSON)
|
|
132
|
+
const rl = readline.createInterface({
|
|
133
|
+
input: currentCmd.stdout,
|
|
134
|
+
terminal: false,
|
|
135
|
+
});
|
|
136
|
+
rl.on("line", (line) => {
|
|
137
|
+
if (this.closed)
|
|
138
|
+
return;
|
|
139
|
+
this.handleLine(line);
|
|
140
|
+
});
|
|
141
|
+
// Log stderr
|
|
142
|
+
const stderrRl = readline.createInterface({
|
|
143
|
+
input: currentCmd.stderr,
|
|
144
|
+
terminal: false,
|
|
145
|
+
});
|
|
146
|
+
stderrRl.on("line", (line) => {
|
|
147
|
+
if (!this.closed) {
|
|
148
|
+
console.error(`[codex-sprites:stderr] ${line}`);
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
// Handle process exit — defer to let pending readline events flush first
|
|
152
|
+
currentCmd.on("exit", (code) => {
|
|
153
|
+
console.log(`[codex-sprites] Process exited: code=${code} session=${this.sessionId}`);
|
|
154
|
+
setTimeout(() => {
|
|
155
|
+
// Capture thread ID from parser state before marking not running
|
|
156
|
+
if (this.parser.state.threadId) {
|
|
157
|
+
this.codexThreadId = this.parser.state.threadId;
|
|
158
|
+
}
|
|
159
|
+
this.running = false;
|
|
160
|
+
// Emit session_end if the parser didn't already
|
|
161
|
+
if (!this.closed && !this.resultReceived) {
|
|
162
|
+
const endEvent = {
|
|
163
|
+
type: "session_end",
|
|
164
|
+
success: code === 0,
|
|
165
|
+
ts: ts(),
|
|
166
|
+
};
|
|
167
|
+
this.dispatchEvent(endEvent);
|
|
168
|
+
}
|
|
169
|
+
}, 100);
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
handleLine(line) {
|
|
173
|
+
// Strip ANSI escape sequences and terminal control chars added by tty mode
|
|
174
|
+
const cleaned = stripAnsi(line).trim();
|
|
175
|
+
if (!cleaned)
|
|
176
|
+
return;
|
|
177
|
+
const events = this.parser.parse(cleaned);
|
|
178
|
+
for (const event of events) {
|
|
179
|
+
this.dispatchEvent(event);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
dispatchEvent(event) {
|
|
183
|
+
const msg = { source: "agent", ...event };
|
|
184
|
+
this.writer.append(JSON.stringify(msg)).catch(() => { });
|
|
185
|
+
// Track session_end to prevent duplicates
|
|
186
|
+
if (event.type === "session_end") {
|
|
187
|
+
this.resultReceived = true;
|
|
188
|
+
}
|
|
189
|
+
// Detect dev:start in Bash tool_use → emit app_ready for the UI preview
|
|
190
|
+
if (event.type === "pre_tool_use" && event.tool_name === "Bash") {
|
|
191
|
+
const cmd = event.tool_input?.command;
|
|
192
|
+
if (typeof cmd === "string" && /\bdev:start\b/.test(cmd)) {
|
|
193
|
+
const appReady = { type: "app_ready", ts: ts() };
|
|
194
|
+
const appReadyMsg = { source: "agent", ...appReady };
|
|
195
|
+
this.writer.append(JSON.stringify(appReadyMsg)).catch(() => { });
|
|
196
|
+
for (const cb of this.agentEventCallbacks) {
|
|
197
|
+
try {
|
|
198
|
+
cb(appReady);
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
// Swallow
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
for (const cb of this.agentEventCallbacks) {
|
|
207
|
+
try {
|
|
208
|
+
cb(event);
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
// Swallow callback errors
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (event.type === "session_end" && "success" in event) {
|
|
215
|
+
const success = event.success;
|
|
216
|
+
for (const cb of this.completeCallbacks) {
|
|
217
|
+
try {
|
|
218
|
+
cb(success);
|
|
219
|
+
}
|
|
220
|
+
catch {
|
|
221
|
+
// Swallow callback errors
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/** Strip ANSI escape sequences and control characters from tty output */
|
|
228
|
+
function stripAnsi(str) {
|
|
229
|
+
const ESC = "\x1b";
|
|
230
|
+
const csi = new RegExp(`${ESC}\\[[0-9;]*[a-zA-Z]`, "g");
|
|
231
|
+
const osc1 = new RegExp(`${ESC}\\][^\\x07]*\\x07`, "g");
|
|
232
|
+
const osc2 = new RegExp(`${ESC}\\][^${ESC}]*${ESC}\\\\`, "g");
|
|
233
|
+
// biome-ignore lint/suspicious/noControlCharactersInRegex: strip C0 control chars except \n \r
|
|
234
|
+
const ctrl = /[\x00-\x09\x0b\x0c\x0e-\x1f\x7f]/g;
|
|
235
|
+
return str.replace(csi, "").replace(osc1, "").replace(osc2, "").replace(ctrl, "");
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=codex-sprites.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-sprites.js","sourceRoot":"","sources":["../../src/bridge/codex-sprites.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The create-app skill content as a string constant.
|
|
3
|
+
*
|
|
4
|
+
* This is exported so the server can write the skill to sandboxes where the
|
|
5
|
+
* npm-installed electric-agent package may not include it yet (e.g. version
|
|
6
|
+
* mismatch between the server and the globally installed CLI).
|
|
7
|
+
*
|
|
8
|
+
* The content must stay in sync with packages/agent/template/.claude/skills/create-app/SKILL.md.
|
|
9
|
+
*/
|
|
10
|
+
export declare const createAppSkillContent: string;
|
|
11
|
+
//# sourceMappingURL=create-app-skill.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-app-skill.d.ts","sourceRoot":"","sources":["../../src/bridge/create-app-skill.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAqCH,eAAO,MAAM,qBAAqB,QAAqB,CAAA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The create-app skill content as a string constant.
|
|
3
|
+
*
|
|
4
|
+
* This is exported so the server can write the skill to sandboxes where the
|
|
5
|
+
* npm-installed electric-agent package may not include it yet (e.g. version
|
|
6
|
+
* mismatch between the server and the globally installed CLI).
|
|
7
|
+
*
|
|
8
|
+
* The content must stay in sync with packages/agent/template/.claude/skills/create-app/SKILL.md.
|
|
9
|
+
*/
|
|
10
|
+
import fs from "node:fs";
|
|
11
|
+
import path from "node:path";
|
|
12
|
+
import { fileURLToPath } from "node:url";
|
|
13
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
14
|
+
/**
|
|
15
|
+
* Read the create-app skill from the agent template directory.
|
|
16
|
+
* Falls back to a minimal stub if the file can't be found (e.g. in tests).
|
|
17
|
+
*/
|
|
18
|
+
function loadSkillContent() {
|
|
19
|
+
// Path from studio/dist/bridge/ → agent/template/.claude/skills/create-app/SKILL.md
|
|
20
|
+
const candidates = [
|
|
21
|
+
path.resolve(__dirname, "../../../agent/template/.claude/skills/create-app/SKILL.md"),
|
|
22
|
+
// In npm-installed context, the agent package may be in node_modules
|
|
23
|
+
path.resolve(__dirname, "../../node_modules/@electric-agent/agent/template/.claude/skills/create-app/SKILL.md"),
|
|
24
|
+
];
|
|
25
|
+
for (const candidate of candidates) {
|
|
26
|
+
try {
|
|
27
|
+
if (fs.existsSync(candidate)) {
|
|
28
|
+
return fs.readFileSync(candidate, "utf-8");
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// Continue to next candidate
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
console.warn("[create-app-skill] Could not find SKILL.md in any expected location");
|
|
36
|
+
return "";
|
|
37
|
+
}
|
|
38
|
+
export const createAppSkillContent = loadSkillContent();
|
|
39
|
+
//# sourceMappingURL=create-app-skill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-app-skill.js","sourceRoot":"","sources":["../../src/bridge/create-app-skill.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AAE9D;;;GAGG;AACH,SAAS,gBAAgB;IACxB,oFAAoF;IACpF,MAAM,UAAU,GAAG;QAClB,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,4DAA4D,CAAC;QACrF,qEAAqE;QACrE,IAAI,CAAC,OAAO,CACX,SAAS,EACT,sFAAsF,CACtF;KACD,CAAA;IAED,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACpC,IAAI,CAAC;YACJ,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC9B,OAAO,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;YAC3C,CAAC;QACF,CAAC;QAAC,MAAM,CAAC;YACR,6BAA6B;QAC9B,CAAC;IACF,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,qEAAqE,CAAC,CAAA;IACnF,OAAO,EAAE,CAAA;AACV,CAAC;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG,gBAAgB,EAAE,CAAA"}
|
package/dist/bridge/index.d.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
export { ClaudeCodeDockerBridge, type ClaudeCodeDockerConfig } from "./claude-code-docker.js";
|
|
2
2
|
export { ClaudeCodeSpritesBridge, type ClaudeCodeSpritesConfig } from "./claude-code-sprites.js";
|
|
3
|
-
export { DaytonaSessionBridge } from "./daytona.js";
|
|
4
|
-
export { DockerStdioBridge } from "./docker-stdio.js";
|
|
5
3
|
export { HostedStreamBridge } from "./hosted.js";
|
|
6
|
-
export { SpritesStdioBridge } from "./sprites.js";
|
|
7
4
|
export { createStreamJsonParser } from "./stream-json-parser.js";
|
|
8
5
|
export type { AgentEvent, ServerCommand, ServerGateResponse, SessionBridge, StreamMessage, } from "./types.js";
|
|
9
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bridge/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,KAAK,sBAAsB,EAAE,MAAM,yBAAyB,CAAA;AAC7F,OAAO,EAAE,uBAAuB,EAAE,KAAK,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AAChG,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bridge/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,KAAK,sBAAsB,EAAE,MAAM,yBAAyB,CAAA;AAC7F,OAAO,EAAE,uBAAuB,EAAE,KAAK,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AAChG,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAA;AAChE,YAAY,EACX,UAAU,EACV,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,aAAa,GACb,MAAM,YAAY,CAAA"}
|
package/dist/bridge/index.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
export { ClaudeCodeDockerBridge } from "./claude-code-docker.js";
|
|
2
2
|
export { ClaudeCodeSpritesBridge } from "./claude-code-sprites.js";
|
|
3
|
-
export { DaytonaSessionBridge } from "./daytona.js";
|
|
4
|
-
export { DockerStdioBridge } from "./docker-stdio.js";
|
|
5
3
|
export { HostedStreamBridge } from "./hosted.js";
|
|
6
|
-
export { SpritesStdioBridge } from "./sprites.js";
|
|
7
4
|
export { createStreamJsonParser } from "./stream-json-parser.js";
|
|
8
5
|
//# sourceMappingURL=index.js.map
|
package/dist/bridge/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/bridge/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAA+B,MAAM,yBAAyB,CAAA;AAC7F,OAAO,EAAE,uBAAuB,EAAgC,MAAM,0BAA0B,CAAA;AAChG,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/bridge/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAA+B,MAAM,yBAAyB,CAAA;AAC7F,OAAO,EAAE,uBAAuB,EAAgC,MAAM,0BAA0B,CAAA;AAChG,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAA"}
|
|
@@ -14,8 +14,6 @@ import type { EngineEvent } from "@electric-agent/protocol";
|
|
|
14
14
|
export interface StreamJsonParserState {
|
|
15
15
|
/** Map tool_use_id → tool_name for correlating post_tool_use events */
|
|
16
16
|
toolNames: Map<string, string>;
|
|
17
|
-
/** Accumulated cost from result messages */
|
|
18
|
-
totalCost: number;
|
|
19
17
|
/** Claude Code session ID from init */
|
|
20
18
|
sessionId: string | null;
|
|
21
19
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream-json-parser.d.ts","sourceRoot":"","sources":["../../src/bridge/stream-json-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AA+D3D,MAAM,WAAW,qBAAqB;IACrC,uEAAuE;IACvE,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,
|
|
1
|
+
{"version":3,"file":"stream-json-parser.d.ts","sourceRoot":"","sources":["../../src/bridge/stream-json-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AA+D3D,MAAM,WAAW,qBAAqB;IACrC,uEAAuE;IACvE,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,uCAAuC;IACvC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CACxB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB;;gBAQxB,MAAM,GAAG,WAAW,EAAE;EAInC"}
|
|
@@ -18,7 +18,6 @@ import { ts } from "@electric-agent/protocol";
|
|
|
18
18
|
export function createStreamJsonParser() {
|
|
19
19
|
const state = {
|
|
20
20
|
toolNames: new Map(),
|
|
21
|
-
totalCost: 0,
|
|
22
21
|
sessionId: null,
|
|
23
22
|
};
|
|
24
23
|
return {
|
|
@@ -84,15 +83,6 @@ function handleAssistant(msg, state) {
|
|
|
84
83
|
});
|
|
85
84
|
}
|
|
86
85
|
break;
|
|
87
|
-
case "thinking":
|
|
88
|
-
if (block.thinking) {
|
|
89
|
-
events.push({
|
|
90
|
-
type: "assistant_thinking",
|
|
91
|
-
text: block.thinking,
|
|
92
|
-
ts: ts(),
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
break;
|
|
96
86
|
case "tool_use": {
|
|
97
87
|
// Track tool name for post_tool_use correlation
|
|
98
88
|
state.toolNames.set(block.id, block.name);
|
|
@@ -168,14 +158,6 @@ function handleUser(msg, state) {
|
|
|
168
158
|
}
|
|
169
159
|
function handleResult(msg, state) {
|
|
170
160
|
const events = [];
|
|
171
|
-
if (msg.cost_usd != null) {
|
|
172
|
-
state.totalCost = msg.cost_usd;
|
|
173
|
-
events.push({
|
|
174
|
-
type: "cost_update",
|
|
175
|
-
totalCostUsd: msg.cost_usd,
|
|
176
|
-
ts: ts(),
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
161
|
const success = msg.subtype === "success";
|
|
180
162
|
events.push({
|
|
181
163
|
type: "session_end",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream-json-parser.js","sourceRoot":"","sources":["../../src/bridge/stream-json-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAA;
|
|
1
|
+
{"version":3,"file":"stream-json-parser.js","sourceRoot":"","sources":["../../src/bridge/stream-json-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@font-face{font-family:OpenSauceOne;font-style:normal;font-weight:300;src:url(/assets/OpenSauceOne-Light-NEdTeQp-.woff2) format("woff2")}@font-face{font-family:OpenSauceOne;font-style:normal;font-weight:400;src:url(/assets/OpenSauceOne-Regular-BivIUdzJ.woff2) format("woff2")}@font-face{font-family:OpenSauceOne;font-style:normal;font-weight:500;src:url(/assets/OpenSauceOne-Medium-Cu5cjAHY.woff2) format("woff2")}@font-face{font-family:OpenSauceOne;font-style:normal;font-weight:600;src:url(/assets/OpenSauceOne-Bold-BeiFYFR5.woff2) format("woff2")}@font-face{font-family:OpenSauceOne;font-style:normal;font-weight:700;src:url(/assets/OpenSauceOne-ExtraBold-DO6BqiNe.woff2) format("woff2")}@font-face{font-family:SourceCodePro;font-style:normal;font-weight:400;src:url(/assets/SourceCodePro-Regular-CoIbWt_c.woff2) format("woff2")}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}:root{--bg: #1b1b1f;--bg-surface: #202127;--bg-hover: #2a2a32;--border: #3a3a44;--text: rgba(255, 255, 245, .92);--text-muted: rgba(235, 235, 245, .68);--text-subtle: rgba(235, 235, 245, .46);--brand-1: #d0bcff;--brand-2: #998fe7;--brand-3: #7e78db;--electric-color: #00d2a0;--tanstack-db-color: #ff8c3b;--durable-streams-color: #75fbfd;--green: #3fb950;--yellow: #d29922;--red: #f85149;--purple: #d0bcff;--blue: #9ecbff;--orange: #ff8c3b;--cyan: #75fbfd;--font-sans: OpenSauceOne, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono: SourceCodePro, ui-monospace, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--sh-keyword: #d0bcff;--sh-string: #3fb950;--sh-number: #ff8c3b;--sh-comment: rgba(235, 235, 245, .38);--sh-class: #d29922;--sh-identifier: #9ecbff;--sh-property: #75fbfd;--sh-sign: rgba(235, 235, 245, .5);--sh-entity: #f85149;--sh-jsxliterals: rgba(255, 255, 245, .92);--sidebar-width: 240px;--topbar-height: 48px;--footer-height: 60px}html,body,#root{height:100%;width:100%;background:var(--bg);color:var(--text);font-family:var(--font-sans);font-size:15px;line-height:1.6}*{scrollbar-width:thin;scrollbar-color:var(--border) transparent}*::-webkit-scrollbar{width:6px;height:6px}*::-webkit-scrollbar-track{background:transparent}*::-webkit-scrollbar-thumb{background:var(--border);border-radius:3px}*::-webkit-scrollbar-thumb:hover{background:var(--text-subtle)}.app-shell{display:grid;grid-template-columns:var(--sidebar-width) 1fr;height:100vh;overflow:hidden;transition:grid-template-columns .2s ease;position:relative}.app-shell.sidebar-collapsed{--sidebar-width: 64px}.sidebar{display:flex;flex-direction:column;height:100%;background:var(--bg-surface);border-right:1px solid var(--border);overflow:hidden;transition:width .2s ease}.sidebar-header{display:flex;align-items:center;gap:8px;padding:0 16px;border-bottom:1px solid var(--border);height:var(--topbar-height);flex-shrink:0}.sidebar-icon{width:24px;height:24px;flex-shrink:0}.sidebar-brand{font-size:15px;font-weight:600;color:var(--text);white-space:nowrap;overflow:hidden}.global-settings-btn{position:absolute;top:8px;right:12px;width:32px;height:32px;display:flex;align-items:center;justify-content:center;border:none;background:none;color:var(--text-subtle);cursor:pointer;border-radius:4px;z-index:50;transition:color .15s,background .15s}.global-settings-btn:hover{color:var(--text);background:var(--bg-hover)}.sidebar-collapse{padding:0 8px;flex-shrink:0;border-top:1px solid var(--border);height:var(--footer-height);display:flex;align-items:center;box-sizing:border-box}.sidebar-collapse-btn{display:flex;align-items:center;gap:8px;width:100%;height:32px;padding:0 16px;border:none;background:none;color:var(--text-subtle);cursor:pointer;border-radius:4px;font-size:13px;transition:color .15s,background .15s}.sidebar-collapse-btn:hover{color:var(--text);background:var(--bg-hover)}.sidebar-collapse-btn svg{width:16px;height:16px;flex-shrink:0}.sidebar-collapse-label{white-space:nowrap;overflow:hidden;opacity:1;max-width:120px;transition:opacity .15s ease,max-width .2s ease}.sidebar-collapsed .sidebar-collapse-btn{gap:0}.sidebar-collapsed .sidebar-collapse-label{opacity:0;max-width:0;display:none}.sidebar-collapsed .sidebar-brand{display:none}.sidebar-collapsed .sidebar-section-label{font-size:0;padding:0 8px;margin:4px 0;height:1px;background:var(--border);border-radius:1px}.sidebar-collapsed .sidebar-section-label:first-child{display:none}.sidebar-collapsed .session-item{gap:0}.sidebar-collapsed .session-item-details,.sidebar-collapsed .session-item-delete,.sidebar-collapsed .session-item:hover .session-item-delete{opacity:0;width:0;overflow:hidden;pointer-events:none}.sidebar-section-label{font-size:11px;color:var(--text-subtle);text-transform:uppercase;letter-spacing:.05em;padding:8px 12px 4px}.sidebar-sessions{flex:1;overflow-y:auto;padding:0 4px}.session-content{display:flex;flex-direction:column;flex:1;overflow:hidden}.session-header{display:flex;align-items:center;gap:8px;padding:0 52px 0 16px;height:var(--topbar-height);font-size:13px;position:absolute;top:0;left:0;right:0;z-index:10;background:#1b1b1fcc;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-bottom:1px solid rgba(58,58,68,.5)}.session-header-name{font-weight:600;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.session-header-status{font-size:11px;margin-left:auto;flex-shrink:0}.session-header-action{font-size:12px;font-family:var(--font-mono);cursor:pointer;color:var(--text-muted);background:transparent;border:1px solid var(--border);border-radius:6px;padding:4px 10px;transition:color .15s,background .15s,border-color .15s;flex-shrink:0;text-decoration:none;line-height:1.4}.session-header-action:hover{color:var(--text);background:var(--bg-hover);border-color:var(--text-subtle)}.session-header-action:disabled{opacity:.5;cursor:not-allowed}.session-header-action.primary{border-color:var(--brand-3);color:var(--brand-1)}.session-header-action.primary:hover{background:var(--brand-2);border-color:var(--brand-2);color:#fff}.session-initializing{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;color:var(--text-muted);font-size:15px;padding-top:var(--topbar-height)}.session-loading{padding:calc(var(--topbar-height) + 16px) 16px 16px;flex:1}.session-initializing-spinner{width:28px;height:28px;border:3px solid var(--border);border-top-color:var(--brand-1);border-radius:50%;animation:spin .8s linear infinite}.main-content{display:flex;flex-direction:column;height:100%;overflow:hidden;position:relative}.console{flex:1;overflow-y:auto;padding:calc(var(--topbar-height) + 16px) 16px 16px;position:relative}.mobile-preview-bar~.console{padding-top:16px}.jump-to-bottom{position:sticky;bottom:8px;left:50%;transform:translate(-50%);display:block;margin:0 auto;padding:6px 16px;font-size:11px;font-family:var(--font-mono);color:var(--text);background:var(--bg-surface);border:1px solid var(--border);border-radius:16px;cursor:pointer;z-index:10;opacity:.9;transition:opacity .15s}.jump-to-bottom:hover{opacity:1;background:var(--bg-hover)}.prompt-bar{display:flex;align-items:center;gap:8px;padding:8px 16px;border-top:1px solid var(--border);height:var(--footer-height);box-sizing:border-box;flex-shrink:0}.prompt-bar textarea{flex:1;padding:10px 14px;background:var(--bg-surface);border:1px solid var(--border);border-radius:8px;color:var(--text);font-family:var(--font-sans);font-size:15px;line-height:1.5;resize:none;min-height:44px;max-height:200px;transition:border-color .15s,box-shadow .15s}.prompt-bar textarea:hover{border-color:var(--border)}.prompt-bar textarea:focus{outline:none;border-color:var(--border);box-shadow:none}.prompt-bar textarea::placeholder{color:var(--text-subtle)}.hero{display:flex;flex-direction:column;align-items:center;justify-content:center;flex:1;padding:0 24px;text-align:center}.hero-logo{height:64px;margin-bottom:16px}.hero-subtitle{font-size:17px;font-weight:500;color:var(--text-muted);margin-bottom:36px}.hero-prompt{width:100%;max-width:640px}.hero-prompt .prompt-bar{border-top:none;padding:0;gap:0;background:var(--bg-surface);border:1px solid var(--border);border-radius:14px;overflow:hidden;align-items:center}.hero-prompt .prompt-bar textarea{border:none;border-radius:0;background:transparent;min-height:52px;font-size:15px;padding:14px}.hero-prompt .prompt-bar textarea:hover,.hero-prompt .prompt-bar textarea:focus{border:none;box-shadow:none}.hero-prompt .prompt-bar button{border:none;border-radius:0 13px 13px 0;min-height:52px;padding:8px 24px;flex-shrink:0;align-self:stretch}.shared-session-header{display:flex;align-items:center;gap:8px;padding:0 52px 0 16px;border-bottom:1px solid var(--border);height:var(--topbar-height);flex-shrink:0;font-size:13px}.shared-session-header-name{font-weight:600;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.shared-session-header-participants{display:flex;align-items:center;gap:4px}.shared-session-participant{width:24px;height:24px;border-radius:50%;background:var(--brand-3);color:#fff;font-size:10px;font-weight:600;font-family:var(--font-mono);display:flex;align-items:center;justify-content:center;flex-shrink:0}.invite-code-label{font-size:12px;color:var(--text-subtle);flex-shrink:0;margin-left:auto}.invite-code-btn{font-family:var(--font-mono);font-size:12px;padding:4px 10px;border:1px dashed var(--border);border-radius:6px;background:transparent;color:var(--text-muted);cursor:pointer;transition:color .15s,background .15s,border-color .15s;flex-shrink:0}.invite-code-btn:hover{color:var(--text);background:var(--bg-hover);border-color:var(--text-subtle)}.shared-session-panels{display:flex;flex-direction:column;gap:2px;flex:1;overflow-y:auto;padding:0}.shared-session-panel{border:1px solid var(--border);border-radius:8px;overflow:hidden;display:flex;flex-direction:column}.shared-session-panel-header{display:flex;align-items:center;gap:8px;height:40px;padding:0 12px;cursor:pointer;font-size:13px;font-family:var(--font-mono);background:var(--bg-surface);transition:background .1s;flex-shrink:0;-webkit-user-select:none;user-select:none}.shared-session-panel-header:hover{background:var(--bg-hover)}.shared-session-panel-chevron{width:14px;height:14px;flex-shrink:0;color:var(--text-subtle);transition:transform .2s ease}.shared-session-panel.collapsed .shared-session-panel-chevron{transform:rotate(-90deg)}.shared-session-panel-id{color:var(--text-muted);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.shared-session-panel-body{display:none;flex-direction:column;overflow:hidden}.shared-session-panel.expanded .shared-session-panel-body{display:flex;flex:1}.shared-session-panel.expanded{flex:1}.shared-session-unlink-btn{font-size:11px;font-family:var(--font-mono);padding:2px 8px;border:1px solid var(--border);border-radius:4px;background:transparent;color:var(--text-subtle);cursor:pointer;transition:color .1s,border-color .1s;flex-shrink:0}.shared-session-unlink-btn:hover{color:var(--red);border-color:var(--red)}.shared-session-content{display:flex;flex-direction:column;flex:1;overflow:hidden;padding:8px;gap:8px}.shared-session-toolbar{display:flex;align-items:center;gap:8px;padding:4px 8px;flex-shrink:0}.shared-session-toolbar-label{font-size:12px;font-family:var(--font-mono);color:var(--text-subtle)}.shared-session-link-btn{font-size:12px;font-family:var(--font-mono);padding:4px 10px;border:1px solid var(--brand-3);border-radius:6px;background:transparent;color:var(--brand-1);cursor:pointer;transition:background .15s,color .15s}.shared-session-link-btn:hover{background:var(--brand-2);color:#fff}.shared-session-empty{display:flex;align-items:center;justify-content:center;flex:1;color:var(--text-subtle);font-size:14px}.session-avatar-shared{box-shadow:0 0 0 2px var(--bg-surface),0 0 0 4px var(--purple)}.sidebar-join-input{display:flex;align-items:center;gap:4px;padding:4px 8px;margin-bottom:2px}.sidebar-join-input input{flex:1;min-width:0;padding:4px 8px;background:var(--bg);border:1px solid var(--border);border-radius:4px;color:var(--text);font-family:var(--font-mono);font-size:12px}.sidebar-join-input input:focus{outline:none;border-color:var(--brand-2)}.sidebar-join-input input::placeholder{color:var(--text-subtle)}.sidebar-join-go{padding:4px 8px;border:1px solid var(--border);border-radius:4px;background:var(--bg-surface);color:var(--text-muted);font-family:var(--font-mono);font-size:12px;cursor:pointer;flex-shrink:0}.sidebar-join-go:hover{background:var(--bg-hover);color:var(--text)}.sidebar-join-go:disabled{opacity:.5;cursor:not-allowed}.shared-session-error{display:flex;flex-direction:column;align-items:center;justify-content:center;flex:1;gap:12px;color:var(--text-muted);font-size:14px;padding:24px;text-align:center}.shared-session-error h2{font-size:18px;color:var(--text);margin:0}.shared-session-error p{margin:0}.console-entry{display:flex;align-items:baseline;gap:0;padding:3px 0;font-family:var(--font-mono);font-size:13px;line-height:1.6}.console a{color:var(--brand-1);text-decoration:none}.console a:hover{text-decoration:underline}.console-entry .prefix{font-weight:600;margin-right:6px}.console-entry .prefix.plan{color:var(--brand-1)}.console-entry .prefix.approve{color:var(--brand-2)}.console-entry .prefix.task{color:var(--blue)}.console-entry .prefix.build{color:var(--brand-2)}.console-entry .prefix.fix{color:var(--yellow)}.console-entry .prefix.done{color:var(--green)}.console-entry .prefix.error{color:var(--red)}.console-entry .prefix.debug{color:var(--text-subtle)}.duration{margin-left:auto;font-family:var(--font-mono);font-size:11px;color:var(--text-subtle);white-space:nowrap;flex-shrink:0}.user-message{padding:3px 0;margin:0}.tool-inline{margin:0;padding:0}.tool-inline summary{display:flex;align-items:center;gap:6px;padding:3px 0;cursor:pointer;font-family:var(--font-mono);font-size:13px;color:var(--text-subtle);-webkit-user-select:none;user-select:none;list-style:none;line-height:1.6}.tool-inline summary::-webkit-details-marker{display:none}.tool-inline summary:hover .tool-inline-name{text-decoration:underline}.tool-inline summary:hover .tool-inline-summary{text-decoration:underline;color:var(--text-muted)}.tool-inline-agent{font-weight:600;color:var(--blue);font-size:13px}.tool-inline-name{font-weight:600;color:var(--brand-1);font-size:13px}.tool-inline-summary{color:var(--text-subtle);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:600px}.tool-inline-command{color:var(--text-muted);font-family:var(--font-mono);font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.spinner-inline{width:10px;height:10px;border:1.5px solid var(--border);border-top-color:var(--brand-1);border-radius:50%;animation:spin .8s linear infinite;flex-shrink:0}@keyframes spin{to{transform:rotate(360deg)}}.tool-inline-body{padding:8px 0 8px 16px;border-left:2px solid var(--border);margin:2px 0 4px 6px}.tool-inline-body pre{font-family:var(--font-mono);font-size:12px;line-height:1.5;color:var(--text-muted);white-space:pre-wrap;word-break:break-all;max-height:400px;overflow-y:auto}.tool-inline-body .section-label{font-size:11px;font-weight:600;color:var(--text-subtle);text-transform:uppercase;letter-spacing:.05em;margin:8px 0 4px}.tool-inline-body .section-label:first-child{margin-top:0}.thinking-inline{margin:0;padding:0}.thinking-inline summary{display:flex;align-items:center;gap:6px;padding:3px 0;cursor:pointer;font-family:var(--font-mono);font-size:13px;color:var(--text-subtle);-webkit-user-select:none;user-select:none;list-style:none;line-height:1.6}.thinking-inline summary::-webkit-details-marker{display:none}.thinking-inline summary:hover .thinking-label,.thinking-inline summary:hover .thinking-preview{text-decoration:underline;color:var(--text-muted)}.thinking-label{color:var(--brand-2);font-size:13px;font-weight:600;flex-shrink:0}.thinking-inline summary:hover .thinking-label{color:var(--brand-2)}.thinking-preview{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text-subtle);max-width:600px}.thinking-body{padding:8px 0 8px 16px;border-left:2px solid var(--border);margin:2px 0 4px 6px}.thinking-body pre{font-family:var(--font-mono);font-size:12px;line-height:1.5;color:var(--text-muted);white-space:pre-wrap;word-break:break-word;max-height:400px;overflow-y:auto}.waiting-indicator{gap:6px;color:var(--text-subtle);animation:fade-pulse 2s ease-in-out infinite}.waiting-label{font-style:italic}@keyframes fade-pulse{0%,to{opacity:1}50%{opacity:.5}}.tool-group{margin:2px 0;padding:0}.tool-group-header{display:flex;align-items:center;gap:6px;padding:3px 0;cursor:pointer;font-family:var(--font-mono);font-size:13px;color:var(--text-muted);-webkit-user-select:none;user-select:none;line-height:1.6}.tool-group-header:hover .tool-group-label{text-decoration:underline}.tool-group-label{font-weight:600;color:var(--brand-1)}.tool-group-tail,.tool-group-items{padding-left:16px}.tool-group-tail{overflow:hidden}.tool-group-slide-in{animation:group-slide-in .25s ease-out}@keyframes group-slide-in{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.todo-list{list-style:none;padding:0;margin:0}.todo-item{display:flex;align-items:center;gap:8px;padding:3px 0;font-family:var(--font-mono);font-size:13px;line-height:1.6;color:var(--text-muted)}.todo-status-icon{width:16px;text-align:center;flex-shrink:0;font-size:14px}.todo-status-done{color:var(--green)}.todo-status-progress{color:var(--brand-1)}.todo-status-pending{color:var(--text-subtle)}.todo-content{flex:1}.todo-priority{font-size:11px;padding:1px 6px;border-radius:4px;background:#ffffff0f;color:var(--text-subtle);flex-shrink:0}.gate-prompt{margin:8px 0;padding:16px;border:1px solid var(--border);border-radius:8px;background:var(--bg-surface)}.gate-prompt h3{font-family:var(--font-sans);font-size:15px;font-weight:600;margin-bottom:8px;color:var(--brand-1)}.gate-prompt .gate-summary{color:var(--text-muted);font-size:13px;font-family:var(--font-sans);margin-bottom:12px}.gate-plan{margin:8px 0}.gate-plan-body{padding:4px 0}.gate-plan-actions{display:flex;gap:8px;margin-top:12px;padding:12px 0;border-top:1px solid var(--border)}.gate-prompt .question{margin-bottom:8px}.gate-prompt .question label{display:block;font-family:var(--font-sans);font-size:13px;color:var(--text-muted);margin-bottom:4px}.gate-prompt .question input,.gate-prompt .question select,.gate-prompt .question textarea{width:100%;padding:8px 12px;background:var(--bg);border:1px solid var(--border);border-radius:8px;color:var(--text);font-family:var(--font-mono);font-size:13px;transition:border-color .15s,box-shadow .15s,background .15s}.gate-prompt .question textarea{resize:vertical}.gate-prompt .question input::placeholder,.gate-prompt .question textarea::placeholder{color:var(--text-subtle)}.gate-prompt .question select{appearance:none;-webkit-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='%23888' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 10px center;padding-right:30px;cursor:pointer}.gate-prompt .question input:hover,.gate-prompt .question textarea:hover,.gate-prompt .question select:hover{border-color:var(--text-subtle)}.gate-prompt .question input:focus,.gate-prompt .question textarea:focus,.gate-prompt .question select:focus{outline:none;border-color:var(--brand-2);box-shadow:0 0 0 3px #998fe726}.gate-prompt .question input:disabled,.gate-prompt .question textarea:disabled,.gate-prompt .question select:disabled{opacity:.5;cursor:not-allowed}.gate-actions{display:flex;gap:8px;margin-top:12px}.gate-btn{padding:8px 18px;border-radius:8px;border:1px solid var(--border);background:var(--bg);color:var(--text-muted);font-family:var(--font-mono);font-size:13px;cursor:pointer;transition:background .15s,border-color .15s,color .15s,box-shadow .15s}.gate-btn:hover{background:var(--bg-hover);border-color:var(--text-subtle)}.gate-btn:disabled{opacity:.5;cursor:not-allowed}.gate-btn-primary{background:transparent;border-color:var(--brand-3);color:var(--brand-1);font-weight:600}.gate-btn-primary:hover{background:var(--brand-2);border-color:var(--brand-2);color:#fff}.gate-btn-danger{border-color:var(--red);color:var(--red)}.gate-btn-danger:hover{background:#f851491a}.gate-continue{display:flex;align-items:center;gap:12px;margin:4px 0;padding:8px 12px;border:1px solid var(--border);border-radius:8px;background:var(--bg-surface);font-family:var(--font-mono);font-size:13px}.gate-continue-text{color:var(--text-muted);flex:1}.gate-continue .gate-btn{padding:4px 12px;font-size:12px}.gate-radio-group{display:flex;gap:12px;margin-top:4px;padding:4px 0}.gate-radio{display:inline-flex;align-items:center;gap:8px;font-family:var(--font-mono);font-size:13px;color:var(--text);cursor:pointer;line-height:1.4;padding:8px 12px;border-radius:8px;border:1px solid var(--border);transition:background .15s,border-color .15s}.gate-radio:hover{background:var(--bg-hover);border-color:var(--text-subtle)}.gate-radio:has(input:checked){border-color:var(--brand-2);background:var(--bg-hover)}.gate-radio input[type=radio],.gate-radio input[type=checkbox]{width:auto;margin:0;vertical-align:middle;accent-color:var(--brand-2)}.gate-option-group{display:flex;gap:8px;margin:8px 0}.gate-option{flex:1;display:flex;flex-direction:column;gap:4px;padding:10px 14px;border:1px solid var(--border);border-radius:8px;background:transparent;cursor:pointer;text-align:left;transition:background .15s,border-color .15s,box-shadow .15s}.gate-option:hover{background:var(--bg-hover);border-color:var(--text-subtle)}.gate-option.active{border-color:var(--brand-2);background:var(--bg-hover)}.gate-option:disabled{opacity:.5;cursor:not-allowed}.gate-option.selected{border-color:var(--green);opacity:1}.gate-option-title{font-family:var(--font-mono);font-size:13px;font-weight:600;color:var(--text)}.gate-option-desc{font-size:11px;color:var(--text-subtle);line-height:1.3}.gate-answered{margin:0}.gate-answered-header{display:flex;align-items:center;gap:0;padding:3px 0;font-family:var(--font-mono);font-size:13px;line-height:1.6}.gate-answered-header .prefix{font-weight:600;margin-right:6px}.gate-resolved-label{color:var(--text-subtle)}.gate-answered .gate-prompt,.gate-answered .gate-plan,.gate-answered .gate-continue{opacity:.65}.gate-continue-decision{color:var(--text-muted);font-style:italic}.gate-config-summary{background:#ffffff0a;border:1px solid rgba(255,255,255,.1);border-radius:6px;padding:8px 10px;margin:6px 0;font-family:var(--font-mono);font-size:12px;line-height:1.6;word-break:break-all;color:var(--text-muted)}.gate-config-summary a{color:var(--brand-1);word-break:break-all}.gate-answer-summary{font-family:var(--font-mono);font-size:13px;color:var(--text-muted);padding:6px 10px;margin:8px 0;background:#ffffff0a;border:1px solid rgba(255,255,255,.1);border-radius:6px}.gate-option-group-vert{display:flex;flex-direction:column;gap:6px;margin:8px 0}.gate-option-group-vert .gate-option{flex:none}.gate-option.gate-option-other{border-style:dashed;opacity:.7}.gate-option.gate-option-other:hover{opacity:1}.markdown{font-family:var(--font-sans);font-size:14px;line-height:1.7;color:var(--text);word-wrap:break-word}.markdown h1,.markdown h2,.markdown h3,.markdown h4,.markdown h5,.markdown h6{color:var(--text);font-weight:600;margin-top:1.2em;margin-bottom:.4em;line-height:1.3}.markdown h1{font-size:1.4em}.markdown h2{font-size:1.2em}.markdown h3{font-size:1.1em}.markdown h4{font-size:1em}.markdown h1:first-child,.markdown h2:first-child,.markdown h3:first-child{margin-top:0}.markdown p{margin-bottom:.6em}.markdown p:last-child{margin-bottom:0}.markdown ul,.markdown ol{padding-left:1.5em;margin-bottom:.6em}.markdown li{margin-bottom:.2em}.markdown li>p{margin-bottom:.2em}.markdown code{font-family:var(--font-mono);font-size:.9em;padding:.15em .4em;background:var(--bg-hover);border-radius:4px;color:var(--brand-1)}.markdown pre{margin:.6em 0;padding:12px 16px;background:var(--bg);border:1px solid var(--border);border-radius:6px;overflow-x:auto;font-family:var(--font-mono);font-size:13px;line-height:1.5}.markdown pre code{padding:0;background:none;border-radius:0;color:var(--text-muted);font-size:inherit}.markdown blockquote{margin:.6em 0;padding:4px 12px;border-left:3px solid var(--brand-2);color:var(--text-muted)}.markdown blockquote p{margin-bottom:.2em}.markdown table{width:100%;border-collapse:collapse;margin:.6em 0;font-size:13px}.markdown th,.markdown td{padding:6px 12px;border:1px solid var(--border);text-align:left}.markdown th{background:var(--bg-surface);font-weight:600;color:var(--text)}.markdown td{color:var(--text-muted)}.markdown hr{border:none;border-top:1px solid var(--border);margin:1em 0}.markdown a{color:var(--brand-1);text-decoration:none}.markdown a:hover{text-decoration:underline}.markdown strong{color:var(--text);font-weight:600}.markdown img{max-width:100%;border-radius:4px}.markdown-inline{font-family:var(--font-mono);font-size:13px;line-height:1.6;color:var(--text-muted)}.markdown-inline h1,.markdown-inline h2,.markdown-inline h3,.markdown-inline h4,.markdown-inline h5,.markdown-inline h6{font-size:inherit;font-weight:600;margin:0;line-height:inherit;color:inherit}.markdown-inline p{margin-bottom:.3em}.markdown-inline p:last-child{margin-bottom:0}.markdown-inline pre{font-size:12px;margin:.4em 0}.markdown-inline a{color:var(--brand-1);text-decoration:none}.markdown-inline a:hover{text-decoration:underline}.btn{padding:6px 16px;border-radius:6px;border:1px solid var(--border);background:var(--bg-surface);color:var(--text);font-size:13px;cursor:pointer;transition:background .15s}.btn:hover{background:var(--bg-hover)}.btn:disabled{opacity:.5;cursor:not-allowed}.btn-primary{background:var(--brand-3);border-color:var(--brand-3);color:#fff;font-weight:600}.btn-primary:hover{background:var(--brand-2);border-color:var(--brand-2)}.btn-danger{border-color:var(--red);color:var(--red)}.btn-danger:hover{background:#f851491a}.prompt-bar button{padding:6px 14px;min-height:36px;border-radius:8px;border:1px solid var(--border);background:var(--bg-surface);color:var(--text);font-size:13px;cursor:pointer;transition:background .15s;flex-shrink:0}.prompt-bar button:hover{background:var(--bg-hover)}.prompt-bar button.primary{background:var(--brand-2);border-color:var(--brand-2);color:#fff;font-weight:600}.prompt-bar button.primary:hover{background:var(--brand-1);border-color:var(--brand-1)}.prompt-bar button.danger{border-color:var(--red);color:var(--red)}.prompt-bar button:disabled{opacity:.5;cursor:not-allowed}.tab-bar{display:flex;align-items:stretch;gap:0;border-bottom:1px solid var(--border);padding:0 16px;height:var(--topbar-height);flex-shrink:0}.tab-btn{display:flex;align-items:center;padding:0 16px;border:none;background:none;color:var(--text-subtle);font-size:13px;font-family:var(--font-mono);cursor:pointer;border-bottom:2px solid transparent;transition:color .15s,border-color .15s;margin-bottom:-1px}.tab-btn:hover{color:var(--text-muted)}.tab-bar-toggle{display:flex;align-items:center;justify-content:center;margin-left:auto;padding:6px 8px;border:none;background:none;color:var(--text-subtle);cursor:pointer;border-radius:4px}.tab-bar-toggle:hover{color:var(--text);background:var(--bg-hover)}.tab-btn.active{color:var(--brand-1);border-bottom-color:var(--brand-1)}.status-badge{display:inline-block;font-size:11px;padding:1px 8px;border-radius:10px;font-family:var(--font-mono);line-height:1.6}.status-badge-running{background:var(--cyan);color:var(--bg)}.status-badge-complete{background:var(--green);color:var(--bg)}.status-badge-error{background:var(--red);color:var(--bg)}.status-badge-cancelled{background:var(--text-subtle);color:var(--bg)}.settings-panel{margin:4px 0;padding:8px 0 8px 16px;border-left:2px solid var(--brand-2)}.settings-header{display:flex;align-items:center;gap:8px;margin-bottom:6px}.settings-title{font-family:var(--font-mono);font-size:13px;font-weight:600;color:var(--brand-1)}.settings-status{font-family:var(--font-mono);font-size:11px;padding:1px 6px;border-radius:8px}.settings-status.active{color:var(--green);border:1px solid var(--green)}.settings-status.missing{color:var(--yellow);border:1px solid var(--yellow)}.settings-field label{display:block;font-family:var(--font-mono);font-size:12px;color:var(--text-muted);margin-bottom:4px}.settings-input-row{display:flex;gap:6px}.settings-input-row input{flex:1;padding:8px 12px;background:var(--bg);border:1px solid var(--border);border-radius:8px;color:var(--text);font-family:var(--font-mono);font-size:13px;transition:border-color .15s,box-shadow .15s,background .15s}.settings-input-row input::placeholder{color:var(--text-subtle)}.settings-input-row input:hover{border-color:var(--text-subtle)}.settings-input-row input:focus{outline:none;border-color:var(--brand-2);box-shadow:0 0 0 3px #998fe726}.settings-input-row input:disabled{opacity:.5;cursor:not-allowed}.settings-input-row button{padding:8px 14px;border-radius:8px;border:1px solid var(--border);background:var(--bg-surface);color:var(--text-muted);font-family:var(--font-mono);font-size:13px;cursor:pointer;transition:background .15s,border-color .15s,color .15s}.settings-input-row button:hover{background:var(--bg-hover);border-color:var(--text-subtle)}.settings-input-row button.primary{background:transparent;border-color:var(--brand-3);color:var(--brand-1);font-weight:600}.settings-input-row button.primary:hover{background:var(--brand-2);border-color:var(--brand-2);color:#fff}.settings-input-row button:disabled{opacity:.5;cursor:not-allowed}.settings-divider{border-top:1px solid var(--border);margin:16px 0 12px}.settings-section-label{font-family:var(--font-mono);font-size:11px;color:var(--text-subtle);text-transform:uppercase;letter-spacing:.05em;margin-bottom:8px}.settings-error{font-family:var(--font-mono);font-size:12px;color:var(--red);margin-top:4px}.skeleton{background:linear-gradient(90deg,var(--bg-surface) 25%,var(--bg-hover) 50%,var(--bg-surface) 75%);background-size:200% 100%;animation:skeleton-shimmer 1.5s ease-in-out infinite;border-radius:4px}@keyframes skeleton-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.skeleton-line{height:14px;margin-bottom:8px}.skeleton-block{height:60px;margin-bottom:8px}.session-avatar{width:32px;height:32px;margin:4px;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600;font-family:var(--font-mono);letter-spacing:.5px;border-radius:50%;background:var(--bg-hover);color:var(--text);box-shadow:0 0 0 2px transparent,0 0 0 4px transparent}.session-avatar-running{box-shadow:0 0 0 2px var(--bg-surface),0 0 0 4px var(--cyan)}.session-avatar-complete{box-shadow:0 0 0 2px var(--bg-surface),0 0 0 4px var(--green)}.session-avatar-error{box-shadow:0 0 0 2px var(--bg-surface),0 0 0 4px var(--red)}.session-avatar-cancelled{box-shadow:0 0 0 2px var(--bg-surface),0 0 0 4px var(--text-subtle)}.session-item-pending{opacity:.5;pointer-events:none}.session-avatar-pending{background:var(--border);color:transparent;animation:pulse-fade 1.5s ease-in-out infinite}@keyframes pulse-fade{0%,to{opacity:.4}50%{opacity:.8}}.new-project-avatar{background:transparent;outline:1.5px dashed var(--text-subtle);outline-offset:-1.5px;color:var(--text-subtle);font-size:16px;font-weight:400}.session-item{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:6px;cursor:pointer;transition:background .1s,gap .2s ease;margin-bottom:1px;height:48px;box-sizing:border-box;overflow:hidden}.session-item:hover,.session-item.active{background:var(--bg-hover)}.session-item-details{flex:1;min-width:0;overflow:hidden;opacity:1;transition:opacity .15s ease,width .2s ease}.session-item-name{font-size:13px;font-weight:500;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.session-item-meta{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--text-subtle)}.session-item-delete{opacity:1;padding:4px 6px;border:none;background:none;color:var(--text-subtle);font-size:18px;cursor:pointer;border-radius:4px;line-height:1;flex-shrink:0;overflow:hidden;transition:color .1s,background .1s}.session-item-delete:hover{color:var(--text-muted);background:var(--bg-hover)}.modal-overlay{position:fixed;inset:0;background:#0009;display:flex;align-items:center;justify-content:center;z-index:100}.modal-card{background:var(--bg-surface);border:1px solid var(--border);border-radius:12px;padding:24px;max-width:400px;width:90%}.modal-title{font-size:16px;font-weight:600;color:var(--text);margin-bottom:8px}.modal-body{font-size:14px;color:var(--text-muted);line-height:1.6;margin-bottom:20px}.modal-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:16px}.modal-btn{padding:8px 18px;border-radius:8px;border:1px solid var(--border);background:var(--bg-hover);color:var(--text);font-size:13px;font-family:var(--font-sans);cursor:pointer;transition:background .15s,border-color .15s}.modal-btn:hover{background:var(--border);border-color:var(--text-subtle)}.modal-btn-danger{background:var(--red);border-color:var(--red);color:#fff;font-weight:600}.modal-btn-danger:hover{background:#d63a33;border-color:#d63a33}.toast-container{font-family:var(--font-mono);font-size:13px}.git-status-badge{display:inline-flex;align-items:center;gap:4px;font-family:var(--font-mono);font-size:11px;padding:2px 8px;border-radius:10px;border:1px solid var(--border);color:var(--text-subtle);cursor:default}.git-status-badge:before{content:"";width:6px;height:6px;border-radius:50%;background:var(--green);flex-shrink:0}.repo-picker-filter{margin-top:12px}.repo-picker-filter input{width:100%;box-sizing:border-box;padding:8px 12px;background:var(--bg);border:1px solid var(--border);border-radius:8px;color:var(--text);font-family:var(--font-mono);font-size:13px;transition:border-color .15s,box-shadow .15s}.repo-picker-filter input:hover{border-color:var(--text-subtle)}.repo-picker-filter input:focus{outline:none;border-color:var(--brand-2);box-shadow:0 0 0 3px #998fe726}.repo-picker-filter input::placeholder{color:var(--text-subtle)}.repo-picker-list{max-height:300px;overflow-y:auto;margin-top:12px;border:1px solid var(--border);border-radius:6px}.repo-picker-item{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;font-size:13px;font-family:var(--font-mono);cursor:pointer;border-bottom:1px solid var(--border);transition:background .1s}.repo-picker-item:last-child{border-bottom:none}.repo-picker-item:hover{background:var(--bg-hover);color:var(--text)}.repo-picker-item-name{color:var(--text-muted)}.repo-picker-item-date{font-size:11px;color:var(--text-subtle)}.repo-picker-new-branch{display:flex;gap:8px;padding:8px 12px;align-items:center}.repo-picker-new-branch input{flex:1;padding:8px 12px;background:var(--bg);border:1px solid var(--border);border-radius:8px;color:var(--text);font-family:var(--font-mono);font-size:13px;transition:border-color .15s,box-shadow .15s}.repo-picker-new-branch input:hover{border-color:var(--text-subtle)}.repo-picker-new-branch input:focus{outline:none;border-color:var(--brand-2);box-shadow:0 0 0 3px #998fe726}.repo-picker-new-branch input::placeholder{color:var(--text-subtle)}.hero-resume-btn{margin-top:12px;padding:8px 20px;border-radius:6px;border:1px solid var(--border);background:transparent;color:var(--text-muted);font-size:13px;cursor:pointer;transition:background .15s,color .15s}.hero-resume-btn:hover{background:var(--bg-hover);color:var(--text)}.hero-resume-btn:disabled{opacity:.5;cursor:not-allowed}.modal-btn-primary{background:var(--brand-3);border-color:var(--brand-3);color:#fff}.modal-btn-primary:hover{background:var(--brand-2)}.modal-btn-primary:disabled{opacity:.5;cursor:not-allowed}.font-size-options{display:flex;gap:6px}.font-size-option{flex:1;padding:10px 12px;border-radius:8px;border:1px solid var(--border);background:var(--bg);color:var(--text-muted);font-family:var(--font-sans);font-size:13px;cursor:pointer;transition:background .15s,border-color .15s,color .15s}.font-size-option:hover{background:var(--bg-hover);border-color:var(--text-subtle);color:var(--text)}.font-size-option.active{border-color:var(--brand-3);color:var(--brand-1);background:#7e78db1a}.link-session-list{max-height:300px;overflow-y:auto;border:1px solid var(--border);border-radius:6px;margin-top:12px}.link-session-item{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;font-size:13px;font-family:var(--font-mono);cursor:pointer;border-bottom:1px solid var(--border);transition:background .1s;border:none;background:transparent;width:100%;text-align:left;color:var(--text-muted)}.link-session-item:last-child{border-bottom:none}.link-session-item:hover{background:var(--bg-hover);color:var(--text)}@media(max-width:768px){.app-shell{grid-template-columns:1fr}.sidebar{position:fixed;top:0;left:0;bottom:0;width:280px;z-index:200;transform:translate(-100%);transition:transform .25s ease}.sidebar.mobile-open{transform:translate(0)}.sidebar-backdrop{display:block;position:fixed;inset:0;background:#00000080;z-index:199}.sidebar-collapse{display:none}.app-shell.sidebar-collapsed .sidebar-brand,.app-shell.sidebar-collapsed .sidebar-section-label{display:block}.app-shell.sidebar-collapsed .session-item{gap:8px}.app-shell.sidebar-collapsed .session-item-details,.app-shell.sidebar-collapsed .session-item-delete,.app-shell.sidebar-collapsed .session-item:hover .session-item-delete{opacity:1;width:auto;overflow:visible;pointer-events:auto}.app-shell.sidebar-collapsed .sidebar-collapse-label{opacity:1;max-width:120px;display:inline}.mobile-hamburger{display:flex;align-items:center;justify-content:center;width:42px;height:42px;border:none;background:none;color:var(--text-muted);cursor:pointer;border-radius:6px;flex-shrink:0;-webkit-tap-highlight-color:transparent}.mobile-hamburger:hover{color:var(--text);background:var(--bg-hover)}.session-header{padding:0 8px;gap:6px}.session-header-name{font-size:14px;min-width:0;flex:1}.session-header .session-header-cost,.session-header .session-header-actions-group{display:none}.session-header-overflow{display:flex;align-items:center;justify-content:center;width:36px;height:36px;border:none;background:none;color:var(--text-muted);cursor:pointer;border-radius:6px;flex-shrink:0;-webkit-tap-highlight-color:transparent}.session-header-overflow:hover{color:var(--text);background:var(--bg-hover)}.session-header-overflow-menu{position:absolute;top:calc(var(--topbar-height) - 4px);right:8px;background:var(--bg-surface);border:1px solid var(--border);border-radius:8px;padding:6px;z-index:100;min-width:180px;box-shadow:0 8px 24px #0006}.session-header-overflow-menu-item{display:flex;align-items:center;gap:8px;width:100%;padding:10px 12px;border:none;background:none;color:var(--text-muted);font-size:14px;font-family:var(--font-mono);cursor:pointer;border-radius:6px;text-decoration:none;-webkit-tap-highlight-color:transparent}.session-header-overflow-menu-item:hover{background:var(--bg-hover);color:var(--text)}.mobile-preview-bar{display:flex;align-items:center;justify-content:center;padding:8px 12px;padding-top:calc(var(--topbar-height) + 8px);background:var(--bg-surface);border-bottom:1px solid var(--border);flex-shrink:0}.mobile-preview-link{display:inline-flex;align-items:center;gap:6px;padding:10px 20px;font-size:14px;font-family:var(--font-mono);color:var(--brand-1);background:transparent;border:1px solid var(--brand-3);border-radius:8px;text-decoration:none;-webkit-tap-highlight-color:transparent;transition:color .15s,background .15s,border-color .15s}.mobile-preview-link:hover{background:var(--brand-2);border-color:var(--brand-2);color:#fff}.console{padding:calc(var(--topbar-height) + 8px) 8px 8px;overflow-x:hidden}.mobile-preview-bar~.console{padding-top:8px}.session-content{overflow-x:hidden;touch-action:pan-y pinch-zoom}.session-loading{padding:calc(var(--topbar-height) + 8px) 8px 8px}.tool-inline-summary,.thinking-preview{max-width:200px}.tool-inline-command{max-width:200px;overflow:hidden;text-overflow:ellipsis}.tool-inline-body{padding:6px 0 6px 10px;margin-left:4px}.tool-inline-body pre{max-height:250px}.prompt-bar{padding:6px 8px;gap:6px;height:auto;min-height:var(--footer-height)}.prompt-bar textarea{padding:10px 12px;min-height:42px;font-size:16px}.prompt-bar button{padding:8px 14px;min-height:40px;font-size:14px}.mobile-home-topbar{display:flex;align-items:center;padding:6px 10px;height:52px;flex-shrink:0;border-bottom:1px solid rgba(58,58,68,.5);gap:8px;background:#1b1b1fcc;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);position:relative;z-index:10}.mobile-topbar-logo{height:26px}.hero{padding:0 16px;justify-content:flex-start;padding-top:8vh}.hero-logo{height:48px;margin-bottom:12px}.hero-subtitle{font-size:15px;margin-bottom:24px;white-space:nowrap}.hero-prompt{max-width:100%}.hero-prompt .prompt-bar{border-radius:12px}.hero-prompt .prompt-bar textarea{min-height:48px;font-size:16px;padding:12px}.hero-prompt .prompt-bar button{min-height:48px;padding:8px 18px;font-size:15px;border-radius:0 11px 11px 0}.hero-resume-btn{width:100%;padding:12px 20px;font-size:15px}.gate-prompt{padding:12px}.gate-prompt .question input,.gate-prompt .question textarea,.gate-prompt .question select{font-size:15px;padding:10px 12px}.gate-actions{flex-direction:column}.gate-actions .gate-btn{width:100%;padding:10px 16px;text-align:center}.gate-plan-actions{flex-wrap:wrap}.gate-plan-actions .gate-btn{flex:1;min-width:0;padding:10px 12px;text-align:center}.gate-btn kbd{display:none}.gate-continue{flex-wrap:wrap;gap:8px;padding:10px 12px}.gate-continue-text{width:100%;flex:none}.gate-continue .gate-btn{flex:1;text-align:center;padding:8px 12px}.gate-option-group{flex-direction:column}.gate-option{padding:12px}.modal-overlay{z-index:300}.modal-card{width:95%;max-width:none;max-height:90vh;overflow-y:auto;border-radius:14px}.modal-actions{flex-direction:column-reverse}.modal-actions .modal-btn{width:100%;text-align:center;padding:10px 16px}.settings-input-row{flex-direction:column;gap:8px}.settings-input-row input{font-size:15px;padding:10px 12px}.settings-input-row button{width:100%;padding:8px 12px;text-align:center}.repo-picker-item{padding:14px;min-height:48px}.repo-picker-new-branch{flex-direction:column}.repo-picker-new-branch input{font-size:14px;padding:10px 12px}.global-settings-btn{top:8px;right:8px;width:40px;height:40px}.global-settings-btn svg{width:20px;height:20px}.jump-to-bottom{padding:10px 20px;font-size:13px}.action-item-summary{max-width:150px}.action-item-detail{padding:8px 12px 8px 24px}.markdown pre{padding:10px 12px;font-size:12px}.markdown table{display:block;overflow-x:auto}}@media(min-width:769px){.mobile-hamburger,.mobile-home-topbar,.sidebar-backdrop,.session-header-overflow,.session-header-overflow-menu,.mobile-preview-bar,.mobile-topbar-logo{display:none}}
|