panopticon-cli 0.4.11 → 0.4.12
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/{chunk-ZQA6PUAO.js → chunk-WLL3UEYI.js} +28 -6
- package/dist/chunk-WLL3UEYI.js.map +1 -0
- package/dist/cli/index.js +1 -1
- package/dist/dashboard/public/assets/index-Bp7DyPLO.css +32 -0
- package/dist/dashboard/public/assets/{index-GwTde56u.js → index-Bwu9d0w1.js} +54 -54
- package/dist/dashboard/public/index.html +2 -2
- package/dist/dashboard/server.js +171 -20
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-ZQA6PUAO.js.map +0 -1
- package/dist/dashboard/public/assets/index-iqMjcW09.css +0 -32
|
@@ -870,7 +870,12 @@ var RallyRestApi = class {
|
|
|
870
870
|
}
|
|
871
871
|
const result = await response.json();
|
|
872
872
|
if (result.QueryResult.Errors && result.QueryResult.Errors.length > 0) {
|
|
873
|
-
|
|
873
|
+
const errorDetail = result.QueryResult.Errors.join(", ");
|
|
874
|
+
const queryDetail = config.query ? ` (Query: ${config.query})` : "";
|
|
875
|
+
if (process.env.DEBUG?.includes("rally")) {
|
|
876
|
+
console.error("[Rally WSAPI] Query failed:", { query: config.query, errors: result.QueryResult.Errors });
|
|
877
|
+
}
|
|
878
|
+
throw new Error(`Rally API query failed: ${errorDetail}${queryDetail}`);
|
|
874
879
|
}
|
|
875
880
|
return result;
|
|
876
881
|
}
|
|
@@ -984,6 +989,11 @@ var RallyTracker = class {
|
|
|
984
989
|
this.project = config.project;
|
|
985
990
|
}
|
|
986
991
|
async listIssues(filters) {
|
|
992
|
+
const queryString = this.buildQueryString(filters);
|
|
993
|
+
if (process.env.DEBUG?.includes("rally")) {
|
|
994
|
+
console.debug("[Rally] Query filters:", JSON.stringify(filters));
|
|
995
|
+
console.debug("[Rally] Generated query:", queryString);
|
|
996
|
+
}
|
|
987
997
|
const query = {
|
|
988
998
|
type: "artifact",
|
|
989
999
|
// Query all artifact types
|
|
@@ -1004,7 +1014,7 @@ var RallyTracker = class {
|
|
|
1004
1014
|
"_type"
|
|
1005
1015
|
],
|
|
1006
1016
|
limit: filters?.limit ?? 50,
|
|
1007
|
-
query:
|
|
1017
|
+
query: queryString
|
|
1008
1018
|
};
|
|
1009
1019
|
if (this.workspace) {
|
|
1010
1020
|
query.workspace = this.workspace;
|
|
@@ -1204,6 +1214,17 @@ var RallyTracker = class {
|
|
|
1204
1214
|
await this.addComment(issueId, `Linked Pull Request: ${prUrl}`);
|
|
1205
1215
|
}
|
|
1206
1216
|
// Private helper methods
|
|
1217
|
+
/**
|
|
1218
|
+
* Build a Rally WSAPI query string from issue filters.
|
|
1219
|
+
*
|
|
1220
|
+
* Rally WSAPI v2.0 requires the entire compound query expression to be wrapped
|
|
1221
|
+
* in outer parentheses when multiple conditions are joined with AND/OR.
|
|
1222
|
+
* Without the outer parens, the WSAPI parser fails with:
|
|
1223
|
+
* "Could not parse: Error parsing expression -- expected ")" but saw "AND" instead."
|
|
1224
|
+
*
|
|
1225
|
+
* Valid: (((ScheduleState != "Completed") AND (State != "Closed")) AND (Owner.Name contains "John"))
|
|
1226
|
+
* Invalid: ((ScheduleState != "Completed") AND (State != "Closed")) AND (Owner.Name contains "John")
|
|
1227
|
+
*/
|
|
1207
1228
|
buildQueryString(filters) {
|
|
1208
1229
|
const conditions = [];
|
|
1209
1230
|
if (filters?.state && !filters.includeClosed) {
|
|
@@ -1211,7 +1232,7 @@ var RallyTracker = class {
|
|
|
1211
1232
|
conditions.push(`((ScheduleState = "${rallyState}") OR (State = "${rallyState}"))`);
|
|
1212
1233
|
}
|
|
1213
1234
|
if (!filters?.includeClosed) {
|
|
1214
|
-
conditions.push('((ScheduleState != "Completed") AND (ScheduleState != "Accepted") AND (State != "Closed"))');
|
|
1235
|
+
conditions.push('(((ScheduleState != "Completed") AND (ScheduleState != "Accepted")) AND (State != "Closed"))');
|
|
1215
1236
|
}
|
|
1216
1237
|
if (filters?.assignee) {
|
|
1217
1238
|
conditions.push(`(Owner.Name contains "${filters.assignee}")`);
|
|
@@ -1220,12 +1241,13 @@ var RallyTracker = class {
|
|
|
1220
1241
|
const labelConditions = filters.labels.map(
|
|
1221
1242
|
(label) => `(Tags.Name contains "${label}")`
|
|
1222
1243
|
);
|
|
1223
|
-
|
|
1244
|
+
const labelExpr = labelConditions.reduce((acc, cond) => acc ? `(${acc} AND ${cond})` : cond, "");
|
|
1245
|
+
conditions.push(labelExpr);
|
|
1224
1246
|
}
|
|
1225
1247
|
if (filters?.query) {
|
|
1226
1248
|
conditions.push(`((Name contains "${filters.query}") OR (Description contains "${filters.query}"))`);
|
|
1227
1249
|
}
|
|
1228
|
-
return conditions.
|
|
1250
|
+
return conditions.reduce((acc, cond) => acc ? `(${acc} AND ${cond})` : cond, "");
|
|
1229
1251
|
}
|
|
1230
1252
|
normalizeIssue(rallyArtifact) {
|
|
1231
1253
|
const stateValue = rallyArtifact.ScheduleState || rallyArtifact.State || "Defined";
|
|
@@ -1580,4 +1602,4 @@ export {
|
|
|
1580
1602
|
LinkManager,
|
|
1581
1603
|
getLinkManager
|
|
1582
1604
|
};
|
|
1583
|
-
//# sourceMappingURL=chunk-
|
|
1605
|
+
//# sourceMappingURL=chunk-WLL3UEYI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/shell.ts","../src/lib/backup.ts","../src/lib/sync.ts","../src/lib/tracker/interface.ts","../src/lib/tracker/linear.ts","../src/lib/tracker/github.ts","../src/lib/tracker/gitlab.ts","../src/lib/tracker/factory.ts","../src/lib/tracker/rally.ts","../src/lib/tracker/rally-api.ts","../src/lib/tracker/linking.ts","../src/lib/tracker/index.ts"],"sourcesContent":["import { existsSync, readFileSync, appendFileSync } from 'fs';\nimport { homedir } from 'os';\nimport { join } from 'path';\n\nexport type Shell = 'bash' | 'zsh' | 'fish' | 'unknown';\n\nexport function detectShell(): Shell {\n const shell = process.env.SHELL || '';\n\n if (shell.includes('zsh')) return 'zsh';\n if (shell.includes('bash')) return 'bash';\n if (shell.includes('fish')) return 'fish';\n\n return 'unknown';\n}\n\nexport function getShellRcFile(shell: Shell): string | null {\n const home = homedir();\n\n switch (shell) {\n case 'zsh':\n return join(home, '.zshrc');\n case 'bash':\n // Prefer .bashrc, fall back to .bash_profile\n const bashrc = join(home, '.bashrc');\n if (existsSync(bashrc)) return bashrc;\n return join(home, '.bash_profile');\n case 'fish':\n return join(home, '.config', 'fish', 'config.fish');\n default:\n return null;\n }\n}\n\nconst ALIAS_LINE = 'alias pan=\"panopticon\"';\nconst ALIAS_MARKER = '# Panopticon CLI alias';\n\nexport function hasAlias(rcFile: string): boolean {\n if (!existsSync(rcFile)) return false;\n\n const content = readFileSync(rcFile, 'utf8');\n return content.includes(ALIAS_MARKER) || content.includes(ALIAS_LINE);\n}\n\nexport function addAlias(rcFile: string): void {\n if (hasAlias(rcFile)) return;\n\n const aliasBlock = `\n${ALIAS_MARKER}\n${ALIAS_LINE}\n`;\n\n appendFileSync(rcFile, aliasBlock, 'utf8');\n}\n\nexport function getAliasInstructions(shell: Shell): string {\n const rcFile = getShellRcFile(shell);\n\n if (!rcFile) {\n return `Add this to your shell config:\\n ${ALIAS_LINE}`;\n }\n\n return `Alias added to ${rcFile}. Run:\\n source ${rcFile}`;\n}\n","import { existsSync, mkdirSync, readdirSync, cpSync, rmSync, lstatSync } from 'fs';\nimport { join, basename } from 'path';\nimport { BACKUPS_DIR } from './paths.js';\n\nexport interface BackupInfo {\n timestamp: string;\n path: string;\n targets: string[];\n}\n\nexport function createBackupTimestamp(): string {\n return new Date().toISOString().replace(/[:.]/g, '-');\n}\n\nexport function createBackup(sourceDirs: string[]): BackupInfo {\n const timestamp = createBackupTimestamp();\n const backupPath = join(BACKUPS_DIR, timestamp);\n\n mkdirSync(backupPath, { recursive: true });\n\n const targets: string[] = [];\n\n for (const sourceDir of sourceDirs) {\n if (!existsSync(sourceDir)) continue;\n\n const targetName = basename(sourceDir);\n const targetPath = join(backupPath, targetName);\n\n // Use filter to skip symlinks — sync targets (e.g. ~/.claude/skills/)\n // contain symlinks back into ~/.panopticon/skills/ which causes cpSync\n // to fail with \"cannot copy to a subdirectory of self\".\n cpSync(sourceDir, targetPath, {\n recursive: true,\n filter: (src) => !lstatSync(src).isSymbolicLink(),\n });\n targets.push(targetName);\n }\n\n return {\n timestamp,\n path: backupPath,\n targets,\n };\n}\n\nexport function listBackups(): BackupInfo[] {\n if (!existsSync(BACKUPS_DIR)) return [];\n\n const entries = readdirSync(BACKUPS_DIR, { withFileTypes: true });\n\n return entries\n .filter((e) => e.isDirectory())\n .map((e) => {\n const backupPath = join(BACKUPS_DIR, e.name);\n const contents = readdirSync(backupPath);\n\n return {\n timestamp: e.name,\n path: backupPath,\n targets: contents,\n };\n })\n .sort((a, b) => b.timestamp.localeCompare(a.timestamp));\n}\n\nexport function restoreBackup(timestamp: string, targetDirs: Record<string, string>): void {\n const backupPath = join(BACKUPS_DIR, timestamp);\n\n if (!existsSync(backupPath)) {\n throw new Error(`Backup not found: ${timestamp}`);\n }\n\n const contents = readdirSync(backupPath, { withFileTypes: true });\n\n for (const entry of contents) {\n if (!entry.isDirectory()) continue;\n\n const sourcePath = join(backupPath, entry.name);\n const targetPath = targetDirs[entry.name];\n\n if (!targetPath) continue;\n\n // Remove existing and restore from backup\n if (existsSync(targetPath)) {\n rmSync(targetPath, { recursive: true });\n }\n\n cpSync(sourcePath, targetPath, { recursive: true });\n }\n}\n\nexport function cleanOldBackups(keepCount: number = 10): number {\n const backups = listBackups();\n\n if (backups.length <= keepCount) return 0;\n\n const toRemove = backups.slice(keepCount);\n let removed = 0;\n\n for (const backup of toRemove) {\n rmSync(backup.path, { recursive: true });\n removed++;\n }\n\n return removed;\n}\n","import { existsSync, mkdirSync, readdirSync, symlinkSync, unlinkSync, lstatSync, readlinkSync, rmSync, copyFileSync, chmodSync } from 'fs';\nimport { join, basename } from 'path';\nimport { SKILLS_DIR, COMMANDS_DIR, AGENTS_DIR, BIN_DIR, SOURCE_SCRIPTS_DIR, SOURCE_DEV_SKILLS_DIR, SYNC_TARGETS, isDevMode, type Runtime } from './paths.js';\n\nexport interface SyncItem {\n name: string;\n sourcePath: string;\n targetPath: string;\n status: 'new' | 'exists' | 'conflict' | 'symlink';\n}\n\nexport interface SyncPlan {\n runtime: Runtime;\n skills: SyncItem[];\n commands: SyncItem[];\n agents: SyncItem[];\n devSkills: SyncItem[]; // Developer-only skills (only synced in dev mode)\n}\n\n/**\n * Remove a file, symlink, or directory safely\n */\nfunction removeTarget(targetPath: string): void {\n const stats = lstatSync(targetPath);\n if (stats.isDirectory() && !stats.isSymbolicLink()) {\n // It's a real directory, remove recursively\n rmSync(targetPath, { recursive: true, force: true });\n } else {\n // It's a file or symlink\n unlinkSync(targetPath);\n }\n}\n\n/**\n * Check if a path is a Panopticon-managed symlink\n */\nexport function isPanopticonSymlink(targetPath: string): boolean {\n if (!existsSync(targetPath)) return false;\n\n try {\n const stats = lstatSync(targetPath);\n if (!stats.isSymbolicLink()) return false;\n\n const linkTarget = readlinkSync(targetPath);\n // It's ours if it points to our skills/commands dir\n return linkTarget.includes('.panopticon');\n } catch {\n return false;\n }\n}\n\n/**\n * Plan what would be synced (dry run)\n */\nexport function planSync(runtime: Runtime): SyncPlan {\n const targets = SYNC_TARGETS[runtime];\n if (!targets) {\n throw new Error(`Unknown sync target \"${runtime}\". Valid targets: ${Object.keys(SYNC_TARGETS).join(', ')}`);\n }\n const plan: SyncPlan = {\n runtime,\n skills: [],\n commands: [],\n agents: [],\n devSkills: [],\n };\n\n // Plan skills sync\n if (existsSync(SKILLS_DIR)) {\n const skills = readdirSync(SKILLS_DIR, { withFileTypes: true })\n .filter((d) => d.isDirectory());\n\n for (const skill of skills) {\n const sourcePath = join(SKILLS_DIR, skill.name);\n const targetPath = join(targets.skills, skill.name);\n\n let status: SyncItem['status'] = 'new';\n\n if (existsSync(targetPath)) {\n if (isPanopticonSymlink(targetPath)) {\n status = 'symlink'; // Already managed by us\n } else {\n status = 'conflict'; // User content exists\n }\n }\n\n plan.skills.push({ name: skill.name, sourcePath, targetPath, status });\n }\n }\n\n // Plan dev-skills sync (only in dev mode)\n if (isDevMode() && existsSync(SOURCE_DEV_SKILLS_DIR)) {\n const devSkills = readdirSync(SOURCE_DEV_SKILLS_DIR, { withFileTypes: true })\n .filter((d) => d.isDirectory());\n\n for (const skill of devSkills) {\n const sourcePath = join(SOURCE_DEV_SKILLS_DIR, skill.name);\n const targetPath = join(targets.skills, skill.name);\n\n let status: SyncItem['status'] = 'new';\n\n if (existsSync(targetPath)) {\n if (isPanopticonSymlink(targetPath)) {\n status = 'symlink'; // Already managed by us\n } else {\n status = 'conflict'; // User content exists\n }\n }\n\n plan.devSkills.push({ name: skill.name, sourcePath, targetPath, status });\n }\n }\n\n // Plan commands sync\n if (existsSync(COMMANDS_DIR)) {\n const commands = readdirSync(COMMANDS_DIR, { withFileTypes: true })\n .filter((d) => d.isDirectory());\n\n for (const cmd of commands) {\n const sourcePath = join(COMMANDS_DIR, cmd.name);\n const targetPath = join(targets.commands, cmd.name);\n\n let status: SyncItem['status'] = 'new';\n\n if (existsSync(targetPath)) {\n if (isPanopticonSymlink(targetPath)) {\n status = 'symlink';\n } else {\n status = 'conflict';\n }\n }\n\n plan.commands.push({ name: cmd.name, sourcePath, targetPath, status });\n }\n }\n\n // Plan agents sync\n if (existsSync(AGENTS_DIR)) {\n const agents = readdirSync(AGENTS_DIR, { withFileTypes: true })\n .filter((entry) => entry.isFile() && entry.name.endsWith('.md'));\n\n for (const agent of agents) {\n const sourcePath = join(AGENTS_DIR, agent.name);\n const targetPath = join(targets.agents, agent.name);\n\n let status: SyncItem['status'] = 'new';\n\n if (existsSync(targetPath)) {\n if (isPanopticonSymlink(targetPath)) {\n status = 'symlink'; // Already managed by us\n } else {\n status = 'conflict'; // User content exists\n }\n }\n\n plan.agents.push({ name: agent.name, sourcePath, targetPath, status });\n }\n }\n\n return plan;\n}\n\nexport interface SyncOptions {\n force?: boolean;\n dryRun?: boolean;\n}\n\nexport interface SyncResult {\n created: string[];\n skipped: string[];\n conflicts: string[];\n}\n\n/**\n * Execute sync for a runtime\n */\nexport function executeSync(runtime: Runtime, options: SyncOptions = {}): SyncResult {\n const targets = SYNC_TARGETS[runtime];\n if (!targets) {\n throw new Error(`Unknown sync target \"${runtime}\". Valid targets: ${Object.keys(SYNC_TARGETS).join(', ')}`);\n }\n const plan = planSync(runtime);\n const result: SyncResult = {\n created: [],\n skipped: [],\n conflicts: [],\n };\n\n // Ensure target directories exist\n mkdirSync(targets.skills, { recursive: true });\n mkdirSync(targets.commands, { recursive: true });\n mkdirSync(targets.agents, { recursive: true });\n\n // Process skills\n for (const item of plan.skills) {\n if (options.dryRun) {\n if (item.status === 'new' || item.status === 'symlink') {\n result.created.push(item.name);\n } else {\n result.conflicts.push(item.name);\n }\n continue;\n }\n\n if (item.status === 'conflict' && !options.force) {\n result.conflicts.push(item.name);\n continue;\n }\n\n // Remove existing if force or if it's our symlink\n if (existsSync(item.targetPath)) {\n removeTarget(item.targetPath);\n }\n\n // Create symlink\n symlinkSync(item.sourcePath, item.targetPath);\n result.created.push(item.name);\n }\n\n // Process commands\n for (const item of plan.commands) {\n if (options.dryRun) {\n if (item.status === 'new' || item.status === 'symlink') {\n result.created.push(item.name);\n } else {\n result.conflicts.push(item.name);\n }\n continue;\n }\n\n if (item.status === 'conflict' && !options.force) {\n result.conflicts.push(item.name);\n continue;\n }\n\n if (existsSync(item.targetPath)) {\n removeTarget(item.targetPath);\n }\n\n symlinkSync(item.sourcePath, item.targetPath);\n result.created.push(item.name);\n }\n\n // Process agents\n for (const item of plan.agents) {\n if (options.dryRun) {\n if (item.status === 'new' || item.status === 'symlink') {\n result.created.push(item.name);\n } else {\n result.conflicts.push(item.name);\n }\n continue;\n }\n\n if (item.status === 'conflict' && !options.force) {\n result.conflicts.push(item.name);\n continue;\n }\n\n if (existsSync(item.targetPath)) {\n removeTarget(item.targetPath);\n }\n\n symlinkSync(item.sourcePath, item.targetPath);\n result.created.push(item.name);\n }\n\n // Process dev-skills (only in dev mode)\n for (const item of plan.devSkills) {\n if (options.dryRun) {\n if (item.status === 'new' || item.status === 'symlink') {\n result.created.push(`${item.name} (dev)`);\n } else {\n result.conflicts.push(`${item.name} (dev)`);\n }\n continue;\n }\n\n if (item.status === 'conflict' && !options.force) {\n result.conflicts.push(`${item.name} (dev)`);\n continue;\n }\n\n if (existsSync(item.targetPath)) {\n removeTarget(item.targetPath);\n }\n\n symlinkSync(item.sourcePath, item.targetPath);\n result.created.push(`${item.name} (dev)`);\n }\n\n return result;\n}\n\n/**\n * Hook item for sync planning\n */\nexport interface HookItem {\n name: string;\n sourcePath: string;\n targetPath: string;\n status: 'new' | 'updated' | 'current';\n}\n\n/**\n * Plan hooks sync (checks what would be updated)\n */\nexport function planHooksSync(): HookItem[] {\n const hooks: HookItem[] = [];\n\n if (!existsSync(SOURCE_SCRIPTS_DIR)) {\n return hooks;\n }\n\n // Only sync hook scripts (no extension) - skip helper scripts like .mjs, .sh\n const scripts = readdirSync(SOURCE_SCRIPTS_DIR, { withFileTypes: true })\n .filter((entry) => entry.isFile() && !entry.name.startsWith('.') && !entry.name.includes('.'));\n\n for (const script of scripts) {\n const sourcePath = join(SOURCE_SCRIPTS_DIR, script.name);\n const targetPath = join(BIN_DIR, script.name);\n\n let status: HookItem['status'] = 'new';\n\n if (existsSync(targetPath)) {\n // Could compare file contents/timestamps here for 'current' vs 'updated'\n // For now, always update to ensure latest version\n status = 'updated';\n }\n\n hooks.push({ name: script.name, sourcePath, targetPath, status });\n }\n\n return hooks;\n}\n\n/**\n * Sync hooks (copy scripts to ~/.panopticon/bin/)\n */\nexport function syncHooks(): { synced: string[]; errors: string[] } {\n const result = { synced: [] as string[], errors: [] as string[] };\n\n // Ensure bin directory exists\n mkdirSync(BIN_DIR, { recursive: true });\n\n const hooks = planHooksSync();\n\n for (const hook of hooks) {\n try {\n copyFileSync(hook.sourcePath, hook.targetPath);\n chmodSync(hook.targetPath, 0o755); // Make executable\n result.synced.push(hook.name);\n } catch (error) {\n result.errors.push(`${hook.name}: ${error}`);\n }\n }\n\n return result;\n}\n","/**\n * Issue Tracker Abstraction Layer\n *\n * Provides a unified interface for different issue tracking systems\n * (Linear, GitHub Issues, GitLab Issues, etc.)\n */\n\n// Supported tracker types\nexport type TrackerType = 'linear' | 'github' | 'gitlab' | 'rally';\n\n// Normalized issue state (lowest common denominator)\nexport type IssueState = 'open' | 'in_progress' | 'closed';\n\n// Normalized issue format\nexport interface Issue {\n /** Tracker-specific unique ID */\n id: string;\n\n /** Human-readable reference (e.g., MIN-630, #42) */\n ref: string;\n\n /** Issue title */\n title: string;\n\n /** Issue description/body (markdown) */\n description: string;\n\n /** Normalized state */\n state: IssueState;\n\n /** Labels/tags */\n labels: string[];\n\n /** Assignee username/name */\n assignee?: string;\n\n /** Web URL to the issue */\n url: string;\n\n /** Which tracker this issue came from */\n tracker: TrackerType;\n\n /** Cross-tracker linked issue references */\n linkedIssues?: string[];\n\n /** Priority (1=urgent, 2=high, 3=normal, 4=low) */\n priority?: number;\n\n /** Due date (ISO string) */\n dueDate?: string;\n\n /** Creation timestamp (ISO string) */\n createdAt: string;\n\n /** Last update timestamp (ISO string) */\n updatedAt: string;\n}\n\n// Comment on an issue\nexport interface Comment {\n id: string;\n issueId: string;\n body: string;\n author: string;\n createdAt: string;\n updatedAt: string;\n}\n\n// Filters for listing issues\nexport interface IssueFilters {\n /** Filter by state */\n state?: IssueState;\n\n /** Filter by labels (AND logic) */\n labels?: string[];\n\n /** Filter by assignee */\n assignee?: string;\n\n /** Filter by team/project (tracker-specific) */\n team?: string;\n\n /** Search query for title/description */\n query?: string;\n\n /** Maximum number of results */\n limit?: number;\n\n /** Include closed issues (default: false) */\n includeClosed?: boolean;\n}\n\n// Data for creating a new issue\nexport interface NewIssue {\n title: string;\n description?: string;\n labels?: string[];\n assignee?: string;\n team?: string;\n priority?: number;\n dueDate?: string;\n}\n\n// Data for updating an issue\nexport interface IssueUpdate {\n title?: string;\n description?: string;\n state?: IssueState;\n labels?: string[];\n assignee?: string;\n priority?: number;\n dueDate?: string;\n}\n\n/**\n * Abstract interface for issue trackers.\n * Implementations must handle normalization to/from tracker-specific formats.\n */\nexport interface IssueTracker {\n /** Tracker type identifier */\n readonly name: TrackerType;\n\n /**\n * List issues matching filters\n */\n listIssues(filters?: IssueFilters): Promise<Issue[]>;\n\n /**\n * Get a single issue by ID or ref\n * @param id - Issue ID or human-readable ref (e.g., \"MIN-630\", \"#42\")\n */\n getIssue(id: string): Promise<Issue>;\n\n /**\n * Update an existing issue\n */\n updateIssue(id: string, update: IssueUpdate): Promise<Issue>;\n\n /**\n * Create a new issue\n */\n createIssue(issue: NewIssue): Promise<Issue>;\n\n /**\n * Get comments on an issue\n */\n getComments(issueId: string): Promise<Comment[]>;\n\n /**\n * Add a comment to an issue\n */\n addComment(issueId: string, body: string): Promise<Comment>;\n\n /**\n * Transition issue to a new state\n */\n transitionIssue(id: string, state: IssueState): Promise<void>;\n\n /**\n * Link a PR/MR to an issue\n */\n linkPR(issueId: string, prUrl: string): Promise<void>;\n}\n\n/**\n * Error thrown when a tracker feature is not implemented\n */\nexport class NotImplementedError extends Error {\n constructor(feature: string) {\n super(`Not implemented: ${feature}`);\n this.name = 'NotImplementedError';\n }\n}\n\n/**\n * Error thrown when an issue is not found\n */\nexport class IssueNotFoundError extends Error {\n constructor(id: string, tracker: TrackerType) {\n super(`Issue not found: ${id} (tracker: ${tracker})`);\n this.name = 'IssueNotFoundError';\n }\n}\n\n/**\n * Error thrown when tracker authentication fails\n */\nexport class TrackerAuthError extends Error {\n constructor(tracker: TrackerType, message: string) {\n super(`Authentication failed for ${tracker}: ${message}`);\n this.name = 'TrackerAuthError';\n }\n}\n","/**\n * Linear Issue Tracker Adapter\n *\n * Implements IssueTracker interface for Linear.\n */\n\nimport { LinearClient } from '@linear/sdk';\nimport type {\n Issue,\n IssueFilters,\n IssueState,\n IssueTracker,\n IssueUpdate,\n NewIssue,\n Comment,\n TrackerType,\n} from './interface.js';\nimport { IssueNotFoundError, TrackerAuthError } from './interface.js';\n\n// Map Linear state types to our normalized states\nconst STATE_MAP: Record<string, IssueState> = {\n backlog: 'open',\n unstarted: 'open',\n started: 'in_progress',\n completed: 'closed',\n canceled: 'closed',\n};\n\nexport class LinearTracker implements IssueTracker {\n readonly name: TrackerType = 'linear';\n private client: LinearClient;\n private defaultTeam?: string;\n\n constructor(apiKey: string, options?: { team?: string }) {\n if (!apiKey) {\n throw new TrackerAuthError('linear', 'API key is required');\n }\n this.client = new LinearClient({ apiKey });\n this.defaultTeam = options?.team;\n }\n\n async listIssues(filters?: IssueFilters): Promise<Issue[]> {\n const team = filters?.team ?? this.defaultTeam;\n\n const result = await this.client.issues({\n first: filters?.limit ?? 50,\n filter: {\n team: team ? { key: { eq: team } } : undefined,\n state: filters?.state\n ? { type: { eq: this.reverseMapState(filters.state) } }\n : filters?.includeClosed\n ? undefined\n : { type: { neq: 'completed' } },\n labels: filters?.labels?.length\n ? { name: { in: filters.labels } }\n : undefined,\n assignee: filters?.assignee\n ? { name: { containsIgnoreCase: filters.assignee } }\n : undefined,\n },\n });\n\n const issues: Issue[] = [];\n for (const node of result.nodes) {\n issues.push(await this.normalizeIssue(node));\n }\n return issues;\n }\n\n async getIssue(id: string): Promise<Issue> {\n try {\n // Check if it's a UUID (36 chars with hyphens)\n const isUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id);\n\n if (isUuid) {\n // Fetch directly by UUID\n const issue = await this.client.issue(id);\n if (issue) {\n return this.normalizeIssue(issue);\n }\n } else {\n // Parse identifier (e.g., MIN-630) and search\n const match = id.match(/^([A-Z]+)-(\\d+)$/i);\n if (match) {\n const [, teamKey, number] = match;\n // Use searchIssues which supports identifier matching\n const results = await this.client.searchIssues(id, { first: 1 });\n if (results.nodes.length > 0) {\n return this.normalizeIssue(results.nodes[0]);\n }\n }\n }\n\n throw new IssueNotFoundError(id, 'linear');\n } catch (error) {\n if (error instanceof IssueNotFoundError) throw error;\n throw new IssueNotFoundError(id, 'linear');\n }\n }\n\n async updateIssue(id: string, update: IssueUpdate): Promise<Issue> {\n const issue = await this.getIssue(id);\n\n const updatePayload: Record<string, unknown> = {};\n\n if (update.title !== undefined) {\n updatePayload.title = update.title;\n }\n if (update.description !== undefined) {\n updatePayload.description = update.description;\n }\n if (update.priority !== undefined) {\n updatePayload.priority = update.priority;\n }\n if (update.dueDate !== undefined) {\n updatePayload.dueDate = update.dueDate;\n }\n if (update.state !== undefined) {\n // Need to find the state ID - this is complex in Linear\n // For now, we'll use the transition method\n await this.transitionIssue(id, update.state);\n }\n if (update.labels !== undefined) {\n // Need to look up label IDs - complex operation\n // TODO: Implement label updates\n }\n\n if (Object.keys(updatePayload).length > 0) {\n await this.client.updateIssue(issue.id, updatePayload);\n }\n\n return this.getIssue(id);\n }\n\n async createIssue(newIssue: NewIssue): Promise<Issue> {\n const team = newIssue.team ?? this.defaultTeam;\n\n if (!team) {\n throw new Error('Team is required to create an issue');\n }\n\n // Get team ID from key\n const teams = await this.client.teams({\n filter: { key: { eq: team } },\n });\n\n if (teams.nodes.length === 0) {\n throw new Error(`Team not found: ${team}`);\n }\n\n const teamId = teams.nodes[0].id;\n\n const result = await this.client.createIssue({\n teamId,\n title: newIssue.title,\n description: newIssue.description,\n priority: newIssue.priority,\n dueDate: newIssue.dueDate,\n });\n\n const created = await result.issue;\n if (!created) {\n throw new Error('Failed to create issue');\n }\n\n return this.normalizeIssue(created);\n }\n\n async getComments(issueId: string): Promise<Comment[]> {\n const issue = await this.client.issue(issueId);\n const comments = await issue.comments();\n\n return comments.nodes.map((c) => ({\n id: c.id,\n issueId,\n body: c.body,\n author: c.user?.then((u) => u?.name ?? 'Unknown') as unknown as string, // Simplified\n createdAt: c.createdAt.toISOString(),\n updatedAt: c.updatedAt.toISOString(),\n }));\n }\n\n async addComment(issueId: string, body: string): Promise<Comment> {\n const result = await this.client.createComment({\n issueId,\n body,\n });\n\n const comment = await result.comment;\n if (!comment) {\n throw new Error('Failed to create comment');\n }\n\n return {\n id: comment.id,\n issueId,\n body: comment.body,\n author: 'Panopticon', // Simplified\n createdAt: comment.createdAt.toISOString(),\n updatedAt: comment.updatedAt.toISOString(),\n };\n }\n\n async transitionIssue(id: string, state: IssueState): Promise<void> {\n const issue = await this.getIssue(id);\n\n // Get workflow states for the issue's team\n const linearIssue = await this.client.issue(issue.id);\n const team = await linearIssue.team;\n if (!team) {\n throw new Error('Could not determine issue team');\n }\n\n const states = await team.states();\n const targetStateType = this.reverseMapState(state);\n\n // Find a state matching the target type\n const targetState = states.nodes.find((s) => s.type === targetStateType);\n if (!targetState) {\n throw new Error(`No state found matching type: ${targetStateType}`);\n }\n\n await this.client.updateIssue(issue.id, {\n stateId: targetState.id,\n });\n }\n\n async linkPR(issueId: string, prUrl: string): Promise<void> {\n const issue = await this.getIssue(issueId);\n\n await this.client.createAttachment({\n issueId: issue.id,\n title: 'Pull Request',\n url: prUrl,\n });\n }\n\n private async normalizeIssue(linearIssue: any): Promise<Issue> {\n const state = await linearIssue.state;\n const assignee = await linearIssue.assignee;\n const labels = await linearIssue.labels();\n\n // Handle dueDate - can be Date, string, or undefined\n let dueDate: string | undefined;\n if (linearIssue.dueDate) {\n dueDate = linearIssue.dueDate instanceof Date\n ? linearIssue.dueDate.toISOString()\n : String(linearIssue.dueDate);\n }\n\n return {\n id: linearIssue.id,\n ref: linearIssue.identifier,\n title: linearIssue.title,\n description: linearIssue.description ?? '',\n state: this.mapState(state?.type ?? 'backlog'),\n labels: labels?.nodes?.map((l: any) => l.name) ?? [],\n assignee: assignee?.name,\n url: linearIssue.url,\n tracker: 'linear',\n priority: linearIssue.priority,\n dueDate,\n createdAt: linearIssue.createdAt instanceof Date\n ? linearIssue.createdAt.toISOString()\n : String(linearIssue.createdAt),\n updatedAt: linearIssue.updatedAt instanceof Date\n ? linearIssue.updatedAt.toISOString()\n : String(linearIssue.updatedAt),\n };\n }\n\n private mapState(linearState: string): IssueState {\n return STATE_MAP[linearState] ?? 'open';\n }\n\n private reverseMapState(state: IssueState): string {\n switch (state) {\n case 'open':\n return 'unstarted';\n case 'in_progress':\n return 'started';\n case 'closed':\n return 'completed';\n default:\n return 'unstarted';\n }\n }\n}\n","/**\n * GitHub Issues Tracker Adapter\n *\n * Implements IssueTracker interface for GitHub Issues.\n */\n\nimport { Octokit } from '@octokit/rest';\nimport type {\n Issue,\n IssueFilters,\n IssueState,\n IssueTracker,\n IssueUpdate,\n NewIssue,\n Comment,\n TrackerType,\n} from './interface.js';\nimport { IssueNotFoundError, TrackerAuthError } from './interface.js';\n\nexport class GitHubTracker implements IssueTracker {\n readonly name: TrackerType = 'github';\n private octokit: Octokit;\n private owner: string;\n private repo: string;\n\n constructor(token: string, owner: string, repo: string) {\n if (!token) {\n throw new TrackerAuthError('github', 'Token is required');\n }\n if (!owner || !repo) {\n throw new Error('GitHub owner and repo are required');\n }\n\n this.octokit = new Octokit({ auth: token });\n this.owner = owner;\n this.repo = repo;\n }\n\n async listIssues(filters?: IssueFilters): Promise<Issue[]> {\n const state = this.mapStateToGitHub(filters?.state);\n\n const response = await this.octokit.issues.listForRepo({\n owner: this.owner,\n repo: this.repo,\n state: filters?.includeClosed ? 'all' : state,\n labels: filters?.labels?.join(',') || undefined,\n assignee: filters?.assignee || undefined,\n per_page: filters?.limit ?? 50,\n });\n\n // Filter out pull requests (GitHub API returns both)\n const issues = response.data.filter((item) => !item.pull_request);\n\n return issues.map((issue) => this.normalizeIssue(issue));\n }\n\n async getIssue(id: string): Promise<Issue> {\n try {\n // Parse the issue number from refs like \"#42\" or just \"42\"\n const issueNumber = parseInt(id.replace(/^#/, ''), 10);\n\n if (isNaN(issueNumber)) {\n throw new IssueNotFoundError(id, 'github');\n }\n\n const { data: issue } = await this.octokit.issues.get({\n owner: this.owner,\n repo: this.repo,\n issue_number: issueNumber,\n });\n\n return this.normalizeIssue(issue);\n } catch (error: any) {\n if (error?.status === 404) {\n throw new IssueNotFoundError(id, 'github');\n }\n throw error;\n }\n }\n\n async updateIssue(id: string, update: IssueUpdate): Promise<Issue> {\n const issueNumber = parseInt(id.replace(/^#/, ''), 10);\n\n const updatePayload: Record<string, unknown> = {};\n\n if (update.title !== undefined) {\n updatePayload.title = update.title;\n }\n if (update.description !== undefined) {\n updatePayload.body = update.description;\n }\n if (update.state !== undefined) {\n updatePayload.state = update.state === 'closed' ? 'closed' : 'open';\n }\n if (update.labels !== undefined) {\n updatePayload.labels = update.labels;\n }\n if (update.assignee !== undefined) {\n updatePayload.assignees = update.assignee ? [update.assignee] : [];\n }\n\n await this.octokit.issues.update({\n owner: this.owner,\n repo: this.repo,\n issue_number: issueNumber,\n ...updatePayload,\n });\n\n return this.getIssue(id);\n }\n\n async createIssue(newIssue: NewIssue): Promise<Issue> {\n const { data: issue } = await this.octokit.issues.create({\n owner: this.owner,\n repo: this.repo,\n title: newIssue.title,\n body: newIssue.description,\n labels: newIssue.labels,\n assignees: newIssue.assignee ? [newIssue.assignee] : undefined,\n });\n\n return this.normalizeIssue(issue);\n }\n\n async getComments(issueId: string): Promise<Comment[]> {\n const issueNumber = parseInt(issueId.replace(/^#/, ''), 10);\n\n const { data: comments } = await this.octokit.issues.listComments({\n owner: this.owner,\n repo: this.repo,\n issue_number: issueNumber,\n });\n\n return comments.map((c) => ({\n id: String(c.id),\n issueId,\n body: c.body ?? '',\n author: c.user?.login ?? 'Unknown',\n createdAt: c.created_at,\n updatedAt: c.updated_at,\n }));\n }\n\n async addComment(issueId: string, body: string): Promise<Comment> {\n const issueNumber = parseInt(issueId.replace(/^#/, ''), 10);\n\n const { data: comment } = await this.octokit.issues.createComment({\n owner: this.owner,\n repo: this.repo,\n issue_number: issueNumber,\n body,\n });\n\n return {\n id: String(comment.id),\n issueId,\n body: comment.body ?? '',\n author: comment.user?.login ?? 'Unknown',\n createdAt: comment.created_at,\n updatedAt: comment.updated_at,\n };\n }\n\n async transitionIssue(id: string, state: IssueState): Promise<void> {\n await this.updateIssue(id, { state });\n }\n\n async linkPR(issueId: string, prUrl: string): Promise<void> {\n // GitHub auto-links PRs that mention issues\n // Add a comment with the PR link\n await this.addComment(\n issueId,\n `Linked Pull Request: ${prUrl}`\n );\n }\n\n private normalizeIssue(ghIssue: any): Issue {\n return {\n id: String(ghIssue.id),\n ref: `#${ghIssue.number}`,\n title: ghIssue.title,\n description: ghIssue.body ?? '',\n state: this.mapStateFromGitHub(ghIssue.state),\n labels: ghIssue.labels.map((l: any) =>\n typeof l === 'string' ? l : l.name\n ),\n assignee: ghIssue.assignee?.login,\n url: ghIssue.html_url,\n tracker: 'github',\n priority: undefined, // GitHub doesn't have priority\n dueDate: undefined, // GitHub doesn't have due dates on issues\n createdAt: ghIssue.created_at,\n updatedAt: ghIssue.updated_at,\n };\n }\n\n private mapStateFromGitHub(ghState: string): IssueState {\n // GitHub only has open and closed states\n // No way to distinguish \"in_progress\" without custom labels\n return ghState === 'closed' ? 'closed' : 'open';\n }\n\n private mapStateToGitHub(\n state?: IssueState\n ): 'open' | 'closed' | 'all' {\n if (!state) return 'open';\n if (state === 'closed') return 'closed';\n return 'open'; // Both 'open' and 'in_progress' map to 'open'\n }\n}\n","/**\n * GitLab Issues Tracker Adapter (Stub)\n *\n * Placeholder implementation for GitLab Issues support.\n * Full implementation will use @gitbeaker/rest.\n */\n\nimport type {\n Issue,\n IssueFilters,\n IssueState,\n IssueTracker,\n IssueUpdate,\n NewIssue,\n Comment,\n TrackerType,\n} from './interface.js';\nimport { NotImplementedError } from './interface.js';\n\nexport class GitLabTracker implements IssueTracker {\n readonly name: TrackerType = 'gitlab';\n\n constructor(\n private token: string,\n private projectId: string\n ) {\n // Stub - will initialize @gitbeaker client when implemented\n }\n\n async listIssues(_filters?: IssueFilters): Promise<Issue[]> {\n throw new NotImplementedError(\n 'GitLab tracker is not yet implemented. Coming soon!'\n );\n }\n\n async getIssue(_id: string): Promise<Issue> {\n throw new NotImplementedError(\n 'GitLab tracker is not yet implemented. Coming soon!'\n );\n }\n\n async updateIssue(_id: string, _update: IssueUpdate): Promise<Issue> {\n throw new NotImplementedError(\n 'GitLab tracker is not yet implemented. Coming soon!'\n );\n }\n\n async createIssue(_issue: NewIssue): Promise<Issue> {\n throw new NotImplementedError(\n 'GitLab tracker is not yet implemented. Coming soon!'\n );\n }\n\n async getComments(_issueId: string): Promise<Comment[]> {\n throw new NotImplementedError(\n 'GitLab tracker is not yet implemented. Coming soon!'\n );\n }\n\n async addComment(_issueId: string, _body: string): Promise<Comment> {\n throw new NotImplementedError(\n 'GitLab tracker is not yet implemented. Coming soon!'\n );\n }\n\n async transitionIssue(_id: string, _state: IssueState): Promise<void> {\n throw new NotImplementedError(\n 'GitLab tracker is not yet implemented. Coming soon!'\n );\n }\n\n async linkPR(_issueId: string, _prUrl: string): Promise<void> {\n throw new NotImplementedError(\n 'GitLab tracker is not yet implemented. Coming soon!'\n );\n }\n}\n","/**\n * Tracker Factory\n *\n * Creates appropriate tracker instances based on configuration.\n */\n\nimport type { IssueTracker, TrackerType } from './interface.js';\nimport { TrackerAuthError } from './interface.js';\nimport { LinearTracker } from './linear.js';\nimport { GitHubTracker } from './github.js';\nimport { GitLabTracker } from './gitlab.js';\nimport { RallyTracker } from './rally.js';\nimport type { TrackersConfig } from '../config.js';\nimport { loadConfig as loadYamlConfig } from '../config-yaml.js';\n\n// Configuration for a single tracker\nexport interface TrackerConfig {\n type: TrackerType;\n\n // Linear-specific\n apiKeyEnv?: string;\n team?: string;\n\n // GitHub-specific\n tokenEnv?: string;\n owner?: string;\n repo?: string;\n\n // GitLab-specific\n projectId?: string;\n\n // Rally-specific\n server?: string;\n workspace?: string;\n project?: string;\n}\n\n// Multi-tracker configuration (re-exported from config.ts)\n// Note: Use TrackersConfig from config.ts for full type with nested configs\n\n/**\n * Get tracker API key from config.yaml (Settings page).\n * This is checked FIRST — env vars are the fallback, not the other way around.\n */\nfunction getTrackerKeyFromConfig(trackerType: TrackerType): string | undefined {\n try {\n const yamlConfig = loadYamlConfig();\n return yamlConfig.trackerKeys[trackerType];\n } catch {\n return undefined;\n }\n}\n\n/**\n * Create a tracker instance from configuration.\n * Priority: config.yaml (Settings) > environment variable > custom env var name\n */\nexport function createTracker(config: TrackerConfig): IssueTracker {\n switch (config.type) {\n case 'linear': {\n const configKey = getTrackerKeyFromConfig('linear');\n const envKey = config.apiKeyEnv\n ? process.env[config.apiKeyEnv]\n : process.env.LINEAR_API_KEY;\n const apiKey = configKey || envKey;\n\n if (!apiKey) {\n throw new TrackerAuthError(\n 'linear',\n `API key not found. Configure in Settings or set ${config.apiKeyEnv ?? 'LINEAR_API_KEY'} environment variable.`\n );\n }\n\n return new LinearTracker(apiKey, { team: config.team });\n }\n\n case 'github': {\n const configKey = getTrackerKeyFromConfig('github');\n const envToken = config.tokenEnv\n ? process.env[config.tokenEnv]\n : process.env.GITHUB_TOKEN;\n const token = configKey || envToken;\n\n if (!token) {\n throw new TrackerAuthError(\n 'github',\n `Token not found. Configure in Settings or set ${config.tokenEnv ?? 'GITHUB_TOKEN'} environment variable.`\n );\n }\n\n if (!config.owner || !config.repo) {\n throw new Error(\n 'GitHub tracker requires owner and repo configuration'\n );\n }\n\n return new GitHubTracker(token, config.owner, config.repo);\n }\n\n case 'gitlab': {\n const configKey = getTrackerKeyFromConfig('gitlab');\n const envToken = config.tokenEnv\n ? process.env[config.tokenEnv]\n : process.env.GITLAB_TOKEN;\n const token = configKey || envToken;\n\n if (!token) {\n throw new TrackerAuthError(\n 'gitlab',\n `Token not found. Configure in Settings or set ${config.tokenEnv ?? 'GITLAB_TOKEN'} environment variable.`\n );\n }\n\n if (!config.projectId) {\n throw new Error('GitLab tracker requires projectId configuration');\n }\n\n return new GitLabTracker(token, config.projectId);\n }\n\n case 'rally': {\n const configKey = getTrackerKeyFromConfig('rally');\n const envKey = config.apiKeyEnv\n ? process.env[config.apiKeyEnv]\n : process.env.RALLY_API_KEY;\n const apiKey = configKey || envKey;\n\n if (!apiKey) {\n throw new TrackerAuthError(\n 'rally',\n `API key not found. Configure in Settings or set ${config.apiKeyEnv ?? 'RALLY_API_KEY'} environment variable.`\n );\n }\n\n return new RallyTracker({\n apiKey,\n server: config.server,\n workspace: config.workspace,\n project: config.project,\n });\n }\n\n default:\n throw new Error(`Unknown tracker type: ${config.type}`);\n }\n}\n\n/**\n * Create tracker from trackers configuration section\n */\nexport function createTrackerFromConfig(\n trackersConfig: TrackersConfig,\n trackerType: TrackerType\n): IssueTracker {\n const config = trackersConfig[trackerType];\n\n if (!config) {\n throw new Error(\n `No configuration found for tracker: ${trackerType}. Add [trackers.${trackerType}] to config.`\n );\n }\n\n return createTracker({ ...config, type: trackerType });\n}\n\n/**\n * Get the primary tracker from configuration\n */\nexport function getPrimaryTracker(trackersConfig: TrackersConfig): IssueTracker {\n return createTrackerFromConfig(trackersConfig, trackersConfig.primary);\n}\n\n/**\n * Get the secondary tracker from configuration (if configured)\n */\nexport function getSecondaryTracker(\n trackersConfig: TrackersConfig\n): IssueTracker | null {\n if (!trackersConfig.secondary) {\n return null;\n }\n return createTrackerFromConfig(trackersConfig, trackersConfig.secondary);\n}\n\n/**\n * Get all configured trackers\n */\nexport function getAllTrackers(trackersConfig: TrackersConfig): IssueTracker[] {\n const trackers: IssueTracker[] = [getPrimaryTracker(trackersConfig)];\n\n const secondary = getSecondaryTracker(trackersConfig);\n if (secondary) {\n trackers.push(secondary);\n }\n\n return trackers;\n}\n","/**\n * Rally Tracker Adapter\n *\n * Implements IssueTracker interface for Broadcom Rally (formerly CA Agile Central).\n * Supports all Rally work item types: User Stories, Defects, Tasks, and Features.\n */\n\nimport { RallyRestApi } from './rally-api.js';\nimport type {\n Issue,\n IssueFilters,\n IssueState,\n IssueTracker,\n IssueUpdate,\n NewIssue,\n Comment,\n TrackerType,\n} from './interface.js';\nimport { IssueNotFoundError, TrackerAuthError, NotImplementedError } from './interface.js';\n\n// Map Rally ScheduleState to normalized IssueState\nconst STATE_MAP: Record<string, IssueState> = {\n Defined: 'open',\n 'In-Progress': 'in_progress',\n Completed: 'closed',\n Accepted: 'closed',\n};\n\n// Rally artifact types we support\ntype RallyArtifactType = 'HierarchicalRequirement' | 'Defect' | 'Task' | 'PortfolioItem/Feature';\n\n// Rally priority strings to numbers\nconst PRIORITY_MAP: Record<string, number> = {\n 'Resolve Immediately': 0,\n High: 1,\n Normal: 2,\n Low: 3,\n};\n\n// Reverse priority mapping\nconst REVERSE_PRIORITY_MAP: Record<number, string> = {\n 0: 'Resolve Immediately',\n 1: 'High',\n 2: 'Normal',\n 3: 'Low',\n 4: 'Low',\n};\n\nexport interface RallyConfig {\n apiKey: string;\n server?: string; // Default: rally1.rallydev.com\n workspace?: string; // Rally workspace OID (e.g., \"/workspace/12345\")\n project?: string; // Rally project OID (e.g., \"/project/67890\")\n}\n\nexport class RallyTracker implements IssueTracker {\n readonly name: TrackerType = 'rally' as TrackerType;\n private restApi: RallyRestApi;\n private workspace?: string;\n private project?: string;\n\n constructor(config: RallyConfig) {\n if (!config.apiKey) {\n throw new TrackerAuthError('rally' as TrackerType, 'API key is required');\n }\n\n this.restApi = new RallyRestApi({\n apiKey: config.apiKey,\n server: config.server || 'https://rally1.rallydev.com',\n requestOptions: {\n headers: {\n 'X-RallyIntegrationType': 'Panopticon',\n 'X-RallyIntegrationName': 'Panopticon CLI',\n 'X-RallyIntegrationVendor': 'Mind Your Now',\n 'X-RallyIntegrationVersion': '0.2.0',\n },\n },\n });\n\n this.workspace = config.workspace;\n this.project = config.project;\n }\n\n async listIssues(filters?: IssueFilters): Promise<Issue[]> {\n const queryString = this.buildQueryString(filters);\n\n if (process.env.DEBUG?.includes('rally')) {\n console.debug('[Rally] Query filters:', JSON.stringify(filters));\n console.debug('[Rally] Generated query:', queryString);\n }\n\n const query: any = {\n type: 'artifact', // Query all artifact types\n fetch: [\n 'FormattedID',\n 'Name',\n 'Description',\n 'ScheduleState',\n 'State', // For Defects\n 'Tags',\n 'Owner',\n 'Priority',\n 'DueDate',\n 'CreationDate',\n 'LastUpdateDate',\n 'Parent',\n '_type',\n ],\n limit: filters?.limit ?? 50,\n query: queryString,\n };\n\n if (this.workspace) {\n query.workspace = this.workspace;\n }\n if (this.project) {\n query.project = this.project;\n query.projectScopeDown = true;\n }\n\n try {\n const result = await this.queryRally(query);\n return result.Results.map((artifact: any) => this.normalizeIssue(artifact));\n } catch (error: any) {\n if (error.message?.includes('Unauthorized') || error.message?.includes('401')) {\n throw new TrackerAuthError('rally' as TrackerType, 'Invalid API key or insufficient permissions');\n }\n throw error;\n }\n }\n\n async getIssue(id: string): Promise<Issue> {\n try {\n // Rally FormattedIDs look like: US123, DE456, TA789, F012\n const query: any = {\n type: 'artifact',\n fetch: [\n 'FormattedID',\n 'Name',\n 'Description',\n 'ScheduleState',\n 'State',\n 'Tags',\n 'Owner',\n 'Priority',\n 'DueDate',\n 'CreationDate',\n 'LastUpdateDate',\n 'Parent',\n '_type',\n ],\n query: `(FormattedID = \"${id}\")`,\n };\n\n if (this.workspace) {\n query.workspace = this.workspace;\n }\n\n const result = await this.queryRally(query);\n\n if (!result.Results || result.Results.length === 0) {\n throw new IssueNotFoundError(id, 'rally' as TrackerType);\n }\n\n return this.normalizeIssue(result.Results[0]);\n } catch (error: any) {\n if (error instanceof IssueNotFoundError) throw error;\n throw new IssueNotFoundError(id, 'rally' as TrackerType);\n }\n }\n\n async updateIssue(id: string, update: IssueUpdate): Promise<Issue> {\n const issue = await this.getIssue(id);\n\n // Get the Rally object reference\n const query: any = {\n type: 'artifact',\n fetch: ['ObjectID', '_ref', '_type'],\n query: `(FormattedID = \"${id}\")`,\n };\n\n if (this.workspace) {\n query.workspace = this.workspace;\n }\n\n const result = await this.queryRally(query);\n if (!result.Results || result.Results.length === 0) {\n throw new IssueNotFoundError(id, 'rally' as TrackerType);\n }\n\n const artifact = result.Results[0];\n const updatePayload: Record<string, unknown> = {};\n\n if (update.title !== undefined) {\n updatePayload.Name = update.title;\n }\n if (update.description !== undefined) {\n updatePayload.Description = update.description;\n }\n if (update.state !== undefined) {\n const rallyState = this.reverseMapState(update.state);\n // Use ScheduleState for User Stories and Tasks, State for Defects\n if (artifact._type === 'Defect') {\n updatePayload.State = rallyState;\n } else {\n updatePayload.ScheduleState = rallyState;\n }\n }\n if (update.priority !== undefined) {\n updatePayload.Priority = REVERSE_PRIORITY_MAP[update.priority] || 'Normal';\n }\n if (update.dueDate !== undefined) {\n updatePayload.DueDate = update.dueDate;\n }\n\n if (Object.keys(updatePayload).length > 0) {\n await this.updateRally(artifact._type.toLowerCase(), artifact._ref, updatePayload);\n }\n\n return this.getIssue(id);\n }\n\n async createIssue(newIssue: NewIssue): Promise<Issue> {\n if (!this.project && !newIssue.team) {\n throw new Error('Project is required to create an issue. Set it in config or provide team field.');\n }\n\n const project = newIssue.team || this.project;\n\n // Default to HierarchicalRequirement (User Story) for new issues\n const createPayload: Record<string, unknown> = {\n Name: newIssue.title,\n Description: newIssue.description || '',\n Project: project,\n };\n\n if (newIssue.priority !== undefined) {\n createPayload.Priority = REVERSE_PRIORITY_MAP[newIssue.priority] || 'Normal';\n }\n if (newIssue.dueDate) {\n createPayload.DueDate = newIssue.dueDate;\n }\n if (this.workspace) {\n createPayload.Workspace = this.workspace;\n }\n\n const result = await this.createRally('hierarchicalrequirement', createPayload);\n\n // Fetch the created issue to return normalized format\n return this.getIssue(result.Object.FormattedID);\n }\n\n async getComments(issueId: string): Promise<Comment[]> {\n const issue = await this.getIssue(issueId);\n\n // Get the Rally object to find its Discussion\n const query: any = {\n type: 'artifact',\n fetch: ['ObjectID', '_ref', 'Discussion'],\n query: `(FormattedID = \"${issueId}\")`,\n };\n\n if (this.workspace) {\n query.workspace = this.workspace;\n }\n\n const result = await this.queryRally(query);\n if (!result.Results || result.Results.length === 0) {\n return [];\n }\n\n const artifact = result.Results[0];\n if (!artifact.Discussion) {\n return [];\n }\n\n // Query ConversationPosts for this Discussion\n const postsQuery: any = {\n type: 'conversationpost',\n fetch: ['ObjectID', 'Text', 'User', 'CreationDate', 'PostNumber'],\n query: `(Discussion = \"${artifact.Discussion._ref}\")`,\n order: 'PostNumber',\n };\n\n const postsResult = await this.queryRally(postsQuery);\n\n return (postsResult.Results || []).map((post: any) => ({\n id: post.ObjectID,\n issueId,\n body: post.Text || '',\n author: post.User?._refObjectName || 'Unknown',\n createdAt: post.CreationDate,\n updatedAt: post.CreationDate, // Rally doesn't track comment updates separately\n }));\n }\n\n async addComment(issueId: string, body: string): Promise<Comment> {\n // Get the Rally object to find its Discussion\n const query: any = {\n type: 'artifact',\n fetch: ['ObjectID', '_ref', 'Discussion'],\n query: `(FormattedID = \"${issueId}\")`,\n };\n\n if (this.workspace) {\n query.workspace = this.workspace;\n }\n\n const result = await this.queryRally(query);\n if (!result.Results || result.Results.length === 0) {\n throw new IssueNotFoundError(issueId, 'rally' as TrackerType);\n }\n\n const artifact = result.Results[0];\n\n // If no Discussion exists, create one\n let discussionRef = artifact.Discussion?._ref;\n if (!discussionRef) {\n const discussionResult = await this.createRally('conversationpost', {\n Artifact: artifact._ref,\n Text: body,\n });\n\n return {\n id: discussionResult.Object.ObjectID,\n issueId,\n body,\n author: 'Panopticon',\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n };\n }\n\n // Add a post to existing Discussion\n const postResult = await this.createRally('conversationpost', {\n Artifact: artifact._ref,\n Text: body,\n });\n\n return {\n id: postResult.Object.ObjectID,\n issueId,\n body,\n author: 'Panopticon',\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n };\n }\n\n async transitionIssue(id: string, state: IssueState): Promise<void> {\n await this.updateIssue(id, { state });\n }\n\n async linkPR(issueId: string, prUrl: string): Promise<void> {\n // Add a comment with the PR link\n await this.addComment(issueId, `Linked Pull Request: ${prUrl}`);\n }\n\n // Private helper methods\n\n /**\n * Build a Rally WSAPI query string from issue filters.\n *\n * Rally WSAPI v2.0 requires the entire compound query expression to be wrapped\n * in outer parentheses when multiple conditions are joined with AND/OR.\n * Without the outer parens, the WSAPI parser fails with:\n * \"Could not parse: Error parsing expression -- expected \")\" but saw \"AND\" instead.\"\n *\n * Valid: (((ScheduleState != \"Completed\") AND (State != \"Closed\")) AND (Owner.Name contains \"John\"))\n * Invalid: ((ScheduleState != \"Completed\") AND (State != \"Closed\")) AND (Owner.Name contains \"John\")\n */\n private buildQueryString(filters?: IssueFilters): string {\n const conditions: string[] = [];\n\n if (filters?.state && !filters.includeClosed) {\n const rallyState = this.reverseMapState(filters.state);\n conditions.push(`((ScheduleState = \"${rallyState}\") OR (State = \"${rallyState}\"))`);\n }\n\n if (!filters?.includeClosed) {\n // Exclude completed/accepted items by default\n // Rally WSAPI only supports binary AND/OR — nest into pairs\n conditions.push('(((ScheduleState != \"Completed\") AND (ScheduleState != \"Accepted\")) AND (State != \"Closed\"))');\n }\n\n if (filters?.assignee) {\n conditions.push(`(Owner.Name contains \"${filters.assignee}\")`);\n }\n\n if (filters?.labels && filters.labels.length > 0) {\n const labelConditions = filters.labels.map(\n (label) => `(Tags.Name contains \"${label}\")`\n );\n // Rally WSAPI only supports binary AND — nest into pairs\n const labelExpr = labelConditions.reduce((acc, cond) => acc ? `(${acc} AND ${cond})` : cond, '');\n conditions.push(labelExpr);\n }\n\n if (filters?.query) {\n conditions.push(`((Name contains \"${filters.query}\") OR (Description contains \"${filters.query}\"))`);\n }\n\n // Rally WSAPI only supports binary (expr AND expr) — reduce into nested pairs\n return conditions.reduce((acc, cond) => acc ? `(${acc} AND ${cond})` : cond, '');\n }\n\n private normalizeIssue(rallyArtifact: any): Issue {\n // Determine state from ScheduleState (User Stories, Tasks) or State (Defects)\n const stateValue = rallyArtifact.ScheduleState || rallyArtifact.State || 'Defined';\n const state = this.mapState(stateValue);\n\n // Extract tags\n const labels: string[] = [];\n if (rallyArtifact.Tags && rallyArtifact.Tags._tagsNameArray) {\n labels.push(...rallyArtifact.Tags._tagsNameArray);\n }\n\n // Map priority\n const priority = rallyArtifact.Priority\n ? PRIORITY_MAP[rallyArtifact.Priority] ?? 2\n : undefined;\n\n // Build URL - Rally's web UI uses FormattedID\n const baseUrl = this.restApi.server.replace('/slm/webservice/', '');\n const url = `${baseUrl}/#/detail/${rallyArtifact._type.toLowerCase()}/${rallyArtifact.ObjectID}`;\n\n return {\n id: rallyArtifact.ObjectID,\n ref: rallyArtifact.FormattedID,\n title: rallyArtifact.Name || '',\n description: rallyArtifact.Description || '',\n state,\n labels,\n assignee: rallyArtifact.Owner?._refObjectName,\n url,\n tracker: 'rally' as TrackerType,\n priority,\n dueDate: rallyArtifact.DueDate,\n createdAt: rallyArtifact.CreationDate,\n updatedAt: rallyArtifact.LastUpdateDate,\n };\n }\n\n private mapState(rallyState: string): IssueState {\n return STATE_MAP[rallyState] ?? 'open';\n }\n\n private reverseMapState(state: IssueState): string {\n switch (state) {\n case 'open':\n return 'Defined';\n case 'in_progress':\n return 'In-Progress';\n case 'closed':\n return 'Completed';\n default:\n return 'Defined';\n }\n }\n\n // Rally API wrapper methods\n private async queryRally(queryConfig: any): Promise<any> {\n const result = await this.restApi.query(queryConfig);\n // Extract Results from WSAPI response format\n return {\n Results: result.QueryResult.Results,\n TotalResultCount: result.QueryResult.TotalResultCount,\n };\n }\n\n private async createRally(type: string, data: any): Promise<any> {\n const result = await this.restApi.create({\n type,\n data,\n fetch: ['FormattedID', 'ObjectID', '_ref'],\n });\n // Extract Object from WSAPI response format\n return {\n Object: result.CreateResult.Object,\n };\n }\n\n private async updateRally(type: string, ref: string, data: any): Promise<any> {\n const result = await this.restApi.update({\n type,\n ref,\n data,\n fetch: ['FormattedID', 'ObjectID'],\n });\n // Extract Object from WSAPI response format\n return {\n Object: result.OperationResult.Object,\n };\n }\n}\n","/**\n * Rally WSAPI REST Client\n *\n * Thin wrapper around native fetch for Rally Web Services API v2.0.\n * Provides typed methods for query, create, and update operations.\n */\n\nexport interface RallyQueryConfig {\n type: string;\n fetch?: string[];\n query?: string;\n limit?: number;\n workspace?: string;\n project?: string;\n projectScopeDown?: boolean;\n order?: string;\n}\n\nexport interface RallyQueryResult {\n QueryResult: {\n Results: any[];\n TotalResultCount: number;\n Errors: string[];\n Warnings: string[];\n };\n}\n\nexport interface RallyCreateConfig {\n type: string;\n data: any;\n fetch?: string[];\n}\n\nexport interface RallyCreateResult {\n CreateResult: {\n Object: any;\n Errors: string[];\n Warnings: string[];\n };\n}\n\nexport interface RallyUpdateConfig {\n type: string;\n ref: string;\n data: any;\n fetch?: string[];\n}\n\nexport interface RallyUpdateResult {\n OperationResult: {\n Object: any;\n Errors: string[];\n Warnings: string[];\n };\n}\n\nexport interface RallyApiConfig {\n apiKey: string;\n server?: string;\n requestOptions?: {\n headers?: Record<string, string>;\n };\n}\n\nexport class RallyRestApi {\n private apiKey: string;\n public server: string;\n private customHeaders: Record<string, string>;\n\n constructor(config: RallyApiConfig) {\n this.apiKey = config.apiKey;\n this.server = config.server || 'https://rally1.rallydev.com';\n this.customHeaders = config.requestOptions?.headers || {};\n }\n\n /**\n * Query Rally artifacts\n */\n async query(config: RallyQueryConfig): Promise<RallyQueryResult> {\n const params = new URLSearchParams();\n\n if (config.query) {\n params.set('query', config.query);\n }\n\n if (config.fetch && config.fetch.length > 0) {\n params.set('fetch', config.fetch.join(','));\n }\n\n if (config.limit !== undefined) {\n params.set('pagesize', String(config.limit));\n }\n\n if (config.workspace) {\n params.set('workspace', config.workspace);\n }\n\n if (config.project) {\n params.set('project', config.project);\n if (config.projectScopeDown) {\n params.set('projectScopeDown', 'true');\n }\n }\n\n if (config.order) {\n params.set('order', config.order);\n }\n\n const url = `${this.server}/slm/webservice/v2.0/${config.type}?${params.toString()}`;\n\n const response = await fetch(url, {\n method: 'GET',\n headers: {\n 'ZSESSIONID': this.apiKey,\n 'Content-Type': 'application/json',\n ...this.customHeaders,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error('Unauthorized: Invalid API key or insufficient permissions');\n }\n throw new Error(`Rally API query failed: ${response.status} ${response.statusText}`);\n }\n\n const result = await response.json() as RallyQueryResult;\n\n if (result.QueryResult.Errors && result.QueryResult.Errors.length > 0) {\n const errorDetail = result.QueryResult.Errors.join(', ');\n const queryDetail = config.query ? ` (Query: ${config.query})` : '';\n if (process.env.DEBUG?.includes('rally')) {\n console.error('[Rally WSAPI] Query failed:', { query: config.query, errors: result.QueryResult.Errors });\n }\n throw new Error(`Rally API query failed: ${errorDetail}${queryDetail}`);\n }\n\n return result;\n }\n\n /**\n * Create a Rally object\n */\n async create(config: RallyCreateConfig): Promise<RallyCreateResult> {\n const url = `${this.server}/slm/webservice/v2.0/${config.type}/create`;\n\n const body: any = {\n [config.type]: config.data,\n };\n\n const params = new URLSearchParams();\n if (config.fetch && config.fetch.length > 0) {\n params.set('fetch', config.fetch.join(','));\n }\n\n const finalUrl = params.toString() ? `${url}?${params.toString()}` : url;\n\n const response = await fetch(finalUrl, {\n method: 'POST',\n headers: {\n 'ZSESSIONID': this.apiKey,\n 'Content-Type': 'application/json',\n ...this.customHeaders,\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n throw new Error(`Rally API create failed: ${response.status} ${response.statusText}`);\n }\n\n const result = await response.json() as RallyCreateResult;\n\n if (result.CreateResult.Errors && result.CreateResult.Errors.length > 0) {\n throw new Error(`Rally API create failed: ${result.CreateResult.Errors.join(', ')}`);\n }\n\n return result;\n }\n\n /**\n * Update a Rally object\n */\n async update(config: RallyUpdateConfig): Promise<RallyUpdateResult> {\n // Extract ObjectID from ref (e.g., \"/hierarchicalrequirement/12345\" -> \"12345\")\n const objectId = config.ref.split('/').pop();\n const url = `${this.server}/slm/webservice/v2.0/${config.type}/${objectId}`;\n\n const body: any = {\n [config.type]: config.data,\n };\n\n const params = new URLSearchParams();\n if (config.fetch && config.fetch.length > 0) {\n params.set('fetch', config.fetch.join(','));\n }\n\n const finalUrl = params.toString() ? `${url}?${params.toString()}` : url;\n\n const response = await fetch(finalUrl, {\n method: 'POST',\n headers: {\n 'ZSESSIONID': this.apiKey,\n 'Content-Type': 'application/json',\n ...this.customHeaders,\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n throw new Error(`Rally API update failed: ${response.status} ${response.statusText}`);\n }\n\n const result = await response.json() as RallyUpdateResult;\n\n if (result.OperationResult.Errors && result.OperationResult.Errors.length > 0) {\n throw new Error(`Rally API update failed: ${result.OperationResult.Errors.join(', ')}`);\n }\n\n return result;\n }\n}\n","/**\n * Cross-Tracker Linking\n *\n * Manages links between issues in different trackers.\n * Links are stored in a local JSON file for persistence.\n */\n\nimport { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\nimport type { TrackerType } from './interface.js';\n\n// Link direction types\nexport type LinkDirection = 'blocks' | 'blocked_by' | 'related' | 'duplicate_of';\n\n// A single link between two issues\nexport interface TrackerLink {\n sourceIssueRef: string; // e.g., \"MIN-630\"\n sourceTracker: TrackerType;\n targetIssueRef: string; // e.g., \"#42\"\n targetTracker: TrackerType;\n direction: LinkDirection;\n createdAt: string; // ISO timestamp\n}\n\n// Storage format\ninterface LinkStore {\n version: 1;\n links: TrackerLink[];\n}\n\n/**\n * Parse an issue reference to extract tracker and ID\n * Examples:\n * \"#42\" -> { tracker: \"github\", ref: \"#42\" }\n * \"github#42\" -> { tracker: \"github\", ref: \"#42\" }\n * \"MIN-630\" -> { tracker: \"linear\", ref: \"MIN-630\" }\n * \"gitlab#15\" -> { tracker: \"gitlab\", ref: \"#15\" }\n */\nexport function parseIssueRef(ref: string): { tracker: TrackerType; ref: string } | null {\n // Explicit tracker prefix\n if (ref.startsWith('github#')) {\n return { tracker: 'github', ref: `#${ref.slice(7)}` };\n }\n if (ref.startsWith('gitlab#')) {\n return { tracker: 'gitlab', ref: `#${ref.slice(7)}` };\n }\n if (ref.startsWith('linear:')) {\n return { tracker: 'linear', ref: ref.slice(7) };\n }\n\n // GitHub-style refs (#number)\n if (/^#\\d+$/.test(ref)) {\n return { tracker: 'github', ref };\n }\n\n // Linear-style refs (XXX-123)\n if (/^[A-Z]+-\\d+$/i.test(ref)) {\n return { tracker: 'linear', ref: ref.toUpperCase() };\n }\n\n return null;\n}\n\n/**\n * Format an issue ref with tracker prefix for display\n */\nexport function formatIssueRef(ref: string, tracker: TrackerType): string {\n if (tracker === 'github') {\n return ref.startsWith('#') ? `github${ref}` : `github#${ref}`;\n }\n if (tracker === 'gitlab') {\n return ref.startsWith('#') ? `gitlab${ref}` : `gitlab#${ref}`;\n }\n return ref; // Linear refs are already unique\n}\n\n/**\n * Link Manager for cross-tracker issue linking\n */\nexport class LinkManager {\n private storePath: string;\n private store: LinkStore;\n\n constructor(storePath?: string) {\n this.storePath = storePath ?? join(homedir(), '.panopticon', 'links.json');\n this.store = this.load();\n }\n\n private load(): LinkStore {\n if (existsSync(this.storePath)) {\n try {\n const data = JSON.parse(readFileSync(this.storePath, 'utf-8'));\n if (data.version === 1) {\n return data;\n }\n } catch {\n // Fall through to default\n }\n }\n return { version: 1, links: [] };\n }\n\n private save(): void {\n const dir = join(this.storePath, '..');\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(this.storePath, JSON.stringify(this.store, null, 2));\n }\n\n /**\n * Add a link between two issues\n */\n addLink(\n source: { ref: string; tracker: TrackerType },\n target: { ref: string; tracker: TrackerType },\n direction: LinkDirection = 'related'\n ): TrackerLink {\n // Check if link already exists\n const existing = this.store.links.find(\n (l) =>\n l.sourceIssueRef === source.ref &&\n l.sourceTracker === source.tracker &&\n l.targetIssueRef === target.ref &&\n l.targetTracker === target.tracker\n );\n\n if (existing) {\n // Update direction if different\n if (existing.direction !== direction) {\n existing.direction = direction;\n this.save();\n }\n return existing;\n }\n\n const link: TrackerLink = {\n sourceIssueRef: source.ref,\n sourceTracker: source.tracker,\n targetIssueRef: target.ref,\n targetTracker: target.tracker,\n direction,\n createdAt: new Date().toISOString(),\n };\n\n this.store.links.push(link);\n this.save();\n return link;\n }\n\n /**\n * Remove a link between two issues\n */\n removeLink(\n source: { ref: string; tracker: TrackerType },\n target: { ref: string; tracker: TrackerType }\n ): boolean {\n const index = this.store.links.findIndex(\n (l) =>\n l.sourceIssueRef === source.ref &&\n l.sourceTracker === source.tracker &&\n l.targetIssueRef === target.ref &&\n l.targetTracker === target.tracker\n );\n\n if (index >= 0) {\n this.store.links.splice(index, 1);\n this.save();\n return true;\n }\n return false;\n }\n\n /**\n * Get all issues linked to a given issue\n */\n getLinkedIssues(ref: string, tracker: TrackerType): TrackerLink[] {\n return this.store.links.filter(\n (l) =>\n (l.sourceIssueRef === ref && l.sourceTracker === tracker) ||\n (l.targetIssueRef === ref && l.targetTracker === tracker)\n );\n }\n\n /**\n * Get all links (for debugging/admin)\n */\n getAllLinks(): TrackerLink[] {\n return [...this.store.links];\n }\n\n /**\n * Find linked issue in another tracker\n */\n findLinkedIssue(\n ref: string,\n sourceTracker: TrackerType,\n targetTracker: TrackerType\n ): string | null {\n // Check as source\n const asSource = this.store.links.find(\n (l) =>\n l.sourceIssueRef === ref &&\n l.sourceTracker === sourceTracker &&\n l.targetTracker === targetTracker\n );\n if (asSource) return asSource.targetIssueRef;\n\n // Check as target\n const asTarget = this.store.links.find(\n (l) =>\n l.targetIssueRef === ref &&\n l.targetTracker === sourceTracker &&\n l.sourceTracker === targetTracker\n );\n if (asTarget) return asTarget.sourceIssueRef;\n\n return null;\n }\n\n /**\n * Clear all links (for testing)\n */\n clear(): void {\n this.store.links = [];\n this.save();\n }\n}\n\n// Singleton instance\nlet _linkManager: LinkManager | null = null;\n\nexport function getLinkManager(): LinkManager {\n if (!_linkManager) {\n _linkManager = new LinkManager();\n }\n return _linkManager;\n}\n","/**\n * Issue Tracker Module\n *\n * Provides a unified interface for different issue tracking systems.\n */\n\n// Core interface and types\nexport type {\n IssueTracker,\n Issue,\n IssueFilters,\n IssueState,\n IssueUpdate,\n NewIssue,\n Comment,\n TrackerType,\n} from './interface.js';\n\nexport {\n NotImplementedError,\n IssueNotFoundError,\n TrackerAuthError,\n} from './interface.js';\n\n// Tracker implementations\nexport { LinearTracker } from './linear.js';\nexport { GitHubTracker } from './github.js';\nexport { GitLabTracker } from './gitlab.js';\n\n// Factory functions\nexport type { TrackerConfig } from './factory.js';\nexport {\n createTracker,\n createTrackerFromConfig,\n getPrimaryTracker,\n getSecondaryTracker,\n getAllTrackers,\n} from './factory.js';\n\n// Cross-tracker linking\nexport type { TrackerLink, LinkDirection } from './linking.js';\nexport {\n LinkManager,\n getLinkManager,\n parseIssueRef,\n formatIssueRef,\n} from './linking.js';\n"],"mappings":"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","names":["existsSync","join","existsSync","mkdirSync","readdirSync","lstatSync","rmSync","join","STATE_MAP","readFileSync","existsSync","mkdirSync","join","homedir"]}
|
package/dist/cli/index.js
CHANGED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2014 The xterm.js authors. All rights reserved.
|
|
3
|
+
* Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
|
|
4
|
+
* https://github.com/chjj/term.js
|
|
5
|
+
* @license MIT
|
|
6
|
+
*
|
|
7
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
* in the Software without restriction, including without limitation the rights
|
|
10
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
* furnished to do so, subject to the following conditions:
|
|
13
|
+
*
|
|
14
|
+
* The above copyright notice and this permission notice shall be included in
|
|
15
|
+
* all copies or substantial portions of the Software.
|
|
16
|
+
*
|
|
17
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
23
|
+
* THE SOFTWARE.
|
|
24
|
+
*
|
|
25
|
+
* Originally forked from (with the author's permission):
|
|
26
|
+
* Fabrice Bellard's javascript vt100 for jslinux:
|
|
27
|
+
* http://bellard.org/jslinux/
|
|
28
|
+
* Copyright (c) 2011 Fabrice Bellard
|
|
29
|
+
* The original design remains. The terminal itself
|
|
30
|
+
* has been extended to include xterm CSI codes, among
|
|
31
|
+
* other features.
|
|
32
|
+
*/.xterm{cursor:text;position:relative;-moz-user-select:none;user-select:none;-ms-user-select:none;-webkit-user-select:none}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{position:absolute;top:0;z-index:5}.xterm .xterm-helper-textarea{padding:0;border:0;margin:0;position:absolute;opacity:0;left:-9999em;top:0;width:0;height:0;z-index:-5;white-space:nowrap;overflow:hidden;resize:none}.xterm .composition-view{background:#000;color:#fff;display:none;position:absolute;white-space:nowrap;z-index:1}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{background-color:#000;overflow-y:scroll;cursor:default;position:absolute;right:0;left:0;top:0;bottom:0}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;left:0;top:0}.xterm-char-measure-element{display:inline-block;visibility:hidden;position:absolute;top:0;left:-9999em;line-height:normal}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer,.xterm .xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility:not(.debug),.xterm .xterm-message{position:absolute;left:0;top:0;bottom:0;right:0;z-index:10;color:transparent;pointer-events:none}.xterm .xterm-accessibility-tree:not(.debug) *::-moz-selection{color:transparent}.xterm .xterm-accessibility-tree:not(.debug) *::selection{color:transparent}.xterm .xterm-accessibility-tree{font-family:monospace;-webkit-user-select:text;-moz-user-select:text;user-select:text;white-space:pre}.xterm .xterm-accessibility-tree>div{transform-origin:left;width:-moz-fit-content;width:fit-content}.xterm .live-region{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}.xterm-dim{opacity:1!important}.xterm-underline-1{text-decoration:underline}.xterm-underline-2{-webkit-text-decoration:double underline;text-decoration:double underline}.xterm-underline-3{-webkit-text-decoration:wavy underline;text-decoration:wavy underline}.xterm-underline-4{-webkit-text-decoration:dotted underline;text-decoration:dotted underline}.xterm-underline-5{-webkit-text-decoration:dashed underline;text-decoration:dashed underline}.xterm-overline{text-decoration:overline}.xterm-overline.xterm-underline-1{text-decoration:overline underline}.xterm-overline.xterm-underline-2{-webkit-text-decoration:overline double underline;text-decoration:overline double underline}.xterm-overline.xterm-underline-3{-webkit-text-decoration:overline wavy underline;text-decoration:overline wavy underline}.xterm-overline.xterm-underline-4{-webkit-text-decoration:overline dotted underline;text-decoration:overline dotted underline}.xterm-overline.xterm-underline-5{-webkit-text-decoration:overline dashed underline;text-decoration:overline dashed underline}.xterm-strikethrough{text-decoration:line-through}.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}.xterm-decoration-overview-ruler{z-index:8;position:absolute;top:0;right:0;pointer-events:none}.xterm-decoration-top{z-index:2;position:relative}.xterm .xterm-scrollable-element>.scrollbar{cursor:default}.xterm .xterm-scrollable-element>.scrollbar>.scra{cursor:pointer;font-size:11px!important}.xterm .xterm-scrollable-element>.visible{opacity:1;background:#0000;transition:opacity .1s linear;z-index:11}.xterm .xterm-scrollable-element>.invisible{opacity:0;pointer-events:none}.xterm .xterm-scrollable-element>.invisible.fade{transition:opacity .8s linear}.xterm .xterm-scrollable-element>.shadow{position:absolute;display:none}.xterm .xterm-scrollable-element>.shadow.top{display:block;top:0;left:3px;height:3px;width:100%;box-shadow:var(--vscode-scrollbar-shadow, #000) 0 6px 6px -6px inset}.xterm .xterm-scrollable-element>.shadow.left{display:block;top:3px;left:0;height:100%;width:3px;box-shadow:var(--vscode-scrollbar-shadow, #000) 6px 0 6px -6px inset}.xterm .xterm-scrollable-element>.shadow.top-left-corner{display:block;top:0;left:0;height:3px;width:3px}.xterm .xterm-scrollable-element>.shadow.top.left{box-shadow:var(--vscode-scrollbar-shadow, #000) 6px 0 6px -6px inset}._missionControl_1x340_4{--mc-bg-main: #FFFFFF;--mc-bg-sidebar: #FAF9F7;--mc-bg-hover: #F3F2EF;--mc-bg-selected: #EDE9E3;--mc-text-primary: #1A1A1A;--mc-text-secondary: #6B7280;--mc-text-muted: #9CA3AF;--mc-border: #E5E7EB;--mc-border-strong: #D1D5DB;--mc-accent: #2563EB;--mc-accent-hover: #1D4ED8;--mc-success: #059669;--mc-warning: #D97706;--mc-error: #DC2626;--mc-font-family: -apple-system, BlinkMacSystemFont, "Inter", "SF Pro", system-ui, sans-serif;--mc-font-mono: "SF Mono", "Monaco", "Menlo", "Consolas", monospace;--mc-font-size-xs: 11px;--mc-font-size-sm: 12px;--mc-font-size-base: 14px;--mc-font-size-md: 16px;--mc-font-size-lg: 20px;--mc-font-size-xl: 28px;--mc-line-height: 1.5;--mc-space-1: 4px;--mc-space-2: 8px;--mc-space-3: 12px;--mc-space-4: 16px;--mc-space-5: 20px;--mc-space-6: 24px;--mc-space-8: 32px;--mc-radius-sm: 4px;--mc-radius: 8px;--mc-radius-lg: 12px;font-family:var(--mc-font-family);color:var(--mc-text-primary);line-height:var(--mc-line-height);height:100%}._layout_1x340_53{display:flex;height:100%;overflow:hidden;background:var(--mc-bg-main)}._sidebar_1x340_60{background:var(--mc-bg-sidebar);border-right:1px solid var(--mc-border);display:flex;flex-direction:column;overflow:hidden;flex-shrink:0}._resizeHandle_1x340_69{width:4px;cursor:col-resize;background:transparent;flex-shrink:0;transition:background .15s;position:relative}._resizeHandle_1x340_69:hover,._resizeHandle_1x340_69:active{background:var(--mc-accent)}._sidebarHeader_1x340_83{padding:var(--mc-space-4) var(--mc-space-4) var(--mc-space-3);border-bottom:1px solid var(--mc-border)}._sidebarTitle_1x340_88{font-size:var(--mc-font-size-md);font-weight:600;margin:0 0 var(--mc-space-1)}._sidebarSubtitle_1x340_94{font-size:var(--mc-font-size-sm);color:var(--mc-text-secondary);margin:0}._projectTree_1x340_100{flex:1;overflow-y:auto;padding:var(--mc-space-2) 0}._projectNode_1x340_107{margin-bottom:var(--mc-space-1)}._projectHeader_1x340_111{display:flex;align-items:center;gap:var(--mc-space-2);padding:var(--mc-space-2) var(--mc-space-4);cursor:pointer;transition:background .1s;font-size:var(--mc-font-size-sm);font-weight:600;color:var(--mc-text-primary);border:none;background:none;width:100%;text-align:left}._projectHeader_1x340_111:hover{background:var(--mc-bg-hover)}._chevron_1x340_131{transition:transform .15s;color:var(--mc-text-muted);flex-shrink:0}._chevronOpen_1x340_137{transform:rotate(90deg)}._projectName_1x340_141{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._featureCount_1x340_148{font-size:var(--mc-font-size-xs);color:var(--mc-text-muted);font-weight:400}._featureItem_1x340_155{display:flex;align-items:center;gap:var(--mc-space-2);padding:var(--mc-space-2) var(--mc-space-4) var(--mc-space-2) var(--mc-space-8);cursor:pointer;transition:background .1s;font-size:var(--mc-font-size-sm);border:none;background:none;width:100%;text-align:left;color:var(--mc-text-primary)}._featureItem_1x340_155:hover{background:var(--mc-bg-hover)}._featureItemSelected_1x340_174{background:var(--mc-bg-selected)}._featureStatus_1x340_178{flex-shrink:0;width:16px;height:16px;display:flex;align-items:center;justify-content:center}._featureLabel_1x340_187{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._featureId_sidebar_1x340_194{font-size:var(--mc-font-size-xs);color:var(--mc-text-muted);font-family:var(--mc-font-mono);flex-shrink:0;min-width:56px}._featureState_1x340_202{font-size:10px;color:var(--mc-text-muted);flex-shrink:0;padding:1px 6px;border-radius:3px;background:var(--mc-bg-hover);white-space:nowrap}._featureCost_1x340_212{font-size:var(--mc-font-size-xs);color:var(--mc-text-muted);font-family:var(--mc-font-mono)}._emptyProject_1x340_218{padding:var(--mc-space-2) var(--mc-space-8);font-size:var(--mc-font-size-xs);color:var(--mc-text-muted);font-style:italic}._content_1x340_226{flex:1;display:flex;flex-direction:column;overflow:hidden;min-width:0}._contentEmpty_1x340_234{display:flex;align-items:center;justify-content:center;flex:1;color:var(--mc-text-muted);font-size:var(--mc-font-size-base)}._featureHeader_1x340_244{display:flex;align-items:center;gap:var(--mc-space-3);padding:var(--mc-space-4) var(--mc-space-6);border-bottom:1px solid var(--mc-border);background:var(--mc-bg-main)}._featureTitle_1x340_253{font-size:var(--mc-font-size-lg);font-weight:600;flex:1;margin:0}._featureId_1x340_194{font-size:var(--mc-font-size-sm);color:var(--mc-text-muted);font-family:var(--mc-font-mono)}._badgeBar_1x340_267{display:flex;gap:var(--mc-space-2);padding:var(--mc-space-3) var(--mc-space-6);border-bottom:1px solid var(--mc-border);background:var(--mc-bg-sidebar)}._badge_1x340_267{display:inline-flex;align-items:center;gap:var(--mc-space-1);padding:var(--mc-space-1) var(--mc-space-2);font-size:var(--mc-font-size-xs);border-radius:var(--mc-radius-sm);border:1px solid var(--mc-border);background:var(--mc-bg-main);cursor:pointer;transition:all .1s;color:var(--mc-text-secondary)}._badge_1x340_267:hover{border-color:var(--mc-accent);color:var(--mc-accent)}._badgeDisabled_1x340_294{opacity:.4;cursor:default}._badgeDisabled_1x340_294:hover{border-color:var(--mc-border);color:var(--mc-text-secondary)}._activityContainer_1x340_305{flex:1;overflow-y:auto;padding:var(--mc-space-4) var(--mc-space-6);display:flex;flex-direction:column;gap:var(--mc-space-4)}._agentSection_1x340_315{border:1px solid var(--mc-border);border-radius:var(--mc-radius);overflow:hidden}._sectionHeader_1x340_321{display:flex;align-items:center;gap:var(--mc-space-2);padding:var(--mc-space-3) var(--mc-space-4);background:var(--mc-bg-sidebar);border-bottom:1px solid var(--mc-border);cursor:pointer;transition:background .1s}._sectionHeader_1x340_321:hover{background:var(--mc-bg-hover)}._sectionType_1x340_336{font-size:var(--mc-font-size-xs);font-weight:600;text-transform:uppercase;letter-spacing:.05em;padding:2px var(--mc-space-2);border-radius:var(--mc-radius-sm)}._typePlanning_1x340_345{background:#dbeafe;color:#1e40af}._typeWork_1x340_350{background:#d1fae5;color:#065f46}._typeReview_1x340_355{background:#fef3c7;color:#92400e}._typeTest_1x340_360{background:#e0e7ff;color:#3730a3}._typeMerge_1x340_365{background:#fce7f3;color:#9d174d}._sectionModel_1x340_372{font-size:var(--mc-font-size-xs);color:var(--mc-text-muted);font-family:var(--mc-font-mono)}._sectionTime_1x340_378{font-size:var(--mc-font-size-xs);color:var(--mc-text-muted);margin-left:auto}._sectionCost_1x340_384{font-size:var(--mc-font-size-xs);color:var(--mc-success);font-weight:500;padding:0 var(--mc-space-1)}._costSummary_1x340_391{font-size:var(--mc-font-size-xs);color:var(--mc-text-muted);text-align:right;padding:var(--mc-space-1) var(--mc-space-2);font-weight:500}._sectionStatus_1x340_399{width:8px;height:8px;border-radius:50%;flex-shrink:0}._statusRunning_1x340_406{background:var(--mc-success);animation:_pulse_1x340_1 2s infinite}._statusCompleted_1x340_411{background:var(--mc-text-muted)}._statusFailed_1x340_415{background:var(--mc-error)}@keyframes _pulse_1x340_1{0%,to{opacity:1}50%{opacity:.5}}._sectionContent_1x340_424{padding:var(--mc-space-4);font-size:var(--mc-font-size-sm);font-family:var(--mc-font-mono);white-space:pre-wrap;word-break:break-word;max-height:400px;overflow-y:auto;background:var(--mc-bg-main);line-height:1.6;color:var(--mc-text-primary)}._unreadDot_1x340_437{width:6px;height:6px;border-radius:50%;background:var(--mc-accent);flex-shrink:0}._isolationOverlay_1x340_446{position:fixed;top:0;right:0;bottom:0;left:0;z-index:50;background:var(--mc-bg-main);display:flex;flex-direction:column}._isolationHeader_1x340_455{display:flex;align-items:center;gap:var(--mc-space-3);padding:var(--mc-space-3) var(--mc-space-6);border-bottom:1px solid var(--mc-border);background:var(--mc-bg-sidebar)}._isolationClose_1x340_464{padding:var(--mc-space-1) var(--mc-space-2);border:1px solid var(--mc-border);border-radius:var(--mc-radius-sm);background:var(--mc-bg-main);color:var(--mc-text-secondary);font-size:var(--mc-font-size-xs);cursor:pointer;transition:all .1s}._isolationClose_1x340_464:hover{border-color:var(--mc-text-secondary);color:var(--mc-text-primary)}._isolationContent_1x340_480{flex:1;overflow-y:auto;padding:var(--mc-space-6);font-family:var(--mc-font-mono);font-size:var(--mc-font-size-sm);white-space:pre-wrap;word-break:break-word;line-height:1.6}._modalOverlay_1x340_492{position:fixed;top:0;right:0;bottom:0;left:0;z-index:50;background:#00000080;display:flex;align-items:center;justify-content:center;padding:var(--mc-space-8)}._modalContent_1x340_503{background:var(--mc-bg-main);border-radius:var(--mc-radius-lg);max-width:800px;width:100%;max-height:80vh;display:flex;flex-direction:column;overflow:hidden}._modalHeader_1x340_514{display:flex;align-items:center;justify-content:space-between;padding:var(--mc-space-4) var(--mc-space-6);border-bottom:1px solid var(--mc-border)}._modalTitle_1x340_522{font-size:var(--mc-font-size-md);font-weight:600;margin:0}._modalClose_1x340_528{padding:var(--mc-space-1);border:none;background:none;cursor:pointer;color:var(--mc-text-muted);border-radius:var(--mc-radius-sm);transition:all .1s}._modalClose_1x340_528:hover{color:var(--mc-text-primary);background:var(--mc-bg-hover)}._modalBody_1x340_543{flex:1;overflow-y:auto;padding:var(--mc-space-6)}._uploadZone_1x340_550{border:2px dashed var(--mc-border);border-radius:var(--mc-radius);padding:var(--mc-space-8);text-align:center;cursor:pointer;transition:all .15s;color:var(--mc-text-muted)}._uploadZone_1x340_550:hover,._uploadZoneActive_1x340_561{border-color:var(--mc-accent);background:#2563eb0a;color:var(--mc-accent)}._uploadIcon_1x340_567{margin-bottom:var(--mc-space-2)}._uploadText_1x340_571{font-size:var(--mc-font-size-sm);margin:0}._uploadHint_1x340_576{font-size:var(--mc-font-size-xs);margin:var(--mc-space-1) 0 0}._artifactList_1x340_581{display:flex;flex-direction:column;gap:var(--mc-space-2);margin-top:var(--mc-space-4)}._artifactItem_1x340_588{display:flex;align-items:center;gap:var(--mc-space-2);padding:var(--mc-space-2) var(--mc-space-3);border:1px solid var(--mc-border);border-radius:var(--mc-radius-sm);font-size:var(--mc-font-size-sm);cursor:pointer;transition:all .1s}._artifactItem_1x340_588:hover{background:var(--mc-bg-hover)}._artifactName_1x340_604{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._artifactDate_1x340_611{font-size:var(--mc-font-size-xs);color:var(--mc-text-muted)}._syncButton_1x340_617{display:inline-flex;align-items:center;gap:var(--mc-space-1);padding:var(--mc-space-1) var(--mc-space-3);font-size:var(--mc-font-size-xs);border:1px solid var(--mc-border);border-radius:var(--mc-radius-sm);background:var(--mc-bg-main);color:var(--mc-text-secondary);cursor:pointer;transition:all .1s}._syncButton_1x340_617:hover{border-color:var(--mc-accent);color:var(--mc-accent)}._syncButton_1x340_617:disabled{opacity:.5;cursor:not-allowed}@keyframes _spin_1x340_646{0%{transform:rotate(0)}to{transform:rotate(360deg)}}._spinning_1x340_646{animation:_spin_1x340_646 1s linear infinite}._shadowToggle_1x340_651{display:flex;align-items:center;gap:var(--mc-space-3);padding:var(--mc-space-3) var(--mc-space-4);border:1px solid var(--mc-border);border-radius:var(--mc-radius);margin-top:var(--mc-space-3)}._shadowLabel_1x340_661{flex:1}._shadowTitle_1x340_665{font-size:var(--mc-font-size-sm);font-weight:500;margin:0}._shadowDesc_1x340_671{font-size:var(--mc-font-size-xs);color:var(--mc-text-muted);margin:2px 0 0}._markdownContent_1x340_678{font-size:var(--mc-font-size-sm);line-height:1.7}._markdownContent_1x340_678 h1{font-size:var(--mc-font-size-lg);font-weight:600;margin:var(--mc-space-6) 0 var(--mc-space-3)}._markdownContent_1x340_678 h2{font-size:var(--mc-font-size-md);font-weight:600;margin:var(--mc-space-5) 0 var(--mc-space-2)}._markdownContent_1x340_678 h3{font-size:var(--mc-font-size-base);font-weight:600;margin:var(--mc-space-4) 0 var(--mc-space-2)}._markdownContent_1x340_678 p{margin:0 0 var(--mc-space-3)}._markdownContent_1x340_678 ul,._markdownContent_1x340_678 ol{margin:0 0 var(--mc-space-3);padding-left:var(--mc-space-6)}._markdownContent_1x340_678 li{margin-bottom:var(--mc-space-1)}._markdownContent_1x340_678 code{font-family:var(--mc-font-mono);font-size:var(--mc-font-size-xs);padding:1px var(--mc-space-1);border-radius:3px;background:var(--mc-bg-hover)}._markdownContent_1x340_678 pre{font-family:var(--mc-font-mono);font-size:var(--mc-font-size-xs);padding:var(--mc-space-3);border-radius:var(--mc-radius-sm);background:var(--mc-bg-sidebar);overflow-x:auto;margin:0 0 var(--mc-space-3)}._markdownContent_1x340_678 pre code{padding:0;background:none}._markdownContent_1x340_678 table{width:100%;border-collapse:collapse;margin:0 0 var(--mc-space-3);font-size:var(--mc-font-size-xs)}._markdownContent_1x340_678 th,._markdownContent_1x340_678 td{padding:var(--mc-space-2) var(--mc-space-3);border:1px solid var(--mc-border);text-align:left}._markdownContent_1x340_678 th{background:var(--mc-bg-sidebar);font-weight:600}._markdownContent_1x340_678 tr:nth-child(2n){background:var(--mc-bg-hover)}._kbdHint_1x340_732{display:inline-block;padding:1px 5px;font-size:10px;font-family:var(--mc-font-mono);background:var(--mc-bg-sidebar);border:1px solid var(--mc-border-strong);border-radius:3px;box-shadow:0 1px 0 var(--mc-border);margin-right:4px}._isolationClose_1x340_464:hover ._kbdHint_1x340_732{border-color:var(--mc-text-secondary)}*,: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{--color-base: 17 24 39;--color-raised: 31 41 55;--color-overlay: 55 65 81;--color-emphasis: 75 85 99;--color-heading: 255 255 255;--color-body: 209 213 219;--color-subtle: 156 163 175;--color-muted: 107 114 128;--color-divider: 55 65 81;--color-divider-strong: 75 85 99;--color-input-bg: 55 65 81}:root.light{--color-base: 249 250 251;--color-raised: 255 255 255;--color-overlay: 243 244 246;--color-emphasis: 229 231 235;--color-heading: 17 24 39;--color-body: 55 65 81;--color-subtle: 107 114 128;--color-muted: 156 163 175;--color-divider: 229 231 235;--color-divider-strong: 209 213 219;--color-input-bg: 255 255 255}.container{width:100%}@media (min-width: 640px){.container{max-width:640px}}@media (min-width: 768px){.container{max-width:768px}}@media (min-width: 1024px){.container{max-width:1024px}}@media (min-width: 1280px){.container{max-width:1280px}}@media (min-width: 1536px){.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}.visible{visibility:visible}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{top:0;right:0;bottom:0;left:0}.-top-3{top:-.75rem}.bottom-0{bottom:0}.bottom-4{bottom:1rem}.bottom-6{bottom:1.5rem}.left-0{left:0}.left-0\.5{left:.125rem}.left-1\/2{left:50%}.left-2{left:.5rem}.right-0{right:0}.right-0\.5{right:.125rem}.right-2{right:.5rem}.right-3{right:.75rem}.right-4{right:1rem}.right-8{right:2rem}.top-0{top:0}.top-0\.5{top:.125rem}.top-1\/2{top:50%}.top-10{top:2.5rem}.top-2{top:.5rem}.top-full{top:100%}.z-10{z-index:10}.z-20{z-index:20}.z-40{z-index:40}.z-50{z-index:50}.z-\[60\]{z-index:60}.m-0{margin:0}.-mx-2{margin-left:-.5rem;margin-right:-.5rem}.-mx-3{margin-left:-.75rem;margin-right:-.75rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-4{margin-left:1rem;margin-right:1rem}.mx-6{margin-left:1.5rem;margin-right:1.5rem}.mx-auto{margin-left:auto;margin-right:auto}.my-2{margin-top:.5rem;margin-bottom:.5rem}.-mb-3{margin-bottom:-.75rem}.-mt-0\.5{margin-top:-.125rem}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-10{margin-bottom:2.5rem}.mb-12{margin-bottom:3rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-4{margin-left:1rem}.ml-5{margin-left:1.25rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mr-2{margin-right:.5rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-12{margin-top:3rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.line-clamp-1{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.size-1\.5{width:.375rem;height:.375rem}.size-10{width:2.5rem;height:2.5rem}.size-12{width:3rem;height:3rem}.size-4{width:1rem;height:1rem}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-12{height:3rem}.h-16{height:4rem}.h-2{height:.5rem}.h-2\.5{height:.625rem}.h-20{height:5rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-32{height:8rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-64{height:16rem}.h-8{height:2rem}.h-\[600px\]{height:600px}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-0{max-height:0px}.max-h-24{max-height:6rem}.max-h-32{max-height:8rem}.max-h-48{max-height:12rem}.max-h-64{max-height:16rem}.max-h-96{max-height:24rem}.max-h-\[2000px\]{max-height:2000px}.max-h-\[450px\]{max-height:450px}.max-h-\[500px\]{max-height:500px}.max-h-\[600px\]{max-height:600px}.max-h-\[60vh\]{max-height:60vh}.max-h-\[70vh\]{max-height:70vh}.max-h-\[80vh\]{max-height:80vh}.max-h-\[calc\(100vh-220px\)\]{max-height:calc(100vh - 220px)}.min-h-0{min-height:0px}.w-0\.5{width:.125rem}.w-1{width:.25rem}.w-1\.5{width:.375rem}.w-1\/4{width:25%}.w-10{width:2.5rem}.w-11{width:2.75rem}.w-12{width:3rem}.w-16{width:4rem}.w-2{width:.5rem}.w-2\.5{width:.625rem}.w-20{width:5rem}.w-24{width:6rem}.w-28{width:7rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-3\/4{width:75%}.w-32{width:8rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-56{width:14rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-8{width:2rem}.w-80{width:20rem}.w-full{width:100%}.w-px{width:1px}.min-w-0{min-width:0px}.min-w-\[120px\]{min-width:120px}.min-w-\[140px\]{min-width:140px}.min-w-\[600px\]{min-width:600px}.min-w-max{min-width:-moz-max-content;min-width:max-content}.max-w-2xl{max-width:42rem}.max-w-4xl{max-width:56rem}.max-w-\[1200px\]{max-width:1200px}.max-w-\[200px\]{max-width:200px}.max-w-\[680px\]{max-width:680px}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.origin-left{transform-origin:left}.-translate-x-1\/2{--tw-translate-x: -50%;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))}.-translate-y-1\/2{--tw-translate-y: -50%;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))}.translate-x-1{--tw-translate-x: .25rem;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))}.translate-x-6{--tw-translate-x: 1.5rem;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))}.rotate-2{--tw-rotate: 2deg;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))}.rotate-45{--tw-rotate: 45deg;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))}.scale-105{--tw-scale-x: 1.05;--tw-scale-y: 1.05;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))}.scale-\[1\.02\]{--tw-scale-x: 1.02;--tw-scale-y: 1.02;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))}.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))}.animate-\[pulse_2s_ease-in-out_infinite\]{animation:pulse 2s ease-in-out infinite}@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-col-resize{cursor:col-resize}.cursor-context-menu{cursor:context-menu}.cursor-grab{cursor:grab}.cursor-move{cursor:move}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.cursor-wait{cursor:wait}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize{resize:both}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-\[2fr_minmax\(200px\,1\.5fr\)_120px\]{grid-template-columns:2fr minmax(200px,1.5fr) 120px}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-5{gap:1.25rem}.gap-6{gap:1.5rem}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-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))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(2rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem * 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))}.divide-gray-700>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:rgb(55 65 81 / var(--tw-divide-opacity, 1))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre{white-space:pre}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.rounded-b-lg{border-bottom-right-radius:.5rem;border-bottom-left-radius:.5rem}.rounded-t{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-l-2{border-left-width:2px}.border-l-4{border-left-width:4px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-t-4{border-top-width:4px}.border-amber-500\/30{border-color:#f59e0b4d}.border-amber-700\/30{border-color:#b453094d}.border-blue-400{--tw-border-opacity: 1;border-color:rgb(96 165 250 / var(--tw-border-opacity, 1))}.border-blue-400\/50{border-color:#60a5fa80}.border-blue-500{--tw-border-opacity: 1;border-color:rgb(59 130 246 / var(--tw-border-opacity, 1))}.border-blue-500\/20{border-color:#3b82f633}.border-blue-500\/30{border-color:#3b82f64d}.border-blue-500\/50{border-color:#3b82f680}.border-blue-600{--tw-border-opacity: 1;border-color:rgb(37 99 235 / var(--tw-border-opacity, 1))}.border-blue-600\/50{border-color:#2563eb80}.border-blue-700\/50{border-color:#1d4ed880}.border-current{border-color:currentColor}.border-cyan-500\/30{border-color:#06b6d44d}.border-divider{--tw-border-opacity: 1;border-color:rgb(var(--color-divider) / var(--tw-border-opacity, 1))}.border-divider-strong{--tw-border-opacity: 1;border-color:rgb(var(--color-divider-strong) / var(--tw-border-opacity, 1))}.border-divider-strong\/50{border-color:rgb(var(--color-divider-strong) / .5)}.border-divider\/50{border-color:rgb(var(--color-divider) / .5)}.border-emerald-500\/30{border-color:#10b9814d}.border-emerald-700\/50{border-color:#04785780}.border-gray-400{--tw-border-opacity: 1;border-color:rgb(156 163 175 / var(--tw-border-opacity, 1))}.border-gray-500{--tw-border-opacity: 1;border-color:rgb(107 114 128 / var(--tw-border-opacity, 1))}.border-gray-600{--tw-border-opacity: 1;border-color:rgb(75 85 99 / var(--tw-border-opacity, 1))}.border-gray-700{--tw-border-opacity: 1;border-color:rgb(55 65 81 / var(--tw-border-opacity, 1))}.border-green-500{--tw-border-opacity: 1;border-color:rgb(34 197 94 / var(--tw-border-opacity, 1))}.border-green-500\/30{border-color:#22c55e4d}.border-green-600{--tw-border-opacity: 1;border-color:rgb(22 163 74 / var(--tw-border-opacity, 1))}.border-green-600\/30{border-color:#16a34a4d}.border-green-700\/50{border-color:#15803d80}.border-green-800{--tw-border-opacity: 1;border-color:rgb(22 101 52 / var(--tw-border-opacity, 1))}.border-orange-500\/30{border-color:#f973164d}.border-orange-600\/50{border-color:#ea580c80}.border-orange-700\/50{border-color:#c2410c80}.border-pink-500{--tw-border-opacity: 1;border-color:rgb(236 72 153 / var(--tw-border-opacity, 1))}.border-purple-500\/30{border-color:#a855f74d}.border-purple-600{--tw-border-opacity: 1;border-color:rgb(147 51 234 / var(--tw-border-opacity, 1))}.border-purple-600\/50{border-color:#9333ea80}.border-purple-700\/50{border-color:#7e22ce80}.border-red-500\/30{border-color:#ef44444d}.border-red-600{--tw-border-opacity: 1;border-color:rgb(220 38 38 / var(--tw-border-opacity, 1))}.border-red-600\/30{border-color:#dc26264d}.border-red-700{--tw-border-opacity: 1;border-color:rgb(185 28 28 / var(--tw-border-opacity, 1))}.border-red-700\/50{border-color:#b91c1c80}.border-red-800{--tw-border-opacity: 1;border-color:rgb(153 27 27 / var(--tw-border-opacity, 1))}.border-rose-500\/30{border-color:#f43f5e4d}.border-slate-600{--tw-border-opacity: 1;border-color:rgb(71 85 105 / var(--tw-border-opacity, 1))}.border-slate-700{--tw-border-opacity: 1;border-color:rgb(51 65 85 / var(--tw-border-opacity, 1))}.border-transparent{border-color:transparent}.border-yellow-500{--tw-border-opacity: 1;border-color:rgb(234 179 8 / var(--tw-border-opacity, 1))}.border-yellow-600{--tw-border-opacity: 1;border-color:rgb(202 138 4 / var(--tw-border-opacity, 1))}.border-yellow-700\/50{border-color:#a1620780}.border-yellow-800{--tw-border-opacity: 1;border-color:rgb(133 77 14 / var(--tw-border-opacity, 1))}.border-l-blue-500{--tw-border-opacity: 1;border-left-color:rgb(59 130 246 / var(--tw-border-opacity, 1))}.border-l-divider-strong{--tw-border-opacity: 1;border-left-color:rgb(var(--color-divider-strong) / var(--tw-border-opacity, 1))}.border-l-gray-500{--tw-border-opacity: 1;border-left-color:rgb(107 114 128 / var(--tw-border-opacity, 1))}.border-l-orange-500{--tw-border-opacity: 1;border-left-color:rgb(249 115 22 / var(--tw-border-opacity, 1))}.border-l-red-500{--tw-border-opacity: 1;border-left-color:rgb(239 68 68 / var(--tw-border-opacity, 1))}.border-l-yellow-500{--tw-border-opacity: 1;border-left-color:rgb(234 179 8 / var(--tw-border-opacity, 1))}.bg-\[\#10b981\]{--tw-bg-opacity: 1;background-color:rgb(16 185 129 / var(--tw-bg-opacity, 1))}.bg-\[\#3b82f6\]\/20{background-color:#3b82f633}.bg-\[\#a078f7\]{--tw-bg-opacity: 1;background-color:rgb(160 120 247 / var(--tw-bg-opacity, 1))}.bg-\[\#a078f7\]\/40{background-color:#a078f766}.bg-\[\#fbbf24\]{--tw-bg-opacity: 1;background-color:rgb(251 191 36 / var(--tw-bg-opacity, 1))}.bg-\[\#fbbf24\]\/20{background-color:#fbbf2433}.bg-amber-500\/10{background-color:#f59e0b1a}.bg-amber-500\/20{background-color:#f59e0b33}.bg-amber-500\/5{background-color:#f59e0b0d}.bg-amber-600{--tw-bg-opacity: 1;background-color:rgb(217 119 6 / var(--tw-bg-opacity, 1))}.bg-amber-900\/20{background-color:#78350f33}.bg-amber-900\/50{background-color:#78350f80}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-black\/50{background-color:#00000080}.bg-black\/60{background-color:#0009}.bg-black\/70{background-color:#000000b3}.bg-blue-400{--tw-bg-opacity: 1;background-color:rgb(96 165 250 / var(--tw-bg-opacity, 1))}.bg-blue-500{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))}.bg-blue-500\/10{background-color:#3b82f61a}.bg-blue-500\/20{background-color:#3b82f633}.bg-blue-500\/30{background-color:#3b82f64d}.bg-blue-500\/5{background-color:#3b82f60d}.bg-blue-600{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1))}.bg-blue-900\/20{background-color:#1e3a8a33}.bg-blue-900\/30{background-color:#1e3a8a4d}.bg-blue-900\/40{background-color:#1e3a8a66}.bg-blue-900\/50{background-color:#1e3a8a80}.bg-content-muted{--tw-bg-opacity: 1;background-color:rgb(var(--color-muted) / var(--tw-bg-opacity, 1))}.bg-cyan-900\/20{background-color:#164e6333}.bg-cyan-900\/50{background-color:#164e6380}.bg-divider{--tw-bg-opacity: 1;background-color:rgb(var(--color-divider) / var(--tw-bg-opacity, 1))}.bg-divider-strong{--tw-bg-opacity: 1;background-color:rgb(var(--color-divider-strong) / var(--tw-bg-opacity, 1))}.bg-emerald-500\/10{background-color:#10b9811a}.bg-emerald-500\/20{background-color:#10b98133}.bg-emerald-500\/5{background-color:#10b9810d}.bg-emerald-900\/40{background-color:#064e3b66}.bg-gray-500{--tw-bg-opacity: 1;background-color:rgb(107 114 128 / var(--tw-bg-opacity, 1))}.bg-gray-500\/20{background-color:#6b728033}.bg-gray-500\/30{background-color:#6b72804d}.bg-gray-700{--tw-bg-opacity: 1;background-color:rgb(55 65 81 / var(--tw-bg-opacity, 1))}.bg-gray-800{--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.bg-gray-900{--tw-bg-opacity: 1;background-color:rgb(17 24 39 / var(--tw-bg-opacity, 1))}.bg-gray-950{--tw-bg-opacity: 1;background-color:rgb(3 7 18 / var(--tw-bg-opacity, 1))}.bg-green-500{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-green-500\/20{background-color:#22c55e33}.bg-green-600{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.bg-green-600\/20{background-color:#16a34a33}.bg-green-900{--tw-bg-opacity: 1;background-color:rgb(20 83 45 / var(--tw-bg-opacity, 1))}.bg-green-900\/20{background-color:#14532d33}.bg-green-900\/30{background-color:#14532d4d}.bg-green-900\/50{background-color:#14532d80}.bg-input-bg{--tw-bg-opacity: 1;background-color:rgb(var(--color-input-bg) / var(--tw-bg-opacity, 1))}.bg-orange-500{--tw-bg-opacity: 1;background-color:rgb(249 115 22 / var(--tw-bg-opacity, 1))}.bg-orange-500\/10{background-color:#f973161a}.bg-orange-600{--tw-bg-opacity: 1;background-color:rgb(234 88 12 / var(--tw-bg-opacity, 1))}.bg-orange-600\/20{background-color:#ea580c33}.bg-orange-900\/20{background-color:#7c2d1233}.bg-orange-900\/30{background-color:#7c2d124d}.bg-orange-900\/40{background-color:#7c2d1266}.bg-orange-900\/50{background-color:#7c2d1280}.bg-orange-950\/30{background-color:#4314074d}.bg-pink-600{--tw-bg-opacity: 1;background-color:rgb(219 39 119 / var(--tw-bg-opacity, 1))}.bg-purple-400{--tw-bg-opacity: 1;background-color:rgb(192 132 252 / var(--tw-bg-opacity, 1))}.bg-purple-500{--tw-bg-opacity: 1;background-color:rgb(168 85 247 / var(--tw-bg-opacity, 1))}.bg-purple-500\/10{background-color:#a855f71a}.bg-purple-500\/20{background-color:#a855f733}.bg-purple-600{--tw-bg-opacity: 1;background-color:rgb(147 51 234 / var(--tw-bg-opacity, 1))}.bg-purple-900\/20{background-color:#581c8733}.bg-purple-900\/40{background-color:#581c8766}.bg-purple-900\/50{background-color:#581c8780}.bg-red-500{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.bg-red-500\/20{background-color:#ef444433}.bg-red-600{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.bg-red-600\/20{background-color:#dc262633}.bg-red-700{--tw-bg-opacity: 1;background-color:rgb(185 28 28 / var(--tw-bg-opacity, 1))}.bg-red-900{--tw-bg-opacity: 1;background-color:rgb(127 29 29 / var(--tw-bg-opacity, 1))}.bg-red-900\/20{background-color:#7f1d1d33}.bg-red-900\/30{background-color:#7f1d1d4d}.bg-red-900\/40{background-color:#7f1d1d66}.bg-red-900\/50{background-color:#7f1d1d80}.bg-rose-500\/20{background-color:#f43f5e33}.bg-rose-500\/5{background-color:#f43f5e0d}.bg-slate-700{--tw-bg-opacity: 1;background-color:rgb(51 65 85 / var(--tw-bg-opacity, 1))}.bg-slate-700\/80{background-color:#334155cc}.bg-slate-800{--tw-bg-opacity: 1;background-color:rgb(30 41 59 / var(--tw-bg-opacity, 1))}.bg-status-dead{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.bg-status-healthy{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-status-stuck{--tw-bg-opacity: 1;background-color:rgb(249 115 22 / var(--tw-bg-opacity, 1))}.bg-status-warning{--tw-bg-opacity: 1;background-color:rgb(234 179 8 / var(--tw-bg-opacity, 1))}.bg-surface{--tw-bg-opacity: 1;background-color:rgb(var(--color-base) / var(--tw-bg-opacity, 1))}.bg-surface-emphasis{--tw-bg-opacity: 1;background-color:rgb(var(--color-emphasis) / var(--tw-bg-opacity, 1))}.bg-surface-overlay{--tw-bg-opacity: 1;background-color:rgb(var(--color-overlay) / var(--tw-bg-opacity, 1))}.bg-surface-overlay\/30{background-color:rgb(var(--color-overlay) / .3)}.bg-surface-overlay\/50{background-color:rgb(var(--color-overlay) / .5)}.bg-surface-raised{--tw-bg-opacity: 1;background-color:rgb(var(--color-raised) / var(--tw-bg-opacity, 1))}.bg-surface-raised\/50{background-color:rgb(var(--color-raised) / .5)}.bg-surface-raised\/80{background-color:rgb(var(--color-raised) / .8)}.bg-surface\/30{background-color:rgb(var(--color-base) / .3)}.bg-surface\/50{background-color:rgb(var(--color-base) / .5)}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-yellow-400{--tw-bg-opacity: 1;background-color:rgb(250 204 21 / var(--tw-bg-opacity, 1))}.bg-yellow-500{--tw-bg-opacity: 1;background-color:rgb(234 179 8 / var(--tw-bg-opacity, 1))}.bg-yellow-600{--tw-bg-opacity: 1;background-color:rgb(202 138 4 / var(--tw-bg-opacity, 1))}.bg-yellow-900{--tw-bg-opacity: 1;background-color:rgb(113 63 18 / var(--tw-bg-opacity, 1))}.bg-yellow-900\/20{background-color:#713f1233}.bg-yellow-900\/30{background-color:#713f124d}.bg-yellow-900\/50{background-color:#713f1280}.bg-opacity-20{--tw-bg-opacity: .2}.bg-opacity-50{--tw-bg-opacity: .5}.bg-\[radial-gradient\(circle_at_50\%_50\%\,\#3b82f6_0\%\,transparent_70\%\)\]{background-image:radial-gradient(circle at 50% 50%,#3b82f6 0%,transparent 70%)}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.from-divider{--tw-gradient-from: rgb(var(--color-divider) / 1) var(--tw-gradient-from-position);--tw-gradient-to: rgb(var(--color-divider) / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-divider-strong{--tw-gradient-from: rgb(var(--color-divider-strong) / 1) var(--tw-gradient-from-position);--tw-gradient-to: rgb(var(--color-divider-strong) / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-purple-500{--tw-gradient-from: #a855f7 var(--tw-gradient-from-position);--tw-gradient-to: rgb(168 85 247 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-purple-500\/20{--tw-gradient-from: rgb(168 85 247 / .2) var(--tw-gradient-from-position);--tw-gradient-to: rgb(168 85 247 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.via-blue-500{--tw-gradient-to: rgb(59 130 246 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), #3b82f6 var(--tw-gradient-via-position), var(--tw-gradient-to)}.to-blue-500{--tw-gradient-to: #3b82f6 var(--tw-gradient-to-position)}.to-blue-500\/20{--tw-gradient-to: rgb(59 130 246 / .2) var(--tw-gradient-to-position)}.to-divider{--tw-gradient-to: rgb(var(--color-divider) / 1) var(--tw-gradient-to-position)}.to-divider-strong{--tw-gradient-to: rgb(var(--color-divider-strong) / 1) var(--tw-gradient-to-position)}.fill-current{fill:currentColor}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-0{padding-left:0;padding-right:0}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.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-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-0{padding-top:0;padding-bottom:0}.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-16{padding-top:4rem;padding-bottom:4rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-3\.5{padding-top:.875rem;padding-bottom:.875rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-2{padding-bottom:.5rem}.pb-3{padding-bottom:.75rem}.pb-32{padding-bottom:8rem}.pb-4{padding-bottom:1rem}.pl-2{padding-left:.5rem}.pl-8{padding-left:2rem}.pr-10{padding-right:2.5rem}.pr-16{padding-right:4rem}.pt-1\.5{padding-top:.375rem}.pt-2{padding-top:.5rem}.pt-3{padding-top:.75rem}.pt-4{padding-top:1rem}.pt-5{padding-top:1.25rem}.pt-\[15vh\]{padding-top:15vh}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.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-3xl{font-size:1.875rem;line-height:2.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[14px\]{font-size:14px}.text-\[16px\]{font-size:16px}.text-\[18px\]{font-size:18px}.text-\[8px\]{font-size:8px}.text-\[9px\]{font-size:9px}.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-black{font-weight:900}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.italic{font-style:italic}.leading-relaxed{line-height:1.625}.leading-tight{line-height:1.25}.tracking-tight{letter-spacing:-.025em}.tracking-tighter{letter-spacing:-.05em}.tracking-wider{letter-spacing:.05em}.tracking-widest{letter-spacing:.1em}.text-\[\#10b981\]{--tw-text-opacity: 1;color:rgb(16 185 129 / var(--tw-text-opacity, 1))}.text-\[\#3b82f6\]{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.text-\[\#a078f7\]{--tw-text-opacity: 1;color:rgb(160 120 247 / var(--tw-text-opacity, 1))}.text-\[\#fbbf24\],.text-amber-400{--tw-text-opacity: 1;color:rgb(251 191 36 / var(--tw-text-opacity, 1))}.text-amber-400\/60{color:#fbbf2499}.text-amber-400\/70{color:#fbbf24b3}.text-amber-500{--tw-text-opacity: 1;color:rgb(245 158 11 / var(--tw-text-opacity, 1))}.text-black{--tw-text-opacity: 1;color:rgb(0 0 0 / var(--tw-text-opacity, 1))}.text-blue-300{--tw-text-opacity: 1;color:rgb(147 197 253 / var(--tw-text-opacity, 1))}.text-blue-400{--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.text-blue-500{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-content{--tw-text-opacity: 1;color:rgb(var(--color-heading) / var(--tw-text-opacity, 1))}.text-content-body{--tw-text-opacity: 1;color:rgb(var(--color-body) / var(--tw-text-opacity, 1))}.text-content-muted{--tw-text-opacity: 1;color:rgb(var(--color-muted) / var(--tw-text-opacity, 1))}.text-content-subtle{--tw-text-opacity: 1;color:rgb(var(--color-subtle) / var(--tw-text-opacity, 1))}.text-cyan-400{--tw-text-opacity: 1;color:rgb(34 211 238 / var(--tw-text-opacity, 1))}.text-emerald-300{--tw-text-opacity: 1;color:rgb(110 231 183 / var(--tw-text-opacity, 1))}.text-emerald-400{--tw-text-opacity: 1;color:rgb(52 211 153 / var(--tw-text-opacity, 1))}.text-gray-300{--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}.text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-green-300{--tw-text-opacity: 1;color:rgb(134 239 172 / var(--tw-text-opacity, 1))}.text-green-400{--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.text-green-500{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.text-green-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-orange-200{--tw-text-opacity: 1;color:rgb(254 215 170 / var(--tw-text-opacity, 1))}.text-orange-300{--tw-text-opacity: 1;color:rgb(253 186 116 / var(--tw-text-opacity, 1))}.text-orange-400{--tw-text-opacity: 1;color:rgb(251 146 60 / var(--tw-text-opacity, 1))}.text-orange-500{--tw-text-opacity: 1;color:rgb(249 115 22 / var(--tw-text-opacity, 1))}.text-purple-300{--tw-text-opacity: 1;color:rgb(216 180 254 / var(--tw-text-opacity, 1))}.text-purple-400{--tw-text-opacity: 1;color:rgb(192 132 252 / var(--tw-text-opacity, 1))}.text-purple-500{--tw-text-opacity: 1;color:rgb(168 85 247 / var(--tw-text-opacity, 1))}.text-red-300{--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}.text-red-400{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.text-red-400\/60{color:#f8717199}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-rose-400{--tw-text-opacity: 1;color:rgb(251 113 133 / var(--tw-text-opacity, 1))}.text-slate-200{--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity, 1))}.text-slate-300{--tw-text-opacity: 1;color:rgb(203 213 225 / var(--tw-text-opacity, 1))}.text-slate-500{--tw-text-opacity: 1;color:rgb(100 116 139 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-yellow-300{--tw-text-opacity: 1;color:rgb(253 224 71 / var(--tw-text-opacity, 1))}.text-yellow-400{--tw-text-opacity: 1;color:rgb(250 204 21 / var(--tw-text-opacity, 1))}.text-yellow-500{--tw-text-opacity: 1;color:rgb(234 179 8 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.placeholder-gray-400::-moz-placeholder{--tw-placeholder-opacity: 1;color:rgb(156 163 175 / var(--tw-placeholder-opacity, 1))}.placeholder-gray-400::placeholder{--tw-placeholder-opacity: 1;color:rgb(156 163 175 / var(--tw-placeholder-opacity, 1))}.accent-\[\#a078f7\]{accent-color:#a078f7}.opacity-0{opacity:0}.opacity-10{opacity:.1}.opacity-100{opacity:1}.opacity-25{opacity:.25}.opacity-30{opacity:.3}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-75{opacity:.75}.opacity-90{opacity:.9}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px 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-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px 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-\[0_-2px_10px_rgba\(0\,0\,0\,0\.05\)\]{--tw-shadow: 0 -2px 10px rgba(0,0,0,.05);--tw-shadow-colored: 0 -2px 10px 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-\[0_0_15px_rgba\(59\,130\,246\,0\.1\)\]{--tw-shadow: 0 0 15px rgba(59,130,246,.1);--tw-shadow-colored: 0 0 15px 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-\[0_0_20px_rgba\(59\,130\,246\,0\.4\)\]{--tw-shadow: 0 0 20px rgba(59,130,246,.4);--tw-shadow-colored: 0 0 20px 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-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)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px 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-\[\#a078f7\]\/20{--tw-shadow-color: rgb(160 120 247 / .2);--tw-shadow: var(--tw-shadow-colored)}.shadow-blue-500\/20{--tw-shadow-color: rgb(59 130 246 / .2);--tw-shadow: var(--tw-shadow-colored)}.shadow-blue-500\/5{--tw-shadow-color: rgb(59 130 246 / .05);--tw-shadow: var(--tw-shadow-colored)}.outline{outline-style:solid}.ring-2{--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)}.ring-blue-500{--tw-ring-opacity: 1;--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1))}.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)}.backdrop-blur-md{--tw-backdrop-blur: blur(12px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.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}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-1000{transition-duration:1s}.duration-150{transition-duration:.15s}.duration-300{transition-duration:.3s}.duration-500{transition-duration:.5s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}body{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.scrollbar-hide{-ms-overflow-style:none;scrollbar-width:none}.scrollbar-hide::-webkit-scrollbar{display:none}.terminal-output{font-family:SF Mono,Monaco,Cascadia Code,Roboto Mono,Consolas,monospace;font-size:13px;line-height:1.5}.last\:border-b-0:last-child{border-bottom-width:0px}.hover\:w-1\.5:hover{width:.375rem}.hover\:border-\[\#a078f7\]:hover{--tw-border-opacity: 1;border-color:rgb(160 120 247 / var(--tw-border-opacity, 1))}.hover\:border-amber-500\/50:hover{border-color:#f59e0b80}.hover\:border-divider-strong:hover{--tw-border-opacity: 1;border-color:rgb(var(--color-divider-strong) / var(--tw-border-opacity, 1))}.hover\:border-emerald-500\/50:hover{border-color:#10b98180}.hover\:border-rose-500\/50:hover{border-color:#f43f5e80}.hover\:bg-\[\#a078f7\]\/90:hover{background-color:#a078f7e6}.hover\:bg-amber-500:hover{--tw-bg-opacity: 1;background-color:rgb(245 158 11 / var(--tw-bg-opacity, 1))}.hover\:bg-amber-500\/10:hover{background-color:#f59e0b1a}.hover\:bg-blue-400:hover{--tw-bg-opacity: 1;background-color:rgb(96 165 250 / var(--tw-bg-opacity, 1))}.hover\:bg-blue-500:hover{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))}.hover\:bg-blue-500\/10:hover{background-color:#3b82f61a}.hover\:bg-blue-500\/20:hover{background-color:#3b82f633}.hover\:bg-blue-700:hover{--tw-bg-opacity: 1;background-color:rgb(29 78 216 / var(--tw-bg-opacity, 1))}.hover\:bg-blue-900\/40:hover{background-color:#1e3a8a66}.hover\:bg-blue-900\/50:hover{background-color:#1e3a8a80}.hover\:bg-divider-strong:hover{--tw-bg-opacity: 1;background-color:rgb(var(--color-divider-strong) / var(--tw-bg-opacity, 1))}.hover\:bg-emerald-500\/10:hover{background-color:#10b9811a}.hover\:bg-emerald-500\/20:hover{background-color:#10b98133}.hover\:bg-gray-700:hover{--tw-bg-opacity: 1;background-color:rgb(55 65 81 / var(--tw-bg-opacity, 1))}.hover\:bg-green-500:hover{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.hover\:bg-green-600\/30:hover{background-color:#16a34a4d}.hover\:bg-green-900\/40:hover{background-color:#14532d66}.hover\:bg-green-900\/50:hover{background-color:#14532d80}.hover\:bg-orange-500:hover{--tw-bg-opacity: 1;background-color:rgb(249 115 22 / var(--tw-bg-opacity, 1))}.hover\:bg-orange-600\/30:hover{background-color:#ea580c4d}.hover\:bg-orange-700:hover{--tw-bg-opacity: 1;background-color:rgb(194 65 12 / var(--tw-bg-opacity, 1))}.hover\:bg-orange-900\/50:hover{background-color:#7c2d1280}.hover\:bg-purple-500:hover{--tw-bg-opacity: 1;background-color:rgb(168 85 247 / var(--tw-bg-opacity, 1))}.hover\:bg-purple-900\/40:hover{background-color:#581c8766}.hover\:bg-red-500:hover{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.hover\:bg-red-600:hover{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.hover\:bg-red-600\/30:hover{background-color:#dc26264d}.hover\:bg-red-700:hover{--tw-bg-opacity: 1;background-color:rgb(185 28 28 / var(--tw-bg-opacity, 1))}.hover\:bg-red-900:hover{--tw-bg-opacity: 1;background-color:rgb(127 29 29 / var(--tw-bg-opacity, 1))}.hover\:bg-red-900\/50:hover{background-color:#7f1d1d80}.hover\:bg-rose-500\/10:hover{background-color:#f43f5e1a}.hover\:bg-slate-600\/80:hover{background-color:#475569cc}.hover\:bg-slate-700:hover{--tw-bg-opacity: 1;background-color:rgb(51 65 85 / var(--tw-bg-opacity, 1))}.hover\:bg-surface:hover{--tw-bg-opacity: 1;background-color:rgb(var(--color-base) / var(--tw-bg-opacity, 1))}.hover\:bg-surface-emphasis:hover{--tw-bg-opacity: 1;background-color:rgb(var(--color-emphasis) / var(--tw-bg-opacity, 1))}.hover\:bg-surface-overlay:hover{--tw-bg-opacity: 1;background-color:rgb(var(--color-overlay) / var(--tw-bg-opacity, 1))}.hover\:bg-surface-overlay\/30:hover{background-color:rgb(var(--color-overlay) / .3)}.hover\:bg-surface-overlay\/50:hover{background-color:rgb(var(--color-overlay) / .5)}.hover\:bg-surface-raised:hover{--tw-bg-opacity: 1;background-color:rgb(var(--color-raised) / var(--tw-bg-opacity, 1))}.hover\:bg-yellow-500:hover{--tw-bg-opacity: 1;background-color:rgb(234 179 8 / var(--tw-bg-opacity, 1))}.hover\:bg-yellow-900:hover{--tw-bg-opacity: 1;background-color:rgb(113 63 18 / var(--tw-bg-opacity, 1))}.hover\:bg-opacity-30:hover{--tw-bg-opacity: .3}.hover\:text-\[\#a078f7\]:hover{--tw-text-opacity: 1;color:rgb(160 120 247 / var(--tw-text-opacity, 1))}.hover\:text-amber-300:hover{--tw-text-opacity: 1;color:rgb(252 211 77 / var(--tw-text-opacity, 1))}.hover\:text-amber-400:hover{--tw-text-opacity: 1;color:rgb(251 191 36 / var(--tw-text-opacity, 1))}.hover\:text-blue-300:hover{--tw-text-opacity: 1;color:rgb(147 197 253 / var(--tw-text-opacity, 1))}.hover\:text-blue-400:hover{--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.hover\:text-content:hover{--tw-text-opacity: 1;color:rgb(var(--color-heading) / var(--tw-text-opacity, 1))}.hover\:text-content-body:hover{--tw-text-opacity: 1;color:rgb(var(--color-body) / var(--tw-text-opacity, 1))}.hover\:text-content-subtle:hover{--tw-text-opacity: 1;color:rgb(var(--color-subtle) / var(--tw-text-opacity, 1))}.hover\:text-green-300:hover{--tw-text-opacity: 1;color:rgb(134 239 172 / var(--tw-text-opacity, 1))}.hover\:text-green-400:hover{--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.hover\:text-orange-300:hover{--tw-text-opacity: 1;color:rgb(253 186 116 / var(--tw-text-opacity, 1))}.hover\:text-purple-300:hover{--tw-text-opacity: 1;color:rgb(216 180 254 / var(--tw-text-opacity, 1))}.hover\:text-red-300:hover{--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}.hover\:text-red-400:hover{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.hover\:text-rose-300:hover{--tw-text-opacity: 1;color:rgb(253 164 175 / var(--tw-text-opacity, 1))}.hover\:text-white:hover{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.hover\:text-yellow-300:hover{--tw-text-opacity: 1;color:rgb(253 224 71 / var(--tw-text-opacity, 1))}.hover\:text-yellow-400:hover{--tw-text-opacity: 1;color:rgb(250 204 21 / var(--tw-text-opacity, 1))}.hover\:opacity-80:hover{opacity:.8}.focus\:border-\[\#a078f7\]:focus{--tw-border-opacity: 1;border-color:rgb(160 120 247 / var(--tw-border-opacity, 1))}.focus\:border-blue-500:focus{--tw-border-opacity: 1;border-color:rgb(59 130 246 / var(--tw-border-opacity, 1))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-1: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(1px + 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-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-\[\#a078f7\]:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(160 120 247 / var(--tw-ring-opacity, 1))}.focus\:ring-blue-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1))}.focus\:ring-green-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(34 197 94 / var(--tw-ring-opacity, 1))}.focus\:ring-orange-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(249 115 22 / var(--tw-ring-opacity, 1))}.focus\:ring-purple-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(168 85 247 / var(--tw-ring-opacity, 1))}.focus\:ring-offset-gray-800:focus{--tw-ring-offset-color: #1f2937}.focus\:ring-offset-surface:focus{--tw-ring-offset-color: rgb(var(--color-base) / 1)}.active\:scale-95:active{--tw-scale-x: .95;--tw-scale-y: .95;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))}.active\:cursor-grabbing:active{cursor:grabbing}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:bg-green-800:disabled{--tw-bg-opacity: 1;background-color:rgb(22 101 52 / var(--tw-bg-opacity, 1))}.disabled\:bg-purple-800:disabled{--tw-bg-opacity: 1;background-color:rgb(107 33 168 / var(--tw-bg-opacity, 1))}.disabled\:bg-yellow-800:disabled{--tw-bg-opacity: 1;background-color:rgb(133 77 14 / var(--tw-bg-opacity, 1))}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-50:disabled{opacity:.5}.group:hover .group-hover\:bg-blue-400{--tw-bg-opacity: 1;background-color:rgb(96 165 250 / var(--tw-bg-opacity, 1))}.group:hover .group-hover\:bg-divider{--tw-bg-opacity: 1;background-color:rgb(var(--color-divider) / var(--tw-bg-opacity, 1))}.group:hover .group-hover\:opacity-100{opacity:1}.aria-selected\:bg-surface-overlay[aria-selected=true]{--tw-bg-opacity: 1;background-color:rgb(var(--color-overlay) / var(--tw-bg-opacity, 1))}.prose-headings\:my-2 :is(:where(h1,h2,h3,h4,h5,h6,th):not(:where([class~=not-prose],[class~=not-prose] *))){margin-top:.5rem;margin-bottom:.5rem}.prose-p\:my-2 :is(:where(p):not(:where([class~=not-prose],[class~=not-prose] *))){margin-top:.5rem;margin-bottom:.5rem}.prose-ul\:my-1 :is(:where(ul):not(:where([class~=not-prose],[class~=not-prose] *))){margin-top:.25rem;margin-bottom:.25rem}.prose-li\:my-0 :is(:where(li):not(:where([class~=not-prose],[class~=not-prose] *))){margin-top:0;margin-bottom:0}@media (min-width: 768px){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:items-center{align-items:center}.md\:px-10{padding-left:2.5rem;padding-right:2.5rem}}@media (min-width: 1024px){.lg\:w-2\/5{width:40%}.lg\:w-3\/5{width:60%}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}.lg\:border-b-0{border-bottom-width:0px}.lg\:border-r{border-right-width:1px}}
|