A side pane, In this chat, that lists the to-do list, connectors, context files and skills this chat used

Mods for Claude Code.
| Mod | What it does |
|---|---|
| cache-bar | Status-line bar under your existing status line showing how long the prompt cache stays warm, with a handoff countdown: cache ▰▰▰▱▱▱▱▱ 23m 182k · handoff in 18m. Turns yellow at a quarter of the TTL, red at the handoff threshold, and follows the drop to a 5-minute TTL. /cache-bar:setup installs it. |
| filetree | Fork of data-goblin/claude-code-filetree that shows only the files Claude touched this session; the header's ◆ button toggles to the whole tree. |
| helper-desk | Task list above the prompt that follows Claude's to-do list, plus a side pane with one live card per subagent. |
| helpin-per | Pane listing open Helpin PER-* tasks; pick one to have Claude start working on it. |
| cache-clock | Countdown above the prompt until the chat's cache goes cold, with a Keep warm button. |
| handoff | When a chat gets very long, writes a handoff prompt and starts a fresh chat with it (/refresh <focus>; the handoff tells the new chat to run /pickup). |
| reflect | When you correct Claude, offers to save the fix as a lasting rule in CLAUDE.md or a rules folder. |
| chat-inventory | Side pane, In this chat, listing the to-do list, connectors and calls per connector, files and skills this chat used. |
| screen-share | /screen-share hides names, emails, phone numbers and money amounts on screen while you record. |
| replay-theater | /replay steps through the file edits Claude made in the last turn, one diff at a time. |
| mods | /mods opens a pane to turn each mod on or off, including mods installed from other marketplaces, and to install mods a marketplace offers that are not installed yet. |
| effort-optimizer | Before Claude starts on a prompt, a quick Sonnet check picks the effort level it needs (Low to Max) and offers a one-click switch, or sets it by itself with /effort-optimizer auto. |
| prompt-refiner | A Refine button in the hint line under the prompt, any time in the chat. Press it and pick a rewrite style for the prompt in the box, like a phone keyboard's suggestions: Clearer, Shorter, Elaborate (fuller, same shape), Structured (the job, the why, the guardrails, done means), Ask me first (up to 3 questions on gaps), or My guidance. The rewrite shows above the prompt with what changed; Use it fills the box, Refine runs another pass. /refine <prompt> does the same. |
The eight mods other than replay-theater, from helper-desk to effort-optimizer, come from Ben AI's benai-mods (benai.co) and are redistributed with permission, with Windows fixes added here. replay-theater (one Ben AI change: /mods switch support) is Anthropic's sample mod from anthropics/claude-code-playground, under the Apache 2.0 license in its LICENSE.
Reflect saves a rule either to ~/.claude/CLAUDE.md (Save everywhere) or as its own note in a folder you choose (Save to vault). Set that folder as rules_folder when you install reflect, or later for reflect in /config. If it is empty, reflect asks for the folder the first time you press Save to vault.
At the prompt of a terminal session:
/plugin install helper-desk --marketplace jz-wilson/claude-mods
Answer y to add the marketplace, then pick a scope.
From a shell:
claude plugin install helper-desk --marketplace jz-wilson/claude-mods
claude plugin install cache-bar --marketplace jz-wilson/claude-mods
In the desktop app, where /plugin does not run: click + next to the prompt box, then Plugins, Add marketplace with jz-wilson/claude-mods, then Add plugin.
cache-bar is a status-line script, so it takes over statusLine and runs the previous status line inside it. After installing, run /cache-bar:setup. It:
settings.json to settings.json.bak-cache-bar;statusLine.command (claude-hud's, for example) into inner in ~/.claude/plugins/cache-bar/config.json;statusLine.command at the newest installed cache-bar version, and sets refreshInterval: 60 so the countdown repaints while you are idle.The previous status line prints first, unchanged, and the bar goes on its own line underneath. If the inner command fails, the bar still prints. Before the first request of a session there is no cache yet, so the bar is hidden; after expiry it shows a dim cold.
The same config file sets the handoff threshold and the context floor:
{ "inner": "…", "handoffMinutes": 5, "floorTokens": 80000 }
The threshold is capped at a fifth of the TTL, so it fits the 5-minute TTL too. Under floorTokens of context the bar says no handoff (<floor).
To undo, copy settings.json.bak-cache-bar back over settings.json, or set statusLine.command back to the inner value.
Each mod is a folder with .claude-plugin/plugin.json. CI runs claude plugin validate on every mod for each push and pull request, then claude plugin test for mods with a hooks module and bun test for the rest. A merge to main that bumps a mod's version publishes a GitHub release tagged <mod>-v<version>.
claude plugin validate agent-tree
claude plugin test agent-tree
bun test cache-barhooks/register.tsx 926 lines1import { atom, read, update } from 'claude-code'
2import type { EngineInterface, Register, SessionMessage } from 'claude-code'
3
4import type { CallRow, ConnectorRow, FileRow, Inventory, Plan, PlanStep, SkillRow } from '../types'
5import { CONNECTOR_NAMES, connectorName as nameOf, splitTool } from './connectors'
6import { LOGOS } from './logos'
7
8const PLUGIN = 'chat-inventory'
9const NAME = 'chat-inventory'
10const PANE = 'chat-inventory'
11const TITLE = 'In this chat'
12const MAX_ROWS = 40
13const MAX_CALLS = 60
14// Context files show in a window this many rows tall; Up and Down move it.
15const FILE_WINDOW = 10
16const FILE_STEP = 5
17const SECTIONS = ['todo', 'connectors', 'files', 'skills'] as const
18const OFF_LINE = 'Turned off. Open /mods to turn it on.'
19const NO_PLAN = 'No to-do list yet. Claude makes one for jobs with 3 or more steps.'
20// The plan tool helper-desk registers, and Claude's built-in list tools, all feed the To-do section.
21const PLAN_TOOL = 'mcp__helper-desk__plan'
22const PLAN_TOOLS = new Set([PLAN_TOOL, 'TodoWrite', 'TaskCreate', 'TaskUpdate'])
23
24// Functional color follows the person's theme; the badge SVG paints its own tile, so it keeps a fixed hex.
25const ACCENT = 'claude'
26const INFO = 'suggestion'
27const GOOD = 'success'
28const BADGE = '#d97757'
29
30const EMPTY: Inventory = { connectors: [], files: [], skills: [] }
31const inv = atom({ plugin: 'chat-inventory', key: 'inv' } as const, EMPTY)
32const NO_STEPS: Plan = { title: '', steps: [], updatedAt: 0 }
33const planAtom = atom({ plugin: 'chat-inventory', key: 'plan' } as const, NO_STEPS)
34const openKey = atom({ plugin: 'chat-inventory', key: 'open' } as const, '')
35const offAtom = atom({ plugin: 'chat-inventory', key: 'off' } as const, false)
36// Sections the person closed, and the first context file row shown. Kept per chat in $.state.
37const foldedAtom = atom({ plugin: 'chat-inventory', key: 'folded' } as const, [] as string[])
38const fileTopAtom = atom({ plugin: 'chat-inventory', key: 'fileTop' } as const, 0)
39
40// Logo keys whose slug differs from the name.
41const ALIAS: Record<string, string> = { googleworkspace: 'google', metaads: 'meta' }
42
43// CLI tools in Bash that count as connectors. Matched as a command word.
44const CLI_RE = /(?:^|[;&|(\n`]|\bdo\b|\bthen\b|\$\()\s*(?:[A-Za-z_][A-Za-z0-9_]*=\S*\s+)*(gws|firecrawl|youtube-pp-cli|browser-harness|agent-browser)\b([^;&|\n`)]*)/g
45const GWS: Record<string, string> = {
46 gmail: 'Gmail',
47 calendar: 'Google Calendar',
48 drive: 'Google Drive',
49 sheets: 'Google Sheets',
50 docs: 'Google Docs',
51}
52const CLI_NAME: Record<string, string> = {
53 firecrawl: 'Firecrawl',
54 'youtube-pp-cli': 'YouTube',
55 'browser-harness': 'Browser',
56 'agent-browser': 'Browser',
57}
58
59// Input keys worth showing, best first.
60const ARG_KEYS = [
61 'query', 'q', 'search', 'searchQuery', 'keyword', 'keywords', 'url', 'file_path', 'path', 'filename', 'fileName',
62 'name', 'title', 'subject', 'transcriptId', 'threadId', 'messageId', 'documentId', 'spreadsheetId', 'fileId',
63 'pageId', 'eventId', 'calendarId', 'id', 'email', 'channel', 'prompt', 'skill', 'command',
64]
65const NOT_ARGS = new Set(['tool', 'tool_use_id', 'agentId', 'hook_event_name', 'session_id', 'transcript_path', 'cwd', 'permission_mode', 'surface'])
66
67// Module variables reset on a reload; the lists live in $.state.
68let home = ''
69let seq = 0
70let autoOpened = false
71let off = false
72// "chat-inventory:hidden": true in switches.json closes the pane and stops it opening by itself.
73let hidden = false
74let switchTimer: unknown
75const seen = new Set<string>()
76let skillNames = new Set<string>()
77
78const slug = (name: string) => {
79 const s = name.toLowerCase().replace(/[^a-z0-9]/g, '')
80 return ALIAS[s] ?? s
81}
82
83const clip = (s: string, n = 60) => {
84 const flat = s.replace(/\s+/g, ' ').trim()
85 return flat.length > n ? `${flat.slice(0, n - 1)}…` : flat
86}
87
88const base = (p: string) => (/^[~/.]/.test(p) && p.includes('/') ? p.slice(p.replace(/\/+$/, '').lastIndexOf('/') + 1) : p)
89
90/** The friendly connector name for an MCP tool, or '' when the tool is not a connector's. */
91function connectorName(tool: string): string {
92 if (!tool.startsWith('mcp__')) return ''
93 const { server, name } = splitTool(tool)
94 if (!server || server.startsWith('ccd_')) return ''
95 return nameOf(server, name)
96}
97
98/** "fireflies_get_transcripts" for Fireflies becomes "get transcripts". */
99function humanTool(tool: string, name: string): string {
100 const raw = tool.split('__').slice(2).join('__') || tool
101 const words = raw.split(/[-_\s]+/).filter(Boolean).map(w => w.toLowerCase())
102 const own = new Set([slug(name), ...name.toLowerCase().split(/\s+/)])
103 while (words.length > 1 && (own.has(words[0]!) || /^s\d+$/.test(words[0]!))) words.shift()
104 return words.join(' ')
105}
106
107/** The main argument of a call, short. */
108function summaryOf(input: Record<string, unknown>): string {
109 for (const k of ARG_KEYS) {
110 const v = input[k]
111 if (typeof v === 'string' && v.trim()) return clip(base(v))
112 if (typeof v === 'number') return String(v)
113 }
114 for (const [k, v] of Object.entries(input)) {
115 if (NOT_ARGS.has(k)) continue
116 if (typeof v === 'string' && v.trim()) return clip(base(v))
117 }
118 for (const [k, v] of Object.entries(input)) {
119 if (NOT_ARGS.has(k)) continue
120 if (typeof v === 'number' || typeof v === 'boolean') return clip(`${k} ${v}`)
121 }
122 return ''
123}
124
125/** The main argument of a CLI line: a query or id in --params, else the rest of the line. */
126function cliSummary(rest: string): string {
127 const m = /\\?"(q|query|id|fileId|spreadsheetId|documentId|calendarId|url)\\?"\s*:\s*\\?"([^"\\]+)/.exec(rest)
128 if (m) return clip(m[2]!)
129 const url = /https?:\/\/\S+/.exec(rest)
130 if (url) return clip(url[0])
131 return clip(rest.replace(/<<-?\s*'?\w+'?/, '').replace(/^\s*(?:[a-z][a-zA-Z-]*\s*)+/, ''))
132}
133
134type CallHit = { kind: 'connector'; name: string; call: Omit<CallRow, 'at'> }
135type Hit = CallHit | { kind: 'file' | 'skill'; name: string; always?: boolean }
136
137/** Connector calls inside one Bash command line. */
138function cliHits(command: string): CallHit[] {
139 const out: CallHit[] = []
140 const done = new Set<string>()
141 for (const m of command.matchAll(CLI_RE)) {
142 const cmd = m[1]!
143 const rest = m[2] ?? ''
144 let name = CLI_NAME[cmd] ?? ''
145 let tool = ''
146 if (cmd === 'gws') {
147 const svc = /^\s*([a-z]+)/.exec(rest)?.[1] ?? ''
148 name = GWS[svc] ?? 'Google Workspace'
149 const words = rest
150 .trim()
151 .split(/\s+/)
152 .filter(w => /^[a-z][a-zA-Z]*$/.test(w))
153 tool = (GWS[svc] ? words.slice(1) : words).slice(0, 3).join(' ') || svc || 'run'
154 } else if (cmd === 'firecrawl' || cmd === 'youtube-pp-cli') {
155 tool = /^\s*([a-z][a-z-]*)/.exec(rest)?.[1]?.replace(/-/g, ' ') ?? 'run'
156 } else {
157 tool = 'run script'
158 }
159 const summary = cmd === 'browser-harness' || cmd === 'agent-browser' ? '' : cliSummary(rest)
160 const id = `${name}|${tool}|${summary}`
161 if (done.has(id)) continue
162 done.add(id)
163 out.push({ kind: 'connector', name, call: { tool, summary, cli: true } })
164 }
165 return out
166}
167
168/** What one tool call adds to the lists. */
169function hitsOf(tool: string, input: Record<string, unknown>): Hit[] {
170 // The plan tool is the To-do section, not a connector.
171 if (tool === PLAN_TOOL) return []
172 const connector = connectorName(tool)
173 if (connector) return [{ kind: 'connector', name: connector, call: { tool: humanTool(tool, connector), summary: summaryOf(input), cli: false } }]
174 if (tool === 'Bash' && typeof input.command === 'string') return cliHits(input.command)
175 if (tool === 'Read' && typeof input.file_path === 'string') {
176 const fp = input.file_path
177 // A skill file read on purpose is a skill, named for its folder.
178 const skill = /\/([^/]+)\/SKILL\.md$/.exec(fp)
179 if (skill) return [{ kind: 'skill', name: skill[1]! }]
180 // Claude's own spill files (big tool results, temp copies) are not context the person gave it.
181 if (/\/tool-results\/|^\/private\/tmp\/|^\/tmp\/|\/\.claude\/projects\/[^/]+\/[0-9a-f-]{36}\//.test(fp)) return []
182 return [{ kind: 'file', name: fp }]
183 }
184 if (tool === 'Skill' && typeof input.skill === 'string' && input.skill) return [{ kind: 'skill', name: input.skill.replace(/^\//, '') }]
185 return []
186}
187
188const tilde = (p: string) => (home && p.startsWith(home) ? `~${p.slice(home.length)}` : p)
189const plural = (n: number, word: string) => `${n} ${word}${n === 1 ? '' : 's'}`
190const pad = (n: number) => String(n).padStart(2, '0')
191const clockTime = (ms: number) => {
192 if (!ms) return ''
193 const d = new Date(ms)
194 return `${pad(d.getHours())}:${pad(d.getMinutes())}`
195}
196
197// $.fs has no delete, and Windows has no rm outside Git Bash: del through cmd there.
198async function removeFile($: EngineInterface, path: string) {
199 const windows = (await $.env.get('OS')) === 'Windows_NT'
200 await $.process.run(windows ? ['cmd', '/c', 'del', '/f', '/q', path.replace(/\//g, '\\')] : ['rm', '-f', path])
201}
202
203async function logError($: EngineInterface, where: string, err: unknown) {
204 try {
205 const path = `${home}/.claude/mods-logs/${PLUGIN}.log`
206 let old = ''
207 try {
208 old = String(await $.fs.read(path))
209 } catch {
210 // No log yet: $.fs.write below makes it and its folder.
211 }
212 const line = `${new Date(await $.clock.now()).toISOString()} ${where}: ${String(err instanceof Error ? err.message : err)}\n`
213 await $.fs.write(path, old + line)
214 } catch {
215 // Nowhere left to report it.
216 }
217}
218
219function bumpConnector(rows: ConnectorRow[], hit: CallHit, at: number, time: number): ConnectorRow[] {
220 const key = slug(hit.name)
221 const old = rows.find(r => r.key === key)
222 const rest = rows.filter(r => r.key !== key)
223 const calls = [...(old?.calls ?? []), { ...hit.call, at: time }].slice(-MAX_CALLS)
224 return [
225 ...rest,
226 {
227 key,
228 name: hit.name,
229 count: (old?.count ?? 0) + 1,
230 seq: at,
231 cli: (old?.cli ?? false) || hit.call.cli,
232 mcp: (old?.mcp ?? false) || !hit.call.cli,
233 calls,
234 },
235 ]
236}
237
238function bumpSkill(rows: SkillRow[], name: string, at: number, always: boolean): SkillRow[] {
239 const old = rows.find(r => r.name === name)
240 const rest = rows.filter(r => r.name !== name)
241 if (always) return [...rest, { name, count: old?.count ?? 0, seq: old?.seq ?? at, always: true }]
242 return [...rest, { name, count: (old?.count ?? 0) + 1, seq: at, always: old?.always ?? false }]
243}
244
245type Stamped = { hit: Hit; at: number; time: number }
246
247function apply(list: Inventory, hits: Stamped[]): Inventory {
248 let { connectors, files, skills } = list
249 for (const { hit, at, time } of hits) {
250 if (hit.kind === 'connector') connectors = bumpConnector(connectors, hit as CallHit, at, time)
251 else if (hit.kind === 'skill') skills = bumpSkill(skills, hit.name, at, hit.always === true)
252 else files = [...files.filter(f => f.path !== hit.name), { path: hit.name, auto: false, seq: at }]
253 }
254 return { connectors, files, skills }
255}
256
257const STATUSES = new Set(['pending', 'in_progress', 'completed'])
258const statusOf = (v: unknown): PlanStep['status'] => (typeof v === 'string' && STATUSES.has(v) ? (v as PlanStep['status']) : 'pending')
259const str = (v: unknown) => (typeof v === 'string' ? v.trim() : '')
260
261/** Steps from a list of objects, reading the text from the first key that has it. */
262function stepsOf(raw: unknown, textKeys: string[]): PlanStep[] {
263 if (!Array.isArray(raw)) return []
264 const out: PlanStep[] = []
265 for (const item of raw) {
266 if (!item || typeof item !== 'object') continue
267 const o = item as Record<string, unknown>
268 const text = textKeys.map(k => str(o[k])).find(Boolean) ?? ''
269 if (!text) continue
270 const active = str(o.activeForm)
271 out.push({ text, status: statusOf(o.status), ...(active ? { active } : {}) })
272 }
273 return out
274}
275
276/** The plan after one main-chat call to a plan tool, or null when the call changes nothing. */
277function planAfter(cur: Plan, tool: string, input: Record<string, unknown>, result: unknown, time: number): Plan | null {
278 if (tool === 'TodoWrite') return { title: cur.title, steps: stepsOf(input.todos, ['content']), updatedAt: time }
279 if (tool === PLAN_TOOL) {
280 const title = typeof input.title === 'string' ? input.title.trim() : cur.title
281 return { title, steps: stepsOf(input.steps, ['text']), updatedAt: time }
282 }
283 if (tool === 'TaskCreate') {
284 const text = str(input.subject)
285 if (!text) return null
286 const made = (result as { task?: { id?: unknown } } | undefined)?.task?.id
287 const id = typeof made === 'string' || typeof made === 'number' ? String(made) : String(cur.steps.length + 1)
288 const active = str(input.activeForm)
289 return { ...cur, steps: [...cur.steps, { text, status: 'pending', id, ...(active ? { active } : {}) }], updatedAt: time }
290 }
291 if (tool === 'TaskUpdate') {
292 const id = str(input.taskId) || (typeof input.taskId === 'number' ? String(input.taskId) : '')
293 let at = cur.steps.findIndex(st => st.id === id)
294 if (at < 0 && /^\d+$/.test(id) && !cur.steps.some(st => st.id)) at = Number(id) - 1
295 const old = cur.steps[at]
296 if (!old) return null
297 if (input.status === 'deleted') return { ...cur, steps: cur.steps.filter((_, i) => i !== at), updatedAt: time }
298 const text = str(input.subject) || old.text
299 const active = str(input.activeForm) || old.active
300 const status = input.status === undefined ? old.status : statusOf(input.status)
301 const steps = cur.steps.map((st, i) => (i === at ? { ...st, text, status, ...(active ? { active } : {}) } : st))
302 return { ...cur, steps, updatedAt: time }
303 }
304 return null
305}
306
307/** Watches a plan tool call in the main chat, so the list works with helper-desk off. */
308async function watchPlan($: EngineInterface, call: Record<string, unknown> & { tool: string }, result: unknown, time: number) {
309 if (!PLAN_TOOLS.has(call.tool) || call.agentId) return false
310 let changed = false
311 await update($, planAtom, cur => {
312 const nextPlan = planAfter(cur, call.tool, call, result, Math.max(time, cur.updatedAt + 1))
313 if (!nextPlan) return cur
314 changed = true
315 return nextPlan
316 })
317 return changed
318}
319
320const planPath = (sid: string) => `${home}/.claude/mods-state/plan-${sid}.json`
321
322/** Reads the shared plan file for this chat; it wins when it is newer than what the pane has. Never throws. */
323async function readPlan($: EngineInterface) {
324 try {
325 const path = planPath(await $.session.id())
326 if (!(await $.fs.exists(path))) return
327 const json = JSON.parse(String(await $.fs.read(path))) as Record<string, unknown>
328 const at = typeof json.updatedAt === 'string' ? Date.parse(json.updatedAt) : typeof json.updatedAt === 'number' ? json.updatedAt : NaN
329 if (!Number.isFinite(at)) return
330 const cur = await read($, planAtom)
331 if (at <= cur.updatedAt) return
332 // Keep TodoWrite's present-tense text and TaskCreate's ids for steps the file also has.
333 const steps = stepsOf(json.steps, ['text']).map(st => {
334 const was = cur.steps.find(o => o.text === st.text)
335 return { ...st, ...(was?.active && !st.active ? { active: was.active } : {}), ...(was?.id ? { id: was.id } : {}) }
336 })
337 const title = typeof json.title === 'string' ? json.title.trim() : ''
338 await update($, planAtom, () => ({ title, steps, updatedAt: at }))
339 } catch (err) {
340 await logError($, 'plan', err)
341 }
342}
343
344/** Splits text into lines no wider than `width` columns, breaking at spaces. */
345function wrapLines(text: string, width: number): string[] {
346 const w = Math.max(8, width)
347 const lines: string[] = []
348 let cur = ''
349 for (const word of text.replace(/\s+/g, ' ').trim().split(' ')) {
350 let rest = word
351 while (rest.length > w) {
352 if (cur) lines.push(cur)
353 cur = ''
354 lines.push(rest.slice(0, w))
355 rest = rest.slice(w)
356 }
357 if (!rest) continue
358 if (!cur) cur = rest
359 else if (cur.length + 1 + rest.length <= w) cur += ` ${rest}`
360 else {
361 lines.push(cur)
362 cur = rest
363 }
364 }
365 if (cur || !lines.length) lines.push(cur)
366 return lines
367}
368
369async function openPane($: EngineInterface) {
370 await $.ui.open({ id: PANE, title: TITLE })
371}
372
373async function record($: EngineInterface, id: string, hits: Hit[]) {
374 if (!hits.length) return
375 if (id) {
376 if (seen.has(id)) return
377 seen.add(id)
378 }
379 const time = await $.clock.now()
380 const stamped = hits.map(hit => {
381 seq += 1
382 return { hit, at: seq, time }
383 })
384 await update($, inv, list => apply(list, stamped))
385 autoOpen($)
386}
387
388/** Opens the pane the first time the chat uses something, unless it is hidden. */
389function autoOpen($: EngineInterface) {
390 if (autoOpened || hidden) return
391 autoOpened = true
392 void openPane($).catch(err => logError($, 'open', err))
393}
394
395async function loadSkillNames($: EngineInterface) {
396 const names = new Set<string>()
397 try {
398 const usage = await $.session.usage({ breakdown: 'summary' })
399 for (const s of usage.context.breakdown?.skills?.skillFrontmatter ?? []) names.add(s.name)
400 } catch {
401 // No breakdown: fall back to the command list below.
402 }
403 if (names.size) skillNames = names
404 return names
405}
406
407/** True when a typed slash command is a skill. */
408async function isSkill($: EngineInterface, name: string) {
409 if (!skillNames.size) await loadSkillNames($)
410 if (skillNames.has(name)) return true
411 if (skillNames.size) return false
412 const cmds = await $.command.list()
413 return cmds.some(c => c.name === name && c.source === 'user')
414}
415
416const skillOfPath = (p: string) => /\/([^/]+)\/SKILL\.md$/.exec(p)?.[1] ?? ''
417
418/** Memory files the chat loaded at start. A SKILL.md among them is a skill, always loaded. */
419async function loadMemoryFiles($: EngineInterface) {
420 const usage = await $.session.usage({ breakdown: 'summary' })
421 const b = usage.context.breakdown
422 if (!b) return
423 for (const s of b.skills?.skillFrontmatter ?? []) skillNames.add(s.name)
424 const all = b.memoryFiles.map(m => m.path).filter(Boolean)
425 const skills = all.map(skillOfPath).filter(Boolean)
426 const paths = all.filter(p => !skillOfPath(p))
427 if (!paths.length && !skills.length) return
428 await update($, inv, list => {
429 const have = new Set(list.files.map(f => f.path))
430 const added: FileRow[] = paths.filter(p => !have.has(p)).map((p, i) => ({ path: p, auto: true, seq: -1000 + i }))
431 const files = list.files.filter(f => !skillOfPath(f.path)).map(f => (paths.includes(f.path) ? { ...f, auto: true } : f))
432 let rows = list.skills
433 skills.forEach((name, i) => {
434 rows = bumpSkill(rows, name, -2000 + i, true)
435 })
436 return { ...list, files: [...files, ...added], skills: rows }
437 })
438}
439
440/** tool_use id to the time it was written, from this chat's transcript file. */
441async function callTimes($: EngineInterface): Promise<Map<string, number>> {
442 const times = new Map<string, number>()
443 try {
444 const sid = await $.session.id()
445 const cwd = await $.session.cwd()
446 const path = `${home}/.claude/projects/${cwd.replace(/[^a-zA-Z0-9]/g, '-')}/${sid}.jsonl`
447 if (!(await $.fs.exists(path))) return times
448 const text = String(await $.fs.read(path))
449 for (const line of text.split('\n')) {
450 if (!line.includes('"tool_use"')) continue
451 const ts = /"timestamp":"([^"]+)"/.exec(line)?.[1]
452 const ms = ts ? Date.parse(ts) : NaN
453 if (!Number.isFinite(ms)) continue
454 for (const m of line.matchAll(/"type":"tool_use","id":"([^"]+)"/g)) times.set(m[1]!, ms)
455 }
456 } catch {
457 // Times stay blank for older calls.
458 }
459 return times
460}
461
462const SLASH_RE = /<command-name>\/?([\w:.-]+)<\/command-name>|^\/([\w:.-]+)/
463
464async function seed($: EngineInterface) {
465 const main = await $.session.messages()
466 const all: SessionMessage[] = [...main]
467 for (const m of main) {
468 for (const u of m.toolUses) {
469 if (!u.agentId) continue
470 const child = await $.session.messages({ agentId: u.agentId })
471 if (Array.isArray(child)) all.push(...child)
472 }
473 }
474 // Plan calls already in the chat, oldest first, stamped old so a newer plan file still wins.
475 let plan = await read($, planAtom)
476 let planChanged = false
477 for (const m of main) {
478 for (const u of m.toolUses) {
479 if (u.agentId || !PLAN_TOOLS.has(u.tool)) continue
480 const nextPlan = planAfter(plan, u.tool, u.input, undefined, plan.updatedAt + 1)
481 if (nextPlan) {
482 plan = nextPlan
483 planChanged = true
484 }
485 }
486 }
487 if (planChanged) await update($, planAtom, cur => (cur.updatedAt >= plan.updatedAt ? cur : plan))
488 const times = all.some(m => m.toolUses.length) ? await callTimes($) : new Map<string, number>()
489 const hits: Stamped[] = []
490 for (const m of all) {
491 if (m.role === 'user' && typeof m.text === 'string') {
492 const found = SLASH_RE.exec(m.text.trim())
493 const name = found?.[1] ?? found?.[2]
494 if (name && (await isSkill($, name))) {
495 seq += 1
496 hits.push({ hit: { kind: 'skill', name }, at: seq, time: 0 })
497 }
498 }
499 for (const u of m.toolUses) {
500 if (seen.has(u.tool_use_id)) continue
501 const found = hitsOf(u.tool, u.input)
502 if (!found.length) continue
503 seen.add(u.tool_use_id)
504 for (const hit of found) {
505 seq += 1
506 hits.push({ hit, at: seq, time: times.get(u.tool_use_id) ?? 0 })
507 }
508 }
509 }
510 // A reload of a chat that already used things does not pop the pane open again.
511 if (hits.length) autoOpened = true
512 if (hits.length) await update($, inv, list => apply(list, hits))
513}
514
515const HIDE_KEY = `${NAME}:hidden`
516const switchesPath = () => `${home}/.claude/mods/switches.json`
517
518async function readSwitches($: EngineInterface): Promise<Record<string, unknown>> {
519 if (!(await $.fs.exists(switchesPath()))) return {}
520 const json = JSON.parse(String(await $.fs.read(switchesPath()))) as unknown
521 return json && typeof json === 'object' && !Array.isArray(json) ? (json as Record<string, unknown>) : {}
522}
523
524/** Reads the shared switch file and the open request for this chat. Never throws. */
525async function readSwitch($: EngineInterface) {
526 try {
527 let next = false
528 let nowHidden = false
529 try {
530 const json = await readSwitches($)
531 next = json[NAME] === false
532 nowHidden = json[HIDE_KEY] === true
533 } catch {
534 next = false
535 nowHidden = hidden
536 }
537 // Off or hidden, the pane goes; /mods Open or /inventory brings it back once on and shown.
538 if ((nowHidden && !hidden) || (next && !off)) await $.ui.close({ id: PANE }).catch(() => undefined)
539 hidden = nowHidden
540 if (next !== off) {
541 off = next
542 await update($, offAtom, () => next)
543 $.ui.invalidate('ui.render')
544 }
545 const sid = await $.session.id()
546 const req = `${home}/.claude/mods/.open-${NAME}-${sid}`
547 if (await $.fs.exists(req)) {
548 await removeFile($, req)
549 if (!off) await openPane($)
550 }
551 } catch (err) {
552 await logError($, 'switch', err)
553 }
554}
555
556// Read, change, write the whole file, so every chat sees the choice within 3 s.
557async function setHidden($: EngineInterface, value: boolean) {
558 try {
559 const json = await readSwitches($)
560 if (value) json[HIDE_KEY] = true
561 else delete json[HIDE_KEY]
562 await $.fs.write(switchesPath(), `${JSON.stringify(json, null, 2)}\n`)
563 } catch (err) {
564 await logError($, 'save hidden', err)
565 }
566 hidden = value
567 if (value) await $.ui.close({ id: PANE }).catch(() => undefined)
568}
569
570const newest = <T extends { seq: number }>(rows: T[]) => [...rows].sort((a, b) => b.seq - a.seq)
571
572/** A logo tile with its call count in a corner badge. */
573function badgeSvg(key: string, name: string, count: number): string {
574 const logo = LOGOS[key]
575 const tile =
576 logo?.svg ??
577 `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32" height="32"><rect width="32" height="32" rx="8" fill="${BADGE}"/><text x="16" y="21.5" text-anchor="middle" font-family="-apple-system, Helvetica, Arial, sans-serif" font-size="16" font-weight="700" fill="#ffffff">${(name[0] ?? '?').toUpperCase()}</text></svg>`
578 const inner = tile.replace('<svg ', '<svg x="1" y="7" ')
579 const label = count > 99 ? '99+' : String(count)
580 const w = label.length > 1 ? 9 + label.length * 4 : 15
581 return (
582 '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 44 40" width="44" height="40">' +
583 inner +
584 `<rect x="${42 - w}" y="1" width="${w}" height="15" rx="7.5" fill="${BADGE}" stroke="#ffffff" stroke-width="1.5"/>` +
585 `<text x="${42 - w / 2}" y="12" text-anchor="middle" font-family="-apple-system, Helvetica, Arial, sans-serif" font-size="10" font-weight="700" fill="#ffffff">${label}</text>` +
586 '</svg>'
587 )
588}
589
590async function togglePress($: EngineInterface, element: string) {
591 if (!element.startsWith('c:')) return
592 const key = element.slice(2)
593 await update($, openKey, cur => (cur === key ? '' : key))
594}
595
596async function toggleSection($: EngineInterface, id: string) {
597 await update($, foldedAtom, cur => (cur.includes(id) ? cur.filter(x => x !== id) : [...cur, id]))
598}
599
600async function moveFiles($: EngineInterface, by: number) {
601 const total = (await read($, inv)).files.length
602 const last = Math.max(0, total - FILE_WINDOW)
603 await update($, fileTopAtom, cur => Math.min(last, Math.max(0, Math.min(cur, last) + by)))
604}
605
606// Every key a connector can carry, so each press has its own handler.
607const KNOWN_KEYS = [...new Set([...Object.keys(LOGOS), ...[...CONNECTOR_NAMES, ...Object.values(GWS), ...Object.values(CLI_NAME), 'Google Workspace'].map(slug)])]
608
609export const register: Register = on => {
610 on('session.start', async ($, e, next) => {
611 home = $.plugin.root.replace(/\\/g, '/').split('/.claude/')[0] ?? ''
612 await $.command.register({ name: 'inventory', description: 'Show the connectors, files and skills this chat used', immediate: true })
613 await readSwitch($)
614 if (!switchTimer)
615 switchTimer = $.clock.every(3000, () => {
616 void readSwitch($)
617 if (!off) void readPlan($)
618 })
619 void seed($)
620 .then(() => readPlan($))
621 .catch(err => logError($, 'seed', err))
622 void loadMemoryFiles($).catch(err => logError($, 'memory', err))
623 return next(e)
624 })
625
626 on('command.run', { command: 'inventory' }, async ($, e) => {
627 if (off) return { text: 'Chat Inventory is off. Turn it on with /mods.' }
628 // The pane's buttons as subcommands: /inventory hide, up, down.
629 const sub = e.args.trim().toLowerCase()
630 if (sub === 'hide') {
631 await setHidden($, true)
632 return { text: 'Chat Inventory hidden. Type /inventory or open /mods to show it.' }
633 }
634 if (sub === 'up' || sub === 'down') {
635 await moveFiles($, sub === 'up' ? -FILE_STEP : FILE_STEP)
636 return { text: `Moved the context files ${sub}.` }
637 }
638 if (hidden) await setHidden($, false)
639 await openPane($)
640 void loadMemoryFiles($).catch(err => logError($, 'memory', err))
641 return { text: 'Opened the In this chat pane.' }
642 })
643
644 // A skill the person typed as a slash command.
645 on('command.run', async ($, e, next) => {
646 const ran = await next(e)
647 if (off) return ran
648 try {
649 if (e.command !== 'inventory' && (await isSkill($, e.command))) await record($, '', [{ kind: 'skill', name: e.command }])
650 } catch (err) {
651 await logError($, 'command', err)
652 }
653 return ran
654 }).catch(($, e, next) => next(e))
655
656 // Every tool call, in the main chat and in helpers: the call runs first, then it is counted.
657 on('tool.call', async ($, e, next) => {
658 if (off) return next(e)
659 const ran = await next(e)
660 try {
661 if ((ran as { deny?: unknown }).deny === undefined) {
662 const call = e as unknown as Record<string, unknown> & { tool: string; tool_use_id: string }
663 await record($, call.tool_use_id, hitsOf(call.tool, call))
664 if (await watchPlan($, call, (ran as { result?: unknown }).result, await $.clock.now())) autoOpen($)
665 }
666 } catch (err) {
667 await logError($, 'tool.call', err)
668 }
669 return ran
670 }).catch(($, e, next) => next(e))
671
672 // A press on a connector logo opens its call list; a second press closes it.
673 for (const key of KNOWN_KEYS) {
674 on('ui.press', { plugin: 'chat-inventory', element: `c:${key}` }, async ($, e) => {
675 await togglePress($, e.element)
676 return { element: e.element }
677 })
678 }
679 // The arrow on each section header opens or closes it.
680 for (const id of SECTIONS) {
681 on('ui.press', { plugin: 'chat-inventory', element: `sec-${id}` }, async ($, e) => {
682 await toggleSection($, id)
683 return { element: e.element }
684 })
685 }
686 on('ui.press', { plugin: 'chat-inventory', element: 'files-up' }, async ($, e) => {
687 await moveFiles($, -FILE_STEP)
688 return { element: e.element }
689 })
690 on('ui.press', { plugin: 'chat-inventory', element: 'files-down' }, async ($, e) => {
691 await moveFiles($, FILE_STEP)
692 return { element: e.element }
693 })
694
695 on('ui.press', { plugin: 'chat-inventory', element: 'hide' }, async ($, e) => {
696 await setHidden($, true)
697 try {
698 $.ui.toast('Chat Inventory hidden. Type /inventory or open /mods to show it.')
699 } catch {
700 // The toast is only a hint.
701 }
702 return { element: e.element }
703 })
704
705 // Connectors with no known key (an unmapped server).
706 on('ui.press', { plugin: 'chat-inventory' }, async ($, e, next) => {
707 const key = e.element.slice(2)
708 if (!e.element.startsWith('c:') || KNOWN_KEYS.includes(key)) return next(e)
709 await togglePress($, e.element)
710 return { element: e.element }
711 })
712
713 on('ui.render', { component: 'Pane', requestId: PANE }, async ($, e) => {
714 const els = $.ui.resolve(e)
715 const { Box, Text, Button } = els
716 const width = Math.max(20, e.props.bodyColumns)
717 const inner = width - 4
718 if (await read($, offAtom)) return <Text dimColor wrap="truncate-end">{OFF_LINE}</Text>
719 const list = await read($, inv)
720 const open = await read($, openKey)
721 const folded = await read($, foldedAtom)
722 const Svg = e.surface !== 'terminal' && 'Svg' in els ? els.Svg : undefined
723
724 // The header is the toggle: an arrow, the title, and the count on the right.
725 const header = (key: string, title: string, right: string, isOpen: boolean) => (
726 <Box key="h" flexDirection="row" justifyContent="space-between" width={inner}>
727 <Button key={`sec-${key}`} plain onPress={() => undefined}>
728 <Text color={ACCENT}>{isOpen ? '▾ ' : '▸ '}</Text>
729 <Text weight="bold">{title}</Text>
730 </Button>
731 {right ? <Text dimColor wrap="truncate-end">{right}</Text> : null}
732 </Box>
733 )
734 const none = <Text dimColor wrap="truncate-end">None used yet</Text>
735 const section = (key: string, title: string, right: string, body: unknown) => {
736 const isOpen = !folded.includes(key)
737 return (
738 <Box key={key} flexDirection="column" borderStyle="round" paddingX={1} width={width} flexShrink={0}>
739 {header(key, title, right, isOpen)}
740 {isOpen ? (body as never) : null}
741 </Box>
742 )
743 }
744 const row = (key: string, left: unknown, right: unknown) => (
745 <Box key={key} flexDirection="row" justifyContent="space-between" width={inner} height={1} gap={1}>
746 <Box flexShrink={1} flexGrow={1} height={1} overflow="hidden">
747 {left as never}
748 </Box>
749 {right ? <Box flexShrink={0}>{right as never}</Box> : null}
750 </Box>
751 )
752 const capped = <T,>(rows: T[], draw: (r: T) => unknown) => {
753 const shown = rows.slice(0, MAX_ROWS)
754 const more = rows.length - shown.length
755 return [...shown.map(draw), more > 0 ? <Text key="more" dimColor wrap="truncate-end">{`+${more} more`}</Text> : null] as never
756 }
757
758 // Connectors: a grid of logos, then the open one's calls.
759 const conns = newest(list.connectors)
760 const callList = (c: ConnectorRow) => {
761 const calls = [...c.calls].reverse()
762 return (
763 <Box key={`calls:${c.key}`} flexDirection="column" width={inner} marginTop={1}>
764 <Text dimColor wrap="truncate-end">{`${c.name} calls, newest first`}</Text>
765 {capped(calls, call => {
766 const i = calls.indexOf(call)
767 return row(
768 `call:${c.key}:${i}`,
769 <Text wrap="truncate-end">
770 {call.tool}
771 {call.summary ? <Text dimColor>{` ${call.summary}`}</Text> : null}
772 </Text>,
773 <Text dimColor wrap="truncate-end">{`${call.cli ? 'CLI ' : ''}${clockTime(call.at)}`.trim() || ' '}</Text>,
774 )
775 })}
776 </Box>
777 )
778 }
779 let connectorBody: unknown = none
780 if (conns.length && Svg) {
781 const tileCols = 12
782 const perRow = Math.max(1, Math.floor(inner / tileCols))
783 const rows: ConnectorRow[][] = []
784 for (let i = 0; i < conns.length; i += perRow) rows.push(conns.slice(i, i + perRow))
785 connectorBody = rows.map((r, ri) => (
786 <Box key={`row${ri}`} flexDirection="column" width={inner}>
787 <Box flexDirection="row" width={inner}>
788 {r.map(c => (
789 <Box key={`t:${c.key}`} flexDirection="column" alignItems="center" width={tileCols} flexShrink={0}>
790 <Svg source={badgeSvg(c.key, c.name, c.count)} alt={`${c.name}, ${plural(c.count, 'call')}`} width={44} height={40} />
791 <Button key={`c:${c.key}`} plain dimColor={open !== c.key} onPress={() => undefined}>
792 {c.name}
793 </Button>
794 <Text dimColor wrap="truncate-end">{c.cli && !c.mcp ? 'via CLI' : c.cli ? 'MCP + CLI' : ' '}</Text>
795 </Box>
796 ))}
797 </Box>
798 {r.some(c => c.key === open) ? callList(r.find(c => c.key === open)!) : null}
799 </Box>
800 ))
801 } else if (conns.length) {
802 // Terminal: one row per connector, the name pressable.
803 connectorBody = conns.map(c => (
804 <Box key={`r:${c.key}`} flexDirection="column" width={inner}>
805 {row(
806 `l:${c.key}`,
807 <Button key={`c:${c.key}`} plain onPress={() => undefined}>
808 {`${open === c.key ? '▾' : '▸'} ${c.name}`}
809 {c.cli && !c.mcp ? <Text dimColor> via CLI</Text> : c.cli ? <Text dimColor> MCP + CLI</Text> : null}
810 </Button>,
811 <Text color={ACCENT} wrap="truncate-end">{plural(c.count, 'call')}</Text>,
812 )}
813 {open === c.key ? callList(c) : null}
814 </Box>
815 ))
816 }
817
818 const files = newest(list.files)
819 const fileRow = (f: FileRow) => {
820 const cut = f.path.lastIndexOf('/')
821 const name = f.path.slice(cut + 1)
822 const full = tilde(cut > 0 ? f.path.slice(0, cut) : '/')
823 // One line per file: long folders wrapped and drew over the row above on desktop.
824 const parts = full.split('/').filter(Boolean)
825 const folder = full.length > 28 && parts.length > 1 ? `…/${parts[parts.length - 1]}` : full
826 return row(
827 `f:${f.path}`,
828 <Text wrap="truncate-end">
829 {name}
830 <Text dimColor>{` ${folder}`}</Text>
831 </Text>,
832 f.auto ? <Text color={INFO} wrap="truncate-end">auto</Text> : null,
833 )
834 }
835 // A fixed window of rows: a Box cannot scroll inside a pane, so Up and Down move it.
836 const top = Math.min(await read($, fileTopAtom), Math.max(0, files.length - FILE_WINDOW))
837 const windowed = files.slice(top, top + FILE_WINDOW)
838 const atTop = top === 0
839 const atEnd = top + FILE_WINDOW >= files.length
840 const readCount = files.filter(f => !f.auto).length
841 const readLine = row('fread', <Text dimColor wrap="truncate-end">Files read</Text>, <Text dimColor wrap="truncate-end">{String(readCount)}</Text>)
842 const fileBody = !files.length
843 ? none
844 : files.length <= FILE_WINDOW
845 ? [readLine, ...files.map(fileRow)]
846 : [
847 readLine,
848 <Box key="fwin" flexDirection="column" width={inner} height={FILE_WINDOW} overflow="hidden" flexShrink={0}>
849 {windowed.map(fileRow)}
850 </Box>,
851 <Box key="fnav" flexDirection="row" justifyContent="space-between" width={inner} gap={1}>
852 <Text dimColor wrap="truncate-end">{`${top + 1} to ${top + windowed.length} of ${files.length}`}</Text>
853 <Box flexDirection="row" gap={1} flexShrink={0}>
854 {atTop ? <Text dimColor>▴ Up</Text> : <Button key="files-up" plain onPress={() => undefined}>▴ Up</Button>}
855 {atEnd ? <Text dimColor>▾ Down</Text> : <Button key="files-down" plain onPress={() => undefined}>▾ Down</Button>}
856 </Box>
857 </Box>,
858 ]
859
860 const skills = newest(list.skills)
861 const skillBody = skills.length
862 ? capped(skills, s =>
863 row(
864 `s:${s.name}`,
865 <Text wrap="truncate-end">
866 <Text color={ACCENT}>/</Text>
867 {s.name}
868 </Text>,
869 <Text>
870 {s.always ? <Text color={INFO}>always loaded</Text> : null}
871 {s.always && s.count ? <Text dimColor>{' '}</Text> : null}
872 {s.count ? <Text dimColor>{plural(s.count, 'use')}</Text> : null}
873 </Text>,
874 ),
875 )
876 : none
877
878 // To-do: one row per step, the mark in a fixed column and the text wrapped beside it.
879 const plan = await read($, planAtom)
880 const textCols = inner - 2
881 const todoRow = (st: PlanStep, i: number) => {
882 const done = st.status === 'completed'
883 const now = st.status === 'in_progress'
884 const lines = wrapLines(now && st.active ? st.active : st.text, textCols)
885 return (
886 <Box key={`todo:${i}`} flexDirection="row" width={inner} flexShrink={0}>
887 <Box width={2} flexShrink={0}>
888 {done ? <Text color={GOOD}>✓</Text> : now ? <Text color={ACCENT}>●</Text> : <Text dimColor>○</Text>}
889 </Box>
890 <Box flexDirection="column" width={textCols} flexShrink={0}>
891 {lines.map((line, j) => (
892 <Text key={`l${j}`} wrap="truncate-end" dimColor={done} strikethrough={done} weight={now ? 'bold' : undefined}>
893 {line}
894 </Text>
895 ))}
896 </Box>
897 </Box>
898 )
899 }
900 const doneCount = plan.steps.filter(st => st.status === 'completed').length
901 const todoBody = plan.steps.length
902 ? [
903 ...(plan.title ? wrapLines(plan.title, inner).map((line, j) => <Text key={`pt${j}`} dimColor wrap="truncate-end">{line}</Text>) : []),
904 ...plan.steps.map(todoRow),
905 ]
906 : wrapLines(NO_PLAN, inner).map((line, j) => <Text key={`np${j}`} dimColor wrap="truncate-end">{line}</Text>)
907
908 return (
909 <Box flexDirection="column" width={width}>
910 <Box key="top" flexDirection="row" justifyContent="flex-end" width={width}>
911 <Button key="hide" label="Hide" dimColor onPress={() => undefined} />
912 </Box>
913 {section('todo', 'To-do', plan.steps.length ? `${doneCount} of ${plan.steps.length}` : '', todoBody)}
914 {section('connectors', 'Connectors', String(conns.length), connectorBody)}
915 {section('files', 'Context files', String(files.length), fileBody)}
916 {section('skills', 'Skills', String(skills.length), skillBody)}
917 {!e.props.isFocused && (
918 <Text key="focus-hint" dimColor wrap="truncate-end">
919 focus: click · /inventory hide|up|down
920 </Text>
921 )}
922 </Box>
923 )
924 })
925}
926hooks/connectors.ts 117 lines1// Names an MCP connector the same way on every account.
2// A server with a readable name (mcp__notion__..., mcp__plugin_x_fireflies__...) is named for it.
3// A claude.ai connector shows a random id as its server (mcp__<random id>__<tool>), and that id differs per
4// account, so it is named by its tool names instead. Anything else gets a tidy label, never the raw id.
5
6/** Readable server names, keyed in lower case. */
7const NAMED: Record<string, string> = {
8 'google-workspace': 'Google Workspace',
9 gmail: 'Gmail',
10 'google-calendar': 'Google Calendar',
11 'google-drive': 'Google Drive',
12 'chat-relay': 'Chat Relay',
13 handoff: 'Handoff',
14 vidiq: 'vidIQ',
15 apify: 'Apify',
16 'claude-in-chrome': 'Chrome',
17 claude_browser: 'Browser',
18 fireflies: 'Fireflies',
19 posthog: 'PostHog',
20 pipedrive: 'Pipedrive',
21 pandadoc: 'PandaDoc',
22 firecrawl: 'Firecrawl',
23 attio: 'Attio',
24 composio: 'Composio',
25 figma: 'Figma',
26 stripe: 'Stripe',
27 shopify: 'Shopify',
28 notion: 'Notion',
29 slack: 'Slack',
30 calendly: 'Calendly',
31 youtube: 'YouTube',
32 kit: 'Kit',
33 circle: 'Circle',
34 'circle-community': 'Circle',
35 supabase: 'Supabase',
36 vercel: 'Vercel',
37 make: 'Make',
38 higgsfield: 'Higgsfield',
39 github: 'GitHub',
40 linear: 'Linear',
41 hubspot: 'HubSpot',
42 reddit: 'Reddit',
43}
44
45/** Tool name patterns, first match wins. Prefixed families first, then the exact names one app uses. */
46const BY_TOOL: [RegExp, string][] = [
47 [/^fireflies_/i, 'Fireflies'],
48 [/^notion-/i, 'Notion'],
49 [/^vidiq_/i, 'vidIQ'],
50 [/^slack_/i, 'Slack'],
51 [/^composio_/i, 'Composio'],
52 [/^(ads_studio|ai_influencer|scene_builder_3d|shorts_studio|tiktok)_/i, 'Higgsfield'],
53 [/^ads_/i, 'Meta Ads'],
54 [/^(availability|event_types|meetings|routing_forms|scheduling_links|shares|locations|users|organizations)-|calendly/i, 'Calendly'],
55 [
56 /^(search_threads|get_thread|get_message|list_drafts|get_draft|create_draft|update_draft|delete_draft|list_labels|create_label|update_label|delete_label|(un)?label_(thread|message)|(un)?trash_(thread|message)|(un)?mark_(thread|message)_spam|apply_sensitive_(thread|message)_label|update_message_labels|forward|reply)$/i,
57 'Gmail',
58 ],
59 [/^(list_calendars|respond_to_event|suggest_time|search_events)$/i, 'Google Calendar'],
60 [
61 /^(list_recent_files|search_files|read_file_content|download_file_content|get_file_metadata|get_file_permissions|share_file|trash_file|copy_file)$/i,
62 'Google Drive',
63 ],
64 [/^(get_spreadsheet|get_values|update_values|append_values|batch_clear_values|update_formulas|insert_dimension|update_spreadsheet|copy_sheet_to_another_spreadsheet)$/i, 'Google Sheets'],
65 [/(subscriber|broadcast|sequence|landing_page|snippet|growth_stats|email_template|creator_profile|email_stats)/i, 'Kit'],
66 [/(community_member|space_group|(^|_)spaces?(_|$)|space_member|course_(lesson|section)|access_group|member_tag|tagged_member|live_room|gamification|paywall|flagged_content|filter_kit|post_summary|advanced_search)/i, 'Circle'],
67 [/(^|-)actors?(-|$)|apify|(^|-)dataset(-|$)|key-value-store/i, 'Apify'],
68 [/-records?(-|$)|^semantic-search-|call-recording|^run-basic-report$|-workspace-(members|teams)$|-list-entry-|attribute-definitions$/i, 'Attio'],
69 [/^(scenarios?|scenario-[a-z-]+|data-stores?|data-store-records|data-structures?|hooks|hook-[a-z-]+|executions|credential-requests|app-modules?|connections|connection-[a-z-]+)_/i, 'Make'],
70 [/^(apply_migration|execute_sql|list_migrations|list_tables|list_extensions|generate_typescript_types|get_advisors|get_publishable_keys|get_project_url|deploy_edge_function|list_edge_functions|get_edge_function|create_edge_function_secret)$/i, 'Supabase'],
71 [/deployment|vercel|edge_config|project_domain|sandboxes|named_sandbox|toolbar_|rolling_release|_drains?$|kms_/i, 'Vercel'],
72 [/^(get_design_context|get_figjam|use_figma|get_figma_skill|get_variable_defs|create_design_system_rules|search_design_system|send_code_to_figma|add_code_connect_map|get_motion_context)$|code_connect|shader|generative_plugin|^weave_/i, 'Figma'],
73 [/^(find_(person|company|decision_maker)_emails?|verify_email|report_bad_email)$/i, 'AnyMailFinder'],
74 [/^(match|enrich)-(business|prospects)$|^fetch-(entities|businesses-events|prospects-events|entities-statistics)$/i, 'Vibe Prospecting'],
75 [/^(getTranscripts|getVideoDetails|searchVideos|getChannelStatistics|getVideoComments|getTrendingVideos|getChannelTopVideos|getVideoCategories)$/, 'YouTube'],
76]
77
78/** The label for a connector whose name cannot be told from its server or its tools. */
79export const OTHER = 'Connector'
80
81/** Every name this file can give, so a caller can set up one handler per name. */
82export const CONNECTOR_NAMES: readonly string[] = [...new Set([...Object.values(NAMED), ...BY_TOOL.map(r => r[1]), OTHER])]
83
84const titleCase = (s: string) =>
85 s
86 .split(/[-_\s]+/)
87 .filter(Boolean)
88 .map(w => w[0]!.toUpperCase() + w.slice(1))
89 .join(' ')
90
91/** A random id rather than a name: 8 hex characters, a dash, then more hex and dashes. */
92export const isIdServer = (server: string) => /^[0-9a-f]{8}-[0-9a-f-]*$/i.test(server)
93
94// Servers already named by one of their tools, so a tool that fits no pattern still gets the name.
95const known = new Map<string, string>()
96
97/** The server and tool parts of an MCP tool name: mcp__<server>__<tool>. */
98export function splitTool(tool: string): { server: string; name: string } {
99 const [, server = '', ...rest] = tool.split('__')
100 return { server, name: rest.join('__') }
101}
102
103/** The friendly name for an MCP server, given one of its tool names. */
104export function connectorName(server: string, toolName: string): string {
105 if (!isIdServer(server)) {
106 let name = server.replace(/^plugin_[^_]+_/, '').replace(/^claude_ai_/i, '')
107 if (!name) name = server
108 return NAMED[name.toLowerCase()] ?? titleCase(name)
109 }
110 const hit = BY_TOOL.find(([re]) => re.test(toolName))
111 if (hit) {
112 known.set(server, hit[1])
113 return hit[1]
114 }
115 return known.get(server) ?? OTHER
116}
117hooks/logos.ts 4 lines1// Generated by assets/build-logos.py. Do not edit by hand.
2export type Logo = { svg: string; color: string; real: boolean }
3export const LOGOS: Record<string, Logo> = {"gmail": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 49.4 512 399.42\" preserveAspectRatio=\"xMidYMid meet\"><g fill=\"none\" fill-rule=\"evenodd\"><g fill-rule=\"nonzero\"><path fill=\"#4285f4\" d=\"M34.91 448.818h81.454V251L0 163.727V413.91c0 19.287 15.622 34.91 34.91 34.91z\"/><path fill=\"#34a853\" d=\"M395.636 448.818h81.455c19.287 0 34.909-15.622 34.909-34.909V163.727L395.636 251z\"/><path fill=\"#fbbc04\" d=\"M395.636 99.727V251L512 163.727v-46.545c0-43.142-49.25-67.782-83.782-41.891z\"/></g><path fill=\"#ea4335\" d=\"M116.364 251V99.727L256 204.455 395.636 99.727V251L256 355.727z\"/><path fill=\"#c5221f\" fill-rule=\"nonzero\" d=\"M0 117.182v46.545L116.364 251V99.727L83.782 75.291C49.25 49.4 0 74.04 0 117.18z\"/></g></svg></svg>", "color": "#EA4335", "real": true}, "googlecalendar": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 256 256\" preserveAspectRatio=\"xMidYMid meet\"><g><polygon fill=\"#FFFFFF\" points=\"195.368421 60.6315789 60.6315789 60.6315789 60.6315789 195.368421 195.368421 195.368421\"></polygon><polygon fill=\"#EA4335\" points=\"195.368421 256 256 195.368421 225.684211 190.196005 195.368421 195.368421 189.835162 223.098002\"></polygon><path d=\"M1.42108547e-14,195.368421 L1.42108547e-14,235.789474 C1.42108547e-14,246.955789 9.04421053,256 20.2105263,256 L60.6315789,256 L66.8568645,225.684211 L60.6315789,195.368421 L27.5991874,190.196005 L1.42108547e-14,195.368421 Z\" fill=\"#188038\"></path><path d=\"M256,60.6315789 L256,20.2105263 C256,9.04421053 246.955789,1.42108547e-14 235.789474,1.42108547e-14 L195.368421,1.42108547e-14 C191.679582,15.0358547 189.835162,26.1010948 189.835162,33.1957202 C189.835162,40.2903456 191.679582,49.4356319 195.368421,60.6315789 C208.777986,64.4714866 218.883249,66.3914404 225.684211,66.3914404 C232.485172,66.3914404 242.590435,64.4714866 256,60.6315789 Z\" fill=\"#1967D2\"></path><polygon fill=\"#FBBC04\" points=\"256 60.6315789 195.368421 60.6315789 195.368421 195.368421 256 195.368421\"></polygon><polygon fill=\"#34A853\" points=\"195.368421 195.368421 60.6315789 195.368421 60.6315789 256 195.368421 256\"></polygon><path d=\"M195.368421,0 L20.2105263,0 C9.04421053,0 0,9.04421053 0,20.2105263 L0,195.368421 L60.6315789,195.368421 L60.6315789,60.6315789 L195.368421,60.6315789 L195.368421,0 Z\" fill=\"#4285F4\"></path><path d=\"M88.2694737,165.153684 C83.2336842,161.751579 79.7473684,156.783158 77.8442105,150.214737 L89.5326316,145.397895 C90.5936842,149.44 92.4463158,152.572632 95.0905263,154.795789 C97.7178947,157.018947 100.917895,158.113684 104.656842,158.113684 C108.48,158.113684 111.764211,156.951579 114.509474,154.627368 C117.254737,152.303158 118.635789,149.338947 118.635789,145.751579 C118.635789,142.08 117.187368,139.082105 114.290526,136.757895 C111.393684,134.433684 107.755789,133.271579 103.410526,133.271579 L96.6568421,133.271579 L96.6568421,121.701053 L102.72,121.701053 C106.458947,121.701053 109.608421,120.690526 112.168421,118.669474 C114.728421,116.648421 116.008421,113.886316 116.008421,110.366316 C116.008421,107.233684 114.863158,104.741053 112.572632,102.871579 C110.282105,101.002105 107.385263,100.058947 103.865263,100.058947 C100.429474,100.058947 97.7010526,100.968421 95.68,102.804211 C93.6602819,104.644885 92.1418208,106.968942 91.2673684,109.557895 L79.6968421,104.741053 C81.2294737,100.395789 84.0421053,96.5557895 88.1684211,93.2378947 C92.2947368,89.92 97.5663158,88.2526316 103.966316,88.2526316 C108.698947,88.2526316 112.96,89.1621053 116.732632,90.9978947 C120.505263,92.8336842 123.469474,95.3768421 125.608421,98.6105263 C127.747368,101.861053 128.808421,105.498947 128.808421,109.541053 C128.808421,113.667368 127.814737,117.153684 125.827368,120.016842 C123.84,122.88 121.397895,125.069474 118.501053,126.602105 L118.501053,127.292632 C122.241568,128.834789 125.490747,131.367752 127.898947,134.618947 C130.341053,137.903158 131.570526,141.827368 131.570526,146.408421 C131.570526,150.989474 130.408421,155.082105 128.084211,158.669474 C125.76,162.256842 122.543158,165.086316 118.467368,167.141053 C114.374737,169.195789 109.776842,170.240124 104.673684,170.240124 C98.7621053,170.256842 93.3052632,168.555789 88.2694737,165.153684 L88.2694737,165.153684 Z M160.067368,107.149474 L147.233684,116.429474 L140.816842,106.694737 L163.84,90.0884211 L172.665263,90.0884211 L172.665263,168.421053 L160.067368,168.421053 L160.067368,107.149474 Z\" fill=\"#4285F4\"></path></g></svg></svg>", "color": "#4285F4", "real": true}, "googledrive": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 256 229\" preserveAspectRatio=\"xMidYMid meet\"><g><path d=\"M19.3542312,196.033928 L30.644172,215.534816 C32.9900287,219.64014 36.3622164,222.86588 40.3210929,225.211737 C51.6602421,210.818376 59.5534225,199.772864 64.000634,192.075201 C68.5137119,184.263529 74.0609657,172.045039 80.6423954,155.41973 C62.9064315,153.085282 49.4659974,151.918058 40.3210929,151.918058 C31.545465,151.918058 18.1051007,153.085282 0,155.41973 C0,159.964996 1.17298825,164.510261 3.51893479,168.615586 L19.3542312,196.033928 Z\" fill=\"#0066DA\"></path><path d=\"M215.681443,225.211737 C219.64032,222.86588 223.012507,219.64014 225.358364,215.534816 L230.050377,207.470615 L252.483511,168.615586 C254.829368,164.510261 256.002446,159.964996 256.002446,155.41973 C237.79254,153.085282 224.376613,151.918058 215.754667,151.918058 C206.488712,151.918058 193.072785,153.085282 175.506888,155.41973 C182.010479,172.136093 187.484394,184.354584 191.928633,192.075201 C196.412073,199.863919 204.329677,210.909431 215.681443,225.211737 Z\" fill=\"#EA4335\"></path><path d=\"M128.001268,73.3111515 C141.121182,57.4655263 150.162898,45.2470011 155.126415,36.6555757 C159.123121,29.7376196 163.521739,18.6920726 168.322271,3.51893479 C164.363395,1.1729583 159.818129,0 155.126415,0 L100.876121,0 C96.1841079,0 91.638842,1.31958557 87.6799655,3.51893479 C93.7861943,20.9210065 98.9675428,33.3058067 103.224011,40.6733354 C107.927832,48.8151881 116.186918,59.6944602 128.001268,73.3111515 Z\" fill=\"#00832D\"></path><path d=\"M175.360141,155.41973 L80.6420959,155.41973 L40.3210929,225.211737 C44.2799694,227.557893 48.8252352,228.730672 53.5172481,228.730672 L202.485288,228.730672 C207.177301,228.730672 211.722567,227.411146 215.681443,225.211737 L175.360141,155.41973 Z\" fill=\"#2684FC\"></path><path d=\"M128.001268,73.3111515 L87.680265,3.51893479 C83.7213885,5.86488134 80.3489013,9.09044179 78.0030446,13.1960654 L3.51893479,142.223575 C1.17298825,146.329198 0,150.874464 0,155.41973 L80.6423954,155.41973 L128.001268,73.3111515 Z\" fill=\"#00AC47\"></path><path d=\"M215.241501,77.7099697 L177.999492,13.1960654 C175.653635,9.09044179 172.281148,5.86488134 168.322271,3.51893479 L128.001268,73.3111515 L175.360141,155.41973 L255.855999,155.41973 C255.855999,150.874464 254.682921,146.329198 252.337064,142.223575 L215.241501,77.7099697 Z\" fill=\"#FFBA00\"></path></g></svg></svg>", "color": "#0F9D58", "real": true}, "googlesheets": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 74 100\" preserveAspectRatio=\"xMidYMid meet\"><mask id=\"googlesheets-mask0_1:52\" style=\"mask-type:alpha\" maskUnits=\"userSpaceOnUse\" x=\"1\" y=\"1\" width=\"71\" height=\"98\"><path d=\"M45.398 1.43036H7.86688C4.22415 1.43036 1.24374 4.41077 1.24374 8.0535V91.9465C1.24374 95.5893 4.22415 98.5697 7.86688 98.5697H65.2674C68.9101 98.5697 71.8905 95.5893 71.8905 91.9465V27.9229L45.398 1.43036Z\" fill=\"white\"/></mask><g mask=\"url(#googlesheets-mask0_1:52)\"><path d=\"M45.398 1.43036H7.86688C4.22415 1.43036 1.24374 4.41077 1.24374 8.0535V91.9465C1.24374 95.5893 4.22415 98.5697 7.86688 98.5697H65.2674C68.9101 98.5697 71.8905 95.5893 71.8905 91.9465V27.9229L56.4365 16.8843L45.398 1.43036Z\" fill=\"#0F9D58\"/></g><mask id=\"googlesheets-mask1_1:52\" style=\"mask-type:alpha\" maskUnits=\"userSpaceOnUse\" x=\"1\" y=\"1\" width=\"71\" height=\"98\"><path d=\"M45.398 1.43036H7.86688C4.22415 1.43036 1.24374 4.41077 1.24374 8.0535V91.9465C1.24374 95.5893 4.22415 98.5697 7.86688 98.5697H65.2674C68.9101 98.5697 71.8905 95.5893 71.8905 91.9465V27.9229L45.398 1.43036Z\" fill=\"white\"/></mask><g mask=\"url(#googlesheets-mask1_1:52)\"><path d=\"M18.9054 48.8962V80.908H54.2288V48.8962H18.9054ZM34.3594 76.4926H23.3209V70.9733H34.3594V76.4926ZM34.3594 67.6617H23.3209V62.1424H34.3594V67.6617ZM34.3594 58.8309H23.3209V53.3116H34.3594V58.8309ZM49.8134 76.4926H38.7748V70.9733H49.8134V76.4926ZM49.8134 67.6617H38.7748V62.1424H49.8134V67.6617ZM49.8134 58.8309H38.7748V53.3116H49.8134V58.8309Z\" fill=\"#F1F1F1\"/></g><mask id=\"googlesheets-mask2_1:52\" style=\"mask-type:alpha\" maskUnits=\"userSpaceOnUse\" x=\"1\" y=\"1\" width=\"71\" height=\"98\"><path d=\"M45.398 1.43036H7.86688C4.22415 1.43036 1.24374 4.41077 1.24374 8.0535V91.9465C1.24374 95.5893 4.22415 98.5697 7.86688 98.5697H65.2674C68.9101 98.5697 71.8905 95.5893 71.8905 91.9465V27.9229L45.398 1.43036Z\" fill=\"white\"/></mask><g mask=\"url(#googlesheets-mask2_1:52)\"><path d=\"M47.3352 25.9856L71.8905 50.5354V27.9229L47.3352 25.9856Z\" fill=\"url(#googlesheets-paint0_linear_1:52)\"/></g><mask id=\"googlesheets-mask3_1:52\" style=\"mask-type:alpha\" maskUnits=\"userSpaceOnUse\" x=\"1\" y=\"1\" width=\"71\" height=\"98\"><path d=\"M45.398 1.43036H7.86688C4.22415 1.43036 1.24374 4.41077 1.24374 8.0535V91.9465C1.24374 95.5893 4.22415 98.5697 7.86688 98.5697H65.2674C68.9101 98.5697 71.8905 95.5893 71.8905 91.9465V27.9229L45.398 1.43036Z\" fill=\"white\"/></mask><g mask=\"url(#googlesheets-mask3_1:52)\"><path d=\"M45.398 1.43036V21.2998C45.398 24.959 48.3618 27.9229 52.0211 27.9229H71.8905L45.398 1.43036Z\" fill=\"#87CEAC\"/></g><mask id=\"googlesheets-mask4_1:52\" style=\"mask-type:alpha\" maskUnits=\"userSpaceOnUse\" x=\"1\" y=\"1\" width=\"71\" height=\"98\"><path d=\"M45.398 1.43036H7.86688C4.22415 1.43036 1.24374 4.41077 1.24374 8.0535V91.9465C1.24374 95.5893 4.22415 98.5697 7.86688 98.5697H65.2674C68.9101 98.5697 71.8905 95.5893 71.8905 91.9465V27.9229L45.398 1.43036Z\" fill=\"white\"/></mask><g mask=\"url(#googlesheets-mask4_1:52)\"><path d=\"M7.86688 1.43036C4.22415 1.43036 1.24374 4.41077 1.24374 8.0535V8.60542C1.24374 4.9627 4.22415 1.98229 7.86688 1.98229H45.398V1.43036H7.86688Z\" fill=\"white\" fill-opacity=\"0.2\"/></g><mask id=\"googlesheets-mask5_1:52\" style=\"mask-type:alpha\" maskUnits=\"userSpaceOnUse\" x=\"1\" y=\"1\" width=\"71\" height=\"98\"><path d=\"M45.398 1.43036H7.86688C4.22415 1.43036 1.24374 4.41077 1.24374 8.0535V91.9465C1.24374 95.5893 4.22415 98.5697 7.86688 98.5697H65.2674C68.9101 98.5697 71.8905 95.5893 71.8905 91.9465V27.9229L45.398 1.43036Z\" fill=\"white\"/></mask><g mask=\"url(#googlesheets-mask5_1:52)\"><path d=\"M65.2674 98.0177H7.86688C4.22415 98.0177 1.24374 95.0373 1.24374 91.3946V91.9465C1.24374 95.5893 4.22415 98.5697 7.86688 98.5697H65.2674C68.9101 98.5697 71.8905 95.5893 71.8905 91.9465V91.3946C71.8905 95.0373 68.9101 98.0177 65.2674 98.0177Z\" fill=\"#263238\" fill-opacity=\"0.2\"/></g><mask id=\"googlesheets-mask6_1:52\" style=\"mask-type:alpha\" maskUnits=\"userSpaceOnUse\" x=\"1\" y=\"1\" width=\"71\" height=\"98\"><path d=\"M45.398 1.43036H7.86688C4.22415 1.43036 1.24374 4.41077 1.24374 8.0535V91.9465C1.24374 95.5893 4.22415 98.5697 7.86688 98.5697H65.2674C68.9101 98.5697 71.8905 95.5893 71.8905 91.9465V27.9229L45.398 1.43036Z\" fill=\"white\"/></mask><g mask=\"url(#googlesheets-mask6_1:52)\"><path d=\"M52.0211 27.9229C48.3618 27.9229 45.398 24.959 45.398 21.2998V21.8517C45.398 25.511 48.3618 28.4748 52.0211 28.4748H71.8905V27.9229H52.0211Z\" fill=\"#263238\" fill-opacity=\"0.1\"/></g><path d=\"M45.398 1.43036H7.86688C4.22415 1.43036 1.24374 4.41077 1.24374 8.0535V91.9465C1.24374 95.5893 4.22415 98.5697 7.86688 98.5697H65.2674C68.9101 98.5697 71.8905 95.5893 71.8905 91.9465V27.9229L45.398 1.43036Z\" fill=\"url(#googlesheets-paint1_radial_1:52)\"/><defs><linearGradient id=\"googlesheets-paint0_linear_1:52\" x1=\"59.6142\" y1=\"28.0935\" x2=\"59.6142\" y2=\"50.5388\" gradientUnits=\"userSpaceOnUse\"><stop stop-color=\"#263238\" stop-opacity=\"0.2\"/><stop offset=\"1\" stop-color=\"#263238\" stop-opacity=\"0.02\"/></linearGradient><radialGradient id=\"googlesheets-paint1_radial_1:52\" cx=\"0\" cy=\"0\" r=\"1\" gradientUnits=\"userSpaceOnUse\" gradientTransform=\"translate(3.48187 3.36121) scale(113.917)\"><stop stop-color=\"white\" stop-opacity=\"0.1\"/><stop offset=\"1\" stop-color=\"white\" stop-opacity=\"0\"/></radialGradient></defs></svg></svg>", "color": "#34A853", "real": true}, "googledocs": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" preserveAspectRatio=\"xMidYMid meet\"><path fill=\"#4285F4\" d=\"M14.727 6.727H14V0H4.91c-.905 0-1.637.732-1.637 1.636v20.728c0 .904.732 1.636 1.636 1.636h14.182c.904 0 1.636-.732 1.636-1.636V6.727h-6zm-.545 10.455H7.09v-1.364h7.09v1.364zm2.727-3.273H7.091v-1.364h9.818v1.364zm0-3.273H7.091V9.273h9.818v1.363zM14.727 6h6l-6-6v6z\"/></svg></svg>", "color": "#4285F4", "real": true}, "google": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 268.152 273.883\" preserveAspectRatio=\"xMidYMid meet\"><defs><linearGradient id=\"google-a\"><stop offset=\"0\" stop-color=\"#0fbc5c\"/><stop offset=\"1\" stop-color=\"#0cba65\"/></linearGradient><linearGradient id=\"google-g\"><stop offset=\".231\" stop-color=\"#0fbc5f\"/><stop offset=\".312\" stop-color=\"#0fbc5f\"/><stop offset=\".366\" stop-color=\"#0fbc5e\"/><stop offset=\".458\" stop-color=\"#0fbc5d\"/><stop offset=\".54\" stop-color=\"#12bc58\"/><stop offset=\".699\" stop-color=\"#28bf3c\"/><stop offset=\".771\" stop-color=\"#38c02b\"/><stop offset=\".861\" stop-color=\"#52c218\"/><stop offset=\".915\" stop-color=\"#67c30f\"/><stop offset=\"1\" stop-color=\"#86c504\"/></linearGradient><linearGradient id=\"google-h\"><stop offset=\".142\" stop-color=\"#1abd4d\"/><stop offset=\".248\" stop-color=\"#6ec30d\"/><stop offset=\".312\" stop-color=\"#8ac502\"/><stop offset=\".366\" stop-color=\"#a2c600\"/><stop offset=\".446\" stop-color=\"#c8c903\"/><stop offset=\".54\" stop-color=\"#ebcb03\"/><stop offset=\".616\" stop-color=\"#f7cd07\"/><stop offset=\".699\" stop-color=\"#fdcd04\"/><stop offset=\".771\" stop-color=\"#fdce05\"/><stop offset=\".861\" stop-color=\"#ffce0a\"/></linearGradient><linearGradient id=\"google-f\"><stop offset=\".316\" stop-color=\"#ff4c3c\"/><stop offset=\".604\" stop-color=\"#ff692c\"/><stop offset=\".727\" stop-color=\"#ff7825\"/><stop offset=\".885\" stop-color=\"#ff8d1b\"/><stop offset=\"1\" stop-color=\"#ff9f13\"/></linearGradient><linearGradient id=\"google-b\"><stop offset=\".231\" stop-color=\"#ff4541\"/><stop offset=\".312\" stop-color=\"#ff4540\"/><stop offset=\".458\" stop-color=\"#ff4640\"/><stop offset=\".54\" stop-color=\"#ff473f\"/><stop offset=\".699\" stop-color=\"#ff5138\"/><stop offset=\".771\" stop-color=\"#ff5b33\"/><stop offset=\".861\" stop-color=\"#ff6c29\"/><stop offset=\"1\" stop-color=\"#ff8c18\"/></linearGradient><linearGradient id=\"google-d\"><stop offset=\".408\" stop-color=\"#fb4e5a\"/><stop offset=\"1\" stop-color=\"#ff4540\"/></linearGradient><linearGradient id=\"google-c\"><stop offset=\".132\" stop-color=\"#0cba65\"/><stop offset=\".21\" stop-color=\"#0bb86d\"/><stop offset=\".297\" stop-color=\"#09b479\"/><stop offset=\".396\" stop-color=\"#08ad93\"/><stop offset=\".477\" stop-color=\"#0aa6a9\"/><stop offset=\".568\" stop-color=\"#0d9cc6\"/><stop offset=\".667\" stop-color=\"#1893dd\"/><stop offset=\".769\" stop-color=\"#258bf1\"/><stop offset=\".859\" stop-color=\"#3086ff\"/></linearGradient><linearGradient id=\"google-e\"><stop offset=\".366\" stop-color=\"#ff4e3a\"/><stop offset=\".458\" stop-color=\"#ff8a1b\"/><stop offset=\".54\" stop-color=\"#ffa312\"/><stop offset=\".616\" stop-color=\"#ffb60c\"/><stop offset=\".771\" stop-color=\"#ffcd0a\"/><stop offset=\".861\" stop-color=\"#fecf0a\"/><stop offset=\".915\" stop-color=\"#fecf08\"/><stop offset=\"1\" stop-color=\"#fdcd01\"/></linearGradient><linearGradient xlink:href=\"#google-a\" id=\"google-s\" x1=\"219.7\" x2=\"254.467\" y1=\"329.535\" y2=\"329.535\" gradientUnits=\"userSpaceOnUse\"/><radialGradient xlink:href=\"#google-b\" id=\"google-m\" cx=\"109.627\" cy=\"135.862\" r=\"71.46\" fx=\"109.627\" fy=\"135.862\" gradientTransform=\"matrix(-1.93688 1.043 1.45573 2.55542 290.525 -400.634)\" gradientUnits=\"userSpaceOnUse\"/><radialGradient xlink:href=\"#google-c\" id=\"google-n\" cx=\"45.259\" cy=\"279.274\" r=\"71.46\" fx=\"45.259\" fy=\"279.274\" gradientTransform=\"matrix(-3.5126 -4.45809 -1.69255 1.26062 870.8 191.554)\" gradientUnits=\"userSpaceOnUse\"/><radialGradient xlink:href=\"#google-d\" id=\"google-l\" cx=\"304.017\" cy=\"118.009\" r=\"47.854\" fx=\"304.017\" fy=\"118.009\" gradientTransform=\"matrix(2.06435 0 0 2.59204 -297.679 -151.747)\" gradientUnits=\"userSpaceOnUse\"/><radialGradient xlink:href=\"#google-e\" id=\"google-o\" cx=\"181.001\" cy=\"177.201\" r=\"71.46\" fx=\"181.001\" fy=\"177.201\" gradientTransform=\"matrix(-.24858 2.08314 2.96249 .33417 -255.146 -331.164)\" gradientUnits=\"userSpaceOnUse\"/><radialGradient xlink:href=\"#google-f\" id=\"google-p\" cx=\"207.673\" cy=\"108.097\" r=\"41.102\" fx=\"207.673\" fy=\"108.097\" gradientTransform=\"matrix(-1.2492 1.34326 -3.89684 -3.4257 880.501 194.905)\" gradientUnits=\"userSpaceOnUse\"/><radialGradient xlink:href=\"#google-g\" id=\"google-r\" cx=\"109.627\" cy=\"135.862\" r=\"71.46\" fx=\"109.627\" fy=\"135.862\" gradientTransform=\"matrix(-1.93688 -1.043 1.45573 -2.55542 290.525 838.683)\" gradientUnits=\"userSpaceOnUse\"/><radialGradient xlink:href=\"#google-h\" id=\"google-j\" cx=\"154.87\" cy=\"145.969\" r=\"71.46\" fx=\"154.87\" fy=\"145.969\" gradientTransform=\"matrix(-.0814 -1.93722 2.92674 -.11625 -215.135 632.86)\" gradientUnits=\"userSpaceOnUse\"/><filter id=\"google-q\" width=\"1.097\" height=\"1.116\" x=\"-.048\" y=\"-.058\" color-interpolation-filters=\"sRGB\"><feGaussianBlur stdDeviation=\"1.701\"/></filter><filter id=\"google-k\" width=\"1.033\" height=\"1.02\" x=\"-.017\" y=\"-.01\" color-interpolation-filters=\"sRGB\"><feGaussianBlur stdDeviation=\".242\"/></filter><clipPath id=\"google-i\" clipPathUnits=\"userSpaceOnUse\"><path d=\"M371.378 193.24H237.083v53.438h77.167c-1.241 7.563-4.026 15.003-8.105 21.786-4.674 7.773-10.451 13.69-16.373 18.196-17.74 13.498-38.42 16.258-52.783 16.258-36.283 0-67.283-23.286-79.285-54.928-.484-1.149-.805-2.335-1.197-3.507a81.115 81.115 0 0 1-4.101-25.448c0-9.226 1.569-18.057 4.43-26.398 11.285-32.897 42.985-57.467 80.179-57.467 7.481 0 14.685.884 21.517 2.648a77.668 77.668 0 0 1 33.425 18.25l40.834-39.712c-24.839-22.616-57.219-36.32-95.844-36.32-30.878 0-59.386 9.553-82.748 25.7-18.945 13.093-34.483 30.625-44.97 50.985-9.753 18.879-15.094 39.8-15.094 62.294 0 22.495 5.35 43.633 15.103 62.337v.126c10.302 19.857 25.368 36.954 43.678 49.988 15.997 11.386 44.68 26.551 84.031 26.551 22.63 0 42.687-4.051 60.375-11.644 12.76-5.478 24.065-12.622 34.301-21.804 13.525-12.132 24.117-27.139 31.347-44.404 7.23-17.265 11.097-36.79 11.097-57.957 0-9.858-.998-19.87-2.689-28.968Z\"/></clipPath></defs><g clip-path=\"url(#google-i)\" transform=\"matrix(.95792 0 0 .98525 -90.174 -78.856)\"><path fill=\"url(#google-j)\" d=\"M92.076 219.958c.148 22.14 6.501 44.983 16.117 63.424v.127c6.949 13.392 16.445 23.97 27.26 34.452l65.327-23.67c-12.36-6.235-14.246-10.055-23.105-17.026-9.054-9.066-15.802-19.473-20.004-31.677h-.17l.17-.127c-2.765-8.058-3.037-16.613-3.14-25.503Z\" filter=\"url(#google-k)\"/><path fill=\"url(#google-l)\" d=\"M237.083 79.025c-6.456 22.526-3.988 44.421 0 57.161 7.457.006 14.64.888 21.45 2.647a77.662 77.662 0 0 1 33.424 18.25l41.88-40.726c-24.81-22.59-54.667-37.297-96.754-37.332Z\" filter=\"url(#google-k)\"/><path fill=\"url(#google-m)\" d=\"M236.943 78.847c-31.67 0-60.91 9.798-84.871 26.359a145.533 145.533 0 0 0-24.332 21.15c-1.904 17.744 14.257 39.551 46.262 39.37 15.528-17.936 38.495-29.542 64.056-29.542l.07.002-1.044-57.335c-.048 0-.093-.004-.14-.004Z\" filter=\"url(#google-k)\"/><path fill=\"url(#google-n)\" d=\"m341.475 226.379-28.268 19.285c-1.24 7.562-4.028 15.002-8.107 21.786-4.674 7.772-10.45 13.69-16.373 18.196-17.702 13.47-38.328 16.244-52.687 16.255-14.842 25.102-17.444 37.675 1.043 57.934 22.877-.016 43.157-4.117 61.046-11.796 12.931-5.551 24.388-12.792 34.761-22.097 13.706-12.295 24.442-27.503 31.769-45 7.327-17.497 11.245-37.282 11.245-58.734Z\" filter=\"url(#google-k)\"/><path fill=\"#3086ff\" d=\"M234.996 191.21v57.498h136.006c1.196-7.874 5.152-18.064 5.152-26.5 0-9.858-.996-21.899-2.687-30.998Z\" filter=\"url(#google-k)\"/><path fill=\"url(#google-o)\" d=\"M128.39 124.327c-8.394 9.119-15.564 19.326-21.249 30.364-9.753 18.879-15.094 41.83-15.094 64.324 0 .317.026.627.029.944 4.32 8.224 59.666 6.649 62.456 0-.004-.31-.039-.613-.039-.924 0-9.226 1.57-16.026 4.43-24.367 3.53-10.289 9.056-19.763 16.123-27.926 1.602-2.031 5.875-6.397 7.121-9.016.475-.997-.862-1.557-.937-1.908-.083-.393-1.876-.077-2.277-.37-1.275-.929-3.8-1.414-5.334-1.845-3.277-.921-8.708-2.953-11.725-5.06-9.536-6.658-24.417-14.612-33.505-24.216Z\" filter=\"url(#google-k)\"/><path fill=\"url(#google-p)\" d=\"M162.099 155.857c22.112 13.301 28.471-6.714 43.173-12.977l-25.574-52.664a144.74 144.74 0 0 0-26.543 14.504c-12.316 8.512-23.192 18.9-32.176 30.72Z\" filter=\"url(#google-q)\"/><path fill=\"url(#google-r)\" d=\"M171.099 290.222c-29.683 10.641-34.33 11.023-37.062 29.29a144.806 144.806 0 0 0 16.792 13.984c15.996 11.386 46.766 26.551 86.118 26.551.046 0 .09-.004.137-.004v-59.157l-.094.002c-14.736 0-26.512-3.843-38.585-10.527-2.977-1.648-8.378 2.777-11.123.799-3.786-2.729-12.9 2.35-16.183-.938Z\" filter=\"url(#google-k)\"/><path fill=\"url(#google-s)\" d=\"M219.7 299.023v59.996c5.506.64 11.236 1.028 17.247 1.028 6.026 0 11.855-.307 17.52-.872v-59.748a105.119 105.119 0 0 1-17.477 1.461c-5.932 0-11.7-.686-17.29-1.865Z\" filter=\"url(#google-k)\" opacity=\".5\"/></g></svg></svg>", "color": "#4285F4", "real": true}, "notion": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 256 268\" preserveAspectRatio=\"xMidYMid meet\"><g><path d=\"M16.0924984,11.5384656 L164.089991,0.608048392 C182.268719,-0.952166138 186.940447,0.0998642306 198.370133,8.40912104 L245.613429,41.6907258 C253.405586,47.4144843 256,48.9746988 256,55.2066414 L256,237.73391 C256,249.172512 251.845372,255.939385 237.304172,256.973584 L65.4398551,267.377986 C54.5272689,267.895086 49.3295257,266.334872 43.6146827,259.050899 L8.82635648,213.813593 C2.58549836,205.486505 0,199.254562 0,191.970589 L0,29.7261093 C0,20.3737376 4.1546284,12.572665 16.0924984,11.5384656 Z\" fill=\"#FFFFFF\"></path><path d=\"M164.089991,0.608048392 L16.0924984,11.5384656 C4.1546284,12.572665 0,20.3737376 0,29.7261093 L0,191.970589 C0,199.254562 2.58549836,205.486505 8.82635648,213.813593 L43.6146827,259.050899 C49.3295257,266.334872 54.5272689,267.895086 65.4398551,267.377986 L237.304172,256.973584 C251.836456,255.939385 256,249.172512 256,237.73391 L256,55.2066414 C256,49.2956572 253.664136,47.5927945 246.790277,42.5466149 C246.394749,42.2616979 245.999494,41.9764014 245.604513,41.6907258 L198.370133,8.40912104 C186.940447,0.0998642306 182.268719,-0.952166138 164.089991,0.608048392 Z M69.3270182,52.219945 C55.2940029,53.1649893 52.1111653,53.3789615 44.1406979,46.8973846 L23.8757401,30.7781396 C21.8162569,28.6919099 22.8504562,26.0885805 28.039284,25.5714809 L170.313018,15.1759943 C182.259804,14.1328795 188.482831,18.2964234 193.154559,21.9339521 L217.556314,39.6134116 C218.599429,40.1394268 221.193843,43.2509404 218.073414,43.2509404 L71.1457825,52.0951279 L69.3270182,52.219945 Z M52.9670544,236.173696 L52.9670544,81.2221043 C52.9670544,74.455231 55.0443686,71.3348019 61.2673957,70.8087867 L230.020199,60.9303999 C235.743958,60.4133002 238.329456,64.0508289 238.329456,70.8087867 L238.329456,224.726179 C238.329456,231.493052 237.286341,237.216811 227.942885,237.73391 L66.4562234,247.095198 C57.1127673,247.612297 52.9670544,244.500784 52.9670544,236.173696 Z M212.376402,89.5313611 C213.410601,94.2120046 212.376402,98.8926482 207.695758,99.4275789 L199.912517,100.969962 L199.912517,215.373807 C193.154559,219.011336 186.931532,221.08865 181.733788,221.08865 C173.424532,221.08865 171.347217,218.485321 165.12419,210.693164 L114.225535,130.614039 L114.225535,208.089834 L130.326949,211.736279 C130.326949,211.736279 130.326949,221.097566 117.337048,221.097566 L81.523438,223.17488 C80.4803232,221.08865 81.523438,215.890907 85.1520513,214.856708 L94.5044229,212.262294 L94.5044229,109.823065 L81.523438,108.771035 C80.4803232,104.090391 83.0747371,97.3324337 90.3497945,96.8064185 L128.77565,94.2209202 L181.733788,175.334245 L181.733788,103.573292 L168.235704,102.021993 C167.192589,96.2893189 171.347217,92.1257749 176.536045,91.6175908 L212.376402,89.5313611 L212.376402,89.5313611 Z\" fill=\"#000000\"></path></g></svg></svg>", "color": "#000000", "real": true}, "slack": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 256 256\" preserveAspectRatio=\"xMidYMid meet\"><g><path d=\"M53.8412698,161.320635 C53.8412698,176.152381 41.8539683,188.139683 27.0222222,188.139683 C12.1904762,188.139683 0.203174603,176.152381 0.203174603,161.320635 C0.203174603,146.488889 12.1904762,134.501587 27.0222222,134.501587 L53.8412698,134.501587 L53.8412698,161.320635 Z M67.2507937,161.320635 C67.2507937,146.488889 79.2380952,134.501587 94.0698413,134.501587 C108.901587,134.501587 120.888889,146.488889 120.888889,161.320635 L120.888889,228.368254 C120.888889,243.2 108.901587,255.187302 94.0698413,255.187302 C79.2380952,255.187302 67.2507937,243.2 67.2507937,228.368254 L67.2507937,161.320635 Z\" fill=\"#E01E5A\"></path><path d=\"M94.0698413,53.6380952 C79.2380952,53.6380952 67.2507937,41.6507937 67.2507937,26.8190476 C67.2507937,11.9873016 79.2380952,-7.10542736e-15 94.0698413,-7.10542736e-15 C108.901587,-7.10542736e-15 120.888889,11.9873016 120.888889,26.8190476 L120.888889,53.6380952 L94.0698413,53.6380952 Z M94.0698413,67.2507937 C108.901587,67.2507937 120.888889,79.2380952 120.888889,94.0698413 C120.888889,108.901587 108.901587,120.888889 94.0698413,120.888889 L26.8190476,120.888889 C11.9873016,120.888889 0,108.901587 0,94.0698413 C0,79.2380952 11.9873016,67.2507937 26.8190476,67.2507937 L94.0698413,67.2507937 Z\" fill=\"#36C5F0\"></path><path d=\"M201.549206,94.0698413 C201.549206,79.2380952 213.536508,67.2507937 228.368254,67.2507937 C243.2,67.2507937 255.187302,79.2380952 255.187302,94.0698413 C255.187302,108.901587 243.2,120.888889 228.368254,120.888889 L201.549206,120.888889 L201.549206,94.0698413 Z M188.139683,94.0698413 C188.139683,108.901587 176.152381,120.888889 161.320635,120.888889 C146.488889,120.888889 134.501587,108.901587 134.501587,94.0698413 L134.501587,26.8190476 C134.501587,11.9873016 146.488889,-1.42108547e-14 161.320635,-1.42108547e-14 C176.152381,-1.42108547e-14 188.139683,11.9873016 188.139683,26.8190476 L188.139683,94.0698413 Z\" fill=\"#2EB67D\"></path><path d=\"M161.320635,201.549206 C176.152381,201.549206 188.139683,213.536508 188.139683,228.368254 C188.139683,243.2 176.152381,255.187302 161.320635,255.187302 C146.488889,255.187302 134.501587,243.2 134.501587,228.368254 L134.501587,201.549206 L161.320635,201.549206 Z M161.320635,188.139683 C146.488889,188.139683 134.501587,176.152381 134.501587,161.320635 C134.501587,146.488889 146.488889,134.501587 161.320635,134.501587 L228.571429,134.501587 C243.403175,134.501587 255.390476,146.488889 255.390476,161.320635 C255.390476,176.152381 243.403175,188.139683 228.571429,188.139683 L161.320635,188.139683 Z\" fill=\"#ECB22E\"></path></g></svg></svg>", "color": "#4A154B", "real": true}, "stripe": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" preserveAspectRatio=\"xMidYMid meet\"><path fill=\"#635BFF\" d=\"M13.976 9.15c-2.172-.806-3.356-1.426-3.356-2.409 0-.831.683-1.305 1.901-1.305 2.227 0 4.515.858 6.09 1.631l.89-5.494C18.252.975 15.697 0 12.165 0 9.667 0 7.589.654 6.104 1.872 4.56 3.147 3.757 4.992 3.757 7.218c0 4.039 2.467 5.76 6.476 7.219 2.585.92 3.445 1.574 3.445 2.583 0 .98-.84 1.545-2.354 1.545-1.875 0-4.965-.921-6.99-2.109l-.9 5.555C5.175 22.99 8.385 24 11.714 24c2.641 0 4.843-.624 6.328-1.813 1.664-1.305 2.525-3.236 2.525-5.732 0-4.128-2.524-5.851-6.594-7.305h.003z\"/></svg></svg>", "color": "#635BFF", "real": true}, "calendly": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 841.89 595.28\" preserveAspectRatio=\"xMidYMid meet\"><style type=\"text/css\"> .st0{fill:#3664AE;} .st1{fill:#5FC2D6;} </style><path class=\"st0\" d=\"M505.27,365.28c-14.79,12.86-33.19,28.86-66.71,28.86h-20.01c-24.22,0-46.25-8.62-62.01-24.28 c-15.39-15.3-23.89-36.22-23.89-58.94v-26.87c0-22.72,8.48-43.66,23.89-58.94c15.77-15.66,37.79-24.28,62.01-24.28h20.01 c33.51,0,51.92,16,66.71,28.86c15.34,13.34,28.59,24.86,63.89,24.86c5.48,0,10.86-0.43,16.09-1.26c-0.04-0.11-0.08-0.2-0.12-0.3 c-2.1-5.1-4.57-10.12-7.42-14.96l-23.6-40.1c-21.65-36.8-61.68-59.46-104.98-59.46h-47.21c-43.3,0-83.33,22.67-104.98,59.46 l-23.6,40.1c-21.65,36.8-21.65,82.12,0,118.91l23.6,40.1c21.65,36.8,61.68,59.45,104.98,59.45h47.21 c43.3,0,83.33-22.67,104.98-59.45l23.6-40.1c2.85-4.85,5.32-9.85,7.42-14.95c0.04-0.11,0.08-0.2,0.12-0.3 c-5.23-0.83-10.59-1.26-16.09-1.26C533.87,340.42,520.61,351.94,505.27,365.28z\"/><path class=\"st0\" d=\"M438.57,225.16h-20.01c-36.86,0-61.09,25.83-61.09,58.89v26.87c0,33.06,24.22,58.89,61.09,58.89h20.01 c53.71,0,49.49-53.72,130.59-53.72c7.77,0,15.45,0.7,22.92,2.06c2.46-13.66,2.46-27.64,0-41.31c-7.48,1.36-15.15,2.06-22.92,2.06 C488.06,278.89,492.28,225.16,438.57,225.16z\"/><path class=\"st0\" d=\"M638.66,337.76c-13.85-10.02-29.74-16.56-46.59-19.64c-0.03,0.13-0.04,0.26-0.07,0.39 c-1.44,7.87-3.69,15.62-6.77,23.14c14.22,2.26,27.32,7.5,38.52,15.55c-0.04,0.12-0.07,0.24-0.11,0.37 c-6.46,20.57-16.2,39.96-28.93,57.6c-12.58,17.42-27.79,32.76-45.22,45.57c-36.18,26.62-79.27,40.68-124.63,40.68 c-28.08,0-55.31-5.39-80.94-16.02c-24.75-10.27-46.99-24.98-66.11-43.73c-19.11-18.75-34.1-40.56-44.57-64.85 c-10.83-25.14-16.33-51.85-16.33-79.4c0-27.55,5.5-54.26,16.33-79.4c10.47-24.28,25.46-46.1,44.57-64.85 c19.11-18.75,41.35-33.45,66.11-43.73c25.62-10.63,52.85-16.02,80.94-16.02c45.36,0,88.45,14.06,124.63,40.68 c17.43,12.82,32.63,28.15,45.22,45.57c12.73,17.65,22.47,37.04,28.93,57.6c0.04,0.13,0.08,0.25,0.11,0.37 c-11.19,8.04-24.3,13.3-38.52,15.55c3.08,7.53,5.34,15.3,6.77,23.17c0.03,0.13,0.04,0.25,0.07,0.38 c16.85-3.08,32.73-9.62,46.59-19.64c13.28-9.64,10.71-20.53,8.69-26.99C618.08,136.9,529.55,69.12,424.87,69.12 c-128.55,0-232.75,102.22-232.75,228.32c0,126.1,104.21,228.32,232.75,228.32c104.68,0,193.21-67.79,222.48-161.05 C649.38,358.29,651.96,347.41,638.66,337.76z\"/><path class=\"st1\" d=\"M585.25,253.26c-5.23,0.83-10.59,1.26-16.09,1.26c-35.29,0-48.55-11.52-63.89-24.86 c-14.79-12.86-33.19-28.86-66.71-28.86h-20.01c-24.22,0-46.25,8.62-62.01,24.28c-15.39,15.3-23.89,36.22-23.89,58.94v26.87 c0,22.72,8.48,43.66,23.89,58.94c15.77,15.66,37.79,24.28,62.01,24.28h20.01c33.51,0,51.92-16.01,66.71-28.86 c15.34-13.34,28.59-24.86,63.89-24.86c5.48,0,10.86,0.43,16.09,1.26c3.08-7.52,5.32-15.28,6.77-23.14c0.03-0.13,0.04-0.26,0.07-0.39 c-7.48-1.36-15.15-2.06-22.92-2.06c-81.1,0-76.88,53.72-130.59,53.72h-20.01c-36.86,0-61.09-25.83-61.09-58.89v-26.87 c0-33.06,24.22-58.89,61.09-58.89h20.01c53.71,0,49.5,53.72,130.59,53.72c7.77,0,15.45-0.7,22.92-2.06 c-0.03-0.13-0.04-0.25-0.07-0.38C590.59,268.56,588.33,260.8,585.25,253.26z\"/><path class=\"st1\" d=\"M585.25,253.26c-5.23,0.83-10.59,1.26-16.09,1.26c-35.29,0-48.55-11.52-63.89-24.86 c-14.79-12.86-33.19-28.86-66.71-28.86h-20.01c-24.22,0-46.25,8.62-62.01,24.28c-15.39,15.3-23.89,36.22-23.89,58.94v26.87 c0,22.72,8.48,43.66,23.89,58.94c15.77,15.66,37.79,24.28,62.01,24.28h20.01c33.51,0,51.92-16.01,66.71-28.86 c15.34-13.34,28.59-24.86,63.89-24.86c5.48,0,10.86,0.43,16.09,1.26c3.08-7.52,5.32-15.28,6.77-23.14c0.03-0.13,0.04-0.26,0.07-0.39 c-7.48-1.36-15.15-2.06-22.92-2.06c-81.1,0-76.88,53.72-130.59,53.72h-20.01c-36.86,0-61.09-25.83-61.09-58.89v-26.87 c0-33.06,24.22-58.89,61.09-58.89h20.01c53.71,0,49.5,53.72,130.59,53.72c7.77,0,15.45-0.7,22.92-2.06 c-0.03-0.13-0.04-0.25-0.07-0.38C590.59,268.56,588.33,260.8,585.25,253.26z\"/></svg></svg>", "color": "#006BFF", "real": true}, "figma": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 54 80\" preserveAspectRatio=\"xMidYMid meet\"><g clip-path=\"url(#figma-clip0_912_3)\"><path d=\"M13.3333 80.0002C20.6933 80.0002 26.6667 74.0268 26.6667 66.6668V53.3335H13.3333C5.97333 53.3335 0 59.3068 0 66.6668C0 74.0268 5.97333 80.0002 13.3333 80.0002Z\" fill=\"#0ACF83\"/><path d=\"M0 39.9998C0 32.6398 5.97333 26.6665 13.3333 26.6665H26.6667V53.3332H13.3333C5.97333 53.3332 0 47.3598 0 39.9998Z\" fill=\"#A259FF\"/><path d=\"M0 13.3333C0 5.97333 5.97333 0 13.3333 0H26.6667V26.6667H13.3333C5.97333 26.6667 0 20.6933 0 13.3333Z\" fill=\"#F24E1E\"/><path d=\"M26.6667 0H40.0001C47.3601 0 53.3334 5.97333 53.3334 13.3333C53.3334 20.6933 47.3601 26.6667 40.0001 26.6667H26.6667V0Z\" fill=\"#FF7262\"/><path d=\"M53.3334 39.9998C53.3334 47.3598 47.3601 53.3332 40.0001 53.3332C32.6401 53.3332 26.6667 47.3598 26.6667 39.9998C26.6667 32.6398 32.6401 26.6665 40.0001 26.6665C47.3601 26.6665 53.3334 32.6398 53.3334 39.9998Z\" fill=\"#1ABCFE\"/></g><defs><clipPath id=\"figma-clip0_912_3\"><rect width=\"53.3333\" height=\"80\" fill=\"white\"/></clipPath></defs></svg></svg>", "color": "#F24E1E", "real": true}, "vercel": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 256 222\" preserveAspectRatio=\"xMidYMid meet\"><g><polygon fill=\"#000000\" points=\"127.999778 0 256 221.704527 0 221.704527\"></polygon></g></svg></svg>", "color": "#000000", "real": true}, "supabase": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 256 263\" preserveAspectRatio=\"xMidYMid meet\"><defs><linearGradient x1=\"20.8617445%\" y1=\"20.6868812%\" x2=\"63.4256086%\" y2=\"44.0710077%\" id=\"supabase-supabase-linearGradient-1\"><stop stop-color=\"#249361\" offset=\"0%\"></stop><stop stop-color=\"#3ECF8E\" offset=\"100%\"></stop></linearGradient><linearGradient x1=\"1.99116498%\" y1=\"-13.1584008%\" x2=\"21.4025077%\" y2=\"34.708062%\" id=\"supabase-supabase-linearGradient-2\"><stop stop-color=\"#000000\" offset=\"0%\"></stop><stop stop-color=\"#000000\" stop-opacity=\"0\" offset=\"100%\"></stop></linearGradient></defs><g><path d=\"M149.601512,258.578826 C142.884085,267.038157 129.263882,262.403261 129.102024,251.601817 L126.735244,93.6176533 L232.963622,93.6176533 C252.204429,93.6176533 262.935398,115.840956 250.971119,130.909887 L149.601512,258.578826 Z\" fill=\"url(#supabase-supabase-linearGradient-1)\"></path><path d=\"M149.601512,258.578826 C142.884085,267.038157 129.263882,262.403261 129.102024,251.601817 L126.735244,93.6176533 L232.963622,93.6176533 C252.204429,93.6176533 262.935398,115.840956 250.971119,130.909887 L149.601512,258.578826 Z\" fill-opacity=\"0.2\" fill=\"url(#supabase-supabase-linearGradient-2)\"></path><path d=\"M106.399023,4.36908575 C113.11645,-4.09118439 126.736889,0.544432392 126.898746,11.3460249 L127.935901,169.329953 L23.0369844,169.329953 C3.79559007,169.329953 -6.93568494,147.106651 5.02918175,132.037719 L106.399023,4.36908575 Z\" fill=\"#3ECF8E\"></path></g></svg></svg>", "color": "#3FCF8E", "real": true}, "make": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" preserveAspectRatio=\"xMidYMid meet\"><path fill=\"#6D00CC\" d=\"M13.38 3.498c-.27 0-.511.19-.566.465L9.85 18.986a.578.578 0 0 0 .453.678l4.095.826a.58.58 0 0 0 .682-.455l2.963-15.021a.578.578 0 0 0-.453-.678l-4.096-.826a.589.589 0 0 0-.113-.012zm-5.876.098a.576.576 0 0 0-.516.318L.062 17.697a.575.575 0 0 0 .256.774l3.733 1.877a.578.578 0 0 0 .775-.258l6.926-13.781a.577.577 0 0 0-.256-.776L7.762 3.658a.571.571 0 0 0-.258-.062zm11.74.115a.576.576 0 0 0-.576.576v15.426c0 .318.258.578.576.578h4.178a.58.58 0 0 0 .578-.578V4.287a.578.578 0 0 0-.578-.576Z\"/></svg></svg>", "color": "#6D00CC", "real": true}, "youtube": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 256 180\" preserveAspectRatio=\"xMidYMid meet\"><g><path d=\"M250.346231,28.0746923 C247.358133,17.0320558 238.732098,8.40602109 227.689461,5.41792308 C207.823743,0 127.868333,0 127.868333,0 C127.868333,0 47.9129229,0.164179487 28.0472049,5.58210256 C17.0045684,8.57020058 8.37853373,17.1962353 5.39043571,28.2388718 C-0.618533519,63.5374615 -2.94988224,117.322662 5.5546152,151.209308 C8.54271322,162.251944 17.1687479,170.877979 28.2113844,173.866077 C48.0771024,179.284 128.032513,179.284 128.032513,179.284 C128.032513,179.284 207.987923,179.284 227.853641,173.866077 C238.896277,170.877979 247.522312,162.251944 250.51041,151.209308 C256.847738,115.861464 258.801474,62.1091 250.346231,28.0746923 Z\" fill=\"#FF0000\"></path><polygon fill=\"#FFFFFF\" points=\"102.420513 128.06 168.749025 89.642 102.420513 51.224\"></polygon></g></svg></svg>", "color": "#FF0000", "real": true}, "shopify": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 256 292\" preserveAspectRatio=\"xMidYMid meet\"><g><path d=\"M223.773626,57.3402078 C223.572932,55.8793405 222.29409,55.0718963 221.236945,54.9832175 C220.182133,54.8945386 197.853734,53.2399781 197.853734,53.2399781 C197.853734,53.2399781 182.346604,37.8448639 180.64537,36.1412966 C178.941803,34.4377293 175.616346,34.9558004 174.325836,35.336186 C174.134476,35.3921937 170.937371,36.3793293 165.646977,38.0152206 C160.466266,23.1101737 151.325344,9.41162582 135.241802,9.41162582 C134.798408,9.41162582 134.341011,9.43029505 133.883615,9.45596525 C129.309654,3.40713457 123.643542,0.779440373 118.74987,0.779440373 C81.285392,0.779440373 63.3862673,47.6135387 57.7738299,71.414474 C43.2164974,75.9254268 32.8737437,79.1318671 31.5528956,79.5472575 C23.4271131,82.0956074 23.1704111,82.3523094 22.1039313,90.0090275 C21.2988208,95.8058236 0.0369009009,260.235071 0.0369009009,260.235071 L165.714653,291.277334 L255.485648,271.856667 C255.485648,271.856667 223.971987,58.8010751 223.773626,57.3402078 L223.773626,57.3402078 Z M156.48972,40.8482763 C152.328815,42.1364532 147.598499,43.5996542 142.471461,45.1865388 C142.476129,44.1994032 142.480796,43.2262696 142.480796,42.1644571 C142.480796,32.8998514 141.194953,25.4414939 139.132003,19.5280151 C147.418807,20.5688247 152.937899,29.9967861 156.48972,40.8482763 L156.48972,40.8482763 Z M128.852258,21.3646006 C131.155574,27.1380602 132.65378,35.4225312 132.65378,46.6030666 C132.65378,47.1748118 132.649112,47.6975503 132.644445,48.2272897 C123.52686,51.0510108 113.620499,54.1174319 103.690802,57.1931876 C109.265901,35.6768995 119.716003,25.2851391 128.852258,21.3646006 L128.852258,21.3646006 Z M117.720729,10.8281537 C119.337951,10.8281537 120.966841,11.3765623 122.525722,12.4500431 C110.519073,18.099819 97.6489725,32.3304399 92.2138928,60.7473424 C84.2701352,63.2070135 76.506069,65.6106769 69.3277499,67.834649 C75.6939575,46.1596724 90.8113669,10.8281537 117.720729,10.8281537 L117.720729,10.8281537 Z\" fill=\"#95BF46\"></path><path d=\"M221.236945,54.9832175 C220.182133,54.8945386 197.853734,53.2399781 197.853734,53.2399781 C197.853734,53.2399781 182.346604,37.8448639 180.64537,36.1412966 C180.008283,35.5065427 179.149498,35.1821649 178.251042,35.0421456 L165.723988,291.275001 L255.485648,271.856667 C255.485648,271.856667 223.971987,58.8010751 223.773626,57.3402078 C223.572932,55.8793405 222.29409,55.0718963 221.236945,54.9832175\" fill=\"#5E8E3E\"></path><path d=\"M135.241802,104.585029 L124.173282,137.510551 C124.173282,137.510551 114.474617,132.334507 102.586984,132.334507 C85.1592573,132.334507 84.2818035,143.272342 84.2818035,146.028387 C84.2818035,161.066452 123.48252,166.828244 123.48252,202.052414 C123.48252,229.764553 105.90544,247.610004 82.2048516,247.610004 C53.7646126,247.610004 39.2212821,229.90924 39.2212821,229.90924 L46.8359944,204.750118 C46.8359944,204.750118 61.7853808,217.585214 74.4011133,217.585214 C82.6435785,217.585214 85.9970391,211.095323 85.9970391,206.353338 C85.9970391,186.736644 53.8369559,185.861524 53.8369559,153.629098 C53.8369559,126.500372 73.3089633,100.246767 112.614694,100.246767 C127.760108,100.246767 135.241802,104.585029 135.241802,104.585029\" fill=\"#FFFFFF\"></path></g></svg></svg>", "color": "#7AB55C", "real": true}, "meta": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 256 171\" preserveAspectRatio=\"xMidYMid meet\"><defs><linearGradient id=\"meta-a\" x1=\"13.878%\" x2=\"89.144%\" y1=\"55.934%\" y2=\"58.694%\"><stop offset=\"0%\" stop-color=\"#0064E1\"/><stop offset=\"40%\" stop-color=\"#0064E1\"/><stop offset=\"83%\" stop-color=\"#0073EE\"/><stop offset=\"100%\" stop-color=\"#0082FB\"/></linearGradient><linearGradient id=\"meta-b\" x1=\"54.315%\" x2=\"54.315%\" y1=\"82.782%\" y2=\"39.307%\"><stop offset=\"0%\" stop-color=\"#0082FB\"/><stop offset=\"100%\" stop-color=\"#0064E0\"/></linearGradient></defs><path fill=\"#0081FB\" d=\"M27.651 112.136c0 9.775 2.146 17.28 4.95 21.82 3.677 5.947 9.16 8.466 14.751 8.466 7.211 0 13.808-1.79 26.52-19.372 10.185-14.092 22.186-33.874 30.26-46.275l13.675-21.01c9.499-14.591 20.493-30.811 33.1-41.806C161.196 4.985 172.298 0 183.47 0c18.758 0 36.625 10.87 50.3 31.257C248.735 53.584 256 81.707 256 110.729c0 17.253-3.4 29.93-9.187 39.946-5.591 9.686-16.488 19.363-34.818 19.363v-27.616c15.695 0 19.612-14.422 19.612-30.927 0-23.52-5.484-49.623-17.564-68.273-8.574-13.23-19.684-21.313-31.907-21.313-13.22 0-23.859 9.97-35.815 27.75-6.356 9.445-12.882 20.956-20.208 33.944l-8.066 14.289c-16.203 28.728-20.307 35.271-28.408 46.07-14.2 18.91-26.324 26.076-42.287 26.076-18.935 0-30.91-8.2-38.325-20.556C2.973 139.413 0 126.202 0 111.148l27.651.988Z\"/><path fill=\"url(#meta-a)\" d=\"M21.802 33.206C34.48 13.666 52.774 0 73.757 0 85.91 0 97.99 3.597 110.605 13.897c13.798 11.261 28.505 29.805 46.853 60.368l6.58 10.967c15.881 26.459 24.917 40.07 30.205 46.49 6.802 8.243 11.565 10.7 17.752 10.7 15.695 0 19.612-14.422 19.612-30.927l24.393-.766c0 17.253-3.4 29.93-9.187 39.946-5.591 9.686-16.488 19.363-34.818 19.363-11.395 0-21.49-2.475-32.654-13.007-8.582-8.083-18.615-22.443-26.334-35.352l-22.96-38.352C118.528 64.08 107.96 49.73 101.845 43.23c-6.578-6.988-15.036-15.428-28.532-15.428-10.923 0-20.2 7.666-27.963 19.39L21.802 33.206Z\"/><path fill=\"url(#meta-b)\" d=\"M73.312 27.802c-10.923 0-20.2 7.666-27.963 19.39-10.976 16.568-17.698 41.245-17.698 64.944 0 9.775 2.146 17.28 4.95 21.82L9.027 149.482C2.973 139.413 0 126.202 0 111.148 0 83.772 7.514 55.24 21.802 33.206 34.48 13.666 52.774 0 73.757 0l-.445 27.802Z\"/></svg></svg>", "color": "#0467DF", "real": true}, "attio": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 103 26\" preserveAspectRatio=\"xMidYMid meet\"><path d=\"M84.2267 1.03809H79.9922V5.27257H84.2267V1.03809Z\" fill=\"#000000\"></path><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M67.7423 11.9094H64.0236V18.7905C64.0236 19.364 64.1661 19.7836 64.4529 20.0473C64.7396 20.3129 65.1592 20.4669 65.7097 20.5112C66.2602 20.5324 66.9454 20.5227 67.7615 20.4785V24.3492C64.8725 24.6802 62.811 24.4146 61.5753 23.5562C60.3627 22.6746 59.7564 21.0867 59.7564 18.7924V11.9113H56.8789V7.80774H59.7564V4.46635L64.0236 3.17676V7.80967H70.6198V4.46828L74.887 3.17868V7.81159H78.6249V11.9152H74.887V18.7962C74.887 19.3698 75.0294 19.7894 75.3162 20.0531C75.603 20.3187 76.0226 20.4727 76.5731 20.517C77.1236 20.5381 77.8088 20.5285 78.623 20.4842V24.3549C75.7339 24.686 73.6725 24.4204 72.4368 23.5619C71.2242 22.6804 70.6179 21.0925 70.6179 18.7981V11.9171H67.7404L67.7423 11.9094Z\" fill=\"#000000\"></path><path d=\"M84.2477 7.80371H79.9805V24.3471H84.2477V7.80371Z\" fill=\"#000000\"></path><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M94.3015 7.375C89.4973 7.375 85.6016 11.2707 85.6016 16.0769C85.6016 20.883 89.4973 24.7787 94.3015 24.7787C99.1057 24.7787 103.001 20.883 103.001 16.0769C103.001 11.2707 99.1076 7.375 94.3015 7.375V7.375ZM94.2861 20.6771C91.7377 20.6771 89.6705 18.6099 89.6705 16.0615C89.6705 13.5131 91.7377 11.4459 94.2861 11.4459C96.8345 11.4459 98.8998 13.5111 98.8998 16.0615C98.8998 18.6118 96.8345 20.6771 94.2861 20.6771V20.6771Z\" fill=\"#000000\"></path><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M51.2865 7.7715V8.68961C49.9526 7.85812 48.3782 7.375 46.6902 7.375C41.886 7.375 37.9902 11.2707 37.9902 16.0769C37.9902 20.883 41.886 24.7787 46.6902 24.7787C48.3782 24.7787 49.9526 24.2975 51.2865 23.4641V24.3822H55.521V7.7715H51.2865ZM46.6748 20.6771C44.1264 20.6771 42.0592 18.6099 42.0592 16.0615C42.0592 13.5131 44.1264 11.4459 46.6748 11.4459C49.2232 11.4459 51.2461 13.4707 51.2865 15.9845V16.1365C51.2461 18.6503 49.1981 20.6751 46.6748 20.6751V20.6771Z\" fill=\"#000000\"></path><path d=\"M30.6468 17.7823L28.0599 13.6422C28.0599 13.6422 28.0503 13.6248 28.0445 13.6172L27.8405 13.2919C27.4555 12.674 26.7895 12.3045 26.062 12.3025L21.8949 12.2891L21.6042 12.7549L16.6249 20.7234L16.3496 21.1642L18.4361 24.4978C18.821 25.1176 19.487 25.4872 20.2203 25.4872H26.06C26.7799 25.4872 27.4613 25.108 27.8424 24.4998L28.0483 24.1706C28.0483 24.1706 28.056 24.161 28.058 24.1572L30.6487 20.0112C31.0741 19.3337 31.0741 18.4579 30.6487 17.7823H30.6468ZM29.8576 19.5166L27.2669 23.6625C27.2553 23.6817 27.2419 23.6971 27.2303 23.7125C27.1398 23.8146 27.0224 23.828 26.9705 23.828C26.9108 23.828 26.7645 23.8107 26.6702 23.6606L24.0795 19.5146C24.0506 19.4684 24.0256 19.4203 24.0025 19.3683C23.9794 19.3183 23.9621 19.2683 23.9467 19.2163C23.8889 19.0084 23.8889 18.7851 23.9467 18.5773C23.9755 18.4753 24.0198 18.3732 24.0775 18.2809L26.6644 14.1388C26.6644 14.1388 26.6683 14.133 26.6702 14.1291C26.7318 14.0367 26.8088 13.9944 26.8762 13.9809C26.9031 13.9732 26.9262 13.9713 26.9454 13.9675C26.9551 13.9675 26.9647 13.9675 26.9743 13.9675C27.034 13.9675 27.1822 13.9867 27.2746 14.1368L29.8615 18.277C30.0982 18.6543 30.0982 19.1393 29.8615 19.5166H29.8576Z\" fill=\"#000000\"></path><path d=\"M22.9913 7.7644C23.4148 7.08496 23.4148 6.21112 22.9913 5.53553L20.4044 1.39536L20.1889 1.04697C19.802 0.429125 19.136 0.0595703 18.4046 0.0595703H12.5649C11.8354 0.0595703 11.1694 0.429125 10.7806 1.0489L0.323361 17.7847C0.113561 18.1196 0 18.5065 0 18.8992C0 19.2918 0.111636 19.6787 0.321436 20.0117L3.12582 24.5022C3.5127 25.1219 4.17866 25.4896 4.90815 25.4896H10.7479C11.4812 25.4896 12.1472 25.12 12.5321 24.5002L12.7458 24.1615C12.7458 24.1615 12.7458 24.1615 12.7458 24.1576C12.7458 24.1576 12.7496 24.1519 12.7496 24.1499L14.8342 20.8162L21.0127 10.9287L22.9875 7.76633L22.9913 7.7644ZM22.3812 6.64996C22.3812 6.86361 22.3215 7.07919 22.2002 7.26974L11.9566 23.6649C11.8643 23.8131 11.716 23.8304 11.6564 23.8304C11.5967 23.8304 11.4504 23.8131 11.3561 23.6649L8.7673 19.517C8.53248 19.1417 8.53248 18.6586 8.7673 18.2794L19.0109 1.8881C19.1033 1.73797 19.2515 1.72064 19.3112 1.72064C19.3708 1.72064 19.519 1.73797 19.6134 1.89002L22.2002 6.03019C22.3215 6.22074 22.3812 6.43632 22.3812 6.64996V6.64996Z\" fill=\"#000000\"></path></svg></svg>", "color": "#000000", "real": true}, "fireflies": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 1 22 22\" preserveAspectRatio=\"xMidYMid meet\"><path fill=\"url(#logo-with-text_svg__a)\" d=\"M7.36 2H.787v6.527H7.36z\"></path><path fill=\"url(#logo-with-text_svg__b)\" d=\"M15.149 9.88H8.574v6.526h6.575z\"></path><path fill=\"url(#logo-with-text_svg__c)\" d=\"M15.149 2H8.574v6.527h12.212v-.933a5.57 5.57 0 0 0-1.651-3.956A5.66 5.66 0 0 0 15.15 2z\"></path><path fill=\"url(#logo-with-text_svg__d)\" d=\"M.786 9.88v6.526c0 1.484.594 2.907 1.65 3.956A5.66 5.66 0 0 0 6.423 22h.939V9.88z\"></path><path fill=\"url(#logo-with-text_svg__e)\" d=\"M.786 2 7.36 8.527H.786z\" opacity=\"0.18\"></path><path fill=\"url(#logo-with-text_svg__f)\" d=\"m8.574 9.88 6.575 6.526H8.574z\" opacity=\"0.18\"></path><path fill=\"url(#logo-with-text_svg__g)\" d=\"M.786 16.406c0 1.484.594 2.907 1.65 3.956A5.66 5.66 0 0 0 6.423 22h.939V9.88z\" opacity=\"0.18\"></path><path fill=\"url(#logo-with-text_svg__h)\" d=\"M15.15 2c1.494 0 2.928.59 3.985 1.638a5.57 5.57 0 0 1 1.65 3.956v.933H8.576z\" opacity=\"0.18\"></path><defs><linearGradient id=\"logo-with-text_svg__a\" x1=\"16.868\" x2=\"-10.77\" y1=\"18.512\" y2=\"-10.526\" gradientUnits=\"userSpaceOnUse\"><stop stop-color=\"#E82A73\"></stop><stop offset=\"0.113\" stop-color=\"#DE2D7A\"></stop><stop offset=\"0.3\" stop-color=\"#C5388F\"></stop><stop offset=\"0.54\" stop-color=\"#9B4AB0\"></stop><stop offset=\"0.818\" stop-color=\"#6262DE\"></stop><stop offset=\"0.994\" stop-color=\"#3B73FF\"></stop></linearGradient><linearGradient id=\"logo-with-text_svg__b\" x1=\"16.964\" x2=\"-10.674\" y1=\"18.423\" y2=\"-10.616\" gradientUnits=\"userSpaceOnUse\"><stop stop-color=\"#FF3C82\"></stop><stop offset=\"0.103\" stop-color=\"#F53E88\"></stop><stop offset=\"0.274\" stop-color=\"#DC4598\"></stop><stop offset=\"0.492\" stop-color=\"#B251B2\"></stop><stop offset=\"0.745\" stop-color=\"#7961D7\"></stop><stop offset=\"0.994\" stop-color=\"#3B73FF\"></stop></linearGradient><linearGradient id=\"logo-with-text_svg__c\" x1=\"21.555\" x2=\"12.19\" y1=\"14.055\" y2=\"-19.882\" gradientUnits=\"userSpaceOnUse\"><stop stop-color=\"#E82A73\"></stop><stop offset=\"0.113\" stop-color=\"#DE2D7A\"></stop><stop offset=\"0.3\" stop-color=\"#C5388F\"></stop><stop offset=\"0.54\" stop-color=\"#9B4AB0\"></stop><stop offset=\"0.818\" stop-color=\"#6262DE\"></stop><stop offset=\"0.994\" stop-color=\"#3B73FF\"></stop></linearGradient><linearGradient id=\"logo-with-text_svg__d\" x1=\"12.338\" x2=\"-21.187\" y1=\"22.824\" y2=\"12.611\" gradientUnits=\"userSpaceOnUse\"><stop stop-color=\"#E82A73\"></stop><stop offset=\"0.113\" stop-color=\"#DE2D7A\"></stop><stop offset=\"0.3\" stop-color=\"#C5388F\"></stop><stop offset=\"0.54\" stop-color=\"#9B4AB0\"></stop><stop offset=\"0.818\" stop-color=\"#6262DE\"></stop><stop offset=\"0.994\" stop-color=\"#3B73FF\"></stop></linearGradient><linearGradient id=\"logo-with-text_svg__e\" x1=\"-2.429\" x2=\"6.961\" y1=\"-6.152\" y2=\"15.365\" gradientUnits=\"userSpaceOnUse\"><stop stop-color=\"#E82A73\"></stop><stop offset=\"0.114\" stop-color=\"#DE286E\"></stop><stop offset=\"0.303\" stop-color=\"#C52361\"></stop><stop offset=\"0.544\" stop-color=\"#9B1A4D\"></stop><stop offset=\"0.825\" stop-color=\"#620F30\"></stop><stop offset=\"0.994\" stop-color=\"#3D081E\"></stop></linearGradient><linearGradient id=\"logo-with-text_svg__f\" x1=\"5.359\" x2=\"14.749\" y1=\"1.727\" y2=\"23.245\" gradientUnits=\"userSpaceOnUse\"><stop stop-color=\"#E82A73\"></stop><stop offset=\"0.114\" stop-color=\"#DE286E\"></stop><stop offset=\"0.303\" stop-color=\"#C52361\"></stop><stop offset=\"0.544\" stop-color=\"#9B1A4D\"></stop><stop offset=\"0.825\" stop-color=\"#620F30\"></stop><stop offset=\"0.994\" stop-color=\"#3D081E\"></stop></linearGradient><linearGradient id=\"logo-with-text_svg__g\" x1=\"-1.397\" x2=\"19.87\" y1=\"1.383\" y2=\"15.511\" gradientUnits=\"userSpaceOnUse\"><stop stop-color=\"#E82A73\"></stop><stop offset=\"0.114\" stop-color=\"#DE286E\"></stop><stop offset=\"0.303\" stop-color=\"#C52361\"></stop><stop offset=\"0.544\" stop-color=\"#9B1A4D\"></stop><stop offset=\"0.825\" stop-color=\"#620F30\"></stop><stop offset=\"0.994\" stop-color=\"#3D081E\"></stop></linearGradient><linearGradient id=\"logo-with-text_svg__h\" x1=\"-464.769\" x2=\"-461.125\" y1=\"461.172\" y2=\"489.944\" gradientUnits=\"userSpaceOnUse\"><stop stop-color=\"#E82A73\"></stop><stop offset=\"0.114\" stop-color=\"#DE286E\"></stop><stop offset=\"0.303\" stop-color=\"#C52361\"></stop><stop offset=\"0.544\" stop-color=\"#9B1A4D\"></stop><stop offset=\"0.825\" stop-color=\"#620F30\"></stop><stop offset=\"0.994\" stop-color=\"#3D081E\"></stop></linearGradient><clipPath id=\"logo-with-text_svg__i\"><path fill=\"#fff\" d=\"M28.786 0h69.429v24h-69.43z\"></path></clipPath></defs></svg></svg>", "color": "#6262DE", "real": true}, "kit": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 400 181\" preserveAspectRatio=\"xMidYMid meet\"><path d=\"M109.562 75.1422c49.21 9.535 64.488 55.0968 64.903 100.9298 0 1.03-.831 1.878-1.86 1.878h-61.959c-1.03 0-1.86-.83-1.86-1.842-.181-35.557-5.942-66.925-41.1743-68.28-1.0474-.036-1.9322.795-1.9322 1.86v66.42c0 1.03-.8307 1.86-1.8601 1.86H1.86a1.857 1.857 0 0 1-1.86-1.86V6.8262c0-1.0294.8307-1.86 1.86-1.86h61.9775c1.0293 0 1.86.8306 1.86 1.86v63.4041c0 .939.7585 1.6975 1.6975 1.6975.7404 0 1.4086-.4876 1.6253-1.1919C84.9661 18.4379 114.781 5.2912 163.196 4.9842c1.03 0 1.86.8307 1.86 1.86v63.2416c0 1.0293-.83 1.86-1.86 1.86h-53.327c-.903 0-1.625.7224-1.625 1.6253 0 .7585.56 1.4266 1.318 1.5711Zm169.661 39.6388V73.7878c0-1.0293.831-1.86 1.861-1.86h45.598c.903 0 1.625-.7224 1.625-1.6253 0-.7765-.56-1.4447-1.318-1.5892-35.684-7.079-52.154-27.6117-52.714-61.8871-.018-1.0113.795-1.86 1.824-1.86h66.962c1.029 0 1.86.8306 1.86 1.86V35.702c0 1.0294.831 1.8601 1.86 1.8601h38.393c1.029 0 1.86.8307 1.86 1.86v30.6817c0 1.0294-.831 1.8601-1.86 1.8601h-38.393c-1.029 0-1.86.8307-1.86 1.86v33.0651c0 11.684 7.169 15.531 16.686 15.531 14.917 0 29.653-6.718 35.558-9.77 1.228-.632 2.709.253 2.709 1.643v51.468c0 1.372-.759 2.636-1.969 3.286-5.833 3.07-23.855 11.576-44.46 11.576-42.456-.036-74.222-17.318-74.222-65.842Zm-87.169 61.309V73.7878c0-1.0293.831-1.86 1.86-1.86h61.978c1.029 0 1.86.8307 1.86 1.86V176.09c0 1.03-.831 1.86-1.86 1.86h-61.978c-1.029-.018-1.86-.848-1.86-1.86Zm-3.521-144.5595c0 17.4086 12.298 31.5305 35.918 31.5305 23.621 0 35.919-14.1219 35.919-31.5305S248.09 0 224.451 0c-23.62 0-35.918 14.1219-35.918 31.5305Z\" fill=\"#1e1e1e\"/></svg></svg>", "color": "#1E1E1E", "real": true}, "circle": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 200 58\" preserveAspectRatio=\"xMidYMid meet\"><path d=\"M26.5583 57.3672C22.8697 57.3672 19.4023 56.6783 16.1563 55.3006C12.9103 53.8737 10.0823 51.9056 7.6724 49.3962C5.26248 46.8376 3.36897 43.8854 1.99187 40.5395C0.663958 37.1937 0 33.5772 0 29.6901C0 25.803 0.663958 22.2111 1.99187 18.9145C3.36897 15.5686 5.26248 12.641 7.6724 10.1316C10.0823 7.62225 12.9103 5.67871 16.1563 4.301C19.4023 2.8741 22.8697 2.16064 26.5583 2.16064C31.2306 2.16064 35.4603 3.12012 39.2473 5.03906C43.0835 6.958 46.2311 9.6396 48.6902 13.0839C51.1493 16.5281 52.674 20.5136 53.2642 25.0404H41.3867C40.9933 22.4818 40.0834 20.243 38.6571 18.3241C37.28 16.4051 35.5586 14.9044 33.493 13.8219C31.4765 12.7394 29.2141 12.1982 26.7059 12.1982C24.3943 12.1982 22.3041 12.6164 20.4351 13.4529C18.6154 14.2894 17.017 15.4948 15.6399 17.0694C14.312 18.6439 13.2792 20.5136 12.5414 22.6786C11.8529 24.7943 11.5086 27.1315 11.5086 29.6901C11.5086 32.2979 11.8529 34.6843 12.5414 36.8492C13.2792 38.965 14.312 40.8101 15.6399 42.3847C17.017 43.9592 18.6154 45.1893 20.4351 46.0749C22.3041 46.9114 24.3943 47.3296 26.7059 47.3296C29.2141 47.3296 31.5011 46.7884 33.5668 45.7059C35.6324 44.5742 37.3292 43.0489 38.6571 41.13C40.0342 39.1618 40.9441 36.923 41.3867 34.4137H53.2642C52.6248 38.9896 51.0756 42.9997 48.6165 46.444C46.1574 49.8882 43.0343 52.5698 39.2473 54.4888C35.4603 56.4077 31.2306 57.3672 26.5583 57.3672Z\" fill=\"#191B1F\"/><path d=\"M68.9876 56.2601H58.7332V16.8479H68.9876V56.2601Z\" fill=\"#191B1F\"/><path d=\"M86.892 37.1445V56.2601H76.6376V16.8479H86.0805V24.4499C87.556 21.9405 89.6954 19.9724 92.4988 18.5455C95.3022 17.1186 98.2777 16.4051 101.425 16.4051V27.0331C98.5728 26.8363 96.0399 26.9839 93.8267 27.4759C91.6627 27.9188 89.9659 28.9274 88.7364 30.502C87.5068 32.0273 86.892 34.2414 86.892 37.1445Z\" fill=\"#191B1F\"/><path d=\"M121.587 56.9981C117.8 56.9981 114.456 56.1371 111.554 54.415C108.702 52.6928 106.464 50.2818 104.841 47.182C103.218 44.0822 102.406 40.5395 102.406 36.554C102.406 32.6177 103.218 29.1243 104.841 26.0736C106.513 22.9738 108.8 20.5382 111.702 18.7669C114.603 16.9956 117.899 16.1099 121.587 16.1099C124.981 16.1099 128.055 16.8479 130.809 18.3241C133.563 19.751 135.801 21.7929 137.522 24.4499C139.244 27.0577 140.301 30.1329 140.695 33.6756H129.924C129.678 31.0678 128.792 29.0013 127.268 27.4759C125.792 25.9506 123.899 25.188 121.587 25.188C119.817 25.188 118.267 25.6554 116.94 26.5903C115.661 27.5251 114.653 28.829 113.915 30.502C113.226 32.1749 112.882 34.1922 112.882 36.554C112.882 38.8666 113.226 40.8839 113.915 42.6061C114.653 44.3282 115.661 45.6567 116.94 46.5916C118.267 47.4772 119.817 47.9201 121.587 47.9201C123.948 47.9201 125.842 47.182 127.268 45.7059C128.743 44.1806 129.629 42.0894 129.924 39.4324H140.695C140.35 43.0243 139.317 46.1487 137.596 48.8057C135.875 51.4135 133.661 53.4309 130.956 54.8578C128.251 56.2847 125.128 56.9981 121.587 56.9981Z\" fill=\"#191B1F\"/><path d=\"M156.131 56.2601H145.803V3.26773L156.131 3.26773V56.2601Z\" fill=\"#191B1F\"/><path d=\"M180.967 56.9243C177.032 56.9243 173.565 56.0879 170.565 54.415C167.614 52.6928 165.327 50.2818 163.704 47.182C162.081 44.0822 161.269 40.4903 161.269 36.4064C161.269 32.4701 162.105 28.9767 163.777 25.926C165.45 22.8754 167.761 20.489 170.712 18.7669C173.663 16.9956 177.032 16.1099 180.819 16.1099C183.917 16.1099 186.721 16.7003 189.229 17.8812C191.787 19.0129 193.926 20.6366 195.647 22.7524C197.369 24.8681 198.598 27.3283 199.336 30.1329C200.074 32.8883 200.197 35.8652 199.705 39.0634H167.319V32.5685H188.86C188.762 29.8131 187.95 27.6482 186.426 26.0736C184.95 24.4499 183.008 23.6381 180.598 23.6381C178.68 23.6381 177.057 24.1301 175.729 25.1142C174.401 26.0982 173.368 27.5497 172.63 29.4687C171.942 31.3384 171.597 33.651 171.597 36.4064C171.597 39.1126 171.942 41.4006 172.63 43.2703C173.319 45.1401 174.352 46.567 175.729 47.551C177.106 48.5351 178.778 49.0272 180.745 49.0272C183.008 49.0272 184.877 48.4859 186.352 47.4034C187.827 46.3209 188.86 44.8202 189.45 42.9013H199.631C198.5 47.3296 196.311 50.7739 193.065 53.2341C189.819 55.6943 185.786 56.9243 180.967 56.9243Z\" fill=\"#191B1F\"/><path d=\"M70.5386 7.01152C70.5386 9.02888 69.8992 10.7018 68.6205 12.0303C67.3418 13.3096 65.6942 13.9492 63.6777 13.9492C61.6613 13.9492 59.9891 13.3096 58.6611 12.0303C57.3824 10.7018 56.743 9.02888 56.743 7.01152C56.743 4.94497 57.3824 3.27205 58.6611 1.99275C59.9891 0.664252 61.6613 0 63.6777 0C65.6942 0 67.3418 0.664252 68.6205 1.99275C69.8992 3.27205 70.5386 4.94497 70.5386 7.01152Z\" fill=\"#506CF0\"/></svg></svg>", "color": "#506CF0", "real": true}, "vidiq": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 16 16\" preserveAspectRatio=\"xMidYMid meet\"><g clip-path=\"url(#a)\"><path fill=\"#2574F5\" d=\"M0 0h16v16H0z\"/><path fill=\"#0A0D15\" d=\"m3 3 12 5-12 5V3Z\"/><g filter=\"url(#b)\"><path fill=\"#F7F7F7\" fill-rule=\"evenodd\" d=\"m11.506 9.708 1.122 1.094-.857.873-1.158-1.129c-.43.205-.989.31-1.706.31-2.01 0-2.939-.882-2.939-2.901 0-1.96 1.009-2.9 2.94-2.9 1.854 0 2.942.94 2.944 2.9 0 .711-.101 1.299-.346 1.753ZM8.907 6.555c-.857 0-1.396.507-1.396 1.4 0 .892.533 1.411 1.396 1.4.845-.009 1.388-.437 1.396-1.4.009-.895-.538-1.4-1.396-1.4ZM5.59 5.107H3.965v5.644H5.59V5.107Z\" clip-rule=\"evenodd\"/></g></g><defs><clipPath id=\"a\"><path fill=\"#fff\" d=\"M0 0h16v16H0z\"/></clipPath><filter id=\"b\" width=\"19.927\" height=\"27.442\" x=\"-1.667\" y=\"3.945\" color-interpolation-filters=\"sRGB\" filterUnits=\"userSpaceOnUse\"><feFlood flood-opacity=\"0\" result=\"BackgroundImageFix\"/><feColorMatrix in=\"SourceAlpha\" result=\"hardAlpha\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\"/><feOffset dy=\".853\"/><feGaussianBlur stdDeviation=\".981\"/><feColorMatrix values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0\"/><feBlend in2=\"BackgroundImageFix\" result=\"effect1_dropShadow_9_207\"/><feColorMatrix in=\"SourceAlpha\" result=\"hardAlpha\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\"/><feOffset dy=\"3.499\"/><feGaussianBlur stdDeviation=\"1.749\"/><feColorMatrix values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.09 0\"/><feBlend in2=\"effect1_dropShadow_9_207\" result=\"effect2_dropShadow_9_207\"/><feColorMatrix in=\"SourceAlpha\" result=\"hardAlpha\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\"/><feOffset dy=\"7.936\"/><feGaussianBlur stdDeviation=\"2.389\"/><feColorMatrix values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.05 0\"/><feBlend in2=\"effect2_dropShadow_9_207\" result=\"effect3_dropShadow_9_207\"/><feColorMatrix in=\"SourceAlpha\" result=\"hardAlpha\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\"/><feOffset dy=\"14.08\"/><feGaussianBlur stdDeviation=\"2.816\"/><feColorMatrix values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.01 0\"/><feBlend in2=\"effect3_dropShadow_9_207\" result=\"effect4_dropShadow_9_207\"/><feBlend in=\"SourceGraphic\" in2=\"effect4_dropShadow_9_207\" result=\"shape\"/></filter></defs></svg></svg>", "color": "#2574F5", "real": true}, "posthog": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 300 300\" preserveAspectRatio=\"xMidYMid meet\"><rect width=\"300\" height=\"300\" fill=\"#000\"/><path fill=\"#fff\" d=\"M33 179.379L72.0038 218.33H33V179.379ZM33 169.641L81.7548 218.33H120.759L33 130.689V169.641ZM33 120.951L130.51 218.33H169.513L33 82V120.951ZM81.7548 120.951L179.264 218.33V179.379L81.7548 82V120.951ZM130.51 82V120.951L179.264 169.641V130.689L130.51 82Z\"/><path fill=\"#fff\" d=\"M266.863 203.174C256.87 203.174 247.291 199.208 240.231 192.158L186 138V218.754H266.863V203.174Z\"/><path fill=\"#000\" d=\"M209.563 202.75C213.871 202.75 217.363 199.262 217.363 194.959C217.363 190.657 213.871 187.169 209.563 187.169C205.254 187.169 201.762 190.657 201.762 194.959C201.762 199.262 205.254 202.75 209.563 202.75Z\"/><path fill=\"#fff\" d=\"M33 218.33H72.0038L33 179.379V218.33Z\"/><path fill=\"#fff\" d=\"M81.7548 130.689L33 82V120.951L81.7548 169.641V130.689Z\"/><path fill=\"#fff\" d=\"M33 130.689V169.641L81.7548 218.33V179.379L33 130.689Z\"/><path fill=\"#fff\" d=\"M130.51 130.689L81.7548 82V120.951L130.51 169.641V130.689Z\"/><path fill=\"#fff\" d=\"M81.7548 218.33H120.759L81.7548 179.379V218.33Z\"/><path fill=\"#fff\" d=\"M81.7548 130.689V169.641L130.51 218.33V179.379L81.7548 130.689Z\"/></svg></svg>", "color": "#000000", "real": true}, "apify": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 1080 1080\" preserveAspectRatio=\"xMidYMid meet\"><path d=\"M607.859 78.2218H987.785C995.513 78.2218 1001.78 84.4868 1001.78 92.2151V672.834C1001.78 686.742 983.69 692.134 976.075 680.496L596.15 99.877C590.06 90.5703 596.737 78.2218 607.859 78.2218Z\" fill=\"#246DFF\"/><path d=\"M472.141 78.2218H92.215C84.4867 78.2218 78.2217 84.4868 78.2217 92.2151V672.834C78.2217 686.742 96.3094 692.134 103.924 680.496L483.85 99.877C489.94 90.5703 483.263 78.2218 472.141 78.2218Z\" fill=\"#20A34E\"/><path d=\"M533.491 543.086L101.895 977.927C93.1302 986.758 99.3849 1001.78 111.826 1001.78H968.529C980.919 1001.78 987.197 986.863 978.535 978.003L553.429 543.161C547.969 537.576 538.993 537.542 533.491 543.086Z\" fill=\"#F86606\"/></svg></svg>", "color": "#246DFF", "real": true}, "higgsfield": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 20 20\" preserveAspectRatio=\"xMidYMid meet\"><path d=\"M18.3498 9.83713L18.3339 9.65759C18.1831 7.93447 17.0963 4.69261 14.0816 4.69261C11.8445 4.69261 10.1545 6.97097 8.66311 8.97967C7.47302 10.5883 6.4419 11.9683 5.3073 11.9683C5.00574 11.9357 4.61708 11.7805 4.3792 11.4294C4.16497 11.1108 4.10948 10.7026 4.22046 10.2126C4.39489 9.43684 5.39463 8.7182 6.44963 7.95063C7.02864 7.54238 7.6238 7.10955 8.03634 6.69311C9.22643 5.5091 9.82932 4.65164 9.82932 3.2717C9.82932 1.89176 9.09157 1.20565 8.47276 0.911636C7.23514 0.323844 5.41851 0.666781 4.26026 1.69583C4.08583 1.85922 3.91117 2.01418 3.75243 2.16119C2.58622 3.23097 1.80094 3.95781 0 3.40232V5.63972C2.38791 6.72588 4.39512 4.65164 5.15675 3.69633C5.74372 3.06758 6.36253 2.70006 6.82283 2.70006H6.84671C7.05298 2.70825 7.22741 2.78995 7.35454 2.93696C7.56081 3.18204 7.64018 3.46786 7.60038 3.78622C7.51305 4.45594 6.83875 5.23967 5.60113 6.09713C4.14928 7.10159 1.7218 8.78374 1.53122 10.8987C1.3884 12.4177 2.15003 13.9365 3.34012 14.5243C6.11669 15.8798 7.80665 13.5444 9.5994 11.0783C10.9719 9.1756 12.273 7.37103 14.0818 7.37103C15.7081 7.37103 16.311 8.75916 16.311 9.63301V9.80459L16.1523 9.83713C12.2095 10.5558 10.0595 14.3611 10.0595 16.1167C10.0595 17.8724 11.5034 19.375 13.2804 19.375C15.359 19.375 17.9293 17.5458 18.3419 12.4013L18.3578 12.2136H20V9.83737H18.3498V9.83713ZM16.1998 12.4746C15.8826 15.5531 14.3513 16.9904 13.4232 16.9904C13.0027 16.9904 12.4158 16.631 12.4158 15.9615C12.4158 15.2104 13.5026 12.932 15.946 12.2543L16.2316 12.1808L16.1998 12.4748V12.4746Z\" fill=\"#030304\"></path></svg></svg>", "color": "#030304", "real": true}, "anymailfinder": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 38 38\" preserveAspectRatio=\"xMidYMid meet\"><g fill=\"#0073e6\"><path clip-rule=\"evenodd\" d=\"M0.914602 12.1473C0.914602 12.1473 13.8811 21.2685 19.0491 22.5118C16.5611 25.4521 9.66107 31.2255 9.75306 31.167C17.1059 26.8151 32.5413 13.7506 32.5413 13.7506C33.02 13.4454 33.5147 13.6719 33.6455 14.2523L37.3308 30.6191C37.4615 31.1995 37.0496 31.7654 36.4095 31.8833L6.78525 37.3397C6.1457 37.4575 5.47651 36.8836 5.29052 36.0576L0.0463848 12.7683C-0.13958 11.9425 0.250498 11.6686 0.914602 12.1473ZM2.52542 9.77466C2.52542 9.77466 19.3996 -0.381419 21.4381 0.011091C23.428 0.394256 31.1593 11.1758 31.5264 11.689L31.5399 11.7079C31.8475 12.0512 31.6451 12.3014 31.0874 12.2682L2.42364 10.571C1.86514 10.5381 1.91192 10.1802 2.52542 9.77466Z\" fill-rule=\"evenodd\"></path></g></svg></svg>", "color": "#0073E6", "real": true}, "composio": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 64 64\" preserveAspectRatio=\"xMidYMid meet\"><g clip-path=\"url(#clip0_2129_471)\"><g clip-path=\"url(#clip1_2129_471)\"><path\n\t\t\t\td=\"M58.5409 18.0442L22.4819 10.6695C20.1176 10.1841 17.8943 12.0003 17.8943 14.4116V31.4939V32.402V49.4842C17.8943 51.8955 20.1176 53.712 22.4819 53.2265L58.5409 45.8518\"\n\t\t\t\tstroke=\"black\"\n\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\tstroke-miterlimit=\"10\"\n\t\t\t\tstroke-width=\"1.82758\"\n\t\t\t/><path\n\t\t\t\td=\"M30.6983 4.73539C30.6984 1.34782 34.161 -0.917709 37.2617 0.379183L37.4093 0.443562L37.4126 0.445442L56.7025 9.35428C58.3954 10.1174 59.4565 11.8082 59.4569 13.6442V21.1912C59.4569 23.9444 57.112 26.1189 54.3726 25.9069L32.5258 24.2763V39.6193L54.3692 37.9887L54.6252 37.9755C57.2487 37.9116 59.456 40.0302 59.4406 42.6889V50.2358C59.4406 52.086 58.3516 53.7519 56.6895 54.5248L56.6867 54.5257L37.413 63.4183L37.4135 63.4188C34.2705 64.8735 30.6983 62.5825 30.6983 59.1294V51.9373C30.5567 51.9931 30.405 52.0302 30.2458 52.0417L19.585 52.8093C18.6942 52.8733 17.9362 52.1673 17.9361 51.2742V43.3595C17.9361 43.0526 18.0277 42.7648 18.1851 42.5225L9.41491 43.1776H9.41164C6.67967 43.3713 4.33082 41.2037 4.33081 38.4614V25.4342C4.33101 22.6801 6.67776 20.5047 9.41823 20.7185H9.41775L17.9939 21.3585C17.9567 21.2261 17.9361 21.0869 17.9361 20.9431V12.6057C17.9361 11.3884 19.025 10.4599 20.227 10.6522L30.3783 12.2763C30.4899 12.2941 30.5967 12.3247 30.6983 12.3646V4.73539ZM54.5116 39.8111H54.5083L32.5258 41.452V50.9913L57.6135 45.7476V42.6823L57.6106 42.5272C57.5355 40.9328 56.1381 39.6842 54.5116 39.8111ZM17.5836 23.1607C17.7369 23.4005 17.8261 23.6847 17.8261 23.9882V40.1889C17.8261 40.3767 17.7909 40.5566 17.7289 40.7236L30.6983 39.7556V24.1395L17.5836 23.1607ZM32.5258 22.4436L54.5083 24.0845L54.5116 24.085L54.6675 24.093C56.2752 24.1322 57.6293 22.8309 57.6293 21.1912V18.0187L32.5258 12.7711V22.4436Z\"\n\t\t\t\tfill=\"black\"\n\t\t\t/></g></g><defs><clipPath id=\"clip0_2129_471\"><rect fill=\"white\" height=\"64\" width=\"64\" /></clipPath><clipPath id=\"clip1_2129_471\"><rect\n\t\t\t\tfill=\"white\"\n\t\t\t\theight=\"64\"\n\t\t\t\ttransform=\"translate(4.33081 0.00878906)\"\n\t\t\t\twidth=\"55.3383\"\n\t\t\t/></clipPath></defs></svg></svg>", "color": "#000000", "real": true}, "firecrawl": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"8 44 570 570\" preserveAspectRatio=\"xMidYMid meet\"><g><g transform=\" translate(293.035, 553.013) scale(0.97724, 0.97724) translate(-533.035, -800.013)\"><path d=\" M603.36 416.33 C581,433 586.63,450.25 583.86,466.55 C583.19,470.47 577.75,469.25 576.54,465.71 C559.5,447 549.55,423.61 559.33,394.37 C577.25,340.75 614.25,311.25 594.16,288.45 C590.97,284.83 591.83,284.26 590.22,288.82 C572.5,339 363,338 427.98,536 C430.85,544.77 430.25,555.25 429.51,565.8 C429.28,568.95 427.08,571.32 424.17,570.12 C401.5,560.75 395.38,525.75 390.42,516.28 C389,513.58 387.5,514.5 385.67,517.95 C381.03,524.07 377.94,532.3 374.2,538.54 C336.92,600.69 343.58,664.33 368.03,714.96 C368.94,716.86 369.89,718.74 370.85,720.6 C371.93,722.68 373.05,724.75 374.19,726.79 C391.8,758.26 416.04,783.76 439.75,799.32 C442.6,801.19 446.26,798.52 445.29,795.24 C437.07,767.62 642.75,744.75 634.67,795.2 C634.12,798.62 637.29,801.28 640.2,799.38 C659.88,786.47 680.25,766.82 695.21,741.99 C696.41,740.01 697.57,737.99 698.7,735.93 C699.47,734.52 700.23,733.09 700.97,731.65 C711.2,711.65 717.8,688.75 718.09,663.65 C718.33,643.75 714.58,622.45 705.52,600.11 C703.78,595.83 700.25,616.5 684.38,613.26 C682.86,612.95 691.25,586.13 692.06,570.64 C692.44,563.26 690.67,544.7 683.23,524.06 C667.77,481.12 615.5,466.25 609.58,417.31 C609.25,414.61 605.53,414.71 603.36,416.33z \" fill=\"#FA5D19\" fill-opacity=\"1\" fill-rule=\"nonzero\"></path></g><g transform=\" translate(300, 470.504) scale(0.9650799999999999, 0.9650799999999999) translate(-510.283, -685.815)\"><path d=\" M410.06 771.87 C412.91,773.74 416.57,771.07 415.6,767.79 C407.38,740.17 411.54,708.64 427.68,684.63 C455.29,643.16 510.65,603.1 501.81,548.71 C501.24,545.26 505.31,542.99 507.87,545.36 C546.86,581 554.59,628.95 548.18,671.96 C547.63,675.7 552.32,677.69 554.68,674.76 C560.64,667.29 567.92,660.74 575.85,655.81 C577.82,654.59 580.46,655.52 581.21,657.72 C594.24,695.64 617.69,725.57 604.98,767.75 C603.97,771.07 607.6,773.83 610.51,771.93 C610.51,771.93 610.51,827.25 610.51,827.25 C610.51,827.25 410.06,827.25 410.06,827.25 C410.06,827.25 410.06,771.87 410.06,771.87z \" fill=\"#FA5D19\" fill-opacity=\"1\" fill-rule=\"nonzero\"></path></g></g></svg></svg>", "color": "#FA5D19", "real": true}, "pipedrive": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect x=\"0.5\" y=\"0.5\" width=\"31\" height=\"31\" rx=\"8\" fill=\"#ffffff\" stroke=\"#d9d9d9\"/><svg x=\"5\" y=\"5\" width=\"22\" height=\"22\" viewBox=\"0 0 32 32\" preserveAspectRatio=\"xMidYMid meet\"><g fill=\"#FFFFFF\"><g clip-path=\"url(#clip0_503_588)\"><path fill=\"#017737\" d=\"M32 16C32 24.8366 24.8366 32 16 32C7.16344 32 0 24.8366 0 16C0 7.16344 7.16344 0 16 0C24.8366 0 32 7.16344 32 16Z\"></path><path d=\"M24.9842 13.4564C24.9842 17.8851 22.1247 20.914 18.036 20.914C16.0923 20.914 14.4903 20.1136 13.8906 19.1134L13.9189 20.142V26.4847H9.74512V10.0846C9.74512 9.85644 9.68836 9.79843 9.4304 9.79843H8V6.31321H11.4889C13.0896 6.31321 13.4907 7.68461 13.6042 8.28525C14.2337 7.22834 15.8911 6 18.2359 6C22.2679 5.99871 24.9842 8.99802 24.9842 13.4564ZM20.724 13.4847C20.724 11.1131 19.1801 9.48523 17.2351 9.48523C15.6344 9.48523 13.8325 10.5421 13.8325 13.5144C13.8325 15.4568 14.9186 17.4855 17.1783 17.4855C18.837 17.4842 20.724 16.2843 20.724 13.4847Z\" fill=\"#FFFFFF\"></path></g></g></svg></svg>", "color": "#017737", "real": true}, "pandadoc": {"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\"><rect width=\"32\" height=\"32\" rx=\"8\" fill=\"#248567\"/><text x=\"16\" y=\"21.5\" text-anchor=\"middle\" font-family=\"-apple-system, Helvetica, Arial, sans-serif\" font-size=\"16\" font-weight=\"700\" fill=\"#ffffff\">P</text></svg>", "color": "#248567", "real": false}}
4types/index.d.ts 88 lines1/** One call a connector made in this chat. */
2export type CallRow = {
3 /** Humanised tool name: "search threads". */
4 tool: string
5 /** The main argument, short: a query, an id, a file name. */
6 summary: string
7 /** Milliseconds since the epoch; 0 when unknown. */
8 at: number
9 /** True for a CLI call made through Bash. */
10 cli: boolean
11}
12
13/** One connector, with every call it made. */
14export type ConnectorRow = {
15 /** Logo key and press address: "gmail", "fireflies". */
16 key: string
17 name: string
18 count: number
19 /** Order of last use: higher is newer. */
20 seq: number
21 /** Used through a CLI in Bash. */
22 cli: boolean
23 /** Used through an MCP tool. */
24 mcp: boolean
25 /** Newest last; capped. */
26 calls: CallRow[]
27}
28
29/** One skill, with how many times this chat used it. */
30export type SkillRow = {
31 name: string
32 count: number
33 seq: number
34 /** Loaded at start through a memory file (CLAUDE.md import). */
35 always: boolean
36}
37
38/** One file in the chat's context. */
39export type FileRow = {
40 /** Absolute path. */
41 path: string
42 /** True for a memory file the chat loaded at start (CLAUDE.md, AGENTS.md, MEMORY.md). */
43 auto: boolean
44 seq: number
45}
46
47export type Inventory = {
48 connectors: ConnectorRow[]
49 files: FileRow[]
50 skills: SkillRow[]
51}
52
53/** One step of this chat's to-do list. */
54export type PlanStep = {
55 text: string
56 status: 'pending' | 'in_progress' | 'completed'
57 /** TodoWrite's present-tense form, shown while the step is in progress. */
58 active?: string
59 /** TaskCreate's id, so TaskUpdate finds the step. */
60 id?: string
61}
62
63/** The to-do list: from the shared plan file, or from Claude's own plan tool calls. Newest wins. */
64export type Plan = {
65 title: string
66 steps: PlanStep[]
67 /** Milliseconds since the epoch of the last change; 0 for none. */
68 updatedAt: number
69}
70
71declare module 'claude-code' {
72 interface PluginState {
73 'chat-inventory': {
74 inv: Inventory
75 /** The to-do list shown at the top of the pane. */
76 plan: Plan
77 /** Key of the connector whose call list is open; '' for none. */
78 open: string
79 /** True when switches.json turns the mod off. */
80 off: boolean
81 /** Sections the person closed with the header arrow: todo, connectors, files, skills. */
82 folded: string[]
83 /** First context file row shown in the 10-row window. */
84 fileTop: number
85 }
86 }
87}
88