native macOS codings agent orchestrator
6
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(terminal): brand SVG assets + immediate-apply detector

Wires real artwork into the auto-detected tab icon and rewrites the
detector around mapping hits instead of debounce.

Assets

- Adds 21 monochrome SVG imagesets under Assets.xcassets/CommandIcons
(Simple Icons + Lobe Icons), all template-rendered and shipped as
vector so they tint with foregroundStyle and adapt to dark/light.
Coverage: editors (vim, nvim), package managers (npm, pnpm, yarn,
bun), VCS (git, GitHub), build tools (swift, rust, xcode, gradle),
containers (docker, kubernetes, podman), DB REPLs (postgresql,
mysql, sqlite), curl, ClaudeCode, Codex.

Storage / rendering

- TabIconSource gains storageString; assets serialise to "@asset:Name"
while SF Symbols stay bare so the existing IconPicker / persistence
path keeps working unchanged.
- ResolvedTabIcon enum parses the stored string for renderers.
- New TabIconImage view dispatches to Image(systemName:) vs Image(_:)
+ .resizable() based on parse, both branches honour foregroundStyle
and a parent-supplied pointSize so SF Symbol fallbacks and branded
assets land at the same on-screen footprint.
- ShelfSpineView and TerminalTabLabelView swap their inline Image
call for TabIconImage; ShelfMetrics.tabIconPointSize centralises
the spine-side size.

Detector rewrite

- Drops the per-surface debounce timer entirely. Mapping hits apply
immediately; misses leave the tab icon alone (selection-2 keeps the
previously detected icon).
- Unblocks short-lived commands (`git status`, `cd foo`) and TUIs
that overwrite their preexec title before any debounce window
could fire (`codex` jumps straight to the repo name).
- Substring-match path removed — first-token alone now covers every
case in the current map (claude is detected at preexec, the
TUI-set "✳ Claude Code" no-ops via the unchanged guard).
- Idle-prompt suppression is preserved: shape heuristic plus the
per-surface learned-idle set populated from the first title that
arrives after each command_finished.

CommandIconMap

- 21 entries gain assetName: pointing at the new imageset; SF Symbol
remains as the renderer-side fallback when an asset is missing.
- Substring map and its lookup function deleted.

onevcat f26adde4 5e526b1c

