@saga-ai/cli 2.13.0 → 2.14.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/cli.cjs
CHANGED
|
@@ -25,8 +25,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
25
25
|
|
|
26
26
|
// src/cli.ts
|
|
27
27
|
var import_commander = require("commander");
|
|
28
|
-
var
|
|
29
|
-
var
|
|
28
|
+
var import_node_path9 = require("node:path");
|
|
29
|
+
var import_node_fs8 = require("node:fs");
|
|
30
30
|
|
|
31
31
|
// src/commands/init.ts
|
|
32
32
|
var import_node_path2 = require("node:path");
|
|
@@ -1400,8 +1400,8 @@ function validateTaskStatus(status) {
|
|
|
1400
1400
|
return "pending";
|
|
1401
1401
|
}
|
|
1402
1402
|
async function parseStory(storyPath, epicSlug) {
|
|
1403
|
-
const { join:
|
|
1404
|
-
const { stat:
|
|
1403
|
+
const { join: join14 } = await import("path");
|
|
1404
|
+
const { stat: stat4 } = await import("fs/promises");
|
|
1405
1405
|
let content;
|
|
1406
1406
|
try {
|
|
1407
1407
|
content = await (0, import_promises3.readFile)(storyPath, "utf-8");
|
|
@@ -1420,10 +1420,10 @@ async function parseStory(storyPath, epicSlug) {
|
|
|
1420
1420
|
const title = frontmatter.title || dirName;
|
|
1421
1421
|
const status = validateStatus(frontmatter.status);
|
|
1422
1422
|
const tasks = parseTasks(frontmatter.tasks);
|
|
1423
|
-
const journalPath =
|
|
1423
|
+
const journalPath = join14(storyDir, "journal.md");
|
|
1424
1424
|
let hasJournal = false;
|
|
1425
1425
|
try {
|
|
1426
|
-
await
|
|
1426
|
+
await stat4(journalPath);
|
|
1427
1427
|
hasJournal = true;
|
|
1428
1428
|
} catch {
|
|
1429
1429
|
}
|
|
@@ -1887,6 +1887,290 @@ async function createSagaWatcher(sagaRoot) {
|
|
|
1887
1887
|
|
|
1888
1888
|
// src/server/websocket.ts
|
|
1889
1889
|
var import_path5 = require("path");
|
|
1890
|
+
|
|
1891
|
+
// src/lib/log-stream-manager.ts
|
|
1892
|
+
var import_chokidar2 = __toESM(require("chokidar"), 1);
|
|
1893
|
+
var import_node_fs6 = require("node:fs");
|
|
1894
|
+
var import_promises4 = require("node:fs/promises");
|
|
1895
|
+
var import_node_path6 = require("node:path");
|
|
1896
|
+
var LogStreamManager = class {
|
|
1897
|
+
/**
|
|
1898
|
+
* Active file watchers indexed by session name
|
|
1899
|
+
*/
|
|
1900
|
+
watchers = /* @__PURE__ */ new Map();
|
|
1901
|
+
/**
|
|
1902
|
+
* Current file position (byte offset) per session for incremental reads
|
|
1903
|
+
*/
|
|
1904
|
+
filePositions = /* @__PURE__ */ new Map();
|
|
1905
|
+
/**
|
|
1906
|
+
* Client subscriptions per session
|
|
1907
|
+
*/
|
|
1908
|
+
subscriptions = /* @__PURE__ */ new Map();
|
|
1909
|
+
/**
|
|
1910
|
+
* Function to send messages to clients
|
|
1911
|
+
*/
|
|
1912
|
+
sendToClient;
|
|
1913
|
+
/**
|
|
1914
|
+
* Create a new LogStreamManager instance
|
|
1915
|
+
*
|
|
1916
|
+
* @param sendToClient - Function to send log data messages to clients
|
|
1917
|
+
*/
|
|
1918
|
+
constructor(sendToClient) {
|
|
1919
|
+
this.sendToClient = sendToClient;
|
|
1920
|
+
}
|
|
1921
|
+
/**
|
|
1922
|
+
* Get the number of subscriptions for a session
|
|
1923
|
+
*
|
|
1924
|
+
* @param sessionName - The session to check
|
|
1925
|
+
* @returns Number of subscribed clients
|
|
1926
|
+
*/
|
|
1927
|
+
getSubscriptionCount(sessionName) {
|
|
1928
|
+
const subs = this.subscriptions.get(sessionName);
|
|
1929
|
+
return subs ? subs.size : 0;
|
|
1930
|
+
}
|
|
1931
|
+
/**
|
|
1932
|
+
* Check if a watcher exists for a session
|
|
1933
|
+
*
|
|
1934
|
+
* @param sessionName - The session to check
|
|
1935
|
+
* @returns True if a watcher exists
|
|
1936
|
+
*/
|
|
1937
|
+
hasWatcher(sessionName) {
|
|
1938
|
+
return this.watchers.has(sessionName);
|
|
1939
|
+
}
|
|
1940
|
+
/**
|
|
1941
|
+
* Get the current file position for a session
|
|
1942
|
+
*
|
|
1943
|
+
* @param sessionName - The session to check
|
|
1944
|
+
* @returns The current byte offset, or 0 if not tracked
|
|
1945
|
+
*/
|
|
1946
|
+
getFilePosition(sessionName) {
|
|
1947
|
+
return this.filePositions.get(sessionName) ?? 0;
|
|
1948
|
+
}
|
|
1949
|
+
/**
|
|
1950
|
+
* Subscribe a client to a session's log stream
|
|
1951
|
+
*
|
|
1952
|
+
* Reads the full file content and sends it as the initial message.
|
|
1953
|
+
* Adds the client to the subscription set for incremental updates.
|
|
1954
|
+
* Creates a file watcher if this is the first subscriber.
|
|
1955
|
+
*
|
|
1956
|
+
* @param sessionName - The session to subscribe to
|
|
1957
|
+
* @param ws - The WebSocket client to subscribe
|
|
1958
|
+
*/
|
|
1959
|
+
async subscribe(sessionName, ws) {
|
|
1960
|
+
const outputFile = (0, import_node_path6.join)(OUTPUT_DIR, `${sessionName}.out`);
|
|
1961
|
+
if (!(0, import_node_fs6.existsSync)(outputFile)) {
|
|
1962
|
+
this.sendToClient(ws, {
|
|
1963
|
+
type: "logs:error",
|
|
1964
|
+
sessionName,
|
|
1965
|
+
error: `Output file not found: ${outputFile}`
|
|
1966
|
+
});
|
|
1967
|
+
return;
|
|
1968
|
+
}
|
|
1969
|
+
const content = await (0, import_promises4.readFile)(outputFile, "utf-8");
|
|
1970
|
+
this.sendToClient(ws, {
|
|
1971
|
+
type: "logs:data",
|
|
1972
|
+
sessionName,
|
|
1973
|
+
data: content,
|
|
1974
|
+
isInitial: true,
|
|
1975
|
+
isComplete: false
|
|
1976
|
+
});
|
|
1977
|
+
this.filePositions.set(sessionName, content.length);
|
|
1978
|
+
let subs = this.subscriptions.get(sessionName);
|
|
1979
|
+
if (!subs) {
|
|
1980
|
+
subs = /* @__PURE__ */ new Set();
|
|
1981
|
+
this.subscriptions.set(sessionName, subs);
|
|
1982
|
+
}
|
|
1983
|
+
subs.add(ws);
|
|
1984
|
+
if (!this.watchers.has(sessionName)) {
|
|
1985
|
+
this.createWatcher(sessionName, outputFile);
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1988
|
+
/**
|
|
1989
|
+
* Create a chokidar file watcher for a session's output file
|
|
1990
|
+
*
|
|
1991
|
+
* The watcher detects changes and triggers incremental content delivery
|
|
1992
|
+
* to all subscribed clients.
|
|
1993
|
+
*
|
|
1994
|
+
* @param sessionName - The session name
|
|
1995
|
+
* @param outputFile - Path to the session output file
|
|
1996
|
+
*/
|
|
1997
|
+
createWatcher(sessionName, outputFile) {
|
|
1998
|
+
const watcher = import_chokidar2.default.watch(outputFile, {
|
|
1999
|
+
persistent: true,
|
|
2000
|
+
awaitWriteFinish: false
|
|
2001
|
+
});
|
|
2002
|
+
watcher.on("change", async () => {
|
|
2003
|
+
await this.sendIncrementalContent(sessionName, outputFile);
|
|
2004
|
+
});
|
|
2005
|
+
this.watchers.set(sessionName, watcher);
|
|
2006
|
+
}
|
|
2007
|
+
/**
|
|
2008
|
+
* Clean up a watcher and associated state for a session
|
|
2009
|
+
*
|
|
2010
|
+
* Closes the file watcher and removes all tracking state for the session.
|
|
2011
|
+
* Should be called when the last subscriber unsubscribes or disconnects.
|
|
2012
|
+
*
|
|
2013
|
+
* @param sessionName - The session to clean up
|
|
2014
|
+
*/
|
|
2015
|
+
cleanupWatcher(sessionName) {
|
|
2016
|
+
const watcher = this.watchers.get(sessionName);
|
|
2017
|
+
if (watcher) {
|
|
2018
|
+
watcher.close();
|
|
2019
|
+
this.watchers.delete(sessionName);
|
|
2020
|
+
}
|
|
2021
|
+
this.filePositions.delete(sessionName);
|
|
2022
|
+
this.subscriptions.delete(sessionName);
|
|
2023
|
+
}
|
|
2024
|
+
/**
|
|
2025
|
+
* Send incremental content to all subscribed clients for a session
|
|
2026
|
+
*
|
|
2027
|
+
* Reads from the last known position to the end of the file and sends
|
|
2028
|
+
* the new content to all subscribed clients.
|
|
2029
|
+
*
|
|
2030
|
+
* @param sessionName - The session name
|
|
2031
|
+
* @param outputFile - Path to the session output file
|
|
2032
|
+
*/
|
|
2033
|
+
async sendIncrementalContent(sessionName, outputFile) {
|
|
2034
|
+
const lastPosition = this.filePositions.get(sessionName) ?? 0;
|
|
2035
|
+
const fileStat = await (0, import_promises4.stat)(outputFile);
|
|
2036
|
+
const currentSize = fileStat.size;
|
|
2037
|
+
if (currentSize <= lastPosition) {
|
|
2038
|
+
return;
|
|
2039
|
+
}
|
|
2040
|
+
const newContent = await this.readFromPosition(outputFile, lastPosition, currentSize);
|
|
2041
|
+
this.filePositions.set(sessionName, currentSize);
|
|
2042
|
+
const subs = this.subscriptions.get(sessionName);
|
|
2043
|
+
if (subs) {
|
|
2044
|
+
const message = {
|
|
2045
|
+
type: "logs:data",
|
|
2046
|
+
sessionName,
|
|
2047
|
+
data: newContent,
|
|
2048
|
+
isInitial: false,
|
|
2049
|
+
isComplete: false
|
|
2050
|
+
};
|
|
2051
|
+
for (const ws of subs) {
|
|
2052
|
+
this.sendToClient(ws, message);
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2055
|
+
}
|
|
2056
|
+
/**
|
|
2057
|
+
* Read file content from a specific position
|
|
2058
|
+
*
|
|
2059
|
+
* @param filePath - Path to the file
|
|
2060
|
+
* @param start - Starting byte position
|
|
2061
|
+
* @param end - Ending byte position
|
|
2062
|
+
* @returns The content read from the file
|
|
2063
|
+
*/
|
|
2064
|
+
readFromPosition(filePath, start, end) {
|
|
2065
|
+
return new Promise((resolve2, reject) => {
|
|
2066
|
+
let content = "";
|
|
2067
|
+
const stream = (0, import_node_fs6.createReadStream)(filePath, {
|
|
2068
|
+
start,
|
|
2069
|
+
end: end - 1,
|
|
2070
|
+
// createReadStream end is inclusive
|
|
2071
|
+
encoding: "utf-8"
|
|
2072
|
+
});
|
|
2073
|
+
stream.on("data", (chunk) => {
|
|
2074
|
+
content += chunk;
|
|
2075
|
+
});
|
|
2076
|
+
stream.on("end", () => {
|
|
2077
|
+
resolve2(content);
|
|
2078
|
+
});
|
|
2079
|
+
stream.on("error", reject);
|
|
2080
|
+
});
|
|
2081
|
+
}
|
|
2082
|
+
/**
|
|
2083
|
+
* Unsubscribe a client from a session's log stream
|
|
2084
|
+
*
|
|
2085
|
+
* Removes the client from the subscription set. If this was the last
|
|
2086
|
+
* subscriber, cleans up the watcher and associated state.
|
|
2087
|
+
*
|
|
2088
|
+
* @param sessionName - The session to unsubscribe from
|
|
2089
|
+
* @param ws - The WebSocket client to unsubscribe
|
|
2090
|
+
*/
|
|
2091
|
+
unsubscribe(sessionName, ws) {
|
|
2092
|
+
const subs = this.subscriptions.get(sessionName);
|
|
2093
|
+
if (subs) {
|
|
2094
|
+
subs.delete(ws);
|
|
2095
|
+
if (subs.size === 0) {
|
|
2096
|
+
this.cleanupWatcher(sessionName);
|
|
2097
|
+
}
|
|
2098
|
+
}
|
|
2099
|
+
}
|
|
2100
|
+
/**
|
|
2101
|
+
* Handle client disconnect by removing from all subscriptions
|
|
2102
|
+
*
|
|
2103
|
+
* Should be called when a WebSocket connection closes to clean up
|
|
2104
|
+
* any subscriptions the client may have had. Also triggers watcher
|
|
2105
|
+
* cleanup for any sessions that no longer have subscribers.
|
|
2106
|
+
*
|
|
2107
|
+
* @param ws - The WebSocket client that disconnected
|
|
2108
|
+
*/
|
|
2109
|
+
handleClientDisconnect(ws) {
|
|
2110
|
+
for (const [sessionName, subs] of this.subscriptions) {
|
|
2111
|
+
subs.delete(ws);
|
|
2112
|
+
if (subs.size === 0) {
|
|
2113
|
+
this.cleanupWatcher(sessionName);
|
|
2114
|
+
}
|
|
2115
|
+
}
|
|
2116
|
+
}
|
|
2117
|
+
/**
|
|
2118
|
+
* Notify that a session has completed
|
|
2119
|
+
*
|
|
2120
|
+
* Reads any remaining content from the file and sends it with isComplete=true
|
|
2121
|
+
* to all subscribed clients, then cleans up the watcher regardless of
|
|
2122
|
+
* subscription count. Called by session polling when it detects completion.
|
|
2123
|
+
*
|
|
2124
|
+
* @param sessionName - The session that has completed
|
|
2125
|
+
*/
|
|
2126
|
+
async notifySessionCompleted(sessionName) {
|
|
2127
|
+
const subs = this.subscriptions.get(sessionName);
|
|
2128
|
+
if (!subs || subs.size === 0) {
|
|
2129
|
+
return;
|
|
2130
|
+
}
|
|
2131
|
+
const outputFile = (0, import_node_path6.join)(OUTPUT_DIR, `${sessionName}.out`);
|
|
2132
|
+
let finalContent = "";
|
|
2133
|
+
try {
|
|
2134
|
+
if ((0, import_node_fs6.existsSync)(outputFile)) {
|
|
2135
|
+
const lastPosition = this.filePositions.get(sessionName) ?? 0;
|
|
2136
|
+
const fileStat = await (0, import_promises4.stat)(outputFile);
|
|
2137
|
+
const currentSize = fileStat.size;
|
|
2138
|
+
if (currentSize > lastPosition) {
|
|
2139
|
+
finalContent = await this.readFromPosition(outputFile, lastPosition, currentSize);
|
|
2140
|
+
}
|
|
2141
|
+
}
|
|
2142
|
+
} catch {
|
|
2143
|
+
}
|
|
2144
|
+
const message = {
|
|
2145
|
+
type: "logs:data",
|
|
2146
|
+
sessionName,
|
|
2147
|
+
data: finalContent,
|
|
2148
|
+
isInitial: false,
|
|
2149
|
+
isComplete: true
|
|
2150
|
+
};
|
|
2151
|
+
for (const ws of subs) {
|
|
2152
|
+
this.sendToClient(ws, message);
|
|
2153
|
+
}
|
|
2154
|
+
this.cleanupWatcher(sessionName);
|
|
2155
|
+
}
|
|
2156
|
+
/**
|
|
2157
|
+
* Clean up all watchers and subscriptions
|
|
2158
|
+
*
|
|
2159
|
+
* Call this when shutting down the server.
|
|
2160
|
+
*/
|
|
2161
|
+
async dispose() {
|
|
2162
|
+
const closePromises = [];
|
|
2163
|
+
for (const [, watcher] of this.watchers) {
|
|
2164
|
+
closePromises.push(watcher.close());
|
|
2165
|
+
}
|
|
2166
|
+
await Promise.all(closePromises);
|
|
2167
|
+
this.watchers.clear();
|
|
2168
|
+
this.filePositions.clear();
|
|
2169
|
+
this.subscriptions.clear();
|
|
2170
|
+
}
|
|
2171
|
+
};
|
|
2172
|
+
|
|
2173
|
+
// src/server/websocket.ts
|
|
1890
2174
|
function makeStoryKey(epicSlug, storySlug) {
|
|
1891
2175
|
return `${epicSlug}:${storySlug}`;
|
|
1892
2176
|
}
|
|
@@ -1923,13 +2207,29 @@ async function createWebSocketServer(httpServer, sagaRoot) {
|
|
|
1923
2207
|
ws.send(JSON.stringify(message));
|
|
1924
2208
|
}
|
|
1925
2209
|
}
|
|
2210
|
+
function sendLogMessage(ws, message) {
|
|
2211
|
+
if (ws.readyState === import_ws.WebSocket.OPEN) {
|
|
2212
|
+
ws.send(JSON.stringify({ event: message.type, data: message }));
|
|
2213
|
+
}
|
|
2214
|
+
}
|
|
2215
|
+
const logStreamManager = new LogStreamManager(sendLogMessage);
|
|
1926
2216
|
function broadcast(message) {
|
|
1927
2217
|
for (const [ws] of clients) {
|
|
1928
2218
|
sendToClient(ws, message);
|
|
1929
2219
|
}
|
|
1930
2220
|
}
|
|
2221
|
+
let previousSessionStates = /* @__PURE__ */ new Map();
|
|
1931
2222
|
startSessionPolling((msg) => {
|
|
1932
2223
|
broadcast({ event: msg.type, data: msg.sessions });
|
|
2224
|
+
const currentStates = /* @__PURE__ */ new Map();
|
|
2225
|
+
for (const session of msg.sessions) {
|
|
2226
|
+
currentStates.set(session.name, session.status);
|
|
2227
|
+
const previousStatus = previousSessionStates.get(session.name);
|
|
2228
|
+
if (previousStatus === "running" && session.status === "completed") {
|
|
2229
|
+
logStreamManager.notifySessionCompleted(session.name);
|
|
2230
|
+
}
|
|
2231
|
+
}
|
|
2232
|
+
previousSessionStates = currentStates;
|
|
1933
2233
|
});
|
|
1934
2234
|
function broadcastToSubscribers(storyKey, message) {
|
|
1935
2235
|
for (const [ws, state] of clients) {
|
|
@@ -1971,6 +2271,20 @@ async function createWebSocketServer(httpServer, sagaRoot) {
|
|
|
1971
2271
|
}
|
|
1972
2272
|
break;
|
|
1973
2273
|
}
|
|
2274
|
+
case "subscribe:logs": {
|
|
2275
|
+
const { sessionName } = message.data || {};
|
|
2276
|
+
if (sessionName) {
|
|
2277
|
+
logStreamManager.subscribe(sessionName, ws);
|
|
2278
|
+
}
|
|
2279
|
+
break;
|
|
2280
|
+
}
|
|
2281
|
+
case "unsubscribe:logs": {
|
|
2282
|
+
const { sessionName } = message.data || {};
|
|
2283
|
+
if (sessionName) {
|
|
2284
|
+
logStreamManager.unsubscribe(sessionName, ws);
|
|
2285
|
+
}
|
|
2286
|
+
break;
|
|
2287
|
+
}
|
|
1974
2288
|
default:
|
|
1975
2289
|
break;
|
|
1976
2290
|
}
|
|
@@ -1979,10 +2293,12 @@ async function createWebSocketServer(httpServer, sagaRoot) {
|
|
|
1979
2293
|
});
|
|
1980
2294
|
ws.on("close", () => {
|
|
1981
2295
|
clients.delete(ws);
|
|
2296
|
+
logStreamManager.handleClientDisconnect(ws);
|
|
1982
2297
|
});
|
|
1983
2298
|
ws.on("error", (err) => {
|
|
1984
2299
|
console.error("WebSocket error:", err);
|
|
1985
2300
|
clients.delete(ws);
|
|
2301
|
+
logStreamManager.handleClientDisconnect(ws);
|
|
1986
2302
|
});
|
|
1987
2303
|
});
|
|
1988
2304
|
if (watcher) {
|
|
@@ -2054,6 +2370,7 @@ async function createWebSocketServer(httpServer, sagaRoot) {
|
|
|
2054
2370
|
async close() {
|
|
2055
2371
|
clearInterval(heartbeatInterval);
|
|
2056
2372
|
stopSessionPolling();
|
|
2373
|
+
await logStreamManager.dispose();
|
|
2057
2374
|
for (const [ws] of clients) {
|
|
2058
2375
|
ws.close();
|
|
2059
2376
|
}
|
|
@@ -2159,7 +2476,7 @@ async function dashboardCommand(options) {
|
|
|
2159
2476
|
}
|
|
2160
2477
|
|
|
2161
2478
|
// src/commands/scope-validator.ts
|
|
2162
|
-
var
|
|
2479
|
+
var import_node_path7 = require("node:path");
|
|
2163
2480
|
function getFilePathFromInput(hookInput) {
|
|
2164
2481
|
try {
|
|
2165
2482
|
const data = JSON.parse(hookInput);
|
|
@@ -2179,10 +2496,10 @@ function isArchiveAccess(path) {
|
|
|
2179
2496
|
return path.includes(".saga/archive");
|
|
2180
2497
|
}
|
|
2181
2498
|
function isWithinWorktree(filePath, worktreePath) {
|
|
2182
|
-
const absoluteFilePath = (0,
|
|
2183
|
-
const absoluteWorktree = (0,
|
|
2184
|
-
const relativePath = (0,
|
|
2185
|
-
if (relativePath.startsWith("..") || (0,
|
|
2499
|
+
const absoluteFilePath = (0, import_node_path7.resolve)(filePath);
|
|
2500
|
+
const absoluteWorktree = (0, import_node_path7.resolve)(worktreePath);
|
|
2501
|
+
const relativePath = (0, import_node_path7.relative)(absoluteWorktree, absoluteFilePath);
|
|
2502
|
+
if (relativePath.startsWith("..") || (0, import_node_path7.resolve)(relativePath) === relativePath) {
|
|
2186
2503
|
return false;
|
|
2187
2504
|
}
|
|
2188
2505
|
return true;
|
|
@@ -2297,8 +2614,8 @@ async function findCommand(query, options) {
|
|
|
2297
2614
|
}
|
|
2298
2615
|
|
|
2299
2616
|
// src/commands/worktree.ts
|
|
2300
|
-
var
|
|
2301
|
-
var
|
|
2617
|
+
var import_node_path8 = require("node:path");
|
|
2618
|
+
var import_node_fs7 = require("node:fs");
|
|
2302
2619
|
var import_node_child_process3 = require("node:child_process");
|
|
2303
2620
|
function runGitCommand(args, cwd) {
|
|
2304
2621
|
try {
|
|
@@ -2329,7 +2646,7 @@ function getMainBranch(cwd) {
|
|
|
2329
2646
|
}
|
|
2330
2647
|
function createWorktree(projectPath, epicSlug, storySlug) {
|
|
2331
2648
|
const branchName = `story-${storySlug}-epic-${epicSlug}`;
|
|
2332
|
-
const worktreePath = (0,
|
|
2649
|
+
const worktreePath = (0, import_node_path8.join)(
|
|
2333
2650
|
projectPath,
|
|
2334
2651
|
".saga",
|
|
2335
2652
|
"worktrees",
|
|
@@ -2342,7 +2659,7 @@ function createWorktree(projectPath, epicSlug, storySlug) {
|
|
|
2342
2659
|
error: `Branch already exists: ${branchName}`
|
|
2343
2660
|
};
|
|
2344
2661
|
}
|
|
2345
|
-
if ((0,
|
|
2662
|
+
if ((0, import_node_fs7.existsSync)(worktreePath)) {
|
|
2346
2663
|
return {
|
|
2347
2664
|
success: false,
|
|
2348
2665
|
error: `Worktree directory already exists: ${worktreePath}`
|
|
@@ -2360,8 +2677,8 @@ function createWorktree(projectPath, epicSlug, storySlug) {
|
|
|
2360
2677
|
error: `Failed to create branch: ${createBranchResult.output}`
|
|
2361
2678
|
};
|
|
2362
2679
|
}
|
|
2363
|
-
const worktreeParent = (0,
|
|
2364
|
-
(0,
|
|
2680
|
+
const worktreeParent = (0, import_node_path8.join)(projectPath, ".saga", "worktrees", epicSlug);
|
|
2681
|
+
(0, import_node_fs7.mkdirSync)(worktreeParent, { recursive: true });
|
|
2365
2682
|
const createWorktreeResult = runGitCommand(
|
|
2366
2683
|
["worktree", "add", worktreePath, branchName],
|
|
2367
2684
|
projectPath
|
|
@@ -2417,8 +2734,8 @@ async function sessionsKillCommand(sessionName) {
|
|
|
2417
2734
|
}
|
|
2418
2735
|
|
|
2419
2736
|
// src/cli.ts
|
|
2420
|
-
var packageJsonPath = (0,
|
|
2421
|
-
var packageJson = JSON.parse((0,
|
|
2737
|
+
var packageJsonPath = (0, import_node_path9.join)(__dirname, "..", "package.json");
|
|
2738
|
+
var packageJson = JSON.parse((0, import_node_fs8.readFileSync)(packageJsonPath, "utf-8"));
|
|
2422
2739
|
var program = new import_commander.Command();
|
|
2423
2740
|
program.name("saga").description("CLI for SAGA - Structured Autonomous Goal Achievement").version(packageJson.version).addHelpCommand("help [command]", "Display help for a command");
|
|
2424
2741
|
program.option("-p, --path <dir>", "Path to SAGA project directory (overrides auto-discovery)");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:root{--bg-dark: oklch(.1 .025 264);--bg: oklch(.15 .025 264);--bg-light: oklch(.2 .025 264);--text: oklch(.96 .05 264);--text-muted: oklch(.76 .05 264);--highlight: oklch(.5 .05 264);--border: oklch(.4 .05 264);--border-muted: oklch(.3 .05 264);--primary: oklch(.76 .1 264);--secondary: oklch(.76 .1 84);--danger: oklch(.7 .05 30);--warning: oklch(.7 .05 100);--success: oklch(.7 .05 160);--info: oklch(.7 .05 260);--background: var(--bg);--foreground: var(--text);--card: var(--bg-dark);--card-foreground: var(--text);--popover: var(--bg-dark);--popover-foreground: var(--text);--primary-foreground: var(--bg-dark);--secondary-foreground: var(--bg-dark);--muted: var(--bg-light);--muted-foreground: var(--text-muted);--accent: var(--bg-light);--accent-foreground: var(--text);--destructive: var(--danger);--destructive-foreground: var(--text);--input: var(--border-muted);--ring: var(--primary);--radius: .5rem}*{border-color:var(--border)}body{background-color:var(--bg);color:var(--text);font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,sans-serif;min-height:100vh}.\!container{width:100%!important}.container{width:100%}@media(min-width:640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media(min-width:768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media(min-width:1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media(min-width:1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media(min-width:1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.prose{color:var(--tw-prose-body);max-width:65ch}.prose :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-lead);font-size:1.25em;line-height:1.6;margin-top:1.2em;margin-bottom:1.2em}.prose :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-links);text-decoration:underline;font-weight:500}.prose :where(strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:600}.prose :where(a strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(blockquote strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(thead th strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal;margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose :where(ol[type=A]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=A s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=I]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type=I s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type="1"]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal}.prose :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:disc;margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{font-weight:400;color:var(--tw-prose-counters)}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.prose :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;margin-top:1.25em}.prose :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-top:3em;margin-bottom:3em}.prose :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:500;font-style:italic;color:var(--tw-prose-quotes);border-inline-start-width:.25rem;border-inline-start-color:var(--tw-prose-quote-borders);quotes:"“""”""‘""’";margin-top:1.6em;margin-bottom:1.6em;padding-inline-start:1em}.prose :where(blockquote p:first-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:open-quote}.prose :where(blockquote p:last-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:close-quote}.prose :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:800;font-size:2.25em;margin-top:0;margin-bottom:.8888889em;line-height:1.1111111}.prose :where(h1 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:900;color:inherit}.prose :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:700;font-size:1.5em;margin-top:2em;margin-bottom:1em;line-height:1.3333333}.prose :where(h2 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:800;color:inherit}.prose :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;font-size:1.25em;margin-top:1.6em;margin-bottom:.6em;line-height:1.6}.prose :where(h3 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:700;color:inherit}.prose :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;margin-top:1.5em;margin-bottom:.5em;line-height:1.5}.prose :where(h4 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:700;color:inherit}.prose :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){display:block;margin-top:2em;margin-bottom:2em}.prose :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:500;font-family:inherit;color:var(--tw-prose-kbd);box-shadow:0 0 0 1px var(--tw-prose-kbd-shadows),0 3px 0 var(--tw-prose-kbd-shadows);font-size:.875em;border-radius:.3125rem;padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;padding-inline-start:.375em}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code);font-weight:600;font-size:.875em}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:"`"}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:"`"}.prose :where(a code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h1 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.875em}.prose :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.9em}.prose :where(h4 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(blockquote code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(thead th code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-pre-code);background-color:var(--tw-prose-pre-bg);overflow-x:auto;font-weight:400;font-size:.875em;line-height:1.7142857;margin-top:1.7142857em;margin-bottom:1.7142857em;border-radius:.375rem;padding-top:.8571429em;padding-inline-end:1.1428571em;padding-bottom:.8571429em;padding-inline-start:1.1428571em}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)){background-color:transparent;border-width:0;border-radius:0;padding:0;font-weight:inherit;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:none}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:none}.prose :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){width:100%;table-layout:auto;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.7142857}.prose :where(thead):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-th-borders)}.prose :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;vertical-align:bottom;padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose :where(tbody tr):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-td-borders)}.prose :where(tbody tr:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:0}.prose :where(tbody td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:baseline}.prose :where(tfoot):not(:where([class~=not-prose],[class~=not-prose] *)){border-top-width:1px;border-top-color:var(--tw-prose-th-borders)}.prose :where(tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:top}.prose :where(th,td):not(:where([class~=not-prose],[class~=not-prose] *)){text-align:start}.prose :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-captions);font-size:.875em;line-height:1.4285714;margin-top:.8571429em}.prose{--tw-prose-body: #374151;--tw-prose-headings: #111827;--tw-prose-lead: #4b5563;--tw-prose-links: #111827;--tw-prose-bold: #111827;--tw-prose-counters: #6b7280;--tw-prose-bullets: #d1d5db;--tw-prose-hr: #e5e7eb;--tw-prose-quotes: #111827;--tw-prose-quote-borders: #e5e7eb;--tw-prose-captions: #6b7280;--tw-prose-kbd: #111827;--tw-prose-kbd-shadows: rgb(17 24 39 / 10%);--tw-prose-code: #111827;--tw-prose-pre-code: #e5e7eb;--tw-prose-pre-bg: #1f2937;--tw-prose-th-borders: #d1d5db;--tw-prose-td-borders: #e5e7eb;--tw-prose-invert-body: #d1d5db;--tw-prose-invert-headings: #fff;--tw-prose-invert-lead: #9ca3af;--tw-prose-invert-links: #fff;--tw-prose-invert-bold: #fff;--tw-prose-invert-counters: #9ca3af;--tw-prose-invert-bullets: #4b5563;--tw-prose-invert-hr: #374151;--tw-prose-invert-quotes: #f3f4f6;--tw-prose-invert-quote-borders: #374151;--tw-prose-invert-captions: #9ca3af;--tw-prose-invert-kbd: #fff;--tw-prose-invert-kbd-shadows: rgb(255 255 255 / 10%);--tw-prose-invert-code: #fff;--tw-prose-invert-pre-code: #d1d5db;--tw-prose-invert-pre-bg: rgb(0 0 0 / 50%);--tw-prose-invert-th-borders: #4b5563;--tw-prose-invert-td-borders: #374151;font-size:1rem;line-height:1.75}.prose :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;margin-bottom:.5em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(.prose>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(.prose>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(.prose>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;padding-inline-start:1.625em}.prose :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.5714286em;padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(.prose>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(.prose>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.prose-sm{font-size:.875rem;line-height:1.7142857}.prose-sm :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.1428571em;margin-bottom:1.1428571em}.prose-sm :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:1.2857143em;line-height:1.5555556;margin-top:.8888889em;margin-bottom:.8888889em}.prose-sm :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.3333333em;margin-bottom:1.3333333em;padding-inline-start:1.1111111em}.prose-sm :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:2.1428571em;margin-top:0;margin-bottom:.8em;line-height:1.2}.prose-sm :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:1.4285714em;margin-top:1.6em;margin-bottom:.8em;line-height:1.4}.prose-sm :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:1.2857143em;margin-top:1.5555556em;margin-bottom:.4444444em;line-height:1.5555556}.prose-sm :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.4285714em;margin-bottom:.5714286em;line-height:1.4285714}.prose-sm :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.7142857em;margin-bottom:1.7142857em}.prose-sm :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.7142857em;margin-bottom:1.7142857em}.prose-sm :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose-sm :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.7142857em;margin-bottom:1.7142857em}.prose-sm :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.8571429em;border-radius:.3125rem;padding-top:.1428571em;padding-inline-end:.3571429em;padding-bottom:.1428571em;padding-inline-start:.3571429em}.prose-sm :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.8571429em}.prose-sm :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.9em}.prose-sm :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.8888889em}.prose-sm :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.8571429em;line-height:1.6666667;margin-top:1.6666667em;margin-bottom:1.6666667em;border-radius:.25rem;padding-top:.6666667em;padding-inline-end:1em;padding-bottom:.6666667em;padding-inline-start:1em}.prose-sm :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.1428571em;margin-bottom:1.1428571em;padding-inline-start:1.5714286em}.prose-sm :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.1428571em;margin-bottom:1.1428571em;padding-inline-start:1.5714286em}.prose-sm :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.2857143em;margin-bottom:.2857143em}.prose-sm :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.4285714em}.prose-sm :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.4285714em}.prose-sm :where(.prose-sm>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5714286em;margin-bottom:.5714286em}.prose-sm :where(.prose-sm>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.1428571em}.prose-sm :where(.prose-sm>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.1428571em}.prose-sm :where(.prose-sm>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.1428571em}.prose-sm :where(.prose-sm>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.1428571em}.prose-sm :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5714286em;margin-bottom:.5714286em}.prose-sm :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.1428571em;margin-bottom:1.1428571em}.prose-sm :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.1428571em}.prose-sm :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.2857143em;padding-inline-start:1.5714286em}.prose-sm :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2.8571429em;margin-bottom:2.8571429em}.prose-sm :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-sm :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-sm :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-sm :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-sm :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.8571429em;line-height:1.5}.prose-sm :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:1em;padding-bottom:.6666667em;padding-inline-start:1em}.prose-sm :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose-sm :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose-sm :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.6666667em;padding-inline-end:1em;padding-bottom:.6666667em;padding-inline-start:1em}.prose-sm :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose-sm :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose-sm :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.7142857em;margin-bottom:1.7142857em}.prose-sm :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose-sm :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.8571429em;line-height:1.3333333;margin-top:.6666667em}.prose-sm :where(.prose-sm>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-sm :where(.prose-sm>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.prose-invert{--tw-prose-body: var(--tw-prose-invert-body);--tw-prose-headings: var(--tw-prose-invert-headings);--tw-prose-lead: var(--tw-prose-invert-lead);--tw-prose-links: var(--tw-prose-invert-links);--tw-prose-bold: var(--tw-prose-invert-bold);--tw-prose-counters: var(--tw-prose-invert-counters);--tw-prose-bullets: var(--tw-prose-invert-bullets);--tw-prose-hr: var(--tw-prose-invert-hr);--tw-prose-quotes: var(--tw-prose-invert-quotes);--tw-prose-quote-borders: var(--tw-prose-invert-quote-borders);--tw-prose-captions: var(--tw-prose-invert-captions);--tw-prose-kbd: var(--tw-prose-invert-kbd);--tw-prose-kbd-shadows: var(--tw-prose-invert-kbd-shadows);--tw-prose-code: var(--tw-prose-invert-code);--tw-prose-pre-code: var(--tw-prose-invert-pre-code);--tw-prose-pre-bg: var(--tw-prose-invert-pre-bg);--tw-prose-th-borders: var(--tw-prose-invert-th-borders);--tw-prose-td-borders: var(--tw-prose-invert-td-borders)}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.visible{visibility:visible}.collapse{visibility:collapse}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.left-0{left:0}.right-2{right:.5rem}.top-0{top:0}.top-2{top:.5rem}.z-\[100\]{z-index:100}.mx-auto{margin-left:auto;margin-right:auto}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.ml-2{margin-left:.5rem}.ml-auto{margin-left:auto}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.block{display:block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-20{height:5rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-96{height:24rem}.h-full{height:100%}.max-h-screen{max-height:100vh}.min-h-screen{min-height:100vh}.w-1\/2{width:50%}.w-10{width:2.5rem}.w-16{width:4rem}.w-2\/3{width:66.666667%}.w-20{width:5rem}.w-24{width:6rem}.w-3\.5{width:.875rem}.w-3\/4{width:75%}.w-32{width:8rem}.w-4{width:1rem}.w-48{width:12rem}.w-5{width:1.25rem}.w-5\/6{width:83.333333%}.w-64{width:16rem}.w-full{width:100%}.max-w-none{max-width:none}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(1rem * var(--tw-space-x-reverse));margin-left:calc(1rem * calc(1 - var(--tw-space-x-reverse)))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.rounded-t-lg{border-top-left-radius:var(--radius);border-top-right-radius:var(--radius)}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-dashed{border-style:dashed}.border-bg-light{border-color:var(--bg-light)}.border-border{border-color:var(--border)}.border-destructive{border-color:var(--destructive)}.border-input{border-color:var(--input)}.border-transparent{border-color:transparent}.bg-background{background-color:var(--background)}.bg-bg{background-color:var(--bg)}.bg-bg-dark{background-color:var(--bg-dark)}.bg-bg-light{background-color:var(--bg-light)}.bg-card{background-color:var(--card)}.bg-danger{background-color:var(--danger)}.bg-destructive{background-color:var(--destructive)}.bg-muted{background-color:var(--muted)}.bg-primary{background-color:var(--primary)}.bg-secondary{background-color:var(--secondary)}.bg-success{background-color:var(--success)}.bg-transparent{background-color:transparent}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-8{padding-left:2rem;padding-right:2rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-2{padding-bottom:.5rem}.pb-4{padding-bottom:1rem}.pr-8{padding-right:2rem}.pt-0{padding-top:0}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.tracking-tight{letter-spacing:-.025em}.text-card-foreground{color:var(--card-foreground)}.text-danger{color:var(--danger)}.text-destructive-foreground{color:var(--destructive-foreground)}.text-foreground{color:var(--foreground)}.text-muted{color:var(--muted)}.text-muted-foreground{color:var(--muted-foreground)}.text-primary{color:var(--primary)}.text-primary-foreground{color:var(--primary-foreground)}.text-secondary-foreground{color:var(--secondary-foreground)}.text-success{color:var(--success)}.text-text{color:var(--text)}.text-text-muted{color:var(--text-muted)}.line-through{text-decoration-line:line-through}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-90{opacity:.9}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline{outline-style:solid}.ring-offset-background{--tw-ring-offset-color: var(--background)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}@keyframes enter{0%{opacity:var(--tw-enter-opacity, 1);transform:translate3d(var(--tw-enter-translate-x, 0),var(--tw-enter-translate-y, 0),0) scale3d(var(--tw-enter-scale, 1),var(--tw-enter-scale, 1),var(--tw-enter-scale, 1)) rotate(var(--tw-enter-rotate, 0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity, 1);transform:translate3d(var(--tw-exit-translate-x, 0),var(--tw-exit-translate-y, 0),0) scale3d(var(--tw-exit-scale, 1),var(--tw-exit-scale, 1),var(--tw-exit-scale, 1)) rotate(var(--tw-exit-rotate, 0))}}.running{animation-play-state:running}.hover\:bg-accent:hover{background-color:var(--accent)}.hover\:bg-secondary:hover{background-color:var(--secondary)}.hover\:text-accent-foreground:hover{color:var(--accent-foreground)}.hover\:text-foreground:hover{color:var(--foreground)}.hover\:text-primary:hover{color:var(--primary)}.hover\:text-text:hover{color:var(--text)}.hover\:underline:hover{text-decoration-line:underline}.focus\:opacity-100:focus{opacity:1}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-ring:focus{--tw-ring-color: var(--ring)}.focus\:ring-offset-2:focus{--tw-ring-offset-width: 2px}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color: var(--ring)}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width: 2px}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:opacity-50:disabled{opacity:.5}.group:hover .group-hover\:opacity-100{opacity:1}.group.destructive .group-\[\.destructive\]\:text-red-300{--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}.group.destructive .group-\[\.destructive\]\:hover\:bg-destructive:hover{background-color:var(--destructive)}.group.destructive .group-\[\.destructive\]\:hover\:text-destructive-foreground:hover{color:var(--destructive-foreground)}.group.destructive .group-\[\.destructive\]\:hover\:text-red-50:hover{--tw-text-opacity: 1;color:rgb(254 242 242 / var(--tw-text-opacity, 1))}.group.destructive .group-\[\.destructive\]\:focus\:ring-destructive:focus{--tw-ring-color: var(--destructive)}.group.destructive .group-\[\.destructive\]\:focus\:ring-red-400:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(248 113 113 / var(--tw-ring-opacity, 1))}.group.destructive .group-\[\.destructive\]\:focus\:ring-offset-red-600:focus{--tw-ring-offset-color: #dc2626}.data-\[swipe\=cancel\]\:translate-x-0[data-swipe=cancel]{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[swipe\=end\]\:translate-x-\[var\(--radix-toast-swipe-end-x\)\][data-swipe=end]{--tw-translate-x: var(--radix-toast-swipe-end-x);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[swipe\=move\]\:translate-x-\[var\(--radix-toast-swipe-move-x\)\][data-swipe=move]{--tw-translate-x: var(--radix-toast-swipe-move-x);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[state\=active\]\:bg-background[data-state=active]{background-color:var(--background)}.data-\[state\=active\]\:text-foreground[data-state=active]{color:var(--foreground)}.data-\[state\=active\]\:shadow-sm[data-state=active]{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.data-\[swipe\=move\]\:transition-none[data-swipe=move]{transition-property:none}.data-\[state\=open\]\:animate-in[data-state=open]{animation-name:enter;animation-duration:.15s;--tw-enter-opacity: initial;--tw-enter-scale: initial;--tw-enter-rotate: initial;--tw-enter-translate-x: initial;--tw-enter-translate-y: initial}.data-\[state\=closed\]\:animate-out[data-state=closed],.data-\[swipe\=end\]\:animate-out[data-swipe=end]{animation-name:exit;animation-duration:.15s;--tw-exit-opacity: initial;--tw-exit-scale: initial;--tw-exit-rotate: initial;--tw-exit-translate-x: initial;--tw-exit-translate-y: initial}.data-\[state\=closed\]\:fade-out-80[data-state=closed]{--tw-exit-opacity: .8}.data-\[state\=closed\]\:slide-out-to-right-full[data-state=closed]{--tw-exit-translate-x: 100%}.data-\[state\=open\]\:slide-in-from-top-full[data-state=open]{--tw-enter-translate-y: -100%}.prose-headings\:text-text :is(:where(h1,h2,h3,h4,h5,h6,th):not(:where([class~=not-prose],[class~=not-prose] *))){color:var(--text)}.prose-p\:text-text-muted :is(:where(p):not(:where([class~=not-prose],[class~=not-prose] *))){color:var(--text-muted)}.prose-a\:text-primary :is(:where(a):not(:where([class~=not-prose],[class~=not-prose] *))){color:var(--primary)}.prose-a\:no-underline :is(:where(a):not(:where([class~=not-prose],[class~=not-prose] *))){text-decoration-line:none}.hover\:prose-a\:underline :is(:where(a):not(:where([class~=not-prose],[class~=not-prose] *))):hover{text-decoration-line:underline}.prose-strong\:text-text :is(:where(strong):not(:where([class~=not-prose],[class~=not-prose] *))){color:var(--text)}.prose-code\:rounded :is(:where(code):not(:where([class~=not-prose],[class~=not-prose] *))){border-radius:.25rem}.prose-code\:bg-bg-dark :is(:where(code):not(:where([class~=not-prose],[class~=not-prose] *))){background-color:var(--bg-dark)}.prose-code\:px-1 :is(:where(code):not(:where([class~=not-prose],[class~=not-prose] *))){padding-left:.25rem;padding-right:.25rem}.prose-code\:py-0\.5 :is(:where(code):not(:where([class~=not-prose],[class~=not-prose] *))){padding-top:.125rem;padding-bottom:.125rem}.prose-code\:text-primary :is(:where(code):not(:where([class~=not-prose],[class~=not-prose] *))){color:var(--primary)}.prose-code\:before\:content-none :is(:where(code):not(:where([class~=not-prose],[class~=not-prose] *))):before{--tw-content: none;content:var(--tw-content)}.prose-code\:after\:content-none :is(:where(code):not(:where([class~=not-prose],[class~=not-prose] *))):after{--tw-content: none;content:var(--tw-content)}.prose-pre\:border :is(:where(pre):not(:where([class~=not-prose],[class~=not-prose] *))){border-width:1px}.prose-pre\:bg-bg-dark :is(:where(pre):not(:where([class~=not-prose],[class~=not-prose] *))){background-color:var(--bg-dark)}.prose-li\:text-text-muted :is(:where(li):not(:where([class~=not-prose],[class~=not-prose] *))){color:var(--text-muted)}.prose-table\:border :is(:where(table):not(:where([class~=not-prose],[class~=not-prose] *))){border-width:1px}.prose-th\:bg-bg-dark :is(:where(th):not(:where([class~=not-prose],[class~=not-prose] *))){background-color:var(--bg-dark)}.prose-th\:px-3 :is(:where(th):not(:where([class~=not-prose],[class~=not-prose] *))){padding-left:.75rem;padding-right:.75rem}.prose-th\:py-2 :is(:where(th):not(:where([class~=not-prose],[class~=not-prose] *))){padding-top:.5rem;padding-bottom:.5rem}.prose-th\:text-text :is(:where(th):not(:where([class~=not-prose],[class~=not-prose] *))){color:var(--text)}.prose-td\:border-t :is(:where(td):not(:where([class~=not-prose],[class~=not-prose] *))){border-top-width:1px}.prose-td\:px-3 :is(:where(td):not(:where([class~=not-prose],[class~=not-prose] *))){padding-left:.75rem;padding-right:.75rem}.prose-td\:py-2 :is(:where(td):not(:where([class~=not-prose],[class~=not-prose] *))){padding-top:.5rem;padding-bottom:.5rem}@media(min-width:640px){.sm\:bottom-0{bottom:0}.sm\:right-0{right:0}.sm\:top-auto{top:auto}.sm\:flex-col{flex-direction:column}.data-\[state\=open\]\:sm\:slide-in-from-bottom-full[data-state=open]{--tw-enter-translate-y: 100%}}@media(min-width:768px){.md\:max-w-\[420px\]{max-width:420px}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(min-width:1024px){.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-4 svg{width:1rem;height:1rem}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}
|