{
"keymap.json": "[\n {\n \"bindings\": {\n \"f12\": [\"zed::IncreaseUiFontSize\", { \"persist\": false }],\n \"secondary-f12\": [\"zed::DecreaseUiFontSize\", { \"persist\": false }],\n \"secondary-1\": \"project_panel::ToggleFocus\",\n \"secondary-2\": \"terminal_panel::ToggleFocus\",\n \"secondary-3\": \"workspace::ToggleRightDock\",\n \"secondary-shift-g\": \"git_panel::ToggleFocus\",\n \"secondary-shift-v\": \"zed::Extensions\",\n \"secondary-p\": \"command_palette::Toggle\",\n \"secondary-o\": \"file_finder::Toggle\",\n \"secondary-9\": \"pane::ActivatePreviousItem\",\n \"secondary-0\": \"pane::ActivateNextItem\",\n \"alt-1\": [\"workspace::ActivatePane\", 0],\n \"alt-2\": [\"workspace::ActivatePane\", 1],\n \"alt-3\": [\"workspace::ActivatePane\", 2],\n \"alt-4\": [\"workspace::ActivatePane\", 3],\n \"alt-5\": [\"workspace::ActivatePane\", 4],\n \"secondary-shift-o\": \"workspace::Open\",\n \"secondary-enter\": \"workspace::ToggleZoom\",\n \"secondary-r\": \"task::Spawn\",\n \"secondary-shift-r\": \"projects::OpenRecent\",\n \"shift-alt-r\": null,\n \"secondary-; k\": \"workspace::Reload\",\n \"secondary-; g\": \"git::FileHistory\",\n \"secondary-; p\": \"git::Push\",\n \"secondary-; secondary-p\": \"git::Pull\",\n \"secondary-; n\": \"git::Branch\",\n \"secondary-; s\": \"git::StashAll\",\n \"secondary-; z\": \"git::StashPop\",\n \"secondary-; a\": \"git::StageAll\",\n \"secondary-; u\": [\n \"task::Spawn\",\n { \"task_name\": \"Zed Settings: Push Now\" }\n ],\n \"secondary-; d\": [\n \"task::Spawn\",\n { \"task_name\": \"Zed Settings: Pull Now\" }\n ],\n \"shift-alt--\": [\n \"task::Spawn\",\n { \"task_name\": \"Toggle excluded files\" }\n ]\n }\n },\n {\n \"context\": \"Workspace\",\n \"bindings\": {\n \"secondary-; c\": \"git_panel::ToggleFocus\"\n }\n },\n {\n \"context\": \"GitPanel\",\n \"bindings\": {\n \"secondary-; c\": \"git_panel::FocusEditor\"\n }\n },\n {\n \"context\": \"Editor && mode == full\",\n \"bindings\": {\n \"secondary-shift-[\": \"editor::Fold\",\n \"secondary-shift-]\": \"editor::UnfoldLines\",\n \"secondary--\": \"editor::FoldAll\",\n \"secondary-=\": \"editor::UnfoldAll\"\n }\n },\n {\n \"context\": \"Editor && extension == md\",\n \"bindings\": {\n \"alt-p\": \"markdown::OpenPreview\",\n \"shift-alt-p\": \"markdown::OpenPreviewToTheSide\"\n }\n },\n {\n \"context\": \"ProjectPanel\",\n \"bindings\": {\n \"alt--\": \"project_panel::CollapseAllEntries\"\n }\n }\n]\n",
"scripts/file-exclusions.json": "{\n \"defaults\": [\n \"**/.git\",\n \"**/.svn\",\n \"**/.hg\",\n \"**/.jj\",\n \"**/CVS\",\n \"**/.DS_Store\",\n \"**/Thumbs.db\",\n \"**/.classpath\",\n \"**/.settings\"\n ],\n \"custom\": [\n \"**/.playwright-cli\",\n \"**/output\",\n \"**/.cursor\",\n \"**/.vscode\",\n \"**/.idea\",\n \"**/.fleet\",\n \"**/node_modules\",\n \"**/bun.lockb\",\n \"**/pnpm-lock.yaml\",\n \"**/package-lock.json\",\n \"**/yarn.lock\",\n \"**/dist\",\n \"**/out\",\n \"**/build\",\n \"**/.next\",\n \"**/.nuxt\",\n \"**/.output\",\n \"**/.cache\",\n \"**/.turbo\",\n \"**/.vercel\",\n \"**/.netlify\",\n \"**/tsconfig.tsbuildinfo\",\n \"**/auto-imports.d.ts\",\n \"**/components.json\",\n \"**/unplugin-vue-components.d.ts\",\n \"src/*.d.ts\",\n \"**/__pycache__\",\n \"**/__init__.py\",\n \"**/.ipynb_checkpoints\",\n \"**/.pytest_cache\",\n \"**/.mypy_cache\",\n \"**/.venv\",\n \"**/env\",\n \"**/venv\",\n \"**/.github\",\n \"**/.husky\",\n \"**/.npmrc\",\n \"**/.eslintrc*\",\n \"**/.prettier*\",\n \"**/.editorconfig\",\n \"**/.dockerignore\",\n \"**/docker-compose.override.yml\",\n \"**/cypress*\",\n \"**/prisma/migrations\"\n ]\n}\n",
"scripts/toggle-file-scan-exclusions.mjs": "import { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { fileURLToPath } from \"node:url\";\n\nconst scriptDirectory = dirname(fileURLToPath(import.meta.url));\n\nasync function exclusionRules() {\n const rulesPath = join(scriptDirectory, \"file-exclusions.json\");\n const rules = JSON.parse(await readFile(rulesPath, \"utf8\"));\n if (!Array.isArray(rules.defaults) || !Array.isArray(rules.custom)) {\n throw new Error(\"file-exclusions.json must contain defaults and custom arrays\");\n }\n return {\n defaults: [...new Set(rules.defaults)],\n custom: [...new Set(rules.custom)].filter(\n (entry) => !rules.defaults.includes(entry),\n ),\n };\n}\n\nfunction settingsPath() {\n if (process.platform === \"win32\") {\n const appData = process.env.APPDATA;\n if (!appData) throw new Error(\"APPDATA is not set\");\n return join(appData, \"Zed\", \"settings.json\");\n }\n return join(homedir(), \".config\", \"zed\", \"settings.json\");\n}\n\nfunction findArrayRange(source) {\n const property = /\"file_scan_exclusions\"\\s*:/g.exec(source);\n if (!property) throw new Error(\"file_scan_exclusions is missing from settings.json\");\n\n const start = source.indexOf(\"[\", property.index + property[0].length);\n if (start === -1) throw new Error(\"file_scan_exclusions is not an array\");\n\n let inString = false;\n let escaped = false;\n let depth = 0;\n for (let index = start; index < source.length; index += 1) {\n const character = source[index];\n if (inString) {\n if (escaped) escaped = false;\n else if (character === \"\\\\\") escaped = true;\n else if (character === '\"') inString = false;\n continue;\n }\n if (character === '\"') inString = true;\n else if (character === \"[\") depth += 1;\n else if (character === \"]\" && --depth === 0) return { start, end: index + 1 };\n }\n throw new Error(\"file_scan_exclusions array is not closed\");\n}\n\nfunction formatArray(values, indent, newline) {\n const itemIndent = `${indent} `;\n const items = values.map((value) => `${itemIndent}${JSON.stringify(value)}`);\n return `[${newline}${items.join(`,${newline}`)}${newline}${indent}]`;\n}\n\nasync function replaceAtomically(path, contents) {\n const temporaryPath = join(dirname(path), `.settings.json.${process.pid}.tmp`);\n try {\n await writeFile(temporaryPath, contents, \"utf8\");\n await rename(temporaryPath, path);\n } finally {\n await rm(temporaryPath, { force: true });\n }\n}\n\nconst path = settingsPath();\nconst { defaults, custom } = await exclusionRules();\nconst source = await readFile(path, \"utf8\");\nconst newline = source.includes(\"\\r\\n\") ? \"\\r\\n\" : \"\\n\";\nconst range = findArrayRange(source);\nconst current = JSON.parse(source.slice(range.start, range.end));\nconst customIsActive = current.some((entry) => !defaults.includes(entry));\nconst next = customIsActive ? defaults : [...defaults, ...custom];\nconst lineStart = source.lastIndexOf(\"\\n\", range.start) + 1;\nconst indent = source.slice(lineStart, range.start).match(/^\\s*/)?.[0] ?? \"\";\nconst updated =\n source.slice(0, range.start) +\n formatArray(next, indent, newline) +\n source.slice(range.end);\n\nawait replaceAtomically(path, updated);\nconsole.log(`Excluded files are now ${customIsActive ? \"shown\" : \"hidden\"}.`);\n",
"scripts/zed-settings-sync.mjs": "import { createHash } from \"node:crypto\";\nimport {\n appendFile,\n copyFile,\n mkdir,\n readFile,\n readdir,\n rename,\n rm,\n stat,\n writeFile,\n} from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport { spawnSync } from \"node:child_process\";\nimport { createInterface } from \"node:readline/promises\";\n\nconst BUNDLE_NAME = \"zed-settings-sync.json\";\nconst GIST_DESCRIPTION = \"Zed settings sync\";\nconst REQUIRED_FILES = [\"settings.json\", \"keymap.json\", \"tasks.json\"];\nconst FIXED_FILES = [\n ...REQUIRED_FILES,\n \"debug.json\",\n \"scripts/toggle-file-scan-exclusions.mjs\",\n \"scripts/file-exclusions.json\",\n \"scripts/zed-settings-sync.mjs\",\n];\nconst OPTIONAL_DIRECTORIES = [\"snippets\", \"themes\"];\nconst LOCAL_SYNC_CONFIG = \"scripts/settings-sync.json\";\nconst DEFAULT_SYNC_CONFIG = {\n gist_id: \"\",\n last_synced_hash: \"\",\n auto_sync: false,\n interval_minutes: 15,\n last_run_at: \"\",\n last_result: \"\",\n};\nconst LOCK_MAX_AGE_MS = 10 * 60 * 1000;\nconst LOG_MAX_BYTES = 1024 * 1024;\nconst SCHEDULER_NAME = \"ZedSettingsSync\";\n\nfunction zedConfigDirectory() {\n if (process.env.ZED_CONFIG_DIR) return resolve(process.env.ZED_CONFIG_DIR);\n if (process.platform === \"win32\") {\n if (!process.env.APPDATA) throw new Error(\"APPDATA is not set\");\n return join(process.env.APPDATA, \"Zed\");\n }\n return join(process.env.XDG_CONFIG_HOME || join(homedir(), \".config\"), \"zed\");\n}\n\nfunction timestamp() {\n return new Date().toISOString().replace(/[:.]/g, \"-\");\n}\n\nfunction now() {\n return new Date().toISOString();\n}\n\nasync function writeAtomically(path, contents) {\n await mkdir(dirname(path), { recursive: true });\n const temporaryPath = join(dirname(path), `.${basename(path)}.${process.pid}.tmp`);\n try {\n await writeFile(temporaryPath, contents, \"utf8\");\n await rename(temporaryPath, path);\n } finally {\n await rm(temporaryPath, { force: true });\n }\n}\n\nasync function listFilesRecursively(directory, prefix) {\n if (!existsSync(directory)) return [];\n const results = [];\n for (const entry of await readdir(directory, { withFileTypes: true })) {\n const absolutePath = join(directory, entry.name);\n const relativePath = `${prefix}/${entry.name}`;\n if (entry.isDirectory()) results.push(...await listFilesRecursively(absolutePath, relativePath));\n else if (entry.isFile()) results.push(relativePath);\n }\n return results;\n}\n\nasync function synchronizedPaths(configDirectory) {\n const paths = FIXED_FILES.filter((path) => existsSync(join(configDirectory, ...path.split(\"/\"))));\n for (const directory of OPTIONAL_DIRECTORIES) {\n paths.push(...await listFilesRecursively(join(configDirectory, directory), directory));\n }\n return [...new Set(paths)].sort();\n}\n\nfunction isAllowedBundlePath(path) {\n if (typeof path !== \"string\" || path.startsWith(\"/\") || path.includes(\"\\\\\")) return false;\n const segments = path.split(\"/\");\n if (segments.some((segment) => !segment || segment === \".\" || segment === \"..\")) return false;\n if (FIXED_FILES.includes(path) || path === LOCAL_SYNC_CONFIG) return true;\n return OPTIONAL_DIRECTORIES.some((directory) => path.startsWith(`${directory}/`));\n}\n\nfunction replaceTaskPath(source, path, placeholder) {\n return source\n .replaceAll(path.replaceAll(\"\\\\\", \"\\\\\\\\\"), placeholder)\n .replaceAll(path.replaceAll(\"\\\\\", \"/\"), placeholder);\n}\n\nfunction portableTasks(source, configDirectory) {\n return replaceTaskPath(\n replaceTaskPath(\n source,\n join(configDirectory, \"scripts\", \"toggle-file-scan-exclusions.mjs\"),\n \"__TOGGLE_SCRIPT__\",\n ),\n join(configDirectory, \"scripts\", \"zed-settings-sync.mjs\"),\n \"__SYNC_SCRIPT__\",\n );\n}\n\nfunction installedTasks(source, configDirectory) {\n return source\n .replaceAll(\n \"__TOGGLE_SCRIPT__\",\n join(configDirectory, \"scripts\", \"toggle-file-scan-exclusions.mjs\").replaceAll(\"\\\\\", \"/\"),\n )\n .replaceAll(\n \"__SYNC_SCRIPT__\",\n join(configDirectory, \"scripts\", \"zed-settings-sync.mjs\").replaceAll(\"\\\\\", \"/\"),\n );\n}\n\nfunction hashContents(contents) {\n return createHash(\"sha256\").update(contents).digest(\"hex\");\n}\n\nasync function createBundle() {\n const configDirectory = zedConfigDirectory();\n const files = {};\n for (const relativePath of await synchronizedPaths(configDirectory)) {\n const absolutePath = join(configDirectory, ...relativePath.split(\"/\"));\n let contents = await readFile(absolutePath, \"utf8\");\n if (relativePath === \"tasks.json\") contents = portableTasks(contents, configDirectory);\n files[relativePath] = contents;\n }\n for (const required of REQUIRED_FILES) {\n if (!(required in files)) throw new Error(`Cannot export: ${required} is missing`);\n }\n const contents = serializeBundle(files);\n return { files, contents, hash: hashContents(contents) };\n}\n\nfunction serializeBundle(files) {\n return `${JSON.stringify(files, null, 2)}\\n`;\n}\n\nfunction parseBundle(contents, sourceName) {\n let files;\n try {\n files = JSON.parse(contents);\n } catch (error) {\n throw new Error(`Invalid JSON in ${sourceName}: ${error.message}`);\n }\n if (!files || Array.isArray(files) || typeof files !== \"object\") {\n throw new Error(`Invalid Zed settings bundle: ${sourceName}`);\n }\n for (const required of REQUIRED_FILES) {\n if (typeof files[required] !== \"string\") throw new Error(`Invalid bundle: ${required} is missing`);\n }\n for (const [path, value] of Object.entries(files)) {\n if (!isAllowedBundlePath(path) || typeof value !== \"string\") {\n throw new Error(`Invalid bundle file: ${path}`);\n }\n }\n return { files, hash: hashContents(contents) };\n}\n\nasync function exportBundle(path) {\n const bundle = await createBundle();\n await writeAtomically(path, bundle.contents);\n console.log(`Exported Zed settings to ${path}`);\n console.log(`SHA-256: ${bundle.hash}`);\n return bundle;\n}\n\nasync function backupCurrentConfiguration(configDirectory) {\n const backupDirectory = join(configDirectory, \"backups\", `sync-import-${timestamp()}`);\n await mkdir(backupDirectory, { recursive: true });\n for (const relativePath of await synchronizedPaths(configDirectory)) {\n const source = join(configDirectory, ...relativePath.split(\"/\"));\n const destination = join(backupDirectory, ...relativePath.split(\"/\"));\n await mkdir(dirname(destination), { recursive: true });\n await copyFile(source, destination);\n }\n return backupDirectory;\n}\n\nasync function installBundleContents(contents, sourceName) {\n const parsed = parseBundle(contents, sourceName);\n const configDirectory = zedConfigDirectory();\n const backupDirectory = await backupCurrentConfiguration(configDirectory);\n for (const [relativePath, sourceContents] of Object.entries(parsed.files)) {\n if (relativePath === LOCAL_SYNC_CONFIG) continue;\n const destination = join(configDirectory, ...relativePath.split(\"/\"));\n const installedContents = relativePath === \"tasks.json\"\n ? installedTasks(sourceContents, configDirectory)\n : sourceContents;\n await writeAtomically(destination, installedContents);\n }\n console.log(`Imported Zed settings from ${sourceName}`);\n console.log(`Previous settings were backed up to ${backupDirectory}`);\n return { ...parsed, backupDirectory };\n}\n\nasync function importBundle(path) {\n return installBundleContents(await readFile(path, \"utf8\"), path);\n}\n\nfunction runPowerShell(command, extraEnv = {}) {\n const result = spawnSync(\"powershell.exe\", [\"-NoProfile\", \"-STA\", \"-Command\", command], {\n encoding: \"utf8\",\n env: { ...process.env, ...extraEnv },\n windowsHide: false,\n });\n if (result.status !== 0) throw new Error(result.stderr.trim() || \"Windows dialog failed\");\n return result.stdout.trim();\n}\n\nfunction nativeFileDialog(mode) {\n if (process.env.ZED_SYNC_NO_DIALOGS === \"1\") return \"\";\n if (process.platform === \"win32\") {\n const common = \"[Console]::OutputEncoding=[Text.Encoding]::UTF8; Add-Type -AssemblyName System.Windows.Forms; $o=New-Object System.Windows.Forms.Form; $o.TopMost=$true; $o.ShowInTaskbar=$false; $o.Opacity=0; $o.Show(); $o.Activate(); \";\n const command = mode === \"save\"\n ? `${common}$d=New-Object System.Windows.Forms.SaveFileDialog; $d.Filter='Zed settings (*.json)|*.json'; $d.FileName='${BUNDLE_NAME}'; $d.AddExtension=$true; if($d.ShowDialog($o) -eq 'OK'){[Console]::Write($d.FileName)}; $o.Close()`\n : `${common}$d=New-Object System.Windows.Forms.OpenFileDialog; $d.Filter='Zed settings (*.json)|*.json'; $d.FileName='${BUNDLE_NAME}'; if($d.ShowDialog($o) -eq 'OK'){[Console]::Write($d.FileName)}; $o.Close()`;\n return runPowerShell(command);\n }\n if (process.platform === \"darwin\") {\n const script = mode === \"save\"\n ? `POSIX path of (choose file name with prompt \"Export Zed settings\" default name \"${BUNDLE_NAME}\")`\n : \"POSIX path of (choose file with prompt \\\"Import Zed settings\\\")\";\n const result = spawnSync(\"osascript\", [\"-e\", script], { encoding: \"utf8\" });\n return result.status === 0 ? result.stdout.trim() : \"\";\n }\n const args = [\"--file-selection\", `--title=${mode === \"save\" ? \"Export\" : \"Import\"} Zed settings`];\n if (mode === \"save\") args.push(\"--save\", \"--confirm-overwrite\", `--filename=${BUNDLE_NAME}`);\n const result = spawnSync(\"zenity\", args, { encoding: \"utf8\" });\n return result.status === 0 ? result.stdout.trim() : \"\";\n}\n\nasync function readSyncConfiguration() {\n const path = join(zedConfigDirectory(), ...LOCAL_SYNC_CONFIG.split(\"/\"));\n let source = {};\n try {\n source = JSON.parse(await readFile(path, \"utf8\"));\n } catch (error) {\n if (error.code !== \"ENOENT\") throw error;\n }\n return {\n path,\n config: {\n ...DEFAULT_SYNC_CONFIG,\n gist_id: typeof source.gist_id === \"string\" ? source.gist_id : \"\",\n last_synced_hash: typeof source.last_synced_hash === \"string\" ? source.last_synced_hash : \"\",\n auto_sync: source.auto_sync === true,\n interval_minutes: Number.isInteger(source.interval_minutes) && source.interval_minutes >= 5\n ? source.interval_minutes\n : DEFAULT_SYNC_CONFIG.interval_minutes,\n last_run_at: typeof source.last_run_at === \"string\" ? source.last_run_at : \"\",\n last_result: typeof source.last_result === \"string\" ? source.last_result : \"\",\n },\n };\n}\n\nasync function saveSyncConfiguration(path, config) {\n await writeAtomically(path, `${JSON.stringify(config, null, 2)}\\n`);\n}\n\nfunction normalizeGistId(value) {\n const matches = value.trim().match(/[a-f0-9]{8,}/gi);\n if (!matches?.length) throw new Error(\"Enter a valid GitHub Gist ID or URL\");\n return matches.at(-1).toLowerCase();\n}\n\nfunction sanitizedEnvironment() {\n const env = { ...process.env };\n delete env.GH_TOKEN;\n delete env.GITHUB_TOKEN;\n return env;\n}\n\nfunction execute(command, args, options = {}) {\n return spawnSync(command, args, {\n encoding: options.stdio === \"inherit\" ? undefined : \"utf8\",\n env: options.env || process.env,\n input: options.input,\n stdio: options.stdio || \"pipe\",\n windowsHide: options.windowsHide ?? true,\n });\n}\n\nfunction ghMissingMessage() {\n if (process.platform === \"win32\") return \"GitHub CLI is required. Install it with: winget install GitHub.cli\";\n if (process.platform === \"darwin\") return \"GitHub CLI is required. Install it with: brew install gh\";\n return \"GitHub CLI is required. Install it from https://cli.github.com/\";\n}\n\nfunction executeGh(args, options = {}) {\n if (process.env.ZED_SYNC_GH_SCRIPT) {\n return execute(process.execPath, [process.env.ZED_SYNC_GH_SCRIPT, ...args], options);\n }\n return execute(\"gh\", args, options);\n}\n\nfunction testGhAuthentication(env) {\n const user = executeGh([\"api\", \"user\", \"--jq\", \".login\"], { env });\n if (user.error?.code === \"ENOENT\") return { ok: false, missing: true, message: ghMissingMessage() };\n if (user.status !== 0) {\n return { ok: false, login: \"\", message: (user.stderr || user.stdout || \"GitHub authentication failed\").trim() };\n }\n const gists = executeGh([\"api\", \"gists?per_page=1\", \"--silent\"], { env });\n return {\n ok: gists.status === 0,\n login: user.stdout.trim(),\n message: gists.status === 0 ? \"\" : (gists.stderr || gists.stdout || \"The GitHub credential cannot access Gists\").trim(),\n };\n}\n\nasync function resolveGhAuthentication({ interactive = false, requireStored = false } = {}) {\n const hasEnvironmentToken = Boolean(process.env.GH_TOKEN || process.env.GITHUB_TOKEN);\n if (!requireStored) {\n const current = testGhAuthentication(process.env);\n if (current.missing) throw new Error(current.message);\n if (current.ok) {\n return { env: process.env, login: current.login, source: hasEnvironmentToken ? \"environment\" : \"credential-store\" };\n }\n if (hasEnvironmentToken) console.log(\"The inherited GitHub token is invalid; trying stored GitHub CLI credentials.\");\n }\n\n const cleanEnv = sanitizedEnvironment();\n const stored = testGhAuthentication(cleanEnv);\n if (stored.missing) throw new Error(stored.message);\n if (stored.ok) return { env: cleanEnv, login: stored.login, source: \"credential-store\" };\n if (!interactive) throw new Error(\"GitHub is not authenticated. Run 'Zed Settings: Set Up / Reconfigure Sync...'.\");\n\n console.log(\"Opening GitHub browser authentication. No personal access token needs to be pasted.\");\n const authenticationArgs = stored.login\n ? [\"auth\", \"refresh\", \"--hostname\", \"github.com\", \"--scopes\", \"gist\"]\n : [\"auth\", \"login\", \"--hostname\", \"github.com\", \"--web\", \"--clipboard\", \"--scopes\", \"gist\"];\n const login = executeGh(\n authenticationArgs,\n { env: cleanEnv, stdio: \"inherit\", windowsHide: false },\n );\n if (login.status !== 0) throw new Error(\"GitHub browser authentication was cancelled or failed.\");\n const verified = testGhAuthentication(cleanEnv);\n if (!verified.ok) throw new Error(verified.message || \"GitHub authentication could not be verified.\");\n return { env: cleanEnv, login: verified.login, source: \"credential-store\" };\n}\n\nfunction runGh(args, auth, input) {\n const result = executeGh(args, { env: auth.env, input });\n if (result.error?.code === \"ENOENT\") throw new Error(ghMissingMessage());\n if (result.status !== 0) throw new Error((result.stderr || result.stdout || `gh ${args[0]} failed`).trim());\n return result.stdout.trim();\n}\n\nfunction readRemoteGist(gistId, auth) {\n const gist = JSON.parse(runGh([\"api\", `gists/${gistId}`], auth));\n const file = gist.files?.[BUNDLE_NAME];\n if (!file) return { gist, parsed: null, contents: null };\n if (file.truncated) throw new Error(`${BUNDLE_NAME} is too large to read through the Gist API`);\n return { gist, parsed: parseBundle(file.content, `Gist ${gistId}`), contents: file.content };\n}\n\nfunction updateRemoteGist(gistId, contents, auth) {\n const payload = JSON.stringify({ files: { [BUNDLE_NAME]: { content: contents } } });\n return JSON.parse(runGh([\"api\", \"--method\", \"PATCH\", `gists/${gistId}`, \"--input\", \"-\"], auth, payload));\n}\n\nfunction createRemoteGist(contents, auth) {\n const payload = JSON.stringify({\n description: GIST_DESCRIPTION,\n public: false,\n files: { [BUNDLE_NAME]: { content: contents } },\n });\n return JSON.parse(runGh([\"api\", \"--method\", \"POST\", \"gists\", \"--input\", \"-\"], auth, payload));\n}\n\nfunction discoverGists(auth) {\n const raw = runGh([\"api\", \"--paginate\", \"--slurp\", \"gists?per_page=100\"], auth);\n const pages = JSON.parse(raw);\n const gists = (Array.isArray(pages[0]) ? pages.flat() : pages)\n .filter((gist) => gist.files?.[BUNDLE_NAME])\n .sort((a, b) => String(b.updated_at).localeCompare(String(a.updated_at)));\n return gists;\n}\n\nfunction shortHash(hash) {\n return hash ? hash.slice(0, 12) : \"none\";\n}\n\nfunction classifySync(localHash, remoteHash, lastHash) {\n if (!remoteHash) return \"remote-missing\";\n if (localHash === remoteHash) return \"synchronized\";\n if (!lastHash) return \"no-baseline\";\n if (localHash === lastHash) return \"remote-changed\";\n if (remoteHash === lastHash) return \"local-changed\";\n return \"conflict\";\n}\n\nlet scriptedAnswers;\nasync function ask(question, defaultValue = \"\") {\n if (scriptedAnswers === undefined) {\n try {\n scriptedAnswers = JSON.parse(process.env.ZED_SYNC_ANSWERS || \"[]\");\n } catch {\n scriptedAnswers = [];\n }\n }\n if (scriptedAnswers.length) {\n const answer = String(scriptedAnswers.shift());\n console.log(`${question}${answer}`);\n return answer;\n }\n if (!process.stdin.isTTY) throw new Error(\"Interactive input is required. Run this command from the Zed Task Picker.\");\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n try {\n return (await rl.question(question)).trim() || defaultValue;\n } finally {\n rl.close();\n }\n}\n\nasync function askYesNo(question, defaultYes = false) {\n const answer = (await ask(`${question} ${defaultYes ? \"[Y/n]\" : \"[y/N]\"} `, defaultYes ? \"y\" : \"n\")).toLowerCase();\n return answer === \"y\" || answer === \"yes\";\n}\n\nasync function appendLog(message) {\n const logDirectory = join(zedConfigDirectory(), \"logs\");\n const logPath = join(logDirectory, \"settings-sync.log\");\n await mkdir(logDirectory, { recursive: true });\n try {\n if ((await stat(logPath)).size > LOG_MAX_BYTES) {\n await rm(`${logPath}.3`, { force: true });\n if (existsSync(`${logPath}.2`)) await rename(`${logPath}.2`, `${logPath}.3`);\n if (existsSync(`${logPath}.1`)) await rename(`${logPath}.1`, `${logPath}.2`);\n await rename(logPath, `${logPath}.1`);\n }\n } catch (error) {\n if (error.code !== \"ENOENT\") throw error;\n }\n await appendFile(logPath, `${now()} ${message}\\n`, \"utf8\");\n}\n\nasync function recordResult(state, result) {\n state.config.last_run_at = now();\n state.config.last_result = result;\n await saveSyncConfiguration(state.path, state.config);\n await appendLog(result);\n}\n\nfunction notify(message) {\n if (process.env.ZED_SYNC_NO_NOTIFICATIONS === \"1\") return;\n if (process.platform === \"win32\") {\n execute(\"msg.exe\", [process.env.USERNAME || \"*\", message]);\n } else if (process.platform === \"darwin\") {\n const escaped = message.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll('\"', '\\\\\"');\n execute(\"osascript\", [\"-e\", `display notification \"${escaped}\" with title \"Zed Settings Sync\"`]);\n } else {\n execute(\"notify-send\", [\"Zed Settings Sync\", message]);\n }\n}\n\nasync function withSyncLock(action) {\n const lockPath = join(zedConfigDirectory(), \"scripts\", \".settings-sync.lock\");\n try {\n await mkdir(lockPath, { recursive: false });\n } catch (error) {\n if (error.code !== \"EEXIST\") throw error;\n const age = Date.now() - (await stat(lockPath)).mtimeMs;\n if (age <= LOCK_MAX_AGE_MS) {\n console.log(\"Another settings sync is already running.\");\n return null;\n }\n await rm(lockPath, { recursive: true, force: true });\n await mkdir(lockPath);\n }\n try {\n await writeFile(join(lockPath, \"owner.json\"), JSON.stringify({ pid: process.pid, started_at: now() }));\n return await action();\n } finally {\n await rm(lockPath, { recursive: true, force: true });\n }\n}\n\nasync function selectSetupGist(gists, state) {\n console.log(\"\\nAvailable Zed settings Gists:\");\n gists.forEach((gist, index) => {\n const current = gist.id === state.config.gist_id ? \" (current)\" : \"\";\n console.log(` ${index + 1}. ${gist.description || \"Untitled\"} - ${gist.id}${current} - ${gist.updated_at}`);\n });\n console.log(\" N. Create a new Secret Gist from this machine\");\n console.log(\" M. Enter another Gist URL or ID\");\n console.log(\" Q. Cancel\");\n const defaultChoice = gists.length === 1 ? \"1\" : (gists.length === 0 ? \"n\" : \"q\");\n const choice = (await ask(`Choose [${defaultChoice.toUpperCase()}]: `, defaultChoice)).toLowerCase();\n if (choice === \"q\") return { action: \"cancel\" };\n if (choice === \"n\") return { action: \"create\" };\n if (choice === \"m\") return { action: \"existing\", gistId: normalizeGistId(await ask(\"Gist URL or ID: \")) };\n const index = Number.parseInt(choice, 10) - 1;\n if (!Number.isInteger(index) || !gists[index]) throw new Error(\"Invalid Gist selection\");\n return { action: \"existing\", gistId: gists[index].id };\n}\n\nasync function setupSync({ offerAutomaticSync = true } = {}) {\n console.log(\"Zed Settings Sync Setup\\n\");\n const auth = await resolveGhAuthentication({ interactive: true });\n console.log(`Connected to GitHub as ${auth.login} (${auth.source}).`);\n const state = await readSyncConfiguration();\n const gists = discoverGists(auth);\n if (state.config.gist_id && !gists.some((gist) => gist.id === state.config.gist_id)) {\n try {\n gists.unshift(readRemoteGist(state.config.gist_id, auth).gist);\n } catch (error) {\n console.log(`The currently configured Gist could not be loaded: ${error.message}`);\n }\n }\n const selection = await selectSetupGist(gists, state);\n if (selection.action === \"cancel\") {\n console.log(\"Setup cancelled. Local Zed settings remain installed and unchanged.\");\n return;\n }\n\n const local = await createBundle();\n if (selection.action === \"create\") {\n const created = createRemoteGist(local.contents, auth);\n state.config.gist_id = created.id;\n state.config.last_synced_hash = local.hash;\n await recordResult(state, `Created and uploaded Secret Gist ${created.id}`);\n console.log(`\\nCreated Secret Gist: ${created.html_url || created.id}`);\n console.log(`SHA-256: ${local.hash}`);\n } else {\n const remote = readRemoteGist(selection.gistId, auth);\n console.log(`\\nRemote: ${remote.gist.html_url || selection.gistId}`);\n state.config.gist_id = selection.gistId;\n if (!remote.parsed) {\n console.log(`This Gist does not contain ${BUNDLE_NAME}.`);\n if (!await askYesNo(\"Upload this machine's current Zed settings to it?\", true)) return;\n updateRemoteGist(selection.gistId, local.contents, auth);\n state.config.last_synced_hash = local.hash;\n await recordResult(state, `Initialized Gist ${selection.gistId} with this machine's settings`);\n } else {\n console.log(`Local SHA-256: ${shortHash(local.hash)}`);\n console.log(`Remote SHA-256: ${shortHash(remote.parsed.hash)}`);\n console.log(\" P. Pull remote settings onto this machine (backup first)\");\n console.log(\" U. Upload this machine's settings to the Gist\");\n console.log(\" Q. Cancel\");\n const direction = (await ask(\"Initial sync direction [P]: \", \"p\")).toLowerCase();\n if (direction === \"q\") return;\n if (direction === \"p\") {\n if (local.hash !== remote.parsed.hash) await installBundleContents(remote.contents, `Gist ${selection.gistId}`);\n state.config.last_synced_hash = remote.parsed.hash;\n await recordResult(state, `Pulled settings from Gist ${selection.gistId}`);\n } else if (direction === \"u\") {\n updateRemoteGist(selection.gistId, local.contents, auth);\n state.config.last_synced_hash = local.hash;\n await recordResult(state, `Uploaded settings to Gist ${selection.gistId}`);\n } else {\n throw new Error(\"Invalid initial sync direction\");\n }\n }\n await saveSyncConfiguration(state.path, state.config);\n console.log(`Configured Gist ${selection.gistId}.`);\n }\n\n if (offerAutomaticSync) {\n if (await askYesNo(\"Enable automatic synchronization every 15 minutes?\", false)) {\n await enableAutomaticSync();\n } else {\n console.log(\"Automatic synchronization remains disabled. Use Push Now and Pull Now from the Task Picker.\");\n }\n }\n}\n\nasync function requireConfiguredState() {\n const state = await readSyncConfiguration();\n if (state.config.gist_id) return state;\n console.log(\"No Gist is configured. Starting setup...\\n\");\n await setupSync();\n const configured = await readSyncConfiguration();\n return configured.config.gist_id ? configured : null;\n}\n\nasync function pushGist() {\n return withSyncLock(async () => {\n const state = await requireConfiguredState();\n if (!state) return;\n const auth = await resolveGhAuthentication({ interactive: true });\n const local = await createBundle();\n const remote = readRemoteGist(state.config.gist_id, auth);\n const remoteHash = remote.parsed?.hash || \"\";\n const status = classifySync(local.hash, remoteHash, state.config.last_synced_hash);\n if ([\"remote-changed\", \"conflict\", \"no-baseline\"].includes(status)) {\n console.log(`Remote settings differ (${status}).`);\n console.log(`Local: ${shortHash(local.hash)} Remote: ${shortHash(remoteHash)} Last: ${shortHash(state.config.last_synced_hash)}`);\n if (!await askYesNo(\"Overwrite the remote Gist with this machine's settings?\", false)) return;\n }\n updateRemoteGist(state.config.gist_id, local.contents, auth);\n state.config.last_synced_hash = local.hash;\n await recordResult(state, `Uploaded settings to Gist ${state.config.gist_id}`);\n console.log(`Uploaded to ${remote.gist.html_url || state.config.gist_id}`);\n console.log(`SHA-256: ${local.hash}`);\n });\n}\n\nasync function pullGist() {\n return withSyncLock(async () => {\n const state = await requireConfiguredState();\n if (!state) return;\n const auth = await resolveGhAuthentication({ interactive: true });\n const local = await createBundle();\n const remote = readRemoteGist(state.config.gist_id, auth);\n if (!remote.parsed) throw new Error(`Gist ${state.config.gist_id} does not contain ${BUNDLE_NAME}`);\n const status = classifySync(local.hash, remote.parsed.hash, state.config.last_synced_hash);\n if ([\"local-changed\", \"conflict\", \"no-baseline\"].includes(status)) {\n console.log(`Local settings differ (${status}).`);\n console.log(`Local: ${shortHash(local.hash)} Remote: ${shortHash(remote.parsed.hash)} Last: ${shortHash(state.config.last_synced_hash)}`);\n if (!await askYesNo(\"Replace local settings with the Gist version? A backup will be created first.\", false)) return;\n }\n if (local.hash !== remote.parsed.hash) await installBundleContents(remote.contents, `Gist ${state.config.gist_id}`);\n state.config.last_synced_hash = remote.parsed.hash;\n await recordResult(state, `Pulled settings from Gist ${state.config.gist_id}`);\n console.log(`Downloaded from ${remote.gist.html_url || state.config.gist_id}`);\n console.log(`SHA-256: ${remote.parsed.hash}`);\n });\n}\n\nasync function showStatus() {\n const state = await readSyncConfiguration();\n if (!state.config.gist_id) {\n console.log(\"Sync is not configured. Run 'Zed Settings: Set Up / Reconfigure Sync...'.\");\n return;\n }\n const auth = await resolveGhAuthentication();\n const local = await createBundle();\n const remote = readRemoteGist(state.config.gist_id, auth);\n const status = classifySync(local.hash, remote.parsed?.hash || \"\", state.config.last_synced_hash);\n console.log(`Gist: ${remote.gist.html_url || state.config.gist_id}`);\n console.log(`Status: ${status}`);\n console.log(`Automatic sync: ${state.config.auto_sync ? `enabled (${state.config.interval_minutes} minutes)` : \"disabled\"}`);\n console.log(`Local: ${shortHash(local.hash)}`);\n console.log(`Remote: ${shortHash(remote.parsed?.hash || \"\")}`);\n console.log(`Last: ${shortHash(state.config.last_synced_hash)}`);\n console.log(`Last run: ${state.config.last_run_at || \"never\"}`);\n console.log(`Last result: ${state.config.last_result || \"none\"}`);\n}\n\nasync function automaticSync() {\n return withSyncLock(async () => {\n const state = await readSyncConfiguration();\n if (!state.config.auto_sync) return;\n try {\n if (!state.config.gist_id) throw new Error(\"Automatic sync requires setup\");\n const auth = await resolveGhAuthentication({ requireStored: true });\n const local = await createBundle();\n const remote = readRemoteGist(state.config.gist_id, auth);\n const remoteHash = remote.parsed?.hash || \"\";\n const status = classifySync(local.hash, remoteHash, state.config.last_synced_hash);\n if (status === \"synchronized\") {\n await recordResult(state, \"Automatic sync: already synchronized\");\n } else if (status === \"local-changed\") {\n updateRemoteGist(state.config.gist_id, local.contents, auth);\n state.config.last_synced_hash = local.hash;\n await recordResult(state, \"Automatic sync: uploaded local changes\");\n } else if (status === \"remote-changed\") {\n await installBundleContents(remote.contents, `Gist ${state.config.gist_id}`);\n state.config.last_synced_hash = remote.parsed.hash;\n await recordResult(state, \"Automatic sync: downloaded remote changes\");\n } else {\n const result = `Automatic sync stopped: ${status}`;\n const shouldNotify = state.config.last_result !== result;\n await recordResult(state, result);\n if (shouldNotify) notify(`${result}. Open the Zed Task Picker to resolve it.`);\n }\n } catch (error) {\n const result = `Automatic sync failed: ${error.message}`;\n const shouldNotify = state.config.last_result !== result;\n await recordResult(state, result);\n if (shouldNotify) notify(result);\n throw error;\n }\n });\n}\n\nfunction shellQuote(value) {\n return `'${value.replaceAll(\"'\", `'\"'\"'`)}'`;\n}\n\nfunction xmlEscape(value) {\n return value.replaceAll(\"&\", \"&\").replaceAll(\"<\", \"<\").replaceAll(\">\", \">\");\n}\n\nfunction schedulerPlatform() {\n return process.env.ZED_SYNC_PLATFORM || process.platform;\n}\n\nasync function configureScheduler(enable, intervalMinutes) {\n const platform = schedulerPlatform();\n const scriptPath = resolve(process.argv[1]);\n const dryRun = process.env.ZED_SYNC_SCHEDULER_DRY_RUN === \"1\";\n const actions = [];\n const run = (command, args, options = {}) => {\n actions.push([command, ...args].join(\" \"));\n if (dryRun) return { status: 0, stdout: \"\", stderr: \"\" };\n return execute(command, args, options);\n };\n\n if (platform === \"win32\") {\n if (enable) {\n const taskCommand = `\\\"${process.execPath}\\\" \\\"${scriptPath}\\\" auto-sync`;\n const result = run(\"schtasks.exe\", [\"/Create\", \"/SC\", \"MINUTE\", \"/MO\", String(intervalMinutes), \"/TN\", SCHEDULER_NAME, \"/TR\", taskCommand, \"/F\"]);\n if (result.status !== 0) throw new Error((result.stderr || result.stdout || \"Could not create Windows scheduled task\").trim());\n } else {\n run(\"schtasks.exe\", [\"/Delete\", \"/TN\", SCHEDULER_NAME, \"/F\"]);\n }\n } else if (platform === \"darwin\") {\n const plistPath = join(homedir(), \"Library\", \"LaunchAgents\", \"cool.okk.zed-settings-sync.plist\");\n run(\"launchctl\", [\"unload\", plistPath]);\n if (enable) {\n const plist = `\\n\\n\\n Labelcool.okk.zed-settings-sync\\n ProgramArguments${xmlEscape(process.execPath)}${xmlEscape(scriptPath)}auto-sync\\n StartInterval${intervalMinutes * 60}\\n RunAtLoad\\n\\n`;\n if (!dryRun) await writeAtomically(plistPath, plist);\n actions.push(`write ${plistPath}`);\n const result = run(\"launchctl\", [\"load\", plistPath]);\n if (result.status !== 0) throw new Error((result.stderr || \"Could not load LaunchAgent\").trim());\n } else if (!dryRun) {\n await rm(plistPath, { force: true });\n }\n } else {\n const systemdDirectory = join(homedir(), \".config\", \"systemd\", \"user\");\n const servicePath = join(systemdDirectory, \"zed-settings-sync.service\");\n const timerPath = join(systemdDirectory, \"zed-settings-sync.timer\");\n const systemd = run(\"systemctl\", [\"--user\", \"--version\"]);\n const systemdSession = systemd.status === 0\n ? run(\"systemctl\", [\"--user\", \"show-environment\"])\n : { status: 1 };\n if (enable && systemdSession.status === 0) {\n const service = `[Unit]\\nDescription=Synchronize Zed settings\\n\\n[Service]\\nType=oneshot\\nExecStart=\\\"${process.execPath.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll('\"', '\\\\\"')}\\\" \\\"${scriptPath.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll('\"', '\\\\\"')}\\\" auto-sync\\n`;\n const timer = `[Unit]\\nDescription=Synchronize Zed settings every ${intervalMinutes} minutes\\n\\n[Timer]\\nOnBootSec=2min\\nOnUnitActiveSec=${intervalMinutes}min\\nPersistent=true\\n\\n[Install]\\nWantedBy=timers.target\\n`;\n if (!dryRun) {\n await writeAtomically(servicePath, service);\n await writeAtomically(timerPath, timer);\n }\n actions.push(`write ${servicePath}`, `write ${timerPath}`);\n run(\"systemctl\", [\"--user\", \"daemon-reload\"]);\n const result = run(\"systemctl\", [\"--user\", \"enable\", \"--now\", \"zed-settings-sync.timer\"]);\n if (result.status !== 0) throw new Error((result.stderr || \"Could not enable systemd user timer\").trim());\n } else if (!enable) {\n if (systemd.status === 0) run(\"systemctl\", [\"--user\", \"disable\", \"--now\", \"zed-settings-sync.timer\"]);\n if (!dryRun) {\n await rm(servicePath, { force: true });\n await rm(timerPath, { force: true });\n }\n if (systemdSession.status === 0) run(\"systemctl\", [\"--user\", \"daemon-reload\"]);\n const current = run(\"crontab\", [\"-l\"]);\n if (current.status === 0) {\n const lines = current.stdout.split(/\\r?\\n/).filter((line) => line && !line.includes(\"# zed-settings-sync\"));\n run(\"crontab\", [\"-\"], { input: `${lines.join(\"\\n\")}\\n` });\n }\n } else {\n const current = run(\"crontab\", [\"-l\"]);\n const marker = \"# zed-settings-sync\";\n const lines = (current.status === 0 ? current.stdout : \"\").split(/\\r?\\n/).filter((line) => line && !line.includes(marker));\n lines.push(`*/${intervalMinutes} * * * * ${shellQuote(process.execPath)} ${shellQuote(scriptPath)} auto-sync ${marker}`);\n const updated = `${lines.join(\"\\n\")}\\n`;\n const result = run(\"crontab\", [\"-\"], { input: updated });\n if (result.status !== 0) throw new Error((result.stderr || \"Could not update crontab\").trim());\n }\n }\n if (dryRun) console.log(actions.join(\"\\n\"));\n}\n\nasync function enableAutomaticSync() {\n const state = await readSyncConfiguration();\n if (!state.config.gist_id) {\n console.log(\"Sync must be configured before automatic synchronization can be enabled.\");\n await setupSync({ offerAutomaticSync: false });\n }\n const configured = await readSyncConfiguration();\n if (!configured.config.gist_id) return;\n const auth = await resolveGhAuthentication({ interactive: true, requireStored: true });\n console.log(`Stored GitHub credentials verified for ${auth.login}.`);\n await configureScheduler(true, configured.config.interval_minutes);\n configured.config.auto_sync = true;\n await recordResult(configured, `Automatic sync enabled every ${configured.config.interval_minutes} minutes`);\n console.log(`Automatic synchronization is enabled every ${configured.config.interval_minutes} minutes.`);\n}\n\nasync function disableAutomaticSync() {\n const state = await readSyncConfiguration();\n await configureScheduler(false, state.config.interval_minutes);\n state.config.auto_sync = false;\n await recordResult(state, \"Automatic sync disabled\");\n console.log(\"Automatic synchronization is disabled.\");\n}\n\nasync function main() {\n const [mode, explicitPath] = process.argv.slice(2);\n if (mode === \"export\") return exportBundle(resolve(explicitPath));\n if (mode === \"import\") return importBundle(resolve(explicitPath));\n if (mode === \"export-dialog\") {\n const path = nativeFileDialog(\"save\");\n if (path) await exportBundle(path);\n return;\n }\n if (mode === \"import-dialog\") {\n const path = nativeFileDialog(\"open\");\n if (path) await importBundle(path);\n return;\n }\n if (mode === \"setup\") return setupSync();\n if (mode === \"status\") return showStatus();\n if (mode === \"push\") return pushGist();\n if (mode === \"pull\") return pullGist();\n if (mode === \"auto-sync\") return automaticSync();\n if (mode === \"auto-enable\") return enableAutomaticSync();\n if (mode === \"auto-disable\") return disableAutomaticSync();\n throw new Error(`Unknown mode: ${mode || \"\"}`);\n}\n\ntry {\n await main();\n} catch (error) {\n console.error(error.stack || error.message);\n try {\n await appendLog(`ERROR ${error.message}`);\n } catch {\n // The terminal remains the primary error channel.\n }\n process.exitCode = 1;\n}\n",
"settings.json": "// Zed settings\n//\n// For information on how to configure Zed, see the Zed\n// documentation: https://zed.dev/docs/configuring-zed\n//\n// To see all of Zed's default settings without changing your\n// custom settings, run `zed: open default settings` from the\n// command palette (cmd-shift-p / ctrl-shift-p)\n{\n \"cli_default_open_behavior\": \"existing_window\",\n \"icon_theme\": \"Material Icon Theme\",\n \"auto_install_extensions\": {\n \"dockerfile\": true,\n \"env\": true,\n \"html\": true,\n \"material-icon-theme\": true,\n \"mcp-server-context7\": true,\n \"mcp-server-github\": true,\n \"one-dark-pro\": true,\n \"powershell\": true,\n \"toml\": true\n },\n \"disable_ai\": false,\n \"proxy\": \"\",\n \"agent\": {\n \"sidebar_side\": \"right\",\n \"favorite_models\": [],\n \"model_parameters\": []\n },\n \"project_panel\": {\n \"dock\": \"left\"\n },\n \"telemetry\": {\n \"diagnostics\": false,\n \"metrics\": false,\n \"anthropic_retention\": false\n },\n \"terminal\": {\n \"font_size\": 16.0,\n \"cursor_shape\": \"bar\"\n },\n \"base_keymap\": \"VSCode\",\n \"file_scan_exclusions\": [\n \"**/.git\",\n \"**/.svn\",\n \"**/.hg\",\n \"**/.jj\",\n \"**/CVS\",\n \"**/.DS_Store\",\n \"**/Thumbs.db\",\n \"**/.classpath\",\n \"**/.settings\",\n \"**/.playwright-cli\",\n \"**/output\",\n \"**/.cursor\",\n \"**/.vscode\",\n \"**/.idea\",\n \"**/.fleet\",\n \"**/node_modules\",\n \"**/bun.lockb\",\n \"**/pnpm-lock.yaml\",\n \"**/package-lock.json\",\n \"**/yarn.lock\",\n \"**/dist\",\n \"**/out\",\n \"**/build\",\n \"**/.next\",\n \"**/.nuxt\",\n \"**/.output\",\n \"**/.cache\",\n \"**/.turbo\",\n \"**/.vercel\",\n \"**/.netlify\",\n \"**/tsconfig.tsbuildinfo\",\n \"**/auto-imports.d.ts\",\n \"**/components.json\",\n \"**/unplugin-vue-components.d.ts\",\n \"src/*.d.ts\",\n \"**/__pycache__\",\n \"**/__init__.py\",\n \"**/.ipynb_checkpoints\",\n \"**/.pytest_cache\",\n \"**/.mypy_cache\",\n \"**/.venv\",\n \"**/env\",\n \"**/venv\",\n \"**/.github\",\n \"**/.husky\",\n \"**/.npmrc\",\n \"**/.eslintrc*\",\n \"**/.prettier*\",\n \"**/.editorconfig\",\n \"**/.dockerignore\",\n \"**/docker-compose.override.yml\",\n \"**/cypress*\",\n \"**/prisma/migrations\"\n ],\n \"preview_tabs\": {\n \"enabled\": false\n },\n \"git_panel\": {\n \"fallback_branch_name\": \"master\"\n },\n \"sticky_scroll\": {\n \"enabled\": true\n },\n \"minimap\": {\n \"show\": \"always\"\n },\n \"hover_popover_delay\": 250,\n \"cursor_blink\": true,\n \"autosave\": \"on_focus_change\",\n \"buffer_font_fallbacks\": [\n \"Consolas\",\n \"Sarasa Gothic SC\",\n \"Courier New\",\n \"monospace\"\n ],\n \"buffer_font_family\": \"Fira Code\",\n \"auto_indent_on_paste\": true,\n \"linked_edits\": true,\n \"show_edit_predictions\": true,\n \"line_ending\": \"prefer_lf\",\n \"hard_tabs\": false,\n \"tab_size\": 2,\n \"agent_servers\": {\n \"codex-acp\": {\n \"type\": \"registry\"\n }\n },\n \"ui_font_size\": 16,\n \"buffer_font_size\": 16.0,\n \"theme\": {\n \"mode\": \"system\",\n \"light\": \"One Light\",\n \"dark\": \"One Dark Pro\",\n },\n}\n",
"tasks.json": "// Project tasks configuration. See https://zed.dev/docs/tasks for documentation.\r\n//\n// Example:\n[\n /* The generated example task is intentionally disabled.\n {\n \"label\": \"Example task\",\r\n \"command\": \"for i in {1..5}; do echo \\\"Hello $i/5\\\"; sleep 1; done\",\r\n //\"args\": [],\r\n // Env overrides for the command, will be appended to the terminal's environment from the settings.\r\n \"env\": { \"foo\": \"bar\" },\r\n // Current working directory to spawn the command into, defaults to current project root.\r\n //\"cwd\": \"/path/to/working/directory\",\r\n // Whether to use a new terminal tab or reuse the existing one to spawn the process, defaults to `false`.\r\n \"use_new_terminal\": false,\r\n // Whether to allow multiple instances of the same task to be run, or rather wait for the existing ones to finish, defaults to `false`.\r\n \"allow_concurrent_runs\": false,\r\n // What to do with the terminal pane and tab, after the command was started:\r\n // * `always` — always show the task's pane, and focus the corresponding tab in it (default)\r\n // * `no_focus` — always show the task's pane, add the task's tab in it, but don't focus it\r\n // * `never` — do not alter focus, but still add/reuse the task's tab in its pane\r\n \"reveal\": \"always\",\r\n // Where to place the task's terminal item after starting the task:\r\n // * `dock` — in the terminal dock, \"regular\" terminal items' place (default)\r\n // * `center` — in the central pane group, \"main\" editor area\r\n \"reveal_target\": \"dock\",\r\n // What to do with the terminal pane and tab, after the command had finished:\r\n // * `never` — Do nothing when the command finishes (default)\r\n // * `always` — always hide the terminal tab, hide the pane also if it was the last tab in it\r\n // * `on_success` — hide the terminal tab on task success only, otherwise behaves similar to `always`\r\n \"hide\": \"never\",\r\n // Which shell to use when running a task inside the terminal.\r\n // May take 3 values:\r\n // 1. (default) Use the system's default terminal configuration in /etc/passwd\r\n // \"shell\": \"system\"\r\n // 2. A program:\r\n // \"shell\": {\r\n // \"program\": \"sh\"\r\n // }\r\n // 3. A program with arguments:\r\n // \"shell\": {\r\n // \"with_arguments\": {\r\n // \"program\": \"/bin/bash\",\r\n // \"args\": [\"--login\"]\r\n // }\r\n // }\r\n \"shell\": \"system\",\r\n // Whether to show the task line in the output of the spawned task, defaults to `true`.\r\n \"show_summary\": true,\r\n // Whether to show the command line in the output of the spawned task, defaults to `true`.\r\n \"show_command\": true,\r\n // Which edited buffers to save before running the task:\r\n // * `all` — save all edited buffers\r\n // * `current` — save currently active buffer only\r\n // * `none` — don't save any buffers\r\n \"save\": \"none\",\r\n // Represents the tags for inline runnable indicators, or spawning multiple tasks at once.\r\n // \"tags\": []\n }, */\n {\n \"label\": \"Toggle excluded files\",\n \"command\": \"node\",\n \"args\": [\n \"__TOGGLE_SCRIPT__\"\n ],\n \"use_new_terminal\": false,\n \"allow_concurrent_runs\": false,\n \"reveal\": \"never\",\n \"hide\": \"always\",\n \"show_summary\": false,\n \"show_command\": false,\n \"save\": \"none\"\n },\n {\n \"label\": \"Zed Settings: Export JSON...\",\n \"command\": \"node\",\n \"args\": [\n \"__SYNC_SCRIPT__\",\n \"export-dialog\"\n ],\n \"allow_concurrent_runs\": false,\n \"reveal\": \"always\",\n \"hide\": \"never\",\n \"show_summary\": false,\n \"show_command\": false,\n \"save\": \"all\"\n },\n {\n \"label\": \"Zed Settings: Import JSON...\",\n \"command\": \"node\",\n \"args\": [\n \"__SYNC_SCRIPT__\",\n \"import-dialog\"\n ],\n \"allow_concurrent_runs\": false,\n \"reveal\": \"always\",\n \"hide\": \"never\",\n \"show_summary\": false,\n \"show_command\": false,\n \"save\": \"all\"\n },\n {\n \"label\": \"Zed Settings: Set Up / Reconfigure Sync...\",\n \"command\": \"node\",\n \"args\": [\n \"__SYNC_SCRIPT__\",\n \"setup\"\n ],\n \"allow_concurrent_runs\": false,\n \"reveal\": \"always\",\n \"hide\": \"never\",\n \"show_summary\": true,\n \"show_command\": false,\n \"save\": \"all\"\n },\n {\n \"label\": \"Zed Settings: Show Sync Status\",\n \"command\": \"node\",\n \"args\": [\n \"__SYNC_SCRIPT__\",\n \"status\"\n ],\n \"allow_concurrent_runs\": false,\n \"reveal\": \"always\",\n \"hide\": \"never\",\n \"show_summary\": false,\n \"show_command\": false,\n \"save\": \"all\"\n },\n {\n \"label\": \"Zed Settings: Push Now\",\n \"command\": \"node\",\n \"args\": [\n \"__SYNC_SCRIPT__\",\n \"push\"\n ],\n \"allow_concurrent_runs\": false,\n \"reveal\": \"always\",\n \"hide\": \"never\",\n \"show_summary\": false,\n \"show_command\": false,\n \"save\": \"all\"\n },\n {\n \"label\": \"Zed Settings: Pull Now\",\n \"command\": \"node\",\n \"args\": [\n \"__SYNC_SCRIPT__\",\n \"pull\"\n ],\n \"allow_concurrent_runs\": false,\n \"reveal\": \"always\",\n \"hide\": \"never\",\n \"show_summary\": false,\n \"show_command\": false,\n \"save\": \"all\"\n },\n {\n \"label\": \"Zed Settings: Enable Automatic Sync\",\n \"command\": \"node\",\n \"args\": [\n \"__SYNC_SCRIPT__\",\n \"auto-enable\"\n ],\n \"allow_concurrent_runs\": false,\n \"reveal\": \"always\",\n \"hide\": \"never\",\n \"show_summary\": false,\n \"show_command\": false,\n \"save\": \"all\"\n },\n {\n \"label\": \"Zed Settings: Disable Automatic Sync\",\n \"command\": \"node\",\n \"args\": [\n \"__SYNC_SCRIPT__\",\n \"auto-disable\"\n ],\n \"allow_concurrent_runs\": false,\n \"reveal\": \"always\",\n \"hide\": \"never\",\n \"show_summary\": false,\n \"show_command\": false,\n \"save\": \"none\"\n },\n]\n"
}