+536 -250
+1
supacode/Assets.xcassets/CommandIcons/Bun.imageset/Bun.svg
··· 1 + <svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Bun</title><path d="M12 22.596c6.628 0 12-4.338 12-9.688 0-3.318-2.057-6.248-5.219-7.986-1.286-.715-2.297-1.357-3.139-1.89C14.058 2.025 13.08 1.404 12 1.404c-1.097 0-2.334.785-3.966 1.821a49.92 49.92 0 0 1-2.816 1.697C2.057 6.66 0 9.59 0 12.908c0 5.35 5.372 9.687 12 9.687v.001ZM10.599 4.715c.334-.759.503-1.58.498-2.409 0-.145.202-.187.23-.029.658 2.783-.902 4.162-2.057 4.624-.124.048-.199-.121-.103-.209a5.763 5.763 0 0 0 1.432-1.977Zm2.058-.102a5.82 5.82 0 0 0-.782-2.306v-.016c-.069-.123.086-.263.185-.172 1.962 2.111 1.307 4.067.556 5.051-.082.103-.23-.003-.189-.126a5.85 5.85 0 0 0 .23-2.431Zm1.776-.561a5.727 5.727 0 0 0-1.612-1.806v-.014c-.112-.085-.024-.274.114-.218 2.595 1.087 2.774 3.18 2.459 4.407a.116.116 0 0 1-.049.071.11.11 0 0 1-.153-.026.122.122 0 0 1-.022-.083 5.891 5.891 0 0 0-.737-2.331Zm-5.087.561c-.617.546-1.282.76-2.063 1-.117 0-.195-.078-.156-.181 1.752-.909 2.376-1.649 2.999-2.778 0 0 .155-.118.188.085 0 .304-.349 1.329-.968 1.874Zm4.945 11.237a2.957 2.957 0 0 1-.937 1.553c-.346.346-.8.565-1.286.62a2.178 2.178 0 0 1-1.327-.62 2.955 2.955 0 0 1-.925-1.553.244.244 0 0 1 .064-.198.234.234 0 0 1 .193-.069h3.965a.226.226 0 0 1 .19.07c.05.053.073.125.063.197Zm-5.458-2.176a1.862 1.862 0 0 1-2.384-.245 1.98 1.98 0 0 1-.233-2.447c.207-.319.503-.566.848-.713a1.84 1.84 0 0 1 1.092-.11c.366.075.703.261.967.531a1.98 1.98 0 0 1 .408 2.114 1.931 1.931 0 0 1-.698.869v.001Zm8.495.005a1.86 1.86 0 0 1-2.381-.253 1.964 1.964 0 0 1-.547-1.366c0-.384.11-.76.32-1.079.207-.319.503-.567.849-.713a1.844 1.844 0 0 1 1.093-.108c.367.076.704.262.968.534a1.98 1.98 0 0 1 .4 2.117 1.932 1.932 0 0 1-.702.868Z"/></svg>
+16
supacode/Assets.xcassets/CommandIcons/Bun.imageset/Contents.json
··· 1 + { 2 + "images" : [ 3 + { 4 + "filename" : "Bun.svg", 5 + "idiom" : "universal" 6 + } 7 + ], 8 + "info" : { 9 + "author" : "xcode", 10 + "version" : 1 11 + }, 12 + "properties" : { 13 + "preserves-vector-representation" : true, 14 + "template-rendering-intent" : "template" 15 + } 16 + }
+1
supacode/Assets.xcassets/CommandIcons/ClaudeCode.imageset/ClaudeCode.svg
··· 1 + <svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Claude</title><path d="M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z"></path></svg>
+16
supacode/Assets.xcassets/CommandIcons/ClaudeCode.imageset/Contents.json
··· 1 + { 2 + "images" : [ 3 + { 4 + "filename" : "ClaudeCode.svg", 5 + "idiom" : "universal" 6 + } 7 + ], 8 + "info" : { 9 + "author" : "xcode", 10 + "version" : 1 11 + }, 12 + "properties" : { 13 + "preserves-vector-representation" : true, 14 + "template-rendering-intent" : "template" 15 + } 16 + }
+1
supacode/Assets.xcassets/CommandIcons/Codex.imageset/Codex.svg
··· 1 + <svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Codex</title><path clip-rule="evenodd" d="M8.086.457a6.105 6.105 0 013.046-.415c1.333.153 2.521.72 3.564 1.7a.117.117 0 00.107.029c1.408-.346 2.762-.224 4.061.366l.063.03.154.076c1.357.703 2.33 1.77 2.918 3.198.278.679.418 1.388.421 2.126a5.655 5.655 0 01-.18 1.631.167.167 0 00.04.155 5.982 5.982 0 011.578 2.891c.385 1.901-.01 3.615-1.183 5.14l-.182.22a6.063 6.063 0 01-2.934 1.851.162.162 0 00-.108.102c-.255.736-.511 1.364-.987 1.992-1.199 1.582-2.962 2.462-4.948 2.451-1.583-.008-2.986-.587-4.21-1.736a.145.145 0 00-.14-.032c-.518.167-1.04.191-1.604.185a5.924 5.924 0 01-2.595-.622 6.058 6.058 0 01-2.146-1.781c-.203-.269-.404-.522-.551-.821a7.74 7.74 0 01-.495-1.283 6.11 6.11 0 01-.017-3.064.166.166 0 00.008-.074.115.115 0 00-.037-.064 5.958 5.958 0 01-1.38-2.202 5.196 5.196 0 01-.333-1.589 6.915 6.915 0 01.188-2.132c.45-1.484 1.309-2.648 2.577-3.493.282-.188.55-.334.802-.438.286-.12.573-.22.861-.304a.129.129 0 00.087-.087A6.016 6.016 0 015.635 2.31C6.315 1.464 7.132.846 8.086.457zm-.804 7.85a.848.848 0 00-1.473.842l1.694 2.965-1.688 2.848a.849.849 0 001.46.864l1.94-3.272a.849.849 0 00.007-.854l-1.94-3.393zm5.446 6.24a.849.849 0 000 1.695h4.848a.849.849 0 000-1.696h-4.848z"></path></svg>
+16
supacode/Assets.xcassets/CommandIcons/Codex.imageset/Contents.json
··· 1 + { 2 + "images" : [ 3 + { 4 + "filename" : "Codex.svg", 5 + "idiom" : "universal" 6 + } 7 + ], 8 + "info" : { 9 + "author" : "xcode", 10 + "version" : 1 11 + }, 12 + "properties" : { 13 + "preserves-vector-representation" : true, 14 + "template-rendering-intent" : "template" 15 + } 16 + }
+6
supacode/Assets.xcassets/CommandIcons/Contents.json
··· 1 + { 2 + "info" : { 3 + "author" : "xcode", 4 + "version" : 1 5 + } 6 + }
+16
supacode/Assets.xcassets/CommandIcons/Curl.imageset/Contents.json
··· 1 + { 2 + "images" : [ 3 + { 4 + "filename" : "Curl.svg", 5 + "idiom" : "universal" 6 + } 7 + ], 8 + "info" : { 9 + "author" : "xcode", 10 + "version" : 1 11 + }, 12 + "properties" : { 13 + "preserves-vector-representation" : true, 14 + "template-rendering-intent" : "template" 15 + } 16 + }
+1
supacode/Assets.xcassets/CommandIcons/Curl.imageset/Curl.svg
··· 1 + <svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>curl</title><path d="M.803 14.8169c0-.5342.433-.9665.9665-.9665.5335 0 .9665.4323.9665.9665 0 .5335-.433.9657-.9665.9657-.5335 0-.9666-.4322-.9666-.9657m2.736 0c0-.1963-.0532-.376-.1119-.5525-.2344-.7024-.876-1.2169-1.6575-1.2169-.1249 0-.2344.0465-.3524.0708C.6149 13.2865 0 13.9646 0 14.817c0 .9764.7923 1.7694 1.7695 1.7694.9772 0 1.7694-.793 1.7694-1.7694m-1.7694-7.149c.5335 0 .9665.433.9665.9665 0 .5335-.433.9665-.9665.9665-.5343 0-.9666-.433-.9666-.9665 0-.5335.4323-.9665.9666-.9665m0 2.7359c.9772 0 1.7694-.7923 1.7694-1.7694 0-.1956-.0532-.376-.1119-.5525-.2344-.7024-.8767-1.2169-1.6575-1.2169-.1249 0-.2344.0465-.3524.0716C.6149 7.104 0 7.782 0 8.6344c0 .9771.7923 1.7694 1.7695 1.7694m13.221-5.694c-.5342 0-.9665-.433-.9665-.9664a.966.966 0 01.9666-.9665c.5335 0 .9658.4322.9658.9665 0 .5334-.4323.9664-.9658.9664m-9.6 16.5133c-.5335 0-.9666-.433-.9666-.9665 0-.5342.433-.9665.9666-.9665a.966.966 0 01.9665.9665c0 .5335-.4323.9665-.9665.9665m9.6-19.2491c-.978 0-1.7695.7922-1.7695 1.7694 0 .2085.0525.4025.1187.5882L5.039 18.5581c-.803.1681-1.4179.8462-1.4179 1.6985 0 .9772.7923 1.7694 1.7695 1.7694.9772 0 1.7694-.7922 1.7694-1.7694 0-.1963-.0525-.3759-.111-.5525l8.3427-14.2728c.7778-.1865 1.3683-.8531 1.3683-1.688 0-.977-.793-1.7693-1.7694-1.7693m7.24 2.7359c-.5343 0-.9666-.433-.9666-.9665a.966.966 0 01.9665-.9665c.5335 0 .9666.4322.9666.9665 0 .5334-.433.9665-.9666.9665M12.6313 21.223c-.5343 0-.9665-.433-.9665-.9665a.966.966 0 01.9665-.9665c.5335 0 .9658.4323.9658.9665 0 .5335-.4323.9665-.9658.9665M22.2305 1.974c-.9772 0-1.7694.7922-1.7694 1.7694 0 .2085.0525.4025.1187.5882l-8.3009 14.2265c-.8021.1681-1.417.8462-1.417 1.6985 0 .9772.7922 1.7694 1.7694 1.7694.9764 0 1.7687-.7922 1.7687-1.7694 0-.1963-.0525-.3759-.1111-.5525l8.3427-14.2728C23.4094 5.2448 24 4.5782 24 3.7433c0-.977-.7923-1.7693-1.7695-1.7693"/></svg>
+16
supacode/Assets.xcassets/CommandIcons/Docker.imageset/Contents.json
··· 1 + { 2 + "images" : [ 3 + { 4 + "filename" : "Docker.svg", 5 + "idiom" : "universal" 6 + } 7 + ], 8 + "info" : { 9 + "author" : "xcode", 10 + "version" : 1 11 + }, 12 + "properties" : { 13 + "preserves-vector-representation" : true, 14 + "template-rendering-intent" : "template" 15 + } 16 + }
+1
supacode/Assets.xcassets/CommandIcons/Docker.imageset/Docker.svg
··· 1 + <svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Docker</title><path d="M13.983 11.078h2.119a.186.186 0 00.186-.185V9.006a.186.186 0 00-.186-.186h-2.119a.185.185 0 00-.185.185v1.888c0 .102.083.185.185.185m-2.954-5.43h2.118a.186.186 0 00.186-.186V3.574a.186.186 0 00-.186-.185h-2.118a.185.185 0 00-.185.185v1.888c0 .102.082.185.185.185m0 2.716h2.118a.187.187 0 00.186-.186V6.29a.186.186 0 00-.186-.185h-2.118a.185.185 0 00-.185.185v1.887c0 .102.082.185.185.186m-2.93 0h2.12a.186.186 0 00.184-.186V6.29a.185.185 0 00-.185-.185H8.1a.185.185 0 00-.185.185v1.887c0 .102.083.185.185.186m-2.964 0h2.119a.186.186 0 00.185-.186V6.29a.185.185 0 00-.185-.185H5.136a.186.186 0 00-.186.185v1.887c0 .102.084.185.186.186m5.893 2.715h2.118a.186.186 0 00.186-.185V9.006a.186.186 0 00-.186-.186h-2.118a.185.185 0 00-.185.185v1.888c0 .102.082.185.185.185m-2.93 0h2.12a.185.185 0 00.184-.185V9.006a.185.185 0 00-.184-.186h-2.12a.185.185 0 00-.184.185v1.888c0 .102.083.185.185.185m-2.964 0h2.119a.185.185 0 00.185-.185V9.006a.185.185 0 00-.184-.186h-2.12a.186.186 0 00-.186.186v1.887c0 .102.084.185.186.185m-2.92 0h2.12a.185.185 0 00.184-.185V9.006a.185.185 0 00-.184-.186h-2.12a.185.185 0 00-.184.185v1.888c0 .102.082.185.185.185M23.763 9.89c-.065-.051-.672-.51-1.954-.51-.338.001-.676.03-1.01.087-.248-1.7-1.653-2.53-1.716-2.566l-.344-.199-.226.327c-.284.438-.49.922-.612 1.43-.23.97-.09 1.882.403 2.661-.595.332-1.55.413-1.744.42H.751a.751.751 0 00-.75.748 11.376 11.376 0 00.692 4.062c.545 1.428 1.355 2.48 2.41 3.124 1.18.723 3.1 1.137 5.275 1.137.983.003 1.963-.086 2.93-.266a12.248 12.248 0 003.823-1.389c.98-.567 1.86-1.288 2.61-2.136 1.252-1.418 1.998-2.997 2.553-4.4h.221c1.372 0 2.215-.549 2.68-1.009.309-.293.55-.65.707-1.046l.098-.288Z"/></svg>
+16
supacode/Assets.xcassets/CommandIcons/Git.imageset/Contents.json
··· 1 + { 2 + "images" : [ 3 + { 4 + "filename" : "Git.svg", 5 + "idiom" : "universal" 6 + } 7 + ], 8 + "info" : { 9 + "author" : "xcode", 10 + "version" : 1 11 + }, 12 + "properties" : { 13 + "preserves-vector-representation" : true, 14 + "template-rendering-intent" : "template" 15 + } 16 + }
+1
supacode/Assets.xcassets/CommandIcons/Git.imageset/Git.svg
··· 1 + <svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Git</title><path d="M23.546 10.93L13.067.452c-.604-.603-1.582-.603-2.188 0L8.708 2.627l2.76 2.76c.645-.215 1.379-.07 1.889.441.516.515.658 1.258.438 1.9l2.658 2.66c.645-.223 1.387-.078 1.9.435.721.72.721 1.884 0 2.604-.719.719-1.881.719-2.6 0-.539-.541-.674-1.337-.404-1.996L12.86 8.955v6.525c.176.086.342.203.488.348.713.721.713 1.883 0 2.6-.719.721-1.889.721-2.609 0-.719-.719-.719-1.879 0-2.598.182-.18.387-.316.605-.406V8.835c-.217-.091-.424-.222-.6-.401-.545-.545-.676-1.342-.396-2.009L7.636 3.7.45 10.881c-.6.605-.6 1.584 0 2.189l10.48 10.477c.604.604 1.582.604 2.186 0l10.43-10.43c.605-.603.605-1.582 0-2.187"/></svg>
+16
supacode/Assets.xcassets/CommandIcons/GitHub.imageset/Contents.json
··· 1 + { 2 + "images" : [ 3 + { 4 + "filename" : "GitHub.svg", 5 + "idiom" : "universal" 6 + } 7 + ], 8 + "info" : { 9 + "author" : "xcode", 10 + "version" : 1 11 + }, 12 + "properties" : { 13 + "preserves-vector-representation" : true, 14 + "template-rendering-intent" : "template" 15 + } 16 + }
+1
supacode/Assets.xcassets/CommandIcons/GitHub.imageset/GitHub.svg
··· 1 + <svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>
+16
supacode/Assets.xcassets/CommandIcons/Gradle.imageset/Contents.json
··· 1 + { 2 + "images" : [ 3 + { 4 + "filename" : "Gradle.svg", 5 + "idiom" : "universal" 6 + } 7 + ], 8 + "info" : { 9 + "author" : "xcode", 10 + "version" : 1 11 + }, 12 + "properties" : { 13 + "preserves-vector-representation" : true, 14 + "template-rendering-intent" : "template" 15 + } 16 + }
+1
supacode/Assets.xcassets/CommandIcons/Gradle.imageset/Gradle.svg
··· 1 + <svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Gradle</title><path d="M22.695 4.297a3.807 3.807 0 0 0-5.29-.09.368.368 0 0 0 0 .533l.46.47a.363.363 0 0 0 .474.032 2.182 2.182 0 0 1 2.86 3.291c-3.023 3.02-7.056-5.447-16.211-1.083a1.24 1.24 0 0 0-.534 1.745l1.571 2.713a1.238 1.238 0 0 0 1.681.461l.037-.02-.029.02.688-.384a16.083 16.083 0 0 0 2.193-1.635.384.384 0 0 1 .499-.016.357.357 0 0 1 .016.534 16.435 16.435 0 0 1-2.316 1.741H8.77l-.696.39a1.958 1.958 0 0 1-.963.25 1.987 1.987 0 0 1-1.726-.989L3.9 9.696C1.06 11.72-.686 15.603.26 20.522a.363.363 0 0 0 .354.296h1.675a.363.363 0 0 0 .37-.331 2.478 2.478 0 0 1 4.915 0 .36.36 0 0 0 .357.317h1.638a.363.363 0 0 0 .357-.317 2.478 2.478 0 0 1 4.914 0 .363.363 0 0 0 .358.317h1.627a.363.363 0 0 0 .363-.357c.037-2.294.656-4.93 2.42-6.25 6.108-4.57 4.502-8.486 3.088-9.9zm-6.229 6.901l-1.165-.584a.73.73 0 1 1 1.165.587z"/></svg>
+16
supacode/Assets.xcassets/CommandIcons/Kubernetes.imageset/Contents.json
··· 1 + { 2 + "images" : [ 3 + { 4 + "filename" : "Kubernetes.svg", 5 + "idiom" : "universal" 6 + } 7 + ], 8 + "info" : { 9 + "author" : "xcode", 10 + "version" : 1 11 + }, 12 + "properties" : { 13 + "preserves-vector-representation" : true, 14 + "template-rendering-intent" : "template" 15 + } 16 + }
+1
supacode/Assets.xcassets/CommandIcons/Kubernetes.imageset/Kubernetes.svg
··· 1 + <svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Kubernetes</title><path d="M10.204 14.35l.007.01-.999 2.413a5.171 5.171 0 0 1-2.075-2.597l2.578-.437.004.005a.44.44 0 0 1 .484.606zm-.833-2.129a.44.44 0 0 0 .173-.756l.002-.011L7.585 9.7a5.143 5.143 0 0 0-.73 3.255l2.514-.725.002-.009zm1.145-1.98a.44.44 0 0 0 .699-.337l.01-.005.15-2.62a5.144 5.144 0 0 0-3.01 1.442l2.147 1.523.004-.002zm.76 2.75l.723.349.722-.347.18-.78-.5-.623h-.804l-.5.623.179.779zm1.5-3.095a.44.44 0 0 0 .7.336l.008.003 2.134-1.513a5.188 5.188 0 0 0-2.992-1.442l.148 2.615.002.001zm10.876 5.97l-5.773 7.181a1.6 1.6 0 0 1-1.248.594l-9.261.003a1.6 1.6 0 0 1-1.247-.596l-5.776-7.18a1.583 1.583 0 0 1-.307-1.34L2.1 5.573c.108-.47.425-.864.863-1.073L11.305.513a1.606 1.606 0 0 1 1.385 0l8.345 3.985c.438.209.755.604.863 1.073l2.062 8.955c.108.47-.005.963-.308 1.34zm-3.289-2.057c-.042-.01-.103-.026-.145-.034-.174-.033-.315-.025-.479-.038-.35-.037-.638-.067-.895-.148-.105-.04-.18-.165-.216-.216l-.201-.059a6.45 6.45 0 0 0-.105-2.332 6.465 6.465 0 0 0-.936-2.163c.052-.047.15-.133.177-.159.008-.09.001-.183.094-.282.197-.185.444-.338.743-.522.142-.084.273-.137.415-.242.032-.024.076-.062.11-.089.24-.191.295-.52.123-.736-.172-.216-.506-.236-.745-.045-.034.027-.08.062-.111.088-.134.116-.217.23-.33.35-.246.25-.45.458-.673.609-.097.056-.239.037-.303.033l-.19.135a6.545 6.545 0 0 0-4.146-2.003l-.012-.223c-.065-.062-.143-.115-.163-.25-.022-.268.015-.557.057-.905.023-.163.061-.298.068-.475.001-.04-.001-.099-.001-.142 0-.306-.224-.555-.5-.555-.275 0-.499.249-.499.555l.001.014c0 .041-.002.092 0 .128.006.177.044.312.067.475.042.348.078.637.056.906a.545.545 0 0 1-.162.258l-.012.211a6.424 6.424 0 0 0-4.166 2.003 8.373 8.373 0 0 1-.18-.128c-.09.012-.18.04-.297-.029-.223-.15-.427-.358-.673-.608-.113-.12-.195-.234-.329-.349-.03-.026-.077-.062-.111-.088a.594.594 0 0 0-.348-.132.481.481 0 0 0-.398.176c-.172.216-.117.546.123.737l.007.005.104.083c.142.105.272.159.414.242.299.185.546.338.743.522.076.082.09.226.1.288l.16.143a6.462 6.462 0 0 0-1.02 4.506l-.208.06c-.055.072-.133.184-.215.217-.257.081-.546.11-.895.147-.164.014-.305.006-.48.039-.037.007-.09.02-.133.03l-.004.002-.007.002c-.295.071-.484.342-.423.608.061.267.349.429.645.365l.007-.001.01-.003.129-.029c.17-.046.294-.113.448-.172.33-.118.604-.217.87-.256.112-.009.23.069.288.101l.217-.037a6.5 6.5 0 0 0 2.88 3.596l-.09.218c.033.084.069.199.044.282-.097.252-.263.517-.452.813-.091.136-.185.242-.268.399-.02.037-.045.095-.064.134-.128.275-.034.591.213.71.248.12.556-.007.69-.282v-.002c.02-.039.046-.09.062-.127.07-.162.094-.301.144-.458.132-.332.205-.68.387-.897.05-.06.13-.082.215-.105l.113-.205a6.453 6.453 0 0 0 4.609.012l.106.192c.086.028.18.042.256.155.136.232.229.507.342.84.05.156.074.295.145.457.016.037.043.09.062.129.133.276.442.402.69.282.247-.118.341-.435.213-.71-.02-.039-.045-.096-.065-.134-.083-.156-.177-.261-.268-.398-.19-.296-.346-.541-.443-.793-.04-.13.007-.21.038-.294-.018-.022-.059-.144-.083-.202a6.499 6.499 0 0 0 2.88-3.622c.064.01.176.03.213.038.075-.05.144-.114.28-.104.266.039.54.138.87.256.154.06.277.128.448.173.036.01.088.019.13.028l.009.003.007.001c.297.064.584-.098.645-.365.06-.266-.128-.537-.423-.608zM16.4 9.701l-1.95 1.746v.005a.44.44 0 0 0 .173.757l.003.01 2.526.728a5.199 5.199 0 0 0-.108-1.674A5.208 5.208 0 0 0 16.4 9.7zm-4.013 5.325a.437.437 0 0 0-.404-.232.44.44 0 0 0-.372.233h-.002l-1.268 2.292a5.164 5.164 0 0 0 3.326.003l-1.27-2.296h-.01zm1.888-1.293a.44.44 0 0 0-.27.036.44.44 0 0 0-.214.572l-.003.004 1.01 2.438a5.15 5.15 0 0 0 2.081-2.615l-2.6-.44-.004.005z"/></svg>
+16
supacode/Assets.xcassets/CommandIcons/MySQL.imageset/Contents.json
··· 1 + { 2 + "images" : [ 3 + { 4 + "filename" : "MySQL.svg", 5 + "idiom" : "universal" 6 + } 7 + ], 8 + "info" : { 9 + "author" : "xcode", 10 + "version" : 1 11 + }, 12 + "properties" : { 13 + "preserves-vector-representation" : true, 14 + "template-rendering-intent" : "template" 15 + } 16 + }
+1
supacode/Assets.xcassets/CommandIcons/MySQL.imageset/MySQL.svg
··· 1 + <svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>MySQL</title><path d="M16.405 5.501c-.115 0-.193.014-.274.033v.013h.014c.054.104.146.18.214.273.054.107.1.214.154.32l.014-.015c.094-.066.14-.172.14-.333-.04-.047-.046-.094-.08-.14-.04-.067-.126-.1-.18-.153zM5.77 18.695h-.927a50.854 50.854 0 00-.27-4.41h-.008l-1.41 4.41H2.45l-1.4-4.41h-.01a72.892 72.892 0 00-.195 4.41H0c.055-1.966.192-3.81.41-5.53h1.15l1.335 4.064h.008l1.347-4.064h1.095c.242 2.015.384 3.86.428 5.53zm4.017-4.08c-.378 2.045-.876 3.533-1.492 4.46-.482.716-1.01 1.073-1.583 1.073-.153 0-.34-.046-.566-.138v-.494c.11.017.24.026.386.026.268 0 .483-.075.647-.222.197-.18.295-.382.295-.605 0-.155-.077-.47-.23-.944L6.23 14.615h.91l.727 2.36c.164.536.233.91.205 1.123.4-1.064.678-2.227.835-3.483zm12.325 4.08h-2.63v-5.53h.885v4.85h1.745zm-3.32.135l-1.016-.5c.09-.076.177-.158.255-.25.433-.506.648-1.258.648-2.253 0-1.83-.718-2.746-2.155-2.746-.704 0-1.254.232-1.65.697-.43.508-.646 1.256-.646 2.245 0 .972.19 1.686.574 2.14.35.41.877.615 1.583.615.264 0 .506-.033.725-.098l1.325.772.36-.622zM15.5 17.588c-.225-.36-.337-.94-.337-1.736 0-1.393.424-2.09 1.27-2.09.443 0 .77.167.977.5.224.362.336.936.336 1.723 0 1.404-.424 2.108-1.27 2.108-.445 0-.77-.167-.978-.5zm-1.658-.425c0 .47-.172.856-.516 1.156-.344.3-.803.45-1.384.45-.543 0-1.064-.172-1.573-.515l.237-.476c.438.22.833.328 1.19.328.332 0 .593-.073.783-.22a.754.754 0 00.3-.615c0-.33-.23-.61-.648-.845-.388-.213-1.163-.657-1.163-.657-.422-.307-.632-.636-.632-1.177 0-.45.157-.81.47-1.085.315-.278.72-.415 1.22-.415.512 0 .98.136 1.4.41l-.213.476a2.726 2.726 0 00-1.064-.23c-.283 0-.502.068-.654.206a.685.685 0 00-.248.524c0 .328.234.61.666.85.393.215 1.187.67 1.187.67.433.305.648.63.648 1.168zm9.382-5.852c-.535-.014-.95.04-1.297.188-.1.04-.26.04-.274.167.055.053.063.14.11.214.08.134.218.313.346.407.14.11.28.216.427.31.26.16.555.255.81.416.145.094.293.213.44.313.073.05.12.14.214.172v-.02c-.046-.06-.06-.147-.105-.214-.067-.067-.134-.127-.2-.193a3.223 3.223 0 00-.695-.675c-.214-.146-.682-.35-.77-.595l-.013-.014c.146-.013.32-.066.46-.106.227-.06.435-.047.67-.106.106-.027.213-.06.32-.094v-.06c-.12-.12-.21-.283-.334-.395a8.867 8.867 0 00-1.104-.823c-.21-.134-.476-.22-.697-.334-.08-.04-.214-.06-.26-.127-.12-.146-.19-.34-.275-.514a17.69 17.69 0 01-.547-1.163c-.12-.262-.193-.523-.34-.763-.69-1.137-1.437-1.826-2.586-2.5-.247-.14-.543-.2-.856-.274-.167-.008-.334-.02-.5-.027-.11-.047-.216-.174-.31-.235-.38-.24-1.364-.76-1.644-.072-.18.434.267.862.422 1.082.115.153.26.328.34.5.047.116.06.235.107.356.106.294.207.622.347.897.073.14.153.287.247.413.054.073.146.107.167.227-.094.136-.1.334-.154.5-.24.757-.146 1.693.194 2.25.107.166.362.534.703.393.3-.12.234-.5.32-.835.02-.08.007-.133.048-.187v.015c.094.188.188.367.274.555.206.328.566.668.867.895.16.12.287.328.487.402v-.02h-.015c-.043-.058-.1-.086-.154-.133a3.445 3.445 0 01-.35-.4 8.76 8.76 0 01-.747-1.218c-.11-.21-.202-.436-.29-.643-.04-.08-.04-.2-.107-.24-.1.146-.247.273-.32.453-.127.288-.14.642-.188 1.01-.027.007-.014 0-.027.014-.214-.052-.287-.274-.367-.46-.2-.475-.233-1.238-.06-1.785.047-.14.247-.582.167-.716-.042-.127-.174-.2-.247-.303a2.478 2.478 0 01-.24-.427c-.16-.374-.24-.788-.414-1.162-.08-.173-.22-.354-.334-.513-.127-.18-.267-.307-.368-.52-.033-.073-.08-.194-.027-.274.014-.054.042-.075.094-.09.088-.072.335.022.422.062.247.1.455.194.662.334.094.066.195.193.315.226h.14c.214.047.455.014.655.073.355.114.675.28.962.46a5.953 5.953 0 012.085 2.286c.08.154.115.295.188.455.14.33.313.663.455.982.14.315.275.636.476.897.1.14.502.213.682.286.133.06.34.115.46.188.23.14.454.3.67.454.11.076.443.243.463.378z"/></svg>
+16
supacode/Assets.xcassets/CommandIcons/Neovim.imageset/Contents.json
··· 1 + { 2 + "images" : [ 3 + { 4 + "filename" : "Neovim.svg", 5 + "idiom" : "universal" 6 + } 7 + ], 8 + "info" : { 9 + "author" : "xcode", 10 + "version" : 1 11 + }, 12 + "properties" : { 13 + "preserves-vector-representation" : true, 14 + "template-rendering-intent" : "template" 15 + } 16 + }
+1
supacode/Assets.xcassets/CommandIcons/Neovim.imageset/Neovim.svg
··· 1 + <svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Neovim</title><path d="M2.214 4.954v13.615L7.655 24V10.314L3.312 3.845 2.214 4.954zm4.999 17.98l-4.557-4.548V5.136l.59-.596 3.967 5.908v12.485zm14.573-4.457l-.862.937-4.24-6.376V0l5.068 5.092.034 13.385zM7.431.001l12.998 19.835-3.637 3.637L3.787 3.683 7.43 0z"/></svg>
+16
supacode/Assets.xcassets/CommandIcons/Npm.imageset/Contents.json
··· 1 + { 2 + "images" : [ 3 + { 4 + "filename" : "Npm.svg", 5 + "idiom" : "universal" 6 + } 7 + ], 8 + "info" : { 9 + "author" : "xcode", 10 + "version" : 1 11 + }, 12 + "properties" : { 13 + "preserves-vector-representation" : true, 14 + "template-rendering-intent" : "template" 15 + } 16 + }
+1
supacode/Assets.xcassets/CommandIcons/Npm.imageset/Npm.svg
··· 1 + <svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>npm</title><path d="M1.763 0C.786 0 0 .786 0 1.763v20.474C0 23.214.786 24 1.763 24h20.474c.977 0 1.763-.786 1.763-1.763V1.763C24 .786 23.214 0 22.237 0zM5.13 5.323l13.837.019-.009 13.836h-3.464l.01-10.382h-3.456L12.04 19.17H5.113z"/></svg>
+16
supacode/Assets.xcassets/CommandIcons/Pnpm.imageset/Contents.json
··· 1 + { 2 + "images" : [ 3 + { 4 + "filename" : "Pnpm.svg", 5 + "idiom" : "universal" 6 + } 7 + ], 8 + "info" : { 9 + "author" : "xcode", 10 + "version" : 1 11 + }, 12 + "properties" : { 13 + "preserves-vector-representation" : true, 14 + "template-rendering-intent" : "template" 15 + } 16 + }
+1
supacode/Assets.xcassets/CommandIcons/Pnpm.imageset/Pnpm.svg
··· 1 + <svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>pnpm</title><path d="M0 0v7.5h7.5V0zm8.25 0v7.5h7.498V0zm8.25 0v7.5H24V0zM2 2h3.5v3.5H2zm8.25 0h3.498v3.5H10.25zm8.25 0H22v3.5h-3.5zM8.25 8.25v7.5h7.498v-7.5zm8.25 0v7.5H24v-7.5zm2 2H22v3.5h-3.5zM0 16.5V24h7.5v-7.5zm8.25 0V24h7.498v-7.5zm8.25 0V24H24v-7.5z"/></svg>
+16
supacode/Assets.xcassets/CommandIcons/Podman.imageset/Contents.json
··· 1 + { 2 + "images" : [ 3 + { 4 + "filename" : "Podman.svg", 5 + "idiom" : "universal" 6 + } 7 + ], 8 + "info" : { 9 + "author" : "xcode", 10 + "version" : 1 11 + }, 12 + "properties" : { 13 + "preserves-vector-representation" : true, 14 + "template-rendering-intent" : "template" 15 + } 16 + }
+1
supacode/Assets.xcassets/CommandIcons/Podman.imageset/Podman.svg
··· 1 + <svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Podman</title><path d="M17.2.275L6.75.308a.259.259 0 0 0-.203.098L.056 8.602a.259.259 0 0 0-.05.219l2.356 10.194a.26.26 0 0 0 .14.174l9.43 4.511a.258.258 0 0 0 .224-.002l9.401-4.566a.259.259 0 0 0 .141-.175L23.993 8.75a.258.258 0 0 0-.051-.22L17.403.374A.259.259 0 0 0 17.2.275zm-.123.517l6.385 7.966-2.242 9.964-9.177 4.457-9.205-4.402L.54 8.827 6.875.824zM11.46 2.857c-.933 0-1.84.1-2.426.332h-.002c-1.554.569-2.725 2.105-3.074 3.952v.004c-.309 1.463-.392 2.703-.556 3.824-.07.481-.159.94-.283 1.387-.628.497-1.079 1.263-1.244 2.138v.004c-.116.547-.181 1.04-.237 1.5h-.644v.518h8.891c-.061.464-.122.996-.181 1.42H7.596v.517h7.939c-.242-.078-.486-.218-.756-.502h-.697l-.85.488-.232-.396.162-.092h-1.069c.113-.776.17-1.601.373-2.564v-.004c.22-1.164.96-2.112 1.895-2.453l.004-.002h.002c.318-.127.928-.205 1.543-.205.613 0 1.244.075 1.622.207.935.341 1.676 1.29 1.895 2.453v.004c.204.963.26 1.788.373 2.564h-.742l.162.092-.233.396-.85-.488h-.75c-.219.25-.474.412-.747.502h4.392v-.518h-.842c-.103-.743-.181-1.67-.382-2.623v-.002a4.14 4.14 0 0 0-.264-.863h1.863v-.517h-2.13a3.488 3.488 0 0 0-.8-.906h1.8v-.518H17.95a8.862 8.862 0 0 1-.193-.775h1.484v-.518h-1.576c-.013-.081-.027-.161-.039-.244-.164-1.12-.246-2.36-.555-3.824v-.004c-.348-1.848-1.52-3.383-3.075-3.952l-.002-.002h-.002c-.65-.227-1.596-.33-2.531-.33zm0 .386c.904 0 1.833.11 2.404.309h.002c1.4.514 2.5 1.934 2.826 3.666v.003c.303 1.436.385 2.66.552 3.805.076.515.173 1.013.315 1.505-.449-.135-1.05-.197-1.648-.197-.12 0-.236.003-.352.008l-1.863-1.865a2.17 2.17 0 0 0 .11-.246l2.13 1.23.13-.224-2.185-1.262c.016-.069.027-.14.036-.21l2.302.616.068-.248-2.354-.63c-.02-1.153-1.008-2.078-2.208-2.078-1.205 0-2.196.931-2.206 2.091l-2.303.617.066.25 2.252-.605c.01.076.024.151.041.224L7.436 11.24l.129.222 2.087-1.207c.034.089.074.176.12.258l-1.266 1.266a6.959 6.959 0 0 0-1.045-.075c-.603 0-1.186.064-1.578.22a2.668 2.668 0 0 0-.285.124c.076-.335.137-.675.187-1.021.168-1.144.248-2.37.551-3.805l.002-.001v-.002c.326-1.733 1.426-3.153 2.828-3.666h.002l.004-.002c.488-.194 1.381-.307 2.287-.307zM8.473 5.194a1.295 1.295 0 0 0-.965.502l-.117.153.306.236.12-.152a.923.923 0 0 1 .673-.352.92.92 0 0 1 .67.262l.139.134.271-.275-.136-.137a1.293 1.293 0 0 0-.961-.37zm6.39 0a1.289 1.289 0 0 0-.96.371l-.138.137.274.275.136-.134a.923.923 0 0 1 .672-.262.923.923 0 0 1 .674.352l.119.152.307-.236-.12-.153c-.23-.3-.587-.486-.964-.502zM8.53 6.708c-.642 0-1.164.538-1.164 1.19 0 .65.522 1.187 1.164 1.187.643 0 1.164-.536 1.164-1.188 0-.651-.521-1.19-1.164-1.19zm6.273 0c-.643 0-1.162.538-1.162 1.19 0 .65.52 1.187 1.162 1.187.643 0 1.164-.536 1.164-1.188 0-.651-.521-1.19-1.164-1.19zm-6.273.387c.428 0 .776.355.776.802 0 .447-.348.8-.776.8a.785.785 0 0 1-.775-.8c0-.035.002-.07.006-.103.07.191.248.318.445.318a.487.487 0 0 0 .477-.496.49.49 0 0 0-.383-.486.759.759 0 0 1 .23-.035zm6.273 0c.428 0 .777.355.777.802 0 .447-.349.8-.777.8a.785.785 0 0 1-.77-.9c.072.19.248.315.444.315a.486.486 0 0 0 .479-.496.491.491 0 0 0-.383-.484.755.755 0 0 1 .23-.037zm-3.08.716c1.012 0 1.819.775 1.819 1.723 0 .947-.807 1.722-1.819 1.722s-1.82-.775-1.82-1.722c0-.948.808-1.723 1.82-1.723zm-.002.528c-.142 0-.258.043-.355.076a.804.804 0 0 1-.232.054c-.107 0-.2.047-.268.127a.568.568 0 0 0-.104.207c-.04.134-.062.268-.08.315a.276.276 0 0 0 .032.25c.033.056.071.1.117.146.09.092.206.183.322.268.12.088.237.166.326.224l-.008.09c-.043.036-.14.102-.324.178a.533.533 0 0 1-.299.025.43.43 0 0 1-.236-.172c.015-.138.044-.293.068-.449l-.376-.095c-.05.238-.067.43-.094.64l.037.059c.143.224.318.344.506.392a.908.908 0 0 0 .52-.033 1.57 1.57 0 0 0 .444-.242c.088.067.244.174.446.242a.908.908 0 0 0 .52.033.868.868 0 0 0 .507-.392l.037-.059a6.292 6.292 0 0 0-.096-.637l-.377.092c.032.148.051.32.07.451a.434.434 0 0 1-.237.17.533.533 0 0 1-.3-.025c-.178-.068-.272-.14-.325-.178l-.006-.084c.09-.058.209-.137.336-.23.115-.085.231-.176.322-.268a.72.72 0 0 0 .117-.146.273.273 0 0 0 .031-.25c-.018-.047-.039-.181-.08-.315a.564.564 0 0 0-.103-.207.343.343 0 0 0-.268-.127.815.815 0 0 1-.234-.054c-.097-.033-.212-.076-.354-.076zm.002.386c.057 0 .134.024.23.057.09.03.208.07.337.076.04.102.06.237.09.338a.361.361 0 0 1-.041.045 2.66 2.66 0 0 1-.276.228c-.165.122-.271.188-.342.233a5.287 5.287 0 0 1-.34-.233 2.557 2.557 0 0 1-.275-.228.34.34 0 0 1-.04-.047c.035-.119.046-.234.089-.34.08.012.246-.042.336-.072a.837.837 0 0 1 .232-.057zm-3.234.61a.635.635 0 0 0-.611.517l1.084-.289a.614.614 0 0 0-.473-.228zm6.336 0a.61.61 0 0 0-.436.187c.352.096.69.184 1.033.275a.632.632 0 0 0-.597-.462zm-.623.607c-.007.035-.002.07-.002.103l.921.532a.648.648 0 0 0 .276-.313l-1.195-.322zm-5.086.05l-1.18.315c.078.15.207.264.362.316l.797-.46c.018-.059.015-.12.021-.17zm4.441.714l1.656 1.658a4.19 4.19 0 0 0-.826.146l-.95-1.647a2.51 2.51 0 0 0 .12-.157zm-3.646.03c.04.055.083.118.129.169l-.658 1.134a2.656 2.656 0 0 0-.276-.119l-.002-.002a3.3 3.3 0 0 0-.292-.082zm3.338.317l.892 1.547c-.623.251-1.149.725-1.523 1.33h-1.652c-.262-.75-.741-1.38-1.358-1.764l.623-1.082c.394.347.919.559 1.492.559a2.25 2.25 0 0 0 1.526-.59zM7.46 12.09c.574 0 1.167.073 1.518.195.867.319 1.555 1.203 1.76 2.285l.001.002v.002c.109.513.173.98.227 1.424H9.86a.386.386 0 0 0-.494 0H9.11a1.351 1.351 0 0 0-.078-.418.799.799 0 0 0 .569.238c.45 0 .814-.375.814-.828a.824.824 0 0 0-.814-.828.822.822 0 0 0-.791 1.016 1.495 1.495 0 0 0-1.18-.559c-.798 0-1.46.611-1.48 1.38h-.342a.386.386 0 0 0-.494 0H4.028c.054-.445.116-.912.224-1.425l.002-.002v-.002c.205-1.084.894-1.97 1.764-2.287h.002l.004-.002c.295-.117.863-.191 1.437-.19zm-1.91 1.105a.898.898 0 0 0-.67.348l-.119.154.307.237.119-.155a.525.525 0 0 1 .379-.197.52.52 0 0 1 .377.147l.138.136.272-.275-.137-.137a.895.895 0 0 0-.666-.258zm4.094 0a.9.9 0 0 0-.668.258l-.137.137.273.275.137-.136a.522.522 0 0 1 .377-.147.525.525 0 0 1 .379.197l.119.155.307-.237-.12-.154a.894.894 0 0 0-.667-.348zm4.222.735a.947.947 0 0 0-.707.365l-.117.154.306.237.12-.155a.568.568 0 0 1 .413-.213.571.571 0 0 1 .414.159l.14.136.27-.275-.138-.137a.942.942 0 0 0-.701-.271zm4.374 0a.942.942 0 0 0-.7.271l-.14.137.272.275.139-.136a.571.571 0 0 1 .414-.159.568.568 0 0 1 .414.213l.119.155.306-.237-.117-.154a.947.947 0 0 0-.707-.365zm-12.65.232a.824.824 0 0 0-.815.828c0 .453.365.828.814.828.45 0 .815-.375.815-.828a.824.824 0 0 0-.815-.828zm5.518.285h1.242a4.137 4.137 0 0 0-.263.864v.002c-.05.237-.092.464-.127.685h-.602a16.77 16.77 0 0 0-.236-1.5l-.002-.002c-.003-.016-.009-.032-.012-.049zm-5.519.102a.43.43 0 0 1 .426.441.43.43 0 0 1-.426.442c-.22 0-.4-.171-.422-.397a.298.298 0 0 0 .215.092.31.31 0 0 0 .305-.316.317.317 0 0 0-.129-.258c.01-.001.02-.004.031-.004zm4.014 0c.235 0 .427.193.427.441a.433.433 0 0 1-.427.442.427.427 0 0 1-.422-.405.3.3 0 0 0 .256.145.31.31 0 0 0 .304-.317.314.314 0 0 0-.207-.298c.023-.004.045-.008.069-.008zm4.304.414a.865.865 0 0 0-.856.87c0 .478.382.874.856.874a.868.868 0 0 0 .857-.873.867.867 0 0 0-.857-.871zm4.292 0a.867.867 0 0 0-.814 1.14 1.597 1.597 0 0 0-1.295-.652c-.846 0-1.546.65-1.568 1.463l-1.525.408.066.248 1.477-.394c.004.028.009.06.015.087l-1.418.817.131.222 1.367-.789c.235.552.801.94 1.455.94.66 0 1.233-.397 1.463-.957l1.398.806.13-.222-1.45-.836c.005-.025.008-.053.012-.078l1.511.404.067-.248-1.563-.418a1.438 1.438 0 0 0-.107-.5c.157.186.39.303.648.303a.867.867 0 0 0 .856-.873.865.865 0 0 0-.856-.871zm-10.567.043c.598 0 1.071.444 1.092.992h-.41c.007-.01.016-.02.023-.033a.24.24 0 0 0 .025-.22c-.005-.016-.021-.102-.05-.196a.416.416 0 0 0-.078-.156.282.282 0 0 0-.225-.108.499.499 0 0 1-.129-.031c-.062-.021-.142-.05-.248-.05-.106 0-.188.029-.25.05a.49.49 0 0 1-.127.031.29.29 0 0 0-.225.108.424.424 0 0 0-.08.156c-.029.094-.043.18-.048.195a.242.242 0 0 0 .023.22c.008.014.017.023.025.034h-.41c.02-.548.494-.992 1.092-.992zm6.275.344c.259 0 .47.211.47.484a.477.477 0 0 1-.47.486.472.472 0 0 1-.467-.453.322.322 0 0 0 .246.115c.18 0 .326-.15.326-.338a.34.34 0 0 0-.156-.289c.017-.002.033-.005.05-.005zm4.292 0c.26 0 .469.211.469.484 0 .272-.21.486-.469.486a.477.477 0 0 1-.47-.486c0-.016.002-.031.004-.047a.33.33 0 0 0 .312.24c.18 0 .326-.15.326-.338a.338.338 0 0 0-.256-.332.475.475 0 0 1 .084-.007zm-10.567.24c.021 0 .063.01.125.031.086.03.117.039.186.049.012.041.022.088.033.129a1.475 1.475 0 0 1-.168.138c-.038.028-.064.045-.088.061h-.176c-.024-.016-.052-.033-.09-.06a1.602 1.602 0 0 1-.168-.14l.034-.128c.107-.014.146-.04.185-.049a.504.504 0 0 1 .127-.031zm8.458.25c.661 0 1.184.502 1.184 1.113 0 .156-.035.304-.096.44l-.002-.024-.022-.156a2.443 2.443 0 0 0-.04-.24l-.377.093.044.274a.24.24 0 0 1-.115.074.299.299 0 0 1-.168-.014c-.087-.03-.132-.063-.18-.094.057-.037.13-.084.198-.134.08-.06.16-.123.226-.19a.542.542 0 0 0 .092-.111.245.245 0 0 0 .026-.225c-.008-.019-.022-.112-.053-.21a.444.444 0 0 0-.084-.163.286.286 0 0 0-.23-.107.566.566 0 0 1-.14-.037c-.065-.022-.152-.055-.263-.055-.11 0-.195.032-.262.055a.575.575 0 0 1-.14.037.294.294 0 0 0-.23.107.436.436 0 0 0-.083.162c-.03.1-.045.192-.052.211a.246.246 0 0 0 .025.225.534.534 0 0 0 .09.111c.066.067.146.13.226.19.068.05.138.095.194.132a.57.57 0 0 1-.18.096.305.305 0 0 1-.17.014.237.237 0 0 1-.111-.076c.008-.09.026-.177.04-.272l-.376-.094c-.032.146-.045.286-.063.409a1.052 1.052 0 0 1-.09-.428c0-.611.521-1.113 1.182-1.113zm0 .623c.026 0 .074.01.14.033.066.025.169.052.206.055l.035.156c-.04.04-.112.1-.184.152-.095.07-.14.095-.197.131-.056-.036-.1-.061-.195-.13a1.236 1.236 0 0 1-.184-.157l.035-.152a1.04 1.04 0 0 0 .206-.055.523.523 0 0 1 .138-.033zm-2.22.353a.43.43 0 0 0-.385.272l.656-.176a.416.416 0 0 0-.271-.096zm4.333 0a.414.414 0 0 0-.22.07l.603.16a.426.426 0 0 0-.383-.23zm-4.054.567l-.607.162a.436.436 0 0 0 .125.113zm3.925.002l.407.234a.443.443 0 0 0 .087-.102zm-1.986.234c.067.047.165.108.285.148a.68.68 0 0 0 .389.024.57.57 0 0 0 .232-.121 1.201 1.201 0 0 1-.904.394c-.356 0-.67-.145-.885-.375a.58.58 0 0 0 .207.102c.144.036.28.014.391-.024.12-.04.218-.1.285-.148zm-9.524 1.61v.517h6.214v-.518zm3.619 1.292v.517H15.3v-.517z"/></svg>
+16
supacode/Assets.xcassets/CommandIcons/PostgreSQL.imageset/Contents.json
··· 1 + { 2 + "images" : [ 3 + { 4 + "filename" : "PostgreSQL.svg", 5 + "idiom" : "universal" 6 + } 7 + ], 8 + "info" : { 9 + "author" : "xcode", 10 + "version" : 1 11 + }, 12 + "properties" : { 13 + "preserves-vector-representation" : true, 14 + "template-rendering-intent" : "template" 15 + } 16 + }
+1
supacode/Assets.xcassets/CommandIcons/PostgreSQL.imageset/PostgreSQL.svg
··· 1 + <svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>PostgreSQL</title><path d="M23.5594 14.7228a.5269.5269 0 0 0-.0563-.1191c-.139-.2632-.4768-.3418-1.0074-.2321-1.6533.3411-2.2935.1312-2.5256-.0191 1.342-2.0482 2.445-4.522 3.0411-6.8297.2714-1.0507.7982-3.5237.1222-4.7316a1.5641 1.5641 0 0 0-.1509-.235C21.6931.9086 19.8007.0248 17.5099.0005c-1.4947-.0158-2.7705.3461-3.1161.4794a9.449 9.449 0 0 0-.5159-.0816 8.044 8.044 0 0 0-1.3114-.1278c-1.1822-.0184-2.2038.2642-3.0498.8406-.8573-.3211-4.7888-1.645-7.2219.0788C.9359 2.1526.3086 3.8733.4302 6.3043c.0409.818.5069 3.334 1.2423 5.7436.4598 1.5065.9387 2.7019 1.4334 3.582.553.9942 1.1259 1.5933 1.7143 1.7895.4474.1491 1.1327.1441 1.8581-.7279.8012-.9635 1.5903-1.8258 1.9446-2.2069.4351.2355.9064.3625 1.39.3772a.0569.0569 0 0 0 .0004.0041 11.0312 11.0312 0 0 0-.2472.3054c-.3389.4302-.4094.5197-1.5002.7443-.3102.064-1.1344.2339-1.1464.8115-.0025.1224.0329.2309.0919.3268.2269.4231.9216.6097 1.015.6331 1.3345.3335 2.5044.092 3.3714-.6787-.017 2.231.0775 4.4174.3454 5.0874.2212.5529.7618 1.9045 2.4692 1.9043.2505 0 .5263-.0291.8296-.0941 1.7819-.3821 2.5557-1.1696 2.855-2.9059.1503-.8707.4016-2.8753.5388-4.1012.0169-.0703.0357-.1207.057-.1362.0007-.0005.0697-.0471.4272.0307a.3673.3673 0 0 0 .0443.0068l.2539.0223.0149.001c.8468.0384 1.9114-.1426 2.5312-.4308.6438-.2988 1.8057-1.0323 1.5951-1.6698zM2.371 11.8765c-.7435-2.4358-1.1779-4.8851-1.2123-5.5719-.1086-2.1714.4171-3.6829 1.5623-4.4927 1.8367-1.2986 4.8398-.5408 6.108-.13-.0032.0032-.0066.0061-.0098.0094-2.0238 2.044-1.9758 5.536-1.9708 5.7495-.0002.0823.0066.1989.0162.3593.0348.5873.0996 1.6804-.0735 2.9184-.1609 1.1504.1937 2.2764.9728 3.0892.0806.0841.1648.1631.2518.2374-.3468.3714-1.1004 1.1926-1.9025 2.1576-.5677.6825-.9597.5517-1.0886.5087-.3919-.1307-.813-.5871-1.2381-1.3223-.4796-.839-.9635-2.0317-1.4155-3.5126zm6.0072 5.0871c-.1711-.0428-.3271-.1132-.4322-.1772.0889-.0394.2374-.0902.4833-.1409 1.2833-.2641 1.4815-.4506 1.9143-1.0002.0992-.126.2116-.2687.3673-.4426a.3549.3549 0 0 0 .0737-.1298c.1708-.1513.2724-.1099.4369-.0417.156.0646.3078.26.3695.4752.0291.1016.0619.2945-.0452.4444-.9043 1.2658-2.2216 1.2494-3.1676 1.0128zm2.094-3.988-.0525.141c-.133.3566-.2567.6881-.3334 1.003-.6674-.0021-1.3168-.2872-1.8105-.8024-.6279-.6551-.9131-1.5664-.7825-2.5004.1828-1.3079.1153-2.4468.079-3.0586-.005-.0857-.0095-.1607-.0122-.2199.2957-.2621 1.6659-.9962 2.6429-.7724.4459.1022.7176.4057.8305.928.5846 2.7038.0774 3.8307-.3302 4.7363-.084.1866-.1633.3629-.2311.5454zm7.3637 4.5725c-.0169.1768-.0358.376-.0618.5959l-.146.4383a.3547.3547 0 0 0-.0182.1077c-.0059.4747-.054.6489-.115.8693-.0634.2292-.1353.4891-.1794 1.0575-.11 1.4143-.8782 2.2267-2.4172 2.5565-1.5155.3251-1.7843-.4968-2.0212-1.2217a6.5824 6.5824 0 0 0-.0769-.2266c-.2154-.5858-.1911-1.4119-.1574-2.5551.0165-.5612-.0249-1.9013-.3302-2.6462.0044-.2932.0106-.5909.019-.8918a.3529.3529 0 0 0-.0153-.1126 1.4927 1.4927 0 0 0-.0439-.208c-.1226-.4283-.4213-.7866-.7797-.9351-.1424-.059-.4038-.1672-.7178-.0869.067-.276.1831-.5875.309-.9249l.0529-.142c.0595-.16.134-.3257.213-.5012.4265-.9476 1.0106-2.2453.3766-5.1772-.2374-1.0981-1.0304-1.6343-2.2324-1.5098-.7207.0746-1.3799.3654-1.7088.5321a5.6716 5.6716 0 0 0-.1958.1041c.0918-1.1064.4386-3.1741 1.7357-4.4823a4.0306 4.0306 0 0 1 .3033-.276.3532.3532 0 0 0 .1447-.0644c.7524-.5706 1.6945-.8506 2.802-.8325.4091.0067.8017.0339 1.1742.081 1.939.3544 3.2439 1.4468 4.0359 2.3827.8143.9623 1.2552 1.9315 1.4312 2.4543-1.3232-.1346-2.2234.1268-2.6797.779-.9926 1.4189.543 4.1729 1.2811 5.4964.1353.2426.2522.4522.2889.5413.2403.5825.5515.9713.7787 1.2552.0696.087.1372.1714.1885.245-.4008.1155-1.1208.3825-1.0552 1.717-.0123.1563-.0423.4469-.0834.8148-.0461.2077-.0702.4603-.0994.7662zm.8905-1.6211c-.0405-.8316.2691-.9185.5967-1.0105a2.8566 2.8566 0 0 0 .135-.0406 1.202 1.202 0 0 0 .1342.103c.5703.3765 1.5823.4213 3.0068.1344-.2016.1769-.5189.3994-.9533.6011-.4098.1903-1.0957.333-1.7473.3636-.7197.0336-1.0859-.0807-1.1721-.151zm.5695-9.2712c-.0059.3508-.0542.6692-.1054 1.0017-.055.3576-.112.7274-.1264 1.1762-.0142.4368.0404.8909.0932 1.3301.1066.887.216 1.8003-.2075 2.7014a3.5272 3.5272 0 0 1-.1876-.3856c-.0527-.1276-.1669-.3326-.3251-.6162-.6156-1.1041-2.0574-3.6896-1.3193-4.7446.3795-.5427 1.3408-.5661 2.1781-.463zm.2284 7.0137a12.3762 12.3762 0 0 0-.0853-.1074l-.0355-.0444c.7262-1.1995.5842-2.3862.4578-3.4385-.0519-.4318-.1009-.8396-.0885-1.2226.0129-.4061.0666-.7543.1185-1.0911.0639-.415.1288-.8443.1109-1.3505.0134-.0531.0188-.1158.0118-.1902-.0457-.4855-.5999-1.938-1.7294-3.253-.6076-.7073-1.4896-1.4972-2.6889-2.0395.5251-.1066 1.2328-.2035 2.0244-.1859 2.0515.0456 3.6746.8135 4.8242 2.2824a.908.908 0 0 1 .0667.1002c.7231 1.3556-.2762 6.2751-2.9867 10.5405zm-8.8166-6.1162c-.025.1794-.3089.4225-.6211.4225a.5821.5821 0 0 1-.0809-.0056c-.1873-.026-.3765-.144-.5059-.3156-.0458-.0605-.1203-.178-.1055-.2844.0055-.0401.0261-.0985.0925-.1488.1182-.0894.3518-.1226.6096-.0867.3163.0441.6426.1938.6113.4186zm7.9305-.4114c.0111.0792-.049.201-.1531.3102-.0683.0717-.212.1961-.4079.2232a.5456.5456 0 0 1-.075.0052c-.2935 0-.5414-.2344-.5607-.3717-.024-.1765.2641-.3106.5611-.352.297-.0414.6111.0088.6356.1851z"/></svg>
+16
supacode/Assets.xcassets/CommandIcons/Rust.imageset/Contents.json
··· 1 + { 2 + "images" : [ 3 + { 4 + "filename" : "Rust.svg", 5 + "idiom" : "universal" 6 + } 7 + ], 8 + "info" : { 9 + "author" : "xcode", 10 + "version" : 1 11 + }, 12 + "properties" : { 13 + "preserves-vector-representation" : true, 14 + "template-rendering-intent" : "template" 15 + } 16 + }
+1
supacode/Assets.xcassets/CommandIcons/Rust.imageset/Rust.svg
··· 1 + <svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Rust</title><path d="M23.8346 11.7033l-1.0073-.6236a13.7268 13.7268 0 00-.0283-.2936l.8656-.8069a.3483.3483 0 00-.1154-.578l-1.1066-.414a8.4958 8.4958 0 00-.087-.2856l.6904-.9587a.3462.3462 0 00-.2257-.5446l-1.1663-.1894a9.3574 9.3574 0 00-.1407-.2622l.49-1.0761a.3437.3437 0 00-.0274-.3361.3486.3486 0 00-.3006-.154l-1.1845.0416a6.7444 6.7444 0 00-.1873-.2268l.2723-1.153a.3472.3472 0 00-.417-.4172l-1.1532.2724a14.0183 14.0183 0 00-.2278-.1873l.0415-1.1845a.3442.3442 0 00-.49-.328l-1.076.491c-.0872-.0476-.1742-.0952-.2623-.1407l-.1903-1.1673A.3483.3483 0 0016.256.955l-.9597.6905a8.4867 8.4867 0 00-.2855-.086l-.414-1.1066a.3483.3483 0 00-.5781-.1154l-.8069.8666a9.2936 9.2936 0 00-.2936-.0284L12.2946.1683a.3462.3462 0 00-.5892 0l-.6236 1.0073a13.7383 13.7383 0 00-.2936.0284L9.9803.3374a.3462.3462 0 00-.578.1154l-.4141 1.1065c-.0962.0274-.1903.0567-.2855.086L7.744.955a.3483.3483 0 00-.5447.2258L7.009 2.348a9.3574 9.3574 0 00-.2622.1407l-1.0762-.491a.3462.3462 0 00-.49.328l.0416 1.1845a7.9826 7.9826 0 00-.2278.1873L3.8413 3.425a.3472.3472 0 00-.4171.4171l.2713 1.1531c-.0628.075-.1255.1509-.1863.2268l-1.1845-.0415a.3462.3462 0 00-.328.49l.491 1.0761a9.167 9.167 0 00-.1407.2622l-1.1662.1894a.3483.3483 0 00-.2258.5446l.6904.9587a13.303 13.303 0 00-.087.2855l-1.1065.414a.3483.3483 0 00-.1155.5781l.8656.807a9.2936 9.2936 0 00-.0283.2935l-1.0073.6236a.3442.3442 0 000 .5892l1.0073.6236c.008.0982.0182.1964.0283.2936l-.8656.8079a.3462.3462 0 00.1155.578l1.1065.4141c.0273.0962.0567.1914.087.2855l-.6904.9587a.3452.3452 0 00.2268.5447l1.1662.1893c.0456.088.0922.1751.1408.2622l-.491 1.0762a.3462.3462 0 00.328.49l1.1834-.0415c.0618.0769.1235.1528.1873.2277l-.2713 1.1541a.3462.3462 0 00.4171.4161l1.153-.2713c.075.0638.151.1255.2279.1863l-.0415 1.1845a.3442.3442 0 00.49.327l1.0761-.49c.087.0486.1741.0951.2622.1407l.1903 1.1662a.3483.3483 0 00.5447.2268l.9587-.6904a9.299 9.299 0 00.2855.087l.414 1.1066a.3452.3452 0 00.5781.1154l.8079-.8656c.0972.0111.1954.0203.2936.0294l.6236 1.0073a.3472.3472 0 00.5892 0l.6236-1.0073c.0982-.0091.1964-.0183.2936-.0294l.8069.8656a.3483.3483 0 00.578-.1154l.4141-1.1066a8.4626 8.4626 0 00.2855-.087l.9587.6904a.3452.3452 0 00.5447-.2268l.1903-1.1662c.088-.0456.1751-.0931.2622-.1407l1.0762.49a.3472.3472 0 00.49-.327l-.0415-1.1845a6.7267 6.7267 0 00.2267-.1863l1.1531.2713a.3472.3472 0 00.4171-.416l-.2713-1.1542c.0628-.0749.1255-.1508.1863-.2278l1.1845.0415a.3442.3442 0 00.328-.49l-.49-1.076c.0475-.0872.0951-.1742.1407-.2623l1.1662-.1893a.3483.3483 0 00.2258-.5447l-.6904-.9587.087-.2855 1.1066-.414a.3462.3462 0 00.1154-.5781l-.8656-.8079c.0101-.0972.0202-.1954.0283-.2936l1.0073-.6236a.3442.3442 0 000-.5892zm-6.7413 8.3551a.7138.7138 0 01.2986-1.396.714.714 0 11-.2997 1.396zm-.3422-2.3142a.649.649 0 00-.7715.5l-.3573 1.6685c-1.1035.501-2.3285.7795-3.6193.7795a8.7368 8.7368 0 01-3.6951-.814l-.3574-1.6684a.648.648 0 00-.7714-.499l-1.473.3158a8.7216 8.7216 0 01-.7613-.898h7.1676c.081 0 .1356-.0141.1356-.088v-2.536c0-.074-.0536-.0881-.1356-.0881h-2.0966v-1.6077h2.2677c.2065 0 1.1065.0587 1.394 1.2088.0901.3533.2875 1.5044.4232 1.8729.1346.413.6833 1.2381 1.2685 1.2381h3.5716a.7492.7492 0 00.1296-.0131 8.7874 8.7874 0 01-.8119.9526zM6.8369 20.024a.714.714 0 11-.2997-1.396.714.714 0 01.2997 1.396zM4.1177 8.9972a.7137.7137 0 11-1.304.5791.7137.7137 0 011.304-.579zm-.8352 1.9813l1.5347-.6824a.65.65 0 00.33-.8585l-.3158-.7147h1.2432v5.6025H3.5669a8.7753 8.7753 0 01-.2834-3.348zm6.7343-.5437V8.7836h2.9601c.153 0 1.0792.1772 1.0792.8697 0 .575-.7107.7815-1.2948.7815zm10.7574 1.4862c0 .2187-.008.4363-.0243.651h-.9c-.09 0-.1265.0586-.1265.1477v.413c0 .973-.5487 1.1846-1.0296 1.2382-.4576.0517-.9648-.1913-1.0275-.4717-.2704-1.5186-.7198-1.8436-1.4305-2.4034.8817-.5599 1.799-1.386 1.799-2.4915 0-1.1936-.819-1.9458-1.3769-2.3153-.7825-.5163-1.6491-.6195-1.883-.6195H5.4682a8.7651 8.7651 0 014.907-2.7699l1.0974 1.151a.648.648 0 00.9182.0213l1.227-1.1743a8.7753 8.7753 0 016.0044 4.2762l-.8403 1.8982a.652.652 0 00.33.8585l1.6178.7188c.0283.2875.0425.577.0425.8717zm-9.3006-9.5993a.7128.7128 0 11.984 1.0316.7137.7137 0 01-.984-1.0316zm8.3389 6.71a.7107.7107 0 01.9395-.3625.7137.7137 0 11-.9405.3635z"/></svg>
+16
supacode/Assets.xcassets/CommandIcons/SQLite.imageset/Contents.json
··· 1 + { 2 + "images" : [ 3 + { 4 + "filename" : "SQLite.svg", 5 + "idiom" : "universal" 6 + } 7 + ], 8 + "info" : { 9 + "author" : "xcode", 10 + "version" : 1 11 + }, 12 + "properties" : { 13 + "preserves-vector-representation" : true, 14 + "template-rendering-intent" : "template" 15 + } 16 + }
+1
supacode/Assets.xcassets/CommandIcons/SQLite.imageset/SQLite.svg
··· 1 + <svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>SQLite</title><path d="M21.678.521c-1.032-.92-2.28-.55-3.513.544a8.71 8.71 0 0 0-.547.535c-2.109 2.237-4.066 6.38-4.674 9.544.237.48.422 1.093.544 1.561a13.044 13.044 0 0 1 .164.703s-.019-.071-.096-.296l-.05-.146a1.689 1.689 0 0 0-.033-.08c-.138-.32-.518-.995-.686-1.289-.143.423-.27.818-.376 1.176.484.884.778 2.4.778 2.4s-.025-.099-.147-.442c-.107-.303-.644-1.244-.772-1.464-.217.804-.304 1.346-.226 1.478.152.256.296.698.422 1.186.286 1.1.485 2.44.485 2.44l.017.224a22.41 22.41 0 0 0 .056 2.748c.095 1.146.273 2.13.5 2.657l.155-.084c-.334-1.038-.47-2.399-.41-3.967.09-2.398.642-5.29 1.661-8.304 1.723-4.55 4.113-8.201 6.3-9.945-1.993 1.8-4.692 7.63-5.5 9.788-.904 2.416-1.545 4.684-1.931 6.857.666-2.037 2.821-2.912 2.821-2.912s1.057-1.304 2.292-3.166c-.74.169-1.955.458-2.362.629-.6.251-.762.337-.762.337s1.945-1.184 3.613-1.72C21.695 7.9 24.195 2.767 21.678.521m-18.573.543A1.842 1.842 0 0 0 1.27 2.9v16.608a1.84 1.84 0 0 0 1.835 1.834h9.418a22.953 22.953 0 0 1-.052-2.707c-.006-.062-.011-.141-.016-.2a27.01 27.01 0 0 0-.473-2.378c-.121-.47-.275-.898-.369-1.057-.116-.197-.098-.31-.097-.432 0-.12.015-.245.037-.386a9.98 9.98 0 0 1 .234-1.045l.217-.028c-.017-.035-.014-.065-.031-.097l-.041-.381a32.8 32.8 0 0 1 .382-1.194l.2-.019c-.008-.016-.01-.038-.018-.053l-.043-.316c.63-3.28 2.587-7.443 4.8-9.791.066-.069.133-.128.198-.194Z"/></svg>
+16
supacode/Assets.xcassets/CommandIcons/Swift.imageset/Contents.json
··· 1 + { 2 + "images" : [ 3 + { 4 + "filename" : "Swift.svg", 5 + "idiom" : "universal" 6 + } 7 + ], 8 + "info" : { 9 + "author" : "xcode", 10 + "version" : 1 11 + }, 12 + "properties" : { 13 + "preserves-vector-representation" : true, 14 + "template-rendering-intent" : "template" 15 + } 16 + }
+1
supacode/Assets.xcassets/CommandIcons/Swift.imageset/Swift.svg
··· 1 + <svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Swift</title><path d="M7.508 0c-.287 0-.573 0-.86.002-.241.002-.483.003-.724.01-.132.003-.263.009-.395.015A9.154 9.154 0 0 0 4.348.15 5.492 5.492 0 0 0 2.85.645 5.04 5.04 0 0 0 .645 2.848c-.245.48-.4.972-.495 1.5-.093.52-.122 1.05-.136 1.576a35.2 35.2 0 0 0-.012.724C0 6.935 0 7.221 0 7.508v8.984c0 .287 0 .575.002.862.002.24.005.481.012.722.014.526.043 1.057.136 1.576.095.528.25 1.02.495 1.5a5.03 5.03 0 0 0 2.205 2.203c.48.244.97.4 1.498.495.52.093 1.05.124 1.576.138.241.007.483.009.724.01.287.002.573.002.86.002h8.984c.287 0 .573 0 .86-.002.241-.001.483-.003.724-.01a10.523 10.523 0 0 0 1.578-.138 5.322 5.322 0 0 0 1.498-.495 5.035 5.035 0 0 0 2.203-2.203c.245-.48.4-.972.495-1.5.093-.52.124-1.05.138-1.576.007-.241.009-.481.01-.722.002-.287.002-.575.002-.862V7.508c0-.287 0-.573-.002-.86a33.662 33.662 0 0 0-.01-.724 10.5 10.5 0 0 0-.138-1.576 5.328 5.328 0 0 0-.495-1.5A5.039 5.039 0 0 0 21.152.645 5.32 5.32 0 0 0 19.654.15a10.493 10.493 0 0 0-1.578-.138 34.98 34.98 0 0 0-.722-.01C17.067 0 16.779 0 16.492 0H7.508zm6.035 3.41c4.114 2.47 6.545 7.162 5.549 11.131-.024.093-.05.181-.076.272l.002.001c2.062 2.538 1.5 5.258 1.236 4.745-1.072-2.086-3.066-1.568-4.088-1.043a6.803 6.803 0 0 1-.281.158l-.02.012-.002.002c-2.115 1.123-4.957 1.205-7.812-.022a12.568 12.568 0 0 1-5.64-4.838c.649.48 1.35.902 2.097 1.252 3.019 1.414 6.051 1.311 8.197-.002C9.651 12.73 7.101 9.67 5.146 7.191a10.628 10.628 0 0 1-1.005-1.384c2.34 2.142 6.038 4.83 7.365 5.576C8.69 8.408 6.208 4.743 6.324 4.86c4.436 4.47 8.528 6.996 8.528 6.996.154.085.27.154.36.213.085-.215.16-.437.224-.668.708-2.588-.09-5.548-1.893-7.992z"/></svg>
+16
supacode/Assets.xcassets/CommandIcons/Vim.imageset/Contents.json
··· 1 + { 2 + "images" : [ 3 + { 4 + "filename" : "Vim.svg", 5 + "idiom" : "universal" 6 + } 7 + ], 8 + "info" : { 9 + "author" : "xcode", 10 + "version" : 1 11 + }, 12 + "properties" : { 13 + "preserves-vector-representation" : true, 14 + "template-rendering-intent" : "template" 15 + } 16 + }
+1
supacode/Assets.xcassets/CommandIcons/Vim.imageset/Vim.svg
··· 1 + <svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Vim</title><path d="M24 11.986h-.027l-4.318-4.318 4.303-4.414V1.461l-.649-.648h-8.198l-.66.605v1.045L12.015.027V0L12 .014 11.986 0v.027l-1.29 1.291-.538-.539H2.035l-.638.692v1.885l.616.616h.72v5.31L.027 11.987H0L.014 12 0 12.014h.027l2.706 2.706v6.467l.907.523h2.322l1.857-1.904 4.166 4.166V24l.015-.014.014.014v-.028l2.51-2.509h.485c.111 0 .211-.07.25-.179l.146-.426c.028-.084.012-.172-.037-.239l1.462-1.462-.612 1.962c-.043.141.036.289.177.332.025.008.052.012.078.012h1.824c.106-.001.201-.064.243-.163l.165-.394c.025-.065.024-.138-.004-.203-.027-.065-.08-.116-.146-.142-.029-.012-.062-.019-.097-.02h-.075l.84-2.644h1.232l-1.016 3.221c-.043.141.036.289.176.332.025.008.052.012.079.012h2.002c.11 0 .207-.066.248-.17l.164-.428c.051-.138-.021-.29-.158-.341-.029-.011-.06-.017-.091-.017h-.145l1.131-3.673c.027-.082.012-.173-.039-.24l-.375-.504-.003-.005c-.051-.064-.127-.102-.209-.102h-1.436c-.071 0-.141.03-.19.081l-.4.439h-.624l-.042-.046 4.445-4.445H24L23.986 12l.014-.014zM9.838 21.139l1.579-4.509h-.501l.297-.304h1.659l-1.563 4.555h.623l-.079.258H9.838zm3.695-7.516l.15.151-.269.922-.225.226h-.969l-.181-.181.311-.871.288-.247h.895zM5.59 20.829H3.877l-.262-.15V3.091H2.379l-.1-.1V1.815l.143-.154h7.371l.213.214v1.108l-.142.173H8.785v8.688l8.807-8.688h-2.086l-.175-.188V1.805l.121-.111h7.49l.132.133v1.07L12.979 13.25h-.373c-.015-.001-.028 0-.042.001l-.02.003c-.045.01-.086.03-.119.06l-.343.295-.004.003c-.033.031-.059.069-.073.111l-.296.83-6.119 6.276zm14.768-3.952l.474-.519h1.334l.309.415-1.265 4.107h.493l-.08.209H19.84l1.124-3.564h-2.015l-1.077 3.391h.424l-.073.174h-1.605l1.107-3.548h-2.096l-1.062 3.339h.436l-.072.209H13.27l1.514-4.46H14.198l.091-.271h1.65l.519.537h.906l.491-.554h1.061l.489.535h.953z"/></svg>
+16
supacode/Assets.xcassets/CommandIcons/Xcode.imageset/Contents.json
··· 1 + { 2 + "images" : [ 3 + { 4 + "filename" : "Xcode.svg", 5 + "idiom" : "universal" 6 + } 7 + ], 8 + "info" : { 9 + "author" : "xcode", 10 + "version" : 1 11 + }, 12 + "properties" : { 13 + "preserves-vector-representation" : true, 14 + "template-rendering-intent" : "template" 15 + } 16 + }
+1
supacode/Assets.xcassets/CommandIcons/Xcode.imageset/Xcode.svg
··· 1 + <svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Xcode</title><path d="M19.06 5.3327c.4517-.1936.7744-.2581 1.097-.1936.5163.1291.7744.5163.968.7098.1936.3872.9034.7744 1.2261.8389.2581.0645.7098-.6453 1.0325-1.2906.3227-.5808.5163-1.3552.4517-1.5488-.0645-.1936-.968-.5808-1.1616-.5808-.1291 0-.3872.1291-.8389.0645-.4517-.0645-.9034-.5808-1.1616-.968-.4517-.6453-1.097-1.0325-1.6778-1.3552-.6453-.3227-1.3552-.5163-2.065-.6453-1.0325-.2581-2.065-.4517-3.0975-.3227-.5808.0645-1.2906.1291-1.8069.3227-.0645 0-.1936.1936-.0645.1936s.5808.0645.5808.0645-.5807.1292-.5807.2583c0 .1291.0645.1291.1291.1291.0645 0 1.4842-.0645 2.065 0 .6453.1291 1.3552.4517 1.8069 1.2261.7744 1.4197.4517 2.7749.2581 3.2266-.968 2.1295-8.6472 15.2294-9.0344 16.1328-.3873.9034-.5163 1.4842.5807 2.065s1.6778.3227 2.0005-.0645c.3872-.5163 7.0339-17.1654 9.2925-18.2624zm-3.6138 8.7117h1.5488c1.0325 0 1.2261.5163 1.2261.7098.0645.5163-.1936 1.1616-1.2261 1.1616h-.968l.7744 1.2906c.4517.7744.2581 1.1616 0 1.4197-.3872.3872-1.2261.3872-1.6778-.4517l-.9034-1.5488c-.6453 1.4197-1.2906 2.9684-2.065 4.7753h4.0009c1.9359 0 3.5492-1.6133 3.5492-3.5492V6.5588c-.0645-.1291-.1936-.0645-.2581 0-.3872.4517-1.4842 2.0004-4.001 7.4856zm-9.8087 8.0019h-.3227c-2.3231 0-4.1945-1.8714-4.1945-4.1945V7.0105c0-2.3231 1.8714-4.1945 4.1945-4.1945h9.3571c-.1936-.1936-.968-.5163-1.7423-.4517-.3227 0-.968.1291-1.3552-.1291-.3872-.3227-.3227-.5163-.9034-.5163H4.9277c-2.6458 0-4.7753 2.1295-4.7753 4.7753v11.7447c0 2.6458 2.1295 4.7753 4.4527 4.7108.6452 0 .8388-.5162 1.0324-.9034zM20.4152 6.9459v10.9058c0 2.3231-1.8714 4.1945-4.1945 4.1945H11.897s-.3872 1.0325.8389 1.0325h3.8719c2.6458 0 4.7753-2.1295 4.7753-4.7753V8.8173c.0646-.9034-.7098-1.4842-.9679-1.8714zm-18.5851.0646v10.8413c0 1.9359 1.6133 3.5492 3.5492 3.5492h.5808c0-.0645.7744-1.4197 2.4522-4.2591.1936-.3872.4517-.7744.7098-1.2261H4.4114c-.5808 0-.9034-.3872-.968-.7098-.1291-.5163.1936-1.1616.9034-1.1616h2.3877l3.033-5.2916s-.7098-1.2906-.9034-1.6133c-.2582-.4517-.1291-.9034.129-1.1615.3872-.3872 1.0325-.5808 1.6778.4517l.2581.3872.2581-.3872c.5808-.8389.968-.7744 1.2906-.7098.5163.1291.8389.7098.3872 1.6133L8.864 14.0444h1.3552c.4517-.7744.9034-1.5488 1.3552-2.3877-.0645-.3227-.1291-.7098-.0645-1.0325.0645-.5163.3227-.968.6453-1.3552l.3872.6453c1.2261-2.1295 2.1295-3.9364 2.3877-4.6463.1291-.3872.3227-1.1616.1291-1.8069H5.3794c-2.0005.0001-3.5493 1.6134-3.5493 3.5494zM4.605 17.7872c0-.0645.7744-1.4197.7744-1.4197 1.2261-.3227 1.8069.4517 1.8714.5163 0 0-.8389 1.4842-1.097 1.7423s-.5808.3227-.9034.2581c-.5164-.129-.839-.6453-.6454-1.097z"/></svg>
+16
supacode/Assets.xcassets/CommandIcons/Yarn.imageset/Contents.json
··· 1 + { 2 + "images" : [ 3 + { 4 + "filename" : "Yarn.svg", 5 + "idiom" : "universal" 6 + } 7 + ], 8 + "info" : { 9 + "author" : "xcode", 10 + "version" : 1 11 + }, 12 + "properties" : { 13 + "preserves-vector-representation" : true, 14 + "template-rendering-intent" : "template" 15 + } 16 + }
+1
supacode/Assets.xcassets/CommandIcons/Yarn.imageset/Yarn.svg
··· 1 + <svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Yarn</title><path d="M12 0C5.375 0 0 5.375 0 12s5.375 12 12 12 12-5.375 12-12S18.625 0 12 0zm.768 4.105c.183 0 .363.053.525.157.125.083.287.185.755 1.154.31-.088.468-.042.551-.019.204.056.366.19.463.375.477.917.542 2.553.334 3.605-.241 1.232-.755 2.029-1.131 2.576.324.329.778.899 1.117 1.825.278.774.31 1.478.273 2.015a5.51 5.51 0 0 0 .602-.329c.593-.366 1.487-.917 2.553-.931.714-.009 1.269.445 1.353 1.103a1.23 1.23 0 0 1-.945 1.362c-.649.158-.95.278-1.821.843-1.232.797-2.539 1.242-3.012 1.39a1.686 1.686 0 0 1-.704.343c-.737.181-3.266.315-3.466.315h-.046c-.783 0-1.214-.241-1.45-.491-.658.329-1.51.19-2.122-.134a1.078 1.078 0 0 1-.58-1.153 1.243 1.243 0 0 1-.153-.195c-.162-.25-.528-.936-.454-1.946.056-.723.556-1.367.88-1.71a5.522 5.522 0 0 1 .408-2.256c.306-.727.885-1.348 1.32-1.737-.32-.537-.644-1.367-.329-2.21.227-.602.412-.936.82-1.08h-.005c.199-.074.389-.153.486-.259a3.418 3.418 0 0 1 2.298-1.103c.037-.093.079-.185.125-.283.31-.658.639-1.029 1.024-1.168a.94.94 0 0 1 .328-.06zm.006.7c-.507.016-1.001 1.519-1.001 1.519s-1.27-.204-2.266.871c-.199.218-.468.334-.746.44-.079.028-.176.023-.417.672-.371.991.625 2.094.625 2.094s-1.186.839-1.626 1.881c-.486 1.144-.338 2.261-.338 2.261s-.843.732-.899 1.487c-.051.663.139 1.2.343 1.515.227.343.51.176.51.176s-.561.653-.037.931c.477.25 1.283.394 1.71-.037.31-.31.371-1.001.486-1.283.028-.065.12.111.209.199.097.093.264.195.264.195s-.755.324-.445 1.066c.102.246.468.403 1.066.398.222-.005 2.664-.139 3.313-.296.375-.088.505-.283.505-.283s1.566-.431 2.998-1.357c.917-.598 1.293-.76 2.034-.936.612-.148.57-1.098-.241-1.084-.839.009-1.575.44-2.196.825-1.163.718-1.742.672-1.742.672l-.018-.032c-.079-.13.371-1.293-.134-2.678-.547-1.515-1.413-1.881-1.344-1.997.297-.5 1.038-1.297 1.334-2.78.176-.899.13-2.377-.269-3.151-.074-.144-.732.241-.732.241s-.616-1.371-.788-1.483a.271.271 0 0 0-.157-.046z"/></svg>
+14 -8
supacode/Features/Shelf/Views/ShelfSpineView.swift
··· 350 350 } 351 351 .accessibilityHidden(true) 352 352 } else { 353 - Image(systemName: tab.icon ?? ShelfMetrics.defaultTabIcon) 354 - .imageScale(.medium) 355 - .foregroundStyle(foregroundTint) 356 - // Dim tabs without a hotkey when ⌘ is held, so the "this slot 357 - // can't be jumped to via Cmd+N" affordance is legible without 358 - // shifting any layout. 359 - .opacity(commandKeyObserver.isPressed && hotkeyIndex == nil ? 0.45 : 1) 360 - .accessibilityHidden(true) 353 + TabIconImage( 354 + rawName: tab.icon ?? ShelfMetrics.defaultTabIcon, 355 + pointSize: ShelfMetrics.tabIconPointSize 356 + ) 357 + .foregroundStyle(foregroundTint) 358 + // Dim tabs without a hotkey when ⌘ is held, so the "this slot 359 + // can't be jumped to via Cmd+N" affordance is legible without 360 + // shifting any layout. 361 + .opacity(commandKeyObserver.isPressed && hotkeyIndex == nil ? 0.45 : 1) 362 + .accessibilityHidden(true) 361 363 } 362 364 } 363 365 ··· 418 420 static let headerMaxLength: CGFloat = 160 419 421 /// Fallback icon when a tab has no custom icon set. 420 422 static let defaultTabIcon: String = "terminal" 423 + /// Point size used by `TabIconImage` for both the SF Symbol 424 + /// (`.font(.system(size:))`) and the asset (`.frame`) branches so 425 + /// branded artwork visually matches the SF-Symbol fallback. 426 + static let tabIconPointSize: CGFloat = 18 421 427 }
+29 -59
supacode/Features/Terminal/Models/CommandIconMap.swift
··· 2 2 3 3 /// Resolves a tab icon from a command title surfaced by the 4 4 /// auto-detector (typically the OSC 2 title set by the shell's 5 - /// `preexec`, or one a TUI rewrites on launch). 6 - /// 7 - /// Two lookup paths exist: 5 + /// `preexec`). 8 6 /// 9 - /// - `iconForFirstToken(_:)`: case-insensitive match on the *first 10 - /// whitespace-delimited token*. Used by the debounce path so short 11 - /// commands (`ls`, `git status`) never trigger an icon swap. 12 - /// Examples: `"swift build"` and `"swift test"` route through the 13 - /// `swift` entry; `"claude"` routes through `claude`. 14 - /// 15 - /// - `iconForSubstring(_:)`: case-insensitive substring match against 16 - /// the entire title. Used as an immediate-apply path that bypasses 17 - /// the debounce, intended for TUI tools that overwrite their own 18 - /// title after launch (e.g. `claude` → `✳ Claude Code`). The 19 - /// substring rule wins so a TUI's branded title can refine the 20 - /// icon set by the initial command name. 7 + /// Lookup is case-insensitive on the *first whitespace-delimited 8 + /// token*. Examples: `"swift build"` and `"swift test"` route through 9 + /// the `swift` entry; `"claude"` routes through `claude`. 21 10 /// 22 - /// Both return `nil` when nothing matches; the auto-detector then 23 - /// leaves the tab's existing icon untouched (selection-2 semantics — 24 - /// a previously-detected icon is preserved across unknown commands). 11 + /// Returns `nil` when nothing matches; the auto-detector then leaves 12 + /// the tab's existing icon untouched (selection-2 semantics — a 13 + /// previously-detected icon is preserved across unknown commands). 25 14 enum CommandIconMap { 26 15 static func iconForFirstToken(_ title: String) -> TabIconSource? { 27 16 let token = firstToken(of: title).lowercased() 28 17 return firstTokenMapping[token] 29 - } 30 - 31 - static func iconForSubstring(_ title: String) -> TabIconSource? { 32 - let lowered = title.lowercased() 33 - for (needle, icon) in substringMapping where lowered.contains(needle) { 34 - return icon 35 - } 36 - return nil 37 18 } 38 19 39 20 private static func firstToken(of title: String) -> String { ··· 49 30 /// before asset rendering is wired; entries that ship branded 50 31 /// artwork should add `assetName:` and let renderers prefer it. 51 32 private static let firstTokenMapping: [String: TabIconSource] = [ 52 - // Coding agents — the SF Symbol is just a placeholder so the icon 53 - // is non-blank; the real branded artwork is picked up via the 54 - // substring path (which routes the post-launch TUI title to an 55 - // assetName entry). 56 - "claude": TabIconSource(systemSymbol: "sparkle", assetName: "Claude Code"), 57 - "codex": TabIconSource(systemSymbol: "sparkle"), 33 + // Coding agents 34 + "claude": TabIconSource(systemSymbol: "sparkle", assetName: "ClaudeCode"), 35 + "codex": TabIconSource(systemSymbol: "sparkle", assetName: "Codex"), 58 36 "aider": TabIconSource(systemSymbol: "sparkle"), 59 37 60 38 // Editors / pagers 61 - "vim": TabIconSource(systemSymbol: "pencil.and.scribble"), 62 - "nvim": TabIconSource(systemSymbol: "pencil.and.scribble"), 39 + "vim": TabIconSource(systemSymbol: "pencil.and.scribble", assetName: "Vim"), 40 + "nvim": TabIconSource(systemSymbol: "pencil.and.scribble", assetName: "Neovim"), 63 41 "nano": TabIconSource(systemSymbol: "pencil.and.scribble"), 64 42 65 43 // Package managers / JS runtimes 66 - "npm": TabIconSource(systemSymbol: "shippingbox"), 67 - "pnpm": TabIconSource(systemSymbol: "shippingbox"), 68 - "yarn": TabIconSource(systemSymbol: "shippingbox"), 69 - "bun": TabIconSource(systemSymbol: "shippingbox"), 44 + "npm": TabIconSource(systemSymbol: "shippingbox", assetName: "Npm"), 45 + "pnpm": TabIconSource(systemSymbol: "shippingbox", assetName: "Pnpm"), 46 + "yarn": TabIconSource(systemSymbol: "shippingbox", assetName: "Yarn"), 47 + "bun": TabIconSource(systemSymbol: "shippingbox", assetName: "Bun"), 70 48 71 49 // VCS 72 - "git": TabIconSource(systemSymbol: "arrow.triangle.branch"), 73 - "gh": TabIconSource(systemSymbol: "arrow.triangle.branch"), 50 + "git": TabIconSource(systemSymbol: "arrow.triangle.branch", assetName: "Git"), 51 + "gh": TabIconSource(systemSymbol: "arrow.triangle.branch", assetName: "GitHub"), 74 52 75 53 // Build tools 76 54 "make": TabIconSource(systemSymbol: "hammer"), 77 - "swift": TabIconSource(systemSymbol: "hammer"), 78 - "cargo": TabIconSource(systemSymbol: "hammer"), 79 - "xcodebuild": TabIconSource(systemSymbol: "hammer"), 80 - "gradle": TabIconSource(systemSymbol: "hammer"), 55 + "swift": TabIconSource(systemSymbol: "hammer", assetName: "Swift"), 56 + "cargo": TabIconSource(systemSymbol: "hammer", assetName: "Rust"), 57 + "xcodebuild": TabIconSource(systemSymbol: "hammer", assetName: "Xcode"), 58 + "gradle": TabIconSource(systemSymbol: "hammer", assetName: "Gradle"), 81 59 82 60 // Container / orchestration 83 - "docker": TabIconSource(systemSymbol: "shippingbox.fill"), 84 - "kubectl": TabIconSource(systemSymbol: "shippingbox.fill"), 85 - "podman": TabIconSource(systemSymbol: "shippingbox.fill"), 61 + "docker": TabIconSource(systemSymbol: "shippingbox.fill", assetName: "Docker"), 62 + "kubectl": TabIconSource(systemSymbol: "shippingbox.fill", assetName: "Kubernetes"), 63 + "podman": TabIconSource(systemSymbol: "shippingbox.fill", assetName: "Podman"), 86 64 87 65 // Network / remote 88 66 "ssh": TabIconSource(systemSymbol: "network"), 89 67 "mosh": TabIconSource(systemSymbol: "network"), 90 - "curl": TabIconSource(systemSymbol: "network"), 68 + "curl": TabIconSource(systemSymbol: "network", assetName: "Curl"), 91 69 92 70 // Process / system viewers 93 71 "htop": TabIconSource(systemSymbol: "waveform.path.ecg"), ··· 95 73 "top": TabIconSource(systemSymbol: "waveform.path.ecg"), 96 74 97 75 // Database REPLs 98 - "psql": TabIconSource(systemSymbol: "cylinder.split.1x2"), 99 - "mysql": TabIconSource(systemSymbol: "cylinder.split.1x2"), 100 - "sqlite3": TabIconSource(systemSymbol: "cylinder.split.1x2"), 76 + "psql": TabIconSource(systemSymbol: "cylinder.split.1x2", assetName: "PostgreSQL"), 77 + "mysql": TabIconSource(systemSymbol: "cylinder.split.1x2", assetName: "MySQL"), 78 + "sqlite3": TabIconSource(systemSymbol: "cylinder.split.1x2", assetName: "SQLite"), 101 79 102 80 // Logs / streams 103 81 "tail": TabIconSource(systemSymbol: "text.justifyleft"), 104 82 "journalctl": TabIconSource(systemSymbol: "text.justifyleft"), 105 - ] 106 - 107 - /// Substring patterns for TUI tools that rewrite their own title 108 - /// after launch. Needles are matched case-insensitively against the 109 - /// full title; the first match wins, so list more specific 110 - /// patterns earlier when conflicts arise. 111 - private static let substringMapping: [(needle: String, icon: TabIconSource)] = [ 112 - ("claude code", TabIconSource(systemSymbol: "sparkle", assetName: "Claude Code")), 113 83 ] 114 84 }
+41 -20
supacode/Features/Terminal/Models/TabIconSource.swift
··· 1 1 import Foundation 2 2 3 - /// Specifies the artwork to use for a tab icon. `systemSymbol` is the 4 - /// always-renderable SF Symbol that the current call sites paint 5 - /// (`Image(systemName:)` in `ShelfSpineView` and 6 - /// `TerminalTabLabelView`). `assetName` is an optional, more specific 7 - /// PNG/SVG shipped in the asset catalog — reserved for tools where 8 - /// stock SF Symbols don't read well (claude, docker, npm, …). 3 + /// Specifies the artwork to use for a tab icon. `systemSymbol` is an 4 + /// always-available SF Symbol fallback; `assetName` is an optional, 5 + /// more specific PNG/SVG shipped in the asset catalog (used for 6 + /// branded CLI tools like docker/git/claude where stock SF Symbols 7 + /// don't read well). 9 8 /// 10 - /// Today no call site reads `assetName`, so `assetName`-bearing 11 - /// entries gracefully degrade to their `systemSymbol`. To wire real 12 - /// asset rendering: 13 - /// 1. Ship the artwork in the app's asset catalog. 14 - /// 2. Add an `assetName:` argument on the relevant `CommandIconMap` 15 - /// entry (or use it on a new `TabIconSource(systemSymbol:assetName:)`). 16 - /// 3. Extend the icon-rendering call sites to prefer `assetName` 17 - /// when present (`Image(_:)`) and fall back to `systemSymbol` 18 - /// when the asset is missing. 9 + /// Renderers prefer `assetName` when present, falling back to 10 + /// `systemSymbol` when the asset is missing or asset rendering isn't 11 + /// yet wired into a particular call site. 19 12 struct TabIconSource: Equatable, Hashable, Sendable { 20 - /// SF Symbol drawn via `Image(systemName:)`. Always set so callers 21 - /// have something renderable even before asset rendering is wired. 13 + /// SF Symbol drawn via `Image(systemName:)`. 22 14 let systemSymbol: String 23 - /// Asset catalog entry, if any. Renderers that support assets 24 - /// should prefer this when set; renderers that don't will keep 25 - /// painting `systemSymbol` and the user gets a graceful fallback. 15 + /// Asset catalog entry. When set, renderers paint `Image(_:)` for 16 + /// this name and ignore `systemSymbol`; when missing, they fall 17 + /// back to the SF Symbol. 26 18 let assetName: String? 27 19 28 20 init(systemSymbol: String, assetName: String? = nil) { 29 21 self.systemSymbol = systemSymbol 30 22 self.assetName = assetName 23 + } 24 + 25 + /// Serialised form stored in `TerminalTabItem.icon`. SF Symbols are 26 + /// stored bare (so existing `tab.icon = "terminal"` keeps working 27 + /// for the user-icon-picker path); assets carry a marker so the 28 + /// renderer can switch APIs. 29 + var storageString: String { 30 + if let assetName { 31 + return ResolvedTabIcon.assetMarker + assetName 32 + } 33 + return systemSymbol 34 + } 35 + } 36 + 37 + /// What `TerminalTabItem.icon` resolves to once parsed by the 38 + /// renderer. Built from a stored string via `parse(_:)` — the inverse 39 + /// of `TabIconSource.storageString`. Lives next to `TabIconSource` 40 + /// because the two share the marker convention. 41 + enum ResolvedTabIcon: Equatable, Hashable, Sendable { 42 + case systemSymbol(String) 43 + case asset(name: String) 44 + 45 + static let assetMarker = "@asset:" 46 + 47 + static func parse(_ raw: String) -> ResolvedTabIcon { 48 + if raw.hasPrefix(assetMarker) { 49 + return .asset(name: String(raw.dropFirst(assetMarker.count))) 50 + } 51 + return .systemSymbol(raw) 31 52 } 32 53 }
+50 -161
supacode/Features/Terminal/Models/WorktreeTerminalState.swift
··· 15 15 let isFocused: Bool 16 16 } 17 17 18 - /// Pending state for the title-debounce-based command detector. 19 - /// `task` fires after `commandDetectThresholdMs` if no further title 20 - /// change arrives — at which point `title` is treated as a likely 21 - /// long-running command. Cancelled when a new title arrives, when 22 - /// the surface goes away, or when `command_finished` is received. 23 - fileprivate struct CommandDetectorPending { 24 - let title: String 25 - let startedAt: ContinuousClock.Instant 26 - let task: Task<Void, Never> 27 - } 28 - 29 18 let tabManager: TerminalTabManager 30 19 private let runtime: GhosttyRuntime 31 20 private let worktree: Worktree ··· 61 50 /// Surfaces running a tracked Custom Command. The stored name is surfaced as a success 62 51 /// toast when the command exits with code 0. One-shot: removed on the first finish event. 63 52 private var pendingCustomCommands: [UUID: String] = [:] 64 - /// Per-surface pending state for the title-debounce-based tab-icon 65 - /// auto-detection. Research/log-only for now: records the most recent 66 - /// non-empty OSC 2 title and fires a timer after 67 - /// `commandDetectThresholdMs` to distinguish long-running commands 68 - /// (worth reflecting in the tab icon) from short ones (e.g. `ls`, 69 - /// `git status`) that would just cause icon flicker. 70 - private var commandDetectorPendingBySurface: [UUID: CommandDetectorPending] = [:] 71 - /// The title that was the active candidate immediately before the 72 - /// current one — i.e. the title set by `preexec` for the command 73 - /// that just ran. By the time `onCommandFinished` arrives, `precmd` 74 - /// has already overwritten the live title with the idle prompt, so 75 - /// the "current" candidate would be useless for naming the just- 76 - /// finished command. This slot preserves the real command name. 77 - /// Cleared each time a `command_finished` event consumes it. 78 - private var lastObservedTitleBySurface: [UUID: String] = [:] 79 53 /// Per-surface set of titles known to be the shell's idle prompt 80 - /// (between commands). Populated by observing the first title that 81 - /// arrives after each `command_finished`: that title is reliably 82 - /// `precmd`-set, i.e. an idle prompt. Subsequent occurrences of any 83 - /// learned title skip the debounce timer entirely so they cannot 84 - /// trigger spurious `[live]` "long-running command" reports. 54 + /// (the title `precmd` restores between commands). Populated by 55 + /// observing the first title that arrives after each 56 + /// `command_finished` — reliably the precmd-set prompt. Subsequent 57 + /// occurrences are skipped so they can't clobber the icon set by a 58 + /// real command. 85 59 private var learnedIdleTitlesBySurface: [UUID: Set<String>] = [:] 86 - /// Surfaces whose next title-change event should be added to 87 - /// `learnedIdleTitlesBySurface`. Set by `command_finished`, consumed 88 - /// by the next title arrival. 60 + /// Surfaces whose next title-change should be added to 61 + /// `learnedIdleTitlesBySurface`. Armed by `command_finished`, 62 + /// consumed by the next title arrival. 89 63 private var awaitingIdleTitleLearningBySurface: Set<UUID> = [] 90 - /// Per-surface guard recording the title that has already been 91 - /// reported as the running command for the current command cycle. 92 - /// While set, further title changes for the same surface skip the 93 - /// debounce timer — a long-running TUI (claude, vim) frequently 94 - /// rewrites its title (`claude` → `✳ Claude Code` → `⠐ Claude Code`) 95 - /// and we only want to surface the initial command name once per 96 - /// run. Cleared on `command_finished`. 97 - private var reportedRunningCommandBySurface: [UUID: String] = [:] 98 64 var hasUnseenNotification: Bool { 99 65 notifications.contains { !$0.isRead } 100 66 } ··· 1456 1422 appendNotification(title: title, body: body, surfaceId: surfaceId) 1457 1423 } 1458 1424 1459 - // MARK: - Tab Icon Auto-Detection (research / log only) 1425 + // MARK: - Tab Icon Auto-Detection 1426 + // 1427 + // Strategy: each OSC 2 title change is matched against 1428 + // `CommandIconMap` (substring rules first, then first-token). A hit 1429 + // applies the icon immediately — no debounce. Rationale: the 1430 + // mapping is a curated allow-list, so a hit is by definition a 1431 + // command we're happy to brand the tab with; a miss leaves the 1432 + // existing icon untouched (selection-2 semantics). 1460 1433 // 1461 - // Strategy: each OSC 2 title change starts a per-surface debounce 1462 - // timer. If the title is still in place after the threshold, it is a 1463 - // likely long-running command worth turning into a tab icon. Short 1464 - // titles (`ls`, `git status`, …) get overwritten by the shell's idle 1465 - // prompt long before the threshold fires and are silently dropped. 1466 - // `command_finished` lets us cross-check duration: if the command 1467 - // exceeded the threshold, log it as a confirmed long-running entry 1468 - // even when its title timer was cancelled by a precmd-driven retitle. 1434 + // Idle-prompt suppression keeps the lookup focused on real 1435 + // commands: the first title after each `command_finished` is the 1436 + // shell's `precmd`-set prompt, and gets memorised into a learned- 1437 + // idle set so we never reach the mapping with a `user@host`-style 1438 + // string. Shape heuristics (`isLikelyIdleTitleByShape`) cover the 1439 + // bootstrap window before the learner has seen anything. 1469 1440 // 1470 - // For now this layer only emits log lines so the user can validate 1471 - // detection accuracy across their real workflows before we wire any 1472 - // icon-mapping logic on top. 1473 - 1474 - private static let commandDetectThresholdMs = 1500 1441 + // The mapping-hit-equals-apply rule also unblocks short-lived 1442 + // commands (`git status`, `cd foo`) and TUIs that immediately 1443 + // overwrite their preexec title (`codex` → repo name) — both used 1444 + // to slip past a debounce-based detector. 1475 1445 1476 1446 func noteTitleForCommandDetection(_ rawTitle: String, surfaceId: UUID, tabId: TerminalTabID) { 1477 1447 let title = rawTitle.trimmingCharacters(in: .whitespacesAndNewlines) 1478 - // Empty titles tend to mean "shell reset between commands" — that's 1479 - // an end-of-candidate signal, not a new candidate. 1480 - guard !title.isEmpty else { 1481 - cancelCommandDetectionTimer(forSurfaceId: surfaceId) 1482 - return 1483 - } 1484 - // Same title again (common when shells re-emit the OSC on every 1485 - // prompt redraw) is a no-op so the existing timer keeps ticking. 1486 - if let pending = commandDetectorPendingBySurface[surfaceId], pending.title == title { 1487 - return 1488 - } 1489 - // (A) The first title to arrive after `command_finished` is the 1490 - // shell's idle prompt for this surface. Memorise it so future 1491 - // appearances skip the debounce. 1448 + guard !title.isEmpty else { return } 1449 + // Learn this surface's idle prompt: the first title after 1450 + // `command_finished` is reliably the precmd-set one. 1492 1451 if awaitingIdleTitleLearningBySurface.remove(surfaceId) != nil { 1493 1452 learnedIdleTitlesBySurface[surfaceId, default: []].insert(title) 1494 1453 } 1495 - // Substring path: TUI tools that rewrite their own title after 1496 - // launch (e.g. `claude` → `✳ Claude Code`). These bypass the 1497 - // debounce — the title *is* the brand signal, no need to wait — 1498 - // and they bypass the per-cycle `reportedRunning` guard so they 1499 - // can refine an icon already set by the initial command name. 1500 - if let immediateIcon = CommandIconMap.iconForSubstring(title) { 1501 - applyResolvedIcon(immediateIcon, surfaceId: surfaceId, tabId: tabId) 1502 - return 1503 - } 1504 - // Decide whether this title should arm a debounce timer. Skip when: 1505 - // (B) it looks like an idle prompt by shape — bootstraps before 1506 - // the learner has seen `command_finished` once on this surface. 1507 - // (A) it matches a learned idle prompt for this surface. 1508 - // (D) the surface is mid-command and we already reported one — a 1509 - // long-running TUI keeps mutating its title (claude's 1510 - // spinner cycles through `✳ Claude Code` → `⠐ Claude Code` 1511 - // etc.) but it's still the same run. 1512 - let isLearnedIdle = learnedIdleTitlesBySurface[surfaceId]?.contains(title) ?? false 1513 - let shouldDebounce = 1514 - !isLikelyIdleTitleByShape(title) 1515 - && !isLearnedIdle 1516 - && reportedRunningCommandBySurface[surfaceId] == nil 1517 - guard shouldDebounce else { return } 1518 - // Park the about-to-be-replaced candidate as the "previous" title 1519 - // so a subsequent `command_finished` can name the just-finished 1520 - // command correctly even though `precmd` will have set the live 1521 - // title back to the idle prompt by then. 1522 - if let outgoing = commandDetectorPendingBySurface[surfaceId] { 1523 - lastObservedTitleBySurface[surfaceId] = outgoing.title 1524 - } 1525 - commandDetectorPendingBySurface[surfaceId]?.task.cancel() 1526 - let startedAt = ContinuousClock.now 1527 - let task = Task { [weak self] in 1528 - try? await Task.sleep(for: .milliseconds(WorktreeTerminalState.commandDetectThresholdMs)) 1529 - guard !Task.isCancelled else { return } 1530 - self?.commandDetectionTimerFired(forSurfaceId: surfaceId, tabId: tabId) 1531 - } 1532 - commandDetectorPendingBySurface[surfaceId] = CommandDetectorPending( 1533 - title: title, 1534 - startedAt: startedAt, 1535 - task: task 1536 - ) 1454 + // Drop idle prompts so they can't reach the mapping lookup. 1455 + if isLikelyIdleTitleByShape(title) { return } 1456 + if learnedIdleTitlesBySurface[surfaceId]?.contains(title) == true { return } 1457 + guard let icon = CommandIconMap.iconForFirstToken(title) else { return } 1458 + applyResolvedIcon(icon, surfaceId: surfaceId, tabId: tabId) 1537 1459 } 1538 1460 1539 1461 func noteCommandFinishedForCommandDetection(surfaceId: UUID) { 1540 - // Drop transient pending/parked state, reset the per-cycle 1541 - // "already reported" guard, and arm the idle-prompt learner so 1542 - // the next title (the precmd-set prompt) gets memorised. 1543 - cancelCommandDetectionTimer(forSurfaceId: surfaceId) 1544 - reportedRunningCommandBySurface.removeValue(forKey: surfaceId) 1462 + // Arm the idle-prompt learner: the next title arrival is the 1463 + // precmd-set prompt and should join the learned-idle set. 1545 1464 awaitingIdleTitleLearningBySurface.insert(surfaceId) 1546 1465 } 1547 1466 1548 - /// Cancel the in-flight debounce timer and discard the transient 1549 - /// pending/parked title state. Persistent learning state (learned 1550 - /// idle prompts, per-cycle reported guard) is left intact so it can 1551 - /// keep filtering across command boundaries. Use 1552 - /// `cleanupCommandDetectorState(forSurfaceId:)` instead when the 1553 - /// surface itself is being torn down. 1554 - func cancelCommandDetectionTimer(forSurfaceId surfaceId: UUID) { 1555 - commandDetectorPendingBySurface.removeValue(forKey: surfaceId)?.task.cancel() 1556 - lastObservedTitleBySurface.removeValue(forKey: surfaceId) 1557 - } 1558 - 1559 - /// Drop every detector slot keyed by this surface. Called when a 1560 - /// surface is closed or its parent tab is torn down so we don't 1561 - /// retain learned-idle sets / pending tasks for ids that will never 1562 - /// emit again. 1467 + /// Drop the per-surface detector state. Called when a surface is 1468 + /// closed or its parent tab is torn down so we don't retain 1469 + /// learned-idle sets keyed by ids that will never emit again. 1563 1470 func cleanupCommandDetectorState(forSurfaceId surfaceId: UUID) { 1564 - cancelCommandDetectionTimer(forSurfaceId: surfaceId) 1565 1471 learnedIdleTitlesBySurface.removeValue(forKey: surfaceId) 1566 1472 awaitingIdleTitleLearningBySurface.remove(surfaceId) 1567 - reportedRunningCommandBySurface.removeValue(forKey: surfaceId) 1568 1473 } 1569 1474 1570 - /// Heuristic shape-only detection for shell idle prompts. Used as 1571 - /// the bootstrap filter so the very first time a surface goes idle 1572 - /// — before the learner has anything to match against — we can 1573 - /// still skip the false-positive `[live]` report. Two patterns: 1475 + /// Heuristic shape-only detection for shell idle prompts. The 1476 + /// bootstrap filter — before `awaitingIdleTitleLearning` has caught 1477 + /// the precmd-set prompt at least once on this surface — for two 1478 + /// common forms: 1574 1479 /// 1. `user@host[:path]` — contains `@` plus `:` or `/`, no spaces. 1575 1480 /// 2. Pure path — starts with `~`, `/`, or `…`, no spaces. 1576 1481 /// Real commands typically contain a space (program + args) or a ··· 1587 1492 return false 1588 1493 } 1589 1494 1590 - private func commandDetectionTimerFired(forSurfaceId surfaceId: UUID, tabId: TerminalTabID) { 1591 - guard let pending = commandDetectorPendingBySurface[surfaceId] else { return } 1592 - // Mark this command as already reported so subsequent title 1593 - // mutations within the same run (claude's spinner, vim's mode 1594 - // line, …) don't fire additional debounce passes until 1595 - // `command_finished` clears the guard. 1596 - reportedRunningCommandBySurface[surfaceId] = pending.title 1597 - if let icon = CommandIconMap.iconForFirstToken(pending.title) { 1598 - applyResolvedIcon(icon, surfaceId: surfaceId, tabId: tabId) 1599 - } 1600 - } 1601 - 1602 - /// Apply an already-resolved icon to the tab. Shared between the 1603 - /// debounce-driven first-token path and the substring-driven 1604 - /// immediate path so focus / lock / unchanged checks stay in one 1605 - /// place. 1495 + /// Apply an already-resolved icon to the tab. Honours focus and 1496 + /// user-icon-lock; encodes the icon through `storageString` so 1497 + /// `assetName`-bearing entries pick up the `@asset:` marker the 1498 + /// renderers parse via `ResolvedTabIcon`. 1606 1499 private func applyResolvedIcon( 1607 1500 _ icon: TabIconSource, 1608 1501 surfaceId: UUID, ··· 1615 1508 guard focusedSurfaceIdByTab[tabId] == surfaceId else { return } 1616 1509 guard let tab = tabManager.tabs.first(where: { $0.id == tabId }) else { return } 1617 1510 guard !tab.isIconLocked else { return } 1618 - // `tab.icon` storage is the SF Symbol string; the asset variant 1619 - // (when set) is the real branding, but rendering hasn't been 1620 - // wired yet so we still write the symbol. See `TabIconSource` 1621 - // docs for the three-step recipe to enable asset rendering. 1622 - let symbol = icon.systemSymbol 1623 - guard tab.icon != symbol else { return } 1624 - tabManager.updateIcon(tabId, icon: symbol) 1511 + let serialised = icon.storageString 1512 + guard tab.icon != serialised else { return } 1513 + tabManager.updateIcon(tabId, icon: serialised) 1625 1514 } 1626 1515 1627 1516 static func formatDuration(_ seconds: Int) -> String {
+1 -2
supacode/Features/Terminal/TabBar/Views/TerminalTabLabelView.swift
··· 17 17 .controlSize(.small) 18 18 .tint(isActive ? TerminalTabBarColors.activeText : TerminalTabBarColors.inactiveText) 19 19 } else if let icon = tab.icon { 20 - Image(systemName: icon) 21 - .imageScale(.small) 20 + TabIconImage(rawName: icon, pointSize: 12) 22 21 .foregroundStyle(isActive ? TerminalTabBarColors.activeText : TerminalTabBarColors.inactiveText) 23 22 } 24 23 }
+38
supacode/Features/Terminal/Views/TabIconImage.swift
··· 1 + import SwiftUI 2 + 3 + /// Renders the icon for a `TerminalTabItem`. Decodes the storage 4 + /// string via `ResolvedTabIcon` and dispatches to either 5 + /// `Image(systemName:)` (SF Symbol) or `Image(_:)` (asset catalog). 6 + /// Both branches honour the surrounding `foregroundStyle` because 7 + /// asset entries ship as template SVGs (`@asset:` marker — see 8 + /// `TabIconSource.storageString` and `Assets.xcassets/CommandIcons`). 9 + /// 10 + /// `pointSize` is the on-screen size both branches target: the SF 11 + /// Symbol path uses `.font(.system(size:))` so the symbol scales 12 + /// with the value; the asset path uses `.resizable() + frame` for 13 + /// the same final footprint. Keeping both branches at the same 14 + /// nominal size avoids visual jumps when a tab switches between an 15 + /// SF Symbol fallback and a branded asset. 16 + struct TabIconImage: View { 17 + let rawName: String 18 + let pointSize: CGFloat 19 + 20 + var body: some View { 21 + Group { 22 + switch ResolvedTabIcon.parse(rawName) { 23 + case .systemSymbol(let name): 24 + Image(systemName: name) 25 + .font(.system(size: pointSize)) 26 + case .asset(let name): 27 + Image(name) 28 + .resizable() 29 + .scaledToFit() 30 + .frame(width: pointSize, height: pointSize) 31 + } 32 + } 33 + // Tab icons are decorative — `tab.title` already provides the 34 + // accessible label for the tab. Callers that need a custom label 35 + // can override after construction. 36 + .accessibilityHidden(true) 37 + } 38 + }